build fix: no comphelper/profilezone.hxx in this branch
[LibreOffice.git] / vcl / source / window / window2.cxx
blob7617937925dc378c61808bb2b70cfed03ddd74dd
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>
21 #include <tools/debug.hxx>
22 #include <tools/poly.hxx>
24 #include <vcl/bitmap.hxx>
25 #include <vcl/dialog.hxx>
26 #include <vcl/event.hxx>
27 #include <vcl/fixed.hxx>
28 #include <vcl/layout.hxx>
29 #include <vcl/timer.hxx>
30 #include <vcl/metric.hxx>
31 #include <vcl/virdev.hxx>
32 #include <vcl/window.hxx>
33 #include <vcl/scrbar.hxx>
34 #include <vcl/dockwin.hxx>
35 #include <vcl/tabctrl.hxx>
36 #include <vcl/settings.hxx>
38 #include <window.h>
39 #include <fontinstance.hxx>
40 #include <outdev.h>
41 #include <svdata.hxx>
42 #include <impbmp.hxx>
43 #include <salbmp.hxx>
44 #include <salgdi.hxx>
45 #include <salframe.hxx>
46 #include <scrwnd.hxx>
48 using namespace com::sun::star;
50 namespace vcl {
52 void Window::ShowFocus( const Rectangle& rRect )
54 if( mpWindowImpl->mbInShowFocus )
55 return;
56 mpWindowImpl->mbInShowFocus = true;
58 ImplWinData* pWinData = ImplGetWinData();
60 // native themeing suggest not to use focus rects
61 if( ! ( mpWindowImpl->mbUseNativeFocus &&
62 IsNativeWidgetEnabled() ) )
64 if ( !mpWindowImpl->mbInPaint )
66 if ( mpWindowImpl->mbFocusVisible )
68 if ( *(pWinData->mpFocusRect) == rRect )
70 mpWindowImpl->mbInShowFocus = false;
71 return;
74 ImplInvertFocus( *(pWinData->mpFocusRect) );
77 ImplInvertFocus( rRect );
79 if ( !pWinData->mpFocusRect )
80 pWinData->mpFocusRect = new Rectangle( rRect );
81 else
82 *(pWinData->mpFocusRect) = rRect;
83 mpWindowImpl->mbFocusVisible = true;
85 else
87 if( ! mpWindowImpl->mbNativeFocusVisible )
89 mpWindowImpl->mbNativeFocusVisible = true;
90 if ( !mpWindowImpl->mbInPaint )
91 Invalidate();
94 mpWindowImpl->mbInShowFocus = false;
97 void Window::HideFocus()
100 if( mpWindowImpl->mbInHideFocus )
101 return;
102 mpWindowImpl->mbInHideFocus = true;
104 // native themeing can suggest not to use focus rects
105 if( ! ( mpWindowImpl->mbUseNativeFocus &&
106 IsNativeWidgetEnabled() ) )
108 if ( !mpWindowImpl->mbFocusVisible )
110 mpWindowImpl->mbInHideFocus = false;
111 return;
114 if ( !mpWindowImpl->mbInPaint )
115 ImplInvertFocus( *(ImplGetWinData()->mpFocusRect) );
116 mpWindowImpl->mbFocusVisible = false;
118 else
120 if( mpWindowImpl->mbNativeFocusVisible )
122 mpWindowImpl->mbNativeFocusVisible = false;
123 if ( !mpWindowImpl->mbInPaint )
124 Invalidate();
127 mpWindowImpl->mbInHideFocus = false;
130 void Window::ShowTracking( const Rectangle& rRect, ShowTrackFlags nFlags )
132 ImplWinData* pWinData = ImplGetWinData();
134 if ( !mpWindowImpl->mbInPaint || !(nFlags & ShowTrackFlags::TrackWindow) )
136 if ( mpWindowImpl->mbTrackVisible )
138 if ( (*(pWinData->mpTrackRect) == rRect) &&
139 (pWinData->mnTrackFlags == nFlags) )
140 return;
142 InvertTracking( *(pWinData->mpTrackRect), pWinData->mnTrackFlags );
145 InvertTracking( rRect, nFlags );
148 if ( !pWinData->mpTrackRect )
149 pWinData->mpTrackRect = new Rectangle( rRect );
150 else
151 *(pWinData->mpTrackRect) = rRect;
152 pWinData->mnTrackFlags = nFlags;
153 mpWindowImpl->mbTrackVisible = true;
156 void Window::HideTracking()
158 if ( mpWindowImpl->mbTrackVisible )
160 ImplWinData* pWinData = ImplGetWinData();
161 if ( !mpWindowImpl->mbInPaint || !(pWinData->mnTrackFlags & ShowTrackFlags::TrackWindow) )
162 InvertTracking( *(pWinData->mpTrackRect), pWinData->mnTrackFlags );
163 mpWindowImpl->mbTrackVisible = false;
167 void Window::InvertTracking( const Rectangle& rRect, ShowTrackFlags nFlags )
169 OutputDevice *pOutDev = GetOutDev();
170 Rectangle aRect( pOutDev->ImplLogicToDevicePixel( rRect ) );
172 if ( aRect.IsEmpty() )
173 return;
174 aRect.Justify();
176 SalGraphics* pGraphics;
178 if ( nFlags & ShowTrackFlags::TrackWindow )
180 if ( !IsDeviceOutputNecessary() )
181 return;
183 // we need a graphics
184 if ( !mpGraphics )
186 if ( !pOutDev->AcquireGraphics() )
187 return;
190 if ( mbInitClipRegion )
191 InitClipRegion();
193 if ( mbOutputClipped )
194 return;
196 pGraphics = mpGraphics;
198 else
200 pGraphics = ImplGetFrameGraphics();
202 if ( nFlags & ShowTrackFlags::Clip )
204 Point aPoint( mnOutOffX, mnOutOffY );
205 vcl::Region aRegion( Rectangle( aPoint,
206 Size( mnOutWidth, mnOutHeight ) ) );
207 ImplClipBoundaries( aRegion, false, false );
208 pOutDev->SelectClipRegion( aRegion, pGraphics );
212 ShowTrackFlags nStyle = nFlags & ShowTrackFlags::StyleMask;
213 if ( nStyle == ShowTrackFlags::Object )
214 pGraphics->Invert( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight(), SalInvert::TrackFrame, this );
215 else if ( nStyle == ShowTrackFlags::Split )
216 pGraphics->Invert( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight(), SalInvert::N50, this );
217 else
219 long nBorder = 1;
220 if ( nStyle == ShowTrackFlags::Big )
221 nBorder = 5;
222 pGraphics->Invert( aRect.Left(), aRect.Top(), aRect.GetWidth(), nBorder, SalInvert::N50, this );
223 pGraphics->Invert( aRect.Left(), aRect.Bottom()-nBorder+1, aRect.GetWidth(), nBorder, SalInvert::N50, this );
224 pGraphics->Invert( aRect.Left(), aRect.Top()+nBorder, nBorder, aRect.GetHeight()-(nBorder*2), SalInvert::N50, this );
225 pGraphics->Invert( aRect.Right()-nBorder+1, aRect.Top()+nBorder, nBorder, aRect.GetHeight()-(nBorder*2), SalInvert::N50, this );
229 void Window::InvertTracking( const tools::Polygon& rPoly, ShowTrackFlags nFlags )
231 sal_uInt16 nPoints = rPoly.GetSize();
233 if ( nPoints < 2 )
234 return;
236 OutputDevice *pOutDev = GetOutDev();
238 tools::Polygon aPoly( pOutDev->ImplLogicToDevicePixel( rPoly ) );
240 SalGraphics* pGraphics;
242 if ( nFlags & ShowTrackFlags::TrackWindow )
244 if ( !IsDeviceOutputNecessary() )
245 return;
247 // we need a graphics
248 if ( !mpGraphics )
250 if ( !pOutDev->AcquireGraphics() )
251 return;
254 if ( mbInitClipRegion )
255 InitClipRegion();
257 if ( mbOutputClipped )
258 return;
260 pGraphics = mpGraphics;
262 else
264 pGraphics = ImplGetFrameGraphics();
266 if ( nFlags & ShowTrackFlags::Clip )
268 Point aPoint( mnOutOffX, mnOutOffY );
269 vcl::Region aRegion( Rectangle( aPoint,
270 Size( mnOutWidth, mnOutHeight ) ) );
271 ImplClipBoundaries( aRegion, false, false );
272 pOutDev->SelectClipRegion( aRegion, pGraphics );
276 const SalPoint* pPtAry = reinterpret_cast<const SalPoint*>(aPoly.GetConstPointAry());
277 pGraphics->Invert( nPoints, pPtAry, SalInvert::TrackFrame, this );
280 IMPL_LINK( Window, ImplTrackTimerHdl, Timer*, pTimer, void )
282 ImplSVData* pSVData = ImplGetSVData();
284 // Bei Button-Repeat muessen wir den Timeout umsetzen
285 if ( pSVData->maWinData.mnTrackFlags & StartTrackingFlags::ButtonRepeat )
286 pTimer->SetTimeout( GetSettings().GetMouseSettings().GetButtonRepeat() );
288 // Tracking-Event erzeugen
289 Point aMousePos( mpWindowImpl->mpFrameData->mnLastMouseX, mpWindowImpl->mpFrameData->mnLastMouseY );
290 if( ImplIsAntiparallel() )
292 // - RTL - re-mirror frame pos at pChild
293 const OutputDevice *pOutDev = GetOutDev();
294 pOutDev->ReMirror( aMousePos );
296 MouseEvent aMEvt( ImplFrameToOutput( aMousePos ),
297 mpWindowImpl->mpFrameData->mnClickCount, MouseEventModifiers::NONE,
298 mpWindowImpl->mpFrameData->mnMouseCode,
299 mpWindowImpl->mpFrameData->mnMouseCode );
300 TrackingEvent aTEvt( aMEvt, TrackingEventFlags::Repeat );
301 Tracking( aTEvt );
304 void Window::StartTracking( StartTrackingFlags nFlags )
306 ImplSVData* pSVData = ImplGetSVData();
308 if ( pSVData->maWinData.mpTrackWin.get() != this )
310 if ( pSVData->maWinData.mpTrackWin )
311 pSVData->maWinData.mpTrackWin->EndTracking( TrackingEventFlags::Cancel );
314 if ( nFlags & (StartTrackingFlags::ScrollRepeat | StartTrackingFlags::ButtonRepeat) )
316 pSVData->maWinData.mpTrackTimer = new AutoTimer;
318 if ( nFlags & StartTrackingFlags::ScrollRepeat )
319 pSVData->maWinData.mpTrackTimer->SetTimeout( GetSettings().GetMouseSettings().GetScrollRepeat() );
320 else
321 pSVData->maWinData.mpTrackTimer->SetTimeout( GetSettings().GetMouseSettings().GetButtonStartRepeat() );
322 pSVData->maWinData.mpTrackTimer->SetTimeoutHdl( LINK( this, Window, ImplTrackTimerHdl ) );
323 pSVData->maWinData.mpTrackTimer->SetDebugName( "vcl::Window pSVData->maWinData.mpTrackTimer" );
324 pSVData->maWinData.mpTrackTimer->Start();
327 pSVData->maWinData.mpTrackWin = this;
328 pSVData->maWinData.mnTrackFlags = nFlags;
329 CaptureMouse();
332 void Window::EndTracking( TrackingEventFlags nFlags )
334 ImplSVData* pSVData = ImplGetSVData();
336 if ( pSVData->maWinData.mpTrackWin.get() == this )
338 // due to DbgChkThis in brackets, as the window could be destroyed
339 // in the handler
342 if ( pSVData->maWinData.mpTrackTimer )
344 delete pSVData->maWinData.mpTrackTimer;
345 pSVData->maWinData.mpTrackTimer = nullptr;
348 pSVData->maWinData.mpTrackWin = nullptr;
349 pSVData->maWinData.mnTrackFlags = StartTrackingFlags::NONE;
350 ReleaseMouse();
353 // call EndTracking if required
354 if ( !(nFlags & TrackingEventFlags::DontCallHdl) )
356 Point aMousePos( mpWindowImpl->mpFrameData->mnLastMouseX, mpWindowImpl->mpFrameData->mnLastMouseY );
357 if( ImplIsAntiparallel() )
359 // - RTL - re-mirror frame pos at pChild
360 const OutputDevice *pOutDev = GetOutDev();
361 pOutDev->ReMirror( aMousePos );
364 MouseEvent aMEvt( ImplFrameToOutput( aMousePos ),
365 mpWindowImpl->mpFrameData->mnClickCount, MouseEventModifiers::NONE,
366 mpWindowImpl->mpFrameData->mnMouseCode,
367 mpWindowImpl->mpFrameData->mnMouseCode );
368 TrackingEvent aTEvt( aMEvt, nFlags | TrackingEventFlags::End );
369 // CompatTracking effectively
370 if (!mpWindowImpl || mpWindowImpl->mbInDispose)
371 return Window::Tracking( aTEvt );
372 else
373 return Tracking( aTEvt );
378 bool Window::IsTracking() const
380 return (ImplGetSVData()->maWinData.mpTrackWin == this);
383 void Window::StartAutoScroll( StartAutoScrollFlags nFlags )
385 ImplSVData* pSVData = ImplGetSVData();
387 if ( pSVData->maWinData.mpAutoScrollWin.get() != this )
389 if ( pSVData->maWinData.mpAutoScrollWin )
390 pSVData->maWinData.mpAutoScrollWin->EndAutoScroll();
393 pSVData->maWinData.mpAutoScrollWin = this;
394 pSVData->maWinData.mnAutoScrollFlags = nFlags;
395 pSVData->maAppData.mpWheelWindow = VclPtr<ImplWheelWindow>::Create( this );
398 void Window::EndAutoScroll()
400 ImplSVData* pSVData = ImplGetSVData();
402 if ( pSVData->maWinData.mpAutoScrollWin.get() == this )
404 pSVData->maWinData.mpAutoScrollWin = nullptr;
405 pSVData->maWinData.mnAutoScrollFlags = StartAutoScrollFlags::NONE;
406 pSVData->maAppData.mpWheelWindow->ImplStop();
407 pSVData->maAppData.mpWheelWindow->doLazyDelete();
408 pSVData->maAppData.mpWheelWindow = nullptr;
412 VclPtr<vcl::Window> Window::SaveFocus()
414 ImplSVData* pSVData = ImplGetSVData();
415 if ( pSVData->maWinData.mpFocusWin )
417 return pSVData->maWinData.mpFocusWin;
419 else
420 return nullptr;
423 void Window::EndSaveFocus(const VclPtr<vcl::Window>& xFocusWin)
425 if (xFocusWin && !xFocusWin->IsDisposed())
427 xFocusWin->GrabFocus();
431 void Window::SetZoom( const Fraction& rZoom )
433 if ( mpWindowImpl && mpWindowImpl->maZoom != rZoom )
435 mpWindowImpl->maZoom = rZoom;
436 CompatStateChanged( StateChangedType::Zoom );
440 inline long WinFloatRound( double fVal )
442 return( fVal > 0.0 ? (long) ( fVal + 0.5 ) : -(long) ( -fVal + 0.5 ) );
445 void Window::SetZoomedPointFont(vcl::RenderContext& rRenderContext, const vcl::Font& rFont)
447 const Fraction& rZoom = GetZoom();
448 if (rZoom.GetNumerator() != rZoom.GetDenominator())
450 vcl::Font aFont(rFont);
451 Size aSize = aFont.GetFontSize();
452 double n = double(aSize.Width());
453 n *= double(rZoom.GetNumerator());
454 n /= double(rZoom.GetDenominator());
455 aSize.Width() = WinFloatRound(n);
456 n = double(aSize.Height());
457 n *= double(rZoom.GetNumerator());
458 n /= double(rZoom.GetDenominator());
459 aSize.Height() = WinFloatRound(n);
460 aFont.SetFontSize(aSize);
461 SetPointFont(rRenderContext, aFont);
463 else
465 SetPointFont(rRenderContext, rFont);
469 long Window::CalcZoom( long nCalc ) const
472 const Fraction& rZoom = GetZoom();
473 if ( rZoom.GetNumerator() != rZoom.GetDenominator() )
475 double n = (double)nCalc;
476 n *= (double)rZoom.GetNumerator();
477 n /= (double)rZoom.GetDenominator();
478 nCalc = WinFloatRound( n );
480 return nCalc;
483 void Window::SetControlFont()
485 if (mpWindowImpl && mpWindowImpl->mpControlFont)
487 delete mpWindowImpl->mpControlFont;
488 mpWindowImpl->mpControlFont = nullptr;
489 CompatStateChanged(StateChangedType::ControlFont);
493 void Window::SetControlFont(const vcl::Font& rFont)
495 if (rFont == vcl::Font())
497 SetControlFont();
498 return;
501 if (mpWindowImpl->mpControlFont)
503 if (*mpWindowImpl->mpControlFont == rFont)
504 return;
505 *mpWindowImpl->mpControlFont = rFont;
507 else
508 mpWindowImpl->mpControlFont = new vcl::Font(rFont);
510 CompatStateChanged(StateChangedType::ControlFont);
513 vcl::Font Window::GetControlFont() const
515 if (mpWindowImpl->mpControlFont)
516 return *mpWindowImpl->mpControlFont;
517 else
519 vcl::Font aFont;
520 return aFont;
524 void Window::ApplyControlFont(vcl::RenderContext& rRenderContext, const vcl::Font& rFont)
526 vcl::Font aFont(rFont);
527 if (IsControlFont())
528 aFont.Merge(GetControlFont());
529 SetZoomedPointFont(rRenderContext, aFont);
532 void Window::SetControlForeground()
534 if (mpWindowImpl->mbControlForeground)
536 mpWindowImpl->maControlForeground = Color(COL_TRANSPARENT);
537 mpWindowImpl->mbControlForeground = false;
538 CompatStateChanged(StateChangedType::ControlForeground);
542 void Window::SetControlForeground(const Color& rColor)
544 if (rColor.GetTransparency())
546 if (mpWindowImpl->mbControlForeground)
548 mpWindowImpl->maControlForeground = Color(COL_TRANSPARENT);
549 mpWindowImpl->mbControlForeground = false;
550 CompatStateChanged(StateChangedType::ControlForeground);
553 else
555 if (mpWindowImpl->maControlForeground != rColor)
557 mpWindowImpl->maControlForeground = rColor;
558 mpWindowImpl->mbControlForeground = true;
559 CompatStateChanged(StateChangedType::ControlForeground);
564 void Window::ApplyControlForeground(vcl::RenderContext& rRenderContext, const Color& rDefaultColor)
566 Color aTextColor(rDefaultColor);
567 if (IsControlForeground())
568 aTextColor = GetControlForeground();
569 rRenderContext.SetTextColor(aTextColor);
572 void Window::SetControlBackground()
574 if (mpWindowImpl->mbControlBackground)
576 mpWindowImpl->maControlBackground = Color(COL_TRANSPARENT);
577 mpWindowImpl->mbControlBackground = false;
578 CompatStateChanged(StateChangedType::ControlBackground);
582 void Window::SetControlBackground(const Color& rColor)
584 if (rColor.GetTransparency())
586 if (mpWindowImpl->mbControlBackground)
588 mpWindowImpl->maControlBackground = Color(COL_TRANSPARENT);
589 mpWindowImpl->mbControlBackground = false;
590 CompatStateChanged(StateChangedType::ControlBackground);
593 else
595 if (mpWindowImpl->maControlBackground != rColor)
597 mpWindowImpl->maControlBackground = rColor;
598 mpWindowImpl->mbControlBackground = true;
599 CompatStateChanged(StateChangedType::ControlBackground);
604 void Window::ApplyControlBackground(vcl::RenderContext& rRenderContext, const Color& rDefaultColor)
606 Color aColor(rDefaultColor);
607 if (IsControlBackground())
608 aColor = GetControlBackground();
609 rRenderContext.SetBackground(aColor);
612 Size Window::CalcWindowSize( const Size& rOutSz ) const
614 Size aSz = rOutSz;
615 aSz.Width() += mpWindowImpl->mnLeftBorder+mpWindowImpl->mnRightBorder;
616 aSz.Height() += mpWindowImpl->mnTopBorder+mpWindowImpl->mnBottomBorder;
617 return aSz;
620 Size Window::CalcOutputSize( const Size& rWinSz ) const
622 Size aSz = rWinSz;
623 aSz.Width() -= mpWindowImpl->mnLeftBorder+mpWindowImpl->mnRightBorder;
624 aSz.Height() -= mpWindowImpl->mnTopBorder+mpWindowImpl->mnBottomBorder;
625 return aSz;
628 vcl::Font Window::GetDrawPixelFont(OutputDevice* pDev) const
630 vcl::Font aFont = GetPointFont(*const_cast<Window*>(this));
631 Size aFontSize = aFont.GetFontSize();
632 MapMode aPtMapMode(MapUnit::MapPoint);
633 aFontSize = pDev->LogicToPixel( aFontSize, aPtMapMode );
634 aFont.SetFontSize( aFontSize );
635 return aFont;
638 long Window::GetDrawPixel( OutputDevice* pDev, long nPixels ) const
640 long nP = nPixels;
641 if ( pDev->GetOutDevType() != OUTDEV_WINDOW )
643 MapMode aMap( MapUnit::Map100thMM );
644 Size aSz( nP, 0 );
645 aSz = PixelToLogic( aSz, aMap );
646 aSz = pDev->LogicToPixel( aSz, aMap );
647 nP = aSz.Width();
649 return nP;
652 static void lcl_HandleScrollHelper( ScrollBar* pScrl, double nN, bool isMultiplyByLineSize )
654 if ( pScrl && nN && pScrl->IsEnabled() && pScrl->IsInputEnabled() && ! pScrl->IsInModalMode() )
656 long nNewPos = pScrl->GetThumbPos();
658 if ( nN == -LONG_MAX )
659 nNewPos += pScrl->GetPageSize();
660 else if ( nN == LONG_MAX )
661 nNewPos -= pScrl->GetPageSize();
662 else
664 // allowing both chunked and continuous scrolling
665 if(isMultiplyByLineSize){
666 nN*=pScrl->GetLineSize();
669 const double fVal = nNewPos - nN;
671 if ( fVal < LONG_MIN )
672 nNewPos = LONG_MIN;
673 else if ( fVal > LONG_MAX )
674 nNewPos = LONG_MAX;
675 else
676 nNewPos = (long)fVal;
679 pScrl->DoScroll( nNewPos );
684 bool Window::HandleScrollCommand( const CommandEvent& rCmd,
685 ScrollBar* pHScrl, ScrollBar* pVScrl )
687 bool bRet = false;
689 if ( pHScrl || pVScrl )
691 switch( rCmd.GetCommand() )
693 case CommandEventId::StartAutoScroll:
695 StartAutoScrollFlags nFlags = StartAutoScrollFlags::NONE;
696 if ( pHScrl )
698 if ( (pHScrl->GetVisibleSize() < pHScrl->GetRangeMax()) &&
699 pHScrl->IsEnabled() && pHScrl->IsInputEnabled() && ! pHScrl->IsInModalMode() )
700 nFlags |= StartAutoScrollFlags::Horz;
702 if ( pVScrl )
704 if ( (pVScrl->GetVisibleSize() < pVScrl->GetRangeMax()) &&
705 pVScrl->IsEnabled() && pVScrl->IsInputEnabled() && ! pVScrl->IsInModalMode() )
706 nFlags |= StartAutoScrollFlags::Vert;
709 if ( nFlags != StartAutoScrollFlags::NONE )
711 StartAutoScroll( nFlags );
712 bRet = true;
715 break;
717 case CommandEventId::Wheel:
719 const CommandWheelData* pData = rCmd.GetWheelData();
721 if ( pData && (CommandWheelMode::SCROLL == pData->GetMode()) )
723 if (!pData->IsDeltaPixel())
725 double nScrollLines = pData->GetScrollLines();
726 double nLines;
727 if ( nScrollLines == COMMAND_WHEEL_PAGESCROLL )
729 if ( pData->GetDelta() < 0 )
730 nLines = -LONG_MAX;
731 else
732 nLines = LONG_MAX;
734 else
735 nLines = pData->GetNotchDelta() * nScrollLines;
736 if ( nLines )
738 ImplHandleScroll( nullptr,
740 pData->IsHorz() ? pHScrl : pVScrl,
741 nLines );
742 bRet = true;
745 else
747 // Mobile / touch scrolling section
748 const Point & deltaPoint = rCmd.GetMousePosPixel();
750 double deltaXInPixels = double(deltaPoint.X());
751 double deltaYInPixels = double(deltaPoint.Y());
752 Size winSize = this->GetOutputSizePixel();
754 if(pHScrl)
756 double visSizeX = double(pHScrl->GetVisibleSize());
757 double ratioX = deltaXInPixels / double(winSize.getWidth());
758 long deltaXInLogic = long(visSizeX * ratioX);
759 // Touch need to work by pixels. Did not apply this to
760 // Android, as android code may require adaptations
761 // to work with this scrolling code
762 #ifndef IOS
763 long lineSizeX = pHScrl->GetLineSize();
765 if(lineSizeX)
767 deltaXInLogic /= lineSizeX;
769 else
771 deltaXInLogic = 0;
773 #endif
774 if ( deltaXInLogic)
776 #ifndef IOS
777 bool isMultiplyByLineSize = true;
778 #else
779 bool isMultiplyByLineSize = false;
780 #endif
781 lcl_HandleScrollHelper( pHScrl, deltaXInLogic, isMultiplyByLineSize );
782 bRet = true;
785 if(pVScrl)
787 double visSizeY = double(pVScrl->GetVisibleSize());
788 double ratioY = deltaYInPixels / double(winSize.getHeight());
789 long deltaYInLogic = long(visSizeY * ratioY);
791 // Touch need to work by pixels. Did not apply this to
792 // Android, as android code may require adaptations
793 // to work with this scrolling code
794 #ifndef IOS
795 long lineSizeY = pVScrl->GetLineSize();
796 if(lineSizeY)
798 deltaYInLogic /= lineSizeY;
800 else
802 deltaYInLogic = 0;
804 #endif
805 if ( deltaYInLogic )
807 #ifndef IOS
808 bool isMultiplyByLineSize = true;
809 #else
810 bool isMultiplyByLineSize = false;
811 #endif
812 lcl_HandleScrollHelper( pVScrl, deltaYInLogic, isMultiplyByLineSize );
814 bRet = true;
820 break;
822 case CommandEventId::AutoScroll:
824 const CommandScrollData* pData = rCmd.GetAutoScrollData();
825 if ( pData && (pData->GetDeltaX() || pData->GetDeltaY()) )
827 ImplHandleScroll( pHScrl, pData->GetDeltaX(),
828 pVScrl, pData->GetDeltaY() );
829 bRet = true;
832 break;
834 default:
835 break;
839 return bRet;
842 // Note that when called for CommandEventId::Wheel above, despite its name,
843 // pVScrl isn't necessarily the vertical scroll bar. Depending on
844 // whether the scroll is horizontal or vertical, it is either the
845 // horizontal or vertical scroll bar. nY is correspondingly either
846 // the horizontal or vertical scroll amount.
848 void Window::ImplHandleScroll( ScrollBar* pHScrl, double nX,
849 ScrollBar* pVScrl, double nY )
851 lcl_HandleScrollHelper( pHScrl, nX, true );
852 lcl_HandleScrollHelper( pVScrl, nY, true );
855 DockingManager* Window::GetDockingManager()
857 return ImplGetDockingManager();
860 void Window::EnableDocking( bool bEnable )
862 // update list of dockable windows
863 if( bEnable )
864 ImplGetDockingManager()->AddWindow( this );
865 else
866 ImplGetDockingManager()->RemoveWindow( this );
869 // retrieves the list of owner draw decorated windows for this window hiearchy
870 ::std::vector<VclPtr<vcl::Window> >& Window::ImplGetOwnerDrawList()
872 return ImplGetTopmostFrameWindow()->mpWindowImpl->mpFrameData->maOwnerDrawList;
875 void Window::SetHelpId( const OString& rHelpId )
877 mpWindowImpl->maHelpId = rHelpId;
880 const OString& Window::GetHelpId() const
882 return mpWindowImpl->maHelpId;
885 OString Window::GetScreenshotId() const
887 return GetHelpId();
890 // --------- old inline methods ---------------
892 vcl::Window* Window::ImplGetWindow()
894 if ( mpWindowImpl->mpClientWindow )
895 return mpWindowImpl->mpClientWindow;
896 else
897 return this;
900 ImplFrameData* Window::ImplGetFrameData()
902 return mpWindowImpl ? mpWindowImpl->mpFrameData : nullptr;
905 SalFrame* Window::ImplGetFrame() const
907 return mpWindowImpl ? mpWindowImpl->mpFrame : nullptr;
910 vcl::Window* Window::ImplGetParent() const
912 return mpWindowImpl ? mpWindowImpl->mpParent.get() : nullptr;
915 vcl::Window* Window::ImplGetClientWindow() const
917 return mpWindowImpl ? mpWindowImpl->mpClientWindow.get() : nullptr;
920 vcl::Window* Window::ImplGetBorderWindow() const
922 return mpWindowImpl ? mpWindowImpl->mpBorderWindow.get() : nullptr;
925 vcl::Window* Window::ImplGetFirstOverlapWindow()
927 if ( mpWindowImpl->mbOverlapWin )
928 return this;
929 else
930 return mpWindowImpl->mpOverlapWindow;
933 const vcl::Window* Window::ImplGetFirstOverlapWindow() const
935 if ( mpWindowImpl->mbOverlapWin )
936 return this;
937 else
938 return mpWindowImpl->mpOverlapWindow;
941 vcl::Window* Window::ImplGetFrameWindow() const
943 return mpWindowImpl ? mpWindowImpl->mpFrameWindow.get() : nullptr;
946 bool Window::IsDockingWindow() const
948 return mpWindowImpl && mpWindowImpl->mbDockWin;
951 bool Window::ImplIsFloatingWindow() const
953 return mpWindowImpl && mpWindowImpl->mbFloatWin;
956 bool Window::ImplIsSplitter() const
958 return mpWindowImpl && mpWindowImpl->mbSplitter;
961 bool Window::ImplIsPushButton() const
963 return mpWindowImpl && mpWindowImpl->mbPushButton;
966 bool Window::ImplIsOverlapWindow() const
968 return mpWindowImpl && mpWindowImpl->mbOverlapWin;
971 void Window::ImplSetMouseTransparent( bool bTransparent )
973 if (mpWindowImpl)
974 mpWindowImpl->mbMouseTransparent = bTransparent;
977 Point Window::ImplOutputToFrame( const Point& rPos )
979 return Point( rPos.X()+mnOutOffX, rPos.Y()+mnOutOffY );
982 Point Window::ImplFrameToOutput( const Point& rPos )
984 return Point( rPos.X()-mnOutOffX, rPos.Y()-mnOutOffY );
987 void Window::SetCompoundControl( bool bCompound )
989 if (mpWindowImpl)
990 mpWindowImpl->mbCompoundControl = bCompound;
993 void Window::IncrementLockCount()
995 assert( mpWindowImpl != nullptr );
996 mpWindowImpl->mnLockCount++;
999 void Window::DecrementLockCount()
1001 assert( mpWindowImpl != nullptr );
1002 if (mpWindowImpl)
1003 mpWindowImpl->mnLockCount--;
1006 WinBits Window::GetStyle() const
1008 return mpWindowImpl ? mpWindowImpl->mnStyle : 0;
1011 WinBits Window::GetPrevStyle() const
1013 return mpWindowImpl ? mpWindowImpl->mnPrevStyle : 0;
1016 WinBits Window::GetExtendedStyle() const
1018 return mpWindowImpl ? mpWindowImpl->mnExtendedStyle : 0;
1021 void Window::SetType( WindowType nType )
1023 if (mpWindowImpl)
1024 mpWindowImpl->mnType = nType;
1027 WindowType Window::GetType() const
1029 if (mpWindowImpl)
1030 return mpWindowImpl->mnType;
1031 else
1032 return 0;
1035 Dialog* Window::GetParentDialog() const
1037 const vcl::Window *pWindow = this;
1039 while( pWindow )
1041 if( pWindow->IsDialog() )
1042 break;
1044 pWindow = pWindow->GetParent();
1047 return const_cast<Dialog *>(dynamic_cast<const Dialog*>(pWindow));
1050 bool Window::IsSystemWindow() const
1052 return mpWindowImpl && mpWindowImpl->mbSysWin;
1055 bool Window::IsDialog() const
1057 return mpWindowImpl && mpWindowImpl->mbDialog;
1060 bool Window::IsMenuFloatingWindow() const
1062 return mpWindowImpl && mpWindowImpl->mbMenuFloatingWindow;
1065 bool Window::IsToolbarFloatingWindow() const
1067 return mpWindowImpl && mpWindowImpl->mbToolbarFloatingWindow;
1070 void Window::EnableAllResize()
1072 mpWindowImpl->mbAllResize = true;
1075 void Window::EnableChildTransparentMode( bool bEnable )
1077 mpWindowImpl->mbChildTransparent = bEnable;
1080 bool Window::IsChildTransparentModeEnabled() const
1082 return mpWindowImpl && mpWindowImpl->mbChildTransparent;
1085 bool Window::IsMouseTransparent() const
1087 return mpWindowImpl && mpWindowImpl->mbMouseTransparent;
1090 bool Window::IsPaintTransparent() const
1092 return mpWindowImpl && mpWindowImpl->mbPaintTransparent;
1095 void Window::SetDialogControlStart( bool bStart )
1097 mpWindowImpl->mbDlgCtrlStart = bStart;
1100 bool Window::IsDialogControlStart() const
1102 return mpWindowImpl && mpWindowImpl->mbDlgCtrlStart;
1105 void Window::SetDialogControlFlags( DialogControlFlags nFlags )
1107 mpWindowImpl->mnDlgCtrlFlags = nFlags;
1110 DialogControlFlags Window::GetDialogControlFlags() const
1112 return mpWindowImpl->mnDlgCtrlFlags;
1115 const InputContext& Window::GetInputContext() const
1117 return mpWindowImpl->maInputContext;
1120 bool Window::IsControlFont() const
1122 return (mpWindowImpl->mpControlFont != nullptr);
1125 const Color& Window::GetControlForeground() const
1127 return mpWindowImpl->maControlForeground;
1130 bool Window::IsControlForeground() const
1132 return mpWindowImpl->mbControlForeground;
1135 const Color& Window::GetControlBackground() const
1137 return mpWindowImpl->maControlBackground;
1140 bool Window::IsControlBackground() const
1142 return mpWindowImpl->mbControlBackground;
1145 bool Window::IsInPaint() const
1147 return mpWindowImpl && mpWindowImpl->mbInPaint;
1150 vcl::Window* Window::GetParent() const
1152 return mpWindowImpl ? mpWindowImpl->mpRealParent.get() : nullptr;
1155 bool Window::IsVisible() const
1157 return mpWindowImpl && mpWindowImpl->mbVisible;
1160 bool Window::IsReallyVisible() const
1162 return mpWindowImpl && mpWindowImpl->mbReallyVisible;
1165 bool Window::IsReallyShown() const
1167 return mpWindowImpl && mpWindowImpl->mbReallyShown;
1170 bool Window::IsInInitShow() const
1172 return mpWindowImpl->mbInInitShow;
1175 bool Window::IsEnabled() const
1177 return mpWindowImpl && !mpWindowImpl->mbDisabled;
1180 bool Window::IsInputEnabled() const
1182 return mpWindowImpl && !mpWindowImpl->mbInputDisabled;
1185 bool Window::IsAlwaysEnableInput() const
1187 return mpWindowImpl->meAlwaysInputMode == AlwaysInputEnabled;
1190 ActivateModeFlags Window::GetActivateMode() const
1192 return mpWindowImpl->mnActivateMode;
1196 bool Window::IsAlwaysOnTopEnabled() const
1198 return mpWindowImpl->mbAlwaysOnTop;
1201 bool Window::IsDefaultPos() const
1203 return mpWindowImpl->mbDefPos;
1206 bool Window::IsDefaultSize() const
1208 return mpWindowImpl->mbDefSize;
1211 Point Window::GetOffsetPixelFrom(const vcl::Window& rWindow) const
1213 return Point(GetOutOffXPixel() - rWindow.GetOutOffXPixel(), GetOutOffYPixel() - rWindow.GetOutOffYPixel());
1216 void Window::EnablePaint( bool bEnable )
1218 mpWindowImpl->mbPaintDisabled = !bEnable;
1221 bool Window::IsPaintEnabled() const
1223 return !mpWindowImpl->mbPaintDisabled;
1226 bool Window::IsUpdateMode() const
1228 return !mpWindowImpl->mbNoUpdate;
1231 void Window::SetParentUpdateMode( bool bUpdate )
1233 mpWindowImpl->mbNoParentUpdate = !bUpdate;
1236 bool Window::IsActive() const
1238 return mpWindowImpl->mbActive;
1241 GetFocusFlags Window::GetGetFocusFlags() const
1243 return mpWindowImpl->mnGetFocusFlags;
1246 bool Window::IsCompoundControl() const
1248 return mpWindowImpl->mbCompoundControl;
1251 bool Window::IsWait() const
1253 return (mpWindowImpl->mnWaitCount != 0);
1256 vcl::Cursor* Window::GetCursor() const
1258 if (!mpWindowImpl)
1259 return nullptr;
1260 return mpWindowImpl->mpCursor;
1263 const Fraction& Window::GetZoom() const
1265 return mpWindowImpl->maZoom;
1268 bool Window::IsZoom() const
1270 return mpWindowImpl->maZoom.GetNumerator() != mpWindowImpl->maZoom.GetDenominator();
1273 void Window::SetHelpText( const OUString& rHelpText )
1275 mpWindowImpl->maHelpText = rHelpText;
1276 mpWindowImpl->mbHelpTextDynamic = true;
1279 void Window::SetQuickHelpText( const OUString& rHelpText )
1281 if (mpWindowImpl)
1282 mpWindowImpl->maQuickHelpText = rHelpText;
1285 const OUString& Window::GetQuickHelpText() const
1287 return mpWindowImpl->maQuickHelpText;
1290 bool Window::IsCreatedWithToolkit() const
1292 return mpWindowImpl->mbCreatedWithToolkit;
1295 void Window::SetCreatedWithToolkit( bool b )
1297 mpWindowImpl->mbCreatedWithToolkit = b;
1300 const Pointer& Window::GetPointer() const
1302 return mpWindowImpl->maPointer;
1305 VCLXWindow* Window::GetWindowPeer() const
1307 return mpWindowImpl ? mpWindowImpl->mpVCLXWindow : nullptr;
1310 void Window::SetPosPixel( const Point& rNewPos )
1312 setPosSizePixel( rNewPos.X(), rNewPos.Y(), 0, 0, PosSizeFlags::Pos );
1315 void Window::SetSizePixel( const Size& rNewSize )
1317 setPosSizePixel( 0, 0, rNewSize.Width(), rNewSize.Height(),
1318 PosSizeFlags::Size );
1321 void Window::SetPosSizePixel( const Point& rNewPos, const Size& rNewSize )
1323 setPosSizePixel( rNewPos.X(), rNewPos.Y(),
1324 rNewSize.Width(), rNewSize.Height());
1327 void Window::SetOutputSizePixel( const Size& rNewSize )
1329 SetSizePixel( Size( rNewSize.Width()+mpWindowImpl->mnLeftBorder+mpWindowImpl->mnRightBorder,
1330 rNewSize.Height()+mpWindowImpl->mnTopBorder+mpWindowImpl->mnBottomBorder ) );
1333 //When a widget wants to renegotiate layout, get toplevel parent dialog and call
1334 //resize on it. Mark all intermediate containers (or container-alike) widgets
1335 //as dirty for the size remains unchanged, but layout changed circumstances
1336 namespace
1338 bool queue_ungrouped_resize(vcl::Window *pOrigWindow)
1340 bool bSomeoneCares = false;
1342 vcl::Window *pWindow = pOrigWindow->GetParent();
1343 if (pWindow)
1345 if (isContainerWindow(*pWindow))
1347 bSomeoneCares = true;
1349 else if (pWindow->GetType() == WINDOW_TABCONTROL)
1351 bSomeoneCares = true;
1353 pWindow->queue_resize();
1356 return bSomeoneCares;
1360 void Window::InvalidateSizeCache()
1362 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1363 pWindowImpl->mnOptimalWidthCache = -1;
1364 pWindowImpl->mnOptimalHeightCache = -1;
1367 void Window::queue_resize(StateChangedType eReason)
1369 if (IsDisposed())
1370 return;
1372 bool bSomeoneCares = queue_ungrouped_resize(this);
1374 if (eReason != StateChangedType::Visible)
1376 InvalidateSizeCache();
1379 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1380 if (pWindowImpl->m_xSizeGroup && pWindowImpl->m_xSizeGroup->get_mode() != VCL_SIZE_GROUP_NONE)
1382 std::set<VclPtr<vcl::Window> > &rWindows = pWindowImpl->m_xSizeGroup->get_widgets();
1383 for (VclPtr<vcl::Window> const & pOther : rWindows)
1385 if (pOther == this)
1386 continue;
1387 queue_ungrouped_resize(pOther);
1391 if (bSomeoneCares && !mpWindowImpl->mbInDispose)
1393 //fdo#57090 force a resync of the borders of the borderwindow onto this
1394 //window in case they have changed
1395 vcl::Window* pBorderWindow = ImplGetBorderWindow();
1396 if (pBorderWindow)
1397 pBorderWindow->Resize();
1400 if (VclPtr<vcl::Window> pParent = GetParentWithLOKNotifier())
1402 if (!pParent->IsInInitShow())
1403 LogicInvalidate(nullptr);
1407 namespace
1409 VclAlign toAlign(const OString &rValue)
1411 VclAlign eRet = VclAlign::Fill;
1413 if (rValue == "fill")
1414 eRet = VclAlign::Fill;
1415 else if (rValue == "start")
1416 eRet = VclAlign::Start;
1417 else if (rValue == "end")
1418 eRet = VclAlign::End;
1419 else if (rValue == "center")
1420 eRet = VclAlign::Center;
1421 return eRet;
1425 bool Window::set_font_attribute(const OString &rKey, const OString &rValue)
1427 if (rKey == "weight")
1429 vcl::Font aFont(GetControlFont());
1430 if (rValue == "thin")
1431 aFont.SetWeight(WEIGHT_THIN);
1432 else if (rValue == "ultralight")
1433 aFont.SetWeight(WEIGHT_ULTRALIGHT);
1434 else if (rValue == "light")
1435 aFont.SetWeight(WEIGHT_LIGHT);
1436 else if (rValue == "book")
1437 aFont.SetWeight(WEIGHT_SEMILIGHT);
1438 else if (rValue == "normal")
1439 aFont.SetWeight(WEIGHT_NORMAL);
1440 else if (rValue == "medium")
1441 aFont.SetWeight(WEIGHT_MEDIUM);
1442 else if (rValue == "semibold")
1443 aFont.SetWeight(WEIGHT_SEMIBOLD);
1444 else if (rValue == "bold")
1445 aFont.SetWeight(WEIGHT_BOLD);
1446 else if (rValue == "ultrabold")
1447 aFont.SetWeight(WEIGHT_ULTRABOLD);
1448 else
1449 aFont.SetWeight(WEIGHT_BLACK);
1450 SetControlFont(aFont);
1452 else if (rKey == "style")
1454 vcl::Font aFont(GetControlFont());
1455 if (rValue == "normal")
1456 aFont.SetItalic(ITALIC_NONE);
1457 else if (rValue == "oblique")
1458 aFont.SetItalic(ITALIC_OBLIQUE);
1459 else if (rValue == "italic")
1460 aFont.SetItalic(ITALIC_NORMAL);
1461 SetControlFont(aFont);
1463 else if (rKey == "underline")
1465 vcl::Font aFont(GetControlFont());
1466 aFont.SetUnderline(toBool(rValue) ? LINESTYLE_SINGLE : LINESTYLE_NONE);
1467 SetControlFont(aFont);
1469 else if (rKey == "size")
1471 vcl::Font aFont(GetControlFont());
1472 sal_Int32 nHeight = rValue.toInt32() / 1000;
1473 aFont.SetFontHeight(nHeight);
1474 SetControlFont(aFont);
1476 else
1478 SAL_INFO("vcl.layout", "unhandled font attribute: " << rKey.getStr());
1479 return false;
1481 return true;
1484 bool Window::set_property(const OString &rKey, const OString &rValue)
1486 if ((rKey == "label") || (rKey == "title") || (rKey == "text") )
1488 SetText(OStringToOUString(VclBuilder::convertMnemonicMarkup(rValue), RTL_TEXTENCODING_UTF8));
1490 else if (rKey == "visible")
1491 Show(toBool(rValue));
1492 else if (rKey == "sensitive")
1493 Enable(toBool(rValue));
1494 else if (rKey == "resizable")
1496 WinBits nBits = GetStyle();
1497 nBits &= ~(WB_SIZEABLE);
1498 if (toBool(rValue))
1499 nBits |= WB_SIZEABLE;
1500 SetStyle(nBits);
1502 else if (rKey == "xalign")
1504 WinBits nBits = GetStyle();
1505 nBits &= ~(WB_LEFT | WB_CENTER | WB_RIGHT);
1507 float f = rValue.toFloat();
1508 if (f == 0.0)
1509 nBits |= WB_LEFT;
1510 else if (f == 1.0)
1511 nBits |= WB_RIGHT;
1512 else if (f == 0.5)
1513 nBits |= WB_CENTER;
1515 SetStyle(nBits);
1517 else if (rKey == "justification")
1519 WinBits nBits = GetStyle();
1520 nBits &= ~(WB_LEFT | WB_CENTER | WB_RIGHT);
1522 if (rValue == "left")
1523 nBits |= WB_LEFT;
1524 else if (rValue == "right")
1525 nBits |= WB_RIGHT;
1526 else if (rValue == "center")
1527 nBits |= WB_CENTER;
1529 SetStyle(nBits);
1531 else if (rKey == "yalign")
1533 WinBits nBits = GetStyle();
1534 nBits &= ~(WB_TOP | WB_VCENTER | WB_BOTTOM);
1536 float f = rValue.toFloat();
1537 if (f == 0.0)
1538 nBits |= WB_TOP;
1539 else if (f == 1.0)
1540 nBits |= WB_BOTTOM;
1541 else if (f == 0.5)
1542 nBits |= WB_CENTER;
1544 SetStyle(nBits);
1546 else if (rKey == "wrap")
1548 WinBits nBits = GetStyle();
1549 nBits &= ~(WB_WORDBREAK);
1550 if (toBool(rValue))
1551 nBits |= WB_WORDBREAK;
1552 SetStyle(nBits);
1554 else if (rKey == "height-request")
1555 set_height_request(rValue.toInt32());
1556 else if (rKey == "width-request")
1557 set_width_request(rValue.toInt32());
1558 else if (rKey == "hexpand")
1559 set_hexpand(toBool(rValue));
1560 else if (rKey == "vexpand")
1561 set_vexpand(toBool(rValue));
1562 else if (rKey == "halign")
1563 set_halign(toAlign(rValue));
1564 else if (rKey == "valign")
1565 set_valign(toAlign(rValue));
1566 else if (rKey == "tooltip-markup")
1567 SetQuickHelpText(OStringToOUString(rValue, RTL_TEXTENCODING_UTF8));
1568 else if (rKey == "tooltip-text")
1569 SetQuickHelpText(OStringToOUString(rValue, RTL_TEXTENCODING_UTF8));
1570 else if (rKey == "border-width")
1571 set_border_width(rValue.toInt32());
1572 else if (rKey == "margin-left")
1573 set_margin_left(rValue.toInt32());
1574 else if (rKey == "margin-right")
1575 set_margin_right(rValue.toInt32());
1576 else if (rKey == "margin-top")
1577 set_margin_top(rValue.toInt32());
1578 else if (rKey == "margin-bottom")
1579 set_margin_bottom(rValue.toInt32());
1580 else if (rKey == "hscrollbar-policy")
1582 WinBits nBits = GetStyle();
1583 nBits &= ~(WB_AUTOHSCROLL|WB_HSCROLL);
1584 if (rValue == "always")
1585 nBits |= WB_HSCROLL;
1586 else if (rValue == "automatic")
1587 nBits |= WB_AUTOHSCROLL;
1588 SetStyle(nBits);
1590 else if (rKey == "vscrollbar-policy")
1592 WinBits nBits = GetStyle();
1593 nBits &= ~(WB_AUTOVSCROLL|WB_VSCROLL);
1594 if (rValue == "always")
1595 nBits |= WB_VSCROLL;
1596 else if (rValue == "automatic")
1597 nBits |= WB_AUTOVSCROLL;
1598 SetStyle(nBits);
1600 else if (rKey == "accessible-name")
1602 SetAccessibleName(OStringToOUString(rValue, RTL_TEXTENCODING_UTF8));
1604 else if (rKey == "accessible-description")
1606 SetAccessibleDescription(OStringToOUString(rValue, RTL_TEXTENCODING_UTF8));
1608 else if (rKey == "use-markup")
1610 //https://live.gnome.org/GnomeGoals/RemoveMarkupInMessages
1611 SAL_WARN_IF(toBool(rValue), "vcl.layout", "Use pango attributes instead of mark-up");
1613 else if (rKey == "has-focus")
1615 if (toBool(rValue))
1616 GrabFocus();
1618 else
1620 SAL_INFO("vcl.layout", "unhandled property: " << rKey.getStr());
1621 return false;
1623 return true;
1626 void Window::set_height_request(sal_Int32 nHeightRequest)
1628 if (!mpWindowImpl)
1629 return;
1631 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1633 if ( pWindowImpl->mnHeightRequest != nHeightRequest )
1635 pWindowImpl->mnHeightRequest = nHeightRequest;
1636 queue_resize();
1640 void Window::set_width_request(sal_Int32 nWidthRequest)
1642 if (!mpWindowImpl)
1643 return;
1645 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1647 if ( pWindowImpl->mnWidthRequest != nWidthRequest )
1649 pWindowImpl->mnWidthRequest = nWidthRequest;
1650 queue_resize();
1654 Size Window::get_ungrouped_preferred_size() const
1656 Size aRet(get_width_request(), get_height_request());
1657 if (aRet.Width() == -1 || aRet.Height() == -1)
1659 //cache gets blown away by queue_resize
1660 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1661 if (pWindowImpl->mnOptimalWidthCache == -1 || pWindowImpl->mnOptimalHeightCache == -1)
1663 Size aOptimal(GetOptimalSize());
1664 pWindowImpl->mnOptimalWidthCache = aOptimal.Width();
1665 pWindowImpl->mnOptimalHeightCache = aOptimal.Height();
1668 if (aRet.Width() == -1)
1669 aRet.Width() = pWindowImpl->mnOptimalWidthCache;
1670 if (aRet.Height() == -1)
1671 aRet.Height() = pWindowImpl->mnOptimalHeightCache;
1673 return aRet;
1676 Size Window::get_preferred_size() const
1678 Size aRet(get_ungrouped_preferred_size());
1680 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1681 if (pWindowImpl->m_xSizeGroup)
1683 const VclSizeGroupMode eMode = pWindowImpl->m_xSizeGroup->get_mode();
1684 if (eMode != VCL_SIZE_GROUP_NONE)
1686 const bool bIgnoreInHidden = pWindowImpl->m_xSizeGroup->get_ignore_hidden();
1687 const std::set<VclPtr<vcl::Window> > &rWindows = pWindowImpl->m_xSizeGroup->get_widgets();
1688 for (auto aI = rWindows.begin(), aEnd = rWindows.end(); aI != aEnd; ++aI)
1690 const vcl::Window *pOther = *aI;
1691 if (pOther == this)
1692 continue;
1693 if (bIgnoreInHidden && !pOther->IsVisible())
1694 continue;
1695 Size aOtherSize = pOther->get_ungrouped_preferred_size();
1696 if (eMode == VCL_SIZE_GROUP_BOTH || eMode == VCL_SIZE_GROUP_HORIZONTAL)
1697 aRet.Width() = std::max(aRet.Width(), aOtherSize.Width());
1698 if (eMode == VCL_SIZE_GROUP_BOTH || eMode == VCL_SIZE_GROUP_VERTICAL)
1699 aRet.Height() = std::max(aRet.Height(), aOtherSize.Height());
1704 return aRet;
1707 VclAlign Window::get_halign() const
1709 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1710 return pWindowImpl->meHalign;
1713 void Window::set_halign(VclAlign eAlign)
1715 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1716 pWindowImpl->meHalign = eAlign;
1719 VclAlign Window::get_valign() const
1721 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1722 return pWindowImpl->meValign;
1725 void Window::set_valign(VclAlign eAlign)
1727 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1728 pWindowImpl->meValign = eAlign;
1731 bool Window::get_hexpand() const
1733 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1734 return pWindowImpl->mbHexpand;
1737 void Window::set_hexpand(bool bExpand)
1739 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1740 pWindowImpl->mbHexpand = bExpand;
1743 bool Window::get_vexpand() const
1745 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1746 return pWindowImpl->mbVexpand;
1749 void Window::set_vexpand(bool bExpand)
1751 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1752 pWindowImpl->mbVexpand = bExpand;
1755 bool Window::get_expand() const
1757 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1758 return pWindowImpl->mbExpand;
1761 void Window::set_expand(bool bExpand)
1763 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1764 pWindowImpl->mbExpand = bExpand;
1767 VclPackType Window::get_pack_type() const
1769 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1770 return pWindowImpl->mePackType;
1773 void Window::set_pack_type(VclPackType ePackType)
1775 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1776 pWindowImpl->mePackType = ePackType;
1779 sal_Int32 Window::get_padding() const
1781 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1782 return pWindowImpl->mnPadding;
1785 void Window::set_padding(sal_Int32 nPadding)
1787 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1788 pWindowImpl->mnPadding = nPadding;
1791 bool Window::get_fill() const
1793 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1794 return pWindowImpl->mbFill;
1797 void Window::set_fill(bool bFill)
1799 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1800 pWindowImpl->mbFill = bFill;
1803 sal_Int32 Window::get_grid_width() const
1805 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1806 return pWindowImpl->mnGridWidth;
1809 void Window::set_grid_width(sal_Int32 nCols)
1811 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1812 pWindowImpl->mnGridWidth = nCols;
1815 sal_Int32 Window::get_grid_left_attach() const
1817 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1818 return pWindowImpl->mnGridLeftAttach;
1821 void Window::set_grid_left_attach(sal_Int32 nAttach)
1823 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1824 pWindowImpl->mnGridLeftAttach = nAttach;
1827 sal_Int32 Window::get_grid_height() const
1829 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1830 return pWindowImpl->mnGridHeight;
1833 void Window::set_grid_height(sal_Int32 nRows)
1835 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1836 pWindowImpl->mnGridHeight = nRows;
1839 sal_Int32 Window::get_grid_top_attach() const
1841 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1842 return pWindowImpl->mnGridTopAttach;
1845 void Window::set_grid_top_attach(sal_Int32 nAttach)
1847 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1848 pWindowImpl->mnGridTopAttach = nAttach;
1851 void Window::set_border_width(sal_Int32 nBorderWidth)
1853 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1854 pWindowImpl->mnBorderWidth = nBorderWidth;
1857 sal_Int32 Window::get_border_width() const
1859 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1860 return pWindowImpl->mnBorderWidth;
1863 void Window::set_margin_left(sal_Int32 nWidth)
1865 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1866 pWindowImpl->mnMarginLeft = nWidth;
1869 sal_Int32 Window::get_margin_left() const
1871 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1872 return pWindowImpl->mnMarginLeft;
1875 void Window::set_margin_right(sal_Int32 nWidth)
1877 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1878 pWindowImpl->mnMarginRight = nWidth;
1881 sal_Int32 Window::get_margin_right() const
1883 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1884 return pWindowImpl->mnMarginRight;
1887 void Window::set_margin_top(sal_Int32 nWidth)
1889 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1890 pWindowImpl->mnMarginTop = nWidth;
1893 sal_Int32 Window::get_margin_top() const
1895 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1896 return pWindowImpl->mnMarginTop;
1899 void Window::set_margin_bottom(sal_Int32 nWidth)
1901 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1902 pWindowImpl->mnMarginBottom = nWidth;
1905 sal_Int32 Window::get_margin_bottom() const
1907 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1908 return pWindowImpl->mnMarginBottom;
1911 sal_Int32 Window::get_height_request() const
1913 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1914 return pWindowImpl->mnHeightRequest;
1917 sal_Int32 Window::get_width_request() const
1919 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1920 return pWindowImpl->mnWidthRequest;
1923 bool Window::get_secondary() const
1925 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1926 return pWindowImpl->mbSecondary;
1929 void Window::set_secondary(bool bSecondary)
1931 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1932 pWindowImpl->mbSecondary = bSecondary;
1935 bool Window::get_non_homogeneous() const
1937 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1938 return pWindowImpl->mbNonHomogeneous;
1941 void Window::set_non_homogeneous(bool bNonHomogeneous)
1943 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1944 pWindowImpl->mbNonHomogeneous = bNonHomogeneous;
1947 void Window::add_to_size_group(const std::shared_ptr<VclSizeGroup>& xGroup)
1949 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1950 //To-Do, multiple groups
1951 pWindowImpl->m_xSizeGroup = xGroup;
1952 pWindowImpl->m_xSizeGroup->insert(this);
1953 if (VCL_SIZE_GROUP_NONE != pWindowImpl->m_xSizeGroup->get_mode())
1954 queue_resize();
1957 void Window::remove_from_all_size_groups()
1959 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1960 //To-Do, multiple groups
1961 if (pWindowImpl->m_xSizeGroup)
1963 if (VCL_SIZE_GROUP_NONE != pWindowImpl->m_xSizeGroup->get_mode())
1964 queue_resize();
1965 pWindowImpl->m_xSizeGroup->erase(this);
1966 pWindowImpl->m_xSizeGroup.reset();
1970 void Window::add_mnemonic_label(FixedText *pLabel)
1972 std::vector<VclPtr<FixedText> >& v = mpWindowImpl->m_aMnemonicLabels;
1973 if (std::find(v.begin(), v.end(), VclPtr<FixedText>(pLabel)) != v.end())
1974 return;
1975 v.push_back(pLabel);
1976 pLabel->set_mnemonic_widget(this);
1979 void Window::remove_mnemonic_label(FixedText *pLabel)
1981 std::vector<VclPtr<FixedText> >& v = mpWindowImpl->m_aMnemonicLabels;
1982 auto aFind = std::find(v.begin(), v.end(), VclPtr<FixedText>(pLabel));
1983 if (aFind == v.end())
1984 return;
1985 v.erase(aFind);
1986 pLabel->set_mnemonic_widget(nullptr);
1989 const std::vector<VclPtr<FixedText> >& Window::list_mnemonic_labels() const
1991 return mpWindowImpl->m_aMnemonicLabels;
1994 } /* namespace vcl */
1997 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */