mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
support removing key bindings
This commit is contained in:
parent
e12390b08b
commit
71d2be5f76
@ -30,6 +30,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Worldgen wildlife density modifier in features.ron
|
||||
- Rivers now make ambient sounds (again)
|
||||
- Added a setting to see own speech bubbles
|
||||
- Added an option to allow players to remove keybindings
|
||||
|
||||
### Changed
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
"main.connecting": "Connecting",
|
||||
"main.creating_world": "Creating world",
|
||||
"main.tip": "Tip:",
|
||||
"main.unbound_key_tip": "unbound",
|
||||
|
||||
// Welcome notice that appears the first time Veloren is started
|
||||
"main.notice": r#"Welcome to the alpha version of Veloren!
|
||||
|
@ -22,6 +22,7 @@ widget_ids! {
|
||||
window_r,
|
||||
window_scrollbar,
|
||||
reset_controls_button,
|
||||
keybinding_mode_button,
|
||||
controls_alignment_rectangle,
|
||||
controls_texts[],
|
||||
controls_buttons[],
|
||||
@ -178,7 +179,11 @@ impl<'a> Widget for Controls<'a> {
|
||||
.set(button_id, ui)
|
||||
.was_clicked()
|
||||
{
|
||||
if self.global_state.window.keybinding_mode {
|
||||
events.push(ChangeBinding(game_input));
|
||||
} else {
|
||||
events.push(RemoveBinding(game_input));
|
||||
}
|
||||
}
|
||||
// Set the previous id to the current one for the next cycle
|
||||
previous_element_id = Some(text_id);
|
||||
@ -204,6 +209,27 @@ impl<'a> Widget for Controls<'a> {
|
||||
previous_element_id = Some(state.ids.reset_controls_button)
|
||||
}
|
||||
|
||||
let toggle_widget = Button::new()
|
||||
.label(if self.global_state.window.keybinding_mode {
|
||||
"remap"
|
||||
} else {
|
||||
"clear"
|
||||
})
|
||||
.label_color(TEXT_COLOR)
|
||||
.label_font_id(self.fonts.cyri.conrod_id)
|
||||
.label_font_size(self.fonts.cyri.scale(15))
|
||||
.w(100.0)
|
||||
.rgba(0.0, 0.0, 0.0, 0.0)
|
||||
.border_rgba(0.0, 0.0, 0.0, 255.0)
|
||||
.label_y(Relative::Scalar(1.0));
|
||||
if toggle_widget
|
||||
.top_right_with_margins_on(state.ids.window, 10.0, 15.0)
|
||||
.set(state.ids.keybinding_mode_button, ui)
|
||||
.was_clicked()
|
||||
{
|
||||
events.push(ToggleKeybindingMode);
|
||||
}
|
||||
|
||||
// Add an empty text widget to simulate some bottom margin, because conrod sucks
|
||||
if let Some(prev_id) = previous_element_id {
|
||||
Rectangle::fill_with([1.0, 1.0], color::TRANSPARENT)
|
||||
|
@ -114,8 +114,14 @@ impl Screen {
|
||||
if let Ok(game_input) = GameInput::from_str(&tip[start + 1..end]) {
|
||||
new_tip.push_str(&tip[last_index..start]);
|
||||
new_tip.push_str(
|
||||
controls.keybindings[&game_input]
|
||||
.display_string(key_layout)
|
||||
match controls.keybindings.get(&game_input) {
|
||||
Some(Some(key_mouse)) => {
|
||||
key_mouse.display_string(key_layout)
|
||||
},
|
||||
Some(None) => i18n.get("main.unbound_key_tip").to_string(),
|
||||
None => ControlSettings::default_binding(game_input)
|
||||
.display_string(key_layout),
|
||||
}
|
||||
.as_str(),
|
||||
);
|
||||
last_index = end + 1;
|
||||
|
@ -39,6 +39,8 @@ pub enum Chat {
|
||||
#[derive(Clone)]
|
||||
pub enum Control {
|
||||
ChangeBinding(GameInput),
|
||||
RemoveBinding(GameInput),
|
||||
ToggleKeybindingMode,
|
||||
ResetKeyBindings,
|
||||
}
|
||||
#[derive(Clone)]
|
||||
@ -249,6 +251,12 @@ impl SettingsChange {
|
||||
Control::ChangeBinding(game_input) => {
|
||||
global_state.window.set_keybinding_mode(game_input);
|
||||
},
|
||||
Control::RemoveBinding(game_input) => {
|
||||
settings.controls.remove_binding(game_input);
|
||||
},
|
||||
Control::ToggleKeybindingMode => {
|
||||
global_state.window.toggle_keybinding_mode();
|
||||
},
|
||||
Control::ResetKeyBindings => {
|
||||
settings.controls = ControlSettings::default();
|
||||
},
|
||||
|
@ -8,16 +8,16 @@ use winit::event::{MouseButton, VirtualKeyCode};
|
||||
// post-deserializing the inverse_keybindings hashmap
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct ControlSettingsSerde {
|
||||
keybindings: HashMap<GameInput, KeyMouse>,
|
||||
keybindings: HashMap<GameInput, Option<KeyMouse>>,
|
||||
}
|
||||
|
||||
impl From<ControlSettings> for ControlSettingsSerde {
|
||||
fn from(control_settings: ControlSettings) -> Self {
|
||||
let mut user_bindings: HashMap<GameInput, KeyMouse> = HashMap::new();
|
||||
let mut user_bindings: HashMap<GameInput, Option<KeyMouse>> = HashMap::new();
|
||||
// Do a delta between default() ControlSettings and the argument, and let
|
||||
// keybindings be only the custom keybindings chosen by the user.
|
||||
for (k, v) in control_settings.keybindings {
|
||||
if ControlSettings::default_binding(k) != v {
|
||||
if Some(ControlSettings::default_binding(k)) != v {
|
||||
// Keybinding chosen by the user
|
||||
user_bindings.insert(k, v);
|
||||
}
|
||||
@ -32,7 +32,7 @@ impl From<ControlSettings> for ControlSettingsSerde {
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
#[serde(from = "ControlSettingsSerde", into = "ControlSettingsSerde")]
|
||||
pub struct ControlSettings {
|
||||
pub keybindings: HashMap<GameInput, KeyMouse>,
|
||||
pub keybindings: HashMap<GameInput, Option<KeyMouse>>,
|
||||
pub inverse_keybindings: HashMap<KeyMouse, HashSet<GameInput>>, // used in event loop
|
||||
}
|
||||
|
||||
@ -40,8 +40,11 @@ impl From<ControlSettingsSerde> for ControlSettings {
|
||||
fn from(control_serde: ControlSettingsSerde) -> Self {
|
||||
let user_keybindings = control_serde.keybindings;
|
||||
let mut control_settings = ControlSettings::default();
|
||||
for (k, v) in user_keybindings {
|
||||
control_settings.modify_binding(k, v);
|
||||
for (k, maybe_v) in user_keybindings {
|
||||
match maybe_v {
|
||||
Some(v) => control_settings.modify_binding(k, v),
|
||||
None => control_settings.remove_binding(k),
|
||||
}
|
||||
}
|
||||
control_settings
|
||||
}
|
||||
@ -58,8 +61,19 @@ const MIDDLE_CLICK_KEY: KeyMouse = KeyMouse::Key(VirtualKeyCode::Grave);
|
||||
const MIDDLE_CLICK_KEY: KeyMouse = KeyMouse::Mouse(MouseButton::Middle);
|
||||
|
||||
impl ControlSettings {
|
||||
pub fn remove_binding(&mut self, game_input: GameInput) {
|
||||
if let Some(inverse) = self
|
||||
.keybindings
|
||||
.insert(game_input, None)
|
||||
.flatten()
|
||||
.and_then(|key_mouse| self.inverse_keybindings.get_mut(&key_mouse))
|
||||
{
|
||||
inverse.remove(&game_input);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_binding(&self, game_input: GameInput) -> Option<KeyMouse> {
|
||||
self.keybindings.get(&game_input).copied()
|
||||
self.keybindings.get(&game_input).copied().flatten()
|
||||
}
|
||||
|
||||
pub fn get_associated_game_inputs(&self, key_mouse: &KeyMouse) -> Option<&HashSet<GameInput>> {
|
||||
@ -67,7 +81,7 @@ impl ControlSettings {
|
||||
}
|
||||
|
||||
pub fn insert_binding(&mut self, game_input: GameInput, key_mouse: KeyMouse) {
|
||||
self.keybindings.insert(game_input, key_mouse);
|
||||
self.keybindings.insert(game_input, Some(key_mouse));
|
||||
self.inverse_keybindings
|
||||
.entry(key_mouse)
|
||||
.or_default()
|
||||
@ -89,7 +103,7 @@ impl ControlSettings {
|
||||
.or_default()
|
||||
.insert(game_input);
|
||||
// For the GameInput->KeyMouse hashmap, just overwrite the value
|
||||
self.keybindings.insert(game_input, key_mouse);
|
||||
self.keybindings.insert(game_input, Some(key_mouse));
|
||||
}
|
||||
|
||||
/// Return true if this key is used for multiple GameInputs that aren't
|
||||
|
@ -385,6 +385,8 @@ pub struct Window {
|
||||
needs_refresh_resize: bool,
|
||||
keypress_map: HashMap<GameInput, winit::event::ElementState>,
|
||||
pub remapping_keybindings: Option<GameInput>,
|
||||
//true for remapping keybinds, false for clearing keybinds
|
||||
pub keybinding_mode: bool,
|
||||
events: Vec<Event>,
|
||||
pub focused: bool,
|
||||
gilrs: Option<Gilrs>,
|
||||
@ -486,6 +488,7 @@ impl Window {
|
||||
needs_refresh_resize: false,
|
||||
keypress_map,
|
||||
remapping_keybindings: None,
|
||||
keybinding_mode: true,
|
||||
events: Vec::new(),
|
||||
focused: true,
|
||||
gilrs,
|
||||
@ -1329,6 +1332,8 @@ impl Window {
|
||||
self.remapping_keybindings = Some(game_input);
|
||||
}
|
||||
|
||||
pub fn toggle_keybinding_mode(&mut self) { self.keybinding_mode = !self.keybinding_mode; }
|
||||
|
||||
pub fn window(&self) -> &winit::window::Window { &self.window }
|
||||
|
||||
pub fn modifiers(&self) -> winit::event::ModifiersState { self.modifiers }
|
||||
|
Loading…
Reference in New Issue
Block a user