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 #include <tools/rc.h> 28 #include <tools/poly.hxx> 29 30 #include <vcl/event.hxx> 31 #include <vcl/split.hxx> 32 #include <vcl/svapp.hxx> 33 #include <vcl/syswin.hxx> 34 #include <vcl/taskpanelist.hxx> 35 #include <vcl/gradient.hxx> 36 #include <vcl/lineinfo.hxx> 37 38 #include <rtl/instance.hxx> 39 40 #include <window.h> 41 42 namespace 43 { 44 struct ImplBlackWall 45 : public rtl::StaticWithInit<Wallpaper, ImplBlackWall> { 46 Wallpaper operator () () { 47 return Wallpaper(COL_BLACK); 48 } 49 }; 50 struct ImplWhiteWall 51 : public rtl::StaticWithInit<Wallpaper, ImplWhiteWall> { 52 Wallpaper operator () () { 53 return Wallpaper(COL_LIGHTGRAY); 54 } 55 }; 56 } 57 58 // ======================================================================= 59 60 void Splitter::ImplInitSplitterData() 61 { 62 ImplGetWindowImpl()->mbSplitter = sal_True; 63 mpRefWin = NULL; 64 mnSplitPos = 0; 65 mnLastSplitPos = 0; 66 mnStartSplitPos = 0; 67 mbDragFull = sal_False; 68 mbKbdSplitting = sal_False; 69 mbInKeyEvent = 0; 70 mnKeyboardStepSize = SPLITTER_DEFAULTSTEPSIZE; 71 } 72 73 // ----------------------------------------------------------------------- 74 75 void Splitter::ImplInit( Window* pParent, WinBits nWinStyle ) 76 { 77 Window::ImplInit( pParent, nWinStyle, NULL ); 78 79 mpRefWin = pParent; 80 81 const StyleSettings& rSettings = GetSettings().GetStyleSettings(); 82 long nA = rSettings.GetScrollBarSize(); 83 long nB = rSettings.GetSplitSize(); 84 85 PointerStyle ePointerStyle; 86 87 if ( nWinStyle & WB_HSCROLL ) 88 { 89 ePointerStyle = POINTER_HSPLIT; 90 mbHorzSplit = sal_True; 91 SetSizePixel( Size( nB, nA ) ); 92 } 93 else 94 { 95 ePointerStyle = POINTER_VSPLIT; 96 mbHorzSplit = sal_False; 97 SetSizePixel( Size( nA, nB ) ); 98 } 99 100 SetPointer( Pointer( ePointerStyle ) ); 101 102 if( GetSettings().GetStyleSettings().GetFaceColor().IsDark() ) 103 SetBackground( ImplWhiteWall::get() ); 104 else 105 SetBackground( ImplBlackWall::get() ); 106 107 TaskPaneList *pTList = GetSystemWindow()->GetTaskPaneList(); 108 pTList->AddWindow( this ); 109 } 110 111 // ----------------------------------------------------------------------- 112 113 void Splitter::ImplSplitMousePos( Point& rPos ) 114 { 115 if ( mbHorzSplit ) 116 { 117 if ( rPos.X() > maDragRect.Right()-1 ) 118 rPos.X() = maDragRect.Right()-1; 119 if ( rPos.X() < maDragRect.Left()+1 ) 120 rPos.X() = maDragRect.Left()+1; 121 } 122 else 123 { 124 if ( rPos.Y() > maDragRect.Bottom()-1 ) 125 rPos.Y() = maDragRect.Bottom()-1; 126 if ( rPos.Y() < maDragRect.Top()+1 ) 127 rPos.Y() = maDragRect.Top()+1; 128 } 129 } 130 131 // ----------------------------------------------------------------------- 132 133 void Splitter::ImplDrawSplitter() 134 { 135 Rectangle aInvRect( maDragRect ); 136 137 if ( mbHorzSplit ) 138 { 139 aInvRect.Left() = maDragPos.X() - 1; 140 aInvRect.Right() = maDragPos.X() + 1; 141 } 142 else 143 { 144 aInvRect.Top() = maDragPos.Y() - 1; 145 aInvRect.Bottom() = maDragPos.Y() + 1; 146 } 147 148 mpRefWin->InvertTracking( mpRefWin->PixelToLogic(aInvRect), SHOWTRACK_SPLIT ); 149 } 150 151 // ----------------------------------------------------------------------- 152 153 Splitter::Splitter( Window* pParent, WinBits nStyle ) : 154 Window( WINDOW_SPLITTER ) 155 { 156 ImplInitSplitterData(); 157 ImplInit( pParent, nStyle ); 158 } 159 160 // ----------------------------------------------------------------------- 161 162 Splitter::Splitter( Window* pParent, const ResId& rResId ) : 163 Window( WINDOW_SPLITTER ) 164 { 165 ImplInitSplitterData(); 166 rResId.SetRT( RSC_SPLITTER ); 167 WinBits nStyle = ImplInitRes( rResId ); 168 ImplInit( pParent, nStyle ); 169 ImplLoadRes( rResId ); 170 171 if ( !(nStyle & WB_HIDE) ) 172 Show(); 173 } 174 175 // ----------------------------------------------------------------------- 176 177 Splitter::~Splitter() 178 { 179 TaskPaneList *pTList = GetSystemWindow()->GetTaskPaneList(); 180 pTList->RemoveWindow( this ); 181 } 182 183 // ----------------------------------------------------------------------- 184 185 void Splitter::SetKeyboardStepSize( long nStepSize ) 186 { 187 mnKeyboardStepSize = nStepSize; 188 } 189 190 // ----------------------------------------------------------------------- 191 192 long Splitter::GetKeyboardStepSize() const 193 { 194 return mnKeyboardStepSize; 195 } 196 197 // ----------------------------------------------------------------------- 198 199 Splitter* Splitter::ImplFindSibling() 200 { 201 // look for another splitter with the same parent but different orientation 202 Window *pWin = GetParent()->GetWindow( WINDOW_FIRSTCHILD ); 203 Splitter *pSplitter = NULL; 204 while( pWin ) 205 { 206 if( pWin->ImplIsSplitter() ) 207 { 208 pSplitter = (Splitter*) pWin; 209 if( pSplitter != this && IsHorizontal() != pSplitter->IsHorizontal() ) 210 return pSplitter; 211 } 212 pWin = pWin->GetWindow( WINDOW_NEXT ); 213 } 214 return NULL; 215 } 216 217 // ----------------------------------------------------------------------- 218 219 sal_Bool Splitter::ImplSplitterActive() 220 { 221 // is splitter in document or at scrollbar handle ? 222 223 sal_Bool bActive = sal_True; 224 const StyleSettings& rSettings = GetSettings().GetStyleSettings(); 225 long nA = rSettings.GetScrollBarSize(); 226 long nB = rSettings.GetSplitSize(); 227 228 Size aSize = GetOutputSize(); 229 if ( mbHorzSplit ) 230 { 231 if( aSize.Width() == nB && aSize.Height() == nA ) 232 bActive = sal_False; 233 } 234 else 235 { 236 if( aSize.Width() == nA && aSize.Height() == nB ) 237 bActive = sal_False; 238 } 239 return bActive; 240 } 241 242 // ----------------------------------------------------------------------- 243 244 void Splitter::MouseButtonDown( const MouseEvent& rMEvt ) 245 { 246 if ( rMEvt.GetClicks() == 2 ) 247 { 248 if ( mnLastSplitPos != mnSplitPos ) 249 { 250 StartSplit(); 251 Point aPos = rMEvt.GetPosPixel(); 252 if ( mbHorzSplit ) 253 aPos.X() = mnLastSplitPos; 254 else 255 aPos.Y() = mnLastSplitPos; 256 ImplSplitMousePos( aPos ); 257 Splitting( aPos ); 258 ImplSplitMousePos( aPos ); 259 long nTemp = mnSplitPos; 260 if ( mbHorzSplit ) 261 SetSplitPosPixel( aPos.X() ); 262 else 263 SetSplitPosPixel( aPos.Y() ); 264 mnLastSplitPos = nTemp; 265 Split(); 266 EndSplit(); 267 } 268 } 269 else 270 StartDrag(); 271 } 272 273 // ----------------------------------------------------------------------- 274 275 void Splitter::Tracking( const TrackingEvent& rTEvt ) 276 { 277 if ( rTEvt.IsTrackingEnded() ) 278 { 279 if ( !mbDragFull ) 280 ImplDrawSplitter(); 281 282 if ( !rTEvt.IsTrackingCanceled() ) 283 { 284 long nNewPos; 285 if ( mbHorzSplit ) 286 nNewPos = maDragPos.X(); 287 else 288 nNewPos = maDragPos.Y(); 289 if ( nNewPos != mnStartSplitPos ) 290 { 291 SetSplitPosPixel( nNewPos ); 292 mnLastSplitPos = 0; 293 Split(); 294 } 295 EndSplit(); 296 } 297 else if ( mbDragFull ) 298 { 299 SetSplitPosPixel( mnStartSplitPos ); 300 Split(); 301 } 302 mnStartSplitPos = 0; 303 } 304 else 305 { 306 //Point aNewPos = mpRefWin->ScreenToOutputPixel( OutputToScreenPixel( rTEvt.GetMouseEvent().GetPosPixel() ) ); 307 Point aNewPos = mpRefWin->NormalizedScreenToOutputPixel( OutputToNormalizedScreenPixel( rTEvt.GetMouseEvent().GetPosPixel() ) ); 308 ImplSplitMousePos( aNewPos ); 309 Splitting( aNewPos ); 310 ImplSplitMousePos( aNewPos ); 311 312 if ( mbHorzSplit ) 313 { 314 if ( aNewPos.X() == maDragPos.X() ) 315 return; 316 } 317 else 318 { 319 if ( aNewPos.Y() == maDragPos.Y() ) 320 return; 321 } 322 323 if ( mbDragFull ) 324 { 325 maDragPos = aNewPos; 326 long nNewPos; 327 if ( mbHorzSplit ) 328 nNewPos = maDragPos.X(); 329 else 330 nNewPos = maDragPos.Y(); 331 if ( nNewPos != mnSplitPos ) 332 { 333 SetSplitPosPixel( nNewPos ); 334 mnLastSplitPos = 0; 335 Split(); 336 } 337 338 GetParent()->Update(); 339 } 340 else 341 { 342 ImplDrawSplitter(); 343 maDragPos = aNewPos; 344 ImplDrawSplitter(); 345 } 346 } 347 } 348 349 // ----------------------------------------------------------------------- 350 351 void Splitter::ImplKbdTracking( KeyCode aKeyCode ) 352 { 353 sal_uInt16 nCode = aKeyCode.GetCode(); 354 if ( nCode == KEY_ESCAPE || nCode == KEY_RETURN ) 355 { 356 if( !mbKbdSplitting ) 357 return; 358 else 359 mbKbdSplitting = sal_False; 360 361 if ( nCode != KEY_ESCAPE ) 362 { 363 long nNewPos; 364 if ( mbHorzSplit ) 365 nNewPos = maDragPos.X(); 366 else 367 nNewPos = maDragPos.Y(); 368 if ( nNewPos != mnStartSplitPos ) 369 { 370 SetSplitPosPixel( nNewPos ); 371 mnLastSplitPos = 0; 372 Split(); 373 } 374 } 375 else 376 { 377 SetSplitPosPixel( mnStartSplitPos ); 378 Split(); 379 EndSplit(); 380 } 381 mnStartSplitPos = 0; 382 } 383 else 384 { 385 Point aNewPos; 386 Size aSize = mpRefWin->GetOutputSize(); 387 Point aPos = GetPosPixel(); 388 // depending on the position calc allows continous moves or snaps to row/columns 389 // continous mode is active when position is at the origin or end of the splitter 390 // otherwise snap mode is active 391 // default here is snap, holding shift sets continous mode 392 if( mbHorzSplit ) 393 aNewPos = Point( ImplSplitterActive() ? aPos.X() : mnSplitPos, aKeyCode.IsShift() ? 0 : aSize.Height()/2); 394 else 395 aNewPos = Point( aKeyCode.IsShift() ? 0 : aSize.Width()/2, ImplSplitterActive() ? aPos.Y() : mnSplitPos ); 396 397 Point aOldWindowPos = GetPosPixel(); 398 399 int maxiter = 500; // avoid endless loop 400 int delta=0; 401 int delta_step = mbHorzSplit ? aSize.Width()/10 : aSize.Height()/10; 402 403 // use the specified step size if it was set 404 if( mnKeyboardStepSize != SPLITTER_DEFAULTSTEPSIZE ) 405 delta_step = mnKeyboardStepSize; 406 407 while( maxiter-- && aOldWindowPos == GetPosPixel() ) 408 { 409 // inc/dec position until application performs changes 410 // thus a single key press really moves the splitter 411 if( aKeyCode.IsShift() ) 412 delta++; 413 else 414 delta += delta_step; 415 416 switch( nCode ) 417 { 418 case KEY_LEFT: 419 aNewPos.X()-=delta; 420 break; 421 case KEY_RIGHT: 422 aNewPos.X()+=delta; 423 break; 424 case KEY_UP: 425 aNewPos.Y()-=delta; 426 break; 427 case KEY_DOWN: 428 aNewPos.Y()+=delta; 429 break; 430 default: 431 maxiter = 0; // leave loop 432 break; 433 } 434 ImplSplitMousePos( aNewPos ); 435 Splitting( aNewPos ); 436 ImplSplitMousePos( aNewPos ); 437 438 if ( mbHorzSplit ) 439 { 440 if ( aNewPos.X() == maDragPos.X() ) 441 continue; 442 } 443 else 444 { 445 if ( aNewPos.Y() == maDragPos.Y() ) 446 continue; 447 } 448 449 maDragPos = aNewPos; 450 long nNewPos; 451 if ( mbHorzSplit ) 452 nNewPos = maDragPos.X(); 453 else 454 nNewPos = maDragPos.Y(); 455 if ( nNewPos != mnSplitPos ) 456 { 457 SetSplitPosPixel( nNewPos ); 458 mnLastSplitPos = 0; 459 Split(); 460 } 461 GetParent()->Update(); 462 } 463 } 464 } 465 466 // ----------------------------------------------------------------------- 467 468 void Splitter::StartSplit() 469 { 470 maStartSplitHdl.Call( this ); 471 } 472 473 // ----------------------------------------------------------------------- 474 475 void Splitter::Split() 476 { 477 maSplitHdl.Call( this ); 478 } 479 480 // ----------------------------------------------------------------------- 481 482 void Splitter::EndSplit() 483 { 484 if ( maEndSplitHdl.IsSet() ) 485 maEndSplitHdl.Call( this ); 486 } 487 488 // ----------------------------------------------------------------------- 489 490 void Splitter::Splitting( Point& /* rSplitPos */ ) 491 { 492 } 493 494 // ----------------------------------------------------------------------- 495 496 void Splitter::SetDragRectPixel( const Rectangle& rDragRect, Window* _pRefWin ) 497 { 498 maDragRect = rDragRect; 499 if ( !_pRefWin ) 500 mpRefWin = GetParent(); 501 else 502 mpRefWin = _pRefWin; 503 } 504 505 // ----------------------------------------------------------------------- 506 507 void Splitter::SetSplitPosPixel( long nNewPos ) 508 { 509 mnSplitPos = nNewPos; 510 } 511 512 // ----------------------------------------------------------------------- 513 514 void Splitter::SetLastSplitPosPixel( long nNewPos ) 515 { 516 mnLastSplitPos = nNewPos; 517 } 518 519 // ----------------------------------------------------------------------- 520 521 void Splitter::StartDrag() 522 { 523 if ( IsTracking() ) 524 return; 525 526 StartSplit(); 527 528 // Tracking starten 529 StartTracking(); 530 531 // Start-Positon ermitteln 532 maDragPos = mpRefWin->GetPointerPosPixel(); 533 ImplSplitMousePos( maDragPos ); 534 Splitting( maDragPos ); 535 ImplSplitMousePos( maDragPos ); 536 if ( mbHorzSplit ) 537 mnStartSplitPos = maDragPos.X(); 538 else 539 mnStartSplitPos = maDragPos.Y(); 540 541 mbDragFull = (Application::GetSettings().GetStyleSettings().GetDragFullOptions() & DRAGFULL_OPTION_SPLIT) != 0; 542 if ( !mbDragFull ) 543 ImplDrawSplitter(); 544 } 545 546 547 // ----------------------------------------------------------------------- 548 549 void Splitter::ImplStartKbdSplitting() 550 { 551 if( mbKbdSplitting ) 552 return; 553 554 mbKbdSplitting = sal_True; 555 556 StartSplit(); 557 558 // determine start position 559 // because we have no mouse position we take either the position 560 // of the splitter window or the last split position 561 // the other coordinate is just the center of the reference window 562 Size aSize = mpRefWin->GetOutputSize(); 563 Point aPos = GetPosPixel(); 564 if( mbHorzSplit ) 565 maDragPos = Point( ImplSplitterActive() ? aPos.X() : mnSplitPos, aSize.Height()/2 ); 566 else 567 maDragPos = Point( aSize.Width()/2, ImplSplitterActive() ? aPos.Y() : mnSplitPos ); 568 ImplSplitMousePos( maDragPos ); 569 Splitting( maDragPos ); 570 ImplSplitMousePos( maDragPos ); 571 if ( mbHorzSplit ) 572 mnStartSplitPos = maDragPos.X(); 573 else 574 mnStartSplitPos = maDragPos.Y(); 575 } 576 577 // ----------------------------------------------------------------------- 578 579 void Splitter::ImplRestoreSplitter() 580 { 581 // set splitter in the center of the ref window 582 StartSplit(); 583 Size aSize = mpRefWin->GetOutputSize(); 584 Point aPos = Point( aSize.Width()/2 , aSize.Height()/2); 585 if ( mnLastSplitPos != mnSplitPos && mnLastSplitPos > 5 ) 586 { 587 // restore last pos if it was a useful position (>5) 588 if ( mbHorzSplit ) 589 aPos.X() = mnLastSplitPos; 590 else 591 aPos.Y() = mnLastSplitPos; 592 } 593 594 ImplSplitMousePos( aPos ); 595 Splitting( aPos ); 596 ImplSplitMousePos( aPos ); 597 long nTemp = mnSplitPos; 598 if ( mbHorzSplit ) 599 SetSplitPosPixel( aPos.X() ); 600 else 601 SetSplitPosPixel( aPos.Y() ); 602 mnLastSplitPos = nTemp; 603 Split(); 604 EndSplit(); 605 } 606 607 608 // ----------------------------------------------------------------------- 609 610 void Splitter::GetFocus() 611 { 612 if( !ImplSplitterActive() ) 613 ImplRestoreSplitter(); 614 615 Invalidate(); 616 } 617 618 // ----------------------------------------------------------------------- 619 620 void Splitter::LoseFocus() 621 { 622 if( mbKbdSplitting ) 623 { 624 KeyCode aReturnKey( KEY_RETURN ); 625 ImplKbdTracking( aReturnKey ); 626 mbKbdSplitting = sal_False; 627 } 628 Invalidate(); 629 } 630 631 // ----------------------------------------------------------------------- 632 633 void Splitter::KeyInput( const KeyEvent& rKEvt ) 634 { 635 if( mbInKeyEvent ) 636 return; 637 638 mbInKeyEvent = 1; 639 640 Splitter *pSibling = ImplFindSibling(); 641 KeyCode aKeyCode = rKEvt.GetKeyCode(); 642 sal_uInt16 nCode = aKeyCode.GetCode(); 643 switch ( nCode ) 644 { 645 case KEY_UP: 646 case KEY_DOWN: 647 if( !mbHorzSplit ) 648 { 649 ImplStartKbdSplitting(); 650 ImplKbdTracking( aKeyCode ); 651 } 652 else 653 { 654 if( pSibling ) 655 { 656 pSibling->GrabFocus(); 657 pSibling->KeyInput( rKEvt ); 658 } 659 } 660 break; 661 case KEY_RIGHT: 662 case KEY_LEFT: 663 if( mbHorzSplit ) 664 { 665 ImplStartKbdSplitting(); 666 ImplKbdTracking( aKeyCode ); 667 } 668 else 669 { 670 if( pSibling ) 671 { 672 pSibling->GrabFocus(); 673 pSibling->KeyInput( rKEvt ); 674 } 675 } 676 break; 677 678 case KEY_DELETE: 679 if( ImplSplitterActive() ) 680 { 681 if( mbKbdSplitting ) 682 { 683 KeyCode aKey( KEY_ESCAPE ); 684 ImplKbdTracking( aKey ); 685 } 686 687 StartSplit(); 688 Point aPos; 689 if ( mbHorzSplit ) 690 aPos.X() = 0; 691 else 692 aPos.Y() = 0; 693 ImplSplitMousePos( aPos ); 694 Splitting( aPos ); 695 ImplSplitMousePos( aPos ); 696 long nTemp = mnSplitPos; 697 if ( mbHorzSplit ) 698 SetSplitPosPixel( aPos.X() ); 699 else 700 SetSplitPosPixel( aPos.Y() ); 701 mnLastSplitPos = nTemp; 702 Split(); 703 EndSplit(); 704 705 // Shift-Del deletes both splitters 706 if( aKeyCode.IsShift() && pSibling ) 707 pSibling->KeyInput( rKEvt ); 708 709 GrabFocusToDocument(); 710 } 711 break; 712 713 case KEY_ESCAPE: 714 if( mbKbdSplitting ) 715 ImplKbdTracking( aKeyCode ); 716 else 717 GrabFocusToDocument(); 718 break; 719 720 case KEY_RETURN: 721 ImplKbdTracking( aKeyCode ); 722 GrabFocusToDocument(); 723 break; 724 default: // let any key input fix the splitter 725 Window::KeyInput( rKEvt ); 726 GrabFocusToDocument(); 727 break; 728 } 729 mbInKeyEvent = 0; 730 } 731 732 // ----------------------------------------------------------------------- 733 734 long Splitter::Notify( NotifyEvent& rNEvt ) 735 { 736 return Window::Notify( rNEvt ); 737 } 738 739 // ----------------------------------------------------------------------- 740 741 void Splitter::DataChanged( const DataChangedEvent& rDCEvt ) 742 { 743 Window::DataChanged( rDCEvt ); 744 if( rDCEvt.GetType() == DATACHANGED_SETTINGS ) 745 { 746 Color oldFaceColor = ((AllSettings *) rDCEvt.GetData())->GetStyleSettings().GetFaceColor(); 747 Color newFaceColor = Application::GetSettings().GetStyleSettings().GetFaceColor(); 748 if( oldFaceColor.IsDark() != newFaceColor.IsDark() ) 749 { 750 if( newFaceColor.IsDark() ) 751 SetBackground( ImplWhiteWall::get() ); 752 else 753 SetBackground( ImplBlackWall::get() ); 754 } 755 } 756 } 757 758 // ----------------------------------------------------------------------- 759 760 void Splitter::Paint( const Rectangle& rPaintRect ) 761 { 762 if( HasFocus() || mbKbdSplitting ) 763 { 764 Color oldFillCol = GetFillColor(); 765 Color oldLineCol = GetLineColor(); 766 767 SetLineColor(); 768 SetFillColor( GetSettings().GetStyleSettings().GetFaceColor() ); 769 DrawRect( rPaintRect ); 770 771 Color aSelectionBorderCol( GetSettings().GetStyleSettings().GetActiveColor() ); 772 SetFillColor( aSelectionBorderCol ); 773 SetLineColor(); 774 775 Polygon aPoly( rPaintRect ); 776 PolyPolygon aPolyPoly( aPoly ); 777 DrawTransparent( aPolyPoly, 85 ); 778 779 SetLineColor( aSelectionBorderCol ); 780 SetFillColor(); 781 782 if( mbKbdSplitting ) 783 { 784 LineInfo aInfo( LINE_DASH ); 785 //aInfo.SetDashLen( 2 ); 786 //aInfo.SetDashCount( 1 ); 787 aInfo.SetDistance( 1 ); 788 aInfo.SetDotLen( 2 ); 789 aInfo.SetDotCount( 1 ); 790 791 DrawPolyLine( aPoly, aInfo ); 792 } 793 else 794 DrawRect( rPaintRect ); 795 796 SetFillColor( oldFillCol); 797 SetLineColor( oldLineCol); 798 } 799 else 800 { 801 Window::Paint( rPaintRect ); 802 } 803 } 804