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