don't generate a scroll event when setting scroll position from scroll event handler
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
This commit is contained in:
@@ -215,6 +215,7 @@ public:
|
|||||||
GtkRange* m_scrollBar[2];
|
GtkRange* m_scrollBar[2];
|
||||||
// horizontal/vertical scroll position
|
// horizontal/vertical scroll position
|
||||||
double m_scrollPos[2];
|
double m_scrollPos[2];
|
||||||
|
bool m_blockValueChanged[2];
|
||||||
|
|
||||||
// extra (wxGTK-specific) flags
|
// extra (wxGTK-specific) flags
|
||||||
bool m_needParent:1; // ! wxFrame, wxDialog, wxNotebookPage ?
|
bool m_needParent:1; // ! wxFrame, wxDialog, wxNotebookPage ?
|
||||||
|
@@ -32,9 +32,11 @@ gtk_value_changed(GtkRange* range, wxScrollBar* win)
|
|||||||
if (eventType != wxEVT_NULL)
|
if (eventType != wxEVT_NULL)
|
||||||
{
|
{
|
||||||
const int orient = win->HasFlag(wxSB_VERTICAL) ? wxVERTICAL : wxHORIZONTAL;
|
const int orient = win->HasFlag(wxSB_VERTICAL) ? wxVERTICAL : wxHORIZONTAL;
|
||||||
|
const int i = orient == wxVERTICAL;
|
||||||
const int value = win->GetThumbPosition();
|
const int value = win->GetThumbPosition();
|
||||||
wxScrollEvent event(eventType, win->GetId(), value, orient);
|
wxScrollEvent event(eventType, win->GetId(), value, orient);
|
||||||
event.SetEventObject(win);
|
event.SetEventObject(win);
|
||||||
|
win->m_blockValueChanged[i] = true;
|
||||||
win->GetEventHandler()->ProcessEvent(event);
|
win->GetEventHandler()->ProcessEvent(event);
|
||||||
if (!win->m_isScrolling)
|
if (!win->m_isScrolling)
|
||||||
{
|
{
|
||||||
@@ -42,6 +44,7 @@ gtk_value_changed(GtkRange* range, wxScrollBar* win)
|
|||||||
event.SetEventObject(win);
|
event.SetEventObject(win);
|
||||||
win->GetEventHandler()->ProcessEvent(event);
|
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);
|
wxScrollEvent event(wxEVT_SCROLL_THUMBRELEASE, win->GetId(), value, orient);
|
||||||
event.SetEventObject(win);
|
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);
|
wxScrollEvent event2(wxEVT_SCROLL_CHANGED, win->GetId(), value, orient);
|
||||||
event2.SetEventObject(win);
|
event2.SetEventObject(win);
|
||||||
win->GetEventHandler()->ProcessEvent(event2);
|
win->GetEventHandler()->AddPendingEvent(event2);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -171,12 +176,21 @@ void wxScrollBar::SetThumbPosition( int viewStart )
|
|||||||
{
|
{
|
||||||
if (GetThumbPosition() != viewStart)
|
if (GetThumbPosition() != viewStart)
|
||||||
{
|
{
|
||||||
BlockScrollEvent();
|
|
||||||
gtk_range_set_value((GtkRange*)m_widget, viewStart);
|
|
||||||
UnblockScrollEvent();
|
|
||||||
GtkAdjustment* adj = ((GtkRange*)m_widget)->adjustment;
|
GtkAdjustment* adj = ((GtkRange*)m_widget)->adjustment;
|
||||||
const int i = HasFlag(wxSB_VERTICAL);
|
const int i = (GtkRange*)m_widget == m_scrollBar[1];
|
||||||
m_scrollPos[i] = adj->value;
|
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 =
|
range =
|
||||||
thumbSize = 1;
|
thumbSize = 1;
|
||||||
}
|
}
|
||||||
|
if (position > range - thumbSize)
|
||||||
|
position = range - thumbSize;
|
||||||
|
if (position < 0)
|
||||||
|
position = 0;
|
||||||
GtkAdjustment* adj = ((GtkRange*)m_widget)->adjustment;
|
GtkAdjustment* adj = ((GtkRange*)m_widget)->adjustment;
|
||||||
adj->value = position;
|
|
||||||
adj->step_increment = 1;
|
adj->step_increment = 1;
|
||||||
adj->page_increment = pageSize;
|
adj->page_increment = pageSize;
|
||||||
adj->page_size = thumbSize;
|
adj->page_size = thumbSize;
|
||||||
BlockScrollEvent();
|
adj->upper = range;
|
||||||
gtk_range_set_range((GtkRange*)m_widget, 0, range);
|
SetThumbPosition(position);
|
||||||
UnblockScrollEvent();
|
gtk_adjustment_changed(adj);
|
||||||
const int i = HasFlag(wxSB_VERTICAL);
|
|
||||||
m_scrollPos[i] = adj->value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxScrollBar::SetPageSize( int pageLength )
|
void wxScrollBar::SetPageSize( int pageLength )
|
||||||
|
@@ -2107,9 +2107,12 @@ gtk_scrollbar_value_changed(GtkRange* range, wxWindow* win)
|
|||||||
// Convert scroll event type to scrollwin event type
|
// Convert scroll event type to scrollwin event type
|
||||||
eventType += wxEVT_SCROLLWIN_TOP - wxEVT_SCROLL_TOP;
|
eventType += wxEVT_SCROLLWIN_TOP - wxEVT_SCROLL_TOP;
|
||||||
const int orient = range == win->m_scrollBar[0] ? wxHORIZONTAL : wxVERTICAL;
|
const int orient = range == win->m_scrollBar[0] ? wxHORIZONTAL : wxVERTICAL;
|
||||||
|
const int i = orient == wxVERTICAL;
|
||||||
wxScrollWinEvent event(eventType, win->GetScrollPos(orient), orient);
|
wxScrollWinEvent event(eventType, win->GetScrollPos(orient), orient);
|
||||||
event.SetEventObject(win);
|
event.SetEventObject(win);
|
||||||
|
win->m_blockValueChanged[i] = true;
|
||||||
win->GetEventHandler()->ProcessEvent(event);
|
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;
|
const int orient = range == win->m_scrollBar[0] ? wxHORIZONTAL : wxVERTICAL;
|
||||||
wxScrollWinEvent event(wxEVT_SCROLLWIN_THUMBRELEASE, win->GetScrollPos(orient), orient);
|
wxScrollWinEvent event(wxEVT_SCROLLWIN_THUMBRELEASE, win->GetScrollPos(orient), orient);
|
||||||
event.SetEventObject(win);
|
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;
|
return false;
|
||||||
@@ -2462,6 +2467,8 @@ void wxWindowGTK::Init()
|
|||||||
m_scrollBar[1] = NULL;
|
m_scrollBar[1] = NULL;
|
||||||
m_scrollPos[0] =
|
m_scrollPos[0] =
|
||||||
m_scrollPos[1] = 0;
|
m_scrollPos[1] = 0;
|
||||||
|
m_blockValueChanged[0] =
|
||||||
|
m_blockValueChanged[1] = false;
|
||||||
|
|
||||||
m_oldClientWidth =
|
m_oldClientWidth =
|
||||||
m_oldClientHeight = 0;
|
m_oldClientHeight = 0;
|
||||||
@@ -4085,18 +4092,18 @@ void wxWindowGTK::SetScrollbar( int orient, int pos, int thumbVisible,
|
|||||||
thumbVisible = 1;
|
thumbVisible = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pos > range - thumbVisible)
|
||||||
|
pos = range - thumbVisible;
|
||||||
|
if (pos < 0)
|
||||||
|
pos = 0;
|
||||||
const int i = orient == wxVERTICAL;
|
const int i = orient == wxVERTICAL;
|
||||||
GtkAdjustment* adj = m_scrollBar[i]->adjustment;
|
GtkAdjustment* adj = m_scrollBar[i]->adjustment;
|
||||||
adj->value = pos;
|
|
||||||
adj->step_increment = 1;
|
adj->step_increment = 1;
|
||||||
adj->page_increment =
|
adj->page_increment =
|
||||||
adj->page_size = thumbVisible;
|
adj->page_size = thumbVisible;
|
||||||
|
adj->upper = range;
|
||||||
BlockScrollEvent();
|
SetScrollPos(orient, pos);
|
||||||
// automatically clamps value to [0,range-page_size], and emits change events
|
gtk_adjustment_changed(adj);
|
||||||
gtk_range_set_range(m_scrollBar[i], 0, range);
|
|
||||||
UnblockScrollEvent();
|
|
||||||
m_scrollPos[i] = adj->value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxWindowGTK::SetScrollPos( int orient, int pos, bool WXUNUSED(refresh) )
|
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)
|
if (GetScrollPos(orient) != pos)
|
||||||
{
|
{
|
||||||
const int i = orient == wxVERTICAL;
|
const int i = orient == wxVERTICAL;
|
||||||
BlockScrollEvent();
|
GtkAdjustment* adj = m_scrollBar[i]->adjustment;
|
||||||
gtk_range_set_value(m_scrollBar[i], pos);
|
const int max = int(adj->upper - adj->page_size);
|
||||||
UnblockScrollEvent();
|
if (pos > max)
|
||||||
m_scrollPos[i] = m_scrollBar[i]->adjustment->value;
|
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
|
// update current position
|
||||||
m_scrollPos[barIndex] = adj->value;
|
m_scrollPos[barIndex] = adj->value;
|
||||||
// If event should be ignored, or integral position has not changed
|
// 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;
|
return wxEVT_NULL;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user