summaryrefslogtreecommitdiff
path: root/gtk2_ardour
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2007-11-07 17:05:46 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2007-11-07 17:05:46 +0000
commit998771e57d4687c0937fe1c36b294d4f075b6d3c (patch)
treec2b4443cf23dbe71c0c2e60eb3ea47377f2f97ea /gtk2_ardour
parent5cd58a2e8bbc7e3d2face30ad0bf8e307ab395fa (diff)
initial round of work to support new edit point option, and removal of edit cursor
git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@2605 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'gtk2_ardour')
-rw-r--r--gtk2_ardour/editing.h11
-rw-r--r--gtk2_ardour/editing_syms.h3
-rw-r--r--gtk2_ardour/editor.cc120
-rw-r--r--gtk2_ardour/editor.h30
-rw-r--r--gtk2_ardour/editor_actions.cc53
-rw-r--r--gtk2_ardour/editor_audio_import.cc8
-rw-r--r--gtk2_ardour/editor_markers.cc8
-rw-r--r--gtk2_ardour/editor_mouse.cc33
-rw-r--r--gtk2_ardour/editor_ops.cc62
-rw-r--r--gtk2_ardour/enums.cc6
-rw-r--r--gtk2_ardour/marker_selection.h31
-rw-r--r--gtk2_ardour/public_editor.h10
-rw-r--r--gtk2_ardour/selection.cc52
-rw-r--r--gtk2_ardour/selection.h10
14 files changed, 348 insertions, 89 deletions
diff --git a/gtk2_ardour/editing.h b/gtk2_ardour/editing.h
index ee9b030f4f..bfb9b49ee6 100644
--- a/gtk2_ardour/editing.h
+++ b/gtk2_ardour/editing.h
@@ -35,6 +35,7 @@
#define IMPORTMODE(a) /*empty*/
#define IMPORTPOSITION(a) /*empty*/
#define IMPORTDISPOSITION(a) /*empty*/
+#define EDITPOINT(a) /*empty*/
namespace Editing {
@@ -152,6 +153,16 @@ enum ImportDisposition {
#undef IMPORTDISPOSITION
#define IMPORTDISPOSITION(a) /*empty*/
+// EDITPOINT
+#undef EDITPOINT
+#define EDITPOINT(a) a,
+enum EditPoint {
+ #include "editing_syms.h"
+};
+
+#undef EDITPOINT
+#define EDITPOINT(a) /*empty*/
+
/////////////////////
// These don't need their state saved. yet...
enum CutCopyOp {
diff --git a/gtk2_ardour/editing_syms.h b/gtk2_ardour/editing_syms.h
index ceedabb76d..0182752337 100644
--- a/gtk2_ardour/editing_syms.h
+++ b/gtk2_ardour/editing_syms.h
@@ -92,3 +92,6 @@ IMPORTDISPOSITION(ImportMergeFiles=1)
IMPORTDISPOSITION(ImportSerializeFiles=2)
IMPORTDISPOSITION(ImportDistinctChannels=3)
+EDITPOINT(EditAtPlayhead)
+EDITPOINT(EditAtSelectedMarker)
+EDITPOINT(EditAtMouse)
diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc
index 263be3c8c4..844fea9905 100644
--- a/gtk2_ardour/editor.cc
+++ b/gtk2_ardour/editor.cc
@@ -135,6 +135,13 @@ static const gchar *_snap_mode_strings[] = {
0
};
+static const gchar *_edit_point_strings[] = {
+ N_("Playhead"),
+ N_("Marker"),
+ N_("Mouse"),
+ 0
+};
+
static const gchar *_zoom_focus_strings[] = {
N_("Left"),
N_("Right"),
@@ -164,20 +171,6 @@ show_me_the_size (Requisition* r, const char* what)
cerr << "size of " << what << " = " << r->width << " x " << r->height << endl;
}
-void
-check_adjustment (Gtk::Adjustment* adj)
-{
- cerr << "CHANGE adj = "
- << adj->get_lower () << ' '
- << adj->get_upper () << ' '
- << adj->get_value () << ' '
- << adj->get_step_increment () << ' '
- << adj->get_page_increment () << ' '
- << adj->get_page_size () << ' '
- << endl;
-
-}
-
Editor::Editor ()
:
/* time display buttons */
@@ -246,14 +239,20 @@ Editor::Editor ()
current_mixer_strip = 0;
current_bbt_points = 0;
- snap_type_strings = I18N (_snap_type_strings);
- snap_mode_strings = I18N (_snap_mode_strings);
- zoom_focus_strings = I18N(_zoom_focus_strings);
+ snap_type_strings = I18N (_snap_type_strings);
+ snap_mode_strings = I18N (_snap_mode_strings);
+ zoom_focus_strings = I18N (_zoom_focus_strings);
+ edit_point_strings = I18N (_edit_point_strings);
snap_type = SnapToFrame;
set_snap_to (snap_type);
+
snap_mode = SnapNormal;
set_snap_mode (snap_mode);
+
+ _edit_point = EditAtMouse;
+ set_edit_point (_edit_point);
+
snap_threshold = 5.0;
bbt_beat_subdivision = 4;
canvas_width = 0;
@@ -318,7 +317,6 @@ Editor::Editor ()
_dragging_playhead = false;
_dragging_hscrollbar = false;
- _scrubbing = false;
scrubbing_direction = 0;
sfbrowser = 0;
@@ -1405,7 +1403,7 @@ Editor::popup_track_context_menu (int button, int32_t time, ItemType item_type,
case RegionViewNameHighlight:
if (!with_selection) {
if (region_edit_menu_split_item) {
- if (clicked_regionview && clicked_regionview->region()->covers (edit_cursor->current_frame)) {
+ if (clicked_regionview && clicked_regionview->region()->covers (get_preferred_edit_position())) {
ActionManager::set_sensitive (ActionManager::edit_cursor_in_region_sensitive_actions, true);
} else {
ActionManager::set_sensitive (ActionManager::edit_cursor_in_region_sensitive_actions, false);
@@ -2064,6 +2062,18 @@ Editor::set_snap_mode (SnapMode mode)
instant_save ();
}
+void
+Editor::set_edit_point (EditPoint ep)
+{
+ _edit_point = ep;
+ string str = edit_point_strings[(int)ep];
+
+ if (str != edit_point_selector.get_active_text ()) {
+ edit_point_selector.set_active_text (str);
+ }
+
+ instant_save ();
+}
int
Editor::set_state (const XMLNode& node)
@@ -2141,6 +2151,10 @@ Editor::set_state (const XMLNode& node)
set_snap_mode ((SnapMode) atoi (prop->value()));
}
+ if ((prop = node.property ("edit-point"))) {
+ set_edit_point ((EditPoint) string_2_enum (prop->value(), _edit_point));
+ }
+
if ((prop = node.property ("mouse-mode"))) {
MouseMode m = str2mousemode(prop->value());
mouse_mode = MouseMode ((int) m + 1); /* lie, force mode switch */
@@ -2276,6 +2290,8 @@ Editor::get_state ()
snprintf (buf, sizeof(buf), "%d", (int) snap_mode);
node->add_property ("snap-mode", buf);
+ node->add_property ("edit-point", enum_2_string (_edit_point));
+
snprintf (buf, sizeof (buf), "%" PRIu32, playhead_cursor->current_frame);
node->add_property ("playhead", buf);
snprintf (buf, sizeof (buf), "%" PRIu32, edit_cursor->current_frame);
@@ -2437,7 +2453,7 @@ Editor::snap_to (nframes64_t& start, int32_t direction, bool for_mark)
break;
case SnapToEditCursor:
- start = edit_cursor->current_frame;
+ start = get_preferred_edit_position ();
break;
case SnapToMark:
@@ -2670,17 +2686,24 @@ Editor::setup_toolbar ()
Gtkmm2ext::set_size_request_to_display_given_text (snap_type_selector, "SMPTE Seconds", 2+FUDGE, 10);
set_popdown_strings (snap_type_selector, snap_type_strings);
snap_type_selector.signal_changed().connect (mem_fun(*this, &Editor::snap_type_selection_done));
- ARDOUR_UI::instance()->tooltips().set_tip (snap_type_selector, _("Unit to snap cursors and ranges to"));
+ ARDOUR_UI::instance()->tooltips().set_tip (snap_type_selector, _("Snap/Grid Units"));
snap_mode_selector.set_name ("SnapModeSelector");
Gtkmm2ext::set_size_request_to_display_given_text (snap_mode_selector, "Magnetic Snap", 2+FUDGE, 10);
set_popdown_strings (snap_mode_selector, snap_mode_strings);
snap_mode_selector.signal_changed().connect (mem_fun(*this, &Editor::snap_mode_selection_done));
+ ARDOUR_UI::instance()->tooltips().set_tip (snap_mode_selector, _("Snap/Grid Mode"));
+
+ edit_point_selector.set_name ("SnapModeSelector");
+ Gtkmm2ext::set_size_request_to_display_given_text (edit_point_selector, "Playhead", 2+FUDGE, 10);
+ set_popdown_strings (edit_point_selector, edit_point_strings);
+ edit_point_selector.signal_changed().connect (mem_fun(*this, &Editor::edit_point_selection_done));
+ ARDOUR_UI::instance()->tooltips().set_tip (edit_point_selector, _("Edit point"));
snap_box.pack_start (edit_cursor_clock, false, false);
snap_box.pack_start (snap_mode_selector, false, false);
snap_box.pack_start (snap_type_selector, false, false);
-
+ snap_box.pack_start (edit_point_selector, false, false);
/* Nudge */
@@ -2750,8 +2773,6 @@ Editor::convert_drop_to_paths (vector<ustring>& paths,
vector<ustring> uris = data.get_uris();
- cerr << "there were " << uris.size() << " in that drag data\n";
-
if (uris.empty()) {
/* This is seriously fucked up. Nautilus doesn't say that its URI lists
@@ -3136,6 +3157,27 @@ Editor::snap_mode_selection_done ()
}
void
+Editor::edit_point_selection_done ()
+{
+ string choice = edit_point_selector.get_active_text();
+ EditPoint ep = EditAtSelectedMarker;
+
+ if (choice == _("Marker")) {
+ _edit_point = EditAtSelectedMarker;
+ } else if (choice == _("Playhead")) {
+ _edit_point = EditAtPlayhead;
+ } else {
+ _edit_point = EditAtMouse;
+ }
+
+ RefPtr<RadioAction> ract = edit_point_action (ep);
+
+ if (ract) {
+ ract->set_active (true);
+ }
+}
+
+void
Editor::zoom_focus_selection_done ()
{
string choice = zoom_focus_selector.get_active_text();
@@ -3938,6 +3980,36 @@ Editor::edit_cursor_position(bool sync)
return edit_cursor->current_frame;
}
+nframes64_t
+Editor::get_preferred_edit_position() const
+{
+ bool ignored;
+ nframes64_t where;
+
+ switch (_edit_point) {
+ case EditAtPlayhead:
+ return playhead_cursor->current_frame;
+
+ case EditAtSelectedMarker:
+ if (!selection->markers.empty()) {
+ bool whocares;
+ Location* loc = find_location_from_marker (selection->markers.front(), whocares);
+ if (loc) {
+ return loc->start();
+ }
+ }
+ /* fallthru */
+
+ default:
+ case EditAtMouse:
+ if (mouse_frame (where, ignored)) {
+ return where;
+ }
+ }
+
+ return -1;
+}
+
void
Editor::set_loop_range (nframes_t start, nframes_t end, string cmd)
{
diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h
index e494780ba1..ac36ee1d3b 100644
--- a/gtk2_ardour/editor.h
+++ b/gtk2_ardour/editor.h
@@ -176,15 +176,15 @@ class Editor : public PublicEditor
/* undo related */
- nframes_t unit_to_frame (double unit) {
+ nframes_t unit_to_frame (double unit) const {
return (nframes_t) rint (unit * frames_per_unit);
}
- double frame_to_unit (nframes_t frame) {
+ double frame_to_unit (nframes_t frame) const {
return rint ((double) frame / (double) frames_per_unit);
}
- double frame_to_unit (double frame) {
+ double frame_to_unit (double frame) const {
return rint (frame / frames_per_unit);
}
@@ -195,7 +195,7 @@ class Editor : public PublicEditor
xscroll_adjustment.
*/
- nframes64_t pixel_to_frame (double pixel) {
+ nframes64_t pixel_to_frame (double pixel) const {
/* pixel can be less than zero when motion events
are processed. since we've already run the world->canvas
@@ -210,7 +210,7 @@ class Editor : public PublicEditor
}
}
- gulong frame_to_pixel (nframes64_t frame) {
+ gulong frame_to_pixel (nframes64_t frame) const {
return (gulong) rint ((frame / (frames_per_unit * GNOME_CANVAS(track_canvas.gobj())->pixels_per_unit)));
}
@@ -345,6 +345,8 @@ class Editor : public PublicEditor
void reposition_and_zoom (nframes_t, double);
nframes_t edit_cursor_position(bool);
+ nframes64_t get_preferred_edit_position () const;
+
bool update_mouse_speed ();
bool decelerate_mouse_speed ();
@@ -412,8 +414,8 @@ class Editor : public PublicEditor
void set_color_rgba (uint32_t);
};
- LocationMarkers *find_location_markers (ARDOUR::Location *);
- ARDOUR::Location* find_location_from_marker (Marker *, bool& is_start);
+ LocationMarkers *find_location_markers (ARDOUR::Location *) const;
+ ARDOUR::Location* find_location_from_marker (Marker *, bool& is_start) const;
typedef std::map<ARDOUR::Location*,LocationMarkers *> LocationMarkerMap;
LocationMarkerMap location_markers;
@@ -1730,11 +1732,11 @@ class Editor : public PublicEditor
void duplicate_dialog (bool for_region);
- nframes64_t event_frame (GdkEvent*, double* px = 0, double* py = 0);
+ nframes64_t event_frame (GdkEvent*, double* px = 0, double* py = 0) const;
/* returns false if mouse pointer is not in track or marker canvas
*/
- bool mouse_frame (nframes64_t&, bool& in_track_canvas);
+ bool mouse_frame (nframes64_t&, bool& in_track_canvas) const;
void time_fx_motion (ArdourCanvas::Item*, GdkEvent*);
void start_time_fx (ArdourCanvas::Item*, GdkEvent*);
@@ -1900,6 +1902,16 @@ class Editor : public PublicEditor
void color_handler ();
Gtk::HBox status_bar_hpacker;
+
+ Editing::EditPoint _edit_point;
+
+ Gtk::ComboBoxText edit_point_selector;
+
+ void set_edit_point (Editing::EditPoint ep);
+ void edit_point_selection_done ();
+ void edit_point_chosen (Editing::EditPoint);
+ Glib::RefPtr<Gtk::RadioAction> edit_point_action (Editing::EditPoint);
+ std::vector<std::string> edit_point_strings;
};
#endif /* __ardour_editor_h__ */
diff --git a/gtk2_ardour/editor_actions.cc b/gtk2_ardour/editor_actions.cc
index 73e42cfcdd..e4977209bf 100644
--- a/gtk2_ardour/editor_actions.cc
+++ b/gtk2_ardour/editor_actions.cc
@@ -301,6 +301,11 @@ Editor::register_actions ()
ActionManager::register_radio_action (mouse_mode_actions, mouse_mode_group, "set-mouse-mode-zoom", _("Zoom Tool"), bind (mem_fun(*this, &Editor::set_mouse_mode), Editing::MouseZoom, false));
ActionManager::register_radio_action (mouse_mode_actions, mouse_mode_group, "set-mouse-mode-timefx", _("Timefx Tool"), bind (mem_fun(*this, &Editor::set_mouse_mode), Editing::MouseTimeFX, false));
+ RadioAction::Group edit_point_group;
+ ActionManager::register_radio_action (editor_actions, edit_point_group, X_("edit-at-playhead"), _("Playhead"), (bind (mem_fun(*this, &Editor::edit_point_chosen), Editing::EditAtPlayhead)));
+ ActionManager::register_radio_action (editor_actions, edit_point_group, X_("edit-at-mouse"), _("Mouse"), (bind (mem_fun(*this, &Editor::edit_point_chosen), Editing::EditAtPlayhead)));
+ ActionManager::register_radio_action (editor_actions, edit_point_group, X_("edit-at-selected-marker"), _("Marker"), (bind (mem_fun(*this, &Editor::edit_point_chosen), Editing::EditAtPlayhead)));
+
ActionManager::register_action (editor_actions, X_("SnapTo"), _("Snap To"));
ActionManager::register_action (editor_actions, X_("SnapMode"), _("Snap Mode"));
@@ -826,6 +831,54 @@ Editor::snap_mode_chosen (SnapMode mode)
}
}
+RefPtr<RadioAction>
+Editor::edit_point_action (EditPoint ep)
+{
+ const char* action = 0;
+ RefPtr<Action> act;
+
+ switch (ep) {
+ case Editing::EditAtPlayhead:
+ action = X_("edit-at-playhead");
+ break;
+ case Editing::EditAtSelectedMarker:
+ action = X_("edit-at-selected-marker");
+ break;
+ case Editing::EditAtMouse:
+ action = X_("edit-at-mouse");
+ break;
+ default:
+ fatal << string_compose (_("programming error: %1: %2"), "Editor: impossible edit point type", (int) ep) << endmsg;
+ /*NOTREACHED*/
+ }
+
+ act = ActionManager::get_action (X_("Editor"), action);
+
+ if (act) {
+ RefPtr<RadioAction> ract = RefPtr<RadioAction>::cast_dynamic(act);
+ return ract;
+
+ } else {
+ error << string_compose (_("programming error: %1: %2"), "Editor::edit_point_action could not find action to match edit point.", action) << endmsg;
+ return RefPtr<RadioAction> ();
+ }
+}
+
+void
+Editor::edit_point_chosen (EditPoint ep)
+{
+ /* this is driven by a toggle on a radio group, and so is invoked twice,
+ once for the item that became inactive and once for the one that became
+ active.
+ */
+
+ RefPtr<RadioAction> ract = edit_point_action (ep);
+
+ if (ract && ract->get_active()) {
+ set_edit_point (ep);
+ }
+}
+
RefPtr<RadioAction>
Editor::zoom_focus_action (ZoomFocus focus)
diff --git a/gtk2_ardour/editor_audio_import.cc b/gtk2_ardour/editor_audio_import.cc
index 02faf1bb6c..693f0e4986 100644
--- a/gtk2_ardour/editor_audio_import.cc
+++ b/gtk2_ardour/editor_audio_import.cc
@@ -143,7 +143,7 @@ Editor::external_audio_dialog ()
switch (pos) {
case ImportAtEditCursor:
- where = edit_cursor->current_frame;
+ where = get_preferred_edit_position ();
break;
case ImportAtTimestamp:
where = -1;
@@ -156,6 +156,10 @@ Editor::external_audio_dialog ()
break;
}
+ if (where < 0) {
+ return;
+ }
+
SrcQuality quality = sfbrowser->get_src_quality();
if (sfbrowser->copy_files_btn.get_active()) {
@@ -591,7 +595,7 @@ Editor::add_sources (vector<Glib::ustring> paths, SourceList& sources, nframes64
pos = sources[0]->natural_position();
} else {
// XXX is this the best alternative ?
- pos = edit_cursor->current_frame;
+ pos = get_preferred_edit_position ();
}
}
diff --git a/gtk2_ardour/editor_markers.cc b/gtk2_ardour/editor_markers.cc
index c9d30486fb..158715846d 100644
--- a/gtk2_ardour/editor_markers.cc
+++ b/gtk2_ardour/editor_markers.cc
@@ -188,9 +188,9 @@ Editor::LocationMarkers::~LocationMarkers ()
}
Editor::LocationMarkers *
-Editor::find_location_markers (Location *location)
+Editor::find_location_markers (Location *location) const
{
- LocationMarkerMap::iterator i;
+ LocationMarkerMap::const_iterator i;
for (i = location_markers.begin(); i != location_markers.end(); ++i) {
if ((*i).first == location) {
@@ -202,9 +202,9 @@ Editor::find_location_markers (Location *location)
}
Location *
-Editor::find_location_from_marker (Marker *marker, bool& is_start)
+Editor::find_location_from_marker (Marker *marker, bool& is_start) const
{
- LocationMarkerMap::iterator i;
+ LocationMarkerMap::const_iterator i;
for (i = location_markers.begin(); i != location_markers.end(); ++i) {
LocationMarkers *lm = (*i).second;
diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc
index 6f104059b6..86e6a9960a 100644
--- a/gtk2_ardour/editor_mouse.cc
+++ b/gtk2_ardour/editor_mouse.cc
@@ -70,14 +70,14 @@ using namespace Gtk;
using namespace Editing;
bool
-Editor::mouse_frame (nframes64_t& where, bool& in_track_canvas)
+Editor::mouse_frame (nframes64_t& where, bool& in_track_canvas) const
{
int x, y;
double wx, wy;
Gdk::ModifierType mask;
- Glib::RefPtr<Gdk::Window> canvas_window = track_canvas.get_window();
- Glib::RefPtr<Gdk::Window> pointer_window;
-
+ Glib::RefPtr<Gdk::Window> canvas_window = const_cast<Editor*>(this)->track_canvas.get_window();
+ Glib::RefPtr<const Gdk::Window> pointer_window;
+
pointer_window = canvas_window->get_pointer (x, y, mask);
if (pointer_window == track_canvas.get_bin_window()) {
@@ -108,7 +108,7 @@ Editor::mouse_frame (nframes64_t& where, bool& in_track_canvas)
}
nframes64_t
-Editor::event_frame (GdkEvent* event, double* pcx, double* pcy)
+Editor::event_frame (GdkEvent* event, double* pcx, double* pcy) const
{
double cx, cy;
@@ -3676,17 +3676,22 @@ Editor::region_view_item_click (AudioRegionView& rv, GdkEventButton* event)
speed = atv->get_diskstream()->speed();
}
- if (Keyboard::modifier_state_equals (event->state, Keyboard::ModifierMask (Keyboard::Control|Keyboard::Alt))) {
-
- align_region (rv.region(), SyncPoint, (nframes_t) (edit_cursor->current_frame * speed));
-
- } else if (Keyboard::modifier_state_equals (event->state, Keyboard::ModifierMask (Keyboard::Control|Keyboard::Shift))) {
+ nframes64_t where = get_preferred_edit_position();
- align_region (rv.region(), End, (nframes_t) (edit_cursor->current_frame * speed));
+ if (where >= 0) {
- } else {
-
- align_region (rv.region(), Start, (nframes_t) (edit_cursor->current_frame * speed));
+ if (Keyboard::modifier_state_equals (event->state, Keyboard::ModifierMask (Keyboard::Control|Keyboard::Alt))) {
+
+ align_region (rv.region(), SyncPoint, (nframes_t) (where * speed));
+
+ } else if (Keyboard::modifier_state_equals (event->state, Keyboard::ModifierMask (Keyboard::Control|Keyboard::Shift))) {
+
+ align_region (rv.region(), End, (nframes_t) (where * speed));
+
+ } else {
+
+ align_region (rv.region(), Start, (nframes_t) (where * speed));
+ }
}
}
}
diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc
index 26d6f900ee..1584388508 100644
--- a/gtk2_ardour/editor_ops.cc
+++ b/gtk2_ardour/editor_ops.cc
@@ -91,17 +91,10 @@ Editor::redo (uint32_t n)
}
}
-int
-Editor::ensure_cursor (nframes_t *pos)
-{
- *pos = edit_cursor->current_frame;
- return 0;
-}
-
void
Editor::split_region ()
{
- split_region_at (edit_cursor->current_frame);
+ split_region_at (get_preferred_edit_position());
}
void
@@ -135,7 +128,16 @@ Editor::split_regions_at (nframes_t where, RegionSelection& regions)
for (RegionSelection::iterator a = regions.begin(); a != regions.end(); ) {
RegionSelection::iterator tmp;
+
+ /* XXX this test needs to be more complicated, to make sure we really
+ have something to split.
+ */
+ if (!(*a)->region()->covers (where)) {
+ ++a;
+ continue;
+ }
+
tmp = a;
++tmp;
@@ -885,7 +887,7 @@ Editor::cursor_align (bool playhead_to_edit)
{
if (playhead_to_edit) {
if (session) {
- session->request_locate (edit_cursor->current_frame);
+ session->request_locate (get_preferred_edit_position());
}
} else {
edit_cursor->set_position (playhead_cursor->current_frame);
@@ -895,8 +897,8 @@ Editor::cursor_align (bool playhead_to_edit)
void
Editor::edit_cursor_backward ()
{
- nframes_t pos;
- nframes_t cnt;
+ nframes64_t pos;
+ nframes64_t cnt;
float prefix;
bool was_floating;
@@ -910,9 +912,11 @@ Editor::edit_cursor_backward ()
}
}
- pos = edit_cursor->current_frame;
+ if ((pos = get_preferred_edit_position()) < 0) {
+ return;
+ }
- if ((nframes_t) pos < cnt) {
+ if (pos < cnt) {
pos = 0;
} else {
pos -= cnt;
@@ -1177,8 +1181,8 @@ Editor::temporal_zoom (gdouble fpu)
case ZoomFocusEdit:
/* try to keep the edit cursor in the center */
- if (edit_cursor->current_frame > new_page/2) {
- leftmost_after_zoom = edit_cursor->current_frame - (new_page/2);
+ if (get_preferred_edit_position() > new_page/2) {
+ leftmost_after_zoom = get_preferred_edit_position() - (new_page/2);
} else {
leftmost_after_zoom = 0;
}
@@ -1193,7 +1197,7 @@ Editor::temporal_zoom (gdouble fpu)
// session->add_redo (bind (mem_fun(*this, &Editor::reposition_and_zoom), leftmost_after_zoom, nfpu));
// commit_reversible_command ();
- cerr << "repos & zoom to " << leftmost_after_zoom << " @ " << nfpu << endl;
+ // cerr << "repos & zoom to " << leftmost_after_zoom << " @ " << nfpu << endl;
reposition_and_zoom (leftmost_after_zoom, nfpu);
}
@@ -1615,7 +1619,7 @@ Editor::insert_region_list_selection (float times)
begin_reversible_command (_("insert region"));
XMLNode &before = playlist->get_state();
- playlist->add_region ((RegionFactory::create (region)), edit_cursor->current_frame, times);
+ playlist->add_region ((RegionFactory::create (region)), get_preferred_edit_position(), times);
session->add_command(new MementoCommand<Playlist>(*playlist, &before, &playlist->get_state()));
commit_reversible_command ();
}
@@ -1702,7 +1706,7 @@ Editor::play_from_start ()
void
Editor::play_from_edit_cursor ()
{
- session->request_locate (edit_cursor->current_frame, true);
+ session->request_locate (get_preferred_edit_position(), true);
}
void
@@ -2333,7 +2337,7 @@ Editor::set_region_sync_from_edit_cursor ()
return;
}
- if (!clicked_regionview->region()->covers (edit_cursor->current_frame)) {
+ if (!clicked_regionview->region()->covers (get_preferred_edit_position())) {
error << _("Place the edit cursor at the desired sync point") << endmsg;
return;
}
@@ -2341,7 +2345,7 @@ Editor::set_region_sync_from_edit_cursor ()
boost::shared_ptr<Region> region (clicked_regionview->region());
begin_reversible_command (_("set sync from edit cursor"));
XMLNode &before = region->playlist()->get_state();
- region->set_sync_position (edit_cursor->current_frame);
+ region->set_sync_position (get_preferred_edit_position());
XMLNode &after = region->playlist()->get_state();
session->add_command(new MementoCommand<Playlist>(*(region->playlist()), &before, &after));
commit_reversible_command ();
@@ -2380,13 +2384,13 @@ Editor::naturalize ()
void
Editor::align (RegionPoint what)
{
- align_selection (what, edit_cursor->current_frame);
+ align_selection (what, get_preferred_edit_position());
}
void
Editor::align_relative (RegionPoint what)
{
- align_selection_relative (what, edit_cursor->current_frame);
+ align_selection_relative (what, get_preferred_edit_position());
}
struct RegionSortByTime {
@@ -2523,7 +2527,7 @@ Editor::trim_region_to_edit_cursor ()
begin_reversible_command (_("trim to edit"));
XMLNode &before = region->playlist()->get_state();
- region->trim_end( session_frame_to_track_frame(edit_cursor->current_frame, speed), this);
+ region->trim_end( session_frame_to_track_frame(get_preferred_edit_position(), speed), this);
XMLNode &after = region->playlist()->get_state();
session->add_command(new MementoCommand<Playlist>(*(region->playlist()), &before, &after));
commit_reversible_command ();
@@ -2549,7 +2553,7 @@ Editor::trim_region_from_edit_cursor ()
begin_reversible_command (_("trim to edit"));
XMLNode &before = region->playlist()->get_state();
- region->trim_front ( session_frame_to_track_frame(edit_cursor->current_frame, speed), this);
+ region->trim_front ( session_frame_to_track_frame(get_preferred_edit_position(), speed), this);
XMLNode &after = region->playlist()->get_state();
session->add_command(new MementoCommand<Playlist>(*(region->playlist()), &before, &after));
commit_reversible_command ();
@@ -2935,7 +2939,7 @@ Editor::cut_copy_ranges (CutCopyOp op)
void
Editor::paste (float times)
{
- paste_internal (edit_cursor->current_frame, times);
+ paste_internal (get_preferred_edit_position(), times);
}
void
@@ -2962,7 +2966,7 @@ Editor::paste_internal (nframes_t position, float times)
}
if (position == max_frames) {
- position = edit_cursor->current_frame;
+ position = get_preferred_edit_position();
}
begin_reversible_command (_("paste"));
@@ -3033,7 +3037,7 @@ Editor::paste_named_selection (float times)
++tmp;
XMLNode &before = apl->get_state();
- apl->paste (*chunk, edit_cursor->current_frame, times);
+ apl->paste (*chunk, get_preferred_edit_position(), times);
session->add_command(new MementoCommand<AudioPlaylist>(*apl, &before, &apl->get_state()));
if (tmp != ns->playlists.end()) {
@@ -3145,7 +3149,7 @@ Editor::center_edit_cursor ()
{
float page = canvas_width * frames_per_unit;
- center_screen_internal (edit_cursor->current_frame, page);
+ center_screen_internal (get_preferred_edit_position(), page);
}
void
@@ -3168,7 +3172,7 @@ Editor::nudge_track (bool use_edit_cursor, bool forwards)
nframes_t start;
if (use_edit_cursor) {
- start = edit_cursor->current_frame;
+ start = get_preferred_edit_position();
} else {
start = 0;
}
diff --git a/gtk2_ardour/enums.cc b/gtk2_ardour/enums.cc
index c33b2965c3..f626bfb968 100644
--- a/gtk2_ardour/enums.cc
+++ b/gtk2_ardour/enums.cc
@@ -38,6 +38,7 @@ setup_gtk_ardour_enums ()
AudioClock::Mode clock_mode;
Width width;
ImportMode import_mode;
+ EditPoint edit_point;
#define REGISTER(e) enum_writer.register_distinct (typeid(e).name(), i, s); i.clear(); s.clear()
#define REGISTER_BITS(e) enum_writer.register_bits (typeid(e).name(), i, s); i.clear(); s.clear()
@@ -60,4 +61,9 @@ setup_gtk_ardour_enums ()
REGISTER_ENUM (ImportAsRegion);
REGISTER_ENUM (ImportAsTapeTrack);
REGISTER (import_mode);
+
+ REGISTER_ENUM (EditAtPlayhead);
+ REGISTER_ENUM (EditAtMouse);
+ REGISTER_ENUM (EditAtSelectedMarker);
+ REGISTER (edit_point);
}
diff --git a/gtk2_ardour/marker_selection.h b/gtk2_ardour/marker_selection.h
new file mode 100644
index 0000000000..aa1413ed3e
--- /dev/null
+++ b/gtk2_ardour/marker_selection.h
@@ -0,0 +1,31 @@
+/*
+ Copyright (C) 2000-2007 Paul Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef __ardour_gtk_marker_selection_h__
+#define __ardour_gtk_marker_selection_h__
+
+#include <list>
+
+#include "marker.h"
+
+struct MarkerSelection : public std::list<Marker*>
+{
+};
+
+#endif /* __ardour_gtk_marker_selection_h__ */
diff --git a/gtk2_ardour/public_editor.h b/gtk2_ardour/public_editor.h
index c70705df3d..290b2824ec 100644
--- a/gtk2_ardour/public_editor.h
+++ b/gtk2_ardour/public_editor.h
@@ -106,11 +106,11 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulThingWithGoingAway
virtual void separate_region_from_selection () = 0;
virtual void toggle_playback (bool with_abort) = 0;
virtual void transition_to_rolling (bool fwd) = 0;
- virtual nframes_t unit_to_frame (double unit) = 0;
- virtual double frame_to_unit (nframes_t frame) = 0;
- virtual double frame_to_unit (double frame) = 0;
- virtual nframes64_t pixel_to_frame (double pixel) = 0;
- virtual gulong frame_to_pixel (nframes64_t frame) = 0;
+ virtual nframes_t unit_to_frame (double unit) const = 0;
+ virtual double frame_to_unit (nframes_t frame) const = 0;
+ virtual double frame_to_unit (double frame) const = 0;
+ virtual nframes64_t pixel_to_frame (double pixel) const = 0;
+ virtual gulong frame_to_pixel (nframes64_t frame) const = 0;
virtual Selection& get_selection() const = 0;
virtual Selection& get_cut_buffer() const = 0;
virtual bool extend_selection_to_track (TimeAxisView&) = 0;
diff --git a/gtk2_ardour/selection.cc b/gtk2_ardour/selection.cc
index 1e8874444c..6b2915ac02 100644
--- a/gtk2_ardour/selection.cc
+++ b/gtk2_ardour/selection.cc
@@ -153,6 +153,15 @@ Selection::clear_lines ()
}
void
+Selection::clear_markers ()
+{
+ if (!markers.empty()) {
+ markers.clear ();
+ MarkersChanged();
+ }
+}
+
+void
Selection::toggle (boost::shared_ptr<Redirect> r)
{
RedirectSelection::iterator i;
@@ -624,7 +633,8 @@ Selection::empty ()
lines.empty () &&
time.empty () &&
playlists.empty () &&
- redirects.empty ()
+ redirects.empty () &&
+ markers.empty()
;
}
@@ -731,3 +741,43 @@ Selection::add (vector<AutomationSelectable*>& autos)
PointsChanged ();
}
+
+void
+Selection::set (Marker* m)
+{
+ clear_markers ();
+ add (m);
+}
+
+void
+Selection::toggle (Marker* m)
+{
+ MarkerSelection::iterator i;
+
+ if ((i = find (markers.begin(), markers.end(), m)) == markers.end()) {
+ add (m);
+ } else {
+ remove (m);
+ }
+}
+
+void
+Selection::remove (Marker* m)
+{
+ MarkerSelection::iterator i;
+
+ if ((i = find (markers.begin(), markers.end(), m)) != markers.end()) {
+ markers.erase (i);
+ MarkersChanged();
+ }
+}
+
+
+void
+Selection::add (Marker* m)
+{
+ if (find (markers.begin(), markers.end(), m) == markers.end()) {
+ markers.push_back (m);
+ MarkersChanged();
+ }
+}
diff --git a/gtk2_ardour/selection.h b/gtk2_ardour/selection.h
index 00bc6eeaaa..5196f0a4e4 100644
--- a/gtk2_ardour/selection.h
+++ b/gtk2_ardour/selection.h
@@ -32,6 +32,7 @@
#include "playlist_selection.h"
#include "redirect_selection.h"
#include "point_selection.h"
+#include "marker_selection.h"
class TimeAxisView;
class RegionView;
@@ -67,6 +68,7 @@ class Selection : public sigc::trackable
PlaylistSelection playlists;
RedirectSelection redirects;
PointSelection points;
+ MarkerSelection markers;
Selection() {
next_time_id = 0;
@@ -82,6 +84,7 @@ class Selection : public sigc::trackable
sigc::signal<void> PlaylistsChanged;
sigc::signal<void> RedirectsChanged;
sigc::signal<void> PointsChanged;
+ sigc::signal<void> MarkersChanged;
void clear ();
bool empty();
@@ -105,6 +108,7 @@ class Selection : public sigc::trackable
void set (const std::list<boost::shared_ptr<ARDOUR::Playlist> >&);
void set (boost::shared_ptr<ARDOUR::Redirect>);
void set (AutomationSelectable*);
+ void set (Marker*);
void toggle (TimeAxisView*);
void toggle (const std::list<TimeAxisView*>&);
@@ -116,6 +120,7 @@ class Selection : public sigc::trackable
void toggle (const std::list<boost::shared_ptr<ARDOUR::Playlist> >&);
void toggle (boost::shared_ptr<ARDOUR::Redirect>);
void toggle (const std::vector<AutomationSelectable*>&);
+ void toggle (Marker*);
void add (TimeAxisView*);
void add (const std::list<TimeAxisView*>&);
@@ -126,7 +131,8 @@ class Selection : public sigc::trackable
void add (boost::shared_ptr<ARDOUR::Playlist>);
void add (const std::list<boost::shared_ptr<ARDOUR::Playlist> >&);
void add (boost::shared_ptr<ARDOUR::Redirect>);
-
+ void add (Marker*);
+
void remove (TimeAxisView*);
void remove (const std::list<TimeAxisView*>&);
void remove (RegionView*);
@@ -137,6 +143,7 @@ class Selection : public sigc::trackable
void remove (const std::list<boost::shared_ptr<ARDOUR::Playlist> >&);
void remove (boost::shared_ptr<ARDOUR::Redirect>);
void remove (const list<Selectable*>&);
+ void remove (Marker*);
void replace (uint32_t time_index, nframes_t start, nframes_t end);
@@ -147,6 +154,7 @@ class Selection : public sigc::trackable
void clear_playlists ();
void clear_redirects ();
void clear_points ();
+ void clear_markers ();
void foreach_region (void (ARDOUR::Region::*method)(void));
template<class A> void foreach_region (void (ARDOUR::Region::*method)(A), A arg);