mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-10-02 00:38:12 +08:00
Store overlays, snapping, and grid state in saved documents and toggle them with hotkeys
This commit is contained in:
@@ -22,6 +22,6 @@ impl MessageHandler<BroadcastMessage, ()> for BroadcastMessageHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn actions(&self) -> ActionList {
|
fn actions(&self) -> ActionList {
|
||||||
vec![]
|
actions!(BroadcastEventDiscriminant;)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-4
@@ -15,13 +15,13 @@ use glam::DVec2;
|
|||||||
impl From<MappingVariant> for Mapping {
|
impl From<MappingVariant> for Mapping {
|
||||||
fn from(value: MappingVariant) -> Self {
|
fn from(value: MappingVariant) -> Self {
|
||||||
match value {
|
match value {
|
||||||
MappingVariant::Default => default_mapping(),
|
MappingVariant::Default => input_mappings(),
|
||||||
MappingVariant::ZoomWithScroll => zoom_with_scroll(),
|
MappingVariant::ZoomWithScroll => zoom_with_scroll(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn default_mapping() -> Mapping {
|
pub fn input_mappings() -> Mapping {
|
||||||
use InputMapperMessage::*;
|
use InputMapperMessage::*;
|
||||||
use Key::*;
|
use Key::*;
|
||||||
|
|
||||||
@@ -61,7 +61,7 @@ pub fn default_mapping() -> Mapping {
|
|||||||
entry!(KeyDown(KeyD); modifiers=[Accel], action_dispatch=NodeGraphMessage::DuplicateSelectedNodes),
|
entry!(KeyDown(KeyD); modifiers=[Accel], action_dispatch=NodeGraphMessage::DuplicateSelectedNodes),
|
||||||
entry!(KeyDown(KeyH); modifiers=[Accel], action_dispatch=NodeGraphMessage::ToggleSelectedVisibility),
|
entry!(KeyDown(KeyH); modifiers=[Accel], action_dispatch=NodeGraphMessage::ToggleSelectedVisibility),
|
||||||
entry!(KeyDown(KeyL); modifiers=[Accel], action_dispatch=NodeGraphMessage::ToggleSelectedLocked),
|
entry!(KeyDown(KeyL); modifiers=[Accel], action_dispatch=NodeGraphMessage::ToggleSelectedLocked),
|
||||||
entry!(KeyDown(KeyL); modifiers=[Alt], action_dispatch=NodeGraphMessage::ToggleSelectedLayers),
|
entry!(KeyDown(KeyL); modifiers=[Alt], action_dispatch=NodeGraphMessage::ToggleSelectedAsLayersOrNodes),
|
||||||
//
|
//
|
||||||
// TransformLayerMessage
|
// TransformLayerMessage
|
||||||
entry!(KeyDown(Enter); action_dispatch=TransformLayerMessage::ApplyTransformOperation),
|
entry!(KeyDown(Enter); action_dispatch=TransformLayerMessage::ApplyTransformOperation),
|
||||||
@@ -292,6 +292,9 @@ pub fn default_mapping() -> Mapping {
|
|||||||
entry!(KeyDown(Delete); action_dispatch=DocumentMessage::DeleteSelectedLayers),
|
entry!(KeyDown(Delete); action_dispatch=DocumentMessage::DeleteSelectedLayers),
|
||||||
entry!(KeyDown(Backspace); action_dispatch=DocumentMessage::DeleteSelectedLayers),
|
entry!(KeyDown(Backspace); action_dispatch=DocumentMessage::DeleteSelectedLayers),
|
||||||
entry!(KeyDown(KeyP); modifiers=[Alt], action_dispatch=DocumentMessage::DebugPrintDocument),
|
entry!(KeyDown(KeyP); modifiers=[Alt], action_dispatch=DocumentMessage::DebugPrintDocument),
|
||||||
|
entry!(KeyDown(KeyO); modifiers=[Alt], action_dispatch=DocumentMessage::ToggleOverlaysVisibility),
|
||||||
|
entry!(KeyDown(KeyS); modifiers=[Alt], action_dispatch=DocumentMessage::ToggleSnapping),
|
||||||
|
entry!(KeyDown(KeyG); modifiers=[Alt], action_dispatch=DocumentMessage::ToggleGridVisibility),
|
||||||
entry!(KeyDown(KeyZ); modifiers=[Accel, Shift], action_dispatch=DocumentMessage::Redo),
|
entry!(KeyDown(KeyZ); modifiers=[Accel, Shift], action_dispatch=DocumentMessage::Redo),
|
||||||
entry!(KeyDown(KeyY); modifiers=[Accel], action_dispatch=DocumentMessage::Redo),
|
entry!(KeyDown(KeyY); modifiers=[Accel], action_dispatch=DocumentMessage::Redo),
|
||||||
entry!(KeyDown(KeyZ); modifiers=[Accel], action_dispatch=DocumentMessage::Undo),
|
entry!(KeyDown(KeyZ); modifiers=[Accel], action_dispatch=DocumentMessage::Undo),
|
||||||
@@ -422,7 +425,7 @@ pub fn default_mapping() -> Mapping {
|
|||||||
pub fn zoom_with_scroll() -> Mapping {
|
pub fn zoom_with_scroll() -> Mapping {
|
||||||
use InputMapperMessage::*;
|
use InputMapperMessage::*;
|
||||||
|
|
||||||
let mut mapping = default_mapping();
|
let mut mapping = input_mappings();
|
||||||
|
|
||||||
let remove = [
|
let remove = [
|
||||||
entry!(WheelScroll; modifiers=[Control], action_dispatch=NavigationMessage::CanvasZoomMouseWheel),
|
entry!(WheelScroll; modifiers=[Control], action_dispatch=NavigationMessage::CanvasZoomMouseWheel),
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
mod input_mapper_message;
|
mod input_mapper_message;
|
||||||
mod input_mapper_message_handler;
|
mod input_mapper_message_handler;
|
||||||
|
|
||||||
pub mod default_mapping;
|
pub mod input_mappings;
|
||||||
pub mod key_mapping;
|
pub mod key_mapping;
|
||||||
pub mod utility_types;
|
pub mod utility_types;
|
||||||
|
|
||||||
|
|||||||
@@ -296,7 +296,7 @@ impl<F: Fn(&MessageDiscriminant) -> Vec<KeysGroup>> MessageHandler<LayoutMessage
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn actions(&self) -> ActionList {
|
fn actions(&self) -> ActionList {
|
||||||
actions!()
|
actions!(LayoutMessageDiscriminant;)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ pub enum DocumentMessage {
|
|||||||
GraphViewOverlayToggle,
|
GraphViewOverlayToggle,
|
||||||
GridOptions(GridSnapping),
|
GridOptions(GridSnapping),
|
||||||
GridOverlays(OverlayContext),
|
GridOverlays(OverlayContext),
|
||||||
GridVisible(bool),
|
GridVisibility(bool),
|
||||||
GroupSelectedLayers,
|
GroupSelectedLayers,
|
||||||
ImaginateGenerate,
|
ImaginateGenerate,
|
||||||
ImaginateRandom {
|
ImaginateRandom {
|
||||||
@@ -138,6 +138,9 @@ pub enum DocumentMessage {
|
|||||||
ToggleLayerExpansion {
|
ToggleLayerExpansion {
|
||||||
id: NodeId,
|
id: NodeId,
|
||||||
},
|
},
|
||||||
|
ToggleGridVisibility,
|
||||||
|
ToggleOverlaysVisibility,
|
||||||
|
ToggleSnapping,
|
||||||
Undo,
|
Undo,
|
||||||
UndoFinished,
|
UndoFinished,
|
||||||
UngroupSelectedLayers,
|
UngroupSelectedLayers,
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ pub struct DocumentMessageHandler {
|
|||||||
// ======================
|
// ======================
|
||||||
// Child message handlers
|
// Child message handlers
|
||||||
// ======================
|
// ======================
|
||||||
|
//
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
navigation_handler: NavigationMessageHandler,
|
navigation_handler: NavigationMessageHandler,
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
@@ -54,49 +55,78 @@ pub struct DocumentMessageHandler {
|
|||||||
overlays_message_handler: OverlaysMessageHandler,
|
overlays_message_handler: OverlaysMessageHandler,
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
properties_panel_message_handler: PropertiesPanelMessageHandler,
|
properties_panel_message_handler: PropertiesPanelMessageHandler,
|
||||||
|
|
||||||
// ============================================
|
// ============================================
|
||||||
// Fields that are saved in the document format
|
// Fields that are saved in the document format
|
||||||
// ============================================
|
// ============================================
|
||||||
|
//
|
||||||
|
/// The node graph that generates this document's artwork.
|
||||||
|
/// It recursively stores its sub-graphs, so this root graph is the whole snapshot of the document content.
|
||||||
#[serde(default = "default_network")]
|
#[serde(default = "default_network")]
|
||||||
pub network: NodeNetwork,
|
pub network: NodeNetwork,
|
||||||
|
/// List of the [`NodeId`]s that are currently selected by the user.
|
||||||
#[serde(default = "default_selected_nodes")]
|
#[serde(default = "default_selected_nodes")]
|
||||||
pub selected_nodes: SelectedNodes,
|
pub selected_nodes: SelectedNodes,
|
||||||
|
/// List of the [`LayerNodeIdentifier`]s that are currently collapsed by the user in the Layers panel.
|
||||||
|
/// Collapsed means that the expansion arrow isn't set to show the children of these layers.
|
||||||
#[serde(default = "default_collapsed")]
|
#[serde(default = "default_collapsed")]
|
||||||
pub collapsed: CollapsedLayers,
|
pub collapsed: CollapsedLayers,
|
||||||
|
/// The name of the document, which is displayed in the tab and title bar of the editor.
|
||||||
#[serde(default = "default_name")]
|
#[serde(default = "default_name")]
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
/// The full Git commit hash of the Graphite repository that was used to build the editor.
|
||||||
|
/// We save this to provide a hint about which version of the editor was used to create the document.
|
||||||
#[serde(default = "default_commit_hash")]
|
#[serde(default = "default_commit_hash")]
|
||||||
commit_hash: String,
|
commit_hash: String,
|
||||||
|
/// The current pan, tilt, and zoom state of the viewport's view of the document canvas.
|
||||||
#[serde(default = "default_pan_tilt_zoom")]
|
#[serde(default = "default_pan_tilt_zoom")]
|
||||||
pub navigation: PTZ,
|
pub navigation: PTZ,
|
||||||
|
/// The current mode that the document is in, which starts out as Design Mode. This choice affects the editing behavior of the tools.
|
||||||
#[serde(default = "default_document_mode")]
|
#[serde(default = "default_document_mode")]
|
||||||
document_mode: DocumentMode,
|
document_mode: DocumentMode,
|
||||||
|
/// The current view mode that the user has set for rendering the document within the viewport.
|
||||||
|
/// This is usually "Normal" but can be set to "Outline" or "Pixels" to see the canvas differently.
|
||||||
#[serde(default = "default_view_mode")]
|
#[serde(default = "default_view_mode")]
|
||||||
pub view_mode: ViewMode,
|
pub view_mode: ViewMode,
|
||||||
|
/// Sets whether or not all the viewport overlays should be drawn on top of the artwork.
|
||||||
|
/// This includes tool interaction visualizations (like the transform cage and path anchors/handles), the grid, and more.
|
||||||
#[serde(default = "default_overlays_visible")]
|
#[serde(default = "default_overlays_visible")]
|
||||||
overlays_visible: bool,
|
overlays_visible: bool,
|
||||||
|
/// Sets whether or not the rulers should be drawn along the top and left edges of the viewport area.
|
||||||
#[serde(default = "default_rulers_visible")]
|
#[serde(default = "default_rulers_visible")]
|
||||||
pub rulers_visible: bool,
|
pub rulers_visible: bool,
|
||||||
|
/// Sets whether or not the node graph is drawn (as an overlay) on top of the viewport area, or otherwise if it's hidden.
|
||||||
|
#[serde(default = "default_graph_view_overlay_open")]
|
||||||
|
graph_view_overlay_open: bool,
|
||||||
|
/// The current user choices for snapping behavior, including whether snapping is enabled at all.
|
||||||
|
#[serde(default = "default_snapping_state")]
|
||||||
|
pub snapping_state: SnappingState,
|
||||||
|
|
||||||
// =============================================
|
// =============================================
|
||||||
// Fields omitted from the saved document format
|
// Fields omitted from the saved document format
|
||||||
// =============================================
|
// =============================================
|
||||||
|
//
|
||||||
|
/// Stack of document network snapshots for previous history states.
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
document_undo_history: VecDeque<NodeNetwork>,
|
document_undo_history: VecDeque<NodeNetwork>,
|
||||||
|
/// Stack of document network snapshots for future history states.
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
document_redo_history: VecDeque<NodeNetwork>,
|
document_redo_history: VecDeque<NodeNetwork>,
|
||||||
|
/// Hash of the document snapshot that was most recently saved to disk by the user.
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
saved_hash: Option<u64>,
|
saved_hash: Option<u64>,
|
||||||
|
/// Hash of the document snapshot that was most recently auto-saved to the IndexedDB storage that will reopen when the editor is reloaded.
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
auto_saved_hash: Option<u64>,
|
auto_saved_hash: Option<u64>,
|
||||||
/// Don't allow aborting transactions whilst undoing to avoid #559
|
/// Disallow aborting transactions whilst undoing to avoid #559.
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
undo_in_progress: bool,
|
undo_in_progress: bool,
|
||||||
#[serde(skip)]
|
/// The ID of the layer at the start of a range selection in the Layers panel.
|
||||||
graph_view_overlay_open: bool,
|
/// If the user clicks or Ctrl-clicks one layer, it becomes the start of the range selection and then Shift-clicking another layer selects all layers between the start and end.
|
||||||
#[serde(skip)]
|
|
||||||
pub snapping_state: SnappingState,
|
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
layer_range_selection_reference: Option<LayerNodeIdentifier>,
|
layer_range_selection_reference: Option<LayerNodeIdentifier>,
|
||||||
|
/// Stores stateful information about the document's network such as the graph's structural topology and which layers are hidden, locked, etc.
|
||||||
|
/// This is updated frequently, whenever the information it's derived from changes.
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
pub metadata: DocumentMetadata,
|
pub metadata: DocumentMetadata,
|
||||||
}
|
}
|
||||||
@@ -330,7 +360,7 @@ impl MessageHandler<DocumentMessage, DocumentMessageData<'_>> for DocumentMessag
|
|||||||
grid_overlay(self, &mut overlay_context)
|
grid_overlay(self, &mut overlay_context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DocumentMessage::GridVisible(enabled) => {
|
DocumentMessage::GridVisibility(enabled) => {
|
||||||
self.snapping_state.grid_snapping = enabled;
|
self.snapping_state.grid_snapping = enabled;
|
||||||
responses.add(OverlaysMessage::Draw);
|
responses.add(OverlaysMessage::Draw);
|
||||||
}
|
}
|
||||||
@@ -844,6 +874,20 @@ impl MessageHandler<DocumentMessage, DocumentMessageData<'_>> for DocumentMessag
|
|||||||
}
|
}
|
||||||
responses.add(NodeGraphMessage::RunDocumentGraph);
|
responses.add(NodeGraphMessage::RunDocumentGraph);
|
||||||
}
|
}
|
||||||
|
DocumentMessage::ToggleGridVisibility => {
|
||||||
|
self.snapping_state.grid_snapping = !self.snapping_state.grid_snapping;
|
||||||
|
responses.add(OverlaysMessage::Draw);
|
||||||
|
responses.add(PortfolioMessage::UpdateDocumentWidgets);
|
||||||
|
}
|
||||||
|
DocumentMessage::ToggleOverlaysVisibility => {
|
||||||
|
self.overlays_visible = !self.overlays_visible;
|
||||||
|
responses.add(OverlaysMessage::Draw);
|
||||||
|
responses.add(PortfolioMessage::UpdateDocumentWidgets);
|
||||||
|
}
|
||||||
|
DocumentMessage::ToggleSnapping => {
|
||||||
|
self.snapping_state.snapping_enabled = !self.snapping_state.snapping_enabled;
|
||||||
|
responses.add(PortfolioMessage::UpdateDocumentWidgets);
|
||||||
|
}
|
||||||
DocumentMessage::Undo => {
|
DocumentMessage::Undo => {
|
||||||
self.undo_in_progress = true;
|
self.undo_in_progress = true;
|
||||||
responses.add(ToolMessage::PreUndo);
|
responses.add(ToolMessage::PreUndo);
|
||||||
@@ -967,7 +1011,52 @@ impl MessageHandler<DocumentMessage, DocumentMessageData<'_>> for DocumentMessag
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn actions(&self) -> ActionList {
|
fn actions(&self) -> ActionList {
|
||||||
unimplemented!("Must use `actions_with_graph_open` instead (unless we change every implementation of the MessageHandler trait).")
|
let mut common = actions!(DocumentMessageDiscriminant;
|
||||||
|
CreateEmptyFolder,
|
||||||
|
DebugPrintDocument,
|
||||||
|
DeselectAllLayers,
|
||||||
|
GraphViewOverlayToggle,
|
||||||
|
Noop,
|
||||||
|
Redo,
|
||||||
|
SaveDocument,
|
||||||
|
SelectAllLayers,
|
||||||
|
SetSnapping,
|
||||||
|
ToggleGridVisibility,
|
||||||
|
ToggleOverlaysVisibility,
|
||||||
|
ToggleSnapping,
|
||||||
|
Undo,
|
||||||
|
ZoomCanvasTo100Percent,
|
||||||
|
ZoomCanvasTo200Percent,
|
||||||
|
ZoomCanvasToFitAll,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Additional actions if there are any selected layers
|
||||||
|
if self.selected_nodes.selected_layers(self.metadata()).next().is_some() {
|
||||||
|
let select = actions!(DocumentMessageDiscriminant;
|
||||||
|
DeleteSelectedLayers,
|
||||||
|
DuplicateSelectedLayers,
|
||||||
|
GroupSelectedLayers,
|
||||||
|
NudgeSelectedLayers,
|
||||||
|
SelectedLayersLower,
|
||||||
|
SelectedLayersLowerToBack,
|
||||||
|
SelectedLayersRaise,
|
||||||
|
SelectedLayersRaiseToFront,
|
||||||
|
UngroupSelectedLayers,
|
||||||
|
);
|
||||||
|
common.extend(select);
|
||||||
|
}
|
||||||
|
// Additional actions if the node graph is open
|
||||||
|
if self.graph_view_overlay_open {
|
||||||
|
common.extend(actions!(DocumentMessageDiscriminant;
|
||||||
|
GraphViewOverlay,
|
||||||
|
));
|
||||||
|
common.extend(self.node_graph_handler.actions_additional_if_node_graph_is_open());
|
||||||
|
}
|
||||||
|
// More additional actions
|
||||||
|
common.extend(self.node_graph_handler.actions());
|
||||||
|
common.extend(self.navigation_handler.actions());
|
||||||
|
|
||||||
|
common
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1377,6 +1466,7 @@ impl DocumentMessageHandler {
|
|||||||
CheckboxInput::new(self.overlays_visible)
|
CheckboxInput::new(self.overlays_visible)
|
||||||
.icon("Overlays")
|
.icon("Overlays")
|
||||||
.tooltip("Overlays")
|
.tooltip("Overlays")
|
||||||
|
.tooltip_shortcut(action_keys!(DocumentMessageDiscriminant::ToggleOverlaysVisibility))
|
||||||
.on_update(|optional_input: &CheckboxInput| DocumentMessage::SetOverlaysVisibility { visible: optional_input.checked }.into())
|
.on_update(|optional_input: &CheckboxInput| DocumentMessage::SetOverlaysVisibility { visible: optional_input.checked }.into())
|
||||||
.widget_holder(),
|
.widget_holder(),
|
||||||
PopoverButton::new()
|
PopoverButton::new()
|
||||||
@@ -1393,6 +1483,7 @@ impl DocumentMessageHandler {
|
|||||||
CheckboxInput::new(snapping_state.snapping_enabled)
|
CheckboxInput::new(snapping_state.snapping_enabled)
|
||||||
.icon("Snapping")
|
.icon("Snapping")
|
||||||
.tooltip("Snapping")
|
.tooltip("Snapping")
|
||||||
|
.tooltip_shortcut(action_keys!(DocumentMessageDiscriminant::ToggleSnapping))
|
||||||
.on_update(move |optional_input: &CheckboxInput| {
|
.on_update(move |optional_input: &CheckboxInput| {
|
||||||
let snapping_enabled = optional_input.checked;
|
let snapping_enabled = optional_input.checked;
|
||||||
DocumentMessage::SetSnapping {
|
DocumentMessage::SetSnapping {
|
||||||
@@ -1508,7 +1599,8 @@ impl DocumentMessageHandler {
|
|||||||
CheckboxInput::new(self.snapping_state.grid_snapping)
|
CheckboxInput::new(self.snapping_state.grid_snapping)
|
||||||
.icon("Grid")
|
.icon("Grid")
|
||||||
.tooltip("Grid")
|
.tooltip("Grid")
|
||||||
.on_update(|optional_input: &CheckboxInput| DocumentMessage::GridVisible(optional_input.checked).into())
|
.tooltip_shortcut(action_keys!(DocumentMessageDiscriminant::ToggleGridVisibility))
|
||||||
|
.on_update(|optional_input: &CheckboxInput| DocumentMessage::GridVisibility(optional_input.checked).into())
|
||||||
.widget_holder(),
|
.widget_holder(),
|
||||||
PopoverButton::new()
|
PopoverButton::new()
|
||||||
.popover_layout(overlay_options(&self.snapping_state.grid))
|
.popover_layout(overlay_options(&self.snapping_state.grid))
|
||||||
@@ -1819,47 +1911,6 @@ impl DocumentMessageHandler {
|
|||||||
let insert_index = if relative_index_offset < 0 { neighbor_index } else { neighbor_index + 1 } as isize;
|
let insert_index = if relative_index_offset < 0 { neighbor_index } else { neighbor_index + 1 } as isize;
|
||||||
responses.add(DocumentMessage::MoveSelectedLayersTo { parent, insert_index });
|
responses.add(DocumentMessage::MoveSelectedLayersTo { parent, insert_index });
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn actions_with_graph_open(&self) -> ActionList {
|
|
||||||
let mut common = actions!(DocumentMessageDiscriminant;
|
|
||||||
Noop,
|
|
||||||
Undo,
|
|
||||||
Redo,
|
|
||||||
SelectAllLayers,
|
|
||||||
DeselectAllLayers,
|
|
||||||
SaveDocument,
|
|
||||||
SetSnapping,
|
|
||||||
DebugPrintDocument,
|
|
||||||
ZoomCanvasToFitAll,
|
|
||||||
ZoomCanvasTo100Percent,
|
|
||||||
ZoomCanvasTo200Percent,
|
|
||||||
GraphViewOverlayToggle,
|
|
||||||
CreateEmptyFolder,
|
|
||||||
);
|
|
||||||
|
|
||||||
if self.graph_view_overlay_open {
|
|
||||||
let escape = actions!(DocumentMessageDiscriminant; GraphViewOverlay);
|
|
||||||
common.extend(escape);
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.selected_nodes.selected_layers(self.metadata()).next().is_some() {
|
|
||||||
let select = actions!(DocumentMessageDiscriminant;
|
|
||||||
DeleteSelectedLayers,
|
|
||||||
DuplicateSelectedLayers,
|
|
||||||
NudgeSelectedLayers,
|
|
||||||
SelectedLayersLower,
|
|
||||||
SelectedLayersLowerToBack,
|
|
||||||
SelectedLayersRaise,
|
|
||||||
SelectedLayersRaiseToFront,
|
|
||||||
GroupSelectedLayers,
|
|
||||||
UngroupSelectedLayers,
|
|
||||||
);
|
|
||||||
common.extend(select);
|
|
||||||
}
|
|
||||||
common.extend(self.navigation_handler.actions());
|
|
||||||
common.extend(self.node_graph_handler.actions_with_node_graph_open(self.graph_view_overlay_open));
|
|
||||||
common
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for DocumentMessageHandler {
|
impl Default for DocumentMessageHandler {
|
||||||
@@ -1941,6 +1992,14 @@ fn default_overlays_visible() -> bool {
|
|||||||
fn default_rulers_visible() -> bool {
|
fn default_rulers_visible() -> bool {
|
||||||
DocumentMessageHandler::default().rulers_visible
|
DocumentMessageHandler::default().rulers_visible
|
||||||
}
|
}
|
||||||
|
#[inline(always)]
|
||||||
|
fn default_graph_view_overlay_open() -> bool {
|
||||||
|
DocumentMessageHandler::default().graph_view_overlay_open
|
||||||
|
}
|
||||||
|
#[inline(always)]
|
||||||
|
fn default_snapping_state() -> SnappingState {
|
||||||
|
DocumentMessageHandler::default().snapping_state
|
||||||
|
}
|
||||||
|
|
||||||
fn root_network() -> NodeNetwork {
|
fn root_network() -> NodeNetwork {
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ pub enum NodeGraphMessage {
|
|||||||
TogglePreviewImpl {
|
TogglePreviewImpl {
|
||||||
node_id: NodeId,
|
node_id: NodeId,
|
||||||
},
|
},
|
||||||
ToggleSelectedLayers,
|
ToggleSelectedAsLayersOrNodes,
|
||||||
ToggleSelectedLocked,
|
ToggleSelectedLocked,
|
||||||
ToggleSelectedVisibility,
|
ToggleSelectedVisibility,
|
||||||
ToggleVisibility {
|
ToggleVisibility {
|
||||||
|
|||||||
@@ -702,7 +702,7 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
|
|||||||
document_metadata.load_structure(document_network, selected_nodes);
|
document_metadata.load_structure(document_network, selected_nodes);
|
||||||
self.update_selection_action_buttons(document_network, document_metadata, selected_nodes, responses);
|
self.update_selection_action_buttons(document_network, document_metadata, selected_nodes, responses);
|
||||||
}
|
}
|
||||||
NodeGraphMessage::ToggleSelectedLayers => {
|
NodeGraphMessage::ToggleSelectedAsLayersOrNodes => {
|
||||||
let Some(network) = document_network.nested_network_mut(&self.network) else { return };
|
let Some(network) = document_network.nested_network_mut(&self.network) else { return };
|
||||||
|
|
||||||
for node_id in selected_nodes.selected_nodes() {
|
for node_id in selected_nodes.selected_nodes() {
|
||||||
@@ -788,16 +788,28 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn actions(&self) -> ActionList {
|
fn actions(&self) -> ActionList {
|
||||||
unimplemented!("Must use `actions_with_node_graph_open` instead (unless we change every implementation of the MessageHandler trait).")
|
if self.has_selection {
|
||||||
|
actions!(NodeGraphMessageDiscriminant;
|
||||||
|
ToggleSelectedLocked,
|
||||||
|
ToggleSelectedVisibility,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
actions!(NodeGraphMessageDiscriminant;)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NodeGraphMessageHandler {
|
impl NodeGraphMessageHandler {
|
||||||
pub fn actions_with_node_graph_open(&self, graph_open: bool) -> ActionList {
|
/// Similar to [`NodeGraphMessageHandler::actions`], but this provides additional actions if the node graph is open and should only be called in that circumstance.
|
||||||
if self.has_selection && graph_open {
|
pub fn actions_additional_if_node_graph_is_open(&self) -> ActionList {
|
||||||
actions!(NodeGraphMessageDiscriminant; ToggleSelectedVisibility, ToggleSelectedLocked, ToggleSelectedLayers, DuplicateSelectedNodes, DeleteSelectedNodes, Cut, Copy)
|
if self.has_selection {
|
||||||
} else if self.has_selection {
|
actions!(NodeGraphMessageDiscriminant;
|
||||||
actions!(NodeGraphMessageDiscriminant; ToggleSelectedVisibility, ToggleSelectedLocked)
|
Copy,
|
||||||
|
Cut,
|
||||||
|
DeleteSelectedNodes,
|
||||||
|
DuplicateSelectedNodes,
|
||||||
|
ToggleSelectedAsLayersOrNodes,
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
actions!(NodeGraphMessageDiscriminant;)
|
actions!(NodeGraphMessageDiscriminant;)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ impl DocumentMode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
|
||||||
/// SnappingState determines the current individual snapping states
|
/// SnappingState determines the current individual snapping states
|
||||||
pub struct SnappingState {
|
pub struct SnappingState {
|
||||||
pub snapping_enabled: bool,
|
pub snapping_enabled: bool,
|
||||||
|
|||||||
@@ -536,16 +536,17 @@ impl MessageHandler<PortfolioMessage, PortfolioMessageData<'_>> for PortfolioMes
|
|||||||
ToggleRulers,
|
ToggleRulers,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Extend with actions that require an active document
|
||||||
if let Some(document) = self.active_document() {
|
if let Some(document) = self.active_document() {
|
||||||
|
common.extend(document.actions());
|
||||||
|
|
||||||
|
// Extend with actions that must have a selected layer
|
||||||
if document.selected_nodes.selected_layers(document.metadata()).next().is_some() {
|
if document.selected_nodes.selected_layers(document.metadata()).next().is_some() {
|
||||||
let select = actions!(PortfolioMessageDiscriminant;
|
common.extend(actions!(PortfolioMessageDiscriminant;
|
||||||
Copy,
|
Copy,
|
||||||
Cut,
|
Cut,
|
||||||
);
|
));
|
||||||
common.extend(select);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
common.extend(document.actions_with_graph_open());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
common
|
common
|
||||||
|
|||||||
Reference in New Issue
Block a user