Mixer: Add connection/disconnection submenu to controller module context menu.
This commit is contained in:
parent
07161196bd
commit
a3a8247b83
|
@ -45,6 +45,8 @@
|
||||||
// needed for mixer->endpoint
|
// needed for mixer->endpoint
|
||||||
#include "Mixer.H"
|
#include "Mixer.H"
|
||||||
|
|
||||||
|
#include "string_util.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool Controller_Module::learn_by_number = false;
|
bool Controller_Module::learn_by_number = false;
|
||||||
|
@ -358,7 +360,7 @@ Controller_Module::connect_to ( Port *p )
|
||||||
w = o;
|
w = o;
|
||||||
|
|
||||||
o->type(4);
|
o->type(4);
|
||||||
o->color( FL_DARK1 );
|
o->color( FL_BACKGROUND2_COLOR );
|
||||||
o->selection_color( fl_color_average( FL_GRAY, FL_CYAN, 0.5 ) );
|
o->selection_color( fl_color_average( FL_GRAY, FL_CYAN, 0.5 ) );
|
||||||
o->minimum(1.5);
|
o->minimum(1.5);
|
||||||
o->maximum(0);
|
o->maximum(0);
|
||||||
|
@ -496,6 +498,181 @@ Controller_Module::menu_cb ( const Fl_Menu_ *m )
|
||||||
mode( CV );
|
mode( CV );
|
||||||
else if ( ! strcmp( picked, "/Remove" ) )
|
else if ( ! strcmp( picked, "/Remove" ) )
|
||||||
command_remove();
|
command_remove();
|
||||||
|
else if ( ! strncmp( picked, "Connect To/", strlen( "Connect To/" ) ) )
|
||||||
|
{
|
||||||
|
char *peer_name = index( picked, '/' ) + 1;
|
||||||
|
|
||||||
|
*index( peer_name, '/' ) = 0;
|
||||||
|
|
||||||
|
// OSC::Signal s = (OSC::Signal*)m->mvalue()->user_data();
|
||||||
|
const char *path = ((OSC::Signal*)m->mvalue()->user_data())->path();
|
||||||
|
|
||||||
|
/* if ( ! _osc_output()->is_connected_to( ((OSC::Signal*)m->mvalue()->user_data()) ) ) */
|
||||||
|
/* { */
|
||||||
|
/* _persistent_osc_connections.push_back( strdup(path) ); */
|
||||||
|
|
||||||
|
Port *p = control_output[0].connected_port();
|
||||||
|
|
||||||
|
if ( learn_by_number )
|
||||||
|
{
|
||||||
|
char *our_path = p->osc_number_path();
|
||||||
|
|
||||||
|
mixer->osc_endpoint->add_translation( path, our_path );
|
||||||
|
|
||||||
|
free(our_path);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mixer->osc_endpoint->add_translation( path, p->osc_path() );
|
||||||
|
}
|
||||||
|
else if ( ! strncmp( picked, "Disconnect From/", strlen( "Disconnect From/" ) ) )
|
||||||
|
{
|
||||||
|
/* char *peer_name = index( picked, '/' ) + 1; */
|
||||||
|
|
||||||
|
/* *index( peer_name, '/' ) = 0; */
|
||||||
|
|
||||||
|
// OSC::Signal s = (OSC::Signal*)m->mvalue()->user_data();
|
||||||
|
const char *path = (const char*)m->mvalue()->user_data();
|
||||||
|
|
||||||
|
/* if ( ! _osc_output()->is_connected_to( ((OSC::Signal*)m->mvalue()->user_data()) ) ) */
|
||||||
|
/* { */
|
||||||
|
/* _persistent_osc_connections.push_back( strdup(path) ); */
|
||||||
|
|
||||||
|
// Port *p = control_output[0].connected_port();
|
||||||
|
|
||||||
|
mixer->osc_endpoint->del_translation( path );
|
||||||
|
|
||||||
|
/* if ( learn_by_number ) */
|
||||||
|
/* { */
|
||||||
|
/* char *our_path = p->osc_number_path(); */
|
||||||
|
|
||||||
|
/* mixer->osc_endpoint->add_translation( path, our_path ); */
|
||||||
|
|
||||||
|
/* free(our_path); */
|
||||||
|
/* } */
|
||||||
|
/* else */
|
||||||
|
/* mixer->osc_endpoint->add_translation( path, p->osc_path() ); */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* } */
|
||||||
|
/* else */
|
||||||
|
/* { */
|
||||||
|
/* /\* timeline->osc->disconnect_signal( _osc_output(), path ); *\/ */
|
||||||
|
|
||||||
|
/* /\* for ( std::list<char*>::iterator i = _persistent_osc_connections.begin(); *\/ */
|
||||||
|
/* /\* i != _persistent_osc_connections.end(); *\/ */
|
||||||
|
/* /\* ++i ) *\/ */
|
||||||
|
/* /\* { *\/ */
|
||||||
|
/* /\* if ( !strcmp( *i, path ) ) *\/ */
|
||||||
|
/* /\* { *\/ */
|
||||||
|
/* /\* free( *i ); *\/ */
|
||||||
|
/* /\* i = _persistent_osc_connections.erase( i ); *\/ */
|
||||||
|
/* /\* break; *\/ */
|
||||||
|
/* /\* } *\/ */
|
||||||
|
/* /\* } *\/ */
|
||||||
|
|
||||||
|
/* //free( path ); */
|
||||||
|
/* } */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
static Fl_Menu_Button *peer_menu;
|
||||||
|
static const char *peer_prefix;
|
||||||
|
|
||||||
|
void
|
||||||
|
Controller_Module::peer_callback( OSC::Signal *sig, OSC::Signal::State state, void *v )
|
||||||
|
{
|
||||||
|
char *s;
|
||||||
|
|
||||||
|
DMESSAGE( "Paramter limits: %f %f", sig->parameter_limits().min, sig->parameter_limits().max );
|
||||||
|
|
||||||
|
/* only show outputs */
|
||||||
|
if ( sig->direction() != OSC::Signal::Output )
|
||||||
|
return;
|
||||||
|
|
||||||
|
|
||||||
|
/* only list CV signals for now */
|
||||||
|
if ( ! ( sig->parameter_limits().min == 0.0 &&
|
||||||
|
sig->parameter_limits().max == 1.0 ) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ( ! v )
|
||||||
|
{
|
||||||
|
/* if( state == OSC::Signal::Created ) */
|
||||||
|
/* timeline->connect_osc(); */
|
||||||
|
/* else */
|
||||||
|
/* timeline->update_osc_connection_state(); */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* building menu */
|
||||||
|
const char *name = sig->peer_name();
|
||||||
|
|
||||||
|
assert( sig->path() );
|
||||||
|
|
||||||
|
char *path = strdup( sig->path() );
|
||||||
|
|
||||||
|
unescape_url( path );
|
||||||
|
|
||||||
|
asprintf( &s, "%s/%s", peer_prefix, path );
|
||||||
|
|
||||||
|
peer_menu->add( s, 0, NULL, (void*)( sig ), 0 );
|
||||||
|
|
||||||
|
/* FL_MENU_TOGGLE | */
|
||||||
|
/* ( ((Controller_Module*)v)->_osc_output()->is_connected_to( sig ) ? FL_MENU_VALUE : 0 ) ); */
|
||||||
|
|
||||||
|
free( path );
|
||||||
|
|
||||||
|
free( s );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Controller_Module::add_osc_peers_to_menu ( Fl_Menu_Button *m, const char *prefix )
|
||||||
|
{
|
||||||
|
mixer->osc_endpoint->peer_signal_notification_callback( &Controller_Module::peer_callback, NULL );
|
||||||
|
|
||||||
|
peer_menu = m;
|
||||||
|
peer_prefix = prefix;
|
||||||
|
|
||||||
|
mixer->osc_endpoint->list_peer_signals( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Controller_Module::add_osc_connections_to_menu ( Fl_Menu_Button *m, const char *prefix )
|
||||||
|
{
|
||||||
|
/* peer_menu = m; */
|
||||||
|
const char *peer_prefix = prefix;
|
||||||
|
|
||||||
|
// mixer->osc_endpoint->list_peer_signals( this );
|
||||||
|
|
||||||
|
Port *p = control_output[0].connected_port();
|
||||||
|
|
||||||
|
const char ** conn = mixer->osc_endpoint->get_connections( p->osc_path() );
|
||||||
|
|
||||||
|
if ( conn )
|
||||||
|
{
|
||||||
|
for ( const char **s = conn; *s; s++ )
|
||||||
|
{
|
||||||
|
/* building menu */
|
||||||
|
|
||||||
|
char *path = strdup( *s );
|
||||||
|
|
||||||
|
unescape_url( path );
|
||||||
|
|
||||||
|
char *ns;
|
||||||
|
asprintf( &ns, "%s/%s", peer_prefix, path );
|
||||||
|
|
||||||
|
peer_menu->add( ns, 0, NULL, const_cast<char*>(*s), 0 );
|
||||||
|
|
||||||
|
free( path );
|
||||||
|
// free(*s);
|
||||||
|
}
|
||||||
|
|
||||||
|
free( conn );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** build the context menu for this control */
|
/** build the context menu for this control */
|
||||||
|
@ -504,19 +681,21 @@ Controller_Module::menu ( void )
|
||||||
{
|
{
|
||||||
static Fl_Menu_Button m( 0, 0, 0, 0, "Controller" );
|
static Fl_Menu_Button m( 0, 0, 0, 0, "Controller" );
|
||||||
|
|
||||||
Fl_Menu_Item items[] =
|
m.clear();
|
||||||
|
|
||||||
|
if ( mode() == GUI )
|
||||||
{
|
{
|
||||||
{ "Mode", 0, 0, 0, FL_SUBMENU },
|
add_osc_peers_to_menu( &m, "Connect To" );
|
||||||
{ "GUI + OSC", 0, 0, 0, FL_MENU_RADIO | ( mode() == GUI ? FL_MENU_VALUE : 0 ) },
|
add_osc_connections_to_menu( &m, "Disconnect From" );
|
||||||
{ "Control Voltage (JACK)", 0, 0, 0, FL_MENU_RADIO | ( mode() == CV ? FL_MENU_VALUE : 0 ) },
|
}
|
||||||
{ 0 },
|
|
||||||
{ "Remove", 0, 0, 0, 0 },
|
|
||||||
{ 0 },
|
|
||||||
};
|
|
||||||
|
|
||||||
menu_set_callback( items, &Controller_Module::menu_cb, (void*)this );
|
m.add( "Mode/GUI + OSC", 0, 0, 0, FL_MENU_RADIO | ( mode() == GUI ? FL_MENU_VALUE : 0 ));
|
||||||
|
m.add( "Mode/Control Voltage (JACK)", 0, 0, 0, FL_MENU_RADIO | ( mode() == CV ? FL_MENU_VALUE : 0 ));
|
||||||
|
m.add( "Remove", 0, 0, 0, is_default() ? FL_MENU_INACTIVE : 0 );
|
||||||
|
|
||||||
m.copy( items, (void*)this );
|
// menu_set_callback( m.items(), &Controller_Module::menu_cb, (void*)this );
|
||||||
|
m.callback( &Controller_Module::menu_cb, (void*)this );
|
||||||
|
// m.copy( items, (void*)this );
|
||||||
|
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,12 @@ class Controller_Module : public Module
|
||||||
static void menu_cb ( Fl_Widget *w, void *v );
|
static void menu_cb ( Fl_Widget *w, void *v );
|
||||||
void menu_cb ( const Fl_Menu_ *m );
|
void menu_cb ( const Fl_Menu_ *m );
|
||||||
|
|
||||||
|
|
||||||
|
static void peer_callback( OSC::Signal *sig, OSC::Signal::State state, void *v );
|
||||||
|
void peer_callback( OSC::Signal *sig, OSC::Signal::State state );
|
||||||
|
void add_osc_peers_to_menu ( Fl_Menu_Button *m, const char *prefix );
|
||||||
|
void add_osc_connections_to_menu ( Fl_Menu_Button *m, const char *prefix );
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static bool _learn_mode;
|
static bool _learn_mode;
|
||||||
|
|
|
@ -170,6 +170,8 @@ public:
|
||||||
void buffer ( void *buf, nframes_t nframes ) { _buf = buf; _nframes = nframes; };
|
void buffer ( void *buf, nframes_t nframes ) { _buf = buf; _nframes = nframes; };
|
||||||
void *buffer ( void ) const { return _buf; }
|
void *buffer ( void ) const { return _buf; }
|
||||||
|
|
||||||
|
OSC::Signal *scaled_signal ( void ) { return _scaled_signal; }
|
||||||
|
|
||||||
const char *osc_path ( )
|
const char *osc_path ( )
|
||||||
{
|
{
|
||||||
if ( _scaled_signal )
|
if ( _scaled_signal )
|
||||||
|
|
|
@ -625,6 +625,29 @@ namespace OSC
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char**
|
||||||
|
Endpoint::get_connections ( const char *path )
|
||||||
|
{
|
||||||
|
const char ** conn = NULL;
|
||||||
|
|
||||||
|
int j = 0;
|
||||||
|
for ( std::map<std::string,TranslationDestination>::iterator i = _translations.begin();
|
||||||
|
i != _translations.end();
|
||||||
|
i++ )
|
||||||
|
{
|
||||||
|
if ( !strcmp( i->second.path.c_str(), path ) )
|
||||||
|
{
|
||||||
|
conn = (const char**)realloc( conn, sizeof( char * ) * (j+2));
|
||||||
|
conn[j++] = i->first.c_str();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( conn )
|
||||||
|
conn[j] = 0;
|
||||||
|
|
||||||
|
return conn;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Endpoint::clear_translations ( void )
|
Endpoint::clear_translations ( void )
|
||||||
{
|
{
|
||||||
|
|
|
@ -324,6 +324,7 @@ namespace OSC
|
||||||
return _addr;
|
return _addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char * * get_connections ( const char *path );
|
||||||
void clear_translations ( void );
|
void clear_translations ( void );
|
||||||
void del_translation ( const char *a );
|
void del_translation ( const char *a );
|
||||||
void add_translation ( const char *a, const char *b );
|
void add_translation ( const char *a, const char *b );
|
||||||
|
|
Loading…
Reference in New Issue