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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
//! Bindings module, which is a key combination that does something when pressed.
use super::Button;
use raylib::RaylibHandle;
use serde::{Deserialize, Serialize};
/// Binding struct, which holds any number of buttons (keyboard and mouse may be mixed, if desired)
#[derive(Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct Binding {
buttons: Vec<Button>,
}
impl Binding {
/// Create a new binding from a range of buttons. The button order does not matter, but at least
/// one button must be supplied.
pub fn new(buttons: Vec<Button>) -> Self {
if buttons.is_empty() {
panic!("Tried to create a binding without any keys.");
}
Self { buttons }
}
/// Returns `true` if only mouse buttons are present in this binding, otherwise false.
pub fn mouse_only(&self) -> bool {
for button in &self.buttons {
match button {
Button::Mouse(_) => continue,
_ => return false,
}
}
true
}
/// Returns `true` if only keyboard buttons are present in this binding, otherwise false.
pub fn keyboard_only(&self) -> bool {
for button in &self.buttons {
match button {
Button::Scancode(_) | Button::Text(_) => continue,
_ => return false,
}
}
true
}
/// Returns `true` if at least one mouse button is required for this binding to work.
pub fn has_mouse_component(&self) -> bool {
self.buttons.iter().any(|b| {
if let Button::Mouse(_) = b {
true
} else {
false
}
})
}
/// Returns `true` if at least one keyboard button is required for this binding to work.
pub fn has_keyboard_component(&self) -> bool {
self.buttons.iter().any(|b| match b {
Button::Scancode(_) | Button::Text(_) => true,
_ => false,
})
}
/// Checks if this binding was pressed this frame. Heavily dependent on input struct working
/// correctly.
pub(super) fn is_pressed(
&self,
allow_mouse: bool,
allow_keyboard: bool,
text: &str,
rl: &RaylibHandle,
) -> bool {
let mut distinct_press = false;
for button in &self.buttons {
match *button {
Button::Mouse(mouse_button) => {
if !allow_mouse || !rl.is_mouse_button_down(mouse_button.into()) {
return false;
}
/* Check if the button has been pressed in this frame exactly.
* This prevents activating the same keybinding every frame
* while the buttons are being held down.
*/
if rl.is_mouse_button_pressed(mouse_button.into()) {
distinct_press = true;
}
}
Button::Scancode(code) => {
if !allow_keyboard || !rl.is_key_down(code.into()) {
return false;
}
// Check the same as with the mouse button.
if rl.is_key_pressed(code.into()) {
distinct_press = true;
}
}
Button::Text(c) => {
if !allow_keyboard || !text.contains(c) {
return false;
}
// Always distinct, since on triggering, the text is cleared.
distinct_press = true;
}
}
}
distinct_press
}
}
impl From<Button> for Binding {
fn from(button: Button) -> Self {
Self {
buttons: vec![button],
}
}
}
|