From 863e747dbde0ef7eae2a8e91ec95cb17c57acf76 Mon Sep 17 00:00:00 2001 From: pythongosssss <125205205+pythongosssss@users.noreply.github.com> Date: Wed, 8 Mar 2023 20:03:37 +0000 Subject: [PATCH] Added simple settings dialog Updated to use css vars for colors --- web/scripts/ui.js | 89 +++++++++++++++++++++++++++++++++++++++++++++-- web/style.css | 38 +++++++++++++++----- 2 files changed, 115 insertions(+), 12 deletions(-) diff --git a/web/scripts/ui.js b/web/scripts/ui.js index 0bfb6927..2c5a75f3 100644 --- a/web/scripts/ui.js +++ b/web/scripts/ui.js @@ -13,6 +13,11 @@ function $el(tag, propsOrChildren, children) { const cb = propsOrChildren.$; delete propsOrChildren.$; + if (propsOrChildren.style) { + Object.assign(element.style, propsOrChildren.style); + delete propsOrChildren.style; + } + Object.assign(element, propsOrChildren); if (children) { element.append(...children); @@ -54,6 +59,80 @@ class ComfyDialog { } } +class ComfySettingsDialog extends ComfyDialog { + constructor() { + super(); + this.element.classList.add("comfy-settings"); + this.settings = []; + } + + addSetting({ id, name, type, defaultValue, onChange }) { + if (!id) { + throw new Error("Settings must have an ID"); + } + if (this.settings.find((s) => s.id === id)) { + throw new Error("Setting IDs must be unique"); + } + + const settingId = "Comfy.Settings." + id; + const v = localStorage[settingId]; + let value = v == null ? defaultValue : JSON.parse(v); + + // Trigger initial setting of value + if (onChange) { + onChange(value, undefined); + } + + this.settings.push({ + render: () => { + const setter = (v) => { + if (onChange) { + onChange(v, value); + } + localStorage[settingId] = JSON.stringify(v); + value = v; + }; + + if (typeof type === "function") { + return type(name, setter); + } + + switch (type) { + case "boolean": + return $el("div", [ + $el("label", { textContent: name || id }, [ + $el("input", { + type: "checkbox", + checked: !!value, + oninput: (e) => { + setter(e.target.checked); + }, + }), + ]), + ]); + default: + console.warn("Unsupported setting type, defaulting to text"); + return $el("div", [ + $el("label", { textContent: name || id }, [ + $el("input", { + value, + oninput: (e) => { + setter(e.target.value); + }, + }), + ]), + ]); + } + }, + }); + } + + show() { + super.show(); + this.textElement.replaceChildren(...this.settings.map((s) => s.render())); + } +} + class ComfyList { #type; #text; @@ -150,6 +229,7 @@ export class ComfyUI { constructor(app) { this.app = app; this.dialog = new ComfyDialog(); + this.settings = new ComfySettingsDialog(); this.queue = new ComfyList("Queue"); this.history = new ComfyList("History"); @@ -162,7 +242,7 @@ export class ComfyUI { const fileInput = $el("input", { type: "file", accept: ".json,image/png", - style: "display: none", + style: { display: "none" }, parent: document.body, onchange: () => { app.handleFile(fileInput.files[0]); @@ -170,7 +250,10 @@ export class ComfyUI { }); this.menuContainer = $el("div.comfy-menu", { parent: document.body }, [ - $el("span", { $: (q) => (this.queueSize = q) }), + $el("div", { style: { overflow: "hidden", position: "relative", width: "100%" } }, [ + $el("span", { $: (q) => (this.queueSize = q) }), + $el("button.comfy-settings-btn", { textContent: "⚙️", onclick: () => this.settings.show() }), + ]), $el("button.comfy-queue-btn", { textContent: "Queue Prompt", onclick: () => app.queuePrompt(0) }), $el("div.comfy-menu-btns", [ $el("button", { textContent: "Queue Front", onclick: () => app.queuePrompt(-1) }), @@ -202,7 +285,7 @@ export class ComfyUI { const a = $el("a", { href: url, download: "workflow.json", - style: "display: none", + style: { display: "none" }, parent: document.body, }); a.click(); diff --git a/web/style.css b/web/style.css index c262b2f4..52a8a9c6 100644 --- a/web/style.css +++ b/web/style.css @@ -1,8 +1,22 @@ +:root { + --fg-color: #000; + --bg-color: #fff; +} + +@media (prefers-color-scheme: dark) { + :root { + --fg-color: #fff; + --bg-color: #202020; + } +} + body { width: 100vw; height: 100vh; margin: 0; overflow: hidden; + background-color: var(--bg-color); + color: var(--fg-color); } #graph-canvas { @@ -11,7 +25,8 @@ body { } .comfy-multiline-input { - background-color: #ffffff; + background-color: var(--bg-color); + color: var(--fg-color); overflow: hidden; overflow-y: auto; padding: 2px; @@ -73,6 +88,7 @@ body { top: 50%; right: 0%; background-color: white; + color: #000; text-align: center; z-index: 100; width: 170px; @@ -133,14 +149,18 @@ body { font-size: 12px; } -@media (prefers-color-scheme: dark) { - body { - background-color: #202020; - } - .comfy-multiline-input { - background-color: #202020; - color: white; - } +button.comfy-settings-btn { + font-size: 12px; + padding: 0; + position: absolute; + right: 0; + border: none; +} + +.comfy-modal.comfy-settings { + background-color: var(--bg-color); + color: var(--fg-color); + z-index: 99; } @media only screen and (max-height: 850px) {