1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "vcl/event.hxx"
22 #include "vcl/decoview.hxx"
23 #include "vcl/scrbar.hxx"
24 #include "vcl/timer.hxx"
28 #include "rtl/string.hxx"
34 HACK: for scrollbars in case of thumb rect, page up and page down rect we
35 abuse the HitTestNativeControl interface. All theming engines but aqua
36 are actually able to draw the thumb according to our internal representation.
37 However aqua draws a little outside. The canonical way would be to enhance the
38 HitTestNativeControl passing a ScrollbarValue additionally so all necessary
39 information is available in the call.
41 However since there is only this one small exception we will deviate a little and
42 instead pass the respective rect as control region to allow for a small correction.
44 So all places using HitTestNativeControl on PART_THUMB_HORZ, PART_THUMB_VERT,
45 PART_TRACK_HORZ_LEFT, PART_TRACK_HORZ_RIGHT, PART_TRACK_VERT_UPPER, PART_TRACK_VERT_LOWER
46 do not use the control rectangle as region but the actuall part rectangle, making
47 only small deviations feasible.
50 #include "thumbpos.hxx"
54 #define SCRBAR_DRAW_BTN1 ((sal_uInt16)0x0001)
55 #define SCRBAR_DRAW_BTN2 ((sal_uInt16)0x0002)
56 #define SCRBAR_DRAW_PAGE1 ((sal_uInt16)0x0004)
57 #define SCRBAR_DRAW_PAGE2 ((sal_uInt16)0x0008)
58 #define SCRBAR_DRAW_THUMB ((sal_uInt16)0x0010)
59 #define SCRBAR_DRAW_BACKGROUND ((sal_uInt16)0x0020)
60 #define SCRBAR_DRAW_ALL (SCRBAR_DRAW_BTN1 | SCRBAR_DRAW_BTN2 | \
61 SCRBAR_DRAW_PAGE1 | SCRBAR_DRAW_PAGE2 |\
62 SCRBAR_DRAW_THUMB | SCRBAR_DRAW_BACKGROUND )
64 #define SCRBAR_STATE_BTN1_DOWN ((sal_uInt16)0x0001)
65 #define SCRBAR_STATE_BTN1_DISABLE ((sal_uInt16)0x0002)
66 #define SCRBAR_STATE_BTN2_DOWN ((sal_uInt16)0x0004)
67 #define SCRBAR_STATE_BTN2_DISABLE ((sal_uInt16)0x0008)
68 #define SCRBAR_STATE_PAGE1_DOWN ((sal_uInt16)0x0010)
69 #define SCRBAR_STATE_PAGE2_DOWN ((sal_uInt16)0x0020)
70 #define SCRBAR_STATE_THUMB_DOWN ((sal_uInt16)0x0040)
72 #define SCRBAR_VIEW_STYLE (WB_3DLOOK | WB_HORZ | WB_VERT)
74 struct ImplScrollBarData
76 AutoTimer maTimer
; // Timer
78 Rectangle maTrackRect
; // TODO: move to ScrollBar class when binary incompatibility of ScrollBar class is no longer problematic
81 void ScrollBar::ImplInit( Window
* pParent
, WinBits nStyle
)
96 meScrollType
= SCROLL_DONTKNOW
;
97 meDDScrollType
= SCROLL_DONTKNOW
;
98 mbCalcSize
= sal_True
;
101 if( !mpData
) // TODO: remove when maTrackRect is no longer in mpData
103 mpData
= new ImplScrollBarData
;
104 mpData
->maTimer
.SetTimeoutHdl( LINK( this, ScrollBar
, ImplAutoTimerHdl
) );
105 mpData
->mbHide
= false;
108 ImplInitStyle( nStyle
);
109 Control::ImplInit( pParent
, nStyle
, NULL
);
111 long nScrollSize
= GetSettings().GetStyleSettings().GetScrollBarSize();
112 SetSizePixel( Size( nScrollSize
, nScrollSize
) );
117 void ScrollBar::ImplInitStyle( WinBits nStyle
)
119 if ( nStyle
& WB_DRAG
)
120 mbFullDrag
= sal_True
;
122 mbFullDrag
= (GetSettings().GetStyleSettings().GetDragFullOptions() & DRAGFULL_OPTION_SCROLL
) != 0;
126 ScrollBar::ScrollBar( Window
* pParent
, WinBits nStyle
) :
127 Control( WINDOW_SCROLLBAR
)
129 ImplInit( pParent
, nStyle
);
133 ScrollBar::ScrollBar( Window
* pParent
, const ResId
& rResId
) :
134 Control( WINDOW_SCROLLBAR
)
136 rResId
.SetRT( RSC_SCROLLBAR
);
137 WinBits nStyle
= ImplInitRes( rResId
);
138 ImplInit( pParent
, nStyle
);
139 ImplLoadRes( rResId
);
141 if ( !(nStyle
& WB_HIDE
) )
146 ScrollBar::~ScrollBar()
153 void ScrollBar::ImplLoadRes( const ResId
& rResId
)
155 Control::ImplLoadRes( rResId
);
157 sal_Int16 nMin
= ReadShortRes();
158 sal_Int16 nMax
= ReadShortRes();
159 sal_Int16 nThumbPos
= ReadShortRes();
160 sal_Int16 nPage
= ReadShortRes();
161 sal_Int16 nStep
= ReadShortRes();
162 sal_Int16 nVisibleSize
= ReadShortRes();
164 SetRange( Range( nMin
, nMax
) );
165 SetLineSize( nStep
);
166 SetPageSize( nPage
);
167 SetVisibleSize( nVisibleSize
);
168 SetThumbPos( nThumbPos
);
172 void ScrollBar::ImplUpdateRects( sal_Bool bUpdate
)
174 sal_uInt16 nOldStateFlags
= mnStateFlags
;
175 Rectangle aOldPage1Rect
= maPage1Rect
;
176 Rectangle aOldPage2Rect
= maPage2Rect
;
177 Rectangle aOldThumbRect
= maThumbRect
;
179 mnStateFlags
&= ~SCRBAR_STATE_BTN1_DISABLE
;
180 mnStateFlags
&= ~SCRBAR_STATE_BTN2_DISABLE
;
182 Rectangle
& maTrackRect
= mpData
->maTrackRect
; // TODO: remove when maTrackRect is no longer in mpData
183 if ( mnThumbPixRange
)
185 if ( GetStyle() & WB_HORZ
)
187 maThumbRect
.Left() = maTrackRect
.Left()+mnThumbPixPos
;
188 maThumbRect
.Right() = maThumbRect
.Left()+mnThumbPixSize
-1;
189 if ( !mnThumbPixPos
)
190 maPage1Rect
.Right() = RECT_EMPTY
;
192 maPage1Rect
.Right() = maThumbRect
.Left()-1;
193 if ( mnThumbPixPos
>= (mnThumbPixRange
-mnThumbPixSize
) )
194 maPage2Rect
.Right() = RECT_EMPTY
;
197 maPage2Rect
.Left() = maThumbRect
.Right()+1;
198 maPage2Rect
.Right() = maTrackRect
.Right();
203 maThumbRect
.Top() = maTrackRect
.Top()+mnThumbPixPos
;
204 maThumbRect
.Bottom() = maThumbRect
.Top()+mnThumbPixSize
-1;
205 if ( !mnThumbPixPos
)
206 maPage1Rect
.Bottom() = RECT_EMPTY
;
208 maPage1Rect
.Bottom() = maThumbRect
.Top()-1;
209 if ( mnThumbPixPos
>= (mnThumbPixRange
-mnThumbPixSize
) )
210 maPage2Rect
.Bottom() = RECT_EMPTY
;
213 maPage2Rect
.Top() = maThumbRect
.Bottom()+1;
214 maPage2Rect
.Bottom() = maTrackRect
.Bottom();
220 if ( GetStyle() & WB_HORZ
)
222 const long nSpace
= maTrackRect
.Right() - maTrackRect
.Left();
225 maPage1Rect
.Left() = maTrackRect
.Left();
226 maPage1Rect
.Right() = maTrackRect
.Left() + (nSpace
/2);
227 maPage2Rect
.Left() = maPage1Rect
.Right() + 1;
228 maPage2Rect
.Right() = maTrackRect
.Right();
233 const long nSpace
= maTrackRect
.Bottom() - maTrackRect
.Top();
236 maPage1Rect
.Top() = maTrackRect
.Top();
237 maPage1Rect
.Bottom() = maTrackRect
.Top() + (nSpace
/2);
238 maPage2Rect
.Top() = maPage1Rect
.Bottom() + 1;
239 maPage2Rect
.Bottom() = maTrackRect
.Bottom();
244 if( !IsNativeControlSupported(CTRL_SCROLLBAR
, PART_ENTIRE_CONTROL
) )
246 // disable scrollbar buttons only in VCL's own 'theme'
247 // as it is uncommon on other platforms
248 if ( mnThumbPos
== mnMinRange
)
249 mnStateFlags
|= SCRBAR_STATE_BTN1_DISABLE
;
250 if ( mnThumbPos
>= (mnMaxRange
-mnVisibleSize
) )
251 mnStateFlags
|= SCRBAR_STATE_BTN2_DISABLE
;
256 sal_uInt16 nDraw
= 0;
257 if ( (nOldStateFlags
& SCRBAR_STATE_BTN1_DISABLE
) !=
258 (mnStateFlags
& SCRBAR_STATE_BTN1_DISABLE
) )
259 nDraw
|= SCRBAR_DRAW_BTN1
;
260 if ( (nOldStateFlags
& SCRBAR_STATE_BTN2_DISABLE
) !=
261 (mnStateFlags
& SCRBAR_STATE_BTN2_DISABLE
) )
262 nDraw
|= SCRBAR_DRAW_BTN2
;
263 if ( aOldPage1Rect
!= maPage1Rect
)
264 nDraw
|= SCRBAR_DRAW_PAGE1
;
265 if ( aOldPage2Rect
!= maPage2Rect
)
266 nDraw
|= SCRBAR_DRAW_PAGE2
;
267 if ( aOldThumbRect
!= maThumbRect
)
268 nDraw
|= SCRBAR_DRAW_THUMB
;
269 ImplDraw( nDraw
, this );
274 long ScrollBar::ImplCalcThumbPos( long nPixPos
)
276 // Calculate position
278 nCalcThumbPos
= ImplMulDiv( nPixPos
, mnMaxRange
-mnVisibleSize
-mnMinRange
,
279 mnThumbPixRange
-mnThumbPixSize
);
280 nCalcThumbPos
+= mnMinRange
;
281 return nCalcThumbPos
;
285 long ScrollBar::ImplCalcThumbPosPix( long nPos
)
289 // Calculate position
290 nCalcThumbPos
= ImplMulDiv( nPos
-mnMinRange
, mnThumbPixRange
-mnThumbPixSize
,
291 mnMaxRange
-mnVisibleSize
-mnMinRange
);
293 // At the start and end of the ScrollBar, we try to show the display correctly
294 if ( !nCalcThumbPos
&& (mnThumbPos
> mnMinRange
) )
296 if ( nCalcThumbPos
&&
297 ((nCalcThumbPos
+mnThumbPixSize
) >= mnThumbPixRange
) &&
298 (mnThumbPos
< (mnMaxRange
-mnVisibleSize
)) )
301 return nCalcThumbPos
;
305 void ScrollBar::ImplCalc( sal_Bool bUpdate
)
307 const Size aSize
= GetOutputSizePixel();
308 const long nMinThumbSize
= GetSettings().GetStyleSettings().GetMinThumbSize();
310 Rectangle
& maTrackRect
= mpData
->maTrackRect
; // TODO: remove when maTrackRect is no longer in mpData
313 Size aOldSize
= getCurrentCalcSize();
315 const Rectangle
aControlRegion( Point(0,0), aSize
);
316 Rectangle aBtn1Region
, aBtn2Region
, aTrackRegion
, aBoundingRegion
;
318 if ( GetStyle() & WB_HORZ
)
320 if ( GetNativeControlRegion( CTRL_SCROLLBAR
, IsRTLEnabled()? PART_BUTTON_RIGHT
: PART_BUTTON_LEFT
,
321 aControlRegion
, 0, ImplControlValue(), OUString(), aBoundingRegion
, aBtn1Region
) &&
322 GetNativeControlRegion( CTRL_SCROLLBAR
, IsRTLEnabled()? PART_BUTTON_LEFT
: PART_BUTTON_RIGHT
,
323 aControlRegion
, 0, ImplControlValue(), OUString(), aBoundingRegion
, aBtn2Region
) )
325 maBtn1Rect
= aBtn1Region
;
326 maBtn2Rect
= aBtn2Region
;
330 Size
aBtnSize( aSize
.Height(), aSize
.Height() );
331 maBtn2Rect
.Top() = maBtn1Rect
.Top();
332 maBtn2Rect
.Left() = aSize
.Width()-aSize
.Height();
333 maBtn1Rect
.SetSize( aBtnSize
);
334 maBtn2Rect
.SetSize( aBtnSize
);
337 if ( GetNativeControlRegion( CTRL_SCROLLBAR
, PART_TRACK_HORZ_AREA
,
338 aControlRegion
, 0, ImplControlValue(), OUString(), aBoundingRegion
, aTrackRegion
) )
339 maTrackRect
= aTrackRegion
;
341 maTrackRect
= Rectangle( maBtn1Rect
.TopRight(), maBtn2Rect
.BottomLeft() );
343 // Check if available space is big enough for thumb ( min thumb size = ScrBar width/height )
344 mnThumbPixRange
= maTrackRect
.Right() - maTrackRect
.Left();
345 if( mnThumbPixRange
> 0 )
347 maPage1Rect
.Left() = maTrackRect
.Left();
348 maPage1Rect
.Bottom() =
349 maPage2Rect
.Bottom() =
350 maThumbRect
.Bottom() = maTrackRect
.Bottom();
355 maPage1Rect
.SetEmpty();
356 maPage2Rect
.SetEmpty();
361 if ( GetNativeControlRegion( CTRL_SCROLLBAR
, PART_BUTTON_UP
,
362 aControlRegion
, 0, ImplControlValue(), OUString(), aBoundingRegion
, aBtn1Region
) &&
363 GetNativeControlRegion( CTRL_SCROLLBAR
, PART_BUTTON_DOWN
,
364 aControlRegion
, 0, ImplControlValue(), OUString(), aBoundingRegion
, aBtn2Region
) )
366 maBtn1Rect
= aBtn1Region
;
367 maBtn2Rect
= aBtn2Region
;
371 const Size
aBtnSize( aSize
.Width(), aSize
.Width() );
372 maBtn2Rect
.Left() = maBtn1Rect
.Left();
373 maBtn2Rect
.Top() = aSize
.Height()-aSize
.Width();
374 maBtn1Rect
.SetSize( aBtnSize
);
375 maBtn2Rect
.SetSize( aBtnSize
);
378 if ( GetNativeControlRegion( CTRL_SCROLLBAR
, PART_TRACK_VERT_AREA
,
379 aControlRegion
, 0, ImplControlValue(), OUString(), aBoundingRegion
, aTrackRegion
) )
380 maTrackRect
= aTrackRegion
;
382 maTrackRect
= Rectangle( maBtn1Rect
.BottomLeft()+Point(0,1), maBtn2Rect
.TopRight() );
384 // Check if available space is big enough for thumb
385 mnThumbPixRange
= maTrackRect
.Bottom() - maTrackRect
.Top();
386 if( mnThumbPixRange
> 0 )
388 maPage1Rect
.Top() = maTrackRect
.Top();
389 maPage1Rect
.Right() =
390 maPage2Rect
.Right() =
391 maThumbRect
.Right() = maTrackRect
.Right();
396 maPage1Rect
.SetEmpty();
397 maPage2Rect
.SetEmpty();
401 if ( !mnThumbPixRange
)
402 maThumbRect
.SetEmpty();
404 mbCalcSize
= sal_False
;
406 Size aNewSize
= getCurrentCalcSize();
407 if (aOldSize
!= aNewSize
)
413 if ( mnThumbPixRange
)
416 if ( (mnVisibleSize
>= (mnMaxRange
-mnMinRange
)) ||
417 ((mnMaxRange
-mnMinRange
) <= 0) )
419 mnThumbPos
= mnMinRange
;
421 mnThumbPixSize
= mnThumbPixRange
;
426 mnThumbPixSize
= ImplMulDiv( mnThumbPixRange
, mnVisibleSize
, mnMaxRange
-mnMinRange
);
429 if ( GetStyle() & WB_HORZ
)
430 mnThumbPixSize
= maThumbRect
.GetWidth();
432 mnThumbPixSize
= maThumbRect
.GetHeight();
434 if ( mnThumbPixSize
< nMinThumbSize
)
435 mnThumbPixSize
= nMinThumbSize
;
436 if ( mnThumbPixSize
> mnThumbPixRange
)
437 mnThumbPixSize
= mnThumbPixRange
;
438 mnThumbPixPos
= ImplCalcThumbPosPix( mnThumbPos
);
442 // If we're ought to ouput again and we have been triggered
443 // a Paint event via an Action, we don't output directly,
444 // but invalidate everything
445 if ( bUpdate
&& HasPaintEvent() )
450 ImplUpdateRects( bUpdate
);
453 void ScrollBar::Draw( OutputDevice
* pDev
, const Point
& rPos
, const Size
& /* rSize */, sal_uLong nFlags
)
455 Point aPos
= pDev
->LogicToPixel( rPos
);
459 if ( !(nFlags
& WINDOW_DRAW_MONO
) )
461 // DecoView uses the FaceColor...
462 AllSettings aSettings
= pDev
->GetSettings();
463 StyleSettings aStyleSettings
= aSettings
.GetStyleSettings();
464 if ( IsControlBackground() )
465 aStyleSettings
.SetFaceColor( GetControlBackground() );
467 aStyleSettings
.SetFaceColor( GetSettings().GetStyleSettings().GetFaceColor() );
469 aSettings
.SetStyleSettings( aStyleSettings
);
470 pDev
->SetSettings( aSettings
);
474 // - calculate the size of the rects
475 // - because this is zero-based add the correct offset
477 // - force recalculate
480 ImplCalc( sal_False
);
485 mpData
->maTrackRect
+=aPos
; // TODO: update when maTrackRect is no longer in mpData
489 ImplDraw( SCRBAR_DRAW_ALL
, pDev
);
492 mbCalcSize
= sal_True
;
496 sal_Bool
ScrollBar::ImplDrawNative( sal_uInt16 nDrawFlags
)
498 ScrollbarValue scrValue
;
500 sal_Bool bNativeOK
= IsNativeControlSupported(CTRL_SCROLLBAR
, PART_ENTIRE_CONTROL
);
503 bool bHorz
= (GetStyle() & WB_HORZ
? true : false);
505 // Draw the entire background if the control supports it
506 if( IsNativeControlSupported(CTRL_SCROLLBAR
, bHorz
? PART_DRAW_BACKGROUND_HORZ
: PART_DRAW_BACKGROUND_VERT
) )
508 ControlState nState
= ( IsEnabled() ? CTRL_STATE_ENABLED
: 0 ) | ( HasFocus() ? CTRL_STATE_FOCUSED
: 0 );
510 scrValue
.mnMin
= mnMinRange
;
511 scrValue
.mnMax
= mnMaxRange
;
512 scrValue
.mnCur
= mnThumbPos
;
513 scrValue
.mnVisibleSize
= mnVisibleSize
;
514 scrValue
.maThumbRect
= maThumbRect
;
515 scrValue
.maButton1Rect
= maBtn1Rect
;
516 scrValue
.maButton2Rect
= maBtn2Rect
;
517 scrValue
.mnButton1State
= ((mnStateFlags
& SCRBAR_STATE_BTN1_DOWN
) ? CTRL_STATE_PRESSED
: 0) |
518 ((!(mnStateFlags
& SCRBAR_STATE_BTN1_DISABLE
)) ? CTRL_STATE_ENABLED
: 0);
519 scrValue
.mnButton2State
= ((mnStateFlags
& SCRBAR_STATE_BTN2_DOWN
) ? CTRL_STATE_PRESSED
: 0) |
520 ((!(mnStateFlags
& SCRBAR_STATE_BTN2_DISABLE
)) ? CTRL_STATE_ENABLED
: 0);
521 scrValue
.mnThumbState
= nState
| ((mnStateFlags
& SCRBAR_STATE_THUMB_DOWN
) ? CTRL_STATE_PRESSED
: 0);
522 scrValue
.mnPage1State
= nState
| ((mnStateFlags
& SCRBAR_STATE_PAGE1_DOWN
) ? CTRL_STATE_PRESSED
: 0);
523 scrValue
.mnPage2State
= nState
| ((mnStateFlags
& SCRBAR_STATE_PAGE2_DOWN
) ? CTRL_STATE_PRESSED
: 0);
527 Rectangle
* pRect
= ImplFindPartRect( GetPointerPosPixel() );
530 if( pRect
== &maThumbRect
)
531 scrValue
.mnThumbState
|= CTRL_STATE_ROLLOVER
;
532 else if( pRect
== &maBtn1Rect
)
533 scrValue
.mnButton1State
|= CTRL_STATE_ROLLOVER
;
534 else if( pRect
== &maBtn2Rect
)
535 scrValue
.mnButton2State
|= CTRL_STATE_ROLLOVER
;
536 else if( pRect
== &maPage1Rect
)
537 scrValue
.mnPage1State
|= CTRL_STATE_ROLLOVER
;
538 else if( pRect
== &maPage2Rect
)
539 scrValue
.mnPage2State
|= CTRL_STATE_ROLLOVER
;
543 Rectangle aCtrlRegion
;
544 aCtrlRegion
.Union( maBtn1Rect
);
545 aCtrlRegion
.Union( maBtn2Rect
);
546 aCtrlRegion
.Union( maPage1Rect
);
547 aCtrlRegion
.Union( maPage2Rect
);
548 aCtrlRegion
.Union( maThumbRect
);
549 bNativeOK
= DrawNativeControl( CTRL_SCROLLBAR
, (bHorz
? PART_DRAW_BACKGROUND_HORZ
: PART_DRAW_BACKGROUND_VERT
),
550 aCtrlRegion
, nState
, scrValue
, OUString() );
554 if ( (nDrawFlags
& SCRBAR_DRAW_PAGE1
) || (nDrawFlags
& SCRBAR_DRAW_PAGE2
) )
556 sal_uInt32 part1
= bHorz
? PART_TRACK_HORZ_LEFT
: PART_TRACK_VERT_UPPER
;
557 sal_uInt32 part2
= bHorz
? PART_TRACK_HORZ_RIGHT
: PART_TRACK_VERT_LOWER
;
558 Rectangle
aCtrlRegion1( maPage1Rect
);
559 Rectangle
aCtrlRegion2( maPage2Rect
);
560 ControlState nState1
= (IsEnabled() ? CTRL_STATE_ENABLED
: 0) | (HasFocus() ? CTRL_STATE_FOCUSED
: 0);
561 ControlState nState2
= nState1
;
563 nState1
|= ((mnStateFlags
& SCRBAR_STATE_PAGE1_DOWN
) ? CTRL_STATE_PRESSED
: 0);
564 nState2
|= ((mnStateFlags
& SCRBAR_STATE_PAGE2_DOWN
) ? CTRL_STATE_PRESSED
: 0);
568 Rectangle
* pRect
= ImplFindPartRect( GetPointerPosPixel() );
571 if( pRect
== &maPage1Rect
)
572 nState1
|= CTRL_STATE_ROLLOVER
;
573 else if( pRect
== &maPage2Rect
)
574 nState2
|= CTRL_STATE_ROLLOVER
;
578 if ( nDrawFlags
& SCRBAR_DRAW_PAGE1
)
579 bNativeOK
= DrawNativeControl( CTRL_SCROLLBAR
, part1
, aCtrlRegion1
, nState1
,
580 scrValue
, OUString() );
582 if ( nDrawFlags
& SCRBAR_DRAW_PAGE2
)
583 bNativeOK
= DrawNativeControl( CTRL_SCROLLBAR
, part2
, aCtrlRegion2
, nState2
,
584 scrValue
, OUString() );
586 if ( (nDrawFlags
& SCRBAR_DRAW_BTN1
) || (nDrawFlags
& SCRBAR_DRAW_BTN2
) )
588 sal_uInt32 part1
= bHorz
? PART_BUTTON_LEFT
: PART_BUTTON_UP
;
589 sal_uInt32 part2
= bHorz
? PART_BUTTON_RIGHT
: PART_BUTTON_DOWN
;
590 Rectangle
aCtrlRegion1( maBtn1Rect
);
591 Rectangle
aCtrlRegion2( maBtn2Rect
);
592 ControlState nState1
= HasFocus() ? CTRL_STATE_FOCUSED
: 0;
593 ControlState nState2
= nState1
;
595 if ( !Window::IsEnabled() || !IsEnabled() )
596 nState1
= (nState2
&= ~CTRL_STATE_ENABLED
);
598 nState1
= (nState2
|= CTRL_STATE_ENABLED
);
600 nState1
|= ((mnStateFlags
& SCRBAR_STATE_BTN1_DOWN
) ? CTRL_STATE_PRESSED
: 0);
601 nState2
|= ((mnStateFlags
& SCRBAR_STATE_BTN2_DOWN
) ? CTRL_STATE_PRESSED
: 0);
603 if(mnStateFlags
& SCRBAR_STATE_BTN1_DISABLE
)
604 nState1
&= ~CTRL_STATE_ENABLED
;
605 if(mnStateFlags
& SCRBAR_STATE_BTN2_DISABLE
)
606 nState2
&= ~CTRL_STATE_ENABLED
;
610 Rectangle
* pRect
= ImplFindPartRect( GetPointerPosPixel() );
613 if( pRect
== &maBtn1Rect
)
614 nState1
|= CTRL_STATE_ROLLOVER
;
615 else if( pRect
== &maBtn2Rect
)
616 nState2
|= CTRL_STATE_ROLLOVER
;
620 if ( nDrawFlags
& SCRBAR_DRAW_BTN1
)
621 bNativeOK
= DrawNativeControl( CTRL_SCROLLBAR
, part1
, aCtrlRegion1
, nState1
,
622 scrValue
, OUString() );
624 if ( nDrawFlags
& SCRBAR_DRAW_BTN2
)
625 bNativeOK
= DrawNativeControl( CTRL_SCROLLBAR
, part2
, aCtrlRegion2
, nState2
,
626 scrValue
, OUString() );
628 if ( (nDrawFlags
& SCRBAR_DRAW_THUMB
) && !maThumbRect
.IsEmpty() )
630 ControlState nState
= IsEnabled() ? CTRL_STATE_ENABLED
: 0;
631 Rectangle
aCtrlRegion( maThumbRect
);
633 if ( mnStateFlags
& SCRBAR_STATE_THUMB_DOWN
)
634 nState
|= CTRL_STATE_PRESSED
;
637 nState
|= CTRL_STATE_FOCUSED
;
641 Rectangle
* pRect
= ImplFindPartRect( GetPointerPosPixel() );
644 if( pRect
== &maThumbRect
)
645 nState
|= CTRL_STATE_ROLLOVER
;
649 bNativeOK
= DrawNativeControl( CTRL_SCROLLBAR
, (bHorz
? PART_THUMB_HORZ
: PART_THUMB_VERT
),
650 aCtrlRegion
, nState
, scrValue
, OUString() );
657 void ScrollBar::ImplDraw( sal_uInt16 nDrawFlags
, OutputDevice
* pOutDev
)
659 DecorationView
aDecoView( pOutDev
);
662 const StyleSettings
& rStyleSettings
= pOutDev
->GetSettings().GetStyleSettings();
663 SymbolType eSymbolType
;
664 sal_Bool bEnabled
= IsEnabled();
666 // Finish some open calculations (if any)
668 ImplCalc( sal_False
);
671 if( pOutDev
->GetOutDevType() == OUTDEV_WINDOW
)
672 pWin
= (Window
*) pOutDev
;
674 // Draw the entire control if the native theme engine needs it
675 if ( nDrawFlags
&& pWin
&& pWin
->IsNativeControlSupported(CTRL_SCROLLBAR
, PART_DRAW_BACKGROUND_HORZ
) )
677 ImplDrawNative( SCRBAR_DRAW_BACKGROUND
);
681 if( (nDrawFlags
& SCRBAR_DRAW_BTN1
) && (!pWin
|| !ImplDrawNative( SCRBAR_DRAW_BTN1
) ) )
683 nStyle
= BUTTON_DRAW_NOLIGHTBORDER
;
684 if ( mnStateFlags
& SCRBAR_STATE_BTN1_DOWN
)
685 nStyle
|= BUTTON_DRAW_PRESSED
;
686 aTempRect
= aDecoView
.DrawButton( maBtn1Rect
, nStyle
);
687 ImplCalcSymbolRect( aTempRect
);
689 if ( (mnStateFlags
& SCRBAR_STATE_BTN1_DISABLE
) || !bEnabled
)
690 nStyle
|= SYMBOL_DRAW_DISABLE
;
691 if ( rStyleSettings
.GetOptions() & STYLE_OPTION_SCROLLARROW
)
693 if ( GetStyle() & WB_HORZ
)
694 eSymbolType
= SYMBOL_ARROW_LEFT
;
696 eSymbolType
= SYMBOL_ARROW_UP
;
700 if ( GetStyle() & WB_HORZ
)
701 eSymbolType
= SYMBOL_SPIN_LEFT
;
703 eSymbolType
= SYMBOL_SPIN_UP
;
705 aDecoView
.DrawSymbol( aTempRect
, eSymbolType
, rStyleSettings
.GetButtonTextColor(), nStyle
);
708 if ( (nDrawFlags
& SCRBAR_DRAW_BTN2
) && (!pWin
|| !ImplDrawNative( SCRBAR_DRAW_BTN2
) ) )
710 nStyle
= BUTTON_DRAW_NOLIGHTBORDER
;
711 if ( mnStateFlags
& SCRBAR_STATE_BTN2_DOWN
)
712 nStyle
|= BUTTON_DRAW_PRESSED
;
713 aTempRect
= aDecoView
.DrawButton( maBtn2Rect
, nStyle
);
714 ImplCalcSymbolRect( aTempRect
);
716 if ( (mnStateFlags
& SCRBAR_STATE_BTN2_DISABLE
) || !bEnabled
)
717 nStyle
|= SYMBOL_DRAW_DISABLE
;
718 if ( rStyleSettings
.GetOptions() & STYLE_OPTION_SCROLLARROW
)
720 if ( GetStyle() & WB_HORZ
)
721 eSymbolType
= SYMBOL_ARROW_RIGHT
;
723 eSymbolType
= SYMBOL_ARROW_DOWN
;
727 if ( GetStyle() & WB_HORZ
)
728 eSymbolType
= SYMBOL_SPIN_RIGHT
;
730 eSymbolType
= SYMBOL_SPIN_DOWN
;
732 aDecoView
.DrawSymbol( aTempRect
, eSymbolType
, rStyleSettings
.GetButtonTextColor(), nStyle
);
735 pOutDev
->SetLineColor();
737 if ( (nDrawFlags
& SCRBAR_DRAW_THUMB
) && (!pWin
|| !ImplDrawNative( SCRBAR_DRAW_THUMB
) ) )
739 if ( !maThumbRect
.IsEmpty() )
743 nStyle
= BUTTON_DRAW_NOLIGHTBORDER
;
744 aTempRect
= aDecoView
.DrawButton( maThumbRect
, nStyle
);
748 pOutDev
->SetFillColor( rStyleSettings
.GetCheckedColor() );
749 pOutDev
->DrawRect( maThumbRect
);
754 if ( (nDrawFlags
& SCRBAR_DRAW_PAGE1
) && (!pWin
|| !ImplDrawNative( SCRBAR_DRAW_PAGE1
) ) )
756 if ( mnStateFlags
& SCRBAR_STATE_PAGE1_DOWN
)
757 pOutDev
->SetFillColor( rStyleSettings
.GetShadowColor() );
759 pOutDev
->SetFillColor( rStyleSettings
.GetCheckedColor() );
760 pOutDev
->DrawRect( maPage1Rect
);
762 if ( (nDrawFlags
& SCRBAR_DRAW_PAGE2
) && (!pWin
|| !ImplDrawNative( SCRBAR_DRAW_PAGE2
) ) )
764 if ( mnStateFlags
& SCRBAR_STATE_PAGE2_DOWN
)
765 pOutDev
->SetFillColor( rStyleSettings
.GetShadowColor() );
767 pOutDev
->SetFillColor( rStyleSettings
.GetCheckedColor() );
768 pOutDev
->DrawRect( maPage2Rect
);
773 long ScrollBar::ImplScroll( long nNewPos
, sal_Bool bCallEndScroll
)
775 long nOldPos
= mnThumbPos
;
776 SetThumbPos( nNewPos
);
777 long nDelta
= mnThumbPos
-nOldPos
;
782 if ( bCallEndScroll
)
790 long ScrollBar::ImplDoAction( sal_Bool bCallEndScroll
)
794 switch ( meScrollType
)
797 nDelta
= ImplScroll( mnThumbPos
-mnLineSize
, bCallEndScroll
);
800 case SCROLL_LINEDOWN
:
801 nDelta
= ImplScroll( mnThumbPos
+mnLineSize
, bCallEndScroll
);
805 nDelta
= ImplScroll( mnThumbPos
-mnPageSize
, bCallEndScroll
);
808 case SCROLL_PAGEDOWN
:
809 nDelta
= ImplScroll( mnThumbPos
+mnPageSize
, bCallEndScroll
);
819 void ScrollBar::ImplDoMouseAction( const Point
& rMousePos
, sal_Bool bCallAction
)
821 sal_uInt16 nOldStateFlags
= mnStateFlags
;
822 sal_Bool bAction
= sal_False
;
823 bool bHorizontal
= ( GetStyle() & WB_HORZ
)? true: false;
824 sal_Bool bIsInside
= sal_False
;
826 Point
aPoint( 0, 0 );
827 Rectangle
aControlRegion( aPoint
, GetOutputSizePixel() );
829 switch ( meScrollType
)
832 if ( HitTestNativeControl( CTRL_SCROLLBAR
, bHorizontal
? (IsRTLEnabled()? PART_BUTTON_RIGHT
: PART_BUTTON_LEFT
): PART_BUTTON_UP
,
833 aControlRegion
, rMousePos
, bIsInside
)?
835 maBtn1Rect
.IsInside( rMousePos
) )
837 bAction
= bCallAction
;
838 mnStateFlags
|= SCRBAR_STATE_BTN1_DOWN
;
841 mnStateFlags
&= ~SCRBAR_STATE_BTN1_DOWN
;
844 case SCROLL_LINEDOWN
:
845 if ( HitTestNativeControl( CTRL_SCROLLBAR
, bHorizontal
? (IsRTLEnabled()? PART_BUTTON_LEFT
: PART_BUTTON_RIGHT
): PART_BUTTON_DOWN
,
846 aControlRegion
, rMousePos
, bIsInside
)?
848 maBtn2Rect
.IsInside( rMousePos
) )
850 bAction
= bCallAction
;
851 mnStateFlags
|= SCRBAR_STATE_BTN2_DOWN
;
854 mnStateFlags
&= ~SCRBAR_STATE_BTN2_DOWN
;
858 // HitTestNativeControl, see remark at top of file
859 if ( HitTestNativeControl( CTRL_SCROLLBAR
, bHorizontal
? PART_TRACK_HORZ_LEFT
: PART_TRACK_VERT_UPPER
,
860 maPage1Rect
, rMousePos
, bIsInside
)?
862 maPage1Rect
.IsInside( rMousePos
) )
864 bAction
= bCallAction
;
865 mnStateFlags
|= SCRBAR_STATE_PAGE1_DOWN
;
868 mnStateFlags
&= ~SCRBAR_STATE_PAGE1_DOWN
;
871 case SCROLL_PAGEDOWN
:
872 // HitTestNativeControl, see remark at top of file
873 if ( HitTestNativeControl( CTRL_SCROLLBAR
, bHorizontal
? PART_TRACK_HORZ_RIGHT
: PART_TRACK_VERT_LOWER
,
874 maPage2Rect
, rMousePos
, bIsInside
)?
876 maPage2Rect
.IsInside( rMousePos
) )
878 bAction
= bCallAction
;
879 mnStateFlags
|= SCRBAR_STATE_PAGE2_DOWN
;
882 mnStateFlags
&= ~SCRBAR_STATE_PAGE2_DOWN
;
888 if ( nOldStateFlags
!= mnStateFlags
)
889 ImplDraw( mnDragDraw
, this );
891 ImplDoAction( sal_False
);
894 void ScrollBar::ImplDragThumb( const Point
& rMousePos
)
897 if ( GetStyle() & WB_HORZ
)
898 nMovePix
= rMousePos
.X()-(maThumbRect
.Left()+mnMouseOff
);
900 nMovePix
= rMousePos
.Y()-(maThumbRect
.Top()+mnMouseOff
);
902 // Move thumb if necessary
905 mnThumbPixPos
+= nMovePix
;
906 if ( mnThumbPixPos
< 0 )
908 if ( mnThumbPixPos
> (mnThumbPixRange
-mnThumbPixSize
) )
909 mnThumbPixPos
= mnThumbPixRange
-mnThumbPixSize
;
910 long nOldPos
= mnThumbPos
;
911 mnThumbPos
= ImplCalcThumbPos( mnThumbPixPos
);
913 if ( mbFullDrag
&& (nOldPos
!= mnThumbPos
) )
915 mnDelta
= mnThumbPos
-nOldPos
;
922 void ScrollBar::MouseButtonDown( const MouseEvent
& rMEvt
)
924 bool bPrimaryWarps
= GetSettings().GetStyleSettings().GetPrimaryButtonWarpsSlider();
925 bool bWarp
= bPrimaryWarps
? rMEvt
.IsLeft() : rMEvt
.IsMiddle();
926 bool bPrimaryWarping
= bWarp
&& rMEvt
.IsLeft();
927 bool bPage
= bPrimaryWarps
? rMEvt
.IsRight() : rMEvt
.IsLeft();
929 if (rMEvt
.IsLeft() || rMEvt
.IsMiddle() || rMEvt
.IsRight())
931 const Point
& rMousePos
= rMEvt
.GetPosPixel();
932 sal_uInt16 nTrackFlags
= 0;
933 bool bHorizontal
= ( GetStyle() & WB_HORZ
)? true: false;
934 sal_Bool bIsInside
= sal_False
;
935 bool bDragToMouse
= false;
937 Point
aPoint( 0, 0 );
938 Rectangle
aControlRegion( aPoint
, GetOutputSizePixel() );
940 if ( HitTestNativeControl( CTRL_SCROLLBAR
, bHorizontal
? (IsRTLEnabled()? PART_BUTTON_RIGHT
: PART_BUTTON_LEFT
): PART_BUTTON_UP
,
941 aControlRegion
, rMousePos
, bIsInside
)?
943 maBtn1Rect
.IsInside( rMousePos
) )
945 if (rMEvt
.IsLeft() && !(mnStateFlags
& SCRBAR_STATE_BTN1_DISABLE
) )
947 nTrackFlags
= STARTTRACK_BUTTONREPEAT
;
948 meScrollType
= SCROLL_LINEUP
;
949 mnDragDraw
= SCRBAR_DRAW_BTN1
;
952 else if ( HitTestNativeControl( CTRL_SCROLLBAR
, bHorizontal
? (IsRTLEnabled()? PART_BUTTON_LEFT
: PART_BUTTON_RIGHT
): PART_BUTTON_DOWN
,
953 aControlRegion
, rMousePos
, bIsInside
)?
955 maBtn2Rect
.IsInside( rMousePos
) )
957 if (rMEvt
.IsLeft() && !(mnStateFlags
& SCRBAR_STATE_BTN2_DISABLE
) )
959 nTrackFlags
= STARTTRACK_BUTTONREPEAT
;
960 meScrollType
= SCROLL_LINEDOWN
;
961 mnDragDraw
= SCRBAR_DRAW_BTN2
;
966 bool bThumbHit
= HitTestNativeControl( CTRL_SCROLLBAR
, bHorizontal
? PART_THUMB_HORZ
: PART_THUMB_VERT
,
967 maThumbRect
, rMousePos
, bIsInside
)
968 ? bIsInside
: maThumbRect
.IsInside( rMousePos
);
970 bool bThumbAction
= bWarp
|| bPage
;
972 bool bDragHandling
= bWarp
|| (bThumbHit
&& bThumbAction
);
977 mpData
->mbHide
= true; // disable focus blinking
979 ImplDraw( SCRBAR_DRAW_THUMB
, this ); // paint without focus
982 if ( mnVisibleSize
< mnMaxRange
-mnMinRange
)
985 meScrollType
= SCROLL_DRAG
;
986 mnDragDraw
= SCRBAR_DRAW_THUMB
;
988 // calculate mouse offset
989 if (bWarp
&& (!bThumbHit
|| !bPrimaryWarping
))
992 if ( GetStyle() & WB_HORZ
)
993 mnMouseOff
= maThumbRect
.GetWidth()/2;
995 mnMouseOff
= maThumbRect
.GetHeight()/2;
999 if ( GetStyle() & WB_HORZ
)
1000 mnMouseOff
= rMousePos
.X()-maThumbRect
.Left();
1002 mnMouseOff
= rMousePos
.Y()-maThumbRect
.Top();
1005 mnStateFlags
|= SCRBAR_STATE_THUMB_DOWN
;
1006 ImplDraw( mnDragDraw
, this );
1009 else if(bPage
&& (HitTestNativeControl( CTRL_SCROLLBAR
, bHorizontal
? PART_TRACK_HORZ_AREA
: PART_TRACK_VERT_AREA
,
1010 aControlRegion
, rMousePos
, bIsInside
) ?
1011 bIsInside
: sal_True
) )
1013 nTrackFlags
= STARTTRACK_BUTTONREPEAT
;
1015 // HitTestNativeControl, see remark at top of file
1016 if ( HitTestNativeControl( CTRL_SCROLLBAR
, bHorizontal
? PART_TRACK_HORZ_LEFT
: PART_TRACK_VERT_UPPER
,
1017 maPage1Rect
, rMousePos
, bIsInside
)?
1019 maPage1Rect
.IsInside( rMousePos
) )
1021 meScrollType
= SCROLL_PAGEUP
;
1022 mnDragDraw
= SCRBAR_DRAW_PAGE1
;
1026 meScrollType
= SCROLL_PAGEDOWN
;
1027 mnDragDraw
= SCRBAR_DRAW_PAGE2
;
1032 // Should we start Tracking?
1033 if ( meScrollType
!= SCROLL_DONTKNOW
)
1035 // store original position for cancel and EndScroll delta
1036 mnStartPos
= mnThumbPos
;
1037 // #92906# Call StartTracking() before ImplDoMouseAction(), otherwise
1038 // MouseButtonUp() / EndTracking() may be called if somebody is spending
1039 // a lot of time in the scroll handler
1040 StartTracking( nTrackFlags
);
1041 ImplDoMouseAction( rMousePos
);
1044 ImplDragThumb( rMousePos
);
1050 void ScrollBar::Tracking( const TrackingEvent
& rTEvt
)
1052 if ( rTEvt
.IsTrackingEnded() )
1054 // Restore Button and PageRect status
1055 sal_uInt16 nOldStateFlags
= mnStateFlags
;
1056 mnStateFlags
&= ~(SCRBAR_STATE_BTN1_DOWN
| SCRBAR_STATE_BTN2_DOWN
|
1057 SCRBAR_STATE_PAGE1_DOWN
| SCRBAR_STATE_PAGE2_DOWN
|
1058 SCRBAR_STATE_THUMB_DOWN
);
1059 if ( nOldStateFlags
!= mnStateFlags
)
1060 ImplDraw( mnDragDraw
, this );
1063 // Restore the old ThumbPosition when canceled
1064 if ( rTEvt
.IsTrackingCanceled() )
1066 long nOldPos
= mnThumbPos
;
1067 SetThumbPos( mnStartPos
);
1068 mnDelta
= mnThumbPos
-nOldPos
;
1072 if ( meScrollType
== SCROLL_DRAG
)
1074 // On a SCROLLDRAG we recalculate the Thumb, so that it's back to a
1075 // rounded ThumbPosition
1078 if ( !mbFullDrag
&& (mnStartPos
!= mnThumbPos
) )
1080 mnDelta
= mnThumbPos
-mnStartPos
;
1086 mnDelta
= mnThumbPos
-mnStartPos
;
1089 meScrollType
= SCROLL_DONTKNOW
;
1092 mpData
->mbHide
= false; // re-enable focus blinking
1096 const Point rMousePos
= rTEvt
.GetMouseEvent().GetPosPixel();
1098 // Dragging is treated in a special way
1099 if ( meScrollType
== SCROLL_DRAG
)
1100 ImplDragThumb( rMousePos
);
1102 ImplDoMouseAction( rMousePos
, rTEvt
.IsTrackingRepeat() );
1104 // If ScrollBar values are translated in a way that there's
1105 // nothing left to track, we cancel here
1106 if ( !IsVisible() || (mnVisibleSize
>= (mnMaxRange
-mnMinRange
)) )
1111 void ScrollBar::KeyInput( const KeyEvent
& rKEvt
)
1113 if ( !rKEvt
.GetKeyCode().GetModifier() )
1115 switch ( rKEvt
.GetKeyCode().GetCode() )
1122 DoScroll( GetRangeMax() );
1127 DoScrollAction( SCROLL_LINEUP
);
1132 DoScrollAction( SCROLL_LINEDOWN
);
1136 DoScrollAction( SCROLL_PAGEUP
);
1140 DoScrollAction( SCROLL_PAGEDOWN
);
1144 Control::KeyInput( rKEvt
);
1149 Control::KeyInput( rKEvt
);
1152 void ScrollBar::Paint( const Rectangle
& )
1154 ImplDraw( SCRBAR_DRAW_ALL
, this );
1157 void ScrollBar::Resize()
1160 mbCalcSize
= sal_True
;
1161 if ( IsReallyVisible() )
1162 ImplCalc( sal_False
);
1166 IMPL_LINK_NOARG(ScrollBar
, ImplAutoTimerHdl
)
1168 if( mpData
&& mpData
->mbHide
)
1174 void ScrollBar::ImplInvert()
1176 Rectangle
aRect( maThumbRect
);
1177 if( aRect
.getWidth() > 4 )
1182 if( aRect
.getHeight() > 4 )
1185 aRect
.Bottom() -= 2;
1191 void ScrollBar::GetFocus()
1195 mpData
= new ImplScrollBarData
;
1196 mpData
->maTimer
.SetTimeoutHdl( LINK( this, ScrollBar
, ImplAutoTimerHdl
) );
1197 mpData
->mbHide
= false;
1199 ImplInvert(); // react immediately
1200 mpData
->maTimer
.SetTimeout( GetSettings().GetStyleSettings().GetCursorBlinkTime() );
1201 mpData
->maTimer
.Start();
1202 Control::GetFocus();
1205 void ScrollBar::LoseFocus()
1208 mpData
->maTimer
.Stop();
1209 ImplDraw( SCRBAR_DRAW_THUMB
, this );
1211 Control::LoseFocus();
1214 void ScrollBar::StateChanged( StateChangedType nType
)
1216 Control::StateChanged( nType
);
1218 if ( nType
== STATE_CHANGE_INITSHOW
)
1219 ImplCalc( sal_False
);
1220 else if ( nType
== STATE_CHANGE_DATA
)
1222 if ( IsReallyVisible() && IsUpdateMode() )
1223 ImplCalc( sal_True
);
1225 else if ( nType
== STATE_CHANGE_UPDATEMODE
)
1227 if ( IsReallyVisible() && IsUpdateMode() )
1229 ImplCalc( sal_False
);
1233 else if ( nType
== STATE_CHANGE_ENABLE
)
1235 if ( IsReallyVisible() && IsUpdateMode() )
1238 else if ( nType
== STATE_CHANGE_STYLE
)
1240 ImplInitStyle( GetStyle() );
1241 if ( IsReallyVisible() && IsUpdateMode() )
1243 if ( (GetPrevStyle() & SCRBAR_VIEW_STYLE
) !=
1244 (GetStyle() & SCRBAR_VIEW_STYLE
) )
1246 mbCalcSize
= sal_True
;
1247 ImplCalc( sal_False
);
1254 void ScrollBar::DataChanged( const DataChangedEvent
& rDCEvt
)
1256 Control::DataChanged( rDCEvt
);
1258 if ( (rDCEvt
.GetType() == DATACHANGED_SETTINGS
) &&
1259 (rDCEvt
.GetFlags() & SETTINGS_STYLE
) )
1261 mbCalcSize
= sal_True
;
1262 ImplCalc( sal_False
);
1267 Rectangle
* ScrollBar::ImplFindPartRect( const Point
& rPt
)
1269 bool bHorizontal
= ( GetStyle() & WB_HORZ
)? true: false;
1270 sal_Bool bIsInside
= sal_False
;
1272 Point
aPoint( 0, 0 );
1273 Rectangle
aControlRegion( aPoint
, GetOutputSizePixel() );
1275 if( HitTestNativeControl( CTRL_SCROLLBAR
, bHorizontal
? (IsRTLEnabled()? PART_BUTTON_RIGHT
: PART_BUTTON_LEFT
): PART_BUTTON_UP
,
1276 aControlRegion
, rPt
, bIsInside
)?
1278 maBtn1Rect
.IsInside( rPt
) )
1280 else if( HitTestNativeControl( CTRL_SCROLLBAR
, bHorizontal
? (IsRTLEnabled()? PART_BUTTON_LEFT
: PART_BUTTON_RIGHT
): PART_BUTTON_DOWN
,
1281 aControlRegion
, rPt
, bIsInside
)?
1283 maBtn2Rect
.IsInside( rPt
) )
1285 // HitTestNativeControl, see remark at top of file
1286 else if( HitTestNativeControl( CTRL_SCROLLBAR
, bHorizontal
? PART_TRACK_HORZ_LEFT
: PART_TRACK_VERT_UPPER
,
1287 maPage1Rect
, rPt
, bIsInside
)?
1289 maPage1Rect
.IsInside( rPt
) )
1290 return &maPage1Rect
;
1291 // HitTestNativeControl, see remark at top of file
1292 else if( HitTestNativeControl( CTRL_SCROLLBAR
, bHorizontal
? PART_TRACK_HORZ_RIGHT
: PART_TRACK_VERT_LOWER
,
1293 maPage2Rect
, rPt
, bIsInside
)?
1295 maPage2Rect
.IsInside( rPt
) )
1296 return &maPage2Rect
;
1297 // HitTestNativeControl, see remark at top of file
1298 else if( HitTestNativeControl( CTRL_SCROLLBAR
, bHorizontal
? PART_THUMB_HORZ
: PART_THUMB_VERT
,
1299 maThumbRect
, rPt
, bIsInside
)?
1301 maThumbRect
.IsInside( rPt
) )
1302 return &maThumbRect
;
1307 long ScrollBar::PreNotify( NotifyEvent
& rNEvt
)
1310 const MouseEvent
* pMouseEvt
= NULL
;
1312 if( (rNEvt
.GetType() == EVENT_MOUSEMOVE
) && (pMouseEvt
= rNEvt
.GetMouseEvent()) != NULL
)
1314 if( !pMouseEvt
->GetButtons() && !pMouseEvt
->IsSynthetic() && !pMouseEvt
->IsModifierChanged() )
1316 // Trigger a redraw if mouse over state has changed
1317 if( IsNativeControlSupported(CTRL_SCROLLBAR
, PART_ENTIRE_CONTROL
) )
1319 Rectangle
* pRect
= ImplFindPartRect( GetPointerPosPixel() );
1320 Rectangle
* pLastRect
= ImplFindPartRect( GetLastPointerPosPixel() );
1321 if( pRect
!= pLastRect
|| pMouseEvt
->IsLeaveWindow() || pMouseEvt
->IsEnterWindow() )
1323 Region
aRgn( GetActiveClipRegion() );
1327 aClipRegion
.Union( *pRect
);
1329 aClipRegion
.Union( *pLastRect
);
1331 // Support for 3-button scroll bars
1332 sal_Bool bHas3Buttons
= IsNativeControlSupported( CTRL_SCROLLBAR
, HAS_THREE_BUTTONS
);
1333 if ( bHas3Buttons
&& ( pRect
== &maBtn1Rect
|| pLastRect
== &maBtn1Rect
) )
1335 aClipRegion
.Union( maBtn2Rect
);
1338 SetClipRegion( aClipRegion
);
1339 Paint( aClipRegion
.GetBoundRect() );
1341 SetClipRegion( aRgn
);
1347 return nDone
? nDone
: Control::PreNotify(rNEvt
);
1351 void ScrollBar::Scroll()
1353 ImplCallEventListenersAndHandler( VCLEVENT_SCROLLBAR_SCROLL
, maScrollHdl
, this );
1357 void ScrollBar::EndScroll()
1359 ImplCallEventListenersAndHandler( VCLEVENT_SCROLLBAR_ENDSCROLL
, maEndScrollHdl
, this );
1363 long ScrollBar::DoScroll( long nNewPos
)
1365 if ( meScrollType
!= SCROLL_DONTKNOW
)
1368 SAL_INFO("vcl.scrollbar", "DoScroll(" << nNewPos
<< ")");
1369 meScrollType
= SCROLL_DRAG
;
1370 long nDelta
= ImplScroll( nNewPos
, sal_True
);
1371 meScrollType
= SCROLL_DONTKNOW
;
1376 long ScrollBar::DoScrollAction( ScrollType eScrollType
)
1378 if ( (meScrollType
!= SCROLL_DONTKNOW
) ||
1379 (eScrollType
== SCROLL_DONTKNOW
) ||
1380 (eScrollType
== SCROLL_DRAG
) )
1383 meScrollType
= eScrollType
;
1384 long nDelta
= ImplDoAction( sal_True
);
1385 meScrollType
= SCROLL_DONTKNOW
;
1389 void ScrollBar::SetRangeMin( long nNewRange
)
1391 SetRange( Range( nNewRange
, GetRangeMax() ) );
1395 void ScrollBar::SetRangeMax( long nNewRange
)
1397 SetRange( Range( GetRangeMin(), nNewRange
) );
1400 void ScrollBar::SetRange( const Range
& rRange
)
1403 Range aRange
= rRange
;
1405 long nNewMinRange
= aRange
.Min();
1406 long nNewMaxRange
= aRange
.Max();
1408 // If Range differs, set a new one
1409 if ( (mnMinRange
!= nNewMinRange
) ||
1410 (mnMaxRange
!= nNewMaxRange
) )
1412 mnMinRange
= nNewMinRange
;
1413 mnMaxRange
= nNewMaxRange
;
1416 if ( mnThumbPos
> mnMaxRange
-mnVisibleSize
)
1417 mnThumbPos
= mnMaxRange
-mnVisibleSize
;
1418 if ( mnThumbPos
< mnMinRange
)
1419 mnThumbPos
= mnMinRange
;
1421 StateChanged( STATE_CHANGE_DATA
);
1425 void ScrollBar::SetThumbPos( long nNewThumbPos
)
1427 if ( nNewThumbPos
> mnMaxRange
-mnVisibleSize
)
1428 nNewThumbPos
= mnMaxRange
-mnVisibleSize
;
1429 if ( nNewThumbPos
< mnMinRange
)
1430 nNewThumbPos
= mnMinRange
;
1432 if ( mnThumbPos
!= nNewThumbPos
)
1434 mnThumbPos
= nNewThumbPos
;
1435 StateChanged( STATE_CHANGE_DATA
);
1439 void ScrollBar::SetVisibleSize( long nNewSize
)
1441 if ( mnVisibleSize
!= nNewSize
)
1443 mnVisibleSize
= nNewSize
;
1446 if ( mnThumbPos
> mnMaxRange
-mnVisibleSize
)
1447 mnThumbPos
= mnMaxRange
-mnVisibleSize
;
1448 if ( mnThumbPos
< mnMinRange
)
1449 mnThumbPos
= mnMinRange
;
1450 StateChanged( STATE_CHANGE_DATA
);
1454 Size
ScrollBar::GetOptimalSize() const
1457 const_cast<ScrollBar
*>(this)->ImplCalc(sal_False
);
1458 return getCurrentCalcSize();
1461 Size
ScrollBar::getCurrentCalcSize() const
1463 Rectangle aCtrlRegion
;
1464 aCtrlRegion
.Union(maBtn1Rect
);
1465 aCtrlRegion
.Union(maBtn2Rect
);
1466 aCtrlRegion
.Union(maPage1Rect
);
1467 aCtrlRegion
.Union(maPage2Rect
);
1468 aCtrlRegion
.Union(maThumbRect
);
1469 return aCtrlRegion
.GetSize();
1472 void ScrollBarBox::ImplInit( Window
* pParent
, WinBits nStyle
)
1474 Window::ImplInit( pParent
, nStyle
, NULL
);
1476 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
1477 long nScrollSize
= rStyleSettings
.GetScrollBarSize();
1478 SetSizePixel( Size( nScrollSize
, nScrollSize
) );
1482 ScrollBarBox::ScrollBarBox( Window
* pParent
, WinBits nStyle
) :
1483 Window( WINDOW_SCROLLBARBOX
)
1485 ImplInit( pParent
, nStyle
);
1488 void ScrollBarBox::ImplInitSettings()
1490 // FIXME: Hack so that we can build DockingWindows even without background
1491 // and not everything has been switched over yet
1492 if ( IsBackground() )
1495 if ( IsControlBackground() )
1496 aColor
= GetControlBackground();
1498 aColor
= GetSettings().GetStyleSettings().GetFaceColor();
1499 SetBackground( aColor
);
1503 void ScrollBarBox::StateChanged( StateChangedType nType
)
1505 Window::StateChanged( nType
);
1507 if ( nType
== STATE_CHANGE_CONTROLBACKGROUND
)
1514 void ScrollBarBox::DataChanged( const DataChangedEvent
& rDCEvt
)
1516 Window::DataChanged( rDCEvt
);
1518 if ( (rDCEvt
.GetType() == DATACHANGED_SETTINGS
) &&
1519 (rDCEvt
.GetFlags() & SETTINGS_STYLE
) )
1526 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */