; (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")
; (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" "")
(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" "")
<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'/>
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);
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 ();
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)));
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;
}
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);
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)
{
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)
{
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);
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>));
REGISTER_ENUM (SyncPoint);
REGISTER (_RegionPoint);
-
REGISTER_ENUM (PreFader);
REGISTER_ENUM (PostFader);
REGISTER (_Placement);
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;
+}
+
/***********************************************************************/