#include "MV2DElementFloorOutlinePolygon.h" #include "MV2DElement.h" #include "HasMoveableNodes.h" #include "MapViewElementHelper.h" #include MV2DElementFloorOutlinePolygon::MV2DElementFloorOutlinePolygon(Floorplan::FloorOutlinePolygon& fo) : fo(fo) { ; } BBox2 MV2DElementFloorOutlinePolygon::getBoundingBox() const { BBox2 bbox; for (const Point2 p : fo.poly.points) { bbox.add(p); } return bbox; } ClickDist MV2DElementFloorOutlinePolygon::getMinDistanceXY(const Point2 p) const { ClickDist min = ClickDist::max(); for (int i = 0; i < (int)fo.poly.points.size()-1; ++i) { const Point2 p1 = fo.poly.points[i]; const Point2 p2 = fo.poly.points[i+1]; const ClickDist dst = MapElementHelper::getLineDistanceXY(p1, p2, p); if (dst < min) {min = dst;} } return min * 1.1; // penalty.. outlines are everywhere.. reduce priority } void MV2DElementFloorOutlinePolygon::onFocus() { } void MV2DElementFloorOutlinePolygon::onUnfocus() { selectedUserIdx = -1; // clear selection } void MV2DElementFloorOutlinePolygon::paint(Painter& p) { QBrush brush; QPen pen; // fill-style (depends on the mode) switch (fo.method) { case Floorplan::OutlineMethod::ADD: brush.setStyle(Qt::BrushStyle::SolidPattern); brush.setColor( fo.outdoor ? QColor(0,255,0,32) : QColor(0,0,0,24) ); // outdoor = green break; case Floorplan::OutlineMethod::REMOVE: brush.setStyle(Qt::BrushStyle::DiagCrossPattern); brush.setColor(QColor(0,0,0)); break; default: // should not happen brush.setStyle(Qt::BrushStyle::SolidPattern); brush.setColor(QColor(255,0,0)); } if (hasFocus()) { brush.setStyle(Qt::BrushStyle::FDiagPattern); } // outline + filled area pen.setColor(Qt::black); pen.setWidth( hasFocus() ? 2 : 1 ); p.setPenBrush(pen, brush); p.drawPolygon(fo.poly.points); // DEPRECATED // // selected endpoints? // if (hasFocus() && selectedUserIdx != -1) { // p.setPenBrush(Qt::NoPen, CFG::SEL_COLOR); // p.drawCircle(fo.poly.points[selectedUserIdx]); // } // DEPRECATED // // available endpoints // if (hasFocus()) { // p.setPenBrush(Qt::black, Qt::NoBrush); // for (const Point2 pt : fo.poly.points) { // p.drawCircle(pt); // } // } } std::vector MV2DElementFloorOutlinePolygon::getMoveableNodes() const { std::vector nodes; for (int i = 0; i < (int) fo.poly.points.size(); ++i) { nodes.push_back(MoveableNode(i, fo.poly.points[i])); } return nodes; } void MV2DElementFloorOutlinePolygon::onNodeMove(MapView2D* v, const int userIdx, const Point2 newPos) { (void) v; fo.poly.points[userIdx].x = newPos.x; fo.poly.points[userIdx].y = newPos.y; } void MV2DElementFloorOutlinePolygon::onNodeMoved(MapView2D* v, const int userIdx, const Point2 newPos) { (void) userIdx; (void) newPos; emit v->onElementChange(this); } bool MV2DElementFloorOutlinePolygon::keyPressEvent(MapView2D* v, QKeyEvent *e) { (void) v; if (e->key() == Qt::Key_Delete) { // delete the currently selected vertex? if (selectedUserIdx != -1) { fo.poly.points.erase(fo.poly.points.begin() + selectedUserIdx); selectedUserIdx = -1; return true; } } else if (e->key() == Qt::Key_Plus && selectedUserIdx != -1) { int idx1 = selectedUserIdx; int idx2 = (selectedUserIdx + 1) % fo.poly.points.size(); int idxNew = idx2; Point2 pNew = (fo.poly.points[idx1] + fo.poly.points[idx2]) / 2.0f; fo.poly.points.insert(fo.poly.points.begin() + idxNew, pNew); selectedUserIdx = idxNew; return true; } // not consumed return false; }