more scrollbar input handling: extracted common bits to wxStdScrollBarHandler
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/wxUNIVERSAL@8174 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -50,4 +50,115 @@ public:
|
||||
virtual ~wxInputHandler();
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// The classes below provide the standard input handling for some controls so
|
||||
// that the code can be reused in different themes. All of these classes chain
|
||||
// to an existing input handler (which must be given to the ctor) and so allow
|
||||
// custom processing of the events which they don't handle themselves.
|
||||
// ============================================================================
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxStdInputHandler is just a base class for all other "standard" handlers
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class WXDLLEXPORT wxStdInputHandler : public wxInputHandler
|
||||
{
|
||||
public:
|
||||
wxStdInputHandler(wxInputHandler *handler) : m_handler(handler) { }
|
||||
|
||||
virtual wxControlActions Map(wxControl *control,
|
||||
const wxKeyEvent& event,
|
||||
bool pressed)
|
||||
{ return m_handler->Map(control, event, pressed); }
|
||||
virtual wxControlActions Map(wxControl *control,
|
||||
const wxMouseEvent& event)
|
||||
{ return m_handler->Map(control, event); }
|
||||
virtual bool OnMouseMove(wxControl *control, const wxMouseEvent& event)
|
||||
{ return m_handler->OnMouseMove(control, event); }
|
||||
|
||||
private:
|
||||
wxInputHandler *m_handler;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxStdButtonInputHandler: translates SPACE and ENTER keys and the left mouse
|
||||
// click into button press/release actions
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class WXDLLEXPORT wxStdButtonInputHandler : public wxStdInputHandler
|
||||
{
|
||||
public:
|
||||
wxStdButtonInputHandler(wxInputHandler *inphand);
|
||||
|
||||
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:
|
||||
// the window (button) which has capture or NULL and the flag telling if
|
||||
// the mouse is inside the button which captured it or not
|
||||
wxWindow *m_winCapture;
|
||||
bool m_winHasMouse;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// common scrollbar input handler: it manages clicks on the standard scrollbar
|
||||
// elements (line arrows, bar, thumb)
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class WXDLLEXPORT wxStdScrollBarInputHandler : public wxStdInputHandler
|
||||
{
|
||||
public:
|
||||
// constructor takes a renderer (used for scrollbar hit testing) and the
|
||||
// base handler to which all unhandled events are forwarded
|
||||
wxStdScrollBarInputHandler(wxRenderer *renderer,
|
||||
wxInputHandler *inphand);
|
||||
|
||||
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:
|
||||
// the methods which must be overridden in the derived class
|
||||
|
||||
// return TRUE to stop scrolling when the mouse leaves the scrollbar (Win32
|
||||
// behaviour) or FALSE to continue (GTK+)
|
||||
virtual bool OnMouseLeave() = 0;
|
||||
|
||||
// return TRUE if the mouse button can be used to activate scrollbar, FALSE
|
||||
// if not (only left mouse button can do it under Windows, any button under
|
||||
// GTK+)
|
||||
virtual bool IsAllowedButton(int button) = 0;
|
||||
|
||||
// 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); }
|
||||
|
||||
// the window (scrollbar) which has capture or NULL and the flag telling if
|
||||
// the mouse is inside the element which captured it or not
|
||||
wxWindow *m_winCapture;
|
||||
bool m_winHasMouse;
|
||||
int m_btnCapture; // the mouse button which has captured mouse
|
||||
|
||||
// one of wxHT_SCROLLBAR_XXX value: where has the mouse been last time?
|
||||
wxHitTest m_htLast;
|
||||
|
||||
// the renderer (we use it only for hit testing)
|
||||
wxRenderer *m_renderer;
|
||||
};
|
||||
|
||||
#endif // _WX_UNIV_INPHAND_H_
|
||||
|
@@ -46,6 +46,7 @@ enum wxHitTest
|
||||
wxHT_NOWHERE,
|
||||
|
||||
// scrollbar
|
||||
wxHT_SCROLLBAR_FIRST = wxHT_NOWHERE,
|
||||
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
|
||||
@@ -53,6 +54,7 @@ enum wxHitTest
|
||||
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_SCROLLBAR_LAST,
|
||||
|
||||
wxHT_MAX
|
||||
};
|
||||
|
@@ -16,6 +16,8 @@
|
||||
#pragma interface "univscrolbar.h"
|
||||
#endif
|
||||
|
||||
#include "wx/univ/renderer.h" // for wxHitTest
|
||||
|
||||
class WXDLLEXPORT wxInputHandler;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -42,15 +44,17 @@ class WXDLLEXPORT wxInputHandler;
|
||||
class WXDLLEXPORT wxScrollBar : public wxScrollBarBase
|
||||
{
|
||||
public:
|
||||
// the parts of the scrollbar
|
||||
// scrollbar elements: they correspond to wxHT_SCROLLBAR_XXX constants but
|
||||
// start from 0 which allows to use them as array indices
|
||||
enum Element
|
||||
{
|
||||
Element_Arrow_Line_1,
|
||||
Element_Arrow_Line_2,
|
||||
Element_Arrow_Page_1,
|
||||
Element_Arrow_Page_2,
|
||||
Element_Thumb,
|
||||
Element_Bar,
|
||||
Element_Arrow_Thumb,
|
||||
Element_Bar_1,
|
||||
Element_Bar_2,
|
||||
Element_Max
|
||||
};
|
||||
|
||||
@@ -99,10 +103,8 @@ public:
|
||||
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]; }
|
||||
void SetState(Element which, int flags) { m_elementsState[which] = flags; }
|
||||
int GetState(Element which) const { return m_elementsState[which]; }
|
||||
|
||||
protected:
|
||||
virtual wxSize DoGetBestSize() const;
|
||||
@@ -110,7 +112,7 @@ protected:
|
||||
|
||||
// SetThumbPosition() helper
|
||||
void DoSetThumb(int thumbPos);
|
||||
|
||||
|
||||
// common part of all ctors
|
||||
void Init();
|
||||
|
||||
|
@@ -1015,7 +1015,7 @@ void wxWindow::OnIdle(wxIdleEvent& event)
|
||||
state |= MK_MBUTTON;
|
||||
if ( GetKeyState( VK_RBUTTON ) )
|
||||
state |= MK_RBUTTON;
|
||||
|
||||
|
||||
wxMouseEvent event(wxEVT_LEAVE_WINDOW);
|
||||
InitMouseEvent(event, pt.x, pt.y, state);
|
||||
|
||||
@@ -3273,13 +3273,22 @@ bool wxWindow::HandleMouseMove(int x, int y, WXUINT flags)
|
||||
{
|
||||
if ( !m_mouseInWindow )
|
||||
{
|
||||
// Generate an ENTER event
|
||||
m_mouseInWindow = TRUE;
|
||||
// it would be wrogn to assume that just because we get a mouse move
|
||||
// event the mouse is inside the window: although this is usually true,
|
||||
// it is not if we had captured the mouse, so we need to check the
|
||||
// mouse coordinates here
|
||||
POINT pt;
|
||||
::GetCursorPos(&pt);
|
||||
if ( ::WindowFromPoint(pt) == GetHwnd() )
|
||||
{
|
||||
// Generate an ENTER event
|
||||
m_mouseInWindow = TRUE;
|
||||
|
||||
wxMouseEvent event(wxEVT_ENTER_WINDOW);
|
||||
InitMouseEvent(event, x, y, flags);
|
||||
wxMouseEvent event(wxEVT_ENTER_WINDOW);
|
||||
InitMouseEvent(event, x, y, flags);
|
||||
|
||||
(void)GetEventHandler()->ProcessEvent(event);
|
||||
(void)GetEventHandler()->ProcessEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
#if wxUSE_MOUSEEVENT_HACK
|
||||
|
@@ -37,6 +37,10 @@
|
||||
// implementation
|
||||
// ============================================================================
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxInputHandler
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
bool wxInputHandler::OnMouseMove(wxControl * WXUNUSED(control),
|
||||
const wxMouseEvent& WXUNUSED(event))
|
||||
{
|
||||
@@ -46,3 +50,308 @@ bool wxInputHandler::OnMouseMove(wxControl * WXUNUSED(control),
|
||||
wxInputHandler::~wxInputHandler()
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxStdButtonInputHandler
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
wxStdButtonInputHandler::wxStdButtonInputHandler(wxInputHandler *handler)
|
||||
: wxStdInputHandler(handler)
|
||||
{
|
||||
m_winCapture = NULL;
|
||||
}
|
||||
|
||||
wxControlActions wxStdButtonInputHandler::Map(wxControl *control,
|
||||
const wxKeyEvent& event,
|
||||
bool pressed)
|
||||
{
|
||||
int keycode = event.GetKeyCode();
|
||||
if ( keycode == WXK_SPACE || keycode == WXK_RETURN )
|
||||
{
|
||||
return wxACTION_BUTTON_TOGGLE;
|
||||
}
|
||||
|
||||
return wxStdInputHandler::Map(control, event, pressed);
|
||||
}
|
||||
|
||||
wxControlActions wxStdButtonInputHandler::Map(wxControl *control,
|
||||
const wxMouseEvent& event)
|
||||
{
|
||||
// the button has 2 states: pressed and normal with the following
|
||||
// transitions between them:
|
||||
//
|
||||
// normal -> left down -> capture mouse and go to pressed state
|
||||
// pressed -> left up inside -> generate click -> go to normal
|
||||
// outside ------------------>
|
||||
//
|
||||
// the other mouse buttons are ignored
|
||||
if ( event.Button(1) )
|
||||
{
|
||||
if ( event.ButtonDown(1) )
|
||||
{
|
||||
m_winCapture = control;
|
||||
m_winCapture->CaptureMouse();
|
||||
m_winHasMouse = TRUE;
|
||||
|
||||
return wxACTION_BUTTON_PRESS;
|
||||
}
|
||||
else // up
|
||||
{
|
||||
m_winCapture->ReleaseMouse();
|
||||
m_winCapture = NULL;
|
||||
|
||||
if ( m_winHasMouse )
|
||||
{
|
||||
// this will generate a click event
|
||||
return wxACTION_BUTTON_TOGGLE;
|
||||
}
|
||||
//else: the mouse was released outside the window, this doesn't
|
||||
// count as a click
|
||||
}
|
||||
}
|
||||
|
||||
return wxStdInputHandler::Map(control, event);
|
||||
}
|
||||
|
||||
bool wxStdButtonInputHandler::OnMouseMove(wxControl *control,
|
||||
const wxMouseEvent& event)
|
||||
{
|
||||
// we only have to do soemthing when the mouse leaves/enters the pressed
|
||||
// button and don't care about the other ones
|
||||
if ( event.GetEventObject() == m_winCapture )
|
||||
{
|
||||
// leaving the button should remove its pressed state
|
||||
if ( event.Leaving() )
|
||||
{
|
||||
// remember that the mouse is now outside
|
||||
m_winHasMouse = FALSE;
|
||||
|
||||
// we do have a pressed button, so release it
|
||||
if ( control->PerformAction(wxACTION_BUTTON_RELEASE, event) )
|
||||
{
|
||||
// the button state changed, refresh needed
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
// and entering it back should make it pressed again if it had been
|
||||
// pressed
|
||||
else if ( event.Entering() )
|
||||
{
|
||||
// the mouse is (back) inside the button
|
||||
m_winHasMouse = TRUE;
|
||||
|
||||
// we did have a pressed button which we released when leaving the
|
||||
// window, press it again
|
||||
if ( control->PerformAction(wxACTION_BUTTON_PRESS, event) )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return wxStdInputHandler::OnMouseMove(control, event);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxStdScrollBarInputHandler
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
wxStdScrollBarInputHandler::wxStdScrollBarInputHandler(wxRenderer *renderer,
|
||||
wxInputHandler *handler)
|
||||
: wxStdInputHandler(handler)
|
||||
{
|
||||
m_renderer = renderer;
|
||||
m_winCapture = NULL;
|
||||
m_htLast = wxHT_NOWHERE;
|
||||
}
|
||||
|
||||
void wxStdScrollBarInputHandler::SetElementState(wxScrollBar *control,
|
||||
int flag,
|
||||
bool doIt)
|
||||
{
|
||||
if ( m_htLast > wxHT_SCROLLBAR_FIRST && m_htLast < wxHT_SCROLLBAR_LAST )
|
||||
{
|
||||
wxScrollBar::Element
|
||||
elem = (wxScrollBar::Element)(m_htLast - wxHT_SCROLLBAR_FIRST - 1);
|
||||
|
||||
int flags = control->GetState(elem);
|
||||
if ( doIt )
|
||||
flags |= flag;
|
||||
else
|
||||
flags &= ~flag;
|
||||
control->SetState(elem, flags);
|
||||
}
|
||||
}
|
||||
|
||||
wxControlActions wxStdScrollBarInputHandler::Map(wxControl *control,
|
||||
const wxKeyEvent& event,
|
||||
bool pressed)
|
||||
{
|
||||
// we only react to the key presses here
|
||||
if ( pressed )
|
||||
{
|
||||
switch ( event.GetKeyCode() )
|
||||
{
|
||||
case WXK_DOWN:
|
||||
case WXK_RIGHT: return wxACTION_SCROLL_LINE_DOWN;
|
||||
case WXK_UP:
|
||||
case WXK_LEFT: return wxACTION_SCROLL_LINE_UP;
|
||||
case WXK_HOME: return wxACTION_SCROLL_START;
|
||||
case WXK_END: return wxACTION_SCROLL_END;
|
||||
case WXK_PRIOR: return wxACTION_SCROLL_PAGE_UP;
|
||||
case WXK_NEXT: return wxACTION_SCROLL_PAGE_DOWN;
|
||||
}
|
||||
}
|
||||
|
||||
return wxStdInputHandler::Map(control, event, pressed);
|
||||
}
|
||||
|
||||
wxControlActions wxStdScrollBarInputHandler::Map(wxControl *control,
|
||||
const wxMouseEvent& event)
|
||||
{
|
||||
// is this a click event from an acceptable button?
|
||||
int btn = -1;
|
||||
if ( event.IsButton() )
|
||||
{
|
||||
for ( int i = 1; i <= 3; i++ )
|
||||
{
|
||||
if ( event.Button(i) )
|
||||
{
|
||||
btn = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
wxASSERT_MSG( btn != -1, _T("unknown mouse button") );
|
||||
}
|
||||
|
||||
if ( (btn != -1) && IsAllowedButton(btn) )
|
||||
{
|
||||
// determine which part of the window mouse is in
|
||||
wxScrollBar *scrollbar = wxStaticCast(control, wxScrollBar);
|
||||
wxHitTest ht = m_renderer->HitTestScrollbar
|
||||
(
|
||||
scrollbar,
|
||||
event.GetPosition()
|
||||
);
|
||||
|
||||
// when the mouse is pressed on any scrollbar element, we capture it
|
||||
// and hold capture until the same mouse button is released
|
||||
if ( event.ButtonDown() )
|
||||
{
|
||||
if ( !m_winCapture )
|
||||
{
|
||||
m_btnCapture = btn;
|
||||
m_winCapture = control;
|
||||
m_winCapture->CaptureMouse();
|
||||
|
||||
// generate the command
|
||||
bool hasAction = TRUE;
|
||||
wxControlAction action;
|
||||
switch ( ht )
|
||||
{
|
||||
case wxHT_SCROLLBAR_ARROW_LINE_1:
|
||||
action = wxACTION_SCROLL_LINE_UP;
|
||||
break;
|
||||
|
||||
case wxHT_SCROLLBAR_ARROW_LINE_2:
|
||||
action = wxACTION_SCROLL_LINE_DOWN;
|
||||
break;
|
||||
|
||||
case wxHT_SCROLLBAR_BAR_1:
|
||||
action = wxACTION_SCROLL_PAGE_UP;
|
||||
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);
|
||||
|
||||
control->Refresh();
|
||||
}
|
||||
//else: mouse already captured, nothing to do
|
||||
}
|
||||
// release mouse if the *same* button went up
|
||||
else if ( btn == m_btnCapture )
|
||||
{
|
||||
if ( m_winCapture )
|
||||
{
|
||||
m_winCapture->ReleaseMouse();
|
||||
m_winCapture = NULL;
|
||||
m_btnCapture = -1;
|
||||
|
||||
// unpress the arrow and highlight the current element
|
||||
Press(scrollbar, FALSE);
|
||||
m_htLast = ht;
|
||||
Highlight(scrollbar, TRUE);
|
||||
|
||||
control->Refresh();
|
||||
}
|
||||
else
|
||||
{
|
||||
// this is not supposed to happen as the button can't go up
|
||||
// without going down previously and then we'd have
|
||||
// m_winCapture by now
|
||||
wxFAIL_MSG( _T("logic error in mouse capturing code") );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return wxStdInputHandler::Map(control, event);
|
||||
}
|
||||
|
||||
bool wxStdScrollBarInputHandler::OnMouseMove(wxControl *control,
|
||||
const wxMouseEvent& event)
|
||||
{
|
||||
if ( m_winCapture )
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
|
@@ -56,7 +56,7 @@ void wxScrollBar::Init()
|
||||
m_thumbPos =
|
||||
m_pageSize = 0;
|
||||
|
||||
for ( size_t n = 0; n < Element_Max; n++ )
|
||||
for ( size_t n = 0; n < WXSIZEOF(m_elementsState); n++ )
|
||||
{
|
||||
m_elementsState[n] = 0;
|
||||
}
|
||||
|
@@ -162,53 +162,15 @@ protected:
|
||||
wxGTKRenderer *m_renderer;
|
||||
};
|
||||
|
||||
class wxGTKButtonInputHandler : public wxGTKInputHandler
|
||||
class wxGTKScrollBarInputHandler : public wxStdScrollBarInputHandler
|
||||
{
|
||||
public:
|
||||
wxGTKButtonInputHandler(wxGTKRenderer *renderer);
|
||||
wxGTKScrollBarInputHandler(wxRenderer *renderer, wxInputHandler *handler)
|
||||
: wxStdScrollBarInputHandler(renderer, handler) { }
|
||||
|
||||
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;
|
||||
bool m_winHasMouse;
|
||||
};
|
||||
|
||||
class wxGTKScrollBarInputHandler : public wxGTKInputHandler
|
||||
{
|
||||
public:
|
||||
wxGTKScrollBarInputHandler(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);
|
||||
|
||||
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;
|
||||
protected:
|
||||
virtual bool OnMouseLeave() { return FALSE; }
|
||||
virtual bool IsAllowedButton(int WXUNUSED(button)) { return TRUE; }
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -282,9 +244,10 @@ wxInputHandler *wxGTKTheme::GetInputHandler(const wxString& control)
|
||||
n = m_handlerNames.Add(control);
|
||||
|
||||
if ( control == _T("wxButton") )
|
||||
handler = new wxGTKButtonInputHandler(m_renderer);
|
||||
handler = new wxStdButtonInputHandler(GetInputHandler(_T("wxControl")));
|
||||
else if ( control == _T("wxScrollBar") )
|
||||
handler = new wxGTKScrollBarInputHandler(m_renderer);
|
||||
handler = new wxGTKScrollBarInputHandler(m_renderer,
|
||||
GetInputHandler(_T("wxControl")));
|
||||
else
|
||||
handler = new wxGTKInputHandler(m_renderer);
|
||||
|
||||
@@ -810,9 +773,9 @@ void wxGTKRenderer::DrawScrollbar(wxDC& dc,
|
||||
"\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],
|
||||
flags[wxHT_SCROLLBAR_ARROW_LINE_1],
|
||||
flags[wxHT_SCROLLBAR_ARROW_LINE_2],
|
||||
flags[wxHT_SCROLLBAR_THUMB],
|
||||
thumbPosStart, thumbPosEnd);
|
||||
#endif // DEBUG_MOUSE
|
||||
|
||||
@@ -850,7 +813,7 @@ void wxGTKRenderer::DrawScrollbar(wxDC& dc,
|
||||
for ( size_t nArrow = 0; nArrow < 2; nArrow++ )
|
||||
{
|
||||
DrawArrow(dc, arrowDir[nArrow], rectArrow[nArrow],
|
||||
flags[wxScrollBar::Element_Arrow_Line_1 + nArrow]);
|
||||
flags[wxHT_SCROLLBAR_ARROW_LINE_1 + nArrow]);
|
||||
}
|
||||
|
||||
// and, finally, the thumb, if any
|
||||
@@ -874,7 +837,7 @@ void wxGTKRenderer::DrawScrollbar(wxDC& dc,
|
||||
|
||||
// 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] &
|
||||
int flagsThumb = flags[wxHT_SCROLLBAR_THUMB] &
|
||||
~(wxCONTROL_PRESSED | wxCONTROL_FOCUSED);
|
||||
DrawButtonBorder(dc, rectThumb, flagsThumb, &rectThumb);
|
||||
DrawBackground(dc, rectThumb, flagsThumb);
|
||||
@@ -995,300 +958,3 @@ bool wxGTKInputHandler::OnMouseMove(wxControl *control,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxGTKButtonInputHandler
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
wxGTKButtonInputHandler::wxGTKButtonInputHandler(wxGTKRenderer *renderer)
|
||||
: wxGTKInputHandler(renderer)
|
||||
{
|
||||
m_winCapture = NULL;
|
||||
}
|
||||
|
||||
wxControlActions wxGTKButtonInputHandler::Map(wxControl *control,
|
||||
const wxKeyEvent& event,
|
||||
bool pressed)
|
||||
{
|
||||
int keycode = event.GetKeyCode();
|
||||
if ( keycode == WXK_SPACE || keycode == WXK_RETURN )
|
||||
{
|
||||
return wxACTION_BUTTON_TOGGLE;
|
||||
}
|
||||
|
||||
return wxGTKInputHandler::Map(control, event, pressed);
|
||||
}
|
||||
|
||||
wxControlActions wxGTKButtonInputHandler::Map(wxControl *control,
|
||||
const wxMouseEvent& event)
|
||||
{
|
||||
// the button has 2 states: pressed and normal with the following
|
||||
// transitions between them:
|
||||
//
|
||||
// normal -> left down -> capture mouse and go to pressed state
|
||||
// pressed -> left up inside -> generate click -> go to normal
|
||||
// outside ------------------>
|
||||
//
|
||||
// the other mouse buttons are ignored
|
||||
if ( event.Button(1) )
|
||||
{
|
||||
if ( event.ButtonDown(1) )
|
||||
{
|
||||
m_winCapture = control;
|
||||
m_winCapture->CaptureMouse();
|
||||
m_winHasMouse = TRUE;
|
||||
|
||||
return wxACTION_BUTTON_PRESS;
|
||||
}
|
||||
else // up
|
||||
{
|
||||
m_winCapture->ReleaseMouse();
|
||||
m_winCapture = NULL;
|
||||
|
||||
if ( m_winHasMouse )
|
||||
{
|
||||
// this will generate a click event
|
||||
return wxACTION_BUTTON_TOGGLE;
|
||||
}
|
||||
//else: the mouse was released outside the window, this doesn't
|
||||
// count as a click
|
||||
}
|
||||
}
|
||||
|
||||
return wxGTKInputHandler::Map(control, event);
|
||||
}
|
||||
|
||||
bool wxGTKButtonInputHandler::OnMouseMove(wxControl *control,
|
||||
const wxMouseEvent& event)
|
||||
{
|
||||
// leaving the button should remove its pressed state
|
||||
if ( event.Leaving() )
|
||||
{
|
||||
if ( m_winCapture )
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
// and entering it back should make it pressed again if it had been
|
||||
// pressed
|
||||
else if ( event.Entering() )
|
||||
{
|
||||
if ( m_winCapture )
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
return wxGTKInputHandler::OnMouseMove(control, event);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxGTKScrollBarInputHandler
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
wxGTKScrollBarInputHandler::wxGTKScrollBarInputHandler(wxGTKRenderer *renderer)
|
||||
: wxGTKInputHandler(renderer)
|
||||
{
|
||||
m_winCapture = NULL;
|
||||
m_htLast = wxHT_NOWHERE;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
|
@@ -61,6 +61,7 @@ public:
|
||||
{
|
||||
Arrow_Normal,
|
||||
Arrow_Disabled,
|
||||
Arrow_Pressed,
|
||||
Arrow_StateMax
|
||||
};
|
||||
|
||||
@@ -132,7 +133,7 @@ protected:
|
||||
void DrawRaisedBorder(wxDC& dc, wxRect *rect);
|
||||
|
||||
// draw the border used for scrollbar arrows
|
||||
void DrawArrowBorder(wxDC& dc, wxRect *rect);
|
||||
void DrawArrowBorder(wxDC& dc, wxRect *rect, bool isPressed = FALSE);
|
||||
|
||||
// public DrawArrow()s helper
|
||||
void DrawArrow(wxDC& dc, const wxRect& rect,
|
||||
@@ -182,38 +183,26 @@ protected:
|
||||
wxWin32Renderer *m_renderer;
|
||||
};
|
||||
|
||||
class wxWin32ButtonInputHandler : public wxWin32InputHandler
|
||||
class wxWin32ScrollBarInputHandler : public wxStdScrollBarInputHandler
|
||||
{
|
||||
public:
|
||||
wxWin32ButtonInputHandler(wxWin32Renderer *renderer);
|
||||
wxWin32ScrollBarInputHandler(wxWin32Renderer *renderer,
|
||||
wxInputHandler *handler)
|
||||
: wxStdScrollBarInputHandler(renderer, handler) { }
|
||||
|
||||
virtual wxControlActions Map(wxControl *control,
|
||||
const wxKeyEvent& event,
|
||||
bool pressed);
|
||||
virtual wxControlActions Map(wxControl *control,
|
||||
const wxMouseEvent& event);
|
||||
// we don't highlight scrollbar elements, so there is no need to process
|
||||
// mouse move events
|
||||
virtual bool OnMouseMove(wxControl *control, const wxMouseEvent& event)
|
||||
{
|
||||
if ( event.Moving() )
|
||||
return FALSE;
|
||||
|
||||
private:
|
||||
wxWindow *m_winCapture;
|
||||
};
|
||||
return wxStdScrollBarInputHandler::OnMouseMove(control, event);
|
||||
}
|
||||
|
||||
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;
|
||||
protected:
|
||||
virtual bool OnMouseLeave() { return TRUE; }
|
||||
virtual bool IsAllowedButton(int button) { return button == 1; }
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -289,9 +278,10 @@ wxInputHandler *wxWin32Theme::GetInputHandler(const wxString& control)
|
||||
n = m_handlerNames.Add(control);
|
||||
|
||||
if ( control == _T("wxButton") )
|
||||
handler = new wxWin32ButtonInputHandler(m_renderer);
|
||||
handler = new wxStdButtonInputHandler(GetInputHandler(_T("wxControl")));
|
||||
else if ( control == _T("wxScrollBar") )
|
||||
handler = new wxWin32ScrollBarInputHandler(m_renderer);
|
||||
handler = new wxWin32ScrollBarInputHandler(m_renderer,
|
||||
GetInputHandler(_T("wxControl")));
|
||||
else
|
||||
handler = new wxWin32InputHandler(m_renderer);
|
||||
|
||||
@@ -322,6 +312,10 @@ wxColour wxWin32ColourScheme::Get(wxWin32ColourScheme::StdColour col,
|
||||
{
|
||||
case CONTROL: return wxColour(0xc0c0c0);
|
||||
case CONTROL_TEXT: return *wxBLACK;
|
||||
case SCROLLBAR: if ( flags & wxCONTROL_PRESSED )
|
||||
return *wxBLACK;
|
||||
else
|
||||
return wxColour(0xe0e0e0);
|
||||
|
||||
case HIGHLIGHT: return wxColour(0x800000);
|
||||
case HIGHLIGHT_TEXT: return wxColour(0xffffff);
|
||||
@@ -500,6 +494,8 @@ wxWin32Renderer::wxWin32Renderer(const wxColourScheme *scheme)
|
||||
m_bmpArrows[Arrow_Normal][n].SetMask(mask);
|
||||
mask = new wxMask(m_bmpArrows[Arrow_Disabled][n], *wxWHITE);
|
||||
m_bmpArrows[Arrow_Disabled][n].SetMask(mask);
|
||||
|
||||
m_bmpArrows[Arrow_Pressed][n] = m_bmpArrows[Arrow_Normal][n];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -624,10 +620,25 @@ void wxWin32Renderer::DrawRaisedBorder(wxDC& dc, wxRect *rect)
|
||||
DrawShadedRect(dc, rect, m_penLightGrey, m_penDarkGrey);
|
||||
}
|
||||
|
||||
void wxWin32Renderer::DrawArrowBorder(wxDC& dc, wxRect *rect)
|
||||
void wxWin32Renderer::DrawArrowBorder(wxDC& dc, wxRect *rect, bool isPressed)
|
||||
{
|
||||
DrawShadedRect(dc, rect, m_penLightGrey, m_penBlack);
|
||||
DrawShadedRect(dc, rect, m_penHighlight, m_penDarkGrey);
|
||||
if ( isPressed )
|
||||
{
|
||||
DrawRect(dc, rect, m_penDarkGrey);
|
||||
|
||||
// the arrow is usually drawn inside border of width 2 and is offset by
|
||||
// another pixel in both directions when it's pressed - as the border
|
||||
// in this case is more narrow as well, we have to adjust rect like
|
||||
// this:
|
||||
rect->Inflate(-1);
|
||||
rect->x++;
|
||||
rect->y++;
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawShadedRect(dc, rect, m_penLightGrey, m_penBlack);
|
||||
DrawShadedRect(dc, rect, m_penHighlight, m_penDarkGrey);
|
||||
}
|
||||
}
|
||||
|
||||
void wxWin32Renderer::DrawBorder(wxDC& dc,
|
||||
@@ -912,7 +923,7 @@ void wxWin32Renderer::DrawArrowButton(wxDC& dc,
|
||||
wxArrowStyle arrowStyle)
|
||||
{
|
||||
wxRect rect = rectAll;
|
||||
DrawArrowBorder(dc, &rect);
|
||||
DrawArrowBorder(dc, &rect, arrowStyle == Arrow_Pressed);
|
||||
DrawArrow(dc, rect, arrowDir, arrowStyle);
|
||||
}
|
||||
|
||||
@@ -923,10 +934,6 @@ void wxWin32Renderer::DrawScrollbar(wxDC& dc,
|
||||
const wxRect& rect,
|
||||
const int *flags)
|
||||
{
|
||||
int flagsSb = flags ? flags[0] : 0;
|
||||
wxArrowStyle arrowStyle = flagsSb & wxCONTROL_DISABLED ? Arrow_Disabled
|
||||
: Arrow_Normal;
|
||||
|
||||
// first, draw the arrows at the ends
|
||||
wxRect rectArrow[2];
|
||||
wxArrowDirection arrowDir[2];
|
||||
@@ -952,24 +959,34 @@ void wxWin32Renderer::DrawScrollbar(wxDC& dc,
|
||||
arrowDir[1] = Arrow_Right;
|
||||
}
|
||||
|
||||
wxArrowStyle arrowStyle;
|
||||
for ( size_t nArrow = 0; nArrow < 2; nArrow++ )
|
||||
{
|
||||
int flagsArrow = flags[wxScrollBar::Element_Arrow_Line_1 + nArrow];
|
||||
if ( flagsArrow & wxCONTROL_PRESSED )
|
||||
arrowStyle = Arrow_Pressed;
|
||||
else if ( flagsArrow & wxCONTROL_DISABLED )
|
||||
arrowStyle = Arrow_Disabled;
|
||||
else
|
||||
arrowStyle = Arrow_Normal;
|
||||
|
||||
DrawArrowButton(dc, rectArrow[nArrow], arrowDir[nArrow], arrowStyle);
|
||||
}
|
||||
|
||||
// next draw the scrollbar area
|
||||
// next draw the scrollbar area: in a normal state, we draw it all in one
|
||||
// call to DoDrawBackground(), but when either part of the bar is pressed,
|
||||
// we paint them separately
|
||||
wxRect rectBar = rect;
|
||||
if ( orient == wxVERTICAL )
|
||||
rectBar.Inflate(0, -m_sizeScrollbarArrow.y);
|
||||
rectBar.Inflate(0, -(m_sizeScrollbarArrow.y + 1));
|
||||
else
|
||||
rectBar.Inflate(-m_sizeScrollbarArrow.x, 0);
|
||||
rectBar.Inflate(-(m_sizeScrollbarArrow.x + 1), 0);
|
||||
|
||||
DoDrawBackground(dc, m_colHighlight, rectBar);
|
||||
|
||||
// and, finally, the thumb, if any
|
||||
// calculate the thumb position
|
||||
wxRect rectThumb;
|
||||
if ( thumbPosStart < thumbPosEnd )
|
||||
{
|
||||
wxRect rectThumb = rectBar;
|
||||
rectThumb = rectBar;
|
||||
if ( orient == wxVERTICAL )
|
||||
{
|
||||
rectThumb.y += (rectBar.height*thumbPosStart)/100;
|
||||
@@ -980,7 +997,53 @@ void wxWin32Renderer::DrawScrollbar(wxDC& dc,
|
||||
rectThumb.x += (rectBar.width*thumbPosStart)/100;
|
||||
rectThumb.width = (rectBar.width*(thumbPosEnd - thumbPosStart))/100;
|
||||
}
|
||||
}
|
||||
//else: no thumb
|
||||
|
||||
if ( (flags[wxScrollBar::Element_Bar_1] & wxCONTROL_PRESSED) ||
|
||||
(flags[wxScrollBar::Element_Bar_2] & wxCONTROL_PRESSED) )
|
||||
{
|
||||
// calculate the bounding boxes for each of 2 bar parts
|
||||
wxRect rectBars[2];
|
||||
rectBars[0] =
|
||||
rectBars[1] = rectBar;
|
||||
if ( orient == wxVERTICAL )
|
||||
{
|
||||
rectBars[0].SetTop(m_sizeScrollbarArrow.y);
|
||||
rectBars[0].SetBottom(rectThumb.GetTop() - 1);
|
||||
rectBars[1].SetTop(rectThumb.GetBottom() + 1);
|
||||
rectBars[1].SetBottom(rectBar.GetBottom());
|
||||
}
|
||||
else // horizontal
|
||||
{
|
||||
rectBars[0].SetLeft(m_sizeScrollbarArrow.x);
|
||||
rectBars[0].SetRight(rectThumb.GetLeft() - 1);
|
||||
rectBars[1].SetLeft(rectThumb.GetRight() + 1);
|
||||
rectBars[1].SetRight(rectBar.GetRight());
|
||||
}
|
||||
|
||||
for ( size_t nBar = 0; nBar < 2; nBar++ )
|
||||
{
|
||||
DoDrawBackground(
|
||||
dc,
|
||||
m_scheme->Get
|
||||
(
|
||||
wxColourScheme::SCROLLBAR,
|
||||
flags[wxScrollBar::Element_Bar_1 + nBar]
|
||||
),
|
||||
rectBars[nBar]
|
||||
);
|
||||
}
|
||||
}
|
||||
else // nothing is pressed
|
||||
{
|
||||
DoDrawBackground(dc, m_scheme->Get(wxColourScheme::SCROLLBAR), rectBar);
|
||||
}
|
||||
|
||||
// and, finally, the thumb, if any
|
||||
if ( thumbPosStart < thumbPosEnd )
|
||||
{
|
||||
// we don't use the flags, the thumb never changes appearance
|
||||
DrawArrowBorder(dc, &rectThumb);
|
||||
DrawBackground(dc, rectThumb);
|
||||
}
|
||||
@@ -1072,178 +1135,3 @@ wxControlActions wxWin32InputHandler::Map(wxControl *control,
|
||||
{
|
||||
return wxACTION_NONE;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxWin32ButtonInputHandler
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
wxWin32ButtonInputHandler::wxWin32ButtonInputHandler(wxWin32Renderer *renderer)
|
||||
: wxWin32InputHandler(renderer)
|
||||
{
|
||||
m_winCapture = NULL;
|
||||
}
|
||||
|
||||
wxControlActions wxWin32ButtonInputHandler::Map(wxControl *control,
|
||||
const wxKeyEvent& event,
|
||||
bool pressed)
|
||||
{
|
||||
int keycode = event.GetKeyCode();
|
||||
if ( keycode == WXK_SPACE || keycode == WXK_RETURN )
|
||||
{
|
||||
return wxACTION_BUTTON_TOGGLE;
|
||||
}
|
||||
|
||||
return wxWin32InputHandler::Map(control, event, pressed);
|
||||
}
|
||||
|
||||
wxControlActions wxWin32ButtonInputHandler::Map(wxControl *control,
|
||||
const wxMouseEvent& event)
|
||||
{
|
||||
if ( event.IsButton() )
|
||||
{
|
||||
if ( event.ButtonDown() )
|
||||
{
|
||||
m_winCapture = wxWindow::FindFocus();
|
||||
m_winCapture->CaptureMouse();
|
||||
}
|
||||
else // up
|
||||
{
|
||||
m_winCapture->ReleaseMouse();
|
||||
}
|
||||
|
||||
return wxACTION_BUTTON_TOGGLE;
|
||||
}
|
||||
|
||||
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