Simple drawing example.
This commit is contained in:
parent
d7fe11913f
commit
f0091f9e04
27 changed files with 450 additions and 68 deletions
|
@ -17,8 +17,8 @@ TabbedPanelWidget::TabbedPanelWidget()
|
|||
nav->setSize({0, 0, 0, 0, 200, 0});
|
||||
|
||||
auto vertSpacer = VerticalSpacer::Create();
|
||||
vertSpacer->AddWidgetWithScale(std::move(nav), 1);
|
||||
vertSpacer->AddWidgetWithScale(std::move(stack), 4);
|
||||
vertSpacer->addWidgetWithScale(std::move(nav), 1);
|
||||
vertSpacer->addWidgetWithScale(std::move(stack), 4);
|
||||
addWidget(std::move(vertSpacer));
|
||||
}
|
||||
|
||||
|
|
|
@ -12,63 +12,63 @@
|
|||
|
||||
void SharedMemory::allocate(const std::string& namePrefix, std::size_t size)
|
||||
{
|
||||
createFile(namePrefix);
|
||||
createFile(namePrefix);
|
||||
|
||||
if (!mIsValid)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!mIsValid)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
int ret{-1};
|
||||
do {
|
||||
ret = ftruncate(mFileDescriptor, size);
|
||||
} while (ret < 0 && errno == EINTR);
|
||||
int ret{-1};
|
||||
do {
|
||||
ret = ftruncate(mFileDescriptor, size);
|
||||
} while (ret < 0 && errno == EINTR);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
close(mFileDescriptor);
|
||||
mIsValid = false;
|
||||
}
|
||||
if (ret < 0)
|
||||
{
|
||||
close(mFileDescriptor);
|
||||
mIsValid = false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int SharedMemory::getFileDescriptor() const
|
||||
{
|
||||
return mFileDescriptor;
|
||||
return mFileDescriptor;
|
||||
}
|
||||
|
||||
bool SharedMemory::isValid() const
|
||||
{
|
||||
return mIsValid;
|
||||
return mIsValid;
|
||||
}
|
||||
|
||||
void SharedMemory::createFile(const std::string& namePrefix)
|
||||
{
|
||||
#ifdef __linux__
|
||||
unsigned retries = 100;
|
||||
do {
|
||||
const auto name = getRandomName(namePrefix);
|
||||
--retries;
|
||||
unsigned retries = 100;
|
||||
do {
|
||||
const auto name = getRandomName(namePrefix);
|
||||
--retries;
|
||||
|
||||
const int fd = shm_open(name.c_str(), O_RDWR | O_CREAT | O_EXCL, 0600);
|
||||
if (fd >= 0)
|
||||
{
|
||||
shm_unlink(name.c_str());
|
||||
mFileDescriptor = fd;
|
||||
mIsValid = true;
|
||||
break;
|
||||
}
|
||||
} while (retries > 0 && errno == EEXIST);
|
||||
const int fd = shm_open(name.c_str(), O_RDWR | O_CREAT | O_EXCL, 0600);
|
||||
if (fd >= 0)
|
||||
{
|
||||
shm_unlink(name.c_str());
|
||||
mFileDescriptor = fd;
|
||||
mIsValid = true;
|
||||
break;
|
||||
}
|
||||
} while (retries > 0 && errno == EEXIST);
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string SharedMemory::getRandomName(const std::string& namePrefix) const
|
||||
{
|
||||
std::string randomSuffix;
|
||||
for (const auto entry : RandomUtils::getRandomVecUnsigned(6))
|
||||
{
|
||||
randomSuffix += std::to_string(entry);
|
||||
}
|
||||
return namePrefix + randomSuffix;
|
||||
std::string randomSuffix;
|
||||
for (const auto entry : RandomUtils::getRandomVecUnsigned(6))
|
||||
{
|
||||
randomSuffix += std::to_string(entry);
|
||||
}
|
||||
return namePrefix + randomSuffix;
|
||||
}
|
||||
|
|
|
@ -5,18 +5,18 @@
|
|||
class SharedMemory
|
||||
{
|
||||
public:
|
||||
void allocate(const std::string& namePrefix, std::size_t size);
|
||||
void allocate(const std::string& namePrefix, std::size_t size);
|
||||
|
||||
int getFileDescriptor() const;
|
||||
int getFileDescriptor() const;
|
||||
|
||||
bool isValid() const;
|
||||
bool isValid() const;
|
||||
|
||||
private:
|
||||
|
||||
void createFile(const std::string& namePrefix);
|
||||
void createFile(const std::string& namePrefix);
|
||||
|
||||
std::string getRandomName(const std::string& namePrefix) const;
|
||||
std::string getRandomName(const std::string& namePrefix) const;
|
||||
|
||||
int mFileDescriptor{0};
|
||||
bool mIsValid{false};
|
||||
int mFileDescriptor{0};
|
||||
bool mIsValid{false};
|
||||
};
|
||||
|
|
|
@ -110,6 +110,7 @@ void OpenGlMeshPainter::paint(SceneModel* model, DrawingContext* context)
|
|||
auto y = vertices[idx]*transform.getScaleY() + transform.getLocation().getY();
|
||||
vertices[idx] = 1.0 - 2*y/height;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
std::vector<unsigned> indices;
|
||||
|
|
|
@ -32,6 +32,74 @@ std::unique_ptr<TriMesh> MeshPrimitives::buildRectangleAsTriMesh()
|
|||
return MeshBuilder::buildTriMesh(locations, edge_ids, face_ids);
|
||||
}
|
||||
|
||||
std::unique_ptr<TriMesh> MeshPrimitives::buildCircleAsTriMesh(unsigned numSegments)
|
||||
{
|
||||
VecPoints locations(numSegments + 1);
|
||||
locations[0] = {0, 0};
|
||||
|
||||
const double delta_theta = (2.0*M_PI)/double(numSegments);
|
||||
double theta = 0.0;
|
||||
for(unsigned idx=1; idx<=numSegments; idx++)
|
||||
{
|
||||
const double x = sin(theta);
|
||||
const double y = cos(theta);
|
||||
locations[idx] = {x, y};
|
||||
theta += delta_theta;
|
||||
}
|
||||
|
||||
EdgeIds edge_ids(2*numSegments);
|
||||
for(unsigned idx=0; idx<numSegments; idx++)
|
||||
{
|
||||
edge_ids[idx] = {0, idx+1};
|
||||
|
||||
auto wrap_node = idx + 2;
|
||||
if (wrap_node > numSegments)
|
||||
{
|
||||
wrap_node = 1;
|
||||
}
|
||||
edge_ids[idx + numSegments] = {idx + 1, wrap_node};
|
||||
}
|
||||
|
||||
FaceIds face_ids(numSegments);
|
||||
for(unsigned idx=0; idx<numSegments; idx++)
|
||||
{
|
||||
auto top_edge_inner = idx + 1;
|
||||
if (top_edge_inner == numSegments)
|
||||
{
|
||||
top_edge_inner = 0;
|
||||
}
|
||||
|
||||
const auto outer_edge = idx + numSegments;
|
||||
face_ids[idx] = {idx, outer_edge, top_edge_inner};
|
||||
}
|
||||
return MeshBuilder::buildTriMesh(locations, edge_ids, face_ids);
|
||||
}
|
||||
|
||||
std::unique_ptr<LineMesh> MeshPrimitives::buildCircleAsLineMesh(unsigned numSegments)
|
||||
{
|
||||
VecPoints locations(numSegments);
|
||||
const double delta_theta = (2.0*M_PI)/double(numSegments);
|
||||
double theta = 0.0;
|
||||
for(unsigned idx=0; idx<numSegments; idx++)
|
||||
{
|
||||
const double x = sin(theta);
|
||||
const double y = cos(theta);
|
||||
locations[idx] = {x, y};
|
||||
}
|
||||
|
||||
EdgeIds edge_ids(2*numSegments);
|
||||
for(unsigned idx=0; idx<numSegments; idx++)
|
||||
{
|
||||
auto top_node = idx + 1;
|
||||
if (top_node == numSegments)
|
||||
{
|
||||
top_node = 0;
|
||||
}
|
||||
edge_ids[idx] = {idx, top_node};
|
||||
}
|
||||
return MeshBuilder::buildLineMesh(locations, edge_ids);
|
||||
}
|
||||
|
||||
std::unique_ptr<TriMesh> MeshPrimitives::buildRoundedRectangleAsTriMesh(double radius, double aspect_ratio, unsigned num_segments)
|
||||
{
|
||||
unsigned num_fans = 4;
|
||||
|
|
|
@ -6,6 +6,9 @@
|
|||
class MeshPrimitives
|
||||
{
|
||||
public:
|
||||
static std::unique_ptr<TriMesh> buildCircleAsTriMesh(unsigned numSegments = 24);
|
||||
|
||||
static std::unique_ptr<LineMesh> buildCircleAsLineMesh(unsigned numSegments = 24);
|
||||
|
||||
static std::unique_ptr<TriMesh> buildRectangleAsTriMesh();
|
||||
|
||||
|
|
|
@ -17,10 +17,10 @@ std::unique_ptr<VerticalSpacer> VerticalSpacer::Create()
|
|||
|
||||
void VerticalSpacer::addWidget(WidgetUPtr widget)
|
||||
{
|
||||
AddWidgetWithScale(std::move(widget), 1.0);
|
||||
addWidgetWithScale(std::move(widget), 1.0);
|
||||
}
|
||||
|
||||
void VerticalSpacer::AddWidgetWithScale(WidgetUPtr widget, double scale)
|
||||
void VerticalSpacer::addWidgetWithScale(WidgetUPtr widget, double scale)
|
||||
{
|
||||
Widget::addWidget(std::move(widget));
|
||||
mScales.push_back(scale);
|
||||
|
|
|
@ -12,7 +12,7 @@ public:
|
|||
|
||||
void addWidget(WidgetUPtr widget) override;
|
||||
|
||||
void AddWidgetWithScale(WidgetUPtr widget, double scale);
|
||||
void addWidgetWithScale(WidgetUPtr widget, double scale);
|
||||
|
||||
private:
|
||||
void updateChildLocations() override;
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
list(APPEND visual_elements_LIB_INCLUDES
|
||||
GeometryNode.cpp
|
||||
RectangleNode.cpp
|
||||
basic_shapes/RectangleNode.cpp
|
||||
basic_shapes/CircleNode.cpp
|
||||
basic_shapes/LineNode.cpp
|
||||
MaterialNode.cpp
|
||||
MeshNode.cpp
|
||||
TextNode.cpp
|
||||
|
@ -17,7 +19,8 @@ list(APPEND visual_elements_LIB_INCLUDES
|
|||
add_library(visual_elements SHARED ${visual_elements_LIB_INCLUDES})
|
||||
|
||||
target_include_directories(visual_elements PUBLIC
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/basic_shapes
|
||||
)
|
||||
|
||||
target_link_libraries(visual_elements PUBLIC core geometry fonts mesh image)
|
||||
|
|
|
@ -10,7 +10,9 @@ public:
|
|||
Path,
|
||||
Rectangle,
|
||||
Circle,
|
||||
Arc
|
||||
Arc,
|
||||
Line,
|
||||
Polyline
|
||||
};
|
||||
|
||||
public:
|
||||
|
@ -29,4 +31,19 @@ protected:
|
|||
bool mGeometryIsDirty{true};
|
||||
};
|
||||
|
||||
class LineNode : public GeometryNode
|
||||
{
|
||||
public:
|
||||
LineNode(const DiscretePoint& location)
|
||||
: GeometryNode(location)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Type getType()
|
||||
{
|
||||
return Type::Line;
|
||||
}
|
||||
};
|
||||
|
||||
using GeometryNodePtr = std::unique_ptr<GeometryNode>;
|
||||
|
|
83
src/visual_elements/basic_shapes/CircleNode.cpp
Normal file
83
src/visual_elements/basic_shapes/CircleNode.cpp
Normal file
|
@ -0,0 +1,83 @@
|
|||
#include "CircleNode.h"
|
||||
|
||||
#include "FontsManager.h"
|
||||
#include "SceneModel.h"
|
||||
#include "AbstractMesh.h"
|
||||
#include "MeshPrimitives.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
CircleNode::CircleNode(const DiscretePoint& location, unsigned radius)
|
||||
: GeometryNode(location),
|
||||
mRadius(radius)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CircleNode::Type CircleNode::getType()
|
||||
{
|
||||
return Type::Circle;
|
||||
}
|
||||
|
||||
unsigned CircleNode::getRadius() const
|
||||
{
|
||||
return mRadius;
|
||||
}
|
||||
|
||||
SceneItem* CircleNode::getSceneItem(std::size_t idx) const
|
||||
{
|
||||
if (idx == 0)
|
||||
{
|
||||
return mBackgroundItem.get();
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned CircleNode::getNumSceneItems() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
void CircleNode::setRadius(unsigned radius)
|
||||
{
|
||||
if (mRadius != radius)
|
||||
{
|
||||
mRadius = radius;
|
||||
mTransformIsDirty = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CircleNode::update(FontsManager* fontsManager)
|
||||
{
|
||||
if (!mBackgroundItem || mGeometryIsDirty)
|
||||
{
|
||||
auto mesh = MeshPrimitives::buildCircleAsTriMesh();
|
||||
|
||||
if (!mBackgroundItem)
|
||||
{
|
||||
mBackgroundItem = std::make_unique<SceneModel>(std::move(mesh));
|
||||
mBackgroundItem->setName(mName + "_Model");
|
||||
}
|
||||
else
|
||||
{
|
||||
mBackgroundItem->updateMesh(std::move(mesh));
|
||||
}
|
||||
mGeometryIsDirty = false;
|
||||
}
|
||||
|
||||
if (mTransformIsDirty)
|
||||
{
|
||||
mBackgroundItem->updateTransform({mLocation, static_cast<double>(2*mRadius), static_cast<double>(2*mRadius)});
|
||||
mTransformIsDirty = false;
|
||||
}
|
||||
|
||||
if (mMaterialIsDirty)
|
||||
{
|
||||
mBackgroundItem->updateUniformColor(mFillColor);
|
||||
mMaterialIsDirty = false;
|
||||
}
|
||||
}
|
25
src/visual_elements/basic_shapes/CircleNode.h
Normal file
25
src/visual_elements/basic_shapes/CircleNode.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
#pragma once
|
||||
|
||||
#include "GeometryNode.h"
|
||||
|
||||
class CircleNode : public GeometryNode
|
||||
{
|
||||
public:
|
||||
CircleNode(const DiscretePoint& location, unsigned radius);
|
||||
|
||||
Type getType();
|
||||
|
||||
unsigned getRadius() const;
|
||||
|
||||
SceneItem* getSceneItem(std::size_t idx) const override;
|
||||
unsigned getNumSceneItems() const override;
|
||||
|
||||
void setRadius(unsigned radius);
|
||||
|
||||
void update(FontsManager* fontsManager) override;
|
||||
private:
|
||||
unsigned mRadius{1};
|
||||
|
||||
std::unique_ptr<SceneModel> mBackgroundItem;
|
||||
std::unique_ptr<SceneModel> mOutlineItem;
|
||||
};
|
0
src/visual_elements/basic_shapes/LineNode.cpp
Normal file
0
src/visual_elements/basic_shapes/LineNode.cpp
Normal file
0
src/visual_elements/basic_shapes/LineNode.cppcd
Normal file
0
src/visual_elements/basic_shapes/LineNode.cppcd
Normal file
0
src/visual_elements/basic_shapes/LineNode.h
Normal file
0
src/visual_elements/basic_shapes/LineNode.h
Normal file
|
@ -1,9 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "GeometryNode.h"
|
||||
#include "DiscretePoint.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
class RectangleNode : public GeometryNode
|
||||
{
|
Loading…
Add table
Add a link
Reference in a new issue