Add bookmarks list menu. Also adds a label property to them. Think it's worth exposing it on hover as a pseudo-title?
This commit is contained in:
@@ -20,6 +20,10 @@
|
||||
"height": 16,
|
||||
"position": "top"
|
||||
},
|
||||
"bookmark_menu": {
|
||||
"enabled": true,
|
||||
"labeled_only": false
|
||||
},
|
||||
// Enables invokeExtensionsAsync for rgthree-nodes allowing other extensions to hook into the
|
||||
// nodes like the default ComfyNodes. This was not possible before Apr 2024, so it's a config
|
||||
// entry in case it causes issues. This is only for the nodeCreated event/function as of now.
|
||||
|
||||
@@ -14,6 +14,7 @@ import type {
|
||||
|
||||
declare const LiteGraph: typeof TLiteGraph;
|
||||
|
||||
const PROPERTY_LABEL = "label";
|
||||
|
||||
/**
|
||||
* A bookmark node. Can be placed anywhere in the workflow, and given a shortcut key that will
|
||||
@@ -37,6 +38,8 @@ export class Bookmark extends RgthreeBaseVirtualNode {
|
||||
override isVirtualNode = true;
|
||||
override serialize_widgets = true;
|
||||
|
||||
static "@label" = { type: "string" };
|
||||
|
||||
//@ts-ignore - TS Doesn't like us overriding a property with accessors but, too bad.
|
||||
override get _collapsed_width() {
|
||||
return this.___collapsed_width;
|
||||
@@ -55,6 +58,7 @@ export class Bookmark extends RgthreeBaseVirtualNode {
|
||||
|
||||
constructor(title = Bookmark.title) {
|
||||
super(title);
|
||||
this.properties[PROPERTY_LABEL] = "";
|
||||
this.addWidget('text', 'shortcut_key', '1', (value: string, ...args) => {
|
||||
value = value.trim()[0] || '1';
|
||||
},{
|
||||
@@ -78,6 +82,9 @@ export class Bookmark extends RgthreeBaseVirtualNode {
|
||||
// this.size[1] = Math.max(minHeight, this.size[1]);
|
||||
// }
|
||||
|
||||
get shortcutKey(): string {
|
||||
return this.widgets[0]?.value?.toLocaleLowerCase() ?? '';
|
||||
}
|
||||
|
||||
override onAdded(graph: TLGraph): void {
|
||||
window.addEventListener("keydown", this.keypressBound);
|
||||
@@ -89,13 +96,14 @@ export class Bookmark extends RgthreeBaseVirtualNode {
|
||||
|
||||
async onKeypress(event: KeyboardEvent) {
|
||||
const target = (event.target as HTMLElement)!;
|
||||
if (['input','textarea'].includes(target.localName)) {
|
||||
// Span because the properties panel uses a contenteditable <span>
|
||||
if (['input','textarea', 'span'].includes(target.localName)) {
|
||||
return;
|
||||
}
|
||||
if (event.ctrlKey || event.metaKey || event.altKey) {
|
||||
return;
|
||||
}
|
||||
if (event.key.toLocaleLowerCase() === this.widgets[0]!.value.toLocaleLowerCase()) {
|
||||
if (event.key.toLocaleLowerCase() === this.shortcutKey) {
|
||||
this.canvasToBookmark();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,6 +127,20 @@ const CONFIGURABLE: { features: ConfigurationSchema[] } = {
|
||||
"Will show a message at the top of the screen when loading a workflow that has " +
|
||||
"corrupt linking data.",
|
||||
},
|
||||
{
|
||||
key: "features.bookmark_menu.enabled",
|
||||
type: ConfigType.BOOLEAN,
|
||||
label: "Show bookmark shortcuts in context menu",
|
||||
description:
|
||||
"Will list the bookmarks in the rgthree-comfy context menu",
|
||||
subconfig: [
|
||||
{
|
||||
key: "features.bookmark_menu.labeled_only",
|
||||
type: ConfigType.BOOLEAN,
|
||||
label: "Only show explicitly labeled bookmarks (set in Properties)",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
key: "log_level",
|
||||
type: ConfigType.STRING,
|
||||
|
||||
@@ -22,6 +22,7 @@ import { NodeTypesString } from "./constants.js";
|
||||
import { RgthreeProgressBar } from "rgthree/common/progress_bar.js";
|
||||
import { RgthreeConfigDialog } from "./config.js";
|
||||
import { iconGear, iconReplace, iconStarFilled, logoRgthree } from "rgthree/common/media/svgs.js";
|
||||
import type { Bookmark } from './bookmark';
|
||||
|
||||
declare const LiteGraph: typeof TLiteGraph;
|
||||
declare const LGraphCanvas: typeof TLGraphCanvas;
|
||||
@@ -496,6 +497,38 @@ class Rgthree extends EventTarget {
|
||||
}
|
||||
const rerouteLabel = selectedNodes.length ? "selected" : "all";
|
||||
|
||||
function getBookmarks(): ContextMenuItem[] {
|
||||
const showBookmarks = CONFIG_SERVICE.getFeatureValue("bookmark_menu.enabled");
|
||||
|
||||
if (!showBookmarks) { return []; }
|
||||
|
||||
const bookmarkNodes = graph._nodes.filter((n): n is Bookmark => n.type == NodeTypesString.BOOKMARK);
|
||||
const labeledOnly = CONFIG_SERVICE.getFeatureValue("bookmark_menu.labeled_only");
|
||||
|
||||
const bookmarksToList = bookmarkNodes
|
||||
.filter((n) => !labeledOnly || n.properties['label'])
|
||||
// Sort by shortcut key.
|
||||
// I could see an option to sort by either Shortcut, Label, or Position.
|
||||
.sort((a, b) => a.shortcutKey.localeCompare(b.shortcutKey));
|
||||
const bookmarkMenuItems = bookmarksToList.map((n) => ({
|
||||
content: `[${n.shortcutKey}] ${n.properties['label']}`,
|
||||
className: "rgthree-contextmenu-item",
|
||||
callback: () => {
|
||||
n.canvasToBookmark();
|
||||
},
|
||||
}));
|
||||
return [
|
||||
{
|
||||
content: "🔖 Bookmarks",
|
||||
disabled: true,
|
||||
className: "rgthree-contextmenu-item rgthree-contextmenu-label",
|
||||
},
|
||||
...bookmarkMenuItems,
|
||||
]
|
||||
}
|
||||
|
||||
const bookmarkMenuItems = getBookmarks();
|
||||
|
||||
return [
|
||||
{
|
||||
content: "Actions",
|
||||
@@ -535,6 +568,7 @@ class Rgthree extends EventTarget {
|
||||
})();
|
||||
},
|
||||
},
|
||||
...bookmarkMenuItems,
|
||||
{
|
||||
content: "More...",
|
||||
disabled: true,
|
||||
|
||||
@@ -19,6 +19,7 @@ export class Bookmark extends RgthreeBaseVirtualNode {
|
||||
this.___collapsed_width = 0;
|
||||
this.isVirtualNode = true;
|
||||
this.serialize_widgets = true;
|
||||
this.properties[PROPERTY_LABEL] = "";
|
||||
this.addWidget('text', 'shortcut_key', '1', (value, ...args) => {
|
||||
value = value.trim()[0] || '1';
|
||||
}, {
|
||||
@@ -42,7 +43,7 @@ export class Bookmark extends RgthreeBaseVirtualNode {
|
||||
}
|
||||
async onKeypress(event) {
|
||||
const target = event.target;
|
||||
if (['input', 'textarea'].includes(target.localName)) {
|
||||
if (['input', 'textarea', 'span'].includes(target.localName)) {
|
||||
return;
|
||||
}
|
||||
if (event.ctrlKey || event.metaKey || event.altKey) {
|
||||
@@ -72,6 +73,7 @@ export class Bookmark extends RgthreeBaseVirtualNode {
|
||||
Bookmark.type = NodeTypesString.BOOKMARK;
|
||||
Bookmark.title = NodeTypesString.BOOKMARK;
|
||||
Bookmark.slot_start_y = -20;
|
||||
Bookmark["@label"] = { type: "string" };
|
||||
app.registerExtension({
|
||||
name: "rgthree.Bookmark",
|
||||
registerCustomNodes() {
|
||||
|
||||
@@ -102,6 +102,19 @@ const CONFIGURABLE = {
|
||||
description: "Will show a message at the top of the screen when loading a workflow that has " +
|
||||
"corrupt linking data.",
|
||||
},
|
||||
{
|
||||
key: "features.bookmark_menu.enabled",
|
||||
type: ConfigType.BOOLEAN,
|
||||
label: "Show bookmark shortcuts in context menu",
|
||||
description: "Will list the bookmarks in the rgthree-comfy context menu",
|
||||
subconfig: [
|
||||
{
|
||||
key: "features.bookmark_menu.labeled_only",
|
||||
type: ConfigType.BOOLEAN,
|
||||
label: "Only show explicitly labeled bookmarks (set in Properties)",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
key: "log_level",
|
||||
type: ConfigType.STRING,
|
||||
|
||||
@@ -308,6 +308,33 @@ class Rgthree extends EventTarget {
|
||||
rerouteNodes = graph._nodes.filter((n) => n.type == "Reroute");
|
||||
}
|
||||
const rerouteLabel = selectedNodes.length ? "selected" : "all";
|
||||
function getBookmarks() {
|
||||
const showBookmarks = CONFIG_SERVICE.getFeatureValue("bookmark_menu.enabled");
|
||||
if (!showBookmarks) {
|
||||
return [];
|
||||
}
|
||||
const bookmarkNodes = graph._nodes.filter((n) => n.type == NodeTypesString.BOOKMARK);
|
||||
const labeledOnly = CONFIG_SERVICE.getFeatureValue("bookmark_menu.labeled_only");
|
||||
const bookmarksToList = bookmarkNodes
|
||||
.filter((n) => !labeledOnly || n.properties['label'])
|
||||
.sort((a, b) => a.shortcutKey.localeCompare(b.shortcutKey));
|
||||
const bookmarkMenuItems = bookmarksToList.map((n) => ({
|
||||
content: `[${n.shortcutKey}] ${n.properties['label']}`,
|
||||
className: "rgthree-contextmenu-item",
|
||||
callback: () => {
|
||||
n.canvasToBookmark();
|
||||
},
|
||||
}));
|
||||
return [
|
||||
{
|
||||
content: "🔖 Bookmarks",
|
||||
disabled: true,
|
||||
className: "rgthree-contextmenu-item rgthree-contextmenu-label",
|
||||
},
|
||||
...bookmarkMenuItems,
|
||||
];
|
||||
}
|
||||
const bookmarkMenuItems = getBookmarks();
|
||||
return [
|
||||
{
|
||||
content: "Actions",
|
||||
@@ -346,6 +373,7 @@ class Rgthree extends EventTarget {
|
||||
})();
|
||||
},
|
||||
},
|
||||
...bookmarkMenuItems,
|
||||
{
|
||||
content: "More...",
|
||||
disabled: true,
|
||||
|
||||
Reference in New Issue
Block a user