Struct winit_input_map::InputMap
source · pub struct InputMap<const BINDS: usize> {
pub binds: [Vec<Input>; BINDS],
pub pressing: [bool; BINDS],
pub pressed: [bool; BINDS],
pub released: [bool; BINDS],
pub mouse_scroll: f32,
pub mouse_move: (f32, f32),
pub mouse_pos: (f32, f32),
pub other_pressed: Option<Input>,
pub text_typed: Option<String>,
}
Expand description
you can use anything that implements the Into<usize>
trait as an action, but it’s recommended
to use an action enum which derives ToUsize
. input_map!
macro reduces the boilerplate of
this function
#[derive(ToUsize)] // could also manualy implement Into<usize>
enum Actions{
Debug,
Left,
Right,
Click
}
use winit::{event::*, keyboard::KeyCode, event_loop::*, window::Window};
use winit_input_map::*;
use Actions::*;
let mut input = InputMap::new([ // doesnt have to be in the same order as the enum
(Debug, vec![Input::keycode(KeyCode::Space)]),
(Click, vec![Input::Mouse(MouseButton::Left)]),
(Left, vec![Input::keycode(KeyCode::ArrowLeft), Input::keycode(KeyCode::KeyA)]),
(Right, vec![Input::keycode(KeyCode::ArrowRight), Input::keycode(KeyCode::KeyD)]),
]);
let event_loop = EventLoop::new().unwrap();
event_loop.set_control_flow(ControlFlow::Poll);
let _window = Window::new(&event_loop).unwrap();
event_loop.run(|event, target|{
input.update(&event);
match &event {
Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => { target.exit() },
Event::AboutToWait => {
if input.pressed(Debug) { println!("pressed {:?}", input.binds(Debug)) }
if input.pressing(Right) || input.pressing(Left) {
println!("axis: {}", input.axis(Right, Left))
}
if input.mouse_move != (0.0, 0.0) {
println!("mouse moved: {:?} and is now at {:?}", input.mouse_move, input.mouse_pos)
}
if input.released(Click) { println!("released {:?}", input.binds(Click)) }
std::thread::sleep(std::time::Duration::from_millis(100));
//put at end of loop because were done with inputs this loop.
input.init();
}
_ => ()
}
}).unwrap();
Fields§
§binds: [Vec<Input>; BINDS]
§pressing: [bool; BINDS]
§pressed: [bool; BINDS]
§released: [bool; BINDS]
§mouse_scroll: f32
the amount the scroll wheel has changed
mouse_move: (f32, f32)
§mouse_pos: (f32, f32)
§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
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. the input_map!
macro reduces boilerplate.
use Action::*;
use input::*;
use winit::keyboard::KeyCode;
#[derive(ToUsize)]
enum Action {
Forward,
Back,
Left,
Right
}
//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)], Left),
(vec![Input::keycode(KeyCode::KeyS)], Back),
(vec![Input::keycode(KeyCode::KeyD)], Right)
]);
sourcepub fn empty() -> InputMap<0>
pub fn empty() -> InputMap<0>
use if you dont want to have any action. will still have access to everythin else
sourcepub fn update(&mut self, event: &Event<()>)
pub fn update(&mut self, event: &Event<()>)
updates the input 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(),
_ => ()
}
});
Examples found in repository?
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
fn main() {
use Action::*;
use winit::{window::Window, keyboard::KeyCode, event_loop::EventLoop, event::*};
let mut input = input_map!(
(Return, KeyCode::Enter)
);
let ev = EventLoop::new().unwrap(); // notice that we didnt set control flow poll
let _window = Window::new(&ev).unwrap();
let mut text = String::new();
ev.run(|event, target|{
input.update(&event);
match &event {
Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => { target.exit() },
Event::AboutToWait => {
if input.pressed(Return) {
println!("{text}");
text = String::new();
} else if let Some(new) = &input.text_typed {
text.push_str(new);
}
input.init();
}
_ => ()
}
}).unwrap()
}
More examples
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
fn main() {
#[derive(ToUsize)]
enum Actions {
Debug,
Left,
Right,
Click,
}
use winit_input_map::*;
use Actions::*;
let mut input = input_map!(
(Debug, KeyCode::Space),
(Left, KeyCode::ArrowLeft, KeyCode::KeyA),
(Right, KeyCode::ArrowRight, KeyCode::KeyD),
(Click, MouseButton::Left)
);
use winit::{event::*, keyboard::KeyCode, window::Window};
let event_loop = winit::event_loop::EventLoop::new().unwrap();
event_loop.set_control_flow(winit::event_loop::ControlFlow::Poll);
let _window = Window::new(&event_loop).unwrap();
event_loop.run(|event, target| {
input.update(&event);
match &event {
Event::WindowEvent {
event: WindowEvent::CloseRequested, ..
} => target.exit(),
Event::AboutToWait => {
if input.pressed(Debug) {
println!("pressed {:?}", input.binds(Debug))
}
if input.pressing(Right) || input.pressing(Left) {
println!("axis: {}", input.axis(Right, Left))
}
if input.mouse_move != (0.0, 0.0) {
println!(
"mouse moved: {:?} and is now at {:?}",
input.mouse_move, input.mouse_pos
)
}
if input.released(Click) {
println!("released {:?}", input.binds(Click))
}
if input.mouse_scroll != 0.0 {
println!("scrolling {}", input.mouse_scroll);
}
std::thread::sleep(std::time::Duration::from_millis(100));
//reset input. use after your done with the input
input.init();
}
_ => (),
}
}).unwrap();
}
sourcepub fn init(&mut self)
pub fn init(&mut self)
initialise input. use when your done with input this loop. required to be called for
everything except pressing
and mouse_pos
to work properly.
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(),
_ => ()
}
});
Examples found in repository?
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
fn main() {
use Action::*;
use winit::{window::Window, keyboard::KeyCode, event_loop::EventLoop, event::*};
let mut input = input_map!(
(Return, KeyCode::Enter)
);
let ev = EventLoop::new().unwrap(); // notice that we didnt set control flow poll
let _window = Window::new(&ev).unwrap();
let mut text = String::new();
ev.run(|event, target|{
input.update(&event);
match &event {
Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => { target.exit() },
Event::AboutToWait => {
if input.pressed(Return) {
println!("{text}");
text = String::new();
} else if let Some(new) = &input.text_typed {
text.push_str(new);
}
input.init();
}
_ => ()
}
}).unwrap()
}
More examples
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
fn main() {
#[derive(ToUsize)]
enum Actions {
Debug,
Left,
Right,
Click,
}
use winit_input_map::*;
use Actions::*;
let mut input = input_map!(
(Debug, KeyCode::Space),
(Left, KeyCode::ArrowLeft, KeyCode::KeyA),
(Right, KeyCode::ArrowRight, KeyCode::KeyD),
(Click, MouseButton::Left)
);
use winit::{event::*, keyboard::KeyCode, window::Window};
let event_loop = winit::event_loop::EventLoop::new().unwrap();
event_loop.set_control_flow(winit::event_loop::ControlFlow::Poll);
let _window = Window::new(&event_loop).unwrap();
event_loop.run(|event, target| {
input.update(&event);
match &event {
Event::WindowEvent {
event: WindowEvent::CloseRequested, ..
} => target.exit(),
Event::AboutToWait => {
if input.pressed(Debug) {
println!("pressed {:?}", input.binds(Debug))
}
if input.pressing(Right) || input.pressing(Left) {
println!("axis: {}", input.axis(Right, Left))
}
if input.mouse_move != (0.0, 0.0) {
println!(
"mouse moved: {:?} and is now at {:?}",
input.mouse_move, input.mouse_pos
)
}
if input.released(Click) {
println!("released {:?}", input.binds(Click))
}
if input.mouse_scroll != 0.0 {
println!("scrolling {}", input.mouse_scroll);
}
std::thread::sleep(std::time::Duration::from_millis(100));
//reset input. use after your done with the input
input.init();
}
_ => (),
}
}).unwrap();
}
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?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
fn main() {
#[derive(ToUsize)]
enum Actions {
Debug,
Left,
Right,
Click,
}
use winit_input_map::*;
use Actions::*;
let mut input = input_map!(
(Debug, KeyCode::Space),
(Left, KeyCode::ArrowLeft, KeyCode::KeyA),
(Right, KeyCode::ArrowRight, KeyCode::KeyD),
(Click, MouseButton::Left)
);
use winit::{event::*, keyboard::KeyCode, window::Window};
let event_loop = winit::event_loop::EventLoop::new().unwrap();
event_loop.set_control_flow(winit::event_loop::ControlFlow::Poll);
let _window = Window::new(&event_loop).unwrap();
event_loop.run(|event, target| {
input.update(&event);
match &event {
Event::WindowEvent {
event: WindowEvent::CloseRequested, ..
} => target.exit(),
Event::AboutToWait => {
if input.pressed(Debug) {
println!("pressed {:?}", input.binds(Debug))
}
if input.pressing(Right) || input.pressing(Left) {
println!("axis: {}", input.axis(Right, Left))
}
if input.mouse_move != (0.0, 0.0) {
println!(
"mouse moved: {:?} and is now at {:?}",
input.mouse_move, input.mouse_pos
)
}
if input.released(Click) {
println!("released {:?}", input.binds(Click))
}
if input.mouse_scroll != 0.0 {
println!("scrolling {}", input.mouse_scroll);
}
std::thread::sleep(std::time::Duration::from_millis(100));
//reset input. use after your done with the input
input.init();
}
_ => (),
}
}).unwrap();
}
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.pressing[action.into()]
Examples found in repository?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
fn main() {
#[derive(ToUsize)]
enum Actions {
Debug,
Left,
Right,
Click,
}
use winit_input_map::*;
use Actions::*;
let mut input = input_map!(
(Debug, KeyCode::Space),
(Left, KeyCode::ArrowLeft, KeyCode::KeyA),
(Right, KeyCode::ArrowRight, KeyCode::KeyD),
(Click, MouseButton::Left)
);
use winit::{event::*, keyboard::KeyCode, window::Window};
let event_loop = winit::event_loop::EventLoop::new().unwrap();
event_loop.set_control_flow(winit::event_loop::ControlFlow::Poll);
let _window = Window::new(&event_loop).unwrap();
event_loop.run(|event, target| {
input.update(&event);
match &event {
Event::WindowEvent {
event: WindowEvent::CloseRequested, ..
} => target.exit(),
Event::AboutToWait => {
if input.pressed(Debug) {
println!("pressed {:?}", input.binds(Debug))
}
if input.pressing(Right) || input.pressing(Left) {
println!("axis: {}", input.axis(Right, Left))
}
if input.mouse_move != (0.0, 0.0) {
println!(
"mouse moved: {:?} and is now at {:?}",
input.mouse_move, input.mouse_pos
)
}
if input.released(Click) {
println!("released {:?}", input.binds(Click))
}
if input.mouse_scroll != 0.0 {
println!("scrolling {}", input.mouse_scroll);
}
std::thread::sleep(std::time::Duration::from_millis(100));
//reset input. use after your done with the input
input.init();
}
_ => (),
}
}).unwrap();
}
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?
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
fn main() {
use Action::*;
use winit::{window::Window, keyboard::KeyCode, event_loop::EventLoop, event::*};
let mut input = input_map!(
(Return, KeyCode::Enter)
);
let ev = EventLoop::new().unwrap(); // notice that we didnt set control flow poll
let _window = Window::new(&ev).unwrap();
let mut text = String::new();
ev.run(|event, target|{
input.update(&event);
match &event {
Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => { target.exit() },
Event::AboutToWait => {
if input.pressed(Return) {
println!("{text}");
text = String::new();
} else if let Some(new) = &input.text_typed {
text.push_str(new);
}
input.init();
}
_ => ()
}
}).unwrap()
}
More examples
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
fn main() {
#[derive(ToUsize)]
enum Actions {
Debug,
Left,
Right,
Click,
}
use winit_input_map::*;
use Actions::*;
let mut input = input_map!(
(Debug, KeyCode::Space),
(Left, KeyCode::ArrowLeft, KeyCode::KeyA),
(Right, KeyCode::ArrowRight, KeyCode::KeyD),
(Click, MouseButton::Left)
);
use winit::{event::*, keyboard::KeyCode, window::Window};
let event_loop = winit::event_loop::EventLoop::new().unwrap();
event_loop.set_control_flow(winit::event_loop::ControlFlow::Poll);
let _window = Window::new(&event_loop).unwrap();
event_loop.run(|event, target| {
input.update(&event);
match &event {
Event::WindowEvent {
event: WindowEvent::CloseRequested, ..
} => target.exit(),
Event::AboutToWait => {
if input.pressed(Debug) {
println!("pressed {:?}", input.binds(Debug))
}
if input.pressing(Right) || input.pressing(Left) {
println!("axis: {}", input.axis(Right, Left))
}
if input.mouse_move != (0.0, 0.0) {
println!(
"mouse moved: {:?} and is now at {:?}",
input.mouse_move, input.mouse_pos
)
}
if input.released(Click) {
println!("released {:?}", input.binds(Click))
}
if input.mouse_scroll != 0.0 {
println!("scrolling {}", input.mouse_scroll);
}
std::thread::sleep(std::time::Duration::from_millis(100));
//reset input. use after your done with the input
input.init();
}
_ => (),
}
}).unwrap();
}
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?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
fn main() {
#[derive(ToUsize)]
enum Actions {
Debug,
Left,
Right,
Click,
}
use winit_input_map::*;
use Actions::*;
let mut input = input_map!(
(Debug, KeyCode::Space),
(Left, KeyCode::ArrowLeft, KeyCode::KeyA),
(Right, KeyCode::ArrowRight, KeyCode::KeyD),
(Click, MouseButton::Left)
);
use winit::{event::*, keyboard::KeyCode, window::Window};
let event_loop = winit::event_loop::EventLoop::new().unwrap();
event_loop.set_control_flow(winit::event_loop::ControlFlow::Poll);
let _window = Window::new(&event_loop).unwrap();
event_loop.run(|event, target| {
input.update(&event);
match &event {
Event::WindowEvent {
event: WindowEvent::CloseRequested, ..
} => target.exit(),
Event::AboutToWait => {
if input.pressed(Debug) {
println!("pressed {:?}", input.binds(Debug))
}
if input.pressing(Right) || input.pressing(Left) {
println!("axis: {}", input.axis(Right, Left))
}
if input.mouse_move != (0.0, 0.0) {
println!(
"mouse moved: {:?} and is now at {:?}",
input.mouse_move, input.mouse_pos
)
}
if input.released(Click) {
println!("released {:?}", input.binds(Click))
}
if input.mouse_scroll != 0.0 {
println!("scrolling {}", input.mouse_scroll);
}
std::thread::sleep(std::time::Duration::from_millis(100));
//reset input. use after your done with the input
input.init();
}
_ => (),
}
}).unwrap();
}
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 1.0 if pos is pressed, -1.0 if neg is pressed or 0.0 if either pos and neg or nothing is pressed. usefull for movement controls.
let move_dir = (input.axis(Right, Left), input.axis(Up, Down));
Examples found in repository?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
fn main() {
#[derive(ToUsize)]
enum Actions {
Debug,
Left,
Right,
Click,
}
use winit_input_map::*;
use Actions::*;
let mut input = input_map!(
(Debug, KeyCode::Space),
(Left, KeyCode::ArrowLeft, KeyCode::KeyA),
(Right, KeyCode::ArrowRight, KeyCode::KeyD),
(Click, MouseButton::Left)
);
use winit::{event::*, keyboard::KeyCode, window::Window};
let event_loop = winit::event_loop::EventLoop::new().unwrap();
event_loop.set_control_flow(winit::event_loop::ControlFlow::Poll);
let _window = Window::new(&event_loop).unwrap();
event_loop.run(|event, target| {
input.update(&event);
match &event {
Event::WindowEvent {
event: WindowEvent::CloseRequested, ..
} => target.exit(),
Event::AboutToWait => {
if input.pressed(Debug) {
println!("pressed {:?}", input.binds(Debug))
}
if input.pressing(Right) || input.pressing(Left) {
println!("axis: {}", input.axis(Right, Left))
}
if input.mouse_move != (0.0, 0.0) {
println!(
"mouse moved: {:?} and is now at {:?}",
input.mouse_move, input.mouse_pos
)
}
if input.released(Click) {
println!("released {:?}", input.binds(Click))
}
if input.mouse_scroll != 0.0 {
println!("scrolling {}", input.mouse_scroll);
}
std::thread::sleep(std::time::Duration::from_millis(100));
//reset input. use after your done with the input
input.init();
}
_ => (),
}
}).unwrap();
}
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.