Assists music production by grouping standalone programs into sessions. Community version of "Non Session Manager".
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2052 lines
54KB

  1. # data file for the Fltk User Interface Designer (fluid)
  2. version 1.0300
  3. header_name {.H}
  4. code_name {.C}
  5. comment {//
  6. // Copyright (C) 2008 Jonathan Moore Liles
  7. //
  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.
  12. //
  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.
  17. //
  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.
  21. //
  22. } {in_source in_header
  23. }
  24. decl {\#include <FL/Fl_Dial.H>} {public local
  25. }
  26. decl {\#include <About_Dialog.H>} {private local
  27. }
  28. decl {class Fl_Scalepack;} {public local
  29. }
  30. decl {class Fl_Sometimes_Input;} {public local
  31. }
  32. decl {\#include <Fl_Flowpack.H>} {public global
  33. }
  34. decl {\#include <FL/Fl_Overlay_Window.H>} {public local
  35. }
  36. decl {\#include <FL/Fl_Theme_Chooser.H>} {private local
  37. }
  38. decl {\#include <FL/Fl_Progress.H>} {public global
  39. }
  40. decl {\#include <Fl_Scalepack.H>} {private local
  41. }
  42. decl {\#include <Fl_Sometimes_Input.H>} {private local
  43. }
  44. decl {\#include <Fl_Menu_Settings.H>} {private local
  45. }
  46. decl {\#include <FL/Fl_Shared_Image.H>} {private local
  47. }
  48. decl {\#include <math.h>} {private local
  49. }
  50. decl {\#include "event_edit.H"} {private local
  51. }
  52. decl {\#include "../jack.H"} {private local
  53. }
  54. decl {\#include "../NSM.H"} {private local
  55. }
  56. decl {extern NSM_Client *nsm;} {private local
  57. }
  58. decl {\#include "../transport.H"} {private local
  59. }
  60. decl {extern UI *ui;} {private local
  61. }
  62. decl {class O_Canvas;} {private local
  63. }
  64. decl {class Triggers;} {public local
  65. }
  66. decl {class Instrument_Editor;} {private local
  67. }
  68. decl {Fl_Color canvas_background_color;} {public local
  69. }
  70. decl {Fl_Color velocity_colors[128];} {public local
  71. }
  72. Function {init_colors()} {open private C return_type {static void}
  73. } {
  74. code {unsigned int i;
  75. /* velocity colors */
  76. Fl_Color lo = fl_color_average( FL_CYAN, FL_BLACK, 0.10 );
  77. Fl_Color hi = fl_color_average( FL_CYAN, FL_WHITE, 0.80 );
  78. for ( i = 128; i--; )
  79. {
  80. velocity_colors[i] = fl_color_average( hi, lo, 1.0 * ((float)i / 128) );
  81. }} {}
  82. }
  83. widget_class Visual_Metronome {open
  84. xywh {1166 936 100 100} type Double visible
  85. } {
  86. Fl_Slider progress {
  87. private xywh {139 115 1149 23} type Horizontal box FLAT_BOX color 7 selection_color 54
  88. code0 {o->resize( x(), (y() + h()) - (h() / 3), w(), h() / 3 );}
  89. code1 {o->slider_size( 0.25 );}
  90. code2 {o->slider( FL_FLAT_BOX );}
  91. }
  92. Function {draw(void)} {open protected return_type void
  93. } {
  94. code {if ( damage() & ~FL_DAMAGE_CHILD )
  95. {
  96. int bw = w() / _bpb;
  97. int b = _bpb;
  98. if ( b )
  99. {
  100. for ( int i = 0; i < b; ++i )
  101. {
  102. if ( i == _beat )
  103. fl_color( velocity_colors[ i * 127 / _bpb ] );
  104. else
  105. fl_color( FL_GRAY );
  106. int X = x() + ( i * bw );
  107. int Y = y();
  108. int W = bw;
  109. int H = h() - 14;
  110. fl_rectf(X,Y,W,H);
  111. fl_color( fl_darker( fl_color() ) );
  112. fl_rect( X,Y,W,H);
  113. char pat[4];
  114. snprintf( pat, sizeof(pat), "%d", i + 1 );
  115. fl_font( FL_HELVETICA_BOLD, 24 );
  116. fl_draw( pat, X,Y,W,H, FL_ALIGN_CENTER );
  117. }
  118. }
  119. }
  120. progress->resize( x(), y() + h() - 14, w(), 14 );
  121. if ( damage() & FL_DAMAGE_CHILD )
  122. update_child( *progress );
  123. else
  124. draw_child( *progress );
  125. // _flip = ! _flip;} {}
  126. }
  127. decl {int _bpb} {private local
  128. }
  129. decl {int _tpb} {private local
  130. }
  131. decl {int _beat} {private local
  132. }
  133. decl {bool _flip} {private local
  134. }
  135. decl {int _tick} {private local
  136. }
  137. Function {bpb( int b )} {open private return_type void
  138. } {
  139. code {if ( b != _bpb )
  140. {
  141. _bpb = b;
  142. redraw();
  143. }} {}
  144. }
  145. Function {tpb( int ticks )} {open private return_type void
  146. } {
  147. code {_tpb = ticks;
  148. progress->minimum( 0 );
  149. progress->maximum( ticks );} {}
  150. }
  151. Function {beat( int b )} {open private return_type void
  152. } {
  153. code {if ( b == _beat || b >= _bpb )
  154. return;
  155. _flip = ! _flip;
  156. _beat = b;
  157. redraw();} {}
  158. }
  159. Function {tick( int tick )} {open private return_type void
  160. } {
  161. code {if ( tick == _tick )
  162. return;
  163. if ( _beat < 0 )
  164. return;
  165. if ( _flip )
  166. {
  167. progress->value( _tpb - tick );
  168. }
  169. else
  170. {
  171. progress->value( tick );
  172. }
  173. _tick = tick;} {}
  174. }
  175. Function {update( void )} {open return_type void
  176. } {
  177. code {if ( transport.beats_per_bar ) {
  178. bpb( transport.beats_per_bar );
  179. tpb( transport.ticks_per_beat );
  180. beat( transport.beat - 1 );
  181. tick( transport.tick - 1 );}} {}
  182. }
  183. code {_bpb = 0;
  184. _tpb = 0;
  185. _beat = 0;
  186. _tick = 0;
  187. _flip = 0;} {}
  188. }
  189. class Overlay_Callback_Window {: {public Fl_Overlay_Window}
  190. } {
  191. decl {void (*_draw_overlay_callback)(void*);} {private local
  192. }
  193. decl {void *_draw_overlay_userdata;} {private local
  194. }
  195. Function {Overlay_Callback_Window(int X, int Y, int W, int H, const char *L=0) : Fl_Overlay_Window(X,Y,W,H,L)} {open
  196. } {
  197. code {_draw_overlay_callback = 0;
  198. _draw_overlay_userdata = 0;} {}
  199. }
  200. Function {Overlay_Callback_Window(int W, int H, const char *L=0) : Fl_Overlay_Window(W,H,L)} {open
  201. } {
  202. code {_draw_overlay_callback = 0;
  203. _draw_overlay_userdata = 0;} {}
  204. }
  205. Function {draw_overlay()} {open return_type {virtual void}
  206. } {
  207. code {if ( _draw_overlay_callback )
  208. _draw_overlay_callback( _draw_overlay_userdata );} {}
  209. }
  210. Function {draw_overlay_callback( void(*cb)(void*), void *v)} {open return_type void
  211. } {
  212. code {_draw_overlay_callback = cb;
  213. _draw_overlay_userdata = v;} {}
  214. }
  215. }
  216. Function {update_transport( void * )} {open return_type void
  217. } {
  218. code {// transport_poll();
  219. handle_midi_input();
  220. ui->progress_group->do_callback();
  221. ui->vmetro_widget->update();
  222. ui->triggers_widget->update();
  223. Fl::repeat_timeout( TRANSPORT_POLL_INTERVAL, update_transport );
  224. static int oldstate = -1;
  225. if ( transport.rolling != oldstate )
  226. {
  227. ui->play_button->label( transport.rolling ? "@square" : "@>" );
  228. oldstate = transport.rolling;
  229. if ( transport.rolling )
  230. {
  231. ui->menu_new->deactivate();
  232. ui->menu_open->deactivate();
  233. }
  234. else
  235. {
  236. ui->menu_new->activate();
  237. ui->menu_open->activate();
  238. }
  239. }
  240. if ( nsm && nsm->is_active() )
  241. {
  242. if ( ui->menu_new->active() )
  243. {
  244. ui->menu_new->deactivate();
  245. ui->menu_open->deactivate();
  246. ui->menu_save_as->deactivate();
  247. }
  248. }
  249. // JUST A TEST
  250. if ( transport.rolling )
  251. {
  252. if ( ui->tabs->value() == ui->pattern_tab )
  253. ui->pattern_canvas_widget->redraw_playhead();
  254. else
  255. if ( ui->tabs->value() == ui->phrase_tab )
  256. ui->phrase_canvas_widget->redraw_playhead();
  257. }
  258. ui->transport_state->do_callback();} {}
  259. }
  260. class UI {open
  261. } {
  262. decl {Fl_Text_Buffer *sequence_notes_buffer;} {private local
  263. }
  264. decl {Fl_Text_Buffer *pattern_notes_buffer;} {private local
  265. }
  266. decl {Fl_Text_Buffer *phrase_notes_buffer} {private local
  267. }
  268. Function {UI()} {open
  269. } {
  270. code {fl_register_images();
  271. canvas_background_color = FL_GREEN;
  272. playback_mode_menu = NULL;
  273. main_window = make_main_window();
  274. seq_window = make_seq_window();
  275. init_colors();
  276. make_randomization_dialog();
  277. // make_instrument_edit_dialog();
  278. // use old focus behavior
  279. Fl::visible_focus( 0 );
  280. // try to fill the screen, but only when the screen is tiny and our window is huge.
  281. {
  282. int sx, sy, sw, sh;
  283. Fl::screen_xywh( sx, sy, sw, sh );
  284. if ( sw < main_window->w() || sh < main_window->h() )
  285. main_window->resize( sx, sy, sw, sh );
  286. }
  287. Fl::add_timeout( TRANSPORT_POLL_INTERVAL, update_transport );
  288. playlist->signal_new_song.connect( sigc::mem_fun( this, &UI::update_sequence_widgets ) );} {}
  289. }
  290. Function {~UI()} {open
  291. } {
  292. code {delete seq_window;
  293. delete main_window;} {}
  294. }
  295. Function {run()} {open
  296. } {
  297. code {Fl::run();} {}
  298. }
  299. Function {load_settings()} {open return_type void
  300. } {
  301. code {char *path;
  302. asprintf( &path, "%s/%s", config.user_config_dir, "view" );
  303. ((Fl_Menu_Settings*)menu_bar)->load( menu_bar->find_item( "&View" ), path );
  304. free( path );} {}
  305. }
  306. Function {save_settings()} {open return_type void
  307. } {
  308. code {char *path;
  309. asprintf( &path, "%s/%s", config.user_config_dir, "view" );
  310. ((Fl_Menu_Settings*)menu_bar)->dump( menu_bar->find_item( "&View" ), path );
  311. free( path );} {}
  312. }
  313. Function {draw_overlay( void *v )} {open protected return_type {static void}
  314. } {
  315. code {((UI*)v)->draw_overlay();} {}
  316. }
  317. Function {draw_overlay()} {open protected return_type void
  318. } {
  319. code {if ( pattern_canvas_widget )
  320. pattern_canvas_widget->draw_overlay();} {}
  321. }
  322. Function {make_main_window()} {open
  323. } {
  324. Fl_Window main_window {
  325. label {Non Sequencer}
  326. callback {// Ignore escape
  327. if ( Fl::event() == FL_SHORTCUT && Fl::event_key() == FL_Escape )
  328. return;
  329. if ( maybe_save_song() )
  330. quit();} open
  331. xywh {750 223 865 805} type Double color 47 resizable
  332. code0 {o->color( FL_BACKGROUND_COLOR );}
  333. code1 {o->draw_overlay_callback( &UI::draw_overlay, this );}
  334. code2 {o->xclass( APP_NAME );}
  335. class Overlay_Callback_Window size_range {700 509 0 0} visible
  336. } {
  337. Fl_Group {} {open
  338. xywh {0 25 865 65} box FLAT_BOX
  339. } {
  340. Fl_Group {} {open
  341. xywh {665 36 195 52}
  342. } {
  343. Fl_Value_Input {} {
  344. label BPM
  345. callback {transport.set_beats_per_minute( o->value() );}
  346. xywh {825 68 35 19} labelsize 9 align 1 when 8 textsize 10
  347. code1 {transport.signal_tempo_change.connect( sigc::mem_fun( o, static_cast<int (Fl_Valuator::*)(double)>(&Fl_Valuator::value) ) );}
  348. code2 {o->value( transport.beats_per_minute );}
  349. }
  350. Fl_Group {} {
  351. label {Time Sig.} open
  352. xywh {756 67 64 21} labelsize 9
  353. } {
  354. Fl_Value_Input {} {
  355. callback {transport.set_beats_per_bar( o->value() );}
  356. xywh {756 68 24 19} textsize 10
  357. code0 {transport.signal_bpb_change.connect( sigc::mem_fun( o, static_cast<int (Fl_Valuator::*)(double)>(&Fl_Valuator::value) ) );}
  358. code1 {o->value( transport.beats_per_bar );}
  359. }
  360. Fl_Box {} {
  361. label {/}
  362. xywh {780 67 14 21}
  363. }
  364. Fl_Value_Input {} {
  365. callback {transport.set_beat_type( o->value() );}
  366. xywh {795 68 24 19} textsize 10
  367. code0 {transport.signal_beat_change.connect( sigc::mem_fun( o, static_cast<int (Fl_Valuator::*)(double)>(&Fl_Valuator::value) ) );}
  368. code1 {o->value( transport.beat_type );}
  369. }
  370. }
  371. Fl_Choice record_mode_menu {
  372. label {Record Mode}
  373. callback {if ( ! transport.recording )
  374. config.record_mode = (record_mode_e)o->value();
  375. else
  376. o->value( config.record_mode );}
  377. xywh {755 36 105 19} box DOWN_BOX down_box BORDER_BOX color 37 labelsize 9 align 1 textsize 9
  378. } {
  379. MenuItem {} {
  380. label Merge
  381. xywh {15 15 40 25} labelfont 3 labelsize 10
  382. }
  383. MenuItem {} {
  384. label Overwrite
  385. xywh {25 25 40 25} labelfont 3 labelsize 10
  386. }
  387. MenuItem {} {
  388. label Layer
  389. xywh {35 35 40 25} labelfont 3 labelsize 10
  390. }
  391. MenuItem {} {
  392. label New
  393. xywh {45 45 40 25} labelfont 3 labelsize 10
  394. }
  395. }
  396. Fl_Choice playback_mode_menu {
  397. label {Playback &Mode}
  398. xywh {665 68 85 19} box DOWN_BOX down_box BORDER_BOX color 37 labelsize 9 align 1
  399. } {
  400. MenuItem {} {
  401. label Pattern
  402. callback {song.play_mode = PATTERN;}
  403. xywh {5 5 40 25} labelfont 3 labelsize 10
  404. }
  405. MenuItem {} {
  406. label Sequence
  407. callback {song.play_mode = SEQUENCE;}
  408. xywh {15 15 40 25} labelfont 3 labelsize 10
  409. }
  410. MenuItem {} {
  411. label Trigger
  412. callback {song.play_mode = TRIGGER;}
  413. xywh {25 25 40 25} labelfont 3 labelsize 10
  414. }
  415. MenuItem {} {
  416. label Queue
  417. callback {song.play_mode = QUEUE;}
  418. xywh {0 0 40 24} labelfont 3 labelsize 10
  419. }
  420. }
  421. Fl_Choice edit_mode_menu {
  422. label {Edit Mode}
  423. xywh {665 36 85 19} box DOWN_BOX down_box BORDER_BOX color 37 labelsize 9 align 1
  424. } {
  425. MenuItem {} {
  426. label Pattern
  427. callback {tabs->value( pattern_tab );
  428. edit_menu->activate();
  429. menu_bar->redraw();}
  430. xywh {15 15 40 25} shortcut 0x80031 labelfont 3 labelsize 10
  431. }
  432. MenuItem {} {
  433. label Phrase
  434. callback {tabs->value( phrase_tab );
  435. edit_menu->activate();
  436. menu_bar->redraw();}
  437. xywh {25 25 40 25} shortcut 0x80032 labelfont 3 labelsize 11
  438. }
  439. MenuItem {} {
  440. label Sequence
  441. callback {tabs->value( sequence_tab );
  442. edit_menu->deactivate();
  443. menu_bar->redraw();}
  444. xywh {25 25 40 25} shortcut 0x80033 labelfont 3 labelsize 10
  445. }
  446. MenuItem {} {
  447. label Trigger
  448. callback {song.play_mode = TRIGGER;}
  449. xywh {35 35 40 25} labelfont 3 labelsize 10 hide deactivate
  450. }
  451. }
  452. }
  453. Fl_Pack vmetro_widget {
  454. label Metronome
  455. xywh {160 27 500 60} type HORIZONTAL box UP_BOX color 40 selection_color 48 labelsize 33 align 0 resizable
  456. code0 {o->box( FL_FLAT_BOX );}
  457. class Visual_Metronome
  458. } {}
  459. Fl_Pack transport_controls_group {open
  460. xywh {4 27 151 60} type HORIZONTAL
  461. code0 {o->spacing( 2 );}
  462. class Fl_Scalepack
  463. } {
  464. Fl_Button play_button {
  465. label {@>}
  466. callback {transport.toggle();}
  467. xywh {10 29 43 38} shortcut 0x20 labeltype ENGRAVED_LABEL
  468. }
  469. Fl_Button rec_button {
  470. label {@circle}
  471. callback {transport.recording = o->value();
  472. if ( o->value() )
  473. {
  474. if ( config.record_mode == NEW )
  475. {
  476. pattern *p = new pattern;
  477. p->length( -1 );
  478. pattern_canvas_widget->grid( p );
  479. }
  480. ((pattern*)pattern_canvas_widget->grid())->record( 0 );
  481. o->labelcolor( FL_RED );
  482. }
  483. else
  484. {
  485. pattern::recording()->record_stop();
  486. o->labelcolor( FL_WHITE );
  487. }}
  488. xywh {60 29 43 38} type Toggle shortcut 0x80072 selection_color 47 labeltype ENGRAVED_LABEL when 1
  489. }
  490. Fl_Button home_button {
  491. label {@|<}
  492. callback {transport.locate( 0 );}
  493. xywh {110 29 43 38} shortcut 0xff50 labeltype ENGRAVED_LABEL
  494. }
  495. }
  496. }
  497. Fl_Tabs tabs {
  498. callback {((Fl_Group*)o->value())->child( 0 )->take_focus();} open
  499. xywh {0 91 865 694} box FLAT_BOX color 47 labeltype SHADOW_LABEL labelsize 19 when 1 resizable
  500. code0 {canvas_background_color = fl_rgb_color( 18, 18, 18 );}
  501. } {
  502. Fl_Group sequence_tab {open
  503. xywh {0 91 865 678} box FLAT_BOX color 37 labeltype NO_LABEL hide resizable
  504. code0 {update_sequence_widgets();}
  505. } {
  506. Fl_Group {} {open
  507. xywh {10 118 233 502} labelsize 12
  508. } {
  509. Fl_Browser playlist_browser {
  510. label Playlist
  511. xywh {10 118 233 435} type Hold box EMBOSSED_BOX color 39 selection_color 30 labelcolor 55 align 1 when 4 textsize 18 textcolor 95 resizable
  512. code0 {static int widths[] = { 40, 30, 0 };}
  513. code1 {o->column_widths( widths ); o->column_char( '\\t' );}
  514. code2 {o->value( 1 );}
  515. }
  516. Fl_Button sequence_phrase_delete_button {
  517. label Delete
  518. callback {int val = playlist_browser->value();
  519. if ( val > 1 )
  520. {
  521. // playlist_browser->value( playlist_browser->value() + 1 );
  522. playlist->remove( val - 2 );
  523. update_sequence_widgets();
  524. if ( ! playlist_browser->value() )
  525. playlist_browser->value( playlist_browser->size() );
  526. }}
  527. xywh {14 559 73 25} shortcut 0xffff color 88 labelcolor 23
  528. }
  529. Fl_Button sequence_phrase_up_button {
  530. label Up
  531. callback {if ( playlist_browser->value() > 2 )
  532. {
  533. playlist->move( playlist_browser->value() - 2, UP );
  534. playlist_browser->value( playlist_browser->value() - 1 );
  535. update_sequence_widgets();
  536. }}
  537. xywh {97 559 65 25} shortcut 0xffbf
  538. }
  539. Fl_Button sequence_phrase_down_button {
  540. label Down
  541. callback {if ( playlist_browser->value() > 1 )
  542. {
  543. playlist->move( playlist_browser->value() - 2, DOWN );
  544. playlist_browser->value( playlist_browser->value() + 1 );
  545. update_sequence_widgets();
  546. }}
  547. xywh {169 559 74 25} shortcut 0xffc0
  548. }
  549. Fl_Menu_Button sequence_phrase_choice {
  550. label {Insert Phrase}
  551. callback {playlist->insert( playlist_browser->value() - 1, o->value() + 1 );
  552. update_sequence_widgets();
  553. int val = playlist_browser->value();
  554. if ( val )
  555. playlist_browser->value( playlist_browser->value() + 1 );
  556. else
  557. playlist_browser->value( playlist_browser->size() );} open
  558. xywh {11 590 232 30} color 63
  559. } {}
  560. }
  561. Fl_Input sequence_name_field {
  562. label {name:}
  563. callback {playlist->name( o->value() );}
  564. xywh {91 733 158 26} color 36 align 20 when 1 textcolor 32
  565. }
  566. Fl_Light_Button detach_button {
  567. label Detach
  568. callback {if ( o->value() )
  569. {
  570. Fl_Group *g = seq_detached_group;
  571. seq_window->show();
  572. g->add( sequence_tab );
  573. sequence_tab->resize( g->x(), g->y(), g->w(), g->h() );
  574. tabs->do_callback();
  575. main_window->redraw();
  576. }
  577. else
  578. {
  579. seq_window->hide();
  580. tabs->insert( (Fl_Widget&)*sequence_tab, 0 );
  581. sequence_tab->resize( pattern_tab->x(), pattern_tab->y(), pattern_tab->w(), pattern_tab->h() );
  582. tabs->do_callback();
  583. }}
  584. xywh {7 733 78 26}
  585. }
  586. Fl_Text_Editor sequence_notes_edit {
  587. label {Notes:}
  588. callback {playlist->notes( o->buffer()->text() );}
  589. xywh {254 684 606 73} selection_color 48 labelsize 12 align 5 textcolor 94
  590. code0 {o->buffer( sequence_notes_buffer = new Fl_Text_Buffer );}
  591. }
  592. Fl_Box triggers_widget {
  593. label Patterns
  594. xywh {253 118 607 549} box FLAT_BOX color 48 align 1 resizable
  595. code0 {o->color( FL_BACKGROUND_COLOR );}
  596. code1 {o->rows( 32 );}
  597. class Triggers
  598. }
  599. Fl_Group progress_group {
  600. callback {if ( ! o->visible_r() )
  601. return;
  602. phrase *p = phrase::phrase_by_number( playlist->playing() );
  603. if ( p )
  604. phrase_progress->value( p->index() / (double)p->length() );
  605. if ( playlist->length() )
  606. sequence_progress->value( playlist->index() / (double)playlist->length() );} open
  607. xywh {10 649 233 66}
  608. } {
  609. Fl_Slider phrase_progress {
  610. label Phrase
  611. xywh {10 649 233 24} type Horizontal labelsize 12 align 1
  612. }
  613. Fl_Slider sequence_progress {
  614. label Sequence
  615. callback {transport.locate( (tick_t)((double)playlist->length() * o->value()) );}
  616. xywh {10 691 233 24} type Horizontal labelsize 12 align 1
  617. }
  618. }
  619. }
  620. Fl_Group phrase_tab {open
  621. xywh {0 91 865 678} box FLAT_BOX color 47 labeltype NO_LABEL hide
  622. code0 {update_phrase_widgets();}
  623. } {
  624. Fl_Box phrase_canvas_widget {
  625. label Phrase
  626. xywh {1 91 863 592} box FLAT_BOX color 37 labelsize 100 align 16 resizable
  627. class Canvas
  628. }
  629. Fl_Group {} {open
  630. xywh {5 690 856 77} box FLAT_BOX color 47
  631. } {
  632. Fl_Input phrase_name_field {
  633. label {name:}
  634. callback {phrase_canvas_widget->grid()->name( strdup( o->value() ) );
  635. // if the name changed..
  636. update_sequence_widgets();}
  637. xywh {5 697 155 24} box ROUNDED_BOX color 49 labelfont 2 labelcolor 55 align 20 textfont 2
  638. code0 {o->up_box( FL_ROUNDED_BOX );}
  639. class Fl_Sometimes_Input
  640. }
  641. Fl_Light_Button phrase_mute_button {
  642. label Mute
  643. xywh {5 733 93 23} color 37 hide
  644. }
  645. Fl_Light_Button phrase_solo_button {
  646. label Solo
  647. xywh {111 733 87 23} color 37 hide
  648. }
  649. Fl_Text_Editor phrase_notes_edit {
  650. label {Notes:}
  651. callback {phrase_canvas_widget->grid()->notes( o->buffer()->text() );}
  652. xywh {170 702 685 58} selection_color 48 labelsize 12 textcolor 94 resizable
  653. code0 {o->buffer( phrase_notes_buffer = new Fl_Text_Buffer );}
  654. }
  655. Fl_Value_Slider phrase_number_spinner {
  656. label Phrase
  657. callback {phrase *p = ((phrase *)phrase_canvas_widget->grid())->by_number( o->value() );
  658. if ( p )
  659. phrase_canvas_widget->grid( p );
  660. o->maximum( phrase::phrases() );}
  661. xywh {5 737 155 24} type Horizontal labelsize 10 align 1 minimum 1 maximum 128 step 1 value 1 textsize 14
  662. }
  663. }
  664. }
  665. Fl_Group pattern_tab {open
  666. xywh {0 91 865 694} box FLAT_BOX color 47 labeltype NO_LABEL
  667. code0 {update_pattern_widgets();}
  668. } {
  669. Fl_Box pattern_canvas_widget {
  670. label Pattern
  671. xywh {0 91 865 637} box FLAT_BOX color 37 labelsize 100 align 16 resizable
  672. class Canvas
  673. }
  674. Fl_Group pattern_settings_group {open
  675. xywh {0 731 865 54} box FLAT_BOX color 47
  676. } {
  677. Fl_Input pattern_name_field {
  678. label {name:}
  679. callback {pattern_canvas_widget->grid()->name( strdup( o->value() ) );}
  680. xywh {5 734 185 21} box ROUNDED_BOX color 49 labelsize 12 align 20 when 8 textfont 2 textsize 12 textcolor 55
  681. code0 {o->up_box( FL_ROUNDED_BOX );}
  682. class Fl_Sometimes_Input
  683. }
  684. Fl_Light_Button pattern_mute_button {
  685. label Mute
  686. callback {Grid *g = pattern_canvas_widget->grid();
  687. g->mode( g->mode() == MUTE ? PLAY : MUTE );
  688. o->value( g->mode() == MUTE );
  689. pattern_solo_button->value( 0 );}
  690. xywh {195 734 58 19} type Normal shortcut 0x6d color 37 labelsize 12
  691. }
  692. Fl_Light_Button pattern_solo_button {
  693. label Solo
  694. callback {Grid *g = pattern_canvas_widget->grid();
  695. g->mode( g->mode() == SOLO ? PLAY : SOLO );
  696. o->value( g->mode() == SOLO );
  697. pattern_mute_button->value( 0 );}
  698. xywh {195 758 58 19} type Normal shortcut 0x73 color 37 labelsize 12
  699. }
  700. Fl_Text_Editor pattern_notes_edit {
  701. label {Notes:}
  702. callback {pattern_canvas_widget->grid()->notes( o->buffer()->text() );}
  703. xywh {310 734 240 46} color 40 selection_color 48 labeltype NO_LABEL labelsize 10 textsize 11 textcolor 63 resizable
  704. code0 {o->buffer( pattern_notes_buffer = new Fl_Text_Buffer );}
  705. code1 {o->wrap_mode( Fl_Text_Editor::WRAP_AT_BOUNDS, 0 );}
  706. }
  707. Fl_Group {} {open
  708. xywh {555 731 310 49}
  709. } {
  710. Fl_Spinner pattern_channel_spinner {
  711. label Channel
  712. callback {((pattern *)pattern_canvas_widget->grid())->channel( o->value() - 1 );}
  713. xywh {820 735 40 19} color 36 labelsize 10 when 1 textsize 12
  714. code0 {\#include "../pattern.H"}
  715. code1 {o->maximum( 16 );}
  716. }
  717. Fl_Spinner pattern_port_spinner {
  718. label Port
  719. callback {((pattern *)pattern_canvas_widget->grid())->port( o->value() - 1 );}
  720. xywh {820 758 40 19} color 36 labelsize 10 when 1 textsize 12
  721. code0 {o->maximum( 16 );}
  722. }
  723. Fl_Output mapping_text {
  724. label Mapping
  725. xywh {555 758 105 19} labelsize 10 align 20 textsize 11
  726. }
  727. Fl_Menu_Button mapping_menu {
  728. label {@>}
  729. callback {mapping_text->value( o->text() );
  730. char picked[80];
  731. mapping_menu->item_pathname(picked, sizeof(picked)-1 );
  732. if ( 0 == strncmp( picked, "Instrument", strlen( "Instrument" ) ) )
  733. {
  734. ((pattern*)pattern_canvas_widget->grid())->mapping.open( Mapping::INSTRUMENT, o->text() );
  735. pattern_canvas_widget->changed_mapping();
  736. pattern_key_combo->deactivate();
  737. }
  738. else
  739. if ( 0 == strncmp( picked, "Scale", strlen( "Scale" ) ) )
  740. {
  741. ((pattern*)pattern_canvas_widget->grid())->mapping.open( Mapping::SCALE, o->text() );
  742. pattern_canvas_widget->changed_mapping();
  743. pattern_key_combo->activate();
  744. }} open
  745. xywh {660 758 30 19} labeltype NO_LABEL labelsize 10 textsize 12
  746. code0 {update_mapping_menu();}
  747. } {
  748. Submenu mapping_scale_menu {
  749. label Scale open
  750. xywh {25 25 74 25}
  751. } {}
  752. Submenu mapping_instrument_menu {
  753. label Instrument open
  754. xywh {10 10 74 25}
  755. } {}
  756. }
  757. Fl_Choice pattern_key_combo {
  758. label {&Key}
  759. callback {((pattern*)pattern_canvas_widget->grid())->mapping.key( o->value() );
  760. pattern_canvas_widget->changed_mapping();} open
  761. xywh {720 758 75 19} down_box BORDER_BOX labelsize 10 when 1 textsize 11
  762. } {
  763. MenuItem {} {
  764. label C
  765. xywh {30 30 40 25} labelsize 11
  766. }
  767. MenuItem {} {
  768. label {C\#/Db}
  769. xywh {40 40 40 25} labelsize 11
  770. }
  771. MenuItem {} {
  772. label D
  773. xywh {50 50 40 25} labelsize 11
  774. }
  775. MenuItem {} {
  776. label {D\#/Eb}
  777. xywh {60 60 40 25} labelsize 11
  778. }
  779. MenuItem {} {
  780. label E
  781. xywh {70 70 40 25} labelsize 11
  782. }
  783. MenuItem {} {
  784. label F
  785. xywh {80 80 40 25} labelsize 11
  786. }
  787. MenuItem {} {
  788. label {F\#/Gb}
  789. xywh {90 90 40 25} labelsize 11
  790. }
  791. MenuItem {} {
  792. label G
  793. xywh {100 100 40 25} labelsize 11
  794. }
  795. MenuItem {} {
  796. label {G\#}
  797. xywh {110 110 40 25} labelsize 11
  798. }
  799. MenuItem {} {
  800. label A
  801. xywh {0 0 40 25} labelsize 11
  802. }
  803. MenuItem {} {
  804. label {A\#/Bb}
  805. xywh {10 10 40 25} labelsize 11
  806. }
  807. MenuItem {} {
  808. label B
  809. xywh {20 20 40 25} labelsize 11
  810. }
  811. }
  812. Fl_Choice pattern_note_combo {
  813. label {&Note 1/}
  814. callback {((pattern*)pattern_canvas_widget->grid())->note( atoi( o->menu()[ o->value() ].text ));} open
  815. xywh {730 735 45 19} down_box BORDER_BOX labelsize 10 when 1 textsize 12
  816. } {
  817. MenuItem {} {
  818. label 1
  819. xywh {0 0 40 25} labelsize 11
  820. }
  821. MenuItem {} {
  822. label 2
  823. xywh {10 10 40 25} labelsize 11
  824. }
  825. MenuItem {} {
  826. label 4
  827. xywh {20 20 40 25} labelsize 11
  828. }
  829. MenuItem {} {
  830. label 8
  831. xywh {30 30 40 25} labelsize 11
  832. }
  833. MenuItem {} {
  834. label 16
  835. xywh {40 40 40 25} labelsize 11
  836. }
  837. MenuItem {} {
  838. label 32
  839. xywh {50 50 40 25} labelsize 11
  840. }
  841. MenuItem {} {
  842. label 64
  843. xywh {60 60 40 25} labelsize 11 divider
  844. }
  845. MenuItem {} {
  846. label 3
  847. xywh {60 60 40 25} labelsize 11
  848. }
  849. MenuItem {} {
  850. label 6
  851. xywh {70 70 40 25} labelsize 11
  852. }
  853. MenuItem {} {
  854. label 12
  855. xywh {80 80 40 25} labelsize 11
  856. }
  857. MenuItem {} {
  858. label 24
  859. xywh {90 90 40 25} labelsize 11
  860. }
  861. }
  862. Fl_Choice pattern_res_combo {
  863. label {&Resolution 1/}
  864. callback {pattern_canvas_widget->grid()->resolution( atoi( o->menu()[ o->value() ].text ));} open
  865. xywh {625 735 55 19} down_box BORDER_BOX labelsize 10 when 1 textsize 12
  866. } {
  867. MenuItem {} {
  868. label 1
  869. xywh {40 40 40 25} labelsize 11
  870. }
  871. MenuItem {} {
  872. label 2
  873. xywh {50 50 40 25} labelsize 11
  874. }
  875. MenuItem {} {
  876. label 4
  877. xywh {30 30 40 25} labelsize 11
  878. }
  879. MenuItem {} {
  880. label 8
  881. xywh {40 40 40 25} labelsize 11
  882. }
  883. MenuItem {} {
  884. label 16
  885. xywh {50 50 40 25} labelsize 11
  886. }
  887. MenuItem {} {
  888. label 32
  889. xywh {60 60 40 25} labelsize 11
  890. }
  891. MenuItem {} {
  892. label 64
  893. xywh {80 80 40 25} labelsize 11
  894. }
  895. MenuItem {} {
  896. label 128
  897. xywh {90 90 40 25} labelsize 11 divider
  898. }
  899. MenuItem {} {
  900. label 3
  901. xywh {70 70 40 25} labelsize 11
  902. }
  903. MenuItem {} {
  904. label 6
  905. xywh {80 80 40 25} labelsize 11
  906. }
  907. MenuItem {} {
  908. label 12
  909. xywh {90 90 40 25} labelsize 11
  910. }
  911. MenuItem {} {
  912. label 24
  913. xywh {100 100 40 25} labelsize 11
  914. }
  915. }
  916. }
  917. Fl_Value_Slider pattern_number_spinner {
  918. label Pattern
  919. callback {pattern *p = ((pattern *)pattern_canvas_widget->grid())->by_number( o->value() );
  920. if ( p )
  921. pattern_canvas_widget->grid( p );
  922. update_pattern_widgets();
  923. o->maximum( pattern::patterns() );
  924. pattern_settings_group->redraw();}
  925. xywh {45 759 140 18} type Horizontal labelsize 10 align 4 minimum 1 maximum 128 step 1 value 1
  926. }
  927. Fl_Button {} {
  928. label Select selected
  929. tooltip {Enable selection mode (you can also just hold down shift and drag the mouse)} xywh {260 735 45 45} type Toggle selection_color 5 labelsize 10
  930. }
  931. }
  932. }
  933. }
  934. Fl_Group {} {open
  935. xywh {0 784 865 23}
  936. } {
  937. Fl_Box status {
  938. label status
  939. xywh {1 784 782 23} box UP_BOX align 84
  940. code0 {o->label( NULL );}
  941. }
  942. Fl_Box transport_state {
  943. label state
  944. callback {const char *s = "INVALID";
  945. if ( transport.master )
  946. s = "Master";
  947. else if ( transport.valid )
  948. s = "Slave";
  949. if ( s != o->label() )
  950. {
  951. o->label( s );
  952. if ( ! strcmp( s, "INVALID" ) )
  953. o->color( fl_darker( FL_RED ) );
  954. else
  955. o->color( FL_BACKGROUND_COLOR );
  956. }}
  957. xywh {783 784 82 23} box THIN_UP_BOX align 64
  958. }
  959. }
  960. Fl_Group {} {open
  961. xywh {0 0 865 24}
  962. } {
  963. Fl_Menu_Bar menu_bar {open
  964. xywh {0 0 865 24} color 47 resizable
  965. } {
  966. Submenu {} {
  967. label {&File} open
  968. xywh {0 0 100 20} color 37
  969. } {
  970. MenuItem menu_new {
  971. label {&New}
  972. callback {if ( maybe_save_song() )
  973. {
  974. init_song();
  975. // Sync the GUI.
  976. update_pattern_widgets();
  977. update_sequence_widgets();
  978. update_phrase_widgets();
  979. gui_status( "New song." );
  980. }}
  981. xywh {0 0 40 25}
  982. }
  983. MenuItem menu_open {
  984. label {&Open}
  985. callback {char *name = fl_file_chooser( "Open File", "Non Files (*.non)", NULL, 0 );
  986. if ( name )
  987. {
  988. if ( ! load_song( name ) )
  989. fl_alert( "Could not load song!" );
  990. else
  991. gui_status( "Song opened." );
  992. update_sequence_widgets();
  993. update_pattern_widgets();
  994. update_phrase_widgets();
  995. playback_mode_menu->value( song.play_mode );
  996. playback_mode_menu->redraw();
  997. }}
  998. xywh {0 0 40 25} shortcut 0x4006f color 37
  999. }
  1000. MenuItem menu_save {
  1001. label {&Save}
  1002. callback {save_dialog( song.filename );}
  1003. xywh {0 0 40 25} shortcut 0x40073 color 37 deactivate
  1004. code0 {song.signal_dirty.connect( sigc::mem_fun( o, &Fl_Menu_Item::activate ) );}
  1005. code1 {song.signal_clean.connect( sigc::mem_fun( o, &Fl_Menu_Item::deactivate ) );}
  1006. }
  1007. MenuItem menu_save_as {
  1008. label {Save &As}
  1009. callback {save_dialog( NULL );}
  1010. xywh {0 0 40 25}
  1011. }
  1012. MenuItem {} {
  1013. label {&Import}
  1014. callback {char *name = fl_file_chooser( "MIDI Import", "MIDI Files (*.mid)", NULL, 0 );
  1015. if ( ! name )
  1016. return;
  1017. smf f;
  1018. if ( ! f.open( name, smf::READ ) )
  1019. {
  1020. fl_message( "could not open file" );
  1021. return;
  1022. }
  1023. f.read_header();
  1024. switch ( f.format() )
  1025. {
  1026. case 0:
  1027. if ( ! pattern::import( &f, 0 ) )
  1028. fl_message( "Error importing MIDI" );
  1029. break;
  1030. case 1: case 2:
  1031. {
  1032. char **sa = f.track_listing();
  1033. if ( sa && *sa )
  1034. {
  1035. List_Chooser tc( "Select tracks to import:", "Import" );
  1036. char *s;
  1037. for ( int i = 0; (s = sa[i]); ++i )
  1038. {
  1039. tc.add( s );
  1040. free( s );
  1041. }
  1042. free( sa );
  1043. tc.show();
  1044. while( tc.shown() )
  1045. Fl::wait();
  1046. int n = 0;
  1047. for ( int i = 1; i <= tc.browser->size(); ++i )
  1048. {
  1049. if ( tc.browser->selected( i ) )
  1050. {
  1051. if ( pattern::import( &f , i - 1 ) )
  1052. ++n;
  1053. else
  1054. WARNING( "error importing track %d", i - 1 );
  1055. }
  1056. }
  1057. // fl_message( "%d patterns imported.", n );
  1058. gui_status( "Imported %d tracks as patterns", n );
  1059. }
  1060. break;
  1061. }
  1062. }}
  1063. xywh {0 0 40 25}
  1064. code0 {\#include "../smf.H"}
  1065. }
  1066. MenuItem {} {
  1067. label {&Export}
  1068. callback {// Fl_File_Chooser::custom_filter_label = "*.mid";
  1069. Fl_File_Chooser *fc = new Fl_File_Chooser( ".", "MIDI Files (*.mid)", Fl_File_Chooser::CREATE, "MIDI Export" );
  1070. fc->show();
  1071. // wait for user to make a choice
  1072. while( fc->shown() )
  1073. Fl::wait();
  1074. if ( ! fc->value() )
  1075. return;
  1076. if ( tabs->value() == pattern_tab )
  1077. ((pattern*)pattern_canvas_widget->grid())->save( fc->value() );}
  1078. xywh {0 0 40 25}
  1079. code0 {\#include <FL/Fl_File_Chooser.H>}
  1080. }
  1081. MenuItem {} {
  1082. label {&Quit}
  1083. callback {main_window->do_callback();}
  1084. xywh {0 0 40 25} shortcut 0x40071 color 37
  1085. }
  1086. }
  1087. Submenu {} {
  1088. label {&Settings} open
  1089. xywh {0 0 74 25} color 37
  1090. } {
  1091. MenuItem {} {
  1092. label {&Randomization Settings}
  1093. callback {randomization_dialog->show();}
  1094. xywh {0 0 40 25}
  1095. }
  1096. }
  1097. Submenu {} {
  1098. label {&View} open
  1099. xywh {10 10 74 25} color 37
  1100. } {
  1101. MenuItem {} {
  1102. label {&Metronome}
  1103. callback {int val = o->menu()[ o->value() ].value();
  1104. if ( val )
  1105. vmetro_widget->show();
  1106. else
  1107. vmetro_widget->hide();}
  1108. xywh {0 0 40 25} type Toggle value 1
  1109. }
  1110. MenuItem {} {
  1111. label {&Compacted}
  1112. callback {int val = o->menu()[ o->value() ].value();
  1113. pattern_canvas_widget->row_compact( val ? Canvas::ON : Canvas::OFF );
  1114. pattern_canvas_widget->redraw();}
  1115. xywh {10 10 40 25} type Toggle value 1
  1116. }
  1117. MenuItem {} {
  1118. label {&Follow Playhead}
  1119. callback {int val = o->menu()[ o->value() ].value();
  1120. config.follow_playhead = val ? true : false;}
  1121. xywh {10 10 40 25} type Toggle value 1
  1122. }
  1123. MenuItem {} {
  1124. label {&Theme}
  1125. callback {fl_theme_chooser();}
  1126. xywh {0 0 40 24}
  1127. }
  1128. }
  1129. Submenu {} {
  1130. label {&Help} open
  1131. xywh {100 0 74 25} color 37
  1132. } {
  1133. MenuItem {} {
  1134. label {&Manual}
  1135. callback {show_help_dialog( "MANUAL" );}
  1136. xywh {10 10 40 25} divider
  1137. }
  1138. MenuItem {} {
  1139. label {&About}
  1140. callback {About_Dialog ab( PIXMAP_PATH "/non-sequencer/icon-256x256.png" );
  1141. ab.logo_box->label( VERSION );
  1142. ab.title->label( "Non Sequencer" );
  1143. ab.copyright->label( "Copyright (C) 2007-2013 Jonathan Moore Liles" );
  1144. 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" );
  1145. ab.website_url->label( "http://non.tuxfamily.org" );
  1146. ab.run();}
  1147. xywh {0 0 40 25} color 37
  1148. code0 {\#include "../non.H"}
  1149. }
  1150. }
  1151. Submenu edit_menu {
  1152. label {&Edit} open
  1153. xywh {0 0 68 18}
  1154. } {
  1155. MenuItem {} {
  1156. label {Add New}
  1157. callback {Grid *g = pattern_canvas_widget->grid()->create();
  1158. pattern_canvas_widget->grid( g );
  1159. update_pattern_widgets();
  1160. update_sequence_widgets();}
  1161. xywh {0 0 34 18} shortcut 0x61
  1162. }
  1163. MenuItem {} {
  1164. label Previous
  1165. callback {pattern_number_spinner->value( max( 0, (int)pattern_number_spinner->value() - 1 ) );
  1166. pattern_number_spinner->do_callback();}
  1167. xywh {10 10 34 18} shortcut 0x5b
  1168. }
  1169. MenuItem {} {
  1170. label Next
  1171. callback {pattern_number_spinner->value( min( 127, (int)pattern_number_spinner->value() + 1 ));
  1172. pattern_number_spinner->do_callback();}
  1173. xywh {20 20 34 18} shortcut 0x5d
  1174. }
  1175. MenuItem {} {
  1176. label Duplicate
  1177. callback {Canvas *w = pattern_canvas_widget;
  1178. w->grid( w->grid()->clone() );
  1179. // number of phrases may have changed.
  1180. ui->update_sequence_widgets();}
  1181. xywh {30 30 34 18} shortcut 0x64
  1182. }
  1183. MenuItem {} {
  1184. label {Duplicate Range}
  1185. callback {Canvas *w = pattern_canvas_widget;
  1186. w->duplicate_range();
  1187. // number of phrases may have changed.
  1188. ui->update_sequence_widgets();}
  1189. xywh {40 40 34 18} shortcut 0x10064
  1190. }
  1191. MenuItem {} {
  1192. label {Delete Selected}
  1193. callback {Canvas *w = pattern_canvas_widget;
  1194. w->grid()->delete_selected();}
  1195. xywh {50 50 34 18} shortcut 0xffff
  1196. }
  1197. MenuItem {} {
  1198. label Clear
  1199. callback {Canvas *w = pattern_canvas_widget;
  1200. w->grid()->clear();}
  1201. xywh {60 60 34 18} shortcut 0x1ffff
  1202. }
  1203. MenuItem {} {
  1204. label {Edit Events}
  1205. callback {event_editor( pattern_canvas_widget->grid() );}
  1206. xywh {10 10 40 25}
  1207. }
  1208. MenuItem {} {
  1209. label {Select All}
  1210. callback {Canvas *w = pattern_canvas_widget;
  1211. w->grid()->clear();}
  1212. xywh {70 70 34 18} shortcut 0x40061
  1213. }
  1214. MenuItem {} {
  1215. label {Select None}
  1216. callback {Canvas *w = pattern_canvas_widget;
  1217. w->grid()->clear();}
  1218. xywh {80 80 34 18} shortcut 0x50061
  1219. }
  1220. MenuItem {} {
  1221. label {Invert Selection}
  1222. callback {Canvas *w = pattern_canvas_widget;
  1223. w->grid()->clear();}
  1224. xywh {90 90 34 18} shortcut 0x50069
  1225. }
  1226. MenuItem {} {
  1227. label Copy
  1228. callback {Canvas *w = pattern_canvas_widget;
  1229. w->grid()->clear();}
  1230. xywh {100 100 34 18} shortcut 0x40063
  1231. }
  1232. MenuItem {} {
  1233. label Cut
  1234. callback {Canvas *w = pattern_canvas_widget;
  1235. w->grid()->clear();}
  1236. xywh {110 110 34 18} shortcut 0x40078
  1237. }
  1238. MenuItem {} {
  1239. label Paste
  1240. callback {Canvas *w = pattern_canvas_widget;
  1241. w->grid()->clear();}
  1242. xywh {120 120 34 18} shortcut 0x40076
  1243. }
  1244. }
  1245. }
  1246. Fl_Button sm_indicator {
  1247. label SM
  1248. xywh {825 5 35 15} box ROUNDED_BOX down_box ROUNDED_BOX color 46 selection_color 93 labelfont 3 labelcolor 39 deactivate
  1249. }
  1250. }
  1251. }
  1252. }
  1253. Function {make_seq_window()} {open
  1254. } {
  1255. Fl_Window seq_window {
  1256. label {Non Sequencer - Sequence}
  1257. callback {sequence_tab->activate();
  1258. o->hide();
  1259. detach_button->value( 0 );} open
  1260. xywh {681 189 876 675} type Double hide resizable
  1261. } {
  1262. Fl_Group seq_detached_group {open
  1263. xywh {0 0 876 675} resizable
  1264. } {}
  1265. }
  1266. }
  1267. Function {make_randomization_dialog()} {} {
  1268. Fl_Window randomization_dialog {
  1269. label {Randomization Settings} open
  1270. xywh {656 39 340 95} type Double hide
  1271. code0 {// feel->value( )}
  1272. code1 {probability->value( song.random.probability );} non_modal
  1273. } {
  1274. Fl_Choice feel {
  1275. label {Feel: 1/}
  1276. callback {song.random.feel = atoi( o->menu()[ find_numeric_menu_item( o->menu(), o->value() ) ].text );} open
  1277. xywh {67 55 50 24} down_box BORDER_BOX
  1278. } {
  1279. MenuItem {} {
  1280. label 4
  1281. xywh {10 10 40 25}
  1282. }
  1283. MenuItem {} {
  1284. label 8
  1285. xywh {0 0 40 25}
  1286. }
  1287. MenuItem {} {
  1288. label 16
  1289. xywh {10 10 40 25}
  1290. }
  1291. }
  1292. Fl_Box {} {
  1293. label {Randomization Settings}
  1294. xywh {10 15 321 28} box ROUNDED_BOX color 94 labelsize 22 labelcolor 39
  1295. }
  1296. Fl_Counter probability {
  1297. label Probability
  1298. callback {song.random.probability = o->value();}
  1299. xywh {216 53 112 26} type Simple align 4 when 4 minimum 0 maximum 1 step 0.01
  1300. }
  1301. }
  1302. }
  1303. Function {update_pattern_widgets()} {open
  1304. } {
  1305. code {if ( ! pattern_settings_group )
  1306. return;
  1307. if ( !pattern_canvas_widget)
  1308. return;
  1309. pattern *g = (pattern *)pattern_canvas_widget->grid();
  1310. if ( !g )
  1311. return;
  1312. pattern_number_spinner->value( g->number() );
  1313. pattern_name_field->value( g->name() );
  1314. pattern_channel_spinner->value( 1 + g->channel() );
  1315. pattern_port_spinner->value( 1 + g->port() );
  1316. pattern_solo_button->value( g->mode() == SOLO );
  1317. pattern_mute_button->value( g->mode() == MUTE );
  1318. if ( g->mapping.key() == -1 )
  1319. pattern_key_combo->deactivate();
  1320. else
  1321. {
  1322. pattern_key_combo->activate();
  1323. pattern_key_combo->value( g->mapping.key() );
  1324. }
  1325. mapping_text->value( g->mapping.name() );
  1326. pattern_note_combo->value( find_numeric_menu_item( menu_pattern_note_combo, g->note() ));
  1327. pattern_res_combo->value( find_numeric_menu_item( menu_pattern_res_combo, g->resolution() ));
  1328. if ( g->notes() )
  1329. pattern_notes_buffer->text( g->notes() );
  1330. else
  1331. pattern_notes_buffer->text( strdup( "" ) );} {}
  1332. }
  1333. Function {update_phrase_widgets()} {open
  1334. } {
  1335. code {if ( ! phrase_canvas_widget )
  1336. return;
  1337. phrase *g = (phrase *)phrase_canvas_widget->grid();
  1338. if ( ! g )
  1339. return;
  1340. g->viewport.y = 0;
  1341. g->viewport.h = pattern::patterns();
  1342. phrase_canvas_widget->resize_grid();
  1343. phrase_canvas_widget->changed_mapping();
  1344. phrase_number_spinner->value( g->number() );
  1345. phrase_name_field->value( g->name() );
  1346. phrase_solo_button->value( g->mode() == SOLO );
  1347. phrase_mute_button->value( g->mode() == MUTE );
  1348. if ( g->notes() )
  1349. phrase_notes_buffer->text( g->notes() );
  1350. else
  1351. phrase_notes_buffer->text( strdup( "" ) );} {}
  1352. }
  1353. Function {update_sequence_widgets()} {open
  1354. } {
  1355. code {if ( playlist->notes() )
  1356. sequence_notes_buffer->text( playlist->notes() );
  1357. else
  1358. sequence_notes_buffer->text( strdup( "" ) );
  1359. sequence_name_field->value( playlist->name() );
  1360. sequence_phrase_choice->clear();
  1361. for ( int i = 1; i <= phrase::phrases(); i++ )
  1362. {
  1363. phrase *p = phrase::phrase_by_number( i );
  1364. if ( p )
  1365. sequence_phrase_choice->add( p->name() );
  1366. }
  1367. Fl_Browser *o = playlist_browser;
  1368. int val = o->value();
  1369. o->clear();
  1370. char *s = playlist->dump();
  1371. char *l = strtok( s, "\\n" );
  1372. o->add( "@b@C2Bar\\t@b@C2\#\\t@b@C2Name" );
  1373. if ( ! l )
  1374. return;
  1375. o->add( l );
  1376. while ( ( l = strtok( NULL, "\\n" ) ) )
  1377. {
  1378. o->add( l );
  1379. }
  1380. o->value( val );
  1381. free( s );
  1382. if ( playback_mode_menu )
  1383. playback_mode_menu->value( song.play_mode );} {}
  1384. }
  1385. Function {update_mapping_menu()} {open
  1386. } {
  1387. code {char **sa = Instrument::listing();
  1388. if ( sa )
  1389. {
  1390. for ( int i = 0; sa[i]; i++ )
  1391. {
  1392. char pat[512];
  1393. snprintf( pat, 512, "Instrument/%s", sa[i] );
  1394. mapping_menu->add( pat, 0, 0, 0, 0 );
  1395. free( sa[i] );
  1396. }
  1397. free( sa );
  1398. }
  1399. sa = Scale::listing();
  1400. for ( int i = 0; sa[i]; i++ )
  1401. {
  1402. char pat[512];
  1403. snprintf( pat, 512, "Scale/%s", sa[i] );
  1404. mapping_menu->add( pat, 0, 0, 0, 0 );
  1405. free( sa[i] );
  1406. }
  1407. free( sa );} {}
  1408. }
  1409. Function {update_canvas_widgets()} {return_type {static void}
  1410. } {
  1411. code {if ( ui->pattern_canvas_widget->grid() )
  1412. ui->update_pattern_widgets();
  1413. if ( ui->phrase_canvas_widget->grid() )
  1414. ui->update_phrase_widgets();} {}
  1415. }
  1416. Function {find_numeric_menu_item( const Fl_Menu_Item *menu, int n )} {return_type {static int}
  1417. } {
  1418. code {for ( unsigned int i = 0; menu[i].text; i++ )
  1419. {
  1420. if ( atoi( menu[i].text ) == n )
  1421. return i;
  1422. }
  1423. return 0;} {}
  1424. }
  1425. Function {save_dialog( const char *name )} {open return_type void
  1426. } {
  1427. code {if ( ! name )
  1428. {
  1429. Fl_File_Chooser *fc = new Fl_File_Chooser( ".", "Non Sequences (*.non)", Fl_File_Chooser::CREATE, "Save sequence" );
  1430. fc->show();
  1431. // wait for user to make a choice
  1432. while( fc->shown() )
  1433. Fl::wait();
  1434. if ( ! fc->value() )
  1435. return;
  1436. name = fc->value();
  1437. }
  1438. if ( ! save_song( name ) )
  1439. fl_alert( "Could not save song" );
  1440. else
  1441. gui_status( "Saved." );} {}
  1442. }
  1443. Function {show_help_dialog( const char *file )} {return_type void
  1444. } {
  1445. code {char pat[256];
  1446. snprintf( pat, 256, "file://%s/non-sequencer/%s.html", DOCUMENT_PATH, file );
  1447. open_url( pat );} {}
  1448. }
  1449. Function {maybe_save_song()} {open return_type bool
  1450. } {
  1451. code {if ( song.dirty() )
  1452. {
  1453. int c = fl_choice( "Song has been modified since last save. What shall I do?", "&Cancel", "&Save", "&Discard" );
  1454. switch ( c )
  1455. {
  1456. case 0:
  1457. return false;
  1458. case 1:
  1459. /* SAVE */
  1460. save_dialog( song.filename );
  1461. break;
  1462. case 2:
  1463. break;
  1464. }
  1465. }
  1466. return true;} {}
  1467. }
  1468. Function {switch_to_pattern( int n )} {return_type void
  1469. } {
  1470. code {pattern *p = pattern::pattern_by_number( n );
  1471. if ( p )
  1472. {
  1473. tabs->value( pattern_tab );
  1474. pattern_canvas_widget->take_focus();
  1475. pattern_canvas_widget->grid( p );
  1476. // update_pattern_widgets();
  1477. }} {}
  1478. }
  1479. Function {edit_instrument_row( Instrument *i, int n )} {open return_type void
  1480. } {
  1481. code {Instrument_Editor ie;
  1482. ie.set( i, n );
  1483. ie.run();} {}
  1484. }
  1485. }
  1486. class Instrument_Editor {} {
  1487. Function {Instrument_Editor()} {open return_type void
  1488. } {
  1489. code {make_window();} {}
  1490. }
  1491. decl {Instrument *_inst;} {private local
  1492. }
  1493. decl {int _note;} {private local
  1494. }
  1495. Function {make_window()} {open
  1496. } {
  1497. Fl_Window window {
  1498. label {Instrument Editor}
  1499. callback {done->do_callback();} open
  1500. xywh {670 458 335 190} type Double hide
  1501. } {
  1502. Fl_Box {} {
  1503. label {Instrument Row}
  1504. xywh {8 15 321 28} box ROUNDED_BOX color 94 labelsize 22 labelcolor 39
  1505. }
  1506. Fl_Input name_field {
  1507. label Name
  1508. callback {_inst->note_name( _note, strdup( o->value() ) );}
  1509. xywh {10 70 321 25} selection_color 48 align 1 when 1 textcolor 32
  1510. }
  1511. Fl_Value_Slider volume_slider {
  1512. label {Volume %}
  1513. callback {_inst->velocity( _note, o->value() );}
  1514. xywh {10 112 321 27} type Horizontal align 1 maximum 100 step 1 textsize 14
  1515. }
  1516. Fl_Value_Output note_field {
  1517. label {Note:}
  1518. xywh {52 158 43 24}
  1519. }
  1520. Fl_Return_Button done {
  1521. label Done
  1522. callback {if ( _inst )
  1523. _inst->save();
  1524. window->hide();}
  1525. xywh {255 157 76 25}
  1526. }
  1527. }
  1528. }
  1529. Function {set( Instrument *i, int n )} {open return_type void
  1530. } {
  1531. code {_inst = i;
  1532. _note = n;
  1533. volume_slider->value( i->velocity( n ) );
  1534. name_field->value( i->note_name( n ) );
  1535. note_field->value( n );} {}
  1536. }
  1537. Function {run()} {open return_type void
  1538. } {
  1539. code {window->show();
  1540. while ( window->shown() )
  1541. Fl::wait();} {}
  1542. }
  1543. }
  1544. class Trigger {open : {public Fl_Progress}
  1545. } {
  1546. Function {Trigger( int X, int Y, int W, int H, const char *L =0) : Fl_Progress( X, Y, W, H, L )} {open
  1547. } {
  1548. code {minimum( 0 );
  1549. maximum( 1 );
  1550. //angles( 0, 360 );
  1551. // type( Fl_Dial::ARC_DIAL );
  1552. // type(FL_VERTICAL);} {}
  1553. }
  1554. Function {handle( int m )} {open return_type int
  1555. } {
  1556. code {int r = 0;
  1557. switch ( m )
  1558. {
  1559. case FL_PUSH:
  1560. {
  1561. switch ( Fl::event_button() )
  1562. {
  1563. case 1:
  1564. {
  1565. pattern *p = pattern::pattern_by_number( atoi( label() ) );
  1566. if ( p )
  1567. {
  1568. if ( TRIGGER == song.play_mode )
  1569. {
  1570. if ( p->playing() )
  1571. p->stop();
  1572. else
  1573. p->trigger();
  1574. }
  1575. else
  1576. {
  1577. if ( p->mode() == PLAY )
  1578. p->mode( MUTE );
  1579. else
  1580. p->mode( PLAY );
  1581. }
  1582. }
  1583. break;
  1584. }
  1585. case 2:
  1586. {
  1587. pattern *p = pattern::pattern_by_number( atoi( label() ) );
  1588. if ( p )
  1589. {
  1590. if ( p->mode() != SOLO )
  1591. p->mode( SOLO );
  1592. else
  1593. p->mode( PLAY );
  1594. }
  1595. break;
  1596. }
  1597. case 3:
  1598. {
  1599. ui->switch_to_pattern( atoi( label() ) );
  1600. }
  1601. break;
  1602. }
  1603. r = 1;
  1604. break;
  1605. }
  1606. case FL_RELEASE:
  1607. do_callback();
  1608. r = 1;
  1609. break;
  1610. case FL_DRAG:
  1611. r = 1;
  1612. break;
  1613. default:
  1614. r = Fl_Widget::handle( m );
  1615. break;
  1616. }
  1617. return r;} {}
  1618. }
  1619. }
  1620. widget_class Triggers {open
  1621. xywh {390 620 335 390} type Double hide
  1622. code0 {\#include <FL/Fl_Dial.H>}
  1623. code1 {populate();}
  1624. class Fl_Group
  1625. } {
  1626. Function {populate( void )} {open private return_type void
  1627. } {
  1628. code {_timer = 0;
  1629. for ( int i = 0; i < 128; i++ )
  1630. {
  1631. Trigger *b = new Trigger( 1,1,1,1 );
  1632. char pat[4];
  1633. sprintf( pat, "%d",i +1);
  1634. b->label( strdup( pat ) );
  1635. b->labelsize( 8 );
  1636. b->color2( FL_GRAY );
  1637. b->box( FL_FLAT_BOX );
  1638. // b->down_box( FL_ROUNDED_BOX );
  1639. b->selection_color( FL_GREEN );
  1640. b->color( FL_BLACK );
  1641. b->color2( FL_GREEN );
  1642. b->align( FL_ALIGN_CENTER );
  1643. add( b );
  1644. }} {}
  1645. }
  1646. Function {update( void )} {open return_type void
  1647. } {
  1648. code {++_timer;
  1649. if ( !visible_r() )
  1650. return;
  1651. if ( ! takesevents() )
  1652. return;
  1653. Fl_Color mode_color[3];
  1654. mode_color[PLAY] = fl_color_average( FL_GRAY, FL_GREEN, 0.5 );
  1655. // mode_color[PLAY] = fl_color;
  1656. mode_color[MUTE] = FL_LIGHT2;
  1657. mode_color[SOLO] = fl_color_average( FL_GRAY, FL_RED, 0.5 );
  1658. if ( ! _rows )
  1659. return;
  1660. for ( int i = 0; i < MAX_PATTERN; i++ )
  1661. {
  1662. Trigger *b = (Trigger*)child( i );
  1663. if ( i >= pattern::patterns() )
  1664. {
  1665. b->color( FL_BLACK );
  1666. b->value( 0 );
  1667. continue;
  1668. }
  1669. pattern *p = pattern::pattern_by_number( i + 1 );
  1670. if ( p->playing() )
  1671. {
  1672. b->color( FL_GRAY );
  1673. b->selection_color( mode_color[ p->mode() ] );
  1674. if ( p->queue() >= 0 )
  1675. {
  1676. if ( _timer % 16 < 8 )
  1677. {
  1678. b->color( mode_color[ p->queue() ] );
  1679. }
  1680. }
  1681. b->value( (double)p->index() / p->length() );
  1682. }
  1683. else
  1684. {
  1685. b->value( 0 );
  1686. }
  1687. }} {}
  1688. }
  1689. decl {unsigned long _timer;} {private local
  1690. }
  1691. decl {int _rows;} {private local
  1692. }
  1693. Function {rows(int v)} {open return_type void
  1694. } {
  1695. code {_rows = v;
  1696. redraw();} {}
  1697. }
  1698. Function {draw()} {open return_type void
  1699. } {
  1700. code {int _cols = 128 / _rows;
  1701. int bw = w() / _cols;
  1702. int bh = h() / _rows;
  1703. int t = 0;
  1704. for ( int i = 0; i < _rows; i++ )
  1705. for ( int j = 0; j < _cols ; j++, t++ )
  1706. child( t )->resize( x() + (bw * j), y() + (bh * i), bw, bh );
  1707. Fl_Group::draw();} {}
  1708. }
  1709. decl {\#include <stdlib.h>} {private local
  1710. }
  1711. }
  1712. class List_Chooser {open
  1713. } {
  1714. Function {List_Chooser( const char *name, const char *action )} {} {
  1715. Fl_Window window {open
  1716. xywh {525 313 310 545} type Single hide resizable non_modal size_range {310 524 0 0}
  1717. } {
  1718. Fl_Browser browser {
  1719. label name
  1720. xywh {5 26 300 480} type Multi box THIN_DOWN_BOX color 32 selection_color 0 align 1 textcolor 55 resizable
  1721. code0 {o->label( name );}
  1722. }
  1723. Fl_Group {} {open
  1724. xywh {5 505 300 39}
  1725. } {
  1726. Fl_Button {} {
  1727. label Cancel
  1728. callback {browser->clear();
  1729. window->hide();}
  1730. xywh {5 513 75 27}
  1731. }
  1732. Fl_Return_Button button {
  1733. label action
  1734. callback {window->hide();}
  1735. xywh {115 513 190 27}
  1736. code0 {o->label( action );}
  1737. }
  1738. }
  1739. }
  1740. }
  1741. Function {show()} {open
  1742. } {
  1743. code {window->show();} {}
  1744. }
  1745. Function {shown()} {open return_type bool
  1746. } {
  1747. code {return window->shown();} {}
  1748. }
  1749. Function {add( const char *item )} {open
  1750. } {
  1751. code {browser->add( item );} {}
  1752. }
  1753. }
  1754. decl {float status_intensity;} {private local
  1755. }
  1756. Function {fade_status(void*)} {open private return_type {static void}
  1757. } {
  1758. code {ui->status->labelcolor( fl_color_average( FL_FOREGROUND_COLOR, FL_BACKGROUND_COLOR, status_intensity ) );
  1759. status_intensity -= 0.01f;
  1760. ui->status->redraw();
  1761. if ( status_intensity >= 0.01f )
  1762. Fl::repeat_timeout( 1 / 15.0f, fade_status );} {}
  1763. }
  1764. Function {gui_status( const char *fmt, ... )} {open C return_type void
  1765. } {
  1766. code {va_list args;
  1767. static char pat[256];
  1768. if ( fmt )
  1769. {
  1770. va_start( args, fmt );
  1771. vsnprintf( pat, 256, fmt, args );
  1772. va_end( args );
  1773. }
  1774. ui->status->label( pat );
  1775. ui->status->redraw();
  1776. status_intensity = 1.0f;
  1777. Fl::remove_timeout( fade_status );
  1778. Fl::add_timeout( 1 / 15.0f, fade_status );} {}
  1779. }