1. wxInputHandler now knows about wxRenderer and uses it

2. wxInputHandler::OnMouseMove() added
3. wxGTKRenderer (almost) draws scrollbars
4. scrollbar mouse handling starts to work


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/wxUNIVERSAL@8160 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2000-08-22 17:02:00 +00:00
parent efe51556de
commit 2c0eba5f88
14 changed files with 716 additions and 226 deletions

View File

@@ -2016,7 +2016,7 @@ if test "$wxUSE_GUI" = "yes"; then
fi fi
if test "$wxUSE_UNIVERSAL" = "yes"; then if test "$wxUSE_UNIVERSAL" = "yes"; then
ALL_DEPFILES="\$(GUI_LOWLEVEL_DEPS)" ALL_DEPFILES="\$(GUI_LOWLEVEL_DEPS) \$(UNIVDEPS)"
else else
ALL_DEPFILES="\$(GUIDEPS)" ALL_DEPFILES="\$(GUIDEPS)"
fi fi

View File

@@ -31,9 +31,6 @@ class WXDLLEXPORT wxInputHandler;
// wxButton: a push button // wxButton: a push button
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// class name
#define wxCONTROL_BUTTON _T("button")
class WXDLLEXPORT wxButton : public wxButtonBase class WXDLLEXPORT wxButton : public wxButtonBase
{ {
public: public:
@@ -75,7 +72,6 @@ public:
void Click(); void Click();
protected: protected:
virtual wxInputHandler *CreateInputHandler() const;
virtual bool PerformAction(const wxControlAction& action, virtual bool PerformAction(const wxControlAction& action,
const wxEvent& event); const wxEvent& event);
virtual wxSize DoGetBestSize() const; virtual wxSize DoGetBestSize() const;

View File

@@ -69,17 +69,13 @@ public:
// 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)
#define wxACTION_NONE _T("") // no action to perform #define wxACTION_NONE _T("") // no action to perform
#define wxACTION_HIGHLIGHT _T("focus") // highlight the control #define wxACTION_FOCUS _T("focus") // make control focused
#define wxACTION_UNHIGHLIGHT _T("unfocus") // remove highlight
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxControl: the base class for all GUI controls // wxControl: the base class for all GUI controls
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// class name
#define wxCONTROL_DEFAULT _T("")
class WXDLLEXPORT wxControl : public wxControlBase class WXDLLEXPORT wxControl : public wxControlBase
{ {
public: public:
@@ -140,6 +136,12 @@ 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
// (the exact event type depends on the action), return TRUE if the
// control must be updated
virtual bool PerformAction(const wxControlAction& action,
const wxEvent& event);
protected: protected:
// 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
@@ -151,12 +153,6 @@ protected:
// draw the controls contents // draw the controls contents
virtual void DoDraw(wxControlRenderer *renderer); virtual void DoDraw(wxControlRenderer *renderer);
// perform the action which resulted from the translation of the event
// (the exact event type depends on the action), return TRUE if the
// control must be updated
virtual bool PerformAction(const wxControlAction& action,
const wxEvent& event);
// event handlers // event handlers
void OnMouse(wxMouseEvent& event); void OnMouse(wxMouseEvent& event);
void OnKeyDown(wxKeyEvent& event); void OnKeyDown(wxKeyEvent& event);

View File

@@ -28,10 +28,23 @@ 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)
virtual wxControlActions Map(const wxKeyEvent& event, bool pressed) = 0; virtual wxControlActions Map(wxControl *control,
const wxKeyEvent& event,
bool pressed) = 0;
// map a mouse event to one or more actions // map a mouse (click) event to one or more actions
virtual wxControlActions Map(const wxMouseEvent& event) = 0; virtual wxControlActions Map(wxControl *control,
const wxMouseEvent& event) = 0;
// do something with mouse move/enter/leave: unlike the Map() functions,
// this doesn't translate the event into an action but, normally, uses the
// renderer directly to change the controls appearance as needed
//
// this is faster than using Map() which is important for mouse move
// 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);
// virtual dtor for any base class // virtual dtor for any base class
virtual ~wxInputHandler(); virtual ~wxInputHandler();

View File

@@ -24,11 +24,33 @@
class WXDLLEXPORT wxControl; class WXDLLEXPORT wxControl;
class WXDLLEXPORT wxDC; class WXDLLEXPORT wxDC;
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"
// ----------------------------------------------------------------------------
// constants
// ----------------------------------------------------------------------------
// hit test results
enum wxHitTest
{
wxHT_NOWHERE,
// scrollbar
wxHT_SCROLLBAR_ARROW_LINE_1, // left or upper arrow to scroll by line
wxHT_SCROLLBAR_ARROW_LINE_2, // right or down
wxHT_SCROLLBAR_ARROW_PAGE_1, // left or upper arrow to scroll by page
wxHT_SCROLLBAR_ARROW_PAGE_2, // right or down
wxHT_SCROLLBAR_THUMB, // on the thumb
wxHT_SCROLLBAR_BAR_1, // bar to the left/above the thumb
wxHT_SCROLLBAR_BAR_2, // bar to the right/below the thumb
wxHT_MAX
};
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxRenderer: abstract renderers interface // wxRenderer: abstract renderers interface
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -36,6 +58,9 @@ class WXDLLEXPORT wxWindow;
class WXDLLEXPORT wxRenderer class WXDLLEXPORT wxRenderer
{ {
public: public:
// drawing functions
// -----------------
// draw the controls background // draw the controls background
virtual void DrawBackground(wxDC& dc, virtual void DrawBackground(wxDC& dc,
const wxRect& rect, const wxRect& rect,
@@ -79,14 +104,14 @@ public:
int flags = 0) = 0; int flags = 0) = 0;
// draw a scrollbar: thumb positions are in percent of the full scrollbar // draw a scrollbar: thumb positions are in percent of the full scrollbar
// length // length and the flags array contains the flags corresponding to each of
// wxScrollBar::Elements
virtual void DrawScrollbar(wxDC& dc, virtual void DrawScrollbar(wxDC& dc,
wxOrientation orient, wxOrientation orient,
int thumbPosStart, int thumbPosStart,
int thumbPosEnd, int thumbPosEnd,
const wxRect& rect, const wxRect& rect,
int flags = 0, const int *flags = NULL) = 0;
int extraFlags = 0) = 0;
// TODO: having this is ugly but I don't see how to solve GetBestSize() // TODO: having this is ugly but I don't see how to solve GetBestSize()
// problem without something like this // problem without something like this
@@ -97,6 +122,13 @@ public:
// the control looks "nice" if it uses the adjusted rectangle // the control looks "nice" if it uses the adjusted rectangle
virtual void AdjustSize(wxSize *size, const wxWindow *window) = 0; virtual void AdjustSize(wxSize *size, const wxWindow *window) = 0;
// hit testing functions
// ---------------------
// returns one of wxHT_SCROLLBAR_XXX constants
virtual wxHitTest HitTestScrollbar(wxScrollBar *scrollbar,
const wxPoint& pt) const = 0;
// virtual dtor for any base class // virtual dtor for any base class
virtual ~wxRenderer(); virtual ~wxRenderer();
}; };
@@ -152,14 +184,17 @@ public:
int thumbPosStart, int thumbPosStart,
int thumbPosEnd, int thumbPosEnd,
const wxRect& rect, const wxRect& rect,
int flags = 0, const int *flags = NULL)
int extraFlags = 0)
{ m_renderer->DrawScrollbar(dc, orient, thumbPosStart, { m_renderer->DrawScrollbar(dc, orient, thumbPosStart,
thumbPosEnd, rect, flags, extraFlags); } thumbPosEnd, 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 wxHitTest HitTestScrollbar(wxScrollBar *scrollbar,
const wxPoint& pt) const
{ return m_renderer->HitTestScrollbar(scrollbar, pt); }
protected: protected:
wxRenderer *m_renderer; wxRenderer *m_renderer;
}; };
@@ -181,7 +216,7 @@ public:
void DrawButtonBorder(); void DrawButtonBorder();
void DrawFrame(); void DrawFrame();
void DrawBackgroundBitmap(); void DrawBackgroundBitmap();
void DrawScrollbar(int thumbStart, int thumbEnd, int extraFlags = 0); void DrawScrollbar(wxScrollBar *scrollbar);
// accessors // accessors
wxRenderer *GetRenderer() const { return m_renderer; } wxRenderer *GetRenderer() const { return m_renderer; }

View File

@@ -22,12 +22,6 @@ class WXDLLEXPORT wxInputHandler;
// the actions supported by this control // the actions supported by this control
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// various parts of scrollbar may be highlighted
#define wxACTION_SCROLL_HIGHLIGHT_ARROW_UP _T("focusarrowup")
#define wxACTION_SCROLL_HIGHLIGHT_ARROW_DOWN _T("focusarrowdown")
#define wxACTION_SCROLL_HIGHLIGHT_THUMB _T("focusthumb")
#define wxACTION_SCROLL_HIGHLIGHT_BAR _T("focusbar")
// scroll the bar // scroll the bar
#define wxACTION_SCROLL_START _T("start") // to the beginning #define wxACTION_SCROLL_START _T("start") // to the beginning
#define wxACTION_SCROLL_END _T("end") // to the end #define wxACTION_SCROLL_END _T("end") // to the end
@@ -45,19 +39,19 @@ class WXDLLEXPORT wxInputHandler;
// wxScrollBar // wxScrollBar
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// class name
#define wxCONTROL_SCROLLBAR _T("scrollbar")
class WXDLLEXPORT wxScrollBar : public wxScrollBarBase class WXDLLEXPORT wxScrollBar : public wxScrollBarBase
{ {
public: public:
enum // the parts of the scrollbar
enum Element
{ {
// which part of scrollbar is currently highlighted? Element_Arrow_Line_1,
Highlight_Arrow1 = 0x0001, Element_Arrow_Line_2,
Highlight_Arrow2 = 0x0002, Element_Arrow_Page_1,
Highlight_Thumb = 0x0004, Element_Arrow_Page_2,
Highlight_Bar = 0x0008 Element_Thumb,
Element_Bar,
Element_Max
}; };
wxScrollBar() { Init(); } wxScrollBar() { Init(); }
@@ -84,26 +78,39 @@ public:
virtual ~wxScrollBar(); virtual ~wxScrollBar();
// implementate base class pure virtuals // implement base class pure virtuals
virtual int GetThumbPosition() const; virtual int GetThumbPosition() const;
virtual int GetThumbSize() const; virtual int GetThumbSize() const;
virtual int GetPageSize() const; virtual int GetPageSize() const;
virtual int GetRange() const; virtual int GetRange() const;
virtual void SetThumbPosition(int viewStart); virtual void SetThumbPosition(int thumbPos);
virtual void SetScrollbar(int position, int thumbSize, virtual void SetScrollbar(int position, int thumbSize,
int range, int pageSize, int range, int pageSize,
bool refresh = TRUE); bool refresh = TRUE);
// wxScrollBar actions // wxScrollBar actions
void ScrollToStart();
void ScrollToEnd();
void ScrollLines(int nLines);
void ScrollPages(int nPages);
protected:
virtual wxInputHandler *CreateInputHandler() const;
virtual bool PerformAction(const wxControlAction& action, virtual bool PerformAction(const wxControlAction& action,
const wxEvent& event); const wxEvent& event);
// wxScrollBar sub elements state (combination of wxCONTROL_XXX)
void SetState(Element elem, int flags)
{ m_elementsState[elem] = flags; }
int GetState(Element elem) const
{ return m_elementsState[elem]; }
protected:
virtual wxSize DoGetBestSize() const; virtual wxSize DoGetBestSize() const;
virtual void DoDraw(wxControlRenderer *renderer); virtual void DoDraw(wxControlRenderer *renderer);
// SetThumbPosition() helper
void DoSetThumb(int thumbPos);
// common part of all ctors // common part of all ctors
void Init(); void Init();
@@ -120,6 +127,9 @@ private:
// up/down action is performed // up/down action is performed
int m_pageSize; int m_pageSize;
// the state of the sub elements
int m_elementsState[Element_Max];
DECLARE_DYNAMIC_CLASS(wxScrollBar) DECLARE_DYNAMIC_CLASS(wxScrollBar)
}; };

View File

@@ -118,11 +118,6 @@ void wxButton::DoDraw(wxControlRenderer *renderer)
// input processing // input processing
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
wxInputHandler *wxButton::CreateInputHandler() const
{
return wxTheme::Get()->GetInputHandler(wxCONTROL_BUTTON);
}
void wxButton::Press() void wxButton::Press()
{ {
m_isPressed = TRUE; m_isPressed = TRUE;

View File

@@ -271,22 +271,32 @@ void wxControl::OnFocus(wxFocusEvent& event)
wxInputHandler *wxControl::CreateInputHandler() const wxInputHandler *wxControl::CreateInputHandler() const
{ {
return wxTheme::Get()->GetInputHandler(wxCONTROL_DEFAULT); return wxTheme::Get()->GetInputHandler(GetName());
} }
void wxControl::OnKeyDown(wxKeyEvent& event) void wxControl::OnKeyDown(wxKeyEvent& event)
{ {
PerformActions(m_handler->Map(event, TRUE), event); PerformActions(m_handler->Map(this, event, TRUE), event);
} }
void wxControl::OnKeyUp(wxKeyEvent& event) void wxControl::OnKeyUp(wxKeyEvent& event)
{ {
PerformActions(m_handler->Map(event, FALSE), event); PerformActions(m_handler->Map(this, event, FALSE), event);
} }
void wxControl::OnMouse(wxMouseEvent& event) void wxControl::OnMouse(wxMouseEvent& event)
{ {
PerformActions(m_handler->Map(event), event); if ( event.Moving() || event.Entering() || event.Leaving() )
{
// don't process it at all for static controls which are not supposed
// to react to the mouse in any way at all
if ( AcceptsFocus() && m_handler->OnMouseMove(this, event) )
Refresh();
}
else // a click action
{
PerformActions(m_handler->Map(this, event), event);
}
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -311,17 +321,14 @@ void wxControl::PerformActions(const wxControlActions& actions,
bool wxControl::PerformAction(const wxControlAction& action, bool wxControl::PerformAction(const wxControlAction& action,
const wxEvent& event) const wxEvent& event)
{ {
if ( (action == wxACTION_NONE) || !AcceptsFocus() ) if ( (action == wxACTION_FOCUS) && AcceptsFocus() )
return FALSE; {
SetFocus();
if ( action == wxACTION_HIGHLIGHT ) return TRUE;
SetCurrent(TRUE); }
else if ( action == wxACTION_UNHIGHLIGHT )
SetCurrent(FALSE);
else
return FALSE;
return TRUE; return FALSE;
} }
#endif // wxUSE_CONTROLS #endif // wxUSE_CONTROLS

View File

@@ -11,4 +11,15 @@ UNIVOBJS = \
gtk.o \ gtk.o \
win32.o win32.o
# winuniv.o UNIVDEPS = \
button.d \
colschem.d \
control.d \
inphand.d \
renderer.d \
scrolbar.d \
statbox.d \
stattext.d \
theme.d \
gtk.d \
win32.d

View File

@@ -37,6 +37,12 @@
// implementation // implementation
// ============================================================================ // ============================================================================
bool wxInputHandler::OnMouseMove(wxControl * WXUNUSED(control),
const wxMouseEvent& WXUNUSED(event))
{
return FALSE;
}
wxInputHandler::~wxInputHandler() wxInputHandler::~wxInputHandler()
{ {
} }

View File

@@ -31,6 +31,7 @@
#ifndef WX_PRECOMP #ifndef WX_PRECOMP
#include "wx/app.h" #include "wx/app.h"
#include "wx/control.h" #include "wx/control.h"
#include "wx/scrolbar.h"
#include "wx/dc.h" #include "wx/dc.h"
#endif // WX_PRECOMP #endif // WX_PRECOMP
@@ -176,12 +177,34 @@ void wxControlRenderer::DrawBackgroundBitmap()
m_dc.DrawBitmap(bmp, x, y); m_dc.DrawBitmap(bmp, x, y);
} }
void wxControlRenderer::DrawScrollbar(int thumbStart, int thumbEnd) void wxControlRenderer::DrawScrollbar(wxScrollBar *scrollbar)
{ {
int thumbStart, thumbEnd;
int range = scrollbar->GetRange();
if ( range )
{
int thumbPos = scrollbar->GetThumbPosition(),
thumbSize = scrollbar->GetThumbSize();
thumbStart = (100*thumbPos) / range;
thumbEnd = (100*(thumbPos + thumbSize)) / range;
}
else // no range
{
thumbStart =
thumbEnd = 0;
}
int flags[wxScrollBar::Element_Max];
for ( size_t n = 0; n < WXSIZEOF(flags); n++ )
{
flags[n] = scrollbar->GetState((wxScrollBar::Element)n);
}
m_renderer->DrawScrollbar(m_dc, m_renderer->DrawScrollbar(m_dc,
m_ctrl->GetWindowStyle() & wxVERTICAL m_ctrl->GetWindowStyle() & wxVERTICAL
? wxVERTICAL ? wxVERTICAL
: wxHORIZONTAL, : wxHORIZONTAL,
thumbStart, thumbEnd, m_rect, thumbStart, thumbEnd, m_rect,
m_ctrl->GetStateFlags()); flags);
} }

View File

@@ -55,6 +55,11 @@ void wxScrollBar::Init()
m_thumbSize = m_thumbSize =
m_thumbPos = m_thumbPos =
m_pageSize = 0; m_pageSize = 0;
for ( size_t n = 0; n < Element_Max; n++ )
{
m_elementsState[n] = 0;
}
} }
bool wxScrollBar::Create(wxWindow *parent, bool wxScrollBar::Create(wxWindow *parent,
@@ -90,6 +95,21 @@ wxScrollBar::~wxScrollBar()
// scrollbar API // scrollbar API
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void wxScrollBar::DoSetThumb(int pos)
{
// don't do checks here, we're a private function
if ( pos < 0 )
{
pos = 0;
}
else if ( pos > m_range - m_thumbSize )
{
pos = m_range - m_thumbSize;
}
m_thumbPos = pos;
}
int wxScrollBar::GetThumbPosition() const int wxScrollBar::GetThumbPosition() const
{ {
return m_thumbPos; return m_thumbPos;
@@ -114,12 +134,9 @@ 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") );
if ( pos >= m_range - m_thumbSize ) DoSetThumb(pos);
{
pos = m_range - m_thumbSize;
}
m_thumbPos = pos; Refresh();
} }
void wxScrollBar::SetScrollbar(int position, int thumbSize, void wxScrollBar::SetScrollbar(int position, int thumbSize,
@@ -156,34 +173,53 @@ wxSize wxScrollBar::DoGetBestSize() const
void wxScrollBar::DoDraw(wxControlRenderer *renderer) void wxScrollBar::DoDraw(wxControlRenderer *renderer)
{ {
int thumbStart, thumbEnd; renderer->DrawScrollbar(this);
if ( m_range )
{
thumbStart = (100*m_thumbPos) / m_range;
thumbEnd = (100*(m_thumbPos + m_thumbSize)) / m_range;
}
else // no range
{
thumbStart =
thumbEnd = 0;
}
renderer->DrawScrollbar(thumbStart, thumbEnd);
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// input processing // input processing
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
wxInputHandler *wxScrollBar::CreateInputHandler() const
{
return wxTheme::Get()->GetInputHandler(wxCONTROL_SCROLLBAR);
}
bool wxScrollBar::PerformAction(const wxControlAction& action, bool wxScrollBar::PerformAction(const wxControlAction& action,
const wxEvent& event) const wxEvent& event)
{ {
return wxControl::PerformAction(action, event); if ( action == wxACTION_SCROLL_START )
ScrollToStart();
else if ( action == wxACTION_SCROLL_END )
ScrollToEnd();
else if ( action == wxACTION_SCROLL_LINE_UP )
ScrollLines(-1);
else if ( action == wxACTION_SCROLL_LINE_DOWN )
ScrollLines(1);
else if ( action == wxACTION_SCROLL_PAGE_UP )
ScrollPages(-1);
else if ( action == wxACTION_SCROLL_PAGE_DOWN )
ScrollPages(1);
else
return wxControl::PerformAction(action, event);
// scrollbar position changed - update
return TRUE;
}
void wxScrollBar::ScrollToStart()
{
DoSetThumb(0);
}
void wxScrollBar::ScrollToEnd()
{
DoSetThumb(m_range - m_thumbSize);
}
void wxScrollBar::ScrollLines(int nLines)
{
DoSetThumb(m_thumbPos + nLines);
}
void wxScrollBar::ScrollPages(int nPages)
{
DoSetThumb(m_thumbPos + nPages*m_pageSize);
} }
#endif // wxUSE_SCROLLBAR #endif // wxUSE_SCROLLBAR

View File

@@ -26,6 +26,7 @@
#ifndef WX_PRECOMP #ifndef WX_PRECOMP
#include "wx/intl.h" #include "wx/intl.h"
#include "wx/log.h"
#include "wx/dc.h" #include "wx/dc.h"
#include "wx/window.h" #include "wx/window.h"
@@ -38,6 +39,9 @@
#include "wx/univ/colschem.h" #include "wx/univ/colschem.h"
#include "wx/univ/theme.h" #include "wx/univ/theme.h"
// define this for tons of debugging messages
#undef DEBUG_MOUSE
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxGTKRenderer: draw the GUI elements in GTK style // wxGTKRenderer: draw the GUI elements in GTK style
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -81,13 +85,22 @@ public:
int thumbPosStart, int thumbPosStart,
int thumbPosEnd, int thumbPosEnd,
const wxRect& rect, const wxRect& rect,
int flags = 0, const int *flags = NULL);
int extraFlags = 0);
virtual void AdjustSize(wxSize *size, const wxWindow *window); virtual void AdjustSize(wxSize *size, const wxWindow *window);
// hit testing for the input handlers
virtual wxHitTest HitTestScrollbar(wxScrollBar *scrollbar,
const wxPoint& pt) const;
protected: protected:
// DrawBackground() helper // DrawBackground() helpers
// get the colour to use for background
wxColour GetBackgroundColour(int flags) const
{ return m_scheme->Get(wxColourScheme::CONTROL, flags); }
// draw the background with any colour, not only the default one(s)
void DoDrawBackground(wxDC& dc, void DoDrawBackground(wxDC& dc,
const wxColour& col, const wxColour& col,
const wxRect& rect); const wxRect& rect);
@@ -136,17 +149,30 @@ private:
class wxGTKInputHandler : public wxInputHandler class wxGTKInputHandler : public wxInputHandler
{ {
public: public:
virtual wxControlActions Map(const wxKeyEvent& event, bool pressed); wxGTKInputHandler(wxGTKRenderer *renderer);
virtual wxControlActions Map(const wxMouseEvent& event);
virtual wxControlActions Map(wxControl *control,
const wxKeyEvent& event,
bool pressed);
virtual wxControlActions Map(wxControl *control,
const wxMouseEvent& event);
virtual bool OnMouseMove(wxControl *control, const wxMouseEvent& event);
protected:
wxGTKRenderer *m_renderer;
}; };
class wxGTKButtonInputHandler : public wxGTKInputHandler class wxGTKButtonInputHandler : public wxGTKInputHandler
{ {
public: public:
wxGTKButtonInputHandler(); wxGTKButtonInputHandler(wxGTKRenderer *renderer);
virtual wxControlActions Map(const wxKeyEvent& event, bool pressed); virtual wxControlActions Map(wxControl *control,
virtual wxControlActions Map(const wxMouseEvent& event); const wxKeyEvent& event,
bool pressed);
virtual wxControlActions Map(wxControl *control,
const wxMouseEvent& event);
virtual bool OnMouseMove(wxControl *control, const wxMouseEvent& event);
private: private:
wxWindow *m_winCapture; wxWindow *m_winCapture;
@@ -156,14 +182,33 @@ private:
class wxGTKScrollBarInputHandler : public wxGTKInputHandler class wxGTKScrollBarInputHandler : public wxGTKInputHandler
{ {
public: public:
wxGTKScrollBarInputHandler(); wxGTKScrollBarInputHandler(wxGTKRenderer *renderer);
virtual wxControlActions Map(const wxKeyEvent& event, bool pressed); virtual wxControlActions Map(wxControl *control,
virtual wxControlActions Map(const wxMouseEvent& event); const wxKeyEvent& event,
bool pressed);
virtual wxControlActions Map(wxControl *control,
const wxMouseEvent& event);
virtual bool OnMouseMove(wxControl *control, const wxMouseEvent& event);
private: private:
// set or clear the specified flag on the scrollbar element corresponding
// to m_htLast
void SetElementState(wxScrollBar *scrollbar, int flag, bool doIt);
// [un]highlight the scrollbar element corresponding to m_htLast
void Highlight(wxScrollBar *scrollbar, bool doIt)
{ SetElementState(scrollbar, wxCONTROL_CURRENT, doIt); }
// [un]press the scrollbar element corresponding to m_htLast
void Press(wxScrollBar *scrollbar, bool doIt)
{ SetElementState(scrollbar, wxCONTROL_PRESSED, doIt); }
wxWindow *m_winCapture; wxWindow *m_winCapture;
int m_btnCapture; // the mouse button which was captured mouse
bool m_winHasMouse; bool m_winHasMouse;
wxHitTest m_htLast;
}; };
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -190,7 +235,8 @@ public:
virtual wxRenderer *GetRenderer() { return m_renderer; } virtual wxRenderer *GetRenderer() { return m_renderer; }
virtual wxInputHandler *GetInputHandler(const wxString& control); virtual wxInputHandler *GetInputHandler(const wxString& control);
virtual wxColourScheme *GetColourScheme(const wxString& control) { return m_scheme; } virtual wxColourScheme *GetColourScheme(const wxString& control)
{ return m_scheme; }
private: private:
wxGTKRenderer *m_renderer; wxGTKRenderer *m_renderer;
@@ -235,17 +281,12 @@ wxInputHandler *wxGTKTheme::GetInputHandler(const wxString& control)
// create a new handler // create a new handler
n = m_handlerNames.Add(control); n = m_handlerNames.Add(control);
if ( control == wxCONTROL_BUTTON ) if ( control == wxButtonNameStr )
handler = new wxGTKButtonInputHandler; handler = new wxGTKButtonInputHandler(m_renderer);
else if ( control == wxCONTROL_SCROLLBAR ) else if ( control == wxScrollBarNameStr )
handler = new wxGTKScrollBarInputHandler; handler = new wxGTKScrollBarInputHandler(m_renderer);
else else
{ handler = new wxGTKInputHandler(m_renderer);
wxASSERT_MSG( control == wxCONTROL_DEFAULT,
_T("no input handler defined for this control") );
handler = new wxGTKInputHandler;
}
m_handlers.Insert(handler, n); m_handlers.Insert(handler, n);
} }
@@ -475,8 +516,7 @@ void wxGTKRenderer::DrawButtonBorder(wxDC& dc,
// now draw a normal button // now draw a normal button
DrawShadedRect(dc, &rect, m_penHighlight, m_penBlack); DrawShadedRect(dc, &rect, m_penHighlight, m_penBlack);
DrawAntiShadedRect(dc, &rect, DrawAntiShadedRect(dc, &rect,
flags & wxCONTROL_CURRENT ? m_penHighlight wxPen(GetBackgroundColour(flags), 0, wxSOLID),
: m_penLightGrey,
m_penDarkGrey); m_penDarkGrey);
} }
@@ -580,7 +620,7 @@ void wxGTKRenderer::DrawBackground(wxDC& dc,
const wxRect& rect, const wxRect& rect,
int flags) int flags)
{ {
DoDrawBackground(dc, m_scheme->Get(wxColourScheme::CONTROL, flags), rect); DoDrawBackground(dc, GetBackgroundColour(flags), rect);
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -604,6 +644,23 @@ void wxGTKRenderer::DrawArrow(wxDC& dc,
wxPoint ptArrow[Point_Max]; wxPoint ptArrow[Point_Max];
wxColour colInside = m_scheme->Get(wxColourScheme::CONTROL, flags);
wxPen penShadow[4];
if ( flags & wxCONTROL_PRESSED )
{
penShadow[0] = m_penDarkGrey;
penShadow[1] = m_penHighlight;
penShadow[2] = wxNullPen;
penShadow[3] = m_penBlack;
}
else // normal arrow
{
penShadow[0] = m_penHighlight;
penShadow[1] = m_penBlack;
penShadow[2] = m_penDarkGrey;
penShadow[3] = wxNullPen;
}
wxCoord middle; wxCoord middle;
if ( dir == wxUP || dir == wxDOWN ) if ( dir == wxUP || dir == wxDOWN )
{ {
@@ -617,7 +674,7 @@ void wxGTKRenderer::DrawArrow(wxDC& dc,
// draw the arrow interior // draw the arrow interior
dc.SetPen(*wxTRANSPARENT_PEN); dc.SetPen(*wxTRANSPARENT_PEN);
dc.SetBrush(wxBrush(m_scheme->Get(wxColourScheme::CONTROL), wxSOLID)); dc.SetBrush(wxBrush(colInside, wxSOLID));
switch ( dir ) switch ( dir )
{ {
@@ -663,33 +720,45 @@ void wxGTKRenderer::DrawArrow(wxDC& dc,
dc.DrawPolygon(WXSIZEOF(ptArrow), ptArrow); dc.DrawPolygon(WXSIZEOF(ptArrow), ptArrow);
// draw the arrow border // draw the arrow border
dc.SetPen(m_penHighlight); dc.SetPen(penShadow[0]);
switch ( dir ) switch ( dir )
{ {
case wxUP: case wxUP:
dc.DrawLine(ptArrow[Point_Second], ptArrow[Point_First]); dc.DrawLine(ptArrow[Point_Second], ptArrow[Point_First]);
dc.DrawPoint(ptArrow[Point_First]); dc.DrawPoint(ptArrow[Point_First]);
dc.SetPen(m_penBlack); if ( penShadow[3].Ok() )
{
dc.SetPen(penShadow[3]);
dc.DrawLine(ptArrow[Point_First].x + 1, ptArrow[Point_First].y,
ptArrow[Point_Second].x, ptArrow[Point_Second].y);
}
dc.SetPen(penShadow[1]);
dc.DrawLine(ptArrow[Point_Second].x + 1, ptArrow[Point_Second].y + 1, dc.DrawLine(ptArrow[Point_Second].x + 1, ptArrow[Point_Second].y + 1,
ptArrow[Point_Third].x, ptArrow[Point_Third].y); ptArrow[Point_Third].x, ptArrow[Point_Third].y);
dc.DrawPoint(ptArrow[Point_Third]); dc.DrawPoint(ptArrow[Point_Third]);
dc.DrawLine(ptArrow[Point_Third].x - 2, ptArrow[Point_Third].y, dc.DrawLine(ptArrow[Point_Third].x - 2, ptArrow[Point_Third].y,
ptArrow[Point_First].x + 1, ptArrow[Point_First].y); ptArrow[Point_First].x + 1, ptArrow[Point_First].y);
dc.SetPen(m_penDarkGrey); if ( penShadow[2].Ok() )
dc.DrawLine(ptArrow[Point_Third].x - 1, ptArrow[Point_Third].y, {
ptArrow[Point_Second].x, ptArrow[Point_Second].y + 1); dc.SetPen(penShadow[2]);
dc.DrawLine(ptArrow[Point_Third].x - 1, ptArrow[Point_Third].y - 1, dc.DrawLine(ptArrow[Point_Third].x - 1, ptArrow[Point_Third].y,
ptArrow[Point_First].x + 2, ptArrow[Point_First].y - 1); ptArrow[Point_Second].x, ptArrow[Point_Second].y + 1);
dc.DrawLine(ptArrow[Point_Third].x - 1, ptArrow[Point_Third].y - 1,
ptArrow[Point_First].x + 2, ptArrow[Point_First].y - 1);
}
break; break;
case wxDOWN: case wxDOWN:
dc.DrawLine(ptArrow[Point_First], ptArrow[Point_Second]); dc.DrawLine(ptArrow[Point_First], ptArrow[Point_Second]);
dc.DrawLine(ptArrow[Point_First].x + 2, ptArrow[Point_First].y, dc.DrawLine(ptArrow[Point_First].x + 2, ptArrow[Point_First].y,
ptArrow[Point_Third].x - 1, ptArrow[Point_Third].y); ptArrow[Point_Third].x - 1, ptArrow[Point_Third].y);
dc.SetPen(m_penDarkGrey); if ( penShadow[2].Ok() )
dc.DrawLine(ptArrow[Point_Second].x, ptArrow[Point_Second].y - 1, {
ptArrow[Point_Third].x - 1, ptArrow[Point_Third].y - 1); dc.SetPen(penShadow[2]);
dc.SetPen(m_penBlack); dc.DrawLine(ptArrow[Point_Second].x, ptArrow[Point_Second].y - 1,
ptArrow[Point_Third].x - 1, ptArrow[Point_Third].y - 1);
}
dc.SetPen(penShadow[1]);
dc.DrawLine(ptArrow[Point_Second], ptArrow[Point_Third]); dc.DrawLine(ptArrow[Point_Second], ptArrow[Point_Third]);
dc.DrawPoint(ptArrow[Point_Third]); dc.DrawPoint(ptArrow[Point_Third]);
break; break;
@@ -697,12 +766,15 @@ void wxGTKRenderer::DrawArrow(wxDC& dc,
case wxLEFT: case wxLEFT:
dc.DrawLine(ptArrow[Point_Second], ptArrow[Point_First]); dc.DrawLine(ptArrow[Point_Second], ptArrow[Point_First]);
dc.DrawPoint(ptArrow[Point_First]); dc.DrawPoint(ptArrow[Point_First]);
dc.SetPen(m_penDarkGrey); if ( penShadow[2].Ok() )
dc.DrawLine(ptArrow[Point_Third].x - 1, ptArrow[Point_Third].y, {
ptArrow[Point_First].x - 1, ptArrow[Point_First].y + 2); dc.SetPen(penShadow[2]);
dc.DrawLine(ptArrow[Point_Third].x, ptArrow[Point_Third].y, dc.DrawLine(ptArrow[Point_Third].x - 1, ptArrow[Point_Third].y,
ptArrow[Point_Second].x + 2, ptArrow[Point_Second].y + 1); ptArrow[Point_First].x - 1, ptArrow[Point_First].y + 2);
dc.SetPen(m_penBlack); dc.DrawLine(ptArrow[Point_Third].x, ptArrow[Point_Third].y,
ptArrow[Point_Second].x + 2, ptArrow[Point_Second].y + 1);
}
dc.SetPen(penShadow[1]);
dc.DrawLine(ptArrow[Point_Third].x, ptArrow[Point_Third].y, dc.DrawLine(ptArrow[Point_Third].x, ptArrow[Point_Third].y,
ptArrow[Point_First].x, ptArrow[Point_First].y + 1); ptArrow[Point_First].x, ptArrow[Point_First].y + 1);
dc.DrawLine(ptArrow[Point_Second].x + 1, ptArrow[Point_Second].y + 1, dc.DrawLine(ptArrow[Point_Second].x + 1, ptArrow[Point_Second].y + 1,
@@ -713,7 +785,7 @@ void wxGTKRenderer::DrawArrow(wxDC& dc,
dc.DrawLine(ptArrow[Point_First], ptArrow[Point_Third]); dc.DrawLine(ptArrow[Point_First], ptArrow[Point_Third]);
dc.DrawLine(ptArrow[Point_First].x + 2, ptArrow[Point_First].y + 1, dc.DrawLine(ptArrow[Point_First].x + 2, ptArrow[Point_First].y + 1,
ptArrow[Point_Second].x, ptArrow[Point_Second].y); ptArrow[Point_Second].x, ptArrow[Point_Second].y);
dc.SetPen(m_penBlack); dc.SetPen(penShadow[1]);
dc.DrawLine(ptArrow[Point_Second], ptArrow[Point_Third]); dc.DrawLine(ptArrow[Point_Second], ptArrow[Point_Third]);
dc.DrawPoint(ptArrow[Point_Third]); dc.DrawPoint(ptArrow[Point_Third]);
break; break;
@@ -729,25 +801,20 @@ void wxGTKRenderer::DrawScrollbar(wxDC& dc,
int thumbPosStart, int thumbPosStart,
int thumbPosEnd, int thumbPosEnd,
const wxRect& rect, const wxRect& rect,
int flags, const int *flags)
int extraFlags)
{ {
// handling of wxCONTROL_CURRENT flag is complicated for the scrollbar #ifdef DEBUG_MOUSE
// because, though it's only one window, either an arrow or a thumb may be wxLogDebug("Drawing the scrollbar (orientation = %s):\n"
// highlighted depending on where exactly the mouse is "\tarrow 1: 0x%04x\n"
int flagsArrows[2], flagsThumb; "\tarrow 2: 0x%04x\n"
flagsArrows[0] = "\tthumb: 0x%04x\n"
flagsArrows[1] = "\tthumb from %d to %d",
flagsThumb = flags & ~wxCONTROL_CURRENT; orient == wxVERTICAL ? "vertical" : "horizontal",
if ( flags & wxCONTROL_CURRENT ) flags[wxScrollBar::Element_Arrow_Line_1],
{ flags[wxScrollBar::Element_Arrow_Line_2],
if ( extraFlags & wxScrollBar::Highlight_Arrow1 ) flags[wxScrollBar::Element_Thumb],
flagsArrows[0] |= wxCONTROL_CURRENT; thumbPosStart, thumbPosEnd);
if ( extraFlags & wxScrollBar::Highlight_Arrow2 ) #endif // DEBUG_MOUSE
flagsArrows[1] |= wxCONTROL_CURRENT;
if ( extraFlags & wxScrollBar::Highlight_Thumb )
flagsThumb |= wxCONTROL_CURRENT;
}
// first draw the scrollbar area background // first draw the scrollbar area background
wxRect rectBar = rect; wxRect rectBar = rect;
@@ -782,7 +849,8 @@ void wxGTKRenderer::DrawScrollbar(wxDC& dc,
for ( size_t nArrow = 0; nArrow < 2; nArrow++ ) for ( size_t nArrow = 0; nArrow < 2; nArrow++ )
{ {
DrawArrow(dc, arrowDir[nArrow], rectArrow[nArrow], flags); DrawArrow(dc, arrowDir[nArrow], rectArrow[nArrow],
flags[wxScrollBar::Element_Arrow_Line_1 + nArrow]);
} }
// and, finally, the thumb, if any // and, finally, the thumb, if any
@@ -804,9 +872,71 @@ void wxGTKRenderer::DrawScrollbar(wxDC& dc,
rectThumb.width = (rectBar.width*(thumbPosEnd - thumbPosStart))/100; rectThumb.width = (rectBar.width*(thumbPosEnd - thumbPosStart))/100;
} }
// the thumb never has focus border under GTK // the thumb is never pressed never has focus border under GTK and the
DrawButtonBorder(dc, rectThumb, flags & ~wxCONTROL_FOCUSED, &rectThumb); // scrollbar background never changes at all
DrawBackground(dc, rectThumb, flags); int flagsThumb = flags[wxScrollBar::Element_Thumb] &
~(wxCONTROL_PRESSED | wxCONTROL_FOCUSED);
DrawButtonBorder(dc, rectThumb, flagsThumb, &rectThumb);
DrawBackground(dc, rectThumb, flagsThumb);
}
}
wxHitTest wxGTKRenderer::HitTestScrollbar(wxScrollBar *scrollbar,
const wxPoint& pt) const
{
// we only need to work with tiehr x or y coord depending on the
// orientation, choose one
wxCoord coord, sizeArrow, sizeTotal;
if ( scrollbar->GetWindowStyle() & wxVERTICAL )
{
coord = pt.y;
sizeArrow = m_sizeScrollbarArrow.y;
sizeTotal = scrollbar->GetSize().y;
}
else // horizontal
{
coord = pt.x;
sizeArrow = m_sizeScrollbarArrow.x;
sizeTotal = scrollbar->GetSize().x;
}
// test for the arrows first as it's faster
if ( coord < sizeArrow )
{
return wxHT_SCROLLBAR_ARROW_LINE_1;
}
else if ( coord > sizeTotal - sizeArrow )
{
return wxHT_SCROLLBAR_ARROW_LINE_2;
}
else
{
// calculate the thumb position in pixels
sizeTotal -= 2*sizeArrow;
wxCoord thumbStart, thumbEnd;
int range = scrollbar->GetRange();
if ( !range )
{
thumbStart =
thumbEnd = 0;
}
else
{
int posThumb = scrollbar->GetThumbPosition(),
sizeThumb = scrollbar->GetThumbSize();
thumbStart = (sizeTotal*posThumb) / range;
thumbEnd = (sizeTotal*(posThumb + sizeThumb)) / range;
}
// now compare with the thumb position
coord -= sizeArrow;
if ( coord < thumbStart )
return wxHT_SCROLLBAR_BAR_1;
else if ( coord > thumbEnd )
return wxHT_SCROLLBAR_BAR_2;
else
return wxHT_SCROLLBAR_THUMB;
} }
} }
@@ -874,31 +1004,62 @@ void wxGTKRenderer::AdjustSize(wxSize *size, const wxWindow *window)
// wxGTKInputHandler // wxGTKInputHandler
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
wxControlActions wxGTKInputHandler::Map(const wxKeyEvent& event, bool pressed) wxGTKInputHandler::wxGTKInputHandler(wxGTKRenderer *renderer)
{
m_renderer = renderer;
}
wxControlActions wxGTKInputHandler::Map(wxControl *control,
const wxKeyEvent& event,
bool pressed)
{ {
return wxACTION_NONE; return wxACTION_NONE;
} }
wxControlActions wxGTKInputHandler::Map(const wxMouseEvent& event) wxControlActions wxGTKInputHandler::Map(wxControl *control,
const wxMouseEvent& event)
{ {
if ( event.Entering() ) // clicking on the control gives it focus
return wxACTION_HIGHLIGHT; if ( event.ButtonDown() )
else if ( event.Leaving() ) {
return wxACTION_UNHIGHLIGHT; return wxACTION_FOCUS;
}
return wxACTION_NONE; return wxACTION_NONE;
} }
bool wxGTKInputHandler::OnMouseMove(wxControl *control,
const wxMouseEvent& event)
{
if ( event.Entering() )
{
control->SetCurrent(TRUE);
}
else if ( event.Leaving() )
{
control->SetCurrent(FALSE);
}
else
{
return FALSE;
}
// highlighting changed
return TRUE;
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxGTKButtonInputHandler // wxGTKButtonInputHandler
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
wxGTKButtonInputHandler::wxGTKButtonInputHandler() wxGTKButtonInputHandler::wxGTKButtonInputHandler(wxGTKRenderer *renderer)
: wxGTKInputHandler(renderer)
{ {
m_winCapture = NULL; m_winCapture = NULL;
} }
wxControlActions wxGTKButtonInputHandler::Map(const wxKeyEvent& event, wxControlActions wxGTKButtonInputHandler::Map(wxControl *control,
const wxKeyEvent& event,
bool pressed) bool pressed)
{ {
int keycode = event.GetKeyCode(); int keycode = event.GetKeyCode();
@@ -907,95 +1068,280 @@ wxControlActions wxGTKButtonInputHandler::Map(const wxKeyEvent& event,
return wxACTION_BUTTON_TOGGLE; return wxACTION_BUTTON_TOGGLE;
} }
return wxGTKInputHandler::Map(event, pressed); return wxGTKInputHandler::Map(control, event, pressed);
} }
wxControlActions wxGTKButtonInputHandler::Map(const wxMouseEvent& event) wxControlActions wxGTKButtonInputHandler::Map(wxControl *control,
const wxMouseEvent& event)
{ {
if ( event.IsButton() ) // 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() ) if ( event.ButtonDown(1) )
{ {
m_winCapture = wxWindow::FindFocus(); m_winCapture = control;
m_winCapture->CaptureMouse(); m_winCapture->CaptureMouse();
m_winHasMouse = TRUE; m_winHasMouse = TRUE;
return wxACTION_BUTTON_PRESS;
} }
else // up else // up
{ {
m_winCapture->ReleaseMouse(); m_winCapture->ReleaseMouse();
m_winCapture = NULL; m_winCapture = NULL;
if ( !m_winHasMouse ) if ( m_winHasMouse )
{ {
// the mouse was released outside the window, this doesn't // this will generate a click event
// count as a click return wxACTION_BUTTON_TOGGLE;
return wxGTKInputHandler::Map(event);
} }
//else: the mouse was released outside the window, this doesn't
// count as a click
} }
return wxACTION_BUTTON_TOGGLE;
} }
return wxGTKInputHandler::Map(control, event);
}
bool wxGTKButtonInputHandler::OnMouseMove(wxControl *control,
const wxMouseEvent& event)
{
// leaving the button should remove its pressed state // leaving the button should remove its pressed state
if ( event.Leaving() ) if ( event.Leaving() )
{ {
wxControlActions actions;
if ( m_winCapture ) if ( m_winCapture )
{ {
// we do have a pressed button // we do have a pressed button, so release it
actions.Add(wxACTION_BUTTON_RELEASE); control->PerformAction(wxACTION_BUTTON_RELEASE, event);
// remember that the mouse is now outside // remember that the mouse is now outside
m_winHasMouse = FALSE; m_winHasMouse = FALSE;
} }
actions.Add(wxGTKInputHandler::Map(event));
return actions;
} }
// and entering it back should make it pressed again if it had been
// entering it back should make it pressed again if it had been pressed // pressed
if ( event.Entering() ) else if ( event.Entering() )
{ {
wxControlActions actions;
if ( m_winCapture ) if ( m_winCapture )
{ {
// we do have a pressed button // we did have a pressed button which we released when leaving the
actions.Add(wxACTION_BUTTON_PRESS); // window, press it again
control->PerformAction(wxACTION_BUTTON_PRESS, event);
// and the mouse is (back) inside it // and the mouse is (back) inside it
m_winHasMouse = TRUE; m_winHasMouse = TRUE;
} }
actions.Add(wxGTKInputHandler::Map(event));
return actions;
} }
return wxGTKInputHandler::Map(event); return wxGTKInputHandler::OnMouseMove(control, event);
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxGTKScrollBarInputHandler // wxGTKScrollBarInputHandler
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
wxGTKScrollBarInputHandler::wxGTKScrollBarInputHandler() wxGTKScrollBarInputHandler::wxGTKScrollBarInputHandler(wxGTKRenderer *renderer)
: wxGTKInputHandler(renderer)
{ {
m_winCapture = NULL; m_winCapture = NULL;
m_htLast = wxHT_NOWHERE;
} }
wxControlActions wxGTKScrollBarInputHandler::Map(const wxKeyEvent& event, void wxGTKScrollBarInputHandler::SetElementState(wxScrollBar *control,
bool pressed) int flag,
bool doIt)
{ {
return wxGTKInputHandler::Map(event, pressed); wxScrollBar::Element elem;
} switch ( m_htLast )
wxControlActions wxGTKScrollBarInputHandler::Map(const wxMouseEvent& event)
{
if ( event.Moving() )
{ {
// determin which part of the window mouse is in case wxHT_SCROLLBAR_ARROW_LINE_1:
elem = wxScrollBar::Element_Arrow_Line_1;
break;
case wxHT_SCROLLBAR_ARROW_LINE_2:
elem = wxScrollBar::Element_Arrow_Line_2;
break;
case wxHT_SCROLLBAR_THUMB:
elem = wxScrollBar::Element_Thumb;
break;
/*
we don't highlight nor press the bar
case wxHT_SCROLLBAR_BAR_1:
case wxHT_SCROLLBAR_BAR_2:
*/
default:
elem = wxScrollBar::Element_Max;
} }
return wxGTKInputHandler::Map(event); if ( elem != wxScrollBar::Element_Max )
{
int flags = control->GetState(elem);
if ( doIt )
flags |= flag;
else
flags &= ~flag;
control->SetState(elem, flags);
}
}
wxControlActions wxGTKScrollBarInputHandler::Map(wxControl *control,
const wxKeyEvent& event,
bool pressed)
{
// weirdly enough, GTK+ scrollbars don't have keyboard support - maybe we
// should still have it though (TODO)?
return wxGTKInputHandler::Map(control, event, pressed);
}
wxControlActions wxGTKScrollBarInputHandler::Map(wxControl *control,
const wxMouseEvent& event)
{
if ( event.IsButton() )
{
// 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() )
{
if ( !m_winCapture )
{
m_btnCapture = -1;
for ( int i = 1; i <= 3; i++ )
{
if ( event.ButtonDown(i) )
{
m_btnCapture = i;
break;
}
}
wxASSERT_MSG( m_btnCapture != -1, _T("unknown mouse button") );
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;
break;
case wxHT_SCROLLBAR_BAR_2:
action = wxACTION_SCROLL_PAGE_DOWN;
break;
default:
hasAction = FALSE;
}
if ( hasAction )
{
control->PerformAction(action, event);
}
// remove highlighting and press the arrow instead
Highlight(scrollbar, FALSE);
m_htLast = ht;
Press(scrollbar, TRUE);
}
//else: mouse already captured, nothing to do
}
// release mouse if the *same* button went up
else if ( event.ButtonUp(m_btnCapture) )
{
if ( m_winCapture )
{
m_winCapture->ReleaseMouse();
m_winCapture = NULL;
// unpress the arrow and highlight the current element
Press(scrollbar, TRUE);
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 wxGTKInputHandler::Map(control, event);
}
bool wxGTKScrollBarInputHandler::OnMouseMove(wxControl *control,
const wxMouseEvent& event)
{
if ( m_winCapture )
{
// everything is locked while the mouse is captured, so don't do
// anything
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;
}
// highlighting changed
return TRUE;
} }

View File

@@ -101,10 +101,13 @@ public:
int thumbPosStart, int thumbPosStart,
int thumbPosEnd, int thumbPosEnd,
const wxRect& rect, const wxRect& rect,
int flags = 0); const int *flags = NULL);
virtual void AdjustSize(wxSize *size, const wxWindow *window); virtual void AdjustSize(wxSize *size, const wxWindow *window);
virtual wxHitTest HitTestScrollbar(wxScrollBar *scrollbar,
const wxPoint& pt) const;
protected: protected:
// DrawButtonBorder() helper // DrawButtonBorder() helper
void DoDrawBackground(wxDC& dc, void DoDrawBackground(wxDC& dc,
@@ -167,8 +170,11 @@ private:
class wxWin32InputHandler : public wxInputHandler class wxWin32InputHandler : public wxInputHandler
{ {
public: public:
virtual wxControlActions Map(const wxKeyEvent& event, bool pressed); virtual wxControlActions Map(wxControl *control,
virtual wxControlActions Map(const wxMouseEvent& event); const wxKeyEvent& event,
bool pressed);
virtual wxControlActions Map(wxControl *control,
const wxMouseEvent& event);
}; };
class wxWin32ButtonInputHandler : public wxWin32InputHandler class wxWin32ButtonInputHandler : public wxWin32InputHandler
@@ -176,8 +182,11 @@ class wxWin32ButtonInputHandler : public wxWin32InputHandler
public: public:
wxWin32ButtonInputHandler(); wxWin32ButtonInputHandler();
virtual wxControlActions Map(const wxKeyEvent& event, bool pressed); virtual wxControlActions Map(wxControl *control,
virtual wxControlActions Map(const wxMouseEvent& event); const wxKeyEvent& event,
bool pressed);
virtual wxControlActions Map(wxControl *control,
const wxMouseEvent& event);
private: private:
wxWindow *m_winCapture; wxWindow *m_winCapture;
@@ -255,17 +264,12 @@ wxInputHandler *wxWin32Theme::GetInputHandler(const wxString& control)
// create a new handler // create a new handler
n = m_handlerNames.Add(control); n = m_handlerNames.Add(control);
if ( control == wxCONTROL_BUTTON ) if ( control == wxButtonNameStr )
handler = new wxWin32ButtonInputHandler; handler = new wxWin32ButtonInputHandler;
else if ( control == wxCONTROL_SCROLLBAR ) else if ( control == wxScrollBarNameStr )
handler = new wxWin32InputHandler; // TODO handler = new wxWin32InputHandler; // TODO
else else
{
wxASSERT_MSG( control == wxCONTROL_DEFAULT,
_T("no input handler defined for this control") );
handler = new wxWin32InputHandler; handler = new wxWin32InputHandler;
}
m_handlers.Insert(handler, n); m_handlers.Insert(handler, n);
} }
@@ -893,10 +897,11 @@ void wxWin32Renderer::DrawScrollbar(wxDC& dc,
int thumbPosStart, int thumbPosStart,
int thumbPosEnd, int thumbPosEnd,
const wxRect& rect, const wxRect& rect,
int flags) const int *flags)
{ {
wxArrowStyle arrowStyle = flags & wxCONTROL_DISABLED ? Arrow_Disabled int flagsSb = flags ? flags[0] : 0;
: Arrow_Normal; wxArrowStyle arrowStyle = flagsSb & wxCONTROL_DISABLED ? Arrow_Disabled
: Arrow_Normal;
// first, draw the arrows at the ends // first, draw the arrows at the ends
wxRect rectArrow[2]; wxRect rectArrow[2];
@@ -957,6 +962,12 @@ void wxWin32Renderer::DrawScrollbar(wxDC& dc,
} }
} }
wxHitTest wxWin32Renderer::HitTestScrollbar(wxScrollBar *scrollbar,
const wxPoint& pt) const
{
return wxHT_NOWHERE;
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// size adjustments // size adjustments
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -1020,12 +1031,15 @@ void wxWin32Renderer::AdjustSize(wxSize *size, const wxWindow *window)
// wxWin32InputHandler // wxWin32InputHandler
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
wxControlActions wxWin32InputHandler::Map(const wxKeyEvent& event, bool pressed) wxControlActions wxWin32InputHandler::Map(wxControl *control,
const wxKeyEvent& event,
bool pressed)
{ {
return wxACTION_NONE; return wxACTION_NONE;
} }
wxControlActions wxWin32InputHandler::Map(const wxMouseEvent& event) wxControlActions wxWin32InputHandler::Map(wxControl *control,
const wxMouseEvent& event)
{ {
return wxACTION_NONE; return wxACTION_NONE;
} }
@@ -1039,7 +1053,8 @@ wxWin32ButtonInputHandler::wxWin32ButtonInputHandler()
m_winCapture = NULL; m_winCapture = NULL;
} }
wxControlActions wxWin32ButtonInputHandler::Map(const wxKeyEvent& event, wxControlActions wxWin32ButtonInputHandler::Map(wxControl *control,
const wxKeyEvent& event,
bool pressed) bool pressed)
{ {
int keycode = event.GetKeyCode(); int keycode = event.GetKeyCode();
@@ -1048,10 +1063,11 @@ wxControlActions wxWin32ButtonInputHandler::Map(const wxKeyEvent& event,
return wxACTION_BUTTON_TOGGLE; return wxACTION_BUTTON_TOGGLE;
} }
return wxWin32InputHandler::Map(event, pressed); return wxWin32InputHandler::Map(control, event, pressed);
} }
wxControlActions wxWin32ButtonInputHandler::Map(const wxMouseEvent& event) wxControlActions wxWin32ButtonInputHandler::Map(wxControl *control,
const wxMouseEvent& event)
{ {
if ( event.IsButton() ) if ( event.IsButton() )
{ {
@@ -1068,5 +1084,5 @@ wxControlActions wxWin32ButtonInputHandler::Map(const wxMouseEvent& event)
return wxACTION_BUTTON_TOGGLE; return wxACTION_BUTTON_TOGGLE;
} }
return wxWin32InputHandler::Map(event); return wxWin32InputHandler::Map(control, event);
} }