finished merge of cairocanvas with windows and windows+cc branches
[ardour.git] / gtk2_ardour / midi_region_view.cc
index 08211b6e840da2a2059b1fba834e9e67a1f0913d..afae96bf2215d485a8206472177e4a25bc5437b2 100644 (file)
@@ -43,7 +43,7 @@
 #include "evoral/Control.hpp"
 #include "evoral/midi_util.h"
 
-#include "canvas/pixbuf.h"
+#include "canvas/debug.h"
 
 #include "automation_region_view.h"
 #include "automation_time_axis.h"
@@ -114,6 +114,7 @@ MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &
        , pre_press_cursor (0)
        , _note_player (0)
 {
+       CANVAS_DEBUG_NAME (_note_group, string_compose ("note group for %1", get_item_name()));
        _note_group->raise_to_top();
        PublicEditor::DropDownKeys.connect (sigc::mem_fun (*this, &MidiRegionView::drop_down_keys));
 
@@ -150,7 +151,9 @@ MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &
        , pre_press_cursor (0)
        , _note_player (0)
 {
+       CANVAS_DEBUG_NAME (_note_group, string_compose ("note group for %1", get_item_name()));
        _note_group->raise_to_top();
+
        PublicEditor::DropDownKeys.connect (sigc::mem_fun (*this, &MidiRegionView::drop_down_keys));
 
        connect_to_diskstream ();
@@ -276,8 +279,6 @@ MidiRegionView::init (Gdk::Color const & basic_color, bool wfd)
        reset_width_dependent_items (_pixel_width);
 
        group->raise_to_top();
-       group->Event.connect (sigc::mem_fun (this, &MidiRegionView::canvas_event));
-
 
        midi_view()->midi_track()->PlaybackChannelModeChanged.connect (_channel_mode_changed_connection, invalidator (*this),
                                                                       boost::bind (&MidiRegionView::midi_channel_mode_changed, this),
@@ -319,7 +320,7 @@ MidiRegionView::connect_to_diskstream ()
 }
 
 bool
-MidiRegionView::canvas_event(GdkEvent* ev)
+MidiRegionView::canvas_group_event(GdkEvent* ev)
 {
        bool r;
 
@@ -385,7 +386,7 @@ MidiRegionView::canvas_event(GdkEvent* ev)
                break;
        }
 
-       return false;
+       return trackview.editor().canvas_region_view_event (ev, group, this);
 }
 
 void
@@ -626,7 +627,6 @@ MidiRegionView::motion (GdkEventMotion* ev)
                        MouseMode m = editor.current_mouse_mode();
                        
                        if (m == MouseDraw || (m == MouseObject && Keyboard::modifier_state_contains (ev->state, Keyboard::insert_note_modifier()))) {
-                       
                                editor.drags()->set (new NoteCreateDrag (dynamic_cast<Editor *> (&editor), group, this), (GdkEvent *) ev);
                                _mouse_state = AddDragging;
                                remove_ghost_note ();
@@ -2135,32 +2135,39 @@ MidiRegionView::invert_selection ()
 void
 MidiRegionView::select_matching_notes (uint8_t notenum, uint16_t channel_mask, bool add, bool extend)
 {
+       bool have_selection = !_selection.empty();
        uint8_t low_note = 127;
        uint8_t high_note = 0;
        MidiModel::Notes& notes (_model->notes());
        _optimization_iterator = _events.begin();
+       
+       if (extend && !have_selection) {
+               extend = false;
+       }
 
+       /* 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();
+               }
+       }
+       
        if (!add) {
                clear_selection ();
-       }
 
-       if (extend && _selection.empty()) {
-               extend = false;
+               if (!extend && (low_note == high_note) && (high_note == notenum)) {
+                       /* only note previously selected is the one we are
+                        * reselecting. treat this as cancelling the selection.
+                        */
+                       return;
+               }
        }
 
        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);
        }
@@ -3073,7 +3080,7 @@ MidiRegionView::nudge_notes (bool forward)
                return;
        }
 
-       Evoral::MusicalTime delta = region_frames_to_region_beats (fabs (distance));
+       Evoral::MusicalTime delta = region_frames_to_region_beats (fabs ((double)distance));
 
        if (!forward) {
                delta = -delta;
@@ -3291,7 +3298,7 @@ MidiRegionView::selection_as_cut_buffer () const
 {
        Notes notes;
 
-       for (Selection::iterator i = _selection.begin(); i != _selection.end(); ++i) {
+       for (Selection::const_iterator i = _selection.begin(); i != _selection.end(); ++i) {
                NoteType* n = (*i)->note().get();
                notes.insert (boost::shared_ptr<NoteType> (new NoteType (*n)));
        }
@@ -3755,8 +3762,6 @@ MidiRegionView::edit_patch_change (PatchChange* pc)
 {
        PatchChangeDialog d (&_source_relative_time_converter, trackview.session(), *pc->patch (), instrument_info(), Gtk::Stock::APPLY, true);
 
-        d.set_position (Gtk::WIN_POS_MOUSE);
-       
        int response = d.run();
 
        switch (response) {