Browse Source

resize in presentation mode, more robust initialization, performance improvement, small bug fixes

main
TFLCL 3 months ago
parent
commit
8f4e7ff660
  1. 18
      README.md
  2. 410
      tc.preset.js
  3. 83
      tc.preset_demo.maxpat

18
README.md

@ -3,9 +3,10 @@
A [jsui] replacement for the [preset] object in Cycling'74 Max.
## Features
- Same click + modifier key behavior as the vanilla object to store and delete presets
- Drag and drop presets to re-organize
- Display presets as a grid or a list
- Scrollable (requires Max 8.6.2)
- Scrollable list layout (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)
@ -14,24 +15,27 @@ A [jsui] replacement for the [preset] object in Cycling'74 Max.
- 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
- Dynamically adapts to resize both in Edit and Presentation mode
- Select mode: simple click selects the slot, double click recalls it (allows for organizing presets without recalling them)
- Color mode: ability to color sstored presets with 6 customizable colors (currently colors are only assigned automatically depending on slot number)
## 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].
- Create a [`jsui @filename tc.preset.js`].
- Connect the [pattrstorage] outlet to the [jsui] inlet
- Set the jsui attribute named "pattrstorage" to the name of the pattrstorage you just connected (or send a message like "pattrstorage my_pattrstorage_name")
## Limitations
- Resize doesn't work in Presentation mode (jsui limitation)
- 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
- `recall`: send to [pattrstorage] only
- `recallmulti`, `slotname`: send to [pattrstorage] first (for better timing), then to the [jsui]
- `store`: send to [jsui] only
- Some messages to pattrstorage causes the jsui to be out of sync (`clear`, `insert`, `lockall`, `read`, `readagain`, `remove`, `renumber`). If you use any of these messages, make sure to then send a `resync` to the jsui.
- The js program send a lot of message to the [pattrstorage] (using `maxobj.message()`syntax, so without patch cord), which in return send (using a patch cord) 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 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)
- Select mode: simple click selects the slot, double click recalls it
## Desired features (for someday, if ever)
- 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

410
tc.preset.js

@ -106,18 +106,26 @@ var is_interpolating = 0;
var is_dragging = 0; // Drag flag
var drag_slot = -1; // Stores the slot that's being dragged
if (jsarguments.length>1) {
var has_loaded = false;
// Allows for dynamic resizing even in presentation mode (addressing the limitation of onresize())
var pres_rect = new MaxobjListener(this.box,"presentation_rect",get_prect);
function get_prect(prect) {
onresize(prect.value[2], prect.value[3])
}
if (jsarguments.length>1) { // Depreciated, use "pattrstorage" attribute instead of jsarguments.
pattrstorage_name = jsarguments[1];
}
function loadbang() {
has_loaded = true;
post("loadbang\n");
outlet(2, "set");
find_pattrstorage(pattrstorage_name);
calc_rows_columns();
}
// loadbang();
function calc_rows_columns() {
half_margin = margin / 2;
half_spacing = spacing / 2;
@ -246,6 +254,7 @@ function draw_text_bubble(x, y, w, h, text, cont) {
cont.move_to(txt_pos_x, txt_pos_y);
cont.show_text(text.toString());
}
draw_text_bubble.local = 1;
function format_slot_name(id) {
var text = id;
@ -264,7 +273,7 @@ format_slot_name.local = 1;
function paint_base() {
// We draw all slots (empty and stored ones) so we don't have to for every redraw
// post("paint_base\n");
is_painting_base = 1;
// Background
@ -305,167 +314,174 @@ paint_base.local = 1;
function paint()
{
// post("redraw\n");
with (mgraphics) {
select_font_face(font_name);
set_font_size(font_size);
translate(0, y_offset);
// Draw the base, which includes empty and filled slots
// It is first rendered at twice the size in order to make texts look nice and cripsy on hidpi discplays
// So we need to scale it down here
scale(0.5, 0.5);
image_surface_draw(base_drawing);
scale(2, 2);
set_line_width(1);
// Active slot
if (is_dragging == 0 && active_slot > 0 && active_slot <= slots_count_display) {
set_source_rgba(active_slot_color);
if (color_mode) {
draw_slot_bubble(slots[active_slot][0]+1.5, slots[active_slot][1]+1.5, slot_size-3, slot_size-3);
set_line_width(3);
stroke();
} else {
draw_slot_bubble(slots[active_slot][0], slots[active_slot][1], slot_size, slot_size);
fill();
}
}
// Previous active slot
if (is_dragging == 0 && previous_active_slot > 0 && previous_active_slot <= slots_count_display) {
// set_source_rgba(active_slot_color);
// draw_slot_bubble(slots[previous_active_slot][0]+0.75, slots[previous_active_slot][1]+0.75, slot_size-1.5, slot_size-1.5);
// set_line_width(1.5);
// stroke();
set_source_rgba(active_slot_color[0], active_slot_color[1], active_slot_color[2], active_slot_color[3] * 0.5);
if (color_mode) {
draw_slot_bubble(slots[previous_active_slot][0]+1.5, slots[previous_active_slot][1]+1.5, slot_size-3, slot_size-3);
set_line_width(3);
stroke();
} else {
draw_slot_bubble(slots[previous_active_slot][0], slots[previous_active_slot][1], slot_size, slot_size);
fill();
}
}
// Selected slot
if (select_mode && selected_slot > 0 && selected_slot <= slots_count_display) {
set_source_rgba(active_slot_color);
// Handling Presentation mode enable/disable
var cur_size = mgraphics.size;
if (cur_size[0] != ui_width || cur_size[1] != ui_height) {
onresize(cur_size[0], cur_size[1]);
} else {
with (mgraphics) {
select_font_face(font_name);
set_font_size(font_size);
translate(0, y_offset);
// Draw the base, which includes empty and filled slots
// It is first rendered at twice the size in order to make texts look nice and cripsy on hidpi discplays
// So we need to scale it down here
scale(0.5, 0.5);
image_surface_draw(base_drawing);
scale(2, 2);
set_line_width(1);
draw_slot_bubble(slots[selected_slot][0] - 0.5, slots[selected_slot][1] - 0.5, slot_size + 1, slot_size + 1);
stroke();
}
// Interpolated slots
if (is_dragging == 0 && display_interp && is_interpolating) {
for (var i = 1; i <= slots_count_display; i++) {
var interp = slots[i][6];
if (interp >= 0) {
set_source_rgba(interp_slot_color);
draw_slot_bubble(slots[i][0], slots[i][1], slot_size, slot_size);
// Active slot
if (is_dragging == 0 && active_slot > 0 && active_slot <= slots_count_display) {
set_source_rgba(active_slot_color);
if (color_mode) {
draw_slot_bubble(slots[active_slot][0]+1.5, slots[active_slot][1]+1.5, slot_size-3, slot_size-3);
set_line_width(3);
stroke();
} else {
draw_slot_bubble(slots[active_slot][0], slots[active_slot][1], slot_size, slot_size);
fill();
}
}
// Previous active slot
if (is_dragging == 0 && previous_active_slot > 0 && previous_active_slot <= slots_count_display) {
// set_source_rgba(active_slot_color);
// draw_slot_bubble(slots[previous_active_slot][0]+0.75, slots[previous_active_slot][1]+0.75, slot_size-1.5, slot_size-1.5);
// set_line_width(1.5);
// stroke();
set_source_rgba(active_slot_color[0], active_slot_color[1], active_slot_color[2], active_slot_color[3] * 0.5);
if (color_mode) {
draw_slot_bubble(slots[previous_active_slot][0]+1.5, slots[previous_active_slot][1]+1.5, slot_size-3, slot_size-3);
set_line_width(3);
stroke();
draw_slot_bubble(slots[i][0], slots[i][1] + slot_size * (1-interp), slot_size, slot_size * interp);
} else {
draw_slot_bubble(slots[previous_active_slot][0], slots[previous_active_slot][1], slot_size, slot_size);
fill();
}
}
}
// Hovered slot
if (last_hovered > -1) {
if (shift_hold) {
if (option_hold) {
// About to delete
set_source_rgba(empty_slot_color[0], empty_slot_color[1], empty_slot_color[2], 0.8);
draw_slot_bubble(slots[last_hovered][0] + 1, slots[last_hovered][1] + 1, slot_size-2, slot_size-2);
fill();
} else {
// About to store
set_source_rgba(active_slot_color[0], active_slot_color[1], active_slot_color[2], 0.7);
draw_slot_bubble(slots[last_hovered][0] + 1, slots[last_hovered][1] + 1, slot_size-2, slot_size-2);
fill();
}
}
// Slot border
set_source_rgba(1, 1, 1, 0.8);
draw_slot_bubble(slots[last_hovered][0], slots[last_hovered][1], slot_size, slot_size);
stroke();
if (layout == 0) {
//Text (slot number and name)
var text = format_slot_name(last_hovered);
var text_dim = text_measure(text);
// If the text is too big or a slot is being dragged, display the text on top of the next slot.
// Otherwise, it gets displayed on the hovered slot.
var bg_txt_dim_w = text_dim[0] > slot_size ? text_dim[0] + 4 : slot_size + 4;
var bg_txt_dim_h = text_dim[1] > slot_size ? text_dim[1] + 4 : slot_size + 4;
var bg_txt_pos_x = text_dim[0] > slot_size || is_dragging ? slots[last_hovered][0] + slot_size + 2: slots[last_hovered][0] - 2;
var bg_txt_pos_y = text_dim[1] > slot_size || is_dragging ? slots[last_hovered][1] - 2 : slots[last_hovered][1] - 2;
// Selected slot
if (selected_slot > 0 && selected_slot <= slots_count_display) {
set_source_rgba(active_slot_color);
set_line_width(1);
draw_slot_bubble(slots[selected_slot][0] - 0.5, slots[selected_slot][1] - 0.5, slot_size + 1, slot_size + 1);
stroke();
}
// Interpolated slots
if (is_dragging == 0 && display_interp && is_interpolating) {
for (var i = 1; i <= slots_count_display; i++) {
var interp = slots[i][6];
if (interp >= 0) {
set_source_rgba(interp_slot_color);
draw_slot_bubble(slots[i][0], slots[i][1], slot_size, slot_size);
stroke();
draw_slot_bubble(slots[i][0], slots[i][1] + slot_size * (1-interp), slot_size, slot_size * interp);
fill();
}
}
}
// If there is not enough place, text is displayed on the left
if (bg_txt_pos_x + bg_txt_dim_w > ui_width) {
bg_txt_pos_x = slots[last_hovered][0] - half_spacing - bg_txt_dim_w;
// Hovered slot
if (last_hovered > -1) {
if (shift_hold) {
if (option_hold) {
// About to delete
set_source_rgba(empty_slot_color[0], empty_slot_color[1], empty_slot_color[2], 0.8);
draw_slot_bubble(slots[last_hovered][0] + 1, slots[last_hovered][1] + 1, slot_size-2, slot_size-2);
fill();
} else {
// About to store
set_source_rgba(active_slot_color[0], active_slot_color[1], active_slot_color[2], 0.7);
draw_slot_bubble(slots[last_hovered][0] + 1, slots[last_hovered][1] + 1, slot_size-2, slot_size-2);
fill();
}
}
// Slot border
set_source_rgba(1, 1, 1, 0.8);
draw_slot_bubble(slots[last_hovered][0], slots[last_hovered][1], slot_size, slot_size);
stroke();
var txt_pos_x = text_dim[0] > slot_size ? bg_txt_pos_x + half_spacing : bg_txt_pos_x + (bg_txt_dim_w / 2) - (text_dim[0]/2);
var txt_pos_y = bg_txt_pos_y + (bg_txt_dim_h + text_dim[1]) / 2 - text_dim[1]*0.18;
if (layout == 0) {
//Text (slot number and name)
var text = format_slot_name(last_hovered);
var text_dim = text_measure(text);
// If the text is too big or a slot is being dragged, display the text on top of the next slot.
// Otherwise, it gets displayed on the hovered slot.
var bg_txt_dim_w = text_dim[0] > slot_size ? text_dim[0] + 4 : slot_size + 4;
var bg_txt_dim_h = text_dim[1] > slot_size ? text_dim[1] + 4 : slot_size + 4;
var bg_txt_pos_x = text_dim[0] > slot_size || is_dragging ? slots[last_hovered][0] + slot_size + 2: slots[last_hovered][0] - 2;
var bg_txt_pos_y = text_dim[1] > slot_size || is_dragging ? slots[last_hovered][1] - 2 : slots[last_hovered][1] - 2;
// Bubble background
set_source_rgba(text_bg_color);
rectangle_rounded(bg_txt_pos_x, bg_txt_pos_y, bg_txt_dim_w, bg_txt_dim_h, 4, 4);
fill();
// If there is not enough place, text is displayed on the left
if (bg_txt_pos_x + bg_txt_dim_w > ui_width) {
bg_txt_pos_x = slots[last_hovered][0] - half_spacing - bg_txt_dim_w;
}
// Buble text
set_source_rgba(text_color);
move_to(txt_pos_x, txt_pos_y);
show_text(text.toString());
}
}
var txt_pos_x = text_dim[0] > slot_size ? bg_txt_pos_x + half_spacing : bg_txt_pos_x + (bg_txt_dim_w / 2) - (text_dim[0]/2);
var txt_pos_y = bg_txt_pos_y + (bg_txt_dim_h + text_dim[1]) / 2 - text_dim[1]*0.18;
// Drag slot
if (is_dragging) {
if (layout == 0) {
translate(last_x, last_y );
rotate(0.15);
scale(1.1, 1.1);
// Slot shadow
set_source_rgba(0, 0, 0, 0.15);
for (var i = 0; i<4; i++) {
draw_slot_bubble( i*0.4 + 1-slot_size/2, i*0.4 + 1-slot_size/2, slot_size + i*0.8, slot_size+i*0.8);
// Bubble background
set_source_rgba(text_bg_color);
rectangle_rounded(bg_txt_pos_x, bg_txt_pos_y, bg_txt_dim_w, bg_txt_dim_h, 4, 4);
fill();
}
draw_slot_bubble( 2-slot_size/2, 2-slot_size/2, slot_size, slot_size);
fill();
//Flying slot
set_source_rgba(active_slot_color);
draw_slot_bubble( -slot_size/2, -slot_size/2, slot_size, slot_size);
fill();
} else {
translate(last_x, last_y );
// rotate(0.15);
set_source_rgba(active_slot_color);
// Buble text
set_source_rgba(text_color);
move_to(txt_pos_x, txt_pos_y);
show_text(text.toString());
}
draw_slot_bubble( -slot_size/2, -slot_size/2, slot_size, slot_size);
fill();
// slot name
var text = format_slot_name(drag_slot);
var bg_txt_pos_x = slot_size/2+ spacing;
var bg_txt_pos_y = -slot_size/2;
var bg_txt_dim_w = ui_width - (2*margin + slot_size + spacing);
var bg_txt_dim_h = slot_size;
set_source_rgba(stored_slot_color);
draw_text_bubble(bg_txt_pos_x, bg_txt_pos_y, bg_txt_dim_w, bg_txt_dim_h, text);
}
// Drag slot
if (is_dragging) {
if (layout == 0) {
translate(last_x, last_y );
rotate(0.15);
scale(1.1, 1.1);
// Slot shadow
set_source_rgba(0, 0, 0, 0.15);
for (var i = 0; i<4; i++) {
draw_slot_bubble( i*0.4 + 1-slot_size/2, i*0.4 + 1-slot_size/2, slot_size + i*0.8, slot_size+i*0.8);
fill();
}
draw_slot_bubble( 2-slot_size/2, 2-slot_size/2, slot_size, slot_size);
fill();
//Flying slot
set_source_rgba(active_slot_color);
draw_slot_bubble( -slot_size/2, -slot_size/2, slot_size, slot_size);
fill();
} else {
translate(last_x, last_y );
// rotate(0.15);
set_source_rgba(active_slot_color);
draw_slot_bubble( -slot_size/2, -slot_size/2, slot_size, slot_size);
fill();
// slot name
var text = format_slot_name(drag_slot);
var bg_txt_pos_x = slot_size/2+ spacing;
var bg_txt_pos_y = -slot_size/2;
var bg_txt_dim_w = ui_width - (2*margin + slot_size + spacing);
var bg_txt_dim_h = slot_size;
set_source_rgba(stored_slot_color);
draw_text_bubble(bg_txt_pos_x, bg_txt_pos_y, bg_txt_dim_w, bg_txt_dim_h, text);
}
}
}
}
}
}
}
paint.local = 1;
@ -529,6 +545,8 @@ function anything() {
slots[v][6] = -1;
if (active_slot == v) {
active_slot = 0;
} else if (previous_active_slot == v) {
previous_active_slot = 0;
}
// to_pattrstorage("getslotname", v);
@ -538,6 +556,11 @@ function anything() {
set_active_slot(active_slot);
if (!is_dragging) {
outlet(0, "delete", v);
if (selected_slot == v) {
selected_slot == 0
outlet(2, 'set');
outlet(3, 'set', 0);
}
}
trigger_writeagain();
}
@ -545,8 +568,7 @@ function anything() {
}
}
function bang()
{
function bang() {
to_pattrstorage("recall", active_slot);
}
@ -554,14 +576,17 @@ function msg_int(v) {
to_pattrstorage("recall", v);
}
function msg_float(v)
{
function msg_float(v) {
var s = Math.floor(v);
var i = v % 1;
to_pattrstorage("recall", s, s+1, i);
}
function pattrstorage(v){
function init() {
loadbang();
}
function pattrstorage(v) {
find_pattrstorage(v);
paint_base();
}
@ -756,6 +781,9 @@ function lockedslots() {
if (locked_slots.length) {
for (var i = 0; i < locked_slots.length; i++) {
slots[locked_slots[i]][5] = 1;
if (locked_slots[i] == selected_slot) {
select(selected_slot);
}
}
}
}
@ -780,6 +808,7 @@ function read() {
}
function resync() {
set_active_slot(0);
calc_rows_columns();
}
@ -794,6 +823,9 @@ function find_pattrstorage(name) {
to_pattrstorage("getlockedslots");
} else {
pattrstorage_name = null;
active_slot = 0;
previous_active_slot = 0;
selected_slot = 0;
slots_clear();
// error("Pattrstorage", name, "doesn't exist.\n");
}
@ -882,17 +914,24 @@ trigger_writeagain.local = 1;
// MOUSE EVENTS
function onidle(x,y,but,cmd,shift,capslock,option,ctrl)
{
if (last_x != x || last_y != y - y_offset|| shift_hold != shift || option_hold != option) {
last_x = x;
var redraw_flag = false;
if (last_x != x || last_y != y - y_offset) {
last_x = x;
last_y = y - y_offset;
shift_hold = shift;
option_hold = option;
var cur = get_slot_index(x, y - y_offset);
var cur = get_slot_index(x, y - y_offset);
if (cur != last_hovered) {
last_hovered = cur;
redraw_flag = true;
}
}
if (shift_hold != shift || option_hold != option) {
shift_hold = shift;
option_hold = option;
redraw_flag = true;
}
if (redraw_flag) {
mgraphics.redraw();
}
}
}
onidle.local = 1;
@ -939,28 +978,6 @@ function ondblclick(x,y,but,cmd,shift,capslock,option,ctrl)
{
if (last_hovered > -1 && pattrstorage_name != null && filled_slots.indexOf(last_hovered) > -1) {
to_pattrstorage("recall", last_hovered);
// var output = "recall";
// if (select_mode) {
// output = "select";
// }
// if (shift) {
// output = "store";
// if (option) {
// output = "delete";
// }
// } else if (slots[last_hovered][4] == null) {
// return;
// }
// if (output == "store") {
// store(last_hovered);
// } else {
// if (output == "select") {
// select(last_hovered);
// // mgraphics.redraw();
// } else {
// to_pattrstorage(output, last_hovered);
// }
// }
}
last_x = x;
@ -1075,14 +1092,32 @@ function onresize(w,h)
}
onresize.local = 1;
// function ondblclick(x,y,but,cmd,shift,capslock,option,ctrl)
// {
// last_x = x;
// last_y = y;
// }
// ondblclick.local = 1;
// ATTRIBUTES DECLARATION
declareattribute("pattrstorage", "getpattrstorage", "setpattrstorage", 1);
function getpattrstorage() {
if (pattrstorage_name == null) {
return
} else {
return pattrstorage_name;
}
}
function setpattrstorage(v){
// This method is called for the first time when the patch is loading, before the loadbang (not all objects are instanciated yet)
// With v being the value stored whithin the patcher
if (v == null) {
pattrstorage_name = null;
pattrstorage_obj = null;
} else {
pattrstorage_name = arrayfromargs(arguments)[0];
}
// If the loadbang already occured once, we need to retrigger here
if (has_loaded) {
find_pattrstorage(pattrstorage_name);
loadbang();
}
// Otherwise, we just wait for the patch to call loadbang automatically at the end of its startup routine.
}
declareattribute("bubblesize", "getslotsize", "setslotsize", 1);
function getslotsize() {
return slot_size;
@ -1466,4 +1501,11 @@ function setcolor6(){
} else {
error('color_6: wrong number of arguments\n');
}
}
// UTILITY
function post_keys(obj) {
post('Keys of obj: ', obj, '\n');
post(Object.keys(obj));
post('\n');
}

83
tc.preset_demo.maxpat

@ -4,13 +4,13 @@
"appversion" : {
"major" : 8,
"minor" : 6,
"revision" : 2,
"revision" : 3,
"architecture" : "x64",
"modernui" : 1
}
,
"classnamespace" : "box",
"rect" : [ 34.0, 100.0, 854.0, 848.0 ],
"rect" : [ 310.0, 100.0, 854.0, 848.0 ],
"bglocked" : 0,
"openinpresentation" : 0,
"default_fontsize" : 12.0,
@ -39,6 +39,42 @@
"subpatcher_template" : "",
"assistshowspatchername" : 0,
"boxes" : [ {
"box" : {
"id" : "obj-31",
"maxclass" : "message",
"numinlets" : 2,
"numoutlets" : 1,
"outlettype" : [ "" ],
"patching_rect" : [ 245.5, 565.0, 89.0, 22.0 ],
"text" : "storagewindow"
}
}
, {
"box" : {
"id" : "obj-25",
"maxclass" : "message",
"numinlets" : 2,
"numoutlets" : 1,
"outlettype" : [ "" ],
"patching_rect" : [ 422.0, 598.0, 45.0, 22.0 ],
"text" : "store 3"
}
}
, {
"box" : {
"id" : "obj-14",
"maxclass" : "message",
"numinlets" : 2,
"numoutlets" : 1,
"outlettype" : [ "" ],
"patching_rect" : [ 360.5, 586.0, 29.5, 22.0 ],
"text" : "init"
}
}
, {
"box" : {
"id" : "obj-128",
"items" : [ "Grid", ",", "List" ],
@ -69,7 +105,7 @@
"maxclass" : "comment",
"numinlets" : 1,
"numoutlets" : 0,
"patching_rect" : [ 959.0, 908.0, 131.0, 33.0 ],
"patching_rect" : [ 959.0, 908.0, 133.0, 33.0 ],
"text" : "Set a given color (from 1 to 6)"
}
@ -82,7 +118,6 @@
"numoutlets" : 1,
"outlettype" : [ "" ],
"patching_rect" : [ 830.0, 927.0, 123.0, 22.0 ],
"presentation_linecount" : 2,
"text" : "color_wheel 3 0 1 1 1"
}
@ -129,7 +164,7 @@
"maxclass" : "comment",
"numinlets" : 1,
"numoutlets" : 0,
"patching_rect" : [ 928.0, 780.0, 150.0, 87.0 ],
"patching_rect" : [ 928.0, 780.0, 151.0, 87.0 ],
"text" : "When color mode is set to cycle, stored presets are shown in colors from color_1 to color_6, cyclically depending on their slot number."
}
@ -303,7 +338,7 @@
"appversion" : {
"major" : 8,
"minor" : 6,
"revision" : 2,
"revision" : 3,
"architecture" : "x64",
"modernui" : 1
}
@ -967,7 +1002,7 @@
, {
"box" : {
"id" : "obj-8",
"items" : [ "0 (tmp)", ",", "1 <(unnamed)>", ",", "2 <(unnamed)>", ",", "3 <(unnamed)>", ",", "4 <(unnamed)>", ",", "5 <(unnamed)>", ",", "6 <(unnamed)>", ",", "7 onze", ",", "8 up", ",", "9 <(unnamed)>", ",", "10 oui", ",", "11 <(unnamed)>", ",", "12 <(unnamed)>", ",", "13 <(unnamed)>", ",", "14 <(unnamed)>", ",", "15 <(unnamed)>" ],
"items" : [ "6 <(unnamed)>", ",", "19 <(unnamed)>", ",", "39 <(unnamed)>" ],
"maxclass" : "umenu",
"numinlets" : 1,
"numoutlets" : 3,
@ -987,7 +1022,7 @@
"numinlets" : 1,
"numoutlets" : 0,
"patching_rect" : [ 72.0, 139.0, 507.0, 87.0 ],
"text" : "Pattrstorage messages that doesn't trigger output and need to be sent to the jsui instead:\n- store (send to jsui only)\n- recallmulti (send to pattrstorage first for timing accuracy, then to jsui)\n- slotname (send \"setslotname\" or \"text\" to jsui instead, will rename active slot)\n- lock (or setlock to lock/unlock of the active slot)\n- some other. I've not tested them all. "
"text" : "Pattrstorage messages that doesn't trigger output and need to be sent to the jsui instead:\n- store (send to jsui only)\n- recallmulti (send to pattrstorage first for timing accuracy, then to jsui)\n- slotname (send \"setslotname\" or \"text\" to jsui instead, will rename selected slot)\n- lock (or setlock to lock/unlock of the active slot)\n- some other. I've not tested them all. "
}
}
@ -1056,18 +1091,17 @@
, {
"box" : {
"border" : 0,
"embedstate" : [ [ "autowriteagain", 0 ], [ "active_slot_color", 0.808, 0.898, 0.91, 1 ], [ "color_4", 0.367, 0.542, 0.712, 1 ], [ "slot_round", 0 ], [ "stored_slot_color", 0.502, 0.502, 0.502, 1 ], [ "layout", 0 ], [ "select_mode", 0 ], [ "color_5", 0.283, 0.606, 0.559, 1 ], [ "text_color", 0.129, 0.129, 0.129, 1 ], [ "color_mode", 0 ], [ "color_1", 0.743, 0.41, 0.501, 1 ], [ "bubblesize", 20 ], [ "interp_slot_color", 1, 1, 1, 0.8 ], [ "margin", 4 ], [ "color_6", 0.316, 0.616, 0.377, 1 ], [ "fontsize", 14 ], [ "scrollable", 1 ], [ "empty_slot_color", 0.349, 0.349, 0.349, 1 ], [ "color_2", 0.679, 0.405, 0.669, 1 ], [ "fontname", "Arial" ], [ "ignoreslotzero", 1 ], [ "spacing", 4 ], [ "text_bg_color", 1, 1, 1, 0.5 ], [ "min_rows", 50 ], [ "bgcolor", 0.2, 0.2, 0.2, 1 ], [ "color_3", 0.527, 0.459, 0.756, 1 ], [ "displayinterp", 1 ] ],
"embedstate" : [ [ "layout", 0 ], [ "color_6", 0.316, 0.616, 0.377, 1 ], [ "text_color", 0.129, 0.129, 0.129, 1 ], [ "ignoreslotzero", 1 ], [ "min_rows", 50 ], [ "bgcolor", 0.2, 0.2, 0.2, 1 ], [ "spacing", 4 ], [ "empty_slot_color", 0.349, 0.349, 0.349, 1 ], [ "displayinterp", 1 ], [ "color_1", 0.743, 0.41, 0.501, 1 ], [ "text_bg_color", 1, 1, 1, 0.5 ], [ "slot_round", 0 ], [ "color_2", 0.679, 0.405, 0.669, 1 ], [ "color_4", 0.367, 0.542, 0.712, 1 ], [ "autowriteagain", 0 ], [ "color_3", 0.527, 0.459, 0.756, 1 ], [ "active_slot_color", 0.808, 0.898, 0.91, 1 ], [ "color_mode", 0 ], [ "margin", 4 ], [ "interp_slot_color", 1, 1, 1, 0.8 ], [ "fontsize", 14 ], [ "select_mode", 0 ], [ "color_5", 0.283, 0.606, 0.559, 1 ], [ "bubblesize", 20 ], [ "stored_slot_color", 0.502, 0.502, 0.502, 1 ], [ "scrollable", 1 ], [ "fontname", "Arial" ], [ "pattrstorage", "test" ] ],
"filename" : "tc.preset.js",
"id" : "obj-10",
"jsarguments" : [ "test" ],
"maxclass" : "jsui",
"numinlets" : 1,
"numoutlets" : 4,
"outlettype" : [ "", "", "", "" ],
"parameter_enable" : 0,
"patching_rect" : [ 72.0, 637.0, 364.0, 124.0 ],
"patching_rect" : [ 72.0, 636.0, 364.0, 125.0 ],
"presentation" : 1,
"presentation_rect" : [ 1.0, 103.0, 269.0, 77.0 ]
"presentation_rect" : [ 1.0, 103.0, 293.0, 149.0 ]
}
}
@ -1125,10 +1159,10 @@
"outlettype" : [ "" ],
"patching_rect" : [ 72.0, 599.0, 176.0, 22.0 ],
"saved_object_attributes" : {
"client_rect" : [ 27, 158, 514, 944 ],
"client_rect" : [ 1450, 76, 2131, 1323 ],
"parameter_enable" : 0,
"parameter_mappable" : 0,
"storage_rect" : [ 25, 107, 816, 991 ]
"storage_rect" : [ 583, 69, 1034, 197 ]
}
,
"text" : "pattrstorage test @savemode 0",
@ -1334,6 +1368,13 @@
"source" : [ "obj-131", 0 ]
}
}
, {
"patchline" : {
"destination" : [ "obj-10", 0 ],
"source" : [ "obj-14", 0 ]
}
}
, {
"patchline" : {
@ -1387,6 +1428,13 @@
"source" : [ "obj-24", 0 ]
}
}
, {
"patchline" : {
"destination" : [ "obj-10", 0 ],
"source" : [ "obj-25", 0 ]
}
}
, {
"patchline" : {
@ -1408,6 +1456,13 @@
"source" : [ "obj-3", 1 ]
}
}
, {
"patchline" : {
"destination" : [ "obj-1", 0 ],
"source" : [ "obj-31", 0 ]
}
}
, {
"patchline" : {

Loading…
Cancel
Save