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 = std::make_shared<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  const Color& rBackgroundColor )
294 {
296 
297  if( !EnableNativeWidget( *this ) )
298  return false;
299 
300  // make sure the current clip region is initialized correctly
301  if ( !mpGraphics && !AcquireGraphics() )
302  return false;
303 
304  if ( mbInitClipRegion )
305  InitClipRegion();
306  if ( mbOutputClipped )
307  return true;
308 
309  if ( mbInitLineColor )
310  InitLineColor();
311  if ( mbInitFillColor )
312  InitFillColor();
313 
314  // Convert the coordinates from relative to Window-absolute, so we draw
315  // in the correct place in platform code
316  std::shared_ptr< ImplControlValue > aScreenCtrlValue( TransformControlValue( aValue, *this ) );
317  tools::Rectangle screenRegion( ImplLogicToDevicePixel( rControlRegion ) );
318 
319  bool bRet = mpGraphics->DrawNativeControl(nType, nPart, screenRegion, nState, *aScreenCtrlValue, aCaption, this, rBackgroundColor );
320 
321  return bRet;
322 }
323 
325  ControlPart nPart,
326  const tools::Rectangle& rControlRegion,
327  ControlState nState,
328  const ImplControlValue& aValue,
329  tools::Rectangle &rNativeBoundingRegion,
330  tools::Rectangle &rNativeContentRegion ) const
331 {
332  if( !EnableNativeWidget( *this ) )
333  return false;
334 
335  if ( !mpGraphics && !AcquireGraphics() )
336  return false;
337 
338  // Convert the coordinates from relative to Window-absolute, so we draw
339  // in the correct place in platform code
340  std::shared_ptr< ImplControlValue > aScreenCtrlValue( TransformControlValue( aValue, *this ) );
341  tools::Rectangle screenRegion( ImplLogicToDevicePixel( rControlRegion ) );
342 
343  bool bRet = mpGraphics->GetNativeControlRegion(nType, nPart, screenRegion, nState, *aScreenCtrlValue,
344  rNativeBoundingRegion,
345  rNativeContentRegion, this );
346  if( bRet )
347  {
348  // transform back native regions
349  rNativeBoundingRegion = ImplDevicePixelToLogic( rNativeBoundingRegion );
350  rNativeContentRegion = ImplDevicePixelToLogic( rNativeContentRegion );
351  }
352 
353  return bRet;
354 }
355 
356 /* 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:524
long mnOutOffX
Output offset for device output in pixel (pseudo window offset within window system's frames) ...
Definition: outdev.hxx:340
TabPaneValue * clone() const override
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:342
virtual SliderValue * clone() const override
bool mbOutputClipped
Definition: outdev.hxx:379
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
bool DrawNativeControl(ControlType nType, ControlPart nPart, const tools::Rectangle &rControlRegion, ControlState nState, const ImplControlValue &aValue, const OUString &aCaption, const OutputDevice *pOutDev, const Color &rBackgroundColor=COL_AUTO)
SAL_DLLPRIVATE void InitLineColor()
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
virtual ~TabitemValue() override
virtual ~MenupopupValue() override
SalGraphics * mpGraphics
Graphics context to draw on.
Definition: outdev.hxx:314
DocumentType eType
tools::Rectangle maItemRect
tools::Rectangle maContentRect
SAL_DLLPRIVATE void InitFillColor()
virtual ImplControlValue * clone() const
OutDevType
Definition: outdev.hxx:276
bool IsNativeWidgetEnabled() const
Definition: window.cxx:3679
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:382
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:302
virtual ~ImplControlValue()
virtual SpinbuttonValue * clone() const override
bool DrawNativeControl(ControlType nType, ControlPart nPart, const tools::Rectangle &rControlRegion, ControlState nState, const ImplControlValue &aValue, const OUString &aCaption, const Color &rBackgroundColor=COL_AUTO)
Request rendering of a particular control and/or part.
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
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)
bool mbInitClipRegion
Definition: outdev.hxx:386
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:383
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:534
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:611
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:641
virtual ~ToolbarValue() override