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 text_editor/PlainTextDocument.h
audio_editor/AudioEditorView.h audio_editor/AudioEditorView.h
image_editor/ImageEditorView.h image_editor/ImageEditorView.h
image_editor/ImageViewWidget.h
web_client/WebClientView.h) web_client/WebClientView.h)
@ -16,6 +17,7 @@ list(APPEND client_LIB_INCLUDES
text_editor/PlainTextDocument.cpp text_editor/PlainTextDocument.cpp
audio_editor/AudioEditorView.cpp audio_editor/AudioEditorView.cpp
image_editor/ImageEditorView.cpp image_editor/ImageEditorView.cpp
image_editor/ImageViewWidget.cpp
web_client/WebClientView.cpp web_client/WebClientView.cpp
MediaTool.cpp) MediaTool.cpp)

View file

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

View file

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

View file

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

View file

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

View file

@ -87,6 +87,7 @@ void OpenGlMeshPainter::paint(SceneModel* model, DrawingContext* context)
const auto height = float(surface->getHeight()); const auto height = float(surface->getHeight());
auto mesh = dynamic_cast<TriMesh*>(model->getMesh()); auto mesh = dynamic_cast<TriMesh*>(model->getMesh());
std::cout << "Paint mesh for model " << model->getName() << std::endl;
auto transform = model->getTransform(); auto transform = model->getTransform();
@ -97,6 +98,7 @@ void OpenGlMeshPainter::paint(SceneModel* model, DrawingContext* context)
{ {
auto x = vertices[idx]*transform.getScaleX() + transform.getLocation().getX(); auto x = vertices[idx]*transform.getScaleX() + transform.getLocation().getX();
vertices[idx] = 2*x/width - 1.0; vertices[idx] = 2*x/width - 1.0;
std::cout << "Vert x is " << vertices[idx] << std::endl;
} }
else if(idx%3 == 1) else if(idx%3 == 1)
{ {
@ -108,6 +110,7 @@ void OpenGlMeshPainter::paint(SceneModel* model, DrawingContext* context)
const auto indices = mesh->getFaceNodeIds(); const auto indices = mesh->getFaceNodeIds();
auto model_color = model->getColor().getAsVectorDouble(); 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])}; std::vector<float> color = {float(model_color[0]), float(model_color[1]), float(model_color[2]), float(model_color[3])};
paint(vertices, indices, color); 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 #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 class AbstractMesh
{ {
public: public:
enum class MeshType enum class MeshType
{ {
LINE, LINE,
@ -13,5 +21,35 @@ public:
virtual ~AbstractMesh() = default; 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; 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 list(APPEND mesh_LIB_INCLUDES
AbstractMesh.cpp AbstractMesh.cpp
Edge.cpp Edge.cpp
Face.cpp AbstractFace.cpp
QuadFace.cpp
TriFace.cpp TriFace.cpp
Node.cpp Node.cpp
QuadMesh.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 "Node.h"
#include "Edge.h" #include "Edge.h"
#include "Face.h"
#include "MeshBuilder.h" #include "MeshBuilder.h"
#include "AbstractGeometricItem.h" #include "AbstractGeometricItem.h"
@ -16,32 +15,7 @@ class MeshPrimitives
{ {
public: public:
static std::unique_ptr<TriMesh> build(const Rectangle& rectangle) 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();
VecPoints locations = { static std::unique_ptr<TriMesh> buildExplodedGrid(unsigned numX, unsigned numY);
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);
}
}; };

View file

@ -27,4 +27,19 @@ void Node::updateIndex(unsigned index)
mIndex = 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 "Point.h"
#include <unordered_map>
#include <string>
#include <vector>
class Node class Node
{ {
public: public:
@ -20,7 +25,17 @@ public:
return mPoint; 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: private:
std::unordered_map<std::string, std::vector<double> > mVectorAttributes;
unsigned mIndex{0}; unsigned mIndex{0};
Point mPoint; Point mPoint;
}; };

View file

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

View file

@ -3,10 +3,10 @@
#include "Edge.h" #include "Edge.h"
TriFace::TriFace(Edge* edge0, Edge* edge1, Edge* edge2, unsigned id) TriFace::TriFace(Edge* edge0, Edge* edge1, Edge* edge2, unsigned id)
: mEdge0(edge0), : AbstractFace(id),
mEdge0(edge0),
mEdge1(edge1), mEdge1(edge1),
mEdge2(edge2), mEdge2(edge2)
mId(id)
{ {
} }
@ -25,18 +25,3 @@ std::vector<unsigned> TriFace::getNodeIds() const
{ {
return {mEdge0->getNode0Id(), mEdge0->getNode1Id(), mEdge1->getNode1Id()}; 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 #pragma once
#include <memory> #include "AbstractFace.h"
#include <vector>
#include <unordered_map>
#include <string>
class Edge; class Edge;
class TriFace class TriFace : public AbstractFace
{ {
public: public:
TriFace(Edge* edge0, Edge* edge1, Edge* edge2, unsigned id=0); TriFace(Edge* edge0, Edge* edge1, Edge* edge2, unsigned id=0);
~TriFace(); ~TriFace();
std::vector<unsigned> getNodeIds() const override;
static std::unique_ptr<TriFace> Create(Edge* edge0, Edge* edge1, Edge* edge2, unsigned id=0); 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: private:
unsigned mId{0};
std::unordered_map<std::string, std::vector<double> > mVectorAttributes;
Edge* mEdge0{nullptr}; Edge* mEdge0{nullptr};
Edge* mEdge1{nullptr}; Edge* mEdge1{nullptr};
Edge* mEdge2{nullptr}; Edge* mEdge2{nullptr};

View file

@ -49,34 +49,3 @@ void TriMesh::addConstantFaceVectorAttribute(const std::string& tag, const std::
face->addVectorAttribute(tag, values); 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 #pragma once
#include "AbstractMesh.h" #include "AbstractMesh.h"
#include "Point.h"
#include "Node.h"
#include <vector>
#include <memory>
#include <string> #include <string>
#include <unordered_map> #include <unordered_map>
class Edge; class Edge;
class TriFace; class TriFace;
using NodePtr = std::unique_ptr<Node>;
using EdgePtr = std::unique_ptr<Edge>; using EdgePtr = std::unique_ptr<Edge>;
using TriFacePtr = std::unique_ptr<TriFace>; using TriFacePtr = std::unique_ptr<TriFace>;
using VecNodes = std::vector<NodePtr>;
using VecEdges = std::vector<EdgePtr>; using VecEdges = std::vector<EdgePtr>;
using VecFaces = std::vector<TriFacePtr>; using VecFaces = std::vector<TriFacePtr>;
@ -29,44 +23,18 @@ public:
void populate(VecNodes& nodes, VecEdges& edges, VecFaces& faces); 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; std::vector<unsigned> getFaceNodeIds() const;
void addConstantFaceVectorAttribute(const std::string& tag, const std::vector<double>& values); 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> > 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 MeshType getType() const
{ {
return MeshType::TRI; return MeshType::TRI;
} }
private: private:
std::unordered_map<std::string, std::vector<double> > mVectorAttributes;
VecNodes mNodes;
VecEdges mEdges; VecEdges mEdges;
VecFaces mFaces; VecFaces mFaces;
}; };

View file

@ -21,6 +21,7 @@ list(APPEND ui_elements_LIB_INCLUDES
widgets/VerticalSpacer.cpp widgets/VerticalSpacer.cpp
widgets/StackWidget.cpp widgets/StackWidget.cpp
widgets/TextBox.cpp widgets/TextBox.cpp
style/Theme.cpp
) )
add_library(ui_elements SHARED ${ui_elements_LIB_INCLUDES}) 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 target_include_directories(ui_elements PUBLIC
"${CMAKE_CURRENT_SOURCE_DIR}/" "${CMAKE_CURRENT_SOURCE_DIR}/"
"${CMAKE_CURRENT_SOURCE_DIR}/widgets" "${CMAKE_CURRENT_SOURCE_DIR}/widgets"
"${CMAKE_CURRENT_SOURCE_DIR}/style"
"${CMAKE_CURRENT_SOURCE_DIR}/widgets/elements" "${CMAKE_CURRENT_SOURCE_DIR}/widgets/elements"
"${CMAKE_CURRENT_SOURCE_DIR}/ui_events" "${CMAKE_CURRENT_SOURCE_DIR}/ui_events"
"${CMAKE_CURRENT_SOURCE_DIR}/desktop_elements" "${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 class AbstractVisualNode
{ {
public: public:
AbstractVisualNode(const DiscretePoint& location, const std::string& name = {}) AbstractVisualNode(const DiscretePoint& location, const std::string& name = {});
: mLocation(location),
mName(name)
{
}
virtual ~AbstractVisualNode() = default; virtual ~AbstractVisualNode() = default;
SceneItem* getSceneItem() const void addChild(AbstractVisualNode* child);
{
return mSceneItem.get();
}
virtual void update(FontsManager* fontsManager) virtual SceneItem* getSceneItem(std::size_t idx) const;
{
} virtual unsigned getNumSceneItems() const;
Image<unsigned char>* getImage() const unsigned getNumChildren() const;
{
return mImage.get();
}
void syncChildren(const std::vector<AbstractVisualNode*>& children) const std::vector<AbstractVisualNode*>& getChildren() const;
{
mChildren = children;
}
void addChild(AbstractVisualNode* child) const std::string& getName() const;
{
mChildren.push_back(child);
}
const std::vector<AbstractVisualNode*>& getChildren() const Image<unsigned char>* getImage() const;
{
return mChildren;
}
void setIsVisible(bool isVisible) bool getIsVisible() const;
{
//std::cout << "Setting " << mName << " visibility to " << isVisible << std::endl;
mIsVisible = isVisible;
}
unsigned getNumChildren() const virtual void update(FontsManager* fontsManager);
{
return mChildren.size();
}
void setName(const std::string& name) void syncChildren(const std::vector<AbstractVisualNode*>& children);
{
mName = name;
}
const std::string& getName() const void setIsVisible(bool isVisible);
{
return mName;
}
bool getIsVisible() const void setName(const std::string& name);
{
return mIsVisible;
}
void setLocation(const DiscretePoint& loc) void setLocation(const DiscretePoint& loc);
{
if (mLocation != loc)
{
mTransformIsDirty = true;
mLocation = loc;
}
}
protected: protected:
DiscretePoint mLocation; DiscretePoint mLocation;
std::unique_ptr<SceneItem> mSceneItem; std::vector<std::unique_ptr<SceneItem> > mSceneItems;
std::unique_ptr<Image<unsigned char> > mImage; std::unique_ptr<Image<unsigned char> > mImage;
std::vector<AbstractVisualNode*> mChildren; std::vector<AbstractVisualNode*> mChildren;

View file

@ -9,6 +9,9 @@ list(APPEND visual_elements_LIB_INCLUDES
SceneText.cpp SceneText.cpp
Transform.cpp Transform.cpp
Texture.cpp Texture.cpp
GridNode.cpp
AbstractVisualNode.cpp
) )
add_library(visual_elements SHARED ${visual_elements_LIB_INCLUDES}) 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; 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 unsigned RectangleNode::getWidth() const
{ {
return mWidth; return mWidth;
@ -54,32 +71,32 @@ void RectangleNode::setHeight(unsigned height)
void RectangleNode::update(FontsManager* fontsManager) void RectangleNode::update(FontsManager* fontsManager)
{ {
if (!mSceneItem || mGeometryIsDirty) if (!mBackgroundItem || mGeometryIsDirty)
{ {
const auto rect = Rectangle(Point(), 1, 1); const auto rect = Rectangle(Point(), 1, 1);
auto mesh = MeshPrimitives::build(rect); auto mesh = MeshPrimitives::build(rect);
if (!mSceneItem) if (!mBackgroundItem)
{ {
mSceneItem = std::make_unique<SceneModel>(std::move(mesh)); mBackgroundItem = std::make_unique<SceneModel>(std::move(mesh));
mSceneItem->setName(mName + "_Model"); mBackgroundItem->setName(mName + "_Model");
} }
else else
{ {
dynamic_cast<SceneModel*>(mSceneItem.get())->updateMesh(std::move(mesh)); mBackgroundItem->updateMesh(std::move(mesh));
} }
mGeometryIsDirty = false; mGeometryIsDirty = false;
} }
if (mTransformIsDirty) 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; mTransformIsDirty = false;
} }
if (mMaterialIsDirty) if (mMaterialIsDirty)
{ {
mSceneItem->updateUniformColor(mFillColor); mBackgroundItem->updateUniformColor(mFillColor);
mMaterialIsDirty = false; mMaterialIsDirty = false;
} }
} }

View file

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

View file

@ -30,9 +30,12 @@ void Scene::updateNode(AbstractVisualNode* node, FontsManager* fontsManager)
node->update(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) void TextNode::updateLines(FontsManager* fontsManager)
{ {
auto original_count = mTextData.mLines.size(); auto original_count = mTextData.mLines.size();
@ -116,10 +133,10 @@ void TextNode::updateLines(FontsManager* fontsManager)
void TextNode::update(FontsManager* fontsManager) void TextNode::update(FontsManager* fontsManager)
{ {
if (!mSceneItem) if (!mTextItem)
{ {
mSceneItem = std::make_unique<SceneText>(); mTextItem = std::make_unique<SceneText>();
mSceneItem->setName(mName + "_SceneText"); mTextItem->setName(mName + "_SceneText");
} }
if (mTransformIsDirty || mContentIsDirty) if (mTransformIsDirty || mContentIsDirty)
@ -129,20 +146,20 @@ void TextNode::update(FontsManager* fontsManager)
if (mContentIsDirty || mLinesAreDirty) if (mContentIsDirty || mLinesAreDirty)
{ {
dynamic_cast<SceneText*>(mSceneItem.get())->setTextData(mTextData); dynamic_cast<SceneText*>(mTextItem.get())->setTextData(mTextData);
mContentIsDirty = false; mContentIsDirty = false;
mLinesAreDirty = false; mLinesAreDirty = false;
} }
if (mTransformIsDirty) if (mTransformIsDirty)
{ {
mSceneItem->updateTransform({mLocation}); mTextItem->updateTransform({mLocation});
mTransformIsDirty = false; mTransformIsDirty = false;
} }
if (mMaterialIsDirty) if (mMaterialIsDirty)
{ {
mSceneItem->updateUniformColor(mFillColor); mTextItem->updateUniformColor(mFillColor);
mMaterialIsDirty = false; mMaterialIsDirty = false;
} }
} }

View file

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