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