summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--vcl/inc/widgetdraw/WidgetDefinitionReader.hxx77
-rw-r--r--vcl/source/gdi/FileDefinitionWidgetDraw.cxx145
-rw-r--r--vcl/source/gdi/WidgetDefinitionReader.cxx242
-rw-r--r--vcl/uiconfig/theme_definitions/definition.xml15
4 files changed, 470 insertions, 9 deletions
diff --git a/vcl/inc/widgetdraw/WidgetDefinitionReader.hxx b/vcl/inc/widgetdraw/WidgetDefinitionReader.hxx
index 350696a87dae..a5d8661304ea 100644
--- a/vcl/inc/widgetdraw/WidgetDefinitionReader.hxx
+++ b/vcl/inc/widgetdraw/WidgetDefinitionReader.hxx
@@ -15,14 +15,87 @@
#include <memory>
#include <rtl/ustring.hxx>
#include <tools/color.hxx>
+#include <tools/XmlWalker.hxx>
+#include <unordered_map>
+#include <vector>
+#include <vcl/salnativewidgets.hxx>
namespace vcl
{
+enum class DrawCommandType
+{
+ RECTANGLE
+};
+
+class VCL_DLLPUBLIC DrawCommand
+{
+public:
+ DrawCommand(DrawCommandType aType)
+ : maType(aType)
+ , mnStrokeWidth(-1)
+ , mnMargin(0)
+ {
+ }
+
+ DrawCommandType maType;
+
+ Color maStrokeColor;
+ Color maFillColor;
+ sal_Int32 mnStrokeWidth;
+ sal_Int32 mnMargin;
+};
+
+class VCL_DLLPUBLIC RectangleDrawCommand : public DrawCommand
+{
+public:
+ sal_Int32 mnRx;
+ sal_Int32 mnRy;
+
+ RectangleDrawCommand()
+ : DrawCommand(DrawCommandType::RECTANGLE)
+ , mnRx(0)
+ , mnRy(0)
+ {
+ }
+};
+
+class VCL_DLLPUBLIC WidgetDefinitionState
+{
+public:
+ OString msEnabled;
+ OString msFocused;
+ OString msPressed;
+ OString msRollover;
+ OString msDefault;
+ OString msSelected;
+
+ WidgetDefinitionState(OString const& sEnabled, OString const& sFocused, OString const& sPressed,
+ OString const& sRollover, OString const& sDefault,
+ OString const& sSelected);
+
+ std::vector<std::shared_ptr<DrawCommand>> mpDrawCommands;
+
+ void addDrawRectangle(Color aStrokeColor, sal_Int32 nStrokeWidth, Color aFillColor,
+ sal_Int32 nRx, sal_Int32 nRy, sal_Int32 nMargin);
+};
+
+class VCL_DLLPUBLIC WidgetDefinition
+{
+public:
+ std::vector<std::shared_ptr<WidgetDefinitionState>> getStates(ControlState eState);
+
+ std::vector<std::shared_ptr<WidgetDefinitionState>> maStates;
+};
+
class VCL_DLLPUBLIC WidgetDefinitionReader
{
private:
OUString m_rFilePath;
+ void readPushButton(tools::XmlWalker& rWalker);
+ static void readDrawingDefinition(tools::XmlWalker& rWalker,
+ std::shared_ptr<WidgetDefinitionState>& rStates);
+
public:
Color maFaceColor;
Color maCheckedColor;
@@ -75,6 +148,10 @@ public:
Color maToolTextColor;
Color maFontColor;
+ std::unordered_map<OString, std::shared_ptr<WidgetDefinition>> maPushButtonDefinitions;
+
+ std::shared_ptr<WidgetDefinition> getPushButtonDefinition(ControlPart ePart);
+
WidgetDefinitionReader(OUString const& rFilePath);
bool read();
};
diff --git a/vcl/source/gdi/FileDefinitionWidgetDraw.cxx b/vcl/source/gdi/FileDefinitionWidgetDraw.cxx
index d9ffc93e92ad..7b493c507b26 100644
--- a/vcl/source/gdi/FileDefinitionWidgetDraw.cxx
+++ b/vcl/source/gdi/FileDefinitionWidgetDraw.cxx
@@ -39,9 +39,43 @@ FileDefinitionWidgetDraw::FileDefinitionWidgetDraw(SalGraphics& rGraphics)
pSVData->maNWFData.mbNoFocusRectsForFlatButtons = true;
}
-bool FileDefinitionWidgetDraw::isNativeControlSupported(ControlType /*eType*/,
- ControlPart /*ePart*/)
+bool FileDefinitionWidgetDraw::isNativeControlSupported(ControlType eType, ControlPart /*ePart*/)
{
+ switch (eType)
+ {
+ case ControlType::Generic:
+ case ControlType::Pushbutton:
+ return true;
+ case ControlType::Radiobutton:
+ case ControlType::Checkbox:
+ case ControlType::Combobox:
+ case ControlType::Editbox:
+ case ControlType::EditboxNoBorder:
+ case ControlType::MultilineEditbox:
+ case ControlType::Listbox:
+ case ControlType::Spinbox:
+ case ControlType::SpinButtons:
+ case ControlType::TabItem:
+ case ControlType::TabPane:
+ case ControlType::TabHeader:
+ case ControlType::TabBody:
+ case ControlType::Scrollbar:
+ case ControlType::Slider:
+ case ControlType::Fixedline:
+ case ControlType::Toolbar:
+ case ControlType::Menubar:
+ case ControlType::MenuPopup:
+ case ControlType::Progress:
+ case ControlType::IntroProgress:
+ case ControlType::Tooltip:
+ case ControlType::WindowBackground:
+ case ControlType::Frame:
+ case ControlType::ListNode:
+ case ControlType::ListNet:
+ case ControlType::ListHeader:
+ return false;
+ }
+
return false;
}
@@ -52,14 +86,111 @@ bool FileDefinitionWidgetDraw::hitTestNativeControl(
return false;
}
-bool FileDefinitionWidgetDraw::drawNativeControl(ControlType /*eType*/, ControlPart /*ePart*/,
- const tools::Rectangle& /*rControlRegion*/,
- ControlState /*eState*/,
+namespace
+{
+void munchDrawCommands(std::vector<std::shared_ptr<DrawCommand>> const& rDrawCommands,
+ SalGraphics& rGraphics, long nX, long nY, long nWidth, long nHeight)
+{
+ for (std::shared_ptr<DrawCommand> const& pDrawCommand : rDrawCommands)
+ {
+ switch (pDrawCommand->maType)
+ {
+ case DrawCommandType::RECTANGLE:
+ {
+ auto const& rRectDrawCommand
+ = static_cast<RectangleDrawCommand const&>(*pDrawCommand);
+ Point aRectPoint(nX, nY);
+ Size aRectSize(nWidth - 1, nHeight - 1);
+ tools::Polygon aPolygon(tools::Rectangle(aRectPoint, aRectSize),
+ rRectDrawCommand.mnRx, rRectDrawCommand.mnRy);
+
+ basegfx::B2DPolygon aB2DPolygon(aPolygon.getB2DPolygon());
+ rGraphics.SetLineColor(rRectDrawCommand.maStrokeColor);
+ rGraphics.SetFillColor(rRectDrawCommand.maFillColor);
+ rGraphics.DrawPolyPolygon(basegfx::B2DHomMatrix(),
+ basegfx::B2DPolyPolygon(aB2DPolygon), 0.0f, nullptr);
+ }
+ break;
+ }
+ }
+}
+
+} // end anonymous namespace
+
+bool FileDefinitionWidgetDraw::drawNativeControl(ControlType eType, ControlPart ePart,
+ const tools::Rectangle& rControlRegion,
+ ControlState eState,
const ImplControlValue& /*rValue*/,
const OUString& /*aCaptions*/)
{
- (void)m_rGraphics; // avoid unused warning
- return false;
+ bool bOldAA = m_rGraphics.getAntiAliasB2DDraw();
+ m_rGraphics.setAntiAliasB2DDraw(true);
+
+ long nWidth = rControlRegion.GetWidth();
+ long nHeight = rControlRegion.GetHeight();
+ long nX = rControlRegion.Left() + 1;
+ long nY = rControlRegion.Top() + 1;
+
+ bool bOK = false;
+
+ switch (eType)
+ {
+ case ControlType::Generic:
+ {
+ }
+ break;
+ case ControlType::Pushbutton:
+ {
+ std::shared_ptr<WidgetDefinition> pDefinition
+ = m_WidgetDefinitionReader.getPushButtonDefinition(ePart);
+ if (pDefinition)
+ {
+ std::shared_ptr<WidgetDefinitionState> pState
+ = pDefinition->getStates(eState).back();
+ {
+ munchDrawCommands(pState->mpDrawCommands, m_rGraphics, nX, nY, nWidth, nHeight);
+ bOK = true;
+ }
+ }
+ }
+ break;
+ case ControlType::Radiobutton:
+ case ControlType::Checkbox:
+ case ControlType::Combobox:
+ case ControlType::Editbox:
+ case ControlType::EditboxNoBorder:
+ case ControlType::MultilineEditbox:
+ case ControlType::Listbox:
+ case ControlType::Spinbox:
+ case ControlType::SpinButtons:
+ case ControlType::TabItem:
+ case ControlType::TabPane:
+ case ControlType::TabBody:
+ case ControlType::Scrollbar:
+ case ControlType::Slider:
+ case ControlType::Fixedline:
+ case ControlType::Toolbar:
+ case ControlType::Menubar:
+ break;
+ case ControlType::MenuPopup:
+ break;
+ case ControlType::Progress:
+ case ControlType::IntroProgress:
+ break;
+ case ControlType::Tooltip:
+ break;
+ case ControlType::WindowBackground:
+ case ControlType::Frame:
+ case ControlType::ListNode:
+ case ControlType::ListNet:
+ case ControlType::ListHeader:
+ default:
+ break;
+ }
+
+ m_rGraphics.setAntiAliasB2DDraw(bOldAA);
+
+ return bOK;
}
bool FileDefinitionWidgetDraw::getNativeControlRegion(
diff --git a/vcl/source/gdi/WidgetDefinitionReader.cxx b/vcl/source/gdi/WidgetDefinitionReader.cxx
index 1bb7acb37eeb..0d78522abfd2 100644
--- a/vcl/source/gdi/WidgetDefinitionReader.cxx
+++ b/vcl/source/gdi/WidgetDefinitionReader.cxx
@@ -13,7 +13,6 @@
#include <sal/config.h>
#include <osl/file.hxx>
#include <tools/stream.hxx>
-#include <tools/XmlWalker.hxx>
#include <unordered_map>
namespace vcl
@@ -63,6 +62,82 @@ WidgetDefinitionReader::WidgetDefinitionReader(OUString const& rFilePath)
{
}
+void WidgetDefinitionReader::readDrawingDefinition(tools::XmlWalker& rWalker,
+ std::shared_ptr<WidgetDefinitionState>& rpState)
+{
+ rWalker.children();
+ while (rWalker.isValid())
+ {
+ if (rWalker.name() == "rect")
+ {
+ Color aStrokeColor;
+ readColor(rWalker.attribute("stroke"), aStrokeColor);
+ Color aFillColor;
+ readColor(rWalker.attribute("fill"), aFillColor);
+ OString sStrokeWidth = rWalker.attribute("stroke-width");
+ sal_Int32 nStrokeWidth = -1;
+ if (!sStrokeWidth.isEmpty())
+ nStrokeWidth = sStrokeWidth.toInt32();
+
+ sal_Int32 nRx = -1;
+ OString sRx = rWalker.attribute("rx");
+ if (!sRx.isEmpty())
+ nRx = sRx.toInt32();
+
+ sal_Int32 nRy = -1;
+ OString sRy = rWalker.attribute("ry");
+ if (!sRy.isEmpty())
+ nRy = sRy.toInt32();
+
+ sal_Int32 nMargin = 0;
+ OString sMargin = rWalker.attribute("margin");
+ if (!sMargin.isEmpty())
+ nMargin = sMargin.toInt32();
+
+ rpState->addDrawRectangle(aStrokeColor, nStrokeWidth, aFillColor, nRx, nRy, nMargin);
+ }
+ rWalker.next();
+ }
+ rWalker.parent();
+}
+
+void WidgetDefinitionReader::readPushButton(tools::XmlWalker& rWalker)
+{
+ rWalker.children();
+ while (rWalker.isValid())
+ {
+ if (rWalker.name() == "part")
+ {
+ OString sPart = rWalker.attribute("value");
+ std::shared_ptr<WidgetDefinition> pPart = std::make_shared<WidgetDefinition>();
+ maPushButtonDefinitions.emplace(sPart, pPart);
+ rWalker.children();
+ while (rWalker.isValid())
+ {
+ if (rWalker.name() == "state")
+ {
+ OString sEnabled = rWalker.attribute("enabled");
+ OString sFocused = rWalker.attribute("focused");
+ OString sPressed = rWalker.attribute("pressed");
+ OString sRollover = rWalker.attribute("rollover");
+ OString sDefault = rWalker.attribute("default");
+ OString sSelected = rWalker.attribute("selected");
+
+ std::shared_ptr<WidgetDefinitionState> pState
+ = std::make_shared<WidgetDefinitionState>(sEnabled, sFocused, sPressed,
+ sRollover, sDefault, sSelected);
+ pPart->maStates.push_back(pState);
+ readDrawingDefinition(rWalker, pState);
+ }
+ rWalker.next();
+ }
+ rWalker.parent();
+ }
+ rWalker.next();
+ }
+ rWalker.parent();
+}
+
bool WidgetDefinitionReader::read()
{
if (!lcl_fileExists(m_rFilePath))
@@ -147,6 +222,10 @@ bool WidgetDefinitionReader::read()
}
aWalker.parent();
}
+ else if (aWalker.name() == "pushbutton")
+ {
+ readPushButton(aWalker);
+ }
aWalker.next();
}
aWalker.parent();
@@ -154,6 +233,167 @@ bool WidgetDefinitionReader::read()
return true;
}
+namespace
+{
+OString xmlControlPart(ControlPart ePart)
+{
+ switch (ePart)
+ {
+ case ControlPart::NONE:
+ return "NONE";
+ case ControlPart::Entire:
+ return "Entire";
+ case ControlPart::ListboxWindow:
+ return "ListboxWindow";
+ case ControlPart::Button:
+ return "NONE";
+ case ControlPart::ButtonUp:
+ return "NONE";
+ case ControlPart::ButtonDown:
+ return "NONE";
+ case ControlPart::ButtonLeft:
+ return "NONE";
+ case ControlPart::ButtonRight:
+ return "NONE";
+ case ControlPart::AllButtons:
+ return "NONE";
+ case ControlPart::SeparatorHorz:
+ return "NONE";
+ case ControlPart::SeparatorVert:
+ return "NONE";
+ case ControlPart::TrackHorzLeft:
+ return "NONE";
+ case ControlPart::TrackVertUpper:
+ return "NONE";
+ case ControlPart::TrackHorzRight:
+ return "NONE";
+ case ControlPart::TrackVertLower:
+ return "NONE";
+ case ControlPart::TrackHorzArea:
+ return "NONE";
+ case ControlPart::TrackVertArea:
+ return "NONE";
+ case ControlPart::Arrow:
+ return "NONE";
+ case ControlPart::ThumbHorz:
+ return "NONE";
+ case ControlPart::ThumbVert:
+ return "NONE";
+ case ControlPart::MenuItem:
+ return "NONE";
+ case ControlPart::MenuItemCheckMark:
+ return "NONE";
+ case ControlPart::MenuItemRadioMark:
+ return "NONE";
+ case ControlPart::Separator:
+ return "NONE";
+ case ControlPart::SubmenuArrow:
+ return "NONE";
+ case ControlPart::SubEdit:
+ return "NONE";
+ case ControlPart::DrawBackgroundHorz:
+ return "NONE";
+ case ControlPart::DrawBackgroundVert:
+ return "NONE";
+ case ControlPart::TabsDrawRtl:
+ return "NONE";
+ case ControlPart::HasBackgroundTexture:
+ return "NONE";
+ case ControlPart::HasThreeButtons:
+ return "NONE";
+ case ControlPart::BackgroundWindow:
+ return "NONE";
+ case ControlPart::BackgroundDialog:
+ return "NONE";
+ case ControlPart::Border:
+ return "NONE";
+ case ControlPart::Focus:
+ return "FOCUS";
+
+ default:
+ break;
+ }
+ return "NONE";
+}
+
+} // end anonymous namespace
+
+std::shared_ptr<WidgetDefinition> WidgetDefinitionReader::getPushButtonDefinition(ControlPart ePart)
+{
+ auto aIterator = maPushButtonDefinitions.find(xmlControlPart(ePart));
+
+ if (aIterator != maPushButtonDefinitions.end())
+ return aIterator->second;
+ return std::shared_ptr<WidgetDefinition>();
+}
+
+std::vector<std::shared_ptr<WidgetDefinitionState>> WidgetDefinition::getStates(ControlState eState)
+{
+ std::vector<std::shared_ptr<WidgetDefinitionState>> aStatesToAdd;
+
+ for (auto& state : maStates)
+ {
+ bool bAdd = true;
+
+ if (state->msEnabled != "any"
+ && !((state->msEnabled == "true" && eState & ControlState::ENABLED)
+ || (state->msEnabled == "false" && !(eState & ControlState::ENABLED))))
+ bAdd = false;
+ if (state->msFocused != "any"
+ && !((state->msFocused == "true" && eState & ControlState::FOCUSED)
+ || (state->msFocused == "false" && !(eState & ControlState::FOCUSED))))
+ bAdd = false;
+ if (state->msPressed != "any"
+ && !((state->msPressed == "true" && eState & ControlState::PRESSED)
+ || (state->msPressed == "false" && !(eState & ControlState::PRESSED))))
+ bAdd = false;
+ if (state->msRollover != "any"
+ && !((state->msRollover == "true" && eState & ControlState::ROLLOVER)
+ || (state->msRollover == "false" && !(eState & ControlState::ROLLOVER))))
+ bAdd = false;
+ if (state->msDefault != "any"
+ && !((state->msDefault == "true" && eState & ControlState::DEFAULT)
+ || (state->msDefault == "false" && !(eState & ControlState::DEFAULT))))
+ bAdd = false;
+ if (state->msSelected != "any"
+ && !((state->msSelected == "true" && eState & ControlState::SELECTED)
+ || (state->msSelected == "false" && !(eState & ControlState::SELECTED))))
+ bAdd = false;
+
+ if (bAdd)
+ aStatesToAdd.push_back(state);
+ }
+
+ return aStatesToAdd;
+}
+
+WidgetDefinitionState::WidgetDefinitionState(OString const& sEnabled, OString const& sFocused,
+ OString const& sPressed, OString const& sRollover,
+ OString const& sDefault, OString const& sSelected)
+ : msEnabled(sEnabled)
+ , msFocused(sFocused)
+ , msPressed(sPressed)
+ , msRollover(sRollover)
+ , msDefault(sDefault)
+ , msSelected(sSelected)
+{
+}
+
+void WidgetDefinitionState::addDrawRectangle(Color aStrokeColor, sal_Int32 nStrokeWidth,
+ Color aFillColor, sal_Int32 nRx, sal_Int32 nRy,
+ sal_Int32 nMargin)
+{
+ std::shared_ptr<DrawCommand> pCommand(std::make_shared<RectangleDrawCommand>());
+ pCommand->maStrokeColor = aStrokeColor;
+ pCommand->maFillColor = aFillColor;
+ pCommand->mnStrokeWidth = nStrokeWidth;
+ pCommand->mnMargin = nMargin;
+ RectangleDrawCommand& rRectCommand = static_cast<RectangleDrawCommand&>(*pCommand);
+ rRectCommand.mnRx = nRx;
+ rRectCommand.mnRy = nRy;
+ mpDrawCommands.push_back(pCommand);
+}
+
} // end vcl namespace
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/uiconfig/theme_definitions/definition.xml b/vcl/uiconfig/theme_definitions/definition.xml
index d19db6043a7c..dbf87fddd6ba 100644
--- a/vcl/uiconfig/theme_definitions/definition.xml
+++ b/vcl/uiconfig/theme_definitions/definition.xml
@@ -1,4 +1,4 @@
- <?xml version="1.0" encoding="UTF-8"?>
+<?xml version="1.0" encoding="UTF-8"?>
<widgets>
<style>
@@ -53,4 +53,17 @@
<toolTextColor value="#000000"/>
<fontColor value="#000000"/>
</style>
+
+ <pushbutton>
+ <part value="Entire">
+ <state enabled="any" focused="any" pressed="any" rollover="any" default="any" selected="any">
+ <rect stroke="#007AFF" fill="#FFFFFF" stroke-width="1" rx="5" ry="5" margin="0"/>
+ </state>
+
+ <state enabled="true" focused="any" pressed="any" rollover="true" default="any" selected="any">
+ <rect stroke="#007AFF" fill="#007AFF" stroke-width="1" rx="5" ry="5" margin="0"/>
+ </state>
+ </part>
+ </pushbutton>
+
</widgets>