| @@ -1482,6 +1482,8 @@ Timeline::add_track ( Track *track ) | |||
| tracks->add( track ); | |||
| // update_track_order(); | |||
| engine->unlock(); | |||
| unlock(); | |||
| @@ -1491,6 +1493,91 @@ Timeline::add_track ( Track *track ) | |||
| } | |||
| void | |||
| Timeline::insert_track ( Track *track, int n ) | |||
| { | |||
| if ( n > tracks->children() || n < 0 ) | |||
| return; | |||
| wrlock(); | |||
| engine->lock(); | |||
| tracks->insert( *track, n ); | |||
| update_track_order(); | |||
| tracks->redraw(); | |||
| engine->unlock(); | |||
| unlock(); | |||
| /* FIXME: why is this necessary? doesn't the above add do DAMAGE_CHILD? */ | |||
| // redraw(); | |||
| } | |||
| static | |||
| bool | |||
| compare_tracks ( Track *a, Track *b ) | |||
| { | |||
| return *a < *b; | |||
| } | |||
| void | |||
| Timeline::apply_track_order ( void ) | |||
| { | |||
| wrlock(); | |||
| engine->lock(); | |||
| std::list<Track*> tl; | |||
| for ( int i = 0; i < tracks->children(); i++ ) | |||
| tl.push_back( (Track*)tracks->child( i ) ); | |||
| tl.sort(compare_tracks); | |||
| Fl_Widget **a = const_cast<Fl_Widget**>(tracks->array()); | |||
| int j = 0; | |||
| for ( std::list<Track*>::const_iterator i = tl.begin(); | |||
| i != tl.end(); | |||
| i++, j++ ) | |||
| a[j] = *i; | |||
| update_track_order(); | |||
| engine->unlock(); | |||
| unlock(); | |||
| } | |||
| void | |||
| Timeline::update_track_order ( void ) | |||
| { | |||
| for ( int i = 0; i < tracks->children(); i++ ) | |||
| ((Track*)tracks->child( i ))->row( i ); | |||
| } | |||
| int | |||
| Timeline::find_track ( const Track *track ) const | |||
| { | |||
| return tracks->find( *track ); | |||
| } | |||
| void | |||
| Timeline::move_track_up ( Track *track ) | |||
| { | |||
| insert_track( track, find_track( track ) - 1 ); | |||
| } | |||
| void | |||
| Timeline::move_track_down ( Track *track ) | |||
| { | |||
| insert_track( track, find_track( track ) + 2 ); | |||
| } | |||
| /** remove /track/ from the timeline */ | |||
| void | |||
| Timeline::remove_track ( Track *track ) | |||
| @@ -1504,10 +1591,13 @@ Timeline::remove_track ( Track *track ) | |||
| /* FIXME: what to do about track contents? */ | |||
| tracks->remove( track ); | |||
| update_track_order(); | |||
| engine->unlock(); | |||
| unlock(); | |||
| /* FIXME: why is this necessary? doesn't the above add do DAMAGE_CHILD? */ | |||
| redraw(); | |||
| } | |||
| @@ -1545,6 +1635,8 @@ Timeline::command_load ( const char *name, const char *display_name ) | |||
| Project::set_name ( display_name ? display_name : name ); | |||
| apply_track_order(); | |||
| return true; | |||
| } | |||
| @@ -127,6 +127,10 @@ class Timeline : public Fl_Single_Window, public RWLock | |||
| static void handle_peer_scan_complete ( void * v ); | |||
| void update_track_order ( void ); | |||
| void apply_track_order ( void ); | |||
| void insert_track ( Track *track, int n ); | |||
| public: | |||
| OSC::Endpoint *osc; | |||
| @@ -222,6 +226,11 @@ public: | |||
| void add_track ( Track *track ); | |||
| void remove_track ( Track *track ); | |||
| void move_track_up ( Track *track ); | |||
| void move_track_down ( Track *track ); | |||
| int find_track ( const Track * track ) const; | |||
| int ntracks ( void ) const; | |||
| void zoom ( float secs ); | |||
| @@ -109,6 +109,7 @@ Track::~Track ( ) | |||
| void | |||
| Track::init ( void ) | |||
| { | |||
| _row = 0; | |||
| _sequence = NULL; | |||
| _name = NULL; | |||
| _selected = false; | |||
| @@ -294,7 +295,8 @@ Track::set ( Log_Entry &e ) | |||
| } | |||
| } | |||
| else if ( ! strcmp( s, ":row" ) ) | |||
| row( atoi( v ) ); | |||
| } | |||
| } | |||
| @@ -317,6 +319,19 @@ Track::get_unjournaled ( Log_Entry &e ) const | |||
| e.add( ":armed", armed() ); | |||
| e.add( ":mute", mute() ); | |||
| e.add( ":solo", solo() ); | |||
| e.add( ":row", timeline->find_track( this ) ); | |||
| } | |||
| int | |||
| Track::row ( void ) const | |||
| { | |||
| return _row; | |||
| } | |||
| void | |||
| Track::row ( int n ) | |||
| { | |||
| _row = n; | |||
| } | |||
| void | |||
| @@ -780,6 +795,14 @@ Track::menu_cb ( const Fl_Menu_ *m ) | |||
| { | |||
| ((Fl_Sometimes_Input*)name_field)->take_focus(); | |||
| } | |||
| else if ( ! strcmp( picked, "/Move Up" ) ) | |||
| { | |||
| timeline->move_track_up( this ); | |||
| } | |||
| else if ( ! strcmp( picked, "/Move Down" ) ) | |||
| { | |||
| timeline->move_track_down( this ); | |||
| } | |||
| } | |||
| #include "FL/menu_popup.H" | |||
| @@ -816,6 +839,8 @@ Track::menu ( void ) const | |||
| { "Mute", FL_CTRL + 'm', 0, 0, FL_MENU_TOGGLE | ( mute() ? FL_MENU_VALUE : 0 ) }, | |||
| { "Solo", FL_CTRL + 's', 0, 0, FL_MENU_TOGGLE | ( solo() ? FL_MENU_VALUE : 0 ) }, | |||
| { 0 }, | |||
| { "Move Up", FL_SHIFT + '1', 0, 0 }, | |||
| { "Move Down", FL_SHIFT + '2', 0, 0 }, | |||
| { "Remove", 0, 0, 0 }, // transport->rolling ? FL_MENU_INACTIVE : 0 }, | |||
| { 0 }, | |||
| }; | |||
| @@ -85,6 +85,11 @@ public: | |||
| Fl_Color color ( void ) const { return child(0)->color(); } | |||
| void color ( Fl_Color c ) { child(0)->color( c ); } | |||
| bool operator< ( const Track &rhs ) const | |||
| { | |||
| return _row < rhs._row; | |||
| } | |||
| private: | |||
| static int _soloing; | |||
| @@ -97,6 +102,8 @@ private: | |||
| int _size; | |||
| int _row; | |||
| enum { AUDIO } _type; | |||
| Audio_Sequence *_sequence; | |||
| @@ -198,6 +205,8 @@ public: | |||
| bool selected ( void ) const { return _selected; } | |||
| int row ( void ) const; | |||
| void row ( int ); | |||
| static void cb_input_field ( Fl_Widget *w, void *v ); | |||
| void cb_input_field ( void ); | |||