#include "ToolBoxWidget.h" #include #include #include #include #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/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())); // 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)); 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 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 { 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 { 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::onNewImage() { const Point2 center = view->getScaler().getCenter(); MMFloorUnderlays* underlays = (MMFloorUnderlays*) curLayer; underlays->createImage(center); }