This commit is contained in:
Chris
2025-08-28 12:52:49 +10:00
parent c24483928e
commit f3da445397
11 changed files with 74 additions and 51 deletions
+12 -2
View File
@@ -68,12 +68,22 @@ You will _not_ be able to use workflows saved using v7 with older versions of Co
The `Anything Everywhere` node takes one or more inputs (currently limited to one input of any data type) and sends the data to other nodes that need it.
When you connect an input, a new one automatically appears.
By default the data will be sent to any `input` of the same data type which does not have a connection.
By default the data will be sent to any input of the same data type which does not have a connection, and does not have a widget providing the value.
`Anything Everywhere` does _not_ send to `widgets` by default, but if you right-click on the node that you want to receive the data you can specify which widgets should accept UE connections.
You can specify that an input should not accept data, or that one with a widget should, via the `UE Connectable Inputs` menu:
the green bar indicates an input is connectable. The `Reject UE links` option can be used to make this node completely reject UE links, regardless of other settings.
![uec](docs/connectable.png)
The node also has visual indications: a black ring and a glow on the input dot indicates it is connectable.
In the image below, `positive` has been set to not accept UE inputs, `steps` has been set to accept them, and `model` has a UE connection.
![uec](docs/connectable2.png)
If a widget is getting data from a UE connection, it is grayed out, like `steps` below:
![uec](docs/connectable3.png)
You can also constrain where the data gets send through _restrictions_ applied to the `Anything Everywhere` node.
These restrictions can be accessed by double-clicking the body of the node, or through the right-click menu.
+1 -1
View File
@@ -1,6 +1,6 @@
from .use_everywhere import SeedEverywhere, AnythingEverywherePrompts
UE_VERSION = "7.0.1"
UE_VERSION = "7.1"
NODE_CLASS_MAPPINGS = { "Seed Everywhere": SeedEverywhere }
Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

+4 -1
View File
@@ -55,6 +55,7 @@ const DEFAULT_PROPERTIES = {
group_restricted : 0,
color_restricted : 0,
widget_ue_connectable : {},
input_ue_unconnectable : {},
title_regex : null,
input_regex : null,
group_regex : null,
@@ -90,6 +91,7 @@ export function setup_ue_properties_onload(node) {
group_restricted : node.properties.group_restricted,
color_restricted : node.properties.color_restricted,
widget_ue_connectable : node.properties.widget_ue_connectable,
input_ue_unconnectable: {},
title_regex : node.widgets_values?.[0],
input_regex : node.widgets_values?.[1],
group_regex : node.widgets_values?.[2],
@@ -102,7 +104,8 @@ export function setup_ue_properties_onload(node) {
node.properties.ue_properties.version = VERSION
node.properties.ue_properties.widget_ue_connectable = node.properties.ue_properties.widget_ue_connectable ||
node.properties.widget_ue_connectable ||
[]
{}
node.properties.ue_properties.input_ue_unconnectable = {}
if (node.properties.widget_ue_connectable) delete node.properties.widget_ue_connectable
}
}
+2 -2
View File
@@ -4,6 +4,7 @@ import { convert_to_links } from "./use_everywhere_apply.js";
import { app } from "../../scripts/app.js";
import { settingsCache } from "./use_everywhere_cache.js";
import { master_graph, node_graph, visible_graph } from "./use_everywhere_subgraph_utils.js";
import { is_connectable } from "./use_everywhere_settings.js";
class GraphAnalyser extends Pausable {
static _instance;
@@ -101,8 +102,7 @@ class GraphAnalyser extends Pausable {
node.inputs?.forEach((input,index) => {
if (is_connected(input, treat_bypassed_as_live, node_graph(node))) return;
if (node.reject_ue_connection && node.reject_ue_connection(input)) return;
if (node._getWidgetByName(input.name) && !(node.properties?.ue_properties?.widget_ue_connectable && node.properties.ue_properties.widget_ue_connectable[input.name])) return;
connectable.push({node, input, index});
if (is_connectable(node, input.name)) connectable.push({node, input, index});
})
}
})
+41 -32
View File
@@ -2,7 +2,7 @@ import { app } from "../../scripts/app.js";
import { GraphAnalyser } from "./use_everywhere_graph_analysis.js";
import { LinkRenderController } from "./use_everywhere_ui.js";
import { convert_to_links, remove_all_ues } from "./use_everywhere_apply.js";
import { VERSION } from "./use_everywhere_utilities.js";
import { Logger, VERSION } 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";
@@ -130,52 +130,61 @@ function submenu(properties, property, options, e, menu, node) {
}
}
function highlight_selected(submenu_root, node, names) {
names.forEach((name, i) => {
function show_connectable(submenu_root, node) {
node.inputs.forEach((input, i) => {
const current_element = submenu_root?.querySelector(`:nth-child(${i+1})`);
if (current_element) {
if (node.properties.ue_properties['widget_ue_connectable'][name]) {
current_element.style.borderLeft = "2px solid #484";
} else {
current_element.style.borderLeft = "";
}
} else {
let a;
}
if (current_element) current_element.style.borderLeft = (is_connectable(node,input.name)) ? "2px solid #484" : "";
})
}
export function is_connectable(node, input_name){
const input = node.inputs.find(i => i.name==input_name);
if (!input) {
Logger.log_error(`Can't find input ${label} on node ${node.title}`);
return false;
}
if (input.widget) {
return !!(node.properties?.ue_properties?.widget_ue_connectable?.[input_name])
} else {
return ! (node.properties?.ue_properties?.input_ue_unconnectable?.[input_name])
}
}
function toggle_connectable(node, input_name){
const input = node.inputs.find(i => i.name==input_name);
const p = node.properties.ue_properties
if (input.widget) {
p.widget_ue_connectable[input_name] = !!!p.widget_ue_connectable[input_name];
} else {
p.input_ue_unconnectable[input_name] = !!!p.input_ue_unconnectable[input_name];
}
}
function widget_ue_submenu(value, options, e, menu, node) {
if (!(node.properties.ue_properties)) node.properties.ue_properties = {}
if (!(node.properties.ue_properties.widget_ue_connectable)) node.properties.ue_properties.widget_ue_connectable = {};
if (!(node.properties.ue_properties.input_ue_unconnectable)) node.properties.ue_properties.input_ue_unconnectable = {};
const linkedWidgets = new Set()
node.widgets
.filter(w => w.linkedWidgets)
.forEach((widget) => { widget.linkedWidgets.forEach((lw)=>{linkedWidgets.add(lw)}) });
const label_name_map = {}
node.widgets
.filter(w => !linkedWidgets.has(w))
.filter(w => !w.hidden)
.filter(w => !w.name?.includes('$$'))
.forEach((widget) => { label_name_map[widget.label || widget.name] = widget.name });
const labels = Array.from(Object.keys(label_name_map))
const names = Array.from(Object.values(label_name_map))
const label_to_name = {}
node.inputs
.filter(i => !i.hidden)
.filter(i => !i.name?.includes('$$'))
.forEach((input) => {
label_to_name[input.label || input.name] = input.name
});
const submenu = new LiteGraph.ContextMenu(
labels,
Object.keys(label_to_name),
{ event: e, callback: function (label) {
const name = label_name_map[label];
node.properties.ue_properties.widget_ue_connectable[name] = !!!node.properties.ue_properties.widget_ue_connectable[name];
const name = label_to_name[label];
toggle_connectable(node, name);
LinkRenderController.instance().mark_link_list_outdated();
highlight_selected(this.parentElement, node, names)
show_connectable(this.parentElement, node)
return true; // keep open
},
parentMenu: menu, node:node}
)
highlight_selected(submenu.root, node, names)
show_connectable(submenu.root, node)
}
export function add_extra_menu_items(node_or_node_type, ioio) {
@@ -205,7 +214,7 @@ export function non_ue_menu_settings(options, node) {
if (node.widgets?.length) {
options.push(
{
content: "UE Connectable Widgets",
content: "UE Connectable Inputs",
has_submenu: true,
callback: widget_ue_submenu,
}
+12 -11
View File
@@ -3,6 +3,7 @@ import { app } from "../../scripts/app.js";
import { settingsCache } from "./use_everywhere_cache.js";
import { in_visible_graph, node_graph } from "./use_everywhere_subgraph_utils.js";
import { maybe_show_tooltip } from "./tooltip_window.js";
import { is_connectable } from "./use_everywhere_settings.js";
function nodes_in_my_group(node) {
const nodes_in = new Set();
@@ -195,24 +196,24 @@ class LinkRenderController extends Pausable {
highlight_ue_connections(node, ctx) {
if (!settingsCache.getSettingValue('Use Everywhere.Graphics.highlight')) return;
if (!node.inputs) return;
try {
this.pause('highlight_ue_connections')
if (!this._list_ready()) return;
const unconnected_connectables = node.properties?.ue_properties?.widget_ue_connectable ? new Set(Object.keys(node.properties.ue_properties.widget_ue_connectable).filter((name) => (node.properties.ue_properties.widget_ue_connectable[name]))) : new Set()
node.inputs.filter((input)=>(input.link)).forEach((input) => { unconnected_connectables.delete(input.name) });
const unconnected_connectable_names = new Set(node.inputs
.filter((input)=>is_connectable(node,input.name))
.filter((input)=>(!input.link))
.map((input)=>input.name) || [])
if (this.ue_list.all_connected_inputs) {
this.ue_list.all_connected_inputs(node).forEach((ue_connection) => {
if (!ue_connection.control_node) { // control node deleted...
this.mark_link_list_outdated();
return;
}
if (!node.inputs[ue_connection.input_index]) {
return
}
if (!ue_connection.control_node) return;
if (!node.inputs[ue_connection.input_index]) return
const name_sent_to = node.inputs[ue_connection.input_index].name;
unconnected_connectables.delete(name_sent_to); // remove the name from the list of connectables
unconnected_connectable_names.delete(name_sent_to); // remove the name from the list of connectables
var pos2 = node.getConnectionPos(true, ue_connection.input_index, this.slot_pos1);
pos2[0] -= node.pos[0];
pos2[1] -= node.pos[1];
@@ -239,7 +240,7 @@ class LinkRenderController extends Pausable {
});
}
unconnected_connectables.forEach((name) => {
unconnected_connectable_names.forEach((name) => {
const index = node.inputs.findIndex((i) => i.name == name);
var pos2 = node.getConnectionPos(true, index, this.slot_pos1);
pos2[0] -= node.pos[0];
+1 -1
View File
@@ -2,7 +2,7 @@ import { app } from "../../scripts/app.js";
import { settingsCache } from "./use_everywhere_cache.js";
import { link_is_from_subgraph_input, node_graph, visible_graph, wrap_input } from "./use_everywhere_subgraph_utils.js";
export const VERSION = "7.0.1"
export const VERSION = "7.1"
export function create( tag, clss, parent, properties ) {
const nd = document.createElement(tag);
+1 -1
View File
@@ -1,7 +1,7 @@
[project]
name = "cg-use-everywhere"
description = "A set of nodes that allow data to be 'broadcast' to some or all unconnected inputs. Greatly reduces link spaghetti."
version = "7.0.1"
version = "7.1"
license = { file = "LICENSE" }
[project.urls]