/* * Copyright (C) 2017 Robin Gareus * * 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; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #pragma once #include #include #include #include #include "midi++/midnam_patch.h" #include "pbd/signals.h" #include "ardour/route.h" #include "widgets/ardour_button.h" #include "widgets/ardour_dropdown.h" #include "ardour_dialog.h" #include "ardour_window.h" #include "pianokeyboard.h" namespace ARDOUR { class MIDITrigger; }; class PatchBankList { public: PatchBankList (); virtual ~PatchBankList (); protected: void refill (std::shared_ptr, int const bank); void set_active_pgm (uint8_t); virtual void select_bank (uint32_t) = 0; virtual void select_program (uint8_t) = 0; virtual void instrument_info_changed () = 0; ArdourWidgets::ArdourDropdown _bank_select; Gtk::SpinButton _bank_msb_spin; Gtk::SpinButton _bank_lsb_spin; Gtk::Table _program_table; private: void select_bank_spin (); ArdourWidgets::ArdourButton _program_btn[128]; std::shared_ptr _current_patch_bank; bool _ignore_spin_btn_signals; }; class PatchChangeTab : public Gtk::VBox, public PatchBankList { public: PatchChangeTab (int channel); void refresh (); void reset (std::shared_ptr, std::shared_ptr); protected: int bank () const; uint8_t program () const; /* Implement PatchBankList */ void select_bank (uint32_t); void select_program (uint8_t); 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; int _channel; int _bank; bool _ignore_callback; std::shared_ptr _route; std::shared_ptr _trigger; PBD::ScopedConnectionList _connections; }; class PatchChangeWidget : public Gtk::VBox, public PatchBankList { public: PatchChangeWidget (std::shared_ptr); ~PatchChangeWidget (); void refresh (); protected: int bank (uint8_t) const; uint8_t program (uint8_t) const; void on_show (); void on_hide (); private: void refill_banks (); 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 (); /* callbacks from route AC */ void bank_changed (); void program_changed (); void bankpatch_changed (uint8_t); /* Audition */ void audition_toggle (); void check_note_range (bool); void audition (); void cancel_audition (); bool audition_next (); std::shared_ptr _route; ARDOUR::InstrumentInfo& _info; 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 PatchChangeTriggerWindow : public ArdourWindow { public: PatchChangeTriggerWindow (); void reset (std::shared_ptr, std::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 { public: PatchChangeGridDialog (std::shared_ptr); void on_hide () { w.hide (); ArdourDialog::on_hide (); } void on_show () { w.show (); ArdourDialog::on_show (); } void refresh () { w.refresh (); } private: void route_property_changed (const PBD::PropertyChange&, std::weak_ptr); PBD::ScopedConnection _route_connection; PatchChangeWidget w; };