diff --git a/gtk2_ardour/editing_context.h b/gtk2_ardour/editing_context.h index 647c2bb78f..b1b4484f3b 100644 --- a/gtk2_ardour/editing_context.h +++ b/gtk2_ardour/editing_context.h @@ -183,10 +183,12 @@ public: 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". + /* pixel can be less than zero when motion events are + processed. Since the pixel value is in canvas units (since + it comes from an event delivered to the canvas), we've + already run the window->canvas transform, that means that + the location *really* is "off to the right" and thus really + is "before the start". */ if (pixel >= 0) { @@ -320,6 +322,7 @@ public: /* MIDI actions, proxied to selected MidiRegionView(s) */ ARDOUR::Quantize* get_quantize_op (); void apply_midi_note_edit_op (ARDOUR::MidiOperator& op, const RegionSelection& rs); + PBD::Command* apply_midi_note_edit_op_to_region (ARDOUR::MidiOperator& op, MidiView& mrv); void midi_action (void (MidiView::*method)()); std::vector filter_to_unique_midi_region_views (RegionSelection const & ms) const; @@ -516,8 +519,6 @@ public: void edit_notes (MidiView*); void note_edit_done (int, EditNoteDialog*); - PBD::Command* apply_midi_note_edit_op_to_region (ARDOUR::MidiOperator& op, MidiView& mrv); - void quantize_regions (const RegionSelection& rs); void legatize_regions (const RegionSelection& rs, bool shrink_only); void transform_regions (const RegionSelection& rs); diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index 0a056d1562..bfa2c28cb3 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -353,6 +353,12 @@ Drag::start_grab (GdkEvent* event, Gdk::Cursor* cursor) const samplepos_t pos = editing_context.canvas_event_sample (event, &_grab_x, &_grab_y); + if (_bounding_item) { + ArdourCanvas::Duple d (_bounding_item->canvas_origin()); + _grab_x -= d.x; + _grab_y -= d.y; + } + if (_time_domain == Temporal::AudioTime) { _raw_grab_time = timepos_t (pos); } else { @@ -460,7 +466,12 @@ Drag::snap_delta (guint state) const double Drag::current_pointer_x () const { - return _drags->current_pointer_x (); + if (!_bounding_item) { + return _drags->current_pointer_x (); + } + + std::cerr << "mouse @ " << _drags->current_pointer_x () << " corrected by " << _bounding_item->canvas_origin().x << " to " << _drags->current_pointer_x () - _bounding_item->canvas_origin().x << std::endl; + return _drags->current_pointer_x () - _bounding_item->canvas_origin().x; } double @@ -6202,6 +6213,8 @@ NoteDrag::total_dx (GdkEvent* event) const /* dx in as samples, because we can't do any better */ timecnt_t const dx = timecnt_t (pixel_to_time (_drags->current_pointer_x () - grab_x ()), timepos_t ()); + std::cerr << "apparent dx " << dx.beats().str() << " from " << _drags->current_pointer_x() << " - " << grab_x() << std::endl; + /* primary note time in quarter notes */ timepos_t const n_qn = _region->midi_region()->source_beats_to_absolute_time (_primary->note ()->time ()); @@ -6272,12 +6285,12 @@ NoteDrag::motion (GdkEvent* event, bool first_move) _cumulative_dx = dx_qn; _cumulative_dy += tdy; - int8_t note_delta = total_dy (); + int8_t pitch_delta = total_dy (); if (_copy) { - _region->move_copies (dx_qn, tdy, note_delta); + _region->move_copies (dx_qn, tdy, pitch_delta); } else { - _region->move_selection (dx_qn, tdy, note_delta); + _region->move_selection (dx_qn, tdy, pitch_delta); } /* the new note value may be the same as the old one, but we @@ -6286,7 +6299,7 @@ NoteDrag::motion (GdkEvent* event, bool first_move) * odd with them. so show the note value anyway, always. */ - uint8_t new_note = min (max (_primary->note ()->note () + note_delta, 0), 127); + uint8_t new_note = min (max (_primary->note ()->note () + pitch_delta, 0), 127); _region->show_verbose_cursor_for_new_note_value (_primary->note (), new_note); @@ -6337,6 +6350,7 @@ NoteDrag::finished (GdkEvent* ev, bool moved) } } } else { + std::cerr << "ready to drop\n"; _region->note_dropped (_primary, total_dx (ev), total_dy (), _copy); } } diff --git a/gtk2_ardour/midi_cue_editor.cc b/gtk2_ardour/midi_cue_editor.cc index 5c10fe8f21..9a065e807a 100644 --- a/gtk2_ardour/midi_cue_editor.cc +++ b/gtk2_ardour/midi_cue_editor.cc @@ -486,7 +486,9 @@ MidiCueEditor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event if (note->big_enough_to_trim() && note->mouse_near_ends()) { _drags->set (new NoteResizeDrag (*this, item), event, get_canvas_cursor()); } else { - _drags->set (new NoteDrag (*this, item), event); + NoteDrag* nd = new NoteDrag (*this, item); + nd->set_bounding_item (data_group); + _drags->set (nd, event); } } return true; @@ -1056,7 +1058,7 @@ MidiCueEditor::maybe_autoscroll (bool allow_horiz, bool allow_vert, bool from_he * then we will continuously auto-scroll the canvas in the appropriate * direction(s) * - * the boundary is defined in coordinates relative to canvas' own + * the boundary is defined in coordinates relative to canvas' own * window since that is what we're going to call ::get_pointer() on * during autoscrolling to determine if we're still outside the * boundary or not. @@ -1067,13 +1069,16 @@ MidiCueEditor::maybe_autoscroll (bool allow_horiz, bool allow_vert, bool from_he alloc = get_canvas()->get_allocation (); + alloc.set_x (0); + alloc.set_y (0); + if (allow_vert) { /* reduce height by the height of the timebars, which happens - to correspond to the position of the hv_scroll_group. + to correspond to the position of the data_group. */ - alloc.set_height (alloc.get_height() - hv_scroll_group->position().y); - alloc.set_y (alloc.get_y() + hv_scroll_group->position().y); + alloc.set_height (alloc.get_height() - data_group->position().y); + alloc.set_y (alloc.get_y() + data_group->position().y); /* now reduce it again so that we start autoscrolling before we * move off the top or bottom of the canvas @@ -1083,20 +1088,29 @@ MidiCueEditor::maybe_autoscroll (bool allow_horiz, bool allow_vert, bool from_he alloc.set_y (alloc.get_y() + 10); } - /* the effective width of the autoscroll boundary so - that we start scrolling before we hit the edge. - - this helps when the window is slammed up against the - right edge of the screen, making it hard to scroll - effectively. - */ - if (allow_horiz && (alloc.get_width() > 20)) { + + if (prh) { + double w, h; + prh->size_request (w, h); + + alloc.set_width (alloc.get_width() - w); + alloc.set_x (alloc.get_x() + w); + } + + /* the effective width of the autoscroll boundary so + that we start scrolling before we hit the edge. + + this helps when the window is slammed up against the + right edge of the screen, making it hard to scroll + effectively. + */ + alloc.set_width (alloc.get_width() - 20); alloc.set_x (alloc.get_x() + 10); } - scrolling_boundary = ArdourCanvas::Rect (0., 0., alloc.get_width(), alloc.get_height()); + scrolling_boundary = ArdourCanvas::Rect (alloc.get_x(), alloc.get_y(), alloc.get_x() + alloc.get_width(), alloc.get_y() + alloc.get_height()); int x, y; Gdk::ModifierType mask; diff --git a/gtk2_ardour/midi_view.cc b/gtk2_ardour/midi_view.cc index ecdb9ddfd6..0b70ab03d1 100644 --- a/gtk2_ardour/midi_view.cc +++ b/gtk2_ardour/midi_view.cc @@ -2604,7 +2604,7 @@ MidiView::move_copies (timecnt_t const & dx_qn, double dy, double cumulative_dy) } void -MidiView::note_dropped(NoteBase *, timecnt_t const & d_qn, int8_t dnote, bool copy) +MidiView::note_dropped (NoteBase *, timecnt_t const & d_qn, int8_t dnote, bool copy) { uint8_t lowest_note_in_selection = 127; uint8_t highest_note_in_selection = 0; @@ -4434,23 +4434,25 @@ MidiView::get_draw_length_beats (timepos_t const & pos) const void MidiView::quantize_selected_notes () { -#warning paul fix this MRV/MV -#if 0 std::cerr << "QSN!\n"; - RegionSelection rs; - rs.push_back (this); - Quantize* quant = _editing_context.get_quantize_op (); if (!quant) { return; } - _editing_context.apply_midi_note_edit_op (*quant, rs); + PBD::Command* cmd = _editing_context.apply_midi_note_edit_op_to_region (*quant, *this); + + if (cmd) { + _editing_context.begin_reversible_command (quant->name ()); + (*cmd)(); + _editing_context.session()->add_command (cmd); + _editing_context.commit_reversible_command (); + _editing_context.session()->set_dirty (); + } delete quant; -#endif } void