Line data Source code
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 <vcl/outdev.hxx>
21 : #include <vcl/virdev.hxx>
22 : #include <vcl/window.hxx>
23 :
24 : #include <vcl/salnativewidgets.hxx>
25 : #include <vcl/pdfextoutdevdata.hxx>
26 :
27 : #include <salgdi.hxx>
28 :
29 971353 : static bool EnableNativeWidget( const OutputDevice& i_rDevice )
30 : {
31 971353 : const OutDevType eType( i_rDevice.GetOutDevType() );
32 971353 : switch ( eType )
33 : {
34 :
35 : case OUTDEV_WINDOW:
36 : {
37 971353 : const vcl::Window* pWindow = dynamic_cast< const vcl::Window* >( &i_rDevice );
38 971353 : if (pWindow)
39 : {
40 971353 : return pWindow->IsNativeWidgetEnabled();
41 : }
42 : else
43 : {
44 : SAL_WARN ("vcl.gdi", "Could not cast i_rDevice to Window");
45 : assert (pWindow);
46 0 : return false;
47 : }
48 : }
49 :
50 : case OUTDEV_VIRDEV:
51 : {
52 0 : const vcl::ExtOutDevData* pOutDevData( i_rDevice.GetExtOutDevData() );
53 0 : const vcl::PDFExtOutDevData* pPDFData( dynamic_cast< const vcl::PDFExtOutDevData* >( pOutDevData ) );
54 0 : if ( pPDFData != NULL )
55 0 : return false;
56 0 : return true;
57 : }
58 :
59 : default:
60 0 : return false;
61 : }
62 : }
63 :
64 606237 : ImplControlValue::~ImplControlValue()
65 : {
66 606237 : }
67 :
68 124 : ImplControlValue* ImplControlValue::clone() const
69 : {
70 : assert( typeid( const ImplControlValue ) == typeid( *this ));
71 124 : return new ImplControlValue( *this );
72 : }
73 :
74 87055 : ScrollbarValue::~ScrollbarValue()
75 : {
76 87055 : }
77 :
78 0 : ScrollbarValue* ScrollbarValue::clone() const
79 : {
80 : assert( typeid( const ScrollbarValue ) == typeid( *this ));
81 0 : return new ScrollbarValue( *this );
82 : }
83 :
84 0 : SliderValue::~SliderValue()
85 : {
86 0 : }
87 :
88 0 : SliderValue* SliderValue::clone() const
89 : {
90 : assert( typeid( const SliderValue ) == typeid( *this ));
91 0 : return new SliderValue( *this );
92 : }
93 :
94 8076 : TabitemValue::~TabitemValue()
95 : {
96 8076 : }
97 :
98 0 : TabitemValue* TabitemValue::clone() const
99 : {
100 : assert( typeid( const TabitemValue ) == typeid( *this ));
101 0 : return new TabitemValue( *this );
102 : }
103 :
104 697 : SpinbuttonValue::~SpinbuttonValue()
105 : {
106 697 : }
107 :
108 0 : SpinbuttonValue* SpinbuttonValue::clone() const
109 : {
110 : assert( typeid( const SpinbuttonValue ) == typeid( *this ));
111 0 : return new SpinbuttonValue( *this );
112 : }
113 :
114 0 : ToolbarValue::~ToolbarValue()
115 : {
116 0 : }
117 :
118 0 : ToolbarValue* ToolbarValue::clone() const
119 : {
120 : assert( typeid( const ToolbarValue ) == typeid( *this ));
121 0 : return new ToolbarValue( *this );
122 : }
123 :
124 0 : MenubarValue::~MenubarValue()
125 : {
126 0 : }
127 :
128 0 : MenubarValue* MenubarValue::clone() const
129 : {
130 : assert( typeid( const MenubarValue ) == typeid( *this ));
131 0 : return new MenubarValue( *this );
132 : }
133 :
134 0 : MenupopupValue::~MenupopupValue()
135 : {
136 0 : }
137 :
138 0 : MenupopupValue* MenupopupValue::clone() const
139 : {
140 : assert( typeid( const MenupopupValue ) == typeid( *this ));
141 0 : return new MenupopupValue( *this );
142 : }
143 :
144 0 : PushButtonValue::~PushButtonValue()
145 : {
146 0 : }
147 :
148 0 : PushButtonValue* PushButtonValue::clone() const
149 : {
150 : assert( typeid( const PushButtonValue ) == typeid( *this ));
151 0 : return new PushButtonValue( *this );
152 : }
153 :
154 : // These functions are mainly passthrough functions that allow access to
155 : // the SalFrame behind a Window object for native widget rendering purposes.
156 :
157 788521 : bool OutputDevice::IsNativeControlSupported( ControlType nType, ControlPart nPart ) const
158 : {
159 788521 : if( !EnableNativeWidget( *this ) )
160 33430 : return false;
161 :
162 755091 : if ( !mpGraphics )
163 77842 : if ( !AcquireGraphics() )
164 0 : return false;
165 :
166 755091 : return( mpGraphics->IsNativeControlSupported(nType, nPart) );
167 : }
168 :
169 0 : bool OutputDevice::HitTestNativeControl( ControlType nType,
170 : ControlPart nPart,
171 : const Rectangle& rControlRegion,
172 : const Point& aPos,
173 : bool& rIsInside ) const
174 : {
175 0 : if( !EnableNativeWidget( *this ) )
176 0 : return false;
177 :
178 0 : if ( !mpGraphics )
179 0 : if ( !AcquireGraphics() )
180 0 : return false;
181 :
182 0 : Point aWinOffs( mnOutOffX, mnOutOffY );
183 0 : Rectangle screenRegion( rControlRegion );
184 0 : screenRegion.Move( aWinOffs.X(), aWinOffs.Y());
185 :
186 0 : return( mpGraphics->HitTestNativeControl(nType, nPart, screenRegion, Point( aPos.X() + mnOutOffX, aPos.Y() + mnOutOffY ),
187 0 : rIsInside, this ) );
188 : }
189 :
190 180152 : static std::shared_ptr< ImplControlValue > TransformControlValue( const ImplControlValue& rVal, const OutputDevice& rDev )
191 : {
192 180152 : std::shared_ptr< ImplControlValue > aResult;
193 180152 : switch( rVal.getType() )
194 : {
195 : case CTRL_SLIDER:
196 : {
197 0 : const SliderValue* pSlVal = static_cast<const SliderValue*>(&rVal);
198 0 : SliderValue* pNew = new SliderValue( *pSlVal );
199 0 : aResult.reset( pNew );
200 0 : pNew->maThumbRect = rDev.ImplLogicToDevicePixel( pSlVal->maThumbRect );
201 : }
202 0 : break;
203 : case CTRL_SCROLLBAR:
204 : {
205 0 : const ScrollbarValue* pScVal = static_cast<const ScrollbarValue*>(&rVal);
206 0 : ScrollbarValue* pNew = new ScrollbarValue( *pScVal );
207 0 : aResult.reset( pNew );
208 0 : pNew->maThumbRect = rDev.ImplLogicToDevicePixel( pScVal->maThumbRect );
209 0 : pNew->maButton1Rect = rDev.ImplLogicToDevicePixel( pScVal->maButton1Rect );
210 0 : pNew->maButton2Rect = rDev.ImplLogicToDevicePixel( pScVal->maButton2Rect );
211 : }
212 0 : break;
213 : case CTRL_SPINBUTTONS:
214 : {
215 0 : const SpinbuttonValue* pSpVal = static_cast<const SpinbuttonValue*>(&rVal);
216 0 : SpinbuttonValue* pNew = new SpinbuttonValue( *pSpVal );
217 0 : aResult.reset( pNew );
218 0 : pNew->maUpperRect = rDev.ImplLogicToDevicePixel( pSpVal->maUpperRect );
219 0 : pNew->maLowerRect = rDev.ImplLogicToDevicePixel( pSpVal->maLowerRect );
220 : }
221 0 : break;
222 : case CTRL_TOOLBAR:
223 : {
224 0 : const ToolbarValue* pTVal = static_cast<const ToolbarValue*>(&rVal);
225 0 : ToolbarValue* pNew = new ToolbarValue( *pTVal );
226 0 : aResult.reset( pNew );
227 0 : pNew->maGripRect = rDev.ImplLogicToDevicePixel( pTVal->maGripRect );
228 : }
229 0 : break;
230 : case CTRL_TAB_ITEM:
231 : {
232 2692 : const TabitemValue* pTIVal = static_cast<const TabitemValue*>(&rVal);
233 2692 : TabitemValue* pNew = new TabitemValue( *pTIVal );
234 2692 : pNew->maContentRect = rDev.ImplLogicToDevicePixel(pTIVal->maContentRect);
235 2692 : aResult.reset( pNew );
236 : }
237 2692 : break;
238 : case CTRL_MENUBAR:
239 : {
240 0 : const MenubarValue* pMVal = static_cast<const MenubarValue*>(&rVal);
241 0 : MenubarValue* pNew = new MenubarValue( *pMVal );
242 0 : aResult.reset( pNew );
243 : }
244 0 : break;
245 : case CTRL_PUSHBUTTON:
246 : {
247 0 : const PushButtonValue* pBVal = static_cast<const PushButtonValue*>(&rVal);
248 0 : PushButtonValue* pNew = new PushButtonValue( *pBVal );
249 0 : aResult.reset( pNew );
250 : }
251 0 : break;
252 : case CTRL_GENERIC:
253 177460 : aResult.reset( new ImplControlValue( rVal ) );
254 177460 : break;
255 : case CTRL_MENU_POPUP:
256 : {
257 0 : const MenupopupValue* pMVal = static_cast<const MenupopupValue*>(&rVal);
258 0 : MenupopupValue* pNew = new MenupopupValue( *pMVal );
259 0 : pNew->maItemRect = rDev.ImplLogicToDevicePixel( pMVal->maItemRect );
260 0 : aResult.reset( pNew );
261 : }
262 0 : break;
263 : default:
264 : OSL_FAIL( "unknown ImplControlValue type !" );
265 0 : break;
266 : }
267 180152 : return aResult;
268 : }
269 0 : bool OutputDevice::DrawNativeControl( ControlType nType,
270 : ControlPart nPart,
271 : const Rectangle& rControlRegion,
272 : ControlState nState,
273 : const ImplControlValue& aValue,
274 : const OUString& aCaption )
275 : {
276 0 : assert_if_double_buffered_window();
277 :
278 0 : if( !EnableNativeWidget( *this ) )
279 0 : return false;
280 :
281 : // make sure the current clip region is initialized correctly
282 0 : if ( !mpGraphics )
283 0 : if ( !AcquireGraphics() )
284 0 : return false;
285 :
286 0 : if ( mbInitClipRegion )
287 0 : InitClipRegion();
288 0 : if ( mbOutputClipped )
289 0 : return true;
290 :
291 0 : if ( mbInitLineColor )
292 0 : InitLineColor();
293 0 : if ( mbInitFillColor )
294 0 : InitFillColor();
295 :
296 : // Convert the coordinates from relative to Window-absolute, so we draw
297 : // in the correct place in platform code
298 0 : std::shared_ptr< ImplControlValue > aScreenCtrlValue( TransformControlValue( aValue, *this ) );
299 0 : Rectangle screenRegion( ImplLogicToDevicePixel( rControlRegion ) );
300 :
301 0 : vcl::Region aTestRegion( GetActiveClipRegion() );
302 0 : aTestRegion.Intersect( rControlRegion );
303 0 : if (aTestRegion == vcl::Region(rControlRegion))
304 0 : nState |= ControlState::CACHING_ALLOWED; // control is not clipped, caching allowed
305 :
306 0 : if (dynamic_cast<VirtualDevice*>(this))
307 0 : nState |= ControlState::DOUBLEBUFFERING;
308 :
309 0 : bool bRet = mpGraphics->DrawNativeControl(nType, nPart, screenRegion, nState, *aScreenCtrlValue, aCaption, this );
310 :
311 0 : return bRet;
312 : }
313 :
314 182832 : bool OutputDevice::GetNativeControlRegion( ControlType nType,
315 : ControlPart nPart,
316 : const Rectangle& rControlRegion,
317 : ControlState nState,
318 : const ImplControlValue& aValue,
319 : const OUString& aCaption,
320 : Rectangle &rNativeBoundingRegion,
321 : Rectangle &rNativeContentRegion ) const
322 : {
323 182832 : if( !EnableNativeWidget( *this ) )
324 2680 : return false;
325 :
326 180152 : if ( !mpGraphics )
327 586 : if ( !AcquireGraphics() )
328 0 : return false;
329 :
330 : // Convert the coordinates from relative to Window-absolute, so we draw
331 : // in the correct place in platform code
332 180152 : std::shared_ptr< ImplControlValue > aScreenCtrlValue( TransformControlValue( aValue, *this ) );
333 180152 : Rectangle screenRegion( ImplLogicToDevicePixel( rControlRegion ) );
334 :
335 180152 : bool bRet = mpGraphics->GetNativeControlRegion(nType, nPart, screenRegion, nState, *aScreenCtrlValue,
336 : aCaption, rNativeBoundingRegion,
337 180152 : rNativeContentRegion, this );
338 180152 : if( bRet )
339 : {
340 : // transform back native regions
341 121 : rNativeBoundingRegion = ImplDevicePixelToLogic( rNativeBoundingRegion );
342 121 : rNativeContentRegion = ImplDevicePixelToLogic( rNativeContentRegion );
343 : }
344 :
345 180152 : return bRet;
346 801 : }
347 :
348 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|