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 #include <toolbarvalue.hxx>
27 
28 #include <vcl/salnativewidgets.hxx>
29 #include <vcl/pdfextoutdevdata.hxx>
30 
31 #include <salgdi.hxx>
32 
34 {
35 }
36 
38 {
39  assert( typeid( const ImplControlValue ) == typeid( *this ));
40  return new ImplControlValue( *this );
41 }
42 
44 {
45 }
46 
48 {
49  assert( typeid( const ScrollbarValue ) == typeid( *this ));
50  return new ScrollbarValue( *this );
51 }
52 
54 {
55 }
56 
58 {
59  assert( typeid( const SliderValue ) == typeid( *this ));
60  return new SliderValue( *this );
61 }
62 
64 
66 {
67  assert(typeid(const TabPaneValue) == typeid(*this));
68  return new TabPaneValue(*this);
69 }
70 
72 {
73 }
74 
76 {
77  assert( typeid( const TabitemValue ) == typeid( *this ));
78  return new TabitemValue( *this );
79 }
80 
82 {
83 }
84 
86 {
87  assert( typeid( const SpinbuttonValue ) == typeid( *this ));
88  return new SpinbuttonValue( *this );
89 }
90 
92 {
93 }
94 
96 {
97  assert( typeid( const ToolbarValue ) == typeid( *this ));
98  return new ToolbarValue( *this );
99 }
100 
102 {
103 }
104 
106 {
107  assert( typeid( const MenubarValue ) == typeid( *this ));
108  return new MenubarValue( *this );
109 }
110 
112 {
113 }
114 
116 {
117  assert( typeid( const MenupopupValue ) == typeid( *this ));
118  return new MenupopupValue( *this );
119 }
120 
122 {
123 }
124 
126 {
127  assert( typeid( const PushButtonValue ) == typeid( *this ));
128  return new PushButtonValue( *this );
129 }
130 
131 // These functions are mainly passthrough functions that allow access to
132 // the SalFrame behind a Window object for native widget rendering purposes.
133 
135 {
136  if( !CanEnableNativeWidget() )
137  return false;
138 
139  if ( !mpGraphics && !AcquireGraphics() )
140  return false;
141  assert(mpGraphics);
142 
143  return mpGraphics->IsNativeControlSupported(nType, nPart);
144 }
145 
147  ControlPart nPart,
148  const tools::Rectangle& rControlRegion,
149  const Point& aPos,
150  bool& rIsInside ) const
151 {
152  if( !CanEnableNativeWidget() )
153  return false;
154 
155  if ( !mpGraphics && !AcquireGraphics() )
156  return false;
157  assert(mpGraphics);
158 
159  Point aWinOffs( mnOutOffX, mnOutOffY );
160  tools::Rectangle screenRegion( rControlRegion );
161  screenRegion.Move( aWinOffs.X(), aWinOffs.Y());
162 
163  return mpGraphics->HitTestNativeScrollbar( nPart, screenRegion, Point( aPos.X() + mnOutOffX, aPos.Y() + mnOutOffY ),
164  rIsInside, *this );
165 }
166 
167 static std::unique_ptr< ImplControlValue > TransformControlValue( const ImplControlValue& rVal, const OutputDevice& rDev )
168 {
169  std::unique_ptr< ImplControlValue > aResult;
170  switch( rVal.getType() )
171  {
172  case ControlType::Slider:
173  {
174  const SliderValue* pSlVal = static_cast<const SliderValue*>(&rVal);
175  SliderValue* pNew = new SliderValue( *pSlVal );
176  aResult.reset( pNew );
177  pNew->maThumbRect = rDev.ImplLogicToDevicePixel( pSlVal->maThumbRect );
178  }
179  break;
181  {
182  const ScrollbarValue* pScVal = static_cast<const ScrollbarValue*>(&rVal);
183  ScrollbarValue* pNew = new ScrollbarValue( *pScVal );
184  aResult.reset( pNew );
185  pNew->maThumbRect = rDev.ImplLogicToDevicePixel( pScVal->maThumbRect );
186  pNew->maButton1Rect = rDev.ImplLogicToDevicePixel( pScVal->maButton1Rect );
187  pNew->maButton2Rect = rDev.ImplLogicToDevicePixel( pScVal->maButton2Rect );
188  }
189  break;
191  {
192  const SpinbuttonValue* pSpVal = static_cast<const SpinbuttonValue*>(&rVal);
193  SpinbuttonValue* pNew = new SpinbuttonValue( *pSpVal );
194  aResult.reset( pNew );
195  pNew->maUpperRect = rDev.ImplLogicToDevicePixel( pSpVal->maUpperRect );
196  pNew->maLowerRect = rDev.ImplLogicToDevicePixel( pSpVal->maLowerRect );
197  }
198  break;
200  {
201  const ToolbarValue* pTVal = static_cast<const ToolbarValue*>(&rVal);
202  ToolbarValue* pNew = new ToolbarValue( *pTVal );
203  aResult.reset( pNew );
204  pNew->maGripRect = rDev.ImplLogicToDevicePixel( pTVal->maGripRect );
205  }
206  break;
208  {
209  const TabPaneValue* pTIVal = static_cast<const TabPaneValue*>(&rVal);
210  TabPaneValue* pNew = new TabPaneValue(*pTIVal);
213  aResult.reset(pNew);
214  }
215  break;
217  {
218  const TabitemValue* pTIVal = static_cast<const TabitemValue*>(&rVal);
219  TabitemValue* pNew = new TabitemValue( *pTIVal );
220  pNew->maContentRect = rDev.ImplLogicToDevicePixel(pTIVal->maContentRect);
221  aResult.reset( pNew );
222  }
223  break;
225  {
226  const MenubarValue* pMVal = static_cast<const MenubarValue*>(&rVal);
227  MenubarValue* pNew = new MenubarValue( *pMVal );
228  aResult.reset( pNew );
229  }
230  break;
232  {
233  const PushButtonValue* pBVal = static_cast<const PushButtonValue*>(&rVal);
234  PushButtonValue* pNew = new PushButtonValue( *pBVal );
235  aResult.reset( pNew );
236  }
237  break;
239  aResult = std::make_unique<ImplControlValue>( rVal );
240  break;
242  {
243  const MenupopupValue* pMVal = static_cast<const MenupopupValue*>(&rVal);
244  MenupopupValue* pNew = new MenupopupValue( *pMVal );
245  pNew->maItemRect = rDev.ImplLogicToDevicePixel( pMVal->maItemRect );
246  aResult.reset( pNew );
247  }
248  break;
249  default:
250  std::abort();
251  break;
252  }
253  return aResult;
254 }
256  ControlPart nPart,
257  const tools::Rectangle& rControlRegion,
258  ControlState nState,
259  const ImplControlValue& aValue,
260  const OUString& aCaption,
261  const Color& rBackgroundColor )
262 {
263  assert(!is_double_buffered_window());
264 
265  if( !CanEnableNativeWidget() )
266  return false;
267 
268  // make sure the current clip region is initialized correctly
269  if ( !mpGraphics && !AcquireGraphics() )
270  return false;
271  assert(mpGraphics);
272 
273  if ( mbInitClipRegion )
274  InitClipRegion();
275  if ( mbOutputClipped )
276  return true;
277 
278  if ( mbInitLineColor )
279  InitLineColor();
280  if ( mbInitFillColor )
281  InitFillColor();
282 
283  // Convert the coordinates from relative to Window-absolute, so we draw
284  // in the correct place in platform code
285  std::unique_ptr< ImplControlValue > aScreenCtrlValue( TransformControlValue( aValue, *this ) );
286  tools::Rectangle screenRegion( ImplLogicToDevicePixel( rControlRegion ) );
287 
288  bool bRet = mpGraphics->DrawNativeControl(nType, nPart, screenRegion, nState, *aScreenCtrlValue, aCaption, *this, rBackgroundColor);
289 
290  return bRet;
291 }
292 
294  ControlPart nPart,
295  const tools::Rectangle& rControlRegion,
296  ControlState nState,
297  const ImplControlValue& aValue,
298  tools::Rectangle &rNativeBoundingRegion,
299  tools::Rectangle &rNativeContentRegion ) const
300 {
301  if( !CanEnableNativeWidget() )
302  return false;
303 
304  if ( !mpGraphics && !AcquireGraphics() )
305  return false;
306  assert(mpGraphics);
307 
308  // Convert the coordinates from relative to Window-absolute, so we draw
309  // in the correct place in platform code
310  std::unique_ptr< ImplControlValue > aScreenCtrlValue( TransformControlValue( aValue, *this ) );
311  tools::Rectangle screenRegion( ImplLogicToDevicePixel( rControlRegion ) );
312 
313  bool bRet = mpGraphics->GetNativeControlRegion(nType, nPart, screenRegion, nState, *aScreenCtrlValue,
314  rNativeBoundingRegion,
315  rNativeContentRegion, *this );
316  if( bRet )
317  {
318  // transform back native regions
319  rNativeBoundingRegion = ImplDevicePixelToLogic( rNativeBoundingRegion );
320  rNativeContentRegion = ImplDevicePixelToLogic( rNativeContentRegion );
321  }
322 
323  return bRet;
324 }
325 
326 /* 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:252
tools::Rectangle maButton2Rect
tools::Long mnOutOffY
Output offset for device output in pixel (pseudo window offset within window system's frames) ...
Definition: outdev.hxx:215
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()
Definition: line.cxx:84
MenupopupValue(tools::Long i_nGutterWidth, const tools::Rectangle &i_rItemRect)
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:188
tools::Rectangle maItemRect
tools::Rectangle maContentRect
SAL_DLLPRIVATE void InitFillColor()
Definition: fill.cxx:76
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:255
Some things multiple-inherit from VclAbstractDialog and OutputDevice, so we need to use virtual inher...
Definition: outdev.hxx:175
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:259
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:256
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:386
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:213
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:600
virtual ~SpinbuttonValue() override
virtual MenupopupValue * clone() const override
tools::Rectangle maThumbRect
bool IsNativeControlSupported(ControlType, ControlPart)
Definition: salgdi.hxx:695
virtual ~ToolbarValue() override
virtual bool CanEnableNativeWidget() const
Determine if native widgets can be enabled.
Definition: outdev.hxx:1866