summaryrefslogtreecommitdiff
path: root/gtk2_ardour
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2009-09-08 21:45:44 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2009-09-08 21:45:44 +0000
commit1bf79fa88502a156a71cd3d2de35aa234950c40c (patch)
treed17b2e9ed485511ac557647c4b331054c1d477c0 /gtk2_ardour
parent539c8361de35364effe804e2db184790226b340a (diff)
move note drag & note resize mouse handling up into the Drag/Editor infrastructure/level
git-svn-id: svn://localhost/ardour2/branches/3.0@5641 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'gtk2_ardour')
-rw-r--r--gtk2_ardour/canvas-note-event.cc111
-rw-r--r--gtk2_ardour/canvas-note-event.h1
-rw-r--r--gtk2_ardour/canvas-note.cc82
-rw-r--r--gtk2_ardour/canvas-note.h25
-rw-r--r--gtk2_ardour/editor.h1
-rw-r--r--gtk2_ardour/editor_canvas_events.cc10
-rw-r--r--gtk2_ardour/editor_drag.cc150
-rw-r--r--gtk2_ardour/editor_drag.h33
-rw-r--r--gtk2_ardour/editor_items.h3
-rw-r--r--gtk2_ardour/editor_mouse.cc16
-rw-r--r--gtk2_ardour/midi_region_view.cc95
-rw-r--r--gtk2_ardour/midi_region_view.h13
-rw-r--r--gtk2_ardour/public_editor.h1
13 files changed, 283 insertions, 258 deletions
diff --git a/gtk2_ardour/canvas-note-event.cc b/gtk2_ardour/canvas-note-event.cc
index b796ef47fb..9404c15c2d 100644
--- a/gtk2_ardour/canvas-note-event.cc
+++ b/gtk2_ardour/canvas-note-event.cc
@@ -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;
diff --git a/gtk2_ardour/canvas-note-event.h b/gtk2_ardour/canvas-note-event.h
index 305988667d..ec306d29b8 100644
--- a/gtk2_ardour/canvas-note-event.h
+++ b/gtk2_ardour/canvas-note-event.h
@@ -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) {
diff --git a/gtk2_ardour/canvas-note.cc b/gtk2_ardour/canvas-note.cc
index f51a58ff5f..b43514edcc 100644
--- a/gtk2_ardour/canvas-note.cc
+++ b/gtk2_ardour/canvas-note.cc
@@ -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;
}
}
diff --git a/gtk2_ardour/canvas-note.h b/gtk2_ardour/canvas-note.h
index 46f4bbee35..cd3c166951 100644
--- a/gtk2_ardour/canvas-note.h
+++ b/gtk2_ardour/canvas-note.h
@@ -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
diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h
index 5313c59c6d..9f791e5901 100644
--- a/gtk2_ardour/editor.h
+++ b/gtk2_ardour/editor.h
@@ -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*);
diff --git a/gtk2_ardour/editor_canvas_events.cc b/gtk2_ardour/editor_canvas_events.cc
index a95278f70d..2ea0a476fb 100644
--- a/gtk2_ardour/editor_canvas_events.cc
+++ b/gtk2_ardour/editor_canvas_events.cc
@@ -984,6 +984,16 @@ Editor::canvas_zoom_rect_event (GdkEvent *event, ArdourCanvas::Item* item)
}
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*/)
{
double wx;
diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc
index be261a5de0..fb39a34589 100644
--- a/gtk2_ardour/editor_drag.cc
+++ b/gtk2_ardour/editor_drag.cc
@@ -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);
+ }
+}
diff --git a/gtk2_ardour/editor_drag.h b/gtk2_ardour/editor_drag.h
index 68b2624d11..64989c96fe 100644
--- a/gtk2_ardour/editor_drag.h
+++ b/gtk2_ardour/editor_drag.h
@@ -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
{
diff --git a/gtk2_ardour/editor_items.h b/gtk2_ardour/editor_items.h
index 042fd20852..15e56a3313 100644
--- a/gtk2_ardour/editor_items.h
+++ b/gtk2_ardour/editor_items.h
@@ -46,7 +46,8 @@ enum ItemType {
FadeInHandleItem,
FadeOutItem,
FadeOutHandleItem,
-
+ NoteItem,
+
#ifdef WITH_CMT
MarkerViewItem,
MarkerTimeAxisItem,
diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc
index 164f09dfcf..78947ea808 100644
--- a/gtk2_ardour/editor_mouse.cc
+++ b/gtk2_ardour/editor_mouse.cc
@@ -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;
}
diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc
index 138b53b316..b4acdc7f5e 100644
--- a/gtk2_ardour/midi_region_view.cc
+++ b/gtk2_ardour/midi_region_view.cc
@@ -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
diff --git a/gtk2_ardour/midi_region_view.h b/gtk2_ardour/midi_region_view.h
index 5a7955e140..08dea544e2 100644
--- a/gtk2_ardour/midi_region_view.h
+++ b/gtk2_ardour/midi_region_view.h
@@ -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.
diff --git a/gtk2_ardour/public_editor.h b/gtk2_ardour/public_editor.h
index abf92a8a40..880ebc6c15 100644
--- a/gtk2_ardour/public_editor.h
+++ b/gtk2_ardour/public_editor.h
@@ -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;