1. added wxRenderer::StandardHitTestScrollbar
2. started implementing wxMSW scrollbar input handling git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/wxUNIVERSAL@8165 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -13,6 +13,12 @@
|
|||||||
wxRenderer class is used to draw all wxWindows controls. This is an ABC and
|
wxRenderer class is used to draw all wxWindows controls. This is an ABC and
|
||||||
the look of the application is determined by the concrete derivation of
|
the look of the application is determined by the concrete derivation of
|
||||||
wxRenderer used in the program.
|
wxRenderer used in the program.
|
||||||
|
|
||||||
|
It also contains a few static methods which may be used by the concrete
|
||||||
|
renderers and provide the functionality which is often similar or identical
|
||||||
|
in all renderers (using inheritance here would be more restrictive as the
|
||||||
|
given concrete renderer may need an arbitrary subset of the base class
|
||||||
|
methods)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef __GNUG__
|
#ifdef __GNUG__
|
||||||
@@ -131,6 +137,14 @@ public:
|
|||||||
|
|
||||||
// virtual dtor for any base class
|
// virtual dtor for any base class
|
||||||
virtual ~wxRenderer();
|
virtual ~wxRenderer();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// standard scrollbar hit testing: this assumes that it only has 2 arrows
|
||||||
|
// and a thumb, so the themes which have more complicated scrollbars (e.g.
|
||||||
|
// BeOS) can't use this method
|
||||||
|
static wxHitTest StandardHitTestScrollbar(wxScrollBar *scrollbar,
|
||||||
|
const wxPoint& pt,
|
||||||
|
const wxSize& sizeArrow);
|
||||||
};
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@@ -271,7 +271,7 @@ void wxControl::OnFocus(wxFocusEvent& event)
|
|||||||
|
|
||||||
wxInputHandler *wxControl::CreateInputHandler() const
|
wxInputHandler *wxControl::CreateInputHandler() const
|
||||||
{
|
{
|
||||||
return wxTheme::Get()->GetInputHandler(GetName());
|
return wxTheme::Get()->GetInputHandler(GetClassInfo()->GetClassName());
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxControl::OnKeyDown(wxKeyEvent& event)
|
void wxControl::OnKeyDown(wxKeyEvent& event)
|
||||||
|
@@ -43,6 +43,71 @@
|
|||||||
// implementation
|
// implementation
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// wxRenderer
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/* static */
|
||||||
|
wxHitTest wxRenderer::StandardHitTestScrollbar(wxScrollBar *scrollbar,
|
||||||
|
const wxPoint& pt,
|
||||||
|
const wxSize& sizeArrowSB)
|
||||||
|
{
|
||||||
|
// 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 = sizeArrowSB.y;
|
||||||
|
sizeTotal = scrollbar->GetSize().y;
|
||||||
|
}
|
||||||
|
else // horizontal
|
||||||
|
{
|
||||||
|
coord = pt.x;
|
||||||
|
sizeArrow = sizeArrowSB.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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
wxRenderer::~wxRenderer()
|
wxRenderer::~wxRenderer()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@@ -281,9 +281,9 @@ 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 == wxButtonNameStr )
|
if ( control == _T("wxButton") )
|
||||||
handler = new wxGTKButtonInputHandler(m_renderer);
|
handler = new wxGTKButtonInputHandler(m_renderer);
|
||||||
else if ( control == wxScrollBarNameStr )
|
else if ( control == _T("wxScrollBar") )
|
||||||
handler = new wxGTKScrollBarInputHandler(m_renderer);
|
handler = new wxGTKScrollBarInputHandler(m_renderer);
|
||||||
else
|
else
|
||||||
handler = new wxGTKInputHandler(m_renderer);
|
handler = new wxGTKInputHandler(m_renderer);
|
||||||
@@ -884,60 +884,7 @@ void wxGTKRenderer::DrawScrollbar(wxDC& dc,
|
|||||||
wxHitTest wxGTKRenderer::HitTestScrollbar(wxScrollBar *scrollbar,
|
wxHitTest wxGTKRenderer::HitTestScrollbar(wxScrollBar *scrollbar,
|
||||||
const wxPoint& pt) const
|
const wxPoint& pt) const
|
||||||
{
|
{
|
||||||
// we only need to work with tiehr x or y coord depending on the
|
return StandardHitTestScrollbar(scrollbar, pt, m_sizeScrollbarArrow);
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@@ -170,17 +170,22 @@ private:
|
|||||||
class wxWin32InputHandler : public wxInputHandler
|
class wxWin32InputHandler : public wxInputHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
wxWin32InputHandler(wxWin32Renderer *renderer);
|
||||||
|
|
||||||
virtual wxControlActions Map(wxControl *control,
|
virtual wxControlActions Map(wxControl *control,
|
||||||
const wxKeyEvent& event,
|
const wxKeyEvent& event,
|
||||||
bool pressed);
|
bool pressed);
|
||||||
virtual wxControlActions Map(wxControl *control,
|
virtual wxControlActions Map(wxControl *control,
|
||||||
const wxMouseEvent& event);
|
const wxMouseEvent& event);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
wxWin32Renderer *m_renderer;
|
||||||
};
|
};
|
||||||
|
|
||||||
class wxWin32ButtonInputHandler : public wxWin32InputHandler
|
class wxWin32ButtonInputHandler : public wxWin32InputHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
wxWin32ButtonInputHandler();
|
wxWin32ButtonInputHandler(wxWin32Renderer *renderer);
|
||||||
|
|
||||||
virtual wxControlActions Map(wxControl *control,
|
virtual wxControlActions Map(wxControl *control,
|
||||||
const wxKeyEvent& event,
|
const wxKeyEvent& event,
|
||||||
@@ -192,6 +197,25 @@ private:
|
|||||||
wxWindow *m_winCapture;
|
wxWindow *m_winCapture;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class wxWin32ScrollBarInputHandler : public wxWin32InputHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
wxWin32ScrollBarInputHandler(wxWin32Renderer *renderer);
|
||||||
|
|
||||||
|
virtual wxControlActions Map(wxControl *control,
|
||||||
|
const wxKeyEvent& event,
|
||||||
|
bool pressed);
|
||||||
|
virtual wxControlActions Map(wxControl *control,
|
||||||
|
const wxMouseEvent& event);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void Press(wxScrollBar *scrollbar, bool doIt) { }
|
||||||
|
|
||||||
|
wxWindow *m_winCapture;
|
||||||
|
int m_btnCapture;
|
||||||
|
wxHitTest m_htLast;
|
||||||
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// wxWin32ColourScheme: uses (default) Win32 colours
|
// wxWin32ColourScheme: uses (default) Win32 colours
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -264,12 +288,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 == wxButtonNameStr )
|
if ( control == _T("wxButton") )
|
||||||
handler = new wxWin32ButtonInputHandler;
|
handler = new wxWin32ButtonInputHandler(m_renderer);
|
||||||
else if ( control == wxScrollBarNameStr )
|
else if ( control == _T("wxScrollBar") )
|
||||||
handler = new wxWin32InputHandler; // TODO
|
handler = new wxWin32ScrollBarInputHandler(m_renderer);
|
||||||
else
|
else
|
||||||
handler = new wxWin32InputHandler;
|
handler = new wxWin32InputHandler(m_renderer);
|
||||||
|
|
||||||
m_handlers.Insert(handler, n);
|
m_handlers.Insert(handler, n);
|
||||||
}
|
}
|
||||||
@@ -965,7 +989,7 @@ void wxWin32Renderer::DrawScrollbar(wxDC& dc,
|
|||||||
wxHitTest wxWin32Renderer::HitTestScrollbar(wxScrollBar *scrollbar,
|
wxHitTest wxWin32Renderer::HitTestScrollbar(wxScrollBar *scrollbar,
|
||||||
const wxPoint& pt) const
|
const wxPoint& pt) const
|
||||||
{
|
{
|
||||||
return wxHT_NOWHERE;
|
return StandardHitTestScrollbar(scrollbar, pt, m_sizeScrollbarArrow);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -1031,6 +1055,11 @@ void wxWin32Renderer::AdjustSize(wxSize *size, const wxWindow *window)
|
|||||||
// wxWin32InputHandler
|
// wxWin32InputHandler
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
wxWin32InputHandler::wxWin32InputHandler(wxWin32Renderer *renderer)
|
||||||
|
{
|
||||||
|
m_renderer = renderer;
|
||||||
|
}
|
||||||
|
|
||||||
wxControlActions wxWin32InputHandler::Map(wxControl *control,
|
wxControlActions wxWin32InputHandler::Map(wxControl *control,
|
||||||
const wxKeyEvent& event,
|
const wxKeyEvent& event,
|
||||||
bool pressed)
|
bool pressed)
|
||||||
@@ -1048,7 +1077,8 @@ wxControlActions wxWin32InputHandler::Map(wxControl *control,
|
|||||||
// wxWin32ButtonInputHandler
|
// wxWin32ButtonInputHandler
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
wxWin32ButtonInputHandler::wxWin32ButtonInputHandler()
|
wxWin32ButtonInputHandler::wxWin32ButtonInputHandler(wxWin32Renderer *renderer)
|
||||||
|
: wxWin32InputHandler(renderer)
|
||||||
{
|
{
|
||||||
m_winCapture = NULL;
|
m_winCapture = NULL;
|
||||||
}
|
}
|
||||||
@@ -1086,3 +1116,134 @@ wxControlActions wxWin32ButtonInputHandler::Map(wxControl *control,
|
|||||||
|
|
||||||
return wxWin32InputHandler::Map(control, event);
|
return wxWin32InputHandler::Map(control, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// wxWin32ScrollBarInputHandler
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
wxWin32ScrollBarInputHandler::wxWin32ScrollBarInputHandler(wxWin32Renderer *renderer)
|
||||||
|
: wxWin32InputHandler(renderer)
|
||||||
|
{
|
||||||
|
m_winCapture = NULL;
|
||||||
|
m_htLast = wxHT_NOWHERE;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxControlActions wxWin32ScrollBarInputHandler::Map(wxControl *control,
|
||||||
|
const wxKeyEvent& event,
|
||||||
|
bool pressed)
|
||||||
|
{
|
||||||
|
// we only react to the key presses here
|
||||||
|
if ( pressed )
|
||||||
|
{
|
||||||
|
switch ( event.GetKeyCode() )
|
||||||
|
{
|
||||||
|
case WXK_DOWN:
|
||||||
|
case WXK_RIGHT: return wxACTION_SCROLL_LINE_DOWN;
|
||||||
|
case WXK_UP:
|
||||||
|
case WXK_LEFT: return wxACTION_SCROLL_LINE_UP;
|
||||||
|
case WXK_HOME: return wxACTION_SCROLL_START;
|
||||||
|
case WXK_END: return wxACTION_SCROLL_END;
|
||||||
|
case WXK_PRIOR: return wxACTION_SCROLL_PAGE_UP;
|
||||||
|
case WXK_NEXT: return wxACTION_SCROLL_PAGE_DOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return wxWin32InputHandler::Map(control, event, pressed);
|
||||||
|
}
|
||||||
|
|
||||||
|
wxControlActions wxWin32ScrollBarInputHandler::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
|
||||||
|
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;
|
||||||
|
|
||||||
|
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 wxWin32InputHandler::Map(control, event);
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user