// generated by Fast Light User Interface Designer (fluid) version 1.0308

#include "MasterUI.h"
// MasterUI.cc
// Original ZynAddSubFX author Nasca Octavian Paul
// Copyright (C) 2002-2005 Nasca Octavian Paul
// Copyright 2009-2011, Alan Calvert
// Copyright 2014-2022, Will Godfrey & others

// This file is part of yoshimi, which is free software: you can redistribute
// it and/or modify it under the terms of the GNU General Public
// License as published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.

// yoshimi is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE.   See the GNU General Public License (version 2 or
// later) for more details.

// You should have received a copy of the GNU General Public License along with
// yoshimi; if not, write to the Free Software Foundation, Inc., 51 Franklin
// Street, Fifth Floor, Boston, MA  02110-1301, USA.

// This file is a derivative of the ZynAddSubFX original.
#include "Misc/FileMgrFuncs.h"
    using file::isRegularFile;
    using file::findLeafName;
#include "Misc/FormatFuncs.h"
    using func::string2uint;
    using func::asString;
#include "Misc/TextMsgBuffer.h"

    namespace { // Implementation details...
        TextMsgBuffer& textMsgBuffer = TextMsgBuffer::instance();
    }
using std::to_string;
int lineitem; 

void FilerLine::cb_nametop_i(Fl_Button*, void*) {
  //std::cout << "pressed " << n << std::endl;
lineitem = n;
}
void FilerLine::cb_nametop(Fl_Button* o, void* v) {
  ((FilerLine*)(o->parent()->user_data()))->cb_nametop_i(o,v);
}

Fl_Group* FilerLine::make_window() {
  { filerlist = new Fl_Group(0, 0, 440, 20);
    filerlist->box(FL_FLAT_BOX);
    filerlist->color(FL_BACKGROUND2_COLOR);
    filerlist->selection_color(FL_BACKGROUND_COLOR);
    filerlist->labeltype(FL_NO_LABEL);
    filerlist->labelfont(0);
    filerlist->labelsize(14);
    filerlist->labelcolor(FL_FOREGROUND_COLOR);
    filerlist->user_data((void*)(this));
    filerlist->align(Fl_Align(FL_ALIGN_TOP));
    filerlist->when(FL_WHEN_RELEASE);
    { fileIcon = new Fl_Group(0, 0, 23, 30);
      fileIcon->box(FL_FLAT_BOX);
      fileIcon->color(FL_BACKGROUND2_COLOR);
      { outer_box = new Fl_Box(3, 0, 16, 20);
        outer_box->box(FL_GTK_THIN_UP_BOX);
        outer_box->color((Fl_Color)174);
        outer_box->labeltype(FL_NO_LABEL);
      } // Fl_Box* outer_box
      { inner_box = new Fl_Box(5, 2, 12, 16);
        inner_box->box(FL_GTK_THIN_DOWN_BOX);
        inner_box->color((Fl_Color)174);
        inner_box->labeltype(FL_NO_LABEL);
      } // Fl_Box* inner_box
      { line1 = new Fl_Box(7, 5, 8, 2);
        line1->box(FL_FLAT_BOX);
        line1->color((Fl_Color)124);
      } // Fl_Box* line1
      { line2 = new Fl_Box(7, 9, 8, 2);
        line2->box(FL_FLAT_BOX);
        line2->color((Fl_Color)124);
      } // Fl_Box* line2
      { type = new Fl_Box(4, 6, 15, 17, "xiz");
        type->labelsize(4);
      } // Fl_Box* type
      fileIcon->end();
    } // Fl_Group* fileIcon
    { dirIcon = new Fl_Group(0, 0, 21, 20);
      dirIcon->box(FL_FLAT_BOX);
      dirIcon->color(FL_BACKGROUND2_COLOR);
      dirIcon->hide();
      { Fl_Box* o = new Fl_Box(1, 1, 18, 15);
        o->box(FL_PLASTIC_THIN_UP_BOX);
        o->color((Fl_Color)183);
      } // Fl_Box* o
      { Fl_Box* o = new Fl_Box(3, 4, 18, 16);
        o->box(FL_PLASTIC_THIN_UP_BOX);
        o->color((Fl_Color)183);
      } // Fl_Box* o
      { Fl_Box* o = new Fl_Box(5, 7, 14, 1);
        o->box(FL_DOWN_BOX);
        o->selection_color((Fl_Color)181);
      } // Fl_Box* o
      dirIcon->end();
    } // Fl_Group* dirIcon
    { name = new Fl_Button(25, 0, 415, 21);
      name->box(FL_NO_BOX);
      name->color(FL_BACKGROUND2_COLOR);
      name->labelsize(12);
      name->align(Fl_Align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE));
    } // Fl_Button* name
    { nametop = new Fl_Button(0, 1, 420, 18);
      nametop->box(FL_NO_BOX);
      nametop->callback((Fl_Callback*)cb_nametop);
    } // Fl_Button* nametop
    filerlist->end();
  } // Fl_Group* filerlist
  return filerlist;
}

FilerLine::FilerLine(int x, int y, int w, int h, const char *label):Fl_Group(x,y,w,h,label) {
  n = 0;
}

void FilerLine::init(SynthEngine *synth_, int n_, bool isDir_, string typeName_, string title_) {
  //
  
      synth = synth_;
      n = n_;
      isDir = isDir_;
      typeName = typeName_;
      title = title_;
      make_window();
      if (isDir)
      {
          dirIcon->show();
          fileIcon->hide();
      }
      else
      {
          dirIcon->hide();
          fileIcon->show();
          type->copy_label(typeName.c_str());
          name->copy_label(title.c_str());
      }
      show();
      end();
}

FilerLine::~FilerLine() {
  //
      filerlist->hide();
      delete (filerlist);
}

KeyHandle::KeyHandle(int x,int y, int w, int h, const char *label):Fl_Box(x,y,w,h,label) {
}

void KeyHandle::init(SynthEngine *_synth) {
  //
          synth = _synth;
}

int KeyHandle::handle(int event) {
  //
      int ev = 0;
      if (event == FL_FOCUS)
          ev = 1;
      else if (event == FL_UNFOCUS)
          ev = 1;
      else if (event == FL_SHORTCUT)
      {
          auto key = Fl::event_key();
          if (key == FL_Escape)
              ev = 1;
          else if (key == 'z')
          {
              if (Fl::event_state() == 327680) //ctrl + shift
              {
                  synth->getGuiMaster()->redo->do_callback();
                  ev = 1;
              }
               else if (Fl::event_ctrl())
               {
                   synth->getGuiMaster()->undo->do_callback();
                   ev = 1;
               }
          }
          else if (Fl::event_alt())
          {
              if(key == 'r')
              {
                  synth->getGuiMaster()->redo->do_callback();
                  ev = 1;
              }
              else if(key == 'u')
              {
                  synth->getGuiMaster()->undo->do_callback();
                  ev = 1;
              }
          }
      }
      return ev;
}

void MasterUI::cb_masterwindow_i(Fl_Double_Window*, void*) {
  //
            bool close = true;
            bool force = Fl::event_state(FL_CTRL);
            if (!force && synth->getRuntime().configChanged)
            {
                int r = query("!", "!", "!", "Parameters Changed.\nSave on exit?");
                switch (r)
                {
                    case 3:
                        synth->getRuntime().configChanged = false;
                        // this seems backwards but it *always* saves.
                        // seeing configChanged makes it reload the old settings first.
                        break;
                    case 2:
                        break;
                    default:
                        close = false;
                        break;
                }
            }
            if (close)
            {
                if (force)
                    firstSynth->getRuntime().exitType = FORCED_EXIT;
                    /*
                    * The above line shouldn't be necessary!
                    * It works fine on jack but fails on ALSA.
                    * My best guess is that ALSA shuts down so quickly
                    * that one of the ringbuffers carrying the command
                    * is deleted before it can be read.
                    */
                    //send_data(0, TOPLEVEL::control::forceExit, 0, UNUSED);

                synth->guiClosed(true);
            };
}
void MasterUI::cb_masterwindow(Fl_Double_Window* o, void* v) {
  ((MasterUI*)(o->user_data()))->cb_masterwindow_i(o,v);
}

void MasterUI::cb_mastermenu_i(Fl_Menu_Bar* o, void*) {
  //
    int found = o->value();
    //std::cout << "switch found " << found << std::endl;
    switch (found)
        {
        case 1: // about
            {
            int X, Y, W, H, O;
            loadWin(synth, W, H, X, Y, O, "Master-about");
            if (W < aboutDW || H < aboutDH)
            {
                W = aboutDW;
                H = aboutDH;
            }
            checkSane(X, Y, W, H, aboutDW, aboutDH);
            aboutwindow->resize(X, Y, W, H);
            aboutwindow->show();
            }
            break;
        case 2: // new instance
            if (synth->getIsLV2Plugin())
            {
                query("", "", "", "Start new instances from host");
                return;
            }
            if (synth->getUniqueId() != 0)
            {
                query("", "", "", "Only main instance can start others");
                return;
            }
            startInstance();
            break;
        case 3: // settings
            configui->Show(synth);
            break;
        case 4: // reports
            if (logenable)
                yoshiLog->Show(synth);
            else
                alert(synth, "Logging configured for std::cout");
            break;
        case 5: // manual
//            if (query("", "Yes", "No", "A new manual is being written, so we temporarily include the one for V 1.7.4\n Do you wish to see this?") > 1)
            {
                words->copy_label("Searching for the manual.");
                message->show();
                message->position(masterwindow->x() + 36, masterwindow->y() + 170);
                send_data(TOPLEVEL::action::lowPrio | TOPLEVEL::action::forceUpdate, MAIN::control::openManual, 0, TOPLEVEL::type::Integer, TOPLEVEL::section::main);
            }
            break;
        case 6: // exit
            masterwindow->do_callback();
            break;

        case 7: // section instruments
            break;
        case 8: // section instruments
            break;
        case 9: // show
            bankui->Show();
            break;
        case 10: // load
            {
            string filename = setfiler("", "", false, TOPLEVEL::XML::Instrument);
            if (!filename.empty())
                do_load_instrument(filename);
            }
            break;
        case 11: // save
            {
            /*
            * Instruments are an exception for saving as we always want
            * to offer the INTERNAL name first rather than a possibly
            * confusing external filename.
            */
            string newname = synth->part[activePart]->Pname;
            if (newname == DEFAULT_NAME)
            {
                query("", "", "", "Nothing to save!");
                return;
            }
            if (synth->part[activePart]->info.Ptype == 0)
            {
                if (choice(synth, "", "Save", "Cancel", "Please set instrument type before saving.\nCopyright info also recommended.") != 2)
                    return;
            }
            string filename = setfiler("", newname, true, TOPLEVEL::XML::Instrument);
            if (!filename.empty())
                send_data(TOPLEVEL::action::lowPrio | TOPLEVEL::action::forceUpdate, MAIN::control::saveNamedInstrument, activePart, TOPLEVEL::type::Integer, TOPLEVEL::section::main, UNUSED, UNUSED, UNUSED, textMsgBuffer.push(string(filename)));
            }
            break;
        case 12: // recent
            {
            int xpos = masterwindow->x() + (masterwindow->w() * 0.15f);
            if (xpos + paramsui->Recent->w() > masterwindow->x() + masterwindow->w())
                xpos = masterwindow->x() + masterwindow->w() - paramsui->Recent->w();
            paramsui->Recent->position(xpos,masterwindow->y()+20);
            paramsui->Show(TOPLEVEL::XML::Instrument);
            }
            break;
        case 13: // clear
        if (!fetchData(0, PART::control::enable, activePart))
            {
                alert(synth, "Active part disabled");
                return;
            }
            partui->instrumentReset->do_callback();
            break;
        case 14: // search
        if (!fetchData(0, PART::control::enable, activePart))
            {
                alert(synth, "Active part disabled");
                return;
            }
            bankui->ShowSearch();
            break;

        case 15: // section parameters
            break;
        case 16: // section parameters
            break;
        case 17: // show
            bankui->Showbank();
            break;
        case 18: // load
             do_load_master("");
            break;
        case 19: // save
            {
            bool valid = false;
            for (int npart = 0; npart < NUM_MIDI_PARTS; npart ++)
                if (synth->part[npart]->Pname != DEFAULT_NAME)
                {
                    valid = true;
                    npart = NUM_MIDI_PARTS;
                }
            if (valid)
                do_save_master();
            else
                query("", "", "", "Nothing to save!");
            }
            break;
        case 20: // recent
            {
            int xpos = masterwindow->x() + (masterwindow->w() * 0.35f);
            if (xpos + paramsui->Recent->w() > masterwindow->x() + masterwindow->w())
                xpos = masterwindow->x() + masterwindow->w() - paramsui->Recent->w();
            paramsui->Recent->position(xpos,masterwindow->y()+20);
            paramsui->Show(TOPLEVEL::XML::Patch);
            }
            break;

        case 21: // section paths
            break;
        case 22: // section paths
            break;
        case 23: // root dir
            bankui->ShowRoot();
            break;
        case 24: // preset dir
            configui->Showpresets(synth);
            break;

        case 25: // section state
            break;
        case 26: // section state
            break;

        case 27: // load
            {
            // for Alessandro
            string filename = setfiler("", "", false, TOPLEVEL::XML::State);
            if (!filename.empty())
                setState(filename);
            else
                refresh_master_ui(0x80 | (textMsgBuffer.push(" ") << 8));
            }
            break;
        case 28: // save
            {
            // for Alessandro
            string filename = setfiler("", "", true, TOPLEVEL::XML::State);
            if (!filename.empty())

                send_data(TOPLEVEL::action::lowPrio | TOPLEVEL::action::forceUpdate, MAIN::control::saveNamedState, 0, TOPLEVEL::type::Integer, TOPLEVEL::section::main, UNUSED, UNUSED, UNUSED, textMsgBuffer.push(filename));
            }
            break;
        case 29: // default
            {
            string name = synth->getRuntime().defaultStateName;
            name += ("-" + to_string(instance));
            send_data(TOPLEVEL::action::lowPrio | TOPLEVEL::action::forceUpdate, MAIN::control::saveNamedState, 0, TOPLEVEL::type::Integer, TOPLEVEL::section::main, UNUSED, UNUSED, UNUSED, textMsgBuffer.push(name + ".state"));

            }
            break;
        case 30: // recent
            {
            int xpos = masterwindow->x() + (masterwindow->w() * 0.616f);
            if (xpos + paramsui->Recent->w() > masterwindow->x() + masterwindow->w())
                xpos = masterwindow->x() + masterwindow->w() - paramsui->Recent->w();
            paramsui->Recent->position(xpos,masterwindow->y()+20);

            paramsui->Show(TOPLEVEL::XML::State);
            }
            break;

        case 31: // section scales
            break;
        case 32: // section scales
            break;
        case 33: // show
            microtonalui->showScales();
            break;
        case 34: // load
            {
            filename = setfiler("", "", false, TOPLEVEL::XML::Scale);
            if (!filename.empty())
                do_load_scale(string(filename));
            }
            break;
        case 35: // save
            {
            string filename = setfiler("", "", true, TOPLEVEL::XML::Scale);
            if (!filename.empty())
                send_data(TOPLEVEL::action::lowPrio | TOPLEVEL::action::forceUpdate, MAIN::control::saveNamedScale, 0, TOPLEVEL::type::Integer, TOPLEVEL::section::main, UNUSED, UNUSED, UNUSED, textMsgBuffer.push(filename));
            }
            break;
        case 36: // recent
            paramsui->Recent->position(masterwindow->x() + masterwindow->w() - paramsui->Recent->w(), masterwindow->y()+20);
            paramsui->Show(TOPLEVEL::XML::Scale);
            break;
        case 37: // clear
            if (query("", "Yes", "No", "Set scales to the defaults?") > 1)
            {
                synth->microtonal.defaults();
                synth->setAllPartMaps();
                if (NULL != microtonalui)
                    delete microtonalui;
                microtonalui = new MicrotonalUI(&synth->microtonal, synth);
                send_data(TOPLEVEL::action::forceUpdate, SCALES::control::clearAll, 0, TOPLEVEL::type::Integer, TOPLEVEL::section::scales);
            }
            break;
      };
}
void MasterUI::cb_mastermenu(Fl_Menu_Bar* o, void* v) {
  ((MasterUI*)(o->parent()->user_data()))->cb_mastermenu_i(o,v);
}

void MasterUI::cb_globalfinedetune_i(WidgetPDial* o, void*) {
  //
          send_data(TOPLEVEL::action::lowPrio, MAIN::control::detune, o->value(), TOPLEVEL::type::Integer, TOPLEVEL::section::main);
}
void MasterUI::cb_globalfinedetune(WidgetPDial* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->user_data()))->cb_globalfinedetune_i(o,v);
}

void MasterUI::cb_mainreset_i(Fl_Button*, void*) {
  //
          bool wasCtrl = (Fl::event_state(FL_CTRL) != 0);
          if (query("", "Yes", "No", "Set *ALL* dynamic values to their defaults?") > 1)
          {
              if (wasCtrl || (Fl::event_state(FL_CTRL) != 0))
                  send_data(TOPLEVEL::action::muteAndLoop | TOPLEVEL::action::forceUpdate, MAIN::control::masterResetAndMlearn, 0, TOPLEVEL::type::Integer, TOPLEVEL::section::main);
              else
                  send_data(TOPLEVEL::action::muteAndLoop | TOPLEVEL::action::forceUpdate, MAIN::control::masterReset, 0, TOPLEVEL::type::Integer, TOPLEVEL::section::main);};
}
void MasterUI::cb_mainreset(Fl_Button* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->user_data()))->cb_mainreset_i(o,v);
}

void MasterUI::cb_mainstop_i(Fl_Button*, void*) {
  //
    send_data(TOPLEVEL::action::muteAndLoop, MAIN::control::stopSound, 0, TOPLEVEL::type::Integer, TOPLEVEL::section::main);
}
void MasterUI::cb_mainstop(Fl_Button* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->user_data()))->cb_mainstop_i(o,v);
}

void MasterUI::cb_mastervolumedial_i(WidgetPDial* o, void*) {
  //
          send_data(0, MAIN::control::volume, o->value(), 0, TOPLEVEL::section::main);
}
void MasterUI::cb_mastervolumedial(WidgetPDial* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->user_data()))->cb_mastervolumedial_i(o,v);
}

void MasterUI::cb_mainvirtkeyb_i(Fl_Button*, void*) {
  //
          virkeyboard->ShowKbd();
}
void MasterUI::cb_mainvirtkeyb(Fl_Button* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->user_data()))->cb_mainvirtkeyb_i(o,v);
}

void MasterUI::cb_mixerpanel_i(Fl_Button*, void*) {
  //
          if(panelwindow->visible())
              return;
          panelType &= 3;
          updatepanel();
          panelwindow->show();
}
void MasterUI::cb_mixerpanel(Fl_Button* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->user_data()))->cb_mixerpanel_i(o,v);
}

void MasterUI::cb_mainmidilearn_i(Fl_Button*, void*) {
  //
                midilearnui->showLearn();
}
void MasterUI::cb_mainmidilearn(Fl_Button* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->user_data()))->cb_mainmidilearn_i(o,v);
}

void MasterUI::cb_vectors_i(Fl_Button*, void*) {
  //
          vectorui->Show(synth);
}
void MasterUI::cb_vectors(Fl_Button* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->user_data()))->cb_vectors_i(o,v);
}

void MasterUI::cb_undo_i(Fl_Button*, void*) {
  //
        send_data(0, MAIN::control::undo,  0, TOPLEVEL::type::Integer, TOPLEVEL::section::undoMark);
}
void MasterUI::cb_undo(Fl_Button* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->user_data()))->cb_undo_i(o,v);
}

void MasterUI::cb_redo_i(Fl_Button*, void*) {
  //
        send_data(0, MAIN::control::redo,  0, TOPLEVEL::type::Integer, TOPLEVEL::section::undoMark);
}
void MasterUI::cb_redo(Fl_Button* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->user_data()))->cb_redo_i(o,v);
}

void MasterUI::cb_sysinsgroup_i(Fl_Tabs* o, void*) {
  //
        if (o->value() == SystemEffectsGrp)
            showSysEfxUI();
        else if (o->value() == InsertionEffectsGrp)
            showInsEfxUI();
}
void MasterUI::cb_sysinsgroup(Fl_Tabs* o, void* v) {
  ((MasterUI*)(o->parent()->user_data()))->cb_sysinsgroup_i(o,v);
}

void MasterUI::cb_syseffnocounter_i(WidgetSpinner* o, void*) {
  //
            send_data(TOPLEVEL::action::forceUpdate, EFFECT::sysIns::effectNumber, o->value() - 1, TOPLEVEL::type::Integer, TOPLEVEL::section::systemEffects, o->value() - 1);
}
void MasterUI::cb_syseffnocounter(WidgetSpinner* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->parent()->user_data()))->cb_syseffnocounter_i(o,v);
}

void MasterUI::cb_sysefftype_i(Fl_Choice* o, void*) {
  //
            send_data(TOPLEVEL::action::forceUpdate, EFFECT::sysIns::effectType, o->value(), TOPLEVEL::type::Integer, TOPLEVEL::section::systemEffects, nsyseff);
}
void MasterUI::cb_sysefftype(Fl_Choice* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->parent()->user_data()))->cb_sysefftype_i(o,v);
}

void MasterUI::cb_SysEffOn_i(Fl_Check_Button2* o, void*) {
  //
            if (o->value())
                    sysefftype->activate();
                else
                    sysefftype->deactivate();
            send_data(0, EFFECT::sysIns::effectEnable, o->value(), TOPLEVEL::type::Integer, TOPLEVEL::section::systemEffects, nsyseff);
}
void MasterUI::cb_SysEffOn(Fl_Check_Button2* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->parent()->user_data()))->cb_SysEffOn_i(o,v);
}

void MasterUI::cb_sysEffSend_i(Fl_Button*, void*) {
  //
    showSysEffSends();
}
void MasterUI::cb_sysEffSend(Fl_Button* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->parent()->user_data()))->cb_sysEffSend_i(o,v);
}

void MasterUI::cb_sysCopy_i(Fl_Button*, void*) {
  presetsui->copy(synth->sysefx[nsyseff]);
}
void MasterUI::cb_sysCopy(Fl_Button* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->parent()->user_data()))->cb_sysCopy_i(o,v);
}

void MasterUI::cb_sysPaste_i(Fl_Button*, void*) {
  //
            presetsui->paste(synth->sysefx[nsyseff], syseffectui);
            synth->getRuntime().effectChange = TOPLEVEL::section::systemEffects + (nsyseff << 8); // temporary fix;
}
void MasterUI::cb_sysPaste(Fl_Button* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->parent()->user_data()))->cb_sysPaste_i(o,v);
}

void MasterUI::cb_inseffnocounter_i(WidgetSpinner* o, void*) {
  //
            send_data(TOPLEVEL::action::forceUpdate, EFFECT::sysIns::effectNumber, o->value() - 1, TOPLEVEL::type::Integer, TOPLEVEL::section::insertEffects, o->value() - 1);
}
void MasterUI::cb_inseffnocounter(WidgetSpinner* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->parent()->user_data()))->cb_inseffnocounter_i(o,v);
}

void MasterUI::cb_insefftype_i(Fl_Choice* o, void*) {
  //
            send_data(TOPLEVEL::action::forceUpdate, EFFECT::sysIns::effectType, o->value(), TOPLEVEL::type::Integer, TOPLEVEL::section::insertEffects, ninseff);
}
void MasterUI::cb_insefftype(Fl_Choice* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->parent()->user_data()))->cb_insefftype_i(o,v);
}

void MasterUI::cb_inseffpart_i(Fl_Choice* o, void*) {
  //
            send_data(TOPLEVEL::action::forceUpdate, EFFECT::sysIns::effectDestination, o->value() - 2, TOPLEVEL::type::Integer, TOPLEVEL::section::insertEffects, ninseff);
}
void MasterUI::cb_inseffpart(Fl_Choice* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->parent()->user_data()))->cb_inseffpart_i(o,v);
}

void MasterUI::cb_insCopy_i(Fl_Button*, void*) {
  presetsui->copy(synth->insefx[ninseff]);
}
void MasterUI::cb_insCopy(Fl_Button* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->parent()->user_data()))->cb_insCopy_i(o,v);
}

void MasterUI::cb_insPaste_i(Fl_Button*, void*) {
  //
            presetsui->paste(synth->insefx[ninseff], inseffectui);
            synth->getRuntime().effectChange = TOPLEVEL::section::insertEffects + (ninseff << 8); // temporary fix;
}
void MasterUI::cb_insPaste(Fl_Button* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->parent()->user_data()))->cb_insPaste_i(o,v);
}

void MasterUI::cb_partVol_i(WidgetPDial* o, void*) {
  //
            if (npart >= panelgroup && npart < (panelgroup + NUM_MIDI_CHANNELS))
            setPanelPartVolWidget(npart % NUM_MIDI_CHANNELS, o->value());

            send_data(0, PART::control::volume, o->value(), TOPLEVEL::type::Integer, npart);
}
void MasterUI::cb_partVol(WidgetPDial* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->parent()->user_data()))->cb_partVol_i(o,v);
}

void MasterUI::cb_partPan_i(WidgetPDial* o, void*) {
  //
            if (npart >= panelgroup && npart < (panelgroup + NUM_MIDI_CHANNELS))
                setPanelPartPanWidget(npart % NUM_MIDI_CHANNELS, o->value());

            send_data(0, PART::control::panning, o->value(), TOPLEVEL::type::Integer, npart);
}
void MasterUI::cb_partPan(WidgetPDial* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->parent()->user_data()))->cb_partPan_i(o,v);
}

void MasterUI::cb_partVelOffset_i(WidgetPDial* o, void*) {
  //
            send_data(0, PART::control::velocityOffset, o->value(), TOPLEVEL::type::Integer, npart);
}
void MasterUI::cb_partVelOffset(WidgetPDial* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->parent()->user_data()))->cb_partVelOffset_i(o,v);
}

void MasterUI::cb_partVelSense_i(WidgetPDial* o, void*) {
  //
            send_data(0, PART::control::velocitySense, o->value(), TOPLEVEL::type::Integer, npart);
}
void MasterUI::cb_partVelSense(WidgetPDial* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->parent()->user_data()))->cb_partVelSense_i(o,v);
}

void MasterUI::cb_instrumentlabel_i(Fl_Button*, void*) {
  //;
}
void MasterUI::cb_instrumentlabel(Fl_Button* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_instrumentlabel_i(o,v);
}

void MasterUI::cb_buttontop_i(Fl_Button*, void*) {
  //
          int event = Fl::event_button();
          if (event == FL_LEFT_MOUSE)
          {
              synth->getGuiMaster()->activePart = npart;
              bankui->Show();
          }
          else if (event == FL_RIGHT_MOUSE)
          {
              string name = input_text(synth, "Instrument name:", synth->part[activePart]->Pname);
              if (name == DEFAULT_NAME)
                  alert(synth, "Can't use name of default sound");
              else if (name != synth->part[activePart]->Pname)
              {
                  unsigned char id = textMsgBuffer.push(name);
                  send_data(TOPLEVEL::action::lowPrio | TOPLEVEL::action::forceUpdate, PART::control::instrumentName, 0, TOPLEVEL::type::Integer, activePart, UNUSED, UNUSED, UNUSED, id);
              }
          };
}
void MasterUI::cb_buttontop(Fl_Button* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_buttontop_i(o,v);
}

void MasterUI::cb_partMidiCh_i(WidgetSpinner* o, void*) {
  //
          int tmp = int(o->value()) -1;
          if (tmp >= NUM_MIDI_CHANNELS)
          {
              tmp &= (NUM_MIDI_CHANNELS - 1);
              o->value(tmp +1);
          }
          o->textcolor(FL_BLACK);
          if (npart >= panelgroup && npart < (panelgroup + NUM_MIDI_CHANNELS))
              setPanelPartMidiWidget(npart % NUM_MIDI_CHANNELS, tmp);

          send_data(0, PART::control::midiChannel, tmp, TOPLEVEL::type::Integer, npart);
}
void MasterUI::cb_partMidiCh(WidgetSpinner* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->parent()->user_data()))->cb_partMidiCh_i(o,v);
}

void MasterUI::cb_partEdit_i(Fl_Button*, void*) {
  //
       /* bool divert = true;
        if (lastkey >= 49 && lastkey <= 56)
        { // not working yet :(
            int voiceNum = lastkey - 49;
            if (Fl::event_button() == 3)
            {
                send_data(0, PART::control::enable, 1, TOPLEVEL::type::Integer, UNUSED, 0);
                adsynenabledcheck->value(1);
                send_data(TOPLEVEL::action::forceUpdate, PART::control::volumeEnable, voiceNum, TOPLEVEL::type::Integer);
                //synth->getGuiMaster()->partui->adnoteui->advoice->nvoice = voiceNum;
                //synth->getGuiMaster()->partui->adnoteui->advoice->voiceonbutton->value(1);
            }
            if (adsynenabledcheck->value() == 1)
            {
                ;
            }
            lastkey = -1;
        }
        switch(lastkey)
        {
            case 97: // a
                if (Fl::event_button() == 3)
                {
                    send_data(0, PART::control::enableAdd, 1, TOPLEVEL::type::Integer, UNUSED, 0);
                    adsynenabledcheck->value(1);
                }

                lastkey = -1;
                if (adsynenabledcheck->value() == 1)
                {
                    showparameters(0,0);
                    partui->checkEngines();
                    seteditname();
                }
                else
                    divert = false;
                break;
            case 115: // s
                if (Fl::event_button() == 3)
                {
                    send_data(0, PART::control::enableSub, 1, TOPLEVEL::type::Integer, UNUSED, 1);
                    subsynenabledcheck->value(1);
                }
                lastkey = -1;
                if (subsynenabledcheck->value() == 1)
                {
                showparameters(0,1);
                partui->checkEngines();
                seteditname();
                }
                else
                    divert = false;
                break;
            case 100: // d
            case 112: // p
                if (Fl::event_button() == 3)
                {
                    send_data(0, PART::control::enablePad, 1, TOPLEVEL::type::Integer, UNUSED, 2);
                    padsynenabledcheck->value(1);
                }
                lastkey = -1;
                if (padsynenabledcheck->value() == 1)
                {
                    showparameters(0,2);
                    partui->checkEngines();
                    seteditname();
                    lastkey = -1;
                }
                else
                    divert = false;
                break;
            case 107: // k
                lastkey = -1;
                Showkit();
                break;
            case 101: // e
                lastkey = -1;
                Showefx();
                break;
            default:
                divert = false;
                break;
        }
        */
        //if (!divert)
        //{
            //lastkey = -1;
            partui->Showedit();
       // };
}
void MasterUI::cb_partEdit(Fl_Button* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->parent()->user_data()))->cb_partEdit_i(o,v);
}

void MasterUI::cb_partControllers_i(Fl_Button*, void*) {
  //
          partui->Showctl();
}
void MasterUI::cb_partControllers(Fl_Button* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->parent()->user_data()))->cb_partControllers_i(o,v);
}

void MasterUI::cb_partMidiCCs_i(Fl_Button*, void*) {
  //
          partui->Showctlmidi();
}
void MasterUI::cb_partMidiCCs(Fl_Button* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->parent()->user_data()))->cb_partMidiCCs_i(o,v);
}

void MasterUI::cb_partKeymode_i(Fl_Choice* o, void*) {
  //
          if (o->value() > 1 && partui->drumMode->value() != 0)
              modepatch->color(91);
          else
              modepatch->color(29);
          modepatch->redraw();
          send_data(0, PART::control::keyMode, o->value(), TOPLEVEL::type::Integer, npart);
}
void MasterUI::cb_partKeymode(Fl_Choice* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->parent()->user_data()))->cb_partKeymode_i(o,v);
}

void MasterUI::cb_partPortamento_i(Fl_Check_Button2* o, void*) {
  //
          send_data(0, PART::control::portamento, o->value(), TOPLEVEL::type::Integer, npart);
}
void MasterUI::cb_partPortamento(Fl_Check_Button2* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->parent()->user_data()))->cb_partPortamento_i(o,v);
}

void MasterUI::cb_minKeyCount_i(WidgetSpinner* o, void*) {
  //
          int tmp = o->value();
          int other = maxKeyCount->value();
          if (tmp > other)
          {
              tmp = other;
              o->value(tmp);
          }

          send_data(0, PART::control::minNote, tmp, TOPLEVEL::type::Integer, npart);
}
void MasterUI::cb_minKeyCount(WidgetSpinner* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->parent()->user_data()))->cb_minKeyCount_i(o,v);
}

void MasterUI::cb_maxKeyCount_i(WidgetSpinner* o, void*) {
  //
          int tmp = o->value();
          int other = minKeyCount->value();
          if (tmp < other)
          {
              tmp = other;
              o->value(tmp);
          }

          send_data(0, PART::control::maxNote, tmp, TOPLEVEL::type::Integer, npart);
}
void MasterUI::cb_maxKeyCount(WidgetSpinner* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->parent()->user_data()))->cb_maxKeyCount_i(o,v);
}

void MasterUI::cb_setMinToLast_i(Fl_Button*, void*) {
  //
          int lastnote = synth->part[npart]->getLastNote();
          if (lastnote >= 0)
          {
              minKeyCount->value(lastnote);
              send_data(0, PART::control::minToLastKey, 1, TOPLEVEL::type::Integer, npart);
          };
}
void MasterUI::cb_setMinToLast(Fl_Button* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->parent()->user_data()))->cb_setMinToLast_i(o,v);
}

void MasterUI::cb_setNormal_i(Fl_Button*, void*) {
  //
          minKeyCount->value(0);
          maxKeyCount->value(127);
          send_data(0, PART::control::resetMinMaxKey, 1, TOPLEVEL::type::Integer, npart);
}
void MasterUI::cb_setNormal(Fl_Button* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->parent()->user_data()))->cb_setNormal_i(o,v);
}

void MasterUI::cb_setMaxToLast_i(Fl_Button*, void*) {
  //
          int lastnote = synth->part[npart]->getLastNote();
          if (lastnote >= 0)
          {
              maxKeyCount->value(lastnote);
              send_data(0, PART::control::maxToLastKey, 1, TOPLEVEL::type::Integer, npart);
          };
}
void MasterUI::cb_setMaxToLast(Fl_Button* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->parent()->user_data()))->cb_setMaxToLast_i(o,v);
}

void MasterUI::cb_partKeyShift_i(WidgetSpinner* o, void*) {
  //
          send_data(TOPLEVEL::action::lowPrio, PART::control::keyShift, o->value(), TOPLEVEL::type::Integer, npart);
}
void MasterUI::cb_partKeyShift(WidgetSpinner* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->parent()->user_data()))->cb_partKeyShift_i(o,v);
}

void MasterUI::cb_partKeyLimit_i(WidgetSpinner* o, void*) {
  //
          send_data(0, PART::control::maxNotes, o->value(), TOPLEVEL::type::Integer, npart);
}
void MasterUI::cb_partKeyLimit(WidgetSpinner* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->parent()->user_data()))->cb_partKeyLimit_i(o,v);
}

void MasterUI::cb_sysEff1_i(WidgetPDial* o, void*) {
  //

    send_data(TOPLEVEL::action::forceUpdate, PART::partToSystemEffect1, o->value(), TOPLEVEL::type::Integer, npart);
}
void MasterUI::cb_sysEff1(WidgetPDial* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_sysEff1_i(o,v);
}

void MasterUI::cb_sysEff2_i(WidgetPDial* o, void*) {
  //

    send_data(TOPLEVEL::action::forceUpdate, PART::partToSystemEffect2, o->value(), TOPLEVEL::type::Integer, npart);
}
void MasterUI::cb_sysEff2(WidgetPDial* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_sysEff2_i(o,v);
}

void MasterUI::cb_sysEff3_i(WidgetPDial* o, void*) {
  //

    send_data(TOPLEVEL::action::forceUpdate, PART::partToSystemEffect3, o->value(), TOPLEVEL::type::Integer, npart);
}
void MasterUI::cb_sysEff3(WidgetPDial* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_sysEff3_i(o,v);
}

void MasterUI::cb_sysEff4_i(WidgetPDial* o, void*) {
  //

    send_data(TOPLEVEL::action::forceUpdate, PART::partToSystemEffect4, o->value(), TOPLEVEL::type::Integer, npart);
}
void MasterUI::cb_sysEff4(WidgetPDial* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_sysEff4_i(o,v);
}

void MasterUI::cb_partEnable_i(Fl_Check_Button2* o, void*) {
  //;
        if (o->value() != 1)
            partControls->deactivate();
        else
            partControls->activate();

        if (npart >= panelgroup && npart < (panelgroup + NUM_MIDI_CHANNELS))
        {
            panellistitem[npart % NUM_MIDI_CHANNELS]->partenabled->value(o->value());
            if (o->value() != 1)
                panellistitem[npart % NUM_MIDI_CHANNELS]->panellistitemgroup->deactivate();
            else
                panellistitem[npart % NUM_MIDI_CHANNELS]->panellistitemgroup->activate();
        }

        send_data(0, PART::control::enable, o->value(), TOPLEVEL::type::Integer, npart);
}
void MasterUI::cb_partEnable(Fl_Check_Button2* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->user_data()))->cb_partEnable_i(o,v);
}

void MasterUI::cb__i(Fl_Button*, void*) {
  vumeter->init(-1, synth);
}
void MasterUI::cb_(Fl_Button* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->user_data()))->cb__i(o,v);
}

void MasterUI::cb_mastermono_i(Fl_Button* o, void*) {
  //
        int tmp = 1 -  o->value();
        o->value(tmp);
        if (tmp == 0)
            o->label("Stereo");
        else
            o->label("Mono");
        send_data(0, MAIN::control::mono,  tmp, TOPLEVEL::type::Integer, TOPLEVEL::section::main);
}
void MasterUI::cb_mastermono(Fl_Button* o, void* v) {
  ((MasterUI*)(o->parent()->user_data()))->cb_mastermono_i(o,v);
}

void MasterUI::cb_masterkeyshift_i(WidgetSpinner* o, void*) {
  //
        send_data(TOPLEVEL::action::lowPrio, MAIN::control::keyShift, o->value(), TOPLEVEL::type::Integer, TOPLEVEL::section::main);
}
void MasterUI::cb_masterkeyshift(WidgetSpinner* o, void* v) {
  ((MasterUI*)(o->parent()->user_data()))->cb_masterkeyshift_i(o,v);
}

void MasterUI::cb_bpmfallback_i(WidgetSpinner* o, void*) {
  //
        send_data(TOPLEVEL::action::forceUpdate, MAIN::control::bpmFallback, o->value(), 0, TOPLEVEL::section::main);
}
void MasterUI::cb_bpmfallback(WidgetSpinner* o, void* v) {
  ((MasterUI*)(o->parent()->user_data()))->cb_bpmfallback_i(o,v);
}

void MasterUI::cb_npartcounter_i(WidgetSpinner* o, void*) {
  //
        int nval = o->value() - 1;
        activePart = nval;
        send_data(TOPLEVEL::action::forceUpdate, MAIN::control::partNumber, nval, TOPLEVEL::type::Integer, TOPLEVEL::section::main);
}
void MasterUI::cb_npartcounter(WidgetSpinner* o, void* v) {
  ((MasterUI*)(o->parent()->user_data()))->cb_npartcounter_i(o,v);
}

void MasterUI::cb_maxparts_i(WidgetSpinner* o, void*) {
  //
        int tmp = o->value();
        if (tmp == 48)
        {
            if (partmax == 32)
                tmp = 64;
            else
                tmp = 32;
        }
        send_data(TOPLEVEL::action::forceUpdate, MAIN::control::availableParts, tmp, TOPLEVEL::type::Integer, TOPLEVEL::section::main);
}
void MasterUI::cb_maxparts(WidgetSpinner* o, void* v) {
  ((MasterUI*)(o->parent()->user_data()))->cb_maxparts_i(o,v);
}

void MasterUI::cb_panning_law_i(Fl_Choice* o, void*) {
  //
                       send_data(0, MAIN::control::panLawType, o->value(), TOPLEVEL::type::Integer, TOPLEVEL::section::main);
}
void MasterUI::cb_panning_law(Fl_Choice* o, void* v) {
  ((MasterUI*)(o->parent()->user_data()))->cb_panning_law_i(o,v);
}

void MasterUI::cb_1_i(Fl_Button*, void*) {
  //;
}
void MasterUI::cb_1(Fl_Button* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->user_data()))->cb_1_i(o,v);
}

void MasterUI::cb_cancelInst_i(Fl_Button*, void*) {
  //;
}
void MasterUI::cb_cancelInst(Fl_Button* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->user_data()))->cb_cancelInst_i(o,v);
}

void MasterUI::cb_nextInst_i(Fl_Button*, void*) {
  //;
}
void MasterUI::cb_nextInst(Fl_Button* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->user_data()))->cb_nextInst_i(o,v);
}

void MasterUI::cb_valueInst_i(Fl_Input*, void*) {
  //;
}
void MasterUI::cb_valueInst(Fl_Input* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->user_data()))->cb_valueInst_i(o,v);
}

void MasterUI::cb_about5_i(Fl_Button*, void*) {
  //
                 contributors->show();
                 aboutFirst->hide();
}
void MasterUI::cb_about5(Fl_Button* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->user_data()))->cb_about5_i(o,v);
}

void MasterUI::cb_aboutClose_i(Fl_Button*, void*) {
  //
        aboutFirst->show();
        contributors->hide();
        aboutwindow->hide();
}
void MasterUI::cb_aboutClose(Fl_Button* o, void* v) {
  ((MasterUI*)(o->parent()->user_data()))->cb_aboutClose_i(o,v);
}

void MasterUI::cb_syseffsendwindow_i(Fl_Double_Window*, void*) {
  syseffClose->do_callback();
}
void MasterUI::cb_syseffsendwindow(Fl_Double_Window* o, void* v) {
  ((MasterUI*)(o->user_data()))->cb_syseffsendwindow_i(o,v);
}

void MasterUI::cb_syseffClose_i(Fl_Button*, void*) {
  //
    saveWin(synth, syseffsendwindow->w(), syseffsendwindow->h(), syseffsendwindow->x(), syseffsendwindow->y(), false, "Master-systemeffectsend");
    syseffsendwindow->hide();
    syseffSeen = false;
}
void MasterUI::cb_syseffClose(Fl_Button* o, void* v) {
  ((MasterUI*)(o->parent()->user_data()))->cb_syseffClose_i(o,v);
}

void MasterUI::cb_panelwindow_i(Fl_Double_Window*, void*) {
  Panelclose->do_callback();
}
void MasterUI::cb_panelwindow(Fl_Double_Window* o, void* v) {
  ((MasterUI*)(o->user_data()))->cb_panelwindow_i(o,v);
}

void MasterUI::cb_towide_i(Fl_Button*, void*) {
  //
        changepanelstyle(1);
}
void MasterUI::cb_towide(Fl_Button* o, void* v) {
  ((MasterUI*)(o->parent()->user_data()))->cb_towide_i(o,v);
}

void MasterUI::cb_todeep_i(Fl_Button*, void*) {
  //
        changepanelstyle(2);
}
void MasterUI::cb_todeep(Fl_Button* o, void* v) {
  ((MasterUI*)(o->parent()->user_data()))->cb_todeep_i(o,v);
}

void MasterUI::cb_Panelgroups_i(Fl_Choice* o, void*) {
  //
        int result = o->value();
        panelgroup = result * NUM_MIDI_CHANNELS;
        for (int i = 0; i < NUM_MIDI_CHANNELS; ++i)
            panellistitem[i]->refresh();
}
void MasterUI::cb_Panelgroups(Fl_Choice* o, void* v) {
  ((MasterUI*)(o->parent()->user_data()))->cb_Panelgroups_i(o,v);
}

void MasterUI::cb_Panelsmallgroups_i(Fl_Choice* o, void*) {
  //
        panelgroup = o->value() * NUM_MIDI_CHANNELS;
        for (int i = 0; i < NUM_MIDI_CHANNELS; ++i)
            panellistitem[i]->refresh();
}
void MasterUI::cb_Panelsmallgroups(Fl_Choice* o, void* v) {
  ((MasterUI*)(o->parent()->user_data()))->cb_Panelsmallgroups_i(o,v);
}

void MasterUI::cb_CSspinner_i(WidgetSpinner*, void*) {
  //
        CSpend->show();
}
void MasterUI::cb_CSspinner(WidgetSpinner* o, void* v) {
  ((MasterUI*)(o->parent()->user_data()))->cb_CSspinner_i(o,v);
}

void MasterUI::cb_CSpend_i(Fl_Button* o, void*) {
  //
        CS_CC = synth->getRuntime().channelSwitchCC;
        int candidate = CSspinner->value();
        if (candidate == CS_CC)
        {
            o->hide();
            return;
        }

        string name = synth->getRuntime().masterCCtest(candidate);
        if (!name.empty())
        {
            query("", "", "", "In use for " + name);
            if (CS_CC < 128)
            {
                CSspinner->value(CS_CC);
                CSspinner->redraw();
            }

        }
        else
        {
            send_data(TOPLEVEL::action::forceUpdate, MAIN::control::soloCC, CSspinner->value(), TOPLEVEL::type::Integer, TOPLEVEL::section::main);
        };
}
void MasterUI::cb_CSpend(Fl_Button* o, void* v) {
  ((MasterUI*)(o->parent()->user_data()))->cb_CSpend_i(o,v);
}

void MasterUI::cb_channelswitch_i(Fl_Choice* o, void*) {
  //
                send_data(TOPLEVEL::action::forceUpdate, MAIN::control::soloType, o->value(), TOPLEVEL::type::Integer, TOPLEVEL::section::main);
}
void MasterUI::cb_channelswitch(Fl_Choice* o, void* v) {
  ((MasterUI*)(o->parent()->user_data()))->cb_channelswitch_i(o,v);
}

void MasterUI::cb_Panelclose_i(Fl_Button*, void*) {
  //
    panelType |= 4;
    saveWin(synth, panelwindow->w(), panelwindow->h(), panelwindow->x(), panelwindow->y(), panelType, "Mixer");
    panelwindow->hide();
}
void MasterUI::cb_Panelclose(Fl_Button* o, void* v) {
  ((MasterUI*)(o->parent()->user_data()))->cb_Panelclose_i(o,v);
}

void MasterUI::cb_yesdoit_i(Fl_Button*, void*) {
  //
                send_data(TOPLEVEL::action::lowPrio | TOPLEVEL::action::forceUpdate, BANK::control::refreshDefaults, 1, TOPLEVEL::type::Integer, TOPLEVEL::section::bank);
                closebutton->do_callback();
}
void MasterUI::cb_yesdoit(Fl_Button* o, void* v) {
  ((MasterUI*)(o->parent()->user_data()))->cb_yesdoit_i(o,v);
}

void MasterUI::cb_cancel_i(Fl_Button*, void*) {
  //
                if (msgGroup == TOPLEVEL::msgResponse::refreshBankDefaults)
                    send_data(TOPLEVEL::action::lowPrio, BANK::control::refreshDefaults, 0, TOPLEVEL::type::Integer, TOPLEVEL::section::bank);
                else
                    send_data(0, MIDILEARN::control::cancelLearn, 0, 3, TOPLEVEL::section::midiLearn);
                closebutton->do_callback();
}
void MasterUI::cb_cancel(Fl_Button* o, void* v) {
  ((MasterUI*)(o->parent()->user_data()))->cb_cancel_i(o,v);
}

void MasterUI::cb_closebutton_i(Fl_Button*, void*) {
  //
                yesdoit->hide();
                cancel->hide();
                message->hide();
                msgSeen = false;
}
void MasterUI::cb_closebutton(Fl_Button* o, void* v) {
  ((MasterUI*)(o->parent()->user_data()))->cb_closebutton_i(o,v);
}

void MasterUI::cb_querywindow_i(Fl_Double_Window*, void *) {
  cancelQ->do_callback();
}
void MasterUI::cb_querywindow(Fl_Double_Window* o, void * v) {
  ((MasterUI*)(o->user_data()))->cb_querywindow_i(o,v);
}

void MasterUI::cb_yesQ_i(Fl_Button*, void*) {
  //
    querywindow->hide();
}
void MasterUI::cb_yesQ(Fl_Button* o, void* v) {
  ((MasterUI*)(o->parent()->user_data()))->cb_yesQ_i(o,v);
}

void MasterUI::cb_noQ_i(Fl_Button*, void*) {
  //
    querywindow->hide();
}
void MasterUI::cb_noQ(Fl_Button* o, void* v) {
  ((MasterUI*)(o->parent()->user_data()))->cb_noQ_i(o,v);
}

void MasterUI::cb_cancelQ_i(Fl_Button*, void*) {
  //
    querywindow->hide();
}
void MasterUI::cb_cancelQ(Fl_Button* o, void* v) {
  ((MasterUI*)(o->parent()->user_data()))->cb_cancelQ_i(o,v);
}

void MasterUI::cb_textwindow_i(Fl_Double_Window* o, void*) {
  //
      saveWin(synth, o->w(), o->h(), o->x(), o->y(), false, "Master-textin");
      o->hide();
}
void MasterUI::cb_textwindow(Fl_Double_Window* o, void* v) {
  ((MasterUI*)(o->user_data()))->cb_textwindow_i(o,v);
}

void MasterUI::cb_filerwindow_i(Fl_Double_Window*, void*) {
  //
        filerclose->do_callback();
}
void MasterUI::cb_filerwindow(Fl_Double_Window* o, void* v) {
  ((MasterUI*)(o->user_data()))->cb_filerwindow_i(o,v);
}

void MasterUI::cb_fileroldpath_i(Fl_Input* o, void*) {
  //
        if (Fl::event_key() == FL_Enter)
        {
            filernewname->value("");
            string name = string(o->value());
            if (name.back() != '/')
                name += "/";
            if(!file::isDirectory(name))
            {
                if (!dosave && extension != TOPLEVEL::XML::Dir && extension != TOPLEVEL::XML::Bank)
                {
                    alert(synth, "Not a valid path to load from.");
                    return;
                }
                if (choice(synth, "", "Yes", "No", "Add to path?") < 2)
                    return;
                if (file::createDir(name))
                {
                    alert(synth, "Unable to change a path here.");
                    return;
                }
            }
            filerpath = name;
            o->value(name.c_str());
            fillfiler(type_name);
        };
}
void MasterUI::cb_fileroldpath(Fl_Input* o, void* v) {
  ((MasterUI*)(o->parent()->user_data()))->cb_fileroldpath_i(o,v);
}

void MasterUI::cb_filerback_i(Fl_Button*, void*) {
  //
        if (filerpath == "/")
            return;
        filernewname->value("");
        size_t pos = filerpath.rfind('/', filerpath.length() - 2);
        filerpath = filerpath.substr(0, pos +1);
        if (filerpath.empty())
            filerpath = "/";
        fileroldpath->value(filerpath.c_str());
        fillfiler(type_name);
}
void MasterUI::cb_filerback(Fl_Button* o, void* v) {
  ((MasterUI*)(o->parent()->user_data()))->cb_filerback_i(o,v);
}

void MasterUI::cb_filerfave_i(Fl_Button*, void*) {
  //
        setfavourites();
}
void MasterUI::cb_filerfave(Fl_Button* o, void* v) {
  ((MasterUI*)(o->parent()->user_data()))->cb_filerfave_i(o,v);
}

void MasterUI::cb_faveadd_i(Fl_Button*, void*) {
  //
    string name = string(fileroldpath->value());
    if (name.back() != '/')
        name += "/";
    if (!file::isDirectory(name))
    {
        alert(synth, "Not a valid path");;
        return;
    }
    fileroldpath->value(name.c_str());
    filerpath = name;
    favebrowse->add(name.c_str());
    setfavourites();
}
void MasterUI::cb_faveadd(Fl_Button* o, void* v) {
  ((MasterUI*)(o->parent()->user_data()))->cb_faveadd_i(o,v);
}

void MasterUI::cb_filerclose_i(Fl_Button*, void*) {
  //
        filerfound.clear();
        filerdone = true;
        filernewname->value("Exit");
        saveWin(synth, filerwindow->w(), filerwindow->h(), filerwindow->x(), filerwindow->y(), false, "Master-filer");
}
void MasterUI::cb_filerclose(Fl_Button* o, void* v) {
  ((MasterUI*)(o->parent()->user_data()))->cb_filerclose_i(o,v);
}

void MasterUI::cb_filernewname_i(Fl_Input*, void*) {
  //
      if (Fl::event_key() == FL_Enter)
          fileruse->do_callback();
}
void MasterUI::cb_filernewname(Fl_Input* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->user_data()))->cb_filernewname_i(o,v);
}

void MasterUI::cb_fileruse_i(Fl_Button*, void*) {
  //
        filerpath = string(fileroldpath->value());
        if (filerpath.back() != '/')
        {
            filerpath += '/';
            fileroldpath->value(filerpath.c_str());
        }
        string leaf = string(filernewname->value());
        if (!dosave || !leaf.empty())
            filerfound = filerpath + leaf;
        // error picked up in main loop
        filerdone = true;
}
void MasterUI::cb_fileruse(Fl_Button* o, void* v) {
  ((MasterUI*)(o->parent()->user_data()))->cb_fileruse_i(o,v);
}

void MasterUI::cb_filerOpt8_i(Fl_Check_Button2* o, void*) {
  //
    if (o->value() != 0)
        filerOpt1->deactivate();
    else
        filerOpt1->activate();
    fillfiler(type_name);
}
void MasterUI::cb_filerOpt8(Fl_Check_Button2* o, void* v) {
  ((MasterUI*)(o->parent()->user_data()))->cb_filerOpt8_i(o,v);
}

void MasterUI::cb_filerOpt1_i(Fl_Check_Button2*, void*) {
  //
    fillfiler(type_name);
}
void MasterUI::cb_filerOpt1(Fl_Check_Button2* o, void* v) {
  ((MasterUI*)(o->parent()->user_data()))->cb_filerOpt1_i(o,v);
}

void MasterUI::cb_filerOpt2_i(Fl_Check_Button2*, void*) {
  //
    fillfiler(type_name);
}
void MasterUI::cb_filerOpt2(Fl_Check_Button2* o, void* v) {
  ((MasterUI*)(o->parent()->user_data()))->cb_filerOpt2_i(o,v);
}

void MasterUI::cb_filerOpt16_i(Fl_Check_Button2*, void*) {
  //
    ;
}
void MasterUI::cb_filerOpt16(Fl_Check_Button2* o, void* v) {
  ((MasterUI*)(o->parent()->user_data()))->cb_filerOpt16_i(o,v);
}

void MasterUI::cb_favebrowse_i(Fl_Browser*, void*) {
  //
        if (!favebrowse->value())
            return;
        int result = favebrowse->value();
        if (result < 1)
            return;
        if (Fl::event_clicks())
        {
            Fl::event_clicks(0);
            faveset->do_callback();
        }
        clearfavelist();
        setfavecolour(result);
}
void MasterUI::cb_favebrowse(Fl_Browser* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->user_data()))->cb_favebrowse_i(o,v);
}

void MasterUI::cb_favecancel_i(Fl_Button*, void*) {
  //
    fileroldpath->activate();
    filernewname->activate();
    fileruse->activate();
    filerback->activate();
    filerfave->activate();
    filerclose->activate();
    filerscroll->show();
    favourites->hide();
}
void MasterUI::cb_favecancel(Fl_Button* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->user_data()))->cb_favecancel_i(o,v);
}

void MasterUI::cb_favedefault_i(Fl_Button*, void*) {
  //
    size_t pos = favebrowse->value();
    if (pos > 0)
        favebrowse->move(1, pos);
}
void MasterUI::cb_favedefault(Fl_Button* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->user_data()))->cb_favedefault_i(o,v);
}

void MasterUI::cb_favedelete_i(Fl_Button*, void*) {
  //
    clearfavelist();
    size_t pos = favebrowse->value();
    setfavecolour(1);
    if (pos > 0)
        favebrowse->remove(pos);
}
void MasterUI::cb_favedelete(Fl_Button* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->user_data()))->cb_favedelete_i(o,v);
}

void MasterUI::cb_faveset_i(Fl_Button*, void*) {
  //
    size_t pos = favebrowse->value();
    if (pos > 0)
        filerpath = clearfavecolour(pos);
    else
       filerpath = clearfavecolour(1);

    if (filerpath.back() != '/')
        filerpath += '/';
    fileroldpath->value(filerpath.c_str());
    fillfiler(type_name);
    favecancel->do_callback();
}
void MasterUI::cb_faveset(Fl_Button* o, void* v) {
  ((MasterUI*)(o->parent()->parent()->user_data()))->cb_faveset_i(o,v);
}

MasterUI::MasterUI(SynthEngine *_synth) {
  //
        synth = _synth;
        presetsui = NULL;
        ninseff = 0;
        nsyseff = 0;
        npart = 0;
        panelgroup = 0;
        panelScale = 1;
        for (int i = 0; i < NUM_SYS_EFX; ++i)
        {
            for (int j = 0; j < NUM_SYS_EFX; ++j)
                syseffsend[i][j] = NULL;
        }
        microtonalui = NULL;
        bankui = NULL;
        virkeyboard = NULL;
        configui = NULL;
        presetsui = NULL;
        paramsui = NULL;
        activePart = 0;
        yoshiLog = NULL;
        queryDW = 0;
  
        lastmainW = -1;
        lastpanelW = 0;
        lastmsgW = 0;
        lasttextW = 0;
        lastsyseffW = 0;
        lastvirtW = 0;
        lastaboutW = 0;
        oldH = 0;
  
        filerpath.clear();
        lastfilerW = 0;
}

MasterUI::~MasterUI() {
  //
        aboutwindow->hide();
        delete aboutwindow;
  
        syseffsendwindow->hide();
        if (syseffSeen)
            saveWin(synth, syseffsendwindow->w(), syseffsendwindow->h(), syseffsendwindow->x(), syseffsendwindow->y(), true, "Master-systemeffectsend");
        delete syseffsendwindow;
  
        if (panelType < 4)
            saveWin(synth, panelwindow->w(), panelwindow->h(), panelwindow->x(), panelwindow->y(), panelType, "Mixer");
        panelwindow->hide();
        delete panelwindow;
  
        message->hide();
        delete message;
  
        if (microtonalui)
            delete microtonalui;
  
        if (bankui)
            delete bankui;
  
        if (virkeyboard)
            delete virkeyboard;
  
        if (configui)
            delete configui;
  
        if (presetsui)
            delete presetsui;
  
        if (paramsui)
            delete paramsui;
  
        if (vectorui)
            delete vectorui;
  
        if (midilearnui)
            delete midilearnui;
  
        if (yoshiLog)
            delete yoshiLog;
  
        if (querywindow)
        {
            querywindow->hide();
            delete querywindow;
        }
  
        if (filerwindow)
        {
            filerlist.clear();
            if (filerwindow->visible())
                saveWin(synth, filerwindow->w(), filerwindow->h(), filerwindow->x(), filerwindow->y(), true, "Master-filer");
            filerwindow->hide();
            delete filerwindow;
        }
  
        saveWin(synth, masterwindow->w(), masterwindow->h(), masterwindow->x(), masterwindow->y(), true, "Master");
  
        masterwindow->hide();
        delete masterwindow;
}

void MasterUI::Init(const char *_label) {
  //
        instance = synth->getUniqueId();
        file::createDir(file::configDir() + "/windows");
        panelType = 5;
        msgSeen = false;
        syseffSeen = false;
        partmax = synth->getRuntime().NumAvailableParts;
        microtonalui = new MicrotonalUI(&synth->microtonal, synth);
        bankui = new BankUI(synth);
        virkeyboard = new VirKeyboard(synth);
        configui = new ConfigUI(synth);
        presetsui = new PresetsUI(synth);
        paramsui = new ParametersUI(synth);
        vectorui = new VectorUI(synth, bankui, paramsui);
        midilearnui = new MidiLearnUI(synth);
        yoshiLog = new ConsoleUI(synth);
        make_window();
        bool foundWindows = Showmaster();
  
        partui = new PartUI(0, 0, 0, 0);
        partuigroup->add(partui); // why?
        partui->init(synth->part[npart], npart, bankui);
        partui->kitRtext(true);
        partui->redraw();
  
        partui->checkEngines();
        if (instance > 0)
            foundWindows = true; //  not relevant for later windows
        //std::cout << "Found windows " << int(foundWindows) << std::endl;
        loadWindowData();
        string starterror = "";
        if (synth->getIsLV2Plugin())
        {
            masterwindow->label(_label);
        }
        else
        {
            starterror = textMsgBuffer.fetch(0);
            setMasterLabel(synth->getRuntime().paramsLoad);
        }
        if (starterror.find("Could not") != std::string::npos)
            query("", "", "", starterror);
        microtonalui->microtonaluiwindow->copy_label(synth->makeUniqueName("Scales").c_str());
        yoshiLog->logConsole->copy_label(synth->makeUniqueName("Console").c_str());
        logenable = fetchData(0, CONFIG::control::reportsDestination, TOPLEVEL::section::config);
        if (!foundWindows)
        {
            // fake previously seen.
            saveWin(synth, 0, 0, masterwindow->x() + masterwindow->w() + 16, masterwindow->y(), true, "Midi-virtualkeyboard");
            virkeyboard->ShowKbd();
            panelwindow->resize(masterwindow->x(), masterwindow->y(), PANEL_SINGLE_X, PANEL_SINGLE_Y);
            saveWin(synth, panelwindow->w(), panelwindow->h(), panelwindow->x(), panelwindow->y(), panelType, "Mixer");
            string msg = "As this is a first time start, please check 'Yoshimi->Settings' then save and restart. More information can be found in the manual.";
            setmessage(UNUSED, true, msg, "Close");
        }
        else if (synth->getRuntime().oldConfig)
        {
            string msg;
            msg = "Existing config older than V " + to_string(MIN_CONFIG_MAJOR) + "." + to_string(MIN_CONFIG_MINOR) + " \nCheck settings, save and restart.";
            setmessage(UNUSED, true, msg, "Close");
        }
        else if (instance == 0 && synth->getRuntime().banksChecked == false)
        {
            string msg = "Default banks have been copied to {user}.local/share/yoshimi/found \nAdd these to the bank roots window?";
            setmessage(TOPLEVEL::msgResponse::refreshBankDefaults, true, msg, "Ask Later", "No", "Yes");} {}
}

bool MasterUI::Showmaster() {
  //
      int fetchW, fetchH, fetchX, fetchY, fetchO;
      loadWin(synth, fetchW, fetchH, fetchX, fetchY, fetchO, "Master");
      if (fetchW < mainDW || fetchH < mainDH)
      {
          fetchW = mainDW;
          fetchH = mainDH;
      }
      checkSane(fetchX, fetchY, fetchW, fetchH, mainDW, mainDH);
  
      masterwindow->resize(fetchX, fetchY, fetchW, fetchH);
      masterwindow->show();
      lastmainW = 0;
      mainRtext();
  
      return (fetchO != 0);
}

Fl_Double_Window* MasterUI::make_window() {
  { masterwindow = new Fl_Double_Window(385, 500, "Yoshimi meets ZynAddSubFX");
    masterwindow->labelfont(13);
    masterwindow->labelsize(12);
    masterwindow->callback((Fl_Callback*)cb_masterwindow, (void*)(this));
    { KeyHandle* o = keyHandle = new KeyHandle(0, 0, 385, 500, "keyhandler");
      keyHandle->box(FL_FLAT_BOX);
      keyHandle->color(FL_BACKGROUND_COLOR);
      keyHandle->selection_color(FL_BACKGROUND_COLOR);
      keyHandle->labeltype(FL_NORMAL_LABEL);
      keyHandle->labelfont(0);
      keyHandle->labelsize(14);
      keyHandle->labelcolor(FL_FOREGROUND_COLOR);
      keyHandle->align(Fl_Align(FL_ALIGN_CENTER));
      keyHandle->when(FL_WHEN_RELEASE);
      o->init(synth);
    } // KeyHandle* keyHandle
    { topcontrols = new Fl_Box(271, 28, 111, 115);
      topcontrols->box(FL_ENGRAVED_FRAME);
    } // Fl_Box* topcontrols
    { Fl_Menu_Bar* o = mastermenu = new Fl_Menu_Bar(-7, 0, 395, 25);
      mastermenu->labelsize(12);
      mastermenu->textsize(12);
      mastermenu->callback((Fl_Callback*)cb_mastermenu);
      //
        o->add("&Yoshimi  /&About...");
        o->add("&Yoshimi  /&New Instance");
        o->add("&Yoshimi  /&Settings...");
        o->add("&Yoshimi  /&Reports");
        o->add("&Yoshimi  /&View Manual");
        o->add("&Yoshimi  /&Exit");

        o->add("&Instrument  /S&how Stored...");
        o->add("&Instrument  /&Load External...");
        o->add("&Instrument  /&Save External...");
        o->add("&Instrument  /&Recent Instruments...");
        o->add("&Instrument  /&Clear");
        o->add("&Instrument  /S&earch...");

        o->add("&PatchSet  /&S&how Patch Banks...");
        o->add("&PatchSet  /&Load External...");
        o->add("&PatchSet  /&Save External...");
        o->add("&PatchSet  /&Recent sets...");

        o->add("Pat&h  /&Bank Root Dirs...");
        o->add("Pat&h  /&Preset Dirs...");

        o->add("&State  /&Load...");
        o->add("&State  /&Save...");
        o->add("&State  /&Save As default");
        o->add("&State  /&Recent States");

        o->add("S&cale/S&how Settings...");
        o->add("S&cale/&Load...");
        o->add("S&cale/&Save...");
        o->add("S&cale/&Recent Scales...");
    } // Fl_Menu_Bar* mastermenu
    { MasterControls = new Fl_Group(3, 24, 380, 121, "Master  ");
      MasterControls->labeltype(FL_NO_LABEL);
      MasterControls->labelsize(11);
      MasterControls->labelcolor((Fl_Color)96);
      MasterControls->align(Fl_Align(FL_ALIGN_BOTTOM_LEFT|FL_ALIGN_INSIDE));
      { WidgetPDial* o = globalfinedetune = new WidgetPDial(280, 32, 40, 40, "Detune");
        globalfinedetune->tooltip("Global Fine Detune");
        globalfinedetune->box(FL_ROUND_UP_BOX);
        globalfinedetune->color((Fl_Color)29);
        globalfinedetune->selection_color(FL_INACTIVE_COLOR);
        globalfinedetune->labeltype(FL_NORMAL_LABEL);
        globalfinedetune->labelfont(0);
        globalfinedetune->labelsize(10);
        globalfinedetune->labelcolor(FL_FOREGROUND_COLOR);
        globalfinedetune->maximum(127);
        globalfinedetune->step(1);
        globalfinedetune->value(64);
        globalfinedetune->callback((Fl_Callback*)cb_globalfinedetune);
        globalfinedetune->align(Fl_Align(FL_ALIGN_BOTTOM));
        globalfinedetune->when(FL_WHEN_CHANGED);
        o->setValueType(VC_GlobalFineDetune);
        o->value(synth->microtonal.Pglobalfinedetune);
      } // WidgetPDial* globalfinedetune
      { mainreset = new Fl_Button(7, 60, 68, 24, "Reset");
        mainreset->tooltip("Clear all dynamic settings\n(+Ctrl includes MIDI-learn)");
        mainreset->box(FL_PLASTIC_UP_BOX);
        mainreset->color((Fl_Color)228);
        mainreset->selection_color(FL_GRAY0);
        mainreset->labelfont(1);
        mainreset->labelsize(11);
        mainreset->callback((Fl_Callback*)cb_mainreset);
        mainreset->align(Fl_Align(FL_ALIGN_CENTER|FL_ALIGN_INSIDE));
      } // Fl_Button* mainreset
      { mainstop = new Fl_Button(7, 30, 68, 24, "Stop!");
        mainstop->tooltip("Cease all sound immediately!");
        mainstop->box(FL_PLASTIC_UP_BOX);
        mainstop->color(FL_RED);
        mainstop->selection_color(FL_FOREGROUND_COLOR);
        mainstop->labelfont(1);
        mainstop->labelsize(11);
        mainstop->callback((Fl_Callback*)cb_mainstop);
        mainstop->align(Fl_Align(FL_ALIGN_CENTER|FL_ALIGN_INSIDE));
      } // Fl_Button* mainstop
      { WidgetPDial* o = mastervolumedial = new WidgetPDial(331, 32, 40, 40, "Volume");
        mastervolumedial->tooltip("Master Volume");
        mastervolumedial->box(FL_ROUND_UP_BOX);
        mastervolumedial->color((Fl_Color)29);
        mastervolumedial->selection_color(FL_INACTIVE_COLOR);
        mastervolumedial->labeltype(FL_NORMAL_LABEL);
        mastervolumedial->labelfont(0);
        mastervolumedial->labelsize(10);
        mastervolumedial->labelcolor(FL_FOREGROUND_COLOR);
        mastervolumedial->maximum(127);
        mastervolumedial->step(1);
        mastervolumedial->callback((Fl_Callback*)cb_mastervolumedial);
        mastervolumedial->align(Fl_Align(FL_ALIGN_BOTTOM));
        mastervolumedial->when(FL_WHEN_CHANGED);
        o->setValueType(VC_MasterVolume);
        o->value(synth->Pvolume);
      } // WidgetPDial* mastervolumedial
      { mainvirtkeyb = new Fl_Button(83, 60, 106, 24, "Virtual Keyboard");
        mainvirtkeyb->tooltip("Virtual Keyboard");
        mainvirtkeyb->box(FL_PLASTIC_UP_BOX);
        mainvirtkeyb->color((Fl_Color)228);
        mainvirtkeyb->labelsize(11);
        mainvirtkeyb->labelcolor(FL_GRAY0);
        mainvirtkeyb->callback((Fl_Callback*)cb_mainvirtkeyb);
      } // Fl_Button* mainvirtkeyb
      { mixerpanel = new Fl_Button(83, 30, 106, 24, "Mixer Panel");
        mixerpanel->tooltip("Mixer Panel Window");
        mixerpanel->box(FL_PLASTIC_UP_BOX);
        mixerpanel->color((Fl_Color)228);
        mixerpanel->labelsize(11);
        mixerpanel->labelcolor(FL_GRAY0);
        mixerpanel->callback((Fl_Callback*)cb_mixerpanel);
      } // Fl_Button* mixerpanel
      { mainmidilearn = new Fl_Button(83, 90, 106, 24, "Midi Learn");
        mainmidilearn->tooltip("Message Log");
        mainmidilearn->box(FL_PLASTIC_UP_BOX);
        mainmidilearn->color((Fl_Color)228);
        mainmidilearn->labelsize(11);
        mainmidilearn->callback((Fl_Callback*)cb_mainmidilearn);
      } // Fl_Button* mainmidilearn
      { vectors = new Fl_Button(197, 30, 68, 24, "Vectors");
        vectors->tooltip("Vector Setup Window");
        vectors->box(FL_PLASTIC_UP_BOX);
        vectors->color((Fl_Color)228);
        vectors->labelsize(11);
        vectors->labelcolor(FL_GRAY0);
        vectors->callback((Fl_Callback*)cb_vectors);
      } // Fl_Button* vectors
      { undo = new Fl_Button(197, 60, 68, 24, "Undo");
        undo->tooltip("Revert last change");
        undo->box(FL_PLASTIC_UP_BOX);
        undo->color((Fl_Color)228);
        undo->labelsize(11);
        undo->callback((Fl_Callback*)cb_undo);
      } // Fl_Button* undo
      { redo = new Fl_Button(197, 90, 68, 24, "Redo");
        redo->tooltip("Re-apply last change");
        redo->box(FL_PLASTIC_UP_BOX);
        redo->color((Fl_Color)228);
        redo->labelsize(11);
        redo->callback((Fl_Callback*)cb_redo);
      } // Fl_Button* redo
      MasterControls->end();
    } // Fl_Group* MasterControls
    { sysinsgroup = new Fl_Tabs(3, 118, 379, 68, "System/Insert");
      sysinsgroup->box(FL_PLASTIC_UP_BOX);
      sysinsgroup->color((Fl_Color)44);
      sysinsgroup->selection_color((Fl_Color)221);
      sysinsgroup->labeltype(FL_NO_LABEL);
      sysinsgroup->labelsize(12);
      sysinsgroup->callback((Fl_Callback*)cb_sysinsgroup);
      sysinsgroup->align(Fl_Align(FL_ALIGN_TOP_LEFT));
      { SystemEffectsGrp = new Fl_Group(3, 146, 379, 40, "  System Effects  ");
        SystemEffectsGrp->color((Fl_Color)221);
        SystemEffectsGrp->selection_color((Fl_Color)31);
        SystemEffectsGrp->labelfont(1);
        SystemEffectsGrp->labelsize(12);
        SystemEffectsGrp->align(Fl_Align(FL_ALIGN_LEFT));
        { WidgetSpinner* o = syseffnocounter = new WidgetSpinner(40, 156, 36, 20, "Effect");
          syseffnocounter->box(FL_NO_BOX);
          syseffnocounter->color(FL_BACKGROUND_COLOR);
          syseffnocounter->selection_color(FL_BACKGROUND_COLOR);
          syseffnocounter->labeltype(FL_NO_LABEL);
          syseffnocounter->labelfont(0);
          syseffnocounter->labelsize(11);
          syseffnocounter->labelcolor(FL_FOREGROUND_COLOR);
          syseffnocounter->maximum(4);
          syseffnocounter->textfont(1);
          syseffnocounter->textsize(11);
          syseffnocounter->callback((Fl_Callback*)cb_syseffnocounter);
          syseffnocounter->align(Fl_Align(FL_ALIGN_CENTER));
          syseffnocounter->when(FL_WHEN_RELEASE);
          o->range(1, NUM_SYS_EFX);
          o->value(nsyseff + 1);
        } // WidgetSpinner* syseffnocounter
        { Fl_Choice* o = sysefftype = new Fl_Choice(120, 156, 96, 20, "Type");
          sysefftype->down_box(FL_BORDER_BOX);
          sysefftype->labeltype(FL_NO_LABEL);
          sysefftype->labelsize(11);
          sysefftype->textfont(1);
          sysefftype->textsize(11);
          sysefftype->callback((Fl_Callback*)cb_sysefftype);
          sysefftype->align(Fl_Align(FL_ALIGN_CENTER|FL_ALIGN_INSIDE));
          o->add("No Effect");o->add("Reverb");o->add("Echo");o->add("Chorus");o->add("Phaser");o->add("AlienWah");o->add("Distortion");o->add("EQ");o->add("DynFilter");
          o->value(synth->sysefx[nsyseff]->geteffect());
        } // Fl_Choice* sysefftype
        { SysEffOn = new Fl_Check_Button2(247, 159, 16, 15, "On");
          SysEffOn->box(FL_NO_BOX);
          SysEffOn->down_box(FL_DOWN_BOX);
          SysEffOn->value(1);
          SysEffOn->color(FL_BACKGROUND_COLOR);
          SysEffOn->selection_color(FL_FOREGROUND_COLOR);
          SysEffOn->labeltype(FL_NORMAL_LABEL);
          SysEffOn->labelfont(1);
          SysEffOn->labelsize(11);
          SysEffOn->labelcolor(FL_FOREGROUND_COLOR);
          SysEffOn->callback((Fl_Callback*)cb_SysEffOn);
          SysEffOn->align(Fl_Align(FL_ALIGN_LEFT));
          SysEffOn->when(FL_WHEN_RELEASE);
        } // Fl_Check_Button2* SysEffOn
        { sysEffSend = new Fl_Button(275, 156, 62, 20, "Send to");
          sysEffSend->box(FL_THIN_UP_BOX);
          sysEffSend->labelfont(1);
          sysEffSend->labelsize(11);
          sysEffSend->labelcolor((Fl_Color)97);
          sysEffSend->callback((Fl_Callback*)cb_sysEffSend);
        } // Fl_Button* sysEffSend
        { sysCopy = new Fl_Button(350, 152, 25, 14, "C");
          sysCopy->box(FL_THIN_UP_BOX);
          sysCopy->color((Fl_Color)179);
          sysCopy->labelfont(1);
          sysCopy->labelsize(11);
          sysCopy->labelcolor(FL_BACKGROUND2_COLOR);
          sysCopy->callback((Fl_Callback*)cb_sysCopy);
        } // Fl_Button* sysCopy
        { sysPaste = new Fl_Button(350, 167, 25, 14, "P");
          sysPaste->box(FL_THIN_UP_BOX);
          sysPaste->color((Fl_Color)179);
          sysPaste->labelfont(1);
          sysPaste->labelsize(11);
          sysPaste->labelcolor(FL_BACKGROUND2_COLOR);
          sysPaste->callback((Fl_Callback*)cb_sysPaste);
        } // Fl_Button* sysPaste
        SystemEffectsGrp->end();
      } // Fl_Group* SystemEffectsGrp
      { InsertionEffectsGrp = new Fl_Group(3, 146, 379, 40, " Insertion Effects ");
        InsertionEffectsGrp->color((Fl_Color)221);
        InsertionEffectsGrp->selection_color((Fl_Color)31);
        InsertionEffectsGrp->labelfont(1);
        InsertionEffectsGrp->labelsize(12);
        InsertionEffectsGrp->labelcolor((Fl_Color)33);
        InsertionEffectsGrp->align(Fl_Align(FL_ALIGN_LEFT));
        InsertionEffectsGrp->hide();
        { WidgetSpinner* o = inseffnocounter = new WidgetSpinner(40, 156, 36, 20, "Effect");
          inseffnocounter->box(FL_NO_BOX);
          inseffnocounter->color(FL_BACKGROUND_COLOR);
          inseffnocounter->selection_color(FL_BACKGROUND_COLOR);
          inseffnocounter->labeltype(FL_NO_LABEL);
          inseffnocounter->labelfont(0);
          inseffnocounter->labelsize(11);
          inseffnocounter->labelcolor(FL_FOREGROUND_COLOR);
          inseffnocounter->maximum(8);
          inseffnocounter->textfont(1);
          inseffnocounter->textsize(11);
          inseffnocounter->callback((Fl_Callback*)cb_inseffnocounter);
          inseffnocounter->align(Fl_Align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE));
          inseffnocounter->when(FL_WHEN_RELEASE);
          o->range(1, NUM_INS_EFX);
          o->value(ninseff + 1);
        } // WidgetSpinner* inseffnocounter
        { Fl_Choice* o = insefftype = new Fl_Choice(120, 156, 96, 20, "Type");
          insefftype->down_box(FL_BORDER_BOX);
          insefftype->labeltype(FL_NO_LABEL);
          insefftype->labelsize(11);
          insefftype->textfont(1);
          insefftype->textsize(11);
          insefftype->callback((Fl_Callback*)cb_insefftype);
          insefftype->align(Fl_Align(FL_ALIGN_CENTER));
          o->add("No Effect");o->add("Reverb");o->add("Echo");o->add("Chorus");o->add("Phaser");o->add("AlienWah");o->add("Distortion");o->add("EQ");o->add("DynFilter");
          o->value(synth->insefx[ninseff]->geteffect());
          if (synth->Pinsparts[ninseff]== -1) o->deactivate();
        } // Fl_Choice* insefftype
        { Fl_Choice* o = inseffpart = new Fl_Choice(242, 156, 96, 20, "To ");
          inseffpart->down_box(FL_BORDER_BOX);
          inseffpart->labelfont(1);
          inseffpart->labelsize(11);
          inseffpart->textfont(1);
          inseffpart->textsize(11);
          inseffpart->callback((Fl_Callback*)cb_inseffpart);
          setinspartlist();
          o->value(synth->Pinsparts[ninseff]+2);
        } // Fl_Choice* inseffpart
        { insCopy = new Fl_Button(350, 152, 25, 14, "C");
          insCopy->box(FL_THIN_UP_BOX);
          insCopy->color((Fl_Color)179);
          insCopy->labelfont(1);
          insCopy->labelsize(11);
          insCopy->labelcolor(FL_BACKGROUND2_COLOR);
          insCopy->callback((Fl_Callback*)cb_insCopy);
        } // Fl_Button* insCopy
        { insPaste = new Fl_Button(350, 167, 25, 14, "P");
          insPaste->box(FL_THIN_UP_BOX);
          insPaste->color((Fl_Color)179);
          insPaste->labelfont(1);
          insPaste->labelsize(11);
          insPaste->labelcolor(FL_BACKGROUND2_COLOR);
          insPaste->callback((Fl_Callback*)cb_insPaste);
        } // Fl_Button* insPaste
        InsertionEffectsGrp->end();
      } // Fl_Group* InsertionEffectsGrp
      sysinsgroup->end();
    } // Fl_Tabs* sysinsgroup
    { Fl_Group* o = syseffectuigroup = new Fl_Group(3, 188, 379, 95);
      syseffectuigroup->box(FL_FLAT_BOX);
      syseffectuigroup->color((Fl_Color)48);
      syseffectuigroup->labeltype(FL_NO_LABEL);
      { EffUI* o = syseffectui = new EffUI(3, 188, 379, 95);
        syseffectui->box(FL_NO_BOX);
        syseffectui->color(FL_BACKGROUND_COLOR);
        syseffectui->selection_color(FL_BACKGROUND_COLOR);
        syseffectui->labeltype(FL_NO_LABEL);
        syseffectui->labelfont(0);
        syseffectui->labelsize(14);
        syseffectui->labelcolor(FL_FOREGROUND_COLOR);
        syseffectui->align(Fl_Align(FL_ALIGN_TOP));
        syseffectui->when(FL_WHEN_RELEASE);
        o->init(synth->sysefx[nsyseff], TOPLEVEL::section::systemEffects, nsyseff);o->activate();o->show();
        syseffectui->end();
      } // EffUI* syseffectui
      o->show();
      syseffectuigroup->end();
    } // Fl_Group* syseffectuigroup
    { Fl_Group* o = inseffectuigroup = new Fl_Group(3, 188, 379, 95);
      inseffectuigroup->box(FL_FLAT_BOX);
      inseffectuigroup->color((Fl_Color)48);
      { EffUI* o = inseffectui = new EffUI(3, 188, 379, 95);
        inseffectui->box(FL_NO_BOX);
        inseffectui->color(FL_LIGHT2);
        inseffectui->selection_color(FL_BACKGROUND_COLOR);
        inseffectui->labeltype(FL_NORMAL_LABEL);
        inseffectui->labelfont(0);
        inseffectui->labelsize(14);
        inseffectui->labelcolor(FL_FOREGROUND_COLOR);
        inseffectui->align(Fl_Align(FL_ALIGN_TOP));
        inseffectui->when(FL_WHEN_RELEASE);
        o->init(synth->insefx[ninseff], TOPLEVEL::section::insertEffects, ninseff);o->hide();
        if (synth->Pinsparts[ninseff]== -1) o->deactivate();
        inseffectui->end();
      } // EffUI* inseffectui
      o->hide();
      inseffectuigroup->end();
    } // Fl_Group* inseffectuigroup
    { partuigroup = new Fl_Group(3, 285, 379, 178);
      partuigroup->box(FL_ENGRAVED_FRAME);
      { PartUI* o = partui = new PartUI(3, 285, 379, 172);
        partui->box(FL_NO_BOX);
        partui->color(FL_DARK1);
        partui->selection_color(FL_BACKGROUND_COLOR);
        partui->labeltype(FL_NORMAL_LABEL);
        partui->labelfont(0);
        partui->labelsize(14);
        partui->labelcolor(FL_FOREGROUND_COLOR);
        partui->align(Fl_Align(FL_ALIGN_TOP));
        partui->when(FL_WHEN_RELEASE);
        o->init(synth->part[0],0,bankui);
        partui->end();
      } // PartUI* partui
      { partControls = new Fl_Group(3, 286, 378, 175);
        { WidgetPDial* o = partVol = new WidgetPDial(340, 327, 32, 32, "Volume");
          partVol->box(FL_OVAL_BOX);
          partVol->color(FL_BACKGROUND_COLOR);
          partVol->selection_color(FL_INACTIVE_COLOR);
          partVol->labeltype(FL_NORMAL_LABEL);
          partVol->labelfont(0);
          partVol->labelsize(10);
          partVol->labelcolor(FL_FOREGROUND_COLOR);
          partVol->maximum(127);
          partVol->step(1);
          partVol->callback((Fl_Callback*)cb_partVol);
          partVol->align(Fl_Align(FL_ALIGN_BOTTOM));
          partVol->when(FL_WHEN_CHANGED);
          o->value(fetchData(0, PART::control::volume, npart));
        } // WidgetPDial* partVol
        { WidgetPDial* o = partPan = new WidgetPDial(292, 327, 32, 32, "Panning");
          partPan->box(FL_OVAL_BOX);
          partPan->color(FL_BACKGROUND_COLOR);
          partPan->selection_color(FL_INACTIVE_COLOR);
          partPan->labeltype(FL_NORMAL_LABEL);
          partPan->labelfont(0);
          partPan->labelsize(10);
          partPan->labelcolor(FL_FOREGROUND_COLOR);
          partPan->maximum(127);
          partPan->step(1);
          partPan->callback((Fl_Callback*)cb_partPan);
          partPan->align(Fl_Align(FL_ALIGN_BOTTOM));
          partPan->when(FL_WHEN_CHANGED);
          o->value(fetchData(0, PART::control::panning, npart));
        } // WidgetPDial* partPan
        { WidgetPDial* o = partVelOffset = new WidgetPDial(244, 327, 32, 32, "Vel.Offs");
          partVelOffset->box(FL_OVAL_BOX);
          partVelOffset->color(FL_BACKGROUND_COLOR);
          partVelOffset->selection_color(FL_INACTIVE_COLOR);
          partVelOffset->labeltype(FL_NORMAL_LABEL);
          partVelOffset->labelfont(0);
          partVelOffset->labelsize(10);
          partVelOffset->labelcolor(FL_FOREGROUND_COLOR);
          partVelOffset->maximum(127);
          partVelOffset->step(1);
          partVelOffset->callback((Fl_Callback*)cb_partVelOffset);
          partVelOffset->align(Fl_Align(FL_ALIGN_BOTTOM));
          partVelOffset->when(FL_WHEN_CHANGED);
          o->value(fetchData(0, PART::control::velocityOffset, npart));
        } // WidgetPDial* partVelOffset
        { WidgetPDial* o = partVelSense = new WidgetPDial(196, 327, 32, 32, "Vel.Sense");
          partVelSense->box(FL_OVAL_BOX);
          partVelSense->color(FL_BACKGROUND_COLOR);
          partVelSense->selection_color(FL_INACTIVE_COLOR);
          partVelSense->labeltype(FL_NORMAL_LABEL);
          partVelSense->labelfont(0);
          partVelSense->labelsize(10);
          partVelSense->labelcolor(FL_FOREGROUND_COLOR);
          partVelSense->maximum(127);
          partVelSense->step(1);
          partVelSense->callback((Fl_Callback*)cb_partVelSense);
          partVelSense->align(Fl_Align(FL_ALIGN_BOTTOM));
          partVelSense->when(FL_WHEN_CHANGED);
          o->value(fetchData(0, PART::control::velocitySense, npart));
        } // WidgetPDial* partVelSense
        { instrumentGroup = new Fl_Group(136, 292, 195, 24);
          instrumentGroup->box(FL_PLASTIC_UP_BOX);
          instrumentGroup->color((Fl_Color)228);
          { instrumentaddbox = new Fl_Box(139, 297, 62, 14);
            instrumentaddbox->box(FL_FLAT_BOX);
            instrumentaddbox->color((Fl_Color)17);
          } // Fl_Box* instrumentaddbox
          { instrumentsubbox = new Fl_Box(200, 297, 65, 14);
            instrumentsubbox->box(FL_FLAT_BOX);
            instrumentsubbox->color((Fl_Color)17);
          } // Fl_Box* instrumentsubbox
          { instrumentpadbox = new Fl_Box(264, 297, 63, 14);
            instrumentpadbox->box(FL_FLAT_BOX);
            instrumentpadbox->color((Fl_Color)17);
          } // Fl_Box* instrumentpadbox
          { instrumentlabel = new Fl_Button(139, 295, 187, 16, "Simple Sound");
            instrumentlabel->tooltip("Left mouse button: choose/save/.. from/to bank, Right button: instrument name");
            instrumentlabel->box(FL_NO_BOX);
            instrumentlabel->labelsize(12);
            instrumentlabel->callback((Fl_Callback*)cb_instrumentlabel);
            instrumentlabel->align(Fl_Align(FL_ALIGN_CENTER|FL_ALIGN_INSIDE));
          } // Fl_Button* instrumentlabel
          { instrumentFrame = new Fl_Box(139, 296, 188, 16);
            instrumentFrame->box(FL_PLASTIC_DOWN_FRAME);
            instrumentFrame->color((Fl_Color)237);
          } // Fl_Box* instrumentFrame
          { buttontop = new Fl_Button(136, 292, 195, 24);
            buttontop->tooltip("Left mouse button: choose/save/.. from/to bank, Right button: instrument name");
            buttontop->box(FL_NO_BOX);
            buttontop->labeltype(FL_NO_LABEL);
            buttontop->labelsize(12);
            buttontop->callback((Fl_Callback*)cb_buttontop);
            buttontop->align(Fl_Align(FL_ALIGN_CENTER|FL_ALIGN_INSIDE));
          } // Fl_Button* buttontop
          instrumentGroup->end();
        } // Fl_Group* instrumentGroup
        { WidgetSpinner* o = partMidiCh = new WidgetSpinner(34, 350, 40, 19, "Midi");
          partMidiCh->tooltip("MIDI channel for this part");
          partMidiCh->box(FL_NO_BOX);
          partMidiCh->color(FL_BACKGROUND_COLOR);
          partMidiCh->selection_color(FL_BACKGROUND_COLOR);
          partMidiCh->labeltype(FL_NORMAL_LABEL);
          partMidiCh->labelfont(0);
          partMidiCh->labelsize(11);
          partMidiCh->labelcolor(FL_FOREGROUND_COLOR);
          partMidiCh->maximum(16);
          partMidiCh->textsize(11);
          partMidiCh->callback((Fl_Callback*)cb_partMidiCh);
          partMidiCh->align(Fl_Align(FL_ALIGN_LEFT));
          partMidiCh->when(FL_WHEN_RELEASE);
          int num = fetchData(0,  PART::control::midiChannel, npart); o->value(num + 1); if (num < NUM_MIDI_CHANNELS) o->textcolor(FL_BLACK); else o->textcolor(FL_WHITE);
        } // WidgetSpinner* partMidiCh
        { partEdit = new Fl_Button(334, 292, 42, 24, "Edit");
          partEdit->tooltip("View/change instrument sound and details");
          partEdit->box(FL_PLASTIC_UP_BOX);
          partEdit->color((Fl_Color)228);
          partEdit->labelfont(1);
          partEdit->labelsize(12);
          partEdit->callback((Fl_Callback*)cb_partEdit);
        } // Fl_Button* partEdit
        { partControllers = new Fl_Button(8, 373, 86, 22, "Controllers");
          partControllers->tooltip("MIDI Controller range settings");
          partControllers->box(FL_PLASTIC_UP_BOX);
          partControllers->color((Fl_Color)228);
          partControllers->labelsize(12);
          partControllers->callback((Fl_Callback*)cb_partControllers);
        } // Fl_Button* partControllers
        { partMidiCCs = new Fl_Button(100, 373, 60, 22, "Midi CCs");
          partMidiCCs->tooltip("Emulates common MIDI CCs");
          partMidiCCs->box(FL_PLASTIC_UP_BOX);
          partMidiCCs->color((Fl_Color)228);
          partMidiCCs->labelsize(12);
          partMidiCCs->callback((Fl_Callback*)cb_partMidiCCs);
        } // Fl_Button* partMidiCCs
        { modepatch = new Fl_Box(155, 328, 32, 17, "Mode");
          modepatch->box(FL_FLAT_BOX);
          modepatch->color((Fl_Color)29);
          modepatch->labelsize(11);
        } // Fl_Box* modepatch
        { Fl_Choice* o = partKeymode = new Fl_Choice(82, 327, 68, 19);
          partKeymode->tooltip("Poly, Mono or Legato mode");
          partKeymode->down_box(FL_BORDER_BOX);
          partKeymode->selection_color(FL_BACKGROUND_COLOR);
          partKeymode->labelsize(11);
          partKeymode->textfont(1);
          partKeymode->textsize(11);
          partKeymode->callback((Fl_Callback*)cb_partKeymode);
          partKeymode->align(Fl_Align(FL_ALIGN_RIGHT));
          o->add("Poly");o->add("Mono");o->add("Legato");
          int tmp = synth->ReadPartKeyMode(npart); if (tmp > 1) o->value(2); else o->value(tmp);
          o->value(fetchData(0, PART::control::keyMode, npart));
        } // Fl_Choice* partKeymode
        { portamento_patch = new Fl_Box(81, 351, 18, 18);
          portamento_patch->box(FL_THIN_UP_BOX);
          portamento_patch->color((Fl_Color)237);
        } // Fl_Box* portamento_patch
        { Fl_Check_Button2* o = partPortamento = new Fl_Check_Button2(84, 351, 18, 18, "Portamento");
          partPortamento->tooltip("Enable/Disable the portamento");
          partPortamento->box(FL_NO_BOX);
          partPortamento->down_box(FL_DOWN_BOX);
          partPortamento->color(FL_BACKGROUND_COLOR);
          partPortamento->selection_color(FL_FOREGROUND_COLOR);
          partPortamento->labeltype(FL_NORMAL_LABEL);
          partPortamento->labelfont(0);
          partPortamento->labelsize(11);
          partPortamento->labelcolor(FL_FOREGROUND_COLOR);
          partPortamento->callback((Fl_Callback*)cb_partPortamento);
          partPortamento->align(Fl_Align(FL_ALIGN_RIGHT));
          partPortamento->when(FL_WHEN_RELEASE);
          o->value(fetchData(0, PART::control::portamento, npart));
        } // Fl_Check_Button2* partPortamento
        { WidgetSpinner* o = minKeyCount = new WidgetSpinner(59, 402, 42, 20, "Min Note");
          minKeyCount->tooltip("Minimum note the part receives");
          minKeyCount->box(FL_NO_BOX);
          minKeyCount->color(FL_BACKGROUND_COLOR);
          minKeyCount->selection_color(FL_BACKGROUND_COLOR);
          minKeyCount->labeltype(FL_NORMAL_LABEL);
          minKeyCount->labelfont(0);
          minKeyCount->labelsize(10);
          minKeyCount->labelcolor(FL_FOREGROUND_COLOR);
          minKeyCount->minimum(0);
          minKeyCount->maximum(127);
          minKeyCount->textsize(11);
          minKeyCount->callback((Fl_Callback*)cb_minKeyCount);
          minKeyCount->align(Fl_Align(FL_ALIGN_LEFT));
          minKeyCount->when(FL_WHEN_RELEASE);
          o->value(fetchData(0, PART::control::minNote, npart));
        } // WidgetSpinner* minKeyCount
        { WidgetSpinner* o = maxKeyCount = new WidgetSpinner(59, 434, 42, 20, "Max Note");
          maxKeyCount->tooltip("Maximum note the part receives");
          maxKeyCount->box(FL_NO_BOX);
          maxKeyCount->color(FL_BACKGROUND_COLOR);
          maxKeyCount->selection_color(FL_BACKGROUND_COLOR);
          maxKeyCount->labeltype(FL_NORMAL_LABEL);
          maxKeyCount->labelfont(0);
          maxKeyCount->labelsize(10);
          maxKeyCount->labelcolor(FL_FOREGROUND_COLOR);
          maxKeyCount->minimum(0);
          maxKeyCount->maximum(127);
          maxKeyCount->textsize(11);
          maxKeyCount->callback((Fl_Callback*)cb_maxKeyCount);
          maxKeyCount->align(Fl_Align(FL_ALIGN_LEFT));
          maxKeyCount->when(FL_WHEN_RELEASE);
          o->value(fetchData(0, PART::control::maxNote, npart));
        } // WidgetSpinner* maxKeyCount
        { setMinToLast = new Fl_Button(105, 403, 30, 16, "Set");
          setMinToLast->tooltip("Set minimum note to the last note played");
          setMinToLast->box(FL_PLASTIC_UP_BOX);
          setMinToLast->labelsize(10);
          setMinToLast->callback((Fl_Callback*)cb_setMinToLast);
        } // Fl_Button* setMinToLast
        { setNormal = new Fl_Button(105, 421, 30, 16, "R");
          setNormal->tooltip("Reset the minimum key to 0 and maximum key to 127");
          setNormal->box(FL_PLASTIC_UP_BOX);
          setNormal->labelfont(1);
          setNormal->labelsize(11);
          setNormal->callback((Fl_Callback*)cb_setNormal);
        } // Fl_Button* setNormal
        { setMaxToLast = new Fl_Button(105, 439, 30, 16, "Set");
          setMaxToLast->tooltip("Set maximum note to the last note played");
          setMaxToLast->box(FL_PLASTIC_UP_BOX);
          setMaxToLast->labelsize(10);
          setMaxToLast->callback((Fl_Callback*)cb_setMaxToLast);
        } // Fl_Button* setMaxToLast
        { WidgetSpinner* o = partKeyShift = new WidgetSpinner(195, 403, 38, 20, "Key Shift");
          partKeyShift->box(FL_NO_BOX);
          partKeyShift->color(FL_BACKGROUND_COLOR);
          partKeyShift->selection_color(FL_BACKGROUND_COLOR);
          partKeyShift->labeltype(FL_NORMAL_LABEL);
          partKeyShift->labelfont(0);
          partKeyShift->labelsize(10);
          partKeyShift->labelcolor(FL_FOREGROUND_COLOR);
          partKeyShift->minimum(-36);
          partKeyShift->maximum(36);
          partKeyShift->textsize(11);
          partKeyShift->callback((Fl_Callback*)cb_partKeyShift);
          partKeyShift->align(Fl_Align(FL_ALIGN_LEFT));
          partKeyShift->when(FL_WHEN_RELEASE);
          o->range(MIN_KEY_SHIFT, MAX_KEY_SHIFT);
          o->value(fetchData(0, PART::control::keyShift, npart));
        } // WidgetSpinner* partKeyShift
        { WidgetSpinner* o = partKeyLimit = new WidgetSpinner(195, 435, 38, 20, "Key Limit");
          partKeyLimit->tooltip("Maximum keys for this part");
          partKeyLimit->box(FL_NO_BOX);
          partKeyLimit->color(FL_BACKGROUND_COLOR);
          partKeyLimit->selection_color(FL_BACKGROUND_COLOR);
          partKeyLimit->labeltype(FL_NORMAL_LABEL);
          partKeyLimit->labelfont(0);
          partKeyLimit->labelsize(10);
          partKeyLimit->labelcolor(FL_FOREGROUND_COLOR);
          partKeyLimit->value(20);
          partKeyLimit->textsize(11);
          partKeyLimit->callback((Fl_Callback*)cb_partKeyLimit);
          partKeyLimit->align(Fl_Align(FL_ALIGN_LEFT));
          partKeyLimit->when(FL_WHEN_RELEASE);
          o->range(1, POLYPHONY); // enough for one part!
          o->value(fetchData(0, PART::control::maxNotes, npart));
        } // WidgetSpinner* partKeyLimit
        { sysEffBox = new Fl_Group(240, 400, 134, 58);
          sysEffBox->box(FL_ENGRAVED_FRAME);
          { sysEffName = new Fl_Text_Display(255, 440, 103, 1, "Send to System Effect");
            sysEffName->box(FL_NO_BOX);
            sysEffName->labelsize(11);
            sysEffName->align(Fl_Align(FL_ALIGN_BOTTOM));
          } // Fl_Text_Display* sysEffName
          { WidgetPDial* o = sysEff1 = new WidgetPDial(246, 415, 25, 25, "1");
            sysEff1->box(FL_OVAL_BOX);
            sysEff1->color(FL_BACKGROUND_COLOR);
            sysEff1->selection_color(FL_INACTIVE_COLOR);
            sysEff1->labeltype(FL_NORMAL_LABEL);
            sysEff1->labelfont(1);
            sysEff1->labelsize(10);
            sysEff1->labelcolor(FL_FOREGROUND_COLOR);
            sysEff1->maximum(127);
            sysEff1->step(1);
            sysEff1->callback((Fl_Callback*)cb_sysEff1);
            sysEff1->align(Fl_Align(FL_ALIGN_TOP));
            sysEff1->when(FL_WHEN_CHANGED);
            o->value(fetchData(0, PART::control::partToSystemEffect1, npart));
          } // WidgetPDial* sysEff1
          { WidgetPDial* o = sysEff2 = new WidgetPDial(278, 415, 25, 25, "2");
            sysEff2->box(FL_OVAL_BOX);
            sysEff2->color(FL_BACKGROUND_COLOR);
            sysEff2->selection_color(FL_INACTIVE_COLOR);
            sysEff2->labeltype(FL_NORMAL_LABEL);
            sysEff2->labelfont(1);
            sysEff2->labelsize(10);
            sysEff2->labelcolor(FL_FOREGROUND_COLOR);
            sysEff2->maximum(127);
            sysEff2->step(1);
            sysEff2->callback((Fl_Callback*)cb_sysEff2);
            sysEff2->align(Fl_Align(FL_ALIGN_TOP));
            sysEff2->when(FL_WHEN_CHANGED);
            o->value(fetchData(0, PART::control::partToSystemEffect2, npart));
          } // WidgetPDial* sysEff2
          { WidgetPDial* o = sysEff3 = new WidgetPDial(310, 415, 25, 25, "3");
            sysEff3->box(FL_OVAL_BOX);
            sysEff3->color(FL_BACKGROUND_COLOR);
            sysEff3->selection_color(FL_INACTIVE_COLOR);
            sysEff3->labeltype(FL_NORMAL_LABEL);
            sysEff3->labelfont(1);
            sysEff3->labelsize(10);
            sysEff3->labelcolor(FL_FOREGROUND_COLOR);
            sysEff3->maximum(127);
            sysEff3->step(1);
            sysEff3->callback((Fl_Callback*)cb_sysEff3);
            sysEff3->align(Fl_Align(FL_ALIGN_TOP));
            sysEff3->when(FL_WHEN_CHANGED);
            o->value(fetchData(0, PART::control::partToSystemEffect3, npart));
          } // WidgetPDial* sysEff3
          { WidgetPDial* o = sysEff4 = new WidgetPDial(342, 415, 25, 25, "4");
            sysEff4->box(FL_OVAL_BOX);
            sysEff4->color(FL_BACKGROUND_COLOR);
            sysEff4->selection_color(FL_INACTIVE_COLOR);
            sysEff4->labeltype(FL_NORMAL_LABEL);
            sysEff4->labelfont(1);
            sysEff4->labelsize(10);
            sysEff4->labelcolor(FL_FOREGROUND_COLOR);
            sysEff4->maximum(127);
            sysEff4->step(1);
            sysEff4->callback((Fl_Callback*)cb_sysEff4);
            sysEff4->align(Fl_Align(FL_ALIGN_TOP));
            sysEff4->when(FL_WHEN_CHANGED);
            o->value(fetchData(0, PART::control::partToSystemEffect4, npart));
          } // WidgetPDial* sysEff4
          sysEffBox->end();
        } // Fl_Group* sysEffBox
        partControls->end();
      } // Fl_Group* partControls
      { Fl_Check_Button2* o = partEnable = new Fl_Check_Button2(58, 326, 20, 20, "On");
        partEnable->box(FL_NO_BOX);
        partEnable->down_box(FL_DOWN_BOX);
        partEnable->color(FL_BACKGROUND_COLOR);
        partEnable->selection_color(FL_FOREGROUND_COLOR);
        partEnable->labeltype(FL_NORMAL_LABEL);
        partEnable->labelfont(0);
        partEnable->labelsize(14);
        partEnable->labelcolor(FL_FOREGROUND_COLOR);
        partEnable->callback((Fl_Callback*)cb_partEnable);
        partEnable->align(Fl_Align(FL_ALIGN_LEFT));
        partEnable->when(FL_WHEN_RELEASE);
        o->value(fetchData(0,  PART::control::enable, npart));
      } // Fl_Check_Button2* partEnable
      partuigroup->end();
    } // Fl_Group* partuigroup
    { Fl_Group* o = new Fl_Group(3, 460, 379, 35);
      o->box(FL_DOWN_BOX);
      o->color((Fl_Color)43);
      o->labelsize(12);
      { VUMeter* o = vumeter = new VUMeter(3, 461, 379, 34, "VU-Meter");
        vumeter->box(FL_NO_BOX);
        vumeter->color((Fl_Color)48);
        vumeter->selection_color((Fl_Color)75);
        vumeter->labeltype(FL_NORMAL_LABEL);
        vumeter->labelfont(0);
        vumeter->labelsize(14);
        vumeter->labelcolor(FL_FOREGROUND_COLOR);
        vumeter->align(Fl_Align(FL_ALIGN_CENTER));
        vumeter->when(FL_WHEN_RELEASE);
        o->init(-1, synth);
      } // VUMeter* vumeter
      { Fl_Button* o = new Fl_Button(5, 463, 376, 30);
        o->tooltip("Click here to clear VU peak reading and overload warning.");
        o->box(FL_NO_BOX);
        o->callback((Fl_Callback*)cb_);
      } // Fl_Button* o
      o->end();
    } // Fl_Group* o
    { Fl_Button* o = mastermono = new Fl_Button(7, 90, 68, 24, "Stereo");
      mastermono->tooltip("Master Mono/Stereo switch");
      mastermono->box(FL_PLASTIC_UP_BOX);
      mastermono->down_box(FL_PLASTIC_UP_BOX);
      mastermono->color((Fl_Color)228);
      mastermono->selection_color((Fl_Color)130);
      mastermono->labelfont(1);
      mastermono->labelsize(11);
      mastermono->callback((Fl_Callback*)cb_mastermono);
      o->value(synth->masterMono);
    } // Fl_Button* mastermono
    { WidgetSpinner* o = masterkeyshift = new WidgetSpinner(328, 88, 43, 20, "Key Shift");
      masterkeyshift->tooltip("Shift pitch +/- N semitones");
      masterkeyshift->box(FL_NO_BOX);
      masterkeyshift->color(FL_BACKGROUND_COLOR);
      masterkeyshift->selection_color(FL_BACKGROUND_COLOR);
      masterkeyshift->labeltype(FL_NORMAL_LABEL);
      masterkeyshift->labelfont(0);
      masterkeyshift->labelsize(10);
      masterkeyshift->labelcolor(FL_FOREGROUND_COLOR);
      masterkeyshift->minimum(-36);
      masterkeyshift->maximum(36);
      masterkeyshift->textfont(1);
      masterkeyshift->textsize(12);
      masterkeyshift->callback((Fl_Callback*)cb_masterkeyshift);
      masterkeyshift->align(Fl_Align(FL_ALIGN_LEFT));
      masterkeyshift->when(FL_WHEN_RELEASE);
      o->range(MIN_KEY_SHIFT, MAX_KEY_SHIFT);o->step(1.0);
      o->value(synth->Pkeyshift - 64);
    } // WidgetSpinner* masterkeyshift
    { WidgetSpinner* o = bpmfallback = new WidgetSpinner(316, 116, 56, 20, "F. BPM");
      bpmfallback->tooltip("Fallback BPM (Beats Per Minute). This is only used if the MIDI driver does no\
t provide its own BPM information.");
      bpmfallback->box(FL_NO_BOX);
      bpmfallback->color(FL_BACKGROUND_COLOR);
      bpmfallback->selection_color(FL_BACKGROUND_COLOR);
      bpmfallback->labeltype(FL_NORMAL_LABEL);
      bpmfallback->labelfont(0);
      bpmfallback->labelsize(10);
      bpmfallback->labelcolor(FL_FOREGROUND_COLOR);
      bpmfallback->minimum(0);
      bpmfallback->maximum(0);
      bpmfallback->value(120);
      bpmfallback->textfont(1);
      bpmfallback->textsize(12);
      bpmfallback->callback((Fl_Callback*)cb_bpmfallback);
      bpmfallback->align(Fl_Align(FL_ALIGN_LEFT));
      bpmfallback->when(FL_WHEN_RELEASE);
      o->range(BPM_FALLBACK_MIN, BPM_FALLBACK_MAX);
      o->step(1.0); o->type(FL_FLOAT_INPUT);
      setBpmFallbackValue(synth->PbpmFallback);
    } // WidgetSpinner* bpmfallback
    { WidgetSpinner* o = npartcounter = new WidgetSpinner(36, 293, 40, 22, "Part");
      npartcounter->box(FL_NO_BOX);
      npartcounter->color(FL_BACKGROUND_COLOR);
      npartcounter->selection_color(FL_BACKGROUND_COLOR);
      npartcounter->labeltype(FL_NORMAL_LABEL);
      npartcounter->labelfont(0);
      npartcounter->labelsize(11);
      npartcounter->labelcolor(FL_FOREGROUND_COLOR);
      npartcounter->minimum(0);
      npartcounter->maximum(127);
      npartcounter->textsize(11);
      npartcounter->callback((Fl_Callback*)cb_npartcounter);
      npartcounter->align(Fl_Align(FL_ALIGN_LEFT));
      npartcounter->when(FL_WHEN_RELEASE_ALWAYS);
      o->range(1.0, partmax);
      o->value(synth->getRuntime().currentPart + 1);
      bankui->init(o);
    } // WidgetSpinner* npartcounter
    { WidgetSpinner* o = maxparts = new WidgetSpinner(93, 293, 40, 22, "of");
      maxparts->tooltip("Set the number of available parts");
      maxparts->box(FL_NO_BOX);
      maxparts->color(FL_BACKGROUND_COLOR);
      maxparts->selection_color(FL_BACKGROUND_COLOR);
      maxparts->labeltype(FL_NORMAL_LABEL);
      maxparts->labelfont(0);
      maxparts->labelsize(11);
      maxparts->labelcolor(FL_FOREGROUND_COLOR);
      maxparts->minimum(16);
      maxparts->maximum(64);
      maxparts->step(16);
      maxparts->value(16);
      maxparts->textsize(11);
      maxparts->callback((Fl_Callback*)cb_maxparts);
      maxparts->align(Fl_Align(FL_ALIGN_LEFT));
      maxparts->when(FL_WHEN_RELEASE);
      o->value(partmax);
    } // WidgetSpinner* maxparts
    { Fl_Choice* o = panning_law = new Fl_Choice(216, 376, 160, 20, "Pan Law");
      panning_law->tooltip("Relative values when panned to extremes:\n   Per side, Equivalent Mono");
      panning_law->down_box(FL_BORDER_BOX);
      panning_law->color((Fl_Color)41);
      panning_law->selection_color(FL_FOREGROUND_COLOR);
      panning_law->labelsize(12);
      panning_law->textfont(1);
      panning_law->textsize(12);
      panning_law->textcolor(FL_WHITE);
      panning_law->callback((Fl_Callback*)cb_panning_law);
      o->add("Cut: 0dB, -6dB");o->add("Default: +3dB, -3dB");o->add("Boost: +6dB, 0dB");
      o->value(fetchData(0, MAIN::control::panLawType, TOPLEVEL::section::main));
    } // Fl_Choice* panning_law
    { setInstance = new Fl_Group(82, 57, 193, 60);
      setInstance->box(FL_PLASTIC_UP_BOX);
      setInstance->color((Fl_Color)221);
      setInstance->hide();
      { Fl_Button* o = new Fl_Button(84, 59, 188, 57);
        o->box(FL_NO_BOX);
      } // Fl_Button* o
      { InstBlurb = new Fl_Text_Display(95, 89, 163, 6, "Accept next, or enter\nInstance from 1 to 31");
        InstBlurb->box(FL_NO_BOX);
        InstBlurb->labelsize(12);
      } // Fl_Text_Display* InstBlurb
      { Fl_Button* o = new Fl_Button(162, 91, 35, 22);
        o->box(FL_FLAT_BOX);
        o->down_box(FL_FLAT_BOX);
        o->labelfont(1);
        o->labelsize(11);
        o->callback((Fl_Callback*)cb_1);
      } // Fl_Button* o
      { cancelInst = new Fl_Button(209, 90, 56, 22, "Cancel");
        cancelInst->box(FL_PLASTIC_UP_BOX);
        cancelInst->labelfont(1);
        cancelInst->labelsize(11);
        cancelInst->callback((Fl_Callback*)cb_cancelInst);
      } // Fl_Button* cancelInst
      { nextInst = new Fl_Button(93, 90, 56, 22, "Next");
        nextInst->box(FL_PLASTIC_UP_BOX);
        nextInst->labelfont(1);
        nextInst->labelsize(11);
        nextInst->callback((Fl_Callback*)cb_nextInst);
      } // Fl_Button* nextInst
      { valueInst = new Fl_Input(162, 90, 37, 22);
        valueInst->textsize(11);
        valueInst->callback((Fl_Callback*)cb_valueInst);
      } // Fl_Input* valueInst
      setInstance->end();
    } // Fl_Group* setInstance
    { divider = new Fl_Box(18, 320, 350, 2);
      divider->box(FL_THIN_DOWN_FRAME);
    } // Fl_Box* divider
    mainDW = 385; mainDH = 470;
    masterwindow->size_range(394, 500, 0, 0, 0, 0, 1);
    masterwindow->end();
    masterwindow->resizable(masterwindow);
  } // Fl_Double_Window* masterwindow
// line spaces in boxes below are critical
  { Fl_Double_Window* o = aboutwindow = new Fl_Double_Window(365, 290, "About Yoshimi");
    aboutwindow->color(FL_LIGHT3);
    aboutwindow->labelfont(13);
    aboutwindow->labelsize(13);
    aboutwindow->user_data((void*)(this));
    aboutwindow->when(FL_WHEN_NEVER);
    { aboutFirst = new Fl_Group(0, 0, 365, 290);
      { about1 = new Fl_Box(10, 15, 345, 70, "Yoshimi\nmeets\nZynAddSubFX");
        about1->labelfont(9);
        about1->labelsize(18);
        about1->labelcolor(FL_BLUE);
        about1->align(Fl_Align(FL_ALIGN_CENTER|FL_ALIGN_INSIDE));
        about1->when(FL_WHEN_NEVER);
      } // Fl_Box* about1
      { about2 = new Fl_Box(25, 90, 315, 91, "Copyright 2002-2009, Nasca O. Paul and others\nCopyright 2009-2011, Alan Calv\
ert\nCopyright 2012-2013, Jeremy Jongepier and others\nCopyright 2014-2021, Wi\
ll Godfrey and others\nLV2 plugin Copyright 2014, Andrew Deryabin\nSplash Imag\
e Copyright 2017, Jesper Lloyd");
        about2->color((Fl_Color)51);
        about2->selection_color((Fl_Color)30);
        about2->labelfont(13);
        about2->labelsize(11);
      } // Fl_Box* about2
      { about3 = new Fl_Box(10, 190, 340, 53, "This is free software, and comes with ABSOLUTELY NO\nWARRANTY; you may redist\
ribute it and/or modify it\nunder the terms of GPL version 2, or (at your opti\
on)\nany later version.");
        about3->labelsize(11);
      } // Fl_Box* about3
      { Fl_Box* o = about4 = new Fl_Box(61, 254, 240, 20, " version");
        about4->labelfont(1);
        about4->labelsize(12);
        about4->labelcolor((Fl_Color)145);
        //
            o->copy_label((string("Yoshimi version ")
                           + string(YOSHIMI_VERSION)).c_str());
      } // Fl_Box* about4
      { about5 = new Fl_Button(15, 253, 43, 22, "more");
        about5->tooltip("Yoshimi\'s little band of helpers");
        about5->labelsize(11);
        about5->callback((Fl_Callback*)cb_about5);
      } // Fl_Button* about5
      aboutFirst->end();
    } // Fl_Group* aboutFirst
    { contributors = new Fl_Group(5, 5, 355, 280);
      contributors->box(FL_FLAT_BOX);
      contributors->color(FL_BACKGROUND2_COLOR);
      contributors->labelcolor(FL_BACKGROUND2_COLOR);
      contributors->hide();
      { cont1 = new Fl_Box(12, 8, 340, 57, "Some people who have helped Yoshimi\n in various ways since\nAlan Calvert sta\
rted the project");
        cont1->color(FL_BACKGROUND2_COLOR);
        cont1->labelfont(9);
        cont1->labelsize(15);
        cont1->labelcolor((Fl_Color)4);
      } // Fl_Box* cont1
      { cont2 = new Fl_Box(25, 70, 155, 200, "\n          Chris Ahlstrom\n          Kristian Amlie\n          Jonathan Bric\
kman\n          Jeanette Claassen\n          Rob Couto\n          Andrew Derya\
bin\n          J\303\266rn Eichler\n          Csaba Erdei\n          James Fra\
ser\n          Will Godfrey\n          Alexander Hirsch\n          Jeremy Jong\
epier\n          Iain King-Speir\n          Tobias Kortkamp\n          ");
        cont2->labelsize(12);
      } // Fl_Box* cont2
      { cont3 = new Fl_Box(194, 70, 155, 200, "\n          Tito Latini\n          Rainer Liffers\n          Jesper Lloyd\n  \
        Lars Luthman\n          Holger Marzen\n          Lieven Moors\n       \
   Harry Nakos\n          Iurie Nistor\n          Stephen Parry\n          Lor\
enzo Sutton\n          Hermann Vo\303\237""eler\n          Nikita Zlobin\n\n\n\
          ");
        cont3->labelsize(12);
      } // Fl_Box* cont3
      contributors->end();
    } // Fl_Group* contributors
    { aboutClose = new Fl_Button(305, 253, 43, 22, "Close");
      aboutClose->box(FL_THIN_UP_BOX);
      aboutClose->labelsize(11);
      aboutClose->callback((Fl_Callback*)cb_aboutClose);
    } // Fl_Button* aboutClose
    aboutDW = 365; aboutDH = 290;
    o->size_range(aboutDW,aboutDH, 0, 0, 0, 0, 1);
    aboutwindow->end();
    aboutwindow->resizable(aboutwindow);
  } // Fl_Double_Window* aboutwindow
  { Fl_Double_Window* o = syseffsendwindow = new Fl_Double_Window(120, 245, "Sys Send");
    syseffsendwindow->labelfont(13);
    syseffsendwindow->labelsize(13);
    syseffsendwindow->callback((Fl_Callback*)cb_syseffsendwindow, (void*)(this));
    { Fl_Group* o = syseffgroup = new Fl_Group(9, 46, 109, 172);
      syseffgroup->box(FL_FLAT_BOX);
      //
            for (int neff1 = 0; neff1 < NUM_SYS_EFX; neff1++)
                for (int neff2 = neff1 + 1; neff2 < NUM_SYS_EFX; neff2++)
      {
                syseffsend[neff1][neff2] =
                    new SysEffSend(o->x()+(neff2 - 1) * 35, o->y() + 20 + neff1 * 52, 30, 30);
                syseffsend[neff1][neff2]->label("aaa");
                syseffsend[neff1][neff2]->init(neff1, neff2, synth);
                syseffsend[neff1][neff2]->setValueType(VC_FXSysSend);
            }
      syseffgroup->end();
    } // Fl_Group* syseffgroup
    { syseffClose = new Fl_Button(20, 216, 80, 25, "Close");
      syseffClose->box(FL_THIN_UP_BOX);
      syseffClose->callback((Fl_Callback*)cb_syseffClose);
    } // Fl_Button* syseffClose
    { syseffname = new Fl_Box(5, 5, 110, 35, "Send output of system effect  to other system effects");
      syseffname->labelsize(10);
      syseffname->align(Fl_Align(192));
    } // Fl_Box* syseffname
    syseffDW = 120; syseffDH = 245;
    o->size_range(syseffDW, syseffDH, 0, 0, 0, 0, 1);
    syseffsendwindow->end();
    syseffsendwindow->resizable(syseffsendwindow);
  } // Fl_Double_Window* syseffsendwindow
  { Fl_Double_Window* o = panelwindow = new Fl_Double_Window(1040, 320, "Yoshimi Mixer Panel");
    panelwindow->labelfont(13);
    panelwindow->labelsize(13);
    panelwindow->callback((Fl_Callback*)cb_panelwindow, (void*)(this));
    { Panelframe = new Fl_Group(2, 2, 1036, 286);
      Panelframe->box(FL_ENGRAVED_FRAME);
      //
          for (int i = 0; i < 16; i++)
          {
              panellistitem[i] = new Panellistitem(0, 0, 64, 270, "");
              panellistitem[i]->init(i, bankui, synth);
          }
      Panelframe->end();
    } // Fl_Group* Panelframe
    { towide = new Fl_Button(360, 290, 130, 25, "Change to 1 x 16");
      towide->box(FL_THIN_UP_BOX);
      towide->callback((Fl_Callback*)cb_towide);
    } // Fl_Button* towide
    { todeep = new Fl_Button(831, 290, 120, 25, "Change to 2 x 8");
      todeep->box(FL_THIN_UP_BOX);
      todeep->callback((Fl_Callback*)cb_todeep);
    } // Fl_Button* todeep
    { Fl_Choice* o = Panelgroups = new Fl_Choice(5, 300, 86, 18, "Part Group");
      Panelgroups->down_box(FL_BORDER_BOX);
      Panelgroups->labelsize(12);
      Panelgroups->textsize(12);
      Panelgroups->callback((Fl_Callback*)cb_Panelgroups);
      Panelgroups->align(Fl_Align(FL_ALIGN_TOP));
      o->add("1 to 16");o->add("17 to 32");o->add("33 to 48");o->add("49 to 64");
      o->value(panelgroup / NUM_MIDI_CHANNELS);
    } // Fl_Choice* Panelgroups
    { Fl_Choice* o = Panelsmallgroups = new Fl_Choice(5, 300, 86, 18, "Part Group");
      Panelsmallgroups->down_box(FL_BORDER_BOX);
      Panelsmallgroups->labelsize(12);
      Panelsmallgroups->textsize(12);
      Panelsmallgroups->callback((Fl_Callback*)cb_Panelsmallgroups);
      Panelsmallgroups->align(Fl_Align(FL_ALIGN_TOP));
      o->add("1 to 16");o->add("17 to 32");
      if (panelgroup ==  NUM_MIDI_CHANNELS) o->value(1); else o->value(0);
    } // Fl_Choice* Panelsmallgroups
    { WidgetSpinner* o = CSspinner = new WidgetSpinner(209, 300, 50, 18, "CC");
      CSspinner->box(FL_NO_BOX);
      CSspinner->color(FL_BACKGROUND_COLOR);
      CSspinner->selection_color(FL_BACKGROUND_COLOR);
      CSspinner->labeltype(FL_NORMAL_LABEL);
      CSspinner->labelfont(0);
      CSspinner->labelsize(12);
      CSspinner->labelcolor(FL_FOREGROUND_COLOR);
      CSspinner->minimum(0);
      CSspinner->maximum(127);
      CSspinner->value(115);
      CSspinner->textsize(12);
      CSspinner->callback((Fl_Callback*)cb_CSspinner);
      CSspinner->align(Fl_Align(FL_ALIGN_TOP));
      CSspinner->when(FL_WHEN_RELEASE);
      CS_CC = synth->getRuntime().channelSwitchCC;
      if (CS_CC < 128) o->value(CS_CC); else o->value(115);
    } // WidgetSpinner* CSspinner
    { CSpend = new Fl_Button(276, 290, 70, 25, "Pending");
      CSpend->tooltip("Click to set");
      CSpend->box(FL_PLASTIC_UP_BOX);
      CSpend->color((Fl_Color)90);
      CSpend->labelsize(12);
      CSpend->callback((Fl_Callback*)cb_CSpend);
      CSpend->hide();
    } // Fl_Button* CSpend
    { Fl_Choice* o = channelswitch = new Fl_Choice(114, 300, 74, 18, "Solo");
      channelswitch->tooltip("Assign groups of parts to Ch 1, singly enabled by MIDI");
      channelswitch->down_box(FL_BORDER_BOX);
      channelswitch->labelsize(12);
      channelswitch->textsize(12);
      channelswitch->callback((Fl_Callback*)cb_channelswitch);
      channelswitch->align(Fl_Align(FL_ALIGN_TOP));
      o->add("Off");o->add("Row");o->add("Column");o->add("Loop");o->add("TwoWay");o->add("Channel");
      o->value(synth->getRuntime().channelSwitchType);
      if (o->value() == 0) CSspinner->hide(); else CSspinner->show();
      CS_CC = o->value();
    } // Fl_Choice* channelswitch
    { Panelclose = new Fl_Button(975, 290, 60, 25, "Close");
      Panelclose->box(FL_THIN_UP_BOX);
      Panelclose->labelfont(1);
      Panelclose->callback((Fl_Callback*)cb_Panelclose);
    } // Fl_Button* Panelclose
    o->copy_label(synth->makeUniqueName("Mixer Panel").c_str());
    panelwindow->end();
    panelwindow->resizable(panelwindow);
  } // Fl_Double_Window* panelwindow
  { Fl_Double_Window* o = message = new Fl_Double_Window(290, 85, "Yoshimi");
    message->labelsize(12);
    message->user_data((void*)(this));
    { words = new Fl_Box(5, 9, 280, 45, "?");
      words->color((Fl_Color)55);
      words->selection_color((Fl_Color)55);
      words->labelfont(1);
      words->labelsize(12);
      words->align(Fl_Align(133|FL_ALIGN_INSIDE));
    } // Fl_Box* words
    { yesdoit = new Fl_Button(49, 60, 70, 20, "Yes");
      yesdoit->callback((Fl_Callback*)cb_yesdoit);
      yesdoit->hide();
    } // Fl_Button* yesdoit
    { cancel = new Fl_Button(130, 60, 70, 20, "Cancel");
      cancel->callback((Fl_Callback*)cb_cancel);
      cancel->hide();
    } // Fl_Button* cancel
    { closebutton = new Fl_Button(211, 60, 70, 20, "Close");
      closebutton->callback((Fl_Callback*)cb_closebutton);
    } // Fl_Button* closebutton
    o->copy_label(synth->makeUniqueName("").c_str());
    msgDW = o->w(); msgDH = o->h();
    o->size_range(290, 85, 0, 0, 0, 0, 1);
    message->end();
    message->resizable(message);
  } // Fl_Double_Window* message
  { Fl_Double_Window* o = querywindow = new Fl_Double_Window(420, 105, "Yoshimi");
    querywindow->callback((Fl_Callback*)cb_querywindow, (void*)(this));
    { Fl_Button* o = yesQ = new Fl_Button(205, 80, 60, 20, "Yes");
      yesQ->callback((Fl_Callback*)cb_yesQ);
      o->value(0);
    } // Fl_Button* yesQ
    { Fl_Button* o = noQ = new Fl_Button(276, 80, 60, 20, "No");
      noQ->callback((Fl_Callback*)cb_noQ);
      o->value(0);
    } // Fl_Button* noQ
    { Fl_Button* o = cancelQ = new Fl_Button(348, 80, 66, 20, "Cancel");
      cancelQ->labelfont(1);
      cancelQ->callback((Fl_Callback*)cb_cancelQ);
      o->value(0);
    } // Fl_Button* cancelQ
    { typeQ = new Fl_Box(8, 26, 45, 45, "?");
      typeQ->box(FL_THIN_DOWN_BOX);
      typeQ->color(FL_BACKGROUND2_COLOR);
      typeQ->labelfont(9);
      typeQ->labelsize(40);
      typeQ->labelcolor((Fl_Color)217);
    } // Fl_Box* typeQ
    { textQ = new Fl_Box(65, 11, 345, 63, "text goes here");
      textQ->align(Fl_Align(FL_ALIGN_WRAP));
    } // Fl_Box* textQ
    queryDW = 420; queryDH = 105;
    o->size_range(queryDW, queryDH, 0, 0, 0, 0, 1);
    querywindow->set_modal();
    querywindow->end();
    querywindow->resizable(querywindow);
  } // Fl_Double_Window* querywindow
  { Fl_Double_Window* o = textwindow = new Fl_Double_Window(270, 60, "Yoshimi");
    textwindow->callback((Fl_Callback*)cb_textwindow, (void*)(this));
    { textLine = new Fl_Input(20, 23, 230, 25, "input:");
      textLine->align(Fl_Align(FL_ALIGN_TOP));
    } // Fl_Input* textLine
    textinDW = o->w(); textinDH = o->h();
    o->size_range(textinDW, textinDH, 0, 0, 0, 0, 1);
    textwindow->set_modal();
    textwindow->end();
    textwindow->resizable(textwindow);
  } // Fl_Double_Window* textwindow
  { Fl_Double_Window* o = filerwindow = new Fl_Double_Window(550, 350, "Yoshimi");
    filerwindow->callback((Fl_Callback*)cb_filerwindow, (void*)(this));
    { fileroldpath = new Fl_Input(10, 20, 448, 25, "file paths");
      fileroldpath->tooltip("Current path to use(editable)");
      fileroldpath->labelfont(1);
      fileroldpath->labelsize(12);
      fileroldpath->textfont(1);
      fileroldpath->textsize(12);
      fileroldpath->callback((Fl_Callback*)cb_fileroldpath);
      fileroldpath->align(Fl_Align(FL_ALIGN_TOP));
    } // Fl_Input* fileroldpath
    { filerback = new Fl_Button(463, 21, 78, 24, "Up");
      filerback->tooltip("Go up one directory in path");
      filerback->labelfont(1);
      filerback->labelsize(12);
      filerback->callback((Fl_Callback*)cb_filerback);
    } // Fl_Button* filerback
    { faveGroup = new Fl_Group(458, 116, 85, 60, "Favourites");
      faveGroup->box(FL_ENGRAVED_FRAME);
      faveGroup->end();
    } // Fl_Group* faveGroup
    { filerfave = new Fl_Button(463, 121, 75, 20, "Show List");
      filerfave->tooltip("Examine, re-order or delete entries");
      filerfave->labelfont(1);
      filerfave->labelsize(12);
      filerfave->callback((Fl_Callback*)cb_filerfave);
    } // Fl_Button* filerfave
    { faveadd = new Fl_Button(463, 151, 75, 20, "Add");
      faveadd->tooltip("Add the current path to the favourites list");
      faveadd->labelfont(1);
      faveadd->labelsize(12);
      faveadd->callback((Fl_Callback*)cb_faveadd);
    } // Fl_Button* faveadd
    { filerclose = new Fl_Button(463, 320, 78, 20, "Close");
      filerclose->labelfont(1);
      filerclose->labelsize(12);
      filerclose->callback((Fl_Callback*)cb_filerclose);
    } // Fl_Button* filerclose
    { filernamegroup = new Fl_Group(10, 50, 533, 26, "Name");
      filernamegroup->box(FL_ENGRAVED_FRAME);
      filernamegroup->labelfont(1);
      filernamegroup->labelsize(12);
      filernamegroup->align(Fl_Align(FL_ALIGN_BOTTOM));
      { filernewname = new Fl_Input(14, 53, 444, 20);
        filernewname->tooltip("Name of file item to load or save");
        filernewname->labelsize(12);
        filernewname->textfont(1);
        filernewname->textsize(12);
        filernewname->callback((Fl_Callback*)cb_filernewname);
        filernewname->align(Fl_Align(FL_ALIGN_BOTTOM));
      } // Fl_Input* filernewname
      filernamegroup->end();
    } // Fl_Group* filernamegroup
    { fileruse = new Fl_Button(464, 53, 74, 20, "< Use");
      fileruse->tooltip("Apply this name to the path and load/save");
      fileruse->labelfont(1);
      fileruse->labelsize(12);
      fileruse->callback((Fl_Callback*)cb_fileruse);
    } // Fl_Button* fileruse
    { filerOpt8 = new Fl_Check_Button2(490, 204, 18, 18, "Hide Dirs");
      filerOpt8->tooltip("Hide sub directories so that files are easier to see");
      filerOpt8->box(FL_NO_BOX);
      filerOpt8->down_box(FL_DOWN_BOX);
      filerOpt8->color(FL_BACKGROUND_COLOR);
      filerOpt8->selection_color(FL_FOREGROUND_COLOR);
      filerOpt8->labeltype(FL_NORMAL_LABEL);
      filerOpt8->labelfont(0);
      filerOpt8->labelsize(12);
      filerOpt8->labelcolor(FL_FOREGROUND_COLOR);
      filerOpt8->callback((Fl_Callback*)cb_filerOpt8);
      filerOpt8->align(Fl_Align(FL_ALIGN_TOP));
      filerOpt8->when(FL_WHEN_RELEASE);
    } // Fl_Check_Button2* filerOpt8
    { filerOpt1 = new Fl_Check_Button2(490, 244, 18, 18, ". (dot) Dirs");
      filerOpt1->tooltip("Show hidden paths");
      filerOpt1->box(FL_NO_BOX);
      filerOpt1->down_box(FL_DOWN_BOX);
      filerOpt1->color(FL_BACKGROUND_COLOR);
      filerOpt1->selection_color(FL_FOREGROUND_COLOR);
      filerOpt1->labeltype(FL_NORMAL_LABEL);
      filerOpt1->labelfont(0);
      filerOpt1->labelsize(12);
      filerOpt1->labelcolor(FL_FOREGROUND_COLOR);
      filerOpt1->callback((Fl_Callback*)cb_filerOpt1);
      filerOpt1->align(Fl_Align(FL_ALIGN_TOP));
      filerOpt1->when(FL_WHEN_RELEASE);
    } // Fl_Check_Button2* filerOpt1
    { filerOpt2 = new Fl_Check_Button2(490, 284, 18, 18, ". (dot) Files");
      filerOpt2->tooltip("Show hidden files");
      filerOpt2->box(FL_NO_BOX);
      filerOpt2->down_box(FL_DOWN_BOX);
      filerOpt2->color(FL_BACKGROUND_COLOR);
      filerOpt2->selection_color(FL_FOREGROUND_COLOR);
      filerOpt2->labeltype(FL_NORMAL_LABEL);
      filerOpt2->labelfont(0);
      filerOpt2->labelsize(12);
      filerOpt2->labelcolor(FL_FOREGROUND_COLOR);
      filerOpt2->callback((Fl_Callback*)cb_filerOpt2);
      filerOpt2->align(Fl_Align(FL_ALIGN_TOP));
      filerOpt2->when(FL_WHEN_RELEASE);
    } // Fl_Check_Button2* filerOpt2
    { filerOpt16 = new Fl_Check_Button2(490, 130, 18, 18, "Hide Files");
      filerOpt16->box(FL_NO_BOX);
      filerOpt16->down_box(FL_DOWN_BOX);
      filerOpt16->color(FL_BACKGROUND_COLOR);
      filerOpt16->selection_color(FL_FOREGROUND_COLOR);
      filerOpt16->labeltype(FL_NORMAL_LABEL);
      filerOpt16->labelfont(0);
      filerOpt16->labelsize(12);
      filerOpt16->labelcolor(FL_FOREGROUND_COLOR);
      filerOpt16->callback((Fl_Callback*)cb_filerOpt16);
      filerOpt16->align(Fl_Align(FL_ALIGN_TOP));
      filerOpt16->when(FL_WHEN_RELEASE);
      filerOpt16->hide();
    } // Fl_Check_Button2* filerOpt16
    { filerframe = new Fl_Group(4, 4, 542, 88);
      filerframe->box(FL_ENGRAVED_FRAME);
      filerframe->end();
    } // Fl_Group* filerframe
    { filershort = new Fl_Group(4, 4, 542, 74);
      filershort->box(FL_ENGRAVED_FRAME);
      filershort->end();
    } // Fl_Group* filershort
    { favourites = new Fl_Group(4, 49, 542, 299);
      favourites->box(FL_FLAT_BOX);
      favourites->hide();
      { favename = new Fl_Group(4, 49, 542, 42);
        favename->box(FL_ENGRAVED_FRAME);
        favename->end();
      } // Fl_Group* favename
      { favebrowse = new Fl_Browser(5, 91, 540, 251);
        favebrowse->type(1);
        favebrowse->box(FL_FLAT_BOX);
        favebrowse->color((Fl_Color)26);
        favebrowse->labelsize(12);
        favebrowse->textfont(1);
        favebrowse->textsize(12);
        favebrowse->callback((Fl_Callback*)cb_favebrowse);
      } // Fl_Browser* favebrowse
      { favecancel = new Fl_Button(455, 61, 70, 20, "Back");
        favecancel->tooltip("Cancel any selection and return to filer window");
        favecancel->labelfont(1);
        favecancel->labelsize(12);
        favecancel->callback((Fl_Callback*)cb_favecancel);
      } // Fl_Button* favecancel
      { favedefault = new Fl_Button(287, 61, 110, 20, "Make Default");
        favedefault->tooltip("Set selected entry as the default (move to top)");
        favedefault->labelfont(1);
        favedefault->labelsize(12);
        favedefault->callback((Fl_Callback*)cb_favedefault);
      } // Fl_Button* favedefault
      { favedelete = new Fl_Button(156, 61, 70, 20, "Delete");
        favedelete->tooltip("Remove selected entry");
        favedelete->labelfont(1);
        favedelete->labelsize(12);
        favedelete->callback((Fl_Callback*)cb_favedelete);
      } // Fl_Button* favedelete
      { faveset = new Fl_Button(20, 61, 70, 20, "Set");
        faveset->tooltip("Set the current path to the selected entry and exit");
        faveset->labelfont(1);
        faveset->labelsize(12);
        faveset->callback((Fl_Callback*)cb_faveset);
      } // Fl_Button* faveset
      favourites->end();
    } // Fl_Group* favourites
    { filerscroll = new Fl_Scroll(10, 96, 444, 244);
      filerscroll->type(2);
      filerscroll->color(FL_BACKGROUND2_COLOR);
      filerscroll->end();
    } // Fl_Scroll* filerscroll
    filerDW = o->w(); filerDH = o->h();
    o->size_range(filerDW, filerDH, 0, 0, 0, 0, 1);
    filerwindow->set_modal();
    filerwindow->end();
    filerwindow->resizable(filerwindow);
  } // Fl_Double_Window* filerwindow
  return filerwindow;
}

string MasterUI::setfiler(string title, string name, bool save, int exten) {
  //
      dosave = save;
      extension = exten;
      loadfavourites();
  
      string lastname = textMsgBuffer.fetch(fetchData(extension, MAIN::control::readLastSeen, TOPLEVEL::section::main));
      string path;
      type_name = "";
      size_t pos = string::npos;
      fileruseX = 464;
      fileruse->copy_label("< New Dir");
      filernamegroup->show();
      filerframe ->show();
      filershort->hide();
      string currentfave = string(favebrowse->text(1)).substr(4);
      if (extension == TOPLEVEL::XML::Dir)
      {
          if (!dosave)
          {
              fileruseX = 234;
              fileruse->copy_label("^ From");
              filernamegroup->hide();
              filerframe ->hide();
              filershort->show();
          }
          path = currentfave;
          filernewname->value("");
          filerOpt16->value(1);
          filerOpt8->hide();
          filerOpt2->hide();
      }
      else if(extension == TOPLEVEL::XML::Bank)
      {
          if(!dosave)
          {
              fileruseX = 234;
              fileruse->copy_label("^ Import");
              path = currentfave + name;
              filernewname->value("");
              filernamegroup->hide();
              filerframe ->hide();
              filershort->show();
          }
          else
          {
              fileruse->copy_label("< Export");
              path = currentfave;
              filernewname->value(name.c_str());
          }
          filerOpt16->value(1); // hide files
          filerOpt8->hide(); // hide dirs
          filerOpt2->hide(); // dot files
      }
      else
      {
          if (extension == TOPLEVEL::XML::ScalaTune || extension == TOPLEVEL::XML::ScalaMap)
              fileruse->copy_label("< Import");
  
          else if (dosave)
              fileruse->copy_label("< Save");
          else
              fileruse->copy_label("< Load");
          if (lastname.empty())
          {
              path = currentfave;
              filernewname->value("");
          }
          else
          {
              pos = lastname.rfind('/');
              path = lastname.substr(0, pos);
          }
  
          if (name.empty() && pos != string::npos)
          {
              name = lastname.substr(pos + 1);
          }
          filerOpt16->value(0);
          filerOpt8->show();
          filerOpt2->show();
  
          if (!name.empty())
          {
              pos = name.find('.');
              if (pos != string::npos)
                  name = name.substr(0, pos);
              filernewname->value(name.c_str());
          }
  
          switch(extension)
          {
              case TOPLEVEL::XML::Instrument:
                  filerext = EXTEN::zynInst;
                  fileroldpath->copy_label("Path to Instruments");
                  type_name = "xiz";
                  break;
              case TOPLEVEL::XML::Patch:
                  filerext = EXTEN::patchset;
                  fileroldpath->copy_label("Path to Patch Sets");
                  type_name = "xmz";
                  break;
              case TOPLEVEL::XML::Presets:
                  filerext = EXTEN::presets;
                  fileroldpath->copy_label("Path to Presets");
                  type_name = "xpz";
                  break;
  
              case TOPLEVEL::XML::Scale:
                  filerext = EXTEN::scale;
                  fileroldpath->copy_label("Path to Scales");
                  type_name = "xsz";
                  break;
              case TOPLEVEL::XML::State:
                  filerext = EXTEN::state;
                  fileroldpath->copy_label("Path to States");
                  type_name = "state";
                  break;
              case TOPLEVEL::XML::Vector:
                  filerext = EXTEN::vector;
                  fileroldpath->copy_label("Path to Vectors");
                  type_name = "xvy";
                  break;
              case TOPLEVEL::XML::MLearn:
                  filerext = EXTEN::mlearn;
                  fileroldpath->copy_label("Path to Midi-Learn files");
                  type_name = "xly";
                  break;
              case TOPLEVEL::XML::PadSample:
                  filerext = EXTEN::MSwave;
                  fileroldpath->copy_label("Path to PadSynth samples");
                  type_name = "wav";
                  break;
              case TOPLEVEL::XML::ScalaTune:
                  filerext = EXTEN::scalaTuning;
                  fileroldpath->copy_label("Path to Scala tunings");
                  type_name = "scl";
                  break;
              case TOPLEVEL::XML::ScalaMap:
                  filerext = EXTEN::scalaKeymap;
                  fileroldpath->copy_label("Path to Scala keymaps");
                  type_name = "kbm";
                  break;
              case TOPLEVEL::XML::Bank:
                  fileroldpath->copy_label("Path to Instrument Banks");
                  break;
          }
      }
      if (!title.empty())
          fileroldpath->copy_label(title.c_str());
      if (path.back() != '/')
          path += '/';
      filerpath = path;
      fileroldpath->value(path.c_str());
  
      fillfiler(type_name);
  
      int X, Y, W, H, O;
      loadWin(synth, W, H, X, Y, O, "Master-filer");
      if (W < filerDW || H < filerDH)
      {
          W = filerDW;
          H = filerDH;
      }
      checkSane(X, Y, W, H, filerDW, filerDH);
      filerwindow->resize(X, Y, W, H);
  
      lastfilerW = 0;
      filerdone = false;
      filerwindow->show();
      lineitem = -1;
      while (true)
      {
          if (lastfilerW != filerwindow->w())
          {
              filerRtext();
              lastfilerW = filerwindow->w();
          }
          Fl::wait();
          if (lineitem > -1)
          {
              filerselect(lineitem);
              lineitem = -1;
          }
          if (filerdone && (extension == TOPLEVEL::XML::Dir || extension == TOPLEVEL::XML::Bank))
          {
              if (dosave && string(filernewname->value()).empty())
              {
                  filerdone = false;
                  query("", "", "", "Nothing given to use!");
              }
              else
                  break;
          }
          else if (filerdone && string(filernewname->value()).empty())
          {
              filerdone = false;
              query("", "", "", "Nothing given to use!");
          }
          else if (filerdone)
          break;
      }
      filerwindow->hide();
  
      if (extension == TOPLEVEL::XML::Dir || extension == TOPLEVEL::XML::Bank)
      {
          if (dosave)
          {
              if (string(filernewname->value()).length() < 3)
                  filerfound.clear();
          }
          else
          {
              if (filerfound.back() != '/')
                  filerfound += '/';
          }
      }
      else if (dosave)
      {
          if (extension == TOPLEVEL::XML::Instrument)
          { // try to cover all possibilites!
              int type = fetchData(0, CONFIG::control::savedInstrumentFormat,TOPLEVEL::section::config);
              if ((type == 3 || type == 1) && isRegularFile(filerfound + EXTEN::zynInst))
              {
                  if (query("", "Yes", "No", "The file exists. \nOverwrite it?") < 2)
                      filerfound.clear();
              }
              else if ((type == 3 || type == 2) && isRegularFile(filerfound + EXTEN::yoshInst))
              {
                  if (query("", "Yes", "No", "The file exists. \nOverwrite it?") < 2)
                      filerfound.clear();
              }
          }
          else if (isRegularFile(filerfound + filerext))
          {
              if (query("", "Yes", "No", "The file exists. \nOverwrite it?") < 2)
              {
                  filerfound.clear();
              }
          }
      }
      savefavourites();
      return filerfound;
}

void MasterUI::fillfiler(string type_name) {
  //
          string tofetch;
          int options = filerOpt1->value();
          if (filerOpt2->value() > 0)
              options |= 2;
          if (filerOpt8->value() > 0)
              options |= 8;
          if (filerOpt16->value() > 0)
              options |= 16;
  
          file::dir2string(tofetch, filerpath, filerext, options);
          filerlist.clear();        // Note: must come first; dtor of FL_Group automatically
          filerscroll->clear();     //       detaches child widgets from the FL_Scroll
          lineno = 0;
          //std::cout << "*** list start ***" << std::endl;
          while(!tofetch.empty())
          {
              size_t pos = tofetch.find("\n");
              string next = tofetch.substr(0, pos);
              bool isDir = false;
              filerlist.emplace_back(0, 0, 390, 20);
              if (next.find("Dir:") != std::string::npos)
              {
                  next = next.substr(5);
                  isDir = true;
              }
              filerlist.back().init(synth,lineno, isDir, type_name, next);
              //std::cout << "name >" << next << "<" << std::endl;
              filerlist.back().name->copy_label(next.c_str());
              filerscroll->add(&filerlist.back());
              ++lineno;
              tofetch = tofetch.substr(pos + 1);
          }
          filerscroll->end();
          filerscroll->scroll_to(-10,-10);
          filerRtext();
          //std::cout << "list end " << lineno << std::endl;
}

void MasterUI::filerselect(int item) {
  //
          string line = string(filerlist[item].name->label());
          if (filerlist[item].dirIcon->visible())
          {
              //std::cout << "in dir" << std::endl;
              if (line.back() !='/')
                  line += '/';
              if (Fl::event_clicks())
              {
                  Fl::event_clicks(0);
                  filerpath = filerpath + line;
                  fileroldpath->value(filerpath.c_str());
                  fillfiler(type_name);
              }
              return;
          }
          //std::cout << "files" << std::endl;
          filernewname->value(line.c_str());
          if (Fl::event_clicks())
          {
              Fl::event_clicks(0);
              fileruse->do_callback();
          }
}

void MasterUI::setfavourites() {
  //
      fileroldpath->deactivate();
      filernewname->deactivate();
      fileruse->deactivate();
      filerback->deactivate();
      filerfave->deactivate();
      filerclose->deactivate();
      filerscroll->hide();
      favourites->show();
}

void MasterUI::loadfavourites() {
  //
          string favetext = file::loadText(file::configDir() + "/yoshimi-favourites");
          if (favetext.empty())
              favetext = file::userHome();
          favebrowse->clear();
          string cr = "\n";
          for (int count = 0; count < 20; ++count)
          {
              size_t pos = favetext.find(cr);
              string next = favetext.substr(0, pos);
              favebrowse->add(next.c_str());
              favetext = favetext.substr(pos + 1);
              if (pos == string::npos)
                  break;
          }
          setfavecolour(1);
}

void MasterUI::savefavourites() {
  //
      clearfavelist();
      string favetext;
      string cr = "\n";
      for (int i = 1; i <= favebrowse->size(); ++ i)
      {
          string line = string(favebrowse->text(i));
          favetext += (line + cr);
      }
      file::saveText(favetext, file::configDir() + "/yoshimi-favourites");
}

void MasterUI::clearfavelist() {
  //
      for (int i = 1; i <= favebrowse->size(); ++ i)
      {
          string line = string(favebrowse->text(i));
          if (line.substr(0, 4) == "@C4 ")
          {
              line = line.substr(4);
              favebrowse->text(i, line.c_str());
          }
      }
}

void MasterUI::setfavecolour(int num) {
  //
      string line = "@C4 " + string(favebrowse->text(num));
      favebrowse->text(num, line.c_str());
}

string MasterUI::clearfavecolour(int num) {
  //
  
          string line = string(favebrowse->text(num));
          if (line.substr(0, 4) == "@C4 ")
              line = line.substr(4);
          return line;
}

void MasterUI::filerRtext() {
  //
          float dScale = filerwindow->w() / float(filerDW);
          int size12 = int(12 * dScale);
          int size14 = int(14 * dScale);
  
          fileroldpath->labelsize(size12);
              fileroldpath->textsize(size12);
          filernamegroup->labelsize(size12);
              filernewname->textsize(size12);
          faveGroup->labelsize(size14);
          fileruse->position(fileruseX * dScale, 53 * dScale);
          fileruse->labelsize(size12);
  
          filerback->labelsize(size12);
          faveadd->labelsize(size12);
          filerfave->labelsize(size12);
  
          filerOpt8->labelsize(size12);
          filerOpt1->labelsize(size12);
          filerOpt2->labelsize(size12);
  
          filerclose->labelsize(size12);
  
          favename->labelsize(size14);
          favebrowse->textsize(size12);
          favecancel->labelsize(size12);
          favedefault->labelsize(size12);
          favedelete->labelsize(size12);
          faveset->labelsize(size12);
          for (int i = 0; i < lineno; ++i)
          {
              filerlist[i].resize(int(10 * dScale), int(((i * 20) + 96) * dScale), int(440 * dScale), int(20 * dScale));
              filerlist[i].name->labelsize(size12);
              filerlist[i].type->labelsize(int(4 * dScale));
          }
          filerwindow->redraw();
}

void MasterUI::startInstance() {
  //
      cancelInst->value(0);
      nextInst->value(0);
      valueInst->value("");
      setInstance->show();
      while (setInstance->visible())
      {
          if (cancelInst->value())
          {
              setInstance->hide();
              break;
          }
          if (nextInst->value())
          {
              send_data(TOPLEVEL::action::lowPrio, MAIN::control::startInstance, 0, TOPLEVEL::type::Integer, TOPLEVEL::section::main);
              setInstance->hide();
              break;
          }
          if (Fl::get_key(FL_Enter))
          {
              string testval = valueInst->value();
              if (!testval.empty())
              {
                  if (func::isDigits(testval))
                  {
                      int result = stoi(testval);
                      if (result > 0 && result < 32)
                      {
                          send_data(TOPLEVEL::action::lowPrio, MAIN::control::startInstance, result, TOPLEVEL::type::Integer, TOPLEVEL::section::main);
                          setInstance->hide();
                          break;
                      }
                  }
              }
          }
          Fl::wait();
      };
}

void MasterUI::send_data(int action, int control, float value, int type, int part , int engine , int insert , int parameter , int miscmsg ) {
  //
          type |= TOPLEVEL::type::Write;
          /*
              The following variations are due to the way the section was built
              up over time. It really needs the whole lot expanding for the calls
              to natively include all parameters.
          */
          if (control == MAIN::control::loadInstrumentByName && part == TOPLEVEL::section::main && miscmsg < NO_MSG)
          {
              collect_data(synth, 0, action, type, control, part, engine, UNUSED, UNUSED, UNUSED, UNUSED, miscmsg);
              return;
          }
  
          if (control <= MAIN::control::soloType)
              type |= Fl::event_button();
          if (parameter == 0)
          {
              collect_data(synth, 0, action, type, control, part, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, miscmsg);
              return;
          }
  
          collect_data(synth, value, action, type, control, part, UNUSED, engine, insert, parameter, UNUSED, miscmsg);
}

float MasterUI::fetchData(float value, int control, int part, int kititem , int engine , int insert , int parameter , int offset , int miscmsg , int request ) {
  //
          return collect_readData(synth, value, control, part, kititem, engine, insert, parameter, offset, miscmsg, request);
}

bool MasterUI::part_group_returns(CommandBlock *getData) {
  //
          float value = getData->data.value;
          unsigned char control = getData->data.control;
          unsigned char newpart = getData->data.part;
          int value_int = lrint(value);
          bool value_bool = _SYS_::F2B(value);
          int panelpart = 0;
          bool panelVisible = ((newpart / NUM_MIDI_CHANNELS) == (panelgroup / NUM_MIDI_CHANNELS));
          if (panelVisible)
              panelpart = newpart % NUM_MIDI_CHANNELS;
  
          bool seen = false;
          switch (control)
          {
              case PART::control::enable:
              {
                  if (npart == newpart)
                  {
                      partEnable->value(value);
                      if (value)
                          partControls->activate();
                      else
                          partControls->deactivate();
                  }
                  if (panelVisible)
                  {
                      panellistitem[panelpart]->partenabled->value(value);
                      if (value)
                          panellistitem[panelpart]->panellistitemgroup->activate();
                      else
                          panellistitem[panelpart]->panellistitemgroup->deactivate();
                  }
                  seen = true;
                  break;
              }
              case PART::control::volume:
                  partVol->value(value);
                  if (panelVisible)
                      panellistitem[panelpart]->partvolume->value(value);
                  seen = true;
                  break;
              case PART::control::panning:
                  partPan->value(value);
                  if (panelVisible)
                      panellistitem[panelpart]->partpanning->value(value);
                  seen = true;
                  break;
              case PART::control::velocityOffset:
                  partVelOffset->value(value);
                  seen = true;
                  break;
  
              case PART::control::velocitySense:
                  partVelSense->value(value);
                  seen = true;
                  break;
  
              case PART::control::midiChannel:
              {
                  int tmp = value_int;
                  int textCol = FL_BLACK;
                  if (tmp >= NUM_MIDI_CHANNELS)
                  {
                      if (tmp >= NUM_MIDI_CHANNELS * 2)
                          textCol = FL_RED;
                      else
                          textCol = FL_DARK_CYAN;
                      tmp = (tmp % NUM_MIDI_CHANNELS);
                  }
                  partMidiCh->textcolor(textCol);
                  partMidiCh->value(tmp + 1);
                  if (panelVisible)
                  {
                      panellistitem[panelpart]->partrcv->textcolor(textCol);
                      panellistitem[panelpart]->partrcv->value(tmp);
                  }
                  seen = true;
                  break;
              }
  
              case PART::control::keyMode:
                  partKeymode->value(value_int);
                  if(value_int > 1 && partui->part->Pdrummode != 0)
                      modepatch->color(91);
                  else
                      modepatch->color(29);
                  modepatch->redraw();
                  seen = true;
                  break;
  
              case PART::control::drumMode: // we allow this to cayry on to PartUI
                  if(value_bool != 0 && partKeymode->value() > 1)
                      modepatch->color(91);
                  else
                      modepatch->color(29);
                  modepatch->redraw();
                  break;
  
              case PART::control::portamento:
                  partPortamento->value(value_bool);
                  break;
  
              case PART::control::instrumentName:
                  partui->checkEngines();
                  synth->getGuiMaster()->instrumentlabel->copy_label(synth->part[newpart]->Pname.c_str());
                  seen = true;
                  break;
  
              case PART::control::minNote:
              case PART::control::minToLastKey: // this will have been modified for last key press
                  minKeyCount->value(value_int);
                  seen = true;
                  break;
  
              case PART::control::maxNote:
              case PART::control::maxToLastKey: // this will have been modified for last key press
                  maxKeyCount->value(value_int);
                  seen = true;
                  break;
  
              case PART::control::resetMinMaxKey:
                  minKeyCount->value(0);
                  maxKeyCount->value(127);
                  seen = true;
                  break;
  
              case PART::control::keyShift:
                  partKeyShift->value(value_int);
                  seen = true;
                  break;
  
              case PART::control::maxNotes:
                  partKeyLimit->value(value_int);
                  seen = true;
                  break;
  
              case PART::partToSystemEffect1:
                  sysEff1->value(value);
                  seen = true;
                  break;
              case PART::partToSystemEffect2:
                  sysEff2->value(value);
                  seen = true;
                  break;
              case PART::partToSystemEffect3:
                  sysEff3->value(value);
                  seen = true;
                  break;
              case PART::partToSystemEffect4:
                  sysEff4->value(value);
                  seen = true;
                  break;
  
              case PART::control::audioDestination:
                  int send = value_int - 1;
                  if (send < 0 or send > 2)
                      send = 0;
                  if (panelVisible)
                      panellistitem[panelpart]->audiosend->value(send);
                  seen = true;
                  break;
          }
          return seen;
}

bool MasterUI::returns_update(CommandBlock *getData) {
  //
      float value = getData->data.value;
      bool wasFromHere = ((getData->data.source & TOPLEVEL::action::noAction) == TOPLEVEL::action::fromGUI);
      bool force = getData->data.source & TOPLEVEL::action::forceUpdate;
      unsigned char control = getData->data.control;
      unsigned char newpart = getData->data.part;
      unsigned char kititem = getData->data.kit;
      unsigned char engine = getData->data.engine;
      unsigned char insert = getData->data.insert;
      unsigned char parameter = getData->data.parameter;
      unsigned char miscmsg = getData->data.miscmsg;
      int value_int = lrint(value);
      bool value_bool = _SYS_::F2B(value);
      int chan = kititem & 0x3f;
      bool isSingle = kititem >= 0x40;
      int mask = NUM_MIDI_CHANNELS - 1;
      string name;
      if (miscmsg != NO_MSG)
          name = textMsgBuffer.fetch(miscmsg);
      if (newpart == TOPLEVEL::section::midiIn)
      {
          if (engine == MIDI::CC::volume && partui->part->ctl->volume.receive == 0)
              return false; // disabled
          if (engine == MIDI::CC::expression && partui->part->ctl->expression.receive == 0)
              return false; // disabled
  
          float vol = (value * synth->part[npart]->ctl->volume.data) / 127;
          if (control == MIDI::control::controller)
          { // panel entries only
              for (int i = 0; i < NUM_MIDI_CHANNELS; ++i)
              {
                  if (panellistitem[i]->partenabled->value() != 0)
                  {
                      if ((isSingle && i == (chan & mask)
                                   && panellistitem[i]->partrcv->value() == (chan & mask)
                                   && (chan / NUM_MIDI_CHANNELS) == (panelgroup / NUM_MIDI_CHANNELS))
                           || (!isSingle && panellistitem[i]->partrcv->value() == (chan & mask)))
                      {
                          if (engine == MIDI::CC::volume)
                              panellistitem[i]->partvolume->value(vol);
                          else if (engine == MIDI::CC::panning)
                              panellistitem[i]->partpanning->value(value);
                      }
                  }
              }
          }
  
          bool isForUs = (isSingle && chan == npart)
               || (!isSingle &&  (partMidiCh->value() == (chan & mask) + 1));
          switch(control)
          {
              case MIDI::control::noteOn:
              case MIDI::control::noteOff:
                  break;
              case MIDI::control::controller:
                  //cout << " Value " << value_int << "  kit " << int(kititem) << "  npart " << int(npart) << endl;
                  if (engine <= 119 && engine == synth->getRuntime().channelSwitchCC)
                  { // it's a valid channel switch
                      int newch = partMidiCh->value() - 1;
                      switch (synth->getRuntime().channelSwitchType)
                      {
                          case MIDI::SoloType::Row:
                              if (npart < NUM_MIDI_CHANNELS)
                              {
                                  if (npart != value_int)
                                      newch = NUM_MIDI_CHANNELS;
                                  else
                                      newch = 0;
                              }
                              break;
  
                          case MIDI::SoloType::Column:
                              if (value_int == npart)
                                  newch = (value_int & mask);
                              else if ((value_int & mask) == (npart & mask))
                                  newch = (value_int & mask) + NUM_MIDI_CHANNELS;
                              break;
  
                          case MIDI::SoloType::Loop:
                          case MIDI::SoloType::TwoWay:
                              if (npart < NUM_MIDI_CHANNELS)
                              {
                                  if (npart == synth->getRuntime().channelSwitchValue)
                                      newch = 0;
                                  else if (value_int > 0)
                                      newch = NUM_MIDI_CHANNELS;
                              }
                              break;
  
                          case MIDI::SoloType::Channel:
                              //int ch = value_int % NUM_MIDI_CHANNELS;
                              if (newch == chan || newch == chan + NUM_MIDI_CHANNELS)
                                  newch = chan;
                              else
                                  newch = newch + NUM_MIDI_CHANNELS;
                              break;
  
                      }
                      partMidiCh->value(newch + 1);
  
                      if (newch < NUM_MIDI_CHANNELS)
                          partMidiCh->textcolor(FL_BLACK);
                      else
                          partMidiCh->textcolor(FL_WHITE);
                      updatepanel();
                  }
                  else if (isForUs)
                  {
                      switch(engine)
                      {
                          case MIDI::CC::modulation:
                              partui->modulation->value(value);
                              break;
                          case MIDI::CC::volume:
                              partVol->value(vol);
                              break;
                          case MIDI::CC::panning:
                              partPan->value(value);
                              break;
                          case MIDI::CC::expression:
                              partui->expression->value(value);
                              break;
                          case MIDI::CC::legato:
                          {
                              int mode = synth->ReadPartKeyMode(npart);
                              modepatch->color(29);
                              if (mode > 1)
                              {
                                  partKeymode->value(2);
                                  if (partui->drumMode->value() != 0)
                                      modepatch->color(91);
                              }
                              else
                                  partKeymode->value(mode);
                              modepatch->redraw();
                              break;
                          }
                          case MIDI::CC::filterQ:
                              partui->filterq->value(value);
                              break;
                          case MIDI::CC::filterCutoff:
                              partui->filtercutoff->value(value);
                              break;
                          case MIDI::CC::bandwidth:
                              partui->masterbandwidth->value(value);
                              break;
                      }
                  }
                  break;
              case MIDI::control::bankChange:
                  if (engine != UNUSED)
                      bankui->readbankcfg();
                  bankui->rescan_for_banks();
                  break;
          }
          return false;
      }
      if (newpart == TOPLEVEL::section::systemEffects)
      {
          if (insert == TOPLEVEL::insert::systemEffectSend)
          {
              if (!wasFromHere || force == true)
                  syseffsend[engine][control]->value(value);
          }
          else
          {
              if (control == EFFECT::sysIns::effectNumber)
              {
                  syseffnocounter->value(engine + 1);
                  nsyseff = engine;
                  sysefftype->value(synth->sysefx[nsyseff]->geteffect());
                  syseffectui->refresh(synth->sysefx[nsyseff], TOPLEVEL::section::systemEffects, nsyseff);
                  syseffectui->UpdatePresetColour(parameter, sysefftype->value());
                  SysEffOn->value(fetchData(0, EFFECT::sysIns::effectEnable, TOPLEVEL::section::systemEffects, UNUSED, 0));
                  if (SysEffOn->value())
                      sysefftype->activate();
                  else
                      sysefftype->deactivate();
              }
              else if (control == EFFECT::sysIns::effectType)
              {
                  syseffnocounter->value(engine + 1);
                  nsyseff = engine;
                  sysefftype->value(value_int);
                  syseffectui->refresh(synth->sysefx[nsyseff], TOPLEVEL::section::systemEffects, nsyseff);
                  syseffectui->UpdatePresetColour(parameter, sysefftype->value());
                  if (sysinsgroup->value() == SystemEffectsGrp)
                  {
                      showSysEfxUI();
                      syseffectui->effRtext(mainScale, sysefftype->value());
                  }
              }
              else if (control == EFFECT::sysIns::effectEnable)
              {
                 SysEffOn->value(value_bool);
                 if (value_bool)
                      sysefftype->activate();
                  else
                      sysefftype->deactivate();
              }
          }
          return false;
      }
      else if (newpart == TOPLEVEL::section::insertEffects)
      {
          if (control == EFFECT::sysIns::effectNumber)
          {
              ninseff = engine;
              setInsEff(ninseff);
              if (sysinsgroup->value() == InsertionEffectsGrp)
                  showInsEfxUI();
              inseffectui->UpdatePresetColour(parameter, insefftype->value());
  
          }
          else if (control == EFFECT::sysIns::effectType)
          {
              inseffnocounter->value(engine + 1);
              ninseff = engine;
              insefftype->value(value_int);
              setInsEff(ninseff);
              inseffectui->UpdatePresetColour(parameter, insefftype->value());
              if (sysinsgroup->value() == InsertionEffectsGrp)
              {
                  showInsEfxUI();
                  inseffectui->effRtext(mainScale, insefftype->value());
              }
          }
          else if (control == EFFECT::sysIns::effectDestination)
          {
              inseffpart->value(value_int + 2);
              if (value_int == -1)
                  insefftype->deactivate();
              else
              {
                  insefftype->activate();
                  setInsEff(ninseff);
                  if (sysinsgroup->value() == InsertionEffectsGrp)
                      showInsEfxUI();
              }
          }
          return false;
      }
  
      switch(control)
      {
          case MAIN::control::volume:
              mastervolumedial->value(value);
              break;
  
          case MAIN::control::partNumber:
              if ((getData->data.source & TOPLEVEL::action::noAction) != TOPLEVEL::action::fromGUI)
                  activePart = value_int;
  
              partSwitch(activePart);
              updatepanel();
              break;
  
          case MAIN::control::availableParts:
              partmax = value_int;
              npartcounter->range(1, partmax);
              updatepart();
              updatepanel();
              setinspartlist();
              vectorui->checkParts(value_int);
              break;
          case MAIN::control::panLawType:
              panning_law->value(value_int);
              break;
  
          case MAIN::control::detune:
              globalfinedetune->value(value);
              break;
  
          case MAIN::control::keyShift:
              masterkeyshift->value(value_int);
              break;
  
          case MAIN::control::bpmFallback:
              setBpmFallbackValue(value);
              break;
  
          case MAIN::control::mono:
              mastermono->value(value_int);
              if (value_int)
                  mastermono->label("Mono");
              else
                  mastermono->label("Stereo");
              break;
  
          case MAIN::control::soloType:
              channelswitch->value(value_int);
              if (value_int == 0)
              {
                  CS_CC = 128;
                  CSspinner->value(115); // default
                  CSspinner->hide();
                  CSpend->hide();
                  for (int i = 0; i < NUM_MIDI_CHANNELS; ++i)
                      setPanelPartMidiWidget(i, i);
              }
              else
              {
                  CS_CC = 115;
                  CSspinner->value(115);
                  CSpend->show();
                  CSspinner->show();
                  for (int i = 1; i < NUM_MIDI_CHANNELS; ++i)
                  {
                      if (value_int == 2)
                          setPanelPartMidiWidget(i, i);
                      else
                          setPanelPartMidiWidget(i, 16);
                  }
              }
              panelwindow->changed();
              break;
          case MAIN::control::soloCC:
              updatepanel();
              break;
          case MAIN::control::exportBank:
              if (wasFromHere)
                  query("", "", "", name);
              break;
          case MAIN::control::importBank: // import bank
              if (wasFromHere)
              {
                  if (name.find("FAILED") == 1)
                      query("", "", "", name);
                  else
                  {
                      unsigned int other = name.find(" : ");
                      if (other < 1024) // a bit of a hack :(
                      {
                          name = name.substr(other + 3);
                          query("", "", "", name);
                      }
                  }
              }
              bankui->rescan_for_banks();
              break;
          case MAIN::control::deleteBank: // delete bank and contents
              if (name.find("FAILED") == 1)
              {
                  if (wasFromHere)
                      query("", "", "", name);
              }
              bankui->rescan_for_banks();
              bankui->set_bank_slot();
              break;
  
          case MAIN::control::loadInstrumentFromBank:
              bankui->refreshinstrumentwindow();
              updatepartprogram(kititem);
              break;
  
          case MAIN::control::loadInstrumentByName:
              updatepartprogram(kititem);
              break;
  
          case MAIN::control::saveNamedInstrument: // save instrument
              if (name.find("FAILED") == 1)
              {
                  if (wasFromHere)
                      query("", "", "", name);
              }
              else
              {
                  partui->setinstrumentlabel();
                  panellistitem[newpart % NUM_MIDI_CHANNELS]->refresh();
                  //RecentInstruments->activate();
              }
              break;
  
          case MAIN::control::loadNamedPatchset: // load patchset
              if (name.find("FAILED") == 1)
              {
                  if (wasFromHere)
                      query("", "", "", name);
              }
              else
              {
                  vectorui->RefreshChans();
                  //RecentParams->activate();
                  setMasterLabel(findLeafName(name));
                  refresh_master_ui(2);
              }
  
              break;
  
          case MAIN::control::saveNamedPatchset: // save patch set
              if (name.find("FAILED") == 1)
              {
                  if (wasFromHere)
                      query("", "", "", name);
              }
              else
              {
                  setMasterLabel(findLeafName(name));
                  //RecentParams->activate();
              }
              break;
  
          case MAIN::control::loadNamedVector: // load vector
              if (name.find("FAILED") == 1)
              {
                  if (wasFromHere)
                      query("", "", "", name);
              }
              else
              {
                  vectorui->setLoadLabelRemote(insert, synth->getRuntime().vectordata.Name[insert]);
                  setMasterLabel(findLeafName(name) + " - Vector " + to_string(int(insert) + 1));
                  vectorui->setRecent(true);
                  refresh_master_ui(5);
              }
              break;
  
          case MAIN::control::saveNamedVector: // save vector
              if (name.find("FAILED") == 1)
              {
                  if (wasFromHere)
                      query("", "", "", name);
              }
              else
              {
                  setMasterLabel(findLeafName(name) + " - Vector " + to_string(int(insert) + 1));
                  vectorui->setRecent(true);
              }
              break;
  
          case MAIN::control::loadNamedScale: // load scales
              if (name.find("FAILED") == 1)
              {
                  if (wasFromHere)
                      query("", "", "", name);
              }
              else
              {
                  //RecentScale->activate();
                  microtonalui->microtonaluiwindow->hide();
                  microtonalui->make_window();
                  microtonalui->showScales();
              }
              break;
  
          case MAIN::control::saveNamedScale: // save scales
              if (wasFromHere && name.find("FAILED") == 1)
                  query("", "", "", name);
              //else
                  //RecentScale->activate();
              break;
  
          case MAIN::control::loadNamedState: // load state
              if (wasFromHere && name.find("FAILED") == 1)
              {
                  query("", "", "", name);
                  refresh_master_ui(1);
              }
              else
              {
                  setMasterLabel(findLeafName(name) + " - State");
                  refresh_master_ui(0x14);
              }
              break;
  
          case MAIN::control::saveNamedState: // save state
              if (wasFromHere && name.find("FAILED") == 1)
                  query("", "", "", name);
              else
                  setMasterLabel(findLeafName(name) + " - State");
              break;
          case MAIN::control::defaultPart:
          case MAIN::control::defaultInstrument:
              partSwitch(activePart);
              updatepanel();
              break;
          case MAIN::control::masterReset:
              if (newpart == TOPLEVEL::section::main)
              {
                  refresh_master_ui(1);
                  vumeter->init(-1, synth);
                  resetPartsClip();
              }
              else if (newpart < NUM_MIDI_PARTS)
                  partSwitch(newpart);
              setMasterLabel("");
              break;
  
          case MAIN::control::masterResetAndMlearn:
              refresh_master_ui(1);
              resetPartsClip();
              if (midilearnui)
                  midilearnui->midilearnwindow->hide();//Hide();
              setMasterLabel("");
              break;
  
          case MAIN::control::openManual:
              message->hide();
              if (miscmsg != NO_MSG)
                  query("", "", "", textMsgBuffer.fetch(miscmsg));
              break;
  
          case MAIN::control::startInstance: // new instance (do nothing here)
              break;
  
          case MAIN::control::stopSound:
              virkeyboard->relaseallkeys();
              vumeter->init(-1, synth);
              resetPartsClip();
              break;
      }
      return false;
}

int MasterUI::query(string one, string two, string three, string text) {
  //
      if (one.empty())
          yesQ->hide();
      else
      {
          if(one == "!")
          {
              yesQ->copy_label("Yes");
          }
          else
          {
              yesQ->copy_label(one.c_str());
          }
          yesQ->show();
      }
  
      if (two.empty())
          noQ->hide();
      else
      {
          if (two == "!")
          {
              noQ->copy_label("No");
          }
          else
          {
              noQ->copy_label(two.c_str());
          }
          noQ->show();
      }
      if (three.empty())
      {
          cancelQ->copy_label("OK");
          typeQ->copy_label("!");
      }
      else
      {
          if (three == "!")
          {
              cancelQ->copy_label("Cancel");
          }
          else
          {
              cancelQ->copy_label(three.c_str());
          }
          typeQ->copy_label("?");
      }
  
      textQ->copy_label(text.c_str());
  
      int X, Y, W, H, O;
      loadWin(synth, W, H, X, Y, O, "Master-query");
  
      if (W < queryDW || H < queryDH)
      {
          W = queryDW;
          H = queryDH;
      }
      checkSane(X, Y, W, H, queryDW, queryDH);
      querywindow->resize(Fl::event_x_root() + 16, Fl::event_y_root(), W, H);
  
      querywindow->show();
      int result = 0;
      while(querywindow->shown())
      {
          querywindow->show(); // keep it on top
          queryRtext();
          if (yesQ->value())
              result = 3;
          else if (noQ->value())
              result = 2;
          else if  (cancelQ->value())
              result = 1;
          Fl::wait();
      }
      saveWin(synth, querywindow->w(),querywindow->h(), querywindow->x(), querywindow->y(), false, "Master-query");
      return result;
}

void MasterUI::setmessage(int group, bool fixedPos, string text, string B1 , string B2 , string B3 ) {
  //
          msgGroup = group;
          if (B3.empty())
              yesdoit->hide();
          else
          {
              yesdoit->copy_label(B3.c_str());
              yesdoit->show();
          }
          if (B2.empty())
              cancel->hide();
          else
          {
              cancel->copy_label(B2.c_str());
              cancel->show();
          }
          closebutton->copy_label(B1.c_str());
          int X, Y, W, H, O;
          loadWin(synth, W, H,  X,  Y, O, "Master-message");
          if(W < msgDW || H < msgDW)
          {
              W = msgDW;
              H = msgDH;
  
          }
          checkSane(X, Y, W, H, msgDW, msgDH);
  
          if (fixedPos)
              message->resize(masterwindow->x() + masterwindow->w() / 2 - message->w() / 2, masterwindow->y() + masterwindow->h() / 2 - message->h() / 2, W, H);
          else
              message->resize(Fl::event_x_root() + 16, Fl::event_y_root(), W, H);
          words->copy_label(text.c_str());
          message->show();
}

string MasterUI::setinput(string label, string oldLine) {
  //
      textLine->copy_label(label.c_str());
      textLine->value(oldLine.c_str());
      int X, Y, W, H, O;
      loadWin(synth, W, H, X, Y, O, "Master-textin");
      X = Fl::event_x_root(); // aways want these relative to parent
      Y = Fl::event_y_root();
      if(W < textinDW || H < textinDH)
      {
          W = textinDW;
          H = textinDH;
      }
      checkSane(X, Y, W, H, textinDW, textinDH, true);
  
      textwindow->size(W, H);
      textwindow->show();
      string result;
      string oldline = textLine->value();
      size_t pos = 1;
      while (textwindow->shown())
      {
          textwindow->show(); // keep it on top
          textinRtext();
          result = string(textLine->value());
          Fl::wait();
          pos = result.find_last_not_of(' ');
          if (pos != string::npos)
              pos -= result.find_first_not_of(' ');
          if (Fl::event_key() == FL_Enter)
          {
              if (pos == 0 || pos > 1)
                  textwindow->hide();
              else
                  textLine->copy_label("Must be at least 3 letters or none");
          }
      }
      saveWin(synth, textwindow->w(), textwindow->h(), textwindow->x(), textwindow->y(), false, "Master-textin");
      if (pos == 0 || pos == string::npos)
          return oldline;
  
      return result;
}

void MasterUI::updatesendwindow() {
  //
      for (int neff1 = 0; neff1 < NUM_SYS_EFX; ++neff1)
          for (int neff2 = neff1 + 1; neff2 < NUM_SYS_EFX; ++neff2)
              syseffsend[neff1][neff2]->value(synth->Psysefxsend[neff1][neff2]);
}

void MasterUI::updatelistitem(int part) {
  //
      int tmp = part % NUM_MIDI_CHANNELS;
      panellistitem[tmp]->refresh();
}

void MasterUI::changepanelstyle(int type) {
  //
      if (type == 0)
          type = 1;
      panelwindow->hide();
      if (type != panelType)
      {
          if (type == 1)
          {
              panelwindow->size(PANEL_SINGLE_X, PANEL_SINGLE_Y);
              panelwindow->size_range((PANEL_SINGLE_X * 9) / 10, (PANEL_SINGLE_Y * 9) / 10, 0, 0, 0, 0, 1);
              towide->hide();
              todeep->show();
              Panelclose->position(975, 290);
          }
          else if (type == 2)
          {
              panelwindow->size(PANEL_DUAL_X, PANEL_DUAL_Y);
              panelwindow->size_range((PANEL_DUAL_X * 4) / 5, (PANEL_DUAL_Y * 4) / 5, 0, 0, 0, 0, 1);
              towide->show();
              todeep->hide();
          }
      }
      panelwindow->show();
      panelType = type;
      panelRtext();
}

void MasterUI::Showpanel() {
  //
      int fetchW, fetchH, fetchX, fetchY, fetchO;
      loadWin(synth, fetchW, fetchH, fetchX, fetchY, fetchO, "Mixer");
      if (fetchO == 0)
          fetchO = 1; // it's never been seen so set the default
  
      // assume default sizes
      int defW = (PANEL_SINGLE_X * 9) / 10;
      int defH = (PANEL_SINGLE_Y * 9) / 10;
  
      if (fetchW < (PANEL_DUAL_X * 9) / 10 || fetchH < defH)
      {
          fetchW = defW;
          fetchH = defH;
          fetchO = 1; // it's messed up so force default
      }
  
      int tmp = fetchO & 3;
      if (tmp == 2)
      {
          defW = (PANEL_DUAL_X * 9) / 10;
          defH = (PANEL_DUAL_Y * 9) / 10;
      }
  
      if (tmp == 1)
      {
          towide->hide();
          todeep->show();
      }
      else if (tmp == 2)
      {
          towide->show();
          todeep->hide();
      }
  
      panelwindow->size_range(defW, defH, 0, 0, 0, 0, 1);
      checkSane(fetchX, fetchY, fetchW, fetchH, defW, defH);
      panelwindow->resize(fetchX, fetchY, fetchW, fetchH);
  
      if (fetchO < 4)
      {
          panelType = tmp;
          panelwindow->show();
          updatepanel();
      }
      else
      {
          panelType = fetchO;
          panelwindow->hide();
      }
}

void MasterUI::updatepanel(bool full ) {
  //
      for (int part = 0; part < partmax; ++part)
      {
          if (part < NUM_MIDI_CHANNELS) // will be orred with panel group
              panellistitem[part]->refresh();
          vectorui->setInstrumentLabel(part);
      }
  
      if (partmax == (NUM_MIDI_CHANNELS * 4))
      {
          Panelgroups->value(npart / NUM_MIDI_CHANNELS);
          Panelgroups->show();
      }
      else
          Panelgroups->hide();
  
      if (partmax == (NUM_MIDI_CHANNELS * 2))
      {
          Panelsmallgroups->value(npart / NUM_MIDI_CHANNELS);
          Panelsmallgroups->show();
      }
      else
          Panelsmallgroups->hide();
  
      int oldswitch = channelswitch->value();
      channelswitch->value(synth->getRuntime().channelSwitchType);
      if (full)
      {
          oldswitch = channelswitch->value(); // disables 'pending'
          CS_CC = synth->getRuntime().channelSwitchCC;
      }
      if (synth->getRuntime().channelSwitchType > MIDI::SoloType::Disabled)
      {
          if (oldswitch == MIDI::SoloType::Disabled)
          {
              CSspinner->value(115);
              CSpend->show();
          }
          else
          {
              CSspinner->value(synth->getRuntime().channelSwitchCC);
              CSpend->hide();
          }
          CSspinner->show();
      }
      else
      {
          synth->getRuntime().channelSwitchCC = 128;
          CSspinner->hide();
          CSpend->hide();
      }
      panelwindow->changed();
}

void MasterUI::partSwitch(int next) {
  //
      if (npart != next)
      {
          npartcounter->value(next + 1);
          npartcounter->redraw();
          updatelistitem(npart); // deselect old one
          npart = next;
      }
      updatelistitem(next); // select and/or modify
      activePart = npart;
      partui->rebuild(npart);
  
      partEnable->value(synth->part[npart]->Penabled == 1);
      if (partEnable->value() == 1)
          partControls->activate();
      else
          partControls->deactivate();
      refreshControls(npart);
      masterwindow->redraw();
}

void MasterUI::updateEngines(int engine, string instrumentName) {
  //
          if (engine & 1) // addsynth
          instrumentaddbox->color(ADD_COLOUR);
      else
          instrumentaddbox->color(BASE_COLOUR);
  
      if (engine & 2) // subsynth
          instrumentsubbox->color(SUB_COLOUR);
      else
          instrumentsubbox->color(BASE_COLOUR);
  
      if (engine & 4) // padsynth
          instrumentpadbox->color(PAD_COLOUR);
      else
          instrumentpadbox->color(BASE_COLOUR);
  
      instrumentaddbox->damage(1);
      instrumentsubbox->damage(1);
      instrumentpadbox->damage(1);
      instrumentlabel->copy_label(instrumentName.c_str());
      instrumentlabel->damage(1);
  
      if (npart >= panelgroup && npart < (panelgroup + NUM_MIDI_CHANNELS))
      {
          int num = npart % NUM_MIDI_CHANNELS;
          if (engine & 1)
              panellistitem[num]->partadd->color(ADD_COLOUR);
          else
              panellistitem[num]->partadd->color(FL_BACKGROUND_COLOR);
          if (engine & 2)
              panellistitem[num]->partsub->color(SUB_COLOUR);
          else
              panellistitem[num]->partsub->color(FL_BACKGROUND_COLOR);
          if (engine & 4)
              panellistitem[num]->partpad->color(PAD_COLOUR);
          else
              panellistitem[num]->partpad->color(FL_BACKGROUND_COLOR);
  
          panellistitem[num]->partadd->damage(1);
          panellistitem[num]->partsub->damage(1);
          panellistitem[num]->partpad->damage(1);
          panellistitem[num]->partname->copy_label(instrumentName.c_str());
      }
}

void MasterUI::updatepart() {
  //
      if (checkmaxparts())
      {
          if (npart >= partmax)
          {
              npart %= NUM_MIDI_CHANNELS;
              npart += (partmax - NUM_MIDI_CHANNELS);
              npartcounter->value(npart + 1);
              npartcounter->do_callback();
          }
          maxparts->value(partmax);
          maxparts->redraw();
          return;
      }
  
      partEnable->value(synth->partonoffRead(npart));
  
      maxparts->value(partmax);
      maxparts->redraw();
      npartcounter->value(npart + 1);
      activePart = npart;
      npartcounter->redraw();
      refreshControls(npart);
}

void MasterUI::refreshControls(int npart) {
  //
      partVol->value(synth->part[npart]->Pvolume);
      partPan->value(synth->part[npart]->Ppanning);
      partVelOffset->value(synth->part[npart]->Pveloffs);
      partVelSense->value(synth->part[npart]->Pvelsns);
      partui->setinstrumentlabel();
      partMidiCh->value(synth->part[npart]->Prcvchn + 1);
      partKeyLimit->value(synth->part[npart]->Pkeylimit);
      partKeyShift->value(synth->part[npart]->Pkeyshift - 64);
      minKeyCount->value(synth->part[npart]->Pminkey);
      maxKeyCount->value(synth->part[npart]->Pmaxkey);
      partPortamento->value(synth->part[npart]->ctl->portamento.portamento);
  
      sysEff1->value(synth->Psysefxvol[0][npart]);
      sysEff2->value(synth->Psysefxvol[1][npart]);
      sysEff3->value(synth->Psysefxvol[2][npart]);
      sysEff4->value(synth->Psysefxvol[3][npart]);
  
      int tmp = synth->ReadPartKeyMode(npart);
      if (tmp > PART_MONO)
          partKeymode->value(PART_LEGATO);
      else
          partKeymode->value(tmp);
      if (tmp > PART_MONO && synth->part[npart]->Pdrummode != 0)
          modepatch->color(91);
      else
          modepatch->color(29);
      modepatch->redraw();
  
      partui->checkEngines();
}

void MasterUI::updatepartprogram(int next) {
  //
      if (vectorui)
          vectorui->setInstrumentLabel(next);
  
      if (partui->part->Prcvchn <  NUM_MIDI_CHANNELS)
      {
          partMidiCh->value(partui->part->Prcvchn + 1);
          partMidiCh->textcolor(FL_BLACK);
      }
      else
      {
           partMidiCh->textcolor(FL_WHITE);
           partMidiCh->redraw();
      }
      partSwitch(next);
}

void MasterUI::setMasterLabel(string name) {
  //
      string prefix;
      string panel;
      if  (name.size())
      {
          prefix = synth->makeUniqueName(name);
          panel = synth->makeUniqueName("Mixer Panel - "+name);
      }
      else
      {
          prefix = synth->makeUniqueName("");
          prefix = prefix.substr(0, prefix.length() - 3);
          panel = prefix + " : Mixer Panel";
      }
      masterwindow->copy_label(prefix.c_str());
      panelwindow->copy_label(panel.c_str());
      masterwindow->changed();
}

void MasterUI::do_load_scale(string fname) {
  //
      send_data(TOPLEVEL::action::lowPrio | TOPLEVEL::action::forceUpdate, MAIN::control::loadNamedScale, 0, TOPLEVEL::type::Integer, TOPLEVEL::section::main, UNUSED, UNUSED, UNUSED, textMsgBuffer.push(fname));
}

void MasterUI::do_load_instrument(string fname) {
  //
      int npart = partui->npart;
      if ((npart /  NUM_MIDI_CHANNELS) == (panelgroup  /  NUM_MIDI_CHANNELS))
      {
          int displaypart = npart % NUM_MIDI_CHANNELS;
          panellistitem[displaypart]->partenabled->value(0);
          panellistitem[displaypart]->panellistitemgroup->deactivate();
      }
      partEnable->value(0);
      send_data(TOPLEVEL::action::forceUpdate, MAIN::control::loadInstrumentByName, 0, TOPLEVEL::type::Integer, TOPLEVEL::section::main, npart, UNUSED, UNUSED, textMsgBuffer.push(fname));
}

void MasterUI::do_load_master(string filename) {
  //
      if (filename.empty())
      {
          filename = setfiler("", "", false, TOPLEVEL::XML::Patch);
          if (filename.empty())
              return;
      }
      send_data(TOPLEVEL::action::muteAndLoop | TOPLEVEL::action::forceUpdate, MAIN::control::loadNamedPatchset, 0, TOPLEVEL::type::Integer, TOPLEVEL::section::main, UNUSED, UNUSED, UNUSED, textMsgBuffer.push(filename));
}

void MasterUI::do_save_master() {
  //
      string filename = setfiler("", "", true, TOPLEVEL::XML::Patch);
      if (filename.empty())
          return;
      send_data(TOPLEVEL::action::lowPrio | TOPLEVEL::action::forceUpdate, MAIN::control::saveNamedPatchset, 0, TOPLEVEL::type::Integer, TOPLEVEL::section::main, UNUSED, UNUSED, UNUSED, textMsgBuffer.push(filename));
}

void MasterUI::refresh_master_ui(int type) {
  //
      if (microtonalui) // not taking chances!
          delete microtonalui;
      partmax = synth->getRuntime().NumAvailableParts;
      maxparts->value(partmax);
      checkmaxparts();
      panning_law->value(fetchData(0, MAIN::control::panLawType, TOPLEVEL::section::main));
  
      npartcounter->value((synth->getRuntime().currentPart) + 1);
      int next = synth->getRuntime().currentPart;
      partSwitch(next);
  
      nsyseff = 0;
      syseffnocounter->value(nsyseff + 1);
      sysefftype->value(synth->sysefx[nsyseff]->geteffect());
      syseffectui->refresh(synth->sysefx[nsyseff], TOPLEVEL::section::systemEffects, nsyseff);
  
      ninseff = 0;
      inseffnocounter->value(nsyseff + 1);
      setInsEff(ninseff);
  
      sysinsgroup->value(SystemEffectsGrp);
  
      bool status;
      SysEffOn->value(fetchData(0, EFFECT::sysIns::effectEnable, TOPLEVEL::section::systemEffects, UNUSED, 0));
      if (SysEffOn->value())
          sysefftype->activate();
      else
          sysefftype->deactivate();
      int efftype = fetchData(0, EFFECT::sysIns::effectType, TOPLEVEL::section::systemEffects, UNUSED, 0);
      if (efftype > 0)
      {
          status = fetchData(0, EFFECT::control::changed, TOPLEVEL::section::systemEffects, efftype + EFFECT::type::none, ninseff);
          syseffectui->UpdatePresetColour(status, sysefftype->value());
      }
      efftype = fetchData(0,EFFECT::sysIns::effectType, TOPLEVEL::section::insertEffects, UNUSED, 0);
      if (efftype > 0)
      {
          status = fetchData(0, EFFECT::control::changed, TOPLEVEL::section::insertEffects, efftype + EFFECT::type::none, ninseff);
          inseffectui->UpdatePresetColour(status, insefftype->value());
      }
  
  
  
  
      showSysEfxUI();
  
      masterkeyshift->value(synth->Pkeyshift - 64);
      setBpmFallbackValue(synth->PbpmFallback);
      mastervolumedial->value(synth->Pvolume);
      globalfinedetune->value(synth->microtonal.Pglobalfinedetune);
      microtonalui = new MicrotonalUI(&synth->microtonal, synth);
      if (type & 0x80)
          setMasterLabel(textMsgBuffer.fetch((type >> 8) & UNUSED));
      updatesendwindow();
      updatepanel(type > 0);
      if (type != 5)
          vectorui->RefreshChans();
      mastermono->value(0);
      mastermono->label("Stereo");
      if (type == 0x14)
      {
          for (int i = 1; i < 6; ++i)
              configui->update_config(i);
      }
}

bool MasterUI::checkmaxparts() {
  //
      bool changed = false;
      if (panelgroup >= partmax)
      {
          panelgroup = 0;
          Panelgroups->value(0);
          Panelsmallgroups->value(0);
          changed = true;
      }
      npartcounter->range(1, partmax);
      if (npart >= partmax)
      {
          npartcounter->value(1);
          activePart = 0;
          changed = true;
      }
      return changed;
}

void MasterUI::strategicRetreat(void) {
  query("", "", "", "Bad things happened,\nYoshimi strategically retreats.");
}

void MasterUI::Log(string msg) {
  yoshiLog->log(msg);
}

void MasterUI::showSysEfxUI(void) {
  //
      inseffectui->hide();
      inseffectui->deactivate();
      inseffectuigroup->hide();
      inseffectuigroup->deactivate();
  
      syseffectui->activate();
      syseffectui->show();
      syseffectuigroup->activate();
      syseffectuigroup->show();
}

void MasterUI::showInsEfxUI(void) {
  //
      syseffectui->hide();
      syseffectui->deactivate();
      syseffectuigroup->hide();
      syseffectuigroup->deactivate();
  
      inseffectui->activate();
      inseffectui->show();
      inseffectuigroup->activate();
      inseffectuigroup->show();
}

void MasterUI::showSysEffSends() {
  //
      int fetchW, fetchH, fetchX, fetchY, fetchO;
      loadWin(synth, fetchW, fetchH, fetchX, fetchY, fetchO, "Master-systemeffectsend");
  
      if(fetchW < syseffDW || fetchH < syseffDH)
      {
          fetchW = syseffDW;
          fetchH = syseffDH;
      }
      checkSane(fetchX, fetchY, fetchW, fetchH, syseffDW, syseffDH);
  
      syseffsendwindow->resize(fetchX, fetchY, fetchW, fetchH);
      syseffsendwindow->redraw();
      syseffsendwindow->show();
      syseffSeen = true;
}

void MasterUI::setinspartlist() {
  //
      inseffpart->clear();
      inseffpart->add("Master Out");
      inseffpart->add("Off");
      int size = synth->getRuntime().NumAvailableParts;
      for (int i = 0; i < size; ++i)
      {
          string num = string("00") + asString(i + 1);
          inseffpart->add((string("Part ") + asString(i + 1)).c_str());
      }
      int current = synth->Pinsparts[ninseff];
      if (current >= size)
      {
          current = -1; // off is safe
          synth->Pinsparts[ninseff] = current;
      }
      inseffpart->value(current + 2);
}

PresetsUI * MasterUI::getPresetsUi() {
  //
      return presetsui;
}

void MasterUI::resetPartsClip() {
  //
      for (int i = 0; i < NUM_MIDI_CHANNELS; i++)
      {
          if (panellistitem[i] && panellistitem[i]->partVUMeter)
          {
              panellistitem[i]->partVUMeter->resetPart(true);
          }
      }
}

void MasterUI::setInsEff(int effnum) {
  //
      int ninseff = effnum;
      insefftype->value(synth->insefx[ninseff]->geteffect());
      inseffpart->value(synth->Pinsparts[ninseff] + 2);
      inseffectui->refresh(synth->insefx[ninseff], TOPLEVEL::section::insertEffects, ninseff);
      if (synth->Pinsparts[ninseff] != -1)
      {
          insefftype->activate();
          inseffectui->activate();
          inseffectuigroup->activate();
      }
      else
      {
          insefftype->deactivate();
          inseffectui->deactivate();
          inseffectuigroup->deactivate();
      }
}

void MasterUI::setState(string filename) {
  //
      send_data(TOPLEVEL::action::muteAndLoop | TOPLEVEL::action::forceUpdate, MAIN::control::loadNamedState, 0, TOPLEVEL::type::Integer, TOPLEVEL::section::main, UNUSED, UNUSED, UNUSED, textMsgBuffer.push(filename));
}

string MasterUI::setPartWindowTitle(string prefix) {
  //
      string extension = " - Part " + asString(npart + 1) + " " + synth->part[npart]->Pname;
      if (synth->part[npart]->Pkitmode)
      {
          extension += ", Kit ";
          if (partui->lastkititem >= 0)
          {
              extension += to_string(partui->lastkititem + 1);
              if (partui->kitname > "")
                  extension += (" - " + partui->kitname);
          }
      }
      return synth->makeUniqueName(prefix + extension);
}

void MasterUI::setPartActive(int _npart, bool active) {
  //
      if (_npart == npart)
      {
          partEnable->value(active);
      }
}

void MasterUI::setPanelPartVolWidget(int _npart, float _value) {
  //
      panellistitem[_npart]->partvolume->value(_value);
}

void MasterUI::setPanelPartPanWidget(int _npart, float _value) {
  //
      panellistitem[_npart]->partpanning->value(_value);
}

void MasterUI::setPartMidiWidget(int _npart, unsigned char _value) {
  //
      if (_npart == npart)
          partMidiCh->value(_value);
      partMidiCh->textcolor(FL_BLACK);
}

void MasterUI::setPanelPartMidiWidget(int _npart, unsigned char _value) {
  //
      panellistitem[_npart]->partrcv->value(_value);
      panellistitem[_npart]->partrcv->textcolor(FL_BLACK);
      panellistitem[_npart]->partrcv->redraw();
}

void MasterUI::setLogging(bool isConsole) {
  //
      logenable = isConsole;
      if (logenable)
          yoshiLog->Show(synth);
      else if (yoshiLog->logConsole->visible())
          yoshiLog->Hide(synth);
}

void MasterUI::setBpmFallbackValue(float value) {
  bpmfallback->value(value);
  // Force format to include up to two decimal spaces, but only if
  // they are non-zero.
  char tmp[50];
  snprintf(tmp, sizeof(tmp), "%.2f", value);
  size_t len = strlen(tmp);
  
  // Use const char references, since Fl_Spinner does not make an
  // internal copy.
  const char *format = "%.2f";
  if (tmp[len-1] == '0') {
      format = "%.1f";
      if (tmp[len-2] == '0')
          format = "%.0f";
  }
  bpmfallback->format(format);
}

void MasterUI::updateBankRootDirs() {
  bankui->readbankcfg();
}

void MasterUI::updatepaths(int type) {
  //
      if (type == 0)
      {
          bankui->readbankcfg();
          bankui-> rescan_for_banks();
      }
}

SynthEngine * MasterUI::getSynth() {
  return synth;
}

void MasterUI::loadWindowData() {
  //
      int fetchW, fetchH, fetchX, fetchY, fetchO;
  
      if (lastSeen(synth, "Mixer") & 3)
          Showpanel();
  
      if (lastSeen(synth, "Bank-instrument"))
          bankui->ShowInst();
  
      loadWin(synth, fetchW, fetchH, fetchX, fetchY, fetchO, "Bank-bank");
      bankui->bankuiwindow->position(fetchX, fetchY);
      if (fetchO)
          bankui->Showbank();
      else
          bankui->bankuiwindow->hide();
  
      loadWin(synth, fetchW, fetchH, fetchX, fetchY, fetchO, "Bank-root");
      bankui->rootuiwindow->position(fetchX, fetchY);
      if (fetchO)
          bankui->ShowRoot();
      else
          bankui->rootuiwindow->hide();
  
      if (lastSeen(synth, "Midi-virtualkeyboard"))
          virkeyboard->ShowKbd();
      else
          virkeyboard->virkeyboardwindow->hide();
  
      if (lastSeen(synth, "Scales"))
          microtonalui->showScales();
      else
          microtonalui->microtonaluiwindow->hide();
  
      if (lastSeen(synth, "Midi-learn"))
          midilearnui->showLearn();
      else
          midilearnui->midilearnwindow->hide();
  
      if (lastSeen(synth, "Config"))
          configui->Show(synth); // this does some initialising
      else
          configui->configwindow->hide();
  
      if (lastSeen(synth, "System-log") & 1)
          yoshiLog->Show(synth);
      else if (yoshiLog->logConsole->visible())
          yoshiLog->Hide(synth);
  
      if (lastSeen(synth, "Vector"))
          vectorui->Show(synth);
      else
          vectorui->vectorwindow->hide();
  
       if (lastSeen(synth, "Part-effects"))
          partui->Showefx();
      else
          partui->partfx->hide();
  
      if (lastSeen(synth, "Part-controllers"))
          partui->Showctl();
      else
          partui->ctlwindow->hide();
  
      if (lastSeen(synth, "Part-aftertouch"))
          partui->ShowAT();
      else
          partui->aftertouchcontrol->hide();
  
      if (lastSeen(synth, "Part-ctlmidi"))
          partui->Showctlmidi();
      else
          partui->ctlmidi->hide();
  
      if (lastSeen(synth, "Part-kit"))
          partui->Showkit();
      else
          partui->instrumentkitlist->hide();
  
      if (lastSeen(synth, "Part-edit"))
          partui->Showedit();
      else
          partui->instrumenteditwindow->hide();
}

void MasterUI::checkBuffer(void) {
  //
              if (lastmainW < 0) // not ready yet!
                  return;
              read_updates(synth);
              wincheck();
}

void MasterUI::rescaleMain(void) {
  //
              if (lastmainW < 0) // not ready yet!
                  return;
              float ratio = Fl::w() / float(1024); // reference width
              if (ratio < 1.0f)
                  ratio = 1.0f;
  
  
              int x, y, w, h;
              if (syseffSeen)
              {
                  x = syseffsendwindow->x();
                  y = syseffsendwindow->y();
                  w = syseffDW * ratio;
                  h = syseffDH * ratio;
                  if ((x + w) > Fl::w())
                      x = Fl::w() - w;
                  if ((y + h) > Fl::h())
                      y = Fl::h() - h;
                  syseffsendwindow->resize(x, y, w, h);
              }
  
              // we always check the main window last
              x = masterwindow->x();
              y = masterwindow->y();
              w = mainDW * ratio;
              h = mainDH * ratio;
              if ((x + w) > Fl::w())
                  x = Fl::w() - w;
              if ((y + h) > Fl::h())
                  y = Fl::h() - h;
              masterwindow->resize(x, y, w, h);
              std::cout << "Screen ratio " << ratio << std::endl;
}

void MasterUI::wincheck() {
  //
      /*
       * Below is a pragmatic method of making tooltips
       * fairly readable at all screen resolutions.
       * 768 is the reference height.
       */
          if (oldH != Fl::h())
          {
              int setsize = int((11.0f / 768.0f) * Fl::h());
              Fl_Tooltip::size(setsize);
              oldH = Fl::h();
              //std::cout << "tipset " << setsize << "  actual " <<  Fl_Tooltip::size() << std::endl;
  
              if (masterwindow->x() >= Fl::w() || masterwindow->y() >= Fl::h())
                  Showmaster(); // ensure it's always visible
          }
  
      if (masterwindow->w() != lastmainW)
      {
          mainRtext();
          if (lastmainW < 3)
              ++lastmainW;
          else
              lastmainW = masterwindow->w();
      }
  
      if (yoshiLog->logConsole->visible())
          yoshiLog->consoleRtext();
  
      if (panelwindow->visible())
      {
          if (panelwindow->w() != lastpanelW)
          {
              panelRtext();
              lastpanelW = panelwindow->w();
          }
      }
  
      if (message->visible() && message->w() != lastmsgW)
      {
          msgRtext();
          lastmsgW = message->w();
          msgSeen = true;
      }
  
      if (syseffectui->visible() && sysefftype->value() == 8)
      {
          if(syseffectui->filterwindow != NULL)
          {
              if (syseffectui->filterwindow->visible())
                  syseffectui->filtRtext();
          }
      }
      else if (inseffectui->visible() && insefftype->value() == 8)
      {
          if(inseffectui->filterwindow != NULL)
          {
              if (inseffectui->filterwindow->visible())
                  inseffectui->filtRtext();
          }
      }
  
      if (syseffsendwindow->visible() &&  syseffsendwindow->w() != lastsyseffW)
      {
          syseffRtext();
          lastsyseffW = syseffsendwindow->w();
      }
  
      if (vectorui->vectorwindow->visible())
          vectorui->vectorRtext();
  
      if (microtonalui->microtonaluiwindow->visible())
          microtonalui->scaleRtext();
  
      if (midilearnui->midilearnwindow->visible())
          midilearnui->learnRtext();
  
      if (virkeyboard->virkeyboardwindow->visible() && lastvirtW != virkeyboard->virkeyboardwindow->w())
      {
          virkeyboard->virtRtext();
          lastvirtW = virkeyboard->virkeyboardwindow->w();
      }
  
      if (aboutwindow->visible() && lastaboutW != aboutwindow->w())
      {
          aboutRtext();
          lastaboutW = aboutwindow->w();
      }
  
      if (paramsui->Recent->visible())
          paramsui->paramRtext();
  
      if (configui->configwindow->visible())
          configui->configRtext();
  
      if (configui->presets->visible())
          configui->presetsRtext();
  
      presetsui->presetsRtext();
      bankui->wincheck();
      partui->wincheck();
}

void MasterUI::mainRtext() {
  //
  
      mainScale = float(masterwindow->w() / mainDW);
  
      int size = int(10 * mainScale);
      int size11 = int(11 * mainScale);
      int size12 = int(12 * mainScale);
  
      mastermenu->textsize(size12);
  
      // part insert controls
      partVol->labelsize(size);
      partPan->labelsize(size);
      partVelOffset->labelsize(size);
      partVelSense->labelsize(size);
      instrumentlabel->labelsize(size12);
      partEdit->labelsize(size12);
      partControllers->labelsize(size12);
      partMidiCCs->labelsize(size12);
      partMidiCh->labelsize(size11);
          partMidiCh->textsize(size11);
      partKeymode->textsize(size11);
          modepatch->labelsize(size11);
      partPortamento->labelsize(size11);
      minKeyCount->labelsize(size);
          minKeyCount->textsize(size11);
      maxKeyCount->labelsize(size);
          maxKeyCount->textsize(size11);
      setMinToLast->labelsize(size);
      setNormal->labelsize(size11);
      setMaxToLast->labelsize(size);
      partKeyShift->labelsize(size);
          partKeyShift->textsize(size11);
      partKeyLimit->labelsize(size);
          partKeyLimit->textsize(size11);
  
      sysEff1->labelsize(size);
      sysEff2->labelsize(size);
      sysEff3->labelsize(size);
      sysEff4->labelsize(size);
      sysEffName->labelsize(size);
  
      partEnable->labelsize(14 * mainScale);
  
      mainreset->labelsize(size11);
      mainstop->labelsize(size11);
      mainvirtkeyb->labelsize(size11);
      mixerpanel->labelsize(size11);
      mainmidilearn->labelsize(size11);
      vectors->labelsize(size11);
      globalfinedetune->labelsize(size);
      mastervolumedial->labelsize(size);
      mastermono->labelsize(size11);
      masterkeyshift->labelsize(size);
      masterkeyshift->textsize(size12);
      bpmfallback->labelsize(size);
      bpmfallback->textsize(size12);
  
      InstBlurb->labelsize(size11);
      nextInst->labelsize(size11);
      valueInst->textsize(size11);
      cancelInst->labelsize(size11);
  
      SystemEffectsGrp->labelsize(size12);
      syseffnocounter->labelsize(size11);
          syseffnocounter->textsize(size11);
      sysefftype->labelsize(size11);
          sysefftype->textsize(size11);
  
      SysEffOn->labelsize(size11);
      sysEffSend->labelsize(size11);
      sysCopy->labelsize(size11);
      sysPaste->labelsize(size11);
      syseffectui->effRtext(mainScale, sysefftype->value());
  
      InsertionEffectsGrp->labelsize(size12);
      inseffnocounter->labelsize(size11);
          inseffnocounter->textsize(size11);
      insefftype->labelsize(size11);
          insefftype->textsize(size11);
  
      inseffpart->labelsize(size11);
          inseffpart->textsize(size11);
      insCopy->labelsize(size11);
      insPaste->labelsize(size11);
      inseffectui->effRtext(mainScale, insefftype->value());
  
      npartcounter->labelsize(size11);
          npartcounter->textsize(size11);
      maxparts->labelsize(size11);
          maxparts->textsize(size11);
  
      panning_law->labelsize(size12);
          panning_law->textsize(size12);
  
      undo->labelsize(size11);
      redo->labelsize(size11);
  
      masterwindow->redraw();
}

void MasterUI::panelRtext() {
  //
      int w = panelwindow->w();
      int h = panelwindow->h();
      float dW;
      float dH;
  
      if (panelType == 1)
      {
          dW = w / float(PANEL_SINGLE_X);
          dH = h / float(PANEL_SINGLE_Y);
  
      }
      else
      {
          dW = w / float(PANEL_DUAL_X);
          dH = h / float(PANEL_DUAL_Y);
      }
  
      float dScale;
  
      if (dW < dH)
          dScale = dW;
      else
          dScale = dH;
      if (dScale < 0.2f)
          dScale = 0.2f;
      panelScale = dScale;
      if (panelType == 1)
      {
          for (int i = 0; i < 16; ++ i)
          {
              panellistitem[i]->resize((8 + (i * 64)) * dW, 12 * dH, 63 * dW, 268 * dH);
              panellistitem[i]->itemRtext(dScale);
          }
  
      }
      else
      {
          for (int i = 0; i < 8; ++ i)
          {
              panellistitem[i]->resize((8 + (i * 64)) * dW, 12 * dH, 63 * dW, 268 * dH);
              panellistitem[i]->itemRtext(dScale);
          }
          for (int i = 8; i < 16; ++ i)
          {
              panellistitem[i]->resize((8 + ((i - 8) * 64)) * dW, 290 * dH, 63 * dW, 268 * dH);
              panellistitem[i]->itemRtext(dScale);
          }
  
          towide->resize(335 * dW, (PANEL_DUAL_Y - 30) * dH, 130 * dW, 25 * dH);
          Panelsmallgroups->resize(5 * dW, (PANEL_DUAL_Y - 23) * dH, 86 * dW, 18 * dH);
          Panelgroups->resize(5 * dW, (PANEL_DUAL_Y - 23) * dH, 86 * dW, 18 * dH);
          CSspinner->resize(173 * dW, (PANEL_DUAL_Y - 23) * dH, 50 * dW, 18 * dH);
          CSpend->resize(227 * dW, (PANEL_DUAL_Y - 30) * dH, 74 * dW, 25 * dH);
          channelswitch->resize(95 * dW, (PANEL_DUAL_Y -23) * dH, 74 * dW, 18 * dH);
          Panelclose->resize((PANEL_DUAL_X - 55) * dW, (PANEL_DUAL_Y - 30) * dH, 50 * dW, 25 * dH);
  
      }
  
      int size12 = int(12 * dScale);
      int size14 = int(14 * dScale);
      towide->labelsize(size14);
      todeep->labelsize(size14);
      Panelgroups->labelsize(size12);
          Panelgroups->textsize(size12);
      Panelsmallgroups->labelsize(size12);
          Panelsmallgroups->textsize(size12);
      CSspinner->labelsize(size12);
          CSspinner->textsize(size12);
      CSpend->labelsize(size12);
      channelswitch->labelsize(size12);
          channelswitch->textsize(size12);
      Panelclose->labelsize(size14);
  
      panelwindow->redraw();
}

void MasterUI::aboutRtext() {
  //
      float dScale = aboutwindow->w() / float(aboutDW);
  
      int size11 = int(11 * dScale);
      int size12 = int(12 * dScale);
  
      about2->labelsize(size11);
      about3->labelsize(size11);
      about4->labelsize(size12);
      about5->labelsize(size11);
      cont2->labelsize(size12);
      cont3->labelsize(size12);
      aboutClose->labelsize(size11);
      about1->labelsize(int(18 * dScale));
      cont1->labelsize(int(15 * dScale));
  
      aboutwindow->redraw();
      saveWin(synth, aboutwindow->w(), aboutwindow->h(), aboutwindow->x(), aboutwindow->y(), true, "Master-about");
}

void MasterUI::syseffRtext() {
  //
      float dScale = syseffsendwindow->w() / float(syseffDW);
  
      int size = int(10 * dScale);
  
      syseffgroup->resize(int(9 * dScale), int(46 * dScale), int(109 * dScale), int(172 * dScale));
      syseffname->labelsize(size);
  
      for (int neff1 = 0; neff1 < NUM_SYS_EFX; ++neff1)
          for (int neff2 = neff1 + 1; neff2 < NUM_SYS_EFX; ++neff2)
          {
              syseffsend[neff1][neff2]->labelsize(size);
              syseffsend[neff1][neff2]->resize(int((-25 * dScale) + (35 * (neff2)) * dScale), int((66 * dScale) + (neff1 * dScale * 52)), int(35 * dScale), int(30 * dScale));
          }
  
      syseffClose->labelsize(int(14 * dScale));
  
      syseffsendwindow->redraw();
}

void MasterUI::queryRtext() {
  //
      if (lastqueryW == querywindow->w())
          return;
      lastqueryW = querywindow->w();
  
      float dScale = querywindow->w() / float(queryDW);
  
      int size14 = int(14 * dScale);
  
      yesQ->labelsize(size14);
      noQ->labelsize(size14);
      cancelQ->labelsize(size14);
      textQ->labelsize(size14);
      typeQ->labelsize(int(40 * dScale));
  
      querywindow->redraw();
}

void MasterUI::msgRtext() {
  //
      float dScale = message->w() / float(msgDW);
  
      int size14 = int(14 * dScale);
  
      words->labelsize(12 * dScale);
      yesdoit->labelsize(size14);
      cancel->labelsize(size14);
      closebutton->labelsize(size14);
  
      message->redraw();
      saveWin(synth, message->w(), message->h(),  message->x(),  message->y(), true, "Master-message");
}

void MasterUI::textinRtext() {
  //
      if (lasttextW == textwindow->w())
          return;
      lasttextW = textwindow->w();
  
      float dScale = textwindow->w() / float(textinDW);
  
      int size14 = int(14 * dScale);
  
      textLine->labelsize(size14);
      textLine->textsize(size14);
      textwindow->redraw();
}
