summaryrefslogtreecommitdiff
path: root/gtk2_ardour/midi_region_view.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gtk2_ardour/midi_region_view.cc')
-rw-r--r--gtk2_ardour/midi_region_view.cc144
1 files changed, 88 insertions, 56 deletions
diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc
index 95b1ffad93..317e1f33fe 100644
--- a/gtk2_ardour/midi_region_view.cc
+++ b/gtk2_ardour/midi_region_view.cc
@@ -209,7 +209,7 @@ MidiRegionView::canvas_event(GdkEvent* ev)
static double last_x, last_y;
double event_x, event_y;
nframes64_t event_frame = 0;
- uint8_t d_velocity = 10;
+ bool fine;
static ArdourCanvas::SimpleRect* drag_rect = NULL;
@@ -219,15 +219,13 @@ MidiRegionView::canvas_event(GdkEvent* ev)
switch (ev->type) {
case GDK_SCROLL:
- if (Keyboard::modifier_state_equals (ev->scroll.state, Keyboard::Level4Modifier)) {
- d_velocity = 1;
- }
-
+ fine = Keyboard::modifier_state_equals (ev->scroll.state, Keyboard::Level4Modifier);
+
if (ev->scroll.direction == GDK_SCROLL_UP) {
- change_velocities (d_velocity, true);
+ change_velocities (true, fine, false);
return true;
} else if (ev->scroll.direction == GDK_SCROLL_DOWN) {
- change_velocities(-d_velocity, true);
+ change_velocities (false, fine, false);
return true;
} else {
return false;
@@ -254,7 +252,7 @@ MidiRegionView::canvas_event(GdkEvent* ev)
bool start = (ev->key.keyval == GDK_comma);
bool end = (ev->key.keyval == GDK_period);
bool shorter = Keyboard::modifier_state_contains (ev->key.state, Keyboard::PrimaryModifier);
- bool fine = Keyboard::modifier_state_contains (ev->key.state, Keyboard::SecondaryModifier);
+ fine = Keyboard::modifier_state_contains (ev->key.state, Keyboard::SecondaryModifier);
change_note_lengths (fine, shorter, start, end);
@@ -277,19 +275,25 @@ MidiRegionView::canvas_event(GdkEvent* ev)
} else if (ev->key.keyval == GDK_Up) {
- if (Keyboard::modifier_state_equals (ev->key.state, Keyboard::PrimaryModifier)) {
- change_velocities (1, true);
+ bool allow_smush = Keyboard::modifier_state_contains (ev->key.state, Keyboard::SecondaryModifier);
+ bool fine = Keyboard::modifier_state_contains (ev->key.state, Keyboard::TertiaryModifier);
+
+ if (Keyboard::modifier_state_contains (ev->key.state, Keyboard::PrimaryModifier)) {
+ change_velocities (true, fine, allow_smush);
} else {
- transpose (true, Keyboard::modifier_state_equals (ev->key.state, Keyboard::SecondaryModifier));
+ transpose (true, fine, allow_smush);
}
return true;
} else if (ev->key.keyval == GDK_Down) {
- if (Keyboard::modifier_state_equals (ev->key.state, Keyboard::PrimaryModifier)) {
- change_velocities (-1, true);
+ bool allow_smush = Keyboard::modifier_state_contains (ev->key.state, Keyboard::SecondaryModifier);
+ fine = Keyboard::modifier_state_contains (ev->key.state, Keyboard::TertiaryModifier);
+
+ if (Keyboard::modifier_state_contains (ev->key.state, Keyboard::PrimaryModifier)) {
+ change_velocities (false, fine, allow_smush);
} else {
- transpose (false, Keyboard::modifier_state_equals (ev->key.state, Keyboard::SecondaryModifier));
+ transpose (false, fine, allow_smush);
}
return true;
@@ -349,7 +353,7 @@ MidiRegionView::canvas_event(GdkEvent* ev)
case Pressed: // Drag start
// Select drag start
- if (_pressed_button == 1 && editor.current_mouse_mode() == MouseRange) {
+ if (_pressed_button == 1 && editor.current_mouse_mode() == MouseObject) {
group->grab(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
Gdk::Cursor(Gdk::FLEUR), ev->motion.time);
last_x = event_x;
@@ -372,7 +376,7 @@ MidiRegionView::canvas_event(GdkEvent* ev)
return true;
// Add note drag start
- } else if (editor.current_mouse_mode() == MouseObject) {
+ } else if (editor.current_mouse_mode() == MouseRange) {
group->grab(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
Gdk::Cursor(Gdk::FLEUR), ev->motion.time);
last_x = event_x;
@@ -455,11 +459,11 @@ MidiRegionView::canvas_event(GdkEvent* ev)
switch (_mouse_state) {
case Pressed: // Clicked
switch (editor.current_mouse_mode()) {
- case MouseRange:
+ case MouseObject:
case MouseTimeFX:
clear_selection();
break;
- case MouseObject:
+ case MouseRange:
create_note_at(event_x, event_y, _default_note_length);
break;
default:
@@ -486,7 +490,7 @@ MidiRegionView::canvas_event(GdkEvent* ev)
drag_rect = NULL;
default: break;
}
-
+
default: break;
}
@@ -532,6 +536,8 @@ MidiRegionView::create_note_at(double x, double y, double length)
MidiModel::DeltaCommand* cmd = _model->new_delta_command("add note");
cmd->add(new_note);
_model->apply_command(trackview.session(), cmd);
+
+ play_midi_note (new_note);
}
void
@@ -562,7 +568,7 @@ MidiRegionView::display_model(boost::shared_ptr<MidiModel> model)
_model = model;
content_connection.disconnect ();
content_connection = _model->ContentsChanged.connect(sigc::mem_fun(this, &MidiRegionView::redisplay_model));
-
+
if (_enable_display) {
redisplay_model();
}
@@ -657,17 +663,26 @@ MidiRegionView::redisplay_model()
}
if (_model) {
+
+ // Mark all selected notes for selection when model reloads
+ for (Selection::iterator i = _selection.begin(); i != _selection.end(); ++i) {
+ _marked_for_selection.insert((*i)->note());
+ }
+
+
clear_events();
_model->read_lock();
MidiModel::Notes notes = _model->notes();
for (size_t i = 0; i < _model->n_notes(); ++i) {
- add_note(_model->note_at(i));
+ boost::shared_ptr<NoteType> note (_model->note_at (i));
+ if (note_in_visible_range (note)) {
+ add_note (note);
+ }
}
display_sysexes();
-
display_program_changes();
_model->read_unlock();
@@ -1025,7 +1040,7 @@ MidiRegionView::add_note(const boost::shared_ptr<NoteType> note)
{
assert(note->time() >= 0);
assert(midi_view()->note_mode() == Sustained || midi_view()->note_mode() == Percussive);
-
+
const nframes64_t note_start_frames = beats_to_frames(note->time());
const nframes64_t note_end_frames = beats_to_frames(note->end_time());
@@ -1092,21 +1107,19 @@ MidiRegionView::add_note(const boost::shared_ptr<NoteType> note)
if (event) {
if (_marked_for_selection.find(note) != _marked_for_selection.end()) {
- cerr << "Added note " << *note << " was marked for selection\n";
note_selected(event, true);
- } else {
- cerr << "Added note " << *note << " not selected\n";
- }
+ }
if (_marked_for_velocity.find(note) != _marked_for_velocity.end()) {
event->show_velocity();
}
event->on_channel_selection_change(_last_channel_selection);
_events.push_back(event);
+
if (note_in_visible_range(note)) {
event->show();
} else {
- event->hide();
+ event->hide ();
}
}
}
@@ -1839,18 +1852,38 @@ MidiRegionView::change_note_time (CanvasNoteEvent* event, Evoral::MusicalTime de
}
void
-MidiRegionView::change_velocities (int8_t velocity, bool relative)
+MidiRegionView::change_velocities (bool up, bool fine, bool allow_smush)
{
+ int8_t delta;
+
if (_selection.empty()) {
return;
}
+ if (fine) {
+ delta = 1;
+ } else {
+ delta = 10;
+ }
+
+ if (!up) {
+ delta = -delta;
+ }
+
+ if (!allow_smush) {
+ for (Selection::iterator i = _selection.begin(); i != _selection.end(); ++i) {
+ if ((*i)->note()->velocity() + delta == 0 || (*i)->note()->velocity() + delta == 127) {
+ return;
+ }
+ }
+ }
+
start_delta_command(_("change velocities"));
for (Selection::iterator i = _selection.begin(); i != _selection.end();) {
Selection::iterator next = i;
++next;
- change_note_velocity (*i, velocity, relative);
+ change_note_velocity (*i, delta, true);
i = next;
}
@@ -1859,7 +1892,7 @@ MidiRegionView::change_velocities (int8_t velocity, bool relative)
void
-MidiRegionView::transpose (bool up, bool fine)
+MidiRegionView::transpose (bool up, bool fine, bool allow_smush)
{
if (_selection.empty()) {
return;
@@ -1877,6 +1910,20 @@ MidiRegionView::transpose (bool up, bool fine)
delta = -delta;
}
+ if (!allow_smush) {
+ for (Selection::iterator i = _selection.begin(); i != _selection.end(); ++i) {
+ if (!up) {
+ if ((int8_t) (*i)->note()->note() + delta <= 0) {
+ return;
+ }
+ } else {
+ if ((int8_t) (*i)->note()->note() + delta > 127) {
+ return;
+ }
+ }
+ }
+ }
+
start_delta_command (_("transpose"));
for (Selection::iterator i = _selection.begin(); i != _selection.end(); ) {
@@ -2017,8 +2064,18 @@ MidiRegionView::note_entered(ArdourCanvas::CanvasNoteEvent* ev)
if (_mouse_state == SelectTouchDragging) {
note_selected(ev, true);
}
+
+ PublicEditor& editor (trackview.editor());
+ editor.show_verbose_canvas_cursor_with (Evoral::midi_note_name (ev->note()->note()));
}
+void
+MidiRegionView::note_left (ArdourCanvas::CanvasNoteEvent* ev)
+{
+ PublicEditor& editor (trackview.editor());
+ editor.hide_verbose_canvas_cursor ();
+}
+
void
MidiRegionView::switch_source(boost::shared_ptr<Source> src)
@@ -2231,31 +2288,6 @@ MidiRegionView::goto_previous_note ()
unique_select (*(_events.rbegin()));
}
-MidiModel::DeltaCommand*
-MidiRegionView::apply (Filter& filter, const std::string& name)
-{
- MidiModel::Notes before = _model->notes();
- MidiModel::Notes after;
-
- _region->apply (filter);
-
- redisplay_model ();
-
- after = _model->notes();
-
- start_delta_command (name);
-
- for (MidiModel::Notes::iterator i = before.begin(); i != before.end(); ++i) {
- _delta_command->add (*i);
- }
-
- for (MidiModel::Notes::iterator i = after.begin(); i != after.end(); ++i) {
- _delta_command->remove (*i);
- }
-
- return _delta_command;
-}
-
void
MidiRegionView::selection_as_notelist (NoteList& selected)
{