Mixer: Add context menus for modules.

This commit is contained in:
Jonathan Moore Liles 2010-01-27 22:39:27 -06:00
parent a1387c4d62
commit 3aca0212c4
7 changed files with 246 additions and 176 deletions

View File

@ -692,78 +692,6 @@ Chain::resize ( int X, int Y, int W, int H )
controls_pack->size( W, controls_pack->h() ); controls_pack->size( W, controls_pack->h() );
} }
int
Chain::handle ( int m )
{
switch ( m )
{
case FL_PUSH:
{
if ( Fl::belowmouse() != this )
{
Module *m = NULL;
for ( int i = 0; i < modules(); ++i )
if ( Fl::event_inside( module( i ) ) )
{
m = module( i );
break;
}
if ( m )
{
if ( test_press( FL_BUTTON3 | FL_CTRL ) )
{
if ( m->is_default() )
{
fl_alert( "Default modules may not be deleted." );
}
else
{
remove( m );
delete m;
redraw();
}
return 1;
}
else if ( test_press( FL_BUTTON1 | FL_SHIFT ) )
{
// Module *mod = (Module*)Plugin_Module::pick_plugin();
Module *mod = Module::pick_module();
if ( mod )
{
if ( !strcmp( mod->name(), "JACK" ) )
{
DMESSAGE( "Special casing JACK module" );
JACK_Module *jm = (JACK_Module*)mod;
jm->chain( this );
jm->configure_inputs( m->ninputs() );
jm->configure_outputs( m->ninputs() );
}
if ( ! insert( m, mod ) )
fl_alert( "Cannot insert this module at this point in the chain" );
redraw();
}
return 1;
}
else if ( test_press( FL_BUTTON1 | FL_CTRL ) )
{
if ( m->active() )
m->deactivate();
else
m->activate();
return 1;
}
}
}
break;
}
}
return Fl_Group::handle( m );
}
/**********/ /**********/
@ -784,7 +712,7 @@ Chain::process ( nframes_t nframes )
Module *m = *i; Module *m = *i;
m->nframes( nframes ); m->nframes( nframes );
if ( m->active() ) if ( ! m->bypass() )
m->process(); m->process();
} }
} }

View File

@ -78,7 +78,6 @@ public:
Chain ( ); Chain ( );
virtual ~Chain ( ); virtual ~Chain ( );
int handle ( int m );
void draw ( void ); void draw ( void );
void resize ( int X, int Y, int W, int H ); void resize ( int X, int Y, int W, int H );

View File

@ -23,6 +23,7 @@
#include <FL/Fl.H> #include <FL/Fl.H>
#include <FL/Fl_Widget.H> #include <FL/Fl_Widget.H>
#include <FL/Fl_Valuator.H> #include <FL/Fl_Valuator.H>
class Meter : public Fl_Valuator class Meter : public Fl_Valuator
{ {
@ -36,11 +37,8 @@ protected:
{ {
if ( m == FL_ENTER || m == FL_LEAVE ) if ( m == FL_ENTER || m == FL_LEAVE )
return 1; return 1;
else if ( m == FL_PUSH ) else if ( m == FL_PUSH && Fl::event_button1())
{ {
// if ( Fl::event_button3() )
// hide();
// else
reset(); reset();
return 1; return 1;
} }

View File

@ -546,28 +546,27 @@ Mixer_Strip::handle ( int m )
switch ( m ) switch ( m )
{ {
case FL_KEYBOARD: case FL_KEYBOARD:
if ( Fl_Group::handle( m ) )
return 1;
if ( test_press( FL_Menu ) ) if ( test_press( FL_Menu ) )
{ {
menu_popup( &menu(), x(), y() ); menu_popup( &menu(), x(), y() );
return 1; return 1;
} }
else else
return menu().test_shortcut() || Fl_Group::handle( m ); return menu().test_shortcut() != 0;
case FL_PUSH: case FL_PUSH:
{ {
int r; if ( Fl_Group::handle( m ) )
if ( test_press( FL_BUTTON3 ) ) return 1;
else if ( test_press( FL_BUTTON3 ) )
{ {
menu_popup( &menu() ); menu_popup( &menu() );
r = 1; return 1;
} }
else
r = Fl_Group::handle( m );
if ( r ) return 0;
take_focus();
return r;
} }
case FL_FOCUS: case FL_FOCUS:
_focused = true; _focused = true;

View File

@ -19,6 +19,7 @@
#include "Module.H" #include "Module.H"
#include <FL/fl_draw.H> #include <FL/fl_draw.H>
#include <FL/fl_ask.H>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -33,6 +34,10 @@
#include "Meter_Module.H" #include "Meter_Module.H"
#include "Plugin_Module.H" #include "Plugin_Module.H"
#include <FL/Fl_Menu_Button.H>
#include "FL/test_press.H"
#include "FL/menu_popup.H"
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 )
@ -84,6 +89,7 @@ Module::init ( void )
_editor = 0; _editor = 0;
_chain = 0; _chain = 0;
_instances = 1; _instances = 1;
_bypass = 0;
box( FL_UP_BOX ); box( FL_UP_BOX );
labeltype( FL_NO_LABEL ); labeltype( FL_NO_LABEL );
clip_children( 1 ); clip_children( 1 );
@ -103,7 +109,7 @@ 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", active() ); e.add( ":active", bypass() );
} }
void void
@ -118,7 +124,7 @@ Module::set ( Log_Entry &e )
if ( ! strcmp( s, ":chain" ) ) if ( ! strcmp( s, ":chain" ) )
{ {
/* This trickiness is because we may need to know the name of /* This trickiness is because we may need to know the name of
our chain before we actually get added to it. */ our chain before we actually get added to it. */
int i; int i;
sscanf( v, "%X", &i ); sscanf( v, "%X", &i );
Chain *t = (Chain*)Loggable::find( i ); Chain *t = (Chain*)Loggable::find( i );
@ -147,10 +153,7 @@ Module::set ( Log_Entry &e )
} }
else if ( ! ( strcmp( s, ":active" ) ) ) else if ( ! ( strcmp( s, ":active" ) ) )
{ {
if ( atoi( v ) ) bypass( atoi( v ) );
activate();
else
deactivate();
} }
else if ( ! strcmp( s, ":chain" ) ) else if ( ! strcmp( s, ":chain" ) )
{ {
@ -249,7 +252,7 @@ Module::draw_box ( void )
Fl_Color c = is_default() ? FL_BLACK : color(); Fl_Color c = is_default() ? FL_BLACK : color();
c = active() ? c : fl_inactive( c ); c = active() && ! bypass() ? c : fl_inactive( c );
int spacing = w() / instances(); int spacing = w() / instances();
for ( int i = instances(); i--; ) for ( int i = instances(); i--; )
@ -285,7 +288,7 @@ Module::draw_label ( void )
Fl_Color c = FL_FOREGROUND_COLOR; Fl_Color c = FL_FOREGROUND_COLOR;
if ( ! active() ) if ( bypass() || ! active() )
c = FL_BLACK; c = FL_BLACK;
fl_color( c ); fl_color( c );
@ -320,97 +323,230 @@ Module::draw_label ( void )
delete[] s; delete[] s;
} }
#include <FL/Fl_Menu_Button.H> void
Module::insert_menu_cb ( const Fl_Menu_ *m )
Module *
Module::pick_module ( void )
{ {
Fl_Menu_Button *menu = new Fl_Menu_Button( 0, 0, 400, 400 ); void * v = m->menu()[ m->value() ].user_data();
menu->type( Fl_Menu_Button::POPUP3 );
// menu->add( "JACK", 0, 0, (void*)1 ); if ( v )
menu->add( "Gain", 0, 0, new unsigned long(-2) );
menu->add( "Meter", 0, 0, new unsigned long(-3) );
menu->add( "Mono Pan", 0, 0, new unsigned long(-4) );
Plugin_Module::add_plugins_to_menu( menu );
menu->popup();
if ( menu->value() < 0 )
return NULL;
void * v = menu->menu()[ menu->value() ].user_data();
if ( ! v )
return NULL;
unsigned long id = *((unsigned long *)v);
switch ( id )
{ {
case -1: unsigned long id = *((unsigned long *)v);
return new JACK_Module();
case -2: Module *mod = NULL;
return new Gain_Module();
case -3: switch ( id )
return new Meter_Module(); {
case -4: case -1:
return new Mono_Pan_Module(); mod = new JACK_Module();
break;
case -2:
mod = new Gain_Module();
break;
case -3:
mod = new Meter_Module();
break;
case -4:
mod = new Mono_Pan_Module();
break;
default:
{
Plugin_Module *m = new Plugin_Module();
m->load( id );
mod = m;
}
}
if ( mod )
{
if ( !strcmp( mod->name(), "JACK" ) )
{
DMESSAGE( "Special casing JACK module" );
JACK_Module *jm = (JACK_Module*)mod;
jm->chain( chain() );
jm->configure_inputs( ninputs() );
jm->configure_outputs( ninputs() );
}
if ( ! chain()->insert( this, mod ) )
{
fl_alert( "Cannot insert this module at this point in the chain" );
delete mod;
return;
}
redraw();
}
}
}
void
Module::insert_menu_cb ( Fl_Widget *w, void *v )
{
((Module*)v)->insert_menu_cb( (Fl_Menu_*) w );
}
void
Module::menu_cb ( const Fl_Menu_ *m )
{
char picked[256];
strncpy( picked, m->mvalue()->label(), sizeof( picked ) );
// m->item_pathname( picked, sizeof( picked ) );
DMESSAGE( "%s", picked );
Logger log( this );
if ( ! strcmp( picked, "Edit Parameters" ) )
command_open_parameter_editor();
else if ( ! strcmp( picked, "Activate" ) )
command_activate();
else if ( ! strcmp( picked, "Deactivate" ) )
command_deactivate();
else if ( ! strcmp( picked, "Remove" ) )
command_remove();
}
void
Module::menu_cb ( Fl_Widget *w, void *v )
{
((Module*)v)->menu_cb( (Fl_Menu_*) w );
}
/** build the context menu */
Fl_Menu_Button &
Module::menu ( void ) const
{
static Fl_Menu_Button m( 0, 0, 0, 0, "Module" );
static Fl_Menu_Button *insert_menu = NULL;
if ( ! insert_menu )
{
insert_menu = new Fl_Menu_Button( 0, 0, 0, 0 );
insert_menu->add( "Gain", 0, 0, new unsigned long(-2) );
insert_menu->add( "Meter", 0, 0, new unsigned long(-3) );
insert_menu->add( "Mono Pan", 0, 0, new unsigned long(-4) );
Plugin_Module::add_plugins_to_menu( insert_menu );
// menu_set_callback( insert_menu, &Module::insert_menu_cb, (void*)this );
insert_menu->callback( &Module::insert_menu_cb, (void*)this );
} }
/* Plugin_Module::Plugin_Info *pi = (Plugin_Module::Plugin_Info*)v; */ m.clear();
Plugin_Module *m = new Plugin_Module();
m->load( id ); m.add( "Insert", 0, &Module::menu_cb, (void*)this, 0);
m.add( "Insert", 0, &Module::menu_cb, const_cast< Fl_Menu_Item *>( insert_menu->menu() ), FL_SUBMENU_POINTER );
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( "Remove", 0, &Module::menu_cb, (void*)this );
for ( const Fl_Menu_Item *mi = menu->menu(); mi->label(); ++mi ) // menu_set_callback( menu, &Module::menu_cb, (void*)this );
{ m.callback( &Module::insert_menu_cb, (void*)this );
if ( mi->user_data() )
delete mi->user_data();
}
return m; return m;
} }
#include "FL/test_press.H"
int int
Module::handle ( int m ) Module::handle ( int m )
{ {
switch ( m ) switch ( m )
{ {
case FL_PUSH: case FL_KEYBOARD:
{ {
if ( test_press( FL_BUTTON1 ) ) if ( Fl_Group::handle( m ) )
return 1;
if ( test_press( FL_Menu ) )
{ {
if ( _editor ) menu_popup( &menu(), x(), y() );
{
_editor->show();
}
else if ( ncontrol_inputs() )
{
DMESSAGE( "Opening module parameters for \"%s\"", label() );
_editor = new Module_Parameter_Editor( this );
_editor->show();
do { Fl::wait(); }
while ( _editor->shown() );
DMESSAGE( "Module parameters for \"%s\" closed",label() );
delete _editor;
_editor = NULL;
}
return 1; return 1;
} }
break; else
return menu().test_shortcut() != 0;
}
case FL_PUSH:
{
if ( Fl_Group::handle( m ) )
return 1;
else if ( test_press( FL_BUTTON3 ) )
{
menu_popup( &menu() );
return 1;
}
else if ( test_press( FL_BUTTON1 ) )
{
command_open_parameter_editor();
return 1;
}
else if ( test_press( FL_BUTTON3 | FL_CTRL ) )
{
command_remove();
return 1;
}
return 0;
} }
} }
return Fl_Group::handle( m ); return Fl_Group::handle( m );
} }
/************/
/* Commands */
/************/
void
Module::command_open_parameter_editor ( void )
{
if ( _editor )
{
_editor->show();
}
else if ( ncontrol_inputs() )
{
DMESSAGE( "Opening module parameters for \"%s\"", label() );
_editor = new Module_Parameter_Editor( this );
_editor->show();
do { Fl::wait(); }
while ( _editor->shown() );
DMESSAGE( "Module parameters for \"%s\" closed",label() );
delete _editor;
_editor = NULL;
}
}
void
Module::command_activate ( void )
{
bypass( false );
}
void
Module::command_deactivate ( void )
{
bypass( true );
}
void
Module::command_remove ( void )
{
if ( is_default() )
fl_alert( "Default modules may not be deleted." );
else
{
chain()->remove( this );
Fl::delete_widget( this );
}
}

View File

@ -20,8 +20,6 @@
#pragma once #pragma once
#include <FL/Fl.H> #include <FL/Fl.H>
#include <FL/Fl_Widget.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Group.H> #include <FL/Fl_Group.H>
#include <stdlib.h> #include <stdlib.h>
@ -34,6 +32,9 @@
class Chain; class Chain;
class Module_Parameter_Editor; class Module_Parameter_Editor;
class Fl_Menu_;
class Fl_Menu_Button;
class Fl_Button;
class Module : public Fl_Group, public Loggable { class Module : public Fl_Group, public Loggable {
@ -43,14 +44,19 @@ class Module : public Fl_Group, public Loggable {
unsigned long _nframes; unsigned long _nframes;
Chain *_chain; Chain *_chain;
bool _is_default; bool _is_default;
bool _bypass;
Module_Parameter_Editor *_editor; Module_Parameter_Editor *_editor;
/* void cb_handle(Fl_Widget*); */
/* static void cb_handle(Fl_Widget*, void*); */
void init ( void ); void init ( void );
void insert_menu_cb ( const Fl_Menu_ *m );
static void insert_menu_cb ( Fl_Widget *w, void *v );
void menu_cb ( const Fl_Menu_ *m );
static void menu_cb ( Fl_Widget *w, void *v );
Fl_Menu_Button & menu ( void ) const;
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 */
@ -220,9 +226,6 @@ public:
LOG_NAME_FUNC( Module ); LOG_NAME_FUNC( Module );
// static Module * pick_plugin ( void );
unsigned long nframes ( void ) const { return _nframes; } unsigned long nframes ( void ) const { return _nframes; }
void nframes ( unsigned long v ) { _nframes = v; } void nframes ( unsigned long v ) { _nframes = v; }
@ -285,6 +288,8 @@ public:
return control_output.size(); return control_output.size();
} }
bool bypass ( void ) const { return _bypass; }
void bypass ( bool v ) { _bypass = v; redraw(); }
int control_input_port_index ( Port *p ) int control_input_port_index ( Port *p )
{ {
@ -310,8 +315,6 @@ public:
char *get_parameters ( void ) const; char *get_parameters ( void ) const;
void set_parameters ( const char * ); void set_parameters ( const char * );
static Module * pick_module ( void );
virtual bool initialize ( void ) { return true; } virtual bool initialize ( void ) { return true; }
/* for the given number of inputs, return how many outputs this /* for the given number of inputs, return how many outputs this
@ -347,4 +350,11 @@ protected:
virtual void get ( Log_Entry &e ) const; virtual void get ( Log_Entry &e ) const;
virtual void set ( Log_Entry &e ); virtual void set ( Log_Entry &e );
public:
void command_open_parameter_editor();
void command_activate ( void );
void command_deactivate ( void );
void command_remove ( void );
}; };

View File

@ -112,7 +112,7 @@ Plugin_Module::add_plugins_to_menu ( Fl_Menu_Button *menu )
char path[1024]; char path[1024];
for ( Plugin_Module::Plugin_Info *pi = pia; pi->path; ++pi ) for ( Plugin_Module::Plugin_Info *pi = pia; pi->path; ++pi )
{ {
snprintf( path, sizeof( path ), "%s/%s", "Plugin", pi->path ); snprintf( path, sizeof( path ), "Plugin/%s", pi->path );
menu->add(path, 0, NULL, new unsigned long( pi->id ), 0 ); menu->add(path, 0, NULL, new unsigned long( pi->id ), 0 );
} }