More window cleaning

This commit is contained in:
James Grogan 2022-11-11 14:22:31 +00:00
parent 6adc441e6f
commit 53c98a227d
29 changed files with 422 additions and 261 deletions

View file

@ -21,22 +21,26 @@ std::unique_ptr<Button> Button::Create()
return std::make_unique<Button>();
}
void Button::SetOnClickFunction(clickFunc func)
void Button::setOnClickFunction(clickFunc func)
{
mClickFunc = func;
}
void Button::SetLabel(const std::string& text)
void Button::setLabel(const std::string& text)
{
mLabel = text;
if (text != mLabel)
{
mLabel = text;
mDirty = true;
}
}
void Button::OnMyMouseEvent(const MouseEvent* event)
void Button::onMyMouseEvent(const MouseEvent* event)
{
if(event->GetAction() == MouseEvent::Action::Pressed)
{
mCachedColor = *mBackgroundColor;
SetBackgroundColor(Color::Create(*mClickedColor));
setBackgroundColor(Color::Create(*mClickedColor));
if(mClickFunc)
{
mClickFunc(this);
@ -44,24 +48,39 @@ void Button::OnMyMouseEvent(const MouseEvent* event)
}
else if(event->GetAction() == MouseEvent::Action::Released)
{
SetBackgroundColor(Color::Create(mCachedColor));
setBackgroundColor(Color::Create(mCachedColor));
}
}
void Button::OnPaintEvent(const PaintEvent* event)
void Button::onPaintEvent(const PaintEvent* event)
{
mMyLayers.clear();
AddBackground(event);
if(!mLabel.empty())
if (!needsUpdate())
{
unsigned fontOffset = unsigned(mLabel.size()) * 4;
auto middle = DiscretePoint(mLocation.GetX() + mSize.mWidth/2 - fontOffset,
mLocation.GetY() + mSize.mHeight/2 + 4);
auto textLayer = VisualLayer::Create();
auto textElement = TextElement::Create(mLabel, middle);
textElement->SetFillColor(Color::Create(*mBackgroundColor));
textLayer->SetText(std::move(textElement));
mMyLayers.push_back(std::move(textLayer));
return;
}
CopyMyLayers();
mLayers.clear();
if (mDirty)
{
mMyLayers.clear();
if(!mVisible)
{
return;
}
addBackground(event);
if(!mLabel.empty())
{
unsigned fontOffset = unsigned(mLabel.size()) * 4;
auto middle = DiscretePoint(mLocation.GetX() + mSize.mWidth/2 - fontOffset, mLocation.GetY() + mSize.mHeight/2 + 4);
auto textLayer = VisualLayer::Create();
auto textElement = TextElement::Create(mLabel, middle);
textElement->SetFillColor(Color::Create(*mBackgroundColor));
textLayer->SetText(std::move(textElement));
mMyLayers.push_back(std::move(textLayer));
}
mDirty = false;
addMyLayers();
}
}

View file

@ -11,27 +11,27 @@ class MouseEvent;
class Button : public Widget
{
private:
using clickFunc = std::function<void(Widget* self)>;
std::string mLabel;
clickFunc mClickFunc;
Color mCachedColor;
ColorUPtr mClickedColor;
public:
using clickFunc = std::function<void(Widget* self)>;
Button();
static std::unique_ptr<Button> Create();
void SetLabel(const std::string& text);
void setLabel(const std::string& text);
void SetOnClickFunction(clickFunc func);
void OnPaintEvent(const PaintEvent* event) override;
void setOnClickFunction(clickFunc func);
protected:
void onMyMouseEvent(const MouseEvent* event) override;
void OnMyMouseEvent(const MouseEvent* event) override;
void onPaintEvent(const PaintEvent* event) override;
private:
std::string mLabel;
clickFunc mClickFunc;
Color mCachedColor;
ColorUPtr mClickedColor;
};
using ButtonUPtr = std::unique_ptr<Button>;

View file

@ -15,20 +15,19 @@ std::unique_ptr<HorizontalSpacer> HorizontalSpacer::Create()
return std::make_unique<HorizontalSpacer>();
}
void HorizontalSpacer::AddWidget(WidgetUPtr widget)
void HorizontalSpacer::addWidget(WidgetUPtr widget)
{
AddWidgetWithScale(std::move(widget), 1.0);
addWidgetWithScale(std::move(widget), 1.0);
}
void HorizontalSpacer::AddWidgetWithScale(WidgetUPtr widget, double scale)
void HorizontalSpacer::addWidgetWithScale(WidgetUPtr widget, double scale)
{
Widget::AddWidget(std::move(widget));
Widget::addWidget(std::move(widget));
mScales.push_back(scale);
}
void HorizontalSpacer::AddChildLayers(const PaintEvent* event)
void HorizontalSpacer::addChildLayers(const PaintEvent* event)
{
mLayers.clear();
double scaleSum = std::accumulate(mScales.begin(), mScales.end(), 0.0);
double offset = 0;
double height = mSize.mHeight;
@ -41,21 +40,27 @@ void HorizontalSpacer::AddChildLayers(const PaintEvent* event)
auto& child = mChildren[idx];
double scale = mScales[idx];
double delta = height * (scale/scaleSum);
auto size = child->GetSize();
auto size = child->getSize();
if (size.mMaxHeight > 0 && delta > size.mMaxHeight)
{
delta = size.mMaxHeight;
}
child->SetBounds(mSize.mWidth, unsigned(delta));
child->SetLocation(DiscretePoint(mLocation.GetX(), mLocation.GetY() + unsigned(offset)));
child->OnPaintEvent(event);
auto layers = child->GetLayers();
child->setBounds(mSize.mWidth, unsigned(delta));
child->setLocation(DiscretePoint(mLocation.GetX(), mLocation.GetY() + unsigned(offset)));
child->onPaintEvent(event);
auto layers = child->getLayers();
mLayers.insert(mLayers.end(), layers.begin(), layers.end());
offset += delta;
}
}
void HorizontalSpacer::OnPaintEvent(const PaintEvent* event)
void HorizontalSpacer::onPaintEvent(const PaintEvent* event)
{
AddChildLayers(event);
if (!needsUpdate())
{
return;
}
mLayers.clear();
addChildLayers(event);
}

View file

@ -12,13 +12,13 @@ public:
static std::unique_ptr<HorizontalSpacer> Create();
void AddWidget(WidgetUPtr widget) override;
void addWidget(WidgetUPtr widget) override;
void AddWidgetWithScale(WidgetUPtr widget, double scale);
void addWidgetWithScale(WidgetUPtr widget, double scale);
void AddChildLayers(const PaintEvent* event) override;
void addChildLayers(const PaintEvent* event) override;
void OnPaintEvent(const PaintEvent* event) override;
void onPaintEvent(const PaintEvent* event) override;
};
using HorizontalSpacerUPtr = std::unique_ptr<HorizontalSpacer>;

View file

@ -16,26 +16,42 @@ std::unique_ptr<Label> Label::Create()
return std::make_unique<Label>();
}
void Label::SetLabel(const std::string& text)
void Label::setLabel(const std::string& text)
{
mLabel = text;
}
void Label::OnPaintEvent(const PaintEvent* event)
{
mMyLayers.clear();
AddBackground(event);
if(!mLabel.empty())
if (text != mLabel)
{
unsigned fontOffset = unsigned(mLabel.size()) * 4;
auto middle = DiscretePoint(mLocation.GetX() + mSize.mWidth/2 - fontOffset,
mLocation.GetY() + mSize.mHeight/2 + 4);
auto textLayer = VisualLayer::Create();
auto textElement = TextElement::Create(mLabel, middle);
textElement->SetFillColor(Color::Create(*mBackgroundColor));
textLayer->SetText(std::move(textElement));
mMyLayers.push_back(std::move(textLayer));
mLabel = text;
mDirty = true;
}
}
void Label::onPaintEvent(const PaintEvent* event)
{
if (!needsUpdate())
{
return;
}
mLayers.clear();
if (mDirty)
{
mMyLayers.clear();
if(!mVisible)
{
return;
}
if(!mLabel.empty())
{
unsigned fontOffset = unsigned(mLabel.size()) * 4;
auto middle = DiscretePoint(mLocation.GetX() + mSize.mWidth/2 - fontOffset,
mLocation.GetY() + mSize.mHeight/2 + 4);
auto textLayer = VisualLayer::Create();
auto textElement = TextElement::Create(mLabel, middle);
textElement->SetFillColor(Color::Create(*mBackgroundColor));
textLayer->SetText(std::move(textElement));
mMyLayers.push_back(std::move(textLayer));
}
addMyLayers();
}
CopyMyLayers();
}

View file

@ -16,9 +16,9 @@ public:
static std::unique_ptr<Label> Create();
void SetLabel(const std::string& text);
void setLabel(const std::string& text);
void OnPaintEvent(const PaintEvent* event) override;
void onPaintEvent(const PaintEvent* event) override;
};
using LabelUPtr = std::unique_ptr<Label>;

View file

@ -16,11 +16,11 @@ void StackWidget::ShowChild(Widget* target)
{
if(child.get() == target)
{
child->SetVisible(true);
child->setVisible(true);
}
else
{
child->SetVisible(false);
child->setVisible(false);
}
}
}

View file

@ -36,7 +36,7 @@ void TextBox::AppendContent(const std::string& text)
mContent += text;
}
bool TextBox::OnMyKeyboardEvent(const KeyboardEvent* event)
bool TextBox::onMyKeyboardEvent(const KeyboardEvent* event)
{
if(!event) return false;
@ -72,10 +72,10 @@ bool TextBox::OnMyKeyboardEvent(const KeyboardEvent* event)
return true;
}
void TextBox::OnPaintEvent(const PaintEvent* event)
void TextBox::onPaintEvent(const PaintEvent* event)
{
mMyLayers.clear();
AddBackground(event);
addBackground(event);
double offset = 0;
if(!mContent.empty())
@ -99,5 +99,5 @@ void TextBox::OnPaintEvent(const PaintEvent* event)
offset += 20;
}
}
CopyMyLayers();
addMyLayers();
}

View file

@ -23,9 +23,9 @@ public:
void AppendContent(const std::string& text);
void OnPaintEvent(const PaintEvent* event) override;
void onPaintEvent(const PaintEvent* event) override;
bool OnMyKeyboardEvent(const KeyboardEvent* event) override;
bool onMyKeyboardEvent(const KeyboardEvent* event) override;
};
using TextBoxUPtr = std::unique_ptr<TextBox>;

View file

@ -15,18 +15,18 @@ std::unique_ptr<VerticalSpacer> VerticalSpacer::Create()
return std::make_unique<VerticalSpacer>();
}
void VerticalSpacer::AddWidget(WidgetUPtr widget)
void VerticalSpacer::addWidget(WidgetUPtr widget)
{
AddWidgetWithScale(std::move(widget), 1.0);
}
void VerticalSpacer::AddWidgetWithScale(WidgetUPtr widget, double scale)
{
Widget::AddWidget(std::move(widget));
Widget::addWidget(std::move(widget));
mScales.push_back(scale);
}
void VerticalSpacer::AddChildLayers(const PaintEvent* event)
void VerticalSpacer::addChildLayers(const PaintEvent* event)
{
mLayers.clear();
double scaleSum = std::accumulate(mScales.begin(), mScales.end(), 0.0);
@ -37,16 +37,16 @@ void VerticalSpacer::AddChildLayers(const PaintEvent* event)
auto& child = mChildren[idx];
double scale = mScales[idx];
double delta = mSize.mWidth * (scale/scaleSum);
child->SetBounds(unsigned(delta), mSize.mHeight);
child->SetLocation(DiscretePoint(mLocation.GetX() + unsigned(offset), mLocation.GetY()));
child->OnPaintEvent(event);
auto layers = child->GetLayers();
child->setBounds(unsigned(delta), mSize.mHeight);
child->setLocation(DiscretePoint(mLocation.GetX() + unsigned(offset), mLocation.GetY()));
child->onPaintEvent(event);
auto layers = child->getLayers();
mLayers.insert(mLayers.end(), layers.begin(), layers.end());
offset += delta;
}
}
void VerticalSpacer::OnPaintEvent(const PaintEvent* event)
void VerticalSpacer::onPaintEvent(const PaintEvent* event)
{
AddChildLayers(event);
addChildLayers(event);
}

View file

@ -11,13 +11,13 @@ public:
static std::unique_ptr<VerticalSpacer> Create();
void AddWidget(WidgetUPtr widget) override;
void addWidget(WidgetUPtr widget) override;
void AddWidgetWithScale(WidgetUPtr widget, double scale);
void AddChildLayers(const PaintEvent* event) override;
void addChildLayers(const PaintEvent* event) override;
void OnPaintEvent(const PaintEvent* event) override;
void onPaintEvent(const PaintEvent* event) override;
};
using VerticalSpacerUPtr = std::unique_ptr<VerticalSpacer>;

View file

@ -10,6 +10,7 @@
#include <algorithm>
#include <iterator>
#include <iostream>
Widget::Widget()
: mLocation(DiscretePoint(0, 0)),
@ -37,52 +38,102 @@ std::unique_ptr<Widget> Widget::Create()
return std::make_unique<Widget>();
}
void Widget::AddWidget(WidgetUPtr widget)
void Widget::addWidget(WidgetUPtr widget)
{
mChildren.push_back(std::move(widget));
}
Widget::BoundedSize Widget::GetSize() const
Widget::BoundedSize Widget::getSize() const
{
return mSize;
}
DiscretePoint Widget::GetLocation() const
DiscretePoint Widget::getLocation() const
{
return mLocation;
}
std::vector<VisualLayer*> Widget::GetLayers() const
std::vector<VisualLayer*> Widget::getLayers() const
{
return mLayers;
}
void Widget::SetSize(const BoundedSize& size)
void Widget::setSize(const BoundedSize& size)
{
mSize = size;
if (size != mSize)
{
mSize = size;
mDirty = true;
}
}
void Widget::SetMargin(unsigned margin)
void Widget::setMargin(unsigned margin)
{
mMargin = {margin, margin, margin, margin};
setMargin({margin, margin, margin, margin});
}
void Widget::SetMargin(const BoundaryOffset& margin)
void Widget::setMargin(const BoundaryOffset& margin)
{
mMargin = margin;
if (margin != mMargin)
{
mMargin = margin;
mDirty = true;
}
}
void Widget::SetPadding(unsigned padding)
void Widget::setPadding(unsigned padding)
{
mPadding = {padding, padding, padding, padding};
setPadding({padding, padding, padding, padding});
}
void Widget::SetPadding(const BoundaryOffset& padding)
void Widget::setPadding(const BoundaryOffset& padding)
{
mPadding = padding;
if (padding != mPadding)
{
mPadding = padding;
mDirty = true;
}
}
void Widget::CopyMyLayers()
void Widget::setBounds(unsigned width, unsigned height)
{
if (width != mSize.mWidth || height != mSize.mHeight)
{
mDirty = true;
}
mSize.mWidth = width;
mSize.mHeight = height;
}
void Widget::setBackgroundColor(ColorUPtr color)
{
if (mBackgroundColor != color)
{
mBackgroundColor = std::move(color);
mDirty = true;
}
}
void Widget::setLocation(const DiscretePoint& loc)
{
if (mLocation != loc)
{
mLocation = loc;
mDirty = true;
}
}
void Widget::setVisible(bool visible)
{
if (mVisible != visible)
{
mDirty = true;
}
mVisible = visible;
}
void Widget::addMyLayers()
{
mLayers.clear();
mLayers.reserve(mMyLayers.size());
@ -90,73 +141,107 @@ void Widget::CopyMyLayers()
std::transform(mMyLayers.begin(), mMyLayers.end(), std::back_inserter(mLayers), getRaw);
}
void Widget::SetBounds(unsigned width, unsigned height)
{
mSize.mWidth = width;
mSize.mHeight = height;
}
void Widget::AddChildLayers(const PaintEvent* event)
void Widget::addChildLayers(const PaintEvent* event)
{
for(auto& child: mChildren)
{
child->SetBounds(mSize.mWidth, mSize.mHeight);
child->SetLocation(mLocation);
child->OnPaintEvent(event);
const auto layers = child->GetLayers();
child->setBounds(mSize.mWidth, mSize.mHeight);
child->setLocation(mLocation);
child->onPaintEvent(event);
const auto layers = child->getLayers();
mLayers.insert(mLayers.end(), layers.begin(), layers.end());
}
}
void Widget::OnPaintEvent(const PaintEvent* event)
bool Widget::needsUpdate() const
{
mMyLayers.clear();
mLayers.clear();
if(!mVisible)return;
AddBackground(event);
CopyMyLayers();
AddChildLayers(event);
if (mDirty)
{
return true;
}
for(auto& child: mChildren)
{
if (child->needsUpdate())
{
return true;
}
}
return false;
}
bool Widget::Contains(const DiscretePoint& loc) const
void Widget::onPaintEvent(const PaintEvent* event)
{
if(loc.GetX() < mLocation.GetX()) return false;
if(loc.GetX() > mLocation.GetX() + mSize.mWidth) return false;
if(loc.GetY() > mLocation.GetY() + mSize.mHeight) return false;
if(loc.GetY() < mLocation.GetY()) return false;
if (!needsUpdate())
{
return;
}
mLayers.clear();
if (mDirty)
{
mMyLayers.clear();
if(!mVisible)
{
return;
}
addBackground(event);
mDirty = false;
}
addMyLayers();
addChildLayers(event);
}
bool Widget::contains(const DiscretePoint& loc) const
{
if(loc.GetX() < mLocation.GetX())
{
return false;
}
if(loc.GetX() > mLocation.GetX() + mSize.mWidth)
{
return false;
}
if(loc.GetY() > mLocation.GetY() + mSize.mHeight)
{
return false;
}
if(loc.GetY() < mLocation.GetY())
{
return false;
}
return true;
}
bool Widget::OnKeyboardEvent(const KeyboardEvent* event)
bool Widget::onKeyboardEvent(const KeyboardEvent* event)
{
bool inChild = false;
for(const auto& child : mChildren)
{
if(child->OnKeyboardEvent(event))
if(child->onKeyboardEvent(event))
{
inChild = true;
break;
}
}
if(!inChild)
{
return OnMyKeyboardEvent(event);
return onMyKeyboardEvent(event);
}
return true;
}
bool Widget::OnMyKeyboardEvent(const KeyboardEvent* event)
bool Widget::onMyKeyboardEvent(const KeyboardEvent* event)
{
return false;
}
bool Widget::OnMouseEvent(const MouseEvent* event)
bool Widget::onMouseEvent(const MouseEvent* event)
{
bool inChild = false;
for(const auto& child : mChildren)
{
if(child->OnMouseEvent(event))
if(child->onMouseEvent(event))
{
inChild = true;
break;
@ -164,9 +249,9 @@ bool Widget::OnMouseEvent(const MouseEvent* event)
}
if(!inChild)
{
if(Contains(event->GetClientLocation()))
if(contains(event->GetClientLocation()))
{
OnMyMouseEvent(event);
onMyMouseEvent(event);
return true;
}
else
@ -177,36 +262,27 @@ bool Widget::OnMouseEvent(const MouseEvent* event)
return true;
}
void Widget::OnMyMouseEvent(const MouseEvent* event)
void Widget::onMyMouseEvent(const MouseEvent* event)
{
}
void Widget::AddBackground(const PaintEvent* event)
void Widget::addBackground(const PaintEvent* event)
{
unsigned locX = mLocation.GetX() + mMargin.mLeft;
unsigned locY = mLocation.GetY() + mMargin.mTop;
unsigned deltaX = mSize.mWidth - mMargin.mLeft - mMargin.mRight;
unsigned deltaY = mSize.mHeight - mMargin.mTop - mMargin.mBottom;
auto shape = RectangleElement::Create(DiscretePoint(locX, locY),
deltaX, deltaY);
shape->SetFillColor(Color::Create(*mBackgroundColor));
auto shape = RectangleElement::Create(DiscretePoint(locX, locY), deltaX, deltaY);
std::cout << "Adding shape at : " << locX << " | " << locY << std::endl;
std::cout << "Has dimensions : " << deltaX << " | " << deltaY << std::endl;
auto color = Color::Create(*mBackgroundColor);
std::cout << "Has color : " << color->GetR() << " | " << color->GetG() << " | " << color->GetB() << " | " << color->GetAlpha() << std::endl;
shape->SetFillColor(std::move(color));
auto shapeLayer = VisualLayer::Create();
shapeLayer->SetShape(std::move(shape));
mMyLayers.push_back(std::move(shapeLayer));
}
void Widget::SetBackgroundColor(ColorUPtr color)
{
mBackgroundColor = std::move(color);
}
void Widget::SetLocation(const DiscretePoint& loc)
{
mLocation = loc;
}
void Widget::SetVisible(bool visible)
{
mVisible = visible;
}

View file

@ -15,14 +15,42 @@ class Color;
class Widget
{
public:
struct BoundaryOffset{
struct BoundaryOffset
{
bool operator==(const BoundaryOffset& rhs) const
{
return (mLeft == rhs.mLeft)
&& (mRight == rhs.mRight)
&& (mTop == rhs.mTop)
&& (mBottom == rhs.mBottom);
}
bool operator!=(const BoundaryOffset& rhs) const
{
return !operator==(rhs);
}
unsigned mLeft = 0;
unsigned mRight = 0;
unsigned mTop = 0;
unsigned mBottom = 0;
};
struct BoundedSize{
struct BoundedSize
{
bool operator==(const BoundedSize& rhs) const
{
return (mWidth == rhs.mWidth)
&& (mMaxWidth == rhs.mMaxWidth)
&& (mMinWidth == rhs.mMinWidth)
&& (mHeight == rhs.mHeight)
&& (mMaxHeight == rhs.mMaxHeight)
&& (mMinHeight == rhs.mMinHeight);
}
bool operator!=(const BoundedSize& rhs) const
{
return !operator==(rhs);
}
unsigned mWidth = 0;
unsigned mMaxWidth = 0;
unsigned mMinWidth = 0;
@ -31,19 +59,6 @@ public:
unsigned mMinHeight = 0;
};
protected:
DiscretePoint mLocation;
BoundedSize mSize;
BoundaryOffset mPadding;
BoundaryOffset mMargin;
std::vector<std::unique_ptr<VisualLayer> > mMyLayers;
std::vector<VisualLayer*> mLayers;
std::vector<std::unique_ptr<Widget> > mChildren;
unsigned mBorderThickness;
std::unique_ptr<Color> mBackgroundColor;
std::unique_ptr<Color> mBorderColor;
bool mVisible;
public:
Widget();
@ -52,51 +67,66 @@ public:
static std::unique_ptr<Widget> Create();
virtual void AddWidget(std::unique_ptr<Widget> widget);
virtual void addWidget(std::unique_ptr<Widget> widget);
BoundedSize GetSize() const;
BoundedSize getSize() const;
std::vector<VisualLayer*> GetLayers() const;
std::vector<VisualLayer*> getLayers() const;
DiscretePoint GetLocation() const;
DiscretePoint getLocation() const;
virtual void OnPaintEvent(const PaintEvent* event);
virtual void onPaintEvent(const PaintEvent* event);
virtual bool OnMouseEvent(const MouseEvent* event);
virtual bool onMouseEvent(const MouseEvent* event);
virtual bool OnKeyboardEvent(const KeyboardEvent* event);
virtual bool onKeyboardEvent(const KeyboardEvent* event);
bool Contains(const DiscretePoint& loc) const;
bool contains(const DiscretePoint& loc) const;
void SetBackgroundColor(std::unique_ptr<Color> color);
void setBackgroundColor(std::unique_ptr<Color> color);
void SetBounds(unsigned width, unsigned height);
void setBounds(unsigned width, unsigned height);
void SetSize(const BoundedSize& size);
void setSize(const BoundedSize& size);
void SetMargin(unsigned margin);
void setMargin(unsigned margin);
void SetMargin(const BoundaryOffset& margin);
void setMargin(const BoundaryOffset& margin);
void SetPadding(unsigned padding);
void setPadding(unsigned padding);
void SetPadding(const BoundaryOffset& padding);
void setPadding(const BoundaryOffset& padding);
void SetLocation(const DiscretePoint& loc);
void setLocation(const DiscretePoint& loc);
void SetVisible(bool visible);
void setVisible(bool visible);
protected:
virtual bool onMyKeyboardEvent(const KeyboardEvent* event);
virtual bool OnMyKeyboardEvent(const KeyboardEvent* event);
virtual void onMyMouseEvent(const MouseEvent* event);
virtual void OnMyMouseEvent(const MouseEvent* event);
virtual void addChildLayers(const PaintEvent* event);
virtual void AddChildLayers(const PaintEvent* event);
virtual void addBackground(const PaintEvent* event);
virtual void AddBackground(const PaintEvent* event);
void addMyLayers();
void CopyMyLayers();
bool needsUpdate() const;
protected:
DiscretePoint mLocation;
BoundedSize mSize;
BoundaryOffset mPadding;
BoundaryOffset mMargin;
std::vector<std::unique_ptr<VisualLayer> > mMyLayers;
std::vector<VisualLayer*> mLayers;
std::vector<std::unique_ptr<Widget> > mChildren;
unsigned mBorderThickness{0};
std::unique_ptr<Color> mBackgroundColor;
std::unique_ptr<Color> mBorderColor;
bool mVisible{false};
bool mDirty{true};
};
using WidgetUPtr = std::unique_ptr<Widget>;