diff --git a/editor/src/plugins/absm/mod.rs b/editor/src/plugins/absm/mod.rs index a74cee008..666190c7d 100644 --- a/editor/src/plugins/absm/mod.rs +++ b/editor/src/plugins/absm/mod.rs @@ -98,47 +98,6 @@ struct PreviewModeData { nodes: Vec<(Handle, N)>, } -fn fetch_selection(editor_selection: &Selection) -> AbsmSelection -where - N: Reflect, -{ - if let Some(selection) = editor_selection.as_absm() { - // Some selection in an animation. - AbsmSelection { - absm_node_handle: selection.absm_node_handle, - layer: selection.layer, - entities: selection.entities.clone(), - } - } else if let Some(selection) = editor_selection.as_graph() { - // Only some AnimationPlayer in a graph is selected. - AbsmSelection { - absm_node_handle: ErasedHandle::from( - selection.nodes.first().cloned().unwrap_or_default(), - ) - .into(), - layer: None, - entities: vec![], - } - } else if let Some(selection) = editor_selection.as_ui() { - // Only some AnimationPlayer in a UI is selected. - AbsmSelection { - absm_node_handle: ErasedHandle::from( - selection.widgets.first().cloned().unwrap_or_default(), - ) - .into(), - layer: None, - entities: vec![], - } - } else { - // Stub in other cases. - AbsmSelection { - absm_node_handle: Default::default(), - layer: None, - entities: vec![], - } - } -} - fn machine_container(graph: &mut G, absm_handle: Handle) -> Option<&mut Machine>> where G: SceneGraph, @@ -217,6 +176,12 @@ where Some((animation_player_handle, &**container)) } +#[derive(Default)] +struct AbsmEditorSelectionState { + absm: ErasedHandle, + layer: Option, +} + pub struct AbsmEditor { pub window: Handle, state_graph_viewer: StateGraphViewer, @@ -226,6 +191,7 @@ pub struct AbsmEditor { toolbar: Toolbar, preview_mode_data: Option>, blend_space_editor: BlendSpaceEditor, + selection_state: AbsmEditorSelectionState, } impl AbsmEditor { @@ -308,6 +274,54 @@ impl AbsmEditor { toolbar, preview_mode_data: None, blend_space_editor, + selection_state: Default::default(), + } + } + + fn fetch_selection(&mut self, graph: &G, editor_selection: &Selection) -> AbsmSelection + where + N: NodeWrapper, + G: SceneGraph, + { + if let Some(absm_selection) = editor_selection.as_absm() { + self.selection_state.layer = absm_selection.layer; + self.selection_state.absm = absm_selection.absm_node_handle.into(); + AbsmSelection { + absm_node_handle: absm_selection.absm_node_handle, + layer: absm_selection.layer, + entities: absm_selection.entities.clone(), + } + } else if let Some(graph_selection) = editor_selection.as_graph() { + let new_absm = + ErasedHandle::from(graph_selection.nodes.first().cloned().unwrap_or_default()); + if machine_container_ref(graph, new_absm.into()).is_some() { + self.selection_state.layer = None; + self.selection_state.absm = new_absm; + } + AbsmSelection { + absm_node_handle: self.selection_state.absm.into(), + layer: None, + entities: vec![], + } + } else if let Some(ui_selection) = editor_selection.as_ui() { + let new_absm = + ErasedHandle::from(ui_selection.widgets.first().cloned().unwrap_or_default()); + if machine_container_ref(graph, new_absm.into()).is_some() { + self.selection_state.layer = None; + self.selection_state.absm = new_absm; + } + AbsmSelection { + absm_node_handle: self.selection_state.absm.into(), + layer: None, + entities: vec![], + } + } else { + // Stub in other cases. + AbsmSelection { + absm_node_handle: self.selection_state.absm.into(), + layer: self.selection_state.layer, + entities: vec![], + } } } @@ -389,7 +403,7 @@ impl AbsmEditor { PhantomData: ObjectOrVariantHelper, { if self.preview_mode_data.is_some() { - let selection = fetch_selection(editor_selection); + let selection = self.fetch_selection(graph, editor_selection); assert!(node_overrides.remove(&selection.absm_node_handle)); if let Some((animation_player, _)) = @@ -452,7 +466,7 @@ impl AbsmEditor { { let prev_absm = self.prev_absm; - let selection = fetch_selection(editor_selection); + let selection = self.fetch_selection(graph, editor_selection); let machine = machine_container_ref(graph, selection.absm_node_handle); @@ -467,12 +481,11 @@ impl AbsmEditor { self.toolbar.sync_to_model(machine, ui, &selection); if let Some(layer_index) = selection.layer { if let Some(layer) = machine.layers().get(layer_index) { - self.state_graph_viewer - .sync_to_model(layer, ui, editor_selection); + self.state_graph_viewer.sync_to_model(layer, ui, &selection); self.state_viewer.sync_to_model( ui, layer, - editor_selection, + &selection, animation_container_ref::( graph, selection.absm_node_handle, @@ -539,7 +552,7 @@ impl AbsmEditor { } pub fn handle_machine_events( - &self, + &mut self, editor_selection: &Selection, graph: &mut G, ui: &mut UserInterface, @@ -548,7 +561,7 @@ impl AbsmEditor { G: SceneGraph, N: NodeWrapper, { - let selection = fetch_selection(editor_selection); + let selection = self.fetch_selection(graph, editor_selection); if let Some(machine) = machine_container(graph, selection.absm_node_handle) { if let Some(layer_index) = selection.layer { @@ -584,7 +597,7 @@ impl AbsmEditor { AnimationPlayer: Reflect, PhantomData: ObjectOrVariantHelper, { - let selection = fetch_selection(editor_selection); + let selection = self.fetch_selection(graph, editor_selection); if let Some(machine) = machine_container(graph, selection.absm_node_handle) { if let Some(layer_index) = selection.layer { @@ -623,9 +636,9 @@ impl AbsmEditor { self.preview_mode_data.is_some(), ); - let action = - self.toolbar - .handle_ui_message(message, editor_selection, sender, graph, ui); + let action = self + .toolbar + .handle_ui_message(message, &selection, sender, graph, ui); let machine = machine_container(graph, selection.absm_node_handle).unwrap(); diff --git a/editor/src/plugins/absm/state_graph/mod.rs b/editor/src/plugins/absm/state_graph/mod.rs index 686025cbb..8ca4b1e9a 100644 --- a/editor/src/plugins/absm/state_graph/mod.rs +++ b/editor/src/plugins/absm/state_graph/mod.rs @@ -34,7 +34,6 @@ use crate::fyrox::{ use crate::plugins::absm::{ canvas::{AbsmCanvas, AbsmCanvasBuilder, AbsmCanvasMessage}, command::{AddTransitionCommand, MoveStateNodeCommand}, - fetch_selection, node::{AbsmNode, AbsmNodeBuilder, AbsmNodeMessage}, selection::{AbsmSelection, SelectedEntity}, state_graph::context::{CanvasContextMenu, NodeContextMenu, TransitionContextMenu}, @@ -296,14 +295,13 @@ impl StateGraphViewer { &mut self, machine_layer: &MachineLayer>, ui: &mut UserInterface, - editor_selection: &Selection, + current_selection: &AbsmSelection, ) where P: PrefabData, G: SceneGraph, N: NodeWrapper, { let canvas = &ui[self.canvas]; - let current_selection = fetch_selection(editor_selection); let mut states = Vec::new(); let mut transitions = Vec::new(); diff --git a/editor/src/plugins/absm/state_viewer/mod.rs b/editor/src/plugins/absm/state_viewer/mod.rs index a32d3960e..45cc5dbab 100644 --- a/editor/src/plugins/absm/state_viewer/mod.rs +++ b/editor/src/plugins/absm/state_viewer/mod.rs @@ -48,7 +48,6 @@ use crate::plugins::absm::{ MovePoseNodeCommand, }, connection::{Connection, ConnectionBuilder}, - fetch_selection, node::{AbsmNode, AbsmNodeBuilder, AbsmNodeMessage}, selection::{AbsmSelection, SelectedEntity}, socket::{Socket, SocketBuilder, SocketDirection}, @@ -412,7 +411,7 @@ impl StateViewer { &mut self, ui: &mut UserInterface, machine_layer: &MachineLayer>, - editor_selection: &Selection, + current_selection: &AbsmSelection, animation_container: Option<&AnimationContainer>>, ) where P: PrefabData, @@ -420,8 +419,6 @@ impl StateViewer { N: NodeWrapper, { if let Ok(parent_state_ref) = machine_layer.states().try_borrow(self.state.into()) { - let current_selection = fetch_selection(editor_selection); - let mut views = Vec::new(); if self.prev_layer != current_selection.layer || current_selection.absm_node_handle != Handle::::from(self.prev_absm) diff --git a/editor/src/plugins/absm/toolbar.rs b/editor/src/plugins/absm/toolbar.rs index fd9926156..014852352 100644 --- a/editor/src/plugins/absm/toolbar.rs +++ b/editor/src/plugins/absm/toolbar.rs @@ -43,7 +43,7 @@ use crate::{ plugins::absm::{ animation_container_ref, command::{AddLayerCommand, RemoveLayerCommand, SetLayerMaskCommand, SetLayerNameCommand}, - fetch_selection, machine_container_ref, + machine_container_ref, selection::AbsmSelection, }, scene::{ @@ -160,7 +160,7 @@ impl Toolbar { pub fn handle_ui_message( &mut self, message: &UiMessage, - editor_selection: &Selection, + selection: &AbsmSelection, sender: &MessageSender, graph: &G, ui: &mut UserInterface, @@ -172,8 +172,6 @@ impl Toolbar { AnimationPlayer: Reflect, PhantomData: ObjectOrVariantHelper, { - let selection = fetch_selection(editor_selection); - if let Some(ToggleButtonMessage::Toggled(value)) = message.data_from(self.preview) { return if *value { ToolbarAction::EnterPreviewMode @@ -183,7 +181,7 @@ impl Toolbar { } else if let Some(DropdownListMessage::Selection(Some(index))) = message.data_from(self.layers) { - let mut new_selection = selection; + let mut new_selection = selection.clone(); new_selection.layer = Some(*index); new_selection.entities.clear(); sender.do_command(ChangeSelectionCommand::new(Selection::new(new_selection)));