script/dom/gamepad/
gamepadbuttonlist.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5use dom_struct::dom_struct;
6
7use crate::dom::bindings::codegen::Bindings::GamepadButtonListBinding::GamepadButtonListMethods;
8use crate::dom::bindings::reflector::{Reflector, reflect_dom_object};
9use crate::dom::bindings::root::{Dom, DomRoot, DomSlice};
10use crate::dom::gamepad::gamepadbutton::GamepadButton;
11use crate::dom::window::Window;
12use crate::script_runtime::CanGc;
13
14// https://w3c.github.io/gamepad/#gamepadbutton-interface
15#[dom_struct]
16pub(crate) struct GamepadButtonList {
17    reflector_: Reflector,
18    list: Vec<Dom<GamepadButton>>,
19}
20
21impl GamepadButtonList {
22    #[cfg_attr(crown, allow(crown::unrooted_must_root))]
23    fn new_inherited(list: &[&GamepadButton]) -> GamepadButtonList {
24        GamepadButtonList {
25            reflector_: Reflector::new(),
26            list: list.iter().map(|button| Dom::from_ref(*button)).collect(),
27        }
28    }
29
30    pub(crate) fn new(
31        window: &Window,
32        list: &[&GamepadButton],
33        can_gc: CanGc,
34    ) -> DomRoot<GamepadButtonList> {
35        reflect_dom_object(
36            Box::new(GamepadButtonList::new_inherited(list)),
37            window,
38            can_gc,
39        )
40    }
41}
42
43impl GamepadButtonListMethods<crate::DomTypeHolder> for GamepadButtonList {
44    // https://w3c.github.io/gamepad/#dom-gamepad-buttons
45    fn Length(&self) -> u32 {
46        self.list.len() as u32
47    }
48
49    // https://w3c.github.io/gamepad/#dom-gamepad-buttons
50    fn Item(&self, index: u32) -> Option<DomRoot<GamepadButton>> {
51        self.list
52            .get(index as usize)
53            .map(|button| DomRoot::from_ref(&**button))
54    }
55
56    // https://w3c.github.io/gamepad/#dom-gamepad-buttons
57    fn IndexedGetter(&self, index: u32) -> Option<DomRoot<GamepadButton>> {
58        self.Item(index)
59    }
60}
61
62impl GamepadButtonList {
63    /// Initialize the number of buttons in the "standard" gamepad mapping.
64    /// <https://www.w3.org/TR/gamepad/#dfn-initializing-buttons>
65    pub(crate) fn init_buttons(window: &Window, can_gc: CanGc) -> DomRoot<GamepadButtonList> {
66        let standard_buttons = &[
67            GamepadButton::new(window, false, false, can_gc), // Bottom button in right cluster
68            GamepadButton::new(window, false, false, can_gc), // Right button in right cluster
69            GamepadButton::new(window, false, false, can_gc), // Left button in right cluster
70            GamepadButton::new(window, false, false, can_gc), // Top button in right cluster
71            GamepadButton::new(window, false, false, can_gc), // Top left front button
72            GamepadButton::new(window, false, false, can_gc), // Top right front button
73            GamepadButton::new(window, false, false, can_gc), // Bottom left front button
74            GamepadButton::new(window, false, false, can_gc), // Bottom right front button
75            GamepadButton::new(window, false, false, can_gc), // Left button in center cluster
76            GamepadButton::new(window, false, false, can_gc), // Right button in center cluster
77            GamepadButton::new(window, false, false, can_gc), // Left stick pressed button
78            GamepadButton::new(window, false, false, can_gc), // Right stick pressed button
79            GamepadButton::new(window, false, false, can_gc), // Top button in left cluster
80            GamepadButton::new(window, false, false, can_gc), // Bottom button in left cluster
81            GamepadButton::new(window, false, false, can_gc), // Left button in left cluster
82            GamepadButton::new(window, false, false, can_gc), // Right button in left cluster
83            GamepadButton::new(window, false, false, can_gc), // Center button in center cluster
84        ];
85        rooted_vec!(let buttons <- standard_buttons.iter().map(DomRoot::as_traced));
86        Self::new(window, buttons.r(), can_gc)
87    }
88}