Kaydet (Commit) 8fcfa385 authored tarafından Tomaž Vajngerl's avatar Tomaž Vajngerl Kaydeden (comit) Jan Holesovsky

custom widgets: Custom Widget Themes

Change-Id: I7ec57d18fe99f906aeb6dbb40d0d30c2ac8b51c4
üst 4e6b448b
......@@ -461,6 +461,7 @@ vcl_headless_code= \
vcl/headless/svpdummies \
vcl/headless/svpinst \
vcl/headless/svpvd \
vcl/headless/CustomWidgetDraw \
vcl/unx/generic/app/gendisp \
vcl/unx/generic/app/geninst \
vcl/unx/generic/app/gensys \
......
/* -*- 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/.
*
*/
#include <headless/CustomWidgetDraw.hxx>
#include <vcl/salnativewidgets.hxx>
#include <sal/main.h>
#include <sal/config.h>
#include <rtl/bootstrap.hxx>
#include <tools/svlibrary.h>
#include <osl/module.hxx>
#include <cairo.h>
namespace vcl
{
WidgetThemeLibrary* CustomWidgetDraw::s_pWidgetImplementation = nullptr;
CustomWidgetDraw::CustomWidgetDraw(SvpSalGraphics& rGraphics)
: m_rGraphics(rGraphics)
{
if (!s_pWidgetImplementation)
{
OUString aUrl("${LO_LIB_DIR}/" SVLIBRARY("vcl_widget_theme"));
rtl::Bootstrap::expandMacros(aUrl);
osl::Module aLibrary;
aLibrary.load(aUrl, SAL_LOADMODULE_GLOBAL);
auto fCreateWidgetThemeLibraryFunction
= reinterpret_cast<vcl::WidgetThemeLibrary*(SAL_CALL*)()>(
aLibrary.getFunctionSymbol("CreateWidgetThemeLibrary"));
aLibrary.release();
if (fCreateWidgetThemeLibraryFunction)
s_pWidgetImplementation = (*fCreateWidgetThemeLibraryFunction)();
}
}
CustomWidgetDraw::~CustomWidgetDraw() {}
bool CustomWidgetDraw::isNativeControlSupported(ControlType eType, ControlPart /*ePart*/)
{
switch (eType)
{
case ControlType::Pushbutton:
return true;
default:
break;
}
return false;
}
bool CustomWidgetDraw::hitTestNativeControl(ControlType /*eType*/, ControlPart /*ePart*/,
const tools::Rectangle& /*rBoundingControlRegion*/,
const Point& /*aPos*/, bool& /*rIsInside*/)
{
//printf ("CustomWidgetDraw::hitTestNativeControl\n");
return false;
}
bool CustomWidgetDraw::drawNativeControl(ControlType eType, ControlPart ePart,
const tools::Rectangle& rControlRegion,
ControlState /*eState*/,
const ImplControlValue& /*aValue*/,
const OUString& /*aCaptions*/)
{
printf("CustomWidgetDraw::drawNativeControl %d %d\n", sal_Int32(eType), sal_Int32(ePart));
if (s_pWidgetImplementation == nullptr)
return false;
switch (eType)
{
case ControlType::Generic:
break;
case ControlType::Pushbutton:
{
printf("drawNativeControl -- ControlType::Pushbutton\n");
cairo_t* pCairoContext = m_rGraphics.getCairoContext(false);
m_rGraphics.clipRegion(pCairoContext);
cairo_translate(pCairoContext, rControlRegion.Left(), rControlRegion.Top());
long nX = 0;
long nY = 0;
long nWidth = rControlRegion.GetWidth();
long nHeight = rControlRegion.GetHeight();
if (ePart == ControlPart::Focus)
s_pWidgetImplementation->drawPushButtonFocus(pCairoContext, nX, nY, nWidth,
nHeight);
else
s_pWidgetImplementation->drawPushButton(pCairoContext, nX, nY, nWidth, nHeight);
cairo_destroy(pCairoContext); // unref
return true;
}
break;
case ControlType::Radiobutton:
break;
case ControlType::Checkbox:
break;
case ControlType::Combobox:
break;
case ControlType::Editbox:
break;
case ControlType::EditboxNoBorder:
break;
case ControlType::MultilineEditbox:
break;
case ControlType::Listbox:
break;
case ControlType::Spinbox:
break;
case ControlType::SpinButtons:
break;
case ControlType::TabItem:
break;
case ControlType::TabPane:
break;
case ControlType::TabHeader:
break;
case ControlType::TabBody:
break;
case ControlType::Scrollbar:
break;
case ControlType::Slider:
break;
case ControlType::Fixedline:
break;
case ControlType::Toolbar:
break;
case ControlType::Menubar:
break;
case ControlType::MenuPopup:
break;
case ControlType::Progress:
break;
case ControlType::IntroProgress:
break;
case ControlType::Tooltip:
break;
case ControlType::WindowBackground:
break;
case ControlType::Frame:
break;
case ControlType::ListNode:
break;
case ControlType::ListNet:
break;
case ControlType::ListHeader:
break;
}
return false;
}
bool CustomWidgetDraw::getNativeControlRegion(ControlType /*eType*/, ControlPart /*ePart*/,
const tools::Rectangle& /*rBoundingControlRegion*/,
ControlState /*eState*/,
const ImplControlValue& /*aValue*/,
const OUString& /*aCaption*/,
tools::Rectangle& /*rNativeBoundingRegion*/,
tools::Rectangle& /*rNativeContentRegion*/)
{
//printf ("CustomWidgetDraw::getNativeControlRegion\n");
return false;
}
} // end vcl namespace
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
/* -*- 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/.
*
*/
#ifndef INCLUDED_VCL_INC_WIDGETDRAWINTERFACE_HXX
#define INCLUDED_VCL_INC_WIDGETDRAWINTERFACE_HXX
#include <vcl/dllapi.h>
namespace vcl
{
class VCL_PLUGIN_PUBLIC WidgetDrawInterface
{
public:
virtual ~WidgetDrawInterface() {}
/**
* Query the platform layer for native control support.
*
* @param [in] eType The widget type.
* @param [in] ePart The part of the widget.
* @return true if the platform supports native drawing of the widget type defined by part.
*/
virtual bool isNativeControlSupported(ControlType eType, ControlPart ePart) = 0;
/**
* Query if a position is inside the native widget part.
*
* Mainly used for scrollbars.
*
* @param [in] eType The widget type.
* @param [in] ePart The part of the widget.
* @param [in] rBoundingControlRegion The bounding Rectangle of
the complete control in VCL frame coordinates.
* @param [in] aPos The position to check the hit.
* @param [out] rIsInside true, if \a aPos was inside the native widget.
* @return true, if the query was successful.
*/
virtual bool hitTestNativeControl(ControlType eType, ControlPart ePart,
const tools::Rectangle& rBoundingControlRegion,
const Point& aPos, bool& rIsInside)
= 0;
/**
* Draw the requested control.
*
* @param [in] eType The widget type.
* @param [in] ePart The part of the widget.
* @param [in] rBoundingControlRegion The bounding rectangle of
* the complete control in VCL frame coordinates.
* @param [in] eState The general state of the control (enabled, focused, etc.).
* @param [in] aValue Addition control specific information.
* @param [in] aCaption A caption or title string (like button text etc.).
* @return true, if the control could be drawn.
*/
virtual bool drawNativeControl(ControlType eType, ControlPart ePart,
const tools::Rectangle& rBoundingControlRegion,
ControlState eState, const ImplControlValue& aValue,
const OUString& aCaptions)
= 0;
/**
* Get the native control regions for the control part.
*
* If the return value is true, \a rNativeBoundingRegion contains
* the true bounding region covered by the control including any
* adornment, while \a rNativeContentRegion contains the area
* within the control that can be safely drawn into without drawing over
* the borders of the control.
*
* @param [in] eType Type of the widget.
* @param [in] ePart Specification of the widget's part if it consists of more than one.
* @param [in] rBoundingControlRegion The bounding region of the control in VCL frame coordinates.
* @param [in] eState The general state of the control (enabled, focused, etc.).
* @param [in] aValue Addition control specific information.
* @param [in] aCaption A caption or title string (like button text etc.).
* @param [out] rNativeBoundingRegion The region covered by the control including any adornment.
* @param [out] rNativeContentRegion The region within the control that can be safely drawn into.
* @return true, if the regions are filled.
*/
virtual bool getNativeControlRegion(ControlType eType, ControlPart ePart,
const tools::Rectangle& rBoundingControlRegion,
ControlState eState, const ImplControlValue& aValue,
const OUString& aCaption,
tools::Rectangle& rNativeBoundingRegion,
tools::Rectangle& rNativeContentRegion)
= 0;
};
}
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
/* -*- 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/.
*
*/
#ifndef INCLUDED_VCL_INC_WIDGETTHEME_HXX
#define INCLUDED_VCL_INC_WIDGETTHEME_HXX
#include <cairo.h>
#include <vcl/dllapi.h>
namespace vcl
{
class SAL_DLLPUBLIC_RTTI WidgetThemeLibrary
{
public:
WidgetThemeLibrary();
virtual ~WidgetThemeLibrary();
virtual bool drawPushButtonFocus(cairo_t* pCairo, long nX, long nY, long nWidth, long nHeight);
virtual bool drawPushButton(cairo_t* pCairo, long nX, long nY, long nWidth, long nHeight);
};
extern "C" vcl::WidgetThemeLibrary* CreateWidgetThemeLibrary();
} // end vcl namespace
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
/* -*- 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/.
*
*/
#ifndef INCLUDED_VCL_INC_CUSTOMWIDGETDRAW_HXX
#define INCLUDED_VCL_INC_CUSTOMWIDGETDRAW_HXX
#include <vcl/dllapi.h>
#include <vcl/salnativewidgets.hxx>
#include <WidgetDrawInterface.hxx>
#include <WidgetThemeLibrary.hxx>
#include <headless/svpgdi.hxx>
#include <memory>
namespace vcl
{
class VCL_DLLPUBLIC CustomWidgetDraw : public vcl::WidgetDrawInterface
{
private:
static WidgetThemeLibrary* s_pWidgetImplementation;
SvpSalGraphics& m_rGraphics;
public:
CustomWidgetDraw(SvpSalGraphics& rGraphics);
virtual ~CustomWidgetDraw();
bool isNativeControlSupported(ControlType eType, ControlPart ePart) override;
bool hitTestNativeControl(ControlType eType, ControlPart ePart,
const tools::Rectangle& rBoundingControlRegion, const Point& aPos,
bool& rIsInside) override;
bool drawNativeControl(ControlType eType, ControlPart ePart,
const tools::Rectangle& rBoundingControlRegion, ControlState eState,
const ImplControlValue& aValue, const OUString& aCaptions) override;
bool getNativeControlRegion(ControlType eType, ControlPart ePart,
const tools::Rectangle& rBoundingControlRegion, ControlState eState,
const ImplControlValue& aValue, const OUString& aCaption,
tools::Rectangle& rNativeBoundingRegion,
tools::Rectangle& rNativeContentRegion) override;
};
} // end vcl namespace
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
......@@ -26,6 +26,7 @@
#include "salgdiimpl.hxx"
#include "sallayout.hxx"
#include <basegfx/matrix/b2dhommatrix.hxx>
#include <WidgetDrawInterface.hxx>
#include <config_cairo_canvas.h>
......@@ -663,6 +664,13 @@ protected:
bool m_bAntiAliasB2DDraw : 1;
inline long GetDeviceWidth(const OutputDevice* pOutDev) const;
bool hasWidgetDraw()
{
return bool(m_pWidgetDraw);
}
std::unique_ptr<vcl::WidgetDrawInterface> m_pWidgetDraw;
};
#endif // INCLUDED_VCL_INC_SALGDI_HXX
......
......@@ -19,33 +19,55 @@
#include <salgdi.hxx>
/****************************************************************
* Placeholder for no native widgets
***************************************************************/
bool SalGraphics::IsNativeControlSupported( ControlType, ControlPart )
bool SalGraphics::IsNativeControlSupported(ControlType eType, ControlPart ePart)
{
if (hasWidgetDraw())
return m_pWidgetDraw->isNativeControlSupported(eType, ePart);
return false;
}
bool SalGraphics::hitTestNativeControl( ControlType, ControlPart,
const tools::Rectangle&, const Point&, bool& )
bool SalGraphics::hitTestNativeControl(ControlType eType, ControlPart ePart,
const tools::Rectangle& rBoundingControlRegion,
const Point& rPosition, bool& rIsInside)
{
if (hasWidgetDraw())
{
return m_pWidgetDraw->hitTestNativeControl(eType, ePart, rBoundingControlRegion, rPosition, rIsInside);
}
return false;
}
bool SalGraphics::drawNativeControl( ControlType, ControlPart,
const tools::Rectangle&, ControlState,
const ImplControlValue&, const OUString& )
bool SalGraphics::drawNativeControl(ControlType eType, ControlPart ePart,
const tools::Rectangle& rBoundingControlRegion,
ControlState eState, const ImplControlValue& aValue,
const OUString& aCaptions)
{
if (hasWidgetDraw())
{
return m_pWidgetDraw->drawNativeControl(eType, ePart, rBoundingControlRegion,
eState, aValue, aCaptions);
}
return false;
}
bool SalGraphics::getNativeControlRegion( ControlType, ControlPart,
const tools::Rectangle&, ControlState,
const ImplControlValue&,
const OUString&, tools::Rectangle&, tools::Rectangle& )
bool SalGraphics::getNativeControlRegion(ControlType eType, ControlPart ePart,
const tools::Rectangle& rBoundingControlRegion,
ControlState eState,
const ImplControlValue& aValue,
const OUString& aCaption,
tools::Rectangle& rNativeBoundingRegion,
tools::Rectangle& rNativeContentRegion)
{
if (hasWidgetDraw())
{
return m_pWidgetDraw->getNativeControlRegion(eType, ePart, rBoundingControlRegion,
eState, aValue, aCaption,
rNativeBoundingRegion, rNativeContentRegion);
}
return false;
}
......
......@@ -20,6 +20,8 @@
#include <vcl/decoview.hxx>
#include <vcl/settings.hxx>
#include <unx/fontmanager.hxx>
#include <headless/CustomWidgetDraw.hxx>
#include "cairo_gtk3_cairo.hxx"
#if defined(GDK_WINDOWING_WAYLAND)
# include <gdk/gdkwayland.h>
......@@ -2166,8 +2168,19 @@ static gfloat getArrowSize(GtkStyleContext* context)
bool GtkSalGraphics::drawNativeControl( ControlType nType, ControlPart nPart, const tools::Rectangle& rControlRegion,
ControlState nState, const ImplControlValue& rValue,
const OUString& )
const OUString& aCaptions)
{
if (m_pWidgetDraw)
{
bool bReturn = m_pWidgetDraw->drawNativeControl(nType, nPart, rControlRegion,
nState, rValue, aCaptions);
if (bReturn && !rControlRegion.IsEmpty())
mpFrame->damaged(rControlRegion.Left(), rControlRegion.Top(), rControlRegion.GetWidth(), rControlRegion.GetHeight());
return bReturn;
}
RenderType renderType = nPart == ControlPart::Focus ? RenderType::Focus : RenderType::BackgroundAndFrame;
GtkStyleContext *context = nullptr;
const gchar *styleClass = nullptr;
......@@ -2604,10 +2617,17 @@ static tools::Rectangle AdjustRectForTextBordersPadding(GtkStyleContext* pStyle,
return aEditRect;
}
bool GtkSalGraphics::getNativeControlRegion( ControlType nType, ControlPart nPart, const tools::Rectangle& rControlRegion, ControlState,
const ImplControlValue& rValue, const OUString&,
bool GtkSalGraphics::getNativeControlRegion( ControlType nType, ControlPart nPart, const tools::Rectangle& rControlRegion, ControlState eState,
const ImplControlValue& rValue, const OUString& aCaption,
tools::Rectangle &rNativeBoundingRegion, tools::Rectangle &rNativeContentRegion )
{
if (hasWidgetDraw())
{
return m_pWidgetDraw->getNativeControlRegion(nType, nPart, rControlRegion,
eState, rValue, aCaption,
rNativeBoundingRegion, rNativeContentRegion);
}
/* TODO: all this functions needs improvements */
tools::Rectangle aEditRect = rControlRegion;
gint indicator_size, indicator_spacing, point;
......@@ -3182,6 +3202,11 @@ void GtkSalGraphics::updateSettings( AllSettings& rSettings )
bool GtkSalGraphics::IsNativeControlSupported( ControlType nType, ControlPart nPart )
{
if (m_pWidgetDraw)
{
return m_pWidgetDraw->isNativeControlSupported(nType, nPart);
}
switch(nType)
{
case ControlType::Pushbutton:
......@@ -3358,6 +3383,9 @@ GtkSalGraphics::GtkSalGraphics( GtkSalFrame *pFrame, GtkWidget *pWindow )
mpFrame( pFrame ),
mpWindow( pWindow )
{
/* Set Custom Widget Draw*/
m_pWidgetDraw.reset(new vcl::CustomWidgetDraw(*this));
if (style_loaded)
return;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment