Check mpWindowImpl before use in Window::EndTracking
[LibreOffice.git] / vcl / source / window / window2.cxx
blobbf58278e5b1554d9eddd1c8fcd59ec13f3a5f0d0
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 <tools/helpers.hxx>
27 #include <vcl/toolkit/dialog.hxx>
28 #include <vcl/event.hxx>
29 #include <vcl/toolkit/fixed.hxx>
30 #include <vcl/layout.hxx>
31 #include <vcl/timer.hxx>
32 #include <vcl/window.hxx>
33 #include <vcl/scrbar.hxx>
34 #include <vcl/dockwin.hxx>
35 #include <vcl/settings.hxx>
36 #include <vcl/builder.hxx>
38 #include <window.h>
39 #include <svdata.hxx>
40 #include <salgdi.hxx>
41 #include <salframe.hxx>
42 #include <scrwnd.hxx>
44 #include <com/sun/star/accessibility/AccessibleRelation.hpp>
45 #include <com/sun/star/accessibility/AccessibleRole.hpp>
47 using namespace com::sun::star;
49 namespace vcl {
51 void Window::ShowFocus( const tools::Rectangle& rRect )
53 if( mpWindowImpl->mbInShowFocus )
54 return;
55 mpWindowImpl->mbInShowFocus = true;
57 ImplWinData* pWinData = ImplGetWinData();
59 // native themeing suggest not to use focus rects
60 if( ! ( mpWindowImpl->mbUseNativeFocus &&
61 IsNativeWidgetEnabled() ) )
63 if ( !mpWindowImpl->mbInPaint )
65 if ( mpWindowImpl->mbFocusVisible )
67 if ( *pWinData->mpFocusRect == rRect )
69 mpWindowImpl->mbInShowFocus = false;
70 return;
73 ImplInvertFocus( *pWinData->mpFocusRect );
76 ImplInvertFocus( rRect );
78 pWinData->mpFocusRect = rRect;
79 mpWindowImpl->mbFocusVisible = true;
81 else
83 if( ! mpWindowImpl->mbNativeFocusVisible )
85 mpWindowImpl->mbNativeFocusVisible = true;
86 if ( !mpWindowImpl->mbInPaint )
87 Invalidate();
90 mpWindowImpl->mbInShowFocus = false;
93 void Window::HideFocus()
96 if( mpWindowImpl->mbInHideFocus )
97 return;
98 mpWindowImpl->mbInHideFocus = true;
100 // native themeing can suggest not to use focus rects
101 if( ! ( mpWindowImpl->mbUseNativeFocus &&
102 IsNativeWidgetEnabled() ) )
104 if ( !mpWindowImpl->mbFocusVisible )
106 mpWindowImpl->mbInHideFocus = false;
107 return;
110 if ( !mpWindowImpl->mbInPaint )
111 ImplInvertFocus( *ImplGetWinData()->mpFocusRect );
112 mpWindowImpl->mbFocusVisible = false;
114 else
116 if( mpWindowImpl->mbNativeFocusVisible )
118 mpWindowImpl->mbNativeFocusVisible = false;
119 if ( !mpWindowImpl->mbInPaint )
120 Invalidate();
123 mpWindowImpl->mbInHideFocus = false;
126 void Window::ShowTracking( const tools::Rectangle& rRect, ShowTrackFlags nFlags )
128 ImplWinData* pWinData = ImplGetWinData();
130 if ( !mpWindowImpl->mbInPaint || !(nFlags & ShowTrackFlags::TrackWindow) )
132 if ( mpWindowImpl->mbTrackVisible )
134 if ( (*pWinData->mpTrackRect == rRect) &&
135 (pWinData->mnTrackFlags == nFlags) )
136 return;
138 InvertTracking( *pWinData->mpTrackRect, pWinData->mnTrackFlags );
141 InvertTracking( rRect, nFlags );
144 pWinData->mpTrackRect = rRect;
145 pWinData->mnTrackFlags = nFlags;
146 mpWindowImpl->mbTrackVisible = true;
149 void Window::HideTracking()
151 if ( mpWindowImpl->mbTrackVisible )
153 ImplWinData* pWinData = ImplGetWinData();
154 if ( !mpWindowImpl->mbInPaint || !(pWinData->mnTrackFlags & ShowTrackFlags::TrackWindow) )
155 InvertTracking( *pWinData->mpTrackRect, pWinData->mnTrackFlags );
156 mpWindowImpl->mbTrackVisible = false;
160 void Window::InvertTracking( const tools::Rectangle& rRect, ShowTrackFlags nFlags )
162 OutputDevice *pOutDev = GetOutDev();
163 tools::Rectangle aRect( pOutDev->ImplLogicToDevicePixel( rRect ) );
165 if ( aRect.IsEmpty() )
166 return;
167 aRect.Justify();
169 SalGraphics* pGraphics;
171 if ( nFlags & ShowTrackFlags::TrackWindow )
173 if ( !GetOutDev()->IsDeviceOutputNecessary() )
174 return;
176 // we need a graphics
177 if ( !GetOutDev()->mpGraphics )
179 if ( !pOutDev->AcquireGraphics() )
180 return;
183 if ( GetOutDev()->mbInitClipRegion )
184 GetOutDev()->InitClipRegion();
186 if ( GetOutDev()->mbOutputClipped )
187 return;
189 pGraphics = GetOutDev()->mpGraphics;
191 else
193 pGraphics = ImplGetFrameGraphics();
195 if ( nFlags & ShowTrackFlags::Clip )
197 vcl::Region aRegion( GetOutputRectPixel() );
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, *GetOutDev() );
206 else if ( nStyle == ShowTrackFlags::Split )
207 pGraphics->Invert( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight(), SalInvert::N50, *GetOutDev() );
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, *GetOutDev() );
214 pGraphics->Invert( aRect.Left(), aRect.Bottom()-nBorder+1, aRect.GetWidth(), nBorder, SalInvert::N50, *GetOutDev() );
215 pGraphics->Invert( aRect.Left(), aRect.Top()+nBorder, nBorder, aRect.GetHeight()-(nBorder*2), SalInvert::N50, *GetOutDev() );
216 pGraphics->Invert( aRect.Right()-nBorder+1, aRect.Top()+nBorder, nBorder, aRect.GetHeight()-(nBorder*2), SalInvert::N50, *GetOutDev() );
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( GetOutDev()->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("vcl::Window pSVData->mpWinData->mpTrackTimer");
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->Start();
266 pSVData->mpWinData->mpTrackWin = this;
267 pSVData->mpWinData->mnTrackFlags = nFlags;
268 CaptureMouse();
271 void Window::EndTracking( TrackingEventFlags nFlags )
273 ImplSVData* pSVData = ImplGetSVData();
275 if ( pSVData->mpWinData->mpTrackWin.get() != this )
276 return;
278 if ( pSVData->mpWinData->mpTrackTimer )
280 delete pSVData->mpWinData->mpTrackTimer;
281 pSVData->mpWinData->mpTrackTimer = nullptr;
284 pSVData->mpWinData->mpTrackWin = nullptr;
285 pSVData->mpWinData->mnTrackFlags = StartTrackingFlags::NONE;
286 ReleaseMouse();
288 // call EndTracking if required
289 if (mpWindowImpl && mpWindowImpl->mpFrameData)
291 Point aMousePos( mpWindowImpl->mpFrameData->mnLastMouseX, mpWindowImpl->mpFrameData->mnLastMouseY );
292 if( GetOutDev()->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.disposeAndClear();
345 VclPtr<vcl::Window> Window::SaveFocus()
347 ImplSVData* pSVData = ImplGetSVData();
348 if ( pSVData->mpWinData->mpFocusWin )
350 return pSVData->mpWinData->mpFocusWin;
352 else
353 return nullptr;
356 void Window::EndSaveFocus(const VclPtr<vcl::Window>& xFocusWin)
358 if (xFocusWin && !xFocusWin->isDisposed())
360 xFocusWin->GrabFocus();
364 void Window::SetZoom( const Fraction& rZoom )
366 if ( mpWindowImpl && mpWindowImpl->maZoom != rZoom )
368 mpWindowImpl->maZoom = rZoom;
369 CompatStateChanged( StateChangedType::Zoom );
373 void Window::SetZoomedPointFont(vcl::RenderContext& rRenderContext, const vcl::Font& rFont)
375 const Fraction& rZoom = GetZoom();
376 if (rZoom.GetNumerator() != rZoom.GetDenominator())
378 vcl::Font aFont(rFont);
379 Size aSize = aFont.GetFontSize();
380 aSize.setWidth( FRound(double(aSize.Width() * rZoom)) );
381 aSize.setHeight( FRound(double(aSize.Height() * rZoom)) );
382 aFont.SetFontSize(aSize);
383 SetPointFont(rRenderContext, aFont);
385 else
387 SetPointFont(rRenderContext, rFont);
391 tools::Long Window::CalcZoom( tools::Long nCalc ) const
394 const Fraction& rZoom = GetZoom();
395 if ( rZoom.GetNumerator() != rZoom.GetDenominator() )
397 double n = double(nCalc * rZoom);
398 nCalc = FRound( n );
400 return nCalc;
403 void Window::SetControlFont()
405 if (mpWindowImpl && mpWindowImpl->mpControlFont)
407 mpWindowImpl->mpControlFont.reset();
408 CompatStateChanged(StateChangedType::ControlFont);
412 void Window::SetControlFont(const vcl::Font& rFont)
414 if (rFont == vcl::Font())
416 SetControlFont();
417 return;
420 if (mpWindowImpl->mpControlFont)
422 if (*mpWindowImpl->mpControlFont == rFont)
423 return;
424 *mpWindowImpl->mpControlFont = rFont;
426 else
427 mpWindowImpl->mpControlFont = rFont;
429 CompatStateChanged(StateChangedType::ControlFont);
432 vcl::Font Window::GetControlFont() const
434 if (mpWindowImpl->mpControlFont)
435 return *mpWindowImpl->mpControlFont;
436 else
438 vcl::Font aFont;
439 return aFont;
443 void Window::ApplyControlFont(vcl::RenderContext& rRenderContext, const vcl::Font& rFont)
445 vcl::Font aFont(rFont);
446 if (IsControlFont())
447 aFont.Merge(GetControlFont());
448 SetZoomedPointFont(rRenderContext, aFont);
451 void Window::SetControlForeground()
453 if (mpWindowImpl->mbControlForeground)
455 mpWindowImpl->maControlForeground = COL_TRANSPARENT;
456 mpWindowImpl->mbControlForeground = false;
457 CompatStateChanged(StateChangedType::ControlForeground);
461 void Window::SetControlForeground(const Color& rColor)
463 if (rColor.IsTransparent())
465 if (mpWindowImpl->mbControlForeground)
467 mpWindowImpl->maControlForeground = COL_TRANSPARENT;
468 mpWindowImpl->mbControlForeground = false;
469 CompatStateChanged(StateChangedType::ControlForeground);
472 else
474 if (mpWindowImpl->maControlForeground != rColor)
476 mpWindowImpl->maControlForeground = rColor;
477 mpWindowImpl->mbControlForeground = true;
478 CompatStateChanged(StateChangedType::ControlForeground);
483 void Window::ApplyControlForeground(vcl::RenderContext& rRenderContext, const Color& rDefaultColor)
485 Color aTextColor(rDefaultColor);
486 if (IsControlForeground())
487 aTextColor = GetControlForeground();
488 rRenderContext.SetTextColor(aTextColor);
491 void Window::SetControlBackground()
493 if (mpWindowImpl->mbControlBackground)
495 mpWindowImpl->maControlBackground = COL_TRANSPARENT;
496 mpWindowImpl->mbControlBackground = false;
497 CompatStateChanged(StateChangedType::ControlBackground);
501 void Window::SetControlBackground(const Color& rColor)
503 if (rColor.IsTransparent())
505 if (mpWindowImpl->mbControlBackground)
507 mpWindowImpl->maControlBackground = COL_TRANSPARENT;
508 mpWindowImpl->mbControlBackground = false;
509 CompatStateChanged(StateChangedType::ControlBackground);
512 else
514 if (mpWindowImpl->maControlBackground != rColor)
516 mpWindowImpl->maControlBackground = rColor;
517 mpWindowImpl->mbControlBackground = true;
518 CompatStateChanged(StateChangedType::ControlBackground);
523 void Window::ApplyControlBackground(vcl::RenderContext& rRenderContext, const Color& rDefaultColor)
525 Color aColor(rDefaultColor);
526 if (IsControlBackground())
527 aColor = GetControlBackground();
528 rRenderContext.SetBackground(aColor);
531 Size Window::CalcWindowSize( const Size& rOutSz ) const
533 Size aSz = rOutSz;
534 aSz.AdjustWidth(mpWindowImpl->mnLeftBorder+mpWindowImpl->mnRightBorder );
535 aSz.AdjustHeight(mpWindowImpl->mnTopBorder+mpWindowImpl->mnBottomBorder );
536 return aSz;
539 Size Window::CalcOutputSize( const Size& rWinSz ) const
541 Size aSz = rWinSz;
542 aSz.AdjustWidth( -(mpWindowImpl->mnLeftBorder+mpWindowImpl->mnRightBorder) );
543 aSz.AdjustHeight( -(mpWindowImpl->mnTopBorder+mpWindowImpl->mnBottomBorder) );
544 return aSz;
547 vcl::Font Window::GetDrawPixelFont(OutputDevice const * pDev) const
549 vcl::Font aFont = GetPointFont(*GetOutDev());
550 Size aFontSize = aFont.GetFontSize();
551 MapMode aPtMapMode(MapUnit::MapPoint);
552 aFontSize = pDev->LogicToPixel( aFontSize, aPtMapMode );
553 aFont.SetFontSize( aFontSize );
554 return aFont;
557 tools::Long Window::GetDrawPixel( OutputDevice const * pDev, tools::Long nPixels ) const
559 tools::Long nP = nPixels;
560 if ( pDev->GetOutDevType() != OUTDEV_WINDOW )
562 MapMode aMap( MapUnit::Map100thMM );
563 Size aSz( nP, 0 );
564 aSz = PixelToLogic( aSz, aMap );
565 aSz = pDev->LogicToPixel( aSz, aMap );
566 nP = aSz.Width();
568 return nP;
571 static void lcl_HandleScrollHelper( ScrollBar* pScrl, double nN, bool isMultiplyByLineSize )
573 if ( !pScrl || !nN || !pScrl->IsEnabled() || !pScrl->IsInputEnabled() || pScrl->IsInModalMode() )
574 return;
576 tools::Long nNewPos = pScrl->GetThumbPos();
578 if ( nN == double(-LONG_MAX) )
579 nNewPos += pScrl->GetPageSize();
580 else if ( nN == double(LONG_MAX) )
581 nNewPos -= pScrl->GetPageSize();
582 else
584 // allowing both chunked and continuous scrolling
585 if(isMultiplyByLineSize){
586 nN*=pScrl->GetLineSize();
589 const double fVal = nNewPos - nN;
591 nNewPos = o3tl::saturating_cast<tools::Long>(fVal);
594 pScrl->DoScroll( nNewPos );
598 bool Window::HandleScrollCommand( const CommandEvent& rCmd,
599 ScrollBar* pHScrl, ScrollBar* pVScrl )
601 bool bRet = false;
603 if ( pHScrl || pVScrl )
605 switch( rCmd.GetCommand() )
607 case CommandEventId::StartAutoScroll:
609 StartAutoScrollFlags nFlags = StartAutoScrollFlags::NONE;
610 if ( pHScrl )
612 if ( (pHScrl->GetVisibleSize() < pHScrl->GetRangeMax()) &&
613 pHScrl->IsEnabled() && pHScrl->IsInputEnabled() && ! pHScrl->IsInModalMode() )
614 nFlags |= StartAutoScrollFlags::Horz;
616 if ( pVScrl )
618 if ( (pVScrl->GetVisibleSize() < pVScrl->GetRangeMax()) &&
619 pVScrl->IsEnabled() && pVScrl->IsInputEnabled() && ! pVScrl->IsInModalMode() )
620 nFlags |= StartAutoScrollFlags::Vert;
623 if ( nFlags != StartAutoScrollFlags::NONE )
625 StartAutoScroll( nFlags );
626 bRet = true;
629 break;
631 case CommandEventId::Wheel:
633 const CommandWheelData* pData = rCmd.GetWheelData();
635 if ( pData && (CommandWheelMode::SCROLL == pData->GetMode()) )
637 if (!pData->IsDeltaPixel())
639 double nScrollLines = pData->GetScrollLines();
640 double nLines;
641 if ( nScrollLines == COMMAND_WHEEL_PAGESCROLL )
643 if ( pData->GetDelta() < 0 )
644 nLines = double(-LONG_MAX);
645 else
646 nLines = double(LONG_MAX);
648 else
649 nLines = pData->GetNotchDelta() * nScrollLines;
650 if ( nLines )
652 ImplHandleScroll( nullptr,
654 pData->IsHorz() ? pHScrl : pVScrl,
655 nLines );
656 bRet = true;
659 else
661 // Mobile / touch scrolling section
662 const Point & deltaPoint = rCmd.GetMousePosPixel();
664 double deltaXInPixels = double(deltaPoint.X());
665 double deltaYInPixels = double(deltaPoint.Y());
666 Size winSize = GetOutputSizePixel();
668 if(pHScrl)
670 double visSizeX = double(pHScrl->GetVisibleSize());
671 double ratioX = deltaXInPixels / double(winSize.getWidth());
672 tools::Long deltaXInLogic = tools::Long(visSizeX * ratioX);
673 // Touch need to work by pixels. Did not apply this to
674 // Android, as android code may require adaptations
675 // to work with this scrolling code
676 #ifndef IOS
677 tools::Long lineSizeX = pHScrl->GetLineSize();
679 if(lineSizeX)
681 deltaXInLogic /= lineSizeX;
683 else
685 deltaXInLogic = 0;
687 #endif
688 if ( deltaXInLogic)
690 #ifndef IOS
691 bool const isMultiplyByLineSize = true;
692 #else
693 bool const isMultiplyByLineSize = false;
694 #endif
695 lcl_HandleScrollHelper( pHScrl, deltaXInLogic, isMultiplyByLineSize );
696 bRet = true;
699 if(pVScrl)
701 double visSizeY = double(pVScrl->GetVisibleSize());
702 double ratioY = deltaYInPixels / double(winSize.getHeight());
703 tools::Long deltaYInLogic = tools::Long(visSizeY * ratioY);
705 // Touch need to work by pixels. Did not apply this to
706 // Android, as android code may require adaptations
707 // to work with this scrolling code
708 #ifndef IOS
709 tools::Long lineSizeY = pVScrl->GetLineSize();
710 if(lineSizeY)
712 deltaYInLogic /= lineSizeY;
714 else
716 deltaYInLogic = 0;
718 #endif
719 if ( deltaYInLogic )
721 #ifndef IOS
722 bool const isMultiplyByLineSize = true;
723 #else
724 bool const isMultiplyByLineSize = false;
725 #endif
726 lcl_HandleScrollHelper( pVScrl, deltaYInLogic, isMultiplyByLineSize );
728 bRet = true;
734 break;
736 case CommandEventId::Gesture:
738 if (pVScrl)
740 const CommandGestureData* pData = rCmd.GetGestureData();
741 if (pData->meEventType == GestureEventType::PanningBegin)
743 mpWindowImpl->mpFrameData->mnTouchPanPosition = pVScrl->GetThumbPos();
745 else if(pData->meEventType == GestureEventType::PanningUpdate)
747 tools::Long nOriginalPosition = mpWindowImpl->mpFrameData->mnTouchPanPosition;
748 pVScrl->DoScroll(nOriginalPosition + (pData->mfOffset / pVScrl->GetVisibleSize()));
750 if (pData->meEventType == GestureEventType::PanningEnd)
752 mpWindowImpl->mpFrameData->mnTouchPanPosition = -1;
754 bRet = true;
756 break;
759 case CommandEventId::AutoScroll:
761 const CommandScrollData* pData = rCmd.GetAutoScrollData();
762 if ( pData && (pData->GetDeltaX() || pData->GetDeltaY()) )
764 ImplHandleScroll( pHScrl, pData->GetDeltaX(),
765 pVScrl, pData->GetDeltaY() );
766 bRet = true;
769 break;
771 default:
772 break;
776 return bRet;
779 // Note that when called for CommandEventId::Wheel above, despite its name,
780 // pVScrl isn't necessarily the vertical scroll bar. Depending on
781 // whether the scroll is horizontal or vertical, it is either the
782 // horizontal or vertical scroll bar. nY is correspondingly either
783 // the horizontal or vertical scroll amount.
785 void Window::ImplHandleScroll( ScrollBar* pHScrl, double nX,
786 ScrollBar* pVScrl, double nY )
788 lcl_HandleScrollHelper( pHScrl, nX, true );
789 lcl_HandleScrollHelper( pVScrl, nY, true );
792 DockingManager* Window::GetDockingManager()
794 return ImplGetDockingManager();
797 void Window::EnableDocking( bool bEnable )
799 // update list of dockable windows
800 if( bEnable )
801 ImplGetDockingManager()->AddWindow( this );
802 else
803 ImplGetDockingManager()->RemoveWindow( this );
806 // retrieves the list of owner draw decorated windows for this window hierarchy
807 ::std::vector<VclPtr<vcl::Window> >& Window::ImplGetOwnerDrawList()
809 return ImplGetTopmostFrameWindow()->mpWindowImpl->mpFrameData->maOwnerDrawList;
812 void Window::SetHelpId( const OString& rHelpId )
814 mpWindowImpl->maHelpId = rHelpId;
817 const OString& Window::GetHelpId() const
819 return mpWindowImpl->maHelpId;
822 // --------- old inline methods ---------------
824 vcl::Window* Window::ImplGetWindow() const
826 if ( mpWindowImpl->mpClientWindow )
827 return mpWindowImpl->mpClientWindow;
828 else
829 return const_cast<vcl::Window*>(this);
832 ImplFrameData* Window::ImplGetFrameData()
834 return mpWindowImpl ? mpWindowImpl->mpFrameData : nullptr;
837 SalFrame* Window::ImplGetFrame() const
839 return mpWindowImpl ? mpWindowImpl->mpFrame : nullptr;
842 weld::Window* Window::GetFrameWeld() const
844 SalFrame* pFrame = ImplGetFrame();
845 return pFrame ? pFrame->GetFrameWeld() : nullptr;
848 vcl::Window* Window::GetFrameWindow() const
850 SalFrame* pFrame = ImplGetFrame();
851 return pFrame ? pFrame->GetWindow() : nullptr;
854 vcl::Window* Window::ImplGetParent() const
856 return mpWindowImpl ? mpWindowImpl->mpParent.get() : nullptr;
859 vcl::Window* Window::ImplGetClientWindow() const
861 return mpWindowImpl ? mpWindowImpl->mpClientWindow.get() : nullptr;
864 vcl::Window* Window::ImplGetBorderWindow() const
866 return mpWindowImpl ? mpWindowImpl->mpBorderWindow.get() : nullptr;
869 vcl::Window* Window::ImplGetFirstOverlapWindow()
871 if (!mpWindowImpl)
873 return nullptr;
876 if ( mpWindowImpl->mbOverlapWin )
877 return this;
878 else
879 return mpWindowImpl->mpOverlapWindow;
882 const vcl::Window* Window::ImplGetFirstOverlapWindow() const
884 if (!mpWindowImpl)
886 return nullptr;
889 if ( mpWindowImpl->mbOverlapWin )
890 return this;
891 else
892 return mpWindowImpl->mpOverlapWindow;
895 vcl::Window* Window::ImplGetFrameWindow() const
897 return mpWindowImpl ? mpWindowImpl->mpFrameWindow.get() : nullptr;
900 bool Window::IsDockingWindow() const
902 return mpWindowImpl && mpWindowImpl->mbDockWin;
905 bool Window::ImplIsFloatingWindow() const
907 return mpWindowImpl && mpWindowImpl->mbFloatWin;
910 bool Window::ImplIsSplitter() const
912 return mpWindowImpl && mpWindowImpl->mbSplitter;
915 bool Window::ImplIsPushButton() const
917 return mpWindowImpl && mpWindowImpl->mbPushButton;
920 bool Window::ImplIsOverlapWindow() const
922 return mpWindowImpl && mpWindowImpl->mbOverlapWin;
925 void Window::ImplSetMouseTransparent( bool bTransparent )
927 if (mpWindowImpl)
928 mpWindowImpl->mbMouseTransparent = bTransparent;
931 Point Window::ImplOutputToFrame( const Point& rPos )
933 return Point( rPos.X()+GetOutDev()->mnOutOffX, rPos.Y()+GetOutDev()->mnOutOffY );
936 Point Window::ImplFrameToOutput( const Point& rPos )
938 return Point( rPos.X()-GetOutDev()->mnOutOffX, rPos.Y()-GetOutDev()->mnOutOffY );
941 void Window::SetCompoundControl( bool bCompound )
943 if (mpWindowImpl)
944 mpWindowImpl->mbCompoundControl = bCompound;
947 WinBits Window::GetStyle() const
949 return mpWindowImpl ? mpWindowImpl->mnStyle : 0;
952 WinBits Window::GetPrevStyle() const
954 return mpWindowImpl ? mpWindowImpl->mnPrevStyle : 0;
957 WindowExtendedStyle Window::GetExtendedStyle() const
959 return mpWindowImpl ? mpWindowImpl->mnExtendedStyle : WindowExtendedStyle::NONE;
962 void Window::SetType( WindowType nType )
964 if (mpWindowImpl)
965 mpWindowImpl->mnType = nType;
968 WindowType Window::GetType() const
970 if (mpWindowImpl)
971 return mpWindowImpl->mnType;
972 else
973 return WindowType::NONE;
976 Dialog* Window::GetParentDialog() const
978 const vcl::Window *pWindow = this;
980 while( pWindow )
982 if( pWindow->IsDialog() )
983 break;
985 pWindow = pWindow->GetParent();
988 return const_cast<Dialog *>(dynamic_cast<const Dialog*>(pWindow));
991 bool Window::IsSystemWindow() const
993 return mpWindowImpl && mpWindowImpl->mbSysWin;
996 bool Window::IsDialog() const
998 return mpWindowImpl && mpWindowImpl->mbDialog;
1001 bool Window::IsMenuFloatingWindow() const
1003 return mpWindowImpl && mpWindowImpl->mbMenuFloatingWindow;
1006 bool Window::IsToolbarFloatingWindow() const
1008 return mpWindowImpl && mpWindowImpl->mbToolbarFloatingWindow;
1011 void Window::EnableAllResize()
1013 mpWindowImpl->mbAllResize = true;
1016 void Window::EnableChildTransparentMode( bool bEnable )
1018 mpWindowImpl->mbChildTransparent = bEnable;
1021 bool Window::IsChildTransparentModeEnabled() const
1023 return mpWindowImpl && mpWindowImpl->mbChildTransparent;
1026 bool Window::IsMouseTransparent() const
1028 return mpWindowImpl && mpWindowImpl->mbMouseTransparent;
1031 bool Window::IsPaintTransparent() const
1033 return mpWindowImpl && mpWindowImpl->mbPaintTransparent;
1036 void Window::SetDialogControlStart( bool bStart )
1038 mpWindowImpl->mbDlgCtrlStart = bStart;
1041 bool Window::IsDialogControlStart() const
1043 return mpWindowImpl && mpWindowImpl->mbDlgCtrlStart;
1046 void Window::SetDialogControlFlags( DialogControlFlags nFlags )
1048 mpWindowImpl->mnDlgCtrlFlags = nFlags;
1051 DialogControlFlags Window::GetDialogControlFlags() const
1053 return mpWindowImpl->mnDlgCtrlFlags;
1056 const InputContext& Window::GetInputContext() const
1058 return mpWindowImpl->maInputContext;
1061 bool Window::IsControlFont() const
1063 return bool(mpWindowImpl->mpControlFont);
1066 const Color& Window::GetControlForeground() const
1068 return mpWindowImpl->maControlForeground;
1071 bool Window::IsControlForeground() const
1073 return mpWindowImpl->mbControlForeground;
1076 const Color& Window::GetControlBackground() const
1078 return mpWindowImpl->maControlBackground;
1081 bool Window::IsControlBackground() const
1083 return mpWindowImpl->mbControlBackground;
1086 bool Window::IsInPaint() const
1088 return mpWindowImpl && mpWindowImpl->mbInPaint;
1091 vcl::Window* Window::GetParent() const
1093 return mpWindowImpl ? mpWindowImpl->mpRealParent.get() : nullptr;
1096 bool Window::IsVisible() const
1098 return mpWindowImpl && mpWindowImpl->mbVisible;
1101 bool Window::IsReallyVisible() const
1103 return mpWindowImpl && mpWindowImpl->mbReallyVisible;
1106 bool Window::IsReallyShown() const
1108 return mpWindowImpl && mpWindowImpl->mbReallyShown;
1111 bool Window::IsInInitShow() const
1113 return mpWindowImpl->mbInInitShow;
1116 bool Window::IsEnabled() const
1118 return mpWindowImpl && !mpWindowImpl->mbDisabled;
1121 bool Window::IsInputEnabled() const
1123 return mpWindowImpl && !mpWindowImpl->mbInputDisabled;
1126 bool Window::IsAlwaysEnableInput() const
1128 return mpWindowImpl->meAlwaysInputMode == AlwaysInputEnabled;
1131 ActivateModeFlags Window::GetActivateMode() const
1133 return mpWindowImpl->mnActivateMode;
1137 bool Window::IsAlwaysOnTopEnabled() const
1139 return mpWindowImpl->mbAlwaysOnTop;
1142 bool Window::IsDefaultPos() const
1144 return mpWindowImpl->mbDefPos;
1147 bool Window::IsDefaultSize() const
1149 return mpWindowImpl->mbDefSize;
1152 Point Window::GetOffsetPixelFrom(const vcl::Window& rWindow) const
1154 return Point(GetOutOffXPixel() - rWindow.GetOutOffXPixel(), GetOutOffYPixel() - rWindow.GetOutOffYPixel());
1157 void Window::EnablePaint( bool bEnable )
1159 mpWindowImpl->mbPaintDisabled = !bEnable;
1162 bool Window::IsPaintEnabled() const
1164 return !mpWindowImpl->mbPaintDisabled;
1167 bool Window::IsUpdateMode() const
1169 return !mpWindowImpl->mbNoUpdate;
1172 void Window::SetParentUpdateMode( bool bUpdate )
1174 mpWindowImpl->mbNoParentUpdate = !bUpdate;
1177 bool Window::IsActive() const
1179 return mpWindowImpl->mbActive;
1182 GetFocusFlags Window::GetGetFocusFlags() const
1184 return mpWindowImpl->mnGetFocusFlags;
1187 bool Window::IsCompoundControl() const
1189 return mpWindowImpl && mpWindowImpl->mbCompoundControl;
1192 bool Window::IsWait() const
1194 return (mpWindowImpl->mnWaitCount != 0);
1197 vcl::Cursor* Window::GetCursor() const
1199 if (!mpWindowImpl)
1200 return nullptr;
1201 return mpWindowImpl->mpCursor;
1204 const Fraction& Window::GetZoom() const
1206 return mpWindowImpl->maZoom;
1209 bool Window::IsZoom() const
1211 return mpWindowImpl->maZoom.GetNumerator() != mpWindowImpl->maZoom.GetDenominator();
1214 void Window::SetHelpText( const OUString& rHelpText )
1216 mpWindowImpl->maHelpText = rHelpText;
1217 mpWindowImpl->mbHelpTextDynamic = true;
1220 void Window::SetQuickHelpText( const OUString& rHelpText )
1222 if (mpWindowImpl)
1223 mpWindowImpl->maQuickHelpText = rHelpText;
1226 const OUString& Window::GetQuickHelpText() const
1228 return mpWindowImpl->maQuickHelpText;
1231 bool Window::IsCreatedWithToolkit() const
1233 return mpWindowImpl->mbCreatedWithToolkit;
1236 void Window::SetCreatedWithToolkit( bool b )
1238 mpWindowImpl->mbCreatedWithToolkit = b;
1241 PointerStyle Window::GetPointer() const
1243 return mpWindowImpl->maPointer;
1246 VCLXWindow* Window::GetWindowPeer() const
1248 return mpWindowImpl ? mpWindowImpl->mpVCLXWindow : nullptr;
1251 void Window::SetPosPixel( const Point& rNewPos )
1253 setPosSizePixel( rNewPos.X(), rNewPos.Y(), 0, 0, PosSizeFlags::Pos );
1256 void Window::SetSizePixel( const Size& rNewSize )
1258 setPosSizePixel( 0, 0, rNewSize.Width(), rNewSize.Height(),
1259 PosSizeFlags::Size );
1262 void Window::SetPosSizePixel( const Point& rNewPos, const Size& rNewSize )
1264 setPosSizePixel( rNewPos.X(), rNewPos.Y(),
1265 rNewSize.Width(), rNewSize.Height());
1268 void Window::SetOutputSizePixel( const Size& rNewSize )
1270 SetSizePixel( Size( rNewSize.Width()+mpWindowImpl->mnLeftBorder+mpWindowImpl->mnRightBorder,
1271 rNewSize.Height()+mpWindowImpl->mnTopBorder+mpWindowImpl->mnBottomBorder ) );
1274 //When a widget wants to renegotiate layout, get toplevel parent dialog and call
1275 //resize on it. Mark all intermediate containers (or container-alike) widgets
1276 //as dirty for the size remains unchanged, but layout changed circumstances
1277 namespace
1279 bool queue_ungrouped_resize(vcl::Window const *pOrigWindow)
1281 bool bSomeoneCares = false;
1283 vcl::Window *pWindow = pOrigWindow->GetParent();
1284 if (pWindow)
1286 if (isContainerWindow(*pWindow))
1288 bSomeoneCares = true;
1290 else if (pWindow->GetType() == WindowType::TABCONTROL)
1292 bSomeoneCares = true;
1294 pWindow->queue_resize();
1297 return bSomeoneCares;
1301 void Window::InvalidateSizeCache()
1303 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1304 pWindowImpl->mnOptimalWidthCache = -1;
1305 pWindowImpl->mnOptimalHeightCache = -1;
1308 static bool HasParentDockingWindow(const vcl::Window* pWindow)
1310 while( pWindow )
1312 if( pWindow->IsDockingWindow() )
1313 return true;
1315 pWindow = pWindow->GetParent();
1318 return false;
1321 void Window::queue_resize(StateChangedType eReason)
1323 if (isDisposed())
1324 return;
1326 bool bSomeoneCares = queue_ungrouped_resize(this);
1328 if (eReason != StateChangedType::Visible)
1330 InvalidateSizeCache();
1333 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1334 if (pWindowImpl->m_xSizeGroup && pWindowImpl->m_xSizeGroup->get_mode() != VclSizeGroupMode::NONE)
1336 std::set<VclPtr<vcl::Window> > &rWindows = pWindowImpl->m_xSizeGroup->get_widgets();
1337 for (VclPtr<vcl::Window> const & pOther : rWindows)
1339 if (pOther == this)
1340 continue;
1341 queue_ungrouped_resize(pOther);
1345 if (bSomeoneCares && !isDisposed())
1347 //fdo#57090 force a resync of the borders of the borderwindow onto this
1348 //window in case they have changed
1349 vcl::Window* pBorderWindow = ImplGetBorderWindow();
1350 if (pBorderWindow)
1351 pBorderWindow->Resize();
1353 if (VclPtr<vcl::Window> pParent = GetParentWithLOKNotifier())
1355 Size aSize = GetSizePixel();
1356 if (!aSize.IsEmpty() && !pParent->IsInInitShow()
1357 && (GetParentDialog() || HasParentDockingWindow(this)))
1358 LogicInvalidate(nullptr);
1362 namespace
1364 VclAlign toAlign(std::u16string_view rValue)
1366 VclAlign eRet = VclAlign::Fill;
1368 if (rValue == u"fill")
1369 eRet = VclAlign::Fill;
1370 else if (rValue == u"start")
1371 eRet = VclAlign::Start;
1372 else if (rValue == u"end")
1373 eRet = VclAlign::End;
1374 else if (rValue == u"center")
1375 eRet = VclAlign::Center;
1376 return eRet;
1380 bool Window::set_font_attribute(const OString &rKey, const OUString &rValue)
1382 if (rKey == "weight")
1384 vcl::Font aFont(GetControlFont());
1385 if (rValue == "thin")
1386 aFont.SetWeight(WEIGHT_THIN);
1387 else if (rValue == "ultralight")
1388 aFont.SetWeight(WEIGHT_ULTRALIGHT);
1389 else if (rValue == "light")
1390 aFont.SetWeight(WEIGHT_LIGHT);
1391 else if (rValue == "book")
1392 aFont.SetWeight(WEIGHT_SEMILIGHT);
1393 else if (rValue == "normal")
1394 aFont.SetWeight(WEIGHT_NORMAL);
1395 else if (rValue == "medium")
1396 aFont.SetWeight(WEIGHT_MEDIUM);
1397 else if (rValue == "semibold")
1398 aFont.SetWeight(WEIGHT_SEMIBOLD);
1399 else if (rValue == "bold")
1400 aFont.SetWeight(WEIGHT_BOLD);
1401 else if (rValue == "ultrabold")
1402 aFont.SetWeight(WEIGHT_ULTRABOLD);
1403 else
1404 aFont.SetWeight(WEIGHT_BLACK);
1405 SetControlFont(aFont);
1407 else if (rKey == "style")
1409 vcl::Font aFont(GetControlFont());
1410 if (rValue == "normal")
1411 aFont.SetItalic(ITALIC_NONE);
1412 else if (rValue == "oblique")
1413 aFont.SetItalic(ITALIC_OBLIQUE);
1414 else if (rValue == "italic")
1415 aFont.SetItalic(ITALIC_NORMAL);
1416 SetControlFont(aFont);
1418 else if (rKey == "underline")
1420 vcl::Font aFont(GetControlFont());
1421 aFont.SetUnderline(toBool(rValue) ? LINESTYLE_SINGLE : LINESTYLE_NONE);
1422 SetControlFont(aFont);
1424 else if (rKey == "size")
1426 vcl::Font aFont(GetControlFont());
1427 sal_Int32 nHeight = rValue.toInt32() / 1000;
1428 aFont.SetFontHeight(nHeight);
1429 SetControlFont(aFont);
1431 else
1433 SAL_INFO("vcl.layout", "unhandled font attribute: " << rKey);
1434 return false;
1436 return true;
1439 bool Window::set_property(const OString &rKey, const OUString &rValue)
1441 if ((rKey == "label") || (rKey == "title") || (rKey == "text") )
1443 SetText(BuilderUtils::convertMnemonicMarkup(rValue));
1445 else if (rKey == "visible")
1446 Show(toBool(rValue));
1447 else if (rKey == "sensitive")
1448 Enable(toBool(rValue));
1449 else if (rKey == "resizable")
1451 WinBits nBits = GetStyle();
1452 nBits &= ~WB_SIZEABLE;
1453 if (toBool(rValue))
1454 nBits |= WB_SIZEABLE;
1455 SetStyle(nBits);
1457 else if (rKey == "xalign")
1459 WinBits nBits = GetStyle();
1460 nBits &= ~(WB_LEFT | WB_CENTER | WB_RIGHT);
1462 float f = rValue.toFloat();
1463 assert(f == 0.0 || f == 1.0 || f == 0.5);
1464 if (f == 0.0)
1465 nBits |= WB_LEFT;
1466 else if (f == 1.0)
1467 nBits |= WB_RIGHT;
1468 else if (f == 0.5)
1469 nBits |= WB_CENTER;
1471 SetStyle(nBits);
1473 else if (rKey == "justification")
1475 WinBits nBits = GetStyle();
1476 nBits &= ~(WB_LEFT | WB_CENTER | WB_RIGHT);
1478 if (rValue == "left")
1479 nBits |= WB_LEFT;
1480 else if (rValue == "right")
1481 nBits |= WB_RIGHT;
1482 else if (rValue == "center")
1483 nBits |= WB_CENTER;
1485 SetStyle(nBits);
1487 else if (rKey == "yalign")
1489 WinBits nBits = GetStyle();
1490 nBits &= ~(WB_TOP | WB_VCENTER | WB_BOTTOM);
1492 float f = rValue.toFloat();
1493 assert(f == 0.0 || f == 1.0 || f == 0.5);
1494 if (f == 0.0)
1495 nBits |= WB_TOP;
1496 else if (f == 1.0)
1497 nBits |= WB_BOTTOM;
1498 else if (f == 0.5)
1499 nBits |= WB_CENTER;
1501 SetStyle(nBits);
1503 else if (rKey == "wrap")
1505 WinBits nBits = GetStyle();
1506 nBits &= ~WB_WORDBREAK;
1507 if (toBool(rValue))
1508 nBits |= WB_WORDBREAK;
1509 SetStyle(nBits);
1511 else if (rKey == "height-request")
1512 set_height_request(rValue.toInt32());
1513 else if (rKey == "width-request")
1514 set_width_request(rValue.toInt32());
1515 else if (rKey == "hexpand")
1516 set_hexpand(toBool(rValue));
1517 else if (rKey == "vexpand")
1518 set_vexpand(toBool(rValue));
1519 else if (rKey == "halign")
1520 set_halign(toAlign(rValue));
1521 else if (rKey == "valign")
1522 set_valign(toAlign(rValue));
1523 else if (rKey == "tooltip-markup")
1524 SetQuickHelpText(rValue);
1525 else if (rKey == "tooltip-text")
1526 SetQuickHelpText(rValue);
1527 else if (rKey == "border-width")
1528 set_border_width(rValue.toInt32());
1529 else if (rKey == "margin-start" || rKey == "margin-left")
1531 assert(rKey == "margin-start" && "margin-left deprecated in favor of margin-start");
1532 set_margin_start(rValue.toInt32());
1534 else if (rKey == "margin-end" || rKey == "margin-right")
1536 assert(rKey == "margin-end" && "margin-right deprecated in favor of margin-end");
1537 set_margin_end(rValue.toInt32());
1539 else if (rKey == "margin-top")
1540 set_margin_top(rValue.toInt32());
1541 else if (rKey == "margin-bottom")
1542 set_margin_bottom(rValue.toInt32());
1543 else if (rKey == "hscrollbar-policy")
1545 WinBits nBits = GetStyle();
1546 nBits &= ~(WB_AUTOHSCROLL|WB_HSCROLL);
1547 if (rValue == "always")
1548 nBits |= WB_HSCROLL;
1549 else if (rValue == "automatic")
1550 nBits |= WB_AUTOHSCROLL;
1551 SetStyle(nBits);
1553 else if (rKey == "vscrollbar-policy")
1555 WinBits nBits = GetStyle();
1556 nBits &= ~(WB_AUTOVSCROLL|WB_VSCROLL);
1557 if (rValue == "always")
1558 nBits |= WB_VSCROLL;
1559 else if (rValue == "automatic")
1560 nBits |= WB_AUTOVSCROLL;
1561 SetStyle(nBits);
1563 else if (rKey == "accessible-name")
1565 SetAccessibleName(rValue);
1567 else if (rKey == "accessible-description")
1569 SetAccessibleDescription(rValue);
1571 else if (rKey == "accessible-role")
1573 sal_Int16 role = BuilderUtils::getRoleFromName(rValue.toUtf8());
1574 if (role != com::sun::star::accessibility::AccessibleRole::UNKNOWN)
1575 SetAccessibleRole(role);
1577 else if (rKey == "use-markup")
1579 //https://live.gnome.org/GnomeGoals/RemoveMarkupInMessages
1580 SAL_WARN_IF(toBool(rValue), "vcl.layout", "Use pango attributes instead of mark-up");
1582 else if (rKey == "has-focus")
1584 if (toBool(rValue))
1585 GrabFocus();
1587 else if (rKey == "can-focus")
1589 WinBits nBits = GetStyle();
1590 nBits &= ~(WB_TABSTOP|WB_NOTABSTOP);
1591 if (toBool(rValue))
1592 nBits |= WB_TABSTOP;
1593 else
1594 nBits |= WB_NOTABSTOP;
1595 SetStyle(nBits);
1597 else
1599 SAL_INFO("vcl.layout", "unhandled property: " << rKey);
1600 return false;
1602 return true;
1605 void Window::set_height_request(sal_Int32 nHeightRequest)
1607 if (!mpWindowImpl)
1608 return;
1610 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1612 if ( pWindowImpl->mnHeightRequest != nHeightRequest )
1614 pWindowImpl->mnHeightRequest = nHeightRequest;
1615 queue_resize();
1619 void Window::set_width_request(sal_Int32 nWidthRequest)
1621 if (!mpWindowImpl)
1622 return;
1624 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1626 if ( pWindowImpl->mnWidthRequest != nWidthRequest )
1628 pWindowImpl->mnWidthRequest = nWidthRequest;
1629 queue_resize();
1633 Size Window::get_ungrouped_preferred_size() const
1635 Size aRet(get_width_request(), get_height_request());
1636 if (aRet.Width() == -1 || aRet.Height() == -1)
1638 //cache gets blown away by queue_resize
1639 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1640 if (pWindowImpl->mnOptimalWidthCache == -1 || pWindowImpl->mnOptimalHeightCache == -1)
1642 Size aOptimal(GetOptimalSize());
1643 pWindowImpl->mnOptimalWidthCache = aOptimal.Width();
1644 pWindowImpl->mnOptimalHeightCache = aOptimal.Height();
1647 if (aRet.Width() == -1)
1648 aRet.setWidth( pWindowImpl->mnOptimalWidthCache );
1649 if (aRet.Height() == -1)
1650 aRet.setHeight( pWindowImpl->mnOptimalHeightCache );
1652 return aRet;
1655 Size Window::get_preferred_size() const
1657 Size aRet(get_ungrouped_preferred_size());
1659 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1660 if (pWindowImpl->m_xSizeGroup)
1662 const VclSizeGroupMode eMode = pWindowImpl->m_xSizeGroup->get_mode();
1663 if (eMode != VclSizeGroupMode::NONE)
1665 const bool bIgnoreInHidden = pWindowImpl->m_xSizeGroup->get_ignore_hidden();
1666 const std::set<VclPtr<vcl::Window> > &rWindows = pWindowImpl->m_xSizeGroup->get_widgets();
1667 for (auto const& window : rWindows)
1669 const vcl::Window *pOther = window;
1670 if (pOther == this)
1671 continue;
1672 if (bIgnoreInHidden && !pOther->IsVisible())
1673 continue;
1674 Size aOtherSize = pOther->get_ungrouped_preferred_size();
1675 if (eMode == VclSizeGroupMode::Both || eMode == VclSizeGroupMode::Horizontal)
1676 aRet.setWidth( std::max(aRet.Width(), aOtherSize.Width()) );
1677 if (eMode == VclSizeGroupMode::Both || eMode == VclSizeGroupMode::Vertical)
1678 aRet.setHeight( std::max(aRet.Height(), aOtherSize.Height()) );
1683 return aRet;
1686 VclAlign Window::get_halign() const
1688 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1689 return pWindowImpl->meHalign;
1692 void Window::set_halign(VclAlign eAlign)
1694 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1695 pWindowImpl->meHalign = eAlign;
1698 VclAlign Window::get_valign() const
1700 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1701 return pWindowImpl->meValign;
1704 void Window::set_valign(VclAlign eAlign)
1706 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1707 pWindowImpl->meValign = eAlign;
1710 bool Window::get_hexpand() const
1712 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1713 return pWindowImpl->mbHexpand;
1716 void Window::set_hexpand(bool bExpand)
1718 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1719 pWindowImpl->mbHexpand = bExpand;
1722 bool Window::get_vexpand() const
1724 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1725 return pWindowImpl->mbVexpand;
1728 void Window::set_vexpand(bool bExpand)
1730 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1731 pWindowImpl->mbVexpand = bExpand;
1734 bool Window::get_expand() const
1736 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1737 return pWindowImpl->mbExpand;
1740 void Window::set_expand(bool bExpand)
1742 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1743 pWindowImpl->mbExpand = bExpand;
1746 VclPackType Window::get_pack_type() const
1748 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1749 return pWindowImpl->mePackType;
1752 void Window::set_pack_type(VclPackType ePackType)
1754 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1755 pWindowImpl->mePackType = ePackType;
1758 sal_Int32 Window::get_padding() const
1760 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1761 return pWindowImpl->mnPadding;
1764 void Window::set_padding(sal_Int32 nPadding)
1766 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1767 pWindowImpl->mnPadding = nPadding;
1770 bool Window::get_fill() const
1772 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1773 return pWindowImpl->mbFill;
1776 void Window::set_fill(bool bFill)
1778 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1779 pWindowImpl->mbFill = bFill;
1782 sal_Int32 Window::get_grid_width() const
1784 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1785 return pWindowImpl->mnGridWidth;
1788 void Window::set_grid_width(sal_Int32 nCols)
1790 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1791 pWindowImpl->mnGridWidth = nCols;
1794 sal_Int32 Window::get_grid_left_attach() const
1796 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1797 return pWindowImpl->mnGridLeftAttach;
1800 void Window::set_grid_left_attach(sal_Int32 nAttach)
1802 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1803 pWindowImpl->mnGridLeftAttach = nAttach;
1806 sal_Int32 Window::get_grid_height() const
1808 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1809 return pWindowImpl->mnGridHeight;
1812 void Window::set_grid_height(sal_Int32 nRows)
1814 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1815 pWindowImpl->mnGridHeight = nRows;
1818 sal_Int32 Window::get_grid_top_attach() const
1820 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1821 return pWindowImpl->mnGridTopAttach;
1824 void Window::set_grid_top_attach(sal_Int32 nAttach)
1826 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1827 pWindowImpl->mnGridTopAttach = nAttach;
1830 void Window::set_border_width(sal_Int32 nBorderWidth)
1832 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1833 pWindowImpl->mnBorderWidth = nBorderWidth;
1836 sal_Int32 Window::get_border_width() const
1838 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1839 return pWindowImpl->mnBorderWidth;
1842 void Window::set_margin_start(sal_Int32 nWidth)
1844 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1845 if (pWindowImpl->mnMarginLeft != nWidth)
1847 pWindowImpl->mnMarginLeft = nWidth;
1848 queue_resize();
1852 sal_Int32 Window::get_margin_start() const
1854 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1855 return pWindowImpl->mnMarginLeft;
1858 void Window::set_margin_end(sal_Int32 nWidth)
1860 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1861 if (pWindowImpl->mnMarginRight != nWidth)
1863 pWindowImpl->mnMarginRight = nWidth;
1864 queue_resize();
1868 sal_Int32 Window::get_margin_end() const
1870 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1871 return pWindowImpl->mnMarginRight;
1874 void Window::set_margin_top(sal_Int32 nWidth)
1876 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1877 if (pWindowImpl->mnMarginTop != nWidth)
1879 pWindowImpl->mnMarginTop = nWidth;
1880 queue_resize();
1884 sal_Int32 Window::get_margin_top() const
1886 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1887 return pWindowImpl->mnMarginTop;
1890 void Window::set_margin_bottom(sal_Int32 nWidth)
1892 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1893 if (pWindowImpl->mnMarginBottom != nWidth)
1895 pWindowImpl->mnMarginBottom = nWidth;
1896 queue_resize();
1900 sal_Int32 Window::get_margin_bottom() const
1902 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1903 return pWindowImpl->mnMarginBottom;
1906 sal_Int32 Window::get_height_request() const
1908 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1909 return pWindowImpl->mnHeightRequest;
1912 sal_Int32 Window::get_width_request() const
1914 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1915 return pWindowImpl->mnWidthRequest;
1918 bool Window::get_secondary() const
1920 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1921 return pWindowImpl->mbSecondary;
1924 void Window::set_secondary(bool bSecondary)
1926 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1927 pWindowImpl->mbSecondary = bSecondary;
1930 bool Window::get_non_homogeneous() const
1932 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1933 return pWindowImpl->mbNonHomogeneous;
1936 void Window::set_non_homogeneous(bool bNonHomogeneous)
1938 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1939 pWindowImpl->mbNonHomogeneous = bNonHomogeneous;
1942 void Window::add_to_size_group(const std::shared_ptr<VclSizeGroup>& xGroup)
1944 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1945 //To-Do, multiple groups
1946 pWindowImpl->m_xSizeGroup = xGroup;
1947 pWindowImpl->m_xSizeGroup->insert(this);
1948 if (VclSizeGroupMode::NONE != pWindowImpl->m_xSizeGroup->get_mode())
1949 queue_resize();
1952 void Window::remove_from_all_size_groups()
1954 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1955 //To-Do, multiple groups
1956 if (pWindowImpl->m_xSizeGroup)
1958 if (VclSizeGroupMode::NONE != pWindowImpl->m_xSizeGroup->get_mode())
1959 queue_resize();
1960 pWindowImpl->m_xSizeGroup->erase(this);
1961 pWindowImpl->m_xSizeGroup.reset();
1965 void Window::add_mnemonic_label(FixedText *pLabel)
1967 std::vector<VclPtr<FixedText> >& v = mpWindowImpl->m_aMnemonicLabels;
1968 if (std::find(v.begin(), v.end(), VclPtr<FixedText>(pLabel)) != v.end())
1969 return;
1970 v.emplace_back(pLabel);
1971 pLabel->set_mnemonic_widget(this);
1974 void Window::remove_mnemonic_label(FixedText *pLabel)
1976 std::vector<VclPtr<FixedText> >& v = mpWindowImpl->m_aMnemonicLabels;
1977 auto aFind = std::find(v.begin(), v.end(), VclPtr<FixedText>(pLabel));
1978 if (aFind == v.end())
1979 return;
1980 v.erase(aFind);
1981 pLabel->set_mnemonic_widget(nullptr);
1984 const std::vector<VclPtr<FixedText> >& Window::list_mnemonic_labels() const
1986 return mpWindowImpl->m_aMnemonicLabels;
1989 } /* namespace vcl */
1991 void InvertFocusRect(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
1993 const int nBorder = 1;
1994 rRenderContext.Invert(tools::Rectangle(Point(rRect.Left(), rRect.Top()), Size(rRect.GetWidth(), nBorder)), InvertFlags::N50);
1995 rRenderContext.Invert(tools::Rectangle(Point(rRect.Left(), rRect.Bottom()-nBorder+1), Size(rRect.GetWidth(), nBorder)), InvertFlags::N50);
1996 rRenderContext.Invert(tools::Rectangle(Point(rRect.Left(), rRect.Top()+nBorder), Size(nBorder, rRect.GetHeight()-(nBorder*2))), InvertFlags::N50);
1997 rRenderContext.Invert(tools::Rectangle(Point(rRect.Right()-nBorder+1, rRect.Top()+nBorder), Size(nBorder, rRect.GetHeight()-(nBorder*2))), InvertFlags::N50);
2000 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */