tons of changes:

1. wxListBox class added
2. wxInputHandler rewritten (Map() -> Handle())
3. wxScrollBar redrawing completely changed


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/wxUNIVERSAL@8228 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2000-09-01 12:58:36 +00:00
parent 06be91840a
commit 5096d88d2f
32 changed files with 2682 additions and 1388 deletions

View File

@@ -2,10 +2,11 @@
// Name: generic/scrolwin.cpp
// Purpose: wxScrolledWindow implementation
// Author: Julian Smart
// Modified by:
// Modified by: Vadim Zeitlin on 31.08.00: wxScrollHelper allows to implement
// scrolling in any class, not just wxScrolledWindow
// Created: 01/02/97
// RCS-ID: $Id$
// Copyright: (c) Julian Smart and Markus Holzem
// Copyright: (c) wxWindows team
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
@@ -51,90 +52,119 @@
#endif
// ----------------------------------------------------------------------------
// event tables
// wxScrollHelperEvtHandler: intercept the events from the window and forward
// them to wxScrollHelper
// ----------------------------------------------------------------------------
BEGIN_EVENT_TABLE(wxScrolledWindow, wxPanel)
EVT_SCROLLWIN(wxScrolledWindow::OnScroll)
EVT_SIZE(wxScrolledWindow::OnSize)
EVT_PAINT(wxScrolledWindow::OnPaint)
EVT_CHAR(wxScrolledWindow::OnChar)
END_EVENT_TABLE()
class wxScrollHelperEvtHandler : public wxEvtHandler
{
public:
wxScrollHelperEvtHandler(wxScrollHelper *scrollHelper)
{
m_scrollHelper = scrollHelper;
}
IMPLEMENT_DYNAMIC_CLASS(wxScrolledWindow, wxPanel)
virtual bool ProcessEvent(wxEvent& event)
{
if ( wxEvtHandler::ProcessEvent(event) )
return TRUE;
switch ( event.GetEventType() )
{
case wxEVT_SCROLLWIN_TOP:
case wxEVT_SCROLLWIN_BOTTOM:
case wxEVT_SCROLLWIN_LINEUP:
case wxEVT_SCROLLWIN_LINEDOWN:
case wxEVT_SCROLLWIN_PAGEUP:
case wxEVT_SCROLLWIN_PAGEDOWN:
case wxEVT_SCROLLWIN_THUMBTRACK:
case wxEVT_SCROLLWIN_THUMBRELEASE:
m_scrollHelper->HandleOnScroll((wxScrollWinEvent&)event);
break;
case wxEVT_PAINT:
m_scrollHelper->HandleOnPaint((wxPaintEvent&)event);
break;
case wxEVT_SIZE:
m_scrollHelper->HandleOnSize((wxSizeEvent&)event);
break;
case wxEVT_CHAR:
m_scrollHelper->HandleOnChar((wxKeyEvent&)event);
break;
default:
return FALSE;
}
return TRUE;
}
private:
wxScrollHelper *m_scrollHelper;
};
// ============================================================================
// implementation
// ============================================================================
// ----------------------------------------------------------------------------
// wxScrolledWindow creation
// wxScrollHelper construction
// ----------------------------------------------------------------------------
wxScrolledWindow::wxScrolledWindow()
wxScrollHelper::wxScrollHelper(wxWindow *win)
{
m_xScrollPixelsPerLine = 0;
m_yScrollPixelsPerLine = 0;
m_xScrollingEnabled = TRUE;
m_yScrollingEnabled = TRUE;
m_xScrollPosition = 0;
m_yScrollPosition = 0;
m_xScrollLines = 0;
m_yScrollLines = 0;
m_xScrollLinesPerPage = 0;
m_xScrollPixelsPerLine =
m_yScrollPixelsPerLine =
m_xScrollPosition =
m_yScrollPosition =
m_xScrollLines =
m_yScrollLines =
m_xScrollLinesPerPage =
m_yScrollLinesPerPage = 0;
m_scaleX = 1.0;
m_scaleY = 1.0;
m_targetWindow = (wxWindow*) NULL;
}
bool wxScrolledWindow::Create(wxWindow *parent,
wxWindowID id,
const wxPoint& pos,
const wxSize& size,
long style,
const wxString& name)
{
m_xScrollPixelsPerLine = 0;
m_yScrollPixelsPerLine = 0;
m_xScrollingEnabled = TRUE;
m_xScrollingEnabled =
m_yScrollingEnabled = TRUE;
m_xScrollPosition = 0;
m_yScrollPosition = 0;
m_xScrollLines = 0;
m_yScrollLines = 0;
m_xScrollLinesPerPage = 0;
m_yScrollLinesPerPage = 0;
m_scaleX = 1.0;
m_scaleX =
m_scaleY = 1.0;
m_targetWindow = this;
m_win =
m_targetWindow = (wxWindow *)NULL;
bool ok = wxPanel::Create(parent, id, pos, size, style, name);
#ifdef __WXMSW__
// we need to process arrows ourselves for scrolling
m_lDlgCode |= DLGC_WANTARROWS;
#endif // __WXMSW__
return ok;
if ( win )
SetWindow(win);
}
wxScrolledWindow::~wxScrolledWindow()
void wxScrollHelper::SetWindow(wxWindow *win)
{
wxCHECK_RET( win, _T("wxScrollHelper needs a window to scroll") );
m_targetWindow = m_win = win;
// install the event handler which will intercept the events we're
// interested in
m_win->PushEventHandler(new wxScrollHelperEvtHandler(this));
}
wxScrollHelper::~wxScrollHelper()
{
if ( m_targetWindow )
m_targetWindow->PopEventHandler(TRUE /* do delete it */);
}
// ----------------------------------------------------------------------------
// setting scrolling parameters
// ----------------------------------------------------------------------------
/*
* pixelsPerUnitX/pixelsPerUnitY: number of pixels per unit (e.g. pixels per text line)
* noUnitsX/noUnitsY: : no. units per scrollbar
*/
void wxScrolledWindow::SetScrollbars (int pixelsPerUnitX, int pixelsPerUnitY,
int noUnitsX, int noUnitsY,
int xPos, int yPos, bool noRefresh )
void wxScrollHelper::SetScrollbars(int pixelsPerUnitX,
int pixelsPerUnitY,
int noUnitsX,
int noUnitsY,
int xPos,
int yPos,
bool noRefresh)
{
int xpos, ypos;
@@ -142,14 +172,12 @@ void wxScrolledWindow::SetScrollbars (int pixelsPerUnitX, int pixelsPerUnitY,
bool do_refresh =
(
(noUnitsX != 0 && m_xScrollLines == 0) ||
(noUnitsX < m_xScrollLines && xpos > pixelsPerUnitX*noUnitsX) ||
(noUnitsX < m_xScrollLines && xpos > pixelsPerUnitX*noUnitsX) ||
(noUnitsY != 0 && m_yScrollLines == 0) ||
(noUnitsY < m_yScrollLines && ypos > pixelsPerUnitY*noUnitsY) ||
(xPos != m_xScrollPosition) ||
(yPos != m_yScrollPosition)
// (pixelsPerUnitX != m_xScrollPixelsPerLine) ||
// (pixelsPerUnitY != m_yScrollPixelsPerLine)
);
m_xScrollPixelsPerLine = pixelsPerUnitX;
@@ -165,21 +193,21 @@ void wxScrolledWindow::SetScrollbars (int pixelsPerUnitX, int pixelsPerUnitY,
// be entirely generic because it relies on the wxWindowDC implementation
// to duplicate X drawing calls for the backing pixmap.
if ((m_windowStyle & wxRETAINED) == wxRETAINED)
if ( m_targetWindow->GetWindowStyle() & wxRETAINED )
{
Display* dpy = XtDisplay((Widget) GetMainWidget());
Display* dpy = XtDisplay((Widget)m_targetWindow->GetMainWidget());
int totalPixelWidth = m_xScrollLines * m_xScrollPixelsPerLine;
int totalPixelHeight = m_yScrollLines * m_yScrollPixelsPerLine;
if (m_backingPixmap &&
!((m_pixmapWidth == totalPixelWidth) &&
(m_pixmapHeight == totalPixelHeight)))
if (m_targetWindow->m_backingPixmap &&
!((m_targetWindow->m_pixmapWidth == totalPixelWidth) &&
(m_targetWindow->m_pixmapHeight == totalPixelHeight)))
{
XFreePixmap (dpy, (Pixmap) m_backingPixmap);
m_backingPixmap = (WXPixmap) 0;
XFreePixmap (dpy, (Pixmap) m_targetWindow->m_backingPixmap);
m_targetWindow->m_backingPixmap = (WXPixmap) 0;
}
if (!m_backingPixmap &&
if (!m_targetWindow->m_backingPixmap &&
(noUnitsX != 0) && (noUnitsY != 0))
{
int depth = wxDisplayDepth();
@@ -197,16 +225,6 @@ void wxScrolledWindow::SetScrollbars (int pixelsPerUnitX, int pixelsPerUnitY,
if (do_refresh && !noRefresh)
m_targetWindow->Refresh();
#ifdef __WXMSW__
// GRG: if this turns out to be really necessary, we could
// at least move it to the above if { ... } so that it is
// only done if noRefresh = FALSE (the default). OTOH, if
// this doesn't break anything, which seems to be the
// case, we could just leave it out.
// Necessary?
// UpdateWindow ((HWND) m_targetWindow->GetHWND());
#endif
#ifdef __WXMAC__
m_targetWindow->MacUpdateImmediately() ;
#endif
@@ -216,13 +234,13 @@ void wxScrolledWindow::SetScrollbars (int pixelsPerUnitX, int pixelsPerUnitY,
// target window handling
// ----------------------------------------------------------------------------
void wxScrolledWindow::SetTargetWindow( wxWindow *target )
void wxScrollHelper::SetTargetWindow( wxWindow *target )
{
wxASSERT_MSG( target, wxT("target window must not be NULL") );
m_targetWindow = target;
}
wxWindow *wxScrolledWindow::GetTargetWindow()
wxWindow *wxScrollHelper::GetTargetWindow() const
{
return m_targetWindow;
}
@@ -231,7 +249,7 @@ wxWindow *wxScrolledWindow::GetTargetWindow()
// scrolling implementation itself
// ----------------------------------------------------------------------------
void wxScrolledWindow::OnScroll(wxScrollWinEvent& event)
void wxScrollHelper::HandleOnScroll(wxScrollWinEvent& event)
{
int orient = event.GetOrientation();
@@ -241,12 +259,12 @@ void wxScrolledWindow::OnScroll(wxScrollWinEvent& event)
if (orient == wxHORIZONTAL)
{
int newPos = m_xScrollPosition + nScrollInc;
SetScrollPos(wxHORIZONTAL, newPos, FALSE );
m_win->SetScrollPos(wxHORIZONTAL, newPos, FALSE );
}
else
{
int newPos = m_yScrollPosition + nScrollInc;
SetScrollPos(wxVERTICAL, newPos, FALSE );
m_win->SetScrollPos(wxVERTICAL, newPos, FALSE );
}
if (orient == wxHORIZONTAL)
@@ -277,7 +295,7 @@ void wxScrolledWindow::OnScroll(wxScrollWinEvent& event)
#endif
}
int wxScrolledWindow::CalcScrollInc(wxScrollWinEvent& event)
int wxScrollHelper::CalcScrollInc(wxScrollWinEvent& event)
{
int pos = event.GetPosition();
int orient = event.GetOrientation();
@@ -387,7 +405,7 @@ int wxScrolledWindow::CalcScrollInc(wxScrollWinEvent& event)
}
// Adjust the scrollbars - new version.
void wxScrolledWindow::AdjustScrollbars()
void wxScrollHelper::AdjustScrollbars()
{
int w, h;
m_targetWindow->GetClientSize(&w, &h);
@@ -407,14 +425,14 @@ void wxScrolledWindow::AdjustScrollbars()
m_xScrollPosition = wxMin( m_xScrollLines-noPagePositions, m_xScrollPosition);
m_xScrollPosition = wxMax( 0, m_xScrollPosition );
SetScrollbar(wxHORIZONTAL, m_xScrollPosition, noPagePositions, m_xScrollLines);
m_win->SetScrollbar(wxHORIZONTAL, m_xScrollPosition, noPagePositions, m_xScrollLines);
// The amount by which we scroll when paging
SetScrollPageSize(wxHORIZONTAL, noPagePositions);
}
else
{
m_xScrollPosition = 0;
SetScrollbar (wxHORIZONTAL, 0, 0, 0, FALSE);
m_win->SetScrollbar (wxHORIZONTAL, 0, 0, 0, FALSE);
}
if (m_yScrollLines > 0)
@@ -429,14 +447,14 @@ void wxScrolledWindow::AdjustScrollbars()
m_yScrollPosition = wxMin( m_yScrollLines-noPagePositions, m_yScrollPosition );
m_yScrollPosition = wxMax( 0, m_yScrollPosition );
SetScrollbar(wxVERTICAL, m_yScrollPosition, noPagePositions, m_yScrollLines);
m_win->SetScrollbar(wxVERTICAL, m_yScrollPosition, noPagePositions, m_yScrollLines);
// The amount by which we scroll when paging
SetScrollPageSize(wxVERTICAL, noPagePositions);
}
else
{
m_yScrollPosition = 0;
SetScrollbar (wxVERTICAL, 0, 0, 0, FALSE);
m_win->SetScrollbar (wxVERTICAL, 0, 0, 0, FALSE);
}
if (oldXScroll != m_xScrollPosition)
@@ -456,9 +474,7 @@ void wxScrolledWindow::AdjustScrollbars()
}
}
// Override this function if you don't want to have wxScrolledWindow
// automatically change the origin according to the scroll position.
void wxScrolledWindow::PrepareDC(wxDC& dc)
void wxScrollHelper::DoPrepareDC(wxDC& dc)
{
dc.SetDeviceOrigin( -m_xScrollPosition * m_xScrollPixelsPerLine,
-m_yScrollPosition * m_yScrollPixelsPerLine );
@@ -467,30 +483,14 @@ void wxScrolledWindow::PrepareDC(wxDC& dc)
// for wxUniversal we need to set the clipping region to avoid overwriting
// the scrollbars with the user drawing
#ifdef __WXUNIVERSAL__
wxSize size = GetClientSize();
wxSize size = m_win->GetClientSize();
dc.SetClippingRegion(m_xScrollPosition * m_xScrollPixelsPerLine,
m_yScrollPosition * m_yScrollPixelsPerLine,
size.x, size.y);
#endif // __WXUNIVERSAL__
}
#if WXWIN_COMPATIBILITY
void wxScrolledWindow::GetScrollUnitsPerPage (int *x_page, int *y_page) const
{
*x_page = GetScrollPageSize(wxHORIZONTAL);
*y_page = GetScrollPageSize(wxVERTICAL);
}
void wxScrolledWindow::CalcUnscrolledPosition(int x, int y, float *xx, float *yy) const
{
if ( xx )
*xx = (float)(x + m_xScrollPosition * m_xScrollPixelsPerLine);
if ( yy )
*yy = (float)(y + m_yScrollPosition * m_yScrollPixelsPerLine);
}
#endif // WXWIN_COMPATIBILITY
void wxScrolledWindow::GetScrollPixelsPerUnit (int *x_unit, int *y_unit) const
void wxScrollHelper::GetScrollPixelsPerUnit (int *x_unit, int *y_unit) const
{
if ( x_unit )
*x_unit = m_xScrollPixelsPerLine;
@@ -498,7 +498,7 @@ void wxScrolledWindow::GetScrollPixelsPerUnit (int *x_unit, int *y_unit) const
*y_unit = m_yScrollPixelsPerLine;
}
int wxScrolledWindow::GetScrollPageSize(int orient) const
int wxScrollHelper::GetScrollPageSize(int orient) const
{
if ( orient == wxHORIZONTAL )
return m_xScrollLinesPerPage;
@@ -506,7 +506,7 @@ int wxScrolledWindow::GetScrollPageSize(int orient) const
return m_yScrollLinesPerPage;
}
void wxScrolledWindow::SetScrollPageSize(int orient, int pageSize)
void wxScrollHelper::SetScrollPageSize(int orient, int pageSize)
{
if ( orient == wxHORIZONTAL )
m_xScrollLinesPerPage = pageSize;
@@ -517,7 +517,7 @@ void wxScrolledWindow::SetScrollPageSize(int orient, int pageSize)
/*
* Scroll to given position (scroll position, not pixel position)
*/
void wxScrolledWindow::Scroll( int x_pos, int y_pos )
void wxScrollHelper::Scroll( int x_pos, int y_pos )
{
if (!m_targetWindow)
return;
@@ -562,7 +562,7 @@ void wxScrolledWindow::Scroll( int x_pos, int y_pos )
// the visible portion of it or if below zero
m_yScrollPosition = wxMin( m_yScrollLines-noPagePositions, m_yScrollPosition );
m_yScrollPosition = wxMax( 0, m_yScrollPosition );
if (old_y != m_yScrollPosition) {
m_targetWindow->SetScrollPos( wxVERTICAL, m_yScrollPosition, TRUE );
m_targetWindow->ScrollWindow( 0, (old_y-m_yScrollPosition)*m_yScrollPixelsPerLine );
@@ -574,13 +574,13 @@ void wxScrolledWindow::Scroll( int x_pos, int y_pos )
#endif
}
void wxScrolledWindow::EnableScrolling (bool x_scroll, bool y_scroll)
void wxScrollHelper::EnableScrolling (bool x_scroll, bool y_scroll)
{
m_xScrollingEnabled = x_scroll;
m_yScrollingEnabled = y_scroll;
}
void wxScrolledWindow::GetVirtualSize (int *x, int *y) const
void wxScrollHelper::GetVirtualSize (int *x, int *y) const
{
if ( x )
*x = m_xScrollPixelsPerLine * m_xScrollLines;
@@ -589,7 +589,7 @@ void wxScrolledWindow::GetVirtualSize (int *x, int *y) const
}
// Where the current view starts from
void wxScrolledWindow::GetViewStart (int *x, int *y) const
void wxScrollHelper::GetViewStart (int *x, int *y) const
{
if ( x )
*x = m_xScrollPosition;
@@ -597,7 +597,7 @@ void wxScrolledWindow::GetViewStart (int *x, int *y) const
*y = m_yScrollPosition;
}
void wxScrolledWindow::CalcScrolledPosition(int x, int y, int *xx, int *yy) const
void wxScrollHelper::CalcScrolledPosition(int x, int y, int *xx, int *yy) const
{
if ( xx )
*xx = x - m_xScrollPosition * m_xScrollPixelsPerLine;
@@ -605,7 +605,7 @@ void wxScrolledWindow::CalcScrolledPosition(int x, int y, int *xx, int *yy) cons
*yy = y - m_yScrollPosition * m_yScrollPixelsPerLine;
}
void wxScrolledWindow::CalcUnscrolledPosition(int x, int y, int *xx, int *yy) const
void wxScrollHelper::CalcUnscrolledPosition(int x, int y, int *xx, int *yy) const
{
if ( xx )
*xx = x + m_xScrollPosition * m_xScrollPixelsPerLine;
@@ -618,11 +618,11 @@ void wxScrolledWindow::CalcUnscrolledPosition(int x, int y, int *xx, int *yy) co
// ----------------------------------------------------------------------------
// Default OnSize resets scrollbars, if any
void wxScrolledWindow::OnSize(wxSizeEvent& WXUNUSED(event))
void wxScrollHelper::HandleOnSize(wxSizeEvent& WXUNUSED(event))
{
#if wxUSE_CONSTRAINTS
if (GetAutoLayout())
Layout();
if ( m_targetWindow->GetAutoLayout() )
m_targetWindow->Layout();
#endif
AdjustScrollbars();
@@ -630,10 +630,10 @@ void wxScrolledWindow::OnSize(wxSizeEvent& WXUNUSED(event))
// This calls OnDraw, having adjusted the origin according to the current
// scroll position
void wxScrolledWindow::OnPaint(wxPaintEvent& WXUNUSED(event))
void wxScrollHelper::HandleOnPaint(wxPaintEvent& WXUNUSED(event))
{
wxPaintDC dc(this);
PrepareDC(dc);
wxPaintDC dc(m_targetWindow);
DoPrepareDC(dc);
OnDraw(dc);
}
@@ -642,14 +642,14 @@ void wxScrolledWindow::OnPaint(wxPaintEvent& WXUNUSED(event))
// compatibility here - if we used OnKeyDown(), the programs which process
// arrows themselves in their OnChar() would never get the message and like
// this they always have the priority
void wxScrolledWindow::OnChar(wxKeyEvent& event)
void wxScrollHelper::HandleOnChar(wxKeyEvent& event)
{
int stx, sty, // view origin
szx, szy, // view size (total)
clix, cliy; // view size (on screen)
ViewStart(&stx, &sty);
GetClientSize(&clix, &cliy);
GetViewStart(&stx, &sty);
m_win->GetClientSize(&clix, &cliy);
GetVirtualSize(&szx, &szy);
if( m_xScrollPixelsPerLine )
@@ -716,3 +716,49 @@ void wxScrolledWindow::OnChar(wxKeyEvent& event)
event.Skip();
}
}
// ----------------------------------------------------------------------------
// wxScrolledWindow implementation
// ----------------------------------------------------------------------------
IMPLEMENT_DYNAMIC_CLASS(wxScrolledWindow, wxPanel)
bool wxScrolledWindow::Create(wxWindow *parent,
wxWindowID id,
const wxPoint& pos,
const wxSize& size,
long style,
const wxString& name)
{
m_targetWindow = this;
bool ok = wxPanel::Create(parent, id, pos, size, style, name);
#ifdef __WXMSW__
// we need to process arrows ourselves for scrolling
m_lDlgCode |= DLGC_WANTARROWS;
#endif // __WXMSW__
return ok;
}
wxScrolledWindow::~wxScrolledWindow()
{
}
#if WXWIN_COMPATIBILITY
void wxScrolledWindow::GetScrollUnitsPerPage (int *x_page, int *y_page) const
{
*x_page = GetScrollPageSize(wxHORIZONTAL);
*y_page = GetScrollPageSize(wxVERTICAL);
}
void wxScrolledWindow::CalcUnscrolledPosition(int x, int y, float *xx, float *yy) const
{
if ( xx )
*xx = (float)(x + m_xScrollPosition * m_xScrollPixelsPerLine);
if ( yy )
*yy = (float)(y + m_yScrollPosition * m_yScrollPixelsPerLine);
}
#endif // WXWIN_COMPATIBILITY