1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: scrbar.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_vcl.hxx"
34 #include "vcl/event.hxx"
35 #include "vcl/sound.hxx"
36 #include "vcl/decoview.hxx"
37 #include "vcl/scrbar.hxx"
38 #include "vcl/timer.hxx"
39 #include "vcl/svdata.hxx"
41 #include "rtl/string.hxx"
49 HACK: for scrollbars in case of thumb rect, page up and page down rect we
50 abuse the HitTestNativeControl interface. All theming engines but aqua
51 are actually able to draw the thumb according to our internal representation.
52 However aqua draws a little outside. The canonical way would be to enhance the
53 HitTestNativeControl passing a ScrollbarValue additionally so all necessary
54 information is available in the call.
56 However since there is only this one small exception we will deviate a little and
57 instead pass the respective rect as control region to allow for a small correction.
59 So all places using HitTestNativeControl on PART_THUMB_HORZ, PART_THUMB_VERT,
60 PART_TRACK_HORZ_LEFT, PART_TRACK_HORZ_RIGHT, PART_TRACK_VERT_UPPER, PART_TRACK_VERT_LOWER
61 do not use the control rectangle as region but the actuall part rectangle, making
62 only small deviations feasible.
66 // =======================================================================
68 static long ImplMulDiv( long nNumber
, long nNumerator
, long nDenominator
)
70 double n
= ((double)nNumber
* (double)nNumerator
) / (double)nDenominator
;
74 // =======================================================================
76 #define SCRBAR_DRAW_BTN1 ((USHORT)0x0001)
77 #define SCRBAR_DRAW_BTN2 ((USHORT)0x0002)
78 #define SCRBAR_DRAW_PAGE1 ((USHORT)0x0004)
79 #define SCRBAR_DRAW_PAGE2 ((USHORT)0x0008)
80 #define SCRBAR_DRAW_THUMB ((USHORT)0x0010)
81 #define SCRBAR_DRAW_BACKGROUND ((USHORT)0x0020)
82 #define SCRBAR_DRAW_ALL (SCRBAR_DRAW_BTN1 | SCRBAR_DRAW_BTN2 | \
83 SCRBAR_DRAW_PAGE1 | SCRBAR_DRAW_PAGE2 |\
84 SCRBAR_DRAW_THUMB | SCRBAR_DRAW_BACKGROUND )
86 #define SCRBAR_STATE_BTN1_DOWN ((USHORT)0x0001)
87 #define SCRBAR_STATE_BTN1_DISABLE ((USHORT)0x0002)
88 #define SCRBAR_STATE_BTN2_DOWN ((USHORT)0x0004)
89 #define SCRBAR_STATE_BTN2_DISABLE ((USHORT)0x0008)
90 #define SCRBAR_STATE_PAGE1_DOWN ((USHORT)0x0010)
91 #define SCRBAR_STATE_PAGE2_DOWN ((USHORT)0x0020)
92 #define SCRBAR_STATE_THUMB_DOWN ((USHORT)0x0040)
94 #define SCRBAR_VIEW_STYLE (WB_3DLOOK | WB_HORZ | WB_VERT)
96 struct ImplScrollBarData
98 AutoTimer maTimer
; // Timer
100 Rectangle maTrackRect
; // TODO: move to ScrollBar class when binary incompatibility of ScrollBar class is no longer problematic
103 // =======================================================================
105 void ScrollBar::ImplInit( Window
* pParent
, WinBits nStyle
)
120 meScrollType
= SCROLL_DONTKNOW
;
121 meDDScrollType
= SCROLL_DONTKNOW
;
125 if( !mpData
) // TODO: remove when maTrackRect is no longer in mpData
127 mpData
= new ImplScrollBarData
;
128 mpData
->maTimer
.SetTimeoutHdl( LINK( this, ScrollBar
, ImplAutoTimerHdl
) );
129 mpData
->mbHide
= FALSE
;
132 ImplInitStyle( nStyle
);
133 Control::ImplInit( pParent
, nStyle
, NULL
);
135 long nScrollSize
= GetSettings().GetStyleSettings().GetScrollBarSize();
136 SetSizePixel( Size( nScrollSize
, nScrollSize
) );
140 // -----------------------------------------------------------------------
142 void ScrollBar::ImplInitStyle( WinBits nStyle
)
144 if ( nStyle
& WB_DRAG
)
147 mbFullDrag
= (GetSettings().GetStyleSettings().GetDragFullOptions() & DRAGFULL_OPTION_SCROLL
) != 0;
150 // -----------------------------------------------------------------------
152 ScrollBar::ScrollBar( Window
* pParent
, WinBits nStyle
) :
153 Control( WINDOW_SCROLLBAR
)
155 ImplInit( pParent
, nStyle
);
158 // -----------------------------------------------------------------------
160 ScrollBar::ScrollBar( Window
* pParent
, const ResId
& rResId
) :
161 Control( WINDOW_SCROLLBAR
)
163 rResId
.SetRT( RSC_SCROLLBAR
);
164 WinBits nStyle
= ImplInitRes( rResId
);
165 ImplInit( pParent
, nStyle
);
166 ImplLoadRes( rResId
);
168 if ( !(nStyle
& WB_HIDE
) )
172 // -----------------------------------------------------------------------
174 ScrollBar::~ScrollBar()
180 // -----------------------------------------------------------------------
182 void ScrollBar::ImplLoadRes( const ResId
& rResId
)
184 Control::ImplLoadRes( rResId
);
186 INT16 nMin
= ReadShortRes();
187 INT16 nMax
= ReadShortRes();
188 INT16 nThumbPos
= ReadShortRes();
189 INT16 nPage
= ReadShortRes();
190 INT16 nStep
= ReadShortRes();
191 INT16 nVisibleSize
= ReadShortRes();
193 SetRange( Range( nMin
, nMax
) );
194 SetLineSize( nStep
);
195 SetPageSize( nPage
);
196 SetVisibleSize( nVisibleSize
);
197 SetThumbPos( nThumbPos
);
200 // -----------------------------------------------------------------------
202 void ScrollBar::ImplUpdateRects( BOOL bUpdate
)
204 USHORT nOldStateFlags
= mnStateFlags
;
205 Rectangle aOldPage1Rect
= maPage1Rect
;
206 Rectangle aOldPage2Rect
= maPage2Rect
;
207 Rectangle aOldThumbRect
= maThumbRect
;
209 mnStateFlags
&= ~SCRBAR_STATE_BTN1_DISABLE
;
210 mnStateFlags
&= ~SCRBAR_STATE_BTN2_DISABLE
;
212 Rectangle
& maTrackRect
= mpData
->maTrackRect
; // TODO: remove when maTrackRect is no longer in mpData
213 if ( mnThumbPixRange
)
215 if ( GetStyle() & WB_HORZ
)
217 maThumbRect
.Left() = maTrackRect
.Left()+mnThumbPixPos
;
218 maThumbRect
.Right() = maThumbRect
.Left()+mnThumbPixSize
-1;
219 if ( !mnThumbPixPos
)
220 maPage1Rect
.Right() = RECT_EMPTY
;
222 maPage1Rect
.Right() = maThumbRect
.Left()-1;
223 if ( mnThumbPixPos
>= (mnThumbPixRange
-mnThumbPixSize
) )
224 maPage2Rect
.Right() = RECT_EMPTY
;
227 maPage2Rect
.Left() = maThumbRect
.Right()+1;
228 maPage2Rect
.Right() = maTrackRect
.Right();
233 maThumbRect
.Top() = maTrackRect
.Top()+mnThumbPixPos
;
234 maThumbRect
.Bottom() = maThumbRect
.Top()+mnThumbPixSize
-1;
235 if ( !mnThumbPixPos
)
236 maPage1Rect
.Bottom() = RECT_EMPTY
;
238 maPage1Rect
.Bottom() = maThumbRect
.Top()-1;
239 if ( mnThumbPixPos
>= (mnThumbPixRange
-mnThumbPixSize
) )
240 maPage2Rect
.Bottom() = RECT_EMPTY
;
243 maPage2Rect
.Top() = maThumbRect
.Bottom()+1;
244 maPage2Rect
.Bottom() = maTrackRect
.Bottom();
250 Size aScrBarSize
= GetOutputSizePixel();
251 if ( GetStyle() & WB_HORZ
)
253 const long nSpace
= maTrackRect
.Right() - maTrackRect
.Left();
256 maPage1Rect
.Left() = maTrackRect
.Left();
257 maPage1Rect
.Right() = maTrackRect
.Left() + (nSpace
/2);
258 maPage2Rect
.Left() = maPage1Rect
.Right() + 1;
259 maPage2Rect
.Right() = maTrackRect
.Right();
264 const long nSpace
= maTrackRect
.Bottom() - maTrackRect
.Top();
267 maPage1Rect
.Top() = maTrackRect
.Top();
268 maPage1Rect
.Bottom() = maTrackRect
.Top() + (nSpace
/2);
269 maPage2Rect
.Top() = maPage1Rect
.Bottom() + 1;
270 maPage2Rect
.Bottom() = maTrackRect
.Bottom();
275 if( !IsNativeControlSupported(CTRL_SCROLLBAR
, PART_ENTIRE_CONTROL
) )
277 // disable scrollbar buttons only in VCL's own 'theme'
278 // as it is uncommon on other platforms
279 if ( mnThumbPos
== mnMinRange
)
280 mnStateFlags
|= SCRBAR_STATE_BTN1_DISABLE
;
281 if ( mnThumbPos
>= (mnMaxRange
-mnVisibleSize
) )
282 mnStateFlags
|= SCRBAR_STATE_BTN2_DISABLE
;
288 if ( (nOldStateFlags
& SCRBAR_STATE_BTN1_DISABLE
) !=
289 (mnStateFlags
& SCRBAR_STATE_BTN1_DISABLE
) )
290 nDraw
|= SCRBAR_DRAW_BTN1
;
291 if ( (nOldStateFlags
& SCRBAR_STATE_BTN2_DISABLE
) !=
292 (mnStateFlags
& SCRBAR_STATE_BTN2_DISABLE
) )
293 nDraw
|= SCRBAR_DRAW_BTN2
;
294 if ( aOldPage1Rect
!= maPage1Rect
)
295 nDraw
|= SCRBAR_DRAW_PAGE1
;
296 if ( aOldPage2Rect
!= maPage2Rect
)
297 nDraw
|= SCRBAR_DRAW_PAGE2
;
298 if ( aOldThumbRect
!= maThumbRect
)
299 nDraw
|= SCRBAR_DRAW_THUMB
;
300 ImplDraw( nDraw
, this );
304 // -----------------------------------------------------------------------
306 long ScrollBar::ImplCalcThumbPos( long nPixPos
)
308 // Position berechnen
310 nCalcThumbPos
= ImplMulDiv( nPixPos
, mnMaxRange
-mnVisibleSize
-mnMinRange
,
311 mnThumbPixRange
-mnThumbPixSize
);
312 nCalcThumbPos
+= mnMinRange
;
313 return nCalcThumbPos
;
316 // -----------------------------------------------------------------------
318 long ScrollBar::ImplCalcThumbPosPix( long nPos
)
322 // Position berechnen
323 nCalcThumbPos
= ImplMulDiv( nPos
-mnMinRange
, mnThumbPixRange
-mnThumbPixSize
,
324 mnMaxRange
-mnVisibleSize
-mnMinRange
);
326 // Am Anfang und Ende des ScrollBars versuchen wir die Anzeige korrekt
328 if ( !nCalcThumbPos
&& (mnThumbPos
> mnMinRange
) )
330 if ( nCalcThumbPos
&&
331 ((nCalcThumbPos
+mnThumbPixSize
) >= mnThumbPixRange
) &&
332 (mnThumbPos
< (mnMaxRange
-mnVisibleSize
)) )
335 return nCalcThumbPos
;
338 // -----------------------------------------------------------------------
340 void ScrollBar::ImplCalc( BOOL bUpdate
)
342 const Size aSize
= GetOutputSizePixel();
343 const long nMinThumbSize
= GetSettings().GetStyleSettings().GetMinThumbSize();;
345 Rectangle
& maTrackRect
= mpData
->maTrackRect
; // TODO: remove when maTrackRect is no longer in mpData
348 const Region
aControlRegion( Rectangle( (const Point
&)Point(0,0), aSize
) );
349 Region aBtn1Region
, aBtn2Region
, aTrackRegion
, aBoundingRegion
;
351 if ( GetStyle() & WB_HORZ
)
353 if ( GetNativeControlRegion( CTRL_SCROLLBAR
, PART_BUTTON_LEFT
,
354 aControlRegion
, 0, ImplControlValue(), rtl::OUString(), aBoundingRegion
, aBtn1Region
) &&
355 GetNativeControlRegion( CTRL_SCROLLBAR
, PART_BUTTON_RIGHT
,
356 aControlRegion
, 0, ImplControlValue(), rtl::OUString(), aBoundingRegion
, aBtn2Region
) )
358 maBtn1Rect
= aBtn1Region
.GetBoundRect();
359 maBtn2Rect
= aBtn2Region
.GetBoundRect();
363 Size
aBtnSize( aSize
.Height(), aSize
.Height() );
364 maBtn2Rect
.Top() = maBtn1Rect
.Top();
365 maBtn2Rect
.Left() = aSize
.Width()-aSize
.Height();
366 maBtn1Rect
.SetSize( aBtnSize
);
367 maBtn2Rect
.SetSize( aBtnSize
);
370 if ( GetNativeControlRegion( CTRL_SCROLLBAR
, PART_TRACK_HORZ_AREA
,
371 aControlRegion
, 0, ImplControlValue(), rtl::OUString(), aBoundingRegion
, aTrackRegion
) )
372 maTrackRect
= aTrackRegion
.GetBoundRect();
374 maTrackRect
= Rectangle( maBtn1Rect
.TopRight(), maBtn2Rect
.BottomLeft() );
376 // Check if available space is big enough for thumb ( min thumb size = ScrBar width/height )
377 mnThumbPixRange
= maTrackRect
.Right() - maTrackRect
.Left();
378 if( mnThumbPixRange
> 0 )
380 maPage1Rect
.Left() = maTrackRect
.Left();
381 maPage1Rect
.Bottom() =
382 maPage2Rect
.Bottom() =
383 maThumbRect
.Bottom() = maTrackRect
.Bottom();
388 maPage1Rect
.SetEmpty();
389 maPage2Rect
.SetEmpty();
394 if ( GetNativeControlRegion( CTRL_SCROLLBAR
, PART_BUTTON_UP
,
395 aControlRegion
, 0, ImplControlValue(), rtl::OUString(), aBoundingRegion
, aBtn1Region
) &&
396 GetNativeControlRegion( CTRL_SCROLLBAR
, PART_BUTTON_DOWN
,
397 aControlRegion
, 0, ImplControlValue(), rtl::OUString(), aBoundingRegion
, aBtn2Region
) )
399 maBtn1Rect
= aBtn1Region
.GetBoundRect();
400 maBtn2Rect
= aBtn2Region
.GetBoundRect();
404 const Size
aBtnSize( aSize
.Width(), aSize
.Width() );
405 maBtn2Rect
.Left() = maBtn1Rect
.Left();
406 maBtn2Rect
.Top() = aSize
.Height()-aSize
.Width();
407 maBtn1Rect
.SetSize( aBtnSize
);
408 maBtn2Rect
.SetSize( aBtnSize
);
411 if ( GetNativeControlRegion( CTRL_SCROLLBAR
, PART_TRACK_VERT_AREA
,
412 aControlRegion
, 0, ImplControlValue(), rtl::OUString(), aBoundingRegion
, aTrackRegion
) )
413 maTrackRect
= aTrackRegion
.GetBoundRect();
415 maTrackRect
= Rectangle( maBtn1Rect
.BottomLeft()+Point(0,1), maBtn2Rect
.TopRight() );
417 // Check if available space is big enough for thumb
418 mnThumbPixRange
= maTrackRect
.Bottom() - maTrackRect
.Top();
419 if( mnThumbPixRange
> 0 )
421 maPage1Rect
.Top() = maTrackRect
.Top();
422 maPage1Rect
.Right() =
423 maPage2Rect
.Right() =
424 maThumbRect
.Right() = maTrackRect
.Right();
429 maPage1Rect
.SetEmpty();
430 maPage2Rect
.SetEmpty();
434 if ( !mnThumbPixRange
)
435 maThumbRect
.SetEmpty();
440 if ( mnThumbPixRange
)
443 if ( (mnVisibleSize
>= (mnMaxRange
-mnMinRange
)) ||
444 ((mnMaxRange
-mnMinRange
) <= 0) )
446 mnThumbPos
= mnMinRange
;
448 mnThumbPixSize
= mnThumbPixRange
;
453 mnThumbPixSize
= ImplMulDiv( mnThumbPixRange
, mnVisibleSize
, mnMaxRange
-mnMinRange
);
456 if ( GetStyle() & WB_HORZ
)
457 mnThumbPixSize
= maThumbRect
.GetWidth();
459 mnThumbPixSize
= maThumbRect
.GetHeight();
461 if ( mnThumbPixSize
< nMinThumbSize
)
462 mnThumbPixSize
= nMinThumbSize
;
463 if ( mnThumbPixSize
> mnThumbPixRange
)
464 mnThumbPixSize
= mnThumbPixRange
;
465 mnThumbPixPos
= ImplCalcThumbPosPix( mnThumbPos
);
469 // Wenn neu ausgegeben werden soll und wir schon ueber eine
470 // Aktion einen Paint-Event ausgeloest bekommen haben, dann
471 // geben wir nicht direkt aus, sondern invalidieren nur alles
472 if ( bUpdate
&& HasPaintEvent() )
477 ImplUpdateRects( bUpdate
);
480 // -----------------------------------------------------------------------
482 void ScrollBar::Draw( OutputDevice
* pDev
, const Point
& rPos
, const Size
& rSize
, ULONG nFlags
)
484 Point aPos
= pDev
->LogicToPixel( rPos
);
485 Size aSize
= pDev
->LogicToPixel( rSize
);
486 Rectangle
aRect( aPos
, aSize
);
490 if ( !(nFlags
& WINDOW_DRAW_MONO
) )
492 // DecoView uses the FaceColor...
493 AllSettings aSettings
= pDev
->GetSettings();
494 StyleSettings aStyleSettings
= aSettings
.GetStyleSettings();
495 if ( IsControlBackground() )
496 aStyleSettings
.SetFaceColor( GetControlBackground() );
498 aStyleSettings
.SetFaceColor( GetSettings().GetStyleSettings().GetFaceColor() );
500 aSettings
.SetStyleSettings( aStyleSettings
);
501 pDev
->SetSettings( aSettings
);
505 // -calculate the size of the rects
506 // -because this is zero-based add the correct offset
508 // -force recalculate
516 mpData
->maTrackRect
+=aPos
; // TODO: update when maTrackRect is no longer in mpData
520 ImplDraw( SCRBAR_DRAW_ALL
, pDev
);
526 // -----------------------------------------------------------------------
528 BOOL
ScrollBar::ImplDrawNative( USHORT nDrawFlags
)
530 ImplControlValue
aControlValue( BUTTONVALUE_DONTKNOW
, rtl::OUString(), 0 );
532 BOOL bNativeOK
= IsNativeControlSupported(CTRL_SCROLLBAR
, PART_ENTIRE_CONTROL
);
535 BOOL bHorz
= (GetStyle() & WB_HORZ
? true : false);
537 // Draw the entire background if the control supports it
538 if( IsNativeControlSupported(CTRL_SCROLLBAR
, bHorz
? PART_DRAW_BACKGROUND_HORZ
: PART_DRAW_BACKGROUND_VERT
) )
540 ControlState nState
= ( IsEnabled() ? CTRL_STATE_ENABLED
: 0 ) | ( HasFocus() ? CTRL_STATE_FOCUSED
: 0 );
541 ScrollbarValue scrValue
;
543 scrValue
.mnMin
= mnMinRange
;
544 scrValue
.mnMax
= mnMaxRange
;
545 scrValue
.mnCur
= mnThumbPos
;
546 scrValue
.mnVisibleSize
= mnVisibleSize
;
547 scrValue
.maThumbRect
= maThumbRect
;
548 scrValue
.maButton1Rect
= maBtn1Rect
;
549 scrValue
.maButton2Rect
= maBtn2Rect
;
550 scrValue
.mnButton1State
= ((mnStateFlags
& SCRBAR_STATE_BTN1_DOWN
) ? CTRL_STATE_PRESSED
: 0) |
551 ((!(mnStateFlags
& SCRBAR_STATE_BTN1_DISABLE
)) ? CTRL_STATE_ENABLED
: 0);
552 scrValue
.mnButton2State
= ((mnStateFlags
& SCRBAR_STATE_BTN2_DOWN
) ? CTRL_STATE_PRESSED
: 0) |
553 ((!(mnStateFlags
& SCRBAR_STATE_BTN2_DISABLE
)) ? CTRL_STATE_ENABLED
: 0);
554 scrValue
.mnThumbState
= nState
| ((mnStateFlags
& SCRBAR_STATE_THUMB_DOWN
) ? CTRL_STATE_PRESSED
: 0);
555 scrValue
.mnPage1State
= nState
| ((mnStateFlags
& SCRBAR_STATE_PAGE1_DOWN
) ? CTRL_STATE_PRESSED
: 0);
556 scrValue
.mnPage2State
= nState
| ((mnStateFlags
& SCRBAR_STATE_PAGE2_DOWN
) ? CTRL_STATE_PRESSED
: 0);
560 Rectangle
* pRect
= ImplFindPartRect( GetPointerPosPixel() );
563 if( pRect
== &maThumbRect
)
564 scrValue
.mnThumbState
|= CTRL_STATE_ROLLOVER
;
565 else if( pRect
== &maBtn1Rect
)
566 scrValue
.mnButton1State
|= CTRL_STATE_ROLLOVER
;
567 else if( pRect
== &maBtn2Rect
)
568 scrValue
.mnButton2State
|= CTRL_STATE_ROLLOVER
;
569 else if( pRect
== &maPage1Rect
)
570 scrValue
.mnPage1State
|= CTRL_STATE_ROLLOVER
;
571 else if( pRect
== &maPage2Rect
)
572 scrValue
.mnPage2State
|= CTRL_STATE_ROLLOVER
;
576 aControlValue
.setOptionalVal( (void *)(&scrValue
) );
580 aCtrlRegion
.Union( maBtn1Rect
);
581 aCtrlRegion
.Union( maBtn2Rect
);
582 aCtrlRegion
.Union( maPage1Rect
);
583 aCtrlRegion
.Union( maPage2Rect
);
584 aCtrlRegion
.Union( maThumbRect
);
586 const Region
aCtrlRegion( Rectangle( Point(0,0), GetOutputSizePixel() ) );
588 bNativeOK
= DrawNativeControl( CTRL_SCROLLBAR
, (bHorz
? PART_DRAW_BACKGROUND_HORZ
: PART_DRAW_BACKGROUND_VERT
),
589 aCtrlRegion
, nState
, aControlValue
, rtl::OUString() );
593 if ( (nDrawFlags
& SCRBAR_DRAW_PAGE1
) || (nDrawFlags
& SCRBAR_DRAW_PAGE2
) )
595 sal_uInt32 part1
= bHorz
? PART_TRACK_HORZ_LEFT
: PART_TRACK_VERT_UPPER
;
596 sal_uInt32 part2
= bHorz
? PART_TRACK_HORZ_RIGHT
: PART_TRACK_VERT_LOWER
;
597 Region
aCtrlRegion1( maPage1Rect
);
598 Region
aCtrlRegion2( maPage2Rect
);
599 ControlState nState1
= (IsEnabled() ? CTRL_STATE_ENABLED
: 0) | (HasFocus() ? CTRL_STATE_FOCUSED
: 0);
600 ControlState nState2
= nState1
;
602 nState1
|= ((mnStateFlags
& SCRBAR_STATE_PAGE1_DOWN
) ? CTRL_STATE_PRESSED
: 0);
603 nState2
|= ((mnStateFlags
& SCRBAR_STATE_PAGE2_DOWN
) ? CTRL_STATE_PRESSED
: 0);
607 Rectangle
* pRect
= ImplFindPartRect( GetPointerPosPixel() );
610 if( pRect
== &maPage1Rect
)
611 nState1
|= CTRL_STATE_ROLLOVER
;
612 else if( pRect
== &maPage2Rect
)
613 nState2
|= CTRL_STATE_ROLLOVER
;
617 if ( nDrawFlags
& SCRBAR_DRAW_PAGE1
)
618 bNativeOK
= DrawNativeControl( CTRL_SCROLLBAR
, part1
, aCtrlRegion1
, nState1
,
619 aControlValue
, rtl::OUString() );
621 if ( nDrawFlags
& SCRBAR_DRAW_PAGE2
)
622 bNativeOK
= DrawNativeControl( CTRL_SCROLLBAR
, part2
, aCtrlRegion2
, nState2
,
623 aControlValue
, rtl::OUString() );
625 if ( (nDrawFlags
& SCRBAR_DRAW_BTN1
) || (nDrawFlags
& SCRBAR_DRAW_BTN2
) )
627 sal_uInt32 part1
= bHorz
? PART_BUTTON_LEFT
: PART_BUTTON_UP
;
628 sal_uInt32 part2
= bHorz
? PART_BUTTON_RIGHT
: PART_BUTTON_DOWN
;
629 Region
aCtrlRegion1( maBtn1Rect
);
630 Region
aCtrlRegion2( maBtn2Rect
);
631 ControlState nState1
= HasFocus() ? CTRL_STATE_FOCUSED
: 0;
632 ControlState nState2
= nState1
;
634 if ( !Window::IsEnabled() || !IsEnabled() )
635 nState1
= (nState2
&= ~CTRL_STATE_ENABLED
);
637 nState1
= (nState2
|= CTRL_STATE_ENABLED
);
639 nState1
|= ((mnStateFlags
& SCRBAR_STATE_BTN1_DOWN
) ? CTRL_STATE_PRESSED
: 0);
640 nState2
|= ((mnStateFlags
& SCRBAR_STATE_BTN2_DOWN
) ? CTRL_STATE_PRESSED
: 0);
642 if(mnStateFlags
& SCRBAR_STATE_BTN1_DISABLE
)
643 nState1
&= ~CTRL_STATE_ENABLED
;
644 if(mnStateFlags
& SCRBAR_STATE_BTN2_DISABLE
)
645 nState2
&= ~CTRL_STATE_ENABLED
;
649 Rectangle
* pRect
= ImplFindPartRect( GetPointerPosPixel() );
652 if( pRect
== &maBtn1Rect
)
653 nState1
|= CTRL_STATE_ROLLOVER
;
654 else if( pRect
== &maBtn2Rect
)
655 nState2
|= CTRL_STATE_ROLLOVER
;
659 if ( nDrawFlags
& SCRBAR_DRAW_BTN1
)
660 bNativeOK
= DrawNativeControl( CTRL_SCROLLBAR
, part1
, aCtrlRegion1
, nState1
,
661 aControlValue
, rtl::OUString() );
663 if ( nDrawFlags
& SCRBAR_DRAW_BTN2
)
664 bNativeOK
= DrawNativeControl( CTRL_SCROLLBAR
, part2
, aCtrlRegion2
, nState2
,
665 aControlValue
, rtl::OUString() );
667 if ( (nDrawFlags
& SCRBAR_DRAW_THUMB
) && !maThumbRect
.IsEmpty() )
669 ControlState nState
= IsEnabled() ? CTRL_STATE_ENABLED
: 0;
670 Region
aCtrlRegion( maThumbRect
);
672 if ( mnStateFlags
& SCRBAR_STATE_THUMB_DOWN
)
673 nState
|= CTRL_STATE_PRESSED
;
676 nState
|= CTRL_STATE_FOCUSED
;
680 Rectangle
* pRect
= ImplFindPartRect( GetPointerPosPixel() );
683 if( pRect
== &maThumbRect
)
684 nState
|= CTRL_STATE_ROLLOVER
;
688 bNativeOK
= DrawNativeControl( CTRL_SCROLLBAR
, (bHorz
? PART_THUMB_HORZ
: PART_THUMB_VERT
),
689 aCtrlRegion
, nState
, aControlValue
, rtl::OUString() );
696 void ScrollBar::ImplDraw( USHORT nDrawFlags
, OutputDevice
* pOutDev
)
698 DecorationView
aDecoView( pOutDev
);
701 const StyleSettings
& rStyleSettings
= pOutDev
->GetSettings().GetStyleSettings();
702 SymbolType eSymbolType
;
703 BOOL bEnabled
= IsEnabled();
705 // Evt. noch offene Berechnungen nachholen
710 if( pOutDev
->GetOutDevType() == OUTDEV_WINDOW
)
711 pWin
= (Window
*) pOutDev
;
713 // Draw the entire control if the native theme engine needs it
714 if ( nDrawFlags
&& pWin
&& pWin
->IsNativeControlSupported(CTRL_SCROLLBAR
, PART_DRAW_BACKGROUND_HORZ
) )
716 ImplDrawNative( SCRBAR_DRAW_BACKGROUND
);
720 if( (nDrawFlags
& SCRBAR_DRAW_BTN1
) && (!pWin
|| !ImplDrawNative( SCRBAR_DRAW_BTN1
) ) )
722 nStyle
= BUTTON_DRAW_NOLIGHTBORDER
;
723 if ( mnStateFlags
& SCRBAR_STATE_BTN1_DOWN
)
724 nStyle
|= BUTTON_DRAW_PRESSED
;
725 aTempRect
= aDecoView
.DrawButton( maBtn1Rect
, nStyle
);
726 ImplCalcSymbolRect( aTempRect
);
728 if ( (mnStateFlags
& SCRBAR_STATE_BTN1_DISABLE
) || !bEnabled
)
729 nStyle
|= SYMBOL_DRAW_DISABLE
;
730 if ( rStyleSettings
.GetOptions() & STYLE_OPTION_SCROLLARROW
)
732 if ( GetStyle() & WB_HORZ
)
733 eSymbolType
= SYMBOL_ARROW_LEFT
;
735 eSymbolType
= SYMBOL_ARROW_UP
;
739 if ( GetStyle() & WB_HORZ
)
740 eSymbolType
= SYMBOL_SPIN_LEFT
;
742 eSymbolType
= SYMBOL_SPIN_UP
;
744 aDecoView
.DrawSymbol( aTempRect
, eSymbolType
, rStyleSettings
.GetButtonTextColor(), nStyle
);
747 if ( (nDrawFlags
& SCRBAR_DRAW_BTN2
) && (!pWin
|| !ImplDrawNative( SCRBAR_DRAW_BTN2
) ) )
749 nStyle
= BUTTON_DRAW_NOLIGHTBORDER
;
750 if ( mnStateFlags
& SCRBAR_STATE_BTN2_DOWN
)
751 nStyle
|= BUTTON_DRAW_PRESSED
;
752 aTempRect
= aDecoView
.DrawButton( maBtn2Rect
, nStyle
);
753 ImplCalcSymbolRect( aTempRect
);
755 if ( (mnStateFlags
& SCRBAR_STATE_BTN2_DISABLE
) || !bEnabled
)
756 nStyle
|= SYMBOL_DRAW_DISABLE
;
757 if ( rStyleSettings
.GetOptions() & STYLE_OPTION_SCROLLARROW
)
759 if ( GetStyle() & WB_HORZ
)
760 eSymbolType
= SYMBOL_ARROW_RIGHT
;
762 eSymbolType
= SYMBOL_ARROW_DOWN
;
766 if ( GetStyle() & WB_HORZ
)
767 eSymbolType
= SYMBOL_SPIN_RIGHT
;
769 eSymbolType
= SYMBOL_SPIN_DOWN
;
771 aDecoView
.DrawSymbol( aTempRect
, eSymbolType
, rStyleSettings
.GetButtonTextColor(), nStyle
);
774 pOutDev
->SetLineColor();
776 if ( (nDrawFlags
& SCRBAR_DRAW_THUMB
) && (!pWin
|| !ImplDrawNative( SCRBAR_DRAW_THUMB
) ) )
778 if ( !maThumbRect
.IsEmpty() )
782 nStyle
= BUTTON_DRAW_NOLIGHTBORDER
;
783 // pressed thumbs only in OS2 style
784 if ( rStyleSettings
.GetOptions() & STYLE_OPTION_OS2STYLE
)
785 if ( mnStateFlags
& SCRBAR_STATE_THUMB_DOWN
)
786 nStyle
|= BUTTON_DRAW_PRESSED
;
787 aTempRect
= aDecoView
.DrawButton( maThumbRect
, nStyle
);
788 // OS2 style requires pattern on the thumb
789 if ( rStyleSettings
.GetOptions() & STYLE_OPTION_OS2STYLE
)
791 if ( GetStyle() & WB_HORZ
)
793 if ( aTempRect
.GetWidth() > 6 )
795 long nX
= aTempRect
.Center().X();
797 if ( nX
< aTempRect
.Left() )
798 nX
= aTempRect
.Left();
799 for ( int i
= 0; i
< 6; i
++ )
801 if ( nX
> aTempRect
.Right()-1 )
804 pOutDev
->SetLineColor( rStyleSettings
.GetButtonTextColor() );
805 pOutDev
->DrawLine( Point( nX
, aTempRect
.Top()+1 ),
806 Point( nX
, aTempRect
.Bottom()-1 ) );
808 pOutDev
->SetLineColor( rStyleSettings
.GetLightColor() );
809 pOutDev
->DrawLine( Point( nX
, aTempRect
.Top()+1 ),
810 Point( nX
, aTempRect
.Bottom()-1 ) );
817 if ( aTempRect
.GetHeight() > 6 )
819 long nY
= aTempRect
.Center().Y();
821 if ( nY
< aTempRect
.Top() )
822 nY
= aTempRect
.Top();
823 for ( int i
= 0; i
< 6; i
++ )
825 if ( nY
> aTempRect
.Bottom()-1 )
828 pOutDev
->SetLineColor( rStyleSettings
.GetButtonTextColor() );
829 pOutDev
->DrawLine( Point( aTempRect
.Left()+1, nY
),
830 Point( aTempRect
.Right()-1, nY
) );
832 pOutDev
->SetLineColor( rStyleSettings
.GetLightColor() );
833 pOutDev
->DrawLine( Point( aTempRect
.Left()+1, nY
),
834 Point( aTempRect
.Right()-1, nY
) );
839 pOutDev
->SetLineColor();
844 pOutDev
->SetFillColor( rStyleSettings
.GetCheckedColor() );
845 pOutDev
->DrawRect( maThumbRect
);
850 if ( (nDrawFlags
& SCRBAR_DRAW_PAGE1
) && (!pWin
|| !ImplDrawNative( SCRBAR_DRAW_PAGE1
) ) )
852 if ( mnStateFlags
& SCRBAR_STATE_PAGE1_DOWN
)
853 pOutDev
->SetFillColor( rStyleSettings
.GetShadowColor() );
855 pOutDev
->SetFillColor( rStyleSettings
.GetCheckedColor() );
856 pOutDev
->DrawRect( maPage1Rect
);
858 if ( (nDrawFlags
& SCRBAR_DRAW_PAGE2
) && (!pWin
|| !ImplDrawNative( SCRBAR_DRAW_PAGE2
) ) )
860 if ( mnStateFlags
& SCRBAR_STATE_PAGE2_DOWN
)
861 pOutDev
->SetFillColor( rStyleSettings
.GetShadowColor() );
863 pOutDev
->SetFillColor( rStyleSettings
.GetCheckedColor() );
864 pOutDev
->DrawRect( maPage2Rect
);
868 // -----------------------------------------------------------------------
870 long ScrollBar::ImplScroll( long nNewPos
, BOOL bCallEndScroll
)
872 long nOldPos
= mnThumbPos
;
873 SetThumbPos( nNewPos
);
874 long nDelta
= mnThumbPos
-nOldPos
;
879 if ( bCallEndScroll
)
886 // -----------------------------------------------------------------------
888 long ScrollBar::ImplDoAction( BOOL bCallEndScroll
)
892 switch ( meScrollType
)
895 nDelta
= ImplScroll( mnThumbPos
-mnLineSize
, bCallEndScroll
);
898 case SCROLL_LINEDOWN
:
899 nDelta
= ImplScroll( mnThumbPos
+mnLineSize
, bCallEndScroll
);
903 nDelta
= ImplScroll( mnThumbPos
-mnPageSize
, bCallEndScroll
);
906 case SCROLL_PAGEDOWN
:
907 nDelta
= ImplScroll( mnThumbPos
+mnPageSize
, bCallEndScroll
);
916 // -----------------------------------------------------------------------
918 void ScrollBar::ImplDoMouseAction( const Point
& rMousePos
, BOOL bCallAction
)
920 USHORT nOldStateFlags
= mnStateFlags
;
921 BOOL bAction
= FALSE
;
922 BOOL bHorizontal
= ( GetStyle() & WB_HORZ
)? TRUE
: FALSE
;
923 BOOL bIsInside
= FALSE
;
925 Point
aPoint( 0, 0 );
926 Region
aControlRegion( Rectangle( aPoint
, GetOutputSizePixel() ) );
928 switch ( meScrollType
)
931 if ( HitTestNativeControl( CTRL_SCROLLBAR
, bHorizontal
? PART_BUTTON_LEFT
: PART_BUTTON_UP
,
932 aControlRegion
, rMousePos
, bIsInside
)?
934 maBtn1Rect
.IsInside( rMousePos
) )
936 bAction
= bCallAction
;
937 mnStateFlags
|= SCRBAR_STATE_BTN1_DOWN
;
940 mnStateFlags
&= ~SCRBAR_STATE_BTN1_DOWN
;
943 case SCROLL_LINEDOWN
:
944 if ( HitTestNativeControl( CTRL_SCROLLBAR
, bHorizontal
? PART_BUTTON_RIGHT
: PART_BUTTON_DOWN
,
945 aControlRegion
, rMousePos
, bIsInside
)?
947 maBtn2Rect
.IsInside( rMousePos
) )
949 bAction
= bCallAction
;
950 mnStateFlags
|= SCRBAR_STATE_BTN2_DOWN
;
953 mnStateFlags
&= ~SCRBAR_STATE_BTN2_DOWN
;
957 // HitTestNativeControl, see remark at top of file
958 if ( HitTestNativeControl( CTRL_SCROLLBAR
, bHorizontal
? PART_TRACK_HORZ_LEFT
: PART_TRACK_VERT_UPPER
,
959 Region( maPage1Rect
), rMousePos
, bIsInside
)?
961 maPage1Rect
.IsInside( rMousePos
) )
963 bAction
= bCallAction
;
964 mnStateFlags
|= SCRBAR_STATE_PAGE1_DOWN
;
967 mnStateFlags
&= ~SCRBAR_STATE_PAGE1_DOWN
;
970 case SCROLL_PAGEDOWN
:
971 // HitTestNativeControl, see remark at top of file
972 if ( HitTestNativeControl( CTRL_SCROLLBAR
, bHorizontal
? PART_TRACK_HORZ_RIGHT
: PART_TRACK_VERT_LOWER
,
973 Region( maPage2Rect
), rMousePos
, bIsInside
)?
975 maPage2Rect
.IsInside( rMousePos
) )
977 bAction
= bCallAction
;
978 mnStateFlags
|= SCRBAR_STATE_PAGE2_DOWN
;
981 mnStateFlags
&= ~SCRBAR_STATE_PAGE2_DOWN
;
987 if ( nOldStateFlags
!= mnStateFlags
)
988 ImplDraw( mnDragDraw
, this );
990 ImplDoAction( FALSE
);
993 // -----------------------------------------------------------------------
995 void ScrollBar::ImplDragThumb( const Point
& rMousePos
)
998 if ( GetStyle() & WB_HORZ
)
999 nMovePix
= rMousePos
.X()-(maThumbRect
.Left()+mnMouseOff
);
1001 nMovePix
= rMousePos
.Y()-(maThumbRect
.Top()+mnMouseOff
);
1003 // move thumb if necessary
1006 mnThumbPixPos
+= nMovePix
;
1007 if ( mnThumbPixPos
< 0 )
1009 if ( mnThumbPixPos
> (mnThumbPixRange
-mnThumbPixSize
) )
1010 mnThumbPixPos
= mnThumbPixRange
-mnThumbPixSize
;
1011 long nOldPos
= mnThumbPos
;
1012 mnThumbPos
= ImplCalcThumbPos( mnThumbPixPos
);
1014 if ( mbFullDrag
&& (nOldPos
!= mnThumbPos
) )
1016 mnDelta
= mnThumbPos
-nOldPos
;
1023 // -----------------------------------------------------------------------
1025 void ScrollBar::MouseButtonDown( const MouseEvent
& rMEvt
)
1027 if ( rMEvt
.IsLeft() || rMEvt
.IsMiddle() )
1029 const Point
& rMousePos
= rMEvt
.GetPosPixel();
1030 USHORT nTrackFlags
= 0;
1031 BOOL bHorizontal
= ( GetStyle() & WB_HORZ
)? TRUE
: FALSE
;
1032 BOOL bIsInside
= FALSE
;
1033 BOOL bDragToMouse
= FALSE
;
1035 Point
aPoint( 0, 0 );
1036 Region
aControlRegion( Rectangle( aPoint
, GetOutputSizePixel() ) );
1038 if ( HitTestNativeControl( CTRL_SCROLLBAR
, bHorizontal
? PART_BUTTON_LEFT
: PART_BUTTON_UP
,
1039 aControlRegion
, rMousePos
, bIsInside
)?
1041 maBtn1Rect
.IsInside( rMousePos
) )
1043 if ( !(mnStateFlags
& SCRBAR_STATE_BTN1_DISABLE
) )
1045 nTrackFlags
= STARTTRACK_BUTTONREPEAT
;
1046 meScrollType
= SCROLL_LINEUP
;
1047 mnDragDraw
= SCRBAR_DRAW_BTN1
;
1050 Sound::Beep( SOUND_DISABLE
, this );
1052 else if ( HitTestNativeControl( CTRL_SCROLLBAR
, bHorizontal
? PART_BUTTON_RIGHT
: PART_BUTTON_DOWN
,
1053 aControlRegion
, rMousePos
, bIsInside
)?
1055 maBtn2Rect
.IsInside( rMousePos
) )
1057 if ( !(mnStateFlags
& SCRBAR_STATE_BTN2_DISABLE
) )
1059 nTrackFlags
= STARTTRACK_BUTTONREPEAT
;
1060 meScrollType
= SCROLL_LINEDOWN
;
1061 mnDragDraw
= SCRBAR_DRAW_BTN2
;
1064 Sound::Beep( SOUND_DISABLE
, this );
1068 bool bThumbHit
= HitTestNativeControl( CTRL_SCROLLBAR
, bHorizontal
? PART_THUMB_HORZ
: PART_THUMB_VERT
,
1069 Region( maThumbRect
), rMousePos
, bIsInside
)
1070 ? bIsInside
: maThumbRect
.IsInside( rMousePos
);
1071 bool bDragHandling
= rMEvt
.IsMiddle() || bThumbHit
|| ImplGetSVData()->maNWFData
.mbScrollbarJumpPage
;
1076 mpData
->mbHide
= TRUE
; // disable focus blinking
1078 ImplDraw( SCRBAR_DRAW_THUMB
, this ); // paint without focus
1081 if ( mnVisibleSize
< mnMaxRange
-mnMinRange
)
1084 meScrollType
= SCROLL_DRAG
;
1085 mnDragDraw
= SCRBAR_DRAW_THUMB
;
1087 // calculate mouse offset
1088 if( rMEvt
.IsMiddle() || (ImplGetSVData()->maNWFData
.mbScrollbarJumpPage
&& !bThumbHit
) )
1090 bDragToMouse
= TRUE
;
1091 if ( GetStyle() & WB_HORZ
)
1092 mnMouseOff
= maThumbRect
.GetWidth()/2;
1094 mnMouseOff
= maThumbRect
.GetHeight()/2;
1098 if ( GetStyle() & WB_HORZ
)
1099 mnMouseOff
= rMousePos
.X()-maThumbRect
.Left();
1101 mnMouseOff
= rMousePos
.Y()-maThumbRect
.Top();
1104 mnStateFlags
|= SCRBAR_STATE_THUMB_DOWN
;
1105 ImplDraw( mnDragDraw
, this );
1108 Sound::Beep( SOUND_DISABLE
, this );
1110 else if( HitTestNativeControl( CTRL_SCROLLBAR
, bHorizontal
? PART_TRACK_HORZ_AREA
: PART_TRACK_VERT_AREA
,
1111 aControlRegion
, rMousePos
, bIsInside
)?
1114 nTrackFlags
= STARTTRACK_BUTTONREPEAT
;
1116 // HitTestNativeControl, see remark at top of file
1117 if ( HitTestNativeControl( CTRL_SCROLLBAR
, bHorizontal
? PART_TRACK_HORZ_LEFT
: PART_TRACK_VERT_UPPER
,
1118 Region( maPage1Rect
), rMousePos
, bIsInside
)?
1120 maPage1Rect
.IsInside( rMousePos
) )
1122 meScrollType
= SCROLL_PAGEUP
;
1123 mnDragDraw
= SCRBAR_DRAW_PAGE1
;
1127 meScrollType
= SCROLL_PAGEDOWN
;
1128 mnDragDraw
= SCRBAR_DRAW_PAGE2
;
1133 // Soll Tracking gestartet werden
1134 if ( meScrollType
!= SCROLL_DONTKNOW
)
1136 // remember original position in case of abort or EndScroll-Delta
1137 mnStartPos
= mnThumbPos
;
1138 // #92906# Call StartTracking() before ImplDoMouseAction(), otherwise
1139 // MouseButtonUp() / EndTracking() may be called if somebody is spending
1140 // a lot of time in the scroll handler
1141 StartTracking( nTrackFlags
);
1142 ImplDoMouseAction( rMousePos
);
1145 ImplDragThumb( rMousePos
);
1150 // -----------------------------------------------------------------------
1152 void ScrollBar::Tracking( const TrackingEvent
& rTEvt
)
1154 if ( rTEvt
.IsTrackingEnded() )
1156 // Button und PageRect-Status wieder herstellen
1157 USHORT nOldStateFlags
= mnStateFlags
;
1158 mnStateFlags
&= ~(SCRBAR_STATE_BTN1_DOWN
| SCRBAR_STATE_BTN2_DOWN
|
1159 SCRBAR_STATE_PAGE1_DOWN
| SCRBAR_STATE_PAGE2_DOWN
|
1160 SCRBAR_STATE_THUMB_DOWN
);
1161 if ( nOldStateFlags
!= mnStateFlags
)
1162 ImplDraw( mnDragDraw
, this );
1165 // Bei Abbruch, die alte ThumbPosition wieder herstellen
1166 if ( rTEvt
.IsTrackingCanceled() )
1168 long nOldPos
= mnThumbPos
;
1169 SetThumbPos( mnStartPos
);
1170 mnDelta
= mnThumbPos
-nOldPos
;
1174 if ( meScrollType
== SCROLL_DRAG
)
1176 // Wenn gedragt wurde, berechnen wir den Thumb neu, damit
1177 // er wieder auf einer gerundeten ThumbPosition steht
1180 if ( !mbFullDrag
&& (mnStartPos
!= mnThumbPos
) )
1182 mnDelta
= mnThumbPos
-mnStartPos
;
1188 mnDelta
= mnThumbPos
-mnStartPos
;
1191 meScrollType
= SCROLL_DONTKNOW
;
1194 mpData
->mbHide
= FALSE
; // re-enable focus blinking
1198 const Point rMousePos
= rTEvt
.GetMouseEvent().GetPosPixel();
1200 // Dragging wird speziell behandelt
1201 if ( meScrollType
== SCROLL_DRAG
)
1202 ImplDragThumb( rMousePos
);
1204 ImplDoMouseAction( rMousePos
, rTEvt
.IsTrackingRepeat() );
1206 // Wenn ScrollBar-Werte so umgesetzt wurden, das es nichts
1207 // mehr zum Tracking gibt, dann berechen wir hier ab
1208 if ( !IsVisible() || (mnVisibleSize
>= (mnMaxRange
-mnMinRange
)) )
1213 // -----------------------------------------------------------------------
1215 void ScrollBar::KeyInput( const KeyEvent
& rKEvt
)
1217 if ( !rKEvt
.GetKeyCode().GetModifier() )
1219 switch ( rKEvt
.GetKeyCode().GetCode() )
1226 DoScroll( GetRangeMax() );
1231 DoScrollAction( SCROLL_LINEUP
);
1236 DoScrollAction( SCROLL_LINEDOWN
);
1240 DoScrollAction( SCROLL_PAGEUP
);
1244 DoScrollAction( SCROLL_PAGEDOWN
);
1248 Control::KeyInput( rKEvt
);
1253 Control::KeyInput( rKEvt
);
1256 // -----------------------------------------------------------------------
1258 void ScrollBar::Paint( const Rectangle
& )
1260 ImplDraw( SCRBAR_DRAW_ALL
, this );
1263 // -----------------------------------------------------------------------
1265 void ScrollBar::Resize()
1269 if ( IsReallyVisible() )
1274 // -----------------------------------------------------------------------
1276 IMPL_LINK( ScrollBar
, ImplAutoTimerHdl
, AutoTimer
*, EMPTYARG
)
1278 if( mpData
&& mpData
->mbHide
)
1284 void ScrollBar::ImplInvert()
1286 Rectangle
aRect( maThumbRect
);
1287 if( aRect
.getWidth() > 4 )
1292 if( aRect
.getHeight() > 4 )
1295 aRect
.Bottom() -= 2;
1301 // -----------------------------------------------------------------------
1303 void ScrollBar::GetFocus()
1307 mpData
= new ImplScrollBarData
;
1308 mpData
->maTimer
.SetTimeoutHdl( LINK( this, ScrollBar
, ImplAutoTimerHdl
) );
1309 mpData
->mbHide
= FALSE
;
1311 ImplInvert(); // react immediately
1312 mpData
->maTimer
.SetTimeout( GetSettings().GetStyleSettings().GetCursorBlinkTime() );
1313 mpData
->maTimer
.Start();
1314 Control::GetFocus();
1317 // -----------------------------------------------------------------------
1319 void ScrollBar::LoseFocus()
1322 mpData
->maTimer
.Stop();
1323 ImplDraw( SCRBAR_DRAW_THUMB
, this );
1325 Control::LoseFocus();
1328 // -----------------------------------------------------------------------
1330 void ScrollBar::StateChanged( StateChangedType nType
)
1332 Control::StateChanged( nType
);
1334 if ( nType
== STATE_CHANGE_INITSHOW
)
1336 else if ( nType
== STATE_CHANGE_DATA
)
1338 if ( IsReallyVisible() && IsUpdateMode() )
1341 else if ( nType
== STATE_CHANGE_UPDATEMODE
)
1343 if ( IsReallyVisible() && IsUpdateMode() )
1349 else if ( nType
== STATE_CHANGE_ENABLE
)
1351 if ( IsReallyVisible() && IsUpdateMode() )
1354 else if ( nType
== STATE_CHANGE_STYLE
)
1356 ImplInitStyle( GetStyle() );
1357 if ( IsReallyVisible() && IsUpdateMode() )
1359 if ( (GetPrevStyle() & SCRBAR_VIEW_STYLE
) !=
1360 (GetStyle() & SCRBAR_VIEW_STYLE
) )
1370 // -----------------------------------------------------------------------
1372 void ScrollBar::DataChanged( const DataChangedEvent
& rDCEvt
)
1374 Control::DataChanged( rDCEvt
);
1376 if ( (rDCEvt
.GetType() == DATACHANGED_SETTINGS
) &&
1377 (rDCEvt
.GetFlags() & SETTINGS_STYLE
) )
1385 // -----------------------------------------------------------------------
1387 Rectangle
* ScrollBar::ImplFindPartRect( const Point
& rPt
)
1389 BOOL bHorizontal
= ( GetStyle() & WB_HORZ
)? TRUE
: FALSE
;
1390 BOOL bIsInside
= FALSE
;
1392 Point
aPoint( 0, 0 );
1393 Region
aControlRegion( Rectangle( aPoint
, GetOutputSizePixel() ) );
1395 if( HitTestNativeControl( CTRL_SCROLLBAR
, bHorizontal
? PART_BUTTON_LEFT
: PART_BUTTON_UP
,
1396 aControlRegion
, rPt
, bIsInside
)?
1398 maBtn1Rect
.IsInside( rPt
) )
1400 else if( HitTestNativeControl( CTRL_SCROLLBAR
, bHorizontal
? PART_BUTTON_RIGHT
: PART_BUTTON_DOWN
,
1401 aControlRegion
, rPt
, bIsInside
)?
1403 maBtn2Rect
.IsInside( rPt
) )
1405 // HitTestNativeControl, see remark at top of file
1406 else if( HitTestNativeControl( CTRL_SCROLLBAR
, bHorizontal
? PART_TRACK_HORZ_LEFT
: PART_TRACK_VERT_UPPER
,
1407 Region( maPage1Rect
), rPt
, bIsInside
)?
1409 maPage1Rect
.IsInside( rPt
) )
1410 return &maPage1Rect
;
1411 // HitTestNativeControl, see remark at top of file
1412 else if( HitTestNativeControl( CTRL_SCROLLBAR
, bHorizontal
? PART_TRACK_HORZ_RIGHT
: PART_TRACK_VERT_LOWER
,
1413 Region( maPage2Rect
), rPt
, bIsInside
)?
1415 maPage2Rect
.IsInside( rPt
) )
1416 return &maPage2Rect
;
1417 // HitTestNativeControl, see remark at top of file
1418 else if( HitTestNativeControl( CTRL_SCROLLBAR
, bHorizontal
? PART_THUMB_HORZ
: PART_THUMB_VERT
,
1419 Region( maThumbRect
), rPt
, bIsInside
)?
1421 maThumbRect
.IsInside( rPt
) )
1422 return &maThumbRect
;
1427 long ScrollBar::PreNotify( NotifyEvent
& rNEvt
)
1430 const MouseEvent
* pMouseEvt
= NULL
;
1432 if( (rNEvt
.GetType() == EVENT_MOUSEMOVE
) && (pMouseEvt
= rNEvt
.GetMouseEvent()) != NULL
)
1434 if( !pMouseEvt
->GetButtons() && !pMouseEvt
->IsSynthetic() && !pMouseEvt
->IsModifierChanged() )
1436 // trigger redraw if mouse over state has changed
1437 if( IsNativeControlSupported(CTRL_SCROLLBAR
, PART_ENTIRE_CONTROL
) )
1439 Rectangle
* pRect
= ImplFindPartRect( GetPointerPosPixel() );
1440 Rectangle
* pLastRect
= ImplFindPartRect( GetLastPointerPosPixel() );
1441 if( pRect
!= pLastRect
|| pMouseEvt
->IsLeaveWindow() || pMouseEvt
->IsEnterWindow() )
1443 Region
aRgn( GetActiveClipRegion() );
1447 aClipRegion
.Union( *pRect
);
1449 aClipRegion
.Union( *pLastRect
);
1451 // Support for 3-button scroll bars
1452 BOOL bHas3Buttons
= IsNativeControlSupported( CTRL_SCROLLBAR
, HAS_THREE_BUTTONS
);
1453 if ( bHas3Buttons
&& ( pRect
== &maBtn1Rect
|| pLastRect
== &maBtn1Rect
) )
1455 aClipRegion
.Union( maBtn2Rect
);
1458 SetClipRegion( aClipRegion
);
1459 Paint( aClipRegion
.GetBoundRect() );
1461 SetClipRegion( aRgn
);
1467 return nDone
? nDone
: Control::PreNotify(rNEvt
);
1470 // -----------------------------------------------------------------------
1472 void ScrollBar::Scroll()
1474 ImplCallEventListenersAndHandler( VCLEVENT_SCROLLBAR_SCROLL
, maScrollHdl
, this );
1477 // -----------------------------------------------------------------------
1479 void ScrollBar::EndScroll()
1481 ImplCallEventListenersAndHandler( VCLEVENT_SCROLLBAR_ENDSCROLL
, maEndScrollHdl
, this );
1484 // -----------------------------------------------------------------------
1486 long ScrollBar::DoScroll( long nNewPos
)
1488 if ( meScrollType
!= SCROLL_DONTKNOW
)
1491 meScrollType
= SCROLL_DRAG
;
1492 long nDelta
= ImplScroll( nNewPos
, TRUE
);
1493 meScrollType
= SCROLL_DONTKNOW
;
1497 // -----------------------------------------------------------------------
1499 long ScrollBar::DoScrollAction( ScrollType eScrollType
)
1501 if ( (meScrollType
!= SCROLL_DONTKNOW
) ||
1502 (eScrollType
== SCROLL_DONTKNOW
) ||
1503 (eScrollType
== SCROLL_DRAG
) )
1506 meScrollType
= eScrollType
;
1507 long nDelta
= ImplDoAction( TRUE
);
1508 meScrollType
= SCROLL_DONTKNOW
;
1512 // -----------------------------------------------------------------------
1514 void ScrollBar::SetRangeMin( long nNewRange
)
1516 SetRange( Range( nNewRange
, GetRangeMax() ) );
1519 // -----------------------------------------------------------------------
1521 void ScrollBar::SetRangeMax( long nNewRange
)
1523 SetRange( Range( GetRangeMin(), nNewRange
) );
1526 // -----------------------------------------------------------------------
1528 void ScrollBar::SetRange( const Range
& rRange
)
1531 Range aRange
= rRange
;
1533 long nNewMinRange
= aRange
.Min();
1534 long nNewMaxRange
= aRange
.Max();
1536 // Wenn Range sich unterscheidet, dann neuen setzen
1537 if ( (mnMinRange
!= nNewMinRange
) ||
1538 (mnMaxRange
!= nNewMaxRange
) )
1540 mnMinRange
= nNewMinRange
;
1541 mnMaxRange
= nNewMaxRange
;
1544 if ( mnThumbPos
> mnMaxRange
-mnVisibleSize
)
1545 mnThumbPos
= mnMaxRange
-mnVisibleSize
;
1546 if ( mnThumbPos
< mnMinRange
)
1547 mnThumbPos
= mnMinRange
;
1549 StateChanged( STATE_CHANGE_DATA
);
1553 // -----------------------------------------------------------------------
1555 void ScrollBar::SetThumbPos( long nNewThumbPos
)
1557 if ( nNewThumbPos
> mnMaxRange
-mnVisibleSize
)
1558 nNewThumbPos
= mnMaxRange
-mnVisibleSize
;
1559 if ( nNewThumbPos
< mnMinRange
)
1560 nNewThumbPos
= mnMinRange
;
1562 if ( mnThumbPos
!= nNewThumbPos
)
1564 mnThumbPos
= nNewThumbPos
;
1565 StateChanged( STATE_CHANGE_DATA
);
1569 // -----------------------------------------------------------------------
1571 void ScrollBar::SetVisibleSize( long nNewSize
)
1573 if ( mnVisibleSize
!= nNewSize
)
1575 mnVisibleSize
= nNewSize
;
1578 if ( mnThumbPos
> mnMaxRange
-mnVisibleSize
)
1579 mnThumbPos
= mnMaxRange
-mnVisibleSize
;
1580 if ( mnThumbPos
< mnMinRange
)
1581 mnThumbPos
= mnMinRange
;
1582 StateChanged( STATE_CHANGE_DATA
);
1586 // =======================================================================
1588 void ScrollBarBox::ImplInit( Window
* pParent
, WinBits nStyle
)
1590 Window::ImplInit( pParent
, nStyle
, NULL
);
1592 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
1593 long nScrollSize
= rStyleSettings
.GetScrollBarSize();
1594 SetSizePixel( Size( nScrollSize
, nScrollSize
) );
1598 // -----------------------------------------------------------------------
1600 ScrollBarBox::ScrollBarBox( Window
* pParent
, WinBits nStyle
) :
1601 Window( WINDOW_SCROLLBARBOX
)
1603 ImplInit( pParent
, nStyle
);
1606 // -----------------------------------------------------------------------
1608 ScrollBarBox::ScrollBarBox( Window
* pParent
, const ResId
& rResId
) :
1609 Window( WINDOW_SCROLLBARBOX
)
1611 rResId
.SetRT( RSC_SCROLLBAR
);
1612 ImplInit( pParent
, ImplInitRes( rResId
) );
1613 ImplLoadRes( rResId
);
1616 // -----------------------------------------------------------------------
1618 void ScrollBarBox::ImplInitSettings()
1620 // Hack, damit man auch DockingWindows ohne Hintergrund bauen kann
1621 // und noch nicht alles umgestellt ist
1622 if ( IsBackground() )
1625 if ( IsControlBackground() )
1626 aColor
= GetControlBackground();
1628 aColor
= GetSettings().GetStyleSettings().GetFaceColor();
1629 SetBackground( aColor
);
1633 // -----------------------------------------------------------------------
1635 void ScrollBarBox::StateChanged( StateChangedType nType
)
1637 Window::StateChanged( nType
);
1639 if ( nType
== STATE_CHANGE_CONTROLBACKGROUND
)
1646 // -----------------------------------------------------------------------
1648 void ScrollBarBox::DataChanged( const DataChangedEvent
& rDCEvt
)
1650 Window::DataChanged( rDCEvt
);
1652 if ( (rDCEvt
.GetType() == DATACHANGED_SETTINGS
) &&
1653 (rDCEvt
.GetFlags() & SETTINGS_STYLE
) )