LibreOffice Module vcl (master)  1
nativecontrols.cxx
Go to the documentation of this file.
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 <cassert>
21 
22 #include <vcl/outdev.hxx>
23 #include <vcl/virdev.hxx>
24 #include <vcl/window.hxx>
25 #include <sal/log.hxx>
26 
27 #include <vcl/salnativewidgets.hxx>
28 #include <vcl/pdfextoutdevdata.hxx>
29 
30 #include <salgdi.hxx>
31 
32 static bool EnableNativeWidget( const OutputDevice& i_rDevice )
33 {
34  const OutDevType eType( i_rDevice.GetOutDevType() );
35  switch ( eType )
36  {
37 
38  case OUTDEV_WINDOW:
39  {
40  const vcl::Window* pWindow = dynamic_cast< const vcl::Window* >( &i_rDevice );
41  if (pWindow)
42  {
43  return pWindow->IsNativeWidgetEnabled();
44  }
45  else
46  {
47  SAL_WARN ("vcl.gdi", "Could not cast i_rDevice to Window");
48  assert (pWindow);
49  return false;
50  }
51  }
52 
53  case OUTDEV_PDF:
54  [[fallthrough]];
55  case OUTDEV_VIRDEV:
56  {
57  const vcl::ExtOutDevData* pOutDevData( i_rDevice.GetExtOutDevData() );
58  const vcl::PDFExtOutDevData* pPDFData( dynamic_cast< const vcl::PDFExtOutDevData* >( pOutDevData ) );
59  return pPDFData == nullptr;
60  }
61 
62  default:
63  return false;
64  }
65 }
66 
68 {
69 }
70 
72 {
73  assert( typeid( const ImplControlValue ) == typeid( *this ));
74  return new ImplControlValue( *this );
75 }
76 
78 {
79 }
80 
82 {
83  assert( typeid( const ScrollbarValue ) == typeid( *this ));
84  return new ScrollbarValue( *this );
85 }
86 
88 {
89 }
90 
92 {
93  assert( typeid( const SliderValue ) == typeid( *this ));
94  return new SliderValue( *this );
95 }
96 
98 
100 {
101  assert(typeid(const TabPaneValue) == typeid(*this));
102  return new TabPaneValue(*this);
103 }
104 
106 {
107 }
108 
110 {
111  assert( typeid( const TabitemValue ) == typeid( *this ));
112  return new TabitemValue( *this );
113 }
114 
116 {
117 }
118 
120 {
121  assert( typeid( const SpinbuttonValue ) == typeid( *this ));
122  return new SpinbuttonValue( *this );
123 }
124 
126 {
127 }
128 
130 {
131  assert( typeid( const ToolbarValue ) == typeid( *this ));
132  return new ToolbarValue( *this );
133 }
134 
136 {
137 }
138 
140 {
141  assert( typeid( const MenubarValue ) == typeid( *this ));
142  return new MenubarValue( *this );
143 }
144 
146 {
147 }
148 
150 {
151  assert( typeid( const MenupopupValue ) == typeid( *this ));
152  return new MenupopupValue( *this );
153 }
154 
156 {
157 }
158 
160 {
161  assert( typeid( const PushButtonValue ) == typeid( *this ));
162  return new PushButtonValue( *this );
163 }
164 
165 // These functions are mainly passthrough functions that allow access to
166 // the SalFrame behind a Window object for native widget rendering purposes.
167 
169 {
170  if( !EnableNativeWidget( *this ) )
171  return false;
172 
173  if ( !mpGraphics && !AcquireGraphics() )
174  return false;
175 
176  return mpGraphics->IsNativeControlSupported(nType, nPart);
177 }
178 
180  ControlPart nPart,
181  const tools::Rectangle& rControlRegion,
182  const Point& aPos,
183  bool& rIsInside ) const
184 {
185  if( !EnableNativeWidget( *this ) )
186  return false;
187 
188  if ( !mpGraphics && !AcquireGraphics() )
189  return false;
190 
191  Point aWinOffs( mnOutOffX, mnOutOffY );
192  tools::Rectangle screenRegion( rControlRegion );
193  screenRegion.Move( aWinOffs.X(), aWinOffs.Y());
194 
195  return mpGraphics->HitTestNativeScrollbar( nPart, screenRegion, Point( aPos.X() + mnOutOffX, aPos.Y() + mnOutOffY ),
196  rIsInside, this );
197 }
198 
199 static std::shared_ptr< ImplControlValue > TransformControlValue( const ImplControlValue& rVal, const OutputDevice& rDev )
200 {
201  std::shared_ptr< ImplControlValue > aResult;
202  switch( rVal.getType() )
203  {
204  case ControlType::Slider:
205  {
206  const SliderValue* pSlVal = static_cast<const SliderValue*>(&rVal);
207  SliderValue* pNew = new SliderValue( *pSlVal );
208  aResult.reset( pNew );
209  pNew->maThumbRect = rDev.ImplLogicToDevicePixel( pSlVal->maThumbRect );
210  }
211  break;
213  {
214  const ScrollbarValue* pScVal = static_cast<const ScrollbarValue*>(&rVal);
215  ScrollbarValue* pNew = new ScrollbarValue( *pScVal );
216  aResult.reset( pNew );
217  pNew->maThumbRect = rDev.ImplLogicToDevicePixel( pScVal->maThumbRect );
218  pNew->maButton1Rect = rDev.ImplLogicToDevicePixel( pScVal->maButton1Rect );
219  pNew->maButton2Rect = rDev.ImplLogicToDevicePixel( pScVal->maButton2Rect );
220  }
221  break;
223  {
224  const SpinbuttonValue* pSpVal = static_cast<const SpinbuttonValue*>(&rVal);
225  SpinbuttonValue* pNew = new SpinbuttonValue( *pSpVal );
226  aResult.reset( pNew );
227  pNew->maUpperRect = rDev.ImplLogicToDevicePixel( pSpVal->maUpperRect );
228  pNew->maLowerRect = rDev.ImplLogicToDevicePixel( pSpVal->maLowerRect );
229  }
230  break;
232  {
233  const ToolbarValue* pTVal = static_cast<const ToolbarValue*>(&rVal);
234  ToolbarValue* pNew = new ToolbarValue( *pTVal );
235  aResult.reset( pNew );
236  pNew->maGripRect = rDev.ImplLogicToDevicePixel( pTVal->maGripRect );
237  }
238  break;
240  {
241  const TabPaneValue* pTIVal = static_cast<const TabPaneValue*>(&rVal);
242  TabPaneValue* pNew = new TabPaneValue(*pTIVal);
245  aResult.reset(pNew);
246  }
247  break;
249  {
250  const TabitemValue* pTIVal = static_cast<const TabitemValue*>(&rVal);
251  TabitemValue* pNew = new TabitemValue( *pTIVal );
252  pNew->maContentRect = rDev.ImplLogicToDevicePixel(pTIVal->maContentRect);
253  aResult.reset( pNew );
254  }
255  break;
257  {
258  const MenubarValue* pMVal = static_cast<const MenubarValue*>(&rVal);
259  MenubarValue* pNew = new MenubarValue( *pMVal );
260  aResult.reset( pNew );
261  }
262  break;
264  {
265  const PushButtonValue* pBVal = static_cast<const PushButtonValue*>(&rVal);
266  PushButtonValue* pNew = new PushButtonValue( *pBVal );
267  aResult.reset( pNew );
268  }
269  break;
271  aResult.reset( new ImplControlValue( rVal ) );
272  break;
274  {
275  const MenupopupValue* pMVal = static_cast<const MenupopupValue*>(&rVal);
276  MenupopupValue* pNew = new MenupopupValue( *pMVal );
277  pNew->maItemRect = rDev.ImplLogicToDevicePixel( pMVal->maItemRect );
278  aResult.reset( pNew );
279  }
280  break;
281  default:
282  std::abort();
283  break;
284  }
285  return aResult;
286 }
288  ControlPart nPart,
289  const tools::Rectangle& rControlRegion,
290  ControlState nState,
291  const ImplControlValue& aValue,
292  const OUString& aCaption )
293 {
294  assert(!is_double_buffered_window());
295 
296  if( !EnableNativeWidget( *this ) )
297  return false;
298 
299  // make sure the current clip region is initialized correctly
300  if ( !mpGraphics && !AcquireGraphics() )
301  return false;
302 
303  if ( mbInitClipRegion )
304  InitClipRegion();
305  if ( mbOutputClipped )
306  return true;
307 
308  if ( mbInitLineColor )
309  InitLineColor();
310  if ( mbInitFillColor )
311  InitFillColor();
312 
313  // Convert the coordinates from relative to Window-absolute, so we draw
314  // in the correct place in platform code
315  std::shared_ptr< ImplControlValue > aScreenCtrlValue( TransformControlValue( aValue, *this ) );
316  tools::Rectangle screenRegion( ImplLogicToDevicePixel( rControlRegion ) );
317 
318  vcl::Region aTestRegion( GetActiveClipRegion() );
319  aTestRegion.Intersect( rControlRegion );
320  if (aTestRegion == vcl::Region(rControlRegion))
321  nState |= ControlState::CACHING_ALLOWED; // control is not clipped, caching allowed
322 
323  if (dynamic_cast<VirtualDevice*>(this))
325 
326  bool bRet = mpGraphics->DrawNativeControl(nType, nPart, screenRegion, nState, *aScreenCtrlValue, aCaption, this );
327 
328  return bRet;
329 }
330 
332  ControlPart nPart,
333  const tools::Rectangle& rControlRegion,
334  ControlState nState,
335  const ImplControlValue& aValue,
336  tools::Rectangle &rNativeBoundingRegion,
337  tools::Rectangle &rNativeContentRegion ) const
338 {
339  if( !EnableNativeWidget( *this ) )
340  return false;
341 
342  if ( !mpGraphics && !AcquireGraphics() )
343  return false;
344 
345  // Convert the coordinates from relative to Window-absolute, so we draw
346  // in the correct place in platform code
347  std::shared_ptr< ImplControlValue > aScreenCtrlValue( TransformControlValue( aValue, *this ) );
348  tools::Rectangle screenRegion( ImplLogicToDevicePixel( rControlRegion ) );
349 
350  bool bRet = mpGraphics->GetNativeControlRegion(nType, nPart, screenRegion, nState, *aScreenCtrlValue,
351  rNativeBoundingRegion,
352  rNativeContentRegion, this );
353  if( bRet )
354  {
355  // transform back native regions
356  rNativeBoundingRegion = ImplDevicePixelToLogic( rNativeBoundingRegion );
357  rNativeContentRegion = ImplDevicePixelToLogic( rNativeContentRegion );
358  }
359 
360  return bRet;
361 }
362 
363 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual ~ScrollbarValue() override
tools::Rectangle m_aTabHeaderRect
virtual MenubarValue * clone() const override
OutDevType GetOutDevType() const
Definition: outdev.hxx:522
long mnOutOffX
Output offset for device output in pixel (pseudo window offset within window system's frames) ...
Definition: outdev.hxx:342
TabPaneValue * clone() const override
bool DrawNativeControl(ControlType nType, ControlPart nPart, const tools::Rectangle &rControlRegion, ControlState nState, const ImplControlValue &aValue, const OUString &aCaption)
Request rendering of a particular control and/or part.
bool GetNativeControlRegion(ControlType nType, ControlPart nPart, const tools::Rectangle &rControlRegion, ControlState nState, const ImplControlValue &aValue, tools::Rectangle &rNativeBoundingRegion, tools::Rectangle &rNativeContentRegion) const
Query the native control's actual drawing region (including adornment)
ControlType getType() const
long mnOutOffY
Output offset for device output in pixel (pseudo window offset within window system's frames) ...
Definition: outdev.hxx:344
virtual SliderValue * clone() const override
bool mbOutputClipped
Definition: outdev.hxx:381
tools::Rectangle maButton2Rect
SAL_DLLPRIVATE bool is_double_buffered_window() const
tools::Rectangle maLowerRect
bool IsNativeControlSupported(ControlType nType, ControlPart nPart) const
Query the platform layer for control support.
void Move(long nHorzMoveDelta, long nVertMoveDelta)
tools::Rectangle maUpperRect
SAL_DLLPRIVATE void InitLineColor()
Set when the control is painted using double-buffering via VirtualDevice.
virtual ~TabitemValue() override
virtual ~MenupopupValue() override
SalGraphics * mpGraphics
Graphics context to draw on.
Definition: outdev.hxx:316
tools::Rectangle maItemRect
tools::Rectangle maContentRect
Set when the control is completely visible (i.e. not clipped).
SAL_DLLPRIVATE void InitFillColor()
virtual ImplControlValue * clone() const
OutDevType
Definition: outdev.hxx:278
bool IsNativeWidgetEnabled() const
Definition: window.cxx:3568
tools::Rectangle maButton1Rect
virtual bool AcquireGraphics() const =0
Acquire a graphics device that the output device uses to draw on.
bool mbInitLineColor
Definition: outdev.hxx:384
static std::shared_ptr< ImplControlValue > TransformControlValue(const ImplControlValue &rVal, const OutputDevice &rDev)
Some things multiple-inherit from VclAbstractDialog and OutputDevice, so we need to use virtual inher...
Definition: outdev.hxx:304
virtual ~ImplControlValue()
void Intersect(const tools::Rectangle &rRegion)
Definition: region.cxx:584
bool DrawNativeControl(ControlType nType, ControlPart nPart, const tools::Rectangle &rControlRegion, ControlState nState, const ImplControlValue &aValue, const OUString &aCaption, const OutputDevice *pOutDev)
virtual SpinbuttonValue * clone() const override
bool HitTestNativeScrollbar(ControlPart nPart, const tools::Rectangle &rControlRegion, const Point &aPos, bool &rIsInside) const
Query the native control to determine if it was acted upon.
tools::Rectangle m_aSelectedTabRect
DocumentType const eType
long X() const
tools::Rectangle maThumbRect
TabitemValue(const tools::Rectangle &rContentRect)
ControlType
These types are all based on the supported variants vcl/salnativewidgets.hxx and must be kept in-sync...
static bool EnableNativeWidget(const OutputDevice &i_rDevice)
virtual ~PushButtonValue() override
bool HitTestNativeScrollbar(ControlPart nPart, const tools::Rectangle &rControlRegion, const Point &aPos, bool &rIsInside, const OutputDevice *pOutDev)
TabPaneValue(const tools::Rectangle &rTabHeaderRect, const tools::Rectangle &rSelectedTabRect)
bool GetNativeControlRegion(ControlType nType, ControlPart nPart, const tools::Rectangle &rControlRegion, ControlState nState, const ImplControlValue &aValue, tools::Rectangle &rNativeBoundingRegion, tools::Rectangle &rNativeContentRegion, const OutputDevice *pOutDev)
virtual vcl::Region GetActiveClipRegion() const
bool mbInitClipRegion
Definition: outdev.hxx:388
virtual ToolbarValue * clone() const override
virtual PushButtonValue * clone() const override
virtual ScrollbarValue * clone() const override
virtual ~MenubarValue() override
virtual void InitClipRegion()
static int m_nOverlap
virtual ~SliderValue() override
bool mbInitFillColor
Definition: outdev.hxx:385
SAL_DLLPRIVATE tools::Rectangle ImplLogicToDevicePixel(const tools::Rectangle &rLogicRect) const
Convert a logical rectangle to a rectangle in physical device pixel units.
Definition: map.cxx:504
virtual TabitemValue * clone() const override
tools::Rectangle maGripRect
#define SAL_WARN(area, stream)
vcl::ExtOutDevData * GetExtOutDevData() const
Definition: outdev.hxx:532
SAL_DLLPRIVATE tools::Rectangle ImplDevicePixelToLogic(const tools::Rectangle &rPixelRect) const
Convert a rectangle in physical pixel units to a rectangle in physical pixel units and coords...
Definition: map.cxx:612
MenupopupValue(long i_nGutterWidth, const tools::Rectangle &i_rItemRect)
virtual ~SpinbuttonValue() override
virtual MenupopupValue * clone() const override
tools::Rectangle maThumbRect
bool IsNativeControlSupported(ControlType, ControlPart)
Definition: salgdi.hxx:612
long Y() const
virtual ~ToolbarValue() override