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 .
20 #include <vcl/event.hxx>
21 #include <vcl/decoview.hxx>
22 #include <vcl/scrbar.hxx>
23 #include <vcl/timer.hxx>
24 #include <vcl/settings.hxx>
25 #include <vcl/vclevent.hxx>
27 #include <sal/log.hxx>
30 HACK: for scrollbars in case of thumb rect, page up and page down rect we
31 abuse the HitTestNativeScrollbar interface. All theming engines but macOS
32 are actually able to draw the thumb according to our internal representation.
33 However macOS draws a little outside. The canonical way would be to enhance the
34 HitTestNativeScrollbar passing a ScrollbarValue additionally so all necessary
35 information is available in the call.
37 However since there is only this one small exception we will deviate a little and
38 instead pass the respective rect as control region to allow for a small correction.
40 So all places using HitTestNativeScrollbar on ControlPart::ThumbHorz, ControlPart::ThumbVert,
41 ControlPart::TrackHorzLeft, ControlPart::TrackHorzRight, ControlPart::TrackVertUpper, ControlPart::TrackVertLower
42 do not use the control rectangle as region but the actual part rectangle, making
43 only small deviations feasible.
46 #include "thumbpos.hxx"
48 #define SCRBAR_DRAW_BTN1 (sal_uInt16(0x0001))
49 #define SCRBAR_DRAW_BTN2 (sal_uInt16(0x0002))
50 #define SCRBAR_DRAW_PAGE1 (sal_uInt16(0x0004))
51 #define SCRBAR_DRAW_PAGE2 (sal_uInt16(0x0008))
52 #define SCRBAR_DRAW_THUMB (sal_uInt16(0x0010))
53 #define SCRBAR_DRAW_BACKGROUND (sal_uInt16(0x0020))
55 #define SCRBAR_STATE_BTN1_DOWN (sal_uInt16(0x0001))
56 #define SCRBAR_STATE_BTN1_DISABLE (sal_uInt16(0x0002))
57 #define SCRBAR_STATE_BTN2_DOWN (sal_uInt16(0x0004))
58 #define SCRBAR_STATE_BTN2_DISABLE (sal_uInt16(0x0008))
59 #define SCRBAR_STATE_PAGE1_DOWN (sal_uInt16(0x0010))
60 #define SCRBAR_STATE_PAGE2_DOWN (sal_uInt16(0x0020))
61 #define SCRBAR_STATE_THUMB_DOWN (sal_uInt16(0x0040))
63 #define SCRBAR_VIEW_STYLE (WB_3DLOOK | WB_HORZ | WB_VERT)
65 struct ImplScrollBarData
67 AutoTimer maTimer
; // Timer
71 void ScrollBar::ImplInit( vcl::Window
* pParent
, WinBits nStyle
)
85 meScrollType
= ScrollType::DontKnow
;
89 ImplInitStyle( nStyle
);
90 Control::ImplInit( pParent
, nStyle
, nullptr );
92 long nScrollSize
= GetSettings().GetStyleSettings().GetScrollBarSize();
93 SetSizePixel( Size( nScrollSize
, nScrollSize
) );
96 void ScrollBar::ImplInitStyle( WinBits nStyle
)
98 if ( nStyle
& WB_DRAG
)
101 mbFullDrag
= bool(GetSettings().GetStyleSettings().GetDragFullOptions() & DragFullOptions::Scroll
);
104 ScrollBar::ScrollBar( vcl::Window
* pParent
, WinBits nStyle
) :
105 Control( WindowType::SCROLLBAR
)
107 ImplInit( pParent
, nStyle
);
110 ScrollBar::~ScrollBar()
115 void ScrollBar::dispose()
121 void ScrollBar::ImplUpdateRects( bool bUpdate
)
123 mnStateFlags
&= ~SCRBAR_STATE_BTN1_DISABLE
;
124 mnStateFlags
&= ~SCRBAR_STATE_BTN2_DISABLE
;
126 if ( mnThumbPixRange
)
128 if ( GetStyle() & WB_HORZ
)
130 maThumbRect
.SetLeft( maTrackRect
.Left()+mnThumbPixPos
);
131 maThumbRect
.SetRight( maThumbRect
.Left()+mnThumbPixSize
-1 );
132 if ( !mnThumbPixPos
)
133 maPage1Rect
.SetWidthEmpty();
135 maPage1Rect
.SetRight( maThumbRect
.Left()-1 );
136 if ( mnThumbPixPos
>= (mnThumbPixRange
-mnThumbPixSize
) )
137 maPage2Rect
.SetWidthEmpty();
140 maPage2Rect
.SetLeft( maThumbRect
.Right()+1 );
141 maPage2Rect
.SetRight( maTrackRect
.Right() );
146 maThumbRect
.SetTop( maTrackRect
.Top()+mnThumbPixPos
);
147 maThumbRect
.SetBottom( maThumbRect
.Top()+mnThumbPixSize
-1 );
148 if ( !mnThumbPixPos
)
149 maPage1Rect
.SetHeightEmpty();
151 maPage1Rect
.SetBottom( maThumbRect
.Top()-1 );
152 if ( mnThumbPixPos
>= (mnThumbPixRange
-mnThumbPixSize
) )
153 maPage2Rect
.SetHeightEmpty();
156 maPage2Rect
.SetTop( maThumbRect
.Bottom()+1 );
157 maPage2Rect
.SetBottom( maTrackRect
.Bottom() );
163 if ( GetStyle() & WB_HORZ
)
165 const long nSpace
= maTrackRect
.Right() - maTrackRect
.Left();
168 maPage1Rect
.SetLeft( maTrackRect
.Left() );
169 maPage1Rect
.SetRight( maTrackRect
.Left() + (nSpace
/2) );
170 maPage2Rect
.SetLeft( maPage1Rect
.Right() + 1 );
171 maPage2Rect
.SetRight( maTrackRect
.Right() );
176 const long nSpace
= maTrackRect
.Bottom() - maTrackRect
.Top();
179 maPage1Rect
.SetTop( maTrackRect
.Top() );
180 maPage1Rect
.SetBottom( maTrackRect
.Top() + (nSpace
/2) );
181 maPage2Rect
.SetTop( maPage1Rect
.Bottom() + 1 );
182 maPage2Rect
.SetBottom( maTrackRect
.Bottom() );
187 if( !IsNativeControlSupported(ControlType::Scrollbar
, ControlPart::Entire
) )
189 // disable scrollbar buttons only in VCL's own 'theme'
190 // as it is uncommon on other platforms
191 if ( mnThumbPos
== mnMinRange
)
192 mnStateFlags
|= SCRBAR_STATE_BTN1_DISABLE
;
193 if ( mnThumbPos
>= (mnMaxRange
-mnVisibleSize
) )
194 mnStateFlags
|= SCRBAR_STATE_BTN2_DISABLE
;
203 long ScrollBar::ImplCalcThumbPos( long nPixPos
)
205 // Calculate position
207 nCalcThumbPos
= ImplMulDiv( nPixPos
, mnMaxRange
-mnVisibleSize
-mnMinRange
,
208 mnThumbPixRange
-mnThumbPixSize
);
209 nCalcThumbPos
+= mnMinRange
;
210 return nCalcThumbPos
;
213 long ScrollBar::ImplCalcThumbPosPix( long nPos
)
217 // Calculate position
218 nCalcThumbPos
= ImplMulDiv( nPos
-mnMinRange
, mnThumbPixRange
-mnThumbPixSize
,
219 mnMaxRange
-mnVisibleSize
-mnMinRange
);
221 // At the start and end of the ScrollBar, we try to show the display correctly
222 if ( !nCalcThumbPos
&& (mnThumbPos
> mnMinRange
) )
224 if ( nCalcThumbPos
&&
225 ((nCalcThumbPos
+mnThumbPixSize
) >= mnThumbPixRange
) &&
226 (mnThumbPos
< (mnMaxRange
-mnVisibleSize
)) )
229 return nCalcThumbPos
;
232 void ScrollBar::ImplCalc( bool bUpdate
)
234 const Size aSize
= GetOutputSizePixel();
235 const long nMinThumbSize
= GetSettings().GetStyleSettings().GetMinThumbSize();
239 Size aOldSize
= getCurrentCalcSize();
241 const tools::Rectangle
aControlRegion( Point(0,0), aSize
);
242 tools::Rectangle aBtn1Region
, aBtn2Region
, aTrackRegion
, aBoundingRegion
;
244 // reset rectangles to empty *and* (0,0) position
245 maThumbRect
= tools::Rectangle();
246 maPage1Rect
= tools::Rectangle();
247 maPage2Rect
= tools::Rectangle();
249 if ( GetStyle() & WB_HORZ
)
251 if ( GetNativeControlRegion( ControlType::Scrollbar
, IsRTLEnabled()? ControlPart::ButtonRight
: ControlPart::ButtonLeft
,
252 aControlRegion
, ControlState::NONE
, ImplControlValue(), aBoundingRegion
, aBtn1Region
) &&
253 GetNativeControlRegion( ControlType::Scrollbar
, IsRTLEnabled()? ControlPart::ButtonLeft
: ControlPart::ButtonRight
,
254 aControlRegion
, ControlState::NONE
, ImplControlValue(), aBoundingRegion
, aBtn2Region
) )
256 maBtn1Rect
= aBtn1Region
;
257 maBtn2Rect
= aBtn2Region
;
261 Size
aBtnSize( aSize
.Height(), aSize
.Height() );
262 maBtn2Rect
.SetTop( maBtn1Rect
.Top() );
263 maBtn2Rect
.SetLeft( aSize
.Width()-aSize
.Height() );
264 maBtn1Rect
.SetSize( aBtnSize
);
265 maBtn2Rect
.SetSize( aBtnSize
);
268 if ( GetNativeControlRegion( ControlType::Scrollbar
, ControlPart::TrackHorzArea
,
269 aControlRegion
, ControlState::NONE
, ImplControlValue(), aBoundingRegion
, aTrackRegion
) )
270 maTrackRect
= aTrackRegion
;
272 maTrackRect
= tools::Rectangle( maBtn1Rect
.TopRight(), maBtn2Rect
.BottomLeft() );
274 // Check if available space is big enough for thumb ( min thumb size = ScrBar width/height )
275 mnThumbPixRange
= maTrackRect
.Right() - maTrackRect
.Left();
276 if( mnThumbPixRange
> 0 )
278 maPage1Rect
.SetLeft( maTrackRect
.Left() );
279 maPage1Rect
.SetBottom( maTrackRect
.Bottom() );
280 maPage2Rect
.SetBottom (maTrackRect
.Bottom() );
281 maThumbRect
.SetBottom( maTrackRect
.Bottom() );
288 if ( GetNativeControlRegion( ControlType::Scrollbar
, ControlPart::ButtonUp
,
289 aControlRegion
, ControlState::NONE
, ImplControlValue(), aBoundingRegion
, aBtn1Region
) &&
290 GetNativeControlRegion( ControlType::Scrollbar
, ControlPart::ButtonDown
,
291 aControlRegion
, ControlState::NONE
, ImplControlValue(), aBoundingRegion
, aBtn2Region
) )
293 maBtn1Rect
= aBtn1Region
;
294 maBtn2Rect
= aBtn2Region
;
298 const Size
aBtnSize( aSize
.Width(), aSize
.Width() );
299 maBtn2Rect
.SetLeft( maBtn1Rect
.Left() );
300 maBtn2Rect
.SetTop( aSize
.Height()-aSize
.Width() );
301 maBtn1Rect
.SetSize( aBtnSize
);
302 maBtn2Rect
.SetSize( aBtnSize
);
305 if ( GetNativeControlRegion( ControlType::Scrollbar
, ControlPart::TrackVertArea
,
306 aControlRegion
, ControlState::NONE
, ImplControlValue(), aBoundingRegion
, aTrackRegion
) )
307 maTrackRect
= aTrackRegion
;
309 maTrackRect
= tools::Rectangle( maBtn1Rect
.BottomLeft()+Point(0,1), maBtn2Rect
.TopRight() );
311 // Check if available space is big enough for thumb
312 mnThumbPixRange
= maTrackRect
.Bottom() - maTrackRect
.Top();
313 if( mnThumbPixRange
> 0 )
315 maPage1Rect
.SetTop( maTrackRect
.Top() );
316 maPage1Rect
.SetRight( maTrackRect
.Right() );
317 maPage2Rect
.SetRight( maTrackRect
.Right() );
318 maThumbRect
.SetRight( maTrackRect
.Right() );
326 Size aNewSize
= getCurrentCalcSize();
327 if (aOldSize
!= aNewSize
)
333 if ( mnThumbPixRange
)
336 if ( (mnVisibleSize
>= (mnMaxRange
-mnMinRange
)) ||
337 ((mnMaxRange
-mnMinRange
) <= 0) )
339 mnThumbPos
= mnMinRange
;
341 mnThumbPixSize
= mnThumbPixRange
;
346 mnThumbPixSize
= ImplMulDiv( mnThumbPixRange
, mnVisibleSize
, mnMaxRange
-mnMinRange
);
349 if ( GetStyle() & WB_HORZ
)
350 mnThumbPixSize
= maThumbRect
.GetWidth();
352 mnThumbPixSize
= maThumbRect
.GetHeight();
354 if ( mnThumbPixSize
< nMinThumbSize
)
355 mnThumbPixSize
= nMinThumbSize
;
356 if ( mnThumbPixSize
> mnThumbPixRange
)
357 mnThumbPixSize
= mnThumbPixRange
;
358 mnThumbPixPos
= ImplCalcThumbPosPix( mnThumbPos
);
362 // If we're ought to output again and we have been triggered
363 // a Paint event via an Action, we don't output directly,
364 // but invalidate everything
365 if ( bUpdate
&& HasPaintEvent() )
370 ImplUpdateRects( bUpdate
);
373 void ScrollBar::Draw( OutputDevice
* pDev
, const Point
& rPos
, const Size
& /* rSize */, DrawFlags nFlags
)
375 Point aPos
= pDev
->LogicToPixel( rPos
);
379 if ( !(nFlags
& DrawFlags::Mono
) )
381 // DecoView uses the FaceColor...
382 AllSettings aSettings
= pDev
->GetSettings();
383 StyleSettings aStyleSettings
= aSettings
.GetStyleSettings();
384 if ( IsControlBackground() )
385 aStyleSettings
.SetFaceColor( GetControlBackground() );
387 aStyleSettings
.SetFaceColor( GetSettings().GetStyleSettings().GetFaceColor() );
389 aSettings
.SetStyleSettings( aStyleSettings
);
390 pDev
->SetSettings( aSettings
);
394 // - calculate the size of the rects
395 // - because this is zero-based add the correct offset
397 // - force recalculate
415 bool ScrollBar::ImplDrawNative(vcl::RenderContext
& rRenderContext
, sal_uInt16 nDrawFlags
)
417 ScrollbarValue scrValue
;
419 bool bNativeOK
= rRenderContext
.IsNativeControlSupported(ControlType::Scrollbar
, ControlPart::Entire
);
423 bool bHorz
= (GetStyle() & WB_HORZ
) != 0;
425 // Draw the entire background if the control supports it
426 if (rRenderContext
.IsNativeControlSupported(ControlType::Scrollbar
, bHorz
? ControlPart::DrawBackgroundHorz
: ControlPart::DrawBackgroundVert
))
428 ControlState nState
= (IsEnabled() ? ControlState::ENABLED
: ControlState::NONE
)
429 | (HasFocus() ? ControlState::FOCUSED
: ControlState::NONE
);
431 scrValue
.mnMin
= mnMinRange
;
432 scrValue
.mnMax
= mnMaxRange
;
433 scrValue
.mnCur
= mnThumbPos
;
434 scrValue
.mnVisibleSize
= mnVisibleSize
;
435 scrValue
.maThumbRect
= maThumbRect
;
436 scrValue
.maButton1Rect
= maBtn1Rect
;
437 scrValue
.maButton2Rect
= maBtn2Rect
;
438 scrValue
.mnButton1State
= ((mnStateFlags
& SCRBAR_STATE_BTN1_DOWN
) ? ControlState::PRESSED
: ControlState::NONE
) |
439 ((!(mnStateFlags
& SCRBAR_STATE_BTN1_DISABLE
)) ? ControlState::ENABLED
: ControlState::NONE
);
440 scrValue
.mnButton2State
= ((mnStateFlags
& SCRBAR_STATE_BTN2_DOWN
) ? ControlState::PRESSED
: ControlState::NONE
) |
441 ((!(mnStateFlags
& SCRBAR_STATE_BTN2_DISABLE
)) ? ControlState::ENABLED
: ControlState::NONE
);
442 scrValue
.mnThumbState
= nState
| ((mnStateFlags
& SCRBAR_STATE_THUMB_DOWN
) ? ControlState::PRESSED
: ControlState::NONE
);
446 tools::Rectangle
* pRect
= ImplFindPartRect(GetPointerPosPixel());
449 if (pRect
== &maThumbRect
)
450 scrValue
.mnThumbState
|= ControlState::ROLLOVER
;
451 else if (pRect
== &maBtn1Rect
)
452 scrValue
.mnButton1State
|= ControlState::ROLLOVER
;
453 else if (pRect
== &maBtn2Rect
)
454 scrValue
.mnButton2State
|= ControlState::ROLLOVER
;
458 tools::Rectangle aCtrlRegion
;
459 aCtrlRegion
.Union(maBtn1Rect
);
460 aCtrlRegion
.Union(maBtn2Rect
);
461 aCtrlRegion
.Union(maPage1Rect
);
462 aCtrlRegion
.Union(maPage2Rect
);
463 aCtrlRegion
.Union(maThumbRect
);
465 tools::Rectangle
aRequestedRegion(Point(0,0), GetOutputSizePixel());
466 // if the actual native control region is smaller then the region that
467 // we requested the control to draw in, then draw a background rectangle
468 // to avoid drawing artifacts in the uncovered region
469 if (aCtrlRegion
.GetWidth() < aRequestedRegion
.GetWidth() ||
470 aCtrlRegion
.GetHeight() < aRequestedRegion
.GetHeight())
472 Color aFaceColor
= rRenderContext
.GetSettings().GetStyleSettings().GetFaceColor();
473 rRenderContext
.SetFillColor(aFaceColor
);
474 rRenderContext
.SetLineColor(aFaceColor
);
475 rRenderContext
.DrawRect(aRequestedRegion
);
478 bNativeOK
= rRenderContext
.DrawNativeControl(ControlType::Scrollbar
, (bHorz
? ControlPart::DrawBackgroundHorz
: ControlPart::DrawBackgroundVert
),
479 aCtrlRegion
, nState
, scrValue
, OUString());
483 if ((nDrawFlags
& SCRBAR_DRAW_PAGE1
) || (nDrawFlags
& SCRBAR_DRAW_PAGE2
))
485 ControlPart part1
= bHorz
? ControlPart::TrackHorzLeft
: ControlPart::TrackVertUpper
;
486 ControlPart part2
= bHorz
? ControlPart::TrackHorzRight
: ControlPart::TrackVertLower
;
487 tools::Rectangle
aCtrlRegion1(maPage1Rect
);
488 tools::Rectangle
aCtrlRegion2(maPage2Rect
);
489 ControlState nState1
= (IsEnabled() ? ControlState::ENABLED
: ControlState::NONE
)
490 | (HasFocus() ? ControlState::FOCUSED
: ControlState::NONE
);
491 ControlState nState2
= nState1
;
493 nState1
|= ((mnStateFlags
& SCRBAR_STATE_PAGE1_DOWN
) ? ControlState::PRESSED
: ControlState::NONE
);
494 nState2
|= ((mnStateFlags
& SCRBAR_STATE_PAGE2_DOWN
) ? ControlState::PRESSED
: ControlState::NONE
);
498 tools::Rectangle
* pRect
= ImplFindPartRect(GetPointerPosPixel());
501 if (pRect
== &maPage1Rect
)
502 nState1
|= ControlState::ROLLOVER
;
503 else if (pRect
== &maPage2Rect
)
504 nState2
|= ControlState::ROLLOVER
;
508 if (nDrawFlags
& SCRBAR_DRAW_PAGE1
)
509 bNativeOK
= rRenderContext
.DrawNativeControl(ControlType::Scrollbar
, part1
, aCtrlRegion1
, nState1
, scrValue
, OUString());
511 if (nDrawFlags
& SCRBAR_DRAW_PAGE2
)
512 bNativeOK
= rRenderContext
.DrawNativeControl(ControlType::Scrollbar
, part2
, aCtrlRegion2
, nState2
, scrValue
, OUString());
514 if ((nDrawFlags
& SCRBAR_DRAW_BTN1
) || (nDrawFlags
& SCRBAR_DRAW_BTN2
))
516 ControlPart part1
= bHorz
? ControlPart::ButtonLeft
: ControlPart::ButtonUp
;
517 ControlPart part2
= bHorz
? ControlPart::ButtonRight
: ControlPart::ButtonDown
;
518 tools::Rectangle
aCtrlRegion1(maBtn1Rect
);
519 tools::Rectangle
aCtrlRegion2(maBtn2Rect
);
520 ControlState nState1
= HasFocus() ? ControlState::FOCUSED
: ControlState::NONE
;
521 ControlState nState2
= nState1
;
523 if (!Window::IsEnabled() || !IsEnabled())
524 nState1
= (nState2
&= ~ControlState::ENABLED
);
526 nState1
= (nState2
|= ControlState::ENABLED
);
528 nState1
|= ((mnStateFlags
& SCRBAR_STATE_BTN1_DOWN
) ? ControlState::PRESSED
: ControlState::NONE
);
529 nState2
|= ((mnStateFlags
& SCRBAR_STATE_BTN2_DOWN
) ? ControlState::PRESSED
: ControlState::NONE
);
531 if (mnStateFlags
& SCRBAR_STATE_BTN1_DISABLE
)
532 nState1
&= ~ControlState::ENABLED
;
533 if (mnStateFlags
& SCRBAR_STATE_BTN2_DISABLE
)
534 nState2
&= ~ControlState::ENABLED
;
538 tools::Rectangle
* pRect
= ImplFindPartRect(GetPointerPosPixel());
541 if (pRect
== &maBtn1Rect
)
542 nState1
|= ControlState::ROLLOVER
;
543 else if (pRect
== &maBtn2Rect
)
544 nState2
|= ControlState::ROLLOVER
;
548 if (nDrawFlags
& SCRBAR_DRAW_BTN1
)
549 bNativeOK
= rRenderContext
.DrawNativeControl(ControlType::Scrollbar
, part1
, aCtrlRegion1
, nState1
, scrValue
, OUString());
551 if (nDrawFlags
& SCRBAR_DRAW_BTN2
)
552 bNativeOK
= rRenderContext
.DrawNativeControl(ControlType::Scrollbar
, part2
, aCtrlRegion2
, nState2
, scrValue
, OUString());
554 if ((nDrawFlags
& SCRBAR_DRAW_THUMB
) && !maThumbRect
.IsEmpty())
556 ControlState nState
= IsEnabled() ? ControlState::ENABLED
: ControlState::NONE
;
557 tools::Rectangle
aCtrlRegion(maThumbRect
);
559 if (mnStateFlags
& SCRBAR_STATE_THUMB_DOWN
)
560 nState
|= ControlState::PRESSED
;
563 nState
|= ControlState::FOCUSED
;
567 tools::Rectangle
* pRect
= ImplFindPartRect(GetPointerPosPixel());
568 if (pRect
&& pRect
== &maThumbRect
)
569 nState
|= ControlState::ROLLOVER
;
572 bNativeOK
= rRenderContext
.DrawNativeControl(ControlType::Scrollbar
, (bHorz
? ControlPart::ThumbHorz
: ControlPart::ThumbVert
),
573 aCtrlRegion
, nState
, scrValue
, OUString());
579 void ScrollBar::ImplDraw(vcl::RenderContext
& rRenderContext
)
581 DecorationView
aDecoView(&rRenderContext
);
582 tools::Rectangle aTempRect
;
583 DrawButtonFlags nStyle
;
584 const StyleSettings
& rStyleSettings
= rRenderContext
.GetSettings().GetStyleSettings();
585 SymbolType eSymbolType
;
586 bool bEnabled
= IsEnabled();
588 // Finish some open calculations (if any)
592 //vcl::Window *pWin = NULL;
593 //if (rRenderContext.GetOutDevType() == OUTDEV_WINDOW)
594 // pWin = static_cast<vcl::Window*>(&rRenderContext);
596 // Draw the entire control if the native theme engine needs it
597 if (rRenderContext
.IsNativeControlSupported(ControlType::Scrollbar
, ControlPart::DrawBackgroundHorz
))
599 ImplDrawNative(rRenderContext
, SCRBAR_DRAW_BACKGROUND
);
603 if (!ImplDrawNative(rRenderContext
, SCRBAR_DRAW_BTN1
))
605 nStyle
= DrawButtonFlags::NoLightBorder
;
606 if (mnStateFlags
& SCRBAR_STATE_BTN1_DOWN
)
607 nStyle
|= DrawButtonFlags::Pressed
;
608 aTempRect
= aDecoView
.DrawButton( PixelToLogic(maBtn1Rect
), nStyle
);
609 ImplCalcSymbolRect( aTempRect
);
610 DrawSymbolFlags nSymbolStyle
= DrawSymbolFlags::NONE
;
611 if ((mnStateFlags
& SCRBAR_STATE_BTN1_DISABLE
) || !bEnabled
)
612 nSymbolStyle
|= DrawSymbolFlags::Disable
;
613 if (GetStyle() & WB_HORZ
)
614 eSymbolType
= SymbolType::SPIN_LEFT
;
616 eSymbolType
= SymbolType::SPIN_UP
;
617 aDecoView
.DrawSymbol(aTempRect
, eSymbolType
, rStyleSettings
.GetButtonTextColor(), nSymbolStyle
);
620 if (!ImplDrawNative(rRenderContext
, SCRBAR_DRAW_BTN2
))
622 nStyle
= DrawButtonFlags::NoLightBorder
;
623 if (mnStateFlags
& SCRBAR_STATE_BTN2_DOWN
)
624 nStyle
|= DrawButtonFlags::Pressed
;
625 aTempRect
= aDecoView
.DrawButton(PixelToLogic(maBtn2Rect
), nStyle
);
626 ImplCalcSymbolRect(aTempRect
);
627 DrawSymbolFlags nSymbolStyle
= DrawSymbolFlags::NONE
;
628 if ((mnStateFlags
& SCRBAR_STATE_BTN2_DISABLE
) || !bEnabled
)
629 nSymbolStyle
|= DrawSymbolFlags::Disable
;
630 if (GetStyle() & WB_HORZ
)
631 eSymbolType
= SymbolType::SPIN_RIGHT
;
633 eSymbolType
= SymbolType::SPIN_DOWN
;
634 aDecoView
.DrawSymbol(aTempRect
, eSymbolType
, rStyleSettings
.GetButtonTextColor(), nSymbolStyle
);
637 rRenderContext
.SetLineColor();
639 if (!ImplDrawNative(rRenderContext
, SCRBAR_DRAW_THUMB
))
641 if (!maThumbRect
.IsEmpty())
645 nStyle
= DrawButtonFlags::NoLightBorder
;
646 aTempRect
= aDecoView
.DrawButton(PixelToLogic(maThumbRect
), nStyle
);
650 rRenderContext
.SetFillColor(rStyleSettings
.GetCheckedColor());
651 rRenderContext
.DrawRect(PixelToLogic(maThumbRect
));
656 if (!ImplDrawNative(rRenderContext
, SCRBAR_DRAW_PAGE1
))
658 if (mnStateFlags
& SCRBAR_STATE_PAGE1_DOWN
)
659 rRenderContext
.SetFillColor(rStyleSettings
.GetShadowColor());
661 rRenderContext
.SetFillColor(rStyleSettings
.GetCheckedColor());
662 rRenderContext
.DrawRect(PixelToLogic(maPage1Rect
));
664 if (!ImplDrawNative(rRenderContext
, SCRBAR_DRAW_PAGE2
))
666 if (mnStateFlags
& SCRBAR_STATE_PAGE2_DOWN
)
667 rRenderContext
.SetFillColor(rStyleSettings
.GetShadowColor());
669 rRenderContext
.SetFillColor(rStyleSettings
.GetCheckedColor());
670 rRenderContext
.DrawRect(PixelToLogic(maPage2Rect
));
674 long ScrollBar::ImplScroll( long nNewPos
, bool bCallEndScroll
)
676 long nOldPos
= mnThumbPos
;
677 SetThumbPos( nNewPos
);
678 long nDelta
= mnThumbPos
-nOldPos
;
683 if ( bCallEndScroll
)
690 long ScrollBar::ImplDoAction( bool bCallEndScroll
)
694 switch ( meScrollType
)
696 case ScrollType::LineUp
:
697 nDelta
= ImplScroll( mnThumbPos
-mnLineSize
, bCallEndScroll
);
700 case ScrollType::LineDown
:
701 nDelta
= ImplScroll( mnThumbPos
+mnLineSize
, bCallEndScroll
);
704 case ScrollType::PageUp
:
705 nDelta
= ImplScroll( mnThumbPos
-mnPageSize
, bCallEndScroll
);
708 case ScrollType::PageDown
:
709 nDelta
= ImplScroll( mnThumbPos
+mnPageSize
, bCallEndScroll
);
718 void ScrollBar::ImplDoMouseAction( const Point
& rMousePos
, bool bCallAction
)
720 sal_uInt16 nOldStateFlags
= mnStateFlags
;
721 bool bAction
= false;
722 bool bHorizontal
= ( GetStyle() & WB_HORZ
) != 0;
723 bool bIsInside
= false;
725 Point
aPoint( 0, 0 );
726 tools::Rectangle
aControlRegion( aPoint
, GetOutputSizePixel() );
728 switch ( meScrollType
)
730 case ScrollType::LineUp
:
731 if ( HitTestNativeScrollbar( bHorizontal
? (IsRTLEnabled()? ControlPart::ButtonRight
: ControlPart::ButtonLeft
): ControlPart::ButtonUp
,
732 aControlRegion
, rMousePos
, bIsInside
)?
734 maBtn1Rect
.IsInside( rMousePos
) )
736 bAction
= bCallAction
;
737 mnStateFlags
|= SCRBAR_STATE_BTN1_DOWN
;
740 mnStateFlags
&= ~SCRBAR_STATE_BTN1_DOWN
;
743 case ScrollType::LineDown
:
744 if ( HitTestNativeScrollbar( bHorizontal
? (IsRTLEnabled()? ControlPart::ButtonLeft
: ControlPart::ButtonRight
): ControlPart::ButtonDown
,
745 aControlRegion
, rMousePos
, bIsInside
)?
747 maBtn2Rect
.IsInside( rMousePos
) )
749 bAction
= bCallAction
;
750 mnStateFlags
|= SCRBAR_STATE_BTN2_DOWN
;
753 mnStateFlags
&= ~SCRBAR_STATE_BTN2_DOWN
;
756 case ScrollType::PageUp
:
757 // HitTestNativeScrollbar, see remark at top of file
758 if ( HitTestNativeScrollbar( bHorizontal
? ControlPart::TrackHorzLeft
: ControlPart::TrackVertUpper
,
759 maPage1Rect
, rMousePos
, bIsInside
)?
761 maPage1Rect
.IsInside( rMousePos
) )
763 bAction
= bCallAction
;
764 mnStateFlags
|= SCRBAR_STATE_PAGE1_DOWN
;
767 mnStateFlags
&= ~SCRBAR_STATE_PAGE1_DOWN
;
770 case ScrollType::PageDown
:
771 // HitTestNativeScrollbar, see remark at top of file
772 if ( HitTestNativeScrollbar( bHorizontal
? ControlPart::TrackHorzRight
: ControlPart::TrackVertLower
,
773 maPage2Rect
, rMousePos
, bIsInside
)?
775 maPage2Rect
.IsInside( rMousePos
) )
777 bAction
= bCallAction
;
778 mnStateFlags
|= SCRBAR_STATE_PAGE2_DOWN
;
781 mnStateFlags
&= ~SCRBAR_STATE_PAGE2_DOWN
;
787 if ( nOldStateFlags
!= mnStateFlags
)
790 ImplDoAction( false );
793 void ScrollBar::ImplDragThumb( const Point
& rMousePos
)
796 if ( GetStyle() & WB_HORZ
)
797 nMovePix
= rMousePos
.X()-(maThumbRect
.Left()+mnMouseOff
);
799 nMovePix
= rMousePos
.Y()-(maThumbRect
.Top()+mnMouseOff
);
801 // Move thumb if necessary
804 mnThumbPixPos
+= nMovePix
;
805 if ( mnThumbPixPos
< 0 )
807 if ( mnThumbPixPos
> (mnThumbPixRange
-mnThumbPixSize
) )
808 mnThumbPixPos
= mnThumbPixRange
-mnThumbPixSize
;
809 long nOldPos
= mnThumbPos
;
810 mnThumbPos
= ImplCalcThumbPos( mnThumbPixPos
);
812 if ( mbFullDrag
&& (nOldPos
!= mnThumbPos
) )
814 // When dragging in windows the repaint request gets starved so dragging
815 // the scrollbar feels slower than it actually is. Let's force an immediate
816 // repaint of the scrollbar.
817 if (SupportsDoubleBuffering())
825 mnDelta
= mnThumbPos
-nOldPos
;
832 void ScrollBar::MouseButtonDown( const MouseEvent
& rMEvt
)
834 bool bPrimaryWarps
= GetSettings().GetStyleSettings().GetPrimaryButtonWarpsSlider();
835 bool bWarp
= bPrimaryWarps
? rMEvt
.IsLeft() : rMEvt
.IsMiddle();
836 bool bPrimaryWarping
= bWarp
&& rMEvt
.IsLeft();
837 bool bPage
= bPrimaryWarps
? rMEvt
.IsRight() : rMEvt
.IsLeft();
839 if (!rMEvt
.IsLeft() && !rMEvt
.IsMiddle() && !rMEvt
.IsRight())
843 if (!IsMapModeEnabled() && GetMapMode().GetMapUnit() == MapUnit::MapTwip
)
845 // rMEvt coordinates are in twips.
846 Push(PushFlags::MAPMODE
);
848 MapMode aMapMode
= GetMapMode();
849 aMapMode
.SetOrigin(Point(0, 0));
850 SetMapMode(aMapMode
);
851 aPosPixel
= LogicToPixel(rMEvt
.GetPosPixel());
854 const Point
& rMousePos
= (GetMapMode().GetMapUnit() != MapUnit::MapTwip
? rMEvt
.GetPosPixel() : aPosPixel
);
855 StartTrackingFlags nTrackFlags
= StartTrackingFlags::NONE
;
856 bool bHorizontal
= ( GetStyle() & WB_HORZ
) != 0;
857 bool bIsInside
= false;
858 bool bDragToMouse
= false;
860 Point
aPoint( 0, 0 );
861 tools::Rectangle
aControlRegion( aPoint
, GetOutputSizePixel() );
863 if ( HitTestNativeScrollbar( bHorizontal
? (IsRTLEnabled()? ControlPart::ButtonRight
: ControlPart::ButtonLeft
): ControlPart::ButtonUp
,
864 aControlRegion
, rMousePos
, bIsInside
)?
866 maBtn1Rect
.IsInside( rMousePos
) )
868 if (rMEvt
.IsLeft() && !(mnStateFlags
& SCRBAR_STATE_BTN1_DISABLE
) )
870 nTrackFlags
= StartTrackingFlags::ButtonRepeat
;
871 meScrollType
= ScrollType::LineUp
;
874 else if ( HitTestNativeScrollbar( bHorizontal
? (IsRTLEnabled()? ControlPart::ButtonLeft
: ControlPart::ButtonRight
): ControlPart::ButtonDown
,
875 aControlRegion
, rMousePos
, bIsInside
)?
877 maBtn2Rect
.IsInside( rMousePos
) )
879 if (rMEvt
.IsLeft() && !(mnStateFlags
& SCRBAR_STATE_BTN2_DISABLE
) )
881 nTrackFlags
= StartTrackingFlags::ButtonRepeat
;
882 meScrollType
= ScrollType::LineDown
;
887 bool bThumbHit
= HitTestNativeScrollbar( bHorizontal
? ControlPart::ThumbHorz
: ControlPart::ThumbVert
,
888 maThumbRect
, rMousePos
, bIsInside
)
889 ? bIsInside
: maThumbRect
.IsInside( rMousePos
);
891 bool bThumbAction
= bWarp
|| bPage
;
893 bool bDragHandling
= bWarp
|| (bThumbHit
&& bThumbAction
);
898 mpData
->mbHide
= true; // disable focus blinking
901 mnStateFlags
|= SCRBAR_DRAW_THUMB
; // paint without focus
906 if ( mnVisibleSize
< mnMaxRange
-mnMinRange
)
908 nTrackFlags
= StartTrackingFlags::NONE
;
909 meScrollType
= ScrollType::Drag
;
911 // calculate mouse offset
912 if (bWarp
&& (!bThumbHit
|| !bPrimaryWarping
))
915 if ( GetStyle() & WB_HORZ
)
916 mnMouseOff
= maThumbRect
.GetWidth()/2;
918 mnMouseOff
= maThumbRect
.GetHeight()/2;
922 if ( GetStyle() & WB_HORZ
)
923 mnMouseOff
= rMousePos
.X()-maThumbRect
.Left();
925 mnMouseOff
= rMousePos
.Y()-maThumbRect
.Top();
928 mnStateFlags
|= SCRBAR_STATE_THUMB_DOWN
;
932 else if(bPage
&& (!HitTestNativeScrollbar( bHorizontal
? ControlPart::TrackHorzArea
: ControlPart::TrackVertArea
,
933 aControlRegion
, rMousePos
, bIsInside
) ||
936 nTrackFlags
= StartTrackingFlags::ButtonRepeat
;
938 // HitTestNativeScrollbar, see remark at top of file
939 if ( HitTestNativeScrollbar( bHorizontal
? ControlPart::TrackHorzLeft
: ControlPart::TrackVertUpper
,
940 maPage1Rect
, rMousePos
, bIsInside
)?
942 maPage1Rect
.IsInside( rMousePos
) )
944 meScrollType
= ScrollType::PageUp
;
948 meScrollType
= ScrollType::PageDown
;
953 // Should we start Tracking?
954 if ( meScrollType
!= ScrollType::DontKnow
)
956 // store original position for cancel and EndScroll delta
957 mnStartPos
= mnThumbPos
;
958 // #92906# Call StartTracking() before ImplDoMouseAction(), otherwise
959 // MouseButtonUp() / EndTracking() may be called if somebody is spending
960 // a lot of time in the scroll handler
961 StartTracking( nTrackFlags
);
962 ImplDoMouseAction( rMousePos
);
965 ImplDragThumb( rMousePos
);
970 void ScrollBar::Tracking( const TrackingEvent
& rTEvt
)
972 if ( rTEvt
.IsTrackingEnded() )
974 // Restore Button and PageRect status
975 sal_uInt16 nOldStateFlags
= mnStateFlags
;
976 mnStateFlags
&= ~(SCRBAR_STATE_BTN1_DOWN
| SCRBAR_STATE_BTN2_DOWN
|
977 SCRBAR_STATE_PAGE1_DOWN
| SCRBAR_STATE_PAGE2_DOWN
|
978 SCRBAR_STATE_THUMB_DOWN
);
979 if ( nOldStateFlags
!= mnStateFlags
)
982 // Restore the old ThumbPosition when canceled
983 if ( rTEvt
.IsTrackingCanceled() )
985 long nOldPos
= mnThumbPos
;
986 SetThumbPos( mnStartPos
);
987 mnDelta
= mnThumbPos
-nOldPos
;
991 if ( meScrollType
== ScrollType::Drag
)
993 // On a SCROLLDRAG we recalculate the Thumb, so that it's back to a
994 // rounded ThumbPosition
997 if ( !mbFullDrag
&& (mnStartPos
!= mnThumbPos
) )
999 mnDelta
= mnThumbPos
-mnStartPos
;
1005 mnDelta
= mnThumbPos
-mnStartPos
;
1008 meScrollType
= ScrollType::DontKnow
;
1011 mpData
->mbHide
= false; // re-enable focus blinking
1016 if (!IsMapModeEnabled() && GetMapMode().GetMapUnit() == MapUnit::MapTwip
)
1018 // rTEvt coordinates are in twips.
1019 Push(PushFlags::MAPMODE
);
1021 MapMode aMapMode
= GetMapMode();
1022 aMapMode
.SetOrigin(Point(0, 0));
1023 SetMapMode(aMapMode
);
1024 aPosPixel
= LogicToPixel(rTEvt
.GetMouseEvent().GetPosPixel());
1027 const Point rMousePos
= (GetMapMode().GetMapUnit() != MapUnit::MapTwip
? rTEvt
.GetMouseEvent().GetPosPixel() : aPosPixel
);
1029 // Dragging is treated in a special way
1030 if ( meScrollType
== ScrollType::Drag
)
1031 ImplDragThumb( rMousePos
);
1033 ImplDoMouseAction( rMousePos
, rTEvt
.IsTrackingRepeat() );
1035 // If ScrollBar values are translated in a way that there's
1036 // nothing left to track, we cancel here
1037 if ( !IsVisible() || (mnVisibleSize
>= (mnMaxRange
-mnMinRange
)) )
1042 void ScrollBar::KeyInput( const KeyEvent
& rKEvt
)
1044 if ( !rKEvt
.GetKeyCode().GetModifier() )
1046 switch ( rKEvt
.GetKeyCode().GetCode() )
1053 DoScroll( GetRangeMax() );
1058 DoScrollAction( ScrollType::LineUp
);
1063 DoScrollAction( ScrollType::LineDown
);
1067 DoScrollAction( ScrollType::PageUp
);
1071 DoScrollAction( ScrollType::PageDown
);
1075 Control::KeyInput( rKEvt
);
1080 Control::KeyInput( rKEvt
);
1083 void ScrollBar::ApplySettings(vcl::RenderContext
& rRenderContext
)
1085 rRenderContext
.SetBackground();
1088 void ScrollBar::Paint(vcl::RenderContext
& rRenderContext
, const tools::Rectangle
&)
1090 ImplDraw(rRenderContext
);
1093 void ScrollBar::Move()
1097 if (IsReallyVisible())
1102 void ScrollBar::Resize()
1106 if ( IsReallyVisible() )
1111 IMPL_LINK_NOARG(ScrollBar
, ImplAutoTimerHdl
, Timer
*, void)
1113 if( mpData
&& mpData
->mbHide
)
1118 void ScrollBar::ImplInvert()
1120 tools::Rectangle
aRect( maThumbRect
);
1121 if( aRect
.getWidth() > 4 )
1123 aRect
.AdjustLeft(2 );
1124 aRect
.AdjustRight( -2 );
1126 if( aRect
.getHeight() > 4 )
1128 aRect
.AdjustTop(2 );
1129 aRect
.AdjustBottom( -2 );
1135 void ScrollBar::GetFocus()
1139 mpData
.reset(new ImplScrollBarData
);
1140 mpData
->maTimer
.SetInvokeHandler( LINK( this, ScrollBar
, ImplAutoTimerHdl
) );
1141 mpData
->maTimer
.SetDebugName( "vcl::ScrollBar mpData->maTimer" );
1142 mpData
->mbHide
= false;
1144 ImplInvert(); // react immediately
1145 mpData
->maTimer
.SetTimeout( GetSettings().GetStyleSettings().GetCursorBlinkTime() );
1146 mpData
->maTimer
.Start();
1147 Control::GetFocus();
1150 void ScrollBar::LoseFocus()
1153 mpData
->maTimer
.Stop();
1156 Control::LoseFocus();
1159 void ScrollBar::StateChanged( StateChangedType nType
)
1161 Control::StateChanged( nType
);
1163 if ( nType
== StateChangedType::InitShow
)
1165 else if ( nType
== StateChangedType::Data
)
1167 if ( IsReallyVisible() && IsUpdateMode() )
1170 else if ( nType
== StateChangedType::UpdateMode
)
1172 if ( IsReallyVisible() && IsUpdateMode() )
1178 else if ( nType
== StateChangedType::Enable
)
1180 if ( IsReallyVisible() && IsUpdateMode() )
1183 else if ( nType
== StateChangedType::Style
)
1185 ImplInitStyle( GetStyle() );
1186 if ( IsReallyVisible() && IsUpdateMode() )
1188 if ( (GetPrevStyle() & SCRBAR_VIEW_STYLE
) !=
1189 (GetStyle() & SCRBAR_VIEW_STYLE
) )
1199 void ScrollBar::DataChanged( const DataChangedEvent
& rDCEvt
)
1201 Control::DataChanged( rDCEvt
);
1203 if ( (rDCEvt
.GetType() == DataChangedEventType::SETTINGS
) &&
1204 (rDCEvt
.GetFlags() & AllSettingsFlags::STYLE
) )
1212 tools::Rectangle
* ScrollBar::ImplFindPartRect( const Point
& rPt
)
1214 bool bHorizontal
= ( GetStyle() & WB_HORZ
) != 0;
1215 bool bIsInside
= false;
1217 Point
aPoint( 0, 0 );
1218 tools::Rectangle
aControlRegion( aPoint
, GetOutputSizePixel() );
1220 if( HitTestNativeScrollbar( bHorizontal
? (IsRTLEnabled()? ControlPart::ButtonRight
: ControlPart::ButtonLeft
): ControlPart::ButtonUp
,
1221 aControlRegion
, rPt
, bIsInside
)?
1223 maBtn1Rect
.IsInside( rPt
) )
1225 else if( HitTestNativeScrollbar( bHorizontal
? (IsRTLEnabled()? ControlPart::ButtonLeft
: ControlPart::ButtonRight
): ControlPart::ButtonDown
,
1226 aControlRegion
, rPt
, bIsInside
)?
1228 maBtn2Rect
.IsInside( rPt
) )
1230 // HitTestNativeScrollbar, see remark at top of file
1231 else if( HitTestNativeScrollbar( bHorizontal
? ControlPart::TrackHorzLeft
: ControlPart::TrackVertUpper
,
1232 maPage1Rect
, rPt
, bIsInside
)?
1234 maPage1Rect
.IsInside( rPt
) )
1235 return &maPage1Rect
;
1236 // HitTestNativeScrollbar, see remark at top of file
1237 else if( HitTestNativeScrollbar( bHorizontal
? ControlPart::TrackHorzRight
: ControlPart::TrackVertLower
,
1238 maPage2Rect
, rPt
, bIsInside
)?
1240 maPage2Rect
.IsInside( rPt
) )
1241 return &maPage2Rect
;
1242 // HitTestNativeScrollbar, see remark at top of file
1243 else if( HitTestNativeScrollbar( bHorizontal
? ControlPart::ThumbHorz
: ControlPart::ThumbVert
,
1244 maThumbRect
, rPt
, bIsInside
)?
1246 maThumbRect
.IsInside( rPt
) )
1247 return &maThumbRect
;
1252 bool ScrollBar::PreNotify( NotifyEvent
& rNEvt
)
1254 const MouseEvent
* pMouseEvt
= nullptr;
1256 if( (rNEvt
.GetType() == MouseNotifyEvent::MOUSEMOVE
) && (pMouseEvt
= rNEvt
.GetMouseEvent()) != nullptr )
1258 if( !pMouseEvt
->GetButtons() && !pMouseEvt
->IsSynthetic() && !pMouseEvt
->IsModifierChanged() )
1260 // Trigger a redraw if mouse over state has changed
1261 if( IsNativeControlSupported(ControlType::Scrollbar
, ControlPart::Entire
) )
1263 tools::Rectangle
* pRect
= ImplFindPartRect( GetPointerPosPixel() );
1264 tools::Rectangle
* pLastRect
= ImplFindPartRect( GetLastPointerPosPixel() );
1265 if( pRect
!= pLastRect
|| pMouseEvt
->IsLeaveWindow() || pMouseEvt
->IsEnterWindow() )
1267 vcl::Region
aRgn( GetActiveClipRegion() );
1268 vcl::Region aClipRegion
;
1271 aClipRegion
.Union( *pRect
);
1273 aClipRegion
.Union( *pLastRect
);
1275 // Support for 3-button scroll bars
1276 bool bHas3Buttons
= IsNativeControlSupported( ControlType::Scrollbar
, ControlPart::HasThreeButtons
);
1277 if ( bHas3Buttons
&& ( pRect
== &maBtn1Rect
|| pLastRect
== &maBtn1Rect
) )
1279 aClipRegion
.Union( maBtn2Rect
);
1282 SetClipRegion( aClipRegion
);
1283 Invalidate(aClipRegion
.GetBoundRect());
1285 SetClipRegion( aRgn
);
1291 return Control::PreNotify(rNEvt
);
1294 void ScrollBar::Scroll()
1296 ImplCallEventListenersAndHandler( VclEventId::ScrollbarScroll
, [this] () { maScrollHdl
.Call(this); } );
1299 void ScrollBar::EndScroll()
1301 ImplCallEventListenersAndHandler( VclEventId::ScrollbarEndScroll
, [this] () { maEndScrollHdl
.Call(this); } );
1304 long ScrollBar::DoScroll( long nNewPos
)
1306 if ( meScrollType
!= ScrollType::DontKnow
)
1309 SAL_INFO("vcl.scrollbar", "DoScroll(" << nNewPos
<< ")");
1310 meScrollType
= ScrollType::Drag
;
1311 long nDelta
= ImplScroll( nNewPos
, true );
1312 meScrollType
= ScrollType::DontKnow
;
1316 long ScrollBar::DoScrollAction( ScrollType eScrollType
)
1318 if ( (meScrollType
!= ScrollType::DontKnow
) ||
1319 (eScrollType
== ScrollType::DontKnow
) ||
1320 (eScrollType
== ScrollType::Drag
) )
1323 meScrollType
= eScrollType
;
1324 long nDelta
= ImplDoAction( true );
1325 meScrollType
= ScrollType::DontKnow
;
1329 void ScrollBar::SetRangeMin( long nNewRange
)
1331 SetRange( Range( nNewRange
, GetRangeMax() ) );
1334 void ScrollBar::SetRangeMax( long nNewRange
)
1336 SetRange( Range( GetRangeMin(), nNewRange
) );
1339 void ScrollBar::SetRange( const Range
& rRange
)
1342 Range aRange
= rRange
;
1344 long nNewMinRange
= aRange
.Min();
1345 long nNewMaxRange
= aRange
.Max();
1347 // If Range differs, set a new one
1348 if ( (mnMinRange
!= nNewMinRange
) ||
1349 (mnMaxRange
!= nNewMaxRange
) )
1351 mnMinRange
= nNewMinRange
;
1352 mnMaxRange
= nNewMaxRange
;
1355 if ( mnThumbPos
> mnMaxRange
-mnVisibleSize
)
1356 mnThumbPos
= mnMaxRange
-mnVisibleSize
;
1357 if ( mnThumbPos
< mnMinRange
)
1358 mnThumbPos
= mnMinRange
;
1360 CompatStateChanged( StateChangedType::Data
);
1364 void ScrollBar::SetThumbPos( long nNewThumbPos
)
1366 if ( nNewThumbPos
> mnMaxRange
-mnVisibleSize
)
1367 nNewThumbPos
= mnMaxRange
-mnVisibleSize
;
1368 if ( nNewThumbPos
< mnMinRange
)
1369 nNewThumbPos
= mnMinRange
;
1371 if ( mnThumbPos
!= nNewThumbPos
)
1373 mnThumbPos
= nNewThumbPos
;
1374 CompatStateChanged( StateChangedType::Data
);
1378 void ScrollBar::SetVisibleSize( long nNewSize
)
1380 if ( mnVisibleSize
!= nNewSize
)
1382 mnVisibleSize
= nNewSize
;
1385 if ( mnThumbPos
> mnMaxRange
-mnVisibleSize
)
1386 mnThumbPos
= mnMaxRange
-mnVisibleSize
;
1387 if ( mnThumbPos
< mnMinRange
)
1388 mnThumbPos
= mnMinRange
;
1389 CompatStateChanged( StateChangedType::Data
);
1393 Size
ScrollBar::GetOptimalSize() const
1396 const_cast<ScrollBar
*>(this)->ImplCalc(false);
1398 Size aRet
= getCurrentCalcSize();
1400 const long nMinThumbSize
= GetSettings().GetStyleSettings().GetMinThumbSize();
1402 if (GetStyle() & WB_HORZ
)
1404 aRet
.setWidth( maBtn1Rect
.GetWidth() + nMinThumbSize
+ maBtn2Rect
.GetWidth() );
1408 aRet
.setHeight( maBtn1Rect
.GetHeight() + nMinThumbSize
+ maBtn2Rect
.GetHeight() );
1414 Size
ScrollBar::getCurrentCalcSize() const
1416 tools::Rectangle aCtrlRegion
;
1417 aCtrlRegion
.Union(maBtn1Rect
);
1418 aCtrlRegion
.Union(maBtn2Rect
);
1419 aCtrlRegion
.Union(maPage1Rect
);
1420 aCtrlRegion
.Union(maPage2Rect
);
1421 aCtrlRegion
.Union(maThumbRect
);
1422 return aCtrlRegion
.GetSize();
1425 void ScrollBarBox::ImplInit(vcl::Window
* pParent
, WinBits nStyle
)
1427 Window::ImplInit( pParent
, nStyle
, nullptr );
1429 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
1430 long nScrollSize
= rStyleSettings
.GetScrollBarSize();
1431 SetSizePixel(Size(nScrollSize
, nScrollSize
));
1434 ScrollBarBox::ScrollBarBox( vcl::Window
* pParent
, WinBits nStyle
) :
1435 Window( WindowType::SCROLLBARBOX
)
1437 ImplInit( pParent
, nStyle
);
1440 void ScrollBarBox::ApplySettings(vcl::RenderContext
& rRenderContext
)
1442 if (rRenderContext
.IsBackground())
1444 Color aColor
= rRenderContext
.GetSettings().GetStyleSettings().GetFaceColor();
1445 ApplyControlBackground(rRenderContext
, aColor
);
1449 void ScrollBarBox::StateChanged( StateChangedType nType
)
1451 Window::StateChanged( nType
);
1453 if (nType
== StateChangedType::ControlBackground
)
1459 void ScrollBarBox::DataChanged( const DataChangedEvent
& rDCEvt
)
1461 Window::DataChanged( rDCEvt
);
1463 if ((rDCEvt
.GetType() == DataChangedEventType::SETTINGS
) &&
1464 (rDCEvt
.GetFlags() & AllSettingsFlags::STYLE
))
1470 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */