move note drag & note resize mouse handling up into the Drag/Editor infrastructure...
authorPaul Davis <paul@linuxaudiosystems.com>
Tue, 8 Sep 2009 21:45:44 +0000 (21:45 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Tue, 8 Sep 2009 21:45:44 +0000 (21:45 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@5641 d708f5d6-7413-0410-9779-e7cbd77b26cf

13 files changed:
gtk2_ardour/canvas-note-event.cc
gtk2_ardour/canvas-note-event.h
gtk2_ardour/canvas-note.cc
gtk2_ardour/canvas-note.h
gtk2_ardour/editor.h
gtk2_ardour/editor_canvas_events.cc
gtk2_ardour/editor_drag.cc
gtk2_ardour/editor_drag.h
gtk2_ardour/editor_items.h
gtk2_ardour/editor_mouse.cc
gtk2_ardour/midi_region_view.cc
gtk2_ardour/midi_region_view.h
gtk2_ardour/public_editor.h

index b796ef47fba8ae7cbe7f8551754f7b22e76ad0ce..9404c15c2df3a8d5de7dc41b68873e274191bc7b 100644 (file)
@@ -218,18 +218,9 @@ CanvasNoteEvent::on_event(GdkEvent* ev)
                return false;
        }
 
-       MidiStreamView *streamview = _region.midi_stream_view();
-       static uint8_t drag_delta_note = 0;
-       static double  drag_delta_x = 0;
-       static double last_x, last_y;
-       double event_x, event_y, dx, dy;
-       bool select_mod;
-
        switch (ev->type) {
        case GDK_ENTER_NOTIFY:
                _region.note_entered(this);
-               //_item->grab_focus();
-               //show_velocity();
                //Keyboard::magic_widget_grab_focus();
                break;
 
@@ -239,118 +230,20 @@ CanvasNoteEvent::on_event(GdkEvent* ev)
                if (!selected()) {
                        hide_velocity();
                }
-               //_region.get_canvas_group()->grab_focus();
                break;
 
        case GDK_BUTTON_PRESS:
-               if (ev->button.button == 1) {
-                       _state = Pressed;
-               } else if (ev->button.button == 3) {
+               if (ev->button.button == 3) {
                        show_channel_selector();
-               }
-               return true;
-
-       case GDK_MOTION_NOTIFY:
-               event_x = ev->motion.x;
-               event_y = ev->motion.y;
-
-               switch (_state) {
-               case Pressed: // Drag begin
-                       if (editor.current_mouse_mode() == Editing::MouseObject && _region.mouse_state() != MidiRegionView::SelectTouchDragging) {
-                               _item->grab(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
-                                               Gdk::Cursor(Gdk::FLEUR), ev->motion.time);
-                               _state = Dragging;
-                               _item->property_parent().get_value()->w2i(event_x, event_y);
-                               event_x = _region.snap_to_pixel(event_x); 
-                               last_x = event_x;
-                               last_y = event_y;
-                               drag_delta_x = 0;
-                               drag_delta_note = 0;
-                               _region.note_selected(this, true);
-                       }
-                       return true;
-
-               case Dragging: // Drag motion
-                       if (ev->motion.is_hint) {
-                               int t_x;
-                               int t_y;
-                               GdkModifierType state;
-                               gdk_window_get_pointer(ev->motion.window, &t_x, &t_y, &state);
-                               event_x = t_x;
-                               event_y = t_y;
-                       }
-                       _item->property_parent().get_value()->w2i(event_x, event_y);
-                       
-                       event_x = _region.snap_to_pixel(event_x); 
-
-                       dx     = event_x - last_x;
-                       dy     = event_y - last_y;
-                       last_x = event_x;
-
-                       drag_delta_x += dx;
-
-                       // Snap to note rows
-                       if (abs(dy) < streamview->note_height()) {
-                               dy = 0.0;
-                       } else {
-                               int8_t this_delta_note;
-                               if (dy > 0) {
-                                       this_delta_note = (int8_t)ceil(dy / streamview->note_height() / 2.0);
-                               } else {
-                                       this_delta_note = (int8_t)floor(dy / streamview->note_height() / 2.0);
-                               }
-                               drag_delta_note -= this_delta_note;
-                               dy = streamview->note_height() * this_delta_note;
-                               last_y = last_y + dy;
-                       }
-
-                       _region.move_selection(dx, dy);
-
                        return true;
-               default:
-                       break;
                }
                break;
 
        case GDK_BUTTON_RELEASE:
-               select_mod = (ev->motion.state & (Keyboard::PrimaryModifier | Keyboard::SecondaryModifier));
-               event_x = ev->button.x;
-               event_y = ev->button.y;
-               _item->property_parent().get_value()->w2i(event_x, event_y);
-               
                if (ev->button.button == 3) {
                        return true;
                }
-               
-               switch (_state) {
-               case Pressed: // Clicked
-                       if (editor.current_mouse_mode() == Editing::MouseRange) {
-                               _state = None;
-                               if (_selected) {
-                                       _region.note_deselected(this, select_mod);
-                               } else {
-                                       bool extend = Keyboard::modifier_state_equals (ev->motion.state, Keyboard::TertiaryModifier);
-                                       bool add = Keyboard::modifier_state_equals (ev->motion.state, Keyboard::PrimaryModifier);
-
-                                       if (!extend && !add && _region.selection_size() > 1) {
-                                               _region.unique_select(this);
-                                       } else {
-                                               _region.note_selected (this, (extend ? true : add), extend);
-                                       }
-                               }
-                       }
-                       return true;
-
-               case Dragging: // Dropped
-                       _item->ungrab(ev->button.time);
-                       _state = None;
-                       if (_note) {
-                               _region.note_dropped(this, drag_delta_x, drag_delta_note);
-                       }
-                       return true;
-               default:
-                       break;
-               }
+               break;
 
        default:
                break;
index 305988667dc3e11514b4f353bcd7ab03514cf054..ec306d29b89adb973c3c1ee1abe855d4627f3a63 100644 (file)
@@ -94,6 +94,7 @@ public:
        virtual double y2() = 0;
 
        const boost::shared_ptr<NoteType> note() const { return _note; }
+       MidiRegionView& region_view() const { return _region; }
        
        inline static uint32_t meter_style_fill_color(uint8_t vel) {
                if (vel < 64) {
index f51a58ff5fffc292f044be5d8520b5f1bd538ed6..b43514edcc82d5383bba0a5303e614b00714a2bc 100644 (file)
@@ -11,84 +11,10 @@ namespace Canvas {
 bool
 CanvasNote::on_event(GdkEvent* ev)
 {
-       PublicEditor& editor (_region.get_trackview().editor());
-
-       if (!editor.internal_editing()) {
-               return false;
-       }
-
-       double          event_x;
-       static double   middle_point, last_x;
-       Gdk::Cursor     cursor;
-       static NoteEnd  note_end;
-
-       switch (ev->type) {
-       case GDK_BUTTON_PRESS:
-               if (ev->button.button == 2 ||
-                   (ev->button.button == 1 && editor.current_mouse_mode() == Editing::MouseTimeFX)) {
-                       double region_start = _region.get_position_pixels();
-                       event_x = ev->button.x;
-                       middle_point = region_start + x1() + (x2() - x1()) / 2.0L;
-
-                       if (event_x <= middle_point) {
-                               cursor = Gdk::Cursor(Gdk::LEFT_SIDE);
-                               note_end = NOTE_ON;
-                       } else {
-                               cursor = Gdk::Cursor(Gdk::RIGHT_SIDE);
-                               note_end = NOTE_OFF;
-                       }
-
-                       _item->grab(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK, cursor, ev->motion.time);
-
-                       if (_region.mouse_state() == MidiRegionView::SelectTouchDragging) {
-                               _note_state = AbsoluteResize;
-                       } else {
-                               _note_state = RelativeResize;
-                       }
-
-                       _region.note_selected(this, true);
-                       _region.begin_resizing(note_end);
-                       last_x = event_x;
-
-                       return true;
-               } 
-               
-       case GDK_MOTION_NOTIFY:
-               event_x = ev->motion.x;
-
-               if (_note_state == RelativeResize) {
-                       _region.update_resizing(note_end, event_x - last_x, true);
-                       last_x = event_x;
-                       return true;
-               }
-
-               if (_note_state == AbsoluteResize) {
-                       _region.update_resizing(note_end, event_x, false);
-                       return true;
-               }
-
-       case GDK_BUTTON_RELEASE:
-               event_x = ev->button.x;
-
-               switch (_note_state) {
-               case RelativeResize: // Clicked
-                       _item->ungrab(ev->button.time);
-                       _region.commit_resizing(note_end, event_x, true);
-                       _note_state = None;
-                       return true;
-
-               case AbsoluteResize: // Clicked
-                       _item->ungrab(ev->button.time);
-                       _region.commit_resizing(note_end, event_x, false);
-                       _note_state = None;
-                       return true;
-
-               default:
-                       return CanvasNoteEvent::on_event(ev);
-               }
-
-       default:
-               return CanvasNoteEvent::on_event(ev);
+       if (!_region.get_trackview().editor().canvas_note_event (ev, this)) {
+               return CanvasNoteEvent::on_event (ev);
+       } else {
+               return true;
        }
 }
 
index 46f4bbee35982de1c0728945810fcfcedd0eb685..cd3c1669515dcee1e59476f555b746678f61dbfe 100644 (file)
@@ -31,7 +31,7 @@ namespace Canvas {
 
 class CanvasNote : public SimpleRect, public CanvasNoteEvent {
 public:
-       typedef Evoral::Note<double> NoteType;
+       typedef Evoral::Note<Evoral::MusicalTime> NoteType;
 
        double x1() { return property_x1(); }
        double y1() { return property_y1(); }
@@ -46,27 +46,12 @@ public:
 
        bool on_event(GdkEvent* ev);
 
-       enum NoteEnd {
-               NOTE_ON,
-               NOTE_OFF
-       };
-
-       enum NoteState {
-               None,
-               RelativeResize,
-               AbsoluteResize
-       };
-
-       CanvasNote(
-                       MidiRegionView&                   region,
-                       Group&                            group,
-                       const boost::shared_ptr<NoteType> note = boost::shared_ptr<NoteType>())
-               : SimpleRect(group), CanvasNoteEvent(region, this, note), _note_state(None)
+       CanvasNote (MidiRegionView&                   region,
+                   Group&                            group,
+                   const boost::shared_ptr<NoteType> note = boost::shared_ptr<NoteType>())
+               : SimpleRect(group), CanvasNoteEvent(region, this, note)
        {
        }
-
-protected:
-       NoteState _note_state;
 };
 
 } // namespace Gnome
index 5313c59c6d70e2e538e05a8503fa80f7fc4cba01..9f791e59015e56ab4dc4f765e2c63cadf7f7fc71 100644 (file)
@@ -1370,6 +1370,7 @@ public:
        bool canvas_tempo_marker_event (GdkEvent* event,ArdourCanvas::Item*, TempoMarker*);
        bool canvas_meter_marker_event (GdkEvent* event,ArdourCanvas::Item*, MeterMarker*);
        bool canvas_automation_track_event(GdkEvent* event, ArdourCanvas::Item*, AutomationTimeAxisView*) ;
+       bool canvas_note_event (GdkEvent* event, ArdourCanvas::Item*);
 
        bool canvas_tempo_bar_event (GdkEvent* event, ArdourCanvas::Item*);
        bool canvas_meter_bar_event (GdkEvent* event, ArdourCanvas::Item*);
index a95278f70d741fa9c23065143a7bf5f77ee1e331..2ea0a476fbc9a7c02a58222917196c6cad3245a2 100644 (file)
@@ -983,6 +983,16 @@ Editor::canvas_zoom_rect_event (GdkEvent *event, ArdourCanvas::Item* item)
        return typed_event (item, event, NoItem);
 }
 
+bool
+Editor::canvas_note_event (GdkEvent *event, ArdourCanvas::Item* item)
+{
+       if (!internal_editing()) {
+               return false;
+       }
+
+       return typed_event (item, event, NoteItem);
+}
+
 bool
 Editor::track_canvas_drag_motion (Glib::RefPtr<Gdk::DragContext> const & /*c*/, int x, int y, guint /*time*/)
 {
index be261a5de02de6f4eddfed03d2143c5f10e4e712..fb39a34589cb6cc350b0cfa21081683df633d8b4 100644 (file)
@@ -35,6 +35,7 @@
 #include "editor_drag.h"
 #include "audio_time_axis.h"
 #include "midi_time_axis.h"
+#include "canvas-note.h"
 
 using namespace std;
 using namespace ARDOUR;
@@ -1379,6 +1380,58 @@ RegionCreateDrag::finished (GdkEvent* event, bool movement_occurred)
        }
 }
 
+NoteResizeDrag::NoteResizeDrag (Editor* e, ArdourCanvas::Item* i)
+       : Drag (e, i)
+       , region (0)
+{
+       
+}
+
+void
+NoteResizeDrag::start_grab (GdkEvent* event, Gdk::Cursor *)
+{
+       Gdk::Cursor     cursor;
+       ArdourCanvas::CanvasNote*     cnote = dynamic_cast<ArdourCanvas::CanvasNote*>(_item);
+       
+       Drag::start_grab (event);
+
+       region = &cnote->region_view();
+
+       double region_start = region->get_position_pixels();
+       double middle_point = region_start + cnote->x1() + (cnote->x2() - cnote->x1()) / 2.0L;
+       
+       if (_grab_x <= middle_point) {
+               cursor = Gdk::Cursor(Gdk::LEFT_SIDE);
+               at_front = true;
+       } else {
+               cursor = Gdk::Cursor(Gdk::RIGHT_SIDE);
+               at_front = false;
+       }
+       
+       _item->grab(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK, cursor, event->motion.time);
+       
+       if (event->motion.state & Keyboard::PrimaryModifier) {
+               relative = false;
+       } else {
+               relative = true;
+       }
+       
+       region->note_selected (cnote, true);
+       region->begin_resizing (at_front);
+}
+
+void
+NoteResizeDrag::motion (GdkEvent* /*event*/, bool first_move)
+{
+       region->update_resizing (at_front, _current_pointer_x - _grab_x, relative);
+} 
+
+void
+NoteResizeDrag::finished (GdkEvent* event, bool movement_occurred)
+{
+       region->commit_resizing (at_front, _current_pointer_x - _grab_x, relative);
+}
+
 void
 RegionGainDrag::motion (GdkEvent* /*event*/, bool)
 {
@@ -3287,3 +3340,100 @@ MouseZoomDrag::finished (GdkEvent* event, bool movement_occurred)
 
        _editor->zoom_rect->hide();
 }
+
+NoteDrag::NoteDrag (Editor* e, ArdourCanvas::Item* i)
+       : Drag (e, i)
+{
+       ArdourCanvas::CanvasNote*     cnote = dynamic_cast<ArdourCanvas::CanvasNote*>(_item);   
+       region = &cnote->region_view();
+}
+
+void
+NoteDrag::start_grab (GdkEvent* event, Gdk::Cursor *)
+{
+       Drag::start_grab (event);
+
+       drag_delta_x = 0;
+       drag_delta_note = 0;
+
+       double event_x;
+       double event_y;
+
+       event_x = _current_pointer_x;
+       event_y = _current_pointer_y;
+
+       _item->property_parent().get_value()->w2i(event_x, event_y);
+
+       last_x = region->snap_to_pixel(event_x); 
+       last_y = event_y;
+
+       ArdourCanvas::CanvasNote* cnote = dynamic_cast<ArdourCanvas::CanvasNote*>(_item);       
+       region->note_selected (cnote, true);
+}
+
+void
+NoteDrag::motion (GdkEvent* ev, bool)
+{
+       MidiStreamView* streamview = region->midi_stream_view();
+       double event_x;
+       double event_y;
+
+       event_x = _current_pointer_x;
+       event_y = _current_pointer_y;
+
+       _item->property_parent().get_value()->w2i(event_x, event_y);
+
+       event_x = region->snap_to_pixel(event_x); 
+
+       double dx     = event_x - last_x;
+       double dy     = event_y - last_y;
+       last_x = event_x;
+       
+       drag_delta_x += dx;
+
+       // Snap to note rows
+
+       if (abs (dy) < streamview->note_height()) {
+               dy = 0.0;
+       } else {
+               int8_t this_delta_note;
+               if (dy > 0) {
+                       this_delta_note = (int8_t)ceil(dy / streamview->note_height() / 2.0);
+               } else {
+                       this_delta_note = (int8_t)floor(dy / streamview->note_height() / 2.0);
+               }
+               drag_delta_note -= this_delta_note;
+               dy = streamview->note_height() * this_delta_note;
+               last_y = last_y + dy;
+       }
+       
+       region->move_selection (dx, dy);
+}
+       
+void
+NoteDrag::finished (GdkEvent* ev, bool moved)
+{
+       ArdourCanvas::CanvasNote* cnote = dynamic_cast<ArdourCanvas::CanvasNote*>(_item);
+
+       if (!moved) {
+               if (_editor->current_mouse_mode() == Editing::MouseObject) {
+                       
+                       bool select_mod = (ev->motion.state & (Keyboard::PrimaryModifier | Keyboard::SecondaryModifier));
+
+                       if (cnote->selected()) {
+                               region->note_deselected (cnote, select_mod);
+                       } else {
+                               bool extend = Keyboard::modifier_state_equals (ev->button.state, Keyboard::TertiaryModifier);
+                               bool add = Keyboard::modifier_state_equals (ev->button.state, Keyboard::PrimaryModifier);
+                               
+                               if (!extend && !add && region->selection_size() > 1) {
+                                       region->unique_select(cnote);
+                               } else {
+                                       region->note_selected (cnote, (extend ? true : add), extend);
+                               }
+                       }
+               }
+       } else {
+               region->note_dropped (cnote, drag_delta_x, drag_delta_note);
+       }
+}
index 68b2624d112bbc83bb1e24bc5057be8c267786fc..64989c96fef6373a4981eccbe81f35cedcdc9c4d 100644 (file)
@@ -263,6 +263,39 @@ private:
        TimeAxisView* _dest_trackview;
 };
 
+/** Drags to resize MIDI notes */
+class NoteResizeDrag : public Drag
+{
+public:
+       NoteResizeDrag (Editor *, ArdourCanvas::Item *);
+
+       void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
+       void motion (GdkEvent *, bool);
+       void finished (GdkEvent *, bool);
+
+private:
+       MidiRegionView*     region;
+       bool                relative;
+       bool                at_front;
+};
+
+class NoteDrag : public Drag
+{
+  public:      
+       NoteDrag (Editor*, ArdourCanvas::Item*);
+
+       void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
+       void motion (GdkEvent *, bool);
+       void finished (GdkEvent *, bool);
+
+  private:
+       MidiRegionView* region;
+       double last_x;
+       double last_y;
+       double drag_delta_x;
+       double drag_delta_note;
+};
+
 /** Drag of region gain */
 class RegionGainDrag : public Drag
 {
index 042fd20852fcd287c1659d79b5e6a299412e275a..15e56a331361893e3da4b2903d2de76914c96ffd 100644 (file)
@@ -46,7 +46,8 @@ enum ItemType {
        FadeInHandleItem,
        FadeOutItem,
        FadeOutHandleItem,
-       
+       NoteItem,
+
 #ifdef WITH_CMT
        MarkerViewItem,
        MarkerTimeAxisItem,
index 164f09dfcf347c1ef522a06682b4022ff82daa9f..78947ea8086e2dbfc87c953b93a9c8a8b4806cfb 100644 (file)
@@ -605,6 +605,22 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
                        _drag = new RegionCreateDrag (this, item, clicked_axisview);
                        _drag->start_grab (event);
                        return true;
+               case NoteItem:
+                       /* Note: we don't get here if not in internal_editing() mode */
+                       if (mouse_mode == MouseTimeFX) {
+                               assert (_drag == 0);
+                               _drag = new NoteResizeDrag (this, item);
+                               _drag->start_grab (event);
+                               return true;
+                       } else if (mouse_mode == MouseObject) {
+                               assert (_drag == 0);
+                               _drag = new NoteDrag (this, item);
+                               _drag->start_grab (event);
+                               return true;
+                       } else {
+                               return false;
+                       }
+                       break;
                default:
                        return true;
                }
index 138b53b316d0cd77dd84562260b8251bd791981e..b4acdc7f5ee21e50b1f00ba8083b5ff636a97a76 100644 (file)
@@ -353,6 +353,7 @@ MidiRegionView::canvas_event(GdkEvent* ev)
 
                        // Select drag start
                        if (_pressed_button == 1 && editor.current_mouse_mode() == MouseObject) {
+                               cerr << "MRV start select grab\n";
                                group->grab(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
                                                Gdk::Cursor(Gdk::FLEUR), ev->motion.time);
                                last_x = event_x;
@@ -376,6 +377,7 @@ MidiRegionView::canvas_event(GdkEvent* ev)
 
                        // Add note drag start
                        } else if (editor.current_mouse_mode() == MouseRange) {
+                               cerr << "MRV start note grab\n";
                                group->grab(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
                                                Gdk::Cursor(Gdk::FLEUR), ev->motion.time);
                                last_x = event_x;
@@ -1680,7 +1682,7 @@ MidiRegionView::frames_to_beats(nframes64_t frames) const
 }
 
 void
-MidiRegionView::begin_resizing(CanvasNote::NoteEnd note_end)
+MidiRegionView::begin_resizing(bool at_front)
 {
        _resize_data.clear();
 
@@ -1714,37 +1716,37 @@ MidiRegionView::begin_resizing(CanvasNote::NoteEnd note_end)
                                        ARDOUR_UI::config()->canvasvar_MidiNoteSelected.get());
 
                        resize_data->resize_rect = resize_rect;
-
-                       if (note_end == CanvasNote::NOTE_ON) {
-                               resize_data->current_x = note->x1();
-                       } else { // NOTE_OFF
-                               resize_data->current_x = note->x2();
-                       }
-
                        _resize_data.push_back(resize_data);
                }
        }
 }
 
 void
-MidiRegionView::update_resizing(CanvasNote::NoteEnd note_end, double x, bool relative)
+MidiRegionView::update_resizing (bool at_front, double delta_x, bool relative)
 {
        for (std::vector<NoteResizeData *>::iterator i = _resize_data.begin(); i != _resize_data.end(); ++i) {
                SimpleRect* resize_rect = (*i)->resize_rect;
                CanvasNote* canvas_note = (*i)->canvas_note;
-
                const double region_start = get_position_pixels();
+               double current_x;
 
-               if (relative) {
-                       (*i)->current_x = (*i)->current_x + x;
+               if (at_front) {
+                       if (relative) {
+                               current_x = canvas_note->x1() + delta_x;
+                       } else {
+                               // x is in track relative, transform it to region relative
+                               current_x = delta_x - region_start;
+                       }
                } else {
-                       // x is in track relative, transform it to region relative
-                       (*i)->current_x = x - region_start;
+                       if (relative) {
+                               current_x = canvas_note->x2() + delta_x;
+                       } else {
+                               // x is in track relative, transform it to region relative
+                               current_x = delta_x - region_start;
+                       }
                }
-
-               double current_x = (*i)->current_x;
-
-               if (note_end == CanvasNote::NOTE_ON) {
+               
+               if (at_front) {
                        resize_rect->property_x1() = snap_to_pixel(current_x);
                        resize_rect->property_x2() = canvas_note->x2();
                } else {
@@ -1755,40 +1757,47 @@ MidiRegionView::update_resizing(CanvasNote::NoteEnd note_end, double x, bool rel
 }
 
 void
-MidiRegionView::commit_resizing(CanvasNote::NoteEnd note_end, double event_x, bool relative)
+MidiRegionView::commit_resizing (bool at_front, double delta_x, bool relative)
 {
-       start_delta_command(_("resize notes"));
+       start_diff_command(_("resize notes"));
 
        for (std::vector<NoteResizeData *>::iterator i = _resize_data.begin(); i != _resize_data.end(); ++i) {
                CanvasNote*  canvas_note = (*i)->canvas_note;
                SimpleRect*  resize_rect = (*i)->resize_rect;
-               double       current_x   = (*i)->current_x;
-               const double position    = get_position_pixels();
+               const double region_start = get_position_pixels();
+               double current_x;
 
-               if (!relative) {
-                       // event_x is in track relative, transform it to region relative
-                       current_x = event_x - position;
+               if (at_front) {
+                       if (relative) {
+                               current_x = canvas_note->x1() + delta_x;
+                       } else {
+                               // x is in track relative, transform it to region relative
+                               current_x = delta_x - region_start;
+                       }
+               } else {
+                       if (relative) {
+                               current_x = canvas_note->x2() + delta_x;
+                       } else {
+                               // x is in track relative, transform it to region relative
+                               current_x = delta_x - region_start;
+                       }
                }
-
-               // because snapping works on world coordinates we have to transform current_x
-               // to world coordinates before snapping and transform it back afterwards
-               nframes64_t current_frame = snap_pixel_to_frame(current_x);
-               // transform to region start relative
-               current_frame += _region->start();
                
-               const boost::shared_ptr<NoteType> copy(new NoteType(*(canvas_note->note().get())));
+               current_x = snap_pixel_to_frame (current_x);
+               current_x = frames_to_beats (current_x);
 
-               // resize beginning of note
-               if (note_end == CanvasNote::NOTE_ON && current_frame < copy->end_time()) {
-                       delta_remove_note(canvas_note);
-                       copy->on_event().time() = current_frame;
-                       delta_add_note(copy, _selection.find(canvas_note) != _selection.end());
+               if (at_front && current_x < canvas_note->note()->end_time()) {
+
+                       diff_add_change (canvas_note, MidiModel::DiffCommand::StartTime, current_x);
                }
-               // resize end of note
-               if (note_end == CanvasNote::NOTE_OFF && current_frame > copy->time()) {
-                       delta_remove_note(canvas_note);
-                       copy->off_event().time() = current_frame;
-                       delta_add_note(copy, _selection.find(canvas_note) != _selection.end());
+
+               if (!at_front) {
+                       double len = current_x - canvas_note->note()->time();
+
+                       if (len > 0) {
+                               /* XXX convert to beats */
+                               diff_add_change (canvas_note, MidiModel::DiffCommand::Length, len);
+                       }
                }
 
                delete resize_rect;
@@ -1796,7 +1805,7 @@ MidiRegionView::commit_resizing(CanvasNote::NoteEnd note_end, double event_x, bo
        }
 
        _resize_data.clear();
-       apply_delta();
+       apply_diff();
 }
 
 void
index 5a7955e1405d34afca3980603ae11accbdde47df..08dea544e213d9abdd937720855f43a8c4070276 100644 (file)
@@ -201,24 +201,24 @@ class MidiRegionView : public RegionView
 
        /** Begin resizing of some notes.
         * Called by CanvasMidiNote when resizing starts.
-        * @param note_end which end of the note, NOTE_ON or NOTE_OFF
+        * @param at_front which end of the note (true == note on, false == note off)
         */
-       void begin_resizing(ArdourCanvas::CanvasNote::NoteEnd note_end);
+       void begin_resizing(bool at_front);
 
        /** Update resizing notes while user drags.
-        * @param note_end which end of the note, NOTE_ON or NOTE_OFF
+        * @param at_front which end of the note (true == note on, false == note off)
         * @param x the difference in mouse motion, ie the motion difference if relative=true
         *           or the absolute mouse position (track-relative) if relative is false
         * @param relative true if relative resizing is taking place, false if absolute resizing
         */
-       void update_resizing(ArdourCanvas::CanvasNote::NoteEnd note_end, double x, bool relative);
+       void update_resizing(bool at_front, double x, bool relative);
 
        /** Finish resizing notes when the user releases the mouse button.
-        * @param note_end which end of the note, NOTE_ON or NOTE_OFF
+        * @param at_front which end of the note (true == note on, false == note off)
         * @param event_x the absolute mouse position (track-relative)
         * @param relative true if relative resizing is taking place, false if absolute resizing
         */
-       void commit_resizing(ArdourCanvas::CanvasNote::NoteEnd note_end, double event_x, bool relative);
+       void commit_resizing(bool at_front, double event_x, bool relative);
 
        /** Adjust the velocity on a note, and the selection if applicable.
         * @param velocity the relative or absolute velocity
@@ -244,7 +244,6 @@ class MidiRegionView : public RegionView
        struct NoteResizeData {
                ArdourCanvas::CanvasNote  *canvas_note;
                ArdourCanvas::SimpleRect  *resize_rect;
-               double                     current_x;
        };
        
        /** Snap a region relative pixel coordinate to pixel units.
index abf92a8a400f473b344df7b7e1ac2c48fda60901..880ebc6c159c075b7d97e9ef58ed4378606df84a 100644 (file)
@@ -312,6 +312,7 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulThingWithGoingAway
        virtual bool canvas_marker_bar_event (GdkEvent* event, ArdourCanvas::Item*) = 0;
        virtual bool canvas_range_marker_bar_event (GdkEvent* event, ArdourCanvas::Item*) = 0;
        virtual bool canvas_transport_marker_bar_event (GdkEvent* event, ArdourCanvas::Item*) = 0;
+       virtual bool canvas_note_event (GdkEvent* event, ArdourCanvas::Item*) = 0;
 
 #ifdef WITH_CMT
        virtual bool canvas_imageframe_item_view_event(GdkEvent* event, ArdourCanvas::Item*,ImageFrameView*) = 0;