X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/940f5ae85da605ce4f5c0e95b881903947a2e702..16487a6fde0a205051f4a8a573ef5da2158f4d83:/src/gtk/scrolwin.cpp?ds=sidebyside diff --git a/src/gtk/scrolwin.cpp b/src/gtk/scrolwin.cpp index b0bf3aa768..7519c5c589 100644 --- a/src/gtk/scrolwin.cpp +++ b/src/gtk/scrolwin.cpp @@ -50,8 +50,10 @@ void wxScrollHelperNative::SetScrollbars(int pixelsPerUnitX, int pixelsPerUnitY, m_xScrollPixelsPerLine = pixelsPerUnitX; m_yScrollPixelsPerLine = pixelsPerUnitY; - m_win->m_hAdjust->value = m_xScrollPosition = xPos; - m_win->m_vAdjust->value = m_yScrollPosition = yPos; + m_win->m_scrollBar[wxWindow::ScrollDir_Horz]->adjustment->value = + m_xScrollPosition = xPos; + m_win->m_scrollBar[wxWindow::ScrollDir_Vert]->adjustment->value = + m_yScrollPosition = yPos; // Setting hints here should arguably be deprecated, but without it // a sizer might override this manual scrollbar setting in old code. @@ -62,6 +64,14 @@ void wxScrollHelperNative::SetScrollbars(int pixelsPerUnitX, int pixelsPerUnitY, m_targetWindow->SetVirtualSize( w ? w : wxDefaultCoord, h ? h : wxDefaultCoord); + // If the target is not the same as the window with the scrollbars, + // then we need to update the scrollbars here, since they won't have + // been updated by SetVirtualSize(). + if (m_targetWindow != m_win) + { + AdjustScrollbars(); + } + if (!noRefresh) { int new_x = m_xScrollPixelsPerLine * m_xScrollPosition; @@ -69,11 +79,9 @@ void wxScrollHelperNative::SetScrollbars(int pixelsPerUnitX, int pixelsPerUnitY, m_targetWindow->ScrollWindow( old_x - new_x, old_y - new_y ); } - - m_targetWindow->m_hasScrolling = pixelsPerUnitX || pixelsPerUnitY; } -void wxScrollHelperNative::DoAdjustScrollbar(GtkAdjustment *adj, +void wxScrollHelperNative::DoAdjustScrollbar(GtkRange* range, int pixelsPerLine, int winSize, int virtSize, @@ -81,84 +89,82 @@ void wxScrollHelperNative::DoAdjustScrollbar(GtkAdjustment *adj, int *lines, int *linesPerPage) { - if ( pixelsPerLine == 0 || winSize >= virtSize) + int upper; + int page_size; + if (pixelsPerLine > 0 && winSize > 0 && winSize < virtSize) { - if ( !wxIsNullDouble(adj->value) ) - { - adj->value = 0.0; - g_signal_emit_by_name (adj, "value_changed"); - } - - adj->upper = 1.0; - adj->page_increment = 1.0; - adj->page_size = 1.0; + upper = (virtSize + pixelsPerLine - 1) / pixelsPerLine; + page_size = winSize / pixelsPerLine; + *lines = upper; + *linesPerPage = page_size; } - else // we do have scrollbar + else { - // round because we need to show all the items - adj->upper = (virtSize + pixelsPerLine - 1) / pixelsPerLine; - - // truncate here as we want to show visible lines entirely - adj->page_size = - adj->page_increment = winSize / pixelsPerLine; - - // If the scrollbar hits the right side, move the window - // right to keep it from over extending. - if ( !wxIsNullDouble(adj->value) && - (adj->value + adj->page_size > adj->upper) ) - { - adj->value = adj->upper - adj->page_size; - if (adj->value < 0.0) - adj->value = 0.0; - - g_signal_emit_by_name (adj, "value_changed"); - } + // GtkRange won't allow upper == lower, so for disabled state use [0,1] + // with a page size of 1. This will also clamp position to 0. + upper = 1; + page_size = 1; + *lines = 0; + *linesPerPage = 0; } - *lines = (int)(adj->upper + 0.5); - *linesPerPage = (int)(adj->page_increment + 0.5); - g_signal_emit_by_name (adj, "changed"); + GtkAdjustment* adj = range->adjustment; + adj->step_increment = 1; + adj->page_increment = + adj->page_size = page_size; + gtk_range_set_range(range, 0, upper); + + // ensure that the scroll position is always in valid range + if (*pos > *lines) + *pos = *lines; } void wxScrollHelperNative::AdjustScrollbars() { - int w, h; int vw, vh; - - m_targetWindow->GetClientSize( &w, &h ); m_targetWindow->GetVirtualSize( &vw, &vh ); - DoAdjustScrollbar(m_win->m_hAdjust, m_xScrollPixelsPerLine, w, vw, - &m_xScrollPosition, &m_xScrollLines, &m_xScrollLinesPerPage); - DoAdjustScrollbar(m_win->m_vAdjust, m_yScrollPixelsPerLine, h, vh, - &m_yScrollPosition, &m_yScrollLines, &m_yScrollLinesPerPage); + int w; + m_targetWindow->GetClientSize(&w, NULL); + DoAdjustHScrollbar(w, vw); + + int h; + m_targetWindow->GetClientSize(NULL, &h); + DoAdjustVScrollbar(h, vh); + + const int w_old = w; + m_targetWindow->GetClientSize(&w, NULL); + if ( w != w_old ) + { + // It is necessary to repeat the calculations in this case to avoid an + // observed infinite series of size events, involving alternating + // changes in visibility of the scrollbars. + // At this point, GTK+ has already queued a resize, which will cause + // AdjustScrollbars() to be called again. If the scrollbar visibility + // is not correct before then, yet another resize will occur, possibly + // leading to an unending series if the sizes are just right. + DoAdjustHScrollbar(w, vw); + + m_targetWindow->GetClientSize(NULL, &h); + DoAdjustVScrollbar(h, vh); + } } void wxScrollHelperNative::DoScroll(int orient, - GtkAdjustment *adj, int pos, int pixelsPerLine, int *posOld) { if ( pos != -1 && pos != *posOld && pixelsPerLine ) { - int max = (int)(adj->upper - adj->page_size + 0.5); - if (max < 0) - max = 0; - if (pos > max) - pos = max; - if (pos < 0) - pos = 0; - - adj->value = pos; + m_win->SetScrollPos(orient, pos); + pos = m_win->GetScrollPos(orient); int diff = (*posOld - pos)*pixelsPerLine; m_targetWindow->ScrollWindow(orient == wxHORIZONTAL ? diff : 0, orient == wxHORIZONTAL ? 0 : diff); *posOld = pos; - - m_win->GtkUpdateScrollbar(orient); } } @@ -166,9 +172,6 @@ void wxScrollHelperNative::Scroll( int x_pos, int y_pos ) { wxCHECK_RET( m_targetWindow != 0, _T("No target window") ); - DoScroll(wxHORIZONTAL, m_win->m_hAdjust, x_pos, m_xScrollPixelsPerLine, - &m_xScrollPosition); - DoScroll(wxVERTICAL, m_win->m_vAdjust, y_pos, m_yScrollPixelsPerLine, - &m_yScrollPosition); + DoScroll(wxHORIZONTAL, x_pos, m_xScrollPixelsPerLine, &m_xScrollPosition); + DoScroll(wxVERTICAL, y_pos, m_yScrollPixelsPerLine, &m_yScrollPosition); } -