526 lines
13 KiB
C++
526 lines
13 KiB
C++
#include "ToolBoxWidget.h"
|
|
|
|
#include <QVBoxLayout>
|
|
#include <QGridLayout>
|
|
|
|
#include <QPushButton>
|
|
#include <QPixmap>
|
|
|
|
#include "../mapview/model/MapLayers.h"
|
|
|
|
#include "../mapview/2D/MapView2D.h"
|
|
#include "../mapview/model/MapModel.h"
|
|
#include "../mapview/model/MMFloorAccessPoint.h"
|
|
#include "../mapview/model/MMFloorBeacon.h"
|
|
#include "../mapview/model/MMFloorGroundTruthPoints.h"
|
|
|
|
#include "../mapview/2D/tools/ToolMeasure.h"
|
|
|
|
#include "../UIHelper.h"
|
|
|
|
QSplitter* getSplitter() {
|
|
|
|
QSplitter* splt = new QSplitter();
|
|
splt->setStyleSheet("background-color:black;");
|
|
splt->setMinimumHeight(1);
|
|
return splt;
|
|
|
|
}
|
|
|
|
ToolBoxWidget::ToolBoxWidget(MapView2D* view, QWidget *parent) : QWidget(parent), view(view) {
|
|
|
|
const int s = 32;
|
|
setMaximumWidth(48);
|
|
setMinimumWidth(48);
|
|
|
|
QGridLayout* lay = new QGridLayout(this);
|
|
|
|
// SELECTION
|
|
btnSelect = new QPushButton(UIHelper::getIcon("cursor"), "");
|
|
btnSelect->setMinimumSize(s,s);
|
|
lay->addWidget(btnSelect, r++, 0, 1,1,Qt::AlignTop);
|
|
connect(btnSelect, SIGNAL(clicked(bool)), this, SLOT(onSelect()));
|
|
|
|
|
|
// MEASURE
|
|
btnMeasure = new QPushButton(UIHelper::getIcon("ruler"), "");
|
|
btnMeasure->setMinimumSize(s,s);
|
|
lay->addWidget(btnMeasure, r++, 0, 1,1,Qt::AlignTop);
|
|
connect(btnMeasure, SIGNAL(clicked(bool)), this, SLOT(onMeasure()));
|
|
|
|
|
|
// splitter
|
|
lay->addWidget(getSplitter(), r++, 0, 1,1,Qt::AlignTop);
|
|
|
|
|
|
// OBSTACLES
|
|
btnGround = new QPushButton(UIHelper::getIcon("floor"), "");
|
|
btnGround->setMinimumSize(s,s);
|
|
lay->addWidget(btnGround, r++, 0, 1,1,Qt::AlignTop);
|
|
connect(btnGround, SIGNAL(clicked(bool)), this, SLOT(onNewGround()));
|
|
|
|
btnWall = new QPushButton(UIHelper::getIcon("wall"), "");
|
|
btnWall->setMinimumSize(s,s);
|
|
lay->addWidget(btnWall, r++, 0, 1,1,Qt::AlignTop);
|
|
connect(btnWall, SIGNAL(clicked(bool)), this, SLOT(onNewWall()));
|
|
|
|
btnPillar = new QPushButton(UIHelper::getIcon("pillar"), "");
|
|
btnPillar->setMinimumSize(s,s);
|
|
lay->addWidget(btnPillar, r++, 0, 1,1,Qt::AlignTop);
|
|
connect(btnPillar, SIGNAL(clicked(bool)), this, SLOT(onNewPillar()));
|
|
|
|
btnDoor = new QPushButton(UIHelper::getIcon("door"), "");
|
|
btnDoor->setMinimumSize(s,s);
|
|
lay->addWidget(btnDoor, r++, 0, 1,1,Qt::AlignTop);
|
|
connect(btnDoor, SIGNAL(clicked(bool)), this, SLOT(onNewDoor()));
|
|
|
|
btnStair = new QPushButton(UIHelper::getIcon("stair"), "");
|
|
btnStair->setMinimumSize(s,s);
|
|
lay->addWidget(btnStair, r++, 0, 1,1,Qt::AlignTop);
|
|
connect(btnStair, SIGNAL(clicked(bool)), this, SLOT(onNewStair()));
|
|
|
|
btnElevator = new QPushButton(UIHelper::getIcon("elevator"), "");
|
|
btnElevator->setMinimumSize(s,s);
|
|
lay->addWidget(btnElevator, r++, 0, 1,1,Qt::AlignTop);
|
|
connect(btnElevator, SIGNAL(clicked(bool)), this, SLOT(onNewElevator()));
|
|
|
|
|
|
// splitter
|
|
lay->addWidget(getSplitter(), r++, 0, 1,1,Qt::AlignTop);
|
|
|
|
|
|
// TRANSMITTERS
|
|
btnWifi = new QPushButton(UIHelper::getIcon("wifi"), "");
|
|
btnWifi->setMinimumSize(s,s);
|
|
lay->addWidget(btnWifi, r++, 0, 1,1,Qt::AlignTop);
|
|
connect(btnWifi, SIGNAL(clicked(bool)), this, SLOT(onNewAccessPoint()));
|
|
|
|
btnBeacon = new QPushButton(UIHelper::getIcon("beacon"), "");
|
|
btnBeacon->setMinimumSize(s,s);
|
|
lay->addWidget(btnBeacon, r++, 0, 1,1,Qt::AlignTop);
|
|
connect(btnBeacon, SIGNAL(clicked(bool)), this, SLOT(onNewBeacon()));
|
|
|
|
// TRANSMITTER RELATED
|
|
btnFingerprintLocation = new QPushButton(UIHelper::getIcon("fingerprint"), "");
|
|
btnFingerprintLocation->setMinimumSize(s,s);
|
|
lay->addWidget(btnFingerprintLocation, r++, 0, 1,1,Qt::AlignTop);
|
|
connect(btnFingerprintLocation, SIGNAL(clicked(bool)), this, SLOT(onNewFingerprintLocation()));
|
|
|
|
// IMAGES
|
|
btnImage = new QPushButton(UIHelper::getIcon("image"), "");
|
|
btnImage->setMinimumSize(s,s);
|
|
lay->addWidget(btnImage, r++, 0, 1,1,Qt::AlignTop);
|
|
connect(btnImage, SIGNAL(clicked(bool)), this, SLOT(onNewImage()));
|
|
|
|
// POI
|
|
btnPOI = new QPushButton(UIHelper::getIcon("poi"), "");
|
|
btnPOI->setMinimumSize(s,s);
|
|
lay->addWidget(btnPOI, r++, 0, 1,1,Qt::AlignTop);
|
|
connect(btnPOI, SIGNAL(clicked(bool)), this, SLOT(onNewPOI()));
|
|
|
|
// GROUNDTRUTH
|
|
btnGTP = new QPushButton(UIHelper::getIcon("gtp"), "");
|
|
btnGTP->setMinimumSize(s,s);
|
|
lay->addWidget(btnGTP, r++, 0, 1,1,Qt::AlignTop);
|
|
connect(btnGTP, SIGNAL(clicked(bool)), this, SLOT(onNewGTP()));
|
|
|
|
// FILL
|
|
lay->addItem(new QSpacerItem(0,0,QSizePolicy::Minimum, QSizePolicy::MinimumExpanding), r, 0);
|
|
|
|
// start empty
|
|
setSelectedLayer(nullptr);
|
|
|
|
}
|
|
|
|
void ToolBoxWidget::setSelectedLayer(MapLayer *ml) {
|
|
|
|
this->curLayer = ml;
|
|
|
|
btnGround->setEnabled(ml && (ml->getLayerType() == MapLayerType::FLOOR_GROUND));
|
|
|
|
btnWall->setEnabled(ml && (ml->getLayerType() == MapLayerType::FLOOR_OBSTACLES));
|
|
btnPillar->setEnabled(ml && (ml->getLayerType() == MapLayerType::FLOOR_OBSTACLES));
|
|
btnDoor->setEnabled(ml && (ml->getLayerType() == MapLayerType::FLOOR_OBSTACLES));
|
|
|
|
btnStair->setEnabled(ml && (ml->getLayerType() == MapLayerType::FLOOR_STAIRS));
|
|
btnElevator->setEnabled(ml && (ml->getLayerType() == MapLayerType::FLOOR_ELEVATORS));
|
|
|
|
btnWifi->setEnabled(ml && (ml->getLayerType() == MapLayerType::FLOOR_ACCESS_POINTS));
|
|
btnBeacon->setEnabled(ml && (ml->getLayerType() == MapLayerType::FLOOR_BEACONS));
|
|
btnFingerprintLocation->setEnabled(ml && (ml->getLayerType() == MapLayerType::FLOOR_FINGERPRINTS));
|
|
btnPOI->setEnabled(ml && (ml->getLayerType() == MapLayerType::FLOOR_POIS));
|
|
btnGTP->setEnabled(ml && (ml->getLayerType() == MapLayerType::FLOOR_GROUND_TRUTH_POINTS));
|
|
|
|
btnImage->setEnabled(ml && (ml->getLayerType() == MapLayerType::FLOOR_UNDERLAYS));
|
|
|
|
}
|
|
|
|
|
|
void ToolBoxWidget::onNewGround() {
|
|
|
|
const Point2 center = view->getScaler().getCenter();
|
|
float s = view->getScaler().sm(50);
|
|
|
|
Floorplan::FloorOutlinePolygon* poly = new Floorplan::FloorOutlinePolygon();
|
|
poly->name = "new";
|
|
poly->poly.points.push_back(Point2(center.x-s, center.y-s));
|
|
poly->poly.points.push_back(Point2(center.x+s, center.y-s));
|
|
poly->poly.points.push_back(Point2(center.x, center.y+s));
|
|
|
|
|
|
MMFloorOutline* ml = (MMFloorOutline*)curLayer;
|
|
ml->create(poly);
|
|
|
|
view->getModel()->reselect();
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename FloorplanElement, typename MapModelElement> class NewElementTool : public Tool {
|
|
|
|
protected:
|
|
|
|
/** add another line after this one? */
|
|
bool addAnother = true;
|
|
|
|
/** register this tool into the given tools-queue */
|
|
Tools& tools;
|
|
Tool* oldMainTool;
|
|
|
|
/** the layer to add the new element to */
|
|
MapLayer* layer = nullptr;
|
|
|
|
/** currently edited element */
|
|
FloorplanElement* foEL = nullptr;
|
|
MapModelElement* mmEL = nullptr;
|
|
|
|
public:
|
|
|
|
NewElementTool(Tools& tools, MapLayer* layer) : tools(tools), layer(layer) {
|
|
oldMainTool = tools.getMain(); // keep the current tool to reset it later
|
|
tools.setMain(this);
|
|
}
|
|
|
|
virtual ~NewElementTool() {
|
|
tools.setMain(oldMainTool); // reset to the previous tool
|
|
}
|
|
|
|
virtual bool mousePressEvent(MapView2D* m, QMouseEvent* e) override {
|
|
if (e->button() == Qt::MouseButton::LeftButton) {
|
|
(void) m; (void) e;
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
virtual bool mouseMoveEvent(MapView2D* m, QMouseEvent* e) override {
|
|
const Point2 onScreen(e->x(), e->y());
|
|
Point2 onMap = m->getScaler().sm(onScreen);
|
|
onMap = m->getScaler().snap(onMap);
|
|
moving(onMap);
|
|
return true;
|
|
}
|
|
|
|
virtual bool mouseReleaseEvent(MapView2D* m, QMouseEvent* e) override {
|
|
if (e->button() == Qt::MouseButton::LeftButton) {
|
|
(void) m; (void) e;
|
|
next();
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
virtual bool keyPressEvent(MapView2D* m, QKeyEvent* e) override {
|
|
(void) m;
|
|
if (e->key() == Qt::Key_Escape) {
|
|
deleteCurrent();
|
|
disableMe();
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
protected:
|
|
|
|
/** all subclasses must create a new, empty element here */
|
|
virtual void createEmptyElement() = 0;
|
|
|
|
/** mouse is currently moved */
|
|
virtual void moving(const Point2 mapPoint) = 0;
|
|
|
|
/** next pont */
|
|
virtual void next() = 0;
|
|
|
|
protected:
|
|
|
|
void create() {
|
|
createEmptyElement();
|
|
mmEL->getMV2D()->focus();
|
|
}
|
|
|
|
/** delete the currently edited element */
|
|
void deleteCurrent() {
|
|
if (mmEL) {mmEL->deleteMe();}
|
|
}
|
|
|
|
/** finalize the current element (if any) */
|
|
void finalizeCurrent() {
|
|
if (!mmEL) {return;}
|
|
mmEL->getMV2D()->unfocus();
|
|
mmEL = nullptr;
|
|
}
|
|
|
|
/** finish creating new elements */
|
|
void disableMe() {
|
|
finalizeCurrent();
|
|
delete this; // see dtor!
|
|
}
|
|
|
|
};
|
|
|
|
class NewWallTool : public NewElementTool<Floorplan::FloorObstacleLine, MMFloorObstacleLine> {
|
|
|
|
private:
|
|
|
|
/** currently edited line node (has 2) */
|
|
int idx = 0;
|
|
|
|
public:
|
|
|
|
NewWallTool(Tools& tools, MapLayer* layer) : NewElementTool(tools, layer) {
|
|
create();
|
|
}
|
|
|
|
const std::string getName() const override {
|
|
return "new Wall";
|
|
}
|
|
|
|
void createEmptyElement() override {
|
|
|
|
foEL = new Floorplan::FloorObstacleLine(Floorplan::ObstacleType::WALL, Floorplan::Material::DRYWALL, Point2(0, 0), Point2(0, 0));
|
|
MMFloorObstacles* obs = (MMFloorObstacles*)layer;
|
|
mmEL = obs->createLine(foEL);
|
|
|
|
}
|
|
|
|
/** mouse is currently moved */
|
|
void moving(const Point2 mapPoint) override {
|
|
|
|
if (idx == 0) { foEL->from = mapPoint; foEL->to = mapPoint; }
|
|
if (idx == 1) { foEL->to = mapPoint; }
|
|
|
|
}
|
|
|
|
/** next pont */
|
|
void next() override {
|
|
|
|
if (++idx == 2) {
|
|
finalizeCurrent();
|
|
if (addAnother) {
|
|
idx = 0;
|
|
create();
|
|
} else {
|
|
disableMe();
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
class NewDoorTool : public NewElementTool<Floorplan::FloorObstacleDoor, MMFloorObstacleDoor> {
|
|
|
|
private:
|
|
|
|
/** currently edited line node (has 2) */
|
|
int idx = 0;
|
|
|
|
public:
|
|
|
|
NewDoorTool(Tools& tools, MapLayer* layer) : NewElementTool(tools, layer) {
|
|
create();
|
|
}
|
|
|
|
const std::string getName() const override {
|
|
return "new Door";
|
|
}
|
|
|
|
void createEmptyElement() override {
|
|
|
|
foEL = new Floorplan::FloorObstacleDoor(Floorplan::DoorType::SWING, Floorplan::Material::WOOD, Point2(0, 0), Point2(0, 0));
|
|
MMFloorObstacles* obs = (MMFloorObstacles*)layer;
|
|
mmEL = obs->createDoor(foEL);
|
|
|
|
}
|
|
|
|
/** mouse is currently moved */
|
|
void moving(const Point2 mapPoint) override {
|
|
|
|
if (idx == 0) { foEL->from = mapPoint; foEL->to = mapPoint; }
|
|
if (idx == 1) { foEL->to = mapPoint; }
|
|
|
|
}
|
|
|
|
/** next pont */
|
|
void next() override {
|
|
|
|
if (++idx == 2) {
|
|
finalizeCurrent();
|
|
if (addAnother) {
|
|
idx = 0;
|
|
create();
|
|
} else {
|
|
disableMe();
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
void ToolBoxWidget::onSelect() {
|
|
|
|
|
|
}
|
|
|
|
void ToolBoxWidget::onMeasure() {
|
|
|
|
new ToolMeasure(view->getTools());
|
|
|
|
}
|
|
|
|
|
|
|
|
void ToolBoxWidget::onNewWall() {
|
|
|
|
new NewWallTool(view->getTools(), curLayer);
|
|
//view->getModel()->reselect();
|
|
|
|
}
|
|
|
|
void ToolBoxWidget::onNewPillar() {
|
|
|
|
const Point2 center = view->getScaler().getCenter();
|
|
float s = view->getScaler().sm(50);
|
|
|
|
Floorplan::FloorObstacleCircle* pillar = new Floorplan::FloorObstacleCircle(
|
|
Floorplan::Material::DRYWALL,
|
|
Point2(center.x-s, center.y),
|
|
s
|
|
);
|
|
|
|
MMFloorObstacles* obs = (MMFloorObstacles*)curLayer;
|
|
obs->createCircle(pillar);
|
|
|
|
//view->getModel()->reselect();
|
|
|
|
}
|
|
|
|
void ToolBoxWidget::onNewDoor() {
|
|
|
|
new NewDoorTool(view->getTools(), curLayer);
|
|
|
|
}
|
|
|
|
void ToolBoxWidget::onNewStair() {
|
|
|
|
const Point2 center = view->getScaler().getCenter();
|
|
|
|
Floorplan::StairFreeform* stair = new Floorplan::StairFreeform();
|
|
Floorplan::StairPart part(Point3(center.x-3, center.y, 0), Point3(center.x+3, center.y, 3), 3);
|
|
stair->parts.push_back( part );
|
|
|
|
MMFloorStairs* stairs = (MMFloorStairs*)curLayer;
|
|
stairs->create(stair);
|
|
|
|
//view->getModel()->reselect();
|
|
|
|
}
|
|
|
|
void ToolBoxWidget::onNewElevator() {
|
|
|
|
const Point2 center = view->getScaler().getCenter();
|
|
|
|
Floorplan::Elevator* elevator = new Floorplan::Elevator(center);
|
|
|
|
MMFloorElevators* elevators = (MMFloorElevators*)curLayer;
|
|
elevators->create(elevator);
|
|
|
|
//view->getModel()->reselect();
|
|
|
|
}
|
|
|
|
void ToolBoxWidget::onNewAccessPoint() {
|
|
|
|
const Point2 center = view->getScaler().getCenter();
|
|
Floorplan::AccessPoint* ap = new Floorplan::AccessPoint(
|
|
"noname", "00:00:00:00:00:00", Point3(center.x, center.y, 0)
|
|
);
|
|
|
|
MMFloorAccessPoints* aps = (MMFloorAccessPoints*) curLayer;
|
|
aps->createAP(ap);
|
|
|
|
}
|
|
|
|
void ToolBoxWidget::onNewBeacon() {
|
|
|
|
const Point2 center = view->getScaler().getCenter();
|
|
Floorplan::Beacon* b = new Floorplan::Beacon(
|
|
"noname", "00:00:00:00:00:00", Point3(center.x, center.y, 0)
|
|
);
|
|
|
|
MMFloorBeacons* beacons = (MMFloorBeacons*) curLayer;
|
|
beacons->createBeacon(b);
|
|
|
|
}
|
|
|
|
void ToolBoxWidget::onNewFingerprintLocation() {
|
|
|
|
const Point2 center = view->getScaler().getCenter();
|
|
Floorplan::FingerprintLocation* fpl = new Floorplan::FingerprintLocation("noname", center, 0);
|
|
|
|
MMFloorFingerprints* fps = (MMFloorFingerprints*) curLayer;
|
|
fps->create(fpl);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ToolBoxWidget::onNewPOI() {
|
|
|
|
const Point2 center = view->getScaler().getCenter();
|
|
Floorplan::POI* poi = new Floorplan::POI(
|
|
Floorplan::POIType::ROOM, "noname", Point2(center.x, center.y)
|
|
);
|
|
|
|
MMFloorPOIs* pois = (MMFloorPOIs*) curLayer;
|
|
pois->createPOI(poi);
|
|
|
|
}
|
|
|
|
void ToolBoxWidget::onNewGTP() {
|
|
|
|
const Point2 center = view->getScaler().getCenter();
|
|
Floorplan::GroundTruthPoint* gtp = new Floorplan::GroundTruthPoint(
|
|
0, Point2(center.x, center.y)
|
|
);
|
|
|
|
MMFloorGroundTruthPoints* gtps = (MMFloorGroundTruthPoints*) curLayer;
|
|
gtps->createGroundTruthPoint(gtp);
|
|
|
|
}
|
|
|
|
void ToolBoxWidget::onNewImage() {
|
|
|
|
const Point2 center = view->getScaler().getCenter();
|
|
|
|
MMFloorUnderlays* underlays = (MMFloorUnderlays*) curLayer;
|
|
underlays->createImage(center);
|
|
|
|
}
|