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
bool DrawNativeControl(ControlType nType, ControlPart nPart, const tools::Rectangle &rControlRegion, ControlState nState, const ImplControlValue &aValue, const OUString &aCaption, const OutputDevice &rOutDev, const Color &rBackgroundColor=COL_AUTO)
virtual MenubarValue * clone() const override
OutDevType GetOutDevType() const
Definition: outdev.hxx:523
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
virtual SliderValue * clone() const override
bool mbOutputClipped
Definition: outdev.hxx:378
tools::Rectangle maButton2Rect
tools::Long mnOutOffY
Output offset for device output in pixel (pseudo window offset within window system's frames) ...
Definition: outdev.hxx:342
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.
tools::Rectangle maUpperRect
SAL_DLLPRIVATE void InitLineColor()
MenupopupValue(tools::Long i_nGutterWidth, const tools::Rectangle &i_rItemRect)
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:3675
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:381
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)
bool GetNativeControlRegion(ControlType nType, ControlPart nPart, const tools::Rectangle &rControlRegion, ControlState nState, const ImplControlValue &aValue, tools::Rectangle &rNativeBoundingRegion, tools::Rectangle &rNativeContentRegion, const OutputDevice &rOutDev)
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
TabPaneValue(const tools::Rectangle &rTabHeaderRect, const tools::Rectangle &rSelectedTabRect)
bool mbInitClipRegion
Definition: outdev.hxx:385
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:382
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:406
bool HitTestNativeScrollbar(ControlPart nPart, const tools::Rectangle &rControlRegion, const Point &aPos, bool &rIsInside, const OutputDevice &rOutDev)
virtual TabitemValue * clone() const override
void Move(tools::Long nHorzMoveDelta, tools::Long nVertMoveDelta)
tools::Rectangle maGripRect
tools::Long mnOutOffX
Output offset for device output in pixel (pseudo window offset within window system's frames) ...
Definition: outdev.hxx:340
#define SAL_WARN(area, stream)
vcl::ExtOutDevData * GetExtOutDevData() const
Definition: outdev.hxx:533
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:507
virtual ~SpinbuttonValue() override
virtual MenupopupValue * clone() const override
tools::Rectangle maThumbRect
bool IsNativeControlSupported(ControlType, ControlPart)
Definition: salgdi.hxx:653
virtual ~ToolbarValue() override