From ab3410cffe81451af3aac811a270abd665a65017 Mon Sep 17 00:00:00 2001 From: Keavon Chambers Date: Sat, 25 Nov 2023 01:56:05 -0800 Subject: [PATCH] Consolidate MenuListButton into TextButton (#1470) --- .../export_dialog_message_handler.rs | 2 +- .../utility_types/widgets/button_widgets.rs | 3 + .../utility_types/widgets/input_widgets.rs | 10 +- .../document/document_message_handler.rs | 8 +- .../node_properties.rs | 14 +-- .../messages/tool/tool_messages/brush_tool.rs | 2 +- .../tool/tool_messages/select_tool.rs | 2 +- .../layout/ConditionalWrapper.svelte | 14 +++ .../widgets/buttons/MenuListButton.svelte | 83 ------------- .../widgets/buttons/TextButton.svelte | 116 +++++++++++++----- .../widgets/inputs/FieldInput.svelte | 7 +- .../widgets/inputs/NumberInput.svelte | 6 +- .../window/title-bar/TitleBar.svelte | 8 +- frontend/src/wasm-communication/messages.ts | 4 +- 14 files changed, 141 insertions(+), 138 deletions(-) create mode 100644 frontend/src/components/layout/ConditionalWrapper.svelte delete mode 100644 frontend/src/components/widgets/buttons/MenuListButton.svelte diff --git a/editor/src/messages/dialog/export_dialog/export_dialog_message_handler.rs b/editor/src/messages/dialog/export_dialog/export_dialog_message_handler.rs index cd883922d6..480936596e 100644 --- a/editor/src/messages/dialog/export_dialog/export_dialog_message_handler.rs +++ b/editor/src/messages/dialog/export_dialog/export_dialog_message_handler.rs @@ -95,7 +95,7 @@ impl LayoutHolder for ExportDialogMessageHandler { let index = export_area_options.iter().position(|(val, _, _)| val == &self.bounds).unwrap(); let entries = vec![export_area_options .into_iter() - .map(|(val, name, disabled)| DropdownEntryData::new(name).on_update(move |_| ExportDialogMessage::ExportBounds(val).into()).disabled(disabled)) + .map(|(val, name, disabled)| MenuListEntry::new(name).on_update(move |_| ExportDialogMessage::ExportBounds(val).into()).disabled(disabled)) .collect()]; let export_area = vec![ 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 95310a554e..7dae666778 100644 --- a/editor/src/messages/layout/utility_types/widgets/button_widgets.rs +++ b/editor/src/messages/layout/utility_types/widgets/button_widgets.rs @@ -100,6 +100,9 @@ pub struct TextButton { #[serde(skip)] pub tooltip_shortcut: Option, + #[serde(rename = "menuListChildren")] + pub menu_list_children: MenuListEntrySections, + // Callbacks #[serde(skip)] #[derivative(Debug = "ignore", PartialEq = "ignore")] 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 788fdac627..79b1438b61 100644 --- a/editor/src/messages/layout/utility_types/widgets/input_widgets.rs +++ b/editor/src/messages/layout/utility_types/widgets/input_widgets.rs @@ -48,7 +48,7 @@ impl Default for CheckboxInput { #[derivative(Debug, PartialEq, Default)] pub struct DropdownInput { #[widget_builder(constructor)] - pub entries: DropdownInputEntries, + pub entries: MenuListEntrySections, // This uses `u32` instead of `usize` since it will be serialized as a normal JS number (replace this with `usize` after switching to a Rust-based GUI) #[serde(rename = "selectedIndex")] @@ -68,15 +68,15 @@ pub struct DropdownInput { pub tooltip_shortcut: Option, // // Callbacks - // `on_update` exists on the `DropdownEntryData`, not this parent `DropdownInput` + // `on_update` exists on the `MenuListEntry`, not this parent `DropdownInput` } -pub type DropdownInputEntries = Vec>; +pub type MenuListEntrySections = Vec>; #[derive(Clone, Serialize, Deserialize, Derivative, Default, WidgetBuilder, specta::Type)] #[derivative(Debug, PartialEq)] #[widget_builder(not_widget_holder)] -pub struct DropdownEntryData { +pub struct MenuListEntry { pub value: String, #[widget_builder(constructor)] @@ -91,7 +91,7 @@ pub struct DropdownEntryData { pub disabled: bool, - pub children: DropdownInputEntries, + pub children: MenuListEntrySections, // Callbacks #[serde(skip)] diff --git a/editor/src/messages/portfolio/document/document_message_handler.rs b/editor/src/messages/portfolio/document/document_message_handler.rs index 386f2d19d4..fa4e1dad0c 100644 --- a/editor/src/messages/portfolio/document/document_message_handler.rs +++ b/editor/src/messages/portfolio/document/document_message_handler.rs @@ -1590,11 +1590,11 @@ impl DocumentMessageHandler { widgets: vec![ DropdownInput::new( vec![vec![ - DropdownEntryData::new(DocumentMode::DesignMode.to_string()).icon(DocumentMode::DesignMode.icon_name()), - DropdownEntryData::new(DocumentMode::SelectMode.to_string()) + MenuListEntry::new(DocumentMode::DesignMode.to_string()).icon(DocumentMode::DesignMode.icon_name()), + MenuListEntry::new(DocumentMode::SelectMode.to_string()) .icon(DocumentMode::SelectMode.icon_name()) .on_update(|_| DialogMessage::RequestComingSoonDialog { issue: Some(330) }.into()), - DropdownEntryData::new(DocumentMode::GuideMode.to_string()) + MenuListEntry::new(DocumentMode::GuideMode.to_string()) .icon(DocumentMode::GuideMode.icon_name()) .on_update(|_| DialogMessage::RequestComingSoonDialog { issue: Some(331) }.into()), ]]) @@ -1662,7 +1662,7 @@ impl DocumentMessageHandler { modes .iter() .map(|mode| { - DropdownEntryData::new(mode.to_string()) + MenuListEntry::new(mode.to_string()) .value(mode.to_string()) .on_update(|_| DocumentMessage::SetBlendModeForSelectedLayers { blend_mode: *mode }.into()) }) 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 cf8034cf64..34fca8ba49 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 @@ -333,7 +333,7 @@ fn color_channel(document_node: &DocumentNode, node_id: u64, index: usize, name: let calculation_modes = [RedGreenBlue::Red, RedGreenBlue::Green, RedGreenBlue::Blue]; let mut entries = Vec::with_capacity(calculation_modes.len()); for method in calculation_modes { - entries.push(DropdownEntryData::new(method.to_string()).on_update(update_value(move |_| TaggedValue::RedGreenBlue(method), node_id, index))); + entries.push(MenuListEntry::new(method.to_string()).on_update(update_value(move |_| TaggedValue::RedGreenBlue(method), node_id, index))); } let entries = vec![entries]; @@ -356,7 +356,7 @@ fn noise_type(document_node: &DocumentNode, node_id: u64, index: usize, name: &s let calculation_modes = NoiseType::list(); let mut entries = Vec::with_capacity(calculation_modes.len()); for method in calculation_modes { - entries.push(DropdownEntryData::new(method.to_string()).on_update(update_value(move |_| TaggedValue::NoiseType(method), node_id, index))); + entries.push(MenuListEntry::new(method.to_string()).on_update(update_value(move |_| TaggedValue::NoiseType(method), node_id, index))); } let entries = vec![entries]; @@ -381,7 +381,7 @@ fn blend_mode(document_node: &DocumentNode, node_id: u64, index: usize, name: &s .map(|category| { category .iter() - .map(|mode| DropdownEntryData::new(mode.to_string()).on_update(update_value(move |_| TaggedValue::BlendMode(*mode), node_id, index))) + .map(|mode| MenuListEntry::new(mode.to_string()).on_update(update_value(move |_| TaggedValue::BlendMode(*mode), node_id, index))) .collect() }) .collect(); @@ -405,7 +405,7 @@ fn luminance_calculation(document_node: &DocumentNode, node_id: u64, index: usiz let calculation_modes = LuminanceCalculation::list(); let mut entries = Vec::with_capacity(calculation_modes.len()); for method in calculation_modes { - entries.push(DropdownEntryData::new(method.to_string()).on_update(update_value(move |_| TaggedValue::LuminanceCalculation(method), node_id, index))); + entries.push(MenuListEntry::new(method.to_string()).on_update(update_value(move |_| TaggedValue::LuminanceCalculation(method), node_id, index))); } let entries = vec![entries]; @@ -955,7 +955,7 @@ pub fn adjust_selective_color_properties(document_node: &DocumentNode, node_id: .map(|section| { section .iter() - .map(|choice| DropdownEntryData::new(choice.to_string()).on_update(update_value(move |_| TaggedValue::SelectiveColorChoice(*choice), node_id, colors_index))) + .map(|choice| MenuListEntry::new(choice.to_string()).on_update(update_value(move |_| TaggedValue::SelectiveColorChoice(*choice), node_id, colors_index))) .collect() }) .collect(); @@ -1577,7 +1577,7 @@ pub fn imaginate_properties(document_node: &DocumentNode, node_id: NodeId, conte let sampling_methods = ImaginateSamplingMethod::list(); let mut entries = Vec::with_capacity(sampling_methods.len()); for method in sampling_methods { - entries.push(DropdownEntryData::new(method.to_string()).on_update(update_value(move |_| TaggedValue::ImaginateSamplingMethod(method), node_id, sampling_method_index))); + entries.push(MenuListEntry::new(method.to_string()).on_update(update_value(move |_| TaggedValue::ImaginateSamplingMethod(method), node_id, sampling_method_index))); } let entries = vec![entries]; @@ -1730,7 +1730,7 @@ pub fn imaginate_properties(document_node: &DocumentNode, node_id: NodeId, conte let mask_fill_content_modes = ImaginateMaskStartingFill::list(); let mut entries = Vec::with_capacity(mask_fill_content_modes.len()); for mode in mask_fill_content_modes { - entries.push(DropdownEntryData::new(mode.to_string()).on_update(update_value(move |_| TaggedValue::ImaginateMaskStartingFill(mode), node_id, mask_fill_index))); + entries.push(MenuListEntry::new(mode.to_string()).on_update(update_value(move |_| TaggedValue::ImaginateMaskStartingFill(mode), node_id, mask_fill_index))); } let entries = vec![entries]; diff --git a/editor/src/messages/tool/tool_messages/brush_tool.rs b/editor/src/messages/tool/tool_messages/brush_tool.rs index 7e6d38915f..354952d542 100644 --- a/editor/src/messages/tool/tool_messages/brush_tool.rs +++ b/editor/src/messages/tool/tool_messages/brush_tool.rs @@ -198,7 +198,7 @@ impl LayoutHolder for BrushTool { group .iter() .map(|blend_mode| { - DropdownEntryData::new(format!("{blend_mode}")) + MenuListEntry::new(format!("{blend_mode}")) .value(format!("{blend_mode:?}")) .on_update(|_| BrushToolMessage::UpdateOptions(BrushToolMessageOptionsUpdate::BlendMode(*blend_mode)).into()) }) diff --git a/editor/src/messages/tool/tool_messages/select_tool.rs b/editor/src/messages/tool/tool_messages/select_tool.rs index ee3330d8fd..6224ddad0c 100644 --- a/editor/src/messages/tool/tool_messages/select_tool.rs +++ b/editor/src/messages/tool/tool_messages/select_tool.rs @@ -103,7 +103,7 @@ impl SelectTool { // let layer_selection_behavior_entries = [NestedSelectionBehavior::Deepest, NestedSelectionBehavior::Shallowest] // .iter() // .map(|mode| { - // DropdownEntryData::new(mode.to_string()) + // MenuListEntry::new(mode.to_string()) // .value(mode.to_string()) // .on_update(move |_| SelectToolMessage::SelectOptions(SelectOptionsUpdate::NestedSelectionBehavior(*mode)).into()) // }) diff --git a/frontend/src/components/layout/ConditionalWrapper.svelte b/frontend/src/components/layout/ConditionalWrapper.svelte new file mode 100644 index 0000000000..46d5e80b04 --- /dev/null +++ b/frontend/src/components/layout/ConditionalWrapper.svelte @@ -0,0 +1,14 @@ + + +{#if condition} +
+ +
+{:else} + +{/if} + + diff --git a/frontend/src/components/widgets/buttons/MenuListButton.svelte b/frontend/src/components/widgets/buttons/MenuListButton.svelte deleted file mode 100644 index edb770482f..0000000000 --- a/frontend/src/components/widgets/buttons/MenuListButton.svelte +++ /dev/null @@ -1,83 +0,0 @@ - - - - - diff --git a/frontend/src/components/widgets/buttons/TextButton.svelte b/frontend/src/components/widgets/buttons/TextButton.svelte index 96987070ed..0d1df71b7a 100644 --- a/frontend/src/components/widgets/buttons/TextButton.svelte +++ b/frontend/src/components/widgets/buttons/TextButton.svelte @@ -1,9 +1,17 @@ - + {#if menuListChildrenExists} + self && (self.open = detail)} + open={self?.open || false} + entries={menuListChildren || []} + direction="Bottom" + minWidth={240} + drawIcon={true} + bind:this={self} + /> {/if} - {label} - + diff --git a/frontend/src/components/widgets/inputs/NumberInput.svelte b/frontend/src/components/widgets/inputs/NumberInput.svelte index 2a9990bd56..51e87cc83a 100644 --- a/frontend/src/components/widgets/inputs/NumberInput.svelte +++ b/frontend/src/components/widgets/inputs/NumberInput.svelte @@ -248,7 +248,7 @@ function onDragPointerDown(e: PointerEvent) { // Only drag the number with left click (and when it's valid to do so) - if (e.button !== BUTTON_LEFT || mode !== "Increment" || value === undefined) return; + if (e.button !== BUTTON_LEFT || mode !== "Increment" || value === undefined || disabled) return; // Don't drag the text value from is input element e.preventDefault(); @@ -633,8 +633,8 @@ } // Show the left-right arrow cursor when hovered over the draggable area - input[type="text"]:not(:focus), - label { + &:not(.disabled) input[type="text"]:not(:focus), + &:not(.disabled) label { cursor: ew-resize; } diff --git a/frontend/src/components/window/title-bar/TitleBar.svelte b/frontend/src/components/window/title-bar/TitleBar.svelte index adf7902216..ab7a4736b6 100644 --- a/frontend/src/components/window/title-bar/TitleBar.svelte +++ b/frontend/src/components/window/title-bar/TitleBar.svelte @@ -11,7 +11,7 @@ import { type KeyRaw, type LayoutKeysGroup, type MenuBarEntry, type MenuListEntry, UpdateMenuBarLayout } from "@graphite/wasm-communication/messages"; import LayoutRow from "@graphite/components/layout/LayoutRow.svelte"; - import MenuListButton from "@graphite/components/widgets/buttons/MenuListButton.svelte"; + import TextButton from "@graphite/components/widgets/buttons/TextButton.svelte"; import WindowButtonsMac from "@graphite/components/window/title-bar/WindowButtonsMac.svelte"; import WindowButtonsWeb from "@graphite/components/window/title-bar/WindowButtonsWeb.svelte"; import WindowButtonsWindows from "@graphite/components/window/title-bar/WindowButtonsWindows.svelte"; @@ -77,7 +77,7 @@ {:else} {#each entries as entry} - + {/each} {/if} @@ -115,5 +115,9 @@ justify-content: flex-end; } } + + .text-button { + height: 28px; + } } diff --git a/frontend/src/wasm-communication/messages.ts b/frontend/src/wasm-communication/messages.ts index 5ffaaca661..55a1190d73 100644 --- a/frontend/src/wasm-communication/messages.ts +++ b/frontend/src/wasm-communication/messages.ts @@ -793,7 +793,7 @@ export type MenuBarEntry = MenuEntryCommon & { disabled?: boolean; }; -// An entry in the all-encompassing MenuList component which defines all types of menus (which are spawned by widgets like `MenuListButton` and `DropdownInput`) +// An entry in the all-encompassing MenuList component which defines all types of menus (which are spawned by widgets like `TextButton` and `DropdownInput`) export type MenuListEntry = MenuEntryCommon & { action?: () => void; children?: MenuListEntry[][]; @@ -1055,6 +1055,8 @@ export class TextButton extends WidgetProps { @Transform(({ value }: { value: string }) => value || undefined) tooltip!: string | undefined; + + menuListChildren!: MenuListEntry[][]; } export type TextButtonWidget = {