#include "wx/window.h"
#include "wx/panel.h"
-extern WXDLLEXPORT_DATA(const wxChar*) wxPanelNameStr;
-
-// default scrolled window style
-#ifndef wxScrolledWindowStyle
- #define wxScrolledWindowStyle (wxHSCROLL | wxVSCROLL)
-#endif
-
// ----------------------------------------------------------------------------
// wxGenericScrolledWindow
// ----------------------------------------------------------------------------
-class WXDLLEXPORT wxGenericScrolledWindow : public wxPanel,
- public wxScrollHelper
-{
-public:
- wxGenericScrolledWindow() : wxScrollHelper(this) { }
- wxGenericScrolledWindow(wxWindow *parent,
- wxWindowID winid = wxID_ANY,
- const wxPoint& pos = wxDefaultPosition,
- const wxSize& size = wxDefaultSize,
- long style = wxScrolledWindowStyle,
- const wxString& name = wxPanelNameStr)
- : wxScrollHelper(this)
- {
- Create(parent, winid, pos, size, style, name);
- }
-
- virtual ~wxGenericScrolledWindow();
-
- bool Create(wxWindow *parent,
- wxWindowID winid,
- const wxPoint& pos = wxDefaultPosition,
- const wxSize& size = wxDefaultSize,
- long style = wxScrolledWindowStyle,
- const wxString& name = wxPanelNameStr);
-
- virtual void PrepareDC(wxDC& dc) { DoPrepareDC(dc); }
-
- // lay out the window and its children
- virtual bool Layout();
-
- virtual void DoSetVirtualSize(int x, int y);
-
- // wxWindow's GetBestVirtualSize returns the actual window size,
- // whereas we want to return the virtual size
- virtual wxSize GetBestVirtualSize() const;
-
- // Return the size best suited for the current window
- // (this isn't a virtual size, this is a sensible size for the window)
- virtual wxSize DoGetBestSize() const;
-
-protected:
- // this is needed for wxEVT_PAINT processing hack described in
- // wxScrollHelperEvtHandler::ProcessEvent()
- void OnPaint(wxPaintEvent& event);
-
- // we need to return a special WM_GETDLGCODE value to process just the
- // arrows but let the other navigation characters through
-#ifdef __WXMSW__
- virtual WXLRESULT MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam);
-#endif // __WXMSW__
-
-private:
- DECLARE_DYNAMIC_CLASS_NO_COPY(wxGenericScrolledWindow)
- DECLARE_EVENT_TABLE()
-};
-
#endif // _WX_GENERIC_SCROLLWIN_H_
// Name: wx/gtk/scrolwin.h
// Purpose: wxScrolledWindow class
// Author: Robert Roebling
-// Modified by:
+// Modified by: Vadim Zeitlin (2005-10-10): wxScrolledWindow is now common
// Created: 01/02/97
// RCS-ID: $Id$
// Copyright: (c) Robert Roebling
#ifndef _WX_GTK_SCROLLWIN_H_
#define _WX_GTK_SCROLLWIN_H_
-// ----------------------------------------------------------------------------
-// headers and constants
-// ----------------------------------------------------------------------------
-
-#include "wx/window.h"
-#include "wx/panel.h"
-
-WXDLLEXPORT_DATA(extern const wxChar*) wxPanelNameStr;
-
-// default scrolled window style
-#ifndef wxScrolledWindowStyle
-#define wxScrolledWindowStyle (wxHSCROLL | wxVSCROLL)
-#endif
-
// ----------------------------------------------------------------------------
// wxScrolledWindow
// ----------------------------------------------------------------------------
-class WXDLLEXPORT wxScrolledWindow : public wxPanel
+class WXDLLEXPORT wxScrollHelperNative : public wxScrollHelper
{
public:
- wxScrolledWindow()
- { Init(); }
-
- wxScrolledWindow(wxWindow *parent,
- wxWindowID id = -1,
- const wxPoint& pos = wxDefaultPosition,
- const wxSize& size = wxDefaultSize,
- long style = wxScrolledWindowStyle,
- const wxString& name = wxPanelNameStr)
- { Create(parent, id, pos, size, style, name); }
-
- void Init();
-
- bool Create(wxWindow *parent,
- wxWindowID id,
- const wxPoint& pos = wxDefaultPosition,
- const wxSize& size = wxDefaultSize,
- long style = wxScrolledWindowStyle,
- const wxString& name = wxPanelNameStr);
+ // default ctor doesn't do anything
+ wxScrollHelperNative(wxWindow *win) : wxScrollHelper(win) { }
- // Normally the wxScrolledWindow will scroll itself, but in
- // some rare occasions you might want it to scroll another
- // window (e.g. a child of it in order to scroll only a portion
- // the area between the scrollbars (spreadsheet: only cell area
- // will move).
- virtual void SetTargetWindow( wxWindow *target, bool pushEventHandler = FALSE );
- virtual wxWindow *GetTargetWindow() const;
-
- // Set the scrolled area of the window.
- virtual void DoSetVirtualSize( int x, int y );
-
- // wxWindow's GetBestVirtualSize returns the actual window size,
- // whereas we want to return the virtual size
- virtual wxSize GetBestVirtualSize() const;
-
- // Return the size best suited for the current window
- // (this isn't a virtual size, this is a sensible size for the window)
- virtual wxSize DoGetBestSize() const;
-
- // 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,
- bool noRefresh = FALSE );
-
- // Physically scroll the window
- virtual void Scroll(int x_pos, int y_pos);
-
- int GetScrollPageSize(int orient) const;
- void SetScrollPageSize(int orient, int pageSize);
-
- virtual void GetScrollPixelsPerUnit(int *x_unit, int *y_unit) const;
-
- // Enable/disable Windows scrolling in either direction.
- // If TRUE, wxWidgets scrolls the canvas and only a bit of
- // the canvas is invalidated; no Clear() is necessary.
- // If FALSE, the whole canvas is invalidated and a Clear() is
- // necessary. Disable for when the scroll increment is used
- // to actually scroll a non-constant distance
- virtual void EnableScrolling(bool x_scrolling, bool y_scrolling);
-
- // Get the view start
- virtual void GetViewStart(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); }
- wxPoint CalcScrolledPosition(const wxPoint& pt) const
- {
- wxPoint p2;
- DoCalcScrolledPosition(pt.x, pt.y, &p2.x, &p2.y);
- return p2;
- }
-
- void CalcUnscrolledPosition(int x, int y, int *xx, int *yy) const
- { DoCalcUnscrolledPosition(x, y, xx, yy); }
- wxPoint CalcUnscrolledPosition(const wxPoint& pt) const
- {
- wxPoint p2;
- DoCalcUnscrolledPosition(pt.x, pt.y, &p2.x, &p2.y);
- return p2;
- }
-
- virtual void DoCalcScrolledPosition(int x, int y, int *xx, int *yy) const;
- virtual void DoCalcUnscrolledPosition(int x, int y, int *xx, int *yy) const;
-
- // Override this function to draw the graphic (or just process EVT_PAINT)
- virtual void OnDraw(wxDC& WXUNUSED(dc)) {}
-
- // Override this function if you don't want to have wxScrolledWindow
- // automatically change the origin according to the scroll position.
- void PrepareDC(wxDC& dc) { DoPrepareDC(dc); }
-
- // lay out the window and its children
- virtual bool Layout();
-
- // Adjust the scrollbars
+ int noUnitsX, int noUnitsY,
+ int xPos = 0, int yPos = 0,
+ bool noRefresh = false);
virtual void AdjustScrollbars();
-
- // 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; }
- double GetScaleY() const { return m_scaleY; }
-
- // implementation from now on
- void OnScroll(wxScrollWinEvent& event);
- void OnSize(wxSizeEvent& event);
- void OnPaint(wxPaintEvent& event);
- void OnChar(wxKeyEvent& event);
-
- void GtkVScroll( float value, unsigned int scroll_type );
- void GtkHScroll( float value, unsigned int scroll_type );
- void GtkVConnectEvent();
- void GtkHConnectEvent();
- void GtkVDisconnectEvent();
- void GtkHDisconnectEvent();
-
- // Calculate scroll increment
- virtual int CalcScrollInc(wxScrollWinEvent& event);
-
- // Overridden from wxWidgets due callback being static
- virtual void SetScrollPos( int orient, int pos, bool refresh = TRUE );
-
- virtual void DoPrepareDC(wxDC& dc);
+ virtual void Scroll(int x, int y);
protected:
- wxWindow *m_targetWindow;
- int m_xScrollPixelsPerLine;
- 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_xScrollLinesPerPage;
- int m_yScrollLinesPerPage;
-
- double m_scaleY,m_scaleX;
+ // this does (each) half of AdjustScrollbars() work
+ void DoAdjustScrollbar(GtkAdjustment *adj,
+ int pixelsPerLine,
+ int winSize,
+ int virtSize,
+ int *pos,
+ int *lines,
+ int *linesPerPage);
+
+ // and this does the same for Scroll()
+ void DoScroll(int orient,
+ GtkAdjustment *adj,
+ int pos,
+ int pixelsPerLine,
+ int *posOld);
private:
- DECLARE_EVENT_TABLE()
- DECLARE_DYNAMIC_CLASS(wxScrolledWindow)
+ DECLARE_NO_COPY_CLASS(wxScrollHelperNative)
};
-#endif
- // _WX_GTK_SCROLLWIN_H_
+#endif // _WX_GTK_SCROLLWIN_H_
-// vi:sts=4:sw=4:et
// Name: wx/gtk/scrolwin.h
// Purpose: wxScrolledWindow class
// Author: Robert Roebling
-// Modified by:
+// Modified by: Vadim Zeitlin (2005-10-10): wxScrolledWindow is now common
// Created: 01/02/97
// RCS-ID: $Id$
// Copyright: (c) Robert Roebling
#ifndef _WX_GTK_SCROLLWIN_H_
#define _WX_GTK_SCROLLWIN_H_
-// ----------------------------------------------------------------------------
-// headers and constants
-// ----------------------------------------------------------------------------
-
-#include "wx/window.h"
-#include "wx/panel.h"
-
-WXDLLEXPORT_DATA(extern const wxChar*) wxPanelNameStr;
-
-// default scrolled window style
-#ifndef wxScrolledWindowStyle
-#define wxScrolledWindowStyle (wxHSCROLL | wxVSCROLL)
-#endif
-
// ----------------------------------------------------------------------------
// wxScrolledWindow
// ----------------------------------------------------------------------------
-class WXDLLEXPORT wxScrolledWindow : public wxPanel
+class WXDLLEXPORT wxScrollHelperNative : public wxScrollHelper
{
public:
- wxScrolledWindow()
- { Init(); }
-
- wxScrolledWindow(wxWindow *parent,
- wxWindowID id = -1,
- const wxPoint& pos = wxDefaultPosition,
- const wxSize& size = wxDefaultSize,
- long style = wxScrolledWindowStyle,
- const wxString& name = wxPanelNameStr)
- { Create(parent, id, pos, size, style, name); }
-
- void Init();
-
- bool Create(wxWindow *parent,
- wxWindowID id,
- const wxPoint& pos = wxDefaultPosition,
- const wxSize& size = wxDefaultSize,
- long style = wxScrolledWindowStyle,
- const wxString& name = wxPanelNameStr);
+ // default ctor doesn't do anything
+ wxScrollHelperNative(wxWindow *win) : wxScrollHelper(win) { }
- // Normally the wxScrolledWindow will scroll itself, but in
- // some rare occasions you might want it to scroll another
- // window (e.g. a child of it in order to scroll only a portion
- // the area between the scrollbars (spreadsheet: only cell area
- // will move).
- virtual void SetTargetWindow( wxWindow *target, bool pushEventHandler = FALSE );
- virtual wxWindow *GetTargetWindow() const;
-
- // Set the scrolled area of the window.
- virtual void DoSetVirtualSize( int x, int y );
-
- // wxWindow's GetBestVirtualSize returns the actual window size,
- // whereas we want to return the virtual size
- virtual wxSize GetBestVirtualSize() const;
-
- // Return the size best suited for the current window
- // (this isn't a virtual size, this is a sensible size for the window)
- virtual wxSize DoGetBestSize() const;
-
- // 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,
- bool noRefresh = FALSE );
-
- // Physically scroll the window
- virtual void Scroll(int x_pos, int y_pos);
-
- int GetScrollPageSize(int orient) const;
- void SetScrollPageSize(int orient, int pageSize);
-
- virtual void GetScrollPixelsPerUnit(int *x_unit, int *y_unit) const;
-
- // Enable/disable Windows scrolling in either direction.
- // If TRUE, wxWidgets scrolls the canvas and only a bit of
- // the canvas is invalidated; no Clear() is necessary.
- // If FALSE, the whole canvas is invalidated and a Clear() is
- // necessary. Disable for when the scroll increment is used
- // to actually scroll a non-constant distance
- virtual void EnableScrolling(bool x_scrolling, bool y_scrolling);
-
- // Get the view start
- virtual void GetViewStart(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); }
- wxPoint CalcScrolledPosition(const wxPoint& pt) const
- {
- wxPoint p2;
- DoCalcScrolledPosition(pt.x, pt.y, &p2.x, &p2.y);
- return p2;
- }
-
- void CalcUnscrolledPosition(int x, int y, int *xx, int *yy) const
- { DoCalcUnscrolledPosition(x, y, xx, yy); }
- wxPoint CalcUnscrolledPosition(const wxPoint& pt) const
- {
- wxPoint p2;
- DoCalcUnscrolledPosition(pt.x, pt.y, &p2.x, &p2.y);
- return p2;
- }
-
- virtual void DoCalcScrolledPosition(int x, int y, int *xx, int *yy) const;
- virtual void DoCalcUnscrolledPosition(int x, int y, int *xx, int *yy) const;
-
- // Override this function to draw the graphic (or just process EVT_PAINT)
- virtual void OnDraw(wxDC& WXUNUSED(dc)) {}
-
- // Override this function if you don't want to have wxScrolledWindow
- // automatically change the origin according to the scroll position.
- void PrepareDC(wxDC& dc) { DoPrepareDC(dc); }
-
- // lay out the window and its children
- virtual bool Layout();
-
- // Adjust the scrollbars
+ int noUnitsX, int noUnitsY,
+ int xPos = 0, int yPos = 0,
+ bool noRefresh = false);
virtual void AdjustScrollbars();
-
- // 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; }
- double GetScaleY() const { return m_scaleY; }
-
- // implementation from now on
- void OnScroll(wxScrollWinEvent& event);
- void OnSize(wxSizeEvent& event);
- void OnPaint(wxPaintEvent& event);
- void OnChar(wxKeyEvent& event);
-
- void GtkVScroll( float value, unsigned int scroll_type );
- void GtkHScroll( float value, unsigned int scroll_type );
- void GtkVConnectEvent();
- void GtkHConnectEvent();
- void GtkVDisconnectEvent();
- void GtkHDisconnectEvent();
-
- // Calculate scroll increment
- virtual int CalcScrollInc(wxScrollWinEvent& event);
-
- // Overridden from wxWidgets due callback being static
- virtual void SetScrollPos( int orient, int pos, bool refresh = TRUE );
-
- virtual void DoPrepareDC(wxDC& dc);
+ virtual void Scroll(int x, int y);
protected:
- wxWindow *m_targetWindow;
- int m_xScrollPixelsPerLine;
- 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_xScrollLinesPerPage;
- int m_yScrollLinesPerPage;
-
- double m_scaleY,m_scaleX;
+ // this does (each) half of AdjustScrollbars() work
+ void DoAdjustScrollbar(GtkAdjustment *adj,
+ int pixelsPerLine,
+ int winSize,
+ int virtSize,
+ int *pos,
+ int *lines,
+ int *linesPerPage);
+
+ // and this does the same for Scroll()
+ void DoScroll(int orient,
+ GtkAdjustment *adj,
+ int pos,
+ int pixelsPerLine,
+ int *posOld);
private:
- DECLARE_EVENT_TABLE()
- DECLARE_DYNAMIC_CLASS(wxScrolledWindow)
+ DECLARE_NO_COPY_CLASS(wxScrollHelperNative)
};
-#endif
- // _WX_GTK_SCROLLWIN_H_
+#endif // _WX_GTK_SCROLLWIN_H_
-// vi:sts=4:sw=4:et
class WXDLLEXPORT wxScrollHelperEvtHandler;
class WXDLLEXPORT wxTimer;
+WXDLLEXPORT_DATA(extern const wxChar*) wxPanelNameStr;
+
+// default scrolled window style: scroll in both directions
+#define wxScrolledWindowStyle (wxHSCROLL | wxVSCROLL)
+
// ----------------------------------------------------------------------------
-// wxScrollHelper: this class implements the scrolling logic which is used by
-// wxScrolledWindow and wxScrolledControl. It is a mix-in: just derive from it
-// to implement scrolling in your class.
+// The hierarchy of scrolling classes is a bit complicated because we want to
+// put as much functionality as possible in a mix-in class not deriving from
+// wxWindow so that other classes could derive from the same base class on all
+// platforms irrespectively of whether they are native controls (and hence
+// don't use our scrolling) or not.
+//
+// So we have
+//
+// wxScrollHelper
+// |
+// |
+// \|/
+// wxWindow wxScrollHelperNative
+// | \ / /
+// | \ / /
+// | _| |_ /
+// | wxScrolledWindow /
+// | /
+// \|/ /
+// wxControl /
+// \ /
+// \ /
+// _| |_
+// wxScrolledControl
+//
// ----------------------------------------------------------------------------
-#if !defined(__WXGTK__) || defined(__WXUNIVERSAL__)
class WXDLLEXPORT wxScrollHelper
{
public:
- // ctor and dtor
- wxScrollHelper(wxWindow *winToScroll = (wxWindow *)NULL);
- void SetWindow(wxWindow *winToScroll);
+ // ctor must be given the associated window
+ wxScrollHelper(wxWindow *winToScroll);
virtual ~wxScrollHelper();
// configure the scrolling
*h = size.y;
}
+ // implementations of various wxWindow virtual methods which should be
+ // forwarded to us (this can be done by WX_FORWARD_TO_SCROLL_HELPER())
+ bool ScrollLayout();
+ void ScrollDoSetVirtualSize(int x, int y);
+ wxSize ScrollGetBestVirtualSize() const;
+ wxSize ScrollGetWindowSizeForVirtualSize(const wxSize& size) const;
+
// change just the target window (unlike SetWindow which changes m_win as
// well)
void DoSetTargetWindow(wxWindow *target);
// delete the event handler we installed
void DeleteEvtHandler();
+
double m_scaleX;
double m_scaleY;
DECLARE_NO_COPY_CLASS(wxScrollHelper)
};
+// this macro can be used in a wxScrollHelper-derived class to forward wxWindow
+// methods to corresponding wxScrollHelper methods
+#define WX_FORWARD_TO_SCROLL_HELPER() \
+ virtual void PrepareDC(wxDC& dc) { DoPrepareDC(dc); } \
+ virtual bool Layout() { return ScrollLayout(); } \
+ virtual void DoSetVirtualSize(int x, int y) \
+ { ScrollDoSetVirtualSize(x, y); } \
+ virtual wxSize GetBestVirtualSize() const \
+ { return ScrollGetBestVirtualSize(); } \
+ virtual wxSize GetWindowSizeForVirtualSize(const wxSize& size) const \
+ { return ScrollGetWindowSizeForVirtualSize(size); }
+
+// include the declaration of wxScrollHelperNative if needed
+#if defined(__WXGTK__) && !defined(__WXUNIVERSAL__)
+ #include "wx/gtk/scrolwin.h"
+#else
+ typedef wxScrollHelper wxScrollHelperNative;
#endif
// ----------------------------------------------------------------------------
// wxScrolledWindow: a wxWindow which knows how to scroll
// ----------------------------------------------------------------------------
-#if defined(__WXGTK__) && !defined(__WXUNIVERSAL__)
- #include "wx/gtk/scrolwin.h"
-#else // !wxGTK
- #include "wx/generic/scrolwin.h"
-
- class WXDLLEXPORT wxScrolledWindow : public wxGenericScrolledWindow
+class WXDLLEXPORT wxScrolledWindow : public wxPanel,
+ public wxScrollHelperNative
+{
+public:
+ wxScrolledWindow() : wxScrollHelperNative(this) { }
+ wxScrolledWindow(wxWindow *parent,
+ wxWindowID winid = wxID_ANY,
+ const wxPoint& pos = wxDefaultPosition,
+ const wxSize& size = wxDefaultSize,
+ long style = wxScrolledWindowStyle,
+ const wxString& name = wxPanelNameStr)
+ : wxScrollHelperNative(this)
{
- public:
- wxScrolledWindow() { }
- wxScrolledWindow(wxWindow *parent,
- wxWindowID winid = wxID_ANY,
- const wxPoint& pos = wxDefaultPosition,
- const wxSize& size = wxDefaultSize,
- long style = wxScrolledWindowStyle,
- const wxString& name = wxPanelNameStr)
- : wxGenericScrolledWindow(parent, winid, pos, size, style, name)
- {
- }
-
- private:
- DECLARE_DYNAMIC_CLASS_NO_COPY(wxScrolledWindow)
- };
-
- #define wxSCROLLED_WINDOW_IS_GENERIC 1
-#endif
+ Create(parent, winid, pos, size, style, name);
+ }
-#endif
- // _WX_SCROLWIN_H_BASE_
+ virtual ~wxScrolledWindow();
+
+ bool Create(wxWindow *parent,
+ wxWindowID winid,
+ const wxPoint& pos = wxDefaultPosition,
+ const wxSize& size = wxDefaultSize,
+ long style = wxScrolledWindowStyle,
+ const wxString& name = wxPanelNameStr);
+
+ WX_FORWARD_TO_SCROLL_HELPER()
+
+protected:
+ // this is needed for wxEVT_PAINT processing hack described in
+ // wxScrollHelperEvtHandler::ProcessEvent()
+ void OnPaint(wxPaintEvent& event);
+
+ // we need to return a special WM_GETDLGCODE value to process just the
+ // arrows but let the other navigation characters through
+#ifdef __WXMSW__
+ virtual WXLRESULT MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam);
+#endif // __WXMSW__
+
+private:
+ DECLARE_DYNAMIC_CLASS_NO_COPY(wxScrolledWindow)
+ DECLARE_EVENT_TABLE()
+};
+
+#endif // _WX_SCROLWIN_H_BASE_
/////////////////////////////////////////////////////////////////////////////
// Name: generic/scrolwin.cpp
-// Purpose: wxGenericScrolledWindow implementation
+// Purpose: wxScrolledWindow implementation
// Author: Julian Smart
// Modified by: Vadim Zeitlin on 31.08.00: wxScrollHelper allows to implement.
// Ron Lee on 10.4.02: virtual size / auto scrollbars et al.
#pragma hdrstop
#endif
-#if !defined(__WXGTK__) || defined(__WXUNIVERSAL__)
-
#include "wx/utils.h"
#include "wx/dcclient.h"
#endif
#endif
-IMPLEMENT_CLASS(wxScrolledWindow, wxGenericScrolledWindow)
-
/*
TODO PROPERTIES
style wxHSCROLL | wxVSCROLL
wxScrollHelper::wxScrollHelper(wxWindow *win)
{
+ wxASSERT_MSG( win, _T("associated window can't be NULL in wxScrollHelper") );
+
m_xScrollPixelsPerLine =
m_yScrollPixelsPerLine =
m_xScrollPosition =
m_handler = NULL;
- if ( win )
- SetWindow(win);
+ m_win = win;
+
+ // by default, the associated window is also the target window
+ DoSetTargetWindow(win);
}
wxScrollHelper::~wxScrollHelper()
}
}
-void wxScrollHelper::SetWindow(wxWindow *win)
-{
- wxCHECK_RET( win, _T("wxScrollHelper needs a window to scroll") );
-
- m_win = win;
-
- // by default, the associated window is also the target window
- DoSetTargetWindow(win);
-}
-
void wxScrollHelper::DoSetTargetWindow(wxWindow *target)
{
m_targetWindow = target;
do
{
iterationCount ++;
-
+
GetTargetSize(&w, 0);
// scroll lines per page: if 0, no scrolling is needed
*yy = y + m_yScrollPosition * m_yScrollPixelsPerLine;
}
+// ----------------------------------------------------------------------------
+// geometry
+// ----------------------------------------------------------------------------
+
+bool wxScrollHelper::ScrollLayout()
+{
+ if ( m_win->GetSizer() && m_targetWindow == m_win )
+ {
+ // 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);
+ m_win->GetVirtualSize(&w, &h);
+ m_win->GetSizer()->SetDimension(x, y, w, h);
+ return true;
+ }
+
+ // fall back to default for LayoutConstraints
+ return m_win->wxWindow::Layout();
+}
+
+void wxScrollHelper::ScrollDoSetVirtualSize(int x, int y)
+{
+ m_win->wxWindow::DoSetVirtualSize( x, y );
+ AdjustScrollbars();
+
+ if (m_win->GetAutoLayout())
+ m_win->Layout();
+}
+
+// wxWindow's GetBestVirtualSize returns the actual window size,
+// whereas we want to return the virtual size
+wxSize wxScrollHelper::ScrollGetBestVirtualSize() const
+{
+ wxSize clientSize(m_win->GetClientSize());
+ if ( m_win->GetSizer() )
+ clientSize.IncTo(m_win->GetSizer()->CalcMin());
+
+ return clientSize;
+}
+
+// return the window best size from the given best virtual size
+wxSize
+wxScrollHelper::ScrollGetWindowSizeForVirtualSize(const wxSize& size) const
+{
+ // Only use the content to set the window size in the direction
+ // where there's no scrolling; otherwise we're going to get a huge
+ // window in the direction in which scrolling is enabled
+ int ppuX, ppuY;
+ GetScrollPixelsPerUnit(&ppuX, &ppuY);
+
+ wxSize minSize = m_win->GetMinSize();
+ if ( !minSize.IsFullySpecified() )
+ minSize = m_win->GetSize();
+
+ wxSize best(size);
+ if (ppuX > 0)
+ best.x = minSize.x;
+ if (ppuY > 0)
+ best.y = minSize.y;
+
+ return best;
+}
+
// ----------------------------------------------------------------------------
// event handlers
// ----------------------------------------------------------------------------
if ( m_targetWindow->GetAutoLayout() )
{
wxSize size = m_targetWindow->GetBestVirtualSize();
-
+
// This will call ::Layout() and ::AdjustScrollbars()
m_win->SetVirtualSize( size );
}
#endif // wxUSE_MOUSEWHEEL
// ----------------------------------------------------------------------------
-// wxGenericScrolledWindow implementation
+// wxScrolledWindow implementation
// ----------------------------------------------------------------------------
-IMPLEMENT_DYNAMIC_CLASS(wxGenericScrolledWindow, wxPanel)
+IMPLEMENT_DYNAMIC_CLASS(wxScrolledWindow, wxPanel)
-BEGIN_EVENT_TABLE(wxGenericScrolledWindow, wxPanel)
- EVT_PAINT(wxGenericScrolledWindow::OnPaint)
+BEGIN_EVENT_TABLE(wxScrolledWindow, wxPanel)
+ EVT_PAINT(wxScrolledWindow::OnPaint)
END_EVENT_TABLE()
-bool wxGenericScrolledWindow::Create(wxWindow *parent,
+bool wxScrolledWindow::Create(wxWindow *parent,
wxWindowID id,
const wxPoint& pos,
const wxSize& size,
return ok;
}
-wxGenericScrolledWindow::~wxGenericScrolledWindow()
+wxScrolledWindow::~wxScrolledWindow()
{
}
-bool wxGenericScrolledWindow::Layout()
-{
- if (GetSizer() && m_targetWindow == this)
- {
- // 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);
- GetSizer()->SetDimension(x, y, w, h);
- return true;
- }
-
- // fall back to default for LayoutConstraints
- return wxPanel::Layout();
-}
-
-void wxGenericScrolledWindow::DoSetVirtualSize(int x, int y)
-{
- wxPanel::DoSetVirtualSize( x, y );
- AdjustScrollbars();
-
- if (GetAutoLayout())
- Layout();
-}
-
-// wxWindow's GetBestVirtualSize returns the actual window size,
-// whereas we want to return the virtual size
-wxSize wxGenericScrolledWindow::GetBestVirtualSize() const
-{
- wxSize clientSize( GetClientSize() );
- if (GetSizer())
- {
- wxSize minSize( GetSizer()->CalcMin() );
-
- return wxSize( wxMax( clientSize.x, minSize.x ), wxMax( clientSize.y, minSize.y ) );
- }
- else
- return clientSize;
-}
-
-// return the size best suited for the current window
-// (this isn't a virtual size, this is a sensible size for the window)
-wxSize wxGenericScrolledWindow::DoGetBestSize() const
-{
- wxSize best;
-
- if ( GetSizer() )
- {
- wxSize b = GetSizer()->GetMinSize();
-
- // Only use the content to set the window size in the direction
- // where there's no scrolling; otherwise we're going to get a huge
- // window in the direction in which scrolling is enabled
- int ppuX, ppuY;
- GetScrollPixelsPerUnit(& ppuX, & ppuY);
-
- wxSize minSize;
- if ( GetMinSize().IsFullySpecified() )
- minSize = GetMinSize();
- else
- minSize = GetSize();
-
- if (ppuX > 0)
- b.x = minSize.x;
- if (ppuY > 0)
- b.y = minSize.y;
- best = b;
- }
- else
- return wxWindow::DoGetBestSize();
-
- // Add any difference between size and client size
- wxSize diff = GetSize() - GetClientSize();
- best.x += wxMax(0, diff.x);
- best.y += wxMax(0, diff.y);
-
- return best;
-}
-
-void wxGenericScrolledWindow::OnPaint(wxPaintEvent& event)
+void wxScrolledWindow::OnPaint(wxPaintEvent& event)
{
// the user code didn't really draw the window if we got here, so set this
// flag to try to call OnDraw() later
}
#ifdef __WXMSW__
-WXLRESULT
-wxGenericScrolledWindow::MSWWindowProc(WXUINT nMsg,
+WXLRESULT wxScrolledWindow::MSWWindowProc(WXUINT nMsg,
WXWPARAM wParam,
WXLPARAM lParam)
{
#endif // __WXMSW__
-#endif // !wxGTK
-
-// vi:sts=4:sw=4:et
// 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
#endif
#include "wx/scrolwin.h"
-#include "wx/utils.h"
-#include "wx/dcclient.h"
-#include "wx/panel.h"
-#include "wx/sizer.h"
-#include "wx/math.h"
-
#include "wx/gtk/private.h"
-#include "wx/gtk/win_gtk.h"
-
-// ----------------------------------------------------------------------------
-// event tables
-// ----------------------------------------------------------------------------
-
-BEGIN_EVENT_TABLE(wxScrolledWindow, wxPanel)
- EVT_SCROLLWIN(wxScrolledWindow::OnScroll)
- EVT_SIZE(wxScrolledWindow::OnSize)
- EVT_PAINT(wxScrolledWindow::OnPaint)
- EVT_CHAR(wxScrolledWindow::OnChar)
-END_EVENT_TABLE()
-
-IMPLEMENT_DYNAMIC_CLASS(wxScrolledWindow, wxPanel)
// ============================================================================
// implementation
// ============================================================================
-//-----------------------------------------------------------------------------
-// data
-//-----------------------------------------------------------------------------
-
-extern bool g_blockEventsOnDrag;
-extern bool g_blockEventsOnScroll;
-
-//-----------------------------------------------------------------------------
-// idle system
-//-----------------------------------------------------------------------------
-
-extern void wxapp_install_idle_handler();
-extern bool g_isIdle;
-
-//-----------------------------------------------------------------------------
-// "value_changed" from m_vAdjust
-//-----------------------------------------------------------------------------
-
-extern "C" {
-static void gtk_scrolled_window_vscroll_callback( GtkAdjustment *adjust,
- SCROLLBAR_CBACK_ARG
- wxScrolledWindow *win )
-{
- if (g_isIdle)
- wxapp_install_idle_handler();
-
- if (g_blockEventsOnDrag) return;
-
- if (!win->m_hasVMT) return;
-
- win->GtkVScroll( adjust->value,
- GET_SCROLL_TYPE(GTK_SCROLLED_WINDOW(win->m_widget)->vscrollbar) );
-}
-}
-
-//-----------------------------------------------------------------------------
-// "value_changed" from m_hAdjust
-//-----------------------------------------------------------------------------
-
-extern "C" {
-static void gtk_scrolled_window_hscroll_callback( GtkAdjustment *adjust,
- SCROLLBAR_CBACK_ARG
- wxScrolledWindow *win )
-{
- if (g_isIdle)
- wxapp_install_idle_handler();
-
- if (g_blockEventsOnDrag) return;
- if (!win->m_hasVMT) return;
-
- win->GtkHScroll( adjust->value,
- GET_SCROLL_TYPE(GTK_SCROLLED_WINDOW(win->m_widget)->hscrollbar) );
-}
-}
-
-//-----------------------------------------------------------------------------
-// "button_press_event" from scrollbar
-//-----------------------------------------------------------------------------
-
-extern "C" {
-static gint gtk_scrollbar_button_press_callback( GtkRange *widget,
- GdkEventButton *gdk_event,
- wxWindowGTK *win)
-{
- if (g_isIdle)
- wxapp_install_idle_handler();
-
- g_blockEventsOnScroll = TRUE;
-
- // FIXME: there is no slider field any more, what was meant here?
-#ifndef __WXGTK20__
- win->m_isScrolling = (gdk_event->window == widget->slider);
-#endif
-
- return FALSE;
-}
-}
-
-//-----------------------------------------------------------------------------
-// "button_release_event" from scrollbar
-//-----------------------------------------------------------------------------
-
-extern "C" {
-static gint gtk_scrollbar_button_release_callback( GtkRange *widget,
- GdkEventButton *WXUNUSED(gdk_event),
- wxWindowGTK *win)
-{
-// don't test here as we can release the mouse while being over
-// a different window than the slider
-//
-// if (gdk_event->window != widget->slider) return FALSE;
-
- g_blockEventsOnScroll = FALSE;
-
- if (win->m_isScrolling)
- {
- wxEventType command = wxEVT_SCROLLWIN_THUMBRELEASE;
- int value = -1;
- int dir = -1;
-
- GtkScrolledWindow *scrolledWindow = GTK_SCROLLED_WINDOW(win->m_widget);
- if (widget == GTK_RANGE(scrolledWindow->hscrollbar))
- {
- value = (int)(win->m_hAdjust->value+0.5);
- dir = wxHORIZONTAL;
- }
- if (widget == GTK_RANGE(scrolledWindow->vscrollbar))
- {
- value = (int)(win->m_vAdjust->value+0.5);
- dir = wxVERTICAL;
- }
-
- wxScrollWinEvent event( command, value, dir );
- event.SetEventObject( win );
- win->GetEventHandler()->ProcessEvent( event );
- }
-
- win->m_isScrolling = FALSE;
-
- return FALSE;
-}
-}
-
-//-----------------------------------------------------------------------------
-// InsertChild for wxScrolledWindow
-//-----------------------------------------------------------------------------
-
-static void wxInsertChildInScrolledWindow( wxWindow* parent, wxWindow* child )
-{
- // The window might have been scrolled already, do we
- // have to adapt the position.
- GtkPizza *pizza = GTK_PIZZA(parent->m_wxwindow);
- child->m_x += pizza->xoffset;
- child->m_y += pizza->yoffset;
-
- gtk_pizza_put( GTK_PIZZA(parent->m_wxwindow),
- GTK_WIDGET(child->m_widget),
- child->m_x,
- child->m_y,
- child->m_width,
- child->m_height );
-}
-
-// ----------------------------------------------------------------------------
-// wxScrolledWindow creation
-// ----------------------------------------------------------------------------
-
-void wxScrolledWindow::Init()
-{
- m_xScrollPixelsPerLine = 0;
- m_yScrollPixelsPerLine = 0;
- m_xScrollingEnabled = TRUE;
- m_yScrollingEnabled = TRUE;
- m_xScrollPosition = 0;
- m_yScrollPosition = 0;
- m_xScrollLinesPerPage = 0;
- m_yScrollLinesPerPage = 0;
- m_targetWindow = (wxWindow*) NULL;
- m_scaleX = 1.0;
- m_scaleY = 1.0;
- m_hasScrolling = TRUE;
-}
-
-bool wxScrolledWindow::Create(wxWindow *parent,
- wxWindowID id,
- const wxPoint& pos,
- const wxSize& size,
- long style,
- const wxString& name)
-{
- Init();
-
- if (!PreCreation( parent, pos, size ) ||
- !CreateBase( parent, id, pos, size, style, wxDefaultValidator, name ))
- {
- wxFAIL_MSG( wxT("wxWindow creation failed") );
- return FALSE;
- }
-
- m_insertCallback = wxInsertChildInScrolledWindow;
-
- m_targetWindow = this;
-
- m_widget = gtk_scrolled_window_new( (GtkAdjustment *) NULL, (GtkAdjustment *) NULL );
- GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS );
-
- GtkScrolledWindow *scrolledWindow = GTK_SCROLLED_WINDOW(m_widget);
-
- GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT_GET_CLASS(m_widget) );
- scroll_class->scrollbar_spacing = 0;
-
- gtk_scrolled_window_set_policy( scrolledWindow, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC );
-
- m_hAdjust = gtk_range_get_adjustment( GTK_RANGE(scrolledWindow->hscrollbar) );
- m_vAdjust = gtk_range_get_adjustment( GTK_RANGE(scrolledWindow->vscrollbar) );
-
- m_wxwindow = gtk_pizza_new();
-
- gtk_container_add( GTK_CONTAINER(m_widget), m_wxwindow );
-
- GtkPizza *pizza = GTK_PIZZA(m_wxwindow);
-
- if (HasFlag(wxRAISED_BORDER))
- {
- gtk_pizza_set_shadow_type( pizza, GTK_MYSHADOW_OUT );
- }
- else if (HasFlag(wxSUNKEN_BORDER))
- {
- gtk_pizza_set_shadow_type( pizza, GTK_MYSHADOW_IN );
- }
- else if (HasFlag(wxSIMPLE_BORDER))
- {
- gtk_pizza_set_shadow_type( pizza, GTK_MYSHADOW_THIN );
- }
- else
- {
- gtk_pizza_set_shadow_type( pizza, GTK_MYSHADOW_NONE );
- }
-
- GTK_WIDGET_SET_FLAGS( m_wxwindow, GTK_CAN_FOCUS );
- m_acceptsFocus = TRUE;
-
- // I _really_ don't want scrollbars in the beginning
- m_vAdjust->lower = 0.0;
- m_vAdjust->upper = 1.0;
- m_vAdjust->value = 0.0;
- m_vAdjust->step_increment = 1.0;
- m_vAdjust->page_increment = 2.0;
- gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust), "changed" );
- m_hAdjust->lower = 0.0;
- m_hAdjust->upper = 1.0;
- m_hAdjust->value = 0.0;
- m_hAdjust->step_increment = 1.0;
- m_hAdjust->page_increment = 2.0;
- gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "changed" );
-
- // Handlers for new scrollbar values
- GtkVConnectEvent();
- GtkHConnectEvent();
-
- // these handlers block mouse events to any window during scrolling such as
- // motion events and prevent GTK and wxWidgets from fighting over where the
- // slider should be
-
- gtk_signal_connect( GTK_OBJECT(scrolledWindow->vscrollbar), "button_press_event",
- (GtkSignalFunc)gtk_scrollbar_button_press_callback, (gpointer) this );
-
- gtk_signal_connect( GTK_OBJECT(scrolledWindow->hscrollbar), "button_press_event",
- (GtkSignalFunc)gtk_scrollbar_button_press_callback, (gpointer) this );
-
- gtk_signal_connect( GTK_OBJECT(scrolledWindow->vscrollbar), "button_release_event",
- (GtkSignalFunc)gtk_scrollbar_button_release_callback, (gpointer) this );
-
- gtk_signal_connect( GTK_OBJECT(scrolledWindow->hscrollbar), "button_release_event",
- (GtkSignalFunc)gtk_scrollbar_button_release_callback, (gpointer) this );
-
- gtk_widget_show( m_wxwindow );
-
- if (m_parent)
- m_parent->DoAddChild( this );
-
- m_focusWidget = m_wxwindow;
-
- PostCreation();
-
- Show( TRUE );
-
- return TRUE;
-}
-
// ----------------------------------------------------------------------------
-// setting scrolling parameters
+// wxScrollHelper implementation
// ----------------------------------------------------------------------------
-void wxScrolledWindow::DoSetVirtualSize( int x, int y )
-{
- wxPanel::DoSetVirtualSize( x, y );
- AdjustScrollbars();
-
- if (GetAutoLayout())
- Layout();
-}
-
-// wxWindow's GetBestVirtualSize returns the actual window size,
-// whereas we want to return the virtual size
-wxSize wxScrolledWindow::GetBestVirtualSize() const
-{
- wxSize clientSize( GetClientSize() );
- if (GetSizer())
- {
- wxSize minSize( GetSizer()->CalcMin() );
-
- return wxSize( wxMax( clientSize.x, minSize.x ), wxMax( clientSize.y, minSize.y ) );
- }
- else
- return clientSize;
-}
-
-// return the size best suited for the current window
-// (this isn't a virtual size, this is a sensible size for the window)
-wxSize wxScrolledWindow::DoGetBestSize() const
-{
- wxSize best;
-
- if ( GetSizer() )
- {
- wxSize b = GetSizer()->GetMinSize();
-
- // Only use the content to set the window size in the direction
- // where there's no scrolling; otherwise we're going to get a huge
- // window in the direction in which scrolling is enabled
- int ppuX, ppuY;
- GetScrollPixelsPerUnit(& ppuX, & ppuY);
-
- wxSize minSize;
- if ( GetMinSize().IsFullySpecified() )
- minSize = GetMinSize();
- else
- minSize = GetSize();
-
- if (ppuX > 0)
- b.x = minSize.x;
- if (ppuY > 0)
- b.y = minSize.y;
- best = b;
- }
- else
- return wxWindow::DoGetBestSize();
-
- // Add any difference between size and client size
- wxSize diff = GetSize() - GetClientSize();
- best.x += wxMax(0, diff.x);
- best.y += wxMax(0, diff.y);
-
- return best;
-}
-
-/*
- * 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 wxScrollHelperNative::SetScrollbars(int pixelsPerUnitX, int pixelsPerUnitY,
+ int noUnitsX, int noUnitsY,
+ int xPos, int yPos,
+ bool noRefresh)
{
int xs, ys;
- GetViewStart (& xs, & ys);
+ GetViewStart(& xs, & ys);
int old_x = m_xScrollPixelsPerLine * xs;
int old_y = m_yScrollPixelsPerLine * ys;
m_xScrollPixelsPerLine = pixelsPerUnitX;
m_yScrollPixelsPerLine = pixelsPerUnitY;
- m_hAdjust->value = m_xScrollPosition = xPos;
- m_vAdjust->value = m_yScrollPosition = yPos;
+ m_win->m_hAdjust->value = m_xScrollPosition = xPos;
+ m_win->m_vAdjust->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->ScrollWindow( old_x - new_x, old_y - new_y );
}
+
+ m_targetWindow->m_hasScrolling = pixelsPerUnitX || pixelsPerUnitY;
}
-void wxScrolledWindow::AdjustScrollbars()
+void wxScrollHelperNative::DoAdjustScrollbar(GtkAdjustment *adj,
+ int pixelsPerLine,
+ int winSize,
+ int virtSize,
+ int *pos,
+ int *lines,
+ int *linesPerPage)
{
- int w, h;
- int vw, vh;
-
- m_targetWindow->GetClientSize( &w, &h );
- m_targetWindow->GetVirtualSize( &vw, &vh );
-
- if (m_xScrollPixelsPerLine == 0)
+ if ( pixelsPerLine == 0 )
{
- m_hAdjust->upper = 1.0;
- m_hAdjust->page_increment = 1.0;
- m_hAdjust->page_size = 1.0;
+ adj->upper = 1.0;
+ adj->page_increment = 1.0;
+ adj->page_size = 1.0;
}
- else
+ else // we do have scrollbar
{
- m_hAdjust->upper = (vw+m_xScrollPixelsPerLine-1) / m_xScrollPixelsPerLine;
- m_hAdjust->page_size = w / m_xScrollPixelsPerLine;
- m_hAdjust->page_increment = w / m_xScrollPixelsPerLine;
+ adj->upper = (virtSize + pixelsPerLine - 1) / pixelsPerLine;
+ adj->page_size = winSize / pixelsPerLine;
+ adj->page_increment = winSize / pixelsPerLine;
// Special case. When client and virtual size are very close but
// the client is big enough, kill scrollbar.
- if ((m_hAdjust->page_size < m_hAdjust->upper) && (w >= vw))
- m_hAdjust->page_size += 1.0;
+ if ((adj->page_size < adj->upper) && (winSize >= virtSize))
+ adj->page_size += 1.0;
// If the scrollbar hits the right side, move the window
// right to keep it from over extending.
- if ( !wxIsNullDouble(m_hAdjust->value) &&
- (m_hAdjust->value + m_hAdjust->page_size > m_hAdjust->upper) )
+ if ( !wxIsNullDouble(adj->value) &&
+ (adj->value + adj->page_size > adj->upper) )
{
- m_hAdjust->value = m_hAdjust->upper - m_hAdjust->page_size;
- if (m_hAdjust->value < 0.0)
- m_hAdjust->value = 0.0;
-
- if (GetChildren().GetCount() == 0)
- m_xScrollPosition = (int)m_hAdjust->value; // This is enough without child windows
+ adj->value = adj->upper - adj->page_size;
+ if (adj->value < 0.0)
+ adj->value = 0.0;
+
+ if ( m_win->GetChildren().empty() )
+ {
+ // This is enough without child windows
+ *pos = (int)adj->value;
+ }
else
- gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "value_changed" ); // Actually scroll window
+ {
+ // We need to actually scroll window
+ gtk_signal_emit_by_name( GTK_OBJECT(adj), "value_changed" );
+ }
}
}
- if (m_yScrollPixelsPerLine == 0)
- {
- m_vAdjust->upper = 1.0;
- m_vAdjust->page_increment = 1.0;
- m_vAdjust->page_size = 1.0;
- }
- else
- {
- m_vAdjust->upper = (vh+m_yScrollPixelsPerLine-1) / m_yScrollPixelsPerLine;
- m_vAdjust->page_size = h / m_yScrollPixelsPerLine;
- m_vAdjust->page_increment = h / m_yScrollPixelsPerLine;
-
- if ((m_vAdjust->page_size < m_vAdjust->upper) && (h >= vh))
- m_vAdjust->page_size += 1.0;
-
- if ( !wxIsNullDouble(m_vAdjust->value) &&
- (m_vAdjust->value + m_vAdjust->page_size > m_vAdjust->upper) )
- {
- m_vAdjust->value = m_vAdjust->upper - m_vAdjust->page_size;
- if (m_vAdjust->value < 0.0)
- m_vAdjust->value = 0.0;
-
- if (GetChildren().GetCount() == 0)
- m_yScrollPosition = (int)m_vAdjust->value;
- else
- gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust), "value_changed" );
- }
- }
-
- m_xScrollLinesPerPage = (int)(m_hAdjust->page_increment + 0.5);
- m_yScrollLinesPerPage = (int)(m_vAdjust->page_increment + 0.5);
-
- gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust), "changed" );
- gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "changed" );
-}
-
-
-// ----------------------------------------------------------------------------
-// target window handling
-// ----------------------------------------------------------------------------
-
-void wxScrolledWindow::SetTargetWindow( wxWindow *target, bool WXUNUSED(pushEventHandler) )
-{
- wxASSERT_MSG( target, wxT("target window must not be NULL") );
- m_targetWindow = target;
-}
-
-wxWindow *wxScrolledWindow::GetTargetWindow() const
-{
- return m_targetWindow;
-}
-
-// Override this function if you don't want to have wxScrolledWindow
-// automatically change the origin according to the scroll position.
-void wxScrolledWindow::DoPrepareDC(wxDC& dc)
-{
- dc.SetDeviceOrigin( -m_xScrollPosition * m_xScrollPixelsPerLine,
- -m_yScrollPosition * m_yScrollPixelsPerLine );
+ *lines = (int)(adj->upper + 0.5);
+ *linesPerPage = (int)(adj->page_increment + 0.5);
+ gtk_signal_emit_by_name( GTK_OBJECT(adj), "changed" );
}
-void wxScrolledWindow::SetScrollRate( int xstep, int ystep )
+void wxScrollHelperNative::AdjustScrollbars()
{
- 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 )
- *x_unit = m_xScrollPixelsPerLine;
- if ( y_unit )
- *y_unit = m_yScrollPixelsPerLine;
-}
-
-int wxScrolledWindow::GetScrollPageSize(int orient) const
-{
- if ( orient == wxHORIZONTAL )
- return m_xScrollLinesPerPage;
- else
- return m_yScrollLinesPerPage;
-}
-
-void wxScrolledWindow::SetScrollPageSize(int orient, int pageSize)
-{
- if ( orient == wxHORIZONTAL )
- m_xScrollLinesPerPage = pageSize;
- else
- m_yScrollLinesPerPage = pageSize;
-}
-
-void wxScrolledWindow::OnScroll(wxScrollWinEvent& event)
-{
- int orient = event.GetOrientation();
-
- int nScrollInc = CalcScrollInc(event);
- if (nScrollInc == 0) return;
-
- if (orient == wxHORIZONTAL)
- {
- int newPos = m_xScrollPosition + nScrollInc;
- SetScrollPos(wxHORIZONTAL, newPos, TRUE );
- }
- else
- {
- int newPos = m_yScrollPosition + nScrollInc;
- SetScrollPos(wxVERTICAL, newPos, TRUE );
- }
-
- if (orient == wxHORIZONTAL)
- {
- m_xScrollPosition += nScrollInc;
- }
- else
- {
- m_yScrollPosition += nScrollInc;
- }
-
- if (orient == wxHORIZONTAL)
- {
- if (m_xScrollingEnabled)
- m_targetWindow->ScrollWindow(-m_xScrollPixelsPerLine * nScrollInc, 0, (const wxRect *) NULL);
- else
- m_targetWindow->Refresh();
- }
- else
- {
- if (m_yScrollingEnabled)
- m_targetWindow->ScrollWindow(0, -m_yScrollPixelsPerLine * nScrollInc, (const wxRect *) NULL);
- else
- m_targetWindow->Refresh();
- }
-}
-
-void wxScrolledWindow::Scroll( int x_pos, int y_pos )
-{
- 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;
-
- if ((x_pos != -1) && (m_xScrollPixelsPerLine))
- {
- int max = (int)(m_hAdjust->upper - m_hAdjust->page_size + 0.5);
- if (max < 0) max = 0;
- 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;
-
- m_targetWindow->ScrollWindow( (old_x-m_xScrollPosition)*m_xScrollPixelsPerLine, 0 );
-
- // Just update the scrollbar, don't send any wxWidgets event
- GtkHDisconnectEvent();
- gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "value_changed" );
- GtkHConnectEvent();
- }
-
- if ((y_pos != -1) && (m_yScrollPixelsPerLine))
- {
- int max = (int)(m_vAdjust->upper - m_vAdjust->page_size + 0.5);
- if (max < 0) max = 0;
- 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;
-
- m_targetWindow->ScrollWindow( 0, (old_y-m_yScrollPosition)*m_yScrollPixelsPerLine );
-
- // Just update the scrollbar, don't send any wxWidgets event
- GtkVDisconnectEvent();
- gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust), "value_changed" );
- GtkVConnectEvent();
- }
-}
-
-// TODO: [VH]Scroll functions should be combined
-
-void wxScrolledWindow::GtkVScroll( float value, unsigned int scroll_type )
-{
- wxASSERT_MSG( m_targetWindow != 0, _T("No target window") );
-
- if (m_yScrollPixelsPerLine == 0)
- return;
-
- int y_pos = (int)(value+0.5);
-
- if (y_pos == m_yScrollPosition)
- return;
-
- wxEventType command = GtkScrollWinTypeToWx(scroll_type);
-
- wxScrollWinEvent event( command, y_pos, wxVERTICAL );
- event.SetEventObject( this );
- GetEventHandler()->ProcessEvent( event );
-}
-
-void wxScrolledWindow::GtkHScroll( float value, unsigned int scroll_type )
-{
- wxASSERT_MSG( m_targetWindow != 0, _T("No target window") );
-
- if (m_xScrollPixelsPerLine == 0)
- return;
-
- int x_pos = (int)(value+0.5);
-
- if (x_pos == m_xScrollPosition)
- return;
-
- wxEventType command = GtkScrollWinTypeToWx(scroll_type);
-
- wxScrollWinEvent event( command, x_pos, wxHORIZONTAL );
- event.SetEventObject( this );
- GetEventHandler()->ProcessEvent( event );
-}
-
-void wxScrolledWindow::EnableScrolling (bool x_scroll, bool y_scroll)
-{
- m_xScrollingEnabled = x_scroll;
- m_yScrollingEnabled = y_scroll;
-}
-
-// Where the current view starts from
-void wxScrolledWindow::GetViewStart (int *x, int *y) const
-{
- if ( x )
- *x = m_xScrollPosition;
- if ( y )
- *y = m_yScrollPosition;
-}
-
-void wxScrolledWindow::DoCalcScrolledPosition(int x, int y, int *xx, int *yy) const
-{
- int xs, ys;
- GetViewStart (& xs, & ys);
-
- if ( xx )
- *xx = x - xs * m_xScrollPixelsPerLine;
- if ( yy )
- *yy = y - ys * m_yScrollPixelsPerLine;
-}
-
-void wxScrolledWindow::DoCalcUnscrolledPosition(int x, int y, int *xx, int *yy) const
-{
- int xs, ys;
- GetViewStart (& xs, & ys);
-
- if ( xx )
- *xx = x + xs * m_xScrollPixelsPerLine;
- if ( yy )
- *yy = y + ys * m_yScrollPixelsPerLine;
-}
-
-int wxScrolledWindow::CalcScrollInc(wxScrollWinEvent& event)
-{
- int pos = event.GetPosition();
- int orient = event.GetOrientation();
-
- int nScrollInc = 0;
- if (event.GetEventType() == wxEVT_SCROLLWIN_TOP)
- {
- if (orient == wxHORIZONTAL)
- nScrollInc = - m_xScrollPosition;
- else
- nScrollInc = - m_yScrollPosition;
- } else
- if (event.GetEventType() == wxEVT_SCROLLWIN_BOTTOM)
- {
- if (orient == wxHORIZONTAL)
- nScrollInc = GetVirtualSize().GetWidth() / m_xScrollPixelsPerLine - m_xScrollPosition;
- else
- nScrollInc = GetVirtualSize().GetHeight() / m_yScrollPixelsPerLine - m_yScrollPosition;
- } else
- if (event.GetEventType() == wxEVT_SCROLLWIN_LINEUP)
- {
- nScrollInc = -1;
- } else
- if (event.GetEventType() == wxEVT_SCROLLWIN_LINEDOWN)
- {
- nScrollInc = 1;
- } else
- if (event.GetEventType() == wxEVT_SCROLLWIN_PAGEUP)
- {
- if (orient == wxHORIZONTAL)
- nScrollInc = -GetScrollPageSize(wxHORIZONTAL);
- else
- nScrollInc = -GetScrollPageSize(wxVERTICAL);
- } else
- if (event.GetEventType() == wxEVT_SCROLLWIN_PAGEDOWN)
- {
- if (orient == wxHORIZONTAL)
- nScrollInc = GetScrollPageSize(wxHORIZONTAL);
- else
- nScrollInc = GetScrollPageSize(wxVERTICAL);
- } else
- if ((event.GetEventType() == wxEVT_SCROLLWIN_THUMBTRACK) ||
- (event.GetEventType() == wxEVT_SCROLLWIN_THUMBRELEASE))
- {
- if (orient == wxHORIZONTAL)
- nScrollInc = pos - m_xScrollPosition;
- else
- nScrollInc = pos - m_yScrollPosition;
- }
-
- if (orient == wxHORIZONTAL)
- {
- if (m_xScrollPixelsPerLine > 0)
- {
- int max = (int)(m_hAdjust->upper - m_hAdjust->page_size + 0.5);
- if (max < 0) max = 0;
-
- if ( (m_xScrollPosition + nScrollInc) < 0 )
- nScrollInc = -m_xScrollPosition; // As -ve as we can go
- else if ( (m_xScrollPosition + nScrollInc) > max )
- nScrollInc = max - m_xScrollPosition; // As +ve as we can go
- }
- else
- m_targetWindow->Refresh();
- }
- else
- {
- if (m_yScrollPixelsPerLine > 0)
- {
- int max = (int)(m_vAdjust->upper - m_vAdjust->page_size + 0.5);
- if (max < 0) max = 0;
-
- if ( (m_yScrollPosition + nScrollInc) < 0 )
- nScrollInc = -m_yScrollPosition; // As -ve as we can go
- else if ( (m_yScrollPosition + nScrollInc) > max )
- nScrollInc = max - m_yScrollPosition; // As +ve as we can go
- }
- else
- m_targetWindow->Refresh();
- }
-
- return nScrollInc;
-}
-
-void wxScrolledWindow::SetScrollPos( int orient, int pos, bool refresh )
-{
- wxCHECK_RET( m_widget != NULL, wxT("invalid window") );
-
- wxCHECK_RET( m_wxwindow != NULL, wxT("window needs client area for scrolling") );
-
- if (orient == wxHORIZONTAL)
- {
- int max = (int)(m_hAdjust->upper - m_hAdjust->page_size + 0.5);
- if (max < 0) max = 0;
-
- if (pos > max) pos = 0;
- if (pos < 0) pos = 0;
-
- if (pos == (int)(m_hAdjust->value+0.5)) return;
- m_hAdjust->value = pos;
- }
- else
- {
- int max = (int)(m_vAdjust->upper - m_vAdjust->page_size + 0.5);
- if (max < 0) max = 0;
-
- if (pos > max) pos = 0;
- if (pos < 0) pos = 0;
-
- if (pos == (int)(m_vAdjust->value+0.5)) return;
- m_vAdjust->value = pos;
- }
-
- if (m_wxwindow->window)
- {
- if (orient == wxHORIZONTAL)
- {
- // Just update the scrollbar, don't send any wxWidgets event
- GtkHDisconnectEvent();
- gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "value_changed" );
- GtkHConnectEvent();
- }
- else
- {
- // Just update the scrollbar, don't send any wxWidgets event
- GtkVDisconnectEvent();
- gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust), "value_changed" );
- GtkVConnectEvent();
- }
- }
-}
-
-void wxScrolledWindow::GtkVConnectEvent()
-{
- gtk_signal_connect( GTK_OBJECT(m_vAdjust), "value_changed",
- (GtkSignalFunc) gtk_scrolled_window_vscroll_callback, (gpointer) this );
-}
-
-void wxScrolledWindow::GtkHConnectEvent()
-{
- gtk_signal_connect( GTK_OBJECT(m_hAdjust), "value_changed",
- (GtkSignalFunc) gtk_scrolled_window_hscroll_callback, (gpointer) this );
-}
+ int w, h;
+ int vw, vh;
-void wxScrolledWindow::GtkHDisconnectEvent()
-{
- gtk_signal_disconnect_by_func( GTK_OBJECT(m_hAdjust),
- (GtkSignalFunc) gtk_scrolled_window_hscroll_callback, (gpointer) this );
-}
+ m_targetWindow->GetClientSize( &w, &h );
+ m_targetWindow->GetVirtualSize( &vw, &vh );
-void wxScrolledWindow::GtkVDisconnectEvent()
-{
- gtk_signal_disconnect_by_func( GTK_OBJECT(m_vAdjust),
- (GtkSignalFunc) gtk_scrolled_window_vscroll_callback, (gpointer) this );
+ 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);
}
-bool wxScrolledWindow::Layout()
+void wxScrollHelperNative::DoScroll(int orient,
+ GtkAdjustment *adj,
+ int pos,
+ int pixelsPerLine,
+ int *posOld)
{
- if (GetSizer() && m_targetWindow == this)
+ if ( pos != -1 && pos != *posOld && pixelsPerLine )
{
- // If we're the scroll target, take into account the
- // virtual size and scrolled position of the window.
+ 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;
- int x, y, w, h;
- CalcScrolledPosition(0,0, &x,&y);
- GetVirtualSize(&w, &h);
- GetSizer()->SetDimension(x, y, w, h);
- return TRUE;
- }
- else
- return wxPanel::Layout(); // fall back to default for LayoutConstraints
-}
+ adj->value = pos;
-// ----------------------------------------------------------------------------
-// event handlers
-// ----------------------------------------------------------------------------
+ int diff = (*posOld - pos)*pixelsPerLine;
+ m_targetWindow->ScrollWindow(orient == wxHORIZONTAL ? diff : 0,
+ orient == wxHORIZONTAL ? 0 : diff);
-// Default OnSize resets scrollbars, if any
-void wxScrolledWindow::OnSize(wxSizeEvent& WXUNUSED(event))
-{
- if ( m_targetWindow->GetAutoLayout() )
- {
- wxSize size = m_targetWindow->GetBestVirtualSize();
+ *posOld = pos;
- // This will call ::Layout() and ::AdjustScrollbars()
- SetVirtualSize( size );
- }
- else
- {
- AdjustScrollbars();
+ m_win->GtkUpdateScrollbar(orient);
}
}
-// This calls OnDraw, having adjusted the origin according to the current
-// scroll position
-void wxScrolledWindow::OnPaint(wxPaintEvent& WXUNUSED(event))
+void wxScrollHelperNative::Scroll( int x_pos, int y_pos )
{
- wxPaintDC dc(this);
- PrepareDC(dc);
-
- OnDraw(dc);
-}
-
-// kbd handling: notice that we use OnChar() and not OnKeyDown() for
-// 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)
-{
- int stx, sty, // view origin
- szx, szy, // view size (total)
- clix, cliy; // view size (on screen)
-
- GetViewStart(&stx, &sty);
- GetClientSize(&clix, &cliy);
- GetVirtualSize(&szx, &szy);
-
- if( m_xScrollPixelsPerLine )
- {
- clix /= m_xScrollPixelsPerLine;
- szx /= m_xScrollPixelsPerLine;
- }
- else
- {
- clix = 0;
- szx = -1;
- }
- if( m_yScrollPixelsPerLine )
- {
- cliy /= m_yScrollPixelsPerLine;
- szy /= m_yScrollPixelsPerLine;
- }
- else
- {
- cliy = 0;
- szy = -1;
- }
-
- int xScrollOld = GetScrollPos(wxHORIZONTAL),
- yScrollOld = GetScrollPos(wxVERTICAL);
-
- int dsty;
- switch ( event.GetKeyCode() )
- {
- case WXK_PAGEUP:
- case WXK_PRIOR:
- dsty = sty - (5 * cliy / 6);
- Scroll(-1, (dsty == -1) ? 0 : dsty);
- break;
-
- case WXK_PAGEDOWN:
- case WXK_NEXT:
- Scroll(-1, sty + (5 * cliy / 6));
- break;
-
- case WXK_HOME:
- Scroll(0, event.ControlDown() ? 0 : -1);
- break;
-
- case WXK_END:
- Scroll(szx - clix, event.ControlDown() ? szy - cliy : -1);
- break;
-
- case WXK_UP:
- Scroll(-1, sty - 1);
- break;
-
- case WXK_DOWN:
- Scroll(-1, sty + 1);
- break;
+ wxCHECK_RET( m_targetWindow != 0, _T("No target window") );
- case WXK_LEFT:
- Scroll(stx - 1, -1);
- break;
-
- case WXK_RIGHT:
- Scroll(stx + 1, -1);
- break;
-
- default:
- // not for us
- event.Skip();
- return;
- }
-
- int xScroll = GetScrollPos(wxHORIZONTAL);
- if ( xScroll != xScrollOld )
- {
- wxScrollWinEvent eventS(wxEVT_SCROLLWIN_THUMBTRACK, xScroll,
- wxHORIZONTAL);
- eventS.SetEventObject(this);
- GetEventHandler()->ProcessEvent(eventS);
- }
-
- int yScroll = GetScrollPos(wxVERTICAL);
- if ( yScroll != yScrollOld )
- {
- wxScrollWinEvent eventS(wxEVT_SCROLLWIN_THUMBTRACK, yScroll,
- wxVERTICAL);
- eventS.SetEventObject(this);
- GetEventHandler()->ProcessEvent(eventS);
- }
+ DoScroll(wxHORIZONTAL, m_win->m_hAdjust, x_pos, m_xScrollPixelsPerLine,
+ &m_xScrollPosition);
+ DoScroll(wxVERTICAL, m_win->m_vAdjust, y_pos, m_yScrollPixelsPerLine,
+ &m_yScrollPosition);
}
-
-// vi:sts=4:sw=4:et
// 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
#endif
#include "wx/scrolwin.h"
-#include "wx/utils.h"
-#include "wx/dcclient.h"
-#include "wx/panel.h"
-#include "wx/sizer.h"
-#include "wx/math.h"
-
#include "wx/gtk/private.h"
-#include "wx/gtk/win_gtk.h"
-
-// ----------------------------------------------------------------------------
-// event tables
-// ----------------------------------------------------------------------------
-
-BEGIN_EVENT_TABLE(wxScrolledWindow, wxPanel)
- EVT_SCROLLWIN(wxScrolledWindow::OnScroll)
- EVT_SIZE(wxScrolledWindow::OnSize)
- EVT_PAINT(wxScrolledWindow::OnPaint)
- EVT_CHAR(wxScrolledWindow::OnChar)
-END_EVENT_TABLE()
-
-IMPLEMENT_DYNAMIC_CLASS(wxScrolledWindow, wxPanel)
// ============================================================================
// implementation
// ============================================================================
-//-----------------------------------------------------------------------------
-// data
-//-----------------------------------------------------------------------------
-
-extern bool g_blockEventsOnDrag;
-extern bool g_blockEventsOnScroll;
-
-//-----------------------------------------------------------------------------
-// idle system
-//-----------------------------------------------------------------------------
-
-extern void wxapp_install_idle_handler();
-extern bool g_isIdle;
-
-//-----------------------------------------------------------------------------
-// "value_changed" from m_vAdjust
-//-----------------------------------------------------------------------------
-
-extern "C" {
-static void gtk_scrolled_window_vscroll_callback( GtkAdjustment *adjust,
- SCROLLBAR_CBACK_ARG
- wxScrolledWindow *win )
-{
- if (g_isIdle)
- wxapp_install_idle_handler();
-
- if (g_blockEventsOnDrag) return;
-
- if (!win->m_hasVMT) return;
-
- win->GtkVScroll( adjust->value,
- GET_SCROLL_TYPE(GTK_SCROLLED_WINDOW(win->m_widget)->vscrollbar) );
-}
-}
-
-//-----------------------------------------------------------------------------
-// "value_changed" from m_hAdjust
-//-----------------------------------------------------------------------------
-
-extern "C" {
-static void gtk_scrolled_window_hscroll_callback( GtkAdjustment *adjust,
- SCROLLBAR_CBACK_ARG
- wxScrolledWindow *win )
-{
- if (g_isIdle)
- wxapp_install_idle_handler();
-
- if (g_blockEventsOnDrag) return;
- if (!win->m_hasVMT) return;
-
- win->GtkHScroll( adjust->value,
- GET_SCROLL_TYPE(GTK_SCROLLED_WINDOW(win->m_widget)->hscrollbar) );
-}
-}
-
-//-----------------------------------------------------------------------------
-// "button_press_event" from scrollbar
-//-----------------------------------------------------------------------------
-
-extern "C" {
-static gint gtk_scrollbar_button_press_callback( GtkRange *widget,
- GdkEventButton *gdk_event,
- wxWindowGTK *win)
-{
- if (g_isIdle)
- wxapp_install_idle_handler();
-
- g_blockEventsOnScroll = TRUE;
-
- // FIXME: there is no slider field any more, what was meant here?
-#ifndef __WXGTK20__
- win->m_isScrolling = (gdk_event->window == widget->slider);
-#endif
-
- return FALSE;
-}
-}
-
-//-----------------------------------------------------------------------------
-// "button_release_event" from scrollbar
-//-----------------------------------------------------------------------------
-
-extern "C" {
-static gint gtk_scrollbar_button_release_callback( GtkRange *widget,
- GdkEventButton *WXUNUSED(gdk_event),
- wxWindowGTK *win)
-{
-// don't test here as we can release the mouse while being over
-// a different window than the slider
-//
-// if (gdk_event->window != widget->slider) return FALSE;
-
- g_blockEventsOnScroll = FALSE;
-
- if (win->m_isScrolling)
- {
- wxEventType command = wxEVT_SCROLLWIN_THUMBRELEASE;
- int value = -1;
- int dir = -1;
-
- GtkScrolledWindow *scrolledWindow = GTK_SCROLLED_WINDOW(win->m_widget);
- if (widget == GTK_RANGE(scrolledWindow->hscrollbar))
- {
- value = (int)(win->m_hAdjust->value+0.5);
- dir = wxHORIZONTAL;
- }
- if (widget == GTK_RANGE(scrolledWindow->vscrollbar))
- {
- value = (int)(win->m_vAdjust->value+0.5);
- dir = wxVERTICAL;
- }
-
- wxScrollWinEvent event( command, value, dir );
- event.SetEventObject( win );
- win->GetEventHandler()->ProcessEvent( event );
- }
-
- win->m_isScrolling = FALSE;
-
- return FALSE;
-}
-}
-
-//-----------------------------------------------------------------------------
-// InsertChild for wxScrolledWindow
-//-----------------------------------------------------------------------------
-
-static void wxInsertChildInScrolledWindow( wxWindow* parent, wxWindow* child )
-{
- // The window might have been scrolled already, do we
- // have to adapt the position.
- GtkPizza *pizza = GTK_PIZZA(parent->m_wxwindow);
- child->m_x += pizza->xoffset;
- child->m_y += pizza->yoffset;
-
- gtk_pizza_put( GTK_PIZZA(parent->m_wxwindow),
- GTK_WIDGET(child->m_widget),
- child->m_x,
- child->m_y,
- child->m_width,
- child->m_height );
-}
-
-// ----------------------------------------------------------------------------
-// wxScrolledWindow creation
-// ----------------------------------------------------------------------------
-
-void wxScrolledWindow::Init()
-{
- m_xScrollPixelsPerLine = 0;
- m_yScrollPixelsPerLine = 0;
- m_xScrollingEnabled = TRUE;
- m_yScrollingEnabled = TRUE;
- m_xScrollPosition = 0;
- m_yScrollPosition = 0;
- m_xScrollLinesPerPage = 0;
- m_yScrollLinesPerPage = 0;
- m_targetWindow = (wxWindow*) NULL;
- m_scaleX = 1.0;
- m_scaleY = 1.0;
- m_hasScrolling = TRUE;
-}
-
-bool wxScrolledWindow::Create(wxWindow *parent,
- wxWindowID id,
- const wxPoint& pos,
- const wxSize& size,
- long style,
- const wxString& name)
-{
- Init();
-
- if (!PreCreation( parent, pos, size ) ||
- !CreateBase( parent, id, pos, size, style, wxDefaultValidator, name ))
- {
- wxFAIL_MSG( wxT("wxWindow creation failed") );
- return FALSE;
- }
-
- m_insertCallback = wxInsertChildInScrolledWindow;
-
- m_targetWindow = this;
-
- m_widget = gtk_scrolled_window_new( (GtkAdjustment *) NULL, (GtkAdjustment *) NULL );
- GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS );
-
- GtkScrolledWindow *scrolledWindow = GTK_SCROLLED_WINDOW(m_widget);
-
- GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT_GET_CLASS(m_widget) );
- scroll_class->scrollbar_spacing = 0;
-
- gtk_scrolled_window_set_policy( scrolledWindow, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC );
-
- m_hAdjust = gtk_range_get_adjustment( GTK_RANGE(scrolledWindow->hscrollbar) );
- m_vAdjust = gtk_range_get_adjustment( GTK_RANGE(scrolledWindow->vscrollbar) );
-
- m_wxwindow = gtk_pizza_new();
-
- gtk_container_add( GTK_CONTAINER(m_widget), m_wxwindow );
-
- GtkPizza *pizza = GTK_PIZZA(m_wxwindow);
-
- if (HasFlag(wxRAISED_BORDER))
- {
- gtk_pizza_set_shadow_type( pizza, GTK_MYSHADOW_OUT );
- }
- else if (HasFlag(wxSUNKEN_BORDER))
- {
- gtk_pizza_set_shadow_type( pizza, GTK_MYSHADOW_IN );
- }
- else if (HasFlag(wxSIMPLE_BORDER))
- {
- gtk_pizza_set_shadow_type( pizza, GTK_MYSHADOW_THIN );
- }
- else
- {
- gtk_pizza_set_shadow_type( pizza, GTK_MYSHADOW_NONE );
- }
-
- GTK_WIDGET_SET_FLAGS( m_wxwindow, GTK_CAN_FOCUS );
- m_acceptsFocus = TRUE;
-
- // I _really_ don't want scrollbars in the beginning
- m_vAdjust->lower = 0.0;
- m_vAdjust->upper = 1.0;
- m_vAdjust->value = 0.0;
- m_vAdjust->step_increment = 1.0;
- m_vAdjust->page_increment = 2.0;
- gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust), "changed" );
- m_hAdjust->lower = 0.0;
- m_hAdjust->upper = 1.0;
- m_hAdjust->value = 0.0;
- m_hAdjust->step_increment = 1.0;
- m_hAdjust->page_increment = 2.0;
- gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "changed" );
-
- // Handlers for new scrollbar values
- GtkVConnectEvent();
- GtkHConnectEvent();
-
- // these handlers block mouse events to any window during scrolling such as
- // motion events and prevent GTK and wxWidgets from fighting over where the
- // slider should be
-
- gtk_signal_connect( GTK_OBJECT(scrolledWindow->vscrollbar), "button_press_event",
- (GtkSignalFunc)gtk_scrollbar_button_press_callback, (gpointer) this );
-
- gtk_signal_connect( GTK_OBJECT(scrolledWindow->hscrollbar), "button_press_event",
- (GtkSignalFunc)gtk_scrollbar_button_press_callback, (gpointer) this );
-
- gtk_signal_connect( GTK_OBJECT(scrolledWindow->vscrollbar), "button_release_event",
- (GtkSignalFunc)gtk_scrollbar_button_release_callback, (gpointer) this );
-
- gtk_signal_connect( GTK_OBJECT(scrolledWindow->hscrollbar), "button_release_event",
- (GtkSignalFunc)gtk_scrollbar_button_release_callback, (gpointer) this );
-
- gtk_widget_show( m_wxwindow );
-
- if (m_parent)
- m_parent->DoAddChild( this );
-
- m_focusWidget = m_wxwindow;
-
- PostCreation();
-
- Show( TRUE );
-
- return TRUE;
-}
-
// ----------------------------------------------------------------------------
-// setting scrolling parameters
+// wxScrollHelper implementation
// ----------------------------------------------------------------------------
-void wxScrolledWindow::DoSetVirtualSize( int x, int y )
-{
- wxPanel::DoSetVirtualSize( x, y );
- AdjustScrollbars();
-
- if (GetAutoLayout())
- Layout();
-}
-
-// wxWindow's GetBestVirtualSize returns the actual window size,
-// whereas we want to return the virtual size
-wxSize wxScrolledWindow::GetBestVirtualSize() const
-{
- wxSize clientSize( GetClientSize() );
- if (GetSizer())
- {
- wxSize minSize( GetSizer()->CalcMin() );
-
- return wxSize( wxMax( clientSize.x, minSize.x ), wxMax( clientSize.y, minSize.y ) );
- }
- else
- return clientSize;
-}
-
-// return the size best suited for the current window
-// (this isn't a virtual size, this is a sensible size for the window)
-wxSize wxScrolledWindow::DoGetBestSize() const
-{
- wxSize best;
-
- if ( GetSizer() )
- {
- wxSize b = GetSizer()->GetMinSize();
-
- // Only use the content to set the window size in the direction
- // where there's no scrolling; otherwise we're going to get a huge
- // window in the direction in which scrolling is enabled
- int ppuX, ppuY;
- GetScrollPixelsPerUnit(& ppuX, & ppuY);
-
- wxSize minSize;
- if ( GetMinSize().IsFullySpecified() )
- minSize = GetMinSize();
- else
- minSize = GetSize();
-
- if (ppuX > 0)
- b.x = minSize.x;
- if (ppuY > 0)
- b.y = minSize.y;
- best = b;
- }
- else
- return wxWindow::DoGetBestSize();
-
- // Add any difference between size and client size
- wxSize diff = GetSize() - GetClientSize();
- best.x += wxMax(0, diff.x);
- best.y += wxMax(0, diff.y);
-
- return best;
-}
-
-/*
- * 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 wxScrollHelperNative::SetScrollbars(int pixelsPerUnitX, int pixelsPerUnitY,
+ int noUnitsX, int noUnitsY,
+ int xPos, int yPos,
+ bool noRefresh)
{
int xs, ys;
- GetViewStart (& xs, & ys);
+ GetViewStart(& xs, & ys);
int old_x = m_xScrollPixelsPerLine * xs;
int old_y = m_yScrollPixelsPerLine * ys;
m_xScrollPixelsPerLine = pixelsPerUnitX;
m_yScrollPixelsPerLine = pixelsPerUnitY;
- m_hAdjust->value = m_xScrollPosition = xPos;
- m_vAdjust->value = m_yScrollPosition = yPos;
+ m_win->m_hAdjust->value = m_xScrollPosition = xPos;
+ m_win->m_vAdjust->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->ScrollWindow( old_x - new_x, old_y - new_y );
}
+
+ m_targetWindow->m_hasScrolling = pixelsPerUnitX || pixelsPerUnitY;
}
-void wxScrolledWindow::AdjustScrollbars()
+void wxScrollHelperNative::DoAdjustScrollbar(GtkAdjustment *adj,
+ int pixelsPerLine,
+ int winSize,
+ int virtSize,
+ int *pos,
+ int *lines,
+ int *linesPerPage)
{
- int w, h;
- int vw, vh;
-
- m_targetWindow->GetClientSize( &w, &h );
- m_targetWindow->GetVirtualSize( &vw, &vh );
-
- if (m_xScrollPixelsPerLine == 0)
+ if ( pixelsPerLine == 0 )
{
- m_hAdjust->upper = 1.0;
- m_hAdjust->page_increment = 1.0;
- m_hAdjust->page_size = 1.0;
+ adj->upper = 1.0;
+ adj->page_increment = 1.0;
+ adj->page_size = 1.0;
}
- else
+ else // we do have scrollbar
{
- m_hAdjust->upper = (vw+m_xScrollPixelsPerLine-1) / m_xScrollPixelsPerLine;
- m_hAdjust->page_size = w / m_xScrollPixelsPerLine;
- m_hAdjust->page_increment = w / m_xScrollPixelsPerLine;
+ adj->upper = (virtSize + pixelsPerLine - 1) / pixelsPerLine;
+ adj->page_size = winSize / pixelsPerLine;
+ adj->page_increment = winSize / pixelsPerLine;
// Special case. When client and virtual size are very close but
// the client is big enough, kill scrollbar.
- if ((m_hAdjust->page_size < m_hAdjust->upper) && (w >= vw))
- m_hAdjust->page_size += 1.0;
+ if ((adj->page_size < adj->upper) && (winSize >= virtSize))
+ adj->page_size += 1.0;
// If the scrollbar hits the right side, move the window
// right to keep it from over extending.
- if ( !wxIsNullDouble(m_hAdjust->value) &&
- (m_hAdjust->value + m_hAdjust->page_size > m_hAdjust->upper) )
+ if ( !wxIsNullDouble(adj->value) &&
+ (adj->value + adj->page_size > adj->upper) )
{
- m_hAdjust->value = m_hAdjust->upper - m_hAdjust->page_size;
- if (m_hAdjust->value < 0.0)
- m_hAdjust->value = 0.0;
-
- if (GetChildren().GetCount() == 0)
- m_xScrollPosition = (int)m_hAdjust->value; // This is enough without child windows
+ adj->value = adj->upper - adj->page_size;
+ if (adj->value < 0.0)
+ adj->value = 0.0;
+
+ if ( m_win->GetChildren().empty() )
+ {
+ // This is enough without child windows
+ *pos = (int)adj->value;
+ }
else
- gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "value_changed" ); // Actually scroll window
+ {
+ // We need to actually scroll window
+ gtk_signal_emit_by_name( GTK_OBJECT(adj), "value_changed" );
+ }
}
}
- if (m_yScrollPixelsPerLine == 0)
- {
- m_vAdjust->upper = 1.0;
- m_vAdjust->page_increment = 1.0;
- m_vAdjust->page_size = 1.0;
- }
- else
- {
- m_vAdjust->upper = (vh+m_yScrollPixelsPerLine-1) / m_yScrollPixelsPerLine;
- m_vAdjust->page_size = h / m_yScrollPixelsPerLine;
- m_vAdjust->page_increment = h / m_yScrollPixelsPerLine;
-
- if ((m_vAdjust->page_size < m_vAdjust->upper) && (h >= vh))
- m_vAdjust->page_size += 1.0;
-
- if ( !wxIsNullDouble(m_vAdjust->value) &&
- (m_vAdjust->value + m_vAdjust->page_size > m_vAdjust->upper) )
- {
- m_vAdjust->value = m_vAdjust->upper - m_vAdjust->page_size;
- if (m_vAdjust->value < 0.0)
- m_vAdjust->value = 0.0;
-
- if (GetChildren().GetCount() == 0)
- m_yScrollPosition = (int)m_vAdjust->value;
- else
- gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust), "value_changed" );
- }
- }
-
- m_xScrollLinesPerPage = (int)(m_hAdjust->page_increment + 0.5);
- m_yScrollLinesPerPage = (int)(m_vAdjust->page_increment + 0.5);
-
- gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust), "changed" );
- gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "changed" );
-}
-
-
-// ----------------------------------------------------------------------------
-// target window handling
-// ----------------------------------------------------------------------------
-
-void wxScrolledWindow::SetTargetWindow( wxWindow *target, bool WXUNUSED(pushEventHandler) )
-{
- wxASSERT_MSG( target, wxT("target window must not be NULL") );
- m_targetWindow = target;
-}
-
-wxWindow *wxScrolledWindow::GetTargetWindow() const
-{
- return m_targetWindow;
-}
-
-// Override this function if you don't want to have wxScrolledWindow
-// automatically change the origin according to the scroll position.
-void wxScrolledWindow::DoPrepareDC(wxDC& dc)
-{
- dc.SetDeviceOrigin( -m_xScrollPosition * m_xScrollPixelsPerLine,
- -m_yScrollPosition * m_yScrollPixelsPerLine );
+ *lines = (int)(adj->upper + 0.5);
+ *linesPerPage = (int)(adj->page_increment + 0.5);
+ gtk_signal_emit_by_name( GTK_OBJECT(adj), "changed" );
}
-void wxScrolledWindow::SetScrollRate( int xstep, int ystep )
+void wxScrollHelperNative::AdjustScrollbars()
{
- 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 )
- *x_unit = m_xScrollPixelsPerLine;
- if ( y_unit )
- *y_unit = m_yScrollPixelsPerLine;
-}
-
-int wxScrolledWindow::GetScrollPageSize(int orient) const
-{
- if ( orient == wxHORIZONTAL )
- return m_xScrollLinesPerPage;
- else
- return m_yScrollLinesPerPage;
-}
-
-void wxScrolledWindow::SetScrollPageSize(int orient, int pageSize)
-{
- if ( orient == wxHORIZONTAL )
- m_xScrollLinesPerPage = pageSize;
- else
- m_yScrollLinesPerPage = pageSize;
-}
-
-void wxScrolledWindow::OnScroll(wxScrollWinEvent& event)
-{
- int orient = event.GetOrientation();
-
- int nScrollInc = CalcScrollInc(event);
- if (nScrollInc == 0) return;
-
- if (orient == wxHORIZONTAL)
- {
- int newPos = m_xScrollPosition + nScrollInc;
- SetScrollPos(wxHORIZONTAL, newPos, TRUE );
- }
- else
- {
- int newPos = m_yScrollPosition + nScrollInc;
- SetScrollPos(wxVERTICAL, newPos, TRUE );
- }
-
- if (orient == wxHORIZONTAL)
- {
- m_xScrollPosition += nScrollInc;
- }
- else
- {
- m_yScrollPosition += nScrollInc;
- }
-
- if (orient == wxHORIZONTAL)
- {
- if (m_xScrollingEnabled)
- m_targetWindow->ScrollWindow(-m_xScrollPixelsPerLine * nScrollInc, 0, (const wxRect *) NULL);
- else
- m_targetWindow->Refresh();
- }
- else
- {
- if (m_yScrollingEnabled)
- m_targetWindow->ScrollWindow(0, -m_yScrollPixelsPerLine * nScrollInc, (const wxRect *) NULL);
- else
- m_targetWindow->Refresh();
- }
-}
-
-void wxScrolledWindow::Scroll( int x_pos, int y_pos )
-{
- 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;
-
- if ((x_pos != -1) && (m_xScrollPixelsPerLine))
- {
- int max = (int)(m_hAdjust->upper - m_hAdjust->page_size + 0.5);
- if (max < 0) max = 0;
- 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;
-
- m_targetWindow->ScrollWindow( (old_x-m_xScrollPosition)*m_xScrollPixelsPerLine, 0 );
-
- // Just update the scrollbar, don't send any wxWidgets event
- GtkHDisconnectEvent();
- gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "value_changed" );
- GtkHConnectEvent();
- }
-
- if ((y_pos != -1) && (m_yScrollPixelsPerLine))
- {
- int max = (int)(m_vAdjust->upper - m_vAdjust->page_size + 0.5);
- if (max < 0) max = 0;
- 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;
-
- m_targetWindow->ScrollWindow( 0, (old_y-m_yScrollPosition)*m_yScrollPixelsPerLine );
-
- // Just update the scrollbar, don't send any wxWidgets event
- GtkVDisconnectEvent();
- gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust), "value_changed" );
- GtkVConnectEvent();
- }
-}
-
-// TODO: [VH]Scroll functions should be combined
-
-void wxScrolledWindow::GtkVScroll( float value, unsigned int scroll_type )
-{
- wxASSERT_MSG( m_targetWindow != 0, _T("No target window") );
-
- if (m_yScrollPixelsPerLine == 0)
- return;
-
- int y_pos = (int)(value+0.5);
-
- if (y_pos == m_yScrollPosition)
- return;
-
- wxEventType command = GtkScrollWinTypeToWx(scroll_type);
-
- wxScrollWinEvent event( command, y_pos, wxVERTICAL );
- event.SetEventObject( this );
- GetEventHandler()->ProcessEvent( event );
-}
-
-void wxScrolledWindow::GtkHScroll( float value, unsigned int scroll_type )
-{
- wxASSERT_MSG( m_targetWindow != 0, _T("No target window") );
-
- if (m_xScrollPixelsPerLine == 0)
- return;
-
- int x_pos = (int)(value+0.5);
-
- if (x_pos == m_xScrollPosition)
- return;
-
- wxEventType command = GtkScrollWinTypeToWx(scroll_type);
-
- wxScrollWinEvent event( command, x_pos, wxHORIZONTAL );
- event.SetEventObject( this );
- GetEventHandler()->ProcessEvent( event );
-}
-
-void wxScrolledWindow::EnableScrolling (bool x_scroll, bool y_scroll)
-{
- m_xScrollingEnabled = x_scroll;
- m_yScrollingEnabled = y_scroll;
-}
-
-// Where the current view starts from
-void wxScrolledWindow::GetViewStart (int *x, int *y) const
-{
- if ( x )
- *x = m_xScrollPosition;
- if ( y )
- *y = m_yScrollPosition;
-}
-
-void wxScrolledWindow::DoCalcScrolledPosition(int x, int y, int *xx, int *yy) const
-{
- int xs, ys;
- GetViewStart (& xs, & ys);
-
- if ( xx )
- *xx = x - xs * m_xScrollPixelsPerLine;
- if ( yy )
- *yy = y - ys * m_yScrollPixelsPerLine;
-}
-
-void wxScrolledWindow::DoCalcUnscrolledPosition(int x, int y, int *xx, int *yy) const
-{
- int xs, ys;
- GetViewStart (& xs, & ys);
-
- if ( xx )
- *xx = x + xs * m_xScrollPixelsPerLine;
- if ( yy )
- *yy = y + ys * m_yScrollPixelsPerLine;
-}
-
-int wxScrolledWindow::CalcScrollInc(wxScrollWinEvent& event)
-{
- int pos = event.GetPosition();
- int orient = event.GetOrientation();
-
- int nScrollInc = 0;
- if (event.GetEventType() == wxEVT_SCROLLWIN_TOP)
- {
- if (orient == wxHORIZONTAL)
- nScrollInc = - m_xScrollPosition;
- else
- nScrollInc = - m_yScrollPosition;
- } else
- if (event.GetEventType() == wxEVT_SCROLLWIN_BOTTOM)
- {
- if (orient == wxHORIZONTAL)
- nScrollInc = GetVirtualSize().GetWidth() / m_xScrollPixelsPerLine - m_xScrollPosition;
- else
- nScrollInc = GetVirtualSize().GetHeight() / m_yScrollPixelsPerLine - m_yScrollPosition;
- } else
- if (event.GetEventType() == wxEVT_SCROLLWIN_LINEUP)
- {
- nScrollInc = -1;
- } else
- if (event.GetEventType() == wxEVT_SCROLLWIN_LINEDOWN)
- {
- nScrollInc = 1;
- } else
- if (event.GetEventType() == wxEVT_SCROLLWIN_PAGEUP)
- {
- if (orient == wxHORIZONTAL)
- nScrollInc = -GetScrollPageSize(wxHORIZONTAL);
- else
- nScrollInc = -GetScrollPageSize(wxVERTICAL);
- } else
- if (event.GetEventType() == wxEVT_SCROLLWIN_PAGEDOWN)
- {
- if (orient == wxHORIZONTAL)
- nScrollInc = GetScrollPageSize(wxHORIZONTAL);
- else
- nScrollInc = GetScrollPageSize(wxVERTICAL);
- } else
- if ((event.GetEventType() == wxEVT_SCROLLWIN_THUMBTRACK) ||
- (event.GetEventType() == wxEVT_SCROLLWIN_THUMBRELEASE))
- {
- if (orient == wxHORIZONTAL)
- nScrollInc = pos - m_xScrollPosition;
- else
- nScrollInc = pos - m_yScrollPosition;
- }
-
- if (orient == wxHORIZONTAL)
- {
- if (m_xScrollPixelsPerLine > 0)
- {
- int max = (int)(m_hAdjust->upper - m_hAdjust->page_size + 0.5);
- if (max < 0) max = 0;
-
- if ( (m_xScrollPosition + nScrollInc) < 0 )
- nScrollInc = -m_xScrollPosition; // As -ve as we can go
- else if ( (m_xScrollPosition + nScrollInc) > max )
- nScrollInc = max - m_xScrollPosition; // As +ve as we can go
- }
- else
- m_targetWindow->Refresh();
- }
- else
- {
- if (m_yScrollPixelsPerLine > 0)
- {
- int max = (int)(m_vAdjust->upper - m_vAdjust->page_size + 0.5);
- if (max < 0) max = 0;
-
- if ( (m_yScrollPosition + nScrollInc) < 0 )
- nScrollInc = -m_yScrollPosition; // As -ve as we can go
- else if ( (m_yScrollPosition + nScrollInc) > max )
- nScrollInc = max - m_yScrollPosition; // As +ve as we can go
- }
- else
- m_targetWindow->Refresh();
- }
-
- return nScrollInc;
-}
-
-void wxScrolledWindow::SetScrollPos( int orient, int pos, bool refresh )
-{
- wxCHECK_RET( m_widget != NULL, wxT("invalid window") );
-
- wxCHECK_RET( m_wxwindow != NULL, wxT("window needs client area for scrolling") );
-
- if (orient == wxHORIZONTAL)
- {
- int max = (int)(m_hAdjust->upper - m_hAdjust->page_size + 0.5);
- if (max < 0) max = 0;
-
- if (pos > max) pos = 0;
- if (pos < 0) pos = 0;
-
- if (pos == (int)(m_hAdjust->value+0.5)) return;
- m_hAdjust->value = pos;
- }
- else
- {
- int max = (int)(m_vAdjust->upper - m_vAdjust->page_size + 0.5);
- if (max < 0) max = 0;
-
- if (pos > max) pos = 0;
- if (pos < 0) pos = 0;
-
- if (pos == (int)(m_vAdjust->value+0.5)) return;
- m_vAdjust->value = pos;
- }
-
- if (m_wxwindow->window)
- {
- if (orient == wxHORIZONTAL)
- {
- // Just update the scrollbar, don't send any wxWidgets event
- GtkHDisconnectEvent();
- gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "value_changed" );
- GtkHConnectEvent();
- }
- else
- {
- // Just update the scrollbar, don't send any wxWidgets event
- GtkVDisconnectEvent();
- gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust), "value_changed" );
- GtkVConnectEvent();
- }
- }
-}
-
-void wxScrolledWindow::GtkVConnectEvent()
-{
- gtk_signal_connect( GTK_OBJECT(m_vAdjust), "value_changed",
- (GtkSignalFunc) gtk_scrolled_window_vscroll_callback, (gpointer) this );
-}
-
-void wxScrolledWindow::GtkHConnectEvent()
-{
- gtk_signal_connect( GTK_OBJECT(m_hAdjust), "value_changed",
- (GtkSignalFunc) gtk_scrolled_window_hscroll_callback, (gpointer) this );
-}
+ int w, h;
+ int vw, vh;
-void wxScrolledWindow::GtkHDisconnectEvent()
-{
- gtk_signal_disconnect_by_func( GTK_OBJECT(m_hAdjust),
- (GtkSignalFunc) gtk_scrolled_window_hscroll_callback, (gpointer) this );
-}
+ m_targetWindow->GetClientSize( &w, &h );
+ m_targetWindow->GetVirtualSize( &vw, &vh );
-void wxScrolledWindow::GtkVDisconnectEvent()
-{
- gtk_signal_disconnect_by_func( GTK_OBJECT(m_vAdjust),
- (GtkSignalFunc) gtk_scrolled_window_vscroll_callback, (gpointer) this );
+ 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);
}
-bool wxScrolledWindow::Layout()
+void wxScrollHelperNative::DoScroll(int orient,
+ GtkAdjustment *adj,
+ int pos,
+ int pixelsPerLine,
+ int *posOld)
{
- if (GetSizer() && m_targetWindow == this)
+ if ( pos != -1 && pos != *posOld && pixelsPerLine )
{
- // If we're the scroll target, take into account the
- // virtual size and scrolled position of the window.
+ 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;
- int x, y, w, h;
- CalcScrolledPosition(0,0, &x,&y);
- GetVirtualSize(&w, &h);
- GetSizer()->SetDimension(x, y, w, h);
- return TRUE;
- }
- else
- return wxPanel::Layout(); // fall back to default for LayoutConstraints
-}
+ adj->value = pos;
-// ----------------------------------------------------------------------------
-// event handlers
-// ----------------------------------------------------------------------------
+ int diff = (*posOld - pos)*pixelsPerLine;
+ m_targetWindow->ScrollWindow(orient == wxHORIZONTAL ? diff : 0,
+ orient == wxHORIZONTAL ? 0 : diff);
-// Default OnSize resets scrollbars, if any
-void wxScrolledWindow::OnSize(wxSizeEvent& WXUNUSED(event))
-{
- if ( m_targetWindow->GetAutoLayout() )
- {
- wxSize size = m_targetWindow->GetBestVirtualSize();
+ *posOld = pos;
- // This will call ::Layout() and ::AdjustScrollbars()
- SetVirtualSize( size );
- }
- else
- {
- AdjustScrollbars();
+ m_win->GtkUpdateScrollbar(orient);
}
}
-// This calls OnDraw, having adjusted the origin according to the current
-// scroll position
-void wxScrolledWindow::OnPaint(wxPaintEvent& WXUNUSED(event))
+void wxScrollHelperNative::Scroll( int x_pos, int y_pos )
{
- wxPaintDC dc(this);
- PrepareDC(dc);
-
- OnDraw(dc);
-}
-
-// kbd handling: notice that we use OnChar() and not OnKeyDown() for
-// 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)
-{
- int stx, sty, // view origin
- szx, szy, // view size (total)
- clix, cliy; // view size (on screen)
-
- GetViewStart(&stx, &sty);
- GetClientSize(&clix, &cliy);
- GetVirtualSize(&szx, &szy);
-
- if( m_xScrollPixelsPerLine )
- {
- clix /= m_xScrollPixelsPerLine;
- szx /= m_xScrollPixelsPerLine;
- }
- else
- {
- clix = 0;
- szx = -1;
- }
- if( m_yScrollPixelsPerLine )
- {
- cliy /= m_yScrollPixelsPerLine;
- szy /= m_yScrollPixelsPerLine;
- }
- else
- {
- cliy = 0;
- szy = -1;
- }
-
- int xScrollOld = GetScrollPos(wxHORIZONTAL),
- yScrollOld = GetScrollPos(wxVERTICAL);
-
- int dsty;
- switch ( event.GetKeyCode() )
- {
- case WXK_PAGEUP:
- case WXK_PRIOR:
- dsty = sty - (5 * cliy / 6);
- Scroll(-1, (dsty == -1) ? 0 : dsty);
- break;
-
- case WXK_PAGEDOWN:
- case WXK_NEXT:
- Scroll(-1, sty + (5 * cliy / 6));
- break;
-
- case WXK_HOME:
- Scroll(0, event.ControlDown() ? 0 : -1);
- break;
-
- case WXK_END:
- Scroll(szx - clix, event.ControlDown() ? szy - cliy : -1);
- break;
-
- case WXK_UP:
- Scroll(-1, sty - 1);
- break;
-
- case WXK_DOWN:
- Scroll(-1, sty + 1);
- break;
+ wxCHECK_RET( m_targetWindow != 0, _T("No target window") );
- case WXK_LEFT:
- Scroll(stx - 1, -1);
- break;
-
- case WXK_RIGHT:
- Scroll(stx + 1, -1);
- break;
-
- default:
- // not for us
- event.Skip();
- return;
- }
-
- int xScroll = GetScrollPos(wxHORIZONTAL);
- if ( xScroll != xScrollOld )
- {
- wxScrollWinEvent eventS(wxEVT_SCROLLWIN_THUMBTRACK, xScroll,
- wxHORIZONTAL);
- eventS.SetEventObject(this);
- GetEventHandler()->ProcessEvent(eventS);
- }
-
- int yScroll = GetScrollPos(wxVERTICAL);
- if ( yScroll != yScrollOld )
- {
- wxScrollWinEvent eventS(wxEVT_SCROLLWIN_THUMBTRACK, yScroll,
- wxVERTICAL);
- eventS.SetEventObject(this);
- GetEventHandler()->ProcessEvent(eventS);
- }
+ DoScroll(wxHORIZONTAL, m_win->m_hAdjust, x_pos, m_xScrollPixelsPerLine,
+ &m_xScrollPosition);
+ DoScroll(wxVERTICAL, m_win->m_vAdjust, y_pos, m_yScrollPixelsPerLine,
+ &m_yScrollPosition);
}
-
-// vi:sts=4:sw=4:et