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(), rtl::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(), rtl::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 : // Position berechnen
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 : // Position berechnen
237 : long nCalcThumbPos;
238 0 : nCalcThumbPos = ImplMulDiv( nPos-mnMinRange, mnThumbPixRange-1, mnMaxRange-mnMinRange );
239 : // Am Anfang und Ende des Sliders versuchen wir die Anzeige korrekt
240 : // anzuzeigen
241 0 : if ( !nCalcThumbPos && (mnThumbPos > mnMinRange) )
242 0 : nCalcThumbPos = 1;
243 0 : if ( nCalcThumbPos &&
244 : (nCalcThumbPos == mnThumbPixRange-1) &&
245 : (mnThumbPos < mnMaxRange) )
246 0 : nCalcThumbPos--;
247 0 : return nCalcThumbPos+mnThumbPixOffset;
248 : }
249 :
250 : // -----------------------------------------------------------------------
251 :
252 0 : void Slider::ImplCalc( sal_Bool bUpdate )
253 : {
254 0 : sal_Bool bInvalidateAll = sal_False;
255 :
256 0 : if ( mbCalcSize )
257 : {
258 0 : long nOldChannelPixOffset = mnChannelPixOffset;
259 0 : long nOldChannelPixRange = mnChannelPixRange;
260 0 : long nOldChannelPixTop = mnChannelPixTop;
261 0 : long nOldChannelPixBottom = mnChannelPixBottom;
262 : long nCalcWidth;
263 : long nCalcHeight;
264 :
265 0 : maChannel1Rect.SetEmpty();
266 0 : maChannel2Rect.SetEmpty();
267 0 : maThumbRect.SetEmpty();
268 :
269 0 : Size aSize = GetOutputSizePixel();
270 0 : if ( GetStyle() & WB_HORZ )
271 : {
272 0 : nCalcWidth = aSize.Width();
273 0 : nCalcHeight = aSize.Height();
274 0 : maThumbRect.Top() = 0;
275 0 : maThumbRect.Bottom()= aSize.Height()-1;
276 : }
277 : else
278 : {
279 0 : nCalcWidth = aSize.Height();
280 0 : nCalcHeight = aSize.Width();
281 0 : maThumbRect.Left() = 0;
282 0 : maThumbRect.Right() = aSize.Width()-1;
283 : }
284 :
285 0 : if ( nCalcWidth >= SLIDER_THUMB_SIZE )
286 : {
287 0 : mnThumbPixOffset = SLIDER_THUMB_HALFSIZE;
288 0 : mnThumbPixRange = nCalcWidth-(SLIDER_THUMB_HALFSIZE*2);
289 0 : mnThumbPixPos = 0;
290 0 : mnChannelPixOffset = SLIDER_CHANNEL_OFFSET;
291 0 : mnChannelPixRange = nCalcWidth-(SLIDER_CHANNEL_OFFSET*2);
292 0 : mnChannelPixTop = (nCalcHeight/2)-SLIDER_CHANNEL_HALFSIZE;
293 0 : mnChannelPixBottom = mnChannelPixTop+SLIDER_CHANNEL_SIZE-1;
294 : }
295 : else
296 : {
297 0 : mnThumbPixRange = 0;
298 0 : mnChannelPixRange = 0;
299 : }
300 :
301 0 : if ( (nOldChannelPixOffset != mnChannelPixOffset) ||
302 : (nOldChannelPixRange != mnChannelPixRange) ||
303 : (nOldChannelPixTop != mnChannelPixTop) ||
304 : (nOldChannelPixBottom != mnChannelPixBottom) )
305 0 : bInvalidateAll = sal_True;
306 :
307 0 : mbCalcSize = sal_False;
308 : }
309 :
310 0 : if ( mnThumbPixRange )
311 0 : mnThumbPixPos = ImplCalcThumbPosPix( mnThumbPos );
312 :
313 0 : if ( bUpdate && bInvalidateAll )
314 : {
315 0 : Invalidate();
316 0 : bUpdate = sal_False;
317 : }
318 0 : ImplUpdateRects( bUpdate );
319 0 : }
320 :
321 : // -----------------------------------------------------------------------
322 :
323 0 : void Slider::ImplDraw( sal_uInt16 nDrawFlags )
324 : {
325 0 : DecorationView aDecoView( this );
326 : sal_uInt16 nStyle;
327 0 : const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
328 0 : sal_Bool bEnabled = IsEnabled();
329 :
330 : // Evt. noch offene Berechnungen nachholen
331 0 : if ( mbCalcSize )
332 0 : ImplCalc( sal_False );
333 :
334 0 : ControlPart nPart = (GetStyle() & WB_HORZ) ? PART_TRACK_HORZ_AREA : PART_TRACK_VERT_AREA;
335 0 : ControlState nState = ( IsEnabled() ? CTRL_STATE_ENABLED : 0 ) | ( HasFocus() ? CTRL_STATE_FOCUSED : 0 );
336 0 : SliderValue sldValue;
337 :
338 0 : sldValue.mnMin = mnMinRange;
339 0 : sldValue.mnMax = mnMaxRange;
340 0 : sldValue.mnCur = mnThumbPos;
341 0 : sldValue.maThumbRect = maThumbRect;
342 :
343 0 : if( IsMouseOver() )
344 : {
345 0 : if( maThumbRect.IsInside( GetPointerPosPixel() ) )
346 0 : sldValue.mnThumbState |= CTRL_STATE_ROLLOVER;
347 : }
348 :
349 0 : const Rectangle aCtrlRegion( Point(0,0), GetOutputSizePixel() );
350 : bool bNativeOK = DrawNativeControl( CTRL_SLIDER, nPart,
351 0 : aCtrlRegion, nState, sldValue, rtl::OUString() );
352 0 : if( bNativeOK )
353 0 : return;
354 :
355 0 : if ( (nDrawFlags & SLIDER_DRAW_CHANNEL1) && !maChannel1Rect.IsEmpty() )
356 : {
357 : long nRectSize;
358 0 : Rectangle aRect = maChannel1Rect;
359 0 : SetLineColor( rStyleSettings.GetShadowColor() );
360 0 : if ( GetStyle() & WB_HORZ )
361 : {
362 0 : DrawLine( aRect.TopLeft(), Point( aRect.Left(), aRect.Bottom()-1 ) );
363 0 : DrawLine( aRect.TopLeft(), aRect.TopRight() );
364 : }
365 : else
366 : {
367 0 : DrawLine( aRect.TopLeft(), Point( aRect.Right()-1, aRect.Top() ) );
368 0 : DrawLine( aRect.TopLeft(), aRect.BottomLeft() );
369 : }
370 0 : SetLineColor( rStyleSettings.GetLightColor() );
371 0 : if ( GetStyle() & WB_HORZ )
372 : {
373 0 : DrawLine( aRect.BottomLeft(), aRect.BottomRight() );
374 0 : nRectSize = aRect.GetWidth();
375 : }
376 : else
377 : {
378 0 : DrawLine( aRect.TopRight(), aRect.BottomRight() );
379 0 : nRectSize = aRect.GetHeight();
380 : }
381 :
382 0 : if ( nRectSize > 1 )
383 : {
384 0 : aRect.Left()++;
385 0 : aRect.Top()++;
386 0 : if ( GetStyle() & WB_HORZ )
387 0 : aRect.Bottom()--;
388 : else
389 0 : aRect.Right()--;
390 0 : SetLineColor();
391 0 : if ( mnStateFlags & SLIDER_STATE_CHANNEL1_DOWN )
392 0 : SetFillColor( rStyleSettings.GetShadowColor() );
393 : else
394 0 : SetFillColor( rStyleSettings.GetCheckedColor() );
395 0 : DrawRect( aRect );
396 : }
397 : }
398 :
399 0 : if ( (nDrawFlags & SLIDER_DRAW_CHANNEL2) && !maChannel2Rect.IsEmpty() )
400 : {
401 : long nRectSize;
402 0 : Rectangle aRect = maChannel2Rect;
403 0 : SetLineColor( rStyleSettings.GetLightColor() );
404 0 : if ( GetStyle() & WB_HORZ )
405 : {
406 0 : DrawLine( aRect.TopRight(), aRect.BottomRight() );
407 0 : DrawLine( aRect.BottomLeft(), aRect.BottomRight() );
408 0 : nRectSize = aRect.GetWidth();
409 : }
410 : else
411 : {
412 0 : DrawLine( aRect.BottomLeft(), aRect.BottomRight() );
413 0 : DrawLine( aRect.TopRight(), aRect.BottomRight() );
414 0 : nRectSize = aRect.GetHeight();
415 : }
416 :
417 0 : if ( nRectSize > 1 )
418 : {
419 0 : SetLineColor( rStyleSettings.GetShadowColor() );
420 0 : if ( GetStyle() & WB_HORZ )
421 0 : DrawLine( aRect.TopLeft(), Point( aRect.Right()-1, aRect.Top() ) );
422 : else
423 0 : DrawLine( aRect.TopLeft(), Point( aRect.Left(), aRect.Bottom()-1 ) );
424 :
425 0 : aRect.Right()--;
426 0 : aRect.Bottom()--;
427 0 : if ( GetStyle() & WB_HORZ )
428 0 : aRect.Top()++;
429 : else
430 0 : aRect.Left()++;
431 0 : SetLineColor();
432 0 : if ( mnStateFlags & SLIDER_STATE_CHANNEL2_DOWN )
433 0 : SetFillColor( rStyleSettings.GetShadowColor() );
434 : else
435 0 : SetFillColor( rStyleSettings.GetCheckedColor() );
436 0 : DrawRect( aRect );
437 : }
438 : }
439 :
440 0 : if ( nDrawFlags & SLIDER_DRAW_THUMB )
441 : {
442 0 : if ( !maThumbRect.IsEmpty() )
443 : {
444 0 : if ( bEnabled )
445 : {
446 0 : nStyle = 0;
447 0 : if ( mnStateFlags & SLIDER_STATE_THUMB_DOWN )
448 0 : nStyle |= BUTTON_DRAW_PRESSED;
449 0 : aDecoView.DrawButton( maThumbRect, nStyle );
450 : }
451 : else
452 : {
453 0 : SetLineColor( rStyleSettings.GetShadowColor() );
454 0 : SetFillColor( rStyleSettings.GetCheckedColor() );
455 0 : DrawRect( maThumbRect );
456 : }
457 : }
458 0 : }
459 : }
460 :
461 : // -----------------------------------------------------------------------
462 :
463 0 : sal_Bool Slider::ImplIsPageUp( const Point& rPos )
464 : {
465 0 : Size aSize = GetOutputSizePixel();
466 0 : Rectangle aRect = maChannel1Rect;
467 0 : if ( GetStyle() & WB_HORZ )
468 : {
469 0 : aRect.Top() = 0;
470 0 : aRect.Bottom() = aSize.Height()-1;
471 : }
472 : else
473 : {
474 0 : aRect.Left() = 0;
475 0 : aRect.Right() = aSize.Width()-1;
476 : }
477 0 : return aRect.IsInside( rPos );
478 : }
479 :
480 : // -----------------------------------------------------------------------
481 :
482 0 : sal_Bool Slider::ImplIsPageDown( const Point& rPos )
483 : {
484 0 : Size aSize = GetOutputSizePixel();
485 0 : Rectangle aRect = maChannel2Rect;
486 0 : if ( GetStyle() & WB_HORZ )
487 : {
488 0 : aRect.Top() = 0;
489 0 : aRect.Bottom() = aSize.Height()-1;
490 : }
491 : else
492 : {
493 0 : aRect.Left() = 0;
494 0 : aRect.Right() = aSize.Width()-1;
495 : }
496 0 : return aRect.IsInside( rPos );
497 : }
498 :
499 : // -----------------------------------------------------------------------
500 :
501 0 : long Slider::ImplSlide( long nNewPos, sal_Bool bCallEndSlide )
502 : {
503 0 : long nOldPos = mnThumbPos;
504 0 : SetThumbPos( nNewPos );
505 0 : long nDelta = mnThumbPos-nOldPos;
506 0 : if ( nDelta )
507 : {
508 0 : mnDelta = nDelta;
509 0 : Slide();
510 0 : if ( bCallEndSlide )
511 0 : EndSlide();
512 0 : mnDelta = 0;
513 : }
514 0 : return nDelta;
515 : }
516 :
517 : // -----------------------------------------------------------------------
518 :
519 0 : long Slider::ImplDoAction( sal_Bool bCallEndSlide )
520 : {
521 0 : long nDelta = 0;
522 :
523 0 : switch ( meScrollType )
524 : {
525 : case SCROLL_LINEUP:
526 0 : nDelta = ImplSlide( mnThumbPos-mnLineSize, bCallEndSlide );
527 0 : break;
528 :
529 : case SCROLL_LINEDOWN:
530 0 : nDelta = ImplSlide( mnThumbPos+mnLineSize, bCallEndSlide );
531 0 : break;
532 :
533 : case SCROLL_PAGEUP:
534 0 : nDelta = ImplSlide( mnThumbPos-mnPageSize, bCallEndSlide );
535 0 : break;
536 :
537 : case SCROLL_PAGEDOWN:
538 0 : nDelta = ImplSlide( mnThumbPos+mnPageSize, bCallEndSlide );
539 0 : break;
540 :
541 : case SCROLL_SET:
542 0 : nDelta = ImplSlide( ImplCalcThumbPos( GetPointerPosPixel().X() ), bCallEndSlide );
543 0 : break;
544 : default:
545 0 : break;
546 : }
547 :
548 0 : return nDelta;
549 : }
550 :
551 : // -----------------------------------------------------------------------
552 :
553 0 : void Slider::ImplDoMouseAction( const Point& rMousePos, sal_Bool bCallAction )
554 : {
555 0 : sal_uInt16 nOldStateFlags = mnStateFlags;
556 0 : sal_Bool bAction = sal_False;
557 :
558 0 : switch ( meScrollType )
559 : {
560 : case( SCROLL_SET ):
561 : {
562 0 : const bool bUp = ImplIsPageUp( rMousePos ), bDown = ImplIsPageDown( rMousePos );
563 :
564 0 : if ( bUp || bDown )
565 : {
566 0 : bAction = bCallAction;
567 0 : mnStateFlags |= ( bUp ? SLIDER_STATE_CHANNEL1_DOWN : SLIDER_STATE_CHANNEL2_DOWN );
568 : }
569 : else
570 0 : mnStateFlags &= ~( SLIDER_STATE_CHANNEL1_DOWN | SLIDER_STATE_CHANNEL2_DOWN );
571 0 : break;
572 : }
573 :
574 : case SCROLL_PAGEUP:
575 0 : if ( ImplIsPageUp( rMousePos ) )
576 : {
577 0 : bAction = bCallAction;
578 0 : mnStateFlags |= SLIDER_STATE_CHANNEL1_DOWN;
579 : }
580 : else
581 0 : mnStateFlags &= ~SLIDER_STATE_CHANNEL1_DOWN;
582 0 : break;
583 :
584 : case SCROLL_PAGEDOWN:
585 0 : if ( ImplIsPageDown( rMousePos ) )
586 : {
587 0 : bAction = bCallAction;
588 0 : mnStateFlags |= SLIDER_STATE_CHANNEL2_DOWN;
589 : }
590 : else
591 0 : mnStateFlags &= ~SLIDER_STATE_CHANNEL2_DOWN;
592 0 : break;
593 : default:
594 0 : break;
595 : }
596 :
597 0 : if ( bAction )
598 : {
599 0 : if ( ImplDoAction( sal_False ) )
600 : {
601 : // Update the channel complete
602 0 : if ( mnDragDraw & SLIDER_DRAW_CHANNEL )
603 : {
604 0 : Update();
605 0 : ImplDraw( mnDragDraw );
606 : }
607 : }
608 : }
609 0 : else if ( nOldStateFlags != mnStateFlags )
610 0 : ImplDraw( mnDragDraw );
611 0 : }
612 :
613 : // -----------------------------------------------------------------------
614 :
615 0 : long Slider::ImplDoSlide( long nNewPos )
616 : {
617 0 : if ( meScrollType != SCROLL_DONTKNOW )
618 0 : return 0;
619 :
620 0 : meScrollType = SCROLL_DRAG;
621 0 : long nDelta = ImplSlide( nNewPos, sal_True );
622 0 : meScrollType = SCROLL_DONTKNOW;
623 0 : return nDelta;
624 : }
625 :
626 : // -----------------------------------------------------------------------
627 :
628 0 : long Slider::ImplDoSlideAction( ScrollType eScrollType )
629 : {
630 0 : if ( (meScrollType != SCROLL_DONTKNOW) ||
631 : (eScrollType == SCROLL_DONTKNOW) ||
632 : (eScrollType == SCROLL_DRAG) )
633 0 : return 0;
634 :
635 0 : meScrollType = eScrollType;
636 0 : long nDelta = ImplDoAction( sal_True );
637 0 : meScrollType = SCROLL_DONTKNOW;
638 0 : return nDelta;
639 : }
640 :
641 : // -----------------------------------------------------------------------
642 :
643 0 : void Slider::MouseButtonDown( const MouseEvent& rMEvt )
644 : {
645 0 : if ( rMEvt.IsLeft() )
646 : {
647 0 : const Point& rMousePos = rMEvt.GetPosPixel();
648 0 : sal_uInt16 nTrackFlags = 0;
649 :
650 0 : if ( maThumbRect.IsInside( rMousePos ) )
651 : {
652 0 : nTrackFlags = 0;
653 0 : meScrollType = SCROLL_DRAG;
654 0 : mnDragDraw = SLIDER_DRAW_THUMB;
655 :
656 : // Zusaetzliche Daten berechnen
657 0 : Point aCenterPos = maThumbRect.Center();
658 0 : if ( GetStyle() & WB_HORZ )
659 0 : mnMouseOff = rMousePos.X()-aCenterPos.X();
660 : else
661 0 : mnMouseOff = rMousePos.Y()-aCenterPos.Y();
662 : }
663 0 : else if ( ImplIsPageUp( rMousePos ) )
664 : {
665 0 : if( GetStyle() & WB_SLIDERSET )
666 0 : meScrollType = SCROLL_SET;
667 : else
668 : {
669 0 : nTrackFlags = STARTTRACK_BUTTONREPEAT;
670 0 : meScrollType = SCROLL_PAGEUP;
671 : }
672 :
673 0 : mnDragDraw = SLIDER_DRAW_CHANNEL;
674 : }
675 0 : else if ( ImplIsPageDown( rMousePos ) )
676 : {
677 0 : if( GetStyle() & WB_SLIDERSET )
678 0 : meScrollType = SCROLL_SET;
679 : else
680 : {
681 0 : nTrackFlags = STARTTRACK_BUTTONREPEAT;
682 0 : meScrollType = SCROLL_PAGEDOWN;
683 : }
684 :
685 0 : mnDragDraw = SLIDER_DRAW_CHANNEL;
686 : }
687 :
688 : // Soll Tracking gestartet werden
689 0 : if( meScrollType != SCROLL_DONTKNOW )
690 : {
691 : // Startposition merken fuer Abbruch und EndScroll-Delta
692 0 : mnStartPos = mnThumbPos;
693 0 : ImplDoMouseAction( rMousePos, meScrollType != SCROLL_SET );
694 0 : Update();
695 :
696 0 : if( meScrollType != SCROLL_SET )
697 0 : StartTracking( nTrackFlags );
698 : }
699 : }
700 0 : }
701 :
702 : // -----------------------------------------------------------------------
703 :
704 0 : void Slider::MouseButtonUp( const MouseEvent& )
705 : {
706 0 : if( SCROLL_SET == meScrollType )
707 : {
708 : // Button und PageRect-Status wieder herstellen
709 0 : const sal_uInt16 nOldStateFlags = mnStateFlags;
710 :
711 0 : mnStateFlags &= ~( SLIDER_STATE_CHANNEL1_DOWN | SLIDER_STATE_CHANNEL2_DOWN | SLIDER_STATE_THUMB_DOWN );
712 :
713 0 : if ( nOldStateFlags != mnStateFlags )
714 0 : ImplDraw( mnDragDraw );
715 :
716 0 : mnDragDraw = 0;
717 0 : ImplDoAction( sal_True );
718 0 : meScrollType = SCROLL_DONTKNOW;
719 : }
720 0 : }
721 :
722 : // -----------------------------------------------------------------------
723 :
724 0 : void Slider::Tracking( const TrackingEvent& rTEvt )
725 : {
726 0 : if ( rTEvt.IsTrackingEnded() )
727 : {
728 : // Button und PageRect-Status wieder herstellen
729 0 : sal_uInt16 nOldStateFlags = mnStateFlags;
730 : mnStateFlags &= ~(SLIDER_STATE_CHANNEL1_DOWN | SLIDER_STATE_CHANNEL2_DOWN |
731 0 : SLIDER_STATE_THUMB_DOWN);
732 0 : if ( nOldStateFlags != mnStateFlags )
733 0 : ImplDraw( mnDragDraw );
734 0 : mnDragDraw = 0;
735 :
736 : // Bei Abbruch, die alte ThumbPosition wieder herstellen
737 0 : if ( rTEvt.IsTrackingCanceled() )
738 : {
739 0 : long nOldPos = mnThumbPos;
740 0 : SetThumbPos( mnStartPos );
741 0 : mnDelta = mnThumbPos-nOldPos;
742 0 : Slide();
743 : }
744 :
745 0 : if ( meScrollType == SCROLL_DRAG )
746 : {
747 : // Wenn gedragt wurde, berechnen wir den Thumb neu, damit
748 : // er wieder auf einer gerundeten ThumbPosition steht
749 0 : ImplCalc();
750 0 : Update();
751 :
752 0 : if ( !mbFullDrag && (mnStartPos != mnThumbPos) )
753 : {
754 0 : mnDelta = mnThumbPos-mnStartPos;
755 0 : Slide();
756 0 : mnDelta = 0;
757 : }
758 : }
759 :
760 0 : mnDelta = mnThumbPos-mnStartPos;
761 0 : EndSlide();
762 0 : mnDelta = 0;
763 0 : meScrollType = SCROLL_DONTKNOW;
764 : }
765 : else
766 : {
767 0 : const Point rMousePos = rTEvt.GetMouseEvent().GetPosPixel();
768 :
769 : // Dragging wird speziell behandelt
770 0 : if ( meScrollType == SCROLL_DRAG )
771 : {
772 : long nMovePix;
773 0 : Point aCenterPos = maThumbRect.Center();
774 0 : if ( GetStyle() & WB_HORZ )
775 0 : nMovePix = rMousePos.X()-(aCenterPos.X()+mnMouseOff);
776 : else
777 0 : nMovePix = rMousePos.Y()-(aCenterPos.Y()+mnMouseOff);
778 : // Nur wenn sich Maus in die Scrollrichtung bewegt, muessen
779 : // wir etwas tun
780 0 : if ( nMovePix )
781 : {
782 0 : mnThumbPixPos += nMovePix;
783 0 : if ( mnThumbPixPos < mnThumbPixOffset )
784 0 : mnThumbPixPos = mnThumbPixOffset;
785 0 : if ( mnThumbPixPos > (mnThumbPixOffset+mnThumbPixRange-1) )
786 0 : mnThumbPixPos = mnThumbPixOffset+mnThumbPixRange-1;
787 0 : long nOldPos = mnThumbPos;
788 0 : mnThumbPos = ImplCalcThumbPos( mnThumbPixPos );
789 0 : if ( nOldPos != mnThumbPos )
790 : {
791 0 : ImplUpdateRects();
792 0 : Update();
793 0 : if ( mbFullDrag && (nOldPos != mnThumbPos) )
794 : {
795 0 : mnDelta = mnThumbPos-nOldPos;
796 0 : Slide();
797 0 : mnDelta = 0;
798 : }
799 : }
800 : }
801 : }
802 : else
803 0 : ImplDoMouseAction( rMousePos, rTEvt.IsTrackingRepeat() );
804 :
805 : // Wenn Slider-Werte so umgesetzt wurden, das es nichts
806 : // mehr zum Tracking gibt, dann berechen wir hier ab
807 0 : if ( !IsVisible() )
808 0 : EndTracking();
809 : }
810 0 : }
811 :
812 : // -----------------------------------------------------------------------
813 :
814 0 : void Slider::KeyInput( const KeyEvent& rKEvt )
815 : {
816 0 : if ( !rKEvt.GetKeyCode().GetModifier() )
817 : {
818 0 : switch ( rKEvt.GetKeyCode().GetCode() )
819 : {
820 : case KEY_HOME:
821 0 : ImplDoSlide( GetRangeMin() );
822 0 : break;
823 : case KEY_END:
824 0 : ImplDoSlide( GetRangeMax() );
825 0 : break;
826 :
827 : case KEY_LEFT:
828 : case KEY_UP:
829 0 : ImplDoSlideAction( SCROLL_LINEUP );
830 0 : break;
831 :
832 : case KEY_RIGHT:
833 : case KEY_DOWN:
834 0 : ImplDoSlideAction( SCROLL_LINEDOWN );
835 0 : break;
836 :
837 : case KEY_PAGEUP:
838 0 : ImplDoSlideAction( SCROLL_PAGEUP );
839 0 : break;
840 :
841 : case KEY_PAGEDOWN:
842 0 : ImplDoSlideAction( SCROLL_PAGEDOWN );
843 0 : break;
844 :
845 : default:
846 0 : Control::KeyInput( rKEvt );
847 0 : break;
848 : }
849 : }
850 : else
851 0 : Control::KeyInput( rKEvt );
852 0 : }
853 :
854 : // -----------------------------------------------------------------------
855 :
856 0 : void Slider::Paint( const Rectangle& )
857 : {
858 0 : ImplDraw( SLIDER_DRAW_ALL );
859 0 : }
860 :
861 : // -----------------------------------------------------------------------
862 :
863 0 : void Slider::Resize()
864 : {
865 0 : Control::Resize();
866 0 : mbCalcSize = sal_True;
867 0 : if ( IsReallyVisible() )
868 0 : ImplCalc( sal_False );
869 0 : Invalidate();
870 0 : }
871 :
872 : // -----------------------------------------------------------------------
873 :
874 0 : void Slider::RequestHelp( const HelpEvent& rHEvt )
875 : {
876 0 : Control::RequestHelp( rHEvt );
877 0 : }
878 :
879 : // -----------------------------------------------------------------------
880 :
881 0 : void Slider::StateChanged( StateChangedType nType )
882 : {
883 0 : Control::StateChanged( nType );
884 :
885 0 : if ( nType == STATE_CHANGE_INITSHOW )
886 0 : ImplCalc( sal_False );
887 0 : else if ( nType == STATE_CHANGE_DATA )
888 : {
889 0 : if ( IsReallyVisible() && IsUpdateMode() )
890 0 : ImplCalc( sal_True );
891 : }
892 0 : else if ( nType == STATE_CHANGE_UPDATEMODE )
893 : {
894 0 : if ( IsReallyVisible() && IsUpdateMode() )
895 : {
896 0 : ImplCalc( sal_False );
897 0 : Invalidate();
898 : }
899 : }
900 0 : else if ( nType == STATE_CHANGE_ENABLE )
901 : {
902 0 : if ( IsReallyVisible() && IsUpdateMode() )
903 0 : Invalidate();
904 : }
905 0 : else if ( nType == STATE_CHANGE_STYLE )
906 : {
907 0 : if ( IsReallyVisible() && IsUpdateMode() )
908 : {
909 0 : if ( (GetPrevStyle() & SLIDER_VIEW_STYLE) !=
910 0 : (GetStyle() & SLIDER_VIEW_STYLE) )
911 : {
912 0 : mbCalcSize = sal_True;
913 0 : ImplCalc( sal_False );
914 0 : Invalidate();
915 : }
916 : }
917 : }
918 0 : else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
919 : {
920 0 : ImplInitSettings();
921 0 : Invalidate();
922 : }
923 0 : }
924 :
925 : // -----------------------------------------------------------------------
926 :
927 0 : void Slider::DataChanged( const DataChangedEvent& rDCEvt )
928 : {
929 0 : Control::DataChanged( rDCEvt );
930 :
931 0 : if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
932 0 : (rDCEvt.GetFlags() & SETTINGS_STYLE) )
933 : {
934 0 : ImplInitSettings();
935 0 : Invalidate();
936 : }
937 0 : }
938 :
939 : // -----------------------------------------------------------------------
940 :
941 0 : void Slider::Slide()
942 : {
943 0 : maSlideHdl.Call( this );
944 0 : }
945 :
946 : // -----------------------------------------------------------------------
947 :
948 0 : void Slider::EndSlide()
949 : {
950 0 : maEndSlideHdl.Call( this );
951 0 : }
952 :
953 : // -----------------------------------------------------------------------
954 :
955 0 : void Slider::SetRange( const Range& rRange )
956 : {
957 : // Range einpassen
958 0 : Range aRange = rRange;
959 0 : aRange.Justify();
960 0 : long nNewMinRange = aRange.Min();
961 0 : long nNewMaxRange = aRange.Max();
962 :
963 : // Wenn Range sich unterscheidet, dann neuen setzen
964 0 : if ( (mnMinRange != nNewMinRange) ||
965 : (mnMaxRange != nNewMaxRange) )
966 : {
967 0 : mnMinRange = nNewMinRange;
968 0 : mnMaxRange = nNewMaxRange;
969 :
970 : // Thumb einpassen
971 0 : if ( mnThumbPos > mnMaxRange )
972 0 : mnThumbPos = mnMaxRange;
973 0 : if ( mnThumbPos < mnMinRange )
974 0 : mnThumbPos = mnMinRange;
975 :
976 0 : StateChanged( STATE_CHANGE_DATA );
977 : }
978 0 : }
979 :
980 : // -----------------------------------------------------------------------
981 :
982 0 : void Slider::SetThumbPos( long nNewThumbPos )
983 : {
984 0 : if ( nNewThumbPos < mnMinRange )
985 0 : nNewThumbPos = mnMinRange;
986 0 : if ( nNewThumbPos > mnMaxRange )
987 0 : nNewThumbPos = mnMaxRange;
988 :
989 0 : if ( mnThumbPos != nNewThumbPos )
990 : {
991 0 : mnThumbPos = nNewThumbPos;
992 0 : StateChanged( STATE_CHANGE_DATA );
993 : }
994 0 : }
995 :
996 : // -----------------------------------------------------------------------
997 :
998 0 : Size Slider::CalcWindowSizePixel()
999 : {
1000 0 : long nWidth = mnMaxRange-mnMinRange+(SLIDER_THUMB_HALFSIZE*2)+1;
1001 0 : long nHeight = SLIDER_HEIGHT;
1002 0 : Size aSize;
1003 0 : if ( GetStyle() & WB_HORZ )
1004 : {
1005 0 : aSize.Width() = nWidth;
1006 0 : aSize.Height() = nHeight;
1007 : }
1008 : else
1009 : {
1010 0 : aSize.Height() = nWidth;
1011 0 : aSize.Width() = nHeight;
1012 : }
1013 0 : return aSize;
1014 : }
1015 :
1016 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|