Update text rendering.
This commit is contained in:
parent
8536908eab
commit
8130308f7f
27 changed files with 503 additions and 77 deletions
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
struct Bounds
|
struct Bounds
|
||||||
{
|
{
|
||||||
Bounds(double minX, double maxX, double minY, double maxY, double minZ = 0.0, double maxZ = 0.0)
|
Bounds(double minX = 0.0, double maxX = 0.0, double minY = 0.0, double maxY = 0.0, double minZ = 0.0, double maxZ = 0.0)
|
||||||
: mMinX(minX),
|
: mMinX(minX),
|
||||||
mMaxX(maxX),
|
mMaxX(maxX),
|
||||||
mMinY(minY),
|
mMinY(minY),
|
||||||
|
@ -60,4 +60,21 @@ struct Bounds
|
||||||
mMaxZ = z;
|
mMaxZ = z;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool operator==(const Bounds& rhs) const
|
||||||
|
{
|
||||||
|
return (mMinX == rhs.mMinX)
|
||||||
|
&& (mMaxX == rhs.mMaxX)
|
||||||
|
|
||||||
|
&& (mMinY == rhs.mMinY)
|
||||||
|
&& (mMaxY == rhs.mMaxY)
|
||||||
|
|
||||||
|
&& (mMinZ == rhs.mMinZ)
|
||||||
|
&& (mMaxZ == rhs.mMaxZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const Bounds& rhs) const
|
||||||
|
{
|
||||||
|
return !operator==(rhs);
|
||||||
|
}
|
||||||
};
|
};
|
|
@ -31,6 +31,21 @@ public:
|
||||||
return !operator==(rhs);
|
return !operator==(rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool hasDefaultLocation() const
|
||||||
|
{
|
||||||
|
return mLocation.getX() == 0.0 && mLocation.getY() == 0.0 && mLocation.getZ() == 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hasDefaultScale() const
|
||||||
|
{
|
||||||
|
return mScaleX == 1.0 && mScaleY == 1.0 && mScaleZ == 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isDefaultTransform() const
|
||||||
|
{
|
||||||
|
return hasDefaultLocation() && hasDefaultScale();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Point mLocation;
|
Point mLocation;
|
||||||
double mScaleX{1};
|
double mScaleX{1};
|
||||||
|
|
|
@ -13,8 +13,10 @@
|
||||||
#include "AbstractFace.h"
|
#include "AbstractFace.h"
|
||||||
|
|
||||||
#include "Circle.h"
|
#include "Circle.h"
|
||||||
|
#include "Rectangle.h"
|
||||||
|
|
||||||
#include "SvgShapeElements.h"
|
#include "SvgShapeElements.h"
|
||||||
|
#include "SvgTextElement.h"
|
||||||
#include "XmlAttribute.h"
|
#include "XmlAttribute.h"
|
||||||
|
|
||||||
std::unique_ptr<SvgDocument> SvgPainter::paint(Scene* scene, double width, double height) const
|
std::unique_ptr<SvgDocument> SvgPainter::paint(Scene* scene, double width, double height) const
|
||||||
|
@ -102,22 +104,33 @@ void SvgPainter::setStyle(SceneModel* model, SvgShapeElement* element) const
|
||||||
if (model->hasOutlineColor())
|
if (model->hasOutlineColor())
|
||||||
{
|
{
|
||||||
element->setStrokeColor(model->getOutlineColor());
|
element->setStrokeColor(model->getOutlineColor());
|
||||||
element->setStrokeWidth(model->getOutlineThickness() / transform.getScaleX());
|
element->setStrokeWidth(model->getOutlineThickness());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
element->setNoStroke();
|
element->setNoStroke();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!transform.isDefaultTransform())
|
||||||
|
{
|
||||||
element->addAttribute(std::move(toTransform(transform)));
|
element->addAttribute(std::move(toTransform(transform)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SvgPainter::paintPrimitive(SvgDocument* document, SceneModel* model) const
|
void SvgPainter::paintPrimitive(SvgDocument* document, SceneModel* model) const
|
||||||
{
|
{
|
||||||
if (model->getGeometry()->getType() == AbstractGeometricItem::Type::RECTANGLE)
|
if (model->getGeometry()->getType() == AbstractGeometricItem::Type::RECTANGLE)
|
||||||
{
|
{
|
||||||
|
auto model_rect = dynamic_cast<ntk::Rectangle*>(model->getGeometry());
|
||||||
|
|
||||||
auto rect = std::make_unique<SvgRectangle>();
|
auto rect = std::make_unique<SvgRectangle>();
|
||||||
rect->setWidth(1.0);
|
rect->setWidth(model_rect->getWidth());
|
||||||
rect->setHeight(1.0);
|
rect->setHeight(model_rect->getHeight());
|
||||||
|
|
||||||
|
if (model_rect->getRadius() > 0.0)
|
||||||
|
{
|
||||||
|
rect->setRadius(model_rect->getRadius());
|
||||||
|
}
|
||||||
|
|
||||||
setStyle(model, rect.get());
|
setStyle(model, rect.get());
|
||||||
document->getRoot()->addChild(std::move(rect));
|
document->getRoot()->addChild(std::move(rect));
|
||||||
|
@ -139,9 +152,17 @@ void SvgPainter::paintPrimitive(SvgDocument* document, SceneModel* model) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SvgPainter::paintText(SvgDocument* document, SceneText* model) const
|
void SvgPainter::paintText(SvgDocument* document, SceneText* text) const
|
||||||
{
|
{
|
||||||
|
auto svg_text = std::make_unique<SvgTextElement>();
|
||||||
|
svg_text->setContent(text->getTextData().mContent);
|
||||||
|
svg_text->setLocation(text->getTransform().getLocation());
|
||||||
|
|
||||||
|
svg_text->setFontFamily(text->getTextData().mFont.getFaceName());
|
||||||
|
svg_text->setFill(text->getFillColor());
|
||||||
|
svg_text->setFontSize(text->getTextData().mFont.getSize());
|
||||||
|
|
||||||
|
document->getRoot()->addChild(std::move(svg_text));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<XmlAttribute> SvgPainter::toTransform(const Transform& transform) const
|
std::unique_ptr<XmlAttribute> SvgPainter::toTransform(const Transform& transform) const
|
||||||
|
@ -149,8 +170,14 @@ std::unique_ptr<XmlAttribute> SvgPainter::toTransform(const Transform& transform
|
||||||
auto svg_transform = std::make_unique<XmlAttribute>("transform");
|
auto svg_transform = std::make_unique<XmlAttribute>("transform");
|
||||||
|
|
||||||
std::string ops;
|
std::string ops;
|
||||||
|
if (!transform.hasDefaultLocation())
|
||||||
|
{
|
||||||
ops += "translate(" + std::to_string(transform.getLocation().getX()) + " " + std::to_string(transform.getLocation().getY()) + ") ";
|
ops += "translate(" + std::to_string(transform.getLocation().getX()) + " " + std::to_string(transform.getLocation().getY()) + ") ";
|
||||||
|
}
|
||||||
|
if (!transform.hasDefaultScale())
|
||||||
|
{
|
||||||
ops += "scale(" + std::to_string(transform.getScaleX()) + " " + std::to_string(transform.getScaleY()) + ") ";
|
ops += "scale(" + std::to_string(transform.getScaleX()) + " " + std::to_string(transform.getScaleY()) + ") ";
|
||||||
|
}
|
||||||
svg_transform->setValue(ops);
|
svg_transform->setValue(ops);
|
||||||
|
|
||||||
return std::move(svg_transform);
|
return std::move(svg_transform);
|
||||||
|
|
|
@ -34,23 +34,47 @@ void DirectX2dPainter::paint(SceneModel* model)
|
||||||
|
|
||||||
if (model->getGeometry()->getType() == AbstractGeometricItem::Type::RECTANGLE)
|
if (model->getGeometry()->getType() == AbstractGeometricItem::Type::RECTANGLE)
|
||||||
{
|
{
|
||||||
|
auto rect = dynamic_cast<ntk::Rectangle*>(model->getGeometry());
|
||||||
|
|
||||||
const auto loc = model->getTransform().getLocation();
|
const auto loc = model->getTransform().getLocation();
|
||||||
const auto scale_x = model->getTransform().getScaleX();
|
const auto scale_x = model->getTransform().getScaleX();
|
||||||
const auto scale_y = model->getTransform().getScaleY();
|
const auto scale_y = model->getTransform().getScaleY();
|
||||||
D2D1_RECT_F d2d_rect{ static_cast<float>(loc.getX()), static_cast<float>(loc.getY() + scale_y), static_cast<float>(loc.getX() + scale_x), static_cast<float>(loc.getY()) };
|
|
||||||
|
|
||||||
|
const auto min_x = static_cast<float>(loc.getX());
|
||||||
|
const auto max_x = static_cast<float>(loc.getX() + rect->getWidth()* scale_x);
|
||||||
|
|
||||||
|
const auto min_y = static_cast<float>(loc.getY());
|
||||||
|
const auto max_y = static_cast<float>(loc.getY() + rect->getHeight() * scale_y);
|
||||||
|
|
||||||
|
D2D1_RECT_F d2d_rect{ min_x, max_y, max_x, min_y };
|
||||||
|
if (rect->getRadius() == 0.0)
|
||||||
|
{
|
||||||
if (model->hasFillColor())
|
if (model->hasFillColor())
|
||||||
{
|
{
|
||||||
mSolidBrush->SetColor(toD2dColor(model->getFillColor()));
|
mSolidBrush->SetColor(toD2dColor(model->getFillColor()));
|
||||||
rt->FillRectangle(d2d_rect, mSolidBrush.Get());
|
rt->FillRectangle(d2d_rect, mSolidBrush.Get());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (model->hasOutlineColor())
|
if (model->hasOutlineColor())
|
||||||
{
|
{
|
||||||
mSolidBrush->SetColor(toD2dColor(model->getOutlineColor()));
|
mSolidBrush->SetColor(toD2dColor(model->getOutlineColor()));
|
||||||
rt->DrawRectangle(d2d_rect, mSolidBrush.Get(), 1.0f);
|
rt->DrawRectangle(d2d_rect, mSolidBrush.Get(), 1.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
D2D1_ROUNDED_RECT rounded_rect{ d2d_rect , static_cast<float>(rect->getRadius()), static_cast<float>(rect->getRadius()) };
|
||||||
|
if (model->hasFillColor())
|
||||||
|
{
|
||||||
|
mSolidBrush->SetColor(toD2dColor(model->getFillColor()));
|
||||||
|
rt->FillRoundedRectangle(rounded_rect, mSolidBrush.Get());
|
||||||
|
}
|
||||||
|
if (model->hasOutlineColor())
|
||||||
|
{
|
||||||
|
mSolidBrush->SetColor(toD2dColor(model->getOutlineColor()));
|
||||||
|
rt->DrawRoundedRectangle(rounded_rect, mSolidBrush.Get(), 1.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (model->getGeometry()->getType() == AbstractGeometricItem::Type::CIRCLE)
|
else if (model->getGeometry()->getType() == AbstractGeometricItem::Type::CIRCLE)
|
||||||
{
|
{
|
||||||
const auto loc = model->getTransform().getLocation();
|
const auto loc = model->getTransform().getLocation();
|
||||||
|
|
|
@ -30,28 +30,40 @@ void DirectXTextPainter::setD2dInterface(DirectX2dInterface* d2dIterface)
|
||||||
mD2dInterface->getRenderTarget()->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::Black), &mTextBrush);
|
mD2dInterface->getRenderTarget()->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::Black), &mTextBrush);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DirectXTextPainter::updateTextFormat(const FontItem& font)
|
void DirectXTextPainter::updateTextFormat(SceneText* text)
|
||||||
{
|
{
|
||||||
mD2dInterface->getDirectWriteFactory()->CreateTextFormat(
|
mD2dInterface->getDirectWriteFactory()->CreateTextFormat(
|
||||||
UnicodeUtils::utf8ToUtf16WString(font.getFaceName()).c_str(),
|
UnicodeUtils::utf8ToUtf16WString(text->getTextData().mFont.getFaceName()).c_str(),
|
||||||
nullptr,
|
nullptr,
|
||||||
DWRITE_FONT_WEIGHT_NORMAL,
|
DWRITE_FONT_WEIGHT_NORMAL,
|
||||||
DWRITE_FONT_STYLE_NORMAL,
|
DWRITE_FONT_STYLE_NORMAL,
|
||||||
DWRITE_FONT_STRETCH_NORMAL,
|
DWRITE_FONT_STRETCH_NORMAL,
|
||||||
static_cast<float>(font.getSize()),
|
static_cast<float>(text->getTextData().mFont.getSize()),
|
||||||
L"en-us",
|
L"en-us",
|
||||||
&mTextFormat
|
&mTextFormat
|
||||||
);
|
);
|
||||||
//mTextFormat->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_CENTER);
|
mTextFormat->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_CENTER);
|
||||||
//mTextFormat->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_CENTER);
|
mTextFormat->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_CENTER);
|
||||||
|
|
||||||
|
mTextBrush->SetColor(toD2dColor(text->getFillColor()));
|
||||||
|
}
|
||||||
|
|
||||||
|
D2D1::ColorF DirectXTextPainter::toD2dColor(const Color& color)
|
||||||
|
{
|
||||||
|
return D2D1::ColorF(static_cast<float>(color.getR() / 255.0), static_cast<float>(color.getG() / 255.0),
|
||||||
|
static_cast<float>(color.getB() / 255.0), static_cast<float>(color.getAlpha()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void DirectXTextPainter::paint(SceneText* text, DrawingContext* context)
|
void DirectXTextPainter::paint(SceneText* text, DrawingContext* context)
|
||||||
{
|
{
|
||||||
const auto location = text->getTransform().getLocation();
|
const auto location = text->getTransform().getLocation();
|
||||||
D2D1_RECT_F textRect = D2D1::RectF(static_cast<float>(location.getX()), static_cast<float>(location.getY()), static_cast<float>(location.getX() + 200), static_cast<float>(location.getY() + 100));
|
|
||||||
|
|
||||||
updateTextFormat(text->getTextData().mFont);
|
const auto width = static_cast<float>(text->getTextWidth());
|
||||||
|
const auto height = static_cast<float>(text->getTextHeight());
|
||||||
|
|
||||||
|
D2D1_RECT_F textRect = D2D1::RectF(static_cast<float>(location.getX()), static_cast<float>(location.getY()), static_cast<float>(location.getX() + width), static_cast<float>(location.getY() + height));
|
||||||
|
|
||||||
|
updateTextFormat(text);
|
||||||
|
|
||||||
auto content = UnicodeUtils::utf8ToUtf16WString(text->getTextData().mContent);
|
auto content = UnicodeUtils::utf8ToUtf16WString(text->getTextData().mContent);
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "FontItem.h"
|
#include "FontItem.h"
|
||||||
|
#include "Color.h"
|
||||||
|
|
||||||
#include <wrl.h>
|
#include <wrl.h>
|
||||||
#include <dwrite.h>
|
#include <dwrite.h>
|
||||||
|
@ -32,7 +33,9 @@ public:
|
||||||
void setD2dInterface(DirectX2dInterface* d2dIterface);
|
void setD2dInterface(DirectX2dInterface* d2dIterface);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateTextFormat(const FontItem& font);
|
void updateTextFormat(SceneText* text);
|
||||||
|
|
||||||
|
D2D1::ColorF toD2dColor(const Color& color);
|
||||||
|
|
||||||
DirectX2dInterface* mD2dInterface{ nullptr };
|
DirectX2dInterface* mD2dInterface{ nullptr };
|
||||||
Microsoft::WRL::ComPtr<ID2D1SolidColorBrush> mTextBrush;
|
Microsoft::WRL::ComPtr<ID2D1SolidColorBrush> mTextBrush;
|
||||||
|
|
|
@ -23,6 +23,8 @@ list(APPEND visual_elements_LIB_INCLUDES
|
||||||
svg/SvgReader.h
|
svg/SvgReader.h
|
||||||
svg/SvgShapeElement.h
|
svg/SvgShapeElement.h
|
||||||
svg/SvgElement.h
|
svg/SvgElement.h
|
||||||
|
svg/SvgTextElement.h
|
||||||
|
svg/SvgTextElement.cpp
|
||||||
svg/elements/SvgShapeElements.h
|
svg/elements/SvgShapeElements.h
|
||||||
svg/SvgDocument.cpp
|
svg/SvgDocument.cpp
|
||||||
svg/SvgReader.cpp
|
svg/SvgReader.cpp
|
||||||
|
|
|
@ -42,7 +42,7 @@ void RectangleNode::setWidth(double width)
|
||||||
{
|
{
|
||||||
if (mWidth != width)
|
if (mWidth != width)
|
||||||
{
|
{
|
||||||
mTransformIsDirty = true;
|
mGeometryIsDirty = true;
|
||||||
mWidth = width;
|
mWidth = width;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -51,7 +51,7 @@ void RectangleNode::setHeight(double height)
|
||||||
{
|
{
|
||||||
if (mHeight != height)
|
if (mHeight != height)
|
||||||
{
|
{
|
||||||
mTransformIsDirty = true;
|
mGeometryIsDirty = true;
|
||||||
mHeight = height;
|
mHeight = height;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,7 @@ void RectangleNode::createOrUpdateGeometry(SceneInfo* sceneInfo)
|
||||||
{
|
{
|
||||||
if (sceneInfo->mSupportsGeometryPrimitives)
|
if (sceneInfo->mSupportsGeometryPrimitives)
|
||||||
{
|
{
|
||||||
auto rect = std::make_unique<ntk::Rectangle>(Point{ 0, 0 }, 1, 1);
|
auto rect = std::make_unique<ntk::Rectangle>(Point{ 0, 0 }, mWidth, mHeight);
|
||||||
rect->setRadius(mRadius);
|
rect->setRadius(mRadius);
|
||||||
mBackgroundItem = std::make_unique<SceneModel>(std::move(rect));
|
mBackgroundItem = std::make_unique<SceneModel>(std::move(rect));
|
||||||
}
|
}
|
||||||
|
@ -87,7 +87,7 @@ void RectangleNode::createOrUpdateGeometry(SceneInfo* sceneInfo)
|
||||||
{
|
{
|
||||||
if (sceneInfo->mSupportsGeometryPrimitives)
|
if (sceneInfo->mSupportsGeometryPrimitives)
|
||||||
{
|
{
|
||||||
auto rect = std::make_unique<ntk::Rectangle>(Point{ 0, 0 }, 1, 1);
|
auto rect = std::make_unique<ntk::Rectangle>(Point{ 0, 0 }, mWidth, mHeight);
|
||||||
rect->setRadius(mRadius);
|
rect->setRadius(mRadius);
|
||||||
mBackgroundItem->updateGeometry(std::move(rect));
|
mBackgroundItem->updateGeometry(std::move(rect));
|
||||||
}
|
}
|
||||||
|
@ -96,5 +96,5 @@ void RectangleNode::createOrUpdateGeometry(SceneInfo* sceneInfo)
|
||||||
|
|
||||||
void RectangleNode::updateTransform()
|
void RectangleNode::updateTransform()
|
||||||
{
|
{
|
||||||
mBackgroundItem->updateTransform({ mLocation, mWidth, mHeight });
|
mBackgroundItem->updateTransform({ mLocation });
|
||||||
}
|
}
|
|
@ -161,7 +161,7 @@ void TextNode::update(SceneInfo* sceneInfo)
|
||||||
|
|
||||||
if (mContentIsDirty || mLinesAreDirty)
|
if (mContentIsDirty || mLinesAreDirty)
|
||||||
{
|
{
|
||||||
dynamic_cast<SceneText*>(mTextItem.get())->setTextData(mTextData);
|
mTextItem->setTextData(mTextData);
|
||||||
mContentIsDirty = false;
|
mContentIsDirty = false;
|
||||||
mLinesAreDirty = false;
|
mLinesAreDirty = false;
|
||||||
}
|
}
|
||||||
|
@ -169,6 +169,8 @@ void TextNode::update(SceneInfo* sceneInfo)
|
||||||
if (mTransformIsDirty)
|
if (mTransformIsDirty)
|
||||||
{
|
{
|
||||||
mTextItem->updateTransform({mLocation});
|
mTextItem->updateTransform({mLocation});
|
||||||
|
mTextItem->setTextWidth(mWidth);
|
||||||
|
mTextItem->setTextHeight(mHeight);
|
||||||
mTransformIsDirty = false;
|
mTransformIsDirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
#include "FontItem.h"
|
#include "FontItem.h"
|
||||||
#include "TextData.h"
|
#include "TextData.h"
|
||||||
|
#include "Bounds.h"
|
||||||
|
#include "SceneText.h"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -47,7 +49,7 @@ private:
|
||||||
double mWidth{1};
|
double mWidth{1};
|
||||||
double mHeight{1};
|
double mHeight{1};
|
||||||
|
|
||||||
std::unique_ptr<SceneItem> mTextItem;
|
std::unique_ptr<SceneText> mTextItem;
|
||||||
};
|
};
|
||||||
|
|
||||||
using TextNodetr = std::unique_ptr<TextNode>;
|
using TextNodetr = std::unique_ptr<TextNode>;
|
||||||
|
|
|
@ -23,3 +23,31 @@ void SceneText::setTextData(const TextData& data)
|
||||||
mTextData = data;
|
mTextData = data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double SceneText::getTextWidth() const
|
||||||
|
{
|
||||||
|
return mTextWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
double SceneText::getTextHeight() const
|
||||||
|
{
|
||||||
|
return mTextHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneText::setTextWidth(double width)
|
||||||
|
{
|
||||||
|
if (mTextWidth != width)
|
||||||
|
{
|
||||||
|
mTextWidth = width;
|
||||||
|
mTextGeometryIsDirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneText::setTextHeight(double height)
|
||||||
|
{
|
||||||
|
if (mTextHeight != height)
|
||||||
|
{
|
||||||
|
mTextHeight = height;
|
||||||
|
mTextGeometryIsDirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -10,11 +10,21 @@ public:
|
||||||
|
|
||||||
Type getType() const override;
|
Type getType() const override;
|
||||||
|
|
||||||
|
double getTextWidth() const;
|
||||||
|
|
||||||
|
double getTextHeight() const;
|
||||||
|
|
||||||
const TextData& getTextData() const;
|
const TextData& getTextData() const;
|
||||||
|
|
||||||
|
void setTextWidth(double width);
|
||||||
|
|
||||||
|
void setTextHeight(double height);
|
||||||
|
|
||||||
void setTextData(const TextData& content);
|
void setTextData(const TextData& content);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool mTextGeometryIsDirty{true};
|
bool mTextGeometryIsDirty{true};
|
||||||
TextData mTextData;
|
TextData mTextData;
|
||||||
|
double mTextWidth{ 0.0 };
|
||||||
|
double mTextHeight{ 0.0 };
|
||||||
};
|
};
|
||||||
|
|
53
src/rendering/visual_elements/svg/SvgTextElement.cpp
Normal file
53
src/rendering/visual_elements/svg/SvgTextElement.cpp
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
#include "SvgTextElement.h"
|
||||||
|
|
||||||
|
#include "XmlAttribute.h"
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
SvgTextElement::SvgTextElement()
|
||||||
|
:SvgElement("text")
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void SvgTextElement::setLocation(const Point& loc)
|
||||||
|
{
|
||||||
|
auto x = std::make_unique<XmlAttribute>("x");
|
||||||
|
auto y = std::make_unique<XmlAttribute>("y");
|
||||||
|
|
||||||
|
x->setValue(std::to_string(loc.getX()));
|
||||||
|
y->setValue(std::to_string(loc.getY()));
|
||||||
|
|
||||||
|
addAttribute(std::move(x));
|
||||||
|
addAttribute(std::move(y));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SvgTextElement::setContent(const std::string& content)
|
||||||
|
{
|
||||||
|
setText(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SvgTextElement::setFill(const Color& fill)
|
||||||
|
{
|
||||||
|
auto attr = std::make_unique<XmlAttribute>("fill");
|
||||||
|
|
||||||
|
std::stringstream sstr;
|
||||||
|
sstr << "rgb(" << fill.toString() << ")";
|
||||||
|
attr->setValue(sstr.str());
|
||||||
|
|
||||||
|
addAttribute(std::move(attr));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SvgTextElement::setFontFamily(const std::string& family)
|
||||||
|
{
|
||||||
|
auto attr = std::make_unique<XmlAttribute>("font-family");
|
||||||
|
attr->setValue(family);
|
||||||
|
addAttribute(std::move(attr));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SvgTextElement::setFontSize(float size)
|
||||||
|
{
|
||||||
|
auto attr = std::make_unique<XmlAttribute>("font-size");
|
||||||
|
attr->setValue(std::to_string(size));
|
||||||
|
addAttribute(std::move(attr));
|
||||||
|
}
|
21
src/rendering/visual_elements/svg/SvgTextElement.h
Normal file
21
src/rendering/visual_elements/svg/SvgTextElement.h
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "SvgElement.h"
|
||||||
|
#include "Point.h"
|
||||||
|
#include "Color.h"
|
||||||
|
|
||||||
|
class SvgTextElement : public SvgElement
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SvgTextElement();
|
||||||
|
|
||||||
|
void setLocation(const Point& loc);
|
||||||
|
|
||||||
|
void setContent(const std::string& content);
|
||||||
|
|
||||||
|
void setFill(const Color& fill);
|
||||||
|
|
||||||
|
void setFontFamily(const std::string& family);
|
||||||
|
|
||||||
|
void setFontSize(float size);
|
||||||
|
};
|
|
@ -124,6 +124,15 @@ void SvgRectangle::setHeight(double h)
|
||||||
addAttribute(std::move(height));
|
addAttribute(std::move(height));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SvgRectangle::setRadius(double radius)
|
||||||
|
{
|
||||||
|
auto rx = std::make_unique<XmlAttribute>("rx");
|
||||||
|
|
||||||
|
rx->setValue(std::to_string(radius));
|
||||||
|
|
||||||
|
addAttribute(std::move(rx));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
SvgPolygon::SvgPolygon()
|
SvgPolygon::SvgPolygon()
|
||||||
: SvgShapeElement("polygon")
|
: SvgShapeElement("polygon")
|
||||||
|
|
|
@ -43,6 +43,8 @@ public:
|
||||||
void setWidth(double width);
|
void setWidth(double width);
|
||||||
|
|
||||||
void setHeight(double height);
|
void setHeight(double height);
|
||||||
|
|
||||||
|
void setRadius(double radius);
|
||||||
};
|
};
|
||||||
|
|
||||||
class SvgPolygon : public SvgShapeElement
|
class SvgPolygon : public SvgShapeElement
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
#include "ThemeManager.h"
|
#include "ThemeManager.h"
|
||||||
#include "PaintEvent.h"
|
#include "PaintEvent.h"
|
||||||
|
|
||||||
|
#include "FontTokens.h"
|
||||||
|
|
||||||
#include "MouseEvent.h"
|
#include "MouseEvent.h"
|
||||||
#include "FileLogger.h"
|
#include "FileLogger.h"
|
||||||
|
|
||||||
|
@ -16,6 +18,10 @@ Button::Button(ButtonData::Component component)
|
||||||
{
|
{
|
||||||
mStyle.mComponent = component;
|
mStyle.mComponent = component;
|
||||||
mName = "Button";
|
mName = "Button";
|
||||||
|
|
||||||
|
setHeight(mStyle.getContainerHeight());
|
||||||
|
setMaxHeight(mStyle.getContainerHeight());
|
||||||
|
setRadius(mStyle.getContainerCornerRadius());
|
||||||
}
|
}
|
||||||
|
|
||||||
Button::~Button()
|
Button::~Button()
|
||||||
|
@ -66,7 +72,39 @@ void Button::setEnabled(bool isEnabled)
|
||||||
void Button::updateState()
|
void Button::updateState()
|
||||||
{
|
{
|
||||||
setBackground(mStyle.getContainerColor());
|
setBackground(mStyle.getContainerColor());
|
||||||
|
setBackgroundTone(mStyle.getContainerSurfaceTintColor());
|
||||||
|
setElevation(mStyle.getContainerElevation());
|
||||||
|
|
||||||
|
setLabelTextColor(mStyle.getLabelTextColor());
|
||||||
|
setLabelTextOpacity(mStyle.getLabelOpacity());
|
||||||
|
setLabelTextTypescale(mStyle.getLabelTypescale());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Button::setLabelTextColor(Theme::Sys::Color color)
|
||||||
|
{
|
||||||
|
if (mLabelTextColor != color)
|
||||||
|
{
|
||||||
|
mLabelTextColor = color;
|
||||||
|
mMaterialDirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Button::setLabelTextOpacity(float opacity)
|
||||||
|
{
|
||||||
|
if (mLabelOpacity != opacity)
|
||||||
|
{
|
||||||
|
mLabelOpacity = opacity;
|
||||||
|
mMaterialDirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Button::setLabelTextTypescale(Theme::Sys::Typescale typescale)
|
||||||
|
{
|
||||||
|
if (mLabelTextTypescale != typescale)
|
||||||
|
{
|
||||||
|
mLabelTextTypescale = typescale;
|
||||||
|
mMaterialDirty = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Button::onMyMouseEvent(const MouseEvent* event)
|
void Button::onMyMouseEvent(const MouseEvent* event)
|
||||||
|
@ -131,29 +169,31 @@ void Button::doPaint(const PaintEvent* event)
|
||||||
|
|
||||||
void Button::updateLabel(const PaintEvent* event)
|
void Button::updateLabel(const PaintEvent* event)
|
||||||
{
|
{
|
||||||
unsigned fontOffset = unsigned(mLabel.size()) * 4;
|
|
||||||
auto middle = DiscretePoint(mLocation.getX() + mSize.mWidth/2 - fontOffset, mLocation.getY() + mSize.mHeight/2 + 4);
|
|
||||||
|
|
||||||
if (!mTextNode)
|
if (!mTextNode)
|
||||||
{
|
{
|
||||||
mTextNode = TextNode::Create(mLabel, middle);
|
mTextNode = TextNode::Create(mLabel, mLocation);
|
||||||
mTextNode->setName(mName + "_TextNode");
|
mTextNode->setName(mName + "_TextNode");
|
||||||
mTextNode->setContent(mLabel);
|
mTextNode->setContent(mLabel);
|
||||||
mTextNode->setWidth(mSize.mWidth);
|
|
||||||
mTextNode->setHeight(mSize.mHeight);
|
|
||||||
mRootNode->addChild(mTextNode.get());
|
mRootNode->addChild(mTextNode.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mTransformDirty)
|
if (mTransformDirty)
|
||||||
{
|
{
|
||||||
mTextNode->setLocation(middle);
|
mTextNode->setLocation(mLocation);
|
||||||
mTextNode->setWidth(mSize.mWidth);
|
mTextNode->setWidth(mSize.mWidth);
|
||||||
mTextNode->setHeight(mSize.mHeight);
|
mTextNode->setHeight(mSize.mHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mMaterialDirty)
|
if (mMaterialDirty)
|
||||||
{
|
{
|
||||||
mTextNode->setFillColor(event->getThemesManager()->getColor(mBackground));
|
auto fill_color = event->getThemesManager()->getColor(mLabelTextColor);
|
||||||
|
fill_color.setAlpha(mLabelOpacity);
|
||||||
|
mTextNode->setFillColor(fill_color);
|
||||||
|
|
||||||
|
auto size = FontTokens::getSize(mLabelTextTypescale);
|
||||||
|
auto family = FontTokens::getFont(FontTokens::getFont(mLabelTextTypescale));
|
||||||
|
auto font_data = FontItem(family, static_cast<float>(size));
|
||||||
|
mTextNode->setFont(font_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mContentDirty)
|
if (mContentDirty)
|
||||||
|
|
|
@ -34,6 +34,10 @@ protected:
|
||||||
bool isDirty() const override;
|
bool isDirty() const override;
|
||||||
void doPaint(const PaintEvent* event) override;
|
void doPaint(const PaintEvent* event) override;
|
||||||
|
|
||||||
|
void setLabelTextColor(Theme::Sys::Color color);
|
||||||
|
void setLabelTextOpacity(float opacity);
|
||||||
|
void setLabelTextTypescale(Theme::Sys::Typescale typescale);
|
||||||
|
|
||||||
void updateLabel(const PaintEvent* event);
|
void updateLabel(const PaintEvent* event);
|
||||||
|
|
||||||
void setState(ButtonData::State state);
|
void setState(ButtonData::State state);
|
||||||
|
@ -44,6 +48,10 @@ private:
|
||||||
ButtonData mStyle;
|
ButtonData mStyle;
|
||||||
|
|
||||||
std::string mLabel;
|
std::string mLabel;
|
||||||
|
Theme::Sys::Color mLabelTextColor;
|
||||||
|
Theme::Sys::Typescale mLabelTextTypescale;
|
||||||
|
float mLabelOpacity{ 1.0 };
|
||||||
|
|
||||||
clickFunc mClickFunc;
|
clickFunc mClickFunc;
|
||||||
|
|
||||||
std::unique_ptr<TextNode> mTextNode;
|
std::unique_ptr<TextNode> mTextNode;
|
||||||
|
|
|
@ -218,6 +218,29 @@ float ButtonData::getStateLayerOverlayOpacity() const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float ButtonData::getLabelOpacity() const
|
||||||
|
{
|
||||||
|
if (auto iter = mLabelTextOpacity.find(std::make_pair(mComponent, mState)); iter != mLabelTextOpacity.end())
|
||||||
|
{
|
||||||
|
return iter->second;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (mState == State::Enabled)
|
||||||
|
{
|
||||||
|
return DEFAULT_CONTAINER_OPACITY;
|
||||||
|
}
|
||||||
|
else if (auto iter = mLabelTextOpacity.find(std::make_pair(mComponent, State::Enabled)); iter != mLabelTextOpacity.end())
|
||||||
|
{
|
||||||
|
return iter->second;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return DEFAULT_CONTAINER_OPACITY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Theme::Sys::Typescale ButtonData::getLabelTypescale() const
|
Theme::Sys::Typescale ButtonData::getLabelTypescale() const
|
||||||
{
|
{
|
||||||
switch (mComponent)
|
switch (mComponent)
|
||||||
|
|
|
@ -40,20 +40,21 @@ public:
|
||||||
Theme::Sys::Color getContainerShadowColor() const;
|
Theme::Sys::Color getContainerShadowColor() const;
|
||||||
Theme::Sys::Color getContainerSurfaceTintColor() const;
|
Theme::Sys::Color getContainerSurfaceTintColor() const;
|
||||||
Theme::Sys::Elevation getContainerElevation() const;
|
Theme::Sys::Elevation getContainerElevation() const;
|
||||||
|
float getStateLayerOverlayOpacity() const;
|
||||||
|
|
||||||
Theme::Sys::Color getLabelTextColor() const;
|
Theme::Sys::Color getLabelTextColor() const;
|
||||||
Theme::Sys::Typescale getLabelTypescale() const;
|
Theme::Sys::Typescale getLabelTypescale() const;
|
||||||
|
float getLabelOpacity() const;
|
||||||
|
|
||||||
bool canHaveIcon() const;
|
bool canHaveIcon() const;
|
||||||
Theme::Sys::Color getIconColor() const;
|
Theme::Sys::Color getIconColor() const;
|
||||||
|
|
||||||
float getStateLayerOverlayOpacity() const;
|
|
||||||
unsigned getContainerHeight() const;
|
unsigned getContainerHeight() const;
|
||||||
unsigned getContainerCornerRadius() const;
|
unsigned getContainerCornerRadius() const;
|
||||||
|
|
||||||
unsigned getIconSize() const;
|
unsigned getIconSize() const;
|
||||||
unsigned getLeftRightPadding() const;
|
|
||||||
|
|
||||||
|
unsigned getLeftRightPadding() const;
|
||||||
unsigned getLeftPaddingWithIcon() const;
|
unsigned getLeftPaddingWithIcon() const;
|
||||||
unsigned getRightPaddingWithIcon() const;
|
unsigned getRightPaddingWithIcon() const;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
#include "FontTokens.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
std::string FontTokens::getFont(Theme::Ref::Typeface::Font font)
|
||||||
|
{
|
||||||
|
switch (font)
|
||||||
|
{
|
||||||
|
case Theme::Ref::Typeface::Font::Brand:
|
||||||
|
return "Segoe UI";
|
||||||
|
case Theme::Ref::Typeface::Font::Plain:
|
||||||
|
return "Segoe UI";
|
||||||
|
default:
|
||||||
|
return "Segoe UI";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Theme::Ref::Typeface::Font FontTokens::getFont(Theme::Sys::Typescale typescale)
|
||||||
|
{
|
||||||
|
switch (typescale)
|
||||||
|
{
|
||||||
|
case Theme::Sys::Typescale::Label_Large:
|
||||||
|
return Theme::Ref::Typeface::Font::Brand;
|
||||||
|
default:
|
||||||
|
return Theme::Ref::Typeface::Font::Brand;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned FontTokens::getLineHeight(Theme::Sys::Typescale typescale)
|
||||||
|
{
|
||||||
|
switch (typescale)
|
||||||
|
{
|
||||||
|
case Theme::Sys::Typescale::Label_Large:
|
||||||
|
return 67;
|
||||||
|
default:
|
||||||
|
return 67;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned FontTokens::getSize(Theme::Sys::Typescale typescale)
|
||||||
|
{
|
||||||
|
switch (typescale)
|
||||||
|
{
|
||||||
|
case Theme::Sys::Typescale::Label_Large:
|
||||||
|
return static_cast<unsigned>(57/3);
|
||||||
|
default:
|
||||||
|
return 57;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned FontTokens::getTracking(Theme::Sys::Typescale typescale)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned FontTokens::getWeight(Theme::Ref::Typeface::Font font)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Theme::Ref::Typeface::Font FontTokens::getWeight(Theme::Sys::Typescale typescale)
|
||||||
|
{
|
||||||
|
return Theme::Ref::Typeface::Font::Brand;
|
||||||
|
}
|
|
@ -51,6 +51,7 @@ namespace Theme
|
||||||
|
|
||||||
class FontTokens
|
class FontTokens
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
static std::string getFont(Theme::Ref::Typeface::Font font);
|
static std::string getFont(Theme::Ref::Typeface::Font font);
|
||||||
|
|
||||||
static Theme::Ref::Typeface::Font getFont(Theme::Sys::Typescale typescale);
|
static Theme::Ref::Typeface::Font getFont(Theme::Sys::Typescale typescale);
|
||||||
|
|
|
@ -77,6 +77,25 @@ void BoxGeometry::setBounds(unsigned width, unsigned height)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BoxGeometry::setWidth(unsigned width)
|
||||||
|
{
|
||||||
|
setBounds(width, mSize.mHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BoxGeometry::setHeight(unsigned height)
|
||||||
|
{
|
||||||
|
setBounds(mSize.mWidth, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BoxGeometry::setMaxHeight(unsigned maxHieght)
|
||||||
|
{
|
||||||
|
if (mSize.mMaxHeight != maxHieght)
|
||||||
|
{
|
||||||
|
mTransformDirty = true;
|
||||||
|
mSize.mMaxHeight = maxHieght;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void BoxGeometry::setLocation(const DiscretePoint& loc)
|
void BoxGeometry::setLocation(const DiscretePoint& loc)
|
||||||
{
|
{
|
||||||
if (mLocation != loc)
|
if (mLocation != loc)
|
||||||
|
|
|
@ -59,6 +59,12 @@ public:
|
||||||
|
|
||||||
const DiscretePoint& getLocation() const;
|
const DiscretePoint& getLocation() const;
|
||||||
|
|
||||||
|
void setWidth(unsigned width);
|
||||||
|
|
||||||
|
void setHeight(unsigned height);
|
||||||
|
|
||||||
|
void setMaxHeight(unsigned maxHieght);
|
||||||
|
|
||||||
void setBounds(unsigned width, unsigned height);
|
void setBounds(unsigned width, unsigned height);
|
||||||
|
|
||||||
void setSize(const BoundedSize& size);
|
void setSize(const BoundedSize& size);
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
Widget::Widget()
|
Widget::Widget()
|
||||||
: BoxGeometry(),
|
: BoxGeometry(),
|
||||||
|
@ -73,6 +72,24 @@ void Widget::setBackground(Theme::Sys::Color token)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Widget::setBackgroundTone(Theme::Sys::Color token)
|
||||||
|
{
|
||||||
|
if (mBackgroundTone != token)
|
||||||
|
{
|
||||||
|
mBackgroundTone = token;
|
||||||
|
mMaterialDirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::setElevation(Theme::Sys::Elevation elevation)
|
||||||
|
{
|
||||||
|
if (mElevation != elevation)
|
||||||
|
{
|
||||||
|
mElevation = elevation;
|
||||||
|
mMaterialDirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Widget::setBackgroundOpacity(float opacity)
|
void Widget::setBackgroundOpacity(float opacity)
|
||||||
{
|
{
|
||||||
if (mBackgroundOpacity != opacity)
|
if (mBackgroundOpacity != opacity)
|
||||||
|
@ -173,6 +190,9 @@ void Widget::onPaintEvent(const PaintEvent* event)
|
||||||
}
|
}
|
||||||
|
|
||||||
doPaint(event);
|
doPaint(event);
|
||||||
|
mGeometryDirty = false;
|
||||||
|
mMaterialDirty = false;
|
||||||
|
mTransformDirty = false;
|
||||||
|
|
||||||
if (mVisibilityDirty)
|
if (mVisibilityDirty)
|
||||||
{
|
{
|
||||||
|
@ -293,32 +313,30 @@ void Widget::onMyMouseEvent(const MouseEvent* event)
|
||||||
|
|
||||||
void Widget::createOrUpdateGeometry()
|
void Widget::createOrUpdateGeometry()
|
||||||
{
|
{
|
||||||
|
const auto deltaX = mSize.mWidth - mMargin.mLeft - mMargin.mRight;
|
||||||
|
const auto deltaY = mSize.mHeight - mMargin.mTop - mMargin.mBottom;
|
||||||
if (!mBackgroundNode)
|
if (!mBackgroundNode)
|
||||||
{
|
{
|
||||||
unsigned locX = mLocation.getX() + mMargin.mLeft;
|
const auto locX = mLocation.getX() + mMargin.mLeft;
|
||||||
unsigned locY = mLocation.getY() + mMargin.mTop;
|
const auto locY = mLocation.getY() + mMargin.mTop;
|
||||||
unsigned deltaX = mSize.mWidth - mMargin.mLeft - mMargin.mRight;
|
|
||||||
unsigned deltaY = mSize.mHeight - mMargin.mTop - mMargin.mBottom;
|
|
||||||
|
|
||||||
mBackgroundNode = std::make_unique<RectangleNode>(DiscretePoint(locX, locY), deltaX, deltaY);
|
mBackgroundNode = std::make_unique<RectangleNode>(DiscretePoint(locX, locY), deltaX, deltaY);
|
||||||
|
mBackgroundNode->setRadius(mRadius);
|
||||||
|
|
||||||
mBackgroundNode->setName(mName + "_BackgroundNode");
|
mBackgroundNode->setName(mName + "_BackgroundNode");
|
||||||
mRootNode->addChild(mBackgroundNode.get());
|
mRootNode->addChild(mBackgroundNode.get());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
mBackgroundNode->setWidth(deltaX);
|
||||||
|
mBackgroundNode->setHeight(deltaY);
|
||||||
mBackgroundNode->setRadius(mRadius);
|
mBackgroundNode->setRadius(mRadius);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::updateTransform()
|
void Widget::updateTransform()
|
||||||
{
|
{
|
||||||
unsigned locX = mLocation.getX() + mMargin.mLeft;
|
const auto locX = mLocation.getX() + mMargin.mLeft;
|
||||||
unsigned locY = mLocation.getY() + mMargin.mTop;
|
const auto locY = mLocation.getY() + mMargin.mTop;
|
||||||
unsigned deltaX = mSize.mWidth - mMargin.mLeft - mMargin.mRight;
|
|
||||||
unsigned deltaY = mSize.mHeight - mMargin.mTop - mMargin.mBottom;
|
|
||||||
|
|
||||||
mBackgroundNode->setWidth(deltaX);
|
|
||||||
mBackgroundNode->setHeight(deltaY);
|
|
||||||
mBackgroundNode->setLocation(DiscretePoint(locX, locY));
|
mBackgroundNode->setLocation(DiscretePoint(locX, locY));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -326,9 +344,16 @@ void Widget::updateMaterial(const PaintEvent* event)
|
||||||
{
|
{
|
||||||
if (mBackground != Theme::Sys::Color::None)
|
if (mBackground != Theme::Sys::Color::None)
|
||||||
{
|
{
|
||||||
|
//if (mBackgroundTone == Theme::Sys::Color::None || mElevation == Theme::Sys::Elevation::Level_0)
|
||||||
|
//{
|
||||||
auto background_color = event->getThemesManager()->getColor(mBackground);
|
auto background_color = event->getThemesManager()->getColor(mBackground);
|
||||||
background_color.setAlpha(mBackgroundOpacity);
|
background_color.setAlpha(mBackgroundOpacity);
|
||||||
mBackgroundNode->setFillColor(background_color);
|
mBackgroundNode->setFillColor(background_color);
|
||||||
|
//}
|
||||||
|
//else
|
||||||
|
//{
|
||||||
|
//event->getThemesManager()->getColor(mBackground);
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -348,22 +373,14 @@ void Widget::updateMaterial(const PaintEvent* event)
|
||||||
|
|
||||||
void Widget::updateBackground(const PaintEvent* event)
|
void Widget::updateBackground(const PaintEvent* event)
|
||||||
{
|
{
|
||||||
unsigned locX = mLocation.getX() + mMargin.mLeft;
|
if (mGeometryDirty)
|
||||||
unsigned locY = mLocation.getY() + mMargin.mTop;
|
|
||||||
unsigned deltaX = mSize.mWidth - mMargin.mLeft - mMargin.mRight;
|
|
||||||
unsigned deltaY = mSize.mHeight - mMargin.mTop - mMargin.mBottom;
|
|
||||||
|
|
||||||
if (!mBackgroundNode)
|
|
||||||
{
|
{
|
||||||
mBackgroundNode = std::make_unique<RectangleNode>(DiscretePoint(locX, locY), deltaX, deltaY);
|
createOrUpdateGeometry();
|
||||||
mBackgroundNode->setName(mName + "_BackgroundNode");
|
|
||||||
mRootNode->addChild(mBackgroundNode.get());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mTransformDirty)
|
if (mTransformDirty)
|
||||||
{
|
{
|
||||||
updateTransform();
|
updateTransform();
|
||||||
mTransformDirty = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mMaterialDirty)
|
if (mMaterialDirty)
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "FontItem.h"
|
#include "FontItem.h"
|
||||||
#include "ITheme.h"
|
|
||||||
#include "WidgetState.h"
|
#include "WidgetState.h"
|
||||||
#include "BoxGeometry.h"
|
#include "BoxGeometry.h"
|
||||||
#include "TransformNode.h"
|
#include "TransformNode.h"
|
||||||
|
|
||||||
|
#include "ITheme.h"
|
||||||
|
#include "ElevationTokens.h"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -55,6 +57,10 @@ public:
|
||||||
|
|
||||||
void setBackground(Theme::Sys::Color token);
|
void setBackground(Theme::Sys::Color token);
|
||||||
|
|
||||||
|
void setBackgroundTone(Theme::Sys::Color token);
|
||||||
|
|
||||||
|
void setElevation(Theme::Sys::Elevation elevation);
|
||||||
|
|
||||||
void setOutlineThickness(double thickness);
|
void setOutlineThickness(double thickness);
|
||||||
|
|
||||||
void setOutline(Theme::Sys::Color token);
|
void setOutline(Theme::Sys::Color token);
|
||||||
|
@ -102,7 +108,9 @@ protected:
|
||||||
Theme::Sys::Color mBorder;
|
Theme::Sys::Color mBorder;
|
||||||
double mBorderThickness{0};
|
double mBorderThickness{0};
|
||||||
|
|
||||||
|
Theme::Sys::Color mBackgroundTone;
|
||||||
Theme::Sys::Color mBackground;
|
Theme::Sys::Color mBackground;
|
||||||
|
Theme::Sys::Elevation mElevation{ Theme::Sys::Elevation::Level_0 };
|
||||||
float mBackgroundOpacity{ 1.0 };
|
float mBackgroundOpacity{ 1.0 };
|
||||||
|
|
||||||
bool mVisible{true};
|
bool mVisible{true};
|
||||||
|
|
|
@ -5,25 +5,37 @@
|
||||||
#include "ThemeManager.h"
|
#include "ThemeManager.h"
|
||||||
#include "PaintEvent.h"
|
#include "PaintEvent.h"
|
||||||
|
|
||||||
|
#include "VerticalSpacer.h"
|
||||||
|
|
||||||
#include "Button.h"
|
#include "Button.h"
|
||||||
|
|
||||||
TEST_CASE(TestButton_Elevated, "ui_controls")
|
TEST_CASE(TestButton_Elevated, "ui_controls")
|
||||||
{
|
{
|
||||||
auto theme_manager = std::make_unique<ThemeManager>();
|
auto theme_manager = std::make_unique<ThemeManager>();
|
||||||
|
|
||||||
auto paint_event = PaintEvent::Create(theme_manager.get(), nullptr);
|
VerticalSpacer spacer;
|
||||||
|
spacer.setWidth(300);
|
||||||
|
spacer.setHeight(200);
|
||||||
|
|
||||||
Button button(ButtonData::Component::Elevated);
|
auto enabled_button = Button::Create(ButtonData::Component::Elevated);
|
||||||
button.setLabel("Enabled");
|
enabled_button->setLabel("Enabled");
|
||||||
|
|
||||||
button.onPaintEvent(paint_event.get());
|
auto disabled_button = Button::Create(ButtonData::Component::Elevated);
|
||||||
|
disabled_button->setEnabled(false);
|
||||||
|
disabled_button->setLabel("Disabled");
|
||||||
|
|
||||||
auto node = button.getRootNode();
|
spacer.addWidget(std::move(enabled_button));
|
||||||
|
spacer.addWidget(std::move(disabled_button));
|
||||||
|
|
||||||
|
auto node = spacer.getRootNode();
|
||||||
|
|
||||||
TestRenderer renderer;
|
TestRenderer renderer;
|
||||||
renderer.getScene()->addNode(node);
|
renderer.getScene()->addNode(node);
|
||||||
|
|
||||||
renderer.writeSvg(TestUtils::getTestOutputDir(__FILE__) / "Elevated_Enabled.svg");
|
auto paint_event = PaintEvent::Create(theme_manager.get(), nullptr);
|
||||||
renderer.write(TestUtils::getTestOutputDir(__FILE__) / "Elevated_Enabled.png");
|
spacer.onPaintEvent(paint_event.get());
|
||||||
|
|
||||||
|
renderer.writeSvg(TestUtils::getTestOutputDir(__FILE__) / "Elevated.svg");
|
||||||
|
renderer.write(TestUtils::getTestOutputDir(__FILE__) / "Elevated.png");
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue