#ifndef TOOLRULER_H #define TOOLRULER_H #include "Tool.h" /** * draw a ruler into the 2D map view */ class ToolRuler : public Tool { private: int mouseX; int mouseY; const bool fullSize = true; const int rs = 40; // ruler size const int tsMajor = 20; // major-tick size const int tsMinor = 5; // minor-tick size public: const std::string getName() const override { return "MapRuler"; } virtual bool mouseMoveEvent(MapView2D* m, QMouseEvent* e) override { (void) m; this->mouseX = e->x(); this->mouseY = e->y(); return false; } virtual void paintBefore(MapView2D* m, Painter& p) override { (void) m; // mouse-indicator within the image? if (fullSize) { const int w = p.width(); const int h = p.height(); p.setPenBrush(Qt::lightGray, Qt::NoBrush); p.p->drawLine(rs, mouseY, w, mouseY); p.p->drawLine(mouseX, rs, mouseX, h); } } virtual void paintAfter(MapView2D* m, Painter& p) override { (void) m; static const QColor c1(240,240,240); static const QColor c2(200,200,200); const int w = p.width(); const int h = p.height(); // ruler step-size depending on the current zoom level const float step = p.getScaler().getLODstep(); const float sStep = step / 10.0f; // the visible map-rect const Rect r = p.getScaler().getMapVisible(w, h, step); QRect rx(rs,0,w-0-rs,rs); QRect ry(0,rs,rs,h-1-rs); // background { // outline p.setPen(Qt::darkGray); p.setBrush(QColor(240,240,240)); // x-axis //QLinearGradient gx(0,0,0,rs); gx.setColorAt(0, c1); gx.setColorAt(1, c2); p.setBrush(gx); p.p->drawRect(rx); // y-axis //QLinearGradient gy(0,0,rs,0); gy.setColorAt(0, c2); gy.setColorAt(1, c1); p.setBrush(gy); p.p->drawRect(ry); } // mouse-indicator p.setPenBrush(Qt::darkGray, Qt::NoBrush); p.p->drawLine(0, mouseY, rs, mouseY); p.p->drawLine(mouseX, 0, mouseX, rs); p.setPenBrush(Qt::black, Qt::NoBrush); char buf[128]; // samller font QFont f = p.p->font(); f.setPointSize(8); p.p->setFont(f); // 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 p.p->setClipRect(ry); for (float y = r.y0; y <= r.y1; y += step) { // major-lines const float yMajor = p.s.yms(y); //if (yMajor < 0 || yMajor > h) {continue;} // stop at the end p.p->drawLine(0,yMajor, tsMajor,yMajor); // minor-lines for (float y1 = y+sStep; y1 < y+step; y1 += sStep) { const float yMinor = p.s.yms(y1); p.p->drawLine(0,yMinor, tsMinor,yMinor); } // text-label std::sprintf(buf, "%.1f", y); p.p->drawText(6, yMajor-2, buf); } // x-axis p.p->setClipRect(rx); for (float x = r.x0; x <= r.x1; x += step) { // major-lines const float xMajor = p.s.xms(x); //if (xMajor < 0 || xMajor > w) {continue;} // stop at the end p.p->drawLine(xMajor,0, xMajor,tsMajor); // minor-lines for (float x1 = x+sStep; x1 < x+step; x1 += sStep) { const float xMinor = p.s.xms(x1); p.p->drawLine(xMinor,0, xMinor,tsMinor); } // text-label std::sprintf(buf, "%.1f", x); p.p->drawText(xMajor+2, 18, buf); } p.p->setClipping(false); // snapped dot const Point2 mouseOnScreen(mouseX, mouseY); const Point2 mouseInMap = p.s.sm(mouseOnScreen); const Point2 snappedMouseInMap = p.s.snap(mouseInMap); p.drawDot(snappedMouseInMap); } }; #endif // TOOLRULER_H