resize in presentation mode, more robust initialization, performance improvement, small bug fixes
This commit is contained in:
18
README.md
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
|
||||
|
428
tc.preset.js
428
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();
|
||||
draw_slot_bubble(slots[i][0], slots[i][1] + slot_size * (1-interp), slot_size, slot_size * interp);
|
||||
} else {
|
||||
draw_slot_bubble(slots[active_slot][0], slots[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;
|
||||
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
// 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();
|
||||
|
||||
// Buble text
|
||||
set_source_rgba(text_color);
|
||||
move_to(txt_pos_x, txt_pos_y);
|
||||
show_text(text.toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 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);
|
||||
// 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();
|
||||
}
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
// 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
// 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();
|
||||
|
||||
// Buble text
|
||||
set_source_rgba(text_color);
|
||||
move_to(txt_pos_x, txt_pos_y);
|
||||
show_text(text.toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 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');
|
||||
}
|
@@ -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" : {
|
||||
|
Reference in New Issue
Block a user