mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-19 02:48:12 +08:00
Simplify the Layers panel tree structure Rust -> JS encoding (#3744)
* replace custom layer structure encoding with simple JSON tree * add leftover files * Renames --------- Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
@@ -6,12 +6,12 @@
|
||||
import {
|
||||
patchLayout,
|
||||
UpdateDocumentLayerDetails,
|
||||
UpdateDocumentLayerStructureJs,
|
||||
UpdateDocumentLayerStructure,
|
||||
UpdateLayersPanelControlBarLeftLayout,
|
||||
UpdateLayersPanelControlBarRightLayout,
|
||||
UpdateLayersPanelBottomBarLayout,
|
||||
} from "@graphite/messages";
|
||||
import type { DataBuffer, LayerPanelEntry, Layout } 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";
|
||||
@@ -91,9 +91,8 @@
|
||||
layersPanelBottomBarLayout = layersPanelBottomBarLayout;
|
||||
});
|
||||
|
||||
editor.subscriptions.subscribeJsMessage(UpdateDocumentLayerStructureJs, (data) => {
|
||||
const structure = newUpdateDocumentLayerStructure(data.dataBuffer);
|
||||
rebuildLayerHierarchy(structure);
|
||||
editor.subscriptions.subscribeJsMessage(UpdateDocumentLayerStructure, (data) => {
|
||||
rebuildLayerHierarchy(data.layerStructure);
|
||||
});
|
||||
|
||||
editor.subscriptions.subscribeJsMessage(UpdateDocumentLayerDetails, (data) => {
|
||||
@@ -117,7 +116,7 @@
|
||||
editor.subscriptions.unsubscribeJsMessage(UpdateLayersPanelControlBarLeftLayout);
|
||||
editor.subscriptions.unsubscribeJsMessage(UpdateLayersPanelControlBarRightLayout);
|
||||
editor.subscriptions.unsubscribeJsMessage(UpdateLayersPanelBottomBarLayout);
|
||||
editor.subscriptions.unsubscribeJsMessage(UpdateDocumentLayerStructureJs);
|
||||
editor.subscriptions.unsubscribeJsMessage(UpdateDocumentLayerStructure);
|
||||
editor.subscriptions.unsubscribeJsMessage(UpdateDocumentLayerDetails);
|
||||
|
||||
removeEventListener("pointerup", draggingPointerUp);
|
||||
@@ -130,65 +129,6 @@
|
||||
removeEventListener("keyup", clippingKeyPress);
|
||||
});
|
||||
|
||||
type DocumentLayerStructure = {
|
||||
layerId: bigint;
|
||||
children: DocumentLayerStructure[];
|
||||
};
|
||||
|
||||
function newUpdateDocumentLayerStructure(dataBuffer: DataBuffer): DocumentLayerStructure {
|
||||
const pointerNum = Number(dataBuffer.pointer);
|
||||
const lengthNum = Number(dataBuffer.length);
|
||||
|
||||
const wasmMemoryBuffer = editor.raw.buffer;
|
||||
|
||||
// Decode the folder structure encoding
|
||||
const encoding = new DataView(wasmMemoryBuffer, pointerNum, lengthNum);
|
||||
|
||||
// The structure section indicates how to read through the upcoming layer list and assign depths to each layer
|
||||
const structureSectionLength = Number(encoding.getBigUint64(0, true));
|
||||
const structureSectionMsbSigned = new DataView(wasmMemoryBuffer, pointerNum + 8, structureSectionLength * 8);
|
||||
|
||||
// The layer IDs section lists each layer ID sequentially in the tree, as it will show up in the panel
|
||||
const layerIdsSection = new DataView(wasmMemoryBuffer, pointerNum + 8 + structureSectionLength * 8);
|
||||
|
||||
let layersEncountered = 0;
|
||||
let currentFolder: DocumentLayerStructure = { layerId: BigInt(-1), children: [] };
|
||||
const currentFolderStack = [currentFolder];
|
||||
|
||||
for (let i = 0; i < structureSectionLength; i += 1) {
|
||||
const msbSigned = structureSectionMsbSigned.getBigUint64(i * 8, true);
|
||||
const msbMask = BigInt(1) << BigInt(64 - 1);
|
||||
|
||||
// Set the MSB to 0 to clear the sign and then read the number as usual
|
||||
const numberOfLayersAtThisDepth = msbSigned & ~msbMask;
|
||||
|
||||
// Store child folders in the current folder (until we are interrupted by an indent)
|
||||
for (let j = 0; j < numberOfLayersAtThisDepth; j += 1) {
|
||||
const layerId = layerIdsSection.getBigUint64(layersEncountered * 8, true);
|
||||
layersEncountered += 1;
|
||||
|
||||
const childLayer: DocumentLayerStructure = { layerId, children: [] };
|
||||
currentFolder.children.push(childLayer);
|
||||
}
|
||||
|
||||
// Check the sign of the MSB, where a 1 is a negative (outward) indent
|
||||
const subsequentDirectionOfDepthChange = (msbSigned & msbMask) === BigInt(0);
|
||||
// Inward
|
||||
if (subsequentDirectionOfDepthChange) {
|
||||
currentFolderStack.push(currentFolder);
|
||||
currentFolder = currentFolder.children[currentFolder.children.length - 1];
|
||||
}
|
||||
// Outward
|
||||
else {
|
||||
const popped = currentFolderStack.pop();
|
||||
if (!popped) throw Error("Too many negative indents in the folder structure");
|
||||
if (popped) currentFolder = popped;
|
||||
}
|
||||
}
|
||||
|
||||
return currentFolder;
|
||||
}
|
||||
|
||||
function toggleNodeVisibilityLayerPanel(id: bigint) {
|
||||
editor.handle.toggleNodeVisibilityLayerPanel(id);
|
||||
}
|
||||
@@ -515,7 +455,7 @@
|
||||
dragInPanel = false;
|
||||
}
|
||||
|
||||
function rebuildLayerHierarchy(updateDocumentLayerStructure: DocumentLayerStructure) {
|
||||
function rebuildLayerHierarchy(layerStructure: LayerStructureEntry[]) {
|
||||
const layerWithNameBeingEdited = layers.find((layer: LayerListingInfo) => layer.editingName);
|
||||
const layerIdWithNameBeingEdited = layerWithNameBeingEdited?.entry.id;
|
||||
|
||||
@@ -523,24 +463,24 @@
|
||||
layers = [];
|
||||
|
||||
// Build the new layer hierarchy
|
||||
const recurse = (folder: DocumentLayerStructure) => {
|
||||
folder.children.forEach((item, index) => {
|
||||
const recurse = (children: LayerStructureEntry[]) => {
|
||||
children.forEach((item, index) => {
|
||||
const mapping = layerCache.get(String(item.layerId));
|
||||
if (mapping) {
|
||||
mapping.id = item.layerId;
|
||||
layers.push({
|
||||
folderIndex: index,
|
||||
bottomLayer: index === folder.children.length - 1,
|
||||
bottomLayer: index === children.length - 1,
|
||||
entry: mapping,
|
||||
editingName: layerIdWithNameBeingEdited === item.layerId,
|
||||
});
|
||||
}
|
||||
|
||||
// Call self recursively if there are any children
|
||||
if (item.children.length >= 1) recurse(item);
|
||||
if (item.children.length >= 1) recurse(item.children);
|
||||
});
|
||||
};
|
||||
recurse(updateDocumentLayerStructure);
|
||||
recurse(layerStructure);
|
||||
layers = layers;
|
||||
}
|
||||
|
||||
|
||||
@@ -796,13 +796,13 @@ export class TriggerSaveActiveDocument extends JsMessage {
|
||||
|
||||
export class DocumentChanged extends JsMessage {}
|
||||
|
||||
export type DataBuffer = {
|
||||
pointer: bigint;
|
||||
length: bigint;
|
||||
export type LayerStructureEntry = {
|
||||
layerId: bigint;
|
||||
children: LayerStructureEntry[];
|
||||
};
|
||||
|
||||
export class UpdateDocumentLayerStructureJs extends JsMessage {
|
||||
readonly dataBuffer!: DataBuffer;
|
||||
export class UpdateDocumentLayerStructure extends JsMessage {
|
||||
readonly layerStructure!: LayerStructureEntry[];
|
||||
}
|
||||
|
||||
export type TextAlign = "Left" | "Center" | "Right" | "JustifyLeft";
|
||||
@@ -1717,7 +1717,7 @@ export const messageMakers: Record<string, MessageMaker> = {
|
||||
UpdateDocumentArtwork,
|
||||
UpdateDocumentBarLayout,
|
||||
UpdateDocumentLayerDetails,
|
||||
UpdateDocumentLayerStructureJs,
|
||||
UpdateDocumentLayerStructure,
|
||||
UpdateDocumentRulers,
|
||||
UpdateDocumentScrollbars,
|
||||
UpdateExportReorderIndex,
|
||||
|
||||
Reference in New Issue
Block a user