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 
33 {
34 }
35 
37 {
38  assert( typeid( const ImplControlValue ) == typeid( *this ));
39  return new ImplControlValue( *this );
40 }
41 
43 {
44 }
45 
47 {
48  assert( typeid( const ScrollbarValue ) == typeid( *this ));
49  return new ScrollbarValue( *this );
50 }
51 
53 {
54 }
55 
57 {
58  assert( typeid( const SliderValue ) == typeid( *this ));
59  return new SliderValue( *this );
60 }
61 
63 
65 {
66  assert(typeid(const TabPaneValue) == typeid(*this));
67  return new TabPaneValue(*this);
68 }
69 
71 {
72 }
73 
75 {
76  assert( typeid( const TabitemValue ) == typeid( *this ));
77  return new TabitemValue( *this );
78 }
79 
81 {
82 }
83 
85 {
86  assert( typeid( const SpinbuttonValue ) == typeid( *this ));
87  return new SpinbuttonValue( *this );
88 }
89 
91 {
92 }
93 
95 {
96  assert( typeid( const ToolbarValue ) == typeid( *this ));
97  return new ToolbarValue( *this );
98 }
99 
101 {
102 }
103 
105 {
106  assert( typeid( const MenubarValue ) == typeid( *this ));
107  return new MenubarValue( *this );
108 }
109 
111 {
112 }
113 
115 {
116  assert( typeid( const MenupopupValue ) == typeid( *this ));
117  return new MenupopupValue( *this );
118 }
119 
121 {
122 }
123 
125 {
126  assert( typeid( const PushButtonValue ) == typeid( *this ));
127  return new PushButtonValue( *this );
128 }
129 
130 // These functions are mainly passthrough functions that allow access to
131 // the SalFrame behind a Window object for native widget rendering purposes.
132 
134 {
135  if( !CanEnableNativeWidget() )
136  return false;
137 
138  if ( !mpGraphics && !AcquireGraphics() )
139  return false;
141 
142  return mpGraphics->IsNativeControlSupported(nType, nPart);
143 }
144 
146  ControlPart nPart,
147  const tools::Rectangle& rControlRegion,
148  const Point& aPos,
149  bool& rIsInside ) const
150 {
151  if( !CanEnableNativeWidget() )
152  return false;
153 
154  if ( !mpGraphics && !AcquireGraphics() )
155  return false;
157 
158  Point aWinOffs( mnOutOffX, mnOutOffY );
159  tools::Rectangle screenRegion( rControlRegion );
160  screenRegion.Move( aWinOffs.X(), aWinOffs.Y());
161 
162  return mpGraphics->HitTestNativeScrollbar( nPart, screenRegion, Point( aPos.X() + mnOutOffX, aPos.Y() + mnOutOffY ),
163  rIsInside, *this );
164 }
165 
166 static std::unique_ptr< ImplControlValue > TransformControlValue( const ImplControlValue& rVal, const OutputDevice& rDev )
167 {
168  std::unique_ptr< ImplControlValue > aResult;
169  switch( rVal.getType() )
170  {
171  case ControlType::Slider:
172  {
173  const SliderValue* pSlVal = static_cast<const SliderValue*>(&rVal);
174  SliderValue* pNew = new SliderValue( *pSlVal );
175  aResult.reset( pNew );
176  pNew->maThumbRect = rDev.ImplLogicToDevicePixel( pSlVal->maThumbRect );
177  }
178  break;
180  {
181  const ScrollbarValue* pScVal = static_cast<const ScrollbarValue*>(&rVal);
182  ScrollbarValue* pNew = new ScrollbarValue( *pScVal );
183  aResult.reset( pNew );
184  pNew->maThumbRect = rDev.ImplLogicToDevicePixel( pScVal->maThumbRect );
185  pNew->maButton1Rect = rDev.ImplLogicToDevicePixel( pScVal->maButton1Rect );
186  pNew->maButton2Rect = rDev.ImplLogicToDevicePixel( pScVal->maButton2Rect );
187  }
188  break;
190  {
191  const SpinbuttonValue* pSpVal = static_cast<const SpinbuttonValue*>(&rVal);
192  SpinbuttonValue* pNew = new SpinbuttonValue( *pSpVal );
193  aResult.reset( pNew );
194  pNew->maUpperRect = rDev.ImplLogicToDevicePixel( pSpVal->maUpperRect );
195  pNew->maLowerRect = rDev.ImplLogicToDevicePixel( pSpVal->maLowerRect );
196  }
197  break;
199  {
200  const ToolbarValue* pTVal = static_cast<const ToolbarValue*>(&rVal);
201  ToolbarValue* pNew = new ToolbarValue( *pTVal );
202  aResult.reset( pNew );
203  pNew->maGripRect = rDev.ImplLogicToDevicePixel( pTVal->maGripRect );
204  }
205  break;
207  {
208  const TabPaneValue* pTIVal = static_cast<const TabPaneValue*>(&rVal);
209  TabPaneValue* pNew = new TabPaneValue(*pTIVal);
212  aResult.reset(pNew);
213  }
214  break;
216  {
217  const TabitemValue* pTIVal = static_cast<const TabitemValue*>(&rVal);
218  TabitemValue* pNew = new TabitemValue( *pTIVal );
219  pNew->maContentRect = rDev.ImplLogicToDevicePixel(pTIVal->maContentRect);
220  aResult.reset( pNew );
221  }
222  break;
224  {
225  const MenubarValue* pMVal = static_cast<const MenubarValue*>(&rVal);
226  MenubarValue* pNew = new MenubarValue( *pMVal );
227  aResult.reset( pNew );
228  }
229  break;
231  {
232  const PushButtonValue* pBVal = static_cast<const PushButtonValue*>(&rVal);
233  PushButtonValue* pNew = new PushButtonValue( *pBVal );
234  aResult.reset( pNew );
235  }
236  break;
238  aResult = std::make_unique<ImplControlValue>( rVal );
239  break;
241  {
242  const MenupopupValue* pMVal = static_cast<const MenupopupValue*>(&rVal);
243  MenupopupValue* pNew = new MenupopupValue( *pMVal );
244  pNew->maItemRect = rDev.ImplLogicToDevicePixel( pMVal->maItemRect );
245  aResult.reset( pNew );
246  }
247  break;
248  default:
249  std::abort();
250  break;
251  }
252  return aResult;
253 }
255  ControlPart nPart,
256  const tools::Rectangle& rControlRegion,
257  ControlState nState,
258  const ImplControlValue& aValue,
259  const OUString& aCaption,
260  const Color& rBackgroundColor )
261 {
263 
264  if( !CanEnableNativeWidget() )
265  return false;
266 
267  // make sure the current clip region is initialized correctly
268  if ( !mpGraphics && !AcquireGraphics() )
269  return false;
271 
272  if ( mbInitClipRegion )
273  InitClipRegion();
274  if ( mbOutputClipped )
275  return true;
276 
277  if ( mbInitLineColor )
278  InitLineColor();
279  if ( mbInitFillColor )
280  InitFillColor();
281 
282  // Convert the coordinates from relative to Window-absolute, so we draw
283  // in the correct place in platform code
284  std::unique_ptr< ImplControlValue > aScreenCtrlValue( TransformControlValue( aValue, *this ) );
285  tools::Rectangle screenRegion( ImplLogicToDevicePixel( rControlRegion ) );
286 
287  bool bRet = mpGraphics->DrawNativeControl(nType, nPart, screenRegion, nState, *aScreenCtrlValue, aCaption, *this, rBackgroundColor);
288 
289  return bRet;
290 }
291 
293  ControlPart nPart,
294  const tools::Rectangle& rControlRegion,
295  ControlState nState,
296  const ImplControlValue& aValue,
297  tools::Rectangle &rNativeBoundingRegion,
298  tools::Rectangle &rNativeContentRegion ) const
299 {
300  if( !CanEnableNativeWidget() )
301  return false;
302 
303  if ( !mpGraphics && !AcquireGraphics() )
304  return false;
306 
307  // Convert the coordinates from relative to Window-absolute, so we draw
308  // in the correct place in platform code
309  std::unique_ptr< ImplControlValue > aScreenCtrlValue( TransformControlValue( aValue, *this ) );
310  tools::Rectangle screenRegion( ImplLogicToDevicePixel( rControlRegion ) );
311 
312  bool bRet = mpGraphics->GetNativeControlRegion(nType, nPart, screenRegion, nState, *aScreenCtrlValue,
313  rNativeBoundingRegion,
314  rNativeContentRegion, *this );
315  if( bRet )
316  {
317  // transform back native regions
318  rNativeBoundingRegion = ImplDevicePixelToLogic( rNativeBoundingRegion );
319  rNativeContentRegion = ImplDevicePixelToLogic( rNativeContentRegion );
320  }
321 
322  return bRet;
323 }
324 
325 /* 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
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:366
tools::Rectangle maButton2Rect
tools::Long mnOutOffY
Output offset for device output in pixel (pseudo window offset within window system's frames) ...
Definition: outdev.hxx:330
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)
static std::unique_ptr< ImplControlValue > TransformControlValue(const ImplControlValue &rVal, const OutputDevice &rDev)
virtual ~TabitemValue() override
virtual ~MenupopupValue() override
SalGraphics * mpGraphics
Graphics context to draw on.
Definition: outdev.hxx:300
tools::Rectangle maItemRect
tools::Rectangle maContentRect
SAL_DLLPRIVATE void InitFillColor()
virtual ImplControlValue * clone() const
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:369
Some things multiple-inherit from VclAbstractDialog and OutputDevice, so we need to use virtual inher...
Definition: outdev.hxx:288
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...
virtual ~PushButtonValue() override
TabPaneValue(const tools::Rectangle &rTabHeaderRect, const tools::Rectangle &rSelectedTabRect)
bool mbInitClipRegion
Definition: outdev.hxx:373
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:370
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:376
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:328
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:502
virtual ~SpinbuttonValue() override
virtual MenupopupValue * clone() const override
tools::Rectangle maThumbRect
bool IsNativeControlSupported(ControlType, ControlPart)
Definition: salgdi.hxx:669
virtual ~ToolbarValue() override
virtual bool CanEnableNativeWidget() const
Determine if native widgets can be enabled.
Definition: outdev.hxx:1972