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