From 96b5d7b520bab9a41952196bddc317f8970050f5 Mon Sep 17 00:00:00 2001 From: Keavon Chambers Date: Thu, 28 Dec 2023 04:35:20 -0800 Subject: [PATCH] Many subtle improvements to the UI design system (#1537) --- .../simple_dialogs/about_graphite_dialog.rs | 4 +- .../simple_dialogs/coming_soon_dialog.rs | 2 +- .../dialog/simple_dialogs/licenses_dialog.rs | 2 +- .../src/messages/frontend/frontend_message.rs | 5 -- .../messages/input_mapper/default_mapping.rs | 4 +- .../messages/layout/layout_message_handler.rs | 9 +- .../layout/utility_types/layout_widget.rs | 11 +-- .../utility_types/widgets/button_widgets.rs | 15 +--- .../utility_types/widgets/input_widgets.rs | 34 +++----- .../utility_types/widgets/label_widgets.rs | 1 - .../portfolio/document/document_message.rs | 4 + .../document/document_message_handler.rs | 83 +++++++++++++------ .../node_graph/node_graph_message_handler.rs | 24 ++++-- .../node_properties.rs | 52 ++++-------- .../properties_panel_message_handler.rs | 4 +- .../messages/portfolio/portfolio_message.rs | 4 - .../portfolio/portfolio_message_handler.rs | 40 +-------- .../messages/tool/tool_messages/brush_tool.rs | 4 +- .../tool/tool_messages/ellipse_tool.rs | 2 +- .../tool/tool_messages/freehand_tool.rs | 2 +- .../messages/tool/tool_messages/pen_tool.rs | 2 +- .../tool/tool_messages/polygon_tool.rs | 4 +- .../tool/tool_messages/rectangle_tool.rs | 2 +- .../tool/tool_messages/select_tool.rs | 9 +- .../tool/tool_messages/spline_tool.rs | 2 +- .../messages/tool/tool_messages/text_tool.rs | 2 +- editor/src/messages/tool/utility_types.rs | 2 +- frontend/src/components/Editor.svelte | 7 +- .../floating-menus/ColorPicker.svelte | 2 +- .../components/floating-menus/Dialog.svelte | 4 +- .../components/floating-menus/MenuList.svelte | 12 ++- .../src/components/panels/Document.svelte | 26 +++--- frontend/src/components/panels/Layers.svelte | 1 - .../src/components/panels/Properties.svelte | 10 +++ frontend/src/components/views/Graph.svelte | 53 ++---------- .../components/widgets/WidgetSection.svelte | 9 +- .../src/components/widgets/WidgetSpan.svelte | 69 +++------------ .../widgets/buttons/ColorButton.svelte | 8 +- .../widgets/buttons/IconButton.svelte | 13 +-- .../buttons/ParameterExposeButton.svelte | 45 ++++++++-- .../widgets/buttons/PopoverButton.svelte | 53 +++++++----- .../widgets/buttons/TextButton.svelte | 10 +-- .../widgets/inputs/CurveInput.svelte | 4 +- .../widgets/inputs/DropdownInput.svelte | 5 +- .../widgets/inputs/FieldInput.svelte | 7 +- .../widgets/inputs/FontInput.svelte | 3 +- .../widgets/inputs/NumberInput.svelte | 4 +- .../widgets/inputs/OptionalInput.svelte | 36 -------- .../widgets/inputs/RadioInput.svelte | 4 +- .../widgets/inputs/RulerInput.svelte | 2 +- .../widgets/inputs/TextInput.svelte | 2 - .../WorkingColorsInput.svelte} | 0 .../widgets/labels/Separator.svelte | 55 +++++------- .../widgets/labels/UserInputLabel.svelte | 4 +- .../window/status-bar/StatusBar.svelte | 3 +- .../window/title-bar/TitleBar.svelte | 2 +- .../components/window/workspace/Panel.svelte | 21 +++-- frontend/src/state-providers/document.ts | 10 --- frontend/src/utility-functions/icons.ts | 1 + frontend/src/wasm-communication/messages.ts | 29 ++----- website/content/learn/introduction/_index.md | 2 +- .../introduction/features-and-limitations.md | 2 +- 62 files changed, 326 insertions(+), 521 deletions(-) delete mode 100644 frontend/src/components/widgets/inputs/OptionalInput.svelte rename frontend/src/components/widgets/{buttons/WorkingColorsButton.svelte => inputs/WorkingColorsInput.svelte} (100%) diff --git a/editor/src/messages/dialog/simple_dialogs/about_graphite_dialog.rs b/editor/src/messages/dialog/simple_dialogs/about_graphite_dialog.rs index e07d33a6..861c7d32 100644 --- a/editor/src/messages/dialog/simple_dialogs/about_graphite_dialog.rs +++ b/editor/src/messages/dialog/simple_dialogs/about_graphite_dialog.rs @@ -29,7 +29,7 @@ impl DialogLayoutHolder for AboutGraphiteDialog { .map(|(icon, label, url)| { TextButton::new(label) .icon(Some(icon.into())) - .no_background(true) + .flush(true) .on_update(|_| FrontendMessage::TriggerVisitLink { url: url.into() }.into()) .widget_holder() }) @@ -40,7 +40,7 @@ impl DialogLayoutHolder for AboutGraphiteDialog { widgets.push( TextButton::new("Licenses") .icon(Some("License".into())) - .no_background(true) + .flush(true) .on_update(move |_| { DialogMessage::RequestLicensesDialogWithLocalizedCommitDate { localized_commit_year: localized_commit_year.clone(), diff --git a/editor/src/messages/dialog/simple_dialogs/coming_soon_dialog.rs b/editor/src/messages/dialog/simple_dialogs/coming_soon_dialog.rs index aff7f224..39247f1f 100644 --- a/editor/src/messages/dialog/simple_dialogs/coming_soon_dialog.rs +++ b/editor/src/messages/dialog/simple_dialogs/coming_soon_dialog.rs @@ -28,7 +28,7 @@ impl LayoutHolder for ComingSoonDialog { let row2 = vec![TextLabel::new("But you can help build it! Visit its issue:").widget_holder()]; let row3 = vec![TextButton::new(format!("GitHub Issue #{issue}")) .icon(Some("Website".into())) - .no_background(true) + .flush(true) .on_update(move |_| { FrontendMessage::TriggerVisitLink { url: format!("https://github.com/GraphiteEditor/Graphite/issues/{issue}"), diff --git a/editor/src/messages/dialog/simple_dialogs/licenses_dialog.rs b/editor/src/messages/dialog/simple_dialogs/licenses_dialog.rs index d1cb8c56..694a9986 100644 --- a/editor/src/messages/dialog/simple_dialogs/licenses_dialog.rs +++ b/editor/src/messages/dialog/simple_dialogs/licenses_dialog.rs @@ -28,7 +28,7 @@ impl DialogLayoutHolder for LicensesDialog { .map(|(icon, label, url)| { TextButton::new(label) .icon(Some(icon.into())) - .no_background(true) + .flush(true) .on_update(|_| FrontendMessage::TriggerVisitLink { url: url.into() }.into()) .widget_holder() }) diff --git a/editor/src/messages/frontend/frontend_message.rs b/editor/src/messages/frontend/frontend_message.rs index ccedbc30..e2208d27 100644 --- a/editor/src/messages/frontend/frontend_message.rs +++ b/editor/src/messages/frontend/frontend_message.rs @@ -173,11 +173,6 @@ pub enum FrontendMessage { #[serde(rename = "setColorChoice")] set_color_choice: Option, }, - UpdateGraphViewOverlayButtonLayout { - #[serde(rename = "layoutTarget")] - layout_target: LayoutTarget, - diff: Vec, - }, UpdateImageData { #[serde(rename = "documentId")] document_id: DocumentId, diff --git a/editor/src/messages/input_mapper/default_mapping.rs b/editor/src/messages/input_mapper/default_mapping.rs index cc9e86f8..1f1d62e1 100644 --- a/editor/src/messages/input_mapper/default_mapping.rs +++ b/editor/src/messages/input_mapper/default_mapping.rs @@ -264,6 +264,8 @@ pub fn default_mapping() -> Mapping { entry!(KeyDown(KeyC); modifiers=[Alt], action_dispatch=ToolMessage::SelectRandomPrimaryColor), // // DocumentMessage + entry!(KeyDown(Space); modifiers=[Control], action_dispatch=DocumentMessage::GraphViewOverlayToggle), + entry!(KeyUp(Escape); action_dispatch=DocumentMessage::GraphViewOverlay { open: false }), entry!(KeyDown(Delete); action_dispatch=DocumentMessage::DeleteSelectedLayers), entry!(KeyDown(Backspace); action_dispatch=DocumentMessage::DeleteSelectedLayers), entry!(KeyDown(KeyP); modifiers=[Alt], action_dispatch=DocumentMessage::DebugPrintDocument), @@ -337,8 +339,6 @@ pub fn default_mapping() -> Mapping { entry!(KeyDown(Period); action_dispatch=NavigationMessage::FitViewportToSelection), // // PortfolioMessage - entry!(KeyDown(Space); modifiers=[Control], action_dispatch=PortfolioMessage::GraphViewOverlayToggle), - entry!(KeyUp(Escape); action_dispatch=PortfolioMessage::GraphViewOverlay { open: false }), entry!(KeyDown(Tab); modifiers=[Control], action_dispatch=PortfolioMessage::NextDocument), entry!(KeyDown(Tab); modifiers=[Control, Shift], action_dispatch=PortfolioMessage::PrevDocument), entry!(KeyDown(KeyW); modifiers=[Accel], action_dispatch=PortfolioMessage::CloseActiveDocumentWithConfirmation), diff --git a/editor/src/messages/layout/layout_message_handler.rs b/editor/src/messages/layout/layout_message_handler.rs index 8c75d468..93ad87cb 100644 --- a/editor/src/messages/layout/layout_message_handler.rs +++ b/editor/src/messages/layout/layout_message_handler.rs @@ -171,12 +171,6 @@ impl Vec> MessageHandler {} // If it's some other type we could just ignore it and leave the value as is }, - Widget::OptionalInput(optional_input) => { - let update_value = value.as_bool().expect("OptionalInput update was not of type: bool"); - optional_input.checked = update_value; - let callback_message = (optional_input.on_update.callback)(optional_input); - responses.add(callback_message); - } Widget::ParameterExposeButton(parameter_expose_button) => { let callback_message = (parameter_expose_button.on_update.callback)(parameter_expose_button); responses.add(callback_message); @@ -212,7 +206,7 @@ impl Vec> MessageHandler {} - Widget::WorkingColorsButton(_) => {} + Widget::WorkingColorsInput(_) => {} }; responses.add(ResendActiveWidget { layout_target, dirty_id: widget_id }); } @@ -273,7 +267,6 @@ impl LayoutMessageHandler { LayoutTarget::DialogColumn2 => FrontendMessage::UpdateDialogColumn2 { layout_target, diff }, LayoutTarget::DocumentBar => FrontendMessage::UpdateDocumentBarLayout { layout_target, diff }, LayoutTarget::DocumentMode => FrontendMessage::UpdateDocumentModeLayout { layout_target, diff }, - LayoutTarget::GraphViewOverlayButton => FrontendMessage::UpdateGraphViewOverlayButtonLayout { layout_target, diff }, LayoutTarget::LayersPanelOptions => FrontendMessage::UpdateLayersPanelOptionsLayout { layout_target, diff }, LayoutTarget::MenuBar => unreachable!("Menu bar is not diffed"), LayoutTarget::NodeGraphBar => FrontendMessage::UpdateNodeGraphBarLayout { layout_target, diff }, diff --git a/editor/src/messages/layout/utility_types/layout_widget.rs b/editor/src/messages/layout/utility_types/layout_widget.rs index f1262130..1234d79a 100644 --- a/editor/src/messages/layout/utility_types/layout_widget.rs +++ b/editor/src/messages/layout/utility_types/layout_widget.rs @@ -34,8 +34,6 @@ pub enum LayoutTarget { DocumentBar, /// Contains the dropdown for design / select / guide mode found on the top left of the canvas. DocumentMode, - /// The button below the tool shelf and directly above the working colors which lets the user toggle the node graph overlaid on the canvas. - GraphViewOverlayButton, /// Options for opacity seen at the top of the Layers panel. LayersPanelOptions, /// The dropdown menu at the very top of the application: File, Edit, etc. @@ -337,7 +335,6 @@ impl LayoutGroup { Widget::IconLabel(x) => &mut x.tooltip, Widget::ImageLabel(x) => &mut x.tooltip, Widget::NumberInput(x) => &mut x.tooltip, - Widget::OptionalInput(x) => &mut x.tooltip, Widget::ParameterExposeButton(x) => &mut x.tooltip, Widget::PopoverButton(x) => &mut x.tooltip, Widget::TextAreaInput(x) => &mut x.tooltip, @@ -345,7 +342,7 @@ impl LayoutGroup { Widget::TextInput(x) => &mut x.tooltip, Widget::TextLabel(x) => &mut x.tooltip, Widget::BreadcrumbTrailButtons(x) => &mut x.tooltip, - Widget::InvisibleStandinInput(_) | Widget::PivotInput(_) | Widget::RadioInput(_) | Widget::Separator(_) | Widget::WorkingColorsButton(_) => continue, + Widget::InvisibleStandinInput(_) | Widget::PivotInput(_) | Widget::RadioInput(_) | Widget::Separator(_) | Widget::WorkingColorsInput(_) => continue, }; if val.is_empty() { *val = tooltip.clone(); @@ -491,7 +488,6 @@ pub enum Widget { ImageLabel(ImageLabel), InvisibleStandinInput(InvisibleStandinInput), NumberInput(NumberInput), - OptionalInput(OptionalInput), ParameterExposeButton(ParameterExposeButton), PivotInput(PivotInput), PopoverButton(PopoverButton), @@ -501,7 +497,7 @@ pub enum Widget { TextButton(TextButton), TextInput(TextInput), TextLabel(TextLabel), - WorkingColorsButton(WorkingColorsButton), + WorkingColorsInput(WorkingColorsInput), } /// A single change to part of the UI, containing the location of the change and the new value. @@ -560,7 +556,6 @@ impl DiffUpdate { Widget::FontInput(widget) => Some((&mut widget.tooltip, &mut widget.tooltip_shortcut)), Widget::IconButton(widget) => Some((&mut widget.tooltip, &mut widget.tooltip_shortcut)), Widget::NumberInput(widget) => Some((&mut widget.tooltip, &mut widget.tooltip_shortcut)), - Widget::OptionalInput(widget) => Some((&mut widget.tooltip, &mut widget.tooltip_shortcut)), Widget::ParameterExposeButton(widget) => Some((&mut widget.tooltip, &mut widget.tooltip_shortcut)), Widget::PopoverButton(widget) => Some((&mut widget.tooltip, &mut widget.tooltip_shortcut)), Widget::TextButton(widget) => Some((&mut widget.tooltip, &mut widget.tooltip_shortcut)), @@ -574,7 +569,7 @@ impl DiffUpdate { | Widget::TextAreaInput(_) | Widget::TextInput(_) | Widget::TextLabel(_) - | Widget::WorkingColorsButton(_) => None, + | Widget::WorkingColorsInput(_) => None, }; if let Some((tooltip, Some(tooltip_shortcut))) = &mut tooltip_shortcut { apply_shortcut_to_tooltip(tooltip_shortcut, tooltip); diff --git a/editor/src/messages/layout/utility_types/widgets/button_widgets.rs b/editor/src/messages/layout/utility_types/widgets/button_widgets.rs index 1f907034..e8ebc4e8 100644 --- a/editor/src/messages/layout/utility_types/widgets/button_widgets.rs +++ b/editor/src/messages/layout/utility_types/widgets/button_widgets.rs @@ -35,6 +35,8 @@ pub struct IconButton { #[derive(Clone, Serialize, Deserialize, Derivative, WidgetBuilder, specta::Type)] #[derivative(Debug, PartialEq, Default)] pub struct PopoverButton { + pub style: Option, + pub icon: Option, pub disabled: bool, @@ -85,8 +87,7 @@ pub struct TextButton { pub icon: Option, - #[serde(rename = "noBackground")] - pub no_background: bool, + pub flush: bool, pub emphasized: bool, @@ -109,16 +110,6 @@ pub struct TextButton { pub on_update: WidgetCallback, } -#[derive(Clone, Serialize, Deserialize, Derivative, WidgetBuilder, specta::Type)] -#[derivative(Debug, PartialEq, Default)] -pub struct WorkingColorsButton { - #[widget_builder(constructor)] - pub primary: Color, - - #[widget_builder(constructor)] - pub secondary: Color, -} - #[derive(Clone, Derivative, Serialize, Deserialize, WidgetBuilder, specta::Type)] #[derivative(Debug, PartialEq, Default)] pub struct ColorButton { diff --git a/editor/src/messages/layout/utility_types/widgets/input_widgets.rs b/editor/src/messages/layout/utility_types/widgets/input_widgets.rs index 1e96e34d..cc2969a4 100644 --- a/editor/src/messages/layout/utility_types/widgets/input_widgets.rs +++ b/editor/src/messages/layout/utility_types/widgets/input_widgets.rs @@ -1,7 +1,7 @@ use crate::messages::input_mapper::utility_types::misc::ActionKeys; use crate::messages::layout::utility_types::widget_prelude::*; -use graphene_core::raster::curve::Curve; +use graphene_core::{raster::curve::Curve, Color}; use graphite_proc_macros::WidgetBuilder; use derivative::*; @@ -253,28 +253,6 @@ pub enum NumberInputMode { Range, } -#[derive(Clone, Default, Derivative, Serialize, Deserialize, WidgetBuilder, specta::Type)] -#[derivative(Debug, PartialEq)] -pub struct OptionalInput { - #[widget_builder(constructor)] - pub checked: bool, - - pub disabled: bool, - - #[widget_builder(constructor)] - pub icon: String, - - pub tooltip: String, - - #[serde(skip)] - pub tooltip_shortcut: Option, - - // Callbacks - #[serde(skip)] - #[derivative(Debug = "ignore", PartialEq = "ignore")] - pub on_update: WidgetCallback, -} - #[derive(Clone, Default, Derivative, Serialize, Deserialize, WidgetBuilder, specta::Type)] #[derivative(Debug, PartialEq)] pub struct RadioInput { @@ -310,6 +288,16 @@ pub struct RadioEntryData { pub on_update: WidgetCallback<()>, } +#[derive(Clone, Serialize, Deserialize, Derivative, WidgetBuilder, specta::Type)] +#[derivative(Debug, PartialEq, Default)] +pub struct WorkingColorsInput { + #[widget_builder(constructor)] + pub primary: Color, + + #[widget_builder(constructor)] + pub secondary: Color, +} + #[derive(Clone, Serialize, Deserialize, Derivative, WidgetBuilder, specta::Type)] #[derivative(Debug, PartialEq, Default)] pub struct TextAreaInput { diff --git a/editor/src/messages/layout/utility_types/widgets/label_widgets.rs b/editor/src/messages/layout/utility_types/widgets/label_widgets.rs index 3c48b0ca..a81c2a9b 100644 --- a/editor/src/messages/layout/utility_types/widgets/label_widgets.rs +++ b/editor/src/messages/layout/utility_types/widgets/label_widgets.rs @@ -46,7 +46,6 @@ pub enum SeparatorType { #[default] Unrelated, Section, - List, } #[derive(Clone, Serialize, Deserialize, Derivative, Debug, PartialEq, Eq, Default, WidgetBuilder, specta::Type)] diff --git a/editor/src/messages/portfolio/document/document_message.rs b/editor/src/messages/portfolio/document/document_message.rs index 2096fbd9..53c480e5 100644 --- a/editor/src/messages/portfolio/document/document_message.rs +++ b/editor/src/messages/portfolio/document/document_message.rs @@ -59,6 +59,10 @@ pub enum DocumentMessage { FlipSelectedLayers { flip_axis: FlipAxis, }, + GraphViewOverlay { + open: bool, + }, + GraphViewOverlayToggle, GroupSelectedLayers, ImaginateGenerate, ImaginateRandom { diff --git a/editor/src/messages/portfolio/document/document_message_handler.rs b/editor/src/messages/portfolio/document/document_message_handler.rs index 1853114d..deedc21e 100644 --- a/editor/src/messages/portfolio/document/document_message_handler.rs +++ b/editor/src/messages/portfolio/document/document_message_handler.rs @@ -81,6 +81,8 @@ pub struct DocumentMessageHandler { #[serde(skip)] undo_in_progress: bool, #[serde(skip)] + graph_view_overlay_open: bool, + #[serde(skip)] pub snapping_state: SnappingState, #[serde(skip)] layer_range_selection_reference: Option, @@ -119,6 +121,7 @@ impl Default for DocumentMessageHandler { saved_hash: None, auto_saved_hash: None, undo_in_progress: false, + graph_view_overlay_open: false, snapping_state: SnappingState::default(), layer_range_selection_reference: None, metadata: Default::default(), @@ -227,7 +230,6 @@ pub struct DocumentInputs<'a> { pub ipp: &'a InputPreprocessorMessageHandler, pub persistent_data: &'a PersistentData, pub executor: &'a mut NodeGraphExecutor, - pub graph_view_overlay_open: bool, } impl MessageHandler> for DocumentMessageHandler { @@ -238,7 +240,6 @@ impl MessageHandler> for DocumentMessageHand ipp, persistent_data, executor, - graph_view_overlay_open, } = document_inputs; use DocumentMessage::*; @@ -282,7 +283,7 @@ impl MessageHandler> for DocumentMessageHand document_name: self.name.as_str(), collapsed: &mut self.collapsed, input: ipp, - graph_view_overlay_open, + graph_view_overlay_open: self.graph_view_overlay_open, }, ); } @@ -382,7 +383,11 @@ impl MessageHandler> for DocumentMessageHand self.update_layers_panel_options_bar_widgets(responses); let data_buffer: RawBuffer = self.serialize_root(); - responses.add(FrontendMessage::UpdateDocumentLayerStructure { data_buffer }) + responses.add(FrontendMessage::UpdateDocumentLayerStructure { data_buffer }); + + if self.graph_view_overlay_open { + responses.add(NodeGraphMessage::SendGraph { should_rerender: false }); + } } DuplicateSelectedLayers => { // TODO: Reimplement selected layer duplication @@ -412,6 +417,17 @@ impl MessageHandler> for DocumentMessageHand responses.add(BroadcastEvent::DocumentIsDirty); } } + GraphViewOverlay { open } => { + self.graph_view_overlay_open = open; + + if open { + responses.add(NodeGraphMessage::SendGraph { should_rerender: false }); + } + responses.add(FrontendMessage::TriggerGraphViewOverlay { open }); + } + GraphViewOverlayToggle => { + responses.add(DocumentMessage::GraphViewOverlay { open: !self.graph_view_overlay_open }); + } GroupSelectedLayers => { // TODO: Add code that changes the insert index of the new folder based on the selected layer let parent = self.metadata().deepest_common_ancestor(self.metadata().selected_layers(), true).unwrap_or(LayerNodeIdentifier::ROOT); @@ -1089,9 +1105,10 @@ impl DocumentMessageHandler { pub fn update_document_widgets(&self, responses: &mut VecDeque) { let snapping_state = self.snapping_state.clone(); let mut widgets = vec![ - OptionalInput::new(snapping_state.snapping_enabled, "Snapping") + CheckboxInput::new(snapping_state.snapping_enabled) + .icon("Snapping") .tooltip("Snapping") - .on_update(move |optional_input: &OptionalInput| { + .on_update(move |optional_input: &CheckboxInput| { let snapping_enabled = optional_input.checked; DocumentMessage::SetSnapping { snapping_enabled: Some(snapping_enabled), @@ -1105,6 +1122,8 @@ impl DocumentMessageHandler { .options_widget(vec![ LayoutGroup::Row { widgets: vec![ + TextLabel::new(SnappingOptions::BoundingBoxes.to_string()).table_align(true).min_width(96).widget_holder(), + Separator::new(SeparatorType::Unrelated).widget_holder(), CheckboxInput::new(snapping_state.bounding_box_snapping) .tooltip(SnappingOptions::BoundingBoxes.to_string()) .on_update(move |input: &CheckboxInput| { @@ -1116,13 +1135,13 @@ impl DocumentMessageHandler { .into() }) .widget_holder(), - Separator::new(SeparatorType::Unrelated).widget_holder(), - TextLabel::new(SnappingOptions::BoundingBoxes.to_string()).table_align(false).min_width(60).widget_holder(), Separator::new(SeparatorType::Related).widget_holder(), ], }, LayoutGroup::Row { widgets: vec![ + TextLabel::new(SnappingOptions::Points.to_string()).table_align(true).min_width(96).widget_holder(), + Separator::new(SeparatorType::Unrelated).widget_holder(), CheckboxInput::new(self.snapping_state.node_snapping) .tooltip(SnappingOptions::Points.to_string()) .on_update(|input: &CheckboxInput| { @@ -1134,22 +1153,22 @@ impl DocumentMessageHandler { .into() }) .widget_holder(), - Separator::new(SeparatorType::Unrelated).widget_holder(), - TextLabel::new(SnappingOptions::Points.to_string()).table_align(false).min_width(60).widget_holder(), ], }, ]) .widget_holder(), - Separator::new(SeparatorType::Unrelated).widget_holder(), - OptionalInput::new(true, "Grid") + Separator::new(SeparatorType::Related).widget_holder(), + CheckboxInput::new(true) + .icon("Grid") .tooltip("Grid") .on_update(|_| DialogMessage::RequestComingSoonDialog { issue: Some(318) }.into()) .widget_holder(), PopoverButton::new("Grid", "Coming soon").widget_holder(), - Separator::new(SeparatorType::Unrelated).widget_holder(), - OptionalInput::new(self.overlays_visible, "Overlays") + Separator::new(SeparatorType::Related).widget_holder(), + CheckboxInput::new(self.overlays_visible) + .icon("Overlays") .tooltip("Overlays") - .on_update(|optional_input: &OptionalInput| DocumentMessage::SetOverlaysVisibility { visible: optional_input.checked }.into()) + .on_update(|optional_input: &CheckboxInput| DocumentMessage::SetOverlaysVisibility { visible: optional_input.checked }.into()) .widget_holder(), PopoverButton::new("Overlays", "Coming soon").widget_holder(), Separator::new(SeparatorType::Unrelated).widget_holder(), @@ -1176,7 +1195,7 @@ impl DocumentMessageHandler { }) .widget_holder(), PopoverButton::new("View Mode", "Coming soon").widget_holder(), - Separator::new(SeparatorType::Section).widget_holder(), + Separator::new(SeparatorType::Unrelated).widget_holder(), IconButton::new("ZoomIn", 24) .tooltip("Zoom In") .tooltip_shortcut(action_keys!(NavigationMessageDiscriminant::IncreaseCanvasZoom)) @@ -1192,6 +1211,11 @@ impl DocumentMessageHandler { .tooltip_shortcut(action_keys!(DocumentMessageDiscriminant::ZoomCanvasTo100Percent)) .on_update(|_| NavigationMessage::SetCanvasZoom { zoom_factor: 1. }.into()) .widget_holder(), + PopoverButton::new( + "Canvas Navigation", + "Interactive controls in this\nmenu are coming soon.\n\nPan:\n• Middle Click Drag\n\nTilt:\n• Alt + Middle Click Drag\n\nZoom:\n• Shift + Middle Click Drag\n• Ctrl + Scroll Wheel Roll", + ) + .widget_holder(), Separator::new(SeparatorType::Related).widget_holder(), NumberInput::new(Some(self.navigation_handler.snapped_scale(self.navigation.zoom) * 100.)) .unit("%") @@ -1208,6 +1232,13 @@ impl DocumentMessageHandler { .increment_callback_decrease(|_| NavigationMessage::DecreaseCanvasZoom { center_on_mouse: false }.into()) .increment_callback_increase(|_| NavigationMessage::IncreaseCanvasZoom { center_on_mouse: false }.into()) .widget_holder(), + Separator::new(SeparatorType::Unrelated).widget_holder(), + TextButton::new("Node Graph") + .icon(Some(if self.graph_view_overlay_open { "GraphViewOpen".into() } else { "GraphViewClosed".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()) + .widget_holder(), ]; let rotation_value = self.navigation_handler.snapped_angle(self.navigation.tilt) / (std::f64::consts::PI / 180.); if rotation_value.abs() > 0.00001 { @@ -1225,14 +1256,6 @@ impl DocumentMessageHandler { .widget_holder(), ]); } - widgets.extend([ - Separator::new(SeparatorType::Related).widget_holder(), - PopoverButton::new( - "Canvas Navigation", - "Interactive options in this popover\nmenu are coming soon.\n\nZoom:\n• Shift + Middle Click Drag\n• Ctrl + Scroll Wheel Roll\nRotate:\n• Alt + Left Click Drag", - ) - .widget_holder(), - ]); let document_bar_layout = WidgetLayout::new(vec![LayoutGroup::Row { widgets }]); let document_mode_layout = WidgetLayout::new(vec![LayoutGroup::Row { @@ -1339,7 +1362,7 @@ impl DocumentMessageHandler { } }) .widget_holder(), - Separator::new(SeparatorType::Section).widget_holder(), + Separator::new(SeparatorType::Unrelated).widget_holder(), IconButton::new("Folder", 24) .tooltip("New Folder") .tooltip_shortcut(action_keys!(DocumentMessageDiscriminant::CreateEmptyFolder)) @@ -1398,7 +1421,7 @@ impl DocumentMessageHandler { responses.add(DocumentMessage::MoveSelectedLayersTo { parent, insert_index }); } - pub fn actions_with_graph_open(&self, graph_open: bool) -> ActionList { + pub fn actions_with_graph_open(&self) -> ActionList { let mut common = actions!(DocumentMessageDiscriminant; Undo, Redo, @@ -1411,9 +1434,15 @@ impl DocumentMessageHandler { ZoomCanvasToFitAll, ZoomCanvasTo100Percent, ZoomCanvasTo200Percent, + GraphViewOverlayToggle, CreateEmptyFolder, ); + if self.graph_view_overlay_open { + let escape = actions!(DocumentMessageDiscriminant; GraphViewOverlay); + common.extend(escape); + } + if self.metadata().selected_layers().next().is_some() { let select = actions!(DocumentMessageDiscriminant; DeleteSelectedLayers, @@ -1429,7 +1458,7 @@ impl DocumentMessageHandler { common.extend(select); } common.extend(self.navigation_handler.actions()); - common.extend(self.node_graph_handler.actions_with_node_graph_open(graph_open)); + common.extend(self.node_graph_handler.actions_with_node_graph_open(self.graph_view_overlay_open)); common } } diff --git a/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler.rs b/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler.rs index 5622887d..d3dffe7a 100644 --- a/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler.rs +++ b/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler.rs @@ -130,14 +130,22 @@ pub struct NodeGraphMessageHandler { impl Default for NodeGraphMessageHandler { fn default() -> Self { - // TODO: Replace this with an "Add Node" button, also next to an "Add Layer" button - let add_nodes_label = TextLabel::new("Right Click Graph to Add Nodes").italic(true).widget_holder(); - let add_nodes_label_row = LayoutGroup::Row { widgets: vec![add_nodes_label] }; + let right_side_widgets = vec![ + // TODO: Replace this with an "Add Node" button, also next to an "Add Layer" button + TextLabel::new("Right Click in Graph to Add Nodes").italic(true).widget_holder(), + Separator::new(SeparatorType::Unrelated).widget_holder(), + TextButton::new("Node Graph") + .icon(Some("GraphViewOpen".into())) + .tooltip("Hide Node Graph") + .tooltip_shortcut(action_keys!(DocumentMessageDiscriminant::GraphViewOverlayToggle)) + .on_update(move |_| DocumentMessage::GraphViewOverlayToggle.into()) + .widget_holder(), + ]; Self { network: Vec::new(), has_selection: false, - widgets: [add_nodes_label_row, LayoutGroup::default()], + widgets: [LayoutGroup::Row { widgets: Vec::new() }, LayoutGroup::Row { widgets: right_side_widgets }], } } } @@ -161,8 +169,6 @@ impl NodeGraphMessageHandler { // If there is at least one other selected node then show the hide or show button if selected_nodes.next().is_some() { - widgets.push(Separator::new(SeparatorType::Unrelated).widget_holder()); - // Check if any of the selected nodes are disabled let is_hidden = document_metadata.selected_nodes().any(|id| network.disabled.contains(id)); @@ -178,13 +184,13 @@ impl NodeGraphMessageHandler { .on_update(move |_| NodeGraphMessage::ToggleSelectedHidden.into()) .widget_holder(); widgets.push(hide_button); + + widgets.push(Separator::new(SeparatorType::Related).widget_holder()); } // If only one node is selected then show the preview or stop previewing button let mut selected_nodes = document_metadata.selected_nodes(); if let (Some(&node_id), None) = (selected_nodes.next(), selected_nodes.next()) { - widgets.push(Separator::new(SeparatorType::Unrelated).widget_holder()); - // Is this node the current output let is_output = network.outputs_contain(node_id); @@ -199,7 +205,7 @@ impl NodeGraphMessageHandler { } } - self.widgets[1] = LayoutGroup::Row { widgets }; + self.widgets[0] = LayoutGroup::Row { widgets }; } self.send_node_bar_layout(responses); } diff --git a/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler/node_properties.rs b/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler/node_properties.rs index ec2b305d..95a0df91 100644 --- a/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler/node_properties.rs +++ b/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler/node_properties.rs @@ -52,22 +52,19 @@ fn expose_widget(node_id: NodeId, index: usize, data_type: FrontendGraphDataType .widget_holder() } +// TODO: Remove this when we have proper entry row formatting that includes room for Assists. fn add_blank_assist(widgets: &mut Vec) { widgets.extend_from_slice(&[ - Separator::new(SeparatorType::Unrelated).widget_holder(), // TODO: These three separators add up to 24px, - Separator::new(SeparatorType::Unrelated).widget_holder(), // TODO: which is the width of the Assist area. - Separator::new(SeparatorType::Unrelated).widget_holder(), // TODO: Remove these when we have proper entry row formatting that includes room for Assists. - Separator::new(SeparatorType::Unrelated).widget_holder(), // TODO: This last one is the separator after the 24px assist. + // Custom CSS specific to the Properties panel converts this Section separator into the width of an assist (24px). + Separator::new(SeparatorType::Section).widget_holder(), + // This last one is the separator after the 24px assist. + Separator::new(SeparatorType::Unrelated).widget_holder(), ]); } fn start_widgets(document_node: &DocumentNode, node_id: NodeId, index: usize, name: &str, data_type: FrontendGraphDataType, blank_assist: bool) -> Vec { let input = document_node.inputs.get(index).expect("A widget failed to be built because its node's input index is invalid."); - let mut widgets = vec![ - expose_widget(node_id, index, data_type, input.is_exposed()), - Separator::new(SeparatorType::Unrelated).widget_holder(), - TextLabel::new(name).widget_holder(), - ]; + let mut widgets = vec![expose_widget(node_id, index, data_type, input.is_exposed()), TextLabel::new(name).widget_holder()]; if blank_assist { add_blank_assist(&mut widgets); } @@ -291,18 +288,17 @@ fn font_inputs(document_node: &DocumentNode, node_id: NodeId, index: usize, name .on_update(update_value(from_font_input, node_id, index)) .widget_holder(), ]); - second_widgets = Some(vec![ - TextLabel::new("").widget_holder(), - Separator::new(SeparatorType::Unrelated).widget_holder(), - Separator::new(SeparatorType::Unrelated).widget_holder(), - Separator::new(SeparatorType::Unrelated).widget_holder(), - Separator::new(SeparatorType::Unrelated).widget_holder(), + + let mut second_row = vec![TextLabel::new("").widget_holder()]; + add_blank_assist(&mut second_row); + second_row.extend_from_slice(&[ Separator::new(SeparatorType::Unrelated).widget_holder(), FontInput::new(font.font_family.clone(), font.font_style.clone()) .is_style_picker(true) .on_update(update_value(from_font_input, node_id, index)) .widget_holder(), ]); + second_widgets = Some(second_row); } (first_widgets, second_widgets) } @@ -1559,16 +1555,10 @@ pub fn imaginate_properties(document_node: &DocumentNode, node_id: NodeId, conte let transform_not_connected = false; let progress = { + let mut widgets = vec![TextLabel::new("Progress").widget_holder(), Separator::new(SeparatorType::Unrelated).widget_holder()]; + add_blank_assist(&mut widgets); let status = imaginate_status.to_text(); - let widgets = vec![ - TextLabel::new("Progress").widget_holder(), - Separator::new(SeparatorType::Unrelated).widget_holder(), - Separator::new(SeparatorType::Unrelated).widget_holder(), // TODO: These three separators add up to 24px, - Separator::new(SeparatorType::Unrelated).widget_holder(), // TODO: which is the width of the Assist area. - Separator::new(SeparatorType::Unrelated).widget_holder(), // TODO: Remove these when we have proper entry row formatting that includes room for Assists. - Separator::new(SeparatorType::Unrelated).widget_holder(), - TextLabel::new(status.as_ref()).bold(true).widget_holder(), - ]; + widgets.push(TextLabel::new(status.as_ref()).bold(true).widget_holder()); LayoutGroup::Row { widgets }.with_tooltip(match imaginate_status { ImaginateStatus::Failed(_) => status.as_ref(), _ => "When generating, the percentage represents how many sampling steps have so far been processed out of the target number", @@ -1577,20 +1567,14 @@ pub fn imaginate_properties(document_node: &DocumentNode, node_id: NodeId, conte let image_controls = { let mut widgets = vec![TextLabel::new("Image").widget_holder(), Separator::new(SeparatorType::Unrelated).widget_holder()]; - let assist_separators = [ - Separator::new(SeparatorType::Unrelated).widget_holder(), // TODO: These three separators add up to 24px, - Separator::new(SeparatorType::Unrelated).widget_holder(), // TODO: which is the width of the Assist area. - Separator::new(SeparatorType::Unrelated).widget_holder(), // TODO: Remove these when we have proper entry row formatting that includes room for Assists. - Separator::new(SeparatorType::Unrelated).widget_holder(), - ]; match &imaginate_status { ImaginateStatus::Beginning | ImaginateStatus::Uploading => { - widgets.extend_from_slice(&assist_separators); + add_blank_assist(&mut widgets); widgets.push(TextButton::new("Beginning...").tooltip("Sending image generation request to the server").disabled(true).widget_holder()); } ImaginateStatus::Generating(_) => { - widgets.extend_from_slice(&assist_separators); + add_blank_assist(&mut widgets); widgets.push( TextButton::new("Terminate") .tooltip("Cancel the in-progress image generation and keep the latest progress") @@ -1605,7 +1589,7 @@ pub fn imaginate_properties(document_node: &DocumentNode, node_id: NodeId, conte ); } ImaginateStatus::Terminating => { - widgets.extend_from_slice(&assist_separators); + add_blank_assist(&mut widgets); widgets.push( TextButton::new("Terminating...") .tooltip("Waiting on the final image generated after termination") @@ -1755,7 +1739,7 @@ pub fn imaginate_properties(document_node: &DocumentNode, node_id: NodeId, conte resolution_index, )) .widget_holder(), - Separator::new(SeparatorType::Unrelated).widget_holder(), + Separator::new(SeparatorType::Related).widget_holder(), NumberInput::new(Some(vec2.x)) .label("W") .min(64.) diff --git a/editor/src/messages/portfolio/document/properties_panel/properties_panel_message_handler.rs b/editor/src/messages/portfolio/document/properties_panel/properties_panel_message_handler.rs index 552c8e4d..3124e504 100644 --- a/editor/src/messages/portfolio/document/properties_panel/properties_panel_message_handler.rs +++ b/editor/src/messages/portfolio/document/properties_panel/properties_panel_message_handler.rs @@ -47,12 +47,10 @@ impl<'a> MessageHandler, is_default: bool, }, - GraphViewOverlay { - open: bool, - }, - GraphViewOverlayToggle, ImaginateCheckServerStatus, ImaginatePollServerStatus, ImaginatePreferences, diff --git a/editor/src/messages/portfolio/portfolio_message_handler.rs b/editor/src/messages/portfolio/portfolio_message_handler.rs index 0b8dc5c2..f39fa2a8 100644 --- a/editor/src/messages/portfolio/portfolio_message_handler.rs +++ b/editor/src/messages/portfolio/portfolio_message_handler.rs @@ -3,7 +3,6 @@ use crate::application::generate_uuid; use crate::consts::{DEFAULT_DOCUMENT_NAME, GRAPHITE_DOCUMENT_VERSION}; use crate::messages::dialog::simple_dialogs; use crate::messages::frontend::utility_types::FrontendDocumentDetails; -use crate::messages::input_mapper::utility_types::macros::action_keys; use crate::messages::layout::utility_types::widget_prelude::*; use crate::messages::portfolio::document::utility_types::clipboards::{Clipboard, CopyBufferEntry, INTERNAL_CLIPBOARD_COUNT}; use crate::messages::portfolio::document::DocumentInputs; @@ -22,7 +21,6 @@ pub struct PortfolioMessageHandler { documents: HashMap, document_ids: Vec, active_document_id: Option, - graph_view_overlay_open: bool, copy_buffer: [Vec; INTERNAL_CLIPBOARD_COUNT as usize], pub persistent_data: PersistentData, pub executor: NodeGraphExecutor, @@ -55,7 +53,6 @@ impl MessageHandler { - self.graph_view_overlay_open = open; - - let layout = WidgetLayout::new(vec![LayoutGroup::Row { - widgets: vec![IconButton::new(if open { "GraphViewOpen" } else { "GraphViewClosed" }, 32) - .tooltip(if open { "Hide Node Graph" } else { "Show Node Graph" }) - .tooltip_shortcut(action_keys!(PortfolioMessageDiscriminant::GraphViewOverlayToggle)) - .on_update(move |_| PortfolioMessage::GraphViewOverlay { open: !open }.into()) - .widget_holder()], - }]); - responses.add(LayoutMessage::SendLayout { - layout: Layout::WidgetLayout(layout), - layout_target: LayoutTarget::GraphViewOverlayButton, - }); - - if open { - responses.add(NodeGraphMessage::SendGraph { should_rerender: false }); - } - responses.add(FrontendMessage::TriggerGraphViewOverlay { open }); - } - PortfolioMessage::GraphViewOverlayToggle => { - responses.add(PortfolioMessage::GraphViewOverlay { open: !self.graph_view_overlay_open }); - } PortfolioMessage::ImaginateCheckServerStatus => { let server_status = self.persistent_data.imaginate.server_status().clone(); self.persistent_data.imaginate.poll_server_check(); @@ -473,9 +446,6 @@ impl MessageHandler { self.active_document_id = Some(document_id); @@ -553,7 +523,6 @@ impl MessageHandler ActionList { let mut common = actions!(PortfolioMessageDiscriminant; - GraphViewOverlayToggle, CloseActiveDocumentWithConfirmation, CloseAllDocuments, CloseAllDocumentsWithConfirmation, @@ -565,11 +534,6 @@ impl MessageHandler = [DrawMode::Draw, DrawMode::Erase, DrawMode::Restore] .into_iter() @@ -149,7 +149,7 @@ impl LayoutHolder for BrushTool { .collect(); widgets.push(RadioInput::new(draw_mode_entries).selected_index(Some(self.options.draw_mode as u32)).widget_holder()); - widgets.push(Separator::new(SeparatorType::Section).widget_holder()); + widgets.push(Separator::new(SeparatorType::Unrelated).widget_holder()); widgets.append(&mut self.options.color.create_widgets( "Color", diff --git a/editor/src/messages/tool/tool_messages/ellipse_tool.rs b/editor/src/messages/tool/tool_messages/ellipse_tool.rs index 62cda619..c9bf609d 100644 --- a/editor/src/messages/tool/tool_messages/ellipse_tool.rs +++ b/editor/src/messages/tool/tool_messages/ellipse_tool.rs @@ -96,7 +96,7 @@ impl LayoutHolder for EllipseTool { |color: &ColorButton| EllipseToolMessage::UpdateOptions(EllipseOptionsUpdate::FillColor(color.value)).into(), ); - widgets.push(Separator::new(SeparatorType::Section).widget_holder()); + widgets.push(Separator::new(SeparatorType::Unrelated).widget_holder()); widgets.append(&mut self.options.stroke.create_widgets( "Stroke", diff --git a/editor/src/messages/tool/tool_messages/freehand_tool.rs b/editor/src/messages/tool/tool_messages/freehand_tool.rs index 366b687f..9d6a4c86 100644 --- a/editor/src/messages/tool/tool_messages/freehand_tool.rs +++ b/editor/src/messages/tool/tool_messages/freehand_tool.rs @@ -103,7 +103,7 @@ impl LayoutHolder for FreehandTool { |color: &ColorButton| FreehandToolMessage::UpdateOptions(FreehandOptionsUpdate::FillColor(color.value)).into(), ); - widgets.push(Separator::new(SeparatorType::Section).widget_holder()); + widgets.push(Separator::new(SeparatorType::Unrelated).widget_holder()); widgets.append(&mut self.options.stroke.create_widgets( "Stroke", diff --git a/editor/src/messages/tool/tool_messages/pen_tool.rs b/editor/src/messages/tool/tool_messages/pen_tool.rs index a385d5a5..420d78bf 100644 --- a/editor/src/messages/tool/tool_messages/pen_tool.rs +++ b/editor/src/messages/tool/tool_messages/pen_tool.rs @@ -118,7 +118,7 @@ impl LayoutHolder for PenTool { |color: &ColorButton| PenToolMessage::UpdateOptions(PenOptionsUpdate::FillColor(color.value)).into(), ); - widgets.push(Separator::new(SeparatorType::Section).widget_holder()); + widgets.push(Separator::new(SeparatorType::Unrelated).widget_holder()); widgets.append(&mut self.options.stroke.create_widgets( "Stroke", diff --git a/editor/src/messages/tool/tool_messages/polygon_tool.rs b/editor/src/messages/tool/tool_messages/polygon_tool.rs index 64010ed1..d9745022 100644 --- a/editor/src/messages/tool/tool_messages/polygon_tool.rs +++ b/editor/src/messages/tool/tool_messages/polygon_tool.rs @@ -125,7 +125,7 @@ impl LayoutHolder for PolygonTool { create_sides_widget(self.options.vertices), ]; - widgets.push(Separator::new(SeparatorType::Section).widget_holder()); + widgets.push(Separator::new(SeparatorType::Unrelated).widget_holder()); widgets.append(&mut self.options.fill.create_widgets( "Fill", @@ -135,7 +135,7 @@ impl LayoutHolder for PolygonTool { |color: &ColorButton| PolygonToolMessage::UpdateOptions(PolygonOptionsUpdate::FillColor(color.value)).into(), )); - widgets.push(Separator::new(SeparatorType::Section).widget_holder()); + widgets.push(Separator::new(SeparatorType::Unrelated).widget_holder()); widgets.append(&mut self.options.stroke.create_widgets( "Stroke", diff --git a/editor/src/messages/tool/tool_messages/rectangle_tool.rs b/editor/src/messages/tool/tool_messages/rectangle_tool.rs index 6bbeca1a..15091294 100644 --- a/editor/src/messages/tool/tool_messages/rectangle_tool.rs +++ b/editor/src/messages/tool/tool_messages/rectangle_tool.rs @@ -84,7 +84,7 @@ impl LayoutHolder for RectangleTool { |color: &ColorButton| RectangleToolMessage::UpdateOptions(RectangleOptionsUpdate::FillColor(color.value)).into(), ); - widgets.push(Separator::new(SeparatorType::Section).widget_holder()); + widgets.push(Separator::new(SeparatorType::Unrelated).widget_holder()); widgets.append(&mut self.options.stroke.create_widgets( "Stroke", diff --git a/editor/src/messages/tool/tool_messages/select_tool.rs b/editor/src/messages/tool/tool_messages/select_tool.rs index 0a2efbbe..cb8f8af9 100644 --- a/editor/src/messages/tool/tool_messages/select_tool.rs +++ b/editor/src/messages/tool/tool_messages/select_tool.rs @@ -175,23 +175,20 @@ impl LayoutHolder for SelectTool { // Align let disabled = self.tool_data.selected_layers_count < 2; - widgets.push(Separator::new(SeparatorType::Section).widget_holder()); + widgets.push(Separator::new(SeparatorType::Unrelated).widget_holder()); widgets.extend(self.alignment_widgets(disabled)); - widgets.push(Separator::new(SeparatorType::Related).widget_holder()); widgets.push(PopoverButton::new("Align", "Coming soon").disabled(disabled).widget_holder()); // Flip let disabled = self.tool_data.selected_layers_count == 0; - widgets.push(Separator::new(SeparatorType::Section).widget_holder()); + widgets.push(Separator::new(SeparatorType::Unrelated).widget_holder()); widgets.extend(self.flip_widgets(disabled)); - widgets.push(Separator::new(SeparatorType::Related).widget_holder()); widgets.push(PopoverButton::new("Flip", "Coming soon").disabled(disabled).widget_holder()); // Boolean if self.tool_data.selected_layers_count >= 2 { - widgets.push(Separator::new(SeparatorType::Section).widget_holder()); + widgets.push(Separator::new(SeparatorType::Unrelated).widget_holder()); widgets.extend(self.boolean_widgets()); - widgets.push(Separator::new(SeparatorType::Related).widget_holder()); widgets.push(PopoverButton::new("Boolean", "Coming soon").widget_holder()); } diff --git a/editor/src/messages/tool/tool_messages/spline_tool.rs b/editor/src/messages/tool/tool_messages/spline_tool.rs index 96cdef47..8c4e9744 100644 --- a/editor/src/messages/tool/tool_messages/spline_tool.rs +++ b/editor/src/messages/tool/tool_messages/spline_tool.rs @@ -105,7 +105,7 @@ impl LayoutHolder for SplineTool { |color: &ColorButton| SplineToolMessage::UpdateOptions(SplineOptionsUpdate::FillColor(color.value)).into(), ); - widgets.push(Separator::new(SeparatorType::Section).widget_holder()); + widgets.push(Separator::new(SeparatorType::Unrelated).widget_holder()); widgets.append(&mut self.options.stroke.create_widgets( "Stroke", diff --git a/editor/src/messages/tool/tool_messages/text_tool.rs b/editor/src/messages/tool/tool_messages/text_tool.rs index 3ac63fb7..64ca4508 100644 --- a/editor/src/messages/tool/tool_messages/text_tool.rs +++ b/editor/src/messages/tool/tool_messages/text_tool.rs @@ -130,7 +130,7 @@ impl LayoutHolder for TextTool { fn layout(&self) -> Layout { let mut widgets = create_text_widgets(self); - widgets.push(Separator::new(SeparatorType::Section).widget_holder()); + widgets.push(Separator::new(SeparatorType::Unrelated).widget_holder()); widgets.append(&mut self.options.fill.create_widgets( "Fill", diff --git a/editor/src/messages/tool/utility_types.rs b/editor/src/messages/tool/utility_types.rs index 9d0e30e6..c03bcf6e 100644 --- a/editor/src/messages/tool/utility_types.rs +++ b/editor/src/messages/tool/utility_types.rs @@ -138,7 +138,7 @@ impl DocumentToolData { pub fn update_working_colors(&self, responses: &mut VecDeque) { let layout = WidgetLayout::new(vec![ LayoutGroup::Row { - widgets: vec![WorkingColorsButton::new(self.primary_color, self.secondary_color).widget_holder()], + widgets: vec![WorkingColorsInput::new(self.primary_color, self.secondary_color).widget_holder()], }, LayoutGroup::Row { widgets: vec![ diff --git a/frontend/src/components/Editor.svelte b/frontend/src/components/Editor.svelte index 895fd99c..f8dbc41b 100644 --- a/frontend/src/components/Editor.svelte +++ b/frontend/src/components/Editor.svelte @@ -189,11 +189,6 @@ display: block; } - .sharp-right-corners.sharp-right-corners.sharp-right-corners.sharp-right-corners { - border-top-right-radius: 0; - border-bottom-right-radius: 0; - } - .layout-row, .layout-col { .scrollable-x, @@ -265,7 +260,7 @@ .popover-button, .color-button > button, .color-picker .preset-color, - .working-colors-button .swatch > button, + .working-colors-input .swatch > button, .radio-input button, .menu-list, .menu-list-button .entry, diff --git a/frontend/src/components/floating-menus/ColorPicker.svelte b/frontend/src/components/floating-menus/ColorPicker.svelte index 1646abb4..b8db15cd 100644 --- a/frontend/src/components/floating-menus/ColorPicker.svelte +++ b/frontend/src/components/floating-menus/ColorPicker.svelte @@ -537,7 +537,7 @@ width: 208px; height: 32px; border-radius: 2px; - border: 1px solid var(--color-0-black); + border: 1px solid var(--color-1-nearblack); box-sizing: border-box; overflow: hidden; diff --git a/frontend/src/components/floating-menus/Dialog.svelte b/frontend/src/components/floating-menus/Dialog.svelte index 4394baa8..1beecbbb 100644 --- a/frontend/src/components/floating-menus/Dialog.svelte +++ b/frontend/src/components/floating-menus/Dialog.svelte @@ -41,13 +41,13 @@
The editor crashed — sorry about that
Please report this by filing an issue on GitHub:
-
window.open(githubUrl($dialog.panicDetails), "_blank")} />
+
window.open(githubUrl($dialog.panicDetails), "_blank")} />
Reload the editor to continue. If this occurs
immediately on repeated reloads, clear storage:
{ await wipeDocuments(); window.location.reload(); diff --git a/frontend/src/components/floating-menus/MenuList.svelte b/frontend/src/components/floating-menus/MenuList.svelte index 4afa22ec..f7cc172f 100644 --- a/frontend/src/components/floating-menus/MenuList.svelte +++ b/frontend/src/components/floating-menus/MenuList.svelte @@ -212,7 +212,7 @@ {/if} {#each entries as section, sectionIndex (sectionIndex)} {#if sectionIndex > 0} - + {/if} {#each virtualScrollingEntryHeight ? section.slice(virtualScrollingStartIndex, virtualScrollingEndIndex) : section as entry, entryIndex (entryIndex + startIndex)} {/if} - - + @@ -519,6 +518,10 @@ .document { height: 100%; + &.document.document { + padding-bottom: 0; + } + .options-bar { height: 32px; flex: 0 0 auto; @@ -537,12 +540,14 @@ // Enables usage of the `100cqh` unit to reference the height of this container element. container-type: size; // Be sure to recalculate this if the items below the tools (working colors and graph overlay buttons) change height in the future. - --height-of-elements-below-tools: 104px; + --height-of-elements-below-tools: 64px; // Target height for the tools within the container above the lower elements. --available-height: calc(100cqh - var(--height-of-elements-below-tools)); + // Be sure to update this if the height changes as set in `Separator.svelte`. + --separator-height: calc(12px + 1px + 12px); // The least height required to fit all the tools in 1 column and 2 columns, which the available space must exceed in order for the fewest number of columns to be used. - --1-col-required-height: calc(var(--total-tool-rows-for-1-columns) * 32px + var(--total-separators) * (1px + 8px * 2)); - --2-col-required-height: calc(var(--total-tool-rows-for-2-columns) * 32px + var(--total-separators) * (1px + 8px * 2)); + --1-col-required-height: calc(var(--total-tool-rows-for-1-columns) * 32px + var(--total-separators) * var(--separator-height)); + --2-col-required-height: calc(var(--total-tool-rows-for-2-columns) * 32px + var(--total-separators) * var(--separator-height)); // Evaluates to 0px (if false) or 1px (if true). We multiply by 1000000 to force the result to be an integer 0 or 1 and not interpolate values in-between. --needs-at-least-2-columns: calc(1px - clamp(0px, calc((var(--available-height) - Min(var(--available-height), var(--1-col-required-height))) * 1000000), 1px)); --needs-at-least-3-columns: calc(1px - clamp(0px, calc((var(--available-height) - Min(var(--available-height), var(--2-col-required-height))) * 1000000), 1px)); @@ -563,7 +568,7 @@ // Remove this when the Firefox bug is fixed. @-moz-document url-prefix() { --available-height-plus-1: calc(var(--available-height) + 1px); - --3-col-required-height: calc(var(--total-tool-rows-for-3-columns) * 32px + var(--total-separators) * (1px + 8px * 2)); + --3-col-required-height: calc(var(--total-tool-rows-for-3-columns) * 32px + var(--total-separators) * var(--separator-height)); --overflows-with-3-columns: calc(1px - clamp(0px, calc((var(--available-height-plus-1) - Min(var(--available-height-plus-1), var(--3-col-required-height))) * 1000000), 1px)); --firefox-scrollbar-width-space-occupied: 8; // Might change someday, or on different platforms, but this is the value in FF 120 on Windows padding-right: calc(var(--firefox-scrollbar-width-space-occupied) * var(--overflows-with-3-columns)); @@ -610,17 +615,12 @@ flex: 0 0 auto; align-items: center; - .graph-overlay-button-area { - height: auto; - align-items: center; - } - - .working-colors-button-area { + .working-colors-input-area { height: auto; margin: 0; min-height: 0; - .working-colors-button { + .working-colors-input { margin: 0; } diff --git a/frontend/src/components/panels/Layers.svelte b/frontend/src/components/panels/Layers.svelte index e175aa4f..c0f88b4e 100644 --- a/frontend/src/components/panels/Layers.svelte +++ b/frontend/src/components/panels/Layers.svelte @@ -505,7 +505,6 @@ &::placeholder { opacity: 1; color: inherit; - font-style: italic; } } } diff --git a/frontend/src/components/panels/Properties.svelte b/frontend/src/components/panels/Properties.svelte index 85a1b4d4..70baaa28 100644 --- a/frontend/src/components/panels/Properties.svelte +++ b/frontend/src/components/panels/Properties.svelte @@ -51,6 +51,16 @@ .sections { flex: 1 1 100%; + + // Used as a placeholder for empty assist widgets + .separator.section.horizontal { + margin: 0; + margin-left: 24px; + + div { + width: 0; + } + } } .text-button { diff --git a/frontend/src/components/views/Graph.svelte b/frontend/src/components/views/Graph.svelte index bbd99a1c..05b197bc 100644 --- a/frontend/src/components/views/Graph.svelte +++ b/frontend/src/components/views/Graph.svelte @@ -741,7 +741,7 @@
- {node.alias || "Layer"} + {node.alias || "Layer"}
@@ -773,14 +773,13 @@
- {node.alias || node.name} + {node.alias || node.name}
{#if exposedInputsOutputs.length > 0}
{#each exposedInputsOutputs as parameter, index}
-
{parameter.name}
{/each} @@ -1005,10 +1004,6 @@ .icon-label { fill: var(--color-a-softgray); } - - .expand-arrow::after { - background: var(--icon-expand-collapse-arrow-disabled); - } } &.previewed::after { @@ -1035,34 +1030,6 @@ height: 8px; } - .expand-arrow { - width: 16px; - height: 16px; - margin: 0; - padding: 0; - position: relative; - flex: 0 0 auto; - display: flex; - align-items: center; - justify-content: center; - - &::after { - content: ""; - position: absolute; - width: 8px; - height: 8px; - background: var(--icon-expand-collapse-arrow); - } - - &:hover::after { - background: var(--icon-expand-collapse-arrow-hover); - } - } - - .expanded .expand-arrow::after { - transform: rotate(90deg); - } - .text-label { overflow: hidden; text-overflow: ellipsis; @@ -1201,8 +1168,8 @@ } .text-label { - margin-left: 8px; // Remove after reenabling icon-label - margin-right: 4px; + // margin-right: 4px; // Restore after reenabling icon-label + margin: 0 8px; } } @@ -1216,7 +1183,8 @@ position: relative; display: flex; align-items: center; - width: 100%; + margin: 0 8px; + width: calc(100% - 8px - 8px); height: 24px; &:last-of-type { @@ -1227,19 +1195,10 @@ width: 100%; } - &.input { - .expand-arrow { - margin-left: 4px; - } - } - &.output { flex-direction: row-reverse; text-align: right; - .expand-arrow { - margin-right: 4px; - } svg { width: 30px; height: 20px; diff --git a/frontend/src/components/widgets/WidgetSection.svelte b/frontend/src/components/widgets/WidgetSection.svelte index 92df997c..00e8621d 100644 --- a/frontend/src/components/widgets/WidgetSection.svelte +++ b/frontend/src/components/widgets/WidgetSection.svelte @@ -44,6 +44,10 @@ flex: 0 0 auto; margin: 0 4px; + + .widget-section { + margin-top: 4px; + } + .header { text-align: left; align-items: center; @@ -107,7 +111,6 @@ padding: 0 7px; padding-top: 1px; margin-top: -1px; - margin-bottom: 4px; border: 1px solid var(--color-2-mildblack); border-radius: 0 0 4px 4px; overflow: hidden; @@ -130,8 +133,8 @@ margin-left: 16px; } - > .parameter-expose-button ~ .text-label:first-of-type { - margin-left: 0; + > .parameter-expose-button + .text-label:first-of-type { + margin-left: 8px; } > .text-button { diff --git a/frontend/src/components/widgets/WidgetSpan.svelte b/frontend/src/components/widgets/WidgetSpan.svelte index 937a7cd6..c0b20877 100644 --- a/frontend/src/components/widgets/WidgetSpan.svelte +++ b/frontend/src/components/widgets/WidgetSpan.svelte @@ -12,25 +12,22 @@ import ParameterExposeButton from "@graphite/components/widgets/buttons/ParameterExposeButton.svelte"; import PopoverButton from "@graphite/components/widgets/buttons/PopoverButton.svelte"; import TextButton from "@graphite/components/widgets/buttons/TextButton.svelte"; - import WorkingColorsButton from "@graphite/components/widgets/buttons/WorkingColorsButton.svelte"; import CheckboxInput from "@graphite/components/widgets/inputs/CheckboxInput.svelte"; import CurveInput from "@graphite/components/widgets/inputs/CurveInput.svelte"; import DropdownInput from "@graphite/components/widgets/inputs/DropdownInput.svelte"; import FontInput from "@graphite/components/widgets/inputs/FontInput.svelte"; import NumberInput from "@graphite/components/widgets/inputs/NumberInput.svelte"; - import OptionalInput from "@graphite/components/widgets/inputs/OptionalInput.svelte"; import PivotInput from "@graphite/components/widgets/inputs/PivotInput.svelte"; import RadioInput from "@graphite/components/widgets/inputs/RadioInput.svelte"; import TextAreaInput from "@graphite/components/widgets/inputs/TextAreaInput.svelte"; import TextInput from "@graphite/components/widgets/inputs/TextInput.svelte"; + import WorkingColorsInput from "@graphite/components/widgets/inputs/WorkingColorsInput.svelte"; import IconLabel from "@graphite/components/widgets/labels/IconLabel.svelte"; import ImageLabel from "@graphite/components/widgets/labels/ImageLabel.svelte"; import Separator from "@graphite/components/widgets/labels/Separator.svelte"; import TextLabel from "@graphite/components/widgets/labels/TextLabel.svelte"; import WidgetLayout from "@graphite/components/widgets/WidgetLayout.svelte"; - const SUFFIX_WIDGETS = ["PopoverButton"]; - const editor = getContext("editor"); export let widgetData: WidgetSpanRow | WidgetSpanColumn; @@ -47,7 +44,6 @@ $: direction = watchDirection(widgetData); $: widgets = watchWidgets(widgetData); - $: widgetsAndNextSiblingIsSuffix = watchWidgetsAndNextSiblingIsSuffix(widgets); function watchDirection(widgetData: WidgetSpanRow | WidgetSpanColumn): "row" | "column" | undefined { if (isWidgetSpanRow(widgetData)) return "row"; @@ -61,17 +57,6 @@ return widgets; } - function watchWidgetsAndNextSiblingIsSuffix(widgets: Widget[]): [Widget, boolean][] { - return widgets.map((widget, index): [Widget, boolean] => { - // A suffix widget is one that joins up with this widget at the end with only a 1px gap. - // It uses the CSS sibling selector to give its own left edge corners zero radius. - // But this JS is needed to set its preceding sibling widget's right edge corners to zero radius. - const nextSiblingIsSuffix = SUFFIX_WIDGETS.includes(widgets[index + 1]?.props.kind); - - return [widget, nextSiblingIsSuffix]; - }); - } - function updateLayout(index: number, value: unknown) { editor.instance.updateLayout(layoutTarget, widgets[index].widgetId, value); } @@ -88,14 +73,14 @@
- {#each widgetsAndNextSiblingIsSuffix as [component, nextIsSuffix], index} + {#each widgets as component, index} {@const checkboxInput = narrowWidgetProps(component.props, "CheckboxInput")} {#if checkboxInput} updateLayout(index, detail)} /> {/if} {@const colorInput = narrowWidgetProps(component.props, "ColorButton")} {#if colorInput} - updateLayout(index, detail)} sharpRightCorners={nextIsSuffix} /> + updateLayout(index, detail)} /> {/if} {@const curvesInput = narrowWidgetProps(component.props, "CurveInput")} {#if curvesInput} @@ -103,11 +88,11 @@ {/if} {@const dropdownInput = narrowWidgetProps(component.props, "DropdownInput")} {#if dropdownInput} - updateLayout(index, detail)} sharpRightCorners={nextIsSuffix} /> + updateLayout(index, detail)} /> {/if} {@const fontInput = narrowWidgetProps(component.props, "FontInput")} {#if fontInput} - updateLayout(index, detail)} sharpRightCorners={nextIsSuffix} /> + updateLayout(index, detail)} /> {/if} {@const parameterExposeButton = narrowWidgetProps(component.props, "ParameterExposeButton")} {#if parameterExposeButton} @@ -115,7 +100,7 @@ {/if} {@const iconButton = narrowWidgetProps(component.props, "IconButton")} {#if iconButton} - updateLayout(index, undefined)} sharpRightCorners={nextIsSuffix} /> + updateLayout(index, undefined)} /> {/if} {@const iconLabel = narrowWidgetProps(component.props, "IconLabel")} {#if iconLabel} @@ -132,13 +117,8 @@ on:value={({ detail }) => debouncer((value) => updateLayout(index, value)).debounceUpdateValue(detail)} incrementCallbackIncrease={() => updateLayout(index, "Increment")} incrementCallbackDecrease={() => updateLayout(index, "Decrement")} - sharpRightCorners={nextIsSuffix} /> {/if} - {@const optionalInput = narrowWidgetProps(component.props, "OptionalInput")} - {#if optionalInput} - updateLayout(index, detail)} /> - {/if} {@const pivotInput = narrowWidgetProps(component.props, "PivotInput")} {#if pivotInput} updateLayout(index, detail)} /> @@ -156,15 +136,15 @@ {/if} {@const radioInput = narrowWidgetProps(component.props, "RadioInput")} {#if radioInput} - updateLayout(index, detail)} sharpRightCorners={nextIsSuffix} /> + updateLayout(index, detail)} /> {/if} {@const separator = narrowWidgetProps(component.props, "Separator")} {#if separator} {/if} - {@const workingColorsButton = narrowWidgetProps(component.props, "WorkingColorsButton")} - {#if workingColorsButton} - + {@const workingColorsInput = narrowWidgetProps(component.props, "WorkingColorsInput")} + {#if workingColorsInput} + {/if} {@const textAreaInput = narrowWidgetProps(component.props, "TextAreaInput")} {#if textAreaInput} @@ -172,7 +152,7 @@ {/if} {@const textButton = narrowWidgetProps(component.props, "TextButton")} {#if textButton} - updateLayout(index, undefined)} sharpRightCorners={nextIsSuffix} /> + updateLayout(index, undefined)} /> {/if} {@const breadcrumbTrailButtons = narrowWidgetProps(component.props, "BreadcrumbTrailButtons")} {#if breadcrumbTrailButtons} @@ -180,7 +160,7 @@ {/if} {@const textInput = narrowWidgetProps(component.props, "TextInput")} {#if textInput} - updateLayout(index, detail)} sharpRightCorners={nextIsSuffix} /> + updateLayout(index, detail)} /> {/if} {@const textLabel = narrowWidgetProps(component.props, "TextLabel")} {#if textLabel} @@ -218,31 +198,6 @@ --widget-height: 16px; } } - - // TODO: Target this in a better way than using the tooltip, which will break if changed, or when localized/translated - .checkbox-input [title="Preserve Aspect Ratio"] { - margin-bottom: -32px; - position: relative; - - &::before, - &::after { - content: ""; - pointer-events: none; - position: absolute; - left: 8px; - width: 1px; - height: 16px; - background: var(--color-7-middlegray); - } - - &::before { - top: calc(-4px - 16px); - } - - &::after { - bottom: calc(-4px - 16px); - } - } } // paddingpaddingpaddingpaddingpaddingpaddingpaddingpaddingpaddingpaddingpaddingpaddingpaddingpaddingpaddingpaddingpaddingpaddingpaddingpadding diff --git a/frontend/src/components/widgets/buttons/ColorButton.svelte b/frontend/src/components/widgets/buttons/ColorButton.svelte index f95cc875..a7184374 100644 --- a/frontend/src/components/widgets/buttons/ColorButton.svelte +++ b/frontend/src/components/widgets/buttons/ColorButton.svelte @@ -16,10 +16,9 @@ export let allowNone = false; // export let allowTransparency = false; // TODO: Implement export let tooltip: string | undefined = undefined; - export let sharpRightCorners = false; - + {#if disabled && !value.none} sRGB @@ -59,11 +58,6 @@ } } - &.sharp-right-corners { - border-top-right-radius: 0; - border-bottom-right-radius: 0; - } - > button { border: none; padding: 0; diff --git a/frontend/src/components/widgets/buttons/IconButton.svelte b/frontend/src/components/widgets/buttons/IconButton.svelte index 903e9939..b95714bf 100644 --- a/frontend/src/components/widgets/buttons/IconButton.svelte +++ b/frontend/src/components/widgets/buttons/IconButton.svelte @@ -8,7 +8,6 @@ export let disabled = false; export let active = false; export let tooltip: string | undefined = undefined; - export let sharpRightCorners = false; // Callbacks export let action: (e?: MouseEvent) => void; @@ -21,17 +20,7 @@ .join(" "); - diff --git a/frontend/src/components/widgets/buttons/ParameterExposeButton.svelte b/frontend/src/components/widgets/buttons/ParameterExposeButton.svelte index 68a54988..1a4a625f 100644 --- a/frontend/src/components/widgets/buttons/ParameterExposeButton.svelte +++ b/frontend/src/components/widgets/buttons/ParameterExposeButton.svelte @@ -9,7 +9,22 @@ - diff --git a/frontend/src/components/widgets/buttons/TextButton.svelte b/frontend/src/components/widgets/buttons/TextButton.svelte index 0d1df71b..3ef6888b 100644 --- a/frontend/src/components/widgets/buttons/TextButton.svelte +++ b/frontend/src/components/widgets/buttons/TextButton.svelte @@ -15,11 +15,10 @@ export let label: string; export let icon: IconName | undefined = undefined; export let emphasized = false; - export let noBackground = false; + export let flush = false; export let minWidth = 0; export let disabled = false; export let tooltip: string | undefined = undefined; - export let sharpRightCorners = false; export let menuListChildren: MenuListEntry[][] | undefined = undefined; // Callbacks @@ -57,8 +56,7 @@ class:open={self?.open} class:emphasized class:disabled - class:no-background={noBackground} - class:sharp-right-corners={sharpRightCorners} + class:flush style:min-width={minWidth > 0 ? `${minWidth}px` : ""} title={tooltip} data-emphasized={emphasized || undefined} @@ -73,7 +71,7 @@ {/if} {#if icon && label} - + {/if} {#if label} {label} @@ -140,7 +138,7 @@ } } - &.no-background { + &.flush { background: none; &:hover, diff --git a/frontend/src/components/widgets/inputs/CurveInput.svelte b/frontend/src/components/widgets/inputs/CurveInput.svelte index 8833843f..a7a60ce1 100644 --- a/frontend/src/components/widgets/inputs/CurveInput.svelte +++ b/frontend/src/components/widgets/inputs/CurveInput.svelte @@ -218,7 +218,7 @@ max-width: calc(8 * var(--widget-height)); .grid { - stroke: var(--color-7-middlegray); + stroke: var(--color-5-dullgray); stroke-width: 0.005; pointer-events: none; } @@ -251,7 +251,7 @@ } .handle-line { - stroke: var(--color-7-middlegray); + stroke: var(--color-5-dullgray); stroke-width: 0.005; pointer-events: none; } diff --git a/frontend/src/components/widgets/inputs/DropdownInput.svelte b/frontend/src/components/widgets/inputs/DropdownInput.svelte index 18c1b974..338da687 100644 --- a/frontend/src/components/widgets/inputs/DropdownInput.svelte +++ b/frontend/src/components/widgets/inputs/DropdownInput.svelte @@ -21,7 +21,6 @@ export let interactive = true; export let disabled = false; export let tooltip: string | undefined = undefined; - export let sharpRightCorners = false; let activeEntry = makeActiveEntry(); let activeEntrySkipWatcher = false; @@ -64,7 +63,7 @@ !disabled && (open = true)} @@ -128,7 +127,7 @@ &:hover, &.open { - background: var(--color-5-dullgray); + background: var(--color-4-dimgray); } &.disabled { diff --git a/frontend/src/components/widgets/inputs/FieldInput.svelte b/frontend/src/components/widgets/inputs/FieldInput.svelte index 0d820b09..4a92fc71 100644 --- a/frontend/src/components/widgets/inputs/FieldInput.svelte +++ b/frontend/src/components/widgets/inputs/FieldInput.svelte @@ -24,7 +24,6 @@ export let disabled = false; export let textarea = false; export let tooltip: string | undefined = undefined; - export let sharpRightCorners = false; export let placeholder: string | undefined = undefined; export let hideContextMenu = false; @@ -69,7 +68,7 @@ - + {#if !textarea} void) | undefined = undefined; @@ -581,7 +580,6 @@ {label} {disabled} {tooltip} - {sharpRightCorners} {styles} hideContextMenu={true} spellcheck={false} @@ -658,7 +656,7 @@ background: none; &:hover { - background: var(--color-5-dullgray); + background: var(--color-4-dimgray); } &.right { diff --git a/frontend/src/components/widgets/inputs/OptionalInput.svelte b/frontend/src/components/widgets/inputs/OptionalInput.svelte deleted file mode 100644 index 0c3e4622..00000000 --- a/frontend/src/components/widgets/inputs/OptionalInput.svelte +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - diff --git a/frontend/src/components/widgets/inputs/RadioInput.svelte b/frontend/src/components/widgets/inputs/RadioInput.svelte index 6ca26e49..c080512d 100644 --- a/frontend/src/components/widgets/inputs/RadioInput.svelte +++ b/frontend/src/components/widgets/inputs/RadioInput.svelte @@ -12,7 +12,6 @@ export let entries: RadioEntries; export let selectedIndex: number | undefined = undefined; export let disabled = false; - export let sharpRightCorners = false; function handleEntryClick(radioEntryData: RadioEntryData) { const index = entries.indexOf(radioEntryData); @@ -28,7 +27,6 @@ class:active={index === selectedIndex} class:mixed={selectedIndex === undefined} class:disabled - class:sharp-right-corners={index === entries.length - 1 && sharpRightCorners} on:click={() => handleEntryClick(entry)} title={entry.tooltip} tabindex={index === selectedIndex ? -1 : 0} @@ -38,7 +36,7 @@ {/if} {#if entry.label} - {entry.label} + {entry.label} {/if} {/each} diff --git a/frontend/src/components/widgets/inputs/RulerInput.svelte b/frontend/src/components/widgets/inputs/RulerInput.svelte index 7f505a4b..70a97543 100644 --- a/frontend/src/components/widgets/inputs/RulerInput.svelte +++ b/frontend/src/components/widgets/inputs/RulerInput.svelte @@ -135,7 +135,7 @@ path { stroke-width: 1px; - stroke: var(--color-7-middlegray); + stroke: var(--color-6-lowergray); } text { diff --git a/frontend/src/components/widgets/inputs/TextInput.svelte b/frontend/src/components/widgets/inputs/TextInput.svelte index 9a13d96b..2c9b0d1b 100644 --- a/frontend/src/components/widgets/inputs/TextInput.svelte +++ b/frontend/src/components/widgets/inputs/TextInput.svelte @@ -16,7 +16,6 @@ // Styling export let centered = false; export let minWidth = 0; - export let sharpRightCorners = false; let self: FieldInput | undefined; let editing = false; @@ -67,7 +66,6 @@ {disabled} {tooltip} {placeholder} - {sharpRightCorners} bind:this={self} /> diff --git a/frontend/src/components/widgets/buttons/WorkingColorsButton.svelte b/frontend/src/components/widgets/inputs/WorkingColorsInput.svelte similarity index 100% rename from frontend/src/components/widgets/buttons/WorkingColorsButton.svelte rename to frontend/src/components/widgets/inputs/WorkingColorsInput.svelte diff --git a/frontend/src/components/widgets/labels/Separator.svelte b/frontend/src/components/widgets/labels/Separator.svelte index 29392e13..64269fd3 100644 --- a/frontend/src/components/widgets/labels/Separator.svelte +++ b/frontend/src/components/widgets/labels/Separator.svelte @@ -6,7 +6,7 @@
- {#if ["Section", "List"].includes(type)} + {#if type === "Section"}
{/if}
@@ -21,27 +21,20 @@ } &.unrelated { - height: 8px; - } - - &.section, - &.list { - width: 100%; - - div { - height: 1px; - width: calc(100% - 8px); - margin: 0 4px; - background: var(--color-7-middlegray); - } + height: 16px; } &.section { - margin: 8px 0; - } + // If changing this, update `--separator-height` in `Document.svelte` + margin: 12px 0; + width: 100%; - &.list { - margin: 4px 0; + div { + margin: 0 4px; + height: 1px; + width: calc(100% - 8px); + background: var(--color-5-dullgray); + } } } @@ -53,27 +46,19 @@ } &.unrelated { - width: 8px; - } - - &.section, - &.list { - height: 100%; - - div { - height: calc(100% - 8px); - width: 1px; - margin: 4px 0; - background: var(--color-7-middlegray); - } + width: 16px; } &.section { - margin: 0 8px; - } + margin: 0 12px; + height: 100%; - &.list { - margin: 0 4px; + div { + margin: 4px 0; + height: calc(100% - 8px); + width: 1px; + background: var(--color-5-dullgray); + } } } } diff --git a/frontend/src/components/widgets/labels/UserInputLabel.svelte b/frontend/src/components/widgets/labels/UserInputLabel.svelte index e7261983..6af7a8e4 100644 --- a/frontend/src/components/widgets/labels/UserInputLabel.svelte +++ b/frontend/src/components/widgets/labels/UserInputLabel.svelte @@ -248,11 +248,11 @@ .floating-menu-content .row:hover > & { .input-key { - border-color: var(--color-7-middlegray); + border-color: var(--color-8-uppergray); } .input-mouse .dim { - fill: var(--color-7-middlegray); + fill: var(--color-8-uppergray); } } } diff --git a/frontend/src/components/window/status-bar/StatusBar.svelte b/frontend/src/components/window/status-bar/StatusBar.svelte index ca1b6f90..285fe4cb 100644 --- a/frontend/src/components/window/status-bar/StatusBar.svelte +++ b/frontend/src/components/window/status-bar/StatusBar.svelte @@ -57,7 +57,8 @@ overflow: hidden; .separator.section { - margin: 0; + // Width of section separator (12px) minus the margin of the surrounding user input labels (8px) + margin: 0 calc(12px - 8px); } .plus, diff --git a/frontend/src/components/window/title-bar/TitleBar.svelte b/frontend/src/components/window/title-bar/TitleBar.svelte index ab7a4736..c4ec0c00 100644 --- a/frontend/src/components/window/title-bar/TitleBar.svelte +++ b/frontend/src/components/window/title-bar/TitleBar.svelte @@ -77,7 +77,7 @@ {:else} {#each entries as entry} - + {/each} {/if} diff --git a/frontend/src/components/window/workspace/Panel.svelte b/frontend/src/components/window/workspace/Panel.svelte index 1a725dd2..cf941ee7 100644 --- a/frontend/src/components/window/workspace/Panel.svelte +++ b/frontend/src/components/window/workspace/Panel.svelte @@ -3,7 +3,6 @@ import Layers from "@graphite/components/panels/Layers.svelte"; import Properties from "@graphite/components/panels/Properties.svelte"; import IconButton from "@graphite/components/widgets/buttons/IconButton.svelte"; - import PopoverButton from "@graphite/components/widgets/buttons/PopoverButton.svelte"; import TextButton from "@graphite/components/widgets/buttons/TextButton.svelte"; const PANEL_COMPONENTS = { @@ -102,10 +101,10 @@ {/each} - + {#if panelType} @@ -120,7 +119,7 @@
- editor.instance.newDocumentDialog()} /> + editor.instance.newDocumentDialog()} /> @@ -128,7 +127,7 @@
- editor.instance.openDocument()} /> + editor.instance.openDocument()} /> @@ -136,7 +135,7 @@
- editor.instance.demoArtworkDialog()} /> + editor.instance.demoArtworkDialog()} />
@@ -252,9 +251,9 @@ } } - .popover-button { - margin: 2px 4px; - } + // .popover-button { + // margin: 2px 4px; + // } } .panel-body { @@ -262,6 +261,10 @@ flex: 1 1 100%; flex-direction: column; + > div { + padding-bottom: 4px; + } + .empty-panel { background: var(--color-2-mildblack); margin: 4px; diff --git a/frontend/src/state-providers/document.ts b/frontend/src/state-providers/document.ts index ebe38b75..2bdfd898 100644 --- a/frontend/src/state-providers/document.ts +++ b/frontend/src/state-providers/document.ts @@ -11,7 +11,6 @@ import { UpdateToolOptionsLayout, UpdateToolShelfLayout, UpdateWorkingColorsLayout, - UpdateGraphViewOverlayButtonLayout, UpdateNodeGraphBarLayout, TriggerGraphViewOverlay, } from "@graphite/wasm-communication/messages"; @@ -24,7 +23,6 @@ export function createDocumentState(editor: Editor) { toolOptionsLayout: defaultWidgetLayout(), documentBarLayout: defaultWidgetLayout(), toolShelfLayout: defaultWidgetLayout(), - graphViewOverlayButtonLayout: defaultWidgetLayout(), workingColorsLayout: defaultWidgetLayout(), nodeGraphBarLayout: defaultWidgetLayout(), // Graph view overlay @@ -69,14 +67,6 @@ export function createDocumentState(editor: Editor) { return state; }); }); - editor.subscriptions.subscribeJsMessage(UpdateGraphViewOverlayButtonLayout, async (updateGraphViewOverlayButtonLayout) => { - await tick(); - - update((state) => { - patchWidgetLayout(state.graphViewOverlayButtonLayout, updateGraphViewOverlayButtonLayout); - return state; - }); - }); editor.subscriptions.subscribeJsMessage(UpdateWorkingColorsLayout, async (updateWorkingColorsLayout) => { await tick(); diff --git a/frontend/src/utility-functions/icons.ts b/frontend/src/utility-functions/icons.ts index e4df81eb..9c9e9bf8 100644 --- a/frontend/src/utility-functions/icons.ts +++ b/frontend/src/utility-functions/icons.ts @@ -314,6 +314,7 @@ export const ICON_SVG_STRINGS = Object.fromEntries(Object.entries(ICONS).map(([n export type IconName = keyof typeof ICONS; export type IconSize = undefined | 12 | 16 | 24 | 32; +export type PopoverButtonStyle = "DropdownArrow" | "VerticalEllipsis"; // The following helper type declarations allow us to avoid manually maintaining the `IconName` type declaration as a string union paralleling the keys of the // icon definitions. It lets TypeScript do that for us. Our goal is to define the big key-value pair of icons by constraining its values, but inferring its keys. diff --git a/frontend/src/wasm-communication/messages.ts b/frontend/src/wasm-communication/messages.ts index ef9a0e8a..e0184ae8 100644 --- a/frontend/src/wasm-communication/messages.ts +++ b/frontend/src/wasm-communication/messages.ts @@ -3,7 +3,7 @@ import { Transform, Type, plainToClass } from "class-transformer"; -import { type IconName, type IconSize } from "@graphite/utility-functions/icons"; +import { type PopoverButtonStyle, type IconName, type IconSize } from "@graphite/utility-functions/icons"; import { type WasmEditorInstance, type WasmRawInstance } from "@graphite/wasm-communication/editor"; import type MenuList from "@graphite/components/floating-menus/MenuList.svelte"; @@ -918,18 +918,9 @@ export class NumberInput extends WidgetProps { minWidth!: number; } -export class OptionalInput extends WidgetProps { - checked!: boolean; - - disabled!: boolean; - - icon!: IconName; - - @Transform(({ value }: { value: string }) => value || undefined) - tooltip!: string | undefined; -} - export class PopoverButton extends WidgetProps { + style!: PopoverButtonStyle | undefined; + icon!: IconName | undefined; disabled!: boolean; @@ -965,7 +956,7 @@ export class RadioInput extends WidgetProps { } export type SeparatorDirection = "Horizontal" | "Vertical"; -export type SeparatorType = "Related" | "Unrelated" | "Section" | "List"; +export type SeparatorType = "Related" | "Unrelated" | "Section"; export class Separator extends WidgetProps { direction!: SeparatorDirection; @@ -973,7 +964,7 @@ export class Separator extends WidgetProps { type!: SeparatorType; } -export class WorkingColorsButton extends WidgetProps { +export class WorkingColorsInput extends WidgetProps { @Type(() => Color) primary!: Color; @@ -1008,7 +999,7 @@ export class TextButton extends WidgetProps { emphasized!: boolean; - noBackground!: boolean; + flush!: boolean; minWidth!: number; @@ -1029,7 +1020,7 @@ export type TextButtonWidget = { label: string; icon?: IconName; emphasized?: boolean; - noBackground?: boolean; + flush?: boolean; minWidth?: number; disabled?: boolean; tooltip?: string; @@ -1103,13 +1094,12 @@ const widgetSubTypes = [ { value: IconLabel, name: "IconLabel" }, { value: ImageLabel, name: "ImageLabel" }, { value: NumberInput, name: "NumberInput" }, - { value: OptionalInput, name: "OptionalInput" }, { value: ParameterExposeButton, name: "ParameterExposeButton" }, { value: PivotInput, name: "PivotInput" }, { value: PopoverButton, name: "PopoverButton" }, { value: RadioInput, name: "RadioInput" }, { value: Separator, name: "Separator" }, - { value: WorkingColorsButton, name: "WorkingColorsButton" }, + { value: WorkingColorsInput, name: "WorkingColorsInput" }, { value: TextAreaInput, name: "TextAreaInput" }, { value: TextButton, name: "TextButton" }, { value: TextInput, name: "TextInput" }, @@ -1293,8 +1283,6 @@ export class UpdateDocumentBarLayout extends WidgetDiffUpdate {} export class UpdateDocumentModeLayout extends WidgetDiffUpdate {} -export class UpdateGraphViewOverlayButtonLayout extends WidgetDiffUpdate {} - export class UpdateLayersPanelOptionsLayout extends WidgetDiffUpdate {} // Extends JsMessage instead of WidgetDiffUpdate because the menu bar isn't diffed @@ -1384,7 +1372,6 @@ export const messageMakers: Record = { UpdateDocumentRulers, UpdateDocumentScrollbars, UpdateEyedropperSamplingState, - UpdateGraphViewOverlayButtonLayout, UpdateImageData, UpdateInputHints, UpdateLayersPanelOptionsLayout, diff --git a/website/content/learn/introduction/_index.md b/website/content/learn/introduction/_index.md index 627ddcaa..16029f30 100644 --- a/website/content/learn/introduction/_index.md +++ b/website/content/learn/introduction/_index.md @@ -13,7 +13,7 @@ Before taking the time to read the coming chapters, let's build some context by You can follow along with this starter project either by watching the tutorial video or referencing the step-by-step breakdown. -***The tutorial isn't ready quite yet, sorry! Please check back very soon. It should be posted by mid-December.*** +***The tutorial isn't ready quite yet, sorry! Please check back very soon. It should be posted by late December.*** diff --git a/website/content/learn/introduction/features-and-limitations.md b/website/content/learn/introduction/features-and-limitations.md index 54dbdbff..5fadb4b2 100644 --- a/website/content/learn/introduction/features-and-limitations.md +++ b/website/content/learn/introduction/features-and-limitations.md @@ -5,7 +5,7 @@ title = "Features and limitations" order = 1 +++ -Please keep in mind that Graphite is alpha software, meaning it is actively changing and improving. Remember to save you work frequently because crashes are not unheard of. +Please keep in mind that Graphite is alpha software, meaning it is actively changing and improving. Remember to save your work frequently because crashes are not unheard of. ## Current capabilities