13
0

fix geometry calculations during NoteCreateDrags.

This also only uses the draw length parameter if no motion
occured during the NoteCreateDrag. Otherwise it uses the length that was
dragged (which is subjected to a threshold).
This commit is contained in:
Paul Davis 2024-06-11 15:14:03 -06:00
parent dd211c4329
commit 30a7f44c12
5 changed files with 25 additions and 8 deletions

View File

@ -6852,11 +6852,11 @@ NoteCreateDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor)
const timepos_t pos = _drags->current_pointer_time ();
Temporal::Beats aligned_beats (round_to_grid (pos, event));
const Temporal::Beats grid_beats (_midi_view->get_draw_length_beats (pos));
const Temporal::Beats min_length (0, Temporal::Beats::PPQN/ 128);
_note[0] = timepos_t (aligned_beats);
/* minimum initial length is grid beats */
_note[1] = _note[0] + timepos_t (grid_beats);
_note[1] = _note[0] + timepos_t (min_length);
/* the note positions we've just computed are in absolute beats, but
* the drag rect is a member of the region view group, so we need
@ -6882,7 +6882,7 @@ NoteCreateDrag::motion (GdkEvent* event, bool)
const timepos_t pos = _drags->current_pointer_time ();
/* when the user clicks and starts a drag to define the note's length, require notes to be at least |this| long */
const Temporal::Beats min_length (_midi_view->get_draw_length_beats (pos));
const Temporal::Beats min_length (0, Temporal::Beats::PPQN / 128);
Temporal::Beats aligned_beats = round_to_grid (pos, event);
_note[1] = std::max (aligned_beats, (_note[0].beats () + min_length));
@ -6899,12 +6899,18 @@ NoteCreateDrag::motion (GdkEvent* event, bool)
void
NoteCreateDrag::finished (GdkEvent* ev, bool had_movement)
{
/* we create a note even if there was no movement */
Beats length;
/* Compute start within region, rather than absolute time start */
Beats const start = _midi_view->midi_region ()->absolute_time_to_region_beats (min (_note[0], _note[1]));
Beats length = max (Beats (0, 1), (_note[0].distance (_note[1]).abs ().beats ()));
if (!had_movement) {
/* we create a note even if there was no movement */
length = _midi_view->get_draw_length_beats (_note[0]);
} else {
length = _note[0].distance (_note[1]).abs ().beats ();
}
/* create_note_at() implements UNDO for us */
if (UIConfiguration::instance().get_select_last_drawn_note_only()) {

View File

@ -53,6 +53,8 @@ MidiCueView::MidiCueView (std::shared_ptr<ARDOUR::MidiTrack> mt,
event_rect->set_outline (false);
_note_group->raise_to_top ();
set_extensible (true);
}
void

View File

@ -41,6 +41,10 @@ class MidiCueView : public MidiView
void set_height (double);
ArdourCanvas::Item* drag_group() const;
bool note_in_region_range (const std::shared_ptr<NoteType> note, bool& visible) const {
visible = true;
return true;
}
protected:
bool scroll (GdkEventScroll* ev);

View File

@ -135,6 +135,7 @@ MidiView::MidiView (std::shared_ptr<MidiTrack> mt,
, _mouse_changed_selection (false)
, split_tuple (0)
, note_splitting (false)
, _extensible (false)
{
init ();
}
@ -1095,7 +1096,7 @@ MidiView::model_changed()
std::shared_ptr<NoteType> note (*n);
bool visible;
if (note_in_region_range (note, visible)) {
if (_extensible || note_in_region_range (note, visible)) {
if (!empty_when_starting && (cne = find_canvas_note (note)) != 0) {
cne->validate ();
if (visible) {
@ -1648,7 +1649,7 @@ MidiView::update_sustained (Note* ev, bool update_ghost_regions)
const Temporal::Beats source_end ((_midi_region->start() + _midi_region->length()).beats());
if (note->end_time() > source_end) {
if (!_extensible && note->end_time() > source_end) {
note_end = timepos_t (source_end);
}

View File

@ -229,7 +229,7 @@ class MidiView : public virtual sigc::trackable
* @param visible will be set to true if the note is within the visible note range, false otherwise.
* @return true iff the note is within the (time) extent of the region.
*/
bool note_in_region_range(const std::shared_ptr<NoteType> note, bool& visible) const;
virtual bool note_in_region_range(const std::shared_ptr<NoteType> note, bool& visible) const;
/* Test if a note is withing this region's time range. Return true if so */
bool note_in_region_time_range(const std::shared_ptr<NoteType> note) const;
@ -625,6 +625,10 @@ class MidiView : public virtual sigc::trackable
uint32_t split_tuple;
bool note_splitting;
bool _extensible; /* if true, we can add data beyond the current region/source end */
bool extensible() const { return _extensible; }
void set_extensible (bool yn) { _extensible = yn; }
void start_note_splitting ();
void end_note_splitting ();