mouse input
This commit is contained in:
@@ -1,13 +1,18 @@
|
||||
[[button]]
|
||||
name = "QUIT"
|
||||
scancode = 1
|
||||
scan_code = 1
|
||||
|
||||
[[button]]
|
||||
name = "QUIT"
|
||||
mouse = "Left"
|
||||
shift = true
|
||||
|
||||
[[button]]
|
||||
name = "RELOAD_SHADERS"
|
||||
scancode = 19
|
||||
scan_code = 19
|
||||
ctrl = true
|
||||
|
||||
[[axis]]
|
||||
name = "FORWARD"
|
||||
scancode_positive = 17
|
||||
scancode_negative = 31
|
||||
scan_code_positive = 17
|
||||
scan_code_negative = 31
|
||||
@@ -1 +1 @@
|
||||
input = false
|
||||
input = true
|
||||
96
src/input.rs
96
src/input.rs
@@ -6,6 +6,7 @@ use std::fs;
|
||||
use toml;
|
||||
|
||||
use serde_derive::{Serialize, Deserialize};
|
||||
use std::iter::FromIterator;
|
||||
|
||||
pub struct VirtualButton {
|
||||
pub digital_inputs: Vec<DigitalInput>
|
||||
@@ -19,7 +20,8 @@ pub struct InputState {
|
||||
pub virtual_buttons: HashMap<String, VirtualButton>,
|
||||
pub virtual_axes: HashMap<String, VirtualAxis>,
|
||||
input_events: HashSet<DigitalInputEvent>,
|
||||
pressed_buttons: HashSet<ScanCode>
|
||||
pressed_scan_codes: HashSet<ScanCode>,
|
||||
pressed_mouse_buttons: HashSet<MouseButton>
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
@@ -37,34 +39,51 @@ struct InputConfig {
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct InputConfigButton {
|
||||
name: String,
|
||||
scancode: u32,
|
||||
ctrl: Option<bool>
|
||||
scan_code: Option<u32>,
|
||||
mouse: Option<String>,
|
||||
ctrl: Option<bool>,
|
||||
shift: Option<bool>,
|
||||
alt: Option<bool>,
|
||||
logo: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct InputConfigAxis {
|
||||
name: String,
|
||||
scancode_positive: u32,
|
||||
scan_code_positive: u32,
|
||||
ctrl_positive: Option<bool>,
|
||||
scancode_negative: u32,
|
||||
scan_code_negative: u32,
|
||||
ctrl_negative: Option<bool>
|
||||
}
|
||||
|
||||
impl InputState {
|
||||
pub fn new(toml_path: &str) -> InputState {
|
||||
let mut state = InputState { virtual_buttons: HashMap::new(), virtual_axes: HashMap::new(),
|
||||
input_events: HashSet::new(), pressed_buttons: HashSet::new() };
|
||||
input_events: HashSet::new(), pressed_scan_codes: HashSet::new(), pressed_mouse_buttons: HashSet::new() };
|
||||
|
||||
let config: InputConfig = toml::from_slice(&fs::read(toml_path).expect("Failed to read input config!")).expect("Failed to parse input config!");
|
||||
|
||||
config.button.iter().for_each(|bn| {
|
||||
let modifiers = ModifiersState {
|
||||
shift: false,
|
||||
shift: bn.shift.is_some(),
|
||||
ctrl: bn.ctrl.is_some(),
|
||||
alt: false,
|
||||
logo: false
|
||||
alt: bn.alt.is_some(),
|
||||
logo: bn.logo.is_some()
|
||||
};
|
||||
let input = DigitalInput::Keyboard(KeyboardInput { scancode: bn.scancode, modifiers });
|
||||
let input = if let Some(scan_code) = bn.scan_code {
|
||||
DigitalInput::Keyboard(KeyboardInput { scan_code, modifiers })
|
||||
} else if let Some(button_name) = &bn.mouse {
|
||||
let button = match button_name.to_lowercase().as_str() {
|
||||
"left" => MouseButton::Left,
|
||||
"middle" => MouseButton::Middle,
|
||||
"right" => MouseButton::Right,
|
||||
other => MouseButton::Other(other.parse().expect(&format!("Unknown button: {:?}", other)))
|
||||
};
|
||||
DigitalInput::Mouse(MouseInput { button, modifiers })
|
||||
} else {
|
||||
panic!("No mouse or keyboard input for button {:?}", bn.name);
|
||||
};
|
||||
|
||||
if let Some(virtual_button) = state.virtual_buttons.get_mut(&bn.name) {
|
||||
virtual_button.digital_inputs.push(input);
|
||||
} else {
|
||||
@@ -86,8 +105,8 @@ impl InputState {
|
||||
logo: false
|
||||
};
|
||||
let axis = AxisInput::Digital(
|
||||
DigitalInput::Keyboard(KeyboardInput { scancode: a.scancode_positive, modifiers: modifiers_positive }),
|
||||
DigitalInput::Keyboard(KeyboardInput { scancode: a.scancode_negative, modifiers: modifiers_negative })
|
||||
DigitalInput::Keyboard(KeyboardInput { scan_code: a.scan_code_positive, modifiers: modifiers_positive }),
|
||||
DigitalInput::Keyboard(KeyboardInput { scan_code: a.scan_code_negative, modifiers: modifiers_negative })
|
||||
);
|
||||
if let Some(virtual_axis) = state.virtual_axes.get_mut(&a.name) {
|
||||
virtual_axis.axis_inputs.push(axis);
|
||||
@@ -168,35 +187,52 @@ impl InputState {
|
||||
|
||||
pub fn digital_input_pressed(self: &Self, digital_input: &DigitalInput) -> bool {
|
||||
match digital_input {
|
||||
DigitalInput::Keyboard(keyboard_input) =>
|
||||
self.pressed_buttons.contains(&keyboard_input.scancode)
|
||||
&& self.modifiers_are_pressed(keyboard_input.modifiers),
|
||||
DigitalInput::Mouse(_) => false
|
||||
DigitalInput::Keyboard(keyboard_input) => {
|
||||
self.pressed_scan_codes.contains(&keyboard_input.scan_code)
|
||||
&& self.modifiers_are_pressed(keyboard_input.modifiers)
|
||||
},
|
||||
DigitalInput::Mouse(mouse_input) => {
|
||||
self.pressed_mouse_buttons.contains(&mouse_input.button)
|
||||
&& self.modifiers_are_pressed(mouse_input.modifiers)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn modifiers_are_pressed(self: &Self, modifiers: ModifiersState) -> bool {
|
||||
(!modifiers.ctrl || self.pressed_buttons.contains(&29))
|
||||
&& (!modifiers.shift || self.pressed_buttons.contains(&42) || self.pressed_buttons.contains(&54))
|
||||
&& (!modifiers.alt || self.pressed_buttons.contains(&56))
|
||||
&& (!modifiers.logo || self.pressed_buttons.contains(&91) || self.pressed_buttons.contains(&92))
|
||||
(!modifiers.ctrl || self.pressed_scan_codes.contains(&29))
|
||||
&& (!modifiers.shift || self.pressed_scan_codes.contains(&42) || self.pressed_scan_codes.contains(&54))
|
||||
&& (!modifiers.alt || self.pressed_scan_codes.contains(&56))
|
||||
&& (!modifiers.logo || self.pressed_scan_codes.contains(&91) || self.pressed_scan_codes.contains(&92))
|
||||
}
|
||||
|
||||
fn digital_input_to_float(self: &Self, input: &DigitalInput) -> f32 {
|
||||
if self.digital_input_pressed(input) { 1.0 } else { 0.0 }
|
||||
}
|
||||
|
||||
pub fn on_keyboard_event(self: &mut Self, state: ElementState, scancode: ScanCode, modifiers: ModifiersState) {
|
||||
let input = DigitalInput::Keyboard(KeyboardInput { scancode, modifiers });
|
||||
|
||||
pub fn on_keyboard_event(self: &mut Self, state: ElementState, scan_code: ScanCode, modifiers: ModifiersState) {
|
||||
let input = DigitalInput::Keyboard(KeyboardInput { scan_code, modifiers });
|
||||
match state {
|
||||
ElementState::Pressed => {
|
||||
self.input_events.insert(DigitalInputEvent::Pressed(input));
|
||||
self.pressed_buttons.insert(scancode);
|
||||
self.pressed_scan_codes.insert(scan_code);
|
||||
},
|
||||
ElementState::Released => {
|
||||
self.input_events.insert(DigitalInputEvent::Released(input));
|
||||
self.pressed_buttons.remove(&scancode);
|
||||
self.pressed_scan_codes.remove(&scan_code);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn on_mouse_event(self: &mut Self, state: &ElementState, button: &MouseButton, modifiers: &ModifiersState) {
|
||||
let input = DigitalInput::Mouse(MouseInput { button: button.clone(), modifiers: modifiers.clone() });
|
||||
match state {
|
||||
ElementState::Pressed => {
|
||||
self.input_events.insert(DigitalInputEvent::Pressed(input));
|
||||
self.pressed_mouse_buttons.insert(button.clone());
|
||||
},
|
||||
ElementState::Released => {
|
||||
self.input_events.insert(DigitalInputEvent::Released(input));
|
||||
self.pressed_mouse_buttons.remove(button);
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -206,6 +242,14 @@ impl InputState {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn mods_to_string(modifiers: &ModifiersState) -> String {
|
||||
String::from_iter(
|
||||
vec!["shift", "ctrl", "alt", "logo"].iter()
|
||||
.zip(vec![modifiers.shift, modifiers.ctrl, modifiers.alt, modifiers.logo])
|
||||
.filter(|(&_name, state)| *state)
|
||||
.map(|(&name, _state)| name))
|
||||
}
|
||||
|
||||
pub enum AxisInput {
|
||||
Analog(AnalogInput),
|
||||
Digital(DigitalInput, DigitalInput),
|
||||
@@ -219,7 +263,7 @@ pub enum DigitalInput {
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Hash)]
|
||||
pub struct KeyboardInput {
|
||||
scancode: ScanCode,
|
||||
scan_code: ScanCode,
|
||||
modifiers: ModifiersState
|
||||
}
|
||||
|
||||
|
||||
28
src/main.rs
28
src/main.rs
@@ -1,12 +1,11 @@
|
||||
use winit::{Event, WindowEvent};
|
||||
use std::iter::FromIterator;
|
||||
use cgmath::{Matrix4, Rad, Point3, Vector3, Deg};
|
||||
|
||||
mod vulkan;
|
||||
use crate::vulkan::{GameData, Game, LinePoint};
|
||||
|
||||
mod input;
|
||||
use crate::input::{InputState};
|
||||
use crate::input::{InputState, mods_to_string};
|
||||
|
||||
mod config;
|
||||
use crate::config::LogConfig;
|
||||
@@ -63,23 +62,28 @@ impl Game for TestGame {
|
||||
match event {
|
||||
Event::WindowEvent { event: WindowEvent::KeyboardInput { device_id, input }, .. } => {
|
||||
if self.log_config.input {
|
||||
let mods = String::from_iter(
|
||||
vec!["shift", "ctrl", "alt", "logo"].iter()
|
||||
.zip(vec![input.modifiers.shift, input.modifiers.ctrl, input.modifiers.alt, input.modifiers.logo])
|
||||
.filter(|(&_name, state)| *state)
|
||||
.map(|(&name, _state)| name));
|
||||
let mods = mods_to_string(&input.modifiers);
|
||||
if mods.len() > 0 {
|
||||
println!("Keyboard {:?} input {:?} {:?} + {:?}", device_id, input.state, &mods, input.scancode)
|
||||
println!("Keyboard {:?} {:?} {:?} + {:?}", device_id, input.state, &mods, input.scancode)
|
||||
} else {
|
||||
println!("Keyboard {:?} input {:?} {:?}", device_id, input.state, input.scancode)
|
||||
println!("Keyboard {:?} {:?} {:?}", device_id, input.state, input.scancode)
|
||||
}
|
||||
}
|
||||
|
||||
self.input.on_keyboard_event(input.state, input.scancode, input.modifiers);
|
||||
},
|
||||
// Event::WindowEvent { event: WindowEvent::MouseInput { device_id, state, button, modifiers }, .. } => {
|
||||
//
|
||||
// }
|
||||
Event::WindowEvent { event: WindowEvent::MouseInput { device_id, state, button, modifiers }, .. } => {
|
||||
if self.log_config.input {
|
||||
let mods = mods_to_string(modifiers);
|
||||
if mods.len() > 0 {
|
||||
println!("Mouse {:?} {:?} {:?} + {:?}", device_id, state, &mods, button)
|
||||
} else {
|
||||
println!("Mouse {:?} {:?} {:?}", device_id, state, button)
|
||||
}
|
||||
}
|
||||
|
||||
self.input.on_mouse_event(state, button, modifiers);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user