X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Fmidi_region_view.cc;h=26490f76e73ef0e79f26188f2db1bc03f9853ee4;hb=792e3de1d4cb291a02c5c31dad54028049bafed9;hp=a8f6f11b42a653505cf6b920a2fa0331c40bc022;hpb=8687895abba4209a6de8d8a8fc1bda5996f0d875;p=ardour.git diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc index a8f6f11b42..26490f76e7 100644 --- a/gtk2_ardour/midi_region_view.cc +++ b/gtk2_ardour/midi_region_view.cc @@ -29,12 +29,12 @@ #include #include "pbd/memento_command.h" +#include "pbd/stateful_diff_command.h" #include "ardour/playlist.h" #include "ardour/tempo.h" #include "ardour/midi_region.h" #include "ardour/midi_source.h" -#include "ardour/midi_diskstream.h" #include "ardour/midi_model.h" #include "ardour/midi_patch_manager.h" #include "ardour/session.h" @@ -89,6 +89,8 @@ MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView & , _pressed_button(0) , _sort_needed (true) , _optimization_iterator (_events.end()) + , _list_editor (0) + , no_sound_notes (false) { _note_group->raise_to_top(); } @@ -110,6 +112,8 @@ MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView & , _pressed_button(0) , _sort_needed (true) , _optimization_iterator (_events.end()) + , _list_editor (0) + , no_sound_notes (false) { _note_group->raise_to_top(); @@ -132,6 +136,8 @@ MidiRegionView::MidiRegionView (const MidiRegionView& other) , _pressed_button(0) , _sort_needed (true) , _optimization_iterator (_events.end()) + , _list_editor (0) + , no_sound_notes (false) { Gdk::Color c; int r,g,b,a; @@ -157,6 +163,8 @@ MidiRegionView::MidiRegionView (const MidiRegionView& other, boost::shared_ptrshow (); + if (!_list_editor) { + _list_editor = new MidiListEditor (trackview.session(), midi_region()); + } + _list_editor->present (); } /** Add a note to the model, and the view, at a canvas (click) coordinate. @@ -552,7 +562,7 @@ 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); + _model->apply_command(*trackview.session(), cmd); play_midi_note (new_note); } @@ -585,8 +595,8 @@ MidiRegionView::display_model(boost::shared_ptr model) { _model = model; content_connection.disconnect (); - content_connection = _model->ContentsChanged.connect( - sigc::mem_fun(this, &MidiRegionView::redisplay_model)); + _model->ContentsChanged.connect (content_connection, invalidator (*this), boost::bind (&MidiRegionView::redisplay_model, this), gui_context()); + clear_events (); if (_enable_display) { @@ -665,9 +675,9 @@ MidiRegionView::apply_delta() _marked_for_selection.insert((*i)->note()); } - _model->apply_command(trackview.session(), _delta_command); + _model->apply_command(*trackview.session(), _delta_command); _delta_command = 0; - midi_view()->midi_track()->diskstream()->playlist_modified(); + midi_view()->midi_track()->playlist_modified(); _marked_for_selection.clear(); _marked_for_velocity.clear(); @@ -680,9 +690,9 @@ MidiRegionView::apply_diff () return; } - _model->apply_command(trackview.session(), _diff_command); + _model->apply_command(*trackview.session(), _diff_command); _diff_command = 0; - midi_view()->midi_track()->diskstream()->playlist_modified(); + midi_view()->midi_track()->playlist_modified(); _marked_for_velocity.clear(); } @@ -699,9 +709,9 @@ MidiRegionView::apply_delta_as_subcommand() _marked_for_selection.insert((*i)->note()); } - _model->apply_command_as_subcommand(trackview.session(), _delta_command); + _model->apply_command_as_subcommand(*trackview.session(), _delta_command); _delta_command = 0; - midi_view()->midi_track()->diskstream()->playlist_modified(); + midi_view()->midi_track()->playlist_modified(); _marked_for_selection.clear(); _marked_for_velocity.clear(); @@ -719,9 +729,9 @@ MidiRegionView::apply_diff_as_subcommand() _marked_for_selection.insert((*i)->note()); } - _model->apply_command_as_subcommand(trackview.session(), _diff_command); + _model->apply_command_as_subcommand(*trackview.session(), _diff_command); _diff_command = 0; - midi_view()->midi_track()->diskstream()->playlist_modified(); + midi_view()->midi_track()->playlist_modified(); _marked_for_selection.clear(); _marked_for_velocity.clear(); @@ -938,6 +948,8 @@ MidiRegionView::~MidiRegionView () { in_destructor = true; + delete _list_editor; + RegionViewGoingAway (this); /* EMIT_SIGNAL */ if (_active_notes) { @@ -951,11 +963,11 @@ MidiRegionView::~MidiRegionView () } void -MidiRegionView::region_resized (Change what_changed) +MidiRegionView::region_resized (const PropertyChange& what_changed) { RegionView::region_resized(what_changed); - if (what_changed & ARDOUR::PositionChanged) { + if (what_changed.contains (ARDOUR::Properties::position)) { set_duration(_region->length(), 0); if (_enable_display) { redisplay_model(); @@ -1071,7 +1083,7 @@ MidiRegionView::add_ghost (TimeAxisView& tv) } } - ghost->GoingAway.connect (sigc::mem_fun(*this, &MidiRegionView::remove_ghost)); + GhostRegion::CatchDeletion.connect (*this, invalidator (*this), ui_bind (&RegionView::remove_ghost, this, _1), gui_context()); return ghost; } @@ -1139,7 +1151,7 @@ MidiRegionView::extend_active_notes() void MidiRegionView::play_midi_note(boost::shared_ptr note) { - if (!trackview.editor().sound_notes()) { + if (no_sound_notes || !trackview.editor().sound_notes()) { return; } @@ -1151,7 +1163,7 @@ MidiRegionView::play_midi_note(boost::shared_ptr note) const double note_length_beats = (note->off_event().time() - note->on_event().time()); nframes_t note_length_ms = beats_to_frames(note_length_beats) - * (1000 / (double)route_ui->session().nominal_frame_rate()); + * (1000 / (double)route_ui->session()->nominal_frame_rate()); Glib::signal_timeout().connect(sigc::bind(sigc::mem_fun(this, &MidiRegionView::play_midi_note_off), note), note_length_ms, G_PRIORITY_DEFAULT); } @@ -1522,6 +1534,91 @@ MidiRegionView::unique_select(ArdourCanvas::CanvasNoteEvent* ev) } } +void +MidiRegionView::select_matching_notes (uint8_t notenum, uint16_t channel_mask, bool add, bool extend) +{ + uint8_t low_note = 127; + uint8_t high_note = 0; + MidiModel::Notes& notes (_model->notes()); + _optimization_iterator = _events.begin(); + + if (extend && _selection.empty()) { + extend = false; + } + + if (extend) { + + /* scan existing selection to get note range */ + + for (Selection::iterator i = _selection.begin(); i != _selection.end(); ++i) { + if ((*i)->note()->note() < low_note) { + low_note = (*i)->note()->note(); + } + if ((*i)->note()->note() > high_note) { + high_note = (*i)->note()->note(); + } + } + + low_note = min (low_note, notenum); + high_note = max (high_note, notenum); + } + + no_sound_notes = true; + + for (MidiModel::Notes::iterator n = notes.begin(); n != notes.end(); ++n) { + + boost::shared_ptr note (*n); + CanvasNoteEvent* cne; + bool select = false; + + if (((0x0001 << note->channel()) & channel_mask) != 0) { + if (extend) { + if ((note->note() >= low_note && note->note() <= high_note)) { + select = true; + } + } else if (note->note() == notenum) { + select = true; + } + } + + if (select) { + if ((cne = find_canvas_note (note)) != 0) { + // extend is false because we've taken care of it, + // since it extends by time range, not pitch. + note_selected (cne, add, false); + } + } + + add = true; // we need to add all remaining matching notes, even if the passed in value was false (for "set") + + } + + no_sound_notes = false; +} + +void +MidiRegionView::toggle_matching_notes (uint8_t notenum, uint16_t channel_mask) +{ + MidiModel::Notes& notes (_model->notes()); + _optimization_iterator = _events.begin(); + + for (MidiModel::Notes::iterator n = notes.begin(); n != notes.end(); ++n) { + + boost::shared_ptr note (*n); + CanvasNoteEvent* cne; + + if (note->note() == notenum && (((0x0001 << note->channel()) & channel_mask) != 0)) { + if ((cne = find_canvas_note (note)) != 0) { + if (cne->selected()) { + note_deselected (cne); + } else { + note_selected (cne, true, false); + } + } + } + } +} + void MidiRegionView::note_selected(ArdourCanvas::CanvasNoteEvent* ev, bool add, bool extend) { @@ -1659,6 +1756,7 @@ MidiRegionView::add_to_selection (CanvasNoteEvent* ev) } if (_selection.insert (ev).second) { + cerr << "Added CNE to selection, size now " << _selection.size() << endl; ev->selected (true); play_midi_note ((ev)->note()); } @@ -2377,8 +2475,12 @@ MidiRegionView::selection_as_cut_buffer () const { Notes notes; + cerr << "Convert selection of " << _selection.size() << " into a cut buffer\n"; + for (Selection::iterator i = _selection.begin(); i != _selection.end(); ++i) { - notes.insert (boost::shared_ptr (new NoteType (*((*i)->note().get())))); + NoteType* n = (*i)->note().get(); + cerr << "CNE's note is " << n << endl; + notes.insert (boost::shared_ptr (new NoteType (*n))); } MidiCutBuffer* cb = new MidiCutBuffer (trackview.session()); @@ -2431,11 +2533,11 @@ MidiRegionView::paste (nframes64_t pos, float times, const MidiCutBuffer& mcb) if (end_frame > region_end) { - trackview.session().begin_reversible_command (_("paste")); + trackview.session()->begin_reversible_command (_("paste")); - XMLNode& before (_region->get_state()); + _region->clear_history (); _region->set_length (end_frame, this); - trackview.session().add_command (new MementoCommand(*_region, &before, &_region->get_state())); + trackview.session()->add_command (new StatefulDiffCommand (_region)); } apply_delta ();