1 # data file for the Fltk User Interface Designer (fluid)
6 // Copyright (C) 2008 Jonathan Moore Liles
8 // This program is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU General Public License
10 // as published by the Free Software Foundation; either version 2
11 // of the License, or (at your option) any later version.
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU General Public License for more details.
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the Free Software
20 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 } {in_source in_header
25 decl {\#include <FL/Fl_Dial.H>} {public local
28 decl {\#include "FL/About_Dialog.H"} {private local
31 decl {class Fl_Scalepack;} {public local
34 decl {class Fl_Sometimes_Input;} {public local
37 decl {\#include "FL/Fl_Theme_Chooser.H"} {private local
40 decl {\#include "FL/Fl_Scalepack.H"} {private local
43 decl {\#include "FL/Fl_Sometimes_Input.H"} {private local
46 decl {\#include "FL/Fl_Menu_Settings.H"} {private local
49 decl {\#include <FL/Fl_Shared_Image.H>} {private local
52 decl {\#include "widgets.H"} {private local
55 decl {\#include "event_edit.H"} {private local
58 decl {\#include "../jack.H"} {private local
61 decl {\#include "../NSM.H"} {private local
64 decl {extern NSM_Client *nsm;} {private local
67 decl {extern UI *ui;} {private local
70 decl {class O_Canvas;} {private local
73 decl {class Triggers;} {public local
76 decl {class Instrument_Editor;} {private local
79 decl {Fl_Color canvas_background_color;} {public local
82 decl {extern Fl_Color velocity_colors[];} {private local
85 Function {update_transport( void * )} {open return_type void
87 code {// transport_poll();
91 ui->progress_group->do_callback();
93 ui->vmetro_widget->update();
95 ui->triggers_widget->update();
97 Fl::repeat_timeout( TRANSPORT_POLL_INTERVAL, update_transport );
99 static int oldstate = -1;
101 if ( transport.rolling != oldstate )
104 ui->play_button->label( transport.rolling ? "@square" : "@>" );
105 oldstate = transport.rolling;
107 if ( transport.rolling )
109 ui->menu_new->deactivate();
110 ui->menu_open->deactivate();
114 ui->menu_new->activate();
115 ui->menu_open->activate();
120 if ( nsm && nsm->is_active() )
122 if ( ui->menu_new->active() )
124 ui->menu_new->deactivate();
125 ui->menu_open->deactivate();
126 ui->menu_save_as->deactivate();
131 if ( transport.rolling )
133 if ( ui->tabs->value() == ui->pattern_tab )
134 ui->pattern_canvas_widget->redraw_playhead();
136 if ( ui->tabs->value() == ui->phrase_tab )
137 ui->phrase_canvas_widget->redraw_playhead();
141 ui->transport_state->do_callback();} {}
146 decl {Fl_Text_Buffer *sequence_notes_buffer;} {private local
148 decl {Fl_Text_Buffer *pattern_notes_buffer;} {private local
150 decl {Fl_Text_Buffer *phrase_notes_buffer} {private local
152 Function {UI()} {open
154 code {fl_register_images();
156 canvas_background_color = FL_GREEN;
158 playback_mode_menu = NULL;
160 main_window = make_main_window();
161 seq_window = make_seq_window();
163 make_randomization_dialog();
165 // make_instrument_edit_dialog();
167 Fl::add_handler( shortcut_handler );
169 // use old focus behavior
170 Fl::visible_focus( 0 );
172 // try to fill the screen, but only when the screen is tiny and our window is huge.
176 Fl::screen_xywh( sx, sy, sw, sh );
178 if ( sw < main_window->w() || sh < main_window->h() )
179 main_window->resize( sx, sy, sw, sh );
182 Fl::add_timeout( TRANSPORT_POLL_INTERVAL, update_transport );
185 playlist->signal_new_song.connect( sigc::mem_fun( this, &UI::update_sequence_widgets ) );} {}
187 Function {~UI()} {open
189 code {delete seq_window;
190 delete main_window;} {}
192 Function {run()} {open
196 Function {load_settings()} {open return_type void
200 asprintf( &path, "%s/%s", config.user_config_dir, "view" );
202 ((Fl_Menu_Settings*)menu_bar)->load( menu_bar->find_item( "&View" ), path );
206 Function {save_settings()} {open return_type void
210 asprintf( &path, "%s/%s", config.user_config_dir, "view" );
212 ((Fl_Menu_Settings*)menu_bar)->dump( menu_bar->find_item( "&View" ), path );
216 Function {make_main_window()} {open
218 Fl_Window main_window {
219 label {Non Sequencer}
220 callback {// Ignore escape
221 if ( Fl::event() == FL_SHORTCUT && Fl::event_key() == FL_Escape )
224 if ( maybe_save_song() )
226 xywh {798 131 865 805} type Double color 47 resizable
227 code0 {o->color( FL_BACKGROUND_COLOR );} xclass non size_range {700 509 0 0} visible
230 xywh {0 30 865 70} box FLAT_BOX
234 callback {transport.set_beats_per_minute( o->value() );}
235 xywh {389 47 45 25} labelsize 9 align 1 when 8
236 code1 {transport.signal_tempo_change.connect( sigc::mem_fun( o, static_cast<int (Fl_Valuator::*)(double)>(&Fl_Valuator::value) ) );}
237 code2 {o->value( transport.beats_per_minute );}
240 callback {transport.set_beats_per_bar( o->value() );}
242 code0 {transport.signal_bpb_change.connect( sigc::mem_fun( o, static_cast<int (Fl_Valuator::*)(double)>(&Fl_Valuator::value) ) );}
243 code1 {o->value( transport.beats_per_bar );}
250 callback {transport.set_beat_type( o->value() );}
252 code0 {transport.signal_beat_change.connect( sigc::mem_fun( o, static_cast<int (Fl_Valuator::*)(double)>(&Fl_Valuator::value) ) );}
253 code1 {o->value( transport.beat_type );}
255 Fl_Pack vmetro_widget {
257 xywh {520 35 336 59} type HORIZONTAL box UP_BOX color 40 selection_color 48 labelsize 33 align 0 resizable
258 code0 {\#include "widgets.H"}
259 code1 {o->box( FL_FLAT_BOX );}
260 class Visual_Metronome
262 Fl_Pack transport_controls_group {open
263 xywh {4 32 156 42} type HORIZONTAL
264 code0 {o->spacing( 2 );}
267 Fl_Button play_button {
269 callback {transport.toggle();}
270 xywh {10 34 43 38} shortcut 0x20 labeltype ENGRAVED_LABEL
272 Fl_Button rec_button {
274 callback {transport.recording = o->value();
279 if ( config.record_mode == NEW )
281 pattern *p = new pattern;
284 pattern_c->grid( p );
287 ((pattern*)pattern_c->grid())->record( 0 );
289 o->labelcolor( FL_RED );
293 pattern::recording()->record_stop();
295 o->labelcolor( FL_WHITE );
297 xywh {60 34 43 38} type Toggle shortcut 0x80072 selection_color 47 labeltype ENGRAVED_LABEL when 1
299 Fl_Button home_button {
301 callback {transport.locate( 0 );}
302 xywh {110 34 43 38} shortcut 0xff50 labeltype ENGRAVED_LABEL
305 Fl_Choice record_mode_menu {
307 callback {if ( ! transport.recording )
308 config.record_mode = (record_mode_e)o->value();
310 o->value( config.record_mode );} open
311 xywh {170 47 100 25} box DOWN_BOX down_box BORDER_BOX color 37 labelsize 9 align 1
330 Fl_Choice playback_mode_menu {
331 label {Playback &Mode} open
332 xywh {279 47 100 25} box DOWN_BOX down_box BORDER_BOX color 37 labelsize 9 align 1
336 callback {song.play_mode = PATTERN;}
341 callback {song.play_mode = SEQUENCE;}
346 callback {song.play_mode = TRIGGER;}
351 callback {song.play_mode = QUEUE;}
357 callback {((Fl_Group*)o->value())->child( 0 )->take_focus();
359 ui->pan_indicators->show();
361 if ( o->value() == pattern_tab )
362 pattern_canvas_widget->handle_pan();
363 else if ( o->value() == phrase_tab )
364 phrase_canvas_widget->handle_pan();
366 if ( o->value() != pattern_tab )
368 if ( o->value() != phrase_tab )
369 ui->pan_indicators->hide();
370 edit_menu->deactivate();
374 edit_menu->activate();
377 menu_bar->redraw();} open
378 xywh {0 79 865 698} box BORDER_BOX color 47 labeltype SHADOW_LABEL labelsize 19 when 1 resizable
379 code0 {canvas_background_color = fl_rgb_color( 18, 18, 18 );}
381 Fl_Group sequence_tab {
383 xywh {0 102 865 674} box FLAT_BOX color 37 hide resizable
384 code0 {update_sequence_widgets();}
387 xywh {10 125 233 502} labelsize 12
389 Fl_Browser playlist_browser {
391 xywh {10 125 233 435} type Hold box EMBOSSED_BOX color 39 selection_color 30 labelcolor 55 align 1 when 4 textsize 18 textcolor 95 resizable
392 code0 {static int widths[] = { 40, 30, 0 };}
393 code1 {o->column_widths( widths ); o->column_char( '\\t' );}
394 code2 {o->value( 1 );}
396 Fl_Button sequence_phrase_delete_button {
398 callback {int val = playlist_browser->value();
402 // playlist_browser->value( playlist_browser->value() + 1 );
404 playlist->remove( val - 2 );
406 update_sequence_widgets();
408 if ( ! playlist_browser->value() )
409 playlist_browser->value( playlist_browser->size() );
411 xywh {14 566 73 25} shortcut 0xffff color 88 labelcolor 23
413 Fl_Button sequence_phrase_up_button {
415 callback {if ( playlist_browser->value() > 2 )
417 playlist->move( playlist_browser->value() - 2, UP );
418 playlist_browser->value( playlist_browser->value() - 1 );
419 update_sequence_widgets();
421 xywh {97 566 65 25} shortcut 0xffbf
423 Fl_Button sequence_phrase_down_button {
425 callback {if ( playlist_browser->value() > 1 )
427 playlist->move( playlist_browser->value() - 2, DOWN );
428 playlist_browser->value( playlist_browser->value() + 1 );
429 update_sequence_widgets();
431 xywh {169 566 74 25} shortcut 0xffc0
433 Fl_Menu_Button sequence_phrase_choice {
434 label {Insert Phrase}
435 callback {playlist->insert( playlist_browser->value() - 1, o->value() + 1 );
437 update_sequence_widgets();
439 int val = playlist_browser->value();
442 playlist_browser->value( playlist_browser->value() + 1 );
444 playlist_browser->value( playlist_browser->size() );} open
445 xywh {11 597 232 30} color 63
448 Fl_Input sequence_name_field {
450 callback {playlist->name( o->value() );}
451 xywh {91 740 158 26} color 36 align 20 when 1 textcolor 32
453 Fl_Light_Button detach_button {
455 callback {if ( o->value() )
457 Fl_Group *g = seq_detached_group;
459 g->add( sequence_tab );
460 sequence_tab->resize( g->x(), g->y(), g->w(), g->h() );
462 main_window->redraw();
467 tabs->insert( (Fl_Widget&)*sequence_tab, 0 );
468 sequence_tab->resize( pattern_tab->x(), pattern_tab->y(), pattern_tab->w(), pattern_tab->h() );
473 Fl_Text_Editor sequence_notes_edit {
475 callback {playlist->notes( o->buffer()->text() );}
476 xywh {254 691 606 73} selection_color 48 labelsize 12 align 5 textcolor 94
477 code0 {o->buffer( sequence_notes_buffer = new Fl_Text_Buffer );}
479 Fl_Box triggers_widget {
481 xywh {253 125 607 549} color 48 align 1 resizable
482 code0 {o->color( FL_BACKGROUND_COLOR );}
485 Fl_Group progress_group {
486 callback {if ( ! o->visible_r() )
489 phrase *p = phrase::phrase_by_number( playlist->playing() );
492 phrase_progress->value( p->index() / (double)p->length() );
494 if ( playlist->length() )
495 sequence_progress->value( playlist->index() / (double)playlist->length() );} open
498 Fl_Slider phrase_progress {
500 xywh {10 656 233 24} type Horizontal labelsize 12 align 1
502 Fl_Slider sequence_progress {
504 callback {transport.locate( (tick_t)((double)playlist->length() * o->value()) );}
505 xywh {10 698 233 24} type Horizontal labelsize 12 align 1
509 Fl_Group phrase_tab {
511 xywh {0 102 865 674} box FLAT_BOX color 47 hide
512 code0 {update_phrase_widgets();}
514 Fl_Box phrase_canvas_widget {
516 xywh {1 103 863 587} box FLAT_BOX color 37 labelsize 100 align 16 resizable
517 code0 {o->set_canvas( phrase_c );}
518 code1 {phrase_c->signal_pan.connect( sigc::mem_fun( phrase_canvas_widget, &O_Canvas::handle_pan ) );}
522 xywh {5 697 856 77} box FLAT_BOX color 47
524 Fl_Input phrase_name_field {
526 callback {phrase_c->grid()->name( strdup( o->value() ) );
528 // if the name changed..
529 update_sequence_widgets();}
530 xywh {5 704 155 24} box ROUNDED_BOX color 49 labelfont 2 labelcolor 55 align 20 textcolor 32
531 code0 {o->up_box( FL_ROUNDED_BOX );}
532 class Fl_Sometimes_Input
534 Fl_Spinner phrase_number_spinner {
536 callback {phrase *p = ((phrase *)phrase_c->grid())->by_number( o->value() );
541 o->maximum( phrase::phrases() );}
542 xywh {165 704 55 24} color 36 labelsize 9 align 1 when 1
544 Fl_Light_Button phrase_mute_button {
546 xywh {5 740 93 23} color 37 hide
548 Fl_Light_Button phrase_solo_button {
550 xywh {111 740 87 23} color 37 hide
552 Fl_Text_Editor phrase_notes_edit {
554 callback {phrase_c->grid()->notes( o->buffer()->text() );}
555 xywh {235 709 620 58} selection_color 48 labelsize 12 textcolor 94 resizable
556 code0 {o->buffer( phrase_notes_buffer = new Fl_Text_Buffer );}
560 Fl_Group pattern_tab {
562 xywh {0 102 865 674} box FLAT_BOX color 47
563 code0 {update_pattern_widgets();}
565 Fl_Box pattern_canvas_widget {
566 label Pattern selected
567 xywh {1 103 863 587} box FLAT_BOX color 37 labelsize 100 align 16 resizable
568 code0 {\#include "draw.H"}
569 code1 {o->set_canvas( pattern_c );}
570 code2 {\#include "input.H"}
571 code3 {pattern_c->signal_pan.connect( sigc::mem_fun( pattern_canvas_widget, &O_Canvas::handle_pan ) );}
575 xywh {0 694 862 78} box FLAT_BOX color 47
577 Fl_Input pattern_name_field {
579 callback {pattern_c->grid()->name( strdup( o->value() ) );}
580 xywh {5 704 155 24} box ROUNDED_BOX color 49 align 20 when 1 textfont 2 textcolor 55
581 code0 {o->up_box( FL_ROUNDED_BOX );}
582 class Fl_Sometimes_Input
584 Fl_Spinner pattern_number_spinner {
586 callback {pattern *p = ((pattern *)pattern_c->grid())->by_number( o->value() );
589 pattern_c->grid( p );
591 o->maximum( pattern::patterns() );}
592 xywh {165 704 55 24} color 36 labelsize 9 align 1 when 1
593 code0 {o->maximum( 1 );}
594 code1 {// pattern::signal_create_destroy.connect( sigc::mem_fun( o, static_cast<void (Fl_Spinner::*)(double)>(&Fl_Spinner::maximum) ) );}
596 Fl_Light_Button pattern_mute_button {
598 callback {Grid *g = pattern_c->grid();
600 g->mode( g->mode() == MUTE ? PLAY : MUTE );
602 o->value( g->mode() == MUTE );
604 pattern_solo_button->value( 0 );}
605 xywh {10 738 65 25} type Normal color 37
607 Fl_Light_Button pattern_solo_button {
609 callback {Grid *g = pattern_c->grid();
611 g->mode( g->mode() == SOLO ? PLAY : SOLO );
613 o->value( g->mode() == SOLO );
615 pattern_mute_button->value( 0 );}
616 xywh {80 738 65 25} type Normal color 37
618 Fl_Text_Editor pattern_notes_edit {
620 callback {pattern_c->grid()->notes( o->buffer()->text() );}
621 xywh {230 713 227 48} selection_color 48 labelsize 12 textcolor 94 resizable
622 code0 {o->buffer( pattern_notes_buffer = new Fl_Text_Buffer );}
624 Fl_Group pattern_settings_group {open
625 xywh {458 694 400 78}
627 Fl_Spinner pattern_channel_spinner {
629 callback {((pattern *)pattern_c->grid())->channel( o->value() - 1 );}
630 xywh {815 700 40 24} color 36 when 1
631 code0 {\#include "../pattern.H"}
632 code1 {o->maximum( 16 );}
634 Fl_Spinner pattern_port_spinner {
636 callback {((pattern *)pattern_c->grid())->port( o->value() - 1 );}
637 xywh {815 734 40 24} color 36 when 1
638 code0 {o->maximum( 16 );}
640 Fl_Output mapping_text {
642 xywh {464 734 145 24} align 20
644 Fl_Menu_Button mapping_menu {
646 callback {mapping_text->value( o->text() );
650 mapping_menu->item_pathname(picked, sizeof(picked)-1 );
652 if ( 0 == strncmp( picked, "Instrument", strlen( "Instrument" ) ) )
654 ((pattern*)pattern_c->grid())->mapping.open( Mapping::INSTRUMENT, o->text() );
656 pattern_c->changed_mapping();
658 pattern_key_combo->deactivate();
661 if ( 0 == strncmp( picked, "Scale", strlen( "Scale" ) ) )
663 ((pattern*)pattern_c->grid())->mapping.open( Mapping::SCALE, o->text() );
665 pattern_c->changed_mapping();
667 pattern_key_combo->activate();
669 xywh {609 734 30 24} labeltype NO_LABEL
670 code0 {update_mapping_menu();}
672 Submenu mapping_scale_menu {
676 Submenu mapping_instrument_menu {
677 label Instrument open
681 Fl_Choice pattern_key_combo {
683 callback {((pattern*)pattern_c->grid())->mapping.key( o->value() );
685 pattern_c->changed_mapping();}
686 xywh {674 734 75 24} down_box BORDER_BOX when 1
737 Fl_Choice pattern_note_combo {
739 callback {((pattern*)pattern_c->grid())->note( atoi( o->menu()[ o->value() ].text ));}
740 xywh {704 700 45 24} down_box BORDER_BOX when 1
768 xywh {60 60 40 25} divider
787 Fl_Choice pattern_res_combo {
788 label {&Resolution 1/}
789 callback {pattern_c->grid()->resolution( atoi( o->menu()[ o->value() ].text ));}
790 xywh {584 700 55 24} down_box BORDER_BOX when 1
814 xywh {90 90 40 25} divider
842 xywh {1 776 782 31} box UP_BOX align 84
843 code0 {o->label( NULL );}
845 Fl_Box transport_state {
847 callback {const char *s = "INVALID";
849 if ( transport.master )
851 else if ( transport.valid )
854 if ( s != o->label() )
857 if ( ! strcmp( s, "INVALID" ) )
858 o->color( fl_darker( FL_RED ) );
860 o->color( fl_darker( FL_GREEN ) );
862 xywh {783 776 82 31} box THIN_UP_BOX align 64
865 Fl_Group pan_indicators {open
866 xywh {370 692 120 20}
868 Fl_Box scroll_up_box {
872 Fl_Box scroll_down_box {
876 Fl_Box scroll_left_box {
878 xywh {370 692 30 18} hide
880 Fl_Box scroll_right_box {
882 xywh {460 692 30 18} hide
888 Fl_Menu_Bar menu_bar {open
889 xywh {0 0 865 30} color 47
893 xywh {0 0 100 20} color 37
897 callback {if ( maybe_save_song() )
902 update_pattern_widgets();
903 update_sequence_widgets();
904 update_phrase_widgets();
907 gui_status( "New song." );
913 callback {char *name = fl_file_chooser( "Open File", "Non Files (*.non)", NULL, 0 );
917 if ( ! load_song( name ) )
918 fl_alert( "Could not load song!" );
920 gui_status( "Song opened." );
922 update_sequence_widgets();
923 update_pattern_widgets();
924 update_phrase_widgets();
926 playback_mode_menu->value( song.play_mode );
927 playback_mode_menu->redraw();
929 xywh {0 0 40 25} shortcut 0x4006f color 37
933 callback {save_dialog( song.filename );}
934 xywh {0 0 40 25} shortcut 0x40073 color 37 deactivate
935 code0 {song.signal_dirty.connect( sigc::mem_fun( o, &Fl_Menu_Item::activate ) );}
936 code1 {song.signal_clean.connect( sigc::mem_fun( o, &Fl_Menu_Item::deactivate ) );}
938 MenuItem menu_save_as {
940 callback {save_dialog( NULL );}
945 callback {char *name = fl_file_chooser( "MIDI Import", "MIDI Files (*.mid)", NULL, 0 );
952 if ( ! f.open( name, smf::READ ) )
954 fl_message( "could not open file" );
960 switch ( f.format() )
963 if ( ! pattern::import( &f, 0 ) )
964 fl_message( "Error importing MIDI" );
968 char **sa = f.track_listing();
972 List_Chooser tc( "Select tracks to import:", "Import" );
975 for ( int i = 0; (s = sa[i]); ++i )
989 for ( int i = 1; i <= tc.browser->size(); ++i )
991 if ( tc.browser->selected( i ) )
993 if ( pattern::import( &f , i - 1 ) )
996 WARNING( "error importing track %d", i - 1 );
1000 // fl_message( "%d patterns imported.", n );
1001 gui_status( "Imported %d tracks as patterns", n );
1008 code0 {\#include "../smf.H"}
1012 callback {// Fl_File_Chooser::custom_filter_label = "*.mid";
1014 Fl_File_Chooser *fc = new Fl_File_Chooser( ".", "MIDI Files (*.mid)", Fl_File_Chooser::CREATE, "MIDI Export" );
1018 // wait for user to make a choice
1019 while( fc->shown() )
1022 if ( ! fc->value() )
1025 if ( tabs->value() == pattern_tab )
1026 ((pattern*)pattern_c->grid())->save( fc->value() );}
1028 code0 {\#include <FL/Fl_File_Chooser.H>}
1032 callback {main_window->do_callback();}
1033 xywh {0 0 40 25} shortcut 0x40071 color 37
1038 xywh {0 0 74 25} color 37
1042 callback {event_editor( pattern_c->grid() );}
1046 label {&Randomization Settings}
1047 callback {randomization_dialog->show();}
1053 xywh {10 10 74 25} color 37
1057 callback {int val = o->menu()[ o->value() ].value();
1060 vmetro_widget->show();
1062 vmetro_widget->hide();}
1063 xywh {0 0 40 25} type Toggle value 1
1067 callback {int val = o->menu()[ o->value() ].value();
1069 pattern_c->row_compact( val ? Canvas::ON : Canvas::OFF );
1071 pattern_canvas_widget->redraw();}
1072 xywh {10 10 40 25} type Toggle value 1
1075 label {&Follow Playhead}
1076 callback {int val = o->menu()[ o->value() ].value();
1078 config.follow_playhead = val ? true : false;}
1079 xywh {10 10 40 25} type Toggle value 1
1082 label {Note Shape} open
1087 callback {pattern::note_shape = BOX;
1088 pattern_canvas_widget->redraw();}
1089 xywh {0 0 40 24} type Radio
1093 callback {pattern::note_shape = SQUARE;
1094 pattern_canvas_widget->redraw();}
1095 xywh {0 0 40 24} type Radio value 1
1100 callback {fl_theme_chooser();}
1106 xywh {100 0 74 25} color 37
1110 callback {show_help_dialog( "KEYS" );}
1115 callback {show_help_dialog( "MANUAL" );}
1116 xywh {10 10 40 25} divider
1120 callback {About_Dialog ab( PIXMAP_PATH "/non-sequencer/icon-256x256.png" );
1122 ab.logo_box->label( VERSION );
1124 ab.title->label( "The Non Sequencer" );
1126 ab.copyright->label( "Copyright (C) 2007-2012 Jonathan Moore Liles" );
1127 ab.credits->label( "Non-Sequencer was written from scratch by\\nJonathan Moore Liles for his own use\\n(see the manual).\\n\\nNobody planned. Nobody helped.\\nYou can help now by donating time, money,\\nand/or replacing the rest of Linux Audio\\nwith fast, light, reliable alternatives.\\n" );
1129 ab.website_url->label( "http://non-sequencer.tuxfamily.org" );
1132 xywh {0 0 40 25} color 37
1133 code0 {\#include "../non.H"}
1137 Fl_Button sm_indicator {
1139 xywh {825 8 35 15} box ROUNDED_BOX down_box ROUNDED_BOX color 46 selection_color 93 labelfont 3 labelcolor 39 deactivate
1144 Function {make_seq_window()} {open
1146 Fl_Window seq_window {
1147 label {Non Sequencer - Sequence}
1148 callback {sequence_tab->activate();
1150 detach_button->value( 0 );} open
1151 xywh {681 189 876 675} type Double hide resizable
1153 Fl_Group seq_detached_group {open
1154 xywh {0 0 876 675} resizable
1158 Function {make_randomization_dialog()} {} {
1159 Fl_Window randomization_dialog {
1160 label {Randomization Settings} open
1161 xywh {656 39 340 95} type Double hide
1162 code0 {// feel->value( )}
1163 code1 {probability->value( song.random.probability );} non_modal
1167 callback {song.random.feel = atoi( o->menu()[ find_numeric_menu_item( o->menu(), o->value() ) ].text );} open
1168 xywh {67 55 50 24} down_box BORDER_BOX
1184 label {Randomization Settings}
1185 xywh {10 15 321 28} box ROUNDED_BOX color 94 labelsize 22 labelcolor 39
1187 Fl_Counter probability {
1189 callback {song.random.probability = o->value();}
1190 xywh {216 53 112 26} type Simple align 4 when 4 minimum 0 maximum 1 step 0.01
1194 Function {update_pattern_widgets()} {open
1196 code {if ( ! pattern_settings_group )
1199 pattern *g = (pattern *)pattern_c->grid();
1201 pattern_number_spinner->value( g->number() );
1202 pattern_name_field->value( g->name() );
1203 pattern_channel_spinner->value( 1 + g->channel() );
1204 pattern_port_spinner->value( 1 + g->port() );
1205 pattern_solo_button->value( g->mode() == SOLO );
1206 pattern_mute_button->value( g->mode() == MUTE );
1208 if ( g->mapping.key() == -1 )
1209 pattern_key_combo->deactivate();
1212 pattern_key_combo->activate();
1213 pattern_key_combo->value( g->mapping.key() );
1216 mapping_text->value( g->mapping.name() );
1220 pattern_note_combo->value( find_numeric_menu_item( menu_pattern_note_combo, g->note() ));
1221 pattern_res_combo->value( find_numeric_menu_item( menu_pattern_res_combo, g->resolution() ));
1224 pattern_notes_buffer->text( g->notes() );
1226 pattern_notes_buffer->text( strdup( "" ) );} {}
1228 Function {update_phrase_widgets()} {} {
1229 code {phrase *g = (phrase *)phrase_c->grid();
1235 g->viewport.h = pattern::patterns();
1236 phrase_c->resize_grid();
1237 phrase_c->changed_mapping();
1238 phrase_number_spinner->value( g->number() );
1239 phrase_name_field->value( g->name() );
1240 phrase_solo_button->value( g->mode() == SOLO );
1241 phrase_mute_button->value( g->mode() == MUTE );
1244 phrase_notes_buffer->text( g->notes() );
1246 phrase_notes_buffer->text( strdup( "" ) );} {}
1248 Function {update_sequence_widgets()} {open
1250 code {if ( playlist->notes() )
1251 sequence_notes_buffer->text( playlist->notes() );
1253 sequence_notes_buffer->text( strdup( "" ) );
1255 sequence_name_field->value( playlist->name() );
1257 sequence_phrase_choice->clear();
1259 for ( int i = 1; i <= phrase::phrases(); i++ )
1261 phrase *p = phrase::phrase_by_number( i );
1264 sequence_phrase_choice->add( p->name() );
1268 Fl_Browser *o = playlist_browser;
1270 int val = o->value();
1274 char *s = playlist->dump();
1276 char *l = strtok( s, "\\n" );
1278 o->add( "@b@C2Bar\\t@b@C2\#\\t@b@C2Name" );
1285 while ( ( l = strtok( NULL, "\\n" ) ) )
1295 if ( playback_mode_menu )
1296 playback_mode_menu->value( song.play_mode );} {}
1298 Function {update_mapping_menu()} {open
1300 code {char **sa = Instrument::listing();
1305 for ( int i = 0; sa[i]; i++ )
1308 snprintf( pat, 512, "Instrument/%s", sa[i] );
1309 mapping_menu->add( pat, 0, 0, 0, 0 );
1315 sa = Scale::listing();
1316 for ( int i = 0; sa[i]; i++ )
1319 snprintf( pat, 512, "Scale/%s", sa[i] );
1320 mapping_menu->add( pat, 0, 0, 0, 0 );
1325 Function {update_canvas_widgets()} {return_type {static void}
1327 code {if ( pattern_c->grid() )
1328 ui->update_pattern_widgets();
1330 if ( phrase_c->grid() )
1331 ui->update_phrase_widgets();} {}
1333 Function {find_numeric_menu_item( const Fl_Menu_Item *menu, int n )} {return_type {static int}
1335 code {for ( unsigned int i = 0; menu[i].text; i++ )
1337 if ( atoi( menu[i].text ) == n )
1343 Function {save_dialog( const char *name )} {open return_type void
1348 Fl_File_Chooser *fc = new Fl_File_Chooser( ".", "Non Sequences (*.non)", Fl_File_Chooser::CREATE, "Save sequence" );
1352 // wait for user to make a choice
1353 while( fc->shown() )
1356 if ( ! fc->value() )
1362 if ( ! save_song( name ) )
1363 fl_alert( "Could not save song" );
1365 gui_status( "Saved." );} {}
1367 Function {show_help_dialog( const char *file )} {return_type void
1369 code {char pat[256];
1371 snprintf( pat, 256, "file://%s/non-sequencer/%s.html", DOCUMENT_PATH, file );
1373 open_url( pat );} {}
1375 Function {maybe_save_song()} {open return_type bool
1377 code {if ( song.dirty() )
1379 int c = fl_choice( "Song has been modified since last save. What shall I do?", "&Cancel", "&Save", "&Discard" );
1387 save_dialog( song.filename );
1396 Function {switch_to_pattern( int n )} {return_type void
1398 code {pattern *p = pattern::pattern_by_number( n );
1405 tabs->value( pattern_tab );
1407 pattern_canvas_widget->take_focus();
1409 pattern_c->grid( p );
1411 // update_pattern_widgets();
1414 Function {edit_instrument_row( Instrument *i, int n )} {open return_type void
1416 code {Instrument_Editor ie;
1424 Function {shortcut_handler( int e )} {return_type int
1426 code {if ( e != FL_SHORTCUT )
1430 // this is for mainwindow shortcuts only, ignore all other windows.
1431 if ( Fl::first_window() != ui->main_window )
1436 // shortcuts that don't fit anywhere else (widgets that don't take shortcuts, etc.)
1438 \#define KEY(key) ((Fl::test_shortcut( (key) )))
1441 if KEY( FL_ALT + 's' )
1443 ui->tabs->value( ui->sequence_tab );
1444 ui->tabs->do_callback();
1447 if KEY( FL_ALT + 'a' )
1449 ui->tabs->value( ui->phrase_tab );
1450 ui->tabs->do_callback();
1453 if KEY( FL_ALT + 'p' )
1455 ui->tabs->value( ui->pattern_tab );
1456 ui->tabs->do_callback();
1459 if KEY( FL_ALT + 'c' )
1460 ui->pattern_channel_spinner->take_focus();
1462 if KEY( FL_ALT + 'o' )
1463 ui->pattern_port_spinner->take_focus();
1465 if KEY( FL_ALT + 'i' )
1466 ui->mapping_menu->take_focus();
1470 return processed;} {}
1473 class O_Canvas {open : {public Fl_Widget}
1475 decl {Canvas *_c;} {private local
1477 decl {bool _border_drawn;} {private local
1479 Function {O_Canvas( int X, int Y, int W, int H, const char*L=0) : Fl_Widget(X,Y,W,H,L)} {open
1482 _border_drawn = false;
1483 box(FL_FLAT_BOX);} {}
1485 Function {handle( int m )} {open return_type int
1487 code {// Accept focus if offered.
1488 if ( m == FL_FOCUS || m == FL_UNFOCUS )
1490 _border_drawn = false;
1495 // Hack in click-to-focus
1497 if ( Fl::event_inside( this ) )
1501 if ( Fl_Widget::handle( m ) )
1504 // Ignore events unless we have the focus.
1505 if ( this != Fl::focus() )
1508 // MESSAGE( "got event %i for canvas %p", m, _c );
1514 p = canvas_input_callback( this, _c, m );
1519 Function {resize( int x, int y, int w, int h )} {open
1521 code {Fl_Widget::resize( x, y, w, h );
1525 DMESSAGE( "Resizing canvas." );
1526 _c->resize( x + 1, y + 1, w - 1, h - 1 );
1530 // Fl_Window::resize( x, y, w, h );} {}
1532 Function {draw()} {open return_type void
1534 code {draw_border();
1536 //if ( ! takesevents() )
1542 if ( damage() & FL_DAMAGE_ALL ) printf( " damage_all" );
1543 if ( damage() & FL_DAMAGE_SCROLL ) printf( " damage_scroll" );
1544 if ( damage() & FL_DAMAGE_USER1 ) printf( " damage_user1" );
1545 if ( damage() & FL_DAMAGE_USER2 ) printf( " damage_user2" );
1546 if ( damage() & FL_DAMAGE_EXPOSE ) printf( " damage_expose" );
1550 if ( damage() & FL_DAMAGE_ALL )
1552 draw_box( FL_FLAT_BOX, x(), y(), w(), h(), canvas_background_color );
1553 _border_drawn = false;
1556 _c->draw_playhead();
1560 if ( damage() & FL_DAMAGE_SCROLL )
1565 if ( damage() & FL_DAMAGE_USER1 )
1568 _c->draw_playhead();
1574 WARNING( "No canvas set for widget." );
1577 Function {set_canvas( Canvas *c )} {open
1581 _c->resize( x(), y(), w(), h() );
1583 _c->signal_draw.connect( sigc::mem_fun( this, &O_Canvas::redraw_notes ) );
1584 _c->signal_resize.connect( sigc::mem_fun( this, &O_Canvas::clear ) );
1586 _c->signal_settings_change.connect( sigc::ptr_fun( &UI::update_canvas_widgets ) );
1587 _c->signal_settings_change.connect( sigc::mem_fun( song, &song_settings::set_dirty ) );} {}
1589 Function {click_to_focus()} {open return_type bool
1591 code {return true;} {}
1593 Function {clear( void )} {open return_type void
1597 Function {redraw_notes( void )} {open return_type void
1599 code {damage( FL_DAMAGE_SCROLL );
1601 // this might be called from within draw(), in which case the above does nothing.} {}
1603 Function {redraw_playhead( void )} {open return_type void
1605 code {if ( _c && _c->playhead_moved() )
1607 damage( FL_DAMAGE_USER1 );
1610 Function {draw_border()} {open return_type void
1612 code {if ( _border_drawn )
1615 if ( this != Fl::focus() )
1618 fl_color( FL_BLACK );
1620 fl_line_style( FL_DASH );
1621 fl_rect( x(), y(), w(), h() );
1622 fl_line_style( FL_SOLID );
1624 _border_drawn = true;} {}
1626 Function {handle_pan( void )} {open return_type void
1628 code {int up, left, right, down;
1632 _c->can_scroll( &left, &right, &up, &down );
1635 ui->scroll_left_box->hide();
1637 ui->scroll_left_box->show();
1640 ui->scroll_up_box->hide();
1642 ui->scroll_up_box->show();
1645 ui->scroll_down_box->hide();
1647 ui->scroll_down_box->show();
1649 ui->scroll_right_box->hide();} {}
1653 class Instrument_Editor {} {
1654 Function {Instrument_Editor()} {open return_type void
1656 code {make_window();} {}
1658 decl {Instrument *_inst;} {private local
1660 decl {int _note;} {private local
1662 Function {make_window()} {open
1665 label {Instrument Editor}
1666 callback {done->do_callback();} open
1667 xywh {670 458 335 190} type Double hide
1670 label {Instrument Row}
1671 xywh {8 15 321 28} box ROUNDED_BOX color 94 labelsize 22 labelcolor 39
1673 Fl_Input name_field {
1675 callback {_inst->note_name( _note, strdup( o->value() ) );}
1676 xywh {10 70 321 25} selection_color 48 align 1 when 1 textcolor 32
1678 Fl_Value_Slider volume_slider {
1680 callback {_inst->velocity( _note, o->value() );}
1681 xywh {10 112 321 27} type Horizontal align 1 maximum 100 step 1 textsize 14
1683 Fl_Value_Output note_field {
1687 Fl_Return_Button done {
1689 callback {if ( _inst )
1693 xywh {255 157 76 25}
1697 Function {set( Instrument *i, int n )} {open return_type void
1702 volume_slider->value( i->velocity( n ) );
1703 name_field->value( i->note_name( n ) );
1704 note_field->value( n );} {}
1706 Function {run()} {open return_type void
1708 code {window->show();
1710 while ( window->shown() )
1715 class Trigger {open : {public Fl_Dial}
1717 Function {Trigger( int X, int Y, int W, int H, const char *L ) : Fl_Dial( X, Y, W, H, L )} {open
1721 Function {handle( int m )} {open return_type int
1729 switch ( Fl::event_button() )
1733 pattern *p = pattern::pattern_by_number( atoi( label() ) );
1737 if ( TRIGGER == song.play_mode )
1746 if ( p->mode() == PLAY )
1757 pattern *p = pattern::pattern_by_number( atoi( label() ) );
1761 if ( p->mode() != SOLO )
1771 ui->switch_to_pattern( atoi( label() ) );
1786 r = Fl_Widget::handle( m );
1795 widget_class Triggers {open
1796 xywh {335 80 1278 1003} type Double hide resizable
1798 code1 {\#include <FL/Fl_Dial.H>}
1804 Function {populate( void )} {open private return_type void
1808 int bw = (w() / 16);
1809 int bh = h() / (128/ 16);
1813 for ( int n = 0; n < 128 ; n += 16 )
1815 Fl_Pack *p = new Fl_Pack( 0, 0, 25, 25 );
1817 p->type( Fl_Pack::HORIZONTAL );
1819 for ( int i = 0; i < 16; i++ )
1822 Trigger *b = new Trigger( 0, 0, bw, 50, "Num" );
1826 sprintf( pat, "%d", n + i + 1 );
1828 b->label( strdup( pat ) );
1831 b->angles( 0, 360 );
1832 b->type( FL_FILL_DIAL );
1833 b->color2( FL_GRAY );
1834 b->box( FL_ROUNDED_BOX );
1835 // b->down_box( FL_ROUNDED_BOX );
1836 b->selection_color( FL_GREEN );
1837 b->color( FL_BLACK );
1838 b->align( FL_ALIGN_CENTER );
1845 p->resize( 0, 0, w(), bh );
1852 rows->resize( x(), y(), w(), h() );
1856 Function {update( void )} {open return_type void
1863 if ( ! takesevents() )
1866 Fl_Color mode_color[3];
1868 // mode_color[PLAY] = fl_color_average( FL_GRAY, FL_GREEN, 0.5 );
1869 mode_color[PLAY] = FL_DARK2;
1870 mode_color[MUTE] = FL_LIGHT2;
1871 mode_color[SOLO] = fl_color_average( FL_GRAY, FL_RED, 0.5 );
1874 for ( i = 0; i < MAX_PATTERN; i++ )
1878 Trigger *b = (Trigger*)(((Fl_Pack*)rows->child( i / 16 ))->child( i % 16 ));
1880 if ( i >= pattern::patterns() )
1882 b->color( FL_BLACK );
1887 pattern *p = pattern::pattern_by_number( i + 1 );
1891 b->color( FL_GRAY );
1893 b->selection_color( mode_color[ p->mode() ] );
1895 if ( p->queue() >= 0 )
1897 if ( _timer % 16 < 8 )
1899 b->color( mode_color[ p->queue() ] );
1903 b->value( (double)p->index() / p->length() );
1912 Function {resize( int X, int Y, int W, int H )} {open return_type void
1914 code {for ( int i = rows->children(); i--; )
1916 Fl_Pack *p = (Fl_Pack*) rows->child( i );
1918 for ( int j = p->children(); j--; )
1920 int bw = W / p->children();
1921 p->child( j )->resize( 0, 0, bw, 25 );;
1924 p->resize( 0, 0, W, H / rows->children() );
1929 Fl_Group::resize( X, Y, W, H );} {}
1931 decl {unsigned long _timer;} {private local