diff --git a/src/lib/components/ComfyUIPane.svelte b/src/lib/components/ComfyUIPane.svelte
index 88f5bac..9593381 100644
--- a/src/lib/components/ComfyUIPane.svelte
+++ b/src/lib/components/ComfyUIPane.svelte
@@ -47,6 +47,34 @@
console.warn($layoutState)
}
+ function groupWidgets() {
+ const items = layoutState.getCurrentSelection()
+ $layoutState.currentSelection = []
+ layoutState.groupItems(items)
+ }
+
+ let canUngroup = false;
+ let isDeleteGroup = false;
+ $: canUngroup = $layoutState.currentSelection.length === 1
+ && layoutState.getCurrentSelection()[0].type === "container"
+ $: if (canUngroup) {
+ const dragItem = layoutState.getCurrentSelection()[0];
+ const entry = $layoutState.allItems[dragItem.id];
+ isDeleteGroup = entry.children.length === 0
+ }
+ else {
+ isDeleteGroup = false
+ }
+
+ function ungroup() {
+ const item = layoutState.getCurrentSelection()[0]
+ if (item.type !== "container")
+ return;
+
+ $layoutState.currentSelection = []
+ layoutState.ungroup(item as ContainerLayout)
+ }
+
let menuPos = { x: 0, y: 0 };
let showMenu = false;
@@ -78,20 +106,13 @@
{#if showMenu}
{/if}
diff --git a/src/lib/components/WidgetContainer.svelte b/src/lib/components/WidgetContainer.svelte
index 3aa9c66..7c09386 100644
--- a/src/lib/components/WidgetContainer.svelte
+++ b/src/lib/components/WidgetContainer.svelte
@@ -26,7 +26,14 @@
const flipDurationMs = 100;
$: if (dragItem) {
- if (dragItem.type === "container") {
+ if (!$layoutState.allItems[dragItem.id]) {
+ dragItem = null;
+ widget = null;
+ widgetState = null;
+ children = null;
+ container = null;
+ }
+ else if (dragItem.type === "container") {
container = dragItem as ContainerLayout;
children = $layoutState.allItems[dragItem.id].children;
widget = null;
@@ -54,11 +61,16 @@
};
const startDrag = (evt: MouseEvent) => {
- if (evt.button === 2)
- return;
-
const dragItemId: string = evt.target.dataset["dragItemId"];
+
+ if (evt.button !== 0) {
+ if ($layoutState.currentSelection.length <= 1 && !$layoutState.isMenuOpen)
+ $layoutState.currentSelection = [dragItemId]
+ return;
+ }
+
const item = $layoutState.allItems[dragItemId].dragItem
+
if (evt.ctrlKey) {
const index = $layoutState.currentSelection.indexOf(item.id)
if (index === -1)
@@ -103,7 +115,6 @@
1}
- class:is-executing={$queueState.runningNodeId && $queueState.runningNodeId === container.attrs.associatedNode}
use:dndzone="{{
items: children,
flipDurationMs,
@@ -137,6 +148,10 @@
class:selected={$uiState.uiEditMode !== "disabled" && $layoutState.currentSelection.includes(widget.id)}
class:is-executing={$queueState.runningNodeId && $queueState.runningNodeId == widget.attrs.associatedNode}
>
+ {#if widget.attrs.associatedNode}
+ {@const node = $nodeState[widget.attrs.associatedNode].node}
+ ({node.type})
+ {/if}
{#if showHandles}
@@ -261,12 +276,12 @@
}
.edit-title-label {
+ z-index: 10000;
position: relative;
- z-index: var(--layer-1);
}
.edit-title {
- z-index: var(--layer-1);
+ z-index: 10000;
display: block;
position: relative;
outline: none !important;
diff --git a/src/lib/stores/layoutState.ts b/src/lib/stores/layoutState.ts
index fbf5ce8..4edd1f3 100644
--- a/src/lib/stores/layoutState.ts
+++ b/src/lib/stores/layoutState.ts
@@ -48,12 +48,15 @@ export interface WidgetLayout extends IDragItem {
type DragItemID = string;
type LayoutStateOps = {
- addContainer: (parentId: DragItemID, attrs: Partial) => ContainerLayout,
+ addContainer: (parentId: DragItemID, attrs: Partial, index: number) => ContainerLayout,
+ addWidget: (parentId: DragItemID, node: LGraphNode, widget: IWidget, attrs: Partial, index: number) => WidgetLayout,
findDefaultContainerForInsertion: () => ContainerLayout | null,
- addWidget: (parentId: DragItemID, node: LGraphNode, widget: IWidget, attrs: Partial) => WidgetLayout,
updateChildren: (parent: IDragItem, children: IDragItem[]) => IDragItem[],
nodeAdded: (node: LGraphNode) => void,
nodeRemoved: (node: LGraphNode) => void,
+ groupItems: (dragItems: IDragItem[]) => ContainerLayout,
+ ungroup: (container: ContainerLayout) => void,
+ getCurrentSelection: () => IDragItem[],
clear: () => void,
resetLayout: () => void,
}
@@ -87,7 +90,7 @@ function findDefaultContainerForInsertion(): ContainerLayout | null {
return null
}
-function addContainer(parentId: DragItemID | null, attrs: Partial = {}): ContainerLayout {
+function addContainer(parentId: DragItemID | null, attrs: Partial = {}, index: number = -1): ContainerLayout {
const state = get(store);
const dragItem: ContainerLayout = {
type: "container",
@@ -106,13 +109,16 @@ function addContainer(parentId: DragItemID | null, attrs: Partial =
state.allItems[dragItem.id] = entry;
if (parent) {
parent.children ||= []
- parent.children.push(dragItem)
+ if (index)
+ parent.children.splice(index, 0, dragItem)
+ else
+ parent.children.push(dragItem)
}
store.set(state)
return dragItem;
}
-function addWidget(parentId: DragItemID, node: LGraphNode, widget: IWidget, attrs: Partial = {}): WidgetLayout {
+function addWidget(parentId: DragItemID, node: LGraphNode, widget: IWidget, attrs: Partial = {}, index: number = -1): WidgetLayout {
const state = get(store);
const dragItem: WidgetLayout = {
type: "widget",
@@ -132,21 +138,25 @@ function addWidget(parentId: DragItemID, node: LGraphNode, widget: IWidget state.allItems[id].dragItem)
+}
+
+function groupItems(dragItems: IDragItem[]): ContainerLayout {
+ if (dragItems.length === 0)
+ return;
+
+ const state = get(store)
+ const parent = state.allItems[dragItems[0].id].parent || findDefaultContainerForInsertion();
+
+ if (parent === null || parent.type !== "container")
+ return;
+
+ let index = undefined;
+ if (parent) {
+ const indexFound = state.allItems[parent.id].children.indexOf(dragItems[0])
+ if (indexFound !== -1)
+ index = indexFound
+ }
+
+ const container = addContainer(parent.id, { title: "Group" }, index)
+
+ for (const item of dragItems) {
+ moveItem(item, container)
+ }
+
+ store.set(state)
+ return container
+}
+
+function ungroup(container: ContainerLayout) {
+ const state = get(store)
+
+ const parent = state.allItems[container.id].parent;
+ if (!parent || parent.type !== "container") {
+ console.warn("No parent to ungroup into!", container)
+ return;
+ }
+
+ let index = undefined;
+ const parentChildren = state.allItems[parent.id].children;
+ const indexFound = parentChildren.indexOf(container)
+ if (indexFound !== -1)
+ index = indexFound
+
+ const containerEntry = state.allItems[container.id]
+ console.debug("[layoutState] About to ungroup", containerEntry, parent, parentChildren, index)
+
+ const children = [...containerEntry.children]
+ for (const item of children) {
+ moveItem(item, parent as ContainerLayout, index)
+ }
+
+ removeEntry(state, container.id)
+
+ console.debug("[layoutState] Ungrouped", containerEntry, parent, parentChildren, index)
+
+ store.set(state)
+}
+
function clear() {
}
@@ -214,7 +317,7 @@ function resetLayout() {
// TODO
}
-const uiStateStore: WritableLayoutStateStore =
+const layoutStateStore: WritableLayoutStateStore =
{
...store,
addContainer,
@@ -223,7 +326,10 @@ const uiStateStore: WritableLayoutStateStore =
updateChildren,
nodeAdded,
nodeRemoved,
+ getCurrentSelection,
+ groupItems,
+ ungroup,
clear,
resetLayout
}
-export default uiStateStore;
+export default layoutStateStore;