winit_input_map

Struct InputMap

source
pub struct InputMap<const BINDS: usize> {
    pub binds: [Vec<Input>; BINDS],
    pub press_val: [f32; BINDS],
    pub pressed: [bool; BINDS],
    pub released: [bool; BINDS],
    pub mouse_pos: (f32, f32),
    pub other_pressed: Option<Input>,
    pub text_typed: Option<String>,
    pub mouse_scale: f32,
    pub scroll_scale: f32,
}
Expand description

A struct that handles all your input needs once you’ve hooked it up to winit and gilrs.

struct App<const BINDS: usize> {
    window: Option<Window>,
    input: InputMap<BINDS>,
    gilrs: Gilrs
}
impl<const BINDS: usize> ApplicationHandler for App<BINDS> {
    fn resumed(&mut self, event_loop: &ActiveEventLoop) {
        self.window = Some(event_loop.create_window(Window::default_attributes()).unwrap());
    }
    fn window_event(&mut self, event_loop: &ActiveEventLoop, _: WindowId, event: WindowEvent) {
        self.input.update_with_window_event(&event);
        if let WindowEvent::CloseRequested = &event { event_loop.exit() }
    }
    fn device_event(&mut self, _: &ActiveEventLoop, _: DeviceId, event: DeviceEvent) {
        self.input.update_with_device_event(&event);
    }
    fn about_to_wait(&mut self, _: &ActiveEventLoop) {
        self.input.update_with_gilrs(&mut self.gilrs);
 
        // put your code here

        self.input.init();
    }
}

Fields§

§binds: [Vec<Input>; BINDS]§press_val: [f32; BINDS]§pressed: [bool; BINDS]§released: [bool; BINDS]§mouse_pos: (f32, f32)

the amount the scroll wheel has changed

§other_pressed: Option<Input>

last input even if it isnt in the binds. useful for rebinding.

§text_typed: Option<String>

the text typed this loop. useful for typing

§mouse_scale: f32§scroll_scale: f32

Implementations§

source§

impl<const BINDS: usize> InputMap<BINDS>

source

pub fn new(binds: [(impl Into<usize>, Vec<Input>); BINDS]) -> Self

create new input system. recommended to use an action enum which implements the Into<usize> trait. using the input_map! macro to reduce boilerplate is recommended.

use Action::*;
use winit_input_map::*;
use winit::keyboard::KeyCode;
#[derive(ToUsize)]
enum Action {
    Forward,
    Back,
    Pos,
    Neg
}
//doesnt have to be the same ordered as the enum.
let mut input = Input::new([
    (vec![Input::keycode(KeyCode::KeyW)], Forward),
    (vec![Input::keycode(KeyCode::KeyA)], Pos),
    (vec![Input::keycode(KeyCode::KeyS)], Back),
    (vec![Input::keycode(KeyCode::KeyD)], Neg)
]);
source

pub fn empty() -> InputMap<0>

use if you dont want to have any actions and binds. will still have access to everything else.

source

pub fn update_with_winit(&mut self, event: &Event<()>)

👎Deprecated: use update_with_window_event and update_with_device_event

updates the input map using a winit event. make sure to call input.init() when your done with the input this loop.

use winit::{event::*, window::Window, event_loop::EventLoop};
use winit_input_map::InputMap;

let mut event_loop = EventLoop::new().unwrap();
event_loop.set_control_flow(winit::event_loop::ControlFlow::Poll);
let _window = Window::new(&event_loop).unwrap();

let mut input = input_map!();

event_loop.run(|event, target|{
    input.update(&event);
    match &event{
        Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => target.exit(),
        Event::AboutToWait => input.init(),
        _ => ()
    }
});
source

pub fn update_with_device_event(&mut self, event: &DeviceEvent)

Examples found in repository?
examples/minimum.rs (line 21)
20
21
22
    fn device_event(&mut self, _: &ActiveEventLoop, _: DeviceId, event: DeviceEvent) {
        self.input.update_with_device_event(&event);
    }
More examples
Hide additional examples
examples/typing.rs (line 26)
25
26
27
    fn device_event(&mut self, _: &ActiveEventLoop, _: DeviceId, event: DeviceEvent) {
        self.input.update_with_device_event(&event);
    }
examples/example.rs (line 44)
43
44
45
    fn device_event(&mut self, _: &ActiveEventLoop, _: DeviceId, event: DeviceEvent) {
        self.input.update_with_device_event(&event);
    }
source

pub fn update_with_window_event(&mut self, event: &WindowEvent)

Examples found in repository?
examples/minimum.rs (line 17)
16
17
18
19
    fn window_event(&mut self, event_loop: &ActiveEventLoop, _: WindowId, event: WindowEvent) {
        self.input.update_with_window_event(&event);
        if let WindowEvent::CloseRequested = &event { event_loop.exit() }
    }
More examples
Hide additional examples
examples/typing.rs (line 22)
21
22
23
24
    fn window_event(&mut self, event_loop: &ActiveEventLoop, _: WindowId, event: WindowEvent) {
        self.input.update_with_window_event(&event);
        if let WindowEvent::CloseRequested = &event { event_loop.exit() }
    }
examples/example.rs (line 40)
39
40
41
42
    fn window_event(&mut self, event_loop: &ActiveEventLoop, _: WindowId, event: WindowEvent) {
        self.input.update_with_window_event(&event);
        if let WindowEvent::CloseRequested = &event { event_loop.exit() }
    }
source

pub fn update_with_gilrs(&mut self, gilrs: &mut Gilrs)

Examples found in repository?
examples/minimum.rs (line 24)
23
24
25
26
27
28
29
    fn about_to_wait(&mut self, _: &ActiveEventLoop) {
        self.input.update_with_gilrs(&mut self.gilrs);

        // put your code here

        self.input.init();
    }
More examples
Hide additional examples
examples/typing.rs (line 29)
28
29
30
31
32
33
34
35
36
37
38
39
    fn about_to_wait(&mut self, _: &ActiveEventLoop) {
        self.input.update_with_gilrs(&mut self.gilrs);

        if self.input.pressed(Action::Return) {
            println!("{}", self.text);
            self.text = String::new();
        } else if let Some(new) = &self.input.text_typed {
            self.text.push_str(new);
        }

        self.input.init();
    }
examples/example.rs (line 53)
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
    fn about_to_wait(&mut self, _: &ActiveEventLoop) {
        let input = &mut self.input;
        let scroll = input.axis(MouseScrollP, MouseScrollN);
        let mouse_move = (
            input.axis(MouseXP, MouseXN),
            input.axis(MouseYP, MouseYN)
        );
        input.update_with_gilrs(&mut self.gilrs);
        if input.pressed(Debug) {
            println!("pressed {:?}", input.binds(Debug))
        }
        if input.pressing(Right) || input.pressing(Left) {
            println!("axis: {}", input.axis(Right, Left))
        }
        if mouse_move != (0.0, 0.0) {
            println!(
                "mouse moved: {:?} and is now at {:?}",
                mouse_move, input.mouse_pos
            )
        }
        if input.released(Click) {
            println!("released {:?}", input.binds(Click))
        }
        if scroll != 0.0 {
            println!("scrolling {}", scroll);
        }
        if let Some(other) = input.other_pressed {
            println!("{other:?}");
        }
        std::thread::sleep(std::time::Duration::from_millis(100));
        //reset input. use after your done with the input
        input.init();
    }
source

pub fn init(&mut self)

makes the input map ready to recieve new events.

Examples found in repository?
examples/minimum.rs (line 28)
23
24
25
26
27
28
29
    fn about_to_wait(&mut self, _: &ActiveEventLoop) {
        self.input.update_with_gilrs(&mut self.gilrs);

        // put your code here

        self.input.init();
    }
More examples
Hide additional examples
examples/typing.rs (line 38)
28
29
30
31
32
33
34
35
36
37
38
39
    fn about_to_wait(&mut self, _: &ActiveEventLoop) {
        self.input.update_with_gilrs(&mut self.gilrs);

        if self.input.pressed(Action::Return) {
            println!("{}", self.text);
            self.text = String::new();
        } else if let Some(new) = &self.input.text_typed {
            self.text.push_str(new);
        }

        self.input.init();
    }
examples/example.rs (line 77)
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
    fn about_to_wait(&mut self, _: &ActiveEventLoop) {
        let input = &mut self.input;
        let scroll = input.axis(MouseScrollP, MouseScrollN);
        let mouse_move = (
            input.axis(MouseXP, MouseXN),
            input.axis(MouseYP, MouseYN)
        );
        input.update_with_gilrs(&mut self.gilrs);
        if input.pressed(Debug) {
            println!("pressed {:?}", input.binds(Debug))
        }
        if input.pressing(Right) || input.pressing(Left) {
            println!("axis: {}", input.axis(Right, Left))
        }
        if mouse_move != (0.0, 0.0) {
            println!(
                "mouse moved: {:?} and is now at {:?}",
                mouse_move, input.mouse_pos
            )
        }
        if input.released(Click) {
            println!("released {:?}", input.binds(Click))
        }
        if scroll != 0.0 {
            println!("scrolling {}", scroll);
        }
        if let Some(other) = input.other_pressed {
            println!("{other:?}");
        }
        std::thread::sleep(std::time::Duration::from_millis(100));
        //reset input. use after your done with the input
        input.init();
    }
source

pub fn binds(&mut self, action: impl Into<usize>) -> &mut Vec<Input>

get binds of action. same as self.binds[action.into()]

Examples found in repository?
examples/example.rs (line 55)
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
    fn about_to_wait(&mut self, _: &ActiveEventLoop) {
        let input = &mut self.input;
        let scroll = input.axis(MouseScrollP, MouseScrollN);
        let mouse_move = (
            input.axis(MouseXP, MouseXN),
            input.axis(MouseYP, MouseYN)
        );
        input.update_with_gilrs(&mut self.gilrs);
        if input.pressed(Debug) {
            println!("pressed {:?}", input.binds(Debug))
        }
        if input.pressing(Right) || input.pressing(Left) {
            println!("axis: {}", input.axis(Right, Left))
        }
        if mouse_move != (0.0, 0.0) {
            println!(
                "mouse moved: {:?} and is now at {:?}",
                mouse_move, input.mouse_pos
            )
        }
        if input.released(Click) {
            println!("released {:?}", input.binds(Click))
        }
        if scroll != 0.0 {
            println!("scrolling {}", scroll);
        }
        if let Some(other) = input.other_pressed {
            println!("{other:?}");
        }
        std::thread::sleep(std::time::Duration::from_millis(100));
        //reset input. use after your done with the input
        input.init();
    }
source

pub fn pressing(&self, action: impl Into<usize>) -> bool

checks if action is being pressed currently. same as self.press_val[action.into()] != 0.0

Examples found in repository?
examples/example.rs (line 57)
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
    fn about_to_wait(&mut self, _: &ActiveEventLoop) {
        let input = &mut self.input;
        let scroll = input.axis(MouseScrollP, MouseScrollN);
        let mouse_move = (
            input.axis(MouseXP, MouseXN),
            input.axis(MouseYP, MouseYN)
        );
        input.update_with_gilrs(&mut self.gilrs);
        if input.pressed(Debug) {
            println!("pressed {:?}", input.binds(Debug))
        }
        if input.pressing(Right) || input.pressing(Left) {
            println!("axis: {}", input.axis(Right, Left))
        }
        if mouse_move != (0.0, 0.0) {
            println!(
                "mouse moved: {:?} and is now at {:?}",
                mouse_move, input.mouse_pos
            )
        }
        if input.released(Click) {
            println!("released {:?}", input.binds(Click))
        }
        if scroll != 0.0 {
            println!("scrolling {}", scroll);
        }
        if let Some(other) = input.other_pressed {
            println!("{other:?}");
        }
        std::thread::sleep(std::time::Duration::from_millis(100));
        //reset input. use after your done with the input
        input.init();
    }
source

pub fn press_val(&self, action: impl Into<usize>) -> f32

checks how much action is being pressed. same as self.press_val[action.into()]

source

pub fn pressed(&self, action: impl Into<usize>) -> bool

checks if action was just pressed. same as self.pressed[action.into()]

Examples found in repository?
examples/typing.rs (line 31)
28
29
30
31
32
33
34
35
36
37
38
39
    fn about_to_wait(&mut self, _: &ActiveEventLoop) {
        self.input.update_with_gilrs(&mut self.gilrs);

        if self.input.pressed(Action::Return) {
            println!("{}", self.text);
            self.text = String::new();
        } else if let Some(new) = &self.input.text_typed {
            self.text.push_str(new);
        }

        self.input.init();
    }
More examples
Hide additional examples
examples/example.rs (line 54)
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
    fn about_to_wait(&mut self, _: &ActiveEventLoop) {
        let input = &mut self.input;
        let scroll = input.axis(MouseScrollP, MouseScrollN);
        let mouse_move = (
            input.axis(MouseXP, MouseXN),
            input.axis(MouseYP, MouseYN)
        );
        input.update_with_gilrs(&mut self.gilrs);
        if input.pressed(Debug) {
            println!("pressed {:?}", input.binds(Debug))
        }
        if input.pressing(Right) || input.pressing(Left) {
            println!("axis: {}", input.axis(Right, Left))
        }
        if mouse_move != (0.0, 0.0) {
            println!(
                "mouse moved: {:?} and is now at {:?}",
                mouse_move, input.mouse_pos
            )
        }
        if input.released(Click) {
            println!("released {:?}", input.binds(Click))
        }
        if scroll != 0.0 {
            println!("scrolling {}", scroll);
        }
        if let Some(other) = input.other_pressed {
            println!("{other:?}");
        }
        std::thread::sleep(std::time::Duration::from_millis(100));
        //reset input. use after your done with the input
        input.init();
    }
source

pub fn released(&self, action: impl Into<usize>) -> bool

checks if action was just released. same as self.released[action.into()]

Examples found in repository?
examples/example.rs (line 66)
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
    fn about_to_wait(&mut self, _: &ActiveEventLoop) {
        let input = &mut self.input;
        let scroll = input.axis(MouseScrollP, MouseScrollN);
        let mouse_move = (
            input.axis(MouseXP, MouseXN),
            input.axis(MouseYP, MouseYN)
        );
        input.update_with_gilrs(&mut self.gilrs);
        if input.pressed(Debug) {
            println!("pressed {:?}", input.binds(Debug))
        }
        if input.pressing(Right) || input.pressing(Left) {
            println!("axis: {}", input.axis(Right, Left))
        }
        if mouse_move != (0.0, 0.0) {
            println!(
                "mouse moved: {:?} and is now at {:?}",
                mouse_move, input.mouse_pos
            )
        }
        if input.released(Click) {
            println!("released {:?}", input.binds(Click))
        }
        if scroll != 0.0 {
            println!("scrolling {}", scroll);
        }
        if let Some(other) = input.other_pressed {
            println!("{other:?}");
        }
        std::thread::sleep(std::time::Duration::from_millis(100));
        //reset input. use after your done with the input
        input.init();
    }
source

pub fn axis(&self, pos: impl Into<usize>, neg: impl Into<usize>) -> f32

returns f32 based on how much pos and neg are pressed. may return values higher than 1.0 in the case of mouse movement and scrolling. usefull for movement controls.

let move_dir = (input.axis(Neg, Pos), input.axis(Up, Down));
Examples found in repository?
examples/example.rs (line 48)
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
    fn about_to_wait(&mut self, _: &ActiveEventLoop) {
        let input = &mut self.input;
        let scroll = input.axis(MouseScrollP, MouseScrollN);
        let mouse_move = (
            input.axis(MouseXP, MouseXN),
            input.axis(MouseYP, MouseYN)
        );
        input.update_with_gilrs(&mut self.gilrs);
        if input.pressed(Debug) {
            println!("pressed {:?}", input.binds(Debug))
        }
        if input.pressing(Right) || input.pressing(Left) {
            println!("axis: {}", input.axis(Right, Left))
        }
        if mouse_move != (0.0, 0.0) {
            println!(
                "mouse moved: {:?} and is now at {:?}",
                mouse_move, input.mouse_pos
            )
        }
        if input.released(Click) {
            println!("released {:?}", input.binds(Click))
        }
        if scroll != 0.0 {
            println!("scrolling {}", scroll);
        }
        if let Some(other) = input.other_pressed {
            println!("{other:?}");
        }
        std::thread::sleep(std::time::Duration::from_millis(100));
        //reset input. use after your done with the input
        input.init();
    }

Auto Trait Implementations§

§

impl<const BINDS: usize> Freeze for InputMap<BINDS>

§

impl<const BINDS: usize> RefUnwindSafe for InputMap<BINDS>

§

impl<const BINDS: usize> Send for InputMap<BINDS>

§

impl<const BINDS: usize> Sync for InputMap<BINDS>

§

impl<const BINDS: usize> Unpin for InputMap<BINDS>

§

impl<const BINDS: usize> UnwindSafe for InputMap<BINDS>

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> Downcast for T
where T: Any,

source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.
source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
source§

fn as_any(&self) -> &(dyn Any + 'static)

Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
source§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

source§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Send + Sync>

Convert Arc<Trait> (where Trait: Downcast) to Arc<Any>. Arc<Any> can then be further downcast into Arc<ConcreteType> where ConcreteType implements Trait.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

source§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more