Prevent note creation drags with no movement of the pointer. May fix #3159.
[ardour.git] / gtk2_ardour / editor_summary.cc
index be609638cf401466a08f3bd95efff3e052df83b2..5c2135ac43ac45d8dbedae624f3f29ba8956720c 100644 (file)
@@ -28,7 +28,6 @@
 #include "keyboard.h"
 
 using namespace std;
-using namespace sigc;
 using namespace ARDOUR;
 using Gtkmm2ext::Keyboard;
 
@@ -48,25 +47,29 @@ EditorSummary::EditorSummary (Editor* e)
          _zoom_dragging (false)
 
 {
-
+       Region::RegionPropertyChanged.connect (region_property_connection, invalidator (*this), boost::bind (&CairoWidget::set_dirty, this), gui_context());
+       _editor->playhead_cursor->PositionChanged.connect (position_connection, invalidator (*this), ui_bind (&EditorSummary::playhead_position_changed, this, _1), gui_context());
 }
 
 /** Connect to a session.
  *  @param s Session.
  */
 void
-EditorSummary::connect_to_session (Session* s)
+EditorSummary::set_session (Session* s)
 {
-       EditorComponent::connect_to_session (s);
+       EditorComponent::set_session (s);
 
-       Region::RegionPropertyChanged.connect (sigc::hide (mem_fun (*this, &EditorSummary::set_dirty)));
+       set_dirty ();
 
-       _session_connections.push_back (_session->RegionRemoved.connect (sigc::hide (mem_fun (*this, &EditorSummary::set_dirty))));
-       _session_connections.push_back (_session->StartTimeChanged.connect (mem_fun (*this, &EditorSummary::set_dirty)));
-       _session_connections.push_back (_session->EndTimeChanged.connect (mem_fun (*this, &EditorSummary::set_dirty)));
-       _editor->playhead_cursor->PositionChanged.connect (mem_fun (*this, &EditorSummary::playhead_position_changed));
+       /* Note: the EditorSummary already finds out about new regions from Editor::region_view_added
+        * (which attaches to StreamView::RegionViewAdded), and cut regions by the RegionPropertyChanged
+        * emitted when a cut region is added to the `cutlist' playlist.
+        */
 
-       set_dirty ();
+       if (_session) {
+               _session->StartTimeChanged.connect (_session_connections, invalidator (*this), boost::bind (&EditorSummary::set_dirty, this), gui_context());
+               _session->EndTimeChanged.connect (_session_connections, invalidator (*this), boost::bind (&EditorSummary::set_dirty, this), gui_context());
+       }
 }
 
 /** Handle an expose event.
@@ -144,35 +147,38 @@ EditorSummary::render (cairo_t* cr)
 
        int h = 0;
        int max_height = 0;
-       for (PublicEditor::TrackViewList::const_iterator i = _editor->track_views.begin(); i != _editor->track_views.end(); ++i) {
+       for (TrackViewList::const_iterator i = _editor->track_views.begin(); i != _editor->track_views.end(); ++i) {
                int const t = (*i)->effective_height ();
                h += t;
                max_height = max (max_height, t);
        }
 
-       _x_scale = static_cast<double> (_width) / (_end - _start);
+       if (_end != _start) {
+               _x_scale = static_cast<double> (_width) / (_end - _start);
+       } else {
+               _x_scale = 1;
+       }
        _y_scale = static_cast<double> (_height) / h;
 
        /* tallest a region should ever be in the summary, in pixels */
-       int const tallest_region_pixels = 4;
+       int const tallest_region_pixels = _height / 16;
 
        if (max_height * _y_scale > tallest_region_pixels) {
                _y_scale = static_cast<double> (tallest_region_pixels) / max_height;
-
        }
 
        /* render regions */
 
        double y = 0;
-       for (PublicEditor::TrackViewList::const_iterator i = _editor->track_views.begin(); i != _editor->track_views.end(); ++i) {
+       for (TrackViewList::const_iterator i = _editor->track_views.begin(); i != _editor->track_views.end(); ++i) {
                StreamView* s = (*i)->view ();
 
                if (s) {
                        double const h = (*i)->effective_height () * _y_scale;
                        cairo_set_line_width (cr, h);
 
-                       s->foreach_regionview (bind (
-                                                      mem_fun (*this, &EditorSummary::render_region),
+                       s->foreach_regionview (sigc::bind (
+                                                      sigc::mem_fun (*this, &EditorSummary::render_region),
                                                       cr,
                                                       y + h / 2
                                                       ));
@@ -226,7 +232,7 @@ EditorSummary::render_region (RegionView* r, cairo_t* cr, double y) const
 void
 EditorSummary::set_overlays_dirty ()
 {
-       ENSURE_GUI_THREAD (mem_fun (*this, &EditorSummary::set_overlays_dirty));
+       ENSURE_GUI_THREAD (*this, &EditorSummary::set_overlays_dirty)
        queue_draw ();
 }
 
@@ -293,6 +299,22 @@ EditorSummary::on_button_press_event (GdkEventButton* ev)
                _start_mouse_x = ev->x;
                _start_mouse_y = ev->y;
 
+               if (
+                       _start_editor_x.first <= _start_mouse_x && _start_mouse_x <= _start_editor_x.second &&
+                       _start_editor_y.first <= _start_mouse_y && _start_mouse_y <= _start_editor_y.second
+                       ) {
+
+                       _start_position = IN_VIEWBOX;
+
+               } else if (_start_editor_x.first <= _start_mouse_x && _start_mouse_x <= _start_editor_x.second) {
+
+                       _start_position = BELOW_OR_ABOVE_VIEWBOX;
+
+               } else {
+
+                       _start_position = TO_LEFT_OR_RIGHT_OF_VIEWBOX;
+               }
+
                if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
 
                        /* primary-modifier-click: start a zoom drag */
@@ -359,10 +381,17 @@ EditorSummary::on_motion_notify_event (GdkEventMotion* ev)
 
                _moved = true;
 
-               xr.first += ev->x - _start_mouse_x;
-               xr.second += ev->x - _start_mouse_x;
-               yr.first += ev->y - _start_mouse_y;
-               yr.second += ev->y - _start_mouse_y;
+               /* don't alter x if we clicked outside and above or below the viewbox */
+               if (_start_position == IN_VIEWBOX || _start_position == TO_LEFT_OR_RIGHT_OF_VIEWBOX) {
+                       xr.first += ev->x - _start_mouse_x;
+                       xr.second += ev->x - _start_mouse_x;
+               }
+
+               /* don't alter y if we clicked outside and to the left or right of the viewbox */
+               if (_start_position == IN_VIEWBOX || _start_position == BELOW_OR_ABOVE_VIEWBOX) {
+                       yr.first += ev->y - _start_mouse_y;
+                       yr.second += ev->y - _start_mouse_y;
+               }
 
                if (xr.first < 0) {
                        xr.second -= xr.first;
@@ -502,7 +531,7 @@ EditorSummary::set_editor (pair<double,double> const & x, pair<double, double> c
 void
 EditorSummary::playhead_position_changed (nframes64_t p)
 {
-       if (int (p * _x_scale) != int (_last_playhead)) {
+       if (_session && int (p * _x_scale) != int (_last_playhead)) {
                set_overlays_dirty ();
        }
 }