| @@ -26,6 +26,7 @@ class Gain_Module : public Module | |||||
| public: | public: | ||||
| Gain_Module ( ); | Gain_Module ( ); | ||||
| Gain_Module ( const Gain_Module & rhs ); | |||||
| virtual ~Gain_Module ( ); | virtual ~Gain_Module ( ); | ||||
| const char *name ( void ) const { return "Gain"; } | const char *name ( void ) const { return "Gain"; } | ||||
| @@ -35,6 +36,8 @@ public: | |||||
| LOG_CREATE_FUNC( Gain_Module ); | LOG_CREATE_FUNC( Gain_Module ); | ||||
| MODULE_CLONE_FUNC( Gain_Module ); | |||||
| protected: | protected: | ||||
| virtual void process ( nframes_t nframes ); | 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 ) | Module::Module ( int W, int H, const char *L ) : Fl_Group( 0, 0, W, H, L ) | ||||
| { | { | ||||
| init(); | init(); | ||||
| @@ -109,9 +114,70 @@ Module::get ( Log_Entry &e ) const | |||||
| } | } | ||||
| e.add( ":is_default", is_default() ); | e.add( ":is_default", is_default() ); | ||||
| e.add( ":chain", chain() ); | 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 | void | ||||
| Module::set ( Log_Entry &e ) | Module::set ( Log_Entry &e ) | ||||
| { | { | ||||
| @@ -153,7 +219,7 @@ Module::set ( Log_Entry &e ) | |||||
| } | } | ||||
| else if ( ! ( strcmp( s, ":active" ) ) ) | else if ( ! ( strcmp( s, ":active" ) ) ) | ||||
| { | { | ||||
| bypass( atoi( v ) ); | |||||
| bypass( ! atoi( v ) ); | |||||
| } | } | ||||
| else if ( ! strcmp( s, ":chain" ) ) | else if ( ! strcmp( s, ":chain" ) ) | ||||
| { | { | ||||
| @@ -197,10 +263,9 @@ void | |||||
| Module::set_parameters ( const char *parameters ) | Module::set_parameters ( const char *parameters ) | ||||
| { | { | ||||
| char *s = strdup( parameters ); | char *s = strdup( parameters ); | ||||
| char *sp = s; | |||||
| char *start = s; | char *start = s; | ||||
| int i = 0; | |||||
| unsigned int i = 0; | |||||
| for ( char *sp = s; ; ++sp ) | for ( char *sp = s; ; ++sp ) | ||||
| { | { | ||||
| if ( ':' == *sp || '\0' == *sp ) | if ( ':' == *sp || '\0' == *sp ) | ||||
| @@ -289,6 +354,7 @@ Module::draw_label ( void ) | |||||
| Fl_Color c = FL_FOREGROUND_COLOR; | Fl_Color c = FL_FOREGROUND_COLOR; | ||||
| if ( bypass() || ! active() ) | if ( bypass() || ! active() ) | ||||
| c = FL_BLACK; | c = FL_BLACK; | ||||
| fl_color( c ); | fl_color( c ); | ||||
| @@ -406,6 +472,21 @@ Module::menu_cb ( const Fl_Menu_ *m ) | |||||
| command_activate(); | command_activate(); | ||||
| else if ( ! strcmp( picked, "Deactivate" ) ) | else if ( ! strcmp( picked, "Deactivate" ) ) | ||||
| command_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" ) ) | else if ( ! strcmp( picked, "Remove" ) ) | ||||
| command_remove(); | command_remove(); | ||||
| } | } | ||||
| @@ -444,6 +525,9 @@ Module::menu ( void ) const | |||||
| m.add( "Edit Parameters", 0, &Module::menu_cb, (void*)this, 0 ); | 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( "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( "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 ); | m.add( "Remove", 0, &Module::menu_cb, (void*)this ); | ||||
| // menu_set_callback( menu, &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; | Module_Parameter_Editor *_editor; | ||||
| static Module *_copied_module_empty; | |||||
| static char *_copied_module_settings; | |||||
| void init ( void ); | void init ( void ); | ||||
| void insert_menu_cb ( const Fl_Menu_ *m ); | 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 ); | static void menu_cb ( Fl_Widget *w, void *v ); | ||||
| Fl_Menu_Button & menu ( void ) const; | Fl_Menu_Button & menu ( void ) const; | ||||
| void copy ( void ) const; | |||||
| void paste_before ( void ); | |||||
| public: | public: | ||||
| /* true if this module was added by default and not under normal user control */ | /* 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 () {} | 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: | protected: | ||||
| void draw_connections ( void ); | void draw_connections ( void ); | ||||
| @@ -35,6 +35,8 @@ public: | |||||
| LOG_CREATE_FUNC( Mono_Pan_Module ); | LOG_CREATE_FUNC( Mono_Pan_Module ); | ||||
| MODULE_CLONE_FUNC( Mono_Pan_Module ); | |||||
| protected: | protected: | ||||
| virtual void process ( nframes_t nframes ); | virtual void process ( nframes_t nframes ); | ||||
| @@ -114,6 +114,8 @@ public: | |||||
| LOG_CREATE_FUNC( Plugin_Module ); | LOG_CREATE_FUNC( Plugin_Module ); | ||||
| MODULE_CLONE_FUNC( Plugin_Module ); | |||||
| protected: | protected: | ||||
| void get ( Log_Entry &e ) const; | void get ( Log_Entry &e ) const; | ||||
| @@ -49,14 +49,20 @@ public: | |||||
| void grow ( ); | 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 */ | /* Examination */ | ||||
| @@ -699,6 +699,7 @@ Loggable::log_end ( void ) | |||||
| /** Log object creation. *Must* be called at the end of all public | /** Log object creation. *Must* be called at the end of all public | ||||
| * constructors for leaf classes */ | * constructors for leaf classes */ | ||||
| void | void | ||||
| Loggable::log_create ( void ) const | Loggable::log_create ( void ) const | ||||
| { | { | ||||
| @@ -46,20 +46,20 @@ typedef Loggable *(create_func)(Log_Entry &, unsigned int id); | |||||
| #define LOG_NAME_FUNC( class ) \ | #define LOG_NAME_FUNC( class ) \ | ||||
| virtual const char *class_name ( void ) const { return #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 ) \ | #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 Logger; | ||||
| class Loggable | class Loggable | ||||