Merge with 2.0-ongoing R2943.
[ardour.git] / gtk2_ardour / editor_ops.cc
index 4919091a620b0625c10a9854a98603fc7048d25b..33a0e6920c1334bed219f436850083174774abd0 100644 (file)
@@ -49,6 +49,7 @@
 #include <ardour/region_factory.h>
 #include <ardour/playlist_factory.h>
 #include <ardour/reverse.h>
+#include <ardour/dB.h>
 #include <ardour/quantize.h>
 
 #include "ardour_ui.h"
@@ -65,6 +66,8 @@
 #include "editing.h"
 #include "gtk-custom-hruler.h"
 #include "gui_thread.h"
+#include "keyboard.h"
+#include "utils.h"
 
 #include "i18n.h"
 
@@ -330,16 +333,38 @@ Editor::extend_selection_to_start_of_region (bool previous)
        commit_reversible_command ();
 }
 
+bool
+Editor::nudge_forward_release (GdkEventButton* ev)
+{
+       if (ev->state & Keyboard::PrimaryModifier) {
+               nudge_forward (false, true);
+       } else {
+               nudge_forward (false, false);
+       }
+       return false;
+}
+
+bool
+Editor::nudge_backward_release (GdkEventButton* ev)
+{
+       if (ev->state & Keyboard::PrimaryModifier) {
+               nudge_backward (false, true);
+       } else {
+               nudge_backward (false, false);
+       }
+       return false;
+}
+
 
 void
-Editor::nudge_forward (bool next)
+Editor::nudge_forward (bool next, bool force_playhead)
 {
        nframes_t distance;
        nframes_t next_distance;
 
        if (!session) return;
        
-       if (!selection->regions.empty()) {
+       if (!force_playhead && !selection->regions.empty()) {
 
                begin_reversible_command (_("nudge regions forward"));
 
@@ -361,7 +386,7 @@ Editor::nudge_forward (bool next)
                commit_reversible_command ();
 
                
-       } else if (!selection->markers.empty()) {
+       } else if (!force_playhead && !selection->markers.empty()) {
 
                bool is_start;
                Location* loc = find_location_from_marker (selection->markers.front(), is_start);
@@ -405,14 +430,14 @@ Editor::nudge_forward (bool next)
 }
                
 void
-Editor::nudge_backward (bool next)
+Editor::nudge_backward (bool next, bool force_playhead)
 {
        nframes_t distance;
        nframes_t next_distance;
 
        if (!session) return;
        
-       if (!selection->regions.empty()) {
+       if (!force_playhead && !selection->regions.empty()) {
 
                begin_reversible_command (_("nudge regions backward"));
 
@@ -438,7 +463,7 @@ Editor::nudge_backward (bool next)
 
                commit_reversible_command ();
 
-       } else if (!selection->markers.empty()) {
+       } else if (!force_playhead && !selection->markers.empty()) {
 
                bool is_start;
                Location* loc = find_location_from_marker (selection->markers.front(), is_start);
@@ -1515,6 +1540,12 @@ Editor::temporal_zoom (gdouble fpu)
        double nfpu;
        double l;
 
+       /* XXX this limit is also in ::set_frames_per_unit() */
+
+       if (frames_per_unit <= 2.0 && fpu <= frames_per_unit) {
+               return;
+       }
+
        nfpu = fpu;
        
        new_page_size = (nframes_t) floor (canvas_width * nfpu);
@@ -1549,7 +1580,7 @@ Editor::temporal_zoom (gdouble fpu)
                where = playhead_cursor->current_frame;
                
                l = - ((new_page_size * ((where - current_leftmost)/(double)current_page)) - where);
-               
+
                if (l < 0) {
                        leftmost_after_zoom = 0;
                } else if (l > max_frames) { 
@@ -2595,6 +2626,9 @@ Editor::separate_regions_between (const TimeSelection& ts)
 
        sort_track_selection (&tmptracks);
 
+
+
+
        for (TrackSelection::iterator i = tmptracks.begin(); i != tmptracks.end(); ++i) {
 
                RouteTimeAxisView* rtv;
@@ -3298,16 +3332,14 @@ Editor::trim_region_from_edit_point ()
        commit_reversible_command ();
 }
 
-/** Unfreeze selected routes */
 void
-Editor::unfreeze_routes ()
+Editor::unfreeze_route ()
 {
-       for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
-               AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*>(*i);
-               if (atv && atv->is_audio_track()) {
-                       atv->audio_track()->unfreeze ();
-               }
+       if (clicked_routeview == 0 || !clicked_routeview->is_audio_track()) {
+               return;
        }
+       
+       clicked_routeview->audio_track()->unfreeze ();
 }
 
 void*
@@ -3320,15 +3352,7 @@ Editor::_freeze_thread (void* arg)
 void*
 Editor::freeze_thread ()
 {
-       for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
-               AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*>(*i);
-               if (atv && atv->is_audio_track()) {
-                       atv->audio_track()->freeze (*current_interthread_info);
-               }
-       }
-
-       current_interthread_info->done = true;
-       
+       clicked_routeview->audio_track()->freeze (*current_interthread_info);
        return 0;
 }
 
@@ -3339,10 +3363,13 @@ Editor::freeze_progress_timeout (void *arg)
        return !(current_interthread_info->done || current_interthread_info->cancel);
 }
 
-/** Freeze selected routes */
 void
-Editor::freeze_routes ()
+Editor::freeze_route ()
 {
+       if (clicked_routeview == 0 || !clicked_routeview->is_audio_track()) {
+               return;
+       }
+       
        InterThreadInfo itt;
 
        if (interthread_progress_window == 0) {
@@ -3991,7 +4018,7 @@ Editor::clear_playlist (boost::shared_ptr<Playlist> playlist)
 }
 
 void
-Editor::nudge_selected_tracks (bool use_edit, bool forwards)
+Editor::nudge_track (bool use_edit, bool forwards)
 {
        boost::shared_ptr<Playlist> playlist; 
        nframes_t distance;
@@ -4058,7 +4085,7 @@ Editor::remove_last_capture ()
 }
 
 void
-Editor::normalize_regions ()
+Editor::normalize_region ()
 {
        if (!session) {
                return;
@@ -4088,12 +4115,14 @@ Editor::normalize_regions ()
 
 
 void
-Editor::denormalize_regions ()
+Editor::denormalize_region ()
 {
        if (!session) {
                return;
        }
 
+       ExclusiveRegionSelection (*this, entered_regionview);
+
        if (selection->regions.empty()) {
                return;
        }
@@ -4112,9 +4141,65 @@ Editor::denormalize_regions ()
        commit_reversible_command ();
 }
 
+void
+Editor::adjust_region_scale_amplitude (bool up)
+{
+       if (!session) {
+               return;
+       }
+
+       ExclusiveRegionSelection (*this, entered_regionview);
+
+       if (selection->regions.empty()) {
+               return;
+       }
+
+       begin_reversible_command ("denormalize");
+
+       for (RegionSelection::iterator r = selection->regions.begin(); r != selection->regions.end(); ++r) {
+               AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*r);
+               if (!arv)
+                       continue;
+               XMLNode &before = arv->region()->get_state();
+               
+               double fraction = gain_to_slider_position (arv->audio_region()->scale_amplitude ());
+               
+               cerr << "slider pos for " << arv->audio_region()->scale_amplitude ()
+                    << " = " << fraction
+                    << endl;
+
+               if (up) {
+                       fraction += 0.05;
+                       fraction = min (fraction, 1.0);
+               } else {
+                       fraction -= 0.05;
+                       fraction = max (fraction, 0.0);
+               }
+
+               if (!up && fraction <= 0) {
+                       continue;
+               }
+
+               if (up && fraction >= 1.0) {
+                       continue;
+               }
+
+               fraction = slider_position_to_gain (fraction);
+               fraction = coefficient_to_dB (fraction);
+               fraction = dB_to_coefficient (fraction);
+               
+               cerr << "set scale amp for " << arv->audio_region()->name() << " to " << fraction << endl;
+
+               arv->audio_region()->set_scale_amplitude (fraction);
+               session->add_command (new MementoCommand<Region>(*(arv->region().get()), &before, &arv->region()->get_state()));
+       }
+
+       commit_reversible_command ();
+}
+
 
 void
-Editor::reverse_regions ()
+Editor::reverse_region ()
 {
        if (!session) {
                return;
@@ -4126,7 +4211,7 @@ Editor::reverse_regions ()
 
 
 void
-Editor::quantize_regions ()
+Editor::quantize_region ()
 {
        if (!session) {
                return;
@@ -4270,10 +4355,7 @@ Editor::toggle_gain_envelope_visibility ()
        for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
                AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i);
                if (arv) {
-                       bool x = region_envelope_visible_item->get_active();
-                       if (x != arv->envelope_visible()) {
-                               arv->set_envelope_visible (x);
-                       }
+                       arv->set_envelope_visible (!arv->envelope_visible());
                }
        }
 }
@@ -4284,28 +4366,7 @@ Editor::toggle_gain_envelope_active ()
        for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
                AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i);
                if (arv) {
-                       bool x = region_envelope_active_item->get_active();
-                       if (x != arv->audio_region()->envelope_active()) {
-                               arv->audio_region()->set_envelope_active (x);
-                       }
-               }
-       }
-}
-
-/** Set the position-locked state of all selected regions to a particular value.
- * @param yn true to make locked, false to make unlocked.
- */
-void
-Editor::toggle_region_position_lock ()
-{
-       bool x = region_lock_position_item->get_active();
-
-       for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
-               AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i);
-               if (arv) {
-                       if (x != arv->audio_region()->locked()) {
-                               arv->audio_region()->set_position_locked (x);
-                       }
+                       arv->audio_region()->set_envelope_active (!arv->audio_region()->envelope_active());
                }
        }
 }
@@ -4313,45 +4374,24 @@ Editor::toggle_region_position_lock ()
 void
 Editor::toggle_region_lock ()
 {
-       bool x = region_lock_item->get_active();
-
        for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
-               AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i);
-               if (arv) {
-                       if (x != arv->audio_region()->locked()) {
-                               arv->audio_region()->set_locked (x);
-                       }
-               }
+               (*i)->region()->set_locked (!(*i)->region()->locked());
        }
 }
 
 void
 Editor::toggle_region_mute ()
 {
-       bool x = region_mute_item->get_active();
-
        for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
-               AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i);
-               if (arv) {
-                       if (x != arv->audio_region()->muted()) {
-                               arv->audio_region()->set_muted (x);
-                       }
-               }
+               (*i)->region()->set_muted (!(*i)->region()->muted());
        }
 }
 
 void
 Editor::toggle_region_opaque ()
 {
-       bool x = region_opaque_item->get_active();
-
        for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
-               AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i);
-               if (arv) {
-                       if (x != arv->audio_region()->opaque()) {
-                               arv->audio_region()->set_opaque (x);
-                       }
-               }
+               (*i)->region()->set_opaque (!(*i)->region()->opaque());
        }
 }