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