diff --git a/Loggable.C b/Loggable.C index fa5d300..6a28782 100644 --- a/Loggable.C +++ b/Loggable.C @@ -31,6 +31,7 @@ int Loggable::_level = 0; int Loggable::_undo_index = 1; vector Loggable::_loggables; +map Loggable::_class_map; bool Loggable::open ( const char *filename ) @@ -45,6 +46,7 @@ Loggable::open ( const char *filename ) } /** sigh. parse a string of ":name value :name value" pairs into an array of strings, one per pair */ +// FIXME: doesn't handle the case of :name ":foo bar". Also, quotes should be removed here, not in client code. static char ** parse_alist( const char *s ) @@ -94,6 +96,17 @@ parse_alist( const char *s ) } +static +void free_sa ( char **sa ) +{ + char **a = sa; + for ( ; *a; a++ ) + free( *a ); + + free( sa ); +} + + void Loggable::undo ( void ) { @@ -113,18 +126,22 @@ Loggable::undo ( void ) // FIXME: handle blocks int i = 1; - /* move back _undo_index lines from the end */ + /* move back _undo_index items from the end */ for ( int j = _undo_index; j-- ; ) for ( --s; *s && s >= buf; --s, ++i ) { if ( *s == '\n' ) { - // s++; + if ( *(s + 1) == '\t' ) + continue; + break; } } s++; + strtok( s, "\n" ); + buf[ len ] = NULL; // fsync( fileno( _fp ) ); @@ -144,23 +161,58 @@ Loggable::undo ( void ) int id; sscanf( s, "%*s %X ", &id ); Loggable *l = find( id ); - assert( l ); +// assert( l ); + char classname[40]; char command[40]; char *arguments; - sscanf( s, "%*s %*X %s %*[^\n<] << %a[^\n]", command, &arguments ); + sscanf( s, "%s %*X %s %*[^\n<] << %a[^\n]", classname, command, &arguments ); + + + int ui = _undo_index; - if ( ! strcmp( command, "set" ) ) + + if ( ! l ) { + printf( "corrupt undo?\n" ); + abort(); + } - printf( "got set command.\n" ); - char **sa = parse_alist( arguments ); - l->set( sa ); + if ( ! strcmp( command, "destroy" ) ) + { + printf( "should create new %s here\n", classname ); + char **sa = parse_alist( arguments ); + + _class_map[ string( classname ) ]( sa ); } + else + if ( ! strcmp( command, "set" ) ) + { + + printf( "got set command.\n" ); + + char **sa = parse_alist( arguments ); + + l->log_start(); + l->set( sa ); + l->log_end(); + + } + else + if ( ! strcmp( command, "create" ) ) + { + int id = l->id(); + delete l; + _loggables[ id ] = NULL; + } + + +// FIXME: bogus... needs to account for multiple events. + _undo_index = ui + 1; ++_undo_index; @@ -184,17 +236,6 @@ Loggable::log ( const char *fmt, ... ) } -static -void free_sa ( char **sa ) -{ - char **a = sa; - for ( ; *a; a++ ) - free( *a ); - - free( sa ); -} - - void Loggable::log_print( char **o, char **n ) { @@ -244,10 +285,6 @@ log_diff ( char **sa1, char **sa2 ) return w == 0 ? false : true; } - - - - void Loggable::log_start ( void ) { @@ -256,6 +293,7 @@ Loggable::log_start ( void ) ++_nest; + _undo_index = 1; } void @@ -300,7 +338,7 @@ void Loggable::log_create ( void ) { indent(); - log( "%s 0x%X new ", class_name(), _id ); + log( "%s 0x%X create ", class_name(), _id ); char **sa = log_dump(); @@ -317,11 +355,12 @@ void Loggable::log_destroy ( void ) { indent(); - log( "%s 0x%X destroy ", class_name(), _id ); + log( "%s 0x%X destroy (nothing) << ", class_name(), _id ); char **sa = log_dump(); - log_print( sa, NULL ); +// log_print( sa, NULL ); + log_print( NULL, sa ); free_sa( sa ); } diff --git a/Loggable.H b/Loggable.H index 36f4121..aa07a10 100644 --- a/Loggable.H +++ b/Loggable.H @@ -28,6 +28,13 @@ #include using std::vector; +#include +using std::map; +#include +using std::string; + +class Loggable; +typedef Loggable *(create_func)(char **); class Logger; class Loggable @@ -40,6 +47,8 @@ class Loggable static vector _loggables; + static map _class_map; + private: int _id; @@ -65,13 +74,14 @@ public: static bool open ( const char *filename ); static void undo ( void ); + static int undo_index ( void ) { return _undo_index; } static void block_start ( void ) { indent(); - log( "{\n" ); +// log( "{\n" ); ++Loggable::_level; } static @@ -80,7 +90,7 @@ public: { assert( --Loggable::_level >= 0 ); indent(); - log( "}\n" ); +// log( "}\n" ); } static @@ -102,6 +112,21 @@ public: _loggables.push_back( this ); } + virtual ~Loggable ( ) + { + + + + } + + static + void + register_create ( const char *name, create_func *func ) + { + printf( "registering %s to %p\n", name, func ); + + _class_map[ string( name ) ] = func; + } /* log messages for journal */ virtual const char *class_name ( void ) = 0; diff --git a/Region.H b/Region.H index 25686c4..aea2947 100644 --- a/Region.H +++ b/Region.H @@ -63,15 +63,18 @@ protected: char ** log_dump ( void ) { // char *r; - char **sa = (char**)malloc( sizeof( char* ) * 6 ); + char **sa = (char**)malloc( sizeof( char* ) * 7 ); - sa[5] = NULL; + int i = 0; - asprintf( &sa[0], ":x %lu", _offset ); - asprintf( &sa[1], ":l %lu", _start ); - asprintf( &sa[2], ":r %lu", _end ); - asprintf( &sa[3], ":selected %d", _selected ); - asprintf( &sa[4], ":gain %f", _scale ); + asprintf( &sa[ i++ ], ":source \"%s\"", _clip->name() ); + asprintf( &sa[ i++ ], ":x %lu", _offset ); + asprintf( &sa[ i++ ], ":l %lu", _start ); + asprintf( &sa[ i++ ], ":r %lu", _end ); + asprintf( &sa[ i++ ], ":selected %d", _selected ); + asprintf( &sa[ i++ ], ":gain %f", _scale ); + + sa[ i ] = NULL; // asprintf( &sa[4], ":track 0x%X", _track->id() ); // asprintf( &r, ":x %lu\n:l %lu\n:r %lu\n:selected %d\n:gain %f", _offset, _start, _end, _selected, _scale ); @@ -90,6 +93,12 @@ protected: char *v = s + strlen( s ) + 1; + if ( *v == '"' ) + { + v++; + v[ strlen( v ) - 2 ] = '\0'; + } + if ( ! strcmp( s, ":x" ) ) _offset = atol( v ); else @@ -104,7 +113,9 @@ protected: else if ( ! strcmp( s, ":gain" ) ) _scale = atof( v ); - + else + if ( ! strcmp( s, ":source" ) ) + _clip = Audio_File::from_file( v ); /* else */ /* if ( ! strcmp( s, ":track" ) ) */ /* { */ @@ -123,11 +134,29 @@ protected: free( sa ); - _track->redraw(); + if ( _track ) + _track->redraw(); + } + + Region ( ) + { + init(); } public: + /* for loggable */ + static Loggable * + create ( char **sa ) + { + Region *r = new Region; + + r->set( sa ); + + return (Loggable *)r; + } + + Fl_Boxtype box ( void ) const { return Region::_box; } Fl_Align align ( void ) const { return (Fl_Align)(FL_ALIGN_LEFT | FL_ALIGN_BOTTOM /*| FL_ALIGN_CLIP*/ | FL_ALIGN_INSIDE); } diff --git a/Timeline.C b/Timeline.C index fd5cf9e..0f12f96 100644 --- a/Timeline.C +++ b/Timeline.C @@ -55,7 +55,9 @@ cb_vscroll ( Fl_Widget *w, void *v ) timeline->tracks->position( timeline->tracks->x(), (timeline->rulers->y() + timeline->rulers->h()) - sb->value() ); timeline->yposition = sb->value(); - timeline->vscroll->range( 0, timeline->tracks->h() - timeline->h() - timeline->rulers->h() ); +// timeline->vscroll->range( 0, timeline->tracks->h() - timeline->h() - timeline->rulers->h() ); + + sb->value( sb->value(), 30, 0, min( timeline->tracks->h(), timeline->tracks->h() - timeline->h() - timeline->rulers->h() ) ); timeline->damage( FL_DAMAGE_SCROLL ); } diff --git a/Track.H b/Track.H index af72508..2825638 100644 --- a/Track.H +++ b/Track.H @@ -91,8 +91,11 @@ public: log_create(); } - ~Track ( ) + virtual ~Track ( ) { + /* FIXME: what to do with regions? */ + parent()->redraw(); + parent()->remove( this ); log_destroy(); } diff --git a/Track_Widget.H b/Track_Widget.H index 8d728d7..a62b629 100644 --- a/Track_Widget.H +++ b/Track_Widget.H @@ -53,6 +53,12 @@ public: _selected = false; } + virtual ~Track_Widget ( ) + { + redraw(); + _track->remove( this ); + } + Fl_Group * parent ( void ) const { return _track; } int scroll_x ( void ) const { return timeline->ts_to_x( timeline->xoffset ); } diff --git a/main.C b/main.C index 0cfb977..07af037 100644 --- a/main.C +++ b/main.C @@ -53,7 +53,13 @@ Timeline *timeline; void cb_undo ( Fl_Widget *w, void *v ) { + static char pat[20]; + + Loggable::undo(); + + sprintf( pat, "undo %d", Loggable::undo_index() ); + w->label( pat ); } int @@ -65,6 +71,8 @@ main ( int argc, char **argv ) Fl::scheme( "plastic" ); Loggable::open( "history" ); + Loggable::register_create( "Region", &Region::create ); + timeline = new Timeline( 0, 0, 800, 600, "Timeline" );