Mixer: Implement cut/copy/paste for modules.
This commit is contained in:
parent
0fe401bc04
commit
9002016db5
|
@ -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 ) \
|
#define ADD( type, format, exp ) \
|
||||||
void add ( const char *name, type v ) \
|
void add ( const char *name, type v ) \
|
||||||
{ \
|
{ \
|
||||||
grow(); \
|
grow(); \
|
||||||
if ( -1 == asprintf( &_sa[ _i ], "%s " format, name, (exp) ) ) \
|
asprintf( &_sa[ _i ], "%s " format, name, (exp) ); \
|
||||||
abort(); \
|
strtok( _sa[ _i++ ], " " ); \
|
||||||
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 ) \
|
#define LOG_CREATE_FUNC( class ) \
|
||||||
static Loggable * \
|
static Loggable * \
|
||||||
create ( Log_Entry &e, unsigned int id ) \
|
create ( Log_Entry &e, unsigned int id ) \
|
||||||
{ \
|
{ \
|
||||||
class *r = new class; \
|
class *r = new class; \
|
||||||
r->update_id( id ); \
|
r->update_id( id ); \
|
||||||
r->set( e ); \
|
r->set( e ); \
|
||||||
return (Loggable *)r; \
|
return (Loggable *)r; \
|
||||||
} \
|
} \
|
||||||
LOG_NAME_FUNC( class ); \
|
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
|
||||||
|
|
Loading…
Reference in New Issue