1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/univ/scrarrow.cpp
3 // Purpose: wxScrollArrows class implementation
4 // Author: Vadim Zeitlin
8 // Copyright: (c) 2001 SciTech Software, Inc. (www.scitechsoft.com)
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
21 #pragma implementation "univscrarrow.h"
24 #include "wx/wxprec.h"
33 #include "wx/univ/scrtimer.h"
34 #include "wx/univ/scrarrow.h"
36 #include "wx/univ/renderer.h"
37 #include "wx/univ/inphand.h"
38 #include "wx/univ/theme.h"
40 // ----------------------------------------------------------------------------
41 // wxScrollArrowCaptureData: contains the data used while the arrow is being
42 // pressed by the user
43 // ----------------------------------------------------------------------------
45 struct wxScrollArrowCaptureData
47 wxScrollArrowCaptureData()
49 m_arrowPressed
= wxScrollArrows::Arrow_None
;
55 ~wxScrollArrowCaptureData()
58 m_window
->ReleaseMouse();
63 // the arrow being held pressed (may be Arrow_None)
64 wxScrollArrows::Arrow m_arrowPressed
;
66 // the mouse button which started the capture (-1 if none)
69 // the window which has captured the mouse
72 // the timer for generating the scroll events
73 wxScrollTimer
*m_timerScroll
;
76 // ----------------------------------------------------------------------------
77 // wxScrollArrowTimer: a wxScrollTimer which calls OnArrow()
78 // ----------------------------------------------------------------------------
80 class wxScrollArrowTimer
: public wxScrollTimer
83 wxScrollArrowTimer(wxControlWithArrows
*control
,
84 wxScrollArrows::Arrow arrow
)
93 virtual bool DoNotify()
95 return m_control
->OnArrow(m_arrow
);
98 wxControlWithArrows
*m_control
;
99 wxScrollArrows::Arrow m_arrow
;
102 // ============================================================================
103 // implementation of wxScrollArrows
104 // ============================================================================
106 // ----------------------------------------------------------------------------
108 // ----------------------------------------------------------------------------
110 wxScrollArrows::wxScrollArrows(wxControlWithArrows
*control
)
113 m_captureData
= NULL
;
116 wxScrollArrows::~wxScrollArrows()
118 // it should have been destroyed
119 wxASSERT_MSG( !m_captureData
, _T("memory leak in wxScrollArrows") );
122 // ----------------------------------------------------------------------------
124 // ----------------------------------------------------------------------------
126 void wxScrollArrows::DrawArrow(Arrow arrow
,
129 bool scrollbarLike
) const
131 static const wxDirection arrowDirs
[2][Arrow_Max
] =
137 void (wxRenderer::*pfn
)(wxDC
&, wxDirection
, const wxRect
&, int) =
138 scrollbarLike
? &wxRenderer::DrawScrollbarArrow
139 : &wxRenderer::DrawArrow
;
141 (m_control
->GetRenderer()->*pfn
)
144 arrowDirs
[m_control
->IsVertical()][arrow
],
146 m_control
->GetArrowState(arrow
)
150 // ----------------------------------------------------------------------------
152 // ----------------------------------------------------------------------------
154 void wxScrollArrows::UpdateCurrentFlag(Arrow arrow
, Arrow arrowCur
) const
156 m_control
->SetArrowFlag(arrow
, wxCONTROL_CURRENT
, arrow
== arrowCur
);
159 bool wxScrollArrows::HandleMouseMove(const wxMouseEvent
& event
) const
162 if ( event
.Leaving() )
164 // no arrow has mouse if it left the window completely
167 else // Moving() or Entering(), treat them the same here
169 arrow
= m_control
->HitTest(event
.GetPosition());
174 // the mouse is captured, we may want to pause scrolling if it goes
175 // outside the arrow or to resume it if we had paused it before
176 wxTimer
*timer
= m_captureData
->m_timerScroll
;
177 if ( !timer
->IsRunning() )
180 if ( arrow
== m_captureData
->m_arrowPressed
)
183 m_control
->SetArrowFlag(arrow
, wxCONTROL_PRESSED
, TRUE
);
189 else if ( 1 ) //FIXME: m_control->ShouldPauseScrolling() )
191 // we may want to stop it
192 if ( arrow
!= m_captureData
->m_arrowPressed
)
194 // stop as the mouse left the arrow
195 m_control
->SetArrowFlag(m_captureData
->m_arrowPressed
,
196 wxCONTROL_PRESSED
, FALSE
);
206 // reset the wxCONTROL_CURRENT flag for the arrows which don't have the
207 // mouse and set it for the one which has
208 UpdateCurrentFlag(Arrow_First
, arrow
);
209 UpdateCurrentFlag(Arrow_Second
, arrow
);
211 // return TRUE if it was really an event for an arrow
212 return !event
.Leaving() && arrow
!= Arrow_None
;
215 bool wxScrollArrows::HandleMouse(const wxMouseEvent
& event
) const
217 int btn
= event
.GetButton();
220 // we only care about button press/release events
224 if ( event
.ButtonDown() || event
.ButtonDClick() )
226 if ( !m_captureData
)
228 Arrow arrow
= m_control
->HitTest(event
.GetPosition());
229 if ( arrow
== Arrow_None
)
231 // mouse pressed over something else
235 if ( m_control
->GetArrowState(arrow
) & wxCONTROL_DISABLED
)
237 // don't allow to press disabled arrows
241 wxConstCast(this, wxScrollArrows
)->m_captureData
=
242 new wxScrollArrowCaptureData
;
243 m_captureData
->m_arrowPressed
= arrow
;
244 m_captureData
->m_btnCapture
= btn
;
245 m_captureData
->m_window
= m_control
->GetWindow();
246 m_captureData
->m_window
->CaptureMouse();
249 m_captureData
->m_timerScroll
=
250 new wxScrollArrowTimer(m_control
, arrow
);
252 m_control
->SetArrowFlag(arrow
, wxCONTROL_PRESSED
, TRUE
);
254 //else: mouse already captured, nothing to do
256 // release mouse if the *same* button went up
257 else if ( m_captureData
&& (btn
== m_captureData
->m_btnCapture
) )
259 Arrow arrow
= m_captureData
->m_arrowPressed
;
261 delete m_captureData
;
262 wxConstCast(this, wxScrollArrows
)->m_captureData
= NULL
;
264 m_control
->SetArrowFlag(arrow
, wxCONTROL_PRESSED
, FALSE
);
268 // we don't process this