diff options
author | Hanspeter Portner <dev@open-music-kontrollers.ch> | 2015-06-07 22:18:43 +0200 |
---|---|---|
committer | Hanspeter Portner <dev@open-music-kontrollers.ch> | 2015-06-07 22:18:43 +0200 |
commit | 40876ef5d2a35dc87ec995578450a1ab5c3feda1 (patch) | |
tree | 3426ea4663b441996b64ed9dc77651c06007b244 | |
parent | 1364454391801888fef641d3ab3bd88e3f7c6bcb (diff) | |
download | sherlock.lv2-40876ef5d2a35dc87ec995578450a1ab5c3feda1.tar.xz |
a lot of fixes to reach feature completeness.
* consistently use 3 lines of text block
* add atom sequence
* add atom chunk
* truncate long string, URI, path, literal, MIDI, chunk
* hash uris
-rw-r--r-- | atom_inspector_ui.c | 615 | ||||
-rw-r--r-- | sherlock.h | 1 |
2 files changed, 430 insertions, 186 deletions
diff --git a/atom_inspector_ui.c b/atom_inspector_ui.c index 4f4215e..83f7eb0 100644 --- a/atom_inspector_ui.c +++ b/atom_inspector_ui.c @@ -21,7 +21,10 @@ #include <lv2_eo_ui.h> -#define COUNT_MAX 2018 // maximal amount of events shown +#define COUNT_MAX 2048 // maximal amount of events shown +#define STRING_BUF_SIZE 2048 +#define STRING_MAX 256 +#define STRING_OFF (STRING_MAX - 4) // Disable deprecation warnings for Blank and Resource #if defined(__clang__) @@ -32,14 +35,6 @@ # pragma GCC diagnostic ignored "-Wdeprecated-declarations" #endif -// LV2 < 1.12 has a bug in LV2_ATOM_TUPLE_FOREACH -#undef LV2_ATOM_TUPLE_FOREACH - -#define LV2_ATOM_TUPLE_FOREACH(tuple, iter) \ - for (LV2_Atom* (iter) = lv2_atom_tuple_begin(tuple); \ - !lv2_atom_tuple_is_end(LV2_ATOM_BODY(tuple), (tuple)->atom.size, (iter)); \ - (iter) = lv2_atom_tuple_next(iter)) - typedef struct _UI UI; struct _UI { @@ -52,7 +47,19 @@ struct _UI { LV2_URID_Unmap *unmap; struct { LV2_URID midi_MidiEvent; + LV2_URID event_transfer; + + LV2_URID time_position; + LV2_URID time_barBeat; + LV2_URID time_bar; + LV2_URID time_beat; + LV2_URID time_beatUnit; + LV2_URID time_beatsPerBar; + LV2_URID time_beatsPerMinute; + LV2_URID time_frame; + LV2_URID time_framesPerSecond; + LV2_URID time_speed; } uris; LV2_Atom_Forge forge; @@ -62,9 +69,14 @@ struct _UI { Evas_Object *clear; Elm_Genlist_Item_Class *itc_sherlock; + Elm_Genlist_Item_Class *itc_seq; Elm_Genlist_Item_Class *itc_prop; Elm_Genlist_Item_Class *itc_vec; Elm_Genlist_Item_Class *itc_atom; + + char string_buf [STRING_BUF_SIZE]; + + Eina_Hash *urids; }; static inline int @@ -72,21 +84,54 @@ _is_expandable(UI *ui, const uint32_t type) { return lv2_atom_forge_is_object_type(&ui->forge, type) || (type == ui->forge.Tuple) - || (type == ui->forge.Vector); + || (type == ui->forge.Vector) + || (type == ui->forge.Sequence); } -#define HIL_PRE(VAL) ("<color=#bbb font=Mono><b>"VAL"</b></color> <color=#b00>") +#define HIL_PRE(VAL) ("<color=#bbb font=Mono style=plain><b>"VAL"</b></color> <color=#b00 font=Mono style=plain>") #define HIL_POST ("</color>") -#define URI(VAL,TYP) ("<color=#bbb font=Mono><b>"VAL"</b></color> <color=#fff>"TYP"</color>") -#define HIL(VAL,TYP) ("<color=#bbb font=Mono><b>"VAL"</b></color> <color=#b00>"TYP"</color>") +#define URI(VAL,TYP) ("<color=#bbb font=Mono style=plain><b>"VAL"</b></color> <color=#fff style=plain>"TYP"</color>") +#define HIL(VAL,TYP) ("<color=#bbb font=Mono style=plain><b>"VAL"</b></color> <color=#b00 font=Mono style=plain>"TYP"</color>") + +static void +_hash_del(void *data) +{ + char *uri = data; + + if(uri) + free(uri); +} + +static inline const char * +_hash_set(UI *ui, LV2_URID urid) +{ + const char *uri = ui->unmap->unmap(ui->unmap->handle, urid); + if(uri) + eina_hash_add(ui->urids, &urid, strdup(uri)); + + //printf("prefill: %s (%u)\n", uri, urid); + + return uri; +} + +static inline const char * +_hash_get(UI *ui, LV2_URID urid) +{ + const char *uri = eina_hash_find(ui->urids, &urid); + + if(!uri) + uri = _hash_set(ui, urid); + + return uri; +} static char * _atom_stringify(UI *ui, char *ptr, char *end, const LV2_Atom *atom) { //FIXME check for buffer overflows!!! - const char *type = ui->unmap->unmap(ui->unmap->handle, atom->type); + const char *type = _hash_get(ui, atom->type); sprintf(ptr, URI("type ", "%s"), type); ptr += strlen(ptr); @@ -94,10 +139,9 @@ _atom_stringify(UI *ui, char *ptr, char *end, const LV2_Atom *atom) { const LV2_Atom_Object *atom_object = (const LV2_Atom_Object *)atom; const char *id = atom_object->body.id - ? ui->unmap->unmap(ui->unmap->handle, atom_object->body.id) + ? _hash_get(ui, atom_object->body.id) : ""; - const char *otype = ui->unmap->unmap(ui->unmap->handle, - atom_object->body.otype); + const char *otype = _hash_get(ui, atom_object->body.otype); sprintf(ptr, URI("</br>id ", "%s"), id); ptr += strlen(ptr); @@ -107,16 +151,26 @@ _atom_stringify(UI *ui, char *ptr, char *end, const LV2_Atom *atom) else if(atom->type == ui->forge.Tuple) { const LV2_Atom_Tuple *atom_tuple = (const LV2_Atom_Tuple *)atom; - + // do nothing + sprintf(ptr, "</br>"); } else if(atom->type == ui->forge.Vector) { const LV2_Atom_Vector *atom_vector = (const LV2_Atom_Vector *)atom; - const char *ctype = ui->unmap->unmap(ui->unmap->handle, - atom_vector->body.child_type); + const char *ctype = _hash_get(ui, atom_vector->body.child_type); - sprintf(ptr, URI("</br>type ", "%s"), ctype); + sprintf(ptr, URI("</br>ctype ", "%s"), ctype); + ptr += strlen(ptr); + + sprintf(ptr, URI("</br>csize ", "%u"), atom_vector->body.child_size); + } + else if(atom->type == ui->forge.Sequence) + { + const LV2_Atom_Sequence *atom_seq = (const LV2_Atom_Sequence *)atom; + + // do nothing + sprintf(ptr, "</br>"); } else if(atom->type == ui->forge.Int) { @@ -156,61 +210,137 @@ _atom_stringify(UI *ui, char *ptr, char *end, const LV2_Atom *atom) } else if(atom->type == ui->forge.String) { - const char *str = LV2_ATOM_CONTENTS_CONST(LV2_Atom_String, atom); + char *str = LV2_ATOM_CONTENTS(LV2_Atom_String, atom); + + // truncate + char tmp[4]; + if(atom->size > STRING_MAX) + { + memcpy(tmp, &str[STRING_OFF], 4); + strcpy(&str[STRING_OFF], "..."); + } sprintf(ptr, HIL("</br>value ", "%s"), str); + + // restore + if(atom->size > STRING_MAX) + memcpy(&str[STRING_OFF], tmp, 4); } else if(atom->type == ui->forge.Path) { - const char *str = LV2_ATOM_CONTENTS_CONST(LV2_Atom_String, atom); + char *str = LV2_ATOM_CONTENTS(LV2_Atom_String, atom); + + // truncate + char tmp[4]; + if(atom->size > STRING_MAX) + { + memcpy(tmp, &str[STRING_OFF], 4); + strcpy(&str[STRING_OFF], "..."); + } sprintf(ptr, HIL("</br>value ", "%s"), str); + + // restore + if(atom->size > STRING_MAX) + memcpy(&str[STRING_OFF], tmp, 4); } else if(atom->type == ui->forge.Literal) { const LV2_Atom_Literal *atom_lit = (const LV2_Atom_Literal *)atom; - const char *str = LV2_ATOM_CONTENTS_CONST(LV2_Atom_Literal, atom); - const char *datatype = ui->unmap->unmap(ui->unmap->handle, - atom_lit->body.datatype); - const char *lang = ui->unmap->unmap(ui->unmap->handle, - atom_lit->body.lang); + char *str = LV2_ATOM_CONTENTS(LV2_Atom_Literal, atom); + const char *datatype = _hash_get(ui, atom_lit->body.datatype); + const char *lang = _hash_get(ui, atom_lit->body.lang); + + // truncate + char tmp[4]; + if(atom->size > STRING_MAX) + { + memcpy(tmp, &str[STRING_OFF], 4); + strcpy(&str[STRING_OFF], "..."); + } sprintf(ptr, HIL("</br>value ", "%s"), str); ptr += strlen(ptr); + // restore + if(atom->size > STRING_MAX) + memcpy(&str[STRING_OFF], tmp, 4); + sprintf(ptr, URI("</br>datatype", "%s"), datatype); ptr += strlen(ptr); - sprintf(ptr, URI("</br>lang ", "%s"), lang); + sprintf(ptr, URI("</tab>lang ", "%s"), lang); } else if(atom->type == ui->forge.URI) { - const char *str = LV2_ATOM_CONTENTS_CONST(LV2_Atom_String, atom); + char *str = LV2_ATOM_CONTENTS(LV2_Atom_String, atom); + + // truncate + char tmp[4]; + if(atom->size > STRING_MAX) + { + memcpy(tmp, &str[STRING_OFF], 4); + strcpy(&str[STRING_OFF], "..."); + } sprintf(ptr, HIL("</br>value ", "%s"), str); + + // restore + if(atom->size > STRING_MAX) + memcpy(&str[STRING_OFF], tmp, 4); } else if(atom->type == ui->uris.midi_MidiEvent) { const uint8_t *midi = LV2_ATOM_BODY_CONST(atom); - if(midi[0] == 0xf0) + sprintf(ptr, HIL_PRE("</br>value ")); + ptr += strlen(ptr); + + char *barrier = ptr + STRING_OFF; + for(int i=0; (i<atom->size) && (ptr<barrier); i++, ptr += 3) + sprintf(ptr, "%02X ", midi[i]); + + if(ptr >= barrier) // there would be more to print { - sprintf(ptr, HIL("</br>value ", "%s"), "Sysex"); + ptr = barrier; + sprintf(ptr, "..."); + ptr += 4; } - else - { - sprintf(ptr, HIL_PRE("</br>value ")); - ptr += strlen(ptr); - for(int i=0; (i<atom->size) && (ptr<end); i++, ptr += 3) - sprintf(ptr, "%02X ", midi[i]); + sprintf(ptr, HIL_POST); + } + else if(atom->type == ui->forge.Chunk) + { + const uint8_t *chunk = LV2_ATOM_BODY_CONST(atom); + + sprintf(ptr, HIL_PRE("</br>value ")); + ptr += strlen(ptr); + + char *barrier = ptr + STRING_OFF; + for(int i=0; (i<atom->size) && (ptr<barrier); i++, ptr += 3) + sprintf(ptr, "%02X ", chunk[i]); - sprintf(ptr, HIL_POST); + if(ptr >= barrier) // there would be more to print + { + ptr = barrier; + sprintf(ptr, "..."); + ptr += 4; } + + sprintf(ptr, HIL_POST); } - return ptr; + if( !lv2_atom_forge_is_object_type(&ui->forge, atom->type) + && !(atom->type == ui->forge.Literal) + && !(atom->type == ui->forge.Vector) ) + { + ptr += strlen(ptr); + + sprintf(ptr, "</br>"); + } + + return ptr + strlen(ptr); } static char * @@ -224,9 +354,9 @@ _atom_item_label_get(void *data, Evas_Object *obj, const char *part) if(!strcmp(part, "elm.text")) { - char buf [1024]; + char *buf = ui->string_buf; char *ptr = buf; - char *end = buf + 1024; + char *end = buf + STRING_BUF_SIZE; ptr = _atom_stringify(ui, ptr, end, atom); @@ -249,23 +379,23 @@ _prop_item_label_get(void *data, Evas_Object *obj, const char *part) if(!strcmp(part, "elm.text")) { - char buf [1024]; + char *buf = ui->string_buf; char *ptr = buf; - char *end = buf + 1024; + char *end = buf + STRING_BUF_SIZE; - const char *key = ui->unmap->unmap(ui->unmap->handle, prop->key); - const char *context = ui->unmap->unmap(ui->unmap->handle, prop->context); + const char *key = _hash_get(ui, prop->key); + const char *context = _hash_get(ui, prop->context); sprintf(ptr, URI("key ", "%s"), key); ptr += strlen(ptr); if(context) { - sprintf(ptr, URI("</br>context ", "%s"), context); + sprintf(ptr, URI("</tab>context ", "%s"), context); ptr += strlen(ptr); } - sprintf(ptr, "</br>"); + sprintf(ptr, "</tab>"); ptr += strlen(ptr); ptr = _atom_stringify(ui, ptr, end, &prop->value); @@ -279,7 +409,7 @@ _prop_item_label_get(void *data, Evas_Object *obj, const char *part) } static char * -_sherlock_item_label_get(void *data, Evas_Object *obj, const char *part) +_seq_item_label_get(void *data, Evas_Object *obj, const char *part) { UI *ui = evas_object_data_get(obj, "ui"); const LV2_Atom_Event *ev = data; @@ -290,11 +420,9 @@ _sherlock_item_label_get(void *data, Evas_Object *obj, const char *part) if(!strcmp(part, "elm.text")) { - return _atom_item_label_get((void *)atom, obj, part); - - char buf [1024]; + char *buf = ui->string_buf; char *ptr = buf; - char *end = buf + 1024; + char *end = buf + STRING_BUF_SIZE; ptr = _atom_stringify(ui, ptr, end, atom); @@ -312,19 +440,22 @@ _atom_item_content_get(void *data, Evas_Object *obj, const char *part) { UI *ui = evas_object_data_get(obj, "ui"); const LV2_Atom *atom = data; - char buf [512]; if(!ui) return NULL; if(!strcmp(part, "elm.swallow.end")) { + char *buf = ui->string_buf; + sprintf(buf, "<color=#0bb font=Mono>%4u</color>", atom->size); Evas_Object *label = elm_label_add(obj); - elm_object_part_text_set(label, "default", buf); - //evas_object_size_hint_weight_set(label, 0.5, EVAS_HINT_EXPAND); - evas_object_show(label); + if(label) + { + elm_object_part_text_set(label, "default", buf); + evas_object_show(label); + } return label; } @@ -338,19 +469,22 @@ _prop_item_content_get(void *data, Evas_Object *obj, const char *part) UI *ui = evas_object_data_get(obj, "ui"); const LV2_Atom_Property_Body *prop = data; const LV2_Atom *atom = &prop->value; - char buf [512]; if(!ui) return NULL; if(!strcmp(part, "elm.swallow.end")) { + char *buf = ui->string_buf; + sprintf(buf, "<color=#0bb font=Mono>%4u</color>", atom->size); Evas_Object *label = elm_label_add(obj); - elm_object_part_text_set(label, "default", buf); - //evas_object_size_hint_weight_set(label, 0.5, EVAS_HINT_EXPAND); - evas_object_show(label); + if(label) + { + elm_object_part_text_set(label, "default", buf); + evas_object_show(label); + } return label; } @@ -359,47 +493,42 @@ _prop_item_content_get(void *data, Evas_Object *obj, const char *part) } static Evas_Object * -_sherlock_item_content_get(void *data, Evas_Object *obj, const char *part) +_seq_item_content_get(void *data, Evas_Object *obj, const char *part) { UI *ui = evas_object_data_get(obj, "ui"); const LV2_Atom_Event *ev = data; const LV2_Atom *atom = &ev->body; - char buf [512]; if(!ui) return NULL; if(!strcmp(part, "elm.swallow.icon")) { - Evas_Object *ico = elm_icon_add(obj); - evas_object_size_hint_weight_set(ico, 0.f, 0.f); - evas_object_size_hint_min_set(ico, 0.f, 0.f); - evas_object_size_hint_max_set(ico, 0.f, 0.f); - return ico; + char *buf = ui->string_buf; sprintf(buf, "<color=#bb0 font=Mono>%4ld</color>", ev->time.frames); Evas_Object *label = elm_label_add(obj); - elm_object_part_text_set(label, "default", buf); - //evas_object_size_hint_weight_set(label, 0.5, EVAS_HINT_EXPAND); - evas_object_show(label); + if(label) + { + elm_object_part_text_set(label, "default", buf); + evas_object_show(label); + } return label; } else if(!strcmp(part, "elm.swallow.end")) { - Evas_Object *ico = elm_icon_add(obj); - evas_object_size_hint_weight_set(ico, 0.f, 0.f); - evas_object_size_hint_min_set(ico, 0.f, 0.f); - evas_object_size_hint_max_set(ico, 0.f, 0.f); - return ico; + char *buf = ui->string_buf; sprintf(buf, "<color=#0bb font=Mono>%4u</color>", atom->size); Evas_Object *label = elm_label_add(obj); - elm_object_part_text_set(label, "default", buf); - //evas_object_size_hint_weight_set(label, 0.5, EVAS_HINT_EXPAND); - evas_object_show(label); + if(label) + { + elm_object_part_text_set(label, "default", buf); + evas_object_show(label); + } return label; } @@ -432,10 +561,8 @@ _item_contract_request(void *data, Evas_Object *obj, void *event_info) } static void -_atom_expand(UI *ui, const void *data, Evas_Object *obj, Elm_Object_Item *itm) +_atom_expand(UI *ui, const LV2_Atom *atom, Evas_Object *obj, Elm_Object_Item *itm) { - const LV2_Atom *atom = data; - if(lv2_atom_forge_is_object_type(&ui->forge, atom->type)) { const LV2_Atom_Object *atom_object = (const LV2_Atom_Object *)atom; @@ -445,10 +572,9 @@ _atom_expand(UI *ui, const void *data, Evas_Object *obj, Elm_Object_Item *itm) Elm_Genlist_Item_Type type = _is_expandable(ui, prop->value.type) ? ELM_GENLIST_ITEM_TREE : ELM_GENLIST_ITEM_NONE; - type = ELM_GENLIST_ITEM_TREE; //FIXME - Elm_Object_Item *itm2 = elm_genlist_item_append(ui->list, ui->itc_prop, prop, itm, - type, NULL, NULL); + Elm_Object_Item *itm2 = elm_genlist_item_append(ui->list, ui->itc_prop, + prop, itm, type, NULL, NULL); elm_genlist_item_select_mode_set(itm2, ELM_OBJECT_SELECT_MODE_DEFAULT); elm_genlist_item_expanded_set(itm2, EINA_FALSE); } @@ -456,17 +582,17 @@ _atom_expand(UI *ui, const void *data, Evas_Object *obj, Elm_Object_Item *itm) else if(atom->type == ui->forge.Tuple) { const LV2_Atom_Tuple *atom_tuple = (const LV2_Atom_Tuple *)atom; - const LV2_Atom *elmnt; - LV2_ATOM_TUPLE_FOREACH(atom_tuple, elmnt) + for(LV2_Atom *iter = lv2_atom_tuple_begin(atom_tuple); + !lv2_atom_tuple_is_end(LV2_ATOM_BODY(atom_tuple), atom_tuple->atom.size, iter); + iter = lv2_atom_tuple_next(iter)) { - Elm_Genlist_Item_Type type = _is_expandable(ui, elmnt->type) + Elm_Genlist_Item_Type type = _is_expandable(ui, iter->type) ? ELM_GENLIST_ITEM_TREE : ELM_GENLIST_ITEM_NONE; - type = ELM_GENLIST_ITEM_TREE; //FIXME - Elm_Object_Item *itm2 = elm_genlist_item_append(ui->list, ui->itc_atom, elmnt, itm, - type, NULL, NULL); + Elm_Object_Item *itm2 = elm_genlist_item_append(ui->list, ui->itc_atom, + iter, itm, type, NULL, NULL); elm_genlist_item_select_mode_set(itm2, ELM_OBJECT_SELECT_MODE_DEFAULT); elm_genlist_item_expanded_set(itm2, EINA_FALSE); } @@ -478,7 +604,6 @@ _atom_expand(UI *ui, const void *data, Evas_Object *obj, Elm_Object_Item *itm) Elm_Genlist_Item_Type type = _is_expandable(ui, atom_vector->body.child_type) ? ELM_GENLIST_ITEM_TREE : ELM_GENLIST_ITEM_NONE; - type = ELM_GENLIST_ITEM_TREE; //FIXME int num = (atom_vector->atom.size - sizeof(LV2_Atom_Vector_Body)) / atom_vector->body.child_size; @@ -486,33 +611,37 @@ _atom_expand(UI *ui, const void *data, Evas_Object *obj, Elm_Object_Item *itm) for(int i=0; i<num; i++) { LV2_Atom *atom = malloc(sizeof(LV2_Atom) + atom_vector->body.child_size); - atom->size = atom_vector->body.child_size; - atom->type = atom_vector->body.child_type; - memcpy(LV2_ATOM_BODY(atom), body + i*atom->size, atom->size); - - Elm_Genlist_Item *itm2 = elm_genlist_item_append(ui->list, ui->itc_vec, atom, itm, type, NULL, NULL); - elm_genlist_item_select_mode_set(itm2, ELM_OBJECT_SELECT_MODE_DEFAULT); - elm_genlist_item_expanded_set(itm2, EINA_FALSE); + if(atom) + { + atom->size = atom_vector->body.child_size; + atom->type = atom_vector->body.child_type; + memcpy(LV2_ATOM_BODY(atom), body + i*atom->size, atom->size); + + Elm_Genlist_Item *itm2 = elm_genlist_item_append(ui->list, ui->itc_vec, + atom, itm, type, NULL, NULL); + elm_genlist_item_select_mode_set(itm2, ELM_OBJECT_SELECT_MODE_DEFAULT); + elm_genlist_item_expanded_set(itm2, EINA_FALSE); + } } } -} - -static void -_prop_expand(UI *ui, const void *data, Evas_Object *obj, Elm_Object_Item *itm) -{ - const LV2_Atom_Property_Body *prop = data; - const LV2_Atom *atom = &prop->value; + else if(atom->type == ui->forge.Sequence) + { + const LV2_Atom_Sequence *atom_seq = (const LV2_Atom_Sequence *)atom; - _atom_expand(ui, atom, obj, itm); -} + LV2_ATOM_SEQUENCE_FOREACH(atom_seq, ev) + { + const LV2_Atom *atom = &ev->body; -static void -_sherlock_expand(UI *ui, const void *data, Evas_Object *obj, Elm_Object_Item *itm) -{ - const LV2_Atom_Event *ev = data; - const LV2_Atom *atom = &ev->body; + Elm_Genlist_Item_Type type = _is_expandable(ui, atom->type) + ? ELM_GENLIST_ITEM_TREE + : ELM_GENLIST_ITEM_NONE; - _atom_expand(ui, atom, obj, itm); + Elm_Object_Item *itm2 = elm_genlist_item_append(ui->list, ui->itc_seq, + ev, itm, type, NULL, NULL); + elm_genlist_item_select_mode_set(itm2, ELM_OBJECT_SELECT_MODE_DEFAULT); + elm_genlist_item_expanded_set(itm2, EINA_FALSE); + } + } } static void @@ -524,16 +653,26 @@ _item_expanded(void *data, Evas_Object *obj, void *event_info) const Elm_Genlist_Item_Class *class = elm_genlist_item_item_class_get(itm); const void *udata = elm_object_item_data_get(itm); - if(udata) + if(!udata) + return; + + if( (class == ui->itc_sherlock) || (class == ui->itc_seq) ) { - if(class == ui->itc_sherlock) - _sherlock_expand(ui, udata, obj, itm); - else if(class == ui->itc_prop) - _prop_expand(ui, udata, obj, itm); - else if(class == ui->itc_vec) - _atom_expand(ui, udata, obj, itm); - else if(class == ui->itc_atom) - _atom_expand(ui, udata, obj, itm); + const LV2_Atom_Event *ev = udata; + const LV2_Atom *atom = &ev->body; + _atom_expand(ui, atom, obj, itm); + } + else if(class == ui->itc_prop) + { + const LV2_Atom_Property_Body *prop = udata; + const LV2_Atom *atom = &prop->value; + + _atom_expand(ui, atom, obj, itm); + } + else + { + const LV2_Atom *atom = udata; + _atom_expand(ui, atom, obj, itm); } } @@ -547,11 +686,23 @@ _item_contracted(void *data, Evas_Object *obj, void *event_info) } static void +_clear_update(UI *ui, int count) +{ + if(!ui->clear) + return; + + char *buf = ui->string_buf; + sprintf(buf, "Clear (%i of %i)", count, COUNT_MAX); + elm_object_text_set(ui->clear, buf); +} + +static void _clear_clicked(void *data, Evas_Object *obj, void *event_info) { UI *ui = data; elm_genlist_clear(ui->list); + _clear_update(ui, 0); } static Evas_Object * @@ -560,33 +711,42 @@ _content_get(eo_ui_t *eoui) UI *ui = (void *)eoui - offsetof(UI, eoui); ui->vbox = elm_box_add(eoui->win); - elm_box_horizontal_set(ui->vbox, EINA_FALSE); - elm_box_homogeneous_set(ui->vbox, EINA_FALSE); - elm_box_padding_set(ui->vbox, 0, 10); - - ui->list = elm_genlist_add(ui->vbox); - elm_genlist_select_mode_set(ui->list, ELM_OBJECT_SELECT_MODE_DEFAULT); - //elm_genlist_homogeneous_set(ui->list, EINA_TRUE); // TRUE for lazy-loading - elm_genlist_homogeneous_set(ui->list, EINA_FALSE); // XXX - elm_genlist_mode_set(ui->list, ELM_LIST_SCROLL); - evas_object_data_set(ui->list, "ui", ui); - evas_object_smart_callback_add(ui->list, "expand,request", - _item_expand_request, ui); - evas_object_smart_callback_add(ui->list, "contract,request", - _item_contract_request, ui); - evas_object_smart_callback_add(ui->list, "expanded", _item_expanded, ui); - evas_object_smart_callback_add(ui->list, "contracted", _item_contracted, ui); - evas_object_size_hint_weight_set(ui->list, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - evas_object_size_hint_align_set(ui->list, EVAS_HINT_FILL, EVAS_HINT_FILL); - evas_object_show(ui->list); - elm_box_pack_end(ui->vbox, ui->list); - - ui->clear = elm_button_add(ui->vbox); - elm_object_part_text_set(ui->clear, "default", "Clear"); - evas_object_smart_callback_add(ui->clear, "clicked", _clear_clicked, ui); - evas_object_size_hint_align_set(ui->clear, EVAS_HINT_FILL, EVAS_HINT_FILL); - evas_object_show(ui->clear); - elm_box_pack_end(ui->vbox, ui->clear); + if(ui->vbox) + { + elm_box_horizontal_set(ui->vbox, EINA_FALSE); + elm_box_homogeneous_set(ui->vbox, EINA_FALSE); + elm_box_padding_set(ui->vbox, 0, 10); + + ui->list = elm_genlist_add(ui->vbox); + if(ui->list) + { + elm_genlist_select_mode_set(ui->list, ELM_OBJECT_SELECT_MODE_DEFAULT); + //elm_genlist_homogeneous_set(ui->list, EINA_TRUE); // TRUE for lazy-loading + elm_genlist_homogeneous_set(ui->list, EINA_FALSE); // XXX + elm_genlist_mode_set(ui->list, ELM_LIST_SCROLL); + evas_object_data_set(ui->list, "ui", ui); + evas_object_smart_callback_add(ui->list, "expand,request", + _item_expand_request, ui); + evas_object_smart_callback_add(ui->list, "contract,request", + _item_contract_request, ui); + evas_object_smart_callback_add(ui->list, "expanded", _item_expanded, ui); + evas_object_smart_callback_add(ui->list, "contracted", _item_contracted, ui); + evas_object_size_hint_weight_set(ui->list, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(ui->list, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_show(ui->list); + elm_box_pack_end(ui->vbox, ui->list); + } + + ui->clear = elm_button_add(ui->vbox); + if(ui->clear) + { + _clear_update(ui, 0); + evas_object_smart_callback_add(ui->clear, "clicked", _clear_clicked, ui); + evas_object_size_hint_align_set(ui->clear, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_show(ui->clear); + elm_box_pack_end(ui->vbox, ui->clear); + } + } return ui->vbox; } @@ -619,8 +779,8 @@ instantiate(const LV2UI_Descriptor *descriptor, const char *plugin_uri, eo_ui_t *eoui = &ui->eoui; eoui->driver = driver; eoui->content_get = _content_get; - eoui->w = 500, - eoui->h = 500; + eoui->w = 1024, + eoui->h = 480; ui->write_function = write_function; ui->controller = controller; @@ -640,38 +800,57 @@ instantiate(const LV2UI_Descriptor *descriptor, const char *plugin_uri, return NULL; } - ui->uris.midi_MidiEvent = ui->map->map(ui->map->handle, LV2_MIDI__MidiEvent); - ui->uris.event_transfer = ui->map->map(ui->map->handle, LV2_ATOM__eventTransfer); - lv2_atom_forge_init(&ui->forge, ui->map); ui->itc_sherlock = elm_genlist_item_class_new(); - ui->itc_sherlock->item_style = "default_style"; - ui->itc_sherlock->func.text_get = _sherlock_item_label_get; - ui->itc_sherlock->func.content_get = _sherlock_item_content_get; - ui->itc_sherlock->func.state_get = NULL; - ui->itc_sherlock->func.del = _item_del; - + if(ui->itc_sherlock) + { + ui->itc_sherlock->item_style = "default_style"; + ui->itc_sherlock->func.text_get = _seq_item_label_get; + ui->itc_sherlock->func.content_get = _seq_item_content_get; + ui->itc_sherlock->func.state_get = NULL; + ui->itc_sherlock->func.del = _item_del; + } + + ui->itc_seq = elm_genlist_item_class_new(); + if(ui->itc_seq) + { + ui->itc_seq->item_style = "default_style"; + ui->itc_seq->func.text_get = _seq_item_label_get; + ui->itc_seq->func.content_get = _seq_item_content_get; + ui->itc_seq->func.state_get = NULL; + ui->itc_seq->func.del = NULL; + } + ui->itc_prop = elm_genlist_item_class_new(); - ui->itc_prop->item_style = "default_style"; - ui->itc_prop->func.text_get = _prop_item_label_get; - ui->itc_prop->func.content_get = _prop_item_content_get; - ui->itc_prop->func.state_get = NULL; - ui->itc_prop->func.del = NULL; + if(ui->itc_prop) + { + ui->itc_prop->item_style = "default_style"; + ui->itc_prop->func.text_get = _prop_item_label_get; + ui->itc_prop->func.content_get = _prop_item_content_get; + ui->itc_prop->func.state_get = NULL; + ui->itc_prop->func.del = NULL; + } ui->itc_vec = elm_genlist_item_class_new(); - ui->itc_vec->item_style = "default_style"; - ui->itc_vec->func.text_get = _atom_item_label_get; - ui->itc_vec->func.content_get = _atom_item_content_get; - ui->itc_vec->func.state_get = NULL; - ui->itc_vec->func.del = _item_del; + if(ui->itc_vec) + { + ui->itc_vec->item_style = "default_style"; + ui->itc_vec->func.text_get = _atom_item_label_get; + ui->itc_vec->func.content_get = _atom_item_content_get; + ui->itc_vec->func.state_get = NULL; + ui->itc_vec->func.del = _item_del; + } ui->itc_atom = elm_genlist_item_class_new(); - ui->itc_atom->item_style = "default_style"; - ui->itc_atom->func.text_get = _atom_item_label_get; - ui->itc_atom->func.content_get = _atom_item_content_get; - ui->itc_atom->func.state_get = NULL; - ui->itc_atom->func.del = NULL; + if(ui->itc_atom) + { + ui->itc_atom->item_style = "default_style"; + ui->itc_atom->func.text_get = _atom_item_label_get; + ui->itc_atom->func.content_get = _atom_item_content_get; + ui->itc_atom->func.state_get = NULL; + ui->itc_atom->func.del = NULL; + } if(eoui_instantiate(eoui, descriptor, plugin_uri, bundle_path, write_function, controller, widget, features)) @@ -679,6 +858,56 @@ instantiate(const LV2UI_Descriptor *descriptor, const char *plugin_uri, free(ui); return NULL; } + + ui->uris.midi_MidiEvent = ui->map->map(ui->map->handle, LV2_MIDI__MidiEvent); + + ui->uris.event_transfer = ui->map->map(ui->map->handle, LV2_ATOM__eventTransfer); + + ui->uris.time_position = ui->map->map(ui->map->handle, LV2_TIME__Position); + ui->uris.time_barBeat = ui->map->map(ui->map->handle, LV2_TIME__barBeat); + ui->uris.time_bar = ui->map->map(ui->map->handle, LV2_TIME__bar); + ui->uris.time_beat = ui->map->map(ui->map->handle, LV2_TIME__beat); + ui->uris.time_beatUnit = ui->map->map(ui->map->handle, LV2_TIME__beatUnit); + ui->uris.time_beatsPerBar = ui->map->map(ui->map->handle, LV2_TIME__beatsPerBar); + ui->uris.time_beatsPerMinute = ui->map->map(ui->map->handle, LV2_TIME__beatsPerMinute); + ui->uris.time_frame = ui->map->map(ui->map->handle, LV2_TIME__frame); + ui->uris.time_framesPerSecond = ui->map->map(ui->map->handle, LV2_TIME__framesPerSecond); + ui->uris.time_speed = ui->map->map(ui->map->handle, LV2_TIME__speed); + + ui->urids = eina_hash_int32_new(_hash_del); + + // prepopulate hash table + _hash_set(ui, ui->forge.Blank); + _hash_set(ui, ui->forge.Bool); + _hash_set(ui, ui->forge.Chunk); + _hash_set(ui, ui->forge.Double); + _hash_set(ui, ui->forge.Float); + _hash_set(ui, ui->forge.Int); + _hash_set(ui, ui->forge.Long); + _hash_set(ui, ui->forge.Literal); + _hash_set(ui, ui->forge.Object); + _hash_set(ui, ui->forge.Path); + _hash_set(ui, ui->forge.Property); + _hash_set(ui, ui->forge.Resource); + _hash_set(ui, ui->forge.Sequence); + _hash_set(ui, ui->forge.String); + _hash_set(ui, ui->forge.Tuple); + _hash_set(ui, ui->forge.URI); + _hash_set(ui, ui->forge.URID); + _hash_set(ui, ui->forge.Vector); + + _hash_set(ui, ui->uris.midi_MidiEvent); + + _hash_set(ui, ui->uris.time_position); + _hash_set(ui, ui->uris.time_barBeat); + _hash_set(ui, ui->uris.time_bar); + _hash_set(ui, ui->uris.time_beat); + _hash_set(ui, ui->uris.time_beatUnit); + _hash_set(ui, ui->uris.time_beatsPerBar); + _hash_set(ui, ui->uris.time_beatsPerMinute); + _hash_set(ui, ui->uris.time_frame); + _hash_set(ui, ui->uris.time_framesPerSecond); + _hash_set(ui, ui->uris.time_speed); return ui; } @@ -690,10 +919,18 @@ cleanup(LV2UI_Handle handle) eoui_cleanup(&ui->eoui); - elm_genlist_item_class_free(ui->itc_atom); - elm_genlist_item_class_free(ui->itc_vec); - elm_genlist_item_class_free(ui->itc_prop); - elm_genlist_item_class_free(ui->itc_sherlock); + eina_hash_free(ui->urids); + + if(ui->itc_atom) + elm_genlist_item_class_free(ui->itc_atom); + if(ui->itc_vec) + elm_genlist_item_class_free(ui->itc_vec); + if(ui->itc_prop) + elm_genlist_item_class_free(ui->itc_prop); + if(ui->itc_seq) + elm_genlist_item_class_free(ui->itc_seq); + if(ui->itc_sherlock) + elm_genlist_item_class_free(ui->itc_sherlock); free(ui); } @@ -703,35 +940,41 @@ port_event(LV2UI_Handle handle, uint32_t i, uint32_t size, uint32_t urid, const void *buf) { UI *ui = handle; - - if( (i == 2) && (urid == ui->uris.event_transfer) ) + + if( (i == 2) && (urid == ui->uris.event_transfer) && ui->list) { const LV2_Atom_Sequence *seq = buf; + int n = elm_genlist_items_count(ui->list); LV2_ATOM_SEQUENCE_FOREACH(seq, elmnt) { size_t len = sizeof(LV2_Atom_Event) + elmnt->body.size; LV2_Atom_Event *ev = malloc(len); + if(!ev) + continue; + memcpy(ev, elmnt, len); // check item count - if(elm_genlist_items_count(ui->list) >= COUNT_MAX) + if(n++ >= COUNT_MAX) break; const LV2_Atom *atom = &elmnt->body; Elm_Genlist_Item_Type type = _is_expandable(ui, atom->type) ? ELM_GENLIST_ITEM_TREE : ELM_GENLIST_ITEM_NONE; - type = ELM_GENLIST_ITEM_TREE; //FIXME - Elm_Genlist_Item *itm2 = elm_genlist_item_append(ui->list, ui->itc_sherlock, ev, NULL, - type, NULL, NULL); + Elm_Genlist_Item *itm2 = elm_genlist_item_append(ui->list, ui->itc_sherlock, + ev, NULL, type, NULL, NULL); elm_genlist_item_select_mode_set(itm2, ELM_OBJECT_SELECT_MODE_DEFAULT); elm_genlist_item_expanded_set(itm2, EINA_FALSE); // scroll to last item //elm_genlist_item_show(itm, ELM_GENLIST_ITEM_SCROLLTO_MIDDLE); } + + if(seq->atom.size > sizeof(LV2_Atom_Sequence_Body)) + _clear_update(ui, n); // only update if there where any events } } @@ -23,6 +23,7 @@ #include "lv2/lv2plug.in/ns/ext/atom/atom.h" #include "lv2/lv2plug.in/ns/ext/atom/forge.h" #include "lv2/lv2plug.in/ns/ext/midi/midi.h" +#include "lv2/lv2plug.in/ns/ext/time/time.h" #include "lv2/lv2plug.in/ns/ext/urid/urid.h" #include "lv2/lv2plug.in/ns/extensions/ui/ui.h" #include "lv2/lv2plug.in/ns/lv2core/lv2.h" |