1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <vcl/event.hxx>
22 #include <vcl/decoview.hxx>
23 #include <vcl/slider.hxx>
24 #include <vcl/settings.hxx>
26 #include "thumbpos.hxx"
28 #define SLIDER_STATE_CHANNEL1_DOWN ((sal_uInt16)0x0001)
29 #define SLIDER_STATE_CHANNEL2_DOWN ((sal_uInt16)0x0002)
30 #define SLIDER_STATE_THUMB_DOWN ((sal_uInt16)0x0004)
32 #define SLIDER_THUMB_SIZE 9
33 #define SLIDER_THUMB_HALFSIZE 4
34 #define SLIDER_CHANNEL_OFFSET 0
35 #define SLIDER_CHANNEL_SIZE 4
36 #define SLIDER_CHANNEL_HALFSIZE 2
38 #define SLIDER_HEIGHT 16
40 #define SLIDER_VIEW_STYLE (WB_3DLOOK | WB_HORZ | WB_VERT)
42 void Slider::ImplInit( vcl::Window
* pParent
, WinBits nStyle
)
46 mnThumbPixPos
= 0; // between mnThumbPixOffset and mnThumbPixOffset+mnThumbPixRange
47 mnChannelPixOffset
= 0;
48 mnChannelPixRange
= 0;
50 mnChannelPixBottom
= 0;
59 meScrollType
= ScrollType::DontKnow
;
63 mpLinkedField
= nullptr;
65 Control::ImplInit( pParent
, nStyle
, nullptr );
68 SetSizePixel( CalcWindowSizePixel() );
71 Slider::Slider( vcl::Window
* pParent
, WinBits nStyle
) :
72 Control(WINDOW_SLIDER
)
74 ImplInit( pParent
, nStyle
);
82 void Slider::dispose()
84 mpLinkedField
.clear();
88 void Slider::ImplInitSettings()
90 vcl::Window
* pParent
= GetParent();
91 if ( pParent
->IsChildTransparentModeEnabled() && !IsControlBackground() )
93 EnableChildTransparentMode();
94 SetParentClipMode( ParentClipMode::NoClip
);
95 SetPaintTransparent( true );
100 EnableChildTransparentMode( false );
102 SetPaintTransparent( false );
104 if ( IsControlBackground() )
105 SetBackground( GetControlBackground() );
107 SetBackground( pParent
->GetBackground() );
111 void Slider::ImplUpdateRects( bool bUpdate
)
113 Rectangle aOldThumbRect
= maThumbRect
;
114 bool bInvalidateAll
= false;
116 if ( mnThumbPixRange
)
118 if ( GetStyle() & WB_HORZ
)
120 maThumbRect
.Left() = mnThumbPixPos
-SLIDER_THUMB_HALFSIZE
;
121 maThumbRect
.Right() = maThumbRect
.Left()+SLIDER_THUMB_SIZE
-1;
122 if ( mnChannelPixOffset
< maThumbRect
.Left() )
124 maChannel1Rect
.Left() = mnChannelPixOffset
;
125 maChannel1Rect
.Right() = maThumbRect
.Left()-1;
126 maChannel1Rect
.Top() = mnChannelPixTop
;
127 maChannel1Rect
.Bottom() = mnChannelPixBottom
;
130 maChannel1Rect
.SetEmpty();
131 if ( mnChannelPixOffset
+mnChannelPixRange
-1 > maThumbRect
.Right() )
133 maChannel2Rect
.Left() = maThumbRect
.Right()+1;
134 maChannel2Rect
.Right() = mnChannelPixOffset
+mnChannelPixRange
-1;
135 maChannel2Rect
.Top() = mnChannelPixTop
;
136 maChannel2Rect
.Bottom() = mnChannelPixBottom
;
139 maChannel2Rect
.SetEmpty();
141 const Rectangle
aControlRegion( Rectangle( Point(0,0), Size( SLIDER_THUMB_SIZE
, 10 ) ) );
142 Rectangle aThumbBounds
, aThumbContent
;
143 if ( GetNativeControlRegion( ControlType::Slider
, ControlPart::ThumbHorz
,
144 aControlRegion
, ControlState::NONE
, ImplControlValue(), OUString(),
145 aThumbBounds
, aThumbContent
) )
147 maThumbRect
.Left() = mnThumbPixPos
- aThumbBounds
.GetWidth()/2;
148 maThumbRect
.Right() = maThumbRect
.Left() + aThumbBounds
.GetWidth() - 1;
149 bInvalidateAll
= true;
154 maThumbRect
.Top() = mnThumbPixPos
-SLIDER_THUMB_HALFSIZE
;
155 maThumbRect
.Bottom() = maThumbRect
.Top()+SLIDER_THUMB_SIZE
-1;
156 if ( mnChannelPixOffset
< maThumbRect
.Top() )
158 maChannel1Rect
.Top() = mnChannelPixOffset
;
159 maChannel1Rect
.Bottom() = maThumbRect
.Top()-1;
160 maChannel1Rect
.Left() = mnChannelPixTop
;
161 maChannel1Rect
.Right() = mnChannelPixBottom
;
164 maChannel1Rect
.SetEmpty();
165 if ( mnChannelPixOffset
+mnChannelPixRange
-1 > maThumbRect
.Bottom() )
167 maChannel2Rect
.Top() = maThumbRect
.Bottom()+1;
168 maChannel2Rect
.Bottom() = mnChannelPixOffset
+mnChannelPixRange
-1;
169 maChannel2Rect
.Left() = mnChannelPixTop
;
170 maChannel2Rect
.Right() = mnChannelPixBottom
;
173 maChannel2Rect
.SetEmpty();
175 const Rectangle
aControlRegion( Rectangle( Point(0,0), Size( 10, SLIDER_THUMB_SIZE
) ) );
176 Rectangle aThumbBounds
, aThumbContent
;
177 if ( GetNativeControlRegion( ControlType::Slider
, ControlPart::ThumbVert
,
178 aControlRegion
, ControlState::NONE
, ImplControlValue(), OUString(),
179 aThumbBounds
, aThumbContent
) )
181 maThumbRect
.Top() = mnThumbPixPos
- aThumbBounds
.GetHeight()/2;
182 maThumbRect
.Bottom() = maThumbRect
.Top() + aThumbBounds
.GetHeight() - 1;
183 bInvalidateAll
= true;
189 maChannel1Rect
.SetEmpty();
190 maChannel2Rect
.SetEmpty();
191 maThumbRect
.SetEmpty();
196 if ( aOldThumbRect
!= maThumbRect
)
199 Invalidate(InvalidateFlags::NoChildren
| InvalidateFlags::NoErase
);
202 vcl::Region
aInvalidRegion( aOldThumbRect
);
203 aInvalidRegion
.Union( maThumbRect
);
205 if( !IsBackground() && GetParent() )
207 const Point
aPos( GetPosPixel() );
208 aInvalidRegion
.Move( aPos
.X(), aPos
.Y() );
209 GetParent()->Invalidate( aInvalidRegion
, InvalidateFlags::Transparent
| InvalidateFlags::Update
);
212 Invalidate( aInvalidRegion
);
218 void Slider::ImplUpdateLinkedField()
221 mpLinkedField
->SetValue(mnThumbPos
);
224 long Slider::ImplCalcThumbPos( long nPixPos
)
226 // calculate position
228 nCalcThumbPos
= ImplMulDiv( nPixPos
-mnThumbPixOffset
, mnMaxRange
-mnMinRange
, mnThumbPixRange
-1 );
229 nCalcThumbPos
+= mnMinRange
;
230 return nCalcThumbPos
;
233 long Slider::ImplCalcThumbPosPix( long nPos
)
235 // calculate position
237 nCalcThumbPos
= ImplMulDiv( nPos
-mnMinRange
, mnThumbPixRange
-1, mnMaxRange
-mnMinRange
);
238 // at the beginning and end we try to display Slider correctly
239 if ( !nCalcThumbPos
&& (mnThumbPos
> mnMinRange
) )
241 if ( nCalcThumbPos
&&
242 (nCalcThumbPos
== mnThumbPixRange
-1) &&
243 (mnThumbPos
< mnMaxRange
) )
245 return nCalcThumbPos
+mnThumbPixOffset
;
248 void Slider::ImplCalc( bool bUpdate
)
250 bool bInvalidateAll
= false;
254 long nOldChannelPixOffset
= mnChannelPixOffset
;
255 long nOldChannelPixRange
= mnChannelPixRange
;
256 long nOldChannelPixTop
= mnChannelPixTop
;
257 long nOldChannelPixBottom
= mnChannelPixBottom
;
261 maChannel1Rect
.SetEmpty();
262 maChannel2Rect
.SetEmpty();
263 maThumbRect
.SetEmpty();
265 Size aSize
= GetOutputSizePixel();
266 if ( GetStyle() & WB_HORZ
)
268 nCalcWidth
= aSize
.Width();
269 nCalcHeight
= aSize
.Height();
270 maThumbRect
.Top() = 0;
271 maThumbRect
.Bottom()= aSize
.Height()-1;
275 nCalcWidth
= aSize
.Height();
276 nCalcHeight
= aSize
.Width();
277 maThumbRect
.Left() = 0;
278 maThumbRect
.Right() = aSize
.Width()-1;
281 if ( nCalcWidth
>= SLIDER_THUMB_SIZE
)
283 mnThumbPixOffset
= SLIDER_THUMB_HALFSIZE
;
284 mnThumbPixRange
= nCalcWidth
-(SLIDER_THUMB_HALFSIZE
*2);
286 mnChannelPixOffset
= SLIDER_CHANNEL_OFFSET
;
287 mnChannelPixRange
= nCalcWidth
-(SLIDER_CHANNEL_OFFSET
*2);
288 mnChannelPixTop
= (nCalcHeight
/2)-SLIDER_CHANNEL_HALFSIZE
;
289 mnChannelPixBottom
= mnChannelPixTop
+SLIDER_CHANNEL_SIZE
-1;
294 mnChannelPixRange
= 0;
297 if ( (nOldChannelPixOffset
!= mnChannelPixOffset
) ||
298 (nOldChannelPixRange
!= mnChannelPixRange
) ||
299 (nOldChannelPixTop
!= mnChannelPixTop
) ||
300 (nOldChannelPixBottom
!= mnChannelPixBottom
) )
301 bInvalidateAll
= true;
306 if ( mnThumbPixRange
)
307 mnThumbPixPos
= ImplCalcThumbPosPix( mnThumbPos
);
309 if ( bUpdate
&& bInvalidateAll
)
314 ImplUpdateRects( bUpdate
);
317 void Slider::ImplDraw(vcl::RenderContext
& rRenderContext
)
319 DecorationView
aDecoView(&rRenderContext
);
320 DrawButtonFlags nStyle
;
321 const StyleSettings
& rStyleSettings
= rRenderContext
.GetSettings().GetStyleSettings();
322 bool bEnabled
= IsEnabled();
324 // do missing calculations
328 ControlPart nPart
= (GetStyle() & WB_HORZ
) ? ControlPart::TrackHorzArea
: ControlPart::TrackVertArea
;
329 ControlState nState
= (IsEnabled() ? ControlState::ENABLED
: ControlState::NONE
);
330 nState
|= (HasFocus() ? ControlState::FOCUSED
: ControlState::NONE
);
331 SliderValue sldValue
;
333 sldValue
.mnMin
= mnMinRange
;
334 sldValue
.mnMax
= mnMaxRange
;
335 sldValue
.mnCur
= mnThumbPos
;
336 sldValue
.maThumbRect
= maThumbRect
;
340 if (maThumbRect
.IsInside(GetPointerPosPixel()))
341 sldValue
.mnThumbState
|= ControlState::ROLLOVER
;
344 const Rectangle
aCtrlRegion(Point(0,0), GetOutputSizePixel());
345 bool bNativeOK
= rRenderContext
.DrawNativeControl(ControlType::Slider
, nPart
, aCtrlRegion
, nState
, sldValue
, OUString());
349 if (!maChannel1Rect
.IsEmpty())
352 Rectangle aRect
= maChannel1Rect
;
353 rRenderContext
.SetLineColor(rStyleSettings
.GetShadowColor());
354 if (GetStyle() & WB_HORZ
)
356 rRenderContext
.DrawLine(aRect
.TopLeft(), Point(aRect
.Left(), aRect
.Bottom() - 1));
357 rRenderContext
.DrawLine(aRect
.TopLeft(), aRect
.TopRight());
361 rRenderContext
.DrawLine(aRect
.TopLeft(), Point(aRect
.Right() - 1, aRect
.Top()));
362 rRenderContext
.DrawLine(aRect
.TopLeft(), aRect
.BottomLeft());
364 rRenderContext
.SetLineColor(rStyleSettings
.GetLightColor());
365 if (GetStyle() & WB_HORZ
)
367 rRenderContext
.DrawLine(aRect
.BottomLeft(), aRect
.BottomRight());
368 nRectSize
= aRect
.GetWidth();
372 rRenderContext
.DrawLine(aRect
.TopRight(), aRect
.BottomRight());
373 nRectSize
= aRect
.GetHeight();
380 if (GetStyle() & WB_HORZ
)
384 rRenderContext
.SetLineColor();
385 if (mnStateFlags
& SLIDER_STATE_CHANNEL1_DOWN
)
386 rRenderContext
.SetFillColor(rStyleSettings
.GetShadowColor());
388 rRenderContext
.SetFillColor(rStyleSettings
.GetCheckedColor());
389 rRenderContext
.DrawRect(aRect
);
393 if (!maChannel2Rect
.IsEmpty())
396 Rectangle aRect
= maChannel2Rect
;
397 rRenderContext
.SetLineColor(rStyleSettings
.GetLightColor());
398 if (GetStyle() & WB_HORZ
)
400 rRenderContext
.DrawLine(aRect
.TopRight(), aRect
.BottomRight());
401 rRenderContext
.DrawLine(aRect
.BottomLeft(), aRect
.BottomRight());
402 nRectSize
= aRect
.GetWidth();
406 rRenderContext
.DrawLine(aRect
.BottomLeft(), aRect
.BottomRight());
407 rRenderContext
.DrawLine(aRect
.TopRight(), aRect
.BottomRight());
408 nRectSize
= aRect
.GetHeight();
413 rRenderContext
.SetLineColor(rStyleSettings
.GetShadowColor());
414 if (GetStyle() & WB_HORZ
)
415 rRenderContext
.DrawLine(aRect
.TopLeft(), Point(aRect
.Right() - 1, aRect
.Top()));
417 rRenderContext
.DrawLine(aRect
.TopLeft(), Point(aRect
.Left(), aRect
.Bottom() - 1));
421 if (GetStyle() & WB_HORZ
)
425 rRenderContext
.SetLineColor();
426 if (mnStateFlags
& SLIDER_STATE_CHANNEL2_DOWN
)
427 rRenderContext
.SetFillColor(rStyleSettings
.GetShadowColor());
429 rRenderContext
.SetFillColor(rStyleSettings
.GetCheckedColor());
430 rRenderContext
.DrawRect(aRect
);
434 if (!maThumbRect
.IsEmpty())
438 nStyle
= DrawButtonFlags::NONE
;
439 if (mnStateFlags
& SLIDER_STATE_THUMB_DOWN
)
440 nStyle
|= DrawButtonFlags::Pressed
;
441 aDecoView
.DrawButton(maThumbRect
, nStyle
);
445 rRenderContext
.SetLineColor(rStyleSettings
.GetShadowColor());
446 rRenderContext
.SetFillColor(rStyleSettings
.GetCheckedColor());
447 rRenderContext
.DrawRect(maThumbRect
);
452 bool Slider::ImplIsPageUp( const Point
& rPos
)
454 Size aSize
= GetOutputSizePixel();
455 Rectangle aRect
= maChannel1Rect
;
456 if ( GetStyle() & WB_HORZ
)
459 aRect
.Bottom() = aSize
.Height()-1;
464 aRect
.Right() = aSize
.Width()-1;
466 return aRect
.IsInside( rPos
);
469 bool Slider::ImplIsPageDown( const Point
& rPos
)
471 Size aSize
= GetOutputSizePixel();
472 Rectangle aRect
= maChannel2Rect
;
473 if ( GetStyle() & WB_HORZ
)
476 aRect
.Bottom() = aSize
.Height()-1;
481 aRect
.Right() = aSize
.Width()-1;
483 return aRect
.IsInside( rPos
);
486 long Slider::ImplSlide( long nNewPos
, bool bCallEndSlide
)
488 long nOldPos
= mnThumbPos
;
489 SetThumbPos( nNewPos
);
490 long nDelta
= mnThumbPos
-nOldPos
;
502 long Slider::ImplDoAction( bool bCallEndSlide
)
506 switch ( meScrollType
)
508 case ScrollType::LineUp
:
509 nDelta
= ImplSlide( mnThumbPos
-mnLineSize
, bCallEndSlide
);
512 case ScrollType::LineDown
:
513 nDelta
= ImplSlide( mnThumbPos
+mnLineSize
, bCallEndSlide
);
516 case ScrollType::PageUp
:
517 nDelta
= ImplSlide( mnThumbPos
-mnPageSize
, bCallEndSlide
);
520 case ScrollType::PageDown
:
521 nDelta
= ImplSlide( mnThumbPos
+mnPageSize
, bCallEndSlide
);
524 case ScrollType::Set
:
525 nDelta
= ImplSlide( ImplCalcThumbPos( GetPointerPosPixel().X() ), bCallEndSlide
);
534 void Slider::ImplDoMouseAction( const Point
& rMousePos
, bool bCallAction
)
536 sal_uInt16 nOldStateFlags
= mnStateFlags
;
537 bool bAction
= false;
539 switch ( meScrollType
)
541 case ScrollType::Set
:
543 const bool bUp
= ImplIsPageUp( rMousePos
), bDown
= ImplIsPageDown( rMousePos
);
547 bAction
= bCallAction
;
548 mnStateFlags
|= ( bUp
? SLIDER_STATE_CHANNEL1_DOWN
: SLIDER_STATE_CHANNEL2_DOWN
);
551 mnStateFlags
&= ~( SLIDER_STATE_CHANNEL1_DOWN
| SLIDER_STATE_CHANNEL2_DOWN
);
555 case ScrollType::PageUp
:
556 if ( ImplIsPageUp( rMousePos
) )
558 bAction
= bCallAction
;
559 mnStateFlags
|= SLIDER_STATE_CHANNEL1_DOWN
;
562 mnStateFlags
&= ~SLIDER_STATE_CHANNEL1_DOWN
;
565 case ScrollType::PageDown
:
566 if ( ImplIsPageDown( rMousePos
) )
568 bAction
= bCallAction
;
569 mnStateFlags
|= SLIDER_STATE_CHANNEL2_DOWN
;
572 mnStateFlags
&= ~SLIDER_STATE_CHANNEL2_DOWN
;
580 if ( ImplDoAction( false ) )
586 else if ( nOldStateFlags
!= mnStateFlags
)
592 void Slider::ImplDoSlide( long nNewPos
)
594 if ( meScrollType
!= ScrollType::DontKnow
)
597 meScrollType
= ScrollType::Drag
;
598 ImplSlide( nNewPos
, true );
599 meScrollType
= ScrollType::DontKnow
;
602 void Slider::ImplDoSlideAction( ScrollType eScrollType
)
604 if ( (meScrollType
!= ScrollType::DontKnow
) ||
605 (eScrollType
== ScrollType::DontKnow
) ||
606 (eScrollType
== ScrollType::Drag
) )
609 meScrollType
= eScrollType
;
610 ImplDoAction( true );
611 meScrollType
= ScrollType::DontKnow
;
614 void Slider::MouseButtonDown( const MouseEvent
& rMEvt
)
616 if ( rMEvt
.IsLeft() )
618 const Point
& rMousePos
= rMEvt
.GetPosPixel();
619 StartTrackingFlags nTrackFlags
= StartTrackingFlags::NONE
;
621 if ( maThumbRect
.IsInside( rMousePos
) )
623 meScrollType
= ScrollType::Drag
;
625 // calculate additional values
626 Point aCenterPos
= maThumbRect
.Center();
627 if ( GetStyle() & WB_HORZ
)
628 mnMouseOff
= rMousePos
.X()-aCenterPos
.X();
630 mnMouseOff
= rMousePos
.Y()-aCenterPos
.Y();
632 else if ( ImplIsPageUp( rMousePos
) )
634 if( GetStyle() & WB_SLIDERSET
)
635 meScrollType
= ScrollType::Set
;
638 nTrackFlags
= StartTrackingFlags::ButtonRepeat
;
639 meScrollType
= ScrollType::PageUp
;
642 else if ( ImplIsPageDown( rMousePos
) )
644 if( GetStyle() & WB_SLIDERSET
)
645 meScrollType
= ScrollType::Set
;
648 nTrackFlags
= StartTrackingFlags::ButtonRepeat
;
649 meScrollType
= ScrollType::PageDown
;
653 // Shall we start Tracking?
654 if( meScrollType
!= ScrollType::DontKnow
)
656 // store Start position for cancel and EndScroll delta
657 mnStartPos
= mnThumbPos
;
658 ImplDoMouseAction( rMousePos
, meScrollType
!= ScrollType::Set
);
661 if( meScrollType
!= ScrollType::Set
)
662 StartTracking( nTrackFlags
);
667 void Slider::MouseButtonUp( const MouseEvent
& )
669 if( ScrollType::Set
== meScrollType
)
671 // reset Button and PageRect state
672 const sal_uInt16 nOldStateFlags
= mnStateFlags
;
674 mnStateFlags
&= ~( SLIDER_STATE_CHANNEL1_DOWN
| SLIDER_STATE_CHANNEL2_DOWN
| SLIDER_STATE_THUMB_DOWN
);
676 if ( nOldStateFlags
!= mnStateFlags
)
678 Invalidate(InvalidateFlags::NoChildren
| InvalidateFlags::NoErase
);
680 ImplDoAction( true );
681 meScrollType
= ScrollType::DontKnow
;
685 void Slider::Tracking( const TrackingEvent
& rTEvt
)
687 if ( rTEvt
.IsTrackingEnded() )
689 // reset Button and PageRect state
690 sal_uInt16 nOldStateFlags
= mnStateFlags
;
691 mnStateFlags
&= ~(SLIDER_STATE_CHANNEL1_DOWN
| SLIDER_STATE_CHANNEL2_DOWN
|
692 SLIDER_STATE_THUMB_DOWN
);
693 if ( nOldStateFlags
!= mnStateFlags
)
695 Invalidate(InvalidateFlags::NoChildren
| InvalidateFlags::NoErase
);
698 // on cancel, reset the previous Thumb position
699 if ( rTEvt
.IsTrackingCanceled() )
701 long nOldPos
= mnThumbPos
;
702 SetThumbPos( mnStartPos
);
703 mnDelta
= mnThumbPos
-nOldPos
;
707 if ( meScrollType
== ScrollType::Drag
)
709 // after dragging, recalculate to a rounded Thumb position
713 if ( !mbFullDrag
&& (mnStartPos
!= mnThumbPos
) )
715 mnDelta
= mnThumbPos
-mnStartPos
;
721 mnDelta
= mnThumbPos
-mnStartPos
;
724 meScrollType
= ScrollType::DontKnow
;
728 const Point rMousePos
= rTEvt
.GetMouseEvent().GetPosPixel();
730 // special handling for dragging
731 if ( meScrollType
== ScrollType::Drag
)
734 Point aCenterPos
= maThumbRect
.Center();
735 if ( GetStyle() & WB_HORZ
)
736 nMovePix
= rMousePos
.X()-(aCenterPos
.X()+mnMouseOff
);
738 nMovePix
= rMousePos
.Y()-(aCenterPos
.Y()+mnMouseOff
);
739 // only if the mouse moves in Scroll direction we have to act
742 mnThumbPixPos
+= nMovePix
;
743 if ( mnThumbPixPos
< mnThumbPixOffset
)
744 mnThumbPixPos
= mnThumbPixOffset
;
745 if ( mnThumbPixPos
> (mnThumbPixOffset
+mnThumbPixRange
-1) )
746 mnThumbPixPos
= mnThumbPixOffset
+mnThumbPixRange
-1;
747 long nOldPos
= mnThumbPos
;
748 mnThumbPos
= ImplCalcThumbPos( mnThumbPixPos
);
749 if ( nOldPos
!= mnThumbPos
)
753 ImplUpdateLinkedField();
754 if ( mbFullDrag
&& (nOldPos
!= mnThumbPos
) )
756 mnDelta
= mnThumbPos
-nOldPos
;
764 ImplDoMouseAction( rMousePos
, rTEvt
.IsTrackingRepeat() );
766 // end tracking if ScrollBar values indicate we are done
772 void Slider::KeyInput( const KeyEvent
& rKEvt
)
774 if ( !rKEvt
.GetKeyCode().GetModifier() )
776 switch ( rKEvt
.GetKeyCode().GetCode() )
779 ImplDoSlide( GetRangeMin() );
782 ImplDoSlide( GetRangeMax() );
787 ImplDoSlideAction( ScrollType::LineUp
);
792 ImplDoSlideAction( ScrollType::LineDown
);
796 ImplDoSlideAction( ScrollType::PageUp
);
800 ImplDoSlideAction( ScrollType::PageDown
);
804 Control::KeyInput( rKEvt
);
809 Control::KeyInput( rKEvt
);
812 void Slider::Paint(vcl::RenderContext
& rRenderContext
, const Rectangle
& /*rRect*/)
814 ImplDraw(rRenderContext
);
817 void Slider::Resize()
821 if ( IsReallyVisible() )
823 Invalidate(InvalidateFlags::NoChildren
| InvalidateFlags::NoErase
);
826 void Slider::SetLinkedField(VclPtr
<NumericField
> const & pField
)
830 mpLinkedField
->SetModifyHdl(Link
<Edit
&,void>());
831 mpLinkedField
->SetUpHdl(Link
<SpinField
&,void>());
832 mpLinkedField
->SetDownHdl(Link
<SpinField
&,void>());
833 mpLinkedField
->SetFirstHdl(Link
<SpinField
&,void>());
834 mpLinkedField
->SetLastHdl(Link
<SpinField
&,void>());
835 mpLinkedField
->SetLoseFocusHdl(Link
<Control
&,void>());
837 mpLinkedField
= pField
;
840 mpLinkedField
->SetModifyHdl(LINK(this, Slider
, LinkedFieldModifyHdl
));
841 mpLinkedField
->SetUpHdl(LINK(this, Slider
, LinkedFieldSpinnerHdl
));
842 mpLinkedField
->SetDownHdl(LINK(this, Slider
, LinkedFieldSpinnerHdl
));
843 mpLinkedField
->SetFirstHdl(LINK(this, Slider
, LinkedFieldSpinnerHdl
));
844 mpLinkedField
->SetLastHdl(LINK(this, Slider
, LinkedFieldSpinnerHdl
));
845 mpLinkedField
->SetLoseFocusHdl(LINK(this, Slider
, LinkedFieldLoseFocusHdl
));
849 IMPL_LINK_NOARG(Slider
, LinkedFieldSpinnerHdl
, SpinField
&, void)
852 SetThumbPos(mpLinkedField
->GetValue());
854 IMPL_LINK_NOARG(Slider
, LinkedFieldLoseFocusHdl
, Control
&, void)
857 SetThumbPos(mpLinkedField
->GetValue());
859 IMPL_LINK_NOARG(Slider
, LinkedFieldModifyHdl
, Edit
&, void)
862 SetThumbPos(mpLinkedField
->GetValue());
865 void Slider::StateChanged( StateChangedType nType
)
867 Control::StateChanged( nType
);
869 if ( nType
== StateChangedType::InitShow
)
871 else if ( nType
== StateChangedType::Data
)
873 if ( IsReallyVisible() && IsUpdateMode() )
876 else if ( nType
== StateChangedType::UpdateMode
)
878 if ( IsReallyVisible() && IsUpdateMode() )
884 else if ( nType
== StateChangedType::Enable
)
886 if ( IsReallyVisible() && IsUpdateMode() )
891 else if ( nType
== StateChangedType::Style
)
893 if ( IsReallyVisible() && IsUpdateMode() )
895 if ( (GetPrevStyle() & SLIDER_VIEW_STYLE
) !=
896 (GetStyle() & SLIDER_VIEW_STYLE
) )
904 else if ( nType
== StateChangedType::ControlBackground
)
911 void Slider::DataChanged( const DataChangedEvent
& rDCEvt
)
913 Control::DataChanged( rDCEvt
);
915 if ( (rDCEvt
.GetType() == DataChangedEventType::SETTINGS
) &&
916 (rDCEvt
.GetFlags() & AllSettingsFlags::STYLE
) )
925 maSlideHdl
.Call( this );
928 void Slider::EndSlide()
930 maEndSlideHdl
.Call( this );
933 void Slider::SetRangeMin(long nNewRange
)
935 SetRange(Range(nNewRange
, GetRangeMax()));
938 void Slider::SetRangeMax(long nNewRange
)
940 SetRange(Range(GetRangeMin(), nNewRange
));
943 void Slider::SetRange( const Range
& rRange
)
946 Range aRange
= rRange
;
948 long nNewMinRange
= aRange
.Min();
949 long nNewMaxRange
= aRange
.Max();
951 // reset Range if different
952 if ( (mnMinRange
!= nNewMinRange
) ||
953 (mnMaxRange
!= nNewMaxRange
) )
955 mnMinRange
= nNewMinRange
;
956 mnMaxRange
= nNewMaxRange
;
959 if ( mnThumbPos
> mnMaxRange
)
960 mnThumbPos
= mnMaxRange
;
961 if ( mnThumbPos
< mnMinRange
)
962 mnThumbPos
= mnMinRange
;
963 ImplUpdateLinkedField();
964 CompatStateChanged( StateChangedType::Data
);
968 void Slider::SetThumbPos( long nNewThumbPos
)
970 if ( nNewThumbPos
< mnMinRange
)
971 nNewThumbPos
= mnMinRange
;
972 if ( nNewThumbPos
> mnMaxRange
)
973 nNewThumbPos
= mnMaxRange
;
975 if ( mnThumbPos
!= nNewThumbPos
)
977 mnThumbPos
= nNewThumbPos
;
978 ImplUpdateLinkedField();
979 CompatStateChanged( StateChangedType::Data
);
983 Size
Slider::CalcWindowSizePixel()
985 long nWidth
= mnMaxRange
-mnMinRange
+(SLIDER_THUMB_HALFSIZE
*2)+1;
986 long nHeight
= SLIDER_HEIGHT
;
988 if ( GetStyle() & WB_HORZ
)
990 aSize
.Width() = nWidth
;
991 aSize
.Height() = nHeight
;
995 aSize
.Height() = nWidth
;
996 aSize
.Width() = nHeight
;
1001 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */