added a ruler for measuring
added support for meta-data editing improved element selection changed zooming fixed some issues with layer events fixed issue with 3D outline fixed loading issue for old maps some interface changes
This commit is contained in:
@@ -20,9 +20,9 @@ public:
|
||||
Scaler& s = m->getScaler();
|
||||
|
||||
if (e->delta() < 0) {
|
||||
s.setScale(s.getScale() * 0.5);
|
||||
s.setScale(s.getScale() * 0.75);
|
||||
} else {
|
||||
s.setScale(s.getScale() / 0.5);
|
||||
s.setScale(s.getScale() / 0.75);
|
||||
}
|
||||
|
||||
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
|
||||
@@ -46,6 +46,15 @@ public:
|
||||
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:
|
||||
|
||||
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)
|
||||
|
||||
#warning "which elements to select? among all currently visible? or only among the selected layer?"
|
||||
// get all elements with bounding-box matchings
|
||||
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;}
|
||||
BBox2 bbox = el->getMV2D()->getBoundingBox(); // elements 2D bbox
|
||||
bbox.grow(Point2(g, g)); // grow a little (needed for straight lines)
|
||||
|
||||
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
|
||||
@@ -36,7 +36,7 @@ public:
|
||||
MMFloor(MapLayer* parent, Floorplan::IndoorMap* map, Floorplan::Floor* floor) : MapLayer(parent, MapLayerType::FLOOR), map(map), floor(floor) {
|
||||
|
||||
new MMFloorUnderlays(this, floor);
|
||||
elements.push_back(new MMFloorOutline(this, floor));
|
||||
new MMFloorOutline(this, floor);
|
||||
new MMFloorObstacles(this, floor);
|
||||
new MMFloorAccessPoints(this, floor);
|
||||
new MMFloorBeacons(this, floor);
|
||||
|
||||
@@ -3,13 +3,14 @@
|
||||
|
||||
#include "MapModelElement.h"
|
||||
#include "IHasParams.h"
|
||||
#include "IHasEditableMeta.h"
|
||||
|
||||
#include "../2D/MV2DElementAccessPoint.h"
|
||||
#include "../3D/MV3DElementAccessPoint.h"
|
||||
|
||||
#include <Indoor/floorplan/v2/Floorplan.h>
|
||||
|
||||
class MMFloorAccessPoint : public MapModelElement, public IHasParams {
|
||||
class MMFloorAccessPoint : public MapModelElement, public IHasParams, public IHasEditableMeta {
|
||||
|
||||
private:
|
||||
|
||||
@@ -64,6 +65,14 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
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;}
|
||||
MV3DElement* getMV3D() const override {return (MV3DElement*) &mv3d;}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ public:
|
||||
|
||||
// add all APs
|
||||
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);
|
||||
|
||||
// add to myself as element
|
||||
elements.push_back(new MMFloorAccessPoint(this, floor, ap));
|
||||
addElement(new MMFloorAccessPoint(this, floor, ap));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ public:
|
||||
|
||||
// add all 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);
|
||||
|
||||
// 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
|
||||
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);
|
||||
|
||||
// add to myself as element
|
||||
elements.push_back(new MMFloorElevator(this, floor, elevator));
|
||||
addElement(new MMFloorElevator(this, floor, elevator));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -23,11 +23,11 @@ public:
|
||||
// the obstacles
|
||||
for (Floorplan::FloorObstacle* o : floor->obstacles) {
|
||||
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)) {
|
||||
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)) {
|
||||
elements.push_back(new MMFloorObstacleDoor(this, floor, (Floorplan::FloorObstacleDoor*)o));
|
||||
addElement(new MMFloorObstacleDoor(this, floor, (Floorplan::FloorObstacleDoor*)o));
|
||||
} else {
|
||||
throw new Exception("todo: not yet implemented obstacle type");
|
||||
}
|
||||
@@ -46,7 +46,7 @@ public:
|
||||
|
||||
// add to myself as element
|
||||
MMFloorObstacleDoor* mm = new MMFloorObstacleDoor(this, floor, obs);
|
||||
elements.push_back(mm);
|
||||
addElement(mm);
|
||||
return mm;
|
||||
|
||||
}
|
||||
@@ -59,7 +59,7 @@ public:
|
||||
|
||||
// add to myself as element
|
||||
MMFloorObstacleLine* mm = new MMFloorObstacleLine(this, floor, obs);
|
||||
elements.push_back(mm);
|
||||
addElement(mm);
|
||||
return mm;
|
||||
|
||||
}
|
||||
@@ -71,7 +71,7 @@ public:
|
||||
floor->obstacles.push_back(obs);
|
||||
|
||||
// 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 "MMFloorOutlinePolygon.h"
|
||||
#include "../3D/MV3DElementFloorOutline.h"
|
||||
#include "MMFloorOutlinePolygonCombined.h"
|
||||
|
||||
#include "../3D/MV3DElementFloorOutline.h"
|
||||
|
||||
#include <Indoor/floorplan/v2/Floorplan.h>
|
||||
|
||||
/**
|
||||
* layer containing all elements describing a floor's outline
|
||||
*/
|
||||
class MMFloorOutline : public MapLayer, public MapModelElement {
|
||||
class MMFloorOutline : public MapLayer {
|
||||
|
||||
private:
|
||||
|
||||
/** the underlying model */
|
||||
Floorplan::Floor* floor;
|
||||
|
||||
MV3DElementFloorOutline mv3d;
|
||||
|
||||
public:
|
||||
|
||||
/** ctor with the underlying model */
|
||||
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) {
|
||||
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 */
|
||||
@@ -46,7 +47,7 @@ public:
|
||||
floor->outline.push_back(poly);
|
||||
|
||||
// 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
|
||||
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);
|
||||
|
||||
// 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
|
||||
for (Floorplan::Stair* stair : floor->stairs) {
|
||||
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);
|
||||
|
||||
// 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
|
||||
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
|
||||
MMFloorUnderlayImage* img = new MMFloorUnderlayImage(this, floor, elem);
|
||||
elements.push_back(img);
|
||||
addElement(img);
|
||||
img->setAnchor(center);
|
||||
img->setScale(0.1, 0.1);
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#include "MapLayerListener.h"
|
||||
|
||||
class MapModelElement;
|
||||
|
||||
|
||||
@@ -27,14 +29,17 @@ enum class MapLayerType {
|
||||
|
||||
class MapLayer {
|
||||
|
||||
/** this layer's elements */
|
||||
std::vector<MapModelElement*> elements;
|
||||
|
||||
/** attached listeners (if any) */
|
||||
std::vector<MapLayerListener*> listeners;
|
||||
|
||||
protected:
|
||||
|
||||
/** this layer's parent */
|
||||
MapLayer* parent;
|
||||
|
||||
/** this layer's elements */
|
||||
std::vector<MapModelElement*> elements;
|
||||
|
||||
/** this layer's sublayers */
|
||||
std::vector<MapLayer*> sublayers;
|
||||
|
||||
@@ -59,6 +64,11 @@ public:
|
||||
/** dtor */
|
||||
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 */
|
||||
MapLayer* getParent() const {return parent;}
|
||||
|
||||
@@ -76,7 +86,16 @@ public:
|
||||
size_t getNumElements() const {return elements.size();}
|
||||
|
||||
/** 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()); }
|
||||
@@ -85,7 +104,10 @@ public:
|
||||
bool isVisible() const {return 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 */
|
||||
@@ -95,7 +117,7 @@ public:
|
||||
/** helper method to get all elements and those of all sub-layers */
|
||||
void getVisibleElementsRecursive(std::vector<MapModelElement*>& el) {
|
||||
if (isVisible()) {
|
||||
std::vector<MapModelElement*> local = getElements();
|
||||
const std::vector<MapModelElement*> local = getElements();
|
||||
el.insert(el.end(), local.begin(), local.end());
|
||||
for (MapLayer* sub : getSubLayers()) {
|
||||
sub->getVisibleElementsRecursive(el);
|
||||
@@ -105,8 +127,6 @@ public:
|
||||
|
||||
public:
|
||||
|
||||
|
||||
|
||||
/** add a new sublayer to this layer */
|
||||
void addSublayer(MapLayer* ml) {
|
||||
|
||||
@@ -116,8 +136,35 @@ public:
|
||||
|
||||
}
|
||||
|
||||
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 {
|
||||
|
||||
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 "MapModelElement.h"
|
||||
#include "MapModelListener.h"
|
||||
|
||||
#include "MMRoot.h"
|
||||
|
||||
@@ -13,7 +14,7 @@
|
||||
#include <Indoor/floorplan/v2/FloorplanReader.h>
|
||||
#include <Indoor/floorplan/v2/FloorplanWriter.h>
|
||||
|
||||
class MapModel : public QObject {
|
||||
class MapModel : public QObject, public MapLayerListener {
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
@@ -31,6 +32,9 @@ private:
|
||||
/** the loaded floorplan */
|
||||
Floorplan::IndoorMap* im;
|
||||
|
||||
/** listener */
|
||||
std::vector<MapModelListener*> listeners;
|
||||
|
||||
public:
|
||||
|
||||
/** ctor */
|
||||
@@ -42,10 +46,16 @@ public:
|
||||
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));
|
||||
}
|
||||
|
||||
@@ -64,6 +74,7 @@ public:
|
||||
// load the indoor-map using the given XML-file
|
||||
im = Floorplan::Reader::readFromFile(file);
|
||||
root = new MMRoot(nullptr, im);
|
||||
root->addListener(this);
|
||||
|
||||
emit reset();
|
||||
|
||||
@@ -75,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 */
|
||||
Floorplan::IndoorMap* getMap() const {
|
||||
return im;
|
||||
@@ -83,18 +110,21 @@ public:
|
||||
/** get the map's root-layer containing all other layers */
|
||||
MapLayer* getRootLayer() { return root; }
|
||||
|
||||
/** get all elements within the currently selected layer */
|
||||
std::vector<MapModelElement*> getSelectedLayerElements() {
|
||||
//return selElements;
|
||||
//return (selLayer) ? (selLayer->getElementsRecursive()) : (std::vector<MapModelElement*>());
|
||||
std::vector<MapModelElement*> elements;
|
||||
root->getVisibleElementsRecursive(elements);
|
||||
return elements;
|
||||
}
|
||||
// /** get all elements within the currently selected layer */
|
||||
// std::vector<MapModelElement*> getSelectedLayerElements() {
|
||||
// //return selElements;
|
||||
// //return (selLayer) ? (selLayer->getElementsRecursive()) : (std::vector<MapModelElement*>());
|
||||
//// std::vector<MapModelElement*> elements;
|
||||
//// root->getVisibleElementsRecursive(elements);
|
||||
//// return elements;
|
||||
|
||||
// }
|
||||
|
||||
/** get all currently visible elements */
|
||||
std::vector<MapModelElement*> getVisibleElements() {
|
||||
return getSelectedLayerElements();
|
||||
std::vector<MapModelElement*> elements;
|
||||
root->getVisibleElementsRecursive(elements);
|
||||
return elements;
|
||||
}
|
||||
|
||||
/** 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
|
||||
Reference in New Issue
Block a user