#include "MapView2D.h" #include #include #include #include #include #include #include #include "Floor2D.h" #include "ColorPoints2D.h" #include "Path2D.h" #include "WiFiCalibTool.h" #include "../../Icons.h" #include "../../UIHelper.h" MapView2D::MapView2D(QWidget *parent) : QWidget(parent) { setFocusPolicy(Qt::StrongFocus); setRenderHeight(0); colorPoints = new ColorPoints2D(); elementsB.push_back(colorPoints); pathToDest = new Path2D(); pathToDest->setColor(Qt::blue); pathToDest->setWidth(10); elementsB.push_back(pathToDest); pathWalked = new Path2D(); pathToDest->setColor(Qt::black); pathToDest->setWidth(5); elementsB.push_back(pathWalked); // buttons //menu = new QWidget(this); QGridLayout* lay = new QGridLayout(this); int row = 0; lay->addItem(new QSpacerItem(0,0,QSizePolicy::Minimum,QSizePolicy::Expanding), row, 0, 1, 1); ++ row; // // map-layer slider // sldLayer = new QSlider(); // sldLayer->setOrientation(Qt::Horizontal); // connect(sldLayer, &QSlider::sliderMoved, this, &MapView2D::onLayerSelect); // connect(sldLayer, &QSlider::sliderReleased, this, &MapView2D::onLayerSelect); // lay->addWidget(sldLayer, row, 0, 1, 1); // show/hide button const int bs = UIHelper::getButtonSize(this); btnColorPoints = new QPushButton(Icons::getIcon("dots", bs), ""); btnColorPoints->connect(btnColorPoints, &QPushButton::clicked, [&] () {colorPoints->setVisible(!colorPoints->isVisible()); emit update();} ); lay->addWidget(btnColorPoints, row, 0, 1, 1); btnLayerMinus = new QPushButton("-"); connect(btnLayerMinus, &QPushButton::clicked, this, &MapView2D::onLayerMinus); lay->addWidget(btnLayerMinus, row, 1, 1, 1); btnLayerPlus = new QPushButton("+"); connect(btnLayerPlus, &QPushButton::clicked, this, &MapView2D::onLayerPlus); lay->addWidget(btnLayerPlus, row, 2, 1, 1); // start with invisible particles. speeds things up a bit colorPoints->setVisible(false); // we want to receive pinch gestures //setAttribute(Qt::WA_AcceptTouchEvents, true); grabGesture(Qt::PinchGesture); } void MapView2D::onLayerSelect() { setRenderHeight(sldLayer->value()); } void MapView2D::onLayerMinus() { if (layerHeight_m <= 0) {return;} layerHeight_m -= 1; setRenderHeight(layerHeight_m); } void MapView2D::onLayerPlus() { if (layerHeight_m >= 16) {return;} layerHeight_m += 1; setRenderHeight(layerHeight_m); } void MapView2D::setMap(WiFiCalibrationDataModel* mdl, Floorplan::IndoorMap* map) { for (Floorplan::Floor* floor : map->floors) { Floor2D* f = new Floor2D(floor); elementsA.push_back(f); } wifiCalib = new WiFiCalibTool(mdl, map); elementsB.push_back(wifiCalib); const BBox3 bbox3 = FloorplanHelper::getBBox(map); const BBox2 bbox2 = BBox2(bbox3.getMin().xy(), bbox3.getMax().xy()); scaler.setMapBBox(bbox2); scaler.setCenterM(Point2(bbox2.getCenter().x, bbox2.getCenter().y)); } void MapView2D::showParticles(const std::vector>* particles) { this->colorPoints->setFromParticles(*particles); } void MapView2D::setCurrentEstimation(const Point3 pos_m, const Point3 dir) { (void) dir; setRenderHeight(pos_m.z); scaler.setCenterM(pos_m.xy()); } void MapView2D::setRenderHeight(const float height_m) { renderParams.clip.aboveHeight_m = height_m + 1.5; renderParams.clip.belowHeight_m = height_m - 1.5; emit update(); } void MapView2D::showGridImportance(Grid* grid) { colorPoints->showGridImportance(grid); } void MapView2D::resizeEvent(QResizeEvent* evt) { (void) evt; int s = UIHelper::getButtonSize(this->parent()) * 1.5; //sldLayer->setMinimumHeight(s); //sldLayer->setMinimum(0); //sldLayer->setMaximum(16); btnColorPoints->setMinimumHeight(s); btnColorPoints->setMinimumWidth(s); btnLayerMinus->setMinimumHeight(s); btnLayerMinus->setMinimumWidth(s); btnLayerPlus->setMinimumHeight(s); btnLayerPlus->setMinimumWidth(s); scaler.setScreenSize(width(), height()); scaler.setScale( UIHelper::isLarge(this->parent()) ? 2 : 1 ); } void MapView2D::mousePressEvent(QMouseEvent* evt) { move.startCenter_px = scaler.getCenterPX(); move.startMouse_px = Point2(evt->x(), evt->y()); } void MapView2D::mouseMoveEvent(QMouseEvent* evt) { Point2 pt(evt->x(), evt->y()); pt -= move.startMouse_px; pt.x = -pt.x; pt += move.startCenter_px; scaler.setCenterPX(pt); emit update(); } void MapView2D::mouseReleaseEvent(QMouseEvent* evt) { if (!wifiCalib) {return;} const Point2 p1(evt->x(), evt->y()); // fingerprint node pressed? const int fpSize = UIHelper::isLarge(this->parent()) ? (40) : (25); int idx = 0; for (const Point2 p2 : wifiCalib->getNodes()) { const float dist = p1.getDistance(p2); if (dist < fpSize) { wifiCalib->selectNode(idx); emit update(); break; } ++idx; } } void MapView2D::wheelEvent(QWheelEvent* event) { if (event->delta() < 0) { scaler.mulScale(0.5); emit update(); } else { scaler.mulScale(2.0); emit update(); } } void MapView2D::paintEvent(QPaintEvent*) { QPainter qp(this); // clear qp.fillRect(0, 0, width(), height(), Qt::white); // render elements for (Renderable2D* r : elementsA) {r->render(qp, scaler, renderParams);} for (Renderable2D* r : elementsB) {r->render(qp, scaler, renderParams);} qp.end(); } bool MapView2D::event(QEvent *event) { switch (event->type()) { case QEvent::Gesture: return gestureEvent(static_cast(event)); case QEvent::TouchBegin: case QEvent::TouchUpdate: case QEvent::TouchEnd: // prevent [additional] mouse events for undetected gestures [more than 1 finger] // TODO: not yet stable... improvements? if (static_cast(event)->touchPoints().count() == 2) {return true;} break; default: break; } // event not consumed. bubble it to following stages. // this will e.g. generate mouseMoveEvent etc. return QWidget::event(event); } bool MapView2D::gestureEvent(QGestureEvent *event) { if (QGesture* pinch = event->gesture(Qt::PinchGesture)) { const QPinchGesture* pg = static_cast(pinch); scaler.mulScale(pg->scaleFactor()); emit update(); return true; // event consumed } // event not consumed return false; }