1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20 #include <limits.h>
21
22 #include <o3tl/float_int_conversion.hxx>
23 #include <sal/log.hxx>
24
25 #include <vcl/dialog.hxx>
26 #include <vcl/event.hxx>
27 #include <vcl/fixed.hxx>
28 #include <vcl/layout.hxx>
29 #include <vcl/timer.hxx>
30 #include <vcl/window.hxx>
31 #include <vcl/scrbar.hxx>
32 #include <vcl/dockwin.hxx>
33 #include <vcl/settings.hxx>
34 #include <vcl/builder.hxx>
35
36 #include <window.h>
37 #include <svdata.hxx>
38 #include <salgdi.hxx>
39 #include <salframe.hxx>
40 #include <scrwnd.hxx>
41
42 #include <com/sun/star/accessibility/AccessibleRelation.hpp>
43 #include <com/sun/star/accessibility/AccessibleRole.hpp>
44
45 using namespace com::sun::star;
46
47 namespace vcl {
48
ShowFocus(const tools::Rectangle & rRect)49 void Window::ShowFocus( const tools::Rectangle& rRect )
50 {
51 if( mpWindowImpl->mbInShowFocus )
52 return;
53 mpWindowImpl->mbInShowFocus = true;
54
55 ImplWinData* pWinData = ImplGetWinData();
56
57 // native themeing suggest not to use focus rects
58 if( ! ( mpWindowImpl->mbUseNativeFocus &&
59 IsNativeWidgetEnabled() ) )
60 {
61 if ( !mpWindowImpl->mbInPaint )
62 {
63 if ( mpWindowImpl->mbFocusVisible )
64 {
65 if ( *pWinData->mpFocusRect == rRect )
66 {
67 mpWindowImpl->mbInShowFocus = false;
68 return;
69 }
70
71 ImplInvertFocus( *pWinData->mpFocusRect );
72 }
73
74 ImplInvertFocus( rRect );
75 }
76 pWinData->mpFocusRect = rRect;
77 mpWindowImpl->mbFocusVisible = true;
78 }
79 else
80 {
81 if( ! mpWindowImpl->mbNativeFocusVisible )
82 {
83 mpWindowImpl->mbNativeFocusVisible = true;
84 if ( !mpWindowImpl->mbInPaint )
85 Invalidate();
86 }
87 }
88 mpWindowImpl->mbInShowFocus = false;
89 }
90
HideFocus()91 void Window::HideFocus()
92 {
93
94 if( mpWindowImpl->mbInHideFocus )
95 return;
96 mpWindowImpl->mbInHideFocus = true;
97
98 // native themeing can suggest not to use focus rects
99 if( ! ( mpWindowImpl->mbUseNativeFocus &&
100 IsNativeWidgetEnabled() ) )
101 {
102 if ( !mpWindowImpl->mbFocusVisible )
103 {
104 mpWindowImpl->mbInHideFocus = false;
105 return;
106 }
107
108 if ( !mpWindowImpl->mbInPaint )
109 ImplInvertFocus( *ImplGetWinData()->mpFocusRect );
110 mpWindowImpl->mbFocusVisible = false;
111 }
112 else
113 {
114 if( mpWindowImpl->mbNativeFocusVisible )
115 {
116 mpWindowImpl->mbNativeFocusVisible = false;
117 if ( !mpWindowImpl->mbInPaint )
118 Invalidate();
119 }
120 }
121 mpWindowImpl->mbInHideFocus = false;
122 }
123
ShowTracking(const tools::Rectangle & rRect,ShowTrackFlags nFlags)124 void Window::ShowTracking( const tools::Rectangle& rRect, ShowTrackFlags nFlags )
125 {
126 ImplWinData* pWinData = ImplGetWinData();
127
128 if ( !mpWindowImpl->mbInPaint || !(nFlags & ShowTrackFlags::TrackWindow) )
129 {
130 if ( mpWindowImpl->mbTrackVisible )
131 {
132 if ( (*pWinData->mpTrackRect == rRect) &&
133 (pWinData->mnTrackFlags == nFlags) )
134 return;
135
136 InvertTracking( *pWinData->mpTrackRect, pWinData->mnTrackFlags );
137 }
138
139 InvertTracking( rRect, nFlags );
140 }
141
142 pWinData->mpTrackRect = rRect;
143 pWinData->mnTrackFlags = nFlags;
144 mpWindowImpl->mbTrackVisible = true;
145 }
146
HideTracking()147 void Window::HideTracking()
148 {
149 if ( mpWindowImpl->mbTrackVisible )
150 {
151 ImplWinData* pWinData = ImplGetWinData();
152 if ( !mpWindowImpl->mbInPaint || !(pWinData->mnTrackFlags & ShowTrackFlags::TrackWindow) )
153 InvertTracking( *pWinData->mpTrackRect, pWinData->mnTrackFlags );
154 mpWindowImpl->mbTrackVisible = false;
155 }
156 }
157
InvertTracking(const tools::Rectangle & rRect,ShowTrackFlags nFlags)158 void Window::InvertTracking( const tools::Rectangle& rRect, ShowTrackFlags nFlags )
159 {
160 OutputDevice *pOutDev = GetOutDev();
161 tools::Rectangle aRect( pOutDev->ImplLogicToDevicePixel( rRect ) );
162
163 if ( aRect.IsEmpty() )
164 return;
165 aRect.Justify();
166
167 SalGraphics* pGraphics;
168
169 if ( nFlags & ShowTrackFlags::TrackWindow )
170 {
171 if ( !IsDeviceOutputNecessary() )
172 return;
173
174 // we need a graphics
175 if ( !mpGraphics )
176 {
177 if ( !pOutDev->AcquireGraphics() )
178 return;
179 }
180
181 if ( mbInitClipRegion )
182 InitClipRegion();
183
184 if ( mbOutputClipped )
185 return;
186
187 pGraphics = mpGraphics;
188 }
189 else
190 {
191 pGraphics = ImplGetFrameGraphics();
192
193 if ( nFlags & ShowTrackFlags::Clip )
194 {
195 Point aPoint( mnOutOffX, mnOutOffY );
196 vcl::Region aRegion( tools::Rectangle( aPoint,
197 Size( mnOutWidth, mnOutHeight ) ) );
198 ImplClipBoundaries( aRegion, false, false );
199 pOutDev->SelectClipRegion( aRegion, pGraphics );
200 }
201 }
202
203 ShowTrackFlags nStyle = nFlags & ShowTrackFlags::StyleMask;
204 if ( nStyle == ShowTrackFlags::Object )
205 pGraphics->Invert( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight(), SalInvert::TrackFrame, this );
206 else if ( nStyle == ShowTrackFlags::Split )
207 pGraphics->Invert( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight(), SalInvert::N50, this );
208 else
209 {
210 long nBorder = 1;
211 if ( nStyle == ShowTrackFlags::Big )
212 nBorder = 5;
213 pGraphics->Invert( aRect.Left(), aRect.Top(), aRect.GetWidth(), nBorder, SalInvert::N50, this );
214 pGraphics->Invert( aRect.Left(), aRect.Bottom()-nBorder+1, aRect.GetWidth(), nBorder, SalInvert::N50, this );
215 pGraphics->Invert( aRect.Left(), aRect.Top()+nBorder, nBorder, aRect.GetHeight()-(nBorder*2), SalInvert::N50, this );
216 pGraphics->Invert( aRect.Right()-nBorder+1, aRect.Top()+nBorder, nBorder, aRect.GetHeight()-(nBorder*2), SalInvert::N50, this );
217 }
218 }
219
IMPL_LINK(Window,ImplTrackTimerHdl,Timer *,pTimer,void)220 IMPL_LINK( Window, ImplTrackTimerHdl, Timer*, pTimer, void )
221 {
222 ImplSVData* pSVData = ImplGetSVData();
223
224 // if Button-Repeat we have to change the timeout
225 if ( pSVData->maWinData.mnTrackFlags & StartTrackingFlags::ButtonRepeat )
226 pTimer->SetTimeout( GetSettings().GetMouseSettings().GetButtonRepeat() );
227
228 // create Tracking-Event
229 Point aMousePos( mpWindowImpl->mpFrameData->mnLastMouseX, mpWindowImpl->mpFrameData->mnLastMouseY );
230 if( ImplIsAntiparallel() )
231 {
232 // re-mirror frame pos at pChild
233 const OutputDevice *pOutDev = GetOutDev();
234 pOutDev->ReMirror( aMousePos );
235 }
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 );
242 }
243
StartTracking(StartTrackingFlags nFlags)244 void Window::StartTracking( StartTrackingFlags nFlags )
245 {
246 ImplSVData* pSVData = ImplGetSVData();
247
248 if ( pSVData->maWinData.mpTrackWin.get() != this )
249 {
250 if ( pSVData->maWinData.mpTrackWin )
251 pSVData->maWinData.mpTrackWin->EndTracking( TrackingEventFlags::Cancel );
252 }
253
254 if ( nFlags & (StartTrackingFlags::ScrollRepeat | StartTrackingFlags::ButtonRepeat) )
255 {
256 pSVData->maWinData.mpTrackTimer = new AutoTimer;
257
258 if ( nFlags & StartTrackingFlags::ScrollRepeat )
259 pSVData->maWinData.mpTrackTimer->SetTimeout( MouseSettings::GetScrollRepeat() );
260 else
261 pSVData->maWinData.mpTrackTimer->SetTimeout( MouseSettings::GetButtonStartRepeat() );
262 pSVData->maWinData.mpTrackTimer->SetInvokeHandler( LINK( this, Window, ImplTrackTimerHdl ) );
263 pSVData->maWinData.mpTrackTimer->SetDebugName( "vcl::Window pSVData->maWinData.mpTrackTimer" );
264 pSVData->maWinData.mpTrackTimer->Start();
265 }
266
267 pSVData->maWinData.mpTrackWin = this;
268 pSVData->maWinData.mnTrackFlags = nFlags;
269 CaptureMouse();
270 }
271
EndTracking(TrackingEventFlags nFlags)272 void Window::EndTracking( TrackingEventFlags nFlags )
273 {
274 ImplSVData* pSVData = ImplGetSVData();
275
276 if ( pSVData->maWinData.mpTrackWin.get() == this )
277 {
278 if ( pSVData->maWinData.mpTrackTimer )
279 {
280 delete pSVData->maWinData.mpTrackTimer;
281 pSVData->maWinData.mpTrackTimer = nullptr;
282 }
283
284 pSVData->maWinData.mpTrackWin = nullptr;
285 pSVData->maWinData.mnTrackFlags = StartTrackingFlags::NONE;
286 ReleaseMouse();
287
288 // call EndTracking if required
289 {
290 Point aMousePos( mpWindowImpl->mpFrameData->mnLastMouseX, mpWindowImpl->mpFrameData->mnLastMouseY );
291 if( ImplIsAntiparallel() )
292 {
293 // re-mirror frame pos at pChild
294 const OutputDevice *pOutDev = GetOutDev();
295 pOutDev->ReMirror( aMousePos );
296 }
297
298 MouseEvent aMEvt( ImplFrameToOutput( aMousePos ),
299 mpWindowImpl->mpFrameData->mnClickCount, MouseEventModifiers::NONE,
300 mpWindowImpl->mpFrameData->mnMouseCode,
301 mpWindowImpl->mpFrameData->mnMouseCode );
302 TrackingEvent aTEvt( aMEvt, nFlags | TrackingEventFlags::End );
303 // CompatTracking effectively
304 if (!mpWindowImpl || mpWindowImpl->mbInDispose)
305 return Window::Tracking( aTEvt );
306 else
307 return Tracking( aTEvt );
308 }
309 }
310 }
311
IsTracking() const312 bool Window::IsTracking() const
313 {
314 return (ImplGetSVData()->maWinData.mpTrackWin == this);
315 }
316
StartAutoScroll(StartAutoScrollFlags nFlags)317 void Window::StartAutoScroll( StartAutoScrollFlags nFlags )
318 {
319 ImplSVData* pSVData = ImplGetSVData();
320
321 if ( pSVData->maWinData.mpAutoScrollWin.get() != this )
322 {
323 if ( pSVData->maWinData.mpAutoScrollWin )
324 pSVData->maWinData.mpAutoScrollWin->EndAutoScroll();
325 }
326
327 pSVData->maWinData.mpAutoScrollWin = this;
328 pSVData->maWinData.mnAutoScrollFlags = nFlags;
329 pSVData->maAppData.mpWheelWindow = VclPtr<ImplWheelWindow>::Create( this );
330 }
331
EndAutoScroll()332 void Window::EndAutoScroll()
333 {
334 ImplSVData* pSVData = ImplGetSVData();
335
336 if ( pSVData->maWinData.mpAutoScrollWin.get() == this )
337 {
338 pSVData->maWinData.mpAutoScrollWin = nullptr;
339 pSVData->maWinData.mnAutoScrollFlags = StartAutoScrollFlags::NONE;
340 pSVData->maAppData.mpWheelWindow->ImplStop();
341 pSVData->maAppData.mpWheelWindow->SetParentToDefaultWindow();
342 pSVData->maAppData.mpWheelWindow.disposeAndClear();
343 }
344 }
345
SaveFocus()346 VclPtr<vcl::Window> Window::SaveFocus()
347 {
348 ImplSVData* pSVData = ImplGetSVData();
349 if ( pSVData->maWinData.mpFocusWin )
350 {
351 return pSVData->maWinData.mpFocusWin;
352 }
353 else
354 return nullptr;
355 }
356
EndSaveFocus(const VclPtr<vcl::Window> & xFocusWin)357 void Window::EndSaveFocus(const VclPtr<vcl::Window>& xFocusWin)
358 {
359 if (xFocusWin && !xFocusWin->IsDisposed())
360 {
361 xFocusWin->GrabFocus();
362 }
363 }
364
SetZoom(const Fraction & rZoom)365 void Window::SetZoom( const Fraction& rZoom )
366 {
367 if ( mpWindowImpl && mpWindowImpl->maZoom != rZoom )
368 {
369 mpWindowImpl->maZoom = rZoom;
370 CompatStateChanged( StateChangedType::Zoom );
371 }
372 }
373
WinFloatRound(double fVal)374 static long WinFloatRound( double fVal )
375 {
376 return( fVal > 0.0 ? static_cast<long>( fVal + 0.5 ) : -static_cast<long>( -fVal + 0.5 ) );
377 }
378
SetZoomedPointFont(vcl::RenderContext & rRenderContext,const vcl::Font & rFont)379 void Window::SetZoomedPointFont(vcl::RenderContext& rRenderContext, const vcl::Font& rFont)
380 {
381 const Fraction& rZoom = GetZoom();
382 if (rZoom.GetNumerator() != rZoom.GetDenominator())
383 {
384 vcl::Font aFont(rFont);
385 Size aSize = aFont.GetFontSize();
386 aSize.setWidth( WinFloatRound(double(aSize.Width() * rZoom)) );
387 aSize.setHeight( WinFloatRound(double(aSize.Height() * rZoom)) );
388 aFont.SetFontSize(aSize);
389 SetPointFont(rRenderContext, aFont);
390 }
391 else
392 {
393 SetPointFont(rRenderContext, rFont);
394 }
395 }
396
CalcZoom(long nCalc) const397 long Window::CalcZoom( long nCalc ) const
398 {
399
400 const Fraction& rZoom = GetZoom();
401 if ( rZoom.GetNumerator() != rZoom.GetDenominator() )
402 {
403 double n = double(nCalc * rZoom);
404 nCalc = WinFloatRound( n );
405 }
406 return nCalc;
407 }
408
SetControlFont()409 void Window::SetControlFont()
410 {
411 if (mpWindowImpl && mpWindowImpl->mpControlFont)
412 {
413 mpWindowImpl->mpControlFont.reset();
414 CompatStateChanged(StateChangedType::ControlFont);
415 }
416 }
417
SetControlFont(const vcl::Font & rFont)418 void Window::SetControlFont(const vcl::Font& rFont)
419 {
420 if (rFont == vcl::Font())
421 {
422 SetControlFont();
423 return;
424 }
425
426 if (mpWindowImpl->mpControlFont)
427 {
428 if (*mpWindowImpl->mpControlFont == rFont)
429 return;
430 *mpWindowImpl->mpControlFont = rFont;
431 }
432 else
433 mpWindowImpl->mpControlFont.reset( new vcl::Font(rFont) );
434
435 CompatStateChanged(StateChangedType::ControlFont);
436 }
437
GetControlFont() const438 vcl::Font Window::GetControlFont() const
439 {
440 if (mpWindowImpl->mpControlFont)
441 return *mpWindowImpl->mpControlFont;
442 else
443 {
444 vcl::Font aFont;
445 return aFont;
446 }
447 }
448
ApplyControlFont(vcl::RenderContext & rRenderContext,const vcl::Font & rFont)449 void Window::ApplyControlFont(vcl::RenderContext& rRenderContext, const vcl::Font& rFont)
450 {
451 vcl::Font aFont(rFont);
452 if (IsControlFont())
453 aFont.Merge(GetControlFont());
454 SetZoomedPointFont(rRenderContext, aFont);
455 }
456
SetControlForeground()457 void Window::SetControlForeground()
458 {
459 if (mpWindowImpl->mbControlForeground)
460 {
461 mpWindowImpl->maControlForeground = COL_TRANSPARENT;
462 mpWindowImpl->mbControlForeground = false;
463 CompatStateChanged(StateChangedType::ControlForeground);
464 }
465 }
466
SetControlForeground(const Color & rColor)467 void Window::SetControlForeground(const Color& rColor)
468 {
469 if (rColor.GetTransparency())
470 {
471 if (mpWindowImpl->mbControlForeground)
472 {
473 mpWindowImpl->maControlForeground = COL_TRANSPARENT;
474 mpWindowImpl->mbControlForeground = false;
475 CompatStateChanged(StateChangedType::ControlForeground);
476 }
477 }
478 else
479 {
480 if (mpWindowImpl->maControlForeground != rColor)
481 {
482 mpWindowImpl->maControlForeground = rColor;
483 mpWindowImpl->mbControlForeground = true;
484 CompatStateChanged(StateChangedType::ControlForeground);
485 }
486 }
487 }
488
ApplyControlForeground(vcl::RenderContext & rRenderContext,const Color & rDefaultColor)489 void Window::ApplyControlForeground(vcl::RenderContext& rRenderContext, const Color& rDefaultColor)
490 {
491 Color aTextColor(rDefaultColor);
492 if (IsControlForeground())
493 aTextColor = GetControlForeground();
494 rRenderContext.SetTextColor(aTextColor);
495 }
496
SetControlBackground()497 void Window::SetControlBackground()
498 {
499 if (mpWindowImpl->mbControlBackground)
500 {
501 mpWindowImpl->maControlBackground = COL_TRANSPARENT;
502 mpWindowImpl->mbControlBackground = false;
503 CompatStateChanged(StateChangedType::ControlBackground);
504 }
505 }
506
SetControlBackground(const Color & rColor)507 void Window::SetControlBackground(const Color& rColor)
508 {
509 if (rColor.GetTransparency())
510 {
511 if (mpWindowImpl->mbControlBackground)
512 {
513 mpWindowImpl->maControlBackground = COL_TRANSPARENT;
514 mpWindowImpl->mbControlBackground = false;
515 CompatStateChanged(StateChangedType::ControlBackground);
516 }
517 }
518 else
519 {
520 if (mpWindowImpl->maControlBackground != rColor)
521 {
522 mpWindowImpl->maControlBackground = rColor;
523 mpWindowImpl->mbControlBackground = true;
524 CompatStateChanged(StateChangedType::ControlBackground);
525 }
526 }
527 }
528
ApplyControlBackground(vcl::RenderContext & rRenderContext,const Color & rDefaultColor)529 void Window::ApplyControlBackground(vcl::RenderContext& rRenderContext, const Color& rDefaultColor)
530 {
531 Color aColor(rDefaultColor);
532 if (IsControlBackground())
533 aColor = GetControlBackground();
534 rRenderContext.SetBackground(aColor);
535 }
536
CalcWindowSize(const Size & rOutSz) const537 Size Window::CalcWindowSize( const Size& rOutSz ) const
538 {
539 Size aSz = rOutSz;
540 aSz.AdjustWidth(mpWindowImpl->mnLeftBorder+mpWindowImpl->mnRightBorder );
541 aSz.AdjustHeight(mpWindowImpl->mnTopBorder+mpWindowImpl->mnBottomBorder );
542 return aSz;
543 }
544
CalcOutputSize(const Size & rWinSz) const545 Size Window::CalcOutputSize( const Size& rWinSz ) const
546 {
547 Size aSz = rWinSz;
548 aSz.AdjustWidth( -(mpWindowImpl->mnLeftBorder+mpWindowImpl->mnRightBorder) );
549 aSz.AdjustHeight( -(mpWindowImpl->mnTopBorder+mpWindowImpl->mnBottomBorder) );
550 return aSz;
551 }
552
GetDrawPixelFont(OutputDevice const * pDev) const553 vcl::Font Window::GetDrawPixelFont(OutputDevice const * pDev) const
554 {
555 vcl::Font aFont = GetPointFont(*const_cast<Window*>(this));
556 Size aFontSize = aFont.GetFontSize();
557 MapMode aPtMapMode(MapUnit::MapPoint);
558 aFontSize = pDev->LogicToPixel( aFontSize, aPtMapMode );
559 aFont.SetFontSize( aFontSize );
560 return aFont;
561 }
562
GetDrawPixel(OutputDevice const * pDev,long nPixels) const563 long Window::GetDrawPixel( OutputDevice const * pDev, long nPixels ) const
564 {
565 long nP = nPixels;
566 if ( pDev->GetOutDevType() != OUTDEV_WINDOW )
567 {
568 MapMode aMap( MapUnit::Map100thMM );
569 Size aSz( nP, 0 );
570 aSz = PixelToLogic( aSz, aMap );
571 aSz = pDev->LogicToPixel( aSz, aMap );
572 nP = aSz.Width();
573 }
574 return nP;
575 }
576
lcl_HandleScrollHelper(ScrollBar * pScrl,double nN,bool isMultiplyByLineSize)577 static void lcl_HandleScrollHelper( ScrollBar* pScrl, double nN, bool isMultiplyByLineSize )
578 {
579 if ( pScrl && nN && pScrl->IsEnabled() && pScrl->IsInputEnabled() && ! pScrl->IsInModalMode() )
580 {
581 long nNewPos = pScrl->GetThumbPos();
582
583 if ( nN == double(-LONG_MAX) )
584 nNewPos += pScrl->GetPageSize();
585 else if ( nN == double(LONG_MAX) )
586 nNewPos -= pScrl->GetPageSize();
587 else
588 {
589 // allowing both chunked and continuous scrolling
590 if(isMultiplyByLineSize){
591 nN*=pScrl->GetLineSize();
592 }
593
594 const double fVal = nNewPos - nN;
595
596 if ( !o3tl::convertsToAtLeast(fVal, LONG_MIN) )
597 nNewPos = LONG_MIN;
598 else if ( !o3tl::convertsToAtMost(fVal, LONG_MAX) )
599 nNewPos = LONG_MAX;
600 else
601 nNewPos = static_cast<long>(fVal);
602 }
603
604 pScrl->DoScroll( nNewPos );
605 }
606
607 }
608
HandleScrollCommand(const CommandEvent & rCmd,ScrollBar * pHScrl,ScrollBar * pVScrl)609 bool Window::HandleScrollCommand( const CommandEvent& rCmd,
610 ScrollBar* pHScrl, ScrollBar* pVScrl )
611 {
612 bool bRet = false;
613
614 if ( pHScrl || pVScrl )
615 {
616 switch( rCmd.GetCommand() )
617 {
618 case CommandEventId::StartAutoScroll:
619 {
620 StartAutoScrollFlags nFlags = StartAutoScrollFlags::NONE;
621 if ( pHScrl )
622 {
623 if ( (pHScrl->GetVisibleSize() < pHScrl->GetRangeMax()) &&
624 pHScrl->IsEnabled() && pHScrl->IsInputEnabled() && ! pHScrl->IsInModalMode() )
625 nFlags |= StartAutoScrollFlags::Horz;
626 }
627 if ( pVScrl )
628 {
629 if ( (pVScrl->GetVisibleSize() < pVScrl->GetRangeMax()) &&
630 pVScrl->IsEnabled() && pVScrl->IsInputEnabled() && ! pVScrl->IsInModalMode() )
631 nFlags |= StartAutoScrollFlags::Vert;
632 }
633
634 if ( nFlags != StartAutoScrollFlags::NONE )
635 {
636 StartAutoScroll( nFlags );
637 bRet = true;
638 }
639 }
640 break;
641
642 case CommandEventId::Wheel:
643 {
644 const CommandWheelData* pData = rCmd.GetWheelData();
645
646 if ( pData && (CommandWheelMode::SCROLL == pData->GetMode()) )
647 {
648 if (!pData->IsDeltaPixel())
649 {
650 double nScrollLines = pData->GetScrollLines();
651 double nLines;
652 if ( nScrollLines == COMMAND_WHEEL_PAGESCROLL )
653 {
654 if ( pData->GetDelta() < 0 )
655 nLines = double(-LONG_MAX);
656 else
657 nLines = double(LONG_MAX);
658 }
659 else
660 nLines = pData->GetNotchDelta() * nScrollLines;
661 if ( nLines )
662 {
663 ImplHandleScroll( nullptr,
664 0L,
665 pData->IsHorz() ? pHScrl : pVScrl,
666 nLines );
667 bRet = true;
668 }
669 }
670 else
671 {
672 // Mobile / touch scrolling section
673 const Point & deltaPoint = rCmd.GetMousePosPixel();
674
675 double deltaXInPixels = double(deltaPoint.X());
676 double deltaYInPixels = double(deltaPoint.Y());
677 Size winSize = GetOutputSizePixel();
678
679 if(pHScrl)
680 {
681 double visSizeX = double(pHScrl->GetVisibleSize());
682 double ratioX = deltaXInPixels / double(winSize.getWidth());
683 long deltaXInLogic = long(visSizeX * ratioX);
684 // Touch need to work by pixels. Did not apply this to
685 // Android, as android code may require adaptations
686 // to work with this scrolling code
687 #ifndef IOS
688 long lineSizeX = pHScrl->GetLineSize();
689
690 if(lineSizeX)
691 {
692 deltaXInLogic /= lineSizeX;
693 }
694 else
695 {
696 deltaXInLogic = 0;
697 }
698 #endif
699 if ( deltaXInLogic)
700 {
701 #ifndef IOS
702 bool const isMultiplyByLineSize = true;
703 #else
704 bool const isMultiplyByLineSize = false;
705 #endif
706 lcl_HandleScrollHelper( pHScrl, deltaXInLogic, isMultiplyByLineSize );
707 bRet = true;
708 }
709 }
710 if(pVScrl)
711 {
712 double visSizeY = double(pVScrl->GetVisibleSize());
713 double ratioY = deltaYInPixels / double(winSize.getHeight());
714 long deltaYInLogic = long(visSizeY * ratioY);
715
716 // Touch need to work by pixels. Did not apply this to
717 // Android, as android code may require adaptations
718 // to work with this scrolling code
719 #ifndef IOS
720 long lineSizeY = pVScrl->GetLineSize();
721 if(lineSizeY)
722 {
723 deltaYInLogic /= lineSizeY;
724 }
725 else
726 {
727 deltaYInLogic = 0;
728 }
729 #endif
730 if ( deltaYInLogic )
731 {
732 #ifndef IOS
733 bool const isMultiplyByLineSize = true;
734 #else
735 bool const isMultiplyByLineSize = false;
736 #endif
737 lcl_HandleScrollHelper( pVScrl, deltaYInLogic, isMultiplyByLineSize );
738
739 bRet = true;
740 }
741 }
742 }
743 }
744 }
745 break;
746
747 case CommandEventId::Gesture:
748 {
749 if (pVScrl)
750 {
751 const CommandGestureData* pData = rCmd.GetGestureData();
752 if (pData->meEventType == GestureEventType::PanningBegin)
753 {
754 mpWindowImpl->mpFrameData->mnTouchPanPosition = pVScrl->GetThumbPos();
755 }
756 else if(pData->meEventType == GestureEventType::PanningUpdate)
757 {
758 long nOriginalPosition = mpWindowImpl->mpFrameData->mnTouchPanPosition;
759 pVScrl->DoScroll(nOriginalPosition + (pData->mfOffset / pVScrl->GetVisibleSize()));
760 }
761 if (pData->meEventType == GestureEventType::PanningEnd)
762 {
763 mpWindowImpl->mpFrameData->mnTouchPanPosition = -1;
764 }
765 bRet = true;
766 }
767 break;
768 }
769
770 case CommandEventId::AutoScroll:
771 {
772 const CommandScrollData* pData = rCmd.GetAutoScrollData();
773 if ( pData && (pData->GetDeltaX() || pData->GetDeltaY()) )
774 {
775 ImplHandleScroll( pHScrl, pData->GetDeltaX(),
776 pVScrl, pData->GetDeltaY() );
777 bRet = true;
778 }
779 }
780 break;
781
782 default:
783 break;
784 }
785 }
786
787 return bRet;
788 }
789
790 // Note that when called for CommandEventId::Wheel above, despite its name,
791 // pVScrl isn't necessarily the vertical scroll bar. Depending on
792 // whether the scroll is horizontal or vertical, it is either the
793 // horizontal or vertical scroll bar. nY is correspondingly either
794 // the horizontal or vertical scroll amount.
795
ImplHandleScroll(ScrollBar * pHScrl,double nX,ScrollBar * pVScrl,double nY)796 void Window::ImplHandleScroll( ScrollBar* pHScrl, double nX,
797 ScrollBar* pVScrl, double nY )
798 {
799 lcl_HandleScrollHelper( pHScrl, nX, true );
800 lcl_HandleScrollHelper( pVScrl, nY, true );
801 }
802
GetDockingManager()803 DockingManager* Window::GetDockingManager()
804 {
805 return ImplGetDockingManager();
806 }
807
EnableDocking(bool bEnable)808 void Window::EnableDocking( bool bEnable )
809 {
810 // update list of dockable windows
811 if( bEnable )
812 ImplGetDockingManager()->AddWindow( this );
813 else
814 ImplGetDockingManager()->RemoveWindow( this );
815 }
816
817 // retrieves the list of owner draw decorated windows for this window hierarchy
ImplGetOwnerDrawList()818 ::std::vector<VclPtr<vcl::Window> >& Window::ImplGetOwnerDrawList()
819 {
820 return ImplGetTopmostFrameWindow()->mpWindowImpl->mpFrameData->maOwnerDrawList;
821 }
822
SetHelpId(const OString & rHelpId)823 void Window::SetHelpId( const OString& rHelpId )
824 {
825 mpWindowImpl->maHelpId = rHelpId;
826 }
827
GetHelpId() const828 const OString& Window::GetHelpId() const
829 {
830 return mpWindowImpl->maHelpId;
831 }
832
833 // --------- old inline methods ---------------
834
ImplGetWindow() const835 vcl::Window* Window::ImplGetWindow() const
836 {
837 if ( mpWindowImpl->mpClientWindow )
838 return mpWindowImpl->mpClientWindow;
839 else
840 return const_cast<vcl::Window*>(this);
841 }
842
ImplGetFrameData()843 ImplFrameData* Window::ImplGetFrameData()
844 {
845 return mpWindowImpl ? mpWindowImpl->mpFrameData : nullptr;
846 }
847
ImplGetFrame() const848 SalFrame* Window::ImplGetFrame() const
849 {
850 return mpWindowImpl ? mpWindowImpl->mpFrame : nullptr;
851 }
852
GetFrameWeld() const853 weld::Window* Window::GetFrameWeld() const
854 {
855 SalFrame* pFrame = ImplGetFrame();
856 return pFrame ? pFrame->GetFrameWeld() : nullptr;
857 }
858
ImplGetParent() const859 vcl::Window* Window::ImplGetParent() const
860 {
861 return mpWindowImpl ? mpWindowImpl->mpParent.get() : nullptr;
862 }
863
ImplGetClientWindow() const864 vcl::Window* Window::ImplGetClientWindow() const
865 {
866 return mpWindowImpl ? mpWindowImpl->mpClientWindow.get() : nullptr;
867 }
868
ImplGetBorderWindow() const869 vcl::Window* Window::ImplGetBorderWindow() const
870 {
871 return mpWindowImpl ? mpWindowImpl->mpBorderWindow.get() : nullptr;
872 }
873
ImplGetFirstOverlapWindow()874 vcl::Window* Window::ImplGetFirstOverlapWindow()
875 {
876 if ( mpWindowImpl->mbOverlapWin )
877 return this;
878 else
879 return mpWindowImpl->mpOverlapWindow;
880 }
881
ImplGetFirstOverlapWindow() const882 const vcl::Window* Window::ImplGetFirstOverlapWindow() const
883 {
884 if ( mpWindowImpl->mbOverlapWin )
885 return this;
886 else
887 return mpWindowImpl->mpOverlapWindow;
888 }
889
ImplGetFrameWindow() const890 vcl::Window* Window::ImplGetFrameWindow() const
891 {
892 return mpWindowImpl ? mpWindowImpl->mpFrameWindow.get() : nullptr;
893 }
894
IsDockingWindow() const895 bool Window::IsDockingWindow() const
896 {
897 return mpWindowImpl && mpWindowImpl->mbDockWin;
898 }
899
ImplIsFloatingWindow() const900 bool Window::ImplIsFloatingWindow() const
901 {
902 return mpWindowImpl && mpWindowImpl->mbFloatWin;
903 }
904
ImplIsSplitter() const905 bool Window::ImplIsSplitter() const
906 {
907 return mpWindowImpl && mpWindowImpl->mbSplitter;
908 }
909
ImplIsPushButton() const910 bool Window::ImplIsPushButton() const
911 {
912 return mpWindowImpl && mpWindowImpl->mbPushButton;
913 }
914
ImplIsOverlapWindow() const915 bool Window::ImplIsOverlapWindow() const
916 {
917 return mpWindowImpl && mpWindowImpl->mbOverlapWin;
918 }
919
ImplSetMouseTransparent(bool bTransparent)920 void Window::ImplSetMouseTransparent( bool bTransparent )
921 {
922 if (mpWindowImpl)
923 mpWindowImpl->mbMouseTransparent = bTransparent;
924 }
925
ImplOutputToFrame(const Point & rPos)926 Point Window::ImplOutputToFrame( const Point& rPos )
927 {
928 return Point( rPos.X()+mnOutOffX, rPos.Y()+mnOutOffY );
929 }
930
ImplFrameToOutput(const Point & rPos)931 Point Window::ImplFrameToOutput( const Point& rPos )
932 {
933 return Point( rPos.X()-mnOutOffX, rPos.Y()-mnOutOffY );
934 }
935
SetCompoundControl(bool bCompound)936 void Window::SetCompoundControl( bool bCompound )
937 {
938 if (mpWindowImpl)
939 mpWindowImpl->mbCompoundControl = bCompound;
940 }
941
GetStyle() const942 WinBits Window::GetStyle() const
943 {
944 return mpWindowImpl ? mpWindowImpl->mnStyle : 0;
945 }
946
GetPrevStyle() const947 WinBits Window::GetPrevStyle() const
948 {
949 return mpWindowImpl ? mpWindowImpl->mnPrevStyle : 0;
950 }
951
GetExtendedStyle() const952 WindowExtendedStyle Window::GetExtendedStyle() const
953 {
954 return mpWindowImpl ? mpWindowImpl->mnExtendedStyle : WindowExtendedStyle::NONE;
955 }
956
SetType(WindowType nType)957 void Window::SetType( WindowType nType )
958 {
959 if (mpWindowImpl)
960 mpWindowImpl->mnType = nType;
961 }
962
GetType() const963 WindowType Window::GetType() const
964 {
965 if (mpWindowImpl)
966 return mpWindowImpl->mnType;
967 else
968 return WindowType::NONE;
969 }
970
GetParentDialog() const971 Dialog* Window::GetParentDialog() const
972 {
973 const vcl::Window *pWindow = this;
974
975 while( pWindow )
976 {
977 if( pWindow->IsDialog() )
978 break;
979
980 pWindow = pWindow->GetParent();
981 }
982
983 return const_cast<Dialog *>(dynamic_cast<const Dialog*>(pWindow));
984 }
985
IsSystemWindow() const986 bool Window::IsSystemWindow() const
987 {
988 return mpWindowImpl && mpWindowImpl->mbSysWin;
989 }
990
IsDialog() const991 bool Window::IsDialog() const
992 {
993 return mpWindowImpl && mpWindowImpl->mbDialog;
994 }
995
IsMenuFloatingWindow() const996 bool Window::IsMenuFloatingWindow() const
997 {
998 return mpWindowImpl && mpWindowImpl->mbMenuFloatingWindow;
999 }
1000
IsToolbarFloatingWindow() const1001 bool Window::IsToolbarFloatingWindow() const
1002 {
1003 return mpWindowImpl && mpWindowImpl->mbToolbarFloatingWindow;
1004 }
1005
EnableAllResize()1006 void Window::EnableAllResize()
1007 {
1008 mpWindowImpl->mbAllResize = true;
1009 }
1010
EnableChildTransparentMode(bool bEnable)1011 void Window::EnableChildTransparentMode( bool bEnable )
1012 {
1013 mpWindowImpl->mbChildTransparent = bEnable;
1014 }
1015
IsChildTransparentModeEnabled() const1016 bool Window::IsChildTransparentModeEnabled() const
1017 {
1018 return mpWindowImpl && mpWindowImpl->mbChildTransparent;
1019 }
1020
IsMouseTransparent() const1021 bool Window::IsMouseTransparent() const
1022 {
1023 return mpWindowImpl && mpWindowImpl->mbMouseTransparent;
1024 }
1025
IsPaintTransparent() const1026 bool Window::IsPaintTransparent() const
1027 {
1028 return mpWindowImpl && mpWindowImpl->mbPaintTransparent;
1029 }
1030
SetDialogControlStart(bool bStart)1031 void Window::SetDialogControlStart( bool bStart )
1032 {
1033 mpWindowImpl->mbDlgCtrlStart = bStart;
1034 }
1035
IsDialogControlStart() const1036 bool Window::IsDialogControlStart() const
1037 {
1038 return mpWindowImpl && mpWindowImpl->mbDlgCtrlStart;
1039 }
1040
SetDialogControlFlags(DialogControlFlags nFlags)1041 void Window::SetDialogControlFlags( DialogControlFlags nFlags )
1042 {
1043 mpWindowImpl->mnDlgCtrlFlags = nFlags;
1044 }
1045
GetDialogControlFlags() const1046 DialogControlFlags Window::GetDialogControlFlags() const
1047 {
1048 return mpWindowImpl->mnDlgCtrlFlags;
1049 }
1050
GetInputContext() const1051 const InputContext& Window::GetInputContext() const
1052 {
1053 return mpWindowImpl->maInputContext;
1054 }
1055
IsControlFont() const1056 bool Window::IsControlFont() const
1057 {
1058 return bool(mpWindowImpl->mpControlFont);
1059 }
1060
GetControlForeground() const1061 const Color& Window::GetControlForeground() const
1062 {
1063 return mpWindowImpl->maControlForeground;
1064 }
1065
IsControlForeground() const1066 bool Window::IsControlForeground() const
1067 {
1068 return mpWindowImpl->mbControlForeground;
1069 }
1070
GetControlBackground() const1071 const Color& Window::GetControlBackground() const
1072 {
1073 return mpWindowImpl->maControlBackground;
1074 }
1075
IsControlBackground() const1076 bool Window::IsControlBackground() const
1077 {
1078 return mpWindowImpl->mbControlBackground;
1079 }
1080
IsInPaint() const1081 bool Window::IsInPaint() const
1082 {
1083 return mpWindowImpl && mpWindowImpl->mbInPaint;
1084 }
1085
GetParent() const1086 vcl::Window* Window::GetParent() const
1087 {
1088 return mpWindowImpl ? mpWindowImpl->mpRealParent.get() : nullptr;
1089 }
1090
IsVisible() const1091 bool Window::IsVisible() const
1092 {
1093 return mpWindowImpl && mpWindowImpl->mbVisible;
1094 }
1095
IsReallyVisible() const1096 bool Window::IsReallyVisible() const
1097 {
1098 return mpWindowImpl && mpWindowImpl->mbReallyVisible;
1099 }
1100
IsReallyShown() const1101 bool Window::IsReallyShown() const
1102 {
1103 return mpWindowImpl && mpWindowImpl->mbReallyShown;
1104 }
1105
IsInInitShow() const1106 bool Window::IsInInitShow() const
1107 {
1108 return mpWindowImpl->mbInInitShow;
1109 }
1110
IsEnabled() const1111 bool Window::IsEnabled() const
1112 {
1113 return mpWindowImpl && !mpWindowImpl->mbDisabled;
1114 }
1115
IsInputEnabled() const1116 bool Window::IsInputEnabled() const
1117 {
1118 return mpWindowImpl && !mpWindowImpl->mbInputDisabled;
1119 }
1120
IsAlwaysEnableInput() const1121 bool Window::IsAlwaysEnableInput() const
1122 {
1123 return mpWindowImpl->meAlwaysInputMode == AlwaysInputEnabled;
1124 }
1125
GetActivateMode() const1126 ActivateModeFlags Window::GetActivateMode() const
1127 {
1128 return mpWindowImpl->mnActivateMode;
1129
1130 }
1131
IsAlwaysOnTopEnabled() const1132 bool Window::IsAlwaysOnTopEnabled() const
1133 {
1134 return mpWindowImpl->mbAlwaysOnTop;
1135 }
1136
IsDefaultPos() const1137 bool Window::IsDefaultPos() const
1138 {
1139 return mpWindowImpl->mbDefPos;
1140 }
1141
IsDefaultSize() const1142 bool Window::IsDefaultSize() const
1143 {
1144 return mpWindowImpl->mbDefSize;
1145 }
1146
GetOffsetPixelFrom(const vcl::Window & rWindow) const1147 Point Window::GetOffsetPixelFrom(const vcl::Window& rWindow) const
1148 {
1149 return Point(GetOutOffXPixel() - rWindow.GetOutOffXPixel(), GetOutOffYPixel() - rWindow.GetOutOffYPixel());
1150 }
1151
EnablePaint(bool bEnable)1152 void Window::EnablePaint( bool bEnable )
1153 {
1154 mpWindowImpl->mbPaintDisabled = !bEnable;
1155 }
1156
IsPaintEnabled() const1157 bool Window::IsPaintEnabled() const
1158 {
1159 return !mpWindowImpl->mbPaintDisabled;
1160 }
1161
IsUpdateMode() const1162 bool Window::IsUpdateMode() const
1163 {
1164 return !mpWindowImpl->mbNoUpdate;
1165 }
1166
SetParentUpdateMode(bool bUpdate)1167 void Window::SetParentUpdateMode( bool bUpdate )
1168 {
1169 mpWindowImpl->mbNoParentUpdate = !bUpdate;
1170 }
1171
IsActive() const1172 bool Window::IsActive() const
1173 {
1174 return mpWindowImpl->mbActive;
1175 }
1176
GetGetFocusFlags() const1177 GetFocusFlags Window::GetGetFocusFlags() const
1178 {
1179 return mpWindowImpl->mnGetFocusFlags;
1180 }
1181
IsCompoundControl() const1182 bool Window::IsCompoundControl() const
1183 {
1184 return mpWindowImpl->mbCompoundControl;
1185 }
1186
IsWait() const1187 bool Window::IsWait() const
1188 {
1189 return (mpWindowImpl->mnWaitCount != 0);
1190 }
1191
GetCursor() const1192 vcl::Cursor* Window::GetCursor() const
1193 {
1194 if (!mpWindowImpl)
1195 return nullptr;
1196 return mpWindowImpl->mpCursor;
1197 }
1198
GetZoom() const1199 const Fraction& Window::GetZoom() const
1200 {
1201 return mpWindowImpl->maZoom;
1202 }
1203
IsZoom() const1204 bool Window::IsZoom() const
1205 {
1206 return mpWindowImpl->maZoom.GetNumerator() != mpWindowImpl->maZoom.GetDenominator();
1207 }
1208
SetHelpText(const OUString & rHelpText)1209 void Window::SetHelpText( const OUString& rHelpText )
1210 {
1211 mpWindowImpl->maHelpText = rHelpText;
1212 mpWindowImpl->mbHelpTextDynamic = true;
1213 }
1214
SetQuickHelpText(const OUString & rHelpText)1215 void Window::SetQuickHelpText( const OUString& rHelpText )
1216 {
1217 if (mpWindowImpl)
1218 mpWindowImpl->maQuickHelpText = rHelpText;
1219 }
1220
GetQuickHelpText() const1221 const OUString& Window::GetQuickHelpText() const
1222 {
1223 return mpWindowImpl->maQuickHelpText;
1224 }
1225
IsCreatedWithToolkit() const1226 bool Window::IsCreatedWithToolkit() const
1227 {
1228 return mpWindowImpl->mbCreatedWithToolkit;
1229 }
1230
SetCreatedWithToolkit(bool b)1231 void Window::SetCreatedWithToolkit( bool b )
1232 {
1233 mpWindowImpl->mbCreatedWithToolkit = b;
1234 }
1235
GetPointer() const1236 PointerStyle Window::GetPointer() const
1237 {
1238 return mpWindowImpl->maPointer;
1239 }
1240
GetWindowPeer() const1241 VCLXWindow* Window::GetWindowPeer() const
1242 {
1243 return mpWindowImpl ? mpWindowImpl->mpVCLXWindow : nullptr;
1244 }
1245
SetPosPixel(const Point & rNewPos)1246 void Window::SetPosPixel( const Point& rNewPos )
1247 {
1248 setPosSizePixel( rNewPos.X(), rNewPos.Y(), 0, 0, PosSizeFlags::Pos );
1249 }
1250
SetSizePixel(const Size & rNewSize)1251 void Window::SetSizePixel( const Size& rNewSize )
1252 {
1253 setPosSizePixel( 0, 0, rNewSize.Width(), rNewSize.Height(),
1254 PosSizeFlags::Size );
1255 }
1256
SetPosSizePixel(const Point & rNewPos,const Size & rNewSize)1257 void Window::SetPosSizePixel( const Point& rNewPos, const Size& rNewSize )
1258 {
1259 setPosSizePixel( rNewPos.X(), rNewPos.Y(),
1260 rNewSize.Width(), rNewSize.Height());
1261 }
1262
SetOutputSizePixel(const Size & rNewSize)1263 void Window::SetOutputSizePixel( const Size& rNewSize )
1264 {
1265 SetSizePixel( Size( rNewSize.Width()+mpWindowImpl->mnLeftBorder+mpWindowImpl->mnRightBorder,
1266 rNewSize.Height()+mpWindowImpl->mnTopBorder+mpWindowImpl->mnBottomBorder ) );
1267 }
1268
1269 //When a widget wants to renegotiate layout, get toplevel parent dialog and call
1270 //resize on it. Mark all intermediate containers (or container-alike) widgets
1271 //as dirty for the size remains unchanged, but layout changed circumstances
1272 namespace
1273 {
queue_ungrouped_resize(vcl::Window const * pOrigWindow)1274 bool queue_ungrouped_resize(vcl::Window const *pOrigWindow)
1275 {
1276 bool bSomeoneCares = false;
1277
1278 vcl::Window *pWindow = pOrigWindow->GetParent();
1279 if (pWindow)
1280 {
1281 if (isContainerWindow(*pWindow))
1282 {
1283 bSomeoneCares = true;
1284 }
1285 else if (pWindow->GetType() == WindowType::TABCONTROL)
1286 {
1287 bSomeoneCares = true;
1288 }
1289 pWindow->queue_resize();
1290 }
1291
1292 return bSomeoneCares;
1293 }
1294 }
1295
InvalidateSizeCache()1296 void Window::InvalidateSizeCache()
1297 {
1298 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1299 pWindowImpl->mnOptimalWidthCache = -1;
1300 pWindowImpl->mnOptimalHeightCache = -1;
1301 }
1302
queue_resize(StateChangedType eReason)1303 void Window::queue_resize(StateChangedType eReason)
1304 {
1305 if (IsDisposed())
1306 return;
1307
1308 bool bSomeoneCares = queue_ungrouped_resize(this);
1309
1310 if (eReason != StateChangedType::Visible)
1311 {
1312 InvalidateSizeCache();
1313 }
1314
1315 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1316 if (pWindowImpl->m_xSizeGroup && pWindowImpl->m_xSizeGroup->get_mode() != VclSizeGroupMode::NONE)
1317 {
1318 std::set<VclPtr<vcl::Window> > &rWindows = pWindowImpl->m_xSizeGroup->get_widgets();
1319 for (VclPtr<vcl::Window> const & pOther : rWindows)
1320 {
1321 if (pOther == this)
1322 continue;
1323 queue_ungrouped_resize(pOther);
1324 }
1325 }
1326
1327 if (bSomeoneCares && !mpWindowImpl->mbInDispose)
1328 {
1329 //fdo#57090 force a resync of the borders of the borderwindow onto this
1330 //window in case they have changed
1331 vcl::Window* pBorderWindow = ImplGetBorderWindow();
1332 if (pBorderWindow)
1333 pBorderWindow->Resize();
1334 }
1335
1336 if (VclPtr<vcl::Window> pParent = GetParentWithLOKNotifier())
1337 {
1338 if (GetParentDialog() && !pParent->IsInInitShow())
1339 LogicInvalidate(nullptr);
1340 }
1341 }
1342
1343 namespace
1344 {
toAlign(const OUString & rValue)1345 VclAlign toAlign(const OUString &rValue)
1346 {
1347 VclAlign eRet = VclAlign::Fill;
1348
1349 if (rValue == "fill")
1350 eRet = VclAlign::Fill;
1351 else if (rValue == "start")
1352 eRet = VclAlign::Start;
1353 else if (rValue == "end")
1354 eRet = VclAlign::End;
1355 else if (rValue == "center")
1356 eRet = VclAlign::Center;
1357 return eRet;
1358 }
1359 }
1360
set_font_attribute(const OString & rKey,const OUString & rValue)1361 bool Window::set_font_attribute(const OString &rKey, const OUString &rValue)
1362 {
1363 if (rKey == "weight")
1364 {
1365 vcl::Font aFont(GetControlFont());
1366 if (rValue == "thin")
1367 aFont.SetWeight(WEIGHT_THIN);
1368 else if (rValue == "ultralight")
1369 aFont.SetWeight(WEIGHT_ULTRALIGHT);
1370 else if (rValue == "light")
1371 aFont.SetWeight(WEIGHT_LIGHT);
1372 else if (rValue == "book")
1373 aFont.SetWeight(WEIGHT_SEMILIGHT);
1374 else if (rValue == "normal")
1375 aFont.SetWeight(WEIGHT_NORMAL);
1376 else if (rValue == "medium")
1377 aFont.SetWeight(WEIGHT_MEDIUM);
1378 else if (rValue == "semibold")
1379 aFont.SetWeight(WEIGHT_SEMIBOLD);
1380 else if (rValue == "bold")
1381 aFont.SetWeight(WEIGHT_BOLD);
1382 else if (rValue == "ultrabold")
1383 aFont.SetWeight(WEIGHT_ULTRABOLD);
1384 else
1385 aFont.SetWeight(WEIGHT_BLACK);
1386 SetControlFont(aFont);
1387 }
1388 else if (rKey == "style")
1389 {
1390 vcl::Font aFont(GetControlFont());
1391 if (rValue == "normal")
1392 aFont.SetItalic(ITALIC_NONE);
1393 else if (rValue == "oblique")
1394 aFont.SetItalic(ITALIC_OBLIQUE);
1395 else if (rValue == "italic")
1396 aFont.SetItalic(ITALIC_NORMAL);
1397 SetControlFont(aFont);
1398 }
1399 else if (rKey == "underline")
1400 {
1401 vcl::Font aFont(GetControlFont());
1402 aFont.SetUnderline(toBool(rValue) ? LINESTYLE_SINGLE : LINESTYLE_NONE);
1403 SetControlFont(aFont);
1404 }
1405 else if (rKey == "size")
1406 {
1407 vcl::Font aFont(GetControlFont());
1408 sal_Int32 nHeight = rValue.toInt32() / 1000;
1409 aFont.SetFontHeight(nHeight);
1410 SetControlFont(aFont);
1411 }
1412 else
1413 {
1414 SAL_INFO("vcl.layout", "unhandled font attribute: " << rKey);
1415 return false;
1416 }
1417 return true;
1418 }
1419
set_property(const OString & rKey,const OUString & rValue)1420 bool Window::set_property(const OString &rKey, const OUString &rValue)
1421 {
1422 if ((rKey == "label") || (rKey == "title") || (rKey == "text") )
1423 {
1424 SetText(BuilderUtils::convertMnemonicMarkup(rValue));
1425 }
1426 else if (rKey == "visible")
1427 Show(toBool(rValue));
1428 else if (rKey == "sensitive")
1429 Enable(toBool(rValue));
1430 else if (rKey == "resizable")
1431 {
1432 WinBits nBits = GetStyle();
1433 nBits &= ~WB_SIZEABLE;
1434 if (toBool(rValue))
1435 nBits |= WB_SIZEABLE;
1436 SetStyle(nBits);
1437 }
1438 else if (rKey == "xalign")
1439 {
1440 WinBits nBits = GetStyle();
1441 nBits &= ~(WB_LEFT | WB_CENTER | WB_RIGHT);
1442
1443 float f = rValue.toFloat();
1444 if (f == 0.0)
1445 nBits |= WB_LEFT;
1446 else if (f == 1.0)
1447 nBits |= WB_RIGHT;
1448 else if (f == 0.5)
1449 nBits |= WB_CENTER;
1450
1451 SetStyle(nBits);
1452 }
1453 else if (rKey == "justification")
1454 {
1455 WinBits nBits = GetStyle();
1456 nBits &= ~(WB_LEFT | WB_CENTER | WB_RIGHT);
1457
1458 if (rValue == "left")
1459 nBits |= WB_LEFT;
1460 else if (rValue == "right")
1461 nBits |= WB_RIGHT;
1462 else if (rValue == "center")
1463 nBits |= WB_CENTER;
1464
1465 SetStyle(nBits);
1466 }
1467 else if (rKey == "yalign")
1468 {
1469 WinBits nBits = GetStyle();
1470 nBits &= ~(WB_TOP | WB_VCENTER | WB_BOTTOM);
1471
1472 float f = rValue.toFloat();
1473 if (f == 0.0)
1474 nBits |= WB_TOP;
1475 else if (f == 1.0)
1476 nBits |= WB_BOTTOM;
1477 else if (f == 0.5)
1478 nBits |= WB_CENTER;
1479
1480 SetStyle(nBits);
1481 }
1482 else if (rKey == "wrap")
1483 {
1484 WinBits nBits = GetStyle();
1485 nBits &= ~WB_WORDBREAK;
1486 if (toBool(rValue))
1487 nBits |= WB_WORDBREAK;
1488 SetStyle(nBits);
1489 }
1490 else if (rKey == "height-request")
1491 set_height_request(rValue.toInt32());
1492 else if (rKey == "width-request")
1493 set_width_request(rValue.toInt32());
1494 else if (rKey == "hexpand")
1495 set_hexpand(toBool(rValue));
1496 else if (rKey == "vexpand")
1497 set_vexpand(toBool(rValue));
1498 else if (rKey == "halign")
1499 set_halign(toAlign(rValue));
1500 else if (rKey == "valign")
1501 set_valign(toAlign(rValue));
1502 else if (rKey == "tooltip-markup")
1503 SetQuickHelpText(rValue);
1504 else if (rKey == "tooltip-text")
1505 SetQuickHelpText(rValue);
1506 else if (rKey == "border-width")
1507 set_border_width(rValue.toInt32());
1508 else if (rKey == "margin-left")
1509 set_margin_left(rValue.toInt32());
1510 else if (rKey == "margin-right")
1511 set_margin_right(rValue.toInt32());
1512 else if (rKey == "margin-top")
1513 set_margin_top(rValue.toInt32());
1514 else if (rKey == "margin-bottom")
1515 set_margin_bottom(rValue.toInt32());
1516 else if (rKey == "hscrollbar-policy")
1517 {
1518 WinBits nBits = GetStyle();
1519 nBits &= ~(WB_AUTOHSCROLL|WB_HSCROLL);
1520 if (rValue == "always")
1521 nBits |= WB_HSCROLL;
1522 else if (rValue == "automatic")
1523 nBits |= WB_AUTOHSCROLL;
1524 SetStyle(nBits);
1525 }
1526 else if (rKey == "vscrollbar-policy")
1527 {
1528 WinBits nBits = GetStyle();
1529 nBits &= ~(WB_AUTOVSCROLL|WB_VSCROLL);
1530 if (rValue == "always")
1531 nBits |= WB_VSCROLL;
1532 else if (rValue == "automatic")
1533 nBits |= WB_AUTOVSCROLL;
1534 SetStyle(nBits);
1535 }
1536 else if (rKey == "accessible-name")
1537 {
1538 SetAccessibleName(rValue);
1539 }
1540 else if (rKey == "accessible-description")
1541 {
1542 SetAccessibleDescription(rValue);
1543 }
1544 else if (rKey == "accessible-role")
1545 {
1546 sal_Int16 role = BuilderUtils::getRoleFromName(rValue.toUtf8());
1547 if (role != com::sun::star::accessibility::AccessibleRole::UNKNOWN)
1548 SetAccessibleRole(role);
1549 }
1550 else if (rKey == "use-markup")
1551 {
1552 //https://live.gnome.org/GnomeGoals/RemoveMarkupInMessages
1553 SAL_WARN_IF(toBool(rValue), "vcl.layout", "Use pango attributes instead of mark-up");
1554 }
1555 else if (rKey == "has-focus")
1556 {
1557 if (toBool(rValue))
1558 GrabFocus();
1559 }
1560 else if (rKey == "can-focus")
1561 {
1562 WinBits nBits = GetStyle();
1563 nBits &= ~(WB_TABSTOP|WB_NOTABSTOP);
1564 if (toBool(rValue))
1565 nBits |= WB_TABSTOP;
1566 else
1567 nBits |= WB_NOTABSTOP;
1568 SetStyle(nBits);
1569 }
1570 else
1571 {
1572 SAL_INFO("vcl.layout", "unhandled property: " << rKey);
1573 return false;
1574 }
1575 return true;
1576 }
1577
set_height_request(sal_Int32 nHeightRequest)1578 void Window::set_height_request(sal_Int32 nHeightRequest)
1579 {
1580 if (!mpWindowImpl)
1581 return;
1582
1583 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1584
1585 if ( pWindowImpl->mnHeightRequest != nHeightRequest )
1586 {
1587 pWindowImpl->mnHeightRequest = nHeightRequest;
1588 queue_resize();
1589 }
1590 }
1591
set_width_request(sal_Int32 nWidthRequest)1592 void Window::set_width_request(sal_Int32 nWidthRequest)
1593 {
1594 if (!mpWindowImpl)
1595 return;
1596
1597 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1598
1599 if ( pWindowImpl->mnWidthRequest != nWidthRequest )
1600 {
1601 pWindowImpl->mnWidthRequest = nWidthRequest;
1602 queue_resize();
1603 }
1604 }
1605
get_ungrouped_preferred_size() const1606 Size Window::get_ungrouped_preferred_size() const
1607 {
1608 Size aRet(get_width_request(), get_height_request());
1609 if (aRet.Width() == -1 || aRet.Height() == -1)
1610 {
1611 //cache gets blown away by queue_resize
1612 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1613 if (pWindowImpl->mnOptimalWidthCache == -1 || pWindowImpl->mnOptimalHeightCache == -1)
1614 {
1615 Size aOptimal(GetOptimalSize());
1616 pWindowImpl->mnOptimalWidthCache = aOptimal.Width();
1617 pWindowImpl->mnOptimalHeightCache = aOptimal.Height();
1618 }
1619
1620 if (aRet.Width() == -1)
1621 aRet.setWidth( pWindowImpl->mnOptimalWidthCache );
1622 if (aRet.Height() == -1)
1623 aRet.setHeight( pWindowImpl->mnOptimalHeightCache );
1624 }
1625 return aRet;
1626 }
1627
get_preferred_size() const1628 Size Window::get_preferred_size() const
1629 {
1630 Size aRet(get_ungrouped_preferred_size());
1631
1632 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1633 if (pWindowImpl->m_xSizeGroup)
1634 {
1635 const VclSizeGroupMode eMode = pWindowImpl->m_xSizeGroup->get_mode();
1636 if (eMode != VclSizeGroupMode::NONE)
1637 {
1638 const bool bIgnoreInHidden = pWindowImpl->m_xSizeGroup->get_ignore_hidden();
1639 const std::set<VclPtr<vcl::Window> > &rWindows = pWindowImpl->m_xSizeGroup->get_widgets();
1640 for (auto const& window : rWindows)
1641 {
1642 const vcl::Window *pOther = window;
1643 if (pOther == this)
1644 continue;
1645 if (bIgnoreInHidden && !pOther->IsVisible())
1646 continue;
1647 Size aOtherSize = pOther->get_ungrouped_preferred_size();
1648 if (eMode == VclSizeGroupMode::Both || eMode == VclSizeGroupMode::Horizontal)
1649 aRet.setWidth( std::max(aRet.Width(), aOtherSize.Width()) );
1650 if (eMode == VclSizeGroupMode::Both || eMode == VclSizeGroupMode::Vertical)
1651 aRet.setHeight( std::max(aRet.Height(), aOtherSize.Height()) );
1652 }
1653 }
1654 }
1655
1656 return aRet;
1657 }
1658
get_halign() const1659 VclAlign Window::get_halign() const
1660 {
1661 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1662 return pWindowImpl->meHalign;
1663 }
1664
set_halign(VclAlign eAlign)1665 void Window::set_halign(VclAlign eAlign)
1666 {
1667 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1668 pWindowImpl->meHalign = eAlign;
1669 }
1670
get_valign() const1671 VclAlign Window::get_valign() const
1672 {
1673 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1674 return pWindowImpl->meValign;
1675 }
1676
set_valign(VclAlign eAlign)1677 void Window::set_valign(VclAlign eAlign)
1678 {
1679 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1680 pWindowImpl->meValign = eAlign;
1681 }
1682
get_hexpand() const1683 bool Window::get_hexpand() const
1684 {
1685 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1686 return pWindowImpl->mbHexpand;
1687 }
1688
set_hexpand(bool bExpand)1689 void Window::set_hexpand(bool bExpand)
1690 {
1691 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1692 pWindowImpl->mbHexpand = bExpand;
1693 }
1694
get_vexpand() const1695 bool Window::get_vexpand() const
1696 {
1697 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1698 return pWindowImpl->mbVexpand;
1699 }
1700
set_vexpand(bool bExpand)1701 void Window::set_vexpand(bool bExpand)
1702 {
1703 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1704 pWindowImpl->mbVexpand = bExpand;
1705 }
1706
get_expand() const1707 bool Window::get_expand() const
1708 {
1709 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1710 return pWindowImpl->mbExpand;
1711 }
1712
set_expand(bool bExpand)1713 void Window::set_expand(bool bExpand)
1714 {
1715 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1716 pWindowImpl->mbExpand = bExpand;
1717 }
1718
get_pack_type() const1719 VclPackType Window::get_pack_type() const
1720 {
1721 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1722 return pWindowImpl->mePackType;
1723 }
1724
set_pack_type(VclPackType ePackType)1725 void Window::set_pack_type(VclPackType ePackType)
1726 {
1727 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1728 pWindowImpl->mePackType = ePackType;
1729 }
1730
get_padding() const1731 sal_Int32 Window::get_padding() const
1732 {
1733 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1734 return pWindowImpl->mnPadding;
1735 }
1736
set_padding(sal_Int32 nPadding)1737 void Window::set_padding(sal_Int32 nPadding)
1738 {
1739 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1740 pWindowImpl->mnPadding = nPadding;
1741 }
1742
get_fill() const1743 bool Window::get_fill() const
1744 {
1745 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1746 return pWindowImpl->mbFill;
1747 }
1748
set_fill(bool bFill)1749 void Window::set_fill(bool bFill)
1750 {
1751 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1752 pWindowImpl->mbFill = bFill;
1753 }
1754
get_grid_width() const1755 sal_Int32 Window::get_grid_width() const
1756 {
1757 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1758 return pWindowImpl->mnGridWidth;
1759 }
1760
set_grid_width(sal_Int32 nCols)1761 void Window::set_grid_width(sal_Int32 nCols)
1762 {
1763 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1764 pWindowImpl->mnGridWidth = nCols;
1765 }
1766
get_grid_left_attach() const1767 sal_Int32 Window::get_grid_left_attach() const
1768 {
1769 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1770 return pWindowImpl->mnGridLeftAttach;
1771 }
1772
set_grid_left_attach(sal_Int32 nAttach)1773 void Window::set_grid_left_attach(sal_Int32 nAttach)
1774 {
1775 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1776 pWindowImpl->mnGridLeftAttach = nAttach;
1777 }
1778
get_grid_height() const1779 sal_Int32 Window::get_grid_height() const
1780 {
1781 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1782 return pWindowImpl->mnGridHeight;
1783 }
1784
set_grid_height(sal_Int32 nRows)1785 void Window::set_grid_height(sal_Int32 nRows)
1786 {
1787 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1788 pWindowImpl->mnGridHeight = nRows;
1789 }
1790
get_grid_top_attach() const1791 sal_Int32 Window::get_grid_top_attach() const
1792 {
1793 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1794 return pWindowImpl->mnGridTopAttach;
1795 }
1796
set_grid_top_attach(sal_Int32 nAttach)1797 void Window::set_grid_top_attach(sal_Int32 nAttach)
1798 {
1799 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1800 pWindowImpl->mnGridTopAttach = nAttach;
1801 }
1802
set_border_width(sal_Int32 nBorderWidth)1803 void Window::set_border_width(sal_Int32 nBorderWidth)
1804 {
1805 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1806 pWindowImpl->mnBorderWidth = nBorderWidth;
1807 }
1808
get_border_width() const1809 sal_Int32 Window::get_border_width() const
1810 {
1811 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1812 return pWindowImpl->mnBorderWidth;
1813 }
1814
set_margin_left(sal_Int32 nWidth)1815 void Window::set_margin_left(sal_Int32 nWidth)
1816 {
1817 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1818 if (pWindowImpl->mnMarginLeft != nWidth)
1819 {
1820 pWindowImpl->mnMarginLeft = nWidth;
1821 queue_resize();
1822 }
1823 }
1824
get_margin_left() const1825 sal_Int32 Window::get_margin_left() const
1826 {
1827 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1828 return pWindowImpl->mnMarginLeft;
1829 }
1830
set_margin_right(sal_Int32 nWidth)1831 void Window::set_margin_right(sal_Int32 nWidth)
1832 {
1833 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1834 if (pWindowImpl->mnMarginRight != nWidth)
1835 {
1836 pWindowImpl->mnMarginRight = nWidth;
1837 queue_resize();
1838 }
1839 }
1840
get_margin_right() const1841 sal_Int32 Window::get_margin_right() const
1842 {
1843 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1844 return pWindowImpl->mnMarginRight;
1845 }
1846
set_margin_top(sal_Int32 nWidth)1847 void Window::set_margin_top(sal_Int32 nWidth)
1848 {
1849 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1850 if (pWindowImpl->mnMarginTop != nWidth)
1851 {
1852 pWindowImpl->mnMarginTop = nWidth;
1853 queue_resize();
1854 }
1855 }
1856
get_margin_top() const1857 sal_Int32 Window::get_margin_top() const
1858 {
1859 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1860 return pWindowImpl->mnMarginTop;
1861 }
1862
set_margin_bottom(sal_Int32 nWidth)1863 void Window::set_margin_bottom(sal_Int32 nWidth)
1864 {
1865 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1866 if (pWindowImpl->mnMarginBottom != nWidth)
1867 {
1868 pWindowImpl->mnMarginBottom = nWidth;
1869 queue_resize();
1870 }
1871 }
1872
get_margin_bottom() const1873 sal_Int32 Window::get_margin_bottom() const
1874 {
1875 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1876 return pWindowImpl->mnMarginBottom;
1877 }
1878
get_height_request() const1879 sal_Int32 Window::get_height_request() const
1880 {
1881 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1882 return pWindowImpl->mnHeightRequest;
1883 }
1884
get_width_request() const1885 sal_Int32 Window::get_width_request() const
1886 {
1887 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1888 return pWindowImpl->mnWidthRequest;
1889 }
1890
get_secondary() const1891 bool Window::get_secondary() const
1892 {
1893 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1894 return pWindowImpl->mbSecondary;
1895 }
1896
set_secondary(bool bSecondary)1897 void Window::set_secondary(bool bSecondary)
1898 {
1899 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1900 pWindowImpl->mbSecondary = bSecondary;
1901 }
1902
get_non_homogeneous() const1903 bool Window::get_non_homogeneous() const
1904 {
1905 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1906 return pWindowImpl->mbNonHomogeneous;
1907 }
1908
set_non_homogeneous(bool bNonHomogeneous)1909 void Window::set_non_homogeneous(bool bNonHomogeneous)
1910 {
1911 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1912 pWindowImpl->mbNonHomogeneous = bNonHomogeneous;
1913 }
1914
add_to_size_group(const std::shared_ptr<VclSizeGroup> & xGroup)1915 void Window::add_to_size_group(const std::shared_ptr<VclSizeGroup>& xGroup)
1916 {
1917 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1918 //To-Do, multiple groups
1919 pWindowImpl->m_xSizeGroup = xGroup;
1920 pWindowImpl->m_xSizeGroup->insert(this);
1921 if (VclSizeGroupMode::NONE != pWindowImpl->m_xSizeGroup->get_mode())
1922 queue_resize();
1923 }
1924
remove_from_all_size_groups()1925 void Window::remove_from_all_size_groups()
1926 {
1927 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1928 //To-Do, multiple groups
1929 if (pWindowImpl->m_xSizeGroup)
1930 {
1931 if (VclSizeGroupMode::NONE != pWindowImpl->m_xSizeGroup->get_mode())
1932 queue_resize();
1933 pWindowImpl->m_xSizeGroup->erase(this);
1934 pWindowImpl->m_xSizeGroup.reset();
1935 }
1936 }
1937
add_mnemonic_label(FixedText * pLabel)1938 void Window::add_mnemonic_label(FixedText *pLabel)
1939 {
1940 std::vector<VclPtr<FixedText> >& v = mpWindowImpl->m_aMnemonicLabels;
1941 if (std::find(v.begin(), v.end(), VclPtr<FixedText>(pLabel)) != v.end())
1942 return;
1943 v.emplace_back(pLabel);
1944 pLabel->set_mnemonic_widget(this);
1945 }
1946
remove_mnemonic_label(FixedText * pLabel)1947 void Window::remove_mnemonic_label(FixedText *pLabel)
1948 {
1949 std::vector<VclPtr<FixedText> >& v = mpWindowImpl->m_aMnemonicLabels;
1950 auto aFind = std::find(v.begin(), v.end(), VclPtr<FixedText>(pLabel));
1951 if (aFind == v.end())
1952 return;
1953 v.erase(aFind);
1954 pLabel->set_mnemonic_widget(nullptr);
1955 }
1956
list_mnemonic_labels() const1957 const std::vector<VclPtr<FixedText> >& Window::list_mnemonic_labels() const
1958 {
1959 return mpWindowImpl->m_aMnemonicLabels;
1960 }
1961
1962 } /* namespace vcl */
1963
DrawFocusRect(vcl::RenderContext & rRenderContext,const tools::Rectangle & rRect)1964 void DrawFocusRect(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
1965 {
1966 const int nBorder = 1;
1967 rRenderContext.Invert(tools::Rectangle(Point(rRect.Left(), rRect.Top()), Size(rRect.GetWidth(), nBorder)), InvertFlags::N50);
1968 rRenderContext.Invert(tools::Rectangle(Point(rRect.Left(), rRect.Bottom()-nBorder+1), Size(rRect.GetWidth(), nBorder)), InvertFlags::N50);
1969 rRenderContext.Invert(tools::Rectangle(Point(rRect.Left(), rRect.Top()+nBorder), Size(nBorder, rRect.GetHeight()-(nBorder*2))), InvertFlags::N50);
1970 rRenderContext.Invert(tools::Rectangle(Point(rRect.Right()-nBorder+1, rRect.Top()+nBorder), Size(nBorder, rRect.GetHeight()-(nBorder*2))), InvertFlags::N50);
1971 }
1972
1973 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1974