aboutsummaryrefslogtreecommitdiff
path: root/midi_inspector_nk.c
diff options
context:
space:
mode:
Diffstat (limited to 'midi_inspector_nk.c')
-rw-r--r--midi_inspector_nk.c485
1 files changed, 250 insertions, 235 deletions
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);
}