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)
|
||||
, splash_start (0)
|
||||
, bank_start (0)
|
||||
, connection_state (ConnectionState (0))
|
||||
, gui (0)
|
||||
{
|
||||
context = Cairo::Context::create (frame_buffer);
|
||||
tc_clock_layout = Pango::Layout::create (context);
|
||||
@ -100,6 +102,14 @@ Push2::Push2 (ARDOUR::Session& s)
|
||||
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 ()
|
||||
@ -107,6 +117,34 @@ Push2::~Push2 ()
|
||||
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
|
||||
Push2::open ()
|
||||
{
|
||||
@ -1478,3 +1516,67 @@ Push2::pad_filter (MidiBuffer& in, MidiBuffer& out) const
|
||||
|
||||
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 void* request_factory (uint32_t);
|
||||
|
||||
bool has_editor () const { return true; }
|
||||
void* get_gui () const;
|
||||
void tear_down_gui ();
|
||||
|
||||
int set_active (bool yn);
|
||||
XMLNode& get_state();
|
||||
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:
|
||||
libusb_device_handle *handle;
|
||||
uint8_t frame_header[16];
|
||||
@ -452,6 +461,24 @@ class Push2 : public ARDOUR::ControlProtocol
|
||||
bool pad_filter (ARDOUR::MidiBuffer& in, ARDOUR::MidiBuffer& out) const;
|
||||
|
||||
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
|
||||
midi_byte_array.cc
|
||||
leds.cc
|
||||
gui.cc
|
||||
'''
|
||||
obj.export_includes = ['.']
|
||||
obj.defines = [ 'PACKAGE="ardour_push2"' ]
|
||||
@ -33,8 +34,8 @@ def build(bld):
|
||||
obj.includes = [ '.', './push2']
|
||||
obj.name = 'libardour_push2'
|
||||
obj.target = 'ardour_push2'
|
||||
obj.uselib = 'CAIROMM PANGOMM USB'
|
||||
obj.use = 'libardour libardour_cp libpbd libtimecode'
|
||||
obj.uselib = 'CAIROMM PANGOMM USB GTKMM'
|
||||
obj.use = 'libardour libardour_cp libgtkmm2ext libpbd libtimecode'
|
||||
obj.install_path = os.path.join(bld.env['LIBDIR'], 'surfaces')
|
||||
|
||||
def shutdown():
|
||||
|
Loading…
Reference in New Issue
Block a user