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