Context menu for applying edits to note selection.
authorDavid Robillard <d@drobilla.net>
Thu, 25 Dec 2014 20:32:10 +0000 (15:32 -0500)
committerDavid Robillard <d@drobilla.net>
Thu, 25 Dec 2014 20:32:10 +0000 (15:32 -0500)
gtk2_ardour/editor.cc
gtk2_ardour/editor.h
gtk2_ardour/editor_mouse.cc
gtk2_ardour/editor_ops.cc
gtk2_ardour/note_base.cc
gtk2_ardour/public_editor.h
gtk2_ardour/region_selection.cc
gtk2_ardour/region_selection.h

index e379bc253726ea37720d3c523d498e998398e298..58f3da9d96c888612824266a2cd1456d5cc84455 100644 (file)
 #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<NoteBase*>(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()
 {
index 3be24579d7c590734c61c74ac1ea484c1ff2f200..67f1d0824f262bf4678d20aa2d014632d1075afc 100644 (file)
@@ -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 */
 
index 1dd99763e9277d9b46ec09c889ce0b4ba0b0f336..6f22199d661a727558e52bbd171924170b27bf3d 100644 (file)
@@ -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<MidiRegionView*>(&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);
 
index 64a7d1a059842f85998cc2a4ccab78e14aaa5348..2327a318d4393a339abf07cebe1c21a8224fa5a2 100644 (file)
@@ -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<MidiRegionView*> (*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<MidiRegionView*> (*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<MidiRegionView*> (*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
index 9fba9be10aaf9f9d1eb858f76ac86a0d7b7128b2..56ce3bc9d13bb0d35cb1e79e46f54ab18bd5663d 100644 (file)
@@ -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:
index 900e9857dbc7b18d0b0e2a68d3b8b31b2e90618e..c126c1bab953715896dce356bae36255ae8864b7 100644 (file)
@@ -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;
index 54e5aa3acce47b69ff6fb737253bdf6bdaee29a7..1536dd61e4e7ad1b8bfdfa1b5bbff437d8ab981b 100644 (file)
@@ -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<MidiRegionView*> (*r);
+               if (mrv) {
+                       ++count;
+               }
+       }
+
+       return count;
+}
index 0cd603e5f4ebe7c0c89fd3d189c30ef55152f208..062557eb9bbaeb43b1ac4aac921bd142cb31f011 100644 (file)
@@ -61,6 +61,8 @@ class RegionSelection : public std::list<RegionView*>
        void  by_position (std::list<RegionView*>&) const;
        void  by_track (std::list<RegionView*>&) const;
 
+       size_t n_midi_regions() const;
+
        std::set<boost::shared_ptr<ARDOUR::Playlist> > playlists () const;
        std::list<PBD::ID> pending;