LMMS
Loading...
Searching...
No Matches
BankView.cpp
Go to the documentation of this file.
1/*
2 ZynAddSubFX - a software synthesizer
3
4 BankView.cpp - View Of Bank Fields
5 Copyright (C) 2016 Mark McCurry
6
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; either version 2
10 of the License, or (at your option) any later version.
11*/
12#include "BankView.h"
13#include "../Misc/Util.h"
14#include <FL/Fl.H>
15#include <FL/Fl_Check_Button.H>
16#include <FL/fl_ask.H>
17#include <rtosc/rtosc.h>
18#include <cstdio>
19#include <cstring>
20#include <cassert>
21
22using namespace zyncarla;
23
24BankList::BankList(int x,int y, int w, int h, const char *label)
25 :Fl_Osc_Choice(x,y,w,h,label)
26{}
27
28void BankList::init(std::string path)
29{
30 ext = path;
31 oscRegister("bank/bank_select");
32 oscRegister(path.c_str());
33 oscWrite("bank/banks", "");
34}
35
36void BankList::OSC_raw(const char *msg)
37{
38 if(!strcmp(msg, "/bank/bank_select") && !strcmp(rtosc_argument_string(msg),"iss")) {
39
40 const int pos = rtosc_argument(msg, 0).i;
41 const char *path = rtosc_argument(msg, 1).s;
42
43 value(0);
44 if(pos == 0)
45 this->clear();
46
47 if(pos <= this->size()-2) {
48 return;
49 }
50 this->add(path);
51 }
52 if(!strcmp(msg, "/bank/bank_select")&& !strcmp(rtosc_argument_string(msg),"i")) {
53 int val = rtosc_argument(msg, 0).i;
54 if(value() != val) {
55 value(val);
56 for(int i=0; i<160; ++i)
57 osc->write("/bank/slot"+to_s(i), "");
58 }
59 }
60}
61
62BankSlot::BankSlot(int x,int y, int w, int h, const char *label)
63:Fl_Button(x,y,w,h,label), nslot(-1)
64{
65 memset(labelstr, 0, sizeof(labelstr));
66 box(FL_THIN_UP_BOX);
67 labelfont(0);
68 labelsize(13);
69 align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE|FL_ALIGN_CLIP);
70}
71
72int BankSlot::handle(int event)
73{
74 int what = 0;
75 if (Fl::event_inside(this))
76 {
77 what=0;
78 if ((event==FL_RELEASE)&&(Fl::event_button()==1))
79 what=1;
80 if ((event==FL_RELEASE)&&(Fl::event_button()==3))
81 what=2;
82 }
83
84 int tmp=Fl_Button::handle(event);
85
86 if (what && Fl::event_inside(this))
87 bv->react(what, nslot);
88
89 return tmp;
90}
91
92void BankSlot::init(int nslot_, BankView *bv_)
93{
94 nslot = nslot_;
95 bv = bv_;
96
97 snprintf(labelstr, 127, "%d.", nslot_);
98 label(labelstr);
99}
100
101void BankSlot::update(const char *name__, const char *fname__)
102{
103 name_ = name__;
104 filename_ = fname__;
105 snprintf(labelstr, 127, "%d. %s", nslot, name_.c_str());
106 label(labelstr);
107
108 if(name_.empty())
109 label("");
110
111 color(empty() ? 46 : 51);
112#ifdef NTK_GUI
113 redraw();
114#endif
115}
116
117bool BankSlot::empty(void) const
118{
119 return filename_.empty();
120}
121
122const char *BankSlot::name(void) const
123{
124 return name_.c_str();
125}
126
127const char *BankSlot::filename(void) const
128{
129 return filename_.c_str();
130}
131
132/*
133 void BankSlot::init(int nslot_, int *what_, int *whatslot_,void (BankProcess_:: *fnc_)(void),BankProcess_ *bp_,Bank *bank_,int *nselected_) {
134 nslot=nslot_;
135 what=what_;
136 whatslot=whatslot_;
137 fnc=fnc_;
138 bp=bp_;
139//bank=bank_;
140nselected=nselected_;
141box(FL_THIN_UP_BOX);
142labelfont(0);
143labelsize(13);
144align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE|FL_ALIGN_CLIP);
145
146highlight=0;
147//refresh();
148}
149*/
150
151/*
152 void BankSlot::refresh() {
153 if (bank->emptyslot(nslot))
154 color(46);
155 else if (bank->isPADsynth_used(nslot))
156 color(26);
157 else
158 color(51);
159
160
161 if (*nselected==nslot)
162 color(6);
163
164
165 copy_label(bank->getnamenumbered(nslot).c_str());
166 }
167 */
168static int modeCb(const char *label)
169{
170 if(!strcmp("Read", label))
171 return 1;
172 else if(!strcmp("Write", label))
173 return 2;
174 else if(!strcmp("Clear", label))
175 return 3;
176 else if(!strcmp("Swap", label))
177 return 4;
178 return -1;
179}
180
181static void modeButtonCb(Fl_Widget *w, void *v)
182{
184 bvc->mode(modeCb(w->label()));
185}
186
187BankViewControls::BankViewControls(int x, int y, int w, int h, const char *label)
188 :Fl_Group(x,y,w,h,label)
189{
190 //Margin
191 const int m = 10;
192 //Width per elm
193 const float W = w/4;
194
195 read = new Fl_Check_Button(x+m+0*W, y+m, W-2*m, h-2*m, "Read");
196 write = new Fl_Check_Button(x+m+1*W, y+m, W-2*m, h-2*m, "Write");
197 clear = new Fl_Check_Button(x+m+2*W, y+m, W-2*m, h-2*m, "Clear");
198 swap = new Fl_Check_Button(x+m+3*W, y+m, W-2*m, h-2*m, "Swap");
199 read->box(FL_BORDER_BOX);
200 write->box(FL_BORDER_BOX);
201 clear->box(FL_BORDER_BOX);
202 swap->box(FL_BORDER_BOX);
203 read->callback(modeButtonCb, this);
204 write->callback(modeButtonCb, this);
205 clear->callback(modeButtonCb, this);
206 swap->callback(modeButtonCb, this);
207 mode(1);
208}
209
211{
212 return mode_;
213}
214
216{
217 mode_ = m;
218 int M = m-1;
219 assert(0 <= M && M <= 3);
220 Fl_Button *buttons[4]{read, write, clear, swap};
221
222 for(int i=0; i<4; ++i)
223 buttons[i]->value(i==M);
224}
225
226
227BankView::BankView(int x,int y, int w, int h, const char *label)
228 :Fl_Group(x,y,w,h,label), Fl_Osc_Widget(),
229 bvc(NULL), slots{0}, nselected(-1), npart(0), cbwig_(0)
230{}
231
232
234{
235 if(osc) {
236 osc->removeLink("/bankview", this);
237 osc->removeLink("/bank/search_results", this);
238 }
239}
240
241void BankView::init(Fl_Osc_Interface *osc_, BankViewControls *bvc_, int *npart_)
242{
243 assert(osc_);
244
245 osc = osc_;
246 bvc = bvc_;
247 npart = npart_;
248
249 osc->createLink("/bankview", this);
250 osc->createLink("/bank/search_results", this);
251
252 //Element Size
253 const float width = w()/5.0;
254 const float height = h()/32.0;
255
256 //Offsets
257 const int X = x();
258 const int Y = y();
259
260 begin();
261 //Place All Slots
262 for(int i=0; i<5; ++i)
263 for(int j=0; j<32; ++j)
264 slots[i*32 + j] =
265 new BankSlot(X + i*width, Y + j*height, width, height);
266
267 end();
268
269 //Initialize callbacks
270 for(int i=0; i<160; ++i)
271 slots[i]->init(i, this);
272
273 //Create Slot Listeners
274 for(int i=0; i<160; ++i)
275 osc->createLink("/bank/slot"+to_s(i), this);
276 //Request Values
277 for(int i=0; i<160; ++i)
278 osc->write("/bank/slot"+to_s(i), "");
279}
280
281/*
282 * React to user input.
283 * This consists of the events:
284 * - Rename Slot (right click)
285 * - Read From Slot
286 * - Write To Slot
287 * - Swap Slot First Selection
288 * - Swap Slot Second Selction
289 *
290 * TODO restore autoclose functionality
291 */
292void BankView::react(int event, int nslot)
293{
294 BankSlot &slot = *slots[nslot];
295 const bool isempty = slot.empty();
296 const int mode = bvc->mode();
297
298 //Rename slot
299 if (event==2 && !isempty && mode!=4) {
300 if(const char *name=fl_input("Slot (instrument) name:", slot.name())) {
301 osc->write("/bank/rename_slot", "is", nslot, name);
302 osc->write("/bank/slot"+to_s(nslot), "");
303 }
304 }
305
306 //Reads from slot
307 if ((event==1)&&(mode==1) && !isempty){
308 printf("Loading a part #%d with file '%s'\n", nslot, slot.filename());
309 osc->write("/load-part", "iss", *npart, slot.filename(),
310 slot.name());
311 osc->writeValue("/part"+to_s(*npart)+"/Pname", slot.name());
312 if(cbwig_)
313 cbwig_->do_callback();
314 }
315
316 //save(write) to slot
317 if(event==1 && mode==2){
318 if(isempty ||
319 fl_choice("Overwrite the slot no. %d ?","No","Yes",NULL,nslot+1)) {
320 osc->write("/bank/save_to_slot", "ii", *npart, nslot);
321 osc->write("/bank/slot"+to_s(nslot), "");
322 }
323 bvc->mode(1);
324 }
325
326
327 //Clears the slot
328 if(event==1 && mode==3) {
329 if (!isempty &&
330 fl_choice("Clear the slot no. %d ?","No","Yes",NULL, nslot+1)) {
331 osc->write("/bank/clear_slot", "i", nslot);
332 osc->write("/bank/slot"+to_s(nslot), "");
333 }
334 bvc->mode(1);
335 }
336
337 //Swap
338 if(mode==4) {
339 if(event==1 && nselected>=0){
340 osc->write("/bank/swap_slots", "ii", nselected, nslot);
341 osc->write("/bank/slot"+to_s(nslot), "");
342 osc->write("/bank/slot"+to_s(nselected), "");
343 nselected=-1;
344 } else if(nselected<0 || event==2) {
345 nselected=nslot;
346 };
347 };
348}
349
350void BankView::OSC_raw(const char *msg)
351{
352 if(!strcmp(msg, "/bank/search_results")) {
353 const char *ptr = rtosc_argument_string(msg);
354 int slot = 0;
355
356 while (ptr[0] == 's' && ptr[1] == 's') {
357 const char *bank = rtosc_argument(msg, 2*slot).s;
358 const char *fname = rtosc_argument(msg, 2*slot + 1).s;
359
360 /* store search results directly into slot */
361 slots[slot]->update(bank, fname);
362 if (++slot == 160)
363 break;
364 ptr += 2;
365 }
366 while (slot < 160)
367 slots[slot++]->update("", "");
368 } else if(!strcmp(rtosc_argument_string(msg), "iss")) {
369 int nslot = rtosc_argument(msg,0).i;
370 const char *name = rtosc_argument(msg,1).s;
371 const char *fname = rtosc_argument(msg,2).s;
372
373 if(0 <= nslot && nslot < 160)
374 slots[nslot]->update(name, fname);
375 } else if(!strcmp(rtosc_argument_string(msg), "ss")) {
376 while(*msg && !isdigit(*msg)) msg++;
377 int nslot = atoi(msg);
378 const char *name = rtosc_argument(msg,0).s;
379 const char *fname = rtosc_argument(msg,1).s;
380
381 if(0 <= nslot && nslot < 160)
382 slots[nslot]->update(name, fname);
383 }
384}
385
386void BankView::cbwig(Fl_Widget *w)
387{
388 cbwig_ = w;
389}
390
392{
393 assert(osc);
394 //Odd case during initialization
395 if(!osc)
396 return;
397
398 for(int i=0; i<160; ++i)
399 osc->write("/bank/slot"+to_s(i), "");
400}
401
static void modeButtonCb(Fl_Widget *w, void *v)
Definition BankView.cpp:181
static int modeCb(const char *label)
Definition BankView.cpp:168
#define NULL
Definition CarlaBridgeFormat.cpp:30
assert(0)
BankList(int x, int y, int w, int h, const char *label=0)
Definition BankView.cpp:24
void OSC_raw(const char *msg)
Definition BankView.cpp:36
void init(std::string path)
Definition BankView.cpp:28
Definition BankView.h:36
BankSlot(int x, int y, int w, int h, const char *label=0)
Definition BankView.cpp:62
char labelstr[128]
Definition BankView.h:50
int nslot
Definition BankView.h:51
const char * filename(void) const
Definition BankView.cpp:127
BankView * bv
Definition BankView.h:52
bool empty(void) const
Definition BankView.cpp:117
void init(int nslot_, BankView *bv_)
Definition BankView.cpp:92
std::string name_
Definition BankView.h:48
const char * name(void) const
Definition BankView.cpp:122
std::string filename_
Definition BankView.h:49
void update(const char *name__, const char *fname__)
Definition BankView.cpp:101
int handle(int event)
Definition BankView.cpp:72
Definition BankView.h:56
int mode(void) const
Definition BankView.cpp:210
int mode_
Definition BankView.h:75
Fl_Check_Button * clear
Definition BankView.h:68
Fl_Check_Button * write
Definition BankView.h:67
BankViewControls(int x, int y, int w, int h, const char *label=0)
Definition BankView.cpp:187
Fl_Check_Button * read
Definition BankView.h:66
Fl_Check_Button * swap
Definition BankView.h:69
Definition BankView.h:83
void refresh(void)
Definition BankView.cpp:391
void react(int event, int slot)
Definition BankView.cpp:292
BankViewControls * bvc
Definition BankView.h:96
int * npart
Definition BankView.h:101
void cbwig(Fl_Widget *w)
Definition BankView.cpp:386
int nselected
Definition BankView.h:100
Fl_Widget * cbwig_
Definition BankView.h:103
virtual void OSC_raw(const char *msg) override
Definition BankView.cpp:350
BankView(int x, int y, int w, int h, const char *label=0)
Definition BankView.cpp:227
void init(Fl_Osc_Interface *osc_, BankViewControls *bvc_, int *npart_)
Definition BankView.cpp:241
~BankView(void)
Definition BankView.cpp:233
BankSlot * slots[160]
Definition BankView.h:97
Fl_Osc_Choice(int X, int Y, int W, int H, const char *label=NULL)
Definition Fl_Osc_Choice.cpp:26
Definition Fl_Osc_Interface.h:56
Fl_Osc_Interface * osc
Definition Fl_Osc_Widget.H:65
std::string ext
Definition Fl_Osc_Widget.H:64
Fl_Osc_Widget(void)
Definition Fl_Osc_Widget.cpp:16
void oscRegister(const char *path)
Definition Fl_Osc_Widget.cpp:91
void oscWrite(std::string path, const char *args,...)
Definition Fl_Osc_Widget.cpp:60
UINT_D64 w
Definition inflate.c:942
unsigned * m
Definition inflate.c:1559
register unsigned j
Definition inflate.c:1576
int y
Definition inflate.c:1588
unsigned v[N_MAX]
Definition inflate.c:1584
register unsigned i
Definition inflate.c:1575
unsigned x[BMAX+1]
Definition inflate.c:1586
static PuglViewHint int value
Definition pugl.h:1708
static const char * name
Definition pugl.h:1582
static int int height
Definition pugl.h:1594
static int width
Definition pugl.h:1593
int val
Definition jpeglib.h:956
#define X(str)
Definition juce_LV2Common.h:197
const char * msg
Definition missing_descriptor.c:20
Definition zynaddsubfx-src.cpp:569
std::string to_s(T x)
Definition Util.h:67
#define M
Definition nseel-cfunc.c:37
png_structrp int mode
Definition png.h:1139
const char * rtosc_argument_string(const char *msg)
Definition rtosc.c:11
rtosc_arg_t rtosc_argument(const char *msg, unsigned idx)
Definition rtosc.c:732
Definition jquant2.c:258
int32_t i
Definition rtosc.h:47
const char * s
Definition rtosc.h:54
uch h[RAND_HEAD_LEN]
Definition crypt.c:459
ZCONST uch * init
Definition extract.c:2392
ulg size
Definition extract.c:2350