1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
22 #include <vcl/outdev.hxx>
23 #include <vcl/virdev.hxx>
24 #include <vcl/window.hxx>
25 #include <sal/log.hxx>
27 #include <vcl/salnativewidgets.hxx>
28 #include <vcl/pdfextoutdevdata.hxx>
32 static bool EnableNativeWidget( const OutputDevice
& i_rDevice
)
34 const OutDevType
eType( i_rDevice
.GetOutDevType() );
40 const vcl::Window
* pWindow
= dynamic_cast< const vcl::Window
* >( &i_rDevice
);
43 return pWindow
->IsNativeWidgetEnabled();
47 SAL_WARN ("vcl.gdi", "Could not cast i_rDevice to Window");
57 const vcl::ExtOutDevData
* pOutDevData( i_rDevice
.GetExtOutDevData() );
58 const vcl::PDFExtOutDevData
* pPDFData( dynamic_cast< const vcl::PDFExtOutDevData
* >( pOutDevData
) );
59 return pPDFData
== nullptr;
67 ImplControlValue::~ImplControlValue()
71 ImplControlValue
* ImplControlValue::clone() const
73 assert( typeid( const ImplControlValue
) == typeid( *this ));
74 return new ImplControlValue( *this );
77 ScrollbarValue::~ScrollbarValue()
81 ScrollbarValue
* ScrollbarValue::clone() const
83 assert( typeid( const ScrollbarValue
) == typeid( *this ));
84 return new ScrollbarValue( *this );
87 SliderValue::~SliderValue()
91 SliderValue
* SliderValue::clone() const
93 assert( typeid( const SliderValue
) == typeid( *this ));
94 return new SliderValue( *this );
97 int TabPaneValue::m_nOverlap
= 0;
99 TabPaneValue
* TabPaneValue::clone() const
101 assert(typeid(const TabPaneValue
) == typeid(*this));
102 return new TabPaneValue(*this);
105 TabitemValue::~TabitemValue()
109 TabitemValue
* TabitemValue::clone() const
111 assert( typeid( const TabitemValue
) == typeid( *this ));
112 return new TabitemValue( *this );
115 SpinbuttonValue::~SpinbuttonValue()
119 SpinbuttonValue
* SpinbuttonValue::clone() const
121 assert( typeid( const SpinbuttonValue
) == typeid( *this ));
122 return new SpinbuttonValue( *this );
125 ToolbarValue::~ToolbarValue()
129 ToolbarValue
* ToolbarValue::clone() const
131 assert( typeid( const ToolbarValue
) == typeid( *this ));
132 return new ToolbarValue( *this );
135 MenubarValue::~MenubarValue()
139 MenubarValue
* MenubarValue::clone() const
141 assert( typeid( const MenubarValue
) == typeid( *this ));
142 return new MenubarValue( *this );
145 MenupopupValue::~MenupopupValue()
149 MenupopupValue
* MenupopupValue::clone() const
151 assert( typeid( const MenupopupValue
) == typeid( *this ));
152 return new MenupopupValue( *this );
155 PushButtonValue::~PushButtonValue()
159 PushButtonValue
* PushButtonValue::clone() const
161 assert( typeid( const PushButtonValue
) == typeid( *this ));
162 return new PushButtonValue( *this );
165 // These functions are mainly passthrough functions that allow access to
166 // the SalFrame behind a Window object for native widget rendering purposes.
168 bool OutputDevice::IsNativeControlSupported( ControlType nType
, ControlPart nPart
) const
170 if( !EnableNativeWidget( *this ) )
173 if ( !mpGraphics
&& !AcquireGraphics() )
176 return mpGraphics
->IsNativeControlSupported(nType
, nPart
);
179 bool OutputDevice::HitTestNativeScrollbar(
181 const tools::Rectangle
& rControlRegion
,
183 bool& rIsInside
) const
185 if( !EnableNativeWidget( *this ) )
188 if ( !mpGraphics
&& !AcquireGraphics() )
191 Point
aWinOffs( mnOutOffX
, mnOutOffY
);
192 tools::Rectangle
screenRegion( rControlRegion
);
193 screenRegion
.Move( aWinOffs
.X(), aWinOffs
.Y());
195 return mpGraphics
->HitTestNativeScrollbar( nPart
, screenRegion
, Point( aPos
.X() + mnOutOffX
, aPos
.Y() + mnOutOffY
),
199 static std::shared_ptr
< ImplControlValue
> TransformControlValue( const ImplControlValue
& rVal
, const OutputDevice
& rDev
)
201 std::shared_ptr
< ImplControlValue
> aResult
;
202 switch( rVal
.getType() )
204 case ControlType::Slider
:
206 const SliderValue
* pSlVal
= static_cast<const SliderValue
*>(&rVal
);
207 SliderValue
* pNew
= new SliderValue( *pSlVal
);
208 aResult
.reset( pNew
);
209 pNew
->maThumbRect
= rDev
.ImplLogicToDevicePixel( pSlVal
->maThumbRect
);
212 case ControlType::Scrollbar
:
214 const ScrollbarValue
* pScVal
= static_cast<const ScrollbarValue
*>(&rVal
);
215 ScrollbarValue
* pNew
= new ScrollbarValue( *pScVal
);
216 aResult
.reset( pNew
);
217 pNew
->maThumbRect
= rDev
.ImplLogicToDevicePixel( pScVal
->maThumbRect
);
218 pNew
->maButton1Rect
= rDev
.ImplLogicToDevicePixel( pScVal
->maButton1Rect
);
219 pNew
->maButton2Rect
= rDev
.ImplLogicToDevicePixel( pScVal
->maButton2Rect
);
222 case ControlType::SpinButtons
:
224 const SpinbuttonValue
* pSpVal
= static_cast<const SpinbuttonValue
*>(&rVal
);
225 SpinbuttonValue
* pNew
= new SpinbuttonValue( *pSpVal
);
226 aResult
.reset( pNew
);
227 pNew
->maUpperRect
= rDev
.ImplLogicToDevicePixel( pSpVal
->maUpperRect
);
228 pNew
->maLowerRect
= rDev
.ImplLogicToDevicePixel( pSpVal
->maLowerRect
);
231 case ControlType::Toolbar
:
233 const ToolbarValue
* pTVal
= static_cast<const ToolbarValue
*>(&rVal
);
234 ToolbarValue
* pNew
= new ToolbarValue( *pTVal
);
235 aResult
.reset( pNew
);
236 pNew
->maGripRect
= rDev
.ImplLogicToDevicePixel( pTVal
->maGripRect
);
239 case ControlType::TabPane
:
241 const TabPaneValue
* pTIVal
= static_cast<const TabPaneValue
*>(&rVal
);
242 TabPaneValue
* pNew
= new TabPaneValue(*pTIVal
);
243 pNew
->m_aTabHeaderRect
= rDev
.ImplLogicToDevicePixel(pTIVal
->m_aTabHeaderRect
);
244 pNew
->m_aSelectedTabRect
= rDev
.ImplLogicToDevicePixel(pTIVal
->m_aSelectedTabRect
);
248 case ControlType::TabItem
:
250 const TabitemValue
* pTIVal
= static_cast<const TabitemValue
*>(&rVal
);
251 TabitemValue
* pNew
= new TabitemValue( *pTIVal
);
252 pNew
->maContentRect
= rDev
.ImplLogicToDevicePixel(pTIVal
->maContentRect
);
253 aResult
.reset( pNew
);
256 case ControlType::Menubar
:
258 const MenubarValue
* pMVal
= static_cast<const MenubarValue
*>(&rVal
);
259 MenubarValue
* pNew
= new MenubarValue( *pMVal
);
260 aResult
.reset( pNew
);
263 case ControlType::Pushbutton
:
265 const PushButtonValue
* pBVal
= static_cast<const PushButtonValue
*>(&rVal
);
266 PushButtonValue
* pNew
= new PushButtonValue( *pBVal
);
267 aResult
.reset( pNew
);
270 case ControlType::Generic
:
271 aResult
= std::make_shared
<ImplControlValue
>( rVal
);
273 case ControlType::MenuPopup
:
275 const MenupopupValue
* pMVal
= static_cast<const MenupopupValue
*>(&rVal
);
276 MenupopupValue
* pNew
= new MenupopupValue( *pMVal
);
277 pNew
->maItemRect
= rDev
.ImplLogicToDevicePixel( pMVal
->maItemRect
);
278 aResult
.reset( pNew
);
287 bool OutputDevice::DrawNativeControl( ControlType nType
,
289 const tools::Rectangle
& rControlRegion
,
291 const ImplControlValue
& aValue
,
292 const OUString
& aCaption
,
293 const Color
& rBackgroundColor
)
295 assert(!is_double_buffered_window());
297 if( !EnableNativeWidget( *this ) )
300 // make sure the current clip region is initialized correctly
301 if ( !mpGraphics
&& !AcquireGraphics() )
304 if ( mbInitClipRegion
)
306 if ( mbOutputClipped
)
309 if ( mbInitLineColor
)
311 if ( mbInitFillColor
)
314 // Convert the coordinates from relative to Window-absolute, so we draw
315 // in the correct place in platform code
316 std::shared_ptr
< ImplControlValue
> aScreenCtrlValue( TransformControlValue( aValue
, *this ) );
317 tools::Rectangle
screenRegion( ImplLogicToDevicePixel( rControlRegion
) );
319 bool bRet
= mpGraphics
->DrawNativeControl(nType
, nPart
, screenRegion
, nState
, *aScreenCtrlValue
, aCaption
, this, rBackgroundColor
);
324 bool OutputDevice::GetNativeControlRegion( ControlType nType
,
326 const tools::Rectangle
& rControlRegion
,
328 const ImplControlValue
& aValue
,
329 tools::Rectangle
&rNativeBoundingRegion
,
330 tools::Rectangle
&rNativeContentRegion
) const
332 if( !EnableNativeWidget( *this ) )
335 if ( !mpGraphics
&& !AcquireGraphics() )
338 // Convert the coordinates from relative to Window-absolute, so we draw
339 // in the correct place in platform code
340 std::shared_ptr
< ImplControlValue
> aScreenCtrlValue( TransformControlValue( aValue
, *this ) );
341 tools::Rectangle
screenRegion( ImplLogicToDevicePixel( rControlRegion
) );
343 bool bRet
= mpGraphics
->GetNativeControlRegion(nType
, nPart
, screenRegion
, nState
, *aScreenCtrlValue
,
344 rNativeBoundingRegion
,
345 rNativeContentRegion
, this );
348 // transform back native regions
349 rNativeBoundingRegion
= ImplDevicePixelToLogic( rNativeBoundingRegion
);
350 rNativeContentRegion
= ImplDevicePixelToLogic( rNativeContentRegion
);
356 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */