a whole lotta work!!
- refactoring - completely changed the tooling (adding elements) - better re-use for more stable editing - new elements - ui adjustments - LINT for stair-editing - many more changes
This commit is contained in:
0
mapview/2D/tools/Tool.cpp
Normal file
0
mapview/2D/tools/Tool.cpp
Normal file
58
mapview/2D/tools/Tool.h
Normal file
58
mapview/2D/tools/Tool.h
Normal file
@@ -0,0 +1,58 @@
|
||||
#ifndef TOOL_H
|
||||
#define TOOL_H
|
||||
|
||||
#include <QKeyEvent>
|
||||
#include <QMouseEvent>
|
||||
#include <QObject>
|
||||
|
||||
#include "../Painter.h"
|
||||
|
||||
class MapView2D;
|
||||
|
||||
/**
|
||||
* interface for every MapView tool.
|
||||
* a tool may be a background tool (e.g. a ruler-display, grid, ..)
|
||||
* or a foreground (active) one, which e.g. selects nodes, creates a new element, ...
|
||||
*/
|
||||
class Tool : public QObject {
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
Tool() {;}
|
||||
|
||||
virtual ~Tool() {;}
|
||||
|
||||
/** the tool must return its name here */
|
||||
virtual const std::string getName() const = 0;
|
||||
|
||||
/** the tool was activated (by user or by code) */
|
||||
virtual void becomesActive() {;}
|
||||
|
||||
/** the tool was deactivated (by user or by code) */
|
||||
virtual void becomesInactive() {;}
|
||||
|
||||
|
||||
/** events: return TRUE when you consumed the event */
|
||||
|
||||
virtual bool mousePressEvent(MapView2D* m, QMouseEvent* e) { (void) m; (void) e; return false; }
|
||||
virtual bool mouseMoveEvent(MapView2D* m, QMouseEvent* e) { (void) m; (void) e; return false; }
|
||||
virtual bool mouseReleaseEvent(MapView2D* m, QMouseEvent* e) { (void) m; (void) e; return false; }
|
||||
|
||||
virtual bool wheelEvent(MapView2D* m, QWheelEvent* e) { (void) m; (void) e; return false; }
|
||||
|
||||
virtual bool keyPressEvent(MapView2D* m, QKeyEvent* e) { (void) m; (void) e; return false; }
|
||||
|
||||
virtual void paintBefore(MapView2D* m, Painter& p) { (void) m; (void) p; }
|
||||
virtual void paintAfter(MapView2D* m, Painter& p) { (void) m; (void) p; }
|
||||
|
||||
virtual void layerChange(MapView2D* m) { (void) m; }
|
||||
|
||||
signals:
|
||||
|
||||
void onHelpTextChange(QString str);
|
||||
|
||||
};
|
||||
|
||||
#endif // TOOL_H
|
||||
87
mapview/2D/tools/ToolMapGrid.h
Normal file
87
mapview/2D/tools/ToolMapGrid.h
Normal file
@@ -0,0 +1,87 @@
|
||||
#ifndef TOOLMAPGRID_H
|
||||
#define TOOLMAPGRID_H
|
||||
|
||||
#include "Tool.h"
|
||||
|
||||
class ToolMapGrid : public Tool {
|
||||
|
||||
private:
|
||||
|
||||
bool show = true;
|
||||
|
||||
public:
|
||||
|
||||
const std::string getName() const override {
|
||||
return "MapGrid";
|
||||
}
|
||||
|
||||
virtual bool keyPressEvent(MapView2D* m, QKeyEvent* e) override {
|
||||
(void) m;
|
||||
if (e->key() == Qt::Key_NumberSign) { show = !show; return true; }
|
||||
return false;
|
||||
}
|
||||
|
||||
void paintBefore(MapView2D* m, Painter& p) override {
|
||||
|
||||
(void) m;
|
||||
|
||||
if (!show) {return;}
|
||||
|
||||
static const QColor cB(245,245,245);
|
||||
static const QColor cN(225,225,225);
|
||||
static const QColor c0(128,128,128);
|
||||
|
||||
int w = p.width();
|
||||
int h = p.height();
|
||||
|
||||
// grid-size
|
||||
const float step = p.getScaler().getLODstep();
|
||||
const float sStep = step/5;
|
||||
|
||||
// map-region visible on the screen
|
||||
const Rect r = p.getScaler().getMapVisible(w, h, step);
|
||||
|
||||
// x-lines
|
||||
for (float x = r.x0; x < r.x1; x += step) {
|
||||
|
||||
// major-lines (without center)
|
||||
if (std::abs(x) > 0.001) {
|
||||
p.setPenBrush(cN, Qt::NoBrush);
|
||||
p.drawLine(x, r.y0, x, r.y1);
|
||||
}
|
||||
|
||||
// minor-lines
|
||||
p.setPenBrush(cB, Qt::NoBrush);
|
||||
for (float x1 = x+sStep; x1 < x+step; x1 += sStep) {
|
||||
p.drawLine(x1, r.y0, x1, r.y1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// y-lines
|
||||
for (float y = r.y0; y < r.y1; y += step) {
|
||||
|
||||
// major-lines (without center)
|
||||
if (std::abs(y) > 0.001) {
|
||||
p.setPenBrush(cN, Qt::NoBrush);
|
||||
p.drawLine(r.x0, y, r.x1, y);
|
||||
}
|
||||
|
||||
// minor-lines
|
||||
p.setPenBrush(cB, Qt::NoBrush);
|
||||
for (float y1 = y+sStep; y1 < y+step; y1 += sStep) {
|
||||
p.drawLine(r.x0, y1, r.x1, y1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// thick center lines
|
||||
p.setPenBrush(c0, Qt::NoBrush);
|
||||
p.drawLine(0, r.y0, 0, r.y1);
|
||||
p.drawLine(r.x0, 0, r.x1, 0);
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif // TOOLMAPGRID_H
|
||||
37
mapview/2D/tools/ToolMapZoom.h
Normal file
37
mapview/2D/tools/ToolMapZoom.h
Normal file
@@ -0,0 +1,37 @@
|
||||
#ifndef TOOLMAPZOOM_H
|
||||
#define TOOLMAPZOOM_H
|
||||
|
||||
#include "Tool.h"
|
||||
#include "../MapView2D.h"
|
||||
|
||||
/**
|
||||
* this tool allows zooming in and out of the map
|
||||
*/
|
||||
class ToolMapZoom : public Tool {
|
||||
|
||||
public:
|
||||
|
||||
const std::string getName() const override {
|
||||
return "MapZoom";
|
||||
}
|
||||
|
||||
virtual bool wheelEvent(MapView2D* m, QWheelEvent* e) override {
|
||||
|
||||
Scaler& s = m->getScaler();
|
||||
|
||||
if (e->delta() < 0) {
|
||||
s.setScale(s.getScale() * 0.5);
|
||||
} else {
|
||||
s.setScale(s.getScale() / 0.5);
|
||||
}
|
||||
|
||||
if (s.getScale() > 1000) {s.setScale(1000);}
|
||||
if (s.getScale() < 5) {s.setScale(5);}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif // TOOLMAPZOOM_H
|
||||
59
mapview/2D/tools/ToolMoveMap.h
Normal file
59
mapview/2D/tools/ToolMoveMap.h
Normal file
@@ -0,0 +1,59 @@
|
||||
#ifndef TOOLMOVEMAP_H
|
||||
#define TOOLMOVEMAP_H
|
||||
|
||||
#include "Tool.h"
|
||||
#include "../MapView2D.h"
|
||||
|
||||
/**
|
||||
* this tool allows moving the 2D map
|
||||
*/
|
||||
class ToolMoveMap : public Tool {
|
||||
|
||||
private:
|
||||
|
||||
bool mouseIsDown = false;
|
||||
Point3 startOffset;
|
||||
int sx;
|
||||
int sy;
|
||||
|
||||
const std::string getName() const override {
|
||||
return "MapMove";
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
virtual bool mousePressEvent(MapView2D* m, QMouseEvent* e) override {
|
||||
if (e->button() == Qt::MouseButton::MidButton) {
|
||||
mouseIsDown = true;
|
||||
this->sx = e->x();
|
||||
this->sy = e->y();
|
||||
this->startOffset = m->getScaler().getOffset();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool mouseMoveEvent(MapView2D* m, QMouseEvent* e) override {
|
||||
if (!mouseIsDown) {return false;}
|
||||
m->getScaler().setOffset(startOffset);
|
||||
m->getScaler().addOffset(e->x()-sx, e->y()-sy);
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool mouseReleaseEvent(MapView2D* m, QMouseEvent* e) override {
|
||||
(void) m;
|
||||
(void) e;
|
||||
mouseIsDown = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
// virtual void keyPressEvent(MapView2D* m, QKeyEvent* e) override {
|
||||
// (void) m;
|
||||
// (void) e;
|
||||
// // TODO: move on arrow keys?
|
||||
// }
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // TOOLMOVEMAP_H
|
||||
154
mapview/2D/tools/ToolRuler.h
Normal file
154
mapview/2D/tools/ToolRuler.h
Normal file
@@ -0,0 +1,154 @@
|
||||
#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-1-rs,rs);
|
||||
QRect ry(0,rs,rs,h-1-rs);
|
||||
|
||||
// background
|
||||
{
|
||||
|
||||
// samller font
|
||||
QFont f = p.p->font(); f.setPointSize(8);
|
||||
p.p->setFont(f);
|
||||
|
||||
// outline
|
||||
p.setPen(Qt::darkGray);
|
||||
|
||||
// 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];
|
||||
|
||||
// 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
|
||||
0
mapview/2D/tools/ToolSelector.cpp
Normal file
0
mapview/2D/tools/ToolSelector.cpp
Normal file
304
mapview/2D/tools/ToolSelector.h
Normal file
304
mapview/2D/tools/ToolSelector.h
Normal file
@@ -0,0 +1,304 @@
|
||||
#ifndef TOOLSELECTOR_H
|
||||
#define TOOLSELECTOR_H
|
||||
|
||||
|
||||
#include "Tool.h"
|
||||
#include "../MapView2D.h"
|
||||
|
||||
#include "../../model/MapModelElement.h"
|
||||
#include "../../model/MapModel.h"
|
||||
|
||||
|
||||
/**
|
||||
* this tool allows:
|
||||
* - selecting elements within the 2D view (focus/unfocus)
|
||||
* - selecting and moving nodes of elements inheriting from HasMoveableNodes
|
||||
*
|
||||
*/
|
||||
class ToolSelector : public Tool {
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
|
||||
/** the currently focused MapElement (if any) */
|
||||
MapModelElement* focused = nullptr;
|
||||
|
||||
/** whether the mouse-button is currently pressed */
|
||||
bool mouseIsDown = false;
|
||||
|
||||
public:
|
||||
|
||||
virtual ~ToolSelector() {;}
|
||||
|
||||
|
||||
const std::string getName() const override {
|
||||
return "Selection";
|
||||
}
|
||||
|
||||
void becomesActive() override {
|
||||
showHelp();
|
||||
}
|
||||
|
||||
/** needed eg. when the focused element gets invalid (switching visible layers) */
|
||||
void layerChange(MapView2D* m) override {
|
||||
(void) m;
|
||||
setFocused(m, nullptr);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void processUnfocus(MapView2D* m, MapModelElement* elem) {
|
||||
|
||||
MV2DElement* me = elem->getMV2D();
|
||||
if (!me) {return;}
|
||||
|
||||
// elements has selectedable nodes? unselect them
|
||||
if (dynamic_cast<HasMoveableNodes*>(me)) {
|
||||
dynamic_cast<HasMoveableNodes*>(me)->onNodeUnselect(m);
|
||||
}
|
||||
|
||||
// let the element itself process the unfocus
|
||||
me->unfocus();
|
||||
|
||||
}
|
||||
|
||||
void processPress(MapView2D* m, const Point2 p, MapModelElement* elem) {
|
||||
|
||||
MV2DElement* me = elem->getMV2D();
|
||||
if (!me) {return;}
|
||||
|
||||
// let the element itself process all events
|
||||
me->mousePressed(m, p);
|
||||
|
||||
}
|
||||
|
||||
void processMove(MapView2D* m, const Point2 p, MapModelElement* elem) {
|
||||
|
||||
MV2DElement* me = elem->getMV2D();
|
||||
if (!me) {return;}
|
||||
|
||||
// elements has selectedable nodes? try to process them
|
||||
if (dynamic_cast<HasMoveableNodes*>(me)) {
|
||||
if (moveNode(m, p, dynamic_cast<HasMoveableNodes*>(me))) {return;}
|
||||
}
|
||||
|
||||
// otherwise: let the element itself process all events
|
||||
me->mouseMove(m, p);
|
||||
|
||||
}
|
||||
|
||||
void processRelease(MapView2D* m, const Point2 p, MapModelElement* elem) {
|
||||
|
||||
MV2DElement* me = elem->getMV2D();
|
||||
if (!me) {return;}
|
||||
|
||||
// element has selectedable nodes? try to process them
|
||||
if (dynamic_cast<HasMoveableNodes*>(me)) {
|
||||
if (selectNode(m, p, dynamic_cast<HasMoveableNodes*>(me))) {return;}
|
||||
}
|
||||
|
||||
// otherwise: let the element itself process all events
|
||||
me->mouseReleased(m, p);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
private:
|
||||
|
||||
/** the given element has selectable nodes. try to select the one near to the mouse. true if successful */
|
||||
bool selectNode(MapView2D* v, Point2 p, HasMoveableNodes* elem) {
|
||||
|
||||
// select a new point on mouse-release (more robust than on mouse-press)
|
||||
|
||||
// find the node nearest to p
|
||||
auto comp = [&] (const MoveableNode& n1, const MoveableNode& n2) {return n1.pos.getDistance(p) < n2.pos.getDistance(p);};
|
||||
auto lst = elem->getMoveableNodes();
|
||||
auto it = std::min_element(lst.begin(), lst.end(), comp);
|
||||
|
||||
// is the nearest point below the threshold?
|
||||
const float t = v->getScaler().sm(CFG::SEL_THRESHOLD_SIZE_PX);
|
||||
const float d = it->pos.getDistance(p);
|
||||
if (d < t) {
|
||||
elem->onNodeSelect(v, it->userIdx);
|
||||
return true;
|
||||
} else {
|
||||
elem->onNodeSelect(v, -1);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** move the currently selected node. true if successful */
|
||||
bool moveNode(MapView2D* v, Point2 p, HasMoveableNodes* elem) {
|
||||
|
||||
// no node selected? -> done
|
||||
if (elem->getSelectedNode() == -1) {return false;}
|
||||
|
||||
// snap the node
|
||||
const Point2 pSnapped = v->getScaler().snap(p);
|
||||
|
||||
// move
|
||||
elem->onNodeMove(v, elem->getSelectedNode(), pSnapped);
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
private:
|
||||
|
||||
void showHelp() {
|
||||
if (focused) {emit onHelpTextChange("select one of the element's nodes");}
|
||||
if (!focused) {emit onHelpTextChange("select an element by clicking on it");}
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 setFocused(MapView2D* v, MapModelElement* el) {
|
||||
|
||||
// whether the focus has changed or not
|
||||
const bool focusChanged = (focused != el);
|
||||
|
||||
if (focusChanged) {
|
||||
|
||||
// unfocus the old one (if any)
|
||||
if (focused) {processUnfocus(v, focused);}
|
||||
|
||||
// set the currently focused object (if any)
|
||||
focused = el;
|
||||
|
||||
// focus the new one (if any)
|
||||
if (focused) {focused->getMV2D()->focus();}
|
||||
|
||||
// update the help-text
|
||||
showHelp();
|
||||
|
||||
emit onMapElementSelected(el);
|
||||
|
||||
}
|
||||
|
||||
// done
|
||||
return focusChanged;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
private:
|
||||
|
||||
virtual bool mousePressEvent(MapView2D* m, QMouseEvent* e) override {
|
||||
|
||||
if (e->button() != Qt::MouseButton::LeftButton) {return false;}
|
||||
|
||||
mouseIsDown = true;
|
||||
|
||||
const Scaler& s = m->getScaler();
|
||||
const Point2 p2(s.xsm(e->x()), s.ysm(e->y()));
|
||||
|
||||
const float g = m->getScaler().sm(15); // increase each BBox by 15 px (needed mainly for hor/ver lines)
|
||||
|
||||
// get all elements with bounding-box matchings
|
||||
std::vector<MapModelElement*> possible;
|
||||
for (MapModelElement* el : m->getModel()->getSelectedLayerElements()) {
|
||||
if (!el->getMV2D()) {continue;}
|
||||
BBox2 bbox = el->getMV2D()->getBoundingBox(); // elements 2D bbox
|
||||
bbox.grow(Point2(g, g)); // grow a little (needed for straight lines)
|
||||
if (bbox.contains(p2)) {possible.push_back(el);} // intersection?
|
||||
}
|
||||
|
||||
// among those, find the best-matching one (smallest distance to an intersection)
|
||||
auto lambda = [&] (const MapModelElement* el1, const MapModelElement* el2) {return el1->getMV2D()->getMinDistanceXY(p2) < el2->getMV2D()->getMinDistanceXY(p2);};
|
||||
auto it = std::min_element(possible.begin(), possible.end(), lambda);
|
||||
MapModelElement* el = (it == possible.end()) ? (nullptr) : (*it);
|
||||
|
||||
|
||||
|
||||
// focus changed? -> unfocus the old one (if any)
|
||||
if (setFocused(m, el)) {
|
||||
|
||||
;
|
||||
|
||||
} else {
|
||||
|
||||
// focus kept. provide the currently focused element with events
|
||||
if (focused) {
|
||||
processPress(m, p2, focused);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
virtual bool mouseMoveEvent(MapView2D* m, QMouseEvent* e) override {
|
||||
|
||||
const Scaler& s = m->getScaler();
|
||||
Point2 p2(s.xsm(e->x()), s.ysm(e->y()));
|
||||
|
||||
// mouse pressed?
|
||||
if (mouseIsDown) {
|
||||
|
||||
// provide the focused element with the mouse event?
|
||||
if (focused) {processMove(m, p2, focused);}
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
virtual bool mouseReleaseEvent(MapView2D* m, QMouseEvent* e) override {
|
||||
|
||||
const Scaler& s = m->getScaler();
|
||||
Point2 p2(s.xsm(e->x()), s.ysm(e->y()));
|
||||
|
||||
// provide the focused element with the mouse event?
|
||||
if (focused) {processRelease(m, p2, focused);}
|
||||
|
||||
mouseIsDown = false;
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
virtual bool keyPressEvent(MapView2D* m, QKeyEvent* e) override {
|
||||
|
||||
(void) m;
|
||||
|
||||
if (focused) {
|
||||
|
||||
// pass it to the element which may consume this event
|
||||
if (focused->getMV2D()->keyPressEvent(m, e)) {return false;}
|
||||
|
||||
// not consumed -> additional options
|
||||
|
||||
// ESCAPE -> unfocus
|
||||
if (e->key() == Qt::Key_Escape) {setFocused(m, nullptr);}
|
||||
|
||||
// DELETE -> delete
|
||||
if (e->key() == Qt::Key_Delete) {
|
||||
focused->deleteMe();
|
||||
setFocused(m, nullptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
signals:
|
||||
|
||||
/** map element was selected */
|
||||
void onMapElementSelected(MapModelElement* el);
|
||||
|
||||
};
|
||||
|
||||
#endif // TOOLSELECTOR_H
|
||||
0
mapview/2D/tools/Tools.cpp
Normal file
0
mapview/2D/tools/Tools.cpp
Normal file
126
mapview/2D/tools/Tools.h
Normal file
126
mapview/2D/tools/Tools.h
Normal file
@@ -0,0 +1,126 @@
|
||||
#ifndef TOOLS_H
|
||||
#define TOOLS_H
|
||||
|
||||
#include <vector>
|
||||
#include "Tool.h"
|
||||
|
||||
/**
|
||||
* combine several tools under the interface for one tool
|
||||
*/
|
||||
class Tools : public QObject { //public Tool {
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
|
||||
/** all added tools */
|
||||
std::vector<Tool*> backgroundTools;
|
||||
Tool* mainTool = nullptr;
|
||||
|
||||
|
||||
signals:
|
||||
|
||||
void mainToolChanged();
|
||||
|
||||
void onHelpTextChange(QString str);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
Tools() {
|
||||
;
|
||||
}
|
||||
|
||||
virtual ~Tools() {
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const std::string getName() const {//override {
|
||||
return (mainTool) ? (mainTool->getName()) : ("");
|
||||
}
|
||||
|
||||
|
||||
/** add a new background-helper-tool (ruler, grid, ..) those are always processed! */
|
||||
void addBackground(Tool* t) {
|
||||
backgroundTools.push_back(t);
|
||||
}
|
||||
|
||||
/** remove this tool */
|
||||
void removeBackground(Tool* t) {
|
||||
backgroundTools.erase(std::remove(backgroundTools.begin(), backgroundTools.end(), t));
|
||||
}
|
||||
|
||||
/** set the currently active main tool. there is only one that can be active! (e.g. selector, new wall, new polygon, ..) */
|
||||
void setMain(Tool* t) {
|
||||
if (this->mainTool) {
|
||||
this->mainTool->becomesInactive();
|
||||
disconnect(this->mainTool, &Tool::onHelpTextChange, this, &Tools::onHelpTextChange);
|
||||
}
|
||||
this->mainTool = t;
|
||||
emit mainToolChanged();
|
||||
if (this->mainTool) {
|
||||
connect(this->mainTool, &Tool::onHelpTextChange, this, &Tools::onHelpTextChange);
|
||||
this->mainTool->becomesActive();
|
||||
}
|
||||
}
|
||||
|
||||
/** get the current main tool */
|
||||
Tool* getMain() {
|
||||
return this->mainTool;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
virtual bool mousePressEvent(MapView2D* m, QMouseEvent* e) {//override {
|
||||
if (mainTool) {mainTool->mousePressEvent(m, e);}
|
||||
for (Tool* t : backgroundTools) { if(t->mousePressEvent(m, e)) {return true;} }
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool mouseMoveEvent(MapView2D* m, QMouseEvent* e) {//override {
|
||||
if (mainTool) {mainTool->mouseMoveEvent(m, e);}
|
||||
for (Tool* t : backgroundTools) { if(t->mouseMoveEvent(m, e)) {return true;} }
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool mouseReleaseEvent(MapView2D* m, QMouseEvent* e) {//override {
|
||||
if (mainTool) {mainTool->mouseReleaseEvent(m, e);}
|
||||
for (Tool* t : backgroundTools) { if(t->mouseReleaseEvent(m, e)) {return true;} }
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool wheelEvent(MapView2D* m, QWheelEvent* e) {//override {
|
||||
if (mainTool) {mainTool->wheelEvent(m, e);}
|
||||
for (Tool* t : backgroundTools) { if(t->wheelEvent(m, e)) {return true;} }
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool keyPressEvent(MapView2D* m, QKeyEvent* e) {//override {
|
||||
if (mainTool) {mainTool->keyPressEvent(m, e);}
|
||||
for (Tool* t : backgroundTools) { if(t->keyPressEvent(m, e)) {return true;} }
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
virtual void paintBefore(MapView2D* m, Painter& p) {//override {
|
||||
for (Tool* t : backgroundTools) {t->paintBefore(m, p);}
|
||||
if (mainTool) {mainTool->paintBefore(m, p);}
|
||||
}
|
||||
|
||||
virtual void paintAfter(MapView2D* m, Painter& p) {//override {
|
||||
for (Tool* t : backgroundTools) {t->paintAfter(m, p);}
|
||||
if (mainTool) {mainTool->paintAfter(m, p);}
|
||||
}
|
||||
|
||||
virtual void layerChange(MapView2D* m) {//override {
|
||||
for (Tool* t : backgroundTools) {t->layerChange(m);}
|
||||
if (mainTool) {mainTool->layerChange(m);}
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // TOOLS_H
|
||||
Reference in New Issue
Block a user