1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2024-10-07 07:13:21 +02:00
GPXSee/src/GUI/mapitem.cpp

231 lines
4.3 KiB
C++
Raw Normal View History

#include <cmath>
2020-12-02 23:58:11 +01:00
#include <QCursor>
#include <QPainter>
#include <QGraphicsSceneMouseEvent>
#include "map/map.h"
2020-12-10 22:02:09 +01:00
#include "mapaction.h"
2020-12-02 23:58:11 +01:00
#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;
}
2020-12-02 23:58:11 +01:00
QString MapItem::info() const
{
ToolTip tt;
if (!_name.isEmpty())
tt.insert(tr("Name"), _name);
if (!_fileName.isEmpty())
tt.insert(tr("File"), _fileName);
return tt.toString();
}
2020-12-10 22:02:09 +01:00
MapItem::MapItem(MapAction *action, Map *map, GraphicsItem *parent)
2020-12-02 23:58:11 +01:00
: PlaneItem(parent)
{
2020-12-10 22:02:09 +01:00
Map *src = action->data().value<Map*>();
Q_ASSERT(map->isReady());
2020-12-02 23:58:11 +01:00
_name = src->name();
_fileName = src->path();
_bounds = src->llBounds();
2020-12-02 23:58:11 +01:00
2021-04-28 00:01:07 +02:00
connect(this, &MapItem::triggered, action, &MapAction::trigger);
2020-12-10 22:02:09 +01:00
2020-12-02 23:58:11 +01:00
_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);
2020-12-02 23:58:11 +01:00
} else
_painterPath.addRect(r);
2020-12-02 23:58:11 +01:00
}
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();
}