1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2024-11-28 05:34:47 +01:00

Propper reimplementation of the path ticks

This commit is contained in:
Martin Tůma 2019-05-24 18:37:15 +02:00
parent 3b3559eacf
commit a16354a6ba
8 changed files with 136 additions and 107 deletions

View File

@ -178,7 +178,8 @@ HEADERS += src/common/config.h \
src/map/IMG/units.h \ src/map/IMG/units.h \
src/map/IMG/style.h \ src/map/IMG/style.h \
src/map/IMG/netfile.h \ src/map/IMG/netfile.h \
src/GUI/limitedcombobox.h src/GUI/limitedcombobox.h \
src/GUI/pathtickitem.h
SOURCES += src/main.cpp \ SOURCES += src/main.cpp \
src/common/coordinates.cpp \ src/common/coordinates.cpp \
src/common/rectc.cpp \ src/common/rectc.cpp \
@ -307,7 +308,8 @@ SOURCES += src/main.cpp \
src/map/IMG/lblfile.cpp \ src/map/IMG/lblfile.cpp \
src/map/IMG/vectortile.cpp \ src/map/IMG/vectortile.cpp \
src/map/IMG/style.cpp \ src/map/IMG/style.cpp \
src/map/IMG/netfile.cpp src/map/IMG/netfile.cpp \
src/GUI/pathtickitem.cpp
greaterThan(QT_MAJOR_VERSION, 4) { greaterThan(QT_MAJOR_VERSION, 4) {
HEADERS += src/data/geojsonparser.h HEADERS += src/data/geojsonparser.h

View File

@ -3,7 +3,7 @@
#include <QPainter> #include <QPainter>
#include "common/greatcircle.h" #include "common/greatcircle.h"
#include "map/map.h" #include "map/map.h"
#include "font.h" #include "pathtickitem.h"
#include "pathitem.h" #include "pathitem.h"
@ -19,18 +19,6 @@ static inline unsigned segments(qreal distance)
return ceil(distance / GEOGRAPHICAL_MILE); return ceil(distance / GEOGRAPHICAL_MILE);
} }
static QFont font()
{
QFont font;
font.setPixelSize(10);
font.setFamily(FONT_FAMILY);
font.setBold(true);
return font;
}
QFont PathItem::_font = font();
PathItem::PathItem(const Path &path, Map *map, QGraphicsItem *parent) PathItem::PathItem(const Path &path, Map *map, QGraphicsItem *parent)
: QGraphicsObject(parent), _path(path), _map(map) : QGraphicsObject(parent), _path(path), _map(map)
{ {
@ -46,7 +34,7 @@ PathItem::PathItem(const Path &path, Map *map, QGraphicsItem *parent)
updatePainterPath(); updatePainterPath();
updateShape(); updateShape();
updateTickRects(); updateTicks();
_markerDistance = _path.first().first().distance(); _markerDistance = _path.first().first().distance();
_marker = new MarkerItem(this); _marker = new MarkerItem(this);
@ -126,30 +114,7 @@ void PathItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
painter->setPen(_pen); painter->setPen(_pen);
painter->drawPath(_painterPath); painter->drawPath(_painterPath);
if (_showTicks) {
painter->setFont(_font);
painter->setRenderHint(QPainter::Antialiasing, false);
for (int i = 1; i < _tickCount; i++) {
QPoint pos(position(i * _tickSize * xInM()).toPoint());
QPointF arrow[3] = {QPointF(pos.x() - 0.5, pos.y()),
QPointF(pos.x() + 2.5, pos.y() - 3),
QPointF(pos.x() - 3.5, pos.y() - 3)};
QString val(QString::number(i * _tickSize));
QRectF br(_tickRect);
br.moveCenter(QPointF(pos.x() - 0.5, pos.y() - br.height()/2.0
- 2.5));
painter->setPen(Qt::white);
painter->setBrush(_pen.color());
painter->drawPolygon(arrow, 3);
painter->drawRoundedRect(br, 1.5, 1.5);
painter->drawText(br, Qt::AlignCenter, val);
}
}
/* /*
painter->setBrush(Qt::NoBrush);
painter->setPen(Qt::red); painter->setPen(Qt::red);
painter->drawRect(boundingRect()); painter->drawRect(boundingRect());
*/ */
@ -163,7 +128,7 @@ void PathItem::setMap(Map *map)
updatePainterPath(); updatePainterPath();
updateShape(); updateShape();
updateTickRects(); updateTicks();
QPointF pos = position(_markerDistance); QPointF pos = position(_markerDistance);
if (isValid(pos)) if (isValid(pos))
@ -350,24 +315,30 @@ unsigned PathItem::tickSize() const
return 1000; return 1000;
} }
void PathItem::updateTickRects() void PathItem::updateTicks()
{ {
_tickSize = tickSize(); for (int i = 0; i < _ticks.size(); i++)
qreal f = xInM(); delete _ticks[i];
_tickCount = (int)_path.last().last().distance() / (_tickSize * f) + 1; _ticks.clear();
QFontMetrics fm(_font); if (!_showTicks)
_tickRect = fm.boundingRect(QRect(), Qt::AlignCenter, return;
QString::number(qMax(_tickSize * (_tickCount - 1), 10)))
int ts = tickSize();
qreal f = xInM();
int tc = (int)_path.last().last().distance() / (ts * f);
QFontMetrics fm(PathTickItem::font());
QRect tr = fm.boundingRect(QRect(), Qt::AlignCenter,
QString::number(qMax(ts * (tc - 1), 10)))
.adjusted(-2, 0, 2, 0); .adjusted(-2, 0, 2, 0);
_tickBoundingRect = QRectF(); _ticks.resize(tc);
for (int i = 1; i < _tickCount; i++) { for (int i = 0; i < tc; i++) {
QPoint pos(position(i * _tickSize * xInM()).toPoint()); QPoint pos(position((i + 1) * ts * xInM()).toPoint());
QRectF br(_tickRect); _ticks[i] = new PathTickItem(tr, (i + 1) * ts, this);
br.moveCenter(QPointF(pos.x() - 0.5, pos.y() - br.height()/2.0 _ticks[i]->setPos(QPointF(pos.x() - 0.5, pos.y() - 0.5));
- 2.5)); _ticks[i]->setColor(_pen.color());
_tickBoundingRect |= br;
} }
} }
@ -378,6 +349,7 @@ void PathItem::showTicks(bool show)
prepareGeometryChange(); prepareGeometryChange();
_showTicks = show; _showTicks = show;
updateTicks();
} }
void PathItem::setUnits(Units units) void PathItem::setUnits(Units units)
@ -387,7 +359,7 @@ void PathItem::setUnits(Units units)
prepareGeometryChange(); prepareGeometryChange();
_units = units; _units = units;
updateTickRects(); updateTicks();
} }
void PathItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event) void PathItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
@ -411,10 +383,3 @@ void PathItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
emit selected(false); emit selected(false);
} }
QRectF PathItem::boundingRect() const
{
return _showTicks
? _shape.boundingRect() | _tickBoundingRect
: _shape.boundingRect();
}

View File

@ -8,6 +8,7 @@
#include "units.h" #include "units.h"
class Map; class Map;
class PathTickItem;
class PathItem : public QGraphicsObject class PathItem : public QGraphicsObject
{ {
@ -17,7 +18,7 @@ public:
PathItem(const Path &path, Map *map, QGraphicsItem *parent = 0); PathItem(const Path &path, Map *map, QGraphicsItem *parent = 0);
QPainterPath shape() const {return _shape;} QPainterPath shape() const {return _shape;}
QRectF boundingRect() const; QRectF boundingRect() const {return _shape.boundingRect();}
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QWidget *widget); QWidget *widget);
@ -43,10 +44,6 @@ public slots:
signals: signals:
void selected(bool); void selected(bool);
protected:
Path _path;
MarkerItem *_marker;
private: private:
const PathSegment *segment(qreal x) const; const PathSegment *segment(qreal x) const;
QPointF position(qreal distance) const; QPointF position(qreal distance) const;
@ -56,11 +53,12 @@ private:
qreal xInM() const; qreal xInM() const;
unsigned tickSize() const; unsigned tickSize() const;
void updateTickRects(); void updateTicks();
void hoverEnterEvent(QGraphicsSceneHoverEvent *event); void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
void hoverLeaveEvent(QGraphicsSceneHoverEvent *event); void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
Path _path;
Map *_map; Map *_map;
qreal _markerDistance; qreal _markerDistance;
int _digitalZoom; int _digitalZoom;
@ -72,11 +70,9 @@ private:
QPainterPath _painterPath; QPainterPath _painterPath;
bool _showMarker; bool _showMarker;
bool _showTicks; bool _showTicks;
QRect _tickRect;
QRectF _tickBoundingRect;
int _tickSize, _tickCount;
static QFont _font; MarkerItem *_marker;
QVector<PathTickItem*> _ticks;
}; };
#endif // PATHITEM_H #endif // PATHITEM_H

56
src/GUI/pathtickitem.cpp Normal file
View File

@ -0,0 +1,56 @@
#include <QPainter>
#include <QCursor>
#include "font.h"
#include "pathtickitem.h"
static QFont defaultFont()
{
QFont font;
font.setPixelSize(10);
font.setFamily(FONT_FAMILY);
font.setBold(true);
return font;
}
QFont PathTickItem::_font = defaultFont();
PathTickItem::PathTickItem(const QRectF &tickRect, int value,
QGraphicsItem *parent) : QGraphicsItem(parent), _tickRect(tickRect),
_text(QString::number(value))
{
_tickRect.moveCenter(QPointF(0, -_tickRect.height()/2.0 - 3));
setCursor(Qt::ArrowCursor);
setAcceptHoverEvents(true);
}
QRectF PathTickItem::boundingRect() const
{
return _tickRect.adjusted(0, 0, 0, 3);
}
void PathTickItem::paint(QPainter *painter,
const QStyleOptionGraphicsItem *option, QWidget *widget)
{
Q_UNUSED(option);
Q_UNUSED(widget);
QPointF arrow[3] = {QPointF(0, 0), QPointF(3, -3), QPointF(-3, -3)};
painter->setFont(_font);
painter->setRenderHint(QPainter::Antialiasing, false);
painter->setPen(Qt::white);
painter->setBrush(_brush);
painter->drawPolygon(arrow, 3);
painter->drawRoundedRect(_tickRect, 1.5, 1.5);
painter->drawText(_tickRect, Qt::AlignCenter, _text);
/*
painter->setBrush(Qt::NoBrush);
painter->setPen(Qt::red);
painter->drawRect(boundingRect());
*/
}

28
src/GUI/pathtickitem.h Normal file
View File

@ -0,0 +1,28 @@
#ifndef PATHTICKITEM_H
#define PATHTICKITEM_H
#include <QFont>
#include <QGraphicsItem>
class PathTickItem : public QGraphicsItem
{
public:
PathTickItem(const QRectF &tickRect, int value, QGraphicsItem *parent = 0);
QRectF boundingRect() const;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QWidget *widget);
void setColor(const QColor &color) {_brush = QBrush(color);}
static const QFont &font() {return _font;}
private:
QRectF _tickRect;
QString _text;
QBrush _brush;
static QFont _font;
};
#endif // PATHTICKITEM_H

View File

@ -15,7 +15,7 @@ QString RouteItem::toolTip(Units units) const
tt.insert(tr("Name"), _name); tt.insert(tr("Name"), _name);
if (!_desc.isEmpty()) if (!_desc.isEmpty())
tt.insert(tr("Description"), _desc); tt.insert(tr("Description"), _desc);
tt.insert(tr("Distance"), Format::distance(_path.last().last().distance(), tt.insert(tr("Distance"), Format::distance(path().last().last().distance(),
units)); units));
return tt.toString(); return tt.toString();
@ -26,8 +26,9 @@ RouteItem::RouteItem(const Route &route, Map *map, QGraphicsItem *parent)
{ {
const QVector<Waypoint> &waypoints = route.waypoints(); const QVector<Waypoint> &waypoints = route.waypoints();
_waypoints.resize(waypoints.size());
for (int i = 0; i < waypoints.size(); i++) for (int i = 0; i < waypoints.size(); i++)
new WaypointItem(waypoints.at(i), map, this); _waypoints[i] = new WaypointItem(waypoints.at(i), map, this);
_name = route.name(); _name = route.name();
_desc = route.description(); _desc = route.description();
@ -38,13 +39,8 @@ RouteItem::RouteItem(const Route &route, Map *map, QGraphicsItem *parent)
void RouteItem::setMap(Map *map) void RouteItem::setMap(Map *map)
{ {
QList<QGraphicsItem *> childs = childItems(); for (int i = 0; i < _waypoints.count(); i++)
for (int i = 0; i < childs.count(); i++) { _waypoints[i]->setMap(map);
if (childs.at(i) != _marker) {
WaypointItem *wi = static_cast<WaypointItem*>(childs.at(i));
wi->setMap(map);
}
}
PathItem::setMap(map); PathItem::setMap(map);
} }
@ -58,13 +54,8 @@ void RouteItem::setUnits(Units u)
setToolTip(toolTip(units())); setToolTip(toolTip(units()));
QList<QGraphicsItem *> childs = childItems(); for (int i = 0; i < _waypoints.count(); i++)
for (int i = 0; i < childs.count(); i++) { _waypoints[i]->setToolTipFormat(units(), _coordinatesFormat);
if (childs.at(i) != _marker) {
WaypointItem *wi = static_cast<WaypointItem*>(childs.at(i));
wi->setToolTipFormat(units(), _coordinatesFormat);
}
}
} }
void RouteItem::setCoordinatesFormat(CoordinatesFormat format) void RouteItem::setCoordinatesFormat(CoordinatesFormat format)
@ -74,30 +65,18 @@ void RouteItem::setCoordinatesFormat(CoordinatesFormat format)
_coordinatesFormat = format; _coordinatesFormat = format;
QList<QGraphicsItem *> childs = childItems(); for (int i = 0; i < _waypoints.count(); i++)
for (int i = 0; i < childs.count(); i++) { _waypoints[i]->setToolTipFormat(units(), _coordinatesFormat);
if (childs.at(i) != _marker) {
WaypointItem *wi = static_cast<WaypointItem*>(childs.at(i));
wi->setToolTipFormat(units(), _coordinatesFormat);
}
}
} }
void RouteItem::showWaypoints(bool show) void RouteItem::showWaypoints(bool show)
{ {
QList<QGraphicsItem *> childs = childItems(); for (int i = 0; i < _waypoints.count(); i++)
for (int i = 0; i < childs.count(); i++) _waypoints[i]->setVisible(show);
if (childs.at(i) != _marker)
childs.at(i)->setVisible(show);
} }
void RouteItem::showWaypointLabels(bool show) void RouteItem::showWaypointLabels(bool show)
{ {
QList<QGraphicsItem *> childs = childItems(); for (int i = 0; i < _waypoints.count(); i++)
for (int i = 0; i < childs.count(); i++) { _waypoints[i]->showLabel(show);
if (childs.at(i) != _marker) {
WaypointItem *wi = static_cast<WaypointItem*>(childs.at(i));
wi->showLabel(show);
}
}
} }

View File

@ -7,6 +7,7 @@
#include "format.h" #include "format.h"
class Map; class Map;
class WaypointItem;
class RouteItem : public PathItem class RouteItem : public PathItem
{ {
@ -28,6 +29,8 @@ private:
QString _name; QString _name;
QString _desc; QString _desc;
CoordinatesFormat _coordinatesFormat; CoordinatesFormat _coordinatesFormat;
QVector<WaypointItem*> _waypoints;
}; };
#endif // ROUTEITEM_H #endif // ROUTEITEM_H

View File

@ -13,7 +13,7 @@ QString TrackItem::toolTip(Units units) const
tt.insert(tr("Name"), _name); tt.insert(tr("Name"), _name);
if (!_desc.isEmpty()) if (!_desc.isEmpty())
tt.insert(tr("Description"), _desc); tt.insert(tr("Description"), _desc);
tt.insert(tr("Distance"), Format::distance(_path.last().last().distance(), tt.insert(tr("Distance"), Format::distance(path().last().last().distance(),
units)); units));
if (_time > 0) if (_time > 0)
tt.insert(tr("Total time"), Format::timeSpan(_time)); tt.insert(tr("Total time"), Format::timeSpan(_time));