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 tools::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 tools::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 tools::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 tools::Long
ScrollBar::ImplCalcThumbPos( tools::Long nPixPos
)
205 // Calculate position
206 tools::Long nCalcThumbPos
;
207 nCalcThumbPos
= ImplMulDiv( nPixPos
, mnMaxRange
-mnVisibleSize
-mnMinRange
,
208 mnThumbPixRange
-mnThumbPixSize
);
209 nCalcThumbPos
+= mnMinRange
;
210 return nCalcThumbPos
;
213 tools::Long
ScrollBar::ImplCalcThumbPosPix( tools::Long nPos
)
215 tools::Long nCalcThumbPos
;
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 tools::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::Justify( 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::Justify( 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
, 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 tools::Long
ScrollBar::ImplScroll( tools::Long nNewPos
, bool bCallEndScroll
)
676 tools::Long nOldPos
= mnThumbPos
;
677 SetThumbPos( nNewPos
);
678 tools::Long nDelta
= mnThumbPos
-nOldPos
;
683 if ( bCallEndScroll
)
690 tools::Long
ScrollBar::ImplDoAction( bool bCallEndScroll
)
692 tools::Long nDelta
= 0;
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
)
795 tools::Long nMovePix
;
796 if ( GetStyle() & WB_HORZ
)
797 nMovePix
= rMousePos
.X()-(maThumbRect
.Left()+mnMouseOff
);
799 nMovePix
= rMousePos
.Y()-(maThumbRect
.Top()+mnMouseOff
);
801 // Move thumb if necessary
805 mnThumbPixPos
+= nMovePix
;
806 if ( mnThumbPixPos
< 0 )
808 if ( mnThumbPixPos
> (mnThumbPixRange
-mnThumbPixSize
) )
809 mnThumbPixPos
= mnThumbPixRange
-mnThumbPixSize
;
810 tools::Long nOldPos
= mnThumbPos
;
811 mnThumbPos
= ImplCalcThumbPos( mnThumbPixPos
);
813 if ( !(mbFullDrag
&& (nOldPos
!= mnThumbPos
)) )
816 // When dragging in windows the repaint request gets starved so dragging
817 // the scrollbar feels slower than it actually is. Let's force an immediate
818 // repaint of the scrollbar.
819 if (SupportsDoubleBuffering())
827 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
)
957 // store original position for cancel and EndScroll delta
958 mnStartPos
= mnThumbPos
;
959 // #92906# Call StartTracking() before ImplDoMouseAction(), otherwise
960 // MouseButtonUp() / EndTracking() may be called if somebody is spending
961 // a lot of time in the scroll handler
962 StartTracking( nTrackFlags
);
963 ImplDoMouseAction( rMousePos
);
966 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 tools::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 if( rNEvt
.GetType() == MouseNotifyEvent::MOUSEMOVE
)
1256 const MouseEvent
* pMouseEvt
= rNEvt
.GetMouseEvent();
1257 if( pMouseEvt
&& !pMouseEvt
->GetButtons() && !pMouseEvt
->IsSynthetic() && !pMouseEvt
->IsModifierChanged() )
1259 // Trigger a redraw if mouse over state has changed
1260 if( IsNativeControlSupported(ControlType::Scrollbar
, ControlPart::Entire
) )
1262 tools::Rectangle
* pRect
= ImplFindPartRect( GetPointerPosPixel() );
1263 tools::Rectangle
* pLastRect
= ImplFindPartRect( GetLastPointerPosPixel() );
1264 if( pRect
!= pLastRect
|| pMouseEvt
->IsLeaveWindow() || pMouseEvt
->IsEnterWindow() )
1266 vcl::Region
aRgn( GetActiveClipRegion() );
1267 vcl::Region aClipRegion
;
1270 aClipRegion
.Union( *pRect
);
1272 aClipRegion
.Union( *pLastRect
);
1274 // Support for 3-button scroll bars
1275 bool bHas3Buttons
= IsNativeControlSupported( ControlType::Scrollbar
, ControlPart::HasThreeButtons
);
1276 if ( bHas3Buttons
&& ( pRect
== &maBtn1Rect
|| pLastRect
== &maBtn1Rect
) )
1278 aClipRegion
.Union( maBtn2Rect
);
1281 SetClipRegion( aClipRegion
);
1282 Invalidate(aClipRegion
.GetBoundRect());
1284 SetClipRegion( aRgn
);
1290 return Control::PreNotify(rNEvt
);
1293 void ScrollBar::Scroll()
1295 ImplCallEventListenersAndHandler( VclEventId::ScrollbarScroll
, [this] () { maScrollHdl
.Call(this); } );
1298 void ScrollBar::EndScroll()
1300 ImplCallEventListenersAndHandler( VclEventId::ScrollbarEndScroll
, [this] () { maEndScrollHdl
.Call(this); } );
1303 tools::Long
ScrollBar::DoScroll( tools::Long nNewPos
)
1305 if ( meScrollType
!= ScrollType::DontKnow
)
1308 SAL_INFO("vcl.scrollbar", "DoScroll(" << nNewPos
<< ")");
1309 meScrollType
= ScrollType::Drag
;
1310 tools::Long nDelta
= ImplScroll( nNewPos
, true );
1311 meScrollType
= ScrollType::DontKnow
;
1315 tools::Long
ScrollBar::DoScrollAction( ScrollType eScrollType
)
1317 if ( (meScrollType
!= ScrollType::DontKnow
) ||
1318 (eScrollType
== ScrollType::DontKnow
) ||
1319 (eScrollType
== ScrollType::Drag
) )
1322 meScrollType
= eScrollType
;
1323 tools::Long nDelta
= ImplDoAction( true );
1324 meScrollType
= ScrollType::DontKnow
;
1328 void ScrollBar::SetRangeMin( tools::Long nNewRange
)
1330 SetRange( Range( nNewRange
, GetRangeMax() ) );
1333 void ScrollBar::SetRangeMax( tools::Long nNewRange
)
1335 SetRange( Range( GetRangeMin(), nNewRange
) );
1338 void ScrollBar::SetRange( const Range
& rRange
)
1341 Range aRange
= rRange
;
1343 tools::Long nNewMinRange
= aRange
.Min();
1344 tools::Long nNewMaxRange
= aRange
.Max();
1346 // If Range differs, set a new one
1347 if ( (mnMinRange
== nNewMinRange
) && (mnMaxRange
== nNewMaxRange
))
1350 mnMinRange
= nNewMinRange
;
1351 mnMaxRange
= nNewMaxRange
;
1354 if ( mnThumbPos
> mnMaxRange
-mnVisibleSize
)
1355 mnThumbPos
= mnMaxRange
-mnVisibleSize
;
1356 if ( mnThumbPos
< mnMinRange
)
1357 mnThumbPos
= mnMinRange
;
1359 CompatStateChanged( StateChangedType::Data
);
1362 void ScrollBar::SetThumbPos( tools::Long nNewThumbPos
)
1364 if ( nNewThumbPos
> mnMaxRange
-mnVisibleSize
)
1365 nNewThumbPos
= mnMaxRange
-mnVisibleSize
;
1366 if ( nNewThumbPos
< mnMinRange
)
1367 nNewThumbPos
= mnMinRange
;
1369 if ( mnThumbPos
!= nNewThumbPos
)
1371 mnThumbPos
= nNewThumbPos
;
1372 CompatStateChanged( StateChangedType::Data
);
1376 void ScrollBar::SetVisibleSize( tools::Long nNewSize
)
1378 if ( mnVisibleSize
!= nNewSize
)
1380 mnVisibleSize
= nNewSize
;
1383 if ( mnThumbPos
> mnMaxRange
-mnVisibleSize
)
1384 mnThumbPos
= mnMaxRange
-mnVisibleSize
;
1385 if ( mnThumbPos
< mnMinRange
)
1386 mnThumbPos
= mnMinRange
;
1387 CompatStateChanged( StateChangedType::Data
);
1391 Size
ScrollBar::GetOptimalSize() const
1394 const_cast<ScrollBar
*>(this)->ImplCalc(false);
1396 Size aRet
= getCurrentCalcSize();
1398 const tools::Long nMinThumbSize
= GetSettings().GetStyleSettings().GetMinThumbSize();
1400 if (GetStyle() & WB_HORZ
)
1402 aRet
.setWidth( maBtn1Rect
.GetWidth() + nMinThumbSize
+ maBtn2Rect
.GetWidth() );
1406 aRet
.setHeight( maBtn1Rect
.GetHeight() + nMinThumbSize
+ maBtn2Rect
.GetHeight() );
1412 Size
ScrollBar::getCurrentCalcSize() const
1414 tools::Rectangle aCtrlRegion
;
1415 aCtrlRegion
.Union(maBtn1Rect
);
1416 aCtrlRegion
.Union(maBtn2Rect
);
1417 aCtrlRegion
.Union(maPage1Rect
);
1418 aCtrlRegion
.Union(maPage2Rect
);
1419 aCtrlRegion
.Union(maThumbRect
);
1420 return aCtrlRegion
.GetSize();
1423 void ScrollBarBox::ImplInit(vcl::Window
* pParent
, WinBits nStyle
)
1425 Window::ImplInit( pParent
, nStyle
, nullptr );
1427 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
1428 tools::Long nScrollSize
= rStyleSettings
.GetScrollBarSize();
1429 SetSizePixel(Size(nScrollSize
, nScrollSize
));
1432 ScrollBarBox::ScrollBarBox( vcl::Window
* pParent
, WinBits nStyle
) :
1433 Window( WindowType::SCROLLBARBOX
)
1435 ImplInit( pParent
, nStyle
);
1438 void ScrollBarBox::ApplySettings(vcl::RenderContext
& rRenderContext
)
1440 if (rRenderContext
.IsBackground())
1442 Color aColor
= rRenderContext
.GetSettings().GetStyleSettings().GetFaceColor();
1443 ApplyControlBackground(rRenderContext
, aColor
);
1447 void ScrollBarBox::StateChanged( StateChangedType nType
)
1449 Window::StateChanged( nType
);
1451 if (nType
== StateChangedType::ControlBackground
)
1457 void ScrollBarBox::DataChanged( const DataChangedEvent
& rDCEvt
)
1459 Window::DataChanged( rDCEvt
);
1461 if ((rDCEvt
.GetType() == DataChangedEventType::SETTINGS
) &&
1462 (rDCEvt
.GetFlags() & AllSettingsFlags::STYLE
))
1468 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */