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 .
22 #include <o3tl/float_int_conversion.hxx>
23 #include <sal/log.hxx>
25 #include <tools/helpers.hxx>
27 #include <vcl/toolkit/dialog.hxx>
28 #include <vcl/event.hxx>
29 #include <vcl/toolkit/fixed.hxx>
30 #include <vcl/layout.hxx>
31 #include <vcl/timer.hxx>
32 #include <vcl/window.hxx>
33 #include <vcl/scrollable.hxx>
34 #include <vcl/toolkit/scrbar.hxx>
35 #include <vcl/dockwin.hxx>
36 #include <vcl/settings.hxx>
37 #include <vcl/builder.hxx>
38 #include <o3tl/string_view.hxx>
43 #include <salframe.hxx>
46 #include <com/sun/star/accessibility/AccessibleRelation.hpp>
47 #include <com/sun/star/accessibility/AccessibleRole.hpp>
49 using namespace com::sun::star
;
53 void Window::ShowFocus( const tools::Rectangle
& rRect
)
55 if( mpWindowImpl
->mbInShowFocus
)
57 mpWindowImpl
->mbInShowFocus
= true;
59 ImplWinData
* pWinData
= ImplGetWinData();
61 // native themeing suggest not to use focus rects
62 if( ! ( mpWindowImpl
->mbUseNativeFocus
&&
63 IsNativeWidgetEnabled() ) )
65 if ( !mpWindowImpl
->mbInPaint
)
67 if ( mpWindowImpl
->mbFocusVisible
)
69 if ( *pWinData
->mpFocusRect
== rRect
)
71 mpWindowImpl
->mbInShowFocus
= false;
75 ImplInvertFocus( *pWinData
->mpFocusRect
);
78 ImplInvertFocus( rRect
);
80 pWinData
->mpFocusRect
= rRect
;
81 mpWindowImpl
->mbFocusVisible
= true;
85 if( ! mpWindowImpl
->mbNativeFocusVisible
)
87 mpWindowImpl
->mbNativeFocusVisible
= true;
88 if ( !mpWindowImpl
->mbInPaint
)
92 mpWindowImpl
->mbInShowFocus
= false;
95 void Window::HideFocus()
98 if( mpWindowImpl
->mbInHideFocus
)
100 mpWindowImpl
->mbInHideFocus
= true;
102 // native themeing can suggest not to use focus rects
103 if( ! ( mpWindowImpl
->mbUseNativeFocus
&&
104 IsNativeWidgetEnabled() ) )
106 if ( !mpWindowImpl
->mbFocusVisible
)
108 mpWindowImpl
->mbInHideFocus
= false;
112 if ( !mpWindowImpl
->mbInPaint
)
113 ImplInvertFocus( *ImplGetWinData()->mpFocusRect
);
114 mpWindowImpl
->mbFocusVisible
= false;
118 if( mpWindowImpl
->mbNativeFocusVisible
)
120 mpWindowImpl
->mbNativeFocusVisible
= false;
121 if ( !mpWindowImpl
->mbInPaint
)
125 mpWindowImpl
->mbInHideFocus
= false;
128 void Window::ShowTracking( const tools::Rectangle
& rRect
, ShowTrackFlags nFlags
)
130 ImplWinData
* pWinData
= ImplGetWinData();
132 if ( !mpWindowImpl
->mbInPaint
|| !(nFlags
& ShowTrackFlags::TrackWindow
) )
134 if ( mpWindowImpl
->mbTrackVisible
)
136 if ( (*pWinData
->mpTrackRect
== rRect
) &&
137 (pWinData
->mnTrackFlags
== nFlags
) )
140 InvertTracking( *pWinData
->mpTrackRect
, pWinData
->mnTrackFlags
);
143 InvertTracking( rRect
, nFlags
);
146 pWinData
->mpTrackRect
= rRect
;
147 pWinData
->mnTrackFlags
= nFlags
;
148 mpWindowImpl
->mbTrackVisible
= true;
151 void Window::HideTracking()
153 if ( mpWindowImpl
->mbTrackVisible
)
155 ImplWinData
* pWinData
= ImplGetWinData();
156 if ( !mpWindowImpl
->mbInPaint
|| !(pWinData
->mnTrackFlags
& ShowTrackFlags::TrackWindow
) )
157 InvertTracking( *pWinData
->mpTrackRect
, pWinData
->mnTrackFlags
);
158 mpWindowImpl
->mbTrackVisible
= false;
162 void Window::InvertTracking( const tools::Rectangle
& rRect
, ShowTrackFlags nFlags
)
164 OutputDevice
*pOutDev
= GetOutDev();
165 tools::Rectangle
aRect( pOutDev
->ImplLogicToDevicePixel( rRect
) );
167 if ( aRect
.IsEmpty() )
171 SalGraphics
* pGraphics
;
173 if ( nFlags
& ShowTrackFlags::TrackWindow
)
175 if ( !GetOutDev()->IsDeviceOutputNecessary() )
178 // we need a graphics
179 if ( !GetOutDev()->mpGraphics
)
181 if ( !pOutDev
->AcquireGraphics() )
185 if ( GetOutDev()->mbInitClipRegion
)
186 GetOutDev()->InitClipRegion();
188 if ( GetOutDev()->mbOutputClipped
)
191 pGraphics
= GetOutDev()->mpGraphics
;
195 pGraphics
= ImplGetFrameGraphics();
197 if ( nFlags
& ShowTrackFlags::Clip
)
199 vcl::Region
aRegion( GetOutputRectPixel() );
200 ImplClipBoundaries( aRegion
, false, false );
201 pOutDev
->SelectClipRegion( aRegion
, pGraphics
);
205 ShowTrackFlags nStyle
= nFlags
& ShowTrackFlags::StyleMask
;
206 if ( nStyle
== ShowTrackFlags::Object
)
207 pGraphics
->Invert( aRect
.Left(), aRect
.Top(), aRect
.GetWidth(), aRect
.GetHeight(), SalInvert::TrackFrame
, *GetOutDev() );
208 else if ( nStyle
== ShowTrackFlags::Split
)
209 pGraphics
->Invert( aRect
.Left(), aRect
.Top(), aRect
.GetWidth(), aRect
.GetHeight(), SalInvert::N50
, *GetOutDev() );
212 tools::Long nBorder
= 1;
213 if ( nStyle
== ShowTrackFlags::Big
)
215 pGraphics
->Invert( aRect
.Left(), aRect
.Top(), aRect
.GetWidth(), nBorder
, SalInvert::N50
, *GetOutDev() );
216 pGraphics
->Invert( aRect
.Left(), aRect
.Bottom()-nBorder
+1, aRect
.GetWidth(), nBorder
, SalInvert::N50
, *GetOutDev() );
217 pGraphics
->Invert( aRect
.Left(), aRect
.Top()+nBorder
, nBorder
, aRect
.GetHeight()-(nBorder
*2), SalInvert::N50
, *GetOutDev() );
218 pGraphics
->Invert( aRect
.Right()-nBorder
+1, aRect
.Top()+nBorder
, nBorder
, aRect
.GetHeight()-(nBorder
*2), SalInvert::N50
, *GetOutDev() );
222 IMPL_LINK( Window
, ImplTrackTimerHdl
, Timer
*, pTimer
, void )
226 SAL_WARN("vcl", "ImplTrackTimerHdl has outlived dispose");
230 ImplSVData
* pSVData
= ImplGetSVData();
232 // if Button-Repeat we have to change the timeout
233 if ( pSVData
->mpWinData
->mnTrackFlags
& StartTrackingFlags::ButtonRepeat
)
234 pTimer
->SetTimeout( GetSettings().GetMouseSettings().GetButtonRepeat() );
236 // create Tracking-Event
237 Point
aMousePos( mpWindowImpl
->mpFrameData
->mnLastMouseX
, mpWindowImpl
->mpFrameData
->mnLastMouseY
);
238 if( GetOutDev()->ImplIsAntiparallel() )
240 // re-mirror frame pos at pChild
241 const OutputDevice
*pOutDev
= GetOutDev();
242 pOutDev
->ReMirror( aMousePos
);
244 MouseEvent
aMEvt( ScreenToOutputPixel( aMousePos
),
245 mpWindowImpl
->mpFrameData
->mnClickCount
, MouseEventModifiers::NONE
,
246 mpWindowImpl
->mpFrameData
->mnMouseCode
,
247 mpWindowImpl
->mpFrameData
->mnMouseCode
);
248 TrackingEvent
aTEvt( aMEvt
, TrackingEventFlags::Repeat
);
252 void Window::SetUseFrameData(bool bUseFrameData
)
255 mpWindowImpl
->mbUseFrameData
= bUseFrameData
;
258 void Window::StartTracking( StartTrackingFlags nFlags
)
263 ImplSVData
* pSVData
= ImplGetSVData();
264 VclPtr
<vcl::Window
> pTrackWin
= mpWindowImpl
->mbUseFrameData
?
265 mpWindowImpl
->mpFrameData
->mpTrackWin
:
266 pSVData
->mpWinData
->mpTrackWin
;
268 if ( pTrackWin
.get() != this )
271 pTrackWin
->EndTracking( TrackingEventFlags::Cancel
);
274 SAL_WARN_IF(pSVData
->mpWinData
->mpTrackTimer
, "vcl", "StartTracking called while TrackerTimer still running");
276 if ( !mpWindowImpl
->mbUseFrameData
&&
277 (nFlags
& (StartTrackingFlags::ScrollRepeat
| StartTrackingFlags::ButtonRepeat
)) )
279 pSVData
->mpWinData
->mpTrackTimer
.reset(new AutoTimer("vcl::Window pSVData->mpWinData->mpTrackTimer"));
281 if ( nFlags
& StartTrackingFlags::ScrollRepeat
)
282 pSVData
->mpWinData
->mpTrackTimer
->SetTimeout( MouseSettings::GetScrollRepeat() );
284 pSVData
->mpWinData
->mpTrackTimer
->SetTimeout( MouseSettings::GetButtonStartRepeat() );
285 pSVData
->mpWinData
->mpTrackTimer
->SetInvokeHandler( LINK( this, Window
, ImplTrackTimerHdl
) );
286 pSVData
->mpWinData
->mpTrackTimer
->Start();
289 if (mpWindowImpl
->mbUseFrameData
)
291 mpWindowImpl
->mpFrameData
->mpTrackWin
= this;
295 pSVData
->mpWinData
->mpTrackWin
= this;
296 pSVData
->mpWinData
->mnTrackFlags
= nFlags
;
301 void Window::EndTracking( TrackingEventFlags nFlags
)
306 ImplSVData
* pSVData
= ImplGetSVData();
307 VclPtr
<vcl::Window
> pTrackWin
= mpWindowImpl
->mbUseFrameData
?
308 mpWindowImpl
->mpFrameData
->mpTrackWin
:
309 pSVData
->mpWinData
->mpTrackWin
;
311 if ( pTrackWin
.get() != this )
314 if ( !mpWindowImpl
->mbUseFrameData
&& pSVData
->mpWinData
->mpTrackTimer
)
315 pSVData
->mpWinData
->mpTrackTimer
.reset();
317 mpWindowImpl
->mpFrameData
->mpTrackWin
= pSVData
->mpWinData
->mpTrackWin
= nullptr;
318 pSVData
->mpWinData
->mnTrackFlags
= StartTrackingFlags::NONE
;
321 // call EndTracking if required
322 if (mpWindowImpl
->mpFrameData
)
324 Point
aMousePos( mpWindowImpl
->mpFrameData
->mnLastMouseX
, mpWindowImpl
->mpFrameData
->mnLastMouseY
);
325 if( GetOutDev()->ImplIsAntiparallel() )
327 // re-mirror frame pos at pChild
328 const OutputDevice
*pOutDev
= GetOutDev();
329 pOutDev
->ReMirror( aMousePos
);
332 MouseEvent
aMEvt( ScreenToOutputPixel( aMousePos
),
333 mpWindowImpl
->mpFrameData
->mnClickCount
, MouseEventModifiers::NONE
,
334 mpWindowImpl
->mpFrameData
->mnMouseCode
,
335 mpWindowImpl
->mpFrameData
->mnMouseCode
);
336 TrackingEvent
aTEvt( aMEvt
, nFlags
| TrackingEventFlags::End
);
337 // CompatTracking effectively
338 if (!mpWindowImpl
|| mpWindowImpl
->mbInDispose
)
339 return Window::Tracking( aTEvt
);
341 return Tracking( aTEvt
);
345 bool Window::IsTracking() const
349 if (mpWindowImpl
->mbUseFrameData
&& mpWindowImpl
->mpFrameData
)
351 return mpWindowImpl
->mpFrameData
->mpTrackWin
== this;
353 if (!mpWindowImpl
->mbUseFrameData
&& ImplGetSVData()->mpWinData
)
355 return ImplGetSVData()->mpWinData
->mpTrackWin
== this;
360 void Window::StartAutoScroll( StartAutoScrollFlags nFlags
)
362 ImplSVData
* pSVData
= ImplGetSVData();
364 if ( pSVData
->mpWinData
->mpAutoScrollWin
.get() != this )
366 if ( pSVData
->mpWinData
->mpAutoScrollWin
)
367 pSVData
->mpWinData
->mpAutoScrollWin
->EndAutoScroll();
370 pSVData
->mpWinData
->mpAutoScrollWin
= this;
371 pSVData
->mpWinData
->mnAutoScrollFlags
= nFlags
;
372 pSVData
->maAppData
.mpWheelWindow
= VclPtr
<ImplWheelWindow
>::Create( this );
375 void Window::EndAutoScroll()
377 ImplSVData
* pSVData
= ImplGetSVData();
379 if ( pSVData
->mpWinData
->mpAutoScrollWin
.get() == this )
381 pSVData
->mpWinData
->mpAutoScrollWin
= nullptr;
382 pSVData
->mpWinData
->mnAutoScrollFlags
= StartAutoScrollFlags::NONE
;
383 pSVData
->maAppData
.mpWheelWindow
->ImplStop();
384 pSVData
->maAppData
.mpWheelWindow
.disposeAndClear();
388 VclPtr
<vcl::Window
> Window::SaveFocus()
390 ImplSVData
* pSVData
= ImplGetSVData();
391 if ( pSVData
->mpWinData
->mpFocusWin
)
393 return pSVData
->mpWinData
->mpFocusWin
;
399 void Window::EndSaveFocus(const VclPtr
<vcl::Window
>& xFocusWin
)
401 if (xFocusWin
&& !xFocusWin
->isDisposed())
403 xFocusWin
->GrabFocus();
407 void Window::SetZoom( const Fraction
& rZoom
)
409 if ( mpWindowImpl
&& mpWindowImpl
->maZoom
!= rZoom
)
411 mpWindowImpl
->maZoom
= rZoom
;
412 CompatStateChanged( StateChangedType::Zoom
);
416 void Window::SetZoomedPointFont(vcl::RenderContext
& rRenderContext
, const vcl::Font
& rFont
)
418 const Fraction
& rZoom
= GetZoom();
419 if (rZoom
.GetNumerator() != rZoom
.GetDenominator())
421 vcl::Font
aFont(rFont
);
422 Size aSize
= aFont
.GetFontSize();
423 aSize
.setWidth(basegfx::fround
<tools::Long
>(double(aSize
.Width() * rZoom
)));
424 aSize
.setHeight(basegfx::fround
<tools::Long
>(double(aSize
.Height() * rZoom
)));
425 aFont
.SetFontSize(aSize
);
426 SetPointFont(rRenderContext
, aFont
);
430 SetPointFont(rRenderContext
, rFont
);
434 tools::Long
Window::CalcZoom( tools::Long nCalc
) const
437 const Fraction
& rZoom
= GetZoom();
438 if ( rZoom
.GetNumerator() != rZoom
.GetDenominator() )
440 double n
= double(nCalc
* rZoom
);
441 nCalc
= basegfx::fround
<tools::Long
>(n
);
446 void Window::SetControlFont()
448 if (mpWindowImpl
&& mpWindowImpl
->mpControlFont
)
450 mpWindowImpl
->mpControlFont
.reset();
451 CompatStateChanged(StateChangedType::ControlFont
);
455 void Window::SetControlFont(const vcl::Font
& rFont
)
457 if (rFont
== vcl::Font())
463 if (mpWindowImpl
->mpControlFont
)
465 if (*mpWindowImpl
->mpControlFont
== rFont
)
467 *mpWindowImpl
->mpControlFont
= rFont
;
470 mpWindowImpl
->mpControlFont
= rFont
;
472 CompatStateChanged(StateChangedType::ControlFont
);
475 vcl::Font
Window::GetControlFont() const
477 if (mpWindowImpl
->mpControlFont
)
478 return *mpWindowImpl
->mpControlFont
;
486 void Window::ApplyControlFont(vcl::RenderContext
& rRenderContext
, const vcl::Font
& rFont
)
488 vcl::Font
aFont(rFont
);
490 aFont
.Merge(GetControlFont());
491 SetZoomedPointFont(rRenderContext
, aFont
);
494 void Window::SetControlForeground()
496 if (mpWindowImpl
->mbControlForeground
)
498 mpWindowImpl
->maControlForeground
= COL_TRANSPARENT
;
499 mpWindowImpl
->mbControlForeground
= false;
500 CompatStateChanged(StateChangedType::ControlForeground
);
504 void Window::SetControlForeground(const Color
& rColor
)
506 if (rColor
.IsTransparent())
508 if (mpWindowImpl
->mbControlForeground
)
510 mpWindowImpl
->maControlForeground
= COL_TRANSPARENT
;
511 mpWindowImpl
->mbControlForeground
= false;
512 CompatStateChanged(StateChangedType::ControlForeground
);
517 if (mpWindowImpl
->maControlForeground
!= rColor
)
519 mpWindowImpl
->maControlForeground
= rColor
;
520 mpWindowImpl
->mbControlForeground
= true;
521 CompatStateChanged(StateChangedType::ControlForeground
);
526 void Window::ApplyControlForeground(vcl::RenderContext
& rRenderContext
, const Color
& rDefaultColor
)
528 Color
aTextColor(rDefaultColor
);
529 if (IsControlForeground())
530 aTextColor
= GetControlForeground();
531 rRenderContext
.SetTextColor(aTextColor
);
534 void Window::SetControlBackground()
536 if (mpWindowImpl
->mbControlBackground
)
538 mpWindowImpl
->maControlBackground
= COL_TRANSPARENT
;
539 mpWindowImpl
->mbControlBackground
= false;
540 CompatStateChanged(StateChangedType::ControlBackground
);
544 void Window::SetControlBackground(const Color
& rColor
)
546 if (rColor
.IsTransparent())
548 if (mpWindowImpl
->mbControlBackground
)
550 mpWindowImpl
->maControlBackground
= COL_TRANSPARENT
;
551 mpWindowImpl
->mbControlBackground
= false;
552 CompatStateChanged(StateChangedType::ControlBackground
);
557 if (mpWindowImpl
->maControlBackground
!= rColor
)
559 mpWindowImpl
->maControlBackground
= rColor
;
560 mpWindowImpl
->mbControlBackground
= true;
561 CompatStateChanged(StateChangedType::ControlBackground
);
566 void Window::ApplyControlBackground(vcl::RenderContext
& rRenderContext
, const Color
& rDefaultColor
)
568 Color
aColor(rDefaultColor
);
569 if (IsControlBackground())
570 aColor
= GetControlBackground();
571 rRenderContext
.SetBackground(aColor
);
574 Size
Window::CalcWindowSize( const Size
& rOutSz
) const
577 aSz
.AdjustWidth(mpWindowImpl
->mnLeftBorder
+mpWindowImpl
->mnRightBorder
);
578 aSz
.AdjustHeight(mpWindowImpl
->mnTopBorder
+mpWindowImpl
->mnBottomBorder
);
582 Size
Window::CalcOutputSize( const Size
& rWinSz
) const
585 aSz
.AdjustWidth( -(mpWindowImpl
->mnLeftBorder
+mpWindowImpl
->mnRightBorder
) );
586 aSz
.AdjustHeight( -(mpWindowImpl
->mnTopBorder
+mpWindowImpl
->mnBottomBorder
) );
590 vcl::Font
Window::GetDrawPixelFont(OutputDevice
const * pDev
) const
592 vcl::Font aFont
= GetPointFont(*GetOutDev());
593 Size aFontSize
= aFont
.GetFontSize();
594 MapMode
aPtMapMode(MapUnit::MapPoint
);
595 aFontSize
= pDev
->LogicToPixel( aFontSize
, aPtMapMode
);
596 aFont
.SetFontSize( aFontSize
);
600 tools::Long
Window::GetDrawPixel( OutputDevice
const * pDev
, tools::Long nPixels
) const
602 tools::Long nP
= nPixels
;
603 if ( pDev
->GetOutDevType() != OUTDEV_WINDOW
)
605 MapMode
aMap( MapUnit::Map100thMM
);
607 aSz
= PixelToLogic( aSz
, aMap
);
608 aSz
= pDev
->LogicToPixel( aSz
, aMap
);
614 // returns how much was actually scrolled (so that abs(retval) <= abs(nN))
615 static double lcl_HandleScrollHelper( Scrollable
* pScrl
, double nN
, bool isMultiplyByLineSize
)
617 if (!pScrl
|| !nN
|| pScrl
->Inactive())
620 tools::Long nNewPos
= pScrl
->GetThumbPos();
621 double scrolled
= nN
;
623 if ( nN
== double(-LONG_MAX
) )
624 nNewPos
+= pScrl
->GetPageSize();
625 else if ( nN
== double(LONG_MAX
) )
626 nNewPos
-= pScrl
->GetPageSize();
629 // allowing both chunked and continuous scrolling
630 if(isMultiplyByLineSize
){
631 nN
*=pScrl
->GetLineSize();
634 // compute how many quantized units to scroll
635 tools::Long magnitude
= o3tl::saturating_cast
<tools::Long
>(fabs(nN
));
636 tools::Long change
= copysign(magnitude
, nN
);
638 nNewPos
= nNewPos
- change
;
640 scrolled
= double(change
);
641 // convert back to chunked/continuous
642 if(isMultiplyByLineSize
){
643 scrolled
/= pScrl
->GetLineSize();
647 pScrl
->DoScroll( nNewPos
);
652 bool Window::HandleScrollCommand( const CommandEvent
& rCmd
,
653 Scrollable
* pHScrl
, Scrollable
* pVScrl
)
657 if ( pHScrl
|| pVScrl
)
659 switch( rCmd
.GetCommand() )
661 case CommandEventId::StartAutoScroll
:
663 StartAutoScrollFlags nFlags
= StartAutoScrollFlags::NONE
;
666 if ( (pHScrl
->GetVisibleSize() < pHScrl
->GetRangeMax()) &&
667 !pHScrl
->Inactive() )
668 nFlags
|= StartAutoScrollFlags::Horz
;
672 if ( (pVScrl
->GetVisibleSize() < pVScrl
->GetRangeMax()) &&
673 !pVScrl
->Inactive() )
674 nFlags
|= StartAutoScrollFlags::Vert
;
677 if ( nFlags
!= StartAutoScrollFlags::NONE
)
679 StartAutoScroll( nFlags
);
685 case CommandEventId::Wheel
:
687 const CommandWheelData
* pData
= rCmd
.GetWheelData();
689 if ( pData
&& (CommandWheelMode::SCROLL
== pData
->GetMode()) )
691 if (!pData
->IsDeltaPixel())
693 double nScrollLines
= pData
->GetScrollLines();
695 double* partialScroll
= pData
->IsHorz()
696 ? &mpWindowImpl
->mfPartialScrollX
697 : &mpWindowImpl
->mfPartialScrollY
;
698 if ( nScrollLines
== COMMAND_WHEEL_PAGESCROLL
)
700 if ( pData
->GetDelta() < 0 )
701 nLines
= double(-LONG_MAX
);
703 nLines
= double(LONG_MAX
);
706 nLines
= *partialScroll
+ pData
->GetNotchDelta() * nScrollLines
;
709 Scrollable
* pScrl
= pData
->IsHorz() ? pHScrl
: pVScrl
;
710 double scrolled
= lcl_HandleScrollHelper( pScrl
, nLines
, true );
711 *partialScroll
= nLines
- scrolled
;
717 // Mobile / touch scrolling section
718 const Point
& deltaPoint
= rCmd
.GetMousePosPixel();
720 double deltaXInPixels
= double(deltaPoint
.X());
721 double deltaYInPixels
= double(deltaPoint
.Y());
722 Size winSize
= GetOutputSizePixel();
726 double visSizeX
= double(pHScrl
->GetVisibleSize());
727 double ratioX
= deltaXInPixels
/ double(winSize
.getWidth());
728 tools::Long deltaXInLogic
= tools::Long(visSizeX
* ratioX
);
729 // Touch need to work by pixels. Did not apply this to
730 // Android, as android code may require adaptations
731 // to work with this scrolling code
733 tools::Long lineSizeX
= pHScrl
->GetLineSize();
737 deltaXInLogic
/= lineSizeX
;
747 bool const isMultiplyByLineSize
= true;
749 bool const isMultiplyByLineSize
= false;
751 lcl_HandleScrollHelper( pHScrl
, deltaXInLogic
, isMultiplyByLineSize
);
757 double visSizeY
= double(pVScrl
->GetVisibleSize());
758 double ratioY
= deltaYInPixels
/ double(winSize
.getHeight());
759 tools::Long deltaYInLogic
= tools::Long(visSizeY
* ratioY
);
761 // Touch need to work by pixels. Did not apply this to
762 // Android, as android code may require adaptations
763 // to work with this scrolling code
765 tools::Long lineSizeY
= pVScrl
->GetLineSize();
768 deltaYInLogic
/= lineSizeY
;
778 bool const isMultiplyByLineSize
= true;
780 bool const isMultiplyByLineSize
= false;
782 lcl_HandleScrollHelper( pVScrl
, deltaYInLogic
, isMultiplyByLineSize
);
792 case CommandEventId::GesturePan
:
794 const CommandGesturePanData
* pData
= rCmd
.GetGesturePanData();
797 if (pData
->meEventType
== GestureEventPanType::Begin
)
800 mpWindowImpl
->mpFrameData
->mnTouchPanPositionX
= pHScrl
->GetThumbPos();
802 mpWindowImpl
->mpFrameData
->mnTouchPanPositionY
= pVScrl
->GetThumbPos();
804 else if (pData
->meEventType
== GestureEventPanType::Update
)
806 bool bHorz
= pData
->meOrientation
== PanningOrientation::Horizontal
;
807 Scrollable
* pScrl
= bHorz
? pHScrl
: pVScrl
;
810 Point
aGesturePt(pData
->mfX
, pData
->mfY
);
811 tools::Rectangle
aWinRect(this->GetOutputRectPixel());
812 bool bContains
= aWinRect
.Contains(aGesturePt
);
816 tools::Long nOriginalPos
;
819 nWinSize
= GetOutputSizePixel().getWidth();
820 nOriginalPos
= mpWindowImpl
->mpFrameData
->mnTouchPanPositionX
;
824 nWinSize
= GetOutputSizePixel().getHeight();
825 nOriginalPos
= mpWindowImpl
->mpFrameData
->mnTouchPanPositionY
;
827 double nOffset
= pData
->mfOffset
;
828 double nRatio
= nOffset
/ nWinSize
;
829 tools::Long nVisibleSize
= pScrl
->GetVisibleSize();
830 tools::Long nDeltaInLogic
= tools::Long(nVisibleSize
* nRatio
);
831 tools::Long nNewPos
= nOriginalPos
- nDeltaInLogic
;
833 pScrl
->DoScroll(nNewPos
);
837 else if (pData
->meEventType
== GestureEventPanType::End
)
839 mpWindowImpl
->mpFrameData
->mnTouchPanPositionX
= -1;
840 mpWindowImpl
->mpFrameData
->mnTouchPanPositionY
= -1;
847 case CommandEventId::AutoScroll
:
849 const CommandScrollData
* pData
= rCmd
.GetAutoScrollData();
850 if ( pData
&& (pData
->GetDeltaX() || pData
->GetDeltaY()) )
852 ImplHandleScroll( pHScrl
, pData
->GetDeltaX(),
853 pVScrl
, pData
->GetDeltaY() );
867 void Window::ImplHandleScroll( Scrollable
* pHScrl
, double nX
,
868 Scrollable
* pVScrl
, double nY
)
870 lcl_HandleScrollHelper( pHScrl
, nX
, true );
871 lcl_HandleScrollHelper( pVScrl
, nY
, true );
874 DockingManager
* Window::GetDockingManager()
876 return ImplGetDockingManager();
879 void Window::EnableDocking( bool bEnable
)
881 // update list of dockable windows
883 ImplGetDockingManager()->AddWindow( this );
885 ImplGetDockingManager()->RemoveWindow( this );
888 // retrieves the list of owner draw decorated windows for this window hierarchy
889 ::std::vector
<VclPtr
<vcl::Window
> >& Window::ImplGetOwnerDrawList()
891 return ImplGetTopmostFrameWindow()->mpWindowImpl
->mpFrameData
->maOwnerDrawList
;
894 void Window::SetHelpId( const OUString
& rHelpId
)
896 mpWindowImpl
->maHelpId
= rHelpId
;
899 const OUString
& Window::GetHelpId() const
901 return mpWindowImpl
->maHelpId
;
904 // --------- old inline methods ---------------
906 vcl::Window
* Window::ImplGetWindow() const
908 if ( mpWindowImpl
->mpClientWindow
)
909 return mpWindowImpl
->mpClientWindow
;
911 return const_cast<vcl::Window
*>(this);
914 ImplFrameData
* Window::ImplGetFrameData()
916 return mpWindowImpl
? mpWindowImpl
->mpFrameData
: nullptr;
919 SalFrame
* Window::ImplGetFrame() const
921 return mpWindowImpl
? mpWindowImpl
->mpFrame
: nullptr;
924 weld::Window
* Window::GetFrameWeld() const
926 SalFrame
* pFrame
= ImplGetFrame();
927 return pFrame
? pFrame
->GetFrameWeld() : nullptr;
930 vcl::Window
* Window::GetFrameWindow() const
932 SalFrame
* pFrame
= ImplGetFrame();
933 return pFrame
? pFrame
->GetWindow() : nullptr;
936 vcl::Window
* Window::ImplGetParent() const
938 return mpWindowImpl
? mpWindowImpl
->mpParent
.get() : nullptr;
941 vcl::Window
* Window::ImplGetClientWindow() const
943 return mpWindowImpl
? mpWindowImpl
->mpClientWindow
.get() : nullptr;
946 vcl::Window
* Window::ImplGetBorderWindow() const
948 return mpWindowImpl
? mpWindowImpl
->mpBorderWindow
.get() : nullptr;
951 vcl::Window
* Window::ImplGetFirstOverlapWindow()
958 if ( mpWindowImpl
->mbOverlapWin
)
961 return mpWindowImpl
->mpOverlapWindow
;
964 const vcl::Window
* Window::ImplGetFirstOverlapWindow() const
971 if ( mpWindowImpl
->mbOverlapWin
)
974 return mpWindowImpl
->mpOverlapWindow
;
977 vcl::Window
* Window::ImplGetFrameWindow() const
979 return mpWindowImpl
? mpWindowImpl
->mpFrameWindow
.get() : nullptr;
982 bool Window::IsDockingWindow() const
984 return mpWindowImpl
&& mpWindowImpl
->mbDockWin
;
987 bool Window::ImplIsFloatingWindow() const
989 return mpWindowImpl
&& mpWindowImpl
->mbFloatWin
;
992 bool Window::ImplIsSplitter() const
994 return mpWindowImpl
&& mpWindowImpl
->mbSplitter
;
997 bool Window::ImplIsPushButton() const
999 return mpWindowImpl
&& mpWindowImpl
->mbPushButton
;
1002 bool Window::ImplIsOverlapWindow() const
1004 return mpWindowImpl
&& mpWindowImpl
->mbOverlapWin
;
1007 void Window::ImplSetMouseTransparent( bool bTransparent
)
1010 mpWindowImpl
->mbMouseTransparent
= bTransparent
;
1013 void Window::SetCompoundControl( bool bCompound
)
1016 mpWindowImpl
->mbCompoundControl
= bCompound
;
1019 WinBits
Window::GetStyle() const
1021 return mpWindowImpl
? mpWindowImpl
->mnStyle
: 0;
1024 WinBits
Window::GetPrevStyle() const
1026 return mpWindowImpl
? mpWindowImpl
->mnPrevStyle
: 0;
1029 WindowExtendedStyle
Window::GetExtendedStyle() const
1031 return mpWindowImpl
? mpWindowImpl
->mnExtendedStyle
: WindowExtendedStyle::NONE
;
1034 void Window::SetType( WindowType nType
)
1037 mpWindowImpl
->mnType
= nType
;
1040 WindowType
Window::GetType() const
1043 return mpWindowImpl
->mnType
;
1045 return WindowType::NONE
;
1048 Dialog
* Window::GetParentDialog() const
1050 const vcl::Window
*pWindow
= this;
1054 if( pWindow
->IsDialog() )
1057 pWindow
= pWindow
->GetParent();
1060 return const_cast<Dialog
*>(dynamic_cast<const Dialog
*>(pWindow
));
1063 bool Window::IsSystemWindow() const
1065 return mpWindowImpl
&& mpWindowImpl
->mbSysWin
;
1068 bool Window::IsDialog() const
1070 return mpWindowImpl
&& mpWindowImpl
->mbDialog
;
1073 bool Window::IsMenuFloatingWindow() const
1075 return mpWindowImpl
&& mpWindowImpl
->mbMenuFloatingWindow
;
1078 bool Window::IsToolbarFloatingWindow() const
1080 return mpWindowImpl
&& mpWindowImpl
->mbToolbarFloatingWindow
;
1083 bool Window::IsNativeFrame() const
1085 if( mpWindowImpl
->mbFrame
)
1086 // #101741 do not check for WB_CLOSEABLE because undecorated floaters (like menus!) are closeable
1087 if( mpWindowImpl
->mnStyle
& (WB_MOVEABLE
| WB_SIZEABLE
) )
1095 void Window::EnableAllResize()
1097 mpWindowImpl
->mbAllResize
= true;
1100 void Window::EnableChildTransparentMode( bool bEnable
)
1102 mpWindowImpl
->mbChildTransparent
= bEnable
;
1105 bool Window::IsChildTransparentModeEnabled() const
1107 return mpWindowImpl
&& mpWindowImpl
->mbChildTransparent
;
1110 bool Window::IsMouseTransparent() const
1112 return mpWindowImpl
&& mpWindowImpl
->mbMouseTransparent
;
1115 bool Window::IsPaintTransparent() const
1117 return mpWindowImpl
&& mpWindowImpl
->mbPaintTransparent
;
1120 void Window::SetDialogControlStart( bool bStart
)
1122 mpWindowImpl
->mbDlgCtrlStart
= bStart
;
1125 bool Window::IsDialogControlStart() const
1127 return mpWindowImpl
&& mpWindowImpl
->mbDlgCtrlStart
;
1130 void Window::SetDialogControlFlags( DialogControlFlags nFlags
)
1132 mpWindowImpl
->mnDlgCtrlFlags
= nFlags
;
1135 DialogControlFlags
Window::GetDialogControlFlags() const
1137 return mpWindowImpl
->mnDlgCtrlFlags
;
1140 const InputContext
& Window::GetInputContext() const
1142 return mpWindowImpl
->maInputContext
;
1145 bool Window::IsControlFont() const
1147 return bool(mpWindowImpl
->mpControlFont
);
1150 const Color
& Window::GetControlForeground() const
1152 return mpWindowImpl
->maControlForeground
;
1155 bool Window::IsControlForeground() const
1157 return mpWindowImpl
->mbControlForeground
;
1160 const Color
& Window::GetControlBackground() const
1162 return mpWindowImpl
->maControlBackground
;
1165 bool Window::IsControlBackground() const
1167 return mpWindowImpl
->mbControlBackground
;
1170 bool Window::IsInPaint() const
1172 return mpWindowImpl
&& mpWindowImpl
->mbInPaint
;
1175 vcl::Window
* Window::GetParent() const
1177 return mpWindowImpl
? mpWindowImpl
->mpRealParent
.get() : nullptr;
1180 bool Window::IsVisible() const
1182 return mpWindowImpl
&& mpWindowImpl
->mbVisible
;
1185 bool Window::IsReallyVisible() const
1187 return mpWindowImpl
&& mpWindowImpl
->mbReallyVisible
;
1190 bool Window::IsReallyShown() const
1192 return mpWindowImpl
&& mpWindowImpl
->mbReallyShown
;
1195 bool Window::IsInInitShow() const
1197 return mpWindowImpl
->mbInInitShow
;
1200 bool Window::IsEnabled() const
1202 return mpWindowImpl
&& !mpWindowImpl
->mbDisabled
;
1205 bool Window::IsInputEnabled() const
1207 return mpWindowImpl
&& !mpWindowImpl
->mbInputDisabled
;
1210 bool Window::IsAlwaysEnableInput() const
1212 return mpWindowImpl
->meAlwaysInputMode
== AlwaysInputEnabled
;
1215 ActivateModeFlags
Window::GetActivateMode() const
1217 return mpWindowImpl
->mnActivateMode
;
1221 bool Window::IsAlwaysOnTopEnabled() const
1223 return mpWindowImpl
->mbAlwaysOnTop
;
1226 bool Window::IsDefaultPos() const
1228 return mpWindowImpl
->mbDefPos
;
1231 bool Window::IsDefaultSize() const
1233 return mpWindowImpl
->mbDefSize
;
1236 Point
Window::GetOffsetPixelFrom(const vcl::Window
& rWindow
) const
1238 return Point(GetOutOffXPixel() - rWindow
.GetOutOffXPixel(), GetOutOffYPixel() - rWindow
.GetOutOffYPixel());
1241 void Window::EnablePaint( bool bEnable
)
1243 mpWindowImpl
->mbPaintDisabled
= !bEnable
;
1246 bool Window::IsPaintEnabled() const
1248 return !mpWindowImpl
->mbPaintDisabled
;
1251 bool Window::IsUpdateMode() const
1253 return !mpWindowImpl
->mbNoUpdate
;
1256 void Window::SetParentUpdateMode( bool bUpdate
)
1258 mpWindowImpl
->mbNoParentUpdate
= !bUpdate
;
1261 bool Window::IsActive() const
1263 return mpWindowImpl
->mbActive
;
1266 GetFocusFlags
Window::GetGetFocusFlags() const
1268 return mpWindowImpl
->mnGetFocusFlags
;
1271 bool Window::IsCompoundControl() const
1273 return mpWindowImpl
&& mpWindowImpl
->mbCompoundControl
;
1276 bool Window::IsWait() const
1278 return (mpWindowImpl
->mnWaitCount
!= 0);
1281 vcl::Cursor
* Window::GetCursor() const
1285 return mpWindowImpl
->mpCursor
;
1288 const Fraction
& Window::GetZoom() const
1290 return mpWindowImpl
->maZoom
;
1293 bool Window::IsZoom() const
1295 return mpWindowImpl
->maZoom
.GetNumerator() != mpWindowImpl
->maZoom
.GetDenominator();
1298 void Window::SetHelpText( const OUString
& rHelpText
)
1300 mpWindowImpl
->maHelpText
= rHelpText
;
1301 mpWindowImpl
->mbHelpTextDynamic
= true;
1304 void Window::SetQuickHelpText( const OUString
& rHelpText
)
1307 mpWindowImpl
->maQuickHelpText
= rHelpText
;
1310 const OUString
& Window::GetQuickHelpText() const
1312 return mpWindowImpl
->maQuickHelpText
;
1315 bool Window::IsCreatedWithToolkit() const
1317 return mpWindowImpl
->mbCreatedWithToolkit
;
1320 void Window::SetCreatedWithToolkit( bool b
)
1322 mpWindowImpl
->mbCreatedWithToolkit
= b
;
1325 PointerStyle
Window::GetPointer() const
1327 return mpWindowImpl
->maPointer
;
1330 VCLXWindow
* Window::GetWindowPeer() const
1332 return mpWindowImpl
? mpWindowImpl
->mpVCLXWindow
: nullptr;
1335 void Window::SetPosPixel( const Point
& rNewPos
)
1337 setPosSizePixel( rNewPos
.X(), rNewPos
.Y(), 0, 0, PosSizeFlags::Pos
);
1340 void Window::SetSizePixel( const Size
& rNewSize
)
1342 setPosSizePixel( 0, 0, rNewSize
.Width(), rNewSize
.Height(),
1343 PosSizeFlags::Size
);
1346 void Window::SetPosSizePixel( const Point
& rNewPos
, const Size
& rNewSize
)
1348 setPosSizePixel( rNewPos
.X(), rNewPos
.Y(),
1349 rNewSize
.Width(), rNewSize
.Height());
1352 void Window::SetOutputSizePixel( const Size
& rNewSize
)
1354 SetSizePixel( Size( rNewSize
.Width()+mpWindowImpl
->mnLeftBorder
+mpWindowImpl
->mnRightBorder
,
1355 rNewSize
.Height()+mpWindowImpl
->mnTopBorder
+mpWindowImpl
->mnBottomBorder
) );
1358 //When a widget wants to renegotiate layout, get toplevel parent dialog and call
1359 //resize on it. Mark all intermediate containers (or container-alike) widgets
1360 //as dirty for the size remains unchanged, but layout changed circumstances
1363 bool queue_ungrouped_resize(vcl::Window
const *pOrigWindow
)
1365 bool bSomeoneCares
= false;
1367 vcl::Window
*pWindow
= pOrigWindow
->GetParent();
1370 if (isContainerWindow(*pWindow
))
1372 bSomeoneCares
= true;
1374 else if (pWindow
->GetType() == WindowType::TABCONTROL
)
1376 bSomeoneCares
= true;
1378 pWindow
->queue_resize();
1381 return bSomeoneCares
;
1385 void Window::InvalidateSizeCache()
1387 WindowImpl
*pWindowImpl
= mpWindowImpl
->mpBorderWindow
? mpWindowImpl
->mpBorderWindow
->mpWindowImpl
.get() : mpWindowImpl
.get();
1388 pWindowImpl
->mnOptimalWidthCache
= -1;
1389 pWindowImpl
->mnOptimalHeightCache
= -1;
1392 static bool HasParentDockingWindow(const vcl::Window
* pWindow
)
1396 if( pWindow
->IsDockingWindow() )
1399 pWindow
= pWindow
->GetParent();
1405 void Window::queue_resize(StateChangedType eReason
)
1410 bool bSomeoneCares
= queue_ungrouped_resize(this);
1412 if (eReason
!= StateChangedType::Visible
)
1414 InvalidateSizeCache();
1417 WindowImpl
*pWindowImpl
= mpWindowImpl
->mpBorderWindow
? mpWindowImpl
->mpBorderWindow
->mpWindowImpl
.get() : mpWindowImpl
.get();
1418 if (pWindowImpl
->m_xSizeGroup
&& pWindowImpl
->m_xSizeGroup
->get_mode() != VclSizeGroupMode::NONE
)
1420 std::set
<VclPtr
<vcl::Window
> > &rWindows
= pWindowImpl
->m_xSizeGroup
->get_widgets();
1421 for (VclPtr
<vcl::Window
> const & pOther
: rWindows
)
1425 queue_ungrouped_resize(pOther
);
1429 if (bSomeoneCares
&& !isDisposed())
1431 //fdo#57090 force a resync of the borders of the borderwindow onto this
1432 //window in case they have changed
1433 vcl::Window
* pBorderWindow
= ImplGetBorderWindow();
1435 pBorderWindow
->Resize();
1437 if (VclPtr
<vcl::Window
> pParent
= GetParentWithLOKNotifier())
1439 Size aSize
= GetSizePixel();
1440 if (!aSize
.IsEmpty() && !pParent
->IsInInitShow()
1441 && (GetParentDialog() || HasParentDockingWindow(this)))
1442 LogicInvalidate(nullptr);
1448 VclAlign
toAlign(std::u16string_view rValue
)
1450 VclAlign eRet
= VclAlign::Fill
;
1452 if (rValue
== u
"fill")
1453 eRet
= VclAlign::Fill
;
1454 else if (rValue
== u
"start")
1455 eRet
= VclAlign::Start
;
1456 else if (rValue
== u
"end")
1457 eRet
= VclAlign::End
;
1458 else if (rValue
== u
"center")
1459 eRet
= VclAlign::Center
;
1464 bool Window::set_font_attribute(const OUString
&rKey
, std::u16string_view rValue
)
1466 if (rKey
== "weight")
1468 vcl::Font
aFont(GetControlFont());
1469 if (rValue
== u
"thin")
1470 aFont
.SetWeight(WEIGHT_THIN
);
1471 else if (rValue
== u
"ultralight")
1472 aFont
.SetWeight(WEIGHT_ULTRALIGHT
);
1473 else if (rValue
== u
"light")
1474 aFont
.SetWeight(WEIGHT_LIGHT
);
1475 else if (rValue
== u
"book")
1476 aFont
.SetWeight(WEIGHT_SEMILIGHT
);
1477 else if (rValue
== u
"normal")
1478 aFont
.SetWeight(WEIGHT_NORMAL
);
1479 else if (rValue
== u
"medium")
1480 aFont
.SetWeight(WEIGHT_MEDIUM
);
1481 else if (rValue
== u
"semibold")
1482 aFont
.SetWeight(WEIGHT_SEMIBOLD
);
1483 else if (rValue
== u
"bold")
1484 aFont
.SetWeight(WEIGHT_BOLD
);
1485 else if (rValue
== u
"ultrabold")
1486 aFont
.SetWeight(WEIGHT_ULTRABOLD
);
1488 aFont
.SetWeight(WEIGHT_BLACK
);
1489 SetControlFont(aFont
);
1491 else if (rKey
== "style")
1493 vcl::Font
aFont(GetControlFont());
1494 if (rValue
== u
"normal")
1495 aFont
.SetItalic(ITALIC_NONE
);
1496 else if (rValue
== u
"oblique")
1497 aFont
.SetItalic(ITALIC_OBLIQUE
);
1498 else if (rValue
== u
"italic")
1499 aFont
.SetItalic(ITALIC_NORMAL
);
1500 SetControlFont(aFont
);
1502 else if (rKey
== "underline")
1504 vcl::Font
aFont(GetControlFont());
1505 aFont
.SetUnderline(toBool(rValue
) ? LINESTYLE_SINGLE
: LINESTYLE_NONE
);
1506 SetControlFont(aFont
);
1508 else if (rKey
== "scale")
1510 // if no control font was set yet, take the underlying font from the device
1511 vcl::Font
aFont(IsControlFont() ? GetControlFont() : GetPointFont(*GetOutDev()));
1512 aFont
.SetFontHeight(aFont
.GetFontHeight() * o3tl::toDouble(rValue
));
1513 SetControlFont(aFont
);
1515 else if (rKey
== "size")
1517 vcl::Font
aFont(GetControlFont());
1518 sal_Int32 nHeight
= o3tl::toInt32(rValue
) / 1000;
1519 aFont
.SetFontHeight(nHeight
);
1520 SetControlFont(aFont
);
1524 SAL_INFO("vcl.layout", "unhandled font attribute: " << rKey
);
1530 bool Window::set_property(const OUString
&rKey
, const OUString
&rValue
)
1532 if ((rKey
== "label") || (rKey
== "title") || (rKey
== "text") )
1534 SetText(BuilderUtils::convertMnemonicMarkup(rValue
));
1536 else if (rKey
== "visible")
1537 Show(toBool(rValue
));
1538 else if (rKey
== "sensitive")
1539 Enable(toBool(rValue
));
1540 else if (rKey
== "resizable")
1542 WinBits nBits
= GetStyle();
1543 nBits
&= ~WB_SIZEABLE
;
1545 nBits
|= WB_SIZEABLE
;
1548 else if (rKey
== "xalign")
1550 WinBits nBits
= GetStyle();
1551 nBits
&= ~(WB_LEFT
| WB_CENTER
| WB_RIGHT
);
1553 float f
= rValue
.toFloat();
1554 assert(f
== 0.0 || f
== 1.0 || f
== 0.5);
1564 else if (rKey
== "justification")
1566 WinBits nBits
= GetStyle();
1567 nBits
&= ~(WB_LEFT
| WB_CENTER
| WB_RIGHT
);
1569 if (rValue
== "left")
1571 else if (rValue
== "right")
1573 else if (rValue
== "center")
1578 else if (rKey
== "yalign")
1580 WinBits nBits
= GetStyle();
1581 nBits
&= ~(WB_TOP
| WB_VCENTER
| WB_BOTTOM
);
1583 float f
= rValue
.toFloat();
1584 assert(f
== 0.0 || f
== 1.0 || f
== 0.5);
1590 nBits
|= WB_VCENTER
;
1594 else if (rKey
== "wrap")
1596 WinBits nBits
= GetStyle();
1597 nBits
&= ~WB_WORDBREAK
;
1599 nBits
|= WB_WORDBREAK
;
1602 else if (rKey
== "height-request")
1603 set_height_request(rValue
.toInt32());
1604 else if (rKey
== "width-request")
1605 set_width_request(rValue
.toInt32());
1606 else if (rKey
== "hexpand")
1607 set_hexpand(toBool(rValue
));
1608 else if (rKey
== "vexpand")
1609 set_vexpand(toBool(rValue
));
1610 else if (rKey
== "halign")
1611 set_halign(toAlign(rValue
));
1612 else if (rKey
== "valign")
1613 set_valign(toAlign(rValue
));
1614 else if (rKey
== "tooltip-markup")
1615 SetQuickHelpText(rValue
);
1616 else if (rKey
== "tooltip-text")
1617 SetQuickHelpText(rValue
);
1618 else if (rKey
== "border-width")
1619 set_border_width(rValue
.toInt32());
1620 else if (rKey
== "margin-start" || rKey
== "margin-left")
1622 assert(rKey
== "margin-start" && "margin-left deprecated in favor of margin-start");
1623 set_margin_start(rValue
.toInt32());
1625 else if (rKey
== "margin-end" || rKey
== "margin-right")
1627 assert(rKey
== "margin-end" && "margin-right deprecated in favor of margin-end");
1628 set_margin_end(rValue
.toInt32());
1630 else if (rKey
== "margin-top")
1631 set_margin_top(rValue
.toInt32());
1632 else if (rKey
== "margin-bottom")
1633 set_margin_bottom(rValue
.toInt32());
1634 else if (rKey
== "hscrollbar-policy")
1636 WinBits nBits
= GetStyle();
1637 nBits
&= ~(WB_AUTOHSCROLL
|WB_HSCROLL
);
1638 if (rValue
== "always")
1639 nBits
|= WB_HSCROLL
;
1640 else if (rValue
== "automatic")
1641 nBits
|= WB_AUTOHSCROLL
;
1644 else if (rKey
== "vscrollbar-policy")
1646 WinBits nBits
= GetStyle();
1647 nBits
&= ~(WB_AUTOVSCROLL
|WB_VSCROLL
);
1648 if (rValue
== "always")
1649 nBits
|= WB_VSCROLL
;
1650 else if (rValue
== "automatic")
1651 nBits
|= WB_AUTOVSCROLL
;
1654 else if (rKey
== "accessible-name")
1656 SetAccessibleName(rValue
);
1658 else if (rKey
== "accessible-description")
1660 SetAccessibleDescription(rValue
);
1662 else if (rKey
== "accessible-role")
1664 sal_Int16 role
= BuilderUtils::getRoleFromName(rValue
);
1665 if (role
!= css::accessibility::AccessibleRole::UNKNOWN
)
1666 SetAccessibleRole(role
);
1668 else if (rKey
== "use-markup")
1670 //https://live.gnome.org/GnomeGoals/RemoveMarkupInMessages
1671 SAL_WARN_IF(toBool(rValue
), "vcl.layout", "Use pango attributes instead of mark-up");
1673 else if (rKey
== "has-focus")
1678 else if (rKey
== "can-focus")
1680 WinBits nBits
= GetStyle();
1681 nBits
&= ~(WB_TABSTOP
|WB_NOTABSTOP
);
1683 nBits
|= WB_TABSTOP
;
1685 nBits
|= WB_NOTABSTOP
;
1690 SAL_INFO("vcl.layout", "unhandled property: " << rKey
);
1696 void Window::set_height_request(sal_Int32 nHeightRequest
)
1701 WindowImpl
*pWindowImpl
= mpWindowImpl
->mpBorderWindow
? mpWindowImpl
->mpBorderWindow
->mpWindowImpl
.get() : mpWindowImpl
.get();
1703 if ( pWindowImpl
->mnHeightRequest
!= nHeightRequest
)
1705 pWindowImpl
->mnHeightRequest
= nHeightRequest
;
1710 void Window::set_width_request(sal_Int32 nWidthRequest
)
1715 WindowImpl
*pWindowImpl
= mpWindowImpl
->mpBorderWindow
? mpWindowImpl
->mpBorderWindow
->mpWindowImpl
.get() : mpWindowImpl
.get();
1717 if ( pWindowImpl
->mnWidthRequest
!= nWidthRequest
)
1719 pWindowImpl
->mnWidthRequest
= nWidthRequest
;
1724 Size
Window::get_ungrouped_preferred_size() const
1726 Size
aRet(get_width_request(), get_height_request());
1727 if (aRet
.Width() == -1 || aRet
.Height() == -1)
1729 //cache gets blown away by queue_resize
1730 WindowImpl
*pWindowImpl
= mpWindowImpl
->mpBorderWindow
? mpWindowImpl
->mpBorderWindow
->mpWindowImpl
.get() : mpWindowImpl
.get();
1731 if (pWindowImpl
->mnOptimalWidthCache
== -1 || pWindowImpl
->mnOptimalHeightCache
== -1)
1733 Size
aOptimal(GetOptimalSize());
1734 pWindowImpl
->mnOptimalWidthCache
= aOptimal
.Width();
1735 pWindowImpl
->mnOptimalHeightCache
= aOptimal
.Height();
1738 if (aRet
.Width() == -1)
1739 aRet
.setWidth( pWindowImpl
->mnOptimalWidthCache
);
1740 if (aRet
.Height() == -1)
1741 aRet
.setHeight( pWindowImpl
->mnOptimalHeightCache
);
1746 Size
Window::get_preferred_size() const
1748 Size
aRet(get_ungrouped_preferred_size());
1750 WindowImpl
*pWindowImpl
= mpWindowImpl
->mpBorderWindow
? mpWindowImpl
->mpBorderWindow
->mpWindowImpl
.get() : mpWindowImpl
.get();
1751 if (pWindowImpl
->m_xSizeGroup
)
1753 const VclSizeGroupMode eMode
= pWindowImpl
->m_xSizeGroup
->get_mode();
1754 if (eMode
!= VclSizeGroupMode::NONE
)
1756 const bool bIgnoreInHidden
= pWindowImpl
->m_xSizeGroup
->get_ignore_hidden();
1757 const std::set
<VclPtr
<vcl::Window
> > &rWindows
= pWindowImpl
->m_xSizeGroup
->get_widgets();
1758 for (auto const& window
: rWindows
)
1760 const vcl::Window
*pOther
= window
;
1763 if (bIgnoreInHidden
&& !pOther
->IsVisible())
1765 Size aOtherSize
= pOther
->get_ungrouped_preferred_size();
1766 if (eMode
== VclSizeGroupMode::Both
|| eMode
== VclSizeGroupMode::Horizontal
)
1767 aRet
.setWidth( std::max(aRet
.Width(), aOtherSize
.Width()) );
1768 if (eMode
== VclSizeGroupMode::Both
|| eMode
== VclSizeGroupMode::Vertical
)
1769 aRet
.setHeight( std::max(aRet
.Height(), aOtherSize
.Height()) );
1777 VclAlign
Window::get_halign() const
1779 WindowImpl
*pWindowImpl
= mpWindowImpl
->mpBorderWindow
? mpWindowImpl
->mpBorderWindow
->mpWindowImpl
.get() : mpWindowImpl
.get();
1780 return pWindowImpl
->meHalign
;
1783 void Window::set_halign(VclAlign eAlign
)
1785 WindowImpl
*pWindowImpl
= mpWindowImpl
->mpBorderWindow
? mpWindowImpl
->mpBorderWindow
->mpWindowImpl
.get() : mpWindowImpl
.get();
1786 pWindowImpl
->meHalign
= eAlign
;
1789 VclAlign
Window::get_valign() const
1791 WindowImpl
*pWindowImpl
= mpWindowImpl
->mpBorderWindow
? mpWindowImpl
->mpBorderWindow
->mpWindowImpl
.get() : mpWindowImpl
.get();
1792 return pWindowImpl
->meValign
;
1795 void Window::set_valign(VclAlign eAlign
)
1797 WindowImpl
*pWindowImpl
= mpWindowImpl
->mpBorderWindow
? mpWindowImpl
->mpBorderWindow
->mpWindowImpl
.get() : mpWindowImpl
.get();
1798 pWindowImpl
->meValign
= eAlign
;
1801 bool Window::get_hexpand() const
1803 WindowImpl
*pWindowImpl
= mpWindowImpl
->mpBorderWindow
? mpWindowImpl
->mpBorderWindow
->mpWindowImpl
.get() : mpWindowImpl
.get();
1804 return pWindowImpl
->mbHexpand
;
1807 void Window::set_hexpand(bool bExpand
)
1809 WindowImpl
*pWindowImpl
= mpWindowImpl
->mpBorderWindow
? mpWindowImpl
->mpBorderWindow
->mpWindowImpl
.get() : mpWindowImpl
.get();
1810 pWindowImpl
->mbHexpand
= bExpand
;
1813 bool Window::get_vexpand() const
1815 WindowImpl
*pWindowImpl
= mpWindowImpl
->mpBorderWindow
? mpWindowImpl
->mpBorderWindow
->mpWindowImpl
.get() : mpWindowImpl
.get();
1816 return pWindowImpl
->mbVexpand
;
1819 void Window::set_vexpand(bool bExpand
)
1821 WindowImpl
*pWindowImpl
= mpWindowImpl
->mpBorderWindow
? mpWindowImpl
->mpBorderWindow
->mpWindowImpl
.get() : mpWindowImpl
.get();
1822 pWindowImpl
->mbVexpand
= bExpand
;
1825 bool Window::get_expand() const
1827 WindowImpl
*pWindowImpl
= mpWindowImpl
->mpBorderWindow
? mpWindowImpl
->mpBorderWindow
->mpWindowImpl
.get() : mpWindowImpl
.get();
1828 return pWindowImpl
->mbExpand
;
1831 void Window::set_expand(bool bExpand
)
1833 WindowImpl
*pWindowImpl
= mpWindowImpl
->mpBorderWindow
? mpWindowImpl
->mpBorderWindow
->mpWindowImpl
.get() : mpWindowImpl
.get();
1834 pWindowImpl
->mbExpand
= bExpand
;
1837 VclPackType
Window::get_pack_type() const
1839 WindowImpl
*pWindowImpl
= mpWindowImpl
->mpBorderWindow
? mpWindowImpl
->mpBorderWindow
->mpWindowImpl
.get() : mpWindowImpl
.get();
1840 return pWindowImpl
->mePackType
;
1843 void Window::set_pack_type(VclPackType ePackType
)
1845 WindowImpl
*pWindowImpl
= mpWindowImpl
->mpBorderWindow
? mpWindowImpl
->mpBorderWindow
->mpWindowImpl
.get() : mpWindowImpl
.get();
1846 pWindowImpl
->mePackType
= ePackType
;
1849 sal_Int32
Window::get_padding() const
1851 WindowImpl
*pWindowImpl
= mpWindowImpl
->mpBorderWindow
? mpWindowImpl
->mpBorderWindow
->mpWindowImpl
.get() : mpWindowImpl
.get();
1852 return pWindowImpl
->mnPadding
;
1855 void Window::set_padding(sal_Int32 nPadding
)
1857 WindowImpl
*pWindowImpl
= mpWindowImpl
->mpBorderWindow
? mpWindowImpl
->mpBorderWindow
->mpWindowImpl
.get() : mpWindowImpl
.get();
1858 pWindowImpl
->mnPadding
= nPadding
;
1861 bool Window::get_fill() const
1863 WindowImpl
*pWindowImpl
= mpWindowImpl
->mpBorderWindow
? mpWindowImpl
->mpBorderWindow
->mpWindowImpl
.get() : mpWindowImpl
.get();
1864 return pWindowImpl
->mbFill
;
1867 void Window::set_fill(bool bFill
)
1869 WindowImpl
*pWindowImpl
= mpWindowImpl
->mpBorderWindow
? mpWindowImpl
->mpBorderWindow
->mpWindowImpl
.get() : mpWindowImpl
.get();
1870 pWindowImpl
->mbFill
= bFill
;
1873 sal_Int32
Window::get_grid_width() const
1875 WindowImpl
*pWindowImpl
= mpWindowImpl
->mpBorderWindow
? mpWindowImpl
->mpBorderWindow
->mpWindowImpl
.get() : mpWindowImpl
.get();
1876 return pWindowImpl
->mnGridWidth
;
1879 void Window::set_grid_width(sal_Int32 nCols
)
1881 WindowImpl
*pWindowImpl
= mpWindowImpl
->mpBorderWindow
? mpWindowImpl
->mpBorderWindow
->mpWindowImpl
.get() : mpWindowImpl
.get();
1882 pWindowImpl
->mnGridWidth
= nCols
;
1885 sal_Int32
Window::get_grid_left_attach() const
1887 WindowImpl
*pWindowImpl
= mpWindowImpl
->mpBorderWindow
? mpWindowImpl
->mpBorderWindow
->mpWindowImpl
.get() : mpWindowImpl
.get();
1888 return pWindowImpl
->mnGridLeftAttach
;
1891 void Window::set_grid_left_attach(sal_Int32 nAttach
)
1893 WindowImpl
*pWindowImpl
= mpWindowImpl
->mpBorderWindow
? mpWindowImpl
->mpBorderWindow
->mpWindowImpl
.get() : mpWindowImpl
.get();
1894 pWindowImpl
->mnGridLeftAttach
= nAttach
;
1897 sal_Int32
Window::get_grid_height() const
1899 WindowImpl
*pWindowImpl
= mpWindowImpl
->mpBorderWindow
? mpWindowImpl
->mpBorderWindow
->mpWindowImpl
.get() : mpWindowImpl
.get();
1900 return pWindowImpl
->mnGridHeight
;
1903 void Window::set_grid_height(sal_Int32 nRows
)
1905 WindowImpl
*pWindowImpl
= mpWindowImpl
->mpBorderWindow
? mpWindowImpl
->mpBorderWindow
->mpWindowImpl
.get() : mpWindowImpl
.get();
1906 pWindowImpl
->mnGridHeight
= nRows
;
1909 sal_Int32
Window::get_grid_top_attach() const
1911 WindowImpl
*pWindowImpl
= mpWindowImpl
->mpBorderWindow
? mpWindowImpl
->mpBorderWindow
->mpWindowImpl
.get() : mpWindowImpl
.get();
1912 return pWindowImpl
->mnGridTopAttach
;
1915 void Window::set_grid_top_attach(sal_Int32 nAttach
)
1917 WindowImpl
*pWindowImpl
= mpWindowImpl
->mpBorderWindow
? mpWindowImpl
->mpBorderWindow
->mpWindowImpl
.get() : mpWindowImpl
.get();
1918 pWindowImpl
->mnGridTopAttach
= nAttach
;
1921 void Window::set_border_width(sal_Int32 nBorderWidth
)
1923 WindowImpl
*pWindowImpl
= mpWindowImpl
->mpBorderWindow
? mpWindowImpl
->mpBorderWindow
->mpWindowImpl
.get() : mpWindowImpl
.get();
1924 pWindowImpl
->mnBorderWidth
= nBorderWidth
;
1927 sal_Int32
Window::get_border_width() const
1929 WindowImpl
*pWindowImpl
= mpWindowImpl
->mpBorderWindow
? mpWindowImpl
->mpBorderWindow
->mpWindowImpl
.get() : mpWindowImpl
.get();
1930 return pWindowImpl
->mnBorderWidth
;
1933 void Window::set_margin_start(sal_Int32 nWidth
)
1935 WindowImpl
*pWindowImpl
= mpWindowImpl
->mpBorderWindow
? mpWindowImpl
->mpBorderWindow
->mpWindowImpl
.get() : mpWindowImpl
.get();
1936 if (pWindowImpl
->mnMarginLeft
!= nWidth
)
1938 pWindowImpl
->mnMarginLeft
= nWidth
;
1943 sal_Int32
Window::get_margin_start() const
1945 WindowImpl
*pWindowImpl
= mpWindowImpl
->mpBorderWindow
? mpWindowImpl
->mpBorderWindow
->mpWindowImpl
.get() : mpWindowImpl
.get();
1946 return pWindowImpl
->mnMarginLeft
;
1949 void Window::set_margin_end(sal_Int32 nWidth
)
1951 WindowImpl
*pWindowImpl
= mpWindowImpl
->mpBorderWindow
? mpWindowImpl
->mpBorderWindow
->mpWindowImpl
.get() : mpWindowImpl
.get();
1952 if (pWindowImpl
->mnMarginRight
!= nWidth
)
1954 pWindowImpl
->mnMarginRight
= nWidth
;
1959 sal_Int32
Window::get_margin_end() const
1961 WindowImpl
*pWindowImpl
= mpWindowImpl
->mpBorderWindow
? mpWindowImpl
->mpBorderWindow
->mpWindowImpl
.get() : mpWindowImpl
.get();
1962 return pWindowImpl
->mnMarginRight
;
1965 void Window::set_margin_top(sal_Int32 nWidth
)
1967 WindowImpl
*pWindowImpl
= mpWindowImpl
->mpBorderWindow
? mpWindowImpl
->mpBorderWindow
->mpWindowImpl
.get() : mpWindowImpl
.get();
1968 if (pWindowImpl
->mnMarginTop
!= nWidth
)
1970 pWindowImpl
->mnMarginTop
= nWidth
;
1975 sal_Int32
Window::get_margin_top() const
1977 WindowImpl
*pWindowImpl
= mpWindowImpl
->mpBorderWindow
? mpWindowImpl
->mpBorderWindow
->mpWindowImpl
.get() : mpWindowImpl
.get();
1978 return pWindowImpl
->mnMarginTop
;
1981 void Window::set_margin_bottom(sal_Int32 nWidth
)
1983 WindowImpl
*pWindowImpl
= mpWindowImpl
->mpBorderWindow
? mpWindowImpl
->mpBorderWindow
->mpWindowImpl
.get() : mpWindowImpl
.get();
1984 if (pWindowImpl
->mnMarginBottom
!= nWidth
)
1986 pWindowImpl
->mnMarginBottom
= nWidth
;
1991 sal_Int32
Window::get_margin_bottom() const
1993 WindowImpl
*pWindowImpl
= mpWindowImpl
->mpBorderWindow
? mpWindowImpl
->mpBorderWindow
->mpWindowImpl
.get() : mpWindowImpl
.get();
1994 return pWindowImpl
->mnMarginBottom
;
1997 sal_Int32
Window::get_height_request() const
1999 WindowImpl
*pWindowImpl
= mpWindowImpl
->mpBorderWindow
? mpWindowImpl
->mpBorderWindow
->mpWindowImpl
.get() : mpWindowImpl
.get();
2000 return pWindowImpl
->mnHeightRequest
;
2003 sal_Int32
Window::get_width_request() const
2005 WindowImpl
*pWindowImpl
= mpWindowImpl
->mpBorderWindow
? mpWindowImpl
->mpBorderWindow
->mpWindowImpl
.get() : mpWindowImpl
.get();
2006 return pWindowImpl
->mnWidthRequest
;
2009 bool Window::get_secondary() const
2011 WindowImpl
*pWindowImpl
= mpWindowImpl
->mpBorderWindow
? mpWindowImpl
->mpBorderWindow
->mpWindowImpl
.get() : mpWindowImpl
.get();
2012 return pWindowImpl
->mbSecondary
;
2015 void Window::set_secondary(bool bSecondary
)
2017 WindowImpl
*pWindowImpl
= mpWindowImpl
->mpBorderWindow
? mpWindowImpl
->mpBorderWindow
->mpWindowImpl
.get() : mpWindowImpl
.get();
2018 pWindowImpl
->mbSecondary
= bSecondary
;
2021 bool Window::get_non_homogeneous() const
2023 WindowImpl
*pWindowImpl
= mpWindowImpl
->mpBorderWindow
? mpWindowImpl
->mpBorderWindow
->mpWindowImpl
.get() : mpWindowImpl
.get();
2024 return pWindowImpl
->mbNonHomogeneous
;
2027 void Window::set_non_homogeneous(bool bNonHomogeneous
)
2029 WindowImpl
*pWindowImpl
= mpWindowImpl
->mpBorderWindow
? mpWindowImpl
->mpBorderWindow
->mpWindowImpl
.get() : mpWindowImpl
.get();
2030 pWindowImpl
->mbNonHomogeneous
= bNonHomogeneous
;
2033 void Window::add_to_size_group(const std::shared_ptr
<VclSizeGroup
>& xGroup
)
2035 WindowImpl
*pWindowImpl
= mpWindowImpl
->mpBorderWindow
? mpWindowImpl
->mpBorderWindow
->mpWindowImpl
.get() : mpWindowImpl
.get();
2036 //To-Do, multiple groups
2037 pWindowImpl
->m_xSizeGroup
= xGroup
;
2038 pWindowImpl
->m_xSizeGroup
->insert(this);
2039 if (VclSizeGroupMode::NONE
!= pWindowImpl
->m_xSizeGroup
->get_mode())
2043 void Window::remove_from_all_size_groups()
2045 WindowImpl
*pWindowImpl
= mpWindowImpl
->mpBorderWindow
? mpWindowImpl
->mpBorderWindow
->mpWindowImpl
.get() : mpWindowImpl
.get();
2046 //To-Do, multiple groups
2047 if (pWindowImpl
->m_xSizeGroup
)
2049 if (VclSizeGroupMode::NONE
!= pWindowImpl
->m_xSizeGroup
->get_mode())
2051 pWindowImpl
->m_xSizeGroup
->erase(this);
2052 pWindowImpl
->m_xSizeGroup
.reset();
2056 void Window::add_mnemonic_label(FixedText
*pLabel
)
2058 std::vector
<VclPtr
<FixedText
> >& v
= mpWindowImpl
->m_aMnemonicLabels
;
2059 if (std::find(v
.begin(), v
.end(), VclPtr
<FixedText
>(pLabel
)) != v
.end())
2061 v
.emplace_back(pLabel
);
2062 pLabel
->set_mnemonic_widget(this);
2065 void Window::remove_mnemonic_label(FixedText
*pLabel
)
2067 std::vector
<VclPtr
<FixedText
> >& v
= mpWindowImpl
->m_aMnemonicLabels
;
2068 auto aFind
= std::find(v
.begin(), v
.end(), VclPtr
<FixedText
>(pLabel
));
2069 if (aFind
== v
.end())
2072 pLabel
->set_mnemonic_widget(nullptr);
2075 const std::vector
<VclPtr
<FixedText
> >& Window::list_mnemonic_labels() const
2077 return mpWindowImpl
->m_aMnemonicLabels
;
2080 } /* namespace vcl */
2082 void InvertFocusRect(vcl::RenderContext
& rRenderContext
, const tools::Rectangle
& rRect
)
2084 const int nBorder
= 1;
2085 rRenderContext
.Invert(tools::Rectangle(Point(rRect
.Left(), rRect
.Top()), Size(rRect
.GetWidth(), nBorder
)), InvertFlags::N50
);
2086 rRenderContext
.Invert(tools::Rectangle(Point(rRect
.Left(), rRect
.Bottom()-nBorder
+1), Size(rRect
.GetWidth(), nBorder
)), InvertFlags::N50
);
2087 rRenderContext
.Invert(tools::Rectangle(Point(rRect
.Left(), rRect
.Top()+nBorder
), Size(nBorder
, rRect
.GetHeight()-(nBorder
*2))), InvertFlags::N50
);
2088 rRenderContext
.Invert(tools::Rectangle(Point(rRect
.Right()-nBorder
+1, rRect
.Top()+nBorder
), Size(nBorder
, rRect
.GetHeight()-(nBorder
*2))), InvertFlags::N50
);
2091 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */