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