Implement drag and drop for making/breaking JACK connections in Non Mixer and Non Timeline.
(Drag jack output module and drop on jack input module of another strip) In Non Mixer, all JACK modules (including Aux) will now list their connections.
This commit is contained in:
parent
52f016abed
commit
455c93683c
|
@ -157,7 +157,6 @@ public:
|
|||
{
|
||||
static int _button;
|
||||
|
||||
int r = 0;
|
||||
switch ( m )
|
||||
{
|
||||
case FL_PUSH:
|
||||
|
@ -217,6 +216,6 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
return Fl_Group::handle( m ) | r;
|
||||
return Fl_Group::handle( m );
|
||||
}
|
||||
};
|
||||
|
|
|
@ -69,7 +69,7 @@ public:
|
|||
virtual int
|
||||
handle ( int m )
|
||||
{
|
||||
int r = Fl_Input::handle( m );
|
||||
int r = 0;
|
||||
|
||||
switch ( m )
|
||||
{
|
||||
|
@ -79,23 +79,31 @@ public:
|
|||
Fl::event_key() == FL_Tab ) )
|
||||
{
|
||||
Fl::focus( NULL );
|
||||
return 1;
|
||||
r = 1;
|
||||
}
|
||||
else
|
||||
return r;
|
||||
break;
|
||||
}
|
||||
case FL_FOCUS:
|
||||
redraw();
|
||||
return 1;
|
||||
r = 1;
|
||||
break;
|
||||
case FL_UNFOCUS:
|
||||
do_callback();
|
||||
return 1;
|
||||
r = 1;
|
||||
break;
|
||||
case FL_PUSH:
|
||||
take_focus();
|
||||
redraw();
|
||||
return 1;
|
||||
r = 1;
|
||||
break;
|
||||
case FL_DND_ENTER:
|
||||
return 0;
|
||||
case FL_PASTE:
|
||||
return 0;
|
||||
default:
|
||||
return r;
|
||||
break;
|
||||
}
|
||||
|
||||
return Fl_Input::handle( m ) | r;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
/*******************************************************************************/
|
||||
/* Copyright (C) 2013 Jonathan Moore Liles */
|
||||
/* */
|
||||
/* This program is free software; you can redistribute it and/or modify it */
|
||||
/* under the terms of the GNU General Public License as published by the */
|
||||
/* Free Software Foundation; either version 2 of the License, or (at your */
|
||||
/* option) any later version. */
|
||||
/* */
|
||||
/* This program is distributed in the hope that it will be useful, but WITHOUT */
|
||||
/* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
|
||||
/* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for */
|
||||
/* more details. */
|
||||
/* */
|
||||
/* You should have received a copy of the GNU General Public License along */
|
||||
/* with This program; see the file COPYING. If not,write to the Free Software */
|
||||
/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
/*******************************************************************************/
|
||||
|
||||
static unsigned char img_io_input_connector_10x10_png[] = {
|
||||
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
|
||||
0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0a,
|
||||
0x08, 0x06, 0x00, 0x00, 0x00, 0x8d, 0x32, 0xcf, 0xbd, 0x00, 0x00, 0x00,
|
||||
0x04, 0x73, 0x42, 0x49, 0x54, 0x08, 0x08, 0x08, 0x08, 0x7c, 0x08, 0x64,
|
||||
0x88, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00,
|
||||
0x9e, 0x00, 0x00, 0x00, 0x9e, 0x01, 0x22, 0xcb, 0xc6, 0x03, 0x00, 0x00,
|
||||
0x00, 0x19, 0x74, 0x45, 0x58, 0x74, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61,
|
||||
0x72, 0x65, 0x00, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x6e, 0x6b, 0x73, 0x63,
|
||||
0x61, 0x70, 0x65, 0x2e, 0x6f, 0x72, 0x67, 0x9b, 0xee, 0x3c, 0x1a, 0x00,
|
||||
0x00, 0x01, 0x51, 0x49, 0x44, 0x41, 0x54, 0x18, 0x95, 0x3d, 0xd0, 0xb1,
|
||||
0x6a, 0xdb, 0x40, 0x1c, 0xc0, 0xe1, 0x9f, 0x72, 0x7f, 0xcc, 0x21, 0xbc,
|
||||
0xc5, 0x87, 0xb0, 0xb7, 0x18, 0x6c, 0xa8, 0x49, 0x37, 0x1b, 0x8c, 0x26,
|
||||
0xdb, 0x19, 0xfb, 0x0e, 0x7e, 0x82, 0xee, 0x21, 0x53, 0xe9, 0x14, 0x42,
|
||||
0x37, 0x37, 0x7b, 0x9e, 0xa2, 0x63, 0x07, 0x6b, 0xd6, 0xec, 0xc5, 0xe0,
|
||||
0x80, 0xc1, 0x08, 0xac, 0x66, 0xf0, 0xa0, 0xb3, 0x90, 0x4e, 0xa7, 0x4e,
|
||||
0xed, 0xf6, 0xcd, 0x5f, 0xd0, 0xb6, 0x2d, 0x00, 0xfb, 0xfd, 0xfe, 0x4b,
|
||||
0x59, 0x96, 0x8f, 0x4d, 0xd3, 0xdc, 0x01, 0x4e, 0x44, 0xf2, 0x30, 0x0c,
|
||||
0x9f, 0x86, 0xc3, 0xe1, 0x6f, 0x80, 0xa0, 0x6d, 0x5b, 0x76, 0xbb, 0xdd,
|
||||
0xb7, 0xf3, 0xf9, 0xfc, 0x35, 0x4d, 0xd3, 0x5e, 0x96, 0x65, 0x78, 0xef,
|
||||
0x19, 0x0c, 0x06, 0x4c, 0xa7, 0xd3, 0x8f, 0x28, 0x8a, 0x7e, 0x4e, 0x26,
|
||||
0x93, 0xef, 0x6a, 0xbd, 0x5e, 0x3f, 0x9c, 0x4e, 0xa7, 0x1f, 0x49, 0x92,
|
||||
0xf4, 0x2e, 0x97, 0x0b, 0xdb, 0xed, 0x96, 0xe3, 0xf1, 0x88, 0x31, 0x86,
|
||||
0x2c, 0xcb, 0x42, 0x63, 0xcc, 0x7d, 0x5d, 0xd7, 0xbb, 0x1b, 0x6b, 0xed,
|
||||
0x73, 0x9a, 0xa6, 0xb7, 0x00, 0x4a, 0x29, 0x44, 0x04, 0x11, 0x41, 0x29,
|
||||
0x05, 0x40, 0x9a, 0xa6, 0xbd, 0xb2, 0x2c, 0x1f, 0xc5, 0x39, 0x67, 0xac,
|
||||
0xb5, 0x78, 0xef, 0x09, 0x82, 0x80, 0xd5, 0x6a, 0x45, 0x10, 0x04, 0xb4,
|
||||
0x6d, 0x8b, 0x73, 0x8e, 0xa2, 0x28, 0x68, 0x9a, 0xe6, 0x4e, 0x00, 0xf1,
|
||||
0xde, 0x93, 0x24, 0x09, 0x45, 0x51, 0x10, 0xc7, 0x31, 0x22, 0x42, 0x92,
|
||||
0x24, 0x68, 0xad, 0x59, 0x2e, 0x97, 0x00, 0xee, 0x46, 0x29, 0xf5, 0xde,
|
||||
0xed, 0x76, 0xb9, 0x5e, 0xaf, 0x78, 0xef, 0xa9, 0xaa, 0x8a, 0xaa, 0xaa,
|
||||
0xfe, 0x5b, 0x6b, 0x8d, 0x88, 0xe4, 0xa2, 0xb5, 0x7e, 0x99, 0xcd, 0x66,
|
||||
0x9f, 0xf2, 0x3c, 0xef, 0x59, 0x6b, 0x31, 0xc6, 0x00, 0x10, 0xc7, 0x31,
|
||||
0x9d, 0x4e, 0x87, 0xf9, 0x7c, 0xfe, 0x11, 0x86, 0xe1, 0x93, 0xda, 0x6c,
|
||||
0x36, 0x7b, 0x6b, 0x6d, 0xd8, 0xef, 0xf7, 0x3f, 0x5b, 0x6b, 0xc3, 0xba,
|
||||
0xae, 0x01, 0x30, 0xc6, 0xb0, 0x58, 0x2c, 0xfe, 0x44, 0x51, 0xf4, 0x3a,
|
||||
0x1e, 0x8f, 0xdf, 0x82, 0x7f, 0xe1, 0x87, 0xc3, 0xe1, 0xc1, 0x5a, 0xfb,
|
||||
0xec, 0x9c, 0x33, 0x80, 0x28, 0xa5, 0xde, 0xb5, 0xd6, 0x2f, 0xa3, 0xd1,
|
||||
0xe8, 0x17, 0xc0, 0x5f, 0xd1, 0x17, 0xa6, 0x12, 0x83, 0xc3, 0x30, 0x9b,
|
||||
0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
|
||||
|
||||
};
|
||||
static unsigned int img_io_input_connector_10x10_png_len = 468;
|
|
@ -0,0 +1,63 @@
|
|||
|
||||
/*******************************************************************************/
|
||||
/* Copyright (C) 2013 Jonathan Moore Liles */
|
||||
/* */
|
||||
/* This program is free software; you can redistribute it and/or modify it */
|
||||
/* under the terms of the GNU General Public License as published by the */
|
||||
/* Free Software Foundation; either version 2 of the License, or (at your */
|
||||
/* option) any later version. */
|
||||
/* */
|
||||
/* This program is distributed in the hope that it will be useful, but WITHOUT */
|
||||
/* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
|
||||
/* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for */
|
||||
/* more details. */
|
||||
/* */
|
||||
/* You should have received a copy of the GNU General Public License along */
|
||||
/* with This program; see the file COPYING. If not,write to the Free Software */
|
||||
/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
/*******************************************************************************/
|
||||
|
||||
static unsigned char img_io_output_connector_10x10_png[] = {
|
||||
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
|
||||
0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0a,
|
||||
0x08, 0x06, 0x00, 0x00, 0x00, 0x8d, 0x32, 0xcf, 0xbd, 0x00, 0x00, 0x00,
|
||||
0x04, 0x73, 0x42, 0x49, 0x54, 0x08, 0x08, 0x08, 0x08, 0x7c, 0x08, 0x64,
|
||||
0x88, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00,
|
||||
0x9e, 0x00, 0x00, 0x00, 0x9e, 0x01, 0x22, 0xcb, 0xc6, 0x03, 0x00, 0x00,
|
||||
0x00, 0x19, 0x74, 0x45, 0x58, 0x74, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61,
|
||||
0x72, 0x65, 0x00, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x6e, 0x6b, 0x73, 0x63,
|
||||
0x61, 0x70, 0x65, 0x2e, 0x6f, 0x72, 0x67, 0x9b, 0xee, 0x3c, 0x1a, 0x00,
|
||||
0x00, 0x01, 0x61, 0x49, 0x44, 0x41, 0x54, 0x18, 0x95, 0x35, 0xd0, 0xbf,
|
||||
0x6a, 0xc2, 0x40, 0x00, 0x07, 0xe0, 0xdf, 0xfd, 0x89, 0xe4, 0x32, 0xc4,
|
||||
0x40, 0xed, 0x22, 0x9c, 0x50, 0x24, 0x99, 0x1c, 0xdc, 0x33, 0x38, 0x64,
|
||||
0xec, 0x03, 0x14, 0x9c, 0xd4, 0xb9, 0x7b, 0xe9, 0x54, 0x3a, 0x95, 0xd2,
|
||||
0xb1, 0x1d, 0x74, 0xeb, 0xe4, 0xec, 0xd2, 0x31, 0x01, 0x9f, 0x40, 0x04,
|
||||
0xe9, 0x10, 0x85, 0x06, 0x1c, 0x6d, 0x40, 0x34, 0xe4, 0xd0, 0x0b, 0x5e,
|
||||
0xa7, 0x7e, 0x8f, 0xf0, 0x11, 0x63, 0x0c, 0x00, 0x60, 0xbd, 0x5e, 0xdf,
|
||||
0x96, 0x65, 0xf9, 0xa0, 0xb5, 0xbe, 0x21, 0x84, 0x54, 0x9c, 0xf3, 0x9d,
|
||||
0x10, 0xe2, 0x31, 0x08, 0x82, 0x18, 0x00, 0x88, 0x31, 0x06, 0xab, 0xd5,
|
||||
0xea, 0x69, 0xbb, 0xdd, 0xde, 0x27, 0x49, 0xd2, 0xb0, 0x6d, 0x1b, 0x8c,
|
||||
0x31, 0x14, 0x45, 0x81, 0x28, 0x8a, 0x72, 0x29, 0xe5, 0x7b, 0xa7, 0xd3,
|
||||
0x79, 0x66, 0xfd, 0x7e, 0x3f, 0xca, 0xb2, 0xec, 0x6d, 0x36, 0x9b, 0x35,
|
||||
0x84, 0x10, 0x18, 0x8d, 0x46, 0xe8, 0x76, 0xbb, 0x58, 0x2e, 0x97, 0x58,
|
||||
0x2c, 0x16, 0x4e, 0xb3, 0xd9, 0xec, 0x00, 0xf8, 0xa6, 0x4a, 0xa9, 0x97,
|
||||
0x38, 0x8e, 0xaf, 0x00, 0x40, 0x6b, 0x8d, 0xf3, 0xf9, 0x8c, 0xd3, 0xe9,
|
||||
0x04, 0xad, 0x35, 0x00, 0x20, 0x49, 0x92, 0x46, 0x59, 0x96, 0x0f, 0xbc,
|
||||
0xaa, 0xaa, 0xeb, 0xe3, 0xf1, 0x08, 0xc6, 0x18, 0x2e, 0x97, 0x0b, 0xc6,
|
||||
0xe3, 0x31, 0x8c, 0x31, 0xa0, 0x94, 0xa2, 0x56, 0xab, 0xe1, 0x70, 0x38,
|
||||
0x40, 0x6b, 0x7d, 0xc3, 0x8d, 0x31, 0x9c, 0x52, 0x8a, 0xe1, 0x70, 0x08,
|
||||
0xcf, 0xf3, 0x30, 0x9d, 0x4e, 0xa1, 0xb5, 0xc6, 0x60, 0x30, 0x40, 0x51,
|
||||
0x14, 0x98, 0x4c, 0x26, 0x20, 0x84, 0x54, 0xd4, 0xb2, 0xac, 0x1f, 0xd7,
|
||||
0x75, 0xe1, 0xba, 0x2e, 0x38, 0xe7, 0x70, 0x1c, 0x07, 0x42, 0x08, 0x30,
|
||||
0xc6, 0x60, 0xdb, 0x36, 0x3c, 0xcf, 0x03, 0xe7, 0x7c, 0x47, 0xd2, 0x34,
|
||||
0xbd, 0xdd, 0x6c, 0x36, 0x9f, 0xf3, 0xf9, 0xbc, 0x51, 0xaf, 0xd7, 0x91,
|
||||
0x65, 0x19, 0x00, 0xa0, 0xd5, 0x6a, 0x41, 0x29, 0x85, 0x30, 0x0c, 0xf3,
|
||||
0x76, 0xbb, 0x7d, 0x47, 0x7d, 0xdf, 0xff, 0x92, 0x52, 0x7e, 0xf4, 0x7a,
|
||||
0xbd, 0x3c, 0xcf, 0x73, 0xfc, 0xdb, 0xef, 0xf7, 0x08, 0xc3, 0xf0, 0x57,
|
||||
0x4a, 0xf9, 0x1e, 0x04, 0x41, 0x4c, 0xfe, 0xc3, 0xd3, 0x34, 0x8d, 0x94,
|
||||
0x52, 0x2f, 0x55, 0x55, 0x5d, 0x1b, 0x63, 0xb8, 0x65, 0x59, 0x3f, 0x8e,
|
||||
0xe3, 0xbc, 0xfa, 0xbe, 0xff, 0x05, 0x00, 0x7f, 0xb0, 0xa3, 0x9e, 0x20,
|
||||
0x9c, 0xde, 0x99, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44,
|
||||
0xae, 0x42, 0x60, 0x82
|
||||
};
|
||||
static unsigned int img_io_output_connector_10x10_png_len = 484;
|
2
lib/ntk
2
lib/ntk
|
@ -1 +1 @@
|
|||
Subproject commit fe832d3cbc807c475f4b6a51facf543aa7d9882d
|
||||
Subproject commit ed50ecc551d5e490f4acb1ec673c9e8f43e23fb0
|
|
@ -123,6 +123,7 @@ AUX_Module::draw ( void )
|
|||
{
|
||||
int W = 5;
|
||||
|
||||
child(0)->size( w() - W, 18 );
|
||||
Module::draw_box(x(),y(),w() - W,h());
|
||||
Module::draw_label(x(),y(),w() - W,h());
|
||||
|
||||
|
|
|
@ -458,6 +458,7 @@ Chain::name ( const char *name )
|
|||
_engine = new Engine( &Chain::process, this );
|
||||
|
||||
engine()->buffer_size_callback( &Chain::buffer_size, this );
|
||||
engine()->port_connect_callback( &Chain::port_connect, this );
|
||||
|
||||
const char *jack_name = engine()->init( ename );
|
||||
|
||||
|
@ -824,3 +825,43 @@ Chain::buffer_size ( nframes_t nframes )
|
|||
m->resize_buffers( nframes );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Chain::port_connect ( jack_port_id_t a, jack_port_id_t b, int connect, void *v )
|
||||
{
|
||||
((Chain*)v)->port_connect( a, b, connect );
|
||||
}
|
||||
|
||||
/* handle jack port connection change */
|
||||
void
|
||||
Chain::port_connect ( jack_port_id_t a, jack_port_id_t b, int connect )
|
||||
{
|
||||
/* this is called from JACK non-RT thread... */
|
||||
|
||||
if ( jack_port_is_mine( engine()->jack_client(), jack_port_by_id( engine()->jack_client(), a ) ) ||
|
||||
jack_port_is_mine( engine()->jack_client(), jack_port_by_id( engine()->jack_client(), b ) ))
|
||||
{
|
||||
Fl::awake( Chain::update_connection_status, this );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Chain::update_connection_status ( void *v )
|
||||
{
|
||||
((Chain*)v)->update_connection_status();
|
||||
}
|
||||
|
||||
void
|
||||
Chain::update_connection_status ( void )
|
||||
{
|
||||
for ( int i = 0; i < modules(); i++ )
|
||||
{
|
||||
Module *m = module(i);
|
||||
|
||||
if ( !strcmp( m->name(), "JACK" ) ||
|
||||
!strcmp( m->name(), "AUX" ))
|
||||
{
|
||||
((JACK_Module*)m)->update_connection_status();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -73,6 +73,13 @@ private:
|
|||
static void buffer_size ( nframes_t nframes, void *v );
|
||||
void buffer_size ( nframes_t nframes );
|
||||
|
||||
|
||||
static void port_connect ( jack_port_id_t a, jack_port_id_t b, int connect, void *v );
|
||||
void port_connect ( jack_port_id_t a, jack_port_id_t b, int connect );
|
||||
|
||||
static void update_connection_status ( void *v );
|
||||
void update_connection_status ( void );
|
||||
|
||||
protected:
|
||||
|
||||
void get ( Log_Entry &e ) const;
|
||||
|
|
|
@ -36,6 +36,7 @@ Engine::Engine ( void (*process_callback)(nframes_t nframes, void *), void *user
|
|||
_process_callback_user_data = user_data;
|
||||
_buffer_size_callback = 0;
|
||||
_buffers_dropped = 0;
|
||||
_port_connect_callback = 0;
|
||||
}
|
||||
|
||||
Engine::~Engine ( )
|
||||
|
@ -52,6 +53,13 @@ Engine::buffer_size_callback ( void ( *buffer_size_callback ) ( nframes_t, void
|
|||
_buffer_size_callback_user_data = user_data;
|
||||
}
|
||||
|
||||
void
|
||||
Engine::port_connect_callback ( void ( *port_connect_callback ) ( jack_port_id_t a, jack_port_id_t b, int connect, void *arg), void *user_data )
|
||||
{
|
||||
_port_connect_callback = port_connect_callback;
|
||||
_port_connect_callback_user_data = user_data;
|
||||
}
|
||||
|
||||
/*************/
|
||||
/* Callbacks */
|
||||
/*************/
|
||||
|
@ -91,6 +99,15 @@ Engine::buffer_size ( nframes_t nframes )
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* THREAD: ?? */
|
||||
void
|
||||
Engine::port_connect( jack_port_id_t a, jack_port_id_t b, int connect )
|
||||
{
|
||||
if ( _port_connect_callback )
|
||||
_port_connect_callback( a, b, connect, _port_connect_callback_user_data );
|
||||
}
|
||||
|
||||
|
||||
/* THREAD: RT */
|
||||
int
|
||||
Engine::process ( nframes_t nframes )
|
||||
|
|
|
@ -40,13 +40,16 @@ class Engine : public JACK::Client, public Mutex
|
|||
void ( * _buffer_size_callback ) ( nframes_t, void * );
|
||||
void *_buffer_size_callback_user_data;
|
||||
|
||||
void ( * _port_connect_callback ) ( jack_port_id_t a, jack_port_id_t b, int connect, void * );
|
||||
void *_port_connect_callback_user_data;
|
||||
|
||||
void shutdown ( void );
|
||||
int process ( nframes_t nframes );
|
||||
int xrun ( void );
|
||||
void freewheel ( bool yes );
|
||||
int buffer_size ( nframes_t nframes );
|
||||
void thread_init ( void );
|
||||
|
||||
void port_connect ( jack_port_id_t a, jack_port_id_t b, int connect );
|
||||
Engine ( const Engine &rhs );
|
||||
Engine & operator = ( const Engine &rhs );
|
||||
|
||||
|
@ -64,4 +67,5 @@ public:
|
|||
|
||||
int dropped ( void ) const { return _buffers_dropped; }
|
||||
void buffer_size_callback ( void ( *buffer_size_callback ) ( nframes_t, void * ), void *user_data );
|
||||
void port_connect_callback ( void ( *port_connect_callback ) ( jack_port_id_t a, jack_port_id_t b, int connect, void *arg), void *user_data );
|
||||
};
|
||||
|
|
|
@ -22,6 +22,9 @@
|
|||
#include <string.h>
|
||||
|
||||
#include <FL/fl_ask.H>
|
||||
#include <FL/Fl_Box.H>
|
||||
#include <FL/Fl_Pack.H>
|
||||
#include <FL/Fl_Scalepack.H>
|
||||
|
||||
#include "dsp.h"
|
||||
|
||||
|
@ -29,14 +32,30 @@
|
|||
#include "Chain.H"
|
||||
|
||||
#include "JACK_Module.H"
|
||||
#include <FL/fl_draw.H>
|
||||
|
||||
#include <FL/Fl.H>
|
||||
#include <FL/Fl_Browser.H>
|
||||
|
||||
#include <FL/Fl_PNG_Image.H>
|
||||
#include <FL/img_io_input_connector_10x10_png.h>
|
||||
#include <FL/img_io_output_connector_10x10_png.h>
|
||||
|
||||
static Fl_PNG_Image *input_connector_image = NULL;
|
||||
static Fl_PNG_Image *output_connector_image = NULL;
|
||||
|
||||
extern char *instance_name;
|
||||
|
||||
|
||||
static JACK_Module *receptive_to_drop = NULL;
|
||||
|
||||
JACK_Module::JACK_Module ( bool log )
|
||||
: Module ( 50, 24, name() )
|
||||
: Module ( 25, 25, name() )
|
||||
{
|
||||
_prefix = 0;
|
||||
|
||||
align( FL_ALIGN_TOP | FL_ALIGN_INSIDE );
|
||||
|
||||
if ( log )
|
||||
{
|
||||
/* FIXME: how do Controls find out that a connected value has changed? How does this work in ladspa? */
|
||||
|
@ -72,6 +91,60 @@ JACK_Module::JACK_Module ( bool log )
|
|||
log_create();
|
||||
}
|
||||
|
||||
|
||||
{ Fl_Scalepack *o = new Fl_Scalepack( x() + Fl::box_dx(box()),
|
||||
y() + Fl::box_dy(box()),
|
||||
w(),
|
||||
24 - Fl::box_dh(box()) );
|
||||
o->type( Fl_Pack::HORIZONTAL );
|
||||
|
||||
o->spacing( 0 );
|
||||
|
||||
|
||||
{ Fl_Box *o = input_connection_handle = new Fl_Box( x(), y(), 18, 18 );
|
||||
o->tooltip( "Drag and drop to make and break JACK connections.");
|
||||
o->hide();
|
||||
o->image( input_connector_image ? input_connector_image : input_connector_image = new Fl_PNG_Image( "input_connector", img_io_input_connector_10x10_png, img_io_input_connector_10x10_png_len ) );
|
||||
|
||||
}
|
||||
|
||||
{ Fl_Box *o = new Fl_Box( x() + 10, y(), w() - 20, h() );
|
||||
Fl_Group::current()->resizable(o);
|
||||
}
|
||||
|
||||
|
||||
{ Fl_Button *o = dec_button = new Fl_Button( 0, 0, 12, h(), "-" );
|
||||
o->callback( cb_button, this );
|
||||
o->labelsize(10);
|
||||
o->labelfont( FL_HELVETICA_BOLD );
|
||||
o->hide();
|
||||
}
|
||||
{ Fl_Button *o = inc_button = new Fl_Button( 0,0, 12, h(), "+" );
|
||||
o->labelsize(10);
|
||||
o->labelfont( FL_HELVETICA_BOLD );
|
||||
o->callback( cb_button, this );
|
||||
o->hide();
|
||||
}
|
||||
|
||||
{ Fl_Box *o = output_connection_handle = new Fl_Box( x(), y(), 18, 18 );
|
||||
o->tooltip( "Drag and drop to make and break JACK connections.");
|
||||
o->image( output_connector_image ? output_connector_image : output_connector_image = new Fl_PNG_Image( "output_connector", img_io_output_connector_10x10_png, img_io_output_connector_10x10_png_len ) );
|
||||
o->hide();
|
||||
}
|
||||
|
||||
o->end();
|
||||
resizable(o);
|
||||
}
|
||||
|
||||
{
|
||||
Fl_Browser *o = connection_display = new Fl_Browser( x() + Fl::box_dx(box()), y() + 25, w() - Fl::box_dw(box()), 300 );
|
||||
o->textsize( 11 );
|
||||
o->textcolor( FL_LIGHT3 );
|
||||
o->textfont( FL_COURIER );
|
||||
o->box( FL_FLAT_BOX );
|
||||
o->color( fl_color_add_alpha( fl_rgb_color( 10, 10, 10 ), 25 ));
|
||||
}
|
||||
|
||||
end();
|
||||
}
|
||||
|
||||
|
@ -86,6 +159,155 @@ JACK_Module::~JACK_Module ( )
|
|||
|
||||
|
||||
|
||||
void
|
||||
JACK_Module::draw ( void )
|
||||
{
|
||||
Module::draw();
|
||||
if ( this == receptive_to_drop )
|
||||
{
|
||||
Fl_Widget *o = input_connection_handle;
|
||||
fl_draw_box( FL_OVAL_BOX, o->x(), o->y(), o->w(), o->h(), fl_color_add_alpha( FL_GREEN, 127 ) );
|
||||
}
|
||||
}
|
||||
|
||||
static std::list<std::string>
|
||||
get_connections_for_ports ( std::vector<JACK::Port> ports )
|
||||
{
|
||||
std::list<std::string> names;
|
||||
|
||||
for ( unsigned int i = 0; i < ports.size(); ++i )
|
||||
{
|
||||
const char **connections = ports[i].connections();
|
||||
|
||||
if ( ! connections )
|
||||
return names;
|
||||
|
||||
bool is_output = ports[i].type() == JACK::Port::Output;
|
||||
|
||||
for ( const char **c = connections; *c; c++ )
|
||||
{
|
||||
char *client_id = 0;
|
||||
char *strip_name = 0;
|
||||
// char *client_name = 0;
|
||||
|
||||
if ( 2 == sscanf( *c, "Non-Mixer.%a[^:/]/%a[^:]:", &client_id, &strip_name ) )
|
||||
{
|
||||
free( client_id );
|
||||
char *s = NULL;
|
||||
asprintf( &s, "%s%s", is_output ? "@r" : "", strip_name );
|
||||
free( strip_name );
|
||||
strip_name = s;
|
||||
}
|
||||
else
|
||||
if ( 2 == sscanf( *c, "Non-Timeline.%a[^:/]:%a[^/]/", &client_id, &strip_name ) )
|
||||
{
|
||||
free( client_id );
|
||||
char *s = NULL;
|
||||
asprintf( &s, "@C2%s%s", is_output ? "@r" : "", strip_name );
|
||||
free( strip_name );
|
||||
strip_name = s;
|
||||
}
|
||||
else
|
||||
if ( 2 == sscanf( *c, "Non-DAW.%a[^:/]:%a[^/]/", &client_id, &strip_name ) )
|
||||
{
|
||||
free( client_id );
|
||||
char *s = NULL;
|
||||
asprintf( &s, "@C2%s%s", is_output ? "@r" : "", strip_name );
|
||||
free( strip_name );
|
||||
strip_name = s;
|
||||
}
|
||||
else if ( 1 == sscanf( *c, "%a[^:]:", &strip_name ) )
|
||||
{
|
||||
char *s = NULL;
|
||||
asprintf( &s, "@C3%s%s", is_output ? "@r" : "", strip_name );
|
||||
free( strip_name );
|
||||
strip_name = s;
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for ( std::list<std::string>::const_iterator j = names.begin();
|
||||
j != names.end();
|
||||
j++ )
|
||||
{
|
||||
if ( !strcmp( j->c_str(), strip_name ) )
|
||||
{
|
||||
goto skip;
|
||||
}
|
||||
}
|
||||
|
||||
names.push_back( strip_name );
|
||||
|
||||
skip:
|
||||
free( strip_name );
|
||||
|
||||
;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
names.sort();
|
||||
return names;
|
||||
}
|
||||
|
||||
void
|
||||
JACK_Module::update_connection_status ( void )
|
||||
{
|
||||
std::list<std::string> output_names = get_connections_for_ports( jack_output );
|
||||
std::list<std::string> input_names = get_connections_for_ports( jack_input );
|
||||
|
||||
connection_display->clear();
|
||||
|
||||
int n = 0;
|
||||
for ( std::list<std::string>::const_iterator j = input_names.begin();
|
||||
j != input_names.end();
|
||||
j++ )
|
||||
{
|
||||
connection_display->add( j->c_str() );
|
||||
n++;
|
||||
}
|
||||
for ( std::list<std::string>::const_iterator j = output_names.begin();
|
||||
j != output_names.end();
|
||||
j++ )
|
||||
{
|
||||
connection_display->add( j->c_str() );
|
||||
n++;
|
||||
}
|
||||
|
||||
h( 25 + ( n * 13 ) );
|
||||
|
||||
parent()->parent()->redraw();
|
||||
}
|
||||
|
||||
void
|
||||
JACK_Module::cb_button ( Fl_Widget *w, void *v )
|
||||
{
|
||||
((JACK_Module*)v)->cb_button( w );
|
||||
}
|
||||
|
||||
void
|
||||
JACK_Module::cb_button( Fl_Widget *w )
|
||||
{
|
||||
int n = audio_output.size();
|
||||
|
||||
if ( w == dec_button )
|
||||
{
|
||||
--n;
|
||||
}
|
||||
else if ( w == inc_button )
|
||||
{
|
||||
++n;
|
||||
}
|
||||
|
||||
if ( chain()->can_configure_outputs( this, n ) )
|
||||
{
|
||||
configure_outputs( n );
|
||||
chain()->configure_ports();
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
JACK_Module::can_support_inputs ( int )
|
||||
{
|
||||
|
@ -95,6 +317,15 @@ JACK_Module::can_support_inputs ( int )
|
|||
bool
|
||||
JACK_Module::configure_inputs ( int n )
|
||||
{
|
||||
if ( n > 0 )
|
||||
{
|
||||
if ( is_default() )
|
||||
control_input[0].hints.minimum = 1;
|
||||
|
||||
output_connection_handle->show();
|
||||
}
|
||||
|
||||
|
||||
int on = audio_input.size();
|
||||
|
||||
if ( n > on )
|
||||
|
@ -151,6 +382,11 @@ JACK_Module::configure_outputs ( int n )
|
|||
{
|
||||
int on = audio_output.size();
|
||||
|
||||
if ( n > 0 )
|
||||
{
|
||||
input_connection_handle->show();
|
||||
}
|
||||
|
||||
if ( n > on )
|
||||
{
|
||||
for ( int i = on; i < n; ++i )
|
||||
|
@ -191,6 +427,11 @@ JACK_Module::configure_outputs ( int n )
|
|||
if ( is_default() )
|
||||
control_input[1].control_value_no_callback( n );
|
||||
|
||||
if ( n > 0 && is_default() )
|
||||
{
|
||||
dec_button->show();
|
||||
inc_button->show();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -244,6 +485,142 @@ JACK_Module::handle_chain_name_changed ( void )
|
|||
Module::handle_chain_name_changed();
|
||||
}
|
||||
|
||||
int
|
||||
JACK_Module::handle ( int m )
|
||||
{
|
||||
static JACK_Module *drag_source = 0;
|
||||
|
||||
switch ( m )
|
||||
{
|
||||
case FL_PUSH:
|
||||
return Module::handle(m) || 1;
|
||||
case FL_RELEASE:
|
||||
return Module::handle(m) || 1;
|
||||
case FL_DRAG:
|
||||
{
|
||||
if ( ! Fl::event_inside( this ) && this != drag_source )
|
||||
{
|
||||
DMESSAGE( "initiation of drag" );
|
||||
|
||||
char *s = (char*)malloc(256);
|
||||
s[0] = 0;
|
||||
|
||||
for ( unsigned int i = 0; i < jack_output.size(); ++i )
|
||||
{
|
||||
char *s2;
|
||||
asprintf(&s2, "jack.port://%s/%s:%s\r\n", instance_name, chain()->name(), jack_output[i].name() );
|
||||
|
||||
s = (char*)realloc( s, strlen( s ) + strlen( s2 ) + 1 );
|
||||
strcat( s, s2 );
|
||||
|
||||
free( s2 );
|
||||
}
|
||||
|
||||
Fl::copy(s, strlen(s) + 1, 0);
|
||||
|
||||
free( s );
|
||||
|
||||
Fl::dnd();
|
||||
|
||||
drag_source = this;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
/* we have to prevent Fl_Group::handle() from getting these, otherwise it will mess up Fl::belowmouse() */
|
||||
case FL_MOVE:
|
||||
return 0;
|
||||
case FL_ENTER:
|
||||
case FL_DND_ENTER:
|
||||
return 1;
|
||||
case FL_LEAVE:
|
||||
case FL_DND_LEAVE:
|
||||
if ( this == receptive_to_drop )
|
||||
{
|
||||
receptive_to_drop = NULL;
|
||||
redraw();
|
||||
}
|
||||
return 1;
|
||||
case FL_DND_RELEASE:
|
||||
receptive_to_drop = NULL;
|
||||
redraw();
|
||||
return 1;
|
||||
case FL_DND_DRAG:
|
||||
{
|
||||
if ( this == drag_source )
|
||||
return 0;
|
||||
|
||||
if ( this == receptive_to_drop )
|
||||
return 1;
|
||||
|
||||
if ( jack_input.size() )
|
||||
{
|
||||
|
||||
receptive_to_drop = this;
|
||||
redraw();
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
case FL_PASTE:
|
||||
{
|
||||
receptive_to_drop = NULL;
|
||||
redraw();
|
||||
|
||||
drag_source = NULL;
|
||||
|
||||
/* NOW we get the text... */
|
||||
const char *text = Fl::event_text();
|
||||
|
||||
DMESSAGE( "Got drop text \"%s\"",text);
|
||||
|
||||
if ( strncmp( text, "jack.port://", strlen( "jack.port://" ) ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::vector<std::string> port_names;
|
||||
|
||||
char *port_name;
|
||||
int end;
|
||||
while ( sscanf( text, "jack.port://%a[^\r\n]\r\n%n", &port_name, &end ) > 0 )
|
||||
{
|
||||
DMESSAGE( "Scanning %s", port_name );
|
||||
port_names.push_back( port_name );
|
||||
free(port_name );
|
||||
|
||||
text += end;
|
||||
}
|
||||
|
||||
for ( unsigned int i = 0; i < jack_input.size() && i < port_names.size(); i++)
|
||||
{
|
||||
const char *pn = port_names[i].c_str();
|
||||
|
||||
JACK::Port *ji = &jack_input[i];
|
||||
|
||||
if ( ji->connected_to( pn ) )
|
||||
{
|
||||
|
||||
DMESSAGE( "Disconnecting from \"%s\"", pn );
|
||||
ji->disconnect( pn );
|
||||
}
|
||||
else
|
||||
{
|
||||
DMESSAGE( "Connecting to %s", pn );
|
||||
ji->connect( pn );
|
||||
}
|
||||
}
|
||||
|
||||
Fl::selection_owner(0);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return Module::handle(m);
|
||||
}
|
||||
|
||||
|
||||
/**********/
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
class Fl_Box;
|
||||
class Fl_Browser;
|
||||
#include "Module.H"
|
||||
#include "JACK/Port.H"
|
||||
#include <vector>
|
||||
|
@ -45,15 +47,28 @@ protected:
|
|||
|
||||
static void jack_port_activation_error ( JACK::Port *p );
|
||||
|
||||
Fl_Button * dec_button;
|
||||
Fl_Button * inc_button;
|
||||
Fl_Browser * connection_display;
|
||||
Fl_Box * input_connection_handle;
|
||||
Fl_Box * output_connection_handle;
|
||||
|
||||
static void cb_button ( Fl_Widget *w, void *v );
|
||||
void cb_button ( Fl_Widget *w );
|
||||
|
||||
public:
|
||||
|
||||
void update_connection_status ( void );
|
||||
|
||||
JACK_Module ( bool log = true );
|
||||
virtual ~JACK_Module ( );
|
||||
|
||||
virtual const char *name ( void ) const { return "JACK"; }
|
||||
|
||||
virtual bool initialize ( void );
|
||||
|
||||
virtual void draw ( void );
|
||||
virtual int handle ( int m );
|
||||
|
||||
virtual int can_support_inputs ( int );
|
||||
virtual bool configure_inputs ( int n );
|
||||
virtual bool configure_outputs ( int n );
|
||||
|
|
|
@ -730,22 +730,6 @@ Mixer::update_menu ( void )
|
|||
project_name->label( Project::name() );
|
||||
}
|
||||
|
||||
int
|
||||
Mixer::handle ( int m )
|
||||
{
|
||||
if ( Fl_Group::handle( m ) )
|
||||
return 1;
|
||||
|
||||
switch ( m )
|
||||
{
|
||||
case FL_ENTER:
|
||||
case FL_LEAVE:
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/************/
|
||||
|
|
|
@ -73,10 +73,6 @@ private:
|
|||
|
||||
static int osc_non_hello ( const char *, const char *, lo_arg **, int , lo_message msg, void * );
|
||||
|
||||
protected:
|
||||
|
||||
int handle ( int m );
|
||||
|
||||
public:
|
||||
|
||||
char * get_unique_track_name ( const char *name );
|
||||
|
|
|
@ -211,7 +211,7 @@ Mixer_Strip::chain ( Chain *c )
|
|||
|
||||
void Mixer_Strip::cb_handle(Fl_Widget* o) {
|
||||
// parent()->parent()->damage( FL_DAMAGE_ALL, x(), y(), w(), h() );
|
||||
DMESSAGE( "Callback for %s", o->label() );
|
||||
// DMESSAGE( "Callback for %s", o->label() );
|
||||
|
||||
if ( o == tab_button )
|
||||
{
|
||||
|
@ -441,7 +441,6 @@ Mixer_Strip::init ( )
|
|||
|
||||
o->end();
|
||||
} // Fl_Group* o
|
||||
|
||||
{ Fl_Flip_Button* o = tab_button = new Fl_Flip_Button(61, 183, 45, 22, "fader/signal");
|
||||
o->type(1);
|
||||
o->labelsize( 14 );
|
||||
|
@ -481,7 +480,6 @@ Mixer_Strip::init ( )
|
|||
o->pad( false );
|
||||
o->size( 33, 100 );
|
||||
}
|
||||
|
||||
{ Meter_Indicator_Module *o = meter_indicator = new Meter_Indicator_Module( true );
|
||||
o->disable_context_menu( true );
|
||||
o->pad( false );
|
||||
|
@ -693,15 +691,30 @@ Mixer_Strip::menu ( void ) const
|
|||
int
|
||||
Mixer_Strip::handle ( int m )
|
||||
{
|
||||
static int _button = 0;
|
||||
|
||||
Logger log( this );
|
||||
|
||||
if ( Fl_Group::handle( m ) )
|
||||
return 1;
|
||||
|
||||
switch ( m )
|
||||
{
|
||||
case FL_FOCUS:
|
||||
damage( FL_DAMAGE_USER1 );
|
||||
return 1;
|
||||
case FL_UNFOCUS:
|
||||
damage( FL_DAMAGE_USER1 );
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* if ( m == FL_PUSH ) */
|
||||
/* take_focus(); */
|
||||
|
||||
switch ( m )
|
||||
{
|
||||
case FL_KEYBOARD:
|
||||
{
|
||||
if ( Fl_Group::handle( m ) )
|
||||
return 1;
|
||||
|
||||
if ( Fl::event_key() == FL_Menu )
|
||||
{
|
||||
menu_popup( &menu(), x(), y() );
|
||||
|
@ -712,34 +725,27 @@ Mixer_Strip::handle ( int m )
|
|||
break;
|
||||
}
|
||||
case FL_PUSH:
|
||||
_button = Fl::event_button();
|
||||
case FL_RELEASE:
|
||||
{
|
||||
int r = 0;
|
||||
if ( Fl::event_button1() )
|
||||
{
|
||||
take_focus();
|
||||
r = 1;
|
||||
}
|
||||
int b = _button;
|
||||
_button = 0;
|
||||
|
||||
if ( Fl_Group::handle( m ) )
|
||||
return 1;
|
||||
else if ( test_press( FL_BUTTON3 ) )
|
||||
/* if ( 1 == b ) */
|
||||
/* { */
|
||||
/* take_focus(); */
|
||||
/* } */
|
||||
/* else */
|
||||
if ( 3 == b )
|
||||
{
|
||||
menu_popup( &menu() );
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
return r;
|
||||
break;
|
||||
}
|
||||
case FL_FOCUS:
|
||||
damage( FL_DAMAGE_USER1 );
|
||||
return Fl_Group::handle( m ) || 1;
|
||||
case FL_UNFOCUS:
|
||||
damage( FL_DAMAGE_USER1 );
|
||||
return Fl_Group::handle( m ) || 1;
|
||||
}
|
||||
|
||||
return Fl_Group::handle( m );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -133,6 +133,7 @@ Module::init ( void )
|
|||
|
||||
box( FL_UP_BOX );
|
||||
labeltype( FL_NO_LABEL );
|
||||
align( FL_ALIGN_CENTER | FL_ALIGN_INSIDE );
|
||||
set_visible_focus();
|
||||
selection_color( FL_RED );
|
||||
color( fl_color_average( FL_WHITE, FL_CYAN, 0.40 ) );
|
||||
|
@ -599,7 +600,7 @@ Module::draw_label ( int tx, int ty, int tw, int th )
|
|||
|
||||
}
|
||||
|
||||
fl_draw( s ? s : lp, tx, ty, tw, th, (Fl_Align)(FL_ALIGN_CENTER | FL_ALIGN_INSIDE | FL_ALIGN_CLIP ) );
|
||||
fl_draw( s ? s : lp, tx, ty, tw, th, align() | FL_ALIGN_CLIP );
|
||||
|
||||
if ( s )
|
||||
delete[] s;
|
||||
|
@ -777,13 +778,15 @@ Module::handle_chain_name_changed ( )
|
|||
int
|
||||
Module::handle ( int m )
|
||||
{
|
||||
static int _button = 0;
|
||||
|
||||
if ( Fl_Group::handle( m ) )
|
||||
return 1;
|
||||
|
||||
switch ( m )
|
||||
{
|
||||
case FL_KEYBOARD:
|
||||
{
|
||||
if ( Fl_Group::handle( m ) )
|
||||
return 1;
|
||||
|
||||
if ( Fl::event_key() == FL_Menu )
|
||||
{
|
||||
menu_popup( &menu(), x(), y() );
|
||||
|
@ -793,27 +796,34 @@ Module::handle ( int m )
|
|||
return menu().test_shortcut() != 0;
|
||||
}
|
||||
case FL_PUSH:
|
||||
{
|
||||
take_focus();
|
||||
|
||||
if ( Fl_Group::handle( m ) )
|
||||
_button = Fl::event_button();
|
||||
return 1;
|
||||
else if ( test_press( FL_BUTTON3 ) )
|
||||
// if ( Fl::visible_focus() && handle( FL_FOCUS )) Fl::focus(this);
|
||||
case FL_DRAG:
|
||||
_button = Fl::event_button();
|
||||
return 1;
|
||||
case FL_RELEASE:
|
||||
{
|
||||
int b = _button;
|
||||
_button = 0;
|
||||
DMESSAGE( "Button %i", b);
|
||||
if ( 3 == b )
|
||||
{
|
||||
menu_popup( &menu() );
|
||||
return 1;
|
||||
}
|
||||
else if ( test_press( FL_BUTTON1 ) )
|
||||
else if ( 1 == b )
|
||||
{
|
||||
command_open_parameter_editor();
|
||||
return 1;
|
||||
}
|
||||
else if ( test_press( FL_BUTTON3 | FL_CTRL ) )
|
||||
else if ( 3 == b && Fl::event_ctrl() )
|
||||
{
|
||||
command_remove();
|
||||
return 1;
|
||||
}
|
||||
else if ( test_press( FL_BUTTON2 ) )
|
||||
else if ( 2 == b )
|
||||
{
|
||||
if ( !bypassable() )
|
||||
{
|
||||
|
@ -826,6 +836,10 @@ Module::handle ( int m )
|
|||
}
|
||||
return 1;
|
||||
}
|
||||
/* else */
|
||||
/* { */
|
||||
/* take_focus(); */
|
||||
/* } */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -835,7 +849,7 @@ Module::handle ( int m )
|
|||
return 1;
|
||||
}
|
||||
|
||||
return Fl_Group::handle( m );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -295,6 +295,7 @@ main ( int argc, char **argv )
|
|||
}
|
||||
|
||||
Fl::add_timeout( 0.1f, check_sigterm );
|
||||
Fl::dnd_text_ops( 0 );
|
||||
|
||||
if ( ! no_ui )
|
||||
{
|
||||
|
|
|
@ -108,7 +108,11 @@ namespace JACK
|
|||
((Client*)arg)->shutdown();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Client::port_connect ( jack_port_id_t a, jack_port_id_t b, int connect, void *arg )
|
||||
{
|
||||
((Client*)arg)->port_connect( a, b, connect );
|
||||
}
|
||||
|
||||
/** Connect to JACK using client name /client_name/. Return a static
|
||||
* pointer to actual name as reported by JACK */
|
||||
|
@ -125,6 +129,7 @@ namespace JACK
|
|||
set_callback( xrun );
|
||||
set_callback( freewheel );
|
||||
set_callback( buffer_size );
|
||||
set_callback( port_connect );
|
||||
|
||||
/* FIXME: should we wait to register this until after the project
|
||||
has been loaded (and we have disk threads running)? */
|
||||
|
|
|
@ -40,6 +40,8 @@ namespace JACK
|
|||
volatile bool _freewheeling;
|
||||
volatile bool _zombified;
|
||||
|
||||
static void port_connect ( jack_port_id_t a, jack_port_id_t b, int connect, void *arg );
|
||||
virtual void port_connect ( jack_port_id_t a, jack_port_id_t b, int connect ) { }
|
||||
static void shutdown ( void *arg );
|
||||
virtual void shutdown ( void ) = 0;
|
||||
static int process ( nframes_t nframes, void *arg );
|
||||
|
|
|
@ -298,6 +298,42 @@ namespace JACK
|
|||
return true;
|
||||
}
|
||||
|
||||
int
|
||||
Port::connect ( const char *to )
|
||||
{
|
||||
const char *name = jack_port_name( _port );
|
||||
|
||||
if ( _direction == Output )
|
||||
{
|
||||
return jack_connect( _client->jack_client(), name, to );
|
||||
}
|
||||
else
|
||||
{
|
||||
return jack_connect( _client->jack_client(), to, name );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
Port::disconnect ( const char *from )
|
||||
{
|
||||
const char *name = jack_port_name( _port );
|
||||
|
||||
if ( _direction == Output )
|
||||
{
|
||||
return jack_disconnect( _client->jack_client(), name, from );
|
||||
}
|
||||
else
|
||||
{
|
||||
return jack_disconnect( _client->jack_client(), from, name );
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
Port::connected_to ( const char *to )
|
||||
{
|
||||
return jack_port_connected_to( _port, to );
|
||||
}
|
||||
|
||||
void
|
||||
Port::freeze ( void )
|
||||
|
|
|
@ -74,6 +74,9 @@ namespace JACK
|
|||
void *buffer ( nframes_t nframes );
|
||||
void silence ( nframes_t nframes );
|
||||
|
||||
int connect ( const char *to );
|
||||
int disconnect ( const char *from );
|
||||
bool connected_to ( const char *to );
|
||||
/* */
|
||||
const char ** connections ( void );
|
||||
bool connections ( const char **port_names );
|
||||
|
|
|
@ -253,6 +253,8 @@ Audio_Sequence::handle ( int m )
|
|||
{
|
||||
case FL_PASTE:
|
||||
{
|
||||
if ( ! Fl::event_inside( this ) )
|
||||
return 0;
|
||||
const char *text = Fl::event_text();
|
||||
|
||||
if ( ! strcmp( text, "Audio_Region" ) )
|
||||
|
@ -262,7 +264,7 @@ Audio_Sequence::handle ( int m )
|
|||
|
||||
if ( ! sscanf( text, "file://%a[^\r\n]\n", &file ) )
|
||||
{
|
||||
printf( "invalid drop \"%s\"\n", text );
|
||||
WARNING( "invalid drop \"%s\"\n", text );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -43,7 +43,6 @@ protected:
|
|||
void handle_widget_change ( nframes_t start, nframes_t length );
|
||||
|
||||
void draw ( void );
|
||||
int handle ( int m );
|
||||
|
||||
static void cb_button ( Fl_Widget *w, void *v );
|
||||
void cb_button ( Fl_Widget *w );
|
||||
|
@ -52,6 +51,8 @@ protected:
|
|||
|
||||
public:
|
||||
|
||||
int handle ( int m );
|
||||
|
||||
LOG_CREATE_FUNC( Audio_Sequence );
|
||||
|
||||
Audio_Sequence_Header * header ( void ) { return (Audio_Sequence_Header*)child(0); }
|
||||
|
|
|
@ -389,8 +389,6 @@ Sequence::handle ( int m )
|
|||
fl_cursor( FL_CURSOR_DEFAULT );
|
||||
Fl_Group::handle( m );
|
||||
return 1;
|
||||
case FL_DND_DRAG:
|
||||
return 1;
|
||||
case FL_ENTER:
|
||||
// DMESSAGE( "enter" );
|
||||
if ( Fl::event_x() >= drawable_x() )
|
||||
|
@ -424,10 +422,14 @@ Sequence::handle ( int m )
|
|||
{
|
||||
return Fl_Group::handle(m);
|
||||
}
|
||||
case FL_DND_DRAG:
|
||||
case FL_DND_ENTER:
|
||||
case FL_DND_LEAVE:
|
||||
case FL_DND_RELEASE:
|
||||
if ( Fl::event_x() >= drawable_x() )
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
case FL_MOVE:
|
||||
{
|
||||
if ( Fl::event_x() >= drawable_x() )
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
#include <FL/Fl_Menu_Button.H>
|
||||
#include "FL/menu_popup.H"
|
||||
|
||||
extern char *instance_name;
|
||||
|
||||
|
||||
|
||||
|
@ -997,6 +998,8 @@ Track::menu ( void ) const
|
|||
#include "FL/event_name.H"
|
||||
#include "FL/test_press.H"
|
||||
|
||||
static Fl_Widget *receptive_to_drop = NULL;
|
||||
|
||||
void
|
||||
Track::draw ( void )
|
||||
{
|
||||
|
@ -1020,6 +1023,12 @@ Track::draw ( void )
|
|||
else
|
||||
Fl_Group::draw();
|
||||
|
||||
if ( ((Track_Header*)child(0))->input_connector_handle == receptive_to_drop )
|
||||
{
|
||||
Fl_Widget *o = ((Track_Header*)child(0))->input_connector_handle;
|
||||
fl_draw_box( FL_OVAL_BOX, o->x(), o->y(), o->w(), o->h(), fl_color_add_alpha( FL_GREEN, 127 ) );
|
||||
}
|
||||
|
||||
if ( ! Track::colored_tracks )
|
||||
color( saved_color );
|
||||
|
||||
|
@ -1033,6 +1042,19 @@ Track::handle ( int m )
|
|||
/* if ( m != FL_NO_EVENT ) */
|
||||
/* DMESSAGE( "%s", event_name( m ) ); */
|
||||
|
||||
switch ( m )
|
||||
{
|
||||
case FL_DND_ENTER:
|
||||
case FL_DND_LEAVE:
|
||||
case FL_DND_DRAG:
|
||||
case FL_DND_RELEASE:
|
||||
case FL_PASTE:
|
||||
if ( Fl::event_x() > Track::width() )
|
||||
return sequence()->handle(m);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch ( m )
|
||||
{
|
||||
case FL_KEYBOARD:
|
||||
|
@ -1065,6 +1087,9 @@ Track::handle ( int m )
|
|||
}
|
||||
case FL_PUSH:
|
||||
{
|
||||
if ( Fl::event_inside( ((Track_Header*)child(0))->output_connector_handle ) )
|
||||
return 1;
|
||||
|
||||
Logger log( this );
|
||||
|
||||
if ( Fl_Group::handle( m ) )
|
||||
|
@ -1078,6 +1103,140 @@ Track::handle ( int m )
|
|||
|
||||
return 0;
|
||||
}
|
||||
/* we have to prevent Fl_Group::handle() from getting these, otherwise it will mess up Fl::belowmouse() */
|
||||
case FL_ENTER:
|
||||
case FL_LEAVE:
|
||||
case FL_MOVE:
|
||||
if ( Fl::event_x() >= Track::width() )
|
||||
{
|
||||
return sequence()->handle(m);
|
||||
}
|
||||
return 0;
|
||||
case FL_DND_ENTER:
|
||||
return 1;
|
||||
case FL_DND_LEAVE:
|
||||
|
||||
if ( ! Fl::event_inside(this) && this == receptive_to_drop )
|
||||
{
|
||||
receptive_to_drop = 0;
|
||||
redraw();
|
||||
Fl::selection_owner(0);
|
||||
}
|
||||
return 1;
|
||||
case FL_DND_RELEASE:
|
||||
receptive_to_drop = 0;
|
||||
redraw();
|
||||
Fl::selection_owner(0);
|
||||
return 1;
|
||||
case FL_DND_DRAG:
|
||||
{
|
||||
|
||||
if ( receptive_to_drop == ((Track_Header*)child(0))->input_connector_handle )
|
||||
return 1;
|
||||
|
||||
|
||||
|
||||
if ( Fl::event_inside( ((Track_Header*)child(0))->input_connector_handle )
|
||||
&& receptive_to_drop != ((Track_Header*)child(0))->input_connector_handle )
|
||||
|
||||
{
|
||||
receptive_to_drop = ((Track_Header*)child(0))->input_connector_handle;
|
||||
redraw();
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
receptive_to_drop = NULL;
|
||||
redraw();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
case FL_PASTE:
|
||||
{
|
||||
receptive_to_drop = 0;
|
||||
redraw();
|
||||
|
||||
if (! Fl::event_inside( ((Track_Header*)child(0))->input_connector_handle ) )
|
||||
return 0;
|
||||
|
||||
/* NOW we get the text... */
|
||||
const char *text = Fl::event_text();
|
||||
|
||||
DMESSAGE( "Got drop text \"%s\"",text);
|
||||
|
||||
if ( strncmp( text, "jack.port://", strlen( "jack.port://" ) ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::vector<std::string> port_names;
|
||||
|
||||
char *port_name;
|
||||
int end;
|
||||
while ( sscanf( text, "jack.port://%a[^\r\n]\r\n%n", &port_name, &end ) > 0 )
|
||||
{
|
||||
DMESSAGE( "Scanning %s", port_name );
|
||||
port_names.push_back( port_name );
|
||||
free(port_name );
|
||||
|
||||
text += end;
|
||||
}
|
||||
|
||||
for ( unsigned int i = 0; i < input.size() && i < port_names.size(); i++)
|
||||
{
|
||||
const char *pn = port_names[i].c_str();
|
||||
|
||||
JACK::Port *ji = &input[i];
|
||||
|
||||
if ( ji->connected_to( pn ) )
|
||||
{
|
||||
|
||||
DMESSAGE( "Disconnecting from \"%s\"", pn );
|
||||
ji->disconnect( pn );
|
||||
}
|
||||
else
|
||||
{
|
||||
DMESSAGE( "Connecting to %s", pn );
|
||||
ji->connect( pn );
|
||||
}
|
||||
}
|
||||
|
||||
Fl::selection_owner(0);
|
||||
|
||||
return 1;
|
||||
}
|
||||
case FL_DRAG:
|
||||
{
|
||||
if ( this != Fl::selection_owner() &&
|
||||
Fl::event_inside( ((Track_Header*)child(0))->output_connector_handle ) )
|
||||
{
|
||||
char *s = (char*)malloc(256);
|
||||
s[0] = 0;
|
||||
|
||||
for ( unsigned int i = 0; i < output.size(); ++i )
|
||||
{
|
||||
char *s2;
|
||||
asprintf(&s2, "jack.port://%s:%s\r\n", instance_name, output[i].name() );
|
||||
|
||||
s = (char*)realloc( s, strlen( s ) + strlen( s2 ) + 1 );
|
||||
strcat( s, s2 );
|
||||
|
||||
free( s2 );
|
||||
}
|
||||
|
||||
Fl::copy(s, strlen(s) + 1, 0);
|
||||
Fl::selection_owner(this);
|
||||
|
||||
free( s );
|
||||
|
||||
Fl::dnd();
|
||||
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
|
||||
}
|
||||
default:
|
||||
return Fl_Group::handle( m );
|
||||
}
|
||||
|
|
|
@ -8,20 +8,35 @@ decl {\#include "FL/Fl_Sometimes_Input.H"} {public global
|
|||
decl {\#include "FL/Fl_Blink_Button.H"} {public global
|
||||
}
|
||||
|
||||
decl {\#include <FL/Fl_PNG_Image.H>} {private local
|
||||
}
|
||||
|
||||
decl {\#include <FL/img_io_input_connector_10x10_png.h>} {private local
|
||||
}
|
||||
|
||||
decl {\#include <FL/img_io_output_connector_10x10_png.h>} {private local
|
||||
}
|
||||
|
||||
decl {Fl_PNG_Image *output_connector_image = NULL;} {private local
|
||||
}
|
||||
|
||||
decl {Fl_PNG_Image *input_connector_image = NULL;} {private local
|
||||
}
|
||||
|
||||
widget_class Track_Header {open
|
||||
xywh {897 224 525 60} type Double box NO_BOX resizable visible
|
||||
xywh {680 695 525 60} type Double box NO_BOX resizable visible
|
||||
} {
|
||||
Fl_Group box_group {open
|
||||
private xywh {0 0 200 60} box THIN_UP_BOX color 63
|
||||
code0 {o->resizable(0);}
|
||||
} {
|
||||
Fl_Group {} {open
|
||||
xywh {0 0 200 51}
|
||||
xywh {0 0 200 55}
|
||||
code0 {o->resizable(0);}
|
||||
} {
|
||||
Fl_Input name_input {
|
||||
label {input:}
|
||||
xywh {0 2 200 23} labeltype NO_LABEL align 20 when 8
|
||||
xywh {4 2 151 22} labeltype NO_LABEL align 20 when 8
|
||||
class Fl_Sometimes_Input
|
||||
}
|
||||
Fl_Button track_inputs_indicator {
|
||||
|
@ -56,6 +71,16 @@ widget_class Track_Header {open
|
|||
label s
|
||||
tooltip solo xywh {172 26 24 24} type Toggle selection_color 91 labelfont 5 labelsize 12
|
||||
}
|
||||
Fl_Box input_connector_handle {
|
||||
tooltip {Drag and drop this input connector to make or break JACK connections} xywh {157 4 18 18} box FLAT_BOX
|
||||
code0 {o->image( input_connector_image ? input_connector_image : input_connector_image = new Fl_PNG_Image( "input-connector", img_io_input_connector_10x10_png, img_io_input_connector_10x10_png_len ) );}
|
||||
code1 {o->box(FL_NO_BOX);}
|
||||
}
|
||||
Fl_Box output_connector_handle {selected
|
||||
tooltip {Drag and drop this output connector to make or break JACK connections} xywh {177 4 18 18} box FLAT_BOX
|
||||
code0 {o->image( output_connector_image ? output_connector_image : output_connector_image = new Fl_PNG_Image( "output-connector", img_io_output_connector_10x10_png, img_io_output_connector_10x10_png_len ) );}
|
||||
code1 {o->box(FL_NO_BOX);}
|
||||
}
|
||||
}
|
||||
}
|
||||
Fl_Box {} {
|
||||
|
@ -72,7 +97,7 @@ Fl_Group::draw();} {}
|
|||
}
|
||||
|
||||
widget_class Control_Sequence_Header {open
|
||||
xywh {315 771 200 55} type Double box NO_BOX visible
|
||||
xywh {325 886 200 55} type Double box NO_BOX visible
|
||||
} {
|
||||
Fl_Input name_input {
|
||||
label {input:}
|
||||
|
@ -80,7 +105,7 @@ widget_class Control_Sequence_Header {open
|
|||
class Fl_Sometimes_Input
|
||||
}
|
||||
Fl_Button menu_button {
|
||||
label menu selected
|
||||
label menu
|
||||
tooltip {Expand controls} xywh {5 26 31 24} selection_color 3 labelfont 4 labelsize 10
|
||||
}
|
||||
Fl_Button outputs_indicator {
|
||||
|
@ -103,7 +128,7 @@ widget_class Control_Sequence_Header {open
|
|||
}
|
||||
|
||||
widget_class Audio_Sequence_Header {open
|
||||
xywh {332 613 200 50} type Double box NO_BOX resizable visible
|
||||
xywh {404 670 200 50} type Double box NO_BOX resizable visible
|
||||
} {
|
||||
Fl_Group {} {open
|
||||
xywh {0 0 200 55}
|
||||
|
|
Loading…
Reference in New Issue