#include <sigc++/signal.h>
#include "pbd/memento_command.h"
+#include "pbd/stateful_diff_command.h"
#include "ardour/playlist.h"
#include "ardour/tempo.h"
, _pressed_button(0)
, _sort_needed (true)
, _optimization_iterator (_events.end())
+ , _list_editor (0)
+ , no_sound_notes (false)
{
_note_group->raise_to_top();
}
, _pressed_button(0)
, _sort_needed (true)
, _optimization_iterator (_events.end())
+ , _list_editor (0)
+ , no_sound_notes (false)
{
_note_group->raise_to_top();
, _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;
, _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;
region_muted ();
region_sync_changed ();
- region_resized (BoundsChanged);
+ region_resized (ARDOUR::bounds_change);
region_locked ();
reset_width_dependent_items (_pixel_width);
void
MidiRegionView::show_list_editor ()
{
- MidiListEditor* mle = new MidiListEditor (trackview.session(), midi_region());
- mle->show ();
+ 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.
{
in_destructor = true;
+ delete _list_editor;
+
RegionViewGoingAway (this); /* EMIT_SIGNAL */
if (_active_notes) {
}
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();
}
}
- ghost->GoingAway.connect (*this, ui_bind (&RegionView::remove_ghost, this, _1), gui_context());
+ GhostRegion::CatchDeletion.connect (*this, ui_bind (&RegionView::remove_ghost, this, _1), gui_context());
return ghost;
}
void
MidiRegionView::play_midi_note(boost::shared_ptr<NoteType> note)
{
- if (!trackview.editor().sound_notes()) {
+ if (no_sound_notes || !trackview.editor().sound_notes()) {
return;
}
}
}
+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<NoteType> 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<NoteType> 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)
{
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>(*_region, &before, &_region->get_state()));
+ trackview.session()->add_command (new StatefulDiffCommand (_region));
}
apply_delta ();