13
0

Refactor PC Dialog/Window -- non-modal tabbed dialog

This commit is contained in:
Robin Gareus 2022-02-09 18:59:15 +01:00
parent eb674d3b58
commit a4fd29fa7d
Signed by: rgareus
GPG Key ID: A090BCE02CF57F04
2 changed files with 127 additions and 86 deletions

View File

@ -46,12 +46,10 @@
using namespace Gtk; using namespace Gtk;
using namespace ARDOUR; using namespace ARDOUR;
PatchBankList::PatchBankList (boost::shared_ptr<ARDOUR::Route> r) PatchBankList::PatchBankList ()
: _route (r) : _bank_msb_spin (*manage (new Adjustment (0, 0, 127, 1, 16)))
, _bank_msb_spin (*manage (new Adjustment (0, 0, 127, 1, 16)))
, _bank_lsb_spin (*manage (new Adjustment (0, 0, 127, 1, 16))) , _bank_lsb_spin (*manage (new Adjustment (0, 0, 127, 1, 16)))
, _program_table (/*rows*/ 16, /*cols*/ 8, true) , _program_table (/*rows*/ 16, /*cols*/ 8, true)
, _info (r->instrument_info ())
, _ignore_spin_btn_signals (false) , _ignore_spin_btn_signals (false)
{ {
_program_table.set_spacings (1); _program_table.set_spacings (1);
@ -67,14 +65,6 @@ PatchBankList::PatchBankList (boost::shared_ptr<ARDOUR::Route> r)
_bank_msb_spin.signal_changed ().connect (sigc::mem_fun (*this, &PatchBankList::select_bank_spin)); _bank_msb_spin.signal_changed ().connect (sigc::mem_fun (*this, &PatchBankList::select_bank_spin));
_bank_lsb_spin.signal_changed ().connect (sigc::mem_fun (*this, &PatchBankList::select_bank_spin)); _bank_lsb_spin.signal_changed ().connect (sigc::mem_fun (*this, &PatchBankList::select_bank_spin));
_info.Changed.connect (_info_changed_connection, invalidator (*this),
boost::bind (&PatchBankList::instrument_info_changed, this), gui_context ());
if (!boost::dynamic_pointer_cast<MidiTrack> (_route)) {
_route->processors_changed.connect (_route_connection, invalidator (*this),
boost::bind (&PatchBankList::processors_changed, this), gui_context ());
}
} }
PatchBankList::~PatchBankList () PatchBankList::~PatchBankList ()
@ -96,7 +86,7 @@ flip_map (std::map<A, B> const& src)
} }
void void
PatchBankList::refill (const uint8_t channel) PatchBankList::refill (boost::shared_ptr<MIDI::Name::ChannelNameSet> cns, int const b)
{ {
using namespace Menu_Helpers; using namespace Menu_Helpers;
using namespace Gtkmm2ext; using namespace Gtkmm2ext;
@ -105,8 +95,6 @@ PatchBankList::refill (const uint8_t channel)
_current_patch_bank.reset (); _current_patch_bank.reset ();
_bank_select.clear_items (); _bank_select.clear_items ();
const int b = bank (channel);
{ {
PBD::Unwinder<bool> uw (_ignore_spin_btn_signals, true); PBD::Unwinder<bool> uw (_ignore_spin_btn_signals, true);
_bank_msb_spin.set_value (b >> 7); _bank_msb_spin.set_value (b >> 7);
@ -122,7 +110,6 @@ PatchBankList::refill (const uint8_t channel)
unset_notes.set (); unset_notes.set ();
boost::shared_ptr<ChannelNameSet> cns = _info.get_patches (channel);
if (cns) { if (cns) {
const ChannelNameSet::PatchBanks& patch_banks = cns->patch_banks (); const ChannelNameSet::PatchBanks& patch_banks = cns->patch_banks ();
for (ChannelNameSet::PatchBanks::const_iterator bank = patch_banks.begin (); bank != patch_banks.end (); ++bank) { for (ChannelNameSet::PatchBanks::const_iterator bank = patch_banks.begin (); bank != patch_banks.end (); ++bank) {
@ -251,21 +238,12 @@ PatchBankList::set_active_pgm (uint8_t p)
/* ****************************************************************************/ /* ****************************************************************************/
PatchChangeTab::PatchChangeTab (boost::shared_ptr<Route> r, boost::shared_ptr<MIDITrigger> t, int channel) PatchChangeTab::PatchChangeTab (int channel)
: PatchBankList (r) : _enable_btn (_("Override Patch Changes"), ArdourWidgets::ArdourButton::led_default_elements)
, _enable_btn (_("Override Patch Changes"), ArdourWidgets::ArdourButton::led_default_elements)
, _channel (channel) , _channel (channel)
, _bank (0) , _bank (0)
, _ignore_callback (false) , _ignore_callback (false)
, _trigger (t)
{ {
if (_trigger->patch_change_set (_channel)) {
_bank = _trigger->patch_change (_channel).bank ();
_enable_btn.set_active (true);
} else {
_enable_btn.set_active (false);
}
Box* box; Box* box;
box = manage (new HBox ()); box = manage (new HBox ());
box->set_border_width (2); box->set_border_width (2);
@ -288,18 +266,39 @@ PatchChangeTab::PatchChangeTab (boost::shared_ptr<Route> r, boost::shared_ptr<MI
_enable_btn.signal_clicked.connect (sigc::mem_fun (*this, &PatchChangeTab::enable_toggle)); _enable_btn.signal_clicked.connect (sigc::mem_fun (*this, &PatchChangeTab::enable_toggle));
_trigger->PropertyChanged.connect (_trigger_connection, invalidator (*this), boost::bind (&PatchChangeTab::trigger_property_changed, this, _1), gui_context ()); reset (boost::shared_ptr<ARDOUR::Route> (), boost::shared_ptr<ARDOUR::MIDITrigger>());
if (!boost::dynamic_pointer_cast<MidiTrack> (_route)) { }
processors_changed ();
void
PatchChangeTab::reset (boost::shared_ptr<ARDOUR::Route> r, boost::shared_ptr<MIDITrigger> t)
{
_route = r;
_trigger = t;
_connections.drop_connections ();
if (!r || !t) {
_enable_btn.set_active (false);
refill_banks ();
return;
} }
if (_trigger->patch_change_set (_channel)) {
_bank = _trigger->patch_change (_channel).bank ();
_enable_btn.set_active (true);
} else {
_enable_btn.set_active (false);
}
_route->instrument_info().Changed.connect (_connections, invalidator (*this), boost::bind (&PatchChangeTab::instrument_info_changed, this), gui_context ());
_trigger->PropertyChanged.connect (_connections, invalidator (*this), boost::bind (&PatchChangeTab::trigger_property_changed, this, _1), gui_context ());
refill_banks (); refill_banks ();
update_sensitivity ();
} }
void void
PatchChangeTab::enable_toggle () PatchChangeTab::enable_toggle ()
{ {
if (_ignore_callback) { if (_ignore_callback || !_trigger) {
return; return;
} }
if (_enable_btn.get_active ()) { if (_enable_btn.get_active ()) {
@ -313,7 +312,8 @@ PatchChangeTab::enable_toggle ()
void void
PatchChangeTab::update_sensitivity () PatchChangeTab::update_sensitivity ()
{ {
bool en = _trigger->patch_change_set (_channel); bool en = _trigger ? _trigger->patch_change_set (_channel) : false;
_enable_btn.set_sensitive (_trigger ? true : false /* _trigger->region () ? true : false) : false */);
_program_table.set_sensitive (en); _program_table.set_sensitive (en);
_bank_select.set_sensitive (en); _bank_select.set_sensitive (en);
_bank_msb_spin.set_sensitive (en); _bank_msb_spin.set_sensitive (en);
@ -340,7 +340,7 @@ PatchChangeTab::select_bank (uint32_t bank)
void void
PatchChangeTab::select_program (uint8_t pgm) PatchChangeTab::select_program (uint8_t pgm)
{ {
if (pgm > 127) { if (pgm > 127 || !_trigger) {
return; return;
} }
@ -357,15 +357,19 @@ PatchChangeTab::refresh ()
void void
PatchChangeTab::refill_banks () PatchChangeTab::refill_banks ()
{ {
refill (_channel); boost::shared_ptr<MIDI::Name::ChannelNameSet> cns;
if (_route) {
cns = _route->instrument_info ().get_patches (_channel);
}
update_sensitivity ();
refill (cns, bank ());
set_active_pgm (program ()); set_active_pgm (program ());
} }
int int
PatchChangeTab::bank (uint8_t c) const PatchChangeTab::bank () const
{ {
assert (c == _channel); if (_trigger && _trigger->patch_change_set (_channel)) {
if (_trigger->patch_change_set (_channel)) {
return _trigger->patch_change (_channel).bank (); return _trigger->patch_change (_channel).bank ();
} }
return _bank; return _bank;
@ -374,7 +378,7 @@ PatchChangeTab::bank (uint8_t c) const
uint8_t uint8_t
PatchChangeTab::program () const PatchChangeTab::program () const
{ {
if (_trigger->patch_change_set (_channel)) { if (_trigger && _trigger->patch_change_set (_channel)) {
return _trigger->patch_change (_channel).program (); return _trigger->patch_change (_channel).program ();
} }
return 0; return 0;
@ -386,15 +390,11 @@ PatchChangeTab::instrument_info_changed ()
refill_banks (); refill_banks ();
} }
void
PatchChangeTab::processors_changed ()
{
}
/* ****************************************************************************/ /* ****************************************************************************/
PatchChangeWidget::PatchChangeWidget (boost::shared_ptr<ARDOUR::Route> r) PatchChangeWidget::PatchChangeWidget (boost::shared_ptr<ARDOUR::Route> r)
: PatchBankList (r) : _route (r)
, _info (r->instrument_info ())
, _channel (-1) , _channel (-1)
, _no_notifications (false) , _no_notifications (false)
, _audition_enable (_("Audition on Change"), ArdourWidgets::ArdourButton::led_default_elements) , _audition_enable (_("Audition on Change"), ArdourWidgets::ArdourButton::led_default_elements)
@ -467,7 +467,12 @@ PatchChangeWidget::PatchChangeWidget (boost::shared_ptr<ARDOUR::Route> r)
if (!boost::dynamic_pointer_cast<MidiTrack> (_route)) { if (!boost::dynamic_pointer_cast<MidiTrack> (_route)) {
processors_changed (); processors_changed ();
_route->processors_changed.connect (_route_connections, invalidator (*this),
boost::bind (&PatchChangeWidget::processors_changed, this), gui_context ());
} }
_info.Changed.connect (_route_connections, invalidator (*this),
boost::bind (&PatchChangeWidget::instrument_info_changed, this), gui_context ());
} }
PatchChangeWidget::~PatchChangeWidget () PatchChangeWidget::~PatchChangeWidget ()
@ -546,7 +551,9 @@ void
PatchChangeWidget::refill_banks () PatchChangeWidget::refill_banks ()
{ {
cancel_audition (); cancel_audition ();
refill (_channel);
boost::shared_ptr<MIDI::Name::ChannelNameSet> cns = _info.get_patches (_channel);
refill (cns, bank (_channel));
program_changed (); program_changed ();
} }
@ -804,23 +811,53 @@ PatchChangeWidget::program (uint8_t chn) const
/* ***************************************************************************/ /* ***************************************************************************/
PatchChangeTriggerDialog::PatchChangeTriggerDialog (boost::shared_ptr<Route> r, boost::shared_ptr<MIDITrigger> t) PatchChangeTriggerWindow::PatchChangeTriggerWindow ()
: ArdourDialog (string_compose (_("Select Patch for \"%1\""), t->name ()), false, false) : ArdourWindow (_("Trigger Patch Select"))
{ {
for (uint32_t chn = 0; chn < 16; ++chn) { for (uint32_t chn = 0; chn < 16; ++chn) {
_w[chn] = manage (new PatchChangeTab (r, t, chn)); _w[chn] = manage (new PatchChangeTab (chn));
_notebook.append_page (*_w[chn], string_compose (_("Chn %1"), chn + 1)); _notebook.append_page (*_w[chn], string_compose (_("Chn %1"), chn + 1));
} }
_notebook.signal_switch_page ().connect (sigc::mem_fun (*this, &PatchChangeTriggerDialog::on_switch_page));
_notebook.set_current_page (0);
get_vbox ()->add (_notebook);
_notebook.show_all (); _notebook.show_all ();
add (_notebook);
_notebook.signal_switch_page ().connect (sigc::mem_fun (*this, &PatchChangeTriggerWindow::on_switch_page));
_notebook.set_current_page (0);
} }
void void
PatchChangeTriggerDialog::on_switch_page (GtkNotebookPage*, guint page_num) PatchChangeTriggerWindow::clear ()
{
_route_connection.disconnect ();
set_title (_("Trigger Patch Select"));
for (uint32_t chn = 0; chn < 16; ++chn) {
_w[chn]->reset (boost::shared_ptr<ARDOUR::Route> (), boost::shared_ptr<ARDOUR::MIDITrigger>());
}
}
void
PatchChangeTriggerWindow::reset (boost::shared_ptr<Route> r, boost::shared_ptr<MIDITrigger> t)
{
if (!r || !t) {
clear ();
return;
}
set_title (string_compose (_("Select Patch for \"%1\" - \"%2\""), r->name (), t->name ()));
r->DropReferences.connect (_route_connection, invalidator(*this), boost::bind (&PatchChangeTriggerWindow::clear, this), gui_context());
for (uint32_t chn = 0; chn < 16; ++chn) {
_w[chn]->reset (r, t);
}
_notebook.set_current_page (0);
}
void
PatchChangeTriggerWindow::on_switch_page (GtkNotebookPage*, guint page_num)
{ {
_w[page_num]->refresh (); _w[page_num]->refresh ();
} }

View File

@ -33,29 +33,26 @@
#include "widgets/ardour_dropdown.h" #include "widgets/ardour_dropdown.h"
#include "ardour_dialog.h" #include "ardour_dialog.h"
#include "ardour_window.h"
#include "pianokeyboard.h" #include "pianokeyboard.h"
namespace ARDOUR { namespace ARDOUR {
class MIDITrigger; class MIDITrigger;
}; };
class PatchBankList : virtual public sigc::trackable class PatchBankList
{ {
public: public:
PatchBankList (boost::shared_ptr<ARDOUR::Route>); PatchBankList ();
virtual ~PatchBankList (); virtual ~PatchBankList ();
protected: protected:
void refill (uint8_t const channel); void refill (boost::shared_ptr<MIDI::Name::ChannelNameSet>, int const bank);
void set_active_pgm (uint8_t); void set_active_pgm (uint8_t);
virtual int bank (uint8_t chn) const = 0;
virtual void select_bank (uint32_t) = 0; virtual void select_bank (uint32_t) = 0;
virtual void select_program (uint8_t) = 0; virtual void select_program (uint8_t) = 0;
virtual void instrument_info_changed () = 0; virtual void instrument_info_changed () = 0;
virtual void processors_changed () = 0;
boost::shared_ptr<ARDOUR::Route> _route;
ArdourWidgets::ArdourDropdown _bank_select; ArdourWidgets::ArdourDropdown _bank_select;
Gtk::SpinButton _bank_msb_spin; Gtk::SpinButton _bank_msb_spin;
@ -65,37 +62,34 @@ protected:
private: private:
void select_bank_spin (); void select_bank_spin ();
ARDOUR::InstrumentInfo& _info;
ArdourWidgets::ArdourButton _program_btn[128]; ArdourWidgets::ArdourButton _program_btn[128];
boost::shared_ptr<MIDI::Name::PatchBank> _current_patch_bank; boost::shared_ptr<MIDI::Name::PatchBank> _current_patch_bank;
bool _ignore_spin_btn_signals; bool _ignore_spin_btn_signals;
PBD::ScopedConnection _info_changed_connection;
PBD::ScopedConnection _route_connection;
}; };
class PatchChangeTab : public Gtk::VBox, public PatchBankList class PatchChangeTab : public Gtk::VBox, public PatchBankList
{ {
public: public:
PatchChangeTab (boost::shared_ptr<ARDOUR::Route>, boost::shared_ptr<ARDOUR::MIDITrigger>, int channel); PatchChangeTab (int channel);
void refresh (); void refresh ();
void reset (boost::shared_ptr<ARDOUR::Route>, boost::shared_ptr<ARDOUR::MIDITrigger>);
protected: protected:
int bank (uint8_t) const; int bank () const;
uint8_t program () const; uint8_t program () const;
/* Implement PatchBankList */ /* Implement PatchBankList */
void select_bank (uint32_t); void select_bank (uint32_t);
void select_program (uint8_t); void select_program (uint8_t);
void instrument_info_changed ();
void processors_changed ();
private: private:
void refill_banks (); void refill_banks ();
void trigger_property_changed (PBD::PropertyChange const&); void trigger_property_changed (PBD::PropertyChange const&);
void enable_toggle (); void enable_toggle ();
void update_sensitivity (); void update_sensitivity ();
void instrument_info_changed ();
ArdourWidgets::ArdourButton _enable_btn; ArdourWidgets::ArdourButton _enable_btn;
@ -103,8 +97,9 @@ private:
int _bank; int _bank;
bool _ignore_callback; bool _ignore_callback;
boost::shared_ptr<ARDOUR::Route> _route;
boost::shared_ptr<ARDOUR::MIDITrigger> _trigger; boost::shared_ptr<ARDOUR::MIDITrigger> _trigger;
PBD::ScopedConnection _trigger_connection; PBD::ScopedConnectionList _connections;
}; };
class PatchChangeWidget : public Gtk::VBox, public PatchBankList class PatchChangeWidget : public Gtk::VBox, public PatchBankList
@ -125,16 +120,13 @@ protected:
private: private:
void refill_banks (); void refill_banks ();
ArdourWidgets::ArdourDropdown _channel_select;
uint8_t _channel;
bool _no_notifications;
void select_channel (uint8_t); void select_channel (uint8_t);
/* Implement PatchBankList */ /* Implement PatchBankList */
void select_bank (uint32_t); void select_bank (uint32_t);
void select_program (uint8_t); void select_program (uint8_t);
/* Route Callbacks */
void instrument_info_changed (); void instrument_info_changed ();
void processors_changed (); void processors_changed ();
@ -143,8 +135,6 @@ private:
void program_changed (); void program_changed ();
void bankpatch_changed (uint8_t); void bankpatch_changed (uint8_t);
PBD::ScopedConnectionList _ac_connections;
/* Audition */ /* Audition */
void audition_toggle (); void audition_toggle ();
void check_note_range (bool); void check_note_range (bool);
@ -152,32 +142,46 @@ private:
void cancel_audition (); void cancel_audition ();
bool audition_next (); bool audition_next ();
sigc::connection _note_queue_connection; boost::shared_ptr<ARDOUR::Route> _route;
ARDOUR::InstrumentInfo& _info;
ArdourWidgets::ArdourButton _audition_enable; uint8_t _channel;
Gtk::SpinButton _audition_start_spin; // Consider a click-box w/note-names bool _no_notifications;
Gtk::SpinButton _audition_end_spin;
Gtk::SpinButton _audition_velocity; ArdourWidgets::ArdourDropdown _channel_select;
uint8_t _audition_note_num; ArdourWidgets::ArdourButton _audition_enable;
bool _audition_note_on; Gtk::SpinButton _audition_start_spin; // Consider a click-box w/note-names
Gtk::SpinButton _audition_end_spin;
Gtk::SpinButton _audition_velocity;
uint8_t _audition_note_num;
bool _audition_note_on;
APianoKeyboard _piano; APianoKeyboard _piano;
void _note_on_event_handler (int, int); void _note_on_event_handler (int, int);
void note_on_event_handler (int, bool for_audition); void note_on_event_handler (int, bool for_audition);
void note_off_event_handler (int); void note_off_event_handler (int);
sigc::connection _note_queue_connection;
PBD::ScopedConnectionList _ac_connections;
PBD::ScopedConnectionList _route_connections;
}; };
class PatchChangeTriggerDialog : public ArdourDialog class PatchChangeTriggerWindow : public ArdourWindow
{ {
public: public:
PatchChangeTriggerDialog (boost::shared_ptr<ARDOUR::Route>, boost::shared_ptr<ARDOUR::MIDITrigger>); PatchChangeTriggerWindow ();
void reset (boost::shared_ptr<ARDOUR::Route>, boost::shared_ptr<ARDOUR::MIDITrigger>);
void clear ();
private: private:
void on_switch_page (GtkNotebookPage*, guint page_num); void on_switch_page (GtkNotebookPage*, guint page_num);
Gtk::Notebook _notebook; Gtk::Notebook _notebook;
PatchChangeTab* _w[16]; PatchChangeTab* _w[16];
PBD::ScopedConnection _route_connection;
}; };
class PatchChangeGridDialog : public ArdourDialog class PatchChangeGridDialog : public ArdourDialog