From: Ron Lee Date: Fri, 19 Apr 2002 22:12:38 +0000 (+0000) Subject: Added knowledge of virtual size to wx(Scrolled)Windows, they can now X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/566d84a7c3c06956562b9f8ac364aa3bad760c10 Added knowledge of virtual size to wx(Scrolled)Windows, they can now manage their own scrollbars with the help of a sizer or other user clues (SetVirtualSizeHints) without the need for an ancillary container. Added SetSizerAndFit convenience method. SetSizer now enables/disables AutoLayout automagically. Logic bugfix for scrollsub sample. Syntax bugfix in parser.y. Compiler warning fix in textctrl.cpp. Modified Files: docs/latex/wx/scrolwin.tex docs/latex/wx/sizer.tex docs/latex/wx/window.tex include/wx/scrolwin.h include/wx/sizer.h include/wx/window.h include/wx/generic/scrolwin.h include/wx/gtk/scrolwin.h samples/scrollsub/scrollsub.cpp src/common/parser.y src/common/sizer.cpp src/common/wincmn.cpp src/generic/scrlwing.cpp src/gtk/scrolwin.cpp src/msw/textctrl.cpp git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@15210 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/docs/latex/wx/scrolwin.tex b/docs/latex/wx/scrolwin.tex index 0129bee043..f71a9789ba 100644 --- a/docs/latex/wx/scrolwin.tex +++ b/docs/latex/wx/scrolwin.tex @@ -358,11 +358,22 @@ scroll steps may be variable according to the position in the document, it will necessary to derive a new class from wxWindow, overriding {\bf OnSize} and adjusting the scrollbars appropriately. +\wxheading{See also} + +\helpref{wxWindow::SetVirtualSize}{wxwindowsetvirtualsize} + +\membersection{wxScrolledWindow::SetScrollRate}\label{wxscrolledwindowsetscrollrate} + +\func{void}{SetScrollRate}{\param{int}{xstep}, \param{int}{ystep}} + +Set the horizontal and vertical scrolling increment only. See the pixelsPerUnit +parameter in SetScrollbars. + \membersection{wxScrolledWindow::SetTargetWindow}\label{wxscrolledwindowsettargetwindow} \func{void}{SetTargetWindow}{\param{wxWindow* }{window}} -Call this function to tell wxScrolledWindow to perform the actually scrolling on +Call this function to tell wxScrolledWindow to perform the actual scrolling on a different window (not on itself). \membersection{wxScrolledWindow::GetViewStart}\label{wxscrolledwindowgetviewstart} diff --git a/docs/latex/wx/sizer.tex b/docs/latex/wx/sizer.tex index f39b4aeabc..86cf483ab0 100644 --- a/docs/latex/wx/sizer.tex +++ b/docs/latex/wx/sizer.tex @@ -131,6 +131,20 @@ Tell the sizer to resize the {\it window} to match the sizer's minimal size. Thi is commonly done in the constructor of the window itself, see sample in the description of \helpref{wxBoxSizer}{wxboxsizer}. +\membersection{wxSizer::FitInside}\label{wxsizerfitinside} + +\func{void}{FitInside}{\param{wxWindow* }{window}} + +Tell the sizer to resize the virtual size of the {\it window} to match the sizer's +minimal size. This will not alter the on screen size of the window, but may cause +the addition/removal/alteration of scrollbars required to view the virtual area in +windows which manage it. + +\wxheading{See also} + +\helpref{wxScrolledWindow::SetScrollbars}{wxscrolledwindowsetscrollbars},\rtfsp +\helpref{wxSizer::SetVirtualSizeHints}{wxsizersetvirtualsizehints} + \membersection{wxSizer::GetSize}\label{wxsizergetsize} \func{wxSize}{GetSize}{\void} @@ -230,8 +244,19 @@ after initial creation. \func{void}{SetSizeHints}{\param{wxWindow* }{window}} -Tell the sizer to set the minimal size of the {\it window} to match the sizer's minimal size. -This is commonly done in the constructor of the window itself, see sample in the description -of \helpref{wxBoxSizer}{wxboxsizer} if the window is resizable (as are many dialogs under Unix and -frames on probably all platforms). +Tell the sizer to set (and \helpref{Fit}{wxsizerfit}) the minimal size of the {\it window} to +match the sizer's minimal size. This is commonly done in the constructor of the window itself, +see sample in the description of \helpref{wxBoxSizer}{wxboxsizer} if the window is resizable +(as are many dialogs under Unix and frames on probably all platforms). + +\membersection{wxSizer::SetVirtualSizeHints}\label{wxsizersetvirtualsizehints} + +\func{void}{SetVirtualSizeHints}{\param{wxWindow* }{window}} + +Tell the sizer to set the minimal size of the {\it window} virtual area to match the sizer's +minimal size. For windows with managed scrollbars this will set them appropriately. + +\wxheading{See also} + +\helpref{wxScrolledWindow::SetScrollbars}{wxscrolledwindowsetscrollbars} diff --git a/docs/latex/wx/window.tex b/docs/latex/wx/window.tex index c5846f1cd0..4294d874f6 100644 --- a/docs/latex/wx/window.tex +++ b/docs/latex/wx/window.tex @@ -570,6 +570,7 @@ implements the following methods:\par \wxheading{See also} \helpref{GetSize}{wxwindowgetsize} +\helpref{GetVirtualSize}{wxwindowgetvirtualsize} \membersection{wxWindow::GetConstraints}\label{wxwindowgetconstraints} @@ -826,7 +827,8 @@ method:\par \wxheading{See also} -\helpref{GetClientSize}{wxwindowgetclientsize} +\helpref{GetClientSize}{wxwindowgetclientsize},\rtfsp +\helpref{GetVirtualSize}{wxwindowgetvirtualsize} \membersection{wxWindow::GetSizer}\label{wxwindowgetsizer} @@ -902,6 +904,23 @@ only be called within an \helpref{wxPaintEvent}{wxpaintevent} handler. Returns a pointer to the current validator for the window, or NULL if there is none. +\membersection{wxWindow::GetVirtualSize}\label{wxwindowgetvirtualsize} + +\constfunc{void}{GetVirtualSize}{\param{int* }{width}, \param{int* }{height}} + +\constfunc{wxSize}{GetVirtualSize}{\void} + +This gets the virtual size of the window in pixels. + +\wxheading{Parameters} + +\docparam{width}{Receives the window virtual width.} + +\docparam{height}{Receives the window virtual height.} + +\helpref{GetSize}{wxwindowgetsize},\rtfsp +\helpref{GetClientSize}{wxwindowgetclientsize} + \membersection{wxWindow::GetWindowStyleFlag}\label{wxwindowgetwindowstyleflag} \constfunc{long}{GetWindowStyleFlag}{\void} @@ -2405,11 +2424,21 @@ Pass FALSE if you wish to handle deleting the old sizer yourself.} \wxheading{Remarks} +SetSizer now enables and disables Layout automatically, but prior to wxWindows 2.3.3 +the following applied: + You must call \helpref{wxWindow::SetAutoLayout}{wxwindowsetautolayout} to tell a window to use the sizer automatically in OnSize; otherwise, you must override OnSize and call Layout() explicitly. When setting both a wxSizer and a \helpref{wxLayoutConstraints}{wxlayoutconstraints}, only the sizer will have effect. +\membersection{wxWindow::SetSizerAndFit}\label{wxwindowsetsizerandfit} + +\func{void}{SetSizerAndFit}{\param{wxSizer* }{sizer}, \param{bool }{deleteOld=TRUE}} + +The same as \helpref{SetSizer}{wxwindowsetsizer}, except it also sets the size hints +for the window based on the sizer's minimum size. + \membersection{wxWindow::SetTitle}\label{wxwindowsettitle} \func{virtual void}{SetTitle}{\param{const wxString\& }{title}} @@ -2450,6 +2479,37 @@ See also: \helpref{GetToolTip}{wxwindowgettooltip}, Get the associated tooltip or NULL if none. +\membersection{wxWindow::SetVirtualSize}\label{wxwindowsetvirtualsize} + +\func{void}{SetVirtualSize}{\param{int}{ width}, \param{int}{ height}} + +\func{void}{SetVirtualSize}{\param{const wxSize\&}{ size}} + +Sets the virtual size of the window in pixels. + + +\membersection{wxWindow::SetVirtualSizeHints}\label{wxwindowsetvirtualsizehints} + +\func{virtual void}{SetVirtualSizeHints}{\param{int}{ minW},\param{int}{ minH}, \param{int}{ maxW=-1}, \param{int}{ maxH=-1}} + +Allows specification of minimum and maximum virtual window sizes. +If a pair of values is not set (or set to -1), the default values +will be used. + +\wxheading{Parameters} + +\docparam{minW}{Specifies the minimum width allowable.} + +\docparam{minH}{Specifies the minimum height allowable.} + +\docparam{maxW}{Specifies the maximum width allowable.} + +\docparam{maxH}{Specifies the maximum height allowable.} + +\wxheading{Remarks} + +If this function is called, the user will not be able to size the virtual area +of the window outside the given bounds. \membersection{wxWindow::SetWindowStyle}\label{wxwindowsetwindowstyle} diff --git a/include/wx/generic/scrolwin.h b/include/wx/generic/scrolwin.h index 0808cbb2b3..acf05c500b 100644 --- a/include/wx/generic/scrolwin.h +++ b/include/wx/generic/scrolwin.h @@ -69,6 +69,8 @@ public: // lay out the window and its children virtual bool Layout(); + virtual void DoSetVirtualSize( int x, int y ); + protected: // this is needed for wxEVT_PAINT processing hack described in // wxScrollHelperEvtHandler::ProcessEvent() @@ -91,3 +93,5 @@ private: #endif // _WX_GENERIC_SCROLLWIN_H_ + +// vi:sts=4:sw=4:et diff --git a/include/wx/gtk/scrolwin.h b/include/wx/gtk/scrolwin.h index 9d9c0d9a6e..ad017649b2 100644 --- a/include/wx/gtk/scrolwin.h +++ b/include/wx/gtk/scrolwin.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: wx/generic/scrolwin.h +// Name: wx/gtk/scrolwin.h // Purpose: wxScrolledWindow class // Author: Robert Roebling // Modified by: @@ -65,9 +65,17 @@ public: virtual void SetTargetWindow( wxWindow *target, bool pushEventHandler = FALSE ); virtual wxWindow *GetTargetWindow(); + // Set the scrolled area of the window. + virtual void DoSetVirtualSize( int x, int y ); + + // Set the x, y scrolling increments. + void SetScrollRate( int xstep, int ystep ); + // Number of pixels per user unit (0 or -1 for no scrollbar) // Length of virtual canvas in user units // Length of page in user units + // Default action is to set the virtual size and alter scrollbars + // accordingly. virtual void SetScrollbars(int pixelsPerUnitX, int pixelsPerUnitY, int noUnitsX, int noUnitsY, int xPos = 0, int yPos = 0, @@ -95,9 +103,6 @@ public: void ViewStart(int *x, int *y) const { GetViewStart( x, y ); } - // Actual size in pixels when scrolling is taken into account - virtual void GetVirtualSize(int *x, int *y) const; - // translate between scrolled and unscrolled coordinates void CalcScrolledPosition(int x, int y, int *xx, int *yy) const { DoCalcScrolledPosition(x, y, xx, yy); } @@ -163,10 +168,12 @@ protected: int m_yScrollPixelsPerLine; bool m_xScrollingEnabled; bool m_yScrollingEnabled; + + // FIXME: these next four members are duplicated in the GtkAdjustment + // members of wxWindow. Can they be safely removed from here? + int m_xScrollPosition; int m_yScrollPosition; - int m_xScrollLines; - int m_yScrollLines; int m_xScrollLinesPerPage; int m_yScrollLinesPerPage; @@ -179,3 +186,5 @@ private: #endif // _WX_GTK_SCROLLWIN_H_ + +// vi:sts=4:sw=4:et diff --git a/include/wx/gtk1/scrolwin.h b/include/wx/gtk1/scrolwin.h index 9d9c0d9a6e..ad017649b2 100644 --- a/include/wx/gtk1/scrolwin.h +++ b/include/wx/gtk1/scrolwin.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: wx/generic/scrolwin.h +// Name: wx/gtk/scrolwin.h // Purpose: wxScrolledWindow class // Author: Robert Roebling // Modified by: @@ -65,9 +65,17 @@ public: virtual void SetTargetWindow( wxWindow *target, bool pushEventHandler = FALSE ); virtual wxWindow *GetTargetWindow(); + // Set the scrolled area of the window. + virtual void DoSetVirtualSize( int x, int y ); + + // Set the x, y scrolling increments. + void SetScrollRate( int xstep, int ystep ); + // Number of pixels per user unit (0 or -1 for no scrollbar) // Length of virtual canvas in user units // Length of page in user units + // Default action is to set the virtual size and alter scrollbars + // accordingly. virtual void SetScrollbars(int pixelsPerUnitX, int pixelsPerUnitY, int noUnitsX, int noUnitsY, int xPos = 0, int yPos = 0, @@ -95,9 +103,6 @@ public: void ViewStart(int *x, int *y) const { GetViewStart( x, y ); } - // Actual size in pixels when scrolling is taken into account - virtual void GetVirtualSize(int *x, int *y) const; - // translate between scrolled and unscrolled coordinates void CalcScrolledPosition(int x, int y, int *xx, int *yy) const { DoCalcScrolledPosition(x, y, xx, yy); } @@ -163,10 +168,12 @@ protected: int m_yScrollPixelsPerLine; bool m_xScrollingEnabled; bool m_yScrollingEnabled; + + // FIXME: these next four members are duplicated in the GtkAdjustment + // members of wxWindow. Can they be safely removed from here? + int m_xScrollPosition; int m_yScrollPosition; - int m_xScrollLines; - int m_yScrollLines; int m_xScrollLinesPerPage; int m_yScrollLinesPerPage; @@ -179,3 +186,5 @@ private: #endif // _WX_GTK_SCROLLWIN_H_ + +// vi:sts=4:sw=4:et diff --git a/include/wx/scrolwin.h b/include/wx/scrolwin.h index 2986a6c9c4..8e12c38018 100644 --- a/include/wx/scrolwin.h +++ b/include/wx/scrolwin.h @@ -44,6 +44,9 @@ public: int GetScrollPageSize(int orient) const; void SetScrollPageSize(int orient, int pageSize); + // Set the x, y scrolling increments. + void SetScrollRate( int xstep, int ystep ); + // get the size of one logical unit in physical ones virtual void GetScrollPixelsPerUnit(int *pixelsPerUnitX, int *pixelsPerUnitY) const; @@ -58,9 +61,6 @@ public: // Get the view start virtual void GetViewStart(int *x, int *y) const; - // Actual size in pixels when scrolling is taken into account - virtual void GetVirtualSize(int *x, int *y) const; - // Set the scale factor, used in PrepareDC void SetScale(double xs, double ys) { m_scaleX = xs; m_scaleY = ys; } double GetScaleX() const { return m_scaleX; } @@ -230,3 +230,5 @@ protected: #endif // _WX_SCROLWIN_H_BASE_ + +// vi:sts=4:sw=4:et diff --git a/include/wx/sizer.h b/include/wx/sizer.h index 11b4e38912..d406d059b6 100644 --- a/include/wx/sizer.h +++ b/include/wx/sizer.h @@ -2,7 +2,7 @@ // Name: sizer.h // Purpose: provide wxSizer class for layouting // Author: Robert Roebling and Robin Dunn -// Modified by: +// Modified by: Ron Lee // Created: // RCS-ID: $Id$ // Copyright: (c) Robin Dunn, Dirk Holtwick and Robert Roebling @@ -185,7 +185,9 @@ public: virtual void Layout(); void Fit( wxWindow *window ); + void FitInside( wxWindow *window ); void SetSizeHints( wxWindow *window ); + void SetVirtualSizeHints( wxWindow *window ); wxList& GetChildren() { return m_children; } @@ -200,7 +202,10 @@ protected: wxSize GetMaxWindowSize( wxWindow *window ); wxSize GetMinWindowSize( wxWindow *window ); + wxSize GetMaxClientSize( wxWindow *window ); + wxSize GetMinClientSize( wxWindow *window ); wxSize FitSize( wxWindow *window ); + wxSize VirtualFitSize( wxWindow *window ); virtual void DoSetMinSize( int width, int height ); virtual bool DoSetItemMinSize( wxWindow *window, int width, int height ); diff --git a/include/wx/window.h b/include/wx/window.h index 1b7071d626..25cb7ad47b 100644 --- a/include/wx/window.h +++ b/include/wx/window.h @@ -2,7 +2,7 @@ // Name: wx/window.h // Purpose: wxWindowBase class - the interface of wxWindow // Author: Vadim Zeitlin -// Modified by: +// Modified by: Ron Lee // Created: 01/02/97 // RCS-ID: $Id$ // Copyright: (c) wxWindows team @@ -293,6 +293,9 @@ public: int maxW = -1, int maxH = -1, int incW = -1, int incH = -1 ); + virtual void SetVirtualSizeHints( int minW, int minH, + int maxW = -1, int maxH = -1 ); + virtual int GetMinWidth() const { return m_minWidth; } virtual int GetMinHeight() const { return m_minHeight; } int GetMaxWidth() const { return m_maxWidth; } @@ -301,6 +304,33 @@ public: // Override this method to control the values given to Sizers etc. virtual wxSize GetMaxSize() const { return wxSize( m_maxWidth, m_maxHeight ); } + // Methods for accessing the virtual size of a window. For most + // windows this is just the client area of the window, but for + // some like scrolled windows it is more or less independent of + // the screen window size. You may override the DoXXXVirtual + // methods below for classes where that is is the case. + + void SetVirtualSize( const wxSize &size ) { DoSetVirtualSize( size.x, size.y ); } + void SetVirtualSize( int x, int y ) { DoSetVirtualSize( x, y ); } + + wxSize GetVirtualSize() const { return DoGetVirtualSize(); } + void GetVirtualSize( int *x, int *y ) const + { + wxSize s( DoGetVirtualSize() ); + + if( x ) + *x = s.GetWidth(); + if( y ) + *y = s.GetHeight(); + } + + // Override these methods for windows that have a virtual size + // independent of their client size. eg. the virtual area of a + // wxScrolledWindow. Default is to alias VirtualSize to ClientSize. + + virtual void DoSetVirtualSize( int x, int y ); + virtual wxSize DoGetVirtualSize() const; // { return m_virtualSize; } + // window state // ------------ @@ -740,6 +770,8 @@ public: // sizers void SetSizer(wxSizer *sizer, bool deleteOld = TRUE ); + void SetSizerAndFit( wxSizer *sizer, bool deleteOld = TRUE ); + wxSizer *GetSizer() const { return m_windowSizer; } // Track if this window is a member of a sizer @@ -790,6 +822,7 @@ public: #endif // wxUSE_PALETTE protected: + // the window id - a number which uniquely identifies a window among // its siblings unless it is -1 wxWindowID m_windowId; @@ -878,7 +911,13 @@ protected: bool m_hasCustomPalette; #endif // wxUSE_PALETTE -protected: + // Virtual size (scrolling) + wxSize m_virtualSize; + + int m_minVirtualWidth; // VirtualSizeHints + int m_minVirtualHeight; + int m_maxVirtualWidth; + int m_maxVirtualHeight; // common part of all ctors: it is not virtual because it is called from // ctor diff --git a/samples/scrollsub/scrollsub.cpp b/samples/scrollsub/scrollsub.cpp index 3d16d9e91d..f47a253c6b 100644 --- a/samples/scrollsub/scrollsub.cpp +++ b/samples/scrollsub/scrollsub.cpp @@ -210,7 +210,18 @@ MyTopLabels::MyTopLabels( wxScrolledWindow *parent, wxWindowID id, const wxPoint void MyTopLabels::OnPaint( wxPaintEvent &event ) { wxPaintDC dc(this); - m_owner->PrepareDC( dc ); + + // This is wrong.. it will translate both x and y if the + // window is scrolled, the label windows are active in one + // direction only. Do the action below instead -- RL. + //m_owner->PrepareDC( dc ); + + int xScrollUnits, xOrigin; + + m_owner->GetViewStart( &xOrigin, 0 ); + m_owner->GetScrollPixelsPerUnit( &xScrollUnits, 0 ); + dc.SetDeviceOrigin( -xOrigin * xScrollUnits, 0 ); + dc.DrawText( "Column 1", 5, 5 ); dc.DrawText( "Column 2", 105, 5 ); dc.DrawText( "Column 3", 205, 5 ); @@ -233,7 +244,18 @@ MyRightLabels::MyRightLabels( wxScrolledWindow *parent, wxWindowID id, const wxP void MyRightLabels::OnPaint( wxPaintEvent &event ) { wxPaintDC dc(this); - m_owner->PrepareDC( dc ); + + // This is wrong.. it will translate both x and y if the + // window is scrolled, the label windows are active in one + // direction only. Do the action below instead -- RL. + //m_owner->PrepareDC( dc ); + + int yScrollUnits, yOrigin; + + m_owner->GetViewStart( 0, &yOrigin ); + m_owner->GetScrollPixelsPerUnit( 0, &yScrollUnits ); + dc.SetDeviceOrigin( 0, -yOrigin * yScrollUnits ); + dc.DrawText( "Row 1", 5, 5 ); dc.DrawText( "Row 2", 5, 30 ); dc.DrawText( "Row 3", 5, 55 ); diff --git a/src/common/parser.y b/src/common/parser.y index a5dcdf37a7..c922f8c04a 100644 --- a/src/common/parser.y +++ b/src/common/parser.y @@ -97,6 +97,7 @@ arg : WORD EQUALS arg1 free($1); } | arg1 {$$ = $1; } + ; arg1 : WORD {$$ = wxmake_word($1); free($1);} diff --git a/src/common/sizer.cpp b/src/common/sizer.cpp index f20410f51d..3233856426 100644 --- a/src/common/sizer.cpp +++ b/src/common/sizer.cpp @@ -2,7 +2,7 @@ // Name: sizer.cpp // Purpose: provide new wxSizer class for layout // Author: Robert Roebling and Robin Dunn -// Modified by: +// Modified by: Ron Lee // Created: // RCS-ID: $Id$ // Copyright: (c) Robin Dunn, Dirk Holtwick and Robert Roebling @@ -412,6 +412,17 @@ void wxSizer::Fit( wxWindow *window ) window->SetSize( size ); } +void wxSizer::FitInside( wxWindow *window ) +{ + wxSize size; + if (window->IsTopLevel()) + size = VirtualFitSize( window ); + else + size = GetMinClientSize( window ); + + window->SetVirtualSize( size ); +} + void wxSizer::Layout() { CalcMin(); @@ -423,13 +434,27 @@ void wxSizer::SetSizeHints( wxWindow *window ) // Preserve the window's max size hints, but set the // lower bound according to the sizer calculations. - wxSize size = FitSize( window ); + Fit( window ); + wxSize size( window->GetSize() ); window->SetSizeHints( size.x, size.y, window->GetMaxWidth(), window->GetMaxHeight() ); } +void wxSizer::SetVirtualSizeHints( wxWindow *window ) +{ + // Preserve the window's max size hints, but set the + // lower bound according to the sizer calculations. + + FitInside( window ); + wxSize size( window->GetVirtualSize() ); + window->SetVirtualSizeHints( size.x, + size.y, + window->GetMaxWidth(), + window->GetMaxHeight() ); +} + wxSize wxSizer::GetMaxWindowSize( wxWindow *window ) { return window->GetMaxSize(); @@ -460,6 +485,42 @@ wxSize wxSizer::FitSize( wxWindow *window ) return size; } +wxSize wxSizer::GetMaxClientSize( wxWindow *window ) +{ + wxSize maxSize( window->GetMaxSize() ); + + if( maxSize != wxDefaultSize ) + { + wxSize size( window->GetSize() ); + wxSize client_size( window->GetClientSize() ); + + return wxSize( maxSize.x + client_size.x - size.x, + maxSize.y + client_size.y - size.y ); + } + else + return wxDefaultSize; +} + +wxSize wxSizer::GetMinClientSize( wxWindow *window ) +{ + return GetMinSize(); // Already returns client size. +} + +wxSize wxSizer::VirtualFitSize( wxWindow *window ) +{ + wxSize size = GetMinClientSize( window ); + wxSize sizeMax = GetMaxClientSize( window ); + + // Limit the size if sizeMax != wxDefaultSize + + if ( size.x > sizeMax.x && sizeMax.x != -1 ) + size.x = sizeMax.x; + if ( size.y > sizeMax.y && sizeMax.y != -1 ) + size.y = sizeMax.y; + + return size; +} + void wxSizer::SetDimension( int x, int y, int width, int height ) { m_position.x = x; diff --git a/src/common/wincmn.cpp b/src/common/wincmn.cpp index 2641125c24..ec06700081 100644 --- a/src/common/wincmn.cpp +++ b/src/common/wincmn.cpp @@ -174,6 +174,12 @@ void wxWindowBase::InitBase() m_hasCustomPalette = FALSE; #endif // wxUSE_PALETTE + m_virtualSize = wxDefaultSize; + m_minVirtualWidth = -1; + m_minVirtualHeight = -1; + m_maxVirtualWidth = -1; + m_maxVirtualHeight = -1; + // Whether we're using the current theme for this window (wxGTK only for now) m_themeEnabled = FALSE; } @@ -522,6 +528,40 @@ void wxWindowBase::SetSizeHints(int minW, int minH, m_maxHeight = maxH; } +void wxWindowBase::SetVirtualSizeHints( int minW, int minH, + int maxW, int maxH ) +{ + m_minVirtualWidth = minW; + m_maxVirtualWidth = maxW; + m_minVirtualHeight = minH; + m_maxVirtualHeight = maxH; + + SetVirtualSize( GetClientSize() ); +} + +void wxWindowBase::DoSetVirtualSize( int x, int y ) +{ + if( m_minVirtualWidth != -1 && m_minVirtualWidth > x ) x = m_minVirtualWidth; + if( m_maxVirtualWidth != -1 && m_maxVirtualWidth < x ) x = m_maxVirtualWidth; + if( m_minVirtualHeight != -1 && m_minVirtualHeight > y ) y = m_minVirtualHeight; + if( m_maxVirtualHeight != -1 && m_maxVirtualHeight < y ) y = m_maxVirtualHeight; + + m_virtualSize.SetWidth( x ); + m_virtualSize.SetHeight( y ); +} + +wxSize wxWindowBase::DoGetVirtualSize() const +{ + wxSize s( GetClientSize() ); + + if( m_virtualSize.GetWidth() != -1 ) + s.SetWidth( m_virtualSize.GetWidth() ); + if( m_virtualSize.GetHeight() != -1 ) + s.SetHeight( m_virtualSize.GetHeight() ); + + return s; +} + // ---------------------------------------------------------------------------- // show/hide/enable/disable the window // ---------------------------------------------------------------------------- @@ -1190,6 +1230,14 @@ void wxWindowBase::SetSizer(wxSizer *sizer, bool deleteOld) if (m_windowSizer && deleteOld) delete m_windowSizer; m_windowSizer = sizer; + + SetAutoLayout( sizer != 0 ); +} + +void wxWindowBase::SetSizerAndFit(wxSizer *sizer, bool deleteOld) +{ + SetSizer( sizer, deleteOld ); + sizer->SetSizeHints( (wxWindow*) this ); } bool wxWindowBase::Layout() @@ -1198,8 +1246,7 @@ bool wxWindowBase::Layout() if ( GetSizer() ) { int w, h; - GetClientSize(&w, &h); - + GetVirtualSize(&w, &h); GetSizer()->SetDimension( 0, 0, w, h ); } #if wxUSE_CONSTRAINTS diff --git a/src/generic/scrlwing.cpp b/src/generic/scrlwing.cpp index 904104e371..e05628749d 100644 --- a/src/generic/scrlwing.cpp +++ b/src/generic/scrlwing.cpp @@ -2,7 +2,8 @@ // Name: generic/scrolwin.cpp // Purpose: wxGenericScrolledWindow implementation // Author: Julian Smart -// Modified by: Vadim Zeitlin on 31.08.00: wxScrollHelper allows to implement +// Modified by: Vadim Zeitlin on 31.08.00: wxScrollHelper allows to implement. +// Ron Lee on 10.4.02: virtual size / auto scrollbars et al. // Created: 01/02/97 // RCS-ID: $Id$ // Copyright: (c) wxWindows team @@ -326,10 +327,10 @@ void wxScrollHelper::SetScrollbars(int pixelsPerUnitX, 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) || + (noUnitsY < m_yScrollLines && ypos > pixelsPerUnitY * noUnitsY) || (xPos != m_xScrollPosition) || (yPos != m_yScrollPosition) ); @@ -338,43 +339,8 @@ void wxScrollHelper::SetScrollbars(int pixelsPerUnitX, m_yScrollPixelsPerLine = pixelsPerUnitY; m_xScrollPosition = xPos; m_yScrollPosition = yPos; - m_xScrollLines = noUnitsX; - m_yScrollLines = noUnitsY; -#ifdef __WXMOTIF__ - // Sorry, some Motif-specific code to implement a backing pixmap - // for the wxRETAINED style. Implementing a backing store can't - // be entirely generic because it relies on the wxWindowDC implementation - // to duplicate X drawing calls for the backing pixmap. - - if ( m_targetWindow->GetWindowStyle() & wxRETAINED ) - { - Display* dpy = XtDisplay((Widget)m_targetWindow->GetMainWidget()); - - int totalPixelWidth = m_xScrollLines * m_xScrollPixelsPerLine; - int totalPixelHeight = m_yScrollLines * m_yScrollPixelsPerLine; - if (m_targetWindow->GetBackingPixmap() && - !((m_targetWindow->GetPixmapWidth() == totalPixelWidth) && - (m_targetWindow->GetPixmapHeight() == totalPixelHeight))) - { - XFreePixmap (dpy, (Pixmap) m_targetWindow->GetBackingPixmap()); - m_targetWindow->SetBackingPixmap((WXPixmap) 0); - } - - if (!m_targetWindow->GetBackingPixmap() && - (noUnitsX != 0) && (noUnitsY != 0)) - { - int depth = wxDisplayDepth(); - m_targetWindow->SetPixmapWidth(totalPixelWidth); - m_targetWindow->SetPixmapHeight(totalPixelHeight); - m_targetWindow->SetBackingPixmap((WXPixmap) XCreatePixmap (dpy, RootWindow (dpy, DefaultScreen (dpy)), - m_targetWindow->GetPixmapWidth(), m_targetWindow->GetPixmapHeight(), depth)); - } - - } -#endif // Motif - - AdjustScrollbars(); + m_targetWindow->SetVirtualSizeHints( noUnitsX * pixelsPerUnitX, noUnitsY * pixelsPerUnitY ); if (do_refresh && !noRefresh) m_targetWindow->Refresh(TRUE, GetRect()); @@ -615,64 +581,116 @@ void wxScrollHelper::AdjustScrollbars() m_targetWindow->MacUpdateImmediately(); #endif - int w, h; - GetTargetSize(&w, &h); + int w = 0, h = 0; + int oldw, oldh; int oldXScroll = m_xScrollPosition; int oldYScroll = m_yScrollPosition; - if (m_xScrollLines > 0) - { - // Calculate page size i.e. number of scroll units you get on the - // current client window - int noPagePositions = (int) ( (w/(double)m_xScrollPixelsPerLine) + 0.5 ); - if (noPagePositions < 1) noPagePositions = 1; - if ( noPagePositions > m_xScrollLines ) - noPagePositions = m_xScrollLines; + do { + GetTargetSize(&w, 0); - // Correct position if greater than extent of canvas minus - // the visible portion of it or if below zero - m_xScrollPosition = wxMin( m_xScrollLines-noPagePositions, m_xScrollPosition); - m_xScrollPosition = wxMax( 0, m_xScrollPosition ); + if (m_xScrollPixelsPerLine == 0) + { + m_xScrollLines = 0; + m_xScrollPosition = 0; + m_win->SetScrollbar (wxHORIZONTAL, 0, 0, 0, FALSE); + } + else + { + m_xScrollLines = m_targetWindow->GetVirtualSize().GetWidth() / m_xScrollPixelsPerLine; + + // Calculate page size i.e. number of scroll units you get on the + // current client window + int noPagePositions = (int) ( (w/(double)m_xScrollPixelsPerLine) + 0.5 ); + if (noPagePositions < 1) noPagePositions = 1; + if ( noPagePositions > m_xScrollLines ) + noPagePositions = m_xScrollLines; + + // Correct position if greater than extent of canvas minus + // the visible portion of it or if below zero + m_xScrollPosition = wxMin( m_xScrollLines - noPagePositions, m_xScrollPosition); + m_xScrollPosition = wxMax( 0, m_xScrollPosition ); + + m_win->SetScrollbar(wxHORIZONTAL, m_xScrollPosition, noPagePositions, m_xScrollLines); + // The amount by which we scroll when paging + SetScrollPageSize(wxHORIZONTAL, noPagePositions); + } - m_win->SetScrollbar(wxHORIZONTAL, m_xScrollPosition, noPagePositions, m_xScrollLines); - // The amount by which we scroll when paging - SetScrollPageSize(wxHORIZONTAL, noPagePositions); - } - else - { - m_xScrollPosition = 0; - m_win->SetScrollbar (wxHORIZONTAL, 0, 0, 0, FALSE); - } + GetTargetSize(0, &h); - if (m_yScrollLines > 0) - { - // Calculate page size i.e. number of scroll units you get on the - // current client window - int noPagePositions = (int) ( (h/(double)m_yScrollPixelsPerLine) + 0.5 ); - if (noPagePositions < 1) noPagePositions = 1; - if ( noPagePositions > m_yScrollLines ) - noPagePositions = m_yScrollLines; + if (m_yScrollPixelsPerLine == 0) + { + m_yScrollLines = 0; + m_yScrollPosition = 0; + m_win->SetScrollbar (wxVERTICAL, 0, 0, 0, FALSE); + } + else + { + m_yScrollLines = m_targetWindow->GetVirtualSize().GetHeight() / m_yScrollPixelsPerLine; + + // Calculate page size i.e. number of scroll units you get on the + // current client window + int noPagePositions = (int) ( (h/(double)m_yScrollPixelsPerLine) + 0.5 ); + if (noPagePositions < 1) noPagePositions = 1; + if ( noPagePositions > m_yScrollLines ) + noPagePositions = m_yScrollLines; + + // Correct position if greater than extent of canvas minus + // the visible portion of it or if below zero + m_yScrollPosition = wxMin( m_yScrollLines - noPagePositions, m_yScrollPosition ); + m_yScrollPosition = wxMax( 0, m_yScrollPosition ); + + m_win->SetScrollbar(wxVERTICAL, m_yScrollPosition, noPagePositions, m_yScrollLines); + // The amount by which we scroll when paging + SetScrollPageSize(wxVERTICAL, noPagePositions); + } - // Correct position if greater than extent of canvas minus - // the visible portion of it or if below zero - m_yScrollPosition = wxMin( m_yScrollLines-noPagePositions, m_yScrollPosition ); - m_yScrollPosition = wxMax( 0, m_yScrollPosition ); + // If a scrollbar (dis)appeared as a result of this, adjust them again. - m_win->SetScrollbar(wxVERTICAL, m_yScrollPosition, noPagePositions, m_yScrollLines); - // The amount by which we scroll when paging - SetScrollPageSize(wxVERTICAL, noPagePositions); - } - else + oldw = w; + oldh = h; + + GetTargetSize( &w, &h ); + } while ( w != oldw && h != oldh ); + +#ifdef __WXMOTIF__ + // Sorry, some Motif-specific code to implement a backing pixmap + // for the wxRETAINED style. Implementing a backing store can't + // be entirely generic because it relies on the wxWindowDC implementation + // to duplicate X drawing calls for the backing pixmap. + + if ( m_targetWindow->GetWindowStyle() & wxRETAINED ) { - m_yScrollPosition = 0; - m_win->SetScrollbar (wxVERTICAL, 0, 0, 0, FALSE); + Display* dpy = XtDisplay((Widget)m_targetWindow->GetMainWidget()); + + int totalPixelWidth = m_xScrollLines * m_xScrollPixelsPerLine; + int totalPixelHeight = m_yScrollLines * m_yScrollPixelsPerLine; + if (m_targetWindow->GetBackingPixmap() && + !((m_targetWindow->GetPixmapWidth() == totalPixelWidth) && + (m_targetWindow->GetPixmapHeight() == totalPixelHeight))) + { + XFreePixmap (dpy, (Pixmap) m_targetWindow->GetBackingPixmap()); + m_targetWindow->SetBackingPixmap((WXPixmap) 0); + } + + if (!m_targetWindow->GetBackingPixmap() && + (noUnitsX != 0) && (noUnitsY != 0)) + { + int depth = wxDisplayDepth(); + m_targetWindow->SetPixmapWidth(totalPixelWidth); + m_targetWindow->SetPixmapHeight(totalPixelHeight); + m_targetWindow->SetBackingPixmap((WXPixmap) XCreatePixmap (dpy, RootWindow (dpy, DefaultScreen (dpy)), + m_targetWindow->GetPixmapWidth(), m_targetWindow->GetPixmapHeight(), depth)); + } + } +#endif // Motif if (oldXScroll != m_xScrollPosition) { if (m_xScrollingEnabled) - m_targetWindow->ScrollWindow( m_xScrollPixelsPerLine * (oldXScroll-m_xScrollPosition), 0, + m_targetWindow->ScrollWindow( m_xScrollPixelsPerLine * (oldXScroll - m_xScrollPosition), 0, GetRect() ); else m_targetWindow->Refresh(TRUE, GetRect()); @@ -700,6 +718,24 @@ void wxScrollHelper::DoPrepareDC(wxDC& dc) dc.SetUserScale( m_scaleX, m_scaleY ); } +void wxScrollHelper::SetScrollRate( int xstep, int ystep ) +{ + int old_x = m_xScrollPixelsPerLine * m_xScrollPosition; + int old_y = m_yScrollPixelsPerLine * m_yScrollPosition; + + m_xScrollPixelsPerLine = xstep; + m_yScrollPixelsPerLine = ystep; + + int new_x = m_xScrollPixelsPerLine * m_xScrollPosition; + int new_y = m_yScrollPixelsPerLine * m_yScrollPosition; + + m_win->SetScrollPos( wxHORIZONTAL, m_xScrollPosition ); + m_win->SetScrollPos( wxVERTICAL, m_yScrollPosition ); + m_targetWindow->ScrollWindow( old_x - new_x, old_y - new_y ); + + AdjustScrollbars(); +} + void wxScrollHelper::GetScrollPixelsPerUnit (int *x_unit, int *y_unit) const { if ( x_unit ) @@ -797,28 +833,6 @@ void wxScrollHelper::EnableScrolling (bool x_scroll, bool y_scroll) m_yScrollingEnabled = y_scroll; } -void wxScrollHelper::GetVirtualSize (int *x, int *y) const -{ - wxSize sz(0, 0); - if (m_targetWindow) - sz = m_targetWindow->GetClientSize(); - - if ( x ) - { - if (m_xScrollPixelsPerLine == 0) - *x = sz.x; - else - *x = m_xScrollPixelsPerLine * m_xScrollLines; - } - if ( y ) - { - if (m_yScrollPixelsPerLine == 0) - *y = sz.y; - else - *y = m_yScrollPixelsPerLine * m_yScrollLines; - } -} - // Where the current view starts from void wxScrollHelper::GetViewStart (int *x, int *y) const { @@ -851,7 +865,15 @@ void wxScrollHelper::DoCalcUnscrolledPosition(int x, int y, int *xx, int *yy) co // Default OnSize resets scrollbars, if any void wxScrollHelper::HandleOnSize(wxSizeEvent& WXUNUSED(event)) { - AdjustScrollbars(); + if( m_targetWindow != m_win ) + m_targetWindow->SetVirtualSize( m_targetWindow->GetClientSize() ); + + m_win->SetVirtualSize( m_win->GetClientSize() ); + +#if wxUSE_CONSTRAINTS + if (m_win->GetAutoLayout()) + m_win->Layout(); +#endif } // This calls OnDraw, having adjusted the origin according to the current @@ -877,7 +899,7 @@ void wxScrollHelper::HandleOnChar(wxKeyEvent& event) GetViewStart(&stx, &sty); GetTargetSize(&clix, &cliy); - GetVirtualSize(&szx, &szy); + m_targetWindow->GetVirtualSize(&szx, &szy); if( m_xScrollPixelsPerLine ) { @@ -1121,9 +1143,11 @@ wxGenericScrolledWindow::~wxGenericScrolledWindow() bool wxGenericScrolledWindow::Layout() { - if (GetSizer()) + if (GetSizer() && m_targetWindow == this) { - // Take into account the virtual size and scrolled position of the window + // If we're the scroll target, take into account the + // virtual size and scrolled position of the window. + int x, y, w, h; CalcScrolledPosition(0,0, &x,&y); GetVirtualSize(&w, &h); @@ -1135,6 +1159,12 @@ bool wxGenericScrolledWindow::Layout() return wxPanel::Layout(); } +void wxGenericScrolledWindow::DoSetVirtualSize( int x, int y ) +{ + wxPanel::DoSetVirtualSize( x, y ); + AdjustScrollbars(); +} + void wxGenericScrolledWindow::OnPaint(wxPaintEvent& event) { // the user code didn't really draw the window if we got here, so set this @@ -1183,3 +1213,4 @@ void wxGenericScrolledWindow::CalcUnscrolledPosition(int x, int y, float *xx, fl #endif // !wxGTK +// vi:sts=4:sw=4:et diff --git a/src/gtk/scrolwin.cpp b/src/gtk/scrolwin.cpp index fe7bf353ea..0a5ec3f800 100644 --- a/src/gtk/scrolwin.cpp +++ b/src/gtk/scrolwin.cpp @@ -2,7 +2,7 @@ // Name: gtk/scrolwin.cpp // Purpose: wxScrolledWindow implementation // Author: Julian Smart -// Modified by: +// Modified by: Ron Lee // Created: 01/02/97 // RCS-ID: $Id$ // Copyright: (c) Julian Smart and Markus Holzem @@ -202,8 +202,6 @@ void wxScrolledWindow::Init() m_yScrollingEnabled = TRUE; m_xScrollPosition = 0; m_yScrollPosition = 0; - m_xScrollLines = 0; - m_yScrollLines = 0; m_xScrollLinesPerPage = 0; m_yScrollLinesPerPage = 0; m_targetWindow = (wxWindow*) NULL; @@ -323,51 +321,47 @@ bool wxScrolledWindow::Create(wxWindow *parent, // setting scrolling parameters // ---------------------------------------------------------------------------- +void wxScrolledWindow::DoSetVirtualSize( int x, int y ) +{ + wxPanel::DoSetVirtualSize( x, y ); + AdjustScrollbars(); +} + /* * 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 wxScrolledWindow::SetScrollbars( int pixelsPerUnitX, int pixelsPerUnitY, + int noUnitsX, int noUnitsY, + int xPos, int yPos, bool noRefresh ) { int old_x = m_xScrollPixelsPerLine * m_xScrollPosition; int old_y = m_yScrollPixelsPerLine * m_yScrollPosition; m_xScrollPixelsPerLine = pixelsPerUnitX; m_yScrollPixelsPerLine = pixelsPerUnitY; - m_xScrollLines = noUnitsX; - m_yScrollLines = noUnitsY; - m_xScrollPosition = xPos; - m_yScrollPosition = yPos; - m_hAdjust->lower = 0.0; - m_hAdjust->upper = noUnitsX; - m_hAdjust->value = xPos; - m_hAdjust->step_increment = 1.0; - m_hAdjust->page_increment = 2.0; + m_hAdjust->value = m_xScrollPosition = xPos; + m_vAdjust->value = m_yScrollPosition = yPos; - m_vAdjust->lower = 0.0; - m_vAdjust->upper = noUnitsY; - m_vAdjust->value = yPos; - m_vAdjust->step_increment = 1.0; - m_vAdjust->page_increment = 2.0; - - AdjustScrollbars(); + m_targetWindow->SetVirtualSizeHints( noUnitsX * pixelsPerUnitX, noUnitsY * pixelsPerUnitY ); 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 ); + m_targetWindow->ScrollWindow( old_x - new_x, old_y - new_y ); } } void wxScrolledWindow::AdjustScrollbars() { int w, h; + int vw, vh; + m_targetWindow->GetClientSize( &w, &h ); + m_targetWindow->GetVirtualSize( &vw, &vh ); if (m_xScrollPixelsPerLine == 0) { @@ -376,21 +370,18 @@ void wxScrolledWindow::AdjustScrollbars() } else { + m_hAdjust->upper = vw / m_xScrollPixelsPerLine; m_hAdjust->page_size = (w / m_xScrollPixelsPerLine); - int max = (int)(m_hAdjust->upper - m_hAdjust->page_size + 0.5); - if (max < 0) max = 0; - - int x_pos = m_xScrollPosition; - if (x_pos > max) x_pos = max; - if (x_pos < 0) x_pos = 0; - - int old_x = m_xScrollPosition; - m_xScrollPosition = x_pos; - m_hAdjust->value = x_pos; + // If the scrollbar hits the right side, move the window + // right to keep it from over extending. - if (x_pos != old_x) - m_targetWindow->ScrollWindow( (old_x-m_xScrollPosition)*m_xScrollPixelsPerLine, 0 ); + if( m_hAdjust->value + m_hAdjust->page_size > m_hAdjust->upper ) + { + m_hAdjust->value = m_hAdjust->upper - m_hAdjust->page_size; + m_targetWindow->ScrollWindow( (m_xScrollPosition - m_hAdjust->value) * m_xScrollPixelsPerLine, 0 ); + m_xScrollPosition = (int)m_hAdjust->value; + } } if (m_yScrollPixelsPerLine == 0) @@ -400,21 +391,15 @@ void wxScrolledWindow::AdjustScrollbars() } else { + m_vAdjust->upper = vh / m_yScrollPixelsPerLine; m_vAdjust->page_size = (h / m_yScrollPixelsPerLine); - int max = (int)(m_vAdjust->upper - m_vAdjust->page_size + 0.5); - if (max < 0) max = 0; - - int y_pos = m_yScrollPosition; - if (y_pos > max) y_pos = max; - if (y_pos < 0) y_pos = 0; - - int old_y = m_yScrollPosition; - m_yScrollPosition = y_pos; - m_vAdjust->value = y_pos; - - if (y_pos != old_y) - m_targetWindow->ScrollWindow( 0, (old_y-m_yScrollPosition)*m_yScrollPixelsPerLine ); + if( m_vAdjust->value + m_vAdjust->page_size > m_vAdjust->upper ) + { + m_vAdjust->value = m_vAdjust->upper - m_vAdjust->page_size; + m_targetWindow->ScrollWindow( 0, (m_yScrollPosition - m_vAdjust->value) * m_yScrollPixelsPerLine ); + m_yScrollPosition = (int)m_vAdjust->value; + } } m_xScrollLinesPerPage = (int)(m_hAdjust->page_size + 0.5); @@ -424,6 +409,7 @@ void wxScrolledWindow::AdjustScrollbars() gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "changed" ); } + // ---------------------------------------------------------------------------- // target window handling // ---------------------------------------------------------------------------- @@ -447,6 +433,22 @@ void wxScrolledWindow::PrepareDC(wxDC& dc) -m_yScrollPosition * m_yScrollPixelsPerLine ); } +void wxScrolledWindow::SetScrollRate( int xstep, int ystep ) +{ + int old_x = m_xScrollPixelsPerLine * m_xScrollPosition; + int old_y = m_yScrollPixelsPerLine * m_yScrollPosition; + + m_xScrollPixelsPerLine = xstep; + m_yScrollPixelsPerLine = ystep; + + 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 ); + + AdjustScrollbars(); +} + void wxScrolledWindow::GetScrollPixelsPerUnit (int *x_unit, int *y_unit) const { if ( x_unit ) @@ -516,8 +518,7 @@ void wxScrolledWindow::OnScroll(wxScrollWinEvent& event) void wxScrolledWindow::Scroll( int x_pos, int y_pos ) { - if (!m_targetWindow) - return; + wxASSERT_MSG( m_targetWindow != 0, _T("No target window") ); if (((x_pos == -1) || (x_pos == m_xScrollPosition)) && ((y_pos == -1) || (y_pos == m_yScrollPosition))) return; @@ -565,8 +566,7 @@ void wxScrolledWindow::Scroll( int x_pos, int y_pos ) void wxScrolledWindow::GtkVScroll( float value, unsigned int scroll_type ) { - if (!m_targetWindow) - return; + wxASSERT_MSG( m_targetWindow != 0, _T("No target window") ); if (m_yScrollPixelsPerLine == 0) return; @@ -585,8 +585,7 @@ void wxScrolledWindow::GtkVScroll( float value, unsigned int scroll_type ) void wxScrolledWindow::GtkHScroll( float value, unsigned int scroll_type ) { - if (!m_targetWindow) - return; + wxASSERT_MSG( m_targetWindow != 0, _T("No target window") ); if (m_xScrollPixelsPerLine == 0) return; @@ -609,28 +608,6 @@ void wxScrolledWindow::EnableScrolling (bool x_scroll, bool y_scroll) m_yScrollingEnabled = y_scroll; } -void wxScrolledWindow::GetVirtualSize (int *x, int *y) const -{ - wxSize sz(0, 0); - if (m_targetWindow) - sz = m_targetWindow->GetClientSize(); - - if ( x ) - { - if (m_xScrollPixelsPerLine == 0) - *x = sz.x; - else - *x = m_xScrollPixelsPerLine * m_xScrollLines; - } - if ( y ) - { - if (m_yScrollPixelsPerLine == 0) - *y = sz.y; - else - *y = m_yScrollPixelsPerLine * m_yScrollLines; - } -} - // Where the current view starts from void wxScrolledWindow::GetViewStart (int *x, int *y) const { @@ -672,9 +649,9 @@ int wxScrolledWindow::CalcScrollInc(wxScrollWinEvent& event) if (event.GetEventType() == wxEVT_SCROLLWIN_BOTTOM) { if (orient == wxHORIZONTAL) - nScrollInc = m_xScrollLines - m_xScrollPosition; + nScrollInc = GetVirtualSize().GetWidth() / m_xScrollPixelsPerLine - m_xScrollPosition; else - nScrollInc = m_yScrollLines - m_yScrollPosition; + nScrollInc = GetVirtualSize().GetHeight() / m_yScrollPixelsPerLine - m_yScrollPosition; } else if (event.GetEventType() == wxEVT_SCROLLWIN_LINEUP) { @@ -813,12 +790,13 @@ void wxScrolledWindow::GtkVDisconnectEvent() (GtkSignalFunc) gtk_scrolled_window_vscroll_callback, (gpointer) this ); } - bool wxScrolledWindow::Layout() { - if (GetSizer()) + if (GetSizer() && m_targetWindow == this) { - // Take into account the virtual size and scrolled position of the window + // If we're the scroll target, take into account the + // virtual size and scrolled position of the window. + int x, y, w, h; CalcScrolledPosition(0,0, &x,&y); GetVirtualSize(&w, &h); @@ -836,12 +814,15 @@ bool wxScrolledWindow::Layout() // Default OnSize resets scrollbars, if any void wxScrolledWindow::OnSize(wxSizeEvent& WXUNUSED(event)) { + if( m_targetWindow != this ) + m_targetWindow->SetVirtualSize( m_targetWindow->GetClientSize() ); + + SetVirtualSize( GetClientSize() ); + #if wxUSE_CONSTRAINTS if (GetAutoLayout()) Layout(); #endif - - AdjustScrollbars(); } // This calls OnDraw, having adjusted the origin according to the current @@ -955,3 +936,5 @@ void wxScrolledWindow::OnChar(wxKeyEvent& event) } } + +// vi:sts=4:sw=4:et diff --git a/src/gtk1/scrolwin.cpp b/src/gtk1/scrolwin.cpp index fe7bf353ea..0a5ec3f800 100644 --- a/src/gtk1/scrolwin.cpp +++ b/src/gtk1/scrolwin.cpp @@ -2,7 +2,7 @@ // Name: gtk/scrolwin.cpp // Purpose: wxScrolledWindow implementation // Author: Julian Smart -// Modified by: +// Modified by: Ron Lee // Created: 01/02/97 // RCS-ID: $Id$ // Copyright: (c) Julian Smart and Markus Holzem @@ -202,8 +202,6 @@ void wxScrolledWindow::Init() m_yScrollingEnabled = TRUE; m_xScrollPosition = 0; m_yScrollPosition = 0; - m_xScrollLines = 0; - m_yScrollLines = 0; m_xScrollLinesPerPage = 0; m_yScrollLinesPerPage = 0; m_targetWindow = (wxWindow*) NULL; @@ -323,51 +321,47 @@ bool wxScrolledWindow::Create(wxWindow *parent, // setting scrolling parameters // ---------------------------------------------------------------------------- +void wxScrolledWindow::DoSetVirtualSize( int x, int y ) +{ + wxPanel::DoSetVirtualSize( x, y ); + AdjustScrollbars(); +} + /* * 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 wxScrolledWindow::SetScrollbars( int pixelsPerUnitX, int pixelsPerUnitY, + int noUnitsX, int noUnitsY, + int xPos, int yPos, bool noRefresh ) { int old_x = m_xScrollPixelsPerLine * m_xScrollPosition; int old_y = m_yScrollPixelsPerLine * m_yScrollPosition; m_xScrollPixelsPerLine = pixelsPerUnitX; m_yScrollPixelsPerLine = pixelsPerUnitY; - m_xScrollLines = noUnitsX; - m_yScrollLines = noUnitsY; - m_xScrollPosition = xPos; - m_yScrollPosition = yPos; - m_hAdjust->lower = 0.0; - m_hAdjust->upper = noUnitsX; - m_hAdjust->value = xPos; - m_hAdjust->step_increment = 1.0; - m_hAdjust->page_increment = 2.0; + m_hAdjust->value = m_xScrollPosition = xPos; + m_vAdjust->value = m_yScrollPosition = yPos; - m_vAdjust->lower = 0.0; - m_vAdjust->upper = noUnitsY; - m_vAdjust->value = yPos; - m_vAdjust->step_increment = 1.0; - m_vAdjust->page_increment = 2.0; - - AdjustScrollbars(); + m_targetWindow->SetVirtualSizeHints( noUnitsX * pixelsPerUnitX, noUnitsY * pixelsPerUnitY ); 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 ); + m_targetWindow->ScrollWindow( old_x - new_x, old_y - new_y ); } } void wxScrolledWindow::AdjustScrollbars() { int w, h; + int vw, vh; + m_targetWindow->GetClientSize( &w, &h ); + m_targetWindow->GetVirtualSize( &vw, &vh ); if (m_xScrollPixelsPerLine == 0) { @@ -376,21 +370,18 @@ void wxScrolledWindow::AdjustScrollbars() } else { + m_hAdjust->upper = vw / m_xScrollPixelsPerLine; m_hAdjust->page_size = (w / m_xScrollPixelsPerLine); - int max = (int)(m_hAdjust->upper - m_hAdjust->page_size + 0.5); - if (max < 0) max = 0; - - int x_pos = m_xScrollPosition; - if (x_pos > max) x_pos = max; - if (x_pos < 0) x_pos = 0; - - int old_x = m_xScrollPosition; - m_xScrollPosition = x_pos; - m_hAdjust->value = x_pos; + // If the scrollbar hits the right side, move the window + // right to keep it from over extending. - if (x_pos != old_x) - m_targetWindow->ScrollWindow( (old_x-m_xScrollPosition)*m_xScrollPixelsPerLine, 0 ); + if( m_hAdjust->value + m_hAdjust->page_size > m_hAdjust->upper ) + { + m_hAdjust->value = m_hAdjust->upper - m_hAdjust->page_size; + m_targetWindow->ScrollWindow( (m_xScrollPosition - m_hAdjust->value) * m_xScrollPixelsPerLine, 0 ); + m_xScrollPosition = (int)m_hAdjust->value; + } } if (m_yScrollPixelsPerLine == 0) @@ -400,21 +391,15 @@ void wxScrolledWindow::AdjustScrollbars() } else { + m_vAdjust->upper = vh / m_yScrollPixelsPerLine; m_vAdjust->page_size = (h / m_yScrollPixelsPerLine); - int max = (int)(m_vAdjust->upper - m_vAdjust->page_size + 0.5); - if (max < 0) max = 0; - - int y_pos = m_yScrollPosition; - if (y_pos > max) y_pos = max; - if (y_pos < 0) y_pos = 0; - - int old_y = m_yScrollPosition; - m_yScrollPosition = y_pos; - m_vAdjust->value = y_pos; - - if (y_pos != old_y) - m_targetWindow->ScrollWindow( 0, (old_y-m_yScrollPosition)*m_yScrollPixelsPerLine ); + if( m_vAdjust->value + m_vAdjust->page_size > m_vAdjust->upper ) + { + m_vAdjust->value = m_vAdjust->upper - m_vAdjust->page_size; + m_targetWindow->ScrollWindow( 0, (m_yScrollPosition - m_vAdjust->value) * m_yScrollPixelsPerLine ); + m_yScrollPosition = (int)m_vAdjust->value; + } } m_xScrollLinesPerPage = (int)(m_hAdjust->page_size + 0.5); @@ -424,6 +409,7 @@ void wxScrolledWindow::AdjustScrollbars() gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "changed" ); } + // ---------------------------------------------------------------------------- // target window handling // ---------------------------------------------------------------------------- @@ -447,6 +433,22 @@ void wxScrolledWindow::PrepareDC(wxDC& dc) -m_yScrollPosition * m_yScrollPixelsPerLine ); } +void wxScrolledWindow::SetScrollRate( int xstep, int ystep ) +{ + int old_x = m_xScrollPixelsPerLine * m_xScrollPosition; + int old_y = m_yScrollPixelsPerLine * m_yScrollPosition; + + m_xScrollPixelsPerLine = xstep; + m_yScrollPixelsPerLine = ystep; + + 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 ); + + AdjustScrollbars(); +} + void wxScrolledWindow::GetScrollPixelsPerUnit (int *x_unit, int *y_unit) const { if ( x_unit ) @@ -516,8 +518,7 @@ void wxScrolledWindow::OnScroll(wxScrollWinEvent& event) void wxScrolledWindow::Scroll( int x_pos, int y_pos ) { - if (!m_targetWindow) - return; + wxASSERT_MSG( m_targetWindow != 0, _T("No target window") ); if (((x_pos == -1) || (x_pos == m_xScrollPosition)) && ((y_pos == -1) || (y_pos == m_yScrollPosition))) return; @@ -565,8 +566,7 @@ void wxScrolledWindow::Scroll( int x_pos, int y_pos ) void wxScrolledWindow::GtkVScroll( float value, unsigned int scroll_type ) { - if (!m_targetWindow) - return; + wxASSERT_MSG( m_targetWindow != 0, _T("No target window") ); if (m_yScrollPixelsPerLine == 0) return; @@ -585,8 +585,7 @@ void wxScrolledWindow::GtkVScroll( float value, unsigned int scroll_type ) void wxScrolledWindow::GtkHScroll( float value, unsigned int scroll_type ) { - if (!m_targetWindow) - return; + wxASSERT_MSG( m_targetWindow != 0, _T("No target window") ); if (m_xScrollPixelsPerLine == 0) return; @@ -609,28 +608,6 @@ void wxScrolledWindow::EnableScrolling (bool x_scroll, bool y_scroll) m_yScrollingEnabled = y_scroll; } -void wxScrolledWindow::GetVirtualSize (int *x, int *y) const -{ - wxSize sz(0, 0); - if (m_targetWindow) - sz = m_targetWindow->GetClientSize(); - - if ( x ) - { - if (m_xScrollPixelsPerLine == 0) - *x = sz.x; - else - *x = m_xScrollPixelsPerLine * m_xScrollLines; - } - if ( y ) - { - if (m_yScrollPixelsPerLine == 0) - *y = sz.y; - else - *y = m_yScrollPixelsPerLine * m_yScrollLines; - } -} - // Where the current view starts from void wxScrolledWindow::GetViewStart (int *x, int *y) const { @@ -672,9 +649,9 @@ int wxScrolledWindow::CalcScrollInc(wxScrollWinEvent& event) if (event.GetEventType() == wxEVT_SCROLLWIN_BOTTOM) { if (orient == wxHORIZONTAL) - nScrollInc = m_xScrollLines - m_xScrollPosition; + nScrollInc = GetVirtualSize().GetWidth() / m_xScrollPixelsPerLine - m_xScrollPosition; else - nScrollInc = m_yScrollLines - m_yScrollPosition; + nScrollInc = GetVirtualSize().GetHeight() / m_yScrollPixelsPerLine - m_yScrollPosition; } else if (event.GetEventType() == wxEVT_SCROLLWIN_LINEUP) { @@ -813,12 +790,13 @@ void wxScrolledWindow::GtkVDisconnectEvent() (GtkSignalFunc) gtk_scrolled_window_vscroll_callback, (gpointer) this ); } - bool wxScrolledWindow::Layout() { - if (GetSizer()) + if (GetSizer() && m_targetWindow == this) { - // Take into account the virtual size and scrolled position of the window + // If we're the scroll target, take into account the + // virtual size and scrolled position of the window. + int x, y, w, h; CalcScrolledPosition(0,0, &x,&y); GetVirtualSize(&w, &h); @@ -836,12 +814,15 @@ bool wxScrolledWindow::Layout() // Default OnSize resets scrollbars, if any void wxScrolledWindow::OnSize(wxSizeEvent& WXUNUSED(event)) { + if( m_targetWindow != this ) + m_targetWindow->SetVirtualSize( m_targetWindow->GetClientSize() ); + + SetVirtualSize( GetClientSize() ); + #if wxUSE_CONSTRAINTS if (GetAutoLayout()) Layout(); #endif - - AdjustScrollbars(); } // This calls OnDraw, having adjusted the origin according to the current @@ -955,3 +936,5 @@ void wxScrolledWindow::OnChar(wxKeyEvent& event) } } + +// vi:sts=4:sw=4:et diff --git a/src/msw/textctrl.cpp b/src/msw/textctrl.cpp index 1a0b6c5f40..2e7893955d 100644 --- a/src/msw/textctrl.cpp +++ b/src/msw/textctrl.cpp @@ -701,8 +701,8 @@ bool wxTextCtrl::EmulateKeyPress(const wxKeyEvent& event) size_t lenOld = GetValue().length(); wxUint32 code = event.GetRawKeyCode(); - ::keybd_event(code, 0, 0 /* key press */, NULL); - ::keybd_event(code, 0, KEYEVENTF_KEYUP, NULL); + ::keybd_event(code, 0, 0 /* key press */, 0); + ::keybd_event(code, 0, KEYEVENTF_KEYUP, 0); // assume that any alphanumeric key changes the total number of characters // in the control - this should work in 99% of cases