Convert visual layers to scene nodes.

This commit is contained in:
James Grogan 2022-11-16 15:06:08 +00:00
parent 798cb365d7
commit 3e53bd9e00
64 changed files with 863 additions and 551 deletions

View file

@ -4,9 +4,11 @@
#include "MouseEvent.h"
#include "KeyboardEvent.h"
#include "PaintEvent.h"
#include "VisualLayer.h"
#include "AbstractVisualNode.h"
#include "TextNode.h"
#include "Color.h"
#include "TransformNode.h"
#include "RootNode.h"
#include <algorithm>
#include <iterator>
@ -17,8 +19,7 @@ Widget::Widget()
mSize({100, 0, 0, 100, 0, 0}),
mPadding(),
mMargin(),
mMyLayers(),
mLayers(),
mRootNode(std::make_unique<TransformNode>()),
mChildren(),
mBorderThickness(0),
mBackgroundColor(Color(255, 255, 255)),
@ -40,6 +41,7 @@ std::unique_ptr<Widget> Widget::Create()
void Widget::addWidget(WidgetUPtr widget)
{
mPendingChildNodes.push_back(widget->getRootNode());
mChildren.push_back(std::move(widget));
}
@ -53,9 +55,9 @@ const DiscretePoint& Widget::getLocation() const
return mLocation;
}
std::vector<VisualLayer*> Widget::getLayers() const
TransformNode* Widget::getRootNode() const
{
return mLayers;
return mRootNode.get();
}
void Widget::setSize(const BoundedSize& size)
@ -63,7 +65,7 @@ void Widget::setSize(const BoundedSize& size)
if (size != mSize)
{
mSize = size;
mDirty = true;
mTransformDirty = true;
}
}
@ -77,7 +79,7 @@ void Widget::setMargin(const BoundaryOffset& margin)
if (margin != mMargin)
{
mMargin = margin;
mDirty = true;
mTransformDirty = true;
}
}
@ -91,7 +93,7 @@ void Widget::setPadding(const BoundaryOffset& padding)
if (padding != mPadding)
{
mPadding = padding;
mDirty = true;
mTransformDirty = true;
}
}
@ -99,7 +101,7 @@ void Widget::setBounds(unsigned width, unsigned height)
{
if (width != mSize.mWidth || height != mSize.mHeight)
{
mDirty = true;
mTransformDirty = true;
mSize.mWidth = width;
mSize.mHeight = height;
}
@ -110,7 +112,7 @@ void Widget::setBackgroundColor(const Color& color)
if (mBackgroundColor != color)
{
mBackgroundColor = std::move(color);
mDirty = true;
mMaterialDirty = true;
}
}
@ -119,7 +121,7 @@ void Widget::setLocation(const DiscretePoint& loc)
if (mLocation != loc)
{
mLocation = loc;
mDirty = true;
mTransformDirty = true;
}
}
@ -127,35 +129,19 @@ void Widget::setVisible(bool visible)
{
if (mVisible != visible)
{
mDirty = true;
mVisibilityDirty = true;
}
mVisible = visible;
}
void Widget::addMyLayers()
bool Widget::isDirty() const
{
mLayers.clear();
mLayers.reserve(mMyLayers.size());
auto getRaw = [](const VisualLayerUPtr& uptr){return uptr.get();};
std::transform(mMyLayers.begin(), mMyLayers.end(), std::back_inserter(mLayers), getRaw);
}
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();
mLayers.insert(mLayers.end(), layers.begin(), layers.end());
}
return mTransformDirty || mMaterialDirty || mVisibilityDirty || mPendingChildNodes.size() > 0;
}
bool Widget::needsUpdate() const
{
if (mDirty)
if (isDirty())
{
return true;
}
@ -169,26 +155,48 @@ bool Widget::needsUpdate() const
return false;
}
void Widget::doPaint(const PaintEvent* event)
{
updateBackground(event);
}
void Widget::onPaintEvent(const PaintEvent* event)
{
if (!needsUpdate())
{
return;
}
mLayers.clear();
if (mDirty)
if (isDirty())
{
mMyLayers.clear();
if(!mVisible)
{
return;
}
addBackground(event);
mDirty = false;
doPaint(event);
mTransformDirty = false;
mMaterialDirty = false;
mVisibilityDirty = false;
}
for (auto node : mPendingChildNodes)
{
mRootNode->addChild(node);
}
mPendingChildNodes.clear();
updateChildLocations();
for(auto& child: mChildren)
{
child->onPaintEvent(event);
}
}
void Widget::updateChildLocations()
{
for(auto& child: mChildren)
{
child->setBounds(mSize.mWidth, mSize.mHeight);
child->setLocation(mLocation);
}
addMyLayers();
addChildLayers(event);
}
bool Widget::contains(const DiscretePoint& loc) const
@ -267,16 +275,32 @@ void Widget::onMyMouseEvent(const MouseEvent* event)
}
void Widget::addBackground(const PaintEvent* event)
void Widget::updateBackground(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 node = RectangleNode::Create(DiscretePoint(locX, locY), deltaX, deltaY);
node->setFillColor(mBackgroundColor);
auto layer = VisualLayer::Create();
layer->setShapeNode(std::move(node));
mMyLayers.push_back(std::move(layer));
if (!mBackgroundNode)
{
mRootNode->addChild(mBackgroundNode.get());
}
if (mTransformDirty)
{
mBackgroundNode->setWidth(deltaX);
mBackgroundNode->setHeight(deltaY);
mBackgroundNode->setLocation(DiscretePoint(locX, locY));
}
if (mMaterialDirty)
{
mBackgroundNode->setFillColor(mBackgroundColor);
}
if (mVisibilityDirty)
{
mBackgroundNode->setIsVisible(mVisible);
}
}