gdBeatsInput::gdBeatsInput() : gWindow(164, 60, "Beats") { if (G_Conf.beatsX) resize(G_Conf.beatsX, G_Conf.beatsY, w(), h()); set_modal(); beats = new gInput(8, 8, 35, 20); bars = new gInput(47, 8, 35, 20); ok = new gClick(86, 8, 70, 20, "Ok"); resizeRec = new gCheck(8, 40, 12, 12, "resize recorded actions"); end(); char buf_bars[3]; sprintf(buf_bars, "%d", G_Mixer.bars); char buf_beats[3]; sprintf(buf_beats, "%d", G_Mixer.beats); beats->maximum_size(2); beats->value(buf_beats); beats->type(FL_INT_INPUT); bars->maximum_size(2); bars->value(buf_bars); bars->type(FL_INT_INPUT); ok->shortcut(FL_Enter); ok->callback(cb_update_batt, (void*)this); resizeRec->value(G_Conf.resizeRecordings); gu_setFavicon(this); setId(WID_BEATS); show(); }
gdMidiOutputSetup::gdMidiOutputSetup(MidiChannel *ch) : gWindow(300, 64, "Midi Output Setup"), ch(ch) { begin(); enableOut = new gCheck(x()+8, y()+8, 150, 20, "Enable MIDI output"); chanListOut = new gChoice(w()-108, y()+8, 100, 20); save = new gButton(w()-88, chanListOut->y()+chanListOut->h()+8, 80, 20, "Save"); cancel = new gButton(w()-88-save->w()-8, save->y(), 80, 20, "Cancel"); end(); fillChanMenu(chanListOut); if (ch->midiOut) enableOut->value(1); else chanListOut->deactivate(); chanListOut->value(ch->midiOutChan); enableOut->callback(cb_enableChanList, (void*)this); save->callback(cb_save, (void*)this); cancel->callback(cb_cancel, (void*)this); set_modal(); gu_setFavicon(this); show(); }
gdPluginList::gdPluginList(int stackType, Channel *ch) : gWindow(468, 204), ch(ch), stackType(stackType) { if (G_Conf.pluginListX) resize(G_Conf.pluginListX, G_Conf.pluginListY, w(), h()); list = new Fl_Scroll(8, 8, 476, 188); list->type(Fl_Scroll::VERTICAL); list->scrollbar.color(COLOR_BG_0); list->scrollbar.selection_color(COLOR_BG_1); list->scrollbar.labelcolor(COLOR_BD_1); list->scrollbar.slider(G_BOX); list->begin(); refreshList(); list->end(); end(); set_non_modal(); if (stackType == PluginHost::MASTER_OUT) label("Master Out Plugins"); else if (stackType == PluginHost::MASTER_IN) label("Master In Plugins"); else { char tmp[32]; sprintf(tmp, "Channel %d Plugins", ch->index+1); copy_label(tmp); } gu_setFavicon(this); show(); }
gdKeyGrabber::gdKeyGrabber(int ch, gdConfig *w) : Fl_Window(300, 100, "Key configuration"), w(w), ch(ch) { set_modal(); text = new gBox(10, 10, 280, 80, "Press a key (esc to quit):"); gu_setFavicon(this); show(); }
int gdConfirmWin(const char *title, const char *msg) { Fl_Window *win = new Fl_Window( (Fl::w() / 2) - 150, (Fl::h() / 2) - 47, 300, 90, title); win->set_modal(); win->begin(); new gBox(10, 10, 280, 40, msg); gClick *ok = new gClick(212, 62, 80, 20, "Ok"); gClick *ko = new gClick(124, 62, 80, 20, "Cancel"); win->end(); ok->shortcut(FL_Enter); gu_setFavicon(win); win->show(); /* no callbacks here. readqueue() check the event stack. */ int r = 0; while (true) { Fl_Widget *o = Fl::readqueue(); if (!o) Fl::wait(); else if (o == ok) {r = 1; break;} else if (o == ko) {r = 0; break;} } //delete win; win->hide(); return r; }
gdPluginWindow::gdPluginWindow(Plugin *pPlugin) : gWindow(400, 156), pPlugin(pPlugin) // 350 { set_non_modal(); gLiquidScroll *list = new gLiquidScroll(8, 8, w()-16, h()-16); list->type(Fl_Scroll::VERTICAL_ALWAYS); list->begin(); int numParams = pPlugin->getNumParams(); for (int i=0; i<numParams; i++) new Parameter(i, pPlugin, list->x(), list->y()+(i*24), list->w()); list->end(); end(); char name[256]; pPlugin->getProduct(name); if (strcmp(name, " ")==0) pPlugin->getName(name); label(name); size_range(400, (24*1)+12); resizable(list); gu_setFavicon(this); show(); }
gdMidiOutputMidiCh::gdMidiOutputMidiCh(MidiChannel *ch) : gdMidiOutput(300, 168), ch(ch) { setTitle(ch->index+1); begin(); enableOut = new gCheck(x()+8, y()+8, 150, 20, "Enable MIDI output"); chanListOut = new gChoice(w()-108, y()+8, 100, 20); enableLightning = new gCheck(x()+8, chanListOut->y()+chanListOut->h()+8, 120, 20, "Enable MIDI lightning output"); new gLearner(x()+8, enableLightning->y()+enableLightning->h()+8, w()-16, "playing", cb_learn, &ch->midiOutLplaying); new gLearner(x()+8, enableLightning->y()+enableLightning->h()+32, w()-16, "mute", cb_learn, &ch->midiOutLmute); new gLearner(x()+8, enableLightning->y()+enableLightning->h()+56, w()-16, "solo", cb_learn, &ch->midiOutLsolo); close = new gButton(w()-88, enableLightning->y()+enableLightning->h()+84, 80, 20, "Close"); end(); chanListOut->add("Channel 1"); chanListOut->add("Channel 2"); chanListOut->add("Channel 3"); chanListOut->add("Channel 4"); chanListOut->add("Channel 5"); chanListOut->add("Channel 6"); chanListOut->add("Channel 7"); chanListOut->add("Channel 8"); chanListOut->add("Channel 9"); chanListOut->add("Channel 10"); chanListOut->add("Channel 11"); chanListOut->add("Channel 12"); chanListOut->add("Channel 13"); chanListOut->add("Channel 14"); chanListOut->add("Channel 15"); chanListOut->add("Channel 16"); chanListOut->value(0); if (ch->midiOut) enableOut->value(1); else chanListOut->deactivate(); if (ch->midiOutL) enableLightning->value(1); chanListOut->value(ch->midiOutChan); enableOut->callback(cb_enableChanList, (void*)this); close->callback(cb_close, (void*)this); set_modal(); gu_setFavicon(this); show(); }
gdMainWindow::gdMainWindow(int W, int H, const char *title, int argc, char **argv) : gWindow(W, H, title) { Fl::visible_focus(0); Fl::background(25, 25, 25); Fl::set_boxtype(G_BOX, gDrawBox, 1, 1, 2, 2); // custom box G_BOX size_range(GUI_WIDTH, GUI_HEIGHT); menu = new gMenu(8, -1); inOut = new gInOut(408, 8); controller = new gController(8, 39); timing = new gTiming(632, 39); beatMeter = new gBeatMeter(100, 83, 609, 20); keyboard = new gKeyboard(8, 122, w()-16, 380); /* zone 1 - menus, and I/O tools */ Fl_Group *zone1 = new Fl_Group(8, 8, W-16, 20); zone1->add(menu); zone1->resizable(new Fl_Box(300, 8, 80, 20)); zone1->add(inOut); /* zone 2 - controller and timing tools */ Fl_Group *zone2 = new Fl_Group(8, controller->y(), W-16, controller->h()); zone2->add(controller); zone2->resizable(new Fl_Box(controller->x()+controller->w()+4, zone2->y(), 80, 20)); zone2->add(timing); /* zone 3 - beat meter */ Fl_Group *zone3 = new Fl_Group(8, beatMeter->y(), W-16, beatMeter->h()); zone3->add(beatMeter); /* zone 4 - the keyboard (Fl_Group is unnecessary here, keyboard is * a group by itself) */ resizable(keyboard); add(zone1); add(zone2); add(zone3); add(keyboard); callback(cb_endprogram); gu_setFavicon(this); show(argc, argv); }
void gdAlert(const char *c) { Fl_Window *modal = new Fl_Window( (Fl::w() / 2) - 150, (Fl::h() / 2) - 47, 300, 90, "Alert"); modal->set_modal(); modal->begin(); gBox *box = new gBox(10, 10, 280, 40, c); gClick *b = new gClick(210, 60, 80, 20, "Close"); modal->end(); box->labelsize(GUI_FONT_SIZE_BASE); b->callback(__cb_window_closer, (void *)modal); b->shortcut(FL_Enter); gu_setFavicon(modal); modal->show(); }
gdKeyGrabber::gdKeyGrabber(Channel *ch) : gWindow(300, 126, "Key configuration"), ch(ch) { set_modal(); text = new gBox(8, 8, 284, 80, ""); clear = new gClick(w()-88, text->y()+text->h()+8, 80, 20, "Clear"); cancel = new gClick(clear->x()-88, clear->y(), 80, 20, "Close"); end(); clear->callback(cb_clear, (void*)this); cancel->callback(cb_cancel, (void*)this); updateText(ch->key); gu_setFavicon(this); show(); }
gdMidiOutputSampleCh::gdMidiOutputSampleCh(SampleChannel *ch) : gdMidiOutput(300, 140), ch(ch) { setTitle(ch->index+1); enableLightning = new gCheck(8, 8, 120, 20, "Enable MIDI lightning output"); new gLearner(8, enableLightning->y()+enableLightning->h()+8, w()-16, "playing", cb_learn, &ch->midiOutLplaying); new gLearner(8, enableLightning->y()+enableLightning->h()+32, w()-16, "mute", cb_learn, &ch->midiOutLmute); new gLearner(8, enableLightning->y()+enableLightning->h()+56, w()-16, "solo", cb_learn, &ch->midiOutLsolo); close = new gButton(w()-88, enableLightning->y()+enableLightning->h()+84, 80, 20, "Close"); close->callback(cb_close, (void*)this); enableLightning->value(ch->midiOutL); enableLightning->callback(cb_enableLightning, (void*)this); set_modal(); gu_setFavicon(this); show(); }
gdBpmInput::gdBpmInput(const char *label) : gWindow(144, 36, "Bpm") { if (G_Conf.bpmX) resize(G_Conf.bpmX, G_Conf.bpmY, w(), h()); set_modal(); input_a = new gInput(8, 8, 30, 20); input_b = new gInput(42, 8, 20, 20); ok = new gClick(66, 8, 70, 20, "Ok"); end(); char a[4]; snprintf(a, 4, "%d", (int) G_Mixer.bpm); char b[2]; for (unsigned i=0; i<strlen(label); i++) // looking for the dot if (label[i] == '.') { snprintf(b, 2, "%c", label[i+1]); break; } input_a->maximum_size(3); input_a->type(FL_INT_INPUT); input_a->value(a); input_b->maximum_size(1); input_b->type(FL_INT_INPUT); input_b->value(b); ok->shortcut(FL_Enter); ok->callback(cb_update_bpm, (void*)this); gu_setFavicon(this); setId(WID_BPM); show(); }
gdEditor::gdEditor(SampleChannel *ch) : gWindow(640, 480), ch(ch) { set_non_modal(); if (G_Conf.sampleEditorX) resize(G_Conf.sampleEditorX, G_Conf.sampleEditorY, G_Conf.sampleEditorW, G_Conf.sampleEditorH); /* top bar: grid and zoom tools */ Fl_Group *bar = new Fl_Group(8, 8, w()-16, 20); bar->begin(); grid = new gChoice(bar->x(), bar->y(), 50, 20); snap = new gCheck(grid->x()+grid->w()+4, bar->y()+4, 12, 12); zoomOut = new gClick(bar->x()+bar->w()-20, bar->y(), 20, 20, "", zoomOutOff_xpm, zoomOutOn_xpm); zoomIn = new gClick(zoomOut->x()-24, bar->y(), 20, 20, "", zoomInOff_xpm, zoomInOn_xpm); bar->end(); bar->resizable(new gBox(grid->x()+grid->w()+4, bar->y(), 80, bar->h())); /* waveform */ waveTools = new gWaveTools(8, 36, w()-16, h()-120, ch); waveTools->end(); /* other tools */ Fl_Group *tools = new Fl_Group(8, waveTools->y()+waveTools->h()+8, w()-16, 130); tools->begin(); volume = new gDial (tools->x()+50, tools->y(), 20, 20, "Volume"); volumeNum = new gInput(volume->x()+volume->w()+4, tools->y(), 46, 20, "dB"); boost = new gDial (volumeNum->x()+volumeNum->w()+108, tools->y(), 20, 20, "Boost"); boostNum = new gInput(boost->x()+boost->w()+4, tools->y(), 44, 20, "dB"); normalize = new gClick(boostNum->x()+boostNum->w()+54, tools->y(), 70, 20, "Normalize"); pan = new gDial (normalize->x()+normalize->w()+40, tools->y(), 20, 20, "Pan"); panNum = new gInput(pan->x()+pan->w()+4, tools->y(), 45, 20, "%"); pitch = new gDial (tools->x()+50, volume->y()+volume->h()+4, 20, 20, "Pitch"); pitchNum = new gInput(pitch->x()+pitch->w()+4, volume->y()+volume->h()+4, 46, 20); pitchToBar = new gClick(pitchNum->x()+pitchNum->w()+4, volume->y()+volume->h()+4, 60, 20, "To bar"); pitchToSong = new gClick(pitchToBar->x()+pitchToBar->w()+4, volume->y()+volume->h()+4, 60, 20, "To song"); pitchHalf = new gClick(pitchToSong->x()+pitchToSong->w()+4, volume->y()+volume->h()+4, 20, 20, "", divideOff_xpm, divideOn_xpm); pitchDouble = new gClick(pitchHalf->x()+pitchHalf->w()+4, volume->y()+volume->h()+4, 20, 20, "", multiplyOff_xpm, multiplyOn_xpm); pitchReset = new gClick(pitchDouble->x()+pitchDouble->w()+4, volume->y()+volume->h()+4, 46, 20, "Reset"); reload = new gClick(pitchReset->x()+pitchReset->w()+4, volume->y()+volume->h()+4, 70, 20, "Reload"); chanStart = new gInput(tools->x()+60, pitch->y()+pitch->h()+4, 60, 20, "Range"); chanEnd = new gInput(chanStart->x()+chanStart->w()+4, pitch->y()+pitch->h()+4, 60, 20, ""); resetStartEnd = new gClick(chanEnd->x()+chanEnd->w()+4, pitch->y()+pitch->h()+4, 60, 20, "Reset"); tools->end(); tools->resizable(new gBox(panNum->x()+panNum->w()+4, tools->y(), 80, tools->h())); /* grid tool setup */ grid->add("(off)"); grid->add("2"); grid->add("3"); grid->add("4"); grid->add("6"); grid->add("8"); grid->add("16"); grid->add("32"); grid->add("64"); grid->value(G_Conf.sampleEditorGridVal); grid->callback(cb_changeGrid, (void*)this); snap->value(G_Conf.sampleEditorGridOn); snap->callback(cb_enableSnap, (void*)this); /* TODO - redraw grid if != (off) */ char buf[16]; sprintf(buf, "%d", ch->begin / 2); // divided by 2 because stereo chanStart->value(buf); chanStart->type(FL_INT_INPUT); chanStart->callback(cb_setChanPos, this); /* inputs callback: fire when they lose focus or Enter is pressed. */ chanStart->when(FL_WHEN_RELEASE | FL_WHEN_ENTER_KEY); chanEnd ->when(FL_WHEN_RELEASE | FL_WHEN_ENTER_KEY); sprintf(buf, "%d", ch->end / 2); // divided by 2 because stereo chanEnd->value(buf); chanEnd->type(FL_INT_INPUT); chanEnd->callback(cb_setChanPos, this); resetStartEnd->callback(cb_resetStartEnd, this); volume->callback(cb_setVolume, (void*)this); volume->value(ch->guiChannel->vol->value()); float dB = 20*log10(ch->volume); // dB = 20*log_10(linear value) if (dB > -INFINITY) sprintf(buf, "%.2f", dB); else sprintf(buf, "-inf"); volumeNum->value(buf); volumeNum->align(FL_ALIGN_RIGHT); volumeNum->callback(cb_setVolumeNum, (void*)this); boost->range(1.0f, 10.0f); boost->callback(cb_setBoost, (void*)this); if (ch->boost > 10.f) boost->value(10.0f); else boost->value(ch->boost); boost->when(FL_WHEN_CHANGED | FL_WHEN_RELEASE); float boost = 20*log10(ch->boost); // dB = 20*log_10(linear value) sprintf(buf, "%.2f", boost); boostNum->value(buf); boostNum->align(FL_ALIGN_RIGHT); boostNum->callback(cb_setBoostNum, (void*)this); normalize->callback(cb_normalize, (void*)this); pan->range(0.0f, 2.0f); pan->callback(cb_panning, (void*)this); pitch->range(0.01f, 4.0f); pitch->value(ch->pitch); pitch->callback(cb_setPitch, (void*)this); pitch->when(FL_WHEN_RELEASE); sprintf(buf, "%.4f", ch->pitch); // 4 digits pitchNum->value(buf); pitchNum->align(FL_ALIGN_RIGHT); pitchNum->callback(cb_setPitchNum, (void*)this); pitchNum->when(FL_WHEN_RELEASE | FL_WHEN_ENTER_KEY); pitchToBar->callback(cb_setPitchToBar, (void*)this); pitchToSong->callback(cb_setPitchToSong, (void*)this); pitchHalf->callback(cb_setPitchHalf, (void*)this); pitchDouble->callback(cb_setPitchDouble, (void*)this); pitchReset->callback(cb_resetPitch, (void*)this); reload->callback(cb_reload, (void*)this); zoomOut->callback(cb_zoomOut, (void*)this); zoomIn->callback(cb_zoomIn, (void*)this); /* logical samples (aka takes) cannot be reloaded. So far. */ if (ch->wave->isLogical) reload->deactivate(); if (ch->panRight < 1.0f) { char buf[8]; sprintf(buf, "%d L", (int) std::abs((ch->panRight * 100.0f) - 100)); pan->value(ch->panRight); panNum->value(buf); } else if (ch->panRight == 1.0f && ch->panLeft == 1.0f) { pan->value(1.0f); panNum->value("C"); } else { char buf[8]; sprintf(buf, "%d R", (int) std::abs((ch->panLeft * 100.0f) - 100)); pan->value(2.0f - ch->panLeft); panNum->value(buf); } panNum->align(FL_ALIGN_RIGHT); panNum->readonly(1); panNum->cursor_color(FL_WHITE); gu_setFavicon(this); size_range(640, 480); resizable(waveTools); label(ch->wave->name.c_str()); show(); }
gdBrowser::gdBrowser(const char *title, const char *initPath, Channel *ch, int type, int stackType) : gWindow (396, 302, title), ch (ch), type (type), stackType(stackType) { set_non_modal(); browser = new gBrowser(8, 36, 380, 230); Fl_Group *group_btn = new Fl_Group(8, 274, 380, 20); gBox *b = new gBox(8, 274, 204, 20); // spacer window border <-> buttons ok = new gClick(308, 274, 80, 20); cancel = new gClick(220, 274, 80, 20, "Cancel"); status = new gProgress(8, 274, 204, 20); status->minimum(0); status->maximum(1); status->hide(); // show the bar only if necessary group_btn->resizable(b); group_btn->end(); Fl_Group *group_upd = new Fl_Group(8, 8, 380, 25); if (type == BROWSER_SAVE_PATCH || type == BROWSER_SAVE_SAMPLE || type == BROWSER_SAVE_PROJECT) /// bitmask please! name = new gInput(208, 8, 152, 20); if (type == BROWSER_SAVE_PATCH || type == BROWSER_SAVE_SAMPLE || type == BROWSER_SAVE_PROJECT) /// bitmask please! where = new gInput(8, 8, 192, 20); else where = new gInput(8, 8, 352, 20); updir = new gClick(368, 8, 20, 20, "", updirOff_xpm, updirOn_xpm); group_upd->resizable(where); group_upd->end(); end(); resizable(browser); size_range(w(), h(), 0, 0); where->readonly(true); where->cursor_color(COLOR_BG_DARK); if (type == BROWSER_SAVE_PATCH || type == BROWSER_SAVE_SAMPLE || type == BROWSER_SAVE_PROJECT) /// bitmask please! ok->label("Save"); else ok->label("Load"); if (type == BROWSER_LOAD_PATCH) ok->callback(cb_load_patch, (void*)this); else if (type == BROWSER_LOAD_SAMPLE) ok->callback(cb_load_sample, (void*)this); else if (type == BROWSER_SAVE_PATCH) { ok->callback(cb_save_patch, (void*)this); name->value(G_Patch.name[0] == '\0' ? "my_patch.gptc" : G_Patch.name); name->maximum_size(MAX_PATCHNAME_LEN+5); // +5 for ".gptc" } else if (type == BROWSER_SAVE_SAMPLE) { ok->callback(cb_save_sample, (void*)this); name->value(((SampleChannel*)ch)->wave->name.c_str()); } else if (type == BROWSER_SAVE_PROJECT) { ok->callback(cb_save_project, (void*)this); name->value(gStripExt(G_Patch.name).c_str()); } #ifdef WITH_VST else if (type == BROWSER_LOAD_PLUGIN) { ok->callback(cb_loadPlugin, (void*)this); } #endif ok->shortcut(FL_Enter); updir->callback(cb_up, (void*)this); cancel->callback(cb_close, (void*)this); browser->callback(cb_down, this); browser->path_obj = where; browser->init(initPath); if (G_Conf.browserW) resize(G_Conf.browserX, G_Conf.browserY, G_Conf.browserW, G_Conf.browserH); gu_setFavicon(this); show(); }
gdEditor::gdEditor(SampleChannel *ch) : gWindow(640, 480), ch(ch) { set_non_modal(); if (G_Conf.sampleEditorX) resize(G_Conf.sampleEditorX, G_Conf.sampleEditorY, G_Conf.sampleEditorW, G_Conf.sampleEditorH); Fl_Group *bar = new Fl_Group(8, 8, w()-16, 20); bar->begin(); reload = new gClick(bar->x(), bar->y(), 50, 20, "Reload"); zoomOut = new gClick(bar->x()+bar->w()-20, bar->y(), 20, 20, "-"); zoomIn = new gClick(zoomOut->x()-24, bar->y(), 20, 20, "+"); bar->end(); bar->resizable(new gBox(reload->x()+reload->w()+4, bar->y(), 80, bar->h())); waveTools = new gWaveTools(8, 36, w()-16, h()-120, ch); waveTools->end(); Fl_Group *tools = new Fl_Group(8, waveTools->y()+waveTools->h()+8, w()-16, 130); tools->begin(); volume = new gDial (tools->x()+42, tools->y(), 20, 20, "Volume"); volumeNum = new gInput(volume->x()+volume->w()+4, tools->y(), 46, 20, "dB"); boost = new gDial (volumeNum->x()+volumeNum->w()+80, tools->y(), 20, 20, "Boost"); boostNum = new gInput(boost->x()+boost->w()+4, tools->y(), 46, 20, "dB"); normalize = new gClick(boostNum->x()+boostNum->w()+40, tools->y(), 70, 20, "Normalize"); pan = new gDial (normalize->x()+normalize->w()+40, tools->y(), 20, 20, "Pan"); panNum = new gInput(pan->x()+pan->w()+4, tools->y(), 45, 20, "%"); pitch = new gDial (tools->x()+42, volume->y()+volume->h()+4, 20, 20, "Pitch"); pitchNum = new gInput (pitch->x()+pitch->w()+4, volume->y()+volume->h()+4, 46, 20); pitchToBar = new gClick (pitchNum->x()+pitchNum->w()+4, volume->y()+volume->h()+4, 46, 20, "To bar"); pitchToSong = new gClick (pitchToBar->x()+pitchToBar->w()+4, volume->y()+volume->h()+4, 46, 20, "To song"); pitchReset = new gClick (pitchToSong->x()+pitchToSong->w()+4, volume->y()+volume->h()+4, 46, 20, "Reset"); chanStart = new gInput(tools->x()+52, pitch->y()+pitch->h()+4, 60, 20, "Start"); chanEnd = new gInput(chanStart->x()+chanStart->w()+40, pitch->y()+pitch->h()+4, 60, 20, "End"); resetStartEnd = new gClick(chanEnd->x()+chanEnd->w()+4, pitch->y()+pitch->h()+4, 46, 20, "Reset"); tools->end(); tools->resizable(new gBox(chanStart->x()+chanStart->w()+4, tools->y(), 80, tools->h())); char buf[16]; ///sprintf(buf, "%d", ch->beginTrue / 2); // divided by 2 because stereo sprintf(buf, "%d", ch->begin / 2); // divided by 2 because stereo chanStart->value(buf); chanStart->type(FL_INT_INPUT); chanStart->callback(cb_setChanPos, this); /* inputs callback: fire when they lose focus or Enter is pressed. */ chanStart->when(FL_WHEN_RELEASE | FL_WHEN_ENTER_KEY); chanEnd ->when(FL_WHEN_RELEASE | FL_WHEN_ENTER_KEY); ///sprintf(buf, "%d", ch->endTrue / 2); // divided by 2 because stereo sprintf(buf, "%d", ch->end / 2); // divided by 2 because stereo chanEnd->value(buf); chanEnd->type(FL_INT_INPUT); chanEnd->callback(cb_setChanPos, this); resetStartEnd->callback(cb_resetStartEnd, this); volume->callback(cb_setVolume, (void*)this); volume->value(ch->guiChannel->vol->value()); float dB = 20*log10(ch->volume); // dB = 20*log_10(linear value) if (dB > -INFINITY) sprintf(buf, "%.2f", dB); else sprintf(buf, "-inf"); volumeNum->value(buf); volumeNum->align(FL_ALIGN_RIGHT); volumeNum->callback(cb_setVolumeNum, (void*)this); boost->range(1.0f, 10.0f); boost->callback(cb_setBoost, (void*)this); if (ch->boost > 10.f) boost->value(10.0f); else boost->value(ch->boost); boost->when(FL_WHEN_CHANGED | FL_WHEN_RELEASE); float boost = 20*log10(ch->boost); // dB = 20*log_10(linear value) sprintf(buf, "%.2f", boost); boostNum->value(buf); boostNum->align(FL_ALIGN_RIGHT); boostNum->callback(cb_setBoostNum, (void*)this); normalize->callback(cb_normalize, (void*)this); pan->range(0.0f, 2.0f); pan->callback(cb_panning, (void*)this); pitch->range(0.01f, 4.0f); pitch->value(ch->pitch); pitch->callback(cb_setPitch, (void*)this); pitch->when(FL_WHEN_RELEASE); sprintf(buf, "%.4f", ch->pitch); // 4 digits pitchNum->value(buf); pitchNum->align(FL_ALIGN_RIGHT); pitchNum->callback(cb_setPitchNum, (void*)this); pitchNum->when(FL_WHEN_RELEASE | FL_WHEN_ENTER_KEY); pitchToBar->callback(cb_setPitchToBar, (void*)this); pitchToSong->callback(cb_setPitchToSong, (void*)this); pitchReset->callback(cb_resetPitch, (void*)this); reload->callback(cb_reload, (void*)this); zoomOut->callback(cb_zoomOut, (void*)this); zoomIn->callback(cb_zoomIn, (void*)this); /* logical samples (aka takes) cannot be reloaded. So far. */ if (ch->wave->isLogical) reload->deactivate(); if (ch->panRight < 1.0f) { char buf[8]; sprintf(buf, "%d L", abs((ch->panRight * 100.0f) - 100)); pan->value(ch->panRight); panNum->value(buf); } else if (ch->panRight == 1.0f && ch->panLeft == 1.0f) { pan->value(1.0f); panNum->value("C"); } else { char buf[8]; sprintf(buf, "%d R", abs((ch->panLeft * 100.0f) - 100)); pan->value(2.0f - ch->panLeft); panNum->value(buf); } panNum->align(FL_ALIGN_RIGHT); panNum->readonly(1); panNum->cursor_color(FL_WHITE); gu_setFavicon(this); size_range(640, 480); resizable(waveTools); label(ch->wave->name.c_str()); show(); }
gdActionEditor::gdActionEditor(int chan) : gWindow(640, 176), chan(chan), zoom(100) { if (G_Conf.actionEditorW) { resize(G_Conf.actionEditorX, G_Conf.actionEditorY, G_Conf.actionEditorW, G_Conf.actionEditorH); zoom = G_Conf.actionEditorZoom; } framesPerBar = G_Mixer.framesPerBar / 2; // /2 = we don't care about stereo infos framesPerBeat = G_Mixer.framesPerBeat / 2; framesPerBeats = framesPerBeat * G_Mixer.beats; totalFrames = framesPerBeat * MAX_BEATS; beatWidth = framesPerBeat / zoom; totalWidth = (int) ceilf(totalFrames / (float) zoom); /* container with zoom buttons and the action type selector. Scheme of * the resizable boxes: |[--b1--][actionType][--b2--][+][-]| */ Fl_Group *upperArea = new Fl_Group(8, 8, w()-16, 20); upperArea->begin(); actionType = new gChoice(104, 8, 80, 20); gridTool = new gGridTool(188, 8, this); gBox *b1 = new gBox (248, 8, 300, 20); // padding actionType - zoomButtons zoomIn = new gClick(w()-8-40-4, 8, 20, 20, "+"); zoomOut = new gClick(w()-8-20, 8, 20, 20, "-"); upperArea->end(); upperArea->resizable(b1); actionType->add("key press"); actionType->add("key release"); actionType->add("kill chan"); actionType->value(0); gridTool->init(G_Conf.actionEditorGridVal, G_Conf.actionEditorGridOn); gridTool->calc(); if (G_Mixer.chanMode[chan] == SINGLE_PRESS || G_Mixer.chanMode[chan] & LOOP_ANY) actionType->deactivate(); zoomIn->callback(cb_zoomIn, (void*)this); zoomOut->callback(cb_zoomOut, (void*)this); /* side boxes with text infos for the channel (actions, mute, ...) * Even here we need the padding box trick, otherwise when you enlarge * the window vertically, text boxes strech. */ Fl_Group *texts = new Fl_Group(8, 36, 92, 160); gBox *txtActions = new gBox(8, 36, 92, 20, "Actions"); gBox *txtMutes = new gBox(8, 80, 92, 20, "Mute"); gBox *txtDist = new gBox(8, 100, 92, 20); // pading border - buttons txtActions->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE); txtMutes ->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE); if (G_Mixer.chanMode[chan] & LOOP_ANY) { gBox *txtDisabled = new gBox(8, 48, 92, 20, "disabled"); txtDisabled->labelsize(9); txtDisabled->labelcolor(COLOR_BD_0); txtDisabled->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE); } texts->end(); texts->resizable(txtDist); /* main scroller: contains all widgets */ scroller = new Fl_Scroll(104, 36, this->w()-112, this->h()-44); scroller->type(Fl_Scroll::HORIZONTAL); scroller->hscrollbar.color(COLOR_BG_0); scroller->hscrollbar.selection_color(COLOR_BG_1); scroller->hscrollbar.labelcolor(COLOR_BD_1); scroller->hscrollbar.slider(G_BOX); scroller->begin(); ac = new gActionChannel(scroller->x(), 36, this); mc = new gMuteChannel (scroller->x(), 84, this); scroller->end(); end(); /* if channel is LOOP_ANY, deactivate it: a loop mode channel cannot * hold keypress/keyrelease actions */ if (G_Mixer.chanMode[chan] & LOOP_ANY) ac->deactivate(); gu_setFavicon(this); char buf[256]; sprintf(buf, "Edit Actions in Channel %d", chan+1); label(buf); set_non_modal(); size_range(640, 176); resizable(scroller); show(); }
gdMainWindow::gdMainWindow(int x, int y, int w, int h, const char *title, int argc, char **argv) : gWindow(x, y, w, h, title) { Fl::visible_focus(0); Fl::background(25, 25, 25); Fl::set_boxtype(G_BOX, gDrawBox, 1, 1, 2, 2); // custom box G_BOX menu_file = new gClick(8, -1, 70, 21, "file"); menu_edit = new gClick(82, -1, 70, 21, "edit"); menu_config = new gClick(156, -1, 70, 21, "config"); menu_about = new gClick(230, -1, 70, 21, "about"); quantize = new gChoice(632, 49, 40, 15, "", false); bpm = new gClick(676, 49, 40, 15); beats = new gClick(724, 49, 40, 15, "4/1"); beats_mul = new gClick(768, 49, 15, 15, "×"); beats_div = new gClick(787, 49, 15, 15, "÷"); #if defined(WITH_VST) masterFxIn = new gButton(408, 8, 20, 20, "", fxOff_xpm, fxOn_xpm); inVol = new gDial (432, 8, 20, 20); inMeter = new gSoundMeter(456, 13, 140, 10); inToOut = new gClick (600, 13, 10, 10, ""); outMeter = new gSoundMeter(614, 13, 140, 10); outVol = new gDial (758, 8, 20, 20); masterFxOut = new gButton(782, 8, 20, 20, "", fxOff_xpm, fxOn_xpm); #else outMeter = new gSoundMeter(638, 13, 140, 10); inMeter = new gSoundMeter(494, 13, 140, 10); outVol = new gDial(782, 8, 20, 20); inVol = new gDial(470, 8, 20, 20); #endif beatMeter = new gBeatMeter(100, 83, 609, 20); keyboard = new Keyboard(8, 122, 790, 470); beat_rew = new gClick(8, 39, 25, 25, "", rewindOff_xpm, rewindOn_xpm); beat_stop = new gClick(37, 39, 25, 25, "", play_xpm, pause_xpm); beat_rec = new gClick(66, 39, 25, 25, "", recOff_xpm, recOn_xpm); input_rec = new gClick(95, 39, 25, 25, "", inputRecOff_xpm, inputRecOn_xpm); metronome = new gClick(124, 49, 15, 15, "", metronomeOff_xpm, metronomeOn_xpm); end(); char buf_bpm[6]; snprintf(buf_bpm, 6, "%f", G_Mixer.bpm); bpm->copy_label(buf_bpm); bpm->callback(cb_change_bpm); beats->callback(cb_change_batt); menu_about->callback(cb_open_about_win); menu_file->callback(cb_open_file_menu); menu_edit->callback(cb_open_edit_menu); menu_config->callback(cb_open_config_win); outVol->callback(cb_outVol); outVol->value(G_Mixer.outVol); inVol->callback(cb_inVol); inVol->value(G_Mixer.inVol); #ifdef WITH_VST masterFxOut->callback(cb_openMasterFxOut); masterFxIn->callback(cb_openMasterFxIn); inToOut->callback(cb_inToOut); inToOut->type(FL_TOGGLE_BUTTON); #endif beat_rew->callback(cb_rewind_tracker); beat_stop->callback(cb_startstop); beat_stop->type(FL_TOGGLE_BUTTON); beat_rec->callback(cb_rec); beat_rec->type(FL_TOGGLE_BUTTON); input_rec->callback(cb_inputRec); input_rec->type(FL_TOGGLE_BUTTON); beats_mul->callback(cb_beatsMultiply); beats_div->callback(cb_beatsDivide); metronome->type(FL_TOGGLE_BUTTON); metronome->callback(cb_metronome); callback(cb_endprogram); quantize->add("off", 0, cb_quantize, (void*)0); quantize->add("1b", 0, cb_quantize, (void*)1); quantize->add("2b", 0, cb_quantize, (void*)2); quantize->add("3b", 0, cb_quantize, (void*)3); quantize->add("4b", 0, cb_quantize, (void*)4); quantize->add("6b", 0, cb_quantize, (void*)6); quantize->add("8b", 0, cb_quantize, (void*)8); quantize->value(0); // "off" by default gu_setFavicon(this); show(argc, argv); }
gdActionEditor::gdActionEditor(channel *chan) : gWindow(640, 284), chan(chan), zoom(100) { if (G_Conf.actionEditorW) { resize(G_Conf.actionEditorX, G_Conf.actionEditorY, G_Conf.actionEditorW, G_Conf.actionEditorH); zoom = G_Conf.actionEditorZoom; } /* compute values */ calc(); /* container with zoom buttons and the action type selector. Scheme of * the resizable boxes: |[--b1--][actionType][--b2--][+][-]| */ Fl_Group *upperArea = new Fl_Group(8, 8, w()-16, 20); upperArea->begin(); if (chan->type == CHANNEL_SAMPLE) { actionType = new gChoice(8, 8, 80, 20); gridTool = new gGridTool(actionType->x()+actionType->w()+4, 8, this); } else gridTool = new gGridTool(8, 8, this); gBox *b1 = new gBox(gridTool->x()+gridTool->w()+4, 8, 300, 20); // padding actionType - zoomButtons zoomIn = new gClick(w()-8-40-4, 8, 20, 20, "+"); zoomOut = new gClick(w()-8-20, 8, 20, 20, "-"); upperArea->end(); upperArea->resizable(b1); if (chan->type == CHANNEL_SAMPLE) { actionType->add("key press"); actionType->add("key release"); actionType->add("kill chan"); actionType->value(0); } gridTool->init(G_Conf.actionEditorGridVal, G_Conf.actionEditorGridOn); gridTool->calc(); if (chan->type == CHANNEL_SAMPLE && (chan->mode == SINGLE_PRESS || chan->mode & LOOP_ANY)) actionType->deactivate(); zoomIn->callback(cb_zoomIn, (void*)this); zoomOut->callback(cb_zoomOut, (void*)this); /* main scroller: contains all widgets */ scroller = new gScroll(8, 36, this->w()-16, this->h()-44); if (chan->type == CHANNEL_SAMPLE) { ac = new gActionChannel (scroller->x(), upperArea->y()+upperArea->h()+8, this); mc = new gMuteChannel (scroller->x(), ac->y()+ac->h()+8, this); vc = new gEnvelopeChannel (scroller->x(), mc->y()+mc->h()+8, this, ACTION_VOLUME, RANGE_FLOAT, "volume"); scroller->add(ac); //scroller->add(new gResizerBar(ac->x(), ac->y()+ac->h(), scroller->w(), 8)); scroller->add(mc); //scroller->add(new gResizerBar(mc->x(), mc->y()+mc->h(), scroller->w(), 8)); scroller->add(vc); //scroller->add(new gResizerBar(vc->x(), vc->y()+vc->h(), scroller->w(), 8)); /* fill volume envelope with actions from recorder */ vc->fill(); /* if channel is LOOP_ANY, deactivate it: a loop mode channel cannot * hold keypress/keyrelease actions */ if (chan->mode & LOOP_ANY) ac->deactivate(); } else { pr = new gPianoRollContainer(scroller->x(), upperArea->y()+upperArea->h()+8, this); scroller->add(pr); scroller->add(new gResizerBar(pr->x(), pr->y()+pr->h(), scroller->w(), 8)); } end(); gu_setFavicon(this); char buf[256]; sprintf(buf, "Edit Actions in Channel %d", chan->index+1); label(buf); set_non_modal(); size_range(640, 284); resizable(scroller); show(); }
gdEditor::gdEditor(const char *title, int chan) : gWindow(500, 292, title), chan(chan) { set_non_modal(); if (G_Conf.sampleEditorX) resize(G_Conf.sampleEditorX, G_Conf.sampleEditorY, w(), h()); wt = new gWaveTools(8, 8, 484, 179, chan); chanStart = new gInput(50, 192, 70, 20, "Range"); chanEnd = new gInput(124, 192, 70, 20); resetStartEnd = new gClick(198, 192, 50, 20, "Reset"); volume = new gDial (100, 216, 20, 20, "Volume"); volumeNum = new gInput(124, 216, 45, 20, "dB"); boost = new gDial (100, 240, 20, 20, "Boost"); boostNum = new gInput(124, 240, 45, 20, "dB"); normalize = new gClick(198, 240, 50, 20, "Norm."); pan = new gDial (100, 264, 20, 20, "Pan"); panNum = new gInput(124, 264, 45, 20, "%"); reload = new gClick(252, 192, 50, 20, "Reload"); pitch = new gDial (300, 216, 20, 20, "Pitch"); pitchNum = new gInput(324, 216, 45, 20); char buf[16]; sprintf(buf, "%d", G_Mixer.chanStartTrue[chan]/2); // divided by 2 because stereo chanStart->value(buf); chanStart->type(FL_INT_INPUT); chanStart->callback(cb_setChanPos, this); /* inputs callback: fire when they lose focus or Enter is pressed. */ chanStart->when(FL_WHEN_RELEASE | FL_WHEN_ENTER_KEY); chanEnd ->when(FL_WHEN_RELEASE | FL_WHEN_ENTER_KEY); sprintf(buf, "%d", G_Mixer.chanEndTrue[chan]/2); // divided by 2 because stereo chanEnd->value(buf); chanEnd->type(FL_INT_INPUT); chanEnd->callback(cb_setChanPos, this); resetStartEnd->callback(cb_resetStartEnd, this); volume->callback(cb_setVolume, (void*)this); volume->value(mainWin->keyboard->vol[chan]->value()); float dB = 20*log10(G_Mixer.chanVolume[chan]); // dB = 20*log_10(linear value) if (dB > -INFINITY) sprintf(buf, "%.2f", dB); else sprintf(buf, "-inf"); volumeNum->value(buf); volumeNum->align(FL_ALIGN_RIGHT); volumeNum->callback(cb_setVolumeNum, (void*)this); boost->range(1.0f, 10.0f); boost->callback(cb_setBoost, (void*)this); if (G_Mixer.chanBoost[chan] > 10.f) boost->value(10.0f); else boost->value(G_Mixer.chanBoost[chan]); boost->when(FL_WHEN_CHANGED | FL_WHEN_RELEASE); float boost = 20*log10(G_Mixer.chanBoost[chan]); // dB = 20*log_10(linear value) sprintf(buf, "%.2f", boost); boostNum->value(buf); boostNum->align(FL_ALIGN_RIGHT); boostNum->callback(cb_setBoostNum, (void*)this); normalize->callback(cb_normalize, (void*)this); pan->range(0.0f, 2.0f); pan->callback(cb_panning, (void*)this); pitch->range(0.1f, 2.0f); pitch->value(G_Mixer.chanPitch[chan]); pitch->callback(cb_setPitch, (void*)this); sprintf(buf, "%.4f", G_Mixer.chanPitch[chan]); // 4 digits pitchNum->value(buf); pitchNum->align(FL_ALIGN_RIGHT); pitchNum->callback(cb_setPitchNum, (void*)this); pitchNum->when(FL_WHEN_RELEASE | FL_WHEN_ENTER_KEY); reload->callback(cb_reload, (void*)this); /* logical samples (aka takes) cannot be reloaded. So far. */ if (G_Mixer.chan[chan]->isLogical) reload->deactivate(); if (G_Mixer.chanPanRight[chan] < 1.0f) { char buf[8]; sprintf(buf, "%d L", abs((G_Mixer.chanPanRight[chan] * 100.0f) - 100)); pan->value(G_Mixer.chanPanRight[chan]); panNum->value(buf); } else if (G_Mixer.chanPanRight[chan] == 1.0f && G_Mixer.chanPanLeft[chan] == 1.0f) { pan->value(1.0f); panNum->value("C"); } else { char buf[8]; sprintf(buf, "%d R", abs((G_Mixer.chanPanLeft[chan] * 100.0f) - 100)); pan->value(2.0f-G_Mixer.chanPanLeft[chan]); panNum->value(buf); } panNum->align(FL_ALIGN_RIGHT); panNum->readonly(1); panNum->cursor_color(FL_WHITE); gu_setFavicon(this); show(); }