]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/univ/scrarrow.cpp
Add missing WXK constants for the control keys
[wxWidgets.git] / src / univ / scrarrow.cpp
... / ...
CommitLineData
1///////////////////////////////////////////////////////////////////////////////
2// Name: src/univ/scrarrow.cpp
3// Purpose: wxScrollArrows class implementation
4// Author: Vadim Zeitlin
5// Modified by:
6// Created: 22.01.01
7// RCS-ID: $Id$
8// Copyright: (c) 2001 SciTech Software, Inc. (www.scitechsoft.com)
9// Licence: wxWindows licence
10///////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
20#include "wx/wxprec.h"
21
22#ifdef __BORLANDC__
23 #pragma hdrstop
24#endif
25
26#ifndef WX_PRECOMP
27 #include "wx/window.h"
28#endif
29
30#include "wx/univ/scrtimer.h"
31#include "wx/univ/scrarrow.h"
32
33#include "wx/univ/renderer.h"
34#include "wx/univ/inphand.h"
35#include "wx/univ/theme.h"
36
37// ----------------------------------------------------------------------------
38// wxScrollArrowCaptureData: contains the data used while the arrow is being
39// pressed by the user
40// ----------------------------------------------------------------------------
41
42struct wxScrollArrowCaptureData
43{
44 wxScrollArrowCaptureData()
45 {
46 m_arrowPressed = wxScrollArrows::Arrow_None;
47 m_window = NULL;
48 m_btnCapture = -1;
49#if wxUSE_TIMER
50 m_timerScroll = NULL;
51#endif // wxUSE_TIMER
52 }
53
54 ~wxScrollArrowCaptureData()
55 {
56 if ( m_window )
57 m_window->ReleaseMouse();
58
59#if wxUSE_TIMER
60 delete m_timerScroll;
61#endif // wxUSE_TIMER
62 }
63
64 // the arrow being held pressed (may be Arrow_None)
65 wxScrollArrows::Arrow m_arrowPressed;
66
67 // the mouse button which started the capture (-1 if none)
68 int m_btnCapture;
69
70 // the window which has captured the mouse
71 wxWindow *m_window;
72
73#if wxUSE_TIMER
74 // the timer for generating the scroll events
75 wxScrollTimer *m_timerScroll;
76#endif
77};
78
79// ----------------------------------------------------------------------------
80// wxScrollArrowTimer: a wxScrollTimer which calls OnArrow()
81// ----------------------------------------------------------------------------
82
83#if wxUSE_TIMER
84
85class wxScrollArrowTimer : public wxScrollTimer
86{
87public:
88 wxScrollArrowTimer(wxControlWithArrows *control,
89 wxScrollArrows::Arrow arrow)
90 {
91 m_control = control;
92 m_arrow = arrow;
93
94 StartAutoScroll();
95 }
96
97protected:
98 virtual bool DoNotify()
99 {
100 return m_control->OnArrow(m_arrow);
101 }
102
103 wxControlWithArrows *m_control;
104 wxScrollArrows::Arrow m_arrow;
105};
106
107#endif // wxUSE_TIMER
108
109// ============================================================================
110// implementation of wxScrollArrows
111// ============================================================================
112
113// ----------------------------------------------------------------------------
114// con/destruction
115// ----------------------------------------------------------------------------
116
117wxScrollArrows::wxScrollArrows(wxControlWithArrows *control)
118{
119 m_control = control;
120 m_captureData = NULL;
121}
122
123wxScrollArrows::~wxScrollArrows()
124{
125 // it should have been destroyed
126 wxASSERT_MSG( !m_captureData, wxT("memory leak in wxScrollArrows") );
127}
128
129// ----------------------------------------------------------------------------
130// drawing
131// ----------------------------------------------------------------------------
132
133void wxScrollArrows::DrawArrow(Arrow arrow,
134 wxDC& dc,
135 const wxRect& rect,
136 bool scrollbarLike) const
137{
138 static const wxDirection arrowDirs[2][Arrow_Max] =
139 {
140 { wxLEFT, wxRIGHT },
141 { wxUP, wxDOWN }
142 };
143
144 if ( scrollbarLike )
145 m_control->GetRenderer()->DrawScrollbarArrow(
146 dc,
147 arrowDirs[m_control->IsVertical()][arrow],
148 rect,
149 m_control->GetArrowState(arrow));
150 else
151 m_control->GetRenderer()->DrawArrow(
152 dc,
153 arrowDirs[m_control->IsVertical()][arrow],
154 rect,
155 m_control->GetArrowState(arrow));
156}
157
158// ----------------------------------------------------------------------------
159// input handling
160// ----------------------------------------------------------------------------
161
162void wxScrollArrows::UpdateCurrentFlag(Arrow arrow, Arrow arrowCur) const
163{
164 m_control->SetArrowFlag(arrow, wxCONTROL_CURRENT, arrow == arrowCur);
165}
166
167bool wxScrollArrows::HandleMouseMove(const wxMouseEvent& event) const
168{
169 Arrow arrow;
170 if ( event.Leaving() )
171 {
172 // no arrow has mouse if it left the window completely
173 arrow = Arrow_None;
174 }
175 else // Moving() or Entering(), treat them the same here
176 {
177 arrow = m_control->HitTestArrow(event.GetPosition());
178 }
179
180#if wxUSE_TIMER
181 if ( m_captureData && m_captureData->m_timerScroll)
182 {
183 // the mouse is captured, we may want to pause scrolling if it goes
184 // outside the arrow or to resume it if we had paused it before
185 wxTimer *timer = m_captureData->m_timerScroll;
186 if ( !timer->IsRunning() )
187 {
188 // timer is paused
189 if ( arrow == m_captureData->m_arrowPressed )
190 {
191 // resume now
192 m_control->SetArrowFlag(arrow, wxCONTROL_PRESSED, true);
193 timer->Start();
194
195 return true;
196 }
197 }
198 else // if ( 1 ) FIXME: m_control->ShouldPauseScrolling() )
199 {
200 // we may want to stop it
201 if ( arrow != m_captureData->m_arrowPressed )
202 {
203 // stop as the mouse left the arrow
204 m_control->SetArrowFlag(m_captureData->m_arrowPressed,
205 wxCONTROL_PRESSED, false);
206 timer->Stop();
207
208 return true;
209 }
210 }
211
212 return false;
213 }
214#endif // wxUSE_TIMER
215
216 // reset the wxCONTROL_CURRENT flag for the arrows which don't have the
217 // mouse and set it for the one which has
218 UpdateCurrentFlag(Arrow_First, arrow);
219 UpdateCurrentFlag(Arrow_Second, arrow);
220
221 // return true if it was really an event for an arrow
222 return !event.Leaving() && arrow != Arrow_None;
223}
224
225bool wxScrollArrows::HandleMouse(const wxMouseEvent& event) const
226{
227 int btn = event.GetButton();
228 if ( btn == -1 )
229 {
230 // we only care about button press/release events
231 return false;
232 }
233
234 if ( event.ButtonDown() || event.ButtonDClick() )
235 {
236 if ( !m_captureData )
237 {
238 Arrow arrow = m_control->HitTestArrow(event.GetPosition());
239 if ( arrow == Arrow_None )
240 {
241 // mouse pressed over something else
242 return false;
243 }
244
245 if ( m_control->GetArrowState(arrow) & wxCONTROL_DISABLED )
246 {
247 // don't allow to press disabled arrows
248 return true;
249 }
250
251 wxConstCast(this, wxScrollArrows)->m_captureData =
252 new wxScrollArrowCaptureData;
253 m_captureData->m_arrowPressed = arrow;
254 m_captureData->m_btnCapture = btn;
255 m_captureData->m_window = m_control->GetWindow();
256 m_captureData->m_window->CaptureMouse();
257
258#if wxUSE_TIMER
259 // start scrolling
260 wxScrollArrowTimer *tmpTimerScroll =
261 new wxScrollArrowTimer(m_control, arrow);
262#endif // wxUSE_TIMER
263
264 // Because in some cases wxScrollArrowTimer can cause
265 // m_captureData to be destructed we need to test if it
266 // is still valid before using.
267 if (m_captureData)
268 {
269#if wxUSE_TIMER
270 m_captureData->m_timerScroll = tmpTimerScroll;
271#endif // wxUSE_TIMER
272
273 m_control->SetArrowFlag(arrow, wxCONTROL_PRESSED, true);
274 }
275 else
276 {
277#if wxUSE_TIMER
278 delete tmpTimerScroll;
279#endif // wxUSE_TIMER
280 }
281 }
282 //else: mouse already captured, nothing to do
283 }
284 // release mouse if the *same* button went up
285 else if ( m_captureData && (btn == m_captureData->m_btnCapture) )
286 {
287 Arrow arrow = m_captureData->m_arrowPressed;
288
289 delete m_captureData;
290 wxConstCast(this, wxScrollArrows)->m_captureData = NULL;
291
292 m_control->SetArrowFlag(arrow, wxCONTROL_PRESSED, false);
293 }
294 else
295 {
296 // we don't process this
297 return false;
298 }
299
300 return true;
301}