Work on making delete undoable.
This commit is contained in:
parent
3d57bf5c52
commit
66815ae8fb
99
Loggable.C
99
Loggable.C
|
@ -31,6 +31,7 @@ int Loggable::_level = 0;
|
|||
int Loggable::_undo_index = 1;
|
||||
|
||||
vector <Loggable *> Loggable::_loggables;
|
||||
map <string, create_func*> 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,24 +161,59 @@ 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 );
|
||||
|
||||
if ( ! strcmp( command, "set" ) )
|
||||
|
||||
int ui = _undo_index;
|
||||
|
||||
|
||||
if ( ! l )
|
||||
{
|
||||
|
||||
printf( "got set command.\n" );
|
||||
|
||||
char **sa = parse_alist( arguments );
|
||||
|
||||
l->set( sa );
|
||||
|
||||
printf( "corrupt undo?\n" );
|
||||
abort();
|
||||
}
|
||||
|
||||
|
||||
|
||||
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;
|
||||
|
||||
delete buf;
|
||||
|
@ -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 );
|
||||
}
|
||||
|
|
29
Loggable.H
29
Loggable.H
|
@ -28,6 +28,13 @@
|
|||
|
||||
#include <vector>
|
||||
using std::vector;
|
||||
#include <map>
|
||||
using std::map;
|
||||
#include <string>
|
||||
using std::string;
|
||||
|
||||
class Loggable;
|
||||
typedef Loggable *(create_func)(char **);
|
||||
|
||||
class Logger;
|
||||
class Loggable
|
||||
|
@ -40,6 +47,8 @@ class Loggable
|
|||
|
||||
static vector <Loggable *> _loggables;
|
||||
|
||||
static map <string, create_func*> _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;
|
||||
|
|
47
Region.H
47
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); }
|
||||
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
|
5
Track.H
5
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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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 ); }
|
||||
|
|
8
main.C
8
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" );
|
||||
|
||||
|
|
Loading…
Reference in New Issue