nss: upgrade to release 3.73
[LibreOffice.git] / vcl / source / window / window2.cxx
blob75885cb43d98390b8659d24aee2d1dc25ec86d6a
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/toolkit/dialog.hxx>
26 #include <vcl/event.hxx>
27 #include <vcl/toolkit/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 tools::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->mpWinData->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->mpWinData->mpTrackWin.get() != this )
250 if ( pSVData->mpWinData->mpTrackWin )
251 pSVData->mpWinData->mpTrackWin->EndTracking( TrackingEventFlags::Cancel );
254 if ( nFlags & (StartTrackingFlags::ScrollRepeat | StartTrackingFlags::ButtonRepeat) )
256 pSVData->mpWinData->mpTrackTimer = new AutoTimer;
258 if ( nFlags & StartTrackingFlags::ScrollRepeat )
259 pSVData->mpWinData->mpTrackTimer->SetTimeout( MouseSettings::GetScrollRepeat() );
260 else
261 pSVData->mpWinData->mpTrackTimer->SetTimeout( MouseSettings::GetButtonStartRepeat() );
262 pSVData->mpWinData->mpTrackTimer->SetInvokeHandler( LINK( this, Window, ImplTrackTimerHdl ) );
263 pSVData->mpWinData->mpTrackTimer->SetDebugName( "vcl::Window pSVData->mpWinData->mpTrackTimer" );
264 pSVData->mpWinData->mpTrackTimer->Start();
267 pSVData->mpWinData->mpTrackWin = this;
268 pSVData->mpWinData->mnTrackFlags = nFlags;
269 CaptureMouse();
272 void Window::EndTracking( TrackingEventFlags nFlags )
274 ImplSVData* pSVData = ImplGetSVData();
276 if ( pSVData->mpWinData->mpTrackWin.get() != this )
277 return;
279 if ( pSVData->mpWinData->mpTrackTimer )
281 delete pSVData->mpWinData->mpTrackTimer;
282 pSVData->mpWinData->mpTrackTimer = nullptr;
285 pSVData->mpWinData->mpTrackWin = nullptr;
286 pSVData->mpWinData->mnTrackFlags = StartTrackingFlags::NONE;
287 ReleaseMouse();
289 // call EndTracking if required
291 Point aMousePos( mpWindowImpl->mpFrameData->mnLastMouseX, mpWindowImpl->mpFrameData->mnLastMouseY );
292 if( ImplIsAntiparallel() )
294 // re-mirror frame pos at pChild
295 const OutputDevice *pOutDev = GetOutDev();
296 pOutDev->ReMirror( aMousePos );
299 MouseEvent aMEvt( ImplFrameToOutput( aMousePos ),
300 mpWindowImpl->mpFrameData->mnClickCount, MouseEventModifiers::NONE,
301 mpWindowImpl->mpFrameData->mnMouseCode,
302 mpWindowImpl->mpFrameData->mnMouseCode );
303 TrackingEvent aTEvt( aMEvt, nFlags | TrackingEventFlags::End );
304 // CompatTracking effectively
305 if (!mpWindowImpl || mpWindowImpl->mbInDispose)
306 return Window::Tracking( aTEvt );
307 else
308 return Tracking( aTEvt );
312 bool Window::IsTracking() const
314 return (ImplGetSVData()->mpWinData->mpTrackWin == this);
317 void Window::StartAutoScroll( StartAutoScrollFlags nFlags )
319 ImplSVData* pSVData = ImplGetSVData();
321 if ( pSVData->mpWinData->mpAutoScrollWin.get() != this )
323 if ( pSVData->mpWinData->mpAutoScrollWin )
324 pSVData->mpWinData->mpAutoScrollWin->EndAutoScroll();
327 pSVData->mpWinData->mpAutoScrollWin = this;
328 pSVData->mpWinData->mnAutoScrollFlags = nFlags;
329 pSVData->maAppData.mpWheelWindow = VclPtr<ImplWheelWindow>::Create( this );
332 void Window::EndAutoScroll()
334 ImplSVData* pSVData = ImplGetSVData();
336 if ( pSVData->mpWinData->mpAutoScrollWin.get() == this )
338 pSVData->mpWinData->mpAutoScrollWin = nullptr;
339 pSVData->mpWinData->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->mpWinData->mpFocusWin )
351 return pSVData->mpWinData->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 tools::Long WinFloatRound( double fVal )
376 return( fVal > 0.0 ? static_cast<tools::Long>( fVal + 0.5 ) : -static_cast<tools::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 tools::Long Window::CalcZoom( tools::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 tools::Long Window::GetDrawPixel( OutputDevice const * pDev, tools::Long nPixels ) const
565 tools::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() )
580 return;
582 tools::Long nNewPos = pScrl->GetThumbPos();
584 if ( nN == double(-LONG_MAX) )
585 nNewPos += pScrl->GetPageSize();
586 else if ( nN == double(LONG_MAX) )
587 nNewPos -= pScrl->GetPageSize();
588 else
590 // allowing both chunked and continuous scrolling
591 if(isMultiplyByLineSize){
592 nN*=pScrl->GetLineSize();
595 const double fVal = nNewPos - nN;
597 if ( !o3tl::convertsToAtLeast(fVal, LONG_MIN) )
598 nNewPos = LONG_MIN;
599 else if ( !o3tl::convertsToAtMost(fVal, LONG_MAX) )
600 nNewPos = LONG_MAX;
601 else
602 nNewPos = static_cast<tools::Long>(fVal);
605 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 tools::Long deltaXInLogic = tools::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 tools::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 tools::Long deltaYInLogic = tools::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 tools::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 tools::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::GetFrameWindow() const
861 SalFrame* pFrame = ImplGetFrame();
862 return pFrame ? pFrame->GetWindow() : nullptr;
865 vcl::Window* Window::ImplGetParent() const
867 return mpWindowImpl ? mpWindowImpl->mpParent.get() : nullptr;
870 vcl::Window* Window::ImplGetClientWindow() const
872 return mpWindowImpl ? mpWindowImpl->mpClientWindow.get() : nullptr;
875 vcl::Window* Window::ImplGetBorderWindow() const
877 return mpWindowImpl ? mpWindowImpl->mpBorderWindow.get() : nullptr;
880 vcl::Window* Window::ImplGetFirstOverlapWindow()
882 if (!mpWindowImpl)
884 return nullptr;
887 if ( mpWindowImpl->mbOverlapWin )
888 return this;
889 else
890 return mpWindowImpl->mpOverlapWindow;
893 const vcl::Window* Window::ImplGetFirstOverlapWindow() const
895 if ( mpWindowImpl->mbOverlapWin )
896 return this;
897 else
898 return mpWindowImpl->mpOverlapWindow;
901 vcl::Window* Window::ImplGetFrameWindow() const
903 return mpWindowImpl ? mpWindowImpl->mpFrameWindow.get() : nullptr;
906 bool Window::IsDockingWindow() const
908 return mpWindowImpl && mpWindowImpl->mbDockWin;
911 bool Window::ImplIsFloatingWindow() const
913 return mpWindowImpl && mpWindowImpl->mbFloatWin;
916 bool Window::ImplIsSplitter() const
918 return mpWindowImpl && mpWindowImpl->mbSplitter;
921 bool Window::ImplIsPushButton() const
923 return mpWindowImpl && mpWindowImpl->mbPushButton;
926 bool Window::ImplIsOverlapWindow() const
928 return mpWindowImpl && mpWindowImpl->mbOverlapWin;
931 void Window::ImplSetMouseTransparent( bool bTransparent )
933 if (mpWindowImpl)
934 mpWindowImpl->mbMouseTransparent = bTransparent;
937 Point Window::ImplOutputToFrame( const Point& rPos )
939 return Point( rPos.X()+mnOutOffX, rPos.Y()+mnOutOffY );
942 Point Window::ImplFrameToOutput( const Point& rPos )
944 return Point( rPos.X()-mnOutOffX, rPos.Y()-mnOutOffY );
947 void Window::SetCompoundControl( bool bCompound )
949 if (mpWindowImpl)
950 mpWindowImpl->mbCompoundControl = bCompound;
953 WinBits Window::GetStyle() const
955 return mpWindowImpl ? mpWindowImpl->mnStyle : 0;
958 WinBits Window::GetPrevStyle() const
960 return mpWindowImpl ? mpWindowImpl->mnPrevStyle : 0;
963 WindowExtendedStyle Window::GetExtendedStyle() const
965 return mpWindowImpl ? mpWindowImpl->mnExtendedStyle : WindowExtendedStyle::NONE;
968 void Window::SetType( WindowType nType )
970 if (mpWindowImpl)
971 mpWindowImpl->mnType = nType;
974 WindowType Window::GetType() const
976 if (mpWindowImpl)
977 return mpWindowImpl->mnType;
978 else
979 return WindowType::NONE;
982 Dialog* Window::GetParentDialog() const
984 const vcl::Window *pWindow = this;
986 while( pWindow )
988 if( pWindow->IsDialog() )
989 break;
991 pWindow = pWindow->GetParent();
994 return const_cast<Dialog *>(dynamic_cast<const Dialog*>(pWindow));
997 bool Window::IsSystemWindow() const
999 return mpWindowImpl && mpWindowImpl->mbSysWin;
1002 bool Window::IsDialog() const
1004 return mpWindowImpl && mpWindowImpl->mbDialog;
1007 bool Window::IsMenuFloatingWindow() const
1009 return mpWindowImpl && mpWindowImpl->mbMenuFloatingWindow;
1012 bool Window::IsToolbarFloatingWindow() const
1014 return mpWindowImpl && mpWindowImpl->mbToolbarFloatingWindow;
1017 void Window::EnableAllResize()
1019 mpWindowImpl->mbAllResize = true;
1022 void Window::EnableChildTransparentMode( bool bEnable )
1024 mpWindowImpl->mbChildTransparent = bEnable;
1027 bool Window::IsChildTransparentModeEnabled() const
1029 return mpWindowImpl && mpWindowImpl->mbChildTransparent;
1032 bool Window::IsMouseTransparent() const
1034 return mpWindowImpl && mpWindowImpl->mbMouseTransparent;
1037 bool Window::IsPaintTransparent() const
1039 return mpWindowImpl && mpWindowImpl->mbPaintTransparent;
1042 void Window::SetDialogControlStart( bool bStart )
1044 mpWindowImpl->mbDlgCtrlStart = bStart;
1047 bool Window::IsDialogControlStart() const
1049 return mpWindowImpl && mpWindowImpl->mbDlgCtrlStart;
1052 void Window::SetDialogControlFlags( DialogControlFlags nFlags )
1054 mpWindowImpl->mnDlgCtrlFlags = nFlags;
1057 DialogControlFlags Window::GetDialogControlFlags() const
1059 return mpWindowImpl->mnDlgCtrlFlags;
1062 const InputContext& Window::GetInputContext() const
1064 return mpWindowImpl->maInputContext;
1067 bool Window::IsControlFont() const
1069 return bool(mpWindowImpl->mpControlFont);
1072 const Color& Window::GetControlForeground() const
1074 return mpWindowImpl->maControlForeground;
1077 bool Window::IsControlForeground() const
1079 return mpWindowImpl->mbControlForeground;
1082 const Color& Window::GetControlBackground() const
1084 return mpWindowImpl->maControlBackground;
1087 bool Window::IsControlBackground() const
1089 return mpWindowImpl->mbControlBackground;
1092 bool Window::IsInPaint() const
1094 return mpWindowImpl && mpWindowImpl->mbInPaint;
1097 vcl::Window* Window::GetParent() const
1099 return mpWindowImpl ? mpWindowImpl->mpRealParent.get() : nullptr;
1102 bool Window::IsVisible() const
1104 return mpWindowImpl && mpWindowImpl->mbVisible;
1107 bool Window::IsReallyVisible() const
1109 return mpWindowImpl && mpWindowImpl->mbReallyVisible;
1112 bool Window::IsReallyShown() const
1114 return mpWindowImpl && mpWindowImpl->mbReallyShown;
1117 bool Window::IsInInitShow() const
1119 return mpWindowImpl->mbInInitShow;
1122 bool Window::IsEnabled() const
1124 return mpWindowImpl && !mpWindowImpl->mbDisabled;
1127 bool Window::IsInputEnabled() const
1129 return mpWindowImpl && !mpWindowImpl->mbInputDisabled;
1132 bool Window::IsAlwaysEnableInput() const
1134 return mpWindowImpl->meAlwaysInputMode == AlwaysInputEnabled;
1137 ActivateModeFlags Window::GetActivateMode() const
1139 return mpWindowImpl->mnActivateMode;
1143 bool Window::IsAlwaysOnTopEnabled() const
1145 return mpWindowImpl->mbAlwaysOnTop;
1148 bool Window::IsDefaultPos() const
1150 return mpWindowImpl->mbDefPos;
1153 bool Window::IsDefaultSize() const
1155 return mpWindowImpl->mbDefSize;
1158 Point Window::GetOffsetPixelFrom(const vcl::Window& rWindow) const
1160 return Point(GetOutOffXPixel() - rWindow.GetOutOffXPixel(), GetOutOffYPixel() - rWindow.GetOutOffYPixel());
1163 void Window::EnablePaint( bool bEnable )
1165 mpWindowImpl->mbPaintDisabled = !bEnable;
1168 bool Window::IsPaintEnabled() const
1170 return !mpWindowImpl->mbPaintDisabled;
1173 bool Window::IsUpdateMode() const
1175 return !mpWindowImpl->mbNoUpdate;
1178 void Window::SetParentUpdateMode( bool bUpdate )
1180 mpWindowImpl->mbNoParentUpdate = !bUpdate;
1183 bool Window::IsActive() const
1185 return mpWindowImpl->mbActive;
1188 GetFocusFlags Window::GetGetFocusFlags() const
1190 return mpWindowImpl->mnGetFocusFlags;
1193 bool Window::IsCompoundControl() const
1195 return mpWindowImpl->mbCompoundControl;
1198 bool Window::IsWait() const
1200 return (mpWindowImpl->mnWaitCount != 0);
1203 vcl::Cursor* Window::GetCursor() const
1205 if (!mpWindowImpl)
1206 return nullptr;
1207 return mpWindowImpl->mpCursor;
1210 const Fraction& Window::GetZoom() const
1212 return mpWindowImpl->maZoom;
1215 bool Window::IsZoom() const
1217 return mpWindowImpl->maZoom.GetNumerator() != mpWindowImpl->maZoom.GetDenominator();
1220 void Window::SetHelpText( const OUString& rHelpText )
1222 mpWindowImpl->maHelpText = rHelpText;
1223 mpWindowImpl->mbHelpTextDynamic = true;
1226 void Window::SetQuickHelpText( const OUString& rHelpText )
1228 if (mpWindowImpl)
1229 mpWindowImpl->maQuickHelpText = rHelpText;
1232 const OUString& Window::GetQuickHelpText() const
1234 return mpWindowImpl->maQuickHelpText;
1237 bool Window::IsCreatedWithToolkit() const
1239 return mpWindowImpl->mbCreatedWithToolkit;
1242 void Window::SetCreatedWithToolkit( bool b )
1244 mpWindowImpl->mbCreatedWithToolkit = b;
1247 PointerStyle Window::GetPointer() const
1249 return mpWindowImpl->maPointer;
1252 VCLXWindow* Window::GetWindowPeer() const
1254 return mpWindowImpl ? mpWindowImpl->mpVCLXWindow : nullptr;
1257 void Window::SetPosPixel( const Point& rNewPos )
1259 setPosSizePixel( rNewPos.X(), rNewPos.Y(), 0, 0, PosSizeFlags::Pos );
1262 void Window::SetSizePixel( const Size& rNewSize )
1264 setPosSizePixel( 0, 0, rNewSize.Width(), rNewSize.Height(),
1265 PosSizeFlags::Size );
1268 void Window::SetPosSizePixel( const Point& rNewPos, const Size& rNewSize )
1270 setPosSizePixel( rNewPos.X(), rNewPos.Y(),
1271 rNewSize.Width(), rNewSize.Height());
1274 void Window::SetOutputSizePixel( const Size& rNewSize )
1276 SetSizePixel( Size( rNewSize.Width()+mpWindowImpl->mnLeftBorder+mpWindowImpl->mnRightBorder,
1277 rNewSize.Height()+mpWindowImpl->mnTopBorder+mpWindowImpl->mnBottomBorder ) );
1280 //When a widget wants to renegotiate layout, get toplevel parent dialog and call
1281 //resize on it. Mark all intermediate containers (or container-alike) widgets
1282 //as dirty for the size remains unchanged, but layout changed circumstances
1283 namespace
1285 bool queue_ungrouped_resize(vcl::Window const *pOrigWindow)
1287 bool bSomeoneCares = false;
1289 vcl::Window *pWindow = pOrigWindow->GetParent();
1290 if (pWindow)
1292 if (isContainerWindow(*pWindow))
1294 bSomeoneCares = true;
1296 else if (pWindow->GetType() == WindowType::TABCONTROL)
1298 bSomeoneCares = true;
1300 pWindow->queue_resize();
1303 return bSomeoneCares;
1307 void Window::InvalidateSizeCache()
1309 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1310 pWindowImpl->mnOptimalWidthCache = -1;
1311 pWindowImpl->mnOptimalHeightCache = -1;
1314 static bool HasParentDockingWindow(const vcl::Window* pWindow)
1316 while( pWindow )
1318 if( pWindow->IsDockingWindow() )
1319 return true;
1321 pWindow = pWindow->GetParent();
1324 return false;
1327 void Window::queue_resize(StateChangedType eReason)
1329 if (IsDisposed())
1330 return;
1332 bool bSomeoneCares = queue_ungrouped_resize(this);
1334 if (eReason != StateChangedType::Visible)
1336 InvalidateSizeCache();
1339 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1340 if (pWindowImpl->m_xSizeGroup && pWindowImpl->m_xSizeGroup->get_mode() != VclSizeGroupMode::NONE)
1342 std::set<VclPtr<vcl::Window> > &rWindows = pWindowImpl->m_xSizeGroup->get_widgets();
1343 for (VclPtr<vcl::Window> const & pOther : rWindows)
1345 if (pOther == this)
1346 continue;
1347 queue_ungrouped_resize(pOther);
1351 if (bSomeoneCares && !isDisposed())
1353 //fdo#57090 force a resync of the borders of the borderwindow onto this
1354 //window in case they have changed
1355 vcl::Window* pBorderWindow = ImplGetBorderWindow();
1356 if (pBorderWindow)
1357 pBorderWindow->Resize();
1359 if (VclPtr<vcl::Window> pParent = GetParentWithLOKNotifier())
1361 Size aSize = GetSizePixel();
1362 if (!aSize.IsEmpty() && !pParent->IsInInitShow()
1363 && (GetParentDialog() || HasParentDockingWindow(this)))
1364 LogicInvalidate(nullptr);
1368 namespace
1370 VclAlign toAlign(const OUString &rValue)
1372 VclAlign eRet = VclAlign::Fill;
1374 if (rValue == "fill")
1375 eRet = VclAlign::Fill;
1376 else if (rValue == "start")
1377 eRet = VclAlign::Start;
1378 else if (rValue == "end")
1379 eRet = VclAlign::End;
1380 else if (rValue == "center")
1381 eRet = VclAlign::Center;
1382 return eRet;
1386 bool Window::set_font_attribute(const OString &rKey, const OUString &rValue)
1388 if (rKey == "weight")
1390 vcl::Font aFont(GetControlFont());
1391 if (rValue == "thin")
1392 aFont.SetWeight(WEIGHT_THIN);
1393 else if (rValue == "ultralight")
1394 aFont.SetWeight(WEIGHT_ULTRALIGHT);
1395 else if (rValue == "light")
1396 aFont.SetWeight(WEIGHT_LIGHT);
1397 else if (rValue == "book")
1398 aFont.SetWeight(WEIGHT_SEMILIGHT);
1399 else if (rValue == "normal")
1400 aFont.SetWeight(WEIGHT_NORMAL);
1401 else if (rValue == "medium")
1402 aFont.SetWeight(WEIGHT_MEDIUM);
1403 else if (rValue == "semibold")
1404 aFont.SetWeight(WEIGHT_SEMIBOLD);
1405 else if (rValue == "bold")
1406 aFont.SetWeight(WEIGHT_BOLD);
1407 else if (rValue == "ultrabold")
1408 aFont.SetWeight(WEIGHT_ULTRABOLD);
1409 else
1410 aFont.SetWeight(WEIGHT_BLACK);
1411 SetControlFont(aFont);
1413 else if (rKey == "style")
1415 vcl::Font aFont(GetControlFont());
1416 if (rValue == "normal")
1417 aFont.SetItalic(ITALIC_NONE);
1418 else if (rValue == "oblique")
1419 aFont.SetItalic(ITALIC_OBLIQUE);
1420 else if (rValue == "italic")
1421 aFont.SetItalic(ITALIC_NORMAL);
1422 SetControlFont(aFont);
1424 else if (rKey == "underline")
1426 vcl::Font aFont(GetControlFont());
1427 aFont.SetUnderline(toBool(rValue) ? LINESTYLE_SINGLE : LINESTYLE_NONE);
1428 SetControlFont(aFont);
1430 else if (rKey == "size")
1432 vcl::Font aFont(GetControlFont());
1433 sal_Int32 nHeight = rValue.toInt32() / 1000;
1434 aFont.SetFontHeight(nHeight);
1435 SetControlFont(aFont);
1437 else
1439 SAL_INFO("vcl.layout", "unhandled font attribute: " << rKey);
1440 return false;
1442 return true;
1445 bool Window::set_property(const OString &rKey, const OUString &rValue)
1447 if ((rKey == "label") || (rKey == "title") || (rKey == "text") )
1449 SetText(BuilderUtils::convertMnemonicMarkup(rValue));
1451 else if (rKey == "visible")
1452 Show(toBool(rValue));
1453 else if (rKey == "sensitive")
1454 Enable(toBool(rValue));
1455 else if (rKey == "resizable")
1457 WinBits nBits = GetStyle();
1458 nBits &= ~WB_SIZEABLE;
1459 if (toBool(rValue))
1460 nBits |= WB_SIZEABLE;
1461 SetStyle(nBits);
1463 else if (rKey == "xalign")
1465 WinBits nBits = GetStyle();
1466 nBits &= ~(WB_LEFT | WB_CENTER | WB_RIGHT);
1468 float f = rValue.toFloat();
1469 if (f == 0.0)
1470 nBits |= WB_LEFT;
1471 else if (f == 1.0)
1472 nBits |= WB_RIGHT;
1473 else if (f == 0.5)
1474 nBits |= WB_CENTER;
1476 SetStyle(nBits);
1478 else if (rKey == "justification")
1480 WinBits nBits = GetStyle();
1481 nBits &= ~(WB_LEFT | WB_CENTER | WB_RIGHT);
1483 if (rValue == "left")
1484 nBits |= WB_LEFT;
1485 else if (rValue == "right")
1486 nBits |= WB_RIGHT;
1487 else if (rValue == "center")
1488 nBits |= WB_CENTER;
1490 SetStyle(nBits);
1492 else if (rKey == "yalign")
1494 WinBits nBits = GetStyle();
1495 nBits &= ~(WB_TOP | WB_VCENTER | WB_BOTTOM);
1497 float f = rValue.toFloat();
1498 if (f == 0.0)
1499 nBits |= WB_TOP;
1500 else if (f == 1.0)
1501 nBits |= WB_BOTTOM;
1502 else if (f == 0.5)
1503 nBits |= WB_CENTER;
1505 SetStyle(nBits);
1507 else if (rKey == "wrap")
1509 WinBits nBits = GetStyle();
1510 nBits &= ~WB_WORDBREAK;
1511 if (toBool(rValue))
1512 nBits |= WB_WORDBREAK;
1513 SetStyle(nBits);
1515 else if (rKey == "height-request")
1516 set_height_request(rValue.toInt32());
1517 else if (rKey == "width-request")
1518 set_width_request(rValue.toInt32());
1519 else if (rKey == "hexpand")
1520 set_hexpand(toBool(rValue));
1521 else if (rKey == "vexpand")
1522 set_vexpand(toBool(rValue));
1523 else if (rKey == "halign")
1524 set_halign(toAlign(rValue));
1525 else if (rKey == "valign")
1526 set_valign(toAlign(rValue));
1527 else if (rKey == "tooltip-markup")
1528 SetQuickHelpText(rValue);
1529 else if (rKey == "tooltip-text")
1530 SetQuickHelpText(rValue);
1531 else if (rKey == "border-width")
1532 set_border_width(rValue.toInt32());
1533 else if (rKey == "margin-start" || rKey == "margin-left")
1534 set_margin_left(rValue.toInt32());
1535 else if (rKey == "margin-end" || rKey == "margin-right")
1536 set_margin_right(rValue.toInt32());
1537 else if (rKey == "margin-top")
1538 set_margin_top(rValue.toInt32());
1539 else if (rKey == "margin-bottom")
1540 set_margin_bottom(rValue.toInt32());
1541 else if (rKey == "hscrollbar-policy")
1543 WinBits nBits = GetStyle();
1544 nBits &= ~(WB_AUTOHSCROLL|WB_HSCROLL);
1545 if (rValue == "always")
1546 nBits |= WB_HSCROLL;
1547 else if (rValue == "automatic")
1548 nBits |= WB_AUTOHSCROLL;
1549 SetStyle(nBits);
1551 else if (rKey == "vscrollbar-policy")
1553 WinBits nBits = GetStyle();
1554 nBits &= ~(WB_AUTOVSCROLL|WB_VSCROLL);
1555 if (rValue == "always")
1556 nBits |= WB_VSCROLL;
1557 else if (rValue == "automatic")
1558 nBits |= WB_AUTOVSCROLL;
1559 SetStyle(nBits);
1561 else if (rKey == "accessible-name")
1563 SetAccessibleName(rValue);
1565 else if (rKey == "accessible-description")
1567 SetAccessibleDescription(rValue);
1569 else if (rKey == "accessible-role")
1571 sal_Int16 role = BuilderUtils::getRoleFromName(rValue.toUtf8());
1572 if (role != com::sun::star::accessibility::AccessibleRole::UNKNOWN)
1573 SetAccessibleRole(role);
1575 else if (rKey == "use-markup")
1577 //https://live.gnome.org/GnomeGoals/RemoveMarkupInMessages
1578 SAL_WARN_IF(toBool(rValue), "vcl.layout", "Use pango attributes instead of mark-up");
1580 else if (rKey == "has-focus")
1582 if (toBool(rValue))
1583 GrabFocus();
1585 else if (rKey == "can-focus")
1587 WinBits nBits = GetStyle();
1588 nBits &= ~(WB_TABSTOP|WB_NOTABSTOP);
1589 if (toBool(rValue))
1590 nBits |= WB_TABSTOP;
1591 else
1592 nBits |= WB_NOTABSTOP;
1593 SetStyle(nBits);
1595 else
1597 SAL_INFO("vcl.layout", "unhandled property: " << rKey);
1598 return false;
1600 return true;
1603 void Window::set_height_request(sal_Int32 nHeightRequest)
1605 if (!mpWindowImpl)
1606 return;
1608 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1610 if ( pWindowImpl->mnHeightRequest != nHeightRequest )
1612 pWindowImpl->mnHeightRequest = nHeightRequest;
1613 queue_resize();
1617 void Window::set_width_request(sal_Int32 nWidthRequest)
1619 if (!mpWindowImpl)
1620 return;
1622 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1624 if ( pWindowImpl->mnWidthRequest != nWidthRequest )
1626 pWindowImpl->mnWidthRequest = nWidthRequest;
1627 queue_resize();
1631 Size Window::get_ungrouped_preferred_size() const
1633 Size aRet(get_width_request(), get_height_request());
1634 if (aRet.Width() == -1 || aRet.Height() == -1)
1636 //cache gets blown away by queue_resize
1637 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1638 if (pWindowImpl->mnOptimalWidthCache == -1 || pWindowImpl->mnOptimalHeightCache == -1)
1640 Size aOptimal(GetOptimalSize());
1641 pWindowImpl->mnOptimalWidthCache = aOptimal.Width();
1642 pWindowImpl->mnOptimalHeightCache = aOptimal.Height();
1645 if (aRet.Width() == -1)
1646 aRet.setWidth( pWindowImpl->mnOptimalWidthCache );
1647 if (aRet.Height() == -1)
1648 aRet.setHeight( pWindowImpl->mnOptimalHeightCache );
1650 return aRet;
1653 Size Window::get_preferred_size() const
1655 Size aRet(get_ungrouped_preferred_size());
1657 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1658 if (pWindowImpl->m_xSizeGroup)
1660 const VclSizeGroupMode eMode = pWindowImpl->m_xSizeGroup->get_mode();
1661 if (eMode != VclSizeGroupMode::NONE)
1663 const bool bIgnoreInHidden = pWindowImpl->m_xSizeGroup->get_ignore_hidden();
1664 const std::set<VclPtr<vcl::Window> > &rWindows = pWindowImpl->m_xSizeGroup->get_widgets();
1665 for (auto const& window : rWindows)
1667 const vcl::Window *pOther = window;
1668 if (pOther == this)
1669 continue;
1670 if (bIgnoreInHidden && !pOther->IsVisible())
1671 continue;
1672 Size aOtherSize = pOther->get_ungrouped_preferred_size();
1673 if (eMode == VclSizeGroupMode::Both || eMode == VclSizeGroupMode::Horizontal)
1674 aRet.setWidth( std::max(aRet.Width(), aOtherSize.Width()) );
1675 if (eMode == VclSizeGroupMode::Both || eMode == VclSizeGroupMode::Vertical)
1676 aRet.setHeight( std::max(aRet.Height(), aOtherSize.Height()) );
1681 return aRet;
1684 VclAlign Window::get_halign() const
1686 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1687 return pWindowImpl->meHalign;
1690 void Window::set_halign(VclAlign eAlign)
1692 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1693 pWindowImpl->meHalign = eAlign;
1696 VclAlign Window::get_valign() const
1698 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1699 return pWindowImpl->meValign;
1702 void Window::set_valign(VclAlign eAlign)
1704 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1705 pWindowImpl->meValign = eAlign;
1708 bool Window::get_hexpand() const
1710 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1711 return pWindowImpl->mbHexpand;
1714 void Window::set_hexpand(bool bExpand)
1716 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1717 pWindowImpl->mbHexpand = bExpand;
1720 bool Window::get_vexpand() const
1722 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1723 return pWindowImpl->mbVexpand;
1726 void Window::set_vexpand(bool bExpand)
1728 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1729 pWindowImpl->mbVexpand = bExpand;
1732 bool Window::get_expand() const
1734 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1735 return pWindowImpl->mbExpand;
1738 void Window::set_expand(bool bExpand)
1740 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1741 pWindowImpl->mbExpand = bExpand;
1744 VclPackType Window::get_pack_type() const
1746 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1747 return pWindowImpl->mePackType;
1750 void Window::set_pack_type(VclPackType ePackType)
1752 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1753 pWindowImpl->mePackType = ePackType;
1756 sal_Int32 Window::get_padding() const
1758 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1759 return pWindowImpl->mnPadding;
1762 void Window::set_padding(sal_Int32 nPadding)
1764 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1765 pWindowImpl->mnPadding = nPadding;
1768 bool Window::get_fill() const
1770 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1771 return pWindowImpl->mbFill;
1774 void Window::set_fill(bool bFill)
1776 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1777 pWindowImpl->mbFill = bFill;
1780 sal_Int32 Window::get_grid_width() const
1782 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1783 return pWindowImpl->mnGridWidth;
1786 void Window::set_grid_width(sal_Int32 nCols)
1788 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1789 pWindowImpl->mnGridWidth = nCols;
1792 sal_Int32 Window::get_grid_left_attach() const
1794 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1795 return pWindowImpl->mnGridLeftAttach;
1798 void Window::set_grid_left_attach(sal_Int32 nAttach)
1800 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1801 pWindowImpl->mnGridLeftAttach = nAttach;
1804 sal_Int32 Window::get_grid_height() const
1806 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1807 return pWindowImpl->mnGridHeight;
1810 void Window::set_grid_height(sal_Int32 nRows)
1812 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1813 pWindowImpl->mnGridHeight = nRows;
1816 sal_Int32 Window::get_grid_top_attach() const
1818 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1819 return pWindowImpl->mnGridTopAttach;
1822 void Window::set_grid_top_attach(sal_Int32 nAttach)
1824 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1825 pWindowImpl->mnGridTopAttach = nAttach;
1828 void Window::set_border_width(sal_Int32 nBorderWidth)
1830 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1831 pWindowImpl->mnBorderWidth = nBorderWidth;
1834 sal_Int32 Window::get_border_width() const
1836 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1837 return pWindowImpl->mnBorderWidth;
1840 void Window::set_margin_left(sal_Int32 nWidth)
1842 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1843 if (pWindowImpl->mnMarginLeft != nWidth)
1845 pWindowImpl->mnMarginLeft = nWidth;
1846 queue_resize();
1850 sal_Int32 Window::get_margin_left() const
1852 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1853 return pWindowImpl->mnMarginLeft;
1856 void Window::set_margin_right(sal_Int32 nWidth)
1858 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1859 if (pWindowImpl->mnMarginRight != nWidth)
1861 pWindowImpl->mnMarginRight = nWidth;
1862 queue_resize();
1866 sal_Int32 Window::get_margin_right() const
1868 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1869 return pWindowImpl->mnMarginRight;
1872 void Window::set_margin_top(sal_Int32 nWidth)
1874 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1875 if (pWindowImpl->mnMarginTop != nWidth)
1877 pWindowImpl->mnMarginTop = nWidth;
1878 queue_resize();
1882 sal_Int32 Window::get_margin_top() const
1884 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1885 return pWindowImpl->mnMarginTop;
1888 void Window::set_margin_bottom(sal_Int32 nWidth)
1890 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1891 if (pWindowImpl->mnMarginBottom != nWidth)
1893 pWindowImpl->mnMarginBottom = nWidth;
1894 queue_resize();
1898 sal_Int32 Window::get_margin_bottom() const
1900 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1901 return pWindowImpl->mnMarginBottom;
1904 sal_Int32 Window::get_height_request() const
1906 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1907 return pWindowImpl->mnHeightRequest;
1910 sal_Int32 Window::get_width_request() const
1912 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1913 return pWindowImpl->mnWidthRequest;
1916 bool Window::get_secondary() const
1918 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1919 return pWindowImpl->mbSecondary;
1922 void Window::set_secondary(bool bSecondary)
1924 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1925 pWindowImpl->mbSecondary = bSecondary;
1928 bool Window::get_non_homogeneous() const
1930 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1931 return pWindowImpl->mbNonHomogeneous;
1934 void Window::set_non_homogeneous(bool bNonHomogeneous)
1936 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1937 pWindowImpl->mbNonHomogeneous = bNonHomogeneous;
1940 void Window::add_to_size_group(const std::shared_ptr<VclSizeGroup>& xGroup)
1942 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1943 //To-Do, multiple groups
1944 pWindowImpl->m_xSizeGroup = xGroup;
1945 pWindowImpl->m_xSizeGroup->insert(this);
1946 if (VclSizeGroupMode::NONE != pWindowImpl->m_xSizeGroup->get_mode())
1947 queue_resize();
1950 void Window::remove_from_all_size_groups()
1952 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1953 //To-Do, multiple groups
1954 if (pWindowImpl->m_xSizeGroup)
1956 if (VclSizeGroupMode::NONE != pWindowImpl->m_xSizeGroup->get_mode())
1957 queue_resize();
1958 pWindowImpl->m_xSizeGroup->erase(this);
1959 pWindowImpl->m_xSizeGroup.reset();
1963 void Window::add_mnemonic_label(FixedText *pLabel)
1965 std::vector<VclPtr<FixedText> >& v = mpWindowImpl->m_aMnemonicLabels;
1966 if (std::find(v.begin(), v.end(), VclPtr<FixedText>(pLabel)) != v.end())
1967 return;
1968 v.emplace_back(pLabel);
1969 pLabel->set_mnemonic_widget(this);
1972 void Window::remove_mnemonic_label(FixedText *pLabel)
1974 std::vector<VclPtr<FixedText> >& v = mpWindowImpl->m_aMnemonicLabels;
1975 auto aFind = std::find(v.begin(), v.end(), VclPtr<FixedText>(pLabel));
1976 if (aFind == v.end())
1977 return;
1978 v.erase(aFind);
1979 pLabel->set_mnemonic_widget(nullptr);
1982 const std::vector<VclPtr<FixedText> >& Window::list_mnemonic_labels() const
1984 return mpWindowImpl->m_aMnemonicLabels;
1987 } /* namespace vcl */
1989 void DrawFocusRect(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
1991 const int nBorder = 1;
1992 rRenderContext.Invert(tools::Rectangle(Point(rRect.Left(), rRect.Top()), Size(rRect.GetWidth(), nBorder)), InvertFlags::N50);
1993 rRenderContext.Invert(tools::Rectangle(Point(rRect.Left(), rRect.Bottom()-nBorder+1), Size(rRect.GetWidth(), nBorder)), InvertFlags::N50);
1994 rRenderContext.Invert(tools::Rectangle(Point(rRect.Left(), rRect.Top()+nBorder), Size(nBorder, rRect.GetHeight()-(nBorder*2))), InvertFlags::N50);
1995 rRenderContext.Invert(tools::Rectangle(Point(rRect.Right()-nBorder+1, rRect.Top()+nBorder), Size(nBorder, rRect.GetHeight()-(nBorder*2))), InvertFlags::N50);
1998 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */