//! Default editor input bindings + the action-name constants the bindings //! UI and any debug overlay address. //! //! Living in the editor library (not the binary) so the Stage-7 //! [`InputBindings`](crate::shell::Shell) preferences page and any future //! editor module can re-register or remap the same actions without //! depending on the binary's private module. use oxide_engine::input::{ActionMap, AxisBinding, Binding}; use oxide_engine::winit::keyboard::KeyCode; /// The settings-section name under which the editor's /// [`ActionOverrides`](oxide_engine::input::ActionOverrides) are persisted. /// /// The shell registers this section automatically in /// [`EditorState::new`](crate::state::EditorState::new); UI code that wants /// to refresh the section after a binding change addresses it by this name. pub const SETTINGS_SECTION: &str = "input.bindings"; /// Stable action names addressed throughout the editor — the bindings /// preferences page, the camera input poll in the runner, and any future /// debug overlay all reference these strings. pub mod action { /// Button: toggle between orbit and flythrough viewport cameras. pub const TOGGLE_FLYTHROUGH: &str = "editor.camera.toggle_flythrough"; /// Button (held): accelerate flythrough translation while engaged. pub const SPRINT: &str = "editor.camera.sprint"; /// 1D axis: strafe right (+) / strafe left (−) in flythrough mode. pub const MOVE_RIGHT: &str = "editor.camera.move_right"; /// 1D axis: forward (+) / back (−) in flythrough mode. pub const MOVE_FORWARD: &str = "editor.camera.move_forward"; /// 1D axis: ascend (+) / descend (−) in flythrough mode. pub const MOVE_UP: &str = "editor.camera.move_up"; /// Button: switch the transform gizmo to Translate mode (orbit camera only). pub const GIZMO_TRANSLATE: &str = "editor.gizmo.translate"; /// Button: switch the transform gizmo to Rotate mode (orbit camera only). pub const GIZMO_ROTATE: &str = "editor.gizmo.rotate"; /// Button: switch the transform gizmo to Scale mode (orbit camera only). pub const GIZMO_SCALE: &str = "editor.gizmo.scale"; } /// Registers the editor's default action set on `actions`. Defaults follow /// the DCC-tools convention (WASD + QE, Shift sprint, F toggles the /// flythrough camera) so users coming from Blender / Maya / Unity feel at /// home. /// /// Idempotent on the action names — re-registering preserves any user- /// remapped current bindings while refreshing the defaults that the /// "Restore defaults" button reverts to. pub fn register_defaults(actions: &mut ActionMap) { actions .register(action::TOGGLE_FLYTHROUGH, [Binding::Key(KeyCode::KeyF)]) .register( action::SPRINT, [ Binding::Key(KeyCode::ShiftLeft), Binding::Key(KeyCode::ShiftRight), ], ) .register_axis( action::MOVE_RIGHT, AxisBinding::new([Binding::Key(KeyCode::KeyD)], [Binding::Key(KeyCode::KeyA)]), ) .register_axis( action::MOVE_FORWARD, AxisBinding::new([Binding::Key(KeyCode::KeyW)], [Binding::Key(KeyCode::KeyS)]), ) .register_axis( action::MOVE_UP, AxisBinding::new([Binding::Key(KeyCode::KeyE)], [Binding::Key(KeyCode::KeyQ)]), ) // Gizmo tool hotkeys (W/E/R). These share physical keys with // flythrough movement, so the host gates them on the camera being // in orbit mode — in flythrough W/E move the camera, in orbit // they switch the gizmo tool. .register(action::GIZMO_TRANSLATE, [Binding::Key(KeyCode::KeyW)]) .register(action::GIZMO_ROTATE, [Binding::Key(KeyCode::KeyE)]) .register(action::GIZMO_SCALE, [Binding::Key(KeyCode::KeyR)]); } #[cfg(test)] mod tests { use super::*; #[test] fn defaults_register_every_advertised_action() { let mut actions = ActionMap::new(); register_defaults(&mut actions); assert!(actions.has(action::TOGGLE_FLYTHROUGH)); assert!(actions.has(action::SPRINT)); assert!(actions.has_axis(action::MOVE_RIGHT)); assert!(actions.has_axis(action::MOVE_FORWARD)); assert!(actions.has_axis(action::MOVE_UP)); } #[test] fn defaults_are_idempotent_and_preserve_remaps() { let mut actions = ActionMap::new(); register_defaults(&mut actions); // User remaps Toggle to Tab. actions.set_bindings(action::TOGGLE_FLYTHROUGH, vec![Binding::Key(KeyCode::Tab)]); // Re-running register_defaults must not stomp the user's remap. register_defaults(&mut actions); assert_eq!( actions.bindings(action::TOGGLE_FLYTHROUGH), &[Binding::Key(KeyCode::Tab)] ); // But the defaults — what "Restore defaults" reverts to — are still F. assert_eq!( actions.defaults(action::TOGGLE_FLYTHROUGH), &[Binding::Key(KeyCode::KeyF)] ); } }