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:
parent
dd211c4329
commit
30a7f44c12
@ -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()) {
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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 ();
|
||||
|
Loading…
Reference in New Issue
Block a user