From 3aca0212c42fbbc7e6d0fa85d91b7392e3e4137a Mon Sep 17 00:00:00 2001 From: Jonathan Moore Liles Date: Wed, 27 Jan 2010 22:39:27 -0600 Subject: [PATCH] Mixer: Add context menus for modules. --- Mixer/Chain.C | 74 +---------- Mixer/Chain.H | 1 - Mixer/Meter.H | 6 +- Mixer/Mixer_Strip.C | 19 ++- Mixer/Module.C | 290 +++++++++++++++++++++++++++++++----------- Mixer/Module.H | 30 +++-- Mixer/Plugin_Module.C | 2 +- 7 files changed, 246 insertions(+), 176 deletions(-) diff --git a/Mixer/Chain.C b/Mixer/Chain.C index 91f761b..89d58af 100644 --- a/Mixer/Chain.C +++ b/Mixer/Chain.C @@ -692,78 +692,6 @@ Chain::resize ( int X, int Y, int W, int 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; m->nframes( nframes ); - if ( m->active() ) + if ( ! m->bypass() ) m->process(); } } diff --git a/Mixer/Chain.H b/Mixer/Chain.H index 53f25ad..d3467d4 100644 --- a/Mixer/Chain.H +++ b/Mixer/Chain.H @@ -78,7 +78,6 @@ public: Chain ( ); virtual ~Chain ( ); - int handle ( int m ); void draw ( void ); void resize ( int X, int Y, int W, int H ); diff --git a/Mixer/Meter.H b/Mixer/Meter.H index 7114479..6ea99c4 100644 --- a/Mixer/Meter.H +++ b/Mixer/Meter.H @@ -23,6 +23,7 @@ #include #include #include + class Meter : public Fl_Valuator { @@ -36,11 +37,8 @@ protected: { if ( m == FL_ENTER || m == FL_LEAVE ) return 1; - else if ( m == FL_PUSH ) + else if ( m == FL_PUSH && Fl::event_button1()) { -// if ( Fl::event_button3() ) -// hide(); -// else reset(); return 1; } diff --git a/Mixer/Mixer_Strip.C b/Mixer/Mixer_Strip.C index 0ef9aa2..9cb3ab4 100644 --- a/Mixer/Mixer_Strip.C +++ b/Mixer/Mixer_Strip.C @@ -546,28 +546,27 @@ Mixer_Strip::handle ( int m ) switch ( m ) { case FL_KEYBOARD: + if ( Fl_Group::handle( m ) ) + return 1; + if ( test_press( FL_Menu ) ) { menu_popup( &menu(), x(), y() ); return 1; } else - return menu().test_shortcut() || Fl_Group::handle( m ); + return menu().test_shortcut() != 0; case FL_PUSH: { - int r; - if ( test_press( FL_BUTTON3 ) ) + if ( Fl_Group::handle( m ) ) + return 1; + else if ( test_press( FL_BUTTON3 ) ) { menu_popup( &menu() ); - r = 1; + return 1; } - else - r = Fl_Group::handle( m ); - if ( r ) - take_focus(); - - return r; + return 0; } case FL_FOCUS: _focused = true; diff --git a/Mixer/Module.C b/Mixer/Module.C index 70676a9..587b1cc 100644 --- a/Mixer/Module.C +++ b/Mixer/Module.C @@ -19,6 +19,7 @@ #include "Module.H" #include +#include #include #include @@ -33,6 +34,10 @@ #include "Meter_Module.H" #include "Plugin_Module.H" +#include +#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 ) @@ -84,6 +89,7 @@ Module::init ( void ) _editor = 0; _chain = 0; _instances = 1; + _bypass = 0; box( FL_UP_BOX ); labeltype( FL_NO_LABEL ); clip_children( 1 ); @@ -103,7 +109,7 @@ Module::get ( Log_Entry &e ) const } e.add( ":is_default", is_default() ); e.add( ":chain", chain() ); - e.add( ":active", active() ); + e.add( ":active", bypass() ); } void @@ -118,7 +124,7 @@ Module::set ( Log_Entry &e ) if ( ! strcmp( s, ":chain" ) ) { /* 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; sscanf( v, "%X", &i ); Chain *t = (Chain*)Loggable::find( i ); @@ -147,10 +153,7 @@ Module::set ( Log_Entry &e ) } else if ( ! ( strcmp( s, ":active" ) ) ) { - if ( atoi( v ) ) - activate(); - else - deactivate(); + bypass( atoi( v ) ); } else if ( ! strcmp( s, ":chain" ) ) { @@ -249,7 +252,7 @@ Module::draw_box ( void ) 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(); for ( int i = instances(); i--; ) @@ -285,7 +288,7 @@ Module::draw_label ( void ) Fl_Color c = FL_FOREGROUND_COLOR; - if ( ! active() ) + if ( bypass() || ! active() ) c = FL_BLACK; fl_color( c ); @@ -320,97 +323,230 @@ Module::draw_label ( void ) delete[] s; } -#include - -Module * -Module::pick_module ( void ) +void +Module::insert_menu_cb ( const Fl_Menu_ *m ) { - Fl_Menu_Button *menu = new Fl_Menu_Button( 0, 0, 400, 400 ); - menu->type( Fl_Menu_Button::POPUP3 ); + void * v = m->menu()[ m->value() ].user_data(); -// menu->add( "JACK", 0, 0, (void*)1 ); - 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 ) + if ( v ) { - case -1: - return new JACK_Module(); - case -2: - return new Gain_Module(); - case -3: - return new Meter_Module(); - case -4: - return new Mono_Pan_Module(); + unsigned long id = *((unsigned long *)v); + + Module *mod = NULL; + + switch ( id ) + { + case -1: + 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; */ - Plugin_Module *m = new Plugin_Module(); + m.clear(); - 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 ) - { - if ( mi->user_data() ) - delete mi->user_data(); - } +// menu_set_callback( menu, &Module::menu_cb, (void*)this ); + m.callback( &Module::insert_menu_cb, (void*)this ); return m; } -#include "FL/test_press.H" - int Module::handle ( int 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 ) - { - _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; - } - + menu_popup( &menu(), x(), y() ); 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 ); } + + +/************/ +/* 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 ); + } +} diff --git a/Mixer/Module.H b/Mixer/Module.H index 1bed68f..4299a62 100644 --- a/Mixer/Module.H +++ b/Mixer/Module.H @@ -20,8 +20,6 @@ #pragma once #include -#include -#include #include #include @@ -34,6 +32,9 @@ class Chain; class Module_Parameter_Editor; +class Fl_Menu_; +class Fl_Menu_Button; +class Fl_Button; class Module : public Fl_Group, public Loggable { @@ -43,14 +44,19 @@ class Module : public Fl_Group, public Loggable { unsigned long _nframes; Chain *_chain; bool _is_default; + bool _bypass; Module_Parameter_Editor *_editor; -/* void cb_handle(Fl_Widget*); */ -/* static void cb_handle(Fl_Widget*, 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: /* true if this module was added by default and not under normal user control */ @@ -220,9 +226,6 @@ public: LOG_NAME_FUNC( Module ); -// static Module * pick_plugin ( void ); - - unsigned long nframes ( void ) const { return _nframes; } void nframes ( unsigned long v ) { _nframes = v; } @@ -285,6 +288,8 @@ public: return control_output.size(); } + bool bypass ( void ) const { return _bypass; } + void bypass ( bool v ) { _bypass = v; redraw(); } int control_input_port_index ( Port *p ) { @@ -310,8 +315,6 @@ public: char *get_parameters ( void ) const; void set_parameters ( const char * ); - static Module * pick_module ( void ); - virtual bool initialize ( void ) { return true; } /* 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 set ( Log_Entry &e ); +public: + + void command_open_parameter_editor(); + void command_activate ( void ); + void command_deactivate ( void ); + void command_remove ( void ); + }; diff --git a/Mixer/Plugin_Module.C b/Mixer/Plugin_Module.C index 6883286..6b8bec5 100644 --- a/Mixer/Plugin_Module.C +++ b/Mixer/Plugin_Module.C @@ -112,7 +112,7 @@ Plugin_Module::add_plugins_to_menu ( Fl_Menu_Button *menu ) char path[1024]; 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 ); }