@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
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)
|
||||||
|
|||||||
@@ -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)" );
|
||||||
|
}
|
||||||
+38
-29
@@ -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,23 +15,22 @@ 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;
|
|
||||||
node.onDrawForeground = function(ctx) {
|
|
||||||
original_onDrawForeground?.apply(this, arguments);
|
|
||||||
title_bar_additions(this, ctx, this.title_height || LiteGraph.NODE_TITLE_HEIGHT)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
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;
|
const original_onMouseEnter = node.onMouseEnter;
|
||||||
node.onMouseEnter = function(e) {
|
node.onMouseEnter = function(e) {
|
||||||
original_onMouseEnter?.apply(this, arguments)
|
original_onMouseEnter?.apply(this, arguments)
|
||||||
@@ -44,27 +43,20 @@ function add_methods_to_all_nodes(node) {
|
|||||||
shared.linkRenderController.node_over_changed()
|
shared.linkRenderController.node_over_changed()
|
||||||
}
|
}
|
||||||
|
|
||||||
node.ue_methods_added = true;
|
const original_onDrawTitle = node.onDrawTitle;
|
||||||
|
node.onDrawTitle = function(ctx) {
|
||||||
|
title_bar_additions(this, ctx)
|
||||||
|
original_onDrawTitle?.apply(this, arguments)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
node._ue_mouse_events_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);
|
||||||
|
if (running_nodes2()) {
|
||||||
|
addMouseEvents(node)
|
||||||
|
} else {
|
||||||
shared.linkRenderController.highlight_ue_connections(node, ctx);
|
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,15 +294,17 @@ app.registerExtension({
|
|||||||
setTimeout(()=>{app.canvas.setDirty(true,true)},200)
|
setTimeout(()=>{app.canvas.setDirty(true,true)},200)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if (!running_nodes2()) {
|
||||||
app.canvas.canvas.addEventListener('litegraph:canvas', (e)=>{
|
app.canvas.canvas.addEventListener('litegraph:canvas', (e)=>{
|
||||||
if (e?.detail?.subType=='node-double-click') {
|
if (e?.detail?.subType=='node-double-click') {
|
||||||
const node = e.detail.node
|
const node = e.detail.node
|
||||||
if (node_can_broadcast(node)) {
|
if (node_can_broadcast(node)) {
|
||||||
if (app.ui.settings.getSettingValue('Comfy.Node.DoubleClickTitleToEdit') && e.detail.originalEvent.canvasY<node.pos[1]) return
|
if (app.ui.settings.getSettingValue('Comfy.Node.DoubleClickTitleToEdit') && e.detail.originalEvent.canvasY<node.pos[1]) return
|
||||||
edit_restrictions(null, null, null, null, node)
|
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) {
|
||||||
@@ -315,6 +312,18 @@ app.registerExtension({
|
|||||||
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
|
||||||
- catch changes in language (and read initial value) for i18n
|
- catch changes in language (and read initial value) for i18n
|
||||||
|
|||||||
@@ -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
@@ -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);
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user