Simplify using designated initializers
[LibreOffice.git] / vcl / source / control / slider.cxx
blob3a119ea4f5e5e448a2198c1d851f4df34a1b4108
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <slider.hxx>
23 #include <vcl/settings.hxx>
25 #include "thumbpos.hxx"
27 #define SLIDER_STATE_CHANNEL1_DOWN (sal_uInt16(0x0001))
28 #define SLIDER_STATE_CHANNEL2_DOWN (sal_uInt16(0x0002))
29 #define SLIDER_STATE_THUMB_DOWN (sal_uInt16(0x0004))
31 #define SLIDER_THUMB_SIZE 9
32 #define SLIDER_CHANNEL_SIZE 4
33 #define SLIDER_CHANNEL_HALFSIZE 2
35 #define SLIDER_HEIGHT 16
37 #define SLIDER_VIEW_STYLE (WB_3DLOOK | WB_HORZ | WB_VERT)
39 void Slider::ImplInit( vcl::Window* pParent, WinBits nStyle )
41 mnThumbPixOffset = 0;
42 mnThumbPixRange = 0;
43 mnThumbPixPos = 0; // between mnThumbPixOffset and mnThumbPixOffset+mnThumbPixRange
44 mnThumbSize = SLIDER_THUMB_SIZE;
45 mnChannelPixRange = 0;
46 mnChannelPixTop = 0;
47 mnChannelPixBottom = 0;
49 mnMinRange = 0;
50 mnMaxRange = 100;
51 mnThumbPos = 0;
52 mnLineSize = 1;
53 mnPageSize = 1;
54 mnStateFlags = 0;
55 meScrollType = ScrollType::DontKnow;
56 mbCalcSize = true;
58 Control::ImplInit( pParent, nStyle, nullptr );
60 ImplInitSettings();
61 SetSizePixel( CalcWindowSizePixel() );
64 Slider::Slider( vcl::Window* pParent, WinBits nStyle ) :
65 Control(WindowType::SLIDER)
67 ImplInit( pParent, nStyle );
70 Slider::~Slider()
72 disposeOnce();
75 void Slider::ImplInitSettings()
77 vcl::Window* pParent = GetParent();
78 if ( pParent->IsChildTransparentModeEnabled() && !IsControlBackground() )
80 EnableChildTransparentMode();
81 SetParentClipMode( ParentClipMode::NoClip );
82 SetPaintTransparent( true );
83 SetBackground();
85 else
87 EnableChildTransparentMode( false );
88 SetParentClipMode();
89 SetPaintTransparent( false );
91 if ( IsControlBackground() )
92 SetBackground( GetControlBackground() );
93 else
94 SetBackground( pParent->GetBackground() );
98 void Slider::ImplUpdateRects( bool bUpdate )
100 tools::Rectangle aOldThumbRect = maThumbRect;
101 bool bInvalidateAll = false;
103 if ( mnThumbPixRange )
105 if ( GetStyle() & WB_HORZ )
107 maThumbRect.SetLeft(mnThumbPixPos - (mnThumbSize / 2));
108 maThumbRect.SetRight(maThumbRect.Left() + mnThumbSize - 1);
109 if ( 0 < maThumbRect.Left() )
111 maChannel1Rect.SetLeft( 0 );
112 maChannel1Rect.SetRight( maThumbRect.Left()-1 );
113 maChannel1Rect.SetTop( mnChannelPixTop );
114 maChannel1Rect.SetBottom( mnChannelPixBottom );
116 else
117 maChannel1Rect.SetEmpty();
118 if ( mnChannelPixRange-1 > maThumbRect.Right() )
120 maChannel2Rect.SetLeft( maThumbRect.Right()+1 );
121 maChannel2Rect.SetRight( mnChannelPixRange-1 );
122 maChannel2Rect.SetTop( mnChannelPixTop );
123 maChannel2Rect.SetBottom( mnChannelPixBottom );
125 else
126 maChannel2Rect.SetEmpty();
128 const tools::Rectangle aControlRegion(tools::Rectangle(Point(), Size(mnThumbSize, 10)));
129 tools::Rectangle aThumbBounds, aThumbContent;
130 if ( GetNativeControlRegion( ControlType::Slider, ControlPart::ThumbHorz,
131 aControlRegion, ControlState::NONE, ImplControlValue(),
132 aThumbBounds, aThumbContent ) )
134 maThumbRect.SetLeft( mnThumbPixPos - aThumbBounds.GetWidth()/2 );
135 maThumbRect.SetRight( maThumbRect.Left() + aThumbBounds.GetWidth() - 1 );
136 bInvalidateAll = true;
139 else
141 maThumbRect.SetTop( mnThumbPixPos - (mnThumbSize / 2));
142 maThumbRect.SetBottom( maThumbRect.Top() + mnThumbSize - 1);
143 if ( 0 < maThumbRect.Top() )
145 maChannel1Rect.SetTop( 0 );
146 maChannel1Rect.SetBottom( maThumbRect.Top()-1 );
147 maChannel1Rect.SetLeft( mnChannelPixTop );
148 maChannel1Rect.SetRight( mnChannelPixBottom );
150 else
151 maChannel1Rect.SetEmpty();
152 if ( mnChannelPixRange-1 > maThumbRect.Bottom() )
154 maChannel2Rect.SetTop( maThumbRect.Bottom()+1 );
155 maChannel2Rect.SetBottom( mnChannelPixRange-1 );
156 maChannel2Rect.SetLeft( mnChannelPixTop );
157 maChannel2Rect.SetRight( mnChannelPixBottom );
159 else
160 maChannel2Rect.SetEmpty();
162 const tools::Rectangle aControlRegion(tools::Rectangle(Point(), Size(10, mnThumbSize)));
163 tools::Rectangle aThumbBounds, aThumbContent;
164 if ( GetNativeControlRegion( ControlType::Slider, ControlPart::ThumbVert,
165 aControlRegion, ControlState::NONE, ImplControlValue(),
166 aThumbBounds, aThumbContent ) )
168 maThumbRect.SetTop( mnThumbPixPos - aThumbBounds.GetHeight()/2 );
169 maThumbRect.SetBottom( maThumbRect.Top() + aThumbBounds.GetHeight() - 1 );
170 bInvalidateAll = true;
174 else
176 maChannel1Rect.SetEmpty();
177 maChannel2Rect.SetEmpty();
178 maThumbRect.SetEmpty();
181 if ( !bUpdate )
182 return;
184 if ( aOldThumbRect == maThumbRect )
185 return;
187 if( bInvalidateAll )
188 Invalidate(InvalidateFlags::NoChildren | InvalidateFlags::NoErase);
189 else
191 vcl::Region aInvalidRegion( aOldThumbRect );
192 aInvalidRegion.Union( maThumbRect );
194 if( !IsBackground() && GetParent() )
196 const Point aPos( GetPosPixel() );
197 aInvalidRegion.Move( aPos.X(), aPos.Y() );
198 GetParent()->Invalidate( aInvalidRegion, InvalidateFlags::Transparent | InvalidateFlags::Update );
200 else
201 Invalidate( aInvalidRegion );
205 tools::Long Slider::ImplCalcThumbPos( tools::Long nPixPos ) const
207 // calculate position
208 tools::Long nCalcThumbPos;
209 nCalcThumbPos = ImplMulDiv( nPixPos-mnThumbPixOffset, mnMaxRange-mnMinRange, mnThumbPixRange-1 );
210 nCalcThumbPos += mnMinRange;
211 return nCalcThumbPos;
214 tools::Long Slider::ImplCalcThumbPosPix( tools::Long nPos ) const
216 // calculate position
217 tools::Long nCalcThumbPos;
218 nCalcThumbPos = ImplMulDiv( nPos-mnMinRange, mnThumbPixRange-1, mnMaxRange-mnMinRange );
219 // at the beginning and end we try to display Slider correctly
220 if ( !nCalcThumbPos && (mnThumbPos > mnMinRange) )
221 nCalcThumbPos = 1;
222 if ( nCalcThumbPos &&
223 (nCalcThumbPos == mnThumbPixRange-1) &&
224 (mnThumbPos < mnMaxRange) )
225 nCalcThumbPos--;
226 return nCalcThumbPos+mnThumbPixOffset;
229 void Slider::ImplCalc( bool bUpdate )
231 bool bInvalidateAll = false;
233 if (mbCalcSize)
235 if (GetStyle() & WB_HORZ)
237 const tools::Rectangle aControlRegion(tools::Rectangle(Point(), Size(SLIDER_THUMB_SIZE, 10)));
238 tools::Rectangle aThumbBounds, aThumbContent;
239 if (GetNativeControlRegion(ControlType::Slider, ControlPart::ThumbHorz,
240 aControlRegion, ControlState::NONE, ImplControlValue(),
241 aThumbBounds, aThumbContent))
243 mnThumbSize = aThumbBounds.GetWidth();
245 else
247 mnThumbSize = SLIDER_THUMB_SIZE;
250 else
252 const tools::Rectangle aControlRegion(tools::Rectangle(Point(), Size(10, SLIDER_THUMB_SIZE)));
253 tools::Rectangle aThumbBounds, aThumbContent;
254 if (GetNativeControlRegion( ControlType::Slider, ControlPart::ThumbVert,
255 aControlRegion, ControlState::NONE, ImplControlValue(),
256 aThumbBounds, aThumbContent))
258 mnThumbSize = aThumbBounds.GetHeight();
260 else
262 mnThumbSize = SLIDER_THUMB_SIZE;
266 tools::Long nOldChannelPixRange = mnChannelPixRange;
267 tools::Long nOldChannelPixTop = mnChannelPixTop;
268 tools::Long nOldChannelPixBottom = mnChannelPixBottom;
269 tools::Long nCalcWidth;
270 tools::Long nCalcHeight;
272 maChannel1Rect.SetEmpty();
273 maChannel2Rect.SetEmpty();
274 maThumbRect.SetEmpty();
276 Size aSize = GetOutputSizePixel();
277 if ( GetStyle() & WB_HORZ )
279 nCalcWidth = aSize.Width();
280 nCalcHeight = aSize.Height();
281 maThumbRect.SetTop( 0 );
282 maThumbRect.SetBottom( aSize.Height()-1 );
284 else
286 nCalcWidth = aSize.Height();
287 nCalcHeight = aSize.Width();
288 maThumbRect.SetLeft( 0 );
289 maThumbRect.SetRight( aSize.Width()-1 );
292 if (nCalcWidth >= mnThumbSize)
294 mnThumbPixOffset = mnThumbSize / 2;
295 mnThumbPixRange = nCalcWidth - mnThumbSize;
296 mnThumbPixPos = 0;
297 mnChannelPixRange = nCalcWidth;
298 mnChannelPixTop = (nCalcHeight/2)-SLIDER_CHANNEL_HALFSIZE;
299 mnChannelPixBottom = mnChannelPixTop+SLIDER_CHANNEL_SIZE-1;
301 else
303 mnThumbPixRange = 0;
304 mnChannelPixRange = 0;
307 if ( (nOldChannelPixRange != mnChannelPixRange) ||
308 (nOldChannelPixTop != mnChannelPixTop) ||
309 (nOldChannelPixBottom != mnChannelPixBottom) )
310 bInvalidateAll = true;
312 mbCalcSize = false;
315 if ( mnThumbPixRange )
316 mnThumbPixPos = ImplCalcThumbPosPix( mnThumbPos );
318 if ( bUpdate && bInvalidateAll )
320 Invalidate();
321 bUpdate = false;
323 ImplUpdateRects( bUpdate );
326 void Slider::ImplDraw(vcl::RenderContext& rRenderContext)
328 // do missing calculations
329 if (mbCalcSize)
330 ImplCalc(false);
332 ControlPart nPart = (GetStyle() & WB_HORZ) ? ControlPart::TrackHorzArea : ControlPart::TrackVertArea;
334 if (rRenderContext.IsNativeControlSupported(ControlType::Slider, nPart))
336 ControlState nState = (IsEnabled() ? ControlState::ENABLED : ControlState::NONE);
337 nState |= (HasFocus() ? ControlState::FOCUSED : ControlState::NONE);
339 SliderValue aSliderValue;
340 aSliderValue.mnMin = mnMinRange;
341 aSliderValue.mnMax = mnMaxRange;
342 aSliderValue.mnCur = mnThumbPos;
343 aSliderValue.maThumbRect = maThumbRect;
345 if (IsMouseOver())
347 if (maThumbRect.Contains(GetPointerPosPixel()))
348 aSliderValue.mnThumbState |= ControlState::ROLLOVER;
351 const tools::Rectangle aCtrlRegion(Point(0,0), GetOutputSizePixel());
353 if (rRenderContext.DrawNativeControl(ControlType::Slider, nPart, aCtrlRegion, nState, aSliderValue, OUString()))
354 return;
357 DecorationView aDecoView(&rRenderContext);
358 const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
359 bool bEnabled = IsEnabled();
361 if (!maChannel1Rect.IsEmpty())
363 tools::Long nRectSize;
364 tools::Rectangle aRect = maChannel1Rect;
365 rRenderContext.SetLineColor(rStyleSettings.GetShadowColor());
366 if (GetStyle() & WB_HORZ)
368 rRenderContext.DrawLine(aRect.TopLeft(), Point(aRect.Left(), aRect.Bottom() - 1));
369 rRenderContext.DrawLine(aRect.TopLeft(), aRect.TopRight());
371 else
373 rRenderContext.DrawLine(aRect.TopLeft(), Point(aRect.Right() - 1, aRect.Top()));
374 rRenderContext.DrawLine(aRect.TopLeft(), aRect.BottomLeft());
376 rRenderContext.SetLineColor(rStyleSettings.GetLightColor());
377 if (GetStyle() & WB_HORZ)
379 rRenderContext.DrawLine(aRect.BottomLeft(), aRect.BottomRight());
380 nRectSize = aRect.GetWidth();
382 else
384 rRenderContext.DrawLine(aRect.TopRight(), aRect.BottomRight());
385 nRectSize = aRect.GetHeight();
388 if (nRectSize > 1)
390 aRect.AdjustLeft( 1 );
391 aRect.AdjustTop( 1 );
392 if (GetStyle() & WB_HORZ)
393 aRect.AdjustBottom( -1 );
394 else
395 aRect.AdjustRight( -1 );
396 rRenderContext.SetLineColor();
397 if (mnStateFlags & SLIDER_STATE_CHANNEL1_DOWN)
398 rRenderContext.SetFillColor(rStyleSettings.GetShadowColor());
399 else
400 rRenderContext.SetFillColor(rStyleSettings.GetCheckedColor());
401 rRenderContext.DrawRect(aRect);
405 if (!maChannel2Rect.IsEmpty())
407 tools::Long nRectSize;
408 tools::Rectangle aRect = maChannel2Rect;
409 rRenderContext.SetLineColor(rStyleSettings.GetLightColor());
410 if (GetStyle() & WB_HORZ)
412 rRenderContext.DrawLine(aRect.TopRight(), aRect.BottomRight());
413 rRenderContext.DrawLine(aRect.BottomLeft(), aRect.BottomRight());
414 nRectSize = aRect.GetWidth();
416 else
418 rRenderContext.DrawLine(aRect.BottomLeft(), aRect.BottomRight());
419 rRenderContext.DrawLine(aRect.TopRight(), aRect.BottomRight());
420 nRectSize = aRect.GetHeight();
423 if (nRectSize > 1)
425 rRenderContext.SetLineColor(rStyleSettings.GetShadowColor());
426 if (GetStyle() & WB_HORZ)
427 rRenderContext.DrawLine(aRect.TopLeft(), Point(aRect.Right() - 1, aRect.Top()));
428 else
429 rRenderContext.DrawLine(aRect.TopLeft(), Point(aRect.Left(), aRect.Bottom() - 1));
431 aRect.AdjustRight( -1 );
432 aRect.AdjustBottom( -1 );
433 if (GetStyle() & WB_HORZ)
434 aRect.AdjustTop( 1 );
435 else
436 aRect.AdjustLeft( 1 );
437 rRenderContext.SetLineColor();
438 if (mnStateFlags & SLIDER_STATE_CHANNEL2_DOWN)
439 rRenderContext.SetFillColor(rStyleSettings.GetShadowColor());
440 else
441 rRenderContext.SetFillColor(rStyleSettings.GetCheckedColor());
442 rRenderContext.DrawRect(aRect);
446 if (maThumbRect.IsEmpty())
447 return;
449 if (bEnabled)
451 DrawButtonFlags nStyle = DrawButtonFlags::NONE;
452 if (mnStateFlags & SLIDER_STATE_THUMB_DOWN)
453 nStyle |= DrawButtonFlags::Pressed;
454 aDecoView.DrawButton(maThumbRect, nStyle);
456 else
458 rRenderContext.SetLineColor(rStyleSettings.GetShadowColor());
459 rRenderContext.SetFillColor(rStyleSettings.GetCheckedColor());
460 rRenderContext.DrawRect(maThumbRect);
464 bool Slider::ImplIsPageUp( const Point& rPos ) const
466 Size aSize = GetOutputSizePixel();
467 tools::Rectangle aRect = maChannel1Rect;
468 if ( GetStyle() & WB_HORZ )
470 aRect.SetTop( 0 );
471 aRect.SetBottom( aSize.Height()-1 );
473 else
475 aRect.SetLeft( 0 );
476 aRect.SetRight( aSize.Width()-1 );
478 return aRect.Contains( rPos );
481 bool Slider::ImplIsPageDown( const Point& rPos ) const
483 Size aSize = GetOutputSizePixel();
484 tools::Rectangle aRect = maChannel2Rect;
485 if ( GetStyle() & WB_HORZ )
487 aRect.SetTop( 0 );
488 aRect.SetBottom( aSize.Height()-1 );
490 else
492 aRect.SetLeft( 0 );
493 aRect.SetRight( aSize.Width()-1 );
495 return aRect.Contains( rPos );
498 tools::Long Slider::ImplSlide( tools::Long nNewPos )
500 tools::Long nOldPos = mnThumbPos;
501 SetThumbPos( nNewPos );
502 tools::Long nDelta = mnThumbPos-nOldPos;
503 if ( nDelta )
505 Slide();
507 return nDelta;
510 tools::Long Slider::ImplDoAction()
512 tools::Long nDelta = 0;
514 switch ( meScrollType )
516 case ScrollType::LineUp:
517 nDelta = ImplSlide( mnThumbPos-mnLineSize );
518 break;
520 case ScrollType::LineDown:
521 nDelta = ImplSlide( mnThumbPos+mnLineSize );
522 break;
524 case ScrollType::PageUp:
525 nDelta = ImplSlide( mnThumbPos-mnPageSize );
526 break;
528 case ScrollType::PageDown:
529 nDelta = ImplSlide( mnThumbPos+mnPageSize );
530 break;
532 default:
533 break;
536 return nDelta;
539 void Slider::ImplDoMouseAction( const Point& rMousePos, bool bCallAction )
541 sal_uInt16 nOldStateFlags = mnStateFlags;
542 bool bAction = false;
544 switch ( meScrollType )
546 case ScrollType::PageUp:
547 if ( ImplIsPageUp( rMousePos ) )
549 bAction = bCallAction;
550 mnStateFlags |= SLIDER_STATE_CHANNEL1_DOWN;
552 else
553 mnStateFlags &= ~SLIDER_STATE_CHANNEL1_DOWN;
554 break;
556 case ScrollType::PageDown:
557 if ( ImplIsPageDown( rMousePos ) )
559 bAction = bCallAction;
560 mnStateFlags |= SLIDER_STATE_CHANNEL2_DOWN;
562 else
563 mnStateFlags &= ~SLIDER_STATE_CHANNEL2_DOWN;
564 break;
565 default:
566 break;
569 if ( bAction )
571 if ( ImplDoAction() )
573 Invalidate();
576 else if ( nOldStateFlags != mnStateFlags )
578 Invalidate();
582 void Slider::ImplDoSlide( tools::Long nNewPos )
584 if ( meScrollType != ScrollType::DontKnow )
585 return;
587 meScrollType = ScrollType::Drag;
588 ImplSlide( nNewPos );
589 meScrollType = ScrollType::DontKnow;
592 void Slider::ImplDoSlideAction( ScrollType eScrollType )
594 if ( (meScrollType != ScrollType::DontKnow) ||
595 (eScrollType == ScrollType::DontKnow) ||
596 (eScrollType == ScrollType::Drag) )
597 return;
599 meScrollType = eScrollType;
600 ImplDoAction();
601 meScrollType = ScrollType::DontKnow;
604 void Slider::MouseButtonDown( const MouseEvent& rMEvt )
606 if ( !rMEvt.IsLeft() )
607 return;
609 const Point& rMousePos = rMEvt.GetPosPixel();
610 StartTrackingFlags nTrackFlags = StartTrackingFlags::NONE;
612 if ( maThumbRect.Contains( rMousePos ) )
614 meScrollType = ScrollType::Drag;
616 // calculate additional values
617 Point aCenterPos = maThumbRect.Center();
618 if ( GetStyle() & WB_HORZ )
619 mnMouseOff = rMousePos.X()-aCenterPos.X();
620 else
621 mnMouseOff = rMousePos.Y()-aCenterPos.Y();
623 else if ( ImplIsPageUp( rMousePos ) )
625 nTrackFlags = StartTrackingFlags::ButtonRepeat;
626 meScrollType = ScrollType::PageUp;
628 else if ( ImplIsPageDown( rMousePos ) )
630 nTrackFlags = StartTrackingFlags::ButtonRepeat;
631 meScrollType = ScrollType::PageDown;
634 // Shall we start Tracking?
635 if( meScrollType != ScrollType::DontKnow )
637 // store Start position for cancel and EndScroll delta
638 mnStartPos = mnThumbPos;
639 ImplDoMouseAction( rMousePos, /*bCallAction*/true );
640 PaintImmediately();
642 StartTracking( nTrackFlags );
646 void Slider::MouseButtonUp( const MouseEvent& )
650 void Slider::Tracking( const TrackingEvent& rTEvt )
652 if ( rTEvt.IsTrackingEnded() )
654 // reset Button and PageRect state
655 sal_uInt16 nOldStateFlags = mnStateFlags;
656 mnStateFlags &= ~(SLIDER_STATE_CHANNEL1_DOWN | SLIDER_STATE_CHANNEL2_DOWN |
657 SLIDER_STATE_THUMB_DOWN);
658 if ( nOldStateFlags != mnStateFlags )
660 Invalidate(InvalidateFlags::NoChildren | InvalidateFlags::NoErase);
663 // on cancel, reset the previous Thumb position
664 if ( rTEvt.IsTrackingCanceled() )
666 SetThumbPos( mnStartPos );
667 Slide();
670 if ( meScrollType == ScrollType::Drag )
672 // after dragging, recalculate to a rounded Thumb position
673 ImplCalc();
674 PaintImmediately();
677 meScrollType = ScrollType::DontKnow;
679 else
681 const Point rMousePos = rTEvt.GetMouseEvent().GetPosPixel();
683 // special handling for dragging
684 if ( meScrollType == ScrollType::Drag )
686 tools::Long nMovePix;
687 Point aCenterPos = maThumbRect.Center();
688 if ( GetStyle() & WB_HORZ )
689 nMovePix = rMousePos.X()-(aCenterPos.X()+mnMouseOff);
690 else
691 nMovePix = rMousePos.Y()-(aCenterPos.Y()+mnMouseOff);
692 // only if the mouse moves in Scroll direction we have to act
693 if ( nMovePix )
695 mnThumbPixPos += nMovePix;
696 if ( mnThumbPixPos < mnThumbPixOffset )
697 mnThumbPixPos = mnThumbPixOffset;
698 if ( mnThumbPixPos > (mnThumbPixOffset+mnThumbPixRange-1) )
699 mnThumbPixPos = mnThumbPixOffset+mnThumbPixRange-1;
700 tools::Long nOldPos = mnThumbPos;
701 mnThumbPos = ImplCalcThumbPos( mnThumbPixPos );
702 if ( nOldPos != mnThumbPos )
704 ImplUpdateRects();
705 PaintImmediately();
706 if ( nOldPos != mnThumbPos )
708 Slide();
713 else
714 ImplDoMouseAction( rMousePos, rTEvt.IsTrackingRepeat() );
716 // end tracking if ScrollBar values indicate we are done
717 if ( !IsVisible() )
718 EndTracking();
722 void Slider::KeyInput( const KeyEvent& rKEvt )
724 if ( !rKEvt.GetKeyCode().GetModifier() )
726 switch ( rKEvt.GetKeyCode().GetCode() )
728 case KEY_HOME:
729 ImplDoSlide( GetRangeMin() );
730 break;
731 case KEY_END:
732 ImplDoSlide( GetRangeMax() );
733 break;
735 case KEY_LEFT:
736 case KEY_UP:
737 ImplDoSlideAction( ScrollType::LineUp );
738 break;
740 case KEY_RIGHT:
741 case KEY_DOWN:
742 ImplDoSlideAction( ScrollType::LineDown );
743 break;
745 case KEY_PAGEUP:
746 ImplDoSlideAction( ScrollType::PageUp );
747 break;
749 case KEY_PAGEDOWN:
750 ImplDoSlideAction( ScrollType::PageDown );
751 break;
753 default:
754 Control::KeyInput( rKEvt );
755 break;
758 else
759 Control::KeyInput( rKEvt );
762 void Slider::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& /*rRect*/)
764 ImplDraw(rRenderContext);
767 void Slider::Resize()
769 Control::Resize();
770 mbCalcSize = true;
771 if ( IsReallyVisible() )
772 ImplCalc( false );
773 Invalidate(InvalidateFlags::NoChildren | InvalidateFlags::NoErase);
776 void Slider::StateChanged( StateChangedType nType )
778 Control::StateChanged( nType );
780 if ( nType == StateChangedType::InitShow )
781 ImplCalc( false );
782 else if ( nType == StateChangedType::Data )
784 if ( IsReallyVisible() && IsUpdateMode() )
785 ImplCalc();
787 else if ( nType == StateChangedType::UpdateMode )
789 if ( IsReallyVisible() && IsUpdateMode() )
791 ImplCalc( false );
792 Invalidate();
795 else if ( nType == StateChangedType::Enable ||
796 nType == StateChangedType::ControlFocus )
798 if ( IsReallyVisible() && IsUpdateMode() )
800 Invalidate();
803 else if ( nType == StateChangedType::Style )
805 if ( IsReallyVisible() && IsUpdateMode() )
807 if ( (GetPrevStyle() & SLIDER_VIEW_STYLE) !=
808 (GetStyle() & SLIDER_VIEW_STYLE) )
810 mbCalcSize = true;
811 ImplCalc( false );
812 Invalidate();
816 else if ( nType == StateChangedType::ControlBackground )
818 ImplInitSettings();
819 Invalidate();
823 void Slider::DataChanged( const DataChangedEvent& rDCEvt )
825 Control::DataChanged( rDCEvt );
827 if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
828 (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) )
830 ImplInitSettings();
831 Invalidate();
835 void Slider::Slide()
837 maSlideHdl.Call( this );
840 void Slider::SetRangeMin(tools::Long nNewRange)
842 SetRange(Range(nNewRange, GetRangeMax()));
845 void Slider::SetRangeMax(tools::Long nNewRange)
847 SetRange(Range(GetRangeMin(), nNewRange));
850 void Slider::SetRange( const Range& rRange )
852 // adjust Range
853 Range aRange = rRange;
854 aRange.Normalize();
855 tools::Long nNewMinRange = aRange.Min();
856 tools::Long nNewMaxRange = aRange.Max();
858 // reset Range if different
859 if ( (mnMinRange != nNewMinRange) ||
860 (mnMaxRange != nNewMaxRange) )
862 mnMinRange = nNewMinRange;
863 mnMaxRange = nNewMaxRange;
865 // adjust Thumb
866 if ( mnThumbPos > mnMaxRange )
867 mnThumbPos = mnMaxRange;
868 if ( mnThumbPos < mnMinRange )
869 mnThumbPos = mnMinRange;
870 CompatStateChanged( StateChangedType::Data );
874 void Slider::SetThumbPos( tools::Long nNewThumbPos )
876 if ( nNewThumbPos < mnMinRange )
877 nNewThumbPos = mnMinRange;
878 if ( nNewThumbPos > mnMaxRange )
879 nNewThumbPos = mnMaxRange;
881 if ( mnThumbPos != nNewThumbPos )
883 mnThumbPos = nNewThumbPos;
884 CompatStateChanged( StateChangedType::Data );
888 Size Slider::CalcWindowSizePixel() const
890 tools::Long nWidth = mnMaxRange - mnMinRange + mnThumbSize + 1;
891 tools::Long nHeight = SLIDER_HEIGHT;
892 Size aSize;
893 if ( GetStyle() & WB_HORZ )
895 aSize.setWidth( nWidth );
896 aSize.setHeight( nHeight );
898 else
900 aSize.setHeight( nWidth );
901 aSize.setWidth( nHeight );
903 return aSize;
906 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */