diff --git a/IndoorMap.pro b/IndoorMap.pro index 8227576..f021e55 100644 --- a/IndoorMap.pro +++ b/IndoorMap.pro @@ -60,7 +60,15 @@ SOURCES += \ mapview/2D/MV2DElementFloorObstacleDoor.cpp \ mapview/2D/MV2DElementFloorObstacleObject.cpp \ mapview/3D/grid/GridRenderer.cpp \ - mapview/3D/navMesh/NavMeshRenderer.cpp + mapview/3D/navMesh/NavMeshRenderer.cpp \ + mapview/2D/MV2DElementFloorObstacleLine.cpp \ + mapview/2D/MapViewElementHelper.cpp \ + mapview/2D/MV2DElementFloorOutlinePolygon.cpp \ + mapview/2D/Painter.cpp \ + mapview/3D/floorplan/FloorplanRenderer.cpp \ + mapview/2D/MV2DElementStair.cpp \ + mapview/2D/MV2DElementElevator.cpp \ + mapview/2D/MV2DElementFloorObstacleCircle.cpp HEADERS += MainWindow.h \ @@ -156,6 +164,7 @@ HEADERS += MainWindow.h \ mapview/model/MMFloorGroundTruthPoint.h \ mapview/2D/MV2DElementGroundTruthPoint.h \ misc/LINTView.h \ + mapview/2D/HasMoveableNodes.h \ mapview/2D/tools/ToolNewElement.h \ mapview/2D/tools/ToolNewDoor.h \ mapview/2D/tools/ToolNewWall.h \ diff --git a/MainController.cpp b/MainController.cpp index 79d6221..4716bfb 100644 --- a/MainController.cpp +++ b/MainController.cpp @@ -126,7 +126,7 @@ MainController::MainController() { //mapModel->load("/apps/paper/diss/data/maps/walkmodel_stairs3.xml"); //mapModel->load("/apps/paper/maps/museum/map43_svg.xml"); - //mapModel->load("/apps/paper/diss/data/maps/SHL41_nm.xml"); + mapModel->load("/apps/paper/maps/shl/SHL45_nm.xml"); //mapModel->load("/mnt/sdcard/SHL41_nm.xml"); diff --git a/mapview/2D/HasMoveableNodes.h b/mapview/2D/HasMoveableNodes.h index 89e55e7..7ed4f6b 100644 --- a/mapview/2D/HasMoveableNodes.h +++ b/mapview/2D/HasMoveableNodes.h @@ -3,6 +3,7 @@ #include #include "../2D/MapView2D.h" +#include /** the selectable/moveable node */ struct MoveableNode { diff --git a/mapview/2D/MV2DElement.h b/mapview/2D/MV2DElement.h index 6785b57..5de4acf 100644 --- a/mapview/2D/MV2DElement.h +++ b/mapview/2D/MV2DElement.h @@ -10,6 +10,7 @@ #include #include "ClickDist.h" +#include "HasMoveableNodes.h" /** * represents one drawable, selectable, editable, ... @@ -36,7 +37,20 @@ public: /** repaint me */ virtual void paint(Painter& p) = 0; + /** repaint me, 2nd layer (e.g. moveable nodes) */ + virtual void paintAfter(Painter& p) { + // HasMoveableNodes? -> paint them here + HasMoveableNodes* e = dynamic_cast(this); + if (e) { + for (const MoveableNode& n : e->getMoveableNodes()) { + const bool sel = e->getSelectedNode() == n.userIdx; // node is selected + const bool foc = hasFocus(); // element (with nodes) currently focused + p.drawNode(n.pos, foc, sel); + } + } + + } /** got focus */ void focus() { diff --git a/mapview/2D/MV2DElementAccessPoint.h b/mapview/2D/MV2DElementAccessPoint.h index e89388a..a8250cf 100644 --- a/mapview/2D/MV2DElementAccessPoint.h +++ b/mapview/2D/MV2DElementAccessPoint.h @@ -47,28 +47,23 @@ public: static const QPixmap& pixmapFocused = UIHelper::getPixmapColored("wifi", CFG::FOCUS_COLOR, 16); static const QPixmap& pixmapSel = UIHelper::getPixmapColored("wifi", CFG::SEL_COLOR, 16); - if (selectedUserIdx == 0) { - //p.setPenBrush(Qt::black, CFG::SEL_COLOR); - //p.drawCircle(ap->pos.xy()); p.drawPixmap(ap->pos.xy(), pixmapSel); } else if (hasFocus()) { - //p.setPenBrush(Qt::black, Qt::NoBrush); - //p.drawCircle(ap->pos.xy()); p.drawPixmap(ap->pos.xy(), pixmapFocused); } else { - //p.setPenBrush(Qt::gray, Qt::NoBrush); - //p.drawCircle(ap->pos.xy()); p.drawPixmap(ap->pos.xy(), pixmapUnfocused); } // label - p.setPenBrush(Qt::black, Qt::NoBrush); - p.drawDot(ap->pos.xy()); + //p.setPenBrush(Qt::black, Qt::NoBrush); + //p.drawDot(ap->pos.xy()); if (p.getScaler().getScale() >= 25) { + p.setPenBrush(Qt::black, Qt::NoBrush); const std::string str = ap->name + " (" + ap->mac + ")"; p.p->drawText(p.getScaler().xms(ap->pos.x) + 10, p.getScaler().yms(ap->pos.y) + 5, str.c_str()); - } else if (p.getScaler().getScale() >= 10) { + } else if (p.getScaler().getScale() >= 12) { + p.setPenBrush(Qt::black, Qt::NoBrush); const std::string str = ap->name; p.p->drawText(p.getScaler().xms(ap->pos.x) + 10, p.getScaler().yms(ap->pos.y) + 5, str.c_str()); } @@ -90,27 +85,6 @@ public: emit v->onElementChange(this); } - virtual void mousePressed(MapView2D* v, const Point2 p) override { - (void) v; - (void) p; - } - - virtual void mouseMove(MapView2D* v, const Point2 p) override { - (void) v; - (void) p; - } - - virtual void mouseReleased(MapView2D* v, const Point2 p) override { - (void) v; - (void) p; - } - - virtual bool keyPressEvent(MapView2D* v, QKeyEvent *e) override { - (void) v; - (void) e; - return false; - } - virtual void onFocus() override { ; } diff --git a/mapview/2D/MV2DElementBeacon.h b/mapview/2D/MV2DElementBeacon.h index ea329eb..96819e1 100644 --- a/mapview/2D/MV2DElementBeacon.h +++ b/mapview/2D/MV2DElementBeacon.h @@ -41,27 +41,22 @@ public: static const QPixmap& pixmapSel = UIHelper::getPixmapColored("beacon", CFG::SEL_COLOR, 16); if (selectedUserIdx == 0) { - //p.setPenBrush(Qt::black, CFG::SEL_COLOR); - //p.drawCircle(b->pos.xy()); p.drawPixmap(b->pos.xy(), pixmapSel); - } else if (hasFocus()) { - //p.setPenBrush(Qt::black, Qt::NoBrush); - //p.drawCircle(b->pos.xy()); p.drawPixmap(b->pos.xy(), pixmapFocused); } else { - //p.setPenBrush(Qt::gray, Qt::NoBrush); - //p.drawCircle(b->pos.xy()); p.drawPixmap(b->pos.xy(), pixmapUnfocused); } // label - p.setPenBrush(Qt::black, Qt::NoBrush); - p.drawDot(b->pos.xy()); + //p.setPenBrush(Qt::black, Qt::NoBrush); + //p.drawDot(b->pos.xy()); if (p.getScaler().getScale() >= 25) { + p.setPenBrush(Qt::black, Qt::NoBrush); const std::string str = b->name + " (" + b->mac + ")"; p.p->drawText(p.getScaler().xms(b->pos.x) + 10, p.getScaler().yms(b->pos.y) + 5, str.c_str()); - } else if (p.getScaler().getScale() >= 10) { + } else if (p.getScaler().getScale() >= 12) { + p.setPenBrush(Qt::black, Qt::NoBrush); const std::string str = b->name; p.p->drawText(p.getScaler().xms(b->pos.x) + 10, p.getScaler().yms(b->pos.y) + 5, str.c_str()); } @@ -91,31 +86,6 @@ public: ; } - /** mouse pressed at the given point */ - virtual void mousePressed(MapView2D* v, const Point2 p) override { - (void) v; - (void) p; - } - - /** mouse moved to the given point */ - virtual void mouseMove(MapView2D* v, const Point2 p) override { - (void) v; - (void) p; - } - - /** mouse released */ - virtual void mouseReleased(MapView2D* v, const Point2 p) override { - (void) v; - (void) p; - } - - virtual bool keyPressEvent(MapView2D* v, QKeyEvent *e) override { - (void) v; - (void) e; - return false; - } - - }; #endif // MV2DELEMENTBEACON_H diff --git a/mapview/2D/MV2DElementElevator.cpp b/mapview/2D/MV2DElementElevator.cpp new file mode 100644 index 0000000..25844eb --- /dev/null +++ b/mapview/2D/MV2DElementElevator.cpp @@ -0,0 +1,90 @@ +#include "MV2DElementElevator.h" + +#include "MV2DElement.h" +#include "HasMoveableNodes.h" + +#include "MapViewElementHelper.h" +#include + +#include "../../UIHelper.h" + + +/** is the given elevator's end connected to ANY of the floorplan's floors? */ +static inline bool elevatorEndConnected(const Floorplan::IndoorMap* map, const Floorplan::Floor* floor, const Floorplan::Elevator* e) { + const int elevatorEnd_cm = std::round( (floor->atHeight + e->height_m) * 100 ); + std::vector floorsAtHeight_cm; + for (const Floorplan::Floor* f : map->floors) { + const int height_cm = std::round(f->atHeight*100); + floorsAtHeight_cm.push_back(height_cm); + } + const bool connected = std::find(floorsAtHeight_cm.begin(), floorsAtHeight_cm.end(), elevatorEnd_cm) != floorsAtHeight_cm.end(); + return connected; +} + + + +MV2DElementElevator::MV2DElementElevator(Floorplan::IndoorMap* map, Floorplan::Floor* floor, Floorplan::Elevator* elevator) : map(map), floor(floor), elevator(elevator) { + ; +} + +BBox2 MV2DElementElevator::getBoundingBox() const { + BBox2 bbox; + const float max = std::max(elevator->width, elevator->depth); + bbox.add(Point2(elevator->center.x, elevator->center.y)); + bbox.grow(Point2(max/2, max/2)); + return bbox; +} + +ClickDist MV2DElementElevator::getMinDistanceXY(const Point2 p) const { +// std::vector points = elevator->getPoints().points; +// points.push_back(elevator->center); +// auto it minEl = std::min_element(points.begin(), points.end(), + return ClickDist(p.getDistance(elevator->center), ClickDistType::DIRECT); +} + +void MV2DElementElevator::paint(Painter& p) { + + // area + const Floorplan::Polygon2 poly = elevator->getPoints(); + p.setPenBrush(Qt::gray, Qt::lightGray); + p.drawPolygon(poly.points); + + // outline + QPen pen; pen.setWidth(2); pen.setColor(QColor(0,0,0)); + + if (!elevatorEndConnected(map, floor, elevator)) {pen.setColor(QColor(255,0,0));} + if (elevator->height_m == 0) {pen.setColor(QColor(255,0,0));} + + p.setPenBrush(pen, Qt::NoBrush); + //p.drawLine(poly.points[0], poly.points[1]); + p.drawLine(poly.points[1], poly.points[2]); + p.drawLine(poly.points[2], poly.points[3]); + p.drawLine(poly.points[3], poly.points[0]); + +} + + + +std::vector MV2DElementElevator::getMoveableNodes() const { + return { MoveableNode(0, elevator->center) }; +} + +void MV2DElementElevator::onNodeMove(MapView2D* v, const int userIdx, const Point2 newPos) { + (void) v; + if (userIdx == 0) {elevator->center.x = newPos.x; elevator->center.y = newPos.y;} +} + +void MV2DElementElevator::onNodeMoved(MapView2D* v, const int userIdx, const Point2 newPos) { + (void) userIdx; + (void) newPos; + emit v->onElementChange(this); +} + +void MV2DElementElevator::onFocus() { + ; +} + +void MV2DElementElevator::onUnfocus() { + ; +} + diff --git a/mapview/2D/MV2DElementElevator.h b/mapview/2D/MV2DElementElevator.h index 3a03257..e55de5a 100644 --- a/mapview/2D/MV2DElementElevator.h +++ b/mapview/2D/MV2DElementElevator.h @@ -4,11 +4,8 @@ #include "MV2DElement.h" #include "HasMoveableNodes.h" -#include "MapViewElementHelper.h" #include -#include "../../UIHelper.h" - class MV2DElementElevator : public MV2DElement, public HasMoveableNodes { private: @@ -20,117 +17,26 @@ private: public: /** ctor with the AP to render/edit */ - MV2DElementElevator(Floorplan::IndoorMap* map, Floorplan::Floor* floor, Floorplan::Elevator* elevator) : map(map), floor(floor), elevator(elevator) {;} + MV2DElementElevator(Floorplan::IndoorMap* map, Floorplan::Floor* floor, Floorplan::Elevator* elevator); - - BBox2 getBoundingBox() const override { - BBox2 bbox; - const float max = std::max(elevator->width, elevator->depth); - bbox.add(Point2(elevator->center.x, elevator->center.y)); - bbox.grow(Point2(max/2, max/2)); - return bbox; - } + BBox2 getBoundingBox() const override; /** get the element's minimal distance (nearest whatsoever) to the given point */ - ClickDist getMinDistanceXY(const Point2 p) const override { -// std::vector points = elevator->getPoints().points; -// points.push_back(elevator->center); -// auto it minEl = std::min_element(points.begin(), points.end(), - return ClickDist(p.getDistance(elevator->center), ClickDistType::DIRECT); - } + ClickDist getMinDistanceXY(const Point2 p) const override; /** repaint me */ - void paint(Painter& p) override { + void paint(Painter& p) override; - // area - const Floorplan::Polygon2 poly = elevator->getPoints(); - p.setPenBrush(Qt::gray, Qt::lightGray); - p.drawPolygon(poly.points); + virtual std::vector getMoveableNodes() const override; - // outline - QPen pen; pen.setWidth(2); pen.setColor(QColor(0,0,0)); + virtual void onNodeMove(MapView2D* v, const int userIdx, const Point2 newPos) override; - if (!elevatorEndConnected(map, floor, elevator)) {pen.setColor(QColor(255,0,0));} - if (elevator->height_m == 0) {pen.setColor(QColor(255,0,0));} + void onNodeMoved(MapView2D* v, const int userIdx, const Point2 newPos) override; - p.setPenBrush(pen, Qt::NoBrush); - //p.drawLine(poly.points[0], poly.points[1]); - p.drawLine(poly.points[1], poly.points[2]); - p.drawLine(poly.points[2], poly.points[3]); - p.drawLine(poly.points[3], poly.points[0]); + virtual void onFocus() override; - if (selectedUserIdx == 0) { - p.setPenBrush(Qt::black, CFG::SEL_COLOR); - p.drawCircle(elevator->center); - } else if (hasFocus()) { - p.setPenBrush(Qt::black, Qt::NoBrush); - p.drawCircle(elevator->center); - } else { - //p.setPenBrush(Qt::gray, Qt::NoBrush); - //p.drawCircle(elevator->center); - p.drawCircle_px(elevator->center, 3); - } - - } - - /** is the given elevator's end connected to ANY of the floorplan's floors? */ - static inline bool elevatorEndConnected(const Floorplan::IndoorMap* map, const Floorplan::Floor* floor, const Floorplan::Elevator* e) { - const int elevatorEnd_cm = std::round( (floor->atHeight + e->height_m) * 100 ); - std::vector floorsAtHeight_cm; - for (const Floorplan::Floor* f : map->floors) { - const int height_cm = std::round(f->atHeight*100); - floorsAtHeight_cm.push_back(height_cm); - } - const bool connected = std::find(floorsAtHeight_cm.begin(), floorsAtHeight_cm.end(), elevatorEnd_cm) != floorsAtHeight_cm.end(); - return connected; - } - - virtual std::vector getMoveableNodes() const override { - return { MoveableNode(0, elevator->center) }; - } - - virtual void onNodeMove(MapView2D* v, const int userIdx, const Point2 newPos) override { - (void) v; - if (userIdx == 0) {elevator->center.x = newPos.x; elevator->center.y = newPos.y;} - } - - void onNodeMoved(MapView2D* v, const int userIdx, const Point2 newPos) override { - (void) userIdx; - (void) newPos; - emit v->onElementChange(this); - } - - - virtual void mousePressed(MapView2D* v, const Point2 p) override { - (void) v; - (void) p; - } - - virtual void mouseMove(MapView2D* v, const Point2 p) override { - (void) v; - (void) p; - } - - virtual void mouseReleased(MapView2D* v, const Point2 p) override { - (void) v; - (void) p; - } - - virtual bool keyPressEvent(MapView2D* v, QKeyEvent *e) override { - (void) v; - (void) e; - return false; - } - - virtual void onFocus() override { - ; - } - - virtual void onUnfocus() override { - ; - } + virtual void onUnfocus() override; }; - #endif // MV2DELEMENTELEVATOR_H diff --git a/mapview/2D/MV2DElementFingerprintLocation.h b/mapview/2D/MV2DElementFingerprintLocation.h index 1f38b03..bf59c3c 100644 --- a/mapview/2D/MV2DElementFingerprintLocation.h +++ b/mapview/2D/MV2DElementFingerprintLocation.h @@ -49,24 +49,18 @@ public: if (selectedUserIdx == 0) { - //p.setPenBrush(Qt::black, CFG::SEL_COLOR); - //p.drawCircle(ap->pos.xy()); p.drawPixmap(fpl->posOnFloor, pixmapSel); } else if (hasFocus()) { - //p.setPenBrush(Qt::black, Qt::NoBrush); - //p.drawCircle(ap->pos.xy()); p.drawPixmap(fpl->posOnFloor, pixmapFocused); } else { - //p.setPenBrush(Qt::gray, Qt::NoBrush); - //p.drawCircle(ap->pos.xy()); p.drawPixmap(fpl->posOnFloor, pixmapUnfocused); } // label - p.setPenBrush(Qt::black, Qt::NoBrush); - p.drawDot(fpl->posOnFloor); - - if (p.getScaler().getScale() >= 10) { + //p.setPenBrush(Qt::black, Qt::NoBrush); + //p.drawDot(fpl->posOnFloor); + if (p.getScaler().getScale() >= 12) { + p.setPenBrush(Qt::black, Qt::NoBrush); const std::string str = fpl->name; p.p->drawText(p.getScaler().xms(fpl->posOnFloor.x) + 10, p.getScaler().yms(fpl->posOnFloor.y) + 5, str.c_str()); } diff --git a/mapview/2D/MV2DElementFloorObstacleCircle.cpp b/mapview/2D/MV2DElementFloorObstacleCircle.cpp new file mode 100644 index 0000000..1603685 --- /dev/null +++ b/mapview/2D/MV2DElementFloorObstacleCircle.cpp @@ -0,0 +1,81 @@ +#include "MV2DElementFloorObstacleCircle.h" + +#include "MV2DElement.h" +#include "MapViewElementHelper.h" +#include + +MV2DElementFloorObstacleCircle::MV2DElementFloorObstacleCircle(Floorplan::FloorObstacleCircle* c) : c(c) { + ; +} + +BBox2 MV2DElementFloorObstacleCircle::getBoundingBox() const { + BBox2 bbox; + bbox.add(c->center); + bbox.grow(Point2(c->radius, c->radius)); + return bbox; +} + +ClickDist MV2DElementFloorObstacleCircle::getMinDistanceXY(const Point2 p) const { + return ClickDist(p.getDistance(c->center), ClickDistType::DIRECT); +} + +void MV2DElementFloorObstacleCircle::paint(Painter& p) { + + QPen pen;// = MapElementHelper::getPen(c->material, c->type, hasFocus()); + + p.setPenBrush(pen, Qt::NoBrush); + p.drawCircle(c->center, c->radius); + + //QBrush brush = MapElementHelper::getBru(c->material, c->type, _focused); + +// // selected endpoints? +// if (hasFocus()) { +// p.setPenBrush(Qt::NoPen, CFG::SEL_COLOR); +// if (selPoint == 0) {p.drawCircle(getSelPoints()[0]);} +// if (selPoint == 1) {p.drawCircle(getSelPoints()[1]);} +// } + +// // available endpoints +// if (hasFocus()) { +// p.setPenBrush(Qt::black, Qt::NoBrush); +// p.drawCircle(getSelPoints()[0]); +// p.drawCircle(getSelPoints()[1]); +// } + +} + +std::vector MV2DElementFloorObstacleCircle::getMoveableNodes() const { + return { + MoveableNode(0, c->center), + MoveableNode(1, c->center+Point2(c->radius,0)) + }; +} + +void MV2DElementFloorObstacleCircle::onNodeMove(MapView2D* v, const int userIdx, const Point2 newPos) { + (void) v; + switch(userIdx) { + case 0: c->center.x = newPos.x; c->center.y = newPos.y; break; + case 1: c->radius = newPos.getDistance(c->center); break; + } +} + +void MV2DElementFloorObstacleCircle::onNodeMoved(MapView2D* v, const int userIdx, const Point2 newPos) { + (void) userIdx; + (void) newPos; + emit v->onElementChange(this); +} + +//std::vector MV2DElementFloorObstacleCircle::getSelPoints() const { +// return {c->center, (c->center + Point2(c->radius,0))}; +//} + +void MV2DElementFloorObstacleCircle::onFocus() { + ; +} + +void MV2DElementFloorObstacleCircle::onUnfocus() { + selPoint = -1; +} + + + diff --git a/mapview/2D/MV2DElementFloorObstacleCircle.h b/mapview/2D/MV2DElementFloorObstacleCircle.h index cb33604..cf9341b 100644 --- a/mapview/2D/MV2DElementFloorObstacleCircle.h +++ b/mapview/2D/MV2DElementFloorObstacleCircle.h @@ -1,12 +1,12 @@ #ifndef MV2DELEMENTFLOOROBSTACLECIRCLE_H #define MV2DELEMENTFLOOROBSTACLECIRCLE_H - #include "MV2DElement.h" #include "MapViewElementHelper.h" + #include -class MV2DElementFloorObstacleCircle : public MV2DElement { +class MV2DElementFloorObstacleCircle : public MV2DElement, public HasMoveableNodes { private: @@ -16,95 +16,28 @@ private: public: /** ctor */ - MV2DElementFloorObstacleCircle(Floorplan::FloorObstacleCircle* c) : c(c) {;} + MV2DElementFloorObstacleCircle(Floorplan::FloorObstacleCircle* c); /** get the element's 3D bounding box */ - BBox2 getBoundingBox() const override { - BBox2 bbox; - bbox.add(c->center); - bbox.grow(Point2(c->radius, c->radius)); - return bbox; - } + BBox2 getBoundingBox() const override; /** get the element's minimal distance (nearest whatsoever) to the given point */ - ClickDist getMinDistanceXY(const Point2 p) const override { - const ClickDist d1(p.getDistance(getSelPoints()[0]), ClickDistType::DIRECT); - const ClickDist d2(p.getDistance(getSelPoints()[1]), ClickDistType::DIRECT); - return std::min(d1, d2); - //return std::min(p.getDistance(getSelPoints()[0]), p.getDistance(getSelPoints()[1])); - } - + ClickDist getMinDistanceXY(const Point2 p) const override; /** repaint me */ - void paint(Painter& p) override { + void paint(Painter& p) override; - QPen pen;// = MapElementHelper::getPen(c->material, c->type, hasFocus()); + //std::vector getSelPoints() const; - p.setPenBrush(pen, Qt::NoBrush); - p.drawCircle(c->center, c->radius); + virtual std::vector getMoveableNodes() const override; - //QBrush brush = MapElementHelper::getBru(c->material, c->type, _focused); + virtual void onNodeMove(MapView2D* v, const int userIdx, const Point2 newPos) override; - // selected endpoints? - if (hasFocus()) { - p.setPenBrush(Qt::NoPen, CFG::SEL_COLOR); - if (selPoint == 0) {p.drawCircle(getSelPoints()[0]);} - if (selPoint == 1) {p.drawCircle(getSelPoints()[1]);} - } + void onNodeMoved(MapView2D* v, const int userIdx, const Point2 newPos) override; - // available endpoints - if (hasFocus()) { - p.setPenBrush(Qt::black, Qt::NoBrush); - p.drawCircle(getSelPoints()[0]); - p.drawCircle(getSelPoints()[1]); - } + virtual void onFocus() override; - } - - std::vector getSelPoints() const { - return {c->center, (c->center + Point2(c->radius,0))}; - } - - virtual void onFocus() override { - ; - } - - virtual void onUnfocus() override { - selPoint = -1; - } - - /** mouse pressed at the given point */ - virtual void mousePressed(MapView2D* v, const Point2 p) override { - (void) v; - (void) p; - - } - - /** mouse moved to the given point */ - virtual void mouseMove(MapView2D* v, const Point2 _p) override { - (void) v; - if (selPoint == -1) {return;} - const Point2 p = v->getScaler().snap(_p); - if (selPoint == 0) {c->center = p;} - if (selPoint == 1) {c->radius = p.getDistance(c->center);} - } - - /** mouse released */ - virtual void mouseReleased(MapView2D* v, const Point2 _p) override { - const float t = v->getScaler().sm(CFG::SEL_THRESHOLD_SIZE_PX); - const float l1 = _p.getDistance(getSelPoints()[0]); - const float l2 = _p.getDistance(getSelPoints()[1]); - if (l1 < l2 && l1 <= t) {selPoint = 0;} - else if (l2 < l1 && l2 <= t) {selPoint = 1;} - else {selPoint = -1;} - } - - virtual bool keyPressEvent(MapView2D* v, QKeyEvent *e) override { - (void) v; - (void) e; - - return false; - } + virtual void onUnfocus() override; }; diff --git a/mapview/2D/MV2DElementFloorObstacleDoor.cpp b/mapview/2D/MV2DElementFloorObstacleDoor.cpp index fd22f99..782ffd6 100644 --- a/mapview/2D/MV2DElementFloorObstacleDoor.cpp +++ b/mapview/2D/MV2DElementFloorObstacleDoor.cpp @@ -28,12 +28,13 @@ void MV2DElementFloorObstacleDoor::paint(Painter& p) { return; } - // selected endpoints? - if (hasFocus()) { - p.setPenBrush(Qt::NoPen, CFG::SEL_COLOR); - if (selectedUserIdx == 0) {p.drawCircle(fo->from);} - if (selectedUserIdx == 1) {p.drawCircle(fo->to);} - } + // DEPRECATED +// // selected endpoints? +// if (hasFocus()) { +// p.setPenBrush(Qt::NoPen, CFG::SEL_COLOR); +// if (selectedUserIdx == 0) {p.drawCircle(fo->from);} +// if (selectedUserIdx == 1) {p.drawCircle(fo->to);} +// } QPen pen; pen.setColor(QColor(0.5,0.5,0.5)); @@ -80,13 +81,13 @@ void MV2DElementFloorObstacleDoor::paint(Painter& p) { } - - // available endpoints - if (hasFocus()) { - p.setPenBrush(Qt::black, Qt::NoBrush); - p.drawCircle(fo->from); - p.drawCircle(fo->to); - } + // DEPRECATED +// // available endpoints +// if (hasFocus()) { +// p.setPenBrush(Qt::black, Qt::NoBrush); +// p.drawCircle(fo->from); +// p.drawCircle(fo->to); +// } // obstacle length if (hasFocus()) { @@ -129,10 +130,13 @@ std::vector MV2DElementFloorObstacleDoor::getMoveableNodes() const } void MV2DElementFloorObstacleDoor::onNodeMoved(MapView2D* v, const int userIdx, const Point2 newPos) { + (void) userIdx; + (void) newPos; emit v->onElementChange(this); } void MV2DElementFloorObstacleDoor::onNodeMove(MapView2D* v, const int userIdx, const Point2 newPos) { + (void) v; switch (userIdx) { case 0: fo->from = newPos; break; case 1: fo->to = newPos; break; diff --git a/mapview/2D/MV2DElementFloorObstacleLine.cpp b/mapview/2D/MV2DElementFloorObstacleLine.cpp new file mode 100644 index 0000000..1f5f5ce --- /dev/null +++ b/mapview/2D/MV2DElementFloorObstacleLine.cpp @@ -0,0 +1,92 @@ +#include "MV2DElementFloorObstacleLine.h" + +#include "MV2DElement.h" +#include "HasMoveableNodes.h" + +#include "MapViewElementHelper.h" +#include +#include + +MV2DElementFloorObstacleLine::MV2DElementFloorObstacleLine(Floorplan::FloorObstacleLine* fo) : fo(fo) { + ; +} + +BBox2 MV2DElementFloorObstacleLine::getBoundingBox() const { + BBox2 bbox; + bbox.add(fo->from); + bbox.add(fo->to); + return bbox; +} + +ClickDist MV2DElementFloorObstacleLine::getMinDistanceXY(const Point2 p) const { + return MapElementHelper::getLineDistanceXY(fo->from, fo->to, p); +} + +void MV2DElementFloorObstacleLine::paint(Painter& p) { + + // DEPRECATED +// // selected endpoints? +// if (hasFocus()) { +// p.setPenBrush(Qt::NoPen, CFG::SEL_COLOR); +// if (selectedUserIdx == 0) {p.drawCircle(fo->from);} +// if (selectedUserIdx == 1) {p.drawCircle(fo->to);} +// } + + // convert wall's thickness from meter to pixels + const float thickness_px = p.s.ms(fo->thickness_m); + + // remember the old pen + //QPen pen = p.getPen(); + + // see notes within MapElementHelper! + // lines only get thicker, but not longer! + p.setPenBrush(MapElementHelper::getPen(fo->material, fo->type, hasFocus(), thickness_px), Qt::NoBrush); + p.drawLine(fo->from, fo->to); + + // reset the old pen3 + //p.setPen(pen); + + // length info + if (hasFocus()) { + + // obstacle length + p.setPenBrush(Qt::black, Qt::NoBrush); + p.drawLength(fo->from, fo->to, fo->from.getDistance(fo->to), thickness_px/2); + + } + + // DEPRECATED +// // available endpoints +// p.drawNode(fo->from, hasFocus(), hasFocus() && selectedUserIdx == 0); +// p.drawNode(fo->to, hasFocus(), hasFocus() && selectedUserIdx == 1); + +} + +void MV2DElementFloorObstacleLine::onFocus() { + ; +} + +void MV2DElementFloorObstacleLine::onUnfocus() { + selectedUserIdx = -1; // clear selection +} + +std::vector MV2DElementFloorObstacleLine::getMoveableNodes() const { + return { + MoveableNode(0, fo->from), + MoveableNode(1, fo->to) + }; +} + +void MV2DElementFloorObstacleLine::onNodeMove(MapView2D* v, const int userIdx, const Point2 newPos) { + (void) v; + if (userIdx == 0) {fo->from.x = newPos.x; fo->from.y = newPos.y;} + if (userIdx == 1) {fo->to.x = newPos.x; fo->to.y = newPos.y;} +} + +void MV2DElementFloorObstacleLine::onNodeMoved(MapView2D* v, const int userIdx, const Point2 newPos) { + (void) userIdx; + (void) newPos; + emit v->onElementChange(this); +} + + diff --git a/mapview/2D/MV2DElementFloorObstacleLine.h b/mapview/2D/MV2DElementFloorObstacleLine.h index 4f596d3..1b9c74a 100644 --- a/mapview/2D/MV2DElementFloorObstacleLine.h +++ b/mapview/2D/MV2DElementFloorObstacleLine.h @@ -4,9 +4,7 @@ #include "MV2DElement.h" #include "HasMoveableNodes.h" -#include "MapViewElementHelper.h" #include -#include class MV2DElementFloorObstacleLine : public MV2DElement, public HasMoveableNodes { @@ -17,90 +15,26 @@ private: public: /** ctor */ - MV2DElementFloorObstacleLine(Floorplan::FloorObstacleLine* fo) : fo(fo) {;} + MV2DElementFloorObstacleLine(Floorplan::FloorObstacleLine* fo); /** get the element's 3D bounding box */ - BBox2 getBoundingBox() const override { - BBox2 bbox; - bbox.add(fo->from); - bbox.add(fo->to); - return bbox; - } + BBox2 getBoundingBox() const override; /** get the element's minimal distance (nearest whatsoever) to the given point */ - ClickDist getMinDistanceXY(const Point2 p) const override { - return MapElementHelper::getLineDistanceXY(fo->from, fo->to, p); - } + ClickDist getMinDistanceXY(const Point2 p) const override; /** repaint me */ - void paint(Painter& p) override { + void paint(Painter& p) override; - // selected endpoints? - if (hasFocus()) { - p.setPenBrush(Qt::NoPen, CFG::SEL_COLOR); - if (selectedUserIdx == 0) {p.drawCircle(fo->from);} - if (selectedUserIdx == 1) {p.drawCircle(fo->to);} - } + void onFocus() override; - // convert wall's thickness from meter to pixels - const float thickness_px = p.s.ms(fo->thickness_m); + void onUnfocus() override; - // remember the old pen - QPen pen = p.getPen(); + virtual std::vector getMoveableNodes() const override; - // see notes within MapElementHelper! - // lines only get thicker, but not longer! - p.setPenBrush(MapElementHelper::getPen(fo->material, fo->type, hasFocus(), thickness_px), Qt::NoBrush); - p.drawLine(fo->from, fo->to); + void onNodeMove(MapView2D* v, const int userIdx, const Point2 newPos) override; - // reset the old pen - p.setPen(pen); - - // available endpoints - if (hasFocus()) { - - p.setPenBrush(Qt::black, Qt::NoBrush); - p.drawCircle(fo->from); - p.drawCircle(fo->to); - - // obstacle length - p.setPenBrush(Qt::black, Qt::NoBrush); - p.drawLength(fo->from, fo->to, fo->from.getDistance(fo->to), thickness_px/2); - - } else { - //p.setPenBrush(Qt::NoPen, Qt::black); - p.drawCircle_px(fo->from, 3); - p.drawCircle_px(fo->to, 3); - } - - } - - void onFocus() override { - ; - } - - void onUnfocus() override { - selectedUserIdx = -1; // clear selection - } - - virtual std::vector getMoveableNodes() const override { - return { - MoveableNode(0, fo->from), - MoveableNode(1, fo->to) - }; - } - - void onNodeMove(MapView2D* v, const int userIdx, const Point2 newPos) override { - (void) v; - if (userIdx == 0) {fo->from.x = newPos.x; fo->from.y = newPos.y;} - if (userIdx == 1) {fo->to.x = newPos.x; fo->to.y = newPos.y;} - } - - void onNodeMoved(MapView2D* v, const int userIdx, const Point2 newPos) { - (void) userIdx; - (void) newPos; - emit v->onElementChange(this); - } + void onNodeMoved(MapView2D* v, const int userIdx, const Point2 newPos); }; diff --git a/mapview/2D/MV2DElementFloorOutlinePolygon.cpp b/mapview/2D/MV2DElementFloorOutlinePolygon.cpp new file mode 100644 index 0000000..bc06ede --- /dev/null +++ b/mapview/2D/MV2DElementFloorOutlinePolygon.cpp @@ -0,0 +1,134 @@ +#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; + +} diff --git a/mapview/2D/MV2DElementFloorOutlinePolygon.h b/mapview/2D/MV2DElementFloorOutlinePolygon.h index 80998db..3bab9f9 100644 --- a/mapview/2D/MV2DElementFloorOutlinePolygon.h +++ b/mapview/2D/MV2DElementFloorOutlinePolygon.h @@ -3,7 +3,6 @@ #include "MV2DElement.h" #include "HasMoveableNodes.h" -#include "MapViewElementHelper.h" #include @@ -16,167 +15,29 @@ private: public: /** ctor */ - MV2DElementFloorOutlinePolygon(Floorplan::FloorOutlinePolygon& fo) : fo(fo) {;} + MV2DElementFloorOutlinePolygon(Floorplan::FloorOutlinePolygon& fo); /** get the element's 3D bounding box */ - BBox2 getBoundingBox() const override { - BBox2 bbox; - for (const Point2 p : fo.poly.points) { bbox.add(p); } - return bbox; - } + BBox2 getBoundingBox() const override; /** get the element's minimal distance (nearest whatsoever) to the given point */ - ClickDist getMinDistanceXY(const Point2 p) const override { - 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 - } + ClickDist getMinDistanceXY(const Point2 p) const override; - virtual void onFocus() override { + virtual void onFocus() override; - } + virtual void onUnfocus() override; - virtual void onUnfocus() override { - selectedUserIdx = -1; // clear selection - } - - void paint(Painter& p) override { - - 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); - - // selected endpoints? - if (hasFocus() && selectedUserIdx != -1) { - p.setPenBrush(Qt::NoPen, CFG::SEL_COLOR); - p.drawCircle(fo.poly.points[selectedUserIdx]); - } - - // available endpoints - if (hasFocus()) { - p.setPenBrush(Qt::black, Qt::NoBrush); - for (const Point2 pt : fo.poly.points) { - p.drawCircle(pt); - } - } - - - } + void paint(Painter& p) override; /** get a list of all nodes that are selectable / moveable */ - virtual std::vector getMoveableNodes() const override { - 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; - } + virtual std::vector getMoveableNodes() const override; /** the given node was moved */ - void onNodeMove(MapView2D* v, const int userIdx, const Point2 newPos) override { - (void) v; - fo.poly.points[userIdx].x = newPos.x; - fo.poly.points[userIdx].y = newPos.y; - } + void onNodeMove(MapView2D* v, const int userIdx, const Point2 newPos) override; - void onNodeMoved(MapView2D* v, const int userIdx, const Point2 newPos) override { - (void) userIdx; - (void) newPos; - emit v->onElementChange(this); - } - - -// virtual void mousePressed(MapView2D* v, const Point2 p) override { -// (void) v; -// (void) p; -// } - -// virtual void mouseMove(MapView2D* v, const Point2 _p) override { -// (void) v; -// if (selPoint == -1) {return;} -// const Point2 p = v->getScaler().snap(_p); -// fo.poly.points[selPoint].x = p.x; -// fo.poly.points[selPoint].y = p.y; -// } - -// virtual void mouseReleased(MapView2D* v, const Point2 _p) override { - -// (void) v; - -// // if (selPoint != -1) { -// // const Point3 p = Scaler::snap(_p, CFG::MOVE_SNAP_SIZE_M); -// // fo.poly.points[selPoint].x = p.x; -// // fo.poly.points[selPoint].y = p.y; -// // } - -// // select a new point on mouse-release (more robust than on mouse-press) -// const float t = v->getScaler().sm(CFG::SEL_THRESHOLD_SIZE_PX); -// auto comp = [&] (const Point2 a, const Point2 b) {return a.getDistance(_p) < b.getDistance(_p);}; -// auto it = std::min_element(fo.poly.points.begin(), fo.poly.points.end(), comp); -// if (it == fo.poly.points.end()) {selPoint = -1;} // none found -> skip -// else if ((*it).getDistance(_p) > t) {selPoint = -1;} // nearest distance is above threshold -> skip -// else {selPoint = it - fo.poly.points.begin();} - -// } - - virtual bool keyPressEvent(MapView2D* v, QKeyEvent *e) override { - (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; - - } + void onNodeMoved(MapView2D* v, const int userIdx, const Point2 newPos) override; + virtual bool keyPressEvent(MapView2D* v, QKeyEvent *e) override; }; diff --git a/mapview/2D/MV2DElementGroundTruthPoint.h b/mapview/2D/MV2DElementGroundTruthPoint.h index 036a357..d8fde48 100644 --- a/mapview/2D/MV2DElementGroundTruthPoint.h +++ b/mapview/2D/MV2DElementGroundTruthPoint.h @@ -42,36 +42,29 @@ public: return; } - static const QPixmap& pixmapUnfocused = UIHelper::getPixmapColored("gtp", CFG::UNFOCUS_COLOR, 16); - static const QPixmap& pixmapFocused = UIHelper::getPixmapColored("gtp", CFG::FOCUS_COLOR, 16); - static const QPixmap& pixmapSel = UIHelper::getPixmapColored("gtp", CFG::SEL_COLOR, 16); + static const QPixmap& pixmapUnfocused = UIHelper::getPixmapColored("gtp", CFG::UNFOCUS_COLOR, 16); + static const QPixmap& pixmapFocused = UIHelper::getPixmapColored("gtp", CFG::FOCUS_COLOR, 16); + static const QPixmap& pixmapSel = UIHelper::getPixmapColored("gtp", CFG::SEL_COLOR, 16); + if (selectedUserIdx == 0) { + p.drawPixmap(gtp->pos.xy(), pixmapSel); + } else if (hasFocus()) { + p.drawPixmap(gtp->pos.xy(), pixmapFocused); + } else { + p.drawPixmap(gtp->pos.xy(), pixmapUnfocused); + } - if (selectedUserIdx == 0) { -// p.setPenBrush(Qt::black, CFG::SEL_COLOR); -// p.drawCircle(gtp->pos); - p.drawPixmap(gtp->pos.xy(), pixmapSel); - } else if (hasFocus()) { -// p.setPenBrush(Qt::black, Qt::NoBrush); -// p.drawCircle(gtp->pos); - p.drawPixmap(gtp->pos.xy(), pixmapFocused); - } else { -// p.setPenBrush(Qt::gray, Qt::NoBrush); -// p.drawCircle(gtp->pos); - p.drawPixmap(gtp->pos.xy(), pixmapUnfocused); - } - - // label - p.setPenBrush(Qt::black, Qt::NoBrush); - p.drawDot(gtp->pos.xy()); - if (p.getScaler().getScale() >= 10) { - const std::string str = std::to_string(gtp->id); - p.p->drawText(p.getScaler().xms(gtp->pos.x) + 10, p.getScaler().yms(gtp->pos.y) + 5, str.c_str()); - } + // label + //p.setPenBrush(Qt::black, Qt::NoBrush); + //p.drawDot(gtp->pos.xy()); + if (p.getScaler().getScale() >= 12) { + p.setPenBrush(Qt::black, Qt::NoBrush); + const std::string str = std::to_string(gtp->id); + p.p->drawText(p.getScaler().xms(gtp->pos.x) + 10, p.getScaler().yms(gtp->pos.y) + 5, str.c_str()); + } } - virtual std::vector getMoveableNodes() const override { return { MoveableNode(0, gtp->pos.xy()) }; } @@ -87,30 +80,6 @@ public: emit v->onElementChange(this); } - /** mouse pressed at the given point */ - virtual void mousePressed(MapView2D* v, const Point2 p) override { - (void) v; - (void) p; - } - - /** mouse moved to the given point */ - virtual void mouseMove(MapView2D* v, const Point2 p) override { - (void) v; - (void) p; - } - - /** mouse released */ - virtual void mouseReleased(MapView2D* v, const Point2 p) override { - (void) v; - (void) p; - } - - virtual bool keyPressEvent(MapView2D* v, QKeyEvent *e) override { - (void) v; - (void) e; - return false; - } - virtual void onFocus() override { ; } diff --git a/mapview/2D/MV2DElementPOI.h b/mapview/2D/MV2DElementPOI.h index b79f885..a256900 100644 --- a/mapview/2D/MV2DElementPOI.h +++ b/mapview/2D/MV2DElementPOI.h @@ -62,9 +62,10 @@ public: } // label - p.setPenBrush(Qt::black, Qt::NoBrush); - p.drawDot(poi->pos); - if (p.getScaler().getScale() >= 10) { + //p.setPenBrush(Qt::black, Qt::NoBrush); + //p.drawDot(poi->pos); + if (p.getScaler().getScale() >= 12) { + p.setPenBrush(Qt::black, Qt::NoBrush); const std::string str = poi->name; p.p->drawText(p.getScaler().xms(poi->pos.x) + 10, p.getScaler().yms(poi->pos.y) + 5, str.c_str()); } @@ -87,35 +88,6 @@ public: emit v->onElementChange(this); } - /** mouse pressed at the given point */ - virtual void mousePressed(MapView2D* v, const Point2 p) override { - (void) v; - (void) p; - } - - /** mouse moved to the given point */ - virtual void mouseMove(MapView2D* v, const Point2 p) override { - (void) v; - (void) p; -// if (sel) { -// const Point2 p = v->getScaler().snap(_p); -// poi->pos.x = p.x; -// poi->pos.y = p.y; -// } - } - - /** mouse released */ - virtual void mouseReleased(MapView2D* v, const Point2 p) override { - (void) v; - (void) p; - } - - virtual bool keyPressEvent(MapView2D* v, QKeyEvent *e) override { - (void) v; - (void) e; - return false; - } - virtual void onFocus() override { ; } diff --git a/mapview/2D/MV2DElementRegistrationPoint.h b/mapview/2D/MV2DElementRegistrationPoint.h index 7b21b79..d1e263f 100644 --- a/mapview/2D/MV2DElementRegistrationPoint.h +++ b/mapview/2D/MV2DElementRegistrationPoint.h @@ -59,9 +59,10 @@ public: } // label - p.setPenBrush(Qt::black, Qt::NoBrush); + //p.setPenBrush(Qt::black, Qt::NoBrush); //p.drawDot(ap->pos.xy()); - if (p.getScaler().getScale() >= 10) { + if (p.getScaler().getScale() >= 12) { + p.setPenBrush(Qt::black, Qt::NoBrush); const std::string str = std::to_string(reg->posOnEarth.lat) + " " + std::to_string(reg->posOnEarth.lon); p.p->drawText(p.getScaler().xms(reg->posOnMap_m.x) + 10, p.getScaler().yms(reg->posOnMap_m.y) + 5, str.c_str()); } @@ -83,27 +84,6 @@ public: emit v->onElementChange(this); } - virtual void mousePressed(MapView2D* v, const Point2 p) override { - (void) v; - (void) p; - } - - virtual void mouseMove(MapView2D* v, const Point2 p) override { - (void) v; - (void) p; - } - - virtual void mouseReleased(MapView2D* v, const Point2 p) override { - (void) v; - (void) p; - } - - virtual bool keyPressEvent(MapView2D* v, QKeyEvent *e) override { - (void) v; - (void) e; - return false; - } - virtual void onFocus() override { ; } diff --git a/mapview/2D/MV2DElementStair.cpp b/mapview/2D/MV2DElementStair.cpp new file mode 100644 index 0000000..f4bbf16 --- /dev/null +++ b/mapview/2D/MV2DElementStair.cpp @@ -0,0 +1,251 @@ +#include "MV2DElementStair.h" + +#include "MV2DElement.h" +#include "HasMoveableNodes.h" + +#include "MapViewElementHelper.h" +#include + +/** is the given stair's end connected to ANY of the floorplan's floors? */ +static inline bool stairEndConnected(const Floorplan::IndoorMap* map, const Floorplan::Floor* floor, const Floorplan::Stair* stair) { + const int stairEnd_cm = std::round( (floor->atHeight + stair->getParts().back().end.z) * 100 ); + std::vector floorsAtHeight_cm; + for (const Floorplan::Floor* f : map->floors) { + const int height_cm = std::round(f->atHeight*100); + floorsAtHeight_cm.push_back(height_cm); + } + const bool connected = std::find(floorsAtHeight_cm.begin(), floorsAtHeight_cm.end(), stairEnd_cm) != floorsAtHeight_cm.end(); + return connected; +} + +static inline float clamp01(const float val) { + if (val < 0) {return 0;} + if (val > 1) {return 1;} + return val; +} + + + + +MV2DElementStair::MV2DElementStair(Floorplan::IndoorMap* map, Floorplan::Floor* floor, Floorplan::Stair* stair) + : map(map), floor(floor), stair(stair) { + ; +} + + +BBox2 MV2DElementStair::getBoundingBox() const { + BBox2 bbox; + if (dynamic_cast(stair)) { + Floorplan::StairFreeform* stair = dynamic_cast(this->stair); + for (const Floorplan::StairPart p : stair->parts) { + bbox.add(p.start.xy()); + bbox.add(p.end.xy()); + } + } + return bbox; +} + +/** get the element's minimal distance (nearest whatsoever) to the given point */ +ClickDist MV2DElementStair::getMinDistanceXY(const Point2 p) const { + + auto comp = [p] (const Floorplan::StairPart& p1, const Floorplan::StairPart& p2) { + const ClickDist d1 = MapElementHelper::getLineDistanceXY(p1.start.xy(), p1.end.xy(), p); + const ClickDist d2 = MapElementHelper::getLineDistanceXY(p2.start.xy(), p2.end.xy(), p); + return d1 < d2; + }; + + auto parts = stair->getParts(); + auto min = std::min_element(parts.begin(), parts.end(), comp); + return MapElementHelper::getLineDistanceXY(min->start.xy(), min->end.xy(), p); + +} + +int MV2DElementStair::getSelPart() const {return getSelectedNode() < 0 ? getSelectedNode() : getSelectedNode() / 2;} +int MV2DElementStair::getSelNode() const {return getSelectedNode() < 0 ? getSelectedNode() : getSelectedNode() % 2;} + +void MV2DElementStair::paint(Painter& p) { + + Floorplan::StairFreeform* stair = dynamic_cast(this->stair); + + // draw all parts of the stair (all polygons) + p.setPenBrush(Qt::black, Qt::NoBrush); + + std::vector parts = stair->getParts(); + std::vector quads = Floorplan::getQuads(parts, floor); + + // skip drawing? + BBox2 bbox; + for (const Floorplan::Quad3& q : quads) { + bbox.add(q.p1.xy()); + bbox.add(q.p2.xy()); + bbox.add(q.p3.xy()); + bbox.add(q.p4.xy()); + } + if (!p.isVisible(bbox)) { + return; + } + + for (int i = 0; i < (int) parts.size(); ++i) { + + const Floorplan::StairPart& part = parts[i]; + const Floorplan::Quad3& quad = quads[i]; + + // fill the polygon with a gradient corresponding with the stair's height relative to the floor's height + QLinearGradient gradient(p.s.xms(part.start.x), p.s.yms(part.start.y), p.s.xms(part.end.x), p.s.yms(part.end.y)); + const float p1 = 0.1 + clamp01( part.start.z / floor->height) * 0.8; + const float p2 = 0.1 + clamp01( part.end.z / floor->height) * 0.8; + gradient.setColorAt(0, QColor(p1*128, p1*128, p1*255, 128)); + gradient.setColorAt(1, QColor(p2*128, p2*128, p2*255, 128)); + p.setBrush(gradient); + p.setPen(QColor(0,0,0,128)); + + // polygon-construction + //const Floorplan::Quad3 quad = part.getQuad(floor); + const std::vector points = {quad.p1, quad.p2, quad.p3, quad.p4}; + p.drawPolygon(points); + + + QPen pen; + pen.setWidth(5); + pen.setColor(QColor(255,0,0)); + p.setPen(pen); + + // LINT disconnected start + if (i == 0) { + if (quad.p1.z != floor->getStartingZ()) { + p.drawLine(quad.p1, quad.p2); + } + } + + // LINT disconnected end + if (i == (int) parts.size() - 1) { + //if (quad.p3.z != floor->getEndingZ()) { + if (!stairEndConnected(map, floor, stair)) { + p.drawLine(quad.p3, quad.p4); + } + } + + // LINT disconnected within + if (i > 0) { + if (quads[i-1].p4.z != quads[i-0].p1.z) { + p.drawLine(quad.p1, quad.p2); + } + } + + } + + if (hasFocus()) { + int cnt = 0; + std::vector parts = stair->getParts(); + for (const Floorplan::StairPart& part : parts) { + + //p.setPenBrush(Qt::black, (cnt == getSelPart() && getSelNode() == 0) ? CFG::SEL_COLOR : Qt::NoBrush); // part start + //p.drawCircle(part.start.xy()); // DEPRECATED + + //p.setPenBrush(Qt::black, (cnt == getSelPart() && getSelNode() == 1) ? CFG::SEL_COLOR : Qt::NoBrush); // part end + //p.drawRect(part.end.xy()); // DEPRECATED + + p.setPenBrush(Qt::blue, Qt::NoBrush); + Point2 ctr = (part.start+part.end).xy() / 2; + p.drawText(ctr, "p" + std::to_string(cnt+1)); // part name + ++cnt; + + } + for (int i = 0; i < (int)parts.size() - 1; ++i) { + const Point3 p1 = parts[i+0][1]; + const Point3 p2 = parts[i+1][0]; + p.drawLine(p1.xy(), p2.xy()); + } + } + +} + +bool MV2DElementStair::keyPressEvent(MapView2D* v, QKeyEvent *e) { + (void) v; + (void) e; + + Floorplan::StairFreeform* stair = dynamic_cast(this->stair); + + if (e->key() == Qt::Key_Delete) { + + // delete the currently selected vertex? + if (getSelPart() != -1) { +// stair->nodes.erase(stair->nodes.begin() + selIdx); +// selIdx = -1; +// return true; + } + + } else if (e->key() == Qt::Key_Plus && getSelPart() != -1) { +// int idx1 = selIdx; +// int idx2 = (selIdx + 1) % stair->nodes.size(); +// int idxNew = idx2; +// Point3 pNew = (stair->nodes[idx1] + stair->nodes[idx2]) / 2.0f; +// stair->nodes.insert(stair->nodes.begin() + idxNew, pNew); +// selIdx = idxNew; +// return true; + const int idxNew = getSelPart() + 1; + const Point3 p0 = stair->parts[getSelPart()][1]; + const Point3 p1 = p0 + Point3(1,1,0); + const Point3 p2 = p1 + Point3(2,2,0); + const float w = stair->parts[getSelPart()].width; + stair->parts.insert(stair->parts.begin() + idxNew, Floorplan::StairPart(p1, p2, w)); + return true; + } + + // not consumed + return false; + +} + +void MV2DElementStair::onFocus() { + // TODO? +} + +void MV2DElementStair::onUnfocus() { + sel = false; +} + +std::vector MV2DElementStair::getMoveableNodes() const { + + std::vector nodes; + Floorplan::StairFreeform* stair = dynamic_cast(this->stair); + + // get a list of all moveable nodes (2 per stair-part) + int idx = 0; + for (size_t part = 0; part < stair->parts.size(); ++part) { + for (int node = 0; node < 2; ++node) { + MoveableNode mn(idx++, stair->parts[part][node].xy()); + nodes.push_back(mn); + } + } + + return nodes; + +} + +void MV2DElementStair::onNodeMove(MapView2D* v, const int userIdx, const Point2 newPos) { + + (void) v; + + // convert node-index back to stair-part and node-nr within stair-part + const int selPart = userIdx / 2; + const int selNode = userIdx % 2; + + // move the node + Floorplan::StairFreeform* stair = dynamic_cast(this->stair); + stair->parts[selPart][selNode].x = newPos.x; + stair->parts[selPart][selNode].y = newPos.y; + +} + +void MV2DElementStair::onNodeMoved(MapView2D* v, const int userIdx, const Point2 newPos) { + (void) userIdx; + (void) newPos; + emit v->onElementChange(this); +} + +void MV2DElementStair::onNodeSelect(MapView2D* v, const int userIdx) { + HasMoveableNodes::onNodeSelect(v, userIdx); + emit v->onElementChange(this); +} + diff --git a/mapview/2D/MV2DElementStair.h b/mapview/2D/MV2DElementStair.h index a5b0f5e..8e941d3 100644 --- a/mapview/2D/MV2DElementStair.h +++ b/mapview/2D/MV2DElementStair.h @@ -4,21 +4,8 @@ #include "MV2DElement.h" #include "HasMoveableNodes.h" -#include "MapViewElementHelper.h" #include -/** is the given stair's end connected to ANY of the floorplan's floors? */ -static inline bool stairEndConnected(const Floorplan::IndoorMap* map, const Floorplan::Floor* floor, const Floorplan::Stair* stair) { - const int stairEnd_cm = std::round( (floor->atHeight + stair->getParts().back().end.z) * 100 ); - std::vector floorsAtHeight_cm; - for (const Floorplan::Floor* f : map->floors) { - const int height_cm = std::round(f->atHeight*100); - floorsAtHeight_cm.push_back(height_cm); - } - const bool connected = std::find(floorsAtHeight_cm.begin(), floorsAtHeight_cm.end(), stairEnd_cm) != floorsAtHeight_cm.end(); - return connected; -} - class MV2DElementStair : public MV2DElement, public HasMoveableNodes { private: @@ -27,296 +14,38 @@ private: Floorplan::IndoorMap* map; Floorplan::Floor* floor; Floorplan::Stair* stair; - //int selPart = -1; - //int selNode = -1; + public: /** ctor with the stair to render/edit */ - MV2DElementStair(Floorplan::IndoorMap* map, Floorplan::Floor* floor, Floorplan::Stair* stair) : map(map), floor(floor), stair(stair) {;} - + MV2DElementStair(Floorplan::IndoorMap* map, Floorplan::Floor* floor, Floorplan::Stair* stair); /** get the element's 3D bounding box */ - BBox2 getBoundingBox() const override { - BBox2 bbox; - if (dynamic_cast(stair)) { - Floorplan::StairFreeform* stair = dynamic_cast(this->stair); - for (const Floorplan::StairPart p : stair->parts) { - bbox.add(p.start.xy()); - bbox.add(p.end.xy()); - } - } - return bbox; - } + BBox2 getBoundingBox() const override; /** get the element's minimal distance (nearest whatsoever) to the given point */ - ClickDist getMinDistanceXY(const Point2 p) const override { + ClickDist getMinDistanceXY(const Point2 p) const override; - auto comp = [p] (const Floorplan::StairPart& p1, const Floorplan::StairPart& p2) { - const ClickDist d1 = MapElementHelper::getLineDistanceXY(p1.start.xy(), p1.end.xy(), p); - const ClickDist d2 = MapElementHelper::getLineDistanceXY(p2.start.xy(), p2.end.xy(), p); - return d1 < d2; - }; - - auto parts = stair->getParts(); - auto min = std::min_element(parts.begin(), parts.end(), comp); - return MapElementHelper::getLineDistanceXY(min->start.xy(), min->end.xy(), p); - - } - - int getSelPart() const {return getSelectedNode() < 0 ? getSelectedNode() : getSelectedNode() / 2;} - int getSelNode() const {return getSelectedNode() < 0 ? getSelectedNode() : getSelectedNode() % 2;} - - static inline float clamp01(const float val) { - if (val < 0) {return 0;} - if (val > 1) {return 1;} - return val; - } + int getSelPart() const; + int getSelNode() const; /** repaint me */ - void paint(Painter& p) override { + void paint(Painter& p) override; - Floorplan::StairFreeform* stair = dynamic_cast(this->stair); + virtual bool keyPressEvent(MapView2D* v, QKeyEvent *e) override; -// if (sel) { -// p.setPenBrush(Qt::black, CFG::SEL_COLOR); -// p.drawCircle(stair->center); -// } else if (hasFocus()) { -// p.setPenBrush(Qt::black, Qt::NoBrush); -// p.drawCircle(stair->center); -// } else { -// p.setPenBrush(Qt::gray, Qt::NoBrush); -// p.drawCircle(stair->center); -// } + virtual void onFocus() override; - // draw all parts of the stair (all polygons) - p.setPenBrush(Qt::black, Qt::NoBrush); + virtual void onUnfocus() override; - std::vector parts = stair->getParts(); - std::vector quads = Floorplan::getQuads(parts, floor); + virtual std::vector getMoveableNodes() const override; - // skip drawing? - BBox2 bbox; - for (const Floorplan::Quad3& q : quads) { - bbox.add(q.p1.xy()); - bbox.add(q.p2.xy()); - bbox.add(q.p3.xy()); - bbox.add(q.p4.xy()); - } - if (!p.isVisible(bbox)) { - return; - } + void onNodeMove(MapView2D* v, const int userIdx, const Point2 newPos) override; - for (int i = 0; i < (int) parts.size(); ++i) { + void onNodeMoved(MapView2D* v, const int userIdx, const Point2 newPos) override; - const Floorplan::StairPart& part = parts[i]; - const Floorplan::Quad3& quad = quads[i]; - - // fill the polygon with a gradient corresponding with the stair's height relative to the floor's height - QLinearGradient gradient(p.s.xms(part.start.x), p.s.yms(part.start.y), p.s.xms(part.end.x), p.s.yms(part.end.y)); - const float p1 = 0.1 + clamp01( part.start.z / floor->height) * 0.8; - const float p2 = 0.1 + clamp01( part.end.z / floor->height) * 0.8; - gradient.setColorAt(0, QColor(p1*128, p1*128, p1*255, 128)); - gradient.setColorAt(1, QColor(p2*128, p2*128, p2*255, 128)); - p.setBrush(gradient); - p.setPen(QColor(0,0,0,128)); - - // polygon-construction - //const Floorplan::Quad3 quad = part.getQuad(floor); - const std::vector points = {quad.p1, quad.p2, quad.p3, quad.p4}; - p.drawPolygon(points); - - - QPen pen; - pen.setWidth(5); - pen.setColor(QColor(255,0,0)); - p.setPen(pen); - - // LINT disconnected start - if (i == 0) { - if (quad.p1.z != floor->getStartingZ()) { - p.drawLine(quad.p1, quad.p2); - } - } - - // LINT disconnected end - if (i == (int) parts.size() - 1) { - //if (quad.p3.z != floor->getEndingZ()) { - if (!stairEndConnected(map, floor, stair)) { - p.drawLine(quad.p3, quad.p4); - } - } - - // LINT disconnected within - if (i > 0) { - if (quads[i-1].p4.z != quads[i-0].p1.z) { - p.drawLine(quad.p1, quad.p2); - } - } - - } - - if (hasFocus()) { - int cnt = 0; - std::vector parts = stair->getParts(); - for (const Floorplan::StairPart& part : parts) { - p.setPenBrush(Qt::black, (cnt == getSelPart() && getSelNode() == 0) ? CFG::SEL_COLOR : Qt::NoBrush); // part start - p.drawCircle(part.start.xy()); - p.setPenBrush(Qt::black, (cnt == getSelPart() && getSelNode() == 1) ? CFG::SEL_COLOR : Qt::NoBrush); // part end - p.drawRect(part.end.xy()); - p.setPenBrush(Qt::blue, Qt::NoBrush); - Point2 ctr = (part.start+part.end).xy() / 2; - p.drawText(ctr, "p" + std::to_string(cnt+1)); // part name - ++cnt; - } - for (int i = 0; i < (int)parts.size() - 1; ++i) { - const Point3 p1 = parts[i+0][1]; - const Point3 p2 = parts[i+1][0]; - p.drawLine(p1.xy(), p2.xy()); - } - } - - } - - - -// /** mouse pressed at the given point */ -// virtual void mousePressed(MapView2D* v, const Point2 p) override { -// (void) v; -// (void) p; - -// } - -// /** mouse moved to the given point */ -// virtual void mouseMove(MapView2D* v, const Point2 _p) override { -// (void) v; -// if (selPart == -1) {return;} -// Floorplan::StairFreeform* stair = dynamic_cast(this->stair); -// const Point2 p = v->getScaler().snap(_p); -// stair->parts[selPart][selNode].x = p.x; -// stair->parts[selPart][selNode].y = p.y; -// } - -// /** mouse released */ -// virtual void mouseReleased(MapView2D* v, const Point2 _p) override { -// (void) v; -// (void) _p; -// // select a new point on mouse-release (more robust than on mouse-press) -// Floorplan::StairFreeform* stair = dynamic_cast(this->stair); -// const float t = v->getScaler().sm(CFG::SEL_THRESHOLD_SIZE_PX); -//// auto comp = [&] (const Point3 a, const Point3 b) {return a.xy().getDistance(_p) < b.xy().getDistance(_p);}; -//// auto it = std::min_element(stair->nodes.begin(), stair->nodes.end(), comp); -//// if (it == stair->nodes.end()) {selIdx = -1;} // none found -> skip -//// else if ((*it).xy().getDistance(_p) > t) {selIdx = -1;} // nearest distance is above threshold -> skip -//// else {selIdx = it - stair->nodes.begin();} - -// float best = 999999; -// int minPart; int minNode; -// for (int part = 0; part < (int) stair->parts.size(); ++part) { -// for (int node = 0; node < 2; ++node) { -// const float dist = stair->parts[part][node].xy().getDistance(_p); -// if (dist < best) {best = dist; minPart = part; minNode = node;} -// } -// } - -// if (best <= t) { -// selPart = minPart; selNode = minNode; -// } else { -// selPart = -1; selNode = -1; -// } - -// emit v->onElementChange(this); - -// } - - virtual bool keyPressEvent(MapView2D* v, QKeyEvent *e) override { - (void) v; - (void) e; - - Floorplan::StairFreeform* stair = dynamic_cast(this->stair); - - if (e->key() == Qt::Key_Delete) { - - // delete the currently selected vertex? - if (getSelPart() != -1) { -// stair->nodes.erase(stair->nodes.begin() + selIdx); -// selIdx = -1; -// return true; - } - - } else if (e->key() == Qt::Key_Plus && getSelPart() != -1) { -// int idx1 = selIdx; -// int idx2 = (selIdx + 1) % stair->nodes.size(); -// int idxNew = idx2; -// Point3 pNew = (stair->nodes[idx1] + stair->nodes[idx2]) / 2.0f; -// stair->nodes.insert(stair->nodes.begin() + idxNew, pNew); -// selIdx = idxNew; -// return true; - const int idxNew = getSelPart() + 1; - const Point3 p0 = stair->parts[getSelPart()][1]; - const Point3 p1 = p0 + Point3(1,1,0); - const Point3 p2 = p1 + Point3(2,2,0); - const float w = stair->parts[getSelPart()].width; - stair->parts.insert(stair->parts.begin() + idxNew, Floorplan::StairPart(p1, p2, w)); - return true; - } - - // not consumed - return false; - - } - - virtual void onFocus() override { - // TODO? - } - - virtual void onUnfocus() override { - sel = false; - } - - virtual std::vector getMoveableNodes() const override { - - std::vector nodes; - Floorplan::StairFreeform* stair = dynamic_cast(this->stair); - - // get a list of all moveable nodes (2 per stair-part) - int idx = 0; - for (size_t part = 0; part < stair->parts.size(); ++part) { - for (int node = 0; node < 2; ++node) { - MoveableNode mn(idx++, stair->parts[part][node].xy()); - nodes.push_back(mn); - } - } - - return nodes; - - } - - void onNodeMove(MapView2D* v, const int userIdx, const Point2 newPos) override { - - (void) v; - - // convert node-index back to stair-part and node-nr within stair-part - const int selPart = userIdx / 2; - const int selNode = userIdx % 2; - - // move the node - Floorplan::StairFreeform* stair = dynamic_cast(this->stair); - stair->parts[selPart][selNode].x = newPos.x; - stair->parts[selPart][selNode].y = newPos.y; - - } - - void onNodeMoved(MapView2D* v, const int userIdx, const Point2 newPos) override { - (void) userIdx; - (void) newPos; - emit v->onElementChange(this); - } - - void onNodeSelect(MapView2D* v, const int userIdx) override { - HasMoveableNodes::onNodeSelect(v, userIdx); - emit v->onElementChange(this); - } + void onNodeSelect(MapView2D* v, const int userIdx) override; }; diff --git a/mapview/2D/MapView2D.cpp b/mapview/2D/MapView2D.cpp index f3c15b6..4a35c5e 100644 --- a/mapview/2D/MapView2D.cpp +++ b/mapview/2D/MapView2D.cpp @@ -16,7 +16,7 @@ MapView2D::MapView2D(QWidget* parent) : QOpenGLWidget(parent) { // openGL params QSurfaceFormat format; - format.setDepthBufferSize(24); + format.setDepthBufferSize(8); // 24 format.setStencilBufferSize(8); format.setSamples(1); // format.setVersion(3, 2); @@ -49,11 +49,19 @@ void MapView2D::paintGL() { // background tools tools.paintBefore(this, p); - // render all visible elements + qp.setRenderHint( QPainter::Antialiasing, true ); + + // render all visible elements. 1st run for (MapModelElement* el : getModel()->getVisibleElements()) { if (el->getMV2D()) {el->getMV2D()->paint(p);} } + + // render all visible elements. 2nd run + for (MapModelElement* el : getModel()->getVisibleElements()) { + if (el->getMV2D()) {el->getMV2D()->paintAfter(p);} + } + qp.setRenderHint( QPainter::Antialiasing, false ); // foreground tools @@ -68,7 +76,9 @@ void MapView2D::initializeGL() { } -void MapView2D::resizeGL() { +void MapView2D::resizeGL(int w, int h) { + (void) w; + (void) h; // TODO ? } @@ -110,10 +120,12 @@ bool MapView2D::event(QEvent* event) { bool MapView2D::gestureEvent(QGestureEvent* event) { if (QGesture *swipe = event->gesture(Qt::SwipeGesture)) { + (void) swipe; //swipeTriggered(static_cast(swipe)); - } else if (QGesture *pan = event->gesture(Qt::PanGesture)) + } else if (QGesture *pan = event->gesture(Qt::PanGesture)) { panTriggered(static_cast(pan)); return true; + } if (QGesture *pinch = event->gesture(Qt::PinchGesture)) { pinchTriggered(static_cast(pinch)); return true; diff --git a/mapview/2D/MapView2D.h b/mapview/2D/MapView2D.h index 3565c2c..4c18560 100644 --- a/mapview/2D/MapView2D.h +++ b/mapview/2D/MapView2D.h @@ -47,9 +47,9 @@ public: public: - void paintGL(); - void initializeGL(); - void resizeGL(); + virtual void paintGL() override; + virtual void initializeGL() override; + virtual void resizeGL(int w, int h) override; Tools& getTools() {return tools;} diff --git a/mapview/2D/MapViewElementHelper.cpp b/mapview/2D/MapViewElementHelper.cpp new file mode 100644 index 0000000..1d77517 --- /dev/null +++ b/mapview/2D/MapViewElementHelper.cpp @@ -0,0 +1,66 @@ +#include "MapViewElementHelper.h" + +#include +#include +#include + +#include +#include +#include + +#include + +ClickDist MapElementHelper::getLineDistanceXY(Point2 p1, Point2 p2, Point2 dst) { + + // the line (p1, p2) + const Line2 line(p1, p2); + + // 90 degree rotation L of the line (p1, p2) + const Point2 vec = (p1 - p2).perpendicular(); + + // the line L + const Line2 perb(dst-vec*100, dst+vec*100); + + // calculate the cut betwen L and (p1,p2) (if any) + Point2 cut(0,0); + ClickDist cutDist(99999999, ClickDistType::CUT); + if (line.getSegmentIntersection(perb, cut)) { + + // distance between cut-point and mouse + cutDist.dst_px = cut.getDistance(dst); + + } + + // (direct) distance from endpoints + const ClickDist d1(p1.getDistance(dst), ClickDistType::DIRECT); + const ClickDist d2(p2.getDistance(dst), ClickDistType::DIRECT); + + // return the nearest possibility: + return std::min(d1, std::min(d2, cutDist)); + +} + +QPen MapElementHelper::getPen(Floorplan::Material mat, Floorplan::ObstacleType type, bool focus, float thickness_px) { + + using namespace Floorplan; + QPen pen; + pen.setColor(Qt::darkGray); // default color + pen.setWidth(thickness_px); // element thickness + + // this one is very important! + // as we change the line's width, the line also becomes longer + // but, we do not want this! -> FlatCap + pen.setCapStyle(Qt::FlatCap); + + if (focus) {pen.setColor(QColor(64,64,200));} + else if (mat == Material::CONCRETE) {pen.setColor(QColor(32,32,32));} + else if (mat == Material::DRYWALL) {;} + else if (mat == Material::GLASS) {pen.setStyle(Qt::PenStyle::DotLine);} + else if (mat == Material::METALLIZED_GLAS) {pen.setStyle(Qt::PenStyle::DotLine);} + else if (mat == Material::METAL) {pen.setColor(QColor(64, 64, 64));} + else if (type == ObstacleType::HANDRAIL) {pen.setStyle(Qt::PenStyle::DashLine);} + else if (type == ObstacleType::UNKNOWN) {pen.setColor(Qt::red);} + else if (type == ObstacleType::PILLAR) {pen.setColor(Qt::red);} + + return pen; +} diff --git a/mapview/2D/MapViewElementHelper.h b/mapview/2D/MapViewElementHelper.h index ccb6b1e..4410f89 100644 --- a/mapview/2D/MapViewElementHelper.h +++ b/mapview/2D/MapViewElementHelper.h @@ -5,9 +5,7 @@ #include #include -#include #include -#include #include @@ -35,59 +33,9 @@ public: * move l into dst * and calculate the cut-point between l and (p1, p2) */ - static ClickDist getLineDistanceXY(Point2 p1, Point2 p2, Point2 dst) { - - // the line (p1, p2) - const Line2 line(p1, p2); - - // 90 degree rotation L of the line (p1, p2) - const Point2 vec = (p1 - p2).perpendicular(); - - // the line L - const Line2 perb(dst-vec*100, dst+vec*100); - - // calculate the cut betwen L and (p1,p2) (if any) - Point2 cut(0,0); - ClickDist cutDist(99999999, ClickDistType::CUT); - if (line.getSegmentIntersection(perb, cut)) { - - // distance between cut-point and mouse - cutDist.dst_px = cut.getDistance(dst); - - } - - // (direct) distance from endpoints - const ClickDist d1(p1.getDistance(dst), ClickDistType::DIRECT); - const ClickDist d2(p2.getDistance(dst), ClickDistType::DIRECT); - - // return the nearest possibility: - return std::min(d1, std::min(d2, cutDist)); - - } - - static QPen getPen(Floorplan::Material mat, Floorplan::ObstacleType type, bool focus, float thickness_px) { - - using namespace Floorplan; - QPen pen; pen.setColor(Qt::darkGray); - pen.setWidth(thickness_px); - - // this one is very important! - // as we change the line's width, the line also becomes longer - // but, we do not want this! -> FlatCap - pen.setCapStyle(Qt::FlatCap); - - if (focus) {pen.setColor(Qt::black);} - if (mat == Material::CONCRETE) {;} - if (mat == Material::GLASS) {pen.setStyle(Qt::PenStyle::DotLine);} - if (mat == Material::METALLIZED_GLAS) {pen.setStyle(Qt::PenStyle::DotLine);} - if (mat == Material::METAL) {pen.setColor(QColor(50, 50, 50));} - if (type == ObstacleType::HANDRAIL) {pen.setStyle(Qt::PenStyle::DashLine);} - if (type == ObstacleType::UNKNOWN) {pen.setColor(Qt::red);} - if (type == ObstacleType::PILLAR) {pen.setColor(Qt::red);} - - return pen; - } + static ClickDist getLineDistanceXY(Point2 p1, Point2 p2, Point2 dst); + static QPen getPen(Floorplan::Material mat, Floorplan::ObstacleType type, bool focus, float thickness_px); }; diff --git a/mapview/2D/Painter.cpp b/mapview/2D/Painter.cpp new file mode 100644 index 0000000..7663323 --- /dev/null +++ b/mapview/2D/Painter.cpp @@ -0,0 +1,158 @@ +#include "Painter.h" + +#include +#include + +#include +#include +#include + +#include "Scaler.h" + +Painter::Painter(Scaler& s, QPainter* p, int w, int h) : s(s), p(p), w(w), h(h) { + p->setPen(Qt::black); + p->setBrush(Qt::NoBrush); +} + +int Painter::width() {return w;} + +int Painter::height() {return h;} + +bool Painter::isVisible(const Point2 p) { + const float x = s.xms(p.x); + const float y = s.yms(p.y); + return (x >= 0 && y >= 0 && x < w && y < h); +} + +bool Painter::isVisible(const BBox2 bb) { + const BBox2 bbt(0,0,w,h); + BBox2 bbs; + bbs.add(s.xms(bb.getMin().x), s.yms(bb.getMin().y)); // y might be inverted! -> use the add() method to address this + bbs.add(s.xms(bb.getMax().x), s.yms(bb.getMax().y)); // y might be inverted! -> use the add() method to address this + return bbt.intersects(bbs); +} + +void Painter::drawLine(const Point2 p1, const Point2 p2) { + //p->drawLine(s.xms(p1.x), s.yms(p1.y), s.xms(p2.x), s.yms(p2.y)); + p->drawLine(QPointF(s.xms(p1.x), s.yms(p1.y)), QPointF(s.xms(p2.x), s.yms(p2.y))); +} +void Painter::drawLine(const Point3 p1, const Point3 p2) { + //p->drawLine(s.xms(p1.x), s.yms(p1.y), s.xms(p2.x), s.yms(p2.y)); + p->drawLine(QPointF(s.xms(p1.x), s.yms(p1.y)), QPointF(s.xms(p2.x), s.yms(p2.y))); +} + +float Painter::radToDeg(const float rad) const { + return rad * 180 / M_PI; +} + +void Painter::drawArc(const Point2 center, const float radius, const float startAngleRad, const float spanAngleRad) { + const float wh = s.ms(radius) * 2; + const float x1 = s.xms(center.x) - wh/2; + const float y1 = s.yms(center.y) - wh/2; + p->drawArc(x1, y1, wh, wh, radToDeg(startAngleRad)*16, radToDeg(spanAngleRad)*16); +} + +void Painter::drawCircle(const Point3 center) { + int r = 5; + p->drawEllipse(s.xms(center.x)-r, s.yms(center.y)-r, 2*r, 2*r); +} + +void Painter::drawCircle(const Point2 center) { + int r = 5; + p->drawEllipse(s.xms(center.x)-r, s.yms(center.y)-r, 2*r, 2*r); +} + +/** draw a dot at the given map coordinates */ +void Painter::drawDot(const Point2 center) { + int r = 1; + p->drawEllipse(s.xms(center.x)-r, s.yms(center.y)-r, 2*r, 2*r); +} + +void Painter::drawCircle(const Point2 center, const float size_m) { + int r = s.ms(size_m); + p->drawEllipse(s.xms(center.x)-r, s.yms(center.y)-r, 2*r, 2*r); +} + +void Painter::drawCircle_px(const Point2 center, const float size_px) { + int r = size_px; + p->drawEllipse(s.xms(center.x)-r, s.yms(center.y)-r, 2*r, 2*r); +} + +void Painter::drawNode(Point2 pt, bool focused, bool selected) { + float rs = 0.05; + if (selected) {setPenBrush(Qt::black, Qt::gray); rs = 0.08;} + else if (focused) {setPenBrush(Qt::black, Qt::white); rs = 0.08;} + else {setPenBrush(Qt::black, Qt::NoBrush); rs = 0.04;} + const float s = this->s.getScale(); + if (s > 10) {drawCircle(pt, rs);} // only at a certain zoom level +} + +void Painter::drawLine(const float x1, const float y1, const float x2, const float y2) { + p->drawLine(s.xms(x1), s.yms(y1), s.xms(x2), s.yms(y2)); +} + +void Painter::drawRect(const Point2 p1, const Point2 p2) { + drawRect(p1.x, p1.y, p2.x, p2.y); +} + +void Painter::drawRect(const float x1, const float y1, const float x2, const float y2) { + float w = x2-x1; + float h = y1-y2; + p->drawRect(s.xms(x1), s.yms(y1), s.ms(w), s.ms(h)); +} + +void Painter::drawRect(const Point2 center) { + float r = s.sm(5); // 5 pixel + drawRect(center-Point2(r,r), center+Point2(r,r)); +} + +void Painter::drawText(const Point2 pos, const std::string& text) { + p->drawText(s.xms(pos.x), s.yms(pos.y), text.c_str()); +} + +void Painter::drawPolygon(const std::vector& points) { + std::vector vec; + for (const Point2 p : points) { + vec.push_back(QPointF(s.xms(p.x), s.yms(p.y))); + } + p->drawPolygon(vec.data(), vec.size()); +} +void Painter::drawPolygon(const std::vector& points) { + std::vector vec; + for (const Point3 p : points) { + vec.push_back(QPointF(s.xms(p.x), s.yms(p.y))); + } + p->drawPolygon(vec.data(), vec.size()); +} + +void Painter::drawPixmap(const Point2 pt, const QPixmap& img) { + p->drawPixmap(s.xms(pt.x)-img.width()/2, s.yms(pt.y)-img.height()/2, img); +} + +void Painter::drawImage(const Point2 pt, const QImage& img) { + p->drawImage(s.xms(pt.x)-img.width()/2, s.yms(pt.y)-img.height()/2, img); +} + +void Painter::drawLength(Point2 p1, Point2 p2, const float len, const float offset) { + if (p1.x < p2.x) {swap(p1, p2);} + const Point2 center_m = (p1 + p2) / 2; + Point2 dir_px = (p2 - p1).perpendicular().normalized() * (5+offset); + if (dir_px.x <= 0) {dir_px = -dir_px;} + const Point2 pos_m = center_m + dir_px / getScaler().getScale(); + char buf[64]; sprintf(buf, "%.1f", len); + drawText(pos_m, buf); +} + + + +void Painter::setBrush(const QBrush& brush) { p->setBrush(brush); } +void Painter::setBrush(const Qt::BrushStyle& brush) { p->setBrush(brush); } + +void Painter::setPen(const QPen& pen) {p->setPen(pen); } +void Painter::setPen(const QColor& pen) {p->setPen(pen); } +void Painter::setPen(const Qt::PenStyle& pen) {p->setPen(pen); } + +const QPen& Painter::getPen() {return p->pen();} + +const Scaler& Painter::getScaler() {return s;} + diff --git a/mapview/2D/Painter.h b/mapview/2D/Painter.h index fdb502d..eb5e870 100644 --- a/mapview/2D/Painter.h +++ b/mapview/2D/Painter.h @@ -1,14 +1,21 @@ #ifndef PAINTER_H #define PAINTER_H -#include -#include - #include #include #include -#include "Scaler.h" +//#include "Scaler.h" + +class Scaler; +class QPainter; +class QPixmap; +class QImage; +class QPen; +class QColor; +class QBrush; + +#include class Painter { @@ -22,145 +29,66 @@ public: public: /** ctor */ - Painter(Scaler& s, QPainter* p, int w, int h) : s(s), p(p), w(w), h(h) { - p->setPen(Qt::black); - p->setBrush(Qt::NoBrush); - } + Painter(Scaler& s, QPainter* p, int w, int h); - int width() {return w;} + int width(); - int height() {return h;} + int height(); /** is the given point visible on screen? */ - bool isVisible(const Point2 p) { - const float x = s.xms(p.x); - const float y = s.yms(p.y); - return (x >= 0 && y >= 0 && x < w && y < h); - } + bool isVisible(const Point2 p); /** is the given volume visible on screen? */ - bool isVisible(const BBox2 bb) { - const BBox2 bbt(0,0,w,h); - BBox2 bbs; - bbs.add(s.xms(bb.getMin().x), s.yms(bb.getMin().y)); // y might be inverted! -> use the add() method to address this - bbs.add(s.xms(bb.getMax().x), s.yms(bb.getMax().y)); // y might be inverted! -> use the add() method to address this - return bbt.intersects(bbs); - } + bool isVisible(const BBox2 bb); - void drawLine(const Point2 p1, const Point2 p2) { - p->drawLine(s.xms(p1.x), s.yms(p1.y), s.xms(p2.x), s.yms(p2.y)); - } - void drawLine(const Point3 p1, const Point3 p2) { - p->drawLine(s.xms(p1.x), s.yms(p1.y), s.xms(p2.x), s.yms(p2.y)); - } + void drawLine(const Point2 p1, const Point2 p2); + void drawLine(const Point3 p1, const Point3 p2); + void drawLine(const float x1, const float y1, const float x2, const float y2); - float radToDeg(const float rad) const { - return rad * 180 / M_PI; - } + float radToDeg(const float rad) const; - void drawArc(const Point2 center, const float radius, const float startAngleRad, const float spanAngleRad) { - const float wh = s.ms(radius) * 2; - const float x1 = s.xms(center.x) - wh/2; - const float y1 = s.yms(center.y) - wh/2; - p->drawArc(x1, y1, wh, wh, radToDeg(startAngleRad)*16, radToDeg(spanAngleRad)*16); - } - - void drawCircle(const Point3 center) { - int r = 5; - p->drawEllipse(s.xms(center.x)-r, s.yms(center.y)-r, 2*r, 2*r); - } - - void drawCircle(const Point2 center) { - int r = 5; - p->drawEllipse(s.xms(center.x)-r, s.yms(center.y)-r, 2*r, 2*r); - } + void drawArc(const Point2 center, const float radius, const float startAngleRad, const float spanAngleRad); /** draw a dot at the given map coordinates */ - void drawDot(const Point2 center) { - int r = 1; - p->drawEllipse(s.xms(center.x)-r, s.yms(center.y)-r, 2*r, 2*r); + void drawDot(const Point2 center); + + void drawCircle(const Point3 center); + void drawCircle(const Point2 center); + void drawCircle(const Point2 center, const float size_m); + void drawCircle_px(const Point2 center, const float size_px); + + void drawRect(const Point2 p1, const Point2 p2); + void drawRect(const float x1, const float y1, const float x2, const float y2); + void drawRect(const Point2 center); + + void drawNode(Point2 pt, bool focused, bool selected); + + void drawText(const Point2 pos, const std::string& text); + + void drawPolygon(const std::vector& points); + void drawPolygon(const std::vector& points); + + void drawPixmap(const Point2 pt, const QPixmap& img); + + void drawImage(const Point2 pt, const QImage& img); + + void drawLength(Point2 p1, Point2 p2, const float len, const float offset = 0); + + void setBrush(const QBrush& brush); + void setBrush(const Qt::BrushStyle& brush); + + void setPen(const QPen& pen); + void setPen(const QColor& pen); + void setPen(const Qt::PenStyle& pen); + + const QPen& getPen(); + + template void setPenBrush(const Pen& pen, const Brush& brush) { + setPen(pen); + setBrush(brush); } - void drawCircle(const Point2 center, const float size_m) { - int r = s.ms(size_m); - p->drawEllipse(s.xms(center.x)-r, s.yms(center.y)-r, 2*r, 2*r); - } - - void drawCircle_px(const Point2 center, const float size_px) { - int r = size_px; - p->drawEllipse(s.xms(center.x)-r, s.yms(center.y)-r, 2*r, 2*r); - } - - void drawLine(const float x1, const float y1, const float x2, const float y2) { - p->drawLine(s.xms(x1), s.yms(y1), s.xms(x2), s.yms(y2)); - } - - void drawRect(const Point2 p1, const Point2 p2) { - drawRect(p1.x, p1.y, p2.x, p2.y); - } - - void drawRect(const float x1, const float y1, const float x2, const float y2) { - float w = x2-x1; - float h = y1-y2; - p->drawRect(s.xms(x1), s.yms(y1), s.ms(w), s.ms(h)); - } - - void drawRect(const Point2 center) { - float r = s.sm(5); // 5 pixel - drawRect(center-Point2(r,r), center+Point2(r,r)); - } - - void drawText(const Point2 pos, const std::string& text) { - p->drawText(s.xms(pos.x), s.yms(pos.y), text.c_str()); - } - - void drawPolygon(const std::vector& points) { - std::vector vec; - for (const Point2 p : points) { - vec.push_back(QPointF(s.xms(p.x), s.yms(p.y))); - } - p->drawPolygon(vec.data(), vec.size()); - } - void drawPolygon(const std::vector& points) { - std::vector vec; - for (const Point3 p : points) { - vec.push_back(QPointF(s.xms(p.x), s.yms(p.y))); - } - p->drawPolygon(vec.data(), vec.size()); - } - - void drawPixmap(const Point2 pt, const QPixmap& img) { - p->drawPixmap(s.xms(pt.x)-img.width()/2, s.yms(pt.y)-img.height()/2, img); - } - - void drawImage(const Point2 pt, const QImage& img) { - p->drawImage(s.xms(pt.x)-img.width()/2, s.yms(pt.y)-img.height()/2, img); - } - - void drawLength(Point2 p1, Point2 p2, const float len, const float offset = 0) { - if (p1.x < p2.x) {swap(p1, p2);} - const Point2 center_m = (p1 + p2) / 2; - Point2 dir_px = (p2 - p1).perpendicular().normalized() * (5+offset); - if (dir_px.x <= 0) {dir_px = -dir_px;} - const Point2 pos_m = center_m + dir_px / getScaler().getScale(); - char buf[64]; sprintf(buf, "%.1f", len); - drawText(pos_m, buf); - } - - void setBrush(const QBrush& brush) { p->setBrush(brush); } - void setBrush(const Qt::BrushStyle& brush) { p->setBrush(brush); } - - void setPen(const QPen& pen) {p->setPen(pen); } - void setPen(const QColor& pen) {p->setPen(pen); } - void setPen(const Qt::PenStyle& pen) {p->setPen(pen); } - - - const QPen& getPen() {return p->pen();} - - - template void setPenBrush(const Pen& pen, const Brush& brush) {setPen(pen); setBrush(brush);} - - const Scaler& getScaler() {return s;} + const Scaler& getScaler(); private: diff --git a/mapview/3D/MapView3D.cpp b/mapview/3D/MapView3D.cpp index 83eca0b..e3e3a7c 100644 --- a/mapview/3D/MapView3D.cpp +++ b/mapview/3D/MapView3D.cpp @@ -236,10 +236,12 @@ bool MapView3D::event(QEvent* event) { bool MapView3D::gestureEvent(QGestureEvent* event) { if (QGesture *swipe = event->gesture(Qt::SwipeGesture)) { + (void) swipe; //swipeTriggered(static_cast(swipe)); - } else if (QGesture *pan = event->gesture(Qt::PanGesture)) + } else if (QGesture *pan = event->gesture(Qt::PanGesture)) { panTriggered(static_cast(pan)); return true; + } if (QGesture *pinch = event->gesture(Qt::PinchGesture)) { pinchTriggered(static_cast(pinch)); return true; @@ -248,6 +250,7 @@ bool MapView3D::gestureEvent(QGestureEvent* event) { } void MapView3D::pinchTriggered(QPinchGesture* gesture) { + (void) gesture; update(); } diff --git a/mapview/3D/floorplan/FloorplanRenderer.cpp b/mapview/3D/floorplan/FloorplanRenderer.cpp new file mode 100644 index 0000000..45f3567 --- /dev/null +++ b/mapview/3D/floorplan/FloorplanRenderer.cpp @@ -0,0 +1,82 @@ +#include "FloorplanRenderer.h" + +#include +#include +#include +#include + +#include +#include +#include + +#include "../misc/Renderable3D.h" +#include "../misc/Shader.h" +#include "../misc/TriangleData.h" + +#include + +#include "RenderTriangle.h" + + +/** ctor */ +FloorplanRenderer::FloorplanRenderer() { + ; +} + +void FloorplanRenderer::renderSolid(const RenderSettings& rs, const RenderTriangle& rt, bool wireframe) { + + rs.shader->bind(); + rs.shader->setModelMatrix(QMatrix4x4()); + + rs.shader->setVertices(rt.getVertices()); + rs.shader->setNormals(rt.getNormals()); + rs.shader->setVertexColor(rt.getRGBA()); + rs.funcs->glDrawArrays(GL_TRIANGLES, 0, rt.count()); + rs.shader->unsetVertices(); + rs.shader->unsetNormals(); + rs.shader->unsetVertexColor(); + + if (wireframe) { + RenderTriangle rt2 = rt.toWireframe(false); + rs.shader->setColor(0,0,0,128); + rs.shader->setVertices(rt2.getVertices()); + //rs.shader->setVertexColor(rt2.getRGBA()); + rs.funcs->glDrawArrays(GL_LINES, 0, rt2.count()); + rs.shader->unsetVertices(); + //rs.shader->unsetVertexColor(); + } + rs.shader->release(); + +} + +void FloorplanRenderer::renderTransp(const RenderSettings& rs, const RenderTriangle& rt, bool wireframe) { + + rs.funcs->glEnable(GL_BLEND); + rs.funcs->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + rs.shader->bind(); + rs.shader->setModelMatrix(QMatrix4x4()); + + rs.shader->setVertices(rt.getVertices()); + rs.shader->setNormals(rt.getNormals()); + rs.shader->setVertexColor(rt.getRGBA()); + rs.funcs->glDrawArrays(GL_TRIANGLES, 0, rt.count()); + rs.shader->unsetVertices(); + rs.shader->unsetNormals(); + rs.shader->unsetVertexColor(); + + if (wireframe) { + RenderTriangle rt2 = rt.toWireframe(false); + rs.shader->setColor(0,0,0,128); + rs.shader->setVertices(rt2.getVertices()); + //rs.shader->setVertexColor(rt2.getRGBA()); + rs.funcs->glDrawArrays(GL_LINES, 0, rt2.count()); + rs.shader->unsetVertices(); + //rs.shader->unsetVertexColor(); + } + + rs.shader->release(); + + rs.funcs->glDisable(GL_BLEND); + +} diff --git a/mapview/3D/floorplan/FloorplanRenderer.h b/mapview/3D/floorplan/FloorplanRenderer.h index c7ed2cf..5a854d1 100644 --- a/mapview/3D/floorplan/FloorplanRenderer.h +++ b/mapview/3D/floorplan/FloorplanRenderer.h @@ -1,91 +1,22 @@ #ifndef FLOORPLANRENDERER_H #define FLOORPLANRENDERER_H -#include -#include -#include -#include - -#include -#include -#include - #include "../misc/Renderable3D.h" -#include "../misc/Shader.h" -#include "../misc/TriangleData.h" -#include - -#include "RenderTriangle.h" +class RenderTriangle; class FloorplanRenderer { public: /** ctor */ - FloorplanRenderer() { - ; - } + FloorplanRenderer(); /** render the given grid using GL commands */ - void renderSolid(const RenderSettings& rs, const RenderTriangle& rt, bool wireframe) { - - rs.shader->bind(); - rs.shader->setModelMatrix(QMatrix4x4()); - - rs.shader->setVertices(rt.getVertices()); - rs.shader->setNormals(rt.getNormals()); - rs.shader->setVertexColor(rt.getRGBA()); - rs.funcs->glDrawArrays(GL_TRIANGLES, 0, rt.count()); - rs.shader->unsetVertices(); - rs.shader->unsetNormals(); - rs.shader->unsetVertexColor(); - - if (wireframe) { - RenderTriangle rt2 = rt.toWireframe(false); - rs.shader->setColor(0,0,0,128); - rs.shader->setVertices(rt2.getVertices()); - //rs.shader->setVertexColor(rt2.getRGBA()); - rs.funcs->glDrawArrays(GL_LINES, 0, rt2.count()); - rs.shader->unsetVertices(); - //rs.shader->unsetVertexColor(); - } - rs.shader->release(); - - } + void renderSolid(const RenderSettings& rs, const RenderTriangle& rt, bool wireframe); /** render the given grid using GL commands */ - void renderTransp(const RenderSettings& rs, const RenderTriangle& rt, bool wireframe) { - - rs.funcs->glEnable(GL_BLEND); - rs.funcs->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - rs.shader->bind(); - rs.shader->setModelMatrix(QMatrix4x4()); - - rs.shader->setVertices(rt.getVertices()); - rs.shader->setNormals(rt.getNormals()); - rs.shader->setVertexColor(rt.getRGBA()); - rs.funcs->glDrawArrays(GL_TRIANGLES, 0, rt.count()); - rs.shader->unsetVertices(); - rs.shader->unsetNormals(); - rs.shader->unsetVertexColor(); - - if (wireframe) { - RenderTriangle rt2 = rt.toWireframe(false); - rs.shader->setColor(0,0,0,128); - rs.shader->setVertices(rt2.getVertices()); - //rs.shader->setVertexColor(rt2.getRGBA()); - rs.funcs->glDrawArrays(GL_LINES, 0, rt2.count()); - rs.shader->unsetVertices(); - //rs.shader->unsetVertexColor(); - } - - rs.shader->release(); - - rs.funcs->glDisable(GL_BLEND); - - } + void renderTransp(const RenderSettings& rs, const RenderTriangle& rt, bool wireframe); }; diff --git a/mapview/3D/navMesh/NavMeshRenderer.cpp b/mapview/3D/navMesh/NavMeshRenderer.cpp index 880e062..601737f 100644 --- a/mapview/3D/navMesh/NavMeshRenderer.cpp +++ b/mapview/3D/navMesh/NavMeshRenderer.cpp @@ -56,7 +56,7 @@ void NavMeshRenderer::rebuildIfNeeded(NavMeshModel* model) { case (int) NM::NavMeshType::STAIR_SKEWED: color = Point3(0.4, 0.4, 0.4); break; } - const float o = 0.001f; + //const float o = 0.001f; outlines.addLine(tria->getP1(), tria->getP2(), color.x, color.y, color.z, 1); outlines.addLine(tria->getP2(), tria->getP3(), color.x, color.y, color.z, 1); outlines.addLine(tria->getP3(), tria->getP1(), color.x, color.y, color.z, 1); diff --git a/mapview/model/MMFloorObstacleDoor.h b/mapview/model/MMFloorObstacleDoor.h index af42c29..0e878a9 100644 --- a/mapview/model/MMFloorObstacleDoor.h +++ b/mapview/model/MMFloorObstacleDoor.h @@ -9,7 +9,7 @@ #include "IHasParams.h" #include "../2D/MV2DElementFloorObstacleDoor.h" -#include "../3D/MV3DElementFloorObstacleDoor.h" +//#include "../3D/MV3DElementFloorObstacleDoor.h" #include @@ -21,12 +21,12 @@ public: Floorplan::Floor* mf; Floorplan::FloorObstacleDoor* fo; MV2DElementFloorObstacleDoor mv2d; - MV3DElementFloorObstacleDoor mv3d; + //MV3DElementFloorObstacleDoor mv3d; public: MMFloorObstacleDoor(MapLayer* parent, Floorplan::Floor* mf, Floorplan::FloorObstacleDoor* fo) : - MapModelElement(parent), mf(mf), fo(fo), mv2d(fo), mv3d(mf,fo) { + MapModelElement(parent), mf(mf), fo(fo), mv2d(fo) {//, mv3d(mf,fo) { } @@ -37,7 +37,7 @@ public: Floorplan::DoorType getDoorType() const override {return fo->type;} MV2DElement* getMV2D() const override {return (MV2DElement*) &mv2d;} - MV3DElement* getMV3D() const override {return (MV3DElement*) &mv3d;} + //MV3DElement* getMV3D() const override {return (MV3DElement*) &mv3d;} void deleteMe() const override { parent->removeElement(this); diff --git a/mapview/model/MMFloorObstacleLine.h b/mapview/model/MMFloorObstacleLine.h index 95fde9d..4e93943 100644 --- a/mapview/model/MMFloorObstacleLine.h +++ b/mapview/model/MMFloorObstacleLine.h @@ -9,7 +9,7 @@ #include "IHasParams.h" #include "../2D/MV2DElementFloorObstacleLine.h" -#include "../3D/MV3DElementFloorObstacleWall.h" +//#include "../3D/MV3DElementFloorObstacleWall.h" #include @@ -21,12 +21,12 @@ public: Floorplan::Floor* mf; Floorplan::FloorObstacleLine* fo; MV2DElementFloorObstacleLine mv2d; - MV3DElementFloorObstacleWall mv3d; + //MV3DElementFloorObstacleWall mv3d; public: MMFloorObstacleLine(MapLayer* parent, Floorplan::Floor* mf, Floorplan::FloorObstacleLine* fo) : - MapModelElement(parent), mf(mf), fo(fo), mv2d(fo), mv3d(mf,fo) { + MapModelElement(parent), mf(mf), fo(fo), mv2d(fo) {//, mv3d(mf,fo) { } @@ -37,7 +37,7 @@ public: Floorplan::ObstacleType getObatcleType() const override {return fo->type;} MV2DElement* getMV2D() const override {return (MV2DElement*) &mv2d;} - MV3DElement* getMV3D() const override {return (MV3DElement*) &mv3d;} + //MV3DElement* getMV3D() const override {return (MV3DElement*) &mv3d;} void deleteMe() const override { parent->removeElement(this); diff --git a/mapview/model/MMFloorObstacleObject.h b/mapview/model/MMFloorObstacleObject.h index 5502602..36af8fb 100644 --- a/mapview/model/MMFloorObstacleObject.h +++ b/mapview/model/MMFloorObstacleObject.h @@ -10,7 +10,7 @@ #include "IHasParams.h" #include "../2D/MV2DElementFloorObstacleObject.h" -#include "../3D/MV3DElementFloorObstacleObject.h" +//#include "../3D/MV3DElementFloorObstacleObject.h" #include @@ -22,17 +22,17 @@ public: Floorplan::Floor* mf; Floorplan::FloorObstacleObject* fo; MV2DElementFloorObstacleObject mv2d; - MV3DElementFloorObstacleObject mv3d; + //MV3DElementFloorObstacleObject mv3d; public: MMFloorObstacleObject(MapLayer* parent, Floorplan::Floor* mf, Floorplan::FloorObstacleObject* fo) : - MapModelElement(parent), mf(mf), fo(fo), mv2d(fo), mv3d(mf,fo) { + MapModelElement(parent), mf(mf), fo(fo), mv2d(fo) {//, mv3d(mf,fo) { } MV2DElement* getMV2D() const override {return (MV2DElement*) &mv2d;} - MV3DElement* getMV3D() const override {return (MV3DElement*) &mv3d;} + //MV3DElement* getMV3D() const override {return (MV3DElement*) &mv3d;} void deleteMe() const override { parent->removeElement(this); diff --git a/mapview/model/MMFloorOutline.h b/mapview/model/MMFloorOutline.h index 49280a3..5db08fc 100644 --- a/mapview/model/MMFloorOutline.h +++ b/mapview/model/MMFloorOutline.h @@ -5,7 +5,7 @@ #include "MMFloorOutlinePolygon.h" #include "MMFloorOutlinePolygonCombined.h" -#include "../3D/MV3DElementFloorOutline.h" +//#include "../3D/MV3DElementFloorOutline.h" #include diff --git a/mapview/model/MMFloorOutlinePolygonCombined.h b/mapview/model/MMFloorOutlinePolygonCombined.h index 7fa59a7..d822203 100644 --- a/mapview/model/MMFloorOutlinePolygonCombined.h +++ b/mapview/model/MMFloorOutlinePolygonCombined.h @@ -3,7 +3,7 @@ #include "MapLayer.h" #include "MMFloorOutlinePolygon.h" -#include "../3D/MV3DElementFloorOutline.h" +//#include "../3D/MV3DElementFloorOutline.h" #include @@ -19,19 +19,19 @@ private: /** the underlying model */ Floorplan::Floor* floor; - MV3DElementFloorOutline mv3d; + //MV3DElementFloorOutline mv3d; public: /** ctor with the underlying model */ MMFloorOutlinePolygonCombined(MapLayer* parent, Floorplan::Floor* floor) : - MapModelElement(parent), floor(floor), mv3d(floor, &floor->outline) { + MapModelElement(parent), floor(floor) {//, mv3d(floor, &floor->outline) { ; } - MV3DElement* getMV3D() const override {return (MV3DElement*) &mv3d;} + //MV3DElement* getMV3D() const override {return (MV3DElement*) &mv3d;} /** get the corresponding floor from the underlying model */ Floorplan::Floor* getFloor() {return floor;} diff --git a/mapview/model/MMFloorStair.h b/mapview/model/MMFloorStair.h index 98a1aa6..b9c3ac6 100644 --- a/mapview/model/MMFloorStair.h +++ b/mapview/model/MMFloorStair.h @@ -6,7 +6,7 @@ #include "MMFloorOutlinePolygon.h" #include "../2D/MV2DElementStair.h" -#include "../3D/MV3DElementStair.h" +//#include "../3D/MV3DElementStair.h" #include @@ -23,20 +23,20 @@ private: Floorplan::StairFreeform* stair; MV2DElementStair mv2d; - MV3DElementStair mv3d; + //MV3DElementStair mv3d; public: /** ctor with the underlying model */ MMFloorStair(MapLayer* parent, Floorplan::IndoorMap* map, Floorplan::Floor* floor, Floorplan::StairFreeform* stair) : - MapModelElement(parent), floor(floor), stair(stair), mv2d(map, floor, stair), mv3d(floor, stair) { + MapModelElement(parent), floor(floor), stair(stair), mv2d(map, floor, stair) {//, mv3d(floor, stair) { ; } MV2DElement* getMV2D() const override {return (MV2DElement*) &mv2d;} - MV3DElement* getMV3D() const override {return (MV3DElement*) &mv3d;} + //MV3DElement* getMV3D() const override {return (MV3DElement*) &mv3d;} virtual int getNumParams() const override { diff --git a/mapview/model/MapLayer.h b/mapview/model/MapLayer.h index 2537494..d0145b1 100644 --- a/mapview/model/MapLayer.h +++ b/mapview/model/MapLayer.h @@ -188,6 +188,7 @@ public: } void setVisible(const bool visible) override { + (void) visible; throw "error"; } diff --git a/params/EditFields.h b/params/EditFields.h index d3a383e..c201893 100644 --- a/params/EditFields.h +++ b/params/EditFields.h @@ -7,15 +7,17 @@ #include #include #include +#include +#include +#include + #include "../mapview/model/IHasParams.h" class EditFields { public: - static void get(QGridLayout* lay, IHasParams* elem) { - - int r = 0; + static void get(QWidget* parent, int& r, QGridLayout* lay, IHasParams* elem) { for(int i = 0; i < elem->getNumParams(); ++i) { @@ -29,8 +31,24 @@ public: switch(param.type) { + case ParamType::NOT_AVAILABLE: + break; + + case ParamType::ENUM: { + QComboBox* cmb = new QComboBox(parent); + int idx = 0; + for (const std::string& str : param.getEnumValues()) {cmb->addItem(str.c_str(), idx++);} + cmb->setCurrentIndex(value.toInt()); + cmb->connect(cmb, static_cast(&QComboBox::currentIndexChanged), [i, elem, cmb] (int idx) { + (void) idx; + elem->setParamValue(i, cmb->currentData().toInt() ); + }); + lay->addWidget(cmb,r,1); + break; + } + case ParamType::BOOL: { - QCheckBox* chk = new QCheckBox( ); + QCheckBox* chk = new QCheckBox(parent); chk->setChecked(value.toBool()); if (param.readOnly) { chk->setEnabled(false); @@ -46,9 +64,9 @@ public: case ParamType::FLOAT: { const std::string str = std::to_string(value.toFloat()); if (param.readOnly) { - lay->addWidget(new QLabel(str.c_str()),r,1); + lay->addWidget(new QLabel(str.c_str(), parent),r,1); } else { - QLineEdit* le = new QLineEdit( str.c_str() ); + QLineEdit* le = new QLineEdit(str.c_str(), parent); le->connect(le, &QLineEdit::textChanged, [i,elem] (const QString& str) { const float val = str.toFloat(); elem->setParamValue(i, ParamValue(val)); @@ -61,11 +79,11 @@ public: case ParamType::DOUBLE: { const std::string str = std::to_string(value.toDouble()); if (param.readOnly) { - lay->addWidget(new QLabel(str.c_str()),r,1); + lay->addWidget(new QLabel(str.c_str(), parent),r,1); } else { - QLineEdit* le = new QLineEdit( str.c_str() ); + QLineEdit* le = new QLineEdit(str.c_str(), parent); le->connect(le, &QLineEdit::textChanged, [i,elem] (const QString& str) { - const float val = str.toDouble(); + const double val = str.toDouble(); elem->setParamValue(i, ParamValue(val)); }); lay->addWidget(le,r,1); @@ -75,7 +93,7 @@ public: case ParamType::INT: { const std::string str = std::to_string(value.toInt()); - QLineEdit* le = new QLineEdit( str.c_str() ); + QLineEdit* le = new QLineEdit(str.c_str(), parent); le->connect(le, &QLineEdit::textChanged, [i,elem] (const QString& str) { const int val = str.toInt(); elem->setParamValue(i, ParamValue(val)); @@ -86,7 +104,7 @@ public: case ParamType::STRING: { const std::string str = value.toString(); - QLineEdit* le = new QLineEdit( str.c_str() ); + QLineEdit* le = new QLineEdit(str.c_str(), parent); le->connect(le, &QLineEdit::textChanged, [i,elem] (const QString& str) { elem->setParamValue(i, ParamValue(str.toStdString())); }); @@ -96,8 +114,8 @@ public: case ParamType::FILE: { const std::string str = value.toString(); - QLabel* lblFile = new QLabel(str.c_str()); - QPushButton* btn = new QPushButton("<"); + QLabel* lblFile = new QLabel(str.c_str(), parent); + QPushButton* btn = new QPushButton("<",parent); btn->setMaximumSize(32,32); btn->connect(btn, &QPushButton::clicked, [i,elem,lblFile] (const bool checked) { (void) checked; @@ -112,10 +130,10 @@ public: case ParamType::POINT2: { const Point2 p2 = value.toPoint2(); - QWidget* subWidget = new QWidget(); + QWidget* subWidget = new QWidget(parent); QGridLayout* laySub = new QGridLayout(subWidget); laySub->setMargin(0); - QLineEdit* txtX = new QLineEdit(QString::number(p2.x)); - QLineEdit* txtY = new QLineEdit(QString::number(p2.y)); + QLineEdit* txtX = new QLineEdit(QString::number(p2.x), subWidget); + QLineEdit* txtY = new QLineEdit(QString::number(p2.y), subWidget); laySub->addWidget(txtX,0,0); laySub->addWidget(txtY,0,1); lay->addWidget(subWidget,r,1); @@ -130,11 +148,11 @@ public: case ParamType::POINT3: { const Point3 p3 = value.toPoint3(); - QWidget* subWidget = new QWidget(); + QWidget* subWidget = new QWidget(parent); QGridLayout* laySub = new QGridLayout(subWidget); laySub->setMargin(0); - QLineEdit* txtX = new QLineEdit(QString::number(p3.x)); - QLineEdit* txtY = new QLineEdit(QString::number(p3.y)); - QLineEdit* txtZ = new QLineEdit(QString::number(p3.z)); + QLineEdit* txtX = new QLineEdit(QString::number(p3.x), subWidget); + QLineEdit* txtY = new QLineEdit(QString::number(p3.y), subWidget); + QLineEdit* txtZ = new QLineEdit(QString::number(p3.z), subWidget); laySub->addWidget(txtX,0,0); laySub->addWidget(txtY,0,1); laySub->addWidget(txtZ,0,2); @@ -149,8 +167,8 @@ public: break; } - case ParamType::NOT_AVAILABLE: - break; + + } diff --git a/params/ElementParamWidget.cpp b/params/ElementParamWidget.cpp index 673664b..e7e2ca3 100644 --- a/params/ElementParamWidget.cpp +++ b/params/ElementParamWidget.cpp @@ -10,6 +10,7 @@ #include "../mapview/model/IHasEditableMeta.h" #include "MetaEditWidget.h" +#include "EditFields.h" #include @@ -19,6 +20,7 @@ #include #include #include +#include QComboBox* getMaterials() { using namespace Floorplan; @@ -96,7 +98,7 @@ void ElementParamWidget::refresh() { while ( QWidget* w = this->findChild() ) {delete w;} delete this->layout(); - this->lay = new QGridLayout(); + this->lay = new QGridLayout(this); this->setLayout(lay); int r = 0; @@ -107,7 +109,7 @@ void ElementParamWidget::refresh() { IHasMaterial* elem = dynamic_cast(el); if (elem) { material.cmb = getMaterials(); - material.lbl = new QLabel("material"); + material.lbl = new QLabel("material", this); lay->addWidget(material.lbl,r,0); lay->addWidget(material.cmb,r,1); connect(material.cmb , SIGNAL(currentIndexChanged(int)), this, SLOT(onMaterialChange())); @@ -121,7 +123,7 @@ void ElementParamWidget::refresh() { IHasObstacleType* elem = dynamic_cast(el); if (elem) { obstacleType.cmb = getObstacleTypes(); - obstacleType.lbl = new QLabel("type"); + obstacleType.lbl = new QLabel("type", this); lay->addWidget(obstacleType.lbl,r,0); lay->addWidget(obstacleType.cmb,r,1); connect(obstacleType.cmb, SIGNAL(currentIndexChanged(int)), this, SLOT(onObstacleTypeChange())); @@ -135,7 +137,7 @@ void ElementParamWidget::refresh() { MMFloorOutlinePolygon* elem = dynamic_cast(el); if (elem) { QComboBox* cmb = getOutlineMethods(); - QLabel* lbl = new QLabel("outline"); + QLabel* lbl = new QLabel("outline", this); lay->addWidget(lbl,r,0); lay->addWidget(cmb,r,1); cmb->setCurrentIndex((int)elem->getMethod()); @@ -150,176 +152,21 @@ void ElementParamWidget::refresh() { { // does the element have "parameters" ? IHasParams* elem = dynamic_cast(el); if (elem) { - - for(int i = 0; i < elem->getNumParams(); ++i) { - - const Param param = elem->getParamDesc(i); - const ParamValue value = elem->getParamValue(i); - - // skip Not-Available entries - if (param.type == ParamType::NOT_AVAILABLE) {continue;} - - lay->addWidget(new QLabel(param.name.c_str()),r,0); - - switch(param.type) { - - case ParamType::NOT_AVAILABLE: - break; - - case ParamType::ENUM: { - QComboBox* cmb = new QComboBox(); - int idx = 0; - for (const std::string& str : param.getEnumValues()) {cmb->addItem(str.c_str(), idx++);} - cmb->setCurrentIndex(value.toInt()); - connect(cmb, static_cast(&QComboBox::currentIndexChanged), [i, elem, cmb] (int idx) { - (void) idx; - elem->setParamValue(i, cmb->currentData().toInt() ); - }); - lay->addWidget(cmb,r,1); - break; - } - - - - case ParamType::BOOL: { - QCheckBox* chk = new QCheckBox( ); - chk->setChecked(value.toBool()); - if (param.readOnly) { - chk->setEnabled(false); - } else { - connect(chk, &QCheckBox::clicked, [i,elem] (const bool checked) { - elem->setParamValue(i, ParamValue(checked)); - }); - } - lay->addWidget(chk,r,1); - break; - } - - case ParamType::FLOAT: { - const std::string str = std::to_string(value.toFloat()); - if (param.readOnly) { - lay->addWidget(new QLabel(str.c_str()),r,1); - } else { - QLineEdit* le = new QLineEdit( str.c_str() ); - connect(le, &QLineEdit::textChanged, [i,elem] (const QString& str) { - const float val = str.toFloat(); - elem->setParamValue(i, ParamValue(val)); - }); - lay->addWidget(le,r,1); - } - break; - } - - case ParamType::DOUBLE: { - const std::string str = std::to_string(value.toDouble()); - if (param.readOnly) { - lay->addWidget(new QLabel(str.c_str()),r,1); - } else { - QLineEdit* le = new QLineEdit( str.c_str() ); - connect(le, &QLineEdit::textChanged, [i,elem] (const QString& str) { - const double val = str.toDouble(); - elem->setParamValue(i, ParamValue(val)); - }); - lay->addWidget(le,r,1); - } - break; - } - - case ParamType::INT: { - const std::string str = std::to_string(value.toInt()); - QLineEdit* le = new QLineEdit( str.c_str() ); - connect(le, &QLineEdit::textChanged, [i,elem] (const QString& str) { - const int val = str.toInt(); - elem->setParamValue(i, ParamValue(val)); - }); - lay->addWidget(le,r,1); - break; - } - - case ParamType::STRING: { - const std::string str = value.toString(); - QLineEdit* le = new QLineEdit( str.c_str() ); - connect(le, &QLineEdit::textChanged, [i,elem] (const QString& str) { - elem->setParamValue(i, ParamValue(str.toStdString())); - }); - lay->addWidget(le,r,1); - break; - } - - case ParamType::FILE: { - const std::string str = value.toString(); - QLabel* lblFile = new QLabel(str.c_str()); - QPushButton* btn = new QPushButton("<"); - btn->setMaximumSize(32,32); - connect(btn, &QPushButton::clicked, [i,elem,lblFile] (const bool checked) { - (void) checked; - QString res = QFileDialog::getOpenFileName(); - elem->setParamValue(i, ParamValue(res.toStdString())); - lblFile->setText(res); - }); - lay->addWidget(lblFile,r,1); - lay->addWidget(btn,r,2); - break; - } - - case ParamType::POINT2: { - const Point2 p2 = value.toPoint2(); - QWidget* subWidget = new QWidget(); - QGridLayout* laySub = new QGridLayout(subWidget); laySub->setMargin(0); - QLineEdit* txtX = new QLineEdit(QString::number(p2.x)); - QLineEdit* txtY = new QLineEdit(QString::number(p2.y)); - laySub->addWidget(txtX,0,0); - laySub->addWidget(txtY,0,1); - lay->addWidget(subWidget,r,1); - auto onChange = [i,elem,txtX,txtY] (const QString& str) { - (void) str; - elem->setParamValue(i, ParamValue( Point2(txtX->text().toFloat(), txtY->text().toFloat()) )); - }; - connect(txtX, &QLineEdit::textChanged, onChange); - connect(txtY, &QLineEdit::textChanged, onChange); - break; - } - - case ParamType::POINT3: { - const Point3 p3 = value.toPoint3(); - QWidget* subWidget = new QWidget(); - QGridLayout* laySub = new QGridLayout(subWidget); laySub->setMargin(0); - QLineEdit* txtX = new QLineEdit(QString::number(p3.x)); - QLineEdit* txtY = new QLineEdit(QString::number(p3.y)); - QLineEdit* txtZ = new QLineEdit(QString::number(p3.z)); - laySub->addWidget(txtX,0,0); - laySub->addWidget(txtY,0,1); - laySub->addWidget(txtZ,0,2); - lay->addWidget(subWidget,r,1); - auto onChange = [i,elem,txtX,txtY,txtZ] (const QString& str) { - (void) str; - elem->setParamValue(i, ParamValue( Point3(txtX->text().toFloat(), txtY->text().toFloat(), txtZ->text().toFloat()) )); - }; - connect(txtX, &QLineEdit::textChanged, onChange); - connect(txtY, &QLineEdit::textChanged, onChange); - connect(txtZ, &QLineEdit::textChanged, onChange); - break; - } - - } - - ++r; - - } + EditFields::get(this, r, lay, elem); } { // does the element have editable metadata? IHasEditableMeta* elem = dynamic_cast(el); if (elem) { - QPushButton* btn = new QPushButton("edit"); + QPushButton* btn = new QPushButton("edit", this); connect(btn, &QPushButton::clicked, [elem] (const bool checked) { (void) checked; if (!elem->getMeta()) {elem->setMeta(new Floorplan::Meta());} // ensure meta-object is present MetaEditWidget* mew = new MetaEditWidget(elem->getMeta()); // edit mew->show(); }); - lay->addWidget(new QLabel("Meta"),r,0); + lay->addWidget(new QLabel("Meta", this),r,0); lay->addWidget(btn,r,1); } } diff --git a/params/LayerParamWidget.cpp b/params/LayerParamWidget.cpp index d255901..d4c15d6 100644 --- a/params/LayerParamWidget.cpp +++ b/params/LayerParamWidget.cpp @@ -68,7 +68,7 @@ void LayerParamWidget::setElement(MapLayer* l) { delete this->layout(); this->lay = new QGridLayout(); this->setLayout(lay); -// int r = 0; + int r = 0; // { @@ -97,7 +97,7 @@ void LayerParamWidget::setElement(MapLayer* l) { { IHasParams* elem = dynamic_cast(l); if (elem) { - EditFields::get(lay, elem); + EditFields::get(this, r, lay, elem); } } diff --git a/params/LayerParamWidget.h b/params/LayerParamWidget.h index 53dc266..684edf5 100644 --- a/params/LayerParamWidget.h +++ b/params/LayerParamWidget.h @@ -11,6 +11,7 @@ class QLabel; class QLineEdit; class QComboBox; class QGridLayout; +class IHasParams; class LayerParamWidget : public QWidget { @@ -48,6 +49,7 @@ private: QLabel* lbl; } height; + void buildFields(QGridLayout* lay, IHasParams* elem); signals: diff --git a/params/MetaEditModel.cpp b/params/MetaEditModel.cpp index 20d568b..884bafe 100644 --- a/params/MetaEditModel.cpp +++ b/params/MetaEditModel.cpp @@ -15,11 +15,13 @@ void MetaEditModel::setSource(Floorplan::Meta* meta) { endResetModel(); } -int MetaEditModel::rowCount(const QModelIndex &parent) const { +int MetaEditModel::rowCount(const QModelIndex& parent) const { + (void) parent; return (meta) ? (meta->size()) : (0); } -int MetaEditModel::columnCount(const QModelIndex &parent) const { +int MetaEditModel::columnCount(const QModelIndex& parent) const { + (void) parent; return 2; }