@@ -26,6 +26,7 @@ class Gain_Module : public Module | |||
public: | |||
Gain_Module ( ); | |||
Gain_Module ( const Gain_Module & rhs ); | |||
virtual ~Gain_Module ( ); | |||
const char *name ( void ) const { return "Gain"; } | |||
@@ -35,6 +36,8 @@ public: | |||
LOG_CREATE_FUNC( Gain_Module ); | |||
MODULE_CLONE_FUNC( Gain_Module ); | |||
protected: | |||
virtual void process ( nframes_t nframes ); | |||
@@ -40,6 +40,11 @@ | |||
Module *Module::_copied_module_empty = 0; | |||
char *Module::_copied_module_settings = 0; | |||
Module::Module ( int W, int H, const char *L ) : Fl_Group( 0, 0, W, H, L ) | |||
{ | |||
init(); | |||
@@ -109,9 +114,70 @@ Module::get ( Log_Entry &e ) const | |||
} | |||
e.add( ":is_default", is_default() ); | |||
e.add( ":chain", chain() ); | |||
e.add( ":active", bypass() ); | |||
e.add( ":active", ! bypass() ); | |||
} | |||
void | |||
Module::copy ( void ) const | |||
{ | |||
Module *m = clone_empty(); | |||
if ( ! m ) | |||
{ | |||
DMESSAGE( "Module \"%s\" doesn't support cloning", name() ); | |||
} | |||
Log_Entry *ne = new Log_Entry(); | |||
_copied_module_empty = m; | |||
{ | |||
Log_Entry e; | |||
get( e ); | |||
for ( int i = 0; i < e.size(); ++i ) | |||
{ | |||
const char *s, *v; | |||
e.get( i, &s, &v ); | |||
/* we don't want this module to get added to the current | |||
chain... */ | |||
if ( !( !strcmp( s, ":chain" ) || | |||
!strcmp( s, ":is_default" ) ) ) | |||
{ | |||
DMESSAGE( "%s = %s", s, v ); | |||
ne->add_raw( s, v ); | |||
} | |||
} | |||
} | |||
_copied_module_settings = ne->print(); | |||
} | |||
void | |||
Module::paste_before ( void ) | |||
{ | |||
Module *m = _copied_module_empty; | |||
m->chain( chain() ); | |||
Log_Entry le( _copied_module_settings ); | |||
m->set( le ); | |||
if ( ! chain()->insert( this, m ) ) | |||
{ | |||
fl_alert( "Copied module cannot be inserted at this point in the chain" ); | |||
} | |||
free( _copied_module_settings ); | |||
_copied_module_settings = NULL; | |||
_copied_module_empty = NULL; | |||
/* set up for another copy */ | |||
m->copy(); | |||
} | |||
void | |||
Module::set ( Log_Entry &e ) | |||
{ | |||
@@ -153,7 +219,7 @@ Module::set ( Log_Entry &e ) | |||
} | |||
else if ( ! ( strcmp( s, ":active" ) ) ) | |||
{ | |||
bypass( atoi( v ) ); | |||
bypass( ! atoi( v ) ); | |||
} | |||
else if ( ! strcmp( s, ":chain" ) ) | |||
{ | |||
@@ -197,10 +263,9 @@ void | |||
Module::set_parameters ( const char *parameters ) | |||
{ | |||
char *s = strdup( parameters ); | |||
char *sp = s; | |||
char *start = s; | |||
int i = 0; | |||
unsigned int i = 0; | |||
for ( char *sp = s; ; ++sp ) | |||
{ | |||
if ( ':' == *sp || '\0' == *sp ) | |||
@@ -289,6 +354,7 @@ Module::draw_label ( void ) | |||
Fl_Color c = FL_FOREGROUND_COLOR; | |||
if ( bypass() || ! active() ) | |||
c = FL_BLACK; | |||
fl_color( c ); | |||
@@ -406,6 +472,21 @@ Module::menu_cb ( const Fl_Menu_ *m ) | |||
command_activate(); | |||
else if ( ! strcmp( picked, "Deactivate" ) ) | |||
command_deactivate(); | |||
else if ( ! strcmp( picked, "Cut" ) ) | |||
{ | |||
copy(); | |||
chain()->remove( this ); | |||
Fl::delete_widget( this ); | |||
} | |||
else if ( ! strcmp( picked, "Copy" ) ) | |||
{ | |||
copy(); | |||
} | |||
else if ( ! strcmp( picked, "Paste" ) ) | |||
{ | |||
paste_before(); | |||
} | |||
else if ( ! strcmp( picked, "Remove" ) ) | |||
command_remove(); | |||
} | |||
@@ -444,6 +525,9 @@ Module::menu ( void ) const | |||
m.add( "Edit Parameters", 0, &Module::menu_cb, (void*)this, 0 ); | |||
m.add( "Activate", 0, &Module::menu_cb, (void*)this, ! bypass() ? FL_MENU_INACTIVE : 0 ); | |||
m.add( "Deactivate", 0, &Module::menu_cb, (void*)this, bypass() ? FL_MENU_INACTIVE : 0 ); | |||
m.add( "Cut", FL_CTRL + 'x', &Module::menu_cb, (void*)this, is_default() ? FL_MENU_INACTIVE : 0 ); | |||
m.add( "Copy", FL_CTRL + 'c', &Module::menu_cb, (void*)this, is_default() ? FL_MENU_INACTIVE : 0 ); | |||
m.add( "Paste", FL_CTRL + 'v', &Module::menu_cb, (void*)this, _copied_module_empty ? 0 : FL_MENU_INACTIVE ); | |||
m.add( "Remove", 0, &Module::menu_cb, (void*)this ); | |||
// menu_set_callback( menu, &Module::menu_cb, (void*)this ); | |||
@@ -49,6 +49,9 @@ class Module : public Fl_Group, public Loggable { | |||
Module_Parameter_Editor *_editor; | |||
static Module *_copied_module_empty; | |||
static char *_copied_module_settings; | |||
void init ( void ); | |||
void insert_menu_cb ( const Fl_Menu_ *m ); | |||
@@ -58,6 +61,9 @@ class Module : public Fl_Group, public Loggable { | |||
static void menu_cb ( Fl_Widget *w, void *v ); | |||
Fl_Menu_Button & menu ( void ) const; | |||
void copy ( void ) const; | |||
void paste_before ( void ); | |||
public: | |||
/* true if this module was added by default and not under normal user control */ | |||
@@ -339,6 +345,16 @@ public: | |||
virtual void handle_port_connection_change () {} | |||
#define MODULE_CLONE_FUNC(class) \ | |||
virtual Module *clone_empty ( void ) const \ | |||
{ \ | |||
return new class (); \ | |||
} | |||
virtual Module *clone_empty ( void ) const { return NULL; } | |||
Module *clone ( Chain *dest ) const; | |||
Module *clone ( void ) const; | |||
protected: | |||
void draw_connections ( void ); | |||
@@ -35,6 +35,8 @@ public: | |||
LOG_CREATE_FUNC( Mono_Pan_Module ); | |||
MODULE_CLONE_FUNC( Mono_Pan_Module ); | |||
protected: | |||
virtual void process ( nframes_t nframes ); | |||
@@ -114,6 +114,8 @@ public: | |||
LOG_CREATE_FUNC( Plugin_Module ); | |||
MODULE_CLONE_FUNC( Plugin_Module ); | |||
protected: | |||
void get ( Log_Entry &e ) const; | |||
@@ -49,14 +49,20 @@ public: | |||
void grow ( ); | |||
#define ADD( type, format, exp ) \ | |||
void add ( const char *name, type v ) \ | |||
{ \ | |||
grow(); \ | |||
if ( -1 == asprintf( &_sa[ _i ], "%s " format, name, (exp) ) ) \ | |||
abort(); \ | |||
strtok( _sa[ _i++ ], " " ); \ | |||
} \ | |||
#define ADD( type, format, exp ) \ | |||
void add ( const char *name, type v ) \ | |||
{ \ | |||
grow(); \ | |||
asprintf( &_sa[ _i ], "%s " format, name, (exp) ); \ | |||
strtok( _sa[ _i++ ], " " ); \ | |||
} | |||
void add_raw ( const char *name, const char *v ) | |||
{ | |||
grow(); | |||
asprintf( &_sa[ _i ], "%s %s", name, v ); | |||
strtok( _sa[ _i++ ], " " ); | |||
} | |||
/***************/ | |||
/* Examination */ | |||
@@ -699,6 +699,7 @@ Loggable::log_end ( void ) | |||
/** Log object creation. *Must* be called at the end of all public | |||
* constructors for leaf classes */ | |||
void | |||
Loggable::log_create ( void ) const | |||
{ | |||
@@ -46,20 +46,20 @@ typedef Loggable *(create_func)(Log_Entry &, unsigned int id); | |||
#define LOG_NAME_FUNC( class ) \ | |||
virtual const char *class_name ( void ) const { return #class ; } | |||
#define LOG_CREATE_FUNC( class ) \ | |||
static Loggable * \ | |||
create ( Log_Entry &e, unsigned int id ) \ | |||
{ \ | |||
class *r = new class; \ | |||
r->update_id( id ); \ | |||
r->set( e ); \ | |||
return (Loggable *)r; \ | |||
} \ | |||
LOG_NAME_FUNC( class ); \ | |||
#define LOG_CREATE_FUNC( class ) \ | |||
static Loggable * \ | |||
create ( Log_Entry &e, unsigned int id ) \ | |||
{ \ | |||
class *r = new class; \ | |||
r->update_id( id ); \ | |||
r->set( e ); \ | |||
return (Loggable *)r; \ | |||
} \ | |||
LOG_NAME_FUNC( class ); | |||
#define LOG_NOT_LOGGABLE_FUNC( class ) \ | |||
virtual const char *class_name ( void ) const { return #class ; } \ | |||
virtual const char *class_name ( void ) const { return #class ; } | |||
class Logger; | |||
class Loggable | |||