provide support for playhead-to-next/previous-region-boundary actions, and bindings...
authorPaul Davis <paul@linuxaudiosystems.com>
Wed, 28 Nov 2007 03:29:53 +0000 (03:29 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Wed, 28 Nov 2007 03:29:53 +0000 (03:29 +0000)
git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@2719 d708f5d6-7413-0410-9779-e7cbd77b26cf

gtk2_ardour/ardour-sae.bindings.in
gtk2_ardour/ardour-sae.menus
gtk2_ardour/editor.h
gtk2_ardour/editor_actions.cc
gtk2_ardour/editor_ops.cc
gtk2_ardour/route_time_axis.cc
gtk2_ardour/route_time_axis.h
libs/ardour/ardour/playlist.h
libs/ardour/enums.cc
libs/ardour/playlist.cc

index 4c1ec31fe06b6b2d3137b0cc8fbc17f435eabdac..bb0923e80af9768bbf97b680ca2c2b6a0cb8672b 100644 (file)
@@ -9,7 +9,6 @@
 ; (gtk_accel_path "<Actions>/JACK/JACKReconnect" "")
 ; (gtk_accel_path "<Actions>/Editor/Autoconnect" "")
 ; (gtk_accel_path "<Actions>/Editor/Edit" "")
-(gtk_accel_path "<Actions>/Editor/playhead-to-previous-region-end" "<%PRIMARY%>comma")
 (gtk_accel_path "<Actions>/Editor/cycle-edit-point" "grave")
 (gtk_accel_path "<Actions>/Editor/toggle-edit-mode" "1")
 (gtk_accel_path "<Actions>/Editor/cycle-snap-mode" "2")
@@ -28,7 +27,7 @@
 ; (gtk_accel_path "<Actions>/options/MeterFalloffSlow" "")
 ; (gtk_accel_path "<Actions>/RegionList/rlHide" "")
 ; (gtk_accel_path "<Actions>/Main/Metering" "")
-(gtk_accel_path "<Actions>/Editor/playhead-to-next-region-end" "<%PRIMARY%>period")
+(gtk_accel_path "<Actions>/Editor/playhead-to-next-region-boundary" "period")
 ; (gtk_accel_path "<Actions>/Zoom/zoom-focus-playhead" "")
 ; (gtk_accel_path "<Actions>/Editor/center-edit-cursor" "")
 ; (gtk_accel_path "<Actions>/Editor/Monitoring" "")
@@ -99,7 +98,7 @@
 (gtk_accel_path "<Actions>/Editor/set-edit-point" "o")
 ; (gtk_accel_path "<Actions>/Editor/Smpte30drop" "")
 ; (gtk_accel_path "<Actions>/Zoom/zoom-focus-edit" "")
-(gtk_accel_path "<Actions>/Editor/playhead-to-previous-region-start" "comma")
+(gtk_accel_path "<Actions>/Editor/playhead-to-previous-region-boundary" "comma")
 ; (gtk_accel_path "<Actions>/Editor/EditCursorMovementOptions" "")
 ; (gtk_accel_path "<Actions>/redirectmenu/activate_all" "")
 ; (gtk_accel_path "<Actions>/redirectmenu/paste" "")
 ; (gtk_accel_path "<Actions>/options/VerifyRemoveLastCapture" "")
 ; (gtk_accel_path "<Actions>/options/OutputAutoConnectPhysical" "")
 (gtk_accel_path "<Actions>/Editor/step-tracks-up" "uparrow")
-(gtk_accel_path "<Actions>/Editor/playhead-to-next-region-start" "period")
 ; (gtk_accel_path "<Actions>/options/SendMMC" "")
 ; (gtk_accel_path "<Actions>/Editor/toggle-auto-xfades" "")
 ; (gtk_accel_path "<Actions>/Main/AudioFileFormatHeader" "")
index 188ccf85fb36c1b196d51bbc54d1ba1e6788d5b4..ba88f555f089a2ef4a9de86395c59f53755acdd8 100644 (file)
                <menuitem action='jump-backward-to-mark'/>
                <menuitem action='add-location-from-playhead'/>
                <separator/> 
-               <menuitem action='playhead-to-next-region-start'/>
-               <menuitem action='playhead-to-next-region-end'/>
-               <menuitem action='playhead-to-previous-region-start'/>
-               <menuitem action='playhead-to-previous-region-end'/>
+               <menuitem action='playhead-to-next-region-boundary'/>
+               <menuitem action='playhead-to-previous-region-boundary'/>
                <menuitem action='playhead-to-next-region-sync'/>
                <menuitem action='playhead-to-previous-region-sync'/>
                <menuitem action='center-playhead'/>
index d7a14d33cb34c6a537fb7026e0b8edfd2856f546..1f64e4d2e585f29ebb214e0c9e9cabfac59404d4 100644 (file)
@@ -656,6 +656,9 @@ class Editor : public PublicEditor
        Cursor* playhead_cursor;
        ArdourCanvas::Group* cursor_group;
 
+       void    cursor_to_region_boundary (Cursor*, int32_t dir);
+       void    cursor_to_next_region_boundary (Cursor*);
+       void    cursor_to_previous_region_boundary (Cursor*);
        void    cursor_to_next_region_point (Cursor*, ARDOUR::RegionPoint);
        void    cursor_to_previous_region_point (Cursor*, ARDOUR::RegionPoint);
        void    cursor_to_region_point (Cursor*, ARDOUR::RegionPoint, int32_t dir);
@@ -674,6 +677,7 @@ class Editor : public PublicEditor
        void    select_range_between ();
 
        boost::shared_ptr<ARDOUR::Region> find_next_region (nframes_t, ARDOUR::RegionPoint, int32_t dir, TrackViewList&, TimeAxisView ** = 0);
+       nframes64_t find_next_region_boundary (nframes64_t, int32_t dir, const TrackViewList&);
 
        vector<nframes_t> region_boundary_cache;
        void build_region_boundary_cache ();
index 0141e2a7cee6149f9c50b13a43fd7660011e7385..074cf899119ce5fa613df655846b4e5ba9506731 100644 (file)
@@ -84,6 +84,11 @@ Editor::register_actions ()
        act = ActionManager::register_toggle_action (editor_actions, "toggle-auto-xfades", _("Created Automatically"), mem_fun(*this, &Editor::toggle_auto_xfade));
        ActionManager::session_sensitive_actions.push_back (act);
 
+       act = ActionManager::register_action (editor_actions, "playhead-to-next-region-boundary", _("Playhead to Next Region Boundary"), bind (mem_fun(*this, &Editor::cursor_to_next_region_boundary), playhead_cursor));
+       ActionManager::session_sensitive_actions.push_back (act);
+       act = ActionManager::register_action (editor_actions, "playhead-to-previous-region-boundary", _("Playhead to Previous Region Boundary"), bind (mem_fun(*this, &Editor::cursor_to_previous_region_boundary), playhead_cursor));
+       ActionManager::session_sensitive_actions.push_back (act);
+
        act = ActionManager::register_action (editor_actions, "playhead-to-next-region-start", _("Playhead to Next Region Start"), bind (mem_fun(*this, &Editor::cursor_to_next_region_point), playhead_cursor, RegionPoint (Start)));
        ActionManager::session_sensitive_actions.push_back (act);
        act = ActionManager::register_action (editor_actions, "playhead-to-next-region-end", _("Playhead to Next Region End"), bind (mem_fun(*this, &Editor::cursor_to_next_region_point), playhead_cursor, RegionPoint (End)));
index 15ed822d4312fa684225ce7afe0c42f81717a3d0..27af0bd93e61115077317b4f0de407716b2d852f 100644 (file)
@@ -555,12 +555,15 @@ Editor::build_region_boundary_cache ()
                        case Start:
                                rpos = r->first_frame();
                                break;
+
                        case End:
                                rpos = r->last_frame();
                                break;  
+
                        case SyncPoint:
                                rpos = r->adjust_to_sync (r->first_frame());
                                break;
+
                        default:
                                break;
                        }
@@ -647,6 +650,7 @@ Editor::find_next_region (nframes_t frame, RegionPoint point, int32_t dir, Track
                        rpos = r->adjust_to_sync (r->first_frame());
                        break;
                }
+
                // rpos is a "track frame", converting it to "session frame"
                rpos = track_frame_to_session_frame(rpos, track_speed);
 
@@ -667,6 +671,84 @@ Editor::find_next_region (nframes_t frame, RegionPoint point, int32_t dir, Track
        return ret;
 }
 
+nframes64_t
+Editor::find_next_region_boundary (nframes64_t pos, int32_t dir, const TrackViewList& tracks)
+{
+       nframes64_t distance = max_frames;
+       nframes64_t current_nearest = -1;
+
+       for (TrackViewList::const_iterator i = tracks.begin(); i != tracks.end(); ++i) {
+               nframes64_t contender;
+               nframes64_t d;
+
+               RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (*i);
+
+               if (!rtv) {
+                       continue;
+               }
+
+               if ((contender = rtv->find_next_region_boundary (pos, dir)) < 0) {
+                       continue;
+               }
+
+               d = ::llabs (pos - contender);
+
+               if (d < distance) {
+                       current_nearest = contender;
+                       distance = d;
+               }
+       }
+       
+       return current_nearest;
+}
+
+void
+Editor::cursor_to_region_boundary (Cursor* cursor, int32_t dir)
+{
+       nframes64_t pos = cursor->current_frame;
+       nframes64_t target;
+
+       if (!session) {
+               return;
+       }
+
+       // so we don't find the current region again..
+       if (dir > 0 || pos > 0) {
+               pos += dir;
+       }
+
+       if (!selection->tracks.empty()) {
+               
+               target = find_next_region_boundary (pos, dir, selection->tracks);
+               
+       } else {
+               
+               target = find_next_region_boundary (pos, dir, track_views);
+       }
+       
+       if (target < 0) {
+               return;
+       }
+
+       if (cursor == playhead_cursor) {
+               session->request_locate (target);
+       } else {
+               cursor->set_position (target);
+       }
+}
+
+void
+Editor::cursor_to_next_region_boundary (Cursor* cursor)
+{
+       cursor_to_region_boundary (cursor, 1);
+}
+
+void
+Editor::cursor_to_previous_region_boundary (Cursor* cursor)
+{
+       cursor_to_region_boundary (cursor, -1);
+}
+
 void
 Editor::cursor_to_region_point (Cursor* cursor, RegionPoint point, int32_t dir)
 {
index d7eeceafed0f399b7827e18e4f7c34e1c8837f22..0f2cf4ddd14179932ab98e12ef44d6ce690758e0 100644 (file)
@@ -1180,6 +1180,19 @@ RouteTimeAxisView::find_next_region (nframes_t pos, RegionPoint point, int32_t d
        return boost::shared_ptr<Region> ();
 }
 
+nframes64_t 
+RouteTimeAxisView::find_next_region_boundary (nframes64_t pos, int32_t dir)
+{
+       boost::shared_ptr<Diskstream> stream;
+       boost::shared_ptr<Playlist> playlist;
+
+       if ((stream = get_diskstream()) != 0 && (playlist = stream->playlist()) != 0) {
+               return playlist->find_next_region_boundary (pos, dir);
+       }
+
+       return -1;
+}
+
 bool
 RouteTimeAxisView::cut_copy_clear (Selection& selection, CutCopyOp op)
 {
index 672236a7e51079b30a1458d958cb5de16569ebe8..41599690730432ffd13f96fd08444de9080c62f0 100644 (file)
@@ -82,6 +82,7 @@ public:
        void get_inverted_selectables (Selection&, list<Selectable*>&);
                
        boost::shared_ptr<ARDOUR::Region> find_next_region (nframes_t pos, ARDOUR::RegionPoint, int32_t dir);
+       nframes64_t find_next_region_boundary (nframes64_t pos, int32_t dir);
 
        /* Editing operations */
        bool cut_copy_clear (Selection&, Editing::CutCopyOp);
index fab29b0c20c34b74c9e5edaccd9dc481ae53aaac..1161afbd9d7ab1f46cf9bfd814338243e957bc0c 100644 (file)
@@ -103,6 +103,7 @@ class Playlist : public PBD::StatefulDestructible, public boost::enable_shared_f
        boost::shared_ptr<Region>  find_region (const PBD::ID&) const;
        boost::shared_ptr<Region>  top_region_at (nframes_t frame);
        boost::shared_ptr<Region>  find_next_region (nframes_t frame, RegionPoint point, int dir);
+       nframes64_t                find_next_region_boundary (nframes64_t frame, int dir);
 
        template<class T> void foreach_region (T *t, void (T::*func)(boost::shared_ptr<Region>, void *), void *arg);
        template<class T> void foreach_region (T *t, void (T::*func)(boost::shared_ptr<Region>));
index 068aec654d5dfcdf5f6c00b28215aa9b6dd020f8..2f119918cc08cde45701056b38686d3c66af835d 100644 (file)
@@ -153,7 +153,6 @@ setup_enum_writer ()
        REGISTER_ENUM (SyncPoint);      
        REGISTER (_RegionPoint);
 
-
        REGISTER_ENUM (PreFader);
        REGISTER_ENUM (PostFader);
        REGISTER (_Placement);
index 37c7a4e5c8fb6f68c1cf941698d55482fcf6f6af..2833aa4dcc4dabb46c0935a6ee3ec82b306bc82a 100644 (file)
@@ -1464,6 +1464,91 @@ Playlist::find_next_region (nframes_t frame, RegionPoint point, int dir)
        return ret;
 }
 
+nframes64_t
+Playlist::find_next_region_boundary (nframes64_t frame, int dir)
+{
+       RegionLock rlock (this);
+
+       nframes64_t closest = max_frames;
+       nframes64_t ret = -1;
+
+       if (dir > 0) {
+
+               for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
+                       
+                       boost::shared_ptr<Region> r = (*i);
+                       nframes64_t distance;
+                       bool reset;
+
+                       reset = false;
+
+                       if (r->first_frame() > frame) {
+
+                               distance = r->first_frame() - frame;
+                               
+                               if (distance < closest) {
+                                       ret = r->first_frame();
+                                       closest = distance;
+                                       reset = true;
+                               }
+                       }
+
+                       if (r->last_frame() > frame) {
+                               
+                               distance = r->last_frame() - frame;
+                               
+                               if (distance < closest) {
+                                       ret = r->last_frame();
+                                       closest = distance;
+                                       reset = true;
+                               }
+                       }
+
+                       if (reset) {
+                               break;
+                       }
+               }
+
+       } else {
+
+               for (RegionList::const_reverse_iterator i = regions.rbegin(); i != regions.rend(); ++i) {
+                       
+                       boost::shared_ptr<Region> r = (*i);
+                       nframes64_t distance;
+                       bool reset;
+
+                       reset = false;
+
+                       if (r->last_frame() < frame) {
+
+                               distance = frame - r->last_frame();
+                               
+                               if (distance < closest) {
+                                       ret = r->last_frame();
+                                       closest = distance;
+                                       reset = true;
+                               }
+                       }
+
+                       if (r->first_frame() < frame) {
+                               distance = frame - r->last_frame();
+                               
+                               if (distance < closest) {
+                                       ret = r->first_frame();
+                                       closest = distance;
+                                       reset = true;
+                               }
+                       }
+
+                       if (reset) {
+                               break;
+                       }
+               }
+       }
+
+       return ret;
+}
+
 /***********************************************************************/