new_snap: Snapped Cursor ( squashed commit )
Snapped Cursor is a line that follows the edit point, and indicates where the operation will occur. This replaces and extends the line that appears with the Cut tool. New associated preferences: snap_threshold and show_snap_cursor.
This commit is contained in:
parent
70d8300cb2
commit
c6eab71435
@ -335,6 +335,7 @@ Editor::Editor ()
|
||||
, cd_mark_label (_("CD Markers"))
|
||||
, videotl_label (_("Video Timeline"))
|
||||
, videotl_group (0)
|
||||
, snapped_cursor (0)
|
||||
, playhead_cursor (0)
|
||||
, edit_packer (4, 4, true)
|
||||
, vertical_adjustment (0.0, 0.0, 10.0, 400.0)
|
||||
@ -367,7 +368,6 @@ Editor::Editor ()
|
||||
, pending_keyboard_selection_start (0)
|
||||
, _snap_type (SnapToBeat)
|
||||
, _snap_mode (SnapOff)
|
||||
, snap_threshold (5.0)
|
||||
, ignore_gui_changes (false)
|
||||
, _drags (new DragManager (this))
|
||||
, lock_dialog (0)
|
||||
@ -1406,8 +1406,13 @@ Editor::set_session (Session *t)
|
||||
_session->locations()->changed.connect (_session_connections, invalidator (*this), boost::bind (&Editor::refresh_location_display, this), gui_context());
|
||||
_session->history().Changed.connect (_session_connections, invalidator (*this), boost::bind (&Editor::history_changed, this), gui_context());
|
||||
|
||||
playhead_cursor->track_canvas_item().reparent ((ArdourCanvas::Item*) get_cursor_scroll_group());
|
||||
playhead_cursor->show ();
|
||||
|
||||
snapped_cursor->track_canvas_item().reparent ((ArdourCanvas::Item*) get_cursor_scroll_group());
|
||||
snapped_cursor->set_color (UIConfiguration::instance().color ("edit point"));
|
||||
snapped_cursor->show ();
|
||||
|
||||
boost::function<void (string)> pc (boost::bind (&Editor::parameter_changed, this, _1));
|
||||
Config->map_parameters (pc);
|
||||
_session->config.map_parameters (pc);
|
||||
@ -2287,6 +2292,7 @@ Editor::set_edit_point_preference (EditPoint ep, bool force)
|
||||
|
||||
switch (_edit_point) {
|
||||
case EditAtPlayhead:
|
||||
//ToDo: hide or show mouse_cursor
|
||||
action = "edit-at-playhead";
|
||||
break;
|
||||
case EditAtSelectedMarker:
|
||||
@ -2637,6 +2643,15 @@ Editor::trackview_by_y_position (double y, bool trackview_relative_offset) const
|
||||
return std::make_pair ( (TimeAxisView *) 0, 0);
|
||||
}
|
||||
|
||||
void
|
||||
Editor::set_snapped_cursor_position (samplepos_t pos)
|
||||
{
|
||||
if ( _edit_point == EditAtMouse ) {
|
||||
snapped_cursor->set_position(pos);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Snap a position to the grid, if appropriate, taking into account current
|
||||
* grid settings and also the state of any snap modifier keys that may be pressed.
|
||||
* @param start Position to snap.
|
||||
@ -2756,6 +2771,8 @@ Editor::snap_to_internal (MusicSample& start, RoundMode direction, bool for_mark
|
||||
samplepos_t before;
|
||||
samplepos_t after;
|
||||
|
||||
int snap_threshold_s = pixel_to_sample(UIConfiguration::instance().get_snap_threshold());
|
||||
|
||||
switch (_snap_type) {
|
||||
case SnapToTimecodeFrame:
|
||||
case SnapToTimecodeSeconds:
|
||||
@ -2942,12 +2959,12 @@ Editor::snap_to_internal (MusicSample& start, RoundMode direction, bool for_mark
|
||||
}
|
||||
|
||||
if (presnap > start.sample) {
|
||||
if (presnap > (start.sample + pixel_to_sample(snap_threshold))) {
|
||||
if (presnap > (start.sample + snap_threshold_s)) {
|
||||
start.set (presnap, 0);
|
||||
}
|
||||
|
||||
} else if (presnap < start.sample) {
|
||||
if (presnap < (start.sample - pixel_to_sample(snap_threshold))) {
|
||||
if (presnap < (start.sample - snap_threshold_s)) {
|
||||
start.set (presnap, 0);
|
||||
}
|
||||
}
|
||||
@ -5797,27 +5814,6 @@ Editor::super_rapid_screen_update ()
|
||||
current_mixer_strip->fast_update ();
|
||||
}
|
||||
|
||||
/* PLAYHEAD AND VIEWPORT */
|
||||
|
||||
/* There are a few reasons why we might not update the playhead / viewport stuff:
|
||||
*
|
||||
* 1. we don't update things when there's a pending locate request, otherwise
|
||||
* when the editor requests a locate there is a chance that this method
|
||||
* will move the playhead before the locate request is processed, causing
|
||||
* a visual glitch.
|
||||
* 2. if we're not rolling, there's nothing to do here (locates are handled elsewhere).
|
||||
* 3. if we're still at the same sample that we were last time, there's nothing to do.
|
||||
*/
|
||||
if (_pending_locate_request || !_session->transport_rolling ()) {
|
||||
_last_update_time = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (_dragging_playhead) {
|
||||
_last_update_time = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
bool latent_locate = false;
|
||||
samplepos_t sample = _session->audible_sample (&latent_locate);
|
||||
const int64_t now = g_get_monotonic_time ();
|
||||
@ -5857,6 +5853,47 @@ Editor::super_rapid_screen_update ()
|
||||
} else {
|
||||
_last_update_time = now;
|
||||
}
|
||||
|
||||
//snapped cursor stuff ( the snapped_cursor shows where an operation is going to occur )
|
||||
bool ignored;
|
||||
MusicSample where (sample, 0);
|
||||
if ( !UIConfiguration::instance().get_show_snapped_cursor() ) {
|
||||
snapped_cursor->hide ();
|
||||
} else if ( _edit_point == EditAtPlayhead && !_dragging_playhead) {
|
||||
snap_to (where); // can't use snap_to_with_modifier?
|
||||
snapped_cursor->set_position (where.sample);
|
||||
snapped_cursor->show ();
|
||||
} else if ( _edit_point == EditAtSelectedMarker ) {
|
||||
//NOTE: I don't think EditAtSelectedMarker should snap. they are what they are.
|
||||
//however, the current editing code -does- snap so I'll draw it that way for now.
|
||||
MusicSample ms (selection->markers.front()->position(), 0);
|
||||
snap_to (ms); // should use snap_to_with_modifier?
|
||||
snapped_cursor->set_position ( ms.sample );
|
||||
snapped_cursor->show ();
|
||||
} else if (mouse_sample (where.sample, ignored)) { //cursor is in the editing canvas. show it.
|
||||
snapped_cursor->show ();
|
||||
} else { //mouse is out of the editing canvas. hide the snapped_cursor
|
||||
snapped_cursor->hide ();
|
||||
}
|
||||
|
||||
/* There are a few reasons why we might not update the playhead / viewport stuff:
|
||||
*
|
||||
* 1. we don't update things when there's a pending locate request, otherwise
|
||||
* when the editor requests a locate there is a chance that this method
|
||||
* will move the playhead before the locate request is processed, causing
|
||||
* a visual glitch.
|
||||
* 2. if we're not rolling, there's nothing to do here (locates are handled elsewhere).
|
||||
* 3. if we're still at the same frame that we were last time, there's nothing to do.
|
||||
*/
|
||||
if (_pending_locate_request) {
|
||||
_last_update_time = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (_dragging_playhead) {
|
||||
_last_update_time = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (playhead_cursor->current_sample () == sample) {
|
||||
return;
|
||||
|
@ -169,7 +169,6 @@ public:
|
||||
void prev_snap_choice_music_and_time ();
|
||||
void set_snap_to (Editing::SnapType);
|
||||
void set_snap_mode (Editing::SnapMode);
|
||||
void set_snap_threshold (double pixel_distance) {snap_threshold = pixel_distance;}
|
||||
|
||||
Editing::SnapMode snap_mode () const;
|
||||
Editing::SnapType snap_type () const;
|
||||
@ -472,6 +471,8 @@ public:
|
||||
ARDOUR::RoundMode direction = ARDOUR::RoundNearest,
|
||||
bool for_mark = false);
|
||||
|
||||
void set_snapped_cursor_position (samplepos_t pos);
|
||||
|
||||
void begin_selection_op_history ();
|
||||
void begin_reversible_selection_op (std::string cmd_name);
|
||||
void commit_reversible_selection_op ();
|
||||
@ -533,6 +534,7 @@ public:
|
||||
ArdourCanvas::ScrollGroup* get_hscroll_group () const { return h_scroll_group; }
|
||||
ArdourCanvas::ScrollGroup* get_hvscroll_group () const { return hv_scroll_group; }
|
||||
ArdourCanvas::ScrollGroup* get_cursor_scroll_group () const { return cursor_scroll_group; }
|
||||
ArdourCanvas::Container* get_drag_motion_group () const { return _drag_motion_group; }
|
||||
|
||||
ArdourCanvas::GtkCanvasViewport* get_track_canvas () const;
|
||||
|
||||
@ -1032,6 +1034,8 @@ private:
|
||||
|
||||
friend class EditorCursor;
|
||||
|
||||
EditorCursor* snapped_cursor;
|
||||
|
||||
EditorCursor* playhead_cursor;
|
||||
samplepos_t playhead_cursor_sample () const;
|
||||
|
||||
@ -1529,9 +1533,6 @@ private:
|
||||
Editing::SnapType _snap_type;
|
||||
Editing::SnapMode _snap_mode;
|
||||
|
||||
/// Snap threshold in pixels
|
||||
double snap_threshold;
|
||||
|
||||
bool ignore_gui_changes;
|
||||
|
||||
DragManager* _drags;
|
||||
|
@ -217,6 +217,8 @@ Editor::initialize_canvas ()
|
||||
|
||||
playhead_cursor = new EditorCursor (*this, &Editor::canvas_playhead_cursor_event);
|
||||
|
||||
snapped_cursor = new EditorCursor (*this);
|
||||
|
||||
_canvas_drop_zone = new ArdourCanvas::Rectangle (hv_scroll_group, ArdourCanvas::Rect (0.0, 0.0, ArdourCanvas::COORD_MAX, 0.0));
|
||||
/* this thing is transparent */
|
||||
_canvas_drop_zone->set_fill (false);
|
||||
|
@ -719,6 +719,8 @@ RegionMotionDrag::compute_x_delta (GdkEvent const * event, MusicSample* pending_
|
||||
}
|
||||
}
|
||||
|
||||
_editor->set_snapped_cursor_position(pending_region_position->sample);
|
||||
|
||||
return dx;
|
||||
}
|
||||
|
||||
@ -3320,6 +3322,7 @@ MeterMarkerDrag::motion (GdkEvent* event, bool first_move)
|
||||
_marker->set_position (adjusted_current_sample (event, false));
|
||||
|
||||
show_verbose_cursor_time (_real_section->sample());
|
||||
_editor->set_snapped_cursor_position(_real_section->sample());
|
||||
}
|
||||
|
||||
void
|
||||
@ -3485,6 +3488,7 @@ TempoMarkerDrag::motion (GdkEvent* event, bool first_move)
|
||||
map.gui_set_tempo_position (_real_section, pf, sub_num);
|
||||
|
||||
show_verbose_cursor_time (_real_section->sample());
|
||||
_editor->set_snapped_cursor_position(_real_section->sample());
|
||||
}
|
||||
_marker->set_position (adjusted_current_sample (event, false));
|
||||
}
|
||||
@ -4609,6 +4613,7 @@ MarkerDrag::motion (GdkEvent* event, bool)
|
||||
assert (!_copied_locations.empty());
|
||||
|
||||
show_verbose_cursor_time (newframe);
|
||||
_editor->set_snapped_cursor_position(newframe);
|
||||
}
|
||||
|
||||
void
|
||||
@ -6144,6 +6149,8 @@ NoteDrag::motion (GdkEvent * event, bool first_move)
|
||||
uint8_t new_note = min (max (_primary->note()->note() + note_delta, 0), 127);
|
||||
|
||||
_region->show_verbose_cursor_for_new_note_value (_primary->note(), new_note);
|
||||
|
||||
_editor->set_snapped_cursor_position( _region->source_beats_to_absolute_samples(_primary->note()->time()) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -6956,16 +6963,11 @@ CrossfadeEdgeDrag::aborted (bool)
|
||||
|
||||
RegionCutDrag::RegionCutDrag (Editor* e, ArdourCanvas::Item* item, samplepos_t pos)
|
||||
: Drag (e, item, true)
|
||||
, line (new EditorCursor (*e))
|
||||
{
|
||||
line->set_position (pos);
|
||||
line->show ();
|
||||
line->track_canvas_item().reparent (_editor->_drag_motion_group);
|
||||
}
|
||||
|
||||
RegionCutDrag::~RegionCutDrag ()
|
||||
{
|
||||
delete line;
|
||||
}
|
||||
|
||||
void
|
||||
@ -6978,10 +6980,6 @@ RegionCutDrag::start_grab (GdkEvent* event, Gdk::Cursor* c)
|
||||
void
|
||||
RegionCutDrag::motion (GdkEvent* event, bool)
|
||||
{
|
||||
MusicSample pos (_drags->current_pointer_sample(), 0);
|
||||
_editor->snap_to_with_modifier (pos, event);
|
||||
|
||||
line->set_position (pos.sample);
|
||||
}
|
||||
|
||||
void
|
||||
@ -6992,7 +6990,6 @@ RegionCutDrag::finished (GdkEvent* event, bool)
|
||||
|
||||
MusicSample pos (_drags->current_pointer_sample(), 0);
|
||||
_editor->snap_to_with_modifier (pos, event);
|
||||
line->hide ();
|
||||
|
||||
RegionSelection rs = _editor->get_regions_from_selection_and_mouse (pos.sample);
|
||||
|
||||
|
@ -511,7 +511,6 @@ public:
|
||||
void aborted (bool);
|
||||
|
||||
private:
|
||||
EditorCursor* line;
|
||||
};
|
||||
|
||||
/** Drags to create regions */
|
||||
|
@ -2078,6 +2078,15 @@ Editor::motion_handler (ArdourCanvas::Item* /*item*/, GdkEvent* event, bool from
|
||||
|
||||
update_join_object_range_location (event->motion.y);
|
||||
|
||||
//snapped_cursor stuff ( the snapped_cursor shows where an operation is going to occur )
|
||||
bool ignored;
|
||||
MusicSample where (0, 0);
|
||||
if (mouse_sample (where.sample, ignored)) {
|
||||
snap_to_with_modifier (where, event);
|
||||
set_snapped_cursor_position (where.sample);
|
||||
}
|
||||
|
||||
//drags might also change the snapped_cursor location, because we are snapping the thing being dragged, not the actual mouse cursor
|
||||
if (_drags->active ()) {
|
||||
return _drags->motion_handler (event, from_autoscroll);
|
||||
}
|
||||
|
@ -837,7 +837,6 @@ LuaInstance::register_classes (lua_State* L)
|
||||
.addFunction ("snap_type", &PublicEditor::snap_type)
|
||||
.addFunction ("snap_mode", &PublicEditor::snap_mode)
|
||||
.addFunction ("set_snap_mode", &PublicEditor::set_snap_mode)
|
||||
.addFunction ("set_snap_threshold", &PublicEditor::set_snap_threshold)
|
||||
|
||||
.addFunction ("undo", &PublicEditor::undo)
|
||||
.addFunction ("redo", &PublicEditor::redo)
|
||||
|
@ -348,7 +348,6 @@ ArdourMarker::setup_line ()
|
||||
if (_track_canvas_line == 0) {
|
||||
|
||||
_track_canvas_line = new ArdourCanvas::Line (editor.get_hscroll_group());
|
||||
_track_canvas_line->set_outline_color (UIConfiguration::instance().color ("edit point"));
|
||||
_track_canvas_line->Event.connect (sigc::bind (sigc::mem_fun (editor, &PublicEditor::canvas_marker_event), group, this));
|
||||
}
|
||||
|
||||
@ -359,7 +358,7 @@ ArdourMarker::setup_line ()
|
||||
_track_canvas_line->set_x1 (d.x);
|
||||
_track_canvas_line->set_y0 (d.y);
|
||||
_track_canvas_line->set_y1 (ArdourCanvas::COORD_MAX);
|
||||
_track_canvas_line->set_outline_color (_selected ? UIConfiguration::instance().color ("edit point") : _color);
|
||||
_track_canvas_line->set_outline_color ( _selected ? UIConfiguration::instance().color ("entered marker") : _color );
|
||||
_track_canvas_line->raise_to_top ();
|
||||
_track_canvas_line->show ();
|
||||
|
||||
|
@ -347,6 +347,9 @@ MidiRegionView::canvas_group_event(GdkEvent* ev)
|
||||
return RegionView::canvas_group_event (ev);
|
||||
}
|
||||
|
||||
//For now, move the snapped cursor aside so it doesn't bother you during internal editing
|
||||
//trackview.editor().set_snapped_cursor_position(_region->position());
|
||||
|
||||
bool r;
|
||||
|
||||
switch (ev->type) {
|
||||
@ -3035,6 +3038,7 @@ MidiRegionView::update_resizing (NoteBase* primary, bool at_front, double delta_
|
||||
} else {
|
||||
snapped_x = trackview.editor ().pixel_to_sample (current_x);
|
||||
}
|
||||
|
||||
const Temporal::Beats beats = Temporal::Beats (tmap.exact_beat_at_sample (snapped_x + midi_region()->position(), divisions)
|
||||
- midi_region()->beat()) + midi_region()->start_beats();
|
||||
|
||||
@ -3058,6 +3062,8 @@ MidiRegionView::update_resizing (NoteBase* primary, bool at_front, double delta_
|
||||
show_verbose_cursor (buf, 0, 0);
|
||||
|
||||
cursor_set = true;
|
||||
|
||||
trackview.editor().set_snapped_cursor_position ( snapped_x + midi_region()->position() );
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -151,6 +151,7 @@ void
|
||||
MiniTimeline::set_colors ()
|
||||
{
|
||||
// TODO UIConfiguration::instance().color & font
|
||||
_phead_color = UIConfiguration::instance().color ("play head");
|
||||
}
|
||||
|
||||
void
|
||||
@ -648,7 +649,8 @@ MiniTimeline::render (Cairo::RefPtr<Cairo::Context> const& ctx, cairo_rectangle_
|
||||
/* playhead on top */
|
||||
int xc = width * 0.5f;
|
||||
cairo_set_line_width (cr, 1.0);
|
||||
cairo_set_source_rgb (cr, 1, 0, 0); // playhead color
|
||||
double r,g,b,a; Gtkmm2ext::color_to_rgba(_phead_color, r,g,b,a);
|
||||
cairo_set_source_rgb (cr, r,g,b); // playhead color
|
||||
cairo_move_to (cr, xc - .5, 0);
|
||||
cairo_rel_line_to (cr, 0, height);
|
||||
cairo_stroke (cr);
|
||||
|
@ -101,6 +101,8 @@ private:
|
||||
|
||||
Gtk::Menu* _minitl_context_menu;
|
||||
|
||||
uint32_t _phead_color;
|
||||
|
||||
struct JumpRange {
|
||||
JumpRange (int l, int r, samplepos_t t, bool p = false)
|
||||
: left (l), right (r), to (t), prelight (p) {}
|
||||
|
@ -143,11 +143,6 @@ public:
|
||||
*/
|
||||
virtual void set_snap_mode (Editing::SnapMode m) = 0;
|
||||
|
||||
/** Set the snap threshold.
|
||||
* @param t Snap threshold in `units'.
|
||||
*/
|
||||
virtual void set_snap_threshold (double t) = 0;
|
||||
|
||||
/**
|
||||
* Snap a value according to the current snap setting.
|
||||
* ensure_snap overrides SnapOff and magnetic snap
|
||||
@ -426,6 +421,7 @@ public:
|
||||
virtual ArdourCanvas::ScrollGroup* get_hscroll_group () const = 0;
|
||||
virtual ArdourCanvas::ScrollGroup* get_hvscroll_group () const = 0;
|
||||
virtual ArdourCanvas::ScrollGroup* get_cursor_scroll_group () const = 0;
|
||||
virtual ArdourCanvas::Container* get_drag_motion_group () const = 0;
|
||||
|
||||
virtual ArdourCanvas::GtkCanvasViewport* get_track_canvas() const = 0;
|
||||
|
||||
@ -467,6 +463,8 @@ public:
|
||||
ARDOUR::RoundMode direction = ARDOUR::RoundNearest,
|
||||
bool for_mark = false) = 0;
|
||||
|
||||
virtual void set_snapped_cursor_position (samplepos_t pos) = 0;
|
||||
|
||||
virtual void get_regions_at (RegionSelection &, samplepos_t where, TrackViewList const &) const = 0;
|
||||
virtual void get_regions_after (RegionSelection&, samplepos_t where, const TrackViewList& ts) const = 0;
|
||||
virtual RegionSelection get_regions_from_selection_and_mouse (samplepos_t) = 0;
|
||||
|
@ -2490,6 +2490,26 @@ RCOptionEditor::RCOptionEditor ()
|
||||
|
||||
add_option (_("Editor"), rsas);
|
||||
|
||||
add_option (_("Editor/Snap"), new OptionEditorHeading (_("General Snap options:")));
|
||||
|
||||
add_option (_("Editor/Snap"),
|
||||
new SpinOption<uint32_t> (
|
||||
"snap-threshold",
|
||||
_("Snap Threshold (pixels)"),
|
||||
sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_snap_threshold),
|
||||
sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_snap_threshold),
|
||||
10, 200,
|
||||
1, 10
|
||||
));
|
||||
|
||||
add_option (_("Editor/Snap"),
|
||||
new BoolOption (
|
||||
"show-snapped-cursor",
|
||||
_("Show Snapped Cursor"),
|
||||
sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_snapped_cursor),
|
||||
sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_snapped_cursor)
|
||||
));
|
||||
|
||||
add_option (_("Editor/Modifiers"), new OptionEditorHeading (_("Keyboard Modifiers")));
|
||||
add_option (_("Editor/Modifiers"), new KeyboardOptions);
|
||||
add_option (_("Editor/Modifiers"), new OptionEditorBlank ());
|
||||
|
@ -100,3 +100,6 @@ UI_CONFIG_VARIABLE (bool, prefer_inline_over_gui, "prefer-inline-over-gui", true
|
||||
UI_CONFIG_VARIABLE (uint32_t, action_table_columns, "action-table-columns", 0)
|
||||
UI_CONFIG_VARIABLE (bool, use_wm_visibility, "use-wm-visibility", true)
|
||||
UI_CONFIG_VARIABLE (std::string, stripable_color_palette, "stripable-color-palette", "#AA3939:#FFAAAA:#D46A6A:#801515:#550000:#AA8E39:#FFEAAA:#D4BA6A:#806515:#554000:#343477:#8080B3:#565695:#1A1A59:#09093B:#2D882D:#88CC88:#55AA55:#116611:#004400") /* Gtk::ColorSelection::palette_to_string */
|
||||
|
||||
UI_CONFIG_VARIABLE (bool, show_snapped_cursor, "show-snapped-cursor", true)
|
||||
UI_CONFIG_VARIABLE (uint32_t, snap_threshold, "snap-threshold", 25)
|
||||
|
Loading…
Reference in New Issue
Block a user