# data file for the Fltk User Interface Designer (fluid)
version 1.0308
header_name {.h}
code_name {.cc}
comment {SubNoteUI.h} {not_in_source in_header
}

comment {SubNoteUI.cc} {in_source not_in_header
}

comment {Original ZynAddSubFX author Nasca Octavian Paul
Copyright (C) 2002-2005 Nasca Octavian Paul
Copyright 2009-2011, Alan Calvert
Copyright 2015-2024, 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 derivative of ZynAddSubFX original code

} {selected in_source in_header
}

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

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

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

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

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

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

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

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

decl {\#include "Params/SUBnoteParameters.h"} {public local
}

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

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

decl {\#include "Misc/SynthHelper.h"
    using synth::getDetune;} {private local
}

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

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

class SUBnoteharmonic {: {public Fl_Group}
} {
  Function {make_window()} {} {
    Fl_Window harmonic {
      xywh {800 500 50 300} type Double box NO_BOX hide resizable
      class Fl_Group
    } {
      Fl_Slider mag {
        callback {//
        int x = 0;
        if (Fl::event_button() != 3)
            x = lrint(o->value());
        else
        {
            if (n == 0)
                x = 127;
            o->value(x);
        }
        if (n == 0)
            o->selection_color(setSlider(o->value(),127));
        else
            o->selection_color(setSlider(o->value(),0));
        send_data(0, TOPLEVEL::insert::harmonicAmplitude, n, x, TOPLEVEL::type::Integer);}
        tooltip {Harmonic's magnitude} xywh {0 2 15 131} type {Vert Knob} box FLAT_BOX labelcolor 64 minimum 127 maximum 0 step 1 value 127
        code0 {o->setValueType(VC_SubHarmonicMagnitude); o->useCustomTip(true);}
        class mwheel_slider
      }
      Fl_Slider bw {
        callback {//
        int x = 64;
        if (Fl::event_button() != 3)
            x = 64 + lrint(o->value());
        else
            o->value(0);
        o->selection_color(setSlider(o->value(),0));
        send_data(0, TOPLEVEL::insert::harmonicBandwidth, n, x, TOPLEVEL::type::Integer);}
        tooltip {Harmonic's bandwidth multiplier} xywh {0 166 15 128} type {Vert Knob} box FLAT_BOX labelcolor 64 minimum 63 maximum -64 step 1
        code0 {o->setValueType(VC_SubBandwidthRel);}
        code1 {o->useCustomTip(true);}
        class mwheel_slider
      }
      Fl_Box h_dash {
        xywh {16 227 10 3} box FLAT_BOX color 39
        code0 {if (n+1==MAX_SUB_HARMONICS) o->hide();}
      }
      Fl_Box h_num {
        label 01
        xywh {0 142 15 15} labelfont 1 labelsize 12 labelcolor 64 align 16
        code0 {char tmp[12];snprintf(tmp,12,"%d",n+1);o->label(strdup(tmp));}
      }
    }
  }
  Function {SUBnoteharmonic(int x,int y, int w, int h, const char *label=0):Fl_Group(x,y,w,h,label)} {} {
    code {n=0;} {}
  }
  Function {send_data(int action, int insert, int control, float value, int type)} {} {
    code {//
        type |= TOPLEVEL::type::Write;
        collect_writeData(synth, value, action, type, control, npart, kititem, PART::engine::subSynth, insert);} {}
  }
  Function {init(SUBnoteParameters *pars_, int n_, int npart_, int kititem_)} {} {
    code {//
    pars=pars_;
    synth = & pars->getSynthEngine();
    n=n_;
    npart = npart_;
    kititem = kititem_;
    make_window();
    refresh();
    harmonic->show();
    end();} {}
  }
  Function {refresh()} {} {
    code {//
        unsigned char magVal = collect_readData(synth, 0, n, npart, kititem, PART::engine::subSynth, TOPLEVEL::insert::harmonicAmplitude);
        mag->value(magVal);
        if (n == 0)
            mag->selection_color(setSlider(magVal,127));
        else
            mag->selection_color(setSlider(magVal,0));

        unsigned char bwVal = collect_readData(synth, 0, n, npart, kititem, PART::engine::subSynth, TOPLEVEL::insert::harmonicBandwidth) - 64;
        bw->value(bwVal);
        bw->selection_color(setSlider(bwVal,0));
        ;} {}
  }
  Function {~SUBnoteharmonic()} {} {
    code {//
    harmonic->hide();
    hide();} {}
  }
  decl {SUBnoteParameters *pars;} {private local
  }
  decl {SynthEngine *synth;} {private local
  }
  decl {int n;} {private local
  }
  decl {int npart;} {private local
  }
  decl {int kititem;} {private local
  }
}

class SUBnoteUI {: {public PresetsUI_}
} {
  Function {make_window()} {} {
    comment {randompan MUST be placed after panwidth} {in_source in_header
    }
    Fl_Window SUBparameters {
      label {SUBsynth Parameters}
      callback {//
    if (subSeen)
        saveWin(synth,o->w(), SUBparameters->h(),o->x(), o->y(), false, "SubSynth");
    subSeen = false;
    o->hide();}
      xywh {463 28 735 470} type Double labelcolor 64 hide resizable
      code0 {o->copy_label(textMsgBuffer.fetch(collect_readData(synth, textMsgBuffer.push("SubSynth"), npart, TOPLEVEL::windowTitle, kititem)).c_str());}
      code1 {subDW = o->w();subDH=o->h();}
      code2 {SUBparameters->size_range(subDW, subDH, 0, 0, 0, 0, 1);}
    } {
      Fl_Scroll frame {
        xywh {5 140 435 326} type HORIZONTAL box THIN_UP_BOX when 1
      } {
        Fl_Pack harmonics {
          xywh {4 148 435 290} type HORIZONTAL resizable
          code0 {new Fl_Box(0,0,9,o->h());}
          code1 {for (int i=0;i<MAX_SUB_HARMONICS;i++){h[i]=new SUBnoteharmonic(0,0,20,o->h(),"");h[i]->init(pars, i, npart, kititem);}}
          code2 {new Fl_Box(0,0,3,o->h());}
        } {}
      }
      Fl_Box {} {
        xywh {10 6 205 60} box PLASTIC_UP_BOX color 223
      }
      Fl_Group ampgrp {
        xywh {5 5 215 135} box THIN_UP_FRAME labelfont 1 labelsize 11 labelcolor 64 align 17
      } {
        Fl_Dial vol {
          label Volume
          callback {//
          o->selection_color(setKnob(o->value(),96));

          send_data (0, SUBSYNTH::control::volume, o->value(), TOPLEVEL::type::Integer);}
          tooltip Volume xywh {22 22 29 29} box ROUND_UP_BOX labelsize 10 labelcolor 64 align 10 maximum 127 step 1
          code0 {o->setValueType(VC_InstrumentVolume);}
          class WidgetPDial
        }
        Fl_Dial vsns {
          label {Vel Sens}
          callback {//
          o->selection_color(setKnob(o->value(),90));
          send_data (0, SUBSYNTH::control::velocitySense, o->value(), TOPLEVEL::type::Integer);}
          tooltip {Velocity sensing} xywh {66 22 29 29} box ROUND_UP_BOX labelsize 10 labelcolor 64 maximum 127 step 1
          code0 {o->setValueType(VC_AmpVelocitySense);}
          class WidgetPDial
        }
        Fl_Dial pan {
          label Pan
          callback {//
          o->selection_color(setKnob(o->value(),64));
          send_data (0, SUBSYNTH::control::panning, o->value(), TOPLEVEL::type::Integer);}
          tooltip Panning xywh {118 22 29 29} box ROUND_UP_BOX labelsize 10 labelcolor 64 maximum 127 step 1
          code0 {o->setValueType(VC_PanningStd);}
          class WidgetPDial
        }
        Fl_Group ampenv {
          label {Yoshimi : SubSynth - Amplitude Envelope}
          xywh {10 65 205 70} box FLAT_BOX color 51 labelcolor 64 align 144
          code0 {o->init(pars->AmpEnvelope, npart, kititem, PART::engine::subSynth, 0);}
          class EnvelopeUI
        } {}
        Fl_Dial panwidth {
          label Width
          callback {//
          o->selection_color(setKnob(o->value(),63));
          send_data (0, SUBSYNTH::control::randomWidth, o->value(), TOPLEVEL::type::Integer);}
          tooltip {Random Width} xywh {178 22 29 29} box ROUND_UP_BOX labelsize 10 labelcolor 64 maximum 63 step 1 value 63
          code0 {o->setValueType(VC_PanningRandom);}
          class WidgetPDial
        }
        Fl_Check_Button randompan {
          label Rand
          callback {//
        int tmp = o->value();
        if (tmp == 0)
            panwidth->deactivate();
        else
            panwidth->activate();
        send_data(0, SUBSYNTH::control::enableRandomPan, tmp, TOPLEVEL::type::Integer);}
          tooltip {Enable random panning} xywh {155 31 15 15} down_box DOWN_BOX color 48 selection_color 64 labelsize 11 labelcolor 64 align 1
          class Fl_Check_Button2
        }
        Fl_Box {} {
          xywh {108 22 4 38} box THIN_DOWN_FRAME
        }
        Fl_Box ampLabel {
          label AMPLITUDE
          xywh {100 10 20 10} labelfont 1 labelsize 11 labelcolor 64
        }
      }
      Fl_Group freqsettingsui {
        label FREQUENCY
        xywh {440 5 290 135} box THIN_UP_FRAME labelfont 1 labelsize 11 labelcolor 64 align 17
      } {
        Fl_Group freqenvelopegroup {
          label {Yoshimi : SubSynth - Frequency Envelope}
          xywh {445 65 205 70} box FLAT_BOX color 51 align 144
          code0 {o->init(pars->FreqEnvelope, npart, kititem, PART::engine::subSynth, 1);}
          code1 {if (collect_readData(synth, 0, SUBSYNTH::control::enableFrequencyEnvelope, npart, kititem, PART::engine::subSynth) == 0) o->deactivate();}
          class EnvelopeUI
        } {}
        Fl_Check_Button freqee {
          label On
          callback {//
          if (o->value() == 0)
              freqenvelopegroup->deactivate();
          else
              freqenvelopegroup->activate();
          o->show();
          freqsettingsui->redraw();
          send_data (0, SUBSYNTH::control::enableFrequencyEnvelope, o->value(), TOPLEVEL::type::Integer);}
          xywh {445 67 34 12} down_box DOWN_BOX selection_color 64 labelfont 3 labelsize 10 labelcolor 226
          class Fl_Check_Button2
        }
        Fl_Text_Display octavetext {
          label Octave
          xywh {446 19 50 7} box NO_BOX labelfont 3 labelsize 10 labelcolor 226
        }
        Fl_Counter octave {
          callback {//
          send_data (0, SUBSYNTH::control::octave, o->value(), TOPLEVEL::type::Integer);}
          tooltip Octave xywh {445 18 52 15} type Simple selection_color 49 labelfont 3 labelsize 10 labelcolor 64 align 1 minimum -8 maximum 7 step 1 textfont 1 textsize 11 textcolor 64
        }
        Fl_Dial bend {
          label Bend
          callback {//
          o->selection_color(setKnob(o->value(),88));
          send_data(0, SUBSYNTH::control::pitchBendAdjustment, o->value(), TOPLEVEL::type::Integer);}
          tooltip {Pitch bend range scaling} xywh {500 21 20 20} box ROUND_UP_BOX labelsize 10 labelcolor 64 align 8 maximum 127 step 1
          code0 {o->setValueType(VC_PitchBend);}
          class WidgetPDial
        }
        Fl_Dial offset {
          label Offset
          callback {//
          o->selection_color(setKnob(o->value(),64));
          send_data(0, SUBSYNTH::control::pitchBendOffset, o->value(), TOPLEVEL::type::Integer);}
          tooltip {Offset of the frequency in Hz.} xywh {558 21 20 20} box ROUND_UP_BOX labelsize 10 labelcolor 64 align 8 maximum 127 step 1
          code0 {o->setValueType(VC_FreqOffsetHz);}
          class WidgetPDial
        }
        Fl_Check_Button hz440 {
          label 440Hz
          callback {//
          int x = (int) o->value();

          if (x == 0)
              fixedfreqetdial->deactivate();
          else
              fixedfreqetdial->activate();
          send_data (0, SUBSYNTH::control::baseFrequencyAs440Hz, x, TOPLEVEL::type::Integer);}
          tooltip {set the base frequency to 440Hz} xywh {620 24 48 15} down_box DOWN_BOX selection_color 64 labelfont 1 labelsize 10 labelcolor 64 align 24
          code0 {o->value(collect_readData(synth, 0, SUBSYNTH::control::baseFrequencyAs440Hz, npart, kititem, PART::engine::subSynth));}
          class Fl_Check_Button2
        }
        Fl_Dial fixedfreqetdial {
          label {Eq.T.}
          callback {//
          o->selection_color(setKnob(o->value(),0));
          send_data (0, SUBSYNTH::control::equalTemperVariation, o->value(), TOPLEVEL::type::Integer);}
          tooltip {How the frequency varies according to the keyboard (leftmost for fixed frequency)} xywh {675 21 20 20} box ROUND_UP_BOX labelsize 10 labelcolor 64 align 8 maximum 127 step 1
          code0 {o->setValueType(VC_FixedFreqET);}
          class WidgetPDial
        }
        Fl_Slider detune {
          callback {//
          o->selection_color(setSlider(o->value(),0));
          send_data (TOPLEVEL::action::forceUpdate, SUBSYNTH::control::detuneFrequency, o->value(), TOPLEVEL::type::Integer);}
          tooltip {Fine Detune (cents)} xywh {491 47 234 15} type {Horz Knob} box THIN_DOWN_BOX labelcolor 64 minimum -8192 maximum 8191 step 1
          code0 {o->selection_color(setSlider(o->value(),0));}
          class mwheel_slider_rev
        }
        Fl_Choice detunetype {
          label {Detune Type}
          callback {//

          send_data (TOPLEVEL::action::forceUpdate, SUBSYNTH::control::detuneType, o->value() + 1, TOPLEVEL::type::Integer);}
          xywh {655 78 70 15} down_box BORDER_BOX selection_color 64 labelsize 10 labelcolor 64 align 5 textfont 1 textsize 10 textcolor 64
          code0 {o->add("L35cents");o->add("L10cents");o->add("E100cents");o->add("E1200cents");}
        } {}
        Fl_Counter coarsedet {
          label {Coarse Det.}
          callback {//
          int k = (int) o->value();
          if (k < 0)
              k += 1024;

          send_data (0, SUBSYNTH::control::coarseDetune, k, TOPLEVEL::type::Integer);}
          tooltip {Coarse Detune} xywh {654 111 74 15} selection_color 64 labelsize 10 labelcolor 64 align 1 minimum -64 maximum 63 step 1 textfont 1 textsize 11 textcolor 64
          code0 {o->lstep(10);}
        }
      }
      Fl_Value_Output detunevalueoutput {
        label Detune
        callback {//
              o->value(getDetune(detunetype->value()+1,0, detune->value()+8192));
              ;}
        xywh {445 47 45 15} labelsize 10 labelcolor 64 align 5 minimum -5000 maximum 5000 textfont 1 textsize 10 textcolor 64
        code0 {o->step(0.01, 1);}
      }
      Fl_Box {} {
        xywh {440 406 65 35} box THIN_UP_FRAME
      }
      Fl_Group bandwidthsettingsui {
        label BANDWIDTH
        xywh {220 5 220 135} box THIN_UP_FRAME labelfont 1 labelsize 11 labelcolor 64 align 17
      } {
        Fl_Group bandwidthenvelopegroup {
          label {Yoshimi : SubSynth - BandWidth Envelope}
          xywh {225 65 210 70} box FLAT_BOX color 51 align 144
          code0 {o->init(pars->BandWidthEnvelope, npart, kititem, PART::engine::subSynth, 3);}
          code1 {if (collect_readData(synth, 0, SUBSYNTH::control::enableBandwidthEnvelope, npart, kititem, PART::engine::subSynth)==0) o->deactivate();}
          class EnvelopeUI
        } {}
        Fl_Check_Button bwee {
          label On
          callback {//
          if (o->value() == 0)
              bandwidthenvelopegroup->deactivate();
          else
              bandwidthenvelopegroup->activate();
          o->show();
          bandwidthsettingsui->redraw();
          send_data (0, SUBSYNTH::control::enableBandwidthEnvelope, o->value(), TOPLEVEL::type::Integer);}
          xywh {225 67 34 12} down_box DOWN_BOX selection_color 64 labelfont 3 labelsize 10 labelcolor 226
          class Fl_Check_Button2
        }
        Fl_Value_Slider bandwidth {
          label Bandwidth
          callback {//
          o->selection_color(setSlider(o->value(),40));
          send_data (0, SUBSYNTH::control::bandwidth, o->value(), TOPLEVEL::type::Integer);}
          tooltip {Base bandwidth, approximate} xywh {225 40 115 15} type {Horz Knob} box THIN_DOWN_BOX labelsize 10 labelcolor 64 align 1 maximum 127 step 1 textcolor 64
          code0 {o->setValueType(VC_SubBandwidth);}
          code1 {o->useCustomTip(true);}
          class mwheel_slider_rev
        }
        Fl_Value_Slider bwidthscale {
          label {Bandwidth Scale}
          callback {//
          o->selection_color(setSlider(o->value(),0));
          send_data (0, SUBSYNTH::control::bandwidthScale, o->value(), TOPLEVEL::type::Integer);}
          tooltip {Freq-dep. bw. scaling} xywh {344 40 90 15} type {Horz Knob} box THIN_DOWN_BOX labelsize 10 labelcolor 64 align 1 minimum -64 maximum 63 step 1 textcolor 64
          code0 {o->setValueType(VC_SubBandwidthScale); o->setGraphicsType(VC_SubBandwidthScale);}
          code1 {o->useCustomTip(true);}
          class mwheel_slider_rev
        }
      }
      Fl_Group spreadGroup {
        label OVERTONES
        xywh {440 140 290 81} box THIN_UP_FRAME labelfont 1 labelsize 11 labelcolor 64 align 17
      } {
        Fl_Dial spreadpar1 {
          label Par1
          callback {//
          o->selection_color(setKnob(o->value(),0));
          send_data (TOPLEVEL::action::forceUpdate, SUBSYNTH::control::overtoneParameter1, o->value(), TOPLEVEL::type::Integer);}
          xywh {570 166 30 30} box ROUND_UP_BOX labelsize 10 labelcolor 64 maximum 255 step 1
          class WidgetPDial
        }
        Fl_Dial spreadpar2 {
          label Par2
          callback {//
          o->selection_color(setKnob(o->value(),0));
          send_data (0, SUBSYNTH::control::overtoneParameter2, o->value(), TOPLEVEL::type::Integer);}
          xywh {625 166 30 30} box ROUND_UP_BOX labelsize 10 labelcolor 64 maximum 255 step 1
          class WidgetPDial
        }
        Fl_Dial spreadpar3 {
          label ForceH
          callback {//
          o->selection_color(setKnob(o->value(),0));
          send_data (0, SUBSYNTH::control::overtoneForceHarmonics, o->value(), TOPLEVEL::type::Integer);}
          tooltip {Move towards closest harmonic} xywh {680 166 30 30} box ROUND_UP_BOX labelsize 10 labelcolor 64 maximum 255 step 1
          code0 {o->setValueType(VC_percent255);}
          class WidgetPDial
        }
      }
      Fl_Choice spreadtype {
        label {Overtone Positions}
        callback {//
          send_data (TOPLEVEL::action::forceUpdate, SUBSYNTH::control::overtonePosition, o->value(), TOPLEVEL::type::Integer);}
        xywh {460 171 87 20} down_box BORDER_BOX selection_color 64 labelsize 11 labelcolor 64 align 2 textfont 1 textsize 11 textcolor 64
        code0 {o->add("Harmonic");o->add("ShiftU");o->add("ShiftL");o->add("PowerU");o->add("PowerL");o->add("Sine");o->add("Power");o->add("Shift");}
      } {}
      Fl_Group globalfiltergroup {
        label { FILTER }
        xywh {440 221 290 185} box THIN_UP_FRAME labelfont 1 labelsize 11 labelcolor 64 align 17
        code0 {if (collect_readData(synth, 0, SUBSYNTH::control::enableFilter, npart, kititem, PART::engine::subSynth)==0) o->deactivate();}
      } {
        Fl_Group filterenv {
          label {Yoshimi : SubSynth - Filter Envelope}
          xywh {447 328 275 70} box FLAT_BOX color 51 align 144
          code0 {o->init(pars->GlobalFilterEnvelope, npart, kititem, PART::engine::subSynth, 2);}
          class EnvelopeUI
        } {}
        Fl_Group filterui {
          label {Yoshimi : SubSynth - Filter}
          xywh {447 246 275 75} box FLAT_BOX color 50 align 144
          code0 {o->init(pars->GlobalFilter,&pars->PGlobalFilterVelocityScale,&pars->PGlobalFilterVelocityScaleFunction, npart, kititem, 1);}
          class FilterUI
        } {}
      }
      Fl_Check_Button filtere {
        label On
        callback {//
        if (o->value() == 0)
            globalfiltergroup->deactivate();
        else
            globalfiltergroup->activate();
        o->show();
        globalfiltergroup->redraw();
        send_data (0, SUBSYNTH::control::enableFilter, o->value(), TOPLEVEL::type::Integer);}
        xywh {446 227 36 13} down_box DOWN_BOX selection_color 64 labelfont 3 labelsize 10 labelcolor 226
        class Fl_Check_Button2
      }
      Fl_Group {} {
        xywh {504 406 226 35} box THIN_UP_FRAME
      } {
        Fl_Counter filterstages {
          label {Filter Stages}
          callback {//
          send_data (0, SUBSYNTH::control::filterStages, o->value(), TOPLEVEL::type::Integer);}
          tooltip {How many times the noise is filtered} xywh {513 421 66 15} type Simple selection_color 64 labelfont 1 labelsize 10 labelcolor 64 align 1 minimum 1 maximum 5 step 1 value 1 textsize 10 textcolor 64
        }
        Fl_Choice magtype {
          label {Mag.Type}
          callback {//
          send_data (0, SUBSYNTH::control::magType, o->value(), TOPLEVEL::type::Integer);}
          xywh {590 421 65 15} down_box BORDER_BOX selection_color 64 labelfont 1 labelsize 10 labelcolor 64 align 1 textfont 1 textsize 11 textcolor 64
          code0 {o->add("Linear");o->add("-40dB");o->add("-60dB");o->add("-80dB");o->add("-100dB");}
        } {}
        Fl_Choice start {
          label Start
          callback {//
          send_data (0, SUBSYNTH::control::startPosition, o->value(), TOPLEVEL::type::Integer);}
          xywh {670 421 50 15} down_box BORDER_BOX selection_color 64 labelfont 1 labelsize 10 labelcolor 64 align 1 textfont 1 textsize 11 textcolor 64
          code0 {o->add("Zero");o->add("Rnd");o->add("Max.");}
        } {}
      }
      Fl_Check_Button stereo {
        label { Stereo}
        callback {//
        send_data (0, SUBSYNTH::control::stereo, o->value(), TOPLEVEL::type::Integer);}
        xywh {442 415 59 15} down_box DOWN_BOX selection_color 64 labelfont 3 labelsize 10 labelcolor 226
        class Fl_Check_Button2
      }
      Fl_Button subClear {
        label Clear
        callback {//
        send_data (TOPLEVEL::action::forceUpdate, SUBSYNTH::control::clearHarmonics, o->value(), TOPLEVEL::type::Integer);}
        tooltip {Clear the harmonics} xywh {445 446 70 20} box PLASTIC_UP_BOX color 228 labelfont 1 labelsize 11 labelcolor 64
      }
      Fl_Button subCopy {
        label C
        callback {//
        synth->getGuiMaster()->getPresetsUi()->Ucopy(npart, kititem, PART::engine::subSynth);}
        xywh {540 449 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 11 labelcolor 197
      }
      Fl_Button subPaste {
        label P
        callback {//
        synth->getGuiMaster()->getPresetsUi()->Upaste(npart, kititem, PART::engine::subSynth);}
        xywh {576 449 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 11 labelcolor 197
      }
      Fl_Button subClose {
        label &Close
        callback {//
        saveWin(synth, SUBparameters->w(), SUBparameters->h(), SUBparameters->x(), SUBparameters->y(), false, "SubSynth");
        subSeen = false;
        SUBparameters->hide();
        if ((Fl::event_button() == 3))
        {
            if (synth->getGuiMaster()->partui->partKitOn)
                synth->getGuiMaster()->partui->instrumentkitlist->show();
            else
                synth->getGuiMaster()->partui->instrumenteditwindow->show();
        }}
        tooltip {Right click: also reopen previous} xywh {625 446 105 20} box THIN_UP_BOX color 196 labelfont 1 labelsize 11 labelcolor 64
      }
    }
  }
  Function {refresh()} {} {
    code {//
    for (int i = 0; i < MAX_SUB_HARMONICS; ++i)
        h[i]->refresh();
    vol->value(collect_readData(synth, 0, SUBSYNTH::control::volume, npart, kititem, PART::engine::subSynth));
        vol->selection_color(setKnob(vol->value(),96));
    vsns->value(collect_readData(synth, 0, SUBSYNTH::control::velocitySense, npart, kititem, PART::engine::subSynth));
        vsns->selection_color(setKnob(vsns->value(),90));
    pan->value(collect_readData(synth, 0, SUBSYNTH::control::panning, npart, kititem, PART::engine::subSynth));
        pan->selection_color(setKnob(pan->value(),64));
    randompan->value(collect_readData(synth, 0, SUBSYNTH::control::enableRandomPan, npart, kititem, PART::engine::subSynth));
    if (randompan->value() == 0)
        panwidth->deactivate();
    else
        panwidth->activate();
    panwidth->value(collect_readData(synth, 0, SUBSYNTH::control::randomWidth, npart, kititem, PART::engine::subSynth));
        panwidth->selection_color(setKnob(panwidth->value(),63));

    bandwidth->value(collect_readData(synth, 0, SUBSYNTH::control::bandwidth, npart, kititem, PART::engine::subSynth));
        bandwidth->selection_color(setSlider(bandwidth->value(),40));
    bwidthscale->value(collect_readData(synth, 0, SUBSYNTH::control::bandwidthScale, npart, kititem, PART::engine::subSynth));
        bwidthscale->selection_color(setSlider(bwidthscale->value(),0));
    bwee->value(collect_readData(synth, 0, SUBSYNTH::control::enableBandwidthEnvelope, npart, kititem, PART::engine::subSynth));
    if (bwee->value() == 0)
        bandwidthenvelopegroup->deactivate();
    else
        bandwidthenvelopegroup->activate();
    bwee->show();
    bandwidthsettingsui->redraw();

    bend->value(collect_readData(synth, 0, SUBSYNTH::control::pitchBendAdjustment, npart, kititem, PART::engine::subSynth));
        bend->selection_color(setKnob(bend->value(),88));
    offset->value(collect_readData(synth, 0, SUBSYNTH::control::pitchBendOffset, npart, kititem, PART::engine::subSynth));
        offset->selection_color(setKnob(offset->value(),64));
    hz440->value(collect_readData(synth, 0, SUBSYNTH::control::baseFrequencyAs440Hz, npart, kititem, PART::engine::subSynth));
    if (hz440->value() == 0)
        fixedfreqetdial->deactivate();
    else
        fixedfreqetdial->activate();
    fixedfreqetdial->value(collect_readData(synth, 0, SUBSYNTH::control::equalTemperVariation, npart, kititem, PART::engine::subSynth));
        fixedfreqetdial->selection_color(setKnob(fixedfreqetdial->value(),0));

    freqee->value(collect_readData(synth, 0, SUBSYNTH::control::enableFrequencyEnvelope, npart, kititem, PART::engine::subSynth));
    if (freqee->value() == 0)
        freqenvelopegroup->deactivate();
    else
        freqenvelopegroup->activate();
    freqee->show();
    freqsettingsui->redraw();

    octave->value(collect_readData(synth, 0, SUBSYNTH::control::octave, npart, kititem, PART::engine::subSynth));

    int detVal = collect_readData(synth, 0, SUBSYNTH::control::detuneFrequency, npart, kititem, PART::engine::subSynth);
    detune->value(detVal);
        detune->selection_color(setSlider(detVal,0));

    int detType = collect_readData(synth, 0, SUBSYNTH::control::detuneType, npart, kititem, PART::engine::subSynth);
    detunetype->value(detType - 1);

    coarsedet->value(collect_readData(synth, 0, SUBSYNTH::control::coarseDetune, npart, kititem, PART::engine::subSynth));
    detunevalueoutput->value(getDetune(detType,0,detVal+8192));

    spreadtype->value(collect_readData(synth, 0, SUBSYNTH::control::overtonePosition, npart, kititem, PART::engine::subSynth));
    if (spreadtype->value() > 0)
    {
        spreadGroup->activate();
    }
    else
    {
        spreadGroup->deactivate();
    }
    spreadpar1->value(collect_readData(synth, 0, SUBSYNTH::control::overtoneParameter1, npart, kititem, PART::engine::subSynth));
        spreadpar1->selection_color(setKnob(spreadpar1->value(),0));
    spreadpar2->value(collect_readData(synth, 0, SUBSYNTH::control::overtoneParameter2, npart, kititem, PART::engine::subSynth));
        spreadpar2->selection_color(setKnob(spreadpar1->value(),0));
    spreadpar3->value(collect_readData(synth, 0, SUBSYNTH::control::overtoneForceHarmonics, npart, kititem, PART::engine::subSynth));
        spreadpar3->selection_color(setKnob(spreadpar1->value(),0));

    filtere->value(collect_readData(synth, 0, SUBSYNTH::control::enableFilter, npart, kititem, PART::engine::subSynth));
    if (filtere->value() == 0)
        globalfiltergroup->deactivate();
    else
        globalfiltergroup->activate();
    filtere->show();
    globalfiltergroup->redraw();

    filterstages->value(collect_readData(synth, 0, SUBSYNTH::control::filterStages, npart, kititem, PART::engine::subSynth));
    magtype->value(collect_readData(synth, 0, SUBSYNTH::control::magType, npart, kititem, PART::engine::subSynth));
    start->value(collect_readData(synth, 0, SUBSYNTH::control::startPosition, npart, kititem, PART::engine::subSynth));

    stereo->value(collect_readData(synth, 0, SUBSYNTH::control::stereo, npart, kititem, PART::engine::subSynth));

    ampenv->refresh();
    bandwidthenvelopegroup->refresh();
    freqenvelopegroup->refresh();
    filterui->refresh();
    filterenv->refresh();} {}
  }
  Function {Showsub()} {} {
    code {//
    int fetchW, fetchH, fetchX, fetchY, fetchO;
    loadWin(synth, fetchW, fetchH, fetchX, fetchY, fetchO, "SubSynth");
    if (fetchW < subDW || fetchH < subDH)
    {
        fetchW = subDW;
        fetchH = subDH;
    }
    checkSane(fetchX, fetchY, fetchW, fetchH, subDW, subDH);

    SUBparameters->resize(fetchX, fetchY, fetchW, fetchH);
    SUBparameters->show();
    lastsubW = 0;
    subSeen = true;} {}
  }
  Function {subRtext()} {} {
    code {//
    ampenv->wincheck();
    bandwidthenvelopegroup->wincheck();
    filterenv->wincheck();
    freqenvelopegroup->wincheck();

    if (filterui->formantparswindow->visible())
        filterui->formantRtext();

    if (!SUBparameters->visible())
        return;

    if(SUBparameters->w() == lastsubW)
         return;

    lastsubW = SUBparameters->w();

    float dScale = SUBparameters->w() / float(subDW);
    if (dScale < 0.2f)
        dScale = 0.2f;

    ampenv->envRtext(dScale);
    bandwidthenvelopegroup->envRtext(dScale);
    filterenv->envRtext(dScale);
    freqenvelopegroup->envRtext(dScale);

    filterui->filterRtext(dScale);

    int size = int(10 * dScale);
    int size11 = int(11 * dScale);
    frame->scroll_to(0, 0);
    frame->size(int(435 * dScale), int(326 * dScale));
    frame->scrollbar_size(12 * dScale);
    harmonics->size(int(435 * dScale), int(275 * dScale * 1.1));

    for (int i=0;i<MAX_SUB_HARMONICS;i++)
    {
        h[i]->size(20 * dScale, 275 * dScale * 1.1);
        h[i]->h_num->labelsize(int(12 * dScale));
        h[i]->h_dash->size(int(10 * dScale), int(3 * dScale));
    }

    ampLabel->labelsize(size11);
    vol->labelsize(size);
    vsns->labelsize(size);
    pan->labelsize(size);
    panwidth->labelsize(size);
    randompan->labelsize(size11);

    freqsettingsui->labelsize(size11);
    freqee->labelsize(size);
    octavetext->labelsize(size);
        octave->textsize(size11);
    bend->labelsize(size);
    offset->labelsize(size);
    hz440->labelsize(size);
    fixedfreqetdial->labelsize(size);
    detunevalueoutput->labelsize(size);
        detunevalueoutput->textsize(size);
    detunetype->labelsize(size);
        detunetype->textsize(size);
    coarsedet->labelsize(size);
        coarsedet->textsize(size11);

    bandwidthsettingsui->labelsize(size11);
    bwee->labelsize(size);
    bandwidth->labelsize(size);
         bandwidth->textsize(size);
    bwidthscale->labelsize(size);
        bwidthscale->textsize(size);

    spreadGroup->labelsize(size11);
    spreadpar1->labelsize(size);
    spreadpar2->labelsize(size);
    spreadpar3->labelsize(size);
    spreadtype->labelsize(size11);
        spreadtype->textsize(size11);

    globalfiltergroup->labelsize(size11);
    filtere->labelsize(size);
    filterstages->labelsize(size);
        filterstages->textsize(size11);
    magtype->labelsize(size);
        magtype->textsize(size11);
    start->labelsize(size);
        start->textsize(size11);

    stereo->labelsize(size);
    subClear->labelsize(size11);
    subCopy->labelsize(size11);
    subPaste->labelsize(size11);
    subClose->labelsize(size11);

    SUBparameters->redraw();} {}
  }
  Function {theme()} {} {
    code {//
        if(SUBparameters->visible())
        {
            lastsubW = 0;
            subRtext();
        }
        ampenv->theme();
        freqenvelopegroup->theme();
        filterenv->theme();
        bandwidthenvelopegroup->theme();
        if (filterui->formantparswindow->visible())
            filterui->theme();
        ;} {}
  }
  Function {send_data(int action, int control, float value, int type)} {} {
    code {//
        type |= TOPLEVEL::type::Write;
        collect_writeData(synth, value, action, type, control, npart, kititem, 1);} {}
  }
  Function {returns_update(CommandBlock *getData)} {} {
    code {//
    float value = getData->data.value;
    unsigned char control = getData->data.control;
    unsigned char insert = getData->data.insert;
    bool val_bool = _SYS_::F2B(value);
    int value_int = int(value);
    if (insert == TOPLEVEL::insert::harmonicAmplitude)
    {
        h[control]->mag->value(value_int);
        int temp = 127;
        if (control > 0)
            temp = 0;
        h[control]->mag->selection_color(setSlider(value_int,temp));
        return;
    }
    if (insert == TOPLEVEL::insert::harmonicBandwidth)
    {
        h[control]->bw->value(value_int - 64);
        h[control]->bw->selection_color(setSlider(value_int,64));
        return;
    }

    switch(control)
    {
        case SUBSYNTH::control::volume:
            vol->value(value);
            vol->selection_color(setKnob(value,96));

            break;

        case SUBSYNTH::control::velocitySense:
            vsns->value(value);
            vsns->selection_color(setKnob(value,90));

            break;

        case SUBSYNTH::control::panning:
            pan->value(value);
            pan->selection_color(setKnob(value,64));
            break;
        case SUBSYNTH::control::enableRandomPan:
            randompan->value(val_bool);
            if (val_bool)
                panwidth->activate();
            else
                panwidth->deactivate();
            break;
        case SUBSYNTH::control::randomWidth:
            panwidth->value(value);
            panwidth->selection_color(setKnob(value,63));
            break;

        case SUBSYNTH::control::bandwidth:
            bandwidth->value(value);
            bandwidth->selection_color(setSlider(value,40));
            break;

        case SUBSYNTH::control::bandwidthScale:
            bwidthscale->value(value);
            bwidthscale->selection_color(setSlider(value,0));
            break;

        case SUBSYNTH::control::enableBandwidthEnvelope:
            bwee->value(val_bool);
            if (val_bool)
                bandwidthenvelopegroup->activate();
            else
                bandwidthenvelopegroup->deactivate();
            bwee->show();
            break;

        case SUBSYNTH::control::detuneFrequency:
            detune->value(value);
            detune->selection_color(setSlider(value,0));
            detunevalueoutput->do_callback();
            break;

        case SUBSYNTH::control::equalTemperVariation:
            fixedfreqetdial->value(value);
            fixedfreqetdial->selection_color(setKnob(value,0));
            break;

        case SUBSYNTH::control::baseFrequencyAs440Hz:
            hz440->value(_SYS_::F2B(value));
            if (value == 0)
                fixedfreqetdial->deactivate();
            else
                fixedfreqetdial->activate();
            break;

        case SUBSYNTH::control::octave:
            octave->value(lrint(value));
            break;

        case SUBSYNTH::control::detuneType:
            detunetype->value(value - 1);
            break;

        case SUBSYNTH::control::coarseDetune:
            coarsedet->value(value);
            break;

        case SUBSYNTH::control::pitchBendAdjustment:
            bend->value(value);
            bend->selection_color(setKnob(value,88));
            break;

        case SUBSYNTH::control::pitchBendOffset:
            offset->value(value);
            offset->selection_color(setKnob(value,64));
            break;

        case SUBSYNTH::control::enableFrequencyEnvelope:
            freqee->value(value);
            if (val_bool)
                freqenvelopegroup->activate();
            else
                freqenvelopegroup->deactivate();
            freqee->show();
            break;

        case SUBSYNTH::control::overtoneParameter1:
            spreadpar1->value((unsigned int) value);
            spreadpar1->selection_color(setKnob(value,0));
            break;

        case SUBSYNTH::control::overtoneParameter2:
            spreadpar2->value((unsigned int) value);
            spreadpar2->selection_color(setKnob(value,0));
            break;

        case SUBSYNTH::control::overtoneForceHarmonics:
            spreadpar3->value((unsigned int) value);
            spreadpar3->selection_color(setKnob(value,0));
            break;

        case SUBSYNTH::control::overtonePosition:
            spreadtype->value((int) value);
            if (spreadtype->value() > 0)
            {
                spreadGroup->activate();
                if (spreadtype->value() < 7)
                    spreadpar2->activate();
                else
                    spreadpar2->deactivate();
            }
            else
                spreadGroup->deactivate();
            break;

        case SUBSYNTH::control::enableFilter:
            filtere->value(val_bool);
            if (val_bool)
                globalfiltergroup->activate();
            else
                globalfiltergroup->deactivate();
            globalfiltergroup->redraw();
            break;

        case SUBSYNTH::control::filterStages:
            filterstages->value((int) value);
            break;
        case SUBSYNTH::control::magType:
            magtype->value((int) value);
            break;

        case SUBSYNTH::control::startPosition:
            start->value((int) value);
            break;

        case SUBSYNTH::control::clearHarmonics:
            for (int i = 0; i < MAX_SUB_HARMONICS; i++)
            {
                if (i == 0)
                {
                    h[i]->mag->value(127);
                    h[i]->mag->selection_color(setSlider(127,127));
                }
                else
                {
                    h[i]->mag->value(0);
                    h[i]->mag->selection_color(setSlider(0,0));
                }
                h[i]->bw->value(0);
                h[i]->bw->selection_color(setSlider(64,64));
            }

            break;

        case SUBSYNTH::control::stereo:
            stereo->value(val_bool);
            break;
    }} {}
  }
  Function {SUBnoteUI(SUBnoteParameters *parameters, int npart_, int kititem_)} {} {
    code {//
    pars = parameters;
    synth = & pars->getSynthEngine();
    npart = npart_;
    kititem = kititem_;
    lastsubW = 0;
    subSeen = false;
    make_window();
    refresh();} {}
  }
  Function {~SUBnoteUI()} {return_type virtual
  } {
    code {//
    if (subSeen)
        saveWin(synth, SUBparameters->w(), SUBparameters->h(), SUBparameters->x(), SUBparameters->y(),  true, "SubSynth");
    subSeen = false;
    SUBparameters->hide();
    delete(SUBparameters);} {}
  }
  decl {SUBnoteParameters *pars;} {private local
  }
  decl {SUBnoteharmonic *h[MAX_SUB_HARMONICS];} {private local
  }
  decl {SynthEngine *synth;} {private local
  }
  decl {int npart;} {private local
  }
  decl {int kititem;} {private local
  }
  decl {float subDW;} {private local
  }
  decl {float subDH;} {private local
  }
  decl {bool subSeen;} {private local
  }
  decl {int lastsubW;} {private local
  }
}
