--- a/src/ui/canvas.cpp Wed May 25 17:56:30 2022 +0300 +++ b/src/ui/canvas.cpp Wed May 25 18:29:49 2022 +0300 @@ -3,9 +3,6 @@ #include "modeleditor.h" #include "document.h" #include "canvas.h" -#include "linetypes/edge.h" -#include "linetypes/triangle.h" -#include "linetypes/quadrilateral.h" Canvas::Canvas( Model* model, @@ -46,31 +43,6 @@ } } -void updatePreviewPolygon(DrawState* drawState) -{ - drawState->previewPolygon = drawState->polygon; - drawState->previewPolygon.resize(drawState->polygon.size() + 1); - drawState->previewPolygon.back() = drawState->previewPoint; - if (drawState->previewPolygon.size() > 2) - { - drawState->isconcave = not geom::isConvex(drawState->previewPolygon); - } -} - -void removeLastPoint(DrawState* drawState) -{ - if (drawState->polygon.size() > 0) - { - drawState->polygon.erase(drawState->polygon.end() - 1); - updatePreviewPolygon(drawState); - } -} - -bool isCloseToExistingPoints(const std::vector<glm::vec3>& points, const glm::vec3 &pos) -{ - return any(points, std::bind(geom::isclose, std::placeholders::_1, pos)); -} - void Canvas::mouseMoveEvent(QMouseEvent* event) { const ldraw::id_t id = this->pick(event->pos()); @@ -94,21 +66,7 @@ // grid matrix. this->worldPosition = this->gridMatrix * glm::vec4{*this->worldPosition, 1}; } - switch(this->mode) - { - case SelectMode: - break; - case DrawMode: - const auto& worldPosition = this->getWorldPosition(); - if (worldPosition.has_value()) - { - this->drawState.previewPoint = worldPosition.value(); - updatePreviewPolygon(&this->drawState); - this->update(); - } - event->accept(); - break; - } + Q_EMIT this->mouseMove(event); PartRenderer::mouseMoveEvent(event); this->update(); } @@ -124,45 +82,7 @@ { if (this->totalMouseMove < (2.0 / sqrt(2)) * 5.0) { - switch(this->mode) - { - case SelectMode: - if (event->button() == Qt::LeftButton) - { - const ldraw::id_t highlighted = this->getHighlightedObject(); - this->clearSelection(); - if (highlighted != ldraw::NULL_ID) - { - this->addToSelection(highlighted); - } - event->accept(); - } - break; - case DrawMode: - if (event->button() == Qt::LeftButton and this->worldPosition.has_value()) - { - const glm::vec3& pos = worldPosition.value(); - if (isCloseToExistingPoints(this->drawState.polygon, pos)) - { - this->closeShape(); - } - else - { - this->drawState.polygon.push_back(pos); - updatePreviewPolygon(&this->drawState); - } - event->accept(); - } - else if (true - and event->button() == Qt::RightButton - and this->drawState.polygon.size() > 0 - ) { - this->drawState.polygon.erase(this->drawState.polygon.end() - 1); - updatePreviewPolygon(&this->drawState); - event->accept(); - } - break; - } + Q_EMIT this->mouseClick(event); } PartRenderer::mouseReleaseEvent(event); this->update(); @@ -208,6 +128,11 @@ const QBrush redPolygonBrush = {QColor{255, 96, 96, 192}}; } pens; +static void renderDrawState( + QPainter* painter, + Canvas* canvas, + DrawState* drawState); + void Canvas::paintGL() { PartRenderer::paintGL(); @@ -254,39 +179,49 @@ { this->renderAxesLabels(painter); } - switch(this->mode) + if (this->drawState != nullptr) { + renderDrawState(&painter, this, this->drawState); + } + } +} + +static void renderDrawState( + QPainter* painter, + Canvas* canvas, + DrawState* drawState) +{ + switch(drawState->mode) + { + case SelectMode: + break; + case DrawMode: { - case SelectMode: - break; - case DrawMode: + painter->setPen(drawState->isconcave ? ::pens.badPolygonPen : ::pens.polygonPen); + if (drawState->previewPolygon.size() > 2 and not drawState->isconcave) { - painter.setPen(this->drawState.isconcave ? ::pens.badPolygonPen : ::pens.polygonPen); - if (this->drawState.previewPolygon.size() > 2 and not this->drawState.isconcave) + if (canvas->worldPolygonWinding(drawState->previewPolygon) == Winding::Clockwise) { - if (this->worldPolygonWinding(this->drawState.previewPolygon) == Winding::Clockwise) - { - painter.setBrush(::pens.greenPolygonBrush); - } - else - { - painter.setBrush(::pens.redPolygonBrush); - } - this->drawWorldPolygon(&painter, this->drawState.previewPolygon); + painter->setBrush(::pens.greenPolygonBrush); } else { - this->drawWorldPolyline(&painter, this->drawState.previewPolygon); + painter->setBrush(::pens.redPolygonBrush); } - painter.setBrush(::pens.pointBrush); - painter.setPen(::pens.pointPen); - for (const glm::vec3& point : this->drawState.polygon) - { - this->drawWorldPoint(&painter, point); - } - this->drawWorldPoint(&painter, this->drawState.previewPoint); + canvas->drawWorldPolygon(painter, drawState->previewPolygon); + } + else + { + canvas->drawWorldPolyline(painter, drawState->previewPolygon); } - break; + painter->setBrush(::pens.pointBrush); + painter->setPen(::pens.pointPen); + for (const glm::vec3& point : drawState->polygon) + { + canvas->drawWorldPoint(painter, point); + } + canvas->drawWorldPoint(painter, drawState->previewPoint); } + break; } } @@ -414,34 +349,6 @@ return this->gridMatrix; } -void Canvas::closeShape() -{ - if (this->drawState.polygon.size() >= 2 and this->drawState.polygon.size() <= 4) - { - std::unique_ptr<ModelEditor> modelEditor = this->document->editModel(); - switch (this->drawState.polygon.size()) - { - case 2: - modelEditor->append<ldraw::Edge>( - vectorToArray<2>(this->drawState.polygon), - ldraw::EDGE_COLOR); - break; - case 3: - modelEditor->append<ldraw::Triangle>( - vectorToArray<3>(this->drawState.polygon), - ldraw::MAIN_COLOR); - break; - case 4: - modelEditor->append<ldraw::Quadrilateral>( - vectorToArray<4>(this->drawState.polygon), - ldraw::MAIN_COLOR); - break; - } - } - this->drawState.polygon.clear(); - updatePreviewPolygon(&this->drawState); -} - /** * @brief Paints a circle at where @c worldPoint is located on the screen. * @param painter Painter to use to render