*/
#include "ardour/dB.h"
+#include "ardour/plugin_insert.h"
#include "ardour/session.h"
#include "ardour/session_configuration.h"
#include "ardour/types.h"
_ctrls.button (ID).pressed.connect_same_thread (button_connections, boost::bind (&FaderPort8::button_user, this, true, ID)); \
_ctrls.button (ID).released.connect_same_thread (button_connections, boost::bind (&FaderPort8::button_user, this, false, ID));
+
+/* Bind button signals (press, release) to callback methods
+ * (called once after constructing buttons).
+ * Bound actions are handled the the ctrl-surface thread.
+ */
void
FaderPort8::setup_actions ()
{
BindAction (BtnUndo, "Editor", "undo");
BindAction (BtnRedo, "Editor", "redo");
+#ifdef FP8_MUTESOLO_UNDO
+ BindMethod (BtnSoloClear, button_solo_clear);
+#else
BindAction (BtnSoloClear, "Main", "cancel-solo");
+#endif
BindMethod (BtnMuteClear, button_mute_clear);
BindMethod (FP8Controls::BtnArmAll, button_arm_all);
BindFunction (BtnATouch, released, button_automation, ARDOUR::Touch);
BindFunction (BtnARead, released, button_automation, ARDOUR::Play);
BindFunction (BtnAWrite, released, button_automation, ARDOUR::Write);
+ BindFunction (BtnALatch, released, button_automation, ARDOUR::Latch);
_ctrls.button (FP8Controls::BtnEncoder).pressed.connect_same_thread (button_connections, boost::bind (&FaderPort8::button_encoder, this));
_ctrls.button (FP8Controls::BtnParam).pressed.connect_same_thread (button_connections, boost::bind (&FaderPort8::button_parameter, this));
- BindAction (BtnBypass, "Mixer", "ab-plugins");
- BindAction (BtnBypassAll, "Mixer", "ab-plugins"); // XXX
+ BindMethod (BtnBypass, button_bypass);
+ BindAction (BtnBypassAll, "Mixer", "ab-plugins");
- BindAction (BtnMacro, "Mixer", "show-editor");
- BindAction (BtnLink, "Window", "show-mixer");
+ BindAction (BtnMacro, "Common", "toggle-editor-and-mixer");
+ BindMethod (BtnOpen, button_open);
- BindAction (BtnOpen, "Common", "addExistingAudioFiles");
- BindAction (BtnLock, "Editor", "lock");
+ BindMethod (BtnLink, button_link);
+ BindMethod (BtnLock, button_lock);
// user-specific
for (FP8Controls::UserButtonMap::const_iterator i = _ctrls.user_buttons ().begin ();
}
}
+/* ****************************************************************************
+ * Direct control callback Actions
+ */
+
void
FaderPort8::button_play ()
{
Config->set_clicking (!Config->get_clicking ());
}
+void
+FaderPort8::button_bypass ()
+{
+ boost::shared_ptr<PluginInsert> pi = _plugin_insert.lock();
+ if (pi) {
+ pi->enable (! pi->enabled ());
+ } else {
+ AccessAction ("Mixer", "ab-plugins");
+ }
+}
+
+void
+FaderPort8::button_open ()
+{
+ boost::shared_ptr<PluginInsert> pi = _plugin_insert.lock();
+ if (pi) {
+ pi->ToggleUI (); /* EMIT SIGNAL */
+ } else {
+ AccessAction ("Common", "addExistingAudioFiles");
+ }
+}
+void
+FaderPort8::button_lock ()
+{
+ if (!_link_enabled) {
+ AccessAction ("Editor", "lock");
+ return;
+ }
+ if (_link_locked) {
+ unlock_link ();
+ } else if (!_link_control.expired ()) {
+ lock_link ();
+ }
+}
+
+void
+FaderPort8::button_link ()
+{
+ switch (_ctrls.fader_mode()) {
+ case ModeTrack:
+ case ModePan:
+ if (_link_enabled) {
+ stop_link ();
+ } else {
+ start_link ();
+ }
+ break;
+ default:
+ //AccessAction ("Window", "show-mixer");
+ break;
+ }
+}
+
void
FaderPort8::button_automation (ARDOUR::AutoState as)
{
break;
}
+ // TODO link/lock control automation?
+
// apply to all selected tracks
StripableList all;
session->get_stripables (all);
session->request_transport_speed (speed, false);
}
+#ifdef FP8_MUTESOLO_UNDO
void
-FaderPort8::button_mute_clear ()
+FaderPort8::button_solo_clear ()
{
- StripableList all;
- session->get_stripables (all);
- boost::shared_ptr<ControlList> cl (new ControlList);
- for (StripableList::const_iterator i = all.begin(); i != all.end(); ++i) {
- if ((*i)->is_master() || (*i)->is_monitor()) {
- continue;
+ bool soloing = session->soloing() || session->listening();
+#ifdef MIXBUS
+ soloing |= session->mixbus_soloed();
+#endif
+ if (soloing) {
+ StripableList all;
+ session->get_stripables (all);
+ for (StripableList::const_iterator i = all.begin(); i != all.end(); ++i) {
+ if ((*i)->is_master() || (*i)->is_auditioner() || (*i)->is_monitor()) {
+ continue;
+ }
+ boost::shared_ptr<SoloControl> sc = (*i)->solo_control();
+ if (sc && sc->self_soloed ()) {
+ _solo_state.push_back (boost::weak_ptr<AutomationControl>(sc));
+ }
}
- boost::shared_ptr<AutomationControl> ac = (*i)->mute_control();
- if (ac && ac->get_value () > 0) {
- if (ac->automation_state() == Touch && !ac->touching ()) {
- ac->start_touch (ac->session().transport_frame());
+ cancel_all_solo (); // AccessAction ("Main", "cancel-solo");
+ } else {
+ /* restore solo */
+ boost::shared_ptr<ControlList> cl (new ControlList);
+ for (std::vector <boost::weak_ptr<AutomationControl> >::const_iterator i = _solo_state.begin(); i != _solo_state.end(); ++i) {
+ boost::shared_ptr<AutomationControl> ac = (*i).lock();
+ if (!ac) {
+ continue;
}
+ ac->start_touch (ac->session().transport_frame());
cl->push_back (ac);
}
+ if (!cl->empty()) {
+ session->set_controls (cl, 1.0, PBD::Controllable::NoGroup);
+ }
}
- session->set_controls (cl, 0.0, PBD::Controllable::UseGroup);
}
+#endif
void
-FaderPort8::button_arm (bool press)
+FaderPort8::button_mute_clear ()
{
- FaderMode fadermode = _ctrls.fader_mode ();
- if (fadermode == ModeTrack || fadermode == ModePan) {
- _ctrls.button (FP8Controls::BtnArm).set_active (press);
- ARMButtonChange (press);
+#ifdef FP8_MUTESOLO_UNDO
+ if (session->muted ()) {
+ _mute_state = session->cancel_all_mute ();
+ } else {
+ /* restore mute */
+ boost::shared_ptr<ControlList> cl (new ControlList);
+ for (std::vector <boost::weak_ptr<AutomationControl> >::const_iterator i = _mute_state.begin(); i != _mute_state.end(); ++i) {
+ boost::shared_ptr<AutomationControl> ac = (*i).lock();
+ if (!ac) {
+ continue;
+ }
+ cl->push_back (ac);
+ ac->start_touch (ac->session().transport_frame());
+ }
+ if (!cl->empty()) {
+ session->set_controls (cl, 1.0, PBD::Controllable::NoGroup);
+ }
}
+#else
+ session->cancel_all_mute ();
+#endif
}
void
BasicUI::all_tracks_rec_in ();
}
+/* access generic action */
void
FaderPort8::button_action (const std::string& group, const std::string& item)
{
AccessAction (group, item);
}
+/* ****************************************************************************
+ * Control Interaction (encoder)
+ */
+
+void
+FaderPort8::handle_encoder_pan (int steps)
+{
+ boost::shared_ptr<Stripable> s = first_selected_stripable();
+ if (s) {
+ boost::shared_ptr<AutomationControl> ac;
+ if (shift_mod () || _ctrls.fader_mode() == ModePan) {
+ ac = s->pan_width_control ();
+ } else {
+ ac = s->pan_azimuth_control ();
+ }
+ if (ac) {
+ ac->start_touch (ac->session().transport_frame());
+ if (steps == 0) {
+ ac->set_value (ac->normal(), PBD::Controllable::UseGroup);
+ } else {
+ double v = ac->internal_to_interface (ac->get_value());
+ v = std::max (0.0, std::min (1.0, v + steps * .01));
+ ac->set_value (ac->interface_to_internal(v), PBD::Controllable::UseGroup);
+ }
+ }
+ }
+}
+
+void
+FaderPort8::handle_encoder_link (int steps)
+{
+ if (_link_control.expired ()) {
+ return;
+ }
+ boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> (_link_control.lock ());
+ if (!ac) {
+ return;
+ }
+
+ double v = ac->internal_to_interface (ac->get_value());
+ ac->start_touch (ac->session().transport_frame());
+
+ if (steps == 0) {
+ ac->set_value (ac->normal(), PBD::Controllable::UseGroup);
+ return;
+ }
+
+ if (ac->desc().toggled) {
+ v = v > 0 ? 0. : 1.;
+ } else if (ac->desc().integer_step) {
+ v += steps / (1.f + ac->desc().upper - ac->desc().lower);
+ } else if (ac->desc().enumeration) {
+ ac->set_value (ac->desc().step_enum (ac->get_value(), steps < 0), PBD::Controllable::UseGroup);
+ return;
+ } else {
+ v = std::max (0.0, std::min (1.0, v + steps * .01));
+ }
+ ac->set_value (ac->interface_to_internal(v), PBD::Controllable::UseGroup);
+}
+
+
+/* ****************************************************************************
+ * Mode specific and internal callbacks
+ */
+
+/* handle "ARM" press -- act like shift, change "Select" button mode */
+void
+FaderPort8::button_arm (bool press)
+{
+ FaderMode fadermode = _ctrls.fader_mode ();
+ if (fadermode == ModeTrack || fadermode == ModePan) {
+ _ctrls.button (FP8Controls::BtnArm).set_active (press);
+ ARMButtonChange (press); /* EMIT SIGNAL */
+ }
+}
+
void
FaderPort8::button_prev_next (bool next)
{
void
FaderPort8::button_encoder ()
{
+ /* special-case metronome level */
+ if (_ctrls.button (FP8Controls::BtnClick).is_pressed ()) {
+ Config->set_click_gain (1.0);
+ _ctrls.button (FP8Controls::BtnClick).ignore_release();
+ return;
+ }
switch (_ctrls.nav_mode()) {
case NavZoom:
ZoomToSession (); // XXX undo zoom
ZoomToSession ();
break;
case NavChannel:
+ AccessAction ("Editor", "select-topmost");
+ break;
case NavBank:
move_selected_into_view ();
break;
ac = session->master_out()->gain_control ();
}
if (ac) {
- if (ac->automation_state() == Touch && !ac->touching ()) {
- ac->start_touch (ac->session().transport_frame());
- }
+ ac->start_touch (ac->session().transport_frame());
ac->set_value (ac->normal(), PBD::Controllable::NoGroup);
}
}
switch (_ctrls.nav_mode()) {
case NavChannel:
if (neg) {
- StepTracksUp ();
+ AccessAction ("Mixer", "scroll-left");
+ AccessAction ("Editor", "step-tracks-up");
} else {
- StepTracksDown ();
+ AccessAction ("Mixer", "scroll-right");
+ AccessAction ("Editor", "step-tracks-down");
}
break;
case NavZoom:
if (ac) {
double v = ac->internal_to_interface (ac->get_value());
v = std::max (0.0, std::min (1.0, v + steps * (neg ? -.01 : .01)));
- if (ac->automation_state() == Touch && !ac->touching ()) {
- ac->start_touch (ac->session().transport_frame());
- }
+ ac->start_touch (ac->session().transport_frame());
ac->set_value (ac->interface_to_internal(v), PBD::Controllable::NoGroup);
}
}
switch (_ctrls.fader_mode()) {
case ModeTrack:
case ModePan:
- {
- boost::shared_ptr<Stripable> s = first_selected_stripable();
- if (s) {
- boost::shared_ptr<AutomationControl> ac;
- if (shift_mod () || _ctrls.fader_mode() == ModePan) {
- ac = s->pan_width_control ();
- } else {
- ac = s->pan_azimuth_control ();
- }
- if (ac) {
- if (ac->automation_state() == Touch && !ac->touching ()) {
- ac->start_touch (ac->session().transport_frame());
- }
- ac->set_value (ac->normal(), PBD::Controllable::UseGroup);
- }
- }
+ if (_link_enabled || _link_locked) {
+ handle_encoder_link (0);
+ } else {
+ handle_encoder_pan (0);
}
break;
case ModePlugins:
+ toggle_preset_param_mode ();
break;
case ModeSend:
break;
switch (_ctrls.fader_mode()) {
case ModeTrack:
case ModePan:
- {
- boost::shared_ptr<Stripable> s = first_selected_stripable();
- if (s) {
- boost::shared_ptr<AutomationControl> ac;
- if (shift_mod () || _ctrls.fader_mode() == ModePan) {
- ac = s->pan_width_control ();
- } else {
- ac = s->pan_azimuth_control ();
- }
- if (ac) {
- double v = ac->internal_to_interface (ac->get_value());
- v = std::max (0.0, std::min (1.0, v + steps * (neg ? -.01 : .01)));
- if (ac->automation_state() == Touch && !ac->touching ()) {
- ac->start_touch (ac->session().transport_frame());
- }
- ac->set_value (ac->interface_to_internal(v), PBD::Controllable::UseGroup);
- }
+ if (steps != 0) {
+ if (_link_enabled || _link_locked) {
+ handle_encoder_link (neg ? -steps : steps);
+ } else {
+ handle_encoder_pan (neg ? -steps : steps);
}
}
break;
case ModePlugins:
case ModeSend:
while (steps > 0) {
- bank_param (neg, false);
+ bank_param (neg, shift_mod());
--steps;
}
break;