# data file for the Fltk User Interface Designer (fluid)
version 1.0308
header_name {.h}
code_name {.cc}
comment {
Copyright (C) 2016-2024, Will Godfrey

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 3 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 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.

} {selected in_source in_header
}

decl {\#include "MasterUI.h"} {private global
}

decl {\#include "Misc/SynthEngine.h"} {public global
}

decl {\#include "UI/MiscGui.h"} {public local
}

decl {\#include "UI/WidgetSpinner.h"} {public local
}

decl {\#include "BankUI.h"} {public local
}

decl {\#include "ParametersUI.h"} {public local
}

decl {\#include "Misc/FileMgrFuncs.h"
    using file::findLeafName;
    using file::setExtension;
    using file::isRegularFile;} {private local
}

decl {\#include "Misc/NumericFuncs.h"
    using func::bitClear;
    using func::bitTest;
    using func::bitSet;} {private local
}

decl {\#include "Misc/TextMsgBuffer.h"

    namespace { // Implementation details...
        TextMsgBuffer& textMsgBuffer = TextMsgBuffer::instance();
    }} {private local
}

decl {\#include <vector>
    \#include <string>
    using std::vector;
    using std::to_string;} {private global
}

class VectorUI {} {
  Function {make_window()} {} {
    Fl_Window vectorwindow {
      label {Yoshimi : Vectors}
      callback {//
      Closevector->do_callback();} open
      xywh {382 256 375 295} type Double labelfont 13 labelsize 12 align 0 hide resizable
      code0 {vecDW = o->w();vecDH = o->h();}
      code1 {o->size_range(vecDW, vecDH, 0, 0, 0, 0, 1);}
    } {
      Fl_Spinner setbasechan {
        label {Base Channel}
        callback {//
        BaseChan = o->value() - 1;
        updateAll(false);}
        tooltip {The channel number for this vector} xywh {121 12 38 20} labelfont 1 labelsize 12 labelcolor 64 maximum 16 textsize 12 textcolor 64
        code0 {o->value(BaseChan + 1);}
        class WidgetSpinner
      }
      Fl_Menu_Button options {
        label {&Options}
        callback {int res = o->value();
switch (res)
{
    case 0:
        loadVector("");
        break;
    case 1:
    {
        bool ok = true;
          int count;
          int size;
          string name;

          if (Xcc == 0)
          {
              alert(synth, "Nothing to save!");
              ok = false;
          }
          else
          {
              count = 0;
              if (Ycc > 0)
                  size = NUM_MIDI_CHANNELS * 4;
              else
                  size = NUM_MIDI_CHANNELS * 2;
              for (int i = 0; i < size; i += NUM_MIDI_CHANNELS)
              {
                  string partName = "";
                  if (textMsgBuffer.fetch(collect_readData(synth, 0, PART::instrumentName, BaseChan + i)) != DEFAULT_NAME)
                      count += NUM_MIDI_CHANNELS;
              }
              if (count != size)
              {
                  if (count == 0)
                      name = "No instruments set!";
                  else
                      name = "Only " + to_string(count/NUM_MIDI_CHANNELS) + " of " +  to_string(size/NUM_MIDI_CHANNELS) + " instruments set!";
                  alert(synth, name);
                  ok = false;
              }
          }

          if (ok)
              saveVector();
        break;
    }
    case 2:
        paramsui->Recent->position(vectorwindow->x() + vectorwindow->w() - paramsui->Recent->w(),vectorwindow->y()+20);
        paramsui->Show(TOPLEVEL::XML::Vector);
        break;
    case 3:
        send_data(TOPLEVEL::action::forceUpdate, VECTOR::control::erase, 0, TOPLEVEL::type::Integer, TOPLEVEL::section::vector, UNUSED, UNUSED, UNUSED, BaseChan);
        break;
    case 4:
        send_data(TOPLEVEL::action::forceUpdate, VECTOR::control::erase, 0, TOPLEVEL::type::Integer);
        break;
}}
        xywh {275 12 74 20} labelsize 12 labelcolor 64 textsize 12 textcolor 64
        code0 {o->add("Load");o->add("Save");o->add("Recent");o->add("Clear Ch");o->add("Clear All");}
        code1 {vector<string> const& history{synth->getHistory(TOPLEVEL::XML::Vector)};}
        code2 {setRecent(not history.empty());}
      } {}
      Fl_Group Xgroup {
        label X
        xywh {8 42 360 104} box PLASTIC_THIN_UP_BOX color 223 labelfont 1 labelsize 16 labelcolor 64 align 0 deactivate
      } {
        Fl_Box AddBackL {
          xywh {21 53 53 19} box FLAT_BOX color 50
        }
        Fl_Box SubBackL {
          xywh {74 53 53 19} box FLAT_BOX color 50
        }
        Fl_Box PadBackL {
          xywh {127 53 53 19} box FLAT_BOX color 50
        }
        Fl_Text_Display XinstL {
          xywh {20 69 160 1} box NO_BOX labelsize 12 labelcolor 64 align 97 textsize 12 textcolor 64
        }
        Fl_Button XL {
          callback {//
          (void) o; // suppress warning
          synth->getGuiMaster()->partSwitch(BaseChan);
          bankui->Show();}
          tooltip {Part corresponding to joystick 'left' position} xywh {20 53 160 20} box ENGRAVED_FRAME color 51 labelsize 12 align 64
        }
        Fl_Box AddBackR {
          xywh {21 115 53 19} box FLAT_BOX color 50
        }
        Fl_Box SubBackR {
          xywh {74 115 53 19} box FLAT_BOX color 50
        }
        Fl_Box PadBackR {
          xywh {127 115 53 19} box FLAT_BOX color 50
        }
        Fl_Text_Display XinstR {
          xywh {20 131 160 1} box NO_BOX labelsize 12 labelcolor 64 align 97 textsize 12 textcolor 64
        }
        Fl_Button XR {
          callback {//
          (void) o; // suppress warning
          synth->getGuiMaster()->partSwitch(BaseChan + NUM_MIDI_CHANNELS);
          bankui->Show();}
          tooltip {Part corresponding to joystick 'right' position} xywh {20 115 160 20} box ENGRAVED_FRAME color 51 labelsize 12 labelcolor 64 align 64
        }
        Fl_Text_Display Xfeat {
          label Features
          xywh {233 101 97 14} box NO_BOX labelfont 1 labelcolor 64 textsize 12 textcolor 64
        }
        Fl_Choice Xfeat1 {
          label 1
          callback {//
          if (o->value() == 0)
              bitClear(Xf, 0);
          else
              bitSet(Xf, 0);
          send_data(0, VECTOR::control::Xfeature0, o->value(), TOPLEVEL::type::Integer);}
          xywh {208 53 58 20} down_box BORDER_BOX labelsize 12 labelcolor 64 align 8 textsize 12 textcolor 64
          code0 {o->add("off");o->add("vol");}
        } {}
        Fl_Choice Xfeat2 {
          label 2
          callback {//
          bitClear(Xf, 1);
          bitClear(Xf, 4);
          if (o->value() >= 1)
          {
              bitSet(Xf, 1);
              if (o->value() == 2)
                  bitSet(Xf, 4);
          }
          send_data(0, VECTOR::control::Xfeature1, o->value(), TOPLEVEL::type::Integer);}
          xywh {302 53 58 20} down_box BORDER_BOX labelsize 12 labelcolor 64 textsize 12 textcolor 64
          code0 {o->add("off");o->add("pan");o->add("panR");}
        } {}
        Fl_Choice Xfeat3 {
          label 3
          callback {//
          bitClear(Xf, 2);
          bitClear(Xf, 5);
          if (o->value() >= 1)
          {
              bitSet(Xf, 2);
              if (o->value() == 2)
                  bitSet(Xf, 5);
          }
          send_data(0, VECTOR::control::Xfeature2, o->value(), TOPLEVEL::type::Integer);}
          xywh {208 115 58 20} down_box BORDER_BOX labelsize 12 labelcolor 64 align 8 textsize 12 textcolor 64
          code0 {o->add("off");o->add("filt");o->add("filtR");}
        } {}
        Fl_Choice Xfeat4 {
          label 4
          callback {//
          bitClear(Xf, 3);
          bitClear(Xf, 6);
          if (o->value() >= 1)
          {
              bitSet(Xf, 3);
              if (o->value() == 2)
                  bitSet(Xf, 6);
          }
          send_data(0, VECTOR::control::Xfeature3, o->value(), TOPLEVEL::type::Integer);}
          xywh {302 115 58 20} down_box BORDER_BOX labelsize 12 labelcolor 64 textsize 12 textcolor 64
          code0 {o->add("off");o->add("mod");o->add("modR");}
        } {}
      }
      Fl_Spinner Xcontrol {
        label Controller
        callback {//
        int tmp = o->value();

        if (tmp == 0)
        {
            Xcc = 0;
            Xgroup->deactivate();
            Ycc = 0;
            Ycontrol->value(0);
            Ycontrol->deactivate();
            Ygroup->deactivate();
            send_data(TOPLEVEL::action::forceUpdate, VECTOR::control::erase, 0, TOPLEVEL::type::Integer, TOPLEVEL::section::vector, UNUSED, UNUSED, UNUSED, BaseChan);
            return;
        }

        if (tmp > 119)
        {
            o->value(0);
            Xcc = 0;
            Xgroup->deactivate();
            Ycc = 0;
            Ycontrol->value(0);
            Ycontrol->deactivate();
            Ygroup->deactivate();
            errorlabel("CC must be less than 120");
            return;

        }

        string name = textMsgBuffer.fetch(collect_readData(synth, tmp, MAIN::knownCCtest, TOPLEVEL::main));
        if (name != "")
        {
            errorlabel("CC " + to_string(tmp) +" in use for " + name);
            Xcc = 0;
            o->value(0);
            Xgroup->deactivate();
            Ycc = 0;
            Ycontrol->value(0);
            Ycontrol->deactivate();
            Ygroup->deactivate();
            return;
        }

        Ycontrol->activate();
        Xcc =  tmp;
        Xgroup->activate();
        send_data(TOPLEVEL::action::forceUpdate, VECTOR::control::Xcontroller, tmp, TOPLEVEL::type::Integer);}
        tooltip {The MIDI CC this axis reponds to} xywh {110 85 50 20} labelfont 1 labelsize 12 labelcolor 64 minimum 0 maximum 127 value 0 textsize 12 textcolor 64
        code0 {//
        o->value(Xcc);}
        class WidgetSpinner
      }
      Fl_Button Closevector {
        label {&Close}
        callback {//
            saveWin(synth, vectorwindow->w(), vectorwindow->h(), vectorwindow->x(), vectorwindow->y(), false, "Vector");
        vectorwindow->hide();
        setVisible(synth, false, "Vector");
        vectorSeen = false;}
        xywh {308 264 58 22} color 196 labelfont 13 labelsize 12 labelcolor 64
      }
      Fl_Group Ygroup {
        label Y
        xywh {8 152 360 104} box PLASTIC_THIN_UP_BOX color 223 labelfont 1 labelsize 16 labelcolor 64 align 0 deactivate
      } {
        Fl_Box AddBackU {
          xywh {21 163 53 19} box FLAT_BOX color 50
        }
        Fl_Box SubBackU {
          xywh {74 163 53 19} box FLAT_BOX color 50
        }
        Fl_Box PadBackU {
          xywh {127 163 53 19} box FLAT_BOX color 50
        }
        Fl_Text_Display YinstU {
          private xywh {20 179 160 1} box NO_BOX labelsize 12 labelcolor 64 align 97 textsize 12 textcolor 64
        }
        Fl_Button YU {
          callback {//
          (void) o; // suppress warning
          synth->getGuiMaster()->partSwitch(BaseChan + (NUM_MIDI_CHANNELS * 2));
          bankui->Show();}
          tooltip {Part corresponding to joystick 'up' position} xywh {20 163 160 20} box ENGRAVED_FRAME color 51 labelsize 12 labelcolor 64 align 64
        }
        Fl_Box AddBackD {
          xywh {21 225 53 19} box FLAT_BOX color 50
        }
        Fl_Box SubBackD {
          xywh {74 225 53 19} box FLAT_BOX color 50
        }
        Fl_Box PadBackD {
          xywh {127 225 53 19} box FLAT_BOX color 50
        }
        Fl_Text_Display YinstD {
          private xywh {20 241 160 1} box NO_BOX labelsize 12 labelcolor 64 align 97 textsize 12 textcolor 64
        }
        Fl_Button YD {
          callback {//
          (void) o; // suppress warning
          synth->getGuiMaster()->partSwitch(BaseChan + (NUM_MIDI_CHANNELS * 3));
          bankui->Show();}
          tooltip {Part corresponding to joystick 'down'position} xywh {20 225 160 20} box ENGRAVED_FRAME color 51 labelsize 12 labelcolor 64 align 64
        }
        Fl_Text_Display Yfeat {
          label Features
          xywh {233 211 97 14} box NO_BOX labelfont 1 labelcolor 64 textsize 12 textcolor 64
        }
        Fl_Choice Yfeat1 {
          label 1
          callback {//
          if (o->value() == 0)
              bitClear(Yf, 0);
          else
              bitSet(Yf, 0);
          send_data(0, VECTOR::control::Yfeature0, o->value(), TOPLEVEL::type::Integer);}
          xywh {208 163 58 20} down_box BORDER_BOX labelsize 12 labelcolor 64 align 8 textsize 12 textcolor 64
          code0 {o->add("off");o->add("vol");}
        } {}
        Fl_Choice Yfeat2 {
          label 2
          callback {//
          bitClear(Yf, 1);
          bitClear(Yf, 4);
          if (o->value() >= 1)
          {
              bitSet(Yf, 1);
              if (o->value() == 2)
                  bitSet(Yf, 4);
          }
          send_data(0, VECTOR::control::Yfeature1, o->value(), TOPLEVEL::type::Integer);}
          xywh {302 163 58 20} down_box BORDER_BOX labelsize 12 labelcolor 64 textsize 12 textcolor 64
          code0 {o->add("off");o->add("pan");o->add("panR");}
        } {}
        Fl_Choice Yfeat3 {
          label 3
          callback {//
          bitClear(Yf, 2);
          bitClear(Yf, 5);
          if (o->value() >= 1)
          {
              bitSet(Yf, 2);
              if (o->value() == 2)
                  bitSet(Yf, 5);
          }
          send_data(0, VECTOR::control::Yfeature2, o->value(), TOPLEVEL::type::Integer);}
          xywh {208 225 58 20} down_box BORDER_BOX labelsize 12 labelcolor 64 align 8 textsize 12 textcolor 64
          code0 {o->add("off");o->add("filt");o->add("filtR");}
        } {}
        Fl_Choice Yfeat4 {
          label 4
          callback {//
          bitClear(Yf, 3);
          bitClear(Yf, 6);
          if (o->value() >= 1)
          {
              bitSet(Yf, 3);
              if (o->value() == 2)
                  bitSet(Yf, 6);
          }
          send_data(0, VECTOR::control::Yfeature3, o->value(), TOPLEVEL::type::Integer);}
          xywh {302 225 58 20} down_box BORDER_BOX labelsize 12 labelcolor 64 textsize 12 textcolor 64
          code0 {o->add("off");o->add("mod");o->add("modR");}
        } {}
      }
      Fl_Spinner Ycontrol {
        label Controller
        callback {//
        int tmp = o->value();

        if (tmp < 1)
        {
            Ycc = 0;
            Ygroup->deactivate();
            send_data(0, VECTOR::control::Ycontroller, 0xff, TOPLEVEL::type::Integer);
            return;
        }
        if (tmp > 119)
        {
                Ygroup->deactivate();
                errorlabel("CC must be less than 120");
                Ycc = 0;
                o->value(0);
                return;

        }


        string name = textMsgBuffer.fetch(collect_readData(synth, tmp, MAIN::knownCCtest, TOPLEVEL::main));
        if (name != "")
        {
            errorlabel("CC " + to_string(tmp) +" in use for " + name);
            Ycc = 0;
            Ygroup->deactivate();
            o->value(0);
            return;
        }


        Ycc =  tmp;
        send_data(TOPLEVEL::action::forceUpdate, VECTOR::control::Ycontroller, tmp, TOPLEVEL::type::Integer);}
        tooltip {The MIDI CC this axis reponds to} xywh {110 195 50 20} labelfont 1 labelsize 12 labelcolor 64 minimum 0 maximum 127 value 0 textsize 12 textcolor 64 deactivate
        code0 {o->value(Ycc);}
        class WidgetSpinner
      }
      Fl_Button Loaded {
        label {No Name}
        callback {//
        (void) o; // suppress warning
        string tmp = input_text(synth, "Vector name:", loadlabel[BaseChan]);
        if (tmp != loadlabel[BaseChan])
            send_data(TOPLEVEL::action::lowPrio | TOPLEVEL::action::forceUpdate, VECTOR::control::name, 0, TOPLEVEL::type::Integer, TOPLEVEL::section::vector, UNUSED, UNUSED, UNUSED, BaseChan, textMsgBuffer.push(tmp));}
        tooltip {Last saved or loaded vector file - click to change the name} xywh {45 264 198 22} box DOWN_BOX color 7 labelfont 1 labelsize 12 labelcolor 64
      }
    }
  }
  Function {send_data(int action, int control, float value, int type, int part = TOPLEVEL::section::vector, int kit = UNUSED, int engine = UNUSED, int insert = UNUSED, int parameter = UNUSED, int miscmsg = UNUSED)} {} {
    code {//
        if (control != MAIN::control::partNumber && control != MAIN::loadNamedVector && control != MAIN::saveNamedVector && control != VECTOR::control::erase)
        {
            parameter = BaseChan;
        }
        type |= TOPLEVEL::type::Write;
        collect_writeData(synth, value, action, type, control, part, kit, engine, insert, parameter, UNUSED, miscmsg);} {}
  }
  Function {returns_update(CommandBlock *getData)} {} {
    code {//
    float value = getData->data.value;
    unsigned char control = getData->data.control;
    unsigned char parameter = getData->data.parameter;
    unsigned char miscmsg = getData->data.miscmsg;
    int value_int = lrint(value);
    string msg;

    switch (control)
    {
        case VECTOR::control::name:
            msg = textMsgBuffer.fetch(miscmsg);
            loadlabel[parameter] = msg;
            Loaded->copy_label(msg.c_str());
            break;

        case VECTOR::control::Xcontroller:
            if (value_int > 119)
            {
                Xcc = 0;
                Ycc = 0;
                Xgroup->deactivate();
                Xcontrol->value(0);
                Ycontrol->value(0);
                Ygroup->deactivate();
                Ycontrol->deactivate();
                errorlabel("CC must be less than 120");
            }
            else
            {
                Xgroup->activate();
                Xcontrol->value(value_int);
                Ycontrol->activate();

                if (synth->getGuiMaster()->partmax < NUM_MIDI_CHANNELS * 2)
                {
                    synth->getGuiMaster()->maxparts->value(NUM_MIDI_CHANNELS * 2);
                    synth->getGuiMaster()->maxparts->do_callback();
                    synth->getGuiMaster()->Panelsmallgroups->show();
                }
            }
            break;

        case VECTOR::control::Xfeature0:
            Xfeat1->value(value_int);
            break;
        case VECTOR::control::Xfeature1:
            Xfeat2->value(value_int);
            break;
        case VECTOR::control::Xfeature2:
            Xfeat3->value(value_int);
            break;
        case VECTOR::control::Xfeature3:
            Xfeat4->value(value_int);
            break;

        case VECTOR::control::Ycontroller:
            if (value_int > 119)
            {
                Ygroup->deactivate();
                Ycontrol->value(0);
                Ycc = 0;
                Ygroup->deactivate();
                errorlabel("CC must be less than 120");
            }
            else
            {
                Ygroup->activate();
                Ycontrol->value(value_int);

                if (synth->getGuiMaster()->partmax < NUM_MIDI_CHANNELS * 4)
                {
                    synth->getGuiMaster()->maxparts->value(NUM_MIDI_CHANNELS * 4);
                    synth->getGuiMaster()->maxparts->do_callback();
                    synth->getGuiMaster()->Panelsmallgroups->hide();
                    synth->getGuiMaster()->Panelgroups->show();
                }
            }
            break;

        case VECTOR::control::Yfeature0:
            Yfeat1->value(value_int);
            break;
        case VECTOR::control::Yfeature1:
            Yfeat2->value(value_int);
            break;
        case VECTOR::control::Yfeature2:
            Yfeat3->value(value_int);
            break;
        case VECTOR::control::Yfeature3:
            Yfeat4->value(value_int);
            break;

        case VECTOR::control::erase:
            if (parameter >= NUM_MIDI_PARTS)
            {
                for (int i = NUM_MIDI_CHANNELS - 1; i >= 0; --i)
                    clearVector(i);
                BaseChan = 0;
                setbasechan->value(1);
            }
            else
                clearVector(parameter);
            break;
    };
    vectorwindow->redraw();} {}
  }
  Function {setRecent(bool active)} {} {
    code {//
    Fl_Menu_Item *m = (Fl_Menu_Item*)options->find_item("Recent");
    if (active)
        m->activate();
    else
        m->deactivate();} {}
  }
  Function {VectorUI(SynthEngine *_synth, BankUI *_bankui, ParametersUI *_paramsui)} {} {
    code {//
    synth = _synth;
    bankui = _bankui;
    paramsui = _paramsui;
    BaseChan = 0;
    Xcc = 0;
    Xf = 0;
    Ycc = 0;
    Yf = 0;
    make_window();
    vectorwindow->copy_label(textMsgBuffer.fetch(collect_readData(synth, textMsgBuffer.push("Vectors"), UNUSED, TOPLEVEL::windowTitle)).c_str());
    updateAll();
    vectorSeen = false;
    lastvectorW = 0;} {}
  }
  Function {~VectorUI()} {} {
    code {//
        if (vectorSeen)
            saveWin(synth, vectorwindow->w(), vectorwindow->h(), vectorwindow->x(), vectorwindow->y(), true, "Vector");
        vectorwindow->hide();
        delete  vectorwindow;} {}
  }
  Function {updateAll(bool everything = true)} {} {
    code {//
    if (everything)
    {
        BaseChan = 0;
        setbasechan->value(BaseChan + 1);
        for (int i = 0; i < NUM_MIDI_CHANNELS; ++i)
            loadlabel[i] = "No Name " + to_string(i + 1);

    }
    setInstrumentLabel(BaseChan);
    setInstrumentLabel(BaseChan + NUM_MIDI_CHANNELS);
    setInstrumentLabel(BaseChan + NUM_MIDI_CHANNELS * 2);
    setInstrumentLabel(BaseChan + NUM_MIDI_CHANNELS * 3);

    Loaded->copy_label(loadlabel[BaseChan].c_str());
    setbuttons();
    if (Xcontrol->value() > 0)
        Ycontrol->activate();
    else
        Ycontrol->deactivate();} {}
  }
  Function {RefreshChans()} {} {
    code {//
    for (int i = NUM_MIDI_CHANNELS; i > 0; --i)
    {
        BaseChan = i - 1;
        setInstrumentLabel(BaseChan);
        setInstrumentLabel(BaseChan + NUM_MIDI_CHANNELS);
        setInstrumentLabel(BaseChan + NUM_MIDI_CHANNELS * 2);
        setInstrumentLabel(BaseChan + NUM_MIDI_CHANNELS * 3);
        setbuttons();
    }
    Loaded->copy_label(loadlabel[0].c_str());
    setbasechan->value(1);} {}
  }
  Function {setbuttons()} {} {
    code {//
    Xcc = collect_readData(synth, 0, VECTOR::control::Xcontroller, TOPLEVEL::section::vector, UNUSED, UNUSED, UNUSED, BaseChan);
    if (Xcc == 0 || Xcc > 119)
    {
        Xcc = 0;
        Xf = 0;
        Xgroup->deactivate();
        Ycc = 0;
        Yf = 0;
        Ygroup->deactivate();
    }
    else
    {
        Xf = collect_readData(synth, 0, VECTOR::control::Xfeature0, TOPLEVEL::section::vector, UNUSED, UNUSED, UNUSED, BaseChan);
        Xgroup->activate();

        Ycc = collect_readData(synth, 0, VECTOR::control::Ycontroller, TOPLEVEL::section::vector, UNUSED, UNUSED, UNUSED, BaseChan);
        if (Ycc > 119)
        {
            Ycc = 0;
            Ygroup->deactivate();
        }
        else
        {
            Yf = collect_readData(synth, 0, VECTOR::control::Yfeature0, TOPLEVEL::section::vector, UNUSED, UNUSED, UNUSED, BaseChan);
            Ygroup->activate();
        }
    }

    Xcontrol->value(Xcc);
    if (bitTest(Xf,0))
        Xfeat1->value(1);
    else
        Xfeat1->value(0);

    if (bitTest(Xf,4))
        Xfeat2->value(2);
    else if (bitTest(Xf,1))
        Xfeat2->value(1);
    else
        Xfeat2->value(0);

    if (bitTest(Xf,5))
        Xfeat3->value(2);
    else if (bitTest(Xf,2))
        Xfeat3->value(1);
    else
        Xfeat3->value(0);

    if (bitTest(Xf,6))
        Xfeat4->value(2);
    else if (bitTest(Xf,3))
        Xfeat4->value(1);
    else
        Xfeat4->value(0);

    Ycontrol->value(Ycc);
    if (bitTest(Yf,0))
        Yfeat1->value(1);
    else
        Yfeat1->value(0);

    if (bitTest(Yf,4))
        Yfeat2->value(2);
    else if (bitTest(Yf,1))
        Yfeat2->value(1);
    else
        Yfeat2->value(0);

    if (bitTest(Yf,5))
        Yfeat3->value(2);
    else if (bitTest(Yf,2))
        Yfeat3->value(1);
    else
        Yfeat3->value(0);

    if (bitTest(Yf,6))
        Yfeat4->value(2);
    else if (bitTest(Yf,3))
        Yfeat4->value(1);
    else
        Yfeat4->value(0);} {}
  }
  Function {Show(SynthEngine *synth)} {} {
    code {//
    int fetchW, fetchH, fetchX, fetchY, fetchO;
    loadWin(synth, fetchW, fetchH, fetchX, fetchY, fetchO, "Vector");
    vectorwindow->show();
    if (fetchW < vecDW || fetchH < vecDH)
    {
        fetchW = vecDW;
        fetchH = vecDH;
    }
    checkSane(fetchX, fetchY, fetchW, fetchH, vecDW, vecDH, true);

    vectorwindow->resize(fetchX, fetchY, fetchW, fetchH);
    vectorSeen = true;
    lastvectorW = 0;} {}
  }
  Function {vectorRtext()} {} {
    code {//
    if (lastvectorW == vectorwindow->w())
        return;
    lastvectorW = vectorwindow->w();

    float dW = vectorwindow->w() / vecDW;
    float dH = vectorwindow->h() / vecDH;
    float dScale;
    if (dW < dH)
        dScale = dW;
    else
        dScale = dH;
    if (dScale < 0.2f)
        dScale = 0.2f;

    int size12 = int(dScale * 12);
    int size16 = int(dScale * 16);

    setbasechan->labelsize(size12);
    setbasechan->textsize(size12);
    options->labelsize(size12);
        options->textsize(size12);

    Xgroup->labelsize(size16);
    Xcontrol->labelsize(size12);
        Xcontrol->textsize(size12);
    XinstL->labelsize(size12);
    XinstR->labelsize(size12);
    Xfeat->labelsize(size12);
    Xfeat1->labelsize(size12);
         Xfeat1->textsize(size12);
    Xfeat2->labelsize(size12);
         Xfeat2->textsize(size12);
    Xfeat3->labelsize(size12);
         Xfeat3->textsize(size12);
    Xfeat4->labelsize(size12);
         Xfeat4->textsize(size12);

    Ygroup->labelsize(size16);
    Ycontrol->labelsize(size12);
        Ycontrol->textsize(size12);
    YinstU->labelsize(size12);
    YinstD->labelsize(size12);
    Yfeat->labelsize(size12);
    Yfeat1->labelsize(size12);
        Yfeat1->textsize(size12);
    Yfeat2->labelsize(size12);
        Yfeat2->textsize(size12);
    Yfeat3->labelsize(size12);
        Yfeat3->textsize(size12);
    Yfeat4->labelsize(size12);
        Yfeat4->textsize(size12);

    Loaded->labelsize(size12);
    Closevector->labelsize(size12);

    vectorwindow->redraw();} {}
  }
  Function {setInstrumentLabel(int vecPart)} {} {
    code {//
    if ((vecPart & 0xf) != BaseChan)
        return;
    int engines = findengines(vecPart);
    int addcol = setcolors(engines & 1);
    int subcol = setcolors(engines & 2);
    int padcol = setcolors(engines & 4);

    if (vecPart == BaseChan)
    {
        AddBackL->color(addcol);
        SubBackL->color(subcol);
        PadBackL->color(padcol);
        XinstL->copy_label(findnames(vecPart).c_str());
    }
    else if (vecPart == BaseChan + NUM_MIDI_CHANNELS)
    {
        AddBackR->color(addcol);
        SubBackR->color(subcol);
        PadBackR->color(padcol);
        XinstR->copy_label(findnames(vecPart).c_str());
    }
    else if (vecPart == BaseChan + NUM_MIDI_CHANNELS * 2)
    {
        AddBackU->color(addcol);
        SubBackU->color(subcol);
        PadBackU->color(padcol);
        YinstU->copy_label(findnames(vecPart).c_str());
    }
    else if (vecPart == BaseChan + NUM_MIDI_CHANNELS * 3)
    {
        AddBackD->color(addcol);
        SubBackD->color(subcol);
        PadBackD->color(padcol);
        YinstD->copy_label(findnames(vecPart).c_str());
    }
    vectorwindow->redraw();
    Loaded->copy_label(loadlabel[BaseChan].c_str());} {}
  }
  Function {setLoadLabelRemote(int chan, string name)} {} {
    code {//
    loadlabel[chan] = name;
    BaseChan = chan;
    setbasechan->value(BaseChan + 1);
    updateAll(false);} {}
  }
  Function {findnames(int vecPart)} {return_type string
  } {
    code {//
        return textMsgBuffer.fetch(collect_readData(synth, 0, PART::control::instrumentName, vecPart, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, TOPLEVEL::action::lowPrio));
        ;} {}
  }
  Function {findengines(int vecPart)} {return_type {unsigned int}
  } {
    code {//
        return collect_readData(synth, 0, PART::control::instrumentEngines, vecPart);
        ;} {}
  }
  Function {setcolors(int engine)} {return_type int
  } {
    code {//
    int col;
    switch(engine)
    {
        case 1:
            col = add_back;
            break;
        case 2:
            col = sub_back;
            break;
        case 4:
            col = pad_back;
            break;
        default:
            col = bank_back_used;
            break;
    }
    return col;} {}
  }
  Function {loadVector(string fname)} {} {
    code {//
    if (fname.empty())
    {
        fname = setfiler(synth,"", "", false, TOPLEVEL::XML::Vector);
        if (fname.empty())
            return;
    }
    send_data(TOPLEVEL::action::muteAndLoop | TOPLEVEL::action::forceUpdate, MAIN::loadNamedVector, 0, TOPLEVEL::type::Integer, TOPLEVEL::section::main, UNUSED, UNUSED, BaseChan, UNUSED, textMsgBuffer.push(fname));} {}
  }
  Function {saveVector()} {} {
    code {//
    string filename = setfiler(synth,"", "", true, TOPLEVEL::XML::Vector);
    if (filename.empty())
        return;
    int pos = loadlabel[BaseChan].find("No Name");
    if (pos >=0 && pos < 2)
        Loaded->copy_label(findLeafName(filename).c_str());
    send_data(TOPLEVEL::action::lowPrio, MAIN::saveNamedVector, 0, TOPLEVEL::type::Integer, TOPLEVEL::section::main, UNUSED, UNUSED, BaseChan, UNUSED, textMsgBuffer.push(filename));} {}
  }
  Function {clearVector(int BaseC)} {} {
    code {//
    int min = 0;
    int max = NUM_MIDI_CHANNELS;
    if (BaseC < NUM_MIDI_CHANNELS)
    {
        min = BaseC;
        max = BaseC + 1;
    }
    for (int i = min; i < max; ++i)
    {
        loadlabel[i] = "No Name " + to_string(i + 1);
        Loaded->copy_label(loadlabel[i].c_str());
     }
     if (BaseC >= NUM_MIDI_CHANNELS)
     {
         BaseChan = 0;
         setInstrumentLabel(0);
         setInstrumentLabel(NUM_MIDI_CHANNELS);
         setInstrumentLabel(NUM_MIDI_CHANNELS * 2);
         setInstrumentLabel(NUM_MIDI_CHANNELS * 3);
     }

     Xcc = 0;
     Xf = 0;
     Xgroup->deactivate();
     Xcontrol->value(0);
     Ycc = 0;
     Yf = 0;
     Ygroup->deactivate();
     Ycontrol->deactivate();
     Ycontrol->value(0);} {}
  }
  Function {checkParts(int nval)} {} {
    code {//
for (int i = 0; i < NUM_MIDI_CHANNELS; ++i)
{
    if (nval > NUM_MIDI_CHANNELS * 3)
        Ygroup->activate();
    else
        Ygroup->deactivate();

    if (nval > NUM_MIDI_CHANNELS)
        Xgroup->activate();
    else
        Xgroup->deactivate();
}} {}
  }
  Function {errorlabel(string msg)} {} {
    code {//
            synth->getGuiMaster()->words->copy_label(msg.c_str());
            synth->getGuiMaster()->message->show();
            synth->getGuiMaster()->message->position(Fl::event_x_root() + 16, Fl::event_y_root());} {}
  }
  decl {SynthEngine *synth;} {private local
  }
  decl {BankUI *bankui;} {private local
  }
  decl {ParametersUI *paramsui;} {private local
  }
  decl {int BaseChan;} {private local
  }
  decl {int Xcc;} {private local
  }
  decl {unsigned int Xf;} {private local
  }
  decl {int Ycc;} {private local
  }
  decl {unsigned int Yf;} {private local
  }
  decl {float vecDW;} {private local
  }
  decl {float vecDH;} {private local
  }
  decl {string loadlabel [NUM_MIDI_CHANNELS];} {private local
  }
  decl {bool vectorSeen;} {private local
  }
  decl {int lastvectorW;} {public local
  }
}
