Sun, 25 Jul 2021 13:49:37 +0300
work on editing tools
src/document.cpp | file | annotate | diff | comparison | revisions | |
src/document.h | file | annotate | diff | comparison | revisions | |
src/geometry.h | file | annotate | diff | comparison | revisions | |
src/mainwindow.cpp | file | annotate | diff | comparison | revisions | |
src/mainwindow.h | file | annotate | diff | comparison | revisions | |
src/tools/basetool.h | file | annotate | diff | comparison | revisions | |
src/tools/drawtool.cpp | file | annotate | diff | comparison | revisions | |
src/tools/drawtool.h | file | annotate | diff | comparison | revisions | |
src/ui/canvas.cpp | file | annotate | diff | comparison | revisions | |
src/ui/canvas.h | file | annotate | diff | comparison | revisions |
--- a/src/document.cpp Sat Jul 24 01:50:38 2021 +0300 +++ b/src/document.cpp Sun Jul 25 13:49:37 2021 +0300 @@ -72,6 +72,7 @@ }); connect(this->model, &Model::dataChanged, this->renderer, qOverload<>(&Canvas::update)); connect(this->renderer, &Canvas::mouseClick, this, &Document::mouseClick); + connect(this->renderer, &Canvas::mouseMove, this, &Document::mouseMove); } Document::~Document()
--- a/src/document.h Sat Jul 24 01:50:38 2021 +0300 +++ b/src/document.h Sun Jul 25 13:49:37 2021 +0300 @@ -46,6 +46,7 @@ void newStatusText(const QString& newStatusText); void splitterChanged(); void mouseClick(const Canvas::MouseClickInfo& info); + void mouseMove(const Canvas::MouseMoveInfo& info); private: void selectionChanged(const QSet<ldraw::id_t>& newSelection); Model* model;
--- a/src/geometry.h Sat Jul 24 01:50:38 2021 +0300 +++ b/src/geometry.h Sun Jul 25 13:49:37 2021 +0300 @@ -103,10 +103,31 @@ std::vector<glm::vec3> points; }; - inline bool isclose(const glm::vec3& a, const glm::vec3& b) + inline constexpr bool isclose(const glm::vec3& a, const glm::vec3& b) { return qFuzzyCompare(a.x, b.x) and qFuzzyCompare(a.y, b.y) and qFuzzyCompare(a.z, b.z); } + + struct CircleF + { + QPointF center; + qreal radius; + }; + + /** + * @param center + * @param radius + * @returns a QRectF that encloses the specified circle + */ + inline constexpr QRectF inscribe(const CircleF& circle) + { + return { + circle.center.x() - circle.radius, + circle.center.y() - circle.radius, + circle.radius * 2, + circle.radius * 2 + }; + } }
--- a/src/mainwindow.cpp Sat Jul 24 01:50:38 2021 +0300 +++ b/src/mainwindow.cpp Sun Jul 25 13:49:37 2021 +0300 @@ -213,6 +213,7 @@ document->restoreSplitterState(this->documentSplitterState); connect(document, &Document::splitterChanged, this, &MainWindow::handleDocumentSplitterChange); connect(document, &Document::mouseClick, this, &MainWindow::canvasMouseReleased); + connect(document, &Document::mouseMove, this, &MainWindow::canvasMouseMoved); } void MainWindow::runSettingsEditor() @@ -429,9 +430,12 @@ Q_UNUSED(event) } -void MainWindow::canvasMouseMoved(QMouseEvent* event) +void MainWindow::canvasMouseMoved(const Canvas::MouseMoveInfo& info) { - Q_UNUSED(event) + if (this->selectedTool != nullptr) + { + this->selectedTool->mouseMove(info); + } } void MainWindow::canvasKeyReleased(QKeyEvent* event)
--- a/src/mainwindow.h Sat Jul 24 01:50:38 2021 +0300 +++ b/src/mainwindow.h Sun Jul 25 13:49:37 2021 +0300 @@ -78,6 +78,6 @@ void canvasMousePressed(QMouseEvent* event); void canvasMouseReleased(const Canvas::MouseClickInfo& info); void canvasMouseDoubleClicked(QMouseEvent* event); - void canvasMouseMoved(QMouseEvent*); + void canvasMouseMoved(const Canvas::MouseMoveInfo& info); void canvasKeyReleased(QKeyEvent*); };
--- a/src/tools/basetool.h Sat Jul 24 01:50:38 2021 +0300 +++ b/src/tools/basetool.h Sun Jul 25 13:49:37 2021 +0300 @@ -15,7 +15,7 @@ virtual bool mousePressed(QMouseEvent*) { return false; } virtual bool mouseClick(const Canvas::MouseClickInfo&) { return false; } virtual bool mouseDoubleClicked(QMouseEvent*) { return false; } - virtual bool mouseMoved(QMouseEvent*) { return false; } + virtual bool mouseMove(const Canvas::MouseMoveInfo&) { return false; } virtual bool keyReleased(QKeyEvent*) { return false; } virtual void reset() {} };
--- a/src/tools/drawtool.cpp Sat Jul 24 01:50:38 2021 +0300 +++ b/src/tools/drawtool.cpp Sun Jul 25 13:49:37 2021 +0300 @@ -1,6 +1,10 @@ #include <QMessageBox> #include "drawtool.h" +static const QBrush brush = {Qt::white}; +static const QPen pen = {Qt::black}; +static const QBrush polygonBrush = {QColor{64, 255, 128}}; + DrawTool::DrawTool(QObject* parent) : BaseTool{parent} {} @@ -29,9 +33,11 @@ else { this->polygon.push_back(pos); - auto& previewLayer = info.invoker->modifyPreviewLayer(Canvas::DrawToolPreview).polygons; - previewLayer.clear(); - previewLayer.push_back({this->polygon}); + auto& previewLayer = info.invoker->modifyPreviewLayer(Canvas::DrawToolPreview); + previewLayer.points.resize(this->polygon.size()); + previewLayer.points.back() = {pos, brush, pen}; + previewLayer.polygons.clear(); + previewLayer.polygons.push_back({geom::NPolygon{this->polygon}, polygonBrush, pen}); if (this->polygon.size() == 4) { QMessageBox::information(nullptr, "test", "close the polygon"); @@ -41,6 +47,27 @@ return true; } +bool DrawTool::mouseMove(const Canvas::MouseMoveInfo& info) +{ + if (this->polygon.size() < 4 and info.worldPosition.has_value()) + { + auto& previewLayer = info.invoker->modifyPreviewLayer(Canvas::DrawToolPreview); + previewLayer.points.resize(this->polygon.size() + 1); + previewLayer.points.back() = {info.worldPosition.value(), brush, pen}; + if (previewLayer.polygons.size() > 0) + { + auto& polygon = previewLayer.polygons.back(); + polygon.geometry.points.resize(this->polygon.size() + 1); + polygon.geometry.points.back() = info.worldPosition.value(); + } + return true; + } + else + { + return false; + } +} + void DrawTool::reset() { this->polygon.clear();
--- a/src/tools/drawtool.h Sat Jul 24 01:50:38 2021 +0300 +++ b/src/tools/drawtool.h Sun Jul 25 13:49:37 2021 +0300 @@ -11,6 +11,7 @@ QString name() const override; QString toolTip() const override; bool mouseClick(const Canvas::MouseClickInfo& info) override; + bool mouseMove(const Canvas::MouseMoveInfo&) override; void reset() override; private: std::vector<glm::vec3> polygon;
--- a/src/ui/canvas.cpp Sat Jul 24 01:50:38 2021 +0300 +++ b/src/ui/canvas.cpp Sun Jul 25 13:49:37 2021 +0300 @@ -77,6 +77,10 @@ this->updateGridMatrix(); this->update(); } + MouseMoveInfo info; + info.invoker = this; + info.worldPosition = this->worldPosition; + emit mouseMove(info); PartRenderer::mouseMoveEvent(event); } @@ -225,16 +229,27 @@ } for (const PreviewLayer& previewLayer : this->previewLayers) { - painter.setBrush({previewLayer.color}); - for (const geom::NPolygon& polygon3d : previewLayer.polygons) + for (const PreviewLayer::Polygon& polygon3d : previewLayer.polygons) { + painter.setBrush(polygon3d.brush); + painter.setPen(polygon3d.pen); QVector<QPointF> points2d; - points2d.reserve(polygon3d.points.size()); - for (const glm::vec3& point : polygon3d.points) + points2d.reserve(polygon3d.geometry.points.size()); + for (const glm::vec3& point : polygon3d.geometry.points) { points2d.push_back(this->modelToScreenCoordinates(point)); } - painter.drawPolygon({points2d}); + painter.drawPolygon(QPolygonF{points2d}); + } + for (const PreviewLayer::Point& point : previewLayer.points) + { + const geom::CircleF circle = { + this->modelToScreenCoordinates(point.location), + 5.0, + }; + painter.setBrush(point.brush); + painter.setPen(point.pen); + painter.drawEllipse(geom::inscribe(circle)); } } }
--- a/src/ui/canvas.h Sat Jul 24 01:50:38 2021 +0300 +++ b/src/ui/canvas.h Sun Jul 25 13:49:37 2021 +0300 @@ -1,4 +1,6 @@ #pragma once +#include <QBrush> +#include <QPen> #include "gl/partrenderer.h" #include "gl/gridprogram.h" #include "gl/axesprogram.h" @@ -8,14 +10,27 @@ Q_OBJECT public: struct MouseClickInfo; + struct MouseMoveInfo; enum PreviewLayerName : std::int8_t { DrawToolPreview }; struct PreviewLayer { - QVector<geom::NPolygon> polygons; - QColor color{64, 255, 128}; + struct Point + { + glm::vec3 location; + QBrush brush = {}; + QPen pen = {}; + }; + struct Polygon + { + geom::NPolygon geometry; + QBrush brush = {}; + QPen pen = {}; + }; + QVector<Point> points; + QVector<Polygon> polygons; }; static constexpr int NUM_PREVIEW_LAYERS = 1; @@ -40,6 +55,7 @@ void newStatusText(const QString& newStatusText); void selectionChanged(const QSet<ldraw::id_t>& newSelection); void mouseClick(const MouseClickInfo& info); + void mouseMove(const MouseMoveInfo& info); private: void updateGridMatrix(); glm::vec3 cameraVector() const; @@ -59,3 +75,9 @@ std::optional<glm::vec3> worldPosition; Canvas* invoker; }; + +struct Canvas::MouseMoveInfo +{ + std::optional<glm::vec3> worldPosition; + Canvas* invoker; +};