Refactor widget wrappers
This commit is contained in:
@@ -64,9 +64,12 @@
|
|||||||
|
|
||||||
(window as any).app = app;
|
(window as any).app = app;
|
||||||
|
|
||||||
let graphPaneDiv = containerElem.querySelector(".canvas-wrapper").parentNode as HTMLDivNode;
|
let wrappers = containerElem.querySelectorAll<HTMLDivNode>(".pane-wrapper")
|
||||||
graphPaneDiv.ontransitionend = () => {
|
for (const wrapper of wrappers) {
|
||||||
app.resizeCanvas()
|
const paneNode = wrapper.parentNode; // get the node inside the <Pane/>
|
||||||
|
paneNode.ontransitionend = () => {
|
||||||
|
app.resizeCanvas()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
@@ -80,14 +83,14 @@
|
|||||||
<ComfyUIPane bind:this={uiPane} {app} />
|
<ComfyUIPane bind:this={uiPane} {app} />
|
||||||
</Pane>
|
</Pane>
|
||||||
<Pane bind:size={graphSize}>
|
<Pane bind:size={graphSize}>
|
||||||
<div class="canvas-wrapper">
|
<div class="canvas-wrapper pane-wrapper">
|
||||||
<canvas id="graph-canvas" />
|
<canvas id="graph-canvas" />
|
||||||
</div>
|
</div>
|
||||||
</Pane>
|
</Pane>
|
||||||
</Splitpanes>
|
</Splitpanes>
|
||||||
</Pane>
|
</Pane>
|
||||||
<Pane bind size={sidebarSize}>
|
<Pane bind:size={sidebarSize}>
|
||||||
<div>
|
<div class="sidebar-wrapper pane-wrapper">
|
||||||
Sidebar
|
Sidebar
|
||||||
</div>
|
</div>
|
||||||
</Pane>
|
</Pane>
|
||||||
@@ -139,6 +142,11 @@
|
|||||||
background-color: #333;
|
background-color: #333;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.sidebar-wrapper {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.dropzone {
|
.dropzone {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
display: none;
|
display: none;
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { onDestroy } from "svelte";
|
import { onDestroy } from "svelte";
|
||||||
import { Block, BlockTitle } from "@gradio/atoms";
|
import { Block, BlockTitle } from "@gradio/atoms";
|
||||||
import { Dropdown, Range, TextBox } from "@gradio/form";
|
|
||||||
import { Move } from 'radix-icons-svelte';
|
import { Move } from 'radix-icons-svelte';
|
||||||
|
import ComboWidget from "./widgets/ComboWidget.svelte";
|
||||||
|
import RangeWidget from "./widgets/RangeWidget.svelte";
|
||||||
|
import TextWidget from "./widgets/TextWidget.svelte";
|
||||||
import widgetState from "$lib/stores/widgetState";
|
import widgetState from "$lib/stores/widgetState";
|
||||||
|
|
||||||
import { dndzone, SHADOW_ITEM_MARKER_PROPERTY_NAME } from 'svelte-dnd-action';
|
import { dndzone, SHADOW_ITEM_MARKER_PROPERTY_NAME } from 'svelte-dnd-action';
|
||||||
@@ -59,47 +61,11 @@
|
|||||||
</label>
|
</label>
|
||||||
{#each $widgetState[id] as item, i}
|
{#each $widgetState[id] as item, i}
|
||||||
{#if item.widget.type == "combo"}
|
{#if item.widget.type == "combo"}
|
||||||
<div class="wrapper">
|
<ComboWidget {item} />
|
||||||
<Dropdown
|
|
||||||
bind:value={item.value}
|
|
||||||
choices={item.widget.options.values}
|
|
||||||
multiselect={false}
|
|
||||||
max_choices={1},
|
|
||||||
label={item.widget.name}
|
|
||||||
show_label={true}
|
|
||||||
disabled={item.widget.options.values.length === 0}
|
|
||||||
on:change
|
|
||||||
on:select
|
|
||||||
on:blur
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
{:else if item.widget.type == "number"}
|
{:else if item.widget.type == "number"}
|
||||||
<div class="wrapper">
|
<RangeWidget {item} />
|
||||||
<Range
|
|
||||||
bind:value={item.value}
|
|
||||||
minimum={item.widget.options.min}
|
|
||||||
maximum={item.widget.options.max}
|
|
||||||
step={item.widget.options.step}
|
|
||||||
label={item.widget.name}
|
|
||||||
show_label={true}
|
|
||||||
on:change
|
|
||||||
on:release
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
{:else if item.widget.type == "text"}
|
{:else if item.widget.type == "text"}
|
||||||
<div class="wrapper">
|
<TextWidget {item} />
|
||||||
<TextBox
|
|
||||||
bind:value={item.value}
|
|
||||||
label={item.widget.name}
|
|
||||||
lines={item.widget.options.multiline ? 5 : 1}
|
|
||||||
max_lines={item.widget.options.multiline ? 5 : 1}
|
|
||||||
show_label={true}
|
|
||||||
on:change
|
|
||||||
on:submit
|
|
||||||
on:blur
|
|
||||||
on:select
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
{/if}
|
{/if}
|
||||||
{#if dragItem[SHADOW_ITEM_MARKER_PROPERTY_NAME]}
|
{#if dragItem[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'/>
|
||||||
@@ -145,9 +111,4 @@
|
|||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.wrapper {
|
|
||||||
padding: 2px;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -12,25 +12,34 @@
|
|||||||
|
|
||||||
export let totalId = 0;
|
export let totalId = 0;
|
||||||
|
|
||||||
|
function addUIForNewNode(node: LGraphNode) {
|
||||||
|
let minWidgetCount = 2 ** 64;
|
||||||
|
let minIndex = 0;
|
||||||
|
let state = get(widgetState);
|
||||||
|
for (let i = 0; i < dragItemss.length; i++) {
|
||||||
|
let widgetCount = 0;
|
||||||
|
for (let j = 0; j < dragItemss[i].length; j++) {
|
||||||
|
const nodeID = dragItemss[i][j].node.id;
|
||||||
|
widgetCount += state[nodeID].length;
|
||||||
|
}
|
||||||
|
if (widgetCount < minWidgetCount) {
|
||||||
|
minWidgetCount = widgetCount
|
||||||
|
minIndex = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dragItemss[minIndex].push({ id: totalId++, node: node });
|
||||||
|
}
|
||||||
|
|
||||||
$: if(app && !dragConfigured) {
|
$: if(app && !dragConfigured) {
|
||||||
dragConfigured = true;
|
dragConfigured = true;
|
||||||
app.eventBus.on("nodeAdded", (node: LGraphNode) => {
|
app.eventBus.on("nodeAdded", addUIForNewNode);
|
||||||
let minWidgetCount = 2 ** 64;
|
}
|
||||||
let minIndex = 0;
|
|
||||||
let state = get(widgetState);
|
/*
|
||||||
for (let i = 0; i < dragItemss.length; i++) {
|
* Serialize UI panel order so it can be restored when workflow is loaded
|
||||||
let widgetCount = 0;
|
*/
|
||||||
for (let j = 0; j < dragItemss[i].length; j++) {
|
function getUIState(): any {
|
||||||
const nodeID = dragItemss[i][j].node.id;
|
|
||||||
widgetCount += state[nodeID].length;
|
|
||||||
}
|
|
||||||
if (widgetCount < minWidgetCount) {
|
|
||||||
minWidgetCount = widgetCount
|
|
||||||
minIndex = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dragItemss[minIndex].push({ id: totalId++, node: node });
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
29
src/lib/components/widgets/ComboWidget.svelte
Normal file
29
src/lib/components/widgets/ComboWidget.svelte
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import type { WidgetUIState } from "$lib/stores/widgetState";
|
||||||
|
import { Dropdown } from "@gradio/form";
|
||||||
|
export let item: WidgetUIState | null = null;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="wrapper">
|
||||||
|
{#if item}
|
||||||
|
<Dropdown
|
||||||
|
bind:value={item.value}
|
||||||
|
choices={item.widget.options.values}
|
||||||
|
multiselect={false}
|
||||||
|
max_choices={1}
|
||||||
|
label={item.widget.name}
|
||||||
|
show_label={true}
|
||||||
|
disabled={item.widget.options.values.length === 0}
|
||||||
|
on:change
|
||||||
|
on:select
|
||||||
|
on:blur
|
||||||
|
/>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.wrapper {
|
||||||
|
padding: 2px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
27
src/lib/components/widgets/RangeWidget.svelte
Normal file
27
src/lib/components/widgets/RangeWidget.svelte
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import type { WidgetUIState } from "$lib/stores/widgetState";
|
||||||
|
import { Range } from "@gradio/form";
|
||||||
|
export let item: WidgetUIState | null = null;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="wrapper">
|
||||||
|
{#if item}
|
||||||
|
<Range
|
||||||
|
bind:value={item.value}
|
||||||
|
minimum={item.widget.options.min}
|
||||||
|
maximum={item.widget.options.max}
|
||||||
|
step={item.widget.options.step}
|
||||||
|
label={item.widget.name}
|
||||||
|
show_label={true}
|
||||||
|
on:change
|
||||||
|
on:release
|
||||||
|
/>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.wrapper {
|
||||||
|
padding: 2px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
28
src/lib/components/widgets/TextWidget.svelte
Normal file
28
src/lib/components/widgets/TextWidget.svelte
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import type { WidgetUIState } from "$lib/stores/widgetState";
|
||||||
|
import { TextBox } from "@gradio/form";
|
||||||
|
export let item: WidgetUIState | null = null;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="wrapper">
|
||||||
|
{#if item}
|
||||||
|
<TextBox
|
||||||
|
bind:value={item.value}
|
||||||
|
label={item.widget.name}
|
||||||
|
lines={item.widget.options.multiline ? 5 : 1}
|
||||||
|
max_lines={item.widget.options.multiline ? 5 : 1}
|
||||||
|
show_label={true}
|
||||||
|
on:change
|
||||||
|
on:submit
|
||||||
|
on:blur
|
||||||
|
on:select
|
||||||
|
/>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.wrapper {
|
||||||
|
padding: 2px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user