docs and initial i18n
This commit is contained in:
@@ -8,7 +8,7 @@ Problems? Jump down to [logging and debugging](https://github.com/chrisgoringe/c
|
||||
|
||||
Ideas for how to improve the nodes (or bug reports) - [raise an issue](https://github.com/chrisgoringe/cg-use-everywhere/issues)
|
||||
|
||||
Shameless plug for my other nodes -> Check out [Image Picker](https://github.com/chrisgoringe/cg-image-filter) for another way to make some workflows smoother. And leave a star if you like something!
|
||||
Shameless plug for another nodes -> Check out [Image Picker](https://github.com/chrisgoringe/cg-image-filter) for another way to make some workflows smoother. And leave a star if you like something!
|
||||
|
||||
---
|
||||
|
||||
@@ -29,6 +29,7 @@ This is what the default wan 2.2 s2v video workflow looks like:
|
||||
|-|-|
|
||||
|||
|
||||
|
||||
---
|
||||
|
||||
# Anything Everywhere v7
|
||||
|
||||
@@ -63,13 +64,17 @@ However, there may be edge cases that don't work; if you have any problems, plea
|
||||
|
||||
You will _not_ be able to use workflows saved using v7 with older versions of ComfyUI or older versions of UE.
|
||||
|
||||
# Anything Everywhere
|
||||
**Group Nodes are no longer supported**
|
||||
|
||||
## Anything Everywhere
|
||||
---
|
||||
|
||||
# Anything Everywhere
|
||||
|
||||
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.
|
||||
|
||||
## Where will the data be sent?
|
||||
|
||||
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.
|
||||
|
||||
You can specify that an input should not accept data, or that one with a widget should, via the `UE Connectable Inputs` menu:
|
||||
@@ -98,38 +103,47 @@ The Group and Colour restrictions will constrain the node to only send to nodes
|
||||
|
||||
If you select multiple restrictions, all must be satisfied for the node to send.
|
||||
|
||||
If any restrictions are applied, the `Anything Everywhere` node gets a green circle in the top left hand corner, and a tooltip if yuo hover the mouse over it.
|
||||
If any restrictions are applied, the `Anything Everywhere` node gets a green circle in the top left hand corner, and a tooltip if you hover the mouse over it (as long as Show Links is not set to None).
|
||||
|
||||
`Repeated Types` determines behaviour when more than one input of the same type is connected to an `Anything Everywhere` node.
|
||||
In this case an additional constraint is used to disambiguate which inputs match
|
||||
by comparing the name of the input slot on the `Anything Everywhere` node with
|
||||
either the name of the input slot on the target node, or the name of the target node.
|
||||
The `match start` and `match end` options require that the input names match from the start (or end) for the full length of the shorter:
|
||||
so you can match `seed` to `seed` or `noise_seed` by naming the `Anything Everywhere` input `seed` and selecting `Match end of input names`.
|
||||
|
||||
You can rename input slots by right-clicking on the input dot - but you can't rename widget inputs - this is a limitation imposed by ComfyUI ([discussion](https://github.com/Comfy-Org/ComfyUI_frontend/issues/3654)). The work-around is to rename the target node (or use multiple `Anything Everywhere` nodes with other constraints, especially color matching).
|
||||
|
||||
## Resolving clashes
|
||||
|
||||
What if two or more `Anything Everywhere` nodes can send to the same input?
|
||||
|
||||
Each node has an automatically calculated priority - in general the more restrictive the node, the higher the priority.
|
||||
You can see this prority in the restrictions dialog, and you can choose to replace the automatically calculated value if you wish.
|
||||
|
||||
Priority has an automatically calculated value which you can choose to override.
|
||||
If two more more `Anything Everywhere` nodes match the same input, the higher priority node is used. If there is a tie, _no connection is made_.
|
||||
When there is a tie, if you right-click on the canvas you will find an option to show which nodes are the problem.
|
||||
|
||||
`Repeated Types` determines behaviour when more than one input of the same type is connected to an `Anything Everywhere` node.
|
||||
In this case an additional constraint is used to disambiguate which inputs match based on the names of the input
|
||||
slots on the `Anything Everywhere` node and the target node.
|
||||
Note that you can rename the input slots on the `Anything Everywhere` node by right-clicking on the input dot.
|
||||
## Special Case Nodes
|
||||
|
||||
These two nodes might go away in the future; if they do, workflows using them will be automatically updated with their replacements...
|
||||
|
||||
## Seed Everywhere
|
||||
|
||||
Seed Everywhere connects to any unconnected INT input with `seed` in the input name (seed, noise_seed, etc), and it has the control_after_generate feature. So if you convert the seed widgets to inputs you can use the same seed everywhere.
|
||||
|
||||
Hopefully this node will soon be retired, but if it is, workflows using it will be automatically converted.
|
||||
Seed Everywhere connects to any unconnected INT input which matches the regex `seed|随机种` (basically all the default seed input names).
|
||||
It has the control_after_generate feature. So if you mark the seed widgets as allowing UE Connections, you can use the same seed everywhere.
|
||||
|
||||
## Prompts Everywhere
|
||||
|
||||
Prompt Everywhere has two inputs. They will be sent with regex matching rules of `(^prompt|^positive)` and `neg` respectively. These should match the various versions of names that get used for prompts and negative prompts or conditionings. The regexes can be edited, but additional inputs are not created.
|
||||
Prompt Everywhere has two inputs. They will be sent with regex matching rules designed to match `prompt` or `positive`, and `neg`, respectively.
|
||||
|
||||
The actual regexes used are `(_|\\b)pos(itive|_|\\b)|^prompt|正面` and `(_|\\b)neg(ative|_|\\b)|负面`
|
||||
|
||||
|strings|conditionings|
|
||||
|-|-|
|
||||
||
|
||||
|
||||
Hopefully this node will soon be retired, but if it is, workflows using it will be automatically converted.
|
||||
|
||||
## Primitives and COMBOs and the like
|
||||
|
||||
UE nodes don't work with primitives and COMBOs (the data type used for dropdown lists, which are also a type of primitive within Comfy). It's unlikely they ever will.
|
||||
|
||||
For more on this, see [this discussion](https://github.com/chrisgoringe/cg-use-everywhere/issues/69)
|
||||
---
|
||||
|
||||
# Options
|
||||
|
||||
@@ -143,14 +157,14 @@ The bottom set, `Options`, modify behaviour:
|
||||
|
||||
- Block workflow validation. This prevents other nodes from complaining about the lack of connections, or creating them. If you turn this off, there may be unexpected consequences.
|
||||
- Logging. Increase the logging level if you are asked to help debug.
|
||||
- Check loops before submitting will attempt to check for loops in the workflow created by Use Everywhere links. Comfy is much better at handling this now, so I would suggest leaving it off.
|
||||
- Connect to bypassed nodes. When off, Use Everywhere will not connect to a bypassed node, and will attempt to work out whether an input is connected when upstream nodes are bypassed.
|
||||
- Check loops before submitting will attempt to check for loops in the workflow created by Use Everywhere links. Comfy is much better at handling this now, so I would recommend leaving it off.
|
||||
- Connect to bypassed nodes. When off, Use Everywhere will not connect to a bypassed node, and will attempt to work out whether an input is connected when upstream nodes are bypassed. I recommend turning this on.
|
||||
|
||||
*I recommend turning `Connect to bypassed nodes` on; the default is off for backward compatibility.*
|
||||
---
|
||||
|
||||
# Other features
|
||||
|
||||
## Third Party Integration
|
||||
## Third Party Integration - the UE API
|
||||
|
||||
At the suggestion of [@fighting-tx](https://github.com/fighting-tx),
|
||||
I've added a method that third party nodes can use if they want to see the prompt as generated by UE.
|
||||
@@ -167,10 +181,6 @@ if (app.ue_modified_prompt) {
|
||||
|
||||
Other methods could be exposed if there is interest - raise an issue if you'd like to see something.
|
||||
|
||||
## Reject links
|
||||
|
||||
Right click on a node and you can set it to reject UE links
|
||||
|
||||
## Show links - visualisation and animation.
|
||||
|
||||
If you want to see the UE links, you can turn them on and off by right-clicking on the canvas. For finer control, the main settings menu has options to show links when the mouse moves over the node at either end, or when one of those nodes is selected.
|
||||
@@ -187,15 +197,26 @@ This can be done for a single node by right-clicking on it and selecting `Conver
|
||||
|
||||
---
|
||||
|
||||
# Primitives and COMBOs and the like
|
||||
|
||||

|
||||
|
||||
UE nodes work with the primitives added in more recent versions of Comfy (in the `primitive` submenu), but not the old-style `Primitive`.
|
||||
They also do not work with COMBOs (the data type used for dropdown lists, which are also a type of primitive within Comfy), or reroute nodes.
|
||||
|
||||
It is very unlikely this will ever change, as it relates to some issues deep within Comfy...
|
||||
|
||||
For more on this, see [this discussion](https://github.com/chrisgoringe/cg-use-everywhere/issues/69)
|
||||
|
||||
---
|
||||
|
||||
# Roadmap
|
||||
|
||||
In the near future I hope to do the following:
|
||||
|
||||
- Add a mechanism to support multiple inputs of the same type
|
||||
- Once this is done, `Prompts Everywhere` will be retired
|
||||
- Replace the `Prompt Everywhere` and `Seed Everywhere` nodes
|
||||
- Add a mechanism to retire `Seed Everywhere` (or auto convert to an integer node connected to a `Anything Everywhere` node)
|
||||
- Add a clean way to localise for non-English language use
|
||||
- Enable individual inputs to reject connections
|
||||
- Add localisation
|
||||
- Negative regexes ('must not match')
|
||||
- Possibly add a global variable system (so multiple modes can be changed with a single modification)
|
||||
|
||||
@@ -205,14 +226,6 @@ Feel free to [make suggestions](https://github.com/chrisgoringe/cg-use-everywher
|
||||
|
||||
# More detailed notes on a few things
|
||||
|
||||
## Naming widgets
|
||||
|
||||
The restrictions make use of the name of an input. On some occasions this might mean you want to rename an input.
|
||||
|
||||
For an input that can't be a widget, that's trivial - right click on the input dot and select `Rename Slot`. The name will be updated, and the new name displayed next to the dot.
|
||||
|
||||
If an input *can* be a widget, you cannot rename it. This is a decision taken by the Comfy team (see [here](https://github.com/Comfy-Org/ComfyUI_frontend/issues/3654)).
|
||||
|
||||
## Subgraph creation
|
||||
|
||||
There are three nodes involved in every UE link:
|
||||
@@ -237,7 +250,9 @@ No* indicates a case that does not work, but might get implemented.
|
||||
|
||||
No indicates a case I'm unlikely ever to support
|
||||
|
||||
## Reporting a bug well
|
||||
---
|
||||
|
||||
# Reporting a bug well
|
||||
|
||||
If you are having problems, the better information you give me, the more chance I can fix it!
|
||||
|
||||
@@ -247,21 +262,24 @@ Read the list below and include anything that seems relevant. If you can't get t
|
||||
- if you have a simple workflow that recreates the problem, that's a huge help
|
||||
- Comfy version information (in Settings - About, it looks like this:)
|
||||

|
||||
- include what all your settings are - in the Comfy settings select `AE` in the left menu
|
||||
- check your version of the node (in the settings from version 6.0.4, before that look in the `cg-use-everywhere` folder in the file `__init__.py`)
|
||||
- check your version of the node (look in the `Use Everywhere` settings)
|
||||
- press f12 and see if there are any errors in the javascript console that look like they might be relevant
|
||||
- look at the server (python) console log and see if there are any errors there
|
||||
|
||||
## Thanks to
|
||||
---
|
||||
|
||||
# Thanks to
|
||||
|
||||
The following people have contributed code or helpful discussions, without which these nodes would be less good!
|
||||
|
||||
- [DrJKL](https://github.com/DrJKL)
|
||||
- [fighting-tx](https://github.com/fighting-tx)
|
||||
- [huchenlei](https://github.com/huchenlei)
|
||||
- [fichas](https://github.com/fichas)
|
||||
- [LukeG89](https://github.com/LukeG89)
|
||||
- [set-soft](https://github.com/set-soft)
|
||||
- [TinyTerra](https://github.com/TinyTerra)
|
||||
- [bananasss00](https://github.com/bananasss00)
|
||||
- [fichas](https://github.com/fichas)
|
||||
- [JorgeR81](https://github.com/JorgeR81)
|
||||
- [LukeG89](https://github.com/LukeG89)
|
||||
|
||||
Feel free to [make suggestions, or implement features](https://github.com/chrisgoringe/cg-use-everywhere/issues) to get your name added here!
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 8.2 KiB |
+102
-46
@@ -1,46 +1,112 @@
|
||||
import { app } from "../../scripts/app.js";
|
||||
|
||||
const FUNCTIONAL = {
|
||||
seed_input_regex : "seed|随机种",
|
||||
prompt_regex : "(_|\\b)pos(itive|_|\\b)|^prompt|正面",
|
||||
negative_regex : "(_|\\b)neg(ative|_|\\b)|负面",
|
||||
export var REPEATED_TYPE_OPTIONS;
|
||||
export var GROUP_RESTRICTION_OPTIONS;
|
||||
export var COLOR_RESTRICTION_OPTIONS;
|
||||
|
||||
const LANGUAGES = {
|
||||
en : "English",
|
||||
cn : "Mandarin",
|
||||
}
|
||||
|
||||
const DISPLAY = {
|
||||
title : "title",
|
||||
input : "input",
|
||||
group : "group",
|
||||
Group : "Group",
|
||||
Color : "Colour",
|
||||
Priority : "Priority",
|
||||
prompt_regexes_text : "Prompt Everywhere",
|
||||
"No restrictions" : "No restrictions",
|
||||
"Send only within group" : "Send only within group",
|
||||
"Send only not within group" : "Send only not within group",
|
||||
"Send only to same color" : "Send only to same color",
|
||||
"Send only to different color" : "Send only to different color",
|
||||
"Exact match of input names" : "Exact match of input names",
|
||||
"Match start of input names" : "Match start of input names",
|
||||
"Match end of input names" : "Match end of input names",
|
||||
const _FUNCTIONAL = {
|
||||
'en':{
|
||||
seed_input_regex : "seed|随机种",
|
||||
prompt_regex : "(_|\\b)pos(itive|_|\\b)|^prompt|正面",
|
||||
negative_regex : "(_|\\b)neg(ative|_|\\b)|负面",
|
||||
},
|
||||
'cn':{
|
||||
seed_input_regex : "seed|随机种",
|
||||
prompt_regex : "(_|\\b)pos(itive|_|\\b)|^prompt|正面",
|
||||
negative_regex : "(_|\\b)neg(ative|_|\\b)|负面",
|
||||
},
|
||||
}
|
||||
|
||||
export const REPEATED_TYPE_OPTIONS = [
|
||||
i18n("Exact match of input names"),
|
||||
i18n("Match start of input names"),
|
||||
i18n("Match end of input names"),
|
||||
]
|
||||
const _DISPLAY = {
|
||||
'en' : {
|
||||
prompt_regexes_text : "Prompt Everywhere",
|
||||
},
|
||||
'cn' : {
|
||||
anything : "anything chinese",
|
||||
title : "title chinese",
|
||||
input : "input chinese",
|
||||
group : "group chinese",
|
||||
Group : "Group chinese",
|
||||
Color : "Colour chinese",
|
||||
Priority : "Priority chinese",
|
||||
prompt_regexes_text : "Prompt Everywhere chinese",
|
||||
"No restrictions" : "No restrictions chinese",
|
||||
"Send only within group" : "Send only within group chinese",
|
||||
"Send only not within group" : "Send only not within group chinese",
|
||||
"Send only to same color" : "Send only to same color chinese",
|
||||
"Send only to different color" : "Send only to different color chinese",
|
||||
"Exact match of input names" : "Exact match of input names chinese",
|
||||
"Match start of input names" : "Match start of input names chinese",
|
||||
"Match end of input names" : "Match end of input names chinese",
|
||||
|
||||
export const GROUP_RESTRICTION_OPTIONS = [
|
||||
i18n("No restrictions"),
|
||||
i18n("Send only within group"),
|
||||
i18n("Send only not within group")
|
||||
]
|
||||
"Selected nodes" : "Selected nodes chinese",
|
||||
}
|
||||
}
|
||||
|
||||
export const COLOR_RESTRICTION_OPTIONS = [
|
||||
i18n("No restrictions"),
|
||||
i18n("Send only to same color"),
|
||||
i18n("Send only to different color")
|
||||
]
|
||||
function DISPLAY(v, lang) { return _DISPLAY[lang || current_language()]?.[v] || _DISPLAY['en'][v] }
|
||||
|
||||
function current_language() {
|
||||
return app.ui.settings.getSettingValue("Use Everywhere.Language.language")
|
||||
}
|
||||
|
||||
export function language_changed(is_now, was_before) {
|
||||
if (was_before) {
|
||||
app.graph.nodes.filter((node)=>node.IS_UE).forEach((node)=>{
|
||||
// translate node inputs
|
||||
node.inputs?.forEach((input)=>{
|
||||
if (input.label && input.label.startsWith(i18n('anything', was_before))) {
|
||||
input.label = input.label.replace(i18n('anything', {language:was_before}), i18n('anything', {language:is_now}))
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
REPEATED_TYPE_OPTIONS = [
|
||||
i18n("Exact match of input names"),
|
||||
i18n("Match start of input names"),
|
||||
i18n("Match end of input names"),
|
||||
i18n("Inputs matches target node name"),
|
||||
]
|
||||
|
||||
GROUP_RESTRICTION_OPTIONS = [
|
||||
i18n("No restrictions"),
|
||||
i18n("Send only within group"),
|
||||
i18n("Send only not within group")
|
||||
]
|
||||
|
||||
COLOR_RESTRICTION_OPTIONS = [
|
||||
i18n("No restrictions"),
|
||||
i18n("Send only to same color"),
|
||||
i18n("Send only to different color")
|
||||
]
|
||||
}
|
||||
|
||||
export function language_options() {
|
||||
const options = []
|
||||
Object.keys(LANGUAGES).forEach((k) => {options.push({value:k, text:k})})
|
||||
return options
|
||||
}
|
||||
|
||||
export function i18n_functional(v) { return _FUNCTIONAL[current_language()]?.[v] || _FUNCTIONAL['en'][v] }
|
||||
|
||||
export function i18n(v, extras) {
|
||||
var r = DISPLAY(v, extras?.language) || LANGUAGES[v] || v
|
||||
if (extras?.titlecase) r = toTitleCase(r)
|
||||
return r
|
||||
}
|
||||
|
||||
export function i18ify_settings(settings) {
|
||||
settings.forEach((s)=>{
|
||||
if (s.name) s.name = i18n(s.name)
|
||||
if (s.tooltip) s.tooltip = i18n(s.tooltip)
|
||||
if (s.options) s.options.forEach((o) => {o.text = i18n(o.text)})
|
||||
})
|
||||
return settings
|
||||
}
|
||||
|
||||
const toTitleCase = (phrase) => {
|
||||
return phrase
|
||||
@@ -48,14 +114,4 @@ const toTitleCase = (phrase) => {
|
||||
.split(' ')
|
||||
.map(word => word.charAt(0).toUpperCase() + word.slice(1))
|
||||
.join(' ');
|
||||
};
|
||||
|
||||
export function i18n(v, extras) {
|
||||
var r = DISPLAY[v] || v
|
||||
if (extras?.titlecase) r = toTitleCase(r)
|
||||
return r
|
||||
}
|
||||
|
||||
export function default_regex(v) {
|
||||
return FUNCTIONAL[v]
|
||||
}
|
||||
};
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
import { VERSION, version_at_least, is_UEnode, graphConverter, fix_inputs, create } from "./use_everywhere_utilities.js"
|
||||
import { i18n, default_regex, GROUP_RESTRICTION_OPTIONS, COLOR_RESTRICTION_OPTIONS } from "./i18n.js";
|
||||
import { i18n, i18n_functional, GROUP_RESTRICTION_OPTIONS, COLOR_RESTRICTION_OPTIONS } from "./i18n.js";
|
||||
|
||||
const ALL_REGEXES = ['title', 'input', 'prompt', 'negative', 'group']
|
||||
|
||||
@@ -127,7 +127,7 @@ function convert_node_types(node) {
|
||||
} else if (node.type=="Seed Everywhere") {
|
||||
node.properties.ue_properties.fixed_inputs = true
|
||||
node.properties.ue_properties.seed_inputs = true
|
||||
node.properties.ue_properties.input_regex = node.properties.ue_properties.input_regex || default_regex('seed_input_regex')
|
||||
node.properties.ue_properties.input_regex = node.properties.ue_properties.input_regex || i18n_functional('seed_input_regex')
|
||||
} else if (node.type=="Prompts Everywhere") {
|
||||
node.properties.ue_properties.fixed_inputs = true
|
||||
node.properties.ue_properties.prompt_regexes = true
|
||||
|
||||
+10
-11
@@ -1,8 +1,7 @@
|
||||
import { LinkRenderController } from "./use_everywhere_ui.js";
|
||||
import { i18n, default_regex } from "./i18n.js";
|
||||
import { i18n, i18n_functional, GROUP_RESTRICTION_OPTIONS, COLOR_RESTRICTION_OPTIONS, REPEATED_TYPE_OPTIONS } from "./i18n.js";
|
||||
import { app } from "../../scripts/app.js";
|
||||
import { default_priority } from "./ue_properties.js";
|
||||
import { GROUP_RESTRICTION_OPTIONS, COLOR_RESTRICTION_OPTIONS, REPEATED_TYPE_OPTIONS } from "./i18n.js";
|
||||
import { edit_window } from "./floating_window.js";
|
||||
|
||||
const REGEXES = ['title', 'input', 'group']
|
||||
@@ -40,7 +39,7 @@ function changed(node, property, value) {
|
||||
if (node.properties.ue_properties.prompt_regexes) {
|
||||
for (var i=0; i<2; i++) {
|
||||
if (!node.properties.ue_properties[`${P_REGEXES[i]}_regex`]) {
|
||||
document.getElementById(`${P_REGEXES[i]}_regex_value`).value = default_regex(`${P_REGEXES[i]}_regex`)
|
||||
document.getElementById(`${P_REGEXES[i]}_regex_value`).value = i18n_functional(`${P_REGEXES[i]}_regex`)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -63,7 +62,7 @@ function create_editor_html(node) {
|
||||
const row = add_row(table, `${i18n(name)} regex`)
|
||||
const input = document.createElement('input')
|
||||
input.type = "text"
|
||||
input.value = node.properties.ue_properties[`${name}_regex`] || default_regex(`${name}_regex`)
|
||||
input.value = node.properties.ue_properties[`${name}_regex`] || i18n_functional(`${name}_regex`)
|
||||
if (!node.properties.ue_properties[`${name}_regex`]) input.style.opacity = 0.5
|
||||
input.id = `${name}_regex_value`
|
||||
input.style.width = '250px'
|
||||
@@ -91,6 +90,13 @@ function create_editor_html(node) {
|
||||
add_cell(col_row,col_select)
|
||||
add_select_options(node, col_select, COLOR_RESTRICTION_OPTIONS, `color_restricted` )
|
||||
|
||||
if (!node.properties.ue_properties.prompt_regexes) {
|
||||
const repeated_type_row = add_row(table, i18n("Repeated Types"))
|
||||
const repeated_type_select = document.createElement('select')
|
||||
add_cell(repeated_type_row,repeated_type_select)
|
||||
add_select_options(node, repeated_type_select, REPEATED_TYPE_OPTIONS, `repeated_type_rule`)
|
||||
}
|
||||
|
||||
const priority_row = add_row(table, i18n("Priority"))
|
||||
const priority_edit = document.createElement("input")
|
||||
priority_edit.value = `${node.properties.ue_properties.priority || default_priority(node)}`
|
||||
@@ -103,13 +109,6 @@ function create_editor_html(node) {
|
||||
if (!node.properties.ue_properties.priority) priority_edit.style.opacity = 0.5
|
||||
add_cell(priority_row,priority_edit)
|
||||
|
||||
if (!node.properties.ue_properties.prompt_regexes) {
|
||||
const repeated_type_row = add_row(table, i18n("Repeated Types"))
|
||||
const repeated_type_select = document.createElement('select')
|
||||
add_cell(repeated_type_row,repeated_type_select)
|
||||
add_select_options(node, repeated_type_select, REPEATED_TYPE_OPTIONS, `repeated_type_rule`)
|
||||
}
|
||||
|
||||
return table
|
||||
}
|
||||
|
||||
|
||||
@@ -82,23 +82,7 @@ app.registerExtension({
|
||||
linkRenderController.mark_link_list_outdated();
|
||||
onConnectionsChange?.apply(this, arguments);
|
||||
};
|
||||
|
||||
/*
|
||||
Reject duplicated inputs for now
|
||||
|
||||
no, allow them
|
||||
|
||||
if (is_UEnode(nodeType)) {
|
||||
const onConnectInput = nodeType.prototype.onConnectInput
|
||||
nodeType.prototype.onConnectInput = function (index, type) {
|
||||
if (!this.properties.ue_properties.fixed_inputs) {
|
||||
if (this.inputs.find((i, j)=>(i.type==type && j!=index))) return false
|
||||
}
|
||||
return onConnectInput?.apply(this, arguments)
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
/*
|
||||
Extra menu options are the node right click menu.
|
||||
We add to this list, and also insert a link list outdate to everything.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { default_regex } from "./i18n.js";
|
||||
import { i18n_functional } from "./i18n.js";
|
||||
import { default_priority } from "./ue_properties.js";
|
||||
import { node_graph, visible_graph } from "./use_everywhere_subgraph_utils.js";
|
||||
import { nodes_in_my_group, nodes_not_in_my_group, nodes_my_color, nodes_not_my_color, nodes_in_groups_matching } from "./use_everywhere_ui.js";
|
||||
@@ -79,7 +79,7 @@ class UseEverywhere {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.additional_requirement && !this.additional_requirement(input)) return false
|
||||
if (this.additional_requirement && !this.additional_requirement(input, node)) return false
|
||||
|
||||
if (this.output[0] == node.id) return false;
|
||||
if (this.restrict_to && !this.restrict_to.includes(node.id)) return false;
|
||||
@@ -262,26 +262,33 @@ export class UseEverywhereList {
|
||||
var additional_requirement = null
|
||||
if (duplicated_input_types.has(connection.type) && !node.properties.ue_properties.prompt_regexes) {
|
||||
const input_name = input.label || input.name
|
||||
if (node.properties.ue_properties?.repeated_type_rule == 0) { // 0 is exact match of input name
|
||||
const rule = node.properties.ue_properties?.repeated_type_rule || 0
|
||||
if (rule == 0) { // 0 is exact match of input name
|
||||
additional_requirement = (target_input) => {
|
||||
const target_name = target_input.label || target_input.name
|
||||
return (target_name == input_name)
|
||||
}
|
||||
}
|
||||
if (node.properties.ue_properties?.repeated_type_rule == 1) { // 1 is match start of input name
|
||||
if (rule == 1) { // 1 is match start of input name
|
||||
additional_requirement = (target_input) => {
|
||||
const target_name = target_input.label || target_input.name
|
||||
const chars = Math.min( input_name.length, target_name.length )
|
||||
return (target_name.substring(0, chars) == input_name.substring(0, chars))
|
||||
}
|
||||
}
|
||||
if (node.properties.ue_properties?.repeated_type_rule == 2) { // 2 is match end of input name
|
||||
if (rule == 2) { // 2 is match end of input name
|
||||
additional_requirement = (target_input) => {
|
||||
const target_name = target_input.label || target_input.name
|
||||
const chars = Math.min( input_name.length, target_name.length )
|
||||
return (target_name.substring(target_name.length - chars) == input_name.substring(input_name.length - chars))
|
||||
}
|
||||
}
|
||||
if (rule == 3) { // 3 input is match of target node name
|
||||
additional_requirement = (_, target_node) => {
|
||||
const target_name = target_node.title
|
||||
return (target_name == input_name)
|
||||
}
|
||||
}
|
||||
}
|
||||
this.add_ue(node, i, connection.type, [connection.link.origin_id.toString(), connection.link.origin_slot], input_regex, additional_requirement);
|
||||
}
|
||||
@@ -291,7 +298,7 @@ export class UseEverywhereList {
|
||||
}
|
||||
|
||||
const P_REGEXES = ['prompt', 'negative']
|
||||
const PROMPT_REGEXES = [new RegExp(default_regex('prompt_regex')), new RegExp(default_regex('negative_regex'))]
|
||||
const PROMPT_REGEXES = [new RegExp(i18n_functional('prompt_regex')), new RegExp(i18n_functional('negative_regex'))]
|
||||
|
||||
function prompt_regex(node, i) {
|
||||
const reg = node.properties.ue_properties[`${P_REGEXES[i]}_regex`]
|
||||
|
||||
@@ -7,13 +7,23 @@ import { settingsCache } from "./use_everywhere_cache.js";
|
||||
import { visible_graph } from "./use_everywhere_subgraph_utils.js";
|
||||
import { edit_restrictions } from "./ue_properties_editor.js";
|
||||
import { is_UEnode } from "./use_everywhere_utilities.js";
|
||||
import { language_changed, language_options, i18ify_settings } from "./i18n.js";
|
||||
|
||||
export const SETTINGS = [
|
||||
const _SETTINGS = [
|
||||
{
|
||||
id: "Use Everywhere.About",
|
||||
name: `Version ${VERSION}`,
|
||||
type: () => {return document.createElement('span')},
|
||||
},
|
||||
{
|
||||
id: "Use Everywhere.Language.language",
|
||||
name: "Language",
|
||||
type: "combo",
|
||||
options: language_options(),
|
||||
defaultValue: 'en',
|
||||
onChange: language_changed,
|
||||
tooltip: "Probably requires page refresh",
|
||||
},
|
||||
{
|
||||
id: "Use Everywhere.Graphics.showlinks",
|
||||
name: "Show links",
|
||||
@@ -72,7 +82,7 @@ export const SETTINGS = [
|
||||
id: "Use Everywhere.Options.connect_to_bypassed",
|
||||
name: "Connect to bypassed nodes",
|
||||
type: "boolean",
|
||||
defaultValue: false,
|
||||
defaultValue: true,
|
||||
onChange: settingsCache.onSettingChange,
|
||||
tooltip: "By default UE links are made to the node downstream of bypassed nodes."
|
||||
},
|
||||
@@ -102,12 +112,15 @@ export const SETTINGS = [
|
||||
},
|
||||
]
|
||||
|
||||
export const SETTINGS = i18ify_settings(_SETTINGS)
|
||||
|
||||
const ui_update_settings = [
|
||||
"Use Everywhere.Graphics.showlinks",
|
||||
"Use Everywhere.Graphics.fuzzlinks",
|
||||
"Use Everywhere.Graphics.animate",
|
||||
"Use Everywhere.Graphics.stop_animation_when_running",
|
||||
"Use Everywhere.Graphics.highlight",
|
||||
"Use Everywhere.Language.language",
|
||||
]
|
||||
ui_update_settings.forEach((id) => {
|
||||
settingsCache.addCallback(id, ()=>{app.graph?.change.bind(app.graph)})
|
||||
|
||||
@@ -4,6 +4,7 @@ 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";
|
||||
import { i18n } from "./i18n.js";
|
||||
|
||||
function nodes_in_my_group(node) {
|
||||
const nodes_in = new Set();
|
||||
@@ -88,10 +89,10 @@ function indicate_restriction(ctx, title_height) {
|
||||
function update_input_label(node, slot, app) {
|
||||
const type = node.inputs[slot].type
|
||||
if (type) {
|
||||
node.inputs[slot].label = node.inputs[slot].label || type;
|
||||
if (!node.inputs[slot].label || node.inputs[slot].label==i18n('anything')) node.inputs[slot].label = type;
|
||||
node.inputs[slot].color_on = app.canvas.default_connection_color_byType[type];
|
||||
} else {
|
||||
node.inputs[slot].label = "anything";
|
||||
node.inputs[slot].label = i18n('anything');
|
||||
node.inputs[slot].color_on = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,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";
|
||||
import { i18n } from "./i18n.js";
|
||||
|
||||
export const VERSION = "7.1"
|
||||
|
||||
@@ -124,8 +125,8 @@ class GraphConverter {
|
||||
if (node.type == "Anything Everywhere?") expected_inputs = 4
|
||||
|
||||
// remove all the 'anything' inputs (because they may be duplicated)
|
||||
const removed = node.inputs.filter(i=>(i.label=='anything' || i.label=='*'))
|
||||
node.inputs = node.inputs.filter(i=>(i.label!='anything' && i.label!='*'))
|
||||
const removed = node.inputs.filter(i=>(i.label==i18n('anything') || i.label=='*'))
|
||||
node.inputs = node.inputs.filter(i=>(i.label!=i18n('anything') && i.label!='*'))
|
||||
// add them back as required
|
||||
while (node.inputs.length < expected_inputs) { node.inputs.push(removed.pop()) }
|
||||
// the input comes before the regex widgets in UE?
|
||||
@@ -136,7 +137,7 @@ class GraphConverter {
|
||||
}
|
||||
// fix the localized names
|
||||
node.inputs = node.inputs.map((input) => {
|
||||
if (!input.localized_name || input.localized_name.startsWith('anything')) input.localized_name = input.name
|
||||
if (!input.localized_name || input.localized_name.startsWith(i18n('anything'))) input.localized_name = input.name
|
||||
return input;
|
||||
})
|
||||
|
||||
@@ -152,7 +153,7 @@ class GraphConverter {
|
||||
input.type = llink.type;
|
||||
}
|
||||
} else {
|
||||
input.type = (input.label && input.label!='anything') ? input.label : input.name
|
||||
input.type = (input.label && input.label!=i18n('anything')) ? input.label : input.name
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -426,7 +427,7 @@ export function fix_inputs(node) {
|
||||
if (excess_inputs<0) {
|
||||
try {
|
||||
node.properties.ue_properties.next_input_index = (node.properties.ue_properties.next_input_index || 10) + 1
|
||||
node.addInput(`anything${node.properties.ue_properties.next_input_index}`, "*", {label:"anything"})
|
||||
node.addInput(`anything${node.properties.ue_properties.next_input_index}`, "*", {label:i18n('anything')})
|
||||
fix_inputs(node)
|
||||
} catch (e) {
|
||||
Logger.log_error(e)
|
||||
|
||||
Reference in New Issue
Block a user