From 12a7f12b0bcee20b6041b7ece27a120b130271c2 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Thu, 25 Dec 2014 15:32:10 -0500 Subject: Context menu for applying edits to note selection. --- gtk2_ardour/editor.cc | 36 ++++++++++++++++++++++ gtk2_ardour/editor.h | 9 ++++-- gtk2_ardour/editor_mouse.cc | 16 +++++----- gtk2_ardour/editor_ops.cc | 66 +++++++++++++---------------------------- gtk2_ardour/note_base.cc | 7 ----- gtk2_ardour/public_editor.h | 2 +- gtk2_ardour/region_selection.cc | 16 ++++++++++ gtk2_ardour/region_selection.h | 2 ++ 8 files changed, 90 insertions(+), 64 deletions(-) diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index e379bc2537..58f3da9d96 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -107,10 +107,12 @@ #include "gui_thread.h" #include "keyboard.h" #include "marker.h" +#include "midi_region_view.h" #include "midi_time_axis.h" #include "mixer_strip.h" #include "mixer_ui.h" #include "mouse_cursors.h" +#include "note_base.h" #include "playlist_selector.h" #include "public_editor.h" #include "region_layering_order_editor.h" @@ -5735,6 +5737,40 @@ Editor::popup_control_point_context_menu (ArdourCanvas::Item* item, GdkEvent* ev _control_point_context_menu.popup (event->button.button, event->button.time); } +void +Editor::popup_note_context_menu (ArdourCanvas::Item* item, GdkEvent* event) +{ + using namespace Menu_Helpers; + + NoteBase* note = reinterpret_cast(item->get_data("notebase")); + if (!note) { + return; + } + + /* We need to get the selection here and pass it to the operations, since + popping up the menu will cause a region leave event which clears + entered_regionview. */ + + MidiRegionView& mrv = note->region_view(); + const RegionSelection rs = get_regions_from_selection_and_entered (); + + MenuList& items = _note_context_menu.items(); + items.clear(); + + items.push_back(MenuElem(_("Delete"), + sigc::mem_fun(mrv, &MidiRegionView::delete_selection))); + items.push_back(MenuElem(_("Edit..."), + sigc::bind(sigc::mem_fun(*this, &Editor::edit_notes), &mrv))); + items.push_back(MenuElem(_("Legatize"), + sigc::bind(sigc::mem_fun(*this, &Editor::legatize_regions), rs, false))); + items.push_back(MenuElem(_("Quantize..."), + sigc::bind(sigc::mem_fun(*this, &Editor::quantize_regions), rs))); + items.push_back(MenuElem(_("Remove Overlap"), + sigc::bind(sigc::mem_fun(*this, &Editor::legatize_regions), rs, true))); + + _note_context_menu.popup (event->button.button, event->button.time); +} + void Editor::zoom_vertical_modifier_released() { diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index 3be24579d7..67f1d0824f 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -740,6 +740,9 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD void popup_control_point_context_menu (ArdourCanvas::Item *, GdkEvent *); Gtk::Menu _control_point_context_menu; + void popup_note_context_menu (ArdourCanvas::Item *, GdkEvent *); + Gtk::Menu _note_context_menu; + void add_routes (ARDOUR::RouteList&); void timeaxisview_deleted (TimeAxisView *); @@ -1227,7 +1230,9 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD void reset_region_scale_amplitude (); void adjust_region_gain (bool up); void quantize_region (); + void quantize_regions (const RegionSelection& rs); void legatize_region (bool shrink_only); + void legatize_regions (const RegionSelection& rs, bool shrink_only); void insert_patch_change (bool from_context); void fork_region (); @@ -1608,7 +1613,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD void edit_tempo_marker (TempoMarker&); void edit_meter_marker (MeterMarker&); void edit_control_point (ArdourCanvas::Item*); - void edit_notes (TimeAxisViewItem&); + void edit_notes (MidiRegionView*); void marker_menu_edit (); void marker_menu_remove (); @@ -2016,7 +2021,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD void apply_filter (ARDOUR::Filter&, std::string cmd, ProgressReporter* progress = 0); Command* apply_midi_note_edit_op_to_region (ARDOUR::MidiOperator& op, MidiRegionView& mrv); - void apply_midi_note_edit_op (ARDOUR::MidiOperator& op); + void apply_midi_note_edit_op (ARDOUR::MidiOperator& op, const RegionSelection& rs); /* handling cleanup */ diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc index 1dd99763e9..6f22199d66 100644 --- a/gtk2_ardour/editor_mouse.cc +++ b/gtk2_ardour/editor_mouse.cc @@ -1305,6 +1305,12 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT popup_control_point_context_menu (item, event); break; + case NoteItem: + if (internal_editing()) { + popup_note_context_menu (item, event); + } + break; + default: break; } @@ -1883,21 +1889,15 @@ Editor::edit_control_point (ArdourCanvas::Item* item) } void -Editor::edit_notes (TimeAxisViewItem& tavi) +Editor::edit_notes (MidiRegionView* mrv) { - MidiRegionView* mrv = dynamic_cast(&tavi); - - if (!mrv) { - return; - } - MidiRegionView::Selection const & s = mrv->selection(); if (s.empty ()) { return; } - EditNoteDialog* d = new EditNoteDialog (&(*s.begin())->region_view(), s); + EditNoteDialog* d = new EditNoteDialog (mrv, s); d->show_all (); ensure_float (*d); diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc index 64a7d1a059..2327a318d4 100644 --- a/gtk2_ardour/editor_ops.cc +++ b/gtk2_ardour/editor_ops.cc @@ -4909,26 +4909,22 @@ Editor::apply_midi_note_edit_op_to_region (MidiOperator& op, MidiRegionView& mrv } void -Editor::apply_midi_note_edit_op (MidiOperator& op) +Editor::apply_midi_note_edit_op (MidiOperator& op, const RegionSelection& rs) { - Command* cmd; - - RegionSelection rs = get_regions_from_selection_and_entered (); - if (rs.empty()) { return; } begin_reversible_command (op.name ()); - for (RegionSelection::iterator r = rs.begin(); r != rs.end(); ) { - RegionSelection::iterator tmp = r; + for (RegionSelection::const_iterator r = rs.begin(); r != rs.end(); ) { + RegionSelection::const_iterator tmp = r; ++tmp; MidiRegionView* const mrv = dynamic_cast (*r); if (mrv) { - cmd = apply_midi_note_edit_op_to_region (op, *mrv); + Command* cmd = apply_midi_note_edit_op_to_region (op, *mrv); if (cmd) { (*cmd)(); _session->add_command (cmd); @@ -4984,26 +4980,15 @@ Editor::fork_region () void Editor::quantize_region () { - int selected_midi_region_cnt = 0; - - if (!_session) { - return; - } - - RegionSelection rs = get_regions_from_selection_and_entered (); - - if (rs.empty()) { - return; - } - - for (RegionSelection::iterator r = rs.begin(); r != rs.end(); ++r) { - MidiRegionView* const mrv = dynamic_cast (*r); - if (mrv) { - selected_midi_region_cnt++; - } + if (_session) { + quantize_regions(get_regions_from_selection_and_entered ()); } +} - if (selected_midi_region_cnt == 0) { +void +Editor::quantize_regions (const RegionSelection& rs) +{ + if (rs.n_midi_regions() == 0) { return; } @@ -5018,38 +5003,27 @@ Editor::quantize_region () qd->start_grid_size(), qd->end_grid_size(), qd->strength(), qd->swing(), qd->threshold()); - apply_midi_note_edit_op (quant); + apply_midi_note_edit_op (quant, rs); } } void Editor::legatize_region (bool shrink_only) { - int selected_midi_region_cnt = 0; - - if (!_session) { - return; - } - - RegionSelection rs = get_regions_from_selection_and_entered (); - - if (rs.empty()) { - return; - } - - for (RegionSelection::iterator r = rs.begin(); r != rs.end(); ++r) { - MidiRegionView* const mrv = dynamic_cast (*r); - if (mrv) { - selected_midi_region_cnt++; - } + if (_session) { + legatize_regions(get_regions_from_selection_and_entered (), shrink_only); } +} - if (selected_midi_region_cnt == 0) { +void +Editor::legatize_regions (const RegionSelection& rs, bool shrink_only) +{ + if (rs.n_midi_regions() == 0) { return; } Legatize legatize(shrink_only); - apply_midi_note_edit_op (legatize); + apply_midi_note_edit_op (legatize, rs); } void diff --git a/gtk2_ardour/note_base.cc b/gtk2_ardour/note_base.cc index 9fba9be10a..56ce3bc9d1 100644 --- a/gtk2_ardour/note_base.cc +++ b/gtk2_ardour/note_base.cc @@ -276,17 +276,10 @@ NoteBase::event_handler (GdkEvent* ev) case GDK_BUTTON_PRESS: set_mouse_fractions (ev); - if (ev->button.button == 3 && Keyboard::no_modifiers_active (ev->button.state) && _selected) { - editor.edit_notes (_region); - return true; - } break; case GDK_BUTTON_RELEASE: set_mouse_fractions (ev); - if (ev->button.button == 3 && Keyboard::no_modifiers_active (ev->button.state)) { - return true; - } break; default: diff --git a/gtk2_ardour/public_editor.h b/gtk2_ardour/public_editor.h index 900e9857db..c126c1bab9 100644 --- a/gtk2_ardour/public_editor.h +++ b/gtk2_ardour/public_editor.h @@ -290,7 +290,7 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulDestructible, publi virtual framecnt_t get_nudge_distance (framepos_t pos, framecnt_t& next) = 0; virtual framecnt_t get_paste_offset (framepos_t pos, unsigned paste_count, framecnt_t duration) = 0; virtual Evoral::MusicalTime get_grid_type_as_beats (bool& success, framepos_t position) = 0; - virtual void edit_notes (TimeAxisViewItem&) = 0; + virtual void edit_notes (MidiRegionView*) = 0; virtual void queue_visual_videotimeline_update () = 0; virtual void set_close_video_sensitive (bool) = 0; diff --git a/gtk2_ardour/region_selection.cc b/gtk2_ardour/region_selection.cc index 54e5aa3acc..1536dd61e4 100644 --- a/gtk2_ardour/region_selection.cc +++ b/gtk2_ardour/region_selection.cc @@ -21,6 +21,7 @@ #include "ardour/region.h" #include "gui_thread.h" +#include "midi_region_view.h" #include "region_view.h" #include "region_selection.h" #include "time_axis_view.h" @@ -287,3 +288,18 @@ RegionSelection::playlists () const return pl; } + +size_t +RegionSelection::n_midi_regions () const +{ + size_t count = 0; + + for (const_iterator r = begin(); r != end(); ++r) { + MidiRegionView* const mrv = dynamic_cast (*r); + if (mrv) { + ++count; + } + } + + return count; +} diff --git a/gtk2_ardour/region_selection.h b/gtk2_ardour/region_selection.h index 0cd603e5f4..062557eb9b 100644 --- a/gtk2_ardour/region_selection.h +++ b/gtk2_ardour/region_selection.h @@ -61,6 +61,8 @@ class RegionSelection : public std::list void by_position (std::list&) const; void by_track (std::list&) const; + size_t n_midi_regions() const; + std::set > playlists () const; std::list pending; -- cgit v1.2.3