--- cui_midi.c- Sat Apr 19 22:00:00 2014 +++ cui_midi.c Sun Apr 20 22:00:00 2014 @@ -2,6 +2,7 @@ #include #include #include +#include #include "cui/cui.h" #include "cui/scpanel.h" #include "cui/button.h" @@ -239,13 +240,16 @@ int play_mode; int cursor; cui sheet; + + cui oct, name, note_no, freq; } *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); +void cui_kbd_cursor_set(cui obj, int note); +int cui_kbd_cursor_get(cui obj); #include "cui/key.h" @@ -280,9 +284,10 @@ { cui_kbd p = (cui_kbd)obj; int i; + char *name_lst[] = { "G#", "G", "F#", "F", "E", "D#", "D", "C#", "C", "B", "A#", "A", NULL }; - cui_base_init(obj, parent, x, y, w, 2); - p->sheet = cui_base_new(obj, 0, 0, kbd_note_x(128), 2); + cui_base_init(obj, parent, x, y, w, 3); + p->sheet = cui_base_new(obj, 0, 1, kbd_note_x(128), 2); obj->flags |= CUI_FLG_CAN_FOCUS; for(i=0; i<128; i++) p->v[i] = FALSE; @@ -291,6 +296,16 @@ cui_x_set(p->sheet, -kbd_note_x(p->cursor)); cui_bind(obj, CUI_EVT_DRAW | CUI_EVT_KEY, cui_kbd_hdr, NULL); + + p->oct = cui_menu_int_new(obj, 0, 0, 2+1, 5, -1, 9); + p->name = cui_menu_popup_new(obj, cui_x2(p->oct), 0, 2+1, name_lst, 11); + p->note_no = cui_num_new(obj, cui_x2(p->name)+2, 0, 3+3, 69, 0, 127, 0); + p->freq = cui_num_dbl_new(obj, cui_x2(p->note_no)+2, 0, 7+3, 440.0, 8.2, 12543.9, 0.1, 0); + + cui_bind(p->oct, CUI_EVT_BUTTON, cui_kbd_hdr, obj); + cui_bind(p->name, CUI_EVT_BUTTON, cui_kbd_hdr, obj); + cui_bind(p->note_no, CUI_EVT_BUTTON, cui_kbd_hdr, obj); + cui_bind(p->freq, CUI_EVT_BUTTON, cui_kbd_hdr, obj); } static void @@ -354,6 +369,7 @@ int cui_kbd_hdr(cui obj, int evt, int val, void *prm) { + cui ev_obj = obj; cui_kbd p = (cui_kbd)obj; switch(evt){ @@ -384,6 +400,8 @@ } kbd_draw_note(obj, FALSE, p->cursor--); kbd_draw_note(obj, FALSE, p->cursor); + cui_num_set(p->note_no, p->cursor); + cui_handler_call(p->note_no, CUI_EVT_BUTTON, p->cursor); } break; case CUI_KEY_RIGHT: @@ -395,6 +413,8 @@ } kbd_draw_note(obj, FALSE, p->cursor++); kbd_draw_note(obj, FALSE, p->cursor); + cui_num_set(p->note_no, p->cursor); + cui_handler_call(p->note_no, CUI_EVT_BUTTON, p->cursor); } break; case CUI_KEY_UP: @@ -413,6 +433,43 @@ break; } return TRUE; + case CUI_EVT_BUTTON: + obj = (cui)prm; + p = (cui_kbd)obj; + + if(ev_obj == p->note_no){ + int note = val; + int oct_v = (note - 9 + 12) / 12 - 1; + int name_v = (note - 9) % 12; + double fq = 440 * pow(2, (note - 69) / 12.0); + + if(cui_menu_int_get(p->oct) != oct_v) cui_menu_int_set(p->oct, oct_v); + if(cui_menu_popup_get(p->name) != 11-name_v) cui_menu_popup_set(p->name, 11-name_v); + if(cui_num_dbl_get(p->freq) != fq) cui_num_dbl_set(p->freq, fq); + if(cui_kbd_cursor_get(obj) != note) cui_kbd_cursor_set(obj, note); + }else if(ev_obj == p->oct){ + int oct_v = val; + int name_v = 11 - cui_menu_popup_get(p->name); + int note = oct_v * 12 + name_v + 9; + if(cui_num_get(p->note_no) != note){ + cui_num_set(p->note_no, note); + cui_handler_call(p->note_no, CUI_EVT_BUTTON, note); + } + }else if(ev_obj == p->name){ + int oct_v = cui_menu_int_get(p->oct); + int name_v = 11 - val; + int note = oct_v * 12 + name_v + 9; + if(cui_num_get(p->note_no) != note){ + cui_num_set(p->note_no, note); + cui_handler_call(p->note_no, CUI_EVT_BUTTON, note); + } + }else if(ev_obj == p->freq){ + double fq = cui_num_dbl_get(p->freq); + int note = (int)( ( log(fq/440) / log(2) ) * 12 + 69 + 0.5 ); + cui_num_set(p->note_no, note); + cui_handler_call(p->note_no, CUI_EVT_BUTTON, note); + }else return FALSE; + break; default: return FALSE; } @@ -432,6 +489,36 @@ { cui_kbd p = (cui_kbd)obj; return p->v[ note ]; +} + +void +cui_kbd_cursor_set(cui obj, int note) +{ + cui_kbd p = (cui_kbd)obj; + int bak = p->cursor; + int x, mv = 0; + + if(note < 0) note = 0; + if(note > 127) note = 127; + if(bak == note) return; + + x = p->sheet->x + kbd_note_x(note); + if(x < 0) mv = -x; + else if(x > obj->w-1) mv = -(x - (obj->w-1)); + if(mv != 0){ + cui_x_set(p->sheet, p->sheet->x + mv); + cui_draw(obj); + } + p->cursor = note; + kbd_draw_note(obj, FALSE, bak); + kbd_draw_note(obj, FALSE, p->cursor); +} + +int +cui_kbd_cursor_get(cui obj) +{ + cui_kbd p = (cui_kbd)obj; + return p->cursor; } /**/