break;
}
- if(_mouse_changed_selection) {
+ if (_mouse_changed_selection) {
trackview.editor().begin_reversible_selection_op (_("Mouse Selection Change"));
trackview.editor().commit_reversible_selection_op ();
}
delete_selection();
return true;
- } else if (ev->keyval == GDK_Tab) {
+ } else if (ev->keyval == GDK_Tab || ev->keyval == GDK_ISO_Left_Tab) {
trackview.editor().begin_reversible_selection_op (_("Select Adjacent Note"));
return true;
- } else if (ev->keyval == GDK_ISO_Left_Tab) {
-
- /* Shift-TAB generates ISO Left Tab, for some reason */
-
- trackview.editor().begin_reversible_selection_op (_("Select Adjacent Note"));
-
- if (Keyboard::modifier_state_contains (ev->state, Keyboard::PrimaryModifier)) {
- goto_previous_note (Keyboard::modifier_state_contains (ev->state, Keyboard::TertiaryModifier));
- } else {
- goto_next_note (Keyboard::modifier_state_contains (ev->state, Keyboard::TertiaryModifier));
- }
-
- trackview.editor().commit_reversible_selection_op();
-
- return true;
-
-
-
} else if (ev->keyval == GDK_Up) {
bool allow_smush = Keyboard::modifier_state_contains (ev->state, Keyboard::TertiaryModifier);
view->update_note_range(new_note->note());
- trackview.editor().begin_reversible_command(_("add note"));
- MidiModel::NoteDiffCommand* cmd = _model->new_note_diff_command(_("add note"));
- cmd->add (new_note);
- _model->apply_command(*trackview.session(), cmd);
- trackview.editor().commit_reversible_command();
+ start_note_diff_command(_("add note"));
+
+ clear_selection ();
+ note_diff_add_note (new_note, true, false);
+
+ apply_diff();
play_midi_note (new_note);
}
content_connection.disconnect ();
_model->ContentsChanged.connect (content_connection, invalidator (*this), boost::bind (&MidiRegionView::redisplay_model, this), gui_context());
- /* Don't signal as nobody else needs to know until selection has been altered.*/
+ /* Don't signal as nobody else needs to know until selection has been altered. */
clear_events (false);
if (_enable_display) {
return 0;
}
-/** This version finds any canvas note matching the supplied note.*/
+/** This version finds any canvas note matching the supplied note. */
NoteBase*
MidiRegionView::find_canvas_note (NoteType note)
{
- if (_optimization_iterator != _events.end()) {
- ++_optimization_iterator;
- }
-
- if (_optimization_iterator != _events.end() && (*(*_optimization_iterator)->note()) == note) {
- return *_optimization_iterator;
- }
+ Events::iterator it;
- for (_optimization_iterator = _events.begin(); _optimization_iterator != _events.end(); ++_optimization_iterator) {
- if (*((*_optimization_iterator)->note()) == note) {
- return *_optimization_iterator;
+ for (it = _events.begin(); it != _events.end(); ++it) {
+ if (*((*it)->note()) == note) {
+ return *it;
}
}
bool
MidiRegionView::note_in_region_range (const boost::shared_ptr<NoteType> note, bool& visible) const
{
+ /* This is imprecise due to all the conversion conversion involved, so only
+ hide notes if they seem to start more than one tick before the start. */
+ const framecnt_t tick_frames = Evoral::Beats::tick().to_ticks(trackview.session()->frame_rate());
const framepos_t note_start_frames = source_beats_to_region_frames (note->time());
- bool outside = (note_start_frames < 0) || (note_start_frames > _region->last_frame());
+ const bool outside = ((note_start_frames <= -tick_frames) ||
+ (note_start_frames > _region->last_frame()));
visible = (note->note() >= midi_stream_view()->lowest_note()) &&
(note->note() <= midi_stream_view()->highest_note());
view->update_note_range(new_note->note());
_marked_for_selection.clear ();
- clear_selection ();
start_note_diff_command (_("step add"));
+
+ clear_selection ();
note_diff_add_note (new_note, true, false);
+
apply_diff();
// last_step_edit_note = new_note;
void
MidiRegionView::commit_resizing (NoteBase* primary, bool at_front, double delta_x, bool relative)
{
- start_note_diff_command (_("resize notes"));
+ _note_diff_command = _model->new_note_diff_command (_("resize notes"));
for (std::vector<NoteResizeData *>::iterator i = _resize_data.begin(); i != _resize_data.end(); ++i) {
Note* canvas_note = (*i)->note;
}
_resize_data.clear();
- apply_diff();
+ apply_diff(true);
}
void
bool
MidiRegionView::paste (framepos_t pos, const ::Selection& selection, PasteContext& ctx)
{
+ bool commit = false;
// Paste notes, if available
MidiNoteSelection::const_iterator m = selection.midi_notes.get_nth(ctx.counts.n_notes());
if (m != selection.midi_notes.end()) {
ctx.counts.increase_n_notes();
+ if (!(*m)->empty()) { commit = true; }
paste_internal(pos, ctx.count, ctx.times, **m);
}
typedef RouteTimeAxisView::AutomationTracks ATracks;
const ATracks& atracks = midi_view()->automation_tracks();
for (ATracks::const_iterator a = atracks.begin(); a != atracks.end(); ++a) {
- a->second->paste(pos, selection, ctx);
+ if (a->second->paste(pos, selection, ctx)) {
+ commit = true;
+ }
}
+ if (commit) {
+ trackview.editor().commit_reversible_command ();
+ }
return true;
}