diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2007-11-07 17:05:46 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2007-11-07 17:05:46 +0000 |
commit | 998771e57d4687c0937fe1c36b294d4f075b6d3c (patch) | |
tree | c2b4443cf23dbe71c0c2e60eb3ea47377f2f97ea /gtk2_ardour | |
parent | 5cd58a2e8bbc7e3d2face30ad0bf8e307ab395fa (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.h | 11 | ||||
-rw-r--r-- | gtk2_ardour/editing_syms.h | 3 | ||||
-rw-r--r-- | gtk2_ardour/editor.cc | 120 | ||||
-rw-r--r-- | gtk2_ardour/editor.h | 30 | ||||
-rw-r--r-- | gtk2_ardour/editor_actions.cc | 53 | ||||
-rw-r--r-- | gtk2_ardour/editor_audio_import.cc | 8 | ||||
-rw-r--r-- | gtk2_ardour/editor_markers.cc | 8 | ||||
-rw-r--r-- | gtk2_ardour/editor_mouse.cc | 33 | ||||
-rw-r--r-- | gtk2_ardour/editor_ops.cc | 62 | ||||
-rw-r--r-- | gtk2_ardour/enums.cc | 6 | ||||
-rw-r--r-- | gtk2_ardour/marker_selection.h | 31 | ||||
-rw-r--r-- | gtk2_ardour/public_editor.h | 10 | ||||
-rw-r--r-- | gtk2_ardour/selection.cc | 52 | ||||
-rw-r--r-- | gtk2_ardour/selection.h | 10 |
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); |