diff --git a/README.md b/README.md index 4573015..9950ff6 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ A [jsui] replacement for the [preset] object in Cycling'74 Max. - 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]. ## Known bugs -- Text in list layout is blurry (but not the dragged slot) +- Some interactions should be ignored when no pattrstorage is linked ## Desired features (for someday) - No need for a patch cord (programmatically create a [send]/[receive] pair?) diff --git a/tc.preset.js b/tc.preset.js index 010d45f..37f14b9 100644 --- a/tc.preset.js +++ b/tc.preset.js @@ -82,6 +82,7 @@ var bg_width, bg_height = 0; var mg = new MGraphics(ui_width, ui_height); var base_drawing; +var is_painting_base = 0; var half_slot_size, half_margin, half_spacing; var last_x, last_y, last_hovered = -1; @@ -166,22 +167,17 @@ function draw_slot(id, scale, cont) { cont = typeof cont !== 'undefined' ? cont : mgraphics; // Sets drawing context to mgraphics by default if not passed as argument var offset = slot_size * (1 - scale); - - draw_slot_bubble(slots[id][0] + offset, slots[id][1] + offset, slot_size * scale, slot_size * scale, cont); - cont.fill(); - if (layout == 1) { - // // Slot number - // var nb = i.toString(); - // var nb_dim = text_measure(nb); - // var nb_pos_x = slots[i][0] + (slot_size - nb_dim[0]) / 2; - // var nb_pos_y = slots[i][1] + (slot_size - spacing + nb_dim[1]) / 2 ; + if(is_painting_base) { + draw_slot_bubble(slots[id][0] * scale, slots[id][1] *scale, slot_size * scale, slot_size * scale, cont); - // set_source_rgba(text_color); - // move_to(nb_pos_x, nb_pos_y); - // show_text(nb); + } else { + draw_slot_bubble(slots[id][0] + offset, slots[id][1] + offset, slot_size * scale, slot_size * scale, cont); + } + cont.fill(); + if (layout == 1) { // slot text background var bg_txt_pos_x = margin + slot_size + spacing; var bg_txt_pos_y = slots[id][1]; @@ -193,36 +189,17 @@ function draw_slot(id, scale, cont) { } else { cont.set_source_rgba(empty_slot_color); } - // cont.rectangle_rounded(bg_txt_pos_x, bg_txt_pos_y, bg_txt_dim_w, bg_txt_dim_h, 4, 4); // slot name + cont.set_font_size(font_size*scale); var text = format_slot_name(id); - draw_text_bubble(bg_txt_pos_x, bg_txt_pos_y, bg_txt_dim_w, bg_txt_dim_h, text, cont); - // cont.fill(); - + if (is_painting_base) { + draw_text_bubble(bg_txt_pos_x * scale, bg_txt_pos_y * scale, bg_txt_dim_w * scale, bg_txt_dim_h * scale, text, cont); - // // slot name - // var text = id; - // // If slot is locked, add brackets around its number - // if (slots[id][5] == 1) { - // text = '[' + text + ']'; - // } - // // If slot has a name, append it to the preset name - // if (slots[id][4] != null) { - // text += ': ' + slots[id][4]; - // } - - // text = text.toString(); - // var text_dim = cont.text_measure(text); - - // var txt_pos_x = margin + slot_size + 2 * spacing; - // var txt_pos_y = bg_txt_pos_y + (bg_txt_dim_h - spacing + text_dim[1]) / 2 ; - - // cont.set_source_rgba(text_color); - // cont.move_to(txt_pos_x, txt_pos_y); - // cont.show_text(text.toString()); - + } else { + draw_text_bubble(bg_txt_pos_x + offset, bg_txt_pos_y + offset, bg_txt_dim_w * scale, bg_txt_dim_h * scale, text, cont); + } } } @@ -243,23 +220,13 @@ draw_slot_bubble.local = 1; function draw_text_bubble(x, y, w, h, text, cont) { cont = typeof cont !== 'undefined' ? cont : mgraphics; // slot text background - // var bg_txt_pos_x = margin + slot_size + spacing; - // var bg_txt_pos_y = slots[id][1]; - // var bg_txt_dim_w = ui_width - (2*margin + slot_size + spacing); - // var bg_txt_dim_h = slot_size; - - // if (slots[id][4] != null) { - // cont.set_source_rgba(stored_slot_color); - // } else { - // cont.set_source_rgba(empty_slot_color); - // } cont.rectangle_rounded(x, y, w, h, 4, 4); cont.fill(); var text_dim = cont.text_measure(text); - var txt_pos_x = margin + slot_size + 2 * spacing; - var txt_pos_y = y + (h - spacing + text_dim[1]) / 2 ; + var txt_pos_x = x + spacing; + var txt_pos_y = y + (text_dim[1] + h)/2 - text_dim[1]*0.18; cont.set_source_rgba(text_color); cont.move_to(txt_pos_x, txt_pos_y); @@ -283,14 +250,15 @@ 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 + is_painting_base = 1; // Background bg_width = layout == 0 ? columns * (slot_size + spacing) - spacing + 2 * margin : ui_width; bg_height = rows * (slot_size + spacing) - spacing + 2 * margin; - mg = new MGraphics(ui_width, bg_height); + mg = new MGraphics(ui_width*2, bg_height*2); with(mg) { set_source_rgba(background_color); - rectangle(0, 0, bg_width, bg_height); + rectangle(0, 0, bg_width*2, bg_height*2); fill(); select_font_face(font_name); @@ -304,10 +272,11 @@ function paint_base() { } else { set_source_rgba(empty_slot_color); } - draw_slot(i, 1, mg); + draw_slot(i, 2, mg); } } } + is_painting_base = 0; update_umenu(); base_drawing = new Image(mg); mgraphics.redraw(); @@ -318,9 +287,15 @@ 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); @@ -376,8 +351,6 @@ function paint() if (layout == 0) { //Text (slot number and name) var text = format_slot_name(last_hovered); - select_font_face(font_name); - set_font_size(font_size); 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. @@ -414,9 +387,8 @@ function paint() translate(last_x, last_y ); rotate(0.15); scale(1.1, 1.1); - // scale(3, 3); - // Shadow + // 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); @@ -424,6 +396,8 @@ function paint() } 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(); @@ -435,15 +409,7 @@ function paint() draw_slot_bubble( -slot_size/2, -slot_size/2, slot_size, slot_size); fill(); // slot name - var text = drag_slot; - // If slot is locked, add brackets around its number - if (slots[drag_slot][5] == 1) { - text = '[' + text + ']'; - } - // If slot has a name, append it to the preset name - if (slots[drag_slot][4] != null) { - text += ': ' + slots[drag_slot][4]; - } + 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); diff --git a/tc.preset_demo.maxpat b/tc.preset_demo.maxpat index 67a4162..fda2fb6 100755 --- a/tc.preset_demo.maxpat +++ b/tc.preset_demo.maxpat @@ -10,7 +10,7 @@ } , "classnamespace" : "box", - "rect" : [ 134.0, 100.0, 715.0, 848.0 ], + "rect" : [ 34.0, 100.0, 688.0, 848.0 ], "bglocked" : 0, "openinpresentation" : 0, "default_fontsize" : 12.0, @@ -39,6 +39,18 @@ "subpatcher_template" : "", "assistshowspatchername" : 0, "boxes" : [ { + "box" : { + "id" : "obj-9", + "maxclass" : "message", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 465.0, 630.0, 127.0, 22.0 ], + "text" : "fontname \"Arial Black\"" + } + + } +, { "box" : { "id" : "obj-65", "linecount" : 6, @@ -848,14 +860,15 @@ "parameter_enable" : 0, "patching_rect" : [ 302.0, 772.0, 100.0, 50.0 ], "presentation" : 1, - "presentation_rect" : [ 146.0, 63.5, 119.0, 22.0 ] + "presentation_rect" : [ 146.0, 63.5, 119.0, 22.0 ], + "text" : "<(unnamed)>" } } , { "box" : { "id" : "obj-8", - "items" : "", + "items" : [ "1 <(unnamed)>", ",", "2 <(unnamed)>" ], "maxclass" : "umenu", "numinlets" : 1, "numoutlets" : 3, @@ -944,7 +957,7 @@ , { "box" : { "border" : 0, - "embedstate" : [ [ "fontsize", 14 ], [ "displayinterp", 1 ], [ "fontname", "Arial" ], [ "stored_slot_color", 0.502, 0.502, 0.502, 1 ], [ "scrollable", 1 ], [ "layout", 0 ], [ "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 ] ], + "embedstate" : [ [ "text_bg_color", 1, 1, 1, 0.5 ], [ "autowriteagain", 0 ], [ "layout", 1 ], [ "empty_slot_color", 0.349, 0.349, 0.349, 1 ], [ "spacing", 4 ], [ "text_color", 0.129, 0.129, 0.129, 1 ], [ "ignoreslotzero", 1 ], [ "min_rows", 50 ], [ "active_slot_color", 0.808, 0.898, 0.91, 1 ], [ "bubblesize", 20 ], [ "displayinterp", 1 ], [ "stored_slot_color", 0.502, 0.502, 0.502, 1 ], [ "scrollable", 1 ], [ "margin", 4 ], [ "fontsize", 14 ], [ "interp_slot_color", 1, 1, 1, 0.8 ], [ "slot_round", 0 ], [ "bgcolor", 0.2, 0.2, 0.2, 1 ], [ "fontname", "Arial" ] ], "filename" : "tc.preset.js", "id" : "obj-10", "jsarguments" : [ "test" ], @@ -1366,6 +1379,13 @@ "source" : [ "obj-87", 0 ] } + } +, { + "patchline" : { + "destination" : [ "obj-10", 0 ], + "source" : [ "obj-9", 0 ] + } + } ], "dependency_cache" : [ {