xref: /trunk/main/vcl/source/control/scrbar.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_vcl.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include "vcl/event.hxx"
32*cdf0e10cSrcweir #include "vcl/sound.hxx"
33*cdf0e10cSrcweir #include "vcl/decoview.hxx"
34*cdf0e10cSrcweir #include "vcl/scrbar.hxx"
35*cdf0e10cSrcweir #include "vcl/timer.hxx"
36*cdf0e10cSrcweir 
37*cdf0e10cSrcweir #include "svdata.hxx"
38*cdf0e10cSrcweir 
39*cdf0e10cSrcweir #include "rtl/string.hxx"
40*cdf0e10cSrcweir #include "tools/rc.h"
41*cdf0e10cSrcweir 
42*cdf0e10cSrcweir 
43*cdf0e10cSrcweir 
44*cdf0e10cSrcweir using namespace rtl;
45*cdf0e10cSrcweir 
46*cdf0e10cSrcweir /*  #i77549#
47*cdf0e10cSrcweir     HACK: for scrollbars in case of thumb rect, page up and page down rect we
48*cdf0e10cSrcweir     abuse the HitTestNativeControl interface. All theming engines but aqua
49*cdf0e10cSrcweir     are actually able to draw the thumb according to our internal representation.
50*cdf0e10cSrcweir     However aqua draws a little outside. The canonical way would be to enhance the
51*cdf0e10cSrcweir     HitTestNativeControl passing a ScrollbarValue additionally so all necessary
52*cdf0e10cSrcweir     information is available in the call.
53*cdf0e10cSrcweir     .
54*cdf0e10cSrcweir     However since there is only this one small exception we will deviate a little and
55*cdf0e10cSrcweir     instead pass the respective rect as control region to allow for a small correction.
56*cdf0e10cSrcweir 
57*cdf0e10cSrcweir     So all places using HitTestNativeControl on PART_THUMB_HORZ, PART_THUMB_VERT,
58*cdf0e10cSrcweir     PART_TRACK_HORZ_LEFT, PART_TRACK_HORZ_RIGHT, PART_TRACK_VERT_UPPER, PART_TRACK_VERT_LOWER
59*cdf0e10cSrcweir     do not use the control rectangle as region but the actuall part rectangle, making
60*cdf0e10cSrcweir     only small deviations feasible.
61*cdf0e10cSrcweir */
62*cdf0e10cSrcweir 
63*cdf0e10cSrcweir 
64*cdf0e10cSrcweir // =======================================================================
65*cdf0e10cSrcweir 
66*cdf0e10cSrcweir static long ImplMulDiv( long nNumber, long nNumerator, long nDenominator )
67*cdf0e10cSrcweir {
68*cdf0e10cSrcweir     double n = ((double)nNumber * (double)nNumerator) / (double)nDenominator;
69*cdf0e10cSrcweir     return (long)n;
70*cdf0e10cSrcweir }
71*cdf0e10cSrcweir 
72*cdf0e10cSrcweir // =======================================================================
73*cdf0e10cSrcweir 
74*cdf0e10cSrcweir #define SCRBAR_DRAW_BTN1            ((sal_uInt16)0x0001)
75*cdf0e10cSrcweir #define SCRBAR_DRAW_BTN2            ((sal_uInt16)0x0002)
76*cdf0e10cSrcweir #define SCRBAR_DRAW_PAGE1           ((sal_uInt16)0x0004)
77*cdf0e10cSrcweir #define SCRBAR_DRAW_PAGE2           ((sal_uInt16)0x0008)
78*cdf0e10cSrcweir #define SCRBAR_DRAW_THUMB           ((sal_uInt16)0x0010)
79*cdf0e10cSrcweir #define SCRBAR_DRAW_BACKGROUND      ((sal_uInt16)0x0020)
80*cdf0e10cSrcweir #define SCRBAR_DRAW_ALL             (SCRBAR_DRAW_BTN1 | SCRBAR_DRAW_BTN2 |  \
81*cdf0e10cSrcweir                                      SCRBAR_DRAW_PAGE1 | SCRBAR_DRAW_PAGE2 |\
82*cdf0e10cSrcweir                                      SCRBAR_DRAW_THUMB | SCRBAR_DRAW_BACKGROUND )
83*cdf0e10cSrcweir 
84*cdf0e10cSrcweir #define SCRBAR_STATE_BTN1_DOWN      ((sal_uInt16)0x0001)
85*cdf0e10cSrcweir #define SCRBAR_STATE_BTN1_DISABLE   ((sal_uInt16)0x0002)
86*cdf0e10cSrcweir #define SCRBAR_STATE_BTN2_DOWN      ((sal_uInt16)0x0004)
87*cdf0e10cSrcweir #define SCRBAR_STATE_BTN2_DISABLE   ((sal_uInt16)0x0008)
88*cdf0e10cSrcweir #define SCRBAR_STATE_PAGE1_DOWN     ((sal_uInt16)0x0010)
89*cdf0e10cSrcweir #define SCRBAR_STATE_PAGE2_DOWN     ((sal_uInt16)0x0020)
90*cdf0e10cSrcweir #define SCRBAR_STATE_THUMB_DOWN     ((sal_uInt16)0x0040)
91*cdf0e10cSrcweir 
92*cdf0e10cSrcweir #define SCRBAR_VIEW_STYLE           (WB_3DLOOK | WB_HORZ | WB_VERT)
93*cdf0e10cSrcweir 
94*cdf0e10cSrcweir struct ImplScrollBarData
95*cdf0e10cSrcweir {
96*cdf0e10cSrcweir     AutoTimer       maTimer;            // Timer
97*cdf0e10cSrcweir     sal_Bool            mbHide;
98*cdf0e10cSrcweir     Rectangle       maTrackRect; // TODO: move to ScrollBar class when binary incompatibility of ScrollBar class is no longer problematic
99*cdf0e10cSrcweir };
100*cdf0e10cSrcweir 
101*cdf0e10cSrcweir // =======================================================================
102*cdf0e10cSrcweir 
103*cdf0e10cSrcweir void ScrollBar::ImplInit( Window* pParent, WinBits nStyle )
104*cdf0e10cSrcweir {
105*cdf0e10cSrcweir     mpData              = NULL;
106*cdf0e10cSrcweir     mnThumbPixRange     = 0;
107*cdf0e10cSrcweir     mnThumbPixPos       = 0;
108*cdf0e10cSrcweir     mnThumbPixSize      = 0;
109*cdf0e10cSrcweir     mnMinRange          = 0;
110*cdf0e10cSrcweir     mnMaxRange          = 100;
111*cdf0e10cSrcweir     mnThumbPos          = 0;
112*cdf0e10cSrcweir     mnVisibleSize       = 0;
113*cdf0e10cSrcweir     mnLineSize          = 1;
114*cdf0e10cSrcweir     mnPageSize          = 1;
115*cdf0e10cSrcweir     mnDelta             = 0;
116*cdf0e10cSrcweir     mnDragDraw          = 0;
117*cdf0e10cSrcweir     mnStateFlags        = 0;
118*cdf0e10cSrcweir     meScrollType        = SCROLL_DONTKNOW;
119*cdf0e10cSrcweir     meDDScrollType      = SCROLL_DONTKNOW;
120*cdf0e10cSrcweir     mbCalcSize          = sal_True;
121*cdf0e10cSrcweir     mbFullDrag          = 0;
122*cdf0e10cSrcweir 
123*cdf0e10cSrcweir     if( !mpData )  // TODO: remove when maTrackRect is no longer in mpData
124*cdf0e10cSrcweir     {
125*cdf0e10cSrcweir         mpData = new ImplScrollBarData;
126*cdf0e10cSrcweir         mpData->maTimer.SetTimeoutHdl( LINK( this, ScrollBar, ImplAutoTimerHdl ) );
127*cdf0e10cSrcweir         mpData->mbHide = sal_False;
128*cdf0e10cSrcweir     }
129*cdf0e10cSrcweir 
130*cdf0e10cSrcweir     ImplInitStyle( nStyle );
131*cdf0e10cSrcweir     Control::ImplInit( pParent, nStyle, NULL );
132*cdf0e10cSrcweir 
133*cdf0e10cSrcweir     long nScrollSize = GetSettings().GetStyleSettings().GetScrollBarSize();
134*cdf0e10cSrcweir     SetSizePixel( Size( nScrollSize, nScrollSize ) );
135*cdf0e10cSrcweir     SetBackground();
136*cdf0e10cSrcweir }
137*cdf0e10cSrcweir 
138*cdf0e10cSrcweir // -----------------------------------------------------------------------
139*cdf0e10cSrcweir 
140*cdf0e10cSrcweir void ScrollBar::ImplInitStyle( WinBits nStyle )
141*cdf0e10cSrcweir {
142*cdf0e10cSrcweir     if ( nStyle & WB_DRAG )
143*cdf0e10cSrcweir         mbFullDrag = sal_True;
144*cdf0e10cSrcweir     else
145*cdf0e10cSrcweir         mbFullDrag = (GetSettings().GetStyleSettings().GetDragFullOptions() & DRAGFULL_OPTION_SCROLL) != 0;
146*cdf0e10cSrcweir }
147*cdf0e10cSrcweir 
148*cdf0e10cSrcweir // -----------------------------------------------------------------------
149*cdf0e10cSrcweir 
150*cdf0e10cSrcweir ScrollBar::ScrollBar( Window* pParent, WinBits nStyle ) :
151*cdf0e10cSrcweir     Control( WINDOW_SCROLLBAR )
152*cdf0e10cSrcweir {
153*cdf0e10cSrcweir     ImplInit( pParent, nStyle );
154*cdf0e10cSrcweir }
155*cdf0e10cSrcweir 
156*cdf0e10cSrcweir // -----------------------------------------------------------------------
157*cdf0e10cSrcweir 
158*cdf0e10cSrcweir ScrollBar::ScrollBar( Window* pParent, const ResId& rResId ) :
159*cdf0e10cSrcweir     Control( WINDOW_SCROLLBAR )
160*cdf0e10cSrcweir {
161*cdf0e10cSrcweir     rResId.SetRT( RSC_SCROLLBAR );
162*cdf0e10cSrcweir     WinBits nStyle = ImplInitRes( rResId );
163*cdf0e10cSrcweir     ImplInit( pParent, nStyle );
164*cdf0e10cSrcweir     ImplLoadRes( rResId );
165*cdf0e10cSrcweir 
166*cdf0e10cSrcweir     if ( !(nStyle & WB_HIDE) )
167*cdf0e10cSrcweir         Show();
168*cdf0e10cSrcweir }
169*cdf0e10cSrcweir 
170*cdf0e10cSrcweir // -----------------------------------------------------------------------
171*cdf0e10cSrcweir 
172*cdf0e10cSrcweir ScrollBar::~ScrollBar()
173*cdf0e10cSrcweir {
174*cdf0e10cSrcweir     if( mpData )
175*cdf0e10cSrcweir         delete mpData;
176*cdf0e10cSrcweir }
177*cdf0e10cSrcweir 
178*cdf0e10cSrcweir // -----------------------------------------------------------------------
179*cdf0e10cSrcweir 
180*cdf0e10cSrcweir void ScrollBar::ImplLoadRes( const ResId& rResId )
181*cdf0e10cSrcweir {
182*cdf0e10cSrcweir     Control::ImplLoadRes( rResId );
183*cdf0e10cSrcweir 
184*cdf0e10cSrcweir     sal_Int16 nMin          = ReadShortRes();
185*cdf0e10cSrcweir     sal_Int16 nMax          = ReadShortRes();
186*cdf0e10cSrcweir     sal_Int16 nThumbPos     = ReadShortRes();
187*cdf0e10cSrcweir     sal_Int16 nPage         = ReadShortRes();
188*cdf0e10cSrcweir     sal_Int16 nStep         = ReadShortRes();
189*cdf0e10cSrcweir     sal_Int16 nVisibleSize  = ReadShortRes();
190*cdf0e10cSrcweir 
191*cdf0e10cSrcweir     SetRange( Range( nMin, nMax ) );
192*cdf0e10cSrcweir     SetLineSize( nStep );
193*cdf0e10cSrcweir     SetPageSize( nPage );
194*cdf0e10cSrcweir     SetVisibleSize( nVisibleSize );
195*cdf0e10cSrcweir     SetThumbPos( nThumbPos );
196*cdf0e10cSrcweir }
197*cdf0e10cSrcweir 
198*cdf0e10cSrcweir // -----------------------------------------------------------------------
199*cdf0e10cSrcweir 
200*cdf0e10cSrcweir void ScrollBar::ImplUpdateRects( sal_Bool bUpdate )
201*cdf0e10cSrcweir {
202*cdf0e10cSrcweir     sal_uInt16      nOldStateFlags  = mnStateFlags;
203*cdf0e10cSrcweir     Rectangle   aOldPage1Rect = maPage1Rect;
204*cdf0e10cSrcweir     Rectangle   aOldPage2Rect = maPage2Rect;
205*cdf0e10cSrcweir     Rectangle   aOldThumbRect = maThumbRect;
206*cdf0e10cSrcweir 
207*cdf0e10cSrcweir     mnStateFlags  &= ~SCRBAR_STATE_BTN1_DISABLE;
208*cdf0e10cSrcweir     mnStateFlags  &= ~SCRBAR_STATE_BTN2_DISABLE;
209*cdf0e10cSrcweir 
210*cdf0e10cSrcweir     Rectangle& maTrackRect = mpData->maTrackRect; // TODO: remove when maTrackRect is no longer in mpData
211*cdf0e10cSrcweir     if ( mnThumbPixRange )
212*cdf0e10cSrcweir     {
213*cdf0e10cSrcweir         if ( GetStyle() & WB_HORZ )
214*cdf0e10cSrcweir         {
215*cdf0e10cSrcweir             maThumbRect.Left()      = maTrackRect.Left()+mnThumbPixPos;
216*cdf0e10cSrcweir             maThumbRect.Right()     = maThumbRect.Left()+mnThumbPixSize-1;
217*cdf0e10cSrcweir             if ( !mnThumbPixPos )
218*cdf0e10cSrcweir                 maPage1Rect.Right()     = RECT_EMPTY;
219*cdf0e10cSrcweir             else
220*cdf0e10cSrcweir                 maPage1Rect.Right()     = maThumbRect.Left()-1;
221*cdf0e10cSrcweir             if ( mnThumbPixPos >= (mnThumbPixRange-mnThumbPixSize) )
222*cdf0e10cSrcweir                 maPage2Rect.Right()     = RECT_EMPTY;
223*cdf0e10cSrcweir             else
224*cdf0e10cSrcweir             {
225*cdf0e10cSrcweir                 maPage2Rect.Left()      = maThumbRect.Right()+1;
226*cdf0e10cSrcweir                 maPage2Rect.Right()     = maTrackRect.Right();
227*cdf0e10cSrcweir             }
228*cdf0e10cSrcweir         }
229*cdf0e10cSrcweir         else
230*cdf0e10cSrcweir         {
231*cdf0e10cSrcweir             maThumbRect.Top()       = maTrackRect.Top()+mnThumbPixPos;
232*cdf0e10cSrcweir             maThumbRect.Bottom()    = maThumbRect.Top()+mnThumbPixSize-1;
233*cdf0e10cSrcweir             if ( !mnThumbPixPos )
234*cdf0e10cSrcweir                 maPage1Rect.Bottom()    = RECT_EMPTY;
235*cdf0e10cSrcweir             else
236*cdf0e10cSrcweir                 maPage1Rect.Bottom()    = maThumbRect.Top()-1;
237*cdf0e10cSrcweir             if ( mnThumbPixPos >= (mnThumbPixRange-mnThumbPixSize) )
238*cdf0e10cSrcweir                 maPage2Rect.Bottom()    = RECT_EMPTY;
239*cdf0e10cSrcweir             else
240*cdf0e10cSrcweir             {
241*cdf0e10cSrcweir                 maPage2Rect.Top()       = maThumbRect.Bottom()+1;
242*cdf0e10cSrcweir                 maPage2Rect.Bottom()    = maTrackRect.Bottom();
243*cdf0e10cSrcweir             }
244*cdf0e10cSrcweir         }
245*cdf0e10cSrcweir     }
246*cdf0e10cSrcweir     else
247*cdf0e10cSrcweir     {
248*cdf0e10cSrcweir         Size aScrBarSize = GetOutputSizePixel();
249*cdf0e10cSrcweir         if ( GetStyle() & WB_HORZ )
250*cdf0e10cSrcweir         {
251*cdf0e10cSrcweir             const long nSpace = maTrackRect.Right() - maTrackRect.Left();
252*cdf0e10cSrcweir             if ( nSpace > 0 )
253*cdf0e10cSrcweir             {
254*cdf0e10cSrcweir                 maPage1Rect.Left()   = maTrackRect.Left();
255*cdf0e10cSrcweir                 maPage1Rect.Right()  = maTrackRect.Left() + (nSpace/2);
256*cdf0e10cSrcweir                 maPage2Rect.Left()   = maPage1Rect.Right() + 1;
257*cdf0e10cSrcweir                 maPage2Rect.Right()  = maTrackRect.Right();
258*cdf0e10cSrcweir             }
259*cdf0e10cSrcweir         }
260*cdf0e10cSrcweir         else
261*cdf0e10cSrcweir         {
262*cdf0e10cSrcweir             const long nSpace = maTrackRect.Bottom() - maTrackRect.Top();
263*cdf0e10cSrcweir             if ( nSpace > 0 )
264*cdf0e10cSrcweir             {
265*cdf0e10cSrcweir                 maPage1Rect.Top()    = maTrackRect.Top();
266*cdf0e10cSrcweir                 maPage1Rect.Bottom() = maTrackRect.Top() + (nSpace/2);
267*cdf0e10cSrcweir                 maPage2Rect.Top()    = maPage1Rect.Bottom() + 1;
268*cdf0e10cSrcweir                 maPage2Rect.Bottom() = maTrackRect.Bottom();
269*cdf0e10cSrcweir             }
270*cdf0e10cSrcweir         }
271*cdf0e10cSrcweir     }
272*cdf0e10cSrcweir 
273*cdf0e10cSrcweir     if( !IsNativeControlSupported(CTRL_SCROLLBAR, PART_ENTIRE_CONTROL) )
274*cdf0e10cSrcweir     {
275*cdf0e10cSrcweir         // disable scrollbar buttons only in VCL's own 'theme'
276*cdf0e10cSrcweir         // as it is uncommon on other platforms
277*cdf0e10cSrcweir         if ( mnThumbPos == mnMinRange )
278*cdf0e10cSrcweir             mnStateFlags |= SCRBAR_STATE_BTN1_DISABLE;
279*cdf0e10cSrcweir         if ( mnThumbPos >= (mnMaxRange-mnVisibleSize) )
280*cdf0e10cSrcweir             mnStateFlags |= SCRBAR_STATE_BTN2_DISABLE;
281*cdf0e10cSrcweir     }
282*cdf0e10cSrcweir 
283*cdf0e10cSrcweir     if ( bUpdate )
284*cdf0e10cSrcweir     {
285*cdf0e10cSrcweir         sal_uInt16 nDraw = 0;
286*cdf0e10cSrcweir         if ( (nOldStateFlags & SCRBAR_STATE_BTN1_DISABLE) !=
287*cdf0e10cSrcweir              (mnStateFlags & SCRBAR_STATE_BTN1_DISABLE) )
288*cdf0e10cSrcweir             nDraw |= SCRBAR_DRAW_BTN1;
289*cdf0e10cSrcweir         if ( (nOldStateFlags & SCRBAR_STATE_BTN2_DISABLE) !=
290*cdf0e10cSrcweir              (mnStateFlags & SCRBAR_STATE_BTN2_DISABLE) )
291*cdf0e10cSrcweir             nDraw |= SCRBAR_DRAW_BTN2;
292*cdf0e10cSrcweir         if ( aOldPage1Rect != maPage1Rect )
293*cdf0e10cSrcweir             nDraw |= SCRBAR_DRAW_PAGE1;
294*cdf0e10cSrcweir         if ( aOldPage2Rect != maPage2Rect )
295*cdf0e10cSrcweir             nDraw |= SCRBAR_DRAW_PAGE2;
296*cdf0e10cSrcweir         if ( aOldThumbRect != maThumbRect )
297*cdf0e10cSrcweir             nDraw |= SCRBAR_DRAW_THUMB;
298*cdf0e10cSrcweir         ImplDraw( nDraw, this );
299*cdf0e10cSrcweir     }
300*cdf0e10cSrcweir }
301*cdf0e10cSrcweir 
302*cdf0e10cSrcweir // -----------------------------------------------------------------------
303*cdf0e10cSrcweir 
304*cdf0e10cSrcweir long ScrollBar::ImplCalcThumbPos( long nPixPos )
305*cdf0e10cSrcweir {
306*cdf0e10cSrcweir     // Position berechnen
307*cdf0e10cSrcweir     long nCalcThumbPos;
308*cdf0e10cSrcweir     nCalcThumbPos = ImplMulDiv( nPixPos, mnMaxRange-mnVisibleSize-mnMinRange,
309*cdf0e10cSrcweir                                 mnThumbPixRange-mnThumbPixSize );
310*cdf0e10cSrcweir     nCalcThumbPos += mnMinRange;
311*cdf0e10cSrcweir     return nCalcThumbPos;
312*cdf0e10cSrcweir }
313*cdf0e10cSrcweir 
314*cdf0e10cSrcweir // -----------------------------------------------------------------------
315*cdf0e10cSrcweir 
316*cdf0e10cSrcweir long ScrollBar::ImplCalcThumbPosPix( long nPos )
317*cdf0e10cSrcweir {
318*cdf0e10cSrcweir     long nCalcThumbPos;
319*cdf0e10cSrcweir 
320*cdf0e10cSrcweir     // Position berechnen
321*cdf0e10cSrcweir     nCalcThumbPos = ImplMulDiv( nPos-mnMinRange, mnThumbPixRange-mnThumbPixSize,
322*cdf0e10cSrcweir                                 mnMaxRange-mnVisibleSize-mnMinRange );
323*cdf0e10cSrcweir 
324*cdf0e10cSrcweir     // Am Anfang und Ende des ScrollBars versuchen wir die Anzeige korrekt
325*cdf0e10cSrcweir     // anzuzeigen
326*cdf0e10cSrcweir     if ( !nCalcThumbPos && (mnThumbPos > mnMinRange) )
327*cdf0e10cSrcweir         nCalcThumbPos = 1;
328*cdf0e10cSrcweir     if ( nCalcThumbPos &&
329*cdf0e10cSrcweir          ((nCalcThumbPos+mnThumbPixSize) >= mnThumbPixRange) &&
330*cdf0e10cSrcweir          (mnThumbPos < (mnMaxRange-mnVisibleSize)) )
331*cdf0e10cSrcweir         nCalcThumbPos--;
332*cdf0e10cSrcweir 
333*cdf0e10cSrcweir     return nCalcThumbPos;
334*cdf0e10cSrcweir }
335*cdf0e10cSrcweir 
336*cdf0e10cSrcweir // -----------------------------------------------------------------------
337*cdf0e10cSrcweir 
338*cdf0e10cSrcweir void ScrollBar::ImplCalc( sal_Bool bUpdate )
339*cdf0e10cSrcweir {
340*cdf0e10cSrcweir     const Size aSize = GetOutputSizePixel();
341*cdf0e10cSrcweir     const long nMinThumbSize = GetSettings().GetStyleSettings().GetMinThumbSize();;
342*cdf0e10cSrcweir 
343*cdf0e10cSrcweir     Rectangle& maTrackRect = mpData->maTrackRect;  // TODO: remove when maTrackRect is no longer in mpData
344*cdf0e10cSrcweir     if ( mbCalcSize )
345*cdf0e10cSrcweir     {
346*cdf0e10cSrcweir         const Rectangle aControlRegion( Point(0,0), aSize );
347*cdf0e10cSrcweir         Rectangle aBtn1Region, aBtn2Region, aTrackRegion, aBoundingRegion;
348*cdf0e10cSrcweir 
349*cdf0e10cSrcweir         if ( GetStyle() & WB_HORZ )
350*cdf0e10cSrcweir         {
351*cdf0e10cSrcweir             if ( GetNativeControlRegion( CTRL_SCROLLBAR, PART_BUTTON_LEFT,
352*cdf0e10cSrcweir                         aControlRegion, 0, ImplControlValue(), rtl::OUString(), aBoundingRegion, aBtn1Region ) &&
353*cdf0e10cSrcweir                  GetNativeControlRegion( CTRL_SCROLLBAR, PART_BUTTON_RIGHT,
354*cdf0e10cSrcweir                         aControlRegion, 0, ImplControlValue(), rtl::OUString(), aBoundingRegion, aBtn2Region ) )
355*cdf0e10cSrcweir             {
356*cdf0e10cSrcweir                 maBtn1Rect = aBtn1Region;
357*cdf0e10cSrcweir                 maBtn2Rect = aBtn2Region;
358*cdf0e10cSrcweir             }
359*cdf0e10cSrcweir             else
360*cdf0e10cSrcweir             {
361*cdf0e10cSrcweir                 Size aBtnSize( aSize.Height(), aSize.Height() );
362*cdf0e10cSrcweir                 maBtn2Rect.Top()    = maBtn1Rect.Top();
363*cdf0e10cSrcweir                 maBtn2Rect.Left()   = aSize.Width()-aSize.Height();
364*cdf0e10cSrcweir                 maBtn1Rect.SetSize( aBtnSize );
365*cdf0e10cSrcweir                 maBtn2Rect.SetSize( aBtnSize );
366*cdf0e10cSrcweir             }
367*cdf0e10cSrcweir 
368*cdf0e10cSrcweir             if ( GetNativeControlRegion( CTRL_SCROLLBAR, PART_TRACK_HORZ_AREA,
369*cdf0e10cSrcweir                      aControlRegion, 0, ImplControlValue(), rtl::OUString(), aBoundingRegion, aTrackRegion ) )
370*cdf0e10cSrcweir                 maTrackRect = aTrackRegion;
371*cdf0e10cSrcweir             else
372*cdf0e10cSrcweir                 maTrackRect = Rectangle( maBtn1Rect.TopRight(), maBtn2Rect.BottomLeft() );
373*cdf0e10cSrcweir 
374*cdf0e10cSrcweir             // Check if available space is big enough for thumb ( min thumb size = ScrBar width/height )
375*cdf0e10cSrcweir             mnThumbPixRange = maTrackRect.Right() - maTrackRect.Left();
376*cdf0e10cSrcweir             if( mnThumbPixRange > 0 )
377*cdf0e10cSrcweir             {
378*cdf0e10cSrcweir                 maPage1Rect.Left()      = maTrackRect.Left();
379*cdf0e10cSrcweir                 maPage1Rect.Bottom()    =
380*cdf0e10cSrcweir                 maPage2Rect.Bottom()    =
381*cdf0e10cSrcweir                 maThumbRect.Bottom()    = maTrackRect.Bottom();
382*cdf0e10cSrcweir             }
383*cdf0e10cSrcweir             else
384*cdf0e10cSrcweir             {
385*cdf0e10cSrcweir                 mnThumbPixRange = 0;
386*cdf0e10cSrcweir                 maPage1Rect.SetEmpty();
387*cdf0e10cSrcweir                 maPage2Rect.SetEmpty();
388*cdf0e10cSrcweir             }
389*cdf0e10cSrcweir         }
390*cdf0e10cSrcweir         else
391*cdf0e10cSrcweir         {
392*cdf0e10cSrcweir             if ( GetNativeControlRegion( CTRL_SCROLLBAR, PART_BUTTON_UP,
393*cdf0e10cSrcweir                         aControlRegion, 0, ImplControlValue(), rtl::OUString(), aBoundingRegion, aBtn1Region ) &&
394*cdf0e10cSrcweir                  GetNativeControlRegion( CTRL_SCROLLBAR, PART_BUTTON_DOWN,
395*cdf0e10cSrcweir                         aControlRegion, 0, ImplControlValue(), rtl::OUString(), aBoundingRegion, aBtn2Region ) )
396*cdf0e10cSrcweir             {
397*cdf0e10cSrcweir                 maBtn1Rect = aBtn1Region;
398*cdf0e10cSrcweir                 maBtn2Rect = aBtn2Region;
399*cdf0e10cSrcweir             }
400*cdf0e10cSrcweir             else
401*cdf0e10cSrcweir             {
402*cdf0e10cSrcweir                 const Size aBtnSize( aSize.Width(), aSize.Width() );
403*cdf0e10cSrcweir                 maBtn2Rect.Left()   = maBtn1Rect.Left();
404*cdf0e10cSrcweir                 maBtn2Rect.Top()    = aSize.Height()-aSize.Width();
405*cdf0e10cSrcweir                 maBtn1Rect.SetSize( aBtnSize );
406*cdf0e10cSrcweir                 maBtn2Rect.SetSize( aBtnSize );
407*cdf0e10cSrcweir             }
408*cdf0e10cSrcweir 
409*cdf0e10cSrcweir             if ( GetNativeControlRegion( CTRL_SCROLLBAR, PART_TRACK_VERT_AREA,
410*cdf0e10cSrcweir                      aControlRegion, 0, ImplControlValue(), rtl::OUString(), aBoundingRegion, aTrackRegion ) )
411*cdf0e10cSrcweir                 maTrackRect = aTrackRegion;
412*cdf0e10cSrcweir             else
413*cdf0e10cSrcweir                 maTrackRect = Rectangle( maBtn1Rect.BottomLeft()+Point(0,1), maBtn2Rect.TopRight() );
414*cdf0e10cSrcweir 
415*cdf0e10cSrcweir             // Check if available space is big enough for thumb
416*cdf0e10cSrcweir             mnThumbPixRange = maTrackRect.Bottom() - maTrackRect.Top();
417*cdf0e10cSrcweir             if( mnThumbPixRange > 0 )
418*cdf0e10cSrcweir             {
419*cdf0e10cSrcweir                 maPage1Rect.Top()       = maTrackRect.Top();
420*cdf0e10cSrcweir                 maPage1Rect.Right()     =
421*cdf0e10cSrcweir                 maPage2Rect.Right()     =
422*cdf0e10cSrcweir                 maThumbRect.Right()     = maTrackRect.Right();
423*cdf0e10cSrcweir             }
424*cdf0e10cSrcweir             else
425*cdf0e10cSrcweir             {
426*cdf0e10cSrcweir                 mnThumbPixRange = 0;
427*cdf0e10cSrcweir                 maPage1Rect.SetEmpty();
428*cdf0e10cSrcweir                 maPage2Rect.SetEmpty();
429*cdf0e10cSrcweir             }
430*cdf0e10cSrcweir         }
431*cdf0e10cSrcweir 
432*cdf0e10cSrcweir         if ( !mnThumbPixRange )
433*cdf0e10cSrcweir             maThumbRect.SetEmpty();
434*cdf0e10cSrcweir 
435*cdf0e10cSrcweir         mbCalcSize = sal_False;
436*cdf0e10cSrcweir     }
437*cdf0e10cSrcweir 
438*cdf0e10cSrcweir     if ( mnThumbPixRange )
439*cdf0e10cSrcweir     {
440*cdf0e10cSrcweir         // Werte berechnen
441*cdf0e10cSrcweir         if ( (mnVisibleSize >= (mnMaxRange-mnMinRange)) ||
442*cdf0e10cSrcweir              ((mnMaxRange-mnMinRange) <= 0) )
443*cdf0e10cSrcweir         {
444*cdf0e10cSrcweir             mnThumbPos      = mnMinRange;
445*cdf0e10cSrcweir             mnThumbPixPos   = 0;
446*cdf0e10cSrcweir             mnThumbPixSize  = mnThumbPixRange;
447*cdf0e10cSrcweir         }
448*cdf0e10cSrcweir         else
449*cdf0e10cSrcweir         {
450*cdf0e10cSrcweir             if ( mnVisibleSize )
451*cdf0e10cSrcweir                 mnThumbPixSize = ImplMulDiv( mnThumbPixRange, mnVisibleSize, mnMaxRange-mnMinRange );
452*cdf0e10cSrcweir             else
453*cdf0e10cSrcweir             {
454*cdf0e10cSrcweir                 if ( GetStyle() & WB_HORZ )
455*cdf0e10cSrcweir                     mnThumbPixSize = maThumbRect.GetWidth();
456*cdf0e10cSrcweir                 else
457*cdf0e10cSrcweir                     mnThumbPixSize = maThumbRect.GetHeight();
458*cdf0e10cSrcweir             }
459*cdf0e10cSrcweir             if ( mnThumbPixSize < nMinThumbSize )
460*cdf0e10cSrcweir                 mnThumbPixSize = nMinThumbSize;
461*cdf0e10cSrcweir             if ( mnThumbPixSize > mnThumbPixRange )
462*cdf0e10cSrcweir                 mnThumbPixSize = mnThumbPixRange;
463*cdf0e10cSrcweir             mnThumbPixPos = ImplCalcThumbPosPix( mnThumbPos );
464*cdf0e10cSrcweir         }
465*cdf0e10cSrcweir     }
466*cdf0e10cSrcweir 
467*cdf0e10cSrcweir     // Wenn neu ausgegeben werden soll und wir schon ueber eine
468*cdf0e10cSrcweir     // Aktion einen Paint-Event ausgeloest bekommen haben, dann
469*cdf0e10cSrcweir     // geben wir nicht direkt aus, sondern invalidieren nur alles
470*cdf0e10cSrcweir     if ( bUpdate && HasPaintEvent() )
471*cdf0e10cSrcweir     {
472*cdf0e10cSrcweir         Invalidate();
473*cdf0e10cSrcweir         bUpdate = sal_False;
474*cdf0e10cSrcweir     }
475*cdf0e10cSrcweir     ImplUpdateRects( bUpdate );
476*cdf0e10cSrcweir }
477*cdf0e10cSrcweir 
478*cdf0e10cSrcweir // -----------------------------------------------------------------------
479*cdf0e10cSrcweir 
480*cdf0e10cSrcweir void ScrollBar::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize, sal_uLong nFlags )
481*cdf0e10cSrcweir {
482*cdf0e10cSrcweir     Point       aPos  = pDev->LogicToPixel( rPos );
483*cdf0e10cSrcweir     Size        aSize = pDev->LogicToPixel( rSize );
484*cdf0e10cSrcweir     Rectangle   aRect( aPos, aSize );
485*cdf0e10cSrcweir 
486*cdf0e10cSrcweir     pDev->Push();
487*cdf0e10cSrcweir     pDev->SetMapMode();
488*cdf0e10cSrcweir     if ( !(nFlags & WINDOW_DRAW_MONO) )
489*cdf0e10cSrcweir     {
490*cdf0e10cSrcweir         // DecoView uses the FaceColor...
491*cdf0e10cSrcweir         AllSettings aSettings = pDev->GetSettings();
492*cdf0e10cSrcweir         StyleSettings aStyleSettings = aSettings.GetStyleSettings();
493*cdf0e10cSrcweir         if ( IsControlBackground() )
494*cdf0e10cSrcweir             aStyleSettings.SetFaceColor( GetControlBackground() );
495*cdf0e10cSrcweir         else
496*cdf0e10cSrcweir             aStyleSettings.SetFaceColor( GetSettings().GetStyleSettings().GetFaceColor() );
497*cdf0e10cSrcweir 
498*cdf0e10cSrcweir         aSettings.SetStyleSettings( aStyleSettings );
499*cdf0e10cSrcweir         pDev->SetSettings( aSettings );
500*cdf0e10cSrcweir     }
501*cdf0e10cSrcweir 
502*cdf0e10cSrcweir     // for printing:
503*cdf0e10cSrcweir     // -calculate the size of the rects
504*cdf0e10cSrcweir     // -because this is zero-based add the correct offset
505*cdf0e10cSrcweir     // -print
506*cdf0e10cSrcweir     // -force recalculate
507*cdf0e10cSrcweir 
508*cdf0e10cSrcweir     if ( mbCalcSize )
509*cdf0e10cSrcweir         ImplCalc( sal_False );
510*cdf0e10cSrcweir 
511*cdf0e10cSrcweir     maBtn1Rect+=aPos;
512*cdf0e10cSrcweir     maBtn2Rect+=aPos;
513*cdf0e10cSrcweir     maThumbRect+=aPos;
514*cdf0e10cSrcweir     mpData->maTrackRect+=aPos; // TODO: update when maTrackRect is no longer in mpData
515*cdf0e10cSrcweir     maPage1Rect+=aPos;
516*cdf0e10cSrcweir     maPage2Rect+=aPos;
517*cdf0e10cSrcweir 
518*cdf0e10cSrcweir     ImplDraw( SCRBAR_DRAW_ALL, pDev );
519*cdf0e10cSrcweir     pDev->Pop();
520*cdf0e10cSrcweir 
521*cdf0e10cSrcweir     mbCalcSize = sal_True;
522*cdf0e10cSrcweir }
523*cdf0e10cSrcweir 
524*cdf0e10cSrcweir // -----------------------------------------------------------------------
525*cdf0e10cSrcweir 
526*cdf0e10cSrcweir sal_Bool ScrollBar::ImplDrawNative( sal_uInt16 nDrawFlags )
527*cdf0e10cSrcweir {
528*cdf0e10cSrcweir     ScrollbarValue scrValue;
529*cdf0e10cSrcweir 
530*cdf0e10cSrcweir     sal_Bool bNativeOK = IsNativeControlSupported(CTRL_SCROLLBAR, PART_ENTIRE_CONTROL);
531*cdf0e10cSrcweir     if( bNativeOK )
532*cdf0e10cSrcweir     {
533*cdf0e10cSrcweir         sal_Bool bHorz = (GetStyle() & WB_HORZ ? true : false);
534*cdf0e10cSrcweir 
535*cdf0e10cSrcweir         // Draw the entire background if the control supports it
536*cdf0e10cSrcweir         if( IsNativeControlSupported(CTRL_SCROLLBAR, bHorz ? PART_DRAW_BACKGROUND_HORZ : PART_DRAW_BACKGROUND_VERT) )
537*cdf0e10cSrcweir         {
538*cdf0e10cSrcweir             ControlState        nState = ( IsEnabled() ? CTRL_STATE_ENABLED : 0 ) | ( HasFocus() ? CTRL_STATE_FOCUSED : 0 );
539*cdf0e10cSrcweir 
540*cdf0e10cSrcweir             scrValue.mnMin = mnMinRange;
541*cdf0e10cSrcweir             scrValue.mnMax = mnMaxRange;
542*cdf0e10cSrcweir             scrValue.mnCur = mnThumbPos;
543*cdf0e10cSrcweir             scrValue.mnVisibleSize = mnVisibleSize;
544*cdf0e10cSrcweir             scrValue.maThumbRect = maThumbRect;
545*cdf0e10cSrcweir             scrValue.maButton1Rect = maBtn1Rect;
546*cdf0e10cSrcweir             scrValue.maButton2Rect = maBtn2Rect;
547*cdf0e10cSrcweir             scrValue.mnButton1State = ((mnStateFlags & SCRBAR_STATE_BTN1_DOWN) ? CTRL_STATE_PRESSED : 0) |
548*cdf0e10cSrcweir                                 ((!(mnStateFlags & SCRBAR_STATE_BTN1_DISABLE)) ? CTRL_STATE_ENABLED : 0);
549*cdf0e10cSrcweir             scrValue.mnButton2State = ((mnStateFlags & SCRBAR_STATE_BTN2_DOWN) ? CTRL_STATE_PRESSED : 0) |
550*cdf0e10cSrcweir                                 ((!(mnStateFlags & SCRBAR_STATE_BTN2_DISABLE)) ? CTRL_STATE_ENABLED : 0);
551*cdf0e10cSrcweir             scrValue.mnThumbState = nState | ((mnStateFlags & SCRBAR_STATE_THUMB_DOWN) ? CTRL_STATE_PRESSED : 0);
552*cdf0e10cSrcweir             scrValue.mnPage1State = nState | ((mnStateFlags & SCRBAR_STATE_PAGE1_DOWN) ? CTRL_STATE_PRESSED : 0);
553*cdf0e10cSrcweir             scrValue.mnPage2State = nState | ((mnStateFlags & SCRBAR_STATE_PAGE2_DOWN) ? CTRL_STATE_PRESSED : 0);
554*cdf0e10cSrcweir 
555*cdf0e10cSrcweir             if( IsMouseOver() )
556*cdf0e10cSrcweir             {
557*cdf0e10cSrcweir                 Rectangle* pRect = ImplFindPartRect( GetPointerPosPixel() );
558*cdf0e10cSrcweir                 if( pRect )
559*cdf0e10cSrcweir                 {
560*cdf0e10cSrcweir                     if( pRect == &maThumbRect )
561*cdf0e10cSrcweir                         scrValue.mnThumbState |= CTRL_STATE_ROLLOVER;
562*cdf0e10cSrcweir                     else if( pRect == &maBtn1Rect )
563*cdf0e10cSrcweir                         scrValue.mnButton1State |= CTRL_STATE_ROLLOVER;
564*cdf0e10cSrcweir                     else if( pRect == &maBtn2Rect )
565*cdf0e10cSrcweir                         scrValue.mnButton2State |= CTRL_STATE_ROLLOVER;
566*cdf0e10cSrcweir                     else if( pRect == &maPage1Rect )
567*cdf0e10cSrcweir                         scrValue.mnPage1State |= CTRL_STATE_ROLLOVER;
568*cdf0e10cSrcweir                     else if( pRect == &maPage2Rect )
569*cdf0e10cSrcweir                         scrValue.mnPage2State |= CTRL_STATE_ROLLOVER;
570*cdf0e10cSrcweir                 }
571*cdf0e10cSrcweir             }
572*cdf0e10cSrcweir 
573*cdf0e10cSrcweir             Rectangle aCtrlRegion;
574*cdf0e10cSrcweir             aCtrlRegion.Union( maBtn1Rect );
575*cdf0e10cSrcweir             aCtrlRegion.Union( maBtn2Rect );
576*cdf0e10cSrcweir             aCtrlRegion.Union( maPage1Rect );
577*cdf0e10cSrcweir             aCtrlRegion.Union( maPage2Rect );
578*cdf0e10cSrcweir             aCtrlRegion.Union( maThumbRect );
579*cdf0e10cSrcweir             bNativeOK = DrawNativeControl( CTRL_SCROLLBAR, (bHorz ? PART_DRAW_BACKGROUND_HORZ : PART_DRAW_BACKGROUND_VERT),
580*cdf0e10cSrcweir                             aCtrlRegion, nState, scrValue, rtl::OUString() );
581*cdf0e10cSrcweir         }
582*cdf0e10cSrcweir         else
583*cdf0e10cSrcweir       {
584*cdf0e10cSrcweir         if ( (nDrawFlags & SCRBAR_DRAW_PAGE1) || (nDrawFlags & SCRBAR_DRAW_PAGE2) )
585*cdf0e10cSrcweir         {
586*cdf0e10cSrcweir             sal_uInt32  part1 = bHorz ? PART_TRACK_HORZ_LEFT : PART_TRACK_VERT_UPPER;
587*cdf0e10cSrcweir             sal_uInt32  part2 = bHorz ? PART_TRACK_HORZ_RIGHT : PART_TRACK_VERT_LOWER;
588*cdf0e10cSrcweir             Rectangle   aCtrlRegion1( maPage1Rect );
589*cdf0e10cSrcweir             Rectangle   aCtrlRegion2( maPage2Rect );
590*cdf0e10cSrcweir             ControlState nState1 = (IsEnabled() ? CTRL_STATE_ENABLED : 0) | (HasFocus() ? CTRL_STATE_FOCUSED : 0);
591*cdf0e10cSrcweir             ControlState nState2 = nState1;
592*cdf0e10cSrcweir 
593*cdf0e10cSrcweir             nState1 |= ((mnStateFlags & SCRBAR_STATE_PAGE1_DOWN) ? CTRL_STATE_PRESSED : 0);
594*cdf0e10cSrcweir             nState2 |= ((mnStateFlags & SCRBAR_STATE_PAGE2_DOWN) ? CTRL_STATE_PRESSED : 0);
595*cdf0e10cSrcweir 
596*cdf0e10cSrcweir             if( IsMouseOver() )
597*cdf0e10cSrcweir             {
598*cdf0e10cSrcweir                 Rectangle* pRect = ImplFindPartRect( GetPointerPosPixel() );
599*cdf0e10cSrcweir                 if( pRect )
600*cdf0e10cSrcweir                 {
601*cdf0e10cSrcweir                     if( pRect == &maPage1Rect )
602*cdf0e10cSrcweir                         nState1 |= CTRL_STATE_ROLLOVER;
603*cdf0e10cSrcweir                     else if( pRect == &maPage2Rect )
604*cdf0e10cSrcweir                         nState2 |= CTRL_STATE_ROLLOVER;
605*cdf0e10cSrcweir                 }
606*cdf0e10cSrcweir             }
607*cdf0e10cSrcweir 
608*cdf0e10cSrcweir             if ( nDrawFlags & SCRBAR_DRAW_PAGE1 )
609*cdf0e10cSrcweir                 bNativeOK = DrawNativeControl( CTRL_SCROLLBAR, part1, aCtrlRegion1, nState1,
610*cdf0e10cSrcweir                                 scrValue, rtl::OUString() );
611*cdf0e10cSrcweir 
612*cdf0e10cSrcweir             if ( nDrawFlags & SCRBAR_DRAW_PAGE2 )
613*cdf0e10cSrcweir                 bNativeOK = DrawNativeControl( CTRL_SCROLLBAR, part2, aCtrlRegion2, nState2,
614*cdf0e10cSrcweir                                 scrValue, rtl::OUString() );
615*cdf0e10cSrcweir         }
616*cdf0e10cSrcweir         if ( (nDrawFlags & SCRBAR_DRAW_BTN1) || (nDrawFlags & SCRBAR_DRAW_BTN2) )
617*cdf0e10cSrcweir         {
618*cdf0e10cSrcweir             sal_uInt32  part1 = bHorz ? PART_BUTTON_LEFT : PART_BUTTON_UP;
619*cdf0e10cSrcweir             sal_uInt32  part2 = bHorz ? PART_BUTTON_RIGHT : PART_BUTTON_DOWN;
620*cdf0e10cSrcweir             Rectangle   aCtrlRegion1( maBtn1Rect );
621*cdf0e10cSrcweir             Rectangle   aCtrlRegion2( maBtn2Rect );
622*cdf0e10cSrcweir             ControlState nState1 = HasFocus() ? CTRL_STATE_FOCUSED : 0;
623*cdf0e10cSrcweir             ControlState nState2 = nState1;
624*cdf0e10cSrcweir 
625*cdf0e10cSrcweir             if ( !Window::IsEnabled() || !IsEnabled() )
626*cdf0e10cSrcweir                 nState1 = (nState2 &= ~CTRL_STATE_ENABLED);
627*cdf0e10cSrcweir             else
628*cdf0e10cSrcweir                 nState1 = (nState2 |= CTRL_STATE_ENABLED);
629*cdf0e10cSrcweir 
630*cdf0e10cSrcweir             nState1 |= ((mnStateFlags & SCRBAR_STATE_BTN1_DOWN) ? CTRL_STATE_PRESSED : 0);
631*cdf0e10cSrcweir             nState2 |= ((mnStateFlags & SCRBAR_STATE_BTN2_DOWN) ? CTRL_STATE_PRESSED : 0);
632*cdf0e10cSrcweir 
633*cdf0e10cSrcweir             if(mnStateFlags & SCRBAR_STATE_BTN1_DISABLE)
634*cdf0e10cSrcweir                 nState1 &= ~CTRL_STATE_ENABLED;
635*cdf0e10cSrcweir             if(mnStateFlags & SCRBAR_STATE_BTN2_DISABLE)
636*cdf0e10cSrcweir                 nState2 &= ~CTRL_STATE_ENABLED;
637*cdf0e10cSrcweir 
638*cdf0e10cSrcweir             if( IsMouseOver() )
639*cdf0e10cSrcweir             {
640*cdf0e10cSrcweir                 Rectangle* pRect = ImplFindPartRect( GetPointerPosPixel() );
641*cdf0e10cSrcweir                 if( pRect )
642*cdf0e10cSrcweir                 {
643*cdf0e10cSrcweir                     if( pRect == &maBtn1Rect )
644*cdf0e10cSrcweir                         nState1 |= CTRL_STATE_ROLLOVER;
645*cdf0e10cSrcweir                     else if( pRect == &maBtn2Rect )
646*cdf0e10cSrcweir                         nState2 |= CTRL_STATE_ROLLOVER;
647*cdf0e10cSrcweir                 }
648*cdf0e10cSrcweir             }
649*cdf0e10cSrcweir 
650*cdf0e10cSrcweir             if ( nDrawFlags & SCRBAR_DRAW_BTN1 )
651*cdf0e10cSrcweir                 bNativeOK = DrawNativeControl( CTRL_SCROLLBAR, part1, aCtrlRegion1, nState1,
652*cdf0e10cSrcweir                                 scrValue, rtl::OUString() );
653*cdf0e10cSrcweir 
654*cdf0e10cSrcweir             if ( nDrawFlags & SCRBAR_DRAW_BTN2 )
655*cdf0e10cSrcweir                 bNativeOK = DrawNativeControl( CTRL_SCROLLBAR, part2, aCtrlRegion2, nState2,
656*cdf0e10cSrcweir                                 scrValue, rtl::OUString() );
657*cdf0e10cSrcweir         }
658*cdf0e10cSrcweir         if ( (nDrawFlags & SCRBAR_DRAW_THUMB) && !maThumbRect.IsEmpty() )
659*cdf0e10cSrcweir         {
660*cdf0e10cSrcweir             ControlState    nState = IsEnabled() ? CTRL_STATE_ENABLED : 0;
661*cdf0e10cSrcweir             Rectangle       aCtrlRegion( maThumbRect );
662*cdf0e10cSrcweir 
663*cdf0e10cSrcweir             if ( mnStateFlags & SCRBAR_STATE_THUMB_DOWN )
664*cdf0e10cSrcweir                 nState |= CTRL_STATE_PRESSED;
665*cdf0e10cSrcweir 
666*cdf0e10cSrcweir             if ( HasFocus() )
667*cdf0e10cSrcweir                 nState |= CTRL_STATE_FOCUSED;
668*cdf0e10cSrcweir 
669*cdf0e10cSrcweir             if( IsMouseOver() )
670*cdf0e10cSrcweir             {
671*cdf0e10cSrcweir                 Rectangle* pRect = ImplFindPartRect( GetPointerPosPixel() );
672*cdf0e10cSrcweir                 if( pRect )
673*cdf0e10cSrcweir                 {
674*cdf0e10cSrcweir                     if( pRect == &maThumbRect )
675*cdf0e10cSrcweir                         nState |= CTRL_STATE_ROLLOVER;
676*cdf0e10cSrcweir                 }
677*cdf0e10cSrcweir             }
678*cdf0e10cSrcweir 
679*cdf0e10cSrcweir             bNativeOK = DrawNativeControl( CTRL_SCROLLBAR, (bHorz ? PART_THUMB_HORZ : PART_THUMB_VERT),
680*cdf0e10cSrcweir                     aCtrlRegion, nState, scrValue, rtl::OUString() );
681*cdf0e10cSrcweir         }
682*cdf0e10cSrcweir       }
683*cdf0e10cSrcweir     }
684*cdf0e10cSrcweir     return bNativeOK;
685*cdf0e10cSrcweir }
686*cdf0e10cSrcweir 
687*cdf0e10cSrcweir void ScrollBar::ImplDraw( sal_uInt16 nDrawFlags, OutputDevice* pOutDev )
688*cdf0e10cSrcweir {
689*cdf0e10cSrcweir     DecorationView          aDecoView( pOutDev );
690*cdf0e10cSrcweir     Rectangle               aTempRect;
691*cdf0e10cSrcweir     sal_uInt16                  nStyle;
692*cdf0e10cSrcweir     const StyleSettings&    rStyleSettings = pOutDev->GetSettings().GetStyleSettings();
693*cdf0e10cSrcweir     SymbolType              eSymbolType;
694*cdf0e10cSrcweir     sal_Bool                    bEnabled = IsEnabled();
695*cdf0e10cSrcweir 
696*cdf0e10cSrcweir     // Evt. noch offene Berechnungen nachholen
697*cdf0e10cSrcweir     if ( mbCalcSize )
698*cdf0e10cSrcweir         ImplCalc( sal_False );
699*cdf0e10cSrcweir 
700*cdf0e10cSrcweir     Window *pWin = NULL;
701*cdf0e10cSrcweir     if( pOutDev->GetOutDevType() == OUTDEV_WINDOW )
702*cdf0e10cSrcweir         pWin = (Window*) pOutDev;
703*cdf0e10cSrcweir 
704*cdf0e10cSrcweir     // Draw the entire control if the native theme engine needs it
705*cdf0e10cSrcweir     if ( nDrawFlags && pWin && pWin->IsNativeControlSupported(CTRL_SCROLLBAR, PART_DRAW_BACKGROUND_HORZ) )
706*cdf0e10cSrcweir     {
707*cdf0e10cSrcweir         ImplDrawNative( SCRBAR_DRAW_BACKGROUND );
708*cdf0e10cSrcweir         return;
709*cdf0e10cSrcweir     }
710*cdf0e10cSrcweir 
711*cdf0e10cSrcweir     if( (nDrawFlags & SCRBAR_DRAW_BTN1) && (!pWin || !ImplDrawNative( SCRBAR_DRAW_BTN1 ) ) )
712*cdf0e10cSrcweir     {
713*cdf0e10cSrcweir         nStyle = BUTTON_DRAW_NOLIGHTBORDER;
714*cdf0e10cSrcweir         if ( mnStateFlags & SCRBAR_STATE_BTN1_DOWN )
715*cdf0e10cSrcweir             nStyle |= BUTTON_DRAW_PRESSED;
716*cdf0e10cSrcweir         aTempRect = aDecoView.DrawButton( maBtn1Rect, nStyle );
717*cdf0e10cSrcweir         ImplCalcSymbolRect( aTempRect );
718*cdf0e10cSrcweir         nStyle = 0;
719*cdf0e10cSrcweir         if ( (mnStateFlags & SCRBAR_STATE_BTN1_DISABLE) || !bEnabled )
720*cdf0e10cSrcweir             nStyle |= SYMBOL_DRAW_DISABLE;
721*cdf0e10cSrcweir         if ( rStyleSettings.GetOptions() & STYLE_OPTION_SCROLLARROW )
722*cdf0e10cSrcweir         {
723*cdf0e10cSrcweir             if ( GetStyle() & WB_HORZ )
724*cdf0e10cSrcweir                 eSymbolType = SYMBOL_ARROW_LEFT;
725*cdf0e10cSrcweir             else
726*cdf0e10cSrcweir                 eSymbolType = SYMBOL_ARROW_UP;
727*cdf0e10cSrcweir         }
728*cdf0e10cSrcweir         else
729*cdf0e10cSrcweir         {
730*cdf0e10cSrcweir             if ( GetStyle() & WB_HORZ )
731*cdf0e10cSrcweir                 eSymbolType = SYMBOL_SPIN_LEFT;
732*cdf0e10cSrcweir             else
733*cdf0e10cSrcweir                 eSymbolType = SYMBOL_SPIN_UP;
734*cdf0e10cSrcweir         }
735*cdf0e10cSrcweir         aDecoView.DrawSymbol( aTempRect, eSymbolType, rStyleSettings.GetButtonTextColor(), nStyle );
736*cdf0e10cSrcweir     }
737*cdf0e10cSrcweir 
738*cdf0e10cSrcweir     if ( (nDrawFlags & SCRBAR_DRAW_BTN2) && (!pWin || !ImplDrawNative( SCRBAR_DRAW_BTN2 ) ) )
739*cdf0e10cSrcweir     {
740*cdf0e10cSrcweir         nStyle = BUTTON_DRAW_NOLIGHTBORDER;
741*cdf0e10cSrcweir         if ( mnStateFlags & SCRBAR_STATE_BTN2_DOWN )
742*cdf0e10cSrcweir             nStyle |= BUTTON_DRAW_PRESSED;
743*cdf0e10cSrcweir         aTempRect = aDecoView.DrawButton(  maBtn2Rect, nStyle );
744*cdf0e10cSrcweir         ImplCalcSymbolRect( aTempRect );
745*cdf0e10cSrcweir         nStyle = 0;
746*cdf0e10cSrcweir         if ( (mnStateFlags & SCRBAR_STATE_BTN2_DISABLE) || !bEnabled )
747*cdf0e10cSrcweir             nStyle |= SYMBOL_DRAW_DISABLE;
748*cdf0e10cSrcweir         if ( rStyleSettings.GetOptions() & STYLE_OPTION_SCROLLARROW )
749*cdf0e10cSrcweir         {
750*cdf0e10cSrcweir             if ( GetStyle() & WB_HORZ )
751*cdf0e10cSrcweir                 eSymbolType = SYMBOL_ARROW_RIGHT;
752*cdf0e10cSrcweir             else
753*cdf0e10cSrcweir                 eSymbolType = SYMBOL_ARROW_DOWN;
754*cdf0e10cSrcweir         }
755*cdf0e10cSrcweir         else
756*cdf0e10cSrcweir         {
757*cdf0e10cSrcweir             if ( GetStyle() & WB_HORZ )
758*cdf0e10cSrcweir                 eSymbolType = SYMBOL_SPIN_RIGHT;
759*cdf0e10cSrcweir             else
760*cdf0e10cSrcweir                 eSymbolType = SYMBOL_SPIN_DOWN;
761*cdf0e10cSrcweir         }
762*cdf0e10cSrcweir         aDecoView.DrawSymbol( aTempRect, eSymbolType, rStyleSettings.GetButtonTextColor(), nStyle );
763*cdf0e10cSrcweir     }
764*cdf0e10cSrcweir 
765*cdf0e10cSrcweir     pOutDev->SetLineColor();
766*cdf0e10cSrcweir 
767*cdf0e10cSrcweir     if ( (nDrawFlags & SCRBAR_DRAW_THUMB) && (!pWin || !ImplDrawNative( SCRBAR_DRAW_THUMB ) ) )
768*cdf0e10cSrcweir     {
769*cdf0e10cSrcweir         if ( !maThumbRect.IsEmpty() )
770*cdf0e10cSrcweir         {
771*cdf0e10cSrcweir             if ( bEnabled )
772*cdf0e10cSrcweir             {
773*cdf0e10cSrcweir                 nStyle = BUTTON_DRAW_NOLIGHTBORDER;
774*cdf0e10cSrcweir                 aTempRect = aDecoView.DrawButton( maThumbRect, nStyle );
775*cdf0e10cSrcweir             }
776*cdf0e10cSrcweir             else
777*cdf0e10cSrcweir             {
778*cdf0e10cSrcweir                 pOutDev->SetFillColor( rStyleSettings.GetCheckedColor() );
779*cdf0e10cSrcweir                 pOutDev->DrawRect( maThumbRect );
780*cdf0e10cSrcweir             }
781*cdf0e10cSrcweir         }
782*cdf0e10cSrcweir     }
783*cdf0e10cSrcweir 
784*cdf0e10cSrcweir     if ( (nDrawFlags & SCRBAR_DRAW_PAGE1) && (!pWin || !ImplDrawNative( SCRBAR_DRAW_PAGE1 ) ) )
785*cdf0e10cSrcweir     {
786*cdf0e10cSrcweir         if ( mnStateFlags & SCRBAR_STATE_PAGE1_DOWN )
787*cdf0e10cSrcweir             pOutDev->SetFillColor( rStyleSettings.GetShadowColor() );
788*cdf0e10cSrcweir         else
789*cdf0e10cSrcweir             pOutDev->SetFillColor( rStyleSettings.GetCheckedColor() );
790*cdf0e10cSrcweir         pOutDev->DrawRect( maPage1Rect );
791*cdf0e10cSrcweir     }
792*cdf0e10cSrcweir     if ( (nDrawFlags & SCRBAR_DRAW_PAGE2) && (!pWin || !ImplDrawNative( SCRBAR_DRAW_PAGE2 ) ) )
793*cdf0e10cSrcweir     {
794*cdf0e10cSrcweir         if ( mnStateFlags & SCRBAR_STATE_PAGE2_DOWN )
795*cdf0e10cSrcweir             pOutDev->SetFillColor( rStyleSettings.GetShadowColor() );
796*cdf0e10cSrcweir         else
797*cdf0e10cSrcweir             pOutDev->SetFillColor( rStyleSettings.GetCheckedColor() );
798*cdf0e10cSrcweir         pOutDev->DrawRect( maPage2Rect );
799*cdf0e10cSrcweir     }
800*cdf0e10cSrcweir }
801*cdf0e10cSrcweir 
802*cdf0e10cSrcweir // -----------------------------------------------------------------------
803*cdf0e10cSrcweir 
804*cdf0e10cSrcweir long ScrollBar::ImplScroll( long nNewPos, sal_Bool bCallEndScroll )
805*cdf0e10cSrcweir {
806*cdf0e10cSrcweir     long nOldPos = mnThumbPos;
807*cdf0e10cSrcweir     SetThumbPos( nNewPos );
808*cdf0e10cSrcweir     long nDelta = mnThumbPos-nOldPos;
809*cdf0e10cSrcweir     if ( nDelta )
810*cdf0e10cSrcweir     {
811*cdf0e10cSrcweir         mnDelta = nDelta;
812*cdf0e10cSrcweir         Scroll();
813*cdf0e10cSrcweir         if ( bCallEndScroll )
814*cdf0e10cSrcweir             EndScroll();
815*cdf0e10cSrcweir         mnDelta = 0;
816*cdf0e10cSrcweir     }
817*cdf0e10cSrcweir     return nDelta;
818*cdf0e10cSrcweir }
819*cdf0e10cSrcweir 
820*cdf0e10cSrcweir // -----------------------------------------------------------------------
821*cdf0e10cSrcweir 
822*cdf0e10cSrcweir long ScrollBar::ImplDoAction( sal_Bool bCallEndScroll )
823*cdf0e10cSrcweir {
824*cdf0e10cSrcweir     long nDelta = 0;
825*cdf0e10cSrcweir 
826*cdf0e10cSrcweir     switch ( meScrollType )
827*cdf0e10cSrcweir     {
828*cdf0e10cSrcweir         case SCROLL_LINEUP:
829*cdf0e10cSrcweir             nDelta = ImplScroll( mnThumbPos-mnLineSize, bCallEndScroll );
830*cdf0e10cSrcweir             break;
831*cdf0e10cSrcweir 
832*cdf0e10cSrcweir         case SCROLL_LINEDOWN:
833*cdf0e10cSrcweir             nDelta = ImplScroll( mnThumbPos+mnLineSize, bCallEndScroll );
834*cdf0e10cSrcweir             break;
835*cdf0e10cSrcweir 
836*cdf0e10cSrcweir         case SCROLL_PAGEUP:
837*cdf0e10cSrcweir             nDelta = ImplScroll( mnThumbPos-mnPageSize, bCallEndScroll );
838*cdf0e10cSrcweir             break;
839*cdf0e10cSrcweir 
840*cdf0e10cSrcweir         case SCROLL_PAGEDOWN:
841*cdf0e10cSrcweir             nDelta = ImplScroll( mnThumbPos+mnPageSize, bCallEndScroll );
842*cdf0e10cSrcweir             break;
843*cdf0e10cSrcweir         default:
844*cdf0e10cSrcweir             ;
845*cdf0e10cSrcweir     }
846*cdf0e10cSrcweir 
847*cdf0e10cSrcweir     return nDelta;
848*cdf0e10cSrcweir }
849*cdf0e10cSrcweir 
850*cdf0e10cSrcweir // -----------------------------------------------------------------------
851*cdf0e10cSrcweir 
852*cdf0e10cSrcweir void ScrollBar::ImplDoMouseAction( const Point& rMousePos, sal_Bool bCallAction )
853*cdf0e10cSrcweir {
854*cdf0e10cSrcweir     sal_uInt16  nOldStateFlags = mnStateFlags;
855*cdf0e10cSrcweir     sal_Bool    bAction = sal_False;
856*cdf0e10cSrcweir     sal_Bool    bHorizontal = ( GetStyle() & WB_HORZ )? sal_True: sal_False;
857*cdf0e10cSrcweir     sal_Bool    bIsInside = sal_False;
858*cdf0e10cSrcweir 
859*cdf0e10cSrcweir     Point aPoint( 0, 0 );
860*cdf0e10cSrcweir     Rectangle aControlRegion( aPoint, GetOutputSizePixel() );
861*cdf0e10cSrcweir 
862*cdf0e10cSrcweir     switch ( meScrollType )
863*cdf0e10cSrcweir     {
864*cdf0e10cSrcweir         case SCROLL_LINEUP:
865*cdf0e10cSrcweir             if ( HitTestNativeControl( CTRL_SCROLLBAR, bHorizontal? PART_BUTTON_LEFT: PART_BUTTON_UP,
866*cdf0e10cSrcweir                         aControlRegion, rMousePos, bIsInside )?
867*cdf0e10cSrcweir                     bIsInside:
868*cdf0e10cSrcweir                     maBtn1Rect.IsInside( rMousePos ) )
869*cdf0e10cSrcweir             {
870*cdf0e10cSrcweir                 bAction = bCallAction;
871*cdf0e10cSrcweir                 mnStateFlags |= SCRBAR_STATE_BTN1_DOWN;
872*cdf0e10cSrcweir             }
873*cdf0e10cSrcweir             else
874*cdf0e10cSrcweir                 mnStateFlags &= ~SCRBAR_STATE_BTN1_DOWN;
875*cdf0e10cSrcweir             break;
876*cdf0e10cSrcweir 
877*cdf0e10cSrcweir         case SCROLL_LINEDOWN:
878*cdf0e10cSrcweir             if ( HitTestNativeControl( CTRL_SCROLLBAR, bHorizontal? PART_BUTTON_RIGHT: PART_BUTTON_DOWN,
879*cdf0e10cSrcweir                         aControlRegion, rMousePos, bIsInside )?
880*cdf0e10cSrcweir                     bIsInside:
881*cdf0e10cSrcweir                     maBtn2Rect.IsInside( rMousePos ) )
882*cdf0e10cSrcweir             {
883*cdf0e10cSrcweir                 bAction = bCallAction;
884*cdf0e10cSrcweir                 mnStateFlags |= SCRBAR_STATE_BTN2_DOWN;
885*cdf0e10cSrcweir             }
886*cdf0e10cSrcweir             else
887*cdf0e10cSrcweir                 mnStateFlags &= ~SCRBAR_STATE_BTN2_DOWN;
888*cdf0e10cSrcweir             break;
889*cdf0e10cSrcweir 
890*cdf0e10cSrcweir         case SCROLL_PAGEUP:
891*cdf0e10cSrcweir             // HitTestNativeControl, see remark at top of file
892*cdf0e10cSrcweir             if ( HitTestNativeControl( CTRL_SCROLLBAR, bHorizontal? PART_TRACK_HORZ_LEFT: PART_TRACK_VERT_UPPER,
893*cdf0e10cSrcweir                                        maPage1Rect, rMousePos, bIsInside )?
894*cdf0e10cSrcweir                     bIsInside:
895*cdf0e10cSrcweir                     maPage1Rect.IsInside( rMousePos ) )
896*cdf0e10cSrcweir             {
897*cdf0e10cSrcweir                 bAction = bCallAction;
898*cdf0e10cSrcweir                 mnStateFlags |= SCRBAR_STATE_PAGE1_DOWN;
899*cdf0e10cSrcweir             }
900*cdf0e10cSrcweir             else
901*cdf0e10cSrcweir                 mnStateFlags &= ~SCRBAR_STATE_PAGE1_DOWN;
902*cdf0e10cSrcweir             break;
903*cdf0e10cSrcweir 
904*cdf0e10cSrcweir         case SCROLL_PAGEDOWN:
905*cdf0e10cSrcweir             // HitTestNativeControl, see remark at top of file
906*cdf0e10cSrcweir             if ( HitTestNativeControl( CTRL_SCROLLBAR, bHorizontal? PART_TRACK_HORZ_RIGHT: PART_TRACK_VERT_LOWER,
907*cdf0e10cSrcweir                                        maPage2Rect, rMousePos, bIsInside )?
908*cdf0e10cSrcweir                     bIsInside:
909*cdf0e10cSrcweir                     maPage2Rect.IsInside( rMousePos ) )
910*cdf0e10cSrcweir             {
911*cdf0e10cSrcweir                 bAction = bCallAction;
912*cdf0e10cSrcweir                 mnStateFlags |= SCRBAR_STATE_PAGE2_DOWN;
913*cdf0e10cSrcweir             }
914*cdf0e10cSrcweir             else
915*cdf0e10cSrcweir                 mnStateFlags &= ~SCRBAR_STATE_PAGE2_DOWN;
916*cdf0e10cSrcweir             break;
917*cdf0e10cSrcweir         default:
918*cdf0e10cSrcweir             ;
919*cdf0e10cSrcweir     }
920*cdf0e10cSrcweir 
921*cdf0e10cSrcweir     if ( nOldStateFlags != mnStateFlags )
922*cdf0e10cSrcweir         ImplDraw( mnDragDraw, this );
923*cdf0e10cSrcweir     if ( bAction )
924*cdf0e10cSrcweir         ImplDoAction( sal_False );
925*cdf0e10cSrcweir }
926*cdf0e10cSrcweir 
927*cdf0e10cSrcweir // -----------------------------------------------------------------------
928*cdf0e10cSrcweir 
929*cdf0e10cSrcweir void ScrollBar::ImplDragThumb( const Point& rMousePos )
930*cdf0e10cSrcweir {
931*cdf0e10cSrcweir     long nMovePix;
932*cdf0e10cSrcweir     if ( GetStyle() & WB_HORZ )
933*cdf0e10cSrcweir         nMovePix = rMousePos.X()-(maThumbRect.Left()+mnMouseOff);
934*cdf0e10cSrcweir     else
935*cdf0e10cSrcweir         nMovePix = rMousePos.Y()-(maThumbRect.Top()+mnMouseOff);
936*cdf0e10cSrcweir 
937*cdf0e10cSrcweir     // move thumb if necessary
938*cdf0e10cSrcweir     if ( nMovePix )
939*cdf0e10cSrcweir     {
940*cdf0e10cSrcweir         mnThumbPixPos += nMovePix;
941*cdf0e10cSrcweir         if ( mnThumbPixPos < 0 )
942*cdf0e10cSrcweir             mnThumbPixPos = 0;
943*cdf0e10cSrcweir         if ( mnThumbPixPos > (mnThumbPixRange-mnThumbPixSize) )
944*cdf0e10cSrcweir             mnThumbPixPos = mnThumbPixRange-mnThumbPixSize;
945*cdf0e10cSrcweir         long nOldPos = mnThumbPos;
946*cdf0e10cSrcweir         mnThumbPos = ImplCalcThumbPos( mnThumbPixPos );
947*cdf0e10cSrcweir         ImplUpdateRects();
948*cdf0e10cSrcweir         if ( mbFullDrag && (nOldPos != mnThumbPos) )
949*cdf0e10cSrcweir         {
950*cdf0e10cSrcweir             mnDelta = mnThumbPos-nOldPos;
951*cdf0e10cSrcweir             Scroll();
952*cdf0e10cSrcweir             mnDelta = 0;
953*cdf0e10cSrcweir         }
954*cdf0e10cSrcweir     }
955*cdf0e10cSrcweir }
956*cdf0e10cSrcweir 
957*cdf0e10cSrcweir // -----------------------------------------------------------------------
958*cdf0e10cSrcweir 
959*cdf0e10cSrcweir void ScrollBar::MouseButtonDown( const MouseEvent& rMEvt )
960*cdf0e10cSrcweir {
961*cdf0e10cSrcweir     if ( rMEvt.IsLeft() || rMEvt.IsMiddle() )
962*cdf0e10cSrcweir     {
963*cdf0e10cSrcweir         const Point&    rMousePos = rMEvt.GetPosPixel();
964*cdf0e10cSrcweir         sal_uInt16          nTrackFlags = 0;
965*cdf0e10cSrcweir         sal_Bool            bHorizontal = ( GetStyle() & WB_HORZ )? sal_True: sal_False;
966*cdf0e10cSrcweir         sal_Bool            bIsInside = sal_False;
967*cdf0e10cSrcweir         sal_Bool            bDragToMouse = sal_False;
968*cdf0e10cSrcweir 
969*cdf0e10cSrcweir         Point aPoint( 0, 0 );
970*cdf0e10cSrcweir         Rectangle aControlRegion( aPoint, GetOutputSizePixel() );
971*cdf0e10cSrcweir 
972*cdf0e10cSrcweir         if ( HitTestNativeControl( CTRL_SCROLLBAR, bHorizontal? PART_BUTTON_LEFT: PART_BUTTON_UP,
973*cdf0e10cSrcweir                     aControlRegion, rMousePos, bIsInside )?
974*cdf0e10cSrcweir                 bIsInside:
975*cdf0e10cSrcweir                 maBtn1Rect.IsInside( rMousePos ) )
976*cdf0e10cSrcweir         {
977*cdf0e10cSrcweir             if ( !(mnStateFlags & SCRBAR_STATE_BTN1_DISABLE) )
978*cdf0e10cSrcweir             {
979*cdf0e10cSrcweir                 nTrackFlags     = STARTTRACK_BUTTONREPEAT;
980*cdf0e10cSrcweir                 meScrollType    = SCROLL_LINEUP;
981*cdf0e10cSrcweir                 mnDragDraw      = SCRBAR_DRAW_BTN1;
982*cdf0e10cSrcweir             }
983*cdf0e10cSrcweir             else
984*cdf0e10cSrcweir                 Sound::Beep( SOUND_DISABLE, this );
985*cdf0e10cSrcweir         }
986*cdf0e10cSrcweir         else if ( HitTestNativeControl( CTRL_SCROLLBAR, bHorizontal? PART_BUTTON_RIGHT: PART_BUTTON_DOWN,
987*cdf0e10cSrcweir                     aControlRegion, rMousePos, bIsInside )?
988*cdf0e10cSrcweir                 bIsInside:
989*cdf0e10cSrcweir                 maBtn2Rect.IsInside( rMousePos ) )
990*cdf0e10cSrcweir         {
991*cdf0e10cSrcweir             if ( !(mnStateFlags & SCRBAR_STATE_BTN2_DISABLE) )
992*cdf0e10cSrcweir             {
993*cdf0e10cSrcweir                 nTrackFlags     = STARTTRACK_BUTTONREPEAT;
994*cdf0e10cSrcweir                 meScrollType    = SCROLL_LINEDOWN;
995*cdf0e10cSrcweir                 mnDragDraw      = SCRBAR_DRAW_BTN2;
996*cdf0e10cSrcweir             }
997*cdf0e10cSrcweir             else
998*cdf0e10cSrcweir                 Sound::Beep( SOUND_DISABLE, this );
999*cdf0e10cSrcweir         }
1000*cdf0e10cSrcweir         else
1001*cdf0e10cSrcweir         {
1002*cdf0e10cSrcweir             bool bThumbHit = HitTestNativeControl( CTRL_SCROLLBAR, bHorizontal? PART_THUMB_HORZ : PART_THUMB_VERT,
1003*cdf0e10cSrcweir                                                    maThumbRect, rMousePos, bIsInside )
1004*cdf0e10cSrcweir                              ? bIsInside : maThumbRect.IsInside( rMousePos );
1005*cdf0e10cSrcweir             bool bDragHandling = rMEvt.IsMiddle() || bThumbHit || ImplGetSVData()->maNWFData.mbScrollbarJumpPage;
1006*cdf0e10cSrcweir             if( bDragHandling )
1007*cdf0e10cSrcweir             {
1008*cdf0e10cSrcweir                 if( mpData )
1009*cdf0e10cSrcweir                 {
1010*cdf0e10cSrcweir                     mpData->mbHide = sal_True;  // disable focus blinking
1011*cdf0e10cSrcweir                     if( HasFocus() )
1012*cdf0e10cSrcweir                         ImplDraw( SCRBAR_DRAW_THUMB, this ); // paint without focus
1013*cdf0e10cSrcweir                 }
1014*cdf0e10cSrcweir 
1015*cdf0e10cSrcweir                 if ( mnVisibleSize < mnMaxRange-mnMinRange )
1016*cdf0e10cSrcweir                 {
1017*cdf0e10cSrcweir                     nTrackFlags     = 0;
1018*cdf0e10cSrcweir                     meScrollType    = SCROLL_DRAG;
1019*cdf0e10cSrcweir                     mnDragDraw      = SCRBAR_DRAW_THUMB;
1020*cdf0e10cSrcweir 
1021*cdf0e10cSrcweir                     // calculate mouse offset
1022*cdf0e10cSrcweir                     if( rMEvt.IsMiddle() || (ImplGetSVData()->maNWFData.mbScrollbarJumpPage && !bThumbHit) )
1023*cdf0e10cSrcweir                     {
1024*cdf0e10cSrcweir                         bDragToMouse = sal_True;
1025*cdf0e10cSrcweir                         if ( GetStyle() & WB_HORZ )
1026*cdf0e10cSrcweir                             mnMouseOff = maThumbRect.GetWidth()/2;
1027*cdf0e10cSrcweir                         else
1028*cdf0e10cSrcweir                             mnMouseOff = maThumbRect.GetHeight()/2;
1029*cdf0e10cSrcweir                     }
1030*cdf0e10cSrcweir                     else
1031*cdf0e10cSrcweir                     {
1032*cdf0e10cSrcweir                         if ( GetStyle() & WB_HORZ )
1033*cdf0e10cSrcweir                             mnMouseOff = rMousePos.X()-maThumbRect.Left();
1034*cdf0e10cSrcweir                         else
1035*cdf0e10cSrcweir                             mnMouseOff = rMousePos.Y()-maThumbRect.Top();
1036*cdf0e10cSrcweir                     }
1037*cdf0e10cSrcweir 
1038*cdf0e10cSrcweir                     mnStateFlags |= SCRBAR_STATE_THUMB_DOWN;
1039*cdf0e10cSrcweir                     ImplDraw( mnDragDraw, this );
1040*cdf0e10cSrcweir                 }
1041*cdf0e10cSrcweir                 else
1042*cdf0e10cSrcweir                     Sound::Beep( SOUND_DISABLE, this );
1043*cdf0e10cSrcweir             }
1044*cdf0e10cSrcweir             else if( HitTestNativeControl( CTRL_SCROLLBAR, bHorizontal? PART_TRACK_HORZ_AREA : PART_TRACK_VERT_AREA,
1045*cdf0e10cSrcweir                                            aControlRegion, rMousePos, bIsInside )?
1046*cdf0e10cSrcweir                 bIsInside : sal_True )
1047*cdf0e10cSrcweir             {
1048*cdf0e10cSrcweir                 nTrackFlags = STARTTRACK_BUTTONREPEAT;
1049*cdf0e10cSrcweir 
1050*cdf0e10cSrcweir                 // HitTestNativeControl, see remark at top of file
1051*cdf0e10cSrcweir                 if ( HitTestNativeControl( CTRL_SCROLLBAR, bHorizontal? PART_TRACK_HORZ_LEFT : PART_TRACK_VERT_UPPER,
1052*cdf0e10cSrcweir                                            maPage1Rect, rMousePos, bIsInside )?
1053*cdf0e10cSrcweir                     bIsInside:
1054*cdf0e10cSrcweir                     maPage1Rect.IsInside( rMousePos ) )
1055*cdf0e10cSrcweir                 {
1056*cdf0e10cSrcweir                     meScrollType    = SCROLL_PAGEUP;
1057*cdf0e10cSrcweir                     mnDragDraw      = SCRBAR_DRAW_PAGE1;
1058*cdf0e10cSrcweir                 }
1059*cdf0e10cSrcweir                 else
1060*cdf0e10cSrcweir                 {
1061*cdf0e10cSrcweir                     meScrollType    = SCROLL_PAGEDOWN;
1062*cdf0e10cSrcweir                     mnDragDraw      = SCRBAR_DRAW_PAGE2;
1063*cdf0e10cSrcweir                 }
1064*cdf0e10cSrcweir             }
1065*cdf0e10cSrcweir         }
1066*cdf0e10cSrcweir 
1067*cdf0e10cSrcweir         // Soll Tracking gestartet werden
1068*cdf0e10cSrcweir         if ( meScrollType != SCROLL_DONTKNOW )
1069*cdf0e10cSrcweir         {
1070*cdf0e10cSrcweir             // remember original position in case of abort or EndScroll-Delta
1071*cdf0e10cSrcweir             mnStartPos = mnThumbPos;
1072*cdf0e10cSrcweir             // #92906# Call StartTracking() before ImplDoMouseAction(), otherwise
1073*cdf0e10cSrcweir             // MouseButtonUp() / EndTracking() may be called if somebody is spending
1074*cdf0e10cSrcweir             // a lot of time in the scroll handler
1075*cdf0e10cSrcweir             StartTracking( nTrackFlags );
1076*cdf0e10cSrcweir             ImplDoMouseAction( rMousePos );
1077*cdf0e10cSrcweir 
1078*cdf0e10cSrcweir             if( bDragToMouse )
1079*cdf0e10cSrcweir                 ImplDragThumb( rMousePos );
1080*cdf0e10cSrcweir         }
1081*cdf0e10cSrcweir     }
1082*cdf0e10cSrcweir }
1083*cdf0e10cSrcweir 
1084*cdf0e10cSrcweir // -----------------------------------------------------------------------
1085*cdf0e10cSrcweir 
1086*cdf0e10cSrcweir void ScrollBar::Tracking( const TrackingEvent& rTEvt )
1087*cdf0e10cSrcweir {
1088*cdf0e10cSrcweir     if ( rTEvt.IsTrackingEnded() )
1089*cdf0e10cSrcweir     {
1090*cdf0e10cSrcweir         // Button und PageRect-Status wieder herstellen
1091*cdf0e10cSrcweir         sal_uInt16 nOldStateFlags = mnStateFlags;
1092*cdf0e10cSrcweir         mnStateFlags &= ~(SCRBAR_STATE_BTN1_DOWN | SCRBAR_STATE_BTN2_DOWN |
1093*cdf0e10cSrcweir                           SCRBAR_STATE_PAGE1_DOWN | SCRBAR_STATE_PAGE2_DOWN |
1094*cdf0e10cSrcweir                           SCRBAR_STATE_THUMB_DOWN);
1095*cdf0e10cSrcweir         if ( nOldStateFlags != mnStateFlags )
1096*cdf0e10cSrcweir             ImplDraw( mnDragDraw, this );
1097*cdf0e10cSrcweir         mnDragDraw = 0;
1098*cdf0e10cSrcweir 
1099*cdf0e10cSrcweir         // Bei Abbruch, die alte ThumbPosition wieder herstellen
1100*cdf0e10cSrcweir         if ( rTEvt.IsTrackingCanceled() )
1101*cdf0e10cSrcweir         {
1102*cdf0e10cSrcweir             long nOldPos = mnThumbPos;
1103*cdf0e10cSrcweir             SetThumbPos( mnStartPos );
1104*cdf0e10cSrcweir             mnDelta = mnThumbPos-nOldPos;
1105*cdf0e10cSrcweir             Scroll();
1106*cdf0e10cSrcweir         }
1107*cdf0e10cSrcweir 
1108*cdf0e10cSrcweir         if ( meScrollType == SCROLL_DRAG )
1109*cdf0e10cSrcweir         {
1110*cdf0e10cSrcweir             // Wenn gedragt wurde, berechnen wir den Thumb neu, damit
1111*cdf0e10cSrcweir             // er wieder auf einer gerundeten ThumbPosition steht
1112*cdf0e10cSrcweir             ImplCalc();
1113*cdf0e10cSrcweir 
1114*cdf0e10cSrcweir             if ( !mbFullDrag && (mnStartPos != mnThumbPos) )
1115*cdf0e10cSrcweir             {
1116*cdf0e10cSrcweir                 mnDelta = mnThumbPos-mnStartPos;
1117*cdf0e10cSrcweir                 Scroll();
1118*cdf0e10cSrcweir                 mnDelta = 0;
1119*cdf0e10cSrcweir             }
1120*cdf0e10cSrcweir         }
1121*cdf0e10cSrcweir 
1122*cdf0e10cSrcweir         mnDelta = mnThumbPos-mnStartPos;
1123*cdf0e10cSrcweir         EndScroll();
1124*cdf0e10cSrcweir         mnDelta = 0;
1125*cdf0e10cSrcweir         meScrollType = SCROLL_DONTKNOW;
1126*cdf0e10cSrcweir 
1127*cdf0e10cSrcweir         if( mpData )
1128*cdf0e10cSrcweir             mpData->mbHide = sal_False; // re-enable focus blinking
1129*cdf0e10cSrcweir     }
1130*cdf0e10cSrcweir     else
1131*cdf0e10cSrcweir     {
1132*cdf0e10cSrcweir         const Point rMousePos = rTEvt.GetMouseEvent().GetPosPixel();
1133*cdf0e10cSrcweir 
1134*cdf0e10cSrcweir         // Dragging wird speziell behandelt
1135*cdf0e10cSrcweir         if ( meScrollType == SCROLL_DRAG )
1136*cdf0e10cSrcweir             ImplDragThumb( rMousePos );
1137*cdf0e10cSrcweir         else
1138*cdf0e10cSrcweir             ImplDoMouseAction( rMousePos, rTEvt.IsTrackingRepeat() );
1139*cdf0e10cSrcweir 
1140*cdf0e10cSrcweir         // Wenn ScrollBar-Werte so umgesetzt wurden, das es nichts
1141*cdf0e10cSrcweir         // mehr zum Tracking gibt, dann berechen wir hier ab
1142*cdf0e10cSrcweir         if ( !IsVisible() || (mnVisibleSize >= (mnMaxRange-mnMinRange)) )
1143*cdf0e10cSrcweir             EndTracking();
1144*cdf0e10cSrcweir     }
1145*cdf0e10cSrcweir }
1146*cdf0e10cSrcweir 
1147*cdf0e10cSrcweir // -----------------------------------------------------------------------
1148*cdf0e10cSrcweir 
1149*cdf0e10cSrcweir void ScrollBar::KeyInput( const KeyEvent& rKEvt )
1150*cdf0e10cSrcweir {
1151*cdf0e10cSrcweir     if ( !rKEvt.GetKeyCode().GetModifier() )
1152*cdf0e10cSrcweir     {
1153*cdf0e10cSrcweir         switch ( rKEvt.GetKeyCode().GetCode() )
1154*cdf0e10cSrcweir         {
1155*cdf0e10cSrcweir             case KEY_HOME:
1156*cdf0e10cSrcweir                 DoScroll( 0 );
1157*cdf0e10cSrcweir                 break;
1158*cdf0e10cSrcweir 
1159*cdf0e10cSrcweir             case KEY_END:
1160*cdf0e10cSrcweir                 DoScroll( GetRangeMax() );
1161*cdf0e10cSrcweir                 break;
1162*cdf0e10cSrcweir 
1163*cdf0e10cSrcweir             case KEY_LEFT:
1164*cdf0e10cSrcweir             case KEY_UP:
1165*cdf0e10cSrcweir                 DoScrollAction( SCROLL_LINEUP );
1166*cdf0e10cSrcweir                 break;
1167*cdf0e10cSrcweir 
1168*cdf0e10cSrcweir             case KEY_RIGHT:
1169*cdf0e10cSrcweir             case KEY_DOWN:
1170*cdf0e10cSrcweir                 DoScrollAction( SCROLL_LINEDOWN );
1171*cdf0e10cSrcweir                 break;
1172*cdf0e10cSrcweir 
1173*cdf0e10cSrcweir             case KEY_PAGEUP:
1174*cdf0e10cSrcweir                 DoScrollAction( SCROLL_PAGEUP );
1175*cdf0e10cSrcweir                 break;
1176*cdf0e10cSrcweir 
1177*cdf0e10cSrcweir             case KEY_PAGEDOWN:
1178*cdf0e10cSrcweir                 DoScrollAction( SCROLL_PAGEDOWN );
1179*cdf0e10cSrcweir                 break;
1180*cdf0e10cSrcweir 
1181*cdf0e10cSrcweir             default:
1182*cdf0e10cSrcweir                 Control::KeyInput( rKEvt );
1183*cdf0e10cSrcweir                 break;
1184*cdf0e10cSrcweir         }
1185*cdf0e10cSrcweir     }
1186*cdf0e10cSrcweir     else
1187*cdf0e10cSrcweir         Control::KeyInput( rKEvt );
1188*cdf0e10cSrcweir }
1189*cdf0e10cSrcweir 
1190*cdf0e10cSrcweir // -----------------------------------------------------------------------
1191*cdf0e10cSrcweir 
1192*cdf0e10cSrcweir void ScrollBar::Paint( const Rectangle& )
1193*cdf0e10cSrcweir {
1194*cdf0e10cSrcweir     ImplDraw( SCRBAR_DRAW_ALL, this );
1195*cdf0e10cSrcweir }
1196*cdf0e10cSrcweir 
1197*cdf0e10cSrcweir // -----------------------------------------------------------------------
1198*cdf0e10cSrcweir 
1199*cdf0e10cSrcweir void ScrollBar::Resize()
1200*cdf0e10cSrcweir {
1201*cdf0e10cSrcweir     Control::Resize();
1202*cdf0e10cSrcweir     mbCalcSize = sal_True;
1203*cdf0e10cSrcweir     if ( IsReallyVisible() )
1204*cdf0e10cSrcweir         ImplCalc( sal_False );
1205*cdf0e10cSrcweir     Invalidate();
1206*cdf0e10cSrcweir }
1207*cdf0e10cSrcweir 
1208*cdf0e10cSrcweir // -----------------------------------------------------------------------
1209*cdf0e10cSrcweir 
1210*cdf0e10cSrcweir IMPL_LINK( ScrollBar, ImplAutoTimerHdl, AutoTimer*, EMPTYARG )
1211*cdf0e10cSrcweir {
1212*cdf0e10cSrcweir     if( mpData && mpData->mbHide )
1213*cdf0e10cSrcweir         return 0;
1214*cdf0e10cSrcweir     ImplInvert();
1215*cdf0e10cSrcweir     return 0;
1216*cdf0e10cSrcweir }
1217*cdf0e10cSrcweir 
1218*cdf0e10cSrcweir void ScrollBar::ImplInvert()
1219*cdf0e10cSrcweir {
1220*cdf0e10cSrcweir     Rectangle aRect( maThumbRect );
1221*cdf0e10cSrcweir     if( aRect.getWidth() > 4 )
1222*cdf0e10cSrcweir     {
1223*cdf0e10cSrcweir         aRect.Left() += 2;
1224*cdf0e10cSrcweir         aRect.Right() -= 2;
1225*cdf0e10cSrcweir     }
1226*cdf0e10cSrcweir     if( aRect.getHeight() > 4 )
1227*cdf0e10cSrcweir     {
1228*cdf0e10cSrcweir         aRect.Top() += 2;
1229*cdf0e10cSrcweir         aRect.Bottom() -= 2;
1230*cdf0e10cSrcweir     }
1231*cdf0e10cSrcweir 
1232*cdf0e10cSrcweir     Invert( aRect, 0 );
1233*cdf0e10cSrcweir }
1234*cdf0e10cSrcweir 
1235*cdf0e10cSrcweir // -----------------------------------------------------------------------
1236*cdf0e10cSrcweir 
1237*cdf0e10cSrcweir void ScrollBar::GetFocus()
1238*cdf0e10cSrcweir {
1239*cdf0e10cSrcweir     if( !mpData )
1240*cdf0e10cSrcweir     {
1241*cdf0e10cSrcweir         mpData = new ImplScrollBarData;
1242*cdf0e10cSrcweir         mpData->maTimer.SetTimeoutHdl( LINK( this, ScrollBar, ImplAutoTimerHdl ) );
1243*cdf0e10cSrcweir         mpData->mbHide = sal_False;
1244*cdf0e10cSrcweir     }
1245*cdf0e10cSrcweir     ImplInvert();   // react immediately
1246*cdf0e10cSrcweir     mpData->maTimer.SetTimeout( GetSettings().GetStyleSettings().GetCursorBlinkTime() );
1247*cdf0e10cSrcweir     mpData->maTimer.Start();
1248*cdf0e10cSrcweir     Control::GetFocus();
1249*cdf0e10cSrcweir }
1250*cdf0e10cSrcweir 
1251*cdf0e10cSrcweir // -----------------------------------------------------------------------
1252*cdf0e10cSrcweir 
1253*cdf0e10cSrcweir void ScrollBar::LoseFocus()
1254*cdf0e10cSrcweir {
1255*cdf0e10cSrcweir     if( mpData )
1256*cdf0e10cSrcweir         mpData->maTimer.Stop();
1257*cdf0e10cSrcweir     ImplDraw( SCRBAR_DRAW_THUMB, this );
1258*cdf0e10cSrcweir 
1259*cdf0e10cSrcweir     Control::LoseFocus();
1260*cdf0e10cSrcweir }
1261*cdf0e10cSrcweir 
1262*cdf0e10cSrcweir // -----------------------------------------------------------------------
1263*cdf0e10cSrcweir 
1264*cdf0e10cSrcweir void ScrollBar::StateChanged( StateChangedType nType )
1265*cdf0e10cSrcweir {
1266*cdf0e10cSrcweir     Control::StateChanged( nType );
1267*cdf0e10cSrcweir 
1268*cdf0e10cSrcweir     if ( nType == STATE_CHANGE_INITSHOW )
1269*cdf0e10cSrcweir         ImplCalc( sal_False );
1270*cdf0e10cSrcweir     else if ( nType == STATE_CHANGE_DATA )
1271*cdf0e10cSrcweir     {
1272*cdf0e10cSrcweir         if ( IsReallyVisible() && IsUpdateMode() )
1273*cdf0e10cSrcweir             ImplCalc( sal_True );
1274*cdf0e10cSrcweir     }
1275*cdf0e10cSrcweir     else if ( nType == STATE_CHANGE_UPDATEMODE )
1276*cdf0e10cSrcweir     {
1277*cdf0e10cSrcweir         if ( IsReallyVisible() && IsUpdateMode() )
1278*cdf0e10cSrcweir         {
1279*cdf0e10cSrcweir             ImplCalc( sal_False );
1280*cdf0e10cSrcweir             Invalidate();
1281*cdf0e10cSrcweir         }
1282*cdf0e10cSrcweir     }
1283*cdf0e10cSrcweir     else if ( nType == STATE_CHANGE_ENABLE )
1284*cdf0e10cSrcweir     {
1285*cdf0e10cSrcweir         if ( IsReallyVisible() && IsUpdateMode() )
1286*cdf0e10cSrcweir             Invalidate();
1287*cdf0e10cSrcweir     }
1288*cdf0e10cSrcweir     else if ( nType == STATE_CHANGE_STYLE )
1289*cdf0e10cSrcweir     {
1290*cdf0e10cSrcweir         ImplInitStyle( GetStyle() );
1291*cdf0e10cSrcweir         if ( IsReallyVisible() && IsUpdateMode() )
1292*cdf0e10cSrcweir         {
1293*cdf0e10cSrcweir             if ( (GetPrevStyle() & SCRBAR_VIEW_STYLE) !=
1294*cdf0e10cSrcweir                  (GetStyle() & SCRBAR_VIEW_STYLE) )
1295*cdf0e10cSrcweir             {
1296*cdf0e10cSrcweir                 mbCalcSize = sal_True;
1297*cdf0e10cSrcweir                 ImplCalc( sal_False );
1298*cdf0e10cSrcweir                 Invalidate();
1299*cdf0e10cSrcweir             }
1300*cdf0e10cSrcweir         }
1301*cdf0e10cSrcweir     }
1302*cdf0e10cSrcweir }
1303*cdf0e10cSrcweir 
1304*cdf0e10cSrcweir // -----------------------------------------------------------------------
1305*cdf0e10cSrcweir 
1306*cdf0e10cSrcweir void ScrollBar::DataChanged( const DataChangedEvent& rDCEvt )
1307*cdf0e10cSrcweir {
1308*cdf0e10cSrcweir     Control::DataChanged( rDCEvt );
1309*cdf0e10cSrcweir 
1310*cdf0e10cSrcweir     if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
1311*cdf0e10cSrcweir          (rDCEvt.GetFlags() & SETTINGS_STYLE) )
1312*cdf0e10cSrcweir     {
1313*cdf0e10cSrcweir         mbCalcSize = sal_True;
1314*cdf0e10cSrcweir         ImplCalc( sal_False );
1315*cdf0e10cSrcweir         Invalidate();
1316*cdf0e10cSrcweir     }
1317*cdf0e10cSrcweir }
1318*cdf0e10cSrcweir 
1319*cdf0e10cSrcweir // -----------------------------------------------------------------------
1320*cdf0e10cSrcweir 
1321*cdf0e10cSrcweir Rectangle* ScrollBar::ImplFindPartRect( const Point& rPt )
1322*cdf0e10cSrcweir {
1323*cdf0e10cSrcweir     sal_Bool    bHorizontal = ( GetStyle() & WB_HORZ )? sal_True: sal_False;
1324*cdf0e10cSrcweir     sal_Bool    bIsInside = sal_False;
1325*cdf0e10cSrcweir 
1326*cdf0e10cSrcweir     Point aPoint( 0, 0 );
1327*cdf0e10cSrcweir     Rectangle aControlRegion( aPoint, GetOutputSizePixel() );
1328*cdf0e10cSrcweir 
1329*cdf0e10cSrcweir     if( HitTestNativeControl( CTRL_SCROLLBAR, bHorizontal? PART_BUTTON_LEFT: PART_BUTTON_UP,
1330*cdf0e10cSrcweir                 aControlRegion, rPt, bIsInside )?
1331*cdf0e10cSrcweir             bIsInside:
1332*cdf0e10cSrcweir             maBtn1Rect.IsInside( rPt ) )
1333*cdf0e10cSrcweir         return &maBtn1Rect;
1334*cdf0e10cSrcweir     else if( HitTestNativeControl( CTRL_SCROLLBAR, bHorizontal? PART_BUTTON_RIGHT: PART_BUTTON_DOWN,
1335*cdf0e10cSrcweir                 aControlRegion, rPt, bIsInside )?
1336*cdf0e10cSrcweir             bIsInside:
1337*cdf0e10cSrcweir             maBtn2Rect.IsInside( rPt ) )
1338*cdf0e10cSrcweir         return &maBtn2Rect;
1339*cdf0e10cSrcweir     // HitTestNativeControl, see remark at top of file
1340*cdf0e10cSrcweir     else if( HitTestNativeControl( CTRL_SCROLLBAR,  bHorizontal ? PART_TRACK_HORZ_LEFT : PART_TRACK_VERT_UPPER,
1341*cdf0e10cSrcweir                 maPage1Rect, rPt, bIsInside)?
1342*cdf0e10cSrcweir             bIsInside:
1343*cdf0e10cSrcweir             maPage1Rect.IsInside( rPt ) )
1344*cdf0e10cSrcweir         return &maPage1Rect;
1345*cdf0e10cSrcweir     // HitTestNativeControl, see remark at top of file
1346*cdf0e10cSrcweir     else if( HitTestNativeControl( CTRL_SCROLLBAR,  bHorizontal ? PART_TRACK_HORZ_RIGHT : PART_TRACK_VERT_LOWER,
1347*cdf0e10cSrcweir                 maPage2Rect, rPt, bIsInside)?
1348*cdf0e10cSrcweir             bIsInside:
1349*cdf0e10cSrcweir             maPage2Rect.IsInside( rPt ) )
1350*cdf0e10cSrcweir         return &maPage2Rect;
1351*cdf0e10cSrcweir     // HitTestNativeControl, see remark at top of file
1352*cdf0e10cSrcweir     else if( HitTestNativeControl( CTRL_SCROLLBAR,  bHorizontal ? PART_THUMB_HORZ : PART_THUMB_VERT,
1353*cdf0e10cSrcweir                 maThumbRect, rPt, bIsInside)?
1354*cdf0e10cSrcweir              bIsInside:
1355*cdf0e10cSrcweir              maThumbRect.IsInside( rPt ) )
1356*cdf0e10cSrcweir         return &maThumbRect;
1357*cdf0e10cSrcweir     else
1358*cdf0e10cSrcweir         return NULL;
1359*cdf0e10cSrcweir }
1360*cdf0e10cSrcweir 
1361*cdf0e10cSrcweir long ScrollBar::PreNotify( NotifyEvent& rNEvt )
1362*cdf0e10cSrcweir {
1363*cdf0e10cSrcweir     long nDone = 0;
1364*cdf0e10cSrcweir     const MouseEvent* pMouseEvt = NULL;
1365*cdf0e10cSrcweir 
1366*cdf0e10cSrcweir     if( (rNEvt.GetType() == EVENT_MOUSEMOVE) && (pMouseEvt = rNEvt.GetMouseEvent()) != NULL )
1367*cdf0e10cSrcweir     {
1368*cdf0e10cSrcweir         if( !pMouseEvt->GetButtons() && !pMouseEvt->IsSynthetic() && !pMouseEvt->IsModifierChanged() )
1369*cdf0e10cSrcweir         {
1370*cdf0e10cSrcweir             // trigger redraw if mouse over state has changed
1371*cdf0e10cSrcweir             if( IsNativeControlSupported(CTRL_SCROLLBAR, PART_ENTIRE_CONTROL) )
1372*cdf0e10cSrcweir             {
1373*cdf0e10cSrcweir                 Rectangle* pRect = ImplFindPartRect( GetPointerPosPixel() );
1374*cdf0e10cSrcweir                 Rectangle* pLastRect = ImplFindPartRect( GetLastPointerPosPixel() );
1375*cdf0e10cSrcweir                 if( pRect != pLastRect || pMouseEvt->IsLeaveWindow() || pMouseEvt->IsEnterWindow() )
1376*cdf0e10cSrcweir                 {
1377*cdf0e10cSrcweir                     Region aRgn( GetActiveClipRegion() );
1378*cdf0e10cSrcweir                     Region aClipRegion;
1379*cdf0e10cSrcweir 
1380*cdf0e10cSrcweir                     if ( pRect )
1381*cdf0e10cSrcweir                         aClipRegion.Union( *pRect );
1382*cdf0e10cSrcweir                     if ( pLastRect )
1383*cdf0e10cSrcweir                         aClipRegion.Union( *pLastRect );
1384*cdf0e10cSrcweir 
1385*cdf0e10cSrcweir                     // Support for 3-button scroll bars
1386*cdf0e10cSrcweir                     sal_Bool bHas3Buttons = IsNativeControlSupported( CTRL_SCROLLBAR, HAS_THREE_BUTTONS );
1387*cdf0e10cSrcweir                     if ( bHas3Buttons && ( pRect == &maBtn1Rect || pLastRect == &maBtn1Rect ) )
1388*cdf0e10cSrcweir                     {
1389*cdf0e10cSrcweir                         aClipRegion.Union( maBtn2Rect );
1390*cdf0e10cSrcweir                     }
1391*cdf0e10cSrcweir 
1392*cdf0e10cSrcweir                     SetClipRegion( aClipRegion );
1393*cdf0e10cSrcweir                     Paint( aClipRegion.GetBoundRect() );
1394*cdf0e10cSrcweir 
1395*cdf0e10cSrcweir                     SetClipRegion( aRgn );
1396*cdf0e10cSrcweir                 }
1397*cdf0e10cSrcweir             }
1398*cdf0e10cSrcweir         }
1399*cdf0e10cSrcweir     }
1400*cdf0e10cSrcweir 
1401*cdf0e10cSrcweir     return nDone ? nDone : Control::PreNotify(rNEvt);
1402*cdf0e10cSrcweir }
1403*cdf0e10cSrcweir 
1404*cdf0e10cSrcweir // -----------------------------------------------------------------------
1405*cdf0e10cSrcweir 
1406*cdf0e10cSrcweir void ScrollBar::Scroll()
1407*cdf0e10cSrcweir {
1408*cdf0e10cSrcweir     ImplCallEventListenersAndHandler( VCLEVENT_SCROLLBAR_SCROLL, maScrollHdl, this );
1409*cdf0e10cSrcweir }
1410*cdf0e10cSrcweir 
1411*cdf0e10cSrcweir // -----------------------------------------------------------------------
1412*cdf0e10cSrcweir 
1413*cdf0e10cSrcweir void ScrollBar::EndScroll()
1414*cdf0e10cSrcweir {
1415*cdf0e10cSrcweir     ImplCallEventListenersAndHandler( VCLEVENT_SCROLLBAR_ENDSCROLL, maEndScrollHdl, this );
1416*cdf0e10cSrcweir }
1417*cdf0e10cSrcweir 
1418*cdf0e10cSrcweir // -----------------------------------------------------------------------
1419*cdf0e10cSrcweir 
1420*cdf0e10cSrcweir long ScrollBar::DoScroll( long nNewPos )
1421*cdf0e10cSrcweir {
1422*cdf0e10cSrcweir     if ( meScrollType != SCROLL_DONTKNOW )
1423*cdf0e10cSrcweir         return 0;
1424*cdf0e10cSrcweir 
1425*cdf0e10cSrcweir     meScrollType = SCROLL_DRAG;
1426*cdf0e10cSrcweir     long nDelta = ImplScroll( nNewPos, sal_True );
1427*cdf0e10cSrcweir     meScrollType = SCROLL_DONTKNOW;
1428*cdf0e10cSrcweir     return nDelta;
1429*cdf0e10cSrcweir }
1430*cdf0e10cSrcweir 
1431*cdf0e10cSrcweir // -----------------------------------------------------------------------
1432*cdf0e10cSrcweir 
1433*cdf0e10cSrcweir long ScrollBar::DoScrollAction( ScrollType eScrollType )
1434*cdf0e10cSrcweir {
1435*cdf0e10cSrcweir     if ( (meScrollType != SCROLL_DONTKNOW) ||
1436*cdf0e10cSrcweir          (eScrollType == SCROLL_DONTKNOW) ||
1437*cdf0e10cSrcweir          (eScrollType == SCROLL_DRAG) )
1438*cdf0e10cSrcweir         return 0;
1439*cdf0e10cSrcweir 
1440*cdf0e10cSrcweir     meScrollType = eScrollType;
1441*cdf0e10cSrcweir     long nDelta = ImplDoAction( sal_True );
1442*cdf0e10cSrcweir     meScrollType = SCROLL_DONTKNOW;
1443*cdf0e10cSrcweir     return nDelta;
1444*cdf0e10cSrcweir }
1445*cdf0e10cSrcweir 
1446*cdf0e10cSrcweir // -----------------------------------------------------------------------
1447*cdf0e10cSrcweir 
1448*cdf0e10cSrcweir void ScrollBar::SetRangeMin( long nNewRange )
1449*cdf0e10cSrcweir {
1450*cdf0e10cSrcweir     SetRange( Range( nNewRange, GetRangeMax() ) );
1451*cdf0e10cSrcweir }
1452*cdf0e10cSrcweir 
1453*cdf0e10cSrcweir // -----------------------------------------------------------------------
1454*cdf0e10cSrcweir 
1455*cdf0e10cSrcweir void ScrollBar::SetRangeMax( long nNewRange )
1456*cdf0e10cSrcweir {
1457*cdf0e10cSrcweir     SetRange( Range( GetRangeMin(), nNewRange ) );
1458*cdf0e10cSrcweir }
1459*cdf0e10cSrcweir 
1460*cdf0e10cSrcweir // -----------------------------------------------------------------------
1461*cdf0e10cSrcweir 
1462*cdf0e10cSrcweir void ScrollBar::SetRange( const Range& rRange )
1463*cdf0e10cSrcweir {
1464*cdf0e10cSrcweir     // Range einpassen
1465*cdf0e10cSrcweir     Range aRange = rRange;
1466*cdf0e10cSrcweir     aRange.Justify();
1467*cdf0e10cSrcweir     long nNewMinRange = aRange.Min();
1468*cdf0e10cSrcweir     long nNewMaxRange = aRange.Max();
1469*cdf0e10cSrcweir 
1470*cdf0e10cSrcweir     // Wenn Range sich unterscheidet, dann neuen setzen
1471*cdf0e10cSrcweir     if ( (mnMinRange != nNewMinRange) ||
1472*cdf0e10cSrcweir          (mnMaxRange != nNewMaxRange) )
1473*cdf0e10cSrcweir     {
1474*cdf0e10cSrcweir         mnMinRange = nNewMinRange;
1475*cdf0e10cSrcweir         mnMaxRange = nNewMaxRange;
1476*cdf0e10cSrcweir 
1477*cdf0e10cSrcweir         // Thumb einpassen
1478*cdf0e10cSrcweir         if ( mnThumbPos > mnMaxRange-mnVisibleSize )
1479*cdf0e10cSrcweir             mnThumbPos = mnMaxRange-mnVisibleSize;
1480*cdf0e10cSrcweir         if ( mnThumbPos < mnMinRange )
1481*cdf0e10cSrcweir             mnThumbPos = mnMinRange;
1482*cdf0e10cSrcweir 
1483*cdf0e10cSrcweir         StateChanged( STATE_CHANGE_DATA );
1484*cdf0e10cSrcweir     }
1485*cdf0e10cSrcweir }
1486*cdf0e10cSrcweir 
1487*cdf0e10cSrcweir // -----------------------------------------------------------------------
1488*cdf0e10cSrcweir 
1489*cdf0e10cSrcweir void ScrollBar::SetThumbPos( long nNewThumbPos )
1490*cdf0e10cSrcweir {
1491*cdf0e10cSrcweir     if ( nNewThumbPos > mnMaxRange-mnVisibleSize )
1492*cdf0e10cSrcweir         nNewThumbPos = mnMaxRange-mnVisibleSize;
1493*cdf0e10cSrcweir     if ( nNewThumbPos < mnMinRange )
1494*cdf0e10cSrcweir         nNewThumbPos = mnMinRange;
1495*cdf0e10cSrcweir 
1496*cdf0e10cSrcweir     if ( mnThumbPos != nNewThumbPos )
1497*cdf0e10cSrcweir     {
1498*cdf0e10cSrcweir         mnThumbPos = nNewThumbPos;
1499*cdf0e10cSrcweir         StateChanged( STATE_CHANGE_DATA );
1500*cdf0e10cSrcweir     }
1501*cdf0e10cSrcweir }
1502*cdf0e10cSrcweir 
1503*cdf0e10cSrcweir // -----------------------------------------------------------------------
1504*cdf0e10cSrcweir 
1505*cdf0e10cSrcweir void ScrollBar::SetVisibleSize( long nNewSize )
1506*cdf0e10cSrcweir {
1507*cdf0e10cSrcweir     if ( mnVisibleSize != nNewSize )
1508*cdf0e10cSrcweir     {
1509*cdf0e10cSrcweir         mnVisibleSize = nNewSize;
1510*cdf0e10cSrcweir 
1511*cdf0e10cSrcweir         // Thumb einpassen
1512*cdf0e10cSrcweir         if ( mnThumbPos > mnMaxRange-mnVisibleSize )
1513*cdf0e10cSrcweir             mnThumbPos = mnMaxRange-mnVisibleSize;
1514*cdf0e10cSrcweir         if ( mnThumbPos < mnMinRange )
1515*cdf0e10cSrcweir             mnThumbPos = mnMinRange;
1516*cdf0e10cSrcweir         StateChanged( STATE_CHANGE_DATA );
1517*cdf0e10cSrcweir     }
1518*cdf0e10cSrcweir }
1519*cdf0e10cSrcweir 
1520*cdf0e10cSrcweir // =======================================================================
1521*cdf0e10cSrcweir 
1522*cdf0e10cSrcweir void ScrollBarBox::ImplInit( Window* pParent, WinBits nStyle )
1523*cdf0e10cSrcweir {
1524*cdf0e10cSrcweir     Window::ImplInit( pParent, nStyle, NULL );
1525*cdf0e10cSrcweir 
1526*cdf0e10cSrcweir     const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1527*cdf0e10cSrcweir     long nScrollSize = rStyleSettings.GetScrollBarSize();
1528*cdf0e10cSrcweir     SetSizePixel( Size( nScrollSize, nScrollSize ) );
1529*cdf0e10cSrcweir     ImplInitSettings();
1530*cdf0e10cSrcweir }
1531*cdf0e10cSrcweir 
1532*cdf0e10cSrcweir // -----------------------------------------------------------------------
1533*cdf0e10cSrcweir 
1534*cdf0e10cSrcweir ScrollBarBox::ScrollBarBox( Window* pParent, WinBits nStyle ) :
1535*cdf0e10cSrcweir     Window( WINDOW_SCROLLBARBOX )
1536*cdf0e10cSrcweir {
1537*cdf0e10cSrcweir     ImplInit( pParent, nStyle );
1538*cdf0e10cSrcweir }
1539*cdf0e10cSrcweir 
1540*cdf0e10cSrcweir // -----------------------------------------------------------------------
1541*cdf0e10cSrcweir 
1542*cdf0e10cSrcweir ScrollBarBox::ScrollBarBox( Window* pParent, const ResId& rResId ) :
1543*cdf0e10cSrcweir     Window( WINDOW_SCROLLBARBOX )
1544*cdf0e10cSrcweir {
1545*cdf0e10cSrcweir     rResId.SetRT( RSC_SCROLLBAR );
1546*cdf0e10cSrcweir     ImplInit( pParent, ImplInitRes( rResId ) );
1547*cdf0e10cSrcweir     ImplLoadRes( rResId );
1548*cdf0e10cSrcweir }
1549*cdf0e10cSrcweir 
1550*cdf0e10cSrcweir // -----------------------------------------------------------------------
1551*cdf0e10cSrcweir 
1552*cdf0e10cSrcweir void ScrollBarBox::ImplInitSettings()
1553*cdf0e10cSrcweir {
1554*cdf0e10cSrcweir     // Hack, damit man auch DockingWindows ohne Hintergrund bauen kann
1555*cdf0e10cSrcweir     // und noch nicht alles umgestellt ist
1556*cdf0e10cSrcweir     if ( IsBackground() )
1557*cdf0e10cSrcweir     {
1558*cdf0e10cSrcweir         Color aColor;
1559*cdf0e10cSrcweir         if ( IsControlBackground() )
1560*cdf0e10cSrcweir             aColor = GetControlBackground();
1561*cdf0e10cSrcweir         else
1562*cdf0e10cSrcweir             aColor = GetSettings().GetStyleSettings().GetFaceColor();
1563*cdf0e10cSrcweir         SetBackground( aColor );
1564*cdf0e10cSrcweir     }
1565*cdf0e10cSrcweir }
1566*cdf0e10cSrcweir 
1567*cdf0e10cSrcweir // -----------------------------------------------------------------------
1568*cdf0e10cSrcweir 
1569*cdf0e10cSrcweir void ScrollBarBox::StateChanged( StateChangedType nType )
1570*cdf0e10cSrcweir {
1571*cdf0e10cSrcweir     Window::StateChanged( nType );
1572*cdf0e10cSrcweir 
1573*cdf0e10cSrcweir     if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
1574*cdf0e10cSrcweir     {
1575*cdf0e10cSrcweir         ImplInitSettings();
1576*cdf0e10cSrcweir         Invalidate();
1577*cdf0e10cSrcweir     }
1578*cdf0e10cSrcweir }
1579*cdf0e10cSrcweir 
1580*cdf0e10cSrcweir // -----------------------------------------------------------------------
1581*cdf0e10cSrcweir 
1582*cdf0e10cSrcweir void ScrollBarBox::DataChanged( const DataChangedEvent& rDCEvt )
1583*cdf0e10cSrcweir {
1584*cdf0e10cSrcweir     Window::DataChanged( rDCEvt );
1585*cdf0e10cSrcweir 
1586*cdf0e10cSrcweir     if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
1587*cdf0e10cSrcweir          (rDCEvt.GetFlags() & SETTINGS_STYLE) )
1588*cdf0e10cSrcweir     {
1589*cdf0e10cSrcweir         ImplInitSettings();
1590*cdf0e10cSrcweir         Invalidate();
1591*cdf0e10cSrcweir     }
1592*cdf0e10cSrcweir }
1593