added more cpp files for faster compile speeds
removed many obsolte elements many improvements and fixes
This commit is contained in:
@@ -60,7 +60,15 @@ SOURCES += \
|
|||||||
mapview/2D/MV2DElementFloorObstacleDoor.cpp \
|
mapview/2D/MV2DElementFloorObstacleDoor.cpp \
|
||||||
mapview/2D/MV2DElementFloorObstacleObject.cpp \
|
mapview/2D/MV2DElementFloorObstacleObject.cpp \
|
||||||
mapview/3D/grid/GridRenderer.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 \
|
HEADERS += MainWindow.h \
|
||||||
@@ -156,6 +164,7 @@ HEADERS += MainWindow.h \
|
|||||||
mapview/model/MMFloorGroundTruthPoint.h \
|
mapview/model/MMFloorGroundTruthPoint.h \
|
||||||
mapview/2D/MV2DElementGroundTruthPoint.h \
|
mapview/2D/MV2DElementGroundTruthPoint.h \
|
||||||
misc/LINTView.h \
|
misc/LINTView.h \
|
||||||
|
mapview/2D/HasMoveableNodes.h \
|
||||||
mapview/2D/tools/ToolNewElement.h \
|
mapview/2D/tools/ToolNewElement.h \
|
||||||
mapview/2D/tools/ToolNewDoor.h \
|
mapview/2D/tools/ToolNewDoor.h \
|
||||||
mapview/2D/tools/ToolNewWall.h \
|
mapview/2D/tools/ToolNewWall.h \
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ MainController::MainController() {
|
|||||||
//mapModel->load("/apps/paper/diss/data/maps/walkmodel_stairs3.xml");
|
//mapModel->load("/apps/paper/diss/data/maps/walkmodel_stairs3.xml");
|
||||||
|
|
||||||
//mapModel->load("/apps/paper/maps/museum/map43_svg.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");
|
//mapModel->load("/mnt/sdcard/SHL41_nm.xml");
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <Indoor/geo/Point2.h>
|
#include <Indoor/geo/Point2.h>
|
||||||
#include "../2D/MapView2D.h"
|
#include "../2D/MapView2D.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
/** the selectable/moveable node */
|
/** the selectable/moveable node */
|
||||||
struct MoveableNode {
|
struct MoveableNode {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#include <Indoor/geo/Line2.h>
|
#include <Indoor/geo/Line2.h>
|
||||||
|
|
||||||
#include "ClickDist.h"
|
#include "ClickDist.h"
|
||||||
|
#include "HasMoveableNodes.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* represents one drawable, selectable, editable, ...
|
* represents one drawable, selectable, editable, ...
|
||||||
@@ -36,7 +37,20 @@ public:
|
|||||||
/** repaint me */
|
/** repaint me */
|
||||||
virtual void paint(Painter& p) = 0;
|
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<HasMoveableNodes*>(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 */
|
/** got focus */
|
||||||
void focus() {
|
void focus() {
|
||||||
|
|||||||
@@ -47,28 +47,23 @@ public:
|
|||||||
static const QPixmap& pixmapFocused = UIHelper::getPixmapColored("wifi", CFG::FOCUS_COLOR, 16);
|
static const QPixmap& pixmapFocused = UIHelper::getPixmapColored("wifi", CFG::FOCUS_COLOR, 16);
|
||||||
static const QPixmap& pixmapSel = UIHelper::getPixmapColored("wifi", CFG::SEL_COLOR, 16);
|
static const QPixmap& pixmapSel = UIHelper::getPixmapColored("wifi", CFG::SEL_COLOR, 16);
|
||||||
|
|
||||||
|
|
||||||
if (selectedUserIdx == 0) {
|
if (selectedUserIdx == 0) {
|
||||||
//p.setPenBrush(Qt::black, CFG::SEL_COLOR);
|
|
||||||
//p.drawCircle(ap->pos.xy());
|
|
||||||
p.drawPixmap(ap->pos.xy(), pixmapSel);
|
p.drawPixmap(ap->pos.xy(), pixmapSel);
|
||||||
} else if (hasFocus()) {
|
} else if (hasFocus()) {
|
||||||
//p.setPenBrush(Qt::black, Qt::NoBrush);
|
|
||||||
//p.drawCircle(ap->pos.xy());
|
|
||||||
p.drawPixmap(ap->pos.xy(), pixmapFocused);
|
p.drawPixmap(ap->pos.xy(), pixmapFocused);
|
||||||
} else {
|
} else {
|
||||||
//p.setPenBrush(Qt::gray, Qt::NoBrush);
|
|
||||||
//p.drawCircle(ap->pos.xy());
|
|
||||||
p.drawPixmap(ap->pos.xy(), pixmapUnfocused);
|
p.drawPixmap(ap->pos.xy(), pixmapUnfocused);
|
||||||
}
|
}
|
||||||
|
|
||||||
// label
|
// label
|
||||||
p.setPenBrush(Qt::black, Qt::NoBrush);
|
//p.setPenBrush(Qt::black, Qt::NoBrush);
|
||||||
p.drawDot(ap->pos.xy());
|
//p.drawDot(ap->pos.xy());
|
||||||
if (p.getScaler().getScale() >= 25) {
|
if (p.getScaler().getScale() >= 25) {
|
||||||
|
p.setPenBrush(Qt::black, Qt::NoBrush);
|
||||||
const std::string str = ap->name + " (" + ap->mac + ")";
|
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());
|
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;
|
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());
|
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);
|
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 onFocus() override {
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,27 +41,22 @@ public:
|
|||||||
static const QPixmap& pixmapSel = UIHelper::getPixmapColored("beacon", CFG::SEL_COLOR, 16);
|
static const QPixmap& pixmapSel = UIHelper::getPixmapColored("beacon", CFG::SEL_COLOR, 16);
|
||||||
|
|
||||||
if (selectedUserIdx == 0) {
|
if (selectedUserIdx == 0) {
|
||||||
//p.setPenBrush(Qt::black, CFG::SEL_COLOR);
|
|
||||||
//p.drawCircle(b->pos.xy());
|
|
||||||
p.drawPixmap(b->pos.xy(), pixmapSel);
|
p.drawPixmap(b->pos.xy(), pixmapSel);
|
||||||
|
|
||||||
} else if (hasFocus()) {
|
} else if (hasFocus()) {
|
||||||
//p.setPenBrush(Qt::black, Qt::NoBrush);
|
|
||||||
//p.drawCircle(b->pos.xy());
|
|
||||||
p.drawPixmap(b->pos.xy(), pixmapFocused);
|
p.drawPixmap(b->pos.xy(), pixmapFocused);
|
||||||
} else {
|
} else {
|
||||||
//p.setPenBrush(Qt::gray, Qt::NoBrush);
|
|
||||||
//p.drawCircle(b->pos.xy());
|
|
||||||
p.drawPixmap(b->pos.xy(), pixmapUnfocused);
|
p.drawPixmap(b->pos.xy(), pixmapUnfocused);
|
||||||
}
|
}
|
||||||
|
|
||||||
// label
|
// label
|
||||||
p.setPenBrush(Qt::black, Qt::NoBrush);
|
//p.setPenBrush(Qt::black, Qt::NoBrush);
|
||||||
p.drawDot(b->pos.xy());
|
//p.drawDot(b->pos.xy());
|
||||||
if (p.getScaler().getScale() >= 25) {
|
if (p.getScaler().getScale() >= 25) {
|
||||||
|
p.setPenBrush(Qt::black, Qt::NoBrush);
|
||||||
const std::string str = b->name + " (" + b->mac + ")";
|
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());
|
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;
|
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());
|
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
|
#endif // MV2DELEMENTBEACON_H
|
||||||
|
|||||||
90
mapview/2D/MV2DElementElevator.cpp
Normal file
90
mapview/2D/MV2DElementElevator.cpp
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
#include "MV2DElementElevator.h"
|
||||||
|
|
||||||
|
#include "MV2DElement.h"
|
||||||
|
#include "HasMoveableNodes.h"
|
||||||
|
|
||||||
|
#include "MapViewElementHelper.h"
|
||||||
|
#include <Indoor/floorplan/v2/Floorplan.h>
|
||||||
|
|
||||||
|
#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<int> 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<Point2> 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<MoveableNode> 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() {
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -4,11 +4,8 @@
|
|||||||
#include "MV2DElement.h"
|
#include "MV2DElement.h"
|
||||||
#include "HasMoveableNodes.h"
|
#include "HasMoveableNodes.h"
|
||||||
|
|
||||||
#include "MapViewElementHelper.h"
|
|
||||||
#include <Indoor/floorplan/v2/Floorplan.h>
|
#include <Indoor/floorplan/v2/Floorplan.h>
|
||||||
|
|
||||||
#include "../../UIHelper.h"
|
|
||||||
|
|
||||||
class MV2DElementElevator : public MV2DElement, public HasMoveableNodes {
|
class MV2DElementElevator : public MV2DElement, public HasMoveableNodes {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -20,117 +17,26 @@ private:
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
/** ctor with the AP to render/edit */
|
/** 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 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** get the element's minimal distance (nearest whatsoever) to the given point */
|
/** 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;
|
||||||
// std::vector<Point2> 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** repaint me */
|
/** repaint me */
|
||||||
void paint(Painter& p) override {
|
void paint(Painter& p) override;
|
||||||
|
|
||||||
// area
|
virtual std::vector<MoveableNode> getMoveableNodes() const override;
|
||||||
const Floorplan::Polygon2 poly = elevator->getPoints();
|
|
||||||
p.setPenBrush(Qt::gray, Qt::lightGray);
|
|
||||||
p.drawPolygon(poly.points);
|
|
||||||
|
|
||||||
// outline
|
virtual void onNodeMove(MapView2D* v, const int userIdx, const Point2 newPos) override;
|
||||||
QPen pen; pen.setWidth(2); pen.setColor(QColor(0,0,0));
|
|
||||||
|
|
||||||
if (!elevatorEndConnected(map, floor, elevator)) {pen.setColor(QColor(255,0,0));}
|
void onNodeMoved(MapView2D* v, const int userIdx, const Point2 newPos) override;
|
||||||
if (elevator->height_m == 0) {pen.setColor(QColor(255,0,0));}
|
|
||||||
|
|
||||||
p.setPenBrush(pen, Qt::NoBrush);
|
virtual void onFocus() override;
|
||||||
//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]);
|
|
||||||
|
|
||||||
if (selectedUserIdx == 0) {
|
virtual void onUnfocus() override;
|
||||||
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<int> 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<MoveableNode> 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 {
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif // MV2DELEMENTELEVATOR_H
|
#endif // MV2DELEMENTELEVATOR_H
|
||||||
|
|||||||
@@ -49,24 +49,18 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
if (selectedUserIdx == 0) {
|
if (selectedUserIdx == 0) {
|
||||||
//p.setPenBrush(Qt::black, CFG::SEL_COLOR);
|
|
||||||
//p.drawCircle(ap->pos.xy());
|
|
||||||
p.drawPixmap(fpl->posOnFloor, pixmapSel);
|
p.drawPixmap(fpl->posOnFloor, pixmapSel);
|
||||||
} else if (hasFocus()) {
|
} else if (hasFocus()) {
|
||||||
//p.setPenBrush(Qt::black, Qt::NoBrush);
|
|
||||||
//p.drawCircle(ap->pos.xy());
|
|
||||||
p.drawPixmap(fpl->posOnFloor, pixmapFocused);
|
p.drawPixmap(fpl->posOnFloor, pixmapFocused);
|
||||||
} else {
|
} else {
|
||||||
//p.setPenBrush(Qt::gray, Qt::NoBrush);
|
|
||||||
//p.drawCircle(ap->pos.xy());
|
|
||||||
p.drawPixmap(fpl->posOnFloor, pixmapUnfocused);
|
p.drawPixmap(fpl->posOnFloor, pixmapUnfocused);
|
||||||
}
|
}
|
||||||
|
|
||||||
// label
|
// label
|
||||||
p.setPenBrush(Qt::black, Qt::NoBrush);
|
//p.setPenBrush(Qt::black, Qt::NoBrush);
|
||||||
p.drawDot(fpl->posOnFloor);
|
//p.drawDot(fpl->posOnFloor);
|
||||||
|
if (p.getScaler().getScale() >= 12) {
|
||||||
if (p.getScaler().getScale() >= 10) {
|
p.setPenBrush(Qt::black, Qt::NoBrush);
|
||||||
const std::string str = fpl->name;
|
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());
|
p.p->drawText(p.getScaler().xms(fpl->posOnFloor.x) + 10, p.getScaler().yms(fpl->posOnFloor.y) + 5, str.c_str());
|
||||||
}
|
}
|
||||||
|
|||||||
81
mapview/2D/MV2DElementFloorObstacleCircle.cpp
Normal file
81
mapview/2D/MV2DElementFloorObstacleCircle.cpp
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
#include "MV2DElementFloorObstacleCircle.h"
|
||||||
|
|
||||||
|
#include "MV2DElement.h"
|
||||||
|
#include "MapViewElementHelper.h"
|
||||||
|
#include <Indoor/floorplan/v2/Floorplan.h>
|
||||||
|
|
||||||
|
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<MoveableNode> 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<Point2> MV2DElementFloorObstacleCircle::getSelPoints() const {
|
||||||
|
// return {c->center, (c->center + Point2(c->radius,0))};
|
||||||
|
//}
|
||||||
|
|
||||||
|
void MV2DElementFloorObstacleCircle::onFocus() {
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MV2DElementFloorObstacleCircle::onUnfocus() {
|
||||||
|
selPoint = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
#ifndef MV2DELEMENTFLOOROBSTACLECIRCLE_H
|
#ifndef MV2DELEMENTFLOOROBSTACLECIRCLE_H
|
||||||
#define MV2DELEMENTFLOOROBSTACLECIRCLE_H
|
#define MV2DELEMENTFLOOROBSTACLECIRCLE_H
|
||||||
|
|
||||||
|
|
||||||
#include "MV2DElement.h"
|
#include "MV2DElement.h"
|
||||||
#include "MapViewElementHelper.h"
|
#include "MapViewElementHelper.h"
|
||||||
|
|
||||||
#include <Indoor/floorplan/v2/Floorplan.h>
|
#include <Indoor/floorplan/v2/Floorplan.h>
|
||||||
|
|
||||||
class MV2DElementFloorObstacleCircle : public MV2DElement {
|
class MV2DElementFloorObstacleCircle : public MV2DElement, public HasMoveableNodes {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@@ -16,95 +16,28 @@ private:
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
/** ctor */
|
/** ctor */
|
||||||
MV2DElementFloorObstacleCircle(Floorplan::FloorObstacleCircle* c) : c(c) {;}
|
MV2DElementFloorObstacleCircle(Floorplan::FloorObstacleCircle* c);
|
||||||
|
|
||||||
/** get the element's 3D bounding box */
|
/** get the element's 3D bounding box */
|
||||||
BBox2 getBoundingBox() const override {
|
BBox2 getBoundingBox() const override;
|
||||||
BBox2 bbox;
|
|
||||||
bbox.add(c->center);
|
|
||||||
bbox.grow(Point2(c->radius, c->radius));
|
|
||||||
return bbox;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** get the element's minimal distance (nearest whatsoever) to the given point */
|
/** 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;
|
||||||
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]));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** repaint me */
|
/** repaint me */
|
||||||
void paint(Painter& p) override {
|
void paint(Painter& p) override;
|
||||||
|
|
||||||
QPen pen;// = MapElementHelper::getPen(c->material, c->type, hasFocus());
|
//std::vector<Point2> getSelPoints() const;
|
||||||
|
|
||||||
p.setPenBrush(pen, Qt::NoBrush);
|
virtual std::vector<MoveableNode> getMoveableNodes() const override;
|
||||||
p.drawCircle(c->center, c->radius);
|
|
||||||
|
|
||||||
//QBrush brush = MapElementHelper::getBru(c->material, c->type, _focused);
|
virtual void onNodeMove(MapView2D* v, const int userIdx, const Point2 newPos) override;
|
||||||
|
|
||||||
// selected endpoints?
|
void onNodeMoved(MapView2D* v, const int userIdx, const Point2 newPos) override;
|
||||||
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
|
virtual void onFocus() override;
|
||||||
if (hasFocus()) {
|
|
||||||
p.setPenBrush(Qt::black, Qt::NoBrush);
|
|
||||||
p.drawCircle(getSelPoints()[0]);
|
|
||||||
p.drawCircle(getSelPoints()[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
virtual void onUnfocus() override;
|
||||||
|
|
||||||
std::vector<Point2> 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -28,12 +28,13 @@ void MV2DElementFloorObstacleDoor::paint(Painter& p) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// selected endpoints?
|
// DEPRECATED
|
||||||
if (hasFocus()) {
|
// // selected endpoints?
|
||||||
p.setPenBrush(Qt::NoPen, CFG::SEL_COLOR);
|
// if (hasFocus()) {
|
||||||
if (selectedUserIdx == 0) {p.drawCircle(fo->from);}
|
// p.setPenBrush(Qt::NoPen, CFG::SEL_COLOR);
|
||||||
if (selectedUserIdx == 1) {p.drawCircle(fo->to);}
|
// if (selectedUserIdx == 0) {p.drawCircle(fo->from);}
|
||||||
}
|
// if (selectedUserIdx == 1) {p.drawCircle(fo->to);}
|
||||||
|
// }
|
||||||
|
|
||||||
QPen pen;
|
QPen pen;
|
||||||
pen.setColor(QColor(0.5,0.5,0.5));
|
pen.setColor(QColor(0.5,0.5,0.5));
|
||||||
@@ -80,13 +81,13 @@ void MV2DElementFloorObstacleDoor::paint(Painter& p) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DEPRECATED
|
||||||
// available endpoints
|
// // available endpoints
|
||||||
if (hasFocus()) {
|
// if (hasFocus()) {
|
||||||
p.setPenBrush(Qt::black, Qt::NoBrush);
|
// p.setPenBrush(Qt::black, Qt::NoBrush);
|
||||||
p.drawCircle(fo->from);
|
// p.drawCircle(fo->from);
|
||||||
p.drawCircle(fo->to);
|
// p.drawCircle(fo->to);
|
||||||
}
|
// }
|
||||||
|
|
||||||
// obstacle length
|
// obstacle length
|
||||||
if (hasFocus()) {
|
if (hasFocus()) {
|
||||||
@@ -129,10 +130,13 @@ std::vector<MoveableNode> MV2DElementFloorObstacleDoor::getMoveableNodes() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MV2DElementFloorObstacleDoor::onNodeMoved(MapView2D* v, const int userIdx, const Point2 newPos) {
|
void MV2DElementFloorObstacleDoor::onNodeMoved(MapView2D* v, const int userIdx, const Point2 newPos) {
|
||||||
|
(void) userIdx;
|
||||||
|
(void) newPos;
|
||||||
emit v->onElementChange(this);
|
emit v->onElementChange(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MV2DElementFloorObstacleDoor::onNodeMove(MapView2D* v, const int userIdx, const Point2 newPos) {
|
void MV2DElementFloorObstacleDoor::onNodeMove(MapView2D* v, const int userIdx, const Point2 newPos) {
|
||||||
|
(void) v;
|
||||||
switch (userIdx) {
|
switch (userIdx) {
|
||||||
case 0: fo->from = newPos; break;
|
case 0: fo->from = newPos; break;
|
||||||
case 1: fo->to = newPos; break;
|
case 1: fo->to = newPos; break;
|
||||||
|
|||||||
92
mapview/2D/MV2DElementFloorObstacleLine.cpp
Normal file
92
mapview/2D/MV2DElementFloorObstacleLine.cpp
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
#include "MV2DElementFloorObstacleLine.h"
|
||||||
|
|
||||||
|
#include "MV2DElement.h"
|
||||||
|
#include "HasMoveableNodes.h"
|
||||||
|
|
||||||
|
#include "MapViewElementHelper.h"
|
||||||
|
#include <Indoor/floorplan/v2/Floorplan.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
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<MoveableNode> 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -4,9 +4,7 @@
|
|||||||
#include "MV2DElement.h"
|
#include "MV2DElement.h"
|
||||||
#include "HasMoveableNodes.h"
|
#include "HasMoveableNodes.h"
|
||||||
|
|
||||||
#include "MapViewElementHelper.h"
|
|
||||||
#include <Indoor/floorplan/v2/Floorplan.h>
|
#include <Indoor/floorplan/v2/Floorplan.h>
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
class MV2DElementFloorObstacleLine : public MV2DElement, public HasMoveableNodes {
|
class MV2DElementFloorObstacleLine : public MV2DElement, public HasMoveableNodes {
|
||||||
|
|
||||||
@@ -17,90 +15,26 @@ private:
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
/** ctor */
|
/** ctor */
|
||||||
MV2DElementFloorObstacleLine(Floorplan::FloorObstacleLine* fo) : fo(fo) {;}
|
MV2DElementFloorObstacleLine(Floorplan::FloorObstacleLine* fo);
|
||||||
|
|
||||||
/** get the element's 3D bounding box */
|
/** get the element's 3D bounding box */
|
||||||
BBox2 getBoundingBox() const override {
|
BBox2 getBoundingBox() const override;
|
||||||
BBox2 bbox;
|
|
||||||
bbox.add(fo->from);
|
|
||||||
bbox.add(fo->to);
|
|
||||||
return bbox;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** get the element's minimal distance (nearest whatsoever) to the given point */
|
/** 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;
|
||||||
return MapElementHelper::getLineDistanceXY(fo->from, fo->to, p);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** repaint me */
|
/** repaint me */
|
||||||
void paint(Painter& p) override {
|
void paint(Painter& p) override;
|
||||||
|
|
||||||
// selected endpoints?
|
void onFocus() override;
|
||||||
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
|
void onUnfocus() override;
|
||||||
const float thickness_px = p.s.ms(fo->thickness_m);
|
|
||||||
|
|
||||||
// remember the old pen
|
virtual std::vector<MoveableNode> getMoveableNodes() const override;
|
||||||
QPen pen = p.getPen();
|
|
||||||
|
|
||||||
// see notes within MapElementHelper!
|
void onNodeMove(MapView2D* v, const int userIdx, const Point2 newPos) override;
|
||||||
// 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 pen
|
void onNodeMoved(MapView2D* v, const int userIdx, const Point2 newPos);
|
||||||
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<MoveableNode> 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
134
mapview/2D/MV2DElementFloorOutlinePolygon.cpp
Normal file
134
mapview/2D/MV2DElementFloorOutlinePolygon.cpp
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
#include "MV2DElementFloorOutlinePolygon.h"
|
||||||
|
|
||||||
|
#include "MV2DElement.h"
|
||||||
|
#include "HasMoveableNodes.h"
|
||||||
|
#include "MapViewElementHelper.h"
|
||||||
|
|
||||||
|
#include <Indoor/floorplan/v2/Floorplan.h>
|
||||||
|
|
||||||
|
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<MoveableNode> MV2DElementFloorOutlinePolygon::getMoveableNodes() const {
|
||||||
|
std::vector<MoveableNode> 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;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
#include "MV2DElement.h"
|
#include "MV2DElement.h"
|
||||||
#include "HasMoveableNodes.h"
|
#include "HasMoveableNodes.h"
|
||||||
#include "MapViewElementHelper.h"
|
|
||||||
|
|
||||||
#include <Indoor/floorplan/v2/Floorplan.h>
|
#include <Indoor/floorplan/v2/Floorplan.h>
|
||||||
|
|
||||||
@@ -16,167 +15,29 @@ private:
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
/** ctor */
|
/** ctor */
|
||||||
MV2DElementFloorOutlinePolygon(Floorplan::FloorOutlinePolygon& fo) : fo(fo) {;}
|
MV2DElementFloorOutlinePolygon(Floorplan::FloorOutlinePolygon& fo);
|
||||||
|
|
||||||
/** get the element's 3D bounding box */
|
/** get the element's 3D bounding box */
|
||||||
BBox2 getBoundingBox() const override {
|
BBox2 getBoundingBox() const override;
|
||||||
BBox2 bbox;
|
|
||||||
for (const Point2 p : fo.poly.points) { bbox.add(p); }
|
|
||||||
return bbox;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** get the element's minimal distance (nearest whatsoever) to the given point */
|
/** 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;
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void onFocus() override {
|
virtual void onFocus() override;
|
||||||
|
|
||||||
}
|
virtual void onUnfocus() override;
|
||||||
|
|
||||||
virtual void onUnfocus() override {
|
void paint(Painter& p) 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/** get a list of all nodes that are selectable / moveable */
|
/** get a list of all nodes that are selectable / moveable */
|
||||||
virtual std::vector<MoveableNode> getMoveableNodes() const override {
|
virtual std::vector<MoveableNode> getMoveableNodes() const override;
|
||||||
std::vector<MoveableNode> nodes;
|
|
||||||
for (int i = 0; i < (int) fo.poly.points.size(); ++i) {
|
|
||||||
nodes.push_back(MoveableNode(i, fo.poly.points[i]));
|
|
||||||
}
|
|
||||||
return nodes;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** the given node was moved */
|
/** the given node was moved */
|
||||||
void onNodeMove(MapView2D* v, const int userIdx, const Point2 newPos) override {
|
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 onNodeMoved(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;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
virtual bool keyPressEvent(MapView2D* v, QKeyEvent *e) override;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -42,36 +42,29 @@ public:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const QPixmap& pixmapUnfocused = UIHelper::getPixmapColored("gtp", CFG::UNFOCUS_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& pixmapFocused = UIHelper::getPixmapColored("gtp", CFG::FOCUS_COLOR, 16);
|
||||||
static const QPixmap& pixmapSel = UIHelper::getPixmapColored("gtp", CFG::SEL_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) {
|
// label
|
||||||
// p.setPenBrush(Qt::black, CFG::SEL_COLOR);
|
//p.setPenBrush(Qt::black, Qt::NoBrush);
|
||||||
// p.drawCircle(gtp->pos);
|
//p.drawDot(gtp->pos.xy());
|
||||||
p.drawPixmap(gtp->pos.xy(), pixmapSel);
|
if (p.getScaler().getScale() >= 12) {
|
||||||
} else if (hasFocus()) {
|
p.setPenBrush(Qt::black, Qt::NoBrush);
|
||||||
// p.setPenBrush(Qt::black, Qt::NoBrush);
|
const std::string str = std::to_string(gtp->id);
|
||||||
// p.drawCircle(gtp->pos);
|
p.p->drawText(p.getScaler().xms(gtp->pos.x) + 10, p.getScaler().yms(gtp->pos.y) + 5, str.c_str());
|
||||||
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());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
virtual std::vector<MoveableNode> getMoveableNodes() const override {
|
virtual std::vector<MoveableNode> getMoveableNodes() const override {
|
||||||
return { MoveableNode(0, gtp->pos.xy()) };
|
return { MoveableNode(0, gtp->pos.xy()) };
|
||||||
}
|
}
|
||||||
@@ -87,30 +80,6 @@ public:
|
|||||||
emit v->onElementChange(this);
|
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 {
|
virtual void onFocus() override {
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,9 +62,10 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// label
|
// label
|
||||||
p.setPenBrush(Qt::black, Qt::NoBrush);
|
//p.setPenBrush(Qt::black, Qt::NoBrush);
|
||||||
p.drawDot(poi->pos);
|
//p.drawDot(poi->pos);
|
||||||
if (p.getScaler().getScale() >= 10) {
|
if (p.getScaler().getScale() >= 12) {
|
||||||
|
p.setPenBrush(Qt::black, Qt::NoBrush);
|
||||||
const std::string str = poi->name;
|
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());
|
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);
|
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 {
|
virtual void onFocus() override {
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,9 +59,10 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// label
|
// label
|
||||||
p.setPenBrush(Qt::black, Qt::NoBrush);
|
//p.setPenBrush(Qt::black, Qt::NoBrush);
|
||||||
//p.drawDot(ap->pos.xy());
|
//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);
|
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());
|
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);
|
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 onFocus() override {
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|||||||
251
mapview/2D/MV2DElementStair.cpp
Normal file
251
mapview/2D/MV2DElementStair.cpp
Normal file
@@ -0,0 +1,251 @@
|
|||||||
|
#include "MV2DElementStair.h"
|
||||||
|
|
||||||
|
#include "MV2DElement.h"
|
||||||
|
#include "HasMoveableNodes.h"
|
||||||
|
|
||||||
|
#include "MapViewElementHelper.h"
|
||||||
|
#include <Indoor/floorplan/v2/Floorplan.h>
|
||||||
|
|
||||||
|
/** 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<int> 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<Floorplan::StairFreeform*>(stair)) {
|
||||||
|
Floorplan::StairFreeform* stair = dynamic_cast<Floorplan::StairFreeform*>(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<Floorplan::StairFreeform*>(this->stair);
|
||||||
|
|
||||||
|
// draw all parts of the stair (all polygons)
|
||||||
|
p.setPenBrush(Qt::black, Qt::NoBrush);
|
||||||
|
|
||||||
|
std::vector<Floorplan::StairPart> parts = stair->getParts();
|
||||||
|
std::vector<Floorplan::Quad3> 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<Point3> 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<Floorplan::StairPart> 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<Floorplan::StairFreeform*>(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<MoveableNode> MV2DElementStair::getMoveableNodes() const {
|
||||||
|
|
||||||
|
std::vector<MoveableNode> nodes;
|
||||||
|
Floorplan::StairFreeform* stair = dynamic_cast<Floorplan::StairFreeform*>(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<Floorplan::StairFreeform*>(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);
|
||||||
|
}
|
||||||
|
|
||||||
@@ -4,21 +4,8 @@
|
|||||||
#include "MV2DElement.h"
|
#include "MV2DElement.h"
|
||||||
#include "HasMoveableNodes.h"
|
#include "HasMoveableNodes.h"
|
||||||
|
|
||||||
#include "MapViewElementHelper.h"
|
|
||||||
#include <Indoor/floorplan/v2/Floorplan.h>
|
#include <Indoor/floorplan/v2/Floorplan.h>
|
||||||
|
|
||||||
/** 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<int> 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 {
|
class MV2DElementStair : public MV2DElement, public HasMoveableNodes {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -27,296 +14,38 @@ private:
|
|||||||
Floorplan::IndoorMap* map;
|
Floorplan::IndoorMap* map;
|
||||||
Floorplan::Floor* floor;
|
Floorplan::Floor* floor;
|
||||||
Floorplan::Stair* stair;
|
Floorplan::Stair* stair;
|
||||||
//int selPart = -1;
|
|
||||||
//int selNode = -1;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/** ctor with the stair to render/edit */
|
/** 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 */
|
/** get the element's 3D bounding box */
|
||||||
BBox2 getBoundingBox() const override {
|
BBox2 getBoundingBox() const override;
|
||||||
BBox2 bbox;
|
|
||||||
if (dynamic_cast<Floorplan::StairFreeform*>(stair)) {
|
|
||||||
Floorplan::StairFreeform* stair = dynamic_cast<Floorplan::StairFreeform*>(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 */
|
/** 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) {
|
int getSelPart() const;
|
||||||
const ClickDist d1 = MapElementHelper::getLineDistanceXY(p1.start.xy(), p1.end.xy(), p);
|
int getSelNode() const;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** repaint me */
|
/** repaint me */
|
||||||
void paint(Painter& p) override {
|
void paint(Painter& p) override;
|
||||||
|
|
||||||
Floorplan::StairFreeform* stair = dynamic_cast<Floorplan::StairFreeform*>(this->stair);
|
virtual bool keyPressEvent(MapView2D* v, QKeyEvent *e) override;
|
||||||
|
|
||||||
// if (sel) {
|
virtual void onFocus() override;
|
||||||
// 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);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// draw all parts of the stair (all polygons)
|
virtual void onUnfocus() override;
|
||||||
p.setPenBrush(Qt::black, Qt::NoBrush);
|
|
||||||
|
|
||||||
std::vector<Floorplan::StairPart> parts = stair->getParts();
|
virtual std::vector<MoveableNode> getMoveableNodes() const override;
|
||||||
std::vector<Floorplan::Quad3> quads = Floorplan::getQuads(parts, floor);
|
|
||||||
|
|
||||||
// skip drawing?
|
void onNodeMove(MapView2D* v, const int userIdx, const Point2 newPos) override;
|
||||||
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) {
|
void onNodeMoved(MapView2D* v, const int userIdx, const Point2 newPos) override;
|
||||||
|
|
||||||
const Floorplan::StairPart& part = parts[i];
|
void onNodeSelect(MapView2D* v, const int userIdx) override;
|
||||||
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<Point3> 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<Floorplan::StairPart> 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<Floorplan::StairFreeform*>(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<Floorplan::StairFreeform*>(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<Floorplan::StairFreeform*>(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<MoveableNode> getMoveableNodes() const override {
|
|
||||||
|
|
||||||
std::vector<MoveableNode> nodes;
|
|
||||||
Floorplan::StairFreeform* stair = dynamic_cast<Floorplan::StairFreeform*>(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<Floorplan::StairFreeform*>(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);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ MapView2D::MapView2D(QWidget* parent) : QOpenGLWidget(parent) {
|
|||||||
|
|
||||||
// openGL params
|
// openGL params
|
||||||
QSurfaceFormat format;
|
QSurfaceFormat format;
|
||||||
format.setDepthBufferSize(24);
|
format.setDepthBufferSize(8); // 24
|
||||||
format.setStencilBufferSize(8);
|
format.setStencilBufferSize(8);
|
||||||
format.setSamples(1);
|
format.setSamples(1);
|
||||||
// format.setVersion(3, 2);
|
// format.setVersion(3, 2);
|
||||||
@@ -49,11 +49,19 @@ void MapView2D::paintGL() {
|
|||||||
// background tools
|
// background tools
|
||||||
tools.paintBefore(this, p);
|
tools.paintBefore(this, p);
|
||||||
|
|
||||||
// render all visible elements
|
|
||||||
qp.setRenderHint( QPainter::Antialiasing, true );
|
qp.setRenderHint( QPainter::Antialiasing, true );
|
||||||
|
|
||||||
|
// render all visible elements. 1st run
|
||||||
for (MapModelElement* el : getModel()->getVisibleElements()) {
|
for (MapModelElement* el : getModel()->getVisibleElements()) {
|
||||||
if (el->getMV2D()) {el->getMV2D()->paint(p);}
|
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 );
|
qp.setRenderHint( QPainter::Antialiasing, false );
|
||||||
|
|
||||||
// foreground tools
|
// foreground tools
|
||||||
@@ -68,7 +76,9 @@ void MapView2D::initializeGL() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapView2D::resizeGL() {
|
void MapView2D::resizeGL(int w, int h) {
|
||||||
|
(void) w;
|
||||||
|
(void) h;
|
||||||
// TODO ?
|
// TODO ?
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,10 +120,12 @@ bool MapView2D::event(QEvent* event) {
|
|||||||
|
|
||||||
bool MapView2D::gestureEvent(QGestureEvent* event) {
|
bool MapView2D::gestureEvent(QGestureEvent* event) {
|
||||||
if (QGesture *swipe = event->gesture(Qt::SwipeGesture)) {
|
if (QGesture *swipe = event->gesture(Qt::SwipeGesture)) {
|
||||||
|
(void) swipe;
|
||||||
//swipeTriggered(static_cast<QSwipeGesture *>(swipe));
|
//swipeTriggered(static_cast<QSwipeGesture *>(swipe));
|
||||||
} else if (QGesture *pan = event->gesture(Qt::PanGesture))
|
} else if (QGesture *pan = event->gesture(Qt::PanGesture)) {
|
||||||
panTriggered(static_cast<QPanGesture *>(pan));
|
panTriggered(static_cast<QPanGesture *>(pan));
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
if (QGesture *pinch = event->gesture(Qt::PinchGesture)) {
|
if (QGesture *pinch = event->gesture(Qt::PinchGesture)) {
|
||||||
pinchTriggered(static_cast<QPinchGesture *>(pinch));
|
pinchTriggered(static_cast<QPinchGesture *>(pinch));
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -47,9 +47,9 @@ public:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void paintGL();
|
virtual void paintGL() override;
|
||||||
void initializeGL();
|
virtual void initializeGL() override;
|
||||||
void resizeGL();
|
virtual void resizeGL(int w, int h) override;
|
||||||
|
|
||||||
|
|
||||||
Tools& getTools() {return tools;}
|
Tools& getTools() {return tools;}
|
||||||
|
|||||||
66
mapview/2D/MapViewElementHelper.cpp
Normal file
66
mapview/2D/MapViewElementHelper.cpp
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
#include "MapViewElementHelper.h"
|
||||||
|
|
||||||
|
#include <Indoor/geo/Point2.h>
|
||||||
|
#include <Indoor/geo/Point3.h>
|
||||||
|
#include <Indoor/geo/Line2.h>
|
||||||
|
|
||||||
|
#include <QColor>
|
||||||
|
#include <QPen>
|
||||||
|
#include <QBrush>
|
||||||
|
|
||||||
|
#include <Indoor/floorplan/v2/Floorplan.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
@@ -5,9 +5,7 @@
|
|||||||
#include <Indoor/geo/Point3.h>
|
#include <Indoor/geo/Point3.h>
|
||||||
#include <Indoor/geo/Line2.h>
|
#include <Indoor/geo/Line2.h>
|
||||||
|
|
||||||
#include <QColor>
|
|
||||||
#include <QPen>
|
#include <QPen>
|
||||||
#include <QBrush>
|
|
||||||
|
|
||||||
#include <Indoor/floorplan/v2/Floorplan.h>
|
#include <Indoor/floorplan/v2/Floorplan.h>
|
||||||
|
|
||||||
@@ -35,59 +33,9 @@ public:
|
|||||||
* move l into dst
|
* move l into dst
|
||||||
* and calculate the cut-point between l and (p1, p2)
|
* and calculate the cut-point between l and (p1, p2)
|
||||||
*/
|
*/
|
||||||
static ClickDist getLineDistanceXY(Point2 p1, Point2 p2, Point2 dst) {
|
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 QPen getPen(Floorplan::Material mat, Floorplan::ObstacleType type, bool focus, float thickness_px);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
158
mapview/2D/Painter.cpp
Normal file
158
mapview/2D/Painter.cpp
Normal file
@@ -0,0 +1,158 @@
|
|||||||
|
#include "Painter.h"
|
||||||
|
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QBitmap>
|
||||||
|
|
||||||
|
#include <Indoor/geo/Point2.h>
|
||||||
|
#include <Indoor/geo/Point3.h>
|
||||||
|
#include <Indoor/geo/BBox2.h>
|
||||||
|
|
||||||
|
#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<Point2>& points) {
|
||||||
|
std::vector<QPointF> 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<Point3>& points) {
|
||||||
|
std::vector<QPointF> 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;}
|
||||||
|
|
||||||
@@ -1,14 +1,21 @@
|
|||||||
#ifndef PAINTER_H
|
#ifndef PAINTER_H
|
||||||
#define PAINTER_H
|
#define PAINTER_H
|
||||||
|
|
||||||
#include <QPainter>
|
|
||||||
#include <QBitmap>
|
|
||||||
|
|
||||||
#include <Indoor/geo/Point2.h>
|
#include <Indoor/geo/Point2.h>
|
||||||
#include <Indoor/geo/Point3.h>
|
#include <Indoor/geo/Point3.h>
|
||||||
#include <Indoor/geo/BBox2.h>
|
#include <Indoor/geo/BBox2.h>
|
||||||
|
|
||||||
#include "Scaler.h"
|
//#include "Scaler.h"
|
||||||
|
|
||||||
|
class Scaler;
|
||||||
|
class QPainter;
|
||||||
|
class QPixmap;
|
||||||
|
class QImage;
|
||||||
|
class QPen;
|
||||||
|
class QColor;
|
||||||
|
class QBrush;
|
||||||
|
|
||||||
|
#include <qnamespace.h>
|
||||||
|
|
||||||
class Painter {
|
class Painter {
|
||||||
|
|
||||||
@@ -22,145 +29,66 @@ public:
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
/** ctor */
|
/** ctor */
|
||||||
Painter(Scaler& s, QPainter* p, int w, int h) : s(s), p(p), w(w), h(h) {
|
Painter(Scaler& s, QPainter* p, int w, int h);
|
||||||
p->setPen(Qt::black);
|
|
||||||
p->setBrush(Qt::NoBrush);
|
|
||||||
}
|
|
||||||
|
|
||||||
int width() {return w;}
|
int width();
|
||||||
|
|
||||||
int height() {return h;}
|
int height();
|
||||||
|
|
||||||
/** is the given point visible on screen? */
|
/** is the given point visible on screen? */
|
||||||
bool isVisible(const Point2 p) {
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** is the given volume visible on screen? */
|
/** is the given volume visible on screen? */
|
||||||
bool isVisible(const BBox2 bb) {
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
void drawLine(const Point2 p1, const Point2 p2) {
|
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);
|
||||||
}
|
void drawLine(const float x1, const float y1, const float x2, const float y2);
|
||||||
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));
|
|
||||||
}
|
|
||||||
|
|
||||||
float radToDeg(const float rad) const {
|
float radToDeg(const float rad) const;
|
||||||
return rad * 180 / M_PI;
|
|
||||||
}
|
|
||||||
|
|
||||||
void drawArc(const Point2 center, const float radius, const float startAngleRad, const float spanAngleRad) {
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** draw a dot at the given map coordinates */
|
/** draw a dot at the given map coordinates */
|
||||||
void drawDot(const Point2 center) {
|
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 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<Point2>& points);
|
||||||
|
void drawPolygon(const std::vector<Point3>& 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 <typename Pen, typename Brush> void setPenBrush(const Pen& pen, const Brush& brush) {
|
||||||
|
setPen(pen);
|
||||||
|
setBrush(brush);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawCircle(const Point2 center, const float size_m) {
|
const Scaler& getScaler();
|
||||||
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<Point2>& points) {
|
|
||||||
std::vector<QPointF> 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<Point3>& points) {
|
|
||||||
std::vector<QPointF> 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 <typename Pen, typename Brush> void setPenBrush(const Pen& pen, const Brush& brush) {setPen(pen); setBrush(brush);}
|
|
||||||
|
|
||||||
const Scaler& getScaler() {return s;}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|||||||
@@ -236,10 +236,12 @@ bool MapView3D::event(QEvent* event) {
|
|||||||
|
|
||||||
bool MapView3D::gestureEvent(QGestureEvent* event) {
|
bool MapView3D::gestureEvent(QGestureEvent* event) {
|
||||||
if (QGesture *swipe = event->gesture(Qt::SwipeGesture)) {
|
if (QGesture *swipe = event->gesture(Qt::SwipeGesture)) {
|
||||||
|
(void) swipe;
|
||||||
//swipeTriggered(static_cast<QSwipeGesture *>(swipe));
|
//swipeTriggered(static_cast<QSwipeGesture *>(swipe));
|
||||||
} else if (QGesture *pan = event->gesture(Qt::PanGesture))
|
} else if (QGesture *pan = event->gesture(Qt::PanGesture)) {
|
||||||
panTriggered(static_cast<QPanGesture *>(pan));
|
panTriggered(static_cast<QPanGesture *>(pan));
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
if (QGesture *pinch = event->gesture(Qt::PinchGesture)) {
|
if (QGesture *pinch = event->gesture(Qt::PinchGesture)) {
|
||||||
pinchTriggered(static_cast<QPinchGesture *>(pinch));
|
pinchTriggered(static_cast<QPinchGesture *>(pinch));
|
||||||
return true;
|
return true;
|
||||||
@@ -248,6 +250,7 @@ bool MapView3D::gestureEvent(QGestureEvent* event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MapView3D::pinchTriggered(QPinchGesture* gesture) {
|
void MapView3D::pinchTriggered(QPinchGesture* gesture) {
|
||||||
|
(void) gesture;
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
82
mapview/3D/floorplan/FloorplanRenderer.cpp
Normal file
82
mapview/3D/floorplan/FloorplanRenderer.cpp
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
#include "FloorplanRenderer.h"
|
||||||
|
|
||||||
|
#include <unordered_set>
|
||||||
|
#include <Indoor/navMesh/NavMesh.h>
|
||||||
|
#include <Indoor/navMesh/NavMeshTriangle.h>
|
||||||
|
#include <Indoor/navMesh/NavMeshType.h>
|
||||||
|
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QOpenGLWidget>
|
||||||
|
#include <QOpenGLFunctions>
|
||||||
|
|
||||||
|
#include "../misc/Renderable3D.h"
|
||||||
|
#include "../misc/Shader.h"
|
||||||
|
#include "../misc/TriangleData.h"
|
||||||
|
|
||||||
|
#include <Indoor/wifi/estimate/ray3/ModelFactory.h>
|
||||||
|
|
||||||
|
#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);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,91 +1,22 @@
|
|||||||
#ifndef FLOORPLANRENDERER_H
|
#ifndef FLOORPLANRENDERER_H
|
||||||
#define FLOORPLANRENDERER_H
|
#define FLOORPLANRENDERER_H
|
||||||
|
|
||||||
#include <unordered_set>
|
|
||||||
#include <Indoor/navMesh/NavMesh.h>
|
|
||||||
#include <Indoor/navMesh/NavMeshTriangle.h>
|
|
||||||
#include <Indoor/navMesh/NavMeshType.h>
|
|
||||||
|
|
||||||
#include <QPainter>
|
|
||||||
#include <QOpenGLWidget>
|
|
||||||
#include <QOpenGLFunctions>
|
|
||||||
|
|
||||||
#include "../misc/Renderable3D.h"
|
#include "../misc/Renderable3D.h"
|
||||||
#include "../misc/Shader.h"
|
|
||||||
#include "../misc/TriangleData.h"
|
|
||||||
|
|
||||||
#include <Indoor/wifi/estimate/ray3/ModelFactory.h>
|
class RenderTriangle;
|
||||||
|
|
||||||
#include "RenderTriangle.h"
|
|
||||||
|
|
||||||
class FloorplanRenderer {
|
class FloorplanRenderer {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/** ctor */
|
/** ctor */
|
||||||
FloorplanRenderer() {
|
FloorplanRenderer();
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** render the given grid using GL commands */
|
/** render the given grid using GL commands */
|
||||||
void renderSolid(const RenderSettings& rs, const RenderTriangle& rt, bool wireframe) {
|
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();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/** render the given grid using GL commands */
|
/** render the given grid using GL commands */
|
||||||
void renderTransp(const RenderSettings& rs, const RenderTriangle& rt, bool wireframe) {
|
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);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ void NavMeshRenderer::rebuildIfNeeded(NavMeshModel* model) {
|
|||||||
case (int) NM::NavMeshType::STAIR_SKEWED: color = Point3(0.4, 0.4, 0.4); break;
|
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->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->getP2(), tria->getP3(), color.x, color.y, color.z, 1);
|
||||||
outlines.addLine(tria->getP3(), tria->getP1(), color.x, color.y, color.z, 1);
|
outlines.addLine(tria->getP3(), tria->getP1(), color.x, color.y, color.z, 1);
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
#include "IHasParams.h"
|
#include "IHasParams.h"
|
||||||
|
|
||||||
#include "../2D/MV2DElementFloorObstacleDoor.h"
|
#include "../2D/MV2DElementFloorObstacleDoor.h"
|
||||||
#include "../3D/MV3DElementFloorObstacleDoor.h"
|
//#include "../3D/MV3DElementFloorObstacleDoor.h"
|
||||||
|
|
||||||
#include <Indoor/floorplan/v2/Floorplan.h>
|
#include <Indoor/floorplan/v2/Floorplan.h>
|
||||||
|
|
||||||
@@ -21,12 +21,12 @@ public:
|
|||||||
Floorplan::Floor* mf;
|
Floorplan::Floor* mf;
|
||||||
Floorplan::FloorObstacleDoor* fo;
|
Floorplan::FloorObstacleDoor* fo;
|
||||||
MV2DElementFloorObstacleDoor mv2d;
|
MV2DElementFloorObstacleDoor mv2d;
|
||||||
MV3DElementFloorObstacleDoor mv3d;
|
//MV3DElementFloorObstacleDoor mv3d;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
MMFloorObstacleDoor(MapLayer* parent, Floorplan::Floor* mf, Floorplan::FloorObstacleDoor* fo) :
|
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;}
|
Floorplan::DoorType getDoorType() const override {return fo->type;}
|
||||||
|
|
||||||
MV2DElement* getMV2D() const override {return (MV2DElement*) &mv2d;}
|
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 {
|
void deleteMe() const override {
|
||||||
parent->removeElement(this);
|
parent->removeElement(this);
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
#include "IHasParams.h"
|
#include "IHasParams.h"
|
||||||
|
|
||||||
#include "../2D/MV2DElementFloorObstacleLine.h"
|
#include "../2D/MV2DElementFloorObstacleLine.h"
|
||||||
#include "../3D/MV3DElementFloorObstacleWall.h"
|
//#include "../3D/MV3DElementFloorObstacleWall.h"
|
||||||
|
|
||||||
#include <Indoor/floorplan/v2/Floorplan.h>
|
#include <Indoor/floorplan/v2/Floorplan.h>
|
||||||
|
|
||||||
@@ -21,12 +21,12 @@ public:
|
|||||||
Floorplan::Floor* mf;
|
Floorplan::Floor* mf;
|
||||||
Floorplan::FloorObstacleLine* fo;
|
Floorplan::FloorObstacleLine* fo;
|
||||||
MV2DElementFloorObstacleLine mv2d;
|
MV2DElementFloorObstacleLine mv2d;
|
||||||
MV3DElementFloorObstacleWall mv3d;
|
//MV3DElementFloorObstacleWall mv3d;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
MMFloorObstacleLine(MapLayer* parent, Floorplan::Floor* mf, Floorplan::FloorObstacleLine* fo) :
|
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;}
|
Floorplan::ObstacleType getObatcleType() const override {return fo->type;}
|
||||||
|
|
||||||
MV2DElement* getMV2D() const override {return (MV2DElement*) &mv2d;}
|
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 {
|
void deleteMe() const override {
|
||||||
parent->removeElement(this);
|
parent->removeElement(this);
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
#include "IHasParams.h"
|
#include "IHasParams.h"
|
||||||
|
|
||||||
#include "../2D/MV2DElementFloorObstacleObject.h"
|
#include "../2D/MV2DElementFloorObstacleObject.h"
|
||||||
#include "../3D/MV3DElementFloorObstacleObject.h"
|
//#include "../3D/MV3DElementFloorObstacleObject.h"
|
||||||
|
|
||||||
#include <Indoor/floorplan/v2/Floorplan.h>
|
#include <Indoor/floorplan/v2/Floorplan.h>
|
||||||
|
|
||||||
@@ -22,17 +22,17 @@ public:
|
|||||||
Floorplan::Floor* mf;
|
Floorplan::Floor* mf;
|
||||||
Floorplan::FloorObstacleObject* fo;
|
Floorplan::FloorObstacleObject* fo;
|
||||||
MV2DElementFloorObstacleObject mv2d;
|
MV2DElementFloorObstacleObject mv2d;
|
||||||
MV3DElementFloorObstacleObject mv3d;
|
//MV3DElementFloorObstacleObject mv3d;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
MMFloorObstacleObject(MapLayer* parent, Floorplan::Floor* mf, Floorplan::FloorObstacleObject* fo) :
|
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;}
|
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 {
|
void deleteMe() const override {
|
||||||
parent->removeElement(this);
|
parent->removeElement(this);
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
#include "MMFloorOutlinePolygon.h"
|
#include "MMFloorOutlinePolygon.h"
|
||||||
#include "MMFloorOutlinePolygonCombined.h"
|
#include "MMFloorOutlinePolygonCombined.h"
|
||||||
|
|
||||||
#include "../3D/MV3DElementFloorOutline.h"
|
//#include "../3D/MV3DElementFloorOutline.h"
|
||||||
|
|
||||||
#include <Indoor/floorplan/v2/Floorplan.h>
|
#include <Indoor/floorplan/v2/Floorplan.h>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include "MapLayer.h"
|
#include "MapLayer.h"
|
||||||
#include "MMFloorOutlinePolygon.h"
|
#include "MMFloorOutlinePolygon.h"
|
||||||
#include "../3D/MV3DElementFloorOutline.h"
|
//#include "../3D/MV3DElementFloorOutline.h"
|
||||||
|
|
||||||
|
|
||||||
#include <Indoor/floorplan/v2/Floorplan.h>
|
#include <Indoor/floorplan/v2/Floorplan.h>
|
||||||
@@ -19,19 +19,19 @@ private:
|
|||||||
/** the underlying model */
|
/** the underlying model */
|
||||||
Floorplan::Floor* floor;
|
Floorplan::Floor* floor;
|
||||||
|
|
||||||
MV3DElementFloorOutline mv3d;
|
//MV3DElementFloorOutline mv3d;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/** ctor with the underlying model */
|
/** ctor with the underlying model */
|
||||||
MMFloorOutlinePolygonCombined(MapLayer* parent, Floorplan::Floor* floor) :
|
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 */
|
/** get the corresponding floor from the underlying model */
|
||||||
Floorplan::Floor* getFloor() {return floor;}
|
Floorplan::Floor* getFloor() {return floor;}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
#include "MMFloorOutlinePolygon.h"
|
#include "MMFloorOutlinePolygon.h"
|
||||||
|
|
||||||
#include "../2D/MV2DElementStair.h"
|
#include "../2D/MV2DElementStair.h"
|
||||||
#include "../3D/MV3DElementStair.h"
|
//#include "../3D/MV3DElementStair.h"
|
||||||
|
|
||||||
|
|
||||||
#include <Indoor/floorplan/v2/Floorplan.h>
|
#include <Indoor/floorplan/v2/Floorplan.h>
|
||||||
@@ -23,20 +23,20 @@ private:
|
|||||||
Floorplan::StairFreeform* stair;
|
Floorplan::StairFreeform* stair;
|
||||||
|
|
||||||
MV2DElementStair mv2d;
|
MV2DElementStair mv2d;
|
||||||
MV3DElementStair mv3d;
|
//MV3DElementStair mv3d;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/** ctor with the underlying model */
|
/** ctor with the underlying model */
|
||||||
MMFloorStair(MapLayer* parent, Floorplan::IndoorMap* map, Floorplan::Floor* floor, Floorplan::StairFreeform* stair) :
|
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;}
|
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 {
|
virtual int getNumParams() const override {
|
||||||
|
|||||||
@@ -188,6 +188,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void setVisible(const bool visible) override {
|
void setVisible(const bool visible) override {
|
||||||
|
(void) visible;
|
||||||
throw "error";
|
throw "error";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,15 +7,17 @@
|
|||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QLineEdit>
|
#include <QLineEdit>
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QFileDialog>
|
||||||
|
|
||||||
#include "../mapview/model/IHasParams.h"
|
#include "../mapview/model/IHasParams.h"
|
||||||
|
|
||||||
class EditFields {
|
class EditFields {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static void get(QGridLayout* lay, IHasParams* elem) {
|
static void get(QWidget* parent, int& r, QGridLayout* lay, IHasParams* elem) {
|
||||||
|
|
||||||
int r = 0;
|
|
||||||
|
|
||||||
for(int i = 0; i < elem->getNumParams(); ++i) {
|
for(int i = 0; i < elem->getNumParams(); ++i) {
|
||||||
|
|
||||||
@@ -29,8 +31,24 @@ public:
|
|||||||
|
|
||||||
switch(param.type) {
|
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<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), [i, elem, cmb] (int idx) {
|
||||||
|
(void) idx;
|
||||||
|
elem->setParamValue(i, cmb->currentData().toInt() );
|
||||||
|
});
|
||||||
|
lay->addWidget(cmb,r,1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case ParamType::BOOL: {
|
case ParamType::BOOL: {
|
||||||
QCheckBox* chk = new QCheckBox( );
|
QCheckBox* chk = new QCheckBox(parent);
|
||||||
chk->setChecked(value.toBool());
|
chk->setChecked(value.toBool());
|
||||||
if (param.readOnly) {
|
if (param.readOnly) {
|
||||||
chk->setEnabled(false);
|
chk->setEnabled(false);
|
||||||
@@ -46,9 +64,9 @@ public:
|
|||||||
case ParamType::FLOAT: {
|
case ParamType::FLOAT: {
|
||||||
const std::string str = std::to_string(value.toFloat());
|
const std::string str = std::to_string(value.toFloat());
|
||||||
if (param.readOnly) {
|
if (param.readOnly) {
|
||||||
lay->addWidget(new QLabel(str.c_str()),r,1);
|
lay->addWidget(new QLabel(str.c_str(), parent),r,1);
|
||||||
} else {
|
} 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) {
|
le->connect(le, &QLineEdit::textChanged, [i,elem] (const QString& str) {
|
||||||
const float val = str.toFloat();
|
const float val = str.toFloat();
|
||||||
elem->setParamValue(i, ParamValue(val));
|
elem->setParamValue(i, ParamValue(val));
|
||||||
@@ -61,11 +79,11 @@ public:
|
|||||||
case ParamType::DOUBLE: {
|
case ParamType::DOUBLE: {
|
||||||
const std::string str = std::to_string(value.toDouble());
|
const std::string str = std::to_string(value.toDouble());
|
||||||
if (param.readOnly) {
|
if (param.readOnly) {
|
||||||
lay->addWidget(new QLabel(str.c_str()),r,1);
|
lay->addWidget(new QLabel(str.c_str(), parent),r,1);
|
||||||
} else {
|
} 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) {
|
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));
|
elem->setParamValue(i, ParamValue(val));
|
||||||
});
|
});
|
||||||
lay->addWidget(le,r,1);
|
lay->addWidget(le,r,1);
|
||||||
@@ -75,7 +93,7 @@ public:
|
|||||||
|
|
||||||
case ParamType::INT: {
|
case ParamType::INT: {
|
||||||
const std::string str = std::to_string(value.toInt());
|
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) {
|
le->connect(le, &QLineEdit::textChanged, [i,elem] (const QString& str) {
|
||||||
const int val = str.toInt();
|
const int val = str.toInt();
|
||||||
elem->setParamValue(i, ParamValue(val));
|
elem->setParamValue(i, ParamValue(val));
|
||||||
@@ -86,7 +104,7 @@ public:
|
|||||||
|
|
||||||
case ParamType::STRING: {
|
case ParamType::STRING: {
|
||||||
const std::string str = value.toString();
|
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) {
|
le->connect(le, &QLineEdit::textChanged, [i,elem] (const QString& str) {
|
||||||
elem->setParamValue(i, ParamValue(str.toStdString()));
|
elem->setParamValue(i, ParamValue(str.toStdString()));
|
||||||
});
|
});
|
||||||
@@ -96,8 +114,8 @@ public:
|
|||||||
|
|
||||||
case ParamType::FILE: {
|
case ParamType::FILE: {
|
||||||
const std::string str = value.toString();
|
const std::string str = value.toString();
|
||||||
QLabel* lblFile = new QLabel(str.c_str());
|
QLabel* lblFile = new QLabel(str.c_str(), parent);
|
||||||
QPushButton* btn = new QPushButton("<");
|
QPushButton* btn = new QPushButton("<",parent);
|
||||||
btn->setMaximumSize(32,32);
|
btn->setMaximumSize(32,32);
|
||||||
btn->connect(btn, &QPushButton::clicked, [i,elem,lblFile] (const bool checked) {
|
btn->connect(btn, &QPushButton::clicked, [i,elem,lblFile] (const bool checked) {
|
||||||
(void) checked;
|
(void) checked;
|
||||||
@@ -112,10 +130,10 @@ public:
|
|||||||
|
|
||||||
case ParamType::POINT2: {
|
case ParamType::POINT2: {
|
||||||
const Point2 p2 = value.toPoint2();
|
const Point2 p2 = value.toPoint2();
|
||||||
QWidget* subWidget = new QWidget();
|
QWidget* subWidget = new QWidget(parent);
|
||||||
QGridLayout* laySub = new QGridLayout(subWidget); laySub->setMargin(0);
|
QGridLayout* laySub = new QGridLayout(subWidget); laySub->setMargin(0);
|
||||||
QLineEdit* txtX = new QLineEdit(QString::number(p2.x));
|
QLineEdit* txtX = new QLineEdit(QString::number(p2.x), subWidget);
|
||||||
QLineEdit* txtY = new QLineEdit(QString::number(p2.y));
|
QLineEdit* txtY = new QLineEdit(QString::number(p2.y), subWidget);
|
||||||
laySub->addWidget(txtX,0,0);
|
laySub->addWidget(txtX,0,0);
|
||||||
laySub->addWidget(txtY,0,1);
|
laySub->addWidget(txtY,0,1);
|
||||||
lay->addWidget(subWidget,r,1);
|
lay->addWidget(subWidget,r,1);
|
||||||
@@ -130,11 +148,11 @@ public:
|
|||||||
|
|
||||||
case ParamType::POINT3: {
|
case ParamType::POINT3: {
|
||||||
const Point3 p3 = value.toPoint3();
|
const Point3 p3 = value.toPoint3();
|
||||||
QWidget* subWidget = new QWidget();
|
QWidget* subWidget = new QWidget(parent);
|
||||||
QGridLayout* laySub = new QGridLayout(subWidget); laySub->setMargin(0);
|
QGridLayout* laySub = new QGridLayout(subWidget); laySub->setMargin(0);
|
||||||
QLineEdit* txtX = new QLineEdit(QString::number(p3.x));
|
QLineEdit* txtX = new QLineEdit(QString::number(p3.x), subWidget);
|
||||||
QLineEdit* txtY = new QLineEdit(QString::number(p3.y));
|
QLineEdit* txtY = new QLineEdit(QString::number(p3.y), subWidget);
|
||||||
QLineEdit* txtZ = new QLineEdit(QString::number(p3.z));
|
QLineEdit* txtZ = new QLineEdit(QString::number(p3.z), subWidget);
|
||||||
laySub->addWidget(txtX,0,0);
|
laySub->addWidget(txtX,0,0);
|
||||||
laySub->addWidget(txtY,0,1);
|
laySub->addWidget(txtY,0,1);
|
||||||
laySub->addWidget(txtZ,0,2);
|
laySub->addWidget(txtZ,0,2);
|
||||||
@@ -149,8 +167,8 @@ public:
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case ParamType::NOT_AVAILABLE:
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#include "../mapview/model/IHasEditableMeta.h"
|
#include "../mapview/model/IHasEditableMeta.h"
|
||||||
|
|
||||||
#include "MetaEditWidget.h"
|
#include "MetaEditWidget.h"
|
||||||
|
#include "EditFields.h"
|
||||||
|
|
||||||
#include <Indoor/floorplan/v2/Floorplan.h>
|
#include <Indoor/floorplan/v2/Floorplan.h>
|
||||||
|
|
||||||
@@ -19,6 +20,7 @@
|
|||||||
#include <QLineEdit>
|
#include <QLineEdit>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
|
#include <QCheckBox>
|
||||||
|
|
||||||
QComboBox* getMaterials() {
|
QComboBox* getMaterials() {
|
||||||
using namespace Floorplan;
|
using namespace Floorplan;
|
||||||
@@ -96,7 +98,7 @@ void ElementParamWidget::refresh() {
|
|||||||
|
|
||||||
while ( QWidget* w = this->findChild<QWidget*>() ) {delete w;}
|
while ( QWidget* w = this->findChild<QWidget*>() ) {delete w;}
|
||||||
delete this->layout();
|
delete this->layout();
|
||||||
this->lay = new QGridLayout();
|
this->lay = new QGridLayout(this);
|
||||||
this->setLayout(lay);
|
this->setLayout(lay);
|
||||||
int r = 0;
|
int r = 0;
|
||||||
|
|
||||||
@@ -107,7 +109,7 @@ void ElementParamWidget::refresh() {
|
|||||||
IHasMaterial* elem = dynamic_cast<IHasMaterial*>(el);
|
IHasMaterial* elem = dynamic_cast<IHasMaterial*>(el);
|
||||||
if (elem) {
|
if (elem) {
|
||||||
material.cmb = getMaterials();
|
material.cmb = getMaterials();
|
||||||
material.lbl = new QLabel("material");
|
material.lbl = new QLabel("material", this);
|
||||||
lay->addWidget(material.lbl,r,0);
|
lay->addWidget(material.lbl,r,0);
|
||||||
lay->addWidget(material.cmb,r,1);
|
lay->addWidget(material.cmb,r,1);
|
||||||
connect(material.cmb , SIGNAL(currentIndexChanged(int)), this, SLOT(onMaterialChange()));
|
connect(material.cmb , SIGNAL(currentIndexChanged(int)), this, SLOT(onMaterialChange()));
|
||||||
@@ -121,7 +123,7 @@ void ElementParamWidget::refresh() {
|
|||||||
IHasObstacleType* elem = dynamic_cast<IHasObstacleType*>(el);
|
IHasObstacleType* elem = dynamic_cast<IHasObstacleType*>(el);
|
||||||
if (elem) {
|
if (elem) {
|
||||||
obstacleType.cmb = getObstacleTypes();
|
obstacleType.cmb = getObstacleTypes();
|
||||||
obstacleType.lbl = new QLabel("type");
|
obstacleType.lbl = new QLabel("type", this);
|
||||||
lay->addWidget(obstacleType.lbl,r,0);
|
lay->addWidget(obstacleType.lbl,r,0);
|
||||||
lay->addWidget(obstacleType.cmb,r,1);
|
lay->addWidget(obstacleType.cmb,r,1);
|
||||||
connect(obstacleType.cmb, SIGNAL(currentIndexChanged(int)), this, SLOT(onObstacleTypeChange()));
|
connect(obstacleType.cmb, SIGNAL(currentIndexChanged(int)), this, SLOT(onObstacleTypeChange()));
|
||||||
@@ -135,7 +137,7 @@ void ElementParamWidget::refresh() {
|
|||||||
MMFloorOutlinePolygon* elem = dynamic_cast<MMFloorOutlinePolygon*>(el);
|
MMFloorOutlinePolygon* elem = dynamic_cast<MMFloorOutlinePolygon*>(el);
|
||||||
if (elem) {
|
if (elem) {
|
||||||
QComboBox* cmb = getOutlineMethods();
|
QComboBox* cmb = getOutlineMethods();
|
||||||
QLabel* lbl = new QLabel("outline");
|
QLabel* lbl = new QLabel("outline", this);
|
||||||
lay->addWidget(lbl,r,0);
|
lay->addWidget(lbl,r,0);
|
||||||
lay->addWidget(cmb,r,1);
|
lay->addWidget(cmb,r,1);
|
||||||
cmb->setCurrentIndex((int)elem->getMethod());
|
cmb->setCurrentIndex((int)elem->getMethod());
|
||||||
@@ -150,176 +152,21 @@ void ElementParamWidget::refresh() {
|
|||||||
{ // does the element have "parameters" ?
|
{ // does the element have "parameters" ?
|
||||||
IHasParams* elem = dynamic_cast<IHasParams*>(el);
|
IHasParams* elem = dynamic_cast<IHasParams*>(el);
|
||||||
if (elem) {
|
if (elem) {
|
||||||
|
EditFields::get(this, r, lay, 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<void (QComboBox::*)(int)>(&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;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{ // does the element have editable metadata?
|
{ // does the element have editable metadata?
|
||||||
IHasEditableMeta* elem = dynamic_cast<IHasEditableMeta*>(el);
|
IHasEditableMeta* elem = dynamic_cast<IHasEditableMeta*>(el);
|
||||||
if (elem) {
|
if (elem) {
|
||||||
|
|
||||||
QPushButton* btn = new QPushButton("edit");
|
QPushButton* btn = new QPushButton("edit", this);
|
||||||
connect(btn, &QPushButton::clicked, [elem] (const bool checked) {
|
connect(btn, &QPushButton::clicked, [elem] (const bool checked) {
|
||||||
(void) checked;
|
(void) checked;
|
||||||
if (!elem->getMeta()) {elem->setMeta(new Floorplan::Meta());} // ensure meta-object is present
|
if (!elem->getMeta()) {elem->setMeta(new Floorplan::Meta());} // ensure meta-object is present
|
||||||
MetaEditWidget* mew = new MetaEditWidget(elem->getMeta()); // edit
|
MetaEditWidget* mew = new MetaEditWidget(elem->getMeta()); // edit
|
||||||
mew->show();
|
mew->show();
|
||||||
});
|
});
|
||||||
lay->addWidget(new QLabel("Meta"),r,0);
|
lay->addWidget(new QLabel("Meta", this),r,0);
|
||||||
lay->addWidget(btn,r,1);
|
lay->addWidget(btn,r,1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ void LayerParamWidget::setElement(MapLayer* l) {
|
|||||||
delete this->layout();
|
delete this->layout();
|
||||||
this->lay = new QGridLayout();
|
this->lay = new QGridLayout();
|
||||||
this->setLayout(lay);
|
this->setLayout(lay);
|
||||||
// int r = 0;
|
int r = 0;
|
||||||
|
|
||||||
|
|
||||||
// {
|
// {
|
||||||
@@ -97,7 +97,7 @@ void LayerParamWidget::setElement(MapLayer* l) {
|
|||||||
{
|
{
|
||||||
IHasParams* elem = dynamic_cast<IHasParams*>(l);
|
IHasParams* elem = dynamic_cast<IHasParams*>(l);
|
||||||
if (elem) {
|
if (elem) {
|
||||||
EditFields::get(lay, elem);
|
EditFields::get(this, r, lay, elem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ class QLabel;
|
|||||||
class QLineEdit;
|
class QLineEdit;
|
||||||
class QComboBox;
|
class QComboBox;
|
||||||
class QGridLayout;
|
class QGridLayout;
|
||||||
|
class IHasParams;
|
||||||
|
|
||||||
class LayerParamWidget : public QWidget {
|
class LayerParamWidget : public QWidget {
|
||||||
|
|
||||||
@@ -48,6 +49,7 @@ private:
|
|||||||
QLabel* lbl;
|
QLabel* lbl;
|
||||||
} height;
|
} height;
|
||||||
|
|
||||||
|
void buildFields(QGridLayout* lay, IHasParams* elem);
|
||||||
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|||||||
@@ -15,11 +15,13 @@ void MetaEditModel::setSource(Floorplan::Meta* meta) {
|
|||||||
endResetModel();
|
endResetModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
int MetaEditModel::rowCount(const QModelIndex &parent) const {
|
int MetaEditModel::rowCount(const QModelIndex& parent) const {
|
||||||
|
(void) parent;
|
||||||
return (meta) ? (meta->size()) : (0);
|
return (meta) ? (meta->size()) : (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int MetaEditModel::columnCount(const QModelIndex &parent) const {
|
int MetaEditModel::columnCount(const QModelIndex& parent) const {
|
||||||
|
(void) parent;
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user