aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--atom_inspector_ui.c615
-rw-r--r--sherlock.h1
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
}
}
diff --git a/sherlock.h b/sherlock.h
index 3f36a06..8354b40 100644
--- a/sherlock.h
+++ b/sherlock.h
@@ -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"