Map API refactoring
[GPXSee.git] / src / GUI / mapitem.cpp
blobaf275a1927ca1079ac52d1d8ea82e383e9182730
1 #include <cmath>
2 #include <QCursor>
3 #include <QPainter>
4 #include <QGraphicsSceneMouseEvent>
5 #include "map/map.h"
6 #include "mapaction.h"
7 #include "popup.h"
8 #include "tooltip.h"
9 #include "mapitem.h"
12 static void growLeft(Map *map, const Coordinates &c, QRectF &rect)
14 QPointF p(map->ll2xy(c));
16 if (p.x() < rect.left())
17 rect.setLeft(p.x());
20 static void growRight(Map *map, const Coordinates &c, QRectF &rect)
23 QPointF p(map->ll2xy(c));
25 if (p.x() > rect.right())
26 rect.setRight(p.x());
29 static void growTop(Map *map, const Coordinates &c, QRectF &rect)
31 QPointF p(map->ll2xy(c));
33 if (p.y() > rect.top())
34 rect.setTop(p.y());
37 static void growBottom(Map *map, const Coordinates &c, QRectF &rect)
39 QPointF p(map->ll2xy(c));
41 if (p.y() < rect.bottom())
42 rect.setBottom(p.y());
45 static QRectF bbox(const RectC &rect, Map *map, int samples = 100)
47 if (!rect.isValid())
48 return QRectF();
50 double dx = rect.width() / samples;
51 double dy = rect.height() / samples;
53 QPointF tl(map->ll2xy(rect.topLeft()));
54 QPointF br(map->ll2xy(rect.bottomRight()));
55 QRectF prect(tl, br);
57 for (int i = 0; i <= samples; i++) {
58 double x = remainder(rect.left() + i * dx, 360.0);
59 growTop(map, Coordinates(x, rect.bottom()), prect);
60 growBottom(map, Coordinates(x, rect.top()), prect);
63 for (int i = 0; i <= samples; i++) {
64 double y = rect.bottom() + i * dy;
65 growLeft(map, Coordinates(rect.left(), y), prect);
66 growRight(map, Coordinates(rect.right(), y), prect);
69 return prect;
72 ToolTip MapItem::info() const
74 ToolTip tt;
76 if (!_name.isEmpty())
77 tt.insert(tr("Name"), _name);
78 if (!_fileName.isEmpty())
79 tt.insert(tr("File"), Util::displayName(_fileName));
81 return tt;
84 MapItem::MapItem(MapAction *action, Map *map, const Projection &proj,
85 GraphicsItem *parent) : PlaneItem(parent)
87 Map *src = action->data().value<Map*>();
88 Q_ASSERT(map->isReady());
90 _name = src->name();
91 _fileName = src->path();
92 _bounds = src->llBounds(proj);
94 connect(this, &MapItem::triggered, action, &MapAction::trigger);
96 _digitalZoom = 0;
98 _width = 2;
99 _opacity = 0.5;
100 QBrush brush(Qt::SolidPattern);
101 _pen = QPen(brush, _width);
103 updatePainterPath(map);
105 setCursor(Qt::ArrowCursor);
106 setAcceptHoverEvents(true);
109 void MapItem::updatePainterPath(Map *map)
111 _painterPath = QPainterPath();
113 QRectF r(bbox(_bounds, map));
115 if (r.left() > r.right()) {
116 QRectF r1(bbox(RectC(_bounds.topLeft(),
117 Coordinates(180, _bounds.bottomRight().lat())), map));
118 QRectF r2(bbox(RectC(Coordinates(-180, _bounds.topLeft().lat()),
119 _bounds.bottomRight()), map));
121 _painterPath.addRect(r1);
122 _painterPath.addRect(r2);
123 } else
124 _painterPath.addRect(r);
127 void MapItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
128 QWidget *widget)
130 Q_UNUSED(option);
131 Q_UNUSED(widget);
133 painter->setPen(_width ? _pen : QPen(Qt::NoPen));
134 painter->drawPath(_painterPath);
135 painter->fillPath(_painterPath, _brush);
137 //QPen p = QPen(QBrush(Qt::red), 0);
138 //painter->setPen(p);
139 //painter->drawRect(boundingRect());
142 void MapItem::setMap(Map *map)
144 prepareGeometryChange();
145 updatePainterPath(map);
148 void MapItem::setColor(const QColor &color)
150 if (_pen.color() == color)
151 return;
153 QColor bc(color);
154 bc.setAlphaF(_opacity * color.alphaF());
156 _pen.setColor(color);
157 _brush = QBrush(bc);
158 update();
161 void MapItem::setOpacity(qreal opacity)
163 if (_opacity == opacity)
164 return;
166 _opacity = opacity;
167 QColor bc(_pen.color());
168 bc.setAlphaF(_opacity * _pen.color().alphaF());
169 _brush = QBrush(bc);
171 update();
174 void MapItem::setWidth(qreal width)
176 if (_width == width)
177 return;
179 prepareGeometryChange();
181 _width = width;
182 _pen.setWidthF(_width * pow(2, -_digitalZoom));
185 void MapItem::setPenStyle(Qt::PenStyle style)
187 if (_pen.style() == style)
188 return;
190 _pen.setStyle(style);
191 update();
194 void MapItem::setDigitalZoom(int zoom)
196 if (_digitalZoom == zoom)
197 return;
199 prepareGeometryChange();
201 _digitalZoom = zoom;
202 _pen.setWidthF(_width * pow(2, -_digitalZoom));
205 void MapItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
207 Q_UNUSED(event);
209 _pen.setWidthF((_width + 1) * pow(2, -_digitalZoom));
210 update();
212 #ifdef Q_OS_ANDROID
213 Popup::show(event->screenPos(), info(), event->widget());
214 #endif // Q_OS_ANDROID
217 void MapItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
219 Q_UNUSED(event);
221 _pen.setWidthF(_width * pow(2, -_digitalZoom));
222 update();
225 void MapItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
227 Q_UNUSED(event);
229 emit triggered();