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