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
|
||||
#include "Mixer.H"
|
||||
|
||||
#include "string_util.h"
|
||||
|
||||
|
||||
|
||||
bool Controller_Module::learn_by_number = false;
|
||||
|
@ -358,7 +360,7 @@ Controller_Module::connect_to ( Port *p )
|
|||
w = o;
|
||||
|
||||
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->minimum(1.5);
|
||||
o->maximum(0);
|
||||
|
@ -496,6 +498,181 @@ Controller_Module::menu_cb ( const Fl_Menu_ *m )
|
|||
mode( CV );
|
||||
else if ( ! strcmp( picked, "/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 */
|
||||
|
@ -504,19 +681,21 @@ Controller_Module::menu ( void )
|
|||
{
|
||||
static Fl_Menu_Button m( 0, 0, 0, 0, "Controller" );
|
||||
|
||||
Fl_Menu_Item items[] =
|
||||
{
|
||||
{ "Mode", 0, 0, 0, FL_SUBMENU },
|
||||
{ "GUI + OSC", 0, 0, 0, FL_MENU_RADIO | ( mode() == GUI ? FL_MENU_VALUE : 0 ) },
|
||||
{ "Control Voltage (JACK)", 0, 0, 0, FL_MENU_RADIO | ( mode() == CV ? FL_MENU_VALUE : 0 ) },
|
||||
{ 0 },
|
||||
{ "Remove", 0, 0, 0, 0 },
|
||||
{ 0 },
|
||||
};
|
||||
m.clear();
|
||||
|
||||
menu_set_callback( items, &Controller_Module::menu_cb, (void*)this );
|
||||
if ( mode() == GUI )
|
||||
{
|
||||
add_osc_peers_to_menu( &m, "Connect To" );
|
||||
add_osc_connections_to_menu( &m, "Disconnect From" );
|
||||
}
|
||||
|
||||
m.copy( items, (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 );
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
|
|
@ -40,6 +40,12 @@ class Controller_Module : public Module
|
|||
static void menu_cb ( Fl_Widget *w, void *v );
|
||||
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:
|
||||
|
||||
static bool _learn_mode;
|
||||
|
|
|
@ -170,6 +170,8 @@ public:
|
|||
void buffer ( void *buf, nframes_t nframes ) { _buf = buf; _nframes = nframes; };
|
||||
void *buffer ( void ) const { return _buf; }
|
||||
|
||||
OSC::Signal *scaled_signal ( void ) { return _scaled_signal; }
|
||||
|
||||
const char *osc_path ( )
|
||||
{
|
||||
if ( _scaled_signal )
|
||||
|
|
|
@ -625,6 +625,29 @@ namespace OSC
|
|||
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
|
||||
Endpoint::clear_translations ( void )
|
||||
{
|
||||
|
|
|
@ -324,6 +324,7 @@ namespace OSC
|
|||
return _addr;
|
||||
}
|
||||
|
||||
const char * * get_connections ( const char *path );
|
||||
void clear_translations ( void );
|
||||
void del_translation ( const char *a );
|
||||
void add_translation ( const char *a, const char *b );
|
||||
|
|
Loading…
Reference in New Issue