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 640ec8a5c7..fcdd7bb3f9 100644 --- a/editor/src/messages/layout/utility_types/widgets/button_widgets.rs +++ b/editor/src/messages/layout/utility_types/widgets/button_widgets.rs @@ -1,5 +1,6 @@ use crate::messages::input_mapper::utility_types::misc::ActionKeys; use crate::messages::layout::utility_types::layout_widget::WidgetCallback; +use crate::messages::layout::utility_types::widget_prelude::WidgetLayout; use crate::messages::portfolio::document::node_graph::FrontendGraphDataType; use graphite_proc_macros::WidgetBuilder; @@ -48,6 +49,8 @@ pub struct PopoverButton { pub tooltip: String, + pub options_widget: WidgetLayout, + #[serde(skip)] pub tooltip_shortcut: Option, } diff --git a/editor/src/messages/portfolio/document/document_message_handler.rs b/editor/src/messages/portfolio/document/document_message_handler.rs index a5762dbf9b..c40a63cee6 100644 --- a/editor/src/messages/portfolio/document/document_message_handler.rs +++ b/editor/src/messages/portfolio/document/document_message_handler.rs @@ -1,5 +1,5 @@ use super::utility_types::error::EditorError; -use super::utility_types::misc::DocumentRenderMode; +use super::utility_types::misc::{DocumentRenderMode, SnappingOptions}; use crate::application::generate_uuid; use crate::consts::{ASYMPTOTIC_EFFECT, DEFAULT_DOCUMENT_NAME, FILE_SAVE_SUFFIX, GRAPHITE_DOCUMENT_VERSION, SCALE_EFFECT, SCROLLBAR_SPACING, VIEWPORT_ZOOM_TO_FIT_PADDING_SCALE_FACTOR}; use crate::messages::frontend::utility_types::ExportBounds; @@ -1561,9 +1561,28 @@ impl DocumentMessageHandler { on_update: WidgetCallback::new(|optional_input: &OptionalInput| DocumentMessage::SetSnapping { snap: optional_input.checked }.into()), ..Default::default() })), + // this isn't working, why? WidgetHolder::new(Widget::PopoverButton(PopoverButton { header: "Snapping".into(), - text: "Coming soon".into(), + text: "Select the vector to snap to.".into(), // TODO: check whether this is an apt description + options_widget: WidgetLayout::new(vec![LayoutGroup::Row { + widgets: vec![WidgetHolder::new(Widget::DropdownInput(DropdownInput { + entries: vec![vec![ + DropdownEntryData { + label: SnappingOptions::BoundingBoxes.to_string(), + ..DropdownEntryData::default() + }, + DropdownEntryData { + label: SnappingOptions::Nodes.to_string(), + ..DropdownEntryData::default() + }, + ]], + selected_index: Some(0_u32), + draw_icon: false, + interactive: true, + ..Default::default() + }))], + }]), ..Default::default() })), WidgetHolder::new(Widget::Separator(Separator { diff --git a/editor/src/messages/portfolio/document/utility_types/misc.rs b/editor/src/messages/portfolio/document/utility_types/misc.rs index 135495b6ed..f43d305121 100644 --- a/editor/src/messages/portfolio/document/utility_types/misc.rs +++ b/editor/src/messages/portfolio/document/utility_types/misc.rs @@ -74,3 +74,19 @@ pub enum DocumentRenderMode<'a> { OnlyBelowLayerInFolder(&'a [LayerId]), LayerCutout(&'a [LayerId], Color), } + +pub enum SnappingOptions { + BoundingBoxes, + Nodes, +} + +impl fmt::Display for SnappingOptions { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + SnappingOptions::BoundingBoxes => write!(f, "Bounding Boxes"), + SnappingOptions::Nodes => write!(f, "Nodes"), + } + } +} + +// TODO: implement icons for SnappingOptions eventually diff --git a/frontend/src/components/widgets/WidgetRow.svelte b/frontend/src/components/widgets/WidgetRow.svelte index 2bce91ee7f..fb6d099c74 100644 --- a/frontend/src/components/widgets/WidgetRow.svelte +++ b/frontend/src/components/widgets/WidgetRow.svelte @@ -141,6 +141,8 @@ {popoverButton.header} {popoverButton.text} + + {/if} {@const radioInput = narrowWidgetProps(component.props, "RadioInput")} diff --git a/frontend/src/components/widgets/buttons/PopoverButton.svelte b/frontend/src/components/widgets/buttons/PopoverButton.svelte index 35355741cc..bc86a7c42d 100644 --- a/frontend/src/components/widgets/buttons/PopoverButton.svelte +++ b/frontend/src/components/widgets/buttons/PopoverButton.svelte @@ -4,10 +4,12 @@ import FloatingMenu from "@graphite/components/layout/FloatingMenu.svelte"; import LayoutRow from "@graphite/components/layout/LayoutRow.svelte"; import IconButton from "@graphite/components/widgets/buttons/IconButton.svelte"; + import WidgetLayout from "../WidgetLayout.svelte"; export let icon: IconName = "DropdownArrow"; export let tooltip: string | undefined = undefined; export let disabled = false; + export let options_widget: WidgetLayout | undefined = undefined; // Callbacks export let action: (() => void) | undefined = undefined; @@ -20,7 +22,13 @@ - onClick()} icon={icon || "DropdownArrow"} size={16} {tooltip} data-floating-menu-spawner /> + {#if options_widget === undefined} + onClick()} icon={icon || "DropdownArrow"} size={16} {tooltip} data-floating-menu-spawner /> + + {:else} + onClick()} icon={icon || "DropdownArrow"} size={16} {options_widget} data-floating-menu-spawner /> + {/if} + (open = detail)} type="Popover" direction="Bottom"> diff --git a/frontend/src/wasm-communication/messages.ts b/frontend/src/wasm-communication/messages.ts index 7dcdb1fed7..0c6cfab5cf 100644 --- a/frontend/src/wasm-communication/messages.ts +++ b/frontend/src/wasm-communication/messages.ts @@ -931,6 +931,8 @@ export class PopoverButton extends WidgetProps { @Transform(({ value }: { value: string }) => value || undefined) tooltip!: string | undefined; + + options_widget: WidgetLayout | undefined; } export type RadioEntryData = {