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:
@@ -2016,7 +2016,7 @@ if test "$wxUSE_GUI" = "yes"; then
|
||||
fi
|
||||
|
||||
if test "$wxUSE_UNIVERSAL" = "yes"; then
|
||||
ALL_DEPFILES="\$(GUI_LOWLEVEL_DEPS)"
|
||||
ALL_DEPFILES="\$(GUI_LOWLEVEL_DEPS) \$(UNIVDEPS)"
|
||||
else
|
||||
ALL_DEPFILES="\$(GUIDEPS)"
|
||||
fi
|
||||
|
@@ -31,9 +31,6 @@ class WXDLLEXPORT wxInputHandler;
|
||||
// wxButton: a push button
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// class name
|
||||
#define wxCONTROL_BUTTON _T("button")
|
||||
|
||||
class WXDLLEXPORT wxButton : public wxButtonBase
|
||||
{
|
||||
public:
|
||||
@@ -75,7 +72,6 @@ public:
|
||||
void Click();
|
||||
|
||||
protected:
|
||||
virtual wxInputHandler *CreateInputHandler() const;
|
||||
virtual bool PerformAction(const wxControlAction& action,
|
||||
const wxEvent& event);
|
||||
virtual wxSize DoGetBestSize() const;
|
||||
|
@@ -70,16 +70,12 @@ public:
|
||||
// in the controls headers)
|
||||
|
||||
#define wxACTION_NONE _T("") // no action to perform
|
||||
#define wxACTION_HIGHLIGHT _T("focus") // highlight the control
|
||||
#define wxACTION_UNHIGHLIGHT _T("unfocus") // remove highlight
|
||||
#define wxACTION_FOCUS _T("focus") // make control focused
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxControl: the base class for all GUI controls
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// class name
|
||||
#define wxCONTROL_DEFAULT _T("")
|
||||
|
||||
class WXDLLEXPORT wxControl : public wxControlBase
|
||||
{
|
||||
public:
|
||||
@@ -140,6 +136,12 @@ public:
|
||||
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:
|
||||
// create the event translator object for this control: the base class
|
||||
// action creates the default one which doesn't do anything
|
||||
@@ -151,12 +153,6 @@ protected:
|
||||
// draw the controls contents
|
||||
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
|
||||
void OnMouse(wxMouseEvent& event);
|
||||
void OnKeyDown(wxKeyEvent& event);
|
||||
|
@@ -28,10 +28,23 @@ class WXDLLEXPORT wxInputHandler
|
||||
public:
|
||||
// map a keyboard event to one or more actions (pressed == TRUE if the key
|
||||
// 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
|
||||
virtual wxControlActions Map(const wxMouseEvent& event) = 0;
|
||||
// map a mouse (click) event to one or more actions
|
||||
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 ~wxInputHandler();
|
||||
|
@@ -24,11 +24,33 @@
|
||||
|
||||
class WXDLLEXPORT wxControl;
|
||||
class WXDLLEXPORT wxDC;
|
||||
class WXDLLEXPORT wxScrollBar;
|
||||
class WXDLLEXPORT wxWindow;
|
||||
|
||||
#include "wx/string.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
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -36,6 +58,9 @@ class WXDLLEXPORT wxWindow;
|
||||
class WXDLLEXPORT wxRenderer
|
||||
{
|
||||
public:
|
||||
// drawing functions
|
||||
// -----------------
|
||||
|
||||
// draw the controls background
|
||||
virtual void DrawBackground(wxDC& dc,
|
||||
const wxRect& rect,
|
||||
@@ -79,14 +104,14 @@ public:
|
||||
int flags = 0) = 0;
|
||||
|
||||
// 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,
|
||||
wxOrientation orient,
|
||||
int thumbPosStart,
|
||||
int thumbPosEnd,
|
||||
const wxRect& rect,
|
||||
int flags = 0,
|
||||
int extraFlags = 0) = 0;
|
||||
const int *flags = NULL) = 0;
|
||||
|
||||
// TODO: having this is ugly but I don't see how to solve GetBestSize()
|
||||
// problem without something like this
|
||||
@@ -97,6 +122,13 @@ public:
|
||||
// the control looks "nice" if it uses the adjusted rectangle
|
||||
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 ~wxRenderer();
|
||||
};
|
||||
@@ -152,14 +184,17 @@ public:
|
||||
int thumbPosStart,
|
||||
int thumbPosEnd,
|
||||
const wxRect& rect,
|
||||
int flags = 0,
|
||||
int extraFlags = 0)
|
||||
const int *flags = NULL)
|
||||
{ m_renderer->DrawScrollbar(dc, orient, thumbPosStart,
|
||||
thumbPosEnd, rect, flags, extraFlags); }
|
||||
thumbPosEnd, rect, flags); }
|
||||
|
||||
virtual void AdjustSize(wxSize *size, const wxWindow *window)
|
||||
{ m_renderer->AdjustSize(size, window); }
|
||||
|
||||
virtual wxHitTest HitTestScrollbar(wxScrollBar *scrollbar,
|
||||
const wxPoint& pt) const
|
||||
{ return m_renderer->HitTestScrollbar(scrollbar, pt); }
|
||||
|
||||
protected:
|
||||
wxRenderer *m_renderer;
|
||||
};
|
||||
@@ -181,7 +216,7 @@ public:
|
||||
void DrawButtonBorder();
|
||||
void DrawFrame();
|
||||
void DrawBackgroundBitmap();
|
||||
void DrawScrollbar(int thumbStart, int thumbEnd, int extraFlags = 0);
|
||||
void DrawScrollbar(wxScrollBar *scrollbar);
|
||||
|
||||
// accessors
|
||||
wxRenderer *GetRenderer() const { return m_renderer; }
|
||||
|
@@ -22,12 +22,6 @@ class WXDLLEXPORT wxInputHandler;
|
||||
// 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
|
||||
#define wxACTION_SCROLL_START _T("start") // to the beginning
|
||||
#define wxACTION_SCROLL_END _T("end") // to the end
|
||||
@@ -45,19 +39,19 @@ class WXDLLEXPORT wxInputHandler;
|
||||
// wxScrollBar
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// class name
|
||||
#define wxCONTROL_SCROLLBAR _T("scrollbar")
|
||||
|
||||
class WXDLLEXPORT wxScrollBar : public wxScrollBarBase
|
||||
{
|
||||
public:
|
||||
enum
|
||||
// the parts of the scrollbar
|
||||
enum Element
|
||||
{
|
||||
// which part of scrollbar is currently highlighted?
|
||||
Highlight_Arrow1 = 0x0001,
|
||||
Highlight_Arrow2 = 0x0002,
|
||||
Highlight_Thumb = 0x0004,
|
||||
Highlight_Bar = 0x0008
|
||||
Element_Arrow_Line_1,
|
||||
Element_Arrow_Line_2,
|
||||
Element_Arrow_Page_1,
|
||||
Element_Arrow_Page_2,
|
||||
Element_Thumb,
|
||||
Element_Bar,
|
||||
Element_Max
|
||||
};
|
||||
|
||||
wxScrollBar() { Init(); }
|
||||
@@ -84,26 +78,39 @@ public:
|
||||
|
||||
virtual ~wxScrollBar();
|
||||
|
||||
// implementate base class pure virtuals
|
||||
// implement base class pure virtuals
|
||||
virtual int GetThumbPosition() const;
|
||||
virtual int GetThumbSize() const;
|
||||
virtual int GetPageSize() const;
|
||||
virtual int GetRange() const;
|
||||
|
||||
virtual void SetThumbPosition(int viewStart);
|
||||
virtual void SetThumbPosition(int thumbPos);
|
||||
virtual void SetScrollbar(int position, int thumbSize,
|
||||
int range, int pageSize,
|
||||
bool refresh = TRUE);
|
||||
|
||||
// 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,
|
||||
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 void DoDraw(wxControlRenderer *renderer);
|
||||
|
||||
// SetThumbPosition() helper
|
||||
void DoSetThumb(int thumbPos);
|
||||
|
||||
// common part of all ctors
|
||||
void Init();
|
||||
|
||||
@@ -120,6 +127,9 @@ private:
|
||||
// up/down action is performed
|
||||
int m_pageSize;
|
||||
|
||||
// the state of the sub elements
|
||||
int m_elementsState[Element_Max];
|
||||
|
||||
DECLARE_DYNAMIC_CLASS(wxScrollBar)
|
||||
};
|
||||
|
||||
|
@@ -118,11 +118,6 @@ void wxButton::DoDraw(wxControlRenderer *renderer)
|
||||
// input processing
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
wxInputHandler *wxButton::CreateInputHandler() const
|
||||
{
|
||||
return wxTheme::Get()->GetInputHandler(wxCONTROL_BUTTON);
|
||||
}
|
||||
|
||||
void wxButton::Press()
|
||||
{
|
||||
m_isPressed = TRUE;
|
||||
|
@@ -271,22 +271,32 @@ void wxControl::OnFocus(wxFocusEvent& event)
|
||||
|
||||
wxInputHandler *wxControl::CreateInputHandler() const
|
||||
{
|
||||
return wxTheme::Get()->GetInputHandler(wxCONTROL_DEFAULT);
|
||||
return wxTheme::Get()->GetInputHandler(GetName());
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
PerformActions(m_handler->Map(event, FALSE), event);
|
||||
PerformActions(m_handler->Map(this, event, FALSE), 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,
|
||||
const wxEvent& event)
|
||||
{
|
||||
if ( (action == wxACTION_NONE) || !AcceptsFocus() )
|
||||
return FALSE;
|
||||
|
||||
if ( action == wxACTION_HIGHLIGHT )
|
||||
SetCurrent(TRUE);
|
||||
else if ( action == wxACTION_UNHIGHLIGHT )
|
||||
SetCurrent(FALSE);
|
||||
else
|
||||
return FALSE;
|
||||
if ( (action == wxACTION_FOCUS) && AcceptsFocus() )
|
||||
{
|
||||
SetFocus();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#endif // wxUSE_CONTROLS
|
||||
|
@@ -11,4 +11,15 @@ UNIVOBJS = \
|
||||
gtk.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
|
||||
|
@@ -37,6 +37,12 @@
|
||||
// implementation
|
||||
// ============================================================================
|
||||
|
||||
bool wxInputHandler::OnMouseMove(wxControl * WXUNUSED(control),
|
||||
const wxMouseEvent& WXUNUSED(event))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
wxInputHandler::~wxInputHandler()
|
||||
{
|
||||
}
|
||||
|
@@ -31,6 +31,7 @@
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/app.h"
|
||||
#include "wx/control.h"
|
||||
#include "wx/scrolbar.h"
|
||||
#include "wx/dc.h"
|
||||
#endif // WX_PRECOMP
|
||||
|
||||
@@ -176,12 +177,34 @@ void wxControlRenderer::DrawBackgroundBitmap()
|
||||
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_ctrl->GetWindowStyle() & wxVERTICAL
|
||||
? wxVERTICAL
|
||||
: wxHORIZONTAL,
|
||||
thumbStart, thumbEnd, m_rect,
|
||||
m_ctrl->GetStateFlags());
|
||||
flags);
|
||||
}
|
||||
|
@@ -55,6 +55,11 @@ void wxScrollBar::Init()
|
||||
m_thumbSize =
|
||||
m_thumbPos =
|
||||
m_pageSize = 0;
|
||||
|
||||
for ( size_t n = 0; n < Element_Max; n++ )
|
||||
{
|
||||
m_elementsState[n] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool wxScrollBar::Create(wxWindow *parent,
|
||||
@@ -90,6 +95,21 @@ wxScrollBar::~wxScrollBar()
|
||||
// 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
|
||||
{
|
||||
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") );
|
||||
|
||||
if ( pos >= m_range - m_thumbSize )
|
||||
{
|
||||
pos = m_range - m_thumbSize;
|
||||
}
|
||||
DoSetThumb(pos);
|
||||
|
||||
m_thumbPos = pos;
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void wxScrollBar::SetScrollbar(int position, int thumbSize,
|
||||
@@ -156,34 +173,53 @@ wxSize wxScrollBar::DoGetBestSize() const
|
||||
|
||||
void wxScrollBar::DoDraw(wxControlRenderer *renderer)
|
||||
{
|
||||
int thumbStart, thumbEnd;
|
||||
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);
|
||||
renderer->DrawScrollbar(this);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// input processing
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
wxInputHandler *wxScrollBar::CreateInputHandler() const
|
||||
{
|
||||
return wxTheme::Get()->GetInputHandler(wxCONTROL_SCROLLBAR);
|
||||
}
|
||||
|
||||
bool wxScrollBar::PerformAction(const wxControlAction& action,
|
||||
const wxEvent& 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
|
||||
|
@@ -26,6 +26,7 @@
|
||||
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/intl.h"
|
||||
#include "wx/log.h"
|
||||
#include "wx/dc.h"
|
||||
#include "wx/window.h"
|
||||
|
||||
@@ -38,6 +39,9 @@
|
||||
#include "wx/univ/colschem.h"
|
||||
#include "wx/univ/theme.h"
|
||||
|
||||
// define this for tons of debugging messages
|
||||
#undef DEBUG_MOUSE
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxGTKRenderer: draw the GUI elements in GTK style
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -81,13 +85,22 @@ public:
|
||||
int thumbPosStart,
|
||||
int thumbPosEnd,
|
||||
const wxRect& rect,
|
||||
int flags = 0,
|
||||
int extraFlags = 0);
|
||||
const int *flags = NULL);
|
||||
|
||||
virtual void AdjustSize(wxSize *size, const wxWindow *window);
|
||||
|
||||
// hit testing for the input handlers
|
||||
virtual wxHitTest HitTestScrollbar(wxScrollBar *scrollbar,
|
||||
const wxPoint& pt) const;
|
||||
|
||||
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,
|
||||
const wxColour& col,
|
||||
const wxRect& rect);
|
||||
@@ -136,17 +149,30 @@ private:
|
||||
class wxGTKInputHandler : public wxInputHandler
|
||||
{
|
||||
public:
|
||||
virtual wxControlActions Map(const wxKeyEvent& event, bool pressed);
|
||||
virtual wxControlActions Map(const wxMouseEvent& event);
|
||||
wxGTKInputHandler(wxGTKRenderer *renderer);
|
||||
|
||||
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
|
||||
{
|
||||
public:
|
||||
wxGTKButtonInputHandler();
|
||||
wxGTKButtonInputHandler(wxGTKRenderer *renderer);
|
||||
|
||||
virtual wxControlActions Map(const wxKeyEvent& event, bool pressed);
|
||||
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);
|
||||
|
||||
private:
|
||||
wxWindow *m_winCapture;
|
||||
@@ -156,14 +182,33 @@ private:
|
||||
class wxGTKScrollBarInputHandler : public wxGTKInputHandler
|
||||
{
|
||||
public:
|
||||
wxGTKScrollBarInputHandler();
|
||||
wxGTKScrollBarInputHandler(wxGTKRenderer *renderer);
|
||||
|
||||
virtual wxControlActions Map(const wxKeyEvent& event, bool pressed);
|
||||
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);
|
||||
|
||||
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;
|
||||
int m_btnCapture; // the mouse button which was captured mouse
|
||||
bool m_winHasMouse;
|
||||
|
||||
wxHitTest m_htLast;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -190,7 +235,8 @@ public:
|
||||
|
||||
virtual wxRenderer *GetRenderer() { return m_renderer; }
|
||||
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:
|
||||
wxGTKRenderer *m_renderer;
|
||||
@@ -235,17 +281,12 @@ wxInputHandler *wxGTKTheme::GetInputHandler(const wxString& control)
|
||||
// create a new handler
|
||||
n = m_handlerNames.Add(control);
|
||||
|
||||
if ( control == wxCONTROL_BUTTON )
|
||||
handler = new wxGTKButtonInputHandler;
|
||||
else if ( control == wxCONTROL_SCROLLBAR )
|
||||
handler = new wxGTKScrollBarInputHandler;
|
||||
if ( control == wxButtonNameStr )
|
||||
handler = new wxGTKButtonInputHandler(m_renderer);
|
||||
else if ( control == wxScrollBarNameStr )
|
||||
handler = new wxGTKScrollBarInputHandler(m_renderer);
|
||||
else
|
||||
{
|
||||
wxASSERT_MSG( control == wxCONTROL_DEFAULT,
|
||||
_T("no input handler defined for this control") );
|
||||
|
||||
handler = new wxGTKInputHandler;
|
||||
}
|
||||
handler = new wxGTKInputHandler(m_renderer);
|
||||
|
||||
m_handlers.Insert(handler, n);
|
||||
}
|
||||
@@ -475,8 +516,7 @@ void wxGTKRenderer::DrawButtonBorder(wxDC& dc,
|
||||
// now draw a normal button
|
||||
DrawShadedRect(dc, &rect, m_penHighlight, m_penBlack);
|
||||
DrawAntiShadedRect(dc, &rect,
|
||||
flags & wxCONTROL_CURRENT ? m_penHighlight
|
||||
: m_penLightGrey,
|
||||
wxPen(GetBackgroundColour(flags), 0, wxSOLID),
|
||||
m_penDarkGrey);
|
||||
}
|
||||
|
||||
@@ -580,7 +620,7 @@ void wxGTKRenderer::DrawBackground(wxDC& dc,
|
||||
const wxRect& rect,
|
||||
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];
|
||||
|
||||
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;
|
||||
if ( dir == wxUP || dir == wxDOWN )
|
||||
{
|
||||
@@ -617,7 +674,7 @@ void wxGTKRenderer::DrawArrow(wxDC& dc,
|
||||
|
||||
// draw the arrow interior
|
||||
dc.SetPen(*wxTRANSPARENT_PEN);
|
||||
dc.SetBrush(wxBrush(m_scheme->Get(wxColourScheme::CONTROL), wxSOLID));
|
||||
dc.SetBrush(wxBrush(colInside, wxSOLID));
|
||||
|
||||
switch ( dir )
|
||||
{
|
||||
@@ -663,33 +720,45 @@ void wxGTKRenderer::DrawArrow(wxDC& dc,
|
||||
dc.DrawPolygon(WXSIZEOF(ptArrow), ptArrow);
|
||||
|
||||
// draw the arrow border
|
||||
dc.SetPen(m_penHighlight);
|
||||
dc.SetPen(penShadow[0]);
|
||||
switch ( dir )
|
||||
{
|
||||
case wxUP:
|
||||
dc.DrawLine(ptArrow[Point_Second], 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,
|
||||
ptArrow[Point_Third].x, ptArrow[Point_Third].y);
|
||||
dc.DrawPoint(ptArrow[Point_Third]);
|
||||
dc.DrawLine(ptArrow[Point_Third].x - 2, ptArrow[Point_Third].y,
|
||||
ptArrow[Point_First].x + 1, ptArrow[Point_First].y);
|
||||
dc.SetPen(m_penDarkGrey);
|
||||
if ( penShadow[2].Ok() )
|
||||
{
|
||||
dc.SetPen(penShadow[2]);
|
||||
dc.DrawLine(ptArrow[Point_Third].x - 1, ptArrow[Point_Third].y,
|
||||
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;
|
||||
|
||||
case wxDOWN:
|
||||
dc.DrawLine(ptArrow[Point_First], ptArrow[Point_Second]);
|
||||
dc.DrawLine(ptArrow[Point_First].x + 2, ptArrow[Point_First].y,
|
||||
ptArrow[Point_Third].x - 1, ptArrow[Point_Third].y);
|
||||
dc.SetPen(m_penDarkGrey);
|
||||
if ( penShadow[2].Ok() )
|
||||
{
|
||||
dc.SetPen(penShadow[2]);
|
||||
dc.DrawLine(ptArrow[Point_Second].x, ptArrow[Point_Second].y - 1,
|
||||
ptArrow[Point_Third].x - 1, ptArrow[Point_Third].y - 1);
|
||||
dc.SetPen(m_penBlack);
|
||||
}
|
||||
dc.SetPen(penShadow[1]);
|
||||
dc.DrawLine(ptArrow[Point_Second], ptArrow[Point_Third]);
|
||||
dc.DrawPoint(ptArrow[Point_Third]);
|
||||
break;
|
||||
@@ -697,12 +766,15 @@ void wxGTKRenderer::DrawArrow(wxDC& dc,
|
||||
case wxLEFT:
|
||||
dc.DrawLine(ptArrow[Point_Second], ptArrow[Point_First]);
|
||||
dc.DrawPoint(ptArrow[Point_First]);
|
||||
dc.SetPen(m_penDarkGrey);
|
||||
if ( penShadow[2].Ok() )
|
||||
{
|
||||
dc.SetPen(penShadow[2]);
|
||||
dc.DrawLine(ptArrow[Point_Third].x - 1, ptArrow[Point_Third].y,
|
||||
ptArrow[Point_First].x - 1, ptArrow[Point_First].y + 2);
|
||||
dc.DrawLine(ptArrow[Point_Third].x, ptArrow[Point_Third].y,
|
||||
ptArrow[Point_Second].x + 2, ptArrow[Point_Second].y + 1);
|
||||
dc.SetPen(m_penBlack);
|
||||
}
|
||||
dc.SetPen(penShadow[1]);
|
||||
dc.DrawLine(ptArrow[Point_Third].x, ptArrow[Point_Third].y,
|
||||
ptArrow[Point_First].x, ptArrow[Point_First].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].x + 2, ptArrow[Point_First].y + 1,
|
||||
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.DrawPoint(ptArrow[Point_Third]);
|
||||
break;
|
||||
@@ -729,25 +801,20 @@ void wxGTKRenderer::DrawScrollbar(wxDC& dc,
|
||||
int thumbPosStart,
|
||||
int thumbPosEnd,
|
||||
const wxRect& rect,
|
||||
int flags,
|
||||
int extraFlags)
|
||||
const int *flags)
|
||||
{
|
||||
// handling of wxCONTROL_CURRENT flag is complicated for the scrollbar
|
||||
// because, though it's only one window, either an arrow or a thumb may be
|
||||
// highlighted depending on where exactly the mouse is
|
||||
int flagsArrows[2], flagsThumb;
|
||||
flagsArrows[0] =
|
||||
flagsArrows[1] =
|
||||
flagsThumb = flags & ~wxCONTROL_CURRENT;
|
||||
if ( flags & wxCONTROL_CURRENT )
|
||||
{
|
||||
if ( extraFlags & wxScrollBar::Highlight_Arrow1 )
|
||||
flagsArrows[0] |= wxCONTROL_CURRENT;
|
||||
if ( extraFlags & wxScrollBar::Highlight_Arrow2 )
|
||||
flagsArrows[1] |= wxCONTROL_CURRENT;
|
||||
if ( extraFlags & wxScrollBar::Highlight_Thumb )
|
||||
flagsThumb |= wxCONTROL_CURRENT;
|
||||
}
|
||||
#ifdef DEBUG_MOUSE
|
||||
wxLogDebug("Drawing the scrollbar (orientation = %s):\n"
|
||||
"\tarrow 1: 0x%04x\n"
|
||||
"\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 rectBar = rect;
|
||||
@@ -782,7 +849,8 @@ void wxGTKRenderer::DrawScrollbar(wxDC& dc,
|
||||
|
||||
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
|
||||
@@ -804,9 +872,71 @@ void wxGTKRenderer::DrawScrollbar(wxDC& dc,
|
||||
rectThumb.width = (rectBar.width*(thumbPosEnd - thumbPosStart))/100;
|
||||
}
|
||||
|
||||
// the thumb never has focus border under GTK
|
||||
DrawButtonBorder(dc, rectThumb, flags & ~wxCONTROL_FOCUSED, &rectThumb);
|
||||
DrawBackground(dc, rectThumb, flags);
|
||||
// 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(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
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
wxControlActions wxGTKInputHandler::Map(const wxMouseEvent& event)
|
||||
wxControlActions wxGTKInputHandler::Map(wxControl *control,
|
||||
const wxMouseEvent& event)
|
||||
{
|
||||
if ( event.Entering() )
|
||||
return wxACTION_HIGHLIGHT;
|
||||
else if ( event.Leaving() )
|
||||
return wxACTION_UNHIGHLIGHT;
|
||||
// clicking on the control gives it focus
|
||||
if ( event.ButtonDown() )
|
||||
{
|
||||
return wxACTION_FOCUS;
|
||||
}
|
||||
|
||||
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(wxGTKRenderer *renderer)
|
||||
: wxGTKInputHandler(renderer)
|
||||
{
|
||||
m_winCapture = NULL;
|
||||
}
|
||||
|
||||
wxControlActions wxGTKButtonInputHandler::Map(const wxKeyEvent& event,
|
||||
wxControlActions wxGTKButtonInputHandler::Map(wxControl *control,
|
||||
const wxKeyEvent& event,
|
||||
bool pressed)
|
||||
{
|
||||
int keycode = event.GetKeyCode();
|
||||
@@ -907,95 +1068,280 @@ wxControlActions wxGTKButtonInputHandler::Map(const wxKeyEvent& event,
|
||||
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_winHasMouse = TRUE;
|
||||
|
||||
return wxACTION_BUTTON_PRESS;
|
||||
}
|
||||
else // up
|
||||
{
|
||||
m_winCapture->ReleaseMouse();
|
||||
m_winCapture = NULL;
|
||||
|
||||
if ( !m_winHasMouse )
|
||||
if ( m_winHasMouse )
|
||||
{
|
||||
// the mouse was released outside the window, this doesn't
|
||||
// count as a click
|
||||
return wxGTKInputHandler::Map(event);
|
||||
}
|
||||
}
|
||||
|
||||
// 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 wxGTKInputHandler::Map(control, event);
|
||||
}
|
||||
|
||||
bool wxGTKButtonInputHandler::OnMouseMove(wxControl *control,
|
||||
const wxMouseEvent& event)
|
||||
{
|
||||
// leaving the button should remove its pressed state
|
||||
if ( event.Leaving() )
|
||||
{
|
||||
wxControlActions actions;
|
||||
if ( m_winCapture )
|
||||
{
|
||||
// we do have a pressed button
|
||||
actions.Add(wxACTION_BUTTON_RELEASE);
|
||||
// we do have a pressed button, so release it
|
||||
control->PerformAction(wxACTION_BUTTON_RELEASE, event);
|
||||
|
||||
// remember that the mouse is now outside
|
||||
m_winHasMouse = FALSE;
|
||||
}
|
||||
|
||||
actions.Add(wxGTKInputHandler::Map(event));
|
||||
|
||||
return actions;
|
||||
}
|
||||
|
||||
// entering it back should make it pressed again if it had been pressed
|
||||
if ( event.Entering() )
|
||||
// and entering it back should make it pressed again if it had been
|
||||
// pressed
|
||||
else if ( event.Entering() )
|
||||
{
|
||||
wxControlActions actions;
|
||||
if ( m_winCapture )
|
||||
{
|
||||
// we do have a pressed button
|
||||
actions.Add(wxACTION_BUTTON_PRESS);
|
||||
// we did have a pressed button which we released when leaving the
|
||||
// window, press it again
|
||||
control->PerformAction(wxACTION_BUTTON_PRESS, event);
|
||||
|
||||
// and the mouse is (back) inside it
|
||||
m_winHasMouse = TRUE;
|
||||
}
|
||||
|
||||
actions.Add(wxGTKInputHandler::Map(event));
|
||||
|
||||
return actions;
|
||||
}
|
||||
|
||||
return wxGTKInputHandler::Map(event);
|
||||
return wxGTKInputHandler::OnMouseMove(control, event);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxGTKScrollBarInputHandler
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
wxGTKScrollBarInputHandler::wxGTKScrollBarInputHandler()
|
||||
wxGTKScrollBarInputHandler::wxGTKScrollBarInputHandler(wxGTKRenderer *renderer)
|
||||
: wxGTKInputHandler(renderer)
|
||||
{
|
||||
m_winCapture = NULL;
|
||||
m_htLast = wxHT_NOWHERE;
|
||||
}
|
||||
|
||||
wxControlActions wxGTKScrollBarInputHandler::Map(const wxKeyEvent& event,
|
||||
void wxGTKScrollBarInputHandler::SetElementState(wxScrollBar *control,
|
||||
int flag,
|
||||
bool doIt)
|
||||
{
|
||||
wxScrollBar::Element elem;
|
||||
switch ( m_htLast )
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return wxGTKInputHandler::Map(event, 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(const wxMouseEvent& event)
|
||||
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() )
|
||||
{
|
||||
// determin which part of the window mouse is in
|
||||
wxHitTest ht = m_renderer->HitTestScrollbar
|
||||
(
|
||||
scrollbar,
|
||||
event.GetPosition()
|
||||
);
|
||||
if ( ht == m_htLast )
|
||||
{
|
||||
// nothing changed
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return wxGTKInputHandler::Map(event);
|
||||
#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;
|
||||
}
|
||||
|
@@ -101,10 +101,13 @@ public:
|
||||
int thumbPosStart,
|
||||
int thumbPosEnd,
|
||||
const wxRect& rect,
|
||||
int flags = 0);
|
||||
const int *flags = NULL);
|
||||
|
||||
virtual void AdjustSize(wxSize *size, const wxWindow *window);
|
||||
|
||||
virtual wxHitTest HitTestScrollbar(wxScrollBar *scrollbar,
|
||||
const wxPoint& pt) const;
|
||||
|
||||
protected:
|
||||
// DrawButtonBorder() helper
|
||||
void DoDrawBackground(wxDC& dc,
|
||||
@@ -167,8 +170,11 @@ private:
|
||||
class wxWin32InputHandler : public wxInputHandler
|
||||
{
|
||||
public:
|
||||
virtual wxControlActions Map(const wxKeyEvent& event, bool pressed);
|
||||
virtual wxControlActions Map(const wxMouseEvent& event);
|
||||
virtual wxControlActions Map(wxControl *control,
|
||||
const wxKeyEvent& event,
|
||||
bool pressed);
|
||||
virtual wxControlActions Map(wxControl *control,
|
||||
const wxMouseEvent& event);
|
||||
};
|
||||
|
||||
class wxWin32ButtonInputHandler : public wxWin32InputHandler
|
||||
@@ -176,8 +182,11 @@ class wxWin32ButtonInputHandler : public wxWin32InputHandler
|
||||
public:
|
||||
wxWin32ButtonInputHandler();
|
||||
|
||||
virtual wxControlActions Map(const wxKeyEvent& event, bool pressed);
|
||||
virtual wxControlActions Map(const wxMouseEvent& event);
|
||||
virtual wxControlActions Map(wxControl *control,
|
||||
const wxKeyEvent& event,
|
||||
bool pressed);
|
||||
virtual wxControlActions Map(wxControl *control,
|
||||
const wxMouseEvent& event);
|
||||
|
||||
private:
|
||||
wxWindow *m_winCapture;
|
||||
@@ -255,17 +264,12 @@ wxInputHandler *wxWin32Theme::GetInputHandler(const wxString& control)
|
||||
// create a new handler
|
||||
n = m_handlerNames.Add(control);
|
||||
|
||||
if ( control == wxCONTROL_BUTTON )
|
||||
if ( control == wxButtonNameStr )
|
||||
handler = new wxWin32ButtonInputHandler;
|
||||
else if ( control == wxCONTROL_SCROLLBAR )
|
||||
else if ( control == wxScrollBarNameStr )
|
||||
handler = new wxWin32InputHandler; // TODO
|
||||
else
|
||||
{
|
||||
wxASSERT_MSG( control == wxCONTROL_DEFAULT,
|
||||
_T("no input handler defined for this control") );
|
||||
|
||||
handler = new wxWin32InputHandler;
|
||||
}
|
||||
|
||||
m_handlers.Insert(handler, n);
|
||||
}
|
||||
@@ -893,9 +897,10 @@ void wxWin32Renderer::DrawScrollbar(wxDC& dc,
|
||||
int thumbPosStart,
|
||||
int thumbPosEnd,
|
||||
const wxRect& rect,
|
||||
int flags)
|
||||
const int *flags)
|
||||
{
|
||||
wxArrowStyle arrowStyle = flags & wxCONTROL_DISABLED ? Arrow_Disabled
|
||||
int flagsSb = flags ? flags[0] : 0;
|
||||
wxArrowStyle arrowStyle = flagsSb & wxCONTROL_DISABLED ? Arrow_Disabled
|
||||
: Arrow_Normal;
|
||||
|
||||
// first, draw the arrows at the ends
|
||||
@@ -957,6 +962,12 @@ void wxWin32Renderer::DrawScrollbar(wxDC& dc,
|
||||
}
|
||||
}
|
||||
|
||||
wxHitTest wxWin32Renderer::HitTestScrollbar(wxScrollBar *scrollbar,
|
||||
const wxPoint& pt) const
|
||||
{
|
||||
return wxHT_NOWHERE;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// size adjustments
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -1020,12 +1031,15 @@ void wxWin32Renderer::AdjustSize(wxSize *size, const wxWindow *window)
|
||||
// wxWin32InputHandler
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
wxControlActions wxWin32InputHandler::Map(const wxKeyEvent& event, bool pressed)
|
||||
wxControlActions wxWin32InputHandler::Map(wxControl *control,
|
||||
const wxKeyEvent& event,
|
||||
bool pressed)
|
||||
{
|
||||
return wxACTION_NONE;
|
||||
}
|
||||
|
||||
wxControlActions wxWin32InputHandler::Map(const wxMouseEvent& event)
|
||||
wxControlActions wxWin32InputHandler::Map(wxControl *control,
|
||||
const wxMouseEvent& event)
|
||||
{
|
||||
return wxACTION_NONE;
|
||||
}
|
||||
@@ -1039,7 +1053,8 @@ wxWin32ButtonInputHandler::wxWin32ButtonInputHandler()
|
||||
m_winCapture = NULL;
|
||||
}
|
||||
|
||||
wxControlActions wxWin32ButtonInputHandler::Map(const wxKeyEvent& event,
|
||||
wxControlActions wxWin32ButtonInputHandler::Map(wxControl *control,
|
||||
const wxKeyEvent& event,
|
||||
bool pressed)
|
||||
{
|
||||
int keycode = event.GetKeyCode();
|
||||
@@ -1048,10 +1063,11 @@ wxControlActions wxWin32ButtonInputHandler::Map(const wxKeyEvent& event,
|
||||
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() )
|
||||
{
|
||||
@@ -1068,5 +1084,5 @@ wxControlActions wxWin32ButtonInputHandler::Map(const wxMouseEvent& event)
|
||||
return wxACTION_BUTTON_TOGGLE;
|
||||
}
|
||||
|
||||
return wxWin32InputHandler::Map(event);
|
||||
return wxWin32InputHandler::Map(control, event);
|
||||
}
|
||||
|
Reference in New Issue
Block a user