1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_vcl.hxx"
26
27 #ifndef _SV_RC_H
28 #include <tools/rc.h>
29 #endif
30 #include <vcl/event.hxx>
31 #include <vcl/decoview.hxx>
32 #include <vcl/slider.hxx>
33
34
35
36 // =======================================================================
37
ImplMulDiv(long nNumber,long nNumerator,long nDenominator)38 static long ImplMulDiv( long nNumber, long nNumerator, long nDenominator )
39 {
40 double n = ((double)nNumber * (double)nNumerator) / (double)nDenominator;
41 return (long)n;
42 }
43
44 // =======================================================================
45
46 #define SLIDER_DRAW_THUMB ((sal_uInt16)0x0001)
47 #define SLIDER_DRAW_CHANNEL1 ((sal_uInt16)0x0002)
48 #define SLIDER_DRAW_CHANNEL2 ((sal_uInt16)0x0004)
49 #define SLIDER_DRAW_CHANNEL (SLIDER_DRAW_CHANNEL1 | SLIDER_DRAW_CHANNEL2)
50 #define SLIDER_DRAW_ALL (SLIDER_DRAW_THUMB | SLIDER_DRAW_CHANNEL)
51
52 #define SLIDER_STATE_CHANNEL1_DOWN ((sal_uInt16)0x0001)
53 #define SLIDER_STATE_CHANNEL2_DOWN ((sal_uInt16)0x0002)
54 #define SLIDER_STATE_THUMB_DOWN ((sal_uInt16)0x0004)
55
56 #define SLIDER_THUMB_SIZE 9
57 #define SLIDER_THUMB_HALFSIZE 4
58 #define SLIDER_CHANNEL_OFFSET 0
59 #define SLIDER_CHANNEL_SIZE 4
60 #define SLIDER_CHANNEL_HALFSIZE 2
61
62 #define SLIDER_HEIGHT 16
63
64 #define SLIDER_VIEW_STYLE (WB_3DLOOK | WB_HORZ | WB_VERT)
65
66 // =======================================================================
67
ImplInit(Window * pParent,WinBits nStyle)68 void Slider::ImplInit( Window* pParent, WinBits nStyle )
69 {
70 mnThumbPixOffset = 0;
71 mnThumbPixRange = 0;
72 mnThumbPixPos = 0; // between mnThumbPixOffset and mnThumbPixOffset+mnThumbPixRange
73 mnChannelPixOffset = 0;
74 mnChannelPixRange = 0;
75 mnChannelPixTop = 0;
76 mnChannelPixBottom = 0;
77
78 mnMinRange = 0;
79 mnMaxRange = 100;
80 mnThumbPos = 0;
81 mnLineSize = 1;
82 mnPageSize = 1;
83 mnDelta = 0;
84 mnDragDraw = 0;
85 mnStateFlags = 0;
86 meScrollType = SCROLL_DONTKNOW;
87 mbCalcSize = sal_True;
88 mbFullDrag = sal_True;
89
90 Control::ImplInit( pParent, nStyle, NULL );
91
92 ImplInitSettings();
93 SetSizePixel( CalcWindowSizePixel() );
94 }
95
96 // -----------------------------------------------------------------------
97
Slider(Window * pParent,WinBits nStyle)98 Slider::Slider( Window* pParent, WinBits nStyle ) :
99 Control( WINDOW_SLIDER )
100 {
101 ImplInit( pParent, nStyle );
102 }
103
104 // -----------------------------------------------------------------------
105
Slider(Window * pParent,const ResId & rResId)106 Slider::Slider( Window* pParent, const ResId& rResId ) :
107 Control( WINDOW_SLIDER )
108 {
109 rResId.SetRT( RSC_SCROLLBAR );
110 WinBits nStyle = ImplInitRes( rResId );
111 ImplInit( pParent, nStyle );
112 ImplLoadRes( rResId );
113
114 if ( !(nStyle & WB_HIDE) )
115 Show();
116 }
117
118 // -----------------------------------------------------------------------
119
ImplLoadRes(const ResId & rResId)120 void Slider::ImplLoadRes( const ResId& rResId )
121 {
122 Control::ImplLoadRes( rResId );
123
124 sal_Int16 nMin = ReadShortRes();
125 sal_Int16 nMax = ReadShortRes();
126 sal_Int16 nThumbPos = ReadShortRes();
127 sal_Int16 nPage = ReadShortRes();
128 sal_Int16 nStep = ReadShortRes();
129 /* sal_Int16 nVisibleSize = */ ReadShortRes();
130
131 SetRange( Range( nMin, nMax ) );
132 SetLineSize( nStep );
133 SetPageSize( nPage );
134 SetThumbPos( nThumbPos );
135 }
136
137 // -----------------------------------------------------------------------
138
ImplInitSettings()139 void Slider::ImplInitSettings()
140 {
141 Window* pParent = GetParent();
142 if ( pParent->IsChildTransparentModeEnabled() && !IsControlBackground() )
143 {
144 EnableChildTransparentMode( sal_True );
145 SetParentClipMode( PARENTCLIPMODE_NOCLIP );
146 SetPaintTransparent( sal_True );
147 SetBackground();
148 }
149 else
150 {
151 EnableChildTransparentMode( sal_False );
152 SetParentClipMode( 0 );
153 SetPaintTransparent( sal_False );
154
155 if ( IsControlBackground() )
156 SetBackground( GetControlBackground() );
157 else
158 SetBackground( pParent->GetBackground() );
159 }
160 }
161
162 // -----------------------------------------------------------------------
163
ImplUpdateRects(sal_Bool bUpdate)164 void Slider::ImplUpdateRects( sal_Bool bUpdate )
165 {
166 Rectangle aOldThumbRect = maThumbRect;
167 bool bInvalidateAll = false;
168
169 if ( mnThumbPixRange )
170 {
171 if ( GetStyle() & WB_HORZ )
172 {
173 maThumbRect.Left() = mnThumbPixPos-SLIDER_THUMB_HALFSIZE;
174 maThumbRect.Right() = maThumbRect.Left()+SLIDER_THUMB_SIZE-1;
175 if ( mnChannelPixOffset < maThumbRect.Left() )
176 {
177 maChannel1Rect.Left() = mnChannelPixOffset;
178 maChannel1Rect.Right() = maThumbRect.Left()-1;
179 maChannel1Rect.Top() = mnChannelPixTop;
180 maChannel1Rect.Bottom() = mnChannelPixBottom;
181 }
182 else
183 maChannel1Rect.SetEmpty();
184 if ( mnChannelPixOffset+mnChannelPixRange-1 > maThumbRect.Right() )
185 {
186 maChannel2Rect.Left() = maThumbRect.Right()+1;
187 maChannel2Rect.Right() = mnChannelPixOffset+mnChannelPixRange-1;
188 maChannel2Rect.Top() = mnChannelPixTop;
189 maChannel2Rect.Bottom() = mnChannelPixBottom;
190 }
191 else
192 maChannel2Rect.SetEmpty();
193
194 const Rectangle aControlRegion( Rectangle( Point(0,0), Size( SLIDER_THUMB_SIZE, 10 ) ) );
195 Rectangle aThumbBounds, aThumbContent;
196 if ( GetNativeControlRegion( CTRL_SLIDER, PART_THUMB_HORZ,
197 aControlRegion, 0, ImplControlValue(), rtl::OUString(),
198 aThumbBounds, aThumbContent ) )
199 {
200 maThumbRect.Left() = mnThumbPixPos - aThumbBounds.GetWidth()/2;
201 maThumbRect.Right() = maThumbRect.Left() + aThumbBounds.GetWidth() - 1;
202 bInvalidateAll = true;
203 }
204 }
205 else
206 {
207 maThumbRect.Top() = mnThumbPixPos-SLIDER_THUMB_HALFSIZE;
208 maThumbRect.Bottom() = maThumbRect.Top()+SLIDER_THUMB_SIZE-1;
209 if ( mnChannelPixOffset < maThumbRect.Top() )
210 {
211 maChannel1Rect.Top() = mnChannelPixOffset;
212 maChannel1Rect.Bottom() = maThumbRect.Top()-1;
213 maChannel1Rect.Left() = mnChannelPixTop;
214 maChannel1Rect.Right() = mnChannelPixBottom;
215 }
216 else
217 maChannel1Rect.SetEmpty();
218 if ( mnChannelPixOffset+mnChannelPixRange-1 > maThumbRect.Bottom() )
219 {
220 maChannel2Rect.Top() = maThumbRect.Bottom()+1;
221 maChannel2Rect.Bottom() = mnChannelPixOffset+mnChannelPixRange-1;
222 maChannel2Rect.Left() = mnChannelPixTop;
223 maChannel2Rect.Right() = mnChannelPixBottom;
224 }
225 else
226 maChannel2Rect.SetEmpty();
227
228 const Rectangle aControlRegion( Rectangle( Point(0,0), Size( 10, SLIDER_THUMB_SIZE ) ) );
229 Rectangle aThumbBounds, aThumbContent;
230 if ( GetNativeControlRegion( CTRL_SLIDER, PART_THUMB_VERT,
231 aControlRegion, 0, ImplControlValue(), rtl::OUString(),
232 aThumbBounds, aThumbContent ) )
233 {
234 maThumbRect.Top() = mnThumbPixPos - aThumbBounds.GetHeight()/2;
235 maThumbRect.Bottom() = maThumbRect.Top() + aThumbBounds.GetHeight() - 1;
236 bInvalidateAll = true;
237 }
238 }
239 }
240 else
241 {
242 maChannel1Rect.SetEmpty();
243 maChannel2Rect.SetEmpty();
244 maThumbRect.SetEmpty();
245 }
246
247 if ( bUpdate )
248 {
249 if ( aOldThumbRect != maThumbRect )
250 {
251 if( bInvalidateAll )
252 Invalidate();
253 else
254 {
255 Region aInvalidRegion( aOldThumbRect );
256 aInvalidRegion.Union( maThumbRect );
257
258 if( !IsBackground() && GetParent() )
259 {
260 const Point aPos( GetPosPixel() );
261 aInvalidRegion.Move( aPos.X(), aPos.Y() );
262 GetParent()->Invalidate( aInvalidRegion, INVALIDATE_TRANSPARENT | INVALIDATE_UPDATE );
263 }
264 else
265 Invalidate( aInvalidRegion );
266 }
267 }
268 }
269 }
270
271 // -----------------------------------------------------------------------
272
ImplCalcThumbPos(long nPixPos)273 long Slider::ImplCalcThumbPos( long nPixPos )
274 {
275 // Position berechnen
276 long nCalcThumbPos;
277 nCalcThumbPos = ImplMulDiv( nPixPos-mnThumbPixOffset, mnMaxRange-mnMinRange, mnThumbPixRange-1 );
278 nCalcThumbPos += mnMinRange;
279 return nCalcThumbPos;
280 }
281
282 // -----------------------------------------------------------------------
283
ImplCalcThumbPosPix(long nPos)284 long Slider::ImplCalcThumbPosPix( long nPos )
285 {
286 // Position berechnen
287 long nCalcThumbPos;
288 nCalcThumbPos = ImplMulDiv( nPos-mnMinRange, mnThumbPixRange-1, mnMaxRange-mnMinRange );
289 // Am Anfang und Ende des Sliders versuchen wir die Anzeige korrekt
290 // anzuzeigen
291 if ( !nCalcThumbPos && (mnThumbPos > mnMinRange) )
292 nCalcThumbPos = 1;
293 if ( nCalcThumbPos &&
294 (nCalcThumbPos == mnThumbPixRange-1) &&
295 (mnThumbPos < mnMaxRange) )
296 nCalcThumbPos--;
297 return nCalcThumbPos+mnThumbPixOffset;
298 }
299
300 // -----------------------------------------------------------------------
301
ImplCalc(sal_Bool bUpdate)302 void Slider::ImplCalc( sal_Bool bUpdate )
303 {
304 sal_Bool bInvalidateAll = sal_False;
305
306 if ( mbCalcSize )
307 {
308 long nOldChannelPixOffset = mnChannelPixOffset;
309 long nOldChannelPixRange = mnChannelPixRange;
310 long nOldChannelPixTop = mnChannelPixTop;
311 long nOldChannelPixBottom = mnChannelPixBottom;
312 long nCalcWidth;
313 long nCalcHeight;
314
315 maChannel1Rect.SetEmpty();
316 maChannel2Rect.SetEmpty();
317 maThumbRect.SetEmpty();
318
319 Size aSize = GetOutputSizePixel();
320 if ( GetStyle() & WB_HORZ )
321 {
322 nCalcWidth = aSize.Width();
323 nCalcHeight = aSize.Height();
324 maThumbRect.Top() = 0;
325 maThumbRect.Bottom()= aSize.Height()-1;
326 }
327 else
328 {
329 nCalcWidth = aSize.Height();
330 nCalcHeight = aSize.Width();
331 maThumbRect.Left() = 0;
332 maThumbRect.Right() = aSize.Width()-1;
333 }
334
335 if ( nCalcWidth >= SLIDER_THUMB_SIZE )
336 {
337 mnThumbPixOffset = SLIDER_THUMB_HALFSIZE;
338 mnThumbPixRange = nCalcWidth-(SLIDER_THUMB_HALFSIZE*2);
339 mnThumbPixPos = 0;
340 mnChannelPixOffset = SLIDER_CHANNEL_OFFSET;
341 mnChannelPixRange = nCalcWidth-(SLIDER_CHANNEL_OFFSET*2);
342 mnChannelPixTop = (nCalcHeight/2)-SLIDER_CHANNEL_HALFSIZE;
343 mnChannelPixBottom = mnChannelPixTop+SLIDER_CHANNEL_SIZE-1;
344 }
345 else
346 {
347 mnThumbPixRange = 0;
348 mnChannelPixRange = 0;
349 }
350
351 if ( (nOldChannelPixOffset != mnChannelPixOffset) ||
352 (nOldChannelPixRange != mnChannelPixRange) ||
353 (nOldChannelPixTop != mnChannelPixTop) ||
354 (nOldChannelPixBottom != mnChannelPixBottom) )
355 bInvalidateAll = sal_True;
356
357 mbCalcSize = sal_False;
358 }
359
360 if ( mnThumbPixRange )
361 mnThumbPixPos = ImplCalcThumbPosPix( mnThumbPos );
362
363 if ( bUpdate && bInvalidateAll )
364 {
365 Invalidate();
366 bUpdate = sal_False;
367 }
368 ImplUpdateRects( bUpdate );
369 }
370
371 // -----------------------------------------------------------------------
372
ImplDraw(sal_uInt16 nDrawFlags)373 void Slider::ImplDraw( sal_uInt16 nDrawFlags )
374 {
375 DecorationView aDecoView( this );
376 sal_uInt16 nStyle;
377 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
378 sal_Bool bEnabled = IsEnabled();
379
380 // Evt. noch offene Berechnungen nachholen
381 if ( mbCalcSize )
382 ImplCalc( sal_False );
383
384 ControlPart nPart = (GetStyle() & WB_HORZ) ? PART_TRACK_HORZ_AREA : PART_TRACK_VERT_AREA;
385 ControlState nState = ( IsEnabled() ? CTRL_STATE_ENABLED : 0 ) | ( HasFocus() ? CTRL_STATE_FOCUSED : 0 );
386 SliderValue sldValue;
387
388 sldValue.mnMin = mnMinRange;
389 sldValue.mnMax = mnMaxRange;
390 sldValue.mnCur = mnThumbPos;
391 sldValue.maThumbRect = maThumbRect;
392
393 if( IsMouseOver() )
394 {
395 if( maThumbRect.IsInside( GetPointerPosPixel() ) )
396 sldValue.mnThumbState |= CTRL_STATE_ROLLOVER;
397 }
398
399 const Rectangle aCtrlRegion( Point(0,0), GetOutputSizePixel() );
400 bool bNativeOK = DrawNativeControl( CTRL_SLIDER, nPart,
401 aCtrlRegion, nState, sldValue, rtl::OUString() );
402 if( bNativeOK )
403 return;
404
405 if ( (nDrawFlags & SLIDER_DRAW_CHANNEL1) && !maChannel1Rect.IsEmpty() )
406 {
407 long nRectSize;
408 Rectangle aRect = maChannel1Rect;
409 SetLineColor( rStyleSettings.GetShadowColor() );
410 if ( GetStyle() & WB_HORZ )
411 {
412 DrawLine( aRect.TopLeft(), Point( aRect.Left(), aRect.Bottom()-1 ) );
413 DrawLine( aRect.TopLeft(), aRect.TopRight() );
414 }
415 else
416 {
417 DrawLine( aRect.TopLeft(), Point( aRect.Right()-1, aRect.Top() ) );
418 DrawLine( aRect.TopLeft(), aRect.BottomLeft() );
419 }
420 SetLineColor( rStyleSettings.GetLightColor() );
421 if ( GetStyle() & WB_HORZ )
422 {
423 DrawLine( aRect.BottomLeft(), aRect.BottomRight() );
424 nRectSize = aRect.GetWidth();
425 }
426 else
427 {
428 DrawLine( aRect.TopRight(), aRect.BottomRight() );
429 nRectSize = aRect.GetHeight();
430 }
431
432 if ( nRectSize > 1 )
433 {
434 aRect.Left()++;
435 aRect.Top()++;
436 if ( GetStyle() & WB_HORZ )
437 aRect.Bottom()--;
438 else
439 aRect.Right()--;
440 SetLineColor();
441 if ( mnStateFlags & SLIDER_STATE_CHANNEL1_DOWN )
442 SetFillColor( rStyleSettings.GetShadowColor() );
443 else
444 SetFillColor( rStyleSettings.GetCheckedColor() );
445 DrawRect( aRect );
446 }
447 }
448
449 if ( (nDrawFlags & SLIDER_DRAW_CHANNEL2) && !maChannel2Rect.IsEmpty() )
450 {
451 long nRectSize;
452 Rectangle aRect = maChannel2Rect;
453 SetLineColor( rStyleSettings.GetLightColor() );
454 if ( GetStyle() & WB_HORZ )
455 {
456 DrawLine( aRect.TopRight(), aRect.BottomRight() );
457 DrawLine( aRect.BottomLeft(), aRect.BottomRight() );
458 nRectSize = aRect.GetWidth();
459 }
460 else
461 {
462 DrawLine( aRect.BottomLeft(), aRect.BottomRight() );
463 DrawLine( aRect.TopRight(), aRect.BottomRight() );
464 nRectSize = aRect.GetHeight();
465 }
466
467 if ( nRectSize > 1 )
468 {
469 SetLineColor( rStyleSettings.GetShadowColor() );
470 if ( GetStyle() & WB_HORZ )
471 DrawLine( aRect.TopLeft(), Point( aRect.Right()-1, aRect.Top() ) );
472 else
473 DrawLine( aRect.TopLeft(), Point( aRect.Left(), aRect.Bottom()-1 ) );
474
475 aRect.Right()--;
476 aRect.Bottom()--;
477 if ( GetStyle() & WB_HORZ )
478 aRect.Top()++;
479 else
480 aRect.Left()++;
481 SetLineColor();
482 if ( mnStateFlags & SLIDER_STATE_CHANNEL2_DOWN )
483 SetFillColor( rStyleSettings.GetShadowColor() );
484 else
485 SetFillColor( rStyleSettings.GetCheckedColor() );
486 DrawRect( aRect );
487 }
488 }
489
490 if ( nDrawFlags & SLIDER_DRAW_THUMB )
491 {
492 if ( !maThumbRect.IsEmpty() )
493 {
494 if ( bEnabled )
495 {
496 nStyle = 0;
497 if ( mnStateFlags & SLIDER_STATE_THUMB_DOWN )
498 nStyle |= BUTTON_DRAW_PRESSED;
499 aDecoView.DrawButton( maThumbRect, nStyle );
500 }
501 else
502 {
503 SetLineColor( rStyleSettings.GetShadowColor() );
504 SetFillColor( rStyleSettings.GetCheckedColor() );
505 DrawRect( maThumbRect );
506 }
507 }
508 }
509 }
510
511 // -----------------------------------------------------------------------
512
ImplIsPageUp(const Point & rPos)513 sal_Bool Slider::ImplIsPageUp( const Point& rPos )
514 {
515 Size aSize = GetOutputSizePixel();
516 Rectangle aRect = maChannel1Rect;
517 if ( GetStyle() & WB_HORZ )
518 {
519 aRect.Top() = 0;
520 aRect.Bottom() = aSize.Height()-1;
521 }
522 else
523 {
524 aRect.Left() = 0;
525 aRect.Right() = aSize.Width()-1;
526 }
527 return aRect.IsInside( rPos );
528 }
529
530 // -----------------------------------------------------------------------
531
ImplIsPageDown(const Point & rPos)532 sal_Bool Slider::ImplIsPageDown( const Point& rPos )
533 {
534 Size aSize = GetOutputSizePixel();
535 Rectangle aRect = maChannel2Rect;
536 if ( GetStyle() & WB_HORZ )
537 {
538 aRect.Top() = 0;
539 aRect.Bottom() = aSize.Height()-1;
540 }
541 else
542 {
543 aRect.Left() = 0;
544 aRect.Right() = aSize.Width()-1;
545 }
546 return aRect.IsInside( rPos );
547 }
548
549 // -----------------------------------------------------------------------
550
ImplSlide(long nNewPos,sal_Bool bCallEndSlide)551 long Slider::ImplSlide( long nNewPos, sal_Bool bCallEndSlide )
552 {
553 long nOldPos = mnThumbPos;
554 SetThumbPos( nNewPos );
555 long nDelta = mnThumbPos-nOldPos;
556 if ( nDelta )
557 {
558 mnDelta = nDelta;
559 Slide();
560 if ( bCallEndSlide )
561 EndSlide();
562 mnDelta = 0;
563 }
564 return nDelta;
565 }
566
567 // -----------------------------------------------------------------------
568
ImplDoAction(sal_Bool bCallEndSlide)569 long Slider::ImplDoAction( sal_Bool bCallEndSlide )
570 {
571 long nDelta = 0;
572
573 switch ( meScrollType )
574 {
575 case SCROLL_LINEUP:
576 nDelta = ImplSlide( mnThumbPos-mnLineSize, bCallEndSlide );
577 break;
578
579 case SCROLL_LINEDOWN:
580 nDelta = ImplSlide( mnThumbPos+mnLineSize, bCallEndSlide );
581 break;
582
583 case SCROLL_PAGEUP:
584 nDelta = ImplSlide( mnThumbPos-mnPageSize, bCallEndSlide );
585 break;
586
587 case SCROLL_PAGEDOWN:
588 nDelta = ImplSlide( mnThumbPos+mnPageSize, bCallEndSlide );
589 break;
590
591 case SCROLL_SET:
592 nDelta = ImplSlide( ImplCalcThumbPos( GetPointerPosPixel().X() ), bCallEndSlide );
593 break;
594 default:
595 break;
596 }
597
598 return nDelta;
599 }
600
601 // -----------------------------------------------------------------------
602
ImplDoMouseAction(const Point & rMousePos,sal_Bool bCallAction)603 void Slider::ImplDoMouseAction( const Point& rMousePos, sal_Bool bCallAction )
604 {
605 sal_uInt16 nOldStateFlags = mnStateFlags;
606 sal_Bool bAction = sal_False;
607
608 switch ( meScrollType )
609 {
610 case( SCROLL_SET ):
611 {
612 const bool bUp = ImplIsPageUp( rMousePos ), bDown = ImplIsPageDown( rMousePos );
613
614 if ( bUp || bDown )
615 {
616 bAction = bCallAction;
617 mnStateFlags |= ( bUp ? SLIDER_STATE_CHANNEL1_DOWN : SLIDER_STATE_CHANNEL2_DOWN );
618 }
619 else
620 mnStateFlags &= ~( SLIDER_STATE_CHANNEL1_DOWN | SLIDER_STATE_CHANNEL2_DOWN );
621 break;
622 }
623
624 case SCROLL_PAGEUP:
625 if ( ImplIsPageUp( rMousePos ) )
626 {
627 bAction = bCallAction;
628 mnStateFlags |= SLIDER_STATE_CHANNEL1_DOWN;
629 }
630 else
631 mnStateFlags &= ~SLIDER_STATE_CHANNEL1_DOWN;
632 break;
633
634 case SCROLL_PAGEDOWN:
635 if ( ImplIsPageDown( rMousePos ) )
636 {
637 bAction = bCallAction;
638 mnStateFlags |= SLIDER_STATE_CHANNEL2_DOWN;
639 }
640 else
641 mnStateFlags &= ~SLIDER_STATE_CHANNEL2_DOWN;
642 break;
643 default:
644 break;
645 }
646
647 if ( bAction )
648 {
649 if ( ImplDoAction( sal_False ) )
650 {
651 // Update the channel complete
652 if ( mnDragDraw & SLIDER_DRAW_CHANNEL )
653 {
654 Update();
655 ImplDraw( mnDragDraw );
656 }
657 }
658 }
659 else if ( nOldStateFlags != mnStateFlags )
660 ImplDraw( mnDragDraw );
661 }
662
663 // -----------------------------------------------------------------------
664
ImplDoSlide(long nNewPos)665 long Slider::ImplDoSlide( long nNewPos )
666 {
667 if ( meScrollType != SCROLL_DONTKNOW )
668 return 0;
669
670 meScrollType = SCROLL_DRAG;
671 long nDelta = ImplSlide( nNewPos, sal_True );
672 meScrollType = SCROLL_DONTKNOW;
673 return nDelta;
674 }
675
676 // -----------------------------------------------------------------------
677
ImplDoSlideAction(ScrollType eScrollType)678 long Slider::ImplDoSlideAction( ScrollType eScrollType )
679 {
680 if ( (meScrollType != SCROLL_DONTKNOW) ||
681 (eScrollType == SCROLL_DONTKNOW) ||
682 (eScrollType == SCROLL_DRAG) )
683 return 0;
684
685 meScrollType = eScrollType;
686 long nDelta = ImplDoAction( sal_True );
687 meScrollType = SCROLL_DONTKNOW;
688 return nDelta;
689 }
690
691 // -----------------------------------------------------------------------
692
MouseButtonDown(const MouseEvent & rMEvt)693 void Slider::MouseButtonDown( const MouseEvent& rMEvt )
694 {
695 if ( rMEvt.IsLeft() )
696 {
697 const Point& rMousePos = rMEvt.GetPosPixel();
698 sal_uInt16 nTrackFlags = 0;
699
700 if ( maThumbRect.IsInside( rMousePos ) )
701 {
702 nTrackFlags = 0;
703 meScrollType = SCROLL_DRAG;
704 mnDragDraw = SLIDER_DRAW_THUMB;
705
706 // Zusaetzliche Daten berechnen
707 Point aCenterPos = maThumbRect.Center();
708 if ( GetStyle() & WB_HORZ )
709 mnMouseOff = rMousePos.X()-aCenterPos.X();
710 else
711 mnMouseOff = rMousePos.Y()-aCenterPos.Y();
712 }
713 else if ( ImplIsPageUp( rMousePos ) )
714 {
715 if( GetStyle() & WB_SLIDERSET )
716 meScrollType = SCROLL_SET;
717 else
718 {
719 nTrackFlags = STARTTRACK_BUTTONREPEAT;
720 meScrollType = SCROLL_PAGEUP;
721 }
722
723 mnDragDraw = SLIDER_DRAW_CHANNEL;
724 }
725 else if ( ImplIsPageDown( rMousePos ) )
726 {
727 if( GetStyle() & WB_SLIDERSET )
728 meScrollType = SCROLL_SET;
729 else
730 {
731 nTrackFlags = STARTTRACK_BUTTONREPEAT;
732 meScrollType = SCROLL_PAGEDOWN;
733 }
734
735 mnDragDraw = SLIDER_DRAW_CHANNEL;
736 }
737
738 // Soll Tracking gestartet werden
739 if( meScrollType != SCROLL_DONTKNOW )
740 {
741 // Startposition merken fuer Abbruch und EndScroll-Delta
742 mnStartPos = mnThumbPos;
743 ImplDoMouseAction( rMousePos, meScrollType != SCROLL_SET );
744 Update();
745
746 if( meScrollType != SCROLL_SET )
747 StartTracking( nTrackFlags );
748 }
749 }
750 }
751
752 // -----------------------------------------------------------------------
753
MouseButtonUp(const MouseEvent &)754 void Slider::MouseButtonUp( const MouseEvent& )
755 {
756 if( SCROLL_SET == meScrollType )
757 {
758 // Button und PageRect-Status wieder herstellen
759 const sal_uInt16 nOldStateFlags = mnStateFlags;
760
761 mnStateFlags &= ~( SLIDER_STATE_CHANNEL1_DOWN | SLIDER_STATE_CHANNEL2_DOWN | SLIDER_STATE_THUMB_DOWN );
762
763 if ( nOldStateFlags != mnStateFlags )
764 ImplDraw( mnDragDraw );
765
766 mnDragDraw = 0;
767 ImplDoAction( sal_True );
768 meScrollType = SCROLL_DONTKNOW;
769 }
770 }
771
772 // -----------------------------------------------------------------------
773
Tracking(const TrackingEvent & rTEvt)774 void Slider::Tracking( const TrackingEvent& rTEvt )
775 {
776 if ( rTEvt.IsTrackingEnded() )
777 {
778 // Button und PageRect-Status wieder herstellen
779 sal_uInt16 nOldStateFlags = mnStateFlags;
780 mnStateFlags &= ~(SLIDER_STATE_CHANNEL1_DOWN | SLIDER_STATE_CHANNEL2_DOWN |
781 SLIDER_STATE_THUMB_DOWN);
782 if ( nOldStateFlags != mnStateFlags )
783 ImplDraw( mnDragDraw );
784 mnDragDraw = 0;
785
786 // Bei Abbruch, die alte ThumbPosition wieder herstellen
787 if ( rTEvt.IsTrackingCanceled() )
788 {
789 long nOldPos = mnThumbPos;
790 SetThumbPos( mnStartPos );
791 mnDelta = mnThumbPos-nOldPos;
792 Slide();
793 }
794
795 if ( meScrollType == SCROLL_DRAG )
796 {
797 // Wenn gedragt wurde, berechnen wir den Thumb neu, damit
798 // er wieder auf einer gerundeten ThumbPosition steht
799 ImplCalc();
800 Update();
801
802 if ( !mbFullDrag && (mnStartPos != mnThumbPos) )
803 {
804 mnDelta = mnThumbPos-mnStartPos;
805 Slide();
806 mnDelta = 0;
807 }
808 }
809
810 mnDelta = mnThumbPos-mnStartPos;
811 EndSlide();
812 mnDelta = 0;
813 meScrollType = SCROLL_DONTKNOW;
814 }
815 else
816 {
817 const Point rMousePos = rTEvt.GetMouseEvent().GetPosPixel();
818
819 // Dragging wird speziell behandelt
820 if ( meScrollType == SCROLL_DRAG )
821 {
822 long nMovePix;
823 Point aCenterPos = maThumbRect.Center();
824 if ( GetStyle() & WB_HORZ )
825 nMovePix = rMousePos.X()-(aCenterPos.X()+mnMouseOff);
826 else
827 nMovePix = rMousePos.Y()-(aCenterPos.Y()+mnMouseOff);
828 // Nur wenn sich Maus in die Scrollrichtung bewegt, muessen
829 // wir etwas tun
830 if ( nMovePix )
831 {
832 mnThumbPixPos += nMovePix;
833 if ( mnThumbPixPos < mnThumbPixOffset )
834 mnThumbPixPos = mnThumbPixOffset;
835 if ( mnThumbPixPos > (mnThumbPixOffset+mnThumbPixRange-1) )
836 mnThumbPixPos = mnThumbPixOffset+mnThumbPixRange-1;
837 long nOldPos = mnThumbPos;
838 mnThumbPos = ImplCalcThumbPos( mnThumbPixPos );
839 if ( nOldPos != mnThumbPos )
840 {
841 ImplUpdateRects();
842 Update();
843 if ( mbFullDrag && (nOldPos != mnThumbPos) )
844 {
845 mnDelta = mnThumbPos-nOldPos;
846 Slide();
847 mnDelta = 0;
848 }
849 }
850 }
851 }
852 else
853 ImplDoMouseAction( rMousePos, rTEvt.IsTrackingRepeat() );
854
855 // Wenn Slider-Werte so umgesetzt wurden, das es nichts
856 // mehr zum Tracking gibt, dann berechen wir hier ab
857 if ( !IsVisible() )
858 EndTracking();
859 }
860 }
861
862 // -----------------------------------------------------------------------
863
KeyInput(const KeyEvent & rKEvt)864 void Slider::KeyInput( const KeyEvent& rKEvt )
865 {
866 if ( !rKEvt.GetKeyCode().GetModifier() )
867 {
868 switch ( rKEvt.GetKeyCode().GetCode() )
869 {
870 case KEY_HOME:
871 ImplDoSlide( GetRangeMin() );
872 break;
873 case KEY_END:
874 ImplDoSlide( GetRangeMax() );
875 break;
876
877 case KEY_LEFT:
878 case KEY_UP:
879 ImplDoSlideAction( SCROLL_LINEUP );
880 break;
881
882 case KEY_RIGHT:
883 case KEY_DOWN:
884 ImplDoSlideAction( SCROLL_LINEDOWN );
885 break;
886
887 case KEY_PAGEUP:
888 ImplDoSlideAction( SCROLL_PAGEUP );
889 break;
890
891 case KEY_PAGEDOWN:
892 ImplDoSlideAction( SCROLL_PAGEDOWN );
893 break;
894
895 default:
896 Control::KeyInput( rKEvt );
897 break;
898 }
899 }
900 else
901 Control::KeyInput( rKEvt );
902 }
903
904 // -----------------------------------------------------------------------
905
Paint(const Rectangle &)906 void Slider::Paint( const Rectangle& )
907 {
908 ImplDraw( SLIDER_DRAW_ALL );
909 }
910
911 // -----------------------------------------------------------------------
912
Resize()913 void Slider::Resize()
914 {
915 Control::Resize();
916 mbCalcSize = sal_True;
917 if ( IsReallyVisible() )
918 ImplCalc( sal_False );
919 Invalidate();
920 }
921
922 // -----------------------------------------------------------------------
923
RequestHelp(const HelpEvent & rHEvt)924 void Slider::RequestHelp( const HelpEvent& rHEvt )
925 {
926 Control::RequestHelp( rHEvt );
927 }
928
929 // -----------------------------------------------------------------------
930
StateChanged(StateChangedType nType)931 void Slider::StateChanged( StateChangedType nType )
932 {
933 Control::StateChanged( nType );
934
935 if ( nType == STATE_CHANGE_INITSHOW )
936 ImplCalc( sal_False );
937 else if ( nType == STATE_CHANGE_DATA )
938 {
939 if ( IsReallyVisible() && IsUpdateMode() )
940 ImplCalc( sal_True );
941 }
942 else if ( nType == STATE_CHANGE_UPDATEMODE )
943 {
944 if ( IsReallyVisible() && IsUpdateMode() )
945 {
946 ImplCalc( sal_False );
947 Invalidate();
948 }
949 }
950 else if ( nType == STATE_CHANGE_ENABLE )
951 {
952 if ( IsReallyVisible() && IsUpdateMode() )
953 Invalidate();
954 }
955 else if ( nType == STATE_CHANGE_STYLE )
956 {
957 if ( IsReallyVisible() && IsUpdateMode() )
958 {
959 if ( (GetPrevStyle() & SLIDER_VIEW_STYLE) !=
960 (GetStyle() & SLIDER_VIEW_STYLE) )
961 {
962 mbCalcSize = sal_True;
963 ImplCalc( sal_False );
964 Invalidate();
965 }
966 }
967 }
968 else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
969 {
970 ImplInitSettings();
971 Invalidate();
972 }
973 }
974
975 // -----------------------------------------------------------------------
976
DataChanged(const DataChangedEvent & rDCEvt)977 void Slider::DataChanged( const DataChangedEvent& rDCEvt )
978 {
979 Control::DataChanged( rDCEvt );
980
981 if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
982 (rDCEvt.GetFlags() & SETTINGS_STYLE) )
983 {
984 ImplInitSettings();
985 Invalidate();
986 }
987 }
988
989 // -----------------------------------------------------------------------
990
Slide()991 void Slider::Slide()
992 {
993 maSlideHdl.Call( this );
994 }
995
996 // -----------------------------------------------------------------------
997
EndSlide()998 void Slider::EndSlide()
999 {
1000 maEndSlideHdl.Call( this );
1001 }
1002
1003 // -----------------------------------------------------------------------
1004
SetRangeMin(long nNewRange)1005 void Slider::SetRangeMin( long nNewRange )
1006 {
1007 SetRange( Range( nNewRange, GetRangeMax() ) );
1008 }
1009
1010 // -----------------------------------------------------------------------
1011
SetRangeMax(long nNewRange)1012 void Slider::SetRangeMax( long nNewRange )
1013 {
1014 SetRange( Range( GetRangeMin(), nNewRange ) );
1015 }
1016
1017 // -----------------------------------------------------------------------
1018
SetRange(const Range & rRange)1019 void Slider::SetRange( const Range& rRange )
1020 {
1021 // Range einpassen
1022 Range aRange = rRange;
1023 aRange.Justify();
1024 long nNewMinRange = aRange.Min();
1025 long nNewMaxRange = aRange.Max();
1026
1027 // Wenn Range sich unterscheidet, dann neuen setzen
1028 if ( (mnMinRange != nNewMinRange) ||
1029 (mnMaxRange != nNewMaxRange) )
1030 {
1031 mnMinRange = nNewMinRange;
1032 mnMaxRange = nNewMaxRange;
1033
1034 // Thumb einpassen
1035 if ( mnThumbPos > mnMaxRange )
1036 mnThumbPos = mnMaxRange;
1037 if ( mnThumbPos < mnMinRange )
1038 mnThumbPos = mnMinRange;
1039
1040 StateChanged( STATE_CHANGE_DATA );
1041 }
1042 }
1043
1044 // -----------------------------------------------------------------------
1045
SetThumbPos(long nNewThumbPos)1046 void Slider::SetThumbPos( long nNewThumbPos )
1047 {
1048 if ( nNewThumbPos < mnMinRange )
1049 nNewThumbPos = mnMinRange;
1050 if ( nNewThumbPos > mnMaxRange )
1051 nNewThumbPos = mnMaxRange;
1052
1053 if ( mnThumbPos != nNewThumbPos )
1054 {
1055 mnThumbPos = nNewThumbPos;
1056 StateChanged( STATE_CHANGE_DATA );
1057 }
1058 }
1059
1060 // -----------------------------------------------------------------------
1061
CalcWindowSizePixel()1062 Size Slider::CalcWindowSizePixel()
1063 {
1064 long nWidth = mnMaxRange-mnMinRange+(SLIDER_THUMB_HALFSIZE*2)+1;
1065 long nHeight = SLIDER_HEIGHT;
1066 Size aSize;
1067 if ( GetStyle() & WB_HORZ )
1068 {
1069 aSize.Width() = nWidth;
1070 aSize.Height() = nHeight;
1071 }
1072 else
1073 {
1074 aSize.Height() = nWidth;
1075 aSize.Width() = nHeight;
1076 }
1077 return aSize;
1078 }
1079