Fixing UI editing mode

This commit is contained in:
space-nuko
2023-04-29 13:08:59 -07:00
parent f62fa69122
commit 42f6f12ceb
5 changed files with 74 additions and 31 deletions

View File

@@ -169,7 +169,12 @@
</Button> </Button>
<Checkbox label="Lock Nodes" bind:value={$uiState.nodesLocked}/> <Checkbox label="Lock Nodes" bind:value={$uiState.nodesLocked}/>
<Checkbox label="Disable Interaction" bind:value={$uiState.graphLocked}/> <Checkbox label="Disable Interaction" bind:value={$uiState.graphLocked}/>
<Checkbox label="Enable UI Editing" bind:value={$uiState.unlocked}/> <label for="enable-ui-editing">Enable UI Editing</label>
<select id="enable-ui-editing" name="enable-ui-editing" bind:value={$uiState.uiEditMode}>
<option value="disabled">Disabled</option>
<option value="widgets">Widgets</option>
<option value="containers">Containers</option>
</select>
</div> </div>
<LightboxModal /> <LightboxModal />
</div> </div>

View File

@@ -53,8 +53,4 @@
} }
#comfy-ui-panes > :global(.root-container > .block) {
padding: 0px;
}
</style> </style>

View File

@@ -14,14 +14,15 @@
import { getComponentForWidgetState } from "$lib/utils" import { getComponentForWidgetState } from "$lib/utils"
export let dragItem: IDragItem | null = null; export let dragItem: IDragItem | null = null;
export let zIndex: number = 100; export let zIndex: number = 0;
export let classes: string[] = []; export let classes: string[] = [];
export let isRoot: boolean = false;
let dragDisabled: boolean = false;
let container: ContainerLayout | null = null; let container: ContainerLayout | null = null;
let widget: WidgetLayout | null = null; let widget: WidgetLayout | null = null;
let widgetState: WidgetUIState | null = null; let widgetState: WidgetUIState | null = null;
let children: IDragItem[] | null = null; let children: IDragItem[] | null = null;
let dragDisabled = true; const flipDurationMs = 100;
const flipDurationMs = 200;
$: if (dragItem) { $: if (dragItem) {
if (dragItem.type === "container") { if (dragItem.type === "container") {
@@ -37,8 +38,6 @@
} }
} }
$: dragDisabled = !$uiState.unlocked;
function handleConsider(evt: any) { function handleConsider(evt: any) {
children = layoutState.updateChildren(dragItem, evt.detail.items) children = layoutState.updateChildren(dragItem, evt.detail.items)
// console.log(dragItems); // console.log(dragItems);
@@ -47,18 +46,13 @@
function handleFinalize(evt: any) { function handleFinalize(evt: any) {
children = layoutState.updateChildren(dragItem, evt.detail.items) children = layoutState.updateChildren(dragItem, evt.detail.items)
// Ensure dragging is stopped on drag finish // Ensure dragging is stopped on drag finish
// dragDisabled = true;
}; };
const startDrag = () => { const startDrag = () => {
if (!$uiState.unlocked)
return return
// dragDisabled = false;
}; };
const stopDrag = () => { const stopDrag = () => {
if (!$uiState.unlocked)
return return
// dragDisabled = true;
}; };
$: if ($queueState && widget) { $: if ($queueState && widget) {
@@ -70,12 +64,14 @@
{#if container && children} {#if container && children}
{@const id = container.id} {@const id = container.id}
<div class="container {container.attrs.direction} {container.attrs.classes} {classes.join(' ')}"> <div class="container {container.attrs.direction} {container.attrs.classes} {classes.join(' ')}"
class:root-container={isRoot}
class:container-edit-outline={$uiState.uiEditMode === "containers" && zIndex > 1}>
<Block> <Block>
{#if container.attrs.showTitle} {#if container.attrs.showTitle}
<label for={String(id)} class={$uiState.unlocked ? "edit-title-label" : ""}> <label for={String(id)} class={$uiState.uiEditMode === "containers" ? "edit-title-label" : ""}>
<BlockTitle> <BlockTitle>
{#if $uiState.unlocked} {#if $uiState.uiEditMode === "containers"}
<input class="edit-title" bind:value={container.attrs.title} type="text" minlength="1" /> <input class="edit-title" bind:value={container.attrs.title} type="text" minlength="1" />
{:else} {:else}
{container.attrs.title} {container.attrs.title}
@@ -85,12 +81,22 @@
{/if} {/if}
<div class="v-pane" <div class="v-pane"
class:empty={children.length === 0} class:empty={children.length === 0}
use:dndzone="{{ items: children, dragDisabled, flipDurationMs }}" class:edit={$uiState.uiEditMode === "containers" && zIndex > 1}
use:dndzone="{{
items: children,
flipDurationMs,
morphDisabled: true,
dropFromOthersDisabled: zIndex === 0,
dragDisabled: zIndex === 0
}}"
on:consider="{handleConsider}" on:consider="{handleConsider}"
on:finalize="{handleFinalize}" on:finalize="{handleFinalize}"
> >
{#each children.filter(item => item.id !== SHADOW_PLACEHOLDER_ITEM_ID) as item(item.id)} {#each children.filter(item => item.id !== SHADOW_PLACEHOLDER_ITEM_ID) as item(item.id)}
<div class="animation-wrapper" class:is-executing={item.isNodeExecuting} animate:flip={{duration:flipDurationMs}}> <div class="animation-wrapper"
class:edit={$uiState.unlocked}
class:is-executing={item.isNodeExecuting}
animate:flip={{duration:flipDurationMs}}>
<svelte:self dragItem={item} zIndex={zIndex+1} /> <svelte:self dragItem={item} zIndex={zIndex+1} />
{#if item[SHADOW_ITEM_MARKER_PROPERTY_NAME]} {#if item[SHADOW_ITEM_MARKER_PROPERTY_NAME]}
<div in:fade={{duration:200, easing: cubicIn}} class='drag-item-shadow'/> <div in:fade={{duration:200, easing: cubicIn}} class='drag-item-shadow'/>
@@ -98,15 +104,17 @@
</div> </div>
{/each} {/each}
</div> </div>
{#if $uiState.unlocked} {#if $uiState.uiEditMode === "containers" && zIndex > 1}
<div class="handle handle-container" style="z-index: {zIndex}" on:mousedown={startDrag} on:touchstart={startDrag} on:mouseup={stopDrag} on:touchend={stopDrag}/> <div class="handle handle-container" style="z-index: {zIndex+100}" on:mousedown={startDrag} on:touchstart={startDrag} on:mouseup={stopDrag} on:touchend={stopDrag}/>
{/if} {/if}
</Block> </Block>
</div> </div>
{:else if widget} {:else if widget}
<div class:widget-edit-outline={$uiState.uiEditMode === "widgets" && zIndex > 1}>
<svelte:component this={getComponentForWidgetState(widgetState)} item={widgetState} /> <svelte:component this={getComponentForWidgetState(widgetState)} item={widgetState} />
{#if $uiState.unlocked} </div>
<div class="handle handle-widget" style="z-index: {zIndex}" on:mousedown={startDrag} on:touchstart={startDrag} on:mouseup={stopDrag} on:touchend={stopDrag}/> {#if $uiState.uiEditMode ==="widgets" && zIndex > 1}
<div class="handle handle-widget" style="z-index: {zIndex+100}" on:mousedown={startDrag} on:touchstart={startDrag} on:mouseup={stopDrag} on:touchend={stopDrag}/>
{/if} {/if}
{/if} {/if}
@@ -117,12 +125,16 @@
overflow: visible; overflow: visible;
display: flex; display: flex;
.edit {
min-width: 200px;
}
&.empty { &.empty {
border-width: 3px; border-width: 3px;
border-color: var(--color-grey-400); border-color: var(--color-grey-400);
border-radius: var(--block-radius); border-radius: var(--block-radius);
background: var(--color-grey-300); background: var(--color-grey-300);
min-height: 50px; min-height: 200px;
border-style: dashed; border-style: dashed;
} }
} }
@@ -134,6 +146,10 @@
height: fit-content; height: fit-content;
} }
&.container-edit-outline {
/* width: 20rem; */
}
&.horizontal { &.horizontal {
flex-wrap: wrap; flex-wrap: wrap;
gap: var(--layout-gap); gap: var(--layout-gap);
@@ -169,8 +185,11 @@
.animation-wrapper { .animation-wrapper {
position: relative; position: relative;
&:not(.edit) {
flex-grow: 1; flex-grow: 1;
} }
}
.handle { .handle {
cursor: grab; cursor: grab;
@@ -235,4 +254,22 @@
.edit-title::placeholder { .edit-title::placeholder {
color: var(--input-placeholder-color); color: var(--input-placeholder-color);
} }
.container-edit-outline > :global(.block) {
border-color: var(--color-pink-500);
border-width: 2px;
border-style: dashed !important;
margin: 0.2em;
padding: 1.2em;
}
.widget-edit-outline {
border: 2px dashed var(--color-blue-400);
margin: 0.2em;
padding: 0.2em;
}
.root-container > :global(.block) {
padding: 0px;
}
</style> </style>

View File

@@ -4,6 +4,7 @@ import type ComfyApp from "$lib/components/ComfyApp"
import type { LGraphNode, IWidget } from "@litegraph-ts/core" import type { LGraphNode, IWidget } from "@litegraph-ts/core"
import nodeState from "$lib/state/nodeState"; import nodeState from "$lib/state/nodeState";
import type { NodeStateStore } from './nodeState'; import type { NodeStateStore } from './nodeState';
import { dndzone, SHADOW_PLACEHOLDER_ITEM_ID } from 'svelte-dnd-action';
type DragItemEntry = { type DragItemEntry = {
dragItem: IDragItem, dragItem: IDragItem,
@@ -136,6 +137,8 @@ function updateChildren(parent: IDragItem, children: IDragItem[]): IDragItem[] {
const state = get(store); const state = get(store);
state.allItems[parent.id].children = children; state.allItems[parent.id].children = children;
for (const child of children) { for (const child of children) {
if (child.id === SHADOW_PLACEHOLDER_ITEM_ID)
continue;
state.allItems[child.id].parent = parent; state.allItems[child.id].parent = parent;
} }
store.set(state) store.set(state)

View File

@@ -2,11 +2,13 @@ import { writable } from 'svelte/store';
import type { Readable, Writable } from 'svelte/store'; import type { Readable, Writable } from 'svelte/store';
import type ComfyApp from "$lib/components/ComfyApp" import type ComfyApp from "$lib/components/ComfyApp"
export type UIEditMode = "disabled" | "widgets" | "containers" | "layout";
export type UIState = { export type UIState = {
app: ComfyApp, app: ComfyApp,
nodesLocked: boolean, nodesLocked: boolean,
graphLocked: boolean, graphLocked: boolean,
unlocked: boolean, uiEditMode: UIEditMode
} }
export type WritableUIStateStore = Writable<UIState>; export type WritableUIStateStore = Writable<UIState>;
@@ -14,7 +16,7 @@ const store: WritableUIStateStore = writable(
{ {
graphLocked: true, graphLocked: true,
nodesLocked: false, nodesLocked: false,
unlocked: false, uiEditMode: "disabled",
}) })
const uiStateStore: WritableUIStateStore = const uiStateStore: WritableUIStateStore =