1 /* 2 * Copyright (C) 2006-2007 John Anderson 3 * Copyright (C) 2012-2015 Paul Davis <paul@linuxaudiosystems.com> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License along 16 * with this program; if not, write to the Free Software Foundation, Inc., 17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 */ 19 20 #ifndef __ardour_mackie_control_protocol_subview_h__ 21 #define __ardour_mackie_control_protocol_subview_h__ 22 23 #include <boost/smart_ptr.hpp> 24 25 #include "ardour/types.h" 26 27 namespace ARDOUR { 28 class ParameterDescriptor; 29 class Plugin; 30 class PluginInsert; 31 } 32 33 namespace ArdourSurface { 34 35 class MackieControlProtocol; 36 37 namespace Mackie { 38 39 class Pot; 40 class Strip; 41 class Subview; 42 class Surface; 43 class SubviewFactory; 44 45 /** 46 This implements the subviews of the Mackie control in a Strategy pattern 47 */ 48 class Subview { 49 public: 50 51 enum Mode { 52 None, 53 EQ, 54 Dynamics, 55 Sends, 56 TrackView, 57 Plugin, 58 }; 59 60 61 Subview(MackieControlProtocol& mcp, boost::shared_ptr<ARDOUR::Stripable> subview_stripable); 62 virtual ~Subview(); 63 64 virtual Mode subview_mode () const = 0; 65 virtual void update_global_buttons() = 0; permit_flipping_faders_and_pots()66 virtual bool permit_flipping_faders_and_pots() { return false; } 67 virtual void setup_vpot( 68 Strip* strip, 69 Pot* vpot, 70 std::string pending_display[2]) = 0; 71 virtual void handle_vselect_event(uint32_t global_strip_position); 72 // returns true if press was handled in the subview, default is false handle_cursor_right_press()73 virtual bool handle_cursor_right_press() { return false; } 74 // returns true if press was handled in the subview, default is false handle_cursor_left_press()75 virtual bool handle_cursor_left_press() { return false; } 76 77 static bool subview_mode_would_be_ok (Subview::Mode, boost::shared_ptr<ARDOUR::Stripable>, std::string& reason_why_not); subview_stripable()78 boost::shared_ptr<ARDOUR::Stripable> subview_stripable() const { return _subview_stripable; } 79 80 void notify_subview_stripable_deleted (); mcp()81 MackieControlProtocol& mcp() { return _mcp; } 82 subview_stripable_connections()83 PBD::ScopedConnectionList& subview_stripable_connections() { return _subview_stripable_connections; } subview_connections()84 PBD::ScopedConnectionList& subview_connections() { return _subview_connections; } 85 86 void do_parameter_display(std::string& display, const ARDOUR::ParameterDescriptor& pd, float param_val, Strip* strip, bool screen_hold); 87 88 protected: 89 void init_strip_vectors(); 90 void store_pointers(Strip* strip, Pot* vpot, std::string* pending_display, uint32_t global_strip_position); 91 bool retrieve_pointers(Strip** strip, Pot** vpot, std::string** pending_display, uint32_t global_strip_position); 92 93 MackieControlProtocol& _mcp; 94 boost::shared_ptr<ARDOUR::Stripable> _subview_stripable; 95 PBD::ScopedConnectionList _subview_stripable_connections; 96 97 std::vector<Strip*> _strips_over_all_surfaces; 98 std::vector<Pot*> _strip_vpots_over_all_surfaces; 99 std::vector<std::string*> _strip_pending_displays_over_all_surfaces; 100 PBD::ScopedConnectionList _subview_connections; 101 private: 102 void reset_all_vpot_controls(); 103 }; 104 105 class NoneSubview : public Subview { 106 public: 107 NoneSubview(MackieControlProtocol& mcp, boost::shared_ptr<ARDOUR::Stripable> subview_stripable); 108 virtual ~NoneSubview(); 109 subview_mode()110 virtual Mode subview_mode () const { return Subview::None; } 111 static bool subview_mode_would_be_ok (boost::shared_ptr<ARDOUR::Stripable> r, std::string& reason_why_not); 112 113 virtual void update_global_buttons(); 114 virtual void setup_vpot( 115 Strip* strip, 116 Pot* vpot, 117 std::string pending_display[2]); 118 }; 119 120 class EQSubview : public Subview { 121 public: 122 EQSubview(MackieControlProtocol& mcp, boost::shared_ptr<ARDOUR::Stripable> subview_stripable); 123 virtual ~EQSubview(); 124 subview_mode()125 virtual Mode subview_mode () const { return Subview::EQ; } 126 static bool subview_mode_would_be_ok (boost::shared_ptr<ARDOUR::Stripable> r, std::string& reason_why_not); 127 virtual void update_global_buttons(); 128 virtual void setup_vpot( 129 Strip* strip, 130 Pot* vpot, 131 std::string pending_display[2]); 132 void notify_change (boost::weak_ptr<ARDOUR::AutomationControl>, uint32_t global_strip_position, bool force); 133 }; 134 135 class DynamicsSubview : public Subview { 136 public: 137 DynamicsSubview(MackieControlProtocol& mcp, boost::shared_ptr<ARDOUR::Stripable> subview_stripable); 138 virtual ~DynamicsSubview(); 139 subview_mode()140 virtual Subview::Mode subview_mode () const { return Subview::Dynamics; } 141 static bool subview_mode_would_be_ok (boost::shared_ptr<ARDOUR::Stripable> r, std::string& reason_why_not); 142 virtual void update_global_buttons(); 143 virtual void setup_vpot( 144 Strip* strip, 145 Pot* vpot, 146 std::string pending_display[2]); 147 void notify_change (boost::weak_ptr<ARDOUR::AutomationControl>, uint32_t global_strip_position, bool force, bool propagate_mode_change); 148 }; 149 150 class SendsSubview : public Subview { 151 public: 152 SendsSubview(MackieControlProtocol& mcp, boost::shared_ptr<ARDOUR::Stripable> subview_stripable); 153 virtual ~SendsSubview(); 154 subview_mode()155 virtual Subview::Mode subview_mode () const { return Subview::Sends; } 156 static bool subview_mode_would_be_ok (boost::shared_ptr<ARDOUR::Stripable> r, std::string& reason_why_not); 157 virtual void update_global_buttons(); permit_flipping_faders_and_pots()158 virtual bool permit_flipping_faders_and_pots() { return true; } 159 virtual void setup_vpot( 160 Strip* strip, 161 Pot* vpot, 162 std::string pending_display[2]); 163 void notify_send_level_change (uint32_t global_strip_position, bool force); 164 165 virtual void handle_vselect_event(uint32_t global_strip_position); 166 }; 167 168 class TrackViewSubview : public Subview { 169 public: 170 TrackViewSubview(MackieControlProtocol& mcp, boost::shared_ptr<ARDOUR::Stripable> subview_stripable); 171 virtual ~TrackViewSubview(); 172 subview_mode()173 virtual Subview::Mode subview_mode () const { return Subview::TrackView; } 174 static bool subview_mode_would_be_ok (boost::shared_ptr<ARDOUR::Stripable> r, std::string& reason_why_not); 175 virtual void update_global_buttons(); 176 virtual void setup_vpot( 177 Strip* strip, 178 Pot* vpot, 179 std::string pending_display[2]); 180 void notify_change (ARDOUR::AutomationType, uint32_t global_strip_position, bool force); 181 }; 182 183 class PluginSubviewState; 184 185 class PluginSubview : public Subview { 186 public: 187 PluginSubview(MackieControlProtocol& mcp, boost::shared_ptr<ARDOUR::Stripable> subview_stripable); 188 virtual ~PluginSubview(); 189 subview_mode()190 virtual Subview::Mode subview_mode () const { return Subview::Plugin; } 191 static bool subview_mode_would_be_ok (boost::shared_ptr<ARDOUR::Stripable> r, std::string& reason_why_not); 192 virtual void update_global_buttons(); 193 virtual bool permit_flipping_faders_and_pots(); 194 virtual void setup_vpot( 195 Strip* strip, 196 Pot* vpot, 197 std::string pending_display[2]); 198 virtual void handle_vselect_event(uint32_t global_strip_position); 199 virtual bool handle_cursor_right_press(); 200 virtual bool handle_cursor_left_press(); 201 202 void set_state(boost::shared_ptr<PluginSubviewState> new_state); 203 204 protected: 205 void connect_processors_changed_signal(); 206 void handle_processors_changed(); 207 208 boost::shared_ptr<PluginSubviewState> _plugin_subview_state; 209 }; 210 211 class PluginSubviewState { 212 public: 213 PluginSubviewState(PluginSubview& context); 214 virtual ~PluginSubviewState(); 215 permit_flipping_faders_and_pots()216 virtual bool permit_flipping_faders_and_pots() { return false; } 217 virtual void setup_vpot( 218 Strip* strip, 219 Pot* vpot, 220 std::string pending_display[2], 221 uint32_t global_strip_position, 222 boost::shared_ptr<ARDOUR::Stripable> subview_stripable) = 0; 223 virtual void handle_vselect_event(uint32_t global_strip_position, boost::shared_ptr<ARDOUR::Stripable> subview_stripable) = 0; 224 static std::string shorten_display_text(const std::string& text, std::string::size_type target_length); 225 virtual bool handle_cursor_right_press(); 226 virtual bool handle_cursor_left_press(); 227 virtual void bank_changed() = 0; 228 229 protected: 230 uint32_t calculate_virtual_strip_position(uint32_t strip_index) const; 231 232 PluginSubview& _context; 233 const uint32_t _bank_size; 234 uint32_t _current_bank; 235 }; 236 237 class PluginSelect : public PluginSubviewState { 238 public: 239 PluginSelect(PluginSubview& context); 240 virtual ~PluginSelect(); 241 242 virtual void setup_vpot( 243 Strip* strip, 244 Pot* vpot, 245 std::string pending_display[2], 246 uint32_t global_strip_position, 247 boost::shared_ptr<ARDOUR::Stripable> subview_stripable); 248 virtual void handle_vselect_event(uint32_t global_strip_position, boost::shared_ptr<ARDOUR::Stripable> subview_stripable); 249 virtual void bank_changed(); 250 }; 251 252 class PluginEdit : public PluginSubviewState { 253 public: 254 PluginEdit(PluginSubview& context, boost::weak_ptr<ARDOUR::PluginInsert> weak_subview_plugin); 255 virtual ~PluginEdit(); 256 permit_flipping_faders_and_pots()257 virtual bool permit_flipping_faders_and_pots() { return true; } 258 virtual void setup_vpot( 259 Strip* strip, 260 Pot* vpot, 261 std::string pending_display[2], 262 uint32_t global_strip_position, 263 boost::shared_ptr<ARDOUR::Stripable> subview_stripable); 264 virtual void handle_vselect_event(uint32_t global_strip_position, boost::shared_ptr<ARDOUR::Stripable> subview_stripable); 265 virtual void bank_changed(); 266 267 void notify_parameter_change(Strip* strip, Pot* vpot, std::string pending_display[2], uint32_t global_strip_position); 268 void init(); 269 bool plugin_went_away() const; 270 void switch_to_plugin_select_state(); 271 272 boost::shared_ptr<ARDOUR::AutomationControl> parameter_control(uint32_t global_strip_position) const; 273 274 boost::weak_ptr<ARDOUR::PluginInsert> _weak_subview_plugin_insert; 275 boost::weak_ptr<ARDOUR::Plugin> _weak_subview_plugin; 276 std::vector<uint32_t> _plugin_input_parameter_indices; 277 }; 278 279 class SubviewFactory { 280 public: 281 static SubviewFactory* instance(); 282 283 boost::shared_ptr<Subview> create_subview(Subview::Mode svm, 284 MackieControlProtocol& mcp, boost::shared_ptr<ARDOUR::Stripable> subview_stripable); 285 protected: 286 SubviewFactory(); 287 private: 288 static SubviewFactory* _instance; 289 }; 290 291 } /* namespace Mackie */ 292 } /* namespace ArdourSurface */ 293 294 #endif /* __ardour_mackie_control_protocol_subview_h__ */ 295