Add support for bookmarks in sub graphs.

This commit is contained in:
rgthree
2025-08-16 15:50:20 -04:00
parent 006cb572fa
commit 5b45e105c0
7 changed files with 55 additions and 35 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
[project]
name = "rgthree-comfy"
description = "Making ComfyUI more comfortable."
version = "1.0.2508161414"
version = "1.0.2508161550"
license = { file = "LICENSE" }
dependencies = []
+14 -2
View File
@@ -1,10 +1,18 @@
import type {LGraph, LGraphCanvas, LGraphNode, Point, CanvasMouseEvent} from "@comfyorg/frontend";
import type {
LGraph,
LGraphCanvas,
LGraphNode,
Point,
CanvasMouseEvent,
Subgraph,
} from "@comfyorg/frontend";
import {app} from "scripts/app.js";
import {RgthreeBaseVirtualNode} from "./base_node.js";
import {SERVICE as KEY_EVENT_SERVICE} from "./services/key_events_services.js";
import {NodeTypesString} from "./constants.js";
import {getClosestOrSelf, query} from "rgthree/common/utils_dom.js";
import {wait} from "rgthree/common/shared_utils.js";
/**
* A bookmark node. Can be placed anywhere in the workflow, and given a shortcut key that will
@@ -119,8 +127,12 @@ export class Bookmark extends RgthreeBaseVirtualNode {
return false;
}
canvasToBookmark() {
async canvasToBookmark() {
const canvas = app.canvas as LGraphCanvas;
if (this.graph !== app.canvas.getCurrentGraph()) {
canvas.openSubgraph(this.graph as Subgraph);
await wait(16);
}
// ComfyUI seemed to break us again, but couldn't repro. No reason to not check, I guess.
// https://github.com/rgthree/rgthree-comfy/issues/71
if (canvas?.ds?.offset) {
+12 -17
View File
@@ -17,10 +17,11 @@ import type {ComfyApp} from "@comfyorg/frontend";
import {app} from "scripts/app.js";
import {api} from "scripts/api.js";
import {SERVICE as CONFIG_SERVICE} from "./services/config_service.js";
import {SERVICE as BOOKMARKS_SERVICE} from "./services/bookmarks_services.js";
import {SERVICE as KEY_EVENT_SERVICE} from "./services/key_events_services.js";
import {WorkflowLinkFixer} from "rgthree/common/link_fixer.js";
import {injectCss, wait} from "rgthree/common/shared_utils.js";
import {replaceNode, waitForCanvas, waitForGraph} from "./utils.js";
import {replaceNode, traverseNodesDepthFirst, waitForCanvas, waitForGraph} from "./utils.js";
import {NodeTypesString, addRgthree, getNodeTypeStrings, stripRgthree} from "./constants.js";
import {RgthreeProgressBar} from "rgthree/common/progress_bar.js";
import {RgthreeConfigDialog} from "./config.js";
@@ -998,22 +999,16 @@ class Rgthree extends EventTarget {
}
function getBookmarks(): IContextMenuValue[] {
const graph: TLGraph = app.graph;
const bookmarks = BOOKMARKS_SERVICE.getCurrentBookmarks();
const bookmarkItems = bookmarks.map((n) => ({
content: `[${n.shortcutKey}] ${n.title}`,
className: "rgthree-contextmenu-item",
callback: () => {
n.canvasToBookmark();
},
}));
// Sorts by Title.
// I could see an option to sort by either Shortcut, Title, or Position.
const bookmarks = graph._nodes
.filter((n): n is Bookmark => n.type === NodeTypesString.BOOKMARK)
.sort((a, b) => a.title.localeCompare(b.title))
.map((n) => ({
content: `[${n.shortcutKey}] ${n.title}`,
className: "rgthree-contextmenu-item",
callback: () => {
n.canvasToBookmark();
},
}));
return !bookmarks.length
return !bookmarkItems.length
? []
: [
{
@@ -1021,7 +1016,7 @@ function getBookmarks(): IContextMenuValue[] {
disabled: true,
className: "rgthree-contextmenu-item rgthree-contextmenu-label",
},
...bookmarks,
...bookmarkItems,
];
}
@@ -2,15 +2,20 @@ import type {Bookmark} from "../bookmark.js";
import {app} from "scripts/app.js";
import {NodeTypesString} from "../constants.js";
import {traverseNodesDepthFirst} from "../utils.js";
class BookmarksService {
/**
* Gets a list of the current bookmarks within the current workflow.
*/
getCurrentBookmarks() {
return app.graph._nodes
.filter((n): n is Bookmark => n.type === NodeTypesString.BOOKMARK)
.sort((a, b) => a.title.localeCompare(b.title));
getCurrentBookmarks(): Bookmark[] {
const bookmarks: Bookmark[] = [];
traverseNodesDepthFirst(app.graph.nodes, (n) => {
if (n.type === NodeTypesString.BOOKMARK) {
bookmarks.push(n as Bookmark);
}
});
return bookmarks.sort((a, b) => a.title.localeCompare(b.title));
}
}
+6 -1
View File
@@ -3,6 +3,7 @@ import { RgthreeBaseVirtualNode } from "./base_node.js";
import { SERVICE as KEY_EVENT_SERVICE } from "./services/key_events_services.js";
import { NodeTypesString } from "./constants.js";
import { getClosestOrSelf, query } from "../../rgthree/common/utils_dom.js";
import { wait } from "../../rgthree/common/shared_utils.js";
export class Bookmark extends RgthreeBaseVirtualNode {
get _collapsed_width() {
return this.___collapsed_width;
@@ -72,9 +73,13 @@ export class Bookmark extends RgthreeBaseVirtualNode {
}
return false;
}
canvasToBookmark() {
async canvasToBookmark() {
var _a, _b;
const canvas = app.canvas;
if (this.graph !== app.canvas.getCurrentGraph()) {
canvas.openSubgraph(this.graph);
await wait(16);
}
if ((_a = canvas === null || canvas === void 0 ? void 0 : canvas.ds) === null || _a === void 0 ? void 0 : _a.offset) {
canvas.ds.offset[0] = -this.pos[0] + 16;
canvas.ds.offset[1] = -this.pos[1] + 40;
+5 -7
View File
@@ -1,6 +1,7 @@
import { app } from "../../scripts/app.js";
import { api } from "../../scripts/api.js";
import { SERVICE as CONFIG_SERVICE } from "./services/config_service.js";
import { SERVICE as BOOKMARKS_SERVICE } from "./services/bookmarks_services.js";
import { SERVICE as KEY_EVENT_SERVICE } from "./services/key_events_services.js";
import { WorkflowLinkFixer } from "../../rgthree/common/link_fixer.js";
import { injectCss, wait } from "../../rgthree/common/shared_utils.js";
@@ -700,18 +701,15 @@ class Rgthree extends EventTarget {
}
}
function getBookmarks() {
const graph = app.graph;
const bookmarks = graph._nodes
.filter((n) => n.type === NodeTypesString.BOOKMARK)
.sort((a, b) => a.title.localeCompare(b.title))
.map((n) => ({
const bookmarks = BOOKMARKS_SERVICE.getCurrentBookmarks();
const bookmarkItems = bookmarks.map((n) => ({
content: `[${n.shortcutKey}] ${n.title}`,
className: "rgthree-contextmenu-item",
callback: () => {
n.canvasToBookmark();
},
}));
return !bookmarks.length
return !bookmarkItems.length
? []
: [
{
@@ -719,7 +717,7 @@ function getBookmarks() {
disabled: true,
className: "rgthree-contextmenu-item rgthree-contextmenu-label",
},
...bookmarks,
...bookmarkItems,
];
}
export const rgthree = new Rgthree();
+8 -3
View File
@@ -1,10 +1,15 @@
import { app } from "../../../scripts/app.js";
import { NodeTypesString } from "../constants.js";
import { traverseNodesDepthFirst } from "../utils.js";
class BookmarksService {
getCurrentBookmarks() {
return app.graph._nodes
.filter((n) => n.type === NodeTypesString.BOOKMARK)
.sort((a, b) => a.title.localeCompare(b.title));
const bookmarks = [];
traverseNodesDepthFirst(app.graph.nodes, (n) => {
if (n.type === NodeTypesString.BOOKMARK) {
bookmarks.push(n);
}
});
return bookmarks.sort((a, b) => a.title.localeCompare(b.title));
}
}
export const SERVICE = new BookmarksService();