merged
This commit is contained in:
@@ -37,7 +37,11 @@ SOURCES += \
|
|||||||
tree/MapTreeModel.cpp \
|
tree/MapTreeModel.cpp \
|
||||||
mapview/3D/MapView3D.cpp \
|
mapview/3D/MapView3D.cpp \
|
||||||
params/StairBuilder.cpp \
|
params/StairBuilder.cpp \
|
||||||
mapview/2D/tools/Tools.cpp
|
mapview/2D/tools/Tools.cpp \
|
||||||
|
params/LayerTree.cpp \
|
||||||
|
mapview/2D/tools/ToolMeasure.cpp \
|
||||||
|
params/MetaEditWidget.cpp \
|
||||||
|
params/MetaEditModel.cpp
|
||||||
|
|
||||||
|
|
||||||
HEADERS += MainWindow.h \
|
HEADERS += MainWindow.h \
|
||||||
@@ -64,6 +68,7 @@ HEADERS += MainWindow.h \
|
|||||||
mapview/2D/MV2DElementBeacon.h \
|
mapview/2D/MV2DElementBeacon.h \
|
||||||
mapview/2D/MV2DElementAccessPoint.h \
|
mapview/2D/MV2DElementAccessPoint.h \
|
||||||
mapview/2D/MV2DElementFloorObstacleCircle.h \
|
mapview/2D/MV2DElementFloorObstacleCircle.h \
|
||||||
|
mapview/2D/MV2DElementFloorObstacleDoor.h \
|
||||||
mapview/2D/MapViewElementHelper.h \
|
mapview/2D/MapViewElementHelper.h \
|
||||||
mapview/2D/MV2DElementFloorUnderlay.h \
|
mapview/2D/MV2DElementFloorUnderlay.h \
|
||||||
mapview/2D/MV2DElementPOI.h \
|
mapview/2D/MV2DElementPOI.h \
|
||||||
@@ -126,6 +131,16 @@ HEADERS += MainWindow.h \
|
|||||||
mapview/2D/MV2DElementElevator.h \
|
mapview/2D/MV2DElementElevator.h \
|
||||||
mapview/model/MMFloorElevators.h \
|
mapview/model/MMFloorElevators.h \
|
||||||
mapview/model/MMFloorElevator.h \
|
mapview/model/MMFloorElevator.h \
|
||||||
|
params/LayerTree.h \
|
||||||
|
params/EditFields.h \
|
||||||
|
mapview/2D/ClickDist.h \
|
||||||
|
mapview/2D/tools/ToolMeasure.h \
|
||||||
|
mapview/model/IHasEditableMeta.h \
|
||||||
|
params/MetaEditWidget.h \
|
||||||
|
params/MetaEditModel.h \
|
||||||
|
mapview/model/MapLayerListener.h \
|
||||||
|
mapview/model/MapModelListener.h \
|
||||||
|
mapview/model/MMFloorOutlinePolygonCombined.h\
|
||||||
mapview/model/MMFloorGroundTruthPoints.h \
|
mapview/model/MMFloorGroundTruthPoints.h \
|
||||||
mapview/model/MMFloorGroundTruthPoint.h \
|
mapview/model/MMFloorGroundTruthPoint.h \
|
||||||
mapview/2D/MV2DElementGroundTruthPoint.h
|
mapview/2D/MV2DElementGroundTruthPoint.h
|
||||||
|
|||||||
@@ -15,6 +15,8 @@
|
|||||||
#include "params/LayerParamWidget.h"
|
#include "params/LayerParamWidget.h"
|
||||||
#include "params/ToolBoxWidget.h"
|
#include "params/ToolBoxWidget.h"
|
||||||
#include "params/ActionWidget.h"
|
#include "params/ActionWidget.h"
|
||||||
|
#include "params/LayerTree.h"
|
||||||
|
#include "params/MetaEditWidget.h"
|
||||||
|
|
||||||
#include "tree/MapTreeModel.h"
|
#include "tree/MapTreeModel.h"
|
||||||
|
|
||||||
@@ -27,12 +29,20 @@
|
|||||||
|
|
||||||
MainController::MainController() {
|
MainController::MainController() {
|
||||||
|
|
||||||
|
// Floorplan::Meta* meta = new Floorplan::Meta();
|
||||||
|
// meta->setVal("a", "b");
|
||||||
|
// meta->setVal("c", "d");
|
||||||
|
// MetaEditWidget* mew = new MetaEditWidget(meta);
|
||||||
|
// mew->resize(300,300);
|
||||||
|
// mew->show();
|
||||||
|
|
||||||
|
|
||||||
mw = new MainWindow();
|
mw = new MainWindow();
|
||||||
mw->resize(1000, 700);
|
mw->resize(1000, 700);
|
||||||
|
|
||||||
MapView2D* mapView2D = mw->getMapView2D();
|
MapView2D* mapView2D = mw->getMapView2D();
|
||||||
MapView3D* mapView3D = mw->getMapView3D();
|
MapView3D* mapView3D = mw->getMapView3D();
|
||||||
QTreeView* layerTree = mw->getTree();
|
LayerTree* layerTree = mw->getTree();
|
||||||
|
|
||||||
|
|
||||||
// model setup
|
// model setup
|
||||||
@@ -43,11 +53,11 @@ MainController::MainController() {
|
|||||||
mapTreeModel = new MapTreeModel(mapModel);
|
mapTreeModel = new MapTreeModel(mapModel);
|
||||||
layerTree->setModel(mapTreeModel);
|
layerTree->setModel(mapTreeModel);
|
||||||
|
|
||||||
ToolMoveMap* moveMap = new ToolMoveMap();
|
moveMap = new ToolMoveMap();
|
||||||
ToolRuler* ruler = new ToolRuler();
|
ruler = new ToolRuler();
|
||||||
ToolMapZoom* mapZoom = new ToolMapZoom();
|
mapZoom = new ToolMapZoom();
|
||||||
ToolMapGrid* mapGrid = new ToolMapGrid();
|
mapGrid = new ToolMapGrid();
|
||||||
ToolSelector* mapSelector = new ToolSelector();
|
mapSelector = new ToolSelector();
|
||||||
|
|
||||||
mapView2D->getTools().addBackground(mapGrid);
|
mapView2D->getTools().addBackground(mapGrid);
|
||||||
mapView2D->getTools().addBackground(moveMap);
|
mapView2D->getTools().addBackground(moveMap);
|
||||||
@@ -58,7 +68,8 @@ MainController::MainController() {
|
|||||||
|
|
||||||
|
|
||||||
//connect(layerTree, SIGNAL(activated(QModelIndex)), this, SLOT(layerSelected(QModelIndex)));
|
//connect(layerTree, SIGNAL(activated(QModelIndex)), this, SLOT(layerSelected(QModelIndex)));
|
||||||
connect(layerTree->selectionModel(), SIGNAL(currentChanged(QModelIndex, QModelIndex)), this, SLOT(layerSelected(QModelIndex)));
|
//connect(layerTree->getTree()->selectionModel(), SIGNAL(currentChanged(QModelIndex, QModelIndex)), this, SLOT(layerSelected(QModelIndex)));
|
||||||
|
connect(layerTree, SIGNAL(layerSelected(QModelIndex)), this, SLOT(layerSelected(QModelIndex)));
|
||||||
|
|
||||||
connect(mapSelector, SIGNAL(onMapElementSelected(MapModelElement*)), this, SLOT(mapElementSelected(MapModelElement*)));
|
connect(mapSelector, SIGNAL(onMapElementSelected(MapModelElement*)), this, SLOT(mapElementSelected(MapModelElement*)));
|
||||||
connect(mw->getMapView2D(), SIGNAL(onElementChange(MV2DElement*)), this, SLOT(curMapElementChanged()));
|
connect(mw->getMapView2D(), SIGNAL(onElementChange(MV2DElement*)), this, SLOT(curMapElementChanged()));
|
||||||
@@ -66,6 +77,7 @@ MainController::MainController() {
|
|||||||
// model events
|
// model events
|
||||||
connect(mapModel, SIGNAL(aboutToReset()), this, SLOT(onMapModelAboutToReset()));
|
connect(mapModel, SIGNAL(aboutToReset()), this, SLOT(onMapModelAboutToReset()));
|
||||||
connect(mapModel, SIGNAL(reset()), this, SLOT(onMapModelReset()));
|
connect(mapModel, SIGNAL(reset()), this, SLOT(onMapModelReset()));
|
||||||
|
mapModel->addListener(this);
|
||||||
|
|
||||||
// load/save
|
// load/save
|
||||||
connect(mw->getActionWidget(), SIGNAL(onLoad()), this, SLOT(onLoad()));
|
connect(mw->getActionWidget(), SIGNAL(onLoad()), this, SLOT(onLoad()));
|
||||||
@@ -81,20 +93,18 @@ MainController::MainController() {
|
|||||||
connect(mw, &MainWindow::onGridShowEdges, [&] (const bool show) {mw->getMapView3D()->getGridRenderer()->setShowEdges(show);} );
|
connect(mw, &MainWindow::onGridShowEdges, [&] (const bool show) {mw->getMapView3D()->getGridRenderer()->setShowEdges(show);} );
|
||||||
|
|
||||||
|
|
||||||
//mapModel->load("../IndoorMap/maps/SHL21.xml");
|
mapModel->load("../IndoorMap/maps/SHL26.xml");
|
||||||
//mapModel->load("../IndoorMap/maps/test.xml");
|
//mapModel->load("../IndoorMap/maps/test.xml");
|
||||||
|
//mapModel->load("../IndoorMap/maps/APs.xml");
|
||||||
|
|
||||||
//mapModel->load("/home/toni/Documents/programme/localization/IPIN2016/competition/src/competition/map/CAR/CAR10.xml");
|
//mapModel->load("/mnt/data/workspaces/IPIN2016/IPIN2016/competition/maps/CAR/CAR9.xml");
|
||||||
mapModel->load("/home/toni/Documents/programme/localization/IPIN2016/competition/src/competition/map/UAH/UAH12_rawObstacles.xml");
|
mapModel->load("/mnt/data/workspaces/IPIN2016/IPIN2016/competition/maps/UAH/UAH9.xml");
|
||||||
//mapModel->load("/home/toni/Documents/programme/localization/IPIN2016/competition/src/competition/map/SHL/SHL25.xml");
|
|
||||||
//mapModel->load("/home/toni/Documents/programme/localization/IPIN2016/competition/src/competition/map/UJI-UB/UJI-UB5.xml");
|
|
||||||
//mapModel->load("/home/toni/Documents/programme/localization/IPIN2016/competition/src/competition/map/UJI-TI/UJI-TI4.xml");
|
|
||||||
//mapModel->load("/mnt/data/workspaces/IPIN2016/IPIN2016/competition/maps/UJI-TI/UJI-TI4.xml");
|
//mapModel->load("/mnt/data/workspaces/IPIN2016/IPIN2016/competition/maps/UJI-TI/UJI-TI4.xml");
|
||||||
//mapModel->load("/home/toni/Documents/programme/localization/IPIN2016/competition/src/competition/map/UJI-UB/UJI-UB5.xml");
|
//mapModel->load("/mnt/data/workspaces/IPIN2016/IPIN2016/competition/maps/UJI-UB/UJI-UB4.xml");
|
||||||
//mapModel->load("/mnt/data/workspaces/Indoor/tests/data/WalkHeadingMap.xml");
|
//mapModel->load("/mnt/data/workspaces/Indoor/tests/data/WalkHeadingMap.xml");
|
||||||
//mapModel->load("/mnt/data/workspaces/IPIN2016/IPIN2016/competition/maps/test.xml");
|
//mapModel->load("/mnt/data/workspaces/IPIN2016/IPIN2016/competition/maps/test.xml");
|
||||||
|
|
||||||
|
//mapModel->startEmpty();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,6 +140,10 @@ void MainController::onMapModelAboutToReset() {
|
|||||||
mw->getMapView2D()->update();
|
mw->getMapView2D()->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainController::onMapModelNeedsRepaint() {
|
||||||
|
mw->getMapView2D()->update();
|
||||||
|
}
|
||||||
|
|
||||||
void MainController::onMapModelReset() {
|
void MainController::onMapModelReset() {
|
||||||
mw->getTree()->expandAll();
|
mw->getTree()->expandAll();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,19 +4,44 @@
|
|||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QModelIndex>
|
#include <QModelIndex>
|
||||||
#include "MainWindow.h"
|
#include "MainWindow.h"
|
||||||
|
#include "mapview/model/MapModelListener.h"
|
||||||
|
|
||||||
class MapTreeModel;
|
class MapTreeModel;
|
||||||
class MapModelElement;
|
class MapModelElement;
|
||||||
class MapModel;
|
class MapModel;
|
||||||
|
|
||||||
class MainController : public QObject {
|
class ToolMoveMap;
|
||||||
|
class ToolRuler;
|
||||||
|
class ToolMapZoom;
|
||||||
|
class ToolMapGrid;
|
||||||
|
class ToolSelector;
|
||||||
|
|
||||||
|
class MainController : public QObject, public MapModelListener {
|
||||||
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
ToolMoveMap* moveMap;
|
||||||
|
ToolRuler* ruler;
|
||||||
|
ToolMapZoom* mapZoom;
|
||||||
|
ToolMapGrid* mapGrid;
|
||||||
|
ToolSelector* mapSelector;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit MainController();
|
explicit MainController();
|
||||||
|
|
||||||
void show() {mw->show();}
|
void show() {mw->show();}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
void onLayerChanged(MapLayer* layer) override;
|
||||||
|
|
||||||
|
void onLayerElementAdded(MapLayer* layer, MapModelElement* elem) override;
|
||||||
|
|
||||||
|
void onLayerElementRemoved(MapLayer* layer, const MapModelElement* elem) override;
|
||||||
|
|
||||||
|
void onLayerVisibilityChanged(MapLayer *layer, const bool visible) override;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
@@ -37,6 +62,7 @@ public slots:
|
|||||||
|
|
||||||
void onMapModelAboutToReset();
|
void onMapModelAboutToReset();
|
||||||
void onMapModelReset();
|
void onMapModelReset();
|
||||||
|
void onMapModelNeedsRepaint();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#include "params/LayerParamWidget.h"
|
#include "params/LayerParamWidget.h"
|
||||||
#include "params/ActionWidget.h"
|
#include "params/ActionWidget.h"
|
||||||
#include "params/ToolBoxWidget.h"
|
#include "params/ToolBoxWidget.h"
|
||||||
|
#include "params/LayerTree.h"
|
||||||
|
|
||||||
#include "tree/MapTreeModel.h"
|
#include "tree/MapTreeModel.h"
|
||||||
|
|
||||||
@@ -39,7 +40,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
|
|||||||
this->setStyleSheet(css);
|
this->setStyleSheet(css);
|
||||||
|
|
||||||
{
|
{
|
||||||
layerTree = new QTreeView();
|
layerTree = new LayerTree();
|
||||||
QString css;
|
QString css;
|
||||||
//css += "QTreeView::item:selected:active {background-color: #888888;}";
|
//css += "QTreeView::item:selected:active {background-color: #888888;}";
|
||||||
//css += "QTreeView::item:selected:!active {background-color: #888888;}";
|
//css += "QTreeView::item:selected:!active {background-color: #888888;}";
|
||||||
@@ -140,6 +141,3 @@ MainWindow::~MainWindow() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QTreeView* MainWindow::getTree() {
|
|
||||||
return layerTree;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ class ElementParamWidget;
|
|||||||
class LayerParamWidget;
|
class LayerParamWidget;
|
||||||
class ActionWidget;
|
class ActionWidget;
|
||||||
class ToolBoxWidget;
|
class ToolBoxWidget;
|
||||||
|
class LayerTree;
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class MainWindow;
|
class MainWindow;
|
||||||
@@ -32,9 +33,7 @@ public:
|
|||||||
LayerParamWidget* getLayerParamWidget() {return layerParamWidget;}
|
LayerParamWidget* getLayerParamWidget() {return layerParamWidget;}
|
||||||
ToolBoxWidget* getToolBoxWidget() {return toolBoxWidget;}
|
ToolBoxWidget* getToolBoxWidget() {return toolBoxWidget;}
|
||||||
ActionWidget* getActionWidget() {return actionWidget;}
|
ActionWidget* getActionWidget() {return actionWidget;}
|
||||||
|
LayerTree* getTree() {return layerTree;}
|
||||||
|
|
||||||
QTreeView* getTree();
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
@@ -47,7 +46,7 @@ signals:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::MainWindow *ui;
|
Ui::MainWindow *ui;
|
||||||
QTreeView* layerTree;
|
LayerTree* layerTree;
|
||||||
MapView2D* mapView2D;
|
MapView2D* mapView2D;
|
||||||
MapView3D* mapView3D;
|
MapView3D* mapView3D;
|
||||||
ElementParamWidget* elementParamWidget;
|
ElementParamWidget* elementParamWidget;
|
||||||
|
|||||||
20
main.cpp
20
main.cpp
@@ -11,6 +11,26 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
QApplication a(argc, argv);
|
QApplication a(argc, argv);
|
||||||
|
|
||||||
|
QString str = R"(
|
||||||
|
|
||||||
|
QDockWidget {
|
||||||
|
border: 1px solid #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDockWidget::title {
|
||||||
|
text-align: left; /* align the text to the left */
|
||||||
|
background: #ccc;
|
||||||
|
padding: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDockWidget::title:hover {
|
||||||
|
background: #bbb;
|
||||||
|
}
|
||||||
|
|
||||||
|
)";
|
||||||
|
|
||||||
|
a.setStyleSheet(str);
|
||||||
|
|
||||||
MainController mc;
|
MainController mc;
|
||||||
mc.show();
|
mc.show();
|
||||||
|
|
||||||
|
|||||||
59
mapview/2D/ClickDist.h
Normal file
59
mapview/2D/ClickDist.h
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
#ifndef CLICKDIST_H
|
||||||
|
#define CLICKDIST_H
|
||||||
|
|
||||||
|
enum class ClickDistType {
|
||||||
|
UNKNOWN,
|
||||||
|
DIRECT, // e.g. distance between cursor and an edge-point, POI, AP, Beacon, ...
|
||||||
|
CUT, // e.g. distance between cursor and an obstacle-line
|
||||||
|
};
|
||||||
|
|
||||||
|
/** describes distances between mouse-cursor and objects within the 2D view */
|
||||||
|
struct ClickDist {
|
||||||
|
|
||||||
|
/** distance in pixels */
|
||||||
|
float dst_px;
|
||||||
|
|
||||||
|
/** distance type */
|
||||||
|
ClickDistType type;
|
||||||
|
|
||||||
|
|
||||||
|
/** ctor */
|
||||||
|
ClickDist(const float dst_px, const ClickDistType type) : dst_px(dst_px), type(type) {;}
|
||||||
|
|
||||||
|
/** max-dummy */
|
||||||
|
static ClickDist max() {return ClickDist(9999999, ClickDistType::UNKNOWN);}
|
||||||
|
|
||||||
|
|
||||||
|
/** distance comparison */
|
||||||
|
bool operator < (const ClickDist o) const {
|
||||||
|
return (this->dst_px * this->mod()) < (o.dst_px * o.mod());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** multiply by constant */
|
||||||
|
ClickDist operator * (const float val) const {return ClickDist(dst_px*val, type);}
|
||||||
|
|
||||||
|
// /** weighted distance comparison based on ClickDistType */
|
||||||
|
// bool compare(const ClickDist o) const {
|
||||||
|
// return ((*this)*mod()) < (o*o.mod());
|
||||||
|
// }
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* artificially modify the distance based on the given type.
|
||||||
|
* this enhances the selection in cases of equal distance
|
||||||
|
* like a POI residing dirctly one a line
|
||||||
|
*/
|
||||||
|
float mod() const {
|
||||||
|
switch (type) {
|
||||||
|
case ClickDistType::UNKNOWN: return 1.1;
|
||||||
|
case ClickDistType::CUT: return 1.0;
|
||||||
|
case ClickDistType::DIRECT: return 0.7;
|
||||||
|
default: throw "code error";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // CLICKDIST_H
|
||||||
@@ -9,6 +9,8 @@
|
|||||||
#include <Indoor/geo/BBox2.h>
|
#include <Indoor/geo/BBox2.h>
|
||||||
#include <Indoor/geo/Line2.h>
|
#include <Indoor/geo/Line2.h>
|
||||||
|
|
||||||
|
#include "ClickDist.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* represents one drawable, selectable, editable, ...
|
* represents one drawable, selectable, editable, ...
|
||||||
* element shown within the MapView2D
|
* element shown within the MapView2D
|
||||||
@@ -29,7 +31,7 @@ public:
|
|||||||
virtual BBox2 getBoundingBox() const = 0;
|
virtual BBox2 getBoundingBox() const = 0;
|
||||||
|
|
||||||
/** get the element's minimal distance (nearest whatsoever) to the given point */
|
/** get the element's minimal distance (nearest whatsoever) to the given point */
|
||||||
virtual float getMinDistanceXY(const Point2 p) const = 0;
|
virtual ClickDist getMinDistanceXY(const Point2 p) const = 0;
|
||||||
|
|
||||||
/** repaint me */
|
/** repaint me */
|
||||||
virtual void paint(Painter& p) = 0;
|
virtual void paint(Painter& p) = 0;
|
||||||
|
|||||||
@@ -31,8 +31,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** get the element's minimal distance (nearest whatsoever) to the given point */
|
/** get the element's minimal distance (nearest whatsoever) to the given point */
|
||||||
float getMinDistanceXY(const Point2 p) const override {
|
ClickDist getMinDistanceXY(const Point2 p) const override {
|
||||||
return p.getDistance(ap->pos.xy());
|
return ClickDist(p.getDistance(ap->pos.xy()), ClickDistType::DIRECT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** repaint me */
|
/** repaint me */
|
||||||
@@ -61,7 +61,7 @@ public:
|
|||||||
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) {
|
||||||
const std::string str = ap->name + " (" + ap->name + ")";
|
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() >= 10) {
|
||||||
const std::string str = ap->name;
|
const std::string str = ap->name;
|
||||||
|
|||||||
@@ -29,8 +29,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** get the element's minimal distance (nearest whatsoever) to the given point */
|
/** get the element's minimal distance (nearest whatsoever) to the given point */
|
||||||
float getMinDistanceXY(const Point2 p) const override {
|
ClickDist getMinDistanceXY(const Point2 p) const override {
|
||||||
return p.getDistance(b->pos.xy());
|
return ClickDist(p.getDistance(b->pos.xy()), ClickDistType::DIRECT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** repaint me */
|
/** repaint me */
|
||||||
|
|||||||
@@ -30,11 +30,11 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** get the element's minimal distance (nearest whatsoever) to the given point */
|
/** get the element's minimal distance (nearest whatsoever) to the given point */
|
||||||
float getMinDistanceXY(const Point2 p) const override {
|
ClickDist getMinDistanceXY(const Point2 p) const override {
|
||||||
// std::vector<Point2> points = elevator->getPoints().points;
|
// std::vector<Point2> points = elevator->getPoints().points;
|
||||||
// points.push_back(elevator->center);
|
// points.push_back(elevator->center);
|
||||||
// auto it minEl = std::min_element(points.begin(), points.end(),
|
// auto it minEl = std::min_element(points.begin(), points.end(),
|
||||||
return p.getDistance(elevator->center);
|
return ClickDist(p.getDistance(elevator->center), ClickDistType::DIRECT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** repaint me */
|
/** repaint me */
|
||||||
|
|||||||
@@ -27,8 +27,11 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** get the element's minimal distance (nearest whatsoever) to the given point */
|
/** get the element's minimal distance (nearest whatsoever) to the given point */
|
||||||
float getMinDistanceXY(const Point2 p) const override {
|
ClickDist getMinDistanceXY(const Point2 p) const override {
|
||||||
return std::min(p.getDistance(getSelPoints()[0]), p.getDistance(getSelPoints()[1]));
|
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]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** get the element's minimal distance (nearest whatsoever) to the given point */
|
/** get the element's minimal distance (nearest whatsoever) to the given point */
|
||||||
float getMinDistanceXY(const Point2 p) const override {
|
ClickDist getMinDistanceXY(const Point2 p) const override {
|
||||||
return MapElementHelper::getLineDistanceXY(fo->from, fo->to, p);
|
return MapElementHelper::getLineDistanceXY(fo->from, fo->to, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,6 +69,12 @@ public:
|
|||||||
p.drawCircle(fo->to);
|
p.drawCircle(fo->to);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// obstacle length
|
||||||
|
if (hasFocus()) {
|
||||||
|
p.setPenBrush(Qt::black, Qt::NoBrush);
|
||||||
|
p.drawLength(fo->from, fo->to, fo->from.getDistance(fo->to));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include "MapViewElementHelper.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 {
|
||||||
|
|
||||||
@@ -27,7 +28,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** get the element's minimal distance (nearest whatsoever) to the given point */
|
/** get the element's minimal distance (nearest whatsoever) to the given point */
|
||||||
float getMinDistanceXY(const Point2 p) const override {
|
ClickDist getMinDistanceXY(const Point2 p) const override {
|
||||||
return MapElementHelper::getLineDistanceXY(fo->from, fo->to, p);
|
return MapElementHelper::getLineDistanceXY(fo->from, fo->to, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,33 +61,49 @@ public:
|
|||||||
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
|
||||||
|
p.setPenBrush(Qt::black, Qt::NoBrush);
|
||||||
|
p.drawLength(fo->from, fo->to, fo->from.getDistance(fo->to));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
//p.setPenBrush(Qt::NoPen, Qt::black);
|
||||||
|
p.drawCircle_px(fo->from, 3);
|
||||||
|
p.drawCircle_px(fo->to, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void paintDoor(Painter& p) {
|
|
||||||
|
|
||||||
QPen pen;
|
|
||||||
pen.setColor(QColor(0.5,0.5,0.5));
|
|
||||||
pen.setStyle(Qt::PenStyle::DotLine);
|
|
||||||
p.setPenBrush(pen, Qt::NoBrush);
|
|
||||||
|
|
||||||
|
|
||||||
// opening indicator
|
|
||||||
const float open = M_PI / 4;
|
|
||||||
const float len = (fo->to - fo->from).length();
|
|
||||||
const float angle1 = std::atan2(fo->to.y-fo->from.y, fo->to.x-fo->from.x);
|
|
||||||
const float angle2 = angle1 + open;
|
|
||||||
const Point2 pOpen = Point2( std::cos(angle2) * len, std::sin(angle2) * len ) + fo->from;
|
|
||||||
|
|
||||||
p.drawLine(fo->from, fo->to);
|
|
||||||
p.drawLine(fo->from, pOpen);
|
|
||||||
|
|
||||||
p.drawArc(fo->from, len, angle1, open);
|
|
||||||
//p.drawLine(fo->to, pOpen);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// void paintDoor(Painter& p) {
|
||||||
|
|
||||||
|
// QPen pen;
|
||||||
|
// pen.setColor(QColor(0.5,0.5,0.5));
|
||||||
|
// pen.setStyle(Qt::PenStyle::DotLine);
|
||||||
|
// p.setPenBrush(pen, Qt::NoBrush);
|
||||||
|
|
||||||
|
|
||||||
|
// // opening indicator
|
||||||
|
// const float open = M_PI / 4;
|
||||||
|
// const float len = (fo->to - fo->from).length();
|
||||||
|
// const float angle1 = std::atan2(fo->to.y-fo->from.y, fo->to.x-fo->from.x);
|
||||||
|
// const float angle2 = angle1 + open;
|
||||||
|
// const Point2 pOpen = Point2( std::cos(angle2) * len, std::sin(angle2) * len ) + fo->from;
|
||||||
|
|
||||||
|
// p.drawLine(fo->from, fo->to);
|
||||||
|
// p.drawLine(fo->from, pOpen);
|
||||||
|
|
||||||
|
// p.drawArc(fo->from, len, angle1, open);
|
||||||
|
// //p.drawLine(fo->to, pOpen);
|
||||||
|
|
||||||
|
// // obstacle length
|
||||||
|
// p.setPenBrush(Qt::black, Qt::NoBrush);
|
||||||
|
// p.drawLength(fo->from, fo->to, fo->from.getDistance(fo->to));
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
void onFocus() override {
|
void onFocus() override {
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,12 +26,12 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** get the element's minimal distance (nearest whatsoever) to the given point */
|
/** get the element's minimal distance (nearest whatsoever) to the given point */
|
||||||
float getMinDistanceXY(const Point2 p) const override {
|
ClickDist getMinDistanceXY(const Point2 p) const override {
|
||||||
float min = 999999;
|
ClickDist min = ClickDist::max();
|
||||||
for (int i = 0; i < (int)fo.poly.points.size()-1; ++i) {
|
for (int i = 0; i < (int)fo.poly.points.size()-1; ++i) {
|
||||||
const Point2 p1 = fo.poly.points[i];
|
const Point2 p1 = fo.poly.points[i];
|
||||||
const Point2 p2 = fo.poly.points[i+1];
|
const Point2 p2 = fo.poly.points[i+1];
|
||||||
const float dst = MapElementHelper::getLineDistanceXY(p1, p2, p);
|
const ClickDist dst = MapElementHelper::getLineDistanceXY(p1, p2, p);
|
||||||
if (dst < min) {min = dst;}
|
if (dst < min) {min = dst;}
|
||||||
}
|
}
|
||||||
return min;
|
return min;
|
||||||
|
|||||||
@@ -42,9 +42,9 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** get the element's minimal distance (nearest whatsoever) to the given point */
|
/** get the element's minimal distance (nearest whatsoever) to the given point */
|
||||||
float getMinDistanceXY(const Point2 p) const override {
|
ClickDist getMinDistanceXY(const Point2 p) const override {
|
||||||
(void) p;
|
(void) p;
|
||||||
return CFG::SEL_THRESHOLD_SIZE_PX; // we do not know the distance from the image
|
return ClickDist(CFG::SEL_THRESHOLD_SIZE_PX, ClickDistType::UNKNOWN); // we do not know the distance from the image
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void onFocus() override {
|
virtual void onFocus() override {
|
||||||
|
|||||||
@@ -30,8 +30,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** get the element's minimal distance (nearest whatsoever) to the given point */
|
/** get the element's minimal distance (nearest whatsoever) to the given point */
|
||||||
float getMinDistanceXY(const Point2 p) const override {
|
ClickDist getMinDistanceXY(const Point2 p) const override {
|
||||||
return p.getDistance(poi->pos);
|
return ClickDist(p.getDistance(poi->pos), ClickDistType::DIRECT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** repaint me */
|
/** repaint me */
|
||||||
|
|||||||
@@ -35,11 +35,11 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** get the element's minimal distance (nearest whatsoever) to the given point */
|
/** get the element's minimal distance (nearest whatsoever) to the given point */
|
||||||
float getMinDistanceXY(const Point2 p) const override {
|
ClickDist getMinDistanceXY(const Point2 p) const override {
|
||||||
|
|
||||||
auto comp = [p] (const Floorplan::StairPart& p1, const Floorplan::StairPart& p2) {
|
auto comp = [p] (const Floorplan::StairPart& p1, const Floorplan::StairPart& p2) {
|
||||||
const float d1 = MapElementHelper::getLineDistanceXY(p1.start.xy(), p1.end.xy(), p);
|
const ClickDist d1 = MapElementHelper::getLineDistanceXY(p1.start.xy(), p1.end.xy(), p);
|
||||||
const float d2 = MapElementHelper::getLineDistanceXY(p2.start.xy(), p2.end.xy(), p);
|
const ClickDist d2 = MapElementHelper::getLineDistanceXY(p2.start.xy(), p2.end.xy(), p);
|
||||||
return d1 < d2;
|
return d1 < d2;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
#include <Indoor/floorplan/v2/Floorplan.h>
|
#include <Indoor/floorplan/v2/Floorplan.h>
|
||||||
|
|
||||||
|
#include "ClickDist.h"
|
||||||
|
|
||||||
/** configuration */
|
/** configuration */
|
||||||
namespace CFG {
|
namespace CFG {
|
||||||
const float MOVE_SNAP_SIZE_M = 0.1f; // in meter (= map-space)
|
const float MOVE_SNAP_SIZE_M = 0.1f; // in meter (= map-space)
|
||||||
@@ -33,7 +35,7 @@ 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 float getLineDistanceXY(Point2 p1, Point2 p2, Point2 dst) {
|
static ClickDist getLineDistanceXY(Point2 p1, Point2 p2, Point2 dst) {
|
||||||
|
|
||||||
// the line (p1, p2)
|
// the line (p1, p2)
|
||||||
const Line2 line(p1, p2);
|
const Line2 line(p1, p2);
|
||||||
@@ -46,20 +48,21 @@ public:
|
|||||||
|
|
||||||
// calculate the cut betwen L and (p1,p2) (if any)
|
// calculate the cut betwen L and (p1,p2) (if any)
|
||||||
Point2 cut(0,0);
|
Point2 cut(0,0);
|
||||||
|
ClickDist cutDist(99999999, ClickDistType::CUT);
|
||||||
if (line.getSegmentIntersection(perb, cut)) {
|
if (line.getSegmentIntersection(perb, cut)) {
|
||||||
|
|
||||||
// distance between cut-point and mouse
|
// distance between cut-point and mouse
|
||||||
return cut.getDistance(dst);
|
cutDist.dst_px = cut.getDistance(dst);
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// no cut detected
|
|
||||||
const float d1 = p1.getDistance(dst);
|
|
||||||
const float d2 = p2.getDistance(dst);
|
|
||||||
return std::min(d1, d2);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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) {
|
static QPen getPen(Floorplan::Material mat, Floorplan::ObstacleType type, bool focus) {
|
||||||
|
|||||||
@@ -69,6 +69,11 @@ public:
|
|||||||
p->drawEllipse(s.xms(center.x)-r, s.yms(center.y)-r, 2*r, 2*r);
|
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) {
|
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));
|
p->drawLine(s.xms(x1), s.yms(y1), s.xms(x2), s.yms(y2));
|
||||||
}
|
}
|
||||||
@@ -115,6 +120,16 @@ public:
|
|||||||
p->drawImage(s.xms(pt.x)-img.width()/2, s.yms(pt.y)-img.height()/2, 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) {
|
||||||
|
if (p1.x < p2.x) {swap(p1, p2);}
|
||||||
|
const Point2 center_m = (p1 + p2) / 2;
|
||||||
|
Point2 dir_px = (p2 - p1).perpendicular().normalized() * 5;
|
||||||
|
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 QBrush& brush) { p->setBrush(brush); }
|
||||||
void setBrush(const Qt::BrushStyle& brush) { p->setBrush(brush); }
|
void setBrush(const Qt::BrushStyle& brush) { p->setBrush(brush); }
|
||||||
|
|
||||||
|
|||||||
@@ -20,9 +20,9 @@ public:
|
|||||||
Scaler& s = m->getScaler();
|
Scaler& s = m->getScaler();
|
||||||
|
|
||||||
if (e->delta() < 0) {
|
if (e->delta() < 0) {
|
||||||
s.setScale(s.getScale() * 0.5);
|
s.setScale(s.getScale() * 0.75);
|
||||||
} else {
|
} else {
|
||||||
s.setScale(s.getScale() / 0.5);
|
s.setScale(s.getScale() / 0.75);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s.getScale() > 1000) {s.setScale(1000);}
|
if (s.getScale() > 1000) {s.setScale(1000);}
|
||||||
|
|||||||
0
mapview/2D/tools/ToolMeasure.cpp
Normal file
0
mapview/2D/tools/ToolMeasure.cpp
Normal file
132
mapview/2D/tools/ToolMeasure.h
Normal file
132
mapview/2D/tools/ToolMeasure.h
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
#ifndef TOOLMEASURE_H
|
||||||
|
#define TOOLMEASURE_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "Tool.h"
|
||||||
|
#include "../MapView2D.h"
|
||||||
|
|
||||||
|
#include "../../model/MapModelElement.h"
|
||||||
|
#include "../../model/MapModel.h"
|
||||||
|
#include "../MapViewElementHelper.h"
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this tool allows:
|
||||||
|
* - selecting elements within the 2D view (focus/unfocus)
|
||||||
|
* - selecting and moving nodes of elements inheriting from HasMoveableNodes
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class ToolMeasure : public Tool {
|
||||||
|
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/** register this tool into the given tools-queue */
|
||||||
|
Tools& tools;
|
||||||
|
Tool* oldMainTool;
|
||||||
|
|
||||||
|
std::vector<Point2> pts_m;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/** ctor */
|
||||||
|
ToolMeasure(Tools& tools) : tools(tools) {
|
||||||
|
|
||||||
|
oldMainTool = tools.getMain(); // keep the current tool to reset it later
|
||||||
|
tools.setMain(this);
|
||||||
|
|
||||||
|
resetMe();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/** dtor */
|
||||||
|
virtual ~ToolMeasure() {
|
||||||
|
tools.setMain(oldMainTool); // reset to the previous tool
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string getName() const {
|
||||||
|
return "Measure";
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool mousePressEvent(MapView2D*, QMouseEvent* e) override {
|
||||||
|
if (e->button() == Qt::MouseButton::LeftButton) {
|
||||||
|
pts_m.push_back(pts_m.back());
|
||||||
|
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);
|
||||||
|
pts_m.back() = onMap;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool mouseReleaseEvent(MapView2D*, QMouseEvent* e) override {
|
||||||
|
if (e->button() == Qt::MouseButton::LeftButton) {
|
||||||
|
return true;
|
||||||
|
} else if (e->button() == Qt::MouseButton::RightButton) {
|
||||||
|
resetMe();
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool keyPressEvent(MapView2D* m, QKeyEvent* e) override {
|
||||||
|
(void) m;
|
||||||
|
if (e->key() == Qt::Key_Escape) {
|
||||||
|
disableMe();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void paintAfter(MapView2D*, Painter& p) override {
|
||||||
|
|
||||||
|
if (pts_m.size() < 1) {return;}
|
||||||
|
|
||||||
|
p.setPen(Qt::black);
|
||||||
|
|
||||||
|
for (const Point2 p_m : pts_m) {
|
||||||
|
p.drawCircle(p_m);
|
||||||
|
}
|
||||||
|
|
||||||
|
float totalLen_m = 0;
|
||||||
|
for (size_t i = 0; i < pts_m.size() - 1; ++i) {
|
||||||
|
const Point2 p1 = pts_m[i];
|
||||||
|
const Point2 p2 = pts_m[i+1];
|
||||||
|
const float len_m = p1.getDistance(p2);
|
||||||
|
p.drawLine(p1, p2);
|
||||||
|
p.drawLength(p1, p2, len_m);
|
||||||
|
totalLen_m += len_m;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pts_m.size() > 1) {
|
||||||
|
emit onHelpTextChange("total length is: " + QString::number(totalLen_m) + "m | right-click to restart");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
|
||||||
|
void resetMe() {
|
||||||
|
pts_m.resize(1);
|
||||||
|
emit onHelpTextChange("select the starting point for measuring");
|
||||||
|
}
|
||||||
|
|
||||||
|
/** finish creating new elements */
|
||||||
|
void disableMe() {
|
||||||
|
delete this; // see dtor!
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // TOOLMEASURE_H
|
||||||
@@ -96,9 +96,19 @@ public:
|
|||||||
p.p->drawLine(mouseX, 0, mouseX, rs);
|
p.p->drawLine(mouseX, 0, mouseX, rs);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
p.setPenBrush(Qt::black, Qt::NoBrush);
|
p.setPenBrush(Qt::black, Qt::NoBrush);
|
||||||
char buf[128];
|
char buf[128];
|
||||||
|
|
||||||
|
// coordinates
|
||||||
|
QRect ru(0,0,rs-1,rs-1);
|
||||||
|
p.p->fillRect(ru, Qt::white);
|
||||||
|
std::sprintf(buf, "%.1f", p.getScaler().xsm(this->mouseX));
|
||||||
|
p.p->drawText(5,15, buf);
|
||||||
|
std::sprintf(buf, "%.1f", p.getScaler().ysm(this->mouseY));
|
||||||
|
p.p->drawText(5,30, buf);
|
||||||
|
|
||||||
// y-axis
|
// y-axis
|
||||||
p.p->setClipRect(ry);
|
p.p->setClipRect(ry);
|
||||||
for (float y = r.y0; y <= r.y1; y += step) {
|
for (float y = r.y0; y <= r.y1; y += step) {
|
||||||
@@ -141,6 +151,8 @@ public:
|
|||||||
|
|
||||||
p.p->setClipping(false);
|
p.p->setClipping(false);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// snapped dot
|
// snapped dot
|
||||||
const Point2 mouseOnScreen(mouseX, mouseY);
|
const Point2 mouseOnScreen(mouseX, mouseY);
|
||||||
const Point2 mouseInMap = p.s.sm(mouseOnScreen);
|
const Point2 mouseInMap = p.s.sm(mouseOnScreen);
|
||||||
|
|||||||
@@ -46,6 +46,15 @@ public:
|
|||||||
setFocused(m, nullptr);
|
setFocused(m, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief change the currently focused element. throws an event.
|
||||||
|
* @param el the to-be-focused element or null
|
||||||
|
* @return true if the focused element has changed. false otherwise
|
||||||
|
*/
|
||||||
|
bool focus(MapView2D* v, MapModelElement* el) {
|
||||||
|
setFocused(v, el);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void processUnfocus(MapView2D* m, MapModelElement* elem) {
|
void processUnfocus(MapView2D* m, MapModelElement* elem) {
|
||||||
@@ -202,9 +211,11 @@ private:
|
|||||||
|
|
||||||
const float g = m->getScaler().sm(15); // increase each BBox by 15 px (needed mainly for hor/ver lines)
|
const float g = m->getScaler().sm(15); // increase each BBox by 15 px (needed mainly for hor/ver lines)
|
||||||
|
|
||||||
|
#warning "which elements to select? among all currently visible? or only among the selected layer?"
|
||||||
// get all elements with bounding-box matchings
|
// get all elements with bounding-box matchings
|
||||||
std::vector<MapModelElement*> possible;
|
std::vector<MapModelElement*> possible;
|
||||||
for (MapModelElement* el : m->getModel()->getSelectedLayerElements()) {
|
// for (MapModelElement* el : m->getModel()->getSelectedLayerElements()) {
|
||||||
|
for (MapModelElement* el : m->getModel()->getVisibleElements()) {
|
||||||
if (!el->getMV2D()) {continue;}
|
if (!el->getMV2D()) {continue;}
|
||||||
BBox2 bbox = el->getMV2D()->getBoundingBox(); // elements 2D bbox
|
BBox2 bbox = el->getMV2D()->getBoundingBox(); // elements 2D bbox
|
||||||
bbox.grow(Point2(g, g)); // grow a little (needed for straight lines)
|
bbox.grow(Point2(g, g)); // grow a little (needed for straight lines)
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ protected:
|
|||||||
/** repaint me */
|
/** repaint me */
|
||||||
void paintGL() override {
|
void paintGL() override {
|
||||||
|
|
||||||
Cube cube(ap->getPos(f), 0.5);
|
Cube cube(ap->getPos(f), 0.25);
|
||||||
cube.paintGL();
|
cube.paintGL();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ protected:
|
|||||||
glColor3f(1,1,1);
|
glColor3f(1,1,1);
|
||||||
break;
|
break;
|
||||||
case Floorplan::OutlineMethod::REMOVE:
|
case Floorplan::OutlineMethod::REMOVE:
|
||||||
glColor3f(0.2, 0.2, 0.2);
|
glColor3f(0.3, 0.3, 0.3);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,11 +32,12 @@ void MapView3D::initializeGL() {
|
|||||||
|
|
||||||
QGLWidget::initializeGL();
|
QGLWidget::initializeGL();
|
||||||
|
|
||||||
//glCullFace(GL_FRONT);
|
glCullFace(GL_FRONT);
|
||||||
|
//glDisable(GL_CULL_FACE);
|
||||||
|
glEnable(GL_CULL_FACE);
|
||||||
|
|
||||||
// culling, lighting, depth-test, ...
|
// culling, lighting, depth-test, ...
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
glEnable(GL_CULL_FACE);
|
|
||||||
glShadeModel(GL_SMOOTH);
|
glShadeModel(GL_SMOOTH);
|
||||||
|
|
||||||
glEnable(GL_MULTISAMPLE);
|
glEnable(GL_MULTISAMPLE);
|
||||||
|
|||||||
21
mapview/model/IHasEditableMeta.h
Normal file
21
mapview/model/IHasEditableMeta.h
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#ifndef IHASEDITABLEMETA_H
|
||||||
|
#define IHASEDITABLEMETA_H
|
||||||
|
|
||||||
|
#include <Indoor/floorplan/v2/Floorplan.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* interface for all classes that provide editable meta information
|
||||||
|
*/
|
||||||
|
class IHasEditableMeta {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/** get the meta-information object [if any] */
|
||||||
|
virtual Floorplan::Meta* getMeta() = 0;
|
||||||
|
|
||||||
|
/** set/overwrite the meta-information object */
|
||||||
|
virtual void setMeta(Floorplan::Meta* meta) = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // IHASEDITABLEMETA_H
|
||||||
@@ -26,16 +26,18 @@ class MMFloor : public MapLayer, public IHasParams {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
Floorplan::IndoorMap* map;
|
||||||
|
|
||||||
/** the underlying data-structure */
|
/** the underlying data-structure */
|
||||||
Floorplan::Floor* floor;
|
Floorplan::Floor* floor;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/** ctor. existing floor */
|
/** ctor. existing floor */
|
||||||
MMFloor(MapLayer* parent, Floorplan::Floor* floor) : MapLayer(parent, MapLayerType::FLOOR), floor(floor) {
|
MMFloor(MapLayer* parent, Floorplan::IndoorMap* map, Floorplan::Floor* floor) : MapLayer(parent, MapLayerType::FLOOR), map(map), floor(floor) {
|
||||||
|
|
||||||
new MMFloorUnderlays(this, floor);
|
new MMFloorUnderlays(this, floor);
|
||||||
elements.push_back(new MMFloorOutline(this, floor));
|
new MMFloorOutline(this, floor);
|
||||||
new MMFloorObstacles(this, floor);
|
new MMFloorObstacles(this, floor);
|
||||||
new MMFloorAccessPoints(this, floor);
|
new MMFloorAccessPoints(this, floor);
|
||||||
new MMFloorBeacons(this, floor);
|
new MMFloorBeacons(this, floor);
|
||||||
@@ -58,12 +60,14 @@ public:
|
|||||||
std::string getLayerName() const override {return floor->name;}
|
std::string getLayerName() const override {return floor->name;}
|
||||||
|
|
||||||
virtual int getNumParams() const override {
|
virtual int getNumParams() const override {
|
||||||
return 1;
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Param getParamDesc(const int idx) const override {
|
virtual Param getParamDesc(const int idx) const override {
|
||||||
switch(idx) {
|
switch(idx) {
|
||||||
case 0: return Param("anem", ParamType::STRING);
|
case 0: return Param("name", ParamType::STRING);
|
||||||
|
case 1: return Param("height", ParamType::FLOAT);
|
||||||
|
case 2: return Param("at height", ParamType::FLOAT);
|
||||||
}
|
}
|
||||||
throw 1;
|
throw 1;
|
||||||
}
|
}
|
||||||
@@ -71,6 +75,8 @@ public:
|
|||||||
virtual ParamValue getParamValue(const int idx) const override {
|
virtual ParamValue getParamValue(const int idx) const override {
|
||||||
switch(idx) {
|
switch(idx) {
|
||||||
case 0: return floor->name;
|
case 0: return floor->name;
|
||||||
|
case 1: return floor->height;
|
||||||
|
case 2: return floor->atHeight;
|
||||||
}
|
}
|
||||||
throw 1;
|
throw 1;
|
||||||
}
|
}
|
||||||
@@ -78,9 +84,16 @@ public:
|
|||||||
virtual void setParamValue(const int idx, const ParamValue& val) const override {
|
virtual void setParamValue(const int idx, const ParamValue& val) const override {
|
||||||
switch(idx) {
|
switch(idx) {
|
||||||
case 0: floor->name = val.toString(); break;
|
case 0: floor->name = val.toString(); break;
|
||||||
|
case 1: floor->height = val.toFloat(); break;
|
||||||
|
case 2: floor->atHeight = val.toFloat(); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void deleteMe() {
|
||||||
|
parent->removeSublayer(this);
|
||||||
|
map->floors.erase(std::remove(map->floors.begin(), map->floors.end(), floor), map->floors.end());
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MMFLOOR_H
|
#endif // MMFLOOR_H
|
||||||
|
|||||||
@@ -3,13 +3,14 @@
|
|||||||
|
|
||||||
#include "MapModelElement.h"
|
#include "MapModelElement.h"
|
||||||
#include "IHasParams.h"
|
#include "IHasParams.h"
|
||||||
|
#include "IHasEditableMeta.h"
|
||||||
|
|
||||||
#include "../2D/MV2DElementAccessPoint.h"
|
#include "../2D/MV2DElementAccessPoint.h"
|
||||||
#include "../3D/MV3DElementAccessPoint.h"
|
#include "../3D/MV3DElementAccessPoint.h"
|
||||||
|
|
||||||
#include <Indoor/floorplan/v2/Floorplan.h>
|
#include <Indoor/floorplan/v2/Floorplan.h>
|
||||||
|
|
||||||
class MMFloorAccessPoint : public MapModelElement, public IHasParams {
|
class MMFloorAccessPoint : public MapModelElement, public IHasParams, public IHasEditableMeta {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@@ -26,7 +27,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual int getNumParams() const override {
|
virtual int getNumParams() const override {
|
||||||
return 3;
|
return 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Param getParamDesc(const int idx) const override {
|
virtual Param getParamDesc(const int idx) const override {
|
||||||
@@ -34,6 +35,9 @@ public:
|
|||||||
case 0: return Param("name", ParamType::STRING);
|
case 0: return Param("name", ParamType::STRING);
|
||||||
case 1: return Param("MAC", ParamType::STRING);
|
case 1: return Param("MAC", ParamType::STRING);
|
||||||
case 2: return Param("Position", ParamType::POINT3);
|
case 2: return Param("Position", ParamType::POINT3);
|
||||||
|
case 3: return Param("TXP", ParamType::FLOAT);
|
||||||
|
case 4: return Param("EXP", ParamType::FLOAT);
|
||||||
|
case 5: return Param("WAF", ParamType::FLOAT);
|
||||||
}
|
}
|
||||||
throw 1;
|
throw 1;
|
||||||
}
|
}
|
||||||
@@ -43,6 +47,9 @@ public:
|
|||||||
case 0: return ap->name;
|
case 0: return ap->name;
|
||||||
case 1: return ap->mac;
|
case 1: return ap->mac;
|
||||||
case 2: return ap->pos;
|
case 2: return ap->pos;
|
||||||
|
case 3: return ap->model.txp;
|
||||||
|
case 4: return ap->model.exp;
|
||||||
|
case 5: return ap->model.waf;
|
||||||
}
|
}
|
||||||
throw 1;
|
throw 1;
|
||||||
}
|
}
|
||||||
@@ -52,9 +59,20 @@ public:
|
|||||||
case 0: ap->name = val.toString(); break;
|
case 0: ap->name = val.toString(); break;
|
||||||
case 1: ap->mac = val.toString(); break;
|
case 1: ap->mac = val.toString(); break;
|
||||||
case 2: ap->pos = val.toPoint3(); break;
|
case 2: ap->pos = val.toPoint3(); break;
|
||||||
|
case 3: ap->model.txp = val.toFloat(); break;
|
||||||
|
case 4: ap->model.exp = val.toFloat(); break;
|
||||||
|
case 5: ap->model.waf = val.toFloat(); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual Floorplan::Meta* getMeta() override {
|
||||||
|
return ap->getMeta();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void setMeta(Floorplan::Meta* meta) override {
|
||||||
|
ap->setMeta(meta);
|
||||||
|
}
|
||||||
|
|
||||||
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;}
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ public:
|
|||||||
|
|
||||||
// add all APs
|
// add all APs
|
||||||
for (Floorplan::AccessPoint* ap : floor->accesspoints) {
|
for (Floorplan::AccessPoint* ap : floor->accesspoints) {
|
||||||
elements.push_back(new MMFloorAccessPoint(this, floor, ap));
|
addElement(new MMFloorAccessPoint(this, floor, ap));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -36,7 +36,7 @@ public:
|
|||||||
floor->accesspoints.push_back(ap);
|
floor->accesspoints.push_back(ap);
|
||||||
|
|
||||||
// add to myself as element
|
// add to myself as element
|
||||||
elements.push_back(new MMFloorAccessPoint(this, floor, ap));
|
addElement(new MMFloorAccessPoint(this, floor, ap));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,14 +23,20 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual int getNumParams() const override {
|
virtual int getNumParams() const override {
|
||||||
return 3;
|
return 9;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Param getParamDesc(const int idx) const override {
|
virtual Param getParamDesc(const int idx) const override {
|
||||||
switch(idx) {
|
switch(idx) {
|
||||||
case 0: return Param("name", ParamType::STRING);
|
case 0: return Param("name", ParamType::STRING);
|
||||||
case 1: return Param("MAC", ParamType::STRING);
|
case 1: return Param("Position", ParamType::POINT3);
|
||||||
case 2: return Param("Position", ParamType::POINT3);
|
case 2: return Param("MAC", ParamType::STRING);
|
||||||
|
case 3: return Param("major", ParamType::STRING);
|
||||||
|
case 4: return Param("minor", ParamType::STRING);
|
||||||
|
case 5: return Param("UUDI", ParamType::STRING);
|
||||||
|
case 6: return Param("TXP", ParamType::FLOAT);
|
||||||
|
case 7: return Param("EXP", ParamType::FLOAT);
|
||||||
|
case 8: return Param("WAF", ParamType::FLOAT);
|
||||||
}
|
}
|
||||||
throw 1;
|
throw 1;
|
||||||
}
|
}
|
||||||
@@ -38,8 +44,14 @@ public:
|
|||||||
virtual ParamValue getParamValue(const int idx) const override {
|
virtual ParamValue getParamValue(const int idx) const override {
|
||||||
switch(idx) {
|
switch(idx) {
|
||||||
case 0: return b->name;
|
case 0: return b->name;
|
||||||
case 1: return b->mac;
|
case 1: return b->pos;
|
||||||
case 2: return b->pos;
|
case 2: return b->mac;
|
||||||
|
case 3: return b->major;
|
||||||
|
case 4: return b->minor;
|
||||||
|
case 5: return b->uuid;
|
||||||
|
case 6: return b->model.txp;
|
||||||
|
case 7: return b->model.exp;
|
||||||
|
case 8: return b->model.waf;
|
||||||
}
|
}
|
||||||
throw 1;
|
throw 1;
|
||||||
}
|
}
|
||||||
@@ -47,8 +59,14 @@ public:
|
|||||||
virtual void setParamValue(const int idx, const ParamValue& val) const override {
|
virtual void setParamValue(const int idx, const ParamValue& val) const override {
|
||||||
switch(idx) {
|
switch(idx) {
|
||||||
case 0: b->name = val.toString(); break;
|
case 0: b->name = val.toString(); break;
|
||||||
case 1: b->mac = val.toString(); break;
|
case 1: b->pos = val.toPoint3(); break;
|
||||||
case 2: b->pos = val.toPoint3(); break;
|
case 2: b->mac = val.toString(); break;
|
||||||
|
case 3: b->major = val.toString(); break;
|
||||||
|
case 4: b->minor = val.toString(); break;
|
||||||
|
case 5: b->uuid = val.toString(); break;
|
||||||
|
case 6: b->uuid = val.toFloat(); break;
|
||||||
|
case 7: b->uuid = val.toFloat(); break;
|
||||||
|
case 8: b->uuid = val.toFloat(); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ public:
|
|||||||
|
|
||||||
// add all Beacons
|
// add all Beacons
|
||||||
for (Floorplan::Beacon* b : floor->beacons) {
|
for (Floorplan::Beacon* b : floor->beacons) {
|
||||||
elements.push_back(new MMFloorBeacon(this, floor, b));
|
addElement(new MMFloorBeacon(this, floor, b));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -36,7 +36,7 @@ public:
|
|||||||
floor->beacons.push_back(b);
|
floor->beacons.push_back(b);
|
||||||
|
|
||||||
// add to myself as element
|
// add to myself as element
|
||||||
elements.push_back(new MMFloorBeacon(this, floor, b));
|
addElement(new MMFloorBeacon(this, floor, b));
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ public:
|
|||||||
|
|
||||||
// add all elevators
|
// add all elevators
|
||||||
for (Floorplan::Elevator* elevator : floor->elevators) {
|
for (Floorplan::Elevator* elevator : floor->elevators) {
|
||||||
elements.push_back(new MMFloorElevator(this, floor, elevator));
|
addElement(new MMFloorElevator(this, floor, elevator));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -37,7 +37,7 @@ public:
|
|||||||
floor->elevators.push_back(elevator);
|
floor->elevators.push_back(elevator);
|
||||||
|
|
||||||
// add to myself as element
|
// add to myself as element
|
||||||
elements.push_back(new MMFloorElevator(this, floor, elevator));
|
addElement(new MMFloorElevator(this, floor, elevator));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include "IHasMaterial.h"
|
#include "IHasMaterial.h"
|
||||||
#include "IHasObstacleType.h"
|
#include "IHasObstacleType.h"
|
||||||
|
#include "IHasParams.h"
|
||||||
|
|
||||||
#include "../2D/MV2DElementFloorObstacleLine.h"
|
#include "../2D/MV2DElementFloorObstacleLine.h"
|
||||||
#include "../3D/MV3DElementFloorObstacleWall.h"
|
#include "../3D/MV3DElementFloorObstacleWall.h"
|
||||||
@@ -13,7 +14,7 @@
|
|||||||
#include <Indoor/floorplan/v2/Floorplan.h>
|
#include <Indoor/floorplan/v2/Floorplan.h>
|
||||||
|
|
||||||
|
|
||||||
class MMFloorObstacleLine : public MapModelElement, public IHasMaterial, public IHasObstacleType {
|
class MMFloorObstacleLine : public MapModelElement, public IHasMaterial, public IHasObstacleType, public IHasParams {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@@ -43,6 +44,31 @@ public:
|
|||||||
mf->obstacles.erase(std::remove(mf->obstacles.begin(), mf->obstacles.end(), fo), mf->obstacles.end());
|
mf->obstacles.erase(std::remove(mf->obstacles.begin(), mf->obstacles.end(), fo), mf->obstacles.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virtual int getNumParams() const override {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual Param getParamDesc(const int idx) const override {
|
||||||
|
switch(idx) {
|
||||||
|
case 0: return Param("length", ParamType::FLOAT, true);
|
||||||
|
}
|
||||||
|
throw 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ParamValue getParamValue(const int idx) const override {
|
||||||
|
switch(idx) {
|
||||||
|
case 0: return fo->from.getDistance(fo->to);
|
||||||
|
}
|
||||||
|
throw 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void setParamValue(const int idx, const ParamValue& val) const override {
|
||||||
|
switch(idx) {
|
||||||
|
case 0: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MAPELEMENTOBSTACLE_H
|
#endif // MAPELEMENTOBSTACLE_H
|
||||||
|
|||||||
@@ -23,11 +23,11 @@ public:
|
|||||||
// the obstacles
|
// the obstacles
|
||||||
for (Floorplan::FloorObstacle* o : floor->obstacles) {
|
for (Floorplan::FloorObstacle* o : floor->obstacles) {
|
||||||
if (dynamic_cast<Floorplan::FloorObstacleLine*>(o)) {
|
if (dynamic_cast<Floorplan::FloorObstacleLine*>(o)) {
|
||||||
elements.push_back(new MMFloorObstacleLine(this, floor, (Floorplan::FloorObstacleLine*)o));
|
addElement(new MMFloorObstacleLine(this, floor, (Floorplan::FloorObstacleLine*)o));
|
||||||
} else if (dynamic_cast<Floorplan::FloorObstacleCircle*>(o)) {
|
} else if (dynamic_cast<Floorplan::FloorObstacleCircle*>(o)) {
|
||||||
elements.push_back(new MMFloorObstacleCircle(this, floor, (Floorplan::FloorObstacleCircle*)o));
|
addElement(new MMFloorObstacleCircle(this, floor, (Floorplan::FloorObstacleCircle*)o));
|
||||||
} else if (dynamic_cast<Floorplan::FloorObstacleDoor*>(o)) {
|
} else if (dynamic_cast<Floorplan::FloorObstacleDoor*>(o)) {
|
||||||
elements.push_back(new MMFloorObstacleDoor(this, floor, (Floorplan::FloorObstacleDoor*)o));
|
addElement(new MMFloorObstacleDoor(this, floor, (Floorplan::FloorObstacleDoor*)o));
|
||||||
} else {
|
} else {
|
||||||
throw new Exception("todo: not yet implemented obstacle type");
|
throw new Exception("todo: not yet implemented obstacle type");
|
||||||
}
|
}
|
||||||
@@ -46,7 +46,7 @@ public:
|
|||||||
|
|
||||||
// add to myself as element
|
// add to myself as element
|
||||||
MMFloorObstacleDoor* mm = new MMFloorObstacleDoor(this, floor, obs);
|
MMFloorObstacleDoor* mm = new MMFloorObstacleDoor(this, floor, obs);
|
||||||
elements.push_back(mm);
|
addElement(mm);
|
||||||
return mm;
|
return mm;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -59,7 +59,7 @@ public:
|
|||||||
|
|
||||||
// add to myself as element
|
// add to myself as element
|
||||||
MMFloorObstacleLine* mm = new MMFloorObstacleLine(this, floor, obs);
|
MMFloorObstacleLine* mm = new MMFloorObstacleLine(this, floor, obs);
|
||||||
elements.push_back(mm);
|
addElement(mm);
|
||||||
return mm;
|
return mm;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -71,7 +71,7 @@ public:
|
|||||||
floor->obstacles.push_back(obs);
|
floor->obstacles.push_back(obs);
|
||||||
|
|
||||||
// add to myself as element
|
// add to myself as element
|
||||||
elements.push_back(new MMFloorObstacleCircle(this, floor, obs));
|
addElement(new MMFloorObstacleCircle(this, floor, obs));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,37 +3,38 @@
|
|||||||
|
|
||||||
#include "MapLayer.h"
|
#include "MapLayer.h"
|
||||||
#include "MMFloorOutlinePolygon.h"
|
#include "MMFloorOutlinePolygon.h"
|
||||||
#include "../3D/MV3DElementFloorOutline.h"
|
#include "MMFloorOutlinePolygonCombined.h"
|
||||||
|
|
||||||
|
#include "../3D/MV3DElementFloorOutline.h"
|
||||||
|
|
||||||
#include <Indoor/floorplan/v2/Floorplan.h>
|
#include <Indoor/floorplan/v2/Floorplan.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* layer containing all elements describing a floor's outline
|
* layer containing all elements describing a floor's outline
|
||||||
*/
|
*/
|
||||||
class MMFloorOutline : public MapLayer, public MapModelElement {
|
class MMFloorOutline : public MapLayer {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/** the underlying model */
|
/** the underlying model */
|
||||||
Floorplan::Floor* floor;
|
Floorplan::Floor* floor;
|
||||||
|
|
||||||
MV3DElementFloorOutline mv3d;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/** ctor with the underlying model */
|
/** ctor with the underlying model */
|
||||||
MMFloorOutline(MapLayer* parent, Floorplan::Floor* floor) :
|
MMFloorOutline(MapLayer* parent, Floorplan::Floor* floor) :
|
||||||
MapLayer(parent, MapLayerType::FLOOR_GROUND), MapModelElement(parent), floor(floor), mv3d(floor, &floor->outline) {
|
MapLayer(parent, MapLayerType::FLOOR_GROUND), floor(floor) {
|
||||||
|
|
||||||
// the outline
|
// each polygon that is part of the outline
|
||||||
for (Floorplan::FloorOutlinePolygon* poly : floor->outline) {
|
for (Floorplan::FloorOutlinePolygon* poly : floor->outline) {
|
||||||
elements.push_back(new MMFloorOutlinePolygon(this, floor, poly));
|
addElement(new MMFloorOutlinePolygon(this, floor, poly));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
// for 3D, alle polygons [add/remove] are combined into one renderable polygons
|
||||||
|
addElement(new MMFloorOutlinePolygonCombined(this, floor));
|
||||||
|
|
||||||
MV3DElement* getMV3D() const override {return (MV3DElement*) &mv3d;}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** get the corresponding floor from the underlying model */
|
/** get the corresponding floor from the underlying model */
|
||||||
@@ -46,7 +47,7 @@ public:
|
|||||||
floor->outline.push_back(poly);
|
floor->outline.push_back(poly);
|
||||||
|
|
||||||
// add to myself as element
|
// add to myself as element
|
||||||
elements.push_back(new MMFloorOutlinePolygon(this, floor, poly));
|
addElement(new MMFloorOutlinePolygon(this, floor, poly));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
41
mapview/model/MMFloorOutlinePolygonCombined.h
Normal file
41
mapview/model/MMFloorOutlinePolygonCombined.h
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
#ifndef MMFLOOROUTLINEPOLYGONCOMBINED_H
|
||||||
|
#define MMFLOOROUTLINEPOLYGONCOMBINED_H
|
||||||
|
|
||||||
|
#include "MapLayer.h"
|
||||||
|
#include "MMFloorOutlinePolygon.h"
|
||||||
|
#include "../3D/MV3DElementFloorOutline.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include <Indoor/floorplan/v2/Floorplan.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this element combines all polygons of one layer
|
||||||
|
* into one large, 3D renderable polygon
|
||||||
|
*/
|
||||||
|
class MMFloorOutlinePolygonCombined : public MapModelElement {
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
/** the underlying model */
|
||||||
|
Floorplan::Floor* floor;
|
||||||
|
|
||||||
|
MV3DElementFloorOutline mv3d;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/** ctor with the underlying model */
|
||||||
|
MMFloorOutlinePolygonCombined(MapLayer* parent, Floorplan::Floor* floor) :
|
||||||
|
MapModelElement(parent), floor(floor), mv3d(floor, &floor->outline) {
|
||||||
|
|
||||||
|
;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
MV3DElement* getMV3D() const override {return (MV3DElement*) &mv3d;}
|
||||||
|
|
||||||
|
/** get the corresponding floor from the underlying model */
|
||||||
|
Floorplan::Floor* getFloor() {return floor;}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MMFLOOROUTLINEPOLYGONCOMBINED_H
|
||||||
@@ -20,7 +20,7 @@ public:
|
|||||||
|
|
||||||
// the POIs
|
// the POIs
|
||||||
for (Floorplan::POI* poi : floor->pois) {
|
for (Floorplan::POI* poi : floor->pois) {
|
||||||
elements.push_back(new MMFloorPOI(this, floor, poi));
|
addElement(new MMFloorPOI(this, floor, poi));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -35,7 +35,7 @@ public:
|
|||||||
floor->pois.push_back(poi);
|
floor->pois.push_back(poi);
|
||||||
|
|
||||||
// add to myself as element
|
// add to myself as element
|
||||||
elements.push_back(new MMFloorPOI(this, floor, poi));
|
addElement(new MMFloorPOI(this, floor, poi));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ public:
|
|||||||
// add all floors
|
// add all floors
|
||||||
for (Floorplan::Stair* stair : floor->stairs) {
|
for (Floorplan::Stair* stair : floor->stairs) {
|
||||||
if (dynamic_cast<Floorplan::StairFreeform*>(stair)) {
|
if (dynamic_cast<Floorplan::StairFreeform*>(stair)) {
|
||||||
elements.push_back( new MMFloorStair(this, floor, (Floorplan::StairFreeform*)stair) );
|
addElement( new MMFloorStair(this, floor, (Floorplan::StairFreeform*)stair) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,7 +35,7 @@ public:
|
|||||||
floor->stairs.push_back(stair);
|
floor->stairs.push_back(stair);
|
||||||
|
|
||||||
// add to myself as element
|
// add to myself as element
|
||||||
elements.push_back(new MMFloorStair(this, floor, stair));
|
addElement(new MMFloorStair(this, floor, stair));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ public:
|
|||||||
|
|
||||||
// the underlays
|
// the underlays
|
||||||
for (Floorplan::UnderlayImage* img : floor->underlays) {
|
for (Floorplan::UnderlayImage* img : floor->underlays) {
|
||||||
elements.push_back(new MMFloorUnderlayImage(this, floor, img));
|
addElement(new MMFloorUnderlayImage(this, floor, img));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -38,7 +38,7 @@ public:
|
|||||||
|
|
||||||
// add to myself as element
|
// add to myself as element
|
||||||
MMFloorUnderlayImage* img = new MMFloorUnderlayImage(this, floor, elem);
|
MMFloorUnderlayImage* img = new MMFloorUnderlayImage(this, floor, elem);
|
||||||
elements.push_back(img);
|
addElement(img);
|
||||||
img->setAnchor(center);
|
img->setAnchor(center);
|
||||||
img->setScale(0.1, 0.1);
|
img->setScale(0.1, 0.1);
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ public:
|
|||||||
|
|
||||||
// add all floors
|
// add all floors
|
||||||
for (Floorplan::Floor* floor : map->floors) {
|
for (Floorplan::Floor* floor : map->floors) {
|
||||||
new MMFloor(this, floor);
|
new MMFloor(this, map, floor);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -32,6 +32,22 @@ public:
|
|||||||
/** get the underlying model */
|
/** get the underlying model */
|
||||||
Floorplan::IndoorMap* getMap() {return map;}
|
Floorplan::IndoorMap* getMap() {return map;}
|
||||||
|
|
||||||
|
MMFloor* createFloor() {
|
||||||
|
|
||||||
|
// add to underlying model
|
||||||
|
Floorplan::Floor* floor = new Floorplan::Floor();
|
||||||
|
floor->name = "floor";
|
||||||
|
map->floors.push_back(floor);
|
||||||
|
|
||||||
|
// add to UI model
|
||||||
|
MMFloor* mmfloor = new MMFloor(this, map, floor);
|
||||||
|
//elements.push_back(mmfloor);
|
||||||
|
|
||||||
|
return mmfloor;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MMFLOORS_H
|
#endif // MMFLOORS_H
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include "MapLayerListener.h"
|
||||||
|
|
||||||
class MapModelElement;
|
class MapModelElement;
|
||||||
|
|
||||||
|
|
||||||
@@ -28,14 +30,17 @@ enum class MapLayerType {
|
|||||||
|
|
||||||
class MapLayer {
|
class MapLayer {
|
||||||
|
|
||||||
|
/** this layer's elements */
|
||||||
|
std::vector<MapModelElement*> elements;
|
||||||
|
|
||||||
|
/** attached listeners (if any) */
|
||||||
|
std::vector<MapLayerListener*> listeners;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/** this layer's parent */
|
/** this layer's parent */
|
||||||
MapLayer* parent;
|
MapLayer* parent;
|
||||||
|
|
||||||
/** this layer's elements */
|
|
||||||
std::vector<MapModelElement*> elements;
|
|
||||||
|
|
||||||
/** this layer's sublayers */
|
/** this layer's sublayers */
|
||||||
std::vector<MapLayer*> sublayers;
|
std::vector<MapLayer*> sublayers;
|
||||||
|
|
||||||
@@ -60,6 +65,11 @@ public:
|
|||||||
/** dtor */
|
/** dtor */
|
||||||
virtual ~MapLayer() {;}
|
virtual ~MapLayer() {;}
|
||||||
|
|
||||||
|
/** attach a listener to this layer [usually only added to the root layer] */
|
||||||
|
void addListener(MapLayerListener* listener) {
|
||||||
|
listeners.push_back(listener);
|
||||||
|
}
|
||||||
|
|
||||||
/** get the layer's parent */
|
/** get the layer's parent */
|
||||||
MapLayer* getParent() const {return parent;}
|
MapLayer* getParent() const {return parent;}
|
||||||
|
|
||||||
@@ -77,14 +87,28 @@ public:
|
|||||||
size_t getNumElements() const {return elements.size();}
|
size_t getNumElements() const {return elements.size();}
|
||||||
|
|
||||||
/** remove the given element from the elements list */
|
/** remove the given element from the elements list */
|
||||||
void removeElement(const MapModelElement* elem) { elements.erase(std::remove(elements.begin(), elements.end(), elem), elements.end()); }
|
void removeElement(const MapModelElement* elem) {
|
||||||
|
elements.erase(std::remove(elements.begin(), elements.end(), elem), elements.end());
|
||||||
|
onElemRemoved(elem);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** add a new element to this layer */
|
||||||
|
void addElement(MapModelElement* el) {
|
||||||
|
elements.push_back(el);
|
||||||
|
onElemAdded(el);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** remove the given sublayer from this layer */
|
||||||
|
void removeSublayer(const MapLayer* layer) { sublayers.erase(std::remove(sublayers.begin(), sublayers.end(), layer), sublayers.end()); }
|
||||||
|
|
||||||
/** is this layer currently visible? */
|
/** is this layer currently visible? */
|
||||||
bool isVisible() const {return visible;}
|
bool isVisible() const {return visible;}
|
||||||
|
|
||||||
/** make this layer visible */
|
/** make this layer visible */
|
||||||
void setVisible(const bool visible) {this->visible = visible;}
|
void setVisible(const bool visible) {
|
||||||
|
this->visible = visible;
|
||||||
|
onVisibilityChanged(visible);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** get all sub-layers within this layer */
|
/** get all sub-layers within this layer */
|
||||||
@@ -94,7 +118,7 @@ public:
|
|||||||
/** helper method to get all elements and those of all sub-layers */
|
/** helper method to get all elements and those of all sub-layers */
|
||||||
void getVisibleElementsRecursive(std::vector<MapModelElement*>& el) {
|
void getVisibleElementsRecursive(std::vector<MapModelElement*>& el) {
|
||||||
if (isVisible()) {
|
if (isVisible()) {
|
||||||
std::vector<MapModelElement*> local = getElements();
|
const std::vector<MapModelElement*> local = getElements();
|
||||||
el.insert(el.end(), local.begin(), local.end());
|
el.insert(el.end(), local.begin(), local.end());
|
||||||
for (MapLayer* sub : getSubLayers()) {
|
for (MapLayer* sub : getSubLayers()) {
|
||||||
sub->getVisibleElementsRecursive(el);
|
sub->getVisibleElementsRecursive(el);
|
||||||
@@ -102,9 +126,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
public:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** add a new sublayer to this layer */
|
/** add a new sublayer to this layer */
|
||||||
void addSublayer(MapLayer* ml) {
|
void addSublayer(MapLayer* ml) {
|
||||||
@@ -115,8 +137,35 @@ protected:
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void onElemAdded(MapModelElement* e) {
|
||||||
|
if (parent) {parent->onElemAdded(e);}
|
||||||
|
for (MapLayerListener* listener : listeners) {
|
||||||
|
listener->onLayerChanged(this);
|
||||||
|
listener->onLayerElementAdded(this, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void onElemRemoved(const MapModelElement* e) {
|
||||||
|
if (parent) {parent->onElemRemoved(e);}
|
||||||
|
for (MapLayerListener* listener : listeners) {
|
||||||
|
listener->onLayerChanged(this);
|
||||||
|
listener->onLayerElementRemoved(this, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void onVisibilityChanged(const bool visibile) {
|
||||||
|
if (parent) {parent->onVisibilityChanged(visibile);}
|
||||||
|
for (MapLayerListener* listener : listeners) {
|
||||||
|
listener->onLayerChanged(this);
|
||||||
|
listener->onLayerVisibilityChanged(this, visibile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class MapLayerRoot : public MapLayer {
|
class MapLayerRoot : public MapLayer {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
25
mapview/model/MapLayerListener.h
Normal file
25
mapview/model/MapLayerListener.h
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
#ifndef MAPLAYERLISTENER_H
|
||||||
|
#define MAPLAYERLISTENER_H
|
||||||
|
|
||||||
|
class MapLayer;
|
||||||
|
class MapModelElement;
|
||||||
|
|
||||||
|
class MapLayerListener {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/** the map layer has changed. e.g. new elements were added */
|
||||||
|
virtual void onLayerChanged(MapLayer* layer) = 0;
|
||||||
|
|
||||||
|
/** a new element was added to a layer */
|
||||||
|
virtual void onLayerElementAdded(MapLayer* layer, MapModelElement* elem) = 0;
|
||||||
|
|
||||||
|
/** an element was removed from the layer */
|
||||||
|
virtual void onLayerElementRemoved(MapLayer* layer, const MapModelElement* elem) = 0;
|
||||||
|
|
||||||
|
/** the layer's visibility has changed */
|
||||||
|
virtual void onLayerVisibilityChanged(MapLayer* layer, const bool visible) = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MAPLAYERLISTENER_H
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include "MapLayer.h"
|
#include "MapLayer.h"
|
||||||
#include "MapModelElement.h"
|
#include "MapModelElement.h"
|
||||||
|
#include "MapModelListener.h"
|
||||||
|
|
||||||
#include "MMRoot.h"
|
#include "MMRoot.h"
|
||||||
|
|
||||||
@@ -13,7 +14,7 @@
|
|||||||
#include <Indoor/floorplan/v2/FloorplanReader.h>
|
#include <Indoor/floorplan/v2/FloorplanReader.h>
|
||||||
#include <Indoor/floorplan/v2/FloorplanWriter.h>
|
#include <Indoor/floorplan/v2/FloorplanWriter.h>
|
||||||
|
|
||||||
class MapModel : public QObject {
|
class MapModel : public QObject, public MapLayerListener {
|
||||||
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
@@ -31,6 +32,9 @@ private:
|
|||||||
/** the loaded floorplan */
|
/** the loaded floorplan */
|
||||||
Floorplan::IndoorMap* im;
|
Floorplan::IndoorMap* im;
|
||||||
|
|
||||||
|
/** listener */
|
||||||
|
std::vector<MapModelListener*> listeners;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/** ctor */
|
/** ctor */
|
||||||
@@ -42,6 +46,19 @@ public:
|
|||||||
cleanup();
|
cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** attach a listener */
|
||||||
|
void addListener(MapModelListener* l) {
|
||||||
|
listeners.push_back(l);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** create a new, empty root node */
|
||||||
|
void startEmpty() {
|
||||||
|
im = new Floorplan::IndoorMap();
|
||||||
|
root = new MMRoot(nullptr, im);
|
||||||
|
root->addListener(this);
|
||||||
|
//root->addSublayer(new MMFloors(root, im));
|
||||||
|
}
|
||||||
|
|
||||||
void cleanup() {
|
void cleanup() {
|
||||||
selLayer = nullptr;
|
selLayer = nullptr;
|
||||||
//selElements.clear();
|
//selElements.clear();
|
||||||
@@ -57,6 +74,7 @@ public:
|
|||||||
// load the indoor-map using the given XML-file
|
// load the indoor-map using the given XML-file
|
||||||
im = Floorplan::Reader::readFromFile(file);
|
im = Floorplan::Reader::readFromFile(file);
|
||||||
root = new MMRoot(nullptr, im);
|
root = new MMRoot(nullptr, im);
|
||||||
|
root->addListener(this);
|
||||||
|
|
||||||
emit reset();
|
emit reset();
|
||||||
|
|
||||||
@@ -68,6 +86,22 @@ public:
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void onLayerChanged(MapLayer* layer) override {
|
||||||
|
for (MapModelListener* l : listeners) {l->onLayerChanged(layer);}
|
||||||
|
}
|
||||||
|
|
||||||
|
void onLayerElementAdded(MapLayer* layer, MapModelElement* elem) override {
|
||||||
|
for (MapModelListener* l : listeners) {l->onLayerElementAdded(layer, elem);}
|
||||||
|
}
|
||||||
|
|
||||||
|
void onLayerElementRemoved(MapLayer* layer, const MapModelElement* elem) override {
|
||||||
|
for (MapModelListener* l : listeners) {l->onLayerElementRemoved(layer, elem);}
|
||||||
|
}
|
||||||
|
|
||||||
|
void onLayerVisibilityChanged(MapLayer* layer, const bool visible) override {
|
||||||
|
for (MapModelListener* l : listeners) {l->onLayerVisibilityChanged(layer, visible);}
|
||||||
|
}
|
||||||
|
|
||||||
/** get the constructed map */
|
/** get the constructed map */
|
||||||
Floorplan::IndoorMap* getMap() const {
|
Floorplan::IndoorMap* getMap() const {
|
||||||
return im;
|
return im;
|
||||||
@@ -76,18 +110,21 @@ public:
|
|||||||
/** get the map's root-layer containing all other layers */
|
/** get the map's root-layer containing all other layers */
|
||||||
MapLayer* getRootLayer() { return root; }
|
MapLayer* getRootLayer() { return root; }
|
||||||
|
|
||||||
/** get all elements within the currently selected layer */
|
// /** get all elements within the currently selected layer */
|
||||||
std::vector<MapModelElement*> getSelectedLayerElements() {
|
// std::vector<MapModelElement*> getSelectedLayerElements() {
|
||||||
//return selElements;
|
// //return selElements;
|
||||||
//return (selLayer) ? (selLayer->getElementsRecursive()) : (std::vector<MapModelElement*>());
|
// //return (selLayer) ? (selLayer->getElementsRecursive()) : (std::vector<MapModelElement*>());
|
||||||
std::vector<MapModelElement*> elements;
|
//// std::vector<MapModelElement*> elements;
|
||||||
root->getVisibleElementsRecursive(elements);
|
//// root->getVisibleElementsRecursive(elements);
|
||||||
return elements;
|
//// return elements;
|
||||||
}
|
|
||||||
|
// }
|
||||||
|
|
||||||
/** get all currently visible elements */
|
/** get all currently visible elements */
|
||||||
std::vector<MapModelElement*> getVisibleElements() {
|
std::vector<MapModelElement*> getVisibleElements() {
|
||||||
return getSelectedLayerElements();
|
std::vector<MapModelElement*> elements;
|
||||||
|
root->getVisibleElementsRecursive(elements);
|
||||||
|
return elements;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** set the currently selected layer */
|
/** set the currently selected layer */
|
||||||
|
|||||||
13
mapview/model/MapModelListener.h
Normal file
13
mapview/model/MapModelListener.h
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#ifndef MAPMODELLISTENER_H
|
||||||
|
#define MAPMODELLISTENER_H
|
||||||
|
|
||||||
|
#include "MapLayerListener.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* listen for changes to the map model
|
||||||
|
*/
|
||||||
|
class MapModelListener : public MapLayerListener {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MAPMODELLISTENER_H
|
||||||
143
params/EditFields.h
Normal file
143
params/EditFields.h
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
#ifndef EDITFIELDS_H
|
||||||
|
#define EDITFIELDS_H
|
||||||
|
|
||||||
|
#include <QGridLayout>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QLineEdit>
|
||||||
|
#include "../mapview/model/IHasParams.h"
|
||||||
|
|
||||||
|
class EditFields {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
static void get(QGridLayout* lay, IHasParams* elem) {
|
||||||
|
|
||||||
|
int r = 0;
|
||||||
|
|
||||||
|
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::BOOL: {
|
||||||
|
QCheckBox* chk = new QCheckBox( );
|
||||||
|
chk->setChecked(value.toBool());
|
||||||
|
if (param.readOnly) {
|
||||||
|
chk->setEnabled(false);
|
||||||
|
} else {
|
||||||
|
chk->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() );
|
||||||
|
le->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::INT: {
|
||||||
|
const std::string str = std::to_string(value.toInt());
|
||||||
|
QLineEdit* le = new QLineEdit( str.c_str() );
|
||||||
|
le->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() );
|
||||||
|
le->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);
|
||||||
|
btn->connect(btn, &QPushButton::clicked, [i,elem,lblFile] (const bool 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) {
|
||||||
|
elem->setParamValue(i, ParamValue( Point2(txtX->text().toFloat(), txtY->text().toFloat()) ));
|
||||||
|
};
|
||||||
|
txtX->connect(txtX, &QLineEdit::textChanged, onChange);
|
||||||
|
txtY->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()) ));
|
||||||
|
};
|
||||||
|
txtX->connect(txtX, &QLineEdit::textChanged, onChange);
|
||||||
|
txtY->connect(txtY, &QLineEdit::textChanged, onChange);
|
||||||
|
txtZ->connect(txtZ, &QLineEdit::textChanged, onChange);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
++r;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // EDITFIELDS_H
|
||||||
@@ -4,9 +4,10 @@
|
|||||||
#include "../mapview/model/MMFloorObstacleLine.h"
|
#include "../mapview/model/MMFloorObstacleLine.h"
|
||||||
#include "../mapview/model/MMFloorOutlinePolygon.h"
|
#include "../mapview/model/MMFloorOutlinePolygon.h"
|
||||||
|
|
||||||
#include "../mapview/model/IHasMAC.h"
|
|
||||||
#include "../mapview/model/IHasFile.h"
|
|
||||||
#include "../mapview/model/IHasParams.h"
|
#include "../mapview/model/IHasParams.h"
|
||||||
|
#include "../mapview/model/IHasEditableMeta.h"
|
||||||
|
|
||||||
|
#include "MetaEditWidget.h"
|
||||||
|
|
||||||
#include <Indoor/floorplan/v2/Floorplan.h>
|
#include <Indoor/floorplan/v2/Floorplan.h>
|
||||||
|
|
||||||
@@ -68,11 +69,14 @@ ElementParamWidget::ElementParamWidget(QWidget *parent) : QWidget(parent) {
|
|||||||
|
|
||||||
this->lay = new QGridLayout(this);
|
this->lay = new QGridLayout(this);
|
||||||
|
|
||||||
setMinimumSize(100, 100);
|
//setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
|
||||||
setMaximumWidth(250);
|
//lay->setSizeConstraint(QLayout::SetMinAndMaxSize);
|
||||||
|
setMinimumSize(200, 25);
|
||||||
|
setMaximumSize(200, 9999);
|
||||||
|
//setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
|
||||||
|
|
||||||
//setTitle("MapElement Parameters");
|
//setTitle("MapElement Parameters");
|
||||||
QGridLayout* lay = new QGridLayout();
|
lay = new QGridLayout();
|
||||||
|
|
||||||
// start empty
|
// start empty
|
||||||
setElement(nullptr);
|
setElement(nullptr);
|
||||||
@@ -90,7 +94,6 @@ 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->setLayout(lay);
|
this->setLayout(lay);
|
||||||
int r = 0;
|
int r = 0;
|
||||||
@@ -136,13 +139,15 @@ void ElementParamWidget::refresh() {
|
|||||||
lay->addWidget(cmb,r,1);
|
lay->addWidget(cmb,r,1);
|
||||||
cmb->setCurrentIndex((int)elem->getMethod());
|
cmb->setCurrentIndex((int)elem->getMethod());
|
||||||
connect(cmb, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), [elem, cmb] (int idx) {
|
connect(cmb, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), [elem, cmb] (int idx) {
|
||||||
|
(void) idx;
|
||||||
elem->setMethod( (Floorplan::OutlineMethod) cmb->currentData().toInt() );
|
elem->setMethod( (Floorplan::OutlineMethod) cmb->currentData().toInt() );
|
||||||
});
|
});
|
||||||
++r;
|
++r;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
|
||||||
|
{ // does the element have "parameters" ?
|
||||||
IHasParams* elem = dynamic_cast<IHasParams*>(el);
|
IHasParams* elem = dynamic_cast<IHasParams*>(el);
|
||||||
if (elem) {
|
if (elem) {
|
||||||
|
|
||||||
@@ -158,6 +163,9 @@ void ElementParamWidget::refresh() {
|
|||||||
|
|
||||||
switch(param.type) {
|
switch(param.type) {
|
||||||
|
|
||||||
|
case ParamType::NOT_AVAILABLE:
|
||||||
|
break;
|
||||||
|
|
||||||
case ParamType::BOOL: {
|
case ParamType::BOOL: {
|
||||||
QCheckBox* chk = new QCheckBox( );
|
QCheckBox* chk = new QCheckBox( );
|
||||||
chk->setChecked(value.toBool());
|
chk->setChecked(value.toBool());
|
||||||
@@ -214,6 +222,7 @@ void ElementParamWidget::refresh() {
|
|||||||
QPushButton* btn = new QPushButton("<");
|
QPushButton* btn = new QPushButton("<");
|
||||||
btn->setMaximumSize(32,32);
|
btn->setMaximumSize(32,32);
|
||||||
connect(btn, &QPushButton::clicked, [i,elem,lblFile] (const bool checked) {
|
connect(btn, &QPushButton::clicked, [i,elem,lblFile] (const bool checked) {
|
||||||
|
(void) checked;
|
||||||
QString res = QFileDialog::getOpenFileName();
|
QString res = QFileDialog::getOpenFileName();
|
||||||
elem->setParamValue(i, ParamValue(res.toStdString()));
|
elem->setParamValue(i, ParamValue(res.toStdString()));
|
||||||
lblFile->setText(res);
|
lblFile->setText(res);
|
||||||
@@ -233,6 +242,7 @@ void ElementParamWidget::refresh() {
|
|||||||
laySub->addWidget(txtY,0,1);
|
laySub->addWidget(txtY,0,1);
|
||||||
lay->addWidget(subWidget,r,1);
|
lay->addWidget(subWidget,r,1);
|
||||||
auto onChange = [i,elem,txtX,txtY] (const QString& str) {
|
auto onChange = [i,elem,txtX,txtY] (const QString& str) {
|
||||||
|
(void) str;
|
||||||
elem->setParamValue(i, ParamValue( Point2(txtX->text().toFloat(), txtY->text().toFloat()) ));
|
elem->setParamValue(i, ParamValue( Point2(txtX->text().toFloat(), txtY->text().toFloat()) ));
|
||||||
};
|
};
|
||||||
connect(txtX, &QLineEdit::textChanged, onChange);
|
connect(txtX, &QLineEdit::textChanged, onChange);
|
||||||
@@ -267,10 +277,39 @@ void ElementParamWidget::refresh() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{ // does the element have editable metadata?
|
||||||
|
IHasEditableMeta* elem = dynamic_cast<IHasEditableMeta*>(el);
|
||||||
|
if (elem) {
|
||||||
|
|
||||||
|
QPushButton* btn = new QPushButton("edit");
|
||||||
|
connect(btn, &QPushButton::clicked, [elem] (const bool checked) {
|
||||||
|
(void) checked;
|
||||||
|
if (!elem->getMeta()) {elem->setMeta(new Floorplan::Meta());} // ensure meta-object is present
|
||||||
|
MetaEditWidget* mew = new MetaEditWidget(elem->getMeta()); // edit
|
||||||
|
mew->show();
|
||||||
|
});
|
||||||
|
lay->addWidget(new QLabel("Meta"),r,0);
|
||||||
|
lay->addWidget(btn,r,1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||||
|
//lay->setSizeConstraint(QLayout::SetMinimumSize);
|
||||||
|
//setLayout(lay);
|
||||||
|
setMinimumSize(150, 30+r*24);
|
||||||
|
setMaximumSize(250, 30+r*24);
|
||||||
|
//resize(100, 20+r*22);
|
||||||
|
//emit update();
|
||||||
|
//setVisible(false);
|
||||||
|
//setVisible(true);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ElementParamWidget::onMaterialChange() {
|
void ElementParamWidget::onMaterialChange() {
|
||||||
IHasMaterial* el = dynamic_cast<IHasMaterial*>(this->curElement);
|
IHasMaterial* el = dynamic_cast<IHasMaterial*>(this->curElement);
|
||||||
if (el) {el->setMaterial( (Floorplan::Material) material.cmb->currentData().toInt() );}
|
if (el) {el->setMaterial( (Floorplan::Material) material.cmb->currentData().toInt() );}
|
||||||
@@ -280,23 +319,3 @@ void ElementParamWidget::onObstacleTypeChange() {
|
|||||||
IHasObstacleType* el = dynamic_cast<IHasObstacleType*>(this->curElement);
|
IHasObstacleType* el = dynamic_cast<IHasObstacleType*>(this->curElement);
|
||||||
if (el) {el->setObstacleType((Floorplan::ObstacleType) obstacleType.cmb->currentData().toInt() );}
|
if (el) {el->setObstacleType((Floorplan::ObstacleType) obstacleType.cmb->currentData().toInt() );}
|
||||||
}
|
}
|
||||||
|
|
||||||
//void ElementParamWidget::onNameChange() {
|
|
||||||
// IHasName* el = dynamic_cast<IHasName*>(this->curElement);
|
|
||||||
// if (el) {el->setName(name.txt->text().toStdString());}
|
|
||||||
//}
|
|
||||||
|
|
||||||
//void ElementParamWidget::onOutlineMethodChange() {
|
|
||||||
// MMFloorOutlinePolygon* el = dynamic_cast<MMFloorOutlinePolygon*>(this->curElement);
|
|
||||||
// if (el) {el->setMethod( (Floorplan::OutlineMethod) outlineMethod.cmb->currentData().toInt() );}
|
|
||||||
//}
|
|
||||||
|
|
||||||
//void ElementParamWidget::onMACChanged() {
|
|
||||||
// dynamic_cast<IHasMAC*>(curElement)->setMAC(mac.txt->text().toStdString());
|
|
||||||
//}
|
|
||||||
|
|
||||||
//void ElementParamWidget::onSelectFileName() {
|
|
||||||
// QString res = QFileDialog::getOpenFileName(this);
|
|
||||||
// dynamic_cast<IHasFile*>(curElement)->setFileName(res.toStdString());
|
|
||||||
// fileName.txt->setText(res);
|
|
||||||
//}
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ public:
|
|||||||
/** refresh the currently selected element */
|
/** refresh the currently selected element */
|
||||||
void refresh();
|
void refresh();
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
QGridLayout* lay;
|
QGridLayout* lay;
|
||||||
|
|||||||
@@ -7,13 +7,15 @@
|
|||||||
#include "mapview/model/IHasName.h"
|
#include "mapview/model/IHasName.h"
|
||||||
#include "mapview/model/MMFloor.h"
|
#include "mapview/model/MMFloor.h"
|
||||||
|
|
||||||
|
#include "EditFields.h"
|
||||||
|
|
||||||
LayerParamWidget::LayerParamWidget(QWidget *parent) : QWidget(parent) {
|
LayerParamWidget::LayerParamWidget(QWidget *parent) : QWidget(parent) {
|
||||||
|
|
||||||
setMinimumSize(100, 100);
|
setMinimumSize(100, 50);
|
||||||
setMaximumWidth(250);
|
setMaximumWidth(250);
|
||||||
//setTitle("MapLayer Parameters");
|
//setTitle("MapLayer Parameters");
|
||||||
|
|
||||||
QGridLayout* lay = new QGridLayout(this);
|
lay = new QGridLayout(this);
|
||||||
int r = 0;
|
int r = 0;
|
||||||
|
|
||||||
|
|
||||||
@@ -53,35 +55,50 @@ void LayerParamWidget::setElement(MapLayer* l) {
|
|||||||
|
|
||||||
this->curElement = l;
|
this->curElement = l;
|
||||||
|
|
||||||
if (l) {
|
// if (l) {
|
||||||
std::string info = l->getLayerName() + " (" + std::to_string(l->getNumElements()) + " elements)";
|
// std::string info = l->getLayerName() + " (" + std::to_string(l->getNumElements()) + " elements)";
|
||||||
selected.info->setText(info.c_str());
|
// selected.info->setText(info.c_str());
|
||||||
} else {
|
// } else {
|
||||||
selected.info->setText("-");
|
// selected.info->setText("-");
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
while ( QWidget* w = this->findChild<QWidget*>() ) {delete w;}
|
||||||
|
delete this->layout();
|
||||||
|
this->lay = new QGridLayout();
|
||||||
|
this->setLayout(lay);
|
||||||
|
int r = 0;
|
||||||
|
|
||||||
|
|
||||||
|
// {
|
||||||
|
// MMFloor* floor = dynamic_cast<MMFloor*>(l);
|
||||||
|
// atHeight.lbl->setVisible(floor);
|
||||||
|
// atHeight.txt->setVisible(floor);
|
||||||
|
// height.lbl->setVisible(floor);
|
||||||
|
// height.txt->setVisible(floor);
|
||||||
|
// if (floor) {
|
||||||
|
// std::string _atHeight = std::to_string(floor->getFloor().atHeight);
|
||||||
|
// atHeight.txt->setText( _atHeight.c_str() );
|
||||||
|
// std::string _height = std::to_string(floor->getFloor().height);
|
||||||
|
// height.txt->setText( _height.c_str() );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // has name
|
||||||
|
// {
|
||||||
|
// IHasName* elem = dynamic_cast<IHasName*>(l);
|
||||||
|
// name.lbl->setVisible(elem);
|
||||||
|
// name.txt->setVisible(elem);
|
||||||
|
// if (elem) {name.txt->setText(elem->getName().c_str());}
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
MMFloor* floor = dynamic_cast<MMFloor*>(l);
|
IHasParams* elem = dynamic_cast<IHasParams*>(l);
|
||||||
atHeight.lbl->setVisible(floor);
|
if (elem) {
|
||||||
atHeight.txt->setVisible(floor);
|
EditFields::get(lay, elem);
|
||||||
height.lbl->setVisible(floor);
|
|
||||||
height.txt->setVisible(floor);
|
|
||||||
if (floor) {
|
|
||||||
std::string _atHeight = std::to_string(floor->getFloor().atHeight);
|
|
||||||
atHeight.txt->setText( _atHeight.c_str() );
|
|
||||||
std::string _height = std::to_string(floor->getFloor().height);
|
|
||||||
height.txt->setText( _height.c_str() );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// has name
|
|
||||||
{
|
|
||||||
IHasName* elem = dynamic_cast<IHasName*>(l);
|
|
||||||
name.lbl->setVisible(elem);
|
|
||||||
name.txt->setVisible(elem);
|
|
||||||
if (elem) {name.txt->setText(elem->getName().c_str());}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -8,11 +8,16 @@ class MapLayer;
|
|||||||
class QLabel;
|
class QLabel;
|
||||||
class QLineEdit;
|
class QLineEdit;
|
||||||
class QComboBox;
|
class QComboBox;
|
||||||
|
class QGridLayout;
|
||||||
|
|
||||||
class LayerParamWidget : public QWidget {
|
class LayerParamWidget : public QWidget {
|
||||||
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
QGridLayout* lay;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
explicit LayerParamWidget(QWidget *parent = 0);
|
explicit LayerParamWidget(QWidget *parent = 0);
|
||||||
|
|||||||
92
params/LayerTree.cpp
Normal file
92
params/LayerTree.cpp
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
#include "LayerTree.h"
|
||||||
|
|
||||||
|
#include <QTreeView>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
#include <QGridLayout>
|
||||||
|
|
||||||
|
#include "../tree/MapTreeModel.h"
|
||||||
|
#include "../UIHelper.h"
|
||||||
|
|
||||||
|
LayerTree::LayerTree(QWidget *parent) : QWidget(parent) {
|
||||||
|
|
||||||
|
QGridLayout* layGrid = new QGridLayout(this);
|
||||||
|
|
||||||
|
tree = new QTreeView(this);
|
||||||
|
tree->setMinimumSize(150, 200);
|
||||||
|
|
||||||
|
QWidget* wButtons = new QWidget();
|
||||||
|
QHBoxLayout* layButtons = new QHBoxLayout(wButtons);
|
||||||
|
|
||||||
|
btnNew = new QPushButton(this);
|
||||||
|
btnNew->setIcon(UIHelper::getIcon("add"));
|
||||||
|
btnNew->setMaximumSize(32,32);
|
||||||
|
btnNew->setMinimumSize(32,32);
|
||||||
|
btnNew->setEnabled(false);
|
||||||
|
layButtons->addWidget(btnNew);
|
||||||
|
|
||||||
|
|
||||||
|
btnDelete = new QPushButton(this);
|
||||||
|
btnDelete->setIcon(UIHelper::getIcon("remove"));
|
||||||
|
btnDelete->setMaximumSize(32,32);
|
||||||
|
btnDelete->setMinimumSize(32,32);
|
||||||
|
btnDelete->setEnabled(false);
|
||||||
|
layButtons->addWidget(btnDelete);
|
||||||
|
|
||||||
|
layGrid->addWidget(tree, 0,0,1,1);
|
||||||
|
layGrid->addWidget(wButtons, 1, 0, 1, 1);
|
||||||
|
|
||||||
|
connect(btnNew, SIGNAL(clicked(bool)), this, SLOT(onBtnNew()));
|
||||||
|
connect(btnDelete, SIGNAL(clicked(bool)), this, SLOT(onBtnDelete()));
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void LayerTree::expandAll() {
|
||||||
|
tree->expandAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LayerTree::setModel(MapTreeModel* model) {
|
||||||
|
|
||||||
|
this->model = model;
|
||||||
|
this->tree->setModel(model);
|
||||||
|
|
||||||
|
// tree model selection events
|
||||||
|
if (!connect(tree->selectionModel(), SIGNAL(currentChanged(QModelIndex, QModelIndex)), this, SLOT(onLayerSelected(QModelIndex)))) {throw "error";}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void LayerTree::onLayerSelected(QModelIndex idx) {
|
||||||
|
|
||||||
|
MapLayer* ml = static_cast<MapLayer*>(idx.internalPointer());
|
||||||
|
|
||||||
|
MMFloors* floors = dynamic_cast<MMFloors*>(ml);
|
||||||
|
btnNew->setEnabled( floors != nullptr );
|
||||||
|
|
||||||
|
MMFloor* floor = dynamic_cast<MMFloor*>(ml);
|
||||||
|
btnDelete->setEnabled( floor != nullptr );
|
||||||
|
|
||||||
|
emit layerSelected(idx);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LayerTree::onBtnNew() {
|
||||||
|
QModelIndex idx = tree->selectionModel()->selectedIndexes().first();
|
||||||
|
MapLayer* ml = static_cast<MapLayer*>(idx.internalPointer());
|
||||||
|
MMFloors* floors = dynamic_cast<MMFloors*>(ml);
|
||||||
|
if (floors) {
|
||||||
|
floors->createFloor();
|
||||||
|
model->getMapModel()->reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LayerTree::onBtnDelete() {
|
||||||
|
QModelIndex idx = tree->selectionModel()->selectedIndexes().first();
|
||||||
|
MapLayer* ml = static_cast<MapLayer*>(idx.internalPointer());
|
||||||
|
MMFloor* floor= dynamic_cast<MMFloor*>(ml);
|
||||||
|
if (floor) {
|
||||||
|
floor->deleteMe();
|
||||||
|
model->getMapModel()->reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
49
params/LayerTree.h
Normal file
49
params/LayerTree.h
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
#ifndef LAYERTREE_H
|
||||||
|
#define LAYERTREE_H
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
class QTreeView;
|
||||||
|
class QPushButton;
|
||||||
|
class MapTreeModel;
|
||||||
|
|
||||||
|
#include <QModelIndex>
|
||||||
|
|
||||||
|
class LayerTree : public QWidget {
|
||||||
|
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
explicit LayerTree(QWidget *parent = 0);
|
||||||
|
|
||||||
|
//QTreeView* getTree() const {return tree;}
|
||||||
|
|
||||||
|
void setModel(MapTreeModel* model);
|
||||||
|
|
||||||
|
void expandAll();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
void layerSelected(QModelIndex);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void onLayerSelected(QModelIndex);
|
||||||
|
|
||||||
|
void onBtnNew();
|
||||||
|
|
||||||
|
void onBtnDelete();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
QTreeView* tree;
|
||||||
|
QPushButton* btnNew;
|
||||||
|
QPushButton* btnDelete;
|
||||||
|
MapTreeModel* model;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // LAYERTREE_H
|
||||||
87
params/MetaEditModel.cpp
Normal file
87
params/MetaEditModel.cpp
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
#include "MetaEditModel.h"
|
||||||
|
|
||||||
|
|
||||||
|
MetaEditModel::MetaEditModel(QObject* parent) : QAbstractTableModel(parent) {
|
||||||
|
|
||||||
|
setHeaderData(0, Qt::Horizontal, QObject::tr("ID"));
|
||||||
|
setHeaderData(1, Qt::Horizontal, QObject::tr("Name"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MetaEditModel::setSource(Floorplan::Meta* meta) {
|
||||||
|
beginResetModel();
|
||||||
|
this->meta = meta;
|
||||||
|
endResetModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
int MetaEditModel::rowCount(const QModelIndex &parent) const {
|
||||||
|
return (meta) ? (meta->size()) : (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int MetaEditModel::columnCount(const QModelIndex &parent) const {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant MetaEditModel::data(const QModelIndex &index, int role) const {
|
||||||
|
|
||||||
|
if (role == Qt::DisplayRole) {
|
||||||
|
switch(index.column()) {
|
||||||
|
case 0: return meta->getKey(index.row()).c_str();
|
||||||
|
case 1: return meta->getVal(index.row()).c_str();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return QVariant();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MetaEditModel::setData(const QModelIndex & index, const QVariant &value, int role) {
|
||||||
|
|
||||||
|
if (role == Qt::EditRole) {
|
||||||
|
switch(index.column()) {
|
||||||
|
case 0: meta->setKey(index.row(), value.toString().toStdString()); return true;
|
||||||
|
case 1: meta->setVal(index.row(), value.toString().toStdString()); return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void MetaEditModel::deleteEntry(const int idx) {
|
||||||
|
beginResetModel();
|
||||||
|
meta->deleteEntry(idx);
|
||||||
|
endResetModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MetaEditModel::addEntry() {
|
||||||
|
beginResetModel();
|
||||||
|
meta->add("key", "val");
|
||||||
|
endResetModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
Qt::ItemFlags MetaEditModel::flags(const QModelIndex &index) const {
|
||||||
|
|
||||||
|
if (!index.isValid()) {return Qt::ItemIsEnabled;}
|
||||||
|
|
||||||
|
return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
QVariant MetaEditModel::headerData(int section, Qt::Orientation orientation, int role) const {
|
||||||
|
|
||||||
|
if (role == Qt::DisplayRole) {
|
||||||
|
if(orientation == Qt::Horizontal) {
|
||||||
|
if (section == 0) {return "key";}
|
||||||
|
if (section == 1) {return "value";}
|
||||||
|
} else {
|
||||||
|
return QString::number(section);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return QVariant();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
41
params/MetaEditModel.h
Normal file
41
params/MetaEditModel.h
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
#ifndef METAEDITMODEL_H
|
||||||
|
#define METAEDITMODEL_H
|
||||||
|
|
||||||
|
#include <Indoor/floorplan/v2/Floorplan.h>
|
||||||
|
#include <QAbstractTableModel>
|
||||||
|
|
||||||
|
class MetaEditModel : public QAbstractTableModel {
|
||||||
|
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Floorplan::Meta* meta = nullptr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
MetaEditModel(QObject* parent = nullptr);
|
||||||
|
|
||||||
|
/** delete the idx-th entry */
|
||||||
|
void deleteEntry(const int idx);
|
||||||
|
|
||||||
|
/** add a new entry at the end */
|
||||||
|
void addEntry();
|
||||||
|
|
||||||
|
void setSource(Floorplan::Meta* meta);
|
||||||
|
|
||||||
|
int rowCount(const QModelIndex& parent) const override;
|
||||||
|
|
||||||
|
int columnCount(const QModelIndex& parent) const override;
|
||||||
|
|
||||||
|
Qt::ItemFlags flags(const QModelIndex &index) const override;
|
||||||
|
|
||||||
|
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
|
||||||
|
|
||||||
|
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
|
||||||
|
|
||||||
|
bool setData(const QModelIndex & index, const QVariant &value, int role = Qt::EditRole) override;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // METAEDITMODEL_H
|
||||||
67
params/MetaEditWidget.cpp
Normal file
67
params/MetaEditWidget.cpp
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
#include "MetaEditWidget.h"
|
||||||
|
#include "MetaEditModel.h"
|
||||||
|
|
||||||
|
#include <QTableView>
|
||||||
|
#include <QGridLayout>
|
||||||
|
#include <QKeyEvent>
|
||||||
|
#include <QPushButton>
|
||||||
|
|
||||||
|
MetaEditWidget::MetaEditWidget(Floorplan::Meta* meta) : QWidget(nullptr), metaOrig(meta) {
|
||||||
|
|
||||||
|
// local copy. for the abort button [orig is unchanged]
|
||||||
|
metaCopy.params = metaOrig->params;
|
||||||
|
|
||||||
|
QGridLayout* lay = new QGridLayout(this);
|
||||||
|
|
||||||
|
tbl = new QTableView();
|
||||||
|
lay->addWidget(tbl, 0, 0, 1, 3);
|
||||||
|
|
||||||
|
model = new MetaEditModel();
|
||||||
|
model->setSource(&metaCopy); // we edit the copy
|
||||||
|
|
||||||
|
tbl->setModel(model);
|
||||||
|
tbl->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||||
|
tbl->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||||
|
|
||||||
|
|
||||||
|
// events
|
||||||
|
QPushButton* btnAdd = new QPushButton("add entry");
|
||||||
|
lay->addWidget(btnAdd, 1, 0);
|
||||||
|
btnAdd->connect(btnAdd, &QPushButton::clicked, [this] (const bool) {
|
||||||
|
model->addEntry();
|
||||||
|
});
|
||||||
|
btnAdd->setToolTip("add a new, empty entry. delete an entry using the keyboard");
|
||||||
|
|
||||||
|
QPushButton* btnCancel = new QPushButton("abort");
|
||||||
|
lay->addWidget(btnCancel, 1, 1);
|
||||||
|
btnCancel->connect(btnCancel, &QPushButton::clicked, [this] (const bool) {
|
||||||
|
// do not apply changes. juts close
|
||||||
|
close();
|
||||||
|
});
|
||||||
|
btnCancel->setToolTip("close the dialog without committing the changes");
|
||||||
|
|
||||||
|
QPushButton* btnOK = new QPushButton("OK");
|
||||||
|
lay->addWidget(btnOK, 1, 2);
|
||||||
|
btnOK->connect(btnOK, &QPushButton::clicked, [this] (const bool) {
|
||||||
|
metaOrig->params = metaCopy.params; // apply changed
|
||||||
|
close();
|
||||||
|
});
|
||||||
|
btnOK->setToolTip("commit the changes and close the dialog");
|
||||||
|
|
||||||
|
|
||||||
|
// sizing
|
||||||
|
resize(500,400);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void MetaEditWidget::keyPressEvent(QKeyEvent* e) {
|
||||||
|
|
||||||
|
if (e->key() == Qt::Key_Delete) {
|
||||||
|
QModelIndexList indices = tbl->selectionModel()->selectedIndexes();
|
||||||
|
for (const QModelIndex& idx : indices) {
|
||||||
|
model->deleteEntry(idx.row());
|
||||||
|
break; // the list contains one entry per column!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
35
params/MetaEditWidget.h
Normal file
35
params/MetaEditWidget.h
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
#ifndef METAEDITWIDGET_H
|
||||||
|
#define METAEDITWIDGET_H
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include <Indoor/floorplan/v2/Floorplan.h>
|
||||||
|
|
||||||
|
class MetaEditModel;
|
||||||
|
class QTableView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* helper class to edit the Floorplan::Meta
|
||||||
|
* key value attribute
|
||||||
|
*/
|
||||||
|
class MetaEditWidget : public QWidget {
|
||||||
|
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Floorplan::Meta* metaOrig;
|
||||||
|
Floorplan::Meta metaCopy; // used for the abort button
|
||||||
|
|
||||||
|
MetaEditModel* model;
|
||||||
|
|
||||||
|
QTableView* tbl;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
MetaEditWidget(Floorplan::Meta* meta);
|
||||||
|
|
||||||
|
void keyPressEvent(QKeyEvent* e);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // METAEDITWIDGET_H
|
||||||
@@ -14,8 +14,19 @@
|
|||||||
#include "../mapview/model/MMFloorBeacon.h"
|
#include "../mapview/model/MMFloorBeacon.h"
|
||||||
#include "../mapview/model/MMFloorGroundTruthPoints.h"
|
#include "../mapview/model/MMFloorGroundTruthPoints.h"
|
||||||
|
|
||||||
|
#include "../mapview/2D/tools/ToolMeasure.h"
|
||||||
|
|
||||||
#include "../UIHelper.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) {
|
ToolBoxWidget::ToolBoxWidget(MapView2D* view, QWidget *parent) : QWidget(parent), view(view) {
|
||||||
|
|
||||||
const int s = 32;
|
const int s = 32;
|
||||||
@@ -31,6 +42,16 @@ ToolBoxWidget::ToolBoxWidget(MapView2D* view, QWidget *parent) : QWidget(parent)
|
|||||||
connect(btnSelect, SIGNAL(clicked(bool)), this, SLOT(onSelect()));
|
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
|
// OBSTACLES
|
||||||
btnGround = new QPushButton(UIHelper::getIcon("floor"), "");
|
btnGround = new QPushButton(UIHelper::getIcon("floor"), "");
|
||||||
@@ -64,6 +85,10 @@ ToolBoxWidget::ToolBoxWidget(MapView2D* view, QWidget *parent) : QWidget(parent)
|
|||||||
connect(btnElevator, SIGNAL(clicked(bool)), this, SLOT(onNewElevator()));
|
connect(btnElevator, SIGNAL(clicked(bool)), this, SLOT(onNewElevator()));
|
||||||
|
|
||||||
|
|
||||||
|
// splitter
|
||||||
|
lay->addWidget(getSplitter(), r++, 0, 1,1,Qt::AlignTop);
|
||||||
|
|
||||||
|
|
||||||
// TRANSMITTERS
|
// TRANSMITTERS
|
||||||
btnWifi = new QPushButton(UIHelper::getIcon("wifi"), "");
|
btnWifi = new QPushButton(UIHelper::getIcon("wifi"), "");
|
||||||
btnWifi->setMinimumSize(s,s);
|
btnWifi->setMinimumSize(s,s);
|
||||||
@@ -350,116 +375,25 @@ public:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//struct NewLineTool : public Tool {
|
|
||||||
|
|
||||||
// /** add another line after this one? */
|
|
||||||
// bool multiple = true;
|
|
||||||
|
|
||||||
// /** register this tool into the given tools-queue */
|
|
||||||
// Tools& tools;
|
|
||||||
|
|
||||||
// /** the layer to add the new line to */
|
|
||||||
// MapLayer* layer;
|
|
||||||
|
|
||||||
// /** currently edited line */
|
|
||||||
// Floorplan::FloorObstacleLine* foLine;
|
|
||||||
// MMFloorObstacleLine* mmLine;
|
|
||||||
|
|
||||||
// /** new line type */
|
|
||||||
// Floorplan::ObstacleType type;
|
|
||||||
|
|
||||||
// /** new line material */
|
|
||||||
// Floorplan::Material mat;
|
|
||||||
|
|
||||||
// /** currently edited line node (has 2) */
|
|
||||||
// int idx = 0;
|
|
||||||
|
|
||||||
|
|
||||||
// NewLineTool(Tools& tools, MapLayer* layer, Floorplan::ObstacleType type, Floorplan::Material mat) : tools(tools), layer(layer), type(type), mat(mat) {
|
|
||||||
// createEmptyLine();
|
|
||||||
// tools.addFront(this);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// virtual bool mousePressEvent(MapView2D* m, QMouseEvent* e) override {
|
|
||||||
// (void) m; (void) e;
|
|
||||||
// return true;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
// if (idx == 0) { foLine->from = onMap; foLine->to = onMap; }
|
|
||||||
// if (idx == 1) { foLine->to = onMap; }
|
|
||||||
// return true;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// virtual bool mouseReleaseEvent(MapView2D* m, QMouseEvent* e) override {
|
|
||||||
// (void) m; (void) e;
|
|
||||||
// ++idx;
|
|
||||||
// if (idx == 2) {
|
|
||||||
|
|
||||||
// finalizeLine();
|
|
||||||
|
|
||||||
// if (multiple) {
|
|
||||||
// idx = 0;
|
|
||||||
// createEmptyLine();
|
|
||||||
// } else {
|
|
||||||
// disableMe();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// return true;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// virtual bool keyPressEvent(MapView2D* m, QKeyEvent* e) override {
|
|
||||||
// (void) m;
|
|
||||||
// if (e->key() == Qt::Key_Escape) {
|
|
||||||
// if (mmLine) {mmLine->deleteMe();}
|
|
||||||
// disableMe(); return true;
|
|
||||||
// }
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
|
|
||||||
//private:
|
|
||||||
|
|
||||||
// /** finalize the current line */
|
|
||||||
// void finalizeLine() {
|
|
||||||
// if (!mmLine) {return;}
|
|
||||||
// mmLine->getMV2D()->unfocus();
|
|
||||||
// mmLine = nullptr;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /** stop creating new lines */
|
|
||||||
// void disableMe() {
|
|
||||||
// finalizeLine();
|
|
||||||
// tools.remove(this);
|
|
||||||
// delete this;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /** create a new, empty line */
|
|
||||||
// void createEmptyLine() {
|
|
||||||
// foLine = new Floorplan::FloorObstacleLine(type, mat, Point2(0, 0), Point2(0, 0));
|
|
||||||
// MMFloorObstacles* obs = (MMFloorObstacles*)layer;
|
|
||||||
// mmLine = obs->createLine(foLine);
|
|
||||||
// mmLine->getMV2D()->focus();
|
|
||||||
// }
|
|
||||||
|
|
||||||
//};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void ToolBoxWidget::onSelect() {
|
void ToolBoxWidget::onSelect() {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void ToolBoxWidget::onMeasure() {
|
||||||
|
|
||||||
|
new ToolMeasure(view->getTools());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void ToolBoxWidget::onNewWall() {
|
void ToolBoxWidget::onNewWall() {
|
||||||
|
|
||||||
new NewWallTool(view->getTools(), curLayer);
|
new NewWallTool(view->getTools(), curLayer);
|
||||||
//view->getModel()->reselect();
|
//view->getModel()->reselect();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ToolBoxWidget::onNewPillar() {
|
void ToolBoxWidget::onNewPillar() {
|
||||||
@@ -484,21 +418,6 @@ void ToolBoxWidget::onNewDoor() {
|
|||||||
|
|
||||||
new NewDoorTool(view->getTools(), curLayer);
|
new NewDoorTool(view->getTools(), curLayer);
|
||||||
|
|
||||||
// const Point2 center = view->getScaler().getCenter();
|
|
||||||
// float s = view->getScaler().sm(50);
|
|
||||||
|
|
||||||
// Floorplan::FloorObstacleDoor* door = new Floorplan::FloorObstacleDoor(
|
|
||||||
// Floorplan::DoorType::SWING,
|
|
||||||
// Floorplan::Material::WOOD,
|
|
||||||
// Point2(center.x-s, center.y),
|
|
||||||
// Point2(center.x+s, center.y)
|
|
||||||
// );
|
|
||||||
|
|
||||||
// MMFloorObstacles* obs = (MMFloorObstacles*)curLayer;
|
|
||||||
// obs->createDoor(door);
|
|
||||||
|
|
||||||
//view->getModel()->reselect();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ToolBoxWidget::onNewStair() {
|
void ToolBoxWidget::onNewStair() {
|
||||||
|
|||||||
@@ -8,7 +8,9 @@ class QPushButton;
|
|||||||
class MapView2D;
|
class MapView2D;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gui element with actions to perform
|
* the toolbox on the left of the map.
|
||||||
|
* gui element with actions to perform.
|
||||||
|
* add new elements, etc.
|
||||||
*/
|
*/
|
||||||
class ToolBoxWidget : public QWidget {
|
class ToolBoxWidget : public QWidget {
|
||||||
|
|
||||||
@@ -32,6 +34,7 @@ private:
|
|||||||
int r = 0;
|
int r = 0;
|
||||||
|
|
||||||
QPushButton* btnSelect;
|
QPushButton* btnSelect;
|
||||||
|
QPushButton* btnMeasure;
|
||||||
|
|
||||||
QPushButton* btnGround;
|
QPushButton* btnGround;
|
||||||
QPushButton* btnWall;
|
QPushButton* btnWall;
|
||||||
@@ -50,6 +53,7 @@ private:
|
|||||||
private slots:
|
private slots:
|
||||||
|
|
||||||
void onSelect();
|
void onSelect();
|
||||||
|
void onMeasure();
|
||||||
|
|
||||||
void onNewGround();
|
void onNewGround();
|
||||||
void onNewWall();
|
void onNewWall();
|
||||||
|
|||||||
3
res.qrc
3
res.qrc
@@ -14,6 +14,9 @@
|
|||||||
<file>res/icons/door.svg</file>
|
<file>res/icons/door.svg</file>
|
||||||
<file>res/icons/cursor.svg</file>
|
<file>res/icons/cursor.svg</file>
|
||||||
<file>res/icons/elevator.svg</file>
|
<file>res/icons/elevator.svg</file>
|
||||||
|
<file>res/icons/add.svg</file>
|
||||||
|
<file>res/icons/remove.svg</file>
|
||||||
|
<file>res/icons/ruler.svg</file>
|
||||||
<file>res/icons/gtp.svg</file>
|
<file>res/icons/gtp.svg</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|||||||
42
res/icons/add.svg
Normal file
42
res/icons/add.svg
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
width="510px" height="510px" viewBox="0 0 510 510" style="enable-background:new 0 0 510 510;" xml:space="preserve">
|
||||||
|
<g>
|
||||||
|
<g id="add-circle">
|
||||||
|
<path d="M255,0C114.75,0,0,114.75,0,255s114.75,255,255,255s255-114.75,255-255S395.25,0,255,0z M382.5,280.5h-102v102h-51v-102
|
||||||
|
h-102v-51h102v-102h51v102h102V280.5z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 871 B |
42
res/icons/remove.svg
Normal file
42
res/icons/remove.svg
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
width="510px" height="510px" viewBox="0 0 510 510" style="enable-background:new 0 0 510 510;" xml:space="preserve">
|
||||||
|
<g>
|
||||||
|
<g id="remove-circle">
|
||||||
|
<path d="M255,0C114.75,0,0,114.75,0,255s114.75,255,255,255s255-114.75,255-255S395.25,0,255,0z M382.5,280.5h-255v-51h255V280.5z
|
||||||
|
"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 840 B |
50
res/icons/ruler.svg
Normal file
50
res/icons/ruler.svg
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 496 496" style="enable-background:new 0 0 496 496;" xml:space="preserve">
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<path d="M420.08,422.424l6.6-13.208L378.776,137.76c4.768-7.448,7.568-16.28,7.568-25.76c0-17.72-9.68-33.192-24-41.504V0h-48
|
||||||
|
v70.496c-14.32,8.312-24,23.784-24,41.504c0,9.48,2.8,18.312,7.568,25.76l-24.376,138.12L2.344,4.688V496h491.312L420.08,422.424z
|
||||||
|
M410.008,406.776l-7.664,15.336L394,405.424l-46.192-246.376c6.264-1.256,12.088-3.736,17.216-7.176L410.008,406.776z
|
||||||
|
M371.872,374.208l-56.464-56.464l22.936-122.336L371.872,374.208z M330.344,16h16v48.72c-2.608-0.44-5.272-0.72-8-0.72
|
||||||
|
c-2.728,0-5.392,0.28-8,0.72V16z M338.344,80c17.648,0,32,14.352,32,32s-14.352,32-32,32s-32-14.352-32-32S320.696,80,338.344,80z
|
||||||
|
M311.664,151.88c5.128,3.44,10.952,5.92,17.216,7.176l-46.192,246.376l-8.344,16.68l-7.664-15.328L311.664,151.88z M386.344,456
|
||||||
|
v24h-32v-40h-16v40h-32v-24h-16v24h-32v-40h-16v40h-32v-24h-16v24h-32v-40h-16v40h-32v-24h-16v24h-32v-40h-16v40h-32v-40h24v-16
|
||||||
|
h-24v-32h40v-16h-40v-32h24v-16h-24v-32h40v-16h-40v-32h24v-16h-24v-32h40v-16h-40v-32h24v-16h-24v-32h40V88h-40V43.312
|
||||||
|
l251.8,251.8l-13.576,76.936L82.344,197.824V416h128v-16h-112V236.448L253.176,391.28l-1.544,8.72h-25.288v16H253.4l20.944,41.888
|
||||||
|
L298,410.576l13.832-73.776l65.256,65.256l1.392,7.416L401.416,456H386.344z M402.344,457.888l10.192-20.384L455.032,480h-52.688
|
||||||
|
V457.888z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.8 KiB |
8
res/icons/sources.txt
Normal file
8
res/icons/sources.txt
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
www.flaticon.com
|
||||||
|
https://icons8.com/web-app/for/all/Ibeacon
|
||||||
|
|
||||||
|
|
||||||
|
# add
|
||||||
|
http://www.flaticon.com/free-icon/add-button-inside-black-circle_60740
|
||||||
|
# remove
|
||||||
|
http://www.flaticon.com/free-icon/rounded-remove-button_60951#term=remove%20button&page=1&position=6
|
||||||
@@ -25,6 +25,10 @@ public:
|
|||||||
|
|
||||||
virtual ~MapTreeModel() {;}
|
virtual ~MapTreeModel() {;}
|
||||||
|
|
||||||
|
MapModel* getMapModel() {
|
||||||
|
return mdl;
|
||||||
|
}
|
||||||
|
|
||||||
virtual QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const override {
|
virtual QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const override {
|
||||||
|
|
||||||
MapLayer* _parent = nullptr;
|
MapLayer* _parent = nullptr;
|
||||||
|
|||||||
Reference in New Issue
Block a user