@@ -1482,6 +1482,8 @@ Timeline::add_track ( Track *track ) | |||||
tracks->add( track ); | tracks->add( track ); | ||||
// update_track_order(); | |||||
engine->unlock(); | engine->unlock(); | ||||
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 */ | /** remove /track/ from the timeline */ | ||||
void | void | ||||
Timeline::remove_track ( Track *track ) | Timeline::remove_track ( Track *track ) | ||||
@@ -1504,10 +1591,13 @@ Timeline::remove_track ( Track *track ) | |||||
/* FIXME: what to do about track contents? */ | /* FIXME: what to do about track contents? */ | ||||
tracks->remove( track ); | tracks->remove( track ); | ||||
update_track_order(); | |||||
engine->unlock(); | engine->unlock(); | ||||
unlock(); | unlock(); | ||||
/* FIXME: why is this necessary? doesn't the above add do DAMAGE_CHILD? */ | /* FIXME: why is this necessary? doesn't the above add do DAMAGE_CHILD? */ | ||||
redraw(); | redraw(); | ||||
} | } | ||||
@@ -1545,6 +1635,8 @@ Timeline::command_load ( const char *name, const char *display_name ) | |||||
Project::set_name ( display_name ? display_name : name ); | Project::set_name ( display_name ? display_name : name ); | ||||
apply_track_order(); | |||||
return true; | return true; | ||||
} | } | ||||
@@ -127,6 +127,10 @@ class Timeline : public Fl_Single_Window, public RWLock | |||||
static void handle_peer_scan_complete ( void * v ); | 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: | public: | ||||
OSC::Endpoint *osc; | OSC::Endpoint *osc; | ||||
@@ -222,6 +226,11 @@ public: | |||||
void add_track ( Track *track ); | void add_track ( Track *track ); | ||||
void remove_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; | int ntracks ( void ) const; | ||||
void zoom ( float secs ); | void zoom ( float secs ); | ||||
@@ -109,6 +109,7 @@ Track::~Track ( ) | |||||
void | void | ||||
Track::init ( void ) | Track::init ( void ) | ||||
{ | { | ||||
_row = 0; | |||||
_sequence = NULL; | _sequence = NULL; | ||||
_name = NULL; | _name = NULL; | ||||
_selected = false; | _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( ":armed", armed() ); | ||||
e.add( ":mute", mute() ); | e.add( ":mute", mute() ); | ||||
e.add( ":solo", solo() ); | 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 | void | ||||
@@ -780,6 +795,14 @@ Track::menu_cb ( const Fl_Menu_ *m ) | |||||
{ | { | ||||
((Fl_Sometimes_Input*)name_field)->take_focus(); | ((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" | #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 ) }, | { "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 ) }, | { "Solo", FL_CTRL + 's', 0, 0, FL_MENU_TOGGLE | ( solo() ? FL_MENU_VALUE : 0 ) }, | ||||
{ 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 }, | { "Remove", 0, 0, 0 }, // transport->rolling ? FL_MENU_INACTIVE : 0 }, | ||||
{ 0 }, | { 0 }, | ||||
}; | }; | ||||
@@ -85,6 +85,11 @@ public: | |||||
Fl_Color color ( void ) const { return child(0)->color(); } | Fl_Color color ( void ) const { return child(0)->color(); } | ||||
void color ( Fl_Color c ) { child(0)->color( c ); } | void color ( Fl_Color c ) { child(0)->color( c ); } | ||||
bool operator< ( const Track &rhs ) const | |||||
{ | |||||
return _row < rhs._row; | |||||
} | |||||
private: | private: | ||||
static int _soloing; | static int _soloing; | ||||
@@ -97,6 +102,8 @@ private: | |||||
int _size; | int _size; | ||||
int _row; | |||||
enum { AUDIO } _type; | enum { AUDIO } _type; | ||||
Audio_Sequence *_sequence; | Audio_Sequence *_sequence; | ||||
@@ -198,6 +205,8 @@ public: | |||||
bool selected ( void ) const { return _selected; } | bool selected ( void ) const { return _selected; } | ||||
int row ( void ) const; | |||||
void row ( int ); | |||||
static void cb_input_field ( Fl_Widget *w, void *v ); | static void cb_input_field ( Fl_Widget *w, void *v ); | ||||
void cb_input_field ( void ); | void cb_input_field ( void ); | ||||