add poll_edited and edited_color attributes for showing a dot on slots when edited

This commit is contained in:
2025-09-17 19:35:03 +02:00
parent ea78a1de13
commit 16cd1cb878
2 changed files with 94 additions and 5 deletions

View File

@@ -167,6 +167,10 @@
<description>When set to 1, the jsui will display the ongoing interpolation between presets when a recall message with three arguments or a recallmulti message with at least one argument are sent to the linked pattrstorage. <description>When set to 1, the jsui will display the ongoing interpolation between presets when a recall message with three arguments or a recallmulti message with at least one argument are sent to the linked pattrstorage.
Notice that the recallmutli message needs to be sent both the pattrstorage and the jsui.</description> Notice that the recallmutli message needs to be sent both the pattrstorage and the jsui.</description>
</attribute> </attribute>
<attribute name='edited_color' get='1' set='1' type='list' size='4' >
<digest>Edited Dot Color</digest>
<description>Defines the color of the dot shown on top of a slot when the corresponding preset is edited. See poll_edited attribute.</description>
</attribute>
<attribute name='empty_slot_color' get='1' set='1' type='list' size='4' > <attribute name='empty_slot_color' get='1' set='1' type='list' size='4' >
<digest>Empty slot color</digest> <digest>Empty slot color</digest>
<description>Sets the empty slot color of the object in RGBA format</description> <description>Sets the empty slot color of the object in RGBA format</description>
@@ -194,10 +198,14 @@
<description>Set the name of the [pattrstorage] to bind to. Its outlet must be connected to the [tc.preset] inlet. <description>Set the name of the [pattrstorage] to bind to. Its outlet must be connected to the [tc.preset] inlet.
</description> </description>
</attribute> </attribute>
<attribute name='recall_passthrough' get='1' set='1' type='bool' size='1' > <attribute name='recall_passthrough' get='1' set='1' type='bool' size='1' >
<digest>Send recall messages to pattrstorage directly</digest> <digest>Send recall messages to pattrstorage directly</digest>
<description>When enabled (default) recall messages triggered by clicking filled slots in tc.preset are sent directly to [pattrstorage]. When disabled, these recall messages are sent out of [tc.preset] left outlet and it's up to the user to pass them to [pattrstorage]. It can be usefull for triggering interpolations with custom logic.</description> <description>When enabled (default) recall messages triggered by clicking filled slots in tc.preset are sent directly to [pattrstorage]. When disabled, these recall messages are sent out of [tc.preset] left outlet and it's up to the user to pass them to [pattrstorage]. It can be usefull for triggering interpolations with custom logic.</description>
</attribute> </attribute>
<attribute name='poll_edited' get='1' set='1' type='bool' size='1' >
<digest>Regularly check if current preset is edited</digest>
<description>When set to a positive value, [tc.preset] will check if the last recalled preset has been edited by polling [pattrstorage] with the 'getedited' message every period of time defined by the value. For example, a value of 0.5 will result in a polling every half second. When a preset is edited, a dot appears on top of its slot.</description>
</attribute>
<attribute name='scrollable' get='1' set='1' type='bool' size='1' > <attribute name='scrollable' get='1' set='1' type='bool' size='1' >
<digest>Scroll through your presets</digest> <digest>Scroll through your presets</digest>
<description>When set to 1, you can through the jsui to see all your presets, or at least up to the row defined by the min_rows attributes. <description>When set to 1, you can through the jsui to see all your presets, or at least up to the row defined by the min_rows attributes.

View File

@@ -56,6 +56,7 @@ var stored_slot_color = [0.502, 0.502, 0.502, 1];
var interp_slot_color = [1.0, 1.0, 1.0, 0.8]; var interp_slot_color = [1.0, 1.0, 1.0, 0.8];
var text_bg_color = [1,1,1, 0.5]; var text_bg_color = [1,1,1, 0.5];
var text_color = [0.129, 0.129, 0.129, 1]; var text_color = [0.129, 0.129, 0.129, 1];
var edited_color = [1, 0.49, 0.263, 1];
var color_1 = [0.743, 0.41, 0.501, 1]; // Color set for the filled slots. I don't like how this is declared. More info in color_wheel() declaration var color_1 = [0.743, 0.41, 0.501, 1]; // Color set for the filled slots. I don't like how this is declared. More info in color_wheel() declaration
var color_2 = [0.679, 0.405, 0.669,1]; var color_2 = [0.679, 0.405, 0.669,1];
@@ -82,6 +83,7 @@ var unique_names = false; // When enabled, force names to be unique when renam
var use_uid = 0; // Generating UID for each presets when enabled. Requires a [pattr preset_metadata] var use_uid = 0; // Generating UID for each presets when enabled. Requires a [pattr preset_metadata]
var recall_passthrough = true; // By default (true), clicking a slot sends a recall message directly to [pattrstorage], and the jsui left outlet outputs a recall message once the recall is done. When disabled, clicking a slot will send a recall message straight from the jsui left outlet, so it's up to the user to forward the message to pattrstorage. It can be usefull for triggering interpolations with custom logic. var recall_passthrough = true; // By default (true), clicking a slot sends a recall message directly to [pattrstorage], and the jsui left outlet outputs a recall message once the recall is done. When disabled, clicking a slot will send a recall message straight from the jsui left outlet, so it's up to the user to forward the message to pattrstorage. It can be usefull for triggering interpolations with custom logic.
var ui_rename = false; // Use the attached textedit, if any, to edit slot names directly in the JSUI frame when clicking a slot while holding the control key. When disabled, the textedit remains untouched but gets focused when clicking a slot while holding the control key. var ui_rename = false; // Use the attached textedit, if any, to edit slot names directly in the JSUI frame when clicking a slot while holding the control key. When disabled, the textedit remains untouched but gets focused when clicking a slot while holding the control key.
var poll_edited = 1; // If >0, check if current preset is edited every X seconds defined by the variable value.
// (WORK) // (WORK)
var pattrstorage_name, pattrstorage_obj = null; var pattrstorage_name, pattrstorage_obj = null;
@@ -94,6 +96,7 @@ var filled_slots = []; // List of stored slots
var filled_slots_dict = new Dict(); var filled_slots_dict = new Dict();
var active_slot = 0; //Last recalled slot var active_slot = 0; //Last recalled slot
var active_slot_edited = false; //Active slot edited state flag. See run_edited_poll_task()
var previous_active_slot = 0; //Previously recalled slot var previous_active_slot = 0; //Previously recalled slot
var previous_target = 0; //Here to deal with ongoing interpolations var previous_target = 0; //Here to deal with ongoing interpolations
var selected_slot = 0; //Last selected slot. Relevant especially when select_mode = 1. Otherwise it is the same as active_slot var selected_slot = 0; //Last selected slot. Relevant especially when select_mode = 1. Otherwise it is the same as active_slot
@@ -133,6 +136,8 @@ var textedit_obj = null;
var textedit_initstate = {}; var textedit_initstate = {};
var is_typing_name = false; var is_typing_name = false;
var poll_edited_task = new Task(do_poll_edited, this);
var has_loaded = false; var has_loaded = false;
if (jsarguments.length>1) { // Depreciated, use "pattrstorage" attribute instead of jsarguments. if (jsarguments.length>1) { // Depreciated, use "pattrstorage" attribute instead of jsarguments.
@@ -416,7 +421,7 @@ function paint()
} }
//Hide dragged slot //Hide dragged slot
if (is_dragging) { if (is_dragging) {
set_source_rgba(empty_slot_color); set_source_rgba(empty_slot_color);
draw_slot_bubble(slots[drag_slot].left, slots[drag_slot].top, slot_size, slot_size); draw_slot_bubble(slots[drag_slot].left, slots[drag_slot].top, slot_size, slot_size);
fill(); fill();
@@ -445,6 +450,14 @@ function paint()
} }
} }
//Edited dot
if (active_slot_edited && active_slot > 0 && selected_slot <= slots_count_display) {
post("draw edited dot\n");
set_source_rgba(edited_color);
ellipse(slots[active_slot].left + 1, slots[active_slot].top + 1, slot_size/3, slot_size/3);
fill();
}
// Hovered slot // Hovered slot
if (last_hovered > -1) { if (last_hovered > -1) {
if (shift_hold) { if (shift_hold) {
@@ -913,20 +926,26 @@ function recall() {
} else { } else {
previous_active_slot = previous_target; previous_active_slot = previous_target;
} }
set_active_slot(src_slot); set_active_slot(src_slot);
active_slot_edited = 0;
run_edited_poll_task();
} else if (interp == 1.0) { } else if (interp == 1.0) {
slots[src_slot].interp = -1; slots[src_slot].interp = -1;
slots[trg_slot].interp = -1; slots[trg_slot].interp = -1;
is_interpolating = 0; is_interpolating = 0;
previous_target = trg_slot; previous_target = trg_slot;
set_active_slot(trg_slot); set_active_slot(trg_slot);
active_slot_edited = 0;
run_edited_poll_task();
} else { } else {
slots[src_slot].interp = 1 - interp; slots[src_slot].interp = 1 - interp;
slots[trg_slot].interp = interp; slots[trg_slot].interp = interp;
is_interpolating = 1; is_interpolating = 1;
active_slot = 0; active_slot = 0;
// if (src_slot != trg_slot) {
// active_slot_edited = 1;
// cancel_edited_poll_task();
// }
} }
if (recall_passthrough) { if (recall_passthrough) {
outlet(0, "recall", src_slot, trg_slot, interp); outlet(0, "recall", src_slot, trg_slot, interp);
@@ -968,6 +987,8 @@ function recallmulti() {
} }
is_interpolating = 1; is_interpolating = 1;
active_slot_edited = 0;
run_edited_poll_task();
mgraphics.redraw(); mgraphics.redraw();
outlet(0, "recallmulti", args); outlet(0, "recallmulti", args);
@@ -1006,6 +1027,9 @@ function store(v) {
to_pattrstorage("store", v); to_pattrstorage("store", v);
to_pattrstorage("getslotlist"); to_pattrstorage("getslotlist");
active_slot_edited = 0;
run_edited_poll_task();
if (recalc_rows_flag) { if (recalc_rows_flag) {
calc_rows_columns(); calc_rows_columns();
} else { } else {
@@ -2114,6 +2138,63 @@ function setui_rename(v){
} }
} }
declareattribute("poll_edited", "getpoll_edited", "setpoll_edited", 1, {type: "float", min: 0, label: "Poll Edited State"});
function getpoll_edited() {
return poll_edited;
}
function setpoll_edited(v){
poll_edited = v == 0 ? 0 : Math.max(0.1, Math.abs(v));
if (poll_edited > 0) {
run_edited_poll_task();
} else {
cancel_edited_poll_task();
}
}
function run_edited_poll_task() {
if (poll_edited_task.valid && !poll_edited_task.running && poll_edited > 0 && active_slot > 0) {
poll_edited_task.interval = poll_edited * 1000;
post("run task!\n");
poll_edited_task.repeat();
}
}
run_edited_poll_task.local = 1;
function cancel_edited_poll_task() {
poll_edited_task.cancel();
}
cancel_edited_poll_task.local = 1;
function do_poll_edited() {
post("do_poll_edited\n");
if (pattrstorage_obj != null) {
to_pattrstorage("getedited");
}
}
do_poll_edited.local = 1;
declareattribute("edited_color", "getedited_color", "setedited_color", 1, {style: "rgba", label: "Edited Dot Color", category: "Appearance"});
function getedited_color() {
return edited_color;
}
function setedited_color(){
if (arguments.length == 4) {
edited_color = [arguments[0], arguments[1], arguments[2], arguments[3]];
} else if (arguments.length == 0) {
edited_color = [1, 0.49, 0.263, 1];
} else {
error('edited_color: wrong number of arguments\n');
}
}
function edited(v) {
active_slot_edited = v;
if (v == 1) {
cancel_edited_poll_task();
mgraphics.redraw();
}
}
// UTILITY // UTILITY
function post_keys(obj) { function post_keys(obj) {
post('Keys of obj: ', obj, '\n'); post('Keys of obj: ', obj, '\n');