Fix #6280 – region (first_frame()==0) selectable with SnapRegionBoundary
[ardour.git] / gtk2_ardour / mixer_ui.cc
index e8c431041a072454bef96672788e3ebe3d193a09..d982e5a30142f72e57a88b08c14afbcfbcced823 100644 (file)
 
 #include <boost/foreach.hpp>
 
+#include <glibmm/threads.h>
+
 #include <gtkmm/accelmap.h>
+#include <gtkmm/stock.h>
 
 #include "pbd/convert.h"
 #include "pbd/stacktrace.h"
 #include "pbd/unwind.h"
 
-#include <glibmm/threads.h>
-
-#include <gtkmm2ext/gtk_ui.h>
-#include <gtkmm2ext/keyboard.h>
-#include <gtkmm2ext/utils.h>
-#include <gtkmm2ext/tearoff.h>
-#include <gtkmm2ext/window_title.h>
-#include <gtkmm2ext/doi.h>
-
 #include "ardour/amp.h"
 #include "ardour/debug.h"
 #include "ardour/audio_track.h"
 #include "ardour/vca.h"
 #include "ardour/vca_manager.h"
 
+#include "gtkmm2ext/gtk_ui.h"
+#include "gtkmm2ext/keyboard.h"
+#include "gtkmm2ext/utils.h"
+#include "gtkmm2ext/window_title.h"
+#include "gtkmm2ext/doi.h"
+
+#include "widgets/tearoff.h"
+
 #include "keyboard.h"
 #include "mixer_ui.h"
 #include "mixer_strip.h"
@@ -61,7 +63,6 @@
 #include "public_editor.h"
 #include "mouse_cursors.h"
 #include "ardour_ui.h"
-#include "prompter.h"
 #include "utils.h"
 #include "route_sorter.h"
 #include "actions.h"
@@ -631,6 +632,12 @@ Mixer_UI::deselect_all_strip_processors ()
        }
 }
 
+void
+Mixer_UI::select_all_tracks ()
+{
+       PublicEditor::instance().select_all_tracks ();
+}
+
 void
 Mixer_UI::select_none ()
 {
@@ -891,14 +898,19 @@ Mixer_UI::strip_button_release_event (GdkEventButton *ev, MixerStrip *strip)
                if (_selection.selected (strip)) {
                        /* primary-click: toggle selection state of strip */
                        if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
-                               _selection.remove (strip);
+                               _selection.remove (strip, true);
                        } else if (_selection.axes.size() > 1) {
                                /* de-select others */
                                _selection.set (strip);
                        }
+                       PublicEditor& pe = PublicEditor::instance();
+                       TimeAxisView* tav = pe.time_axis_view_from_stripable (strip->stripable());
+                       if (tav) {
+                               pe.set_selected_mixer_strip (*tav);
+                       }
                } else {
                        if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
-                               _selection.add (strip);
+                               _selection.add (strip, true);
                        } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::RangeSelectModifier)) {
 
                                /* extend selection */
@@ -946,7 +958,7 @@ Mixer_UI::strip_button_release_event (GdkEventButton *ev, MixerStrip *strip)
                                if (found_another) {
                                        PresentationInfo::ChangeSuspender cs;
                                        for (vector<MixerStrip*>::iterator i = tmp.begin(); i != tmp.end(); ++i) {
-                                               _selection.add (*i);
+                                               _selection.add (*i, true);
                                        }
                                } else {
                                        _selection.set (strip);  //user wants to start a range selection, but there aren't any others selected yet
@@ -2924,6 +2936,7 @@ Mixer_UI::register_actions ()
        myactions.register_action (group, "toggle-processors", _("Toggle Selected Processors"), sigc::mem_fun (*this, &Mixer_UI::toggle_processors));
        myactions.register_action (group, "ab-plugins", _("Toggle Selected Plugins"), sigc::mem_fun (*this, &Mixer_UI::ab_plugins));
        myactions.register_action (group, "select-none", _("Deselect all strips and processors"), sigc::mem_fun (*this, &Mixer_UI::select_none));
+       myactions.register_action (group, "select-all-tracks", _("Select All Tracks"), sigc::mem_fun (*this, &Mixer_UI::select_all_tracks));
 
        myactions.register_action (group, "scroll-left", _("Scroll Mixer Window to the left"), sigc::mem_fun (*this, &Mixer_UI::scroll_left));
        myactions.register_action (group, "scroll-right", _("Scroll Mixer Window to the right"), sigc::mem_fun (*this, &Mixer_UI::scroll_right));
@@ -2983,29 +2996,44 @@ Mixer_UI::rec_enable_action ()
        control_action (&Stripable::rec_enable_control);
 }
 
-void
-Mixer_UI::step_gain_up_action ()
+AutomationControlSet
+Mixer_UI::selected_gaincontrols ()
 {
        set_axis_targets_for_operation ();
-
+       AutomationControlSet rv;
        BOOST_FOREACH(AxisView* r, _axis_targets) {
                MixerStrip* ms = dynamic_cast<MixerStrip*> (r);
                if (ms) {
-                       ms->step_gain_up ();
+                       boost::shared_ptr<GainControl> ac (ms->route()->gain_control());
+                       ControlList cl (ac->grouped_controls());
+                       for (ControlList::const_iterator c = cl.begin(); c != cl.end (); ++c) {
+                               rv.insert (*c);
+                       }
+                       rv.insert (ac);
                }
        }
+       return rv;
 }
 
 void
-Mixer_UI::step_gain_down_action ()
+Mixer_UI::step_gain_up_action ()
 {
-       set_axis_targets_for_operation ();
+       AutomationControlSet acs = selected_gaincontrols ();
+       for (AutomationControlSet::const_iterator i = acs.begin(); i != acs.end (); ++i) {
+               boost::shared_ptr<GainControl> ac = boost::dynamic_pointer_cast<GainControl> (*i);
+               assert (ac);
+               ac->set_value (dB_to_coefficient (accurate_coefficient_to_dB (ac->get_value()) + 0.1), Controllable::NoGroup);
+       }
+}
 
-       BOOST_FOREACH(AxisView* r, _axis_targets) {
-               MixerStrip* ms = dynamic_cast<MixerStrip*> (r);
-               if (ms) {
-                       ms->step_gain_down ();
-               }
+void
+Mixer_UI::step_gain_down_action ()
+{
+       AutomationControlSet acs = selected_gaincontrols ();
+       for (AutomationControlSet::const_iterator i = acs.begin(); i != acs.end (); ++i) {
+               boost::shared_ptr<GainControl> ac = boost::dynamic_pointer_cast<GainControl> (*i);
+               assert (ac);
+               ac->set_value (dB_to_coefficient (accurate_coefficient_to_dB (ac->get_value()) - 0.1), Controllable::NoGroup);
        }
 }