From a4fd29fa7d3ef2744555be2ba788ff6f5b75e7b1 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Wed, 9 Feb 2022 18:59:15 +0100 Subject: [PATCH] Refactor PC Dialog/Window -- non-modal tabbed dialog --- gtk2_ardour/patch_change_widget.cc | 147 ++++++++++++++++++----------- gtk2_ardour/patch_change_widget.h | 66 +++++++------ 2 files changed, 127 insertions(+), 86 deletions(-) diff --git a/gtk2_ardour/patch_change_widget.cc b/gtk2_ardour/patch_change_widget.cc index 6a9cae86f2..b804273fcc 100644 --- a/gtk2_ardour/patch_change_widget.cc +++ b/gtk2_ardour/patch_change_widget.cc @@ -46,12 +46,10 @@ using namespace Gtk; using namespace ARDOUR; -PatchBankList::PatchBankList (boost::shared_ptr r) - : _route (r) - , _bank_msb_spin (*manage (new Adjustment (0, 0, 127, 1, 16))) +PatchBankList::PatchBankList () + : _bank_msb_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) - , _info (r->instrument_info ()) , _ignore_spin_btn_signals (false) { _program_table.set_spacings (1); @@ -67,14 +65,6 @@ PatchBankList::PatchBankList (boost::shared_ptr r) _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)); - - _info.Changed.connect (_info_changed_connection, invalidator (*this), - boost::bind (&PatchBankList::instrument_info_changed, this), gui_context ()); - - if (!boost::dynamic_pointer_cast (_route)) { - _route->processors_changed.connect (_route_connection, invalidator (*this), - boost::bind (&PatchBankList::processors_changed, this), gui_context ()); - } } PatchBankList::~PatchBankList () @@ -96,7 +86,7 @@ flip_map (std::map const& src) } void -PatchBankList::refill (const uint8_t channel) +PatchBankList::refill (boost::shared_ptr cns, int const b) { using namespace Menu_Helpers; using namespace Gtkmm2ext; @@ -105,8 +95,6 @@ PatchBankList::refill (const uint8_t channel) _current_patch_bank.reset (); _bank_select.clear_items (); - const int b = bank (channel); - { PBD::Unwinder uw (_ignore_spin_btn_signals, true); _bank_msb_spin.set_value (b >> 7); @@ -122,7 +110,6 @@ PatchBankList::refill (const uint8_t channel) unset_notes.set (); - boost::shared_ptr cns = _info.get_patches (channel); if (cns) { const ChannelNameSet::PatchBanks& patch_banks = cns->patch_banks (); 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 r, boost::shared_ptr t, int channel) - : PatchBankList (r) - , _enable_btn (_("Override Patch Changes"), ArdourWidgets::ArdourButton::led_default_elements) +PatchChangeTab::PatchChangeTab (int channel) + : _enable_btn (_("Override Patch Changes"), ArdourWidgets::ArdourButton::led_default_elements) , _channel (channel) , _bank (0) , _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 = manage (new HBox ()); box->set_border_width (2); @@ -288,18 +266,39 @@ PatchChangeTab::PatchChangeTab (boost::shared_ptr r, boost::shared_ptrPropertyChanged.connect (_trigger_connection, invalidator (*this), boost::bind (&PatchChangeTab::trigger_property_changed, this, _1), gui_context ()); - if (!boost::dynamic_pointer_cast (_route)) { - processors_changed (); + reset (boost::shared_ptr (), boost::shared_ptr()); +} + +void +PatchChangeTab::reset (boost::shared_ptr r, boost::shared_ptr 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 (); - update_sensitivity (); } void PatchChangeTab::enable_toggle () { - if (_ignore_callback) { + if (_ignore_callback || !_trigger) { return; } if (_enable_btn.get_active ()) { @@ -313,7 +312,8 @@ PatchChangeTab::enable_toggle () void 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); _bank_select.set_sensitive (en); _bank_msb_spin.set_sensitive (en); @@ -340,7 +340,7 @@ PatchChangeTab::select_bank (uint32_t bank) void PatchChangeTab::select_program (uint8_t pgm) { - if (pgm > 127) { + if (pgm > 127 || !_trigger) { return; } @@ -357,15 +357,19 @@ PatchChangeTab::refresh () void PatchChangeTab::refill_banks () { - refill (_channel); + boost::shared_ptr cns; + if (_route) { + cns = _route->instrument_info ().get_patches (_channel); + } + update_sensitivity (); + refill (cns, bank ()); set_active_pgm (program ()); } int -PatchChangeTab::bank (uint8_t c) const +PatchChangeTab::bank () const { - assert (c == _channel); - if (_trigger->patch_change_set (_channel)) { + if (_trigger && _trigger->patch_change_set (_channel)) { return _trigger->patch_change (_channel).bank (); } return _bank; @@ -374,7 +378,7 @@ PatchChangeTab::bank (uint8_t c) const uint8_t PatchChangeTab::program () const { - if (_trigger->patch_change_set (_channel)) { + if (_trigger && _trigger->patch_change_set (_channel)) { return _trigger->patch_change (_channel).program (); } return 0; @@ -386,15 +390,11 @@ PatchChangeTab::instrument_info_changed () refill_banks (); } -void -PatchChangeTab::processors_changed () -{ -} - /* ****************************************************************************/ PatchChangeWidget::PatchChangeWidget (boost::shared_ptr r) - : PatchBankList (r) + : _route (r) + , _info (r->instrument_info ()) , _channel (-1) , _no_notifications (false) , _audition_enable (_("Audition on Change"), ArdourWidgets::ArdourButton::led_default_elements) @@ -467,7 +467,12 @@ PatchChangeWidget::PatchChangeWidget (boost::shared_ptr r) if (!boost::dynamic_pointer_cast (_route)) { 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 () @@ -546,7 +551,9 @@ void PatchChangeWidget::refill_banks () { cancel_audition (); - refill (_channel); + + boost::shared_ptr cns = _info.get_patches (_channel); + refill (cns, bank (_channel)); program_changed (); } @@ -804,23 +811,53 @@ PatchChangeWidget::program (uint8_t chn) const /* ***************************************************************************/ -PatchChangeTriggerDialog::PatchChangeTriggerDialog (boost::shared_ptr r, boost::shared_ptr t) - : ArdourDialog (string_compose (_("Select Patch for \"%1\""), t->name ()), false, false) +PatchChangeTriggerWindow::PatchChangeTriggerWindow () + : ArdourWindow (_("Trigger Patch Select")) { 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.signal_switch_page ().connect (sigc::mem_fun (*this, &PatchChangeTriggerDialog::on_switch_page)); - _notebook.set_current_page (0); - - get_vbox ()->add (_notebook); _notebook.show_all (); + add (_notebook); + + _notebook.signal_switch_page ().connect (sigc::mem_fun (*this, &PatchChangeTriggerWindow::on_switch_page)); + + _notebook.set_current_page (0); } 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 (), boost::shared_ptr()); + } +} + +void +PatchChangeTriggerWindow::reset (boost::shared_ptr r, boost::shared_ptr 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 (); } diff --git a/gtk2_ardour/patch_change_widget.h b/gtk2_ardour/patch_change_widget.h index c4d3133a83..da25e81a00 100644 --- a/gtk2_ardour/patch_change_widget.h +++ b/gtk2_ardour/patch_change_widget.h @@ -33,29 +33,26 @@ #include "widgets/ardour_dropdown.h" #include "ardour_dialog.h" +#include "ardour_window.h" #include "pianokeyboard.h" namespace ARDOUR { class MIDITrigger; }; -class PatchBankList : virtual public sigc::trackable +class PatchBankList { public: - PatchBankList (boost::shared_ptr); + PatchBankList (); virtual ~PatchBankList (); protected: - void refill (uint8_t const channel); + void refill (boost::shared_ptr, int const bank); void set_active_pgm (uint8_t); - virtual int bank (uint8_t chn) const = 0; virtual void select_bank (uint32_t) = 0; virtual void select_program (uint8_t) = 0; virtual void instrument_info_changed () = 0; - virtual void processors_changed () = 0; - - boost::shared_ptr _route; ArdourWidgets::ArdourDropdown _bank_select; Gtk::SpinButton _bank_msb_spin; @@ -65,37 +62,34 @@ protected: private: void select_bank_spin (); - ARDOUR::InstrumentInfo& _info; ArdourWidgets::ArdourButton _program_btn[128]; boost::shared_ptr _current_patch_bank; bool _ignore_spin_btn_signals; - PBD::ScopedConnection _info_changed_connection; - PBD::ScopedConnection _route_connection; }; class PatchChangeTab : public Gtk::VBox, public PatchBankList { public: - PatchChangeTab (boost::shared_ptr, boost::shared_ptr, int channel); + PatchChangeTab (int channel); void refresh (); + void reset (boost::shared_ptr, boost::shared_ptr); protected: - int bank (uint8_t) const; + int bank () const; uint8_t program () const; /* Implement PatchBankList */ void select_bank (uint32_t); void select_program (uint8_t); - void instrument_info_changed (); - void processors_changed (); private: void refill_banks (); void trigger_property_changed (PBD::PropertyChange const&); void enable_toggle (); void update_sensitivity (); + void instrument_info_changed (); ArdourWidgets::ArdourButton _enable_btn; @@ -103,8 +97,9 @@ private: int _bank; bool _ignore_callback; + boost::shared_ptr _route; boost::shared_ptr _trigger; - PBD::ScopedConnection _trigger_connection; + PBD::ScopedConnectionList _connections; }; class PatchChangeWidget : public Gtk::VBox, public PatchBankList @@ -125,16 +120,13 @@ protected: private: void refill_banks (); - ArdourWidgets::ArdourDropdown _channel_select; - - uint8_t _channel; - bool _no_notifications; - void select_channel (uint8_t); /* Implement PatchBankList */ void select_bank (uint32_t); void select_program (uint8_t); + + /* Route Callbacks */ void instrument_info_changed (); void processors_changed (); @@ -143,8 +135,6 @@ private: void program_changed (); void bankpatch_changed (uint8_t); - PBD::ScopedConnectionList _ac_connections; - /* Audition */ void audition_toggle (); void check_note_range (bool); @@ -152,32 +142,46 @@ private: void cancel_audition (); bool audition_next (); - sigc::connection _note_queue_connection; + boost::shared_ptr _route; + ARDOUR::InstrumentInfo& _info; - ArdourWidgets::ArdourButton _audition_enable; - 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; + uint8_t _channel; + bool _no_notifications; + + ArdourWidgets::ArdourDropdown _channel_select; + ArdourWidgets::ArdourButton _audition_enable; + 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; void _note_on_event_handler (int, int); void note_on_event_handler (int, bool for_audition); 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: - PatchChangeTriggerDialog (boost::shared_ptr, boost::shared_ptr); + PatchChangeTriggerWindow (); + + void reset (boost::shared_ptr, boost::shared_ptr); + void clear (); private: void on_switch_page (GtkNotebookPage*, guint page_num); Gtk::Notebook _notebook; PatchChangeTab* _w[16]; + + PBD::ScopedConnection _route_connection; }; class PatchChangeGridDialog : public ArdourDialog