Simple drawing example.
This commit is contained in:
parent
d7fe11913f
commit
f0091f9e04
27 changed files with 450 additions and 68 deletions
|
@ -13,12 +13,13 @@ list(APPEND client_HEADERS
|
||||||
image_editor/ImageViewWidget.h
|
image_editor/ImageViewWidget.h
|
||||||
canvas/CanvasView.h
|
canvas/CanvasView.h
|
||||||
canvas/CanvasController.h
|
canvas/CanvasController.h
|
||||||
|
canvas/CanvasDrawingArea.h
|
||||||
|
canvas/CanvasCommandSelectorView.h
|
||||||
mesh_viewer/MeshViewerView.h
|
mesh_viewer/MeshViewerView.h
|
||||||
mesh_viewer/MeshViewerController.h
|
mesh_viewer/MeshViewerController.h
|
||||||
mesh_viewer/MeshViewerCanvas.h
|
mesh_viewer/MeshViewerCanvas.h
|
||||||
web_client/WebClientView.h)
|
web_client/WebClientView.h)
|
||||||
|
|
||||||
|
|
||||||
list(APPEND client_LIB_INCLUDES
|
list(APPEND client_LIB_INCLUDES
|
||||||
text_editor/TextEditorView.cpp
|
text_editor/TextEditorView.cpp
|
||||||
text_editor/TextEditorModel.cpp
|
text_editor/TextEditorModel.cpp
|
||||||
|
@ -32,6 +33,8 @@ list(APPEND client_LIB_INCLUDES
|
||||||
mesh_viewer/MeshViewerCanvas.cpp
|
mesh_viewer/MeshViewerCanvas.cpp
|
||||||
canvas/CanvasView.cpp
|
canvas/CanvasView.cpp
|
||||||
canvas/CanvasController.cpp
|
canvas/CanvasController.cpp
|
||||||
|
canvas/CanvasDrawingArea.cpp
|
||||||
|
canvas/CanvasCommandSelectorView.cpp
|
||||||
web_client/WebClientView.cpp
|
web_client/WebClientView.cpp
|
||||||
NotesTk.cpp)
|
NotesTk.cpp)
|
||||||
|
|
||||||
|
|
42
apps/notes_tk/canvas/CanvasCommandSelectorView.cpp
Normal file
42
apps/notes_tk/canvas/CanvasCommandSelectorView.cpp
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
#include "CanvasCommandSelectorView.h"
|
||||||
|
|
||||||
|
#include "HorizontalSpacer.h"
|
||||||
|
#include "Button.h"
|
||||||
|
#include "Theme.h"
|
||||||
|
|
||||||
|
CanvasCommandSelectorView::CanvasCommandSelectorView()
|
||||||
|
: Widget()
|
||||||
|
{
|
||||||
|
auto circle_button = Button::Create();
|
||||||
|
|
||||||
|
auto on_circle_click = [this](Widget* self){
|
||||||
|
onCommandSelected(CanvasDrawCommand::CIRCLE);
|
||||||
|
};
|
||||||
|
circle_button->setLabel("Circle");
|
||||||
|
circle_button->setBackgroundColor(Theme::getButtonPrimaryBackground());
|
||||||
|
circle_button->setMargin(2);
|
||||||
|
circle_button->setOnClickFunction(on_circle_click);
|
||||||
|
|
||||||
|
auto on_line_click = [this](Widget* self){
|
||||||
|
onCommandSelected(CanvasDrawCommand::LINE);
|
||||||
|
};
|
||||||
|
auto line_button = Button::Create();
|
||||||
|
line_button->setLabel("Line");
|
||||||
|
line_button->setBackgroundColor(Theme::getButtonPrimaryBackground());
|
||||||
|
line_button->setMargin(2);
|
||||||
|
line_button->setOnClickFunction(on_line_click);
|
||||||
|
|
||||||
|
auto hspacer = HorizontalSpacer::Create();
|
||||||
|
hspacer->addWidgetWithScale(std::move(circle_button), 1);
|
||||||
|
hspacer->addWidgetWithScale(std::move(line_button), 1);
|
||||||
|
|
||||||
|
addWidget(std::move(hspacer));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CanvasCommandSelectorView::onCommandSelected(CanvasDrawCommand command)
|
||||||
|
{
|
||||||
|
if(mCommandSelectedCallback)
|
||||||
|
{
|
||||||
|
mCommandSelectedCallback(command);
|
||||||
|
}
|
||||||
|
}
|
24
apps/notes_tk/canvas/CanvasCommandSelectorView.h
Normal file
24
apps/notes_tk/canvas/CanvasCommandSelectorView.h
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Widget.h"
|
||||||
|
#include "CanvasElements.h"
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
class CanvasCommandSelectorView : public Widget
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
using onCommandSelectedFunc = std::function<void(CanvasDrawCommand command)>;
|
||||||
|
CanvasCommandSelectorView();
|
||||||
|
|
||||||
|
void setCommandSelectedCallback(onCommandSelectedFunc func)
|
||||||
|
{
|
||||||
|
mCommandSelectedCallback = func;
|
||||||
|
}
|
||||||
|
|
||||||
|
void onCommandSelected(CanvasDrawCommand command);
|
||||||
|
|
||||||
|
private:
|
||||||
|
onCommandSelectedFunc mCommandSelectedCallback{nullptr};
|
||||||
|
};
|
54
apps/notes_tk/canvas/CanvasDrawingArea.cpp
Normal file
54
apps/notes_tk/canvas/CanvasDrawingArea.cpp
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
#include "CanvasDrawingArea.h"
|
||||||
|
|
||||||
|
#include "MouseEvent.h"
|
||||||
|
|
||||||
|
#include "GeometryNode.h"
|
||||||
|
#include "TransformNode.h"
|
||||||
|
#include "CircleNode.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
CanvasDrawingArea::~CanvasDrawingArea()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void CanvasDrawingArea::addShapeAt(unsigned x, unsigned y)
|
||||||
|
{
|
||||||
|
if (mActiveDrawingCommand == CanvasDrawCommand::CIRCLE)
|
||||||
|
{
|
||||||
|
auto circle = std::make_unique<CircleNode>(DiscretePoint(x, y), 5);
|
||||||
|
circle->setFillColor(Color(255, 0, 0));
|
||||||
|
circle->setName("CanvasDrawingArea_CircleNode");
|
||||||
|
|
||||||
|
mRootNode->addChild(circle.get());
|
||||||
|
|
||||||
|
mSceneNodes.push_back(std::move(circle));
|
||||||
|
mContentDirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CanvasDrawingArea::isDirty() const
|
||||||
|
{
|
||||||
|
return Widget::isDirty() || mContentDirty;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CanvasDrawingArea::doPaint(const PaintEvent* event)
|
||||||
|
{
|
||||||
|
mContentDirty = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CanvasDrawingArea::onMyMouseEvent(const MouseEvent* event)
|
||||||
|
{
|
||||||
|
if(event->GetAction() == MouseEvent::Action::Pressed)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
else if(event->GetAction() == MouseEvent::Action::Released)
|
||||||
|
{
|
||||||
|
auto client_loc = event->GetClientLocation();
|
||||||
|
auto screen_loc = event->GetScreenLocation();
|
||||||
|
|
||||||
|
addShapeAt(client_loc.GetX(), client_loc.GetY());
|
||||||
|
}
|
||||||
|
}
|
29
apps/notes_tk/canvas/CanvasDrawingArea.h
Normal file
29
apps/notes_tk/canvas/CanvasDrawingArea.h
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Widget.h"
|
||||||
|
#include "CanvasElements.h"
|
||||||
|
|
||||||
|
class GeometryNode;
|
||||||
|
|
||||||
|
class CanvasDrawingArea : public Widget
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
~CanvasDrawingArea();
|
||||||
|
void setActiveDrawingCommand(CanvasDrawCommand command)
|
||||||
|
{
|
||||||
|
mActiveDrawingCommand = command;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool isDirty() const override;
|
||||||
|
void doPaint(const PaintEvent* event) override;
|
||||||
|
|
||||||
|
void onMyMouseEvent(const MouseEvent* event) override;
|
||||||
|
|
||||||
|
void addShapeAt(unsigned x, unsigned y);
|
||||||
|
|
||||||
|
CanvasDrawCommand mActiveDrawingCommand{CanvasDrawCommand::LINE};
|
||||||
|
|
||||||
|
std::vector<std::unique_ptr<GeometryNode> > mSceneNodes;
|
||||||
|
bool mContentDirty{false};
|
||||||
|
};
|
7
apps/notes_tk/canvas/CanvasElements.h
Normal file
7
apps/notes_tk/canvas/CanvasElements.h
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
enum class CanvasDrawCommand
|
||||||
|
{
|
||||||
|
CIRCLE,
|
||||||
|
LINE
|
||||||
|
};
|
|
@ -4,15 +4,16 @@
|
||||||
#include "VerticalSpacer.h"
|
#include "VerticalSpacer.h"
|
||||||
|
|
||||||
#include "CanvasController.h"
|
#include "CanvasController.h"
|
||||||
|
#include "CanvasDrawingArea.h"
|
||||||
|
#include "CanvasCommandSelectorView.h"
|
||||||
|
|
||||||
#include "Theme.h"
|
#include "Theme.h"
|
||||||
|
|
||||||
#include "TextNode.h"
|
#include "TextNode.h"
|
||||||
|
#include "GeometryNode.h"
|
||||||
|
|
||||||
#include "Label.h"
|
#include "Label.h"
|
||||||
#include "Button.h"
|
#include "Button.h"
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
CanvasView::CanvasView()
|
CanvasView::CanvasView()
|
||||||
: mController(CanvasController::Create())
|
: mController(CanvasController::Create())
|
||||||
{
|
{
|
||||||
|
@ -36,11 +37,28 @@ void CanvasView::initialize()
|
||||||
label->setBackgroundColor(Theme::getBannerBackground());
|
label->setBackgroundColor(Theme::getBannerBackground());
|
||||||
label->setMargin(1);
|
label->setMargin(1);
|
||||||
|
|
||||||
|
auto controls = std::make_unique<CanvasCommandSelectorView>();
|
||||||
|
controls->setBackgroundColor(Theme::getBannerBackground());
|
||||||
|
controls->setMargin(1);
|
||||||
|
|
||||||
|
auto on_draw_command_changed = [this](CanvasDrawCommand command){
|
||||||
|
onDrawCommandChanged(command);
|
||||||
|
};
|
||||||
|
controls->setCommandSelectedCallback(on_draw_command_changed);
|
||||||
|
|
||||||
|
auto drawing_area = std::make_unique<CanvasDrawingArea>();
|
||||||
|
drawing_area->setBackgroundColor(Theme::getBackgroundPrimary());
|
||||||
|
drawing_area->setMargin(1);
|
||||||
|
mDrawingArea = drawing_area.get();
|
||||||
|
|
||||||
|
auto control_draw_vspacer = VerticalSpacer::Create();
|
||||||
|
control_draw_vspacer->addWidgetWithScale(std::move(controls), 1);
|
||||||
|
control_draw_vspacer->addWidgetWithScale(std::move(drawing_area), 10);
|
||||||
|
|
||||||
auto hSpacer = HorizontalSpacer::Create();
|
auto hSpacer = HorizontalSpacer::Create();
|
||||||
hSpacer->addWidgetWithScale(std::move(label), 1);
|
hSpacer->addWidgetWithScale(std::move(label), 1);
|
||||||
//hSpacer->addWidgetWithScale(std::move(textBox), 14);
|
|
||||||
|
hSpacer->addWidgetWithScale(std::move(control_draw_vspacer), 10);
|
||||||
|
|
||||||
auto cache_button_spacer = initializeCacheButtons();
|
auto cache_button_spacer = initializeCacheButtons();
|
||||||
hSpacer->addWidgetWithScale(std::move(cache_button_spacer), 1);
|
hSpacer->addWidgetWithScale(std::move(cache_button_spacer), 1);
|
||||||
|
@ -48,6 +66,11 @@ void CanvasView::initialize()
|
||||||
addWidget(std::move(hSpacer));
|
addWidget(std::move(hSpacer));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CanvasView::onDrawCommandChanged(CanvasDrawCommand command)
|
||||||
|
{
|
||||||
|
mDrawingArea->setActiveDrawingCommand(command);
|
||||||
|
}
|
||||||
|
|
||||||
std::unique_ptr<Widget> CanvasView::initializeCacheButtons()
|
std::unique_ptr<Widget> CanvasView::initializeCacheButtons()
|
||||||
{
|
{
|
||||||
auto saveButton = Button::Create();
|
auto saveButton = Button::Create();
|
||||||
|
@ -66,10 +89,9 @@ std::unique_ptr<Widget> CanvasView::initializeCacheButtons()
|
||||||
loadButton->setMargin(2);
|
loadButton->setMargin(2);
|
||||||
|
|
||||||
auto buttonSpacer = VerticalSpacer::Create();
|
auto buttonSpacer = VerticalSpacer::Create();
|
||||||
buttonSpacer->AddWidgetWithScale(std::move(saveButton), 1);
|
buttonSpacer->addWidgetWithScale(std::move(saveButton), 1);
|
||||||
buttonSpacer->AddWidgetWithScale(std::move(clearButton), 1);
|
buttonSpacer->addWidgetWithScale(std::move(clearButton), 1);
|
||||||
buttonSpacer->AddWidgetWithScale(std::move(loadButton), 1);
|
buttonSpacer->addWidgetWithScale(std::move(loadButton), 1);
|
||||||
|
|
||||||
return buttonSpacer;
|
return buttonSpacer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Widget.h"
|
#include "Widget.h"
|
||||||
|
#include "CanvasElements.h"
|
||||||
|
|
||||||
class CanvasController;
|
class CanvasController;
|
||||||
|
class CanvasDrawingArea;
|
||||||
|
|
||||||
class CanvasView : public Widget
|
class CanvasView : public Widget
|
||||||
{
|
{
|
||||||
|
@ -14,13 +16,14 @@ public:
|
||||||
static std::unique_ptr<CanvasView> Create();
|
static std::unique_ptr<CanvasView> Create();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void onDrawCommandChanged(CanvasDrawCommand command);
|
||||||
|
|
||||||
void initialize();
|
void initialize();
|
||||||
|
|
||||||
std::unique_ptr<Widget> initializeCacheButtons();
|
std::unique_ptr<Widget> initializeCacheButtons();
|
||||||
|
|
||||||
//std::unique_ptr<Widget> initializeCacheButtons();
|
|
||||||
|
|
||||||
std::unique_ptr<CanvasController> mController;
|
std::unique_ptr<CanvasController> mController;
|
||||||
|
|
||||||
|
CanvasDrawingArea* mDrawingArea{nullptr};
|
||||||
};
|
};
|
||||||
using CanvasViewPtr = std::unique_ptr<CanvasView>;
|
using CanvasViewPtr = std::unique_ptr<CanvasView>;
|
||||||
|
|
|
@ -72,9 +72,9 @@ void TextEditorView::initialize()
|
||||||
loadButton->setOnClickFunction(onLoad);
|
loadButton->setOnClickFunction(onLoad);
|
||||||
|
|
||||||
auto buttonSpacer = VerticalSpacer::Create();
|
auto buttonSpacer = VerticalSpacer::Create();
|
||||||
buttonSpacer->AddWidgetWithScale(std::move(saveButton), 1);
|
buttonSpacer->addWidgetWithScale(std::move(saveButton), 1);
|
||||||
buttonSpacer->AddWidgetWithScale(std::move(clearButton), 1);
|
buttonSpacer->addWidgetWithScale(std::move(clearButton), 1);
|
||||||
buttonSpacer->AddWidgetWithScale(std::move(loadButton), 1);
|
buttonSpacer->addWidgetWithScale(std::move(loadButton), 1);
|
||||||
|
|
||||||
auto hSpacer = HorizontalSpacer::Create();
|
auto hSpacer = HorizontalSpacer::Create();
|
||||||
hSpacer->addWidgetWithScale(std::move(label), 1);
|
hSpacer->addWidgetWithScale(std::move(label), 1);
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
class TextEditorView : public Widget
|
class TextEditorView : public Widget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
TextEditorView();
|
TextEditorView();
|
||||||
|
|
||||||
static std::unique_ptr<TextEditorView> Create();
|
static std::unique_ptr<TextEditorView> Create();
|
||||||
|
|
|
@ -17,8 +17,8 @@ TabbedPanelWidget::TabbedPanelWidget()
|
||||||
nav->setSize({0, 0, 0, 0, 200, 0});
|
nav->setSize({0, 0, 0, 0, 200, 0});
|
||||||
|
|
||||||
auto vertSpacer = VerticalSpacer::Create();
|
auto vertSpacer = VerticalSpacer::Create();
|
||||||
vertSpacer->AddWidgetWithScale(std::move(nav), 1);
|
vertSpacer->addWidgetWithScale(std::move(nav), 1);
|
||||||
vertSpacer->AddWidgetWithScale(std::move(stack), 4);
|
vertSpacer->addWidgetWithScale(std::move(stack), 4);
|
||||||
addWidget(std::move(vertSpacer));
|
addWidget(std::move(vertSpacer));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -110,6 +110,7 @@ void OpenGlMeshPainter::paint(SceneModel* model, DrawingContext* context)
|
||||||
auto y = vertices[idx]*transform.getScaleY() + transform.getLocation().getY();
|
auto y = vertices[idx]*transform.getScaleY() + transform.getLocation().getY();
|
||||||
vertices[idx] = 1.0 - 2*y/height;
|
vertices[idx] = 1.0 - 2*y/height;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<unsigned> indices;
|
std::vector<unsigned> indices;
|
||||||
|
|
|
@ -32,6 +32,74 @@ std::unique_ptr<TriMesh> MeshPrimitives::buildRectangleAsTriMesh()
|
||||||
return MeshBuilder::buildTriMesh(locations, edge_ids, face_ids);
|
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)
|
std::unique_ptr<TriMesh> MeshPrimitives::buildRoundedRectangleAsTriMesh(double radius, double aspect_ratio, unsigned num_segments)
|
||||||
{
|
{
|
||||||
unsigned num_fans = 4;
|
unsigned num_fans = 4;
|
||||||
|
|
|
@ -6,6 +6,9 @@
|
||||||
class MeshPrimitives
|
class MeshPrimitives
|
||||||
{
|
{
|
||||||
public:
|
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();
|
static std::unique_ptr<TriMesh> buildRectangleAsTriMesh();
|
||||||
|
|
||||||
|
|
|
@ -17,10 +17,10 @@ std::unique_ptr<VerticalSpacer> VerticalSpacer::Create()
|
||||||
|
|
||||||
void VerticalSpacer::addWidget(WidgetUPtr widget)
|
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));
|
Widget::addWidget(std::move(widget));
|
||||||
mScales.push_back(scale);
|
mScales.push_back(scale);
|
||||||
|
|
|
@ -12,7 +12,7 @@ public:
|
||||||
|
|
||||||
void addWidget(WidgetUPtr widget) override;
|
void addWidget(WidgetUPtr widget) override;
|
||||||
|
|
||||||
void AddWidgetWithScale(WidgetUPtr widget, double scale);
|
void addWidgetWithScale(WidgetUPtr widget, double scale);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateChildLocations() override;
|
void updateChildLocations() override;
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
list(APPEND visual_elements_LIB_INCLUDES
|
list(APPEND visual_elements_LIB_INCLUDES
|
||||||
GeometryNode.cpp
|
GeometryNode.cpp
|
||||||
RectangleNode.cpp
|
basic_shapes/RectangleNode.cpp
|
||||||
|
basic_shapes/CircleNode.cpp
|
||||||
|
basic_shapes/LineNode.cpp
|
||||||
MaterialNode.cpp
|
MaterialNode.cpp
|
||||||
MeshNode.cpp
|
MeshNode.cpp
|
||||||
TextNode.cpp
|
TextNode.cpp
|
||||||
|
@ -17,7 +19,8 @@ list(APPEND visual_elements_LIB_INCLUDES
|
||||||
add_library(visual_elements SHARED ${visual_elements_LIB_INCLUDES})
|
add_library(visual_elements SHARED ${visual_elements_LIB_INCLUDES})
|
||||||
|
|
||||||
target_include_directories(visual_elements PUBLIC
|
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)
|
target_link_libraries(visual_elements PUBLIC core geometry fonts mesh image)
|
||||||
|
|
|
@ -10,7 +10,9 @@ public:
|
||||||
Path,
|
Path,
|
||||||
Rectangle,
|
Rectangle,
|
||||||
Circle,
|
Circle,
|
||||||
Arc
|
Arc,
|
||||||
|
Line,
|
||||||
|
Polyline
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -29,4 +31,19 @@ protected:
|
||||||
bool mGeometryIsDirty{true};
|
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>;
|
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
|
#pragma once
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#include "GeometryNode.h"
|
#include "GeometryNode.h"
|
||||||
#include "DiscretePoint.h"
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
class RectangleNode : public GeometryNode
|
class RectangleNode : public GeometryNode
|
||||||
{
|
{
|
Loading…
Reference in a new issue