non/gui/ui.fl

1653 lines
41 KiB
Plaintext

# data file for the Fltk User Interface Designer (fluid)
version 1.0107
header_name {.H}
code_name {.C}
comment {//
// Copyright (C) 2008 Jonathan Moore Liles
//
// 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.
//
// This program 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 for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
} {in_source in_header
}
decl {\#include <Fl/Fl_Dial.H>} {public
}
decl {\#include <Fl/Fl_Help_Dialog.H>} {}
decl {\#include "widgets.H"} {}
decl {\#include "event_edit.H"} {}
decl {\#include "../jack.H"} {}
decl {\#include "../lash.H"} {}
decl {extern UI *ui;} {}
decl {class O_Canvas;} {}
decl {class Triggers;} {public
}
decl {Fl_Color canvas_background_color;} {public
}
decl {extern Fl_Color velocity_colors[];} {}
Function {update_transport( void * )} {open return_type void
} {
code {// transport_poll();
handle_midi_input();
lash.process();
ui->vmetro_widget->update();
if ( transport.rolling )
ui->triggers_widget->update();
Fl::repeat_timeout( TRANSPORT_POLL_INTERVAL, update_transport );
static int oldstate = -1;
if ( transport.rolling != oldstate )
{
ui->play_button->label( transport.rolling ? "@square" : "@>" );
oldstate = transport.rolling;
}
// JUST A TEST
if ( transport.rolling )
{
if ( ui->tabs->value() == ui->pattern_tab )
ui->pattern_canvas_widget->draw_playhead();
else
if ( ui->tabs->value() == ui->phrase_tab )
ui->phrase_canvas_widget->draw_playhead();
}} {}
}
class UI {open
} {
decl {Fl_Text_Buffer *sequence_notes_buffer;} {}
decl {Fl_Text_Buffer *pattern_notes_buffer;} {}
decl {Fl_Text_Buffer *phrase_notes_buffer} {}
Function {UI()} {open
} {
code {// Make her pretty
Fl::background( 32, 32, 32 );
Fl::background2( 36, 36, 36 );
Fl::foreground( 255, 255, 255 );
Fl::scheme( "plastic" );
canvas_background_color = FL_GREEN;
main_window = make_main_window();
seq_window = make_seq_window();
make_randomization_dialog();
Fl::add_handler( shortcut_handler );
// use old focus behavior
Fl::visible_focus( 0 );
main_window->show();
Fl::add_timeout( TRANSPORT_POLL_INTERVAL, update_transport );
playlist->signal_new_song.connect( sigc::mem_fun( this, &UI::update_sequence_widgets ) );} {}
}
Function {~UI()} {open
} {
code {delete seq_window;
delete main_window;} {}
}
Function {run()} {open
} {
code {Fl::run();} {}
}
Function {make_main_window()} {open
} {
Fl_Window main_window {
label {Non Sequencer}
callback {// Ignore escape
if ( Fl::event() == FL_SHORTCUT && Fl::event_key() == FL_Escape )
return;
if ( maybe_save_song() )
quit();} open
xywh {635 48 869 801} type Single box PLASTIC_UP_BOX color 37 resizable xclass non size_range {869 801 0 0} visible
} {
Fl_Menu_Bar {} {open
xywh {0 0 869 30} color 37
} {
Submenu {} {
label {&File} open
xywh {0 0 100 20} color 37
} {
MenuItem {} {
label {&New}
callback {if ( transport.rolling )
{
fl_alert( "Can't make new file while the transport is running." );
return;
}
// FIXME: check for dirtiness and ask to save.
if ( maybe_save_song() )
{
init_song();
// Sync the GUI.
update_pattern_widgets();
update_sequence_widgets();
update_phrase_widgets();
}}
xywh {0 0 40 25}
}
MenuItem {} {
label {&Open}
callback {if ( transport.rolling )
{
fl_alert( "Can't open file while transport is rolling." );
return;
}
char *name = fl_file_chooser( "Open File", "Non Files (*.non)", NULL, 0 );
if ( name )
{
if ( ! load_song( name ) )
fl_alert( "Could not load song!" );
update_sequence_widgets();
update_pattern_widgets();
update_phrase_widgets();
playback_mode_menu->value( song.play_mode );
playback_mode_menu->redraw();
}}
xywh {0 0 40 25} shortcut 0x4006f color 37
}
MenuItem {} {
label {&Save}
callback {save_dialog( song.filename );}
xywh {0 0 40 25} shortcut 0x40073 color 37
}
MenuItem {} {
label {Save &As}
callback {save_dialog( NULL );}
xywh {0 0 40 25}
}
MenuItem {} {
label {&Import}
callback {char *name = fl_file_chooser( "MIDI Import", "MIDI Files (*.mid)", NULL, 0 );
if ( ! name )
return;
smf f;
if ( ! f.open( name, smf::READ ) )
{
fl_message( "could not open file" );
return;
}
f.read_header();
switch ( f.format() )
{
case 0:
if ( ! pattern::import( &f, 0 ) )
fl_message( "Error importing MIDI" );
break;
case 1: case 2:
{
char **sa = f.track_listing();
if ( sa && *sa )
{
List_Chooser tc( "Select tracks to import:", "Import" );
char *s;
for ( int i = 0; (s = sa[i]); ++i )
{
tc.add( s );
free( s );
}
free( sa );
tc.show();
while( tc.shown() )
Fl::wait();
int n = 0;
for ( int i = 1; i <= tc.browser->size(); ++i )
{
if ( tc.browser->selected( i ) )
{
if ( pattern::import( &f , i - 1 ) )
++n;
else
WARNING( "error importing track %d", i - 1 );
}
}
// fl_message( "%d patterns imported.", n );
gui_status( "Imported %d tracks as patterns", n );
}
break;
}
}}
xywh {0 0 40 25}
code0 {\#include "../smf.H"}
}
MenuItem {} {
label {&Export}
callback {// Fl_File_Chooser::custom_filter_label = "*.mid";
Fl_File_Chooser *fc = new Fl_File_Chooser( ".", "MIDI Files (*.mid)", Fl_File_Chooser::CREATE, "MIDI Export" );
fc->show();
// wait for user to make a choice
while( fc->shown() )
Fl::wait();
if ( ! fc->value() )
return;
if ( tabs->value() == pattern_tab )
((pattern*)pattern_c->grid())->save( fc->value() );}
xywh {0 0 40 25}
code0 {\#include <Fl/Fl_File_Chooser.H>}
}
MenuItem {} {
label {&Quit}
callback {main_window->do_callback();}
xywh {0 0 40 25} shortcut 0x40071 color 37
}
}
Submenu {} {
label {&Edit} open
xywh {0 0 74 25} color 37
} {
MenuItem {} {
label {&Mapping}
xywh {5 5 40 25} color 37
}
MenuItem {} {
label {&Events}
callback {if ( tabs->value() != pattern_tab )
return;
event_editor( pattern_c->grid() );}
xywh {0 0 40 25}
}
MenuItem {} {
label {&Randomization Settings}
callback {randomization_dialog->show();}
xywh {0 0 40 25}
}
}
Submenu {} {
label {&View} open
xywh {10 10 74 25} color 37
} {
MenuItem {} {
label {&Metronome}
callback {int val = o->menu()[ o->value() ].value();
if ( val )
vmetro_widget->show();
else
vmetro_widget->hide();}
xywh {0 0 40 25} type Toggle value 1
}
MenuItem {} {
label {&Compacted}
callback {int val = o->menu()[ o->value() ].value();
pattern_c->row_compact( val ? Canvas::ON : Canvas::OFF );}
xywh {10 10 40 25} type Toggle value 1
}
MenuItem {} {
label {&Follow Playhead}
callback {int val = o->menu()[ o->value() ].value();
config.follow_playhead = val ? true : false;}
xywh {10 10 40 25} type Toggle value 1
}
}
Submenu {} {
label {&Help} open
xywh {100 0 74 25} color 37
} {
MenuItem {} {
label {&Keys}
callback {show_help_dialog( "KEYS" );}
xywh {0 0 40 25}
}
MenuItem {} {
label {&Manual}
callback {show_help_dialog( "MANUAL" );}
xywh {10 10 40 25} divider
}
MenuItem {} {
label {&About}
callback {make_about_popup();
about_popup->show();}
xywh {0 0 40 25} color 37
code0 {\#include "../non.H"}
}
}
}
Fl_Tabs tabs {
callback {// give this tab's canvas the focus
//if ( o->value() == sequence_tab )
// sequence_canvas_widget->take_focus();
//else
if ( o->value() == phrase_tab )
phrase_canvas_widget->take_focus();
else
if ( o->value() == pattern_tab )
pattern_canvas_widget->take_focus();} open
xywh {0 76 868 701} color 37 labeltype SHADOW_LABEL labelsize 19 when 1
code0 {canvas_background_color = fl_rgb_color( 18, 18, 18 );}
} {
Fl_Group sequence_tab {
label Sequence open
xywh {0 98 868 674} color 37 hide resizable
code0 {update_sequence_widgets();}
} {
Fl_Group {} {open
xywh {10 125 233 502}
} {
Fl_Browser playlist_browser {
label Playlist
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
code0 {static int widths[] = { 40, 30, 0 };}
code1 {o->column_widths( widths ); o->column_char( '\\t' );}
code2 {o->value( 1 );}
}
Fl_Button sequence_phrase_delete_button {
label Delete
callback {int val = playlist_browser->value();
if ( val > 1 )
{
// playlist_browser->value( playlist_browser->value() + 1 );
playlist->remove( val - 2 );
update_sequence_widgets();
if ( ! playlist_browser->value() )
playlist_browser->value( playlist_browser->size() );
}}
xywh {14 566 73 25} shortcut 0xffff color 88 labelcolor 23
}
Fl_Button sequence_phrase_up_button {
label Up
callback {if ( playlist_browser->value() > 2 )
{
playlist->move( playlist_browser->value() - 2, UP );
playlist_browser->value( playlist_browser->value() - 1 );
update_sequence_widgets();
}}
xywh {97 566 65 25} shortcut 0xffbf
}
Fl_Button sequence_phrase_down_button {
label Down
callback {if ( playlist_browser->value() > 1 )
{
playlist->move( playlist_browser->value() - 2, DOWN );
playlist_browser->value( playlist_browser->value() + 1 );
update_sequence_widgets();
}}
xywh {169 566 74 25} shortcut 0xffc0
}
Fl_Menu_Button sequence_phrase_choice {
label {Insert Phrase}
callback {playlist->insert( playlist_browser->value() - 1, o->value() + 1 );
update_sequence_widgets();
int val = playlist_browser->value();
if ( val )
playlist_browser->value( playlist_browser->value() + 1 );
else
playlist_browser->value( playlist_browser->size() );} open
xywh {11 597 232 30} color 63
} {}
}
Fl_Input sequence_name_field {
label {name:}
callback {playlist->name( o->value() );}
xywh {9 635 151 26} color 36 align 20 when 1 textcolor 32
}
Fl_Light_Button detach_button {
label Detach
callback {if ( o->value() )
{
Fl_Group *g = seq_detached_group;
g->add( sequence_tab );
sequence_tab->resize( g->x(), g->y(), g->w(), g->h() );
seq_window->show();
}
else
{
seq_window->hide();
tabs->insert( (Fl_Widget&)*sequence_tab, 0 );
sequence_tab->resize( pattern_tab->x(), pattern_tab->y(), pattern_tab->w(), pattern_tab->h() );
}}
xywh {165 639 78 26}
}
Fl_Text_Editor sequence_notes_edit {
label {Notes:}
callback {playlist->notes( o->buffer()->text() );}
xywh {16 686 844 78} selection_color 48 labelsize 12 align 5 textcolor 94
code0 {o->buffer( sequence_notes_buffer = new Fl_Text_Buffer );}
}
Fl_Box triggers_widget {
label Patterns
xywh {253 125 607 549} box UP_BOX color 72 align 1 resizable
code0 {o->box( FL_NO_BOX );}
class Triggers
}
}
Fl_Group phrase_tab {
label Phrase open
xywh {0 98 868 674} color 37 hide
code0 {update_phrase_widgets();}
} {
Fl_Box phrase_canvas_widget {
label Phrase
xywh {4 102 860 590} box FLAT_BOX color 37 labelsize 100 align 16 resizable
code0 {o->set_canvas( phrase_c );}
code1 {o->box( FL_NO_BOX );}
class O_Canvas
}
Fl_Group {} {open
xywh {10 703 854 60}
} {
Fl_Input phrase_name_field {
label {name:}
callback {phrase_c->grid()->name( strdup( o->value() ) );
// if the name changed..
update_sequence_widgets();}
xywh {10 703 144 25} color 36 align 20 textcolor 32
}
Fl_Spinner phrase_number_spinner {
callback {phrase *p = ((phrase *)phrase_c->grid())->by_number( o->value() );
if ( p )
phrase_c->grid( p );
o->maximum( phrase::phrases() );}
xywh {164 703 40 25} color 36 labeltype NO_LABEL when 1
}
Fl_Light_Button phrase_mute_button {
label Mute
xywh {10 740 88 23} color 37 hide
}
Fl_Light_Button phrase_solo_button {
label Solo
xywh {111 740 87 23} color 37 hide
}
Fl_Text_Editor phrase_notes_edit {
label {Notes:}
callback {phrase_c->grid()->notes( o->buffer()->text() );}
xywh {211 713 653 46} selection_color 48 labelsize 12 textcolor 94 resizable
code0 {o->buffer( phrase_notes_buffer = new Fl_Text_Buffer );}
}
}
}
Fl_Group pattern_tab {
label Pattern open
xywh {0 98 868 674} color 37
code0 {update_pattern_widgets();}
} {
Fl_Box pattern_canvas_widget {
label Pattern
xywh {4 102 860 590} box FLAT_BOX color 37 labelsize 100 align 16 resizable
code0 {\#include "draw.H"}
code1 {o->set_canvas( pattern_c );}
code2 {\#include "input.H"}
code3 {o->box( FL_NO_BOX );}
class O_Canvas
}
Fl_Group {} {open
xywh {4 694 858 77}
} {
Fl_Input pattern_name_field {
label {name:}
callback {pattern_c->grid()->name( strdup( o->value() ) );}
xywh {10 703 144 25} color 36 align 20 when 1 textcolor 32
}
Fl_Spinner pattern_number_spinner {
callback {pattern *p = ((pattern *)pattern_c->grid())->by_number( o->value() );
if ( p )
pattern_c->grid( p );
o->maximum( pattern::patterns() );}
xywh {164 703 40 25} color 36 labeltype NO_LABEL when 1
code0 {o->maximum( 1 );}
code1 {// pattern::signal_create_destroy.connect( sigc::mem_fun( o, static_cast<void (Fl_Spinner::*)(double)>(&Fl_Spinner::maximum) ) );}
}
Fl_Light_Button pattern_mute_button {
label Mute
callback {Grid *g = pattern_c->grid();
g->mode( g->mode() == MUTE ? PLAY : MUTE );
o->value( g->mode() == MUTE );
pattern_solo_button->value( 0 );}
xywh {10 738 90 23} type Normal color 37
code0 {// o->type(FL_RADIO_BUTTON);}
}
Fl_Light_Button pattern_solo_button {
label Solo
callback {Grid *g = pattern_c->grid();
g->mode( g->mode() == SOLO ? PLAY : SOLO );
o->value( g->mode() == SOLO );
pattern_mute_button->value( 0 );}
xywh {110 738 91 23} type Normal color 37
code0 {// o->type( FL_RADIO_BUTTON );}
}
Fl_Text_Editor pattern_notes_edit {
label {Notes:}
callback {pattern_c->grid()->notes( o->buffer()->text() );}
xywh {214 713 243 48} selection_color 48 labelsize 12 textcolor 94 resizable
code0 {o->buffer( pattern_notes_buffer = new Fl_Text_Buffer );}
}
Fl_Group pattern_settings_group {open
xywh {458 694 400 77}
} {
Fl_Spinner pattern_channel_spinner {
label Channel
callback {((pattern *)pattern_c->grid())->channel( o->value() - 1 );}
xywh {815 700 40 24} color 36 when 1
code0 {\#include "../pattern.H"}
code1 {o->maximum( 16 );}
}
Fl_Spinner pattern_port_spinner {
label Port
callback {((pattern *)pattern_c->grid())->port( o->value() - 1 );}
xywh {815 734 40 24} color 36 when 1
code0 {o->maximum( 16 );}
}
Fl_Output mapping_text {
label Mapping
xywh {464 734 145 24} align 20
}
Fl_Menu_Button mapping_menu {
label {@>}
callback {mapping_text->value( o->text() );
char picked[80];
mapping_menu->item_pathname(picked, sizeof(picked)-1 );
if ( 0 == strncmp( picked, "Instrument", strlen( "Instrument" ) ) )
{
((pattern*)pattern_c->grid())->mapping.open( Mapping::INSTRUMENT, o->text() );
pattern_c->changed_mapping();
pattern_key_combo->deactivate();
}
else
if ( 0 == strncmp( picked, "Scale", strlen( "Scale" ) ) )
{
((pattern*)pattern_c->grid())->mapping.open( Mapping::SCALE, o->text() );
pattern_c->changed_mapping();
pattern_key_combo->activate();
}}
xywh {609 734 30 24} labeltype NO_LABEL
code0 {update_mapping_menu();}
} {
Submenu mapping_instrument_menu {
label Instrument open
xywh {10 10 74 25}
} {}
Submenu mapping_scale_menu {
label Scale open
xywh {25 25 74 25}
} {}
}
Fl_Choice pattern_key_combo {
label {&Key}
callback {((pattern*)pattern_c->grid())->mapping.key( o->value() );
pattern_c->changed_mapping();}
xywh {674 734 75 24} down_box BORDER_BOX when 1
} {
MenuItem {} {
label C
xywh {30 30 40 25}
}
MenuItem {} {
label {C\#/Db}
xywh {40 40 40 25}
}
MenuItem {} {
label D
xywh {50 50 40 25}
}
MenuItem {} {
label {D\#/Eb}
xywh {60 60 40 25}
}
MenuItem {} {
label E
xywh {70 70 40 25}
}
MenuItem {} {
label F
xywh {80 80 40 25}
}
MenuItem {} {
label {F\#/Gb}
xywh {90 90 40 25}
}
MenuItem {} {
label G
xywh {100 100 40 25}
}
MenuItem {} {
label {G\#}
xywh {110 110 40 25}
}
MenuItem {} {
label A
xywh {0 0 40 25}
}
MenuItem {} {
label {A\#/Bb}
xywh {10 10 40 25}
}
MenuItem {} {
label B
xywh {20 20 40 25}
}
}
Fl_Choice pattern_note_combo {
label {&Note 1/}
callback {((pattern*)pattern_c->grid())->note( atoi( o->menu()[ o->value() ].text ));}
xywh {704 700 45 24} down_box BORDER_BOX when 1
} {
MenuItem {} {
label 1
xywh {0 0 40 25}
}
MenuItem {} {
label 2
xywh {10 10 40 25}
}
MenuItem {} {
label 4
xywh {20 20 40 25}
}
MenuItem {} {
label 8
xywh {30 30 40 25}
}
MenuItem {} {
label 16
xywh {40 40 40 25}
}
MenuItem {} {
label 32
xywh {50 50 40 25}
}
MenuItem {} {
label 64
xywh {60 60 40 25} divider
}
MenuItem {} {
label 3
xywh {60 60 40 25}
}
MenuItem {} {
label 6
xywh {70 70 40 25}
}
MenuItem {} {
label 12
xywh {80 80 40 25}
}
MenuItem {} {
label 24
xywh {90 90 40 25}
}
}
Fl_Choice pattern_res_combo {
label {&Resolution 1/}
callback {pattern_c->grid()->resolution( atoi( o->menu()[ o->value() ].text ));}
xywh {584 700 55 24} down_box BORDER_BOX when 1
} {
MenuItem {} {
label 4
xywh {30 30 40 25}
}
MenuItem {} {
label 8
xywh {40 40 40 25}
}
MenuItem {} {
label 16
xywh {50 50 40 25}
}
MenuItem {} {
label 32
xywh {60 60 40 25}
}
MenuItem {} {
label 64
xywh {80 80 40 25}
}
MenuItem {} {
label 128
xywh {90 90 40 25} divider
}
MenuItem {} {
label 3
xywh {70 70 40 25}
}
MenuItem {} {
label 6
xywh {80 80 40 25}
}
MenuItem {} {
label 12
xywh {90 90 40 25}
}
MenuItem {} {
label 24
xywh {100 100 40 25}
}
}
}
}
}
}
Fl_Group {} {open
xywh {5 33 853 52}
} {
Fl_Choice playback_mode_menu {
label {Playback &Mode} open
xywh {751 54 107 30} box PLASTIC_DOWN_BOX down_box BORDER_BOX color 37 align 1
} {
MenuItem {} {
label Pattern
callback {song.play_mode = PATTERN;}
xywh {0 0 40 25}
}
MenuItem {} {
label Sequence
callback {song.play_mode = SEQUENCE;}
xywh {10 10 40 25}
}
MenuItem {} {
label Trigger
callback {song.play_mode = TRIGGER;}
xywh {20 20 40 25}
}
}
Fl_Choice record_mode_menu {
label {&Record Mode}
callback {if ( ! transport.recording )
config.record_mode = (record_mode_e)o->value();
else
o->value( config.record_mode );} open
xywh {634 54 107 30} box PLASTIC_DOWN_BOX down_box BORDER_BOX color 37 align 1
} {
MenuItem {} {
label Merge
xywh {10 10 40 25}
}
MenuItem {} {
label Overwrite
xywh {20 20 40 25}
}
MenuItem {} {
label Layer
xywh {30 30 40 25}
}
MenuItem {} {
label New
xywh {40 40 40 25}
}
}
Fl_Pack vmetro_widget {
label Metronome open
xywh {226 37 245 48} type HORIZONTAL box UP_BOX color 40 selection_color 48 labelsize 33 align 0 resizable
code0 {\#include "widgets.H"}
code1 {o->box( FL_NO_BOX );}
class Visual_Metronome
} {}
Fl_Group transport_controls_group {
xywh {481 37 143 48}
} {
Fl_Button play_button {
label {@>}
callback {transport.toggle();}
xywh {531 43 34 35} shortcut 0x20 labeltype ENGRAVED_LABEL
}
Fl_Button rec_button {
label {@circle}
callback {transport.recording = o->value();
if ( o->value() )
{
if ( config.record_mode == NEW )
{
pattern *p = new pattern;
p->length( -1 );
pattern_c->grid( p );
}
((pattern*)pattern_c->grid())->record( 0 );
o->labelcolor( FL_RED );
}
else
{
pattern::recording()->record_stop();
o->labelcolor( FL_WHITE );
}}
xywh {575 43 49 35} type Toggle shortcut 0x80072 selection_color 47 labeltype ENGRAVED_LABEL when 1
}
Fl_Button home_button {
label {@|<}
callback {transport.locate( 0 );}
xywh {481 43 40 35} shortcut 0xff50 labeltype ENGRAVED_LABEL
}
}
Fl_Group {} {open
xywh {5 33 208 38}
} {
Fl_Box {} {
label {BPM:}
xywh {5 37 35 34}
}
Fl_Counter {} {
callback {transport.set_beats_per_minute( o->value() );}
xywh {43 41 97 24} labeltype NO_LABEL align 4
code1 {transport.signal_tempo_change.connect( sigc::mem_fun( o, static_cast<int (Fl_Counter::*)(double)>(&Fl_Counter::value) ) );}
code2 {o->value( transport.beats_per_minute );}
}
Fl_Value_Input {} {
callback {transport.set_beats_per_bar( o->value() );}
xywh {149 41 26 24}
code0 {transport.signal_bpb_change.connect( sigc::mem_fun( o, static_cast<int (Fl_Valuator::*)(double)>(&Fl_Valuator::value) ) );}
code1 {o->value( transport.beats_per_bar );}
}
Fl_Value_Input {} {
callback {transport.set_beat_type( o->value() );}
xywh {189 41 24 24}
code0 {transport.signal_beat_change.connect( sigc::mem_fun( o, static_cast<int (Fl_Valuator::*)(double)>(&Fl_Valuator::value) ) );}
code1 {o->value( transport.beat_type );}
}
Fl_Box {} {
label {/}
xywh {170 41 19 24}
}
}
}
Fl_Output status {
xywh {3 776 861 21} box NO_BOX color 32 labeltype NO_LABEL textcolor 55
}
}
}
Function {make_seq_window()} {} {
Fl_Window seq_window {
callback {sequence_tab->activate();
o->hide();
detach_button->value( 0 );}
xywh {189 27 1278 1003} type Single hide resizable
} {
Fl_Group seq_detached_group {open
xywh {0 0 1277 1003} resizable
} {}
}
}
Function {make_about_popup()} {} {
Fl_Window about_popup {
label About open
xywh {944 405 539 608} type Single non_modal size_range {539 608 539 608} visible
} {
Fl_Box {} {
label VERSION
image {../logo.xpm} xywh {10 29 525 209}
code0 {o->label( VERSION );}
}
Fl_Group {} {open
xywh {26 272 488 272} box ROUNDED_BOX color 51
} {
Fl_Box {} {
label {Copyright (C) 2007-2008 Jonathan Moore Liles}
xywh {26 272 488 32} labeltype SHADOW_LABEL labelfont 1 labelsize 18
}
Fl_Box {} {
label {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.
This program 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 for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.}
xywh {41 311 463 233} labelfont 1 labelsize 12 align 144
}
}
Fl_Button {} {
label {http://non.tuxfamily.org}
callback {system( "x-www-browser http://non.tuxfamily.org &" );}
xywh {178 554 188 30} color 14 labeltype SHADOW_LABEL labelcolor 6
}
Fl_Return_Button {} {
label rock
callback {about_popup->hide();}
xywh {453 570 78 31}
}
}
}
Function {make_randomization_dialog()} {open
} {
Fl_Window randomization_dialog {
label {Randomization Settings} open
xywh {841 360 342 98} type Double
code0 {// feel->value( )}
code1 {probability->value( song.random.probability );} non_modal visible
} {
Fl_Choice feel {
label {Feel: 1/}
callback {song.random.feel = atoi( o->menu()[ find_numeric_menu_item( o->menu(), o->value() ) ].text );} open
xywh {67 55 50 24} down_box BORDER_BOX
} {
MenuItem {} {
label 4
xywh {10 10 40 25}
}
MenuItem {} {
label 8
xywh {0 0 40 25}
}
MenuItem {} {
label 16
xywh {10 10 40 25}
}
}
Fl_Box {} {
label {Randomization Settings}
xywh {10 15 321 28} box ROUNDED_BOX color 94 labelsize 22 labelcolor 39
}
Fl_Counter probability {
label Probability
callback {song.random.probability = o->value();}
xywh {216 53 112 26} type Simple align 4 when 4 minimum 0 maximum 1 step 0.01
}
}
}
Function {update_pattern_widgets()} {} {
code {if ( ! pattern_settings_group )
return;
pattern *g = (pattern *)pattern_c->grid();
pattern_number_spinner->value( g->number() );
pattern_name_field->value( g->name() );
pattern_channel_spinner->value( 1 + g->channel() );
pattern_port_spinner->value( 1 + g->port() );
pattern_solo_button->value( g->mode() == SOLO );
pattern_mute_button->value( g->mode() == MUTE );
if ( g->mapping.key() == -1 )
pattern_key_combo->deactivate();
else
{
pattern_key_combo->activate();
pattern_key_combo->value( g->mapping.key() );
}
mapping_text->value( g->mapping.name() );
pattern_note_combo->value( find_numeric_menu_item( menu_pattern_note_combo, g->note() ));
pattern_res_combo->value( find_numeric_menu_item( menu_pattern_res_combo, g->resolution() ));
if ( g->notes() )
pattern_notes_buffer->text( g->notes() );
else
pattern_notes_buffer->text( strdup( "" ) );} {}
}
Function {update_phrase_widgets()} {open
} {
code {phrase *g = (phrase *)phrase_c->grid();
if ( ! g )
return;
phrase_number_spinner->value( g->number() );
phrase_name_field->value( g->name() );
phrase_solo_button->value( g->mode() == SOLO );
phrase_mute_button->value( g->mode() == MUTE );
if ( g->notes() )
phrase_notes_buffer->text( g->notes() );
else
phrase_notes_buffer->text( strdup( "" ) );} {}
}
Function {update_sequence_widgets()} {open
} {
code {if ( playlist->notes() )
sequence_notes_buffer->text( playlist->notes() );
else
sequence_notes_buffer->text( strdup( "" ) );
sequence_name_field->value( playlist->name() );
sequence_phrase_choice->clear();
for ( int i = 1; i <= phrase::phrases(); i++ )
{
phrase *p = phrase::phrase_by_number( i );
if ( p )
sequence_phrase_choice->add( p->name() );
}
Fl_Browser *o = playlist_browser;
int val = o->value();
o->clear();
char *s = playlist->dump();
char *l = strtok( s, "\\n" );
o->add( "@b@C2Bar\\t@b@C2\#\\t@b@C2Name" );
if ( ! l )
return;
o->add( l );
while ( ( l = strtok( NULL, "\\n" ) ) )
{
o->add( l );
}
o->value( val );
free( s );} {}
}
Function {update_mapping_menu()} {} {
code {char **sa = Instrument::listing();
for ( int i = 0; sa[i]; i++ )
{
char pat[512];
snprintf( pat, 512, "Instrument/%s", sa[i] );
mapping_menu->add( pat, 0, 0, 0, 0 );
free( sa[i] );
}
free( sa );
sa = Scale::listing();
for ( int i = 0; sa[i]; i++ )
{
char pat[512];
snprintf( pat, 512, "Scale/%s", sa[i] );
mapping_menu->add( pat, 0, 0, 0, 0 );
free( sa[i] );
}
free( sa );} {}
}
Function {update_canvas_widgets()} {return_type {static void}
} {
code {if ( pattern_c->grid() )
ui->update_pattern_widgets();
if ( phrase_c->grid() )
ui->update_phrase_widgets();} {}
}
Function {find_numeric_menu_item( const Fl_Menu_Item *menu, int n )} {open return_type {static int}
} {
code {for ( unsigned int i = 0; menu[i].text; i++ )
{
if ( atoi( menu[i].text ) == n )
return i;
}
return 0;} {}
}
Function {save_dialog( const char *name )} {open return_type void
} {
code {if ( ! name )
{
Fl_File_Chooser *fc = new Fl_File_Chooser( ".", "Non Sequences (*.non)", Fl_File_Chooser::CREATE, "Save sequence" );
fc->show();
// wait for user to make a choice
while( fc->shown() )
Fl::wait();
if ( ! fc->value() )
return;
name = fc->value();
}
if ( ! save_song( name ) )
fl_alert( "Could not save song" );} {}
}
Function {show_help_dialog( const char *file )} {open return_type void
} {
code {char pat[256];
snprintf( pat, 256, "%s%s.html", DOCUMENT_PATH, file );
Fl_Help_Dialog *help; // Help dialog
help = new Fl_Help_Dialog;
help->load( pat );
help->show();
// FIXME: need to delete it somehow.
// help->show(1, argv);} {selected
}
}
Function {maybe_save_song()} {open return_type bool
} {
code {if ( song.dirty )
{
int c = fl_choice( "Song has been modified since last save. What shall I do?", "Cancel", "Save", "Discard" );
switch ( c )
{
case 0:
return false;
case 1:
/* SAVE */
save_dialog( song.filename );
break;
case 2:
break;
}
}
return true;} {}
}
Function {switch_to_pattern( int n )} {open return_type void
} {
code {pattern *p = pattern::pattern_by_number( n );
if ( p )
{
tabs->value( pattern_tab );
pattern_canvas_widget->take_focus();
pattern_c->grid( p );
// update_pattern_widgets();
}} {}
}
}
decl {\#include <Fl/Fl_Single_Window.H>} {public
}
class O_Canvas {open : {public Fl_Widget}
} {
decl {Canvas *_c;} {}
decl {bool _border_drawn;} {}
decl {uint _flags;} {}
Function {O_Canvas( int X, int Y, int W, int H, const char*L=0) : Fl_Widget(X,Y,W,H,L)} {open
} {
code {_c = NULL;
_border_drawn = false;
_flags = 0;} {}
}
Function {handle( int m )} {open return_type int
} {
code {// Accept focus if offered.
if ( m == FL_FOCUS || m == FL_UNFOCUS )
{
_border_drawn = false;
draw_playhead();
return 1;
}
// Hack in click-to-focus
if ( m == FL_PUSH )
if ( Fl::event_inside( this ) )
take_focus();
// Ignore events unless we have the focus.
if ( this != Fl::focus() )
return 0;
// MESSAGE( "got event %i for canvas %p", m, _c );
int p = 0;
if ( _c )
{
p = canvas_input_callback( this, _c, m );
}
return p;} {}
}
Function {resize( int x, int y, int w, int h )} {open
} {
code {if ( _c )
{
DEBUG( "Resizing canvas." );
_c->resize( x + 1, y + 1, w - 1, h - 1 );
}
Fl_Widget::resize( x, y, w, h );
// Fl_Window::resize( x, y, w, h );} {}
}
Function {draw()} {open return_type void
} {
code {draw_border();
if ( ! takesevents() )
return;
if ( _c )
{
damage( _flags );
_flags = 0;
/*
if ( damage() & FL_DAMAGE_ALL ) printf( " damage_all" );
if ( damage() & FL_DAMAGE_SCROLL ) printf( " damage_scroll" );
if ( damage() & FL_DAMAGE_USER1 ) printf( " damage_user1" );
if ( damage() & FL_DAMAGE_USER2 ) printf( " damage_user2" );
if ( damage() & FL_DAMAGE_EXPOSE ) printf( " damage_expose" );
printf("\\n");
*/
if ( damage() & (FL_DAMAGE_ALL | FL_DAMAGE_USER2) )
{
_c->redraw();
}
if ( damage() & (FL_DAMAGE_ALL | FL_DAMAGE_SCROLL) )
{
// optimized draw
_c->draw();
}
else
if ( damage() & (FL_DAMAGE_ALL | FL_DAMAGE_USER1) )
{
// playhead
_c->draw_playhead();
}
else
if ( damage() & FL_DAMAGE_ALL )
{
_border_drawn = false;
draw_border();
_c->redraw();
}
}
else
{
WARNING( "No canvas set for widget." );
}} {}
}
Function {set_canvas( Canvas *c )} {open
} {
code {_c = c;
_c->resize( x(), y(), w(), h() );
_c->signal_draw.connect( sigc::mem_fun( this, &O_Canvas::draw_notes ) );
_c->signal_resize.connect( sigc::mem_fun( this, &O_Canvas::clear ) );
_c->signal_settings_change.connect( sigc::ptr_fun( &UI::update_canvas_widgets ) );} {}
}
Function {click_to_focus()} {open return_type bool
} {
code {return true;} {}
}
Function {clear( void )} {open return_type void
} {
code {parent()->parent()->damage( FL_DAMAGE_ALL, x(), y(), w(), h() );
damage( FL_DAMAGE_USER2 );
_flags |= FL_DAMAGE_USER2;} {}
}
Function {draw_notes( void )} {open return_type void
} {
code {damage( FL_DAMAGE_SCROLL );
// this might be called from within draw(), in which case the above does nothing.
_flags |= FL_DAMAGE_SCROLL;} {}
}
Function {draw_playhead( void )} {open return_type void
} {
code {damage( FL_DAMAGE_USER1 );} {}
}
Function {draw_border()} {open return_type void
} {
code {if ( _border_drawn )
return;
if ( this != Fl::focus() )
fl_color( FL_RED );
else
fl_color( FL_BLACK );
fl_line_style( FL_DASH );
fl_rect( x(), y(), w(), h() );
fl_line_style( FL_SOLID );
_border_drawn = true;} {}
}
}
Function {shortcut_handler( int e )} {open return_type int
} {
code {if ( e != FL_SHORTCUT )
return 0;
// this is for mainwindow shortcuts only, ignore all other windows.
if ( Fl::first_window() != ui->main_window )
return 0;
int processed = 0;
// shortcuts that don't fit anywhere else (widgets that don't take shortcuts, etc.)
\#define KEY(key) ((Fl::test_shortcut( (key) )))
processed = 1;
if KEY( FL_ALT + 's' )
{
ui->tabs->value( ui->sequence_tab );
}
else
if KEY( FL_ALT + 'a' )
{
ui->tabs->value( ui->phrase_tab );
((Fl_Group*)ui->tabs->value())->child( 0 )->take_focus();
}
else
if KEY( FL_ALT + 'p' )
{
ui->tabs->value( ui->pattern_tab );
((Fl_Group*)ui->tabs->value())->child( 0 )->take_focus();
}
else
if KEY( FL_ALT + 'c' )
ui->pattern_channel_spinner->take_focus();
else
if KEY( FL_ALT + 'o' )
ui->pattern_port_spinner->take_focus();
else
if KEY( FL_ALT + 'i' )
ui->mapping_menu->take_focus();
else
processed = 0;
return processed;} {}
}
class Trigger {open : {public Fl_Dial}
} {
Function {Trigger( int X, int Y, int W, int H, const char *L = 0 ) : Fl_Dial( X, Y, W, H, L )} {open
} {}
Function {handle( int m )} {open return_type int
} {
code {int r = 0;
switch ( m )
{
case FL_PUSH:
{
switch ( Fl::event_button() )
{
case 1:
{
pattern *p = pattern::pattern_by_number( atoi( label() ) );
if ( p )
{
if ( p->mode() == MUTE )
p->mode( PLAY );
else
p->mode( MUTE );
}
break;
}
case 2:
{
pattern *p = pattern::pattern_by_number( atoi( label() ) );
if ( p )
{
if ( p->mode() != SOLO )
p->mode( SOLO );
else
p->mode( PLAY );
}
break;
}
case 3:
{
ui->switch_to_pattern( atoi( label() ) );
}
break;
}
r = 1;
break;
}
case FL_RELEASE:
MESSAGE("doing callback");
do_callback();
r = 1;
break;
case FL_DRAG:
r = 1;
break;
default:
r = Fl_Widget::handle( m );
break;
}
return r;} {}
}
}
widget_class Triggers {open
xywh {121 31 1278 1003} type Double hide resizable
code0 {populate();}
code1 {\#include <Fl/Fl_Dial.H>}
class Fl_Group
} {
Fl_Pack rows {open
xywh {25 25 15 15}
code0 {// o->position( x(), y() );}
} {}
Function {populate( void )} {open private return_type void
} {
code {int bw = (w() / 16);
int bh = h() / (128/ 16);
begin();
for ( int n = 0; n < 128 ; n += 16 )
{
Fl_Pack *p = new Fl_Pack( 0, 0, 25, 25 );
p->type( Fl_Pack::HORIZONTAL );
for ( int i = 0; i < 16; i++ )
{
Trigger *b = new Trigger( 0, 0, bw, 50, "Num" );
char pat[4];
sprintf( pat, "%d", n + i + 1 );
b->label( strdup( pat ) );
b->minimum( 0 );
b->maximum( 1 );
b->angles( 0, 360 );
b->type( FL_FILL_DIAL );
// b->box( FL_ROUNDED_BOX );
// b->down_box( FL_ROUNDED_BOX );
b->selection_color( FL_GREEN );
b->color( FL_BLACK );
b->align( FL_ALIGN_CENTER );
p->add( b );
}
p->end();
p->resize( 0, 0, w(), bh );
rows->add( p );
}
end();
rows->resize( x(), y(), w(), h() );
redraw();} {}
}
Function {update( void )} {open return_type void
} {
code {if ( ! takesevents() )
return;
int i;
for ( i = 0; i < MAX_PATTERN; i++ )
{
Trigger *b = (Trigger*)(((Fl_Pack*)rows->child( i / 16 ))->child( i % 16 ));
if ( i >= pattern::patterns() )
{
b->color( FL_BLACK );
b->value( 0 );
continue;
}
pattern *p = pattern::pattern_by_number( i + 1 );
if ( p->playing() )
{
b->color( fl_lighter( FL_GRAY ) );
Fl_Color c;
switch ( p->mode() )
{
case MUTE:
c = FL_GRAY;
break;
case SOLO:
c = FL_RED;
break;
case PLAY:
c = FL_GREEN;
break;
}
b->selection_color( c );
b->value( (double)p->index() / p->length() );
}
else
{
b->value( 0 );
}
}} {}
}
Function {resize( int X, int Y, int W, int H )} {open return_type void
} {
code {for ( int i = rows->children(); i--; )
{
Fl_Pack *p = (Fl_Pack*) rows->child( i );
for ( int j = p->children(); j--; )
{
int bw = W / p->children();
p->child( j )->resize( 0, 0, bw, 25 );;
}
p->resize( 0, 0, W, H / rows->children() );
p->redraw();
}
Fl_Group::resize( X, Y, W, H );} {}
}
}