mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-23 07:48:12 +08:00
Refactor messages.ts by removing class-transformer and JS classes (#3858)
* Fix gamma correction with HTML-based editable Text tool text * Migrate simple, undecorated classes to types * Remove TupleToVec2 transformation * Remove @Transform from tooltips * Cleanup: replace value.toString() with String(value) everywhere * Convert documentId from string to bigint * Migrate the rest of the easy @Transform/@Type decorations * Migrate FillChoice * Migrate WidgetDiffUpdate * Migrate WidgetInstance * Migrate away from classes that extend WidgetProps * Remove class-transformer and all classes in messages.ts * Migrate UI layout passing * Remove dead code * Remove unnecessary export and readonly prefixes * Remove HSVA type * Break out Color, Gradient, and FillChoice functions into a utility-functions file * Move widget helper functions from messages.ts into a new utility-functions file; restructure type imports * Reduce internal type defs * Rename JsMessage to FrontendMessage * Code review fixes * Fix other usages * Tidying up
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { onMount, onDestroy, setContext } from "svelte";
|
||||
|
||||
import { type Editor } from "@graphite/editor";
|
||||
import type { Editor } from "@graphite/editor";
|
||||
import { createClipboardManager } from "@graphite/io-managers/clipboard";
|
||||
import { createHyperlinkManager } from "@graphite/io-managers/hyperlink";
|
||||
import { createInputManager } from "@graphite/io-managers/input";
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
<script lang="ts">
|
||||
import { getContext, onDestroy, createEventDispatcher, tick } from "svelte";
|
||||
|
||||
import type { HSV, RGB, FillChoice, MenuDirection } from "@graphite/messages";
|
||||
import type { FillChoice, MenuDirection } from "@graphite/messages";
|
||||
import type { Color } from "@graphite/messages";
|
||||
import type { TooltipState } from "@graphite/state-providers/tooltip";
|
||||
import {
|
||||
type Color,
|
||||
contrastingOutlineFactor,
|
||||
isColor,
|
||||
isGradient,
|
||||
@@ -12,7 +13,7 @@
|
||||
createColorFromHSVA,
|
||||
colorFromCSS,
|
||||
colorToRgb255,
|
||||
colorToHSVA,
|
||||
colorToHSV,
|
||||
colorToHexOptionalAlpha,
|
||||
colorToHexNoAlpha,
|
||||
colorToRgbCSS,
|
||||
@@ -20,8 +21,8 @@
|
||||
colorOpaque,
|
||||
colorEquals,
|
||||
gradientFirstColor,
|
||||
} from "@graphite/messages";
|
||||
import type { TooltipState } from "@graphite/state-providers/tooltip";
|
||||
} from "@graphite/utility-functions/colors";
|
||||
import type { HSV, RGB } from "@graphite/utility-functions/colors";
|
||||
import { clamp } from "@graphite/utility-functions/math";
|
||||
import { isDesktop } from "@graphite/utility-functions/platform";
|
||||
|
||||
@@ -70,8 +71,8 @@
|
||||
export let open: boolean;
|
||||
|
||||
const colorForHSVA = isColor(colorOrGradient) ? colorOrGradient : gradientFirstColor(colorOrGradient);
|
||||
const hsvaOrNone = colorForHSVA ? colorToHSVA(colorForHSVA) : undefined;
|
||||
const hsva = hsvaOrNone || { h: 0, s: 0, v: 0, a: 1 };
|
||||
const hsvOrNone = colorForHSVA ? colorToHSV(colorForHSVA) : undefined;
|
||||
const hsv = hsvOrNone || { h: 0, s: 0, v: 0 };
|
||||
|
||||
// Gradient color stops
|
||||
$: gradient = isGradient(colorOrGradient) ? colorOrGradient : undefined;
|
||||
@@ -81,17 +82,17 @@
|
||||
// Currently viewed color
|
||||
$: color = isColor(colorOrGradient) ? colorOrGradient : selectedGradientColor;
|
||||
// New color components
|
||||
let hue = hsva.h;
|
||||
let saturation = hsva.s;
|
||||
let value = hsva.v;
|
||||
let alpha = hsva.a;
|
||||
let isNone = hsvaOrNone === undefined;
|
||||
let hue = hsv.h;
|
||||
let saturation = hsv.s;
|
||||
let value = hsv.v;
|
||||
let alpha = colorForHSVA ? colorForHSVA.alpha : 1;
|
||||
let isNone = hsvOrNone === undefined;
|
||||
// Old color components
|
||||
let oldHue = hsva.h;
|
||||
let oldSaturation = hsva.s;
|
||||
let oldValue = hsva.v;
|
||||
let oldAlpha = hsva.a;
|
||||
let oldIsNone = hsvaOrNone === undefined;
|
||||
let oldHue = hsv.h;
|
||||
let oldSaturation = hsv.s;
|
||||
let oldValue = hsv.v;
|
||||
let oldAlpha = colorForHSVA ? colorForHSVA.alpha : 1;
|
||||
let oldIsNone = hsvOrNone === undefined;
|
||||
// Transient state
|
||||
let draggingPickerTrack: HTMLDivElement | undefined = undefined;
|
||||
let strayCloses = true;
|
||||
@@ -114,8 +115,8 @@
|
||||
$: watchOpen(open);
|
||||
$: watchColor(color);
|
||||
|
||||
$: oldColor = generateColor(oldHue, oldSaturation, oldValue, oldAlpha, oldIsNone);
|
||||
$: newColor = generateColor(hue, saturation, value, alpha, isNone);
|
||||
$: oldColor = oldIsNone ? createNoneColor() : createColorFromHSVA(oldHue, oldSaturation, oldValue, oldAlpha);
|
||||
$: newColor = isNone ? createNoneColor() : createColorFromHSVA(hue, saturation, value, alpha);
|
||||
$: rgbChannels = Object.entries(colorToRgb255(newColor) || { 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 = createColorFromHSVA(hue, 1, 1, 1);
|
||||
@@ -123,11 +124,6 @@
|
||||
$: outlined = outlineFactor > 0.0001;
|
||||
$: transparency = newColor.alpha < 1 || oldColor.alpha < 1;
|
||||
|
||||
function generateColor(h: number, s: number, v: number, a: number, none: boolean) {
|
||||
if (none) return createNoneColor();
|
||||
return createColorFromHSVA(h, s, v, a);
|
||||
}
|
||||
|
||||
async function watchOpen(open: boolean) {
|
||||
if (open) {
|
||||
setTimeout(() => hexCodeInputWidget?.focus(), 0);
|
||||
@@ -138,9 +134,9 @@
|
||||
}
|
||||
|
||||
function watchColor(color: Color) {
|
||||
const hsva = colorToHSVA(color);
|
||||
const hsv = colorToHSV(color);
|
||||
|
||||
if (hsva === undefined) {
|
||||
if (hsv === undefined) {
|
||||
setNewHSVA(0, 0, 0, 1, true);
|
||||
return;
|
||||
}
|
||||
@@ -149,14 +145,14 @@
|
||||
// - ...jump the user's hue from 360° (top) to the equivalent 0° (bottom)
|
||||
// - ...reset the hue to 0° if the color is fully desaturated, where all hues are equivalent
|
||||
// - ...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;
|
||||
if (!(hsv.h === 0 && hue === 1) && hsv.s > 0 && hsv.v > 0) hue = hsv.h;
|
||||
// Update the saturation, but only if it is necessary so we don't:
|
||||
// - ...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;
|
||||
if (hsv.v !== 0) saturation = hsv.s;
|
||||
// Update the value
|
||||
value = hsva.v;
|
||||
value = hsv.v;
|
||||
// Update the alpha
|
||||
alpha = hsva.a;
|
||||
alpha = color.alpha;
|
||||
// Update the status of this not being a color
|
||||
isNone = false;
|
||||
}
|
||||
@@ -375,9 +371,10 @@
|
||||
setColor(createNoneColor());
|
||||
} else {
|
||||
const presetColor = createColor(...PURE_COLORS[preset], 1);
|
||||
const hsva = colorToHSVA(presetColor) || { h: 0, s: 0, v: 0, a: 0 };
|
||||
const hsv = colorToHSV(presetColor);
|
||||
if (!hsv) return;
|
||||
|
||||
setNewHSVA(hsva.h, hsva.s, hsva.v, hsva.a, false);
|
||||
setNewHSVA(hsv.h, hsv.s, hsv.v, presetColor.alpha, false);
|
||||
setColor(presetColor);
|
||||
}
|
||||
}
|
||||
@@ -425,13 +422,13 @@
|
||||
activeIndexIsMidpoint = activeMarkerIsMidpoint;
|
||||
|
||||
const color = activeMarkerIndex === undefined ? undefined : gradient?.color[activeMarkerIndex];
|
||||
const hsva = color ? colorToHSVA(color) : undefined;
|
||||
if (!color || !hsva) return;
|
||||
const hsv = color ? colorToHSV(color) : undefined;
|
||||
if (!color || !hsv) return;
|
||||
|
||||
setColor(color);
|
||||
|
||||
setNewHSVA(hsva.h, hsva.s, hsva.v, hsva.a, color.none);
|
||||
setOldHSVA(hsva.h, hsva.s, hsva.v, hsva.a, color.none);
|
||||
setNewHSVA(hsv.h, hsv.s, hsv.v, color.alpha, color.none);
|
||||
setOldHSVA(hsv.h, hsv.s, hsv.v, color.alpha, color.none);
|
||||
}
|
||||
|
||||
export function div(): HTMLDivElement | undefined {
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
import { getContext, onMount, onDestroy } from "svelte";
|
||||
|
||||
import type { Editor } from "@graphite/editor";
|
||||
import { patchLayout, UpdateDataPanelLayout, type Layout } from "@graphite/messages";
|
||||
import type { Layout } from "@graphite/messages";
|
||||
import { patchLayout } from "@graphite/utility-functions/widgets";
|
||||
|
||||
import LayoutCol from "@graphite/components/layout/LayoutCol.svelte";
|
||||
import WidgetLayout from "@graphite/components/widgets/WidgetLayout.svelte";
|
||||
@@ -12,14 +13,14 @@
|
||||
let dataPanelLayout: Layout = [];
|
||||
|
||||
onMount(() => {
|
||||
editor.subscriptions.subscribeJsMessage(UpdateDataPanelLayout, (data) => {
|
||||
editor.subscriptions.subscribeLayoutUpdate("DataPanel", (data) => {
|
||||
patchLayout(dataPanelLayout, data);
|
||||
dataPanelLayout = dataPanelLayout;
|
||||
});
|
||||
});
|
||||
|
||||
onDestroy(() => {
|
||||
editor.subscriptions.unsubscribeJsMessage(UpdateDataPanelLayout);
|
||||
editor.subscriptions.unsubscribeLayoutUpdate("DataPanel");
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@@ -2,33 +2,15 @@
|
||||
import { getContext, onMount, onDestroy, tick } from "svelte";
|
||||
|
||||
import type { Editor } from "@graphite/editor";
|
||||
import {
|
||||
type MenuDirection,
|
||||
type MouseCursorIcon,
|
||||
type XY,
|
||||
type Color,
|
||||
isColor,
|
||||
createColor,
|
||||
colorToHexOptionalAlpha,
|
||||
DisplayEditableTextbox,
|
||||
DisplayEditableTextboxUpdateFontData,
|
||||
DisplayEditableTextboxTransform,
|
||||
DisplayRemoveEditableTextbox,
|
||||
TriggerTextCommit,
|
||||
UpdateDocumentArtwork,
|
||||
UpdateDocumentRulers,
|
||||
UpdateDocumentScrollbars,
|
||||
UpdateEyedropperSamplingState,
|
||||
UpdateGradientStopColorPickerPosition,
|
||||
UpdateMouseCursor,
|
||||
isWidgetSpanRow,
|
||||
} from "@graphite/messages";
|
||||
import type { Color, FrontendMessages, MenuDirection } from "@graphite/messages";
|
||||
import type { AppWindowState } from "@graphite/state-providers/app-window";
|
||||
import type { DocumentState } from "@graphite/state-providers/document";
|
||||
import { isColor, createColor } from "@graphite/utility-functions/colors";
|
||||
import { pasteFile } from "@graphite/utility-functions/files";
|
||||
import { textInputCleanup } from "@graphite/utility-functions/keyboard-entry";
|
||||
import { rasterizeSVGCanvas } from "@graphite/utility-functions/rasterization";
|
||||
import { setupViewportResizeObserver, cleanupViewportResizeObserver } from "@graphite/utility-functions/viewports";
|
||||
import { isWidgetSpanRow } from "@graphite/utility-functions/widgets";
|
||||
|
||||
import ColorPicker from "@graphite/components/floating-menus/ColorPicker.svelte";
|
||||
import EyedropperPreview, { ZOOM_WINDOW_DIMENSIONS } from "@graphite/components/floating-menus/EyedropperPreview.svelte";
|
||||
@@ -39,6 +21,8 @@
|
||||
import ScrollbarInput from "@graphite/components/widgets/inputs/ScrollbarInput.svelte";
|
||||
import WidgetLayout from "@graphite/components/widgets/WidgetLayout.svelte";
|
||||
|
||||
type DisplayEditableTextbox = FrontendMessages["DisplayEditableTextbox"];
|
||||
|
||||
let rulerHorizontal: RulerInput | undefined;
|
||||
let rulerVertical: RulerInput | undefined;
|
||||
let viewport: HTMLDivElement | undefined;
|
||||
@@ -54,12 +38,12 @@
|
||||
let textInputMatrix: number[];
|
||||
|
||||
// Scrollbars
|
||||
let scrollbarPos: XY = { x: 0.5, y: 0.5 };
|
||||
let scrollbarSize: XY = { x: 0.5, y: 0.5 };
|
||||
let scrollbarMultiplier: XY = { x: 0, y: 0 };
|
||||
let scrollbarPos = { x: 0.5, y: 0.5 };
|
||||
let scrollbarSize = { x: 0.5, y: 0.5 };
|
||||
let scrollbarMultiplier = { x: 0, y: 0 };
|
||||
|
||||
// Rulers
|
||||
let rulerOrigin: XY = { x: 0, y: 0 };
|
||||
let rulerOrigin = { x: 0, y: 0 };
|
||||
let rulerSpacing = 100;
|
||||
let rulerInterval = 100;
|
||||
let rulersVisible = true;
|
||||
@@ -227,7 +211,7 @@
|
||||
export async function updateEyedropperSamplingState(
|
||||
// `image` is currently only used for Vello renders
|
||||
image: ImageData | undefined,
|
||||
mousePosition: XY | undefined,
|
||||
mousePosition: [number, number] | undefined,
|
||||
colorPrimary: string,
|
||||
colorSecondary: string,
|
||||
): Promise<[number, number, number] | undefined> {
|
||||
@@ -239,8 +223,8 @@
|
||||
|
||||
if (canvasWidth === undefined || canvasHeight === undefined) return undefined;
|
||||
|
||||
cursorLeft = mousePosition.x;
|
||||
cursorTop = mousePosition.y;
|
||||
cursorLeft = mousePosition[0];
|
||||
cursorTop = mousePosition[1];
|
||||
|
||||
let preview = image;
|
||||
if (!preview) {
|
||||
@@ -262,8 +246,8 @@
|
||||
if (!rasterizedContext) return undefined;
|
||||
|
||||
preview = rasterizedContext.getImageData(
|
||||
mousePosition.x * dpiFactor - (ZOOM_WINDOW_DIMENSIONS - 1) / 2,
|
||||
mousePosition.y * dpiFactor - (ZOOM_WINDOW_DIMENSIONS - 1) / 2,
|
||||
mousePosition[0] * dpiFactor - (ZOOM_WINDOW_DIMENSIONS - 1) / 2,
|
||||
mousePosition[1] * dpiFactor - (ZOOM_WINDOW_DIMENSIONS - 1) / 2,
|
||||
ZOOM_WINDOW_DIMENSIONS,
|
||||
ZOOM_WINDOW_DIMENSIONS,
|
||||
);
|
||||
@@ -293,25 +277,41 @@
|
||||
}
|
||||
|
||||
// Update scrollbars and rulers
|
||||
export function updateDocumentScrollbars(position: XY, size: XY, multiplier: XY) {
|
||||
scrollbarPos = position;
|
||||
scrollbarSize = size;
|
||||
scrollbarMultiplier = multiplier;
|
||||
export function updateDocumentScrollbars(position: [number, number], size: [number, number], multiplier: [number, number]) {
|
||||
scrollbarPos = { x: position[0], y: position[1] };
|
||||
scrollbarSize = { x: size[0], y: size[1] };
|
||||
scrollbarMultiplier = { x: multiplier[0], y: multiplier[1] };
|
||||
}
|
||||
|
||||
export function updateDocumentRulers(origin: XY, spacing: number, interval: number, visible: boolean) {
|
||||
rulerOrigin = origin;
|
||||
export function updateDocumentRulers(origin: [number, number], spacing: number, interval: number, visible: boolean) {
|
||||
rulerOrigin = { x: origin[0], y: origin[1] };
|
||||
rulerSpacing = spacing;
|
||||
rulerInterval = interval;
|
||||
rulersVisible = visible;
|
||||
}
|
||||
|
||||
// Update mouse cursor icon
|
||||
export function updateMouseCursor(cursor: MouseCursorIcon) {
|
||||
let cursorString: string = cursor;
|
||||
export function updateMouseCursor(cursor: string) {
|
||||
const mouseCursorIconCSSNames: Record<string, string> = {
|
||||
Default: "default",
|
||||
Alias: "alias",
|
||||
None: "none",
|
||||
ZoomIn: "zoom-in",
|
||||
ZoomOut: "zoom-out",
|
||||
Grabbing: "grabbing",
|
||||
Crosshair: "crosshair",
|
||||
Text: "text",
|
||||
Move: "move",
|
||||
NSResize: "ns-resize",
|
||||
EWResize: "ew-resize",
|
||||
NESWResize: "nesw-resize",
|
||||
NWSEResize: "nwse-resize",
|
||||
Rotate: "custom-rotate",
|
||||
};
|
||||
let cursorString = mouseCursorIconCSSNames[cursor] || mouseCursorIconCSSNames["Alias"];
|
||||
|
||||
// This isn't very clean but it's good enough for now until we need more icons, then we can build something more robust (consider blob URLs)
|
||||
if (cursor === "custom-rotate") {
|
||||
if (cursor === "Rotate") {
|
||||
const svg = `
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" width="20" height="20">
|
||||
<path fill="none" stroke="black" stroke-width="2" d="M10,15.8c-3.2,0-5.8-2.6-5.8-5.8S6.8,4.2,10,4.2c0.999,0,1.999,0.273,2.877,0.771L11.7,7h5.8l-2.9-5l-1.013,1.746C12.5,3.125,11.271,2.8,10,2.8C6,2.8,2.8,6,2.8,10S6,17.2,10,17.2s7.2-3.2,7.2-7.2h-1.4C15.8,13.2,13.2,15.8,10,15.8z" />
|
||||
@@ -363,7 +363,7 @@
|
||||
textInput.style.height = height;
|
||||
textInput.style.lineHeight = `${data.lineHeightRatio}`;
|
||||
textInput.style.fontSize = `${data.fontSize}px`;
|
||||
textInput.style.color = colorToHexOptionalAlpha(data.color) || "transparent";
|
||||
textInput.style.color = data.color;
|
||||
textInput.style.textAlign = data.align;
|
||||
|
||||
textInput.oninput = () => {
|
||||
@@ -418,7 +418,7 @@
|
||||
// which provides pixel-perfect physical dimensions via devicePixelContentBoxSize
|
||||
}
|
||||
|
||||
function gradientStopPickerDirection(position: XY | undefined, viewport: HTMLDivElement | undefined): MenuDirection {
|
||||
function gradientStopPickerDirection(position: { x: number; y: number } | undefined, viewport: HTMLDivElement | undefined): MenuDirection {
|
||||
const picker = (gradientStopPicker?.div()?.querySelector("[data-floating-menu-content]") || undefined) as HTMLElement | undefined;
|
||||
if (!picker || !position || !viewport) return "Bottom";
|
||||
|
||||
@@ -448,12 +448,12 @@
|
||||
updatePixelRatio();
|
||||
|
||||
// Update rendered SVGs
|
||||
editor.subscriptions.subscribeJsMessage(UpdateDocumentArtwork, async (data) => {
|
||||
editor.subscriptions.subscribeFrontendMessage("UpdateDocumentArtwork", async (data) => {
|
||||
await tick();
|
||||
|
||||
updateDocumentArtwork(data.svg);
|
||||
});
|
||||
editor.subscriptions.subscribeJsMessage(UpdateEyedropperSamplingState, async (data) => {
|
||||
editor.subscriptions.subscribeFrontendMessage("UpdateEyedropperSamplingState", async (data) => {
|
||||
await tick();
|
||||
|
||||
const { image, mousePosition, primaryColor, secondaryColor, setColorChoice } = data;
|
||||
@@ -467,19 +467,19 @@
|
||||
});
|
||||
|
||||
// Gradient stop color picker
|
||||
editor.subscriptions.subscribeJsMessage(UpdateGradientStopColorPickerPosition, (data) => {
|
||||
editor.subscriptions.subscribeFrontendMessage("UpdateGradientStopColorPickerPosition", (data) => {
|
||||
gradientStopPickerColor = data.color;
|
||||
gradientStopPickerPosition = { x: data.x, y: data.y };
|
||||
});
|
||||
|
||||
// Update scrollbars and rulers
|
||||
editor.subscriptions.subscribeJsMessage(UpdateDocumentScrollbars, async (data) => {
|
||||
editor.subscriptions.subscribeFrontendMessage("UpdateDocumentScrollbars", async (data) => {
|
||||
await tick();
|
||||
|
||||
const { position, size, multiplier } = data;
|
||||
updateDocumentScrollbars(position, size, multiplier);
|
||||
});
|
||||
editor.subscriptions.subscribeJsMessage(UpdateDocumentRulers, async (data) => {
|
||||
editor.subscriptions.subscribeFrontendMessage("UpdateDocumentRulers", async (data) => {
|
||||
await tick();
|
||||
|
||||
const { origin, spacing, interval, visible } = data;
|
||||
@@ -487,25 +487,24 @@
|
||||
});
|
||||
|
||||
// Update mouse cursor icon
|
||||
editor.subscriptions.subscribeJsMessage(UpdateMouseCursor, async (data) => {
|
||||
editor.subscriptions.subscribeFrontendMessage("UpdateMouseCursor", async (data) => {
|
||||
await tick();
|
||||
|
||||
const { cursor } = data;
|
||||
updateMouseCursor(cursor);
|
||||
updateMouseCursor(data.cursor);
|
||||
});
|
||||
|
||||
// Text entry
|
||||
editor.subscriptions.subscribeJsMessage(TriggerTextCommit, async () => {
|
||||
editor.subscriptions.subscribeFrontendMessage("TriggerTextCommit", async () => {
|
||||
await tick();
|
||||
|
||||
triggerTextCommit();
|
||||
});
|
||||
editor.subscriptions.subscribeJsMessage(DisplayEditableTextbox, async (data) => {
|
||||
editor.subscriptions.subscribeFrontendMessage("DisplayEditableTextbox", async (data) => {
|
||||
await tick();
|
||||
|
||||
displayEditableTextbox(data);
|
||||
});
|
||||
editor.subscriptions.subscribeJsMessage(DisplayEditableTextboxUpdateFontData, async (data) => {
|
||||
editor.subscriptions.subscribeFrontendMessage("DisplayEditableTextboxUpdateFontData", async (data) => {
|
||||
await tick();
|
||||
|
||||
const fontData = new Uint8Array(data.fontData);
|
||||
@@ -514,10 +513,10 @@
|
||||
textInput.style.fontFamily = "text-font";
|
||||
}
|
||||
});
|
||||
editor.subscriptions.subscribeJsMessage(DisplayEditableTextboxTransform, async (data) => {
|
||||
editor.subscriptions.subscribeFrontendMessage("DisplayEditableTextboxTransform", async (data) => {
|
||||
textInputMatrix = data.transform;
|
||||
});
|
||||
editor.subscriptions.subscribeJsMessage(DisplayRemoveEditableTextbox, async () => {
|
||||
editor.subscriptions.subscribeFrontendMessage("DisplayRemoveEditableTextbox", async () => {
|
||||
await tick();
|
||||
|
||||
displayRemoveEditableTextbox();
|
||||
|
||||
@@ -3,19 +3,12 @@
|
||||
import { SvelteMap } from "svelte/reactivity";
|
||||
|
||||
import type { Editor } from "@graphite/editor";
|
||||
import {
|
||||
patchLayout,
|
||||
UpdateDocumentLayerDetails,
|
||||
UpdateDocumentLayerStructure,
|
||||
UpdateLayersPanelControlBarLeftLayout,
|
||||
UpdateLayersPanelControlBarRightLayout,
|
||||
UpdateLayersPanelBottomBarLayout,
|
||||
} from "@graphite/messages";
|
||||
import type { LayerPanelEntry, LayerStructureEntry, Layout } from "@graphite/messages";
|
||||
import type { NodeGraphState } from "@graphite/state-providers/node-graph";
|
||||
import type { TooltipState } from "@graphite/state-providers/tooltip";
|
||||
import { pasteFile } from "@graphite/utility-functions/files";
|
||||
import { operatingSystem } from "@graphite/utility-functions/platform";
|
||||
import { patchLayout } from "@graphite/utility-functions/widgets";
|
||||
|
||||
import LayoutCol from "@graphite/components/layout/LayoutCol.svelte";
|
||||
import LayoutRow from "@graphite/components/layout/LayoutRow.svelte";
|
||||
@@ -76,26 +69,26 @@
|
||||
let layersPanelBottomBarLayout: Layout = [];
|
||||
|
||||
onMount(() => {
|
||||
editor.subscriptions.subscribeJsMessage(UpdateLayersPanelControlBarLeftLayout, (data) => {
|
||||
editor.subscriptions.subscribeLayoutUpdate("LayersPanelControlLeftBar", (data) => {
|
||||
patchLayout(layersPanelControlBarLeftLayout, data);
|
||||
layersPanelControlBarLeftLayout = layersPanelControlBarLeftLayout;
|
||||
});
|
||||
|
||||
editor.subscriptions.subscribeJsMessage(UpdateLayersPanelControlBarRightLayout, (data) => {
|
||||
editor.subscriptions.subscribeLayoutUpdate("LayersPanelControlRightBar", (data) => {
|
||||
patchLayout(layersPanelControlBarRightLayout, data);
|
||||
layersPanelControlBarRightLayout = layersPanelControlBarRightLayout;
|
||||
});
|
||||
|
||||
editor.subscriptions.subscribeJsMessage(UpdateLayersPanelBottomBarLayout, (data) => {
|
||||
editor.subscriptions.subscribeLayoutUpdate("LayersPanelBottomBar", (data) => {
|
||||
patchLayout(layersPanelBottomBarLayout, data);
|
||||
layersPanelBottomBarLayout = layersPanelBottomBarLayout;
|
||||
});
|
||||
|
||||
editor.subscriptions.subscribeJsMessage(UpdateDocumentLayerStructure, (data) => {
|
||||
editor.subscriptions.subscribeFrontendMessage("UpdateDocumentLayerStructure", (data) => {
|
||||
rebuildLayerHierarchy(data.layerStructure);
|
||||
});
|
||||
|
||||
editor.subscriptions.subscribeJsMessage(UpdateDocumentLayerDetails, (data) => {
|
||||
editor.subscriptions.subscribeFrontendMessage("UpdateDocumentLayerDetails", (data) => {
|
||||
const targetLayer = data.data;
|
||||
const targetId = targetLayer.id;
|
||||
|
||||
@@ -114,11 +107,11 @@
|
||||
});
|
||||
|
||||
onDestroy(() => {
|
||||
editor.subscriptions.unsubscribeJsMessage(UpdateLayersPanelControlBarLeftLayout);
|
||||
editor.subscriptions.unsubscribeJsMessage(UpdateLayersPanelControlBarRightLayout);
|
||||
editor.subscriptions.unsubscribeJsMessage(UpdateLayersPanelBottomBarLayout);
|
||||
editor.subscriptions.unsubscribeJsMessage(UpdateDocumentLayerStructure);
|
||||
editor.subscriptions.unsubscribeJsMessage(UpdateDocumentLayerDetails);
|
||||
editor.subscriptions.unsubscribeLayoutUpdate("LayersPanelControlLeftBar");
|
||||
editor.subscriptions.unsubscribeLayoutUpdate("LayersPanelControlRightBar");
|
||||
editor.subscriptions.unsubscribeLayoutUpdate("LayersPanelBottomBar");
|
||||
editor.subscriptions.unsubscribeFrontendMessage("UpdateDocumentLayerStructure");
|
||||
editor.subscriptions.unsubscribeFrontendMessage("UpdateDocumentLayerDetails");
|
||||
|
||||
removeEventListener("pointerup", draggingPointerUp);
|
||||
removeEventListener("pointermove", draggingPointerMove);
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
import { getContext, onMount, onDestroy } from "svelte";
|
||||
|
||||
import type { Editor } from "@graphite/editor";
|
||||
import { patchLayout, UpdatePropertiesPanelLayout, type Layout } from "@graphite/messages";
|
||||
import type { Layout } from "@graphite/messages";
|
||||
import { patchLayout } from "@graphite/utility-functions/widgets";
|
||||
|
||||
import LayoutCol from "@graphite/components/layout/LayoutCol.svelte";
|
||||
import WidgetLayout from "@graphite/components/widgets/WidgetLayout.svelte";
|
||||
@@ -12,14 +13,14 @@
|
||||
let propertiesPanelLayout: Layout = [];
|
||||
|
||||
onMount(() => {
|
||||
editor.subscriptions.subscribeJsMessage(UpdatePropertiesPanelLayout, (data) => {
|
||||
editor.subscriptions.subscribeLayoutUpdate("PropertiesPanel", (data) => {
|
||||
patchLayout(propertiesPanelLayout, data);
|
||||
propertiesPanelLayout = propertiesPanelLayout;
|
||||
});
|
||||
});
|
||||
|
||||
onDestroy(() => {
|
||||
editor.subscriptions.unsubscribeJsMessage(UpdatePropertiesPanelLayout);
|
||||
editor.subscriptions.unsubscribeLayoutUpdate("PropertiesPanel");
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
|
||||
import type { Editor } from "@graphite/editor";
|
||||
import type { Layout } from "@graphite/messages";
|
||||
import { patchLayout, UpdateWelcomeScreenButtonsLayout } from "@graphite/messages";
|
||||
import { pasteFile } from "@graphite/utility-functions/files";
|
||||
import { isDesktop } from "@graphite/utility-functions/platform";
|
||||
import { patchLayout } from "@graphite/utility-functions/widgets";
|
||||
|
||||
import LayoutCol from "@graphite/components/layout/LayoutCol.svelte";
|
||||
import LayoutRow from "@graphite/components/layout/LayoutRow.svelte";
|
||||
@@ -18,14 +18,14 @@
|
||||
let welcomePanelButtonsLayout: Layout = [];
|
||||
|
||||
onMount(() => {
|
||||
editor.subscriptions.subscribeJsMessage(UpdateWelcomeScreenButtonsLayout, (data) => {
|
||||
editor.subscriptions.subscribeLayoutUpdate("WelcomeScreenButtons", (data) => {
|
||||
patchLayout(welcomePanelButtonsLayout, data);
|
||||
welcomePanelButtonsLayout = welcomePanelButtonsLayout;
|
||||
});
|
||||
});
|
||||
|
||||
onDestroy(() => {
|
||||
editor.subscriptions.unsubscribeJsMessage(UpdateWelcomeScreenButtonsLayout);
|
||||
editor.subscriptions.unsubscribeLayoutUpdate("WelcomeScreenButtons");
|
||||
});
|
||||
|
||||
function dropFile(e: DragEvent) {
|
||||
|
||||
@@ -108,7 +108,7 @@
|
||||
function createNode(identifier: string) {
|
||||
if ($nodeGraph.contextMenuInformation === undefined) return;
|
||||
|
||||
editor.handle.createNode(identifier, $nodeGraph.contextMenuInformation.contextMenuCoordinates.x, $nodeGraph.contextMenuInformation.contextMenuCoordinates.y);
|
||||
editor.handle.createNode(identifier, $nodeGraph.contextMenuInformation.contextMenuCoordinates[0], $nodeGraph.contextMenuInformation.contextMenuCoordinates[1]);
|
||||
}
|
||||
|
||||
function nodeBorderMask(nodeWidth: number, primaryInputExists: boolean, exposedSecondaryInputs: number, primaryOutputExists: boolean, exposedSecondaryOutputs: number): string {
|
||||
@@ -203,8 +203,8 @@
|
||||
class="context-menu"
|
||||
data-context-menu
|
||||
styles={{
|
||||
left: `${$nodeGraph.contextMenuInformation.contextMenuCoordinates.x * $nodeGraph.transform.scale + $nodeGraph.transform.x}px`,
|
||||
top: `${$nodeGraph.contextMenuInformation.contextMenuCoordinates.y * $nodeGraph.transform.scale + $nodeGraph.transform.y}px`,
|
||||
left: `${$nodeGraph.contextMenuInformation.contextMenuCoordinates[0] * $nodeGraph.transform.scale + $nodeGraph.transform.x}px`,
|
||||
top: `${$nodeGraph.contextMenuInformation.contextMenuCoordinates[1] * $nodeGraph.transform.scale + $nodeGraph.transform.y}px`,
|
||||
}}
|
||||
open={true}
|
||||
type="Popover"
|
||||
@@ -257,10 +257,10 @@
|
||||
|
||||
{#if $nodeGraph.error}
|
||||
<div class="node-error-container" style:transform-origin="0 0" style:transform={`translate(${$nodeGraph.transform.x}px, ${$nodeGraph.transform.y}px) scale(${$nodeGraph.transform.scale})`}>
|
||||
<span class="node-error faded" style:left={`${$nodeGraph.error.position.x}px`} style:top={`${$nodeGraph.error.position.y}px`} transition:fade={FADE_TRANSITION}>
|
||||
<span class="node-error faded" style:left={`${$nodeGraph.error.position[0]}px`} style:top={`${$nodeGraph.error.position[1]}px`} transition:fade={FADE_TRANSITION}>
|
||||
{$nodeGraph.error.error}
|
||||
</span>
|
||||
<span class="node-error hover" style:left={`${$nodeGraph.error.position.x}px`} style:top={`${$nodeGraph.error.position.y}px`} transition:fade={FADE_TRANSITION}>
|
||||
<span class="node-error hover" style:left={`${$nodeGraph.error.position[0]}px`} style:top={`${$nodeGraph.error.position[1]}px`} transition:fade={FADE_TRANSITION}>
|
||||
{$nodeGraph.error.error}
|
||||
</span>
|
||||
</div>
|
||||
@@ -324,8 +324,8 @@
|
||||
data-datatype={frontendOutput.dataType}
|
||||
style:--data-color={`var(--color-data-${frontendOutput.dataType.toLowerCase()})`}
|
||||
style:--data-color-dim={`var(--color-data-${frontendOutput.dataType.toLowerCase()}-dim)`}
|
||||
style:--offset-left={($nodeGraph.updateImportsExports.importPosition.x - 8) / 24}
|
||||
style:--offset-top={($nodeGraph.updateImportsExports.importPosition.y - 8) / 24 + index}
|
||||
style:--offset-left={($nodeGraph.updateImportsExports.importPosition[0] - 8) / 24}
|
||||
style:--offset-top={($nodeGraph.updateImportsExports.importPosition[1] - 8) / 24 + index}
|
||||
>
|
||||
{#if frontendOutput.connectedTo.length > 0}
|
||||
<path d="M0,6.306A1.474,1.474,0,0,0,2.356,7.724L7.028,5.248c1.3-.687,1.3-1.809,0-2.5L2.356.276A1.474,1.474,0,0,0,0,1.694Z" fill="var(--data-color)" />
|
||||
@@ -340,8 +340,8 @@
|
||||
class="edit-import-export import"
|
||||
class:separator-bottom={index === 0 && $nodeGraph.updateImportsExports.addImportExport}
|
||||
class:separator-top={index === 1 && $nodeGraph.updateImportsExports.addImportExport}
|
||||
style:--offset-left={($nodeGraph.updateImportsExports.importPosition.x - 8) / 24}
|
||||
style:--offset-top={($nodeGraph.updateImportsExports.importPosition.y - 8) / 24 + index}
|
||||
style:--offset-left={($nodeGraph.updateImportsExports.importPosition[0] - 8) / 24}
|
||||
style:--offset-top={($nodeGraph.updateImportsExports.importPosition[1] - 8) / 24 + index}
|
||||
>
|
||||
{#if editingNameImportIndex === index}
|
||||
<input
|
||||
@@ -377,8 +377,8 @@
|
||||
{:else}
|
||||
<div
|
||||
class="plus"
|
||||
style:--offset-top={($nodeGraph.updateImportsExports.importPosition.y - 12) / 24}
|
||||
style:--offset-left={($nodeGraph.updateImportsExports.importPosition.x - 12) / 24}
|
||||
style:--offset-top={($nodeGraph.updateImportsExports.importPosition[1] - 12) / 24}
|
||||
style:--offset-left={($nodeGraph.updateImportsExports.importPosition[0] - 12) / 24}
|
||||
>
|
||||
<IconButton size={24} icon="Add" action={() => editor.handle.addPrimaryImport()} />
|
||||
</div>
|
||||
@@ -397,8 +397,8 @@
|
||||
data-datatype={frontendInput.dataType}
|
||||
style:--data-color={`var(--color-data-${frontendInput.dataType.toLowerCase()})`}
|
||||
style:--data-color-dim={`var(--color-data-${frontendInput.dataType.toLowerCase()}-dim)`}
|
||||
style:--offset-left={($nodeGraph.updateImportsExports.exportPosition.x - 8) / 24}
|
||||
style:--offset-top={($nodeGraph.updateImportsExports.exportPosition.y - 8) / 24 + index}
|
||||
style:--offset-left={($nodeGraph.updateImportsExports.exportPosition[0] - 8) / 24}
|
||||
style:--offset-top={($nodeGraph.updateImportsExports.exportPosition[1] - 8) / 24 + index}
|
||||
>
|
||||
{#if frontendInput.connectedTo !== "Connected to nothing."}
|
||||
<path d="M0,6.306A1.474,1.474,0,0,0,2.356,7.724L7.028,5.248c1.3-.687,1.3-1.809,0-2.5L2.356.276A1.474,1.474,0,0,0,0,1.694Z" fill="var(--data-color)" />
|
||||
@@ -412,8 +412,8 @@
|
||||
class="edit-import-export export"
|
||||
class:separator-bottom={index === 0 && $nodeGraph.updateImportsExports.addImportExport}
|
||||
class:separator-top={index === 1 && $nodeGraph.updateImportsExports.addImportExport}
|
||||
style:--offset-left={($nodeGraph.updateImportsExports.exportPosition.x - 8) / 24}
|
||||
style:--offset-top={($nodeGraph.updateImportsExports.exportPosition.y - 8) / 24 + index}
|
||||
style:--offset-left={($nodeGraph.updateImportsExports.exportPosition[0] - 8) / 24}
|
||||
style:--offset-top={($nodeGraph.updateImportsExports.exportPosition[1] - 8) / 24 + index}
|
||||
>
|
||||
{#if (hoveringExportIndex === index || editingNameExportIndex === index) && $nodeGraph.updateImportsExports.addImportExport}
|
||||
{#if index > 0}
|
||||
@@ -448,8 +448,8 @@
|
||||
{:else}
|
||||
<div
|
||||
class="plus"
|
||||
style:--offset-left={($nodeGraph.updateImportsExports.exportPosition.x - 12) / 24}
|
||||
style:--offset-top={($nodeGraph.updateImportsExports.exportPosition.y - 12) / 24}
|
||||
style:--offset-left={($nodeGraph.updateImportsExports.exportPosition[0] - 12) / 24}
|
||||
style:--offset-top={($nodeGraph.updateImportsExports.exportPosition[1] - 12) / 24}
|
||||
>
|
||||
<IconButton size={24} icon="Add" action={() => editor.handle.addPrimaryExport()} />
|
||||
</div>
|
||||
@@ -459,15 +459,15 @@
|
||||
{#if $nodeGraph.updateImportsExports.addImportExport}
|
||||
<div
|
||||
class="plus"
|
||||
style:--offset-left={($nodeGraph.updateImportsExports.importPosition.x - 12) / 24}
|
||||
style:--offset-top={($nodeGraph.updateImportsExports.importPosition.y - 12) / 24 + $nodeGraph.updateImportsExports.imports.length}
|
||||
style:--offset-left={($nodeGraph.updateImportsExports.importPosition[0] - 12) / 24}
|
||||
style:--offset-top={($nodeGraph.updateImportsExports.importPosition[1] - 12) / 24 + $nodeGraph.updateImportsExports.imports.length}
|
||||
>
|
||||
<IconButton size={24} icon="Add" action={() => editor.handle.addSecondaryImport()} />
|
||||
</div>
|
||||
<div
|
||||
class="plus"
|
||||
style:--offset-left={($nodeGraph.updateImportsExports.exportPosition.x - 12) / 24}
|
||||
style:--offset-top={($nodeGraph.updateImportsExports.exportPosition.y - 12) / 24 + $nodeGraph.updateImportsExports.exports.length}
|
||||
style:--offset-left={($nodeGraph.updateImportsExports.exportPosition[0] - 12) / 24}
|
||||
style:--offset-top={($nodeGraph.updateImportsExports.exportPosition[1] - 12) / 24 + $nodeGraph.updateImportsExports.exports.length}
|
||||
>
|
||||
<IconButton size={24} icon="Add" action={() => editor.handle.addSecondaryExport()} />
|
||||
</div>
|
||||
@@ -475,16 +475,16 @@
|
||||
|
||||
{#if $nodeGraph.reorderImportIndex !== undefined}
|
||||
{@const position = {
|
||||
x: Number($nodeGraph.updateImportsExports.importPosition.x),
|
||||
y: Number($nodeGraph.updateImportsExports.importPosition.y) + Number($nodeGraph.reorderImportIndex) * 24,
|
||||
x: Number($nodeGraph.updateImportsExports.importPosition[0]),
|
||||
y: Number($nodeGraph.updateImportsExports.importPosition[1]) + Number($nodeGraph.reorderImportIndex) * 24,
|
||||
}}
|
||||
<div class="reorder-bar" style:--offset-left={(position.x - 48) / 24} style:--offset-top={(position.y - 12) / 24}></div>
|
||||
{/if}
|
||||
|
||||
{#if $nodeGraph.reorderExportIndex !== undefined}
|
||||
{@const position = {
|
||||
x: Number($nodeGraph.updateImportsExports.exportPosition.x),
|
||||
y: Number($nodeGraph.updateImportsExports.exportPosition.y) + Number($nodeGraph.reorderExportIndex) * 24,
|
||||
x: Number($nodeGraph.updateImportsExports.exportPosition[0]),
|
||||
y: Number($nodeGraph.updateImportsExports.exportPosition[1]) + Number($nodeGraph.reorderExportIndex) * 24,
|
||||
}}
|
||||
<div class="reorder-bar" style:--offset-left={position.x / 24} style:--offset-top={(position.y - 12) / 24}></div>
|
||||
{/if}
|
||||
@@ -510,8 +510,8 @@
|
||||
class:previewed={node.previewed}
|
||||
class:disabled={!node.visible}
|
||||
class:locked={node.locked}
|
||||
style:--offset-left={node.position?.x || 0}
|
||||
style:--offset-top={node.position?.y || 0}
|
||||
style:--offset-left={node.position?.[0] || 0}
|
||||
style:--offset-top={node.position?.[1] || 0}
|
||||
style:--clip-path-id={`url(#${clipPathId})`}
|
||||
style:--data-color={`var(--color-data-${(node.primaryOutput?.dataType || "General").toLowerCase()})`}
|
||||
style:--data-color-dim={`var(--color-data-${(node.primaryOutput?.dataType || "General").toLowerCase()}-dim)`}
|
||||
@@ -519,7 +519,7 @@
|
||||
style:--node-chain-area-left-extension={layerChainWidth !== 0 ? layerChainWidth + 0.5 : 0}
|
||||
data-tooltip-label={nodeNameTooltipLabel(node)}
|
||||
data-tooltip-description={`
|
||||
${(description || "").trim()}${editor.handle.inDevelopmentMode() ? `\n\nID: ${node.id}. Position: (${node.position.x}, ${node.position.y}).` : ""}
|
||||
${(description || "").trim()}${editor.handle.inDevelopmentMode() ? `\n\nID: ${node.id}. Position: (${node.position[0]}, ${node.position[1]}).` : ""}
|
||||
`.trim()}
|
||||
data-node={node.id}
|
||||
>
|
||||
@@ -675,14 +675,14 @@
|
||||
class:selected={$nodeGraph.selected.includes(node.id)}
|
||||
class:previewed={node.previewed}
|
||||
class:disabled={!node.visible}
|
||||
style:--offset-left={node.position?.x || 0}
|
||||
style:--offset-top={node.position?.y || 0}
|
||||
style:--offset-left={node.position?.[0] || 0}
|
||||
style:--offset-top={node.position?.[1] || 0}
|
||||
style:--clip-path-id={`url(#${clipPathId})`}
|
||||
style:--data-color={`var(--color-data-${(node.primaryOutput?.dataType || "General").toLowerCase()})`}
|
||||
style:--data-color-dim={`var(--color-data-${(node.primaryOutput?.dataType || "General").toLowerCase()}-dim)`}
|
||||
data-tooltip-label={nodeNameTooltipLabel(node)}
|
||||
data-tooltip-description={`
|
||||
${(description || "").trim()}${editor.handle.inDevelopmentMode() ? `\n\nID: ${node.id}. Position: (${node.position.x}, ${node.position.y}).` : ""}
|
||||
${(description || "").trim()}${editor.handle.inDevelopmentMode() ? `\n\nID: ${node.id}. Position: (${node.position[0]}, ${node.position[1]}).` : ""}
|
||||
`.trim()}
|
||||
data-node={node.id}
|
||||
>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { isWidgetSpanColumn, isWidgetSpanRow, isWidgetSection, type Layout, isWidgetTable, type LayoutTarget } from "@graphite/messages";
|
||||
import type { Layout, LayoutTarget } from "@graphite/messages";
|
||||
import { isWidgetSpanColumn, isWidgetSpanRow, isWidgetTable, isWidgetSection } from "@graphite/utility-functions/widgets";
|
||||
|
||||
import WidgetSection from "@graphite/components/widgets/WidgetSection.svelte";
|
||||
import WidgetSpan from "@graphite/components/widgets/WidgetSpan.svelte";
|
||||
|
||||
@@ -2,14 +2,15 @@
|
||||
import { getContext } from "svelte";
|
||||
|
||||
import type { Editor } from "@graphite/editor";
|
||||
import { isWidgetSpanRow, isWidgetSection, type WidgetSection as WidgetSectionFromJsMessages, type LayoutTarget } from "@graphite/messages";
|
||||
import type { WidgetSection as WidgetSectionData, LayoutTarget } from "@graphite/messages";
|
||||
import { isWidgetSpanRow, isWidgetSection } from "@graphite/utility-functions/widgets";
|
||||
|
||||
import LayoutCol from "@graphite/components/layout/LayoutCol.svelte";
|
||||
import IconButton from "@graphite/components/widgets/buttons/IconButton.svelte";
|
||||
import TextLabel from "@graphite/components/widgets/labels/TextLabel.svelte";
|
||||
import WidgetSpan from "@graphite/components/widgets/WidgetSpan.svelte";
|
||||
|
||||
export let widgetData: WidgetSectionFromJsMessages;
|
||||
export let widgetData: WidgetSectionData;
|
||||
export let layoutTarget: LayoutTarget;
|
||||
|
||||
let className = "";
|
||||
|
||||
@@ -3,8 +3,9 @@
|
||||
|
||||
import type { Editor } from "@graphite/editor";
|
||||
import type { LayoutTarget, WidgetInstance, WidgetPropsNames, WidgetPropsSet, WidgetTypes, WidgetSpanColumn, WidgetSpanRow } from "@graphite/messages";
|
||||
import { isWidgetSpanColumn, isWidgetSpanRow } from "@graphite/messages";
|
||||
import { parseFillChoice } from "@graphite/utility-functions/colors";
|
||||
import { debouncer } from "@graphite/utility-functions/debounce";
|
||||
import { isWidgetSpanColumn, isWidgetSpanRow, createLayoutGroup } from "@graphite/utility-functions/widgets";
|
||||
|
||||
import NodeCatalog from "@graphite/components/floating-menus/NodeCatalog.svelte";
|
||||
import BreadcrumbTrailButtons from "@graphite/components/widgets/buttons/BreadcrumbTrailButtons.svelte";
|
||||
@@ -97,6 +98,7 @@
|
||||
component: ColorInput,
|
||||
getProps: (props: WidgetTypes["ColorInput"], index) => ({
|
||||
...exclude(props),
|
||||
value: parseFillChoice(props.value),
|
||||
$$events: {
|
||||
value: (e: CustomEvent) => widgetValueUpdate(index, e.detail, false),
|
||||
startHistoryTransaction: () => widgetValueCommit(index, props.value),
|
||||
@@ -191,6 +193,7 @@
|
||||
getProps: (props: WidgetTypes["PopoverButton"]) => ({
|
||||
...exclude(props),
|
||||
layoutTarget,
|
||||
popoverLayout: props.popoverLayout.map(createLayoutGroup),
|
||||
}),
|
||||
},
|
||||
RadioInput: {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<script lang="ts">
|
||||
import { type LayoutTarget, type WidgetTable as WidgetTableFromJsMessages } from "@graphite/messages";
|
||||
import type { LayoutTarget, WidgetTable as WidgetTableData } from "@graphite/messages";
|
||||
|
||||
import WidgetSpan from "@graphite/components/widgets/WidgetSpan.svelte";
|
||||
|
||||
export let widgetData: WidgetTableFromJsMessages;
|
||||
export let widgetData: WidgetTableData;
|
||||
export let layoutTarget: LayoutTarget;
|
||||
export let unstyled = false;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { type IconName, type IconSize } from "@graphite/icons";
|
||||
import type { IconName, IconSize } from "@graphite/icons";
|
||||
import type { ActionShortcut } from "@graphite/messages";
|
||||
|
||||
import IconLabel from "@graphite/components/widgets/labels/IconLabel.svelte";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { type IconName, type PopoverButtonStyle } from "@graphite/icons";
|
||||
import type { IconName, PopoverButtonStyle } from "@graphite/icons";
|
||||
|
||||
import type { MenuDirection, ActionShortcut, Layout, LayoutTarget } from "@graphite/messages";
|
||||
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
import { createEventDispatcher } from "svelte";
|
||||
|
||||
import type { FillChoice, MenuDirection, ActionShortcut } from "@graphite/messages";
|
||||
import { type Color, contrastingOutlineFactor, isColor, isGradient, colorToHexOptionalAlpha, gradientToLinearGradientCSS } from "@graphite/messages";
|
||||
import type { Color } from "@graphite/messages";
|
||||
import { contrastingOutlineFactor, isColor, isGradient, colorToHexOptionalAlpha, gradientToLinearGradientCSS } from "@graphite/utility-functions/colors";
|
||||
|
||||
import ColorPicker from "@graphite/components/floating-menus/ColorPicker.svelte";
|
||||
import LayoutCol from "@graphite/components/layout/LayoutCol.svelte";
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { createEventDispatcher } from "svelte";
|
||||
|
||||
import { type RadioEntryData } from "@graphite/messages";
|
||||
import type { RadioEntryData } from "@graphite/messages";
|
||||
|
||||
import LayoutRow from "@graphite/components/layout/LayoutRow.svelte";
|
||||
import IconLabel from "@graphite/components/widgets/labels/IconLabel.svelte";
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
import { createEventDispatcher, onDestroy } from "svelte";
|
||||
|
||||
import { evaluateGradientAtPosition } from "@graphite/../wasm/pkg/graphite_wasm";
|
||||
import { type Color, type Gradient, createColor, colorToHexOptionalAlpha, colorToRgbCSS, gradientFirstColor, gradientLastColor, gradientToLinearGradientCSS } from "@graphite/messages";
|
||||
import type { Color, Gradient } from "@graphite/messages";
|
||||
import { createColor, colorToHexOptionalAlpha, colorToRgbCSS, gradientFirstColor, gradientLastColor, gradientToLinearGradientCSS } from "@graphite/utility-functions/colors";
|
||||
|
||||
import { preventEscapeClosingParentFloatingMenu } from "@graphite/components/layout/FloatingMenu.svelte";
|
||||
import LayoutCol from "@graphite/components/layout/LayoutCol.svelte";
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
import { getContext } from "svelte";
|
||||
|
||||
import type { Editor } from "@graphite/editor";
|
||||
import { type Color, isColor, colorToRgbaCSS } from "@graphite/messages";
|
||||
import type { Color } from "@graphite/messages";
|
||||
import { isColor, colorToRgbaCSS } from "@graphite/utility-functions/colors";
|
||||
|
||||
import ColorPicker from "@graphite/components/floating-menus/ColorPicker.svelte";
|
||||
import LayoutCol from "@graphite/components/layout/LayoutCol.svelte";
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { type IconName, ICONS, ICON_SVG_STRINGS } from "@graphite/icons";
|
||||
import { ICONS, ICON_SVG_STRINGS } from "@graphite/icons";
|
||||
import type { IconName } from "@graphite/icons";
|
||||
import type { ActionShortcut } from "@graphite/messages";
|
||||
|
||||
import LayoutRow from "@graphite/components/layout/LayoutRow.svelte";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { type SeparatorDirection, type SeparatorStyle } from "@graphite/messages";
|
||||
import type { SeparatorDirection, SeparatorStyle } from "@graphite/messages";
|
||||
|
||||
// Content
|
||||
export let direction: SeparatorDirection = "Horizontal";
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
import type { Editor } from "@graphite/editor";
|
||||
import type { Layout } from "@graphite/messages";
|
||||
import { patchLayout, UpdateStatusBarHintsLayout, UpdateStatusBarInfoLayout } from "@graphite/messages";
|
||||
import { patchLayout } from "@graphite/utility-functions/widgets";
|
||||
|
||||
import LayoutRow from "@graphite/components/layout/LayoutRow.svelte";
|
||||
import Separator from "@graphite/components/widgets/labels/Separator.svelte";
|
||||
@@ -15,11 +15,11 @@
|
||||
let statusBarInfoLayout: Layout = [];
|
||||
|
||||
onMount(() => {
|
||||
editor.subscriptions.subscribeJsMessage(UpdateStatusBarHintsLayout, (data) => {
|
||||
editor.subscriptions.subscribeLayoutUpdate("StatusBarHints", (data) => {
|
||||
patchLayout(statusBarHintsLayout, data);
|
||||
statusBarHintsLayout = statusBarHintsLayout;
|
||||
});
|
||||
editor.subscriptions.subscribeJsMessage(UpdateStatusBarInfoLayout, (data) => {
|
||||
editor.subscriptions.subscribeLayoutUpdate("StatusBarInfo", (data) => {
|
||||
patchLayout(statusBarInfoLayout, data);
|
||||
statusBarInfoLayout = statusBarInfoLayout;
|
||||
});
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
|
||||
import type { Editor } from "@graphite/editor";
|
||||
import type { Layout } from "@graphite/messages";
|
||||
import { patchLayout, UpdateMenuBarLayout } from "@graphite/messages";
|
||||
import type { AppWindowState } from "@graphite/state-providers/app-window";
|
||||
import type { FullscreenState } from "@graphite/state-providers/fullscreen";
|
||||
import type { TooltipState } from "@graphite/state-providers/tooltip";
|
||||
import { patchLayout } from "@graphite/utility-functions/widgets";
|
||||
|
||||
import LayoutRow from "@graphite/components/layout/LayoutRow.svelte";
|
||||
import IconLabel from "@graphite/components/widgets/labels/IconLabel.svelte";
|
||||
@@ -26,7 +26,7 @@
|
||||
$: height = $appWindow.platform === "Mac" ? 28 * (1 / $appWindow.uiScale) : 28;
|
||||
|
||||
onMount(() => {
|
||||
editor.subscriptions.subscribeJsMessage(UpdateMenuBarLayout, (data) => {
|
||||
editor.subscriptions.subscribeLayoutUpdate("MenuBar", (data) => {
|
||||
patchLayout(menuBarLayout, data);
|
||||
menuBarLayout = menuBarLayout;
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user