diff --git a/gtk2_ardour/canvas-program-change.cc b/gtk2_ardour/canvas-program-change.cc index b48d7b33ba..4e178819f2 100644 --- a/gtk2_ardour/canvas-program-change.cc +++ b/gtk2_ardour/canvas-program-change.cc @@ -2,6 +2,7 @@ #include +#include "gtkmm2ext/keyboard.h" #include "ardour/midi_patch_manager.h" #include "ardour_ui.h" #include "midi_region_view.h" @@ -108,22 +109,27 @@ CanvasProgramChange::on_patch_menu_selected(const PatchPrimaryKey& key) } bool -CanvasProgramChange::on_event(GdkEvent* ev) +CanvasProgramChange::on_event (GdkEvent* ev) { switch (ev->type) { case GDK_BUTTON_PRESS: - switch (ev->button.button) { - case 1: - { - /* XXX: icky dcast */ - Editor* e = dynamic_cast (&_region.get_time_axis_view().editor()); - if (e->current_mouse_mode() == Editing::MouseObject && e->internal_editing()) { + { + /* XXX: icky dcast */ + Editor* e = dynamic_cast (&_region.get_time_axis_view().editor()); + if (e->current_mouse_mode() == Editing::MouseObject && e->internal_editing()) { + + if (Gtkmm2ext::Keyboard::is_delete_event (&ev->button)) { + + _region.delete_program_change (this); + return true; + + } else if (ev->button.button == 1) { e->drags()->set (new ProgramChangeDrag (e, this, &_region), ev); return true; } } - case 3: - // lazy init + + if (ev->button.button == 3) { if (!_popup_initialized) { initialize_popup_menus(); _popup_initialized = true; @@ -132,6 +138,7 @@ CanvasProgramChange::on_event(GdkEvent* ev) return true; } break; + } case GDK_KEY_PRESS: switch (ev->key.keyval) { diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc index e2298c42ad..8ceb31afc9 100644 --- a/gtk2_ardour/midi_region_view.cc +++ b/gtk2_ardour/midi_region_view.cc @@ -1674,21 +1674,20 @@ MidiRegionView::move_program_change (PCEvent pc, double t) boost::shared_ptr control = _model->control (Evoral::Parameter (MidiPgmChangeAutomation, pc.channel, 0)); assert (control); - /* XXX: seems that these events should have IDs, or that this code should - at least be in ControlList. - */ + control->list()->erase (pc.time, pc.value); + control->list()->add (t, pc.value); - boost::shared_ptr list = control->list (); - Evoral::ControlList::iterator i = list->begin (); - while (i != list->end() && ((*i)->when != pc.time || (*i)->value != pc.value)) { - ++i; - } + _pgm_changes.clear (); + display_program_changes (); +} - assert (i != list->end ()); - - list->erase (i); - list->add (t, pc.value); +void +MidiRegionView::delete_program_change (CanvasProgramChange* pc) +{ + boost::shared_ptr control = _model->control (Evoral::Parameter (MidiPgmChangeAutomation, pc->channel(), 0)); + assert (control); + control->list()->erase (pc->event_time(), pc->program()); _pgm_changes.clear (); display_program_changes (); } diff --git a/gtk2_ardour/midi_region_view.h b/gtk2_ardour/midi_region_view.h index 79a8405927..781ef35036 100644 --- a/gtk2_ardour/midi_region_view.h +++ b/gtk2_ardour/midi_region_view.h @@ -150,6 +150,7 @@ class MidiRegionView : public RegionView void alter_program_change(PCEvent& old_program, const MIDI::Name::PatchPrimaryKey& new_patch); void move_program_change (PCEvent, double); + void delete_program_change (ArdourCanvas::CanvasProgramChange *); /** Alter a given program to the new given one. * (Called on context menu select on CanvasProgramChange) diff --git a/libs/evoral/evoral/ControlList.hpp b/libs/evoral/evoral/ControlList.hpp index 16d0400145..8b8083f31c 100644 --- a/libs/evoral/evoral/ControlList.hpp +++ b/libs/evoral/evoral/ControlList.hpp @@ -124,6 +124,7 @@ public: void erase_range (double start, double end); void erase (iterator); void erase (iterator, iterator); + void erase (double, double); bool move_ranges (std::list< RangeMove > const &); void modify (iterator, double, double); diff --git a/libs/evoral/src/ControlList.cpp b/libs/evoral/src/ControlList.cpp index b717190768..cc8ba45001 100644 --- a/libs/evoral/src/ControlList.cpp +++ b/libs/evoral/src/ControlList.cpp @@ -449,6 +449,28 @@ ControlList::erase (iterator start, iterator end) maybe_signal_changed (); } +/** Erase the first event which matches the given time and value */ +void +ControlList::erase (double when, double value) +{ + { + Glib::Mutex::Lock lm (_lock); + + iterator i = begin (); + while (i != end() && ((*i)->when != when || (*i)->value != value)) { + ++i; + } + + if (i != end ()) { + _events.erase (i); + } + + mark_dirty (); + } + + maybe_signal_changed (); +} + void ControlList::reset_range (double start, double endt) {