Merge pull request #473 from chrisgoringe/8.0

8.0
This commit is contained in:
chrisgoringe
2026-07-20 15:49:03 +10:00
committed by GitHub
11 changed files with 291 additions and 113 deletions
+14
View File
@@ -35,6 +35,14 @@ Drop [this workflow](docs/UE_example.json) into Comfy, and take a look at how it
# Common Questions # Common Questions
## Known issues with Nodes 2.0
See [8.0.1 issues list](https://github.com/chrisgoringe/cg-use-everywhere/milestone/23)
- Can't rename inputs and outputs any more. [471](https://github.com/chrisgoringe/cg-use-everywhere/issues/471)
- Work around - turn node into a subgraph and rename internally.
- Exporting doesn't work. [458](https://github.com/chrisgoringe/cg-use-everywhere/issues/458)
- The UE connectable submenu closes every time you change something. [450](https://github.com/chrisgoringe/cg-use-everywhere/issues/450)
## How do I get positive and negative conditionings to work? ## How do I get positive and negative conditionings to work?
Connect both to a single UE node, and then rename the inputs. See [here](https://github.com/chrisgoringe/cg-use-everywhere/issues/317#issuecomment-3663225670). Connect both to a single UE node, and then rename the inputs. See [here](https://github.com/chrisgoringe/cg-use-everywhere/issues/317#issuecomment-3663225670).
@@ -51,6 +59,11 @@ Yes. See Combo Clone node [here](https://github.com/chrisgoringe/cg-use-everywhe
# Recent Changes # Recent Changes
## 8.0
- Updated to work with Nodes 2.0. Lots of changes, anticipate some issues! Please check [8.0.1 issues list](https://github.com/chrisgoringe/cg-use-everywhere/milestone/23) before reporting a bug.
## 7.8 ## 7.8
- Added regex match of outputs to the repeated types options - Added regex match of outputs to the repeated types options
@@ -474,6 +487,7 @@ The following people have contributed code or helpful discussions, without which
- [TinyTerra](https://github.com/TinyTerra) - [TinyTerra](https://github.com/TinyTerra)
- [bananasss00](https://github.com/bananasss00) - [bananasss00](https://github.com/bananasss00)
- [JorgeR81](https://github.com/JorgeR81) - [JorgeR81](https://github.com/JorgeR81)
- [kevgeoleo](https://github.com/kevgeoleo)
Feel free to [make suggestions, or implement features](https://github.com/chrisgoringe/cg-use-everywhere/issues) to get your name added here! Feel free to [make suggestions, or implement features](https://github.com/chrisgoringe/cg-use-everywhere/issues) to get your name added here!
+5 -18
View File
@@ -32,12 +32,10 @@ export class FloatingWindow extends HTMLElement {
this.style.display = 'flex'; this.style.display = 'flex';
const tt = document.getElementById('ue_tooltip') const tt = document.getElementById('ue_tooltip')
if (tt) tt.style.display = 'none' if (tt) tt.style.display = 'none'
this.showing = true if (this.firstFocusable) requestAnimationFrame(() => this.firstFocusable.focus())
}
hide() {
this.style.display = 'none'
this.showing = false
} }
hide() { this.style.display = 'none' }
set_title(title) { set_title(title) {
this.header.innerText = title this.header.innerText = title
} }
@@ -101,20 +99,9 @@ export class FloatingWindow extends HTMLElement {
} }
setup_focus_trap() { setup_focus_trap() {
this.firstFocusable = null
this.lastFocusable = null
const focusableEls = this.querySelectorAll('a[href]:not([disabled]), button:not([disabled]), textarea:not([disabled]), input[type="text"]:not([disabled]), input[type="radio"]:not([disabled]), input[type="checkbox"]:not([disabled]), select:not([disabled])') const focusableEls = this.querySelectorAll('a[href]:not([disabled]), button:not([disabled]), textarea:not([disabled]), input[type="text"]:not([disabled]), input[type="radio"]:not([disabled]), input[type="checkbox"]:not([disabled]), select:not([disabled])')
if (focusableEls?.length == 0) return this.firstFocusable = (focusableEls.length>0) ? focusableEls[0] : null
this.lastFocusable = (focusableEls.length>0) ? focusableEls[focusableEls.length - 1] : null
this.firstFocusable = focusableEls[0] ?? null
this.lastFocusable = focusableEls[focusableEls.length - 1] ?? null
if (this.firstFocusable) {
setTimeout(() => {
this.firstFocusable.focus()
}, 0);
}
} }
} }
+2 -1
View File
@@ -9,7 +9,8 @@ class Shared {
this.graph_currently_modified = 0 this.graph_currently_modified = 0
this.graphAnalyser = undefined this.graphAnalyser = undefined
this.linkRenderController = undefined this.linkRenderController = undefined
this.report_keys = [ 'graph_being_configured', 'in_queuePrompt', 'in_graphToPrompt', 'in_midst_of_change', 'graph_currently_modified' ] this.report_keys = [ 'graph_being_configured', 'in_queuePrompt', 'in_graphToPrompt', 'in_midst_of_change', 'graph_currently_modified' ],
this.mouseOverNode = null
} }
} }
+13 -10
View File
@@ -4,6 +4,7 @@ import { app } from "../../scripts/app.js";
import { create } from "./use_everywhere_utilities.js"; import { create } from "./use_everywhere_utilities.js";
import { edit_window } from "./floating_window.js"; import { edit_window } from "./floating_window.js";
import { settingsCache } from "./use_everywhere_cache.js"; import { settingsCache } from "./use_everywhere_cache.js";
import { shared } from "./shared.js";
const HOVERTIME = 500 const HOVERTIME = 500
var hover_node_id = null var hover_node_id = null
@@ -11,20 +12,21 @@ var mouse_pos = [0,0]
const ue_tooltip_element = create('span', 'ue_tooltip', document.body, {id:'ue_tooltip'}) const ue_tooltip_element = create('span', 'ue_tooltip', document.body, {id:'ue_tooltip'})
function show_tooltip() { function show_tooltip(nodeover) {
ue_tooltip_element.style.display = "block" ue_tooltip_element.style.display = "block"
ue_tooltip_element.style.left = `${mouse_pos[0]+10}px` ue_tooltip_element.style.left = `${mouse_pos[0]+10}px`
ue_tooltip_element.style.top = `${mouse_pos[1]+5}px` ue_tooltip_element.style.top = `${mouse_pos[1]+5}px`
ue_tooltip_element.innerHTML = "" ue_tooltip_element.innerHTML = ""
ue_tooltip_element.appendChild(describe_restrictions(app.canvas.node_over)) ue_tooltip_element.appendChild(describe_restrictions(nodeover))
ue_tooltip_element.showing = true ue_tooltip_element.showing = true
} }
function show_on_hover() { function show_on_hover() {
if (!tooltipable()) return const nodeover = app.canvas?.node_over || shared.mouseOverNode;
if (!tooltipable(nodeover)) return
if (mouse_pos[0]==app.canvas.mouse[0] && mouse_pos[1]==app.canvas.mouse[1]) { if (mouse_pos[0]==app.canvas.mouse[0] && mouse_pos[1]==app.canvas.mouse[1]) {
show_tooltip() show_tooltip(nodeover)
} else { } else {
maybe_show_tooltip() maybe_show_tooltip()
} }
@@ -35,21 +37,22 @@ function hide_tooltip() {
ue_tooltip_element.showing = false ue_tooltip_element.showing = false
} }
function tooltipable() { function tooltipable(nodeover) {
if ( if (
(!app.canvas?.node_over) || (!nodeover) ||
( edit_window.showing) || ( edit_window.style.display != 'none' ) ||
(!settingsCache.getSettingValue('Use Everywhere.Graphics.tooltips')) || (!settingsCache.getSettingValue('Use Everywhere.Graphics.tooltips')) ||
(!any_restrictions(app.canvas.node_over)) (!any_restrictions(nodeover))
) return false ) return false
return true return true
} }
export function maybe_show_tooltip() { export function maybe_show_tooltip() {
if (!tooltipable()) return hide_tooltip() const nodeover = app.canvas?.node_over || shared.mouseOverNode;
if (!tooltipable(nodeover)) return hide_tooltip()
mouse_pos = [...app.canvas.mouse] mouse_pos = [...app.canvas.mouse]
hover_node_id = app.canvas.node_over.id hover_node_id = nodeover.id
setTimeout(show_on_hover, HOVERTIME) setTimeout(show_on_hover, HOVERTIME)
} }
+154
View File
@@ -0,0 +1,154 @@
import { app } from "../../scripts/app.js";
import { titlebar_color } from "./ue_shared_ui.js";
import { node_can_broadcast, is_able_to_broadcast, running_nodes2 } from "./use_everywhere_utilities.js";
import { settingsCache } from "./use_everywhere_cache.js";
import { visible_graph } from "./use_everywhere_subgraph_utils.js";
import { shared } from "./shared.js";
import { Logger } from "./use_everywhere_utilities.js";
import { edit_restrictions } from "./ue_properties_editor.js";
function nodeElement(node) {
return document.querySelector(`div[data-node-id='${node.id}']`)
}
function headerElement(node) {
return nodeElement(node)?.querySelector(`div[data-testid="node-header-${node.id}"]`)
}
export function addMouseEvents(node) {
Logger.log_detail(`addMouseEvents called for ${node.id}`)
if (!running_nodes2()) return Logger.log_problem(`Not running nodes2`)
const element = nodeElement(node)
if (!element) return Logger.log_info(`Could not find node element for ${node.id}`)
if (element._ue_mouse_events_for_nodes2_added) return Logger.log_detail(`Already added`)
Logger.log_info(`adding MouseEvents for ${node.id}`)
element.addEventListener("mouseenter", () => {
node.mouseOver = true
shared.mouseOverNode = node
shared.linkRenderController.node_over_changed()
})
element.addEventListener("mouseleave", () => {
node.mouseOver = false
shared.mouseOverNode = null
shared.linkRenderController.node_over_changed()
})
const header = headerElement(node)
element.addEventListener("click", (e) => {
if (e.detail==2) {
if (header?.contains(e.target)) return;
if (node_can_broadcast(node)) {
edit_restrictions(node)
}
}
})
element._ue_mouse_events_for_nodes2_added = true
}
export function nodes2_overlay(ctx) {
if (!shared.linkRenderController.ue_list) return;
ctx.save()
app.canvas.ds.toCanvasContext(ctx)
visible_graph().nodes.forEach((node) => {
n2_titlebar_additions(node, ctx)
n2_highlight_connections(node, ctx)
n2_widgets(node)
});
ctx.restore()
}
const highlight_color = "rgba(255, 255, 255, 0.8)"
const radius = 9
const blur = 5
function n2_highlight_connections(node, ctx) {
if (!(settingsCache.getSettingValue('Use Everywhere.Graphics.highlight')
&& node.inputs)) return;
ctx.save()
ctx.lineWidth = 1
ctx.shadowColor = "white"
ctx.strokeStyle = highlight_color
ctx.shadowBlur = blur
const ue_list = shared.linkRenderController.ue_list
/* highlight all connected inputs */
ue_list.all_connected_inputs(node)
.filter((uec)=>uec.control_node)
.filter((uec)=>node.inputs[uec.input_index])
.forEach((uec) => {
const pos2 = node.getSlotPosition(uec.input_index, true)
ctx.beginPath();
ctx.arc(pos2[0], pos2[1], radius, 0, 2*Math.PI);
ctx.stroke();
});
/* Highlight connected outputs */
const sending_slots = ue_list.all_sending_slots(node)
node.outputs.forEach((output,i) => {
if (is_able_to_broadcast(node, output.name) && sending_slots.has(i)) {
const pos2 = node.getSlotPosition(i, false);
ctx.beginPath();
ctx.arc(pos2[0], pos2[1], radius, 0, 2*Math.PI);
ctx.stroke();
}
})
/* Highlight inputs with ambiguities */
ctx.lineWidth = 2
ctx.strokeStyle = "red"
ctx.shadowBlur = 0
shared.graphAnalyser.ambiguities.filter((ambiguity)=>(ambiguity.id==node.id)).forEach((ambiguity)=>{
const index = node.inputs.findIndex((input)=>(input.name==ambiguity.input))
if (index>=0) {
const pos2 = node.getSlotPosition(index, true);
ctx.beginPath();
ctx.moveTo(pos2[0]-radius-4,pos2[1]-radius)
ctx.lineTo(pos2[0],pos2[1]+radius)
ctx.moveTo(pos2[0]-radius-4,pos2[1]+radius)
ctx.lineTo(pos2[0],pos2[1]-radius)
ctx.stroke();
}
})
ctx.restore()
}
const badge_size = 12
const titlebar_height = 30
const nudge = 5
function n2_titlebar_additions(node, ctx) {
if (!node_can_broadcast(node)) return;
ctx.save()
const color = titlebar_color(node)
const offset_x = nudge + node.pos[0]
const offset_y = nudge - titlebar_height + node.pos[1]
ctx.lineWidth = badge_size;
ctx.strokeStyle = color;
ctx.beginPath();
ctx.arc(offset_x, offset_y, badge_size/2, 0, 2*Math.PI);
ctx.stroke();
ctx.lineWidth = 1;
ctx.strokeStyle = "rgba(0, 0, 0, 1)";
ctx.beginPath();
ctx.arc(offset_x, offset_y, badge_size, 0, 2*Math.PI);
ctx.stroke();
ctx.restore()
}
function n2_widgets(node) {
const widgets = nodeElement(node)?.querySelector("div[data-testid='node-widgets']")
if (!widgets) return;
const connected = shared.linkRenderController.ue_list.all_connected_inputs(node)
Array.from(widgets.children).forEach((widget_el, index) => {
const input_el = widget_el.querySelector("input")
const widget = node.widgets[index]
if (!input_el || !widget) return;
const wname = widget.label;
const inputindex = node.inputs.findIndex((input)=>(input.label==wname))
const connection = connected.find((uec)=>(uec.input_index==inputindex))
input_el.disabled = !!connection
})
}
+1 -1
View File
@@ -15,7 +15,7 @@ function create_element(tag, parent, options={}) {
return elem return elem
} }
export function edit_restrictions(a,b,c,d, node) { // a,b,c,d parameters are ignored - called from menu system export function edit_restrictions(node) { // a,b,c,d parameters are ignored - called from menu system
edit_window.set_body(create_editor_html(node)) edit_window.set_body(create_editor_html(node))
edit_window.set_title(`Restrictions for node #${node.id}`) edit_window.set_title(`Restrictions for node #${node.id}`)
edit_window.maybe_move_to(app.canvas.mouse[0]+10, app.canvas.mouse[1]+10) edit_window.maybe_move_to(app.canvas.mouse[0]+10, app.canvas.mouse[1]+10)
+10
View File
@@ -0,0 +1,10 @@
import { any_restrictions } from "./ue_properties.js";
import { shared } from "./shared.js";
export function titlebar_color(node) {
const restricted = any_restrictions(node);
const sending = shared.linkRenderController.node_sending_anywhere(node);
return restricted ? ( sending ? "rgba(255, 255, 72, 1)" : "rgba(255, 255, 72, 0.35)" ) :
( sending ? "rgba(72, 255, 72, 1)" : "rgba(72, 255, 72, 0.35)" );
}
+57 -48
View File
@@ -3,7 +3,7 @@ import { api } from "../../scripts/api.js";
import { shared, deferred_actions } from "./shared.js"; import { shared, deferred_actions } from "./shared.js";
import { is_UEnode, inject, Logger, graphConverter, create, node_can_broadcast } from "./use_everywhere_utilities.js"; import { is_UEnode, Logger, graphConverter, create, node_can_broadcast, running_nodes2 } from "./use_everywhere_utilities.js";
import { title_bar_additions, LinkRenderController } from "./use_everywhere_ui.js"; import { title_bar_additions, LinkRenderController } from "./use_everywhere_ui.js";
import { GraphAnalyser } from "./use_everywhere_graph_analysis.js"; import { GraphAnalyser } from "./use_everywhere_graph_analysis.js";
import { canvas_menu_settings, SETTINGS, add_extra_menu_items } from "./use_everywhere_settings.js"; import { canvas_menu_settings, SETTINGS, add_extra_menu_items } from "./use_everywhere_settings.js";
@@ -15,56 +15,48 @@ import { edit_restrictions } from "./ue_properties_editor.js";
import { language_changed } from "./i18n.js"; import { language_changed } from "./i18n.js";
import { input_changed, fix_inputs } from "./connections.js"; import { input_changed, fix_inputs } from "./connections.js";
import { comboclone_on_connection, is_combo_clone } from "./combo_clone.js"; import { comboclone_on_connection, is_combo_clone } from "./combo_clone.js";
import { ue_callbacks } from "./recursive_callbacks.js"; import { ue_callbacks, for_all_nodes } from "./recursive_callbacks.js";
import { nodes2_overlay, addMouseEvents } from "./ue_nodes2.js";
/* /*
All nodes need the onDrawTitleBar method so they can show if they are broadcasting UE data. All nodes (pre Nodes 2.0) need the onDrawTitleBar method so they can show if they are broadcasting UE data.
*/ */
function add_methods_to_all_nodes(node) { function add_methods_to_all_nodes(node) {
if (node.ue_methods_added) return Logger.log_problem(`Node ${node.id} already has UE methods added`); if (node._ue_mouse_events_added) return Logger.log_problem(`Node ${node.id} already has UE methods added`);
try { try {
add_extra_menu_items(node, inject_outdating_into_object_method) // right click menu additions add_extra_menu_items(node) // right click menu additions
const original_onDrawForeground = node.onDrawForeground; if (running_nodes2()) {
node.onDrawForeground = function(ctx) { // this is handled in addMouseEvents in ue_nodes2.js
original_onDrawForeground?.apply(this, arguments); // because they need to be added to the dom element
title_bar_additions(this, ctx, this.title_height || LiteGraph.NODE_TITLE_HEIGHT) } else {
const original_onMouseEnter = node.onMouseEnter;
node.onMouseEnter = function(e) {
original_onMouseEnter?.apply(this, arguments)
shared.linkRenderController.node_over_changed()
}
const original_onMouseLeave = node.onMouseLeave;
node.onMouseLeave = function(e) {
original_onMouseLeave?.apply(this, arguments)
shared.linkRenderController.node_over_changed()
}
const original_onDrawTitle = node.onDrawTitle;
node.onDrawTitle = function(ctx) {
title_bar_additions(this, ctx)
original_onDrawTitle?.apply(this, arguments)
}
} }
const original_onMouseEnter = node.onMouseEnter; node._ue_mouse_events_added = true;
node.onMouseEnter = function(e) {
original_onMouseEnter?.apply(this, arguments)
shared.linkRenderController.node_over_changed()
}
const original_onMouseLeave = node.onMouseLeave;
node.onMouseLeave = function(e) {
original_onMouseLeave?.apply(this, arguments)
shared.linkRenderController.node_over_changed()
}
node.ue_methods_added = true;
} catch (e) { } catch (e) {
Logger.log_error(e); Logger.log_error(e);
} }
} }
/*
Inject a call to linkRenderController.mark_list_link_outdated into a method with name methodname on all objects in the array
If object is undefined, do nothing.
The injection is added at the end of the existing method (if the method didn't exist, it is created).
*/
function inject_outdating_into_objects(array, methodname, tracetext) {
if (array) {
array.forEach((object) => { inject_outdating_into_object_method(object, methodname, tracetext); })
}
}
function inject_outdating_into_object_method(object, methodname, tracetext) {
if (object) inject(object, methodname, tracetext, shared.linkRenderController.mark_link_list_outdated, shared.linkRenderController);
}
app.registerExtension({ app.registerExtension({
name: "cg.customnodes.use_everywhere", name: "cg.customnodes.use_everywhere",
settings: SETTINGS, settings: SETTINGS,
@@ -155,7 +147,11 @@ app.registerExtension({
try { try {
shared.linkRenderController.pause('drawFrontCanvas') shared.linkRenderController.pause('drawFrontCanvas')
const v = original_drawNode.apply(this, arguments); const v = original_drawNode.apply(this, arguments);
shared.linkRenderController.highlight_ue_connections(node, ctx); if (running_nodes2()) {
addMouseEvents(node)
} else {
shared.linkRenderController.highlight_ue_connections(node, ctx);
}
if (node._last_seen_bg !== node.bgcolor) shared.linkRenderController.mark_link_list_outdated(); if (node._last_seen_bg !== node.bgcolor) shared.linkRenderController.mark_link_list_outdated();
node._last_seen_bg = node.bgcolor node._last_seen_bg = node.bgcolor
return v return v
@@ -166,6 +162,7 @@ app.registerExtension({
} }
} }
/* /*
Before drawing the canvas, temporarily disable all the ue connected widgets Before drawing the canvas, temporarily disable all the ue connected widgets
so they get rendered as greyed out. so they get rendered as greyed out.
@@ -250,10 +247,8 @@ app.registerExtension({
try { try {
shared.in_graphToPrompt += 1 shared.in_graphToPrompt += 1
if (shared.in_queuePrompt || app.ui.settings.getSettingValue("Use Everywhere.Options.always_modify_graph")) { if (shared.in_queuePrompt || app.ui.settings.getSettingValue("Use Everywhere.Options.always_modify_graph")) {
//Logger.log_shared('In graphToPrompt (going to modify graph):')
return await shared.graphAnalyser.call_function_with_modified_graph( original_graphToPrompt, arguments ) return await shared.graphAnalyser.call_function_with_modified_graph( original_graphToPrompt, arguments )
} else { } else {
//Logger.log_shared('In graphToPrompt (not going to modify graph):')
return await original_graphToPrompt.apply(this, arguments) return await original_graphToPrompt.apply(this, arguments)
} }
} finally { } finally {
@@ -299,21 +294,35 @@ app.registerExtension({
setTimeout(()=>{app.canvas.setDirty(true,true)},200) setTimeout(()=>{app.canvas.setDirty(true,true)},200)
}) })
app.canvas.canvas.addEventListener('litegraph:canvas', (e)=>{ if (!running_nodes2()) {
if (e?.detail?.subType=='node-double-click') { app.canvas.canvas.addEventListener('litegraph:canvas', (e)=>{
const node = e.detail.node if (e?.detail?.subType=='node-double-click') {
if (node_can_broadcast(node)) { const node = e.detail.node
if (app.ui.settings.getSettingValue('Comfy.Node.DoubleClickTitleToEdit') && e.detail.originalEvent.canvasY<node.pos[1]) return if (node_can_broadcast(node)) {
edit_restrictions(null, null, null, null, node) if (app.ui.settings.getSettingValue('Comfy.Node.DoubleClickTitleToEdit') && e.detail.originalEvent.canvasY<node.pos[1]) return
edit_restrictions(node)
}
} }
} })
}) }
const original_onDrawForeground = app.canvas.onDrawForeground const original_onDrawForeground = app.canvas.onDrawForeground
app.canvas.onDrawForeground = function(ctx, visible_area) { app.canvas.onDrawForeground = function(ctx, visible_area) {
if (original_onDrawForeground) original_onDrawForeground.apply(this, arguments) if (original_onDrawForeground) original_onDrawForeground.apply(this, arguments)
if (this.subgraph) shared.linkRenderController.highlight_subgraph_node_connections.bind(shared.linkRenderController)(this.subgraph, ctx) if (this.subgraph) shared.linkRenderController.highlight_subgraph_node_connections.bind(shared.linkRenderController)(this.subgraph, ctx)
} }
/*
In nodes2, can we do all the ue graphics in an overlay?
*/
const original_onDrawOverlay = app.canvas.onDrawOverlay
app.canvas.onDrawOverlay = function(ctx) {
original_onDrawOverlay?.apply(this, arguments)
if (running_nodes2()) {
nodes2_overlay(ctx)
}
}
/* /*
Midifications to app.ui.settings Midifications to app.ui.settings
+13 -10
View File
@@ -1,6 +1,6 @@
import { app } from "../../scripts/app.js"; import { app } from "../../scripts/app.js";
import { convert_to_links } from "./use_everywhere_apply.js"; import { convert_to_links } from "./use_everywhere_apply.js";
import { Logger, is_UEnode, node_can_broadcast, is_able_to_broadcast } from "./use_everywhere_utilities.js"; import { Logger, is_UEnode, node_can_broadcast, is_able_to_broadcast, running_nodes2 } from "./use_everywhere_utilities.js";
import { settingsCache } from "./use_everywhere_cache.js"; import { settingsCache } from "./use_everywhere_cache.js";
import { visible_graph } from "./use_everywhere_subgraph_utils.js"; import { visible_graph } from "./use_everywhere_subgraph_utils.js";
import { edit_restrictions } from "./ue_properties_editor.js"; import { edit_restrictions } from "./ue_properties_editor.js";
@@ -125,6 +125,7 @@ ui_update_settings.forEach((id) => {
}) })
function show_connectable(submenu_root, node) { function show_connectable(submenu_root, node) {
if (running_nodes2()) return; // nodes2 has broken this...
node.inputs.forEach((input, i) => { node.inputs.forEach((input, i) => {
const current_element = submenu_root?.querySelector(`:nth-child(${i+1})`); const current_element = submenu_root?.querySelector(`:nth-child(${i+1})`);
if (current_element) current_element.style.borderLeft = (is_connectable(node,input.name)) ? "2px solid #484" : ""; if (current_element) current_element.style.borderLeft = (is_connectable(node,input.name)) ? "2px solid #484" : "";
@@ -164,15 +165,22 @@ function widget_ue_submenu(value, options, e, menu, node) {
node.inputs node.inputs
.filter(i => !i.hidden) .filter(i => !i.hidden)
.filter(i => !i.name?.includes('$$')) .filter(i => !i.name?.includes('$$'))
.forEach((input) => { label_to_name[input.label || input.name] = input.name }); .forEach((input) => {
var label = input.label || input.name
if (running_nodes2()) {
label = (is_connectable(node, input.name) ? "☑ " : "☐ ") + label
}
label_to_name[label] = input.name
});
const submenu = new LiteGraph.ContextMenu( const submenu = new LiteGraph.ContextMenu(
Object.keys(label_to_name), Object.keys(label_to_name),
{ event: e, callback: function (label) { { event: e, callback: function (label) {
const parentElement = this?.parentElement
const name = label_to_name[label]; const name = label_to_name[label];
toggle_connectable(node, name); toggle_connectable(node, name);
shared.linkRenderController.mark_link_list_outdated(); shared.linkRenderController.mark_link_list_outdated();
show_connectable(this.parentElement, node) show_connectable(parentElement, node)
return true; // keep open return true; // keep open
}, },
parentMenu: menu, node:node} parentMenu: menu, node:node}
@@ -212,10 +220,7 @@ function output_ue_submenu(value, options, e, menu, node) {
show_broadcasting(submenu.root, node) show_broadcasting(submenu.root, node)
} }
export function add_extra_menu_items(node) {
export function add_extra_menu_items(node, ioio) {
if (node.ue_extra_menu_items_added) return
const getExtraMenuOptions = node.getExtraMenuOptions; const getExtraMenuOptions = node.getExtraMenuOptions;
node.getExtraMenuOptions = function(_, options) { node.getExtraMenuOptions = function(_, options) {
getExtraMenuOptions?.apply(this, arguments); getExtraMenuOptions?.apply(this, arguments);
@@ -227,17 +232,15 @@ export function add_extra_menu_items(node, ioio) {
add_input_and_output_settings(options, node) add_input_and_output_settings(options, node)
} }
options.push(null); options.push(null);
ioio(options,'callback',`menu option on ${this.id}`);
} }
node.ue_extra_menu_items_added = true node.ue_extra_menu_items_added = true
} }
function add_restrictions_and_convert(options, node) { function add_restrictions_and_convert(options, node) {
options.push( options.push(
{ {
content: "Edit restrictions", content: "Edit restrictions",
callback: edit_restrictions, callback: async () => { edit_restrictions(node) },
} }
) )
+18 -10
View File
@@ -1,11 +1,11 @@
import { Logger, get_real_node, Pausable, node_can_broadcast, is_able_to_broadcast } from "./use_everywhere_utilities.js"; import { Logger, get_real_node, Pausable, node_can_broadcast, is_able_to_broadcast, running_nodes2 } from "./use_everywhere_utilities.js";
import { app } from "../../scripts/app.js"; import { app } from "../../scripts/app.js";
import { settingsCache } from "./use_everywhere_cache.js"; import { settingsCache } from "./use_everywhere_cache.js";
import { in_visible_graph, visible_graph } from "./use_everywhere_subgraph_utils.js"; import { in_visible_graph, visible_graph } from "./use_everywhere_subgraph_utils.js";
import { maybe_show_tooltip } from "./tooltip_window.js"; import { maybe_show_tooltip } from "./tooltip_window.js";
import { is_connectable } from "./use_everywhere_settings.js"; import { is_connectable } from "./use_everywhere_settings.js";
import { shared } from "./shared.js"; import { shared } from "./shared.js";
import { any_restrictions } from "./ue_properties.js"; import { titlebar_color } from "./ue_shared_ui.js";
export function nodes_in_my_group(node) { export function nodes_in_my_group(node) {
const nodes_in = new Set(); const nodes_in = new Set();
@@ -77,13 +77,9 @@ export function nodes_not_my_color(node, already_limited_to) {
return [...nodes_in]; return [...nodes_in];
} }
export function title_bar_additions(node, ctx, title_height) { export function title_bar_additions(node, ctx, title_height=30) {
if (node_can_broadcast(node)) { if (node_can_broadcast(node)) {
const restricted = any_restrictions(node); const color = titlebar_color(node)
const sending = shared.linkRenderController.node_sending_anywhere(node);
const color = restricted ? ( sending ? "rgba(255, 255, 72, 1)" : "rgba(255, 255, 72, 0.35)" ) :
( sending ? "rgba(72, 255, 72, 1)" : "rgba(72, 255, 72, 0.35)" );
const offset_x = (node.subgraph) ? 5 : 5 const offset_x = (node.subgraph) ? 5 : 5
const offset_y = (node.subgraph) ? 4 : 5 const offset_y = (node.subgraph) ? 4 : 5
@@ -331,6 +327,12 @@ export class LinkRenderController extends Pausable {
} }
} }
mouse_over_connected_node(ue_connection) {
if (app.canvas.node_over && this.node_in_ueconnection(ue_connection, app.canvas.node_over.id)) return true;
if (ue_connection.control_node?.mouseOver) return true;
if (ue_connection.sending_to?.mouseOver) return true;
}
_render_all_ue_links(ctx) { _render_all_ue_links(ctx) {
if (!this._list_ready()) return; if (!this._list_ready()) return;
this.last_used_ue_list = this.ue_list; this.last_used_ue_list = this.ue_list;
@@ -349,7 +351,13 @@ export class LinkRenderController extends Pausable {
shared.graphAnalyser.ambiguities.forEach((ambiguity)=>{ shared.graphAnalyser.ambiguities.forEach((ambiguity)=>{
ambiguity.matches.forEach((m)=>{ ambiguity.matches.forEach((m)=>{
if (app.canvas.node_over == m.node || ambiguity.id==-20 && ambiguity.graph.outputNode?.isPointerOver) { if (
m.node.selected
|| app.canvas.graph.getNodeById(m.id)?.selected
|| app.canvas.node_over == m.node
|| m.node.mouseOver
|| ambiguity.id==-20 && ambiguity.graph.outputNode?.isPointerOver
) {
this._render_ue_link( this._render_ue_link(
{ {
graph : ambiguity.graph, graph : ambiguity.graph,
@@ -369,7 +377,7 @@ export class LinkRenderController extends Pausable {
any_links = true; any_links = true;
var show = false; var show = false;
if ( mode==4 ) show = true; if ( mode==4 ) show = true;
if ( (mode==2 || mode==3) && app.canvas.node_over && this.node_in_ueconnection(ue_connection, app.canvas.node_over.id) ) show = true; if ( (mode==2 || mode==3) && this.mouse_over_connected_node(ue_connection) ) show = true;
if ( (mode==1 || mode==3) && this.any_node_in_ueconnection(ue_connection, app.canvas.selected_nodes)) show = true; if ( (mode==1 || mode==3) && this.any_node_in_ueconnection(ue_connection, app.canvas.selected_nodes)) show = true;
show = show && in_visible_graph(ue_connection.control_node) && in_visible_graph(ue_connection.sending_to); show = show && in_visible_graph(ue_connection.control_node) && in_visible_graph(ue_connection.sending_to);
+4 -15
View File
@@ -5,6 +5,10 @@ import { i18n } from "./i18n.js";
import { ue_callbacks } from "./recursive_callbacks.js"; import { ue_callbacks } from "./recursive_callbacks.js";
import { shared } from "./shared.js"; import { shared } from "./shared.js";
export function running_nodes2() {
return app.ui.settings.getSettingValue('Comfy.VueNodes.Enabled')
}
export function create( tag, clss, parent, properties ) { export function create( tag, clss, parent, properties ) {
const nd = document.createElement(tag); const nd = document.createElement(tag);
if (clss) clss.split(" ").forEach((s) => nd.classList.add(s)) if (clss) clss.split(" ").forEach((s) => nd.classList.add(s))
@@ -290,21 +294,6 @@ export function node_can_broadcast(node) {
return (node.properties?.ue_convert || is_UEnode(node)) return (node.properties?.ue_convert || is_UEnode(node))
} }
/*
Inject a call into a method on object with name methodname.
The injection is added at the end of the existing method (if the method didn't exist, it is created)
injectionthis and injectionarguments are passed into the apply call (as the this and the arguments)
*/
export function inject(object, methodname, tracetext, injection, injectionthis, injectionarguments) {
const original = object[methodname];
object[methodname] = function() {
original?.apply(this, arguments);
injection.apply(injectionthis, injectionarguments);
}
}
export class Pausable { export class Pausable {
constructor(name) { constructor(name) {
this.name = name this.name = name