push2: basic GUI dialog
This commit is contained in:
parent
6dbe3a1e3b
commit
cf28d71783
BIN
gtk2_ardour/icons/push2-small.png
Normal file
BIN
gtk2_ardour/icons/push2-small.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 40 KiB |
@ -69,6 +69,8 @@ Push2::Push2 (ARDOUR::Session& s)
|
|||||||
, modifier_state (None)
|
, modifier_state (None)
|
||||||
, splash_start (0)
|
, splash_start (0)
|
||||||
, bank_start (0)
|
, bank_start (0)
|
||||||
|
, connection_state (ConnectionState (0))
|
||||||
|
, gui (0)
|
||||||
{
|
{
|
||||||
context = Cairo::Context::create (frame_buffer);
|
context = Cairo::Context::create (frame_buffer);
|
||||||
tc_clock_layout = Pango::Layout::create (context);
|
tc_clock_layout = Pango::Layout::create (context);
|
||||||
@ -100,6 +102,14 @@ Push2::Push2 (ARDOUR::Session& s)
|
|||||||
throw failed_constructor ();
|
throw failed_constructor ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ARDOUR::AudioEngine::instance()->PortRegisteredOrUnregistered.connect (port_reg_connection, MISSING_INVALIDATOR, boost::bind (&Push2::port_registration_handler, this), this);
|
||||||
|
|
||||||
|
/* Catch port connections and disconnections */
|
||||||
|
ARDOUR::AudioEngine::instance()->PortConnectedOrDisconnected.connect (port_connection, MISSING_INVALIDATOR, boost::bind (&Push2::connection_handler, this, _1, _2, _3, _4, _5), this);
|
||||||
|
|
||||||
|
/* ports might already be there */
|
||||||
|
|
||||||
|
port_registration_handler ();
|
||||||
}
|
}
|
||||||
|
|
||||||
Push2::~Push2 ()
|
Push2::~Push2 ()
|
||||||
@ -107,6 +117,34 @@ Push2::~Push2 ()
|
|||||||
stop ();
|
stop ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Push2::port_registration_handler ()
|
||||||
|
{
|
||||||
|
if (_async_in->connected() && _async_out->connected()) {
|
||||||
|
/* don't waste cycles here */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string input_port_name = X_("Ableton Push 2 MIDI 1 in");
|
||||||
|
string output_port_name = X_("Ableton Push 2 MIDI 1 out");
|
||||||
|
vector<string> in;
|
||||||
|
vector<string> out;
|
||||||
|
|
||||||
|
AudioEngine::instance()->get_ports (string_compose (".*%1", input_port_name), DataType::MIDI, PortFlags (IsPhysical|IsOutput), in);
|
||||||
|
AudioEngine::instance()->get_ports (string_compose (".*%1", output_port_name), DataType::MIDI, PortFlags (IsPhysical|IsInput), out);
|
||||||
|
|
||||||
|
if (!in.empty() && !out.empty()) {
|
||||||
|
cerr << "Push2: both ports found\n";
|
||||||
|
cerr << "\tconnecting to " << in.front() << " + " << out.front() << endl;
|
||||||
|
if (!_async_in->connected()) {
|
||||||
|
AudioEngine::instance()->connect (_async_in->name(), in.front());
|
||||||
|
}
|
||||||
|
if (!_async_out->connected()) {
|
||||||
|
AudioEngine::instance()->connect (_async_out->name(), out.front());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
Push2::open ()
|
Push2::open ()
|
||||||
{
|
{
|
||||||
@ -1478,3 +1516,67 @@ Push2::pad_filter (MidiBuffer& in, MidiBuffer& out) const
|
|||||||
|
|
||||||
return matched;
|
return matched;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Push2::connection_handler (boost::weak_ptr<ARDOUR::Port>, std::string name1, boost::weak_ptr<ARDOUR::Port>, std::string name2, bool yn)
|
||||||
|
{
|
||||||
|
DEBUG_TRACE (DEBUG::FaderPort, "FaderPort::connection_handler start\n");
|
||||||
|
if (!_input_port || !_output_port) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
string ni = ARDOUR::AudioEngine::instance()->make_port_name_non_relative (boost::shared_ptr<ARDOUR::Port>(_async_in)->name());
|
||||||
|
string no = ARDOUR::AudioEngine::instance()->make_port_name_non_relative (boost::shared_ptr<ARDOUR::Port>(_async_out)->name());
|
||||||
|
|
||||||
|
if (ni == name1 || ni == name2) {
|
||||||
|
if (yn) {
|
||||||
|
connection_state |= InputConnected;
|
||||||
|
} else {
|
||||||
|
connection_state &= ~InputConnected;
|
||||||
|
}
|
||||||
|
} else if (no == name1 || no == name2) {
|
||||||
|
if (yn) {
|
||||||
|
connection_state |= OutputConnected;
|
||||||
|
} else {
|
||||||
|
connection_state &= ~OutputConnected;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
DEBUG_TRACE (DEBUG::FaderPort, string_compose ("Connections between %1 and %2 changed, but I ignored it\n", name1, name2));
|
||||||
|
/* not our ports */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((connection_state & (InputConnected|OutputConnected)) == (InputConnected|OutputConnected)) {
|
||||||
|
|
||||||
|
/* XXX this is a horrible hack. Without a short sleep here,
|
||||||
|
something prevents the device wakeup messages from being
|
||||||
|
sent and/or the responses from being received.
|
||||||
|
*/
|
||||||
|
|
||||||
|
g_usleep (100000);
|
||||||
|
DEBUG_TRACE (DEBUG::FaderPort, "device now connected for both input and output\n");
|
||||||
|
// connected ();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
DEBUG_TRACE (DEBUG::FaderPort, "Device disconnected (input or output or both) or not yet fully connected\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
ConnectionChange (); /* emit signal for our GUI */
|
||||||
|
|
||||||
|
DEBUG_TRACE (DEBUG::FaderPort, "FaderPort::connection_handler end\n");
|
||||||
|
|
||||||
|
return true; /* connection status changed */
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::shared_ptr<Port>
|
||||||
|
Push2::output_port()
|
||||||
|
{
|
||||||
|
return _async_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::shared_ptr<Port>
|
||||||
|
Push2::input_port()
|
||||||
|
{
|
||||||
|
return _async_in;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -74,10 +74,19 @@ class Push2 : public ARDOUR::ControlProtocol
|
|||||||
static bool probe ();
|
static bool probe ();
|
||||||
static void* request_factory (uint32_t);
|
static void* request_factory (uint32_t);
|
||||||
|
|
||||||
|
bool has_editor () const { return true; }
|
||||||
|
void* get_gui () const;
|
||||||
|
void tear_down_gui ();
|
||||||
|
|
||||||
int set_active (bool yn);
|
int set_active (bool yn);
|
||||||
XMLNode& get_state();
|
XMLNode& get_state();
|
||||||
int set_state (const XMLNode & node, int version);
|
int set_state (const XMLNode & node, int version);
|
||||||
|
|
||||||
|
PBD::Signal0<void> ConnectionChange;
|
||||||
|
|
||||||
|
boost::shared_ptr<ARDOUR::Port> input_port();
|
||||||
|
boost::shared_ptr<ARDOUR::Port> output_port();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
libusb_device_handle *handle;
|
libusb_device_handle *handle;
|
||||||
uint8_t frame_header[16];
|
uint8_t frame_header[16];
|
||||||
@ -452,6 +461,24 @@ class Push2 : public ARDOUR::ControlProtocol
|
|||||||
bool pad_filter (ARDOUR::MidiBuffer& in, ARDOUR::MidiBuffer& out) const;
|
bool pad_filter (ARDOUR::MidiBuffer& in, ARDOUR::MidiBuffer& out) const;
|
||||||
|
|
||||||
boost::weak_ptr<ARDOUR::Stripable> first_selected_stripable;
|
boost::weak_ptr<ARDOUR::Stripable> first_selected_stripable;
|
||||||
|
|
||||||
|
PBD::ScopedConnection port_reg_connection;
|
||||||
|
void port_registration_handler ();
|
||||||
|
|
||||||
|
enum ConnectionState {
|
||||||
|
InputConnected = 0x1,
|
||||||
|
OutputConnected = 0x2
|
||||||
|
};
|
||||||
|
|
||||||
|
int connection_state;
|
||||||
|
bool connection_handler (boost::weak_ptr<ARDOUR::Port>, std::string name1, boost::weak_ptr<ARDOUR::Port>, std::string name2, bool yn);
|
||||||
|
PBD::ScopedConnection port_connection;
|
||||||
|
|
||||||
|
/* GUI */
|
||||||
|
|
||||||
|
mutable void *gui;
|
||||||
|
void build_gui ();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@ def build(bld):
|
|||||||
interface.cc
|
interface.cc
|
||||||
midi_byte_array.cc
|
midi_byte_array.cc
|
||||||
leds.cc
|
leds.cc
|
||||||
|
gui.cc
|
||||||
'''
|
'''
|
||||||
obj.export_includes = ['.']
|
obj.export_includes = ['.']
|
||||||
obj.defines = [ 'PACKAGE="ardour_push2"' ]
|
obj.defines = [ 'PACKAGE="ardour_push2"' ]
|
||||||
@ -33,8 +34,8 @@ def build(bld):
|
|||||||
obj.includes = [ '.', './push2']
|
obj.includes = [ '.', './push2']
|
||||||
obj.name = 'libardour_push2'
|
obj.name = 'libardour_push2'
|
||||||
obj.target = 'ardour_push2'
|
obj.target = 'ardour_push2'
|
||||||
obj.uselib = 'CAIROMM PANGOMM USB'
|
obj.uselib = 'CAIROMM PANGOMM USB GTKMM'
|
||||||
obj.use = 'libardour libardour_cp libpbd libtimecode'
|
obj.use = 'libardour libardour_cp libgtkmm2ext libpbd libtimecode'
|
||||||
obj.install_path = os.path.join(bld.env['LIBDIR'], 'surfaces')
|
obj.install_path = os.path.join(bld.env['LIBDIR'], 'surfaces')
|
||||||
|
|
||||||
def shutdown():
|
def shutdown():
|
||||||
|
Loading…
Reference in New Issue
Block a user