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;
140 
141  return mpGraphics->IsNativeControlSupported(nType, nPart);
142 }
143 
145  ControlPart nPart,
146  const tools::Rectangle& rControlRegion,
147  const Point& aPos,
148  bool& rIsInside ) const
149 {
150  if( !CanEnableNativeWidget() )
151  return false;
152 
153  if ( !mpGraphics && !AcquireGraphics() )
154  return false;
155 
156  Point aWinOffs( mnOutOffX, mnOutOffY );
157  tools::Rectangle screenRegion( rControlRegion );
158  screenRegion.Move( aWinOffs.X(), aWinOffs.Y());
159 
160  return mpGraphics->HitTestNativeScrollbar( nPart, screenRegion, Point( aPos.X() + mnOutOffX, aPos.Y() + mnOutOffY ),
161  rIsInside, *this );
162 }
163 
164 static std::shared_ptr< ImplControlValue > TransformControlValue( const ImplControlValue& rVal, const OutputDevice& rDev )
165 {
166  std::shared_ptr< ImplControlValue > aResult;
167  switch( rVal.getType() )
168  {
169  case ControlType::Slider:
170  {
171  const SliderValue* pSlVal = static_cast<const SliderValue*>(&rVal);
172  SliderValue* pNew = new SliderValue( *pSlVal );
173  aResult.reset( pNew );
174  pNew->maThumbRect = rDev.ImplLogicToDevicePixel( pSlVal->maThumbRect );
175  }
176  break;
178  {
179  const ScrollbarValue* pScVal = static_cast<const ScrollbarValue*>(&rVal);
180  ScrollbarValue* pNew = new ScrollbarValue( *pScVal );
181  aResult.reset( pNew );
182  pNew->maThumbRect = rDev.ImplLogicToDevicePixel( pScVal->maThumbRect );
183  pNew->maButton1Rect = rDev.ImplLogicToDevicePixel( pScVal->maButton1Rect );
184  pNew->maButton2Rect = rDev.ImplLogicToDevicePixel( pScVal->maButton2Rect );
185  }
186  break;
188  {
189  const SpinbuttonValue* pSpVal = static_cast<const SpinbuttonValue*>(&rVal);
190  SpinbuttonValue* pNew = new SpinbuttonValue( *pSpVal );
191  aResult.reset( pNew );
192  pNew->maUpperRect = rDev.ImplLogicToDevicePixel( pSpVal->maUpperRect );
193  pNew->maLowerRect = rDev.ImplLogicToDevicePixel( pSpVal->maLowerRect );
194  }
195  break;
197  {
198  const ToolbarValue* pTVal = static_cast<const ToolbarValue*>(&rVal);
199  ToolbarValue* pNew = new ToolbarValue( *pTVal );
200  aResult.reset( pNew );
201  pNew->maGripRect = rDev.ImplLogicToDevicePixel( pTVal->maGripRect );
202  }
203  break;
205  {
206  const TabPaneValue* pTIVal = static_cast<const TabPaneValue*>(&rVal);
207  TabPaneValue* pNew = new TabPaneValue(*pTIVal);
210  aResult.reset(pNew);
211  }
212  break;
214  {
215  const TabitemValue* pTIVal = static_cast<const TabitemValue*>(&rVal);
216  TabitemValue* pNew = new TabitemValue( *pTIVal );
217  pNew->maContentRect = rDev.ImplLogicToDevicePixel(pTIVal->maContentRect);
218  aResult.reset( pNew );
219  }
220  break;
222  {
223  const MenubarValue* pMVal = static_cast<const MenubarValue*>(&rVal);
224  MenubarValue* pNew = new MenubarValue( *pMVal );
225  aResult.reset( pNew );
226  }
227  break;
229  {
230  const PushButtonValue* pBVal = static_cast<const PushButtonValue*>(&rVal);
231  PushButtonValue* pNew = new PushButtonValue( *pBVal );
232  aResult.reset( pNew );
233  }
234  break;
236  aResult = std::make_shared<ImplControlValue>( rVal );
237  break;
239  {
240  const MenupopupValue* pMVal = static_cast<const MenupopupValue*>(&rVal);
241  MenupopupValue* pNew = new MenupopupValue( *pMVal );
242  pNew->maItemRect = rDev.ImplLogicToDevicePixel( pMVal->maItemRect );
243  aResult.reset( pNew );
244  }
245  break;
246  default:
247  std::abort();
248  break;
249  }
250  return aResult;
251 }
253  ControlPart nPart,
254  const tools::Rectangle& rControlRegion,
255  ControlState nState,
256  const ImplControlValue& aValue,
257  const OUString& aCaption,
258  const Color& rBackgroundColor )
259 {
261 
262  if( !CanEnableNativeWidget() )
263  return false;
264 
265  // make sure the current clip region is initialized correctly
266  if ( !mpGraphics && !AcquireGraphics() )
267  return false;
268 
269  if ( mbInitClipRegion )
270  InitClipRegion();
271  if ( mbOutputClipped )
272  return true;
273 
274  if ( mbInitLineColor )
275  InitLineColor();
276  if ( mbInitFillColor )
277  InitFillColor();
278 
279  // Convert the coordinates from relative to Window-absolute, so we draw
280  // in the correct place in platform code
281  std::shared_ptr< ImplControlValue > aScreenCtrlValue( TransformControlValue( aValue, *this ) );
282  tools::Rectangle screenRegion( ImplLogicToDevicePixel( rControlRegion ) );
283 
284  bool bRet = mpGraphics->DrawNativeControl(nType, nPart, screenRegion, nState, *aScreenCtrlValue, aCaption, *this, rBackgroundColor);
285 
286  return bRet;
287 }
288 
290  ControlPart nPart,
291  const tools::Rectangle& rControlRegion,
292  ControlState nState,
293  const ImplControlValue& aValue,
294  tools::Rectangle &rNativeBoundingRegion,
295  tools::Rectangle &rNativeContentRegion ) const
296 {
297  if( !CanEnableNativeWidget() )
298  return false;
299 
300  if ( !mpGraphics && !AcquireGraphics() )
301  return false;
302 
303  // Convert the coordinates from relative to Window-absolute, so we draw
304  // in the correct place in platform code
305  std::shared_ptr< ImplControlValue > aScreenCtrlValue( TransformControlValue( aValue, *this ) );
306  tools::Rectangle screenRegion( ImplLogicToDevicePixel( rControlRegion ) );
307 
308  bool bRet = mpGraphics->GetNativeControlRegion(nType, nPart, screenRegion, nState, *aScreenCtrlValue,
309  rNativeBoundingRegion,
310  rNativeContentRegion, *this );
311  if( bRet )
312  {
313  // transform back native regions
314  rNativeBoundingRegion = ImplDevicePixelToLogic( rNativeBoundingRegion );
315  rNativeContentRegion = ImplDevicePixelToLogic( rNativeContentRegion );
316  }
317 
318  return bRet;
319 }
320 
321 /* 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:379
tools::Rectangle maButton2Rect
tools::Long mnOutOffY
Output offset for device output in pixel (pseudo window offset within window system's frames) ...
Definition: outdev.hxx:343
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:315
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: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:303
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: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: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:341
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:477
virtual ~SpinbuttonValue() override
virtual MenupopupValue * clone() const override
tools::Rectangle maThumbRect
bool IsNativeControlSupported(ControlType, ControlPart)
Definition: salgdi.hxx:658
virtual ~ToolbarValue() override
virtual bool CanEnableNativeWidget() const
Determine if native widgets can be enabled.
Definition: outdev.hxx:1975