Start adding grid

This commit is contained in:
James Grogan 2022-11-17 17:33:48 +00:00
parent 9301769d58
commit f04d86e0ad
37 changed files with 709 additions and 211 deletions

View file

@ -6,6 +6,7 @@ list(APPEND client_HEADERS
text_editor/PlainTextDocument.h
audio_editor/AudioEditorView.h
image_editor/ImageEditorView.h
image_editor/ImageViewWidget.h
web_client/WebClientView.h)
@ -16,6 +17,7 @@ list(APPEND client_LIB_INCLUDES
text_editor/PlainTextDocument.cpp
audio_editor/AudioEditorView.cpp
image_editor/ImageEditorView.cpp
image_editor/ImageViewWidget.cpp
web_client/WebClientView.cpp
MediaTool.cpp)

View file

@ -1,14 +1,14 @@
#include "AudioEditorView.h"
#include "Label.h"
#include "Color.h"
#include "TextNode.h"
#include "Theme.h"
AudioEditorView::AudioEditorView()
{
auto label = Label::Create();
label->setLabel("audio Editor");
label->setBackgroundColor(Color(200, 189, 160));
label->setBackgroundColor(Theme::getBackgroundPrimary());
label->setMargin(1);
addWidget(std::move(label));
}

View file

@ -3,14 +3,25 @@
#include "Label.h"
#include "Color.h"
#include "TextNode.h"
#include "Theme.h"
#include "ImageViewWidget.h"
#include "HorizontalSpacer.h"
ImageEditorView::ImageEditorView()
{
auto label = Label::Create();
label->setLabel("Image Editor");
label->setBackgroundColor(Color(200, 189, 160));
label->setBackgroundColor(Theme::getBackgroundPrimary());
label->setMargin(1);
addWidget(std::move(label));
auto image_widget = std::make_unique<ImageViewWidget>();
auto hSpacer = HorizontalSpacer::Create();
hSpacer->addWidgetWithScale(std::move(label), 1);
hSpacer->addWidgetWithScale(std::move(image_widget), 14);
addWidget(std::move(hSpacer));
}
std::unique_ptr<ImageEditorView> ImageEditorView::Create()

View file

@ -0,0 +1,32 @@
#include "ImageViewWidget.h"
#include "GridNode.h"
#include "TransformNode.h"
#include <iostream>
ImageViewWidget::ImageViewWidget()
{
mName = "ImageViewWidget";
}
void ImageViewWidget::doPaint(const PaintEvent* event)
{
if (!mVisible)
{
return;
}
if (!mGridNode)
{
std::cout << "Setting up grid node" << std::endl;
mGridNode = std::make_unique<GridNode>(mLocation);
mGridNode->setName(mName + "_GridNode");
mGridNode->setNumX(mNumX);
mGridNode->setNumY(mNumY);
mGridNode->setWidth(mSize.mWidth);
mGridNode->setHeight(mSize.mHeight);
mRootNode->addChild(mGridNode.get());
}
}

View file

@ -0,0 +1,18 @@
#pragma once
#include "Widget.h"
#include "GridNode.h"
class ImageViewWidget : public Widget
{
public:
ImageViewWidget();
private:
void doPaint(const PaintEvent* event) override;
unsigned mNumX{5};
unsigned mNumY{5};
std::unique_ptr<GridNode> mGridNode;
};

View file

@ -1,6 +1,10 @@
#include "HorizontalSpacer.h"
#include "TextEditorView.h"
#include "HorizontalSpacer.h"
#include "VerticalSpacer.h"
#include "Theme.h"
#include "TextNode.h"
#include <iostream>
@ -21,7 +25,7 @@ void TextEditorView::Initialize()
{
auto label = Label::Create();
label->setLabel("Text Editor");
label->setBackgroundColor(Color(181, 189, 200));
label->setBackgroundColor(Theme::getBannerBackground());
label->setMargin(1);
auto textBox = TextBox::Create();
@ -30,7 +34,7 @@ void TextEditorView::Initialize()
auto saveButton = Button::Create();
saveButton->setLabel("Save");
saveButton->setBackgroundColor(Color(200, 200, 200));
saveButton->setBackgroundColor(Theme::getButtonPrimaryBackground());
saveButton->setMargin(2);
auto onSave = [this](Widget* self){
if(this && mController && mTextBox)
@ -43,7 +47,7 @@ void TextEditorView::Initialize()
auto clearButton = Button::Create();
clearButton->setLabel("Clear");
clearButton->setBackgroundColor(Color(200, 200, 200));
clearButton->setBackgroundColor(Theme::getButtonPrimaryBackground());
clearButton->setMargin(2);
auto onClear = [this](Widget* self){
if(this && mController && mTextBox)
@ -56,7 +60,7 @@ void TextEditorView::Initialize()
auto loadButton = Button::Create();
loadButton->setLabel("Load");
loadButton->setBackgroundColor(Color(200, 200, 200));
loadButton->setBackgroundColor(Theme::getButtonPrimaryBackground());
loadButton->setMargin(2);
auto onLoad = [this](Widget* self){
if(this && mController && mTextBox)

View file

@ -1,14 +1,16 @@
#include "WebClientView.h"
#include "Label.h"
#include "Color.h"
#include "TextNode.h"
#include "Theme.h"
WebClientView::WebClientView()
{
auto label = Label::Create();
label->setLabel("Web Client");
label->setBackgroundColor(Color(200, 189, 160));
label->setBackgroundColor(Theme::getBackgroundPrimary());
label->setMargin(1);
addWidget(std::move(label));
}

View file

@ -33,6 +33,12 @@ public:
double getDeltaY(const Point& point) const;
void scale(double x, double y)
{
mX = x*mX;
mY = y*mY;
}
bool operator==(const Point& rhs) const
{
return (mX == rhs.mX)

View file

@ -87,6 +87,7 @@ void OpenGlMeshPainter::paint(SceneModel* model, DrawingContext* context)
const auto height = float(surface->getHeight());
auto mesh = dynamic_cast<TriMesh*>(model->getMesh());
std::cout << "Paint mesh for model " << model->getName() << std::endl;
auto transform = model->getTransform();
@ -97,6 +98,7 @@ void OpenGlMeshPainter::paint(SceneModel* model, DrawingContext* context)
{
auto x = vertices[idx]*transform.getScaleX() + transform.getLocation().getX();
vertices[idx] = 2*x/width - 1.0;
std::cout << "Vert x is " << vertices[idx] << std::endl;
}
else if(idx%3 == 1)
{
@ -108,6 +110,7 @@ void OpenGlMeshPainter::paint(SceneModel* model, DrawingContext* context)
const auto indices = mesh->getFaceNodeIds();
auto model_color = model->getColor().getAsVectorDouble();
std::cout << "Color is " << model_color[0] << "|" << model_color[0] << std::endl;
std::vector<float> color = {float(model_color[0]), float(model_color[1]), float(model_color[2]), float(model_color[3])};
paint(vertices, indices, color);

22
src/mesh/AbstractFace.cpp Normal file
View file

@ -0,0 +1,22 @@
#include "AbstractFace.h"
AbstractFace::AbstractFace(unsigned id)
: mId(id)
{
}
void AbstractFace::addVectorAttribute(const std::string& tag, const std::vector<double>& values)
{
mVectorAttributes[tag] = values;
}
std::vector<double> AbstractFace::getVectorAttribute(const std::string& tag) const
{
auto iter = mVectorAttributes.find(tag);
if (iter != mVectorAttributes.end())
{
return iter->second;
}
return {};
}

24
src/mesh/AbstractFace.h Normal file
View file

@ -0,0 +1,24 @@
#pragma once
#include <memory>
#include <vector>
#include <unordered_map>
#include <string>
class AbstractFace
{
public:
AbstractFace(unsigned id=0);
virtual ~AbstractFace() = default;
virtual std::vector<unsigned> getNodeIds() const = 0;
void addVectorAttribute(const std::string& tag, const std::vector<double>& values);
std::vector<double> getVectorAttribute(const std::string& tag) const;
protected:
unsigned mId{0};
std::unordered_map<std::string, std::vector<double> > mVectorAttributes;
};

View file

@ -0,0 +1,40 @@
#include "AbstractMesh.h"
void AbstractMesh::addConstantNodeVectorAttribute(const std::string& tag, const std::vector<double>& values)
{
}
std::vector<std::vector<double> > AbstractMesh::getNodeVectorAttributes(const std::string& tag)
{
std::vector<std::vector<double> > attribs(mNodes.size());
return attribs;
}
void AbstractMesh::addVectorAttribute(const std::string& tag, const std::vector<double>& values)
{
mVectorAttributes[tag] = values;
}
bool AbstractMesh::hasVectorAttribute(const std::string& tag) const
{
return mVectorAttributes.find(tag) != mVectorAttributes.end();
}
std::vector<double> AbstractMesh::getVectorAttribute(const std::string& tag) const
{
auto iter = mVectorAttributes.find(tag);
if (iter != mVectorAttributes.end())
{
return iter->second;
}
return {};
}
void AbstractMesh::scale(double scaleX, double scaleY)
{
for (auto& node : mNodes)
{
node->scale(scaleX, scaleY);
}
}

View file

@ -1,9 +1,17 @@
#pragma once
#include "Point.h"
#include "Node.h"
#include <memory>
#include <vector>
using NodePtr = std::unique_ptr<Node>;
using VecNodes = std::vector<NodePtr>;
class AbstractMesh
{
public:
enum class MeshType
{
LINE,
@ -13,5 +21,35 @@ public:
virtual ~AbstractMesh() = default;
void addVectorAttribute(const std::string& tag, const std::vector<double>& values);
void addConstantNodeVectorAttribute(const std::string& tag, const std::vector<double>& values);
template<typename T>
std::vector<T> getVerticesFlat(T scaleX = 1.0, T scaleY = 1.0, T scaleZ = 1.0) const
{
std::vector<T> ret(3*mNodes.size());
for(std::size_t idx = 0; idx<mNodes.size(); idx++)
{
auto node = mNodes[idx].get();
ret[3*idx] = node->getPoint().getX()/scaleX;
ret[3*idx + 1] = node->getPoint().getY()/scaleY;
ret[3*idx + 2] = node->getPoint().getZ()/scaleZ;
}
return ret;
}
std::vector<std::vector<double> > getNodeVectorAttributes(const std::string& tag);
std::vector<double> getVectorAttribute(const std::string& tag) const;
virtual MeshType getType() const = 0;
bool hasVectorAttribute(const std::string& tag) const;
void scale(double scaleX, double scaleY);
protected:
std::unordered_map<std::string, std::vector<double> > mVectorAttributes;
VecNodes mNodes;
};

View file

@ -1,7 +1,8 @@
list(APPEND mesh_LIB_INCLUDES
AbstractMesh.cpp
Edge.cpp
Face.cpp
AbstractFace.cpp
QuadFace.cpp
TriFace.cpp
Node.cpp
QuadMesh.cpp

View file

@ -0,0 +1,90 @@
#include "MeshPrimitives.h"
#include <iostream>
std::unique_ptr<TriMesh> MeshPrimitives::build(const Rectangle& rectangle)
{
const auto bottom_left = rectangle.getLocation();
const auto width = rectangle.getWidth();
const auto height = rectangle.getHeight();
VecPoints locations = {
bottom_left,
Point(bottom_left, width, 0),
Point(bottom_left, width, height),
Point(bottom_left, 0, height)
};
EdgeIds edge_ids = {
{0, 1},
{1, 2},
{2, 0},
{2, 3},
{3, 0}
};
FaceIds face_ids = {
{0, 1, 2},
{2, 3, 4}
};
return MeshBuilder::buildTriMesh(locations, edge_ids, face_ids);
}
std::unique_ptr<TriMesh> MeshPrimitives::buildExplodedGrid(unsigned numX, unsigned numY)
{
double delta_x = 1.0/double(numX);
double delta_y = 1.0/double(numY);
VecPoints locations (4 * numX * numY);
double offset_x = delta_x;
double offset_y = delta_y;
for (unsigned idx=0; idx<numY; idx++)
{
for(unsigned jdx=0; jdx<numX; jdx++)
{
auto locX0 = offset_x - delta_x/2.0;
auto locX1 = offset_x + delta_x/2.0;
auto locY0 = offset_y - delta_y/2.0;
auto locY1 = offset_y + delta_y/2.0;
auto id_offset = 4* (jdx + numX*idx);
locations[id_offset] = Point(locX0, locY0);
locations[id_offset + 1] = Point(locX1, locY0);
locations[id_offset + 2] = Point(locX1, locY1);
locations[id_offset + 3] = Point(locX0, locY1);
offset_x += delta_x;
}
offset_x = delta_x;
offset_y += delta_y;
}
EdgeIds edge_ids(5 * numX * numY);
for (unsigned idx=0; idx<numY; idx++)
{
for(unsigned jdx=0; jdx<numX; jdx++)
{
unsigned node_offset = 4 * (jdx + numX * idx);
auto id_offset = 5* (jdx + numX*idx);
edge_ids[id_offset] = {node_offset, node_offset + 1};
edge_ids[id_offset + 1] = {node_offset + 1, node_offset + 2};
edge_ids[id_offset + 2] = {node_offset + 2, node_offset + 3};
edge_ids[id_offset + 3] = {node_offset + 3, node_offset};
edge_ids[id_offset + 4] = {node_offset + 2, node_offset};
}
}
FaceIds face_ids(2 *numX * numY);
for (unsigned idx=0; idx<numY; idx++)
{
for(unsigned jdx=0; jdx<numX; jdx++)
{
unsigned edge_offset = 5 * (jdx + numX * idx);
unsigned face_offset = 2 * (jdx + numX * idx);
face_ids[face_offset] = {edge_offset, edge_offset + 1, edge_offset + 4};
face_ids[face_offset + 1] = {edge_offset + 4, edge_offset + 2, edge_offset + 3};
}
}
return MeshBuilder::buildTriMesh(locations, edge_ids, face_ids);
}

View file

@ -5,7 +5,6 @@
#include "Node.h"
#include "Edge.h"
#include "Face.h"
#include "MeshBuilder.h"
#include "AbstractGeometricItem.h"
@ -16,32 +15,7 @@ class MeshPrimitives
{
public:
static std::unique_ptr<TriMesh> build(const Rectangle& rectangle)
{
const auto bottom_left = rectangle.getLocation();
const auto width = rectangle.getWidth();
const auto height = rectangle.getHeight();
static std::unique_ptr<TriMesh> build(const Rectangle& rectangle);
VecPoints locations = {
bottom_left,
Point(bottom_left, width, 0),
Point(bottom_left, width, height),
Point(bottom_left, 0, height)
};
EdgeIds edge_ids = {
{0, 1},
{1, 2},
{2, 0},
{2, 3},
{3, 0}
};
FaceIds face_ids = {
{0, 1, 2},
{2, 3, 4}
};
return MeshBuilder::buildTriMesh(locations, edge_ids, face_ids);
}
static std::unique_ptr<TriMesh> buildExplodedGrid(unsigned numX, unsigned numY);
};

View file

@ -27,4 +27,19 @@ void Node::updateIndex(unsigned index)
mIndex = index;
}
void Node::addVectorAttribute(const std::string& tag, const std::vector<double>& values)
{
mVectorAttributes[tag] = values;
}
std::vector<double> Node::getVectorAttribute(const std::string& tag) const
{
auto iter = mVectorAttributes.find(tag);
if (iter != mVectorAttributes.end())
{
return iter->second;
}
return {};
}

View file

@ -2,6 +2,11 @@
#include "Point.h"
#include <unordered_map>
#include <string>
#include <vector>
class Node
{
public:
@ -20,7 +25,17 @@ public:
return mPoint;
}
void addVectorAttribute(const std::string& tag, const std::vector<double>& values);
std::vector<double> getVectorAttribute(const std::string& tag) const;
void scale(double x, double y)
{
mPoint.scale(x, y);
}
private:
std::unordered_map<std::string, std::vector<double> > mVectorAttributes;
unsigned mIndex{0};
Point mPoint;
};

View file

@ -2,7 +2,7 @@
class Edge;
class Face
class QuadFace
{
};

View file

@ -3,10 +3,10 @@
#include "Edge.h"
TriFace::TriFace(Edge* edge0, Edge* edge1, Edge* edge2, unsigned id)
: mEdge0(edge0),
mEdge1(edge1),
mEdge2(edge2),
mId(id)
: AbstractFace(id),
mEdge0(edge0),
mEdge1(edge1),
mEdge2(edge2)
{
}
@ -25,18 +25,3 @@ std::vector<unsigned> TriFace::getNodeIds() const
{
return {mEdge0->getNode0Id(), mEdge0->getNode1Id(), mEdge1->getNode1Id()};
}
void TriFace::addVectorAttribute(const std::string& tag, const std::vector<double>& values)
{
mVectorAttributes[tag] = values;
}
std::vector<double> TriFace::getVectorAttribute(const std::string& tag) const
{
auto iter = mVectorAttributes.find(tag);
if (iter != mVectorAttributes.end())
{
return iter->second;
}
return {};
}

View file

@ -1,29 +1,22 @@
#pragma once
#include <memory>
#include <vector>
#include <unordered_map>
#include <string>
#include "AbstractFace.h"
class Edge;
class TriFace
class TriFace : public AbstractFace
{
public:
TriFace(Edge* edge0, Edge* edge1, Edge* edge2, unsigned id=0);
~TriFace();
std::vector<unsigned> getNodeIds() const override;
static std::unique_ptr<TriFace> Create(Edge* edge0, Edge* edge1, Edge* edge2, unsigned id=0);
std::vector<unsigned> getNodeIds() const;
void addVectorAttribute(const std::string& tag, const std::vector<double>& values);
std::vector<double> getVectorAttribute(const std::string& tag) const;
private:
unsigned mId{0};
std::unordered_map<std::string, std::vector<double> > mVectorAttributes;
Edge* mEdge0{nullptr};
Edge* mEdge1{nullptr};
Edge* mEdge2{nullptr};

View file

@ -49,34 +49,3 @@ void TriMesh::addConstantFaceVectorAttribute(const std::string& tag, const std::
face->addVectorAttribute(tag, values);
}
}
void TriMesh::addConstantNodeVectorAttribute(const std::string& tag, const std::vector<double>& values)
{
}
std::vector<std::vector<double> > TriMesh::getNodeVectorAttributes(const std::string& tag)
{
std::vector<std::vector<double> > attribs(mNodes.size());
return attribs;
}
void TriMesh::addVectorAttribute(const std::string& tag, const std::vector<double>& values)
{
mVectorAttributes[tag] = values;
}
bool TriMesh::hasVectorAttribute(const std::string& tag) const
{
return mVectorAttributes.find(tag) != mVectorAttributes.end();
}
std::vector<double> TriMesh::getVectorAttribute(const std::string& tag) const
{
auto iter = mVectorAttributes.find(tag);
if (iter != mVectorAttributes.end())
{
return iter->second;
}
return {};
}

View file

@ -1,22 +1,16 @@
#pragma once
#include "AbstractMesh.h"
#include "Point.h"
#include "Node.h"
#include <vector>
#include <memory>
#include <string>
#include <unordered_map>
class Edge;
class TriFace;
using NodePtr = std::unique_ptr<Node>;
using EdgePtr = std::unique_ptr<Edge>;
using TriFacePtr = std::unique_ptr<TriFace>;
using VecNodes = std::vector<NodePtr>;
using VecEdges = std::vector<EdgePtr>;
using VecFaces = std::vector<TriFacePtr>;
@ -29,44 +23,18 @@ public:
void populate(VecNodes& nodes, VecEdges& edges, VecFaces& faces);
template<typename T>
std::vector<T> getVerticesFlat(T scaleX = 1.0, T scaleY = 1.0, T scaleZ = 1.0) const
{
std::vector<T> ret(3*mNodes.size());
for(std::size_t idx = 0; idx<mNodes.size(); idx++)
{
auto node = mNodes[idx].get();
ret[3*idx] = node->getPoint().getX()/scaleX;
ret[3*idx + 1] = node->getPoint().getY()/scaleY;
ret[3*idx + 2] = node->getPoint().getZ()/scaleZ;
}
return ret;
}
std::vector<unsigned> getFaceNodeIds() const;
void addConstantFaceVectorAttribute(const std::string& tag, const std::vector<double>& values);
void addConstantNodeVectorAttribute(const std::string& tag, const std::vector<double>& values);
std::vector<std::vector<double> > getFaceVectorAttributes(const std::string& tag);
std::vector<std::vector<double> > getNodeVectorAttributes(const std::string& tag);
void addVectorAttribute(const std::string& tag, const std::vector<double>& values);
bool hasVectorAttribute(const std::string& tag) const;
std::vector<double> getVectorAttribute(const std::string& tag) const;
MeshType getType() const
{
return MeshType::TRI;
}
private:
std::unordered_map<std::string, std::vector<double> > mVectorAttributes;
VecNodes mNodes;
VecEdges mEdges;
VecFaces mFaces;
};

View file

@ -21,6 +21,7 @@ list(APPEND ui_elements_LIB_INCLUDES
widgets/VerticalSpacer.cpp
widgets/StackWidget.cpp
widgets/TextBox.cpp
style/Theme.cpp
)
add_library(ui_elements SHARED ${ui_elements_LIB_INCLUDES})
@ -28,6 +29,7 @@ add_library(ui_elements SHARED ${ui_elements_LIB_INCLUDES})
target_include_directories(ui_elements PUBLIC
"${CMAKE_CURRENT_SOURCE_DIR}/"
"${CMAKE_CURRENT_SOURCE_DIR}/widgets"
"${CMAKE_CURRENT_SOURCE_DIR}/style"
"${CMAKE_CURRENT_SOURCE_DIR}/widgets/elements"
"${CMAKE_CURRENT_SOURCE_DIR}/ui_events"
"${CMAKE_CURRENT_SOURCE_DIR}/desktop_elements"

View file

@ -0,0 +1,26 @@
#include "Theme.h"
Color Theme::getBackgroundPrimary()
{
return {217, 217, 217};
}
Color Theme::getBannerBackground()
{
return {181, 189, 200};
}
Color Theme::getButtonPrimaryBackground()
{
return {200, 200, 200};
}
Color Theme::getButtonPrimaryPressed()
{
return {};
}
Color Theme::getTextPrimary()
{
return {};
}

View file

@ -1 +1,15 @@
#include "Color.h"
class Theme
{
public:
static Color getBackgroundPrimary();
static Color getBannerBackground();
static Color getButtonPrimaryBackground();
static Color getButtonPrimaryPressed();
static Color getTextPrimary();
};

View file

@ -0,0 +1,78 @@
#include "AbstractVisualNode.h"
AbstractVisualNode::AbstractVisualNode(const DiscretePoint& location, const std::string& name)
: mLocation(location),
mName(name)
{
}
SceneItem* AbstractVisualNode::getSceneItem(std::size_t idx) const
{
return mSceneItems[idx].get();
}
unsigned AbstractVisualNode::getNumSceneItems() const
{
return mSceneItems.size();
}
void AbstractVisualNode::update(FontsManager* fontsManager)
{
}
Image<unsigned char>* AbstractVisualNode::getImage() const
{
return mImage.get();
}
void AbstractVisualNode::syncChildren(const std::vector<AbstractVisualNode*>& children)
{
mChildren = children;
}
void AbstractVisualNode::addChild(AbstractVisualNode* child)
{
mChildren.push_back(child);
}
const std::vector<AbstractVisualNode*>& AbstractVisualNode::getChildren() const
{
return mChildren;
}
void AbstractVisualNode::setIsVisible(bool isVisible)
{
//std::cout << "Setting " << mName << " visibility to " << isVisible << std::endl;
mIsVisible = isVisible;
}
unsigned AbstractVisualNode::getNumChildren() const
{
return mChildren.size();
}
void AbstractVisualNode::setName(const std::string& name)
{
mName = name;
}
const std::string& AbstractVisualNode::getName() const
{
return mName;
}
bool AbstractVisualNode::getIsVisible() const
{
return mIsVisible;
}
void AbstractVisualNode::setLocation(const DiscretePoint& loc)
{
if (mLocation != loc)
{
mTransformIsDirty = true;
mLocation = loc;
}
}

View file

@ -15,83 +15,39 @@ class FontsManager;
class AbstractVisualNode
{
public:
AbstractVisualNode(const DiscretePoint& location, const std::string& name = {})
: mLocation(location),
mName(name)
{
}
AbstractVisualNode(const DiscretePoint& location, const std::string& name = {});
virtual ~AbstractVisualNode() = default;
SceneItem* getSceneItem() const
{
return mSceneItem.get();
}
void addChild(AbstractVisualNode* child);
virtual void update(FontsManager* fontsManager)
{
virtual SceneItem* getSceneItem(std::size_t idx) const;
}
virtual unsigned getNumSceneItems() const;
Image<unsigned char>* getImage() const
{
return mImage.get();
}
unsigned getNumChildren() const;
void syncChildren(const std::vector<AbstractVisualNode*>& children)
{
mChildren = children;
}
const std::vector<AbstractVisualNode*>& getChildren() const;
void addChild(AbstractVisualNode* child)
{
mChildren.push_back(child);
}
const std::string& getName() const;
const std::vector<AbstractVisualNode*>& getChildren() const
{
return mChildren;
}
Image<unsigned char>* getImage() const;
void setIsVisible(bool isVisible)
{
//std::cout << "Setting " << mName << " visibility to " << isVisible << std::endl;
mIsVisible = isVisible;
}
bool getIsVisible() const;
unsigned getNumChildren() const
{
return mChildren.size();
}
virtual void update(FontsManager* fontsManager);
void setName(const std::string& name)
{
mName = name;
}
void syncChildren(const std::vector<AbstractVisualNode*>& children);
const std::string& getName() const
{
return mName;
}
void setIsVisible(bool isVisible);
bool getIsVisible() const
{
return mIsVisible;
}
void setName(const std::string& name);
void setLocation(const DiscretePoint& loc)
{
if (mLocation != loc)
{
mTransformIsDirty = true;
mLocation = loc;
}
}
void setLocation(const DiscretePoint& loc);
protected:
DiscretePoint mLocation;
std::unique_ptr<SceneItem> mSceneItem;
std::vector<std::unique_ptr<SceneItem> > mSceneItems;
std::unique_ptr<Image<unsigned char> > mImage;
std::vector<AbstractVisualNode*> mChildren;

View file

@ -9,6 +9,9 @@ list(APPEND visual_elements_LIB_INCLUDES
SceneText.cpp
Transform.cpp
Texture.cpp
GridNode.cpp
AbstractVisualNode.cpp
)
add_library(visual_elements SHARED ${visual_elements_LIB_INCLUDES})

View file

@ -0,0 +1,123 @@
#include "GridNode.h"
#include "MeshPrimitives.h"
GridNode::GridNode(const DiscretePoint& location)
: MaterialNode(location)
{
}
void GridNode::setNumX(unsigned numX)
{
if (mNumberX != numX)
{
mNumberX = numX;
mDataDirty = true;
}
}
void GridNode::setNumY(unsigned numY)
{
if (mNumberY != numY)
{
mNumberY = numY;
mDataDirty = true;
}
}
void GridNode::setWidth(unsigned width)
{
if (mWidth != width)
{
mTransformIsDirty = true;
mWidth = width;
}
}
void GridNode::setHeight(unsigned height)
{
if (mHeight != height)
{
mTransformIsDirty = true;
mHeight = height;
}
}
void GridNode::setData(const std::vector<Color>& colors)
{
if (mData != colors)
{
mData = colors;
mDataDirty = true;
}
}
SceneItem* GridNode::getSceneItem(std::size_t idx) const
{
if (idx == 0)
{
return mBackgroundModel.get();
}
else
{
return mOutlineModel.get();
}
}
unsigned GridNode::getNumSceneItems() const
{
return 1;
}
void GridNode::update(FontsManager* fontsManager)
{
if (!mBackgroundModel || mDataDirty)
{
auto mesh = MeshPrimitives::buildExplodedGrid(mNumberX, mNumberY);
if (mHeight > mWidth)
{
mesh->scale(mWidth, mWidth);
}
else
{
mesh->scale(mHeight, mHeight);
}
if (!mBackgroundModel)
{
std::cout << "Setting up background model for grid node " << std::endl;
mBackgroundModel = std::make_unique<SceneModel>(std::move(mesh));
mBackgroundModel->setName(mName + "_Model");
mBackgroundModel->updateUniformColor({200, 200, 200, 1.0});
}
else
{
mBackgroundModel.get()->updateMesh(std::move(mesh));
mBackgroundModel->updateUniformColor({200, 200, 200, 1.0});
}
}
/*
if (!mOutlineModel || mDataDirty)
{
const auto rect = Rectangle(Point(), 1, 1);
auto mesh = MeshPrimitives::build(rect);
if (!mOutlineModel)
{
mOutlineModel = std::make_unique<SceneModel>(std::move(mesh));
mOutlineModel->setName(mName + "_Model");
}
else
{
mOutlineModel.get()->updateMesh(std::move(mesh));
}
}
*/
mDataDirty = false;
}

View file

@ -0,0 +1,36 @@
#pragma once
#include "MaterialNode.h"
#include "Color.h"
class GridNode : public MaterialNode
{
public:
GridNode(const DiscretePoint& location);
void setNumX(unsigned numX);
void setNumY(unsigned numY);
void setData(const std::vector<Color>& colors);
SceneItem* getSceneItem(std::size_t idx) const override;
unsigned getNumSceneItems() const override;
void update(FontsManager* fontsManager) override;
void setWidth(unsigned width);
void setHeight(unsigned height);
private:
unsigned mNumberX{5};
unsigned mNumberY{5};
unsigned mWidth{1};
unsigned mHeight{1};
bool mDataDirty = true;
std::vector<Color> mData;
std::unique_ptr<SceneModel> mBackgroundModel;
std::unique_ptr<SceneModel> mOutlineModel;
};

View file

@ -24,6 +24,23 @@ GeometryNode::Type RectangleNode::getType()
return GeometryNode::Type::Rectangle;
}
SceneItem* RectangleNode::getSceneItem(std::size_t idx) const
{
if (idx == 0)
{
return mBackgroundItem.get();
}
else
{
return nullptr;
}
}
unsigned RectangleNode::getNumSceneItems() const
{
return 1;
}
unsigned RectangleNode::getWidth() const
{
return mWidth;
@ -54,32 +71,32 @@ void RectangleNode::setHeight(unsigned height)
void RectangleNode::update(FontsManager* fontsManager)
{
if (!mSceneItem || mGeometryIsDirty)
if (!mBackgroundItem || mGeometryIsDirty)
{
const auto rect = Rectangle(Point(), 1, 1);
auto mesh = MeshPrimitives::build(rect);
if (!mSceneItem)
if (!mBackgroundItem)
{
mSceneItem = std::make_unique<SceneModel>(std::move(mesh));
mSceneItem->setName(mName + "_Model");
mBackgroundItem = std::make_unique<SceneModel>(std::move(mesh));
mBackgroundItem->setName(mName + "_Model");
}
else
{
dynamic_cast<SceneModel*>(mSceneItem.get())->updateMesh(std::move(mesh));
mBackgroundItem->updateMesh(std::move(mesh));
}
mGeometryIsDirty = false;
}
if (mTransformIsDirty)
{
mSceneItem->updateTransform({mLocation, static_cast<double>(mWidth), static_cast<double>(mHeight)});
mBackgroundItem->updateTransform({mLocation, static_cast<double>(mWidth), static_cast<double>(mHeight)});
mTransformIsDirty = false;
}
if (mMaterialIsDirty)
{
mSceneItem->updateUniformColor(mFillColor);
mBackgroundItem->updateUniformColor(mFillColor);
mMaterialIsDirty = false;
}
}

View file

@ -15,6 +15,9 @@ public:
unsigned getWidth() const;
unsigned getHeight() const;
SceneItem* getSceneItem(std::size_t idx) const override;
unsigned getNumSceneItems() const override;
void setWidth(unsigned width);
void setHeight(unsigned height);
@ -22,6 +25,9 @@ public:
private:
unsigned mWidth{1};
unsigned mHeight{1};
std::unique_ptr<SceneModel> mBackgroundItem;
std::unique_ptr<SceneModel> mOutlineItem;
};
using RectangleNodePtr = std::unique_ptr<RectangleNode>;

View file

@ -30,9 +30,12 @@ void Scene::updateNode(AbstractVisualNode* node, FontsManager* fontsManager)
node->update(fontsManager);
if(auto item = node->getSceneItem())
for (std::size_t idx=0; idx< node->getNumSceneItems(); idx++)
{
mSceneItems.push_back(node->getSceneItem());
if (auto item = node->getSceneItem(idx))
{
mSceneItems.push_back(item);
}
}
}

View file

@ -78,6 +78,23 @@ void TextNode::setContent(const std::string& content)
}
}
SceneItem* TextNode::getSceneItem(std::size_t idx) const
{
if (idx == 0)
{
return mTextItem.get();
}
else
{
return 0;
}
}
unsigned TextNode::getNumSceneItems() const
{
return 1;
}
void TextNode::updateLines(FontsManager* fontsManager)
{
auto original_count = mTextData.mLines.size();
@ -116,10 +133,10 @@ void TextNode::updateLines(FontsManager* fontsManager)
void TextNode::update(FontsManager* fontsManager)
{
if (!mSceneItem)
if (!mTextItem)
{
mSceneItem = std::make_unique<SceneText>();
mSceneItem->setName(mName + "_SceneText");
mTextItem = std::make_unique<SceneText>();
mTextItem->setName(mName + "_SceneText");
}
if (mTransformIsDirty || mContentIsDirty)
@ -129,20 +146,20 @@ void TextNode::update(FontsManager* fontsManager)
if (mContentIsDirty || mLinesAreDirty)
{
dynamic_cast<SceneText*>(mSceneItem.get())->setTextData(mTextData);
dynamic_cast<SceneText*>(mTextItem.get())->setTextData(mTextData);
mContentIsDirty = false;
mLinesAreDirty = false;
}
if (mTransformIsDirty)
{
mSceneItem->updateTransform({mLocation});
mTextItem->updateTransform({mLocation});
mTransformIsDirty = false;
}
if (mMaterialIsDirty)
{
mSceneItem->updateUniformColor(mFillColor);
mTextItem->updateUniformColor(mFillColor);
mMaterialIsDirty = false;
}
}

View file

@ -20,6 +20,9 @@ public:
std::string getContent() const;
std::string getFontLabel() const;
SceneItem* getSceneItem(std::size_t idx) const override;
unsigned getNumSceneItems() const override;
unsigned getWidth() const;
unsigned getHeight() const;
@ -39,6 +42,8 @@ private:
unsigned mWidth{1};
unsigned mHeight{1};
std::unique_ptr<SceneItem> mTextItem;
};
using TextNodetr = std::unique_ptr<TextNode>;