]> git.saurik.com Git - wxWidgets.git/commitdiff
don't generate a scroll event when setting scroll position from scroll event handler
authorPaul Cornett <paulcor@bullseye.com>
Sat, 3 Jun 2006 18:35:29 +0000 (18:35 +0000)
committerPaul Cornett <paulcor@bullseye.com>
Sat, 3 Jun 2006 18:35:29 +0000 (18:35 +0000)
fix setting scroll position from thumb release event handler

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@39536 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/gtk/window.h
src/gtk/scrolbar.cpp
src/gtk/window.cpp

index 0f5478fe2baeab7bbb9f52d8dff09a6c1ad7c1cf..cd4b93c158e19c603ad1bde6f5b02b965674ab78 100644 (file)
@@ -215,6 +215,7 @@ public:
     GtkRange* m_scrollBar[2];
     // horizontal/vertical scroll position
     double m_scrollPos[2];
+    bool m_blockValueChanged[2];
 
     // extra (wxGTK-specific) flags
     bool                 m_needParent:1;        // ! wxFrame, wxDialog, wxNotebookPage ?
index 13983bb7718c4ff6476b691a0a99978f8273858c..cf66761a5d826c207bd0d9eed631d81de1fc0e67 100644 (file)
@@ -32,9 +32,11 @@ gtk_value_changed(GtkRange* range, wxScrollBar* win)
     if (eventType != wxEVT_NULL)
     {
         const int orient = win->HasFlag(wxSB_VERTICAL) ? wxVERTICAL : wxHORIZONTAL;
+        const int i = orient == wxVERTICAL;
         const int value = win->GetThumbPosition();
         wxScrollEvent event(eventType, win->GetId(), value, orient);
         event.SetEventObject(win);
+        win->m_blockValueChanged[i] = true;
         win->GetEventHandler()->ProcessEvent(event);
         if (!win->m_isScrolling)
         {
@@ -42,6 +44,7 @@ gtk_value_changed(GtkRange* range, wxScrollBar* win)
             event.SetEventObject(win);
             win->GetEventHandler()->ProcessEvent(event);
         }
+        win->m_blockValueChanged[i] = false;
     }
 }
 }
@@ -82,11 +85,13 @@ gtk_button_release_event(GtkRange*, GdkEventButton*, wxScrollBar* win)
 
         wxScrollEvent event(wxEVT_SCROLL_THUMBRELEASE, win->GetId(), value, orient);
         event.SetEventObject(win);
-        win->GetEventHandler()->ProcessEvent(event);
+        // To allow setting scroll position from event handler, sending event must
+        // be deferred until after the GtkRange handler for this signal has run
+        win->GetEventHandler()->AddPendingEvent(event);
 
         wxScrollEvent event2(wxEVT_SCROLL_CHANGED, win->GetId(), value, orient);
         event2.SetEventObject(win);
-        win->GetEventHandler()->ProcessEvent(event2);
+        win->GetEventHandler()->AddPendingEvent(event2);
     }
 
     return false;
@@ -171,12 +176,21 @@ void wxScrollBar::SetThumbPosition( int viewStart )
 {
     if (GetThumbPosition() != viewStart)
     {
-        BlockScrollEvent();
-        gtk_range_set_value((GtkRange*)m_widget, viewStart);
-        UnblockScrollEvent();
         GtkAdjustment* adj = ((GtkRange*)m_widget)->adjustment;
-        const int i = HasFlag(wxSB_VERTICAL);
-        m_scrollPos[i] = adj->value;
+        const int i = (GtkRange*)m_widget == m_scrollBar[1];
+        const int max = int(adj->upper - adj->page_size);
+        if (viewStart > max)
+            viewStart = max;
+        if (viewStart < 0)
+            viewStart = 0;
+
+        m_scrollPos[i] =
+        adj->value = viewStart;
+        // If a "value_changed" signal emission is not already in progress
+        if (!m_blockValueChanged[i])
+        {
+            gtk_adjustment_value_changed(adj);
+        }
     }
 }
 
@@ -188,16 +202,17 @@ void wxScrollBar::SetScrollbar(int position, int thumbSize, int range, int pageS
         range =
         thumbSize = 1;
     }
+    if (position > range - thumbSize)
+        position = range - thumbSize;
+    if (position < 0)
+        position = 0;
     GtkAdjustment* adj = ((GtkRange*)m_widget)->adjustment;
-    adj->value = position;
     adj->step_increment = 1;
     adj->page_increment = pageSize;
     adj->page_size = thumbSize;
-    BlockScrollEvent();
-    gtk_range_set_range((GtkRange*)m_widget, 0, range);
-    UnblockScrollEvent();
-    const int i = HasFlag(wxSB_VERTICAL);
-    m_scrollPos[i] = adj->value;
+    adj->upper = range;
+    SetThumbPosition(position);
+    gtk_adjustment_changed(adj);
 }
 
 void wxScrollBar::SetPageSize( int pageLength )
index 5ebf62893df1f5649ea98234e84c50b38c278e83..82eec9cf6275bf6f2f7acaa6d938ad589e0a855b 100644 (file)
@@ -2107,9 +2107,12 @@ gtk_scrollbar_value_changed(GtkRange* range, wxWindow* win)
         // Convert scroll event type to scrollwin event type
         eventType += wxEVT_SCROLLWIN_TOP - wxEVT_SCROLL_TOP;
         const int orient = range == win->m_scrollBar[0] ? wxHORIZONTAL : wxVERTICAL;
+        const int i = orient == wxVERTICAL;
         wxScrollWinEvent event(eventType, win->GetScrollPos(orient), orient);
         event.SetEventObject(win);
+        win->m_blockValueChanged[i] = true;
         win->GetEventHandler()->ProcessEvent(event);
+        win->m_blockValueChanged[i] = false;
     }
 }
 }
@@ -2153,7 +2156,9 @@ gtk_scrollbar_button_release_event(GtkRange* range, GdkEventButton*, wxWindow* w
         const int orient = range == win->m_scrollBar[0] ? wxHORIZONTAL : wxVERTICAL;
         wxScrollWinEvent event(wxEVT_SCROLLWIN_THUMBRELEASE, win->GetScrollPos(orient), orient);
         event.SetEventObject(win);
-        win->GetEventHandler()->ProcessEvent(event);
+        // To allow setting scroll position from event handler, sending event must
+        // be deferred until after the GtkRange handler for this signal has run
+        win->GetEventHandler()->AddPendingEvent(event);
     }
 
     return false;
@@ -2462,6 +2467,8 @@ void wxWindowGTK::Init()
     m_scrollBar[1] = NULL;
     m_scrollPos[0] =
     m_scrollPos[1] = 0;
+    m_blockValueChanged[0] =
+    m_blockValueChanged[1] = false;
 
     m_oldClientWidth =
     m_oldClientHeight = 0;
@@ -4085,18 +4092,18 @@ void wxWindowGTK::SetScrollbar( int orient, int pos, int thumbVisible,
         thumbVisible = 1;
     }
 
+    if (pos > range - thumbVisible)
+        pos = range - thumbVisible;
+    if (pos < 0)
+        pos = 0;
     const int i = orient == wxVERTICAL;
     GtkAdjustment* adj = m_scrollBar[i]->adjustment;
-    adj->value = pos;
     adj->step_increment = 1;
     adj->page_increment =
     adj->page_size = thumbVisible;
-
-    BlockScrollEvent();
-    // automatically clamps value to [0,range-page_size], and emits change events
-    gtk_range_set_range(m_scrollBar[i], 0, range);
-    UnblockScrollEvent();
-    m_scrollPos[i] = adj->value;
+    adj->upper = range;
+    SetScrollPos(orient, pos);
+    gtk_adjustment_changed(adj);
 }
 
 void wxWindowGTK::SetScrollPos( int orient, int pos, bool WXUNUSED(refresh) )
@@ -4109,10 +4116,19 @@ void wxWindowGTK::SetScrollPos( int orient, int pos, bool WXUNUSED(refresh) )
     if (GetScrollPos(orient) != pos)
     {
         const int i = orient == wxVERTICAL;
-        BlockScrollEvent();
-        gtk_range_set_value(m_scrollBar[i], pos);
-        UnblockScrollEvent();
-        m_scrollPos[i] = m_scrollBar[i]->adjustment->value;
+        GtkAdjustment* adj = m_scrollBar[i]->adjustment;
+        const int max = int(adj->upper - adj->page_size);
+        if (pos > max)
+            pos = max;
+        if (pos < 0)
+            pos = 0;
+        m_scrollPos[i] =
+        adj->value = pos;
+        // If a "value_changed" signal emission is not already in progress
+        if (!m_blockValueChanged[i])
+        {
+            gtk_adjustment_value_changed(adj);
+        }
     }
 }
 
@@ -4169,7 +4185,7 @@ wxEventType wxWindowGTK::GetScrollEventType(GtkRange* range)
     // update current position
     m_scrollPos[barIndex] = adj->value;
     // If event should be ignored, or integral position has not changed
-    if (!m_hasVMT || g_blockEventsOnDrag || m_blockScrollEvent || value == int(oldPos + 0.5))
+    if (!m_hasVMT || g_blockEventsOnDrag || value == int(oldPos + 0.5))
     {
         return wxEVT_NULL;
     }