tons of changes:
1. wxListBox class added 2. wxInputHandler rewritten (Map() -> Handle()) 3. wxScrollBar redrawing completely changed git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/wxUNIVERSAL@8228 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -27,7 +27,7 @@
|
|||||||
WXDLLEXPORT_DATA(extern const wxChar*) wxFrameNameStr;
|
WXDLLEXPORT_DATA(extern const wxChar*) wxFrameNameStr;
|
||||||
WXDLLEXPORT_DATA(extern const wxChar*) wxStatusLineNameStr;
|
WXDLLEXPORT_DATA(extern const wxChar*) wxStatusLineNameStr;
|
||||||
WXDLLEXPORT_DATA(extern const wxChar*) wxToolBarNameStr;
|
WXDLLEXPORT_DATA(extern const wxChar*) wxToolBarNameStr;
|
||||||
WXDLLEXPORT_DATA(extern wxWindow*) wxWndHook;
|
WXDLLEXPORT_DATA(extern wxWindowMSW*) wxWndHook;
|
||||||
|
|
||||||
class WXDLLEXPORT wxMenuBar;
|
class WXDLLEXPORT wxMenuBar;
|
||||||
class WXDLLEXPORT wxStatusBar;
|
class WXDLLEXPORT wxStatusBar;
|
||||||
|
@@ -28,25 +28,31 @@ WXDLLEXPORT_DATA(extern const wxChar*) wxPanelNameStr;
|
|||||||
// default scrolled window style
|
// default scrolled window style
|
||||||
#define wxScrolledWindowStyle (wxHSCROLL | wxVSCROLL)
|
#define wxScrolledWindowStyle (wxHSCROLL | wxVSCROLL)
|
||||||
|
|
||||||
|
// avoid triggering this stupid VC++ warning
|
||||||
|
#ifdef __VISUALC__
|
||||||
|
#pragma warning(disable:4355) // 'this' used in base member initializer list
|
||||||
|
#endif
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// wxScrolledWindow
|
// wxScrolledWindow
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
class WXDLLEXPORT wxScrolledWindow : public wxPanel
|
class WXDLLEXPORT wxScrolledWindow : public wxPanel, public wxScrollHelper
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
wxScrolledWindow();
|
wxScrolledWindow() : wxScrollHelper(this) { }
|
||||||
wxScrolledWindow(wxWindow *parent,
|
wxScrolledWindow(wxWindow *parent,
|
||||||
wxWindowID id = -1,
|
wxWindowID id = -1,
|
||||||
const wxPoint& pos = wxDefaultPosition,
|
const wxPoint& pos = wxDefaultPosition,
|
||||||
const wxSize& size = wxDefaultSize,
|
const wxSize& size = wxDefaultSize,
|
||||||
long style = wxScrolledWindowStyle,
|
long style = wxScrolledWindowStyle,
|
||||||
const wxString& name = wxPanelNameStr)
|
const wxString& name = wxPanelNameStr)
|
||||||
|
: wxScrollHelper(this)
|
||||||
{
|
{
|
||||||
Create(parent, id, pos, size, style, name);
|
Create(parent, id, pos, size, style, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
~wxScrolledWindow();
|
virtual ~wxScrolledWindow();
|
||||||
|
|
||||||
bool Create(wxWindow *parent,
|
bool Create(wxWindow *parent,
|
||||||
wxWindowID id,
|
wxWindowID id,
|
||||||
@@ -55,98 +61,15 @@ public:
|
|||||||
long style = wxScrolledWindowStyle,
|
long style = wxScrolledWindowStyle,
|
||||||
const wxString& name = wxPanelNameStr);
|
const wxString& name = wxPanelNameStr);
|
||||||
|
|
||||||
// Normally the wxScrolledWindow will scroll itself, but in
|
virtual void PrepareDC(wxDC& dc) { DoPrepareDC(dc); }
|
||||||
// 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 );
|
|
||||||
virtual wxWindow *GetTargetWindow();
|
|
||||||
|
|
||||||
// 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
|
|
||||||
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);
|
|
||||||
|
|
||||||
#if WXWIN_COMPATIBILITY
|
|
||||||
virtual void GetScrollUnitsPerPage(int *x_page, int *y_page) const;
|
|
||||||
virtual void CalcUnscrolledPosition(int x, int y, float *xx, float *yy) const;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
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, wxWindows 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;
|
|
||||||
// Compatibility
|
|
||||||
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;
|
|
||||||
|
|
||||||
// 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; }
|
|
||||||
|
|
||||||
virtual void CalcScrolledPosition(int x, int y, int *xx, int *yy) const;
|
|
||||||
virtual void CalcUnscrolledPosition(int x, int y, int *xx, int *yy) const;
|
|
||||||
|
|
||||||
// Adjust the scrollbars
|
|
||||||
virtual void AdjustScrollbars(void);
|
|
||||||
|
|
||||||
// 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.
|
|
||||||
virtual void PrepareDC(wxDC& dc);
|
|
||||||
|
|
||||||
// implementation from now on
|
|
||||||
void OnScroll(wxScrollWinEvent& event);
|
|
||||||
void OnSize(wxSizeEvent& event);
|
|
||||||
void OnPaint(wxPaintEvent& event);
|
|
||||||
void OnChar(wxKeyEvent& event);
|
|
||||||
|
|
||||||
// Calculate scroll increment
|
|
||||||
virtual int CalcScrollInc(wxScrollWinEvent& event);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
wxWindow *m_targetWindow;
|
|
||||||
int m_xScrollPixelsPerLine;
|
|
||||||
int m_yScrollPixelsPerLine;
|
|
||||||
bool m_xScrollingEnabled;
|
|
||||||
bool m_yScrollingEnabled;
|
|
||||||
int m_xScrollPosition;
|
|
||||||
int m_yScrollPosition;
|
|
||||||
int m_xScrollLines;
|
|
||||||
int m_yScrollLines;
|
|
||||||
int m_xScrollLinesPerPage;
|
|
||||||
int m_yScrollLinesPerPage;
|
|
||||||
double m_scaleX;
|
|
||||||
double m_scaleY;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DECLARE_EVENT_TABLE()
|
|
||||||
DECLARE_ABSTRACT_CLASS(wxScrolledWindow)
|
DECLARE_ABSTRACT_CLASS(wxScrolledWindow)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef __VISUALC__
|
||||||
|
#pragma warning(default:4355)
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
// _WX_GENERIC_SCROLLWIN_H_
|
// _WX_GENERIC_SCROLLWIN_H_
|
||||||
|
@@ -78,6 +78,16 @@ public:
|
|||||||
void SetFirstItem(int n) { DoSetFirstItem(n); }
|
void SetFirstItem(int n) { DoSetFirstItem(n); }
|
||||||
void SetFirstItem(const wxString& s);
|
void SetFirstItem(const wxString& s);
|
||||||
|
|
||||||
|
// return TRUE if the listbox allows multiple selection
|
||||||
|
bool HasMultipleSelection() const
|
||||||
|
{
|
||||||
|
return (m_windowStyle & wxLB_MULTIPLE) ||
|
||||||
|
(m_windowStyle & wxLB_EXTENDED);
|
||||||
|
}
|
||||||
|
|
||||||
|
// return TRUE if this listbox is sorted
|
||||||
|
bool IsSorted() const { return (m_windowStyle & wxLB_SORT) != 0; }
|
||||||
|
|
||||||
// emulate selecting or deselecting the item event.GetInt() (depending on
|
// emulate selecting or deselecting the item event.GetInt() (depending on
|
||||||
// event.GetExtraLong())
|
// event.GetExtraLong())
|
||||||
void Command(wxCommandEvent& event);
|
void Command(wxCommandEvent& event);
|
||||||
@@ -103,7 +113,9 @@ protected:
|
|||||||
// include the platform-specific class declaration
|
// include the platform-specific class declaration
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
#if defined(__WXMSW__)
|
#if defined(__WXUNIVERSAL__)
|
||||||
|
#include "wx/univ/listbox.h"
|
||||||
|
#elif defined(__WXMSW__)
|
||||||
#include "wx/msw/listbox.h"
|
#include "wx/msw/listbox.h"
|
||||||
#elif defined(__WXMOTIF__)
|
#elif defined(__WXMOTIF__)
|
||||||
#include "wx/motif/listbox.h"
|
#include "wx/motif/listbox.h"
|
||||||
|
@@ -115,9 +115,6 @@ public:
|
|||||||
virtual void SetupColours();
|
virtual void SetupColours();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// do we have multiple selections?
|
|
||||||
bool HasMultipleSelection() const;
|
|
||||||
|
|
||||||
// free memory (common part of Clear() and dtor)
|
// free memory (common part of Clear() and dtor)
|
||||||
void Free();
|
void Free();
|
||||||
|
|
||||||
|
@@ -1,8 +1,9 @@
|
|||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
// Name: window.h
|
// Name: wx/msw/window.h
|
||||||
// Purpose: wxWindow class
|
// Purpose: wxWindow class
|
||||||
// Author: Julian Smart
|
// Author: Julian Smart
|
||||||
// Modified by:
|
// Modified by: Vadim Zeitlin on 13.05.99: complete refont of message handling,
|
||||||
|
// elimination of Default(), ...
|
||||||
// Created: 01/02/97
|
// Created: 01/02/97
|
||||||
// RCS-ID: $Id$
|
// RCS-ID: $Id$
|
||||||
// Copyright: (c) Julian Smart and Markus Holzem
|
// Copyright: (c) Julian Smart and Markus Holzem
|
||||||
@@ -20,8 +21,6 @@
|
|||||||
#pragma interface "window.h"
|
#pragma interface "window.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// #include "wx/msw/winundef.h"
|
|
||||||
|
|
||||||
// VZ: apparently some version of Windows send extra mouse move messages after
|
// VZ: apparently some version of Windows send extra mouse move messages after
|
||||||
// a mouse click. My tests under NT 4.0 and 95 didn't show it so I'm
|
// a mouse click. My tests under NT 4.0 and 95 didn't show it so I'm
|
||||||
// tempted to think that it was just an effect of a poor mouse and so the
|
// tempted to think that it was just an effect of a poor mouse and so the
|
||||||
@@ -29,12 +28,6 @@
|
|||||||
// to reenable it
|
// to reenable it
|
||||||
#define wxUSE_MOUSEEVENT_HACK 0
|
#define wxUSE_MOUSEEVENT_HACK 0
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// forward declarations
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
class WXDLLEXPORT wxButton;
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// constants
|
// constants
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@@ -50,12 +43,12 @@ enum
|
|||||||
// wxWindow declaration for MSW
|
// wxWindow declaration for MSW
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
class WXDLLEXPORT wxWindow : public wxWindowBase
|
class WXDLLEXPORT wxWindowMSW : public wxWindowBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
wxWindow() { Init(); }
|
wxWindowMSW() { Init(); }
|
||||||
|
|
||||||
wxWindow(wxWindow *parent,
|
wxWindowMSW(wxWindow *parent,
|
||||||
wxWindowID id,
|
wxWindowID id,
|
||||||
const wxPoint& pos = wxDefaultPosition,
|
const wxPoint& pos = wxDefaultPosition,
|
||||||
const wxSize& size = wxDefaultSize,
|
const wxSize& size = wxDefaultSize,
|
||||||
@@ -66,7 +59,7 @@ public:
|
|||||||
Create(parent, id, pos, size, style, name);
|
Create(parent, id, pos, size, style, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~wxWindow();
|
virtual ~wxWindowMSW();
|
||||||
|
|
||||||
bool Create(wxWindow *parent,
|
bool Create(wxWindow *parent,
|
||||||
wxWindowID id,
|
wxWindowID id,
|
||||||
@@ -87,7 +80,7 @@ public:
|
|||||||
|
|
||||||
virtual void SetFocus();
|
virtual void SetFocus();
|
||||||
|
|
||||||
virtual bool Reparent( wxWindow *newParent );
|
virtual bool Reparent(wxWindowBase *newParent);
|
||||||
|
|
||||||
virtual void WarpPointer(int x, int y);
|
virtual void WarpPointer(int x, int y);
|
||||||
virtual void CaptureMouse();
|
virtual void CaptureMouse();
|
||||||
@@ -437,8 +430,8 @@ private:
|
|||||||
// the helper functions used by HandleChar/KeyXXX methods
|
// the helper functions used by HandleChar/KeyXXX methods
|
||||||
wxKeyEvent CreateKeyEvent(wxEventType evType, int id, WXLPARAM lp) const;
|
wxKeyEvent CreateKeyEvent(wxEventType evType, int id, WXLPARAM lp) const;
|
||||||
|
|
||||||
DECLARE_DYNAMIC_CLASS(wxWindow);
|
DECLARE_DYNAMIC_CLASS(wxWindowMSW);
|
||||||
DECLARE_NO_COPY_CLASS(wxWindow);
|
DECLARE_NO_COPY_CLASS(wxWindowMSW);
|
||||||
DECLARE_EVENT_TABLE()
|
DECLARE_EVENT_TABLE()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -1,6 +1,115 @@
|
|||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Name: include/wx/scrolwin.h
|
||||||
|
// Purpose: wxScrolledWindow, wxScrolledControl and wxScrollHelper
|
||||||
|
// Author: Vadim Zeitlin
|
||||||
|
// Modified by:
|
||||||
|
// Created: 30.08.00
|
||||||
|
// RCS-ID: $Id$
|
||||||
|
// Copyright: (c) 2000 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
|
||||||
|
// Licence: wxWindows licence
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#ifndef _WX_SCROLWIN_H_BASE_
|
#ifndef _WX_SCROLWIN_H_BASE_
|
||||||
#define _WX_SCROLWIN_H_BASE_
|
#define _WX_SCROLWIN_H_BASE_
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// 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.
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class WXDLLEXPORT wxScrollHelper
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// ctor and dtor
|
||||||
|
wxScrollHelper(wxWindow *winToScroll = (wxWindow *)NULL);
|
||||||
|
void SetWindow(wxWindow *winToScroll);
|
||||||
|
virtual ~wxScrollHelper();
|
||||||
|
|
||||||
|
// configure the scrolling
|
||||||
|
virtual void SetScrollbars(int pixelsPerUnitX, int pixelsPerUnitY,
|
||||||
|
int noUnitsX, int noUnitsY,
|
||||||
|
int xPos = 0, int yPos = 0,
|
||||||
|
bool noRefresh = FALSE );
|
||||||
|
|
||||||
|
// scroll to the given (in logical coords) position
|
||||||
|
virtual void Scroll(int x, int y);
|
||||||
|
|
||||||
|
// get/set the page size for this orientation (wxVERTICAL/wxHORIZONTAL)
|
||||||
|
int GetScrollPageSize(int orient) const;
|
||||||
|
void SetScrollPageSize(int orient, int pageSize);
|
||||||
|
|
||||||
|
// get the size of one logical unit in physical ones
|
||||||
|
virtual void GetScrollPixelsPerUnit(int *pixelsPerUnitX,
|
||||||
|
int *pixelsPerUnitY) const;
|
||||||
|
|
||||||
|
// Enable/disable Windows scrolling in either direction. If TRUE, wxWindows
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
// 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; }
|
||||||
|
double GetScaleY() const { return m_scaleY; }
|
||||||
|
|
||||||
|
// translate between scrolled and unscrolled coordinates
|
||||||
|
virtual void CalcScrolledPosition(int x, int y, int *xx, int *yy) const;
|
||||||
|
virtual void CalcUnscrolledPosition(int x, int y, int *xx, int *yy) const;
|
||||||
|
|
||||||
|
// Adjust the scrollbars
|
||||||
|
virtual void AdjustScrollbars(void);
|
||||||
|
|
||||||
|
// Calculate scroll increment
|
||||||
|
virtual int CalcScrollInc(wxScrollWinEvent& event);
|
||||||
|
|
||||||
|
// 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 );
|
||||||
|
virtual wxWindow *GetTargetWindow() const;
|
||||||
|
|
||||||
|
// Override this function to draw the graphic (or just process EVT_PAINT)
|
||||||
|
virtual void OnDraw(wxDC& WXUNUSED(dc)) { }
|
||||||
|
|
||||||
|
// change the DC origin according to the scroll position.
|
||||||
|
void DoPrepareDC(wxDC& dc);
|
||||||
|
|
||||||
|
// the methods to be called from the window event handlers
|
||||||
|
void HandleOnScroll(wxScrollWinEvent& event);
|
||||||
|
void HandleOnSize(wxSizeEvent& event);
|
||||||
|
void HandleOnPaint(wxPaintEvent& event);
|
||||||
|
void HandleOnChar(wxKeyEvent& event);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
wxWindow *m_win,
|
||||||
|
*m_targetWindow;
|
||||||
|
|
||||||
|
int m_xScrollPixelsPerLine;
|
||||||
|
int m_yScrollPixelsPerLine;
|
||||||
|
int m_xScrollPosition;
|
||||||
|
int m_yScrollPosition;
|
||||||
|
int m_xScrollLines;
|
||||||
|
int m_yScrollLines;
|
||||||
|
int m_xScrollLinesPerPage;
|
||||||
|
int m_yScrollLinesPerPage;
|
||||||
|
|
||||||
|
bool m_xScrollingEnabled;
|
||||||
|
bool m_yScrollingEnabled;
|
||||||
|
|
||||||
|
double m_scaleX;
|
||||||
|
double m_scaleY;
|
||||||
|
};
|
||||||
|
|
||||||
#include "wx/generic/scrolwin.h"
|
#include "wx/generic/scrolwin.h"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -1008,6 +1008,7 @@ public:
|
|||||||
void Remove(const wxChar *sz);
|
void Remove(const wxChar *sz);
|
||||||
// remove item by index
|
// remove item by index
|
||||||
void Remove(size_t nIndex);
|
void Remove(size_t nIndex);
|
||||||
|
void RemoveAt(size_t nIndex) { Remove(nIndex); }
|
||||||
|
|
||||||
// sorting
|
// sorting
|
||||||
// sort array elements in alphabetical order (or reversed alphabetical
|
// sort array elements in alphabetical order (or reversed alphabetical
|
||||||
|
@@ -106,8 +106,9 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual bool PerformAction(const wxControlAction& action,
|
virtual bool PerformAction(const wxControlAction& action,
|
||||||
const wxEvent& event);
|
long numArg = 0,
|
||||||
virtual wxSize DoGetBestSize() const;
|
const wxString& strArg = wxEmptyString);
|
||||||
|
virtual wxSize DoGetBestClientSize() const;
|
||||||
virtual void DoDraw(wxControlRenderer *renderer);
|
virtual void DoDraw(wxControlRenderer *renderer);
|
||||||
|
|
||||||
// common part of all ctors
|
// common part of all ctors
|
||||||
|
@@ -22,32 +22,10 @@ class WXDLLEXPORT wxRenderer;
|
|||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// wxControlAction: the action is currently just a string which identifies it,
|
// wxControlAction: the action is currently just a string which identifies it,
|
||||||
// later it might become an atom (i.e. an opaque handler to string). As one
|
// later it might become an atom (i.e. an opaque handler to string).
|
||||||
// input event may result in several control actions (e.g. a macro expansion
|
|
||||||
// in the text control) we define an array of actions as well.
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
typedef wxString wxControlAction;
|
typedef wxString wxControlAction;
|
||||||
class WXDLLEXPORT wxControlActions : public wxArrayString
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
wxControlActions() { }
|
|
||||||
wxControlActions(const wxControlAction& action)
|
|
||||||
{ wxArrayString::Add(action); }
|
|
||||||
wxControlActions(const wxChar *action)
|
|
||||||
{ wxArrayString::Add(action); }
|
|
||||||
|
|
||||||
wxControlActions& Add(const wxControlActions& other)
|
|
||||||
{
|
|
||||||
size_t count = other.GetCount();
|
|
||||||
for ( size_t n = 0; n < count; n++ )
|
|
||||||
{
|
|
||||||
wxArrayString::Add(other[n]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// the list of actions which apply to all controls (other actions are defined
|
// the list of actions which apply to all controls (other actions are defined
|
||||||
// in the controls headers)
|
// in the controls headers)
|
||||||
@@ -87,7 +65,7 @@ public:
|
|||||||
virtual void SetLabel(const wxString &label);
|
virtual void SetLabel(const wxString &label);
|
||||||
virtual wxString GetLabel() const;
|
virtual wxString GetLabel() const;
|
||||||
|
|
||||||
// implementation only from now on
|
// wxUniversal-specific methods
|
||||||
|
|
||||||
// return the index of the accel char in the label or -1 if none
|
// return the index of the accel char in the label or -1 if none
|
||||||
int GetAccelIndex() const { return m_indexAccel; }
|
int GetAccelIndex() const { return m_indexAccel; }
|
||||||
@@ -98,13 +76,24 @@ public:
|
|||||||
return m_indexAccel == -1 ? _T('\0') : m_label[m_indexAccel];
|
return m_indexAccel == -1 ? _T('\0') : m_label[m_indexAccel];
|
||||||
}
|
}
|
||||||
|
|
||||||
// perform the action which resulted from the translation of the event
|
// perform a control-dependent action: an action may have an optional
|
||||||
// (the exact event type depends on the action), return TRUE if the
|
// numeric and another (also optional) string argument whose interpretation
|
||||||
// control must be updated
|
// depends on the action
|
||||||
|
//
|
||||||
|
// NB: we might use ellipsis in PerformAction() declaration but this
|
||||||
|
// wouldn't be more efficient than always passing 2 unused parameters
|
||||||
|
// but would be more difficult. Another solution would be to have
|
||||||
|
// several overloaded versions but this will expose the problem of
|
||||||
|
// virtual function hiding we don't have here.
|
||||||
virtual bool PerformAction(const wxControlAction& action,
|
virtual bool PerformAction(const wxControlAction& action,
|
||||||
const wxEvent& event);
|
long numArg = 0l,
|
||||||
|
const wxString& strArg = wxEmptyString);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
// by default static controls don't have the border and all the others do
|
||||||
|
// have it
|
||||||
|
virtual wxBorder GetDefaultBorder() const;
|
||||||
|
|
||||||
// create the event translator object for this control: the base class
|
// create the event translator object for this control: the base class
|
||||||
// action creates the default one which doesn't do anything
|
// action creates the default one which doesn't do anything
|
||||||
virtual wxInputHandler *CreateInputHandler() const;
|
virtual wxInputHandler *CreateInputHandler() const;
|
||||||
@@ -119,9 +108,6 @@ private:
|
|||||||
// common part of all ctors
|
// common part of all ctors
|
||||||
void Init();
|
void Init();
|
||||||
|
|
||||||
// common part of OnMouse/OnKeyDown/Up
|
|
||||||
void PerformActions(const wxControlActions& actions, const wxEvent& event);
|
|
||||||
|
|
||||||
// input processor
|
// input processor
|
||||||
wxInputHandler *m_handler;
|
wxInputHandler *m_handler;
|
||||||
|
|
||||||
|
@@ -19,6 +19,8 @@
|
|||||||
|
|
||||||
#include "wx/control.h" // for wxControlAction(s)
|
#include "wx/control.h" // for wxControlAction(s)
|
||||||
|
|
||||||
|
#include "wx/univ/renderer.h" // for wxHitTest
|
||||||
|
|
||||||
class WXDLLEXPORT wxRenderer;
|
class WXDLLEXPORT wxRenderer;
|
||||||
class WXDLLEXPORT wxScrollBar;
|
class WXDLLEXPORT wxScrollBar;
|
||||||
|
|
||||||
@@ -30,31 +32,27 @@ class WXDLLEXPORT wxInputHandler
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// map a keyboard event to one or more actions (pressed == TRUE if the key
|
// map a keyboard event to one or more actions (pressed == TRUE if the key
|
||||||
// was pressed, FALSE if released)
|
// was pressed, FALSE if released), returns TRUE if something was done
|
||||||
virtual wxControlActions Map(wxControl *control,
|
virtual bool HandleKey(wxControl *control,
|
||||||
const wxKeyEvent& event,
|
const wxKeyEvent& event,
|
||||||
bool pressed) = 0;
|
bool pressed) = 0;
|
||||||
|
|
||||||
// map a mouse (click) event to one or more actions
|
// map a mouse (click) event to one or more actions
|
||||||
virtual wxControlActions Map(wxControl *control,
|
virtual bool HandleMouse(wxControl *control,
|
||||||
const wxMouseEvent& event) = 0;
|
const wxMouseEvent& event) = 0;
|
||||||
|
|
||||||
// do something with mouse move/enter/leave: unlike the Map() functions,
|
// handle mouse movement (or enter/leave) event: it is separated from
|
||||||
// this doesn't translate the event into an action but, normally, uses the
|
// HandleMouse() for convenience as many controls don't care about mouse
|
||||||
// renderer directly to change the controls appearance as needed
|
// movements at all
|
||||||
//
|
virtual bool HandleMouseMove(wxControl *control,
|
||||||
// this is faster than using Map() which is important for mouse move
|
const wxMouseEvent& event);
|
||||||
// events as they occur often and in a quick succession
|
|
||||||
//
|
|
||||||
// return TRUE to refresh the control, FALSE otherwise
|
|
||||||
virtual bool OnMouseMove(wxControl *control, const wxMouseEvent& event);
|
|
||||||
|
|
||||||
// do something with focus set/kill event: this is different from
|
// do something with focus set/kill event: this is different from
|
||||||
// OnMouseMove() as the mouse maybe over the control without it having
|
// HandleMouseMove() as the mouse maybe over the control without it having
|
||||||
// focus
|
// focus
|
||||||
//
|
//
|
||||||
// return TRUE to refresh the control, FALSE otherwise
|
// return TRUE to refresh the control, FALSE otherwise
|
||||||
virtual bool OnFocus(wxControl *control, const wxFocusEvent& event);
|
virtual bool HandleFocus(wxControl *control, const wxFocusEvent& event);
|
||||||
|
|
||||||
// virtual dtor for any base class
|
// virtual dtor for any base class
|
||||||
virtual ~wxInputHandler();
|
virtual ~wxInputHandler();
|
||||||
@@ -76,17 +74,17 @@ class WXDLLEXPORT wxStdInputHandler : public wxInputHandler
|
|||||||
public:
|
public:
|
||||||
wxStdInputHandler(wxInputHandler *handler) : m_handler(handler) { }
|
wxStdInputHandler(wxInputHandler *handler) : m_handler(handler) { }
|
||||||
|
|
||||||
virtual wxControlActions Map(wxControl *control,
|
virtual bool HandleKey(wxControl *control,
|
||||||
const wxKeyEvent& event,
|
const wxKeyEvent& event,
|
||||||
bool pressed)
|
bool pressed)
|
||||||
{ return m_handler->Map(control, event, pressed); }
|
{ return m_handler->HandleKey(control, event, pressed); }
|
||||||
virtual wxControlActions Map(wxControl *control,
|
virtual bool HandleMouse(wxControl *control,
|
||||||
const wxMouseEvent& event)
|
const wxMouseEvent& event)
|
||||||
{ return m_handler->Map(control, event); }
|
{ return m_handler->HandleMouse(control, event); }
|
||||||
virtual bool OnMouseMove(wxControl *control, const wxMouseEvent& event)
|
virtual bool HandleMouseMove(wxControl *control, const wxMouseEvent& event)
|
||||||
{ return m_handler->OnMouseMove(control, event); }
|
{ return m_handler->HandleMouseMove(control, event); }
|
||||||
virtual bool OnFocus(wxControl *control, const wxFocusEvent& event)
|
virtual bool HandleFocus(wxControl *control, const wxFocusEvent& event)
|
||||||
{ return m_handler->OnFocus(control, event); }
|
{ return m_handler->HandleFocus(control, event); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
wxInputHandler *m_handler;
|
wxInputHandler *m_handler;
|
||||||
@@ -102,13 +100,13 @@ class WXDLLEXPORT wxStdButtonInputHandler : public wxStdInputHandler
|
|||||||
public:
|
public:
|
||||||
wxStdButtonInputHandler(wxInputHandler *inphand);
|
wxStdButtonInputHandler(wxInputHandler *inphand);
|
||||||
|
|
||||||
virtual wxControlActions Map(wxControl *control,
|
virtual bool HandleKey(wxControl *control,
|
||||||
const wxKeyEvent& event,
|
const wxKeyEvent& event,
|
||||||
bool pressed);
|
bool pressed);
|
||||||
virtual wxControlActions Map(wxControl *control,
|
virtual bool HandleMouse(wxControl *control,
|
||||||
const wxMouseEvent& event);
|
const wxMouseEvent& event);
|
||||||
virtual bool OnMouseMove(wxControl *control, const wxMouseEvent& event);
|
virtual bool HandleMouseMove(wxControl *control, const wxMouseEvent& event);
|
||||||
virtual bool OnFocus(wxControl *control, const wxFocusEvent& event);
|
virtual bool HandleFocus(wxControl *control, const wxFocusEvent& event);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// the window (button) which has capture or NULL and the flag telling if
|
// the window (button) which has capture or NULL and the flag telling if
|
||||||
@@ -130,12 +128,12 @@ public:
|
|||||||
wxStdScrollBarInputHandler(wxRenderer *renderer,
|
wxStdScrollBarInputHandler(wxRenderer *renderer,
|
||||||
wxInputHandler *inphand);
|
wxInputHandler *inphand);
|
||||||
|
|
||||||
virtual wxControlActions Map(wxControl *control,
|
virtual bool HandleKey(wxControl *control,
|
||||||
const wxKeyEvent& event,
|
const wxKeyEvent& event,
|
||||||
bool pressed);
|
bool pressed);
|
||||||
virtual wxControlActions Map(wxControl *control,
|
virtual bool HandleMouse(wxControl *control,
|
||||||
const wxMouseEvent& event);
|
const wxMouseEvent& event);
|
||||||
virtual bool OnMouseMove(wxControl *control, const wxMouseEvent& event);
|
virtual bool HandleMouseMove(wxControl *control, const wxMouseEvent& event);
|
||||||
|
|
||||||
virtual ~wxStdScrollBarInputHandler();
|
virtual ~wxStdScrollBarInputHandler();
|
||||||
|
|
||||||
@@ -143,8 +141,7 @@ public:
|
|||||||
//
|
//
|
||||||
// return TRUE to continue scrolling, FALSE to stop the timer
|
// return TRUE to continue scrolling, FALSE to stop the timer
|
||||||
virtual bool OnScrollTimer(wxScrollBar *scrollbar,
|
virtual bool OnScrollTimer(wxScrollBar *scrollbar,
|
||||||
const wxControlAction& action,
|
const wxControlAction& action);
|
||||||
const wxMouseEvent& event);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// the methods which must be overridden in the derived class
|
// the methods which must be overridden in the derived class
|
||||||
@@ -169,6 +166,13 @@ protected:
|
|||||||
// stop scrolling because we reached the end point
|
// stop scrolling because we reached the end point
|
||||||
void StopScrolling(wxScrollBar *scrollbar);
|
void StopScrolling(wxScrollBar *scrollbar);
|
||||||
|
|
||||||
|
// get the mouse coordinates in the scrollbar direction from the event
|
||||||
|
wxCoord GetMouseCoord(const wxScrollBar *scrollbar,
|
||||||
|
const wxMouseEvent& event) const;
|
||||||
|
|
||||||
|
// generate a "thumb move" action for this mouse event
|
||||||
|
void HandleThumbMove(wxScrollBar *scrollbar, const wxMouseEvent& event);
|
||||||
|
|
||||||
// the window (scrollbar) which has capture or NULL and the flag telling if
|
// the window (scrollbar) which has capture or NULL and the flag telling if
|
||||||
// the mouse is inside the element which captured it or not
|
// the mouse is inside the element which captured it or not
|
||||||
wxWindow *m_winCapture;
|
wxWindow *m_winCapture;
|
||||||
@@ -184,9 +188,32 @@ protected:
|
|||||||
// the renderer (we use it only for hit testing)
|
// the renderer (we use it only for hit testing)
|
||||||
wxRenderer *m_renderer;
|
wxRenderer *m_renderer;
|
||||||
|
|
||||||
|
// the offset of the top/left of the scrollbar relative to the mouse to
|
||||||
|
// keep during the thumb drag
|
||||||
|
int m_ofsMouse;
|
||||||
|
|
||||||
// the timer for generating scroll events when the mouse stays pressed on
|
// the timer for generating scroll events when the mouse stays pressed on
|
||||||
// a scrollbar
|
// a scrollbar
|
||||||
class wxTimer *m_timerScroll;
|
class wxTimer *m_timerScroll;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// wxStdListboxInputHandler: handles mouse and kbd in a single or multi
|
||||||
|
// selection listbox
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class WXDLLEXPORT wxStdListboxInputHandler : public wxStdInputHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
wxStdListboxInputHandler(wxInputHandler *inphand);
|
||||||
|
|
||||||
|
virtual bool HandleKey(wxControl *control,
|
||||||
|
const wxKeyEvent& event,
|
||||||
|
bool pressed);
|
||||||
|
virtual bool HandleMouse(wxControl *control,
|
||||||
|
const wxMouseEvent& event);
|
||||||
|
virtual bool HandleMouseMove(wxControl *control,
|
||||||
|
const wxMouseEvent& event);
|
||||||
|
};
|
||||||
|
|
||||||
#endif // _WX_UNIV_INPHAND_H_
|
#endif // _WX_UNIV_INPHAND_H_
|
||||||
|
191
include/wx/univ/listbox.h
Normal file
191
include/wx/univ/listbox.h
Normal file
@@ -0,0 +1,191 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Name: wx/univ/listbox.h
|
||||||
|
// Purpose: the universal listbox
|
||||||
|
// Author: Vadim Zeitlin
|
||||||
|
// Modified by:
|
||||||
|
// Created: 30.08.00
|
||||||
|
// RCS-ID: $Id$
|
||||||
|
// Copyright: (c) 2000 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
|
||||||
|
// Licence: wxWindows licence
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef _WX_UNIV_LISTBOX_H_
|
||||||
|
#define _WX_UNIV_LISTBOX_H_
|
||||||
|
|
||||||
|
#ifdef __GNUG__
|
||||||
|
#pragma implementation "univlistbox.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "wx/scrolwin.h" // for wxScrollHelper
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// the actions supported by this control
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// change the current item
|
||||||
|
#define wxACTION_LISTBOX_SETFOCUS _T("setfocus") // select the item
|
||||||
|
#define wxACTION_LISTBOX_MOVEDOWN _T("down") // select item below
|
||||||
|
#define wxACTION_LISTBOX_MOVEUP _T("up") // select item above
|
||||||
|
#define wxACTION_LISTBOX_PAGEDOWN _T("pagedown") // go page down
|
||||||
|
#define wxACTION_LISTBOX_PAGEUP _T("pageup") // go page up
|
||||||
|
#define wxACTION_LISTBOX_START _T("start") // go to first item
|
||||||
|
#define wxACTION_LISTBOX_END _T("end") // go to last item
|
||||||
|
|
||||||
|
// do something with the current item
|
||||||
|
#define wxACTION_LISTBOX_ACTIVATE _T("activate") // activate (choose)
|
||||||
|
#define wxACTION_LISTBOX_TOGGLE _T("toggle") // togglee selected state
|
||||||
|
#define wxACTION_LISTBOX_SELECT _T("select") // select/focus
|
||||||
|
#define wxACTION_LISTBOX_UNSELECT _T("unselect") // unselect/unfocus
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// wxListBox: a list of selectable items
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class wxListBox : public wxListBoxBase, public wxScrollHelper
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// ctors and such
|
||||||
|
wxListBox() { Init(); }
|
||||||
|
wxListBox(wxWindow *parent,
|
||||||
|
wxWindowID id,
|
||||||
|
const wxPoint& pos = wxDefaultPosition,
|
||||||
|
const wxSize& size = wxDefaultSize,
|
||||||
|
int n = 0, const wxString choices[] = (const wxString *) NULL,
|
||||||
|
long style = 0,
|
||||||
|
const wxValidator& validator = wxDefaultValidator,
|
||||||
|
const wxString& name = wxListBoxNameStr )
|
||||||
|
{
|
||||||
|
Init();
|
||||||
|
|
||||||
|
Create(parent, id, pos, size, n, choices, style, validator, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~wxListBox();
|
||||||
|
|
||||||
|
bool Create(wxWindow *parent,
|
||||||
|
wxWindowID id,
|
||||||
|
const wxPoint& pos = wxDefaultPosition,
|
||||||
|
const wxSize& size = wxDefaultSize,
|
||||||
|
int n = 0, const wxString choices[] = (const wxString *) NULL,
|
||||||
|
long style = 0,
|
||||||
|
const wxValidator& validator = wxDefaultValidator,
|
||||||
|
const wxString& name = wxListBoxNameStr);
|
||||||
|
|
||||||
|
// implement the listbox interface defined by wxListBoxBase
|
||||||
|
virtual void Clear();
|
||||||
|
virtual void Delete(int n);
|
||||||
|
|
||||||
|
virtual int GetCount() const
|
||||||
|
{ return (int)m_strings.GetCount(); }
|
||||||
|
virtual wxString GetString(int n) const
|
||||||
|
{ return m_strings[n]; }
|
||||||
|
virtual void SetString(int n, const wxString& s)
|
||||||
|
{ m_strings[n] = s; RefreshItem(n); }
|
||||||
|
virtual int FindString(const wxString& s) const
|
||||||
|
{ return m_strings.Index(s); }
|
||||||
|
|
||||||
|
virtual bool IsSelected(int n) const
|
||||||
|
{ return m_selections.Index(n) != wxNOT_FOUND; }
|
||||||
|
virtual void SetSelection(int n, bool select = TRUE);
|
||||||
|
virtual int GetSelection() const;
|
||||||
|
virtual int GetSelections(wxArrayInt& aSelections) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual int DoAppend(const wxString& item);
|
||||||
|
virtual void DoInsertItems(const wxArrayString& items, int pos);
|
||||||
|
virtual void DoSetItems(const wxArrayString& items, void **clientData);
|
||||||
|
|
||||||
|
virtual void DoSetFirstItem(int n);
|
||||||
|
|
||||||
|
virtual void DoSetItemClientData(int n, void* clientData);
|
||||||
|
virtual void* DoGetItemClientData(int n) const;
|
||||||
|
virtual void DoSetItemClientObject(int n, wxClientData* clientData);
|
||||||
|
virtual wxClientData* DoGetItemClientObject(int n) const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// override some more base class methods
|
||||||
|
virtual bool SetFont(const wxFont& font);
|
||||||
|
|
||||||
|
// the wxUniversal-specific additions
|
||||||
|
|
||||||
|
// the current item is the same as the selected one for wxLB_SINGLE
|
||||||
|
// listboxes but for the other ones it is just the focused item which may
|
||||||
|
// be selected or not
|
||||||
|
int GetCurrentItem() const { return m_current; }
|
||||||
|
void SetCurrentItem(int n);
|
||||||
|
|
||||||
|
// select the item which is diff items below the current one
|
||||||
|
void ChangeCurrent(int diff);
|
||||||
|
|
||||||
|
// actions
|
||||||
|
void Activate();
|
||||||
|
void Select(bool sel = TRUE);
|
||||||
|
|
||||||
|
// get, calculating it if necessary, the number of items per page and the
|
||||||
|
// height of each line
|
||||||
|
int GetItemsPerPage() const;
|
||||||
|
wxCoord GetLineHeight() const;
|
||||||
|
|
||||||
|
// override the wxControl virtual methods
|
||||||
|
virtual bool PerformAction(const wxControlAction& action,
|
||||||
|
long numArg = 0l,
|
||||||
|
const wxString& strArg = wxEmptyString);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual wxSize DoGetBestClientSize() const;
|
||||||
|
virtual void DoDraw(wxControlRenderer *renderer);
|
||||||
|
|
||||||
|
// common part of all ctors
|
||||||
|
void Init();
|
||||||
|
|
||||||
|
// event handlers
|
||||||
|
void OnIdle(wxIdleEvent& event);
|
||||||
|
void OnSize(wxSizeEvent& event);
|
||||||
|
|
||||||
|
// common part of Clear() and DoSetItems(): clears everything
|
||||||
|
void DoClear();
|
||||||
|
|
||||||
|
// refresh the given item(s) or everything
|
||||||
|
void RefreshItems(int from, int count);
|
||||||
|
void RefreshItem(int n);
|
||||||
|
void RefreshAll();
|
||||||
|
|
||||||
|
// send an event of the given type
|
||||||
|
bool SendEvent(int item, wxEventType type);
|
||||||
|
|
||||||
|
// calculate the number of items per page using our current size
|
||||||
|
void CalcItemsPerPage();
|
||||||
|
|
||||||
|
// the array containing all items (it is sorted if the listbox has
|
||||||
|
// wxLB_SORT style)
|
||||||
|
wxArrayString m_strings;
|
||||||
|
|
||||||
|
// this array contains the indices of the selected items (for the single
|
||||||
|
// selection listboxes only the first element of it is used and contains
|
||||||
|
// the current selection)
|
||||||
|
wxArrayInt m_selections;
|
||||||
|
|
||||||
|
// and this one the client data (either void or wxClientData)
|
||||||
|
wxArrayPtrVoid m_clientData;
|
||||||
|
|
||||||
|
// the current item
|
||||||
|
int m_current;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// the range of elements which must be updated: if m_updateCount is 0 no
|
||||||
|
// update is needed, if it is -1 everything must be updated, otherwise
|
||||||
|
// m_updateCount items starting from m_updateFrom have to be redrawn
|
||||||
|
int m_updateFrom,
|
||||||
|
m_updateCount;
|
||||||
|
|
||||||
|
// the height of one line in the listbox (all lines have the same height)
|
||||||
|
wxCoord m_lineHeight;
|
||||||
|
|
||||||
|
// the number of items per page
|
||||||
|
size_t m_itemsPerPage;
|
||||||
|
|
||||||
|
DECLARE_EVENT_TABLE()
|
||||||
|
DECLARE_DYNAMIC_CLASS(wxListBox)
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _WX_UNIV_LISTBOX_H_
|
@@ -29,11 +29,13 @@
|
|||||||
#define _WX_UNIV_RENDERER_H_
|
#define _WX_UNIV_RENDERER_H_
|
||||||
|
|
||||||
class WXDLLEXPORT wxDC;
|
class WXDLLEXPORT wxDC;
|
||||||
|
class WXDLLEXPORT wxListBox;
|
||||||
class WXDLLEXPORT wxScrollBar;
|
class WXDLLEXPORT wxScrollBar;
|
||||||
class WXDLLEXPORT wxWindow;
|
class WXDLLEXPORT wxWindow;
|
||||||
|
|
||||||
#include "wx/string.h"
|
#include "wx/string.h"
|
||||||
#include "wx/gdicmn.h"
|
#include "wx/gdicmn.h"
|
||||||
|
#include "wx/scrolbar.h" // for wxScrollBar::Element
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// constants
|
// constants
|
||||||
@@ -70,6 +72,7 @@ public:
|
|||||||
|
|
||||||
// draw the controls background
|
// draw the controls background
|
||||||
virtual void DrawBackground(wxDC& dc,
|
virtual void DrawBackground(wxDC& dc,
|
||||||
|
const wxColour& col,
|
||||||
const wxRect& rect,
|
const wxRect& rect,
|
||||||
int flags) = 0;
|
int flags) = 0;
|
||||||
|
|
||||||
@@ -120,18 +123,24 @@ public:
|
|||||||
const wxRect& rect,
|
const wxRect& rect,
|
||||||
int flags = 0) = 0;
|
int flags = 0) = 0;
|
||||||
|
|
||||||
// draw a scrollbar: thumb positions are in percent of the full scrollbar
|
// draw the scrollbar thumb
|
||||||
// length and the flags array contains the flags corresponding to each of
|
virtual void DrawScrollbarThumb(wxDC& dc,
|
||||||
// wxScrollBar::Elements
|
|
||||||
virtual void DrawScrollbar(wxDC& dc,
|
|
||||||
wxOrientation orient,
|
|
||||||
int thumbPosStart,
|
|
||||||
int thumbPosEnd,
|
|
||||||
const wxRect& rect,
|
const wxRect& rect,
|
||||||
const int *flags = NULL) = 0;
|
int flags = 0) = 0;
|
||||||
|
|
||||||
// TODO: having this is ugly but I don't see how to solve GetBestSize()
|
// draw a (part of) scrollbar shaft
|
||||||
// problem without something like this
|
virtual void DrawScrollbarShaft(wxDC& dc,
|
||||||
|
const wxRect& rect,
|
||||||
|
int flags = 0) = 0;
|
||||||
|
|
||||||
|
// draw an item of a wxControlWithItems
|
||||||
|
virtual void DrawItem(wxDC& dc,
|
||||||
|
const wxString& label,
|
||||||
|
const wxRect& rect,
|
||||||
|
int flags = 0) = 0;
|
||||||
|
|
||||||
|
// geometry functions
|
||||||
|
// ------------------
|
||||||
|
|
||||||
// adjust the size of the control of the given class: for most controls,
|
// adjust the size of the control of the given class: for most controls,
|
||||||
// this just takes into account the border, but for some (buttons, for
|
// this just takes into account the border, but for some (buttons, for
|
||||||
@@ -142,13 +151,20 @@ public:
|
|||||||
// hit testing functions
|
// hit testing functions
|
||||||
// ---------------------
|
// ---------------------
|
||||||
|
|
||||||
|
// gets the bounding box for a scrollbar element for the given (by default
|
||||||
|
// - current) thumb position
|
||||||
|
virtual wxRect GetScrollbarRect(const wxScrollBar *scrollbar,
|
||||||
|
wxScrollBar::Element elem,
|
||||||
|
int thumbPos = -1) const = 0;
|
||||||
|
|
||||||
// returns one of wxHT_SCROLLBAR_XXX constants
|
// returns one of wxHT_SCROLLBAR_XXX constants
|
||||||
virtual wxHitTest HitTestScrollbar(const wxScrollBar *scrollbar,
|
virtual wxHitTest HitTestScrollbar(const wxScrollBar *scrollbar,
|
||||||
const wxPoint& pt) const = 0;
|
const wxPoint& pt) const = 0;
|
||||||
|
|
||||||
// translate the scrollbar position (in logical units) into physical
|
// translate the scrollbar position (in logical units) into physical
|
||||||
// coordinate (in pixels) and the other way round
|
// coordinate (in pixels) and the other way round
|
||||||
virtual wxCoord ScrollbarToPixel(const wxScrollBar *scrollbar) = 0;
|
virtual wxCoord ScrollbarToPixel(const wxScrollBar *scrollbar,
|
||||||
|
int thumbPos = -1) = 0;
|
||||||
virtual int PixelToScrollbar(const wxScrollBar *scrollbar,
|
virtual int PixelToScrollbar(const wxScrollBar *scrollbar,
|
||||||
wxCoord coord) = 0;
|
wxCoord coord) = 0;
|
||||||
|
|
||||||
@@ -165,10 +181,15 @@ protected:
|
|||||||
// standard scrollbar hit testing: this assumes that it only has 2 arrows
|
// standard scrollbar hit testing: this assumes that it only has 2 arrows
|
||||||
// and a thumb, so the themes which have more complicated scrollbars (e.g.
|
// and a thumb, so the themes which have more complicated scrollbars (e.g.
|
||||||
// BeOS) can't use this method
|
// BeOS) can't use this method
|
||||||
|
static wxRect StandardGetScrollbarRect(const wxScrollBar *scrollbar,
|
||||||
|
wxScrollBar::Element elem,
|
||||||
|
int thumbPos,
|
||||||
|
const wxSize& sizeArrow);
|
||||||
static wxHitTest StandardHitTestScrollbar(const wxScrollBar *scrollbar,
|
static wxHitTest StandardHitTestScrollbar(const wxScrollBar *scrollbar,
|
||||||
const wxPoint& pt,
|
const wxPoint& pt,
|
||||||
const wxSize& sizeArrow);
|
const wxSize& sizeArrow);
|
||||||
static wxCoord StandardScrollbarToPixel(const wxScrollBar *scrollbar,
|
static wxCoord StandardScrollbarToPixel(const wxScrollBar *scrollbar,
|
||||||
|
int thumbPos,
|
||||||
const wxSize& sizeArrow);
|
const wxSize& sizeArrow);
|
||||||
static int StandardPixelToScrollbar(const wxScrollBar *scrollbar,
|
static int StandardPixelToScrollbar(const wxScrollBar *scrollbar,
|
||||||
wxCoord coord,
|
wxCoord coord,
|
||||||
@@ -190,9 +211,10 @@ public:
|
|||||||
wxDelegateRenderer(wxRenderer *renderer) : m_renderer(renderer) { }
|
wxDelegateRenderer(wxRenderer *renderer) : m_renderer(renderer) { }
|
||||||
|
|
||||||
virtual void DrawBackground(wxDC& dc,
|
virtual void DrawBackground(wxDC& dc,
|
||||||
|
const wxColour& col,
|
||||||
const wxRect& rect,
|
const wxRect& rect,
|
||||||
int flags)
|
int flags)
|
||||||
{ m_renderer->DrawBackground(dc, rect, flags); }
|
{ m_renderer->DrawBackground(dc, col, rect, flags); }
|
||||||
virtual void DrawLabel(wxDC& dc,
|
virtual void DrawLabel(wxDC& dc,
|
||||||
const wxString& label,
|
const wxString& label,
|
||||||
const wxBitmap& image,
|
const wxBitmap& image,
|
||||||
@@ -232,23 +254,33 @@ public:
|
|||||||
const wxRect& rect,
|
const wxRect& rect,
|
||||||
int flags = 0)
|
int flags = 0)
|
||||||
{ m_renderer->DrawArrow(dc, dir, rect, flags); }
|
{ m_renderer->DrawArrow(dc, dir, rect, flags); }
|
||||||
virtual void DrawScrollbar(wxDC& dc,
|
virtual void DrawScrollbarThumb(wxDC& dc,
|
||||||
wxOrientation orient,
|
|
||||||
int thumbPosStart,
|
|
||||||
int thumbPosEnd,
|
|
||||||
const wxRect& rect,
|
const wxRect& rect,
|
||||||
const int *flags = NULL)
|
int flags = 0)
|
||||||
{ m_renderer->DrawScrollbar(dc, orient, thumbPosStart,
|
{ m_renderer->DrawScrollbarThumb(dc, rect, flags); }
|
||||||
thumbPosEnd, rect, flags); }
|
virtual void DrawScrollbarShaft(wxDC& dc,
|
||||||
|
const wxRect& rect,
|
||||||
|
int flags = 0)
|
||||||
|
{ m_renderer->DrawScrollbarShaft(dc, rect, flags); }
|
||||||
|
virtual void DrawItem(wxDC& dc,
|
||||||
|
const wxString& label,
|
||||||
|
const wxRect& rect,
|
||||||
|
int flags = 0)
|
||||||
|
{ m_renderer->DrawItem(dc, label, rect, flags); }
|
||||||
|
|
||||||
virtual void AdjustSize(wxSize *size, const wxWindow *window)
|
virtual void AdjustSize(wxSize *size, const wxWindow *window)
|
||||||
{ m_renderer->AdjustSize(size, window); }
|
{ m_renderer->AdjustSize(size, window); }
|
||||||
|
|
||||||
|
virtual wxRect GetScrollbarRect(const wxScrollBar *scrollbar,
|
||||||
|
wxScrollBar::Element elem,
|
||||||
|
int thumbPos = -1) const
|
||||||
|
{ return m_renderer->GetScrollbarRect(scrollbar, elem, thumbPos); }
|
||||||
virtual wxHitTest HitTestScrollbar(const wxScrollBar *scrollbar,
|
virtual wxHitTest HitTestScrollbar(const wxScrollBar *scrollbar,
|
||||||
const wxPoint& pt) const
|
const wxPoint& pt) const
|
||||||
{ return m_renderer->HitTestScrollbar(scrollbar, pt); }
|
{ return m_renderer->HitTestScrollbar(scrollbar, pt); }
|
||||||
virtual wxCoord ScrollbarToPixel(const wxScrollBar *scrollbar)
|
virtual wxCoord ScrollbarToPixel(const wxScrollBar *scrollbar,
|
||||||
{ return m_renderer->ScrollbarToPixel(scrollbar); }
|
int thumbPos = -1)
|
||||||
|
{ return m_renderer->ScrollbarToPixel(scrollbar, thumbPos); }
|
||||||
virtual int PixelToScrollbar(const wxScrollBar *scrollbar,
|
virtual int PixelToScrollbar(const wxScrollBar *scrollbar,
|
||||||
wxCoord coord)
|
wxCoord coord)
|
||||||
{ return m_renderer->PixelToScrollbar(scrollbar, coord); }
|
{ return m_renderer->PixelToScrollbar(scrollbar, coord); }
|
||||||
@@ -271,6 +303,8 @@ public:
|
|||||||
// operations
|
// operations
|
||||||
void DrawLabel(const wxBitmap& bitmap = wxNullBitmap,
|
void DrawLabel(const wxBitmap& bitmap = wxNullBitmap,
|
||||||
wxCoord marginX = 0, wxCoord marginY = 0);
|
wxCoord marginX = 0, wxCoord marginY = 0);
|
||||||
|
void DrawItems(const wxListBox *listbox,
|
||||||
|
size_t itemFirst, size_t itemLast);
|
||||||
void DrawBorder();
|
void DrawBorder();
|
||||||
void DrawButtonBorder();
|
void DrawButtonBorder();
|
||||||
// the line must be either horizontal or vertical
|
// the line must be either horizontal or vertical
|
||||||
@@ -282,7 +316,7 @@ public:
|
|||||||
int alignment = wxALIGN_CENTRE | wxALIGN_CENTRE_VERTICAL,
|
int alignment = wxALIGN_CENTRE | wxALIGN_CENTRE_VERTICAL,
|
||||||
wxStretch stretch = wxSTRETCH_NOT);
|
wxStretch stretch = wxSTRETCH_NOT);
|
||||||
void DrawBackgroundBitmap();
|
void DrawBackgroundBitmap();
|
||||||
void DrawScrollbar(const wxScrollBar *scrollbar);
|
void DrawScrollbar(const wxScrollBar *scrollbar, int thumbPosOld);
|
||||||
|
|
||||||
// accessors
|
// accessors
|
||||||
wxWindow *GetWindow() const { return m_window; }
|
wxWindow *GetWindow() const { return m_window; }
|
||||||
|
@@ -16,8 +16,6 @@
|
|||||||
#pragma interface "univscrolbar.h"
|
#pragma interface "univscrolbar.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "wx/univ/renderer.h" // for wxHitTest
|
|
||||||
|
|
||||||
class WXDLLEXPORT wxInputHandler;
|
class WXDLLEXPORT wxInputHandler;
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -100,16 +98,20 @@ public:
|
|||||||
void ScrollPages(int nPages);
|
void ScrollPages(int nPages);
|
||||||
|
|
||||||
virtual bool PerformAction(const wxControlAction& action,
|
virtual bool PerformAction(const wxControlAction& action,
|
||||||
const wxEvent& event);
|
long numArg = 0,
|
||||||
|
const wxString& strArg = wxEmptyString);
|
||||||
|
|
||||||
// wxScrollBar sub elements state (combination of wxCONTROL_XXX)
|
// wxScrollBar sub elements state (combination of wxCONTROL_XXX)
|
||||||
void SetState(Element which, int flags) { m_elementsState[which] = flags; }
|
void SetState(Element which, int flags);
|
||||||
int GetState(Element which) const { return m_elementsState[which]; }
|
int GetState(Element which) const { return m_elementsState[which]; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual wxSize DoGetBestSize() const;
|
virtual wxSize DoGetBestClientSize() const;
|
||||||
virtual void DoDraw(wxControlRenderer *renderer);
|
virtual void DoDraw(wxControlRenderer *renderer);
|
||||||
|
|
||||||
|
// event handler
|
||||||
|
void OnIdle(wxIdleEvent& event);
|
||||||
|
|
||||||
// SetThumbPosition() helper
|
// SetThumbPosition() helper
|
||||||
void DoSetThumb(int thumbPos);
|
void DoSetThumb(int thumbPos);
|
||||||
|
|
||||||
@@ -117,17 +119,15 @@ protected:
|
|||||||
void Init();
|
void Init();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// get the mouse coordinates in the scrollbar direction from a
|
|
||||||
// wxMouseEvent (the event *must* really be of this type!)
|
|
||||||
wxCoord GetMouseCoord(const wxEvent& event) const;
|
|
||||||
|
|
||||||
// total range of the scrollbar in logical units
|
// total range of the scrollbar in logical units
|
||||||
int m_range;
|
int m_range;
|
||||||
|
|
||||||
// the size of the thumb in logical units (from 0 to m_range) and its
|
// the current and previous (after last refresh - this is used for
|
||||||
// position (from 0 to m_range - m_thumbSize)
|
// repainting optimisation) size of the thumb in logical units (from 0 to
|
||||||
|
// m_range) and its position (from 0 to m_range - m_thumbSize)
|
||||||
int m_thumbSize,
|
int m_thumbSize,
|
||||||
m_thumbPos;
|
m_thumbPos,
|
||||||
|
m_thumbPosOld;
|
||||||
|
|
||||||
// the page size, i.e. the number of lines by which to scroll when page
|
// the page size, i.e. the number of lines by which to scroll when page
|
||||||
// up/down action is performed
|
// up/down action is performed
|
||||||
@@ -136,10 +136,10 @@ private:
|
|||||||
// the state of the sub elements
|
// the state of the sub elements
|
||||||
int m_elementsState[Element_Max];
|
int m_elementsState[Element_Max];
|
||||||
|
|
||||||
// the offset of the top/left of the scrollbar relative to the mouse to
|
// the dirty flag: if set, scrollbar must be updated
|
||||||
// keep during the thumb drag
|
bool m_dirty;
|
||||||
int m_ofsMouse;
|
|
||||||
|
|
||||||
|
DECLARE_EVENT_TABLE()
|
||||||
DECLARE_DYNAMIC_CLASS(wxScrollBar)
|
DECLARE_DYNAMIC_CLASS(wxScrollBar)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -74,7 +74,7 @@
|
|||||||
#define wxUSE_CHOICE 0
|
#define wxUSE_CHOICE 0
|
||||||
#define wxUSE_COMBOBOX 0
|
#define wxUSE_COMBOBOX 0
|
||||||
#define wxUSE_GAUGE 0
|
#define wxUSE_GAUGE 0
|
||||||
#define wxUSE_LISTBOX 0
|
#define wxUSE_LISTBOX 1
|
||||||
#define wxUSE_LISTCTRL 0
|
#define wxUSE_LISTCTRL 0
|
||||||
#define wxUSE_RADIOBOX 0
|
#define wxUSE_RADIOBOX 0
|
||||||
#define wxUSE_RADIOBTN 0
|
#define wxUSE_RADIOBTN 0
|
||||||
|
@@ -64,7 +64,7 @@ public:
|
|||||||
wxIcon GetIcon() const;
|
wxIcon GetIcon() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual wxSize DoGetBestSize() const;
|
virtual wxSize DoGetBestClientSize() const;
|
||||||
virtual void DoDraw(wxControlRenderer *renderer);
|
virtual void DoDraw(wxControlRenderer *renderer);
|
||||||
|
|
||||||
// the bitmap which we show
|
// the bitmap which we show
|
||||||
|
@@ -55,7 +55,7 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
// calculate the optimal size for the label
|
// calculate the optimal size for the label
|
||||||
virtual wxSize DoGetBestSize() const;
|
virtual wxSize DoGetBestClientSize() const;
|
||||||
|
|
||||||
// draw the control
|
// draw the control
|
||||||
virtual void DoDraw(wxControlRenderer *renderer);
|
virtual void DoDraw(wxControlRenderer *renderer);
|
||||||
|
@@ -36,8 +36,14 @@ enum
|
|||||||
wxCONTROL_PRESSED = 0x00000004, // (button) is pressed
|
wxCONTROL_PRESSED = 0x00000004, // (button) is pressed
|
||||||
wxCONTROL_ISDEFAULT = 0x00000008, // only applies to the buttons
|
wxCONTROL_ISDEFAULT = 0x00000008, // only applies to the buttons
|
||||||
wxCONTROL_CURRENT = 0x00000010, // mouse is currently over the control
|
wxCONTROL_CURRENT = 0x00000010, // mouse is currently over the control
|
||||||
|
wxCONTROL_SELECTED = 0x00000020, // selected item in e.g. listbox
|
||||||
|
wxCONTROL_CHECKED = 0x00000040, // (check/radio button) is checked
|
||||||
|
|
||||||
wxCONTROL_FLAGS_MASK = 0x0000001f
|
wxCONTROL_FLAGS_MASK = 0x0000007f,
|
||||||
|
|
||||||
|
// this is a pseudo flag not used directly by wxRenderer but rather by some
|
||||||
|
// controls internally
|
||||||
|
wxCONTROL_DIRTY = 0x80000000
|
||||||
};
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -119,7 +125,7 @@ protected:
|
|||||||
|
|
||||||
// returns the (low level) renderer to use for drawing the control by
|
// returns the (low level) renderer to use for drawing the control by
|
||||||
// querying the current theme
|
// querying the current theme
|
||||||
wxRenderer *GetRenderer() const;
|
wxRenderer *GetRenderer() const { return m_renderer; }
|
||||||
|
|
||||||
// draw the control background, return TRUE if done
|
// draw the control background, return TRUE if done
|
||||||
virtual bool DoDrawBackground(wxControlRenderer *renderer);
|
virtual bool DoDrawBackground(wxControlRenderer *renderer);
|
||||||
@@ -127,6 +133,12 @@ protected:
|
|||||||
// draw the controls contents
|
// draw the controls contents
|
||||||
virtual void DoDraw(wxControlRenderer *renderer);
|
virtual void DoDraw(wxControlRenderer *renderer);
|
||||||
|
|
||||||
|
// calculate the best size for the client area of the window: default
|
||||||
|
// implementation of DoGetBestSize() uses this method and adds the border
|
||||||
|
// width to the result
|
||||||
|
virtual wxSize DoGetBestClientSize() const;
|
||||||
|
virtual wxSize DoGetBestSize() const;
|
||||||
|
|
||||||
// adjust the size of the window to take into account its borders
|
// adjust the size of the window to take into account its borders
|
||||||
wxSize AdjustSize(const wxSize& size) const;
|
wxSize AdjustSize(const wxSize& size) const;
|
||||||
|
|
||||||
@@ -139,6 +151,9 @@ protected:
|
|||||||
// put the scrollbars along the edges of the window
|
// put the scrollbars along the edges of the window
|
||||||
void PositionScrollbars();
|
void PositionScrollbars();
|
||||||
|
|
||||||
|
// the renderer we use
|
||||||
|
wxRenderer *m_renderer;
|
||||||
|
|
||||||
// background bitmap info
|
// background bitmap info
|
||||||
wxBitmap m_bitmapBg;
|
wxBitmap m_bitmapBg;
|
||||||
int m_alignBgBitmap;
|
int m_alignBgBitmap;
|
||||||
|
@@ -36,6 +36,7 @@
|
|||||||
|
|
||||||
#include "wx/bmpbuttn.h"
|
#include "wx/bmpbuttn.h"
|
||||||
#include "wx/button.h"
|
#include "wx/button.h"
|
||||||
|
#include "wx/listbox.h"
|
||||||
#include "wx/scrolbar.h"
|
#include "wx/scrolbar.h"
|
||||||
#include "wx/scrolwin.h"
|
#include "wx/scrolwin.h"
|
||||||
#include "wx/statbox.h"
|
#include "wx/statbox.h"
|
||||||
@@ -47,6 +48,8 @@
|
|||||||
|
|
||||||
#include "wx/univ/theme.h"
|
#include "wx/univ/theme.h"
|
||||||
|
|
||||||
|
//#define DEBUG_SCROLL
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// resources
|
// resources
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -184,7 +187,10 @@ bool MyUnivApp::OnInit()
|
|||||||
wxFrame *frame = new MyUnivFrame(_T("wxUniversal demo"));
|
wxFrame *frame = new MyUnivFrame(_T("wxUniversal demo"));
|
||||||
frame->Show();
|
frame->Show();
|
||||||
|
|
||||||
|
#ifdef DEBUG_SCROLL
|
||||||
wxLog::AddTraceMask(_T("scroll"));
|
wxLog::AddTraceMask(_T("scroll"));
|
||||||
|
#endif
|
||||||
|
wxLog::AddTraceMask(_T("listbox"));
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@@ -194,7 +200,7 @@ bool MyUnivApp::OnInit()
|
|||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
MyUnivFrame::MyUnivFrame(const wxString& title)
|
MyUnivFrame::MyUnivFrame(const wxString& title)
|
||||||
: wxFrame(NULL, -1, title, wxDefaultPosition, wxSize(600, 600))
|
: wxFrame(NULL, -1, title, wxDefaultPosition, wxSize(700, 600))
|
||||||
{
|
{
|
||||||
SetBackgroundColour(wxGetApp().GetBgColour());
|
SetBackgroundColour(wxGetApp().GetBgColour());
|
||||||
|
|
||||||
@@ -295,6 +301,17 @@ MyUnivFrame::MyUnivFrame(const wxString& title)
|
|||||||
);
|
);
|
||||||
bmpBtn->SetBitmapSelected(bmp2);
|
bmpBtn->SetBitmapSelected(bmp2);
|
||||||
bmpBtn->SetBitmapFocus(bmp3);
|
bmpBtn->SetBitmapFocus(bmp3);
|
||||||
|
|
||||||
|
static const wxString choices[] =
|
||||||
|
{
|
||||||
|
_T("This"),
|
||||||
|
_T("is one of my"),
|
||||||
|
_T("really"),
|
||||||
|
_T("wonderful"),
|
||||||
|
_T("examples."),
|
||||||
|
};
|
||||||
|
new wxListBox(this, -1, wxPoint(550, 10), wxDefaultSize,
|
||||||
|
WXSIZEOF(choices), choices);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyUnivFrame::OnButton(wxCommandEvent& event)
|
void MyUnivFrame::OnButton(wxCommandEvent& event)
|
||||||
@@ -331,10 +348,14 @@ void MyUnivCanvas::OnPaint(wxPaintEvent& event)
|
|||||||
s_oddRepaint = !s_oddRepaint;
|
s_oddRepaint = !s_oddRepaint;
|
||||||
wxCoord x, y;
|
wxCoord x, y;
|
||||||
GetViewStart(&x, &y);
|
GetViewStart(&x, &y);
|
||||||
|
#ifdef DEBUG_SCROLL
|
||||||
wxLogDebug("Repainting with %s pen (at %dx%d)",
|
wxLogDebug("Repainting with %s pen (at %dx%d)",
|
||||||
s_oddRepaint ? "red" : "green",
|
s_oddRepaint ? "red" : "green",
|
||||||
x, y);
|
x, y);
|
||||||
|
#endif // DEBUG_SCROLL
|
||||||
dc.SetPen(s_oddRepaint ? *wxRED_PEN: *wxGREEN_PEN);
|
dc.SetPen(s_oddRepaint ? *wxRED_PEN: *wxGREEN_PEN);
|
||||||
|
dc.SetTextForeground(s_oddRepaint ? *wxRED : *wxGREEN);
|
||||||
|
|
||||||
dc.DrawLine(0, 0, 1000, 1000);
|
dc.DrawLine(0, 0, 1000, 1000);
|
||||||
dc.DrawText(_T("This is the top of the canvas"), 10, 10);
|
dc.DrawText(_T("This is the top of the canvas"), 10, 10);
|
||||||
dc.DrawLabel(_T("This is the bottom of the canvas"),
|
dc.DrawLabel(_T("This is the bottom of the canvas"),
|
||||||
|
@@ -696,7 +696,8 @@ bool wxEvtHandler::ProcessEvent(wxEvent& event)
|
|||||||
{
|
{
|
||||||
#if wxUSE_GUI
|
#if wxUSE_GUI
|
||||||
// check that our flag corresponds to reality
|
// check that our flag corresponds to reality
|
||||||
wxASSERT( m_isWindow == IsKindOf(CLASSINFO(wxWindow)) );
|
wxASSERT_MSG( m_isWindow == IsKindOf(CLASSINFO(wxWindowBase)),
|
||||||
|
_T("this should [not] be a window but it is [not]") );
|
||||||
#endif // wxUSE_GUI
|
#endif // wxUSE_GUI
|
||||||
|
|
||||||
// An event handler can be enabled or disabled
|
// An event handler can be enabled or disabled
|
||||||
|
@@ -2,10 +2,11 @@
|
|||||||
// Name: generic/scrolwin.cpp
|
// Name: generic/scrolwin.cpp
|
||||||
// Purpose: wxScrolledWindow implementation
|
// Purpose: wxScrolledWindow implementation
|
||||||
// Author: Julian Smart
|
// Author: Julian Smart
|
||||||
// Modified by:
|
// Modified by: Vadim Zeitlin on 31.08.00: wxScrollHelper allows to implement
|
||||||
|
// scrolling in any class, not just wxScrolledWindow
|
||||||
// Created: 01/02/97
|
// Created: 01/02/97
|
||||||
// RCS-ID: $Id$
|
// RCS-ID: $Id$
|
||||||
// Copyright: (c) Julian Smart and Markus Holzem
|
// Copyright: (c) wxWindows team
|
||||||
// Licence: wxWindows license
|
// Licence: wxWindows license
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@@ -51,90 +52,119 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// event tables
|
// wxScrollHelperEvtHandler: intercept the events from the window and forward
|
||||||
|
// them to wxScrollHelper
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
BEGIN_EVENT_TABLE(wxScrolledWindow, wxPanel)
|
class wxScrollHelperEvtHandler : public wxEvtHandler
|
||||||
EVT_SCROLLWIN(wxScrolledWindow::OnScroll)
|
{
|
||||||
EVT_SIZE(wxScrolledWindow::OnSize)
|
public:
|
||||||
EVT_PAINT(wxScrolledWindow::OnPaint)
|
wxScrollHelperEvtHandler(wxScrollHelper *scrollHelper)
|
||||||
EVT_CHAR(wxScrolledWindow::OnChar)
|
{
|
||||||
END_EVENT_TABLE()
|
m_scrollHelper = scrollHelper;
|
||||||
|
}
|
||||||
|
|
||||||
IMPLEMENT_DYNAMIC_CLASS(wxScrolledWindow, wxPanel)
|
virtual bool ProcessEvent(wxEvent& event)
|
||||||
|
{
|
||||||
|
if ( wxEvtHandler::ProcessEvent(event) )
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
switch ( event.GetEventType() )
|
||||||
|
{
|
||||||
|
case wxEVT_SCROLLWIN_TOP:
|
||||||
|
case wxEVT_SCROLLWIN_BOTTOM:
|
||||||
|
case wxEVT_SCROLLWIN_LINEUP:
|
||||||
|
case wxEVT_SCROLLWIN_LINEDOWN:
|
||||||
|
case wxEVT_SCROLLWIN_PAGEUP:
|
||||||
|
case wxEVT_SCROLLWIN_PAGEDOWN:
|
||||||
|
case wxEVT_SCROLLWIN_THUMBTRACK:
|
||||||
|
case wxEVT_SCROLLWIN_THUMBRELEASE:
|
||||||
|
m_scrollHelper->HandleOnScroll((wxScrollWinEvent&)event);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case wxEVT_PAINT:
|
||||||
|
m_scrollHelper->HandleOnPaint((wxPaintEvent&)event);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case wxEVT_SIZE:
|
||||||
|
m_scrollHelper->HandleOnSize((wxSizeEvent&)event);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case wxEVT_CHAR:
|
||||||
|
m_scrollHelper->HandleOnChar((wxKeyEvent&)event);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
wxScrollHelper *m_scrollHelper;
|
||||||
|
};
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// implementation
|
// implementation
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// wxScrolledWindow creation
|
// wxScrollHelper construction
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
wxScrolledWindow::wxScrolledWindow()
|
wxScrollHelper::wxScrollHelper(wxWindow *win)
|
||||||
{
|
{
|
||||||
m_xScrollPixelsPerLine = 0;
|
m_xScrollPixelsPerLine =
|
||||||
m_yScrollPixelsPerLine = 0;
|
m_yScrollPixelsPerLine =
|
||||||
m_xScrollingEnabled = TRUE;
|
m_xScrollPosition =
|
||||||
m_yScrollingEnabled = TRUE;
|
m_yScrollPosition =
|
||||||
m_xScrollPosition = 0;
|
m_xScrollLines =
|
||||||
m_yScrollPosition = 0;
|
m_yScrollLines =
|
||||||
m_xScrollLines = 0;
|
m_xScrollLinesPerPage =
|
||||||
m_yScrollLines = 0;
|
|
||||||
m_xScrollLinesPerPage = 0;
|
|
||||||
m_yScrollLinesPerPage = 0;
|
m_yScrollLinesPerPage = 0;
|
||||||
m_scaleX = 1.0;
|
|
||||||
m_scaleY = 1.0;
|
|
||||||
m_targetWindow = (wxWindow*) NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool wxScrolledWindow::Create(wxWindow *parent,
|
m_xScrollingEnabled =
|
||||||
wxWindowID id,
|
|
||||||
const wxPoint& pos,
|
|
||||||
const wxSize& size,
|
|
||||||
long style,
|
|
||||||
const wxString& name)
|
|
||||||
{
|
|
||||||
m_xScrollPixelsPerLine = 0;
|
|
||||||
m_yScrollPixelsPerLine = 0;
|
|
||||||
m_xScrollingEnabled = TRUE;
|
|
||||||
m_yScrollingEnabled = TRUE;
|
m_yScrollingEnabled = TRUE;
|
||||||
m_xScrollPosition = 0;
|
|
||||||
m_yScrollPosition = 0;
|
m_scaleX =
|
||||||
m_xScrollLines = 0;
|
|
||||||
m_yScrollLines = 0;
|
|
||||||
m_xScrollLinesPerPage = 0;
|
|
||||||
m_yScrollLinesPerPage = 0;
|
|
||||||
m_scaleX = 1.0;
|
|
||||||
m_scaleY = 1.0;
|
m_scaleY = 1.0;
|
||||||
|
|
||||||
m_targetWindow = this;
|
m_win =
|
||||||
|
m_targetWindow = (wxWindow *)NULL;
|
||||||
|
|
||||||
bool ok = wxPanel::Create(parent, id, pos, size, style, name);
|
if ( win )
|
||||||
|
SetWindow(win);
|
||||||
#ifdef __WXMSW__
|
|
||||||
// we need to process arrows ourselves for scrolling
|
|
||||||
m_lDlgCode |= DLGC_WANTARROWS;
|
|
||||||
#endif // __WXMSW__
|
|
||||||
|
|
||||||
return ok;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wxScrolledWindow::~wxScrolledWindow()
|
void wxScrollHelper::SetWindow(wxWindow *win)
|
||||||
{
|
{
|
||||||
|
wxCHECK_RET( win, _T("wxScrollHelper needs a window to scroll") );
|
||||||
|
|
||||||
|
m_targetWindow = m_win = win;
|
||||||
|
|
||||||
|
// install the event handler which will intercept the events we're
|
||||||
|
// interested in
|
||||||
|
m_win->PushEventHandler(new wxScrollHelperEvtHandler(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
wxScrollHelper::~wxScrollHelper()
|
||||||
|
{
|
||||||
|
if ( m_targetWindow )
|
||||||
|
m_targetWindow->PopEventHandler(TRUE /* do delete it */);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// setting scrolling parameters
|
// setting scrolling parameters
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
/*
|
void wxScrollHelper::SetScrollbars(int pixelsPerUnitX,
|
||||||
* pixelsPerUnitX/pixelsPerUnitY: number of pixels per unit (e.g. pixels per text line)
|
int pixelsPerUnitY,
|
||||||
* noUnitsX/noUnitsY: : no. units per scrollbar
|
int noUnitsX,
|
||||||
*/
|
int noUnitsY,
|
||||||
void wxScrolledWindow::SetScrollbars (int pixelsPerUnitX, int pixelsPerUnitY,
|
int xPos,
|
||||||
int noUnitsX, int noUnitsY,
|
int yPos,
|
||||||
int xPos, int yPos, bool noRefresh )
|
bool noRefresh)
|
||||||
{
|
{
|
||||||
int xpos, ypos;
|
int xpos, ypos;
|
||||||
|
|
||||||
@@ -148,8 +178,6 @@ void wxScrolledWindow::SetScrollbars (int pixelsPerUnitX, int pixelsPerUnitY,
|
|||||||
(noUnitsY < m_yScrollLines && ypos > pixelsPerUnitY*noUnitsY) ||
|
(noUnitsY < m_yScrollLines && ypos > pixelsPerUnitY*noUnitsY) ||
|
||||||
(xPos != m_xScrollPosition) ||
|
(xPos != m_xScrollPosition) ||
|
||||||
(yPos != m_yScrollPosition)
|
(yPos != m_yScrollPosition)
|
||||||
// (pixelsPerUnitX != m_xScrollPixelsPerLine) ||
|
|
||||||
// (pixelsPerUnitY != m_yScrollPixelsPerLine)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
m_xScrollPixelsPerLine = pixelsPerUnitX;
|
m_xScrollPixelsPerLine = pixelsPerUnitX;
|
||||||
@@ -165,21 +193,21 @@ void wxScrolledWindow::SetScrollbars (int pixelsPerUnitX, int pixelsPerUnitY,
|
|||||||
// be entirely generic because it relies on the wxWindowDC implementation
|
// be entirely generic because it relies on the wxWindowDC implementation
|
||||||
// to duplicate X drawing calls for the backing pixmap.
|
// to duplicate X drawing calls for the backing pixmap.
|
||||||
|
|
||||||
if ((m_windowStyle & wxRETAINED) == wxRETAINED)
|
if ( m_targetWindow->GetWindowStyle() & wxRETAINED )
|
||||||
{
|
{
|
||||||
Display* dpy = XtDisplay((Widget) GetMainWidget());
|
Display* dpy = XtDisplay((Widget)m_targetWindow->GetMainWidget());
|
||||||
|
|
||||||
int totalPixelWidth = m_xScrollLines * m_xScrollPixelsPerLine;
|
int totalPixelWidth = m_xScrollLines * m_xScrollPixelsPerLine;
|
||||||
int totalPixelHeight = m_yScrollLines * m_yScrollPixelsPerLine;
|
int totalPixelHeight = m_yScrollLines * m_yScrollPixelsPerLine;
|
||||||
if (m_backingPixmap &&
|
if (m_targetWindow->m_backingPixmap &&
|
||||||
!((m_pixmapWidth == totalPixelWidth) &&
|
!((m_targetWindow->m_pixmapWidth == totalPixelWidth) &&
|
||||||
(m_pixmapHeight == totalPixelHeight)))
|
(m_targetWindow->m_pixmapHeight == totalPixelHeight)))
|
||||||
{
|
{
|
||||||
XFreePixmap (dpy, (Pixmap) m_backingPixmap);
|
XFreePixmap (dpy, (Pixmap) m_targetWindow->m_backingPixmap);
|
||||||
m_backingPixmap = (WXPixmap) 0;
|
m_targetWindow->m_backingPixmap = (WXPixmap) 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_backingPixmap &&
|
if (!m_targetWindow->m_backingPixmap &&
|
||||||
(noUnitsX != 0) && (noUnitsY != 0))
|
(noUnitsX != 0) && (noUnitsY != 0))
|
||||||
{
|
{
|
||||||
int depth = wxDisplayDepth();
|
int depth = wxDisplayDepth();
|
||||||
@@ -197,16 +225,6 @@ void wxScrolledWindow::SetScrollbars (int pixelsPerUnitX, int pixelsPerUnitY,
|
|||||||
if (do_refresh && !noRefresh)
|
if (do_refresh && !noRefresh)
|
||||||
m_targetWindow->Refresh();
|
m_targetWindow->Refresh();
|
||||||
|
|
||||||
#ifdef __WXMSW__
|
|
||||||
// GRG: if this turns out to be really necessary, we could
|
|
||||||
// at least move it to the above if { ... } so that it is
|
|
||||||
// only done if noRefresh = FALSE (the default). OTOH, if
|
|
||||||
// this doesn't break anything, which seems to be the
|
|
||||||
// case, we could just leave it out.
|
|
||||||
|
|
||||||
// Necessary?
|
|
||||||
// UpdateWindow ((HWND) m_targetWindow->GetHWND());
|
|
||||||
#endif
|
|
||||||
#ifdef __WXMAC__
|
#ifdef __WXMAC__
|
||||||
m_targetWindow->MacUpdateImmediately() ;
|
m_targetWindow->MacUpdateImmediately() ;
|
||||||
#endif
|
#endif
|
||||||
@@ -216,13 +234,13 @@ void wxScrolledWindow::SetScrollbars (int pixelsPerUnitX, int pixelsPerUnitY,
|
|||||||
// target window handling
|
// target window handling
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
void wxScrolledWindow::SetTargetWindow( wxWindow *target )
|
void wxScrollHelper::SetTargetWindow( wxWindow *target )
|
||||||
{
|
{
|
||||||
wxASSERT_MSG( target, wxT("target window must not be NULL") );
|
wxASSERT_MSG( target, wxT("target window must not be NULL") );
|
||||||
m_targetWindow = target;
|
m_targetWindow = target;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxWindow *wxScrolledWindow::GetTargetWindow()
|
wxWindow *wxScrollHelper::GetTargetWindow() const
|
||||||
{
|
{
|
||||||
return m_targetWindow;
|
return m_targetWindow;
|
||||||
}
|
}
|
||||||
@@ -231,7 +249,7 @@ wxWindow *wxScrolledWindow::GetTargetWindow()
|
|||||||
// scrolling implementation itself
|
// scrolling implementation itself
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
void wxScrolledWindow::OnScroll(wxScrollWinEvent& event)
|
void wxScrollHelper::HandleOnScroll(wxScrollWinEvent& event)
|
||||||
{
|
{
|
||||||
int orient = event.GetOrientation();
|
int orient = event.GetOrientation();
|
||||||
|
|
||||||
@@ -241,12 +259,12 @@ void wxScrolledWindow::OnScroll(wxScrollWinEvent& event)
|
|||||||
if (orient == wxHORIZONTAL)
|
if (orient == wxHORIZONTAL)
|
||||||
{
|
{
|
||||||
int newPos = m_xScrollPosition + nScrollInc;
|
int newPos = m_xScrollPosition + nScrollInc;
|
||||||
SetScrollPos(wxHORIZONTAL, newPos, FALSE );
|
m_win->SetScrollPos(wxHORIZONTAL, newPos, FALSE );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int newPos = m_yScrollPosition + nScrollInc;
|
int newPos = m_yScrollPosition + nScrollInc;
|
||||||
SetScrollPos(wxVERTICAL, newPos, FALSE );
|
m_win->SetScrollPos(wxVERTICAL, newPos, FALSE );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (orient == wxHORIZONTAL)
|
if (orient == wxHORIZONTAL)
|
||||||
@@ -277,7 +295,7 @@ void wxScrolledWindow::OnScroll(wxScrollWinEvent& event)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int wxScrolledWindow::CalcScrollInc(wxScrollWinEvent& event)
|
int wxScrollHelper::CalcScrollInc(wxScrollWinEvent& event)
|
||||||
{
|
{
|
||||||
int pos = event.GetPosition();
|
int pos = event.GetPosition();
|
||||||
int orient = event.GetOrientation();
|
int orient = event.GetOrientation();
|
||||||
@@ -387,7 +405,7 @@ int wxScrolledWindow::CalcScrollInc(wxScrollWinEvent& event)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Adjust the scrollbars - new version.
|
// Adjust the scrollbars - new version.
|
||||||
void wxScrolledWindow::AdjustScrollbars()
|
void wxScrollHelper::AdjustScrollbars()
|
||||||
{
|
{
|
||||||
int w, h;
|
int w, h;
|
||||||
m_targetWindow->GetClientSize(&w, &h);
|
m_targetWindow->GetClientSize(&w, &h);
|
||||||
@@ -407,14 +425,14 @@ void wxScrolledWindow::AdjustScrollbars()
|
|||||||
m_xScrollPosition = wxMin( m_xScrollLines-noPagePositions, m_xScrollPosition);
|
m_xScrollPosition = wxMin( m_xScrollLines-noPagePositions, m_xScrollPosition);
|
||||||
m_xScrollPosition = wxMax( 0, m_xScrollPosition );
|
m_xScrollPosition = wxMax( 0, m_xScrollPosition );
|
||||||
|
|
||||||
SetScrollbar(wxHORIZONTAL, m_xScrollPosition, noPagePositions, m_xScrollLines);
|
m_win->SetScrollbar(wxHORIZONTAL, m_xScrollPosition, noPagePositions, m_xScrollLines);
|
||||||
// The amount by which we scroll when paging
|
// The amount by which we scroll when paging
|
||||||
SetScrollPageSize(wxHORIZONTAL, noPagePositions);
|
SetScrollPageSize(wxHORIZONTAL, noPagePositions);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_xScrollPosition = 0;
|
m_xScrollPosition = 0;
|
||||||
SetScrollbar (wxHORIZONTAL, 0, 0, 0, FALSE);
|
m_win->SetScrollbar (wxHORIZONTAL, 0, 0, 0, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_yScrollLines > 0)
|
if (m_yScrollLines > 0)
|
||||||
@@ -429,14 +447,14 @@ void wxScrolledWindow::AdjustScrollbars()
|
|||||||
m_yScrollPosition = wxMin( m_yScrollLines-noPagePositions, m_yScrollPosition );
|
m_yScrollPosition = wxMin( m_yScrollLines-noPagePositions, m_yScrollPosition );
|
||||||
m_yScrollPosition = wxMax( 0, m_yScrollPosition );
|
m_yScrollPosition = wxMax( 0, m_yScrollPosition );
|
||||||
|
|
||||||
SetScrollbar(wxVERTICAL, m_yScrollPosition, noPagePositions, m_yScrollLines);
|
m_win->SetScrollbar(wxVERTICAL, m_yScrollPosition, noPagePositions, m_yScrollLines);
|
||||||
// The amount by which we scroll when paging
|
// The amount by which we scroll when paging
|
||||||
SetScrollPageSize(wxVERTICAL, noPagePositions);
|
SetScrollPageSize(wxVERTICAL, noPagePositions);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_yScrollPosition = 0;
|
m_yScrollPosition = 0;
|
||||||
SetScrollbar (wxVERTICAL, 0, 0, 0, FALSE);
|
m_win->SetScrollbar (wxVERTICAL, 0, 0, 0, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oldXScroll != m_xScrollPosition)
|
if (oldXScroll != m_xScrollPosition)
|
||||||
@@ -456,9 +474,7 @@ void wxScrolledWindow::AdjustScrollbars()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Override this function if you don't want to have wxScrolledWindow
|
void wxScrollHelper::DoPrepareDC(wxDC& dc)
|
||||||
// automatically change the origin according to the scroll position.
|
|
||||||
void wxScrolledWindow::PrepareDC(wxDC& dc)
|
|
||||||
{
|
{
|
||||||
dc.SetDeviceOrigin( -m_xScrollPosition * m_xScrollPixelsPerLine,
|
dc.SetDeviceOrigin( -m_xScrollPosition * m_xScrollPixelsPerLine,
|
||||||
-m_yScrollPosition * m_yScrollPixelsPerLine );
|
-m_yScrollPosition * m_yScrollPixelsPerLine );
|
||||||
@@ -467,30 +483,14 @@ void wxScrolledWindow::PrepareDC(wxDC& dc)
|
|||||||
// for wxUniversal we need to set the clipping region to avoid overwriting
|
// for wxUniversal we need to set the clipping region to avoid overwriting
|
||||||
// the scrollbars with the user drawing
|
// the scrollbars with the user drawing
|
||||||
#ifdef __WXUNIVERSAL__
|
#ifdef __WXUNIVERSAL__
|
||||||
wxSize size = GetClientSize();
|
wxSize size = m_win->GetClientSize();
|
||||||
dc.SetClippingRegion(m_xScrollPosition * m_xScrollPixelsPerLine,
|
dc.SetClippingRegion(m_xScrollPosition * m_xScrollPixelsPerLine,
|
||||||
m_yScrollPosition * m_yScrollPixelsPerLine,
|
m_yScrollPosition * m_yScrollPixelsPerLine,
|
||||||
size.x, size.y);
|
size.x, size.y);
|
||||||
#endif // __WXUNIVERSAL__
|
#endif // __WXUNIVERSAL__
|
||||||
}
|
}
|
||||||
|
|
||||||
#if WXWIN_COMPATIBILITY
|
void wxScrollHelper::GetScrollPixelsPerUnit (int *x_unit, int *y_unit) const
|
||||||
void wxScrolledWindow::GetScrollUnitsPerPage (int *x_page, int *y_page) const
|
|
||||||
{
|
|
||||||
*x_page = GetScrollPageSize(wxHORIZONTAL);
|
|
||||||
*y_page = GetScrollPageSize(wxVERTICAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void wxScrolledWindow::CalcUnscrolledPosition(int x, int y, float *xx, float *yy) const
|
|
||||||
{
|
|
||||||
if ( xx )
|
|
||||||
*xx = (float)(x + m_xScrollPosition * m_xScrollPixelsPerLine);
|
|
||||||
if ( yy )
|
|
||||||
*yy = (float)(y + m_yScrollPosition * m_yScrollPixelsPerLine);
|
|
||||||
}
|
|
||||||
#endif // WXWIN_COMPATIBILITY
|
|
||||||
|
|
||||||
void wxScrolledWindow::GetScrollPixelsPerUnit (int *x_unit, int *y_unit) const
|
|
||||||
{
|
{
|
||||||
if ( x_unit )
|
if ( x_unit )
|
||||||
*x_unit = m_xScrollPixelsPerLine;
|
*x_unit = m_xScrollPixelsPerLine;
|
||||||
@@ -498,7 +498,7 @@ void wxScrolledWindow::GetScrollPixelsPerUnit (int *x_unit, int *y_unit) const
|
|||||||
*y_unit = m_yScrollPixelsPerLine;
|
*y_unit = m_yScrollPixelsPerLine;
|
||||||
}
|
}
|
||||||
|
|
||||||
int wxScrolledWindow::GetScrollPageSize(int orient) const
|
int wxScrollHelper::GetScrollPageSize(int orient) const
|
||||||
{
|
{
|
||||||
if ( orient == wxHORIZONTAL )
|
if ( orient == wxHORIZONTAL )
|
||||||
return m_xScrollLinesPerPage;
|
return m_xScrollLinesPerPage;
|
||||||
@@ -506,7 +506,7 @@ int wxScrolledWindow::GetScrollPageSize(int orient) const
|
|||||||
return m_yScrollLinesPerPage;
|
return m_yScrollLinesPerPage;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxScrolledWindow::SetScrollPageSize(int orient, int pageSize)
|
void wxScrollHelper::SetScrollPageSize(int orient, int pageSize)
|
||||||
{
|
{
|
||||||
if ( orient == wxHORIZONTAL )
|
if ( orient == wxHORIZONTAL )
|
||||||
m_xScrollLinesPerPage = pageSize;
|
m_xScrollLinesPerPage = pageSize;
|
||||||
@@ -517,7 +517,7 @@ void wxScrolledWindow::SetScrollPageSize(int orient, int pageSize)
|
|||||||
/*
|
/*
|
||||||
* Scroll to given position (scroll position, not pixel position)
|
* Scroll to given position (scroll position, not pixel position)
|
||||||
*/
|
*/
|
||||||
void wxScrolledWindow::Scroll( int x_pos, int y_pos )
|
void wxScrollHelper::Scroll( int x_pos, int y_pos )
|
||||||
{
|
{
|
||||||
if (!m_targetWindow)
|
if (!m_targetWindow)
|
||||||
return;
|
return;
|
||||||
@@ -574,13 +574,13 @@ void wxScrolledWindow::Scroll( int x_pos, int y_pos )
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxScrolledWindow::EnableScrolling (bool x_scroll, bool y_scroll)
|
void wxScrollHelper::EnableScrolling (bool x_scroll, bool y_scroll)
|
||||||
{
|
{
|
||||||
m_xScrollingEnabled = x_scroll;
|
m_xScrollingEnabled = x_scroll;
|
||||||
m_yScrollingEnabled = y_scroll;
|
m_yScrollingEnabled = y_scroll;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxScrolledWindow::GetVirtualSize (int *x, int *y) const
|
void wxScrollHelper::GetVirtualSize (int *x, int *y) const
|
||||||
{
|
{
|
||||||
if ( x )
|
if ( x )
|
||||||
*x = m_xScrollPixelsPerLine * m_xScrollLines;
|
*x = m_xScrollPixelsPerLine * m_xScrollLines;
|
||||||
@@ -589,7 +589,7 @@ void wxScrolledWindow::GetVirtualSize (int *x, int *y) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Where the current view starts from
|
// Where the current view starts from
|
||||||
void wxScrolledWindow::GetViewStart (int *x, int *y) const
|
void wxScrollHelper::GetViewStart (int *x, int *y) const
|
||||||
{
|
{
|
||||||
if ( x )
|
if ( x )
|
||||||
*x = m_xScrollPosition;
|
*x = m_xScrollPosition;
|
||||||
@@ -597,7 +597,7 @@ void wxScrolledWindow::GetViewStart (int *x, int *y) const
|
|||||||
*y = m_yScrollPosition;
|
*y = m_yScrollPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxScrolledWindow::CalcScrolledPosition(int x, int y, int *xx, int *yy) const
|
void wxScrollHelper::CalcScrolledPosition(int x, int y, int *xx, int *yy) const
|
||||||
{
|
{
|
||||||
if ( xx )
|
if ( xx )
|
||||||
*xx = x - m_xScrollPosition * m_xScrollPixelsPerLine;
|
*xx = x - m_xScrollPosition * m_xScrollPixelsPerLine;
|
||||||
@@ -605,7 +605,7 @@ void wxScrolledWindow::CalcScrolledPosition(int x, int y, int *xx, int *yy) cons
|
|||||||
*yy = y - m_yScrollPosition * m_yScrollPixelsPerLine;
|
*yy = y - m_yScrollPosition * m_yScrollPixelsPerLine;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxScrolledWindow::CalcUnscrolledPosition(int x, int y, int *xx, int *yy) const
|
void wxScrollHelper::CalcUnscrolledPosition(int x, int y, int *xx, int *yy) const
|
||||||
{
|
{
|
||||||
if ( xx )
|
if ( xx )
|
||||||
*xx = x + m_xScrollPosition * m_xScrollPixelsPerLine;
|
*xx = x + m_xScrollPosition * m_xScrollPixelsPerLine;
|
||||||
@@ -618,11 +618,11 @@ void wxScrolledWindow::CalcUnscrolledPosition(int x, int y, int *xx, int *yy) co
|
|||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
// Default OnSize resets scrollbars, if any
|
// Default OnSize resets scrollbars, if any
|
||||||
void wxScrolledWindow::OnSize(wxSizeEvent& WXUNUSED(event))
|
void wxScrollHelper::HandleOnSize(wxSizeEvent& WXUNUSED(event))
|
||||||
{
|
{
|
||||||
#if wxUSE_CONSTRAINTS
|
#if wxUSE_CONSTRAINTS
|
||||||
if (GetAutoLayout())
|
if ( m_targetWindow->GetAutoLayout() )
|
||||||
Layout();
|
m_targetWindow->Layout();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
AdjustScrollbars();
|
AdjustScrollbars();
|
||||||
@@ -630,10 +630,10 @@ void wxScrolledWindow::OnSize(wxSizeEvent& WXUNUSED(event))
|
|||||||
|
|
||||||
// This calls OnDraw, having adjusted the origin according to the current
|
// This calls OnDraw, having adjusted the origin according to the current
|
||||||
// scroll position
|
// scroll position
|
||||||
void wxScrolledWindow::OnPaint(wxPaintEvent& WXUNUSED(event))
|
void wxScrollHelper::HandleOnPaint(wxPaintEvent& WXUNUSED(event))
|
||||||
{
|
{
|
||||||
wxPaintDC dc(this);
|
wxPaintDC dc(m_targetWindow);
|
||||||
PrepareDC(dc);
|
DoPrepareDC(dc);
|
||||||
|
|
||||||
OnDraw(dc);
|
OnDraw(dc);
|
||||||
}
|
}
|
||||||
@@ -642,14 +642,14 @@ void wxScrolledWindow::OnPaint(wxPaintEvent& WXUNUSED(event))
|
|||||||
// compatibility here - if we used OnKeyDown(), the programs which process
|
// compatibility here - if we used OnKeyDown(), the programs which process
|
||||||
// arrows themselves in their OnChar() would never get the message and like
|
// arrows themselves in their OnChar() would never get the message and like
|
||||||
// this they always have the priority
|
// this they always have the priority
|
||||||
void wxScrolledWindow::OnChar(wxKeyEvent& event)
|
void wxScrollHelper::HandleOnChar(wxKeyEvent& event)
|
||||||
{
|
{
|
||||||
int stx, sty, // view origin
|
int stx, sty, // view origin
|
||||||
szx, szy, // view size (total)
|
szx, szy, // view size (total)
|
||||||
clix, cliy; // view size (on screen)
|
clix, cliy; // view size (on screen)
|
||||||
|
|
||||||
ViewStart(&stx, &sty);
|
GetViewStart(&stx, &sty);
|
||||||
GetClientSize(&clix, &cliy);
|
m_win->GetClientSize(&clix, &cliy);
|
||||||
GetVirtualSize(&szx, &szy);
|
GetVirtualSize(&szx, &szy);
|
||||||
|
|
||||||
if( m_xScrollPixelsPerLine )
|
if( m_xScrollPixelsPerLine )
|
||||||
@@ -716,3 +716,49 @@ void wxScrolledWindow::OnChar(wxKeyEvent& event)
|
|||||||
event.Skip();
|
event.Skip();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// wxScrolledWindow implementation
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
IMPLEMENT_DYNAMIC_CLASS(wxScrolledWindow, wxPanel)
|
||||||
|
|
||||||
|
bool wxScrolledWindow::Create(wxWindow *parent,
|
||||||
|
wxWindowID id,
|
||||||
|
const wxPoint& pos,
|
||||||
|
const wxSize& size,
|
||||||
|
long style,
|
||||||
|
const wxString& name)
|
||||||
|
{
|
||||||
|
m_targetWindow = this;
|
||||||
|
|
||||||
|
bool ok = wxPanel::Create(parent, id, pos, size, style, name);
|
||||||
|
|
||||||
|
#ifdef __WXMSW__
|
||||||
|
// we need to process arrows ourselves for scrolling
|
||||||
|
m_lDlgCode |= DLGC_WANTARROWS;
|
||||||
|
#endif // __WXMSW__
|
||||||
|
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxScrolledWindow::~wxScrolledWindow()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#if WXWIN_COMPATIBILITY
|
||||||
|
void wxScrolledWindow::GetScrollUnitsPerPage (int *x_page, int *y_page) const
|
||||||
|
{
|
||||||
|
*x_page = GetScrollPageSize(wxHORIZONTAL);
|
||||||
|
*y_page = GetScrollPageSize(wxVERTICAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxScrolledWindow::CalcUnscrolledPosition(int x, int y, float *xx, float *yy) const
|
||||||
|
{
|
||||||
|
if ( xx )
|
||||||
|
*xx = (float)(x + m_xScrollPosition * m_xScrollPixelsPerLine);
|
||||||
|
if ( yy )
|
||||||
|
*yy = (float)(y + m_yScrollPosition * m_yScrollPixelsPerLine);
|
||||||
|
}
|
||||||
|
#endif // WXWIN_COMPATIBILITY
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,7 @@
|
|||||||
// Created: 14.08.00
|
// Created: 14.08.00
|
||||||
// RCS-ID: $Id$
|
// RCS-ID: $Id$
|
||||||
// Copyright: (c) 2000 Vadim Zeitlin
|
// Copyright: (c) 2000 Vadim Zeitlin
|
||||||
// Licence: wxWindows license
|
// Licence: wxWindows licence
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@@ -97,7 +97,7 @@ wxButton::~wxButton()
|
|||||||
// size management
|
// size management
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
wxSize wxButton::DoGetBestSize() const
|
wxSize wxButton::DoGetBestClientSize() const
|
||||||
{
|
{
|
||||||
wxClientDC dc(wxConstCast(this, wxButton));
|
wxClientDC dc(wxConstCast(this, wxButton));
|
||||||
wxCoord width, height;
|
wxCoord width, height;
|
||||||
@@ -113,7 +113,7 @@ wxSize wxButton::DoGetBestSize() const
|
|||||||
width += m_bitmap.GetWidth() + 2*m_marginBmpX;
|
width += m_bitmap.GetWidth() + 2*m_marginBmpX;
|
||||||
}
|
}
|
||||||
|
|
||||||
return AdjustSize(wxSize(width, height));
|
return wxSize(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -132,12 +132,22 @@ void wxButton::DoDraw(wxControlRenderer *renderer)
|
|||||||
|
|
||||||
void wxButton::Press()
|
void wxButton::Press()
|
||||||
{
|
{
|
||||||
|
if ( !m_isPressed )
|
||||||
|
{
|
||||||
m_isPressed = TRUE;
|
m_isPressed = TRUE;
|
||||||
|
|
||||||
|
Refresh();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxButton::Release()
|
void wxButton::Release()
|
||||||
{
|
{
|
||||||
|
if ( m_isPressed )
|
||||||
|
{
|
||||||
m_isPressed = FALSE;
|
m_isPressed = FALSE;
|
||||||
|
|
||||||
|
Refresh();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxButton::Toggle()
|
void wxButton::Toggle()
|
||||||
@@ -162,10 +172,9 @@ void wxButton::Click()
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool wxButton::PerformAction(const wxControlAction& action,
|
bool wxButton::PerformAction(const wxControlAction& action,
|
||||||
const wxEvent& event)
|
long numArg,
|
||||||
|
const wxString& strArg)
|
||||||
{
|
{
|
||||||
bool wasPressed = IsPressed();
|
|
||||||
|
|
||||||
if ( action == wxACTION_BUTTON_TOGGLE )
|
if ( action == wxACTION_BUTTON_TOGGLE )
|
||||||
Toggle();
|
Toggle();
|
||||||
else if ( action == wxACTION_BUTTON_CLICK )
|
else if ( action == wxACTION_BUTTON_CLICK )
|
||||||
@@ -175,9 +184,9 @@ bool wxButton::PerformAction(const wxControlAction& action,
|
|||||||
else if ( action == wxACTION_BUTTON_RELEASE )
|
else if ( action == wxACTION_BUTTON_RELEASE )
|
||||||
Release();
|
Release();
|
||||||
else
|
else
|
||||||
return wxControl::PerformAction(action, event);
|
return wxControl::PerformAction(action, numArg, strArg);
|
||||||
|
|
||||||
return wasPressed != IsPressed();
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -202,5 +211,121 @@ void wxButton::SetDefault()
|
|||||||
m_isDefault = TRUE;
|
m_isDefault = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// wxStdButtonInputHandler
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
wxStdButtonInputHandler::wxStdButtonInputHandler(wxInputHandler *handler)
|
||||||
|
: wxStdInputHandler(handler)
|
||||||
|
{
|
||||||
|
m_winCapture = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxStdButtonInputHandler::HandleKey(wxControl *control,
|
||||||
|
const wxKeyEvent& event,
|
||||||
|
bool pressed)
|
||||||
|
{
|
||||||
|
int keycode = event.GetKeyCode();
|
||||||
|
if ( keycode == WXK_SPACE || keycode == WXK_RETURN )
|
||||||
|
{
|
||||||
|
control->PerformAction(wxACTION_BUTTON_TOGGLE);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return wxStdInputHandler::HandleKey(control, event, pressed);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxStdButtonInputHandler::HandleMouse(wxControl *control,
|
||||||
|
const wxMouseEvent& event)
|
||||||
|
{
|
||||||
|
// the button has 2 states: pressed and normal with the following
|
||||||
|
// transitions between them:
|
||||||
|
//
|
||||||
|
// normal -> left down -> capture mouse and go to pressed state
|
||||||
|
// pressed -> left up inside -> generate click -> go to normal
|
||||||
|
// outside ------------------>
|
||||||
|
//
|
||||||
|
// the other mouse buttons are ignored
|
||||||
|
if ( event.Button(1) )
|
||||||
|
{
|
||||||
|
if ( event.ButtonDown(1) )
|
||||||
|
{
|
||||||
|
m_winCapture = control;
|
||||||
|
m_winCapture->CaptureMouse();
|
||||||
|
m_winHasMouse = TRUE;
|
||||||
|
|
||||||
|
control->PerformAction(wxACTION_BUTTON_PRESS);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else // up
|
||||||
|
{
|
||||||
|
if ( m_winCapture )
|
||||||
|
{
|
||||||
|
m_winCapture->ReleaseMouse();
|
||||||
|
m_winCapture = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( m_winHasMouse )
|
||||||
|
{
|
||||||
|
// this will generate a click event
|
||||||
|
control->PerformAction(wxACTION_BUTTON_TOGGLE);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
//else: the mouse was released outside the window, this doesn't
|
||||||
|
// count as a click
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return wxStdInputHandler::HandleMouse(control, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxStdButtonInputHandler::HandleMouseMove(wxControl *control,
|
||||||
|
const wxMouseEvent& event)
|
||||||
|
{
|
||||||
|
// we only have to do something when the mouse leaves/enters the pressed
|
||||||
|
// button and don't care about the other ones
|
||||||
|
if ( event.GetEventObject() == m_winCapture )
|
||||||
|
{
|
||||||
|
// leaving the button should remove its pressed state
|
||||||
|
if ( event.Leaving() )
|
||||||
|
{
|
||||||
|
// remember that the mouse is now outside
|
||||||
|
m_winHasMouse = FALSE;
|
||||||
|
|
||||||
|
// we do have a pressed button, so release it
|
||||||
|
control->PerformAction(wxACTION_BUTTON_RELEASE);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
// and entering it back should make it pressed again if it had been
|
||||||
|
// pressed
|
||||||
|
else if ( event.Entering() )
|
||||||
|
{
|
||||||
|
// the mouse is (back) inside the button
|
||||||
|
m_winHasMouse = TRUE;
|
||||||
|
|
||||||
|
// we did have a pressed button which we released when leaving the
|
||||||
|
// window, press it again
|
||||||
|
control->PerformAction(wxACTION_BUTTON_PRESS);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return wxStdInputHandler::HandleMouseMove(control, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxStdButtonInputHandler::HandleFocus(wxControl *control,
|
||||||
|
const wxFocusEvent& event)
|
||||||
|
{
|
||||||
|
// buttons change appearance when they get/lose focus
|
||||||
|
control->Refresh();
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // wxUSE_BUTTON
|
#endif // wxUSE_BUTTON
|
||||||
|
|
||||||
|
@@ -62,6 +62,8 @@ END_EVENT_TABLE()
|
|||||||
void wxControl::Init()
|
void wxControl::Init()
|
||||||
{
|
{
|
||||||
m_indexAccel = -1;
|
m_indexAccel = -1;
|
||||||
|
|
||||||
|
m_handler = (wxInputHandler *)NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxControl::Create(wxWindow *parent,
|
bool wxControl::Create(wxWindow *parent,
|
||||||
@@ -75,10 +77,11 @@ bool wxControl::Create(wxWindow *parent,
|
|||||||
if ( !wxControlBase::Create(parent, id, pos, size, style, validator, name) )
|
if ( !wxControlBase::Create(parent, id, pos, size, style, validator, name) )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
SetBackgroundColour(parent->GetBackgroundColour());
|
m_renderer = wxTheme::Get()->GetRenderer();
|
||||||
|
|
||||||
m_handler = CreateInputHandler();
|
m_handler = CreateInputHandler();
|
||||||
|
|
||||||
|
SetBackgroundColour(parent->GetBackgroundColour());
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,8 +138,8 @@ wxString wxControl::GetLabel() const
|
|||||||
|
|
||||||
void wxControl::OnFocus(wxFocusEvent& event)
|
void wxControl::OnFocus(wxFocusEvent& event)
|
||||||
{
|
{
|
||||||
if ( m_handler->OnFocus(this, event) )
|
if ( !m_handler || !m_handler->HandleFocus(this, event) )
|
||||||
Refresh();
|
event.Skip();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -150,56 +153,53 @@ wxInputHandler *wxControl::CreateInputHandler() const
|
|||||||
|
|
||||||
void wxControl::OnKeyDown(wxKeyEvent& event)
|
void wxControl::OnKeyDown(wxKeyEvent& event)
|
||||||
{
|
{
|
||||||
PerformActions(m_handler->Map(this, event, TRUE), event);
|
if ( !m_handler || !m_handler->HandleKey(this, event, TRUE) )
|
||||||
|
event.Skip();
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxControl::OnKeyUp(wxKeyEvent& event)
|
void wxControl::OnKeyUp(wxKeyEvent& event)
|
||||||
{
|
{
|
||||||
PerformActions(m_handler->Map(this, event, FALSE), event);
|
if ( !m_handler || !m_handler->HandleKey(this, event, FALSE) )
|
||||||
|
event.Skip();
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxControl::OnMouse(wxMouseEvent& event)
|
void wxControl::OnMouse(wxMouseEvent& event)
|
||||||
{
|
{
|
||||||
|
if ( m_handler )
|
||||||
|
{
|
||||||
if ( event.Moving() || event.Entering() || event.Leaving() )
|
if ( event.Moving() || event.Entering() || event.Leaving() )
|
||||||
{
|
{
|
||||||
// don't process it at all for static controls which are not supposed
|
if ( m_handler->HandleMouseMove(this, event) )
|
||||||
// to react to the mouse in any way at all
|
return;
|
||||||
if ( AcceptsFocus() && m_handler->OnMouseMove(this, event) )
|
|
||||||
Refresh();
|
|
||||||
}
|
}
|
||||||
else // a click action
|
else // a click action
|
||||||
{
|
{
|
||||||
PerformActions(m_handler->Map(this, event), event);
|
if ( m_handler->HandleMouse(this, event) )
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
event.Skip();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// the actions
|
// the actions
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
void wxControl::PerformActions(const wxControlActions& actions,
|
|
||||||
const wxEvent& event)
|
|
||||||
{
|
|
||||||
bool needsRefresh = FALSE;
|
|
||||||
size_t count = actions.GetCount();
|
|
||||||
for ( size_t n = 0; n < count; n++ )
|
|
||||||
{
|
|
||||||
const wxControlAction& action = actions[n];
|
|
||||||
if ( !action )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if ( PerformAction(action, event) )
|
|
||||||
needsRefresh = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( needsRefresh )
|
|
||||||
Refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool wxControl::PerformAction(const wxControlAction& action,
|
bool wxControl::PerformAction(const wxControlAction& action,
|
||||||
const wxEvent& event)
|
long numArg,
|
||||||
|
const wxString& strArg)
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// border
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
wxBorder wxControl::GetDefaultBorder() const
|
||||||
|
{
|
||||||
|
return AcceptsFocus() ? wxBORDER_SUNKEN : wxBORDER_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // wxUSE_CONTROLS
|
#endif // wxUSE_CONTROLS
|
||||||
|
@@ -29,77 +29,25 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef WX_PRECOMP
|
#ifndef WX_PRECOMP
|
||||||
#include "wx/timer.h"
|
|
||||||
|
|
||||||
#include "wx/button.h"
|
|
||||||
#include "wx/scrolbar.h"
|
|
||||||
#include "wx/univ/renderer.h"
|
|
||||||
#endif // WX_PRECOMP
|
#endif // WX_PRECOMP
|
||||||
|
|
||||||
#include "wx/univ/inphand.h"
|
#include "wx/univ/inphand.h"
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// wxScrollBarTimer: this class is used to repeatedly scroll the scrollbar
|
|
||||||
// when the mouse is help pressed on the arrow or on the bar. It generates the
|
|
||||||
// given scroll action command periodically.
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
class wxScrollBarTimer : public wxTimer
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
wxScrollBarTimer(wxStdScrollBarInputHandler *handler,
|
|
||||||
const wxControlAction& action,
|
|
||||||
const wxMouseEvent& event,
|
|
||||||
wxScrollBar *control);
|
|
||||||
|
|
||||||
virtual void Notify();
|
|
||||||
|
|
||||||
private:
|
|
||||||
wxStdScrollBarInputHandler *m_handler;
|
|
||||||
wxControlAction m_action;
|
|
||||||
wxMouseEvent m_event;
|
|
||||||
wxScrollBar *m_control;
|
|
||||||
};
|
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// implementation
|
// implementation
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// wxScrollBarTimer
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
wxScrollBarTimer::wxScrollBarTimer(wxStdScrollBarInputHandler *handler,
|
|
||||||
const wxControlAction& action,
|
|
||||||
const wxMouseEvent& event,
|
|
||||||
wxScrollBar *control)
|
|
||||||
: m_event(event)
|
|
||||||
{
|
|
||||||
m_handler = handler;
|
|
||||||
m_action = action;
|
|
||||||
m_control = control;
|
|
||||||
}
|
|
||||||
|
|
||||||
void wxScrollBarTimer::Notify()
|
|
||||||
{
|
|
||||||
if ( m_handler->OnScrollTimer(m_control, m_action, m_event) )
|
|
||||||
{
|
|
||||||
// keep scrolling
|
|
||||||
m_control->Refresh();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// wxInputHandler
|
// wxInputHandler
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
bool wxInputHandler::OnMouseMove(wxControl * WXUNUSED(control),
|
bool wxInputHandler::HandleMouseMove(wxControl * WXUNUSED(control),
|
||||||
const wxMouseEvent& WXUNUSED(event))
|
const wxMouseEvent& WXUNUSED(event))
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxInputHandler::OnFocus(wxControl *control, const wxFocusEvent& event)
|
bool wxInputHandler::HandleFocus(wxControl *control, const wxFocusEvent& event)
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -108,396 +56,3 @@ wxInputHandler::~wxInputHandler()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// wxStdButtonInputHandler
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
wxStdButtonInputHandler::wxStdButtonInputHandler(wxInputHandler *handler)
|
|
||||||
: wxStdInputHandler(handler)
|
|
||||||
{
|
|
||||||
m_winCapture = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
wxControlActions wxStdButtonInputHandler::Map(wxControl *control,
|
|
||||||
const wxKeyEvent& event,
|
|
||||||
bool pressed)
|
|
||||||
{
|
|
||||||
int keycode = event.GetKeyCode();
|
|
||||||
if ( keycode == WXK_SPACE || keycode == WXK_RETURN )
|
|
||||||
{
|
|
||||||
return wxACTION_BUTTON_TOGGLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return wxStdInputHandler::Map(control, event, pressed);
|
|
||||||
}
|
|
||||||
|
|
||||||
wxControlActions wxStdButtonInputHandler::Map(wxControl *control,
|
|
||||||
const wxMouseEvent& event)
|
|
||||||
{
|
|
||||||
// the button has 2 states: pressed and normal with the following
|
|
||||||
// transitions between them:
|
|
||||||
//
|
|
||||||
// normal -> left down -> capture mouse and go to pressed state
|
|
||||||
// pressed -> left up inside -> generate click -> go to normal
|
|
||||||
// outside ------------------>
|
|
||||||
//
|
|
||||||
// the other mouse buttons are ignored
|
|
||||||
if ( event.Button(1) )
|
|
||||||
{
|
|
||||||
if ( event.ButtonDown(1) )
|
|
||||||
{
|
|
||||||
m_winCapture = control;
|
|
||||||
m_winCapture->CaptureMouse();
|
|
||||||
m_winHasMouse = TRUE;
|
|
||||||
|
|
||||||
return wxACTION_BUTTON_PRESS;
|
|
||||||
}
|
|
||||||
else // up
|
|
||||||
{
|
|
||||||
if ( m_winCapture )
|
|
||||||
{
|
|
||||||
m_winCapture->ReleaseMouse();
|
|
||||||
m_winCapture = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( m_winHasMouse )
|
|
||||||
{
|
|
||||||
// this will generate a click event
|
|
||||||
return wxACTION_BUTTON_TOGGLE;
|
|
||||||
}
|
|
||||||
//else: the mouse was released outside the window, this doesn't
|
|
||||||
// count as a click
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return wxStdInputHandler::Map(control, event);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool wxStdButtonInputHandler::OnMouseMove(wxControl *control,
|
|
||||||
const wxMouseEvent& event)
|
|
||||||
{
|
|
||||||
// we only have to do soemthing when the mouse leaves/enters the pressed
|
|
||||||
// button and don't care about the other ones
|
|
||||||
if ( event.GetEventObject() == m_winCapture )
|
|
||||||
{
|
|
||||||
// leaving the button should remove its pressed state
|
|
||||||
if ( event.Leaving() )
|
|
||||||
{
|
|
||||||
// remember that the mouse is now outside
|
|
||||||
m_winHasMouse = FALSE;
|
|
||||||
|
|
||||||
// we do have a pressed button, so release it
|
|
||||||
if ( control->PerformAction(wxACTION_BUTTON_RELEASE, event) )
|
|
||||||
{
|
|
||||||
// the button state changed, refresh needed
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// and entering it back should make it pressed again if it had been
|
|
||||||
// pressed
|
|
||||||
else if ( event.Entering() )
|
|
||||||
{
|
|
||||||
// the mouse is (back) inside the button
|
|
||||||
m_winHasMouse = TRUE;
|
|
||||||
|
|
||||||
// we did have a pressed button which we released when leaving the
|
|
||||||
// window, press it again
|
|
||||||
if ( control->PerformAction(wxACTION_BUTTON_PRESS, event) )
|
|
||||||
{
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return wxStdInputHandler::OnMouseMove(control, event);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool wxStdButtonInputHandler::OnFocus(wxControl *control,
|
|
||||||
const wxFocusEvent& event)
|
|
||||||
{
|
|
||||||
// buttons chaneg appearance when they get/lose focus
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// wxStdScrollBarInputHandler
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
wxStdScrollBarInputHandler::wxStdScrollBarInputHandler(wxRenderer *renderer,
|
|
||||||
wxInputHandler *handler)
|
|
||||||
: wxStdInputHandler(handler)
|
|
||||||
{
|
|
||||||
m_renderer = renderer;
|
|
||||||
m_winCapture = NULL;
|
|
||||||
m_htLast = wxHT_NOWHERE;
|
|
||||||
m_timerScroll = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
wxStdScrollBarInputHandler::~wxStdScrollBarInputHandler()
|
|
||||||
{
|
|
||||||
// normally, it's NULL by now but just in case the user somehow managed to
|
|
||||||
// keep the mouse captured until now...
|
|
||||||
delete m_timerScroll;
|
|
||||||
}
|
|
||||||
|
|
||||||
void wxStdScrollBarInputHandler::SetElementState(wxScrollBar *control,
|
|
||||||
int flag,
|
|
||||||
bool doIt)
|
|
||||||
{
|
|
||||||
if ( m_htLast > wxHT_SCROLLBAR_FIRST && m_htLast < wxHT_SCROLLBAR_LAST )
|
|
||||||
{
|
|
||||||
wxScrollBar::Element
|
|
||||||
elem = (wxScrollBar::Element)(m_htLast - wxHT_SCROLLBAR_FIRST - 1);
|
|
||||||
|
|
||||||
int flags = control->GetState(elem);
|
|
||||||
if ( doIt )
|
|
||||||
flags |= flag;
|
|
||||||
else
|
|
||||||
flags &= ~flag;
|
|
||||||
control->SetState(elem, flags);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool wxStdScrollBarInputHandler::OnScrollTimer(wxScrollBar *scrollbar,
|
|
||||||
const wxControlAction& action,
|
|
||||||
const wxMouseEvent& event)
|
|
||||||
{
|
|
||||||
if ( scrollbar->PerformAction(action, event) )
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
// we scrolled till the end
|
|
||||||
m_timerScroll->Stop();
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void wxStdScrollBarInputHandler::StopScrolling(wxScrollBar *control)
|
|
||||||
{
|
|
||||||
// return everything to the normal state
|
|
||||||
if ( m_winCapture )
|
|
||||||
{
|
|
||||||
m_winCapture->ReleaseMouse();
|
|
||||||
m_winCapture = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_btnCapture = -1;
|
|
||||||
|
|
||||||
if ( m_timerScroll )
|
|
||||||
{
|
|
||||||
delete m_timerScroll;
|
|
||||||
m_timerScroll = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// unpress the arrow and highlight the current element
|
|
||||||
Press(control, FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
wxControlActions wxStdScrollBarInputHandler::Map(wxControl *control,
|
|
||||||
const wxKeyEvent& event,
|
|
||||||
bool pressed)
|
|
||||||
{
|
|
||||||
// we only react to the key presses here
|
|
||||||
if ( pressed )
|
|
||||||
{
|
|
||||||
switch ( event.GetKeyCode() )
|
|
||||||
{
|
|
||||||
case WXK_DOWN:
|
|
||||||
case WXK_RIGHT: return wxACTION_SCROLL_LINE_DOWN;
|
|
||||||
case WXK_UP:
|
|
||||||
case WXK_LEFT: return wxACTION_SCROLL_LINE_UP;
|
|
||||||
case WXK_HOME: return wxACTION_SCROLL_START;
|
|
||||||
case WXK_END: return wxACTION_SCROLL_END;
|
|
||||||
case WXK_PRIOR: return wxACTION_SCROLL_PAGE_UP;
|
|
||||||
case WXK_NEXT: return wxACTION_SCROLL_PAGE_DOWN;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return wxStdInputHandler::Map(control, event, pressed);
|
|
||||||
}
|
|
||||||
|
|
||||||
wxControlActions wxStdScrollBarInputHandler::Map(wxControl *control,
|
|
||||||
const wxMouseEvent& event)
|
|
||||||
{
|
|
||||||
// is this a click event from an acceptable button?
|
|
||||||
int btn = -1;
|
|
||||||
if ( event.IsButton() )
|
|
||||||
{
|
|
||||||
for ( int i = 1; i <= 3; i++ )
|
|
||||||
{
|
|
||||||
if ( event.Button(i) )
|
|
||||||
{
|
|
||||||
btn = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
wxASSERT_MSG( btn != -1, _T("unknown mouse button") );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( (btn != -1) && IsAllowedButton(btn) )
|
|
||||||
{
|
|
||||||
// determine which part of the window mouse is in
|
|
||||||
wxScrollBar *scrollbar = wxStaticCast(control, wxScrollBar);
|
|
||||||
wxHitTest ht = m_renderer->HitTestScrollbar
|
|
||||||
(
|
|
||||||
scrollbar,
|
|
||||||
event.GetPosition()
|
|
||||||
);
|
|
||||||
|
|
||||||
// when the mouse is pressed on any scrollbar element, we capture it
|
|
||||||
// and hold capture until the same mouse button is released
|
|
||||||
if ( event.ButtonDown() || event.ButtonDClick() )
|
|
||||||
{
|
|
||||||
if ( !m_winCapture )
|
|
||||||
{
|
|
||||||
m_btnCapture = btn;
|
|
||||||
m_winCapture = control;
|
|
||||||
m_winCapture->CaptureMouse();
|
|
||||||
|
|
||||||
// generate the command
|
|
||||||
bool hasAction = TRUE;
|
|
||||||
wxControlAction action;
|
|
||||||
switch ( ht )
|
|
||||||
{
|
|
||||||
case wxHT_SCROLLBAR_ARROW_LINE_1:
|
|
||||||
action = wxACTION_SCROLL_LINE_UP;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case wxHT_SCROLLBAR_ARROW_LINE_2:
|
|
||||||
action = wxACTION_SCROLL_LINE_DOWN;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case wxHT_SCROLLBAR_BAR_1:
|
|
||||||
action = wxACTION_SCROLL_PAGE_UP;
|
|
||||||
m_ptStartScrolling = event.GetPosition();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case wxHT_SCROLLBAR_BAR_2:
|
|
||||||
action = wxACTION_SCROLL_PAGE_DOWN;
|
|
||||||
m_ptStartScrolling = event.GetPosition();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case wxHT_SCROLLBAR_THUMB:
|
|
||||||
control->PerformAction(wxACTION_SCROLL_THUMB_DRAG, event);
|
|
||||||
// fall through: there is no immediate action
|
|
||||||
|
|
||||||
default:
|
|
||||||
hasAction = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove highlighting
|
|
||||||
Highlight(scrollbar, FALSE);
|
|
||||||
m_htLast = ht;
|
|
||||||
|
|
||||||
// and press the arrow or highlight thumb now instead
|
|
||||||
if ( m_htLast == wxHT_SCROLLBAR_THUMB )
|
|
||||||
Highlight(scrollbar, TRUE);
|
|
||||||
else
|
|
||||||
Press(scrollbar, TRUE);
|
|
||||||
|
|
||||||
// start dragging
|
|
||||||
if ( hasAction )
|
|
||||||
{
|
|
||||||
m_timerScroll = new wxScrollBarTimer(this,
|
|
||||||
action,
|
|
||||||
event,
|
|
||||||
scrollbar);
|
|
||||||
// start scrolling immediately
|
|
||||||
m_timerScroll->Notify();
|
|
||||||
|
|
||||||
// and continue it later
|
|
||||||
m_timerScroll->Start(50); // FIXME hardcoded delay
|
|
||||||
}
|
|
||||||
else // no (immediate) action
|
|
||||||
{
|
|
||||||
// highlighting still might have changed
|
|
||||||
control->Refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
//else: mouse already captured, nothing to do
|
|
||||||
}
|
|
||||||
// release mouse if the *same* button went up
|
|
||||||
else if ( btn == m_btnCapture )
|
|
||||||
{
|
|
||||||
if ( m_winCapture )
|
|
||||||
{
|
|
||||||
StopScrolling(scrollbar);
|
|
||||||
|
|
||||||
// if we were dragging the thumb, send the last event
|
|
||||||
if ( m_htLast == wxHT_SCROLLBAR_THUMB )
|
|
||||||
{
|
|
||||||
scrollbar->PerformAction(wxACTION_SCROLL_THUMB_RELEASE, event);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_htLast = ht;
|
|
||||||
Highlight(scrollbar, TRUE);
|
|
||||||
|
|
||||||
control->Refresh();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// this is not supposed to happen as the button can't go up
|
|
||||||
// without going down previously and then we'd have
|
|
||||||
// m_winCapture by now
|
|
||||||
wxFAIL_MSG( _T("logic error in mouse capturing code") );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return wxStdInputHandler::Map(control, event);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool wxStdScrollBarInputHandler::OnMouseMove(wxControl *control,
|
|
||||||
const wxMouseEvent& event)
|
|
||||||
{
|
|
||||||
if ( m_winCapture )
|
|
||||||
{
|
|
||||||
if ( (m_htLast == wxHT_SCROLLBAR_THUMB) && event.Moving() )
|
|
||||||
{
|
|
||||||
// drag the thumb so that it follows the mouse
|
|
||||||
if ( control->PerformAction(wxACTION_SCROLL_THUMB_MOVE, event) )
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// no other changes are possible while the mouse is captured
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
wxScrollBar *scrollbar = wxStaticCast(control, wxScrollBar);
|
|
||||||
|
|
||||||
if ( event.Moving() )
|
|
||||||
{
|
|
||||||
wxHitTest ht = m_renderer->HitTestScrollbar
|
|
||||||
(
|
|
||||||
scrollbar,
|
|
||||||
event.GetPosition()
|
|
||||||
);
|
|
||||||
if ( ht == m_htLast )
|
|
||||||
{
|
|
||||||
// nothing changed
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG_MOUSE
|
|
||||||
wxLogDebug("Scrollbar::OnMouseMove: ht = %d", ht);
|
|
||||||
#endif // DEBUG_MOUSE
|
|
||||||
|
|
||||||
Highlight(scrollbar, FALSE);
|
|
||||||
m_htLast = ht;
|
|
||||||
Highlight(scrollbar, TRUE);
|
|
||||||
}
|
|
||||||
else if ( event.Leaving() )
|
|
||||||
{
|
|
||||||
Highlight(scrollbar, FALSE);
|
|
||||||
m_htLast = wxHT_NOWHERE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// don't refresh
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// highlighting changed
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
675
src/univ/listbox.cpp
Normal file
675
src/univ/listbox.cpp
Normal file
@@ -0,0 +1,675 @@
|
|||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Name: univ/listbox.cpp
|
||||||
|
// Purpose: wxListBox implementation
|
||||||
|
// Author: Vadim Zeitlin
|
||||||
|
// Modified by:
|
||||||
|
// Created: 30.08.00
|
||||||
|
// RCS-ID: $Id$
|
||||||
|
// Copyright: (c) 2000 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
|
||||||
|
// Licence: wxWindows licence
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// declarations
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// headers
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifdef __GNUG__
|
||||||
|
#pragma implementation "univlistbox.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "wx/wxprec.h"
|
||||||
|
|
||||||
|
#ifdef __BORLANDC__
|
||||||
|
#pragma hdrstop
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if wxUSE_LISTBOX
|
||||||
|
|
||||||
|
#ifndef WX_PRECOMP
|
||||||
|
#include "wx/dcclient.h"
|
||||||
|
#include "wx/listbox.h"
|
||||||
|
#include "wx/validate.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "wx/univ/renderer.h"
|
||||||
|
#include "wx/univ/inphand.h"
|
||||||
|
#include "wx/univ/theme.h"
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// implementation of wxListBox
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
IMPLEMENT_DYNAMIC_CLASS(wxListBox, wxControl)
|
||||||
|
|
||||||
|
BEGIN_EVENT_TABLE(wxListBox, wxListBoxBase)
|
||||||
|
EVT_SIZE(wxListBox::OnSize)
|
||||||
|
|
||||||
|
EVT_IDLE(wxListBox::OnIdle)
|
||||||
|
END_EVENT_TABLE()
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// construction
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void wxListBox::Init()
|
||||||
|
{
|
||||||
|
// will be calculated later when needed
|
||||||
|
m_lineHeight = 0;
|
||||||
|
m_itemsPerPage = 0;
|
||||||
|
|
||||||
|
// no items hence no current item
|
||||||
|
m_current = -1;
|
||||||
|
|
||||||
|
// no need to update anything initially
|
||||||
|
m_updateCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxListBox::Create(wxWindow *parent,
|
||||||
|
wxWindowID id,
|
||||||
|
const wxPoint &pos,
|
||||||
|
const wxSize &size,
|
||||||
|
int n,
|
||||||
|
const wxString choices[],
|
||||||
|
long style,
|
||||||
|
const wxValidator& validator,
|
||||||
|
const wxString &name)
|
||||||
|
{
|
||||||
|
if ( !wxControl::Create(parent, id, pos, size, style, wxDefaultValidator, name) )
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
SetBackgroundColour(*wxWHITE);
|
||||||
|
|
||||||
|
if ( style & wxLB_SORT )
|
||||||
|
m_strings = wxArrayString(TRUE /* auto sort */);
|
||||||
|
|
||||||
|
Set(n, choices);
|
||||||
|
|
||||||
|
SetBestSize(size);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxListBox::~wxListBox()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// adding/inserting strings
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
int wxListBox::DoAppend(const wxString& item)
|
||||||
|
{
|
||||||
|
size_t index = m_strings.Add(item);
|
||||||
|
m_clientData.Insert(NULL, index);
|
||||||
|
|
||||||
|
RefreshItem(m_strings.GetCount() - 1);
|
||||||
|
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxListBox::DoInsertItems(const wxArrayString& items, int pos)
|
||||||
|
{
|
||||||
|
// the position of the item being added to a sorted listbox can't be
|
||||||
|
// specified
|
||||||
|
wxCHECK_RET( !IsSorted(), _T("can't insert items into sorted listbox") );
|
||||||
|
|
||||||
|
size_t count = items.GetCount();
|
||||||
|
for ( size_t n = 0; n < count; n++ )
|
||||||
|
{
|
||||||
|
m_strings.Insert(items[n], pos + n);
|
||||||
|
m_clientData.Insert(NULL, pos + n);
|
||||||
|
}
|
||||||
|
|
||||||
|
RefreshItems(pos, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxListBox::DoSetItems(const wxArrayString& items, void **clientData)
|
||||||
|
{
|
||||||
|
DoClear();
|
||||||
|
|
||||||
|
size_t count = items.GetCount();
|
||||||
|
m_strings.Alloc(count);
|
||||||
|
m_clientData.Alloc(count);
|
||||||
|
for ( size_t n = 0; n < count; n++ )
|
||||||
|
{
|
||||||
|
size_t index = m_strings.Add(items[n]);
|
||||||
|
|
||||||
|
if ( clientData )
|
||||||
|
m_clientData.Insert(clientData[n], index);
|
||||||
|
}
|
||||||
|
|
||||||
|
RefreshAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// removing strings
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void wxListBox::DoClear()
|
||||||
|
{
|
||||||
|
m_strings.Clear();
|
||||||
|
|
||||||
|
if ( HasClientObjectData() )
|
||||||
|
{
|
||||||
|
size_t count = m_clientData.GetCount();
|
||||||
|
for ( size_t n = 0; n < count; n++ )
|
||||||
|
{
|
||||||
|
delete m_clientData[n];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_clientData.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxListBox::Clear()
|
||||||
|
{
|
||||||
|
DoClear();
|
||||||
|
|
||||||
|
RefreshAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxListBox::Delete(int n)
|
||||||
|
{
|
||||||
|
wxCHECK_RET( n < GetCount(), _T("invalid index in wxListBox::Delete") );
|
||||||
|
|
||||||
|
m_strings.RemoveAt(n);
|
||||||
|
|
||||||
|
if ( HasClientObjectData() )
|
||||||
|
{
|
||||||
|
delete m_clientData[n];
|
||||||
|
}
|
||||||
|
|
||||||
|
m_clientData.RemoveAt(n);
|
||||||
|
|
||||||
|
RefreshItems(n, GetCount() - n);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// client data handling
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void wxListBox::DoSetItemClientData(int n, void* clientData)
|
||||||
|
{
|
||||||
|
m_clientData[n] = clientData;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *wxListBox::DoGetItemClientData(int n) const
|
||||||
|
{
|
||||||
|
return m_clientData[n];
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxListBox::DoSetItemClientObject(int n, wxClientData* clientData)
|
||||||
|
{
|
||||||
|
m_clientData[n] = clientData;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxClientData* wxListBox::DoGetItemClientObject(int n) const
|
||||||
|
{
|
||||||
|
return (wxClientData *)m_clientData[n];
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// selection
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void wxListBox::SetSelection(int n, bool select)
|
||||||
|
{
|
||||||
|
if ( select )
|
||||||
|
{
|
||||||
|
if ( m_selections.Index(n) == wxNOT_FOUND )
|
||||||
|
{
|
||||||
|
m_selections.Add(n);
|
||||||
|
|
||||||
|
RefreshItem(n);
|
||||||
|
}
|
||||||
|
//else: already selected
|
||||||
|
}
|
||||||
|
else // unselect
|
||||||
|
{
|
||||||
|
int index = m_selections.Index(n);
|
||||||
|
if ( index != wxNOT_FOUND )
|
||||||
|
{
|
||||||
|
m_selections.RemoveAt(index);
|
||||||
|
|
||||||
|
RefreshItem(n);
|
||||||
|
}
|
||||||
|
//else: not selected
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int wxListBox::GetSelection() const
|
||||||
|
{
|
||||||
|
wxCHECK_MSG( !HasMultipleSelection(), -1,
|
||||||
|
_T("use wxListBox::GetSelections for ths listbox") );
|
||||||
|
|
||||||
|
return m_selections.IsEmpty() ? -1 : m_selections[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
int wxListBox::GetSelections(wxArrayInt& selections) const
|
||||||
|
{
|
||||||
|
selections = m_selections;
|
||||||
|
|
||||||
|
return m_selections.GetCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// refresh logic: we use delayed refreshing which allows to avoid multiple
|
||||||
|
// refreshes (and hence flicker) in case when several listbox items are
|
||||||
|
// added/deleted/changed subsequently
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void wxListBox::RefreshItems(int from, int count)
|
||||||
|
{
|
||||||
|
switch ( m_updateCount )
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
m_updateFrom = from;
|
||||||
|
m_updateCount = count;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case -1:
|
||||||
|
// we refresh everything anyhow
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// add these items to the others which we have to refresh
|
||||||
|
if ( m_updateFrom < from )
|
||||||
|
{
|
||||||
|
count += from - m_updateFrom;
|
||||||
|
if ( m_updateCount < count )
|
||||||
|
m_updateCount = count;
|
||||||
|
}
|
||||||
|
else // m_updateFrom >= from
|
||||||
|
{
|
||||||
|
m_updateCount = wxMax(m_updateCount,
|
||||||
|
from + count - m_updateFrom);
|
||||||
|
m_updateFrom = from;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxListBox::RefreshItem(int n)
|
||||||
|
{
|
||||||
|
switch ( m_updateCount )
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
// refresh this item only
|
||||||
|
m_updateFrom = n;
|
||||||
|
m_updateCount = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case -1:
|
||||||
|
// we refresh everything anyhow
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// add this item to the others which we have to refresh
|
||||||
|
if ( m_updateFrom < n )
|
||||||
|
{
|
||||||
|
if ( m_updateCount < n - m_updateFrom )
|
||||||
|
m_updateFrom = n - m_updateFrom;
|
||||||
|
}
|
||||||
|
else // n <= m_updateFrom
|
||||||
|
{
|
||||||
|
m_updateCount += m_updateFrom - n;
|
||||||
|
m_updateFrom = n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxListBox::RefreshAll()
|
||||||
|
{
|
||||||
|
m_updateCount = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxListBox::OnIdle(wxIdleEvent& event)
|
||||||
|
{
|
||||||
|
if ( m_updateCount )
|
||||||
|
{
|
||||||
|
// only refresh the items which must be refreshed
|
||||||
|
if ( m_updateCount == -1 )
|
||||||
|
{
|
||||||
|
// refresh all
|
||||||
|
wxLogTrace(_T("listbox"), _T("Refreshing all"));
|
||||||
|
|
||||||
|
Refresh();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wxLogTrace(_T("listbox"), _T("Refreshing items %d..%d"),
|
||||||
|
m_updateFrom, m_updateFrom + m_updateCount);
|
||||||
|
|
||||||
|
wxRect rect;
|
||||||
|
rect.x = 0;
|
||||||
|
rect.y = m_updateFrom*GetLineHeight();
|
||||||
|
rect.width = 32767; // larger than our size
|
||||||
|
rect.height = m_updateCount*GetLineHeight();
|
||||||
|
Refresh(TRUE, &rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_updateCount = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// drawing
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void wxListBox::DoDraw(wxControlRenderer *renderer)
|
||||||
|
{
|
||||||
|
// draw the border first
|
||||||
|
wxControl::DoDraw(renderer);
|
||||||
|
|
||||||
|
// adjust the DC to account for scrolling
|
||||||
|
wxDC& dc = renderer->GetDC();
|
||||||
|
PrepareDC(dc);
|
||||||
|
|
||||||
|
// get the items which must be redrawn
|
||||||
|
#if 0
|
||||||
|
int y;
|
||||||
|
GetViewStart(NULL, &y);
|
||||||
|
#endif
|
||||||
|
wxCoord lineHeight = GetLineHeight();
|
||||||
|
wxRect rectUpdate = GetUpdateRegion().GetBox();
|
||||||
|
size_t itemFirst = rectUpdate.GetTop() / lineHeight,
|
||||||
|
itemLast = (rectUpdate.GetBottom() + lineHeight - 1) / lineHeight,
|
||||||
|
itemMax = m_strings.GetCount();
|
||||||
|
|
||||||
|
if ( itemFirst >= itemMax )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ( itemLast > itemMax )
|
||||||
|
itemLast = itemMax;
|
||||||
|
|
||||||
|
// do draw them
|
||||||
|
wxLogTrace(_T("listbox"), _T("Repainting items %d..%d"),
|
||||||
|
itemFirst, itemLast);
|
||||||
|
renderer->DrawItems(this, itemFirst, itemLast);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// size calculations
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
bool wxListBox::SetFont(const wxFont& font)
|
||||||
|
{
|
||||||
|
if ( !wxControl::SetFont(font) )
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
CalcItemsPerPage();
|
||||||
|
|
||||||
|
RefreshAll();
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxListBox::CalcItemsPerPage()
|
||||||
|
{
|
||||||
|
m_lineHeight = wxClientDC(this).GetCharHeight();
|
||||||
|
m_itemsPerPage = GetClientSize().y / m_lineHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
int wxListBox::GetItemsPerPage() const
|
||||||
|
{
|
||||||
|
if ( !m_itemsPerPage )
|
||||||
|
{
|
||||||
|
wxConstCast(this, wxListBox)->CalcItemsPerPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_itemsPerPage;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxCoord wxListBox::GetLineHeight() const
|
||||||
|
{
|
||||||
|
if ( !m_lineHeight )
|
||||||
|
{
|
||||||
|
wxConstCast(this, wxListBox)->CalcItemsPerPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_lineHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxListBox::OnSize(wxSizeEvent& event)
|
||||||
|
{
|
||||||
|
// recalculate the number of items per page
|
||||||
|
CalcItemsPerPage();
|
||||||
|
|
||||||
|
event.Skip();
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxListBox::DoSetFirstItem(int n)
|
||||||
|
{
|
||||||
|
wxFAIL_MSG( _T("TODO") );
|
||||||
|
}
|
||||||
|
|
||||||
|
wxSize wxListBox::DoGetBestClientSize() const
|
||||||
|
{
|
||||||
|
wxClientDC dc(wxConstCast(this, wxListBox));
|
||||||
|
|
||||||
|
wxCoord width = 0,
|
||||||
|
height = 0;
|
||||||
|
|
||||||
|
size_t count = m_strings.GetCount();
|
||||||
|
for ( size_t n = 0; n < count; n++ )
|
||||||
|
{
|
||||||
|
wxCoord w,h;
|
||||||
|
dc.GetTextExtent(m_strings[n], &w, &h);
|
||||||
|
|
||||||
|
if ( w > width )
|
||||||
|
width = w;
|
||||||
|
if ( h > height )
|
||||||
|
height = h;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the listbox is empty, still give it some non zero (even if
|
||||||
|
// arbitrary) size - otherwise, leave small margin around the strings
|
||||||
|
if ( !width )
|
||||||
|
width = 100;
|
||||||
|
else
|
||||||
|
width += 3*dc.GetCharWidth();
|
||||||
|
|
||||||
|
if ( !height )
|
||||||
|
height = dc.GetCharHeight();
|
||||||
|
|
||||||
|
// we need the height of the entire listbox, not just of one line
|
||||||
|
height *= wxMax(count, 7);
|
||||||
|
|
||||||
|
return wxSize(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// listbox actions
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
bool wxListBox::SendEvent(int item, wxEventType type)
|
||||||
|
{
|
||||||
|
wxCommandEvent event(type, m_windowId);
|
||||||
|
event.SetEventObject(this);
|
||||||
|
|
||||||
|
int n;
|
||||||
|
if ( m_selections.GetCount() > 0 )
|
||||||
|
{
|
||||||
|
n = m_selections[0];
|
||||||
|
if ( HasClientObjectData() )
|
||||||
|
event.SetClientObject(GetClientObject(n));
|
||||||
|
else if ( HasClientUntypedData() )
|
||||||
|
event.SetClientData(GetClientData(n));
|
||||||
|
|
||||||
|
event.SetString(GetString(n));
|
||||||
|
}
|
||||||
|
else // no selection
|
||||||
|
{
|
||||||
|
n = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
event.m_commandInt = n;
|
||||||
|
|
||||||
|
return GetEventHandler()->ProcessEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxListBox::SetCurrentItem(int n)
|
||||||
|
{
|
||||||
|
if ( m_current != -1 )
|
||||||
|
RefreshItem(n);
|
||||||
|
|
||||||
|
m_current = n;
|
||||||
|
|
||||||
|
if ( m_current != -1 )
|
||||||
|
RefreshItem(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxListBox::ChangeCurrent(int diff)
|
||||||
|
{
|
||||||
|
int current = m_current == -1 ? 0 : m_current;
|
||||||
|
|
||||||
|
current += diff;
|
||||||
|
|
||||||
|
int last = GetCount() - 1;
|
||||||
|
if ( current < 0 )
|
||||||
|
current = 0;
|
||||||
|
else if ( current > last )
|
||||||
|
current = last;
|
||||||
|
|
||||||
|
SetCurrentItem(current);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxListBox::Select(bool sel)
|
||||||
|
{
|
||||||
|
if ( sel && !HasMultipleSelection() )
|
||||||
|
{
|
||||||
|
// deselect the old item first
|
||||||
|
int selOld = GetSelection();
|
||||||
|
if ( selOld != -1 )
|
||||||
|
{
|
||||||
|
SetSelection(selOld, FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( m_current != -1 )
|
||||||
|
{
|
||||||
|
// [de]select the new one
|
||||||
|
SetSelection(m_current, sel);
|
||||||
|
|
||||||
|
if ( sel )
|
||||||
|
{
|
||||||
|
SendEvent(m_current, wxEVT_COMMAND_LISTBOX_SELECTED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxListBox::Activate()
|
||||||
|
{
|
||||||
|
if ( m_current != -1 )
|
||||||
|
{
|
||||||
|
Select();
|
||||||
|
|
||||||
|
SendEvent(m_current, wxEVT_COMMAND_LISTBOX_DOUBLECLICKED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxListBox::PerformAction(const wxControlAction& action,
|
||||||
|
long numArg,
|
||||||
|
const wxString& strArg)
|
||||||
|
{
|
||||||
|
if ( action == wxACTION_LISTBOX_SETFOCUS )
|
||||||
|
SetCurrentItem(numArg);
|
||||||
|
else if ( action == wxACTION_LISTBOX_ACTIVATE )
|
||||||
|
Activate();
|
||||||
|
else if ( action == wxACTION_LISTBOX_TOGGLE )
|
||||||
|
Select(!IsSelected(m_current));
|
||||||
|
else if ( action == wxACTION_LISTBOX_SELECT )
|
||||||
|
Select(TRUE);
|
||||||
|
else if ( action == wxACTION_LISTBOX_UNSELECT )
|
||||||
|
Select(FALSE);
|
||||||
|
else if ( action == wxACTION_LISTBOX_MOVEDOWN )
|
||||||
|
ChangeCurrent(1);
|
||||||
|
else if ( action == wxACTION_LISTBOX_MOVEUP )
|
||||||
|
ChangeCurrent(-1);
|
||||||
|
else if ( action == wxACTION_LISTBOX_PAGEDOWN )
|
||||||
|
ChangeCurrent(GetItemsPerPage());
|
||||||
|
else if ( action == wxACTION_LISTBOX_PAGEUP )
|
||||||
|
ChangeCurrent(-GetItemsPerPage());
|
||||||
|
else if ( action == wxACTION_LISTBOX_START )
|
||||||
|
SetCurrentItem(0);
|
||||||
|
else if ( action == wxACTION_LISTBOX_END )
|
||||||
|
SetCurrentItem(GetCount() - 1);
|
||||||
|
else
|
||||||
|
return wxControl::PerformAction(action, numArg, strArg);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// implementation of wxStdListboxInputHandler
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
wxStdListboxInputHandler::wxStdListboxInputHandler(wxInputHandler *handler)
|
||||||
|
: wxStdInputHandler(handler)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxStdListboxInputHandler::HandleKey(wxControl *control,
|
||||||
|
const wxKeyEvent& event,
|
||||||
|
bool pressed)
|
||||||
|
{
|
||||||
|
// we're only interested in the key presses
|
||||||
|
if ( pressed )
|
||||||
|
{
|
||||||
|
wxControlAction action;
|
||||||
|
switch ( event.GetKeyCode() )
|
||||||
|
{
|
||||||
|
// movement
|
||||||
|
case WXK_UP: action = wxACTION_LISTBOX_MOVEUP; break;
|
||||||
|
case WXK_DOWN: action = wxACTION_LISTBOX_MOVEDOWN; break;
|
||||||
|
case WXK_PRIOR: action = wxACTION_LISTBOX_PAGEUP; break;
|
||||||
|
case WXK_NEXT: action = wxACTION_LISTBOX_PAGEDOWN; break;
|
||||||
|
case WXK_HOME: action = wxACTION_LISTBOX_START; break;
|
||||||
|
case WXK_END: action = wxACTION_LISTBOX_END; break;
|
||||||
|
|
||||||
|
// selection
|
||||||
|
case WXK_SPACE: action = wxACTION_LISTBOX_TOGGLE; break;
|
||||||
|
case WXK_RETURN:action = wxACTION_LISTBOX_ACTIVATE; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !!action )
|
||||||
|
{
|
||||||
|
control->PerformAction(action);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return wxStdInputHandler::HandleKey(control, event, pressed);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxStdListboxInputHandler::HandleMouse(wxControl *control,
|
||||||
|
const wxMouseEvent& event)
|
||||||
|
{
|
||||||
|
if ( event.LeftDown() )
|
||||||
|
{
|
||||||
|
wxListBox *lbox = wxStaticCast(control, wxListBox);
|
||||||
|
int item = event.GetPosition().y / lbox->GetLineHeight();
|
||||||
|
if ( item < lbox->GetCount() )
|
||||||
|
{
|
||||||
|
lbox->PerformAction(wxACTION_LISTBOX_SETFOCUS, item);
|
||||||
|
lbox->PerformAction(wxACTION_LISTBOX_TOGGLE);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
//else: click outside the item area, ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
return wxStdInputHandler::HandleMouse(control, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxStdListboxInputHandler::HandleMouseMove(wxControl *control,
|
||||||
|
const wxMouseEvent& event)
|
||||||
|
{
|
||||||
|
return wxStdInputHandler::HandleMouseMove(control, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // wxUSE_LISTBOX
|
@@ -70,6 +70,106 @@ void wxRenderer::StandardDrawFrame(wxDC& dc,
|
|||||||
// wxRenderer: scrollbar geometry
|
// wxRenderer: scrollbar geometry
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/* static */
|
||||||
|
wxRect wxRenderer::StandardGetScrollbarRect(const wxScrollBar *scrollbar,
|
||||||
|
wxScrollBar::Element elem,
|
||||||
|
int thumbPos,
|
||||||
|
const wxSize& sizeArrow)
|
||||||
|
{
|
||||||
|
if ( thumbPos == -1 )
|
||||||
|
{
|
||||||
|
thumbPos = scrollbar->GetThumbPosition();
|
||||||
|
}
|
||||||
|
|
||||||
|
wxSize sizeTotal = scrollbar->GetClientSize();
|
||||||
|
wxCoord *start, *width, length, arrow;
|
||||||
|
wxRect rect;
|
||||||
|
if ( scrollbar->IsVertical() )
|
||||||
|
{
|
||||||
|
rect.x = 0;
|
||||||
|
rect.width = sizeTotal.x;
|
||||||
|
length = sizeTotal.y;
|
||||||
|
start = &rect.y;
|
||||||
|
width = &rect.height;
|
||||||
|
arrow = sizeArrow.y;
|
||||||
|
}
|
||||||
|
else // horizontal
|
||||||
|
{
|
||||||
|
rect.y = 0;
|
||||||
|
rect.height = sizeTotal.y;
|
||||||
|
length = sizeTotal.x;
|
||||||
|
start = &rect.x;
|
||||||
|
width = &rect.width;
|
||||||
|
arrow = sizeArrow.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ( elem )
|
||||||
|
{
|
||||||
|
case wxScrollBar::Element_Arrow_Line_1:
|
||||||
|
*start = 0;
|
||||||
|
*width = arrow;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case wxScrollBar::Element_Arrow_Line_2:
|
||||||
|
*start = length - arrow;
|
||||||
|
*width = arrow;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case wxScrollBar::Element_Arrow_Page_1:
|
||||||
|
case wxScrollBar::Element_Arrow_Page_2:
|
||||||
|
// we don't have them at all
|
||||||
|
break;
|
||||||
|
|
||||||
|
case wxScrollBar::Element_Thumb:
|
||||||
|
case wxScrollBar::Element_Bar_1:
|
||||||
|
case wxScrollBar::Element_Bar_2:
|
||||||
|
// we need to calculate the thumb position - do it
|
||||||
|
{
|
||||||
|
length -= 2*arrow;
|
||||||
|
wxCoord thumbStart, thumbEnd;
|
||||||
|
int range = scrollbar->GetRange();
|
||||||
|
if ( !range )
|
||||||
|
{
|
||||||
|
thumbStart =
|
||||||
|
thumbEnd = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int thumbSize = scrollbar->GetThumbSize();
|
||||||
|
|
||||||
|
thumbStart = (length*thumbPos) / range;
|
||||||
|
thumbEnd = (length*(thumbPos + thumbSize)) / range;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( elem == wxScrollBar::Element_Thumb )
|
||||||
|
{
|
||||||
|
*start = thumbStart;
|
||||||
|
*width = thumbEnd - thumbStart;
|
||||||
|
}
|
||||||
|
else if ( elem == wxScrollBar::Element_Bar_1 )
|
||||||
|
{
|
||||||
|
*start = 0;
|
||||||
|
*width = thumbStart;
|
||||||
|
}
|
||||||
|
else // elem == wxScrollBar::Element_Bar_2
|
||||||
|
{
|
||||||
|
*start = thumbEnd;
|
||||||
|
*width = length - thumbEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
// everything is relative to the start of the shaft so far
|
||||||
|
*start += arrow;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case wxScrollBar::Element_Max:
|
||||||
|
default:
|
||||||
|
wxFAIL_MSG( _T("unknown scrollbar element") );
|
||||||
|
}
|
||||||
|
|
||||||
|
return rect;
|
||||||
|
}
|
||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
wxCoord wxRenderer::StandardScrollBarSize(const wxScrollBar *scrollbar,
|
wxCoord wxRenderer::StandardScrollBarSize(const wxScrollBar *scrollbar,
|
||||||
const wxSize& sizeArrowSB)
|
const wxSize& sizeArrowSB)
|
||||||
@@ -91,6 +191,7 @@ wxCoord wxRenderer::StandardScrollBarSize(const wxScrollBar *scrollbar,
|
|||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
wxCoord wxRenderer::StandardScrollbarToPixel(const wxScrollBar *scrollbar,
|
wxCoord wxRenderer::StandardScrollbarToPixel(const wxScrollBar *scrollbar,
|
||||||
|
int thumbPos,
|
||||||
const wxSize& sizeArrow)
|
const wxSize& sizeArrow)
|
||||||
{
|
{
|
||||||
int range = scrollbar->GetRange();
|
int range = scrollbar->GetRange();
|
||||||
@@ -100,8 +201,13 @@ wxCoord wxRenderer::StandardScrollbarToPixel(const wxScrollBar *scrollbar,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ( scrollbar->GetThumbPosition() *
|
if ( thumbPos == -1 )
|
||||||
StandardScrollBarSize(scrollbar, sizeArrow) ) / range
|
{
|
||||||
|
// by default use the current thumb position
|
||||||
|
thumbPos = scrollbar->GetThumbPosition();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ( thumbPos*StandardScrollBarSize(scrollbar, sizeArrow) ) / range
|
||||||
+ (scrollbar->IsVertical() ? sizeArrow.y : sizeArrow.x);
|
+ (scrollbar->IsVertical() ? sizeArrow.y : sizeArrow.x);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,8 +325,13 @@ void wxControlRenderer::DrawBorder()
|
|||||||
m_renderer->DrawBorder(m_dc, m_window->GetBorder(),
|
m_renderer->DrawBorder(m_dc, m_window->GetBorder(),
|
||||||
m_rect, flags, &m_rect);
|
m_rect, flags, &m_rect);
|
||||||
|
|
||||||
// fill the inside (TODO: query the theme for bg bitmap)
|
// fill the inside unless we have the background bitmap as we don't want to
|
||||||
m_renderer->DrawBackground(m_dc, m_rect, flags);
|
// overwrite it
|
||||||
|
if ( !m_window->GetBackgroundBitmap().Ok() )
|
||||||
|
{
|
||||||
|
m_renderer->DrawBackground(m_dc, m_window->GetBackgroundColour(),
|
||||||
|
m_rect, flags);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxControlRenderer::DrawLabel(const wxBitmap& bitmap,
|
void wxControlRenderer::DrawLabel(const wxBitmap& bitmap,
|
||||||
@@ -272,7 +383,8 @@ void wxControlRenderer::DrawButtonBorder()
|
|||||||
|
|
||||||
m_renderer->DrawButtonBorder(m_dc, m_rect, flags, &m_rect);
|
m_renderer->DrawButtonBorder(m_dc, m_rect, flags, &m_rect);
|
||||||
|
|
||||||
m_renderer->DrawBackground(m_dc, m_rect, flags);
|
m_renderer->DrawBackground(m_dc, m_window->GetBackgroundColour(),
|
||||||
|
m_rect, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxControlRenderer::DrawBitmap(const wxBitmap& bitmap)
|
void wxControlRenderer::DrawBitmap(const wxBitmap& bitmap)
|
||||||
@@ -357,36 +469,85 @@ void wxControlRenderer::DrawBitmap(const wxBitmap& bitmap,
|
|||||||
m_dc.DrawBitmap(bmp, x, y, TRUE /* use mask */);
|
m_dc.DrawBitmap(bmp, x, y, TRUE /* use mask */);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxControlRenderer::DrawScrollbar(const wxScrollBar *scrollbar)
|
void wxControlRenderer::DrawScrollbar(const wxScrollBar *scrollbar,
|
||||||
|
int thumbPosOld)
|
||||||
{
|
{
|
||||||
int thumbStart, thumbEnd;
|
// we will only redraw the parts which must be redrawn and not everything
|
||||||
int range = scrollbar->GetRange();
|
wxRegion rgnUpdate = scrollbar->GetUpdateRegion();
|
||||||
if ( range )
|
|
||||||
{
|
|
||||||
int thumbPos = scrollbar->GetThumbPosition(),
|
|
||||||
thumbSize = scrollbar->GetThumbSize();
|
|
||||||
|
|
||||||
thumbStart = (100*thumbPos) / range;
|
// arrows
|
||||||
thumbEnd = (100*(thumbPos + thumbSize)) / range;
|
static const wxDirection arrowDirs[2][2] =
|
||||||
}
|
|
||||||
else // no range
|
|
||||||
{
|
{
|
||||||
thumbStart =
|
{ wxLEFT, wxRIGHT },
|
||||||
thumbEnd = 0;
|
{ wxUP, wxDOWN }
|
||||||
|
};
|
||||||
|
|
||||||
|
for ( int nArrow = 0; nArrow < 2; nArrow++ )
|
||||||
|
{
|
||||||
|
wxScrollBar::Element elem =
|
||||||
|
(wxScrollBar::Element)(wxScrollBar::Element_Arrow_Line_1 + nArrow);
|
||||||
|
|
||||||
|
wxRect rectArrow = m_renderer->GetScrollbarRect(scrollbar, elem);
|
||||||
|
if ( rgnUpdate.Contains(rectArrow) )
|
||||||
|
{
|
||||||
|
m_renderer->DrawArrow(m_dc,
|
||||||
|
arrowDirs[scrollbar->IsVertical()][nArrow],
|
||||||
|
rectArrow,
|
||||||
|
scrollbar->GetState(elem));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int flags[wxScrollBar::Element_Max];
|
// TODO: support for page arrows
|
||||||
for ( size_t n = 0; n < WXSIZEOF(flags); n++ )
|
|
||||||
|
// the shaft
|
||||||
|
for ( int nBar = 0; nBar < 2; nBar++ )
|
||||||
{
|
{
|
||||||
flags[n] = scrollbar->GetState((wxScrollBar::Element)n);
|
wxScrollBar::Element elem =
|
||||||
|
(wxScrollBar::Element)(wxScrollBar::Element_Bar_1 + nBar);
|
||||||
|
|
||||||
|
wxRect rectBar = m_renderer->GetScrollbarRect(scrollbar, elem);
|
||||||
|
|
||||||
|
if ( rgnUpdate.Contains(rectBar) )
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
// we try to avoid redrawing the entire shaft (which might be quite
|
||||||
|
// long) if possible by only redrawing the area between the old and
|
||||||
|
// current positions of the thumb
|
||||||
|
if ( thumbPosOld != -1 )
|
||||||
|
{
|
||||||
|
wxRect rectBarOld = m_renderer->GetScrollbarRect(scrollbar,
|
||||||
|
elem,
|
||||||
|
thumbPosOld);
|
||||||
|
if ( scrollbar->IsVertical() )
|
||||||
|
{
|
||||||
|
if ( nBar )
|
||||||
|
rectBar.SetBottom(rectBar.GetTop());
|
||||||
|
else
|
||||||
|
rectBar.SetTop(rectBarOld.GetBottom());
|
||||||
|
}
|
||||||
|
else // horizontal
|
||||||
|
{
|
||||||
|
if ( nBar )
|
||||||
|
rectBar.SetRight(rectBar.GetLeft());
|
||||||
|
else
|
||||||
|
rectBar.SetLeft(rectBarOld.GetRight());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // 0
|
||||||
|
|
||||||
|
m_renderer->DrawScrollbarShaft(m_dc, rectBar,
|
||||||
|
scrollbar->GetState(elem));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_renderer->DrawScrollbar(m_dc,
|
// and the thumb
|
||||||
m_window->GetWindowStyle() & wxVERTICAL
|
wxScrollBar::Element elem = wxScrollBar::Element_Thumb;
|
||||||
? wxVERTICAL
|
wxRect rectThumb = m_renderer->GetScrollbarRect(scrollbar, elem);
|
||||||
: wxHORIZONTAL,
|
if ( rgnUpdate.Contains(rectThumb) )
|
||||||
thumbStart, thumbEnd, m_rect,
|
{
|
||||||
flags);
|
m_renderer->DrawScrollbarThumb(m_dc, rectThumb,
|
||||||
|
scrollbar->GetState(elem));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxControlRenderer::DrawLine(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2)
|
void wxControlRenderer::DrawLine(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2)
|
||||||
@@ -399,3 +560,24 @@ void wxControlRenderer::DrawLine(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2)
|
|||||||
else // horizontal
|
else // horizontal
|
||||||
m_renderer->DrawHorizontalLine(m_dc, y1, x1, x2);
|
m_renderer->DrawHorizontalLine(m_dc, y1, x1, x2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wxControlRenderer::DrawItems(const wxListBox *lbox,
|
||||||
|
size_t itemFirst, size_t itemLast)
|
||||||
|
{
|
||||||
|
wxCoord lineHeight = lbox->GetLineHeight();
|
||||||
|
wxRect rect = m_rect;
|
||||||
|
rect.y += itemFirst*lineHeight;
|
||||||
|
rect.height = lineHeight;
|
||||||
|
for ( size_t n = itemFirst; n < itemLast; n++ )
|
||||||
|
{
|
||||||
|
int flags = 0;
|
||||||
|
if ( (int)n == lbox->GetCurrentItem() )
|
||||||
|
flags |= wxCONTROL_FOCUSED;
|
||||||
|
if ( lbox->IsSelected(n) )
|
||||||
|
flags |= wxCONTROL_SELECTED;
|
||||||
|
|
||||||
|
m_renderer->DrawItem(m_dc, lbox->GetString(n), rect, flags);
|
||||||
|
|
||||||
|
rect.y += lineHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -30,6 +30,8 @@
|
|||||||
#if wxUSE_SCROLLBAR
|
#if wxUSE_SCROLLBAR
|
||||||
|
|
||||||
#ifndef WX_PRECOMP
|
#ifndef WX_PRECOMP
|
||||||
|
#include "wx/timer.h"
|
||||||
|
|
||||||
#include "wx/dcclient.h"
|
#include "wx/dcclient.h"
|
||||||
#include "wx/scrolbar.h"
|
#include "wx/scrolbar.h"
|
||||||
#include "wx/validate.h"
|
#include "wx/validate.h"
|
||||||
@@ -39,12 +41,37 @@
|
|||||||
#include "wx/univ/inphand.h"
|
#include "wx/univ/inphand.h"
|
||||||
#include "wx/univ/theme.h"
|
#include "wx/univ/theme.h"
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// wxScrollBarTimer: this class is used to repeatedly scroll the scrollbar
|
||||||
|
// when the mouse is help pressed on the arrow or on the bar. It generates the
|
||||||
|
// given scroll action command periodically.
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class wxScrollBarTimer : public wxTimer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
wxScrollBarTimer(wxStdScrollBarInputHandler *handler,
|
||||||
|
const wxControlAction& action,
|
||||||
|
wxScrollBar *control);
|
||||||
|
|
||||||
|
virtual void Notify();
|
||||||
|
|
||||||
|
private:
|
||||||
|
wxStdScrollBarInputHandler *m_handler;
|
||||||
|
wxControlAction m_action;
|
||||||
|
wxScrollBar *m_control;
|
||||||
|
};
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// implementation
|
// implementation
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
IMPLEMENT_DYNAMIC_CLASS(wxScrollBar, wxControl)
|
IMPLEMENT_DYNAMIC_CLASS(wxScrollBar, wxControl)
|
||||||
|
|
||||||
|
BEGIN_EVENT_TABLE(wxScrollBar, wxScrollBarBase)
|
||||||
|
EVT_IDLE(wxScrollBar::OnIdle)
|
||||||
|
END_EVENT_TABLE()
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// creation
|
// creation
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -56,10 +83,14 @@ void wxScrollBar::Init()
|
|||||||
m_thumbPos =
|
m_thumbPos =
|
||||||
m_pageSize = 0;
|
m_pageSize = 0;
|
||||||
|
|
||||||
|
m_thumbPosOld = -1;
|
||||||
|
|
||||||
for ( size_t n = 0; n < WXSIZEOF(m_elementsState); n++ )
|
for ( size_t n = 0; n < WXSIZEOF(m_elementsState); n++ )
|
||||||
{
|
{
|
||||||
m_elementsState[n] = 0;
|
m_elementsState[n] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_dirty = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxScrollBar::Create(wxWindow *parent,
|
bool wxScrollBar::Create(wxWindow *parent,
|
||||||
@@ -102,7 +133,20 @@ void wxScrollBar::DoSetThumb(int pos)
|
|||||||
pos = m_range - m_thumbSize;
|
pos = m_range - m_thumbSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( m_thumbPosOld == -1 )
|
||||||
|
{
|
||||||
|
// remember the old thumb position
|
||||||
|
m_thumbPosOld = m_thumbPos;
|
||||||
|
}
|
||||||
|
|
||||||
m_thumbPos = pos;
|
m_thumbPos = pos;
|
||||||
|
|
||||||
|
// we have to refresh the part of the bar which was under the thumb and the
|
||||||
|
// thumb itself
|
||||||
|
m_elementsState[Element_Thumb] |= wxCONTROL_DIRTY;
|
||||||
|
m_elementsState[m_thumbPos > m_thumbPosOld
|
||||||
|
? Element_Bar_1 : Element_Bar_2] |= wxCONTROL_DIRTY;
|
||||||
|
m_dirty = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int wxScrollBar::GetThumbPosition() const
|
int wxScrollBar::GetThumbPosition() const
|
||||||
@@ -130,8 +174,6 @@ void wxScrollBar::SetThumbPosition(int pos)
|
|||||||
wxCHECK_RET( pos >= 0 && pos <= m_range, _T("thumb position out of range") );
|
wxCHECK_RET( pos >= 0 && pos <= m_range, _T("thumb position out of range") );
|
||||||
|
|
||||||
DoSetThumb(pos);
|
DoSetThumb(pos);
|
||||||
|
|
||||||
Refresh();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxScrollBar::SetScrollbar(int position, int thumbSize,
|
void wxScrollBar::SetScrollbar(int position, int thumbSize,
|
||||||
@@ -155,34 +197,67 @@ void wxScrollBar::SetScrollbar(int position, int thumbSize,
|
|||||||
// size management
|
// size management
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
wxSize wxScrollBar::DoGetBestSize() const
|
wxSize wxScrollBar::DoGetBestClientSize() const
|
||||||
{
|
{
|
||||||
// completely arbitrary
|
// completely arbitrary
|
||||||
return AdjustSize(wxSize(140, 140));
|
return wxSize(140, 140);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// drawing
|
// drawing
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void wxScrollBar::OnIdle(wxIdleEvent& event)
|
||||||
|
{
|
||||||
|
if ( m_dirty )
|
||||||
|
{
|
||||||
|
for ( size_t n = 0; n < WXSIZEOF(m_elementsState); n++ )
|
||||||
|
{
|
||||||
|
if ( m_elementsState[n] & wxCONTROL_DIRTY )
|
||||||
|
{
|
||||||
|
wxRect rect = GetRenderer()->GetScrollbarRect(this, (Element)n);
|
||||||
|
|
||||||
|
if ( rect.width && rect.height )
|
||||||
|
{
|
||||||
|
// don't refresh the background when refreshing the shaft
|
||||||
|
Refresh(TRUE, //(n != Element_Bar_1) && (n != Element_Bar_2)
|
||||||
|
&rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_elementsState[n] &= ~wxCONTROL_DIRTY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_dirty = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void wxScrollBar::DoDraw(wxControlRenderer *renderer)
|
void wxScrollBar::DoDraw(wxControlRenderer *renderer)
|
||||||
{
|
{
|
||||||
renderer->DrawScrollbar(this);
|
renderer->DrawScrollbar(this, m_thumbPosOld);
|
||||||
|
|
||||||
|
// clear all dirty flags
|
||||||
|
m_dirty = FALSE;
|
||||||
|
m_thumbPosOld = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// input processing
|
// input processing
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
wxCoord wxScrollBar::GetMouseCoord(const wxEvent& eventOrig) const
|
void wxScrollBar::SetState(Element which, int flags)
|
||||||
{
|
{
|
||||||
const wxMouseEvent& event = (const wxMouseEvent&)eventOrig;
|
if ( (m_elementsState[which] & ~wxCONTROL_DIRTY) != flags )
|
||||||
wxPoint pt = event.GetPosition();
|
{
|
||||||
return GetWindowStyle() & wxVERTICAL ? pt.y : pt.x;
|
m_elementsState[which] = flags | wxCONTROL_DIRTY;
|
||||||
|
|
||||||
|
m_dirty = TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxScrollBar::PerformAction(const wxControlAction& action,
|
bool wxScrollBar::PerformAction(const wxControlAction& action,
|
||||||
const wxEvent& event)
|
long numArg,
|
||||||
|
const wxString& strArg)
|
||||||
{
|
{
|
||||||
int thumbOld = m_thumbPos;
|
int thumbOld = m_thumbPos;
|
||||||
|
|
||||||
@@ -193,10 +268,7 @@ bool wxScrollBar::PerformAction(const wxControlAction& action,
|
|||||||
// test for thumb move first as these events happen in quick succession
|
// test for thumb move first as these events happen in quick succession
|
||||||
if ( action == wxACTION_SCROLL_THUMB_MOVE )
|
if ( action == wxACTION_SCROLL_THUMB_MOVE )
|
||||||
{
|
{
|
||||||
// make the thumb follow the mouse by keeping the same offset between
|
DoSetThumb(numArg);
|
||||||
// the mouse position and the top/left of the thumb
|
|
||||||
int thumbPos = GetMouseCoord(event) - m_ofsMouse;
|
|
||||||
DoSetThumb(GetRenderer()->PixelToScrollbar(this, thumbPos));
|
|
||||||
|
|
||||||
scrollType = wxEVT_SCROLLWIN_THUMBTRACK;
|
scrollType = wxEVT_SCROLLWIN_THUMBTRACK;
|
||||||
}
|
}
|
||||||
@@ -232,8 +304,10 @@ bool wxScrollBar::PerformAction(const wxControlAction& action,
|
|||||||
}
|
}
|
||||||
else if ( action == wxACTION_SCROLL_THUMB_DRAG )
|
else if ( action == wxACTION_SCROLL_THUMB_DRAG )
|
||||||
{
|
{
|
||||||
m_ofsMouse = GetMouseCoord(event) -
|
// we won't use it but this line suppresses the compiler
|
||||||
GetRenderer()->ScrollbarToPixel(this);
|
// warning about "variable may be used without having been
|
||||||
|
// initialized"
|
||||||
|
scrollType = wxEVT_NULL;
|
||||||
}
|
}
|
||||||
else if ( action == wxACTION_SCROLL_THUMB_RELEASE )
|
else if ( action == wxACTION_SCROLL_THUMB_RELEASE )
|
||||||
{
|
{
|
||||||
@@ -242,7 +316,7 @@ bool wxScrollBar::PerformAction(const wxControlAction& action,
|
|||||||
scrollType = wxEVT_SCROLLWIN_THUMBRELEASE;
|
scrollType = wxEVT_SCROLLWIN_THUMBRELEASE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return wxControl::PerformAction(action, event);
|
return wxControl::PerformAction(action, numArg, strArg);
|
||||||
|
|
||||||
// has scrollbar position changed?
|
// has scrollbar position changed?
|
||||||
bool changed = m_thumbPos != thumbOld;
|
bool changed = m_thumbPos != thumbOld;
|
||||||
@@ -254,8 +328,7 @@ bool wxScrollBar::PerformAction(const wxControlAction& action,
|
|||||||
GetParent()->GetEventHandler()->ProcessEvent(event);
|
GetParent()->GetEventHandler()->ProcessEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
// refresh if something changed
|
return TRUE;
|
||||||
return changed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxScrollBar::ScrollToStart()
|
void wxScrollBar::ScrollToStart()
|
||||||
@@ -278,5 +351,333 @@ void wxScrollBar::ScrollPages(int nPages)
|
|||||||
DoSetThumb(m_thumbPos + nPages*m_pageSize);
|
DoSetThumb(m_thumbPos + nPages*m_pageSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// scroll bar input handler
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// wxScrollBarTimer
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
wxScrollBarTimer::wxScrollBarTimer(wxStdScrollBarInputHandler *handler,
|
||||||
|
const wxControlAction& action,
|
||||||
|
wxScrollBar *control)
|
||||||
|
{
|
||||||
|
m_handler = handler;
|
||||||
|
m_action = action;
|
||||||
|
m_control = control;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxScrollBarTimer::Notify()
|
||||||
|
{
|
||||||
|
m_handler->OnScrollTimer(m_control, m_action);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// wxStdScrollBarInputHandler
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
wxStdScrollBarInputHandler::wxStdScrollBarInputHandler(wxRenderer *renderer,
|
||||||
|
wxInputHandler *handler)
|
||||||
|
: wxStdInputHandler(handler)
|
||||||
|
{
|
||||||
|
m_renderer = renderer;
|
||||||
|
m_winCapture = NULL;
|
||||||
|
m_htLast = wxHT_NOWHERE;
|
||||||
|
m_timerScroll = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxStdScrollBarInputHandler::~wxStdScrollBarInputHandler()
|
||||||
|
{
|
||||||
|
// normally, it's NULL by now but just in case the user somehow managed to
|
||||||
|
// keep the mouse captured until now...
|
||||||
|
delete m_timerScroll;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxStdScrollBarInputHandler::SetElementState(wxScrollBar *control,
|
||||||
|
int flag,
|
||||||
|
bool doIt)
|
||||||
|
{
|
||||||
|
if ( m_htLast > wxHT_SCROLLBAR_FIRST && m_htLast < wxHT_SCROLLBAR_LAST )
|
||||||
|
{
|
||||||
|
wxScrollBar::Element
|
||||||
|
elem = (wxScrollBar::Element)(m_htLast - wxHT_SCROLLBAR_FIRST - 1);
|
||||||
|
|
||||||
|
int flags = control->GetState(elem);
|
||||||
|
if ( doIt )
|
||||||
|
flags |= flag;
|
||||||
|
else
|
||||||
|
flags &= ~flag;
|
||||||
|
control->SetState(elem, flags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxStdScrollBarInputHandler::OnScrollTimer(wxScrollBar *scrollbar,
|
||||||
|
const wxControlAction& action)
|
||||||
|
{
|
||||||
|
int oldThumbPos = scrollbar->GetThumbPosition();
|
||||||
|
scrollbar->PerformAction(action);
|
||||||
|
if ( scrollbar->GetThumbPosition() != oldThumbPos )
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
// we scrolled till the end
|
||||||
|
m_timerScroll->Stop();
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxStdScrollBarInputHandler::StopScrolling(wxScrollBar *control)
|
||||||
|
{
|
||||||
|
// return everything to the normal state
|
||||||
|
if ( m_winCapture )
|
||||||
|
{
|
||||||
|
m_winCapture->ReleaseMouse();
|
||||||
|
m_winCapture = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_btnCapture = -1;
|
||||||
|
|
||||||
|
if ( m_timerScroll )
|
||||||
|
{
|
||||||
|
delete m_timerScroll;
|
||||||
|
m_timerScroll = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// unpress the arrow and highlight the current element
|
||||||
|
Press(control, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
wxCoord
|
||||||
|
wxStdScrollBarInputHandler::GetMouseCoord(const wxScrollBar *scrollbar,
|
||||||
|
const wxMouseEvent& event) const
|
||||||
|
{
|
||||||
|
wxPoint pt = event.GetPosition();
|
||||||
|
return scrollbar->GetWindowStyle() & wxVERTICAL ? pt.y : pt.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxStdScrollBarInputHandler::HandleThumbMove(wxScrollBar *scrollbar,
|
||||||
|
const wxMouseEvent& event)
|
||||||
|
{
|
||||||
|
int thumbPos = GetMouseCoord(scrollbar, event) - m_ofsMouse;
|
||||||
|
thumbPos = m_renderer->PixelToScrollbar(scrollbar, thumbPos);
|
||||||
|
scrollbar->PerformAction(wxACTION_SCROLL_THUMB_MOVE, thumbPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxStdScrollBarInputHandler::HandleKey(wxControl *control,
|
||||||
|
const wxKeyEvent& event,
|
||||||
|
bool pressed)
|
||||||
|
{
|
||||||
|
// we only react to the key presses here
|
||||||
|
if ( pressed )
|
||||||
|
{
|
||||||
|
wxControlAction action;
|
||||||
|
switch ( event.GetKeyCode() )
|
||||||
|
{
|
||||||
|
case WXK_DOWN:
|
||||||
|
case WXK_RIGHT: action = wxACTION_SCROLL_LINE_DOWN; break;
|
||||||
|
case WXK_UP:
|
||||||
|
case WXK_LEFT: action = wxACTION_SCROLL_LINE_UP; break;
|
||||||
|
case WXK_HOME: action = wxACTION_SCROLL_START; break;
|
||||||
|
case WXK_END: action = wxACTION_SCROLL_END; break;
|
||||||
|
case WXK_PRIOR: action = wxACTION_SCROLL_PAGE_UP; break;
|
||||||
|
case WXK_NEXT: action = wxACTION_SCROLL_PAGE_DOWN; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !!action )
|
||||||
|
{
|
||||||
|
control->PerformAction(action);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return wxStdInputHandler::HandleKey(control, event, pressed);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxStdScrollBarInputHandler::HandleMouse(wxControl *control,
|
||||||
|
const wxMouseEvent& event)
|
||||||
|
{
|
||||||
|
// is this a click event from an acceptable button?
|
||||||
|
int btn = -1;
|
||||||
|
if ( event.IsButton() )
|
||||||
|
{
|
||||||
|
for ( int i = 1; i <= 3; i++ )
|
||||||
|
{
|
||||||
|
if ( event.Button(i) )
|
||||||
|
{
|
||||||
|
btn = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wxASSERT_MSG( btn != -1, _T("unknown mouse button") );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( (btn != -1) && IsAllowedButton(btn) )
|
||||||
|
{
|
||||||
|
// determine which part of the window mouse is in
|
||||||
|
wxScrollBar *scrollbar = wxStaticCast(control, wxScrollBar);
|
||||||
|
wxHitTest ht = m_renderer->HitTestScrollbar
|
||||||
|
(
|
||||||
|
scrollbar,
|
||||||
|
event.GetPosition()
|
||||||
|
);
|
||||||
|
|
||||||
|
// when the mouse is pressed on any scrollbar element, we capture it
|
||||||
|
// and hold capture until the same mouse button is released
|
||||||
|
if ( event.ButtonDown() || event.ButtonDClick() )
|
||||||
|
{
|
||||||
|
if ( !m_winCapture )
|
||||||
|
{
|
||||||
|
m_btnCapture = btn;
|
||||||
|
m_winCapture = control;
|
||||||
|
m_winCapture->CaptureMouse();
|
||||||
|
|
||||||
|
// generate the command
|
||||||
|
bool hasAction = TRUE;
|
||||||
|
wxControlAction action;
|
||||||
|
switch ( ht )
|
||||||
|
{
|
||||||
|
case wxHT_SCROLLBAR_ARROW_LINE_1:
|
||||||
|
action = wxACTION_SCROLL_LINE_UP;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case wxHT_SCROLLBAR_ARROW_LINE_2:
|
||||||
|
action = wxACTION_SCROLL_LINE_DOWN;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case wxHT_SCROLLBAR_BAR_1:
|
||||||
|
action = wxACTION_SCROLL_PAGE_UP;
|
||||||
|
m_ptStartScrolling = event.GetPosition();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case wxHT_SCROLLBAR_BAR_2:
|
||||||
|
action = wxACTION_SCROLL_PAGE_DOWN;
|
||||||
|
m_ptStartScrolling = event.GetPosition();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case wxHT_SCROLLBAR_THUMB:
|
||||||
|
control->PerformAction(wxACTION_SCROLL_THUMB_DRAG);
|
||||||
|
m_ofsMouse = GetMouseCoord(scrollbar, event) -
|
||||||
|
m_renderer->ScrollbarToPixel(scrollbar);
|
||||||
|
|
||||||
|
// fall through: there is no immediate action
|
||||||
|
|
||||||
|
default:
|
||||||
|
hasAction = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove highlighting
|
||||||
|
Highlight(scrollbar, FALSE);
|
||||||
|
m_htLast = ht;
|
||||||
|
|
||||||
|
// and press the arrow or highlight thumb now instead
|
||||||
|
if ( m_htLast == wxHT_SCROLLBAR_THUMB )
|
||||||
|
Highlight(scrollbar, TRUE);
|
||||||
|
else
|
||||||
|
Press(scrollbar, TRUE);
|
||||||
|
|
||||||
|
// start dragging
|
||||||
|
if ( hasAction )
|
||||||
|
{
|
||||||
|
m_timerScroll = new wxScrollBarTimer(this,
|
||||||
|
action,
|
||||||
|
scrollbar);
|
||||||
|
// start scrolling immediately
|
||||||
|
m_timerScroll->Notify();
|
||||||
|
|
||||||
|
// and continue it later
|
||||||
|
m_timerScroll->Start(50); // FIXME hardcoded delay
|
||||||
|
}
|
||||||
|
//else: no (immediate) action
|
||||||
|
|
||||||
|
}
|
||||||
|
//else: mouse already captured, nothing to do
|
||||||
|
}
|
||||||
|
// release mouse if the *same* button went up
|
||||||
|
else if ( btn == m_btnCapture )
|
||||||
|
{
|
||||||
|
if ( m_winCapture )
|
||||||
|
{
|
||||||
|
StopScrolling(scrollbar);
|
||||||
|
|
||||||
|
// if we were dragging the thumb, send the last event
|
||||||
|
if ( m_htLast == wxHT_SCROLLBAR_THUMB )
|
||||||
|
{
|
||||||
|
scrollbar->PerformAction(wxACTION_SCROLL_THUMB_RELEASE);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_htLast = ht;
|
||||||
|
Highlight(scrollbar, TRUE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// this is not supposed to happen as the button can't go up
|
||||||
|
// without going down previously and then we'd have
|
||||||
|
// m_winCapture by now
|
||||||
|
wxFAIL_MSG( _T("logic error in mouse capturing code") );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return wxStdInputHandler::HandleMouse(control, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxStdScrollBarInputHandler::HandleMouseMove(wxControl *control,
|
||||||
|
const wxMouseEvent& event)
|
||||||
|
{
|
||||||
|
wxScrollBar *scrollbar = wxStaticCast(control, wxScrollBar);
|
||||||
|
|
||||||
|
if ( m_winCapture )
|
||||||
|
{
|
||||||
|
if ( (m_htLast == wxHT_SCROLLBAR_THUMB) && event.Moving() )
|
||||||
|
{
|
||||||
|
// make the thumb follow the mouse by keeping the same offset
|
||||||
|
// between the mouse position and the top/left of the thumb
|
||||||
|
HandleThumbMove(scrollbar, event);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// no other changes are possible while the mouse is captured
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( event.Moving() )
|
||||||
|
{
|
||||||
|
wxHitTest ht = m_renderer->HitTestScrollbar
|
||||||
|
(
|
||||||
|
scrollbar,
|
||||||
|
event.GetPosition()
|
||||||
|
);
|
||||||
|
if ( ht == m_htLast )
|
||||||
|
{
|
||||||
|
// nothing changed
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_MOUSE
|
||||||
|
wxLogDebug("Scrollbar::OnMouseMove: ht = %d", ht);
|
||||||
|
#endif // DEBUG_MOUSE
|
||||||
|
|
||||||
|
Highlight(scrollbar, FALSE);
|
||||||
|
m_htLast = ht;
|
||||||
|
Highlight(scrollbar, TRUE);
|
||||||
|
}
|
||||||
|
else if ( event.Leaving() )
|
||||||
|
{
|
||||||
|
Highlight(scrollbar, FALSE);
|
||||||
|
m_htLast = wxHT_NOWHERE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// we don't process this event
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// we did something
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // wxUSE_SCROLLBAR
|
#endif // wxUSE_SCROLLBAR
|
||||||
|
|
||||||
|
@@ -102,9 +102,9 @@ wxIcon wxStaticBitmap::GetIcon() const
|
|||||||
// drawing
|
// drawing
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
wxSize wxStaticBitmap::DoGetBestSize() const
|
wxSize wxStaticBitmap::DoGetBestClientSize() const
|
||||||
{
|
{
|
||||||
return AdjustSize(wxStaticBitmapBase::DoGetBestSize());
|
return wxStaticBitmapBase::DoGetBestSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxStaticBitmap::DoDraw(wxControlRenderer *renderer)
|
void wxStaticBitmap::DoDraw(wxControlRenderer *renderer)
|
||||||
|
@@ -58,13 +58,7 @@ bool wxStaticText::Create(wxWindow *parent,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
SetLabel(label);
|
SetLabel(label);
|
||||||
|
SetBestSize(size);
|
||||||
if ( size.x == -1 || size.y == -1 )
|
|
||||||
{
|
|
||||||
wxSize sizeBest = DoGetBestSize();
|
|
||||||
SetSize(size.x == -1 ? sizeBest.x : size.x,
|
|
||||||
size.y == -1 ? sizeBest.y : size.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@@ -78,13 +72,13 @@ void wxStaticText::SetLabel(const wxString& label)
|
|||||||
wxControl::SetLabel(label);
|
wxControl::SetLabel(label);
|
||||||
}
|
}
|
||||||
|
|
||||||
wxSize wxStaticText::DoGetBestSize() const
|
wxSize wxStaticText::DoGetBestClientSize() const
|
||||||
{
|
{
|
||||||
wxClientDC dc(wxConstCast(this, wxStaticText));
|
wxClientDC dc(wxConstCast(this, wxStaticText));
|
||||||
wxCoord width, height;
|
wxCoord width, height;
|
||||||
dc.GetMultiLineTextExtent(GetLabel(), &width, &height);
|
dc.GetMultiLineTextExtent(GetLabel(), &width, &height);
|
||||||
|
|
||||||
return AdjustSize(wxSize(width, height));
|
return wxSize(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@@ -53,6 +53,7 @@ public:
|
|||||||
|
|
||||||
// implement the base class pure virtuals
|
// implement the base class pure virtuals
|
||||||
virtual void DrawBackground(wxDC& dc,
|
virtual void DrawBackground(wxDC& dc,
|
||||||
|
const wxColour& col,
|
||||||
const wxRect& rect,
|
const wxRect& rect,
|
||||||
int flags = 0);
|
int flags = 0);
|
||||||
virtual void DrawLabel(wxDC& dc,
|
virtual void DrawLabel(wxDC& dc,
|
||||||
@@ -86,19 +87,27 @@ public:
|
|||||||
wxDirection dir,
|
wxDirection dir,
|
||||||
const wxRect& rect,
|
const wxRect& rect,
|
||||||
int flags = 0);
|
int flags = 0);
|
||||||
virtual void DrawScrollbar(wxDC& dc,
|
virtual void DrawScrollbarThumb(wxDC& dc,
|
||||||
wxOrientation orient,
|
|
||||||
int thumbPosStart,
|
|
||||||
int thumbPosEnd,
|
|
||||||
const wxRect& rect,
|
const wxRect& rect,
|
||||||
const int *flags = NULL);
|
int flags = 0);
|
||||||
|
virtual void DrawScrollbarShaft(wxDC& dc,
|
||||||
|
const wxRect& rect,
|
||||||
|
int flags = 0);
|
||||||
|
virtual void DrawItem(wxDC& dc,
|
||||||
|
const wxString& label,
|
||||||
|
const wxRect& rect,
|
||||||
|
int flags = 0);
|
||||||
|
|
||||||
virtual void AdjustSize(wxSize *size, const wxWindow *window);
|
virtual void AdjustSize(wxSize *size, const wxWindow *window);
|
||||||
|
|
||||||
// hit testing for the input handlers
|
// hit testing for the input handlers
|
||||||
|
virtual wxRect GetScrollbarRect(const wxScrollBar *scrollbar,
|
||||||
|
wxScrollBar::Element elem,
|
||||||
|
int thumbPos = -1) const;
|
||||||
virtual wxHitTest HitTestScrollbar(const wxScrollBar *scrollbar,
|
virtual wxHitTest HitTestScrollbar(const wxScrollBar *scrollbar,
|
||||||
const wxPoint& pt) const;
|
const wxPoint& pt) const;
|
||||||
virtual wxCoord ScrollbarToPixel(const wxScrollBar *scrollbar);
|
virtual wxCoord ScrollbarToPixel(const wxScrollBar *scrollbar,
|
||||||
|
int thumbPos = -1);
|
||||||
virtual int PixelToScrollbar(const wxScrollBar *scrollbar, wxCoord coord);
|
virtual int PixelToScrollbar(const wxScrollBar *scrollbar, wxCoord coord);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -159,12 +168,12 @@ class wxGTKInputHandler : public wxInputHandler
|
|||||||
public:
|
public:
|
||||||
wxGTKInputHandler(wxGTKRenderer *renderer);
|
wxGTKInputHandler(wxGTKRenderer *renderer);
|
||||||
|
|
||||||
virtual wxControlActions Map(wxControl *control,
|
virtual bool HandleKey(wxControl *control,
|
||||||
const wxKeyEvent& event,
|
const wxKeyEvent& event,
|
||||||
bool pressed);
|
bool pressed);
|
||||||
virtual wxControlActions Map(wxControl *control,
|
virtual bool HandleMouse(wxControl *control,
|
||||||
const wxMouseEvent& event);
|
const wxMouseEvent& event);
|
||||||
virtual bool OnMouseMove(wxControl *control, const wxMouseEvent& event);
|
virtual bool HandleMouseMove(wxControl *control, const wxMouseEvent& event);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
wxGTKRenderer *m_renderer;
|
wxGTKRenderer *m_renderer;
|
||||||
@@ -592,6 +601,32 @@ void wxGTKRenderer::DrawLabel(wxDC& dc,
|
|||||||
dc.DrawLabel(label, image, rect, alignment, indexAccel, rectBounds);
|
dc.DrawLabel(label, image, rect, alignment, indexAccel, rectBounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wxGTKRenderer::DrawItem(wxDC& dc,
|
||||||
|
const wxString& label,
|
||||||
|
const wxRect& rect,
|
||||||
|
int flags)
|
||||||
|
{
|
||||||
|
if ( flags & wxCONTROL_SELECTED )
|
||||||
|
{
|
||||||
|
dc.SetTextBackground(m_scheme->Get(wxColourScheme::HIGHLIGHT));
|
||||||
|
dc.SetTextForeground(m_scheme->Get(wxColourScheme::HIGHLIGHT_TEXT));
|
||||||
|
dc.SetBackgroundMode(wxSOLID);
|
||||||
|
}
|
||||||
|
|
||||||
|
dc.DrawLabel(label, wxNullBitmap, rect);
|
||||||
|
|
||||||
|
if ( flags & wxCONTROL_SELECTED )
|
||||||
|
{
|
||||||
|
dc.SetBackgroundMode(wxTRANSPARENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( flags & wxCONTROL_FOCUSED )
|
||||||
|
{
|
||||||
|
wxRect rectFocus = rect;
|
||||||
|
DrawRect(dc, &rectFocus, m_penBlack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// background
|
// background
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -607,10 +642,14 @@ void wxGTKRenderer::DoDrawBackground(wxDC& dc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void wxGTKRenderer::DrawBackground(wxDC& dc,
|
void wxGTKRenderer::DrawBackground(wxDC& dc,
|
||||||
|
const wxColour& col,
|
||||||
const wxRect& rect,
|
const wxRect& rect,
|
||||||
int flags)
|
int flags)
|
||||||
{
|
{
|
||||||
DoDrawBackground(dc, GetBackgroundColour(flags), rect);
|
DoDrawBackground(dc,
|
||||||
|
col.Ok() ? col
|
||||||
|
: GetBackgroundColour(flags),
|
||||||
|
rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -786,89 +825,35 @@ void wxGTKRenderer::DrawArrow(wxDC& dc,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxGTKRenderer::DrawScrollbar(wxDC& dc,
|
void wxGTKRenderer::DrawScrollbarThumb(wxDC& dc,
|
||||||
wxOrientation orient,
|
|
||||||
int thumbPosStart,
|
|
||||||
int thumbPosEnd,
|
|
||||||
const wxRect& rect,
|
const wxRect& rect,
|
||||||
const int *flags)
|
int flags)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_MOUSE
|
// the thumb is never pressed never has focus border under GTK and the
|
||||||
wxLogDebug("Drawing the scrollbar (orientation = %s):\n"
|
// scrollbar background never changes at all
|
||||||
"\tarrow 1: 0x%04x\n"
|
int flagsThumb = flags & ~(wxCONTROL_PRESSED | wxCONTROL_FOCUSED);
|
||||||
"\tarrow 2: 0x%04x\n"
|
|
||||||
"\tthumb: 0x%04x\n"
|
|
||||||
"\tthumb from %d to %d",
|
|
||||||
orient == wxVERTICAL ? "vertical" : "horizontal",
|
|
||||||
flags[wxScrollBar::Element_Arrow_Line_1],
|
|
||||||
flags[wxScrollBar::Element_Arrow_Line_2],
|
|
||||||
flags[wxScrollBar::Element_Thumb],
|
|
||||||
thumbPosStart, thumbPosEnd);
|
|
||||||
#endif // DEBUG_MOUSE
|
|
||||||
|
|
||||||
// first draw the scrollbar area background
|
wxRect rectThumb = rect;
|
||||||
|
DrawButtonBorder(dc, rectThumb, flagsThumb, &rectThumb);
|
||||||
|
DrawBackground(dc, wxNullColour, rectThumb, flagsThumb);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxGTKRenderer::DrawScrollbarShaft(wxDC& dc,
|
||||||
|
const wxRect& rect,
|
||||||
|
int flags)
|
||||||
|
{
|
||||||
wxRect rectBar = rect;
|
wxRect rectBar = rect;
|
||||||
DrawAntiShadedRect(dc, &rectBar, m_penDarkGrey, m_penHighlight);
|
DrawAntiShadedRect(dc, &rectBar, m_penDarkGrey, m_penHighlight);
|
||||||
DrawAntiShadedRect(dc, &rectBar, m_penBlack, m_penGrey);
|
DrawAntiShadedRect(dc, &rectBar, m_penBlack, m_penGrey);
|
||||||
DoDrawBackground(dc, m_scheme->Get(wxColourScheme::SCROLLBAR), rectBar);
|
DoDrawBackground(dc, m_scheme->Get(wxColourScheme::SCROLLBAR), rectBar);
|
||||||
|
}
|
||||||
|
|
||||||
// next draw the arrows at the ends
|
wxRect wxGTKRenderer::GetScrollbarRect(const wxScrollBar *scrollbar,
|
||||||
wxRect rectArrow[2];
|
wxScrollBar::Element elem,
|
||||||
wxDirection arrowDir[2];
|
int thumbPos) const
|
||||||
|
{
|
||||||
rectArrow[0] =
|
return StandardGetScrollbarRect(scrollbar, elem,
|
||||||
rectArrow[1] = rectBar;
|
thumbPos, m_sizeScrollbarArrow);
|
||||||
if ( orient == wxVERTICAL )
|
|
||||||
{
|
|
||||||
rectArrow[0].height =
|
|
||||||
rectArrow[1].height = m_sizeScrollbarArrow.y - 1;
|
|
||||||
rectArrow[1].y = rectBar.GetBottom() - rectArrow[1].height + 1;
|
|
||||||
|
|
||||||
arrowDir[0] = wxUP;
|
|
||||||
arrowDir[1] = wxDOWN;
|
|
||||||
}
|
|
||||||
else // horizontal
|
|
||||||
{
|
|
||||||
rectArrow[0].width =
|
|
||||||
rectArrow[1].width = m_sizeScrollbarArrow.x - 1;
|
|
||||||
rectArrow[1].x = rectBar.GetRight() - rectArrow[1].width + 1;
|
|
||||||
|
|
||||||
arrowDir[0] = wxLEFT;
|
|
||||||
arrowDir[1] = wxRIGHT;
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( size_t nArrow = 0; nArrow < 2; nArrow++ )
|
|
||||||
{
|
|
||||||
DrawArrow(dc, arrowDir[nArrow], rectArrow[nArrow],
|
|
||||||
flags[wxScrollBar::Element_Arrow_Line_1 + nArrow]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// and, finally, the thumb, if any
|
|
||||||
if ( thumbPosStart < thumbPosEnd )
|
|
||||||
{
|
|
||||||
wxRect rectThumb;
|
|
||||||
if ( orient == wxVERTICAL )
|
|
||||||
{
|
|
||||||
rectBar.Inflate(0, -m_sizeScrollbarArrow.y);
|
|
||||||
rectThumb = rectBar;
|
|
||||||
rectThumb.y += (rectBar.height*thumbPosStart)/100;
|
|
||||||
rectThumb.height = (rectBar.height*(thumbPosEnd - thumbPosStart))/100;
|
|
||||||
}
|
|
||||||
else // horizontal
|
|
||||||
{
|
|
||||||
rectBar.Inflate(-m_sizeScrollbarArrow.x, 0);
|
|
||||||
rectThumb = rectBar;
|
|
||||||
rectThumb.x += (rectBar.width*thumbPosStart)/100;
|
|
||||||
rectThumb.width = (rectBar.width*(thumbPosEnd - thumbPosStart))/100;
|
|
||||||
}
|
|
||||||
|
|
||||||
// the thumb is never pressed never has focus border under GTK and the
|
|
||||||
// scrollbar background never changes at all
|
|
||||||
int flagsThumb = flags[wxScrollBar::Element_Thumb] &
|
|
||||||
~(wxCONTROL_PRESSED | wxCONTROL_FOCUSED);
|
|
||||||
DrawButtonBorder(dc, rectThumb, flagsThumb, &rectThumb);
|
|
||||||
DrawBackground(dc, rectThumb, flagsThumb);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wxHitTest wxGTKRenderer::HitTestScrollbar(const wxScrollBar *scrollbar,
|
wxHitTest wxGTKRenderer::HitTestScrollbar(const wxScrollBar *scrollbar,
|
||||||
@@ -877,9 +862,10 @@ wxHitTest wxGTKRenderer::HitTestScrollbar(const wxScrollBar *scrollbar,
|
|||||||
return StandardHitTestScrollbar(scrollbar, pt, m_sizeScrollbarArrow);
|
return StandardHitTestScrollbar(scrollbar, pt, m_sizeScrollbarArrow);
|
||||||
}
|
}
|
||||||
|
|
||||||
wxCoord wxGTKRenderer::ScrollbarToPixel(const wxScrollBar *scrollbar)
|
wxCoord wxGTKRenderer::ScrollbarToPixel(const wxScrollBar *scrollbar,
|
||||||
|
int thumbPos)
|
||||||
{
|
{
|
||||||
return StandardScrollbarToPixel(scrollbar, m_sizeScrollbarArrow);
|
return StandardScrollbarToPixel(scrollbar, thumbPos, m_sizeScrollbarArrow);
|
||||||
}
|
}
|
||||||
|
|
||||||
int wxGTKRenderer::PixelToScrollbar(const wxScrollBar *scrollbar,
|
int wxGTKRenderer::PixelToScrollbar(const wxScrollBar *scrollbar,
|
||||||
@@ -962,26 +948,28 @@ wxGTKInputHandler::wxGTKInputHandler(wxGTKRenderer *renderer)
|
|||||||
m_renderer = renderer;
|
m_renderer = renderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxControlActions wxGTKInputHandler::Map(wxControl *control,
|
bool wxGTKInputHandler::HandleKey(wxControl *control,
|
||||||
const wxKeyEvent& event,
|
const wxKeyEvent& event,
|
||||||
bool pressed)
|
bool pressed)
|
||||||
{
|
{
|
||||||
return wxACTION_NONE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxControlActions wxGTKInputHandler::Map(wxControl *control,
|
bool wxGTKInputHandler::HandleMouse(wxControl *control,
|
||||||
const wxMouseEvent& event)
|
const wxMouseEvent& event)
|
||||||
{
|
{
|
||||||
// clicking on the control gives it focus
|
// clicking on the control gives it focus
|
||||||
if ( event.ButtonDown() )
|
if ( event.ButtonDown() )
|
||||||
{
|
{
|
||||||
control->SetFocus();
|
control->SetFocus();
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return wxACTION_NONE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxGTKInputHandler::OnMouseMove(wxControl *control,
|
bool wxGTKInputHandler::HandleMouseMove(wxControl *control,
|
||||||
const wxMouseEvent& event)
|
const wxMouseEvent& event)
|
||||||
{
|
{
|
||||||
if ( event.Entering() )
|
if ( event.Entering() )
|
||||||
@@ -997,7 +985,6 @@ bool wxGTKInputHandler::OnMouseMove(wxControl *control,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// highlighting changed
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -71,6 +71,7 @@ public:
|
|||||||
|
|
||||||
// implement the base class pure virtuals
|
// implement the base class pure virtuals
|
||||||
virtual void DrawBackground(wxDC& dc,
|
virtual void DrawBackground(wxDC& dc,
|
||||||
|
const wxColour& col,
|
||||||
const wxRect& rect,
|
const wxRect& rect,
|
||||||
int flags = 0);
|
int flags = 0);
|
||||||
virtual void DrawLabel(wxDC& dc,
|
virtual void DrawLabel(wxDC& dc,
|
||||||
@@ -104,21 +105,32 @@ public:
|
|||||||
wxDirection dir,
|
wxDirection dir,
|
||||||
const wxRect& rect,
|
const wxRect& rect,
|
||||||
int flags = 0);
|
int flags = 0);
|
||||||
virtual void DrawScrollbar(wxDC& dc,
|
virtual void DrawScrollbarThumb(wxDC& dc,
|
||||||
wxOrientation orient,
|
|
||||||
int thumbPosStart,
|
|
||||||
int thumbPosEnd,
|
|
||||||
const wxRect& rect,
|
const wxRect& rect,
|
||||||
const int *flags = NULL);
|
int flags = 0);
|
||||||
|
virtual void DrawScrollbarShaft(wxDC& dc,
|
||||||
|
const wxRect& rect,
|
||||||
|
int flags = 0);
|
||||||
|
virtual void DrawItem(wxDC& dc,
|
||||||
|
const wxString& label,
|
||||||
|
const wxRect& rect,
|
||||||
|
int flags = 0);
|
||||||
|
|
||||||
virtual void AdjustSize(wxSize *size, const wxWindow *window);
|
virtual void AdjustSize(wxSize *size, const wxWindow *window);
|
||||||
|
|
||||||
|
virtual wxRect GetScrollbarRect(const wxScrollBar *scrollbar,
|
||||||
|
wxScrollBar::Element elem,
|
||||||
|
int thumbPos = -1) const;
|
||||||
virtual wxHitTest HitTestScrollbar(const wxScrollBar *scrollbar,
|
virtual wxHitTest HitTestScrollbar(const wxScrollBar *scrollbar,
|
||||||
const wxPoint& pt) const;
|
const wxPoint& pt) const;
|
||||||
virtual wxCoord ScrollbarToPixel(const wxScrollBar *scrollbar);
|
virtual wxCoord ScrollbarToPixel(const wxScrollBar *scrollbar,
|
||||||
|
int thumbPos = -1);
|
||||||
virtual int PixelToScrollbar(const wxScrollBar *scrollbar, wxCoord coord);
|
virtual int PixelToScrollbar(const wxScrollBar *scrollbar, wxCoord coord);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
// common part of DrawLabel() and DrawItem()
|
||||||
|
void DrawFocusRect(wxDC& dc, const wxRect& rect);
|
||||||
|
|
||||||
// DrawButtonBorder() helper
|
// DrawButtonBorder() helper
|
||||||
void DoDrawBackground(wxDC& dc,
|
void DoDrawBackground(wxDC& dc,
|
||||||
const wxColour& col,
|
const wxColour& col,
|
||||||
@@ -182,10 +194,10 @@ class wxWin32InputHandler : public wxInputHandler
|
|||||||
public:
|
public:
|
||||||
wxWin32InputHandler(wxWin32Renderer *renderer);
|
wxWin32InputHandler(wxWin32Renderer *renderer);
|
||||||
|
|
||||||
virtual wxControlActions Map(wxControl *control,
|
virtual bool HandleKey(wxControl *control,
|
||||||
const wxKeyEvent& event,
|
const wxKeyEvent& event,
|
||||||
bool pressed);
|
bool pressed);
|
||||||
virtual wxControlActions Map(wxControl *control,
|
virtual bool HandleMouse(wxControl *control,
|
||||||
const wxMouseEvent& event);
|
const wxMouseEvent& event);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -198,12 +210,11 @@ public:
|
|||||||
wxWin32ScrollBarInputHandler(wxWin32Renderer *renderer,
|
wxWin32ScrollBarInputHandler(wxWin32Renderer *renderer,
|
||||||
wxInputHandler *handler);
|
wxInputHandler *handler);
|
||||||
|
|
||||||
virtual wxControlActions Map(wxControl *control, const wxMouseEvent& event);
|
virtual bool HandleMouse(wxControl *control, const wxMouseEvent& event);
|
||||||
virtual bool OnMouseMove(wxControl *control, const wxMouseEvent& event);
|
virtual bool HandleMouseMove(wxControl *control, const wxMouseEvent& event);
|
||||||
|
|
||||||
virtual bool OnScrollTimer(wxScrollBar *scrollbar,
|
virtual bool OnScrollTimer(wxScrollBar *scrollbar,
|
||||||
const wxControlAction& action,
|
const wxControlAction& action);
|
||||||
const wxMouseEvent& event);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual bool IsAllowedButton(int button) { return button == 1; }
|
virtual bool IsAllowedButton(int button) { return button == 1; }
|
||||||
@@ -294,6 +305,8 @@ wxInputHandler *wxWin32Theme::GetInputHandler(const wxString& control)
|
|||||||
else if ( control == _T("wxScrollBar") )
|
else if ( control == _T("wxScrollBar") )
|
||||||
handler = new wxWin32ScrollBarInputHandler(m_renderer,
|
handler = new wxWin32ScrollBarInputHandler(m_renderer,
|
||||||
GetInputHandler(_T("wxControl")));
|
GetInputHandler(_T("wxControl")));
|
||||||
|
else if ( control == _T("wxListBox") )
|
||||||
|
handler = new wxStdListboxInputHandler(GetInputHandler(_T("wxControl")));
|
||||||
else
|
else
|
||||||
handler = new wxWin32InputHandler(m_renderer);
|
handler = new wxWin32InputHandler(m_renderer);
|
||||||
|
|
||||||
@@ -817,6 +830,40 @@ void wxWin32Renderer::DrawFrame(wxDC& dc,
|
|||||||
// label
|
// label
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void wxWin32Renderer::DrawFocusRect(wxDC& dc, const wxRect& rect)
|
||||||
|
{
|
||||||
|
// VZ: this doesn't work under Windows, the dotted pen has dots of 3
|
||||||
|
// pixels each while we really need dots here... PS_ALTERNATE might
|
||||||
|
// work, but it is for NT 5 only
|
||||||
|
#if 0
|
||||||
|
DrawRect(dc, &rect, wxPen(*wxBLACK, 0, wxDOT));
|
||||||
|
#else
|
||||||
|
// draw the pixels manually
|
||||||
|
dc.SetPen(wxPen(*wxBLACK, 0, wxSOLID));
|
||||||
|
//dc.SetLogicalFunction(wxXOR);
|
||||||
|
|
||||||
|
// Windows quirk: appears to draw them like this, from right to left
|
||||||
|
// (and I don't have Hebrew windows to see what happens there :-)
|
||||||
|
for ( wxCoord x = rect.GetRight(); x >= rect.GetLeft(); x -= 2 )
|
||||||
|
{
|
||||||
|
dc.DrawPoint(x, rect.GetTop());
|
||||||
|
dc.DrawPoint(x, rect.GetBottom());
|
||||||
|
}
|
||||||
|
|
||||||
|
wxCoord shift = rect.width % 2 ? 0 : 1;
|
||||||
|
for ( wxCoord y = rect.GetTop() + 2; y <= rect.GetBottom(); y+= 2 )
|
||||||
|
{
|
||||||
|
dc.DrawPoint(rect.GetLeft(), y - shift);
|
||||||
|
dc.DrawPoint(rect.GetRight(), y);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( shift )
|
||||||
|
{
|
||||||
|
dc.DrawPoint(rect.GetLeft(), rect.GetBottom() - 1);
|
||||||
|
}
|
||||||
|
#endif // 0/1
|
||||||
|
}
|
||||||
|
|
||||||
void wxWin32Renderer::DrawLabel(wxDC& dc,
|
void wxWin32Renderer::DrawLabel(wxDC& dc,
|
||||||
const wxString& label,
|
const wxString& label,
|
||||||
const wxBitmap& image,
|
const wxBitmap& image,
|
||||||
@@ -856,35 +903,39 @@ void wxWin32Renderer::DrawLabel(wxDC& dc,
|
|||||||
|
|
||||||
if ( flags & wxCONTROL_FOCUSED )
|
if ( flags & wxCONTROL_FOCUSED )
|
||||||
{
|
{
|
||||||
// VZ: this doesn't work under Windows, the dotted pen has dots of 3
|
DrawFocusRect(dc, rectText);
|
||||||
// pixels each while we really need dots here... PS_ALTERNATE might
|
}
|
||||||
// work, but it is for NT 5 only
|
}
|
||||||
#if 0
|
|
||||||
DrawRect(dc, &rectText, wxPen(*wxBLACK, 0, wxDOT));
|
|
||||||
#else
|
|
||||||
// draw the pixels manually
|
|
||||||
dc.SetPen(wxPen(*wxBLACK, 0, wxSOLID));
|
|
||||||
|
|
||||||
// Windows quirk: appears to draw them like this, from right to left
|
void wxWin32Renderer::DrawItem(wxDC& dc,
|
||||||
// (and I don't have Hebrew windows to see what happens there)
|
const wxString& label,
|
||||||
for ( wxCoord x = rectText.GetRight(); x >= rectText.GetLeft(); x -= 2 )
|
const wxRect& rect,
|
||||||
|
int flags)
|
||||||
|
{
|
||||||
|
wxColour colFg;
|
||||||
|
if ( flags & wxCONTROL_SELECTED )
|
||||||
{
|
{
|
||||||
dc.DrawPoint(x, rectText.GetTop());
|
dc.SetBrush(wxBrush(m_scheme->Get(wxColourScheme::HIGHLIGHT), wxSOLID));
|
||||||
dc.DrawPoint(x, rectText.GetBottom());
|
dc.SetPen(*wxTRANSPARENT_PEN);
|
||||||
|
dc.DrawRectangle(rect);
|
||||||
|
colFg = dc.GetTextForeground();
|
||||||
|
dc.SetTextForeground(m_scheme->Get(wxColourScheme::HIGHLIGHT_TEXT));
|
||||||
}
|
}
|
||||||
|
|
||||||
wxCoord shift = rectText.width % 2 ? 0 : 1;
|
wxRect rectText = rect;
|
||||||
for ( wxCoord y = rectText.GetTop() + 2; y <= rectText.GetBottom(); y+= 2 )
|
rectText.x += 2;
|
||||||
|
dc.DrawLabel(label, wxNullBitmap, rectText);
|
||||||
|
|
||||||
|
if ( flags & wxCONTROL_FOCUSED )
|
||||||
{
|
{
|
||||||
dc.DrawPoint(rectText.GetLeft(), y - shift);
|
dc.SetBrush(*wxTRANSPARENT_BRUSH);
|
||||||
dc.DrawPoint(rectText.GetRight(), y);
|
DrawFocusRect(dc, rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( shift )
|
// restore the text colour
|
||||||
|
if ( colFg.Ok() )
|
||||||
{
|
{
|
||||||
dc.DrawPoint(rectText.GetLeft(), rectText.GetBottom() - 1);
|
dc.SetTextForeground(colFg);
|
||||||
}
|
|
||||||
#endif // 0/1
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -903,11 +954,15 @@ void wxWin32Renderer::DoDrawBackground(wxDC& dc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void wxWin32Renderer::DrawBackground(wxDC& dc,
|
void wxWin32Renderer::DrawBackground(wxDC& dc,
|
||||||
|
const wxColour& col,
|
||||||
const wxRect& rect,
|
const wxRect& rect,
|
||||||
int flags)
|
int flags)
|
||||||
{
|
{
|
||||||
// just fill it with the default bg colour
|
// just fill it with the default bg colour
|
||||||
DoDrawBackground(dc, m_scheme->Get(wxColourScheme::CONTROL, flags), rect);
|
DoDrawBackground(dc,
|
||||||
|
col.Ok() ? col
|
||||||
|
: m_scheme->Get(wxColourScheme::CONTROL, flags),
|
||||||
|
rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -933,9 +988,18 @@ void wxWin32Renderer::DrawArrow(wxDC& dc,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxArrowStyle arrowStyle = flags & wxCONTROL_DISABLED ? Arrow_Disabled
|
wxArrowStyle arrowStyle;
|
||||||
: Arrow_Normal;
|
if ( flags & wxCONTROL_PRESSED )
|
||||||
DrawArrow(dc, rect, arrowDir, arrowStyle);
|
{
|
||||||
|
// can't be pressed and disabled
|
||||||
|
arrowStyle = Arrow_Pressed;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
arrowStyle = flags & wxCONTROL_DISABLED ? Arrow_Disabled : Arrow_Normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawArrowButton(dc, rect, arrowDir, arrowStyle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxWin32Renderer::DrawArrow(wxDC& dc,
|
void wxWin32Renderer::DrawArrow(wxDC& dc,
|
||||||
@@ -968,126 +1032,30 @@ void wxWin32Renderer::DrawArrowButton(wxDC& dc,
|
|||||||
DrawArrow(dc, rect, arrowDir, arrowStyle);
|
DrawArrow(dc, rect, arrowDir, arrowStyle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxWin32Renderer::DrawScrollbar(wxDC& dc,
|
void wxWin32Renderer::DrawScrollbarThumb(wxDC& dc,
|
||||||
wxOrientation orient,
|
|
||||||
int thumbPosStart,
|
|
||||||
int thumbPosEnd,
|
|
||||||
const wxRect& rect,
|
const wxRect& rect,
|
||||||
const int *flags)
|
int flags)
|
||||||
{
|
{
|
||||||
// first, draw the arrows at the ends
|
|
||||||
wxRect rectArrow[2];
|
|
||||||
wxArrowDirection arrowDir[2];
|
|
||||||
|
|
||||||
rectArrow[0] =
|
|
||||||
rectArrow[1] = rect;
|
|
||||||
if ( orient == wxVERTICAL )
|
|
||||||
{
|
|
||||||
rectArrow[0].height =
|
|
||||||
rectArrow[1].height = m_sizeScrollbarArrow.y;
|
|
||||||
rectArrow[1].y = rect.GetBottom() - rectArrow[1].height;
|
|
||||||
|
|
||||||
arrowDir[0] = Arrow_Up;
|
|
||||||
arrowDir[1] = Arrow_Down;
|
|
||||||
}
|
|
||||||
else // horizontal
|
|
||||||
{
|
|
||||||
rectArrow[0].width =
|
|
||||||
rectArrow[1].width = m_sizeScrollbarArrow.x;
|
|
||||||
rectArrow[1].x = rect.GetRight() - rectArrow[1].width;
|
|
||||||
|
|
||||||
arrowDir[0] = Arrow_Left;
|
|
||||||
arrowDir[1] = Arrow_Right;
|
|
||||||
}
|
|
||||||
|
|
||||||
wxArrowStyle arrowStyle;
|
|
||||||
for ( size_t nArrow = 0; nArrow < 2; nArrow++ )
|
|
||||||
{
|
|
||||||
int flagsArrow = flags[wxScrollBar::Element_Arrow_Line_1 + nArrow];
|
|
||||||
if ( flagsArrow & wxCONTROL_PRESSED )
|
|
||||||
arrowStyle = Arrow_Pressed;
|
|
||||||
else if ( flagsArrow & wxCONTROL_DISABLED )
|
|
||||||
arrowStyle = Arrow_Disabled;
|
|
||||||
else
|
|
||||||
arrowStyle = Arrow_Normal;
|
|
||||||
|
|
||||||
DrawArrowButton(dc, rectArrow[nArrow], arrowDir[nArrow], arrowStyle);
|
|
||||||
}
|
|
||||||
|
|
||||||
// next draw the scrollbar area: in a normal state, we draw it all in one
|
|
||||||
// call to DoDrawBackground(), but when either part of the bar is pressed,
|
|
||||||
// we paint them separately
|
|
||||||
wxRect rectBar = rect;
|
|
||||||
if ( orient == wxVERTICAL )
|
|
||||||
rectBar.Inflate(0, -(m_sizeScrollbarArrow.y + 1));
|
|
||||||
else
|
|
||||||
rectBar.Inflate(-(m_sizeScrollbarArrow.x + 1), 0);
|
|
||||||
|
|
||||||
// calculate the thumb position
|
|
||||||
wxRect rectThumb;
|
|
||||||
if ( thumbPosStart < thumbPosEnd )
|
|
||||||
{
|
|
||||||
rectThumb = rectBar;
|
|
||||||
if ( orient == wxVERTICAL )
|
|
||||||
{
|
|
||||||
rectThumb.y += (rectBar.height*thumbPosStart)/100;
|
|
||||||
rectThumb.height = (rectBar.height*(thumbPosEnd - thumbPosStart))/100;
|
|
||||||
}
|
|
||||||
else // horizontal
|
|
||||||
{
|
|
||||||
rectThumb.x += (rectBar.width*thumbPosStart)/100;
|
|
||||||
rectThumb.width = (rectBar.width*(thumbPosEnd - thumbPosStart))/100;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//else: no thumb
|
|
||||||
|
|
||||||
if ( (flags[wxScrollBar::Element_Bar_1] & wxCONTROL_PRESSED) ||
|
|
||||||
(flags[wxScrollBar::Element_Bar_2] & wxCONTROL_PRESSED) )
|
|
||||||
{
|
|
||||||
// calculate the bounding boxes for each of 2 bar parts
|
|
||||||
wxRect rectBars[2];
|
|
||||||
rectBars[0] =
|
|
||||||
rectBars[1] = rectBar;
|
|
||||||
if ( orient == wxVERTICAL )
|
|
||||||
{
|
|
||||||
rectBars[0].SetTop(m_sizeScrollbarArrow.y);
|
|
||||||
rectBars[0].SetBottom(rectThumb.GetTop() - 1);
|
|
||||||
rectBars[1].SetTop(rectThumb.GetBottom() + 1);
|
|
||||||
rectBars[1].SetBottom(rectBar.GetBottom());
|
|
||||||
}
|
|
||||||
else // horizontal
|
|
||||||
{
|
|
||||||
rectBars[0].SetLeft(m_sizeScrollbarArrow.x);
|
|
||||||
rectBars[0].SetRight(rectThumb.GetLeft() - 1);
|
|
||||||
rectBars[1].SetLeft(rectThumb.GetRight() + 1);
|
|
||||||
rectBars[1].SetRight(rectBar.GetRight());
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( size_t nBar = 0; nBar < 2; nBar++ )
|
|
||||||
{
|
|
||||||
DoDrawBackground(
|
|
||||||
dc,
|
|
||||||
m_scheme->Get
|
|
||||||
(
|
|
||||||
wxColourScheme::SCROLLBAR,
|
|
||||||
flags[wxScrollBar::Element_Bar_1 + nBar]
|
|
||||||
),
|
|
||||||
rectBars[nBar]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else // nothing is pressed
|
|
||||||
{
|
|
||||||
DoDrawBackground(dc, m_scheme->Get(wxColourScheme::SCROLLBAR), rectBar);
|
|
||||||
}
|
|
||||||
|
|
||||||
// and, finally, the thumb, if any
|
|
||||||
if ( thumbPosStart < thumbPosEnd )
|
|
||||||
{
|
|
||||||
// we don't use the flags, the thumb never changes appearance
|
// we don't use the flags, the thumb never changes appearance
|
||||||
|
wxRect rectThumb = rect;
|
||||||
DrawArrowBorder(dc, &rectThumb);
|
DrawArrowBorder(dc, &rectThumb);
|
||||||
DrawBackground(dc, rectThumb);
|
DrawBackground(dc, wxNullColour, rectThumb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wxWin32Renderer::DrawScrollbarShaft(wxDC& dc,
|
||||||
|
const wxRect& rectBar,
|
||||||
|
int flags)
|
||||||
|
{
|
||||||
|
DoDrawBackground(dc, m_scheme->Get(wxColourScheme::SCROLLBAR, flags),
|
||||||
|
rectBar);
|
||||||
|
}
|
||||||
|
|
||||||
|
wxRect wxWin32Renderer::GetScrollbarRect(const wxScrollBar *scrollbar,
|
||||||
|
wxScrollBar::Element elem,
|
||||||
|
int thumbPos) const
|
||||||
|
{
|
||||||
|
return StandardGetScrollbarRect(scrollbar, elem,
|
||||||
|
thumbPos, m_sizeScrollbarArrow);
|
||||||
}
|
}
|
||||||
|
|
||||||
wxHitTest wxWin32Renderer::HitTestScrollbar(const wxScrollBar *scrollbar,
|
wxHitTest wxWin32Renderer::HitTestScrollbar(const wxScrollBar *scrollbar,
|
||||||
@@ -1096,9 +1064,10 @@ wxHitTest wxWin32Renderer::HitTestScrollbar(const wxScrollBar *scrollbar,
|
|||||||
return StandardHitTestScrollbar(scrollbar, pt, m_sizeScrollbarArrow);
|
return StandardHitTestScrollbar(scrollbar, pt, m_sizeScrollbarArrow);
|
||||||
}
|
}
|
||||||
|
|
||||||
wxCoord wxWin32Renderer::ScrollbarToPixel(const wxScrollBar *scrollbar)
|
wxCoord wxWin32Renderer::ScrollbarToPixel(const wxScrollBar *scrollbar,
|
||||||
|
int thumbPos)
|
||||||
{
|
{
|
||||||
return StandardScrollbarToPixel(scrollbar, m_sizeScrollbarArrow);
|
return StandardScrollbarToPixel(scrollbar, thumbPos, m_sizeScrollbarArrow);
|
||||||
}
|
}
|
||||||
|
|
||||||
int wxWin32Renderer::PixelToScrollbar(const wxScrollBar *scrollbar,
|
int wxWin32Renderer::PixelToScrollbar(const wxScrollBar *scrollbar,
|
||||||
@@ -1179,17 +1148,17 @@ wxWin32InputHandler::wxWin32InputHandler(wxWin32Renderer *renderer)
|
|||||||
m_renderer = renderer;
|
m_renderer = renderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxControlActions wxWin32InputHandler::Map(wxControl *control,
|
bool wxWin32InputHandler::HandleKey(wxControl *control,
|
||||||
const wxKeyEvent& event,
|
const wxKeyEvent& event,
|
||||||
bool pressed)
|
bool pressed)
|
||||||
{
|
{
|
||||||
return wxACTION_NONE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxControlActions wxWin32InputHandler::Map(wxControl *control,
|
bool wxWin32InputHandler::HandleMouse(wxControl *control,
|
||||||
const wxMouseEvent& event)
|
const wxMouseEvent& event)
|
||||||
{
|
{
|
||||||
return wxACTION_NONE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -1206,8 +1175,7 @@ wxWin32ScrollBarInputHandler(wxWin32Renderer *renderer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool wxWin32ScrollBarInputHandler::OnScrollTimer(wxScrollBar *scrollbar,
|
bool wxWin32ScrollBarInputHandler::OnScrollTimer(wxScrollBar *scrollbar,
|
||||||
const wxControlAction& action,
|
const wxControlAction& action)
|
||||||
const wxMouseEvent& event)
|
|
||||||
{
|
{
|
||||||
// stop if went beyond the position of the original click (this can only
|
// stop if went beyond the position of the original click (this can only
|
||||||
// happen when we scroll by pages)
|
// happen when we scroll by pages)
|
||||||
@@ -1232,19 +1200,17 @@ bool wxWin32ScrollBarInputHandler::OnScrollTimer(wxScrollBar *scrollbar,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return wxStdScrollBarInputHandler::OnScrollTimer(scrollbar,
|
return wxStdScrollBarInputHandler::OnScrollTimer(scrollbar, action);
|
||||||
action,
|
|
||||||
event);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wxControlActions wxWin32ScrollBarInputHandler::Map(wxControl *control,
|
bool wxWin32ScrollBarInputHandler::HandleMouse(wxControl *control,
|
||||||
const wxMouseEvent& event)
|
const wxMouseEvent& event)
|
||||||
{
|
{
|
||||||
// remember the current state
|
// remember the current state
|
||||||
bool wasDraggingThumb = m_htLast == wxHT_SCROLLBAR_THUMB;
|
bool wasDraggingThumb = m_htLast == wxHT_SCROLLBAR_THUMB;
|
||||||
|
|
||||||
// do process the message
|
// do process the message
|
||||||
wxControlActions actions = wxStdScrollBarInputHandler::Map(control, event);
|
bool rc = wxStdScrollBarInputHandler::HandleMouse(control, event);
|
||||||
|
|
||||||
// analyse the changes
|
// analyse the changes
|
||||||
if ( !wasDraggingThumb && (m_htLast == wxHT_SCROLLBAR_THUMB) )
|
if ( !wasDraggingThumb && (m_htLast == wxHT_SCROLLBAR_THUMB) )
|
||||||
@@ -1254,10 +1220,10 @@ wxControlActions wxWin32ScrollBarInputHandler::Map(wxControl *control,
|
|||||||
m_eventStartDrag = event;
|
m_eventStartDrag = event;
|
||||||
}
|
}
|
||||||
|
|
||||||
return actions;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxWin32ScrollBarInputHandler::OnMouseMove(wxControl *control,
|
bool wxWin32ScrollBarInputHandler::HandleMouseMove(wxControl *control,
|
||||||
const wxMouseEvent& event)
|
const wxMouseEvent& event)
|
||||||
{
|
{
|
||||||
// we don't highlight scrollbar elements, so there is no need to process
|
// we don't highlight scrollbar elements, so there is no need to process
|
||||||
@@ -1299,8 +1265,7 @@ bool wxWin32ScrollBarInputHandler::OnMouseMove(wxControl *control,
|
|||||||
else // we were dragging the thumb
|
else // we were dragging the thumb
|
||||||
{
|
{
|
||||||
// restore its last location
|
// restore its last location
|
||||||
scrollbar->PerformAction(wxACTION_SCROLL_THUMB_MOVE,
|
HandleThumbMove(scrollbar, m_eventLastDrag);
|
||||||
m_eventLastDrag);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@@ -1351,13 +1316,12 @@ bool wxWin32ScrollBarInputHandler::OnMouseMove(wxControl *control,
|
|||||||
|
|
||||||
// and restore the original position (before dragging) of the
|
// and restore the original position (before dragging) of the
|
||||||
// thumb for now
|
// thumb for now
|
||||||
scrollbar->PerformAction(wxACTION_SCROLL_THUMB_MOVE,
|
HandleThumbMove(scrollbar, m_eventStartDrag);
|
||||||
m_eventStartDrag);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return wxStdScrollBarInputHandler::OnMouseMove(control, event);
|
return wxStdScrollBarInputHandler::HandleMouseMove(control, event);
|
||||||
}
|
}
|
||||||
|
@@ -48,9 +48,14 @@
|
|||||||
// event tables
|
// event tables
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowBase)
|
// we can't use wxWindowNative here as it won't be expanded inside the macro
|
||||||
|
#if defined(__WXMSW__)
|
||||||
|
IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowMSW)
|
||||||
|
#elif defined(__WXGTK__)
|
||||||
|
IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowGTK)
|
||||||
|
#endif
|
||||||
|
|
||||||
BEGIN_EVENT_TABLE(wxWindow, wxWindowBase)
|
BEGIN_EVENT_TABLE(wxWindow, wxWindowNative)
|
||||||
EVT_SIZE(wxWindow::OnSize)
|
EVT_SIZE(wxWindow::OnSize)
|
||||||
|
|
||||||
EVT_PAINT(wxWindow::OnPaint)
|
EVT_PAINT(wxWindow::OnPaint)
|
||||||
@@ -67,6 +72,8 @@ void wxWindow::Init()
|
|||||||
m_scrollbarHorz = (wxScrollBar *)NULL;
|
m_scrollbarHorz = (wxScrollBar *)NULL;
|
||||||
|
|
||||||
m_isCurrent = FALSE;
|
m_isCurrent = FALSE;
|
||||||
|
|
||||||
|
m_renderer = (wxRenderer *)NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -100,11 +107,6 @@ const wxBitmap& wxWindow::GetBackgroundBitmap(int *alignment,
|
|||||||
// painting
|
// painting
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
wxRenderer *wxWindow::GetRenderer() const
|
|
||||||
{
|
|
||||||
return wxTheme::Get()->GetRenderer();
|
|
||||||
}
|
|
||||||
|
|
||||||
// the event handler executed when the window background must be painted
|
// the event handler executed when the window background must be painted
|
||||||
void wxWindow::OnErase(wxEraseEvent& event)
|
void wxWindow::OnErase(wxEraseEvent& event)
|
||||||
{
|
{
|
||||||
@@ -121,12 +123,20 @@ void wxWindow::OnErase(wxEraseEvent& event)
|
|||||||
// the event handler executed when the window must be repainted
|
// the event handler executed when the window must be repainted
|
||||||
void wxWindow::OnPaint(wxPaintEvent& event)
|
void wxWindow::OnPaint(wxPaintEvent& event)
|
||||||
{
|
{
|
||||||
|
if ( !m_renderer )
|
||||||
|
{
|
||||||
|
// it is a native control which paints itself
|
||||||
|
event.Skip();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// get the DC to use and create renderer on it
|
// get the DC to use and create renderer on it
|
||||||
wxPaintDC dc(this);
|
wxPaintDC dc(this);
|
||||||
wxControlRenderer renderer(this, dc, GetRenderer());
|
wxControlRenderer renderer(this, dc, m_renderer);
|
||||||
|
|
||||||
// do draw the control!
|
// do draw the control!
|
||||||
DoDraw(&renderer);
|
DoDraw(&renderer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxWindow::DoDrawBackground(wxControlRenderer *renderer)
|
bool wxWindow::DoDrawBackground(wxControlRenderer *renderer)
|
||||||
@@ -211,10 +221,21 @@ void wxWindow::OnSize(wxSizeEvent& event)
|
|||||||
event.Skip();
|
event.Skip();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxSize wxWindow::DoGetBestSize() const
|
||||||
|
{
|
||||||
|
return AdjustSize(DoGetBestClientSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
wxSize wxWindow::DoGetBestClientSize() const
|
||||||
|
{
|
||||||
|
return wxWindowNative::DoGetBestSize();
|
||||||
|
}
|
||||||
|
|
||||||
wxSize wxWindow::AdjustSize(const wxSize& size) const
|
wxSize wxWindow::AdjustSize(const wxSize& size) const
|
||||||
{
|
{
|
||||||
wxSize sz = size;
|
wxSize sz = size;
|
||||||
wxTheme::Get()->GetRenderer()->AdjustSize(&sz, this);
|
if ( m_renderer )
|
||||||
|
m_renderer->AdjustSize(&sz, this);
|
||||||
return sz;
|
return sz;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -344,27 +365,33 @@ void wxWindow::ScrollWindow(int dx, int dy, const wxRect *rect)
|
|||||||
}
|
}
|
||||||
else // move the part which doesn't change to the new location
|
else // move the part which doesn't change to the new location
|
||||||
{
|
{
|
||||||
// positive values mean to scroll to the left/up
|
// note that when we scroll the canvas in some direction we move the
|
||||||
if ( dx > 0 )
|
// block which doesn't need to be refreshed in the opposite direction
|
||||||
|
|
||||||
|
if ( dx < 0 )
|
||||||
{
|
{
|
||||||
ptSource.x = dx;
|
// scroll to the right, move to the left
|
||||||
|
ptSource.x = -dx;
|
||||||
ptDest.x = 0;
|
ptDest.x = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// scroll to the left, move to the right
|
||||||
ptSource.x = 0;
|
ptSource.x = 0;
|
||||||
ptDest.x = -dx;
|
ptDest.x = dx;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( dy > 0 )
|
if ( dy < 0 )
|
||||||
{
|
{
|
||||||
ptSource.y = dy;
|
// scroll down, move up
|
||||||
|
ptSource.y = -dy;
|
||||||
ptDest.y = 0;
|
ptDest.y = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// scroll up, move down
|
||||||
ptSource.y = 0;
|
ptSource.y = 0;
|
||||||
ptDest.y = -dy;
|
ptDest.y = dy;
|
||||||
}
|
}
|
||||||
|
|
||||||
// do move
|
// do move
|
||||||
@@ -387,12 +414,23 @@ void wxWindow::ScrollWindow(int dx, int dy, const wxRect *rect)
|
|||||||
// it bad?
|
// it bad?
|
||||||
|
|
||||||
wxRect rect;
|
wxRect rect;
|
||||||
rect.x = ptSource.x;
|
|
||||||
rect.y = ptSource.y;
|
|
||||||
|
|
||||||
if ( dx )
|
if ( dx )
|
||||||
{
|
{
|
||||||
rect.width = abs(dx);
|
if ( dx < 0 )
|
||||||
|
{
|
||||||
|
// refresh the area along the right border
|
||||||
|
rect.x = size.x;
|
||||||
|
rect.width = -dx;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// refresh the area along the left border
|
||||||
|
rect.x = 0;
|
||||||
|
rect.width = dx;
|
||||||
|
}
|
||||||
|
|
||||||
|
rect.y = 0;
|
||||||
rect.height = sizeTotal.y;
|
rect.height = sizeTotal.y;
|
||||||
|
|
||||||
wxLogTrace(_T("scroll"), _T("refreshing (%d, %d)-(%d, %d)"),
|
wxLogTrace(_T("scroll"), _T("refreshing (%d, %d)-(%d, %d)"),
|
||||||
@@ -403,8 +441,21 @@ void wxWindow::ScrollWindow(int dx, int dy, const wxRect *rect)
|
|||||||
|
|
||||||
if ( dy )
|
if ( dy )
|
||||||
{
|
{
|
||||||
|
if ( dy < 0 )
|
||||||
|
{
|
||||||
|
// refresh the area along the bottom border
|
||||||
|
rect.y = size.y;
|
||||||
|
rect.height = -dy;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// refresh the area along the top border
|
||||||
|
rect.y = 0;
|
||||||
|
rect.height = dy;
|
||||||
|
}
|
||||||
|
|
||||||
|
rect.x = 0;
|
||||||
rect.width = sizeTotal.x;
|
rect.width = sizeTotal.x;
|
||||||
rect.height = abs(dy);
|
|
||||||
|
|
||||||
wxLogTrace(_T("scroll"), _T("refreshing (%d, %d)-(%d, %d)"),
|
wxLogTrace(_T("scroll"), _T("refreshing (%d, %d)-(%d, %d)"),
|
||||||
rect.x, rect.y, rect.GetRight(), rect.GetBottom());
|
rect.x, rect.y, rect.GetRight(), rect.GetBottom());
|
||||||
|
Reference in New Issue
Block a user