#ifndef MV2DELEMENTFLOORUNDERLAY_H #define MV2DELEMENTFLOORUNDERLAY_H #include "MV2DElement.h" #include "MapViewElementHelper.h" #include /** * display e.g. a PNG-file below the map [as reference] */ class MV2DElementFloorUnderlay : public MV2DElement { private: QImage img; std::string tmpFile; Floorplan::UnderlayImage* underlay; BBox2 bbox; int selPoint = -1; public: /** ctor */ MV2DElementFloorUnderlay(Floorplan::UnderlayImage* underlay) : underlay(underlay) { missing(); } void missing() { //img = QImage(QSize(64, 64), QImage::Format_ARGB32); //img.fill(0xFF000000); img = QImage("://res/icons/cross.png"); } /** get the element's 3D bounding box */ BBox2 getBoundingBox() const override { return bbox; } /** get the element's minimal distance (nearest whatsoever) to the given point */ float getMinDistanceXY(const Point2 p) const override { (void) p; return CFG::SEL_THRESHOLD_SIZE_PX; // we do not know the distance from the image } virtual void onFocus() override { } virtual void onUnfocus() override { selPoint = -1; // clear selection } void paint(Painter& p) override { (void) p; if (tmpFile != underlay->filename) { img = QImage(underlay->filename.c_str()); if (img.size().width() == 0) { missing(); } tmpFile = underlay->filename; } // map coordinates float mx1 = underlay->anchor.x; float my1 = underlay->anchor.y; float mw = img.width() * underlay->scaleX; float mh = img.height() * underlay->scaleY; float mx2 = mx1+mw; float my2 = my1+mh; // screen coordinates float sx1 = p.s.xms(mx1); float sy1 = p.s.yms(my1); float sx2 = p.s.xms(mx2); float sy2 = p.s.yms(my2); float sw = abs(sx1-sx2); float sh = abs(sy1-sy2); bbox = BBox2(); bbox.add(Point2(mx1, my1)); bbox.add(Point2(mx2, my2)); p.p->drawImage(QRectF(sx1, sy1-sh, sw, sh), img, QRectF(0,0,img.width(),img.height())); // selected endpoint(s)? if (hasFocus()) { p.setPenBrush(Qt::NoPen, CFG::SEL_COLOR); if (selPoint == 0) {p.drawCircle(bbox.getMin());} } // just focused? if (hasFocus()) { p.setPenBrush(Qt::black, Qt::NoBrush); p.drawRect(mx1,my1,mx2,my2); p.drawCircle(bbox.getMin()); } } virtual void mousePressed(MapView2D* v, const Point2 p) override { (void) v; (void) p; } virtual void mouseMove(MapView2D* v, const Point2 _p) override { (void) v; if (selPoint == -1) {return;} const Point2 p = Scaler::snap(_p, CFG::MOVE_SNAP_SIZE_M); if (selPoint == 0) {underlay->anchor = p;} } virtual void mouseReleased(MapView2D* v, const Point2 _p) override { // select a new point on mouse-release (more robust than on mouse-press) const float t = v->getScaler().sm(CFG::SEL_THRESHOLD_SIZE_PX); const float l1 = _p.getDistance(bbox.getMin()); if (l1 <= t) {selPoint = 0;} else {selPoint = -1;} } virtual bool keyPressEvent(MapView2D* v, QKeyEvent *e) override { (void) v; (void) e; return false; } }; #endif // MV2DELEMENTFLOORUNDERLAY_H