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
This commit is contained in:
Paul Davis 2007-11-07 17:05:46 +00:00
parent 5cd58a2e8b
commit 998771e57d
14 changed files with 348 additions and 89 deletions

View file

@ -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 {

View file

@ -92,3 +92,6 @@ IMPORTDISPOSITION(ImportMergeFiles=1)
IMPORTDISPOSITION(ImportSerializeFiles=2)
IMPORTDISPOSITION(ImportDistinctChannels=3)
EDITPOINT(EditAtPlayhead)
EDITPOINT(EditAtSelectedMarker)
EDITPOINT(EditAtMouse)

View file

@ -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
@ -3135,6 +3156,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 ()
{
@ -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)
{

View file

@ -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__ */

View file

@ -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)

View file

@ -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 ();
}
}

View file

@ -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;

View file

@ -70,13 +70,13 @@ 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);
@ -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))) {
nframes64_t where = get_preferred_edit_position();
align_region (rv.region(), SyncPoint, (nframes_t) (edit_cursor->current_frame * speed));
if (where >= 0) {
} else if (Keyboard::modifier_state_equals (event->state, Keyboard::ModifierMask (Keyboard::Control|Keyboard::Shift))) {
if (Keyboard::modifier_state_equals (event->state, Keyboard::ModifierMask (Keyboard::Control|Keyboard::Alt))) {
align_region (rv.region(), End, (nframes_t) (edit_cursor->current_frame * speed));
align_region (rv.region(), SyncPoint, (nframes_t) (where * speed));
} else {
} else if (Keyboard::modifier_state_equals (event->state, Keyboard::ModifierMask (Keyboard::Control|Keyboard::Shift))) {
align_region (rv.region(), Start, (nframes_t) (edit_cursor->current_frame * speed));
align_region (rv.region(), End, (nframes_t) (where * speed));
} else {
align_region (rv.region(), Start, (nframes_t) (where * speed));
}
}
}
}

View file

@ -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
@ -136,6 +129,15 @@ Editor::split_regions_at (nframes_t where, RegionSelection& regions)
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;
}

View file

@ -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);
}

View file

@ -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__ */

View file

@ -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;

View file

@ -152,6 +152,15 @@ Selection::clear_lines ()
}
}
void
Selection::clear_markers ()
{
if (!markers.empty()) {
markers.clear ();
MarkersChanged();
}
}
void
Selection::toggle (boost::shared_ptr<Redirect> r)
{
@ -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();
}
}

View file

@ -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,6 +131,7 @@ 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*>&);
@ -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);