diff --git a/frontend/src/components/floating-menus/ColorPicker.svelte b/frontend/src/components/floating-menus/ColorPicker.svelte index 0757887d..c08ccb6f 100644 --- a/frontend/src/components/floating-menus/ColorPicker.svelte +++ b/frontend/src/components/floating-menus/ColorPicker.svelte @@ -62,19 +62,17 @@ let draggingPickerTrack: HTMLDivElement | undefined = undefined; let strayCloses = true; - $: rgbChannels = Object.entries(newColor.toRgb255() || { r: undefined, g: undefined, b: undefined }) as [keyof RGB, number | undefined][]; - $: hsvChannels = Object.entries(!isNone ? { h: hue * 360, s: saturation * 100, v: value * 100 } : { h: undefined, s: undefined, v: undefined }) as [keyof HSV, number | undefined][]; - $: opaqueHueColor = new Color({ h: hue, s: 1, v: 1, a: 1 }); - $: newColor = isNone ? new Color("none") : new Color({ h: hue, s: saturation, v: value, a: alpha }); - $: initialColor = updateInitialColor(initialHue, initialSaturation, initialValue, initialAlpha, initialIsNone, open); - $: watchOpen(open); $: watchColor(color); - // Taking `_open` is necessary to make Svelte order the reactive processing queue so this works as required, see: - // https://stackoverflow.com/questions/63934543/svelte-reactivity-not-triggering-when-variable-changed-in-a-function - function updateInitialColor(h: number, s: number, v: number, a: number, initialIsNone: boolean, _open: boolean) { - if (initialIsNone) return new Color("none"); + $: initialColor = generateColor(initialHue, initialSaturation, initialValue, initialAlpha, initialIsNone); + $: newColor = generateColor(hue, saturation, value, alpha, isNone); + $: rgbChannels = Object.entries(newColor.toRgb255() || { r: undefined, g: undefined, b: undefined }) as [keyof RGB, number | undefined][]; + $: hsvChannels = Object.entries(!isNone ? { h: hue * 360, s: saturation * 100, v: value * 100 } : { h: undefined, s: undefined, v: undefined }) as [keyof HSV, number | undefined][]; + $: opaqueHueColor = new Color({ h: hue, s: 1, v: 1, a: 1 }); + + function generateColor(h: number, s: number, v: number, a: number, none: boolean, ..._: any[]) { + if (none) return new Color("none"); return new Color({ h, s, v, a }); } @@ -96,7 +94,7 @@ // - ...reset the hue to 0° if the color's value is black, where all hues are equivalent if (!(hsva.h === 0 && hue === 1) && hsva.s > 0 && hsva.v > 0) hue = hsva.h; // Update the saturation, but only if it is necessary so we don't: - // - ...reset the saturation to the left is the color's value is black along the bottom edge, where all saturations are equivalent + // - ...reset the saturation to the left if the color's value is black along the bottom edge, where all saturations are equivalent if (hsva.v !== 0) saturation = hsva.s; // Update the value value = hsva.v; diff --git a/frontend/src/components/floating-menus/MenuList.svelte b/frontend/src/components/floating-menus/MenuList.svelte index 864d3d70..2d106039 100644 --- a/frontend/src/components/floating-menus/MenuList.svelte +++ b/frontend/src/components/floating-menus/MenuList.svelte @@ -36,6 +36,7 @@ // Called only when `open` is changed from outside this component $: watchOpen(open); $: watchRemeasureWidth(entries, drawIcon); + $: virtualScrollingTotalHeight = entries.length === 0 ? 0 : entries[0].length * virtualScrollingEntryHeight; $: virtualScrollingStartIndex = Math.floor(virtualScrollingEntriesStart / virtualScrollingEntryHeight) || 0; $: virtualScrollingEndIndex = entries.length === 0 ? 0 : Math.min(entries[0].length, virtualScrollingStartIndex + 1 + 400 / virtualScrollingEntryHeight); @@ -62,7 +63,10 @@ dispatch("activeEntry", menuListEntry); // Close the containing menu - if (menuListEntry.ref) menuListEntry.ref.open = false; + if (menuListEntry.ref) { + menuListEntry.ref.open = false; + entries = entries; + } dispatch("open", false); open = false; } @@ -70,15 +74,19 @@ function onEntryPointerEnter(menuListEntry: MenuListEntry): void { if (!menuListEntry.children?.length) return; - if (menuListEntry.ref) menuListEntry.ref.open = true; - else dispatch("open", true); + if (menuListEntry.ref) { + menuListEntry.ref.open = true; + entries = entries; + } else dispatch("open", true); } function onEntryPointerLeave(menuListEntry: MenuListEntry): void { if (!menuListEntry.children?.length) return; - if (menuListEntry.ref) menuListEntry.ref.open = false; - else dispatch("open", false); + if (menuListEntry.ref) { + menuListEntry.ref.open = false; + entries = entries; + } else dispatch("open", false); } function isEntryOpen(menuListEntry: MenuListEntry): boolean { @@ -96,12 +104,15 @@ const flatEntries = entries.flat().filter((entry) => !entry.disabled); const openChild = flatEntries.findIndex((entry) => entry.children?.length && entry.ref?.open); - const openSubmenu = (highlighted: MenuListEntry): void => { - if (highlighted.ref && highlighted.children?.length) { - highlighted.ref.open = true; + const openSubmenu = (highlightedEntry: MenuListEntry): void => { + if (highlightedEntry.ref && highlightedEntry.children?.length) { + highlightedEntry.ref.open = true; + // The reason we bother taking `highlightdEntry` as an argument is because, when this function is called, it can ensure `highlightedEntry` is not undefined. + // But here we still have to set `highlighted` to itself so Svelte knows to reactively update it after we set its `.ref.open` property. + highlighted = highlighted; // Highlight first item - highlighted.ref.setHighlighted(highlighted.children[0][0]); + highlightedEntry.ref.setHighlighted(highlightedEntry.children[0][0]); } }; diff --git a/frontend/src/components/layout/FloatingMenu.svelte b/frontend/src/components/layout/FloatingMenu.svelte index 0514c2ed..506b3a65 100644 --- a/frontend/src/components/layout/FloatingMenu.svelte +++ b/frontend/src/components/layout/FloatingMenu.svelte @@ -50,6 +50,8 @@ let floatingMenuBounds = new DOMRect(); let floatingMenuContentBounds = new DOMRect(); + $: watchOpenChange(open); + $: minWidthStyleValue = measuringOngoing ? "0" : `${Math.max(minWidth, minWidthParentWidth)}px`; $: displayTail = open && type === "Popover"; $: displayContainer = open || measuringOngoing; @@ -60,8 +62,6 @@ .flatMap((styleAndValue) => (styleAndValue[1] !== undefined ? [`${styleAndValue[0]}: ${styleAndValue[1]};`] : [])) .join(" "); - $: watchOpenChange(open); - // Called only when `open` is changed from outside this component async function watchOpenChange(isOpen: boolean) { // Switching from closed to open diff --git a/frontend/src/components/panels/LayerTree.svelte b/frontend/src/components/panels/LayerTree.svelte index 51f6981d..d81a7c74 100644 --- a/frontend/src/components/panels/LayerTree.svelte +++ b/frontend/src/components/panels/LayerTree.svelte @@ -100,8 +100,9 @@ async function onEditLayerName(listing: LayerListingInfo) { if (listing.editingName) return; - listing.editingName = true; draggable = false; + listing.editingName = true; + layers = layers; await tick(); @@ -117,6 +118,7 @@ const name = (e.target as HTMLInputElement | undefined)?.value; listing.editingName = false; + layers = layers; if (name) editor.instance.setLayerName(listing.entry.path, name); } @@ -124,6 +126,7 @@ draggable = true; listing.editingName = false; + layers = layers; await tick(); window.getSelection()?.removeAllRanges(); @@ -211,7 +214,7 @@ }); } - markerHeight -= (treeOffset || 0); + markerHeight -= treeOffset || 0; return { select, diff --git a/frontend/src/components/panels/NodeGraph.svelte b/frontend/src/components/panels/NodeGraph.svelte index 19ce9761..dc64e9ca 100644 --- a/frontend/src/components/panels/NodeGraph.svelte +++ b/frontend/src/components/panels/NodeGraph.svelte @@ -38,6 +38,8 @@ let searchTerm = ""; let nodeListLocation: { x: number; y: number } | undefined = undefined; + $: watchNodes($nodeGraph.nodes); + $: gridSpacing = calculateGridSpacing(transform.scale); $: dotRadius = 1 + Math.floor(transform.scale - 0.5 + 0.001) / 2; $: nodeGraphBarLayout = $nodeGraph.nodeGraphBarLayout; @@ -47,8 +49,6 @@ $: linkPathInProgress = createLinkPathInProgress(linkInProgressFromConnector, linkInProgressToConnector); $: linkPaths = createLinkPaths(linkPathInProgress, nodeLinkPaths); - $: watchNodes($nodeGraph.nodes); - function calculateGridSpacing(scale: number): number { const dense = scale * GRID_SIZE; let sparse = dense; diff --git a/frontend/src/components/widgets/buttons/ParameterExposeButton.svelte b/frontend/src/components/widgets/buttons/ParameterExposeButton.svelte index 54dee48d..7d50236c 100644 --- a/frontend/src/components/widgets/buttons/ParameterExposeButton.svelte +++ b/frontend/src/components/widgets/buttons/ParameterExposeButton.svelte @@ -9,7 +9,7 @@ -