diff --git a/maxdiff/patch_printer.py b/maxdiff/patch_printer.py index 1076987..eff34f1 100644 --- a/maxdiff/patch_printer.py +++ b/maxdiff/patch_printer.py @@ -220,9 +220,7 @@ def get_box_text(box: dict) -> str: return boxtext -def get_object_names_from_ids_recursive( - id_hierarchy: list, boxes_parent: list, indent: int = 0 -): +def get_object_names_from_ids_recursive(id_hierarchy: list, boxes_parent: list): """Translates an object id hierarchy string in the form of "obj-n::obj-m:: etc" to a string in the form of "/ 1: - id_hierarchy.pop(0) + if len(id_hierarchy) > 1: if "patcher" in box: subpatcher_boxes = box["patcher"]["boxes"] - name += f"/{get_object_names_from_ids_recursive(id_hierarchy, subpatcher_boxes, indent + 1)}" + name += f"/{get_object_names_from_ids_recursive(id_hierarchy[1:], subpatcher_boxes)}" else: - for id_level in id_hierarchy: + for id_level in id_hierarchy[1:]: name += f"/[{id_level}]" if name == "": - name = f"[{id_to_check}]" + name = f"[{id_hierarchy[0]}]" return name +def get_param_properties_from_ids_recursive(id_hierarchy: list, boxes_parent: list): + """Travels an object id hierarchy string in the form of "obj-n::obj-m:: etc" and finds properties + contained in valueof in saved_attribute_attributes. + + If an object id cannot be found in the patch, for instance because it refers to an object + inside an abstraction, returns an empty object. + """ + + # every entry of "boxes_parent" has a single item "box" + boxes = list(map(lambda val: val["box"], boxes_parent)) + + for box in boxes: + if "id" in box and id_hierarchy[0] == box["id"]: + if len(id_hierarchy) > 1: + if "patcher" in box: + subpatcher_boxes = box["patcher"]["boxes"] + return get_param_properties_from_ids_recursive( + id_hierarchy[1:], subpatcher_boxes + ) + else: + return {} # can't traverse into abstraction + else: + saved_attrs = box.get("saved_attribute_attributes", {}) + return saved_attrs.get("valueof", {}) + + return {} # object not found + + +def get_param_annotations_from_ids_recursive(id_hierarchy: list, boxes_parent: list): + """Travels an object id hierarchy string in the form of "obj-n::obj-m:: etc" and finds the + parameter's annotations saved as box properties + + If an object id cannot be found in the patch, for instance because it refers to an object + inside an abstraction, returns an empty object. + """ + + # every entry of "boxes_parent" has a single item "box" + boxes = list(map(lambda val: val["box"], boxes_parent)) + + for box in boxes: + if "id" in box and id_hierarchy[0] == box["id"]: + if len(id_hierarchy) > 1: + if "patcher" in box: + subpatcher_boxes = box["patcher"]["boxes"] + return get_param_annotations_from_ids_recursive( + id_hierarchy[1:], subpatcher_boxes + ) + else: + return {} # can't traverse into abstraction + else: + annotation = box.get("annotation", {}) + annotation_name = box.get("annotation_name", {}) + return { + "annotation": annotation, + "annotation_name": annotation_name, + } + + return {} # object not found + + def get_properties_to_print( box_or_patcher: dict, default: dict, skip_properties: list[str] ) -> dict: @@ -279,7 +335,7 @@ def get_properties_to_print( continue if key == "saved_attribute_attributes": - # We take the attributes out or saved_attribute_attributes and present them as properties + # We take the attributes out of saved_attribute_attributes and present them as properties attributes = get_saved_attribute_attributes(value) attributes_to_print = get_properties_to_print( attributes, default, skip_properties @@ -291,7 +347,7 @@ def get_properties_to_print( continue if key == "saved_object_attributes": - # We take the attributes out or saved_object_attributes and present them as properties + # We take the attributes out of saved_object_attributes and present them as properties attributes = get_saved_object_attributes(value) attributes_to_print = get_properties_to_print( attributes, default, skip_properties @@ -373,54 +429,82 @@ def get_parameters_string_block(patcher: dict) -> str: Non-overridden parameter attributes are already shown with the parameter objects. """ parameters = patcher["parameters"] + + param_overrides = ( + parameters["parameter_overrides"] if "parameter_overrides" in parameters else {} + ) + + param_banks = parameters["parameterbanks"] if "parameterbanks" in parameters else {} + parameters_string = "" - for bankindex, bank in parameters.items(): - if bankindex in ["parameter_overrides", "parameterbanks"]: + for index, item in parameters.items(): + if index in ["parameter_overrides", "parameterbanks"]: continue - parsed_key = bankindex - if bankindex.startswith("obj"): - id_tokens = bankindex.split("::") - parsed_key = get_object_names_from_ids_recursive(id_tokens, patcher["boxes"]) - - parameters_string += f"\t{parsed_key}: {bank}" - - if ( - "parameter_overrides" in parameters - and bankindex in parameters["parameter_overrides"] - ): - override = parameters["parameter_overrides"][bankindex] - override_print = [ - override.get("parameter_longname", "-"), - override.get("parameter_shortname", "-"), - str(override.get("parameter_linknames", "-")), - ] - - for key, value in override.items(): - if key in [ - "parameter_longname", - "parameter_shortname", - "parameter_linknames", - ]: - continue - override_print.append(f"{key}: {value}") - - parameters_string += f" > override > {str(override_print)}" + object_names = index + if index.startswith("obj"): + id_tokens = index.split("::") + object_names = get_object_names_from_ids_recursive( + id_tokens, patcher["boxes"] + ) + + parameters_string += f"\t{object_names}: {item}" + + if index.startswith("obj"): + id_tokens = index.split("::") + param_properties = get_param_properties_from_ids_recursive( + id_tokens, patcher["boxes"] + ) + + for key, value in param_properties.items(): + key_text = ( + key[len("parameter_") :] if key.startswith("parameter_") else key + ) + parameters_string += f"\n\t\t{key_text}: {value}" + + param_annotations = get_param_annotations_from_ids_recursive( + id_tokens, patcher["boxes"] + ) + + if param_annotations != {}: + parameters_string += "\n\t\t____Info____" + parameters_string += f"\n\t\t{param_annotations['annotation_name'] if 'annotation_name' in param_annotations and param_annotations['annotation_name'] != {} else ''}" + if ( + "annotation" in param_annotations + and param_annotations["annotation"] != {} + ): + value_text = "\n\t\t".join( + str(param_annotations["annotation"]).splitlines() + ) + parameters_string += f"\n\t\t{value_text}" + else: + parameters_string += "\n\t\t" + + if index in param_overrides: + param_override = param_overrides[index] + + parameters_string += f"\n\toverrides:" + for key, value in param_override.items(): + key_text = ( + key[len("parameter_") :] if key.startswith("parameter_") else key + ) + parameters_string += f"\n\t\t{key_text}: {value}" + parameters_string += "\n" - if "parameterbanks" in parameters: + if param_banks != {}: parameters_string += "banks:\n" - for bankindex, bank in parameters["parameterbanks"].items(): - for key, value in bank.items(): + for index, item in param_banks.items(): + for key, value in item.items(): parameters_string += "\t" if key == "index": parameters_string += f"{value}:" elif key == "name": parameters_string += f"({value})" if value != "" else "" elif key == "parameters": - parameters_string += f"encoders: {bank['parameters']}" + parameters_string += f"encoders: {item['parameters']}" elif key == "buttons": - parameters_string += f"buttons: {bank['buttons']}" + parameters_string += f"buttons: {item['buttons']}" else: parameters_string += f"{value}" parameters_string += "\n" diff --git a/maxdiff/tests/test_baselines/FrozenTest.amxd.txt b/maxdiff/tests/test_baselines/FrozenTest.amxd.txt index 715473a..ec8ed8d 100644 --- a/maxdiff/tests/test_baselines/FrozenTest.amxd.txt +++ b/maxdiff/tests/test_baselines/FrozenTest.amxd.txt @@ -2,10 +2,10 @@ MIDI Effect Device ------------------- Device is frozen ----- Contents ----- -Test.amxd: 36531 bytes, modified at 2026/01/28 10:27:01 UTC <= Device -ParamAbstraction.maxpat: 956 bytes, modified at 2026/01/28 10:25:56 UTC, 2 instances -MyAbstraction.maxpat: 1369 bytes, modified at 2026/01/28 10:26:01 UTC, 6 instances -AbstractionWithParameter.maxpat: 1569 bytes, modified at 2024/05/24 13:59:36 UTC, 2 instances +Test.amxd: 57392 bytes, modified at 2026/02/26 15:45:49 UTC <= Device +MyAbstraction.maxpat: 2027 bytes, modified at 2026/02/26 15:38:57 UTC, 6 instances +ParamAbstraction.maxpat: 1491 bytes, modified at 2026/02/26 15:40:50 UTC, 2 instances +AbstractionWithParameter.maxpat: 1334 bytes, modified at 2026/02/26 15:38:57 UTC, 2 instances hz-icon.svg: 484 bytes, modified at 2024/05/24 13:59:36 UTC, 3 instances beat-icon.svg: 533 bytes, modified at 2024/05/24 13:59:36 UTC, 3 instances fpic.png: 7094 bytes, modified at 2024/05/24 13:59:36 UTC, 5 instances diff --git a/maxdiff/tests/test_baselines/Test.amxd.txt b/maxdiff/tests/test_baselines/Test.amxd.txt index 99bd229..27e14e8 100644 --- a/maxdiff/tests/test_baselines/Test.amxd.txt +++ b/maxdiff/tests/test_baselines/Test.amxd.txt @@ -2,36 +2,93 @@ MIDI Effect Device ------------------- parameters: [p MySubpatcher]/[live.dial]: ['In a subpatcher', 'live.dial', 0] + longname: In a subpatcher + modmode: 0 + shortname: live.dial + type: 0 + unitstyle: 0 + ____Info____ + + [bpatcher ParamAbstraction.maxpat]/[obj-1]: ['InsideBpatcher', 'live.dial', 0] [AbstractionWithParameter]/[obj-1]: ['MyParameter', 'MyParameter', 0] - [AbstractionWithParameter]/[obj-1]: ['MyParameter[1]', 'MyParameter', 0] > override > ['MyParameter[1]', '-', '-'] + [AbstractionWithParameter]/[obj-1]: ['MyParameter[1]', 'MyParameter', 0] + overrides: + longname: MyParameter[1] [p ImplicitDependencies]/[live.tab]: ['Time Mode', 'Time Mode', 0] + enum: ['Free', 'Sync'] + invisible: 2 + linknames: 1 + longname: Time Mode + mmax: 1 + modmode: 0 + shortname: Time Mode + type: 2 + unitstyle: 9 + ____Info____ + Time Mode + Toggles between Beat Sync and Free running (Hz). [p ImplicitDependencies]/[live.text]: ['live.text', 'live.text', 0] + button_mode: Momentary + enum: ['val1', 'val2'] + longname: live.text + mmax: 1 + modmode: 0 + shortname: live.text + type: 2 + ____Info____ + + [p ImplicitDependencies]/[live.menu]: ['live.menu', 'live.menu', 0] - [bpatcher ParamAbstraction.maxpat]/[obj-1]: ['OverruledParamLongName', 'OverruledParamShortName', 0] > override > ['OverruledParamLongName', 'OverruledParamShortName', '-'] + button_mode: Cycle + enum: ['one', 'two', 'three'] + longname: live.menu + mmax: 2 + modmode: 0 + shortname: live.menu + type: 2 + ____Info____ + + + [bpatcher ParamAbstraction.maxpat]/[obj-1]: ['OverruledParamLongName', 'OverruledParamShortName', 0] + overrides: + invisible: 0 + longname: OverruledParamLongName + modmode: 0 + range: [0, 127] + shortname: OverruledParamShortName + type: 1 + unitstyle: 0 [bpatcher ThisWasAnAbstractionBeforeEmbeddingIt.maxpat ]/[live.numbox]: ['EmbeddedParam', 'Embedded', 0] + longname: EmbeddedParam + modmode: 3 + shortname: Embedded + type: 0 + unitstyle: 0 + ____Info____ + + [live.dial]: ['live.dial', 'live.dial', 0] + longname: live.dial + modmode: 0 + shortname: live.dial + type: 0 + unitstyle: 0 + ____Info____ + + [live.dial]: ['live.dial[1]', 'live.dial', 0] + longname: live.dial[1] + modmode: 0 + shortname: live.dial + type: 0 + unitstyle: 0 + ____Info____ + + inherited_shortname: 1 banks: 0: (MyBank) encoders: ['live.dial', 'InsideBpatcher', '-', '-', '-', '-', '-', '-'] buttons: ['live.text', '-', '-', '-', '-', '-', '-', 'live.menu'] -dependency_cache: - {'name': 'AbstractionWithParameter.maxpat', 'bootpath': '~/maxdevtools/maxdiff/tests/test_files', 'type': 'JSON', 'implicit': 1} - {'name': 'MyAbstraction.maxpat', 'bootpath': '~/maxdevtools/maxdiff/tests/test_files', 'type': 'JSON', 'implicit': 1} - {'name': 'ParamAbstraction.maxpat', 'bootpath': '~/maxdevtools/maxdiff/tests/test_files', 'type': 'JSON', 'implicit': 1} - {'name': 'TestScript.js', 'bootpath': '~/maxdevtools/maxdiff/tests/test_files', 'type': 'TEXT', 'implicit': 1} - {'name': 'VisibleBang.js', 'bootpath': '~/maxdevtools/maxdiff/tests/test_files', 'type': 'TEXT', 'implicit': 1} - {'name': 'beat-icon.svg', 'bootpath': '~/maxdevtools/maxdiff/tests/test_files', 'type': 'svg', 'implicit': 1} - {'name': 'collContent.txt', 'bootpath': '~/maxdevtools/maxdiff/tests/test_files', 'type': 'TEXT', 'implicit': 1} - {'name': 'fpic.png', 'bootpath': '~/maxdevtools/maxdiff/tests/test_files', 'type': 'PNG', 'implicit': 1} - {'name': 'hz-icon.svg', 'bootpath': '~/maxdevtools/maxdiff/tests/test_files', 'type': 'svg', 'implicit': 1} - {'name': 'my-maxnode-basic.js', 'bootpath': '~/maxdevtools/maxdiff/tests/test_files', 'type': 'TEXT', 'implicit': 1} - {'name': 'myTestTable', 'bootpath': '~/maxdevtools/maxdiff/tests/test_files', 'type': 'TEXT', 'implicit': 1} - {'name': 'mystorage.json', 'bootpath': '~/maxdevtools/maxdiff/tests/test_files', 'type': 'JSON', 'implicit': 1} - {'name': 'myxfade.genjit', 'bootpath': '~/maxdevtools/maxdiff/tests/test_files', 'type': 'gJIT', 'implicit': 1} - {'name': 'shakerkicksnare.aif', 'bootpath': '~/maxdevtools/maxdiff/tests/test_files', 'type': 'AIFF', 'implicit': 1} - {'name': 'times3.gendsp', 'bootpath': '~/maxdevtools/maxdiff/tests/test_files', 'type': 'gDSP', 'implicit': 1} - project: version: 1 | creationdate: 3590052786 | modificationdate: 3590052786 | viewrect: [25, 106, 300, 500] | autoorganize: 1 | hideprojectwindow: 1 | showdependencies: 1 | autolocalize: 0 | layout: {} | searchpath: {} | detailsvisible: 0 | amxdtype: 1835887981 | readonly: 0 | devpathtype: 0 | devpath: . | sortmode: 0 | viewmode: 0 | includepackages: 0 contents: @@ -39,7 +96,7 @@ project: collContent.txt ----------- patcher ----------- -appversion: 9.0.10-x64-1 | rect: [91, 153, 1288, 310] | openrect: [0, 0, 0, 169] | default_fontsize: 10.0 | default_fontname: Arial Bold | gridsize: [8, 8] | boxanimatetime: 500 | latency: 0 | is_mpe: 0 | external_mpe_tuning_enabled: 0 | platform_compatibility: 0 | autosave: 0 +appversion: 9.1.3-x64-1 | rect: [91, 153, 1288, 310] | openrect: [0, 0, 0, 169] | openrectmode: 0 | default_fontsize: 10.0 | default_fontname: Arial Bold | gridsize: [8, 8] | boxanimatetime: 500 | latency: 0 | is_mpe: 0 | external_mpe_tuning_enabled: 0 | platform_compatibility: 0 | autosave: 0 ----------- objects ----------- [comment NOTE: after any changes to this device, also update FrozenTest.amxd] [poly~ MyAbstraction] @@ -50,7 +107,7 @@ appversion: 9.0.10-x64-1 | rect: [91, 153, 1288, 310] | openrect: [0, 0, 0, 169] [coll] [p ImplicitDependencies] varname: ImplicitDependencies ----------- patcher ----------- - appversion: 9.0.10-x64-1 | rect: [60, 130, 639, 710] + appversion: 9.1.3-x64-1 | rect: [60, 130, 639, 710] ----------- objects ----------- [js TestScript] filename: TestScript | parameter_enable: 0 [comment We would expect implicit dependencies for these but they don't seem to be added.] bubble: 1 | bubbleside: 2 | linecount: 2 @@ -73,17 +130,17 @@ appversion: 9.0.10-x64-1 | rect: [91, 153, 1288, 310] | openrect: [0, 0, 0, 169] [jsui] filename: VisibleBang.js [live.menu] pictures: [hz-icon.svg, beat-icon.svg] | remapsvgcolors: 1 | parameter: | usepicture: 1 | usesvgviewbox: 1 [live.text] pictures: [hz-icon.svg, beat-icon.svg] | remapsvgcolors: 1 | parameter: | usepicture: 1 | usesvgviewbox: 1 - [playlist~] basictuning: 440 | clipheight: 28.0 | data: {'clips': [{'absolutepath': 'shakerkicksnare.aif', 'filename': 'shakerkicksnare.aif', 'filekind': 'audiofile', 'id': 'u400003311', 'loop': 1, 'content_state': {'loop': 1}}]} | mode: basic | originallength: [0, ticks] | originaltempo: 120.0 | quality: basic + [playlist~] clipheight: 28.0 | data: {'clips': [{'absolutepath': 'shakerkicksnare.aif', 'filename': 'shakerkicksnare.aif', 'filekind': 'audiofile', 'id': 'u400003311', 'loop': 1, 'content_state': {'loop': 1}}]} | mode: basic | quality: basic [pictslider] bkgndpict: fpic.png | clickedimage: 0 | knobpict: fpic.png [pictctrl] name: fpic.png [fpic] pic: fpic.png - [live.tab] annotation: Toggles between Beat Sync and Free running (Hz). | annotation_name: Time Mode | fontsize: 9.0 | livemode: 1 | num_lines_patching: 2 | num_lines_presentation: 2 | pictures: [hz-icon.svg, beat-icon.svg] | remapsvgcolors: 1 | parameter: | usepicture: 1 | usesvgviewbox: 1 | varname: Time Mode + [live.tab] annotation: Toggles between Beat Sync and Free running (Hz). | annotation_name: Time Mode | fontsize: 9.0 | livemode: 1 | num_lines_patching: 2 | num_lines_presentation: 2 | pictures: [hz-icon.svg, beat-icon.svg] | remapsvgcolors: 1 | parameter: | usepicture: 1 | usesvgviewbox: 1 | varname: Time Mode ----------- patch cords ----------- [pattr test] (1) => (0) [number] [message read myTestTable] (0) => (0) [table myTestTable] [bpatcher ThisWasAnAbstractionBeforeEmbeddingIt.maxpat] embed: 1 ----------- patcher ----------- - appversion: 9.0.10-x64-1 | rect: [927, 431, 640, 480] + appversion: 9.1.3-x64-1 | rect: [927, 431, 640, 480] ----------- objects ----------- [live.comment Embedded] [live.numbox] parameter: @@ -97,7 +154,7 @@ appversion: 9.0.10-x64-1 | rect: [91, 153, 1288, 310] | openrect: [0, 0, 0, 169] [button] [gen @t exponent] ----------- patcher ----------- - appversion: 9.0.10-x64-1 | classnamespace: dsp.gen | rect: [84, 144, 653, 641] + appversion: 9.1.3-x64-1 | classnamespace: dsp.gen | rect: [84, 144, 653, 641] ----------- objects ----------- [codebox] //============================================================ @@ -140,7 +197,7 @@ appversion: 9.0.10-x64-1 | rect: [91, 153, 1288, 310] | openrect: [0, 0, 0, 169] [coll @embed 1] coll_data: {'count': 2, 'data': [{'key': 0, 'value': ['test']}, {'key': 1, 'value': ['another', 'test']}]} | embed: 1 | precision: 6 [p MySubpatcher] ----------- patcher ----------- - appversion: 9.0.10-x64-1 | rect: [805, 282, 271, 250] + appversion: 9.1.3-x64-1 | rect: [805, 282, 271, 250] ----------- objects ----------- [live.dial] parameter: [t b b] diff --git a/maxdiff/tests/test_files/AbstractionWithParameter.maxpat b/maxdiff/tests/test_files/AbstractionWithParameter.maxpat index b2254af..f029271 100644 --- a/maxdiff/tests/test_files/AbstractionWithParameter.maxpat +++ b/maxdiff/tests/test_files/AbstractionWithParameter.maxpat @@ -1,75 +1,43 @@ { - "patcher" : { - "fileversion" : 1, - "appversion" : { - "major" : 8, - "minor" : 5, - "revision" : 5, - "architecture" : "x64", - "modernui" : 1 - } -, - "classnamespace" : "box", - "rect" : [ 312.0, 228.0, 221.0, 176.0 ], - "bglocked" : 0, - "openinpresentation" : 0, - "default_fontsize" : 12.0, - "default_fontface" : 0, - "default_fontname" : "Arial", - "gridonopen" : 1, - "gridsize" : [ 15.0, 15.0 ], - "gridsnaponopen" : 1, - "objectsnaponopen" : 1, - "statusbarvisible" : 2, - "toolbarvisible" : 1, - "lefttoolbarpinned" : 0, - "toptoolbarpinned" : 0, - "righttoolbarpinned" : 0, - "bottomtoolbarpinned" : 0, - "toolbars_unpinned_last_save" : 0, - "tallnewobj" : 0, - "boxanimatetime" : 200, - "enablehscroll" : 1, - "enablevscroll" : 1, - "devicewidth" : 0.0, - "description" : "", - "digest" : "", - "tags" : "", - "style" : "", - "subpatcher_template" : "", - "assistshowspatchername" : 0, - "boxes" : [ { - "box" : { - "id" : "obj-1", - "maxclass" : "live.dial", - "numinlets" : 1, - "numoutlets" : 2, - "outlettype" : [ "", "float" ], - "parameter_enable" : 1, - "patching_rect" : [ 33.0, 20.0, 81.0, 48.0 ], - "saved_attribute_attributes" : { - "valueof" : { - "parameter_longname" : "MyParameter", - "parameter_shortname" : "MyParameter", - "parameter_type" : 0, - "parameter_unitstyle" : 0 - } - - } -, - "varname" : "live.dial" - } - - } - ], - "lines" : [ ], - "saved_attribute_attributes" : { - "default_plcolor" : { - "expression" : "" - } - - } - - } - -} + "patcher": { + "fileversion": 1, + "appversion": { + "major": 9, + "minor": 1, + "revision": 3, + "architecture": "x64", + "modernui": 1 + }, + "classnamespace": "box", + "rect": [ 312.0, 228.0, 221.0, 176.0 ], + "boxes": [ + { + "box": { + "id": "obj-1", + "maxclass": "live.dial", + "numinlets": 1, + "numoutlets": 2, + "outlettype": [ "", "float" ], + "parameter_enable": 1, + "patching_rect": [ 33.0, 20.0, 81.0, 48.0 ], + "saved_attribute_attributes": { + "valueof": { + "parameter_longname": "MyParameter", + "parameter_modmode": 0, + "parameter_shortname": "MyParameter", + "parameter_type": 0, + "parameter_unitstyle": 0 + } + }, + "varname": "live.dial" + } + } + ], + "lines": [], + "saved_attribute_attributes": { + "default_plcolor": { + "expression": "" + } + } + } +} \ No newline at end of file diff --git a/maxdiff/tests/test_files/FrozenTest.amxd b/maxdiff/tests/test_files/FrozenTest.amxd index 8b0db1c..33e2d80 100644 Binary files a/maxdiff/tests/test_files/FrozenTest.amxd and b/maxdiff/tests/test_files/FrozenTest.amxd differ diff --git a/maxdiff/tests/test_files/MyAbstraction.maxpat b/maxdiff/tests/test_files/MyAbstraction.maxpat index bf73c54..55be0c1 100644 --- a/maxdiff/tests/test_files/MyAbstraction.maxpat +++ b/maxdiff/tests/test_files/MyAbstraction.maxpat @@ -1,79 +1,71 @@ { - "patcher" : { - "fileversion" : 1, - "appversion" : { - "major" : 9, - "minor" : 0, - "revision" : 10, - "architecture" : "x64", - "modernui" : 1 - } -, - "classnamespace" : "box", - "rect" : [ 312.0, 228.0, 221.0, 176.0 ], - "gridsize" : [ 15.0, 15.0 ], - "boxes" : [ { - "box" : { - "id" : "obj-3", - "maxclass" : "button", - "numinlets" : 1, - "numoutlets" : 1, - "outlettype" : [ "bang" ], - "parameter_enable" : 0, - "patching_rect" : [ 113.0, 60.0, 24.0, 24.0 ] - } - - } -, { - "box" : { - "comment" : "", - "id" : "obj-2", - "index" : 1, - "maxclass" : "outlet", - "numinlets" : 1, - "numoutlets" : 0, - "patching_rect" : [ 40.0, 60.0, 30.0, 30.0 ] - } - - } -, { - "box" : { - "comment" : "", - "id" : "obj-1", - "index" : 1, - "maxclass" : "inlet", - "numinlets" : 0, - "numoutlets" : 1, - "outlettype" : [ "" ], - "patching_rect" : [ 40.0, 22.0, 30.0, 30.0 ] - } - - } - ], - "lines" : [ { - "patchline" : { - "destination" : [ "obj-2", 0 ], - "order" : 1, - "source" : [ "obj-1", 0 ] - } - - } -, { - "patchline" : { - "destination" : [ "obj-3", 0 ], - "order" : 0, - "source" : [ "obj-1", 0 ] - } - - } - ], - "saved_attribute_attributes" : { - "default_plcolor" : { - "expression" : "" - } - - } - - } - -} + "patcher": { + "fileversion": 1, + "appversion": { + "major": 9, + "minor": 1, + "revision": 3, + "architecture": "x64", + "modernui": 1 + }, + "classnamespace": "box", + "rect": [ 312.0, 228.0, 221.0, 176.0 ], + "boxes": [ + { + "box": { + "id": "obj-3", + "maxclass": "button", + "numinlets": 1, + "numoutlets": 1, + "outlettype": [ "bang" ], + "parameter_enable": 0, + "patching_rect": [ 113.0, 60.0, 24.0, 24.0 ] + } + }, + { + "box": { + "comment": "", + "id": "obj-2", + "index": 1, + "maxclass": "outlet", + "numinlets": 1, + "numoutlets": 0, + "patching_rect": [ 40.0, 60.0, 30.0, 30.0 ] + } + }, + { + "box": { + "comment": "", + "id": "obj-1", + "index": 1, + "maxclass": "inlet", + "numinlets": 0, + "numoutlets": 1, + "outlettype": [ "" ], + "patching_rect": [ 40.0, 22.0, 30.0, 30.0 ] + } + } + ], + "lines": [ + { + "patchline": { + "destination": [ "obj-2", 0 ], + "order": 1, + "source": [ "obj-1", 0 ] + } + }, + { + "patchline": { + "destination": [ "obj-3", 0 ], + "order": 0, + "source": [ "obj-1", 0 ] + } + } + ], + "saved_attribute_attributes": { + "default_plcolor": { + "expression": "" + } + } + } +} \ No newline at end of file diff --git a/maxdiff/tests/test_files/ParamAbstraction.maxpat b/maxdiff/tests/test_files/ParamAbstraction.maxpat index 45171d7..7a32aff 100644 --- a/maxdiff/tests/test_files/ParamAbstraction.maxpat +++ b/maxdiff/tests/test_files/ParamAbstraction.maxpat @@ -1,50 +1,45 @@ { - "patcher" : { - "fileversion" : 1, - "appversion" : { - "major" : 9, - "minor" : 0, - "revision" : 10, - "architecture" : "x64", - "modernui" : 1 - } -, - "classnamespace" : "box", - "rect" : [ 192.0, 591.0, 640.0, 480.0 ], - "gridsize" : [ 15.0, 15.0 ], - "boxes" : [ { - "box" : { - "id" : "obj-1", - "maxclass" : "live.dial", - "numinlets" : 1, - "numoutlets" : 2, - "outlettype" : [ "", "float" ], - "parameter_enable" : 1, - "patching_rect" : [ 80.0, 64.0, 41.0, 48.0 ], - "saved_attribute_attributes" : { - "valueof" : { - "parameter_longname" : "InsideBpatcher", - "parameter_modmode" : 0, - "parameter_shortname" : "live.dial", - "parameter_type" : 0, - "parameter_unitstyle" : 0 - } - - } -, - "varname" : "live.dial" - } - - } - ], - "lines" : [ ], - "saved_attribute_attributes" : { - "default_plcolor" : { - "expression" : "" - } - - } - - } - -} + "patcher": { + "fileversion": 1, + "appversion": { + "major": 9, + "minor": 1, + "revision": 3, + "architecture": "x64", + "modernui": 1 + }, + "classnamespace": "box", + "rect": [ 192.0, 591.0, 640.0, 480.0 ], + "boxes": [ + { + "box": { + "annotation": "Just another live.dial. Let's test if we can override this.", + "annotation_name": "Just a live.dial", + "id": "obj-1", + "maxclass": "live.dial", + "numinlets": 1, + "numoutlets": 2, + "outlettype": [ "", "float" ], + "parameter_enable": 1, + "patching_rect": [ 80.0, 64.0, 41.0, 48.0 ], + "saved_attribute_attributes": { + "valueof": { + "parameter_longname": "InsideBpatcher", + "parameter_modmode": 0, + "parameter_shortname": "live.dial", + "parameter_type": 0, + "parameter_unitstyle": 0 + } + }, + "varname": "live.dial" + } + } + ], + "lines": [], + "saved_attribute_attributes": { + "default_plcolor": { + "expression": "" + } + } + } +} \ No newline at end of file diff --git a/maxdiff/tests/test_files/Test.amxd b/maxdiff/tests/test_files/Test.amxd index a77c841..c5294a2 100644 Binary files a/maxdiff/tests/test_files/Test.amxd and b/maxdiff/tests/test_files/Test.amxd differ