1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: scrwnd.cxx,v $
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"
36 #include <tools/time.hxx>
37 #include <tools/debug.hxx>
40 #include <vcl/svids.hrc>
42 #include <vcl/svdata.hxx>
43 #ifndef _VCL_TIMER_HXX
44 #include <vcl/timer.hxx>
46 #ifndef _VCL_EVENT_HXX
47 #include <vcl/event.hxx>
49 #ifndef _VCL_SCRWND_HXX
60 #define WHEEL_WIDTH 25
61 #define WHEEL_RADIUS ((WHEEL_WIDTH) >> 1 )
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
),
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();
96 aBmp
= Bitmap( ResId( SV_RESID_BITMAP_SCROLLMSK
, *pResMgr
) );
97 ImplSetRegion( aBmp
);
101 ImplSetWheelMode( WHEELMODE_VH
);
103 ImplSetWheelMode( WHEELMODE_H
);
105 ImplSetWheelMode( WHEELMODE_V
);
109 mpTimer
->SetTimeoutHdl( LINK( this, ImplWheelWindow
, ImplScrollHdl
) );
110 mpTimer
->SetTimeout( mnTimeout
);
116 // ------------------------------------------------------------------------
118 ImplWheelWindow::~ImplWheelWindow()
124 // ------------------------------------------------------------------------
126 void ImplWheelWindow::ImplStop()
133 // ------------------------------------------------------------------------
135 void ImplWheelWindow::ImplSetRegion( const Bitmap
& rRegionBmp
)
137 Point
aPos( GetPointerPosPixel() );
138 const Size
aSize( rRegionBmp
.GetSizePixel() );
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();
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
)
183 // ------------------------------------------------------------------------
185 void ImplWheelWindow::ImplDrawWheel()
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;
201 DrawImage( Point(), maImgList
.GetImage( nId
) );
204 // ------------------------------------------------------------------------
206 void ImplWheelWindow::ImplRecalcScrollValues()
208 if( mnActDist
< WHEEL_RADIUS
)
210 mnActDeltaX
= mnActDeltaY
= 0L;
211 mnTimeout
= DEF_TIMEOUT
;
220 const double fExp
= ( (double) mnActDist
/ mnMaxWidth
) * log10( (double) MAX_TIME
/ MIN_TIME
);
221 nCurTime
= (ULONG
) ( MAX_TIME
/ pow( 10., fExp
) );
229 if( mnRepaintTime
<= nCurTime
)
230 mnTimeout
= nCurTime
- mnRepaintTime
;
233 long nMult
= mnRepaintTime
/ nCurTime
;
235 if( !( mnRepaintTime
% nCurTime
) )
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
;
248 mnActDeltaX
= (long) fValX
;
250 if( fValY
> LONG_MAX
)
251 mnActDeltaY
= LONG_MAX
;
252 else if( fValY
< LONG_MIN
)
253 mnActDeltaY
= LONG_MIN
;
255 mnActDeltaY
= (long) fValY
;
260 // ------------------------------------------------------------------------
262 PointerStyle
ImplWheelWindow::ImplGetMousePointer( long nDistX
, long nDistY
)
265 const USHORT nFlags
= ImplGetSVData()->maWinData
.mnAutoScrollFlags
;
266 const BOOL bHorz
= ( nFlags
& AUTOSCROLL_HORZ
) != 0;
267 const BOOL bVert
= ( nFlags
& AUTOSCROLL_VERT
) != 0;
271 if( mnActDist
< WHEEL_RADIUS
)
274 eStyle
= POINTER_AUTOSCROLL_NSWE
;
276 eStyle
= POINTER_AUTOSCROLL_WE
;
278 eStyle
= POINTER_AUTOSCROLL_NS
;
282 double fAngle
= atan2( (double) -nDistY
, nDistX
) / F_PI180
;
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
;
304 eStyle
= POINTER_AUTOSCROLL_E
;
308 if( fAngle
>= 270. || fAngle
<= 90. )
309 eStyle
= POINTER_AUTOSCROLL_E
;
311 eStyle
= POINTER_AUTOSCROLL_W
;
315 if( fAngle
>= 0. && fAngle
<= 180. )
316 eStyle
= POINTER_AUTOSCROLL_N
;
318 eStyle
= POINTER_AUTOSCROLL_S
;
323 eStyle
= POINTER_ARROW
;
328 // ------------------------------------------------------------------------
330 void ImplWheelWindow::Paint( const Rectangle
& )
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
) )
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;
371 ImplRecalcScrollValues();
372 maLastMousePos
= aMousePos
;
373 SetPointer( eActStyle
);
376 ImplSetWheelMode( bOuter
? WHEELMODE_SCROLL_VH
: WHEELMODE_VH
);
378 ImplSetWheelMode( bOuter
? WHEELMODE_SCROLL_H
: WHEELMODE_H
);
380 ImplSetWheelMode( bOuter
? WHEELMODE_SCROLL_V
: WHEELMODE_V
);
383 // ------------------------------------------------------------------------
385 void ImplWheelWindow::MouseButtonUp( const MouseEvent
& rMEvt
)
387 if( mnActDist
> WHEEL_RADIUS
)
388 GetParent()->EndAutoScroll();
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
);
413 mnRepaintTime
= Max( Time::GetSystemTicks() - nTime
, 1UL );
414 ImplRecalcScrollValues();
418 if ( mnTimeout
!= mpTimer
->GetTimeout() )
419 mpTimer
->SetTimeout( mnTimeout
);