@@ -35,6 +35,14 @@ Drop [this workflow](docs/UE_example.json) into Comfy, and take a look at how it
|
||||
|
||||
# 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?
|
||||
|
||||
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
|
||||
|
||||
## 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
|
||||
|
||||
- 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)
|
||||
- [bananasss00](https://github.com/bananasss00)
|
||||
- [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!
|
||||
|
||||
|
||||
+5
-18
@@ -32,12 +32,10 @@ export class FloatingWindow extends HTMLElement {
|
||||
this.style.display = 'flex';
|
||||
const tt = document.getElementById('ue_tooltip')
|
||||
if (tt) tt.style.display = 'none'
|
||||
this.showing = true
|
||||
}
|
||||
hide() {
|
||||
this.style.display = 'none'
|
||||
this.showing = false
|
||||
if (this.firstFocusable) requestAnimationFrame(() => this.firstFocusable.focus())
|
||||
}
|
||||
hide() { this.style.display = 'none' }
|
||||
|
||||
set_title(title) {
|
||||
this.header.innerText = title
|
||||
}
|
||||
@@ -101,20 +99,9 @@ export class FloatingWindow extends HTMLElement {
|
||||
}
|
||||
|
||||
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])')
|
||||
if (focusableEls?.length == 0) return
|
||||
|
||||
this.firstFocusable = focusableEls[0] ?? null
|
||||
this.lastFocusable = focusableEls[focusableEls.length - 1] ?? null
|
||||
|
||||
if (this.firstFocusable) {
|
||||
setTimeout(() => {
|
||||
this.firstFocusable.focus()
|
||||
}, 0);
|
||||
}
|
||||
this.firstFocusable = (focusableEls.length>0) ? focusableEls[0] : null
|
||||
this.lastFocusable = (focusableEls.length>0) ? focusableEls[focusableEls.length - 1] : null
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -9,7 +9,8 @@ class Shared {
|
||||
this.graph_currently_modified = 0
|
||||
this.graphAnalyser = 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
@@ -4,6 +4,7 @@ import { app } from "../../scripts/app.js";
|
||||
import { create } from "./use_everywhere_utilities.js";
|
||||
import { edit_window } from "./floating_window.js";
|
||||
import { settingsCache } from "./use_everywhere_cache.js";
|
||||
import { shared } from "./shared.js";
|
||||
|
||||
const HOVERTIME = 500
|
||||
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'})
|
||||
|
||||
function show_tooltip() {
|
||||
function show_tooltip(nodeover) {
|
||||
ue_tooltip_element.style.display = "block"
|
||||
ue_tooltip_element.style.left = `${mouse_pos[0]+10}px`
|
||||
ue_tooltip_element.style.top = `${mouse_pos[1]+5}px`
|
||||
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
|
||||
}
|
||||
|
||||
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]) {
|
||||
show_tooltip()
|
||||
show_tooltip(nodeover)
|
||||
} else {
|
||||
maybe_show_tooltip()
|
||||
}
|
||||
@@ -35,21 +37,22 @@ function hide_tooltip() {
|
||||
ue_tooltip_element.showing = false
|
||||
}
|
||||
|
||||
function tooltipable() {
|
||||
function tooltipable(nodeover) {
|
||||
if (
|
||||
(!app.canvas?.node_over) ||
|
||||
( edit_window.showing) ||
|
||||
(!nodeover) ||
|
||||
( edit_window.style.display != 'none' ) ||
|
||||
(!settingsCache.getSettingValue('Use Everywhere.Graphics.tooltips')) ||
|
||||
(!any_restrictions(app.canvas.node_over))
|
||||
(!any_restrictions(nodeover))
|
||||
) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
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]
|
||||
hover_node_id = app.canvas.node_over.id
|
||||
hover_node_id = nodeover.id
|
||||
setTimeout(show_on_hover, HOVERTIME)
|
||||
}
|
||||
+154
@@ -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
|
||||
})
|
||||
}
|
||||
@@ -15,7 +15,7 @@ function create_element(tag, parent, options={}) {
|
||||
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_title(`Restrictions for node #${node.id}`)
|
||||
edit_window.maybe_move_to(app.canvas.mouse[0]+10, app.canvas.mouse[1]+10)
|
||||
|
||||
@@ -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
@@ -3,7 +3,7 @@ import { api } from "../../scripts/api.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 { GraphAnalyser } from "./use_everywhere_graph_analysis.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 { input_changed, fix_inputs } from "./connections.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) {
|
||||
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 {
|
||||
add_extra_menu_items(node, inject_outdating_into_object_method) // right click menu additions
|
||||
|
||||
const original_onDrawForeground = node.onDrawForeground;
|
||||
node.onDrawForeground = function(ctx) {
|
||||
original_onDrawForeground?.apply(this, arguments);
|
||||
title_bar_additions(this, ctx, this.title_height || LiteGraph.NODE_TITLE_HEIGHT)
|
||||
add_extra_menu_items(node) // right click menu additions
|
||||
|
||||
if (running_nodes2()) {
|
||||
// this is handled in addMouseEvents in ue_nodes2.js
|
||||
// because they need to be added to the dom element
|
||||
} 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.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;
|
||||
node._ue_mouse_events_added = true;
|
||||
} catch (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({
|
||||
name: "cg.customnodes.use_everywhere",
|
||||
settings: SETTINGS,
|
||||
@@ -155,7 +147,11 @@ app.registerExtension({
|
||||
try {
|
||||
shared.linkRenderController.pause('drawFrontCanvas')
|
||||
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();
|
||||
node._last_seen_bg = node.bgcolor
|
||||
return v
|
||||
@@ -166,6 +162,7 @@ app.registerExtension({
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Before drawing the canvas, temporarily disable all the ue connected widgets
|
||||
so they get rendered as greyed out.
|
||||
@@ -250,10 +247,8 @@ app.registerExtension({
|
||||
try {
|
||||
shared.in_graphToPrompt += 1
|
||||
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 )
|
||||
} else {
|
||||
//Logger.log_shared('In graphToPrompt (not going to modify graph):')
|
||||
return await original_graphToPrompt.apply(this, arguments)
|
||||
}
|
||||
} finally {
|
||||
@@ -299,21 +294,35 @@ app.registerExtension({
|
||||
setTimeout(()=>{app.canvas.setDirty(true,true)},200)
|
||||
})
|
||||
|
||||
app.canvas.canvas.addEventListener('litegraph:canvas', (e)=>{
|
||||
if (e?.detail?.subType=='node-double-click') {
|
||||
const node = e.detail.node
|
||||
if (node_can_broadcast(node)) {
|
||||
if (app.ui.settings.getSettingValue('Comfy.Node.DoubleClickTitleToEdit') && e.detail.originalEvent.canvasY<node.pos[1]) return
|
||||
edit_restrictions(null, null, null, null, node)
|
||||
if (!running_nodes2()) {
|
||||
app.canvas.canvas.addEventListener('litegraph:canvas', (e)=>{
|
||||
if (e?.detail?.subType=='node-double-click') {
|
||||
const node = e.detail.node
|
||||
if (node_can_broadcast(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
|
||||
app.canvas.onDrawForeground = function(ctx, visible_area) {
|
||||
if (original_onDrawForeground) original_onDrawForeground.apply(this, arguments)
|
||||
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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { app } from "../../scripts/app.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 { visible_graph } from "./use_everywhere_subgraph_utils.js";
|
||||
import { edit_restrictions } from "./ue_properties_editor.js";
|
||||
@@ -125,6 +125,7 @@ ui_update_settings.forEach((id) => {
|
||||
})
|
||||
|
||||
function show_connectable(submenu_root, node) {
|
||||
if (running_nodes2()) return; // nodes2 has broken this...
|
||||
node.inputs.forEach((input, i) => {
|
||||
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" : "";
|
||||
@@ -164,15 +165,22 @@ function widget_ue_submenu(value, options, e, menu, node) {
|
||||
node.inputs
|
||||
.filter(i => !i.hidden)
|
||||
.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(
|
||||
Object.keys(label_to_name),
|
||||
{ event: e, callback: function (label) {
|
||||
const parentElement = this?.parentElement
|
||||
const name = label_to_name[label];
|
||||
toggle_connectable(node, name);
|
||||
shared.linkRenderController.mark_link_list_outdated();
|
||||
show_connectable(this.parentElement, node)
|
||||
show_connectable(parentElement, node)
|
||||
return true; // keep open
|
||||
},
|
||||
parentMenu: menu, node:node}
|
||||
@@ -212,10 +220,7 @@ function output_ue_submenu(value, options, e, menu, node) {
|
||||
show_broadcasting(submenu.root, node)
|
||||
}
|
||||
|
||||
|
||||
|
||||
export function add_extra_menu_items(node, ioio) {
|
||||
if (node.ue_extra_menu_items_added) return
|
||||
export function add_extra_menu_items(node) {
|
||||
const getExtraMenuOptions = node.getExtraMenuOptions;
|
||||
node.getExtraMenuOptions = function(_, options) {
|
||||
getExtraMenuOptions?.apply(this, arguments);
|
||||
@@ -227,17 +232,15 @@ export function add_extra_menu_items(node, ioio) {
|
||||
add_input_and_output_settings(options, node)
|
||||
}
|
||||
options.push(null);
|
||||
ioio(options,'callback',`menu option on ${this.id}`);
|
||||
}
|
||||
node.ue_extra_menu_items_added = true
|
||||
}
|
||||
|
||||
|
||||
function add_restrictions_and_convert(options, node) {
|
||||
options.push(
|
||||
{
|
||||
content: "Edit restrictions",
|
||||
callback: edit_restrictions,
|
||||
callback: async () => { edit_restrictions(node) },
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
+18
-10
@@ -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 { settingsCache } from "./use_everywhere_cache.js";
|
||||
import { in_visible_graph, visible_graph } from "./use_everywhere_subgraph_utils.js";
|
||||
import { maybe_show_tooltip } from "./tooltip_window.js";
|
||||
import { is_connectable } from "./use_everywhere_settings.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) {
|
||||
const nodes_in = new Set();
|
||||
@@ -77,13 +77,9 @@ export function nodes_not_my_color(node, already_limited_to) {
|
||||
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)) {
|
||||
const restricted = any_restrictions(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 color = titlebar_color(node)
|
||||
|
||||
const offset_x = (node.subgraph) ? 5 : 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) {
|
||||
if (!this._list_ready()) return;
|
||||
this.last_used_ue_list = this.ue_list;
|
||||
@@ -349,7 +351,13 @@ export class LinkRenderController extends Pausable {
|
||||
|
||||
shared.graphAnalyser.ambiguities.forEach((ambiguity)=>{
|
||||
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(
|
||||
{
|
||||
graph : ambiguity.graph,
|
||||
@@ -369,7 +377,7 @@ export class LinkRenderController extends Pausable {
|
||||
any_links = true;
|
||||
var show = false;
|
||||
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;
|
||||
|
||||
show = show && in_visible_graph(ue_connection.control_node) && in_visible_graph(ue_connection.sending_to);
|
||||
|
||||
@@ -5,6 +5,10 @@ import { i18n } from "./i18n.js";
|
||||
import { ue_callbacks } from "./recursive_callbacks.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 ) {
|
||||
const nd = document.createElement(tag);
|
||||
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))
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
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 {
|
||||
constructor(name) {
|
||||
this.name = name
|
||||
|
||||
Reference in New Issue
Block a user