Add missing files.
[ardour.git] / gtk2_ardour / midi_region_view.cc
index 8da19dd6e3b8a1a72390830543e8a6b8b91fef07..fcab48328711f3ad127de3f199dc51c668c2883d 100644 (file)
@@ -80,6 +80,8 @@ using namespace Editing;
 using namespace ArdourCanvas;
 using Gtkmm2ext::Keyboard;
 
+PBD::Signal1<void, MidiRegionView *> MidiRegionView::SelectionCleared;
+
 #define MIDI_BP_ZERO ((Config->get_first_midi_bank_is_zero())?0:1)
 
 MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv,
@@ -116,6 +118,8 @@ MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &
 
        Config->ParameterChanged.connect (*this, invalidator (*this), ui_bind (&MidiRegionView::parameter_changed, this, _1), gui_context());
        connect_to_diskstream ();
+
+       SelectionCleared.connect (_selection_cleared_connection, invalidator (*this), ui_bind (&MidiRegionView::selection_cleared, this, _1), gui_context ());
 }
 
 MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv,
@@ -149,6 +153,8 @@ MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &
        PublicEditor::DropDownKeys.connect (sigc::mem_fun (*this, &MidiRegionView::drop_down_keys));
 
        connect_to_diskstream ();
+
+       SelectionCleared.connect (_selection_cleared_connection, invalidator (*this), ui_bind (&MidiRegionView::selection_cleared, this, _1), gui_context ());
 }
 
 void
@@ -284,6 +290,14 @@ MidiRegionView::init (Gdk::Color const & basic_color, bool wfd)
 
        Config->ParameterChanged.connect (*this, invalidator (*this), ui_bind (&MidiRegionView::parameter_changed, this, _1), gui_context());
        connect_to_diskstream ();
+
+       SelectionCleared.connect (_selection_cleared_connection, invalidator (*this), ui_bind (&MidiRegionView::selection_cleared, this, _1), gui_context ());
+}
+
+const boost::shared_ptr<ARDOUR::MidiRegion>
+MidiRegionView::midi_region() const
+{
+       return boost::dynamic_pointer_cast<ARDOUR::MidiRegion>(_region);
 }
 
 void
@@ -380,7 +394,7 @@ MidiRegionView::enter_notify (GdkEventCrossing* ev)
 }
 
 bool
-MidiRegionView::leave_notify (GdkEventCrossing* ev)
+MidiRegionView::leave_notify (GdkEventCrossing*)
 {
        _mouse_mode_connection.disconnect ();
 
@@ -711,6 +725,13 @@ MidiRegionView::scroll (GdkEventScroll* ev)
                return false;
        }
 
+       if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
+               /* XXX: bit of a hack; allow PrimaryModifier scroll through so that
+                  it still works for zoom.
+               */
+               return false;
+       }
+
        trackview.editor().verbose_cursor()->hide ();
 
        bool fine = !Keyboard::modifier_state_equals (ev->state, Keyboard::SecondaryModifier);
@@ -835,7 +856,7 @@ void
 MidiRegionView::channel_edit ()
 {
        bool first = true;
-       uint8_t current_channel;
+       uint8_t current_channel = 0;
 
        if (_selection.empty()) {
                return;
@@ -1960,7 +1981,7 @@ MidiRegionView::delete_note (boost::shared_ptr<NoteType> n)
 }
 
 void
-MidiRegionView::clear_selection_except (ArdourCanvas::CanvasNoteEvent* ev)
+MidiRegionView::clear_selection_except (ArdourCanvas::CanvasNoteEvent* ev, bool signal)
 {
        for (Selection::iterator i = _selection.begin(); i != _selection.end(); ) {
                if ((*i) != ev) {
@@ -1980,6 +2001,10 @@ MidiRegionView::clear_selection_except (ArdourCanvas::CanvasNoteEvent* ev)
        /* this does not change the status of this regionview w.r.t the editor
           selection.
        */
+
+       if (signal) {
+               SelectionCleared (this); /* EMIT SIGNAL */
+       }
 }
 
 void
@@ -2008,6 +2033,31 @@ MidiRegionView::select_all_notes ()
        }
 }
 
+void
+MidiRegionView::select_range (framepos_t start, framepos_t end)
+{
+       clear_selection ();
+
+       for (Events::iterator i = _events.begin(); i != _events.end(); ++i) {
+               framepos_t t = source_beats_to_absolute_frames((*i)->note()->time());
+               if (t >= start && t <= end) {
+                       add_to_selection (*i);
+               }
+       }
+}
+
+void
+MidiRegionView::invert_selection ()
+{
+       for (Events::iterator i = _events.begin(); i != _events.end(); ++i) {
+               if ((*i)->selected()) {
+                       remove_from_selection(*i);
+               } else {
+                       add_to_selection (*i);
+               }
+       }
+}
+
 void
 MidiRegionView::select_matching_notes (uint8_t notenum, uint16_t channel_mask, bool add, bool extend)
 {
@@ -2347,6 +2397,9 @@ MidiRegionView::note_dropped(CanvasNoteEvent *, frameoffset_t dt, int8_t dnote)
        }
 }
 
+/** @param x Pixel relative to the region position.
+ *  @return Snapped frame relative to the region position.
+ */
 framepos_t
 MidiRegionView::snap_pixel_to_frame(double x)
 {
@@ -2354,6 +2407,9 @@ MidiRegionView::snap_pixel_to_frame(double x)
        return snap_frame_to_frame (editor.pixel_to_frame (x));
 }
 
+/** @param x Pixel relative to the region position.
+ *  @return Snapped pixel relative to the region position.
+ */
 double
 MidiRegionView::snap_to_pixel(double x)
 {
@@ -2493,9 +2549,6 @@ MidiRegionView::update_resizing (ArdourCanvas::CanvasNoteEvent* primary, bool at
                        double beats;
 
                        beats = snap_pixel_to_frame (current_x);
-                       /* XXX not sure this is correct - snap_pixel_to_frame()
-                          returns an absolute frame.
-                       */
                        beats = region_frames_to_region_beats (beats);
 
                        double len;
@@ -2558,13 +2611,10 @@ MidiRegionView::commit_resizing (ArdourCanvas::CanvasNoteEvent* primary, bool at
                        }
                }
 
-               /* Convert that to a frame within the region */
+               /* Convert that to a frame within the source */
                current_x = snap_pixel_to_frame (current_x) + _region->start ();
 
                /* and then to beats */
-               /* XXX not sure this is correct - snap_pixel_to_frame()
-                  returns an absolute frame.
-               */
                current_x = region_frames_to_region_beats (current_x);
 
                if (at_front && current_x < canvas_note->note()->end_time()) {
@@ -3627,3 +3677,17 @@ MidiRegionView::snap_frame_to_grid_underneath (framepos_t p, framecnt_t& grid_fr
 
        return snap_frame_to_frame (p);
 }
+
+/** Called when the selection has been cleared in any MidiRegionView.
+ *  @param rv MidiRegionView that the selection was cleared in.
+ */
+void
+MidiRegionView::selection_cleared (MidiRegionView* rv)
+{
+       if (rv == this) {
+               return;
+       }
+
+       /* Clear our selection in sympathy; but don't signal the fact */
+       clear_selection (false);
+}