mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-07 15:25:01 +01:00
finish basic distribution of EditingContext methods
This compiles but is not expected to work yet
This commit is contained in:
parent
4398fe931b
commit
e6c56b39d1
10 changed files with 351 additions and 288 deletions
|
|
@ -28,6 +28,7 @@
|
||||||
#include "actions.h"
|
#include "actions.h"
|
||||||
#include "editing_context.h"
|
#include "editing_context.h"
|
||||||
#include "editor_drag.h"
|
#include "editor_drag.h"
|
||||||
|
#include "keyboard.h"
|
||||||
#include "midi_region_view.h"
|
#include "midi_region_view.h"
|
||||||
#include "selection.h"
|
#include "selection.h"
|
||||||
#include "selection_memento.h"
|
#include "selection_memento.h"
|
||||||
|
|
@ -35,6 +36,7 @@
|
||||||
|
|
||||||
#include "pbd/i18n.h"
|
#include "pbd/i18n.h"
|
||||||
|
|
||||||
|
using namespace ARDOUR;
|
||||||
using namespace Editing;
|
using namespace Editing;
|
||||||
using namespace Glib;
|
using namespace Glib;
|
||||||
using namespace Gtk;
|
using namespace Gtk;
|
||||||
|
|
@ -93,6 +95,11 @@ EditingContext::EditingContext ()
|
||||||
, _verbose_cursor (nullptr)
|
, _verbose_cursor (nullptr)
|
||||||
, samples_per_pixel (2048)
|
, samples_per_pixel (2048)
|
||||||
, zoom_focus (ZoomFocusPlayhead)
|
, zoom_focus (ZoomFocusPlayhead)
|
||||||
|
, bbt_ruler_scale (bbt_show_many)
|
||||||
|
, bbt_bars (0)
|
||||||
|
, bbt_bar_helper_on (0)
|
||||||
|
, _visible_canvas_width (0)
|
||||||
|
, _visible_canvas_height (0)
|
||||||
{
|
{
|
||||||
grid_type_strings = I18N (_grid_type_strings);
|
grid_type_strings = I18N (_grid_type_strings);
|
||||||
|
|
||||||
|
|
@ -1359,8 +1366,8 @@ EditingContext::_snap_to_bbt (timepos_t const & presnap, Temporal::RoundMode dir
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
check_best_snap (timepos_t const & presnap, timepos_t &test, timepos_t &dist, timepos_t &best)
|
EditingContext::check_best_snap (timepos_t const & presnap, timepos_t &test, timepos_t &dist, timepos_t &best)
|
||||||
{
|
{
|
||||||
timepos_t diff = timepos_t (presnap.distance (test).abs ());
|
timepos_t diff = timepos_t (presnap.distance (test).abs ());
|
||||||
if (diff < dist) {
|
if (diff < dist) {
|
||||||
|
|
@ -1371,87 +1378,148 @@ check_best_snap (timepos_t const & presnap, timepos_t &test, timepos_t &dist, ti
|
||||||
test = timepos_t::max (test.time_domain()); // reset this so it doesn't get accidentally reused
|
test = timepos_t::max (test.time_domain()); // reset this so it doesn't get accidentally reused
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
timepos_t
|
||||||
EditingContext::snap_to_internal (timepos_t& start, Temporal::RoundMode direction, SnapPref pref, bool ensure_snap)
|
EditingContext::canvas_event_time (GdkEvent const * event, double* pcx, double* pcy) const
|
||||||
{
|
{
|
||||||
UIConfiguration const& uic (UIConfiguration::instance ());
|
timepos_t pos (canvas_event_sample (event, pcx, pcy));
|
||||||
const timepos_t presnap = start;
|
|
||||||
|
|
||||||
|
if (time_domain() == Temporal::AudioTime) {
|
||||||
timepos_t test = timepos_t::max (start.time_domain()); // for each snap, we'll use this value
|
return pos;
|
||||||
timepos_t dist = timepos_t::max (start.time_domain()); // this records the distance of the best snap result we've found so far
|
|
||||||
timepos_t best = timepos_t::max (start.time_domain()); // this records the best snap-result we've found so far
|
|
||||||
|
|
||||||
/* check Grid */
|
|
||||||
if ( (_grid_type != GridTypeNone) && (uic.get_snap_target () != SnapTargetOther) ) {
|
|
||||||
timepos_t pre (presnap);
|
|
||||||
timepos_t post (snap_to_grid (pre, direction, pref));
|
|
||||||
check_best_snap (presnap, post, dist, best);
|
|
||||||
if (uic.get_snap_target () == SnapTargetGrid) {
|
|
||||||
goto check_distance;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check snap-to-marker */
|
return timepos_t (pos.beats());
|
||||||
if ((pref == SnapToAny_Visual) && uic.get_snap_to_marks ()) {
|
|
||||||
test = snap_to_marker (presnap, direction);
|
|
||||||
check_best_snap (presnap, test, dist, best);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check snap-to-playhead */
|
|
||||||
if ((pref == SnapToAny_Visual) && uic.get_snap_to_playhead () && !_session->transport_rolling ()) {
|
|
||||||
test = timepos_t (_session->audible_sample());
|
|
||||||
check_best_snap (presnap, test, dist, best);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check snap-to-region-{start/end/sync} */
|
|
||||||
if ((pref == SnapToAny_Visual) && (uic.get_snap_to_region_start () || uic.get_snap_to_region_end () || uic.get_snap_to_region_sync ())) {
|
|
||||||
|
|
||||||
if (!region_boundary_cache.empty ()) {
|
|
||||||
|
|
||||||
vector<timepos_t>::iterator prev = region_boundary_cache.begin ();
|
|
||||||
vector<timepos_t>::iterator next = std::upper_bound (region_boundary_cache.begin (), region_boundary_cache.end (), presnap);
|
|
||||||
if (next != region_boundary_cache.begin ()) {
|
|
||||||
prev = next;
|
|
||||||
prev--;
|
|
||||||
}
|
|
||||||
if (next == region_boundary_cache.end ()) {
|
|
||||||
next--;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((direction == Temporal::RoundUpMaybe || direction == Temporal::RoundUpAlways)) {
|
|
||||||
test = *next;
|
|
||||||
} else if ((direction == Temporal::RoundDownMaybe || direction == Temporal::RoundDownAlways)) {
|
|
||||||
test = *prev;
|
|
||||||
} else if (direction == 0) {
|
|
||||||
if ((*prev).distance (presnap) < presnap.distance (*next)) {
|
|
||||||
test = *prev;
|
|
||||||
} else {
|
|
||||||
test = *next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
check_best_snap (presnap, test, dist, best);
|
|
||||||
}
|
|
||||||
|
|
||||||
check_distance:
|
|
||||||
|
|
||||||
if (timepos_t::max (start.time_domain()) == best) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* now check "magnetic" state: is the grid within reasonable on-screen distance to trigger a snap?
|
|
||||||
* this also helps to avoid snapping to somewhere the user can't see. (i.e.: I clicked on a region and it disappeared!!)
|
|
||||||
* ToDo: Perhaps this should only occur if EditPointMouse?
|
|
||||||
*/
|
|
||||||
samplecnt_t snap_threshold_s = pixel_to_sample (uic.get_snap_threshold ());
|
|
||||||
|
|
||||||
if (!ensure_snap && ::llabs (best.distance (presnap).samples()) > snap_threshold_s) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
start = best;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
samplepos_t
|
||||||
|
EditingContext::canvas_event_sample (GdkEvent const * event, double* pcx, double* pcy) const
|
||||||
|
{
|
||||||
|
double x;
|
||||||
|
double y;
|
||||||
|
|
||||||
|
/* event coordinates are already in canvas units */
|
||||||
|
|
||||||
|
if (!gdk_event_get_coords (event, &x, &y)) {
|
||||||
|
std::cerr << "!NO c COORDS for event type " << event->type << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pcx) {
|
||||||
|
*pcx = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pcy) {
|
||||||
|
*pcy = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* note that pixel_to_sample_from_event() never returns less than zero, so even if the pixel
|
||||||
|
position is negative (as can be the case with motion events in particular),
|
||||||
|
the sample location is always positive.
|
||||||
|
*/
|
||||||
|
|
||||||
|
return pixel_to_sample_from_event (x);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
EditingContext::count_bars (Beats const & start, Beats const & end) const
|
||||||
|
{
|
||||||
|
TempoMapPoints bar_grid;
|
||||||
|
TempoMap::SharedPtr tmap (TempoMap::use());
|
||||||
|
bar_grid.reserve (4096);
|
||||||
|
superclock_t s (tmap->superclock_at (start));
|
||||||
|
superclock_t e (tmap->superclock_at (end));
|
||||||
|
tmap->get_grid (bar_grid, s, e, 1);
|
||||||
|
return bar_grid.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
EditingContext::compute_bbt_ruler_scale (samplepos_t lower, samplepos_t upper)
|
||||||
|
{
|
||||||
|
if (_session == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Temporal::BBT_Time lower_beat, upper_beat; // the beats at each end of the ruler
|
||||||
|
Temporal::TempoMap::SharedPtr tmap (Temporal::TempoMap::use());
|
||||||
|
Beats floor_lower_beat = std::max (Beats(), tmap->quarters_at_sample (lower)).round_down_to_beat ();
|
||||||
|
|
||||||
|
if (floor_lower_beat < Temporal::Beats()) {
|
||||||
|
floor_lower_beat = Temporal::Beats();
|
||||||
|
}
|
||||||
|
|
||||||
|
const samplepos_t beat_before_lower_pos = tmap->sample_at (floor_lower_beat);
|
||||||
|
const samplepos_t beat_after_upper_pos = tmap->sample_at ((std::max (Beats(), tmap->quarters_at_sample (upper)).round_down_to_beat()) + Beats (1, 0));
|
||||||
|
|
||||||
|
lower_beat = Temporal::TempoMap::use()->bbt_at (timepos_t (beat_before_lower_pos));
|
||||||
|
upper_beat = Temporal::TempoMap::use()->bbt_at (timepos_t (beat_after_upper_pos));
|
||||||
|
uint32_t beats = 0;
|
||||||
|
|
||||||
|
bbt_bar_helper_on = false;
|
||||||
|
bbt_bars = 0;
|
||||||
|
|
||||||
|
bbt_ruler_scale = bbt_show_many;
|
||||||
|
|
||||||
|
const Beats ceil_upper_beat = std::max (Beats(), tmap->quarters_at_sample (upper)).round_up_to_beat() + Beats (1, 0);
|
||||||
|
|
||||||
|
if (ceil_upper_beat == floor_lower_beat) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bbt_bars = count_bars (floor_lower_beat, ceil_upper_beat);
|
||||||
|
|
||||||
|
double ruler_line_granularity = UIConfiguration::instance().get_ruler_granularity (); //in pixels
|
||||||
|
ruler_line_granularity = visible_canvas_width() / (ruler_line_granularity*5); //fudge factor '5' probably related to (4+1 beats)/measure, I think
|
||||||
|
|
||||||
|
beats = (ceil_upper_beat - floor_lower_beat).get_beats();
|
||||||
|
double beat_density = ((beats + 1) * ((double) (upper - lower) / (double) (1 + beat_after_upper_pos - beat_before_lower_pos))) / (float)ruler_line_granularity;
|
||||||
|
|
||||||
|
/* Only show the bar helper if there aren't many bars on the screen */
|
||||||
|
if ((bbt_bars < 2) || (beats < 5)) {
|
||||||
|
bbt_bar_helper_on = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (beat_density > 2048) {
|
||||||
|
bbt_ruler_scale = bbt_show_many;
|
||||||
|
} else if (beat_density > 1024) {
|
||||||
|
bbt_ruler_scale = bbt_show_64;
|
||||||
|
} else if (beat_density > 256) {
|
||||||
|
bbt_ruler_scale = bbt_show_16;
|
||||||
|
} else if (beat_density > 64) {
|
||||||
|
bbt_ruler_scale = bbt_show_4;
|
||||||
|
} else if (beat_density > 16) {
|
||||||
|
bbt_ruler_scale = bbt_show_1;
|
||||||
|
} else if (beat_density > 4) {
|
||||||
|
bbt_ruler_scale = bbt_show_quarters;
|
||||||
|
} else if (beat_density > 2) {
|
||||||
|
bbt_ruler_scale = bbt_show_eighths;
|
||||||
|
} else if (beat_density > 1) {
|
||||||
|
bbt_ruler_scale = bbt_show_sixteenths;
|
||||||
|
} else if (beat_density > 0.5) {
|
||||||
|
bbt_ruler_scale = bbt_show_thirtyseconds;
|
||||||
|
} else if (beat_density > 0.25) {
|
||||||
|
bbt_ruler_scale = bbt_show_sixtyfourths;
|
||||||
|
} else {
|
||||||
|
bbt_ruler_scale = bbt_show_onetwentyeighths;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now that we know how fine a grid (Ruler) is allowable on this screen, limit it to the coarseness selected by the user */
|
||||||
|
/* note: GridType and RulerScale are not the same enums, so it's not a simple mathematical operation */
|
||||||
|
int suggested_scale = (int) bbt_ruler_scale;
|
||||||
|
int divs = get_grid_music_divisions(_grid_type, 0);
|
||||||
|
if (_grid_type == GridTypeBar) {
|
||||||
|
suggested_scale = std::min(suggested_scale, (int) bbt_show_1);
|
||||||
|
} else if (_grid_type == GridTypeBeat) {
|
||||||
|
suggested_scale = std::min(suggested_scale, (int) bbt_show_quarters);
|
||||||
|
} else if ( divs < 4 ) {
|
||||||
|
suggested_scale = std::min(suggested_scale, (int) bbt_show_eighths);
|
||||||
|
} else if ( divs < 8 ) {
|
||||||
|
suggested_scale = std::min(suggested_scale, (int) bbt_show_sixteenths);
|
||||||
|
} else if ( divs < 16 ) {
|
||||||
|
suggested_scale = std::min(suggested_scale, (int) bbt_show_thirtyseconds);
|
||||||
|
} else if ( divs < 32 ) {
|
||||||
|
suggested_scale = std::min(suggested_scale, (int) bbt_show_sixtyfourths);
|
||||||
|
} else {
|
||||||
|
suggested_scale = std::min(suggested_scale, (int) bbt_show_onetwentyeighths);
|
||||||
|
}
|
||||||
|
|
||||||
|
bbt_ruler_scale = (EditingContext::BBTRulerScale) suggested_scale;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -142,7 +142,6 @@ public:
|
||||||
|
|
||||||
virtual void set_selected_midi_region_view (MidiRegionView&);
|
virtual void set_selected_midi_region_view (MidiRegionView&);
|
||||||
|
|
||||||
|
|
||||||
/* NOTE: these functions assume that the "pixel" coordinate is
|
/* NOTE: these functions assume that the "pixel" coordinate is
|
||||||
in canvas coordinates. These coordinates already take into
|
in canvas coordinates. These coordinates already take into
|
||||||
account any scrolling offsets.
|
account any scrolling offsets.
|
||||||
|
|
@ -180,16 +179,17 @@ public:
|
||||||
double duration_to_pixels (Temporal::timecnt_t const & pos) const;
|
double duration_to_pixels (Temporal::timecnt_t const & pos) const;
|
||||||
double duration_to_pixels_unrounded (Temporal::timecnt_t const & pos) const;
|
double duration_to_pixels_unrounded (Temporal::timecnt_t const & pos) const;
|
||||||
|
|
||||||
/** computes the timeline sample (sample) of an event whose coordinates
|
|
||||||
* are in canvas units (pixels, scroll offset included).
|
|
||||||
*/
|
|
||||||
virtual samplepos_t canvas_event_sample (GdkEvent const * event, double* pcx = nullptr, double* pcy = nullptr) const = 0;
|
|
||||||
/** computes the timeline position for an event whose coordinates
|
/** computes the timeline position for an event whose coordinates
|
||||||
* are in canvas units (pixels, scroll offset included). The time
|
* are in canvas units (pixels, scroll offset included). The time
|
||||||
* domain used by the return value will match ::default_time_domain()
|
* domain used by the return value will match ::default_time_domain()
|
||||||
* at the time of calling.
|
* at the time of calling.
|
||||||
*/
|
*/
|
||||||
virtual Temporal::timepos_t canvas_event_time (GdkEvent const*, double* px = nullptr, double* py = nullptr) const = 0;
|
Temporal::timepos_t canvas_event_time (GdkEvent const*, double* px = 0, double* py = 0) const;
|
||||||
|
|
||||||
|
/** computes the timeline sample (sample) of an event whose coordinates
|
||||||
|
* are in canvas units (pixels, scroll offset included).
|
||||||
|
*/
|
||||||
|
samplepos_t canvas_event_sample (GdkEvent const * event, double* pcx = nullptr, double* pcy = nullptr) const;
|
||||||
|
|
||||||
virtual Temporal::Beats get_grid_type_as_beats (bool& success, Temporal::timepos_t const & position) = 0;
|
virtual Temporal::Beats get_grid_type_as_beats (bool& success, Temporal::timepos_t const & position) = 0;
|
||||||
virtual Temporal::Beats get_draw_length_as_beats (bool& success, Temporal::timepos_t const & position) = 0;
|
virtual Temporal::Beats get_draw_length_as_beats (bool& success, Temporal::timepos_t const & position) = 0;
|
||||||
|
|
@ -346,7 +346,6 @@ public:
|
||||||
ArdourWidgets::ArdourButton snap_mode_button;
|
ArdourWidgets::ArdourButton snap_mode_button;
|
||||||
|
|
||||||
virtual void mark_region_boundary_cache_dirty () {}
|
virtual void mark_region_boundary_cache_dirty () {}
|
||||||
virtual void compute_bbt_ruler_scale (samplepos_t, samplepos_t) {}
|
|
||||||
virtual void update_tempo_based_rulers () {};
|
virtual void update_tempo_based_rulers () {};
|
||||||
virtual void show_rulers_for_grid () {};
|
virtual void show_rulers_for_grid () {};
|
||||||
virtual samplecnt_t current_page_samples() const = 0;
|
virtual samplecnt_t current_page_samples() const = 0;
|
||||||
|
|
@ -381,10 +380,41 @@ public:
|
||||||
ARDOUR::SnapPref gpref,
|
ARDOUR::SnapPref gpref,
|
||||||
Editing::GridType grid_type);
|
Editing::GridType grid_type);
|
||||||
|
|
||||||
void snap_to_internal (Temporal::timepos_t& first,
|
virtual Temporal::timepos_t snap_to_grid (Temporal::timepos_t const & start,
|
||||||
Temporal::RoundMode direction = Temporal::RoundNearest,
|
Temporal::RoundMode direction,
|
||||||
ARDOUR::SnapPref gpref = ARDOUR::SnapToAny_Visual,
|
ARDOUR::SnapPref gpref) = 0;
|
||||||
bool ensure_snap = false);
|
|
||||||
|
virtual void snap_to_internal (Temporal::timepos_t& first,
|
||||||
|
Temporal::RoundMode direction = Temporal::RoundNearest,
|
||||||
|
ARDOUR::SnapPref gpref = ARDOUR::SnapToAny_Visual,
|
||||||
|
bool ensure_snap = false) = 0;
|
||||||
|
|
||||||
|
void check_best_snap (Temporal::timepos_t const & presnap, Temporal::timepos_t &test, Temporal::timepos_t &dist, Temporal::timepos_t &best);
|
||||||
|
virtual double visible_canvas_width() const = 0;
|
||||||
|
|
||||||
|
enum BBTRulerScale {
|
||||||
|
bbt_show_many,
|
||||||
|
bbt_show_64,
|
||||||
|
bbt_show_16,
|
||||||
|
bbt_show_4,
|
||||||
|
bbt_show_1,
|
||||||
|
bbt_show_quarters,
|
||||||
|
bbt_show_eighths,
|
||||||
|
bbt_show_sixteenths,
|
||||||
|
bbt_show_thirtyseconds,
|
||||||
|
bbt_show_sixtyfourths,
|
||||||
|
bbt_show_onetwentyeighths
|
||||||
|
};
|
||||||
|
|
||||||
|
BBTRulerScale bbt_ruler_scale;
|
||||||
|
uint32_t bbt_bars;
|
||||||
|
uint32_t bbt_bar_helper_on;
|
||||||
|
|
||||||
|
uint32_t count_bars (Temporal::Beats const & start, Temporal::Beats const & end) const;
|
||||||
|
void compute_bbt_ruler_scale (samplepos_t lower, samplepos_t upper);
|
||||||
|
|
||||||
|
double _visible_canvas_width;
|
||||||
|
double _visible_canvas_height; ///< height of the visible area of the track canvas
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -278,9 +278,6 @@ Editor::Editor ()
|
||||||
, timecode_mark_modulo (0)
|
, timecode_mark_modulo (0)
|
||||||
, timecode_nmarks (0)
|
, timecode_nmarks (0)
|
||||||
, _samples_ruler_interval (0)
|
, _samples_ruler_interval (0)
|
||||||
, bbt_ruler_scale (bbt_show_many)
|
|
||||||
, bbt_bars (0)
|
|
||||||
, bbt_bar_helper_on (0)
|
|
||||||
, timecode_ruler (0)
|
, timecode_ruler (0)
|
||||||
, bbt_ruler (0)
|
, bbt_ruler (0)
|
||||||
, samples_ruler (0)
|
, samples_ruler (0)
|
||||||
|
|
@ -312,8 +309,6 @@ Editor::Editor ()
|
||||||
, unused_adjustment (0.0, 0.0, 10.0, 400.0)
|
, unused_adjustment (0.0, 0.0, 10.0, 400.0)
|
||||||
, controls_layout (unused_adjustment, vertical_adjustment)
|
, controls_layout (unused_adjustment, vertical_adjustment)
|
||||||
, _scroll_callbacks (0)
|
, _scroll_callbacks (0)
|
||||||
, _visible_canvas_width (0)
|
|
||||||
, _visible_canvas_height (0)
|
|
||||||
, _full_canvas_height (0)
|
, _full_canvas_height (0)
|
||||||
, edit_controls_left_menu (0)
|
, edit_controls_left_menu (0)
|
||||||
, edit_controls_right_menu (0)
|
, edit_controls_right_menu (0)
|
||||||
|
|
@ -6512,3 +6507,87 @@ Editor::track_dragging() const
|
||||||
return (bool) track_drag;
|
return (bool) track_drag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Editor::snap_to_internal (timepos_t& start, Temporal::RoundMode direction, SnapPref pref, bool ensure_snap)
|
||||||
|
{
|
||||||
|
UIConfiguration const& uic (UIConfiguration::instance ());
|
||||||
|
const timepos_t presnap = start;
|
||||||
|
|
||||||
|
|
||||||
|
timepos_t test = timepos_t::max (start.time_domain()); // for each snap, we'll use this value
|
||||||
|
timepos_t dist = timepos_t::max (start.time_domain()); // this records the distance of the best snap result we've found so far
|
||||||
|
timepos_t best = timepos_t::max (start.time_domain()); // this records the best snap-result we've found so far
|
||||||
|
|
||||||
|
/* check Grid */
|
||||||
|
if ( (_grid_type != GridTypeNone) && (uic.get_snap_target () != SnapTargetOther) ) {
|
||||||
|
timepos_t pre (presnap);
|
||||||
|
timepos_t post (snap_to_grid (pre, direction, pref));
|
||||||
|
check_best_snap (presnap, post, dist, best);
|
||||||
|
if (uic.get_snap_target () == SnapTargetGrid) {
|
||||||
|
goto check_distance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check snap-to-marker */
|
||||||
|
if ((pref == SnapToAny_Visual) && uic.get_snap_to_marks ()) {
|
||||||
|
test = snap_to_marker (presnap, direction);
|
||||||
|
check_best_snap (presnap, test, dist, best);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check snap-to-playhead */
|
||||||
|
if ((pref == SnapToAny_Visual) && uic.get_snap_to_playhead () && !_session->transport_rolling ()) {
|
||||||
|
test = timepos_t (_session->audible_sample());
|
||||||
|
check_best_snap (presnap, test, dist, best);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check snap-to-region-{start/end/sync} */
|
||||||
|
if ((pref == SnapToAny_Visual) && (uic.get_snap_to_region_start () || uic.get_snap_to_region_end () || uic.get_snap_to_region_sync ())) {
|
||||||
|
|
||||||
|
if (!region_boundary_cache.empty ()) {
|
||||||
|
|
||||||
|
vector<timepos_t>::iterator prev = region_boundary_cache.begin ();
|
||||||
|
vector<timepos_t>::iterator next = std::upper_bound (region_boundary_cache.begin (), region_boundary_cache.end (), presnap);
|
||||||
|
if (next != region_boundary_cache.begin ()) {
|
||||||
|
prev = next;
|
||||||
|
prev--;
|
||||||
|
}
|
||||||
|
if (next == region_boundary_cache.end ()) {
|
||||||
|
next--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((direction == Temporal::RoundUpMaybe || direction == Temporal::RoundUpAlways)) {
|
||||||
|
test = *next;
|
||||||
|
} else if ((direction == Temporal::RoundDownMaybe || direction == Temporal::RoundDownAlways)) {
|
||||||
|
test = *prev;
|
||||||
|
} else if (direction == 0) {
|
||||||
|
if ((*prev).distance (presnap) < presnap.distance (*next)) {
|
||||||
|
test = *prev;
|
||||||
|
} else {
|
||||||
|
test = *next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
check_best_snap (presnap, test, dist, best);
|
||||||
|
}
|
||||||
|
|
||||||
|
check_distance:
|
||||||
|
|
||||||
|
if (timepos_t::max (start.time_domain()) == best) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* now check "magnetic" state: is the grid within reasonable on-screen distance to trigger a snap?
|
||||||
|
* this also helps to avoid snapping to somewhere the user can't see. (i.e.: I clicked on a region and it disappeared!!)
|
||||||
|
* ToDo: Perhaps this should only occur if EditPointMouse?
|
||||||
|
*/
|
||||||
|
samplecnt_t snap_threshold_s = pixel_to_sample (uic.get_snap_threshold ());
|
||||||
|
|
||||||
|
if (!ensure_snap && ::llabs (best.distance (presnap).samples()) > snap_threshold_s) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
start = best;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -927,27 +927,6 @@ private:
|
||||||
samplecnt_t _samples_ruler_interval;
|
samplecnt_t _samples_ruler_interval;
|
||||||
void set_samples_ruler_scale (samplepos_t, samplepos_t);
|
void set_samples_ruler_scale (samplepos_t, samplepos_t);
|
||||||
|
|
||||||
enum BBTRulerScale {
|
|
||||||
bbt_show_many,
|
|
||||||
bbt_show_64,
|
|
||||||
bbt_show_16,
|
|
||||||
bbt_show_4,
|
|
||||||
bbt_show_1,
|
|
||||||
bbt_show_quarters,
|
|
||||||
bbt_show_eighths,
|
|
||||||
bbt_show_sixteenths,
|
|
||||||
bbt_show_thirtyseconds,
|
|
||||||
bbt_show_sixtyfourths,
|
|
||||||
bbt_show_onetwentyeighths
|
|
||||||
};
|
|
||||||
|
|
||||||
BBTRulerScale bbt_ruler_scale;
|
|
||||||
uint32_t bbt_bars;
|
|
||||||
uint32_t bbt_bar_helper_on;
|
|
||||||
|
|
||||||
uint32_t count_bars (Temporal::Beats const & start, Temporal::Beats const & end) const;
|
|
||||||
void compute_bbt_ruler_scale (samplepos_t lower, samplepos_t upper);
|
|
||||||
|
|
||||||
ArdourCanvas::Ruler* timecode_ruler;
|
ArdourCanvas::Ruler* timecode_ruler;
|
||||||
ArdourCanvas::Ruler* bbt_ruler;
|
ArdourCanvas::Ruler* bbt_ruler;
|
||||||
ArdourCanvas::Ruler* samples_ruler;
|
ArdourCanvas::Ruler* samples_ruler;
|
||||||
|
|
@ -1063,8 +1042,6 @@ private:
|
||||||
sigc::connection _scroll_connection;
|
sigc::connection _scroll_connection;
|
||||||
int _scroll_callbacks;
|
int _scroll_callbacks;
|
||||||
|
|
||||||
double _visible_canvas_width;
|
|
||||||
double _visible_canvas_height; ///< height of the visible area of the track canvas
|
|
||||||
double _full_canvas_height; ///< full height of the canvas
|
double _full_canvas_height; ///< full height of the canvas
|
||||||
|
|
||||||
bool track_canvas_map_handler (GdkEventAny*);
|
bool track_canvas_map_handler (GdkEventAny*);
|
||||||
|
|
@ -2113,18 +2090,6 @@ private:
|
||||||
void duplicate_range (bool with_dialog);
|
void duplicate_range (bool with_dialog);
|
||||||
void duplicate_regions (float times);
|
void duplicate_regions (float times);
|
||||||
|
|
||||||
/** computes the timeline sample (sample) of an event whose coordinates
|
|
||||||
* are in canvas units (pixels, scroll offset included).
|
|
||||||
*/
|
|
||||||
samplepos_t canvas_event_sample (GdkEvent const*, double* px = 0, double* py = 0) const;
|
|
||||||
|
|
||||||
/** computes the timeline position for an event whose coordinates
|
|
||||||
* are in canvas units (pixels, scroll offset included). The time
|
|
||||||
* domain used by the return value will match Editor::default_time_domain()
|
|
||||||
* at the time of calling.
|
|
||||||
*/
|
|
||||||
Temporal::timepos_t canvas_event_time (GdkEvent const*, double* px = 0, double* py = 0) const;
|
|
||||||
|
|
||||||
/** computes the timeline sample (sample) of an event whose coordinates
|
/** computes the timeline sample (sample) of an event whose coordinates
|
||||||
* are in window units (pixels, no scroll offset).
|
* are in window units (pixels, no scroll offset).
|
||||||
*/
|
*/
|
||||||
|
|
@ -2277,13 +2242,16 @@ private:
|
||||||
Temporal::RoundMode direction,
|
Temporal::RoundMode direction,
|
||||||
ARDOUR::SnapPref gpref);
|
ARDOUR::SnapPref gpref);
|
||||||
|
|
||||||
void timecode_snap_to_internal (Temporal::timepos_t & first,
|
void snap_to_internal (Temporal::timepos_t & first,
|
||||||
Temporal::RoundMode direction = Temporal::RoundNearest,
|
Temporal::RoundMode direction = Temporal::RoundNearest,
|
||||||
bool for_mark = false);
|
ARDOUR::SnapPref gpref = ARDOUR::SnapToAny_Visual,
|
||||||
|
bool for_mark = false);
|
||||||
|
|
||||||
Temporal::timepos_t snap_to_marker (Temporal::timepos_t const & presnap,
|
Temporal::timepos_t snap_to_marker (Temporal::timepos_t const & presnap,
|
||||||
Temporal::RoundMode direction = Temporal::RoundNearest);
|
Temporal::RoundMode direction = Temporal::RoundNearest);
|
||||||
|
|
||||||
|
double visible_canvas_width() const { return _visible_canvas_width; }
|
||||||
|
|
||||||
RhythmFerret* rhythm_ferret;
|
RhythmFerret* rhythm_ferret;
|
||||||
|
|
||||||
void fit_tracks (TrackViewList &);
|
void fit_tracks (TrackViewList &);
|
||||||
|
|
|
||||||
|
|
@ -170,47 +170,6 @@ Editor::window_event_sample (GdkEvent const * event, double* pcx, double* pcy) c
|
||||||
return pixel_to_sample (d.x);
|
return pixel_to_sample (d.x);
|
||||||
}
|
}
|
||||||
|
|
||||||
timepos_t
|
|
||||||
Editor::canvas_event_time (GdkEvent const * event, double* pcx, double* pcy) const
|
|
||||||
{
|
|
||||||
timepos_t pos (canvas_event_sample (event, pcx, pcy));
|
|
||||||
|
|
||||||
if (time_domain() == Temporal::AudioTime) {
|
|
||||||
return pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
return timepos_t (pos.beats());
|
|
||||||
}
|
|
||||||
|
|
||||||
samplepos_t
|
|
||||||
Editor::canvas_event_sample (GdkEvent const * event, double* pcx, double* pcy) const
|
|
||||||
{
|
|
||||||
double x;
|
|
||||||
double y;
|
|
||||||
|
|
||||||
/* event coordinates are already in canvas units */
|
|
||||||
|
|
||||||
if (!gdk_event_get_coords (event, &x, &y)) {
|
|
||||||
cerr << "!NO c COORDS for event type " << event->type << endl;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pcx) {
|
|
||||||
*pcx = x;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pcy) {
|
|
||||||
*pcy = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* note that pixel_to_sample_from_event() never returns less than zero, so even if the pixel
|
|
||||||
position is negative (as can be the case with motion events in particular),
|
|
||||||
the sample location is always positive.
|
|
||||||
*/
|
|
||||||
|
|
||||||
return pixel_to_sample_from_event (x);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Editor::set_current_trimmable (std::shared_ptr<Trimmable> t)
|
Editor::set_current_trimmable (std::shared_ptr<Trimmable> t)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1045,111 +1045,6 @@ Editor::metric_get_timecode (std::vector<ArdourCanvas::Ruler::Mark>& marks, int6
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t
|
|
||||||
Editor::count_bars (Beats const & start, Beats const & end) const
|
|
||||||
{
|
|
||||||
TempoMapPoints bar_grid;
|
|
||||||
TempoMap::SharedPtr tmap (TempoMap::use());
|
|
||||||
bar_grid.reserve (4096);
|
|
||||||
superclock_t s (tmap->superclock_at (start));
|
|
||||||
superclock_t e (tmap->superclock_at (end));
|
|
||||||
tmap->get_grid (bar_grid, s, e, 1);
|
|
||||||
return bar_grid.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Editor::compute_bbt_ruler_scale (samplepos_t lower, samplepos_t upper)
|
|
||||||
{
|
|
||||||
if (_session == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Temporal::BBT_Time lower_beat, upper_beat; // the beats at each end of the ruler
|
|
||||||
Temporal::TempoMap::SharedPtr tmap (Temporal::TempoMap::use());
|
|
||||||
Beats floor_lower_beat = std::max (Beats(), tmap->quarters_at_sample (lower)).round_down_to_beat ();
|
|
||||||
|
|
||||||
if (floor_lower_beat < Temporal::Beats()) {
|
|
||||||
floor_lower_beat = Temporal::Beats();
|
|
||||||
}
|
|
||||||
|
|
||||||
const samplepos_t beat_before_lower_pos = tmap->sample_at (floor_lower_beat);
|
|
||||||
const samplepos_t beat_after_upper_pos = tmap->sample_at ((std::max (Beats(), tmap->quarters_at_sample (upper)).round_down_to_beat()) + Beats (1, 0));
|
|
||||||
|
|
||||||
lower_beat = Temporal::TempoMap::use()->bbt_at (timepos_t (beat_before_lower_pos));
|
|
||||||
upper_beat = Temporal::TempoMap::use()->bbt_at (timepos_t (beat_after_upper_pos));
|
|
||||||
uint32_t beats = 0;
|
|
||||||
|
|
||||||
bbt_bar_helper_on = false;
|
|
||||||
bbt_bars = 0;
|
|
||||||
|
|
||||||
bbt_ruler_scale = bbt_show_many;
|
|
||||||
|
|
||||||
const Beats ceil_upper_beat = std::max (Beats(), tmap->quarters_at_sample (upper)).round_up_to_beat() + Beats (1, 0);
|
|
||||||
|
|
||||||
if (ceil_upper_beat == floor_lower_beat) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bbt_bars = count_bars (floor_lower_beat, ceil_upper_beat);
|
|
||||||
|
|
||||||
double ruler_line_granularity = UIConfiguration::instance().get_ruler_granularity (); //in pixels
|
|
||||||
ruler_line_granularity = _visible_canvas_width / (ruler_line_granularity*5); //fudge factor '5' probably related to (4+1 beats)/measure, I think
|
|
||||||
|
|
||||||
beats = (ceil_upper_beat - floor_lower_beat).get_beats();
|
|
||||||
double beat_density = ((beats + 1) * ((double) (upper - lower) / (double) (1 + beat_after_upper_pos - beat_before_lower_pos))) / (float)ruler_line_granularity;
|
|
||||||
|
|
||||||
/* Only show the bar helper if there aren't many bars on the screen */
|
|
||||||
if ((bbt_bars < 2) || (beats < 5)) {
|
|
||||||
bbt_bar_helper_on = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (beat_density > 2048) {
|
|
||||||
bbt_ruler_scale = bbt_show_many;
|
|
||||||
} else if (beat_density > 1024) {
|
|
||||||
bbt_ruler_scale = bbt_show_64;
|
|
||||||
} else if (beat_density > 256) {
|
|
||||||
bbt_ruler_scale = bbt_show_16;
|
|
||||||
} else if (beat_density > 64) {
|
|
||||||
bbt_ruler_scale = bbt_show_4;
|
|
||||||
} else if (beat_density > 16) {
|
|
||||||
bbt_ruler_scale = bbt_show_1;
|
|
||||||
} else if (beat_density > 4) {
|
|
||||||
bbt_ruler_scale = bbt_show_quarters;
|
|
||||||
} else if (beat_density > 2) {
|
|
||||||
bbt_ruler_scale = bbt_show_eighths;
|
|
||||||
} else if (beat_density > 1) {
|
|
||||||
bbt_ruler_scale = bbt_show_sixteenths;
|
|
||||||
} else if (beat_density > 0.5) {
|
|
||||||
bbt_ruler_scale = bbt_show_thirtyseconds;
|
|
||||||
} else if (beat_density > 0.25) {
|
|
||||||
bbt_ruler_scale = bbt_show_sixtyfourths;
|
|
||||||
} else {
|
|
||||||
bbt_ruler_scale = bbt_show_onetwentyeighths;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now that we know how fine a grid (Ruler) is allowable on this screen, limit it to the coarseness selected by the user */
|
|
||||||
/* note: GridType and RulerScale are not the same enums, so it's not a simple mathematical operation */
|
|
||||||
int suggested_scale = (int) bbt_ruler_scale;
|
|
||||||
int divs = get_grid_music_divisions(_grid_type, 0);
|
|
||||||
if (_grid_type == GridTypeBar) {
|
|
||||||
suggested_scale = std::min(suggested_scale, (int) bbt_show_1);
|
|
||||||
} else if (_grid_type == GridTypeBeat) {
|
|
||||||
suggested_scale = std::min(suggested_scale, (int) bbt_show_quarters);
|
|
||||||
} else if ( divs < 4 ) {
|
|
||||||
suggested_scale = std::min(suggested_scale, (int) bbt_show_eighths);
|
|
||||||
} else if ( divs < 8 ) {
|
|
||||||
suggested_scale = std::min(suggested_scale, (int) bbt_show_sixteenths);
|
|
||||||
} else if ( divs < 16 ) {
|
|
||||||
suggested_scale = std::min(suggested_scale, (int) bbt_show_thirtyseconds);
|
|
||||||
} else if ( divs < 32 ) {
|
|
||||||
suggested_scale = std::min(suggested_scale, (int) bbt_show_sixtyfourths);
|
|
||||||
} else {
|
|
||||||
suggested_scale = std::min(suggested_scale, (int) bbt_show_onetwentyeighths);
|
|
||||||
}
|
|
||||||
|
|
||||||
bbt_ruler_scale = (Editor::BBTRulerScale) suggested_scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
edit_last_mark_label (std::vector<ArdourCanvas::Ruler::Mark>& marks, const std::string& newlabel)
|
edit_last_mark_label (std::vector<ArdourCanvas::Ruler::Mark>& marks, const std::string& newlabel)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ MidiClipEditorBox::MidiClipEditorBox ()
|
||||||
_header_label.set_alignment (0.0, 0.5);
|
_header_label.set_alignment (0.0, 0.5);
|
||||||
pack_start (_header_label, false, false, 6);
|
pack_start (_header_label, false, false, 6);
|
||||||
|
|
||||||
editor = manage (new MidiCueEditor ());
|
editor = new MidiCueEditor ();
|
||||||
editor->viewport().set_size_request (600, 120);
|
editor->viewport().set_size_request (600, 120);
|
||||||
|
|
||||||
pack_start (editor->viewport(), true, true);
|
pack_start (editor->viewport(), true, true);
|
||||||
|
|
@ -68,6 +68,7 @@ MidiClipEditorBox::MidiClipEditorBox ()
|
||||||
|
|
||||||
MidiClipEditorBox::~MidiClipEditorBox ()
|
MidiClipEditorBox::~MidiClipEditorBox ()
|
||||||
{
|
{
|
||||||
|
delete editor;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,9 @@
|
||||||
#include "midi_cue_editor.h"
|
#include "midi_cue_editor.h"
|
||||||
#include "ui_config.h"
|
#include "ui_config.h"
|
||||||
|
|
||||||
|
using namespace ARDOUR;
|
||||||
using namespace ArdourCanvas;
|
using namespace ArdourCanvas;
|
||||||
|
using namespace Temporal;
|
||||||
|
|
||||||
MidiCueEditor::MidiCueEditor()
|
MidiCueEditor::MidiCueEditor()
|
||||||
: vertical_adjustment (0.0, 0.0, 10.0, 400.0)
|
: vertical_adjustment (0.0, 0.0, 10.0, 400.0)
|
||||||
|
|
@ -90,3 +92,50 @@ MidiCueEditor::build_canvas ()
|
||||||
rubberband_rect->hide();
|
rubberband_rect->hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
timepos_t
|
||||||
|
MidiCueEditor::snap_to_grid (timepos_t const & presnap, Temporal::RoundMode direction, SnapPref gpref)
|
||||||
|
{
|
||||||
|
/* BBT time only */
|
||||||
|
return snap_to_bbt (presnap, direction, gpref);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
MidiCueEditor::snap_to_internal (timepos_t& start, Temporal::RoundMode direction, SnapPref pref, bool ensure_snap)
|
||||||
|
{
|
||||||
|
UIConfiguration const& uic (UIConfiguration::instance ());
|
||||||
|
const timepos_t presnap = start;
|
||||||
|
|
||||||
|
|
||||||
|
timepos_t dist = timepos_t::max (start.time_domain()); // this records the distance of the best snap result we've found so far
|
||||||
|
timepos_t best = timepos_t::max (start.time_domain()); // this records the best snap-result we've found so far
|
||||||
|
|
||||||
|
timepos_t pre (presnap);
|
||||||
|
timepos_t post (snap_to_grid (pre, direction, pref));
|
||||||
|
|
||||||
|
check_best_snap (presnap, post, dist, best);
|
||||||
|
|
||||||
|
if (timepos_t::max (start.time_domain()) == best) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* now check "magnetic" state: is the grid within reasonable on-screen distance to trigger a snap?
|
||||||
|
* this also helps to avoid snapping to somewhere the user can't see. (i.e.: I clicked on a region and it disappeared!!)
|
||||||
|
* ToDo: Perhaps this should only occur if EditPointMouse?
|
||||||
|
*/
|
||||||
|
samplecnt_t snap_threshold_s = pixel_to_sample (uic.get_snap_threshold ());
|
||||||
|
|
||||||
|
if (!ensure_snap && ::llabs (best.distance (presnap).samples()) > snap_threshold_s) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
start = best;
|
||||||
|
}
|
||||||
|
|
||||||
|
samplecnt_t
|
||||||
|
MidiCueEditor::current_page_samples() const
|
||||||
|
{
|
||||||
|
return (samplecnt_t) _visible_canvas_width* samples_per_pixel;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,27 @@ class MidiCueEditor : public CueEditor
|
||||||
ArdourCanvas::Container* get_noscroll_group() const { return no_scroll_group; }
|
ArdourCanvas::Container* get_noscroll_group() const { return no_scroll_group; }
|
||||||
Gtk::Widget& viewport() { return *_canvas_viewport; }
|
Gtk::Widget& viewport() { return *_canvas_viewport; }
|
||||||
|
|
||||||
|
double visible_canvas_width() const { return _visible_canvas_width; }
|
||||||
|
samplecnt_t current_page_samples() const;
|
||||||
|
|
||||||
|
void get_per_region_note_selection (std::list<std::pair<PBD::ID, std::set<std::shared_ptr<Evoral::Note<Temporal::Beats> > > > >&) const {}
|
||||||
|
|
||||||
|
Temporal::Beats get_grid_type_as_beats (bool& success, Temporal::timepos_t const & position) { return Temporal::Beats (1, 0); }
|
||||||
|
Temporal::Beats get_draw_length_as_beats (bool& success, Temporal::timepos_t const & position) { return Temporal::Beats (1, 0); }
|
||||||
|
|
||||||
|
int32_t get_grid_beat_divisions (Editing::GridType gt) { return 1; }
|
||||||
|
int32_t get_grid_music_divisions (Editing::GridType gt, uint32_t event_state) { return 1; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Temporal::timepos_t snap_to_grid (Temporal::timepos_t const & start,
|
||||||
|
Temporal::RoundMode direction,
|
||||||
|
ARDOUR::SnapPref gpref);
|
||||||
|
|
||||||
|
void snap_to_internal (Temporal::timepos_t& first,
|
||||||
|
Temporal::RoundMode direction = Temporal::RoundNearest,
|
||||||
|
ARDOUR::SnapPref gpref = ARDOUR::SnapToAny_Visual,
|
||||||
|
bool ensure_snap = false);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Gtk::Adjustment vertical_adjustment;
|
Gtk::Adjustment vertical_adjustment;
|
||||||
Gtk::Adjustment horizontal_adjustment;
|
Gtk::Adjustment horizontal_adjustment;
|
||||||
|
|
|
||||||
|
|
@ -452,13 +452,6 @@ public:
|
||||||
|
|
||||||
virtual std::pair <Temporal::timepos_t, Temporal::timepos_t> session_gui_extents (bool use_extra = true) const = 0;
|
virtual std::pair <Temporal::timepos_t, Temporal::timepos_t> session_gui_extents (bool use_extra = true) const = 0;
|
||||||
|
|
||||||
virtual void snap_to_with_modifier (Temporal::timepos_t & first,
|
|
||||||
GdkEvent const* ev,
|
|
||||||
Temporal::RoundMode direction = Temporal::RoundNearest,
|
|
||||||
ARDOUR::SnapPref gpref = ARDOUR::SnapToAny_Visual,
|
|
||||||
bool ensure_snap = false) = 0;
|
|
||||||
virtual Temporal::timepos_t snap_to_bbt (Temporal::timepos_t const & pos, Temporal::RoundMode, ARDOUR::SnapPref) = 0;
|
|
||||||
|
|
||||||
virtual void get_regions_at (RegionSelection &, Temporal::timepos_t const & where, TrackViewList const &) const = 0;
|
virtual void get_regions_at (RegionSelection &, Temporal::timepos_t const & where, TrackViewList const &) const = 0;
|
||||||
virtual void get_regions_after (RegionSelection&, Temporal::timepos_t const & where, const TrackViewList& ts) const = 0;
|
virtual void get_regions_after (RegionSelection&, Temporal::timepos_t const & where, const TrackViewList& ts) const = 0;
|
||||||
virtual RegionSelection get_regions_from_selection_and_mouse (Temporal::timepos_t const &) = 0;
|
virtual RegionSelection get_regions_from_selection_and_mouse (Temporal::timepos_t const &) = 0;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue