Version 6.4.0.0.beta1, tag libreoffice-6.4.0.0.beta1
[LibreOffice.git] / vcl / source / window / window2.cxx
blob6f32ea52eafd0989439329eef601913522e51f63
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <limits.h>
22 #include <o3tl/float_int_conversion.hxx>
23 #include <sal/log.hxx>
25 #include <vcl/dialog.hxx>
26 #include <vcl/event.hxx>
27 #include <vcl/fixed.hxx>
28 #include <vcl/layout.hxx>
29 #include <vcl/timer.hxx>
30 #include <vcl/window.hxx>
31 #include <vcl/scrbar.hxx>
32 #include <vcl/dockwin.hxx>
33 #include <vcl/settings.hxx>
34 #include <vcl/builder.hxx>
36 #include <window.h>
37 #include <svdata.hxx>
38 #include <salgdi.hxx>
39 #include <salframe.hxx>
40 #include <scrwnd.hxx>
42 #include <com/sun/star/accessibility/AccessibleRelation.hpp>
43 #include <com/sun/star/accessibility/AccessibleRole.hpp>
45 using namespace com::sun::star;
47 namespace vcl {
49 void Window::ShowFocus( const tools::Rectangle& rRect )
51 if( mpWindowImpl->mbInShowFocus )
52 return;
53 mpWindowImpl->mbInShowFocus = true;
55 ImplWinData* pWinData = ImplGetWinData();
57 // native themeing suggest not to use focus rects
58 if( ! ( mpWindowImpl->mbUseNativeFocus &&
59 IsNativeWidgetEnabled() ) )
61 if ( !mpWindowImpl->mbInPaint )
63 if ( mpWindowImpl->mbFocusVisible )
65 if ( *pWinData->mpFocusRect == rRect )
67 mpWindowImpl->mbInShowFocus = false;
68 return;
71 ImplInvertFocus( *pWinData->mpFocusRect );
74 ImplInvertFocus( rRect );
76 pWinData->mpFocusRect = rRect;
77 mpWindowImpl->mbFocusVisible = true;
79 else
81 if( ! mpWindowImpl->mbNativeFocusVisible )
83 mpWindowImpl->mbNativeFocusVisible = true;
84 if ( !mpWindowImpl->mbInPaint )
85 Invalidate();
88 mpWindowImpl->mbInShowFocus = false;
91 void Window::HideFocus()
94 if( mpWindowImpl->mbInHideFocus )
95 return;
96 mpWindowImpl->mbInHideFocus = true;
98 // native themeing can suggest not to use focus rects
99 if( ! ( mpWindowImpl->mbUseNativeFocus &&
100 IsNativeWidgetEnabled() ) )
102 if ( !mpWindowImpl->mbFocusVisible )
104 mpWindowImpl->mbInHideFocus = false;
105 return;
108 if ( !mpWindowImpl->mbInPaint )
109 ImplInvertFocus( *ImplGetWinData()->mpFocusRect );
110 mpWindowImpl->mbFocusVisible = false;
112 else
114 if( mpWindowImpl->mbNativeFocusVisible )
116 mpWindowImpl->mbNativeFocusVisible = false;
117 if ( !mpWindowImpl->mbInPaint )
118 Invalidate();
121 mpWindowImpl->mbInHideFocus = false;
124 void Window::ShowTracking( const tools::Rectangle& rRect, ShowTrackFlags nFlags )
126 ImplWinData* pWinData = ImplGetWinData();
128 if ( !mpWindowImpl->mbInPaint || !(nFlags & ShowTrackFlags::TrackWindow) )
130 if ( mpWindowImpl->mbTrackVisible )
132 if ( (*pWinData->mpTrackRect == rRect) &&
133 (pWinData->mnTrackFlags == nFlags) )
134 return;
136 InvertTracking( *pWinData->mpTrackRect, pWinData->mnTrackFlags );
139 InvertTracking( rRect, nFlags );
142 pWinData->mpTrackRect = rRect;
143 pWinData->mnTrackFlags = nFlags;
144 mpWindowImpl->mbTrackVisible = true;
147 void Window::HideTracking()
149 if ( mpWindowImpl->mbTrackVisible )
151 ImplWinData* pWinData = ImplGetWinData();
152 if ( !mpWindowImpl->mbInPaint || !(pWinData->mnTrackFlags & ShowTrackFlags::TrackWindow) )
153 InvertTracking( *pWinData->mpTrackRect, pWinData->mnTrackFlags );
154 mpWindowImpl->mbTrackVisible = false;
158 void Window::InvertTracking( const tools::Rectangle& rRect, ShowTrackFlags nFlags )
160 OutputDevice *pOutDev = GetOutDev();
161 tools::Rectangle aRect( pOutDev->ImplLogicToDevicePixel( rRect ) );
163 if ( aRect.IsEmpty() )
164 return;
165 aRect.Justify();
167 SalGraphics* pGraphics;
169 if ( nFlags & ShowTrackFlags::TrackWindow )
171 if ( !IsDeviceOutputNecessary() )
172 return;
174 // we need a graphics
175 if ( !mpGraphics )
177 if ( !pOutDev->AcquireGraphics() )
178 return;
181 if ( mbInitClipRegion )
182 InitClipRegion();
184 if ( mbOutputClipped )
185 return;
187 pGraphics = mpGraphics;
189 else
191 pGraphics = ImplGetFrameGraphics();
193 if ( nFlags & ShowTrackFlags::Clip )
195 Point aPoint( mnOutOffX, mnOutOffY );
196 vcl::Region aRegion( tools::Rectangle( aPoint,
197 Size( mnOutWidth, mnOutHeight ) ) );
198 ImplClipBoundaries( aRegion, false, false );
199 pOutDev->SelectClipRegion( aRegion, pGraphics );
203 ShowTrackFlags nStyle = nFlags & ShowTrackFlags::StyleMask;
204 if ( nStyle == ShowTrackFlags::Object )
205 pGraphics->Invert( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight(), SalInvert::TrackFrame, this );
206 else if ( nStyle == ShowTrackFlags::Split )
207 pGraphics->Invert( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight(), SalInvert::N50, this );
208 else
210 long nBorder = 1;
211 if ( nStyle == ShowTrackFlags::Big )
212 nBorder = 5;
213 pGraphics->Invert( aRect.Left(), aRect.Top(), aRect.GetWidth(), nBorder, SalInvert::N50, this );
214 pGraphics->Invert( aRect.Left(), aRect.Bottom()-nBorder+1, aRect.GetWidth(), nBorder, SalInvert::N50, this );
215 pGraphics->Invert( aRect.Left(), aRect.Top()+nBorder, nBorder, aRect.GetHeight()-(nBorder*2), SalInvert::N50, this );
216 pGraphics->Invert( aRect.Right()-nBorder+1, aRect.Top()+nBorder, nBorder, aRect.GetHeight()-(nBorder*2), SalInvert::N50, this );
220 IMPL_LINK( Window, ImplTrackTimerHdl, Timer*, pTimer, void )
222 ImplSVData* pSVData = ImplGetSVData();
224 // if Button-Repeat we have to change the timeout
225 if ( pSVData->maWinData.mnTrackFlags & StartTrackingFlags::ButtonRepeat )
226 pTimer->SetTimeout( GetSettings().GetMouseSettings().GetButtonRepeat() );
228 // create Tracking-Event
229 Point aMousePos( mpWindowImpl->mpFrameData->mnLastMouseX, mpWindowImpl->mpFrameData->mnLastMouseY );
230 if( ImplIsAntiparallel() )
232 // re-mirror frame pos at pChild
233 const OutputDevice *pOutDev = GetOutDev();
234 pOutDev->ReMirror( aMousePos );
236 MouseEvent aMEvt( ImplFrameToOutput( aMousePos ),
237 mpWindowImpl->mpFrameData->mnClickCount, MouseEventModifiers::NONE,
238 mpWindowImpl->mpFrameData->mnMouseCode,
239 mpWindowImpl->mpFrameData->mnMouseCode );
240 TrackingEvent aTEvt( aMEvt, TrackingEventFlags::Repeat );
241 Tracking( aTEvt );
244 void Window::StartTracking( StartTrackingFlags nFlags )
246 ImplSVData* pSVData = ImplGetSVData();
248 if ( pSVData->maWinData.mpTrackWin.get() != this )
250 if ( pSVData->maWinData.mpTrackWin )
251 pSVData->maWinData.mpTrackWin->EndTracking( TrackingEventFlags::Cancel );
254 if ( nFlags & (StartTrackingFlags::ScrollRepeat | StartTrackingFlags::ButtonRepeat) )
256 pSVData->maWinData.mpTrackTimer = new AutoTimer;
258 if ( nFlags & StartTrackingFlags::ScrollRepeat )
259 pSVData->maWinData.mpTrackTimer->SetTimeout( MouseSettings::GetScrollRepeat() );
260 else
261 pSVData->maWinData.mpTrackTimer->SetTimeout( MouseSettings::GetButtonStartRepeat() );
262 pSVData->maWinData.mpTrackTimer->SetInvokeHandler( LINK( this, Window, ImplTrackTimerHdl ) );
263 pSVData->maWinData.mpTrackTimer->SetDebugName( "vcl::Window pSVData->maWinData.mpTrackTimer" );
264 pSVData->maWinData.mpTrackTimer->Start();
267 pSVData->maWinData.mpTrackWin = this;
268 pSVData->maWinData.mnTrackFlags = nFlags;
269 CaptureMouse();
272 void Window::EndTracking( TrackingEventFlags nFlags )
274 ImplSVData* pSVData = ImplGetSVData();
276 if ( pSVData->maWinData.mpTrackWin.get() == this )
278 if ( pSVData->maWinData.mpTrackTimer )
280 delete pSVData->maWinData.mpTrackTimer;
281 pSVData->maWinData.mpTrackTimer = nullptr;
284 pSVData->maWinData.mpTrackWin = nullptr;
285 pSVData->maWinData.mnTrackFlags = StartTrackingFlags::NONE;
286 ReleaseMouse();
288 // call EndTracking if required
290 Point aMousePos( mpWindowImpl->mpFrameData->mnLastMouseX, mpWindowImpl->mpFrameData->mnLastMouseY );
291 if( ImplIsAntiparallel() )
293 // re-mirror frame pos at pChild
294 const OutputDevice *pOutDev = GetOutDev();
295 pOutDev->ReMirror( aMousePos );
298 MouseEvent aMEvt( ImplFrameToOutput( aMousePos ),
299 mpWindowImpl->mpFrameData->mnClickCount, MouseEventModifiers::NONE,
300 mpWindowImpl->mpFrameData->mnMouseCode,
301 mpWindowImpl->mpFrameData->mnMouseCode );
302 TrackingEvent aTEvt( aMEvt, nFlags | TrackingEventFlags::End );
303 // CompatTracking effectively
304 if (!mpWindowImpl || mpWindowImpl->mbInDispose)
305 return Window::Tracking( aTEvt );
306 else
307 return Tracking( aTEvt );
312 bool Window::IsTracking() const
314 return (ImplGetSVData()->maWinData.mpTrackWin == this);
317 void Window::StartAutoScroll( StartAutoScrollFlags nFlags )
319 ImplSVData* pSVData = ImplGetSVData();
321 if ( pSVData->maWinData.mpAutoScrollWin.get() != this )
323 if ( pSVData->maWinData.mpAutoScrollWin )
324 pSVData->maWinData.mpAutoScrollWin->EndAutoScroll();
327 pSVData->maWinData.mpAutoScrollWin = this;
328 pSVData->maWinData.mnAutoScrollFlags = nFlags;
329 pSVData->maAppData.mpWheelWindow = VclPtr<ImplWheelWindow>::Create( this );
332 void Window::EndAutoScroll()
334 ImplSVData* pSVData = ImplGetSVData();
336 if ( pSVData->maWinData.mpAutoScrollWin.get() == this )
338 pSVData->maWinData.mpAutoScrollWin = nullptr;
339 pSVData->maWinData.mnAutoScrollFlags = StartAutoScrollFlags::NONE;
340 pSVData->maAppData.mpWheelWindow->ImplStop();
341 pSVData->maAppData.mpWheelWindow->SetParentToDefaultWindow();
342 pSVData->maAppData.mpWheelWindow.disposeAndClear();
346 VclPtr<vcl::Window> Window::SaveFocus()
348 ImplSVData* pSVData = ImplGetSVData();
349 if ( pSVData->maWinData.mpFocusWin )
351 return pSVData->maWinData.mpFocusWin;
353 else
354 return nullptr;
357 void Window::EndSaveFocus(const VclPtr<vcl::Window>& xFocusWin)
359 if (xFocusWin && !xFocusWin->IsDisposed())
361 xFocusWin->GrabFocus();
365 void Window::SetZoom( const Fraction& rZoom )
367 if ( mpWindowImpl && mpWindowImpl->maZoom != rZoom )
369 mpWindowImpl->maZoom = rZoom;
370 CompatStateChanged( StateChangedType::Zoom );
374 static long WinFloatRound( double fVal )
376 return( fVal > 0.0 ? static_cast<long>( fVal + 0.5 ) : -static_cast<long>( -fVal + 0.5 ) );
379 void Window::SetZoomedPointFont(vcl::RenderContext& rRenderContext, const vcl::Font& rFont)
381 const Fraction& rZoom = GetZoom();
382 if (rZoom.GetNumerator() != rZoom.GetDenominator())
384 vcl::Font aFont(rFont);
385 Size aSize = aFont.GetFontSize();
386 aSize.setWidth( WinFloatRound(double(aSize.Width() * rZoom)) );
387 aSize.setHeight( WinFloatRound(double(aSize.Height() * rZoom)) );
388 aFont.SetFontSize(aSize);
389 SetPointFont(rRenderContext, aFont);
391 else
393 SetPointFont(rRenderContext, rFont);
397 long Window::CalcZoom( long nCalc ) const
400 const Fraction& rZoom = GetZoom();
401 if ( rZoom.GetNumerator() != rZoom.GetDenominator() )
403 double n = double(nCalc * rZoom);
404 nCalc = WinFloatRound( n );
406 return nCalc;
409 void Window::SetControlFont()
411 if (mpWindowImpl && mpWindowImpl->mpControlFont)
413 mpWindowImpl->mpControlFont.reset();
414 CompatStateChanged(StateChangedType::ControlFont);
418 void Window::SetControlFont(const vcl::Font& rFont)
420 if (rFont == vcl::Font())
422 SetControlFont();
423 return;
426 if (mpWindowImpl->mpControlFont)
428 if (*mpWindowImpl->mpControlFont == rFont)
429 return;
430 *mpWindowImpl->mpControlFont = rFont;
432 else
433 mpWindowImpl->mpControlFont.reset( new vcl::Font(rFont) );
435 CompatStateChanged(StateChangedType::ControlFont);
438 vcl::Font Window::GetControlFont() const
440 if (mpWindowImpl->mpControlFont)
441 return *mpWindowImpl->mpControlFont;
442 else
444 vcl::Font aFont;
445 return aFont;
449 void Window::ApplyControlFont(vcl::RenderContext& rRenderContext, const vcl::Font& rFont)
451 vcl::Font aFont(rFont);
452 if (IsControlFont())
453 aFont.Merge(GetControlFont());
454 SetZoomedPointFont(rRenderContext, aFont);
457 void Window::SetControlForeground()
459 if (mpWindowImpl->mbControlForeground)
461 mpWindowImpl->maControlForeground = COL_TRANSPARENT;
462 mpWindowImpl->mbControlForeground = false;
463 CompatStateChanged(StateChangedType::ControlForeground);
467 void Window::SetControlForeground(const Color& rColor)
469 if (rColor.GetTransparency())
471 if (mpWindowImpl->mbControlForeground)
473 mpWindowImpl->maControlForeground = COL_TRANSPARENT;
474 mpWindowImpl->mbControlForeground = false;
475 CompatStateChanged(StateChangedType::ControlForeground);
478 else
480 if (mpWindowImpl->maControlForeground != rColor)
482 mpWindowImpl->maControlForeground = rColor;
483 mpWindowImpl->mbControlForeground = true;
484 CompatStateChanged(StateChangedType::ControlForeground);
489 void Window::ApplyControlForeground(vcl::RenderContext& rRenderContext, const Color& rDefaultColor)
491 Color aTextColor(rDefaultColor);
492 if (IsControlForeground())
493 aTextColor = GetControlForeground();
494 rRenderContext.SetTextColor(aTextColor);
497 void Window::SetControlBackground()
499 if (mpWindowImpl->mbControlBackground)
501 mpWindowImpl->maControlBackground = COL_TRANSPARENT;
502 mpWindowImpl->mbControlBackground = false;
503 CompatStateChanged(StateChangedType::ControlBackground);
507 void Window::SetControlBackground(const Color& rColor)
509 if (rColor.GetTransparency())
511 if (mpWindowImpl->mbControlBackground)
513 mpWindowImpl->maControlBackground = COL_TRANSPARENT;
514 mpWindowImpl->mbControlBackground = false;
515 CompatStateChanged(StateChangedType::ControlBackground);
518 else
520 if (mpWindowImpl->maControlBackground != rColor)
522 mpWindowImpl->maControlBackground = rColor;
523 mpWindowImpl->mbControlBackground = true;
524 CompatStateChanged(StateChangedType::ControlBackground);
529 void Window::ApplyControlBackground(vcl::RenderContext& rRenderContext, const Color& rDefaultColor)
531 Color aColor(rDefaultColor);
532 if (IsControlBackground())
533 aColor = GetControlBackground();
534 rRenderContext.SetBackground(aColor);
537 Size Window::CalcWindowSize( const Size& rOutSz ) const
539 Size aSz = rOutSz;
540 aSz.AdjustWidth(mpWindowImpl->mnLeftBorder+mpWindowImpl->mnRightBorder );
541 aSz.AdjustHeight(mpWindowImpl->mnTopBorder+mpWindowImpl->mnBottomBorder );
542 return aSz;
545 Size Window::CalcOutputSize( const Size& rWinSz ) const
547 Size aSz = rWinSz;
548 aSz.AdjustWidth( -(mpWindowImpl->mnLeftBorder+mpWindowImpl->mnRightBorder) );
549 aSz.AdjustHeight( -(mpWindowImpl->mnTopBorder+mpWindowImpl->mnBottomBorder) );
550 return aSz;
553 vcl::Font Window::GetDrawPixelFont(OutputDevice const * pDev) const
555 vcl::Font aFont = GetPointFont(*const_cast<Window*>(this));
556 Size aFontSize = aFont.GetFontSize();
557 MapMode aPtMapMode(MapUnit::MapPoint);
558 aFontSize = pDev->LogicToPixel( aFontSize, aPtMapMode );
559 aFont.SetFontSize( aFontSize );
560 return aFont;
563 long Window::GetDrawPixel( OutputDevice const * pDev, long nPixels ) const
565 long nP = nPixels;
566 if ( pDev->GetOutDevType() != OUTDEV_WINDOW )
568 MapMode aMap( MapUnit::Map100thMM );
569 Size aSz( nP, 0 );
570 aSz = PixelToLogic( aSz, aMap );
571 aSz = pDev->LogicToPixel( aSz, aMap );
572 nP = aSz.Width();
574 return nP;
577 static void lcl_HandleScrollHelper( ScrollBar* pScrl, double nN, bool isMultiplyByLineSize )
579 if ( pScrl && nN && pScrl->IsEnabled() && pScrl->IsInputEnabled() && ! pScrl->IsInModalMode() )
581 long nNewPos = pScrl->GetThumbPos();
583 if ( nN == double(-LONG_MAX) )
584 nNewPos += pScrl->GetPageSize();
585 else if ( nN == double(LONG_MAX) )
586 nNewPos -= pScrl->GetPageSize();
587 else
589 // allowing both chunked and continuous scrolling
590 if(isMultiplyByLineSize){
591 nN*=pScrl->GetLineSize();
594 const double fVal = nNewPos - nN;
596 if ( !o3tl::convertsToAtLeast(fVal, LONG_MIN) )
597 nNewPos = LONG_MIN;
598 else if ( !o3tl::convertsToAtMost(fVal, LONG_MAX) )
599 nNewPos = LONG_MAX;
600 else
601 nNewPos = static_cast<long>(fVal);
604 pScrl->DoScroll( nNewPos );
609 bool Window::HandleScrollCommand( const CommandEvent& rCmd,
610 ScrollBar* pHScrl, ScrollBar* pVScrl )
612 bool bRet = false;
614 if ( pHScrl || pVScrl )
616 switch( rCmd.GetCommand() )
618 case CommandEventId::StartAutoScroll:
620 StartAutoScrollFlags nFlags = StartAutoScrollFlags::NONE;
621 if ( pHScrl )
623 if ( (pHScrl->GetVisibleSize() < pHScrl->GetRangeMax()) &&
624 pHScrl->IsEnabled() && pHScrl->IsInputEnabled() && ! pHScrl->IsInModalMode() )
625 nFlags |= StartAutoScrollFlags::Horz;
627 if ( pVScrl )
629 if ( (pVScrl->GetVisibleSize() < pVScrl->GetRangeMax()) &&
630 pVScrl->IsEnabled() && pVScrl->IsInputEnabled() && ! pVScrl->IsInModalMode() )
631 nFlags |= StartAutoScrollFlags::Vert;
634 if ( nFlags != StartAutoScrollFlags::NONE )
636 StartAutoScroll( nFlags );
637 bRet = true;
640 break;
642 case CommandEventId::Wheel:
644 const CommandWheelData* pData = rCmd.GetWheelData();
646 if ( pData && (CommandWheelMode::SCROLL == pData->GetMode()) )
648 if (!pData->IsDeltaPixel())
650 double nScrollLines = pData->GetScrollLines();
651 double nLines;
652 if ( nScrollLines == COMMAND_WHEEL_PAGESCROLL )
654 if ( pData->GetDelta() < 0 )
655 nLines = double(-LONG_MAX);
656 else
657 nLines = double(LONG_MAX);
659 else
660 nLines = pData->GetNotchDelta() * nScrollLines;
661 if ( nLines )
663 ImplHandleScroll( nullptr,
665 pData->IsHorz() ? pHScrl : pVScrl,
666 nLines );
667 bRet = true;
670 else
672 // Mobile / touch scrolling section
673 const Point & deltaPoint = rCmd.GetMousePosPixel();
675 double deltaXInPixels = double(deltaPoint.X());
676 double deltaYInPixels = double(deltaPoint.Y());
677 Size winSize = GetOutputSizePixel();
679 if(pHScrl)
681 double visSizeX = double(pHScrl->GetVisibleSize());
682 double ratioX = deltaXInPixels / double(winSize.getWidth());
683 long deltaXInLogic = long(visSizeX * ratioX);
684 // Touch need to work by pixels. Did not apply this to
685 // Android, as android code may require adaptations
686 // to work with this scrolling code
687 #ifndef IOS
688 long lineSizeX = pHScrl->GetLineSize();
690 if(lineSizeX)
692 deltaXInLogic /= lineSizeX;
694 else
696 deltaXInLogic = 0;
698 #endif
699 if ( deltaXInLogic)
701 #ifndef IOS
702 bool const isMultiplyByLineSize = true;
703 #else
704 bool const isMultiplyByLineSize = false;
705 #endif
706 lcl_HandleScrollHelper( pHScrl, deltaXInLogic, isMultiplyByLineSize );
707 bRet = true;
710 if(pVScrl)
712 double visSizeY = double(pVScrl->GetVisibleSize());
713 double ratioY = deltaYInPixels / double(winSize.getHeight());
714 long deltaYInLogic = long(visSizeY * ratioY);
716 // Touch need to work by pixels. Did not apply this to
717 // Android, as android code may require adaptations
718 // to work with this scrolling code
719 #ifndef IOS
720 long lineSizeY = pVScrl->GetLineSize();
721 if(lineSizeY)
723 deltaYInLogic /= lineSizeY;
725 else
727 deltaYInLogic = 0;
729 #endif
730 if ( deltaYInLogic )
732 #ifndef IOS
733 bool const isMultiplyByLineSize = true;
734 #else
735 bool const isMultiplyByLineSize = false;
736 #endif
737 lcl_HandleScrollHelper( pVScrl, deltaYInLogic, isMultiplyByLineSize );
739 bRet = true;
745 break;
747 case CommandEventId::Gesture:
749 if (pVScrl)
751 const CommandGestureData* pData = rCmd.GetGestureData();
752 if (pData->meEventType == GestureEventType::PanningBegin)
754 mpWindowImpl->mpFrameData->mnTouchPanPosition = pVScrl->GetThumbPos();
756 else if(pData->meEventType == GestureEventType::PanningUpdate)
758 long nOriginalPosition = mpWindowImpl->mpFrameData->mnTouchPanPosition;
759 pVScrl->DoScroll(nOriginalPosition + (pData->mfOffset / pVScrl->GetVisibleSize()));
761 if (pData->meEventType == GestureEventType::PanningEnd)
763 mpWindowImpl->mpFrameData->mnTouchPanPosition = -1;
765 bRet = true;
767 break;
770 case CommandEventId::AutoScroll:
772 const CommandScrollData* pData = rCmd.GetAutoScrollData();
773 if ( pData && (pData->GetDeltaX() || pData->GetDeltaY()) )
775 ImplHandleScroll( pHScrl, pData->GetDeltaX(),
776 pVScrl, pData->GetDeltaY() );
777 bRet = true;
780 break;
782 default:
783 break;
787 return bRet;
790 // Note that when called for CommandEventId::Wheel above, despite its name,
791 // pVScrl isn't necessarily the vertical scroll bar. Depending on
792 // whether the scroll is horizontal or vertical, it is either the
793 // horizontal or vertical scroll bar. nY is correspondingly either
794 // the horizontal or vertical scroll amount.
796 void Window::ImplHandleScroll( ScrollBar* pHScrl, double nX,
797 ScrollBar* pVScrl, double nY )
799 lcl_HandleScrollHelper( pHScrl, nX, true );
800 lcl_HandleScrollHelper( pVScrl, nY, true );
803 DockingManager* Window::GetDockingManager()
805 return ImplGetDockingManager();
808 void Window::EnableDocking( bool bEnable )
810 // update list of dockable windows
811 if( bEnable )
812 ImplGetDockingManager()->AddWindow( this );
813 else
814 ImplGetDockingManager()->RemoveWindow( this );
817 // retrieves the list of owner draw decorated windows for this window hierarchy
818 ::std::vector<VclPtr<vcl::Window> >& Window::ImplGetOwnerDrawList()
820 return ImplGetTopmostFrameWindow()->mpWindowImpl->mpFrameData->maOwnerDrawList;
823 void Window::SetHelpId( const OString& rHelpId )
825 mpWindowImpl->maHelpId = rHelpId;
828 const OString& Window::GetHelpId() const
830 return mpWindowImpl->maHelpId;
833 // --------- old inline methods ---------------
835 vcl::Window* Window::ImplGetWindow() const
837 if ( mpWindowImpl->mpClientWindow )
838 return mpWindowImpl->mpClientWindow;
839 else
840 return const_cast<vcl::Window*>(this);
843 ImplFrameData* Window::ImplGetFrameData()
845 return mpWindowImpl ? mpWindowImpl->mpFrameData : nullptr;
848 SalFrame* Window::ImplGetFrame() const
850 return mpWindowImpl ? mpWindowImpl->mpFrame : nullptr;
853 weld::Window* Window::GetFrameWeld() const
855 SalFrame* pFrame = ImplGetFrame();
856 return pFrame ? pFrame->GetFrameWeld() : nullptr;
859 vcl::Window* Window::ImplGetParent() const
861 return mpWindowImpl ? mpWindowImpl->mpParent.get() : nullptr;
864 vcl::Window* Window::ImplGetClientWindow() const
866 return mpWindowImpl ? mpWindowImpl->mpClientWindow.get() : nullptr;
869 vcl::Window* Window::ImplGetBorderWindow() const
871 return mpWindowImpl ? mpWindowImpl->mpBorderWindow.get() : nullptr;
874 vcl::Window* Window::ImplGetFirstOverlapWindow()
876 if ( mpWindowImpl->mbOverlapWin )
877 return this;
878 else
879 return mpWindowImpl->mpOverlapWindow;
882 const vcl::Window* Window::ImplGetFirstOverlapWindow() const
884 if ( mpWindowImpl->mbOverlapWin )
885 return this;
886 else
887 return mpWindowImpl->mpOverlapWindow;
890 vcl::Window* Window::ImplGetFrameWindow() const
892 return mpWindowImpl ? mpWindowImpl->mpFrameWindow.get() : nullptr;
895 bool Window::IsDockingWindow() const
897 return mpWindowImpl && mpWindowImpl->mbDockWin;
900 bool Window::ImplIsFloatingWindow() const
902 return mpWindowImpl && mpWindowImpl->mbFloatWin;
905 bool Window::ImplIsSplitter() const
907 return mpWindowImpl && mpWindowImpl->mbSplitter;
910 bool Window::ImplIsPushButton() const
912 return mpWindowImpl && mpWindowImpl->mbPushButton;
915 bool Window::ImplIsOverlapWindow() const
917 return mpWindowImpl && mpWindowImpl->mbOverlapWin;
920 void Window::ImplSetMouseTransparent( bool bTransparent )
922 if (mpWindowImpl)
923 mpWindowImpl->mbMouseTransparent = bTransparent;
926 Point Window::ImplOutputToFrame( const Point& rPos )
928 return Point( rPos.X()+mnOutOffX, rPos.Y()+mnOutOffY );
931 Point Window::ImplFrameToOutput( const Point& rPos )
933 return Point( rPos.X()-mnOutOffX, rPos.Y()-mnOutOffY );
936 void Window::SetCompoundControl( bool bCompound )
938 if (mpWindowImpl)
939 mpWindowImpl->mbCompoundControl = bCompound;
942 WinBits Window::GetStyle() const
944 return mpWindowImpl ? mpWindowImpl->mnStyle : 0;
947 WinBits Window::GetPrevStyle() const
949 return mpWindowImpl ? mpWindowImpl->mnPrevStyle : 0;
952 WindowExtendedStyle Window::GetExtendedStyle() const
954 return mpWindowImpl ? mpWindowImpl->mnExtendedStyle : WindowExtendedStyle::NONE;
957 void Window::SetType( WindowType nType )
959 if (mpWindowImpl)
960 mpWindowImpl->mnType = nType;
963 WindowType Window::GetType() const
965 if (mpWindowImpl)
966 return mpWindowImpl->mnType;
967 else
968 return WindowType::NONE;
971 Dialog* Window::GetParentDialog() const
973 const vcl::Window *pWindow = this;
975 while( pWindow )
977 if( pWindow->IsDialog() )
978 break;
980 pWindow = pWindow->GetParent();
983 return const_cast<Dialog *>(dynamic_cast<const Dialog*>(pWindow));
986 bool Window::IsSystemWindow() const
988 return mpWindowImpl && mpWindowImpl->mbSysWin;
991 bool Window::IsDialog() const
993 return mpWindowImpl && mpWindowImpl->mbDialog;
996 bool Window::IsMenuFloatingWindow() const
998 return mpWindowImpl && mpWindowImpl->mbMenuFloatingWindow;
1001 bool Window::IsToolbarFloatingWindow() const
1003 return mpWindowImpl && mpWindowImpl->mbToolbarFloatingWindow;
1006 void Window::EnableAllResize()
1008 mpWindowImpl->mbAllResize = true;
1011 void Window::EnableChildTransparentMode( bool bEnable )
1013 mpWindowImpl->mbChildTransparent = bEnable;
1016 bool Window::IsChildTransparentModeEnabled() const
1018 return mpWindowImpl && mpWindowImpl->mbChildTransparent;
1021 bool Window::IsMouseTransparent() const
1023 return mpWindowImpl && mpWindowImpl->mbMouseTransparent;
1026 bool Window::IsPaintTransparent() const
1028 return mpWindowImpl && mpWindowImpl->mbPaintTransparent;
1031 void Window::SetDialogControlStart( bool bStart )
1033 mpWindowImpl->mbDlgCtrlStart = bStart;
1036 bool Window::IsDialogControlStart() const
1038 return mpWindowImpl && mpWindowImpl->mbDlgCtrlStart;
1041 void Window::SetDialogControlFlags( DialogControlFlags nFlags )
1043 mpWindowImpl->mnDlgCtrlFlags = nFlags;
1046 DialogControlFlags Window::GetDialogControlFlags() const
1048 return mpWindowImpl->mnDlgCtrlFlags;
1051 const InputContext& Window::GetInputContext() const
1053 return mpWindowImpl->maInputContext;
1056 bool Window::IsControlFont() const
1058 return bool(mpWindowImpl->mpControlFont);
1061 const Color& Window::GetControlForeground() const
1063 return mpWindowImpl->maControlForeground;
1066 bool Window::IsControlForeground() const
1068 return mpWindowImpl->mbControlForeground;
1071 const Color& Window::GetControlBackground() const
1073 return mpWindowImpl->maControlBackground;
1076 bool Window::IsControlBackground() const
1078 return mpWindowImpl->mbControlBackground;
1081 bool Window::IsInPaint() const
1083 return mpWindowImpl && mpWindowImpl->mbInPaint;
1086 vcl::Window* Window::GetParent() const
1088 return mpWindowImpl ? mpWindowImpl->mpRealParent.get() : nullptr;
1091 bool Window::IsVisible() const
1093 return mpWindowImpl && mpWindowImpl->mbVisible;
1096 bool Window::IsReallyVisible() const
1098 return mpWindowImpl && mpWindowImpl->mbReallyVisible;
1101 bool Window::IsReallyShown() const
1103 return mpWindowImpl && mpWindowImpl->mbReallyShown;
1106 bool Window::IsInInitShow() const
1108 return mpWindowImpl->mbInInitShow;
1111 bool Window::IsEnabled() const
1113 return mpWindowImpl && !mpWindowImpl->mbDisabled;
1116 bool Window::IsInputEnabled() const
1118 return mpWindowImpl && !mpWindowImpl->mbInputDisabled;
1121 bool Window::IsAlwaysEnableInput() const
1123 return mpWindowImpl->meAlwaysInputMode == AlwaysInputEnabled;
1126 ActivateModeFlags Window::GetActivateMode() const
1128 return mpWindowImpl->mnActivateMode;
1132 bool Window::IsAlwaysOnTopEnabled() const
1134 return mpWindowImpl->mbAlwaysOnTop;
1137 bool Window::IsDefaultPos() const
1139 return mpWindowImpl->mbDefPos;
1142 bool Window::IsDefaultSize() const
1144 return mpWindowImpl->mbDefSize;
1147 Point Window::GetOffsetPixelFrom(const vcl::Window& rWindow) const
1149 return Point(GetOutOffXPixel() - rWindow.GetOutOffXPixel(), GetOutOffYPixel() - rWindow.GetOutOffYPixel());
1152 void Window::EnablePaint( bool bEnable )
1154 mpWindowImpl->mbPaintDisabled = !bEnable;
1157 bool Window::IsPaintEnabled() const
1159 return !mpWindowImpl->mbPaintDisabled;
1162 bool Window::IsUpdateMode() const
1164 return !mpWindowImpl->mbNoUpdate;
1167 void Window::SetParentUpdateMode( bool bUpdate )
1169 mpWindowImpl->mbNoParentUpdate = !bUpdate;
1172 bool Window::IsActive() const
1174 return mpWindowImpl->mbActive;
1177 GetFocusFlags Window::GetGetFocusFlags() const
1179 return mpWindowImpl->mnGetFocusFlags;
1182 bool Window::IsCompoundControl() const
1184 return mpWindowImpl->mbCompoundControl;
1187 bool Window::IsWait() const
1189 return (mpWindowImpl->mnWaitCount != 0);
1192 vcl::Cursor* Window::GetCursor() const
1194 if (!mpWindowImpl)
1195 return nullptr;
1196 return mpWindowImpl->mpCursor;
1199 const Fraction& Window::GetZoom() const
1201 return mpWindowImpl->maZoom;
1204 bool Window::IsZoom() const
1206 return mpWindowImpl->maZoom.GetNumerator() != mpWindowImpl->maZoom.GetDenominator();
1209 void Window::SetHelpText( const OUString& rHelpText )
1211 mpWindowImpl->maHelpText = rHelpText;
1212 mpWindowImpl->mbHelpTextDynamic = true;
1215 void Window::SetQuickHelpText( const OUString& rHelpText )
1217 if (mpWindowImpl)
1218 mpWindowImpl->maQuickHelpText = rHelpText;
1221 const OUString& Window::GetQuickHelpText() const
1223 return mpWindowImpl->maQuickHelpText;
1226 bool Window::IsCreatedWithToolkit() const
1228 return mpWindowImpl->mbCreatedWithToolkit;
1231 void Window::SetCreatedWithToolkit( bool b )
1233 mpWindowImpl->mbCreatedWithToolkit = b;
1236 PointerStyle Window::GetPointer() const
1238 return mpWindowImpl->maPointer;
1241 VCLXWindow* Window::GetWindowPeer() const
1243 return mpWindowImpl ? mpWindowImpl->mpVCLXWindow : nullptr;
1246 void Window::SetPosPixel( const Point& rNewPos )
1248 setPosSizePixel( rNewPos.X(), rNewPos.Y(), 0, 0, PosSizeFlags::Pos );
1251 void Window::SetSizePixel( const Size& rNewSize )
1253 setPosSizePixel( 0, 0, rNewSize.Width(), rNewSize.Height(),
1254 PosSizeFlags::Size );
1257 void Window::SetPosSizePixel( const Point& rNewPos, const Size& rNewSize )
1259 setPosSizePixel( rNewPos.X(), rNewPos.Y(),
1260 rNewSize.Width(), rNewSize.Height());
1263 void Window::SetOutputSizePixel( const Size& rNewSize )
1265 SetSizePixel( Size( rNewSize.Width()+mpWindowImpl->mnLeftBorder+mpWindowImpl->mnRightBorder,
1266 rNewSize.Height()+mpWindowImpl->mnTopBorder+mpWindowImpl->mnBottomBorder ) );
1269 //When a widget wants to renegotiate layout, get toplevel parent dialog and call
1270 //resize on it. Mark all intermediate containers (or container-alike) widgets
1271 //as dirty for the size remains unchanged, but layout changed circumstances
1272 namespace
1274 bool queue_ungrouped_resize(vcl::Window const *pOrigWindow)
1276 bool bSomeoneCares = false;
1278 vcl::Window *pWindow = pOrigWindow->GetParent();
1279 if (pWindow)
1281 if (isContainerWindow(*pWindow))
1283 bSomeoneCares = true;
1285 else if (pWindow->GetType() == WindowType::TABCONTROL)
1287 bSomeoneCares = true;
1289 pWindow->queue_resize();
1292 return bSomeoneCares;
1296 void Window::InvalidateSizeCache()
1298 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1299 pWindowImpl->mnOptimalWidthCache = -1;
1300 pWindowImpl->mnOptimalHeightCache = -1;
1303 void Window::queue_resize(StateChangedType eReason)
1305 if (IsDisposed())
1306 return;
1308 bool bSomeoneCares = queue_ungrouped_resize(this);
1310 if (eReason != StateChangedType::Visible)
1312 InvalidateSizeCache();
1315 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1316 if (pWindowImpl->m_xSizeGroup && pWindowImpl->m_xSizeGroup->get_mode() != VclSizeGroupMode::NONE)
1318 std::set<VclPtr<vcl::Window> > &rWindows = pWindowImpl->m_xSizeGroup->get_widgets();
1319 for (VclPtr<vcl::Window> const & pOther : rWindows)
1321 if (pOther == this)
1322 continue;
1323 queue_ungrouped_resize(pOther);
1327 if (bSomeoneCares && !mpWindowImpl->mbInDispose)
1329 //fdo#57090 force a resync of the borders of the borderwindow onto this
1330 //window in case they have changed
1331 vcl::Window* pBorderWindow = ImplGetBorderWindow();
1332 if (pBorderWindow)
1333 pBorderWindow->Resize();
1336 if (VclPtr<vcl::Window> pParent = GetParentWithLOKNotifier())
1338 if (!pParent->IsInInitShow())
1339 LogicInvalidate(nullptr);
1343 namespace
1345 VclAlign toAlign(const OUString &rValue)
1347 VclAlign eRet = VclAlign::Fill;
1349 if (rValue == "fill")
1350 eRet = VclAlign::Fill;
1351 else if (rValue == "start")
1352 eRet = VclAlign::Start;
1353 else if (rValue == "end")
1354 eRet = VclAlign::End;
1355 else if (rValue == "center")
1356 eRet = VclAlign::Center;
1357 return eRet;
1361 bool Window::set_font_attribute(const OString &rKey, const OUString &rValue)
1363 if (rKey == "weight")
1365 vcl::Font aFont(GetControlFont());
1366 if (rValue == "thin")
1367 aFont.SetWeight(WEIGHT_THIN);
1368 else if (rValue == "ultralight")
1369 aFont.SetWeight(WEIGHT_ULTRALIGHT);
1370 else if (rValue == "light")
1371 aFont.SetWeight(WEIGHT_LIGHT);
1372 else if (rValue == "book")
1373 aFont.SetWeight(WEIGHT_SEMILIGHT);
1374 else if (rValue == "normal")
1375 aFont.SetWeight(WEIGHT_NORMAL);
1376 else if (rValue == "medium")
1377 aFont.SetWeight(WEIGHT_MEDIUM);
1378 else if (rValue == "semibold")
1379 aFont.SetWeight(WEIGHT_SEMIBOLD);
1380 else if (rValue == "bold")
1381 aFont.SetWeight(WEIGHT_BOLD);
1382 else if (rValue == "ultrabold")
1383 aFont.SetWeight(WEIGHT_ULTRABOLD);
1384 else
1385 aFont.SetWeight(WEIGHT_BLACK);
1386 SetControlFont(aFont);
1388 else if (rKey == "style")
1390 vcl::Font aFont(GetControlFont());
1391 if (rValue == "normal")
1392 aFont.SetItalic(ITALIC_NONE);
1393 else if (rValue == "oblique")
1394 aFont.SetItalic(ITALIC_OBLIQUE);
1395 else if (rValue == "italic")
1396 aFont.SetItalic(ITALIC_NORMAL);
1397 SetControlFont(aFont);
1399 else if (rKey == "underline")
1401 vcl::Font aFont(GetControlFont());
1402 aFont.SetUnderline(toBool(rValue) ? LINESTYLE_SINGLE : LINESTYLE_NONE);
1403 SetControlFont(aFont);
1405 else if (rKey == "size")
1407 vcl::Font aFont(GetControlFont());
1408 sal_Int32 nHeight = rValue.toInt32() / 1000;
1409 aFont.SetFontHeight(nHeight);
1410 SetControlFont(aFont);
1412 else
1414 SAL_INFO("vcl.layout", "unhandled font attribute: " << rKey);
1415 return false;
1417 return true;
1420 bool Window::set_property(const OString &rKey, const OUString &rValue)
1422 if ((rKey == "label") || (rKey == "title") || (rKey == "text") )
1424 SetText(BuilderUtils::convertMnemonicMarkup(rValue));
1426 else if (rKey == "visible")
1427 Show(toBool(rValue));
1428 else if (rKey == "sensitive")
1429 Enable(toBool(rValue));
1430 else if (rKey == "resizable")
1432 WinBits nBits = GetStyle();
1433 nBits &= ~WB_SIZEABLE;
1434 if (toBool(rValue))
1435 nBits |= WB_SIZEABLE;
1436 SetStyle(nBits);
1438 else if (rKey == "xalign")
1440 WinBits nBits = GetStyle();
1441 nBits &= ~(WB_LEFT | WB_CENTER | WB_RIGHT);
1443 float f = rValue.toFloat();
1444 if (f == 0.0)
1445 nBits |= WB_LEFT;
1446 else if (f == 1.0)
1447 nBits |= WB_RIGHT;
1448 else if (f == 0.5)
1449 nBits |= WB_CENTER;
1451 SetStyle(nBits);
1453 else if (rKey == "justification")
1455 WinBits nBits = GetStyle();
1456 nBits &= ~(WB_LEFT | WB_CENTER | WB_RIGHT);
1458 if (rValue == "left")
1459 nBits |= WB_LEFT;
1460 else if (rValue == "right")
1461 nBits |= WB_RIGHT;
1462 else if (rValue == "center")
1463 nBits |= WB_CENTER;
1465 SetStyle(nBits);
1467 else if (rKey == "yalign")
1469 WinBits nBits = GetStyle();
1470 nBits &= ~(WB_TOP | WB_VCENTER | WB_BOTTOM);
1472 float f = rValue.toFloat();
1473 if (f == 0.0)
1474 nBits |= WB_TOP;
1475 else if (f == 1.0)
1476 nBits |= WB_BOTTOM;
1477 else if (f == 0.5)
1478 nBits |= WB_CENTER;
1480 SetStyle(nBits);
1482 else if (rKey == "wrap")
1484 WinBits nBits = GetStyle();
1485 nBits &= ~WB_WORDBREAK;
1486 if (toBool(rValue))
1487 nBits |= WB_WORDBREAK;
1488 SetStyle(nBits);
1490 else if (rKey == "height-request")
1491 set_height_request(rValue.toInt32());
1492 else if (rKey == "width-request")
1493 set_width_request(rValue.toInt32());
1494 else if (rKey == "hexpand")
1495 set_hexpand(toBool(rValue));
1496 else if (rKey == "vexpand")
1497 set_vexpand(toBool(rValue));
1498 else if (rKey == "halign")
1499 set_halign(toAlign(rValue));
1500 else if (rKey == "valign")
1501 set_valign(toAlign(rValue));
1502 else if (rKey == "tooltip-markup")
1503 SetQuickHelpText(rValue);
1504 else if (rKey == "tooltip-text")
1505 SetQuickHelpText(rValue);
1506 else if (rKey == "border-width")
1507 set_border_width(rValue.toInt32());
1508 else if (rKey == "margin-left")
1509 set_margin_left(rValue.toInt32());
1510 else if (rKey == "margin-right")
1511 set_margin_right(rValue.toInt32());
1512 else if (rKey == "margin-top")
1513 set_margin_top(rValue.toInt32());
1514 else if (rKey == "margin-bottom")
1515 set_margin_bottom(rValue.toInt32());
1516 else if (rKey == "hscrollbar-policy")
1518 WinBits nBits = GetStyle();
1519 nBits &= ~(WB_AUTOHSCROLL|WB_HSCROLL);
1520 if (rValue == "always")
1521 nBits |= WB_HSCROLL;
1522 else if (rValue == "automatic")
1523 nBits |= WB_AUTOHSCROLL;
1524 SetStyle(nBits);
1526 else if (rKey == "vscrollbar-policy")
1528 WinBits nBits = GetStyle();
1529 nBits &= ~(WB_AUTOVSCROLL|WB_VSCROLL);
1530 if (rValue == "always")
1531 nBits |= WB_VSCROLL;
1532 else if (rValue == "automatic")
1533 nBits |= WB_AUTOVSCROLL;
1534 SetStyle(nBits);
1536 else if (rKey == "accessible-name")
1538 SetAccessibleName(rValue);
1540 else if (rKey == "accessible-description")
1542 SetAccessibleDescription(rValue);
1544 else if (rKey == "accessible-role")
1546 sal_Int16 role = BuilderUtils::getRoleFromName(rValue.toUtf8());
1547 if (role != com::sun::star::accessibility::AccessibleRole::UNKNOWN)
1548 SetAccessibleRole(role);
1550 else if (rKey == "use-markup")
1552 //https://live.gnome.org/GnomeGoals/RemoveMarkupInMessages
1553 SAL_WARN_IF(toBool(rValue), "vcl.layout", "Use pango attributes instead of mark-up");
1555 else if (rKey == "has-focus")
1557 if (toBool(rValue))
1558 GrabFocus();
1560 else if (rKey == "can-focus")
1562 WinBits nBits = GetStyle();
1563 nBits &= ~(WB_TABSTOP|WB_NOTABSTOP);
1564 if (toBool(rValue))
1565 nBits |= WB_TABSTOP;
1566 else
1567 nBits |= WB_NOTABSTOP;
1568 SetStyle(nBits);
1570 else
1572 SAL_INFO("vcl.layout", "unhandled property: " << rKey);
1573 return false;
1575 return true;
1578 void Window::set_height_request(sal_Int32 nHeightRequest)
1580 if (!mpWindowImpl)
1581 return;
1583 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1585 if ( pWindowImpl->mnHeightRequest != nHeightRequest )
1587 pWindowImpl->mnHeightRequest = nHeightRequest;
1588 queue_resize();
1592 void Window::set_width_request(sal_Int32 nWidthRequest)
1594 if (!mpWindowImpl)
1595 return;
1597 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1599 if ( pWindowImpl->mnWidthRequest != nWidthRequest )
1601 pWindowImpl->mnWidthRequest = nWidthRequest;
1602 queue_resize();
1606 Size Window::get_ungrouped_preferred_size() const
1608 Size aRet(get_width_request(), get_height_request());
1609 if (aRet.Width() == -1 || aRet.Height() == -1)
1611 //cache gets blown away by queue_resize
1612 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1613 if (pWindowImpl->mnOptimalWidthCache == -1 || pWindowImpl->mnOptimalHeightCache == -1)
1615 Size aOptimal(GetOptimalSize());
1616 pWindowImpl->mnOptimalWidthCache = aOptimal.Width();
1617 pWindowImpl->mnOptimalHeightCache = aOptimal.Height();
1620 if (aRet.Width() == -1)
1621 aRet.setWidth( pWindowImpl->mnOptimalWidthCache );
1622 if (aRet.Height() == -1)
1623 aRet.setHeight( pWindowImpl->mnOptimalHeightCache );
1625 return aRet;
1628 Size Window::get_preferred_size() const
1630 Size aRet(get_ungrouped_preferred_size());
1632 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1633 if (pWindowImpl->m_xSizeGroup)
1635 const VclSizeGroupMode eMode = pWindowImpl->m_xSizeGroup->get_mode();
1636 if (eMode != VclSizeGroupMode::NONE)
1638 const bool bIgnoreInHidden = pWindowImpl->m_xSizeGroup->get_ignore_hidden();
1639 const std::set<VclPtr<vcl::Window> > &rWindows = pWindowImpl->m_xSizeGroup->get_widgets();
1640 for (auto const& window : rWindows)
1642 const vcl::Window *pOther = window;
1643 if (pOther == this)
1644 continue;
1645 if (bIgnoreInHidden && !pOther->IsVisible())
1646 continue;
1647 Size aOtherSize = pOther->get_ungrouped_preferred_size();
1648 if (eMode == VclSizeGroupMode::Both || eMode == VclSizeGroupMode::Horizontal)
1649 aRet.setWidth( std::max(aRet.Width(), aOtherSize.Width()) );
1650 if (eMode == VclSizeGroupMode::Both || eMode == VclSizeGroupMode::Vertical)
1651 aRet.setHeight( std::max(aRet.Height(), aOtherSize.Height()) );
1656 return aRet;
1659 VclAlign Window::get_halign() const
1661 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1662 return pWindowImpl->meHalign;
1665 void Window::set_halign(VclAlign eAlign)
1667 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1668 pWindowImpl->meHalign = eAlign;
1671 VclAlign Window::get_valign() const
1673 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1674 return pWindowImpl->meValign;
1677 void Window::set_valign(VclAlign eAlign)
1679 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1680 pWindowImpl->meValign = eAlign;
1683 bool Window::get_hexpand() const
1685 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1686 return pWindowImpl->mbHexpand;
1689 void Window::set_hexpand(bool bExpand)
1691 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1692 pWindowImpl->mbHexpand = bExpand;
1695 bool Window::get_vexpand() const
1697 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1698 return pWindowImpl->mbVexpand;
1701 void Window::set_vexpand(bool bExpand)
1703 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1704 pWindowImpl->mbVexpand = bExpand;
1707 bool Window::get_expand() const
1709 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1710 return pWindowImpl->mbExpand;
1713 void Window::set_expand(bool bExpand)
1715 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1716 pWindowImpl->mbExpand = bExpand;
1719 VclPackType Window::get_pack_type() const
1721 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1722 return pWindowImpl->mePackType;
1725 void Window::set_pack_type(VclPackType ePackType)
1727 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1728 pWindowImpl->mePackType = ePackType;
1731 sal_Int32 Window::get_padding() const
1733 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1734 return pWindowImpl->mnPadding;
1737 void Window::set_padding(sal_Int32 nPadding)
1739 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1740 pWindowImpl->mnPadding = nPadding;
1743 bool Window::get_fill() const
1745 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1746 return pWindowImpl->mbFill;
1749 void Window::set_fill(bool bFill)
1751 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1752 pWindowImpl->mbFill = bFill;
1755 sal_Int32 Window::get_grid_width() const
1757 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1758 return pWindowImpl->mnGridWidth;
1761 void Window::set_grid_width(sal_Int32 nCols)
1763 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1764 pWindowImpl->mnGridWidth = nCols;
1767 sal_Int32 Window::get_grid_left_attach() const
1769 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1770 return pWindowImpl->mnGridLeftAttach;
1773 void Window::set_grid_left_attach(sal_Int32 nAttach)
1775 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1776 pWindowImpl->mnGridLeftAttach = nAttach;
1779 sal_Int32 Window::get_grid_height() const
1781 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1782 return pWindowImpl->mnGridHeight;
1785 void Window::set_grid_height(sal_Int32 nRows)
1787 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1788 pWindowImpl->mnGridHeight = nRows;
1791 sal_Int32 Window::get_grid_top_attach() const
1793 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1794 return pWindowImpl->mnGridTopAttach;
1797 void Window::set_grid_top_attach(sal_Int32 nAttach)
1799 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1800 pWindowImpl->mnGridTopAttach = nAttach;
1803 void Window::set_border_width(sal_Int32 nBorderWidth)
1805 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1806 pWindowImpl->mnBorderWidth = nBorderWidth;
1809 sal_Int32 Window::get_border_width() const
1811 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1812 return pWindowImpl->mnBorderWidth;
1815 void Window::set_margin_left(sal_Int32 nWidth)
1817 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1818 if (pWindowImpl->mnMarginLeft != nWidth)
1820 pWindowImpl->mnMarginLeft = nWidth;
1821 queue_resize();
1825 sal_Int32 Window::get_margin_left() const
1827 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1828 return pWindowImpl->mnMarginLeft;
1831 void Window::set_margin_right(sal_Int32 nWidth)
1833 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1834 if (pWindowImpl->mnMarginRight != nWidth)
1836 pWindowImpl->mnMarginRight = nWidth;
1837 queue_resize();
1841 sal_Int32 Window::get_margin_right() const
1843 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1844 return pWindowImpl->mnMarginRight;
1847 void Window::set_margin_top(sal_Int32 nWidth)
1849 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1850 if (pWindowImpl->mnMarginTop != nWidth)
1852 pWindowImpl->mnMarginTop = nWidth;
1853 queue_resize();
1857 sal_Int32 Window::get_margin_top() const
1859 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1860 return pWindowImpl->mnMarginTop;
1863 void Window::set_margin_bottom(sal_Int32 nWidth)
1865 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1866 if (pWindowImpl->mnMarginBottom != nWidth)
1868 pWindowImpl->mnMarginBottom = nWidth;
1869 queue_resize();
1873 sal_Int32 Window::get_margin_bottom() const
1875 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1876 return pWindowImpl->mnMarginBottom;
1879 sal_Int32 Window::get_height_request() const
1881 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1882 return pWindowImpl->mnHeightRequest;
1885 sal_Int32 Window::get_width_request() const
1887 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1888 return pWindowImpl->mnWidthRequest;
1891 bool Window::get_secondary() const
1893 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1894 return pWindowImpl->mbSecondary;
1897 void Window::set_secondary(bool bSecondary)
1899 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1900 pWindowImpl->mbSecondary = bSecondary;
1903 bool Window::get_non_homogeneous() const
1905 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1906 return pWindowImpl->mbNonHomogeneous;
1909 void Window::set_non_homogeneous(bool bNonHomogeneous)
1911 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1912 pWindowImpl->mbNonHomogeneous = bNonHomogeneous;
1915 void Window::add_to_size_group(const std::shared_ptr<VclSizeGroup>& xGroup)
1917 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1918 //To-Do, multiple groups
1919 pWindowImpl->m_xSizeGroup = xGroup;
1920 pWindowImpl->m_xSizeGroup->insert(this);
1921 if (VclSizeGroupMode::NONE != pWindowImpl->m_xSizeGroup->get_mode())
1922 queue_resize();
1925 void Window::remove_from_all_size_groups()
1927 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1928 //To-Do, multiple groups
1929 if (pWindowImpl->m_xSizeGroup)
1931 if (VclSizeGroupMode::NONE != pWindowImpl->m_xSizeGroup->get_mode())
1932 queue_resize();
1933 pWindowImpl->m_xSizeGroup->erase(this);
1934 pWindowImpl->m_xSizeGroup.reset();
1938 void Window::add_mnemonic_label(FixedText *pLabel)
1940 std::vector<VclPtr<FixedText> >& v = mpWindowImpl->m_aMnemonicLabels;
1941 if (std::find(v.begin(), v.end(), VclPtr<FixedText>(pLabel)) != v.end())
1942 return;
1943 v.emplace_back(pLabel);
1944 pLabel->set_mnemonic_widget(this);
1947 void Window::remove_mnemonic_label(FixedText *pLabel)
1949 std::vector<VclPtr<FixedText> >& v = mpWindowImpl->m_aMnemonicLabels;
1950 auto aFind = std::find(v.begin(), v.end(), VclPtr<FixedText>(pLabel));
1951 if (aFind == v.end())
1952 return;
1953 v.erase(aFind);
1954 pLabel->set_mnemonic_widget(nullptr);
1957 const std::vector<VclPtr<FixedText> >& Window::list_mnemonic_labels() const
1959 return mpWindowImpl->m_aMnemonicLabels;
1962 void Window::AddExtraAccessibleRelation(const css::accessibility::AccessibleRelation &rRelation)
1964 mpWindowImpl->m_aExtraAccessibleRelations.push_back(rRelation);
1967 const std::vector<css::accessibility::AccessibleRelation>& Window::GetExtraAccessibleRelations() const
1969 return mpWindowImpl->m_aExtraAccessibleRelations;
1972 void Window::ClearExtraAccessibleRelations()
1974 mpWindowImpl->m_aExtraAccessibleRelations.clear();
1977 } /* namespace vcl */
1979 void DrawFocusRect(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
1981 const int nBorder = 1;
1982 rRenderContext.Invert(tools::Rectangle(Point(rRect.Left(), rRect.Top()), Size(rRect.GetWidth(), nBorder)), InvertFlags::N50);
1983 rRenderContext.Invert(tools::Rectangle(Point(rRect.Left(), rRect.Bottom()-nBorder+1), Size(rRect.GetWidth(), nBorder)), InvertFlags::N50);
1984 rRenderContext.Invert(tools::Rectangle(Point(rRect.Left(), rRect.Top()+nBorder), Size(nBorder, rRect.GetHeight()-(nBorder*2))), InvertFlags::N50);
1985 rRenderContext.Invert(tools::Rectangle(Point(rRect.Right()-nBorder+1, rRect.Top()+nBorder), Size(nBorder, rRect.GetHeight()-(nBorder*2))), InvertFlags::N50);
1988 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */