--- cui_midi.c- Sun Apr 13 23:00:00 2014 +++ cui_midi.c Sun Apr 13 23:30:00 2014 @@ -231,6 +231,249 @@ return TRUE; } +/**/ + +typedef struct cui_kbd{ + struct cui_base base; + int v[128]; + int play_mode; + int cursor; + cui sheet; +} *cui_kbd; + +cui cui_kbd_new(cui parent, int x, int y, int w); +void cui_kbd_init(cui obj, cui parent, int x, int y, int w); +int cui_kbd_hdr(cui obj, int evt, int val, void *prm); +void cui_kbd_set(cui obj, int note, int v); +int cui_kbd_get(cui obj, int note); + + +#include "cui/key.h" + +static int +kbd_note_x(int note) +{ + int i = note % 12; + int o = note / 12; + return o * 14 + i + (i >= 5); +} + +static int +kbd_x_note(int x) +{ + int o = x / 14; + int i = x % 14; + if(i == 5 || i == 13) return -1; + return o * 12 + i - (i >= 5); +} + +cui +cui_kbd_new(cui parent, int x, int y, int w) +{ + cui obj = cui_alloc(sizeof(struct cui_kbd)); + cui_kbd_init(obj, parent, x, y, w); + return obj; +} + +void +cui_kbd_init(cui obj, cui parent, int x, int y, int w) +{ + cui_kbd p = (cui_kbd)obj; + int i; + + cui_base_init(obj, parent, x, y, w, 2); + p->sheet = cui_base_new(obj, 0, 0, kbd_note_x(128), 2); + + obj->flags |= CUI_FLG_CAN_FOCUS; + for(i=0; i<128; i++) p->v[i] = FALSE; + p->play_mode = FALSE; + p->cursor = 69; + cui_x_set(p->sheet, -kbd_note_x(p->cursor)); + + cui_bind(obj, CUI_EVT_DRAW | CUI_EVT_KEY, cui_kbd_hdr, NULL); +} + +static void +kbd_draw_x_char_attr(cui obj, int fc, int x, char *c_u, int *a_u, char *c_l, int *a_l) +{ + cui_kbd p = (cui_kbd)obj; + int note = kbd_x_note(x); + int blk = x & 1; + *c_u = note < 0 ? '|' : ' '; + *a_u = note >= 0 && blk ? CUI_ATTR_REVERSE : CUI_ATTR_NORMAL; + *c_l = blk ? '|' : ' '; + *a_l = CUI_ATTR_NORMAL; + + if(p->play_mode) *a_l |= CUI_ATTR_ULINE; + if(note == p->cursor){ + if(blk) *c_l = '^'; + else *a_u |= CUI_ATTR_ULINE; + } + if(note >= 0 && p->v[note]){ + if(blk) *c_u = 'o'; + else *c_l = 'o'; + } + if(!p->play_mode && fc){ + *a_u ^= CUI_ATTR_REVERSE; + *a_l ^= CUI_ATTR_REVERSE; + } +} + +static void +kbd_draw_x(cui obj, int fc, int x) +{ + cui_kbd p = (cui_kbd)obj; + char c_u, c_l; + int a_u, a_l; + char buf[2]; + buf[1] = '\0'; + + kbd_draw_x_char_attr(obj, fc, x, &c_u, &a_u, &c_l, &a_l); + + buf[0] = c_u; + cui_draw_str(p->sheet, x, 0, buf, a_u); + + buf[0] = c_l; + cui_draw_str(p->sheet, x, 1, buf, a_l); +} + +static void +kbd_draw_note(cui obj, int fc, int note) +{ + kbd_draw_x(obj, fc, kbd_note_x(note)); +} + +static void +kbd_draw(cui obj, int fc) +{ + cui_kbd p = (cui_kbd)obj; + int x; + for(x=0; xsheet->w; x++) kbd_draw_x(obj, fc, x); +} + +int +cui_kbd_hdr(cui obj, int evt, int val, void *prm) +{ + cui_kbd p = (cui_kbd)obj; + + switch(evt){ + case CUI_EVT_DRAW: + kbd_draw(obj, val == CUI_DRAW_FOCUS); + break; + case CUI_EVT_KEY: + if(!p->play_mode){ + if(val == CUI_KEY_ENTER){ + p->play_mode = TRUE; + cui_draw(obj); + return TRUE; + } + return FALSE; + } + /* play_mode */ + switch(val){ + case CUI_KEY_ENTER: + p->play_mode = FALSE; + cui_draw(obj); + break; + case CUI_KEY_LEFT: + if(p->cursor > 0){ + int mv = -( p->sheet->x + kbd_note_x(p->cursor - 1) ); + if(mv > 0){ + cui_x_set(p->sheet, p->sheet->x + mv); + cui_draw(obj); + } + kbd_draw_note(obj, FALSE, p->cursor--); + kbd_draw_note(obj, FALSE, p->cursor); + } + break; + case CUI_KEY_RIGHT: + if(p->cursor < 127){ + int mv = p->sheet->x + kbd_note_x(p->cursor + 1) - (obj->w - 1); + if(mv > 0){ + cui_x_set(p->sheet, p->sheet->x - mv); + cui_draw(obj); + } + kbd_draw_note(obj, FALSE, p->cursor++); + kbd_draw_note(obj, FALSE, p->cursor); + } + break; + case CUI_KEY_UP: + if(p->v[ p->cursor ]){ + p->v[ p->cursor ] = FALSE; + kbd_draw_note(obj, FALSE, p->cursor); + cui_handler_call(obj, CUI_EVT_BUTTON, p->cursor); + } + break; + case CUI_KEY_DOWN: + if(!p->v[ p->cursor ]){ + p->v[ p->cursor ] = TRUE; + kbd_draw_note(obj, FALSE, p->cursor); + cui_handler_call(obj, CUI_EVT_BUTTON, p->cursor | 0x100); /* ON flag */ + } + break; + } + return TRUE; + default: + return FALSE; + } + return TRUE; +} + +void +cui_kbd_set(cui obj, int note, int v) +{ + cui_kbd p = (cui_kbd)obj; + p->v[ note ] = v; + kbd_draw_note(obj, cui_focus_get() == obj, note); +} + +int +cui_kbd_get(cui obj, int note) +{ + cui_kbd p = (cui_kbd)obj; + return p->v[ note ]; +} + +/**/ + +struct test4_ch{ + int prog, vol, velo; + cui kbd; +}; + +struct test4{ + cui mn_ch, prog, vol, velo; + int midi_ch, bak_ch; + struct test4_ch ch[16]; +}; + +int +t4_btn_hdr(cui obj, int evt, int val, void *prm) +{ + /* CUI_EVT_BUTTON */ + + struct test4 *p = (struct test4 *)prm; + struct test4_ch *ch = &p->ch[ p->midi_ch ]; + + if(obj == p->mn_ch){ + cui_num_vp_set(p->prog, &ch->prog); + cui_num_vp_set(p->vol, &ch->vol); + cui_num_vp_set(p->velo, &ch->velo); + + cui_hide(p->ch[ p->bak_ch ].kbd); + cui_show(ch->kbd); + p->bak_ch = p->midi_ch; + }else if(obj == p->prog){ + set_char2_wrt((0xc<<4) | p->midi_ch, ch->prog); + }else if(obj == p->vol){ + set_char3_wrt((0xb<<4) | p->midi_ch, 7 /* vol msb */, ch->vol); + }else if(obj == ch->kbd){ + if(val & 0x100) set_char3_wrt((9<<4) | p->midi_ch, val & ~0x100, ch->velo); + else set_char3_wrt((8<<4) | p->midi_ch, val & ~0x100, ch->velo); + }else return FALSE; + return TRUE; +} + int main(int ac, char **av) { @@ -254,16 +497,21 @@ cui bs3 = cui_base_new(scp->view, quit->x, cui_y2(quit)+1, 0, 0); struct test3 t3; + + cui bs4 = cui_base_new(scp->view, quit->x, cui_y2(quit)+1, 0, 0); + struct test4 t4; + cui obj; char *cmd = "./add_delta | ./prog31 -V0 -q -play"; int div = 96; int i; - cui tab_sheets[] = { bs1, bs2, bs3 }; + cui tab_sheets[] = { bs1, bs2, bs3, bs4 }; cui_hide(bs1); cui_hide(bs2); cui_hide(bs3); + cui_hide(bs4); lb_buf[0] = '\0'; cui_label_str_set(lb, lb_buf); @@ -351,12 +599,44 @@ cui_handler_call(t3.mn_ch, CUI_EVT_BUTTON, cui_menu_int_get(t3.mn_ch)); + /* t4 */ + + t4.midi_ch = t4.bak_ch = 0; + for(i=0; i<16; i++){ + t4.ch[i].prog = 0; + t4.ch[i].vol = 0; + t4.ch[i].velo = 64; + t4.ch[i].kbd = cui_kbd_new(bs4, 0, 8, 50); + cui_hide(t4.ch[i].kbd); + cui_bind(t4.ch[i].kbd, CUI_EVT_BUTTON, t4_btn_hdr, &t4); + } + obj = cui_label_new(bs4, 0, 0, "midi ch : "); + t4.mn_ch = cui_menu_int_new(bs4, cui_x2(obj), 0, 4, 0, 0, 15); + cui_menu_int_vp_set(t4.mn_ch, &t4.midi_ch); + + obj = cui_label_new(bs4, 2, 2, "prog num : "); + t4.prog = cui_num_new(bs4, cui_x2(obj), 2, 8, 0, 0, 127, 0); + + obj = cui_label_new(bs4, 2, 4, "vol (msb) : "); + t4.vol = cui_num_new(bs4, cui_x2(obj), 4, 8, 0, 0, 127, 0); + + obj = cui_label_new(bs4, 2, 6, "velo : "); + t4.velo = cui_num_new(bs4, cui_x2(obj), 6, 8, 0, 0, 127, 0); + + cui_wh_fit(bs4); + + cui_bind(t4.mn_ch, CUI_EVT_BUTTON, t4_btn_hdr, &t4); + cui_bind(t4.prog, CUI_EVT_BUTTON, t4_btn_hdr, &t4); + cui_bind(t4.vol, CUI_EVT_BUTTON, t4_btn_hdr, &t4); + + cui_handler_call(t4.mn_ch, CUI_EVT_BUTTON, cui_menu_int_get(t4.mn_ch)); + /**/ - cui_show(bs3); + cui_show(bs4); cui_tab_new(scp->view, quit->x, quit->y, -1, - (char *[]){"1st", "2nd", "3rd", NULL}, - tab_sheets, 2); + (char *[]){"1st", "2nd", "3rd", "4th", NULL}, + tab_sheets, 3); cui_wh_fit(scp->view); cui_wh_exp(bs1);