diff --git a/gtk2_ardour/cue_editor.h b/gtk2_ardour/cue_editor.h index bddc655a39..bd079405fd 100644 --- a/gtk2_ardour/cue_editor.h +++ b/gtk2_ardour/cue_editor.h @@ -33,6 +33,8 @@ class CueEditor : public EditingContext void get_regionviews_by_id (PBD::ID const id, RegionSelection & regions) const; StripableTimeAxisView* get_stripable_time_axis_by_id (const PBD::ID& id) const; TrackViewList axis_views_from_routes (std::shared_ptr) const; + AxisView* axis_view_by_stripable (std::shared_ptr) const { return nullptr; } + AxisView* axis_view_by_control (std::shared_ptr) const { return nullptr; } ARDOUR::Location* find_location_from_marker (ArdourMarker*, bool&) const; ArdourMarker* find_marker_from_location_id (PBD::ID const&, bool) const; diff --git a/gtk2_ardour/editing_context.cc b/gtk2_ardour/editing_context.cc index e65d02431d..f4a0f5f6ad 100644 --- a/gtk2_ardour/editing_context.cc +++ b/gtk2_ardour/editing_context.cc @@ -40,6 +40,7 @@ using namespace Glib; using namespace Gtk; using namespace Gtkmm2ext; using namespace PBD; +using namespace Temporal; using std::string; sigc::signal EditingContext::DropDownKeys; @@ -90,6 +91,8 @@ EditingContext::EditingContext () , _selection_memento (new SelectionMemento()) , _cursors (nullptr) , _verbose_cursor (nullptr) + , samples_per_pixel (2048) + , zoom_focus (ZoomFocusPlayhead) { grid_type_strings = I18N (_grid_type_strings); @@ -1172,3 +1175,283 @@ EditingContext::commit_reversible_command () } } +double +EditingContext::time_to_pixel (timepos_t const & pos) const +{ + return sample_to_pixel (pos.samples()); +} + +double +EditingContext::time_to_pixel_unrounded (timepos_t const & pos) const +{ + return sample_to_pixel_unrounded (pos.samples()); +} + +double +EditingContext::duration_to_pixels (timecnt_t const & dur) const +{ + return sample_to_pixel (dur.samples()); +} + +double +EditingContext::duration_to_pixels_unrounded (timecnt_t const & dur) const +{ + return sample_to_pixel_unrounded (dur.samples()); +} + +/** 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. + * @param event Event to get current key modifier information from, or 0. + */ +void +EditingContext::snap_to_with_modifier (timepos_t& start, GdkEvent const * event, Temporal::RoundMode direction, SnapPref pref, bool ensure_snap) +{ + if (!_session || !event) { + return; + } + + if (ArdourKeyboard::indicates_snap (event->button.state)) { + if (_snap_mode == SnapOff) { + snap_to_internal (start, direction, pref, ensure_snap); + } + + } else { + if (_snap_mode != SnapOff) { + snap_to_internal (start, direction, pref); + } else if (ArdourKeyboard::indicates_snap_delta (event->button.state)) { + /* SnapOff, but we pressed the snap_delta modifier */ + snap_to_internal (start, direction, pref, ensure_snap); + } + } +} + +void +EditingContext::snap_to (timepos_t& start, Temporal::RoundMode direction, SnapPref pref, bool ensure_snap) +{ + if (!_session || (_snap_mode == SnapOff && !ensure_snap)) { + return; + } + + snap_to_internal (start, direction, pref, ensure_snap); +} + +timepos_t +EditingContext::snap_to_bbt (timepos_t const & presnap, Temporal::RoundMode direction, SnapPref gpref) +{ + return _snap_to_bbt (presnap, direction, gpref, _grid_type); +} + +timepos_t +EditingContext::_snap_to_bbt (timepos_t const & presnap, Temporal::RoundMode direction, SnapPref gpref, GridType grid_type) +{ + timepos_t ret(presnap); + TempoMap::SharedPtr tmap (TempoMap::use()); + + /* Snap to bar always uses bars, and ignores visual grid, so it may + * sometimes snap to bars that are not visually distinguishable. + * + * XXX this should probably work totally different: we should get the + * nearby grid and walk towards the next bar point. + */ + + if (grid_type == GridTypeBar) { + TempoMetric m (tmap->metric_at (presnap)); + BBT_Argument bbt (m.bbt_at (presnap)); + switch (direction) { + case RoundDownAlways: + bbt = BBT_Argument (bbt.reference(), bbt.round_down_to_bar ()); + break; + case RoundUpAlways: + bbt = BBT_Argument (bbt.reference(), bbt.round_up_to_bar ()); + break; + case RoundNearest: + bbt = BBT_Argument (bbt.reference(), m.round_to_bar (bbt)); + break; + default: + break; + } + return timepos_t (tmap->quarters_at (bbt)); + } + + if (gpref != SnapToGrid_Unscaled) { // use the visual grid lines which are limited by the zoom scale that the user selected + + /* Determine the most obvious divisor of a beat to use + * for the snap, based on the grid setting. + */ + + int divisor; + switch (_grid_type) { + case GridTypeBeatDiv3: + case GridTypeBeatDiv6: + case GridTypeBeatDiv12: + case GridTypeBeatDiv24: + divisor = 3; + break; + case GridTypeBeatDiv5: + case GridTypeBeatDiv10: + case GridTypeBeatDiv20: + divisor = 5; + break; + case GridTypeBeatDiv7: + case GridTypeBeatDiv14: + case GridTypeBeatDiv28: + divisor = 7; + break; + case GridTypeBeat: + divisor = 1; + break; + case GridTypeNone: + return ret; + default: + divisor = 2; + break; + }; + + /* bbt_ruler_scale reflects the level of detail we will show + * for the visual grid. Adjust the "natural" divisor to reflect + * this level of detail, and snap to that. + * + * So, for example, if the grid is Div3, we use 3 divisions per + * beat, but if the visual grid is using bbt_show_sixteenths (a + * fairly high level of detail), we will snap to (2 * 3) + * divisions per beat. Etc. + */ + + BBTRulerScale scale = bbt_ruler_scale; + switch (scale) { + case bbt_show_many: + case bbt_show_64: + case bbt_show_16: + case bbt_show_4: + case bbt_show_1: + /* Round to Bar */ + ret = timepos_t (tmap->quarters_at (presnap).round_to_subdivision (-1, direction)); + break; + case bbt_show_quarters: + /* Round to Beat */ + ret = timepos_t (tmap->quarters_at (presnap).round_to_subdivision (1, direction)); + break; + case bbt_show_eighths: + ret = timepos_t (tmap->quarters_at (presnap).round_to_subdivision (1 * divisor, direction)); + break; + case bbt_show_sixteenths: + ret = timepos_t (tmap->quarters_at (presnap).round_to_subdivision (2 * divisor, direction)); + break; + case bbt_show_thirtyseconds: + ret = timepos_t (tmap->quarters_at (presnap).round_to_subdivision (4 * divisor, direction)); + break; + case bbt_show_sixtyfourths: + ret = timepos_t (tmap->quarters_at (presnap).round_to_subdivision (8 * divisor, direction)); + break; + case bbt_show_onetwentyeighths: + ret = timepos_t (tmap->quarters_at (presnap).round_to_subdivision (16 * divisor, direction)); + break; + } + } else { + /* Just use the grid as specified, without paying attention to + * zoom level + */ + + ret = timepos_t (tmap->quarters_at (presnap).round_to_subdivision (get_grid_beat_divisions(_grid_type), direction)); + } + + return ret; +} + +static void +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 ()); + if (diff < dist) { + dist = diff; + best = test; + } + + test = timepos_t::max (test.time_domain()); // reset this so it doesn't get accidentally reused +} + +void +EditingContext::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::iterator prev = region_boundary_cache.begin (); + vector::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; +} + diff --git a/gtk2_ardour/editing_context.h b/gtk2_ardour/editing_context.h index 4871a1d4e2..22fb49bbae 100644 --- a/gtk2_ardour/editing_context.h +++ b/gtk2_ardour/editing_context.h @@ -142,14 +142,44 @@ public: virtual void set_selected_midi_region_view (MidiRegionView&); - virtual samplepos_t pixel_to_sample_from_event (double pixel) const = 0; - virtual samplepos_t pixel_to_sample (double pixel) const = 0; - virtual double sample_to_pixel (samplepos_t sample) const = 0; - virtual double sample_to_pixel_unrounded (samplepos_t sample) const = 0; - virtual double time_to_pixel (Temporal::timepos_t const & pos) const = 0; - virtual double time_to_pixel_unrounded (Temporal::timepos_t const & pos) const = 0; - virtual double duration_to_pixels (Temporal::timecnt_t const & pos) const = 0; - virtual double duration_to_pixels_unrounded (Temporal::timecnt_t const & pos) const = 0; + + /* NOTE: these functions assume that the "pixel" coordinate is + in canvas coordinates. These coordinates already take into + account any scrolling offsets. + */ + + samplepos_t pixel_to_sample_from_event (double pixel) const { + + /* pixel can be less than zero when motion events + are processed. since we've already run the world->canvas + affine, that means that the location *really* is "off + to the right" and thus really is "before the start". + */ + + if (pixel >= 0) { + return pixel * samples_per_pixel; + } else { + return 0; + } + } + + samplepos_t pixel_to_sample (double pixel) const { + return pixel * samples_per_pixel; + } + + double sample_to_pixel (samplepos_t sample) const { + return round (sample / (double) samples_per_pixel); + } + + double sample_to_pixel_unrounded (samplepos_t sample) const { + return sample / (double) samples_per_pixel; + } + + double time_to_pixel (Temporal::timepos_t const & pos) const; + double time_to_pixel_unrounded (Temporal::timepos_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; + /** computes the timeline sample (sample) of an event whose coordinates * are in canvas units (pixels, scroll offset included). */ @@ -190,17 +220,17 @@ public: virtual void snap_to (Temporal::timepos_t & first, Temporal::RoundMode direction = Temporal::RoundNearest, ARDOUR::SnapPref pref = ARDOUR::SnapToAny_Visual, - bool ensure_snap = false) = 0; + bool ensure_snap = false); 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; + bool ensure_snap = false); virtual Temporal::timepos_t snap_to_bbt (Temporal::timepos_t const & start, Temporal::RoundMode direction, - ARDOUR::SnapPref gpref) = 0; + ARDOUR::SnapPref gpref); virtual double get_y_origin () const = 0; virtual void reset_x_origin (samplepos_t) = 0; @@ -342,7 +372,21 @@ public: MouseCursors* _cursors; VerboseCursor* _verbose_cursor; + + samplecnt_t samples_per_pixel; + Editing::ZoomFocus zoom_focus; + + Temporal::timepos_t _snap_to_bbt (Temporal::timepos_t const & start, + Temporal::RoundMode direction, + ARDOUR::SnapPref gpref, + Editing::GridType grid_type); + + void snap_to_internal (Temporal::timepos_t& first, + Temporal::RoundMode direction = Temporal::RoundNearest, + ARDOUR::SnapPref gpref = ARDOUR::SnapToAny_Visual, + bool ensure_snap = false); }; + #endif /* __ardour_midi_editing_context_h__ */ diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index 4229cc868e..3155fc2634 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -234,8 +234,6 @@ Editor::Editor () , constructed (false) , _properties_box (0) , no_save_visual (false) - , samples_per_pixel (2048) - , zoom_focus (ZoomFocusPlayhead) , mouse_mode (MouseObject) , marker_click_behavior (MarkerClickSelectOnly) , _join_object_range_state (JOIN_OBJECT_RANGE_NONE) @@ -2545,55 +2543,6 @@ Editor::set_snapped_cursor_position (timepos_t const & 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. - * @param event Event to get current key modifier information from, or 0. - */ -void -Editor::snap_to_with_modifier (timepos_t& start, GdkEvent const * event, Temporal::RoundMode direction, SnapPref pref, bool ensure_snap) -{ - if (!_session || !event) { - return; - } - - if (ArdourKeyboard::indicates_snap (event->button.state)) { - if (_snap_mode == SnapOff) { - snap_to_internal (start, direction, pref, ensure_snap); - } - - } else { - if (_snap_mode != SnapOff) { - snap_to_internal (start, direction, pref); - } else if (ArdourKeyboard::indicates_snap_delta (event->button.state)) { - /* SnapOff, but we pressed the snap_delta modifier */ - snap_to_internal (start, direction, pref, ensure_snap); - } - } -} - -void -Editor::snap_to (timepos_t& start, Temporal::RoundMode direction, SnapPref pref, bool ensure_snap) -{ - if (!_session || (_snap_mode == SnapOff && !ensure_snap)) { - return; - } - - snap_to_internal (start, direction, pref, ensure_snap); -} - -static void -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 ()); - if (diff < dist) { - dist = diff; - best = test; - } - - test = timepos_t::max (test.time_domain()); // reset this so it doesn't get accidentally reused -} - timepos_t Editor::snap_to_timecode (timepos_t const & presnap, Temporal::RoundMode direction, SnapPref gpref) { @@ -2744,117 +2693,6 @@ Editor::snap_to_cd_frames (timepos_t const & presnap, Temporal::RoundMode direct return timepos_t (presnap_sample); } -timepos_t -Editor::snap_to_bbt (timepos_t const & presnap, Temporal::RoundMode direction, SnapPref gpref) -{ - return _snap_to_bbt (presnap, direction, gpref, _grid_type); -} - -timepos_t -Editor::_snap_to_bbt (timepos_t const & presnap, Temporal::RoundMode direction, SnapPref gpref, GridType grid_type) -{ - timepos_t ret(presnap); - TempoMap::SharedPtr tmap (TempoMap::use()); - - /* Snap to bar always uses bars, and ignores visual grid, so it may - * sometimes snap to bars that are not visually distinguishable. - * - * XXX this should probably work totally different: we should get the - * nearby grid and walk towards the next bar point. - */ - - if (grid_type == GridTypeBar) { - return timepos_t (tmap->quarters_at (presnap).round_to_subdivision (get_grid_beat_divisions(_grid_type), direction)); - } - - if (gpref != SnapToGrid_Unscaled) { // use the visual grid lines which are limited by the zoom scale that the user selected - - /* Determine the most obvious divisor of a beat to use - * for the snap, based on the grid setting. - */ - - float divisor; - switch (_grid_type) { - case GridTypeBeatDiv3: - case GridTypeBeatDiv6: - case GridTypeBeatDiv12: - case GridTypeBeatDiv24: - divisor = 3; - break; - case GridTypeBeatDiv5: - case GridTypeBeatDiv10: - case GridTypeBeatDiv20: - divisor = 2.5; - break; - case GridTypeBeatDiv7: - case GridTypeBeatDiv14: - case GridTypeBeatDiv28: - /* Septuplets suffer from drifting until libtemporal handles fractional ticks - * or if ticks_per_beat (ppqn) is raised to a point where the result - */ - divisor = 3.5; - break; - case GridTypeBeat: - divisor = 1; - break; - case GridTypeNone: - return ret; - default: - divisor = 2; - break; - }; - - /* bbt_ruler_scale reflects the level of detail we will show - * for the visual grid. Adjust the "natural" divisor to reflect - * this level of detail, and snap to that. - * - * So, for example, if the grid is Div3, we use 3 divisions per - * beat, but if the visual grid is using bbt_show_sixteenths (a - * fairly high level of detail), we will snap to (2 * 3) - * divisions per beat. Etc. - */ - - BBTRulerScale scale = bbt_ruler_scale; - switch (scale) { - case bbt_show_many: - case bbt_show_64: - case bbt_show_16: - case bbt_show_4: - case bbt_show_1: - /* Round to Bar */ - ret = timepos_t (tmap->quarters_at (presnap).round_to_subdivision (-1, direction)); - break; - case bbt_show_quarters: - /* Round to Beat */ - ret = timepos_t (tmap->quarters_at (presnap).round_to_subdivision (1, direction)); - break; - case bbt_show_eighths: - ret = timepos_t (tmap->quarters_at (presnap).round_to_subdivision (1 * divisor, direction)); - break; - case bbt_show_sixteenths: - ret = timepos_t (tmap->quarters_at (presnap).round_to_subdivision (2 * divisor, direction)); - break; - case bbt_show_thirtyseconds: - ret = timepos_t (tmap->quarters_at (presnap).round_to_subdivision (4 * divisor, direction)); - break; - case bbt_show_sixtyfourths: - ret = timepos_t (tmap->quarters_at (presnap).round_to_subdivision (8 * divisor, direction)); - break; - case bbt_show_onetwentyeighths: - ret = timepos_t (tmap->quarters_at (presnap).round_to_subdivision (16 * divisor, direction)); - break; - } - } else { - /* Just use the grid as specified, without paying attention to - * zoom level - */ - - ret = timepos_t (tmap->quarters_at (presnap).round_to_subdivision (get_grid_beat_divisions(_grid_type), direction)); - } - - return ret; -} - timepos_t Editor::snap_to_grid (timepos_t const & presnap, Temporal::RoundMode direction, SnapPref gpref) { @@ -2916,90 +2754,6 @@ Editor::snap_to_marker (timepos_t const & presnap, Temporal::RoundMode direction return test; } -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 ()) { - - set::iterator prev = region_boundary_cache.begin (); - set::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; -} - void Editor::setup_toolbar () @@ -6657,30 +6411,6 @@ Editor::use_own_window (bool and_fill_it) return win; } -double -Editor::time_to_pixel (timepos_t const & pos) const -{ - return sample_to_pixel (pos.samples()); -} - -double -Editor::time_to_pixel_unrounded (timepos_t const & pos) const -{ - return sample_to_pixel_unrounded (pos.samples()); -} - -double -Editor::duration_to_pixels (timecnt_t const & dur) const -{ - return sample_to_pixel (dur.samples()); -} - -double -Editor::duration_to_pixels_unrounded (timecnt_t const & dur) const -{ - return sample_to_pixel_unrounded (dur.samples()); -} - void Editor::start_track_drag (TimeAxisView& tav, int y, Gtk::Widget& w, bool can_change_cursor) { diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index 059d4de433..f30ff42259 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -219,44 +219,6 @@ public: void separate_regions_using_location (ARDOUR::Location&); void transition_to_rolling (bool forward); - /* NOTE: these functions assume that the "pixel" coordinate is - in canvas coordinates. These coordinates already take into - account any scrolling offsets. - */ - - samplepos_t pixel_to_sample_from_event (double pixel) const { - - /* pixel can be less than zero when motion events - are processed. since we've already run the world->canvas - affine, that means that the location *really* is "off - to the right" and thus really is "before the start". - */ - - if (pixel >= 0) { - return pixel * samples_per_pixel; - } else { - return 0; - } - } - - samplepos_t pixel_to_sample (double pixel) const { - return pixel * samples_per_pixel; - } - - double sample_to_pixel (samplepos_t sample) const { - return round (sample / (double) samples_per_pixel); - } - - double sample_to_pixel_unrounded (samplepos_t sample) const { - return sample / (double) samples_per_pixel; - } - - double time_to_pixel (Temporal::timepos_t const & pos) const; - double time_to_pixel_unrounded (Temporal::timepos_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; - /* selection */ Selection& get_selection() const { return *selection; } @@ -471,21 +433,6 @@ public: TrackViewList axis_views_from_routes (std::shared_ptr) const; - void snap_to (Temporal::timepos_t & first, - Temporal::RoundMode direction = Temporal::RoundNearest, - ARDOUR::SnapPref pref = ARDOUR::SnapToAny_Visual, - bool ensure_snap = false); - - 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); - - Temporal::timepos_t snap_to_bbt (Temporal::timepos_t const & start, - Temporal::RoundMode direction, - ARDOUR::SnapPref gpref); - void set_snapped_cursor_position (Temporal::timepos_t const & pos); void begin_selection_op_history (); @@ -621,9 +568,6 @@ private: void start_visual_state_op (uint32_t n); void cancel_visual_state_op (uint32_t n); - samplecnt_t samples_per_pixel; - Editing::ZoomFocus zoom_focus; - void set_samples_per_pixel (samplecnt_t); void on_samples_per_pixel_changed (); @@ -2333,16 +2277,6 @@ private: Temporal::RoundMode direction, ARDOUR::SnapPref gpref); - Temporal::timepos_t _snap_to_bbt (Temporal::timepos_t const & start, - Temporal::RoundMode direction, - ARDOUR::SnapPref gpref, - Editing::GridType grid_type); - - void snap_to_internal (Temporal::timepos_t& first, - Temporal::RoundMode direction = Temporal::RoundNearest, - ARDOUR::SnapPref gpref = ARDOUR::SnapToAny_Visual, - bool ensure_snap = false); - void timecode_snap_to_internal (Temporal::timepos_t & first, Temporal::RoundMode direction = Temporal::RoundNearest, bool for_mark = false); diff --git a/gtk2_ardour/midi_clip_editor.cc b/gtk2_ardour/midi_clip_editor.cc index e2301a2962..2d4de7c6e0 100644 --- a/gtk2_ardour/midi_clip_editor.cc +++ b/gtk2_ardour/midi_clip_editor.cc @@ -38,6 +38,7 @@ #include "automation_line.h" #include "control_point.h" #include "editor.h" +#include "midi_cue_editor.h" #include "region_view.h" #include "ui_config.h" @@ -51,43 +52,6 @@ using namespace ArdourCanvas; using std::max; using std::min; -MidiClipEditor::MidiClipEditor () -{ - set_background_color (UIConfiguration::instance ().color (X_("neutral:backgroundest"))); - - const double scale = UIConfiguration::instance ().get_ui_scale (); - const double width = 600. * scale; - const double height = 210. * scale; - - frame = new ArdourCanvas::Rectangle (this); - - ArdourCanvas::Rect r (0, 0, width, height); - frame->set (r); - frame->set_outline_all (); - - frame->Event.connect (sigc::mem_fun (*this, &MidiClipEditor::event_handler)); -} - -MidiClipEditor::~MidiClipEditor () -{ -} - -bool -MidiClipEditor::event_handler (GdkEvent* ev) -{ - switch (ev->type) { - case GDK_BUTTON_PRESS: - break; - case GDK_ENTER_NOTIFY: - break; - case GDK_LEAVE_NOTIFY: - break; - default: - break; - } - - return false; -} MidiClipEditorBox::MidiClipEditorBox () { @@ -95,11 +59,11 @@ MidiClipEditorBox::MidiClipEditorBox () _header_label.set_alignment (0.0, 0.5); pack_start (_header_label, false, false, 6); - editor = manage (new MidiClipEditor ()); - editor->set_size_request (600, 120); + editor = manage (new MidiCueEditor ()); + editor->viewport().set_size_request (600, 120); - pack_start (*editor, true, true); - editor->show (); + pack_start (editor->viewport(), true, true); + editor->viewport().show (); } MidiClipEditorBox::~MidiClipEditorBox () diff --git a/gtk2_ardour/midi_clip_editor.h b/gtk2_ardour/midi_clip_editor.h index 406dd4f6bf..65ac4d94ee 100644 --- a/gtk2_ardour/midi_clip_editor.h +++ b/gtk2_ardour/midi_clip_editor.h @@ -50,16 +50,7 @@ namespace ArdourCanvas class Polygon; } -class MidiClipEditor : public ArdourCanvas::GtkCanvas -{ -public: - MidiClipEditor (); - ~MidiClipEditor (); - -private: - ArdourCanvas::Rectangle* frame; - bool event_handler (GdkEvent* ev); -}; +class MidiCueEditor; class MidiClipEditorBox : public ClipEditorBox { @@ -76,7 +67,7 @@ private: Gtk::Label _header_label; Gtk::Table table; - MidiClipEditor* editor; + MidiCueEditor* editor; PBD::ScopedConnection state_connection;