1 /*
2 * Author: Harry van Haaren 2013
3 * harryhaaren@gmail.com
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include "gui.hxx"
20 #include "avtk/avtk_image.h"
21 #include "avtk/avtk_button.h"
22
23 #include <sstream>
24
25 #pragma GCC diagnostic ignored "-Wunused-parameter"
26 #pragma GCC diagnostic ignored "-Wmissing-field-initializers"
27
28 // ONLY to be used for QUIT!
29 #include "jack.hxx"
30 extern Jack* jack;
31
32 #include "audiobuffer.hxx"
33 #include "controller/nonseq.hxx"
34 #include "controller/genericmidi.hxx"
35
36 #include "icon.xpm"
37 #include <FL/x.H>
38 #include <FL/fl_draw.H>
39
40 #include <stdlib.h>
41 #include <FL/Fl.H>
42 #include <FL/fl_ask.H>
43 #include <FL/Fl_Window.H>
44 #include <FL/Fl_Group.H>
45 #include <FL/Fl_Wizard.H>
46 #include <FL/Fl_Button.H>
47 #include <FL/Fl_Multiline_Output.H>
48
49 // include the header.c file in the planning dir:
50 // its the GIMP .c export of the LUPPP header image
51 #include "../planning/header.c"
52 #include "../planning/luppp.c"
53 #include "../planning/bg.c"
54
55 using namespace std;
56
57 extern Gui* gui;
58 extern int signalHanlderInt;
59
signalChecker(void *)60 static void signalChecker(void*)
61 {
62 if ( signalHanlderInt ) {
63 // Luppp recieved either a SIGTERM or SIGINT: quit gracefully
64 gui->quit();
65 } else {
66 Fl::repeat_timeout( 0.1, (Fl_Timeout_Handler)&signalChecker, 0 );
67 }
68 }
69
close_cb(Fl_Widget * o,void *)70 void close_cb(Fl_Widget*o, void*)
71 {
72 if ( (Fl::event() == FL_KEYDOWN || Fl::event() == FL_SHORTCUT) && Fl::event_key() == FL_Escape) {
73 // on excape, as about quitting
74 gui->askQuit();
75 } else {
76 gui->quit();
77 }
78 }
gui_static_read_rb(void * inst)79 static void gui_static_read_rb(void* inst)
80 {
81 handleGuiEvents();
82
83 Fl::repeat_timeout( 1 / 30.f, &gui_static_read_rb, inst);
84 }
85
gui_static_nsm_cb(void * inst)86 static void gui_static_nsm_cb(void* inst)
87 {
88 nsm_check_nowait( gui->getNsm() );
89 Fl::repeat_timeout( 1 / 30.f, &gui_static_nsm_cb, inst);
90 }
91
option_controller_cb(Fl_Widget *,void * data)92 void option_controller_cb(Fl_Widget*,void* data)
93 {
94 LUPPP_NOTE("%s","Controller cb");
95 }
96
gui_header_callback(Fl_Widget * w,void * data)97 static void gui_header_callback(Fl_Widget *w, void *data)
98 {
99 Gui* g = (Gui*)data;
100 if ( Fl::event_x() > 130 ) {
101 return;
102 }
103
104 Fl_Menu_Item rclick_menu[] = {
105 { "New Session" },
106 { "Load Session" },
107 { "Save Session ", 0, 0, 0, FL_MENU_DIVIDER},
108 { "Setup", 0, 0, 0, FL_MENU_DIVIDER},
109 { "Quit" },
110 { 0 }
111 };
112
113 // check for NSM running, deactivate new / save / load if yes
114 if ( gui->getNsm() ) {
115 rclick_menu[1].deactivate();
116 rclick_menu[2].deactivate();
117 }
118
119 Fl_Menu_Item *m = (Fl_Menu_Item*) rclick_menu->popup( 10, 38, 0, 0, 0);
120
121 if ( !m ) {
122 return;
123 } else if ( strcmp(m->label(), "New Session") == 0 ) {
124 int yes = fl_choice("Start a new session?","Cancel","Yes",0);
125 if ( yes ) {
126 gui->reset();
127 }
128 } else if ( strcmp(m->label(), "Load Session") == 0 ) {
129
130 std::string tmp;
131 {
132 // Create the file chooser, and show it
133 Fl_File_Chooser chooser(gui->getProjectsDir().c_str(),
134 "*",
135 Fl_File_Chooser::DIRECTORY,
136 "Load Session");
137 chooser.show();
138
139 // Block until user picks something.
140 // (The other way to do this is to use a callback())
141 //
142 while(chooser.shown()) {
143 Fl::wait();
144 }
145
146 // User hit cancel?
147 if ( chooser.value() == NULL ) {
148 fprintf(stderr, "(User hit 'Cancel')\n");
149 return;
150 }
151
152 // Print what the user picked
153 fprintf(stderr, "--------------------\n");
154 fprintf(stderr, "DIRECTORY: '%s'\n", chooser.directory());
155 fprintf(stderr, " VALUE: '%s'\n", chooser.value());
156 fprintf(stderr, " COUNT: %d files selected\n", chooser.count());
157
158 tmp = chooser.value();
159 chooser.hide();
160
161 /*
162 // try to make the Load window dissapear *now*
163 Fl::check();
164 Fl::flush();
165 Fl::wait(0);
166 */
167 }
168
169 LUPPP_NOTE( "Loading session from dir %s", tmp.c_str() );
170
171 // clear the current session: just do a state reset
172 EventStateReset e;
173 writeToDspRingbuffer( &e );
174
175 int sess = gui->getDiskReader()->readSession( tmp );
176 if ( sess != LUPPP_RETURN_OK )
177 LUPPP_ERROR( "Error loading session" );
178
179 return;
180 } else if ( strcmp(m->label(), "Save Session ") == 0 ) {
181 const char* name = fl_input( "Save session as", gui->getDiskWriter()->getLastSaveName().c_str() );
182 if ( name ) {
183 gui->getDiskWriter()->initialize( gui->getProjectsDir().c_str(), name );
184 LUPPP_NOTE("%s %s","Saving session as ", name );
185 EventStateSave e;
186 writeToDspRingbuffer( &e );
187 }
188 } else if ( strcmp(m->label(), "Setup") == 0 ) {
189 g->getOptionsWindow()->show();
190 } else if ( strcmp(m->label(), "Quit") == 0 ) {
191 g->askQuit();
192 }
193 }
194
getOptionsWindow()195 OptionsWindow* Gui::getOptionsWindow()
196 {
197 return optionWindow;
198 }
199
selectLoadController(Fl_Widget * w,void *)200 void Gui::selectLoadController(Fl_Widget* w, void*)
201 {
202 // FIXME: refactor
203 string path;
204 Fl_Native_File_Chooser fnfc;
205 fnfc.title("Pick a controller definition");
206 fnfc.type(Fl_Native_File_Chooser::BROWSE_FILE);
207 fnfc.filter("Controllers\t*.ctlr");
208 fnfc.directory( getenv("HOME") ); // default directory to use
209 // Show native chooser
210 switch ( fnfc.show() ) {
211 case -1:
212 printf("ERROR: %s\n", fnfc.errmsg());
213 break; // ERROR
214 case 1:
215 printf("CANCEL\n");
216 break; // CANCEL
217 default:
218 printf("Loading controller at %s\n", fnfc.filename());
219 path = fnfc.filename();
220 break;
221 }
222
223 if ( strcmp( path.c_str(), "" ) == 0 )
224 return;
225
226 LUPPP_NOTE("%s","ADD Controller cb");
227 Controller* c = new GenericMIDI( path );
228
229 if ( c->status() == Controller::CONTROLLER_OK ) {
230 EventControllerInstance e(c);
231 writeToDspRingbuffer( &e );
232 } else {
233 LUPPP_ERROR("Controller initialization failed!");
234 }
235
236 }
237
setProjectsDir(string dir)238 void Gui::setProjectsDir(string dir)
239 {
240 lupppProjectsDir=dir;
241 }
242
getProjectsDir()243 string Gui::getProjectsDir()
244 {
245 return lupppProjectsDir;
246 }
247
selectSaveSample(int track,int scene)248 void Gui::selectSaveSample( int track, int scene )
249 {
250 EventStateSaveBuffer e;
251 e.track = track,
252 e.scene = scene,
253 writeToDspRingbuffer( &e );
254 }
255
256 char *
selectSavePath()257 Gui::selectSavePath()
258 {
259 string path;
260 Fl_Native_File_Chooser fnfc;
261 fnfc.title("Save filename?");
262 fnfc.type(Fl_Native_File_Chooser::BROWSE_SAVE_FILE);
263
264 std::string defLoadPath = gui->getDiskReader()->getLastLoadedSamplePath();
265 fnfc.directory( defLoadPath.c_str() ); // default directory to use
266
267 // Show native chooser
268 switch ( fnfc.show() ) {
269 case -1: /*printf("ERROR: %s\n", fnfc.errmsg()); */
270 break; // ERROR
271 case 1: /*(printf("CANCEL\n"); */
272 break; // CANCEL
273 default: /*printf("Loading directory: %s\n", fnfc.filename()); */
274 path = fnfc.filename();
275 break;
276 }
277
278 if ( strcmp( path.c_str(), "" ) == 0 )
279 return 0;
280
281 return strdup(path.c_str());
282 }
283
selectLoadSample(int track,int scene)284 void Gui::selectLoadSample( int track, int scene )
285 {
286 // FIXME: refactor
287 string path;
288 Fl_Native_File_Chooser fnfc;
289 fnfc.title("Pick a file");
290 fnfc.type(Fl_Native_File_Chooser::BROWSE_FILE);
291
292 fnfc.filter("Audio\t{*.aiff,*.wav,*.flac,*.ogg}");
293
294 std::string defLoadPath = gui->getDiskReader()->getLastLoadedSamplePath();
295 fnfc.directory( defLoadPath.c_str() ); // default directory to use
296
297 // Show native chooser
298 switch ( fnfc.show() ) {
299 case -1: /*printf("ERROR: %s\n", fnfc.errmsg()); */
300 break; // ERROR
301 case 1: /*(printf("CANCEL\n"); */
302 break; // CANCEL
303 default: /*printf("Loading directory: %s\n", fnfc.filename()); */
304 path = fnfc.filename();
305 break;
306 }
307
308 if ( strcmp( path.c_str(), "" ) == 0 )
309 return;
310
311 // diskReader loads sample, and parses for sample.cfg
312 diskReader->loadSample( track, scene, path );
313 }
314
getAudioEditor()315 AudioEditor* Gui::getAudioEditor()
316 {
317 return audioEditor;
318 }
319
320
cb_nsm_open(const char * name,const char * display_name,const char * client_id,char ** out_msg,void * userdata)321 static int cb_nsm_open (const char *name,
322 const char *display_name,
323 const char *client_id,
324 char **out_msg,
325 void *userdata )
326 {
327 LUPPP_NOTE("NSM: Open, displayname: %s", display_name );
328
329 Jack::setup( client_id );
330
331 // we *must* get the samplerate here: loading files depends on this information!
332 gui->samplerate = jack->getSamplerate();
333
334 stringstream loadPath;
335 loadPath << name;
336
337 // load the NSM provided directory
338 gui->getDiskReader()->readSession( loadPath.str() );
339
340 // initialize the disk-writer to the same directory:
341 // we *always* overwrite the old save file when using NSM
342 gui->getDiskWriter()->initialize( name, display_name );
343
344 return ERR_OK;
345 }
346
cb_nsm_save(char ** out_msg,void * userdata)347 static int cb_nsm_save ( char **out_msg, void *userdata )
348 {
349 LUPPP_NOTE("NSM: saving..." );
350
351 // disk-writer already initialized to the right directory, so just write!
352 EventStateSave e;
353 writeToDspRingbuffer( &e );
354
355 return 0;
356 }
357
358
359
Gui(const char * argZero)360 Gui::Gui(const char* argZero) :
361 samplerate( 0 ),
362 window(1110,700),
363 enablePerTrackOutput(false),
364 diskReader( new DiskReader() ),
365 diskWriter( new DiskWriter() )
366 {
367 gui = this;
368
369 // setup window icon before calling show()
370 fl_open_display();
371 Fl_Pixmap* pixmap = new Fl_Pixmap( icon_xpm );
372 Fl_Offscreen lupppIcon = XCreatePixmap(fl_display, RootWindow(fl_display, fl_screen),
373 pixmap->w(), pixmap->h(), fl_visual->depth);
374 fl_gc = XCreateGC(fl_display, lupppIcon, 0, 0);
375 fl_begin_offscreen(lupppIcon);
376 pixmap->draw(0,0);
377 fl_end_offscreen();
378 delete pixmap;
379 XFreeGC(fl_display, fl_gc);
380
381 window.icon( (void*)lupppIcon );
382
383 // setup callback to signalChecker()
384 Fl::add_timeout( 0.1, (Fl_Timeout_Handler)&signalChecker, 0 );
385
386 // add keyboard shortcut handler
387 Fl::add_handler( keyboardHandler );
388
389 //window.resize( false );
390 window.xclass("luppp");
391 window.iconlabel("luppp");
392
393 window.color(FL_BLACK);
394 window.label("Luppp");
395 window.callback( close_cb, 0 );
396 window.size_range( 800, 450 );
397
398 window.color( fl_rgb_color (7,7,7) );
399
400 // horizontal no-resize-images group
401 Fl_Group* headerImages = new Fl_Group( 0, 0, 1110, 650, "header");
402 {
403 //Fl_Pack* vHeaderImages = new Fl_Pack( 0, 0, 1110, 650, "verticalHeader");
404 {
405 Avtk::Image* bgImage = new Avtk::Image(0,0,1920,36,"bg");
406 bgImage->setPixbuf( bgImg.pixel_data, 4 );
407
408 Avtk::Image* lupppImage = new Avtk::Image(0,0,130,36,"luppp");
409 lupppImage->setPixbuf( lupppImg.pixel_data, 4 );
410 lupppImage->callback( gui_header_callback, this );
411
412 Avtk::Image* headerImage = new Avtk::Image( window.w() - 270,0,270,36,"header");
413 headerImage->setPixbuf( header.pixel_data, 4 );
414 headerImage->stickToRight = true;
415
416
417 Fl_Box* box = new Fl_Box( 130, 0, 400, 36 );
418 headerImages->resizable( box );
419
420 //vHeaderImages->set_vertical();
421 //vHeaderImages->relayout();
422 }
423 //vHeaderImages->end();
424
425 Fl_Box* box = new Fl_Box( 130, 0, 400, 36 );
426 headerImages->resizable( box );
427 }
428 headerImages->end();
429
430 // create a new "Group" with all Luppp GUI contents, for resizing
431 lupppGroup = new Fl_Group( 0, 0, 1110, 700, "Luppp");
432 {
433 int i = 0;
434 for (; i < NTRACKS; i++ ) {
435 stringstream s;
436 s << "Track " << i+1;
437 tracks.push_back( std::make_shared<GTrack>(8 + i * 118, 40, 110, 650, s.str().c_str() ) );
438 }
439 master = new GMasterTrack(8 + i * 118, 40, 150, 650, "Master");
440 }
441 lupppGroup->end();
442
443 window.resizable( lupppGroup );
444
445 window.end();
446
447 specialTrack = 0;
448 specialScene = 0;
449 tracks.at( specialTrack )->getClipSelector()->setSpecial( specialScene );
450
451
452 optionWindow = new OptionsWindow();
453
454 // Create AudioEditor after window.end() has been called
455 audioEditor = new AudioEditor();
456
457 // read settings file using diskreader, and setup controllers etc
458 int prefs = diskReader->loadPreferences();
459 if ( prefs != LUPPP_RETURN_OK ) {
460 LUPPP_WARN("No preferences loaded, using defaults.");
461 } else {
462 LUPPP_NOTE("Loaded preferences");
463 }
464
465 // NSM stuff
466 nsm = 0;
467 const char *nsm_url = getenv( "NSM_URL" );
468 if ( nsm_url ) {
469 nsm = nsm_new();
470
471 nsm_set_open_callback( nsm, cb_nsm_open, this );
472 nsm_set_save_callback( nsm, cb_nsm_save, this );
473
474 if ( nsm_init( nsm, nsm_url ) == 0 ) {
475 nsm_send_announce( nsm, "Luppp", "", argZero );
476 LUPPP_NOTE("Announcing to NSM");
477 } else {
478 nsm_free( nsm );
479 nsm = 0;
480 }
481 }
482 }
483
addMidiControllerToSetup(std::string c)484 void Gui::addMidiControllerToSetup(std::string c)
485 {
486 controllerVector.push_back( c );
487 }
488
setupMidiControllers()489 void Gui::setupMidiControllers()
490 {
491 for(unsigned int i = 0; i < controllerVector.size(); i++) {
492 GenericMIDI* c = new GenericMIDI( controllerVector.at(i).c_str() );
493 if ( c ) {
494 EventControllerInstance e(c);
495 writeToDspRingbuffer( &e );
496 }
497 }
498 }
499
reset()500 void Gui::reset()
501 {
502 // signal to DSP to reset state
503 EventStateReset ev;
504 writeToDspRingbuffer( &ev );
505
506 // clear UI state: track names / scene names
507 for(unsigned int i = 0; i < NTRACKS; i++) {
508 stringstream s;
509 s << "Track " << i+1;
510 tracks.at(i)->bg.copy_label( s.str().c_str() );
511
512 for(unsigned int s = 0; s < NSCENES; s++) {
513 tracks.at(i)->getClipSelector()->clipName( s, "" );
514 }
515 }
516
517 for(unsigned int i = 0; i < NSCENES; i++) {
518 stringstream s;
519 s << "Scene " << i+1;
520 master->getClipSelector()->clipName( i, s.str() );
521 }
522
523 }
524
getTrack(int id) const525 std::shared_ptr<GTrack> Gui::getTrack(int id) const
526 {
527 return tracks.at(id);
528 }
529
show()530 int Gui::show()
531 {
532 window.show();
533
534 gui_static_read_rb( this );
535
536 // only launch NSM check callbacks if NSM is setup
537 if ( gui->getNsm() )
538 gui_static_nsm_cb( this );
539
540 return Fl::run();
541 }
542
543
quit()544 int Gui::quit()
545 {
546 // close JACK client
547 jack->quit();
548
549 // ensure the subwindows are closed
550 optionWindow->hide();
551 audioEditor->hide();
552
553 // quit main window, causing program termination
554 window.hide();
555
556 return 0;
557 }
558
askQuit()559 void Gui::askQuit()
560 {
561 int quit = fl_choice("Really Quit?","Cancel","Quit",0);
562 if ( quit ) { // JUST QUIT
563 gui->quit();
564 }
565 }
566
keyboardHandler(int event)567 int Gui::keyboardHandler(int event)
568 {
569
570 switch( event ) {
571 case FL_SHORTCUT:
572 if ( strcmp( Fl::event_text(), "1" ) == 0 ) {
573 EventGridEvent e( 0, 0, true );
574 writeToDspRingbuffer( &e );
575 return 1;
576 } else if( strcmp( Fl::event_text(), "2" ) == 0 ) {
577 EventGridEvent e( 1, 0, true );
578 writeToDspRingbuffer( &e );
579 return 1;
580 } else if( strcmp( Fl::event_text(), "3" ) == 0 ) {
581 EventGridEvent e( 2, 0, true );
582 writeToDspRingbuffer( &e );
583 return 1;
584 } else if( strcmp( Fl::event_text(), "4" ) == 0 ) {
585 EventGridEvent e( 3, 0, true );
586 writeToDspRingbuffer( &e );
587 return 1;
588 } else if( strcmp( Fl::event_text(), "5" ) == 0 ) {
589 EventGridEvent e( 4, 0, true );
590 writeToDspRingbuffer( &e );
591 return 1;
592 } else if( strcmp( Fl::event_text(), "6" ) == 0 ) {
593 EventGridEvent e( 5, 0, true );
594 writeToDspRingbuffer( &e );
595 return 1;
596 } else if( strcmp( Fl::event_text(), "7" ) == 0 ) {
597 EventGridEvent e( 6, 0, true );
598 writeToDspRingbuffer( &e );
599 return 1;
600 } else if( strcmp( Fl::event_text(), "8" ) == 0 ) {
601 EventGridEvent e( 7, 0, true );
602 writeToDspRingbuffer( &e );
603 return 1;
604 }
605
606 else if( strcmp( Fl::event_text(), "!" ) == 0 ) {
607 EventGridState e( 0, 0, GridLogic::STATE_EMPTY );
608 writeToDspRingbuffer( &e );
609 return 1;
610 } else if( strcmp( Fl::event_text(), "@" ) == 0 ) {
611 EventGridState e( 1, 0, GridLogic::STATE_EMPTY );
612 writeToDspRingbuffer( &e );
613 return 1;
614 } else if( strcmp( Fl::event_text(), "\"" ) == 0 ) {
615 EventGridState e( 1, 0, GridLogic::STATE_EMPTY ); // for UK/Ireland keyboards
616 writeToDspRingbuffer( &e );
617 return 1;
618 } else if( strcmp( Fl::event_text(), "#" ) == 0 ) {
619 EventGridState e( 2, 0, GridLogic::STATE_EMPTY );
620 writeToDspRingbuffer( &e );
621 return 1;
622 } else if( strcmp( Fl::event_text(), "£" ) == 0 ) {
623 EventGridState e( 2, 0, GridLogic::STATE_EMPTY ); // for UK/Ireland keyboards
624 writeToDspRingbuffer( &e );
625 return 1;
626 } else if( strcmp( Fl::event_text(), "$" ) == 0 ) {
627 EventGridState e( 3, 0, GridLogic::STATE_EMPTY );
628 writeToDspRingbuffer( &e );
629 return 1;
630 } else if( strcmp( Fl::event_text(), "%" ) == 0 ) {
631 EventGridState e( 4, 0, GridLogic::STATE_EMPTY );
632 writeToDspRingbuffer( &e );
633 return 1;
634 } else if( strcmp( Fl::event_text(), "^" ) == 0 ) {
635 EventGridState e( 5, 0, GridLogic::STATE_EMPTY );
636 writeToDspRingbuffer( &e );
637 return 1;
638 } else if( strcmp( Fl::event_text(), "&" ) == 0 ) {
639 EventGridState e( 6, 0, GridLogic::STATE_EMPTY );
640 writeToDspRingbuffer( &e );
641 return 1;
642 } else if( strcmp( Fl::event_text(), "*" ) == 0 ) {
643 EventGridState e( 7, 0, GridLogic::STATE_EMPTY );
644 writeToDspRingbuffer( &e );
645 return 1;
646 }
647
648 else if( strcmp( Fl::event_text(), "q" ) == 0 ) {
649 EventGridEvent e( 0, 1, true );
650 writeToDspRingbuffer( &e );
651 return 1;
652 } else if( strcmp( Fl::event_text(), "w" ) == 0 ) {
653 EventGridEvent e( 1, 1, true );
654 writeToDspRingbuffer( &e );
655 return 1;
656 } else if( strcmp( Fl::event_text(), "e" ) == 0 ) {
657 EventGridEvent e( 2, 1, true );
658 writeToDspRingbuffer( &e );
659 return 1;
660 } else if( strcmp( Fl::event_text(), "r" ) == 0 ) {
661 EventGridEvent e( 3, 1, true );
662 writeToDspRingbuffer( &e );
663 return 1;
664 } else if( strcmp( Fl::event_text(), "t" ) == 0 ) {
665 EventGridEvent e( 4, 1, true );
666 writeToDspRingbuffer( &e );
667 return 1;
668 } else if( strcmp( Fl::event_text(), "y" ) == 0 ) {
669 EventGridEvent e( 5, 1, true );
670 writeToDspRingbuffer( &e );
671 return 1;
672 } else if( strcmp( Fl::event_text(), "u" ) == 0 ) {
673 EventGridEvent e( 6, 1, true );
674 writeToDspRingbuffer( &e );
675 return 1;
676 } else if( strcmp( Fl::event_text(), "i" ) == 0 ) {
677 EventGridEvent e( 7, 1, true );
678 writeToDspRingbuffer( &e );
679 return 1;
680 }
681
682 else if( strcmp( Fl::event_text(), "Q" ) == 0 ) {
683 EventGridState e( 0, 1, GridLogic::STATE_EMPTY );
684 writeToDspRingbuffer( &e );
685 return 1;
686 } else if( strcmp( Fl::event_text(), "W" ) == 0 ) {
687 EventGridState e( 1, 1, GridLogic::STATE_EMPTY );
688 writeToDspRingbuffer( &e );
689 return 1;
690 } else if( strcmp( Fl::event_text(), "E" ) == 0 ) {
691 EventGridState e( 2, 1, GridLogic::STATE_EMPTY );
692 writeToDspRingbuffer( &e );
693 return 1;
694 } else if( strcmp( Fl::event_text(), "R" ) == 0 ) {
695 EventGridState e( 3, 1, GridLogic::STATE_EMPTY );
696 writeToDspRingbuffer( &e );
697 return 1;
698 } else if( strcmp( Fl::event_text(), "T" ) == 0 ) {
699 EventGridState e( 4, 1, GridLogic::STATE_EMPTY );
700 writeToDspRingbuffer( &e );
701 return 1;
702 } else if( strcmp( Fl::event_text(), "Y" ) == 0 ) {
703 EventGridState e( 5, 1, GridLogic::STATE_EMPTY );
704 writeToDspRingbuffer( &e );
705 return 1;
706 } else if( strcmp( Fl::event_text(), "U" ) == 0 ) {
707 EventGridState e( 6, 1, GridLogic::STATE_EMPTY );
708 writeToDspRingbuffer( &e );
709 return 1;
710 } else if( strcmp( Fl::event_text(), "I" ) == 0 ) {
711 EventGridState e( 7, 1, GridLogic::STATE_EMPTY );
712 writeToDspRingbuffer( &e );
713 return 1;
714 }
715
716 else if( strcmp( Fl::event_text(), "a" ) == 0 ) {
717 EventGridEvent e( 0, 2, true );
718 writeToDspRingbuffer( &e );
719 return 1;
720 } else if( strcmp( Fl::event_text(), "s" ) == 0 ) {
721 EventGridEvent e( 1, 2, true );
722 writeToDspRingbuffer( &e );
723 return 1;
724 } else if( strcmp( Fl::event_text(), "d" ) == 0 ) {
725 EventGridEvent e( 2, 2, true );
726 writeToDspRingbuffer( &e );
727 return 1;
728 } else if( strcmp( Fl::event_text(), "f" ) == 0 ) {
729 EventGridEvent e( 3, 2, true );
730 writeToDspRingbuffer( &e );
731 return 1;
732 } else if( strcmp( Fl::event_text(), "g" ) == 0 ) {
733 EventGridEvent e( 4, 2, true );
734 writeToDspRingbuffer( &e );
735 return 1;
736 } else if( strcmp( Fl::event_text(), "h" ) == 0 ) {
737 EventGridEvent e( 5, 2, true );
738 writeToDspRingbuffer( &e );
739 return 1;
740 } else if( strcmp( Fl::event_text(), "j" ) == 0 ) {
741 EventGridEvent e( 6, 2, true );
742 writeToDspRingbuffer( &e );
743 return 1;
744 } else if( strcmp( Fl::event_text(), "k" ) == 0 ) {
745 EventGridEvent e( 7, 2, true );
746 writeToDspRingbuffer( &e );
747 return 1;
748 }
749
750 else if( strcmp( Fl::event_text(), "A" ) == 0 ) {
751 EventGridState e( 0, 2, GridLogic::STATE_EMPTY );
752 writeToDspRingbuffer( &e );
753 return 1;
754 } else if( strcmp( Fl::event_text(), "S" ) == 0 ) {
755 EventGridState e( 1, 2, GridLogic::STATE_EMPTY );
756 writeToDspRingbuffer( &e );
757 return 1;
758 } else if( strcmp( Fl::event_text(), "D" ) == 0 ) {
759 EventGridState e( 2, 2, GridLogic::STATE_EMPTY );
760 writeToDspRingbuffer( &e );
761 return 1;
762 } else if( strcmp( Fl::event_text(), "F" ) == 0 ) {
763 EventGridState e( 3, 2, GridLogic::STATE_EMPTY );
764 writeToDspRingbuffer( &e );
765 return 1;
766 } else if( strcmp( Fl::event_text(), "G" ) == 0 ) {
767 EventGridState e( 4, 2, GridLogic::STATE_EMPTY );
768 writeToDspRingbuffer( &e );
769 return 1;
770 } else if( strcmp( Fl::event_text(), "H" ) == 0 ) {
771 EventGridState e( 5, 2, GridLogic::STATE_EMPTY );
772 writeToDspRingbuffer( &e );
773 return 1;
774 } else if( strcmp( Fl::event_text(), "J" ) == 0 ) {
775 EventGridState e( 6, 2, GridLogic::STATE_EMPTY );
776 writeToDspRingbuffer( &e );
777 return 1;
778 } else if( strcmp( Fl::event_text(), "K" ) == 0 ) {
779 EventGridState e( 7, 2, GridLogic::STATE_EMPTY );
780 writeToDspRingbuffer( &e );
781 return 1;
782 }
783
784 else if( strcmp( Fl::event_text(), "z" ) == 0 ) {
785 EventGridEvent e( 0, 3, true );
786 writeToDspRingbuffer( &e );
787 return 1;
788 } else if( strcmp( Fl::event_text(), "x" ) == 0 ) {
789 EventGridEvent e( 1, 3, true );
790 writeToDspRingbuffer( &e );
791 return 1;
792 } else if( strcmp( Fl::event_text(), "c" ) == 0 ) {
793 EventGridEvent e( 2, 3, true );
794 writeToDspRingbuffer( &e );
795 return 1;
796 } else if( strcmp( Fl::event_text(), "v" ) == 0 ) {
797 EventGridEvent e( 3, 3, true );
798 writeToDspRingbuffer( &e );
799 return 1;
800 } else if( strcmp( Fl::event_text(), "b" ) == 0 ) {
801 EventGridEvent e( 4, 3, true );
802 writeToDspRingbuffer( &e );
803 return 1;
804 } else if( strcmp( Fl::event_text(), "n" ) == 0 ) {
805 EventGridEvent e( 5, 3, true );
806 writeToDspRingbuffer( &e );
807 return 1;
808 } else if( strcmp( Fl::event_text(), "m" ) == 0 ) {
809 EventGridEvent e( 6, 3, true );
810 writeToDspRingbuffer( &e );
811 return 1;
812 } else if( strcmp( Fl::event_text(), "," ) == 0 ) {
813 EventGridEvent e( 7, 3, true );
814 writeToDspRingbuffer( &e );
815 return 1;
816 }
817
818 else if( strcmp( Fl::event_text(), "Z" ) == 0 ) {
819 EventGridState e( 0, 3, GridLogic::STATE_EMPTY );
820 writeToDspRingbuffer( &e );
821 return 1;
822 } else if( strcmp( Fl::event_text(), "X" ) == 0 ) {
823 EventGridState e( 1, 3, GridLogic::STATE_EMPTY );
824 writeToDspRingbuffer( &e );
825 return 1;
826 } else if( strcmp( Fl::event_text(), "C" ) == 0 ) {
827 EventGridState e( 2, 3, GridLogic::STATE_EMPTY );
828 writeToDspRingbuffer( &e );
829 return 1;
830 } else if( strcmp( Fl::event_text(), "V" ) == 0 ) {
831 EventGridState e( 3, 3, GridLogic::STATE_EMPTY );
832 writeToDspRingbuffer( &e );
833 return 1;
834 } else if( strcmp( Fl::event_text(), "B" ) == 0 ) {
835 EventGridState e( 4, 3, GridLogic::STATE_EMPTY );
836 writeToDspRingbuffer( &e );
837 return 1;
838 } else if( strcmp( Fl::event_text(), "N" ) == 0 ) {
839 EventGridState e( 5, 3, GridLogic::STATE_EMPTY );
840 writeToDspRingbuffer( &e );
841 return 1;
842 } else if( strcmp( Fl::event_text(), "M" ) == 0 ) {
843 EventGridState e( 6, 3, GridLogic::STATE_EMPTY );
844 writeToDspRingbuffer( &e );
845 return 1;
846 } else if( strcmp( Fl::event_text(), "<" ) == 0 ) {
847 EventGridState e( 7, 3, GridLogic::STATE_EMPTY );
848 writeToDspRingbuffer( &e );
849 return 1;
850 }
851
852 else if( strcmp( Fl::event_text(), "9" ) == 0 ) {
853 EventGridLaunchScene e( 0 );
854 writeToDspRingbuffer( &e );
855 return 1;
856 } else if( strcmp( Fl::event_text(), "o" ) == 0 ) {
857 EventGridLaunchScene e( 1 );
858 writeToDspRingbuffer( &e );
859 return 1;
860 } else if( strcmp( Fl::event_text(), "l" ) == 0 ) {
861 EventGridLaunchScene e( 2 );
862 writeToDspRingbuffer( &e );
863 return 1;
864 } else if( strcmp( Fl::event_text(), "." ) == 0 ) {
865 EventGridLaunchScene e( 3 );
866 writeToDspRingbuffer( &e );
867 return 1;
868 }
869
870 else {
871 //printf("%s\n", Fl::event_text() ); return 1;
872 }
873 }
874
875 // keyboard arrows / space to special key mapping
876 if ( Fl::event_key( 32 ) && Fl::event_state( FL_SHIFT ) ) { //spacebar + shift
877 EventGridState e( gui->specialTrack, gui->specialScene, GridLogic::STATE_EMPTY );
878 writeToDspRingbuffer( &e );
879 return 1;
880 }
881 if ( Fl::event_key( 32 ) ) { //spacebar
882 EventGridEvent e( gui->specialTrack, gui->specialScene, true );
883 writeToDspRingbuffer( &e );
884 return 1;
885 }
886 if ( Fl::event_key( FL_Left ) ) {
887 EventGridSelectNewChosen e( gui->specialTrack-1, gui->specialScene );
888 writeToDspRingbuffer( &e );
889 return 1;
890 }
891 if ( Fl::event_key( FL_Right ) ) {
892 EventGridSelectNewChosen e( gui->specialTrack+1, gui->specialScene );
893 writeToDspRingbuffer( &e );
894 return 1;
895 }
896 if ( Fl::event_key( FL_Up ) ) {
897 EventGridSelectNewChosen e( gui->specialTrack , gui->specialScene-1);
898 writeToDspRingbuffer( &e );
899 return 1;
900 }
901 if ( Fl::event_key( FL_Down ) ) {
902 EventGridSelectNewChosen e( gui->specialTrack , gui->specialScene+1);
903 writeToDspRingbuffer( &e );
904 return 1;
905 }
906
907 return 0;
908 }
909
910
~Gui()911 Gui::~Gui()
912 {
913 delete optionWindow;
914 delete audioEditor;
915
916 delete diskReader;
917 delete diskWriter;
918
919 delete master;
920 }
921