// generated by Fast Light User Interface Designer (fluid) version 1.0300 #include "VirKeyboard.h" //Copyright (c) 2002-2005 Nasca Octavian Paul //License: GNU GPL version 2 or later static const int keyspos[12]={0,-1,1,-2,2,3,-4,4,-5,5,-6,6}; static const int keysoct1qwerty[]={'q','2','w','3','e','r','5','t','6','y','7','u','i','9','o','0','p','[','=',']','\\',FL_Enter,0}; static const int keysoct2qwerty[]={'z','s','x','d','c','v','g','b','h','n','j','m',',','l','.',';','/',0}; static const int keysoct1dw[]={'\'','2',',','3','.','p','5','y','6','f','7','g','c','9','r','0','l','/',']','=','\\',FL_Enter,0}; static const int keysoct2dw[]={';','o','q','e','j','k','i','x','d','b','h','m','w','n','v','s','z',0}; static const int keysoct1qwertz[]={'q','2','w','3','e','r','5','t','6','z','7','u','i','9','o','0','p',252,'\'','+','\\',FL_Enter,0}; static const int keysoct2qwertz[]={'y','s','x','d','c','v','g','b','h','n','j','m',',','l','.',246,'-',0}; static const int keysoct1az[]={'a',233,'z','\"','e','r','(','t','-','y',232,'u','i',231,'o',224,'p',65106,'=','$',0}; static const int keysoct2az[]={'w','s','x','d','c','v','g','b','h','n','j',',',';','l',':','m','!',0}; VirKeys::VirKeys(int x,int y, int w, int h, const char *label):Fl_Box(x,y,w,h,label) { master=NULL; } void VirKeys::init(Master *master_) { master=master_; for (int i=0;i=0){//white keys if (pressed[i]==0) fl_color(250,240,230); else fl_color(FL_BLUE); fl_rectf(ox+(kv+7*noct)*SIZE_WHITE+3,oy+ly*3/5+2, SIZE_WHITE-4,ly*2/5-3); } else {//black keys kv=keyspos[(i+1)%12]; if (pressed[i]==0) fl_color(FL_BLACK); else fl_color(FL_BLUE); fl_rectf(ox+(kv+7*noct)*SIZE_WHITE-SIZE_BLACK/2+2,oy+2, SIZE_BLACK-3,ly*3/5-5); }; }; } int VirKeys::handle(int event) { int i; int ly=h(); int x_=Fl::event_x()-x(); int y_=Fl::event_y()-y(); if ( (x_<0)&&(x_>w()) && (y_<0)&&(y_>h())){ return(0); }; if ((event==FL_PUSH)||(event==FL_DRAG)||(event==FL_RELEASE)){ int kpos=-1; if (y_>ly*3/5){//white keys int pos=x_/SIZE_WHITE; if (pos<0) return(1); for (i=0;i<12;i++) { if (pos%7==keyspos[i]) { kpos=pos/7*12+i; break; }; }; } else {//black keys int pos=(x_+SIZE_WHITE/2)/SIZE_WHITE; if (pos<0) return(1); for (i=1;i<12;i++) { if (pos%7==-keyspos[i]) { kpos=pos/7*12+i; break; }; }; }; if ((kpos!=-1)&&((event==FL_PUSH)||(event==FL_DRAG))&& (Fl::event_shift()==0)) { presskey(kpos,1,1); }; if ((event==FL_PUSH)&&(Fl::event_shift()!=0)) { if (pressed[kpos]==0) presskey(kpos,0,1); else relasekey(kpos,1); }; if ((event==FL_RELEASE)&&(Fl::event_shift()==0)) relaseallkeys(1); take_focus(); }; const int *keysoct1=keysoct1qwerty; const int *keysoct2=keysoct2qwerty; if (config.cfg.VirKeybLayout==2) { keysoct1=keysoct1dw; keysoct2=keysoct2dw; }else if (config.cfg.VirKeybLayout==3) { keysoct1=keysoct1qwertz; keysoct2=keysoct2qwertz; }else if (config.cfg.VirKeybLayout==4) { keysoct1=keysoct1az; keysoct2=keysoct2az; }; if ((event==FL_KEYDOWN)||(event==FL_KEYUP)){ int key=Fl::event_key(); int kpos=-1; for (i=0;keysoct1[i]!=0;i++) if (key==keysoct1[i]) kpos=i+12*keyoct1; for (i=0;keysoct2[i]!=0;i++) if (key==keysoct2[i]) kpos=i+12*keyoct2; if (kpos==-1) return(0); if ((event==FL_KEYUP) && (Fl::event_key(key)==0) && (Fl::get_key(key)!=0)) return(0); if (event==FL_KEYDOWN) presskey(kpos,0,2); else relasekey(kpos,2); }; return(1); } void VirKeys::presskey(int nk,int exclusive,int type) { //Exclusive means that multiple keys can be pressed at once //when the user uses the shift key if (nk>=N_OCT*12) return; if ((nk<0)&&(exclusive==0)) { relaseallkeys(type); return; }; if (nk<0) return; if (pressed[nk]!=0) return;//the key is already pressed if (exclusive!=0) relaseallkeys(type); pressed[nk]=type; damage(1); float vel=midivel; if (rndvelocity!=0){ vel=midivel*(127.0-rndvelocity)/127.0+RND*rndvelocity; }; pthread_mutex_lock(&master->mutex); master->NoteOn(midich,nk+midioct*12,(int)vel); pthread_mutex_unlock(&master->mutex); } void VirKeys::relasekey(int nk,int type) { if ((nk<0)||(nk>=N_OCT*12)) return; if (pressed[nk]==0) return;//the key is not pressed if ((type!=0)&&(pressed[nk]!=type)) return; pressed[nk]=0; damage(1); pthread_mutex_lock(&master->mutex); master->NoteOff(midich,nk+12*midioct); pthread_mutex_unlock(&master->mutex); } void VirKeys::relaseallkeys(int type) { for (int i=0;ihide(); } void VirKeyboard::cb_virkeyboardwindow(Fl_Double_Window* o, void* v) { ((VirKeyboard*)(o->user_data()))->cb_virkeyboardwindow_i(o,v); } void VirKeyboard::cb_qwer_i(Fl_Counter* o, void*) { relaseallkeys(); virkeys->keyoct1=(int) o->value(); virkeys->take_focus(); } void VirKeyboard::cb_qwer(Fl_Counter* o, void* v) { ((VirKeyboard*)(o->parent()->user_data()))->cb_qwer_i(o,v); } void VirKeyboard::cb_zxcv_i(Fl_Counter* o, void*) { relaseallkeys(); virkeys->keyoct2=(int) o->value(); virkeys->take_focus(); } void VirKeyboard::cb_zxcv(Fl_Counter* o, void* v) { ((VirKeyboard*)(o->parent()->user_data()))->cb_zxcv_i(o,v); } void VirKeyboard::cb_Vel_i(Fl_Value_Slider* o, void*) { virkeys->midivel=(int) o->value(); virkeys->take_focus(); } void VirKeyboard::cb_Vel(Fl_Value_Slider* o, void* v) { ((VirKeyboard*)(o->parent()->user_data()))->cb_Vel_i(o,v); } void VirKeyboard::cb_Oct_i(Fl_Counter* o, void*) { relaseallkeys(); virkeys->midioct=(int) o->value(); virkeys->take_focus(); } void VirKeyboard::cb_Oct(Fl_Counter* o, void* v) { ((VirKeyboard*)(o->parent()->user_data()))->cb_Oct_i(o,v); } void VirKeyboard::cb_Close_i(Fl_Button*, void*) { relaseallkeys(); virkeyboardwindow->hide(); } void VirKeyboard::cb_Close(Fl_Button* o, void* v) { ((VirKeyboard*)(o->parent()->user_data()))->cb_Close_i(o,v); } void VirKeyboard::cb_Cval_i(Fl_Value_Slider* o, void*) { int ctl=midictl; pthread_mutex_lock(&master->mutex); master->SetController(virkeys->midich,ctl,(int) o->value()); pthread_mutex_unlock(&master->mutex); virkeys->take_focus(); } void VirKeyboard::cb_Cval(Fl_Value_Slider* o, void* v) { ((VirKeyboard*)(o->parent()->user_data()))->cb_Cval_i(o,v); } void VirKeyboard::cb_Controller_i(Fl_Choice* o, void*) { switch((int) o->value()+1){ case 1: midictl=C_modwheel; break; case 2: midictl=C_volume; break; case 3: midictl=C_panning; break; case 4: midictl=C_expression; break; case 5: midictl=C_sustain; break; case 6: midictl=C_portamento; break; case 7: midictl=C_filterq; break; case 8: midictl=C_filtercutoff; break; case 9: midictl=C_bandwidth; break; case 10: midictl=C_fmamp; break; case 11: midictl=C_resonance_center; break; case 12: midictl=C_resonance_bandwidth; break; default: midictl=C_NULL; break; }; virkeys->take_focus(); } void VirKeyboard::cb_Controller(Fl_Choice* o, void* v) { ((VirKeyboard*)(o->parent()->user_data()))->cb_Controller_i(o,v); } Fl_Menu_Item VirKeyboard::menu_Controller[] = { {"01: Mod.Wheel", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, {"07: Volume", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, {"10: Panning", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, {"11: Expression", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, {"64: Sustain", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, {"65: Portamento", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, {"71: Filter Q", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, {"74: Filter Freq.", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, {"75: Bandwidth", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, {"76: FM Gain", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, {"77: Res. c. freq", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, {"78: Res. bw.", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, {0,0,0,0,0,0,0,0,0} }; void VirKeyboard::cb_pitchwheelroller_i(Fl_Roller* o, void*) { pthread_mutex_lock(&master->mutex); master->SetController(virkeys->midich,C_pitchwheel,-(int) o->value()); pthread_mutex_unlock(&master->mutex); virkeys->take_focus(); } void VirKeyboard::cb_pitchwheelroller(Fl_Roller* o, void* v) { ((VirKeyboard*)(o->parent()->user_data()))->cb_pitchwheelroller_i(o,v); } void VirKeyboard::cb_R_i(Fl_Button*, void*) { pitchwheelroller->value(0); pitchwheelroller->do_callback(); } void VirKeyboard::cb_R(Fl_Button* o, void* v) { ((VirKeyboard*)(o->parent()->user_data()))->cb_R_i(o,v); } void VirKeyboard::cb_Vrnd_i(WidgetPDial* o, void*) { virkeys->rndvelocity=(int) o->value(); } void VirKeyboard::cb_Vrnd(WidgetPDial* o, void* v) { ((VirKeyboard*)(o->parent()->user_data()))->cb_Vrnd_i(o,v); } void VirKeyboard::cb_partrcv_i(Fl_Choice* o, void*) { relaseallkeys(); virkeys->midich=(int) o->value(); virkeys->take_focus(); } void VirKeyboard::cb_partrcv(Fl_Choice* o, void* v) { ((VirKeyboard*)(o->parent()->user_data()))->cb_partrcv_i(o,v); } Fl_Double_Window* VirKeyboard::make_window() { { virkeyboardwindow = new Fl_Double_Window(650, 130, "Virtual Keyboard - ZynAddSubFX"); virkeyboardwindow->callback((Fl_Callback*)cb_virkeyboardwindow, (void*)(this)); { VirKeys* o = virkeys = new VirKeys(10, 10, 590, 80, "Keyboard"); virkeys->box(FL_FLAT_BOX); virkeys->color((Fl_Color)17); virkeys->selection_color(FL_BACKGROUND_COLOR); virkeys->labeltype(FL_NORMAL_LABEL); virkeys->labelfont(0); virkeys->labelsize(14); virkeys->labelcolor(FL_FOREGROUND_COLOR); virkeys->align(Fl_Align(FL_ALIGN_CENTER)); virkeys->when(FL_WHEN_RELEASE); o->init(master); } // VirKeys* virkeys { Fl_Counter* o = new Fl_Counter(380, 95, 45, 15, "\"qwer..\" Oct"); o->tooltip("keys \"q2w3er5t6y...\" octave"); o->type(1); o->labelsize(10); o->minimum(0); o->maximum(5); o->step(1); o->textfont(1); o->textsize(10); o->callback((Fl_Callback*)cb_qwer); o->align(Fl_Align(FL_ALIGN_LEFT)); o->when(FL_WHEN_RELEASE_ALWAYS); o->value(virkeys->keyoct1); } // Fl_Counter* o { Fl_Counter* o = new Fl_Counter(380, 110, 45, 15, "\"zxcv..\" Oct"); o->tooltip("keys \"zsxdcvgbh...\" octave"); o->type(1); o->labelsize(10); o->minimum(0); o->maximum(5); o->step(1); o->textfont(1); o->textsize(10); o->callback((Fl_Callback*)cb_zxcv); o->align(Fl_Align(FL_ALIGN_LEFT)); o->when(FL_WHEN_RELEASE_ALWAYS); o->value(virkeys->keyoct2); } // Fl_Counter* o { Fl_Value_Slider* o = new Fl_Value_Slider(95, 105, 100, 15, "Vel"); o->tooltip("Velocity"); o->type(5); o->box(FL_FLAT_BOX); o->labelsize(10); o->minimum(1); o->maximum(127); o->step(1); o->callback((Fl_Callback*)cb_Vel); o->align(Fl_Align(FL_ALIGN_TOP_LEFT)); o->value(virkeys->midivel); } // Fl_Value_Slider* o { Fl_Counter* o = new Fl_Counter(255, 100, 55, 20, "Oct."); o->tooltip("Midi Octave"); o->type(1); o->labelsize(11); o->minimum(0); o->maximum(5); o->step(1); o->textfont(1); o->textsize(11); o->callback((Fl_Callback*)cb_Oct); o->align(Fl_Align(FL_ALIGN_LEFT)); o->when(FL_WHEN_RELEASE_ALWAYS); o->value(virkeys->midioct); } // Fl_Counter* o { Fl_Button* o = new Fl_Button(545, 105, 55, 20, "Close"); o->box(FL_THIN_UP_BOX); o->callback((Fl_Callback*)cb_Close); } // Fl_Button* o { Fl_Value_Slider* o = new Fl_Value_Slider(605, 10, 15, 115, "Cval"); o->tooltip("Controller value"); o->type(2); o->box(FL_ENGRAVED_BOX); o->selection_color((Fl_Color)229); o->labelsize(8); o->minimum(127); o->maximum(0); o->step(1); o->value(64); o->textsize(7); o->callback((Fl_Callback*)cb_Cval); o->align(Fl_Align(FL_ALIGN_TOP_LEFT)); } // Fl_Value_Slider* o { Fl_Choice* o = new Fl_Choice(435, 105, 100, 15, "Controller"); o->down_box(FL_BORDER_BOX); o->labelsize(10); o->textfont(1); o->textsize(10); o->callback((Fl_Callback*)cb_Controller); o->align(Fl_Align(FL_ALIGN_TOP_LEFT)); o->when(FL_WHEN_RELEASE_ALWAYS); o->menu(menu_Controller); midictl=C_filtercutoff;o->value(7); } // Fl_Choice* o { pitchwheelroller = new Fl_Roller(625, 10, 20, 95, "Pwh"); pitchwheelroller->tooltip("Pitch Wheel"); pitchwheelroller->box(FL_PLASTIC_UP_BOX); pitchwheelroller->labelsize(8); pitchwheelroller->minimum(-8192); pitchwheelroller->maximum(8192); pitchwheelroller->step(64); pitchwheelroller->callback((Fl_Callback*)cb_pitchwheelroller); pitchwheelroller->align(Fl_Align(FL_ALIGN_TOP)); pitchwheelroller->when(3); } // Fl_Roller* pitchwheelroller { Fl_Button* o = new Fl_Button(625, 110, 20, 15, "R"); o->tooltip("Reset Pitch Bend"); o->box(FL_THIN_UP_BOX); o->labelfont(1); o->callback((Fl_Callback*)cb_R); } // Fl_Button* o { WidgetPDial* o = new WidgetPDial(205, 105, 20, 20, "Vrnd"); o->tooltip("Velocity Randomness"); o->box(FL_ROUND_UP_BOX); o->color(FL_BACKGROUND_COLOR); o->selection_color(FL_INACTIVE_COLOR); o->labeltype(FL_NORMAL_LABEL); o->labelfont(0); o->labelsize(10); o->labelcolor(FL_FOREGROUND_COLOR); o->maximum(127); o->step(1); o->callback((Fl_Callback*)cb_Vrnd); o->align(Fl_Align(129)); o->when(FL_WHEN_CHANGED); o->value(virkeys->rndvelocity); } // WidgetPDial* o { Fl_Choice* o = partrcv = new Fl_Choice(20, 105, 65, 20, "MIDI Ch."); partrcv->tooltip("Send to Midi Channel"); partrcv->down_box(FL_BORDER_BOX); partrcv->labelsize(10); partrcv->textfont(1); partrcv->textsize(10); partrcv->callback((Fl_Callback*)cb_partrcv); partrcv->align(Fl_Align(FL_ALIGN_TOP_LEFT)); char nrstr[10]; for(int i=0;iadd(nrstr); else o->add("Drum10");}; o->value(virkeys->midich); } // Fl_Choice* partrcv virkeyboardwindow->end(); } // Fl_Double_Window* virkeyboardwindow return virkeyboardwindow; } VirKeyboard::VirKeyboard(Master *master_) { master=master_; midictl=75; make_window(); } VirKeyboard::~VirKeyboard() { delete virkeyboardwindow; } void VirKeyboard::show() { virkeyboardwindow->show(); } void VirKeyboard::relaseallkeys() { virkeys->relaseallkeys(0); }