Tidy up the UI with clearer Layers panel selection marks and removal of most "coming soon" UI elements

This commit is contained in:
Keavon Chambers
2024-12-14 20:49:21 -08:00
parent 287ef26f64
commit 1264ea8246
11 changed files with 143 additions and 126 deletions
@@ -1699,25 +1699,25 @@ impl DocumentMessageHandler {
let document_mode_layout = WidgetLayout::new(vec![LayoutGroup::Row {
widgets: vec![
DropdownInput::new(
vec![vec![
MenuListEntry::new(format!("{:?}", DocumentMode::DesignMode))
.label(DocumentMode::DesignMode.to_string())
.icon(DocumentMode::DesignMode.icon_name()),
MenuListEntry::new(format!("{:?}", DocumentMode::SelectMode))
.label(DocumentMode::SelectMode.to_string())
.icon(DocumentMode::SelectMode.icon_name())
.on_commit(|_| DialogMessage::RequestComingSoonDialog { issue: Some(330) }.into()),
MenuListEntry::new(format!("{:?}", DocumentMode::GuideMode))
.label(DocumentMode::GuideMode.to_string())
.icon(DocumentMode::GuideMode.icon_name())
.on_commit(|_| DialogMessage::RequestComingSoonDialog { issue: Some(331) }.into()),
]])
.selected_index(Some(self.document_mode as u32))
.draw_icon(true)
.interactive(false) // TODO: set to true when dialogs are not spawned
.widget_holder(),
Separator::new(SeparatorType::Section).widget_holder(),
// DropdownInput::new(
// vec![vec![
// MenuListEntry::new(format!("{:?}", DocumentMode::DesignMode))
// .label(DocumentMode::DesignMode.to_string())
// .icon(DocumentMode::DesignMode.icon_name()),
// MenuListEntry::new(format!("{:?}", DocumentMode::SelectMode))
// .label(DocumentMode::SelectMode.to_string())
// .icon(DocumentMode::SelectMode.icon_name())
// .on_commit(|_| DialogMessage::RequestComingSoonDialog { issue: Some(330) }.into()),
// MenuListEntry::new(format!("{:?}", DocumentMode::GuideMode))
// .label(DocumentMode::GuideMode.to_string())
// .icon(DocumentMode::GuideMode.icon_name())
// .on_commit(|_| DialogMessage::RequestComingSoonDialog { issue: Some(331) }.into()),
// ]])
// .selected_index(Some(self.document_mode as u32))
// .draw_icon(true)
// .interactive(false) // TODO: set to true when dialogs are not spawned
// .widget_holder(),
// Separator::new(SeparatorType::Section).widget_holder(),
],
}]);
@@ -1744,7 +1744,7 @@ impl DocumentMessageHandler {
widgets: vec![TextLabel::new("Overlays").bold(true).widget_holder()],
},
LayoutGroup::Row {
widgets: vec![TextLabel::new("Coming soon").widget_holder()],
widgets: vec![TextLabel::new("Granular settings in this menu are coming soon").widget_holder()],
},
])
.widget_holder(),
@@ -1828,16 +1828,16 @@ impl DocumentMessageHandler {
_ => Some(1),
})
.widget_holder(),
PopoverButton::new()
.popover_layout(vec![
LayoutGroup::Row {
widgets: vec![TextLabel::new("View Mode").bold(true).widget_holder()],
},
LayoutGroup::Row {
widgets: vec![TextLabel::new("Coming soon").widget_holder()],
},
])
.widget_holder(),
// PopoverButton::new()
// .popover_layout(vec![
// LayoutGroup::Row {
// widgets: vec![TextLabel::new("View Mode").bold(true).widget_holder()],
// },
// LayoutGroup::Row {
// widgets: vec![TextLabel::new("Coming soon").widget_holder()],
// },
// ])
// .widget_holder(),
Separator::new(SeparatorType::Unrelated).widget_holder(),
];
@@ -2191,7 +2191,7 @@ impl<'a> ClickXRayIter<'a> {
}
}
pub fn navigation_controls(ptz: &PTZ, navigation_handler: &NavigationMessageHandler, tooltip_name: &str) -> [WidgetHolder; 6] {
pub fn navigation_controls(ptz: &PTZ, navigation_handler: &NavigationMessageHandler, tooltip_name: &str) -> [WidgetHolder; 5] {
[
IconButton::new("ZoomIn", 24)
.tooltip("Zoom In")
@@ -2209,34 +2209,34 @@ pub fn navigation_controls(ptz: &PTZ, navigation_handler: &NavigationMessageHand
.on_update(|_| NavigationMessage::CanvasTiltResetAndZoomTo100Percent.into())
.disabled(ptz.tilt().abs() < 1e-4 && (ptz.zoom() - 1.).abs() < 1e-4)
.widget_holder(),
PopoverButton::new()
.popover_layout(vec![
LayoutGroup::Row {
widgets: vec![TextLabel::new(format!("{tooltip_name} Navigation")).bold(true).widget_holder()],
},
LayoutGroup::Row {
widgets: vec![TextLabel::new({
let tilt = if tooltip_name == "Canvas" { "Tilt:\n• Alt + Middle Click Drag\n\n" } else { "" };
format!(
"
Interactive controls in this\n\
menu are coming soon.\n\
\n\
Pan:\n\
• Middle Click Drag\n\
\n\
{tilt}Zoom:\n\
• Shift + Middle Click Drag\n\
• Ctrl + Scroll Wheel Roll
"
)
.trim()
})
.multiline(true)
.widget_holder()],
},
])
.widget_holder(),
// PopoverButton::new()
// .popover_layout(vec![
// LayoutGroup::Row {
// widgets: vec![TextLabel::new(format!("{tooltip_name} Navigation")).bold(true).widget_holder()],
// },
// LayoutGroup::Row {
// widgets: vec![TextLabel::new({
// let tilt = if tooltip_name == "Canvas" { "Tilt:\n• Alt + Middle Click Drag\n\n" } else { "" };
// format!(
// "
// Interactive controls in this\n\
// menu are coming soon.\n\
// \n\
// Pan:\n\
// • Middle Click Drag\n\
// \n\
// {tilt}Zoom:\n\
// • Shift + Middle Click Drag\n\
// • Ctrl + Scroll Wheel Roll
// "
// )
// .trim()
// })
// .multiline(true)
// .widget_holder()],
// },
// ])
// .widget_holder(),
Separator::new(SeparatorType::Related).widget_holder(),
NumberInput::new(Some(navigation_handler.snapped_zoom(ptz.zoom()) * 100.))
.unit("%")
@@ -2250,13 +2250,17 @@ impl NodeGraphMessageHandler {
.map(|layer| layer.to_node())
.collect::<HashSet<_>>();
let mut selected_parents = HashSet::new();
let mut ancestors_of_selected = HashSet::new();
let mut descendants_of_selected = HashSet::new();
for selected_layer in &selected_layers {
for ancestor in LayerNodeIdentifier::new(*selected_layer, network_interface, &[]).ancestors(network_interface.document_metadata()) {
if ancestor != LayerNodeIdentifier::ROOT_PARENT && !selected_layers.contains(&ancestor.to_node()) {
selected_parents.insert(ancestor.to_node());
if ancestor != LayerNodeIdentifier::ROOT_PARENT && ancestor.to_node() != *selected_layer {
ancestors_of_selected.insert(ancestor.to_node());
}
}
for descendant in LayerNodeIdentifier::new(*selected_layer, network_interface, &[]).descendants(network_interface.document_metadata()) {
descendants_of_selected.insert(descendant.to_node());
}
}
for (&node_id, node_metadata) in &network_interface.network_metadata(&[]).unwrap().persistent_metadata.node_metadata {
@@ -2294,26 +2298,25 @@ impl NodeGraphMessageHandler {
}
});
let is_selected_parent = selected_parents.contains(&node_id);
let data = LayerPanelEntry {
id: node_id,
alias: network_interface.frontend_display_name(&node_id, &[]),
tooltip: if cfg!(debug_assertions) { format!("Layer ID: {node_id}") } else { "".into() },
in_selected_network: selection_network_path.is_empty(),
children_allowed,
children_present: layer.has_children(network_interface.document_metadata()),
expanded: layer.has_children(network_interface.document_metadata()) && !collapsed.0.contains(&layer),
depth: layer.ancestors(network_interface.document_metadata()).count() - 1,
parent_id: layer
.parent(network_interface.document_metadata())
.and_then(|parent| if parent != LayerNodeIdentifier::ROOT_PARENT { Some(parent.to_node()) } else { None }),
alias: network_interface.frontend_display_name(&node_id, &[]),
tooltip: if cfg!(debug_assertions) { format!("Layer ID: {node_id}") } else { "".into() },
visible: network_interface.is_visible(&node_id, &[]),
parents_visible,
unlocked: !network_interface.is_locked(&node_id, &[]),
parents_unlocked,
selected: selected_layers.contains(&node_id) || is_selected_parent,
in_selected_network: selection_network_path.is_empty(),
selected_parent: is_selected_parent,
parent_id: layer
.parent(network_interface.document_metadata())
.and_then(|parent| if parent != LayerNodeIdentifier::ROOT_PARENT { Some(parent.to_node()) } else { None }),
selected: selected_layers.contains(&node_id),
ancestor_of_selected: ancestors_of_selected.contains(&node_id),
descendant_of_selected: descendants_of_selected.contains(&node_id),
};
responses.add(FrontendMessage::UpdateDocumentLayerDetails { data });
}
@@ -36,6 +36,8 @@ pub struct LayerPanelEntry {
pub id: NodeId,
pub alias: String,
pub tooltip: String,
#[serde(rename = "inSelectedNetwork")]
pub in_selected_network: bool,
#[serde(rename = "childrenAllowed")]
pub children_allowed: bool,
#[serde(rename = "childrenPresent")]
@@ -51,10 +53,10 @@ pub struct LayerPanelEntry {
#[serde(rename = "parentId")]
pub parent_id: Option<NodeId>,
pub selected: bool,
#[serde(rename = "inSelectedNetwork")]
pub in_selected_network: bool,
#[serde(rename = "selectedParent")]
pub selected_parent: bool,
#[serde(rename = "ancestorOfSelected")]
pub ancestor_of_selected: bool,
#[serde(rename = "descendantOfSelected")]
pub descendant_of_selected: bool,
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, PartialEq, Eq, specta::Type)]
@@ -176,19 +176,19 @@ impl LayoutHolder for SelectTool {
let disabled = self.tool_data.selected_layers_count < 2;
widgets.push(Separator::new(SeparatorType::Unrelated).widget_holder());
widgets.extend(self.alignment_widgets(disabled));
widgets.push(
PopoverButton::new()
.popover_layout(vec![
LayoutGroup::Row {
widgets: vec![TextLabel::new("Align").bold(true).widget_holder()],
},
LayoutGroup::Row {
widgets: vec![TextLabel::new("Coming soon").widget_holder()],
},
])
.disabled(disabled)
.widget_holder(),
);
// widgets.push(
// PopoverButton::new()
// .popover_layout(vec![
// LayoutGroup::Row {
// widgets: vec![TextLabel::new("Align").bold(true).widget_holder()],
// },
// LayoutGroup::Row {
// widgets: vec![TextLabel::new("Coming soon").widget_holder()],
// },
// ])
// .disabled(disabled)
// .widget_holder(),
// );
// Flip
let disabled = self.tool_data.selected_layers_count == 0;
+7 -10
View File
@@ -250,14 +250,13 @@ impl LayoutHolder for ToolData {
.iter()
.map(|tool_group| tool_group.iter().map(|tool_availability| {
match tool_availability {
ToolAvailability::Available(tool) => ToolEntry::new( tool.tool_type(), tool.icon_name())
.tooltip( tool.tooltip())
.tooltip_shortcut(action_keys!(tool_type_to_activate_tool_message(tool.tool_type())))
,
ToolAvailability::Available(tool) => ToolEntry::new(tool.tool_type(), tool.icon_name())
.tooltip(tool.tooltip())
.tooltip_shortcut(action_keys!(tool_type_to_activate_tool_message(tool.tool_type()))),
ToolAvailability::ComingSoon(tool) => tool.clone(),
}
}).collect::<Vec<_>>())
})
.collect::<Vec<_>>())
.flat_map(|group| {
let separator = std::iter::once(Separator::new(SeparatorType::Section).direction(SeparatorDirection::Vertical).widget_holder());
let buttons = group.into_iter().map(|ToolEntry { tooltip, tooltip_shortcut, tool_type, icon_name }| {
@@ -397,16 +396,14 @@ fn list_tools_in_groups() -> Vec<Vec<ToolAvailability>> {
],
vec![
// Raster tool group
// ToolAvailability::Available(Box::<imaginate_tool::ImaginateTool>::default()), // TODO: Fix and reenable ASAP
ToolAvailability::ComingSoon(
ToolEntry::new(ToolType::Heal, "RasterImaginateTool").tooltip("Coming Soon: Imaginate Tool - Temporarily disabled, please use Imaginate node directly from graph"),
),
ToolAvailability::Available(Box::<brush_tool::BrushTool>::default()),
ToolAvailability::ComingSoon(ToolEntry::new(ToolType::Heal, "RasterHealTool").tooltip("Coming Soon: Heal Tool (J)")),
ToolAvailability::ComingSoon(ToolEntry::new(ToolType::Clone, "RasterCloneTool").tooltip("Coming Soon: Clone Tool (C)")),
ToolAvailability::ComingSoon(ToolEntry::new(ToolType::Patch, "RasterPatchTool").tooltip("Coming Soon: Patch Tool")),
ToolAvailability::ComingSoon(ToolEntry::new(ToolType::Detail, "RasterDetailTool").tooltip("Coming Soon: Detail Tool (D)")),
ToolAvailability::ComingSoon(ToolEntry::new(ToolType::Relight, "RasterRelightTool").tooltip("Coming Soon: Relight Tool (O)")),
// ToolAvailability::Available(Box::<imaginate_tool::ImaginateTool>::default()), // TODO: Fix and reenable
ToolAvailability::ComingSoon(ToolEntry::new(ToolType::Heal, "RasterImaginateTool").tooltip("Coming Soon: Imaginate Tool")),
],
]
}