Clean up code with better naming

This commit is contained in:
Keavon Chambers 2025-12-21 23:32:22 -08:00
parent f705d0080d
commit 64ed21f694
25 changed files with 163 additions and 171 deletions

View File

@ -213,7 +213,7 @@ pub fn path_endpoint_overlays(document: &DocumentMessageHandler, shape_editor: &
let selected = shape_editor.selected_shape_state.get(&layer); let selected = shape_editor.selected_shape_state.get(&layer);
let is_selected = |selected: Option<&SelectedLayerState>, point: ManipulatorPointId| selected.is_some_and(|selected| selected.is_point_selected(point)); let is_selected = |selected: Option<&SelectedLayerState>, point: ManipulatorPointId| selected.is_some_and(|selected| selected.is_point_selected(point));
for point in vector.extendable_points() { for point in vector.anchor_points() {
let Some(position) = vector.point_domain.position_from_id(point) else { continue }; let Some(position) = vector.point_domain.position_from_id(point) else { continue };
let position = transform.transform_point2(position); let position = transform.transform_point2(position);
overlay_context.manipulator_anchor(position, is_selected(selected, ManipulatorPointId::Anchor(point)), None); overlay_context.manipulator_anchor(position, is_selected(selected, ManipulatorPointId::Anchor(point)), None);

View File

@ -43,7 +43,7 @@ where
for layer in layers { for layer in layers {
let viewspace = document.metadata().transform_to_viewport(layer); let viewspace = document.metadata().transform_to_viewport(layer);
let Some(vector) = document.network_interface.compute_modified_vector(layer) else { continue }; let Some(vector) = document.network_interface.compute_modified_vector(layer) else { continue };
for id in vector.extendable_points() { for id in vector.anchor_points() {
if exclude(id) { if exclude(id) {
continue; continue;
} }

View File

@ -518,10 +518,10 @@ mod test_freehand {
initial_segment_count initial_segment_count
); );
let extendable_points = initial_vector.extendable_points().collect::<Vec<_>>(); let endpoints = initial_vector.anchor_endpoints().collect::<Vec<_>>();
assert!(!extendable_points.is_empty(), "No extendable points found in the path"); assert!(!endpoints.is_empty(), "No extendable points found in the path");
let endpoint_id = extendable_points[0]; let endpoint_id = endpoints[0];
let endpoint_pos_option = initial_vector.point_domain.position_from_id(endpoint_id); let endpoint_pos_option = initial_vector.point_domain.position_from_id(endpoint_id);
assert!(endpoint_pos_option.is_some(), "Could not find position for endpoint"); assert!(endpoint_pos_option.is_some(), "Could not find position for endpoint");

View File

@ -823,7 +823,7 @@ impl PathToolData {
.filter(|handle| handle.length(&vector) < 1e-6) .filter(|handle| handle.length(&vector) < 1e-6)
.map(|handle| handle.to_manipulator_point()) .map(|handle| handle.to_manipulator_point())
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let endpoint = vector.extendable_points_no_vector_meshes().any(|anchor| point == anchor); let endpoint = vector.anchor_endpoints().any(|anchor| point == anchor);
if drag_zero_handle && (handles.len() == 1 && !endpoint) { if drag_zero_handle && (handles.len() == 1 && !endpoint) {
shape_editor.deselect_all_points(); shape_editor.deselect_all_points();

View File

@ -652,7 +652,7 @@ impl PenToolData {
} }
fn close_path_on_point(&mut self, snap_data: SnapData, vector: &Vector, document: &DocumentMessageHandler, id: PointId, transform: &DAffine2) -> bool { fn close_path_on_point(&mut self, snap_data: SnapData, vector: &Vector, document: &DocumentMessageHandler, id: PointId, transform: &DAffine2) -> bool {
for id in vector.extendable_points().filter(|&point| point != id) { for id in vector.anchor_points().filter(|&point| point != id) {
let Some(pos) = vector.point_domain.position_from_id(id) else { continue }; let Some(pos) = vector.point_domain.position_from_id(id) else { continue };
let transformed_distance_between_squared = transform.transform_point2(pos).distance_squared(transform.transform_point2(self.next_point)); let transformed_distance_between_squared = transform.transform_point2(pos).distance_squared(transform.transform_point2(self.next_point));
let snap_point_tolerance_squared = crate::consts::SNAP_POINT_TOLERANCE.powi(2); let snap_point_tolerance_squared = crate::consts::SNAP_POINT_TOLERANCE.powi(2);
@ -701,7 +701,7 @@ impl PenToolData {
let vector = document.network_interface.compute_modified_vector(layer)?; let vector = document.network_interface.compute_modified_vector(layer)?;
let start = self.latest_point()?.id; let start = self.latest_point()?.id;
let transform = document.metadata().document_to_viewport * transform; let transform = document.metadata().document_to_viewport * transform;
for id in vector.extendable_points().filter(|&point| point != start) { for id in vector.anchor_points().filter(|&point| point != start) {
let Some(pos) = vector.point_domain.position_from_id(id) else { continue }; let Some(pos) = vector.point_domain.position_from_id(id) else { continue };
let transformed_distance_between_squared = transform.transform_point2(pos).distance_squared(transform.transform_point2(next_point)); let transformed_distance_between_squared = transform.transform_point2(pos).distance_squared(transform.transform_point2(next_point));
let snap_point_tolerance_squared = crate::consts::SNAP_POINT_TOLERANCE.powi(2); let snap_point_tolerance_squared = crate::consts::SNAP_POINT_TOLERANCE.powi(2);
@ -1126,7 +1126,7 @@ impl PenToolData {
let layer = selected_layers.next().filter(|_| selected_layers.next().is_none()).or(self.current_layer)?; let layer = selected_layers.next().filter(|_| selected_layers.next().is_none()).or(self.current_layer)?;
let vector = document.network_interface.compute_modified_vector(layer)?; let vector = document.network_interface.compute_modified_vector(layer)?;
let transform = document.metadata().document_to_viewport * transform; let transform = document.metadata().document_to_viewport * transform;
for point in vector.extendable_points() { for point in vector.anchor_points() {
let Some(pos) = vector.point_domain.position_from_id(point) else { continue }; let Some(pos) = vector.point_domain.position_from_id(point) else { continue };
let transformed_distance_between_squared = transform.transform_point2(pos).distance_squared(transform.transform_point2(self.next_point)); let transformed_distance_between_squared = transform.transform_point2(pos).distance_squared(transform.transform_point2(self.next_point));
let snap_point_tolerance_squared = crate::consts::SNAP_POINT_TOLERANCE.powi(2); let snap_point_tolerance_squared = crate::consts::SNAP_POINT_TOLERANCE.powi(2);
@ -1755,7 +1755,7 @@ impl Fsm for PenToolFsmState {
if let Some(layer) = layer if let Some(layer) = layer
&& let Some(mut vector) = document.network_interface.compute_modified_vector(layer) && let Some(mut vector) = document.network_interface.compute_modified_vector(layer)
{ {
let closest_point = vector.extendable_points().filter(|&id| id != start).find(|&id| { let closest_point = vector.anchor_points().filter(|&id| id != start).find(|&id| {
vector.point_domain.position_from_id(id).is_some_and(|pos| { vector.point_domain.position_from_id(id).is_some_and(|pos| {
let dist_sq = transform.transform_point2(pos).distance_squared(transform.transform_point2(next_point)); let dist_sq = transform.transform_point2(pos).distance_squared(transform.transform_point2(next_point));
dist_sq < crate::consts::SNAP_POINT_TOLERANCE.powi(2) dist_sq < crate::consts::SNAP_POINT_TOLERANCE.powi(2)

View File

@ -646,7 +646,7 @@ mod test_spline_tool {
let layer_to_viewport = document.metadata().transform_to_viewport(spline_layer); let layer_to_viewport = document.metadata().transform_to_viewport(spline_layer);
let endpoints: Vec<(PointId, DVec2)> = first_vector let endpoints: Vec<(PointId, DVec2)> = first_vector
.extendable_points_no_vector_meshes() .anchor_endpoints()
.filter_map(|point_id| first_vector.point_domain.position_from_id(point_id).map(|pos| (point_id, layer_to_viewport.transform_point2(pos)))) .filter_map(|point_id| first_vector.point_domain.position_from_id(point_id).map(|pos| (point_id, layer_to_viewport.transform_point2(pos))))
.collect(); .collect();

View File

@ -12,8 +12,8 @@
let dataPanelLayout: Layout = []; let dataPanelLayout: Layout = [];
onMount(() => { onMount(() => {
editor.subscriptions.subscribeJsMessage(UpdateDataPanelLayout, (updateDataPanelLayout) => { editor.subscriptions.subscribeJsMessage(UpdateDataPanelLayout, (data) => {
patchLayout(dataPanelLayout, updateDataPanelLayout); patchLayout(dataPanelLayout, data);
dataPanelLayout = dataPanelLayout; dataPanelLayout = dataPanelLayout;
}); });
}); });

View File

@ -332,7 +332,7 @@
editor.handle.onChangeText(textCleaned, false); editor.handle.onChangeText(textCleaned, false);
} }
export async function displayEditableTextbox(displayEditableTextbox: DisplayEditableTextbox) { export async function displayEditableTextbox(data: DisplayEditableTextbox) {
showTextInput = true; showTextInput = true;
await tick(); await tick();
@ -340,33 +340,33 @@
if (!textInput) return; if (!textInput) return;
// eslint-disable-next-line svelte/no-dom-manipulating // eslint-disable-next-line svelte/no-dom-manipulating
if (displayEditableTextbox.text === "") textInput.textContent = ""; if (data.text === "") textInput.textContent = "";
// eslint-disable-next-line svelte/no-dom-manipulating // eslint-disable-next-line svelte/no-dom-manipulating
else textInput.textContent = `${displayEditableTextbox.text}\n`; else textInput.textContent = `${data.text}\n`;
// Make it so `maxHeight` is a multiple of `lineHeight` // Make it so `maxHeight` is a multiple of `lineHeight`
const lineHeight = displayEditableTextbox.lineHeightRatio * displayEditableTextbox.fontSize; const lineHeight = data.lineHeightRatio * data.fontSize;
let height = displayEditableTextbox.maxHeight === undefined ? "auto" : `${Math.floor(displayEditableTextbox.maxHeight / lineHeight) * lineHeight}px`; let height = data.maxHeight === undefined ? "auto" : `${Math.floor(data.maxHeight / lineHeight) * lineHeight}px`;
textInput.contentEditable = "true"; textInput.contentEditable = "true";
textInput.style.transformOrigin = "0 0"; textInput.style.transformOrigin = "0 0";
textInput.style.width = displayEditableTextbox.maxWidth ? `${displayEditableTextbox.maxWidth}px` : "max-content"; textInput.style.width = data.maxWidth ? `${data.maxWidth}px` : "max-content";
textInput.style.height = height; textInput.style.height = height;
textInput.style.lineHeight = `${displayEditableTextbox.lineHeightRatio}`; textInput.style.lineHeight = `${data.lineHeightRatio}`;
textInput.style.fontSize = `${displayEditableTextbox.fontSize}px`; textInput.style.fontSize = `${data.fontSize}px`;
textInput.style.color = displayEditableTextbox.color.toHexOptionalAlpha() || "transparent"; textInput.style.color = data.color.toHexOptionalAlpha() || "transparent";
textInput.style.textAlign = displayEditableTextbox.align; textInput.style.textAlign = data.align;
textInput.oninput = () => { textInput.oninput = () => {
if (!textInput) return; if (!textInput) return;
editor.handle.updateBounds(textInputCleanup(textInput.innerText)); editor.handle.updateBounds(textInputCleanup(textInput.innerText));
}; };
textInputMatrix = displayEditableTextbox.transform; textInputMatrix = data.transform;
const data = new Uint8Array(displayEditableTextbox.fontData); const bytes = new Uint8Array(data.fontData);
if (data.length > 0) { if (bytes.length > 0) {
window.document.fonts.add(new FontFace("text-font", data)); window.document.fonts.add(new FontFace("text-font", bytes));
textInput.style.fontFamily = "text-font"; textInput.style.fontFamily = "text-font";
} }

View File

@ -75,28 +75,28 @@
let layersPanelBottomBarLayout: Layout = []; let layersPanelBottomBarLayout: Layout = [];
onMount(() => { onMount(() => {
editor.subscriptions.subscribeJsMessage(UpdateLayersPanelControlBarLeftLayout, (updateLayersPanelControlBarLeftLayout) => { editor.subscriptions.subscribeJsMessage(UpdateLayersPanelControlBarLeftLayout, (data) => {
patchLayout(layersPanelControlBarLeftLayout, updateLayersPanelControlBarLeftLayout); patchLayout(layersPanelControlBarLeftLayout, data);
layersPanelControlBarLeftLayout = layersPanelControlBarLeftLayout; layersPanelControlBarLeftLayout = layersPanelControlBarLeftLayout;
}); });
editor.subscriptions.subscribeJsMessage(UpdateLayersPanelControlBarRightLayout, (updateLayersPanelControlBarRightLayout) => { editor.subscriptions.subscribeJsMessage(UpdateLayersPanelControlBarRightLayout, (data) => {
patchLayout(layersPanelControlBarRightLayout, updateLayersPanelControlBarRightLayout); patchLayout(layersPanelControlBarRightLayout, data);
layersPanelControlBarRightLayout = layersPanelControlBarRightLayout; layersPanelControlBarRightLayout = layersPanelControlBarRightLayout;
}); });
editor.subscriptions.subscribeJsMessage(UpdateLayersPanelBottomBarLayout, (updateLayersPanelBottomBarLayout) => { editor.subscriptions.subscribeJsMessage(UpdateLayersPanelBottomBarLayout, (data) => {
patchLayout(layersPanelBottomBarLayout, updateLayersPanelBottomBarLayout); patchLayout(layersPanelBottomBarLayout, data);
layersPanelBottomBarLayout = layersPanelBottomBarLayout; layersPanelBottomBarLayout = layersPanelBottomBarLayout;
}); });
editor.subscriptions.subscribeJsMessage(UpdateDocumentLayerStructureJs, (updateDocumentLayerStructure) => { editor.subscriptions.subscribeJsMessage(UpdateDocumentLayerStructureJs, (data) => {
const structure = newUpdateDocumentLayerStructure(updateDocumentLayerStructure.dataBuffer); const structure = newUpdateDocumentLayerStructure(data.dataBuffer);
rebuildLayerHierarchy(structure); rebuildLayerHierarchy(structure);
}); });
editor.subscriptions.subscribeJsMessage(UpdateDocumentLayerDetails, (updateDocumentLayerDetails) => { editor.subscriptions.subscribeJsMessage(UpdateDocumentLayerDetails, (data) => {
const targetLayer = updateDocumentLayerDetails.data; const targetLayer = data.data;
const targetId = targetLayer.id; const targetId = targetLayer.id;
updateLayerInTree(targetId, targetLayer); updateLayerInTree(targetId, targetLayer);

View File

@ -12,8 +12,8 @@
let propertiesPanelLayout: Layout = []; let propertiesPanelLayout: Layout = [];
onMount(() => { onMount(() => {
editor.subscriptions.subscribeJsMessage(UpdatePropertiesPanelLayout, (updatePropertiesPanelLayout) => { editor.subscriptions.subscribeJsMessage(UpdatePropertiesPanelLayout, (data) => {
patchLayout(propertiesPanelLayout, updatePropertiesPanelLayout); patchLayout(propertiesPanelLayout, data);
propertiesPanelLayout = propertiesPanelLayout; propertiesPanelLayout = propertiesPanelLayout;
}); });
}); });

View File

@ -17,8 +17,8 @@
let welcomePanelButtonsLayout: Layout = []; let welcomePanelButtonsLayout: Layout = [];
onMount(() => { onMount(() => {
editor.subscriptions.subscribeJsMessage(UpdateWelcomeScreenButtonsLayout, (updateWelcomeScreenButtonsLayout) => { editor.subscriptions.subscribeJsMessage(UpdateWelcomeScreenButtonsLayout, (data) => {
patchLayout(welcomePanelButtonsLayout, updateWelcomeScreenButtonsLayout); patchLayout(welcomePanelButtonsLayout, data);
welcomePanelButtonsLayout = welcomePanelButtonsLayout; welcomePanelButtonsLayout = welcomePanelButtonsLayout;
}); });
}); });

View File

@ -13,8 +13,8 @@
let statusBarHintsLayout: Layout = []; let statusBarHintsLayout: Layout = [];
onMount(() => { onMount(() => {
editor.subscriptions.subscribeJsMessage(UpdateStatusBarHintsLayout, (updateStatusBarHintsLayout) => { editor.subscriptions.subscribeJsMessage(UpdateStatusBarHintsLayout, (data) => {
patchLayout(statusBarHintsLayout, updateStatusBarHintsLayout); patchLayout(statusBarHintsLayout, data);
statusBarHintsLayout = statusBarHintsLayout; statusBarHintsLayout = statusBarHintsLayout;
}); });
}); });

View File

@ -21,8 +21,8 @@
$: height = $appWindow.platform === "Mac" ? 28 * (1 / $appWindow.uiScale) : 28; $: height = $appWindow.platform === "Mac" ? 28 * (1 / $appWindow.uiScale) : 28;
onMount(() => { onMount(() => {
editor.subscriptions.subscribeJsMessage(UpdateMenuBarLayout, (updateMenuBarLayout) => { editor.subscriptions.subscribeJsMessage(UpdateMenuBarLayout, (data) => {
patchLayout(menuBarLayout, updateMenuBarLayout); patchLayout(menuBarLayout, data);
menuBarLayout = menuBarLayout; menuBarLayout = menuBarLayout;
}); });
}); });

View File

@ -3,9 +3,9 @@ import { TriggerClipboardWrite, TriggerSelectionRead, TriggerSelectionWrite } fr
export function createClipboardManager(editor: Editor) { export function createClipboardManager(editor: Editor) {
// Subscribe to process backend event // Subscribe to process backend event
editor.subscriptions.subscribeJsMessage(TriggerClipboardWrite, (triggerTextCopy) => { editor.subscriptions.subscribeJsMessage(TriggerClipboardWrite, (data) => {
// If the Clipboard API is supported in the browser, copy text to the clipboard // If the Clipboard API is supported in the browser, copy text to the clipboard
navigator.clipboard?.writeText?.(triggerTextCopy.content); navigator.clipboard?.writeText?.(data.content);
}); });
editor.subscriptions.subscribeJsMessage(TriggerSelectionRead, async (data) => { editor.subscriptions.subscribeJsMessage(TriggerSelectionRead, async (data) => {
editor.handle.readSelection(readAtCaret(data.cut), data.cut); editor.handle.readSelection(readAtCaret(data.cut), data.cut);

View File

@ -26,16 +26,16 @@ export function createFontsManager(editor: Editor) {
editor.handle.onFontCatalogLoad(catalog); editor.handle.onFontCatalogLoad(catalog);
}); });
editor.subscriptions.subscribeJsMessage(TriggerFontDataLoad, async (triggerFontDataLoad) => { editor.subscriptions.subscribeJsMessage(TriggerFontDataLoad, async (data) => {
const { fontFamily, fontStyle } = triggerFontDataLoad.font; const { fontFamily, fontStyle } = data.font;
try { try {
if (!triggerFontDataLoad.url) throw new Error("No URL provided for font data load"); if (!data.url) throw new Error("No URL provided for font data load");
const response = await fetch(triggerFontDataLoad.url); const response = await fetch(data.url);
const buffer = await response.arrayBuffer(); const buffer = await response.arrayBuffer();
const data = new Uint8Array(buffer); const bytes = new Uint8Array(buffer);
editor.handle.onFontLoad(fontFamily, fontStyle, data); editor.handle.onFontLoad(fontFamily, fontStyle, bytes);
} catch (error) { } catch (error) {
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
console.error("Failed to load font:", error); console.error("Failed to load font:", error);

View File

@ -3,7 +3,7 @@ import { TriggerVisitLink } from "@graphite/messages";
export function createHyperlinkManager(editor: Editor) { export function createHyperlinkManager(editor: Editor) {
// Subscribe to process backend event // Subscribe to process backend event
editor.subscriptions.subscribeJsMessage(TriggerVisitLink, async (triggerOpenLink) => { editor.subscriptions.subscribeJsMessage(TriggerVisitLink, async (data) => {
window.open(triggerOpenLink.url, "_blank"); window.open(data.url, "_blank");
}); });
} }

View File

@ -3,8 +3,8 @@ import { TriggerAboutGraphiteLocalizedCommitDate } from "@graphite/messages";
export function createLocalizationManager(editor: Editor) { export function createLocalizationManager(editor: Editor) {
// Subscribe to process backend event // Subscribe to process backend event
editor.subscriptions.subscribeJsMessage(TriggerAboutGraphiteLocalizedCommitDate, (triggerAboutGraphiteLocalizedCommitDate) => { editor.subscriptions.subscribeJsMessage(TriggerAboutGraphiteLocalizedCommitDate, (data) => {
const localized = localizeTimestamp(triggerAboutGraphiteLocalizedCommitDate.commitDate); const localized = localizeTimestamp(data.commitDate);
editor.handle.requestAboutGraphiteDialogWithLocalizedCommitDate(localized.timestamp, localized.year); editor.handle.requestAboutGraphiteDialogWithLocalizedCommitDate(localized.timestamp, localized.year);
}); });
} }

View File

@ -6,12 +6,12 @@ import { stripIndents } from "@graphite/utility-functions/strip-indents";
export function createPanicManager(editor: Editor, dialogState: DialogState) { export function createPanicManager(editor: Editor, dialogState: DialogState) {
// Code panic dialog and console error // Code panic dialog and console error
editor.subscriptions.subscribeJsMessage(DisplayDialogPanic, (displayDialogPanic) => { editor.subscriptions.subscribeJsMessage(DisplayDialogPanic, (data) => {
// `Error.stackTraceLimit` is only available in V8/Chromium // `Error.stackTraceLimit` is only available in V8/Chromium
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
(Error as any).stackTraceLimit = Infinity; (Error as any).stackTraceLimit = Infinity;
const stackTrace = new Error().stack || ""; const stackTrace = new Error().stack || "";
const panicDetails = `${displayDialogPanic.panicInfo}${stackTrace ? `\n\n${stackTrace}` : ""}`; const panicDetails = `${data.panicInfo}${stackTrace ? `\n\n${stackTrace}` : ""}`;
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
console.error(panicDetails); console.error(panicDetails);

View File

@ -154,17 +154,17 @@ export function createPersistenceManager(editor: Editor, portfolio: PortfolioSta
// FRONTEND MESSAGE SUBSCRIPTIONS // FRONTEND MESSAGE SUBSCRIPTIONS
// Subscribe to process backend events // Subscribe to process backend events
editor.subscriptions.subscribeJsMessage(TriggerSavePreferences, async (preferences) => { editor.subscriptions.subscribeJsMessage(TriggerSavePreferences, async (data) => {
await savePreferences(preferences.preferences); await savePreferences(data.preferences);
}); });
editor.subscriptions.subscribeJsMessage(TriggerLoadPreferences, async () => { editor.subscriptions.subscribeJsMessage(TriggerLoadPreferences, async () => {
await loadPreferences(); await loadPreferences();
}); });
editor.subscriptions.subscribeJsMessage(TriggerPersistenceWriteDocument, async (autoSaveDocument) => { editor.subscriptions.subscribeJsMessage(TriggerPersistenceWriteDocument, async (data) => {
await storeDocument(autoSaveDocument); await storeDocument(data);
}); });
editor.subscriptions.subscribeJsMessage(TriggerPersistenceRemoveDocument, async (removeAutoSaveDocument) => { editor.subscriptions.subscribeJsMessage(TriggerPersistenceRemoveDocument, async (data) => {
await removeDocument(removeAutoSaveDocument.documentId); await removeDocument(data.documentId);
}); });
editor.subscriptions.subscribeJsMessage(TriggerLoadFirstAutoSaveDocument, async () => { editor.subscriptions.subscribeJsMessage(TriggerLoadFirstAutoSaveDocument, async () => {
await loadFirstDocument(); await loadFirstDocument();
@ -175,8 +175,8 @@ export function createPersistenceManager(editor: Editor, portfolio: PortfolioSta
editor.subscriptions.subscribeJsMessage(TriggerOpenLaunchDocuments, async () => { editor.subscriptions.subscribeJsMessage(TriggerOpenLaunchDocuments, async () => {
// TODO: Could be used to load documents from URL params or similar on launch // TODO: Could be used to load documents from URL params or similar on launch
}); });
editor.subscriptions.subscribeJsMessage(TriggerSaveActiveDocument, async (triggerSaveActiveDocument) => { editor.subscriptions.subscribeJsMessage(TriggerSaveActiveDocument, async (data) => {
const documentId = String(triggerSaveActiveDocument.documentId); const documentId = String(data.documentId);
const previouslySavedDocuments = await get<Record<string, TriggerPersistenceWriteDocument>>("documents", graphiteStore); const previouslySavedDocuments = await get<Record<string, TriggerPersistenceWriteDocument>>("documents", graphiteStore);
if (!previouslySavedDocuments) return; if (!previouslySavedDocuments) return;
if (documentId in previouslySavedDocuments) { if (documentId in previouslySavedDocuments) {

View File

@ -13,33 +13,33 @@ export function createAppWindowState(editor: Editor) {
}); });
// Set up message subscriptions on creation // Set up message subscriptions on creation
editor.subscriptions.subscribeJsMessage(UpdatePlatform, (updatePlatform) => { editor.subscriptions.subscribeJsMessage(UpdatePlatform, (data) => {
update((state) => { update((state) => {
state.platform = updatePlatform.platform; state.platform = data.platform;
return state; return state;
}); });
}); });
editor.subscriptions.subscribeJsMessage(UpdateMaximized, (updateMaximized) => { editor.subscriptions.subscribeJsMessage(UpdateMaximized, (data) => {
update((state) => { update((state) => {
state.maximized = updateMaximized.maximized; state.maximized = data.maximized;
return state; return state;
}); });
}); });
editor.subscriptions.subscribeJsMessage(UpdateFullscreen, (updateFullscreen) => { editor.subscriptions.subscribeJsMessage(UpdateFullscreen, (data) => {
update((state) => { update((state) => {
state.fullscreen = updateFullscreen.fullscreen; state.fullscreen = data.fullscreen;
return state; return state;
}); });
}); });
editor.subscriptions.subscribeJsMessage(UpdateViewportHolePunch, (viewportHolePunch) => { editor.subscriptions.subscribeJsMessage(UpdateViewportHolePunch, (data) => {
update((state) => { update((state) => {
state.viewportHolePunch = viewportHolePunch.active; state.viewportHolePunch = data.active;
return state; return state;
}); });
}); });
editor.subscriptions.subscribeJsMessage(UpdateUIScale, (uiScale) => { editor.subscriptions.subscribeJsMessage(UpdateUIScale, (data) => {
update((state) => { update((state) => {
state.uiScale = uiScale.scale; state.uiScale = data.scale;
return state; return state;
}); });
}); });

View File

@ -45,33 +45,33 @@ export function createDialogState(editor: Editor) {
} }
// Subscribe to process backend events // Subscribe to process backend events
editor.subscriptions.subscribeJsMessage(DisplayDialog, (displayDialog) => { editor.subscriptions.subscribeJsMessage(DisplayDialog, (data) => {
update((state) => { update((state) => {
state.visible = true; state.visible = true;
state.title = displayDialog.title; state.title = data.title;
state.icon = displayDialog.icon; state.icon = data.icon;
return state; return state;
}); });
}); });
editor.subscriptions.subscribeJsMessage(UpdateDialogButtons, (updateDialogButtons) => { editor.subscriptions.subscribeJsMessage(UpdateDialogButtons, (data) => {
update((state) => { update((state) => {
patchLayout(state.buttons, updateDialogButtons); patchLayout(state.buttons, data);
return state; return state;
}); });
}); });
editor.subscriptions.subscribeJsMessage(UpdateDialogColumn1, (updateDialogColumn1) => { editor.subscriptions.subscribeJsMessage(UpdateDialogColumn1, (data) => {
update((state) => { update((state) => {
patchLayout(state.column1, updateDialogColumn1); patchLayout(state.column1, data);
return state; return state;
}); });
}); });
editor.subscriptions.subscribeJsMessage(UpdateDialogColumn2, (updateDialogColumn2) => { editor.subscriptions.subscribeJsMessage(UpdateDialogColumn2, (data) => {
update((state) => { update((state) => {
patchLayout(state.column2, updateDialogColumn2); patchLayout(state.column2, data);
return state; return state;
}); });

View File

@ -30,55 +30,55 @@ export function createDocumentState(editor: Editor) {
const { subscribe, update } = state; const { subscribe, update } = state;
// Update layouts // Update layouts
editor.subscriptions.subscribeJsMessage(UpdateGraphFadeArtwork, (updateGraphFadeArtwork) => { editor.subscriptions.subscribeJsMessage(UpdateGraphFadeArtwork, (data) => {
update((state) => { update((state) => {
state.fadeArtwork = updateGraphFadeArtwork.percentage; state.fadeArtwork = data.percentage;
return state; return state;
}); });
}); });
editor.subscriptions.subscribeJsMessage(UpdateToolOptionsLayout, async (updateToolOptionsLayout) => { editor.subscriptions.subscribeJsMessage(UpdateToolOptionsLayout, async (data) => {
await tick(); await tick();
update((state) => { update((state) => {
patchLayout(state.toolOptionsLayout, updateToolOptionsLayout); patchLayout(state.toolOptionsLayout, data);
return state; return state;
}); });
}); });
editor.subscriptions.subscribeJsMessage(UpdateDocumentBarLayout, async (updateDocumentBarLayout) => { editor.subscriptions.subscribeJsMessage(UpdateDocumentBarLayout, async (data) => {
await tick(); await tick();
update((state) => { update((state) => {
patchLayout(state.documentBarLayout, updateDocumentBarLayout); patchLayout(state.documentBarLayout, data);
return state; return state;
}); });
}); });
editor.subscriptions.subscribeJsMessage(UpdateToolShelfLayout, async (updateToolShelfLayout) => { editor.subscriptions.subscribeJsMessage(UpdateToolShelfLayout, async (data) => {
await tick(); await tick();
update((state) => { update((state) => {
patchLayout(state.toolShelfLayout, updateToolShelfLayout); patchLayout(state.toolShelfLayout, data);
return state; return state;
}); });
}); });
editor.subscriptions.subscribeJsMessage(UpdateWorkingColorsLayout, async (updateWorkingColorsLayout) => { editor.subscriptions.subscribeJsMessage(UpdateWorkingColorsLayout, async (data) => {
await tick(); await tick();
update((state) => { update((state) => {
patchLayout(state.workingColorsLayout, updateWorkingColorsLayout); patchLayout(state.workingColorsLayout, data);
return state; return state;
}); });
}); });
editor.subscriptions.subscribeJsMessage(UpdateNodeGraphControlBarLayout, (updateNodeGraphControlBarLayout) => { editor.subscriptions.subscribeJsMessage(UpdateNodeGraphControlBarLayout, (data) => {
update((state) => { update((state) => {
patchLayout(state.nodeGraphControlBarLayout, updateNodeGraphControlBarLayout); patchLayout(state.nodeGraphControlBarLayout, data);
return state; return state;
}); });
}); });
// Show or hide the graph view overlay // Show or hide the graph view overlay
editor.subscriptions.subscribeJsMessage(UpdateGraphViewOverlay, (updateGraphViewOverlay) => { editor.subscriptions.subscribeJsMessage(UpdateGraphViewOverlay, (data) => {
update((state) => { update((state) => {
state.graphViewOverlayOpen = updateGraphViewOverlay.open; state.graphViewOverlayOpen = data.open;
return state; return state;
}); });
}); });

View File

@ -62,87 +62,87 @@ export function createNodeGraphState(editor: Editor) {
} }
// Set up message subscriptions on creation // Set up message subscriptions on creation
editor.subscriptions.subscribeJsMessage(SendUIMetadata, (uiMetadata) => { editor.subscriptions.subscribeJsMessage(SendUIMetadata, (data) => {
update((state) => { update((state) => {
state.nodeDescriptions = uiMetadata.nodeDescriptions; state.nodeDescriptions = data.nodeDescriptions;
state.nodeTypes = uiMetadata.nodeTypes; state.nodeTypes = data.nodeTypes;
return state; return state;
}); });
}); });
editor.subscriptions.subscribeJsMessage(UpdateBox, (updateBox) => { editor.subscriptions.subscribeJsMessage(UpdateBox, (data) => {
update((state) => { update((state) => {
state.box = updateBox.box; state.box = data.box;
return state; return state;
}); });
}); });
editor.subscriptions.subscribeJsMessage(UpdateClickTargets, (UpdateClickTargets) => { editor.subscriptions.subscribeJsMessage(UpdateClickTargets, (data) => {
update((state) => { update((state) => {
state.clickTargets = UpdateClickTargets.clickTargets; state.clickTargets = data.clickTargets;
return state; return state;
}); });
}); });
editor.subscriptions.subscribeJsMessage(UpdateContextMenuInformation, (updateContextMenuInformation) => { editor.subscriptions.subscribeJsMessage(UpdateContextMenuInformation, (data) => {
update((state) => { update((state) => {
state.contextMenuInformation = updateContextMenuInformation.contextMenuInformation; state.contextMenuInformation = data.contextMenuInformation;
return state; return state;
}); });
}); });
editor.subscriptions.subscribeJsMessage(UpdateImportReorderIndex, (updateImportReorderIndex) => { editor.subscriptions.subscribeJsMessage(UpdateImportReorderIndex, (data) => {
update((state) => { update((state) => {
state.reorderImportIndex = updateImportReorderIndex.importIndex; state.reorderImportIndex = data.importIndex;
return state; return state;
}); });
}); });
editor.subscriptions.subscribeJsMessage(UpdateExportReorderIndex, (updateExportReorderIndex) => { editor.subscriptions.subscribeJsMessage(UpdateExportReorderIndex, (data) => {
update((state) => { update((state) => {
state.reorderExportIndex = updateExportReorderIndex.exportIndex; state.reorderExportIndex = data.exportIndex;
return state; return state;
}); });
}); });
editor.subscriptions.subscribeJsMessage(UpdateImportsExports, (updateImportsExports) => { editor.subscriptions.subscribeJsMessage(UpdateImportsExports, (data) => {
update((state) => { update((state) => {
state.updateImportsExports = updateImportsExports; state.updateImportsExports = data;
return state; return state;
}); });
}); });
editor.subscriptions.subscribeJsMessage(UpdateInSelectedNetwork, (updateInSelectedNetwork) => { editor.subscriptions.subscribeJsMessage(UpdateInSelectedNetwork, (data) => {
update((state) => { update((state) => {
state.inSelectedNetwork = updateInSelectedNetwork.inSelectedNetwork; state.inSelectedNetwork = data.inSelectedNetwork;
return state; return state;
}); });
}); });
editor.subscriptions.subscribeJsMessage(UpdateLayerWidths, (updateLayerWidths) => { editor.subscriptions.subscribeJsMessage(UpdateLayerWidths, (data) => {
update((state) => { update((state) => {
state.layerWidths = updateLayerWidths.layerWidths; state.layerWidths = data.layerWidths;
state.chainWidths = updateLayerWidths.chainWidths; state.chainWidths = data.chainWidths;
state.hasLeftInputWire = updateLayerWidths.hasLeftInputWire; state.hasLeftInputWire = data.hasLeftInputWire;
return state; return state;
}); });
}); });
editor.subscriptions.subscribeJsMessage(UpdateNodeGraphNodes, (updateNodeGraphNodes) => { editor.subscriptions.subscribeJsMessage(UpdateNodeGraphNodes, (data) => {
update((state) => { update((state) => {
state.nodes.clear(); state.nodes.clear();
updateNodeGraphNodes.nodes.forEach((node) => { data.nodes.forEach((node) => {
state.nodes.set(node.id, node); state.nodes.set(node.id, node);
}); });
return state; return state;
}); });
}); });
editor.subscriptions.subscribeJsMessage(UpdateNodeGraphErrorDiagnostic, (updateNodeGraphErrorDiagnostic) => { editor.subscriptions.subscribeJsMessage(UpdateNodeGraphErrorDiagnostic, (data) => {
update((state) => { update((state) => {
state.error = updateNodeGraphErrorDiagnostic.error; state.error = data.error;
return state; return state;
}); });
}); });
editor.subscriptions.subscribeJsMessage(UpdateVisibleNodes, (updateVisibleNodes) => { editor.subscriptions.subscribeJsMessage(UpdateVisibleNodes, (data) => {
update((state) => { update((state) => {
state.visibleNodes = new Set<bigint>(updateVisibleNodes.nodes); state.visibleNodes = new Set<bigint>(data.nodes);
return state; return state;
}); });
}); });
editor.subscriptions.subscribeJsMessage(UpdateNodeGraphWires, (updateNodeWires) => { editor.subscriptions.subscribeJsMessage(UpdateNodeGraphWires, (data) => {
update((state) => { update((state) => {
updateNodeWires.wires.forEach((wireUpdate) => { data.wires.forEach((wireUpdate) => {
let inputMap = state.wires.get(wireUpdate.id); let inputMap = state.wires.get(wireUpdate.id);
// If it doesn't exist, create it and set it in the outer map // If it doesn't exist, create it and set it in the outer map
if (!inputMap) { if (!inputMap) {
@ -158,33 +158,33 @@ export function createNodeGraphState(editor: Editor) {
return state; return state;
}); });
}); });
editor.subscriptions.subscribeJsMessage(ClearAllNodeGraphWires, (_) => { editor.subscriptions.subscribeJsMessage(ClearAllNodeGraphWires, () => {
update((state) => { update((state) => {
state.wires.clear(); state.wires.clear();
return state; return state;
}); });
}); });
editor.subscriptions.subscribeJsMessage(UpdateNodeGraphSelection, (updateNodeGraphSelection) => { editor.subscriptions.subscribeJsMessage(UpdateNodeGraphSelection, (data) => {
update((state) => { update((state) => {
state.selected = updateNodeGraphSelection.selected; state.selected = data.selected;
return state; return state;
}); });
}); });
editor.subscriptions.subscribeJsMessage(UpdateNodeGraphTransform, (updateNodeGraphTransform) => { editor.subscriptions.subscribeJsMessage(UpdateNodeGraphTransform, (data) => {
update((state) => { update((state) => {
state.transform = updateNodeGraphTransform.transform; state.transform = data.transform;
return state; return state;
}); });
}); });
editor.subscriptions.subscribeJsMessage(UpdateNodeThumbnail, (updateNodeThumbnail) => { editor.subscriptions.subscribeJsMessage(UpdateNodeThumbnail, (data) => {
update((state) => { update((state) => {
state.thumbnails.set(updateNodeThumbnail.id, updateNodeThumbnail.value); state.thumbnails.set(data.id, data.value);
return state; return state;
}); });
}); });
editor.subscriptions.subscribeJsMessage(UpdateWirePathInProgress, (updateWirePathInProgress) => { editor.subscriptions.subscribeJsMessage(UpdateWirePathInProgress, (data) => {
update((state) => { update((state) => {
state.wirePathInProgress = updateWirePathInProgress.wirePath; state.wirePathInProgress = data.wirePath;
return state; return state;
}); });
}); });

View File

@ -29,26 +29,26 @@ export function createPortfolioState(editor: Editor) {
}); });
// Set up message subscriptions on creation // Set up message subscriptions on creation
editor.subscriptions.subscribeJsMessage(UpdateOpenDocumentsList, (updateOpenDocumentList) => { editor.subscriptions.subscribeJsMessage(UpdateOpenDocumentsList, (data) => {
update((state) => { update((state) => {
state.documents = updateOpenDocumentList.openDocuments; state.documents = data.openDocuments;
return state; return state;
}); });
}); });
editor.subscriptions.subscribeJsMessage(UpdateActiveDocument, (updateActiveDocument) => { editor.subscriptions.subscribeJsMessage(UpdateActiveDocument, (data) => {
update((state) => { update((state) => {
// Assume we receive a correct document id // Assume we receive a correct document id
const activeId = state.documents.findIndex((doc) => doc.id === updateActiveDocument.documentId); const activeId = state.documents.findIndex((doc) => doc.id === data.documentId);
state.activeDocumentIndex = activeId; state.activeDocumentIndex = activeId;
return state; return state;
}); });
}); });
editor.subscriptions.subscribeJsMessage(TriggerFetchAndOpenDocument, async (triggerFetchAndOpenDocument) => { editor.subscriptions.subscribeJsMessage(TriggerFetchAndOpenDocument, async (data) => {
try { try {
const { name, filename } = triggerFetchAndOpenDocument; const { name, filename } = data;
const url = new URL(`demo-artwork/${filename}`, document.location.href); const url = new URL(`demo-artwork/${filename}`, document.location.href);
const data = await fetch(url); const response = await fetch(url);
const content = await data.text(); const content = await response.text();
editor.handle.openDocumentFile(name, content); editor.handle.openDocumentFile(name, content);
} catch { } catch {
@ -90,14 +90,14 @@ export function createPortfolioState(editor: Editor) {
const imageData = await extractPixelData(new Blob([new Uint8Array(data.content.data)], { type: data.type })); const imageData = await extractPixelData(new Blob([new Uint8Array(data.content.data)], { type: data.type }));
editor.handle.pasteImage(data.filename, new Uint8Array(imageData.data), imageData.width, imageData.height); editor.handle.pasteImage(data.filename, new Uint8Array(imageData.data), imageData.width, imageData.height);
}); });
editor.subscriptions.subscribeJsMessage(TriggerSaveDocument, (triggerSaveDocument) => { editor.subscriptions.subscribeJsMessage(TriggerSaveDocument, (data) => {
downloadFile(triggerSaveDocument.name, triggerSaveDocument.content); downloadFile(data.name, data.content);
}); });
editor.subscriptions.subscribeJsMessage(TriggerSaveFile, (triggerFileDownload) => { editor.subscriptions.subscribeJsMessage(TriggerSaveFile, (data) => {
downloadFile(triggerFileDownload.name, triggerFileDownload.content); downloadFile(data.name, data.content);
}); });
editor.subscriptions.subscribeJsMessage(TriggerExportImage, async (TriggerExportImage) => { editor.subscriptions.subscribeJsMessage(TriggerExportImage, async (data) => {
const { svg, name, mime, size } = TriggerExportImage; const { svg, name, mime, size } = data;
// Fill the canvas with white if it'll be a JPEG (which does not support transparency and defaults to black) // Fill the canvas with white if it'll be a JPEG (which does not support transparency and defaults to black)
const backgroundColor = mime.endsWith("jpeg") ? "white" : undefined; const backgroundColor = mime.endsWith("jpeg") ? "white" : undefined;
@ -112,21 +112,21 @@ export function createPortfolioState(editor: Editor) {
// Fail silently if there's an error rasterizing the SVG, such as a zero-sized image // Fail silently if there's an error rasterizing the SVG, such as a zero-sized image
} }
}); });
editor.subscriptions.subscribeJsMessage(UpdateDataPanelState, async (updateDataPanelState) => { editor.subscriptions.subscribeJsMessage(UpdateDataPanelState, async (data) => {
update((state) => { update((state) => {
state.dataPanelOpen = updateDataPanelState.open; state.dataPanelOpen = data.open;
return state; return state;
}); });
}); });
editor.subscriptions.subscribeJsMessage(UpdatePropertiesPanelState, async (updatePropertiesPanelState) => { editor.subscriptions.subscribeJsMessage(UpdatePropertiesPanelState, async (data) => {
update((state) => { update((state) => {
state.propertiesPanelOpen = updatePropertiesPanelState.open; state.propertiesPanelOpen = data.open;
return state; return state;
}); });
}); });
editor.subscriptions.subscribeJsMessage(UpdateLayersPanelState, async (updateLayersPanelState) => { editor.subscriptions.subscribeJsMessage(UpdateLayersPanelState, async (data) => {
update((state) => { update((state) => {
state.layersPanelOpen = updateLayersPanelState.open; state.layersPanelOpen = data.open;
return state; return state;
}); });
}); });

View File

@ -364,22 +364,14 @@ impl<Upstream> Vector<Upstream> {
number != 0 number != 0
} }
/// Points that can be extended from. /// Iterator over all anchor points.
/// pub fn anchor_points(&self) -> impl Iterator<Item = PointId> + '_ {
/// This may be points with more than one connection because of vector meshes.
pub fn extendable_points(&self) -> impl Iterator<Item = PointId> + '_ {
self.point_domain.ids().iter().copied() self.point_domain.ids().iter().copied()
} }
// TODO: Avoid needing this special function that's used in only one place. See: <https://github.com/GraphiteEditor/Graphite/commit/6e7f218068a55cc22659ee2cf4f0f2cf26d37774#r173283173> /// Anchor points at the ends of open subpaths. These are points with exactly one connection by a segment to another anchor.
/// Points that can be extended from. pub fn anchor_endpoints(&self) -> impl Iterator<Item = PointId> + '_ {
/// self.anchor_points().enumerate().filter(|&(index, _)| self.segment_domain.connected_count(index) == 1).map(|(_, id)| id)
/// This includes only points with exactly one connection because vector meshes are ignored.
pub fn extendable_points_no_vector_meshes(&self) -> impl Iterator<Item = PointId> + '_ {
self.extendable_points()
.enumerate()
.filter(|&(index, _)| self.segment_domain.connected_count(index) == 1)
.map(|(_, id)| id)
} }
/// Computes if all the connected handles are colinear for an anchor, or if that handle is colinear for a handle. /// Computes if all the connected handles are colinear for an anchor, or if that handle is colinear for a handle.