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/time.hxx> 28 #ifndef _SV_RC_H 29 #include <tools/rc.h> 30 #endif 31 32 #include <brdwin.hxx> 33 #include <svdata.hxx> 34 #include <salframe.hxx> 35 #include <window.h> 36 37 #include <vcl/event.hxx> 38 #include <vcl/floatwin.hxx> 39 #include <vcl/dockwin.hxx> 40 #include <vcl/toolbox.hxx> 41 #include <vcl/svapp.hxx> 42 #include <vcl/timer.hxx> 43 #include <vcl/lineinfo.hxx> 44 #include <vcl/unowrap.hxx> 45 46 47 // ======================================================================= 48 49 #define DOCKWIN_FLOATSTYLES (WB_SIZEABLE | WB_MOVEABLE | WB_CLOSEABLE | WB_STANDALONE | WB_PINABLE | WB_ROLLABLE ) 50 51 // ======================================================================= 52 53 54 // ======================================================================= 55 56 class ImplDockFloatWin2 : public FloatingWindow 57 { 58 private: 59 ImplDockingWindowWrapper* mpDockWin; 60 sal_uLong mnLastTicks; 61 Timer maDockTimer; 62 Timer maEndDockTimer; 63 Point maDockPos; 64 Rectangle maDockRect; 65 sal_Bool mbInMove; 66 sal_uLong mnLastUserEvent; 67 68 DECL_LINK( DockingHdl, ImplDockFloatWin2* ); 69 DECL_LINK( DockTimerHdl, ImplDockFloatWin2* ); 70 DECL_LINK( EndDockTimerHdl, ImplDockFloatWin2* ); 71 public: 72 ImplDockFloatWin2( Window* pParent, WinBits nWinBits, 73 ImplDockingWindowWrapper* pDockingWin ); 74 ~ImplDockFloatWin2(); 75 76 virtual void Move(); 77 virtual void Resize(); 78 virtual void TitleButtonClick( sal_uInt16 nButton ); 79 virtual void Pin(); 80 virtual void Roll(); 81 virtual void PopupModeEnd(); 82 virtual void Resizing( Size& rSize ); 83 virtual sal_Bool Close(); 84 using Window::SetPosSizePixel; 85 virtual void SetPosSizePixel( long nX, long nY, 86 long nWidth, long nHeight, 87 sal_uInt16 nFlags = WINDOW_POSSIZE_ALL ); 88 89 sal_uLong GetLastTicks() const { return mnLastTicks; } 90 }; 91 92 // ======================================================================= 93 94 ImplDockFloatWin2::ImplDockFloatWin2( Window* pParent, WinBits nWinBits, 95 ImplDockingWindowWrapper* pDockingWin ) : 96 FloatingWindow( pParent, nWinBits ), 97 mpDockWin( pDockingWin ), 98 mnLastTicks( Time::GetSystemTicks() ), 99 mbInMove( sal_False ), 100 mnLastUserEvent( 0 ) 101 { 102 // Daten vom DockingWindow uebernehmen 103 if ( pDockingWin ) 104 { 105 SetSettings( pDockingWin->GetWindow()->GetSettings() ); 106 Enable( pDockingWin->GetWindow()->IsEnabled(), sal_False ); 107 EnableInput( pDockingWin->GetWindow()->IsInputEnabled(), sal_False ); 108 AlwaysEnableInput( pDockingWin->GetWindow()->IsAlwaysEnableInput(), sal_False ); 109 EnableAlwaysOnTop( pDockingWin->GetWindow()->IsAlwaysOnTopEnabled() ); 110 SetActivateMode( pDockingWin->GetWindow()->GetActivateMode() ); 111 } 112 113 SetBackground( GetSettings().GetStyleSettings().GetFaceColor() ); 114 115 maDockTimer.SetTimeoutHdl( LINK( this, ImplDockFloatWin2, DockTimerHdl ) ); 116 maDockTimer.SetTimeout( 50 ); 117 maEndDockTimer.SetTimeoutHdl( LINK( this, ImplDockFloatWin2, EndDockTimerHdl ) ); 118 maEndDockTimer.SetTimeout( 50 ); 119 } 120 121 // ----------------------------------------------------------------------- 122 123 ImplDockFloatWin2::~ImplDockFloatWin2() 124 { 125 if( mnLastUserEvent ) 126 Application::RemoveUserEvent( mnLastUserEvent ); 127 } 128 129 // ----------------------------------------------------------------------- 130 131 IMPL_LINK( ImplDockFloatWin2, DockTimerHdl, ImplDockFloatWin2*, EMPTYARG ) 132 { 133 DBG_ASSERT( mpDockWin->IsFloatingMode(), "docktimer called but not floating" ); 134 135 maDockTimer.Stop(); 136 PointerState aState = GetPointerState(); 137 138 if( aState.mnState & KEY_MOD1 ) 139 { 140 // i43499 CTRL disables docking now 141 mpDockWin->GetWindow()->GetParent()->ImplGetFrameWindow()->HideTracking(); 142 if( aState.mnState & ( MOUSE_LEFT | MOUSE_MIDDLE | MOUSE_RIGHT ) ) 143 maDockTimer.Start(); 144 } 145 else if( ! ( aState.mnState & ( MOUSE_LEFT | MOUSE_MIDDLE | MOUSE_RIGHT ) ) ) 146 { 147 mpDockWin->GetWindow()->GetParent()->ImplGetFrameWindow()->HideTracking(); 148 mpDockWin->EndDocking( maDockRect, sal_False ); 149 } 150 else 151 { 152 mpDockWin->GetWindow()->GetParent()->ImplGetFrameWindow()->ShowTracking( maDockRect, SHOWTRACK_BIG | SHOWTRACK_WINDOW ); 153 maDockTimer.Start(); 154 } 155 156 return 0; 157 } 158 159 IMPL_LINK( ImplDockFloatWin2, EndDockTimerHdl, ImplDockFloatWin2*, EMPTYARG ) 160 { 161 DBG_ASSERT( mpDockWin->IsFloatingMode(), "enddocktimer called but not floating" ); 162 163 maEndDockTimer.Stop(); 164 PointerState aState = GetPointerState(); 165 if( ! ( aState.mnState & ( MOUSE_LEFT | MOUSE_MIDDLE | MOUSE_RIGHT ) ) ) 166 { 167 mpDockWin->GetWindow()->GetParent()->ImplGetFrameWindow()->HideTracking(); 168 mpDockWin->EndDocking( maDockRect, sal_True ); 169 } 170 else 171 { 172 maEndDockTimer.Start(); 173 } 174 175 return 0; 176 } 177 178 179 IMPL_LINK( ImplDockFloatWin2, DockingHdl, ImplDockFloatWin2*, EMPTYARG ) 180 { 181 // called during move of a floating window 182 mnLastUserEvent = 0; 183 184 Window *pDockingArea = mpDockWin->GetWindow()->GetParent(); 185 PointerState aState = pDockingArea->GetPointerState(); 186 187 sal_Bool bRealMove = sal_True; 188 if( GetStyle() & WB_OWNERDRAWDECORATION ) 189 { 190 // for windows with ownerdraw decoration 191 // we allow docking only when the window was moved 192 // by dragging its caption 193 // and ignore move request due to resizing 194 Window *pBorder = GetWindow( WINDOW_BORDER ); 195 if( pBorder != this ) 196 { 197 Point aPt; 198 Rectangle aBorderRect( aPt, pBorder->GetSizePixel() ); 199 sal_Int32 nLeft, nTop, nRight, nBottom; 200 GetBorder( nLeft, nTop, nRight, nBottom ); 201 // limit borderrect to the caption part only and without the resizing borders 202 aBorderRect.nBottom = aBorderRect.nTop + nTop; 203 aBorderRect.nLeft += nLeft; 204 aBorderRect.nRight -= nRight; 205 206 PointerState aBorderState = pBorder->GetPointerState(); 207 if( aBorderRect.IsInside( aBorderState.maPos ) ) 208 bRealMove = sal_True; 209 else 210 bRealMove = sal_False; 211 } 212 } 213 214 if( mpDockWin->IsDockable() && 215 mpDockWin->GetWindow()->IsVisible() && 216 (Time::GetSystemTicks() - mnLastTicks > 500) && 217 ( aState.mnState & ( MOUSE_LEFT | MOUSE_MIDDLE | MOUSE_RIGHT ) ) && 218 !(aState.mnState & KEY_MOD1) && // i43499 CTRL disables docking now 219 bRealMove ) 220 { 221 maDockPos = Point( pDockingArea->OutputToScreenPixel( pDockingArea->AbsoluteScreenToOutputPixel( OutputToAbsoluteScreenPixel( Point() ) ) ) ); 222 maDockRect = Rectangle( maDockPos, mpDockWin->GetSizePixel() ); 223 224 // mouse pos in screen pixels 225 Point aMousePos = pDockingArea->OutputToScreenPixel( aState.maPos ); 226 227 if( ! mpDockWin->IsDocking() ) 228 mpDockWin->StartDocking( aMousePos, maDockRect ); 229 230 sal_Bool bFloatMode = mpDockWin->Docking( aMousePos, maDockRect ); 231 232 if( ! bFloatMode ) 233 { 234 // indicates that the window could be docked at maDockRect 235 maDockRect.SetPos( mpDockWin->GetWindow()->GetParent()->ImplGetFrameWindow()->ScreenToOutputPixel( 236 maDockRect.TopLeft() ) ); 237 mpDockWin->GetWindow()->GetParent()->ImplGetFrameWindow()->ShowTracking( maDockRect, SHOWTRACK_BIG | SHOWTRACK_WINDOW ); 238 maEndDockTimer.Stop(); 239 DockTimerHdl( this ); 240 } 241 else 242 { 243 mpDockWin->GetWindow()->GetParent()->ImplGetFrameWindow()->HideTracking(); 244 maDockTimer.Stop(); 245 EndDockTimerHdl( this ); 246 } 247 } 248 mbInMove = sal_False; 249 return 0; 250 } 251 // ----------------------------------------------------------------------- 252 253 void ImplDockFloatWin2::Move() 254 { 255 if( mbInMove ) 256 return; 257 258 mbInMove = sal_True; 259 FloatingWindow::Move(); 260 mpDockWin->GetWindow()->Move(); 261 262 /* 263 * note: the window should only dock if KEY_MOD1 is pressed 264 * and the user releases all mouse buttons. The real problem here 265 * is that we don't get mouse events (at least not on X) 266 * if the mouse is on the decoration. So we have to start an 267 * awkward timer based process that polls the modifier/buttons 268 * to see whether they are in the right condition shortly after the 269 * last Move message. 270 */ 271 if( ! mnLastUserEvent ) 272 mnLastUserEvent = Application::PostUserEvent( LINK( this, ImplDockFloatWin2, DockingHdl ) ); 273 } 274 275 // ----------------------------------------------------------------------- 276 277 void ImplDockFloatWin2::Resize() 278 { 279 // forwarding of resize only required if we have no borderwindow ( GetWindow() then returns 'this' ) 280 if( GetWindow( WINDOW_BORDER ) == this ) 281 { 282 FloatingWindow::Resize(); 283 Size aSize( GetSizePixel() ); 284 mpDockWin->GetWindow()->ImplPosSizeWindow( 0, 0, aSize.Width(), aSize.Height(), WINDOW_POSSIZE_POSSIZE ); // is this needed ??? 285 } 286 } 287 288 void ImplDockFloatWin2::SetPosSizePixel( long nX, long nY, 289 long nWidth, long nHeight, 290 sal_uInt16 nFlags ) 291 { 292 FloatingWindow::SetPosSizePixel( nX, nY, nWidth, nHeight, nFlags ); 293 } 294 295 // ----------------------------------------------------------------------- 296 297 298 void ImplDockFloatWin2::TitleButtonClick( sal_uInt16 nButton ) 299 { 300 FloatingWindow::TitleButtonClick( nButton ); 301 mpDockWin->TitleButtonClick( nButton ); 302 } 303 304 // ----------------------------------------------------------------------- 305 306 void ImplDockFloatWin2::Pin() 307 { 308 FloatingWindow::Pin(); 309 mpDockWin->Pin(); 310 } 311 312 // ----------------------------------------------------------------------- 313 314 void ImplDockFloatWin2::Roll() 315 { 316 FloatingWindow::Roll(); 317 mpDockWin->Roll(); 318 } 319 320 // ----------------------------------------------------------------------- 321 322 void ImplDockFloatWin2::PopupModeEnd() 323 { 324 FloatingWindow::PopupModeEnd(); 325 mpDockWin->PopupModeEnd(); 326 } 327 328 // ----------------------------------------------------------------------- 329 330 void ImplDockFloatWin2::Resizing( Size& rSize ) 331 { 332 FloatingWindow::Resizing( rSize ); 333 mpDockWin->Resizing( rSize ); 334 } 335 336 // ----------------------------------------------------------------------- 337 338 sal_Bool ImplDockFloatWin2::Close() 339 { 340 return mpDockWin->Close(); 341 } 342 343 // ======================================================================= 344 345 DockingManager::DockingManager() 346 { 347 } 348 349 DockingManager::~DockingManager() 350 { 351 ::std::vector< ImplDockingWindowWrapper* >::iterator p; 352 p = mDockingWindows.begin(); 353 for(; p != mDockingWindows.end(); ++p ) 354 { 355 delete (*p); 356 } 357 mDockingWindows.clear(); 358 } 359 360 ImplDockingWindowWrapper* DockingManager::GetDockingWindowWrapper( const Window *pWindow ) 361 { 362 ::std::vector< ImplDockingWindowWrapper* >::iterator p; 363 p = mDockingWindows.begin(); 364 while( p != mDockingWindows.end() ) 365 { 366 if( (*p)->mpDockingWindow == pWindow ) 367 return (*p); 368 else 369 p++; 370 } 371 return NULL; 372 } 373 374 sal_Bool DockingManager::IsDockable( const Window *pWindow ) 375 { 376 ImplDockingWindowWrapper* pWrapper = GetDockingWindowWrapper( pWindow ); 377 378 /* 379 if( pWindow->HasDockingHandler() ) 380 return sal_True; 381 */ 382 return (pWrapper != NULL); 383 } 384 385 sal_Bool DockingManager::IsFloating( const Window *pWindow ) 386 { 387 ImplDockingWindowWrapper* pWrapper = GetDockingWindowWrapper( pWindow ); 388 if( pWrapper ) 389 return pWrapper->IsFloatingMode(); 390 else 391 return sal_False; 392 } 393 394 sal_Bool DockingManager::IsLocked( const Window *pWindow ) 395 { 396 ImplDockingWindowWrapper* pWrapper = GetDockingWindowWrapper( pWindow ); 397 if( pWrapper && pWrapper->IsLocked() ) 398 return sal_True; 399 else 400 return sal_False; 401 } 402 403 void DockingManager::Lock( const Window *pWindow ) 404 { 405 ImplDockingWindowWrapper* pWrapper = GetDockingWindowWrapper( pWindow ); 406 if( pWrapper ) 407 pWrapper->Lock(); 408 } 409 410 void DockingManager::Unlock( const Window *pWindow ) 411 { 412 ImplDockingWindowWrapper* pWrapper = GetDockingWindowWrapper( pWindow ); 413 if( pWrapper ) 414 pWrapper->Unlock(); 415 } 416 417 void DockingManager::SetFloatingMode( const Window *pWindow, sal_Bool bFloating ) 418 { 419 ImplDockingWindowWrapper* pWrapper = GetDockingWindowWrapper( pWindow ); 420 if( pWrapper ) 421 pWrapper->SetFloatingMode( bFloating ); 422 } 423 424 void DockingManager::StartPopupMode( ToolBox *pParentToolBox, const Window *pWindow, sal_uLong nFlags ) 425 { 426 ImplDockingWindowWrapper* pWrapper = GetDockingWindowWrapper( pWindow ); 427 if( pWrapper ) 428 pWrapper->StartPopupMode( pParentToolBox, nFlags ); 429 } 430 431 void DockingManager::StartPopupMode( ToolBox *pParentToolBox, const Window *pWindow ) 432 { 433 StartPopupMode( pParentToolBox, pWindow, FLOATWIN_POPUPMODE_ALLOWTEAROFF | 434 FLOATWIN_POPUPMODE_NOFOCUSCLOSE | 435 FLOATWIN_POPUPMODE_ALLMOUSEBUTTONCLOSE | 436 FLOATWIN_POPUPMODE_NOMOUSEUPCLOSE ); 437 } 438 439 sal_Bool DockingManager::IsInPopupMode( const Window *pWindow ) 440 { 441 ImplDockingWindowWrapper* pWrapper = GetDockingWindowWrapper( pWindow ); 442 if( pWrapper && pWrapper->IsInPopupMode() ) 443 return sal_True; 444 else 445 return sal_False; 446 } 447 448 // ----------------------------------------------------------------------- 449 450 void DockingManager::EndPopupMode( const Window *pWin ) 451 { 452 ImplDockingWindowWrapper *pWrapper = GetDockingWindowWrapper( pWin ); 453 if( pWrapper && pWrapper->GetFloatingWindow() && pWrapper->GetFloatingWindow()->IsInPopupMode() ) 454 pWrapper->GetFloatingWindow()->EndPopupMode(); 455 } 456 457 // ----------------------------------------------------------------------- 458 459 void DockingManager::AddWindow( const Window *pWindow ) 460 { 461 ImplDockingWindowWrapper* pWrapper = GetDockingWindowWrapper( pWindow ); 462 if( pWrapper ) 463 return; 464 else 465 pWrapper = new ImplDockingWindowWrapper( pWindow ); 466 467 mDockingWindows.push_back( pWrapper ); 468 } 469 470 void DockingManager::RemoveWindow( const Window *pWindow ) 471 { 472 ::std::vector< ImplDockingWindowWrapper* >::iterator p; 473 p = mDockingWindows.begin(); 474 while( p != mDockingWindows.end() ) 475 { 476 if( (*p)->mpDockingWindow == pWindow ) 477 { 478 delete (*p); 479 mDockingWindows.erase( p ); 480 break; 481 } 482 else 483 p++; 484 } 485 } 486 487 void DockingManager::SetPosSizePixel( Window *pWindow, long nX, long nY, 488 long nWidth, long nHeight, 489 sal_uInt16 nFlags ) 490 { 491 ImplDockingWindowWrapper* pWrapper = GetDockingWindowWrapper( pWindow ); 492 if( pWrapper ) 493 pWrapper->SetPosSizePixel( nX, nY, nWidth, nHeight, nFlags ); 494 } 495 496 Rectangle DockingManager::GetPosSizePixel( const Window *pWindow ) 497 { 498 Rectangle aRect; 499 ImplDockingWindowWrapper* pWrapper = GetDockingWindowWrapper( pWindow ); 500 if( pWrapper ) 501 aRect = Rectangle( pWrapper->GetPosPixel(), pWrapper->GetSizePixel() ); 502 503 return aRect; 504 } 505 506 // ======================================================================= 507 // special floating window for popup mode 508 // main purpose: provides tear-off area for undocking 509 // ======================================================================= 510 511 // if TEAROFF_DASHED defined a single dashed line is used 512 // otherwise multiple smaller lines will be painted 513 //#define TEAROFF_DASHED 514 515 // size of the drag area 516 #ifdef TEAROFF_DASHED 517 #define POPUP_DRAGBORDER 2 518 #define POPUP_DRAGGRIP 5 519 #else 520 #define POPUP_DRAGBORDER 3 521 #define POPUP_DRAGGRIP 5 522 #endif 523 #define POPUP_DRAGHEIGHT (POPUP_DRAGGRIP+POPUP_DRAGBORDER+POPUP_DRAGBORDER) 524 #define POPUP_DRAGWIDTH 20 525 526 class ImplPopupFloatWin : public FloatingWindow 527 { 528 private: 529 ImplDockingWindowWrapper* mpDockingWin; 530 sal_Bool mbHighlight; 531 sal_Bool mbMoving; 532 bool mbTrackingEnabled; 533 Point maDelta; 534 Point maTearOffPosition; 535 bool mbGripAtBottom; 536 bool mbHasGrip; 537 void ImplSetBorder(); 538 539 public: 540 ImplPopupFloatWin( Window* pParent, ImplDockingWindowWrapper* pDockingWin, bool bHasGrip ); 541 ~ImplPopupFloatWin(); 542 543 virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > CreateAccessible(); 544 virtual void Paint( const Rectangle& rRect ); 545 virtual void MouseMove( const MouseEvent& rMEvt ); 546 virtual void MouseButtonDown( const MouseEvent& rMEvt ); 547 virtual void MouseButtonUp( const MouseEvent& rMEvt ); 548 virtual void Tracking( const TrackingEvent& rTEvt ); 549 virtual void Resize(); 550 virtual Window* GetPreferredKeyInputWindow(); 551 552 Rectangle GetDragRect() const; 553 Point GetToolboxPosition() const; 554 Point GetTearOffPosition() const; 555 void DrawGrip(); 556 void DrawBorder(); 557 558 bool hasGrip() const { return mbHasGrip; } 559 }; 560 561 ImplPopupFloatWin::ImplPopupFloatWin( Window* pParent, ImplDockingWindowWrapper* pDockingWin, bool bHasGrip ) : 562 FloatingWindow( pParent, WB_NOBORDER | WB_SYSTEMWINDOW | WB_NOSHADOW) 563 { 564 mpWindowImpl->mbToolbarFloatingWindow = sal_True; // indicate window type, required for accessibility 565 // which should not see this window as a toplevel window 566 mpDockingWin = pDockingWin; 567 mbHighlight = sal_False; 568 mbMoving = sal_False; 569 mbTrackingEnabled = sal_False; 570 mbGripAtBottom = sal_True; 571 mbHasGrip = bHasGrip; 572 573 ImplSetBorder(); 574 } 575 576 ImplPopupFloatWin::~ImplPopupFloatWin() 577 { 578 mpDockingWin = NULL; 579 } 580 581 ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > ImplPopupFloatWin::CreateAccessible() 582 { 583 // switch off direct accessibilty support for this window 584 585 // this is to avoid appearance of this window as standalone window in the accessibility hierarchy 586 // as this window is only used as a helper for subtoolbars that are not teared-off, the parent toolbar 587 // has to provide accessibility support (as implemented in the toolkit) 588 // so the contained toolbar should appear as child of the correponsing toolbar item of the parent toolbar 589 return ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >(); 590 } 591 592 Window* ImplPopupFloatWin::GetPreferredKeyInputWindow() 593 { 594 if( mpWindowImpl->mpClientWindow ) 595 return mpWindowImpl->mpClientWindow; 596 else 597 return FloatingWindow::GetPreferredKeyInputWindow(); 598 } 599 600 601 void ImplPopupFloatWin::ImplSetBorder() 602 { 603 // although we have no border in the sense of a borderwindow 604 // we're using a special border for the grip 605 // by setting those members the method SetOutputSizePixel() can 606 // be used to set the proper window size 607 mpWindowImpl->mnTopBorder = 1; 608 if( hasGrip() ) 609 mpWindowImpl->mnTopBorder += POPUP_DRAGHEIGHT+2; 610 mpWindowImpl->mnBottomBorder = 1; 611 mpWindowImpl->mnLeftBorder = 1; 612 mpWindowImpl->mnRightBorder = 1; 613 } 614 615 void ImplPopupFloatWin::Resize() 616 { 617 // the borderview overwrites the border during resize so restore it 618 ImplSetBorder(); 619 } 620 621 Rectangle ImplPopupFloatWin::GetDragRect() const 622 { 623 Rectangle aRect; 624 if( hasGrip() ) 625 { 626 aRect = Rectangle( 1,1, GetOutputSizePixel().Width()-1, 2+POPUP_DRAGHEIGHT ); 627 if( mbGripAtBottom ) 628 { 629 int height = GetOutputSizePixel().Height(); 630 aRect.Top() = height - 3 - POPUP_DRAGHEIGHT; 631 aRect.Bottom() = aRect.Top() + 1 + POPUP_DRAGHEIGHT; 632 } 633 } 634 return aRect; 635 } 636 637 Point ImplPopupFloatWin::GetToolboxPosition() const 638 { 639 // return inner position where a toolbox could be placed 640 Point aPt( 1, 1 + ((mbGripAtBottom || !hasGrip()) ? 0 : GetDragRect().getHeight()) ); // grip + border 641 642 return aPt; 643 } 644 645 Point ImplPopupFloatWin::GetTearOffPosition() const 646 { 647 Point aPt( maTearOffPosition ); 648 //aPt += GetToolboxPosition(); // remove 'decoration' 649 return aPt; 650 } 651 652 void ImplPopupFloatWin::DrawBorder() 653 { 654 SetFillColor(); 655 Point aPt; 656 Rectangle aRect( aPt, GetOutputSizePixel() ); 657 658 Region oldClipRgn( GetClipRegion( ) ); 659 Region aClipRgn( aRect ); 660 Rectangle aItemClipRect( ImplGetItemEdgeClipRect() ); 661 if( !aItemClipRect.IsEmpty() ) 662 { 663 aItemClipRect.SetPos( AbsoluteScreenToOutputPixel( aItemClipRect.TopLeft() ) ); 664 665 // draw the excluded border part with the background color of a toolbox 666 SetClipRegion( Region( aItemClipRect ) ); 667 SetLineColor( GetSettings().GetStyleSettings().GetFaceColor() ); 668 DrawRect( aRect ); 669 670 aClipRgn.Exclude( aItemClipRect ); 671 SetClipRegion( aClipRgn ); 672 } 673 SetLineColor( GetSettings().GetStyleSettings().GetShadowColor() ); 674 DrawRect( aRect ); 675 SetClipRegion( oldClipRgn ); 676 } 677 678 void ImplPopupFloatWin::DrawGrip() 679 { 680 sal_Bool bLinecolor = IsLineColor(); 681 Color aLinecolor = GetLineColor(); 682 sal_Bool bFillcolor = IsFillColor(); 683 Color aFillcolor = GetFillColor(); 684 685 // draw background 686 Rectangle aRect( GetDragRect() ); 687 aRect.nTop += POPUP_DRAGBORDER; 688 aRect.nBottom -= POPUP_DRAGBORDER; 689 aRect.nLeft+=3; 690 aRect.nRight-=3; 691 692 if( mbHighlight ) 693 { 694 Erase( aRect ); 695 DrawSelectionBackground( aRect, 2, sal_False, sal_True, sal_False ); 696 } 697 else 698 { 699 SetFillColor( GetSettings().GetStyleSettings().GetFaceColor() ); 700 SetLineColor(); 701 DrawRect( aRect ); 702 } 703 704 if( !ToolBox::AlwaysLocked() ) // no grip if toolboxes are locked 705 { 706 #ifdef TEAROFF_DASHED 707 // draw single dashed line 708 LineInfo aLineInfo( LINE_DASH ); 709 aLineInfo.SetDistance( 4 ); 710 aLineInfo.SetDashLen( 12 ); 711 aLineInfo.SetDashCount( 1 ); 712 713 aRect.nLeft+=2; aRect.nRight-=2; 714 715 aRect.nTop+=2; 716 aRect.nBottom = aRect.nTop; 717 SetLineColor( GetSettings().GetStyleSettings().GetDarkShadowColor() ); 718 DrawLine( aRect.TopLeft(), aRect.TopRight(), aLineInfo ); 719 720 if( !mbHighlight ) 721 { 722 aRect.nTop++; aRect.nBottom++; 723 SetLineColor( GetSettings().GetStyleSettings().GetLightColor() ); 724 DrawLine( aRect.TopLeft(), aRect.TopRight(), aLineInfo ); 725 } 726 727 #else 728 // draw several grip lines 729 SetFillColor( GetSettings().GetStyleSettings().GetShadowColor() ); 730 aRect.nTop++; 731 aRect.nBottom = aRect.nTop; 732 733 int width = POPUP_DRAGWIDTH; 734 while( width >= aRect.getWidth() ) 735 width -= 4; 736 if( width <= 0 ) 737 width = aRect.getWidth(); 738 //aRect.nLeft = aRect.nLeft + (aRect.getWidth() - width) / 2; 739 aRect.nLeft = (aRect.nLeft + aRect.nRight - width) / 2; 740 aRect.nRight = aRect.nLeft + width; 741 742 int i=0; 743 while( i< POPUP_DRAGGRIP ) 744 { 745 DrawRect( aRect ); 746 aRect.nTop+=2; 747 aRect.nBottom+=2; 748 i+=2; 749 } 750 #endif 751 } 752 753 if( bLinecolor ) 754 SetLineColor( aLinecolor ); 755 else 756 SetLineColor(); 757 if( bFillcolor ) 758 SetFillColor( aFillcolor ); 759 else 760 SetFillColor(); 761 } 762 763 void ImplPopupFloatWin::Paint( const Rectangle& ) 764 { 765 Point aPt; 766 Rectangle aRect( aPt, GetOutputSizePixel() ); 767 DrawWallpaper( aRect, Wallpaper( GetSettings().GetStyleSettings().GetFaceGradientColor() ) ); 768 DrawBorder(); 769 if( hasGrip() ) 770 DrawGrip(); 771 } 772 773 void ImplPopupFloatWin::MouseMove( const MouseEvent& rMEvt ) 774 { 775 Point aMousePos = rMEvt.GetPosPixel(); 776 777 if( !ToolBox::AlwaysLocked() ) // no tear off if locking is enabled 778 { 779 if( mbTrackingEnabled && rMEvt.IsLeft() && GetDragRect().IsInside( aMousePos ) ) 780 { 781 // start window move 782 mbMoving = sal_True; 783 StartTracking( STARTTRACK_NOKEYCANCEL ); 784 return; 785 } 786 if( !mbHighlight && GetDragRect().IsInside( aMousePos ) ) 787 { 788 mbHighlight = sal_True; 789 DrawGrip(); 790 } 791 if( mbHighlight && ( rMEvt.IsLeaveWindow() || !GetDragRect().IsInside( aMousePos ) ) ) 792 { 793 mbHighlight = sal_False; 794 DrawGrip(); 795 } 796 } 797 } 798 799 void ImplPopupFloatWin::MouseButtonUp( const MouseEvent& rMEvt ) 800 { 801 mbTrackingEnabled = false; 802 FloatingWindow::MouseButtonUp( rMEvt ); 803 } 804 805 void ImplPopupFloatWin::MouseButtonDown( const MouseEvent& rMEvt ) 806 { 807 Point aMousePos = rMEvt.GetPosPixel(); 808 if( GetDragRect().IsInside( aMousePos ) ) 809 { 810 // get mouse pos at a static window to have a fixed reference point 811 PointerState aState = GetParent()->GetPointerState(); 812 if (ImplHasMirroredGraphics() && IsRTLEnabled()) 813 ImplMirrorFramePos(aState.maPos); 814 maTearOffPosition = GetWindow( WINDOW_BORDER )->GetPosPixel(); 815 maDelta = aState.maPos - maTearOffPosition; 816 mbTrackingEnabled = true; 817 } 818 else 819 { 820 mbTrackingEnabled = false; 821 } 822 } 823 824 void ImplPopupFloatWin::Tracking( const TrackingEvent& rTEvt ) 825 { 826 if( mbMoving ) 827 { 828 if ( rTEvt.IsTrackingEnded() ) 829 { 830 mbMoving = sal_False; 831 EndPopupMode( FLOATWIN_POPUPMODEEND_TEAROFF ); 832 } 833 else if ( !rTEvt.GetMouseEvent().IsSynthetic() ) 834 { 835 // move the window according to mouse pos 836 PointerState aState = GetParent()->GetPointerState(); 837 if (ImplHasMirroredGraphics() && IsRTLEnabled()) 838 ImplMirrorFramePos(aState.maPos); 839 maTearOffPosition = aState.maPos - maDelta; 840 GetWindow( WINDOW_BORDER )->SetPosPixel( maTearOffPosition ); 841 } 842 } 843 } 844 845 846 // ======================================================================= 847 848 ImplDockingWindowWrapper::ImplDockingWindowWrapper( const Window *pWindow ) 849 { 850 ImplInitData(); 851 852 mpDockingWindow = (Window*) pWindow; 853 mpParent = pWindow->GetParent(); 854 mbDockable = sal_True; 855 mbLocked = sal_False; 856 mnFloatBits = WB_BORDER | WB_CLOSEABLE | WB_SIZEABLE | (pWindow->GetStyle() & DOCKWIN_FLOATSTYLES); 857 DockingWindow *pDockWin = dynamic_cast< DockingWindow* > ( mpDockingWindow ); 858 if( pDockWin ) 859 mnFloatBits = pDockWin->GetFloatStyle(); 860 861 // must be enabled in Window::Notify to prevent permanent docking during mouse move 862 mbStartDockingEnabled = sal_False; 863 } 864 865 ImplDockingWindowWrapper::~ImplDockingWindowWrapper() 866 { 867 if ( IsFloatingMode() ) 868 { 869 GetWindow()->Show( sal_False, SHOW_NOFOCUSCHANGE ); 870 SetFloatingMode( sal_False ); 871 } 872 } 873 874 // ----------------------------------------------------------------------- 875 876 sal_Bool ImplDockingWindowWrapper::ImplStartDocking( const Point& rPos ) 877 { 878 if ( !mbDockable ) 879 return sal_False; 880 881 if( !mbStartDockingEnabled ) 882 return sal_False; 883 884 maMouseOff = rPos; 885 maMouseStart = maMouseOff; 886 mbDocking = sal_True; 887 mbLastFloatMode = IsFloatingMode(); 888 mbStartFloat = mbLastFloatMode; 889 890 // FloatingBorder berechnen 891 FloatingWindow* pWin; 892 if ( mpFloatWin ) 893 pWin = mpFloatWin; 894 else 895 pWin = new ImplDockFloatWin2( mpParent, mnFloatBits, NULL ); 896 pWin->GetBorder( mnDockLeft, mnDockTop, mnDockRight, mnDockBottom ); 897 if ( !mpFloatWin ) 898 delete pWin; 899 900 Point aPos = GetWindow()->ImplOutputToFrame( Point() ); 901 Size aSize = GetWindow()->GetOutputSizePixel(); 902 mnTrackX = aPos.X(); 903 mnTrackY = aPos.Y(); 904 mnTrackWidth = aSize.Width(); 905 mnTrackHeight = aSize.Height(); 906 907 if ( mbLastFloatMode ) 908 { 909 maMouseOff.X() += mnDockLeft; 910 maMouseOff.Y() += mnDockTop; 911 mnTrackX -= mnDockLeft; 912 mnTrackY -= mnDockTop; 913 mnTrackWidth += mnDockLeft+mnDockRight; 914 mnTrackHeight += mnDockTop+mnDockBottom; 915 } 916 917 Window *pDockingArea = GetWindow()->GetParent(); 918 Window::PointerState aState = pDockingArea->GetPointerState(); 919 920 // mouse pos in screen pixels 921 Point aMousePos = pDockingArea->OutputToScreenPixel( aState.maPos ); 922 Point aDockPos = Point( pDockingArea->AbsoluteScreenToOutputPixel( GetWindow()->OutputToAbsoluteScreenPixel( GetWindow()->GetPosPixel() ) ) ); 923 Rectangle aDockRect( aDockPos, GetWindow()->GetSizePixel() ); 924 StartDocking( aMousePos, aDockRect ); 925 926 GetWindow()->ImplUpdateAll(); 927 GetWindow()->ImplGetFrameWindow()->ImplUpdateAll(); 928 929 GetWindow()->StartTracking( STARTTRACK_KEYMOD ); 930 return sal_True; 931 } 932 933 // ======================================================================= 934 935 void ImplDockingWindowWrapper::ImplInitData() 936 { 937 mpDockingWindow = NULL; 938 939 //GetWindow()->mpWindowImpl->mbDockWin = sal_True; // TODO: must be eliminated 940 mpFloatWin = NULL; 941 mbDockCanceled = sal_False; 942 mbFloatPrevented = sal_False; 943 mbDocking = sal_False; 944 mbPined = sal_False; 945 mbRollUp = sal_False; 946 mbDockBtn = sal_False; 947 mbHideBtn = sal_False; 948 maMaxOutSize = Size( SHRT_MAX, SHRT_MAX ); 949 } 950 951 // ----------------------------------------------------------------------- 952 953 void ImplDockingWindowWrapper::Tracking( const TrackingEvent& rTEvt ) 954 { 955 // used during docking of a currently docked window 956 if ( mbDocking ) 957 { 958 if ( rTEvt.IsTrackingEnded() ) 959 { 960 mbDocking = sal_False; 961 GetWindow()->HideTracking(); 962 if ( rTEvt.IsTrackingCanceled() ) 963 { 964 mbDockCanceled = sal_True; 965 EndDocking( Rectangle( Point( mnTrackX, mnTrackY ), Size( mnTrackWidth, mnTrackHeight ) ), mbLastFloatMode ); 966 mbDockCanceled = sal_False; 967 } 968 else 969 EndDocking( Rectangle( Point( mnTrackX, mnTrackY ), Size( mnTrackWidth, mnTrackHeight ) ), mbLastFloatMode ); 970 } 971 // Docking only upon non-synthetic MouseEvents 972 else if ( !rTEvt.GetMouseEvent().IsSynthetic() || rTEvt.GetMouseEvent().IsModifierChanged() ) 973 { 974 Point aMousePos = rTEvt.GetMouseEvent().GetPosPixel(); 975 Point aFrameMousePos = GetWindow()->ImplOutputToFrame( aMousePos ); 976 Size aFrameSize = GetWindow()->ImplGetFrameWindow()->GetOutputSizePixel(); 977 if ( aFrameMousePos.X() < 0 ) 978 aFrameMousePos.X() = 0; 979 if ( aFrameMousePos.Y() < 0 ) 980 aFrameMousePos.Y() = 0; 981 if ( aFrameMousePos.X() > aFrameSize.Width()-1 ) 982 aFrameMousePos.X() = aFrameSize.Width()-1; 983 if ( aFrameMousePos.Y() > aFrameSize.Height()-1 ) 984 aFrameMousePos.Y() = aFrameSize.Height()-1; 985 aMousePos = GetWindow()->ImplFrameToOutput( aFrameMousePos ); 986 aMousePos.X() -= maMouseOff.X(); 987 aMousePos.Y() -= maMouseOff.Y(); 988 Point aPos = GetWindow()->ImplOutputToFrame( aMousePos ); 989 Rectangle aTrackRect( aPos, Size( mnTrackWidth, mnTrackHeight ) ); 990 Rectangle aCompRect = aTrackRect; 991 aPos.X() += maMouseOff.X(); 992 aPos.Y() += maMouseOff.Y(); 993 994 sal_Bool bFloatMode = Docking( aPos, aTrackRect ); 995 996 mbFloatPrevented = sal_False; 997 if ( mbLastFloatMode != bFloatMode ) 998 { 999 if ( bFloatMode ) 1000 { 1001 aTrackRect.Left() -= mnDockLeft; 1002 aTrackRect.Top() -= mnDockTop; 1003 aTrackRect.Right() += mnDockRight; 1004 aTrackRect.Bottom() += mnDockBottom; 1005 } 1006 else 1007 { 1008 if ( aCompRect == aTrackRect ) 1009 { 1010 aTrackRect.Left() += mnDockLeft; 1011 aTrackRect.Top() += mnDockTop; 1012 aTrackRect.Right() -= mnDockRight; 1013 aTrackRect.Bottom() -= mnDockBottom; 1014 } 1015 } 1016 mbLastFloatMode = bFloatMode; 1017 } 1018 1019 sal_uInt16 nTrackStyle; 1020 if ( bFloatMode ) 1021 nTrackStyle = SHOWTRACK_OBJECT; 1022 else 1023 nTrackStyle = SHOWTRACK_BIG; 1024 Rectangle aShowTrackRect = aTrackRect; 1025 aShowTrackRect.SetPos( GetWindow()->ImplFrameToOutput( aShowTrackRect.TopLeft() ) ); 1026 //if( bFloatMode ) 1027 GetWindow()->ShowTracking( aShowTrackRect, nTrackStyle ); 1028 /*else 1029 { 1030 GetWindow()->HideTracking(); 1031 Point aPt( GetWindow()->GetParent()->ScreenToOutputPixel( aTrackRect.TopLeft() ) ); 1032 GetWindow()->SetPosPixel( aPt ); 1033 }*/ 1034 1035 // Maus-Offset neu berechnen, da Rechteck veraendert werden 1036 // konnte 1037 maMouseOff.X() = aPos.X() - aTrackRect.Left(); 1038 maMouseOff.Y() = aPos.Y() - aTrackRect.Top(); 1039 1040 mnTrackX = aTrackRect.Left(); 1041 mnTrackY = aTrackRect.Top(); 1042 mnTrackWidth = aTrackRect.GetWidth(); 1043 mnTrackHeight = aTrackRect.GetHeight(); 1044 } 1045 } 1046 } 1047 1048 1049 // ----------------------------------------------------------------------- 1050 1051 void ImplDockingWindowWrapper::StartDocking( const Point& rPoint, Rectangle& rRect ) 1052 { 1053 DockingData data( rPoint, rRect, IsFloatingMode() ); 1054 1055 GetWindow()->ImplCallEventListeners( VCLEVENT_WINDOW_STARTDOCKING, &data ); 1056 mbDocking = sal_True; 1057 } 1058 1059 // ----------------------------------------------------------------------- 1060 1061 sal_Bool ImplDockingWindowWrapper::Docking( const Point& rPoint, Rectangle& rRect ) 1062 { 1063 DockingData data( rPoint, rRect, IsFloatingMode() ); 1064 1065 GetWindow()->ImplCallEventListeners( VCLEVENT_WINDOW_DOCKING, &data ); 1066 rRect = data.maTrackRect; 1067 return data.mbFloating; 1068 } 1069 1070 // ----------------------------------------------------------------------- 1071 1072 void ImplDockingWindowWrapper::EndDocking( const Rectangle& rRect, sal_Bool bFloatMode ) 1073 { 1074 Rectangle aRect( rRect ); 1075 1076 if ( !IsDockingCanceled() ) 1077 { 1078 sal_Bool bShow = sal_False; 1079 if ( bFloatMode != IsFloatingMode() ) 1080 { 1081 GetWindow()->Show( sal_False, SHOW_NOFOCUSCHANGE ); 1082 SetFloatingMode( bFloatMode ); 1083 bShow = sal_True; 1084 if ( bFloatMode ) 1085 { 1086 // #i44800# always use outputsize - as in all other places 1087 mpFloatWin->SetOutputSizePixel( aRect.GetSize() ); 1088 mpFloatWin->SetPosPixel( aRect.TopLeft() ); 1089 } 1090 } 1091 if ( !bFloatMode ) 1092 { 1093 Point aPos = aRect.TopLeft(); 1094 aPos = GetWindow()->GetParent()->ScreenToOutputPixel( aPos ); 1095 GetWindow()->SetPosSizePixel( aPos, aRect.GetSize() ); 1096 } 1097 1098 if ( bShow ) 1099 GetWindow()->Show( sal_True, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE ); 1100 } 1101 1102 EndDockingData data( aRect, IsFloatingMode(), IsDockingCanceled() ); 1103 GetWindow()->ImplCallEventListeners( VCLEVENT_WINDOW_ENDDOCKING, &data ); 1104 1105 mbDocking = sal_False; 1106 1107 // must be enabled in Window::Notify to prevent permanent docking during mouse move 1108 mbStartDockingEnabled = sal_False; 1109 } 1110 1111 // ----------------------------------------------------------------------- 1112 1113 sal_Bool ImplDockingWindowWrapper::PrepareToggleFloatingMode() 1114 { 1115 sal_Bool bFloating = sal_True; 1116 GetWindow()->ImplCallEventListeners( VCLEVENT_WINDOW_PREPARETOGGLEFLOATING, &bFloating ); 1117 return bFloating; 1118 } 1119 1120 // ----------------------------------------------------------------------- 1121 1122 sal_Bool ImplDockingWindowWrapper::Close() 1123 { 1124 // TODO: send event 1125 /* 1126 ImplDelData aDelData; 1127 ImplAddDel( &aDelData ); 1128 GetWindow()->ImplCallEventListeners( VCLEVENT_WINDOW_CLOSE ); 1129 if ( aDelData.IsDelete() ) 1130 return sal_False; 1131 ImplRemoveDel( &aDelData ); 1132 1133 if ( mpWindowImpl->mxWindowPeer.is() && IsCreatedWithToolkit() ) 1134 return sal_False; 1135 1136 GetWindow()->Show( sal_False, SHOW_NOFOCUSCHANGE ); 1137 */ 1138 return sal_True; 1139 } 1140 1141 // ----------------------------------------------------------------------- 1142 1143 void ImplDockingWindowWrapper::ToggleFloatingMode() 1144 { 1145 // notify dockingwindow/toolbox 1146 // note: this must be done *before* notifying the 1147 // listeners to have the toolbox in the proper state 1148 if( GetWindow()->ImplIsDockingWindow() ) 1149 ((DockingWindow*) GetWindow())->ToggleFloatingMode(); 1150 1151 // now notify listeners 1152 GetWindow()->ImplCallEventListeners( VCLEVENT_WINDOW_TOGGLEFLOATING ); 1153 1154 // must be enabled in Window::Notify to prevent permanent docking during mouse move 1155 mbStartDockingEnabled = sal_False; 1156 } 1157 1158 // ----------------------------------------------------------------------- 1159 1160 void ImplDockingWindowWrapper::TitleButtonClick( sal_uInt16 nType ) 1161 { 1162 if( nType == TITLE_BUTTON_MENU ) 1163 { 1164 ToolBox *pToolBox = dynamic_cast< ToolBox* >( GetWindow() ); 1165 if( pToolBox ) 1166 { 1167 pToolBox->ExecuteCustomMenu(); 1168 } 1169 } 1170 if( nType == TITLE_BUTTON_DOCKING ) 1171 { 1172 SetFloatingMode( !IsFloatingMode() ); 1173 } 1174 } 1175 1176 // ----------------------------------------------------------------------- 1177 1178 void ImplDockingWindowWrapper::Pin() 1179 { 1180 // TODO: send event 1181 } 1182 1183 // ----------------------------------------------------------------------- 1184 1185 void ImplDockingWindowWrapper::Roll() 1186 { 1187 // TODO: send event 1188 } 1189 1190 // ----------------------------------------------------------------------- 1191 1192 void ImplDockingWindowWrapper::PopupModeEnd() 1193 { 1194 // TODO: send event 1195 } 1196 1197 // ----------------------------------------------------------------------- 1198 1199 void ImplDockingWindowWrapper::Resizing( Size& rSize ) 1200 { 1201 // TODO: add virtual Resizing() to class Window, so we can get rid of class DockingWindow 1202 DockingWindow *pDockingWindow = dynamic_cast< DockingWindow* >( GetWindow() ); 1203 if( pDockingWindow ) 1204 pDockingWindow->Resizing( rSize ); 1205 } 1206 1207 // ----------------------------------------------------------------------- 1208 1209 void ImplDockingWindowWrapper::ShowTitleButton( sal_uInt16 nButton, sal_Bool bVisible ) 1210 { 1211 if ( mpFloatWin ) 1212 mpFloatWin->ShowTitleButton( nButton, bVisible ); 1213 else 1214 { 1215 if ( nButton == TITLE_BUTTON_DOCKING ) 1216 mbDockBtn = bVisible; 1217 else // if ( nButton == TITLE_BUTTON_HIDE ) 1218 mbHideBtn = bVisible; 1219 } 1220 } 1221 1222 // ----------------------------------------------------------------------- 1223 1224 sal_Bool ImplDockingWindowWrapper::IsTitleButtonVisible( sal_uInt16 nButton ) const 1225 { 1226 if ( mpFloatWin ) 1227 return mpFloatWin->IsTitleButtonVisible( nButton ); 1228 else 1229 { 1230 if ( nButton == TITLE_BUTTON_DOCKING ) 1231 return mbDockBtn; 1232 else // if ( nButton == TITLE_BUTTON_HIDE ) 1233 return mbHideBtn; 1234 } 1235 } 1236 1237 // ----------------------------------------------------------------------- 1238 1239 void ImplDockingWindowWrapper::StartPopupMode( ToolBox *pParentToolBox, sal_uLong nFlags ) 1240 { 1241 // do nothing if window is floating 1242 if( IsFloatingMode() ) 1243 return; 1244 1245 GetWindow()->Show( sal_False, SHOW_NOFOCUSCHANGE ); 1246 1247 // prepare reparenting 1248 Window* pRealParent = GetWindow()->GetWindow( WINDOW_PARENT ); 1249 mpOldBorderWin = GetWindow()->GetWindow( WINDOW_BORDER ); 1250 if( mpOldBorderWin == GetWindow() ) 1251 mpOldBorderWin = NULL; // no border window found 1252 1253 // the new parent for popup mode 1254 ImplPopupFloatWin* pWin = new ImplPopupFloatWin( mpParent, this, (nFlags & FLOATWIN_POPUPMODE_ALLOWTEAROFF) != 0 ); 1255 1256 pWin->SetPopupModeEndHdl( LINK( this, ImplDockingWindowWrapper, PopupModeEnd ) ); 1257 pWin->SetText( GetWindow()->GetText() ); 1258 1259 pWin->SetOutputSizePixel( GetWindow()->GetSizePixel() ); 1260 1261 GetWindow()->mpWindowImpl->mpBorderWindow = NULL; 1262 GetWindow()->mpWindowImpl->mnLeftBorder = 0; 1263 GetWindow()->mpWindowImpl->mnTopBorder = 0; 1264 GetWindow()->mpWindowImpl->mnRightBorder = 0; 1265 GetWindow()->mpWindowImpl->mnBottomBorder = 0; 1266 1267 // position toolbox below dragrect 1268 GetWindow()->SetPosPixel( pWin->GetToolboxPosition() ); 1269 1270 // reparent borderwindow and window 1271 if ( mpOldBorderWin ) 1272 mpOldBorderWin->SetParent( pWin ); 1273 GetWindow()->SetParent( pWin ); 1274 1275 // correct border window pointers 1276 GetWindow()->mpWindowImpl->mpBorderWindow = pWin; 1277 pWin->mpWindowImpl->mpClientWindow = GetWindow(); 1278 GetWindow()->mpWindowImpl->mpRealParent = pRealParent; 1279 1280 // set mpFloatWin not until all window positioning is done !!! 1281 // (SetPosPixel etc. check for valid mpFloatWin pointer) 1282 mpFloatWin = pWin; 1283 1284 // if the subtoolbar was opened via keyboard make sure that key events 1285 // will go into subtoolbar 1286 if( pParentToolBox->IsKeyEvent() ) 1287 nFlags |= FLOATWIN_POPUPMODE_GRABFOCUS; 1288 1289 mpFloatWin->StartPopupMode( pParentToolBox, nFlags ); 1290 GetWindow()->Show(); 1291 1292 if( pParentToolBox->IsKeyEvent() ) 1293 { 1294 // send HOME key to subtoolbar in order to select first item 1295 KeyEvent aEvent( 0, KeyCode( KEY_HOME ) ); 1296 mpFloatWin->GetPreferredKeyInputWindow()->KeyInput( aEvent ); 1297 } 1298 } 1299 1300 IMPL_LINK( ImplDockingWindowWrapper, PopupModeEnd, void*, EMPTYARG ) 1301 { 1302 GetWindow()->Show( sal_False, SHOW_NOFOCUSCHANGE ); 1303 1304 // set parameter for handler before destroying floating window 1305 ImplPopupFloatWin *pPopupFloatWin = (ImplPopupFloatWin*) mpFloatWin; 1306 EndPopupModeData aData( pPopupFloatWin->GetTearOffPosition(), mpFloatWin->IsPopupModeTearOff() ); 1307 1308 // before deleting change parent back, so we can delete the floating window alone 1309 Window* pRealParent = GetWindow()->GetWindow( WINDOW_PARENT ); 1310 GetWindow()->mpWindowImpl->mpBorderWindow = NULL; 1311 if ( mpOldBorderWin ) 1312 { 1313 GetWindow()->SetParent( mpOldBorderWin ); 1314 ((ImplBorderWindow*)mpOldBorderWin)->GetBorder( 1315 GetWindow()->mpWindowImpl->mnLeftBorder, GetWindow()->mpWindowImpl->mnTopBorder, 1316 GetWindow()->mpWindowImpl->mnRightBorder, GetWindow()->mpWindowImpl->mnBottomBorder ); 1317 mpOldBorderWin->Resize(); 1318 } 1319 GetWindow()->mpWindowImpl->mpBorderWindow = mpOldBorderWin; 1320 GetWindow()->SetParent( pRealParent ); 1321 GetWindow()->mpWindowImpl->mpRealParent = pRealParent; 1322 1323 delete mpFloatWin; 1324 mpFloatWin = NULL; 1325 1326 // call handler - which will destroy the window and thus the wrapper as well ! 1327 GetWindow()->ImplCallEventListeners( VCLEVENT_WINDOW_ENDPOPUPMODE, &aData ); 1328 1329 return 0; 1330 } 1331 1332 1333 sal_Bool ImplDockingWindowWrapper::IsInPopupMode() const 1334 { 1335 if( GetFloatingWindow() ) 1336 return GetFloatingWindow()->IsInPopupMode(); 1337 else 1338 return sal_False; 1339 } 1340 1341 // ----------------------------------------------------------------------- 1342 1343 void ImplDockingWindowWrapper::SetFloatingMode( sal_Bool bFloatMode ) 1344 { 1345 // do nothing if window is docked and locked 1346 if( !IsFloatingMode() && IsLocked() ) 1347 return; 1348 1349 if ( IsFloatingMode() != bFloatMode ) 1350 { 1351 if ( PrepareToggleFloatingMode() ) 1352 { 1353 sal_Bool bVisible = GetWindow()->IsVisible(); 1354 1355 if ( bFloatMode ) 1356 { 1357 GetWindow()->Show( sal_False, SHOW_NOFOCUSCHANGE ); 1358 1359 maDockPos = GetWindow()->GetPosPixel(); 1360 1361 Window* pRealParent = GetWindow()->GetWindow( WINDOW_PARENT ); 1362 mpOldBorderWin = GetWindow()->GetWindow( WINDOW_BORDER ); 1363 if( mpOldBorderWin == mpDockingWindow ) 1364 mpOldBorderWin = NULL; // no border window found 1365 1366 ImplDockFloatWin2* pWin = 1367 new ImplDockFloatWin2( 1368 mpParent, 1369 mnFloatBits & ( WB_MOVEABLE | WB_SIZEABLE | WB_CLOSEABLE ) ? 1370 mnFloatBits | WB_SYSTEMWINDOW 1371 //#ifdef __USE_OWNERDRAWDECORATION__ 1372 | WB_OWNERDRAWDECORATION 1373 //#endif 1374 : mnFloatBits, 1375 this ); 1376 1377 // reduce the border width for seamless NWF painting 1378 // (especially for the toolbar gradient on Windows XP) 1379 /*AllSettings aSettings( pWin->GetSettings() ); 1380 StyleSettings aStyleSettings( aSettings.GetStyleSettings() ); 1381 aStyleSettings.SetBorderSize( 0 ); 1382 aSettings.SetStyleSettings( aStyleSettings ); 1383 pWin->SetSettings( aSettings );*/ 1384 1385 // mpFloatWin = pWin; 1386 1387 1388 GetWindow()->mpWindowImpl->mpBorderWindow = NULL; 1389 GetWindow()->mpWindowImpl->mnLeftBorder = 0; 1390 GetWindow()->mpWindowImpl->mnTopBorder = 0; 1391 GetWindow()->mpWindowImpl->mnRightBorder = 0; 1392 GetWindow()->mpWindowImpl->mnBottomBorder = 0; 1393 1394 // Falls Parent zerstoert wird, muessen wir auch vom 1395 // BorderWindow den Parent umsetzen 1396 if ( mpOldBorderWin ) 1397 mpOldBorderWin->SetParent( pWin ); 1398 GetWindow()->SetParent( pWin ); 1399 pWin->SetPosPixel( Point() ); 1400 1401 GetWindow()->mpWindowImpl->mpBorderWindow = pWin; 1402 pWin->mpWindowImpl->mpClientWindow = mpDockingWindow; 1403 GetWindow()->mpWindowImpl->mpRealParent = pRealParent; 1404 1405 pWin->SetText( GetWindow()->GetText() ); 1406 pWin->SetOutputSizePixel( GetWindow()->GetSizePixel() ); 1407 pWin->SetPosPixel( maFloatPos ); 1408 // DockingDaten ans FloatingWindow weiterreichen 1409 pWin->ShowTitleButton( TITLE_BUTTON_DOCKING, mbDockBtn ); 1410 pWin->ShowTitleButton( TITLE_BUTTON_HIDE, mbHideBtn ); 1411 pWin->SetPin( mbPined ); 1412 if ( mbRollUp ) 1413 pWin->RollUp(); 1414 else 1415 pWin->RollDown(); 1416 pWin->SetRollUpOutputSizePixel( maRollUpOutSize ); 1417 pWin->SetMinOutputSizePixel( maMinOutSize ); 1418 pWin->SetMaxOutputSizePixel( maMaxOutSize ); 1419 1420 mpFloatWin = pWin; 1421 1422 if ( bVisible ) 1423 GetWindow()->Show( sal_True, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE ); 1424 1425 ToggleFloatingMode(); 1426 } 1427 else 1428 { 1429 GetWindow()->Show( sal_False, SHOW_NOFOCUSCHANGE ); 1430 1431 // FloatingDaten wird im FloatingWindow speichern 1432 maFloatPos = mpFloatWin->GetPosPixel(); 1433 mbDockBtn = mpFloatWin->IsTitleButtonVisible( TITLE_BUTTON_DOCKING ); 1434 mbHideBtn = mpFloatWin->IsTitleButtonVisible( TITLE_BUTTON_HIDE ); 1435 mbPined = mpFloatWin->IsPined(); 1436 mbRollUp = mpFloatWin->IsRollUp(); 1437 maRollUpOutSize = mpFloatWin->GetRollUpOutputSizePixel(); 1438 maMinOutSize = mpFloatWin->GetMinOutputSizePixel(); 1439 maMaxOutSize = mpFloatWin->GetMaxOutputSizePixel(); 1440 1441 Window* pRealParent = GetWindow()->GetWindow( WINDOW_PARENT ); //mpWindowImpl->mpRealParent; 1442 GetWindow()->mpWindowImpl->mpBorderWindow = NULL; 1443 if ( mpOldBorderWin ) 1444 { 1445 GetWindow()->SetParent( mpOldBorderWin ); 1446 ((ImplBorderWindow*)mpOldBorderWin)->GetBorder( 1447 GetWindow()->mpWindowImpl->mnLeftBorder, GetWindow()->mpWindowImpl->mnTopBorder, 1448 GetWindow()->mpWindowImpl->mnRightBorder, GetWindow()->mpWindowImpl->mnBottomBorder ); 1449 mpOldBorderWin->Resize(); 1450 } 1451 GetWindow()->mpWindowImpl->mpBorderWindow = mpOldBorderWin; 1452 GetWindow()->SetParent( pRealParent ); 1453 GetWindow()->mpWindowImpl->mpRealParent = pRealParent; 1454 1455 delete static_cast<ImplDockFloatWin2*>(mpFloatWin); 1456 mpFloatWin = NULL; 1457 GetWindow()->SetPosPixel( maDockPos ); 1458 1459 if ( bVisible ) 1460 GetWindow()->Show(); 1461 1462 ToggleFloatingMode(); 1463 1464 } 1465 } 1466 } 1467 } 1468 1469 // ----------------------------------------------------------------------- 1470 1471 void ImplDockingWindowWrapper::SetFloatStyle( WinBits nStyle ) 1472 { 1473 mnFloatBits = nStyle; 1474 } 1475 1476 // ----------------------------------------------------------------------- 1477 1478 WinBits ImplDockingWindowWrapper::GetFloatStyle() const 1479 { 1480 return mnFloatBits; 1481 } 1482 1483 // ----------------------------------------------------------------------- 1484 1485 void ImplDockingWindowWrapper::SetTabStop() 1486 { 1487 GetWindow()->SetStyle( GetWindow()->GetStyle() | (WB_GROUP | WB_TABSTOP) ); 1488 } 1489 1490 // ----------------------------------------------------------------------- 1491 1492 void ImplDockingWindowWrapper::SetPosSizePixel( long nX, long nY, 1493 long nWidth, long nHeight, 1494 sal_uInt16 nFlags ) 1495 { 1496 if ( mpFloatWin ) 1497 mpFloatWin->SetPosSizePixel( nX, nY, nWidth, nHeight, nFlags ); 1498 else 1499 GetWindow()->SetPosSizePixel( nX, nY, nWidth, nHeight, nFlags ); 1500 } 1501 1502 // ----------------------------------------------------------------------- 1503 1504 Point ImplDockingWindowWrapper::GetPosPixel() const 1505 { 1506 if ( mpFloatWin ) 1507 return mpFloatWin->GetPosPixel(); 1508 else 1509 return mpDockingWindow->GetPosPixel(); 1510 } 1511 1512 // ----------------------------------------------------------------------- 1513 1514 Size ImplDockingWindowWrapper::GetSizePixel() const 1515 { 1516 if ( mpFloatWin ) 1517 return mpFloatWin->GetSizePixel(); 1518 else 1519 return mpDockingWindow->GetSizePixel(); 1520 } 1521 1522 // ----------------------------------------------------------------------- 1523 1524 void ImplDockingWindowWrapper::SetOutputSizePixel( const Size& rNewSize ) 1525 { 1526 if ( mpFloatWin ) 1527 mpFloatWin->SetOutputSizePixel( rNewSize ); 1528 else 1529 GetWindow()->SetOutputSizePixel( rNewSize ); 1530 } 1531 1532 // ----------------------------------------------------------------------- 1533 1534 Size ImplDockingWindowWrapper::GetOutputSizePixel() const 1535 { 1536 if ( mpFloatWin ) 1537 return mpFloatWin->GetOutputSizePixel(); 1538 else 1539 return mpDockingWindow->GetOutputSizePixel(); 1540 } 1541 1542 Point ImplDockingWindowWrapper::GetFloatingPos() const 1543 { 1544 if ( mpFloatWin ) 1545 { 1546 //Rectangle aRect = mpFloatWin->GetWindow( WINDOW_CLIENT)->GetWindowExtentsRelative( mpFloatWin->GetParent() ); 1547 WindowStateData aData; 1548 aData.SetMask( WINDOWSTATE_MASK_POS ); 1549 mpFloatWin->GetWindowStateData( aData ); 1550 Point aPos( aData.GetX(), aData.GetY() ); 1551 aPos = mpFloatWin->GetParent()->ImplGetFrameWindow()->AbsoluteScreenToOutputPixel( aPos ); 1552 return aPos; 1553 } 1554 else 1555 return maFloatPos; 1556 } 1557 1558 // ----------------------------------------------------------------------- 1559 // old inlines from DockingWindow 1560 // ----------------------------------------------------------------------- 1561 1562 void ImplDockingWindowWrapper::SetPin( sal_Bool bPin ) 1563 { 1564 if ( mpFloatWin ) 1565 mpFloatWin->SetPin( bPin ); 1566 mbPined = bPin; 1567 } 1568 1569 sal_Bool ImplDockingWindowWrapper::IsPined() const 1570 { 1571 if ( mpFloatWin ) 1572 return mpFloatWin->IsPined(); 1573 return mbPined; 1574 } 1575 1576 void ImplDockingWindowWrapper::RollUp() 1577 { 1578 if ( mpFloatWin ) 1579 mpFloatWin->RollUp(); 1580 mbRollUp = sal_True; 1581 } 1582 1583 void ImplDockingWindowWrapper::RollDown() 1584 { 1585 if ( mpFloatWin ) 1586 mpFloatWin->RollDown(); 1587 mbRollUp = sal_False; 1588 } 1589 1590 sal_Bool ImplDockingWindowWrapper::IsRollUp() const 1591 { 1592 if ( mpFloatWin ) 1593 return mpFloatWin->IsRollUp(); 1594 return mbRollUp; 1595 } 1596 1597 void ImplDockingWindowWrapper::SetRollUpOutputSizePixel( const Size& rSize ) 1598 { 1599 if ( mpFloatWin ) 1600 mpFloatWin->SetRollUpOutputSizePixel( rSize ); 1601 maRollUpOutSize = rSize; 1602 } 1603 1604 Size ImplDockingWindowWrapper::GetRollUpOutputSizePixel() const 1605 { 1606 if ( mpFloatWin ) 1607 return mpFloatWin->GetRollUpOutputSizePixel(); 1608 return maRollUpOutSize; 1609 } 1610 1611 void ImplDockingWindowWrapper::SetMinOutputSizePixel( const Size& rSize ) 1612 { 1613 if ( mpFloatWin ) 1614 mpFloatWin->SetMinOutputSizePixel( rSize ); 1615 maMinOutSize = rSize; 1616 } 1617 1618 void ImplDockingWindowWrapper::SetMaxOutputSizePixel( const Size& rSize ) 1619 { 1620 if ( mpFloatWin ) 1621 mpFloatWin->SetMaxOutputSizePixel( rSize ); 1622 maMaxOutSize = rSize; 1623 } 1624 1625 const Size& ImplDockingWindowWrapper::GetMinOutputSizePixel() const 1626 { 1627 if ( mpFloatWin ) 1628 return mpFloatWin->GetMinOutputSizePixel(); 1629 return maMinOutSize; 1630 } 1631 1632 const Size& ImplDockingWindowWrapper::GetMaxOutputSizePixel() const 1633 { 1634 if ( mpFloatWin ) 1635 return mpFloatWin->GetMaxOutputSizePixel(); 1636 return maMaxOutSize; 1637 } 1638 1639 void ImplDockingWindowWrapper::SetFloatingPos( const Point& rNewPos ) 1640 { 1641 if ( mpFloatWin ) 1642 mpFloatWin->SetPosPixel( rNewPos ); 1643 else 1644 maFloatPos = rNewPos; 1645 } 1646 1647 sal_Bool ImplDockingWindowWrapper::IsFloatingMode() const 1648 { 1649 return (mpFloatWin != NULL); 1650 } 1651 1652 1653 void ImplDockingWindowWrapper::SetDragArea( const Rectangle& rRect ) 1654 { 1655 maDragArea = rRect; 1656 } 1657 1658 Rectangle ImplDockingWindowWrapper::GetDragArea() const 1659 { 1660 return maDragArea; 1661 } 1662 1663 void ImplDockingWindowWrapper::Lock() 1664 { 1665 mbLocked = sal_True; 1666 // only toolbars support locking 1667 ToolBox *pToolBox = dynamic_cast< ToolBox * >( GetWindow() ); 1668 if( pToolBox ) 1669 pToolBox->Lock( mbLocked ); 1670 } 1671 1672 void ImplDockingWindowWrapper::Unlock() 1673 { 1674 mbLocked = sal_False; 1675 // only toolbars support locking 1676 ToolBox *pToolBox = dynamic_cast< ToolBox * >( GetWindow() ); 1677 if( pToolBox ) 1678 pToolBox->Lock( mbLocked ); 1679 } 1680 1681 sal_Bool ImplDockingWindowWrapper::IsLocked() const 1682 { 1683 return mbLocked; 1684 } 1685