Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include <limits.h>
31 : : #include <tools/time.hxx>
32 : : #include <tools/debug.hxx>
33 : :
34 : : #include <svids.hrc>
35 : : #include <svdata.hxx>
36 : : #include <scrwnd.hxx>
37 : :
38 : : #include <vcl/timer.hxx>
39 : : #include <vcl/event.hxx>
40 : :
41 : : #include <math.h>
42 : : #include <limits.h>
43 : :
44 : : // -----------
45 : : // - Defines -
46 : : // -----------
47 : :
48 : : #define WHEEL_WIDTH 25
49 : : #define WHEEL_RADIUS ((WHEEL_WIDTH) >> 1 )
50 : : #define MAX_TIME 300
51 : : #define MIN_TIME 20
52 : : #define DEF_TIMEOUT 50
53 : :
54 : : // -------------------
55 : : // - ImplWheelWindow -
56 : : // -------------------
57 : :
58 : 0 : ImplWheelWindow::ImplWheelWindow( Window* pParent ) :
59 : : FloatingWindow ( pParent, 0 ),
60 : : mnRepaintTime ( 1UL ),
61 : : mnTimeout ( DEF_TIMEOUT ),
62 : : mnWheelMode ( WHEELMODE_NONE ),
63 : : mnActDist ( 0UL ),
64 : : mnActDeltaX ( 0L ),
65 [ # # ][ # # ]: 0 : mnActDeltaY ( 0L )
[ # # ]
66 : : {
67 : : // we need a parent
68 : : DBG_ASSERT( pParent, "ImplWheelWindow::ImplWheelWindow(): Parent not set!" );
69 : :
70 : 0 : const Size aSize( pParent->GetOutputSizePixel() );
71 [ # # ]: 0 : const sal_uInt16 nFlags = ImplGetSVData()->maWinData.mnAutoScrollFlags;
72 : 0 : const sal_Bool bHorz = ( nFlags & AUTOSCROLL_HORZ ) != 0;
73 : 0 : const sal_Bool bVert = ( nFlags & AUTOSCROLL_VERT ) != 0;
74 : :
75 : : // calculate maximum speed distance
76 : 0 : mnMaxWidth = (sal_uLong) ( 0.4 * hypot( (double) aSize.Width(), aSize.Height() ) );
77 : :
78 : : // create wheel window
79 [ # # ]: 0 : SetTitleType( FLOATWIN_TITLE_NONE );
80 [ # # ]: 0 : ImplCreateImageList();
81 [ # # ]: 0 : ResMgr* pResMgr = ImplGetResMgr();
82 [ # # ]: 0 : Bitmap aBmp;
83 [ # # ]: 0 : if( pResMgr )
84 [ # # ][ # # ]: 0 : aBmp = Bitmap( ResId( SV_RESID_BITMAP_SCROLLMSK, *pResMgr ) );
[ # # ]
85 [ # # ]: 0 : ImplSetRegion( aBmp );
86 : :
87 : : // set wheel mode
88 [ # # ][ # # ]: 0 : if( bHorz && bVert )
89 [ # # ]: 0 : ImplSetWheelMode( WHEELMODE_VH );
90 [ # # ]: 0 : else if( bHorz )
91 [ # # ]: 0 : ImplSetWheelMode( WHEELMODE_H );
92 : : else
93 [ # # ]: 0 : ImplSetWheelMode( WHEELMODE_V );
94 : :
95 : : // init timer
96 [ # # ][ # # ]: 0 : mpTimer = new Timer;
97 [ # # ]: 0 : mpTimer->SetTimeoutHdl( LINK( this, ImplWheelWindow, ImplScrollHdl ) );
98 [ # # ]: 0 : mpTimer->SetTimeout( mnTimeout );
99 [ # # ]: 0 : mpTimer->Start();
100 : :
101 [ # # ][ # # ]: 0 : CaptureMouse();
102 : 0 : }
103 : :
104 : : // ------------------------------------------------------------------------
105 : :
106 [ # # ][ # # ]: 0 : ImplWheelWindow::~ImplWheelWindow()
107 : : {
108 [ # # ]: 0 : ImplStop();
109 [ # # ][ # # ]: 0 : delete mpTimer;
110 [ # # ]: 0 : }
111 : :
112 : : // ------------------------------------------------------------------------
113 : :
114 : 0 : void ImplWheelWindow::ImplStop()
115 : : {
116 : 0 : ReleaseMouse();
117 : 0 : mpTimer->Stop();
118 : 0 : Show(sal_False);
119 : 0 : }
120 : :
121 : : // ------------------------------------------------------------------------
122 : :
123 : 0 : void ImplWheelWindow::ImplSetRegion( const Bitmap& rRegionBmp )
124 : : {
125 [ # # ]: 0 : Point aPos( GetPointerPosPixel() );
126 [ # # ]: 0 : const Size aSize( rRegionBmp.GetSizePixel() );
127 : 0 : Point aPoint;
128 [ # # ]: 0 : const Rectangle aRect( aPoint, aSize );
129 : :
130 : 0 : maCenter = maLastMousePos = aPos;
131 : 0 : aPos.X() -= aSize.Width() >> 1;
132 : 0 : aPos.Y() -= aSize.Height() >> 1;
133 : :
134 [ # # ]: 0 : SetPosSizePixel( aPos, aSize );
135 [ # # ][ # # ]: 0 : SetWindowRegionPixel( rRegionBmp.CreateRegion( COL_BLACK, aRect ) );
[ # # ]
136 : 0 : }
137 : :
138 : : // ------------------------------------------------------------------------
139 : :
140 : 0 : void ImplWheelWindow::ImplCreateImageList()
141 : : {
142 : 0 : ResMgr* pResMgr = ImplGetResMgr();
143 [ # # ]: 0 : if( pResMgr )
144 : : maImgList.InsertFromHorizontalBitmap
145 [ # # ]: 0 : ( ResId( SV_RESID_BITMAP_SCROLLBMP, *pResMgr ), 6, NULL );
146 : 0 : }
147 : :
148 : : // ------------------------------------------------------------------------
149 : :
150 : 0 : void ImplWheelWindow::ImplSetWheelMode( sal_uLong nWheelMode )
151 : : {
152 [ # # ]: 0 : if( nWheelMode != mnWheelMode )
153 : : {
154 : 0 : mnWheelMode = nWheelMode;
155 : :
156 [ # # ]: 0 : if( WHEELMODE_NONE == mnWheelMode )
157 : : {
158 [ # # ]: 0 : if( IsVisible() )
159 : 0 : Hide();
160 : : }
161 : : else
162 : : {
163 [ # # ]: 0 : if( !IsVisible() )
164 : 0 : Show();
165 : :
166 : 0 : ImplDrawWheel();
167 : : }
168 : : }
169 : 0 : }
170 : :
171 : : // ------------------------------------------------------------------------
172 : :
173 : 0 : void ImplWheelWindow::ImplDrawWheel()
174 : : {
175 : : sal_uInt16 nId;
176 : :
177 [ # # # # : 0 : switch( mnWheelMode )
# # # ]
178 : : {
179 : 0 : case( WHEELMODE_VH ): nId = 1; break;
180 : 0 : case( WHEELMODE_V ): nId = 2; break;
181 : 0 : case( WHEELMODE_H ): nId = 3; break;
182 : 0 : case( WHEELMODE_SCROLL_VH ):nId = 4; break;
183 : 0 : case( WHEELMODE_SCROLL_V ): nId = 5; break;
184 : 0 : case( WHEELMODE_SCROLL_H ): nId = 6; break;
185 : 0 : default: nId = 0; break;
186 : : }
187 : :
188 [ # # ]: 0 : if( nId )
189 [ # # ]: 0 : DrawImage( Point(), maImgList.GetImage( nId ) );
190 : 0 : }
191 : :
192 : : // ------------------------------------------------------------------------
193 : :
194 : 0 : void ImplWheelWindow::ImplRecalcScrollValues()
195 : : {
196 [ # # ]: 0 : if( mnActDist < WHEEL_RADIUS )
197 : : {
198 : 0 : mnActDeltaX = mnActDeltaY = 0L;
199 : 0 : mnTimeout = DEF_TIMEOUT;
200 : : }
201 : : else
202 : : {
203 : : sal_uLong nCurTime;
204 : :
205 : : // calc current time
206 [ # # ]: 0 : if( mnMaxWidth )
207 : : {
208 : 0 : const double fExp = ( (double) mnActDist / mnMaxWidth ) * log10( (double) MAX_TIME / MIN_TIME );
209 : 0 : nCurTime = (sal_uLong) ( MAX_TIME / pow( 10., fExp ) );
210 : : }
211 : : else
212 : 0 : nCurTime = MAX_TIME;
213 : :
214 [ # # ]: 0 : if( !nCurTime )
215 : 0 : nCurTime = 1UL;
216 : :
217 [ # # ]: 0 : if( mnRepaintTime <= nCurTime )
218 : 0 : mnTimeout = nCurTime - mnRepaintTime;
219 : : else
220 : : {
221 : 0 : long nMult = mnRepaintTime / nCurTime;
222 : :
223 [ # # ]: 0 : if( !( mnRepaintTime % nCurTime ) )
224 : 0 : mnTimeout = 0UL;
225 : : else
226 : 0 : mnTimeout = ++nMult * nCurTime - mnRepaintTime;
227 : :
228 : 0 : double fValX = (double) mnActDeltaX * nMult;
229 : 0 : double fValY = (double) mnActDeltaY * nMult;
230 : :
231 [ # # ]: 0 : if( fValX > LONG_MAX )
232 : 0 : mnActDeltaX = LONG_MAX;
233 [ # # ]: 0 : else if( fValX < LONG_MIN )
234 : 0 : mnActDeltaX = LONG_MIN;
235 : : else
236 : 0 : mnActDeltaX = (long) fValX;
237 : :
238 [ # # ]: 0 : if( fValY > LONG_MAX )
239 : 0 : mnActDeltaY = LONG_MAX;
240 [ # # ]: 0 : else if( fValY < LONG_MIN )
241 : 0 : mnActDeltaY = LONG_MIN;
242 : : else
243 : 0 : mnActDeltaY = (long) fValY;
244 : : }
245 : : }
246 : 0 : }
247 : :
248 : : // ------------------------------------------------------------------------
249 : :
250 : 0 : PointerStyle ImplWheelWindow::ImplGetMousePointer( long nDistX, long nDistY )
251 : : {
252 : : PointerStyle eStyle;
253 : 0 : const sal_uInt16 nFlags = ImplGetSVData()->maWinData.mnAutoScrollFlags;
254 : 0 : const sal_Bool bHorz = ( nFlags & AUTOSCROLL_HORZ ) != 0;
255 : 0 : const sal_Bool bVert = ( nFlags & AUTOSCROLL_VERT ) != 0;
256 : :
257 [ # # ][ # # ]: 0 : if( bHorz || bVert )
258 : : {
259 [ # # ]: 0 : if( mnActDist < WHEEL_RADIUS )
260 : : {
261 [ # # ][ # # ]: 0 : if( bHorz && bVert )
262 : 0 : eStyle = POINTER_AUTOSCROLL_NSWE;
263 [ # # ]: 0 : else if( bHorz )
264 : 0 : eStyle = POINTER_AUTOSCROLL_WE;
265 : : else
266 : 0 : eStyle = POINTER_AUTOSCROLL_NS;
267 : : }
268 : : else
269 : : {
270 : 0 : double fAngle = atan2( (double) -nDistY, nDistX ) / F_PI180;
271 : :
272 [ # # ]: 0 : if( fAngle < 0.0 )
273 : 0 : fAngle += 360.;
274 : :
275 [ # # ][ # # ]: 0 : if( bHorz && bVert )
276 : : {
277 [ # # ][ # # ]: 0 : if( fAngle >= 22.5 && fAngle <= 67.5 )
278 : 0 : eStyle = POINTER_AUTOSCROLL_NE;
279 [ # # ][ # # ]: 0 : else if( fAngle >= 67.5 && fAngle <= 112.5 )
280 : 0 : eStyle = POINTER_AUTOSCROLL_N;
281 [ # # ][ # # ]: 0 : else if( fAngle >= 112.5 && fAngle <= 157.5 )
282 : 0 : eStyle = POINTER_AUTOSCROLL_NW;
283 [ # # ][ # # ]: 0 : else if( fAngle >= 157.5 && fAngle <= 202.5 )
284 : 0 : eStyle = POINTER_AUTOSCROLL_W;
285 [ # # ][ # # ]: 0 : else if( fAngle >= 202.5 && fAngle <= 247.5 )
286 : 0 : eStyle = POINTER_AUTOSCROLL_SW;
287 [ # # ][ # # ]: 0 : else if( fAngle >= 247.5 && fAngle <= 292.5 )
288 : 0 : eStyle = POINTER_AUTOSCROLL_S;
289 [ # # ][ # # ]: 0 : else if( fAngle >= 292.5 && fAngle <= 337.5 )
290 : 0 : eStyle = POINTER_AUTOSCROLL_SE;
291 : : else
292 : 0 : eStyle = POINTER_AUTOSCROLL_E;
293 : : }
294 [ # # ]: 0 : else if( bHorz )
295 : : {
296 [ # # ][ # # ]: 0 : if( fAngle >= 270. || fAngle <= 90. )
297 : 0 : eStyle = POINTER_AUTOSCROLL_E;
298 : : else
299 : 0 : eStyle = POINTER_AUTOSCROLL_W;
300 : : }
301 : : else
302 : : {
303 [ # # ][ # # ]: 0 : if( fAngle >= 0. && fAngle <= 180. )
304 : 0 : eStyle = POINTER_AUTOSCROLL_N;
305 : : else
306 : 0 : eStyle = POINTER_AUTOSCROLL_S;
307 : : }
308 : 0 : }
309 : : }
310 : : else
311 : 0 : eStyle = POINTER_ARROW;
312 : :
313 : 0 : return eStyle;
314 : : }
315 : :
316 : : // ------------------------------------------------------------------------
317 : :
318 : 0 : void ImplWheelWindow::Paint( const Rectangle& )
319 : : {
320 : 0 : ImplDrawWheel();
321 : 0 : }
322 : :
323 : : // ------------------------------------------------------------------------
324 : :
325 : 0 : void ImplWheelWindow::MouseMove( const MouseEvent& rMEvt )
326 : : {
327 [ # # ]: 0 : FloatingWindow::MouseMove( rMEvt );
328 : :
329 [ # # ]: 0 : const Point aMousePos( OutputToScreenPixel( rMEvt.GetPosPixel() ) );
330 : 0 : const long nDistX = aMousePos.X() - maCenter.X();
331 : 0 : const long nDistY = aMousePos.Y() - maCenter.Y();
332 : :
333 : 0 : mnActDist = (sal_uLong) hypot( (double) nDistX, nDistY );
334 : :
335 [ # # ]: 0 : const PointerStyle eActStyle = ImplGetMousePointer( nDistX, nDistY );
336 [ # # ]: 0 : const sal_uInt16 nFlags = ImplGetSVData()->maWinData.mnAutoScrollFlags;
337 : 0 : const sal_Bool bHorz = ( nFlags & AUTOSCROLL_HORZ ) != 0;
338 : 0 : const sal_Bool bVert = ( nFlags & AUTOSCROLL_VERT ) != 0;
339 : 0 : const sal_Bool bOuter = mnActDist > WHEEL_RADIUS;
340 : :
341 [ # # ][ # # ]: 0 : if( bOuter && ( maLastMousePos != aMousePos ) )
[ # # ]
342 : : {
343 [ # # # # : 0 : switch( eActStyle )
# # # #
# ]
344 : : {
345 : 0 : case( POINTER_AUTOSCROLL_N ): mnActDeltaX = +0L, mnActDeltaY = +1L; break;
346 : 0 : case( POINTER_AUTOSCROLL_S ): mnActDeltaX = +0L, mnActDeltaY = -1L; break;
347 : 0 : case( POINTER_AUTOSCROLL_W ): mnActDeltaX = +1L, mnActDeltaY = +0L; break;
348 : 0 : case( POINTER_AUTOSCROLL_E ): mnActDeltaX = -1L, mnActDeltaY = +0L; break;
349 : 0 : case( POINTER_AUTOSCROLL_NW ): mnActDeltaX = +1L, mnActDeltaY = +1L; break;
350 : 0 : case( POINTER_AUTOSCROLL_NE ): mnActDeltaX = -1L, mnActDeltaY = +1L; break;
351 : 0 : case( POINTER_AUTOSCROLL_SW ): mnActDeltaX = +1L, mnActDeltaY = -1L; break;
352 : 0 : case( POINTER_AUTOSCROLL_SE ): mnActDeltaX = -1L, mnActDeltaY = -1L; break;
353 : :
354 : : default:
355 : 0 : break;
356 : : }
357 : : }
358 : :
359 : 0 : ImplRecalcScrollValues();
360 : 0 : maLastMousePos = aMousePos;
361 [ # # ]: 0 : SetPointer( eActStyle );
362 : :
363 [ # # ][ # # ]: 0 : if( bHorz && bVert )
364 [ # # ][ # # ]: 0 : ImplSetWheelMode( bOuter ? WHEELMODE_SCROLL_VH : WHEELMODE_VH );
365 [ # # ]: 0 : else if( bHorz )
366 [ # # ][ # # ]: 0 : ImplSetWheelMode( bOuter ? WHEELMODE_SCROLL_H : WHEELMODE_H );
367 : : else
368 [ # # ][ # # ]: 0 : ImplSetWheelMode( bOuter ? WHEELMODE_SCROLL_V : WHEELMODE_V );
369 : 0 : }
370 : :
371 : : // ------------------------------------------------------------------------
372 : :
373 : 0 : void ImplWheelWindow::MouseButtonUp( const MouseEvent& rMEvt )
374 : : {
375 [ # # ]: 0 : if( mnActDist > WHEEL_RADIUS )
376 : 0 : GetParent()->EndAutoScroll();
377 : : else
378 : 0 : FloatingWindow::MouseButtonUp( rMEvt );
379 : 0 : }
380 : :
381 : : // ------------------------------------------------------------------------
382 : :
383 : 0 : IMPL_LINK_NOARG(ImplWheelWindow, ImplScrollHdl)
384 : : {
385 [ # # ][ # # ]: 0 : if ( mnActDeltaX || mnActDeltaY )
386 : : {
387 [ # # ]: 0 : Window* pWindow = GetParent();
388 [ # # ][ # # ]: 0 : const Point aMousePos( pWindow->OutputToScreenPixel( pWindow->GetPointerPosPixel() ) );
389 [ # # ]: 0 : Point aCmdMousePos( pWindow->ImplFrameToOutput( aMousePos ) );
390 [ # # ]: 0 : CommandScrollData aScrollData( mnActDeltaX, mnActDeltaY );
391 [ # # ]: 0 : CommandEvent aCEvt( aCmdMousePos, COMMAND_AUTOSCROLL, sal_True, &aScrollData );
392 [ # # ]: 0 : NotifyEvent aNCmdEvt( EVENT_COMMAND, pWindow, &aCEvt );
393 : :
394 [ # # ][ # # ]: 0 : if ( !ImplCallPreNotify( aNCmdEvt ) )
395 : : {
396 [ # # ]: 0 : const sal_uLong nTime = Time::GetSystemTicks();
397 [ # # ]: 0 : ImplDelData aDel( this );
398 [ # # ]: 0 : pWindow->Command( aCEvt );
399 [ # # ]: 0 : if( aDel.IsDead() )
400 : 0 : return 0;
401 [ # # ]: 0 : mnRepaintTime = Max( Time::GetSystemTicks() - nTime, (sal_uLong)1 );
402 [ # # ][ # # ]: 0 : ImplRecalcScrollValues();
403 : : }
404 : : }
405 : :
406 [ # # ]: 0 : if ( mnTimeout != mpTimer->GetTimeout() )
407 : 0 : mpTimer->SetTimeout( mnTimeout );
408 : 0 : mpTimer->Start();
409 : :
410 : 0 : return 0L;
411 : : }
412 : :
413 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|