2 * Copyright (C) 2017 Robin Gareus <robin@gareus.org>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 /* Faderport 8 Control Surface
20 * This is the button "View" of the MVC surface inteface,
21 * see actions.cc for the "Controller"
24 #include "ardour/plugin_insert.h"
25 #include "ardour/session.h"
26 #include "ardour/session_configuration.h"
28 #include "gtkmm2ext/actions.h"
30 #include "faderport8.h"
34 using namespace ARDOUR;
35 using namespace ArdourSurface::FP_NAMESPACE;
36 using namespace ArdourSurface::FP_NAMESPACE::FP8Types;
39 FaderPort8::connect_session_signals ()
41 session->RouteAdded.connect(session_connections, MISSING_INVALIDATOR, boost::bind (&FaderPort8::notify_stripable_added_or_removed, this), this);
42 PresentationInfo::Change.connect(session_connections, MISSING_INVALIDATOR, boost::bind (&FaderPort8::notify_pi_property_changed, this, _1), this);
44 Config->ParameterChanged.connect (session_connections, MISSING_INVALIDATOR, boost::bind (&FaderPort8::notify_parameter_changed, this, _1), this);
45 session->config.ParameterChanged.connect (session_connections, MISSING_INVALIDATOR, boost::bind (&FaderPort8::notify_parameter_changed, this, _1), this);
47 session->TransportStateChange.connect (session_connections, MISSING_INVALIDATOR, boost::bind (&FaderPort8::notify_transport_state_changed, this), this);
48 session->TransportLooped.connect (session_connections, MISSING_INVALIDATOR, boost::bind (&FaderPort8::notify_loop_state_changed, this), this);
49 session->RecordStateChanged.connect (session_connections, MISSING_INVALIDATOR, boost::bind (&FaderPort8::notify_record_state_changed, this), this);
51 session->DirtyChanged.connect (session_connections, MISSING_INVALIDATOR, boost::bind (&FaderPort8::notify_session_dirty_changed, this), this);
52 session->SoloChanged.connect (session_connections, MISSING_INVALIDATOR, boost::bind (&FaderPort8::notify_solo_changed, this), this);
53 session->MuteChanged.connect (session_connections, MISSING_INVALIDATOR, boost::bind (&FaderPort8::notify_mute_changed, this), this);
54 session->history().Changed.connect (session_connections, MISSING_INVALIDATOR, boost::bind (&FaderPort8::notify_history_changed, this), this);
58 FaderPort8::send_session_state ()
60 notify_transport_state_changed ();
61 notify_record_state_changed ();
62 notify_session_dirty_changed ();
63 notify_history_changed ();
64 notify_solo_changed ();
65 notify_mute_changed ();
66 notify_parameter_changed ("clicking");
68 notify_route_state_changed (); // XXX (stip specific, see below)
71 // TODO: AutomationState display of plugin & send automation
72 // TODO: link/lock control AS.
74 FaderPort8::notify_route_state_changed ()
76 boost::shared_ptr<Stripable> s = first_selected_stripable();
77 boost::shared_ptr<AutomationControl> ac;
79 switch (_ctrls.fader_mode ()) {
81 ac = s->gain_control();
84 ac = s->pan_azimuth_control();
91 _ctrls.button (FP8Controls::BtnALatch).set_active (false);
92 _ctrls.button (FP8Controls::BtnATrim).set_active (false);
93 _ctrls.button (FP8Controls::BtnAOff).set_active (false);
94 _ctrls.button (FP8Controls::BtnATouch).set_active (false);
95 _ctrls.button (FP8Controls::BtnARead).set_active (false);
96 _ctrls.button (FP8Controls::BtnAWrite).set_active (false);
98 _ctrls.button (FP8Controls::BtnArm).set_active (false);
103 ARDOUR::AutoState as = ac->automation_state();
104 _ctrls.button (FP8Controls::BtnAOff).set_active (as == Off);
105 _ctrls.button (FP8Controls::BtnATouch).set_active (as == Touch);
106 _ctrls.button (FP8Controls::BtnARead).set_active (as == Play);
107 _ctrls.button (FP8Controls::BtnAWrite).set_active (as == Write);
108 _ctrls.button (FP8Controls::BtnALatch).set_active (as == Latch);
111 /* handle the Faderport's track-arm button */
112 ac = s->rec_enable_control ();
113 _ctrls.button (FP8Controls::BtnArm).set_active (ac ? ac->get_value() : false);
118 FaderPort8::notify_parameter_changed (std::string param)
120 if (param == "clicking") {
121 _ctrls.button (FP8Controls::BtnClick).set_active (Config->get_clicking ());
126 FaderPort8::notify_transport_state_changed ()
128 if (session->transport_rolling ()) {
129 _ctrls.button (FP8Controls::BtnPlay).set_active (true);
130 _ctrls.button (FP8Controls::BtnStop).set_active (false);
132 _ctrls.button (FP8Controls::BtnPlay).set_active (false);
133 _ctrls.button (FP8Controls::BtnStop).set_active (true);
136 /* set rewind/fastforward lights */
137 const float ts = session->transport_speed ();
138 FP8ButtonInterface& b_rew = _ctrls.button (FP8Controls::BtnRewind);
139 FP8ButtonInterface& b_ffw = _ctrls.button (FP8Controls::BtnFastForward);
141 const bool rew = (ts < 0.f);
142 const bool ffw = (ts > 0.f && ts != 1.f);
143 if (b_rew.is_active() != rew) {
144 b_rew.set_active (rew);
146 if (b_ffw.is_active() != ffw) {
147 b_ffw.set_active (ffw);
150 notify_loop_state_changed ();
154 FaderPort8::notify_record_state_changed ()
156 switch (session->record_status ()) {
157 case Session::Disabled:
158 _ctrls.button (FP8Controls::BtnRecord).set_active (0);
159 _ctrls.button (FP8Controls::BtnRecord).set_blinking (false);
161 case Session::Enabled:
162 _ctrls.button (FP8Controls::BtnRecord).set_active (true);
163 _ctrls.button (FP8Controls::BtnRecord).set_blinking (true);
165 case Session::Recording:
166 _ctrls.button (FP8Controls::BtnRecord).set_active (true);
167 _ctrls.button (FP8Controls::BtnRecord).set_blinking (false);
173 FaderPort8::notify_loop_state_changed ()
175 bool looping = false;
176 Location* looploc = session->locations ()->auto_loop_location ();
177 if (looploc && session->get_play_loop ()) {
180 _ctrls.button (FP8Controls::BtnLoop).set_active (looping);
184 FaderPort8::notify_session_dirty_changed ()
186 const bool is_dirty = session->dirty ();
187 _ctrls.button (FP8Controls::BtnSave).set_active (is_dirty);
188 _ctrls.button (FP8Controls::BtnSave).set_color (is_dirty ? 0xff0000ff : 0x00ff00ff);
192 FaderPort8::notify_history_changed ()
194 _ctrls.button (FP8Controls::BtnRedo).set_active (session->redo_depth() > 0);
195 _ctrls.button (FP8Controls::BtnUndo).set_active (session->undo_depth() > 0);
199 FaderPort8::notify_solo_changed ()
201 bool soloing = session->soloing() || session->listening();
203 soloing |= session->mixbus_soloed();
205 _ctrls.button (FP8Controls::BtnSoloClear).set_active (soloing);
206 #ifdef FP8_MUTESOLO_UNDO
208 _solo_state.clear ();
214 FaderPort8::notify_mute_changed ()
216 bool muted = session->muted ();
217 #ifdef FP8_MUTESOLO_UNDO
219 _mute_state.clear ();
222 _ctrls.button (FP8Controls::BtnMuteClear).set_active (muted);
226 FaderPort8::notify_plugin_active_changed ()
228 boost::shared_ptr<PluginInsert> pi = _plugin_insert.lock();
230 _ctrls.button (FP8Controls::BtnBypass).set_active (true);
231 _ctrls.button (FP8Controls::BtnBypass).set_color (pi->enabled () ? 0x00ff00ff : 0xff0000ff);
233 _ctrls.button (FP8Controls::BtnBypass).set_active (false);
234 _ctrls.button (FP8Controls::BtnBypass).set_color (0x888888ff);
239 FaderPort8::nofity_focus_control (boost::weak_ptr<PBD::Controllable> c)
241 assert (_link_enabled && !_link_locked);
242 // TODO consider subscribing to c's DropReferences
243 // (in case the control goes away while it has focus, update the BtnColor)
245 if (c.expired () || 0 == boost::dynamic_pointer_cast<AutomationControl> (_link_control.lock ())) {
246 _ctrls.button (FP8Controls::BtnLink).set_color (0xff8800ff);
247 _ctrls.button (FP8Controls::BtnLock).set_color (0xff0000ff);
249 _ctrls.button (FP8Controls::BtnLink).set_color (0x88ff00ff);
250 _ctrls.button (FP8Controls::BtnLock).set_color (0x00ff88ff);