diff options
Diffstat (limited to 'vcl/source/outdev/nativecontrols.cxx')
-rw-r--r-- | vcl/source/outdev/nativecontrols.cxx | 356 |
1 files changed, 356 insertions, 0 deletions
diff --git a/vcl/source/outdev/nativecontrols.cxx b/vcl/source/outdev/nativecontrols.cxx new file mode 100644 index 000000000..14ad647db --- /dev/null +++ b/vcl/source/outdev/nativecontrols.cxx @@ -0,0 +1,356 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <cassert> + +#include <vcl/outdev.hxx> +#include <vcl/virdev.hxx> +#include <vcl/window.hxx> +#include <sal/log.hxx> + +#include <vcl/salnativewidgets.hxx> +#include <vcl/pdfextoutdevdata.hxx> + +#include <salgdi.hxx> + +static bool EnableNativeWidget( const OutputDevice& i_rDevice ) +{ + const OutDevType eType( i_rDevice.GetOutDevType() ); + switch ( eType ) + { + + case OUTDEV_WINDOW: + { + const vcl::Window* pWindow = dynamic_cast< const vcl::Window* >( &i_rDevice ); + if (pWindow) + { + return pWindow->IsNativeWidgetEnabled(); + } + else + { + SAL_WARN ("vcl.gdi", "Could not cast i_rDevice to Window"); + assert (pWindow); + return false; + } + } + + case OUTDEV_PDF: + [[fallthrough]]; + case OUTDEV_VIRDEV: + { + const vcl::ExtOutDevData* pOutDevData( i_rDevice.GetExtOutDevData() ); + const vcl::PDFExtOutDevData* pPDFData( dynamic_cast< const vcl::PDFExtOutDevData* >( pOutDevData ) ); + return pPDFData == nullptr; + } + + default: + return false; + } +} + +ImplControlValue::~ImplControlValue() +{ +} + +ImplControlValue* ImplControlValue::clone() const +{ + assert( typeid( const ImplControlValue ) == typeid( *this )); + return new ImplControlValue( *this ); +} + +ScrollbarValue::~ScrollbarValue() +{ +} + +ScrollbarValue* ScrollbarValue::clone() const +{ + assert( typeid( const ScrollbarValue ) == typeid( *this )); + return new ScrollbarValue( *this ); +} + +SliderValue::~SliderValue() +{ +} + +SliderValue* SliderValue::clone() const +{ + assert( typeid( const SliderValue ) == typeid( *this )); + return new SliderValue( *this ); +} + +int TabPaneValue::m_nOverlap = 0; + +TabPaneValue* TabPaneValue::clone() const +{ + assert(typeid(const TabPaneValue) == typeid(*this)); + return new TabPaneValue(*this); +} + +TabitemValue::~TabitemValue() +{ +} + +TabitemValue* TabitemValue::clone() const +{ + assert( typeid( const TabitemValue ) == typeid( *this )); + return new TabitemValue( *this ); +} + +SpinbuttonValue::~SpinbuttonValue() +{ +} + +SpinbuttonValue* SpinbuttonValue::clone() const +{ + assert( typeid( const SpinbuttonValue ) == typeid( *this )); + return new SpinbuttonValue( *this ); +} + +ToolbarValue::~ToolbarValue() +{ +} + +ToolbarValue* ToolbarValue::clone() const +{ + assert( typeid( const ToolbarValue ) == typeid( *this )); + return new ToolbarValue( *this ); +} + +MenubarValue::~MenubarValue() +{ +} + +MenubarValue* MenubarValue::clone() const +{ + assert( typeid( const MenubarValue ) == typeid( *this )); + return new MenubarValue( *this ); +} + +MenupopupValue::~MenupopupValue() +{ +} + +MenupopupValue* MenupopupValue::clone() const +{ + assert( typeid( const MenupopupValue ) == typeid( *this )); + return new MenupopupValue( *this ); +} + +PushButtonValue::~PushButtonValue() +{ +} + +PushButtonValue* PushButtonValue::clone() const +{ + assert( typeid( const PushButtonValue ) == typeid( *this )); + return new PushButtonValue( *this ); +} + +// These functions are mainly passthrough functions that allow access to +// the SalFrame behind a Window object for native widget rendering purposes. + +bool OutputDevice::IsNativeControlSupported( ControlType nType, ControlPart nPart ) const +{ + if( !EnableNativeWidget( *this ) ) + return false; + + if ( !mpGraphics && !AcquireGraphics() ) + return false; + + return mpGraphics->IsNativeControlSupported(nType, nPart); +} + +bool OutputDevice::HitTestNativeScrollbar( + ControlPart nPart, + const tools::Rectangle& rControlRegion, + const Point& aPos, + bool& rIsInside ) const +{ + if( !EnableNativeWidget( *this ) ) + return false; + + if ( !mpGraphics && !AcquireGraphics() ) + return false; + + Point aWinOffs( mnOutOffX, mnOutOffY ); + tools::Rectangle screenRegion( rControlRegion ); + screenRegion.Move( aWinOffs.X(), aWinOffs.Y()); + + return mpGraphics->HitTestNativeScrollbar( nPart, screenRegion, Point( aPos.X() + mnOutOffX, aPos.Y() + mnOutOffY ), + rIsInside, this ); +} + +static std::shared_ptr< ImplControlValue > TransformControlValue( const ImplControlValue& rVal, const OutputDevice& rDev ) +{ + std::shared_ptr< ImplControlValue > aResult; + switch( rVal.getType() ) + { + case ControlType::Slider: + { + const SliderValue* pSlVal = static_cast<const SliderValue*>(&rVal); + SliderValue* pNew = new SliderValue( *pSlVal ); + aResult.reset( pNew ); + pNew->maThumbRect = rDev.ImplLogicToDevicePixel( pSlVal->maThumbRect ); + } + break; + case ControlType::Scrollbar: + { + const ScrollbarValue* pScVal = static_cast<const ScrollbarValue*>(&rVal); + ScrollbarValue* pNew = new ScrollbarValue( *pScVal ); + aResult.reset( pNew ); + pNew->maThumbRect = rDev.ImplLogicToDevicePixel( pScVal->maThumbRect ); + pNew->maButton1Rect = rDev.ImplLogicToDevicePixel( pScVal->maButton1Rect ); + pNew->maButton2Rect = rDev.ImplLogicToDevicePixel( pScVal->maButton2Rect ); + } + break; + case ControlType::SpinButtons: + { + const SpinbuttonValue* pSpVal = static_cast<const SpinbuttonValue*>(&rVal); + SpinbuttonValue* pNew = new SpinbuttonValue( *pSpVal ); + aResult.reset( pNew ); + pNew->maUpperRect = rDev.ImplLogicToDevicePixel( pSpVal->maUpperRect ); + pNew->maLowerRect = rDev.ImplLogicToDevicePixel( pSpVal->maLowerRect ); + } + break; + case ControlType::Toolbar: + { + const ToolbarValue* pTVal = static_cast<const ToolbarValue*>(&rVal); + ToolbarValue* pNew = new ToolbarValue( *pTVal ); + aResult.reset( pNew ); + pNew->maGripRect = rDev.ImplLogicToDevicePixel( pTVal->maGripRect ); + } + break; + case ControlType::TabPane: + { + const TabPaneValue* pTIVal = static_cast<const TabPaneValue*>(&rVal); + TabPaneValue* pNew = new TabPaneValue(*pTIVal); + pNew->m_aTabHeaderRect = rDev.ImplLogicToDevicePixel(pTIVal->m_aTabHeaderRect); + pNew->m_aSelectedTabRect = rDev.ImplLogicToDevicePixel(pTIVal->m_aSelectedTabRect); + aResult.reset(pNew); + } + break; + case ControlType::TabItem: + { + const TabitemValue* pTIVal = static_cast<const TabitemValue*>(&rVal); + TabitemValue* pNew = new TabitemValue( *pTIVal ); + pNew->maContentRect = rDev.ImplLogicToDevicePixel(pTIVal->maContentRect); + aResult.reset( pNew ); + } + break; + case ControlType::Menubar: + { + const MenubarValue* pMVal = static_cast<const MenubarValue*>(&rVal); + MenubarValue* pNew = new MenubarValue( *pMVal ); + aResult.reset( pNew ); + } + break; + case ControlType::Pushbutton: + { + const PushButtonValue* pBVal = static_cast<const PushButtonValue*>(&rVal); + PushButtonValue* pNew = new PushButtonValue( *pBVal ); + aResult.reset( pNew ); + } + break; + case ControlType::Generic: + aResult = std::make_shared<ImplControlValue>( rVal ); + break; + case ControlType::MenuPopup: + { + const MenupopupValue* pMVal = static_cast<const MenupopupValue*>(&rVal); + MenupopupValue* pNew = new MenupopupValue( *pMVal ); + pNew->maItemRect = rDev.ImplLogicToDevicePixel( pMVal->maItemRect ); + aResult.reset( pNew ); + } + break; + default: + std::abort(); + break; + } + return aResult; +} +bool OutputDevice::DrawNativeControl( ControlType nType, + ControlPart nPart, + const tools::Rectangle& rControlRegion, + ControlState nState, + const ImplControlValue& aValue, + const OUString& aCaption, + const Color& rBackgroundColor ) +{ + assert(!is_double_buffered_window()); + + if( !EnableNativeWidget( *this ) ) + return false; + + // make sure the current clip region is initialized correctly + if ( !mpGraphics && !AcquireGraphics() ) + return false; + + if ( mbInitClipRegion ) + InitClipRegion(); + if ( mbOutputClipped ) + return true; + + if ( mbInitLineColor ) + InitLineColor(); + if ( mbInitFillColor ) + InitFillColor(); + + // Convert the coordinates from relative to Window-absolute, so we draw + // in the correct place in platform code + std::shared_ptr< ImplControlValue > aScreenCtrlValue( TransformControlValue( aValue, *this ) ); + tools::Rectangle screenRegion( ImplLogicToDevicePixel( rControlRegion ) ); + + bool bRet = mpGraphics->DrawNativeControl(nType, nPart, screenRegion, nState, *aScreenCtrlValue, aCaption, this, rBackgroundColor ); + + return bRet; +} + +bool OutputDevice::GetNativeControlRegion( ControlType nType, + ControlPart nPart, + const tools::Rectangle& rControlRegion, + ControlState nState, + const ImplControlValue& aValue, + tools::Rectangle &rNativeBoundingRegion, + tools::Rectangle &rNativeContentRegion ) const +{ + if( !EnableNativeWidget( *this ) ) + return false; + + if ( !mpGraphics && !AcquireGraphics() ) + return false; + + // Convert the coordinates from relative to Window-absolute, so we draw + // in the correct place in platform code + std::shared_ptr< ImplControlValue > aScreenCtrlValue( TransformControlValue( aValue, *this ) ); + tools::Rectangle screenRegion( ImplLogicToDevicePixel( rControlRegion ) ); + + bool bRet = mpGraphics->GetNativeControlRegion(nType, nPart, screenRegion, nState, *aScreenCtrlValue, + rNativeBoundingRegion, + rNativeContentRegion, this ); + if( bRet ) + { + // transform back native regions + rNativeBoundingRegion = ImplDevicePixelToLogic( rNativeBoundingRegion ); + rNativeContentRegion = ImplDevicePixelToLogic( rNativeContentRegion ); + } + + return bRet; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |