#include #include #include #include #include "map/map.h" #include "mapaction.h" #include "popup.h" #include "tooltip.h" #include "mapitem.h" static void growLeft(Map *map, const Coordinates &c, QRectF &rect) { QPointF p(map->ll2xy(c)); if (p.x() < rect.left()) rect.setLeft(p.x()); } static void growRight(Map *map, const Coordinates &c, QRectF &rect) { QPointF p(map->ll2xy(c)); if (p.x() > rect.right()) rect.setRight(p.x()); } static void growTop(Map *map, const Coordinates &c, QRectF &rect) { QPointF p(map->ll2xy(c)); if (p.y() > rect.top()) rect.setTop(p.y()); } static void growBottom(Map *map, const Coordinates &c, QRectF &rect) { QPointF p(map->ll2xy(c)); if (p.y() < rect.bottom()) rect.setBottom(p.y()); } static QRectF bbox(const RectC &rect, Map *map, int samples = 100) { if (!rect.isValid()) return QRectF(); double dx = rect.width() / samples; double dy = rect.height() / samples; QPointF tl(map->ll2xy(rect.topLeft())); QPointF br(map->ll2xy(rect.bottomRight())); QRectF prect(tl, br); for (int i = 0; i <= samples; i++) { double x = remainder(rect.left() + i * dx, 360.0); growTop(map, Coordinates(x, rect.bottom()), prect); growBottom(map, Coordinates(x, rect.top()), prect); } for (int i = 0; i <= samples; i++) { double y = rect.bottom() + i * dy; growLeft(map, Coordinates(rect.left(), y), prect); growRight(map, Coordinates(rect.right(), y), prect); } return prect; } ToolTip MapItem::info() const { ToolTip tt; if (!_name.isEmpty()) tt.insert(tr("Name"), _name); if (!_fileName.isEmpty()) tt.insert(tr("File"), _fileName); return tt; } MapItem::MapItem(MapAction *action, Map *map, GraphicsItem *parent) : PlaneItem(parent) { Map *src = action->data().value(); Q_ASSERT(map->isReady()); _name = src->name(); _fileName = src->path(); _bounds = src->llBounds(); connect(this, &MapItem::triggered, action, &MapAction::trigger); _map = map; _digitalZoom = 0; _width = 2; _opacity = 0.5; QBrush brush(Qt::SolidPattern); _pen = QPen(brush, _width); updatePainterPath(); setCursor(Qt::ArrowCursor); setAcceptHoverEvents(true); } void MapItem::updatePainterPath() { _painterPath = QPainterPath(); QRectF r(bbox(_bounds, _map)); if (r.left() > r.right()) { QRectF r1(bbox(RectC(_bounds.topLeft(), Coordinates(180, _bounds.bottomRight().lat())), _map)); QRectF r2(bbox(RectC(Coordinates(-180, _bounds.topLeft().lat()), _bounds.bottomRight()), _map)); _painterPath.addRect(r1); _painterPath.addRect(r2); } else _painterPath.addRect(r); } void MapItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { Q_UNUSED(option); Q_UNUSED(widget); painter->setPen(_width ? _pen : QPen(Qt::NoPen)); painter->drawPath(_painterPath); painter->fillPath(_painterPath, _brush); //QPen p = QPen(QBrush(Qt::red), 0); //painter->setPen(p); //painter->drawRect(boundingRect()); } void MapItem::setMap(Map *map) { prepareGeometryChange(); _map = map; updatePainterPath(); } void MapItem::setColor(const QColor &color) { if (_pen.color() == color) return; QColor bc(color); bc.setAlphaF(_opacity * color.alphaF()); _pen.setColor(color); _brush = QBrush(bc); update(); } void MapItem::setOpacity(qreal opacity) { if (_opacity == opacity) return; _opacity = opacity; QColor bc(_pen.color()); bc.setAlphaF(_opacity * _pen.color().alphaF()); _brush = QBrush(bc); update(); } void MapItem::setWidth(qreal width) { if (_width == width) return; prepareGeometryChange(); _width = width; _pen.setWidthF(_width * pow(2, -_digitalZoom)); } void MapItem::setStyle(Qt::PenStyle style) { if (_pen.style() == style) return; _pen.setStyle(style); update(); } void MapItem::setDigitalZoom(int zoom) { if (_digitalZoom == zoom) return; prepareGeometryChange(); _digitalZoom = zoom; _pen.setWidthF(_width * pow(2, -_digitalZoom)); } void MapItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event) { Q_UNUSED(event); _pen.setWidthF((_width + 1) * pow(2, -_digitalZoom)); update(); } void MapItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) { Q_UNUSED(event); _pen.setWidthF(_width * pow(2, -_digitalZoom)); update(); } void MapItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) { Q_UNUSED(event); emit triggered(); }