Files
wxWidgets/src/gtk/scrolwin.cpp
Robert Roebling bf6c0db624 Fix scrolling bug where client size was reported wrong
when the scrollbar size was not subtracted when
    using a targetwindow != this.


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@41291 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
2006-09-19 10:22:20 +00:00

181 lines
6.5 KiB
C++

/////////////////////////////////////////////////////////////////////////////
// Name: gtk/scrolwin.cpp
// Purpose: wxScrolledWindow implementation
// Author: Robert Roebling
// Modified by: Ron Lee
// Vadim Zeitlin: removed 90% of duplicated common code
// Created: 01/02/97
// RCS-ID: $Id$
// Copyright: (c) Robert Roebling
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// ============================================================================
// declarations
// ============================================================================
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#include "wx/scrolwin.h"
#include "wx/gtk/private.h"
// ============================================================================
// implementation
// ============================================================================
// ----------------------------------------------------------------------------
// wxScrollHelper implementation
// ----------------------------------------------------------------------------
void wxScrollHelperNative::SetScrollbars(int pixelsPerUnitX, int pixelsPerUnitY,
int noUnitsX, int noUnitsY,
int xPos, int yPos,
bool noRefresh)
{
int xs, ys;
GetViewStart(& xs, & ys);
int old_x = m_xScrollPixelsPerLine * xs;
int old_y = m_yScrollPixelsPerLine * ys;
m_xScrollPixelsPerLine = pixelsPerUnitX;
m_yScrollPixelsPerLine = pixelsPerUnitY;
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.
// m_targetWindow->SetVirtualSizeHints( noUnitsX * pixelsPerUnitX, noUnitsY * pixelsPerUnitY );
int w = noUnitsX * pixelsPerUnitX;
int h = noUnitsY * 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;
int new_y = m_yScrollPixelsPerLine * m_yScrollPosition;
m_targetWindow->ScrollWindow( old_x - new_x, old_y - new_y );
}
}
void wxScrollHelperNative::DoAdjustScrollbar(GtkRange* range,
int pixelsPerLine,
int winSize,
int virtSize,
int *lines,
int *linesPerPage)
{
int upper;
int page_size;
if (pixelsPerLine > 0 && winSize > 0 && winSize < virtSize)
{
upper = (virtSize + pixelsPerLine - 1) / pixelsPerLine;
page_size = winSize / pixelsPerLine;
*lines = upper;
*linesPerPage = page_size;
}
else
{
// 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;
}
GtkAdjustment* adj = range->adjustment;
adj->step_increment = 1;
adj->page_increment =
adj->page_size = page_size;
gtk_range_set_range(range, 0, upper);
}
void wxScrollHelperNative::AdjustScrollbars()
{
int w, h;
int vw, vh;
// this flag indicates which window has the scrollbars
m_win->m_hasScrolling = m_xScrollPixelsPerLine != 0 || m_yScrollPixelsPerLine != 0;
m_targetWindow->GetVirtualSize( &vw, &vh );
m_targetWindow->GetClientSize(&w, NULL);
DoAdjustScrollbar(
m_win->m_scrollBar[wxWindow::ScrollDir_Horz], m_xScrollPixelsPerLine,
w, vw, &m_xScrollLines, &m_xScrollLinesPerPage);
m_targetWindow->GetClientSize(NULL, &h);
DoAdjustScrollbar(
m_win->m_scrollBar[wxWindow::ScrollDir_Vert], m_yScrollPixelsPerLine,
h, vh, &m_yScrollLines, &m_yScrollLinesPerPage);
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.
DoAdjustScrollbar(
m_win->m_scrollBar[wxWindow::ScrollDir_Horz], m_xScrollPixelsPerLine,
w, vw, &m_xScrollLines, &m_xScrollLinesPerPage);
m_targetWindow->GetClientSize(NULL, &h);
DoAdjustScrollbar(
m_win->m_scrollBar[wxWindow::ScrollDir_Vert], m_yScrollPixelsPerLine,
h, vh, &m_yScrollLines, &m_yScrollLinesPerPage);
}
}
void wxScrollHelperNative::DoScroll(int orient,
int pos,
int pixelsPerLine,
int *posOld)
{
if ( pos != -1 && pos != *posOld && pixelsPerLine )
{
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;
}
}
void wxScrollHelperNative::Scroll( int x_pos, int y_pos )
{
wxCHECK_RET( m_targetWindow != 0, _T("No target window") );
DoScroll(wxHORIZONTAL, x_pos, m_xScrollPixelsPerLine, &m_xScrollPosition);
DoScroll(wxVERTICAL, y_pos, m_yScrollPixelsPerLine, &m_yScrollPosition);
}