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