Version 4.2.0.1, tag libreoffice-4.2.0.1
[LibreOffice.git] / vcl / source / control / slider.cxx
blobdf31de0311dcb60b8ea850bb60d715a7b768655c
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 .
21 #include <tools/rc.h>
22 #include <vcl/event.hxx>
23 #include <vcl/decoview.hxx>
24 #include <vcl/slider.hxx>
25 #include "thumbpos.hxx"
27 // =======================================================================
29 #define SLIDER_DRAW_THUMB ((sal_uInt16)0x0001)
30 #define SLIDER_DRAW_CHANNEL1 ((sal_uInt16)0x0002)
31 #define SLIDER_DRAW_CHANNEL2 ((sal_uInt16)0x0004)
32 #define SLIDER_DRAW_CHANNEL (SLIDER_DRAW_CHANNEL1 | SLIDER_DRAW_CHANNEL2)
33 #define SLIDER_DRAW_ALL (SLIDER_DRAW_THUMB | SLIDER_DRAW_CHANNEL)
35 #define SLIDER_STATE_CHANNEL1_DOWN ((sal_uInt16)0x0001)
36 #define SLIDER_STATE_CHANNEL2_DOWN ((sal_uInt16)0x0002)
37 #define SLIDER_STATE_THUMB_DOWN ((sal_uInt16)0x0004)
39 #define SLIDER_THUMB_SIZE 9
40 #define SLIDER_THUMB_HALFSIZE 4
41 #define SLIDER_CHANNEL_OFFSET 0
42 #define SLIDER_CHANNEL_SIZE 4
43 #define SLIDER_CHANNEL_HALFSIZE 2
45 #define SLIDER_HEIGHT 16
47 #define SLIDER_VIEW_STYLE (WB_3DLOOK | WB_HORZ | WB_VERT)
49 // =======================================================================
51 void Slider::ImplInit( Window* pParent, WinBits nStyle )
53 mnThumbPixOffset = 0;
54 mnThumbPixRange = 0;
55 mnThumbPixPos = 0; // between mnThumbPixOffset and mnThumbPixOffset+mnThumbPixRange
56 mnChannelPixOffset = 0;
57 mnChannelPixRange = 0;
58 mnChannelPixTop = 0;
59 mnChannelPixBottom = 0;
61 mnMinRange = 0;
62 mnMaxRange = 100;
63 mnThumbPos = 0;
64 mnLineSize = 1;
65 mnPageSize = 1;
66 mnDelta = 0;
67 mnDragDraw = 0;
68 mnStateFlags = 0;
69 meScrollType = SCROLL_DONTKNOW;
70 mbCalcSize = sal_True;
71 mbFullDrag = sal_True;
73 Control::ImplInit( pParent, nStyle, NULL );
75 ImplInitSettings();
76 SetSizePixel( CalcWindowSizePixel() );
79 // -----------------------------------------------------------------------
81 Slider::Slider( Window* pParent, WinBits nStyle ) :
82 Control( WINDOW_SLIDER )
84 ImplInit( pParent, nStyle );
87 // -----------------------------------------------------------------------
89 void Slider::ImplInitSettings()
91 Window* pParent = GetParent();
92 if ( pParent->IsChildTransparentModeEnabled() && !IsControlBackground() )
94 EnableChildTransparentMode( sal_True );
95 SetParentClipMode( PARENTCLIPMODE_NOCLIP );
96 SetPaintTransparent( sal_True );
97 SetBackground();
99 else
101 EnableChildTransparentMode( sal_False );
102 SetParentClipMode( 0 );
103 SetPaintTransparent( sal_False );
105 if ( IsControlBackground() )
106 SetBackground( GetControlBackground() );
107 else
108 SetBackground( pParent->GetBackground() );
112 // -----------------------------------------------------------------------
114 void Slider::ImplUpdateRects( sal_Bool bUpdate )
116 Rectangle aOldThumbRect = maThumbRect;
117 bool bInvalidateAll = false;
119 if ( mnThumbPixRange )
121 if ( GetStyle() & WB_HORZ )
123 maThumbRect.Left() = mnThumbPixPos-SLIDER_THUMB_HALFSIZE;
124 maThumbRect.Right() = maThumbRect.Left()+SLIDER_THUMB_SIZE-1;
125 if ( mnChannelPixOffset < maThumbRect.Left() )
127 maChannel1Rect.Left() = mnChannelPixOffset;
128 maChannel1Rect.Right() = maThumbRect.Left()-1;
129 maChannel1Rect.Top() = mnChannelPixTop;
130 maChannel1Rect.Bottom() = mnChannelPixBottom;
132 else
133 maChannel1Rect.SetEmpty();
134 if ( mnChannelPixOffset+mnChannelPixRange-1 > maThumbRect.Right() )
136 maChannel2Rect.Left() = maThumbRect.Right()+1;
137 maChannel2Rect.Right() = mnChannelPixOffset+mnChannelPixRange-1;
138 maChannel2Rect.Top() = mnChannelPixTop;
139 maChannel2Rect.Bottom() = mnChannelPixBottom;
141 else
142 maChannel2Rect.SetEmpty();
144 const Rectangle aControlRegion( Rectangle( Point(0,0), Size( SLIDER_THUMB_SIZE, 10 ) ) );
145 Rectangle aThumbBounds, aThumbContent;
146 if ( GetNativeControlRegion( CTRL_SLIDER, PART_THUMB_HORZ,
147 aControlRegion, 0, ImplControlValue(), OUString(),
148 aThumbBounds, aThumbContent ) )
150 maThumbRect.Left() = mnThumbPixPos - aThumbBounds.GetWidth()/2;
151 maThumbRect.Right() = maThumbRect.Left() + aThumbBounds.GetWidth() - 1;
152 bInvalidateAll = true;
155 else
157 maThumbRect.Top() = mnThumbPixPos-SLIDER_THUMB_HALFSIZE;
158 maThumbRect.Bottom() = maThumbRect.Top()+SLIDER_THUMB_SIZE-1;
159 if ( mnChannelPixOffset < maThumbRect.Top() )
161 maChannel1Rect.Top() = mnChannelPixOffset;
162 maChannel1Rect.Bottom() = maThumbRect.Top()-1;
163 maChannel1Rect.Left() = mnChannelPixTop;
164 maChannel1Rect.Right() = mnChannelPixBottom;
166 else
167 maChannel1Rect.SetEmpty();
168 if ( mnChannelPixOffset+mnChannelPixRange-1 > maThumbRect.Bottom() )
170 maChannel2Rect.Top() = maThumbRect.Bottom()+1;
171 maChannel2Rect.Bottom() = mnChannelPixOffset+mnChannelPixRange-1;
172 maChannel2Rect.Left() = mnChannelPixTop;
173 maChannel2Rect.Right() = mnChannelPixBottom;
175 else
176 maChannel2Rect.SetEmpty();
178 const Rectangle aControlRegion( Rectangle( Point(0,0), Size( 10, SLIDER_THUMB_SIZE ) ) );
179 Rectangle aThumbBounds, aThumbContent;
180 if ( GetNativeControlRegion( CTRL_SLIDER, PART_THUMB_VERT,
181 aControlRegion, 0, ImplControlValue(), OUString(),
182 aThumbBounds, aThumbContent ) )
184 maThumbRect.Top() = mnThumbPixPos - aThumbBounds.GetHeight()/2;
185 maThumbRect.Bottom() = maThumbRect.Top() + aThumbBounds.GetHeight() - 1;
186 bInvalidateAll = true;
190 else
192 maChannel1Rect.SetEmpty();
193 maChannel2Rect.SetEmpty();
194 maThumbRect.SetEmpty();
197 if ( bUpdate )
199 if ( aOldThumbRect != maThumbRect )
201 if( bInvalidateAll )
202 Invalidate();
203 else
205 Region aInvalidRegion( aOldThumbRect );
206 aInvalidRegion.Union( maThumbRect );
208 if( !IsBackground() && GetParent() )
210 const Point aPos( GetPosPixel() );
211 aInvalidRegion.Move( aPos.X(), aPos.Y() );
212 GetParent()->Invalidate( aInvalidRegion, INVALIDATE_TRANSPARENT | INVALIDATE_UPDATE );
214 else
215 Invalidate( aInvalidRegion );
221 // -----------------------------------------------------------------------
223 long Slider::ImplCalcThumbPos( long nPixPos )
225 // calculate position
226 long nCalcThumbPos;
227 nCalcThumbPos = ImplMulDiv( nPixPos-mnThumbPixOffset, mnMaxRange-mnMinRange, mnThumbPixRange-1 );
228 nCalcThumbPos += mnMinRange;
229 return nCalcThumbPos;
232 // -----------------------------------------------------------------------
234 long Slider::ImplCalcThumbPosPix( long nPos )
236 // calculate position
237 long nCalcThumbPos;
238 nCalcThumbPos = ImplMulDiv( nPos-mnMinRange, mnThumbPixRange-1, mnMaxRange-mnMinRange );
239 // at the beginning and end we try to display Slider correctly
240 if ( !nCalcThumbPos && (mnThumbPos > mnMinRange) )
241 nCalcThumbPos = 1;
242 if ( nCalcThumbPos &&
243 (nCalcThumbPos == mnThumbPixRange-1) &&
244 (mnThumbPos < mnMaxRange) )
245 nCalcThumbPos--;
246 return nCalcThumbPos+mnThumbPixOffset;
249 // -----------------------------------------------------------------------
251 void Slider::ImplCalc( sal_Bool bUpdate )
253 bool bInvalidateAll = false;
255 if ( mbCalcSize )
257 long nOldChannelPixOffset = mnChannelPixOffset;
258 long nOldChannelPixRange = mnChannelPixRange;
259 long nOldChannelPixTop = mnChannelPixTop;
260 long nOldChannelPixBottom = mnChannelPixBottom;
261 long nCalcWidth;
262 long nCalcHeight;
264 maChannel1Rect.SetEmpty();
265 maChannel2Rect.SetEmpty();
266 maThumbRect.SetEmpty();
268 Size aSize = GetOutputSizePixel();
269 if ( GetStyle() & WB_HORZ )
271 nCalcWidth = aSize.Width();
272 nCalcHeight = aSize.Height();
273 maThumbRect.Top() = 0;
274 maThumbRect.Bottom()= aSize.Height()-1;
276 else
278 nCalcWidth = aSize.Height();
279 nCalcHeight = aSize.Width();
280 maThumbRect.Left() = 0;
281 maThumbRect.Right() = aSize.Width()-1;
284 if ( nCalcWidth >= SLIDER_THUMB_SIZE )
286 mnThumbPixOffset = SLIDER_THUMB_HALFSIZE;
287 mnThumbPixRange = nCalcWidth-(SLIDER_THUMB_HALFSIZE*2);
288 mnThumbPixPos = 0;
289 mnChannelPixOffset = SLIDER_CHANNEL_OFFSET;
290 mnChannelPixRange = nCalcWidth-(SLIDER_CHANNEL_OFFSET*2);
291 mnChannelPixTop = (nCalcHeight/2)-SLIDER_CHANNEL_HALFSIZE;
292 mnChannelPixBottom = mnChannelPixTop+SLIDER_CHANNEL_SIZE-1;
294 else
296 mnThumbPixRange = 0;
297 mnChannelPixRange = 0;
300 if ( (nOldChannelPixOffset != mnChannelPixOffset) ||
301 (nOldChannelPixRange != mnChannelPixRange) ||
302 (nOldChannelPixTop != mnChannelPixTop) ||
303 (nOldChannelPixBottom != mnChannelPixBottom) )
304 bInvalidateAll = true;
306 mbCalcSize = sal_False;
309 if ( mnThumbPixRange )
310 mnThumbPixPos = ImplCalcThumbPosPix( mnThumbPos );
312 if ( bUpdate && bInvalidateAll )
314 Invalidate();
315 bUpdate = sal_False;
317 ImplUpdateRects( bUpdate );
320 // -----------------------------------------------------------------------
322 void Slider::ImplDraw( sal_uInt16 nDrawFlags )
324 DecorationView aDecoView( this );
325 sal_uInt16 nStyle;
326 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
327 sal_Bool bEnabled = IsEnabled();
329 // do missing calculations
330 if ( mbCalcSize )
331 ImplCalc( sal_False );
333 ControlPart nPart = (GetStyle() & WB_HORZ) ? PART_TRACK_HORZ_AREA : PART_TRACK_VERT_AREA;
334 ControlState nState = ( IsEnabled() ? CTRL_STATE_ENABLED : 0 ) | ( HasFocus() ? CTRL_STATE_FOCUSED : 0 );
335 SliderValue sldValue;
337 sldValue.mnMin = mnMinRange;
338 sldValue.mnMax = mnMaxRange;
339 sldValue.mnCur = mnThumbPos;
340 sldValue.maThumbRect = maThumbRect;
342 if( IsMouseOver() )
344 if( maThumbRect.IsInside( GetPointerPosPixel() ) )
345 sldValue.mnThumbState |= CTRL_STATE_ROLLOVER;
348 const Rectangle aCtrlRegion( Point(0,0), GetOutputSizePixel() );
349 bool bNativeOK = DrawNativeControl( CTRL_SLIDER, nPart,
350 aCtrlRegion, nState, sldValue, OUString() );
351 if( bNativeOK )
352 return;
354 if ( (nDrawFlags & SLIDER_DRAW_CHANNEL1) && !maChannel1Rect.IsEmpty() )
356 long nRectSize;
357 Rectangle aRect = maChannel1Rect;
358 SetLineColor( rStyleSettings.GetShadowColor() );
359 if ( GetStyle() & WB_HORZ )
361 DrawLine( aRect.TopLeft(), Point( aRect.Left(), aRect.Bottom()-1 ) );
362 DrawLine( aRect.TopLeft(), aRect.TopRight() );
364 else
366 DrawLine( aRect.TopLeft(), Point( aRect.Right()-1, aRect.Top() ) );
367 DrawLine( aRect.TopLeft(), aRect.BottomLeft() );
369 SetLineColor( rStyleSettings.GetLightColor() );
370 if ( GetStyle() & WB_HORZ )
372 DrawLine( aRect.BottomLeft(), aRect.BottomRight() );
373 nRectSize = aRect.GetWidth();
375 else
377 DrawLine( aRect.TopRight(), aRect.BottomRight() );
378 nRectSize = aRect.GetHeight();
381 if ( nRectSize > 1 )
383 aRect.Left()++;
384 aRect.Top()++;
385 if ( GetStyle() & WB_HORZ )
386 aRect.Bottom()--;
387 else
388 aRect.Right()--;
389 SetLineColor();
390 if ( mnStateFlags & SLIDER_STATE_CHANNEL1_DOWN )
391 SetFillColor( rStyleSettings.GetShadowColor() );
392 else
393 SetFillColor( rStyleSettings.GetCheckedColor() );
394 DrawRect( aRect );
398 if ( (nDrawFlags & SLIDER_DRAW_CHANNEL2) && !maChannel2Rect.IsEmpty() )
400 long nRectSize;
401 Rectangle aRect = maChannel2Rect;
402 SetLineColor( rStyleSettings.GetLightColor() );
403 if ( GetStyle() & WB_HORZ )
405 DrawLine( aRect.TopRight(), aRect.BottomRight() );
406 DrawLine( aRect.BottomLeft(), aRect.BottomRight() );
407 nRectSize = aRect.GetWidth();
409 else
411 DrawLine( aRect.BottomLeft(), aRect.BottomRight() );
412 DrawLine( aRect.TopRight(), aRect.BottomRight() );
413 nRectSize = aRect.GetHeight();
416 if ( nRectSize > 1 )
418 SetLineColor( rStyleSettings.GetShadowColor() );
419 if ( GetStyle() & WB_HORZ )
420 DrawLine( aRect.TopLeft(), Point( aRect.Right()-1, aRect.Top() ) );
421 else
422 DrawLine( aRect.TopLeft(), Point( aRect.Left(), aRect.Bottom()-1 ) );
424 aRect.Right()--;
425 aRect.Bottom()--;
426 if ( GetStyle() & WB_HORZ )
427 aRect.Top()++;
428 else
429 aRect.Left()++;
430 SetLineColor();
431 if ( mnStateFlags & SLIDER_STATE_CHANNEL2_DOWN )
432 SetFillColor( rStyleSettings.GetShadowColor() );
433 else
434 SetFillColor( rStyleSettings.GetCheckedColor() );
435 DrawRect( aRect );
439 if ( nDrawFlags & SLIDER_DRAW_THUMB )
441 if ( !maThumbRect.IsEmpty() )
443 if ( bEnabled )
445 nStyle = 0;
446 if ( mnStateFlags & SLIDER_STATE_THUMB_DOWN )
447 nStyle |= BUTTON_DRAW_PRESSED;
448 aDecoView.DrawButton( maThumbRect, nStyle );
450 else
452 SetLineColor( rStyleSettings.GetShadowColor() );
453 SetFillColor( rStyleSettings.GetCheckedColor() );
454 DrawRect( maThumbRect );
460 // -----------------------------------------------------------------------
462 sal_Bool Slider::ImplIsPageUp( const Point& rPos )
464 Size aSize = GetOutputSizePixel();
465 Rectangle aRect = maChannel1Rect;
466 if ( GetStyle() & WB_HORZ )
468 aRect.Top() = 0;
469 aRect.Bottom() = aSize.Height()-1;
471 else
473 aRect.Left() = 0;
474 aRect.Right() = aSize.Width()-1;
476 return aRect.IsInside( rPos );
479 // -----------------------------------------------------------------------
481 sal_Bool Slider::ImplIsPageDown( const Point& rPos )
483 Size aSize = GetOutputSizePixel();
484 Rectangle aRect = maChannel2Rect;
485 if ( GetStyle() & WB_HORZ )
487 aRect.Top() = 0;
488 aRect.Bottom() = aSize.Height()-1;
490 else
492 aRect.Left() = 0;
493 aRect.Right() = aSize.Width()-1;
495 return aRect.IsInside( rPos );
498 // -----------------------------------------------------------------------
500 long Slider::ImplSlide( long nNewPos, sal_Bool bCallEndSlide )
502 long nOldPos = mnThumbPos;
503 SetThumbPos( nNewPos );
504 long nDelta = mnThumbPos-nOldPos;
505 if ( nDelta )
507 mnDelta = nDelta;
508 Slide();
509 if ( bCallEndSlide )
510 EndSlide();
511 mnDelta = 0;
513 return nDelta;
516 // -----------------------------------------------------------------------
518 long Slider::ImplDoAction( sal_Bool bCallEndSlide )
520 long nDelta = 0;
522 switch ( meScrollType )
524 case SCROLL_LINEUP:
525 nDelta = ImplSlide( mnThumbPos-mnLineSize, bCallEndSlide );
526 break;
528 case SCROLL_LINEDOWN:
529 nDelta = ImplSlide( mnThumbPos+mnLineSize, bCallEndSlide );
530 break;
532 case SCROLL_PAGEUP:
533 nDelta = ImplSlide( mnThumbPos-mnPageSize, bCallEndSlide );
534 break;
536 case SCROLL_PAGEDOWN:
537 nDelta = ImplSlide( mnThumbPos+mnPageSize, bCallEndSlide );
538 break;
540 case SCROLL_SET:
541 nDelta = ImplSlide( ImplCalcThumbPos( GetPointerPosPixel().X() ), bCallEndSlide );
542 break;
543 default:
544 break;
547 return nDelta;
550 // -----------------------------------------------------------------------
552 void Slider::ImplDoMouseAction( const Point& rMousePos, sal_Bool bCallAction )
554 sal_uInt16 nOldStateFlags = mnStateFlags;
555 sal_Bool bAction = sal_False;
557 switch ( meScrollType )
559 case( SCROLL_SET ):
561 const bool bUp = ImplIsPageUp( rMousePos ), bDown = ImplIsPageDown( rMousePos );
563 if ( bUp || bDown )
565 bAction = bCallAction;
566 mnStateFlags |= ( bUp ? SLIDER_STATE_CHANNEL1_DOWN : SLIDER_STATE_CHANNEL2_DOWN );
568 else
569 mnStateFlags &= ~( SLIDER_STATE_CHANNEL1_DOWN | SLIDER_STATE_CHANNEL2_DOWN );
570 break;
573 case SCROLL_PAGEUP:
574 if ( ImplIsPageUp( rMousePos ) )
576 bAction = bCallAction;
577 mnStateFlags |= SLIDER_STATE_CHANNEL1_DOWN;
579 else
580 mnStateFlags &= ~SLIDER_STATE_CHANNEL1_DOWN;
581 break;
583 case SCROLL_PAGEDOWN:
584 if ( ImplIsPageDown( rMousePos ) )
586 bAction = bCallAction;
587 mnStateFlags |= SLIDER_STATE_CHANNEL2_DOWN;
589 else
590 mnStateFlags &= ~SLIDER_STATE_CHANNEL2_DOWN;
591 break;
592 default:
593 break;
596 if ( bAction )
598 if ( ImplDoAction( sal_False ) )
600 // Update the channel complete
601 if ( mnDragDraw & SLIDER_DRAW_CHANNEL )
603 Update();
604 ImplDraw( mnDragDraw );
608 else if ( nOldStateFlags != mnStateFlags )
609 ImplDraw( mnDragDraw );
612 // -----------------------------------------------------------------------
614 long Slider::ImplDoSlide( long nNewPos )
616 if ( meScrollType != SCROLL_DONTKNOW )
617 return 0;
619 meScrollType = SCROLL_DRAG;
620 long nDelta = ImplSlide( nNewPos, sal_True );
621 meScrollType = SCROLL_DONTKNOW;
622 return nDelta;
625 // -----------------------------------------------------------------------
627 long Slider::ImplDoSlideAction( ScrollType eScrollType )
629 if ( (meScrollType != SCROLL_DONTKNOW) ||
630 (eScrollType == SCROLL_DONTKNOW) ||
631 (eScrollType == SCROLL_DRAG) )
632 return 0;
634 meScrollType = eScrollType;
635 long nDelta = ImplDoAction( sal_True );
636 meScrollType = SCROLL_DONTKNOW;
637 return nDelta;
640 // -----------------------------------------------------------------------
642 void Slider::MouseButtonDown( const MouseEvent& rMEvt )
644 if ( rMEvt.IsLeft() )
646 const Point& rMousePos = rMEvt.GetPosPixel();
647 sal_uInt16 nTrackFlags = 0;
649 if ( maThumbRect.IsInside( rMousePos ) )
651 nTrackFlags = 0;
652 meScrollType = SCROLL_DRAG;
653 mnDragDraw = SLIDER_DRAW_THUMB;
655 // calculate additional values
656 Point aCenterPos = maThumbRect.Center();
657 if ( GetStyle() & WB_HORZ )
658 mnMouseOff = rMousePos.X()-aCenterPos.X();
659 else
660 mnMouseOff = rMousePos.Y()-aCenterPos.Y();
662 else if ( ImplIsPageUp( rMousePos ) )
664 if( GetStyle() & WB_SLIDERSET )
665 meScrollType = SCROLL_SET;
666 else
668 nTrackFlags = STARTTRACK_BUTTONREPEAT;
669 meScrollType = SCROLL_PAGEUP;
672 mnDragDraw = SLIDER_DRAW_CHANNEL;
674 else if ( ImplIsPageDown( rMousePos ) )
676 if( GetStyle() & WB_SLIDERSET )
677 meScrollType = SCROLL_SET;
678 else
680 nTrackFlags = STARTTRACK_BUTTONREPEAT;
681 meScrollType = SCROLL_PAGEDOWN;
684 mnDragDraw = SLIDER_DRAW_CHANNEL;
687 // Shall we start Tracking?
688 if( meScrollType != SCROLL_DONTKNOW )
690 // store Start position for cancel and EndScroll delta
691 mnStartPos = mnThumbPos;
692 ImplDoMouseAction( rMousePos, meScrollType != SCROLL_SET );
693 Update();
695 if( meScrollType != SCROLL_SET )
696 StartTracking( nTrackFlags );
701 // -----------------------------------------------------------------------
703 void Slider::MouseButtonUp( const MouseEvent& )
705 if( SCROLL_SET == meScrollType )
707 // reset Button and PageRect state
708 const sal_uInt16 nOldStateFlags = mnStateFlags;
710 mnStateFlags &= ~( SLIDER_STATE_CHANNEL1_DOWN | SLIDER_STATE_CHANNEL2_DOWN | SLIDER_STATE_THUMB_DOWN );
712 if ( nOldStateFlags != mnStateFlags )
713 ImplDraw( mnDragDraw );
715 mnDragDraw = 0;
716 ImplDoAction( sal_True );
717 meScrollType = SCROLL_DONTKNOW;
721 // -----------------------------------------------------------------------
723 void Slider::Tracking( const TrackingEvent& rTEvt )
725 if ( rTEvt.IsTrackingEnded() )
727 // reset Button and PageRect state
728 sal_uInt16 nOldStateFlags = mnStateFlags;
729 mnStateFlags &= ~(SLIDER_STATE_CHANNEL1_DOWN | SLIDER_STATE_CHANNEL2_DOWN |
730 SLIDER_STATE_THUMB_DOWN);
731 if ( nOldStateFlags != mnStateFlags )
732 ImplDraw( mnDragDraw );
733 mnDragDraw = 0;
735 // on cancel, reset the previous Thumb position
736 if ( rTEvt.IsTrackingCanceled() )
738 long nOldPos = mnThumbPos;
739 SetThumbPos( mnStartPos );
740 mnDelta = mnThumbPos-nOldPos;
741 Slide();
744 if ( meScrollType == SCROLL_DRAG )
746 // after dragging, recalculate to a rounded Thumb position
747 ImplCalc();
748 Update();
750 if ( !mbFullDrag && (mnStartPos != mnThumbPos) )
752 mnDelta = mnThumbPos-mnStartPos;
753 Slide();
754 mnDelta = 0;
758 mnDelta = mnThumbPos-mnStartPos;
759 EndSlide();
760 mnDelta = 0;
761 meScrollType = SCROLL_DONTKNOW;
763 else
765 const Point rMousePos = rTEvt.GetMouseEvent().GetPosPixel();
767 // special handling for dragging
768 if ( meScrollType == SCROLL_DRAG )
770 long nMovePix;
771 Point aCenterPos = maThumbRect.Center();
772 if ( GetStyle() & WB_HORZ )
773 nMovePix = rMousePos.X()-(aCenterPos.X()+mnMouseOff);
774 else
775 nMovePix = rMousePos.Y()-(aCenterPos.Y()+mnMouseOff);
776 // only if the mouse moves in Scroll direction we have to act
777 if ( nMovePix )
779 mnThumbPixPos += nMovePix;
780 if ( mnThumbPixPos < mnThumbPixOffset )
781 mnThumbPixPos = mnThumbPixOffset;
782 if ( mnThumbPixPos > (mnThumbPixOffset+mnThumbPixRange-1) )
783 mnThumbPixPos = mnThumbPixOffset+mnThumbPixRange-1;
784 long nOldPos = mnThumbPos;
785 mnThumbPos = ImplCalcThumbPos( mnThumbPixPos );
786 if ( nOldPos != mnThumbPos )
788 ImplUpdateRects();
789 Update();
790 if ( mbFullDrag && (nOldPos != mnThumbPos) )
792 mnDelta = mnThumbPos-nOldPos;
793 Slide();
794 mnDelta = 0;
799 else
800 ImplDoMouseAction( rMousePos, rTEvt.IsTrackingRepeat() );
802 // end tracking if ScrollBar values indicate we are done
803 if ( !IsVisible() )
804 EndTracking();
808 // -----------------------------------------------------------------------
810 void Slider::KeyInput( const KeyEvent& rKEvt )
812 if ( !rKEvt.GetKeyCode().GetModifier() )
814 switch ( rKEvt.GetKeyCode().GetCode() )
816 case KEY_HOME:
817 ImplDoSlide( GetRangeMin() );
818 break;
819 case KEY_END:
820 ImplDoSlide( GetRangeMax() );
821 break;
823 case KEY_LEFT:
824 case KEY_UP:
825 ImplDoSlideAction( SCROLL_LINEUP );
826 break;
828 case KEY_RIGHT:
829 case KEY_DOWN:
830 ImplDoSlideAction( SCROLL_LINEDOWN );
831 break;
833 case KEY_PAGEUP:
834 ImplDoSlideAction( SCROLL_PAGEUP );
835 break;
837 case KEY_PAGEDOWN:
838 ImplDoSlideAction( SCROLL_PAGEDOWN );
839 break;
841 default:
842 Control::KeyInput( rKEvt );
843 break;
846 else
847 Control::KeyInput( rKEvt );
850 // -----------------------------------------------------------------------
852 void Slider::Paint( const Rectangle& )
854 ImplDraw( SLIDER_DRAW_ALL );
857 // -----------------------------------------------------------------------
859 void Slider::Resize()
861 Control::Resize();
862 mbCalcSize = sal_True;
863 if ( IsReallyVisible() )
864 ImplCalc( sal_False );
865 Invalidate();
868 // -----------------------------------------------------------------------
870 void Slider::RequestHelp( const HelpEvent& rHEvt )
872 Control::RequestHelp( rHEvt );
875 // -----------------------------------------------------------------------
877 void Slider::StateChanged( StateChangedType nType )
879 Control::StateChanged( nType );
881 if ( nType == STATE_CHANGE_INITSHOW )
882 ImplCalc( sal_False );
883 else if ( nType == STATE_CHANGE_DATA )
885 if ( IsReallyVisible() && IsUpdateMode() )
886 ImplCalc( sal_True );
888 else if ( nType == STATE_CHANGE_UPDATEMODE )
890 if ( IsReallyVisible() && IsUpdateMode() )
892 ImplCalc( sal_False );
893 Invalidate();
896 else if ( nType == STATE_CHANGE_ENABLE )
898 if ( IsReallyVisible() && IsUpdateMode() )
899 Invalidate();
901 else if ( nType == STATE_CHANGE_STYLE )
903 if ( IsReallyVisible() && IsUpdateMode() )
905 if ( (GetPrevStyle() & SLIDER_VIEW_STYLE) !=
906 (GetStyle() & SLIDER_VIEW_STYLE) )
908 mbCalcSize = sal_True;
909 ImplCalc( sal_False );
910 Invalidate();
914 else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
916 ImplInitSettings();
917 Invalidate();
921 // -----------------------------------------------------------------------
923 void Slider::DataChanged( const DataChangedEvent& rDCEvt )
925 Control::DataChanged( rDCEvt );
927 if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
928 (rDCEvt.GetFlags() & SETTINGS_STYLE) )
930 ImplInitSettings();
931 Invalidate();
935 // -----------------------------------------------------------------------
937 void Slider::Slide()
939 maSlideHdl.Call( this );
942 // -----------------------------------------------------------------------
944 void Slider::EndSlide()
946 maEndSlideHdl.Call( this );
949 // -----------------------------------------------------------------------
951 void Slider::SetRange( const Range& rRange )
953 // adjust Range
954 Range aRange = rRange;
955 aRange.Justify();
956 long nNewMinRange = aRange.Min();
957 long nNewMaxRange = aRange.Max();
959 // reset Range if different
960 if ( (mnMinRange != nNewMinRange) ||
961 (mnMaxRange != nNewMaxRange) )
963 mnMinRange = nNewMinRange;
964 mnMaxRange = nNewMaxRange;
966 // adjust Thumb
967 if ( mnThumbPos > mnMaxRange )
968 mnThumbPos = mnMaxRange;
969 if ( mnThumbPos < mnMinRange )
970 mnThumbPos = mnMinRange;
972 StateChanged( STATE_CHANGE_DATA );
976 // -----------------------------------------------------------------------
978 void Slider::SetThumbPos( long nNewThumbPos )
980 if ( nNewThumbPos < mnMinRange )
981 nNewThumbPos = mnMinRange;
982 if ( nNewThumbPos > mnMaxRange )
983 nNewThumbPos = mnMaxRange;
985 if ( mnThumbPos != nNewThumbPos )
987 mnThumbPos = nNewThumbPos;
988 StateChanged( STATE_CHANGE_DATA );
992 // -----------------------------------------------------------------------
994 Size Slider::CalcWindowSizePixel()
996 long nWidth = mnMaxRange-mnMinRange+(SLIDER_THUMB_HALFSIZE*2)+1;
997 long nHeight = SLIDER_HEIGHT;
998 Size aSize;
999 if ( GetStyle() & WB_HORZ )
1001 aSize.Width() = nWidth;
1002 aSize.Height() = nHeight;
1004 else
1006 aSize.Height() = nWidth;
1007 aSize.Width() = nHeight;
1009 return aSize;
1012 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */