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
|
||||
the look of the application is determined by the concrete derivation of
|
||||
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__
|
||||
@@ -131,6 +137,14 @@ public:
|
||||
|
||||
// virtual dtor for any base class
|
||||
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
|
||||
{
|
||||
return wxTheme::Get()->GetInputHandler(GetName());
|
||||
return wxTheme::Get()->GetInputHandler(GetClassInfo()->GetClassName());
|
||||
}
|
||||
|
||||
void wxControl::OnKeyDown(wxKeyEvent& event)
|
||||
|
@@ -43,6 +43,71 @@
|
||||
// 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()
|
||||
{
|
||||
}
|
||||
|
@@ -281,9 +281,9 @@ wxInputHandler *wxGTKTheme::GetInputHandler(const wxString& control)
|
||||
// create a new handler
|
||||
n = m_handlerNames.Add(control);
|
||||
|
||||
if ( control == wxButtonNameStr )
|
||||
if ( control == _T("wxButton") )
|
||||
handler = new wxGTKButtonInputHandler(m_renderer);
|
||||
else if ( control == wxScrollBarNameStr )
|
||||
else if ( control == _T("wxScrollBar") )
|
||||
handler = new wxGTKScrollBarInputHandler(m_renderer);
|
||||
else
|
||||
handler = new wxGTKInputHandler(m_renderer);
|
||||
@@ -884,60 +884,7 @@ void wxGTKRenderer::DrawScrollbar(wxDC& dc,
|
||||
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;
|
||||
}
|
||||
return StandardHitTestScrollbar(scrollbar, pt, m_sizeScrollbarArrow);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@@ -170,17 +170,22 @@ private:
|
||||
class wxWin32InputHandler : public wxInputHandler
|
||||
{
|
||||
public:
|
||||
wxWin32InputHandler(wxWin32Renderer *renderer);
|
||||
|
||||
virtual wxControlActions Map(wxControl *control,
|
||||
const wxKeyEvent& event,
|
||||
bool pressed);
|
||||
virtual wxControlActions Map(wxControl *control,
|
||||
const wxMouseEvent& event);
|
||||
|
||||
protected:
|
||||
wxWin32Renderer *m_renderer;
|
||||
};
|
||||
|
||||
class wxWin32ButtonInputHandler : public wxWin32InputHandler
|
||||
{
|
||||
public:
|
||||
wxWin32ButtonInputHandler();
|
||||
wxWin32ButtonInputHandler(wxWin32Renderer *renderer);
|
||||
|
||||
virtual wxControlActions Map(wxControl *control,
|
||||
const wxKeyEvent& event,
|
||||
@@ -192,6 +197,25 @@ private:
|
||||
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
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -264,12 +288,12 @@ wxInputHandler *wxWin32Theme::GetInputHandler(const wxString& control)
|
||||
// create a new handler
|
||||
n = m_handlerNames.Add(control);
|
||||
|
||||
if ( control == wxButtonNameStr )
|
||||
handler = new wxWin32ButtonInputHandler;
|
||||
else if ( control == wxScrollBarNameStr )
|
||||
handler = new wxWin32InputHandler; // TODO
|
||||
if ( control == _T("wxButton") )
|
||||
handler = new wxWin32ButtonInputHandler(m_renderer);
|
||||
else if ( control == _T("wxScrollBar") )
|
||||
handler = new wxWin32ScrollBarInputHandler(m_renderer);
|
||||
else
|
||||
handler = new wxWin32InputHandler;
|
||||
handler = new wxWin32InputHandler(m_renderer);
|
||||
|
||||
m_handlers.Insert(handler, n);
|
||||
}
|
||||
@@ -965,7 +989,7 @@ void wxWin32Renderer::DrawScrollbar(wxDC& dc,
|
||||
wxHitTest wxWin32Renderer::HitTestScrollbar(wxScrollBar *scrollbar,
|
||||
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(wxWin32Renderer *renderer)
|
||||
{
|
||||
m_renderer = renderer;
|
||||
}
|
||||
|
||||
wxControlActions wxWin32InputHandler::Map(wxControl *control,
|
||||
const wxKeyEvent& event,
|
||||
bool pressed)
|
||||
@@ -1048,7 +1077,8 @@ wxControlActions wxWin32InputHandler::Map(wxControl *control,
|
||||
// wxWin32ButtonInputHandler
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
wxWin32ButtonInputHandler::wxWin32ButtonInputHandler()
|
||||
wxWin32ButtonInputHandler::wxWin32ButtonInputHandler(wxWin32Renderer *renderer)
|
||||
: wxWin32InputHandler(renderer)
|
||||
{
|
||||
m_winCapture = NULL;
|
||||
}
|
||||
@@ -1086,3 +1116,134 @@ wxControlActions wxWin32ButtonInputHandler::Map(wxControl *control,
|
||||
|
||||
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