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>
impl<const BINDS: usize> InputMap<BINDS>
sourcepub fn new(binds: [(impl Into<usize>, Vec<Input>); BINDS]) -> Self
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)
]);
sourcepub fn empty() -> InputMap<0>
pub fn empty() -> InputMap<0>
use if you dont want to have any actions and binds. will still have access to everything else.
sourcepub fn update_with_winit(&mut self, event: &Event<()>)
👎Deprecated: use update_with_window_event
and update_with_device_event
pub fn update_with_winit(&mut self, event: &Event<()>)
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(),
_ => ()
}
});
sourcepub fn update_with_device_event(&mut self, event: &DeviceEvent)
pub fn update_with_device_event(&mut self, event: &DeviceEvent)
Examples found in repository?
More examples
sourcepub fn update_with_window_event(&mut self, event: &WindowEvent)
pub fn update_with_window_event(&mut self, event: &WindowEvent)
Examples found in repository?
More examples
sourcepub fn update_with_gilrs(&mut self, gilrs: &mut Gilrs)
pub fn update_with_gilrs(&mut self, gilrs: &mut Gilrs)
Examples found in repository?
More examples
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();
}
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();
}
sourcepub fn init(&mut self)
pub fn init(&mut self)
makes the input map ready to recieve new events.
Examples found in repository?
More examples
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();
}
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();
}
sourcepub fn binds(&mut self, action: impl Into<usize>) -> &mut Vec<Input>
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?
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();
}
sourcepub fn pressing(&self, action: impl Into<usize>) -> bool
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?
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();
}
sourcepub fn press_val(&self, action: impl Into<usize>) -> f32
pub fn press_val(&self, action: impl Into<usize>) -> f32
checks how much action is being pressed. same as self.press_val[action.into()]
sourcepub fn pressed(&self, action: impl Into<usize>) -> bool
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?
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
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();
}
sourcepub fn released(&self, action: impl Into<usize>) -> bool
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?
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();
}
sourcepub fn axis(&self, pos: impl Into<usize>, neg: impl Into<usize>) -> f32
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?
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> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
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>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
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)
fn as_any(&self) -> &(dyn Any + 'static)
&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)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &mut Any
’s vtable from &mut Trait
’s.