| 
							- /*
 -   ZynAddSubFX - a software synthesizer
 - 
 -   BankView.cpp - View Of Bank Fields
 -   Copyright (C) 2016 Mark McCurry
 - 
 -   This program 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.
 - */
 - #include "BankView.h"
 - #include "../Misc/Util.h"
 - #include <FL/Fl.H>
 - #include <FL/Fl_Check_Button.H>
 - #include <FL/fl_ask.H>
 - #include <rtosc/rtosc.h>
 - #include <cstdio>
 - #include <cstring>
 - #include <cassert>
 - 
 - using namespace zyncarla;
 - 
 - BankList::BankList(int x,int y, int w, int h, const char *label)
 -     :Fl_Osc_Choice(x,y,w,h,label)
 - {}
 - 
 - void BankList::init(std::string path)
 - {
 -     ext = path;
 -     oscRegister("bank/bank_select");
 -     oscRegister(path.c_str());
 -     oscWrite("bank/banks", "");
 - }
 - 
 - void BankList::OSC_raw(const char *msg)
 - {
 -     if(!strcmp(msg, "/bank/bank_select") && !strcmp(rtosc_argument_string(msg),"iss")) {
 - 
 -         const int   pos  = rtosc_argument(msg, 0).i;
 -         const char *path = rtosc_argument(msg, 1).s;
 - 
 -         value(0);
 -         if(pos == 0)
 -             this->clear();
 - 
 -         if(pos <= this->size()-2)  {
 -             return;
 -         }
 -         this->add(path);
 -     }
 -     if(!strcmp(msg, "/bank/bank_select")&& !strcmp(rtosc_argument_string(msg),"i")) {
 -         int val = rtosc_argument(msg, 0).i;
 -         if(value() != val) {
 -             value(val);
 -             for(int i=0; i<160; ++i)
 -                 osc->write("/bank/slot"+to_s(i), "");
 -         }
 -     }
 - }
 - 
 - BankSlot::BankSlot(int x,int y, int w, int h, const char *label)
 - :Fl_Button(x,y,w,h,label), nslot(-1)
 - {
 -     memset(labelstr, 0, sizeof(labelstr));
 -     box(FL_THIN_UP_BOX);
 -     labelfont(0);
 -     labelsize(13);
 -     align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE|FL_ALIGN_CLIP);
 - }
 - 
 - int BankSlot::handle(int event)
 - {
 -     int what = 0;
 -     if (Fl::event_inside(this))
 -     {
 -         what=0;
 -         if ((event==FL_RELEASE)&&(Fl::event_button()==1))
 -             what=1;
 -         if ((event==FL_RELEASE)&&(Fl::event_button()==3))
 -             what=2;
 -     }
 - 
 -     int tmp=Fl_Button::handle(event);
 - 
 -     if (what && Fl::event_inside(this))
 -         bv->react(what, nslot);
 - 
 -     return tmp;
 - }
 - 
 - void BankSlot::init(int nslot_, BankView *bv_)
 - {
 -     nslot = nslot_;
 -     bv    = bv_;
 - 
 -     snprintf(labelstr, 127, "%d.", nslot_);
 -     label(labelstr);
 - }
 - 
 - void BankSlot::update(const char *name__, const char *fname__)
 - {
 -     name_     = name__;
 -     filename_ = fname__;
 -     snprintf(labelstr, 127, "%d. %s", nslot, name_.c_str());
 -     label(labelstr);
 -     
 -     if(name_.empty())
 -         label("");
 - 
 -     color(empty() ? 46 : 51);
 - #ifdef NTK_GUI
 -     redraw();
 - #endif
 - }
 - 
 - bool BankSlot::empty(void) const
 - {
 -     return filename_.empty();
 - }
 - 
 - const char *BankSlot::name(void) const
 - {
 -     return name_.c_str();
 - }
 - 
 - const char *BankSlot::filename(void) const
 - {
 -     return filename_.c_str();
 - }
 - 
 - /*
 -    void BankSlot::init(int nslot_, int *what_, int *whatslot_,void (BankProcess_:: *fnc_)(void),BankProcess_ *bp_,Bank *bank_,int *nselected_) {
 -    nslot=nslot_;
 -    what=what_;
 -    whatslot=whatslot_;
 -    fnc=fnc_;
 -    bp=bp_;
 - //bank=bank_;
 - nselected=nselected_;
 - box(FL_THIN_UP_BOX);
 - labelfont(0);
 - labelsize(13);
 - align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE|FL_ALIGN_CLIP);
 - 
 - highlight=0;
 - //refresh();
 - }
 - */
 - 
 - /*
 -    void BankSlot::refresh() {
 -    if (bank->emptyslot(nslot))
 -    color(46);
 -    else if (bank->isPADsynth_used(nslot))
 -    color(26);
 -    else
 -    color(51);
 - 
 - 
 -    if (*nselected==nslot)
 -    color(6);
 - 
 - 
 -    copy_label(bank->getnamenumbered(nslot).c_str());
 -    }
 -    */
 - static int modeCb(const char *label)
 - {
 -     if(!strcmp("Read", label))
 -         return 1;
 -     else if(!strcmp("Write", label))
 -         return 2;
 -     else if(!strcmp("Clear", label))
 -         return 3;
 -     else if(!strcmp("Swap", label))
 -         return 4;
 -     return -1;
 - }
 - 
 - static void modeButtonCb(Fl_Widget *w, void *v)
 - {
 -     BankViewControls *bvc = (BankViewControls*)v;
 -     bvc->mode(modeCb(w->label()));
 - }
 - 
 - BankViewControls::BankViewControls(int x, int y, int w, int h, const char *label)
 -     :Fl_Group(x,y,w,h,label)
 - {
 -     //Margin
 -     const int m = 10;
 -     //Width per elm
 -     const float W = w/4;
 - 
 -     read  = new Fl_Check_Button(x+m+0*W, y+m, W-2*m, h-2*m, "Read");
 -     write = new Fl_Check_Button(x+m+1*W, y+m, W-2*m, h-2*m, "Write");
 -     clear = new Fl_Check_Button(x+m+2*W, y+m, W-2*m, h-2*m, "Clear");
 -     swap  = new Fl_Check_Button(x+m+3*W, y+m, W-2*m, h-2*m, "Swap");
 -     read->box(FL_BORDER_BOX);
 -     write->box(FL_BORDER_BOX);
 -     clear->box(FL_BORDER_BOX);
 -     swap->box(FL_BORDER_BOX);
 -     read->callback(modeButtonCb, this);
 -     write->callback(modeButtonCb, this);
 -     clear->callback(modeButtonCb, this);
 -     swap->callback(modeButtonCb, this);
 -     mode(1);
 - }
 - 
 - int BankViewControls::mode(void) const
 - {
 -     return mode_;
 - }
 - 
 - void BankViewControls::mode(int m)
 - {
 -     mode_ = m;
 -     int M = m-1;
 -     assert(0 <= M && M <= 3);
 -     Fl_Button *buttons[4]{read, write, clear, swap};
 - 
 -     for(int i=0; i<4; ++i)
 -         buttons[i]->value(i==M);
 - }
 - 
 - 
 - BankView::BankView(int x,int y, int w, int h, const char *label)
 -     :Fl_Group(x,y,w,h,label), Fl_Osc_Widget(),
 -     bvc(NULL), slots{0}, nselected(-1), npart(0), cbwig_(0)
 - {}
 - 
 - 
 - BankView::~BankView(void)
 - {
 -     if(osc) {
 -        osc->removeLink("/bankview", this);
 -        osc->removeLink("/bank/search_results", this);
 -     }
 - }
 - 
 - void BankView::init(Fl_Osc_Interface *osc_, BankViewControls *bvc_, int *npart_)
 - {
 -     assert(osc_);
 - 
 -     osc = osc_;
 -     bvc = bvc_;
 -     npart = npart_;
 - 
 -     osc->createLink("/bankview", this);
 -     osc->createLink("/bank/search_results", this);
 - 
 -     //Element Size
 -     const float width  = w()/5.0;
 -     const float height = h()/32.0;
 - 
 -     //Offsets
 -     const int X = x();
 -     const int Y = y();
 - 
 -     begin();
 -     //Place All Slots
 -     for(int i=0; i<5; ++i)
 -         for(int j=0; j<32; ++j)
 -             slots[i*32 + j] =
 -                 new BankSlot(X + i*width, Y + j*height, width, height);
 - 
 -     end();
 - 
 -     //Initialize callbacks
 -     for(int i=0; i<160; ++i)
 -         slots[i]->init(i, this);
 - 
 -     //Create Slot Listeners
 -     for(int i=0; i<160; ++i)
 -         osc->createLink("/bank/slot"+to_s(i), this);
 -     //Request Values
 -     for(int i=0; i<160; ++i)
 -         osc->write("/bank/slot"+to_s(i), "");
 - }
 - 
 - /*
 -  * React to user input.
 -  * This consists of the events:
 -  * - Rename Slot (right click)
 -  * - Read From Slot
 -  * - Write To Slot
 -  * - Swap Slot First Selection
 -  * - Swap Slot Second Selction
 -  *
 -  *   TODO restore autoclose functionality
 -  */
 - void BankView::react(int event, int nslot)
 - {
 -     BankSlot &slot = *slots[nslot];
 -     const bool isempty = slot.empty();
 -     const int  mode    = bvc->mode();
 - 
 -     //Rename slot
 -     if (event==2 && !isempty && mode!=4) {
 -         if(const char *name=fl_input("Slot (instrument) name:", slot.name())) {
 -             osc->write("/bank/rename_slot", "is", nslot, name);
 -             osc->write("/bank/slot"+to_s(nslot), "");
 -         }
 -     }
 - 
 -     //Reads from slot
 -     if ((event==1)&&(mode==1) && !isempty){
 -         printf("Loading a part #%d with file '%s'\n", nslot, slot.filename());
 -         osc->write("/load-part", "iss", *npart, slot.filename(),
 -                 slot.name());
 -         osc->writeValue("/part"+to_s(*npart)+"/Pname", slot.name());
 -         if(cbwig_)
 -             cbwig_->do_callback();
 -     }
 - 
 -     //save(write) to slot
 -     if(event==1 && mode==2){
 -         if(isempty ||
 -            fl_choice("Overwrite the slot no. %d ?","No","Yes",NULL,nslot+1)) {
 -             osc->write("/bank/save_to_slot", "ii", *npart, nslot);
 -             osc->write("/bank/slot"+to_s(nslot), "");
 -         }
 -         bvc->mode(1);
 -     }
 - 
 - 
 -     //Clears the slot
 -     if(event==1 && mode==3) {
 -         if (!isempty &&
 -             fl_choice("Clear the slot no. %d ?","No","Yes",NULL, nslot+1)) {
 -             osc->write("/bank/clear_slot", "i", nslot);
 -             osc->write("/bank/slot"+to_s(nslot), "");
 -         }
 -         bvc->mode(1);
 -     }
 - 
 -     //Swap
 -     if(mode==4) {
 -         if(event==1 && nselected>=0){
 -             osc->write("/bank/swap_slots", "ii", nselected, nslot);
 -             osc->write("/bank/slot"+to_s(nslot), "");
 -             osc->write("/bank/slot"+to_s(nselected), "");
 -             nselected=-1;
 -         } else if(nselected<0 || event==2) {
 -             nselected=nslot;
 -         };
 -     };
 - }
 - 
 - void BankView::OSC_raw(const char *msg)
 - {
 -     if(!strcmp(msg, "/bank/search_results")) {
 - 	const char *ptr = rtosc_argument_string(msg);
 - 	int slot = 0;
 - 
 - 	while (ptr[0] == 's' && ptr[1] == 's') {
 - 		const char *bank = rtosc_argument(msg, 2*slot).s;
 - 		const char *fname = rtosc_argument(msg, 2*slot + 1).s;
 - 
 - 		/* store search results directly into slot */
 - 		slots[slot]->update(bank, fname);
 - 		if (++slot == 160)
 - 			break;
 - 		ptr += 2;
 - 	}
 - 	while (slot < 160)
 - 		slots[slot++]->update("", "");
 -     } else if(!strcmp(rtosc_argument_string(msg), "iss")) {
 -         int nslot         = rtosc_argument(msg,0).i;
 -         const char *name  = rtosc_argument(msg,1).s;
 -         const char *fname = rtosc_argument(msg,2).s;
 - 
 -         if(0 <= nslot && nslot < 160)
 -             slots[nslot]->update(name, fname);
 -     } else if(!strcmp(rtosc_argument_string(msg), "ss")) {
 -         while(*msg && !isdigit(*msg)) msg++;
 -         int nslot         = atoi(msg);
 -         const char *name  = rtosc_argument(msg,0).s;
 -         const char *fname = rtosc_argument(msg,1).s;
 - 
 -         if(0 <= nslot && nslot < 160)
 -             slots[nslot]->update(name, fname);
 -     }
 - }
 -         
 - void BankView::cbwig(Fl_Widget *w)
 - {
 -     cbwig_ = w;
 - }
 - 
 - void BankView::refresh(void)
 - {
 -     assert(osc);
 -     //Odd case during initialization
 -     if(!osc)
 -         return;
 - 
 -     for(int i=0; i<160; ++i)
 -         osc->write("/bank/slot"+to_s(i), "");
 - }
 
 
  |