diff --git a/Timeline/Audio_Sequence.C b/Timeline/Audio_Sequence.C index 72d43a0..c5ae1b1 100644 --- a/Timeline/Audio_Sequence.C +++ b/Timeline/Audio_Sequence.C @@ -75,10 +75,10 @@ Audio_Sequence::capture_region ( void ) const void Audio_Sequence::get ( Log_Entry &e ) const - { - e.add( ":track", _track ); - e.add( ":name", name() ); - } +{ + e.add( ":track", _track ); + e.add( ":name", name() ); +} void Audio_Sequence::set ( Log_Entry &e ) @@ -177,9 +177,9 @@ Audio_Sequence::draw ( void ) ++xfades; Rectangle b( (*r)->x(), - o->y(), - (o->x() + o->w()) - (*r)->x(), - o->h() ); + o->y(), + (o->x() + o->w()) - (*r)->x(), + o->h() ); Fl_Color c = fl_color_average( o->box_color(), (*r)->box_color(), 0.50f ); c = fl_color_average( c, FL_YELLOW, 0.30f ); diff --git a/Timeline/Loggable.C b/Timeline/Loggable.C index 9a64bda..fa102f5 100644 --- a/Timeline/Loggable.C +++ b/Timeline/Loggable.C @@ -56,6 +56,9 @@ std::queue Loggable::_transaction; progress_func *Loggable::_progress_callback = NULL; void *Loggable::_progress_callback_arg = NULL; +snapshot_func *Loggable::_snapshot_callback = NULL; +void *Loggable::_snapshot_callback_arg = NULL; + /** ensure that _loggables array is big enough for /n/ elements */ @@ -419,6 +422,12 @@ Loggable::snapshot ( FILE *fp ) { FILE *ofp = _fp; + if ( ! Loggable::_snapshot_callback ) + { + DWARNING( "No snapshot callback defined" ); + return false; + } + if ( ! ( _fp = fp ) ) { _fp = ofp; @@ -427,13 +436,7 @@ Loggable::snapshot ( FILE *fp ) block_start(); - for ( int i = 0; i < _log_id; ++i ) - { - const Loggable * l = _loggables[ i ]; - - if ( l && _class_map[ std::string( l->class_name() ) ] ) - l->log_create(); - } + Loggable::_snapshot_callback( _snapshot_callback_arg ); block_end(); diff --git a/Timeline/Loggable.H b/Timeline/Loggable.H index f71d1b4..6da28d8 100644 --- a/Timeline/Loggable.H +++ b/Timeline/Loggable.H @@ -34,6 +34,7 @@ #include "types.h" typedef void (progress_func)( int, void * ); +typedef void (snapshot_func)( void * ); class Log_Entry; class Loggable; @@ -79,6 +80,9 @@ class Loggable static progress_func *_progress_callback; static void *_progress_callback_arg; + static snapshot_func *_snapshot_callback; + static void *_snapshot_callback_arg; + private: int _id; @@ -124,6 +128,7 @@ private: public: + static void snapshot_callback ( snapshot_func *p, void *arg ) { _snapshot_callback = p; _snapshot_callback_arg = arg; } static void progress_callback ( progress_func *p, void *arg ) { _progress_callback = p; _progress_callback_arg = arg;} static const char *escape ( const char *s ); @@ -165,16 +170,17 @@ public: virtual const char *class_name ( void ) const = 0; + virtual void log_children ( void ) const { return; } static bool do_this ( const char *s, bool reverse ); + void log_create ( void ) const; protected: void log_start ( void ); void log_end ( void ); - void log_create ( void ) const; void log_destroy ( void ) const; /* leaf subclasses *must* call log_create() at the end of their copy contructors */ diff --git a/Timeline/Sequence.C b/Timeline/Sequence.C index 8c7c082..f87c1e9 100644 --- a/Timeline/Sequence.C +++ b/Timeline/Sequence.C @@ -85,23 +85,25 @@ Sequence::~Sequence ( ) +void +Sequence::log_children ( void ) const +{ + if ( id() > 0 ) + log_create(); + + for ( std::list ::const_iterator i = _widgets.begin(); + i != _widgets.end(); ++i ) + (*i)->log_create(); +} + /** remove all widgets from this sequence */ void Sequence::clear ( void ) { Loggable::block_start(); - for ( std::list ::iterator i = _widgets.begin(); - i != _widgets.end(); ++i ) - { - Sequence_Widget *w = *i; - - *i = NULL; - - delete w; - } - - _widgets.clear(); + while ( _widgets.size() ) + delete _widgets.front(); Loggable::block_end(); } @@ -137,6 +139,11 @@ Sequence::overlaps ( Sequence_Widget *r ) void Sequence::handle_widget_change ( nframes_t start, nframes_t length ) { + timeline->wrlock(); + + sort(); + + timeline->unlock(); // timeline->update_length( start + length ); } @@ -177,8 +184,6 @@ Sequence::add ( Sequence_Widget *r ) r->sequence( this ); _widgets.push_back( r ); - sort(); - timeline->unlock(); handle_widget_change( r->start(), r->length() ); diff --git a/Timeline/Sequence.H b/Timeline/Sequence.H index 87aeb72..2133f2e 100644 --- a/Timeline/Sequence.H +++ b/Timeline/Sequence.H @@ -62,9 +62,10 @@ protected: Sequence_Widget *widget_at ( nframes_t ts, int Y ); Sequence_Widget *event_widget ( void ); - public: + virtual void log_children ( void ) const; + /* child classes should implement this if they need to take special action when a widget is changed/moved/resized. /start/ and /length/ define the affected region */ diff --git a/Timeline/Sequence_Widget.C b/Timeline/Sequence_Widget.C index 50adf57..eea2d87 100644 --- a/Timeline/Sequence_Widget.C +++ b/Timeline/Sequence_Widget.C @@ -135,7 +135,7 @@ Sequence_Widget::set ( Log_Entry &e ) sscanf( v, "%X", &i ); Sequence *t = (Sequence*)Loggable::find( i ); - assert( t ); + ASSERT( t, "No such object ID (%s)", v ); t->add( this ); } @@ -144,8 +144,10 @@ Sequence_Widget::set ( Log_Entry &e ) } if ( _sequence ) + { + _sequence->handle_widget_change( _r->start, _r->length ); _sequence->redraw(); - + } } void diff --git a/Timeline/Tempo_Point.C b/Timeline/Tempo_Point.C index 3a80fff..bac51c2 100644 --- a/Timeline/Tempo_Point.C +++ b/Timeline/Tempo_Point.C @@ -83,7 +83,11 @@ Tempo_Point::set ( Log_Entry &e ) _make_label(); } - +void +Tempo_Point::log_children ( void ) const +{ + log_create(); +} int Tempo_Point::handle ( int m ) diff --git a/Timeline/Tempo_Point.H b/Timeline/Tempo_Point.H index f8389dd..f3e4396 100644 --- a/Timeline/Tempo_Point.H +++ b/Timeline/Tempo_Point.H @@ -44,6 +44,7 @@ protected: virtual void get ( Log_Entry &e ) const; void set ( Log_Entry &e ); + void log_children ( void ) const; Tempo_Point ( ); diff --git a/Timeline/Time_Point.C b/Timeline/Time_Point.C index 1dd243d..f1c1ad1 100644 --- a/Timeline/Time_Point.C +++ b/Timeline/Time_Point.C @@ -93,6 +93,12 @@ Time_Point::set ( Log_Entry &e ) _make_label(); } +void +Time_Point::log_children ( void ) const +{ + log_create(); +} + int Time_Point::handle ( int m ) { diff --git a/Timeline/Time_Point.H b/Timeline/Time_Point.H index b589fc1..5d51337 100644 --- a/Timeline/Time_Point.H +++ b/Timeline/Time_Point.H @@ -57,6 +57,7 @@ protected: virtual void get ( Log_Entry &e ) const; void set ( Log_Entry &e ); + void log_children ( void ) const; Time_Point ( ); diff --git a/Timeline/Timeline.C b/Timeline/Timeline.C index faaa679..51e6b89 100644 --- a/Timeline/Timeline.C +++ b/Timeline/Timeline.C @@ -105,6 +105,20 @@ draw_full_arrow_symbol ( Fl_Color color ) +/** callback used by Loggable class to create a snapshot of system + * state. */ +void +Timeline::snapshot ( void ) +{ + tempo_track->log_children(); + time_track->log_children(); + + for ( int i = 0; i < tracks->children(); ++i ) + { + ((Track*)tracks->child( i ))->log_children(); + } +} + /** recalculate the size of vertical scrolling area and inform scrollbar */ void Timeline::adjust_vscroll ( void ) @@ -347,6 +361,8 @@ Timeline::ntracks ( void ) const Timeline::Timeline ( int X, int Y, int W, int H, const char* L ) : Fl_Overlay_Window( X, Y, W, H, L ) { + Loggable::snapshot_callback( &Timeline::snapshot, this ); + _sample_rate = 0; box( FL_FLAT_BOX ); diff --git a/Timeline/Timeline.H b/Timeline/Timeline.H index 73b15f2..ed68f5d 100644 --- a/Timeline/Timeline.H +++ b/Timeline/Timeline.H @@ -213,6 +213,9 @@ public: private: + static void snapshot ( void *v ) { ((Timeline*)v)->snapshot(); } + void snapshot ( void ); + friend class Engine; // FIXME: only Engine::process() needs to be friended.x Track * track_by_name ( const char *name ); diff --git a/Timeline/Track.C b/Timeline/Track.C index be2547f..1a9b152 100644 --- a/Timeline/Track.C +++ b/Timeline/Track.C @@ -72,16 +72,6 @@ Track::Track ( ) : Fl_Group( 0, 0, 1, 1 ) timeline->add_track( this ); } -void -Track::solo ( bool b ) -{ - if ( b && ! solo_button->value() ) - ++_soloing; - else if ( ! b && solo_button->value() ) - --_soloing; - - solo_button->value( b ); -} Track::~Track ( ) { @@ -306,6 +296,33 @@ Track::get ( Log_Entry &e ) const e.add( ":show-all-takes", _show_all_takes ); } +void +Track::log_children ( void ) const +{ + log_create(); + + for ( int i = control->children(); i--; ) + ((Sequence*)control->child( i ))->log_children(); + + for ( int i = annotation->children(); i--; ) + ((Sequence*)annotation->child( i ))->log_children(); + + for ( int i = takes->children(); i--; ) + ((Sequence*)takes->child( i ))->log_children(); + + sequence()->log_children(); +} + +void +Track::solo ( bool b ) +{ + if ( b && ! solo_button->value() ) + ++_soloing; + else if ( ! b && solo_button->value() ) + --_soloing; + + solo_button->value( b ); +} void Track::cb_input_field ( Fl_Widget *, void *v ) diff --git a/Timeline/Track.H b/Timeline/Track.H index 678e5ad..060da3d 100644 --- a/Timeline/Track.H +++ b/Timeline/Track.H @@ -108,6 +108,8 @@ protected: public: + virtual void log_children ( void ) const; + Fl_Input *name_field; Fl_Button *record_button; Fl_Button *mute_button;