aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--VERSION2
-rw-r--r--atom_inspector.c3
-rw-r--r--atom_inspector_nk.c190
-rw-r--r--midi_inspector.c3
-rw-r--r--midi_inspector_nk.c485
-rw-r--r--osc_inspector.c3
-rw-r--r--osc_inspector_nk.c164
-rw-r--r--sherlock.h8
-rw-r--r--sherlock.ttl25
-rw-r--r--sherlock_nk.c158
-rw-r--r--sherlock_nk.h47
11 files changed, 608 insertions, 480 deletions
diff --git a/VERSION b/VERSION
index b1e2591..2685240 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.11.2665
+0.11.2727
diff --git a/atom_inspector.c b/atom_inspector.c
index 86d948f..9e71b43 100644
--- a/atom_inspector.c
+++ b/atom_inspector.c
@@ -71,8 +71,7 @@ instantiate(const LV2_Descriptor* descriptor, double rate,
return NULL;
}
- if( !props_register(&handle->props, &stat_count, &handle->state.count, &handle->stash.count)
- || !props_register(&handle->props, &stat_overwrite, &handle->state.overwrite, &handle->stash.overwrite)
+ if( !props_register(&handle->props, &stat_overwrite, &handle->state.overwrite, &handle->stash.overwrite)
|| !props_register(&handle->props, &stat_block, &handle->state.block, &handle->stash.block)
|| !props_register(&handle->props, &stat_follow, &handle->state.follow, &handle->stash.follow) )
{
diff --git a/atom_inspector_nk.c b/atom_inspector_nk.c
index f66d999..29e80d5 100644
--- a/atom_inspector_nk.c
+++ b/atom_inspector_nk.c
@@ -97,124 +97,117 @@ _atom_inspector_expose(struct nk_context *ctx, struct nk_rect wbounds, void *dat
struct nk_style *style = &ctx->style;
const struct nk_vec2 window_padding = style->window.padding;
const struct nk_vec2 group_padding = style->window.group_padding;
- bool ttl_dirty = false;
+
+ style->selectable.normal.data.color.a = 0x0;
+ style->selectable.hover.data.color.a = 0x0;
if(nk_begin(ctx, "Window", wbounds, NK_WINDOW_NO_SCROLLBAR))
{
nk_window_set_bounds(ctx, wbounds);
struct nk_panel *panel= nk_window_get_panel(ctx);
+ struct nk_command_buffer *canvas = nk_window_get_canvas(ctx);
const float body_h = panel->bounds.h - 2*window_padding.y;
nk_layout_row_dynamic(ctx, body_h, 2);
if(nk_group_begin(ctx, "Left", NK_WINDOW_NO_SCROLLBAR))
{
- nk_layout_row_dynamic(ctx, widget_h, 3);
- {
- if(nk_checkbox_label(ctx, "overwrite", &handle->state.overwrite))
- _toggle(handle, handle->urid.overwrite, handle->state.overwrite, true);
- if(nk_checkbox_label(ctx, "block", &handle->state.block))
- _toggle(handle, handle->urid.block, handle->state.block, true);
- if(nk_checkbox_label(ctx, "follow", &handle->state.follow))
- _toggle(handle, handle->urid.follow, handle->state.follow, true);
- }
-
- nk_layout_row_dynamic(ctx, widget_h, 2);
- {
- if(nk_button_label(ctx, "clear"))
- _clear(handle);
-
- int selected = 0;
- for(int i = 0; i < 5; i++)
- {
- if(handle->state.count == max_values[i])
- {
- selected = i;
- break;
- }
- }
-
- selected = nk_combo(ctx, max_items, 5, selected, widget_h,
- nk_vec2(wbounds.w/3, widget_h*5));
- if(handle->state.count != max_values[selected])
- {
- handle->state.count = max_values[selected];
- _toggle(handle, handle->urid.count, handle->state.count, false);
- }
- }
-
const float content_h = nk_window_get_height(ctx) - 2*window_padding.y - 4*group_padding.y - 2*widget_h;
nk_layout_row_dynamic(ctx, content_h, 1);
- if(nk_group_begin(ctx, "Events", NK_WINDOW_BORDER))
+ nk_flags flags = NK_WINDOW_BORDER;
+ if(handle->state.follow)
+ flags |= NK_WINDOW_NO_SCROLLBAR;
+ struct nk_list_view lview;
+ if(nk_list_view_begin(ctx, &lview, "Events", flags, widget_h, NK_MIN(handle->n_item, MAX_LINES)))
{
- uint32_t counter = 0;
- const LV2_Atom *selected = NULL;
-
- LV2_ATOM_TUPLE_FOREACH((const LV2_Atom_Tuple *)handle->ser.atom, atom)
+ if(handle->state.follow)
{
- const LV2_Atom_Tuple *tup = (const LV2_Atom_Tuple *)atom;
- const LV2_Atom_Long *offset = (const LV2_Atom_Long *)lv2_atom_tuple_begin(tup);
- const LV2_Atom_Int *nsamples = (const LV2_Atom_Int *)lv2_atom_tuple_next(&offset->atom);
- const LV2_Atom_Sequence *seq = (const LV2_Atom_Sequence *)lv2_atom_tuple_next(&nsamples->atom);
-
- nk_layout_row_dynamic(ctx, 2.f, 1);
- _ruler(ctx, 2.f, gray);
-
- nk_layout_row_dynamic(ctx, widget_h, 3);
- nk_labelf_colored(ctx, NK_TEXT_LEFT, orange, "@%"PRIi64, offset->body);
- nk_labelf_colored(ctx, NK_TEXT_CENTERED, green, "-%"PRIu32"-", counter);
- nk_labelf_colored(ctx, NK_TEXT_RIGHT, violet, "%"PRIi32, nsamples->body);
-
- nk_layout_row_dynamic(ctx, 2.f, 1);
- _ruler(ctx, 1.f, gray);
+ lview.end = NK_MAX(handle->n_item, 0);
+ lview.begin = NK_MAX(lview.end - lview.count, 0);
+ }
+ for(int l = lview.begin; (l < lview.end) && (l < handle->n_item); l++)
+ {
+ item_t *itm = handle->items[l];
- const LV2_Atom *last = NULL;
- LV2_ATOM_SEQUENCE_FOREACH(seq, ev)
+ switch(itm->type)
{
- const LV2_Atom *body = &ev->body;
- const int64_t frames = ev->time.frames;
- const char *uri = handle->unmap->unmap(handle->unmap->handle, body->type);
-
- nk_layout_row_begin(ctx, NK_DYNAMIC, widget_h, 3);
+ case ITEM_TYPE_NONE:
{
- nk_layout_row_push(ctx, 0.1);
- nk_labelf_colored(ctx, NK_TEXT_LEFT, yellow, "+%04"PRIi64, frames);
-
- nk_layout_row_push(ctx, 0.8);
- if(nk_select_label(ctx, uri, NK_TEXT_LEFT, handle->selected == body))
+ // skip, never reached
+ } break;
+ case ITEM_TYPE_FRAME:
+ {
+ nk_layout_row_dynamic(ctx, widget_h, 3);
{
- ttl_dirty = handle->selected != body; // has selection actually changed?
- handle->selected = body;
+ struct nk_rect b = nk_widget_bounds(ctx);
+ b.x -= group_padding.x;
+ b.w *= 3;
+ b.w += 4*group_padding.x;
+ nk_fill_rect(canvas, b, 0.f, nk_rgb(0x18, 0x18, 0x18));
}
- nk_layout_row_push(ctx, 0.1);
- nk_labelf_colored(ctx, NK_TEXT_RIGHT, blue, "%"PRIu32, body->size);
- }
- nk_layout_row_end(ctx);
+ nk_labelf_colored(ctx, NK_TEXT_LEFT, orange, "@%"PRIi64, itm->frame.offset);
+ nk_labelf_colored(ctx, NK_TEXT_CENTERED, green, "-%"PRIu32"-", itm->frame.counter);
+ nk_labelf_colored(ctx, NK_TEXT_RIGHT, violet, "%"PRIi32, itm->frame.nsamples);
+ } break;
- last = body;
- counter += 1;
- }
+ case ITEM_TYPE_EVENT:
+ {
+ LV2_Atom_Event *ev = &itm->event.ev;
+ const LV2_Atom *body = &ev->body;
+ const int64_t frames = ev->time.frames;
+ const char *uri = handle->unmap->unmap(handle->unmap->handle, body->type);
- if(handle->bottom)
- {
- ttl_dirty = true;
- handle->selected = last;
+ nk_layout_row_begin(ctx, NK_DYNAMIC, widget_h, 3);
+ {
+ nk_layout_row_push(ctx, 0.1);
+ if(l % 2 == 0)
+ {
+ struct nk_rect b = nk_widget_bounds(ctx);
+ b.x -= group_padding.x;
+ b.w *= 10;
+ b.w += 8*group_padding.x;
+ nk_fill_rect(canvas, b, 0.f, nk_rgb(0x28, 0x28, 0x28));
+ }
+ nk_labelf_colored(ctx, NK_TEXT_LEFT, yellow, "+%04"PRIi64, frames);
+
+ nk_layout_row_push(ctx, 0.8);
+ if(nk_select_label(ctx, uri, NK_TEXT_LEFT, handle->selected == body))
+ {
+ handle->ttl_dirty = handle->ttl_dirty
+ || (handle->selected != body); // has selection actually changed?
+ handle->selected = body;
+ }
+
+ nk_layout_row_push(ctx, 0.1);
+ nk_labelf_colored(ctx, NK_TEXT_RIGHT, blue, "%"PRIu32, body->size);
+ }
+ nk_layout_row_end(ctx);
+ } break;
}
}
- handle->count = counter;
-
- if(handle->bottom)
- {
- panel= nk_window_get_panel(ctx);
- panel->offset->y = panel->at_y;
- handle->bottom = false;
+ nk_list_view_end(&lview);
+ }
- _post_redisplay(handle);
- }
+ nk_layout_row_dynamic(ctx, widget_h, 3);
+ {
+ if(nk_checkbox_label(ctx, "overwrite", &handle->state.overwrite))
+ _toggle(handle, handle->urid.overwrite, handle->state.overwrite, true);
+ if(nk_checkbox_label(ctx, "block", &handle->state.block))
+ _toggle(handle, handle->urid.block, handle->state.block, true);
+ if(nk_checkbox_label(ctx, "follow", &handle->state.follow))
+ _toggle(handle, handle->urid.follow, handle->state.follow, true);
+ }
- nk_group_end(ctx);
+ const bool max_reached = handle->n_item >= MAX_LINES;
+ nk_layout_row_dynamic(ctx, widget_h, 2);
+ if(nk_button_symbol_label(ctx,
+ max_reached ? NK_SYMBOL_TRIANGLE_RIGHT: NK_SYMBOL_NONE,
+ "clear", NK_TEXT_LEFT))
+ {
+ _clear(handle);
}
+ nk_label(ctx, "Sherlock.lv2: "SHERLOCK_VERSION, NK_TEXT_RIGHT);
nk_group_end(ctx);
}
@@ -222,7 +215,7 @@ _atom_inspector_expose(struct nk_context *ctx, struct nk_rect wbounds, void *dat
if(nk_group_begin(ctx, "Right", NK_WINDOW_NO_SCROLLBAR))
{
const LV2_Atom *atom = handle->selected;
- if(ttl_dirty && atom)
+ if(handle->ttl_dirty && atom)
{
char *ttl = _sratom_to_turtle(handle->sratom, handle->unmap,
handle->base_uri, NULL, NULL,
@@ -246,17 +239,22 @@ _atom_inspector_expose(struct nk_context *ctx, struct nk_rect wbounds, void *dat
free(ttl);
}
+
+ handle->ttl_dirty = false;
}
const nk_flags flags = NK_EDIT_EDITOR;
char *str = nk_str_get(&handle->str);
int len = nk_str_len(&handle->str);
- const float content_h = nk_window_get_height(ctx) - 2*window_padding.y - 2*group_padding.y;
- nk_layout_row_dynamic(ctx, content_h, 1);
- nk_edit_focus(ctx, flags);
- const nk_flags mode = nk_edit_string(ctx, flags, str, &len, len, nk_filter_default);
- (void)mode;
+ if(len > 0) //FIXME
+ {
+ const float content_h = nk_window_get_height(ctx) - 2*window_padding.y - 2*group_padding.y;
+ nk_layout_row_dynamic(ctx, content_h, 1);
+ nk_edit_focus(ctx, flags);
+ const nk_flags mode = nk_edit_string(ctx, flags, str, &len, len, nk_filter_default);
+ (void)mode;
+ }
nk_group_end(ctx);
}
diff --git a/midi_inspector.c b/midi_inspector.c
index 8b8573c..29c50a0 100644
--- a/midi_inspector.c
+++ b/midi_inspector.c
@@ -76,8 +76,7 @@ instantiate(const LV2_Descriptor* descriptor, double rate,
return NULL;
}
- if( !props_register(&handle->props, &stat_count, &handle->state.count, &handle->stash.count)
- || !props_register(&handle->props, &stat_overwrite, &handle->state.overwrite, &handle->stash.overwrite)
+ if( !props_register(&handle->props, &stat_overwrite, &handle->state.overwrite, &handle->stash.overwrite)
|| !props_register(&handle->props, &stat_block, &handle->state.block, &handle->stash.block)
|| !props_register(&handle->props, &stat_follow, &handle->state.follow, &handle->stash.follow) )
{
diff --git a/midi_inspector_nk.c b/midi_inspector_nk.c
index 92a4c69..2ac4d4f 100644
--- a/midi_inspector_nk.c
+++ b/midi_inspector_nk.c
@@ -196,6 +196,25 @@ _note(uint8_t val, int8_t *octave)
return keys[val % 12];
}
+static inline void
+_shadow(struct nk_context *ctx, bool *shadow)
+{
+ if(*shadow)
+ {
+ struct nk_style *style = &ctx->style;
+ const struct nk_vec2 group_padding = style->window.group_padding;
+ struct nk_command_buffer *canvas = nk_window_get_canvas(ctx);
+
+ struct nk_rect b = nk_widget_bounds(ctx);
+ b.x -= group_padding.x;
+ b.w *= 10;
+ b.w += 8*group_padding.x;
+ nk_fill_rect(canvas, b, 0.f, nk_rgb(0x28, 0x28, 0x28));
+ }
+
+ *shadow = !*shadow;
+}
+
void
_midi_inspector_expose(struct nk_context *ctx, struct nk_rect wbounds, void *data)
{
@@ -204,287 +223,283 @@ _midi_inspector_expose(struct nk_context *ctx, struct nk_rect wbounds, void *dat
const float widget_h = handle->dy;
struct nk_style *style = &ctx->style;
const struct nk_vec2 window_padding = style->window.padding;
+ const struct nk_vec2 group_padding = style->window.group_padding;
if(nk_begin(ctx, "Window", wbounds, NK_WINDOW_NO_SCROLLBAR))
{
nk_window_set_bounds(ctx, wbounds);
- struct nk_panel *panel= nk_window_get_panel(ctx);
-
- nk_layout_row_dynamic(ctx, widget_h, 3);
- {
- if(nk_checkbox_label(ctx, "overwrite", &handle->state.overwrite))
- _toggle(handle, handle->urid.overwrite, handle->state.overwrite, true);
- if(nk_checkbox_label(ctx, "block", &handle->state.block))
- _toggle(handle, handle->urid.block, handle->state.block, true);
- if(nk_checkbox_label(ctx, "follow", &handle->state.follow))
- _toggle(handle, handle->urid.follow, handle->state.follow, true);
- }
-
- nk_layout_row_dynamic(ctx, widget_h, 2);
- {
- if(nk_button_label(ctx, "clear"))
- _clear(handle);
-
- int selected = 0;
- for(int i = 0; i < 5; i++)
- {
- if(handle->state.count == max_values[i])
- {
- selected = i;
- break;
- }
- }
-
- selected = nk_combo(ctx, max_items, 5, selected, widget_h,
- nk_vec2(wbounds.w/3, widget_h*5));
- if(handle->state.count != max_values[selected])
- {
- handle->state.count = max_values[selected];
- _toggle(handle, handle->urid.count, handle->state.count, false);
- }
- }
+ struct nk_panel *panel = nk_window_get_panel(ctx);
+ struct nk_command_buffer *canvas = nk_window_get_canvas(ctx);
const float body_h = panel->bounds.h - 4*window_padding.y - 2*widget_h;
nk_layout_row_dynamic(ctx, body_h, 1);
- if(nk_group_begin(ctx, "Events", NK_WINDOW_BORDER))
+ nk_flags flags = NK_WINDOW_BORDER;
+ if(handle->state.follow)
+ flags |= NK_WINDOW_NO_SCROLLBAR;
+ struct nk_list_view lview;
+ if(nk_list_view_begin(ctx, &lview, "Events", flags, widget_h, NK_MIN(handle->n_item, MAX_LINES)))
{
- uint32_t counter = 0;
-
- LV2_ATOM_TUPLE_FOREACH((const LV2_Atom_Tuple *)handle->ser.atom, atom)
+ if(handle->state.follow)
{
- const LV2_Atom_Tuple *tup = (const LV2_Atom_Tuple *)atom;
- const LV2_Atom_Long *offset = (const LV2_Atom_Long *)lv2_atom_tuple_begin(tup);
- const LV2_Atom_Int *nsamples = (const LV2_Atom_Int *)lv2_atom_tuple_next(&offset->atom);
- const LV2_Atom_Sequence *seq = (const LV2_Atom_Sequence *)lv2_atom_tuple_next(&nsamples->atom);
-
- nk_layout_row_dynamic(ctx, 2.f, 1);
- _ruler(ctx, 2.f, gray);
-
- nk_layout_row_dynamic(ctx, widget_h, 3);
- nk_labelf_colored(ctx, NK_TEXT_LEFT, orange, "@%"PRIi64, offset->body);
- nk_labelf_colored(ctx, NK_TEXT_CENTERED, green, "-%"PRIu32"-", counter);
- nk_labelf_colored(ctx, NK_TEXT_RIGHT, violet, "%"PRIi32, nsamples->body);
-
- nk_layout_row_dynamic(ctx, 2.f, 1);
- _ruler(ctx, 1.f, gray);
+ lview.end = NK_MAX(handle->n_item, 0);
+ lview.begin = NK_MAX(lview.end - lview.count, 0);
+ }
+ handle->shadow = lview.begin % 2 == 0;
+ for(int l = lview.begin; (l < lview.end) && (l < handle->n_item); l++)
+ {
+ item_t *itm = handle->items[l];
- LV2_ATOM_SEQUENCE_FOREACH(seq, ev)
+ switch(itm->type)
{
- const LV2_Atom *body = &ev->body;
- const int64_t frames = ev->time.frames;
- const uint8_t *msg = LV2_ATOM_BODY_CONST(body);
- const uint8_t cmd = (msg[0] & 0xf0) == 0xf0
- ? msg[0]
- : msg[0] & 0xf0;
-
- const midi_msg_t *command_msg = _search_command(cmd);
- const char *command_str = command_msg
- ? command_msg->key
- : "Unknown";
-
- char tmp [16];
- nk_layout_row_begin(ctx, NK_DYNAMIC, widget_h, 7);
+ case ITEM_TYPE_NONE:
{
- nk_layout_row_push(ctx, 0.1);
- nk_labelf_colored(ctx, NK_TEXT_LEFT, yellow, "+%04"PRIi64, frames);
-
- nk_layout_row_push(ctx, 0.2);
- const unsigned rem = body->size;
- const unsigned to = rem >= 4 ? 4 : rem % 4;
- for(unsigned i=0, ptr=0; i<to; i++, ptr+=3)
- sprintf(&tmp[ptr], "%02"PRIX8" ", msg[i]);
- tmp[to*3 - 1] = '\0';
- nk_label_colored(ctx, tmp, NK_TEXT_LEFT, white);
-
- nk_layout_row_push(ctx, 0.2);
- nk_label_colored(ctx, command_str, NK_TEXT_LEFT, magenta);
-
- switch(cmd)
+ // skip, was sysex payload
+ } break;
+ case ITEM_TYPE_FRAME:
+ {
+ nk_layout_row_dynamic(ctx, widget_h, 3);
{
- case LV2_MIDI_MSG_NOTE_OFF:
- // fall-through
- case LV2_MIDI_MSG_NOTE_ON:
- // fall-through
- case LV2_MIDI_MSG_NOTE_PRESSURE:
- {
- nk_layout_row_push(ctx, 0.1);
- nk_labelf_colored(ctx, NK_TEXT_RIGHT, white, "Ch:%02"PRIu8,
- (msg[0] & 0x0f) + 1);
-
- nk_layout_row_push(ctx, 0.2);
- int8_t octave;
- const char *key = _note(msg[1], &octave);
- nk_labelf_colored(ctx, NK_TEXT_RIGHT, white, "%s%+"PRIi8, key, octave);
+ struct nk_rect b = nk_widget_bounds(ctx);
+ b.x -= group_padding.x;
+ b.w *= 3;
+ b.w += 4*group_padding.x;
+ nk_fill_rect(canvas, b, 0.f, nk_rgb(0x18, 0x18, 0x18));
+ }
- nk_layout_row_push(ctx, 0.1);
- nk_labelf_colored(ctx, NK_TEXT_RIGHT, white, "%"PRIu8, msg[2]);
- } break;
- case LV2_MIDI_MSG_CONTROLLER:
- {
- nk_layout_row_push(ctx, 0.1);
- nk_labelf_colored(ctx, NK_TEXT_RIGHT, white, "Ch:%02"PRIu8,
- (msg[0] & 0x0f) + 1);
+ nk_labelf_colored(ctx, NK_TEXT_LEFT, orange, "@%"PRIi64, itm->frame.offset);
+ nk_labelf_colored(ctx, NK_TEXT_CENTERED, green, "-%"PRIu32"-", itm->frame.counter);
+ nk_labelf_colored(ctx, NK_TEXT_RIGHT, violet, "%"PRIi32, itm->frame.nsamples);
+ } break;
- const midi_msg_t *controller_msg = _search_controller(msg[1]);
- const char *controller_str = controller_msg
- ? controller_msg->key
- : "Unknown";
- nk_layout_row_push(ctx, 0.2);
- nk_label_colored(ctx, controller_str, NK_TEXT_RIGHT, white);
+ case ITEM_TYPE_EVENT:
+ {
+ LV2_Atom_Event *ev = &itm->event.ev;
+ const LV2_Atom *body = &ev->body;
+ const int64_t frames = ev->time.frames;
+ const uint8_t *msg = LV2_ATOM_BODY_CONST(body);
+ const uint8_t cmd = (msg[0] & 0xf0) == 0xf0
+ ? msg[0]
+ : msg[0] & 0xf0;
+
+ const midi_msg_t *command_msg = _search_command(cmd);
+ const char *command_str = command_msg
+ ? command_msg->key
+ : "Unknown";
+
+ char tmp [16];
+ nk_layout_row_begin(ctx, NK_DYNAMIC, widget_h, 7);
+ {
+ nk_layout_row_push(ctx, 0.1);
+ _shadow(ctx, &handle->shadow);
+ nk_labelf_colored(ctx, NK_TEXT_LEFT, yellow, "+%04"PRIi64, frames);
- nk_layout_row_push(ctx, 0.1);
- nk_labelf_colored(ctx, NK_TEXT_RIGHT, white, "%"PRIu8, msg[2]);
- } break;
- case LV2_MIDI_MSG_PGM_CHANGE:
- // fall-through
- case LV2_MIDI_MSG_CHANNEL_PRESSURE:
- {
- nk_layout_row_push(ctx, 0.1);
- nk_labelf_colored(ctx, NK_TEXT_RIGHT, white, "Ch:%02"PRIu8,
- (msg[0] & 0x0f) + 1);
+ nk_layout_row_push(ctx, 0.2);
+ const unsigned rem = body->size;
+ const unsigned to = rem >= 4 ? 4 : rem % 4;
+ for(unsigned i=0, ptr=0; i<to; i++, ptr+=3)
+ sprintf(&tmp[ptr], "%02"PRIX8" ", msg[i]);
+ tmp[to*3 - 1] = '\0';
+ nk_label_colored(ctx, tmp, NK_TEXT_LEFT, white);
- nk_layout_row_push(ctx, 0.2);
- nk_labelf_colored(ctx, NK_TEXT_RIGHT, white, "%"PRIu8, msg[1]);
+ nk_layout_row_push(ctx, 0.2);
+ nk_label_colored(ctx, command_str, NK_TEXT_LEFT, magenta);
- nk_layout_row_push(ctx, 0.1);
- _empty(ctx);
- } break;
- case LV2_MIDI_MSG_BENDER:
+ switch(cmd)
{
- const int16_t bender = (((int16_t)msg[2] << 7) | msg[1]) - 0x2000;
+ case LV2_MIDI_MSG_NOTE_OFF:
+ // fall-through
+ case LV2_MIDI_MSG_NOTE_ON:
+ // fall-through
+ case LV2_MIDI_MSG_NOTE_PRESSURE:
+ {
+ nk_layout_row_push(ctx, 0.1);
+ nk_labelf_colored(ctx, NK_TEXT_RIGHT, white, "Ch:%02"PRIu8,
+ (msg[0] & 0x0f) + 1);
+
+ nk_layout_row_push(ctx, 0.2);
+ int8_t octave;
+ const char *key = _note(msg[1], &octave);
+ nk_labelf_colored(ctx, NK_TEXT_RIGHT, white, "%s%+"PRIi8, key, octave);
+
+ nk_layout_row_push(ctx, 0.1);
+ nk_labelf_colored(ctx, NK_TEXT_RIGHT, white, "%"PRIu8, msg[2]);
+ } break;
+ case LV2_MIDI_MSG_CONTROLLER:
+ {
+ nk_layout_row_push(ctx, 0.1);
+ nk_labelf_colored(ctx, NK_TEXT_RIGHT, white, "Ch:%02"PRIu8,
+ (msg[0] & 0x0f) + 1);
+
+ const midi_msg_t *controller_msg = _search_controller(msg[1]);
+ const char *controller_str = controller_msg
+ ? controller_msg->key
+ : "Unknown";
+ nk_layout_row_push(ctx, 0.2);
+ nk_label_colored(ctx, controller_str, NK_TEXT_RIGHT, white);
+
+ nk_layout_row_push(ctx, 0.1);
+ nk_labelf_colored(ctx, NK_TEXT_RIGHT, white, "%"PRIu8, msg[2]);
+ } break;
+ case LV2_MIDI_MSG_PGM_CHANGE:
+ // fall-through
+ case LV2_MIDI_MSG_CHANNEL_PRESSURE:
+ {
+ nk_layout_row_push(ctx, 0.1);
+ nk_labelf_colored(ctx, NK_TEXT_RIGHT, white, "Ch:%02"PRIu8,
+ (msg[0] & 0x0f) + 1);
+
+ nk_layout_row_push(ctx, 0.2);
+ nk_labelf_colored(ctx, NK_TEXT_RIGHT, white, "%"PRIu8, msg[1]);
+
+ nk_layout_row_push(ctx, 0.1);
+ _empty(ctx);
+ } break;
+ case LV2_MIDI_MSG_BENDER:
+ {
+ const int16_t bender = (((int16_t)msg[2] << 7) | msg[1]) - 0x2000;
+
+ nk_layout_row_push(ctx, 0.1);
+ nk_labelf_colored(ctx, NK_TEXT_RIGHT, white, "Ch:%02"PRIu8,
+ (msg[0] & 0x0f) + 1);
+
+ nk_layout_row_push(ctx, 0.2);
+ nk_labelf_colored(ctx, NK_TEXT_RIGHT, white, "%"PRIi16, bender);
+
+ nk_layout_row_push(ctx, 0.1);
+ _empty(ctx);
+ } break;
+ case LV2_MIDI_MSG_MTC_QUARTER:
+ {
+ const uint8_t msg_type = msg[1] >> 4;
+ const uint8_t msg_val = msg[1] & 0xf;
+
+ nk_layout_row_push(ctx, 0.1);
+ _empty(ctx);
+
+ const midi_msg_t *timecode_msg = _search_timecode(msg_type);
+ const char *timecode_str = timecode_msg
+ ? timecode_msg->key
+ : "Unknown";
+ nk_layout_row_push(ctx, 0.2);
+ nk_label_colored(ctx, timecode_str, NK_TEXT_RIGHT, white);
+
+ nk_layout_row_push(ctx, 0.1);
+ nk_labelf_colored(ctx, NK_TEXT_RIGHT, white, "%"PRIu8, msg_val);
+ } break;
+ case LV2_MIDI_MSG_SONG_POS:
+ {
+ const int16_t song_pos= (((int16_t)msg[2] << 7) | msg[1]);
+
+ nk_layout_row_push(ctx, 0.1);
+ _empty(ctx);
+
+ nk_layout_row_push(ctx, 0.2);
+ nk_labelf_colored(ctx, NK_TEXT_RIGHT, white, "%"PRIu16, song_pos);
+
+ nk_layout_row_push(ctx, 0.1);
+ _empty(ctx);
+ } break;
+ case LV2_MIDI_MSG_SONG_SELECT:
+ {
+ nk_layout_row_push(ctx, 0.1);
+ _empty(ctx);
+
+ nk_layout_row_push(ctx, 0.2);
+ nk_labelf_colored(ctx, NK_TEXT_RIGHT, white, "%"PRIu8, msg[1]);
+
+ nk_layout_row_push(ctx, 0.1);
+ _empty(ctx);
+ } break;
+ case LV2_MIDI_MSG_SYSTEM_EXCLUSIVE:
+ // fall-throuh
+ case LV2_MIDI_MSG_TUNE_REQUEST:
+ // fall-throuh
+ case LV2_MIDI_MSG_CLOCK:
+ // fall-throuh
+ case LV2_MIDI_MSG_START:
+ // fall-throuh
+ case LV2_MIDI_MSG_CONTINUE:
+ // fall-throuh
+ case LV2_MIDI_MSG_STOP:
+ // fall-throuh
+ case LV2_MIDI_MSG_ACTIVE_SENSE:
+ // fall-throuh
+ case LV2_MIDI_MSG_RESET:
+ {
+ nk_layout_row_push(ctx, 0.1);
+ _empty(ctx);
+
+ nk_layout_row_push(ctx, 0.2);
+ _empty(ctx);
+
+ nk_layout_row_push(ctx, 0.1);
+ _empty(ctx);
+ } break;
+ }
- nk_layout_row_push(ctx, 0.1);
- nk_labelf_colored(ctx, NK_TEXT_RIGHT, white, "Ch:%02"PRIu8,
- (msg[0] & 0x0f) + 1);
-
- nk_layout_row_push(ctx, 0.2);
- nk_labelf_colored(ctx, NK_TEXT_RIGHT, white, "%"PRIi16, bender);
+ nk_layout_row_push(ctx, 0.1);
+ nk_labelf_colored(ctx, NK_TEXT_RIGHT, blue, "%"PRIu32, body->size);
+ }
+ nk_layout_row_end(ctx);
- nk_layout_row_push(ctx, 0.1);
- _empty(ctx);
- } break;
- case LV2_MIDI_MSG_MTC_QUARTER:
+ for(unsigned j=4; j<body->size; j+=4)
+ {
+ nk_layout_row_begin(ctx, NK_DYNAMIC, widget_h, 7);
{
- const uint8_t msg_type = msg[1] >> 4;
- const uint8_t msg_val = msg[1] & 0xf;
-
nk_layout_row_push(ctx, 0.1);
+ _shadow(ctx, &handle->shadow);
_empty(ctx);
- const midi_msg_t *timecode_msg = _search_timecode(msg_type);
- const char *timecode_str = timecode_msg
- ? timecode_msg->key
- : "Unknown";
nk_layout_row_push(ctx, 0.2);
- nk_label_colored(ctx, timecode_str, NK_TEXT_RIGHT, white);
-
- nk_layout_row_push(ctx, 0.1);
- nk_labelf_colored(ctx, NK_TEXT_RIGHT, white, "%"PRIu8, msg_val);
- } break;
- case LV2_MIDI_MSG_SONG_POS:
- {
- const int16_t song_pos= (((int16_t)msg[2] << 7) | msg[1]);
-
- nk_layout_row_push(ctx, 0.1);
- _empty(ctx);
+ const unsigned rem = body->size - j;
+ const unsigned to = rem >= 4 ? 4 : rem % 4;
+ for(unsigned i=0, ptr=0; i<to; i++, ptr+=3)
+ sprintf(&tmp[ptr], "%02"PRIX8" ", msg[j+i]);
+ tmp[to*3 - 1] = '\0';
+ nk_label_colored(ctx, tmp, NK_TEXT_LEFT, white);
nk_layout_row_push(ctx, 0.2);
- nk_labelf_colored(ctx, NK_TEXT_RIGHT, white, "%"PRIu16, song_pos);
-
- nk_layout_row_push(ctx, 0.1);
_empty(ctx);
- } break;
- case LV2_MIDI_MSG_SONG_SELECT:
- {
- nk_layout_row_push(ctx, 0.1);
- _empty(ctx);
-
- nk_layout_row_push(ctx, 0.2);
- nk_labelf_colored(ctx, NK_TEXT_RIGHT, white, "%"PRIu8, msg[1]);
nk_layout_row_push(ctx, 0.1);
_empty(ctx);
- } break;
- case LV2_MIDI_MSG_SYSTEM_EXCLUSIVE:
- // fall-throuh
- case LV2_MIDI_MSG_TUNE_REQUEST:
- // fall-throuh
- case LV2_MIDI_MSG_CLOCK:
- // fall-throuh
- case LV2_MIDI_MSG_START:
- // fall-throuh
- case LV2_MIDI_MSG_CONTINUE:
- // fall-throuh
- case LV2_MIDI_MSG_STOP:
- // fall-throuh
- case LV2_MIDI_MSG_ACTIVE_SENSE:
- // fall-throuh
- case LV2_MIDI_MSG_RESET:
- {
- nk_layout_row_push(ctx, 0.1);
- _empty(ctx);
nk_layout_row_push(ctx, 0.2);
_empty(ctx);
nk_layout_row_push(ctx, 0.1);
_empty(ctx);
- } break;
- }
-
- nk_layout_row_push(ctx, 0.1);
- nk_labelf_colored(ctx, NK_TEXT_RIGHT, blue, "%"PRIu32, body->size);
- }
- nk_layout_row_end(ctx);
-
- for(unsigned j=4; j<body->size; j+=4)
- {
- nk_layout_row_begin(ctx, NK_DYNAMIC, widget_h, 7);
- {
- nk_layout_row_push(ctx, 0.1);
- _empty(ctx);
- nk_layout_row_push(ctx, 0.2);
- const unsigned rem = body->size - j;
- const unsigned to = rem >= 4 ? 4 : rem % 4;
- for(unsigned i=0, ptr=0; i<to; i++, ptr+=3)
- sprintf(&tmp[ptr], "%02"PRIX8" ", msg[j+i]);
- tmp[to*3 - 1] = '\0';
- nk_label_colored(ctx, tmp, NK_TEXT_LEFT, white);
-
- nk_layout_row_push(ctx, 0.2);
- _empty(ctx);
-
- nk_layout_row_push(ctx, 0.1);
- _empty(ctx);
-
- nk_layout_row_push(ctx, 0.2);
- _empty(ctx);
-
- nk_layout_row_push(ctx, 0.1);
- _empty(ctx);
-
- nk_layout_row_push(ctx, 0.1);
- _empty(ctx);
+ nk_layout_row_push(ctx, 0.1);
+ _empty(ctx);
+ }
}
- }
- counter += 1;
+ } break;
}
}
- handle->count = counter;
-
- if(handle->bottom)
- {
- panel= nk_window_get_panel(ctx);
- panel->offset->y = panel->at_y;
- handle->bottom = false;
+ nk_list_view_end(&lview);
+ }
- _post_redisplay(handle);
- }
+ nk_layout_row_dynamic(ctx, widget_h, 3);
+ {
+ if(nk_checkbox_label(ctx, "overwrite", &handle->state.overwrite))
+ _toggle(handle, handle->urid.overwrite, handle->state.overwrite, true);
+ if(nk_checkbox_label(ctx, "block", &handle->state.block))
+ _toggle(handle, handle->urid.block, handle->state.block, true);
+ if(nk_checkbox_label(ctx, "follow", &handle->state.follow))
+ _toggle(handle, handle->urid.follow, handle->state.follow, true);
+ }
- nk_group_end(ctx);
+ const bool max_reached = handle->n_item >= MAX_LINES;
+ nk_layout_row_dynamic(ctx, widget_h, 2);
+ if(nk_button_symbol_label(ctx,
+ max_reached ? NK_SYMBOL_TRIANGLE_RIGHT: NK_SYMBOL_NONE,
+ "clear", NK_TEXT_LEFT))
+ {
+ _clear(handle);
}
+ nk_label(ctx, "Sherlock.lv2: "SHERLOCK_VERSION, NK_TEXT_RIGHT);
}
nk_end(ctx);
}
diff --git a/osc_inspector.c b/osc_inspector.c
index ef9622a..f3ebb58 100644
--- a/osc_inspector.c
+++ b/osc_inspector.c
@@ -76,8 +76,7 @@ instantiate(const LV2_Descriptor* descriptor, double rate,
return NULL;
}
- if( !props_register(&handle->props, &stat_count, &handle->state.count, &handle->stash.count)
- || !props_register(&handle->props, &stat_overwrite, &handle->state.overwrite, &handle->stash.overwrite)
+ if( !props_register(&handle->props, &stat_overwrite, &handle->state.overwrite, &handle->stash.overwrite)
|| !props_register(&handle->props, &stat_block, &handle->state.block, &handle->stash.block)
|| !props_register(&handle->props, &stat_follow, &handle->state.follow, &handle->stash.follow) )
{
diff --git a/osc_inspector_nk.c b/osc_inspector_nk.c
index b6966d2..d4f6004 100644
--- a/osc_inspector_nk.c
+++ b/osc_inspector_nk.c
@@ -32,6 +32,25 @@ struct _mem_t {
};
static inline void
+_shadow(struct nk_context *ctx, bool *shadow)
+{
+ if(*shadow)
+ {
+ struct nk_style *style = &ctx->style;
+ const struct nk_vec2 group_padding = style->window.group_padding;
+ struct nk_command_buffer *canvas = nk_window_get_canvas(ctx);
+
+ struct nk_rect b = nk_widget_bounds(ctx);
+ b.x -= group_padding.x;
+ b.w *= 10;
+ b.w += 5*group_padding.x;
+ nk_fill_rect(canvas, b, 0.f, nk_rgb(0x28, 0x28, 0x28));
+ }
+
+ *shadow = !*shadow;
+}
+
+static inline void
_mem_printf(mem_t *mem, const char *fmt, ...)
{
va_list args;
@@ -257,6 +276,7 @@ _osc_bundle(plughandle_t *handle, struct nk_context *ctx, const LV2_Atom_Object
nk_layout_row_begin(ctx, NK_DYNAMIC, widget_h, 4);
nk_layout_row_push(ctx, offset);
+ _shadow(ctx, &handle->shadow);
_empty(ctx);
_osc_packet(handle, ctx, (const LV2_Atom_Object *)item, offset);
@@ -284,11 +304,74 @@ _osc_inspector_expose(struct nk_context *ctx, struct nk_rect wbounds, void *data
const float widget_h = handle->dy;
struct nk_style *style = &ctx->style;
const struct nk_vec2 window_padding = style->window.padding;
+ const struct nk_vec2 group_padding = style->window.group_padding;
if(nk_begin(ctx, "Window", wbounds, NK_WINDOW_NO_SCROLLBAR))
{
nk_window_set_bounds(ctx, wbounds);
struct nk_panel *panel= nk_window_get_panel(ctx);
+ struct nk_command_buffer *canvas = nk_window_get_canvas(ctx);
+
+ const float body_h = panel->bounds.h - 4*window_padding.y - 2*widget_h;
+ nk_layout_row_dynamic(ctx, body_h, 1);
+ nk_flags flags = NK_WINDOW_BORDER;
+ if(handle->state.follow)
+ flags |= NK_WINDOW_NO_SCROLLBAR;
+ struct nk_list_view lview;
+ if(nk_list_view_begin(ctx, &lview, "Events", flags, widget_h, NK_MIN(handle->n_item, MAX_LINES)))
+ {
+ if(handle->state.follow)
+ {
+ lview.end = NK_MAX(handle->n_item, 0);
+ lview.begin = NK_MAX(lview.end - lview.count, 0);
+ }
+ handle->shadow = lview.begin % 2 == 0;
+ for(int l = lview.begin; (l < lview.end) && (l < handle->n_item); l++)
+ {
+ item_t *itm = handle->items[l];
+
+ switch(itm->type)
+ {
+ case ITEM_TYPE_NONE:
+ {
+ // skip, was bundle payload
+ } break;
+ case ITEM_TYPE_FRAME:
+ {
+ nk_layout_row_dynamic(ctx, widget_h, 3);
+ {
+ struct nk_rect b = nk_widget_bounds(ctx);
+ b.x -= group_padding.x;
+ b.w *= 3;
+ b.w += 4*group_padding.x;
+ nk_fill_rect(canvas, b, 0.f, nk_rgb(0x18, 0x18, 0x18));
+ }
+
+ nk_labelf_colored(ctx, NK_TEXT_LEFT, orange, "@%"PRIi64, itm->frame.offset);
+ nk_labelf_colored(ctx, NK_TEXT_CENTERED, green, "-%"PRIu32"-", itm->frame.counter);
+ nk_labelf_colored(ctx, NK_TEXT_RIGHT, violet, "%"PRIi32, itm->frame.nsamples);
+ } break;
+
+ case ITEM_TYPE_EVENT:
+ {
+ LV2_Atom_Event *ev = &itm->event.ev;
+ const LV2_Atom_Object *obj = (const LV2_Atom_Object *)&ev->body;
+ const int64_t frames = ev->time.frames;
+ const float off = 0.1;
+
+ nk_layout_row_begin(ctx, NK_DYNAMIC, widget_h, 4);
+
+ nk_layout_row_push(ctx, off);
+ _shadow(ctx, &handle->shadow);
+ nk_labelf_colored(ctx, NK_TEXT_LEFT, yellow, "+%04"PRIi64, frames);
+
+ _osc_packet(handle, ctx, obj, off);
+ } break;
+ }
+ }
+
+ nk_list_view_end(&lview);
+ }
nk_layout_row_dynamic(ctx, widget_h, 3);
{
@@ -300,84 +383,15 @@ _osc_inspector_expose(struct nk_context *ctx, struct nk_rect wbounds, void *data
_toggle(handle, handle->urid.follow, handle->state.follow, true);
}
+ const bool max_reached = handle->n_item >= MAX_LINES;
nk_layout_row_dynamic(ctx, widget_h, 2);
+ if(nk_button_symbol_label(ctx,
+ max_reached ? NK_SYMBOL_TRIANGLE_RIGHT: NK_SYMBOL_NONE,
+ "clear", NK_TEXT_LEFT))
{
- if(nk_button_label(ctx, "clear"))
- _clear(handle);
-
- int selected = 0;
- for(int i = 0; i < 5; i++)
- {
- if(handle->state.count == max_values[i])
- {
- selected = i;
- break;
- }
- }
-
- selected = nk_combo(ctx, max_items, 5, selected, widget_h,
- nk_vec2(wbounds.w/3, widget_h*5));
- if(handle->state.count != max_values[selected])
- {
- handle->state.count = max_values[selected];
- _toggle(handle, handle->urid.count, handle->state.count, false);
- }
- }
-
- const float body_h = panel->bounds.h - 4*window_padding.y - 2*widget_h;
- nk_layout_row_dynamic(ctx, body_h, 1);
- if(nk_group_begin(ctx, "Events", NK_WINDOW_BORDER))
- {
- uint32_t counter = 0;
-
- LV2_ATOM_TUPLE_FOREACH((const LV2_Atom_Tuple *)handle->ser.atom, atom)
- {
- const LV2_Atom_Tuple *tup = (const LV2_Atom_Tuple *)atom;
- const LV2_Atom_Long *offset = (const LV2_Atom_Long *)lv2_atom_tuple_begin(tup);
- const LV2_Atom_Int *nsamples = (const LV2_Atom_Int *)lv2_atom_tuple_next(&offset->atom);
- const LV2_Atom_Sequence *seq = (const LV2_Atom_Sequence *)lv2_atom_tuple_next(&nsamples->atom);
-
- nk_layout_row_dynamic(ctx, 2.f, 1);
- _ruler(ctx, 2.f, gray);
-
- nk_layout_row_dynamic(ctx, widget_h, 3);
- nk_labelf_colored(ctx, NK_TEXT_LEFT, orange, "@%"PRIi64, offset->body);
- nk_labelf_colored(ctx, NK_TEXT_CENTERED, green, "-%"PRIu32"-", counter);
- nk_labelf_colored(ctx, NK_TEXT_RIGHT, violet, "%"PRIi32, nsamples->body);
-
- nk_layout_row_dynamic(ctx, 2.f, 1);
- _ruler(ctx, 1.f, gray);
-
- LV2_ATOM_SEQUENCE_FOREACH(seq, ev)
- {
- const LV2_Atom_Object *obj = (const LV2_Atom_Object *)&ev->body;
- const int64_t frames = ev->time.frames;
- const float off = 0.1;
-
- nk_layout_row_begin(ctx, NK_DYNAMIC, widget_h, 4);
-
- nk_layout_row_push(ctx, off);
- nk_labelf_colored(ctx, NK_TEXT_LEFT, yellow, "+%04"PRIi64, frames);
-
- _osc_packet(handle, ctx, obj, off);
-
- counter += 1;
- }
- }
-
- handle->count = counter;
-
- if(handle->bottom)
- {
- panel= nk_window_get_panel(ctx);
- panel->offset->y = panel->at_y;
- handle->bottom = false;
-
- _post_redisplay(handle);
- }
-
- nk_group_end(ctx);
+ _clear(handle);
}
+ nk_label(ctx, "Sherlock.lv2: "SHERLOCK_VERSION, NK_TEXT_RIGHT);
}
nk_end(ctx);
}
diff --git a/sherlock.h b/sherlock.h
index 7766a57..524a3a2 100644
--- a/sherlock.h
+++ b/sherlock.h
@@ -58,7 +58,6 @@ struct _position_t {
};
struct _state_t {
- int32_t count;
int32_t overwrite;
int32_t block;
int32_t follow;
@@ -66,13 +65,6 @@ struct _state_t {
#define MAX_NPROPS 4
-static const props_def_t stat_count = {
- .property = SHERLOCK_URI"#count",
- .access = LV2_PATCH__writable,
- .type = LV2_ATOM__Int,
- .mode = PROP_MODE_STATIC
-};
-
static const props_def_t stat_overwrite = {
.property = SHERLOCK_URI"#overwrite",
.access = LV2_PATCH__writable,
diff --git a/sherlock.ttl b/sherlock.ttl
index 495dd3b..fa081e8 100644
--- a/sherlock.ttl
+++ b/sherlock.ttl
@@ -55,19 +55,6 @@ proj:sherlock
doap:maintainer omk:me ;
doap:name "Sherlock Bundle" .
-sherlock:count
- a lv2:Parameter ;
- rdfs:label "Max. events" ;
- rdfs:comment "Maximum number of events shown" ;
- rdfs:range atom:Int ;
- lv2:minimum 1024 ;
- lv2:maximum 16384 ;
- lv2:scalePoint [ rdfs:label "1k" ; rdf:value 1024 ] ;
- lv2:scalePoint [ rdfs:label "2k" ; rdf:value 2048 ] ;
- lv2:scalePoint [ rdfs:label "4k" ; rdf:value 4096 ] ;
- lv2:scalePoint [ rdfs:label "8k" ; rdf:value 8192 ] ;
- lv2:scalePoint [ rdfs:label "16k" ; rdf:value 16384 ] .
-
sherlock:overwrite
a lv2:Parameter ;
rdfs:label "Overwrite" ;
@@ -137,16 +124,14 @@ sherlock:atom_inspector
] ;
patch:writable
- sherlock:count ,
sherlock:overwrite,
sherlock:block ,
sherlock:follow ;
state:state [
- sherlock:count 2048 ;
sherlock:overwrite false ;
sherlock:block false ;
- sherlock:follow true ;
+ sherlock:follow false ;
] .
# MIDI Inspector Plugin
@@ -195,16 +180,14 @@ sherlock:midi_inspector
] ;
patch:writable
- sherlock:count ,
sherlock:overwrite ,
sherlock:block ,
sherlock:follow ;
state:state [
- sherlock:count 2048 ;
sherlock:overwrite false ;
sherlock:block false ;
- sherlock:follow true ;
+ sherlock:follow false ;
] .
# OSC Inspector Plugin
@@ -253,14 +236,12 @@ sherlock:osc_inspector
] ;
patch:writable
- sherlock:count ,
sherlock:overwrite ,
sherlock:block ,
sherlock:follow ;
state:state [
- sherlock:count 2048 ;
sherlock:overwrite false ;
sherlock:block false ;
- sherlock:follow true ;
+ sherlock:follow false ;
] .
diff --git a/sherlock_nk.c b/sherlock_nk.c
index ae7bd11..65233b5 100644
--- a/sherlock_nk.c
+++ b/sherlock_nk.c
@@ -22,6 +22,7 @@
#include <limits.h>
#include <sherlock.h>
+#include <osc.lv2/util.h>
#define NK_PUGL_IMPLEMENTATION
#include <sherlock_nk.h>
@@ -183,21 +184,47 @@ _empty(struct nk_context *ctx)
nk_text(ctx, NULL, 0, NK_TEXT_RIGHT);
}
-void
-_clear(plughandle_t *handle)
+static void
+_clear_items(plughandle_t *handle)
{
- atom_ser_t *ser = &handle->ser;
- struct nk_str *str = &handle->str;
-
- if(_ser_realloc(ser, 1024))
+ if(handle->items)
{
- lv2_atom_forge_set_sink(&handle->mem, _sink, _deref, ser);
- lv2_atom_forge_tuple(&handle->mem, &handle->frame);
+ for(int i = 0; i < handle->n_item; i++)
+ {
+ item_t *itm = handle->items[i];
+
+ if(itm)
+ free(itm);
+ }
+
+ free(handle->items);
+ handle->items = NULL;
}
- handle->count = 0;
+ handle->n_item = 0;
+}
+
+static item_t *
+_append_item(plughandle_t *handle, item_type_t type, size_t sz)
+{
+ handle->items = realloc(handle->items, (handle->n_item + 1)*sizeof(item_t *));
+ handle->items[handle->n_item] = malloc(sizeof(item_t) + sz);
+
+ item_t *itm = handle->items[handle->n_item];
+ itm->type = type;
+
+ handle->n_item += 1;
+
+ return itm;
+}
+
+void
+_clear(plughandle_t *handle)
+{
+ _clear_items(handle);
+ nk_str_clear(&handle->str);
handle->selected = NULL;
- nk_str_clear(str);
+ handle->counter = 0;
}
void
@@ -244,7 +271,6 @@ instantiate(const LV2UI_Descriptor *descriptor, const char *plugin_uri,
handle->event_transfer = handle->map->map(handle->map->handle, LV2_ATOM__eventTransfer);
lv2_atom_forge_init(&handle->forge, handle->map);
- lv2_atom_forge_init(&handle->mem, handle->map);
lv2_osc_urid_init(&handle->osc_urid, handle->map);
handle->write_function = write_function;
@@ -257,8 +283,7 @@ instantiate(const LV2UI_Descriptor *descriptor, const char *plugin_uri,
return NULL;
}
- if( !(handle->urid.count = props_register(&handle->props, &stat_count, &handle->state.count, &handle->stash.count))
- || !(handle->urid.overwrite = props_register(&handle->props, &stat_overwrite, &handle->state.overwrite, &handle->stash.overwrite))
+ if( !(handle->urid.overwrite = props_register(&handle->props, &stat_overwrite, &handle->state.overwrite, &handle->stash.overwrite))
|| !(handle->urid.block = props_register(&handle->props, &stat_block, &handle->state.block, &handle->stash.block))
|| !(handle->urid.follow = props_register(&handle->props, &stat_follow, &handle->state.follow, &handle->stash.follow)) )
{
@@ -280,16 +305,19 @@ instantiate(const LV2UI_Descriptor *descriptor, const char *plugin_uri,
cfg->data = handle;
if(!strcmp(plugin_uri, SHERLOCK_MIDI_INSPECTOR_URI))
{
+ handle->type = SHERLOCK_MIDI_INSPECTOR,
cfg->width = 600 * scale;
cfg->expose = _midi_inspector_expose;
}
else if(!strcmp(plugin_uri, SHERLOCK_ATOM_INSPECTOR_URI))
{
+ handle->type = SHERLOCK_ATOM_INSPECTOR,
cfg->width = 1200 * scale;
cfg->expose = _atom_inspector_expose;
}
else if(!strcmp(plugin_uri, SHERLOCK_OSC_INSPECTOR_URI))
{
+ handle->type = SHERLOCK_OSC_INSPECTOR,
cfg->width = 600 * scale;
cfg->expose = _osc_inspector_expose;
}
@@ -329,11 +357,9 @@ cleanup(LV2UI_Handle instance)
sratom_free(handle->sratom);
+ _clear_items(handle);
nk_str_free(&handle->str);
- atom_ser_t *ser = &handle->ser;
- _ser_free(ser);
-
nk_pugl_hide(&handle->win);
nk_pugl_shutdown(&handle->win);
@@ -341,6 +367,36 @@ cleanup(LV2UI_Handle instance)
}
static void
+_osc_bundle(plughandle_t *handle, const LV2_Atom_Object *obj);
+
+static void
+_osc_packet(plughandle_t *handle, const LV2_Atom_Object *obj)
+{
+ if(lv2_osc_is_message_type(&handle->osc_urid, obj->body.otype))
+ {
+ _append_item(handle, ITEM_TYPE_NONE, 0);
+ }
+ else if(lv2_osc_is_bundle_type(&handle->osc_urid, obj->body.otype))
+ {
+ _append_item(handle, ITEM_TYPE_NONE, 0);
+ _osc_bundle(handle, obj);
+ }
+}
+
+static void
+_osc_bundle(plughandle_t *handle, const LV2_Atom_Object *obj)
+{
+ const LV2_Atom_Object *timetag = NULL;
+ const LV2_Atom_Tuple *items = NULL;
+ lv2_osc_bundle_get(&handle->osc_urid, obj, &timetag, &items);
+
+ LV2_ATOM_TUPLE_FOREACH(items, item)
+ {
+ _osc_packet(handle, (const LV2_Atom_Object *)item);
+ }
+}
+
+static void
port_event(LV2UI_Handle instance, uint32_t i, uint32_t size, uint32_t urid,
const void *buf)
{
@@ -374,32 +430,70 @@ port_event(LV2UI_Handle instance, uint32_t i, uint32_t size, uint32_t urid,
}
case 2:
{
- bool append = true;
-
if(handle->state.block)
- append = false;
-
- if(handle->count > handle->state.count)
{
- if(handle->state.overwrite)
- _clear(handle);
- else
- append = false;
+ break;
}
- if(append)
+ if( (handle->n_item > MAX_LINES) && handle->state.overwrite)
{
- const LV2_Atom *atom = buf;
- const uint32_t sz = lv2_atom_total_size(atom);
+ _clear(handle);
+ }
- lv2_atom_forge_write(&handle->mem, atom, sz);
+ const LV2_Atom *atom = buf;
+ const LV2_Atom_Tuple *tup = (const LV2_Atom_Tuple *)atom;
+ const LV2_Atom_Long *offset = (const LV2_Atom_Long *)lv2_atom_tuple_begin(tup);
+ const LV2_Atom_Int *nsamples = (const LV2_Atom_Int *)lv2_atom_tuple_next(&offset->atom);
+ const LV2_Atom_Sequence *seq = (const LV2_Atom_Sequence *)lv2_atom_tuple_next(&nsamples->atom);
- if(handle->state.follow)
- handle->bottom = true; // signal scrolling to bottom
+ // append frame
+ {
+ item_t *itm = _append_item(handle, ITEM_TYPE_FRAME, 0);
+ itm->frame.offset = offset->body;
+ itm->frame.counter = handle->counter++;
+ itm->frame.nsamples = nsamples->body;
+ }
- nk_pugl_post_redisplay(&handle->win);
+ LV2_ATOM_SEQUENCE_FOREACH(seq, ev)
+ {
+ const size_t ev_sz = sizeof(LV2_Atom_Event) + ev->body.size;
+ item_t *itm = _append_item(handle, ITEM_TYPE_EVENT, ev_sz);
+ memcpy(&itm->event.ev, ev, ev_sz);
+
+ switch(handle->type)
+ {
+ case SHERLOCK_ATOM_INSPECTOR:
+ {
+ if(handle->state.follow)
+ {
+ handle->selected = &itm->event.ev.body;
+ handle->ttl_dirty = true;
+ }
+ } break;
+ case SHERLOCK_OSC_INSPECTOR:
+ {
+ // bundles may span over multiple lines
+ const LV2_Atom_Object *obj = (const LV2_Atom_Object *)&ev->body;
+ if(lv2_osc_is_bundle_type(&handle->osc_urid, obj->body.otype))
+ {
+ _osc_bundle(handle, obj);
+ }
+ } break;
+ case SHERLOCK_MIDI_INSPECTOR:
+ {
+ // sysex messages may span over multiple lines
+ const uint8_t *msg = LV2_ATOM_BODY_CONST(&ev->body);
+ if( (msg[0] == 0xf0) && (ev->body.size > 4) )
+ {
+ for(uint32_t j = 4; j < ev->body.size; j += 4)
+ _append_item(handle, ITEM_TYPE_NONE, 0); // place holder
+ }
+ } break;
+ }
}
+ nk_pugl_post_redisplay(&handle->win);
+
break;
}
}
diff --git a/sherlock_nk.h b/sherlock_nk.h
index 62b63b2..0ec23cf 100644
--- a/sherlock_nk.h
+++ b/sherlock_nk.h
@@ -23,9 +23,37 @@
#include <osc.lv2/osc.h>
#include <sratom/sratom.h>
+#define MAX_LINES 2048
+
+typedef enum _plugin_type_t plugin_type_t;
+typedef enum _item_type_t item_type_t;
+typedef struct _item_t item_t;
typedef struct _plughandle_t plughandle_t;
typedef struct _atom_ser_t atom_ser_t;
+enum _item_type_t {
+ ITEM_TYPE_NONE,
+ ITEM_TYPE_FRAME,
+ ITEM_TYPE_EVENT
+};
+
+struct _item_t {
+ item_type_t type;
+
+ union {
+ struct {
+ int64_t offset;
+ uint32_t counter;
+ int32_t nsamples;
+ } frame;
+
+ struct {
+ LV2_Atom_Event ev;
+ uint8_t body [0];
+ } event;
+ };
+};
+
struct _atom_ser_t {
uint32_t size;
uint32_t offset;
@@ -35,6 +63,12 @@ struct _atom_ser_t {
};
};
+enum _plugin_type_t {
+ SHERLOCK_ATOM_INSPECTOR,
+ SHERLOCK_MIDI_INSPECTOR,
+ SHERLOCK_OSC_INSPECTOR
+};
+
struct _plughandle_t {
LV2UI_Write_Function write_function;
LV2UI_Controller controller;
@@ -42,16 +76,12 @@ struct _plughandle_t {
LV2_URID_Map *map;
LV2_URID_Unmap *unmap;
LV2_Atom_Forge forge;
- LV2_Atom_Forge mem;
- int32_t count;
- bool bottom;
LV2_Atom_Forge_Frame frame;
LV2_URID event_transfer;
LV2_OSC_URID osc_urid;
PROPS_T(props, MAX_NPROPS);
struct {
- LV2_URID count;
LV2_URID overwrite;
LV2_URID block;
LV2_URID follow;
@@ -61,7 +91,7 @@ struct _plughandle_t {
nk_pugl_window_t win;
- atom_ser_t ser;
+ bool ttl_dirty;
const LV2_Atom *selected;
struct nk_str str;
@@ -69,6 +99,13 @@ struct _plughandle_t {
const char *base_uri;
float dy;
+
+ uint32_t counter;
+ int n_item;
+ item_t **items;
+
+ bool shadow;
+ plugin_type_t type;
};
extern const char *max_items [5];