mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-15 14:18:04 +08:00
Polish up the Layers panel design
This commit is contained in:
@@ -13,6 +13,9 @@ pub struct IconButton {
|
||||
#[widget_builder(constructor)]
|
||||
pub icon: String,
|
||||
|
||||
#[serde(rename = "hoverIcon")]
|
||||
pub hover_icon: Option<String>,
|
||||
|
||||
#[widget_builder(constructor)]
|
||||
pub size: u32, // TODO: Convert to an `IconSize` enum
|
||||
|
||||
@@ -95,6 +98,9 @@ pub struct TextButton {
|
||||
|
||||
pub icon: Option<String>,
|
||||
|
||||
#[serde(rename = "hoverIcon")]
|
||||
pub hover_icon: Option<String>,
|
||||
|
||||
pub flush: bool,
|
||||
|
||||
pub emphasized: bool,
|
||||
|
||||
@@ -1296,7 +1296,8 @@ impl DocumentMessageHandler {
|
||||
widgets.extend([
|
||||
Separator::new(SeparatorType::Unrelated).widget_holder(),
|
||||
TextButton::new("Node Graph")
|
||||
.icon(Some(if self.graph_view_overlay_open { "GraphViewOpen".into() } else { "GraphViewClosed".into() }))
|
||||
.icon(Some((if self.graph_view_overlay_open { "GraphViewOpen" } else { "GraphViewClosed" }).into()))
|
||||
.hover_icon(Some((if self.graph_view_overlay_open { "GraphViewClosed" } else { "GraphViewOpen" }).into()))
|
||||
.tooltip(if self.graph_view_overlay_open { "Hide Node Graph" } else { "Show Node Graph" })
|
||||
.tooltip_shortcut(action_keys!(DocumentMessageDiscriminant::GraphViewOverlayToggle))
|
||||
.on_update(move |_| DocumentMessage::GraphViewOverlayToggle.into())
|
||||
@@ -1358,6 +1359,10 @@ impl DocumentMessageHandler {
|
||||
})
|
||||
.collect();
|
||||
|
||||
let has_selection = self.selected_nodes.selected_layers(self.metadata()).next().is_some();
|
||||
let selection_all_visible = self.selected_nodes.selected_layers(self.metadata()).all(|layer| self.metadata().node_is_visible(layer.to_node()));
|
||||
let selection_all_locked = false; // TODO: Implement
|
||||
|
||||
let layers_panel_options_bar = WidgetLayout::new(vec![LayoutGroup::Row {
|
||||
widgets: vec![
|
||||
DropdownInput::new(blend_mode_menu_entries)
|
||||
@@ -1384,16 +1389,42 @@ impl DocumentMessageHandler {
|
||||
}
|
||||
})
|
||||
.widget_holder(),
|
||||
//
|
||||
Separator::new(SeparatorType::Unrelated).widget_holder(),
|
||||
IconButton::new("Folder", 24)
|
||||
.tooltip("New Folder")
|
||||
//
|
||||
IconButton::new("NewLayer", 24)
|
||||
.tooltip("New Folder/Layer")
|
||||
.tooltip_shortcut(action_keys!(DocumentMessageDiscriminant::CreateEmptyFolder))
|
||||
.on_update(|_| DocumentMessage::CreateEmptyFolder.into())
|
||||
.widget_holder(),
|
||||
IconButton::new("Folder", 24)
|
||||
.tooltip("Group Selected")
|
||||
.tooltip_shortcut(action_keys!(DocumentMessageDiscriminant::GroupSelectedLayers))
|
||||
.on_update(|_| DocumentMessage::GroupSelectedLayers.into())
|
||||
.disabled(!has_selection)
|
||||
.widget_holder(),
|
||||
IconButton::new("Trash", 24)
|
||||
.tooltip("Delete Selected")
|
||||
.tooltip_shortcut(action_keys!(DocumentMessageDiscriminant::DeleteSelectedLayers))
|
||||
.on_update(|_| DocumentMessage::DeleteSelectedLayers.into())
|
||||
.disabled(!has_selection)
|
||||
.widget_holder(),
|
||||
//
|
||||
Separator::new(SeparatorType::Unrelated).widget_holder(),
|
||||
//
|
||||
IconButton::new(if selection_all_locked { "PadlockLocked" } else { "PadlockUnlocked" }, 24)
|
||||
.hover_icon(Some((if selection_all_locked { "PadlockUnlocked" } else { "PadlockLocked" }).into()))
|
||||
.tooltip(if selection_all_locked { "Unlock Selected" } else { "Lock Selected" })
|
||||
.tooltip_shortcut(action_keys!(DialogMessageDiscriminant::RequestComingSoonDialog))
|
||||
.on_update(|_| DialogMessage::RequestComingSoonDialog { issue: Some(1127) }.into())
|
||||
.disabled(!has_selection)
|
||||
.widget_holder(),
|
||||
IconButton::new(if selection_all_visible { "EyeVisible" } else { "EyeHidden" }, 24)
|
||||
.hover_icon(Some((if selection_all_visible { "EyeHide" } else { "EyeShow" }).into()))
|
||||
.tooltip(if selection_all_visible { "Hide Selected" } else { "Show Selected" })
|
||||
.tooltip_shortcut(action_keys!(NodeGraphMessageDiscriminant::ToggleSelectedVisibility))
|
||||
.on_update(|_| NodeGraphMessage::ToggleSelectedVisibility.into())
|
||||
.disabled(!has_selection)
|
||||
.widget_holder(),
|
||||
],
|
||||
}]);
|
||||
|
||||
@@ -544,14 +544,16 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
|
||||
}
|
||||
|
||||
fn actions(&self) -> ActionList {
|
||||
unimplemented!("Must use `actions_with_graph_open` instead (unless we change every implementation of the MessageHandler trait).")
|
||||
unimplemented!("Must use `actions_with_node_graph_open` instead (unless we change every implementation of the MessageHandler trait).")
|
||||
}
|
||||
}
|
||||
|
||||
impl NodeGraphMessageHandler {
|
||||
pub fn actions_with_node_graph_open(&self, graph_open: bool) -> ActionList {
|
||||
if self.has_selection && graph_open {
|
||||
actions!(NodeGraphMessageDiscriminant; DeleteSelectedNodes, Cut, Copy, DuplicateSelectedNodes, ToggleSelectedVisibility)
|
||||
actions!(NodeGraphMessageDiscriminant; ToggleSelectedVisibility, DuplicateSelectedNodes, DeleteSelectedNodes, Cut, Copy)
|
||||
} else if self.has_selection {
|
||||
actions!(NodeGraphMessageDiscriminant; ToggleSelectedVisibility)
|
||||
} else {
|
||||
actions!(NodeGraphMessageDiscriminant;)
|
||||
}
|
||||
@@ -777,15 +779,24 @@ impl NodeGraphMessageHandler {
|
||||
}
|
||||
};
|
||||
|
||||
let parents_visible = layer
|
||||
.ancestors(metadata)
|
||||
.filter(|&ancestor| ancestor != layer)
|
||||
.all(|layer| network.nodes.get(&layer.to_node()).map(|node| node.visible).unwrap_or_default());
|
||||
|
||||
let data = LayerPanelEntry {
|
||||
id: node_id,
|
||||
layer_classification,
|
||||
expanded: layer.has_children(metadata) && !collapsed.0.contains(&layer),
|
||||
has_children: layer.has_children(metadata),
|
||||
depth: layer.ancestors(metadata).count() - 1,
|
||||
parent_id: layer.parent(metadata).map(|parent| parent.to_node()),
|
||||
name: network.nodes.get(&node_id).map(|node| node.alias.clone()).unwrap_or_default(),
|
||||
tooltip: if cfg!(debug_assertions) { format!("Layer ID: {node_id}") } else { "".into() },
|
||||
visible: node.visible,
|
||||
parents_visible,
|
||||
unlocked: true,
|
||||
parents_unlocked: true,
|
||||
};
|
||||
responses.add(FrontendMessage::UpdateDocumentLayerDetails { data });
|
||||
}
|
||||
@@ -918,6 +929,7 @@ impl Default for NodeGraphMessageHandler {
|
||||
Separator::new(SeparatorType::Unrelated).widget_holder(),
|
||||
TextButton::new("Node Graph")
|
||||
.icon(Some("GraphViewOpen".into()))
|
||||
.hover_icon(Some("GraphViewClosed".into()))
|
||||
.tooltip("Hide Node Graph")
|
||||
.tooltip_shortcut(action_keys!(DocumentMessageDiscriminant::GraphViewOverlayToggle))
|
||||
.on_update(move |_| DocumentMessage::GraphViewOverlayToggle.into())
|
||||
|
||||
@@ -46,7 +46,14 @@ pub struct LayerPanelEntry {
|
||||
#[serde(rename = "layerClassification")]
|
||||
pub layer_classification: LayerClassification,
|
||||
pub expanded: bool,
|
||||
#[serde(rename = "hasChildren")]
|
||||
pub has_children: bool,
|
||||
pub visible: bool,
|
||||
#[serde(rename = "parentsVisible")]
|
||||
pub parents_visible: bool,
|
||||
pub unlocked: bool,
|
||||
#[serde(rename = "parentsUnlocked")]
|
||||
pub parents_unlocked: bool,
|
||||
#[serde(rename = "parentId")]
|
||||
pub parent_id: Option<NodeId>,
|
||||
pub depth: usize,
|
||||
|
||||
Reference in New Issue
Block a user