1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_vcl.hxx"
26
27 #include "vcl/outdev.hxx"
28 #include "vcl/window.hxx"
29 #include "vcl/salnativewidgets.hxx"
30 #include "vcl/pdfextoutdevdata.hxx"
31
32 #include "salgdi.hxx"
33
34 // -----------------------------------------------------------------------
35
lcl_enableNativeWidget(const OutputDevice & i_rDevice)36 static bool lcl_enableNativeWidget( const OutputDevice& i_rDevice )
37 {
38 const OutDevType eType( i_rDevice.GetOutDevType() );
39 switch ( eType )
40 {
41
42 case OUTDEV_WINDOW:
43 return dynamic_cast< const Window* >( &i_rDevice )->IsNativeWidgetEnabled();
44
45 case OUTDEV_VIRDEV:
46 {
47 const ::vcl::ExtOutDevData* pOutDevData( i_rDevice.GetExtOutDevData() );
48 const ::vcl::PDFExtOutDevData* pPDFData( dynamic_cast< const ::vcl::PDFExtOutDevData* >( pOutDevData ) );
49 if ( pPDFData != NULL )
50 return false;
51 return true;
52 }
53
54 default:
55 return false;
56 }
57 }
58
~ImplControlValue()59 ImplControlValue::~ImplControlValue()
60 {
61 }
62
~ScrollbarValue()63 ScrollbarValue::~ScrollbarValue()
64 {
65 }
66
~SliderValue()67 SliderValue::~SliderValue()
68 {
69 }
70
~TabitemValue()71 TabitemValue::~TabitemValue()
72 {
73 }
74
~SpinbuttonValue()75 SpinbuttonValue::~SpinbuttonValue()
76 {
77 }
78
~ToolbarValue()79 ToolbarValue::~ToolbarValue()
80 {
81 }
82
~MenubarValue()83 MenubarValue::~MenubarValue()
84 {
85 }
86
~MenupopupValue()87 MenupopupValue::~MenupopupValue()
88 {
89 }
90
~PushButtonValue()91 PushButtonValue::~PushButtonValue()
92 {
93 }
94
95 // -----------------------------------------------------------------------
96 // These functions are mainly passthrough functions that allow access to
97 // the SalFrame behind a Window object for native widget rendering purposes.
98 // -----------------------------------------------------------------------
99
100 // -----------------------------------------------------------------------
101
IsNativeControlSupported(ControlType nType,ControlPart nPart)102 sal_Bool OutputDevice::IsNativeControlSupported( ControlType nType, ControlPart nPart )
103 {
104 if( !lcl_enableNativeWidget( *this ) )
105 return sal_False;
106
107 if ( !mpGraphics )
108 if ( !ImplGetGraphics() )
109 return sal_False;
110
111 return( mpGraphics->IsNativeControlSupported(nType, nPart) );
112 }
113
114
115 // -----------------------------------------------------------------------
116
HitTestNativeControl(ControlType nType,ControlPart nPart,const Rectangle & rControlRegion,const Point & aPos,sal_Bool & rIsInside)117 sal_Bool OutputDevice::HitTestNativeControl( ControlType nType,
118 ControlPart nPart,
119 const Rectangle& rControlRegion,
120 const Point& aPos,
121 sal_Bool& rIsInside )
122 {
123 if( !lcl_enableNativeWidget( *this ) )
124 return sal_False;
125
126 if ( !mpGraphics )
127 if ( !ImplGetGraphics() )
128 return sal_False;
129
130 Point aWinOffs( mnOutOffX, mnOutOffY );
131 Rectangle screenRegion( rControlRegion );
132 screenRegion.Move( aWinOffs.X(), aWinOffs.Y());
133
134 return( mpGraphics->HitTestNativeControl(nType, nPart, screenRegion, Point( aPos.X() + mnOutOffX, aPos.Y() + mnOutOffY ),
135 rIsInside, this ) );
136 }
137
138 // -----------------------------------------------------------------------
139
lcl_transformControlValue(const ImplControlValue & rVal,OutputDevice & rDev)140 static boost::shared_ptr< ImplControlValue > lcl_transformControlValue( const ImplControlValue& rVal, OutputDevice& rDev )
141 {
142 boost::shared_ptr< ImplControlValue > aResult;
143 switch( rVal.getType() )
144 {
145 case CTRL_SLIDER:
146 {
147 const SliderValue* pSlVal = static_cast<const SliderValue*>(&rVal);
148 SliderValue* pNew = new SliderValue( *pSlVal );
149 aResult.reset( pNew );
150 pNew->maThumbRect = rDev.ImplLogicToDevicePixel( pSlVal->maThumbRect );
151 }
152 break;
153 case CTRL_SCROLLBAR:
154 {
155 const ScrollbarValue* pScVal = static_cast<const ScrollbarValue*>(&rVal);
156 ScrollbarValue* pNew = new ScrollbarValue( *pScVal );
157 aResult.reset( pNew );
158 pNew->maThumbRect = rDev.ImplLogicToDevicePixel( pScVal->maThumbRect );
159 pNew->maButton1Rect = rDev.ImplLogicToDevicePixel( pScVal->maButton1Rect );
160 pNew->maButton2Rect = rDev.ImplLogicToDevicePixel( pScVal->maButton2Rect );
161 }
162 break;
163 case CTRL_SPINBUTTONS:
164 {
165 const SpinbuttonValue* pSpVal = static_cast<const SpinbuttonValue*>(&rVal);
166 SpinbuttonValue* pNew = new SpinbuttonValue( *pSpVal );
167 aResult.reset( pNew );
168 pNew->maUpperRect = rDev.ImplLogicToDevicePixel( pSpVal->maUpperRect );
169 pNew->maLowerRect = rDev.ImplLogicToDevicePixel( pSpVal->maLowerRect );
170 }
171 break;
172 case CTRL_TOOLBAR:
173 {
174 const ToolbarValue* pTVal = static_cast<const ToolbarValue*>(&rVal);
175 ToolbarValue* pNew = new ToolbarValue( *pTVal );
176 aResult.reset( pNew );
177 pNew->maGripRect = rDev.ImplLogicToDevicePixel( pTVal->maGripRect );
178 }
179 break;
180 case CTRL_TAB_ITEM:
181 {
182 const TabitemValue* pTIVal = static_cast<const TabitemValue*>(&rVal);
183 TabitemValue* pNew = new TabitemValue( *pTIVal );
184 aResult.reset( pNew );
185 }
186 break;
187 case CTRL_MENUBAR:
188 {
189 const MenubarValue* pMVal = static_cast<const MenubarValue*>(&rVal);
190 MenubarValue* pNew = new MenubarValue( *pMVal );
191 aResult.reset( pNew );
192 }
193 break;
194 case CTRL_PUSHBUTTON:
195 {
196 const PushButtonValue* pBVal = static_cast<const PushButtonValue*>(&rVal);
197 PushButtonValue* pNew = new PushButtonValue( *pBVal );
198 aResult.reset( pNew );
199 }
200 break;
201 case CTRL_GENERIC:
202 aResult.reset( new ImplControlValue( rVal ) );
203 break;
204 case CTRL_MENU_POPUP:
205 {
206 const MenupopupValue* pMVal = static_cast<const MenupopupValue*>(&rVal);
207 MenupopupValue* pNew = new MenupopupValue( *pMVal );
208 pNew->maItemRect = rDev.ImplLogicToDevicePixel( pMVal->maItemRect );
209 aResult.reset( pNew );
210 }
211 break;
212 default:
213 OSL_ENSURE( 0, "unknown ImplControlValue type !" );
214 break;
215 }
216 return aResult;
217 }
218
DrawNativeControl(ControlType nType,ControlPart nPart,const Rectangle & rControlRegion,ControlState nState,const ImplControlValue & aValue,::rtl::OUString aCaption)219 sal_Bool OutputDevice::DrawNativeControl( ControlType nType,
220 ControlPart nPart,
221 const Rectangle& rControlRegion,
222 ControlState nState,
223 const ImplControlValue& aValue,
224 ::rtl::OUString aCaption )
225 {
226 if( !lcl_enableNativeWidget( *this ) )
227 return sal_False;
228
229 // make sure the current clip region is initialized correctly
230 if ( !mpGraphics )
231 if ( !ImplGetGraphics() )
232 return sal_False;
233
234 if ( mbInitClipRegion )
235 ImplInitClipRegion();
236 if ( mbOutputClipped )
237 return sal_True;
238
239 if ( mbInitLineColor )
240 ImplInitLineColor();
241 if ( mbInitFillColor )
242 ImplInitFillColor();
243
244 // Convert the coordinates from relative to Window-absolute, so we draw
245 // in the correct place in platform code
246 boost::shared_ptr< ImplControlValue > aScreenCtrlValue( lcl_transformControlValue( aValue, *this ) );
247 Rectangle screenRegion( ImplLogicToDevicePixel( rControlRegion ) );
248
249 Region aTestRegion( GetActiveClipRegion() );
250 aTestRegion.Intersect( rControlRegion );
251 if( aTestRegion == rControlRegion )
252 nState |= CTRL_CACHING_ALLOWED; // control is not clipped, caching allowed
253
254 sal_Bool bRet = mpGraphics->DrawNativeControl(nType, nPart, screenRegion, nState, *aScreenCtrlValue, aCaption, this );
255
256 return bRet;
257 }
258
259
260 // -----------------------------------------------------------------------
261
DrawNativeControlText(ControlType nType,ControlPart nPart,const Rectangle & rControlRegion,ControlState nState,const ImplControlValue & aValue,::rtl::OUString aCaption)262 sal_Bool OutputDevice::DrawNativeControlText(ControlType nType,
263 ControlPart nPart,
264 const Rectangle& rControlRegion,
265 ControlState nState,
266 const ImplControlValue& aValue,
267 ::rtl::OUString aCaption )
268 {
269 if( !lcl_enableNativeWidget( *this ) )
270 return sal_False;
271
272 // make sure the current clip region is initialized correctly
273 if ( !mpGraphics )
274 if ( !ImplGetGraphics() )
275 return false;
276
277 if ( mbInitClipRegion )
278 ImplInitClipRegion();
279 if ( mbOutputClipped )
280 return true;
281
282 if ( mbInitLineColor )
283 ImplInitLineColor();
284 if ( mbInitFillColor )
285 ImplInitFillColor();
286
287 // Convert the coordinates from relative to Window-absolute, so we draw
288 // in the correct place in platform code
289 boost::shared_ptr< ImplControlValue > aScreenCtrlValue( lcl_transformControlValue( aValue, *this ) );
290 Rectangle screenRegion( ImplLogicToDevicePixel( rControlRegion ) );
291
292 sal_Bool bRet = mpGraphics->DrawNativeControlText(nType, nPart, screenRegion, nState, *aScreenCtrlValue, aCaption, this );
293
294 return bRet;
295 }
296
297
298 // -----------------------------------------------------------------------
299
GetNativeControlRegion(ControlType nType,ControlPart nPart,const Rectangle & rControlRegion,ControlState nState,const ImplControlValue & aValue,::rtl::OUString aCaption,Rectangle & rNativeBoundingRegion,Rectangle & rNativeContentRegion)300 sal_Bool OutputDevice::GetNativeControlRegion( ControlType nType,
301 ControlPart nPart,
302 const Rectangle& rControlRegion,
303 ControlState nState,
304 const ImplControlValue& aValue,
305 ::rtl::OUString aCaption,
306 Rectangle &rNativeBoundingRegion,
307 Rectangle &rNativeContentRegion )
308 {
309 if( !lcl_enableNativeWidget( *this ) )
310 return sal_False;
311
312 if ( !mpGraphics )
313 if ( !ImplGetGraphics() )
314 return sal_False;
315
316 // Convert the coordinates from relative to Window-absolute, so we draw
317 // in the correct place in platform code
318 boost::shared_ptr< ImplControlValue > aScreenCtrlValue( lcl_transformControlValue( aValue, *this ) );
319 Rectangle screenRegion( ImplLogicToDevicePixel( rControlRegion ) );
320
321 sal_Bool bRet = mpGraphics->GetNativeControlRegion(nType, nPart, screenRegion, nState, *aScreenCtrlValue,
322 aCaption, rNativeBoundingRegion,
323 rNativeContentRegion, this );
324 if( bRet )
325 {
326 // transform back native regions
327 rNativeBoundingRegion = ImplDevicePixelToLogic( rNativeBoundingRegion );
328 rNativeContentRegion = ImplDevicePixelToLogic( rNativeContentRegion );
329 }
330
331 return bRet;
332 }
333
334
335