From a817c3d6aad48f83d734445ca21295069bb7f0a3 Mon Sep 17 00:00:00 2001 From: Hanspeter Portner Date: Fri, 19 May 2023 23:00:51 +0200 Subject: [PATCH] Add missing widgets to d2tk ui --- meson_options.txt | 2 +- plugin/d2tk_ui.c | 679 ++++++++++++++++++++++++++-------------------- 2 files changed, 392 insertions(+), 289 deletions(-) diff --git a/meson_options.txt b/meson_options.txt index d2062fc..674b91b 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -43,4 +43,4 @@ option('lv2libdir', type : 'string', value : 'lib/lv2') -option('version', type : 'string', value : '0.41.95') +option('version', type : 'string', value : '0.41.97') diff --git a/plugin/d2tk_ui.c b/plugin/d2tk_ui.c index 4862d22..b920a55 100644 --- a/plugin/d2tk_ui.c +++ b/plugin/d2tk_ui.c @@ -417,6 +417,13 @@ _dynparams_get(plughandle_t *handle, LV2_URID prop) static dynparam_t * _dynparams_add(plughandle_t *handle, LV2_URID prop) { + // ignore canvas graph and aspectRatio properties + if( (prop == handle->canvas.urid.Canvas_graph) + || (prop == handle->canvas.urid.Canvas_aspectRatio) ) + { + return NULL; + } + const size_t new_sz = sizeof(dynparam_t) * ++handle->ndynparams; handle->dynparams = realloc(handle->dynparams, new_sz); //TODO check @@ -450,6 +457,7 @@ _dynparams_clr(plughandle_t *handle) } handle->ndynparams = 0; + handle->graph_size = 0; } static void @@ -630,6 +638,14 @@ _dyn_prop_rem(plughandle_t *handle, LV2_URID subj, LV2_URID prop, } } +static void +_dyn_prop_set_body(dynparam_t *dynparam, uint32_t size, const void *body) +{ + dynparam->size = size; + dynparam->val = realloc(dynparam->val, size); //FIXME check + memcpy(dynparam->val, body, size); +} + static void _dyn_prop_set(plughandle_t *handle, LV2_URID subj, LV2_URID prop, const LV2_Atom *atom) @@ -646,9 +662,7 @@ _dyn_prop_set(plughandle_t *handle, LV2_URID subj, LV2_URID prop, return; //TODO log } - dynparam->size = atom->size; - dynparam->val = realloc(dynparam->val, atom->size); //FIXME check - memcpy(dynparam->val, LV2_ATOM_BODY_CONST(atom), atom->size); + _dyn_prop_set_body(dynparam, atom->size, LV2_ATOM_BODY_CONST(atom)); } static void @@ -1058,32 +1072,19 @@ _expose_editor(plughandle_t *handle, const d2tk_rect_t *rect) static void _aspect_correction(d2tk_rect_t *rect, float aspect_ratio) { - const d2tk_coord_t lon = rect->w >= rect->h - ? rect->w - : rect->h; - const d2tk_coord_t sho = rect->w < rect->h - ? rect->w - : rect->h; + const float rect_ar = (float)rect->w / rect->h; if(aspect_ratio <= 0.f) { - aspect_ratio = 1.f; - } - - if(aspect_ratio < 1.f) - { - rect->w = sho * aspect_ratio; - rect->h = sho; + // fill whole are } - else if(aspect_ratio == 1.f) + else if(rect_ar < aspect_ratio) // keep width { - rect->w = sho; - rect->h = sho; + rect->h = rect->w / aspect_ratio; } - else //if(aspect_ratio > 1.f) + else if (rect_ar > aspect_ratio) // keep height { - rect->w = lon; - rect->h = lon / aspect_ratio; + rect->w = rect->h * aspect_ratio; } } @@ -1108,11 +1109,6 @@ _expose_canvas_graph(plughandle_t *handle, const d2tk_rect_t *_rect) { d2tk_base_t *base = d2tk_frontend_get_base(handle->dpugl); - if(handle->graph_size == 0) - { - return; - } - d2tk_rect_t rect = *_rect; _aspect_correction(&rect, handle->state.aspect_ratio); @@ -1196,29 +1192,6 @@ _expose_canvas_graph(plughandle_t *handle, const d2tk_rect_t *_rect) } } -static void -_expose_graph_minimize(plughandle_t *handle, const d2tk_rect_t *rect) -{ - d2tk_base_t *base = d2tk_frontend_get_base(handle->dpugl); - - static const char *path [2] = { "eye-off.png", "eye.png" }; - static const char tip [2][10] = { "show graph", "hide graph" }; - - bool visible = !handle->state.graph_hidden; - const d2tk_state_t state = d2tk_base_toggle_label_image(base, D2TK_ID, - 0, NULL, D2TK_ALIGN_CENTERED, -1, path[visible], rect, &visible); - - if(d2tk_state_is_changed(state)) - { - handle->state.graph_hidden = !handle->state.graph_hidden; - _message_set_key(handle, handle->urid_graphHidden); - } - if(d2tk_state_is_over(state)) - { - d2tk_base_set_tooltip(base, sizeof(tip[visible]), tip[visible], handle->tip_height); - } -} - static void _expose_manual(plughandle_t *handle, const d2tk_rect_t *rect) { @@ -1261,14 +1234,13 @@ _expose_manual(plughandle_t *handle, const d2tk_rect_t *rect) } static void -_expose_graph_footer(plughandle_t *handle, const d2tk_rect_t *rect) +_expose_left(plughandle_t *handle, const d2tk_rect_t *rect) { d2tk_base_t *base = d2tk_frontend_get_base(handle->dpugl); - const d2tk_coord_t frac [3] = { - 0, rect->h, rect->h - }; - D2TK_BASE_LAYOUT(rect, 3, frac, D2TK_FLAG_LAYOUT_X_ABS, lay) + const d2tk_coord_t frac [3] = { 0, 5, 0 }; + const size_t n = handle->graph_size ? 3 : 1; + D2TK_BASE_LAYOUT(rect, n, frac, D2TK_FLAG_LAYOUT_Y_ABS, lay) { const unsigned k = d2tk_layout_get_index(lay); const d2tk_rect_t *lrect = d2tk_layout_get_rect(lay); @@ -1277,50 +1249,15 @@ _expose_graph_footer(plughandle_t *handle, const d2tk_rect_t *rect) { case 0: { - static char lbl [] = "canvas•graph"; - - d2tk_base_label(base, sizeof(lbl), lbl, 0.5f, lrect, - D2TK_ALIGN_LEFT | D2TK_ALIGN_MIDDLE); + _expose_editor(handle, lrect); } break; case 1: { - _expose_manual(handle, lrect); + d2tk_base_separator(base, lrect, D2TK_FLAG_SEPARATOR_Y); } break; case 2: { - _expose_graph_minimize(handle, lrect); - } break; - } - } -} - -static void -_expose_left(plughandle_t *handle, const d2tk_rect_t *rect) -{ - const d2tk_coord_t frac [2] = { - handle->state.graph_hidden ? 1 : 0, - handle->state.editor_hidden ? 1 : 0 - }; - D2TK_BASE_LAYOUT(rect, 2, frac, D2TK_FLAG_LAYOUT_Y_ABS, lay) - { - const unsigned k = d2tk_layout_get_index(lay); - const d2tk_rect_t *lrect = d2tk_layout_get_rect(lay); - - switch(k) - { - case 0: - { - if(!handle->state.graph_hidden) - { - _expose_canvas_graph(handle, lrect); - } - } break; - case 1: - { - if(!handle->state.editor_hidden) - { - _expose_editor(handle, lrect); - } + _expose_canvas_graph(handle, lrect); } break; } } @@ -1367,7 +1304,7 @@ _body_as_double(plughandle_t *handle, const void *data, LV2_URID range) static void _expose_slot_enum(plughandle_t *handle, dynparam_t *dynparam, - const d2tk_rect_t *rect, size_t lbl_len, const char *lbl, unsigned k) + const d2tk_rect_t *rect, unsigned k) { d2tk_frontend_t *dpugl = handle->dpugl; d2tk_base_t *base = d2tk_frontend_get_base(dpugl); @@ -1377,8 +1314,6 @@ _expose_slot_enum(plughandle_t *handle, dynparam_t *dynparam, return; } - d2tk_base_label(base, lbl_len, lbl, 0.5f, rect, D2TK_ALIGN_CENTERED); - // derive item number size_t nitms = 0; LV2_ATOM_TUPLE_FOREACH(dynparam->points, itm) @@ -1417,8 +1352,20 @@ _expose_slot_enum(plughandle_t *handle, dynparam_t *dynparam, itms[nitms++] = LV2_ATOM_BODY_CONST(label); } - const d2tk_state_t state = d2tk_base_combo(base, D2TK_ID_IDX(k), - nitms, itms, rect, &idx); + d2tk_rect_t bnd; + d2tk_rect_shrink_x(&bnd, rect, rect->h/2); + + d2tk_state_t state; + if(dynparam->writable) + { + state = d2tk_base_combo(base, D2TK_ID_IDX(k), + nitms, itms, &bnd, &idx); + } + else + { + state = d2tk_base_label(base, -1, itms[idx], 0.5f, &bnd, + D2TK_ALIGN_LEFT | D2TK_ALIGN_MIDDLE); + } if(d2tk_state_is_changed(state)) { @@ -1446,15 +1393,11 @@ _expose_slot_enum(plughandle_t *handle, dynparam_t *dynparam, _message_set_dynparam(handle, dynparam); } - if(d2tk_state_is_over(state) && dynparam->comment) - { - d2tk_base_set_tooltip(base, -1, dynparam->comment, handle->tip_height); - } } static void _expose_slot_bool(plughandle_t *handle, dynparam_t *dynparam, - const d2tk_rect_t *rect, size_t lbl_len, const char *lbl, unsigned k) + const d2tk_rect_t *rect, unsigned k) { d2tk_frontend_t *dpugl = handle->dpugl; d2tk_base_t *base = d2tk_frontend_get_base(dpugl); @@ -1467,22 +1410,18 @@ _expose_slot_bool(plughandle_t *handle, dynparam_t *dynparam, bool val = *(int32_t *)dynparam->val; const d2tk_state_t state = d2tk_base_spinner_bool(base, - D2TK_ID_IDX(k), rect, lbl_len, lbl, &val, _dynparam_flag(dynparam)); + D2TK_ID_IDX(k), rect, 0, NULL, &val, _dynparam_flag(dynparam)); if(d2tk_state_is_changed(state)) { *(int32_t *)dynparam->val = val; _message_set_dynparam(handle, dynparam); } - if(d2tk_state_is_over(state) && dynparam->comment) - { - d2tk_base_set_tooltip(base, -1, dynparam->comment, handle->tip_height); - } } static void _expose_slot_int(plughandle_t *handle, dynparam_t *dynparam, - const d2tk_rect_t *rect, size_t lbl_len, const char *lbl, unsigned k) + const d2tk_rect_t *rect, unsigned k) { d2tk_frontend_t *dpugl = handle->dpugl; d2tk_base_t *base = d2tk_frontend_get_base(dpugl); @@ -1497,21 +1436,17 @@ _expose_slot_int(plughandle_t *handle, dynparam_t *dynparam, int32_t *val = dynparam->val; const d2tk_state_t state = d2tk_base_spinner_int32(base, - D2TK_ID_IDX(k), rect, lbl_len, lbl, min, val, max, _dynparam_flag(dynparam)); + D2TK_ID_IDX(k), rect, 0, NULL, min, val, max, _dynparam_flag(dynparam)); if(d2tk_state_is_changed(state)) { _message_set_dynparam(handle, dynparam); } - if(d2tk_state_is_over(state) && dynparam->comment) - { - d2tk_base_set_tooltip(base, -1, dynparam->comment, handle->tip_height); - } } static void _expose_slot_long(plughandle_t *handle, dynparam_t *dynparam, - const d2tk_rect_t *rect, size_t lbl_len, const char *lbl, unsigned k) + const d2tk_rect_t *rect, unsigned k) { d2tk_frontend_t *dpugl = handle->dpugl; d2tk_base_t *base = d2tk_frontend_get_base(dpugl); @@ -1526,21 +1461,17 @@ _expose_slot_long(plughandle_t *handle, dynparam_t *dynparam, int64_t *val = dynparam->val; const d2tk_state_t state = d2tk_base_spinner_int64(base, - D2TK_ID_IDX(k), rect, lbl_len, lbl, min, val, max, _dynparam_flag(dynparam)); + D2TK_ID_IDX(k), rect, 0, NULL, min, val, max, _dynparam_flag(dynparam)); if(d2tk_state_is_changed(state)) { _message_set_dynparam(handle, dynparam); } - if(d2tk_state_is_over(state) && dynparam->comment) - { - d2tk_base_set_tooltip(base, -1, dynparam->comment, handle->tip_height); - } } static void _expose_slot_float(plughandle_t *handle, dynparam_t *dynparam, - const d2tk_rect_t *rect, size_t lbl_len, const char *lbl, unsigned k) + const d2tk_rect_t *rect, unsigned k) { d2tk_frontend_t *dpugl = handle->dpugl; d2tk_base_t *base = d2tk_frontend_get_base(dpugl); @@ -1555,21 +1486,17 @@ _expose_slot_float(plughandle_t *handle, dynparam_t *dynparam, float *val = dynparam->val; const d2tk_state_t state = d2tk_base_spinner_float(base, - D2TK_ID_IDX(k), rect, lbl_len, lbl, min, val, max, _dynparam_flag(dynparam)); + D2TK_ID_IDX(k), rect, 0, NULL, min, val, max, _dynparam_flag(dynparam)); if(d2tk_state_is_changed(state)) { _message_set_dynparam(handle, dynparam); } - if(d2tk_state_is_over(state) && dynparam->comment) - { - d2tk_base_set_tooltip(base, -1, dynparam->comment, handle->tip_height); - } } static void _expose_slot_double(plughandle_t *handle, dynparam_t *dynparam, - const d2tk_rect_t *rect, size_t lbl_len, const char *lbl, unsigned k) + const d2tk_rect_t *rect, unsigned k) { d2tk_frontend_t *dpugl = handle->dpugl; d2tk_base_t *base = d2tk_frontend_get_base(dpugl); @@ -1584,21 +1511,23 @@ _expose_slot_double(plughandle_t *handle, dynparam_t *dynparam, double *val = dynparam->val; const d2tk_state_t state = d2tk_base_spinner_double(base, - D2TK_ID_IDX(k), rect, lbl_len, lbl, min, val, max, _dynparam_flag(dynparam)); + D2TK_ID_IDX(k), rect, 0, NULL, min, val, max, _dynparam_flag(dynparam)); if(d2tk_state_is_changed(state)) { _message_set_dynparam(handle, dynparam); } - if(d2tk_state_is_over(state) && dynparam->comment) - { - d2tk_base_set_tooltip(base, -1, dynparam->comment, handle->tip_height); - } } +static const d2tk_lineedit_filter_t urid_filter = { + .completion_cb = NULL, + .hints_cb = NULL, + .free_hints_cb = NULL +}; + static void _expose_slot_urid(plughandle_t *handle, dynparam_t *dynparam, - const d2tk_rect_t *rect, size_t lbl_len, const char *lbl, unsigned k) + const d2tk_rect_t *rect, unsigned k) { d2tk_frontend_t *dpugl = handle->dpugl; d2tk_base_t *base = d2tk_frontend_get_base(dpugl); @@ -1608,167 +1537,412 @@ _expose_slot_urid(plughandle_t *handle, dynparam_t *dynparam, return; } - uint32_t *val = dynparam->val; -//FIXME -#if 0 - char uri [PATH_MAX]; + char txt [2048]; + LV2_URID *val = dynparam->val; - snprintf(uri, sizeof(uri), "%s", + snprintf(txt, sizeof(txt), "%s", handle->unmap->unmap(handle->unmap->handle, *val)); - //FIXME - const d2tk_state_t state = d2tk_base_text_field(base, D2TK_ID_IDX(k), rect, - sizeof(uri), uri, D2TK_ALIGN_MIDDLE | D2TK_ALIGN_LEFT, NULL); -#else - const char *uri = handle->unmap->unmap(handle->unmap->handle, *val); + d2tk_rect_t bnd; + d2tk_rect_shrink_x(&bnd, rect, rect->h/2); - const d2tk_state_t state = d2tk_base_label(base, -1, uri, 0.5f, rect, - D2TK_ALIGN_MIDDLE | D2TK_ALIGN_LEFT); -#endif + d2tk_state_t state; + if(dynparam->writable) + { + state = d2tk_base_lineedit(base, D2TK_ID_IDX(k), + sizeof(txt), txt, &urid_filter, &bnd, D2TK_FLAG_NONE); + } + else + { + state = d2tk_base_label(base, sizeof(txt), txt, 0.5f, &bnd, + D2TK_ALIGN_LEFT | D2TK_ALIGN_MIDDLE); + } if(d2tk_state_is_changed(state)) { - *val = handle->map->map(handle->map->handle, uri); + *val = handle->map->map(handle->map->handle, txt); _message_set_dynparam(handle, dynparam); } - if(d2tk_state_is_over(state) && dynparam->comment) +} + +static void +_expose_dynparam_clear(plughandle_t *handle, dynparam_t *dynparam, + const d2tk_rect_t *rect, unsigned k) +{ + d2tk_frontend_t *dpugl = handle->dpugl; + d2tk_base_t *base = d2tk_frontend_get_base(dpugl); + + static const char path [] = "delete.png"; + static const char none [] = ""; + static const char tip [] = "clear"; + const uint32_t none_sz = dynparam->range == handle->forge.String ? 1 : 0; + + const d2tk_state_t state = d2tk_base_button_image(base, D2TK_ID_IDX(k), + sizeof(path), path, rect); + + if(d2tk_state_is_changed(state)) { - d2tk_base_set_tooltip(base, -1, dynparam->comment, handle->tip_height); + _dyn_prop_set_body(dynparam, none_sz, none); + _message_set_dynparam(handle, dynparam); + } + if(d2tk_state_is_over(state)) + { + d2tk_base_set_tooltip(base, sizeof(tip), tip, handle->tip_height); } } static void -_expose_slot_string(plughandle_t *handle, dynparam_t *dynparam, - const d2tk_rect_t *rect, size_t lbl_len, const char *lbl, unsigned k) +_expose_dynparam_copy(plughandle_t *handle, dynparam_t *dynparam, + const char *mime, const d2tk_rect_t *rect, unsigned k) { d2tk_frontend_t *dpugl = handle->dpugl; d2tk_base_t *base = d2tk_frontend_get_base(dpugl); - if(!dynparam->val) + static const char path [] = "copy.png"; + static const char tip [] = "copy to clipboard"; + + const d2tk_state_t state = d2tk_base_button_image(base, D2TK_ID_IDX(k), + sizeof(path), path, rect); + + if(d2tk_state_is_changed(state)) { - return; + d2tk_frontend_set_clipboard(dpugl, mime, dynparam->val, dynparam->size); + } + if(d2tk_state_is_over(state)) + { + d2tk_base_set_tooltip(base, sizeof(tip), tip, handle->tip_height); } +} + +static void +_expose_dynparam_paste(plughandle_t *handle, dynparam_t *dynparam, + const char *mime_in, const d2tk_rect_t *rect, unsigned k) +{ + d2tk_frontend_t *dpugl = handle->dpugl; + d2tk_base_t *base = d2tk_frontend_get_base(dpugl); - const char *val = dynparam->val; + static const char path [] = "clipboard.png"; + static const char tip [] = "paste from clipboard"; - //FIXME - const d2tk_state_t state = d2tk_base_label(base, -1, val, 0.5f, rect, - D2TK_ALIGN_MIDDLE | D2TK_ALIGN_LEFT); + const d2tk_state_t state = d2tk_base_button_image(base, D2TK_ID_IDX(k), + sizeof(path), path, rect); if(d2tk_state_is_changed(state)) { - _message_set_dynparam(handle, dynparam); + size_t txt_len = 0; + const char *mime_out = mime_in; + const char *txt = d2tk_frontend_get_clipboard(dpugl, &mime_out, &txt_len); + + if(txt && txt_len && mime_out && !strcmp(mime_in, mime_out)) + { + _dyn_prop_set_body(dynparam, txt_len, txt); + _message_set_dynparam(handle, dynparam); + } + else + { + lv2_log_error(&handle->logger, "[%s] failed to paste text: %s", __func__, + mime_out); + } } - if(d2tk_state_is_over(state) && dynparam->comment) + if(d2tk_state_is_over(state)) { - d2tk_base_set_tooltip(base, -1, dynparam->comment, handle->tip_height); + d2tk_base_set_tooltip(base, sizeof(tip), tip, handle->tip_height); } } +#ifdef _LV2_HAS_REQUEST_VALUE static void -_expose_slot_chunk(plughandle_t *handle, dynparam_t *dynparam, - const d2tk_rect_t *rect, size_t lbl_len, const char *lbl, unsigned k) +_expose_blob_load(plughandle_t *handle, LV2_URID prop, LV2_URID range, + const d2tk_rect_t *rect, unsigned k) { d2tk_frontend_t *dpugl = handle->dpugl; d2tk_base_t *base = d2tk_frontend_get_base(dpugl); - if(!dynparam->val) + static const char path [] = "save.png"; + static const char tip [] = "load from file"; + + if(!handle->request_code) { return; } - char sz [128]; - const size_t sz_len = snprintf(sz, sizeof(sz), "%s (%"PRIu32" bytes)", - dynparam->label, dynparam->size); - - //FIXME - const d2tk_state_t state = d2tk_base_label(base, sz_len, sz, 0.5f, rect, - D2TK_ALIGN_MIDDLE | D2TK_ALIGN_LEFT); + const d2tk_state_t state = d2tk_base_button_image(base, D2TK_ID_IDX(k), + sizeof(path), path, rect); if(d2tk_state_is_changed(state)) { - _message_set_dynparam(handle, dynparam); + const LV2UI_Request_Value_Status status = handle->request_code->request( + handle->request_code->handle, prop, range, NULL); + + if( (status != LV2UI_REQUEST_VALUE_SUCCESS) + && (status != LV2UI_REQUEST_VALUE_BUSY) ) + { + lv2_log_error(&handle->logger, "[%s] requestValue failed: %i", __func__, status); + + if(status == LV2UI_REQUEST_VALUE_ERR_UNSUPPORTED) + { + handle->request_code = NULL; + } + } } - if(d2tk_state_is_over(state) && dynparam->comment) + if(d2tk_state_is_over(state)) + { + d2tk_base_set_tooltip(base, sizeof(tip), tip, handle->tip_height); + } +} +#endif + +static size_t +szprintf(char *lbl, size_t lbl_len, uint32_t size) +{ + char suffixes [4] = { ' ', 'K', 'M', 'G' }; + char *suffix = &suffixes[0]; + + while(size > 1024) { - d2tk_base_set_tooltip(base, -1, dynparam->comment, handle->tip_height); + size /= 1024; + suffix++; } + + return snprintf(lbl, lbl_len, "%"PRIu32"%cB", + size, *suffix); } static void -_expose_slot(plughandle_t *handle, const d2tk_rect_t *rect, unsigned k) +_expose_slot_string(plughandle_t *handle, dynparam_t *dynparam, + const d2tk_rect_t *rect, unsigned k) { d2tk_frontend_t *dpugl = handle->dpugl; d2tk_base_t *base = d2tk_frontend_get_base(dpugl); - dynparam_t *dynparam = &handle->dynparams[k]; - - if(!dynparam->label) + if(!dynparam->val) { return; } - char buf[256]; - const char *lbl; - size_t lbl_len; - - if(dynparam->unit) + const d2tk_coord_t frac [6] = { + 0, rect->h, rect->h, rect->h, rect->h, 0 + }; + D2TK_BASE_LAYOUT(rect, 6, frac, D2TK_FLAG_LAYOUT_X_ABS, lay) { - lbl_len = snprintf(buf, sizeof(buf), "%s•%s", dynparam->label, dynparam->unit); - lbl = buf; + const unsigned y = d2tk_layout_get_index(lay); + const d2tk_rect_t *lrect = d2tk_layout_get_rect(lay); + + switch(y) + { + case 0: + { + char lbl [32]; + const size_t lbl_len = szprintf(lbl, sizeof(lbl), dynparam->size); + + d2tk_base_label(base, lbl_len, lbl, 0.5f, rect, + D2TK_ALIGN_LEFT | D2TK_ALIGN_MIDDLE); + } break; + case 1: + { + if(dynparam->writable) + { + _expose_dynparam_clear(handle, dynparam, lrect, k); + } + } break; + case 2: + { + _expose_dynparam_copy(handle, dynparam, "UTF8_STRING", lrect, k); + } break; + case 3: + { + if(dynparam->writable) + { + _expose_dynparam_paste(handle, dynparam, "UTF8_STRING", lrect, k); + } + } break; + case 4: + { +#ifdef _LV2_HAS_REQUEST_VALUE + if(dynparam->writable) + { + _expose_blob_load(handle, dynparam->prop, dynparam->range, lrect, k); + } +#endif + } break; + } } - else +} + +static void +_expose_slot_chunk(plughandle_t *handle, dynparam_t *dynparam, + const d2tk_rect_t *rect, unsigned k) +{ + d2tk_frontend_t *dpugl = handle->dpugl; + d2tk_base_t *base = d2tk_frontend_get_base(dpugl); + + const d2tk_coord_t frac [6] = { + 0, rect->h, rect->h, rect->h, rect->h, 0 + }; + D2TK_BASE_LAYOUT(rect, 6, frac, D2TK_FLAG_LAYOUT_X_ABS, lay) { - lbl_len = -1; - lbl = dynparam->label; + const unsigned y = d2tk_layout_get_index(lay); + const d2tk_rect_t *lrect = d2tk_layout_get_rect(lay); + + switch(y) + { + case 0: + { + char lbl [32]; + const size_t lbl_len = szprintf(lbl, sizeof(lbl), dynparam->size); + + d2tk_base_label(base, lbl_len, lbl, 0.5f, rect, + D2TK_ALIGN_LEFT | D2TK_ALIGN_MIDDLE); + } break; + case 1: + { + if(dynparam->writable) + { + _expose_dynparam_clear(handle, dynparam, lrect, k); + } + } break; + case 2: + { + _expose_dynparam_copy(handle, dynparam, "application/octet-stream", lrect, k); + } break; + case 3: + { + if(dynparam->writable) + { + _expose_dynparam_paste(handle, dynparam, "application/octet-stream", lrect, k); + } + } break; + case 4: + { +#ifdef _LV2_HAS_REQUEST_VALUE + if(dynparam->writable) + { + _expose_blob_load(handle, dynparam->prop, dynparam->range, lrect, k); + } +#endif + } break; + } } +} + +static void +_expose_slot(plughandle_t *handle, const d2tk_rect_t *rect, unsigned k) +{ + d2tk_frontend_t *dpugl = handle->dpugl; + d2tk_base_t *base = d2tk_frontend_get_base(dpugl); + + dynparam_t *dynparam = &handle->dynparams[k]; if(dynparam->points) { - _expose_slot_enum(handle, dynparam, rect, lbl_len, lbl, k); + _expose_slot_enum(handle, dynparam, rect, k); } else if(dynparam->range == handle->props.urid.atom_bool) { - _expose_slot_bool(handle, dynparam, rect, lbl_len, lbl, k); + _expose_slot_bool(handle, dynparam, rect, k); } else if(dynparam->range == handle->props.urid.atom_int) { - _expose_slot_int(handle, dynparam, rect, lbl_len, lbl, k); + _expose_slot_int(handle, dynparam, rect, k); } else if(dynparam->range == handle->props.urid.atom_long) { - _expose_slot_long(handle, dynparam, rect, lbl_len, lbl, k); + _expose_slot_long(handle, dynparam, rect, k); } else if(dynparam->range == handle->props.urid.atom_float) { - _expose_slot_float(handle, dynparam, rect, lbl_len, lbl, k); + _expose_slot_float(handle, dynparam, rect, k); } else if(dynparam->range == handle->props.urid.atom_double) { - _expose_slot_double(handle, dynparam, rect, lbl_len, lbl, k); + _expose_slot_double(handle, dynparam, rect, k); } -#if 0 else if(dynparam->range == handle->props.urid.atom_urid) { - _expose_slot_urid(handle, dynparam, rect, lbl_len, lbl, k); + _expose_slot_urid(handle, dynparam, rect, k); } else if(dynparam->range == handle->forge.String) { - _expose_slot_string(handle, dynparam, rect, lbl_len, lbl, k); + _expose_slot_string(handle, dynparam, rect, k); } else if(dynparam->range == handle->forge.Chunk) { - _expose_slot_chunk(handle, dynparam, rect, lbl_len, lbl, k); + _expose_slot_chunk(handle, dynparam, rect, k); } -#endif else { char lbl [256]; const size_t lbl_len = snprintf(lbl, sizeof(lbl), "%s (type not implemented)", dynparam->label); - d2tk_base_label(base, lbl_len, lbl, 0.375f, rect, - D2TK_ALIGN_RIGHT | D2TK_ALIGN_MIDDLE); + d2tk_rect_t bnd; + d2tk_rect_shrink_x(&bnd, rect, rect->h/2); + + d2tk_base_label(base, lbl_len, lbl, 0.375f, &bnd, + D2TK_ALIGN_LEFT | D2TK_ALIGN_MIDDLE); + } +} + +static void +_expose_slot_frame(plughandle_t *handle, const d2tk_rect_t *rect, unsigned k) +{ + d2tk_frontend_t *dpugl = handle->dpugl; + d2tk_base_t *base = d2tk_frontend_get_base(dpugl); + const d2tk_style_t *style = d2tk_base_get_style(base); + const uint32_t pad = 2*style->border_width; + + dynparam_t *dynparam = &handle->dynparams[k]; + + if(!dynparam->label) + { + return; + } + + char buf[256]; + const char *lbl; + size_t lbl_len; + + if(dynparam->unit) + { + lbl_len = snprintf(buf, sizeof(buf), "%s [%s]", + dynparam->label, dynparam->unit); + lbl = buf; + } + else + { + lbl_len = -1; + lbl = dynparam->label; + } + + D2TK_BASE_FRAME(base, rect, lbl_len, lbl, frm) + { + const d2tk_rect_t *frect = d2tk_frame_get_rect(frm); + + const d2tk_coord_t frac [2] = { 2, 1 }; + D2TK_BASE_LAYOUT(frect, 2, frac, D2TK_FLAG_LAYOUT_Y_REL, lay) + { + const unsigned y = d2tk_layout_get_index(lay); + const d2tk_rect_t *lrect = d2tk_layout_get_rect(lay); + d2tk_rect_t bnd; + + d2tk_rect_shrink(&bnd, lrect, pad); + + switch(y) + { + case 0: + { + _expose_slot(handle, &bnd, k); + } break; + case 1: + { + if(dynparam->comment) + { + d2tk_base_label(base, -1, dynparam->comment, 1.f, &bnd, + D2TK_ALIGN_RIGHT | D2TK_ALIGN_MIDDLE); + } + } break; + } + } } } @@ -1796,7 +1970,7 @@ _expose_right(plughandle_t *handle, const d2tk_rect_t *rect) break; } - _expose_slot(handle, trect, k); + _expose_slot_frame(handle, trect, k); } } } @@ -1807,7 +1981,8 @@ _expose_body(plughandle_t *handle, const d2tk_rect_t *rect) d2tk_base_t *base = d2tk_frontend_get_base(handle->dpugl); const d2tk_coord_t frac [3] = { 0, 5, handle->sidebar_width }; - D2TK_BASE_LAYOUT(rect, 3, frac, D2TK_FLAG_LAYOUT_X_ABS, lay) + const size_t n = handle->ndynparams ? 3 : 1; + D2TK_BASE_LAYOUT(rect, n, frac, D2TK_FLAG_LAYOUT_X_ABS, lay) { const unsigned k = d2tk_layout_get_index(lay); const d2tk_rect_t *lrect = d2tk_layout_get_rect(lay); @@ -1972,78 +2147,11 @@ _expose_text_paste(plughandle_t *handle, const d2tk_rect_t *rect) } } -#ifdef _LV2_HAS_REQUEST_VALUE -static void -_expose_text_load(plughandle_t *handle, const d2tk_rect_t *rect) -{ - d2tk_frontend_t *dpugl = handle->dpugl; - d2tk_base_t *base = d2tk_frontend_get_base(dpugl); - - static const char path [] = "save.png"; - static const char tip [] = "load from file"; - - if(!handle->request_code) - { - return; - } - - const d2tk_state_t state = d2tk_base_button_image(base, D2TK_ID, - sizeof(path), path, rect); - - if(d2tk_state_is_changed(state)) - { - const LV2_URID key = handle->urid_code; - const LV2_URID type = handle->forge.String; - - const LV2UI_Request_Value_Status status = handle->request_code->request( - handle->request_code->handle, key, type, NULL); - - if( (status != LV2UI_REQUEST_VALUE_SUCCESS) - && (status != LV2UI_REQUEST_VALUE_BUSY) ) - { - lv2_log_error(&handle->logger, "[%s] requestValue failed: %i", __func__, status); - - if(status == LV2UI_REQUEST_VALUE_ERR_UNSUPPORTED) - { - handle->request_code = NULL; - } - } - } - if(d2tk_state_is_over(state)) - { - d2tk_base_set_tooltip(base, sizeof(tip), tip, handle->tip_height); - } -} -#endif - -static void -_expose_text_minimize(plughandle_t *handle, const d2tk_rect_t *rect) -{ - d2tk_base_t *base = d2tk_frontend_get_base(handle->dpugl); - - static const char *path [2] = { "eye-off.png", "eye.png" }; - static const char tip [2][10] = { "show code", "hide code" }; - - bool visible = !handle->state.editor_hidden; - const d2tk_state_t state = d2tk_base_toggle_label_image(base, D2TK_ID, - 0, NULL, D2TK_ALIGN_CENTERED, -1, path[visible], rect, &visible); - - if(d2tk_state_is_changed(state)) - { - handle->state.editor_hidden = !handle->state.editor_hidden; - _message_set_key(handle, handle->urid_editorHidden); - } - if(d2tk_state_is_over(state)) - { - d2tk_base_set_tooltip(base, sizeof(tip[visible]), tip[visible], handle->tip_height); - } -} - static void _expose_text_footer(plughandle_t *handle, const d2tk_rect_t *rect) { const d2tk_coord_t frac [8] = { - rect->h, 0, 0, rect->h, rect->h, rect->h, rect->h, rect->h + rect->h, rect->h, 0, 0, rect->h, rect->h, rect->h, rect->h }; D2TK_BASE_LAYOUT(rect, 8, frac, D2TK_FLAG_LAYOUT_X_ABS, lay) { @@ -2058,33 +2166,33 @@ _expose_text_footer(plughandle_t *handle, const d2tk_rect_t *rect) } break; case 1: { - _expose_text_link(handle, lrect); + _expose_manual(handle, lrect); } break; case 2: { - _expose_font_height(handle, lrect); + _expose_text_link(handle, lrect); } break; case 3: { - _expose_text_clear(handle, lrect); + _expose_font_height(handle, lrect); } break; case 4: { - _expose_text_copy(handle, lrect); + _expose_text_clear(handle, lrect); } break; case 5: { - _expose_text_paste(handle, lrect); + _expose_text_copy(handle, lrect); } break; case 6: { -#ifdef _LV2_HAS_REQUEST_VALUE - _expose_text_load(handle, lrect); -#endif + _expose_text_paste(handle, lrect); } break; case 7: { - _expose_text_minimize(handle, lrect); +#ifdef _LV2_HAS_REQUEST_VALUE + _expose_blob_load(handle, handle->urid_code, handle->forge.String, lrect, k); +#endif } break; } } @@ -2110,13 +2218,12 @@ _expose(void *data, d2tk_coord_t w, d2tk_coord_t h) d2tk_base_set_style(base, &style); - const d2tk_coord_t frac [4] = { + const d2tk_coord_t frac [3] = { handle->header_height, - handle->footer_height, 0, handle->footer_height }; - D2TK_BASE_LAYOUT(&rect, 4, frac, D2TK_FLAG_LAYOUT_Y_ABS, lay) + D2TK_BASE_LAYOUT(&rect, 3, frac, D2TK_FLAG_LAYOUT_Y_ABS, lay) { const unsigned k = d2tk_layout_get_index(lay); const d2tk_rect_t *lrect = d2tk_layout_get_rect(lay); @@ -2128,14 +2235,10 @@ _expose(void *data, d2tk_coord_t w, d2tk_coord_t h) _expose_header(handle, lrect); } break; case 1: - { - _expose_graph_footer(handle, lrect); - } break; - case 2: { _expose_body(handle, lrect); } break; - case 3: + case 2: { _expose_text_footer(handle, lrect); } break; @@ -2349,7 +2452,7 @@ instantiate(const LV2UI_Descriptor *descriptor, handle->footer_height = 32 * handle->scale; handle->tip_height = 20 * handle->scale; handle->sidebar_width = 256 * handle->scale; - handle->item_height = 40 * handle->scale; + handle->item_height = 80 * handle->scale; handle->state.font_height = 16; _update_font_height(handle); -- 2.38.5