Import Oxide engine (Stages 0–10) under MIT license
Full project snapshot migrated to new Gitea remote without history: engine, editor, physics, script, examples, tests, docs, and assets. Relicensed from GPLv3 to MIT and updated repo URLs. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
//! 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)]
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user