diff --git a/__init__.py b/__init__.py
index 317c3a8..91e604e 100644
--- a/__init__.py
+++ b/__init__.py
@@ -9,6 +9,7 @@ import glob
import json
import os
import shutil
+import re
# from .server import server
@@ -69,9 +70,28 @@ os.makedirs(DIR_WEB)
shutil.copytree(DIR_DEV_WEB, DIR_WEB, dirs_exist_ok=True)
+def extend_config(default_config, user_config):
+ cfg = {}
+ for key, value in default_config.items():
+ if key not in user_config:
+ cfg[key] = value
+ elif isinstance(value, dict):
+ cfg[key] = extend_config(value, user_config[key])
+ else:
+ cfg[key] = user_config[key] if key in user_config else value
+ return cfg
+
+
+DEFAULT_CONFIG_FILE = os.path.join(THIS_DIR, 'rgthree_config.json.default')
+with open(DEFAULT_CONFIG_FILE, 'r', encoding = 'UTF-8') as file:
+ config = re.sub(r"(?:^|\s)//.*", "", file.read(), flags=re.MULTILINE)
+ rgthree_config_default = json.loads(config)
+
CONFIG_FILE = os.path.join(THIS_DIR, 'rgthree_config.json')
with open(CONFIG_FILE, 'r', encoding = 'UTF-8') as file:
- rgthree_config = json.load(file)
+ rgthree_config_user = json.load(file)
+
+rgthree_config = extend_config(rgthree_config_default, rgthree_config_user)
with open(os.path.join(DIR_WEB, 'rgthree_config.js'), 'w', encoding = 'UTF-8') as file:
file.write('export const rgthreeConfig = ' + json.dumps(rgthree_config))
diff --git a/rgthree_config.json.default b/rgthree_config.json.default
index e630f42..c2d7137 100644
--- a/rgthree_config.json.default
+++ b/rgthree_config.json.default
@@ -1,5 +1,13 @@
+// COPY THIS FILE BEFORE MAKING CHANGES TO: rgthree_config.json
{
"patch_recursive_execution": true,
- "monitor_bad_links": false
+ "monitor_bad_links": false,
+ "nodes": {
+ "reroute": {
+ "default_width": 40,
+ "default_height": 30,
+ "default_resizable": false,
+ "default_layout": ["Left", "Right"]
+ }
+ }
}
-
diff --git a/ts/reroute.ts b/ts/reroute.ts
index 6e2c156..2b8d6b4 100644
--- a/ts/reroute.ts
+++ b/ts/reroute.ts
@@ -1,6 +1,8 @@
// /
// @ts-ignore
import { app } from "../../scripts/app.js";
+// @ts-ignore
+import {rgthreeConfig} from "./rgthree_config.js";
import { rgthree } from "./rgthree.js";
import type {
Vector2,
@@ -15,6 +17,8 @@ import type {
} from "./typings/litegraph.js";
import {
LAYOUT_CLOCKWISE,
+ LAYOUT_LABEL_OPPOSITES,
+ LAYOUT_LABEL_TO_DATA,
addConnectionLayoutSupport,
addMenuItem,
getSlotLinks,
@@ -25,6 +29,22 @@ declare const LiteGraph: typeof TLiteGraph;
declare const LGraphNode: typeof TLGraphNode;
declare const LGraphCanvas: typeof TLGraphCanvas;
+const rerouteConfig = rgthreeConfig?.['nodes']?.['reroute'] || {};
+let configWidth = Math.round((Number(rerouteConfig['default_width']) || 40) / 10) * 10;
+let configHeight = Math.round((Number(rerouteConfig['default_height']) || 30) / 10) * 10;
+const configDefaultSize = [configWidth, configHeight] as Vector2;
+const configResizable = !!rerouteConfig['default_resizable'];
+let configLayout: [string, string] = rerouteConfig['default_layout'];
+if (!Array.isArray(configLayout)) {
+ configLayout = ['Left', 'Right'];
+}
+if (!LAYOUT_LABEL_TO_DATA[configLayout[0]]) {
+ configLayout[0] = 'Left';
+}
+if (!LAYOUT_LABEL_TO_DATA[configLayout[1]] || configLayout[0] == configLayout[1]) {
+ configLayout[1] = LAYOUT_LABEL_OPPOSITES[configLayout[0]]!;
+}
+
app.registerExtension({
name: "rgthree.Reroute",
registerCustomNodes() {
@@ -38,7 +58,7 @@ app.registerExtension({
static readonly title_mode = LiteGraph.NO_TITLE;
static collapsable = false;
static layout_slot_offset = 5;
- static size: Vector2 = [40, 30]; // Starting size, read from within litegraph.core
+ static size: Vector2 = configDefaultSize; // Starting size, read from within litegraph.core
readonly isVirtualNode?: boolean;
readonly hideSlotLabels: boolean;
@@ -46,11 +66,13 @@ app.registerExtension({
private configuring = true;
private schedulePromise: Promise | null = null;
+ defaultConnectionsLayout = configLayout;
+
constructor(title = RerouteNode.title) {
super(title);
this.isVirtualNode = true;
this.hideSlotLabels = true;
- this.setResizable(this.properties['resizable']);
+ this.setResizable(this.properties['resizable'] ?? configResizable);
this.size = RerouteNode.size; // Starting size.
this.addInput("", "*");
this.addOutput("", "*");
@@ -60,7 +82,7 @@ app.registerExtension({
override configure(info: SerializedLGraphNode) {
this.configuring = true;
super.configure(info);
- this.setResizable(this.properties['resizable']);
+ this.setResizable(this.properties['resizable'] ?? configResizable);
this.applyNodeSize();
this.configuring = false;
}
@@ -407,7 +429,7 @@ app.registerExtension({
const h = node.size[1];
node.properties["connections_layout"] = node.properties[
"connections_layout"
- ] || ["Left", "Right"];
+ ] || this.defaultConnectionsLayout;
const inputDirIndex = LAYOUT_CLOCKWISE.indexOf(
node.properties["connections_layout"][0],
);
diff --git a/ts/utils.ts b/ts/utils.ts
index 910f2f7..c37ab81 100644
--- a/ts/utils.ts
+++ b/ts/utils.ts
@@ -51,7 +51,7 @@ export const LAYOUT_LABEL_TO_DATA: { [label: string]: [LiteGraphDir, Vector2, Ve
Top: [LiteGraph.UP, [0.5, 0], [0, PADDING]],
Bottom: [LiteGraph.DOWN, [0.5, 1], [0, -PADDING]],
};
-const OPPOSITE_LABEL: { [label: string]: string } = {
+export const LAYOUT_LABEL_OPPOSITES: { [label: string]: string } = {
Left: "Right",
Right: "Left",
Top: "Bottom",
@@ -157,7 +157,7 @@ export function addConnectionLayoutSupport(
prepareValue: (value, node) => {
const values = value.split(" -> ");
if (!values[1] && !node.outputs?.length) {
- values[1] = OPPOSITE_LABEL[values[0]!]!;
+ values[1] = LAYOUT_LABEL_OPPOSITES[values[0]!]!;
}
if (!LAYOUT_LABEL_TO_DATA[values[0]!] || !LAYOUT_LABEL_TO_DATA[values[1]!]) {
throw new Error(`New Layout invalid: [${values[0]}, ${values[1]}]`);
@@ -180,12 +180,13 @@ export function addConnectionLayoutSupport(
export function setConnectionsLayout(
node: TLGraphNode,
- newLayout: [string, string] = ["Left", "Right"],
+ newLayout: [string, string],
) {
+ newLayout = newLayout || (node as any).defaultConnectionsLayout || ["Left", "Right"];
// If we didn't supply an output layout, and there's no outputs, then just choose the opposite of the
// input as a safety.
if (!newLayout[1] && !node.outputs?.length) {
- newLayout[1] = OPPOSITE_LABEL[newLayout[0]!]!;
+ newLayout[1] = LAYOUT_LABEL_OPPOSITES[newLayout[0]!]!;
}
if (!LAYOUT_LABEL_TO_DATA[newLayout[0]] || !LAYOUT_LABEL_TO_DATA[newLayout[1]]) {
throw new Error(`New Layout invalid: [${newLayout[0]}, ${newLayout[1]}]`);
@@ -213,7 +214,7 @@ export function getConnectionPosForLayout(
) {
out = out || new Float32Array(2);
node.properties = node.properties || {};
- const layout = node.properties["connections_layout"] || ["Left", "Right"];
+ const layout = node.properties["connections_layout"] || (node as any).defaultConnectionsLayout || ["Left", "Right"];
const collapseConnections = node.properties["collapse_connections"] || false;
const offset = (node.constructor as any).layout_slot_offset ?? LiteGraph.NODE_SLOT_HEIGHT * 0.5;
let side = isInput ? layout[0] : layout[1];
diff --git a/web/reroute.js b/web/reroute.js
index 859f8bd..4a7a71c 100644
--- a/web/reroute.js
+++ b/web/reroute.js
@@ -1,26 +1,46 @@
+var _a;
import { app } from "../../scripts/app.js";
+import { rgthreeConfig } from "./rgthree_config.js";
import { rgthree } from "./rgthree.js";
-import { LAYOUT_CLOCKWISE, addConnectionLayoutSupport, addMenuItem, getSlotLinks, wait, } from "./utils.js";
+import { LAYOUT_CLOCKWISE, LAYOUT_LABEL_OPPOSITES, LAYOUT_LABEL_TO_DATA, addConnectionLayoutSupport, addMenuItem, getSlotLinks, wait, } from "./utils.js";
+const rerouteConfig = ((_a = rgthreeConfig === null || rgthreeConfig === void 0 ? void 0 : rgthreeConfig['nodes']) === null || _a === void 0 ? void 0 : _a['reroute']) || {};
+let configWidth = Math.round((Number(rerouteConfig['default_width']) || 40) / 10) * 10;
+let configHeight = Math.round((Number(rerouteConfig['default_height']) || 30) / 10) * 10;
+const configDefaultSize = [configWidth, configHeight];
+const configResizable = !!rerouteConfig['default_resizable'];
+let configLayout = rerouteConfig['default_layout'];
+if (!Array.isArray(configLayout)) {
+ configLayout = ['Left', 'Right'];
+}
+if (!LAYOUT_LABEL_TO_DATA[configLayout[0]]) {
+ configLayout[0] = 'Left';
+}
+if (!LAYOUT_LABEL_TO_DATA[configLayout[1]] || configLayout[0] == configLayout[1]) {
+ configLayout[1] = LAYOUT_LABEL_OPPOSITES[configLayout[0]];
+}
app.registerExtension({
name: "rgthree.Reroute",
registerCustomNodes() {
class RerouteNode extends LGraphNode {
constructor(title = RerouteNode.title) {
+ var _a;
super(title);
this.configuring = true;
this.schedulePromise = null;
+ this.defaultConnectionsLayout = configLayout;
this.isVirtualNode = true;
this.hideSlotLabels = true;
- this.setResizable(this.properties['resizable']);
+ this.setResizable((_a = this.properties['resizable']) !== null && _a !== void 0 ? _a : configResizable);
this.size = RerouteNode.size;
this.addInput("", "*");
this.addOutput("", "*");
setTimeout(() => this.applyNodeSize(), 20);
}
configure(info) {
+ var _a;
this.configuring = true;
super.configure(info);
- this.setResizable(this.properties['resizable']);
+ this.setResizable((_a = this.properties['resizable']) !== null && _a !== void 0 ? _a : configResizable);
this.applyNodeSize();
this.configuring = false;
}
@@ -234,7 +254,7 @@ app.registerExtension({
RerouteNode.title_mode = LiteGraph.NO_TITLE;
RerouteNode.collapsable = false;
RerouteNode.layout_slot_offset = 5;
- RerouteNode.size = [40, 30];
+ RerouteNode.size = configDefaultSize;
addMenuItem(RerouteNode, app, {
name: (node) => { var _a; return `${((_a = node.properties) === null || _a === void 0 ? void 0 : _a['showLabel']) ? "Hide" : "Show"} Label/Title`; },
property: 'showLabel',
@@ -312,7 +332,7 @@ app.registerExtension({
callback: (node, value) => {
const w = node.size[0];
const h = node.size[1];
- node.properties["connections_layout"] = node.properties["connections_layout"] || ["Left", "Right"];
+ node.properties["connections_layout"] = node.properties["connections_layout"] || this.defaultConnectionsLayout;
const inputDirIndex = LAYOUT_CLOCKWISE.indexOf(node.properties["connections_layout"][0]);
const outputDirIndex = LAYOUT_CLOCKWISE.indexOf(node.properties["connections_layout"][1]);
if (value === null || value === void 0 ? void 0 : value.startsWith("Rotate 90°")) {
diff --git a/web/utils.js b/web/utils.js
index c5a1dfc..f379403 100644
--- a/web/utils.js
+++ b/web/utils.js
@@ -18,7 +18,7 @@ export const LAYOUT_LABEL_TO_DATA = {
Top: [LiteGraph.UP, [0.5, 0], [0, PADDING]],
Bottom: [LiteGraph.DOWN, [0.5, 1], [0, -PADDING]],
};
-const OPPOSITE_LABEL = {
+export const LAYOUT_LABEL_OPPOSITES = {
Left: "Right",
Right: "Left",
Top: "Bottom",
@@ -89,7 +89,7 @@ export function addConnectionLayoutSupport(node, app, options = [
var _a;
const values = value.split(" -> ");
if (!values[1] && !((_a = node.outputs) === null || _a === void 0 ? void 0 : _a.length)) {
- values[1] = OPPOSITE_LABEL[values[0]];
+ values[1] = LAYOUT_LABEL_OPPOSITES[values[0]];
}
if (!LAYOUT_LABEL_TO_DATA[values[0]] || !LAYOUT_LABEL_TO_DATA[values[1]]) {
throw new Error(`New Layout invalid: [${values[0]}, ${values[1]}]`);
@@ -105,10 +105,11 @@ export function addConnectionLayoutSupport(node, app, options = [
return getConnectionPosForLayout(this, isInput, slotNumber, out);
};
}
-export function setConnectionsLayout(node, newLayout = ["Left", "Right"]) {
+export function setConnectionsLayout(node, newLayout) {
var _a;
+ newLayout = newLayout || node.defaultConnectionsLayout || ["Left", "Right"];
if (!newLayout[1] && !((_a = node.outputs) === null || _a === void 0 ? void 0 : _a.length)) {
- newLayout[1] = OPPOSITE_LABEL[newLayout[0]];
+ newLayout[1] = LAYOUT_LABEL_OPPOSITES[newLayout[0]];
}
if (!LAYOUT_LABEL_TO_DATA[newLayout[0]] || !LAYOUT_LABEL_TO_DATA[newLayout[1]]) {
throw new Error(`New Layout invalid: [${newLayout[0]}, ${newLayout[1]}]`);
@@ -126,7 +127,7 @@ export function getConnectionPosForLayout(node, isInput, slotNumber, out) {
var _a, _b, _c;
out = out || new Float32Array(2);
node.properties = node.properties || {};
- const layout = node.properties["connections_layout"] || ["Left", "Right"];
+ const layout = node.properties["connections_layout"] || node.defaultConnectionsLayout || ["Left", "Right"];
const collapseConnections = node.properties["collapse_connections"] || false;
const offset = (_a = node.constructor.layout_slot_offset) !== null && _a !== void 0 ? _a : LiteGraph.NODE_SLOT_HEIGHT * 0.5;
let side = isInput ? layout[0] : layout[1];