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