1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <tools/time.hxx>
22 #include <vcl/event.hxx>
23 #include <vcl/floatwin.hxx>
24 #include <vcl/dockwin.hxx>
25 #include <vcl/layout.hxx>
26 #include <vcl/svapp.hxx>
27 #include <vcl/timer.hxx>
28 #include <vcl/idle.hxx>
29 #include <vcl/unowrap.hxx>
30 #include <vcl/settings.hxx>
35 #include <salframe.hxx>
37 #define DOCKWIN_FLOATSTYLES (WB_SIZEABLE | WB_MOVEABLE | WB_CLOSEABLE | WB_STANDALONE | WB_PINABLE | WB_ROLLABLE )
39 class DockingWindow::ImplData
44 VclPtr
<vcl::Window
> mpParent
;
48 DockingWindow::ImplData::ImplData()
51 maMaxOutSize
= Size( SHRT_MAX
, SHRT_MAX
);
54 class ImplDockFloatWin
: public FloatingWindow
57 VclPtr
<DockingWindow
> mpDockWin
;
58 sal_uInt64 mnLastTicks
;
63 ImplSVEvent
* mnLastUserEvent
;
65 DECL_LINK(DockingHdl
, void *, void);
66 DECL_LINK(DockTimerHdl
, Idle
*, void);
68 ImplDockFloatWin( vcl::Window
* pParent
, WinBits nWinBits
,
69 DockingWindow
* pDockingWin
);
70 virtual ~ImplDockFloatWin() override
;
71 virtual void dispose() override
;
73 virtual void Move() override
;
74 virtual void Resize() override
;
75 virtual void Resizing( Size
& rSize
) override
;
76 virtual bool Close() override
;
79 ImplDockFloatWin::ImplDockFloatWin( vcl::Window
* pParent
, WinBits nWinBits
,
80 DockingWindow
* pDockingWin
) :
81 FloatingWindow( pParent
, nWinBits
),
82 mpDockWin( pDockingWin
),
83 mnLastTicks( tools::Time::GetSystemTicks() ),
85 mnLastUserEvent( nullptr )
87 // copy settings of DockingWindow
90 SetSettings( pDockingWin
->GetSettings() );
91 Enable( pDockingWin
->IsEnabled(), false );
92 EnableInput( pDockingWin
->IsInputEnabled(), false );
93 AlwaysEnableInput( pDockingWin
->IsAlwaysEnableInput(), false );
94 EnableAlwaysOnTop( pDockingWin
->IsAlwaysOnTopEnabled() );
95 SetActivateMode( pDockingWin
->GetActivateMode() );
100 maDockIdle
.SetIdleHdl( LINK( this, ImplDockFloatWin
, DockTimerHdl
) );
101 maDockIdle
.SetPriority( SchedulerPriority::MEDIUM
);
102 maDockIdle
.SetDebugName( "vcl::ImplDockFloatWin maDockIdle" );
105 ImplDockFloatWin::~ImplDockFloatWin()
110 void ImplDockFloatWin::dispose()
112 if( mnLastUserEvent
)
113 Application::RemoveUserEvent( mnLastUserEvent
);
118 FloatingWindow::dispose();
121 IMPL_LINK_NOARG(ImplDockFloatWin
, DockTimerHdl
, Idle
*, void)
123 SAL_WARN_IF( !mpDockWin
->IsFloatingMode(), "vcl", "docktimer called but not floating" );
126 PointerState aState
= GetPointerState();
128 if( aState
.mnState
& KEY_MOD1
)
130 // i43499 CTRL disables docking now
131 mpDockWin
->GetParent()->ImplGetFrameWindow()->HideTracking();
132 mpDockWin
->EndDocking( maDockRect
, true );
133 if( aState
.mnState
& ( MOUSE_LEFT
| MOUSE_MIDDLE
| MOUSE_RIGHT
) )
136 else if( ! ( aState
.mnState
& ( MOUSE_LEFT
| MOUSE_MIDDLE
| MOUSE_RIGHT
) ) )
138 mpDockWin
->GetParent()->ImplGetFrameWindow()->HideTracking();
139 mpDockWin
->EndDocking( maDockRect
, false );
143 mpDockWin
->GetParent()->ImplGetFrameWindow()->ShowTracking( maDockRect
, ShowTrackFlags::Big
| ShowTrackFlags::TrackWindow
);
148 IMPL_LINK_NOARG(ImplDockFloatWin
, DockingHdl
, void*, void)
150 PointerState aState
= mpDockWin
->GetParent()->GetPointerState();
152 mnLastUserEvent
= nullptr;
153 if( mpDockWin
->IsDockable() &&
154 (tools::Time::GetSystemTicks() - mnLastTicks
> 500) &&
155 ( aState
.mnState
& ( MOUSE_LEFT
| MOUSE_MIDDLE
| MOUSE_RIGHT
) ) &&
156 !(aState
.mnState
& KEY_MOD1
) ) // i43499 CTRL disables docking now
158 maDockPos
= Point( mpDockWin
->GetParent()->AbsoluteScreenToOutputPixel( OutputToAbsoluteScreenPixel( Point() ) ) );
159 maDockPos
= mpDockWin
->GetParent()->OutputToScreenPixel( maDockPos
); // sfx expects screen coordinates
161 if( ! mpDockWin
->IsDocking() )
162 mpDockWin
->StartDocking();
163 maDockRect
= Rectangle( maDockPos
, mpDockWin
->GetSizePixel() );
165 // mouse pos also in screen pixels
166 Point aMousePos
= mpDockWin
->GetParent()->OutputToScreenPixel( aState
.maPos
);
168 bool bFloatMode
= mpDockWin
->Docking( aMousePos
, maDockRect
);
171 mpDockWin
->GetParent()->ImplGetFrameWindow()->ShowTracking( maDockRect
, ShowTrackFlags::Object
| ShowTrackFlags::TrackWindow
);
172 DockTimerHdl( nullptr );
176 mpDockWin
->GetParent()->ImplGetFrameWindow()->HideTracking();
178 mpDockWin
->EndDocking( maDockRect
, true );
184 void ImplDockFloatWin::Move()
190 FloatingWindow::Move();
194 * note: the window should only dock if
195 * the user releases all mouse buttons. The real problem here
196 * is that we don't get mouse events (at least not on X)
197 * if the mouse is on the decoration. So we have to start an
198 * awkward timer based process that polls the modifier/buttons
199 * to see whether they are in the right condition shortly after the
202 if( ! mnLastUserEvent
)
203 mnLastUserEvent
= Application::PostUserEvent( LINK( this, ImplDockFloatWin
, DockingHdl
), nullptr, true );
206 void ImplDockFloatWin::Resize()
208 FloatingWindow::Resize();
209 Size
aSize( GetSizePixel() );
210 mpDockWin
->ImplPosSizeWindow( 0, 0, aSize
.Width(), aSize
.Height(), PosSizeFlags::PosSize
);
213 void ImplDockFloatWin::Resizing( Size
& rSize
)
215 FloatingWindow::Resizing( rSize
);
216 mpDockWin
->Resizing( rSize
);
219 bool ImplDockFloatWin::Close()
221 return mpDockWin
->Close();
224 bool DockingWindow::ImplStartDocking( const Point
& rPos
)
230 maMouseStart
= maMouseOff
;
232 mbLastFloatMode
= IsFloatingMode();
233 mbStartFloat
= mbLastFloatMode
;
235 // calculate FloatingBorder
236 VclPtr
<FloatingWindow
> pWin
;
240 pWin
= VclPtr
<ImplDockFloatWin
>::Create( mpImplData
->mpParent
, mnFloatBits
, nullptr );
241 pWin
->GetBorder( mnDockLeft
, mnDockTop
, mnDockRight
, mnDockBottom
);
243 pWin
.disposeAndClear();
245 Point aPos
= ImplOutputToFrame( Point() );
246 Size aSize
= Window::GetOutputSizePixel();
249 mnTrackWidth
= aSize
.Width();
250 mnTrackHeight
= aSize
.Height();
252 if ( mbLastFloatMode
)
254 maMouseOff
.X() += mnDockLeft
;
255 maMouseOff
.Y() += mnDockTop
;
256 mnTrackX
-= mnDockLeft
;
257 mnTrackY
-= mnDockTop
;
258 mnTrackWidth
+= mnDockLeft
+mnDockRight
;
259 mnTrackHeight
+= mnDockTop
+mnDockBottom
;
262 if ( GetSettings().GetStyleSettings().GetDragFullOptions() & DragFullOptions::Docking
&&
263 !( mnFloatBits
& ( WB_MOVEABLE
| WB_SIZEABLE
| WB_CLOSEABLE
) ) ) // no full drag when migrating to system window
270 ImplGetFrameWindow()->ImplUpdateAll();
273 StartTracking( StartTrackingFlags::KeyMod
);
277 void DockingWindow::ImplInitDockingWindowData()
279 mpWindowImpl
->mbDockWin
= true;
280 mpFloatWin
= nullptr;
281 mpOldBorderWin
= nullptr;
282 mpImplData
= new ImplData
;
292 mbDockCanceled
= false;
296 mbLastFloatMode
= false;
297 mbStartFloat
= false;
302 mbIsDefferedInit
= false;
303 mbIsCalculatingInitialLayoutSize
= false;
304 mpDialogParent
= nullptr;
306 //To-Do, reuse maResizeTimer
307 maLayoutIdle
.SetPriority(SchedulerPriority::RESIZE
);
308 maLayoutIdle
.SetIdleHdl( LINK( this, DockingWindow
, ImplHandleLayoutTimerHdl
) );
309 maLayoutIdle
.SetDebugName( "vcl::DockingWindow maLayoutIdle" );
312 void DockingWindow::ImplInit( vcl::Window
* pParent
, WinBits nStyle
)
314 if ( !(nStyle
& WB_NODIALOGCONTROL
) )
315 nStyle
|= WB_DIALOGCONTROL
;
317 mpImplData
->mpParent
= pParent
;
318 mbDockable
= (nStyle
& WB_DOCKABLE
) != 0;
319 mnFloatBits
= WB_BORDER
| (nStyle
& DOCKWIN_FLOATSTYLES
);
320 nStyle
&= ~(DOCKWIN_FLOATSTYLES
| WB_BORDER
);
321 if ( nStyle
& WB_DOCKBORDER
)
324 Window::ImplInit( pParent
, nStyle
, nullptr );
329 void DockingWindow::ImplInitSettings()
331 // Hack: to be able to build DockingWindows w/o background before switching
333 if ( IsBackground() )
335 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
338 if ( IsControlBackground() )
339 aColor
= GetControlBackground();
340 else if ( Window::GetStyle() & WB_3DLOOK
)
341 aColor
= rStyleSettings
.GetFaceColor();
343 aColor
= rStyleSettings
.GetWindowColor();
344 SetBackground( aColor
);
348 DockingWindow::DockingWindow( WindowType nType
) :
351 ImplInitDockingWindowData();
354 DockingWindow::DockingWindow( vcl::Window
* pParent
, WinBits nStyle
) :
355 Window( WINDOW_DOCKINGWINDOW
)
357 ImplInitDockingWindowData();
358 ImplInit( pParent
, nStyle
);
361 //Find the real parent stashed in mpDialogParent.
362 void DockingWindow::doDeferredInit(WinBits nBits
)
364 vcl::Window
*pParent
= mpDialogParent
;
365 mpDialogParent
= nullptr;
366 ImplInit(pParent
, nBits
);
367 mbIsDefferedInit
= false;
370 void DockingWindow::loadUI(vcl::Window
* pParent
, const OString
& rID
, const OUString
& rUIXMLDescription
,
371 const css::uno::Reference
<css::frame::XFrame
> &rFrame
)
373 mbIsDefferedInit
= true;
374 mpDialogParent
= pParent
; //should be unset in doDeferredInit
375 m_pUIBuilder
.reset( new VclBuilder(this, getUIRootDir(), rUIXMLDescription
, rID
, rFrame
) );
378 DockingWindow::DockingWindow(vcl::Window
* pParent
, const OString
& rID
,
379 const OUString
& rUIXMLDescription
, const css::uno::Reference
<css::frame::XFrame
> &rFrame
)
380 : Window(WINDOW_DOCKINGWINDOW
)
382 ImplInitDockingWindowData();
384 loadUI(pParent
, rID
, rUIXMLDescription
, rFrame
);
387 DockingWindow::~DockingWindow()
392 void DockingWindow::dispose()
394 if ( IsFloatingMode() )
396 Show( false, ShowFlags::NoFocusChange
);
397 SetFloatingMode(false);
400 mpImplData
= nullptr;
402 mpOldBorderWin
.clear();
403 mpDialogParent
.clear();
408 void DockingWindow::Tracking( const TrackingEvent
& rTEvt
)
410 if( GetDockingManager()->IsDockable( this ) ) // new docking interface
411 return Window::Tracking( rTEvt
);
415 if ( rTEvt
.IsTrackingEnded() )
420 // reset old state on Cancel
421 if ( rTEvt
.IsTrackingCanceled() )
424 Rectangle
aRect( Point( mnTrackX
, mnTrackY
), Size( mnTrackWidth
, mnTrackHeight
) );
425 EndDocking( aRect
, mbStartFloat
);
431 if ( rTEvt
.IsTrackingCanceled() )
433 mbDockCanceled
= true;
434 EndDocking( Rectangle( Point( mnTrackX
, mnTrackY
), Size( mnTrackWidth
, mnTrackHeight
) ), mbLastFloatMode
);
435 mbDockCanceled
= false;
438 EndDocking( Rectangle( Point( mnTrackX
, mnTrackY
), Size( mnTrackWidth
, mnTrackHeight
) ), mbLastFloatMode
);
441 // dock only for non-synthetic MouseEvents
442 else if ( !rTEvt
.GetMouseEvent().IsSynthetic() || rTEvt
.GetMouseEvent().IsModifierChanged() )
444 Point aMousePos
= rTEvt
.GetMouseEvent().GetPosPixel();
445 Point aFrameMousePos
= ImplOutputToFrame( aMousePos
);
446 Size aFrameSize
= mpWindowImpl
->mpFrameWindow
->GetOutputSizePixel();
447 if ( aFrameMousePos
.X() < 0 )
448 aFrameMousePos
.X() = 0;
449 if ( aFrameMousePos
.Y() < 0 )
450 aFrameMousePos
.Y() = 0;
451 if ( aFrameMousePos
.X() > aFrameSize
.Width()-1 )
452 aFrameMousePos
.X() = aFrameSize
.Width()-1;
453 if ( aFrameMousePos
.Y() > aFrameSize
.Height()-1 )
454 aFrameMousePos
.Y() = aFrameSize
.Height()-1;
455 aMousePos
= ImplFrameToOutput( aFrameMousePos
);
456 aMousePos
.X() -= maMouseOff
.X();
457 aMousePos
.Y() -= maMouseOff
.Y();
458 Point aFramePos
= ImplOutputToFrame( aMousePos
);
459 Rectangle
aTrackRect( aFramePos
, Size( mnTrackWidth
, mnTrackHeight
) );
460 Rectangle aCompRect
= aTrackRect
;
461 aFramePos
.X() += maMouseOff
.X();
462 aFramePos
.Y() += maMouseOff
.Y();
465 bool bFloatMode
= Docking( aFramePos
, aTrackRect
);
466 if ( mbLastFloatMode
!= bFloatMode
)
470 aTrackRect
.Left() -= mnDockLeft
;
471 aTrackRect
.Top() -= mnDockTop
;
472 aTrackRect
.Right() += mnDockRight
;
473 aTrackRect
.Bottom() += mnDockBottom
;
477 if ( aCompRect
== aTrackRect
)
479 aTrackRect
.Left() += mnDockLeft
;
480 aTrackRect
.Top() += mnDockTop
;
481 aTrackRect
.Right() -= mnDockRight
;
482 aTrackRect
.Bottom() -= mnDockBottom
;
485 mbLastFloatMode
= bFloatMode
;
489 Point aOldPos
= OutputToScreenPixel( Point() );
490 EndDocking( aTrackRect
, mbLastFloatMode
);
491 // repaint if state or position has changed
492 if ( aOldPos
!= OutputToScreenPixel( Point() ) )
495 ImplGetFrameWindow()->ImplUpdateAll();
497 // EndDocking( aTrackRect, mbLastFloatMode );
501 ShowTrackFlags nTrackStyle
;
503 nTrackStyle
= ShowTrackFlags::Big
;
505 nTrackStyle
= ShowTrackFlags::Object
;
506 Rectangle aShowTrackRect
= aTrackRect
;
507 aShowTrackRect
.SetPos( ImplFrameToOutput( aShowTrackRect
.TopLeft() ) );
508 ShowTracking( aShowTrackRect
, nTrackStyle
);
510 // recalculate mouse offset, as the rectangle was changed
511 maMouseOff
.X() = aFramePos
.X() - aTrackRect
.Left();
512 maMouseOff
.Y() = aFramePos
.Y() - aTrackRect
.Top();
515 mnTrackX
= aTrackRect
.Left();
516 mnTrackY
= aTrackRect
.Top();
517 mnTrackWidth
= aTrackRect
.GetWidth();
518 mnTrackHeight
= aTrackRect
.GetHeight();
523 bool DockingWindow::EventNotify( NotifyEvent
& rNEvt
)
525 if( GetDockingManager()->IsDockable( this ) ) // new docking interface
526 return Window::EventNotify( rNEvt
);
530 const bool bDockingSupportCrippled
= !StyleSettings::GetDockingFloatsSupported();
532 if ( rNEvt
.GetType() == MouseNotifyEvent::MOUSEBUTTONDOWN
)
534 const MouseEvent
* pMEvt
= rNEvt
.GetMouseEvent();
535 if ( pMEvt
->IsLeft() )
537 if (!bDockingSupportCrippled
&& pMEvt
->IsMod1() && (pMEvt
->GetClicks() == 2) )
539 SetFloatingMode( !IsFloatingMode() );
542 else if ( pMEvt
->GetClicks() == 1 )
544 // check if window is floating standalone (IsFloating())
545 // or only partially floating and still docked with one border
546 // ( !mpWindowImpl->mbFrame)
547 if( ! IsFloatingMode() || ! mpFloatWin
->mpWindowImpl
->mbFrame
)
549 Point aPos
= pMEvt
->GetPosPixel();
550 vcl::Window
* pWindow
= rNEvt
.GetWindow();
551 if ( pWindow
!= this )
553 aPos
= pWindow
->OutputToScreenPixel( aPos
);
554 aPos
= ScreenToOutputPixel( aPos
);
556 ImplStartDocking( aPos
);
562 else if( rNEvt
.GetType() == MouseNotifyEvent::KEYINPUT
)
564 const vcl::KeyCode
& rKey
= rNEvt
.GetKeyEvent()->GetKeyCode();
565 if( rKey
.GetCode() == KEY_F10
&& rKey
.GetModifier() &&
566 rKey
.IsShift() && rKey
.IsMod1() && !bDockingSupportCrippled
)
568 SetFloatingMode( !IsFloatingMode() );
574 return Window::EventNotify( rNEvt
);
577 void DockingWindow::StartDocking()
582 bool DockingWindow::Docking( const Point
&, Rectangle
& )
584 return IsFloatingMode();
587 void DockingWindow::EndDocking( const Rectangle
& rRect
, bool bFloatMode
)
589 bool bOrigDockCanceled
= mbDockCanceled
;
590 if (bFloatMode
&& !StyleSettings::GetDockingFloatsSupported())
591 mbDockCanceled
= true;
593 if ( !IsDockingCanceled() )
596 if ( bool(bFloatMode
) != IsFloatingMode() )
598 Show( false, ShowFlags::NoFocusChange
);
599 SetFloatingMode( bFloatMode
);
601 if ( bFloatMode
&& mpFloatWin
)
602 mpFloatWin
->SetPosSizePixel( rRect
.TopLeft(), rRect
.GetSize() );
606 Point aPos
= rRect
.TopLeft();
607 aPos
= GetParent()->ScreenToOutputPixel( aPos
);
608 Window::SetPosSizePixel( aPos
, rRect
.GetSize() );
615 mbDockCanceled
= bOrigDockCanceled
;
618 bool DockingWindow::PrepareToggleFloatingMode()
623 bool DockingWindow::Close()
625 VclPtr
<vcl::Window
> xWindow
= this;
626 CallEventListeners( VCLEVENT_WINDOW_CLOSE
);
627 if ( xWindow
->IsDisposed() )
630 if ( mpWindowImpl
->mxWindowPeer
.is() && IsCreatedWithToolkit() )
633 Show( false, ShowFlags::NoFocusChange
);
637 void DockingWindow::ToggleFloatingMode()
641 void DockingWindow::Resizing( Size
& )
645 void DockingWindow::DoInitialLayout()
647 if (GetSettings().GetStyleSettings().GetAutoMnemonic())
648 Accelerator::GenerateAutoMnemonicsOnHierarchy(this);
650 if (isLayoutEnabled())
652 mbIsCalculatingInitialLayoutSize
= true;
653 setDeferredProperties();
654 if (IsFloatingMode())
655 setOptimalLayoutSize();
656 mbIsCalculatingInitialLayoutSize
= false;
660 void DockingWindow::StateChanged( StateChangedType nType
)
664 case StateChangedType::InitShow
:
668 case StateChangedType::ControlBackground
:
673 case StateChangedType::Style
:
674 mbDockable
= (GetStyle() & WB_DOCKABLE
) != 0;
681 Window::StateChanged( nType
);
684 void DockingWindow::DataChanged( const DataChangedEvent
& rDCEvt
)
686 if ( (rDCEvt
.GetType() == DataChangedEventType::SETTINGS
) &&
687 (rDCEvt
.GetFlags() & AllSettingsFlags::STYLE
) )
693 Window::DataChanged( rDCEvt
);
696 void DockingWindow::SetFloatingMode( bool bFloatMode
)
698 ImplDockingWindowWrapper
*pWrapper
= ImplGetDockingManager()->GetDockingWindowWrapper( this );
701 pWrapper
->SetFloatingMode( bFloatMode
);
704 if ( IsFloatingMode() != bFloatMode
)
706 if ( PrepareToggleFloatingMode() ) // changes to floating mode can be vetoed
708 bool bVisible
= IsVisible();
712 Show( false, ShowFlags::NoFocusChange
);
714 sal_Int32 nBorderWidth
= get_border_width();
716 maDockPos
= Window::GetPosPixel();
718 vcl::Window
* pRealParent
= mpWindowImpl
->mpRealParent
;
719 mpOldBorderWin
= mpWindowImpl
->mpBorderWindow
;
721 VclPtrInstance
<ImplDockFloatWin
> pWin(
722 mpImplData
->mpParent
,
723 mnFloatBits
& ( WB_MOVEABLE
| WB_SIZEABLE
| WB_CLOSEABLE
) ? mnFloatBits
| WB_SYSTEMWINDOW
: mnFloatBits
,
726 mpWindowImpl
->mpBorderWindow
= nullptr;
727 mpWindowImpl
->mnLeftBorder
= 0;
728 mpWindowImpl
->mnTopBorder
= 0;
729 mpWindowImpl
->mnRightBorder
= 0;
730 mpWindowImpl
->mnBottomBorder
= 0;
731 // if the parent gets destroyed, we also have to reset the parent of the BorderWindow
732 if ( mpOldBorderWin
)
733 mpOldBorderWin
->SetParent( pWin
);
735 // #i123765# reset the buffered DropTargets when undocking, else it may not
736 // be correctly initialized
737 mpWindowImpl
->mxDNDListenerContainer
.clear();
740 SetPosPixel( Point() );
741 mpWindowImpl
->mpBorderWindow
= pWin
;
742 pWin
->mpWindowImpl
->mpClientWindow
= this;
743 mpWindowImpl
->mpRealParent
= pRealParent
;
744 pWin
->SetText( Window::GetText() );
745 Size
aSize(Window::GetSizePixel());
746 pWin
->SetOutputSizePixel(aSize
);
747 pWin
->SetPosPixel( maFloatPos
);
748 // pass on DockingData to FloatingWindow
749 pWin
->ShowTitleButton( TitleButton::Docking
, mbDockBtn
);
750 pWin
->ShowTitleButton( TitleButton::Hide
, mbHideBtn
);
751 pWin
->SetPin( mbPinned
);
756 pWin
->SetRollUpOutputSizePixel( maRollUpOutSize
);
757 pWin
->SetMinOutputSizePixel( maMinOutSize
);
759 pWin
->SetMaxOutputSizePixel( mpImplData
->maMaxOutSize
);
761 ToggleFloatingMode();
763 set_border_width(nBorderWidth
);
768 mpFloatWin
->queue_resize();
772 Show( false, ShowFlags::NoFocusChange
);
774 sal_Int32 nBorderWidth
= get_border_width();
776 // store FloatingData in FloatingWindow
777 maFloatPos
= mpFloatWin
->GetPosPixel();
778 mbDockBtn
= mpFloatWin
->IsTitleButtonVisible( TitleButton::Docking
);
779 mbHideBtn
= mpFloatWin
->IsTitleButtonVisible( TitleButton::Hide
);
780 mbPinned
= mpFloatWin
->IsPinned();
781 mbRollUp
= mpFloatWin
->IsRollUp();
782 maRollUpOutSize
= mpFloatWin
->GetRollUpOutputSizePixel();
783 maMinOutSize
= mpFloatWin
->GetMinOutputSizePixel();
784 mpImplData
->maMaxOutSize
= mpFloatWin
->GetMaxOutputSizePixel();
786 vcl::Window
* pRealParent
= mpWindowImpl
->mpRealParent
;
787 mpWindowImpl
->mpBorderWindow
= nullptr;
788 if ( mpOldBorderWin
)
790 SetParent( mpOldBorderWin
);
791 static_cast<ImplBorderWindow
*>(mpOldBorderWin
.get())->GetBorder( mpWindowImpl
->mnLeftBorder
, mpWindowImpl
->mnTopBorder
, mpWindowImpl
->mnRightBorder
, mpWindowImpl
->mnBottomBorder
);
792 mpOldBorderWin
->Resize();
794 mpWindowImpl
->mpBorderWindow
= mpOldBorderWin
;
795 SetParent( pRealParent
);
796 mpWindowImpl
->mpRealParent
= pRealParent
;
797 mpFloatWin
.disposeAndClear();
798 SetPosPixel( maDockPos
);
800 ToggleFloatingMode();
802 set_border_width(nBorderWidth
);
811 void DockingWindow::SetFloatStyle( WinBits nStyle
)
813 ImplDockingWindowWrapper
*pWrapper
= ImplGetDockingManager()->GetDockingWindowWrapper( this );
816 pWrapper
->SetFloatStyle( nStyle
);
820 mnFloatBits
= nStyle
;
823 WinBits
DockingWindow::GetFloatStyle() const
825 ImplDockingWindowWrapper
*pWrapper
= ImplGetDockingManager()->GetDockingWindowWrapper( this );
828 return pWrapper
->GetFloatStyle();
834 void DockingWindow::setPosSizePixel( long nX
, long nY
,
835 long nWidth
, long nHeight
,
836 PosSizeFlags nFlags
)
838 ImplDockingWindowWrapper
*pWrapper
= ImplGetDockingManager()->GetDockingWindowWrapper( this );
841 if (!pWrapper
->mpFloatWin
)
842 Window::setPosSizePixel( nX
, nY
, nWidth
, nHeight
, nFlags
);
847 Window::setPosSizePixel( nX
, nY
, nWidth
, nHeight
, nFlags
);
850 if (::isLayoutEnabled(this))
852 Size
aSize(GetSizePixel());
854 sal_Int32 nBorderWidth
= get_border_width();
856 aSize
.Width() -= 2 * nBorderWidth
;
857 aSize
.Height() -= 2 * nBorderWidth
;
859 Point
aPos(nBorderWidth
, nBorderWidth
);
860 Window
*pBox
= GetWindow(GetWindowType::FirstChild
);
862 VclContainer::setLayoutAllocation(*pBox
, aPos
, aSize
);
866 Point
DockingWindow::GetPosPixel() const
868 ImplDockingWindowWrapper
*pWrapper
= ImplGetDockingManager()->GetDockingWindowWrapper( this );
871 if ( pWrapper
->mpFloatWin
)
872 return pWrapper
->mpFloatWin
->GetPosPixel();
874 return Window::GetPosPixel();
878 return mpFloatWin
->GetPosPixel();
880 return Window::GetPosPixel();
883 Size
DockingWindow::GetSizePixel() const
885 ImplDockingWindowWrapper
*pWrapper
= ImplGetDockingManager()->GetDockingWindowWrapper( this );
888 if ( pWrapper
->mpFloatWin
)
889 return pWrapper
->mpFloatWin
->GetSizePixel();
891 return Window::GetSizePixel();
895 return mpFloatWin
->GetSizePixel();
897 return Window::GetSizePixel();
900 void DockingWindow::SetOutputSizePixel( const Size
& rNewSize
)
902 ImplDockingWindowWrapper
*pWrapper
= ImplGetDockingManager()->GetDockingWindowWrapper( this );
905 if ( pWrapper
->mpFloatWin
)
906 pWrapper
->mpFloatWin
->SetOutputSizePixel( rNewSize
);
908 Window::SetOutputSizePixel( rNewSize
);
913 mpFloatWin
->SetOutputSizePixel( rNewSize
);
915 Window::SetOutputSizePixel( rNewSize
);
918 Size
DockingWindow::GetOutputSizePixel() const
920 ImplDockingWindowWrapper
*pWrapper
= ImplGetDockingManager()->GetDockingWindowWrapper( this );
923 if ( pWrapper
->mpFloatWin
)
924 return pWrapper
->mpFloatWin
->GetOutputSizePixel();
926 return Window::GetOutputSizePixel();
930 return mpFloatWin
->GetOutputSizePixel();
932 return Window::GetOutputSizePixel();
935 Point
DockingWindow::GetFloatingPos() const
937 ImplDockingWindowWrapper
*pWrapper
= ImplGetDockingManager()->GetDockingWindowWrapper( this );
940 if ( pWrapper
->mpFloatWin
)
942 WindowStateData aData
;
943 aData
.SetMask( WindowStateMask::Pos
);
944 pWrapper
->mpFloatWin
->GetWindowStateData( aData
);
945 Point
aPos( aData
.GetX(), aData
.GetY() );
946 aPos
= pWrapper
->mpFloatWin
->GetParent()->ImplGetFrameWindow()->AbsoluteScreenToOutputPixel( aPos
);
955 WindowStateData aData
;
956 aData
.SetMask( WindowStateMask::Pos
);
957 mpFloatWin
->GetWindowStateData( aData
);
958 Point
aPos( aData
.GetX(), aData
.GetY() );
959 aPos
= mpFloatWin
->GetParent()->ImplGetFrameWindow()->AbsoluteScreenToOutputPixel( aPos
);
966 bool DockingWindow::IsFloatingMode() const
968 ImplDockingWindowWrapper
*pWrapper
= ImplGetDockingManager()->GetDockingWindowWrapper( this );
970 return pWrapper
->IsFloatingMode();
972 return (mpFloatWin
!= nullptr);
975 void DockingWindow::SetMaxOutputSizePixel( const Size
& rSize
)
978 mpFloatWin
->SetMaxOutputSizePixel( rSize
);
979 mpImplData
->maMaxOutSize
= rSize
;
982 void DockingWindow::SetText(const OUString
& rStr
)
984 setDeferredProperties();
985 Window::SetText(rStr
);
988 OUString
DockingWindow::GetText() const
990 const_cast<DockingWindow
*>(this)->setDeferredProperties();
991 return Window::GetText();
994 bool DockingWindow::isLayoutEnabled() const
996 //pre dtor called, and single child is a container => we're layout enabled
997 return mpImplData
&& ::isLayoutEnabled(this);
1000 void DockingWindow::setOptimalLayoutSize()
1002 maLayoutIdle
.Stop();
1004 //resize DockingWindow to fit requisition on initial show
1005 Window
*pBox
= GetWindow(GetWindowType::FirstChild
);
1007 Size aSize
= get_preferred_size();
1009 Size
aMax(bestmaxFrameSizeForScreenSize(GetDesktopRectPixel().GetSize()));
1011 aSize
.Width() = std::min(aMax
.Width(), aSize
.Width());
1012 aSize
.Height() = std::min(aMax
.Height(), aSize
.Height());
1014 SetMinOutputSizePixel(aSize
);
1015 SetSizePixel(aSize
);
1016 setPosSizeOnContainee(aSize
, *pBox
);
1019 void DockingWindow::setPosSizeOnContainee(Size aSize
, Window
&rBox
)
1021 sal_Int32 nBorderWidth
= get_border_width();
1023 aSize
.Width() -= 2 * nBorderWidth
;
1024 aSize
.Height() -= 2 * nBorderWidth
;
1026 Point
aPos(nBorderWidth
, nBorderWidth
);
1027 VclContainer::setLayoutAllocation(rBox
, aPos
, aSize
);
1030 Size
DockingWindow::GetOptimalSize() const
1032 if (!isLayoutEnabled())
1033 return Window::GetOptimalSize();
1035 Size aSize
= VclContainer::getLayoutRequisition(*GetWindow(GetWindowType::FirstChild
));
1037 sal_Int32 nBorderWidth
= get_border_width();
1039 aSize
.Height() += 2 * nBorderWidth
;
1040 aSize
.Width() += 2 * nBorderWidth
;
1042 return Window::CalcWindowSize(aSize
);
1045 void DockingWindow::queue_resize(StateChangedType eReason
)
1047 bool bTriggerLayout
= true;
1048 if (maLayoutIdle
.IsActive() || mbIsCalculatingInitialLayoutSize
)
1050 bTriggerLayout
= false;
1052 if (!isLayoutEnabled())
1054 bTriggerLayout
= false;
1058 InvalidateSizeCache();
1059 maLayoutIdle
.Start();
1061 vcl::Window::queue_resize(eReason
);
1064 IMPL_LINK_NOARG(DockingWindow
, ImplHandleLayoutTimerHdl
, Idle
*, void)
1066 if (!isLayoutEnabled())
1068 SAL_WARN("vcl.layout", "DockingWindow has become non-layout because extra children have been added directly to it.");
1072 Window
*pBox
= GetWindow(GetWindowType::FirstChild
);
1074 setPosSizeOnContainee(GetSizePixel(), *pBox
);
1077 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */