@@ -28,6 +28,8 @@ FILE *Loggable::_fp; | |||||
int Loggable::_log_id = 0; | int Loggable::_log_id = 0; | ||||
vector <Loggable *> Loggable::_loggables; | |||||
bool | bool | ||||
Loggable::open ( const char *filename ) | Loggable::open ( const char *filename ) | ||||
{ | { | ||||
@@ -56,3 +58,118 @@ Loggable::log ( const char *module, const char *action, const char *fmt, ... ) | |||||
fprintf( _fp, "\n" ); | fprintf( _fp, "\n" ); | ||||
} | } | ||||
static | |||||
void free_sa ( char **sa ) | |||||
{ | |||||
char **a = sa; | |||||
for ( ; *a; a++ ) | |||||
free( *a ); | |||||
free( sa ); | |||||
} | |||||
static | |||||
void | |||||
log_print( char **o, char **n ) | |||||
{ | |||||
if ( n ) | |||||
for ( ; *n; n++ ) | |||||
printf( "%s%s", *n, *(n + 1) ? " " : "" ); | |||||
if ( o && *o ) | |||||
{ | |||||
if ( n ) printf( " << " ); | |||||
for ( ; *o; o++ ) | |||||
printf( "%s%s", *o, *(o + 1) ? " " : "" ); | |||||
} | |||||
printf( "\n" ); | |||||
} | |||||
/** compare elements of dumps s1 and s2, removing those elements | |||||
of dst which are not changed from src */ | |||||
static | |||||
void | |||||
log_diff ( char **sa1, char **sa2 ) | |||||
{ | |||||
if ( ! sa1 ) | |||||
return; | |||||
int w = 0; | |||||
for ( int i = 0; sa1[ i ]; ++i ) | |||||
{ | |||||
if ( ! strcmp( sa1[ i ], sa2[ i ] ) ) | |||||
{ | |||||
free( sa2[ i ] ); | |||||
free( sa1[ i ] ); | |||||
} | |||||
else | |||||
{ | |||||
sa2[ w ] = sa2[ i ]; | |||||
sa1[ w ] = sa1[ i ]; | |||||
w++; | |||||
} | |||||
} | |||||
sa1[ w ] = NULL; | |||||
sa2[ w ] = NULL; | |||||
} | |||||
void | |||||
Loggable::log_start ( void ) | |||||
{ | |||||
if ( ! _old_state ) | |||||
_old_state = log_dump(); | |||||
} | |||||
void | |||||
Loggable::log_end ( void ) | |||||
{ | |||||
char **_new_state = log_dump(); | |||||
// if ( _old_state ) | |||||
log_diff( _old_state, _new_state ); | |||||
printf( "%s 0x%X set ", class_name(), _id ); | |||||
log_print( _old_state, _new_state ); | |||||
free_sa( _old_state ); | |||||
if ( _new_state ) | |||||
free_sa( _new_state ); | |||||
_old_state = NULL; | |||||
} | |||||
void | |||||
Loggable::log_create ( void ) | |||||
{ | |||||
printf( "%s 0x%X new ", class_name(), _id ); | |||||
char **sa = log_dump(); | |||||
log_print( NULL, sa ); | |||||
free_sa( sa ); | |||||
} | |||||
void | |||||
Loggable::log_destroy ( void ) | |||||
{ | |||||
printf( "%s 0x%X destroy ", class_name(), _id ); | |||||
char **sa = log_dump(); | |||||
log_print( sa, NULL ); | |||||
free_sa( sa ); | |||||
} |
@@ -22,6 +22,12 @@ | |||||
#pragma once | #pragma once | ||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <stdlib.h> | |||||
#include <string.h> | |||||
#include <vector> | |||||
using std::vector; | |||||
class Loggable | class Loggable | ||||
{ | { | ||||
@@ -29,28 +35,60 @@ class Loggable | |||||
static FILE *_fp; | static FILE *_fp; | ||||
static int _log_id; | static int _log_id; | ||||
static vector <Loggable *> _loggables; | |||||
private: | private: | ||||
int _id; | int _id; | ||||
char **_old_state; | |||||
char **_new_state; | |||||
public: | public: | ||||
static bool open ( const char *filename ); | static bool open ( const char *filename ); | ||||
static | |||||
Loggable * | |||||
find ( int id ) | |||||
{ | |||||
if ( id > _log_id ) | |||||
return NULL; | |||||
return _loggables[ id ]; | |||||
} | |||||
Loggable ( ) | Loggable ( ) | ||||
{ | { | ||||
_id = ++_log_id; | _id = ++_log_id; | ||||
_old_state = NULL; | |||||
_loggables.push_back( this ); | |||||
} | } | ||||
/* log messages for journal */ | /* log messages for journal */ | ||||
virtual void log_create ( void ) = 0; | |||||
virtual void log_destroy ( void ) = 0; | |||||
virtual void log_move ( void ) = 0; | |||||
virtual void log_change ( void ) = 0; | |||||
virtual const char *class_name ( void ) = 0; | |||||
virtual char ** log_dump ( void ) = 0; | |||||
/* this method must parse an array of name/value pair strings and make the appropriate changes too | |||||
the object state */ | |||||
virtual void set ( char **sa ) = 0; | |||||
// void log ( const char *module, const char *action, const char *fmt, ... ); | |||||
protected: | |||||
void log ( const char *module, const char *action, const char *fmt, ... ); | void log ( const char *module, const char *action, const char *fmt, ... ); | ||||
void log_start ( void ); | |||||
void log_end ( void ); | |||||
void log_create ( void ); | |||||
void log_destroy ( void ); | |||||
}; | }; | ||||
#ifndef _LOGGABLE_C | #ifndef _LOGGABLE_C | ||||
#define log( act, fmt, args... ) log( __CLASS__, act, fmt, ## args ) | #define log( act, fmt, args... ) log( __CLASS__, act, fmt, ## args ) | ||||
#endif | #endif | ||||
/* #define LOG_START Logger _logger( this ) */ | |||||
/* #define LOG_END _logger.print( this ) */ |
@@ -131,7 +131,7 @@ Region::trim ( enum trim_e t, int X ) | |||||
long td = timeline->x_to_ts( d ); | long td = timeline->x_to_ts( d ); | ||||
printf( "%li %li\n", td, _end - _start ); | |||||
// printf( "%li %li\n", td, _end - _start ); | |||||
if ( td >= 0 && _end - _start < td ) | if ( td >= 0 && _end - _start < td ) | ||||
_end = _start + timeline->x_to_ts( 1 ); | _end = _start + timeline->x_to_ts( 1 ); | ||||
@@ -161,6 +161,7 @@ Region::handle ( int m ) | |||||
int ret; | int ret; | ||||
log_start(); | |||||
switch ( m ) | switch ( m ) | ||||
{ | { | ||||
@@ -178,11 +179,11 @@ Region::handle ( int m ) | |||||
case 3: | case 3: | ||||
trim( trimming = RIGHT, X ); | trim( trimming = RIGHT, X ); | ||||
break; | break; | ||||
default: | default: | ||||
return 0; | return 0; | ||||
break; | |||||
} | } | ||||
fl_cursor( FL_CURSOR_WE ); | fl_cursor( FL_CURSOR_WE ); | ||||
return 1; | return 1; | ||||
} | } | ||||
@@ -205,11 +206,13 @@ Region::handle ( int m ) | |||||
else | else | ||||
_selected = ! _selected; | _selected = ! _selected; | ||||
log_change(); | |||||
redraw(); | redraw(); | ||||
goto changed; | |||||
} | } | ||||
ret = Track_Widget::handle( m ); | ret = Track_Widget::handle( m ); | ||||
return ret | 1; | return ret | 1; | ||||
} | } | ||||
@@ -221,9 +224,9 @@ Region::handle ( int m ) | |||||
if ( trimming != NO ) | if ( trimming != NO ) | ||||
{ | { | ||||
trimming = NO; | trimming = NO; | ||||
log_change(); | |||||
} | } | ||||
return 1; | |||||
printf( "releasing\n"); | |||||
goto changed; | |||||
case FL_DRAG: | case FL_DRAG: | ||||
if ( Fl::event_state() & FL_SHIFT && | if ( Fl::event_state() & FL_SHIFT && | ||||
@@ -278,20 +281,20 @@ Region::handle ( int m ) | |||||
_track->prev()->add( this ); | _track->prev()->add( this ); | ||||
} | } | ||||
// _track->redraw(); | |||||
// _track->damage( FL_DAMAGE_EXPOSE, x(), y(), w(), h() ); | // _track->damage( FL_DAMAGE_EXPOSE, x(), y(), w(), h() ); | ||||
ret = Track_Widget::handle( m ); | ret = Track_Widget::handle( m ); | ||||
return ret | 1; | return ret | 1; | ||||
// _offset = timeline->x_to_ts( x() ); | |||||
default: | default: | ||||
return Track_Widget::handle( m ); | return Track_Widget::handle( m ); | ||||
break; | break; | ||||
} | } | ||||
changed: | |||||
log_end(); | |||||
return 1; | |||||
} | } | ||||
void | void | ||||
@@ -35,6 +35,8 @@ using namespace std; | |||||
#include "Track_Widget.H" | #include "Track_Widget.H" | ||||
#include "Loggable.H" | |||||
/* got I hate C++ */ | /* got I hate C++ */ | ||||
#define __CLASS__ "Region" | #define __CLASS__ "Region" | ||||
@@ -56,25 +58,56 @@ class Region : public Track_Widget | |||||
protected: | protected: | ||||
/* general */ | |||||
void log_create ( void ) | |||||
{ | |||||
log( "create", "%lu \"%s\" %d %f %lu %lu", _offset, _clip->name(), _selected, _scale, _start, _end ); | |||||
} | |||||
const char *class_name ( void ) { return "Region"; } | |||||
void log_destroy ( void ) | |||||
char ** log_dump ( void ) | |||||
{ | { | ||||
log( "destroy", NULL ); | |||||
} | |||||
// char *r; | |||||
char **sa = (char**)malloc( sizeof( char* ) * 6 ); | |||||
void log_move ( void ) | |||||
{ | |||||
log( "move", "%lu", _offset ); | |||||
sa[5] = NULL; | |||||
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( &r, ":x %lu\n:l %lu\n:r %lu\n:selected %d\n:gain %f", _offset, _start, _end, _selected, _scale ); | |||||
return sa; | |||||
} | } | ||||
void log_change ( void ) | |||||
void | |||||
set ( char **sa ) | |||||
{ | { | ||||
log( "change", "%d %f %lu %lu", _selected, _scale, _start, _end ); | |||||
for ( int i = 0; sa[i]; ++i ) | |||||
{ | |||||
char *s = sa[i]; | |||||
strtok( s, " " ); | |||||
char *v = s + strlen( s ); | |||||
if ( ! strcmp( s, ":x" ) ) | |||||
_offset = atol( v ); | |||||
else | |||||
if ( ! strcmp( s, ":l" ) ) | |||||
_start = atol( v ); | |||||
else | |||||
if ( ! strcmp( s, ":r" ) ) | |||||
_end = atol( v ); | |||||
else | |||||
if ( ! strcmp( s, ":selected" ) ) | |||||
_selected = atoi( v ); | |||||
else | |||||
if ( ! strcmp( s, ":gain" ) ) | |||||
_scale = atof( v ); | |||||
free( s ); | |||||
} | |||||
free( sa ); | |||||
} | } | ||||
public: | public: | ||||
@@ -38,6 +38,8 @@ class Tempo_Point : public Track_Point | |||||
protected: | protected: | ||||
const char *class_name ( void ) { return "Tempo_Point"; } | |||||
void log_create ( void ) { log( "create", "%lu %f", _offset, _tempo ); } | void log_create ( void ) { log( "create", "%lu %f", _offset, _tempo ); } | ||||
void log_destroy ( void ) { log( "destroy", NULL ); } | void log_destroy ( void ) { log( "destroy", NULL ); } | ||||
void log_move ( void ) { log( "move", "%lu", _offset ); } | void log_move ( void ) { log( "move", "%lu", _offset ); } | ||||
@@ -52,6 +52,8 @@ class Time_Point : public Track_Point | |||||
protected: | protected: | ||||
const char *class_name ( void ) { return "Time_Point"; } | |||||
void log_create ( void ) { log( "create", "%lu %d %d", _offset, _time.beats_per_bar, _time.note_type ); } | void log_create ( void ) { log( "create", "%lu %d %d", _offset, _time.beats_per_bar, _time.note_type ); } | ||||
void log_destroy ( void ) { log( "destroy", NULL ); } | void log_destroy ( void ) { log( "destroy", NULL ); } | ||||
void log_move ( void ) { log( "move", "%lu", _offset ); } | void log_move ( void ) { log( "move", "%lu", _offset ); } | ||||
@@ -73,7 +73,6 @@ Track::remove ( Track_Widget *r ) | |||||
Track_Widget * | Track_Widget * | ||||
Track::event_widget ( void ) | Track::event_widget ( void ) | ||||
{ | { | ||||
// FIXME: doesn't handle overlap! | |||||
int ets = timeline->xoffset + timeline->x_to_ts( Fl::event_x() ); | int ets = timeline->xoffset + timeline->x_to_ts( Fl::event_x() ); | ||||
for ( list <Track_Widget *>::const_reverse_iterator r = _widgets.rbegin(); r != _widgets.rend(); r++ ) | for ( list <Track_Widget *>::const_reverse_iterator r = _widgets.rbegin(); r != _widgets.rend(); r++ ) | ||||
if ( ets > (*r)->offset() && ets < (*r)->offset() + (*r)->length() ) | if ( ets > (*r)->offset() && ets < (*r)->offset() + (*r)->length() ) | ||||
@@ -146,7 +145,7 @@ done: | |||||
int | int | ||||
Track::handle ( int m ) | Track::handle ( int m ) | ||||
{ | { | ||||
static Track_Widget *current_widget; | |||||
static Track_Widget *pushed; | |||||
switch ( m ) | switch ( m ) | ||||
{ | { | ||||
@@ -155,27 +154,24 @@ Track::handle ( int m ) | |||||
return 1; | return 1; | ||||
default: | default: | ||||
{ | { | ||||
Track_Widget *r = event_widget(); | |||||
if ( current_widget ) | |||||
r = current_widget; | |||||
Track_Widget *r = pushed ? pushed : event_widget(); | |||||
if ( r ) | if ( r ) | ||||
{ | { | ||||
int retval = r->handle( m ); | int retval = r->handle( m ); | ||||
if ( retval && m == FL_PUSH ) | if ( retval && m == FL_PUSH ) | ||||
current_widget = r; | |||||
pushed = r; | |||||
if ( retval && m == FL_RELEASE ) | if ( retval && m == FL_RELEASE ) | ||||
current_widget = NULL; | |||||
pushed = NULL; | |||||
if ( _queued_widget ) | if ( _queued_widget ) | ||||
{ | { | ||||
remove( _queued_widget ); | remove( _queued_widget ); | ||||
delete _queued_widget; | delete _queued_widget; | ||||
_queued_widget = NULL; | _queued_widget = NULL; | ||||
current_widget = NULL; | |||||
// redraw(); | |||||
pushed = NULL; | |||||
} | } | ||||
return retval; | return retval; | ||||
@@ -28,6 +28,14 @@ protected: | |||||
char *_label; | char *_label; | ||||
void set ( char **a ) | |||||
{ | |||||
} | |||||
char ** log_dump ( void ) | |||||
{ | |||||
return NULL; | |||||
} | |||||
void log_change ( void ) | void log_change ( void ) | ||||
{ | { | ||||
} | } | ||||
@@ -206,6 +206,12 @@ public: | |||||
switch ( m ) | switch ( m ) | ||||
{ | { | ||||
case FL_ENTER: | |||||
fl_cursor( FL_CURSOR_HAND ); | |||||
return 1; | |||||
case FL_LEAVE: | |||||
fl_cursor( FL_CURSOR_DEFAULT ); | |||||
return 1; | |||||
case FL_PUSH: | case FL_PUSH: | ||||
{ | { | ||||
ox = x() - X; | ox = x() - X; | ||||
@@ -226,7 +232,7 @@ public: | |||||
case FL_RELEASE: | case FL_RELEASE: | ||||
if ( moved ) | if ( moved ) | ||||
{ | { | ||||
log_move(); | |||||
// log_move(); | |||||
moved = false; | moved = false; | ||||
} | } | ||||
// dump(); | // dump(); | ||||