mirror of
https://github.com/FyroxEngine/Fyrox.git
synced 2026-10-12 02:02:20 +00:00
+52
-66
@@ -1,3 +1,4 @@
|
||||
use crate::settings::keys::KeyBindings;
|
||||
use crate::{settings::camera::CameraSettings, utils::built_in_skybox, SceneCameraSettings};
|
||||
use fyrox::{
|
||||
core::{
|
||||
@@ -201,80 +202,65 @@ impl CameraController {
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn on_key_up(&mut self, key: KeyCode) -> bool {
|
||||
match key {
|
||||
KeyCode::W => {
|
||||
self.move_forward = false;
|
||||
true
|
||||
}
|
||||
KeyCode::S => {
|
||||
self.move_backward = false;
|
||||
true
|
||||
}
|
||||
KeyCode::A => {
|
||||
self.move_left = false;
|
||||
true
|
||||
}
|
||||
KeyCode::D => {
|
||||
self.move_right = false;
|
||||
true
|
||||
}
|
||||
KeyCode::Space | KeyCode::Q => {
|
||||
self.move_up = false;
|
||||
true
|
||||
}
|
||||
KeyCode::E => {
|
||||
self.move_down = false;
|
||||
true
|
||||
}
|
||||
KeyCode::LControl | KeyCode::LShift => {
|
||||
self.speed_factor = 1.0;
|
||||
true
|
||||
}
|
||||
_ => false,
|
||||
pub fn on_key_up(&mut self, key_bindings: &KeyBindings, key: KeyCode) -> bool {
|
||||
if key_bindings.move_forward == key {
|
||||
self.move_forward = false;
|
||||
true
|
||||
} else if key_bindings.move_back == key {
|
||||
self.move_backward = false;
|
||||
true
|
||||
} else if key_bindings.move_left == key {
|
||||
self.move_left = false;
|
||||
true
|
||||
} else if key_bindings.move_right == key {
|
||||
self.move_right = false;
|
||||
true
|
||||
} else if key_bindings.move_up == key {
|
||||
self.move_up = false;
|
||||
true
|
||||
} else if key_bindings.move_down == key {
|
||||
self.move_down = false;
|
||||
true
|
||||
} else if key_bindings.slow_down == key || key_bindings.speed_up == key {
|
||||
self.speed_factor = 1.0;
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn on_key_down(&mut self, key: KeyCode) -> bool {
|
||||
pub fn on_key_down(&mut self, key_bindings: &KeyBindings, key: KeyCode) -> bool {
|
||||
if !self.rotate || self.drag {
|
||||
return false;
|
||||
}
|
||||
|
||||
match key {
|
||||
KeyCode::W => {
|
||||
self.move_forward = true;
|
||||
true
|
||||
}
|
||||
KeyCode::S => {
|
||||
self.move_backward = true;
|
||||
true
|
||||
}
|
||||
KeyCode::A => {
|
||||
self.move_left = true;
|
||||
true
|
||||
}
|
||||
KeyCode::D => {
|
||||
self.move_right = true;
|
||||
true
|
||||
}
|
||||
KeyCode::Space | KeyCode::Q => {
|
||||
self.move_up = true;
|
||||
true
|
||||
}
|
||||
KeyCode::E => {
|
||||
self.move_down = true;
|
||||
true
|
||||
}
|
||||
KeyCode::LControl => {
|
||||
self.speed_factor = 2.0;
|
||||
true
|
||||
}
|
||||
KeyCode::LShift => {
|
||||
self.speed_factor = 0.25;
|
||||
true
|
||||
}
|
||||
_ => false,
|
||||
if key_bindings.move_forward == key {
|
||||
self.move_forward = true;
|
||||
true
|
||||
} else if key_bindings.move_back == key {
|
||||
self.move_backward = true;
|
||||
true
|
||||
} else if key_bindings.move_left == key {
|
||||
self.move_left = true;
|
||||
true
|
||||
} else if key_bindings.move_right == key {
|
||||
self.move_right = true;
|
||||
true
|
||||
} else if key_bindings.move_up == key {
|
||||
self.move_up = true;
|
||||
true
|
||||
} else if key_bindings.move_down == key {
|
||||
self.move_down = true;
|
||||
true
|
||||
} else if key_bindings.speed_up == key {
|
||||
self.speed_factor = 2.0;
|
||||
true
|
||||
} else if key_bindings.slow_down == key {
|
||||
self.speed_factor = 0.25;
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+82
-92
@@ -97,7 +97,8 @@ use fyrox::{
|
||||
file_browser::{FileBrowserMode, FileSelectorBuilder, FileSelectorMessage, Filter},
|
||||
formatted_text::WrapMode,
|
||||
grid::{Column, GridBuilder, Row},
|
||||
message::{KeyCode, MessageDirection, UiMessage},
|
||||
key::HotKey,
|
||||
message::{MessageDirection, UiMessage},
|
||||
messagebox::{MessageBoxBuilder, MessageBoxButtons, MessageBoxMessage, MessageBoxResult},
|
||||
ttf::Font,
|
||||
widget::{WidgetBuilder, WidgetMessage},
|
||||
@@ -980,107 +981,96 @@ impl Editor {
|
||||
let engine = &mut self.engine;
|
||||
|
||||
if let Some(WidgetMessage::KeyDown(key)) = message.data() {
|
||||
match key {
|
||||
KeyCode::Y if modifiers.control => {
|
||||
sender.send(Message::RedoSceneCommand).unwrap();
|
||||
}
|
||||
KeyCode::Z if modifiers.control => {
|
||||
sender.send(Message::UndoSceneCommand).unwrap();
|
||||
}
|
||||
KeyCode::Key1 => {
|
||||
sender
|
||||
.send(Message::SetInteractionMode(InteractionModeKind::Select))
|
||||
.unwrap();
|
||||
}
|
||||
KeyCode::Key2 => {
|
||||
sender
|
||||
.send(Message::SetInteractionMode(InteractionModeKind::Move))
|
||||
.unwrap();
|
||||
}
|
||||
KeyCode::Key3 => {
|
||||
sender
|
||||
.send(Message::SetInteractionMode(InteractionModeKind::Rotate))
|
||||
.unwrap();
|
||||
}
|
||||
KeyCode::Key4 => {
|
||||
sender
|
||||
.send(Message::SetInteractionMode(InteractionModeKind::Scale))
|
||||
.unwrap();
|
||||
}
|
||||
KeyCode::Key5 => {
|
||||
sender
|
||||
.send(Message::SetInteractionMode(InteractionModeKind::Navmesh))
|
||||
.unwrap();
|
||||
}
|
||||
KeyCode::Key6 => {
|
||||
sender
|
||||
.send(Message::SetInteractionMode(InteractionModeKind::Terrain))
|
||||
.unwrap();
|
||||
}
|
||||
KeyCode::L if modifiers.control => {
|
||||
sender.send(Message::OpenLoadSceneDialog).unwrap();
|
||||
}
|
||||
KeyCode::S if modifiers.control => {
|
||||
if let Some(scene) = self.scene.as_ref() {
|
||||
if let Some(path) = scene.path.as_ref() {
|
||||
self.message_sender
|
||||
.send(Message::SaveScene(path.clone()))
|
||||
.unwrap();
|
||||
} else {
|
||||
// Scene wasn't saved yet, open Save As dialog.
|
||||
engine
|
||||
.user_interface
|
||||
.send_message(WindowMessage::open_modal(
|
||||
self.save_file_selector,
|
||||
MessageDirection::ToWidget,
|
||||
true,
|
||||
));
|
||||
}
|
||||
let hot_key = HotKey::Some {
|
||||
code: *key,
|
||||
modifiers,
|
||||
};
|
||||
let key_bindings = &self.settings.key_bindings;
|
||||
|
||||
if hot_key == key_bindings.redo {
|
||||
sender.send(Message::RedoSceneCommand).unwrap();
|
||||
} else if hot_key == key_bindings.undo {
|
||||
sender.send(Message::UndoSceneCommand).unwrap();
|
||||
} else if hot_key == key_bindings.enable_select_mode {
|
||||
sender
|
||||
.send(Message::SetInteractionMode(InteractionModeKind::Select))
|
||||
.unwrap();
|
||||
} else if hot_key == key_bindings.enable_move_mode {
|
||||
sender
|
||||
.send(Message::SetInteractionMode(InteractionModeKind::Move))
|
||||
.unwrap();
|
||||
} else if hot_key == key_bindings.enable_rotate_mode {
|
||||
sender
|
||||
.send(Message::SetInteractionMode(InteractionModeKind::Rotate))
|
||||
.unwrap();
|
||||
} else if hot_key == key_bindings.enable_scale_mode {
|
||||
sender
|
||||
.send(Message::SetInteractionMode(InteractionModeKind::Scale))
|
||||
.unwrap();
|
||||
} else if hot_key == key_bindings.enable_navmesh_mode {
|
||||
sender
|
||||
.send(Message::SetInteractionMode(InteractionModeKind::Navmesh))
|
||||
.unwrap();
|
||||
} else if hot_key == key_bindings.enable_terrain_mode {
|
||||
sender
|
||||
.send(Message::SetInteractionMode(InteractionModeKind::Terrain))
|
||||
.unwrap();
|
||||
} else if hot_key == key_bindings.load_scene {
|
||||
sender.send(Message::OpenLoadSceneDialog).unwrap();
|
||||
} else if hot_key == key_bindings.save_scene {
|
||||
if let Some(scene) = self.scene.as_ref() {
|
||||
if let Some(path) = scene.path.as_ref() {
|
||||
self.message_sender
|
||||
.send(Message::SaveScene(path.clone()))
|
||||
.unwrap();
|
||||
} else {
|
||||
// Scene wasn't saved yet, open Save As dialog.
|
||||
engine
|
||||
.user_interface
|
||||
.send_message(WindowMessage::open_modal(
|
||||
self.save_file_selector,
|
||||
MessageDirection::ToWidget,
|
||||
true,
|
||||
));
|
||||
}
|
||||
}
|
||||
KeyCode::C if modifiers.control => {
|
||||
if let Some(editor_scene) = self.scene.as_mut() {
|
||||
if let Selection::Graph(graph_selection) = &editor_scene.selection {
|
||||
editor_scene.clipboard.fill_from_selection(
|
||||
graph_selection,
|
||||
editor_scene.scene,
|
||||
engine,
|
||||
);
|
||||
}
|
||||
} else if hot_key == key_bindings.copy_selection {
|
||||
if let Some(editor_scene) = self.scene.as_mut() {
|
||||
if let Selection::Graph(graph_selection) = &editor_scene.selection {
|
||||
editor_scene.clipboard.fill_from_selection(
|
||||
graph_selection,
|
||||
editor_scene.scene,
|
||||
engine,
|
||||
);
|
||||
}
|
||||
}
|
||||
KeyCode::V if modifiers.control => {
|
||||
if let Some(editor_scene) = self.scene.as_mut() {
|
||||
if !editor_scene.clipboard.is_empty() {
|
||||
} else if hot_key == key_bindings.paste {
|
||||
if let Some(editor_scene) = self.scene.as_mut() {
|
||||
if !editor_scene.clipboard.is_empty() {
|
||||
sender
|
||||
.send(Message::do_scene_command(PasteCommand::new(
|
||||
engine.scenes[editor_scene.scene].graph.get_root(),
|
||||
)))
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
} else if hot_key == key_bindings.new_scene {
|
||||
sender.send(Message::NewScene).unwrap();
|
||||
} else if hot_key == key_bindings.close_scene {
|
||||
sender.send(Message::CloseScene).unwrap();
|
||||
} else if hot_key == key_bindings.remove_selection {
|
||||
if let Some(editor_scene) = self.scene.as_mut() {
|
||||
if !editor_scene.selection.is_empty() {
|
||||
if let Selection::Graph(_) = editor_scene.selection {
|
||||
sender
|
||||
.send(Message::do_scene_command(PasteCommand::new(
|
||||
engine.scenes[editor_scene.scene].graph.get_root(),
|
||||
.send(Message::DoSceneCommand(make_delete_selection_command(
|
||||
editor_scene,
|
||||
engine,
|
||||
)))
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
KeyCode::N if modifiers.control => {
|
||||
sender.send(Message::NewScene).unwrap();
|
||||
}
|
||||
KeyCode::Q if modifiers.control => {
|
||||
sender.send(Message::CloseScene).unwrap();
|
||||
}
|
||||
KeyCode::Delete => {
|
||||
if let Some(editor_scene) = self.scene.as_mut() {
|
||||
if !editor_scene.selection.is_empty() {
|
||||
if let Selection::Graph(_) = editor_scene.selection {
|
||||
sender
|
||||
.send(Message::DoSceneCommand(make_delete_selection_command(
|
||||
editor_scene,
|
||||
engine,
|
||||
)))
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
use crate::{
|
||||
camera::PickingOptions, gui::make_dropdown_list_option,
|
||||
gui::make_dropdown_list_option_with_height, load_image, utils::enable_widget, AddModelCommand,
|
||||
AssetItem, AssetKind, BuildProfile, ChangeSelectionCommand, CommandGroup, DropdownListBuilder,
|
||||
EditorScene, GameEngine, GraphSelection, InteractionMode, InteractionModeKind, Message, Mode,
|
||||
SceneCommand, Selection, SetMeshTextureCommand, Settings,
|
||||
gui::make_dropdown_list_option_with_height, load_image, settings::keys::KeyBindings,
|
||||
utils::enable_widget, AddModelCommand, AssetItem, AssetKind, BuildProfile,
|
||||
ChangeSelectionCommand, CommandGroup, DropdownListBuilder, EditorScene, GameEngine,
|
||||
GraphSelection, InteractionMode, InteractionModeKind, Message, Mode, SceneCommand, Selection,
|
||||
SetMeshTextureCommand, Settings,
|
||||
};
|
||||
use fyrox::{
|
||||
core::{
|
||||
@@ -555,12 +556,24 @@ impl SceneViewer {
|
||||
self.on_mouse_move(pos, editor_scene, interaction_mode, engine, settings)
|
||||
}
|
||||
WidgetMessage::KeyUp(key) => {
|
||||
if self.on_key_up(key, editor_scene, interaction_mode, engine) {
|
||||
if self.on_key_up(
|
||||
key,
|
||||
editor_scene,
|
||||
interaction_mode,
|
||||
engine,
|
||||
&settings.key_bindings,
|
||||
) {
|
||||
message.set_handled(true);
|
||||
}
|
||||
}
|
||||
WidgetMessage::KeyDown(key) => {
|
||||
if self.on_key_down(key, editor_scene, interaction_mode, engine) {
|
||||
if self.on_key_down(
|
||||
key,
|
||||
editor_scene,
|
||||
interaction_mode,
|
||||
engine,
|
||||
&settings.key_bindings,
|
||||
) {
|
||||
message.set_handled(true);
|
||||
}
|
||||
}
|
||||
@@ -731,8 +744,9 @@ impl SceneViewer {
|
||||
editor_scene: &mut EditorScene,
|
||||
active_interaction_mode: Option<&mut Box<dyn InteractionMode>>,
|
||||
engine: &mut Engine,
|
||||
key_bindings: &KeyBindings,
|
||||
) -> bool {
|
||||
if editor_scene.camera_controller.on_key_up(key) {
|
||||
if editor_scene.camera_controller.on_key_up(key_bindings, key) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -752,8 +766,12 @@ impl SceneViewer {
|
||||
editor_scene: &mut EditorScene,
|
||||
active_interaction_mode: Option<&mut Box<dyn InteractionMode>>,
|
||||
engine: &mut Engine,
|
||||
key_bindings: &KeyBindings,
|
||||
) -> bool {
|
||||
if editor_scene.camera_controller.on_key_down(key) {
|
||||
if editor_scene
|
||||
.camera_controller
|
||||
.on_key_down(key_bindings, key)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
use fyrox::{
|
||||
core::reflect::prelude::*,
|
||||
gui::{
|
||||
key::{HotKey, KeyBinding},
|
||||
message::KeyCode,
|
||||
},
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Deserialize, Serialize, PartialEq, Clone, Debug, Reflect)]
|
||||
pub struct KeyBindings {
|
||||
pub move_forward: KeyBinding,
|
||||
pub move_back: KeyBinding,
|
||||
pub move_left: KeyBinding,
|
||||
pub move_right: KeyBinding,
|
||||
pub move_up: KeyBinding,
|
||||
pub move_down: KeyBinding,
|
||||
pub speed_up: KeyBinding,
|
||||
pub slow_down: KeyBinding,
|
||||
|
||||
pub undo: HotKey,
|
||||
pub redo: HotKey,
|
||||
pub enable_select_mode: HotKey,
|
||||
pub enable_move_mode: HotKey,
|
||||
pub enable_rotate_mode: HotKey,
|
||||
pub enable_scale_mode: HotKey,
|
||||
pub enable_navmesh_mode: HotKey,
|
||||
pub enable_terrain_mode: HotKey,
|
||||
pub save_scene: HotKey,
|
||||
pub load_scene: HotKey,
|
||||
pub copy_selection: HotKey,
|
||||
pub paste: HotKey,
|
||||
pub new_scene: HotKey,
|
||||
pub close_scene: HotKey,
|
||||
pub remove_selection: HotKey,
|
||||
}
|
||||
|
||||
impl Default for KeyBindings {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
move_forward: KeyBinding::from_key_code(KeyCode::W),
|
||||
move_back: KeyBinding::from_key_code(KeyCode::S),
|
||||
move_left: KeyBinding::from_key_code(KeyCode::A),
|
||||
move_right: KeyBinding::from_key_code(KeyCode::D),
|
||||
move_up: KeyBinding::from_key_code(KeyCode::Q),
|
||||
move_down: KeyBinding::from_key_code(KeyCode::E),
|
||||
speed_up: KeyBinding::from_key_code(KeyCode::LControl),
|
||||
slow_down: KeyBinding::from_key_code(KeyCode::LShift),
|
||||
|
||||
undo: HotKey::ctrl_key(KeyCode::Z),
|
||||
redo: HotKey::ctrl_key(KeyCode::Y),
|
||||
enable_select_mode: HotKey::from_key_code(KeyCode::Key1),
|
||||
enable_move_mode: HotKey::from_key_code(KeyCode::Key2),
|
||||
enable_rotate_mode: HotKey::from_key_code(KeyCode::Key3),
|
||||
enable_scale_mode: HotKey::from_key_code(KeyCode::Key4),
|
||||
enable_navmesh_mode: HotKey::from_key_code(KeyCode::Key5),
|
||||
enable_terrain_mode: HotKey::from_key_code(KeyCode::Key6),
|
||||
save_scene: HotKey::ctrl_key(KeyCode::S),
|
||||
load_scene: HotKey::ctrl_key(KeyCode::L),
|
||||
copy_selection: HotKey::ctrl_key(KeyCode::C),
|
||||
paste: HotKey::ctrl_key(KeyCode::V),
|
||||
new_scene: HotKey::ctrl_key(KeyCode::N),
|
||||
close_scene: HotKey::ctrl_key(KeyCode::Q),
|
||||
remove_selection: HotKey::from_key_code(KeyCode::Delete),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
use crate::{
|
||||
inspector::editors::make_property_editors_container,
|
||||
settings::navmesh::NavmeshSettings,
|
||||
settings::{
|
||||
camera::CameraSettings, debugging::DebuggingSettings, graphics::GraphicsSettings,
|
||||
model::ModelSettings, move_mode::MoveInteractionModeSettings, recent::RecentFiles,
|
||||
rotate_mode::RotateInteractionModeSettings, selection::SelectionSettings,
|
||||
keys::KeyBindings, model::ModelSettings, move_mode::MoveInteractionModeSettings,
|
||||
navmesh::NavmeshSettings, recent::RecentFiles, rotate_mode::RotateInteractionModeSettings,
|
||||
selection::SelectionSettings,
|
||||
},
|
||||
GameEngine, Message, MSG_SYNC_FLAG,
|
||||
};
|
||||
@@ -17,6 +17,7 @@ use fyrox::{
|
||||
editors::{
|
||||
enumeration::EnumPropertyEditorDefinition,
|
||||
inspectable::InspectablePropertyEditorDefinition,
|
||||
key::{HotKeyPropertyEditorDefinition, KeyBindingPropertyEditorDefinition},
|
||||
PropertyEditorDefinitionContainer,
|
||||
},
|
||||
InspectorBuilder, InspectorContext, InspectorMessage, PropertyAction, PropertyChanged,
|
||||
@@ -38,6 +39,7 @@ use std::{fs::File, path::PathBuf, rc::Rc, sync::mpsc::Sender};
|
||||
pub mod camera;
|
||||
pub mod debugging;
|
||||
pub mod graphics;
|
||||
pub mod keys;
|
||||
pub mod model;
|
||||
pub mod move_mode;
|
||||
pub mod navmesh;
|
||||
@@ -62,6 +64,7 @@ pub struct Settings {
|
||||
pub model: ModelSettings,
|
||||
pub camera: CameraSettings,
|
||||
pub navmesh: NavmeshSettings,
|
||||
pub key_bindings: KeyBindings,
|
||||
#[reflect(hidden)]
|
||||
pub recent: RecentFiles,
|
||||
}
|
||||
@@ -129,6 +132,9 @@ impl Settings {
|
||||
>::new());
|
||||
container.insert(InspectablePropertyEditorDefinition::<ModelSettings>::new());
|
||||
container.insert(InspectablePropertyEditorDefinition::<NavmeshSettings>::new());
|
||||
container.insert(InspectablePropertyEditorDefinition::<KeyBindings>::new());
|
||||
container.insert(HotKeyPropertyEditorDefinition);
|
||||
container.insert(KeyBindingPropertyEditorDefinition);
|
||||
|
||||
Rc::new(container)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user