mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-15 22:28:10 +08:00
Polish user-created subgraph nodes: imports in the Properties panel; reorder/delete/rename imports/exports (#2105)
* Remove imports/exports * WIP: Autogenerated properties * WIP: Input based properties * WIP: Hashmap based input overrides * Migrate noise pattern node to input properties * Reorder exports * Continue migrating properties * WIP: Improve reorder exports * Automatically populate all input properties for sub networks * Complete reorder import and export * Add widget override to node macro * Migrate assign colors to input based properties * WIP: Full node property override * Node based properties override for proto nodes * Migrate all node properties to be input based * Rename imports/exports * improve UI * Protonode input valid implementations * Valid type list * Small formatting fixes * Polishing small issues * Document upgrade * fix tests * Upgrade noise pattern node * remove console log * Fix upgrade script for Noise Pattern * Improve the Properties panel representation for graphical data * Re-export demo art * Code review * code review improvements * Cleanup for node properties overrides * Reexport demo art * Fix clippy lints --------- Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
@@ -123,8 +123,8 @@
|
||||
--color-data-vectordata-dim: #4b778c;
|
||||
--color-data-number: #cbbab4;
|
||||
--color-data-number-dim: #87736b;
|
||||
--color-data-graphic: #6b84e8;
|
||||
--color-data-graphic-dim: #4a557b;
|
||||
--color-data-group: #6b84e8;
|
||||
--color-data-group-dim: #4a557b;
|
||||
--color-data-artboard: #70a898;
|
||||
--color-data-artboard-dim: #3a6156;
|
||||
|
||||
|
||||
@@ -47,6 +47,69 @@
|
||||
|
||||
$: wirePaths = createWirePaths($nodeGraph.wirePathInProgress, nodeWirePaths);
|
||||
|
||||
let inputElement: HTMLInputElement;
|
||||
let hoveringImportIndex: number | undefined = undefined;
|
||||
let hoveringExportIndex: number | undefined = undefined;
|
||||
|
||||
let editingNameImportIndex: number | undefined = undefined;
|
||||
let editingNameExportIndex: number | undefined = undefined;
|
||||
let editingNameText = "";
|
||||
|
||||
function exportsToEdgeTextInputWidth() {
|
||||
let exportTextDivs = document.querySelectorAll(`[data-export-text-edge]`);
|
||||
let exportTextDiv = Array.from(exportTextDivs).find((div) => {
|
||||
return div.getAttribute("data-index") === String(editingNameExportIndex);
|
||||
});
|
||||
if (!graph || !exportTextDiv) return "50px";
|
||||
let distance = graph.getBoundingClientRect().right - exportTextDiv.getBoundingClientRect().right;
|
||||
return distance - 15 + "px";
|
||||
}
|
||||
|
||||
function importsToEdgeTextInputWidth() {
|
||||
let importTextDivs = document.querySelectorAll(`[data-import-text-edge]`);
|
||||
let importTextDiv = Array.from(importTextDivs).find((div) => {
|
||||
return div.getAttribute("data-index") === String(editingNameImportIndex);
|
||||
});
|
||||
if (!graph || !importTextDiv) return "50px";
|
||||
let distance = importTextDiv.getBoundingClientRect().left - graph.getBoundingClientRect().left;
|
||||
return distance - 15 + "px";
|
||||
}
|
||||
|
||||
function setEditingImportNameIndex(index: number, currentName: string) {
|
||||
focusInput(currentName);
|
||||
editingNameImportIndex = index;
|
||||
}
|
||||
|
||||
function setEditingExportNameIndex(index: number, currentName: string) {
|
||||
focusInput(currentName);
|
||||
editingNameExportIndex = index;
|
||||
}
|
||||
|
||||
function focusInput(currentName: string) {
|
||||
editingNameText = currentName;
|
||||
setTimeout(() => {
|
||||
if (inputElement) {
|
||||
inputElement.focus();
|
||||
}
|
||||
}, 0);
|
||||
}
|
||||
|
||||
function setEditingImportName(event: Event) {
|
||||
if (editingNameImportIndex !== undefined) {
|
||||
let text = (event.target as HTMLInputElement)?.value;
|
||||
editor.handle.setImportName(editingNameImportIndex, text);
|
||||
editingNameImportIndex = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
function setEditingExportName(event: Event) {
|
||||
if (editingNameExportIndex !== undefined) {
|
||||
let text = (event.target as HTMLInputElement)?.value;
|
||||
editor.handle.setExportName(editingNameExportIndex, text);
|
||||
editingNameExportIndex = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
function calculateGridSpacing(scale: number): number {
|
||||
const dense = scale * GRID_SIZE;
|
||||
let sparse = dense;
|
||||
@@ -267,6 +330,10 @@
|
||||
return value.resolvedType ? `Resolved Data: ${value.resolvedType}` : `Unresolved Data: ${value.dataType}`;
|
||||
}
|
||||
|
||||
function validTypesText(value: FrontendGraphInput): string {
|
||||
return `Valid Types:\n${value.validTypes.join(",\n ")}`;
|
||||
}
|
||||
|
||||
function outputConnectedToText(output: FrontendGraphOutput): string {
|
||||
if (output.connectedTo.length === 0) {
|
||||
return "Connected to nothing";
|
||||
@@ -396,6 +463,9 @@
|
||||
{/each}
|
||||
<path class="all-nodes-bounding-box" d={$nodeGraph.clickTargets.allNodesBoundingBox} />
|
||||
<path class="all-nodes-bounding-box" d={$nodeGraph.clickTargets.importExportsBoundingBox} />
|
||||
{#each $nodeGraph.clickTargets.modifyImportExport as pathString}
|
||||
<path class="modify-import-export" d={pathString} />
|
||||
{/each}
|
||||
</svg>
|
||||
</div>
|
||||
{/if}
|
||||
@@ -439,15 +509,54 @@
|
||||
<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-dim)" />
|
||||
{/if}
|
||||
</svg>
|
||||
<p class="import-text" style:--offset-left={position.x / 24} style:--offset-top={position.y / 24}>{outputMetadata.name}</p>
|
||||
|
||||
<div
|
||||
class="edit-import-export import"
|
||||
on:pointerenter={() => (hoveringImportIndex = index)}
|
||||
on:pointerleave={() => (hoveringImportIndex = undefined)}
|
||||
style:--offset-left={position.x / 24}
|
||||
style:--offset-top={position.y / 24}
|
||||
>
|
||||
{#if editingNameImportIndex == index}
|
||||
<input
|
||||
class="import-text-input"
|
||||
type="text"
|
||||
style:width={importsToEdgeTextInputWidth()}
|
||||
bind:this={inputElement}
|
||||
bind:value={editingNameText}
|
||||
on:blur={setEditingImportName}
|
||||
on:keydown={(e) => e.key === "Enter" && setEditingImportName(e)}
|
||||
/>
|
||||
{:else}
|
||||
<p class="import-text" on:dblclick={() => setEditingImportNameIndex(index, outputMetadata.name)}>{outputMetadata.name}</p>
|
||||
{/if}
|
||||
{#if hoveringImportIndex === index || editingNameImportIndex === index}
|
||||
<IconButton
|
||||
size={16}
|
||||
icon={"Remove"}
|
||||
class="remove-button-import"
|
||||
data-index={index}
|
||||
data-import-text-edge
|
||||
action={() => {
|
||||
/* Button is purely visual, clicking is handled in NodeGraphMessage::PointerDown */
|
||||
}}
|
||||
/>
|
||||
<div class="reorder-drag-grip" title="Reorder this import"></div>
|
||||
{/if}
|
||||
</div>
|
||||
{/each}
|
||||
{#if $nodeGraph.reorderImportIndex !== undefined}
|
||||
{@const position = {
|
||||
x: Number($nodeGraph.imports[0].position.x),
|
||||
y: Number($nodeGraph.imports[0].position.y) + Number($nodeGraph.reorderImportIndex) * 24,
|
||||
}}
|
||||
<div class="reorder-bar" style:--offset-left={(position.x - 48) / 24} style:--offset-top={(position.y - 4) / 24} />
|
||||
{/if}
|
||||
{#if $nodeGraph.addImport !== undefined}
|
||||
<div class="plus" style:--offset-left={$nodeGraph.addImport.x / 24} style:--offset-top={$nodeGraph.addImport.y / 24}>
|
||||
<IconButton
|
||||
class={"visibility"}
|
||||
data-visibility-button
|
||||
size={24}
|
||||
icon={"Add"}
|
||||
icon="Add"
|
||||
action={() => {
|
||||
/* Button is purely visual, clicking is handled in NodeGraphMessage::PointerDown */
|
||||
}}
|
||||
@@ -474,13 +583,50 @@
|
||||
<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-dim)" />
|
||||
{/if}
|
||||
</svg>
|
||||
<p class="export-text" style:--offset-left={position.x / 24} style:--offset-top={position.y / 24}>{inputMetadata.name}</p>
|
||||
<div
|
||||
class="edit-import-export export"
|
||||
on:pointerenter={() => (hoveringExportIndex = index)}
|
||||
on:pointerleave={() => (hoveringExportIndex = undefined)}
|
||||
style:--offset-left={position.x / 24}
|
||||
style:--offset-top={position.y / 24}
|
||||
>
|
||||
{#if hoveringExportIndex === index || editingNameExportIndex === index}
|
||||
<div class="reorder-drag-grip" title="Reorder this export"></div>
|
||||
<IconButton
|
||||
size={16}
|
||||
icon={"Remove"}
|
||||
class="remove-button-export"
|
||||
data-index={index}
|
||||
data-export-text-edge
|
||||
action={() => {
|
||||
/* Button is purely visual, clicking is handled in NodeGraphMessage::PointerDown */
|
||||
}}
|
||||
/>
|
||||
{/if}
|
||||
{#if editingNameExportIndex === index}
|
||||
<input
|
||||
type="text"
|
||||
style:width={exportsToEdgeTextInputWidth()}
|
||||
bind:this={inputElement}
|
||||
bind:value={editingNameText}
|
||||
on:blur={setEditingExportName}
|
||||
on:keydown={(e) => e.key === "Enter" && setEditingExportName(e)}
|
||||
/>
|
||||
{:else}
|
||||
<p class="export-text" on:dblclick={() => setEditingExportNameIndex(index, inputMetadata.name)}>{inputMetadata.name}</p>
|
||||
{/if}
|
||||
</div>
|
||||
{/each}
|
||||
{#if $nodeGraph.reorderExportIndex !== undefined}
|
||||
{@const position = {
|
||||
x: Number($nodeGraph.exports[0].position.x),
|
||||
y: Number($nodeGraph.exports[0].position.y) + Number($nodeGraph.reorderExportIndex) * 24,
|
||||
}}
|
||||
<div class="reorder-bar" style:--offset-left={position.x / 24} style:--offset-top={(position.y - 4) / 24} />
|
||||
{/if}
|
||||
{#if $nodeGraph.addExport !== undefined}
|
||||
<div class="plus" style:--offset-left={$nodeGraph.addExport.x / 24} style:--offset-top={$nodeGraph.addExport.y / 24}>
|
||||
<IconButton
|
||||
class={"visibility"}
|
||||
data-visibility-button
|
||||
size={24}
|
||||
icon={"Add"}
|
||||
action={() => {
|
||||
@@ -566,7 +712,7 @@
|
||||
bind:this={inputs[nodeIndex + 1][0]}
|
||||
>
|
||||
{#if node.primaryInput}
|
||||
<title>{`${dataTypeTooltip(node.primaryInput)}\n${inputConnectedToText(node.primaryInput)}`}</title>
|
||||
<title>{`${dataTypeTooltip(node.primaryInput)}\n${validTypesText(node.primaryInput)}\n${inputConnectedToText(node.primaryInput)}`}</title>
|
||||
{/if}
|
||||
{#if node.primaryInput?.connectedTo !== undefined}
|
||||
<path d="M0,0H8V8L5.479,6.319a2.666,2.666,0,0,0-2.959,0L0,8Z" fill="var(--data-color)" />
|
||||
@@ -591,7 +737,7 @@
|
||||
style:--data-color-dim={`var(--color-data-${stackDataInput.dataType.toLowerCase()}-dim)`}
|
||||
bind:this={inputs[nodeIndex + 1][1]}
|
||||
>
|
||||
<title>{`${dataTypeTooltip(stackDataInput)}\n${inputConnectedToText(stackDataInput)}`}</title>
|
||||
<title>{`${dataTypeTooltip(stackDataInput)}\n${validTypesText(stackDataInput)}\n${inputConnectedToText(stackDataInput)}`}</title>
|
||||
{#if stackDataInput.connectedTo !== undefined}
|
||||
<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)" />
|
||||
{:else}
|
||||
@@ -698,7 +844,7 @@
|
||||
style:--data-color-dim={`var(--color-data-${node.primaryInput.dataType.toLowerCase()}-dim)`}
|
||||
bind:this={inputs[nodeIndex + 1][0]}
|
||||
>
|
||||
<title>{`${dataTypeTooltip(node.primaryInput)}\n${inputConnectedToText(node.primaryInput)}`}</title>
|
||||
<title>{`${dataTypeTooltip(node.primaryInput)}\n${validTypesText(node.primaryInput)}\n${inputConnectedToText(node.primaryInput)}`}</title>
|
||||
{#if node.primaryInput.connectedTo !== undefined}
|
||||
<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)" />
|
||||
{:else}
|
||||
@@ -718,7 +864,7 @@
|
||||
style:--data-color-dim={`var(--color-data-${secondary.dataType.toLowerCase()}-dim)`}
|
||||
bind:this={inputs[nodeIndex + 1][index + (node.primaryInput ? 1 : 0)]}
|
||||
>
|
||||
<title>{`${dataTypeTooltip(secondary)}\n${inputConnectedToText(secondary)}`}</title>
|
||||
<title>{`${dataTypeTooltip(secondary)}\n${validTypesText(secondary)}\n${inputConnectedToText(secondary)}`}</title>
|
||||
{#if secondary.connectedTo !== undefined}
|
||||
<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)" />
|
||||
{:else}
|
||||
@@ -880,6 +1026,10 @@
|
||||
.all-nodes-bounding-box {
|
||||
stroke: purple;
|
||||
}
|
||||
|
||||
.modify-import-export {
|
||||
stroke: orange;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -918,30 +1068,66 @@
|
||||
left: calc(var(--offset-left) * 24px);
|
||||
}
|
||||
|
||||
.reorder-bar {
|
||||
position: absolute;
|
||||
top: calc(var(--offset-top) * 24px);
|
||||
left: calc(var(--offset-left) * 24px);
|
||||
width: 50px;
|
||||
height: 2px;
|
||||
background: white;
|
||||
}
|
||||
|
||||
.plus {
|
||||
margin-top: -4px;
|
||||
margin-left: -4px;
|
||||
position: absolute;
|
||||
top: calc(var(--offset-top) * 24px);
|
||||
left: calc(var(--offset-left) * 24px);
|
||||
}
|
||||
|
||||
.export-text {
|
||||
.edit-import-export {
|
||||
position: absolute;
|
||||
margin-top: 0;
|
||||
margin-left: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
top: calc(var(--offset-top) * 24px);
|
||||
left: calc(var(--offset-left) * 24px);
|
||||
}
|
||||
margin-top: -5px;
|
||||
height: 24px;
|
||||
|
||||
.import-text {
|
||||
position: absolute;
|
||||
text-align: right;
|
||||
top: calc(var(--offset-top) * 24px);
|
||||
left: calc(var(--offset-left) * 24px);
|
||||
margin-top: 0;
|
||||
margin-left: calc(-100px - 2px);
|
||||
width: 100px;
|
||||
&.import {
|
||||
right: calc(100% - var(--offset-left) * 24px);
|
||||
}
|
||||
|
||||
&.export {
|
||||
left: calc(var(--offset-left) * 24px + 17px);
|
||||
}
|
||||
|
||||
.import-text {
|
||||
text-align: right;
|
||||
text-wrap: nowrap;
|
||||
}
|
||||
|
||||
.export-text {
|
||||
text-wrap: nowrap;
|
||||
}
|
||||
|
||||
.import-text-input {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.remove-button-import {
|
||||
margin-left: 3px;
|
||||
}
|
||||
|
||||
.remove-button-export {
|
||||
margin-right: 3px;
|
||||
}
|
||||
|
||||
.reorder-drag-grip {
|
||||
width: 8px;
|
||||
height: 24px;
|
||||
background-position: 2px 8px;
|
||||
border-radius: 2px;
|
||||
margin: -6px 0;
|
||||
background-image: var(--icon-drag-grip-hover);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -73,6 +73,14 @@ export class UpdateInSelectedNetwork extends JsMessage {
|
||||
readonly inSelectedNetwork!: boolean;
|
||||
}
|
||||
|
||||
export class UpdateImportReorderIndex extends JsMessage {
|
||||
readonly importIndex!: number | undefined;
|
||||
}
|
||||
|
||||
export class UpdateExportReorderIndex extends JsMessage {
|
||||
readonly exportIndex!: number | undefined;
|
||||
}
|
||||
|
||||
const LayerWidths = Transform(({ obj }) => obj.layerWidths);
|
||||
const ChainWidths = Transform(({ obj }) => obj.chainWidths);
|
||||
const HasLeftInputWire = Transform(({ obj }) => obj.hasLeftInputWire);
|
||||
@@ -170,6 +178,7 @@ export type FrontendClickTargets = {
|
||||
readonly iconClickTargets: string[];
|
||||
readonly allNodesBoundingBox: string;
|
||||
readonly importExportsBoundingBox: string;
|
||||
readonly modifyImportExport: string[];
|
||||
};
|
||||
|
||||
export type ContextMenuInformation = {
|
||||
@@ -178,7 +187,7 @@ export type ContextMenuInformation = {
|
||||
contextMenuData: "CreateNode" | { nodeId: bigint; currentlyIsNode: boolean };
|
||||
};
|
||||
|
||||
export type FrontendGraphDataType = "General" | "Raster" | "VectorData" | "Number" | "Graphic" | "Artboard";
|
||||
export type FrontendGraphDataType = "General" | "Raster" | "VectorData" | "Number" | "Group" | "Artboard";
|
||||
|
||||
export class Node {
|
||||
readonly index!: bigint;
|
||||
@@ -210,6 +219,8 @@ export class FrontendGraphInput {
|
||||
|
||||
readonly resolvedType!: string | undefined;
|
||||
|
||||
readonly validTypes!: string[];
|
||||
|
||||
@CreateOutputConnectorOptional
|
||||
connectedTo!: Node | undefined;
|
||||
}
|
||||
@@ -1592,6 +1603,8 @@ export const messageMakers: Record<string, MessageMaker> = {
|
||||
UpdateImportsExports,
|
||||
UpdateInputHints,
|
||||
UpdateInSelectedNetwork,
|
||||
UpdateExportReorderIndex,
|
||||
UpdateImportReorderIndex,
|
||||
UpdateLayersPanelControlBarLayout,
|
||||
UpdateLayerWidths,
|
||||
UpdateMenuBarLayout,
|
||||
|
||||
@@ -15,6 +15,8 @@ import {
|
||||
UpdateClickTargets,
|
||||
UpdateContextMenuInformation,
|
||||
UpdateInSelectedNetwork,
|
||||
UpdateImportReorderIndex,
|
||||
UpdateExportReorderIndex,
|
||||
UpdateImportsExports,
|
||||
UpdateLayerWidths,
|
||||
UpdateNodeGraph,
|
||||
@@ -47,6 +49,8 @@ export function createNodeGraphState(editor: Editor) {
|
||||
selected: [] as bigint[],
|
||||
transform: { scale: 1, x: 0, y: 0 },
|
||||
inSelectedNetwork: true,
|
||||
reorderImportIndex: undefined as number | undefined,
|
||||
reorderExportIndex: undefined as number | undefined,
|
||||
});
|
||||
|
||||
// Set up message subscriptions on creation
|
||||
@@ -76,6 +80,18 @@ export function createNodeGraphState(editor: Editor) {
|
||||
return state;
|
||||
});
|
||||
});
|
||||
editor.subscriptions.subscribeJsMessage(UpdateImportReorderIndex, (updateImportReorderIndex) => {
|
||||
update((state) => {
|
||||
state.reorderImportIndex = updateImportReorderIndex.importIndex;
|
||||
return state;
|
||||
});
|
||||
});
|
||||
editor.subscriptions.subscribeJsMessage(UpdateExportReorderIndex, (updateExportReorderIndex) => {
|
||||
update((state) => {
|
||||
state.reorderExportIndex = updateExportReorderIndex.exportIndex;
|
||||
return state;
|
||||
});
|
||||
});
|
||||
editor.subscriptions.subscribeJsMessage(UpdateImportsExports, (updateImportsExports) => {
|
||||
update((state) => {
|
||||
state.imports = updateImportsExports.imports;
|
||||
|
||||
@@ -12,7 +12,7 @@ use editor::consts::FILE_SAVE_SUFFIX;
|
||||
use editor::messages::input_mapper::utility_types::input_keyboard::ModifierKeys;
|
||||
use editor::messages::input_mapper::utility_types::input_mouse::{EditorMouseState, ScrollDelta, ViewportBounds};
|
||||
use editor::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
||||
use editor::messages::portfolio::document::utility_types::network_interface::NodeTemplate;
|
||||
use editor::messages::portfolio::document::utility_types::network_interface::{ImportOrExport, NodeTemplate};
|
||||
use editor::messages::portfolio::utility_types::Platform;
|
||||
use editor::messages::prelude::*;
|
||||
use editor::messages::tool::tool_messages::tool_prelude::WidgetId;
|
||||
@@ -697,6 +697,26 @@ impl EditorHandle {
|
||||
self.dispatch(DocumentMessage::SetToNodeOrLayer { node_id: NodeId(id), is_layer });
|
||||
}
|
||||
|
||||
/// Set the name of an import or export
|
||||
#[wasm_bindgen(js_name = setImportName)]
|
||||
pub fn set_import_name(&self, index: usize, name: String) {
|
||||
let message = NodeGraphMessage::SetImportExportName {
|
||||
name,
|
||||
index: ImportOrExport::Import(index),
|
||||
};
|
||||
self.dispatch(message);
|
||||
}
|
||||
|
||||
/// Set the name of an export
|
||||
#[wasm_bindgen(js_name = setExportName)]
|
||||
pub fn set_export_name(&self, index: usize, name: String) {
|
||||
let message = NodeGraphMessage::SetImportExportName {
|
||||
name,
|
||||
index: ImportOrExport::Export(index),
|
||||
};
|
||||
self.dispatch(message);
|
||||
}
|
||||
|
||||
#[wasm_bindgen(js_name = injectImaginatePollServerStatus)]
|
||||
pub fn inject_imaginate_poll_server_status(&self) {
|
||||
self.dispatch(PortfolioMessage::ImaginatePollServerStatus);
|
||||
@@ -754,7 +774,10 @@ impl EditorHandle {
|
||||
if let Some(network) = document_node.implementation.get_network() {
|
||||
let mut nodes_to_upgrade = Vec::new();
|
||||
for (node_id, _) in network.nodes.iter().collect::<Vec<_>>() {
|
||||
if document.network_interface.reference(node_id, &[]).is_some_and(|reference| reference == "To Artboard")
|
||||
if document
|
||||
.network_interface
|
||||
.reference(node_id, &[])
|
||||
.is_some_and(|reference| *reference == Some("To Artboard".to_string()))
|
||||
&& document
|
||||
.network_interface
|
||||
.network(&[])
|
||||
@@ -770,7 +793,7 @@ impl EditorHandle {
|
||||
document
|
||||
.network_interface
|
||||
.replace_implementation(&node_id, &[], DocumentNodeImplementation::proto("graphene_core::ToArtboardNode"));
|
||||
document.network_interface.add_import(TaggedValue::IVec2(glam::IVec2::default()), false, 2, "".to_string(), &[node_id]);
|
||||
document.network_interface.add_import(TaggedValue::IVec2(glam::IVec2::default()), false, 2, "", &[node_id]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user