diff --git a/README.md b/README.md index 4fb27cb..dc5d833 100644 --- a/README.md +++ b/README.md @@ -1,30 +1,53 @@ # tc.preset -A [jsui] replacement for the [preset] object in Cycling'74 Max, with extra features: +A [jsui] replacement for the [preset] object in Cycling'74 Max. + +## Features - Drag and drop presets to re-organize - Display presets as a grid or a list -- Scrollable +- Scrollable (requires Max 8.6.2) - Shows active preset even if recalled directly from pattrstorage - Shows previously active preset, with the ability to ignore preset 0 if it being used as an intermediary step - Shows presets being interpolated (using recall or recallmulti) - Shows preset name and lock state +- Outputs active preset name and lock state from third and fourth outlet - Ability to rewrite json file automatically every time a preset is stored/moved/deleted/renamed/(un)locked - Helps keeping in sync a umenu with the list of stored slotstlet - More look customization +- Same click + modifier key behavior as the vanilla object to store or delete presets ## How to use - Place `tc.preset.js` in the same directory as your patch, or somewhere in the Max search path -- Create a [jsui @filename tc.preset.js]. You can either add `@jsarguments` followed by the name of the pattrstorage you want to communicate with, or set that later by sending a `pattrstorage` (followed by the pattrstorage name) message to the [jsui]. -- Connect the [pattrstorage] outlet to the [jsui] pattrstorage inlet +- Create a [`jsui @filename tc.preset.js`]. You can either add `@jsarguments` followed by the name of the pattrstorage you want to communicate with, or set that later by sending a `pattrstorage` (followed by the pattrstorage name) message to the [jsui]. +- Connect the [pattrstorage] outlet to the [jsui] inlet ## Limitations - Resize doesn't work in Presentation mode (jsui limitation) -- Some messages should be sent to the pattrstorage, some other to the jsui: - - `recall`: send to pattrstorage - - `recallmulti`: send to pattrstorage first, then to the jsui (pattrstorage limitation) - - `store`: send to jsui +- Due to the way [pattrstorage] works, some pattrstorage-specific messages should be sent to the [jsui] instead of the [pattrstorage]. Some to both: + - `recall`, `delete`: send to [pattrstorage] only + - `recallmulti`, `slotname`: send to [pattrstorage] first (for better timing), then to the [jsui] + - `store`: send to [jsui] only +- The js program send a lot of message to the [pattrstorage] (patch cord not required), which makes it output a lot of messages required for the [jsui] to stay in sync. Using one of the above messages incorrectly, or sending `getslotlist`, `getslotnamelist`, or any message that will impact the presets, it might cause the [pattrstorage] to get out of sync. In case something like that happens, you can send the `resync` message to the [jsui]. + ## Desired features (for someday) - No need for a patch cord (programmatically create a [send]/[receive] pair?) - Ability to lock/unlock and rename directly in the jsui without the need of external objects -- Ability to target a [pattrstorage] in a different patcher level \ No newline at end of file +- Ability to target a [pattrstorage] in a different patcher level + +## License +GPL-3.0-or-later + +Copyright (C) 2024 Théophile Clet - https://tflcl.xyz. + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +See . \ No newline at end of file diff --git a/tc.preset.js b/tc.preset.js index 49f31ee..bcbe31a 100644 --- a/tc.preset.js +++ b/tc.preset.js @@ -689,6 +689,10 @@ function read() { } } +function resync() { + calc_rows_columns(); +} + function find_pattrstorage(name) { active_slot = 0; pattrstorage_obj = this.patcher.getnamed(name); diff --git a/tc.preset_demo.maxpat b/tc.preset_demo.maxpat index 4f0714b..a0874de 100755 --- a/tc.preset_demo.maxpat +++ b/tc.preset_demo.maxpat @@ -45,7 +45,7 @@ "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, - "patching_rect" : [ 850.0, 546.0, 150.0, 87.0 ], + "patching_rect" : [ 850.0, 546.0, 153.0, 87.0 ], "text" : "Minimum number of slots to display when scrollable is enabled. If a preset is stored in a slot higher than that value, then it is ignored." } @@ -153,7 +153,7 @@ "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, - "patching_rect" : [ 858.0, 316.0, 185.0, 74.0 ], + "patching_rect" : [ 858.0, 316.0, 188.0, 74.0 ], "text" : "Makes displayed previous active slot and interpolation status to ignore slot 0. Can be usefull when using slot 0 as a temporary step for interpolation." } @@ -517,7 +517,7 @@ "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, - "patching_rect" : [ 527.0, 665.0, 65.0, 20.0 ], + "patching_rect" : [ 523.0, 665.0, 65.0, 20.0 ], "text" : "For testing" } @@ -855,7 +855,7 @@ , { "box" : { "id" : "obj-8", - "items" : "0 (tmp)", + "items" : "", "maxclass" : "umenu", "numinlets" : 1, "numoutlets" : 3, @@ -944,8 +944,8 @@ , { "box" : { "border" : 0, - "embedstate" : [ [ "fontsize", 14 ], [ "displayinterp", 1 ], [ "fontname", "Arial" ], [ "stored_slot_color", 0.502, 0.502, 0.502, 1 ], [ "scrollable", 1 ], [ "layout", 1 ], [ "interp_slot_color", 1, 1, 1, 0.8 ], [ "bubblesize", 20 ], [ "spacing", 4 ], [ "min_rows", 10 ], [ "text_bg_color", 1, 1, 1, 0.5 ], [ "autowriteagain", 0 ], [ "empty_slot_color", 0.349, 0.349, 0.349, 1 ], [ "bgcolor", 0.2, 0.2, 0.2, 1 ], [ "text_color", 0.129, 0.129, 0.129, 1 ], [ "ignoreslotzero", 1 ], [ "margin", 7 ], [ "slot_round", 0 ], [ "active_slot_color", 0.808, 0.898, 0.91, 1 ] ], - "filename" : "preset.better.js", + "embedstate" : [ [ "fontsize", 14 ], [ "displayinterp", 1 ], [ "fontname", "Arial" ], [ "stored_slot_color", 0.502, 0.502, 0.502, 1 ], [ "scrollable", 1 ], [ "layout", 1 ], [ "interp_slot_color", 1, 1, 1, 0.8 ], [ "bubblesize", 20 ], [ "spacing", 4 ], [ "min_rows", 50 ], [ "text_bg_color", 1, 1, 1, 0.5 ], [ "autowriteagain", 0 ], [ "empty_slot_color", 0.349, 0.349, 0.349, 1 ], [ "bgcolor", 0.2, 0.2, 0.2, 1 ], [ "text_color", 0.129, 0.129, 0.129, 1 ], [ "ignoreslotzero", 1 ], [ "margin", 4 ], [ "slot_round", 0 ], [ "active_slot_color", 0.808, 0.898, 0.91, 1 ] ], + "filename" : "tc.preset.js", "id" : "obj-10", "jsarguments" : [ "test" ], "maxclass" : "jsui", @@ -978,15 +978,15 @@ "numinlets" : 1, "numoutlets" : 3, "outlettype" : [ "", "", "" ], - "patching_rect" : [ 459.0, 664.0, 52.0, 22.0 ], + "patching_rect" : [ 464.5, 664.0, 40.0, 22.0 ], "restore" : [ -0.857142857142857, -0.228571428571429, 0.314285714285714, 0.314285714285714, -0.171428571428571, -0.714285714285714, -0.942857142857143, 0.142857142857143, 0.485714285714286, 0.314285714285714, -0.057142857142857, -0.457142857142857, -0.771428571428571, -0.971428571428571, -1.0, -0.8 ], "saved_object_attributes" : { "parameter_enable" : 0, "parameter_mappable" : 0 } , - "text" : "pattr oui", - "varname" : "oui" + "text" : "pattr", + "varname" : "u099005226" } } @@ -1369,8 +1369,8 @@ } ], "dependency_cache" : [ { - "name" : "preset.better.js", - "bootpath" : "~/Documents/_MAX/pattrstorage_helper", + "name" : "tc.preset.js", + "bootpath" : "~/Documents/_MAX/tc.preset", "patcherrelativepath" : ".", "type" : "TEXT", "implicit" : 1