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