From 9a2411d0954617961d5a621901ebada25cbbeeb2 Mon Sep 17 00:00:00 2001 From: "Alexander G. Morano" Date: Wed, 7 Aug 2024 23:50:43 -0700 Subject: [PATCH] renamed tooltip to tooltips to keep old system with new renamed max/min to mij/maj to resolve immediate conflicts for PR 2666 --- __init__.py | 27 +++--- core/calc.py | 165 ++++++++++++++++++----------------- core/compose.py | 122 +++++++++++++------------- core/create.py | 66 +++++++------- core/create_glsl.py | 10 +-- core/device_midi.py | 10 +-- core/device_stream.py | 14 +-- core/utility.py | 76 ++++++++-------- sup/image.py | 63 ++++++++++--- sup/util.py | 2 +- web/core/core_cozy_fields.js | 9 +- web/core/core_cozy_tips.js | 39 +++++++-- web/core/core_help.js | 2 +- web/nodes/adjust.js | 14 +-- web/nodes/calc_binary.js | 15 +--- web/nodes/lerp.js | 12 +-- web/nodes/value.js | 21 ++--- web/util/util_jov.js | 95 ++++++-------------- 18 files changed, 397 insertions(+), 365 deletions(-) diff --git a/__init__.py b/__init__.py index 351cdde..3308352 100644 --- a/__init__.py +++ b/__init__.py @@ -299,7 +299,7 @@ class Lexicon(metaclass=LexiconMeta): SOURCE = 'SRC', "Source" SPACING = 'SPACING', "Line Spacing between Text Lines" START = 'START', "Start of the range" - STEP = '🦢🏽', "Step" + STEP = '🦢🏽', "Steps/Stride between pulses -- useful to do odd or even batches. If set to 0 will stretch from (VAL -> LOOP) / Batch giving a linear range of values." STRENGTH = 'πŸ’ͺ🏽', "Strength" STRING = 'πŸ“', "String Entry" STYLE = 'STYLE', "Style" @@ -355,7 +355,7 @@ def _parse(cls, node: dict, node_cls: object) -> dict: continue for k, v in entry.items(): widget_data = v[1] if isinstance(v, (tuple, list,)) and len(v) > 1 else {} - if (tip := widget_data.get('tooltip', None)) is None: + if (tip := widget_data.get("tooltips", None)) is None: if (tip := cls._tooltipsDB.get(k), None) is None: logger.warning(f"no {k}") continue @@ -392,6 +392,11 @@ class JOVBaseNode: # instance map for caching INSTANCE = {} + @classmethod + def VALIDATE_INPUTS(cls, *arg, **kw) -> bool: + logger.debug(f'validate -- {arg} {kw}') + return True + @classmethod def INPUT_TYPES(cls, prompt:bool=False, extra_png:bool=False) -> dict: data = { @@ -415,9 +420,9 @@ def INPUT_TYPES(cls) -> dict: d = super().INPUT_TYPES() d.update({ "outputs": { - 0: ("IMAGE", {"tooltip":"Full channel [RGBA] image. If there is an alpha, the image will be masked out with it when using this output."}), - 1: ("IMAGE", {"tooltip":"Three channel [RGB] image. There will be no alpha."}), - 2: ("MASK", {"tooltip":"Single channel mask output."}), + 0: ("IMAGE", {"tooltips":"Full channel [RGBA] image. If there is an alpha, the image will be masked out with it when using this output."}), + 1: ("IMAGE", {"tooltips":"Three channel [RGB] image. There will be no alpha."}), + 2: ("MASK", {"tooltips":"Single channel mask output."}), } }) return Lexicon._parse(d, cls) @@ -514,12 +519,12 @@ def get_node_info(node_cls: object) -> Dict[str, Any]: # only stuff that makes sense... junk = ['default', 'min', 'max'] meta = node_param_meta[param_key][1] - if (tip := meta.get('tooltip', None)) is None: + if (tip := meta.get("tooltips", None)) is None: if (tip := Lexicon._tooltipsDB.get(param_key, None)) is None: # logger.warning(f"no tooltip for {node_class}[{k}]::{param_key}") - junk.append('tooltip') + junk.append("tooltips") tip = "Unknown Explanation!" - input_parameters[k][param_key]['tooltip'] = tip + input_parameters[k][param_key]["tooltips"] = tip for scrape in junk: if (val := meta.get(scrape, None)) is not None and val != "": input_parameters[k][param_key][scrape] = val @@ -573,7 +578,7 @@ def json2markdown(json_dict: dict) -> str: typ = param_meta.get('type','UNKNOWN').upper() typ = ', '.join([x.strip() for x in typ.split(',')]) typ = "
".join(textwrap.wrap(typ, 42)) - tool = param_meta.get('tooltip','') + tool = param_meta.get("tooltips",'') tool = "
".join(textwrap.wrap(tool, 42)) default = param_meta.get('default','') ch = ", ".join(param_meta.get('choice', [])) @@ -633,7 +638,7 @@ def template_load(what: str, fname: str) -> Template: typ = param_meta.get('type', 'UNKNOWN').upper() typ = ', '.join([x.strip() for x in typ.split(',')]) typ = '
'.join(textwrap.wrap(typ, 42)) - tool = param_meta.get('tooltip', '') + tool = param_meta.get("tooltips", '') tool = '
'.join(textwrap.wrap(tool, 42)) default = html.escape(str(param_meta.get('default', ''))) ch = ', '.join(param_meta.get('choice', [])) @@ -889,7 +894,7 @@ def __init__(self, *arg, **kw) -> None: try: for class_name, class_def in module.import_dynamic(): setattr(module, class_name, class_def) - logger.info(f"shader: {class_name}") + logger.debug(f"shader: {class_name}") except Exception as e: pass diff --git a/core/calc.py b/core/calc.py index 14fb67e..4a55117 100644 --- a/core/calc.py +++ b/core/calc.py @@ -196,7 +196,7 @@ def INPUT_TYPES(cls) -> dict: Lexicon.FUNC: (EnumUnaryOperation._member_names_, {"default": EnumUnaryOperation.ABS.name}) }, "outputs": { - 0: (Lexicon.UNKNOWN, {"tooltip":"Output type will match the input type"}), + 0: (Lexicon.UNKNOWN, {"tooltips":"Output type will match the input type"}), } }) return Lexicon._parse(d, cls) @@ -296,22 +296,22 @@ def INPUT_TYPES(cls) -> dict: d.update({ "optional": { Lexicon.IN_A: (JOV_TYPE_FULL, {"default": None, - "tooltip":"Passes a raw value directly, or supplies defaults for any value inputs without connections"}), + "tooltips":"Passes a raw value directly, or supplies defaults for any value inputs without connections"}), Lexicon.IN_B: (JOV_TYPE_FULL, {"default": None, - "tooltip":"Passes a raw value directly, or supplies defaults for any value inputs without connections"}), - Lexicon.FUNC: (EnumBinaryOperation._member_names_, {"default": EnumBinaryOperation.ADD.name, "tooltip":"Arithmetic operation to perform"}), + "tooltips":"Passes a raw value directly, or supplies defaults for any value inputs without connections"}), + Lexicon.FUNC: (EnumBinaryOperation._member_names_, {"default": EnumBinaryOperation.ADD.name, "tooltips":"Arithmetic operation to perform"}), Lexicon.TYPE: (names_convert, {"default": names_convert[2], - "tooltip":"Output type desired from resultant operation"}), + "tooltips":"Output type desired from resultant operation"}), Lexicon.FLIP: ("BOOLEAN", {"default": False}), Lexicon.IN_A+Lexicon.IN_A: ("VEC4", {"default": (0,0,0,0), "label": [Lexicon.X, Lexicon.Y, Lexicon.Z, Lexicon.W], - "tooltip":"value vector"}), + "tooltips":"value vector"}), Lexicon.IN_B+Lexicon.IN_B: ("VEC4", {"default": (0,0,0,0), "label": [Lexicon.X, Lexicon.Y, Lexicon.Z, Lexicon.W], - "tooltip":"value vector"}), + "tooltips":"value vector"}), }, "outputs": { - 0: (Lexicon.UNKNOWN, {"tooltip":"Output type will match the input type"}), + 0: (Lexicon.UNKNOWN, {"tooltips":"Output type will match the input type"}), } }) return Lexicon._parse(d, cls) @@ -433,8 +433,8 @@ def INPUT_TYPES(cls) -> dict: d = super().INPUT_TYPES() d.update({ "optional": { - Lexicon.IN_A: (JOV_TYPE_FULL, {"default": 0, "tooltip":"Master Comparator"}), - Lexicon.IN_B: (JOV_TYPE_FULL, {"default": 0, "tooltip":"Secondary Comparator"}), + Lexicon.IN_A: (JOV_TYPE_FULL, {"default": 0, "tooltips":"Master Comparator"}), + Lexicon.IN_B: (JOV_TYPE_FULL, {"default": 0, "tooltips":"Secondary Comparator"}), Lexicon.COMP_A: (JOV_TYPE_ANY, {"default": 0}), Lexicon.COMP_B: (JOV_TYPE_ANY, {"default": 0}), Lexicon.COMPARE: (EnumComparison._member_names_, {"default": EnumComparison.EQUAL.name}), @@ -442,8 +442,8 @@ def INPUT_TYPES(cls) -> dict: Lexicon.INVERT: ("BOOLEAN", {"default": False}), }, "outputs": { - 0: (Lexicon.TRIGGER, {"tooltip":f"Outputs the input at {Lexicon.IN_A} or {Lexicon.IN_B} depending on which evaluated `TRUE`"}), - 1: (Lexicon.VALUE, {"tooltip":"The comparison result value"}), + 0: (Lexicon.TRIGGER, {"tooltips":f"Outputs the input at {Lexicon.IN_A} or {Lexicon.IN_B} depending on which evaluated `TRUE`"}), + 1: (Lexicon.VALUE, {"tooltips":"The comparison result value"}), } }) return Lexicon._parse(d, cls) @@ -549,10 +549,10 @@ def INPUT_TYPES(cls) -> dict: d.update({ "optional": { Lexicon.PASS_IN: (JOV_TYPE_ANY, {"default": None}), - Lexicon.TIMER: ("INT", {"default" : 0, "min": -1}), + Lexicon.TIMER: ("INT", {"default" : 0, "mij": -1}), }, "outputs": { - 0: (Lexicon.PASS_OUT, {"tooltip":f"Pass through data when the delay ends"}) + 0: (Lexicon.PASS_OUT, {"tooltips":f"Pass through data when the delay ends"}) } }) return Lexicon._parse(d, cls) @@ -600,22 +600,22 @@ def INPUT_TYPES(cls) -> dict: names_convert = EnumConvertType._member_names_[:10] d.update({ "optional": { - Lexicon.IN_A: (JOV_TYPE_FULL, {"tooltip": "Custom Start Point"}), - Lexicon.IN_B: (JOV_TYPE_FULL, {"tooltip": "Custom End Point"}), + Lexicon.IN_A: (JOV_TYPE_FULL, {"tooltips": "Custom Start Point"}), + Lexicon.IN_B: (JOV_TYPE_FULL, {"tooltips": "Custom End Point"}), Lexicon.FLOAT: ("VEC4", {"default": (0.5, 0.5, 0.5, 0.5), - "min": 0., "max": 1.0, + "mij": 0., "maj": 1.0, # "step": 0.001, "round": 0.0001, "precision": 5, - "tooltip": "Blend Amount. 0 = full A, 1 = full B"}), + "tooltips": "Blend Amount. 0 = full A, 1 = full B"}), Lexicon.IN_A+Lexicon.IN_A: ("VEC4", {"default": (0, 0, 0, 0), - "tooltip":"default value vector for A"}), + "tooltips":"default value vector for A"}), Lexicon.IN_B+Lexicon.IN_B: ("VEC4", {"default": (1,1,1,1), - "tooltip":"default value vector for B"}), + "tooltips":"default value vector for B"}), Lexicon.TYPE: (names_convert, {"default": "FLOAT", - "tooltip":"Output type desired from resultant operation"}), + "tooltips":"Output type desired from resultant operation"}), Lexicon.EASE: (["NONE"] + EnumEase._member_names_, {"default": "NONE"}), }, "outputs": { - 0: (Lexicon.ANY_OUT, {"tooltip":f"Output can vary depending on the type chosen in the {Lexicon.TYPE} parameter"}) + 0: (Lexicon.ANY_OUT, {"tooltips":f"Output can vary depending on the type chosen in the {Lexicon.TYPE} parameter"}) } }) return Lexicon._parse(d, cls) @@ -693,15 +693,15 @@ def INPUT_TYPES(cls) -> dict: Lexicon.IN_A: (JOV_TYPE_VECTOR, {}), Lexicon.IN_B: (JOV_TYPE_VECTOR, {}), Lexicon.TYPE: (names_convert, {"default": names_convert[2], - "tooltip":"Output type desired from resultant operation"}), + "tooltips":"Output type desired from resultant operation"}), Lexicon.SWAP_X: (EnumSwizzle._member_names_, {"default": EnumSwizzle.A_X.name}), - Lexicon.X: ("FLOAT", {"default": 0, "min": -sys.maxsize, "max": sys.maxsize}), + Lexicon.X: ("FLOAT", {"default": 0, "mij": -sys.maxsize, "maj": sys.maxsize}), Lexicon.SWAP_Y: (EnumSwizzle._member_names_, {"default": EnumSwizzle.A_Y.name}), - Lexicon.Y: ("FLOAT", {"default": 0, "min": -sys.maxsize, "max": sys.maxsize}), + Lexicon.Y: ("FLOAT", {"default": 0, "mij": -sys.maxsize, "maj": sys.maxsize}), Lexicon.SWAP_Z: (EnumSwizzle._member_names_, {"default": EnumSwizzle.A_Z.name}), - Lexicon.Z: ("FLOAT", {"default": 0, "min": -sys.maxsize, "max": sys.maxsize}), + Lexicon.Z: ("FLOAT", {"default": 0, "mij": -sys.maxsize, "maj": sys.maxsize}), Lexicon.SWAP_W: (EnumSwizzle._member_names_, {"default": EnumSwizzle.A_W.name}), - Lexicon.W: ("FLOAT", {"default": 0, "min": -sys.maxsize, "max": sys.maxsize}) + Lexicon.W: ("FLOAT", {"default": 0, "mij": -sys.maxsize, "maj": sys.maxsize}) } }) return Lexicon._parse(d, cls) @@ -710,13 +710,13 @@ def run(self, **kw) -> Tuple[torch.Tensor, torch.Tensor]: pA = parse_param(kw, Lexicon.IN_A, EnumConvertType.VEC4, [(0,0,0,0)]) pB = parse_param(kw, Lexicon.IN_B, EnumConvertType.VEC4, [(0,0,0,0)]) swap_x = parse_param(kw, Lexicon.SWAP_X, EnumConvertType.STRING, EnumSwizzle.A_X.name) - x = parse_param(kw, Lexicon.X, EnumConvertType.FLOAT, 0) + x = parse_param(kw, Lexicon.X, EnumConvertType.FLOAT, 0, -sys.maxsize, sys.maxsize) swap_y = parse_param(kw, Lexicon.SWAP_Y, EnumConvertType.STRING, EnumSwizzle.A_Y.name) - y = parse_param(kw, Lexicon.Y, EnumConvertType.FLOAT, 0) + y = parse_param(kw, Lexicon.Y, EnumConvertType.FLOAT, 0, -sys.maxsize, sys.maxsize) swap_z = parse_param(kw, Lexicon.SWAP_Z, EnumConvertType.STRING, EnumSwizzle.A_W.name) - z = parse_param(kw, Lexicon.Z, EnumConvertType.FLOAT, 0) + z = parse_param(kw, Lexicon.Z, EnumConvertType.FLOAT, 0, -sys.maxsize, sys.maxsize) swap_w = parse_param(kw, Lexicon.SWAP_W, EnumConvertType.STRING, EnumSwizzle.A_Z.name) - w = parse_param(kw, Lexicon.W, EnumConvertType.FLOAT, 0) + w = parse_param(kw, Lexicon.W, EnumConvertType.FLOAT, 0, -sys.maxsize, sys.maxsize) params = list(zip_longest_fill(pA, pB, swap_x, x, swap_y, y, swap_z, z, swap_w, w)) results = [] pbar = ProgressBar(len(params)) @@ -747,32 +747,32 @@ def INPUT_TYPES(cls) -> dict: "optional": { # data to pass on a pulse of the loop Lexicon.TRIGGER: (JOV_TYPE_ANY, {"default": None, - "tooltip":"Output to send when beat (BPM setting) is hit"}), + "tooltips":"Output to send when beat (BPM setting) is hit"}), # forces a MOD on CYCLE - Lexicon.VALUE: ("INT", {"min": 0, "default": 0, - "tooltip": "the current frame number of the tick"}), - Lexicon.LOOP: ("INT", {"min": 0, "max": 32767, "default": 0, - "tooltip": "number of frames before looping starts. 0 means continuous playback (no loop point)"}), + Lexicon.VALUE: ("INT", {"mij": 0, "default": 0, "mij": 0, "maj": sys.maxsize, + "tooltips": "the current frame number of the tick"}), + Lexicon.LOOP: ("INT", {"mij": 0, "maj": sys.maxsize, "default": 0, + "tooltips": "number of frames before looping starts. 0 means continuous playback (no loop point)"}), # - Lexicon.FPS: ("INT", {"min": 1, "default": 24, - "tooltip": "Fixed frame step rate based on FPS (1/FPS)"}), - Lexicon.BPM: ("INT", {"min": 1, "max": 60000, "default": 120, - "tooltip": "BPM trigger rate to send the input. If input is empty, TRUE is sent on trigger"}), - Lexicon.NOTE: ("INT", {"default": 4, "min": 1, "max": 256, - "tooltip":"Number of beats per measure. Quarter note is 4, Eighth is 8, 16 is 16, etc."}), + Lexicon.FPS: ("INT", {"mij": 1, "default": 24, + "tooltips": "Fixed frame step rate based on FPS (1/FPS)"}), + Lexicon.BPM: ("INT", {"mij": 1, "maj": 60000, "default": 120, + "tooltips": "BPM trigger rate to send the input. If input is empty, TRUE is sent on trigger"}), + Lexicon.NOTE: ("INT", {"default": 4, "mij": 1, "maj": 256, + "tooltips":"Number of beats per measure. Quarter note is 4, Eighth is 8, 16 is 16, etc."}), # stick the current "count" Lexicon.WAIT: ("BOOLEAN", {"default": False}), # manual total = 0 Lexicon.RESET: ("BOOLEAN", {"default": False}), # how many frames to dump.... - Lexicon.BATCH: ("INT", {"min": 1, "default": 1, "max": 32767, "tooltip": "Number of frames wanted"}), - Lexicon.STEP: ("INT", {"default": 0, "tooltip": "Steps/Stride between pulses -- useful to do odd or even batches. If set to 0 will stretch from (VAL -> LOOP) / Batch giving a linear range of values."}), + Lexicon.BATCH: ("INT", {"mij": 1, "default": 1, "maj": 32767, "tooltips": "Number of frames wanted"}), + Lexicon.STEP: ("INT", {"default": 0, "mij": 0, "maj": sys.maxsize}), }, "outputs": { - 0: (Lexicon.VALUE, {"tooltip":"Current value for the configured tick"}), - 1: (Lexicon.LINEAR, {"tooltip":"Normalized tick value (0..1) based on BPM and Loop"}), - 2: (Lexicon.FPS, {"tooltip":"Current 'frame' in the tick based on FPS setting"}), - 3: (Lexicon.TRIGGER, {"tooltip":"Based on the BPM settings, on beat hit, output the input at '⚑'"}), + 0: (Lexicon.VALUE, {"tooltips":"Current value for the configured tick"}), + 1: (Lexicon.LINEAR, {"tooltips":"Normalized tick value (0..1) based on BPM and Loop"}), + 2: (Lexicon.FPS, {"tooltips":"Current 'frame' in the tick based on FPS setting"}), + 3: (Lexicon.TRIGGER, {"tooltips":"Based on the BPM settings, on beat hit, output the input at '⚑'"}), } }) return Lexicon._parse(d, cls) @@ -790,9 +790,9 @@ def __init__(self, *arg, **kw) -> None: def run(self, ident, **kw) -> Tuple[int, float, float, Any]: passthru = parse_param(kw, Lexicon.TRIGGER, EnumConvertType.ANY, None)[0] - stride = parse_param(kw, Lexicon.STEP, EnumConvertType.INT, 0, 0)[0] - loop = parse_param(kw, Lexicon.LOOP, EnumConvertType.INT, 0)[0] - self.__frame = parse_param(kw, Lexicon.VALUE, EnumConvertType.INT, self.__frame)[0] + stride = parse_param(kw, Lexicon.STEP, EnumConvertType.INT, 0, 0, sys.maxsize)[0] + loop = parse_param(kw, Lexicon.LOOP, EnumConvertType.INT, 0, 0, sys.maxsize)[0] + self.__frame = parse_param(kw, Lexicon.VALUE, EnumConvertType.INT, self.__frame, 0, sys.maxsize)[0] if loop != 0: self.__frame %= loop # start_frame = max(0, start_frame) @@ -857,26 +857,26 @@ def INPUT_TYPES(cls) -> dict: d.update({ "optional": { Lexicon.IN_A: (JOV_TYPE_ANY, {"default": None, - "tooltip":"Passes a raw value directly, or supplies defaults for any value inputs without connections"}), + "tooltips":"Passes a raw value directly, or supplies defaults for any value inputs without connections"}), Lexicon.TYPE: (typ, {"default": EnumConvertType.BOOLEAN.name, - "tooltip":"Take the input and convert it into the selected type."}), - Lexicon.X: (JOV_TYPE_ANY, {"default": 0, "min": -sys.maxsize, - "max": sys.maxsize, "forceInput": True}), - Lexicon.Y: (JOV_TYPE_ANY, {"default": 0, "min": -sys.maxsize, - "max": sys.maxsize, "forceInput": True}), - Lexicon.Z: (JOV_TYPE_ANY, {"default": 0, "min": -sys.maxsize, - "max": sys.maxsize, "forceInput": True}), - Lexicon.W: (JOV_TYPE_ANY, {"default": 0, "min": -sys.maxsize, - "max": sys.maxsize, "forceInput": True}), + "tooltips":"Take the input and convert it into the selected type."}), + Lexicon.X: (JOV_TYPE_ANY, {"default": 0, "mij": -sys.maxsize, + "maj": sys.maxsize, "forceInput": True}), + Lexicon.Y: (JOV_TYPE_ANY, {"default": 0, "mij": -sys.maxsize, + "maj": sys.maxsize, "forceInput": True}), + Lexicon.Z: (JOV_TYPE_ANY, {"default": 0, "mij": -sys.maxsize, + "maj": sys.maxsize, "forceInput": True}), + Lexicon.W: (JOV_TYPE_ANY, {"default": 0, "mij": -sys.maxsize, + "maj": sys.maxsize, "forceInput": True}), Lexicon.IN_A+Lexicon.IN_A: ("VEC4", {"default": (0, 0, 0, 0), - #"min": -sys.maxsize, "max": sys.maxsize, + #"mij": -sys.maxsize, "maj": sys.maxsize, "label": [Lexicon.X, Lexicon.Y], - "tooltip":"default value vector for A"}), - Lexicon.SEED: ("INT", {"default": 0, "min": 0, "max": sys.maxsize}), + "tooltips":"default value vector for A"}), + Lexicon.SEED: ("INT", {"default": 0, "mij": 0, "maj": sys.maxsize}), Lexicon.IN_B+Lexicon.IN_B: ("VEC4", {"default": (1,1,1,1), - #"min": -sys.maxsize, "max": sys.maxsize, + #"mij": -sys.maxsize, "maj": sys.maxsize, "label": [Lexicon.X, Lexicon.Y, Lexicon.Z, Lexicon.W], - "tooltip":"default value vector for B"}), + "tooltips":"default value vector for B"}), Lexicon.STRING: ("STRING", {"default": "", "dynamicPrompts": False, "multiline": True}), } }) @@ -884,10 +884,10 @@ def INPUT_TYPES(cls) -> dict: def run(self, **kw) -> Tuple[bool]: raw = parse_param(kw, Lexicon.IN_A, EnumConvertType.ANY, None) - r_x = parse_param(kw, Lexicon.X, EnumConvertType.FLOAT, None) - r_y = parse_param(kw, Lexicon.Y, EnumConvertType.FLOAT, None) - r_z = parse_param(kw, Lexicon.Z, EnumConvertType.FLOAT, None) - r_w = parse_param(kw, Lexicon.W, EnumConvertType.FLOAT, None) + r_x = parse_param(kw, Lexicon.X, EnumConvertType.FLOAT, 0, -sys.maxsize, sys.maxsize) + r_y = parse_param(kw, Lexicon.Y, EnumConvertType.FLOAT, 0, -sys.maxsize, sys.maxsize) + r_z = parse_param(kw, Lexicon.Z, EnumConvertType.FLOAT, 0, -sys.maxsize, sys.maxsize) + r_w = parse_param(kw, Lexicon.W, EnumConvertType.FLOAT, 0, -sys.maxsize, sys.maxsize) typ = parse_param(kw, Lexicon.TYPE, EnumConvertType.STRING, EnumConvertType.BOOLEAN.name) xyzw = parse_param(kw, Lexicon.IN_A+Lexicon.IN_A, EnumConvertType.VEC4, [(0, 0, 0, 0)]) seed = parse_param(kw, Lexicon.SEED, EnumConvertType.INT, 0, 0) @@ -963,11 +963,11 @@ def INPUT_TYPES(cls) -> dict: d.update({ "optional": { Lexicon.WAVE: (EnumWave._member_names_, {"default": EnumWave.SIN.name}), - Lexicon.FREQ: ("FLOAT", {"default": 1, "min": 0, "max": 10000000000000000}), - Lexicon.AMP: ("FLOAT", {"default": 1, "min": 0, "max": 10000000000000000}), - Lexicon.PHASE: ("FLOAT", {"default": 0, "min": 0.0, "step": 0.001, "max": 1.0}), - Lexicon.OFFSET: ("FLOAT", {"default": 0, "min": 0.0, "step": 0.001, "max": 1.0}), - Lexicon.TIME: ("FLOAT", {"default": 0, "min": 0, "step": 0.0001}), + Lexicon.FREQ: ("FLOAT", {"default": 1, "mij": 0, "maj": sys.maxsize}), + Lexicon.AMP: ("FLOAT", {"default": 1, "mij": 0, "maj": sys.maxsize}), + Lexicon.PHASE: ("FLOAT", {"default": 0, "mij": 0.0, "maj": 1.0, "step": 0.001, }), + Lexicon.OFFSET: ("FLOAT", {"default": 0, "mij": 0.0, "maj": 1.0, "step": 0.001, }), + Lexicon.TIME: ("FLOAT", {"default": 0, "mij": 0, "maj": sys.maxsize, "step": 0.0001}), Lexicon.INVERT: ("BOOLEAN", {"default": False}), } }) @@ -975,23 +975,24 @@ def INPUT_TYPES(cls) -> dict: def run(self, **kw) -> Tuple[float, int]: op = parse_param(kw, Lexicon.WAVE, EnumConvertType.STRING, EnumWave.SIN.name) - freq = parse_param(kw, Lexicon.FREQ, EnumConvertType.FLOAT, 1, 0.0001) - amp = parse_param(kw, Lexicon.AMP, EnumConvertType.FLOAT, 1, 0.0001) - phase = parse_param(kw, Lexicon.PHASE, EnumConvertType.FLOAT, 0) - shift = parse_param(kw, Lexicon.OFFSET, EnumConvertType.FLOAT, 0) - delta_time = parse_param(kw, Lexicon.TIME, EnumConvertType.FLOAT, 0, 0) + freq = parse_param(kw, Lexicon.FREQ, EnumConvertType.FLOAT, 1, 0, sys.maxsize) + amp = parse_param(kw, Lexicon.AMP, EnumConvertType.FLOAT, 1, 0, sys.maxsize) + phase = parse_param(kw, Lexicon.PHASE, EnumConvertType.FLOAT, 0, 1) + shift = parse_param(kw, Lexicon.OFFSET, EnumConvertType.FLOAT, 0, 1) + delta_time = parse_param(kw, Lexicon.TIME, EnumConvertType.FLOAT, 0, 0, sys.maxsize) invert = parse_param(kw, Lexicon.INVERT, EnumConvertType.BOOLEAN, False) abs = parse_param(kw, Lexicon.ABSOLUTE, EnumConvertType.BOOLEAN, False) results = [] params = list(zip_longest_fill(op, freq, amp, phase, shift, delta_time, invert, abs)) pbar = ProgressBar(len(params)) for idx, (op, freq, amp, phase, shift, delta_time, invert, abs) in enumerate(params): + val = wave_op(op, phase, freq, amp, shift, delta_time) # freq = 1. / freq if invert: - amp = -amp - val = wave_op(op, phase, freq, amp, shift, delta_time) + amp = 1. / val if abs: val = np.abs(val) + val = max(-sys.maxsize, min(val, sys.maxsize)) results.append([val, int(val)]) pbar.update_absolute(idx) return *list(zip(*results)), diff --git a/core/compose.py b/core/compose.py index 2c79bc3..3ada156 100644 --- a/core/compose.py +++ b/core/compose.py @@ -72,19 +72,19 @@ def INPUT_TYPES(cls) -> dict: Lexicon.PIXEL: (JOV_TYPE_IMAGE, {}), Lexicon.MASK: (JOV_TYPE_IMAGE, {}), Lexicon.FUNC: (EnumAdjustOP._member_names_, {"default": EnumAdjustOP.BLUR.name, - "tooltip":"Type of adjustment (e.g., blur, sharpen, invert)"}), - Lexicon.RADIUS: ("INT", {"default": 3, "min": 3}), - Lexicon.VALUE: ("FLOAT", {"default": 1, "min": 0}), + "tooltips":"Type of adjustment (e.g., blur, sharpen, invert)"}), + Lexicon.RADIUS: ("INT", {"default": 3, "mij": 3}), + Lexicon.VALUE: ("FLOAT", {"default": 1, "mij": 0}), Lexicon.LOHI: ("VEC2", {"default": (0, 1), - "min": 0, "max": 1, "label": [Lexicon.LO, Lexicon.HI]}), + "mij": 0, "maj": 1, "label": [Lexicon.LO, Lexicon.HI]}), Lexicon.LMH: ("VEC3", {"default": (0, 0.5, 1), - "min": 0, "max": 1, "label": [Lexicon.LO, Lexicon.MID, Lexicon.HI]}), + "mij": 0, "maj": 1, "label": [Lexicon.LO, Lexicon.MID, Lexicon.HI]}), Lexicon.HSV: ("VEC3",{"default": (0, 1, 1), - "min": 0, "max": 1, "label": [Lexicon.H, Lexicon.S, Lexicon.V]}), - Lexicon.CONTRAST: ("FLOAT", {"default": 0, "min": 0, "max": 1}), - Lexicon.GAMMA: ("FLOAT", {"default": 1, "min": 0.00001, "max": 1}), + "mij": 0, "maj": 1, "label": [Lexicon.H, Lexicon.S, Lexicon.V]}), + Lexicon.CONTRAST: ("FLOAT", {"default": 0, "mij": 0, "maj": 1}), + Lexicon.GAMMA: ("FLOAT", {"default": 1, "mij": 0.00001, "maj": 1}), Lexicon.MATTE: ("VEC4INT", {"default": (0, 0, 0, 255), "rgb": True}), - Lexicon.INVERT: ("BOOLEAN", {"default": False, "tooltip": "Invert the mask input"}) + Lexicon.INVERT: ("BOOLEAN", {"default": False, "tooltips": "Invert the mask input"}) } }) return Lexicon._parse(d, cls) @@ -107,10 +107,9 @@ def run(self, **kw) -> Tuple[torch.Tensor, ...]: images = [] pbar = ProgressBar(len(params)) for idx, (pA, mask, op, radius, val, lohi, lmh, hsv, contrast, gamma, matte, invert) in enumerate(params): - pA = tensor2cv(pA) if pA is not None else channel_solid(chan=EnumImageType.BGRA) - cc = pA.shape[2] if pA.ndim == 3 else 1 - if cc == 4: - alpha = pA[..., 3] + pA = tensor2cv(pA) if pA is not None else channel_solid(chan=EnumImageType.BGR) + alpha = pA[..., 3] if pA.ndim == 3 and pA.shape[2] == 4 else None + pA = image_convert(pA, 3) match EnumAdjustOP[op]: case EnumAdjustOP.INVERT: @@ -191,13 +190,13 @@ def run(self, **kw) -> Tuple[torch.Tensor, ...]: img_new = cv2.morphologyEx(pA, cv2.MORPH_CLOSE, (radius, radius), iterations=int(val)) h, w = pA.shape[:2] - mask = channel_solid(w, h, 255) if mask is None else tensor2cv(mask) + mask = channel_solid(w, h, (255,255,255,255)) if mask is None else tensor2cv(mask) mask = image_grayscale(mask) if invert: mask = 255 - mask pA = image_blend(pA, img_new, mask) - if cc == 4: - pA[..., 3] = alpha + if alpha is not None: + pA = image_mask_add(pA, alpha) images.append(cv2tensor_full(pA, matte)) pbar.update_absolute(idx) return [torch.cat(i, dim=0) for i in zip(*images)] @@ -215,15 +214,15 @@ def INPUT_TYPES(cls) -> dict: d = super().INPUT_TYPES() d.update({ "optional": { - Lexicon.PIXEL_A: (JOV_TYPE_IMAGE, {"tooltip": "Background Plate"}), - Lexicon.PIXEL_B: (JOV_TYPE_IMAGE, {"tooltip": "Image to Overlay on Background Plate"}), - Lexicon.MASK: (JOV_TYPE_IMAGE, {"tooltip": "Optional Mask to use for Alpha Blend Operation. If empty, will use the ALPHA of B"}), - Lexicon.FUNC: (EnumBlendType._member_names_, {"default": EnumBlendType.NORMAL.name, "tooltip": "Blending Operation"}), - Lexicon.A: ("FLOAT", {"default": 1, "min": 0, "max": 1, "tooltip": "Amount of Blending to Perform on the Selected Operation"}), + Lexicon.PIXEL_A: (JOV_TYPE_IMAGE, {"tooltips": "Background Plate"}), + Lexicon.PIXEL_B: (JOV_TYPE_IMAGE, {"tooltips": "Image to Overlay on Background Plate"}), + Lexicon.MASK: (JOV_TYPE_IMAGE, {"tooltips": "Optional Mask to use for Alpha Blend Operation. If empty, will use the ALPHA of B"}), + Lexicon.FUNC: (EnumBlendType._member_names_, {"default": EnumBlendType.NORMAL.name, "tooltips": "Blending Operation"}), + Lexicon.A: ("FLOAT", {"default": 1, "mij": 0, "maj": 1, "tooltips": "Amount of Blending to Perform on the Selected Operation"}), Lexicon.FLIP: ("BOOLEAN", {"default": False}), - Lexicon.INVERT: ("BOOLEAN", {"default": False, "tooltip": "Invert the mask input"}), + Lexicon.INVERT: ("BOOLEAN", {"default": False, "tooltips": "Invert the mask input"}), Lexicon.MODE: (EnumScaleMode._member_names_, {"default": EnumScaleMode.NONE.name}), - Lexicon.WH: ("VEC2INT", {"default": (512, 512), "min":MIN_IMAGE_SIZE, "label": [Lexicon.W, Lexicon.H]}), + Lexicon.WH: ("VEC2INT", {"default": (512, 512), "mij":MIN_IMAGE_SIZE, "label": [Lexicon.W, Lexicon.H]}), Lexicon.SAMPLE: (EnumInterpolation._member_names_, {"default": EnumInterpolation.LANCZOS4.name}), Lexicon.MATTE: ("VEC4INT", {"default": (0, 0, 0, 255), "rgb": True}) } @@ -310,7 +309,7 @@ def INPUT_TYPES(cls) -> dict: {"default": EnumCBDeficiency.PROTAN.name}), Lexicon.SIMULATOR: (EnumCBSimulator._member_names_, {"default": EnumCBSimulator.AUTOSELECT.name}), - Lexicon.VALUE: ("FLOAT", {"default": 1, "min": 0, "max": 1, "step": 0.001, "tooltip":"alpha blending"}), + Lexicon.VALUE: ("FLOAT", {"default": 1, "mij": 0, "maj": 1, "step": 0.001, "tooltips":"alpha blending"}), } }) return Lexicon._parse(d, cls) @@ -352,10 +351,10 @@ def INPUT_TYPES(cls) -> dict: {"default": EnumColorMatchMap.USER_MAP.name}), Lexicon.COLORMAP: (EnumColorMap._member_names_, {"default": EnumColorMap.HSV.name}), - Lexicon.VALUE: ("INT", {"default": 255, "min": 0, "max": 255}), + Lexicon.VALUE: ("INT", {"default": 255, "mij": 0, "maj": 255}), Lexicon.FLIP: ("BOOLEAN", {"default": False}), Lexicon.INVERT: ("BOOLEAN", {"default": False, - "tooltip": "Invert the color match output"}), + "tooltips": "Invert the color match output"}), Lexicon.MATTE: ("VEC4INT", {"default": (0, 0, 0, 255), "rgb": True}), } }) @@ -437,7 +436,7 @@ def INPUT_TYPES(cls) -> dict: "optional": { Lexicon.PIXEL: (JOV_TYPE_IMAGE, {}), Lexicon.SCHEME: (EnumColorTheory._member_names_, {"default": EnumColorTheory.COMPLIMENTARY.name}), - Lexicon.VALUE: ("INT", {"default": 45, "min": -90, "max": 90, "tooltip": "Custom angle of separation to use when calculating colors"}), + Lexicon.VALUE: ("INT", {"default": 45, "mij": -90, "maj": 90, "tooltips": "Custom angle of separation to use when calculating colors"}), Lexicon.INVERT: ("BOOLEAN", {"default": False}) } }) @@ -476,10 +475,10 @@ def INPUT_TYPES(cls) -> dict: "optional": { Lexicon.PIXEL: (JOV_TYPE_IMAGE, {}), Lexicon.FUNC: (EnumCropMode._member_names_, {"default": EnumCropMode.CENTER.name}), - Lexicon.XY: ("VEC2", {"default": (0, 0), "min": 0.5, "max": 0.5, "label": [Lexicon.X, Lexicon.Y]}), - Lexicon.WH: ("VEC2INT", {"default": (512, 512), "min": MIN_IMAGE_SIZE, "label": [Lexicon.W, Lexicon.H]}), - Lexicon.TLTR: ("VEC4", {"default": (0, 0, 0, 1), "min": 0, "max": 1, "label": [Lexicon.TOP, Lexicon.LEFT, Lexicon.TOP, Lexicon.RIGHT]}), - Lexicon.BLBR: ("VEC4", {"default": (1, 0, 1, 1), "min": 0, "max": 1, "label": [Lexicon.BOTTOM, Lexicon.LEFT, Lexicon.BOTTOM, Lexicon.RIGHT]}), + Lexicon.XY: ("VEC2", {"default": (0, 0), "mij": 0.5, "maj": 0.5, "label": [Lexicon.X, Lexicon.Y]}), + Lexicon.WH: ("VEC2INT", {"default": (512, 512), "mij": MIN_IMAGE_SIZE, "label": [Lexicon.W, Lexicon.H]}), + Lexicon.TLTR: ("VEC4", {"default": (0, 0, 0, 1), "mij": 0, "maj": 1, "label": [Lexicon.TOP, Lexicon.LEFT, Lexicon.TOP, Lexicon.RIGHT]}), + Lexicon.BLBR: ("VEC4", {"default": (1, 0, 1, 1), "mij": 0, "maj": 1, "label": [Lexicon.BOTTOM, Lexicon.LEFT, Lexicon.BOTTOM, Lexicon.RIGHT]}), Lexicon.MATTE: ("VEC4INT", {"default": (0, 0, 0, 255), "rgb": True}) } }) @@ -542,9 +541,9 @@ def INPUT_TYPES(cls) -> dict: "optional": { Lexicon.PIXEL_A: (JOV_TYPE_IMAGE, {}), Lexicon.START: ("VEC3INT", {"default": (128, 128, 128), "rgb": True}), - Lexicon.BOOLEAN: ("BOOLEAN", {"default": False, "tooltip": "use an end point (start->end) when calculating the filter range"}), + Lexicon.BOOLEAN: ("BOOLEAN", {"default": False, "tooltips": "use an end point (start->end) when calculating the filter range"}), Lexicon.END: ("VEC3INT", {"default": (128, 128, 128), "rgb": True}), - Lexicon.FLOAT: ("VEC3", {"default": (0.5,0.5,0.5), "min":0, "max":1, "tooltip": "the fuzziness use to extend the start and end range(s)"}), + Lexicon.FLOAT: ("VEC3", {"default": (0.5,0.5,0.5), "mij":0, "maj":1, "tooltips": "the fuzziness use to extend the start and end range(s)"}), Lexicon.MATTE: ("VEC4INT", {"default": (0, 0, 0, 255), "rgb": True}), } }) @@ -586,7 +585,7 @@ def INPUT_TYPES(cls) -> dict: d.update({ "optional": { Lexicon.MODE: (EnumScaleMode._member_names_, {"default": EnumScaleMode.NONE.name}), - Lexicon.WH: ("VEC2INT", {"default": (512, 512), "min":MIN_IMAGE_SIZE, "label": [Lexicon.W, Lexicon.H]}), + Lexicon.WH: ("VEC2INT", {"default": (512, 512), "mij":MIN_IMAGE_SIZE, "label": [Lexicon.W, Lexicon.H]}), Lexicon.SAMPLE: (EnumInterpolation._member_names_, {"default": EnumInterpolation.LANCZOS4.name}), Lexicon.MATTE: ("VEC4INT", {"default": (0, 0, 0, 255), "rgb": True}) } @@ -636,11 +635,11 @@ def INPUT_TYPES(cls) -> dict: d = super().INPUT_TYPES() d.update({ "optional": { - Lexicon.PIXEL: (JOV_TYPE_IMAGE, {"tooltip":"Image to remap with gradient input"}), - Lexicon.GRADIENT: (JOV_TYPE_IMAGE, {"tooltip":f"Look up table (LUT) to remap the input image in `{Lexicon.PIXEL}`"}), - Lexicon.FLIP: ("BOOLEAN", {"default":False, "tooltip":"Reverse the gradient from left-to-right "}), + Lexicon.PIXEL: (JOV_TYPE_IMAGE, {"tooltips":"Image to remap with gradient input"}), + Lexicon.GRADIENT: (JOV_TYPE_IMAGE, {"tooltips":f"Look up table (LUT) to remap the input image in `{Lexicon.PIXEL}`"}), + Lexicon.FLIP: ("BOOLEAN", {"default":False, "tooltips":"Reverse the gradient from left-to-right "}), Lexicon.MODE: (EnumScaleMode._member_names_, {"default": EnumScaleMode.NONE.name}), - Lexicon.WH: ("VEC2INT", {"default": (512, 512), "min":MIN_IMAGE_SIZE, "label": [Lexicon.W, Lexicon.H]}), + Lexicon.WH: ("VEC2INT", {"default": (512, 512), "mij":MIN_IMAGE_SIZE, "label": [Lexicon.W, Lexicon.H]}), Lexicon.SAMPLE: (EnumInterpolation._member_names_, {"default": EnumInterpolation.LANCZOS4.name}), Lexicon.MATTE: ("VEC4INT", {"default": (0, 0, 0, 255), "rgb": True}) } @@ -659,8 +658,11 @@ def run(self, **kw) -> torch.Tensor: params = list(zip_longest_fill(pA, gradient, flip, mode, sample, wihi, matte)) pbar = ProgressBar(len(params)) for idx, (pA, gradient, flip, mode, sample, wihi, matte) in enumerate(params): - pA = channel_solid(chan=EnumImageType.BGRA) if pA is None else tensor2cv(pA) - gradient = channel_solid(chan=EnumImageType.BGRA) if gradient is None else tensor2cv(gradient) + pA = channel_solid(chan=EnumImageType.BGR) if pA is None else tensor2cv(pA) + if pA.ndim == 3 and pA.shape[2] == 4: + mask = image_mask(pA) + + gradient = channel_solid(chan=EnumImageType.BGR) if gradient is None else tensor2cv(gradient) pA = image_gradient_map(pA, gradient) # @TODO: pattern o' scale... when make it a lambda? mode = EnumScaleMode[mode] @@ -669,6 +671,8 @@ def run(self, **kw) -> torch.Tensor: sample = EnumInterpolation[sample] pA = image_scalefit(pA, w, h, mode, sample) # + if mask is not None: + pA = image_mask_add(pA, mask) images.append(cv2tensor_full(pA, matte)) pbar.update_absolute(idx) return [torch.cat(i, dim=0) for i in zip(*images)] @@ -692,11 +696,11 @@ def INPUT_TYPES(cls) -> dict: Lexicon.B: (JOV_TYPE_IMAGE, {}), Lexicon.A: (JOV_TYPE_IMAGE, {}), Lexicon.MODE: (EnumScaleMode._member_names_, {"default": EnumScaleMode.NONE.name}), - Lexicon.WH: ("VEC2INT", {"default": (512, 512), "min":MIN_IMAGE_SIZE, "label": [Lexicon.W, Lexicon.H]}), + Lexicon.WH: ("VEC2INT", {"default": (512, 512), "mij":MIN_IMAGE_SIZE, "label": [Lexicon.W, Lexicon.H]}), Lexicon.SAMPLE: (EnumInterpolation._member_names_, {"default": EnumInterpolation.LANCZOS4.name}), Lexicon.MATTE: ("VEC4INT", {"default": (0, 0, 0, 255), "rgb": True}), - Lexicon.FLIP: ("VEC4", {"min":0, "max":1, "tooltip": "Invert specific input prior to merging. R, G, B, A."}), - Lexicon.INVERT: ("BOOLEAN", {"default": False, "tooltip": "Invert the final merged output"}) + Lexicon.FLIP: ("VEC4", {"mij":0, "maj":1, "tooltips": "Invert specific input prior to merging. R, G, B, A."}), + Lexicon.INVERT: ("BOOLEAN", {"default": False, "tooltips": "Invert the final merged output"}) } }) return Lexicon._parse(d, cls) @@ -796,16 +800,16 @@ def INPUT_TYPES(cls) -> dict: Lexicon.PIXEL_B: (JOV_TYPE_IMAGE, {}), Lexicon.SWAP_R: (EnumPixelSwizzle._member_names_, {"default": EnumPixelSwizzle.RED_A.name}), - Lexicon.R: ("INT", {"default": 0, "min": 0, "max": 255}), + Lexicon.R: ("INT", {"default": 0, "mij": 0, "maj": 255}), Lexicon.SWAP_G: (EnumPixelSwizzle._member_names_, {"default": EnumPixelSwizzle.GREEN_A.name}), - Lexicon.G: ("INT", {"default": 0, "min": 0, "max": 255}), + Lexicon.G: ("INT", {"default": 0, "mij": 0, "maj": 255}), Lexicon.SWAP_B: (EnumPixelSwizzle._member_names_, {"default": EnumPixelSwizzle.BLUE_A.name}), - Lexicon.B: ("INT", {"default": 0, "min": 0, "max": 255}), + Lexicon.B: ("INT", {"default": 0, "mij": 0, "maj": 255}), Lexicon.SWAP_A: (EnumPixelSwizzle._member_names_, {"default": EnumPixelSwizzle.ALPHA_A.name}), - Lexicon.A: ("INT", {"default": 0, "min": 0, "max": 255}), + Lexicon.A: ("INT", {"default": 0, "mij": 0, "maj": 255}), } }) return Lexicon._parse(d, cls) @@ -874,11 +878,11 @@ def INPUT_TYPES(cls) -> dict: d.update({ "optional": { Lexicon.AXIS: (EnumOrientation._member_names_, {"default": EnumOrientation.GRID.name, - "tooltip":"Choose the direction in which to stack the images. Options include horizontal, vertical, or a grid layout"}), - Lexicon.STEP: ("INT", {"min": 0, "default": 1, - "tooltip":"Specify the spacing between each stacked image. This determines how far apart the images are from each other"}), + "tooltips":"Choose the direction in which to stack the images. Options include horizontal, vertical, or a grid layout"}), + Lexicon.STEP: ("INT", {"mij": 0, "default": 1, + "tooltips":"Specify the spacing between each stacked image. This determines how far apart the images are from each other"}), Lexicon.MODE: (EnumScaleMode._member_names_, {"default": EnumScaleMode.NONE.name}), - Lexicon.WH: ("VEC2INT", {"default": (512, 512), "min":MIN_IMAGE_SIZE, "label": [Lexicon.W, Lexicon.H]}), + Lexicon.WH: ("VEC2INT", {"default": (512, 512), "mij":MIN_IMAGE_SIZE, "label": [Lexicon.W, Lexicon.H]}), Lexicon.SAMPLE: (EnumInterpolation._member_names_, {"default": EnumInterpolation.LANCZOS4.name}), Lexicon.MATTE: ("VEC4INT", {"default": (0, 0, 0, 255), "rgb": True}) } @@ -926,9 +930,9 @@ def INPUT_TYPES(cls) -> dict: Lexicon.ADAPT: ( EnumThresholdAdapt._member_names_, {"default": EnumThresholdAdapt.ADAPT_NONE.name}), Lexicon.FUNC: ( EnumThreshold._member_names_, {"default": EnumThreshold.BINARY.name}), - Lexicon.THRESHOLD: ("FLOAT", {"default": 0.5, "min": 0, "max": 1, "step": 0.005}), - Lexicon.SIZE: ("INT", {"default": 3, "min": 3, "max": 103}), - Lexicon.INVERT: ("BOOLEAN", {"default": False, "tooltip": "Invert the mask input"}) + Lexicon.THRESHOLD: ("FLOAT", {"default": 0.5, "mij": 0, "maj": 1, "step": 0.005}), + Lexicon.SIZE: ("INT", {"default": 3, "mij": 3, "maj": 103}), + Lexicon.INVERT: ("BOOLEAN", {"default": False, "tooltips": "Invert the mask input"}) } }) return Lexicon._parse(d, cls) @@ -968,19 +972,19 @@ def INPUT_TYPES(cls) -> dict: d.update({ "optional": { Lexicon.PIXEL: (JOV_TYPE_IMAGE, {}), - Lexicon.XY: ("VEC2", {"default": (0, 0,), "min": -1, "max": 1, "label": [Lexicon.X, Lexicon.Y]}), + Lexicon.XY: ("VEC2", {"default": (0, 0,), "mij": -1, "maj": 1, "label": [Lexicon.X, Lexicon.Y]}), Lexicon.ANGLE: ("FLOAT", {"default": 0}), - Lexicon.SIZE: ("VEC2", {"default": (1., 1.), "min": 0.001, "label": [Lexicon.X, Lexicon.Y]}), - Lexicon.TILE: ("VEC2", {"default": (1., 1.), "min": 1, "label": [Lexicon.X, Lexicon.Y]}), + Lexicon.SIZE: ("VEC2", {"default": (1., 1.), "mij": 0.001, "label": [Lexicon.X, Lexicon.Y]}), + Lexicon.TILE: ("VEC2", {"default": (1., 1.), "mij": 1, "label": [Lexicon.X, Lexicon.Y]}), Lexicon.EDGE: (EnumEdge._member_names_, {"default": EnumEdge.CLIP.name}), Lexicon.MIRROR: (EnumMirrorMode._member_names_, {"default": EnumMirrorMode.NONE.name}), Lexicon.PIVOT: ("VEC2", {"default": (0.5, 0.5), "step": 0.005, "label": [Lexicon.X, Lexicon.Y]}), Lexicon.PROJECTION: (EnumProjection._member_names_, {"default": EnumProjection.NORMAL.name}), Lexicon.TLTR: ("VEC4", {"default": (0, 0, 1, 0), "step": 0.005, "label": [Lexicon.TOP, Lexicon.LEFT, Lexicon.TOP, Lexicon.RIGHT]}), Lexicon.BLBR: ("VEC4", {"default": (0, 1, 1, 1), "step": 0.005, "label": [Lexicon.BOTTOM, Lexicon.LEFT, Lexicon.BOTTOM, Lexicon.RIGHT]}), - Lexicon.STRENGTH: ("FLOAT", {"default": 1, "min": 0, "step": 0.005}), + Lexicon.STRENGTH: ("FLOAT", {"default": 1, "mij": 0, "step": 0.005}), Lexicon.MODE: (EnumScaleMode._member_names_, {"default": EnumScaleMode.NONE.name}), - Lexicon.WH: ("VEC2INT", {"default": (512, 512), "min":MIN_IMAGE_SIZE, "label": [Lexicon.W, Lexicon.H]}), + Lexicon.WH: ("VEC2INT", {"default": (512, 512), "mij":MIN_IMAGE_SIZE, "label": [Lexicon.W, Lexicon.H]}), Lexicon.SAMPLE: (EnumInterpolation._member_names_, {"default": EnumInterpolation.LANCZOS4.name}), Lexicon.MATTE: ("VEC4INT", {"default": (0, 0, 0, 255), "rgb": True}) } diff --git a/core/create.py b/core/create.py index db4dfcd..7ac2c2e 100644 --- a/core/create.py +++ b/core/create.py @@ -48,12 +48,12 @@ def INPUT_TYPES(cls) -> dict: d = super().INPUT_TYPES() d.update({ "optional": { - Lexicon.PIXEL: (JOV_TYPE_IMAGE, {"tooltip":"Optional Image to Matte with Selected Color"}), + Lexicon.PIXEL: (JOV_TYPE_IMAGE, {"tooltips":"Optional Image to Matte with Selected Color"}), Lexicon.RGBA_A: ("VEC4INT", {"default": (0, 0, 0, 255), - "rgb": True, "tooltip": "Constant Color to Output"}), + "rgb": True, "tooltips": "Constant Color to Output"}), Lexicon.WH: ("VEC2INT", {"default": (512, 512), "label": [Lexicon.W, Lexicon.H], - "tooltip": "Desired Width and Height of the Color Output"}), + "tooltips": "Desired Width and Height of the Color Output"}), Lexicon.MODE: (EnumScaleMode._member_names_, {"default": EnumScaleMode.NONE.name}), Lexicon.SAMPLE: (EnumInterpolation._member_names_, {"default": EnumInterpolation.LANCZOS4.name}), } @@ -97,15 +97,15 @@ def INPUT_TYPES(cls) -> dict: d.update({ "optional": { Lexicon.SHAPE: (EnumShapes._member_names_, {"default": EnumShapes.CIRCLE.name}), - Lexicon.SIDES: ("INT", {"default": 3, "min": 3, "max": 100}), - Lexicon.RGBA_A: ("VEC4INT", {"default": (255, 255, 255, 255), "rgb": True, "tooltip": "Main Shape Color"}), - Lexicon.MATTE: ("VEC4INT", {"default": (0, 0, 0, 255), "rgb": True, "tooltip": "Background Color"}), - Lexicon.WH: ("VEC2INT", {"default": (256, 256), "min":MIN_IMAGE_SIZE, "label": [Lexicon.W, Lexicon.H]}), + Lexicon.SIDES: ("INT", {"default": 3, "mij": 3, "maj": 100}), + Lexicon.RGBA_A: ("VEC4INT", {"default": (255, 255, 255, 255), "rgb": True, "tooltips": "Main Shape Color"}), + Lexicon.MATTE: ("VEC4INT", {"default": (0, 0, 0, 255), "rgb": True, "tooltips": "Background Color"}), + Lexicon.WH: ("VEC2INT", {"default": (256, 256), "mij":MIN_IMAGE_SIZE, "label": [Lexicon.W, Lexicon.H]}), Lexicon.XY: ("VEC2", {"default": (0, 0,), "label": [Lexicon.X, Lexicon.Y]}), - Lexicon.ANGLE: ("FLOAT", {"default": 0, "min": -180, "max": 180}), + Lexicon.ANGLE: ("FLOAT", {"default": 0, "mij": -180, "maj": 180}), Lexicon.SIZE: ("VEC2", {"default": (1., 1.), "label": [Lexicon.X, Lexicon.Y]}), Lexicon.EDGE: (EnumEdge._member_names_, {"default": EnumEdge.CLIP.name}), - Lexicon.BLUR: ("FLOAT", {"default": 0, "min": 0, "tooltip": "Edge blur amount (Gaussian blur)"}), + Lexicon.BLUR: ("FLOAT", {"default": 0, "mij": 0, "tooltips": "Edge blur amount (Gaussian blur)"}), } }) return Lexicon._parse(d, cls) @@ -177,10 +177,10 @@ def INPUT_TYPES(cls) -> dict: "optional": { Lexicon.PIXEL: (JOV_TYPE_IMAGE, {}), Lexicon.DEPTH: (JOV_TYPE_IMAGE, {}), - Lexicon.TILE: ("INT", {"default": 8, "min": 1}), - Lexicon.NOISE: ("FLOAT", {"default": 0.33, "min": 0, "max": 1}), - Lexicon.GAMMA: ("FLOAT", {"default": 0.33, "min": 0, "max": 1}), - Lexicon.SHIFT: ("FLOAT", {"default": 1., "min": -1, "max": 1}), + Lexicon.TILE: ("INT", {"default": 8, "mij": 1}), + Lexicon.NOISE: ("FLOAT", {"default": 0.33, "mij": 0, "maj": 1}), + Lexicon.GAMMA: ("FLOAT", {"default": 0.33, "mij": 0, "maj": 1}), + Lexicon.SHIFT: ("FLOAT", {"default": 1., "mij": -1, "maj": 1}), Lexicon.INVERT: ("BOOLEAN", {"default": False}), } }) @@ -221,9 +221,9 @@ def INPUT_TYPES(cls) -> dict: d = super().INPUT_TYPES() d.update({ "optional": { - Lexicon.PIXEL: (JOV_TYPE_IMAGE, {"tooltip":"Optional Image to Matte with Selected Color"}), - Lexicon.INT: ("FLOAT", {"default": 0.1, "min": 0, "max": 1, "tooltip":"Baseline"}), - Lexicon.FOCAL: ("FLOAT", {"default": 500, "min": 0}), + Lexicon.PIXEL: (JOV_TYPE_IMAGE, {"tooltips":"Optional Image to Matte with Selected Color"}), + Lexicon.INT: ("FLOAT", {"default": 0.1, "mij": 0, "maj": 1, "tooltips":"Baseline"}), + Lexicon.FOCAL: ("FLOAT", {"default": 500, "mij": 0}), } }) return Lexicon._parse(d, cls) @@ -261,27 +261,27 @@ def INPUT_TYPES(cls) -> dict: "optional": { Lexicon.STRING: ("STRING", {"default": "jovimetrix", "multiline": True, "dynamicPrompts": False, - "tooltip": "Your Message"}), + "tooltips": "Your Message"}), Lexicon.FONT: (cls.FONT_NAMES, {"default": cls.FONT_NAMES[0]}), Lexicon.LETTER: ("BOOLEAN", {"default": False}), Lexicon.AUTOSIZE: ("BOOLEAN", {"default": False}), - Lexicon.RGBA_A: ("VEC4INT", {"default": (255, 255, 255, 255), "rgb": True, "tooltip": "Color of the letters"}), + Lexicon.RGBA_A: ("VEC4INT", {"default": (255, 255, 255, 255), "rgb": True, "tooltips": "Color of the letters"}), Lexicon.MATTE: ("VEC4INT", {"default": (0, 0, 0, 255), "rgb": True}), - Lexicon.COLUMNS: ("INT", {"default": 0, "min": 0}), + Lexicon.COLUMNS: ("INT", {"default": 0, "mij": 0}), # if auto on, hide these... - Lexicon.FONT_SIZE: ("INT", {"default": 16, "min": 8}), + Lexicon.FONT_SIZE: ("INT", {"default": 16, "mij": 8}), Lexicon.ALIGN: (EnumAlignment._member_names_, {"default": EnumAlignment.CENTER.name}), Lexicon.JUSTIFY: (EnumJustify._member_names_, {"default": EnumJustify.CENTER.name}), - Lexicon.MARGIN: ("INT", {"default": 0, "min": -1024, "max": 1024}), - Lexicon.SPACING: ("INT", {"default": 25, "min": -1024, "max": 1024}), + Lexicon.MARGIN: ("INT", {"default": 0, "mij": -1024, "maj": 1024}), + Lexicon.SPACING: ("INT", {"default": 25, "mij": -1024, "maj": 1024}), Lexicon.WH: ("VEC2INT", {"default": (256, 256), - "min":MIN_IMAGE_SIZE, "label": [Lexicon.W, Lexicon.H]}), - Lexicon.XY: ("VEC2", {"default": (0, 0,), "min": -1, "max": 1, + "mij":MIN_IMAGE_SIZE, "label": [Lexicon.W, Lexicon.H]}), + Lexicon.XY: ("VEC2", {"default": (0, 0,), "mij": -1, "maj": 1, "label": [Lexicon.X, Lexicon.Y], - "tooltip":"Offset the position"}), + "tooltips":"Offset the position"}), Lexicon.ANGLE: ("FLOAT", {"default": 0}), Lexicon.EDGE: (EnumEdge._member_names_, {"default": EnumEdge.CLIP.name}), - Lexicon.INVERT: ("BOOLEAN", {"default": False, "tooltip": "Invert the mask input"}) + Lexicon.INVERT: ("BOOLEAN", {"default": False, "tooltips": "Invert the mask input"}) } }) return Lexicon._parse(d, cls) @@ -359,13 +359,13 @@ def INPUT_TYPES(cls) -> dict: d = super().INPUT_TYPES() d.update({ "optional": { - Lexicon.WAVE: ("AUDIO", {"default": None, "tooltip": "Audio Wave Object"}), - Lexicon.VALUE: ("INT", {"default": 100, "min": 32, "max": 8192, - "tooltip": "Number of Vertical bars to try to fit within the specified Width x Height"}), - Lexicon.THICK: ("FLOAT", {"default": 0.72, "min": 0, "max": 1, - "tooltip": "The percentage of fullness for each bar; currently scaled from the left only"}), - Lexicon.WH: ("VEC2INT", {"default": (256, 256), "min":MIN_IMAGE_SIZE, "label": [Lexicon.W, Lexicon.H], "tooltip": "Final output size of the wave bar graph"}), - Lexicon.RGBA_A: ("VEC4INT", {"default": (128, 128, 0, 255), "rgb": True, "tooltip": "Bar Color"}), + Lexicon.WAVE: ("AUDIO", {"default": None, "tooltips": "Audio Wave Object"}), + Lexicon.VALUE: ("INT", {"default": 100, "mij": 32, "maj": 8192, + "tooltips": "Number of Vertical bars to try to fit within the specified Width x Height"}), + Lexicon.THICK: ("FLOAT", {"default": 0.72, "mij": 0, "maj": 1, + "tooltips": "The percentage of fullness for each bar; currently scaled from the left only"}), + Lexicon.WH: ("VEC2INT", {"default": (256, 256), "mij":MIN_IMAGE_SIZE, "label": [Lexicon.W, Lexicon.H], "tooltips": "Final output size of the wave bar graph"}), + Lexicon.RGBA_A: ("VEC4INT", {"default": (128, 128, 0, 255), "rgb": True, "tooltips": "Bar Color"}), Lexicon.MATTE: ("VEC4INT", {"default": (0, 128, 128, 255), "rgb": True}) } }) diff --git a/core/create_glsl.py b/core/create_glsl.py index 5f4fcf5..f6a0228 100644 --- a/core/create_glsl.py +++ b/core/create_glsl.py @@ -92,7 +92,7 @@ def INPUT_TYPES(cls) -> dict: d.update({ "optional": { Lexicon.MODE: (EnumScaleMode._member_names_, {"default": EnumScaleMode.NONE.name}), - Lexicon.WH: ("VEC2INT", {"default": (512, 512), "min":MIN_IMAGE_SIZE, "label": [Lexicon.W, Lexicon.H]}), + Lexicon.WH: ("VEC2INT", {"default": (512, 512), "mij":MIN_IMAGE_SIZE, "label": [Lexicon.W, Lexicon.H]}), Lexicon.SAMPLE: (EnumInterpolation._member_names_, {"default": EnumInterpolation.LANCZOS4.name}), Lexicon.MATTE: ("VEC4INT", {"default": (0, 0, 0, 255), "rgb": True}) } @@ -183,9 +183,9 @@ def INPUT_TYPES(cls) -> dict: d = super().INPUT_TYPES() opts = d.get('optional', {}) opts.update({ - Lexicon.BATCH: ("INT", {"default": 0, "min": 0, "max": 1048576}), - Lexicon.FPS: ("INT", {"default": 24, "min": 1, "max": 120}), - Lexicon.TIME: ("FLOAT", {"default": 0, "step": 0.0001, "min": 0}), + Lexicon.BATCH: ("INT", {"default": 0, "mij": 0, "maj": 1048576}), + Lexicon.FPS: ("INT", {"default": 24, "mij": 1, "maj": 120}), + Lexicon.TIME: ("FLOAT", {"default": 0, "step": 0.0001, "mij": 0}), Lexicon.PROG_VERT: ("STRING", {"default": GLSLShader.PROG_VERTEX, "multiline": True, "dynamicPrompts": False}), Lexicon.PROG_FRAG: ("STRING", {"default": GLSLShader.PROG_FRAGMENT, "multiline": True, "dynamicPrompts": False}), }) @@ -237,7 +237,7 @@ def INPUT_TYPES(cls) -> dict: params['val_step'] = parse_value(val_step, EnumConvertType.FLOAT, d) if tooltip is not None: - params['tooltip'] = tooltip + params["tooltips"] = tooltip data[name] = (typ.name, params,) data.update(opts) diff --git a/core/device_midi.py b/core/device_midi.py index 9a85dad..86e88d3 100644 --- a/core/device_midi.py +++ b/core/device_midi.py @@ -139,11 +139,11 @@ def INPUT_TYPES(cls) -> dict: "optional": { Lexicon.MIDI: ('JMIDIMSG', {"default": None}), Lexicon.MODE: (MIDINoteOnFilter._member_names_, {"default": MIDINoteOnFilter.IGNORE.name}), - Lexicon.CHANNEL: ("INT", {"default": -1, "min": -1, "max": 127}), - Lexicon.CONTROL: ("INT", {"default": -1, "min": -1, "max": 127}), - Lexicon.NOTE: ("INT", {"default": -1, "min": -1, "max": 127}), - Lexicon.VALUE: ("INT", {"default": -1, "min": -1, "max": 127}), - Lexicon.NORMALIZE: ("FLOAT", {"default": -1, "min": -1, "max": 1}) + Lexicon.CHANNEL: ("INT", {"default": -1, "mij": -1, "maj": 127}), + Lexicon.CONTROL: ("INT", {"default": -1, "mij": -1, "maj": 127}), + Lexicon.NOTE: ("INT", {"default": -1, "mij": -1, "maj": 127}), + Lexicon.VALUE: ("INT", {"default": -1, "mij": -1, "maj": 127}), + Lexicon.NORMALIZE: ("FLOAT", {"default": -1, "mij": -1, "maj": 1}) } }) return Lexicon._parse(d, cls) diff --git a/core/device_stream.py b/core/device_stream.py index ba7a591..5997fea 100644 --- a/core/device_stream.py +++ b/core/device_stream.py @@ -93,13 +93,13 @@ def INPUT_TYPES(cls) -> dict: Lexicon.WINDOW: (window, {"default": window_default, "choice": "list of available system windows"}), Lexicon.DPI: ("BOOLEAN", {"default": True}), Lexicon.BBOX: ("VEC4", {"default": (0, 0, 1, 1), "label": [Lexicon.TOP, Lexicon.LEFT, Lexicon.BOTTOM, Lexicon.RIGHT]}), - Lexicon.FPS: ("INT", {"min": 1, "max": 60, "default": 30}), + Lexicon.FPS: ("INT", {"mij": 1, "maj": 60, "default": 30}), Lexicon.WAIT: ("BOOLEAN", {"default": False}), - Lexicon.BATCH: ("VEC2INT", {"default": (1, 30), "label": ["COUNT", "FPS"], "tooltip": "Number of frames wanted and the FPS"}), + Lexicon.BATCH: ("VEC2INT", {"default": (1, 30), "label": ["COUNT", "FPS"], "tooltips": "Number of frames wanted and the FPS"}), Lexicon.ORIENT: (EnumCanvasOrientation._member_names_, {"default": EnumCanvasOrientation.NORMAL.name}), - Lexicon.ZOOM: ("FLOAT", {"min": 0, "max": 1, "step": 0.005, "default": 0.}), + Lexicon.ZOOM: ("FLOAT", {"mij": 0, "maj": 1, "step": 0.005, "default": 0.}), Lexicon.MODE: (EnumScaleMode._member_names_, {"default": EnumScaleMode.NONE.name}), - Lexicon.WH: ("VEC2INT", {"default": (512, 512), "min":MIN_IMAGE_SIZE, "label": [Lexicon.W, Lexicon.H]}), + Lexicon.WH: ("VEC2INT", {"default": (512, 512), "mij":MIN_IMAGE_SIZE, "label": [Lexicon.W, Lexicon.H]}), Lexicon.SAMPLE: (EnumInterpolation._member_names_, {"default": EnumInterpolation.LANCZOS4.name}), Lexicon.MATTE: ("VEC4INT", {"default": (0, 0, 0, 255), "rgb": True}) } @@ -274,7 +274,7 @@ def INPUT_TYPES(cls) -> dict: Lexicon.PIXEL: (JOV_TYPE_IMAGE, {}), Lexicon.ROUTE: ("STRING", {"default": "/stream"}), Lexicon.MODE: (EnumScaleMode._member_names_, {"default": EnumScaleMode.NONE.name}), - Lexicon.WH: ("VEC2INT", {"default": (512, 512), "min":MIN_IMAGE_SIZE, "label": [Lexicon.W, Lexicon.H]}), + Lexicon.WH: ("VEC2INT", {"default": (512, 512), "mij":MIN_IMAGE_SIZE, "label": [Lexicon.W, Lexicon.H]}), Lexicon.SAMPLE: (EnumInterpolation._member_names_, {"default": EnumInterpolation.LANCZOS4.name}), Lexicon.MATTE: ("VEC4INT", {"default": (0, 0, 0, 0), "rgb": True}) } @@ -344,9 +344,9 @@ def INPUT_TYPES(cls) -> dict: "optional": { Lexicon.PIXEL: (JOV_TYPE_IMAGE, {}), Lexicon.ROUTE: ("STRING", {"default": "Spout Sender"}), - Lexicon.FPS: ("INT", {"min": 0, "max": 60, "default": 30, "tooltip": "@@@ NOT USED @@@"}), + Lexicon.FPS: ("INT", {"mij": 0, "maj": 60, "default": 30, "tooltips": "@@@ NOT USED @@@"}), Lexicon.MODE: (EnumScaleMode._member_names_, {"default": EnumScaleMode.NONE.name}), - Lexicon.WH: ("VEC2INT", {"default": (512, 512), "min":MIN_IMAGE_SIZE, "label": [Lexicon.W, Lexicon.H]}), + Lexicon.WH: ("VEC2INT", {"default": (512, 512), "mij":MIN_IMAGE_SIZE, "label": [Lexicon.W, Lexicon.H]}), Lexicon.SAMPLE: (EnumInterpolation._member_names_, {"default": EnumInterpolation.LANCZOS4.name}), Lexicon.MATTE: ("VEC4INT", {"default": (0, 0, 0, 255), "rgb": True}) } diff --git a/core/utility.py b/core/utility.py index 0a18688..03831ac 100644 --- a/core/utility.py +++ b/core/utility.py @@ -32,8 +32,8 @@ from Jovimetrix.sup.util import parse_dynamic, path_next, \ parse_param, zip_longest_fill, EnumConvertType -from Jovimetrix.sup.image import cv2tensor, image_convert, image_matte, tensor2cv, \ - pil2tensor, image_load, image_formats, tensor2pil, MIN_IMAGE_SIZE +from Jovimetrix.sup.image import cv2tensor, image_by_size, image_convert, \ + image_matte, tensor2cv, pil2tensor, image_load, image_formats, tensor2pil, MIN_IMAGE_SIZE # ============================================================================= @@ -144,20 +144,20 @@ def INPUT_TYPES(cls) -> dict: d = super().INPUT_TYPES() d.update({ "optional": { - Lexicon.BATCH_MODE: (EnumBatchMode._member_names_, {"default": EnumBatchMode.MERGE.name, "tooltip":"Select a single index, specific range, custom index list or randomized"}), - Lexicon.INDEX: ("INT", {"default": 0, "min": 0, "tooltip":"Selected list position"}), - Lexicon.RANGE: ("VEC3", {"default": (0, 0, 1), "min": 0}), - Lexicon.STRING: ("STRING", {"default": "", "tooltip":"Comma separated list of indicies to export"}), - Lexicon.SEED: ("INT", {"default": 0, "min": 0, "max": sys.maxsize}), - Lexicon.COUNT: ("INT", {"default": 0, "min": 0, "max": sys.maxsize, "tooltip":"How many items to return"}), - Lexicon.FLIP: ("BOOLEAN", {"default": False, "tooltip":"invert the calculated output list"}), - Lexicon.BATCH_CHUNK: ("INT", {"default": 0, "min": 0,}), + Lexicon.BATCH_MODE: (EnumBatchMode._member_names_, {"default": EnumBatchMode.MERGE.name, "tooltips":"Select a single index, specific range, custom index list or randomized"}), + Lexicon.INDEX: ("INT", {"default": 0, "mij": 0, "tooltips":"Selected list position"}), + Lexicon.RANGE: ("VEC3", {"default": (0, 0, 1), "mij": 0}), + Lexicon.STRING: ("STRING", {"default": "", "tooltips":"Comma separated list of indicies to export"}), + Lexicon.SEED: ("INT", {"default": 0, "mij": 0, "maj": sys.maxsize}), + Lexicon.COUNT: ("INT", {"default": 0, "mij": 0, "maj": sys.maxsize, "tooltips":"How many items to return"}), + Lexicon.FLIP: ("BOOLEAN", {"default": False, "tooltips":"invert the calculated output list"}), + Lexicon.BATCH_CHUNK: ("INT", {"default": 0, "mij": 0,}), }, "outputs": { - 0: (Lexicon.ANY_OUT, {"tooltip":"Output list from selected operation"}), - 1: (Lexicon.LENGTH, {"tooltip":"Length of output list"}), - 2: (Lexicon.LIST, {"tooltip":"Full list"}), - 3: (Lexicon.LENGTH2, {"tooltip":"Length of all input elements"}), + 0: (Lexicon.ANY_OUT, {"tooltips":"Output list from selected operation"}), + 1: (Lexicon.LENGTH, {"tooltips":"Length of output list"}), + 2: (Lexicon.LIST, {"tooltips":"Full list"}), + 3: (Lexicon.LENGTH2, {"tooltips":"Length of all input elements"}), } }) return Lexicon._parse(d, cls) @@ -184,7 +184,7 @@ def run(self, **kw) -> Tuple[int, list]: slice_range = parse_param(kw, Lexicon.RANGE, EnumConvertType.VEC3INT, [(0, 0, 1)])[0] indices = parse_param(kw, Lexicon.STRING, EnumConvertType.STRING, "")[0] seed = parse_param(kw, Lexicon.SEED, EnumConvertType.INT, 0)[0] - count = parse_param(kw, Lexicon.COUNT, EnumConvertType.INT, 0, 0)[0] + count = parse_param(kw, Lexicon.COUNT, EnumConvertType.INT, 0, 0, sys.maxsize)[0] flip = parse_param(kw, Lexicon.FLIP, EnumConvertType.BOOLEAN, False)[0] batch_chunk = parse_param(kw, Lexicon.BATCH_CHUNK, EnumConvertType.INT, 0, 0)[0] @@ -260,6 +260,10 @@ def run(self, **kw) -> Tuple[int, list]: size = len(results) if output_is_image: + _, w, h = image_by_size(results) + print(w, h) + results = [image_convert(i, 4) for i in results] + results = [image_matte(i, (0,0,0,0), w, h) for i in results] results = torch.stack(results, dim=0) size = results.shape[0] return results, size, full_list, len(full_list) @@ -287,12 +291,12 @@ def INPUT_TYPES(cls) -> dict: # GIF ONLY Lexicon.OPTIMIZE: ("BOOLEAN", {"default": False}), # GIFSKI ONLY - Lexicon.QUALITY: ("INT", {"default": 90, "min": 1, "max": 100}), - Lexicon.QUALITY_M: ("INT", {"default": 100, "min": 1, "max": 100}), + Lexicon.QUALITY: ("INT", {"default": 90, "mij": 1, "maj": 100}), + Lexicon.QUALITY_M: ("INT", {"default": 100, "mij": 1, "maj": 100}), # GIF OR GIFSKI - Lexicon.FPS: ("INT", {"default": 24, "min": 1, "max": 60}), + Lexicon.FPS: ("INT", {"default": 24, "mij": 1, "maj": 60}), # GIF OR GIFSKI - Lexicon.LOOP: ("INT", {"default": 0, "min": 0}), + Lexicon.LOOP: ("INT", {"default": 0, "mij": 0}), } }) return Lexicon._parse(d, cls) @@ -378,11 +382,11 @@ def INPUT_TYPES(cls) -> dict: d.update({ "optional": { Lexicon.RESET: ("BOOLEAN", {"default": False}), - Lexicon.VALUE: ("INT", {"default": 60, "min": 0, "tooltip":"Number of values to graph and display"}), - Lexicon.WH: ("VEC2INT", {"default": (512, 512), "min":MIN_IMAGE_SIZE, "label": [Lexicon.W, Lexicon.H]}) + Lexicon.VALUE: ("INT", {"default": 60, "mij": 0, "tooltips":"Number of values to graph and display"}), + Lexicon.WH: ("VEC2INT", {"default": (512, 512), "mij":MIN_IMAGE_SIZE, "label": [Lexicon.W, Lexicon.H]}) }, "outputs": { - 0: (Lexicon.IMAGE, {"tooltip":"The graphed image"}), + 0: (Lexicon.IMAGE, {"tooltips":"The graphed image"}), } }) return Lexicon._parse(d, cls) @@ -449,10 +453,10 @@ def INPUT_TYPES(cls) -> dict: Lexicon.PIXEL_A: (JOV_TYPE_IMAGE,), }, "outputs": { - 0: (Lexicon.INT, {"tooltip":"Batch count"}), + 0: (Lexicon.INT, {"tooltips":"Batch count"}), 1: (Lexicon.W,), 2: (Lexicon.H,), - 3: (Lexicon.C, {"tooltip":"Number of image channels. 1 (Grayscale), 3 (RGB) or 4 (RGBA)"}), + 3: (Lexicon.C, {"tooltips":"Number of image channels. 1 (Grayscale), 3 (RGB) or 4 (RGBA)"}), 4: (Lexicon.WH,), 5: (Lexicon.WHC,), } @@ -515,17 +519,17 @@ def INPUT_TYPES(cls) -> dict: d.update({ "optional": { Lexicon.QUEUE: ("STRING", {"multiline": True, "default": "./res/img/test-a.png"}), - Lexicon.VALUE: ("INT", {"min": 0, "default": 0, "tooltip": "the current index for the current queue item"}), - Lexicon.WAIT: ("BOOLEAN", {"default": False, "tooltip":"Hold the item at the current queue index"}), - Lexicon.RESET: ("BOOLEAN", {"default": False, "tooltip":"reset the queue back to index 1"}), - Lexicon.BATCH: ("BOOLEAN", {"default": False, "tooltip":"load all items, if they are loadable items, i.e. batch load images from the Queue's list"}), + Lexicon.VALUE: ("INT", {"mij": 0, "default": 0, "tooltips": "the current index for the current queue item"}), + Lexicon.WAIT: ("BOOLEAN", {"default": False, "tooltips":"Hold the item at the current queue index"}), + Lexicon.RESET: ("BOOLEAN", {"default": False, "tooltips":"reset the queue back to index 1"}), + Lexicon.BATCH: ("BOOLEAN", {"default": False, "tooltips":"load all items, if they are loadable items, i.e. batch load images from the Queue's list"}), }, "outputs": { - 0: (Lexicon.ANY_OUT, {"tooltip":"Current item selected from the Queue list"}), - 1: (Lexicon.QUEUE, {"tooltip":"The entire Queue list"}), - 2: (Lexicon.CURRENT, {"tooltip":"Current item selected from the Queue list as a string"}), - 3: (Lexicon.INDEX, {"tooltip":"Current selected item index in the Queue list"}), - 4: (Lexicon.TOTAL, {"tooltip":"Total items in the current Queue List"}), + 0: (Lexicon.ANY_OUT, {"tooltips":"Current item selected from the Queue list"}), + 1: (Lexicon.QUEUE, {"tooltips":"The entire Queue list"}), + 2: (Lexicon.CURRENT, {"tooltips":"Current item selected from the Queue list as a string"}), + 3: (Lexicon.INDEX, {"tooltips":"Current selected item index in the Queue list"}), + 4: (Lexicon.TOTAL, {"tooltips":"Total items in the current Queue List"}), } }) return Lexicon._parse(d, cls) @@ -654,7 +658,7 @@ def process(q_data: Any) -> Tuple[torch.Tensor, torch.Tensor] | str | dict: data = torch.cat(ret, dim=0) else: data = process(self.__q[self.__index]) - if isinstance(data[0], (np.ndarray,)): + if isinstance(data, (list, np.ndarray,)) and isinstance(data[0], (np.ndarray,)): data = cv2tensor(data) self.__index += 1 @@ -687,7 +691,7 @@ def INPUT_TYPES(cls) -> dict: Lexicon.ROUTE: ("BUS", {"default": None}), }, "outputs": { - 0: (Lexicon.ROUTE, {"tooltip":"Pass through for Route node"}) + 0: (Lexicon.ROUTE, {"tooltips":"Pass through for Route node"}) } }) return Lexicon._parse(d, cls) @@ -794,7 +798,7 @@ def INPUT_TYPES(cls) -> dict: Lexicon.ATTRIBUTE: ("STRING", {"default": ""}), Lexicon.AUTH: ("STRING", {"multiline": True, "dynamic": False}), Lexicon.PATH: ("STRING", {"default": ""}), - "iteration_index": ("INT", {"default": 0, "min": 0, "max": 9999}) + "iteration_index": ("INT", {"default": 0, "mij": 0, "maj": 9999}) } } return Lexicon._parse(d, cls) diff --git a/sup/image.py b/sup/image.py index b94adb8..7c832e2 100644 --- a/sup/image.py +++ b/sup/image.py @@ -5,6 +5,7 @@ import math import base64 +import sys import urllib import requests from enum import Enum @@ -116,6 +117,14 @@ class EnumBlendType(Enum): SRCATOP = BlendType.SRCATOP DESTATOP = BlendType.DESTATOP +class EnumImageBySize(Enum): + LARGEST = 10 + SMALLEST = 20 + WIDTH_MIN = 30 + WIDTH_MAX = 40 + HEIGHT_MIN = 50 + HEIGHT_MAX = 60 + class EnumColorMap(Enum): AUTUMN = cv2.COLORMAP_AUTUMN BONE = cv2.COLORMAP_BONE @@ -687,6 +696,47 @@ def image_blend(imageA: TYPE_IMAGE, imageB: TYPE_IMAGE, mask:Optional[TYPE_IMAGE image = pil2cv(image) return image_crop_center(image, w, h) +def image_by_size(image_list: List[TYPE_IMAGE], enumSize: EnumImageBySize=EnumImageBySize.LARGEST) -> Tuple[TYPE_IMAGE, int, int]: + + img = None + mega, width, height = 0, 0, 0 + if enumSize in [EnumImageBySize.SMALLEST, EnumImageBySize.WIDTH_MIN, EnumImageBySize.HEIGHT_MIN]: + mega, width, height = sys.maxsize, sys.maxsize, sys.maxsize + + for i in image_list: + h, w = i.shape[:2] + match enumSize: + case EnumImageBySize.LARGEST: + if (new_mega := w * h) > mega: + mega = new_mega + img = i + width = max(width, w) + height = max(height, h) + case EnumImageBySize.SMALLEST: + if (new_mega := w * h) < mega: + mega = new_mega + img = i + width = min(width, w) + height = min(height, h) + case EnumImageBySize.WIDTH_MIN: + if w < width: + width = w + img = i + case EnumImageBySize.WIDTH_MAX: + if w > width: + width = w + img = i + case EnumImageBySize.HEIGHT_MIN: + if h < height: + height = h + img = i + case EnumImageBySize.HEIGHT_MAX: + if h > height: + height = h + img = i + + return img, width, height + def image_color_blind(image: TYPE_IMAGE, deficiency:EnumCBDeficiency, simulator:EnumCBSimulator=EnumCBSimulator.AUTOSELECT, severity:float=1.0) -> TYPE_IMAGE: @@ -1715,17 +1765,10 @@ def image_split(image: TYPE_IMAGE, convert:object=image_grayscale) -> Tuple[TYPE def image_stack(image_list: List[TYPE_IMAGE], axis:EnumOrientation=EnumOrientation.HORIZONTAL, stride:int=0, matte:TYPE_PIXEL=(0,0,0,255)) -> TYPE_IMAGE: - count = 0 - images = [] - width, height = 0, 0 - for i in image_list: - h, w = i.shape[:2] - width = max(width, w) - height = max(height, h) - images.append(i) - count += 1 + _, width, height = image_by_size(image_list) + images = [image_matte(image_convert(i, 4), matte, width, height) for i in image_list] + count = len(images) - images = [image_matte(image_convert(i, 4), matte, width, height) for i in images] matte = pixel_convert(matte, 4) match axis: case EnumOrientation.GRID: diff --git a/sup/util.py b/sup/util.py index edd877e..adcead4 100644 --- a/sup/util.py +++ b/sup/util.py @@ -246,7 +246,7 @@ def parse_value(val:Any, typ:EnumConvertType, default: Any, elif typ == EnumConvertType.LIST: new_val = list(new_val) elif typ == EnumConvertType.STRING: - if isinstance(new_val, (str, list,)): + if isinstance(new_val, (str, list, int, float,)): new_val = [new_val] new_val = ", ".join(map(str, new_val)) if not isinstance(new_val, str) else new_val elif typ == EnumConvertType.BOOLEAN: diff --git a/web/core/core_cozy_fields.js b/web/core/core_cozy_fields.js index 08b51b3..7237297 100644 --- a/web/core/core_cozy_fields.js +++ b/web/core/core_cozy_fields.js @@ -86,16 +86,21 @@ app.registerExtension({ color = colorHex2RGB(g_highlight); color = g_highlight } catch { - + // Intentionally left blank } } if (g_color_style == "Round Highlight") { const thick = Math.max(1, Math.min(3, g_thickness)); for (const w of this.widgets) { - if (w?.hidden || w.type.startsWith('converted-') || ["customtext"].includes(w.type)) { + if (!w || w?.hidden || !w?.type) { + continue + } + + if (w.type.startsWith('converted-') || ["customtext"].includes(w.type)) { continue; } + ctx.beginPath(); ctx.fillStyle = color; ctx.roundRect(15-thick, w.last_y-thick, node.size[0]-30+2*thick, LiteGraph.NODE_WIDGET_HEIGHT+thick * 2, 12); diff --git a/web/core/core_cozy_tips.js b/web/core/core_cozy_tips.js index 16c9583..d8afe67 100644 --- a/web/core/core_cozy_tips.js +++ b/web/core/core_cozy_tips.js @@ -26,6 +26,8 @@ const JTooltipWidget = (app, name, opts) => { return w } +if(app.extensionManager) { + app.registerExtension({ name: "jovimetrix.help.tooltips", async getCustomWidgets() { @@ -42,11 +44,14 @@ app.registerExtension({ let userTimeout = 750; let tooltipTimeout; + let widget_previous; + const hideTooltip = () => { if (tooltipTimeout) { clearTimeout(tooltipTimeout); } tooltipEl.style.display = "none"; + widget_previous = null; }; const showTooltip = (tooltip) => { @@ -72,18 +77,21 @@ app.registerExtension({ }; const onCanvasPointerMove = function () { - hideTooltip(); const node = this.node_over; - if (!node) return; - - if (node.flags.collapsed) return; + if (!node || node.flags.collapsed) { + hideTooltip(); + return; + } // jovian tooltip const widget_tooltip = (node?.widgets || []) .find(widget => widget.type === 'JTOOLTIP'); - if (!widget_tooltip) return; - const tips = widget_tooltip.options.default || {}; + if (!widget_tooltip) { + hideTooltip(); + return; + } + const tips = widget_tooltip.options.default || {}; const inputSlot = this.isOverNodeInput(node, this.graph_mouse[0], this.graph_mouse[1], [0, 0]); if (inputSlot !== -1) { const slot = node.inputs[inputSlot]; @@ -97,12 +105,23 @@ app.registerExtension({ } } } + + const name = `inputs_${inputSlot}`; + if (widget_previous != name) { + hideTooltip(); + widget_previous = name; + } return showTooltip(tip); } const outputSlot = this.isOverNodeOutput(node, this.graph_mouse[0], this.graph_mouse[1], [0, 0]); if (outputSlot !== -1) { let tip = tips?.['outputs']?.[outputSlot]; + const name = `outputs_${outputSlot}`; + if (widget_previous != name) { + hideTooltip(); + widget_previous = name; + } return showTooltip(tip); } @@ -113,8 +132,13 @@ app.registerExtension({ if (def) { tip += ` (default: ${def})`; } + if (widget_previous != widget.name) { + hideTooltip(); + widget_previous = widget.name; + } return showTooltip(tip); } + hideTooltip(); }.bind(app.canvas); app.ui.settings.addSetting({ @@ -137,4 +161,5 @@ app.registerExtension({ }, }); }, -}); \ No newline at end of file +}); +} \ No newline at end of file diff --git a/web/core/core_help.js b/web/core/core_help.js index 48f2252..f135902 100644 --- a/web/core/core_help.js +++ b/web/core/core_help.js @@ -87,7 +87,7 @@ app.registerExtension({ const firstNodeKey = Object.keys(selectedNodes)[0]; const firstNode = selectedNodes[firstNodeKey]; const data = { - class: firstNode.getNickname() || "jovimetrix", + class: firstNode?.getNickname() || "unknown", name: firstNode.type } const event = new CustomEvent('jovimetrixHelpRequested', { detail: data }); diff --git a/web/nodes/adjust.js b/web/nodes/adjust.js index 7a67e08..26d4d6f 100644 --- a/web/nodes/adjust.js +++ b/web/nodes/adjust.js @@ -29,13 +29,13 @@ app.registerExtension({ const gamma = this.widgets.find(w => w.name === 'πŸ”†'); const op = this.widgets.find(w => w.name === 'βš’οΈ'); op.callback = () => { - widgetHide(this, radius); - widgetHide(this, amount); - widgetHide(this, lohi); - widgetHide(this, lmh); - widgetHide(this, hsv); - widgetHide(this, contrast); - widgetHide(this, gamma); + widgetHide(this, radius, 'jov'); + widgetHide(this, amount, 'jov'); + widgetHide(this, lohi, 'jov'); + widgetHide(this, lmh, 'jov'); + widgetHide(this, hsv, 'jov'); + widgetHide(this, contrast, 'jov'); + widgetHide(this, gamma, 'jov'); if (["BLUR", "STACK_BLUR", "MEDIAN_BLUR", "OUTLINE"].includes(op.value)) { widgetShow(radius); diff --git a/web/nodes/calc_binary.js b/web/nodes/calc_binary.js index 4da017a..f253a20 100644 --- a/web/nodes/calc_binary.js +++ b/web/nodes/calc_binary.js @@ -5,8 +5,8 @@ */ import { app } from "../../../scripts/app.js" -import { TypeSlot } from '../util/util_node.js' -import { widgetABHook } from '../util/util_jov.js' +import { widgetHookAB } from '../util/util_jov.js' + const _id = "OP BINARY (JOV) 🌟" @@ -20,19 +20,10 @@ app.registerExtension({ const onNodeCreated = nodeType.prototype.onNodeCreated nodeType.prototype.onNodeCreated = function () { const me = onNodeCreated?.apply(this); - widgetABHook(this, '❓', 0); + widgetHookAB(this, '❓'); return me; } - const onConnectionsChange = nodeType.prototype.onConnectionsChange - nodeType.prototype.onConnectionsChange = function (slotType) { - if (slotType === TypeSlot.Input) { - const widget_combo = this.widgets.find(w => w.name === '❓'); - setTimeout(() => { widget_combo.callback(); }, 10); - } - return onConnectionsChange?.apply(this, arguments); - } - return nodeType; } }) diff --git a/web/nodes/lerp.js b/web/nodes/lerp.js index c92123c..84e4e48 100644 --- a/web/nodes/lerp.js +++ b/web/nodes/lerp.js @@ -6,7 +6,7 @@ */ import { app } from "../../../scripts/app.js" -import { widgetABHook2, widgetOutputHookType } from '../util/util_jov.js' +import { widgetHookControl, widgetHookAB } from '../util/util_jov.js' const _id = "LERP (JOV) πŸ”°" @@ -21,14 +21,8 @@ app.registerExtension({ nodeType.prototype.onNodeCreated = function () { const me = onNodeCreated?.apply(this); const alpha = this.widgets.find(w => w.name === 'πŸ›Ÿ'); - const AA = this.widgets.find(w => w.name === 'πŸ…°οΈπŸ…°οΈ'); - const BB = this.widgets.find(w => w.name === 'πŸ…±οΈπŸ…±οΈ'); - const combo = this.widgets.find(w => w.name === '❓'); - widgetABHook2(this, '❓', alpha, true); - widgetABHook2(this, '❓', AA); - widgetABHook2(this, '❓', BB); - widgetOutputHookType(this, '❓'); - setTimeout(() => { combo.callback(); }, 5); + widgetHookControl(this, '❓', alpha, true); + widgetHookAB(this, '❓'); return me; } return nodeType; diff --git a/web/nodes/value.js b/web/nodes/value.js index 69dcb84..e3281a5 100644 --- a/web/nodes/value.js +++ b/web/nodes/value.js @@ -5,7 +5,7 @@ */ import { app } from "../../../scripts/app.js" -import { widgetABHook } from '../util/util_jov.js' +import { widgetHookAB } from '../util/util_jov.js' import { nodeFitHeight } from '../util/util_node.js' import { widgetHide, widgetProcessAny, widget_type_name } from '../util/util_widget.js' @@ -32,24 +32,25 @@ app.registerExtension({ widget_str.options.menu = false; widget_str.origComputeSize = widget_str.computeSize; - const ab_data = widgetABHook(this, '❓'); - const oldCallback = ab_data.combo.callback; - ab_data.combo.callback = () => { + const ab_data = widgetHookAB(this, '❓'); + + const oldCallback = ab_data.callback; + ab_data.callback = () => { oldCallback?.apply(this, arguments); widgetHide(this, widget_str); widget_str.inputEl.className = "jov-hidden"; widget_str.computeSize = () => [0, -4]; - this.outputs[0].name = widget_type_name(ab_data.combo.value); - this.outputs[0].type = ab_data.combo.value; - let type = ab_data.combo.value; - if (["LIST", "DICT", "STRING"].includes(ab_data.combo.value)) { - widgetProcessAny(widget_str, ab_data.combo.value); + this.outputs[0].name = widget_type_name(ab_data.value); + this.outputs[0].type = ab_data.value; + let type = ab_data.value; + if (["LIST", "DICT", "STRING"].includes(ab_data.value)) { + widgetProcessAny(widget_str, ab_data.value); widget_str.inputEl.className = "comfy-multiline-input"; widget_str.computeSize = widget_str.origComputeSize; } else { type = "FLOAT"; - if (ab_data.combo.value.endsWith("INT")) { + if (ab_data.value.endsWith("INT")) { type = "INT"; } } diff --git a/web/util/util_jov.js b/web/util/util_jov.js index 459b41d..6eb526d 100644 --- a/web/util/util_jov.js +++ b/web/util/util_jov.js @@ -5,12 +5,12 @@ */ import { nodeFitHeight } from './util_node.js' -import { widgetShowVector, widgetFind, widget_type_name, widgetHide, widgetShow } from './util_widget.js' +import { widgetShowVector, widget_type_name, widgetHide, widgetShow } from './util_widget.js' export function widgetSizeModeHook(node, wh_hide=true) { - const wh = widgetFind(node.widgets, 'πŸ‡ΌπŸ‡­'); - const samp = widgetFind(node.widgets, '🎞️'); - const mode = widgetFind(node.widgets, 'MODE'); + const wh = node.widgets.find(w => w.name === 'πŸ‡ΌπŸ‡­'); + const samp = node.widgets.find(w => w.name === '🎞️'); + const mode = node.widgets.find(w => w.name === 'MODE'); mode.callback = () => { if (wh_hide) { widgetHide(node, wh); @@ -32,9 +32,9 @@ export function widgetSizeModeHook2(nodeType, wh_hide=true) { const onNodeCreated = nodeType.prototype.onNodeCreated nodeType.prototype.onNodeCreated = function (node) { const me = onNodeCreated?.apply(this); - const wh = widgetFind(node.widgets, 'πŸ‡ΌπŸ‡­'); - const samp = widgetFind(node.widgets, '🎞️'); - const mode = widgetFind(node.widgets, 'MODE'); + const wh = node.widgets.find(w => w.name === 'πŸ‡ΌπŸ‡­'); + const samp = node.widgets.find(w => w.name === '🎞️'); + const mode = node.widgets.find(w => w.name === 'MODE'); mode.callback = () => { if (wh_hide) { widgetHide(node, wh); @@ -54,7 +54,7 @@ export function widgetSizeModeHook2(nodeType, wh_hide=true) { } export function widgetOutputHookType(node, control_key, match_output=0) { - const combo = widgetFind(node.widgets, control_key); + const combo = node.widgets.find(w => w.name === control_key); const output = node.outputs[match_output]; if (!output || !combo) { @@ -71,73 +71,32 @@ export function widgetOutputHookType(node, control_key, match_output=0) { setTimeout(() => { combo.callback(); }, 10); } -export function widgetABHook(node, control_key, match_output=-1) { - const initializeTrack = (widget) => { - const track = {}; - for (let i = 0; i < 4; i++) { - track[i] = widget.options?.default[i]; - } - Object.assign(track, widget.value); - return track; - }; - - const setCallback = (widget, trackKey) => { - widget.options.menu = false; - widget.callback = () => { - if (widget.type === "toggle") { - trackKey[0] = widget.value ? 1 : 0; - } else { - Object.keys(widget.value).forEach((key) => { - trackKey[key] = widget.value[key]; - }); - } - }; - }; - - const { widgets } = node; - const A = widgetFind(widgets, 'πŸ…°οΈπŸ…°οΈ'); - const B = widgetFind(widgets, 'πŸ…±οΈπŸ…±οΈ'); - const combo = widgetFind(widgets, control_key); - - if (!A || !B || !combo) { - throw new Error("Required widgets not found"); - } +/* +* matchFloatSize forces the target to be float[n] based on its type size +*/ +export function widgetHookAB(node, control_key) { - const data = { - track_xyzw: initializeTrack(A), - track_yyzw: initializeTrack(B), - A, - B, - combo - }; + const AA = node.widgets.find(w => w.name === 'πŸ…°οΈπŸ…°οΈ'); + const BB = node.widgets.find(w => w.name === 'πŸ…±οΈπŸ…±οΈ'); + const combo = node.widgets.find(w => w.name === control_key); - if (match_output > -1) { - widgetOutputHookType(node, control_key, match_output); + if (combo === undefined) { + return; } - const oldCallback = combo.callback; - combo.callback = () => { - const me = oldCallback?.apply(this, arguments); - widgetHide(node, A); - widgetHide(node, B); - if (["VEC2", "VEC2INT", "COORD2D", "VEC3", "VEC3INT", "VEC4", "VEC4INT", "BOOLEAN", "INT", "FLOAT"].includes(combo.value)) { - widgetShowVector(A, data.track_xyzw, combo.value); - widgetShowVector(B, data.track_yyzw, combo.value); - } - nodeFitHeight(node); - return me; - } + widgetHookControl(node, control_key, AA); + widgetHookControl(node, control_key, BB); + widgetOutputHookType(node, control_key); + setTimeout(() => { combo.callback(); }, 5); - setTimeout(() => { combo.callback(); }, 10); - setCallback(A, data.track_xyzw); - setCallback(B, data.track_yyzw); - return data; -} + return combo; +}; /* * matchFloatSize forces the target to be float[n] based on its type size */ -export function widgetABHook2(node, control_key, target, matchFloatSize=false) { +export function widgetHookControl(node, control_key, target, matchFloatSize=false) { + const initializeTrack = (widget) => { const track = {}; for (let i = 0; i < 4; i++) { @@ -161,7 +120,7 @@ export function widgetABHook2(node, control_key, target, matchFloatSize=false) { }; const { widgets } = node; - const combo = widgetFind(widgets, control_key); + const combo = widgets.find(w => w.name === control_key); if (!target || !combo) { throw new Error("Required widgets not found"); @@ -176,7 +135,7 @@ export function widgetABHook2(node, control_key, target, matchFloatSize=false) { const oldCallback = combo.callback; combo.callback = () => { const me = oldCallback?.apply(this, arguments); - widgetHide(node, target); + widgetHide(node, target, "-jov"); if (["VEC2", "VEC2INT", "COORD2D", "VEC3", "VEC3INT", "VEC4", "VEC4INT", "BOOLEAN", "INT", "FLOAT"].includes(combo.value)) { let size = combo.value; if (matchFloatSize) {