merge the formfield patch from ooo-build
[ooovba.git] / vcl / source / window / scrwnd.cxx
blobca41a7391abe27c7902e0504827943b1a85c8b4c
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: scrwnd.cxx,v $
10 * $Revision: 1.15 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_vcl.hxx"
34 // #include <math.h>
35 #include <limits.h>
36 #include <tools/time.hxx>
37 #include <tools/debug.hxx>
39 #ifndef _SV_SVIDS_HRC
40 #include <vcl/svids.hrc>
41 #endif
42 #include <vcl/svdata.hxx>
43 #ifndef _VCL_TIMER_HXX
44 #include <vcl/timer.hxx>
45 #endif
46 #ifndef _VCL_EVENT_HXX
47 #include <vcl/event.hxx>
48 #endif
49 #ifndef _VCL_SCRWND_HXX
50 #include <scrwnd.hxx>
51 #endif
53 #include <math.h>
54 #include <limits.h>
56 // -----------
57 // - Defines -
58 // -----------
60 #define WHEEL_WIDTH 25
61 #define WHEEL_RADIUS ((WHEEL_WIDTH) >> 1 )
62 #define MAX_TIME 300
63 #define MIN_TIME 20
64 #define DEF_TIMEOUT 50
66 // -------------------
67 // - ImplWheelWindow -
68 // -------------------
70 ImplWheelWindow::ImplWheelWindow( Window* pParent ) :
71 FloatingWindow ( pParent, 0 ),
72 mnRepaintTime ( 1UL ),
73 mnTimeout ( DEF_TIMEOUT ),
74 mnWheelMode ( WHEELMODE_NONE ),
75 mnActDist ( 0UL ),
76 mnActDeltaX ( 0L ),
77 mnActDeltaY ( 0L )
79 // we need a parent
80 DBG_ASSERT( pParent, "ImplWheelWindow::ImplWheelWindow(): Parent not set!" );
82 const Size aSize( pParent->GetOutputSizePixel() );
83 const USHORT nFlags = ImplGetSVData()->maWinData.mnAutoScrollFlags;
84 const BOOL bHorz = ( nFlags & AUTOSCROLL_HORZ ) != 0;
85 const BOOL bVert = ( nFlags & AUTOSCROLL_VERT ) != 0;
87 // calculate maximum speed distance
88 mnMaxWidth = (ULONG) ( 0.4 * hypot( (double) aSize.Width(), aSize.Height() ) );
90 // create wheel window
91 SetTitleType( FLOATWIN_TITLE_NONE );
92 ImplCreateImageList();
93 ResMgr* pResMgr = ImplGetResMgr();
94 Bitmap aBmp;
95 if( pResMgr )
96 aBmp = Bitmap( ResId( SV_RESID_BITMAP_SCROLLMSK, *pResMgr ) );
97 ImplSetRegion( aBmp );
99 // set wheel mode
100 if( bHorz && bVert )
101 ImplSetWheelMode( WHEELMODE_VH );
102 else if( bHorz )
103 ImplSetWheelMode( WHEELMODE_H );
104 else
105 ImplSetWheelMode( WHEELMODE_V );
107 // init timer
108 mpTimer = new Timer;
109 mpTimer->SetTimeoutHdl( LINK( this, ImplWheelWindow, ImplScrollHdl ) );
110 mpTimer->SetTimeout( mnTimeout );
111 mpTimer->Start();
113 CaptureMouse();
116 // ------------------------------------------------------------------------
118 ImplWheelWindow::~ImplWheelWindow()
120 ImplStop();
121 delete mpTimer;
124 // ------------------------------------------------------------------------
126 void ImplWheelWindow::ImplStop()
128 ReleaseMouse();
129 mpTimer->Stop();
130 Show(FALSE);
133 // ------------------------------------------------------------------------
135 void ImplWheelWindow::ImplSetRegion( const Bitmap& rRegionBmp )
137 Point aPos( GetPointerPosPixel() );
138 const Size aSize( rRegionBmp.GetSizePixel() );
139 Point aPoint;
140 const Rectangle aRect( aPoint, aSize );
142 maCenter = maLastMousePos = aPos;
143 aPos.X() -= aSize.Width() >> 1;
144 aPos.Y() -= aSize.Height() >> 1;
146 SetPosSizePixel( aPos, aSize );
147 SetWindowRegionPixel( rRegionBmp.CreateRegion( COL_BLACK, aRect ) );
150 // ------------------------------------------------------------------------
152 void ImplWheelWindow::ImplCreateImageList()
154 ResMgr* pResMgr = ImplGetResMgr();
155 if( pResMgr )
156 maImgList.InsertFromHorizontalBitmap
157 ( ResId( SV_RESID_BITMAP_SCROLLBMP, *pResMgr ), 6, NULL );
160 // ------------------------------------------------------------------------
162 void ImplWheelWindow::ImplSetWheelMode( ULONG nWheelMode )
164 if( nWheelMode != mnWheelMode )
166 mnWheelMode = nWheelMode;
168 if( WHEELMODE_NONE == mnWheelMode )
170 if( IsVisible() )
171 Hide();
173 else
175 if( !IsVisible() )
176 Show();
178 ImplDrawWheel();
183 // ------------------------------------------------------------------------
185 void ImplWheelWindow::ImplDrawWheel()
187 USHORT nId;
189 switch( mnWheelMode )
191 case( WHEELMODE_VH ): nId = 1; break;
192 case( WHEELMODE_V ): nId = 2; break;
193 case( WHEELMODE_H ): nId = 3; break;
194 case( WHEELMODE_SCROLL_VH ):nId = 4; break;
195 case( WHEELMODE_SCROLL_V ): nId = 5; break;
196 case( WHEELMODE_SCROLL_H ): nId = 6; break;
197 default: nId = 0; break;
200 if( nId )
201 DrawImage( Point(), maImgList.GetImage( nId ) );
204 // ------------------------------------------------------------------------
206 void ImplWheelWindow::ImplRecalcScrollValues()
208 if( mnActDist < WHEEL_RADIUS )
210 mnActDeltaX = mnActDeltaY = 0L;
211 mnTimeout = DEF_TIMEOUT;
213 else
215 ULONG nCurTime;
217 // calc current time
218 if( mnMaxWidth )
220 const double fExp = ( (double) mnActDist / mnMaxWidth ) * log10( (double) MAX_TIME / MIN_TIME );
221 nCurTime = (ULONG) ( MAX_TIME / pow( 10., fExp ) );
223 else
224 nCurTime = MAX_TIME;
226 if( !nCurTime )
227 nCurTime = 1UL;
229 if( mnRepaintTime <= nCurTime )
230 mnTimeout = nCurTime - mnRepaintTime;
231 else
233 long nMult = mnRepaintTime / nCurTime;
235 if( !( mnRepaintTime % nCurTime ) )
236 mnTimeout = 0UL;
237 else
238 mnTimeout = ++nMult * nCurTime - mnRepaintTime;
240 double fValX = (double) mnActDeltaX * nMult;
241 double fValY = (double) mnActDeltaY * nMult;
243 if( fValX > LONG_MAX )
244 mnActDeltaX = LONG_MAX;
245 else if( fValX < LONG_MIN )
246 mnActDeltaX = LONG_MIN;
247 else
248 mnActDeltaX = (long) fValX;
250 if( fValY > LONG_MAX )
251 mnActDeltaY = LONG_MAX;
252 else if( fValY < LONG_MIN )
253 mnActDeltaY = LONG_MIN;
254 else
255 mnActDeltaY = (long) fValY;
260 // ------------------------------------------------------------------------
262 PointerStyle ImplWheelWindow::ImplGetMousePointer( long nDistX, long nDistY )
264 PointerStyle eStyle;
265 const USHORT nFlags = ImplGetSVData()->maWinData.mnAutoScrollFlags;
266 const BOOL bHorz = ( nFlags & AUTOSCROLL_HORZ ) != 0;
267 const BOOL bVert = ( nFlags & AUTOSCROLL_VERT ) != 0;
269 if( bHorz || bVert )
271 if( mnActDist < WHEEL_RADIUS )
273 if( bHorz && bVert )
274 eStyle = POINTER_AUTOSCROLL_NSWE;
275 else if( bHorz )
276 eStyle = POINTER_AUTOSCROLL_WE;
277 else
278 eStyle = POINTER_AUTOSCROLL_NS;
280 else
282 double fAngle = atan2( (double) -nDistY, nDistX ) / F_PI180;
284 if( fAngle < 0.0 )
285 fAngle += 360.;
287 if( bHorz && bVert )
289 if( fAngle >= 22.5 && fAngle <= 67.5 )
290 eStyle = POINTER_AUTOSCROLL_NE;
291 else if( fAngle >= 67.5 && fAngle <= 112.5 )
292 eStyle = POINTER_AUTOSCROLL_N;
293 else if( fAngle >= 112.5 && fAngle <= 157.5 )
294 eStyle = POINTER_AUTOSCROLL_NW;
295 else if( fAngle >= 157.5 && fAngle <= 202.5 )
296 eStyle = POINTER_AUTOSCROLL_W;
297 else if( fAngle >= 202.5 && fAngle <= 247.5 )
298 eStyle = POINTER_AUTOSCROLL_SW;
299 else if( fAngle >= 247.5 && fAngle <= 292.5 )
300 eStyle = POINTER_AUTOSCROLL_S;
301 else if( fAngle >= 292.5 && fAngle <= 337.5 )
302 eStyle = POINTER_AUTOSCROLL_SE;
303 else
304 eStyle = POINTER_AUTOSCROLL_E;
306 else if( bHorz )
308 if( fAngle >= 270. || fAngle <= 90. )
309 eStyle = POINTER_AUTOSCROLL_E;
310 else
311 eStyle = POINTER_AUTOSCROLL_W;
313 else
315 if( fAngle >= 0. && fAngle <= 180. )
316 eStyle = POINTER_AUTOSCROLL_N;
317 else
318 eStyle = POINTER_AUTOSCROLL_S;
322 else
323 eStyle = POINTER_ARROW;
325 return eStyle;
328 // ------------------------------------------------------------------------
330 void ImplWheelWindow::Paint( const Rectangle& )
332 ImplDrawWheel();
335 // ------------------------------------------------------------------------
337 void ImplWheelWindow::MouseMove( const MouseEvent& rMEvt )
339 FloatingWindow::MouseMove( rMEvt );
341 const Point aMousePos( OutputToScreenPixel( rMEvt.GetPosPixel() ) );
342 const long nDistX = aMousePos.X() - maCenter.X();
343 const long nDistY = aMousePos.Y() - maCenter.Y();
345 mnActDist = (ULONG) hypot( (double) nDistX, nDistY );
347 const PointerStyle eActStyle = ImplGetMousePointer( nDistX, nDistY );
348 const USHORT nFlags = ImplGetSVData()->maWinData.mnAutoScrollFlags;
349 const BOOL bHorz = ( nFlags & AUTOSCROLL_HORZ ) != 0;
350 const BOOL bVert = ( nFlags & AUTOSCROLL_VERT ) != 0;
351 const BOOL bOuter = mnActDist > WHEEL_RADIUS;
353 if( bOuter && ( maLastMousePos != aMousePos ) )
355 switch( eActStyle )
357 case( POINTER_AUTOSCROLL_N ): mnActDeltaX = +0L, mnActDeltaY = +1L; break;
358 case( POINTER_AUTOSCROLL_S ): mnActDeltaX = +0L, mnActDeltaY = -1L; break;
359 case( POINTER_AUTOSCROLL_W ): mnActDeltaX = +1L, mnActDeltaY = +0L; break;
360 case( POINTER_AUTOSCROLL_E ): mnActDeltaX = -1L, mnActDeltaY = +0L; break;
361 case( POINTER_AUTOSCROLL_NW ): mnActDeltaX = +1L, mnActDeltaY = +1L; break;
362 case( POINTER_AUTOSCROLL_NE ): mnActDeltaX = -1L, mnActDeltaY = +1L; break;
363 case( POINTER_AUTOSCROLL_SW ): mnActDeltaX = +1L, mnActDeltaY = -1L; break;
364 case( POINTER_AUTOSCROLL_SE ): mnActDeltaX = -1L, mnActDeltaY = -1L; break;
366 default:
367 break;
371 ImplRecalcScrollValues();
372 maLastMousePos = aMousePos;
373 SetPointer( eActStyle );
375 if( bHorz && bVert )
376 ImplSetWheelMode( bOuter ? WHEELMODE_SCROLL_VH : WHEELMODE_VH );
377 else if( bHorz )
378 ImplSetWheelMode( bOuter ? WHEELMODE_SCROLL_H : WHEELMODE_H );
379 else
380 ImplSetWheelMode( bOuter ? WHEELMODE_SCROLL_V : WHEELMODE_V );
383 // ------------------------------------------------------------------------
385 void ImplWheelWindow::MouseButtonUp( const MouseEvent& rMEvt )
387 if( mnActDist > WHEEL_RADIUS )
388 GetParent()->EndAutoScroll();
389 else
390 FloatingWindow::MouseButtonUp( rMEvt );
393 // ------------------------------------------------------------------------
395 IMPL_LINK( ImplWheelWindow, ImplScrollHdl, Timer*, EMPTYARG )
397 if ( mnActDeltaX || mnActDeltaY )
399 Window* pWindow = GetParent();
400 const Point aMousePos( pWindow->OutputToScreenPixel( pWindow->GetPointerPosPixel() ) );
401 Point aCmdMousePos( pWindow->ImplFrameToOutput( aMousePos ) );
402 CommandScrollData aScrollData( mnActDeltaX, mnActDeltaY );
403 CommandEvent aCEvt( aCmdMousePos, COMMAND_AUTOSCROLL, TRUE, &aScrollData );
404 NotifyEvent aNCmdEvt( EVENT_COMMAND, pWindow, &aCEvt );
406 if ( !ImplCallPreNotify( aNCmdEvt ) )
408 const ULONG nTime = Time::GetSystemTicks();
409 ImplDelData aDel( this );
410 pWindow->Command( aCEvt );
411 if( aDel.IsDead() )
412 return 0;
413 mnRepaintTime = Max( Time::GetSystemTicks() - nTime, 1UL );
414 ImplRecalcScrollValues();
418 if ( mnTimeout != mpTimer->GetTimeout() )
419 mpTimer->SetTimeout( mnTimeout );
420 mpTimer->Start();
422 return 0L;