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

Improved graph slider and path marker handling

+ related refactoring
This commit is contained in:
Martin Tůma 2021-01-17 16:02:37 +01:00
parent 7217f9acfc
commit 591560c0eb
12 changed files with 190 additions and 112 deletions

View File

@ -85,7 +85,7 @@ const GraphSegment *GraphItem::segment(qreal x, GraphType type) const
return 0; return 0;
} }
qreal GraphItem::yAtX(qreal x) qreal GraphItem::yAtX(qreal x) const
{ {
const GraphSegment *seg = segment(x, _type); const GraphSegment *seg = segment(x, _type);
if (!seg) if (!seg)
@ -106,7 +106,7 @@ qreal GraphItem::yAtX(qreal x)
else if (p.x(_type) < x) else if (p.x(_type) < x)
low = mid + 1; low = mid + 1;
else else
return -p.y(); return p.y();
} }
QLineF l; QLineF l;
@ -117,11 +117,14 @@ qreal GraphItem::yAtX(qreal x)
l = QLineF(seg->at(mid-1).x(_type), seg->at(mid-1).y(), l = QLineF(seg->at(mid-1).x(_type), seg->at(mid-1).y(),
seg->at(mid).x(_type), seg->at(mid).y()); seg->at(mid).x(_type), seg->at(mid).y());
return -l.pointAt((x - l.p1().x()) / (l.p2().x() - l.p1().x())).y(); return l.pointAt((x - l.p1().x()) / (l.p2().x() - l.p1().x())).y();
} }
qreal GraphItem::distanceAtTime(qreal time) qreal GraphItem::distanceAtTime(qreal time) const
{ {
if (!_time)
return NAN;
const GraphSegment *seg = segment(time, Time); const GraphSegment *seg = segment(time, Time);
if (!seg) if (!seg)
return NAN; return NAN;
@ -155,12 +158,42 @@ qreal GraphItem::distanceAtTime(qreal time)
return l.pointAt((time - l.p1().x()) / (l.p2().x() - l.p1().x())).y(); return l.pointAt((time - l.p1().x()) / (l.p2().x() - l.p1().x())).y();
} }
void GraphItem::emitSliderPositionChanged(qreal pos) qreal GraphItem::timeAtDistance(qreal distance) const
{ {
if (_type == Time) if (!_time)
emit sliderPositionChanged(_time ? distanceAtTime(pos) : NAN); return NAN;
const GraphSegment *seg = segment(distance, Distance);
if (!seg)
return NAN;
int low = 0;
int high = seg->count() - 1;
int mid = 0;
if (!(distance >= seg->at(low).s() && distance <= seg->at(high).s()))
return NAN;
while (low <= high) {
mid = low + ((high - low) / 2);
const GraphPoint &p = seg->at(mid);
if (p.s() > distance)
high = mid - 1;
else if (p.s() < distance)
low = mid + 1;
else
return seg->at(mid).t();
}
QLineF l;
if (seg->at(mid).s() < distance)
l = QLineF(seg->at(mid).s(), seg->at(mid).t(), seg->at(mid+1).s(),
seg->at(mid+1).t());
else else
emit sliderPositionChanged(pos); l = QLineF(seg->at(mid-1).s(), seg->at(mid-1).t(),
seg->at(mid).s(), seg->at(mid).t());
return l.pointAt((distance - l.p1().x()) / (l.p2().x() - l.p1().x())).y();
} }
void GraphItem::hover(bool hover) void GraphItem::hover(bool hover)

View File

@ -23,6 +23,7 @@ public:
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QWidget *widget); QWidget *widget);
GraphType graphType() const {return _type;}
const QRectF &bounds() const {return _bounds;} const QRectF &bounds() const {return _bounds;}
qreal max() const; qreal max() const;
@ -38,17 +39,16 @@ public:
GraphItem *secondaryGraph() const {return _secondaryGraph;} GraphItem *secondaryGraph() const {return _secondaryGraph;}
void setSecondaryGraph(GraphItem *graph) {_secondaryGraph = graph;} void setSecondaryGraph(GraphItem *graph) {_secondaryGraph = graph;}
qreal yAtX(qreal x); qreal yAtX(qreal x) const;
qreal distanceAtTime(qreal time); qreal distanceAtTime(qreal time) const;
qreal timeAtDistance(qreal distance) const;
void redraw(); void redraw();
signals: signals:
void sliderPositionChanged(qreal);
void selected(bool); void selected(bool);
public slots: public slots:
void emitSliderPositionChanged(qreal);
void hover(bool hover); void hover(bool hover);
protected: protected:

View File

@ -1,6 +1,7 @@
#ifndef GRAPHTAB_H #ifndef GRAPHTAB_H
#define GRAPHTAB_H #define GRAPHTAB_H
#include <QtGlobal>
#include <QList> #include <QList>
#include "graphview.h" #include "graphview.h"
#include "units.h" #include "units.h"
@ -14,7 +15,12 @@ class GraphTab : public GraphView
Q_OBJECT Q_OBJECT
public: public:
GraphTab(QWidget *parent = 0) : GraphView(parent) {} GraphTab(QWidget *parent = 0) : GraphView(parent)
{
#if defined(Q_OS_WIN32) || defined(Q_OS_MAC)
setFrameShape(QFrame::NoFrame);
#endif // Q_OS_WIN32 || Q_OS_MAC
}
virtual ~GraphTab() {} virtual ~GraphTab() {}
virtual QString label() const = 0; virtual QString label() const = 0;

View File

@ -179,6 +179,13 @@ void GraphView::setGraphType(GraphType type)
_xLabel = tr("Time"); _xLabel = tr("Time");
setXUnits(); setXUnits();
if (singleGraph())
_sliderPos = (type == Distance)
? _graphs.first()->distanceAtTime(_sliderPos)
: _graphs.first()->timeAtDistance(_sliderPos);
else
_sliderPos = 0;
redraw(); redraw();
} }
@ -194,9 +201,6 @@ void GraphView::showSliderInfo(bool show)
void GraphView::addGraph(GraphItem *graph) void GraphView::addGraph(GraphItem *graph)
{ {
connect(this, SIGNAL(sliderPositionChanged(qreal)), graph,
SLOT(emitSliderPositionChanged(qreal)));
_graphs.append(graph); _graphs.append(graph);
if (!graph->bounds().isNull()) if (!graph->bounds().isNull())
_scene->addItem(graph); _scene->addItem(graph);
@ -207,9 +211,6 @@ void GraphView::addGraph(GraphItem *graph)
void GraphView::removeGraph(GraphItem *graph) void GraphView::removeGraph(GraphItem *graph)
{ {
disconnect(this, SIGNAL(sliderPositionChanged(qreal)), graph,
SLOT(emitSliderPositionChanged(qreal)));
_graphs.removeOne(graph); _graphs.removeOne(graph);
_scene->removeItem(graph); _scene->removeItem(graph);
@ -434,12 +435,17 @@ void GraphView::updateSliderPosition()
} }
} }
bool GraphView::singleGraph() const
{
return (_graphs.count() == 1
|| (_graphs.count() == 2 && _graphs.first()->secondaryGraph()));
}
void GraphView::updateSliderInfo() void GraphView::updateSliderInfo()
{ {
QLocale l(QLocale::system()); QLocale l(QLocale::system());
qreal r = 0, y = 0; qreal r = 0, y = 0;
GraphItem *cardinal = (_graphs.count() == 1 || (_graphs.count() == 2 GraphItem *cardinal = singleGraph() ? _graphs.first() : 0;
&& _graphs.first()->secondaryGraph())) ? _graphs.first() : 0;
if (cardinal) { if (cardinal) {
QRectF br(_bounds); QRectF br(_bounds);
@ -447,7 +453,7 @@ void GraphView::updateSliderInfo()
br.adjust(0, -(_minYRange/2 - br.height()/2), 0, br.adjust(0, -(_minYRange/2 - br.height()/2), 0,
_minYRange/2 - br.height()/2); _minYRange/2 - br.height()/2);
y = cardinal->yAtX(_sliderPos); y = -cardinal->yAtX(_sliderPos);
r = (y - br.bottom()) / br.height(); r = (y - br.bottom()) / br.height();
} }
@ -463,7 +469,7 @@ void GraphView::updateSliderInfo()
QString yText((!cardinal) ? QString() : l.toString(-y * _yScale + _yOffset, QString yText((!cardinal) ? QString() : l.toString(-y * _yScale + _yOffset,
'f', _precision) + UNIT_SPACE + _yUnits); 'f', _precision) + UNIT_SPACE + _yUnits);
if (cardinal && cardinal->secondaryGraph()) { if (cardinal && cardinal->secondaryGraph()) {
qreal delta = y - cardinal->secondaryGraph()->yAtX(_sliderPos); qreal delta = y + cardinal->secondaryGraph()->yAtX(_sliderPos);
yText += QString(" ") + QChar(0x0394) + l.toString(-delta * _yScale yText += QString(" ") + QChar(0x0394) + l.toString(-delta * _yScale
+ _yOffset, 'f', _precision) + UNIT_SPACE + _yUnits; + _yOffset, 'f', _precision) + UNIT_SPACE + _yUnits;
} }

View File

@ -43,6 +43,8 @@ public:
void setSliderPosition(qreal pos); void setSliderPosition(qreal pos);
void setSliderColor(const QColor &color); void setSliderColor(const QColor &color);
qreal sliderPosition() const {return _sliderPos;}
signals: signals:
void sliderPositionChanged(qreal); void sliderPositionChanged(qreal);
@ -91,6 +93,7 @@ private:
void updateSliderInfo(); void updateSliderInfo();
void removeItem(QGraphicsItem *item); void removeItem(QGraphicsItem *item);
void addItem(QGraphicsItem *item); void addItem(QGraphicsItem *item);
bool singleGraph() const;
GraphicsScene *_scene; GraphicsScene *_scene;

View File

@ -90,8 +90,7 @@ GUI::GUI()
_routeDistance = 0; _routeDistance = 0;
_time = 0; _time = 0;
_movingTime = 0; _movingTime = 0;
_lastGraphTab = 0;
_sliderPos = 0;
_dataDir = QDir::homePath(); _dataDir = QDir::homePath();
_mapDir = QDir::homePath(); _mapDir = QDir::homePath();
@ -284,7 +283,7 @@ void GUI::createActions()
_overlapPOIAction->setMenuRole(QAction::NoRole); _overlapPOIAction->setMenuRole(QAction::NoRole);
_overlapPOIAction->setCheckable(true); _overlapPOIAction->setCheckable(true);
connect(_overlapPOIAction, SIGNAL(triggered(bool)), _mapView, connect(_overlapPOIAction, SIGNAL(triggered(bool)), _mapView,
SLOT(setPOIOverlap(bool))); SLOT(showOverlappedPOIs(bool)));
_showPOILabelsAction = new QAction(tr("Show POI labels"), this); _showPOILabelsAction = new QAction(tr("Show POI labels"), this);
_showPOILabelsAction->setMenuRole(QAction::NoRole); _showPOILabelsAction->setMenuRole(QAction::NoRole);
_showPOILabelsAction->setCheckable(true); _showPOILabelsAction->setCheckable(true);
@ -375,6 +374,11 @@ void GUI::createActions()
_showTicksAction->setCheckable(true); _showTicksAction->setCheckable(true);
connect(_showTicksAction, SIGNAL(triggered(bool)), _mapView, connect(_showTicksAction, SIGNAL(triggered(bool)), _mapView,
SLOT(showTicks(bool))); SLOT(showTicks(bool)));
_showMarkersAction = new QAction(tr("Position markers"), this);
_showMarkersAction->setMenuRole(QAction::NoRole);
_showMarkersAction->setCheckable(true);
connect(_showMarkersAction, SIGNAL(triggered(bool)), _mapView,
SLOT(showMarkers(bool)));
// Graph actions // Graph actions
_showGraphsAction = new QAction(QIcon(SHOW_GRAPHS_ICON), tr("Show graphs"), _showGraphsAction = new QAction(QIcon(SHOW_GRAPHS_ICON), tr("Show graphs"),
@ -411,11 +415,6 @@ void GUI::createActions()
_showGraphSliderInfoAction->setCheckable(true); _showGraphSliderInfoAction->setCheckable(true);
connect(_showGraphSliderInfoAction, SIGNAL(triggered(bool)), this, connect(_showGraphSliderInfoAction, SIGNAL(triggered(bool)), this,
SLOT(showGraphSliderInfo(bool))); SLOT(showGraphSliderInfo(bool)));
_showMarkersAction = new QAction(tr("Show path markers"), this);
_showMarkersAction->setMenuRole(QAction::NoRole);
_showMarkersAction->setCheckable(true);
connect(_showMarkersAction, SIGNAL(triggered(bool)), _mapView,
SLOT(showMarkers(bool)));
// Settings actions // Settings actions
_showToolbarsAction = new QAction(tr("Show toolbars"), this); _showToolbarsAction = new QAction(tr("Show toolbars"), this);
@ -544,7 +543,6 @@ void GUI::createMenus()
graphMenu->addSeparator(); graphMenu->addSeparator();
graphMenu->addAction(_showGraphGridAction); graphMenu->addAction(_showGraphGridAction);
graphMenu->addAction(_showGraphSliderInfoAction); graphMenu->addAction(_showGraphSliderInfoAction);
graphMenu->addAction(_showMarkersAction);
graphMenu->addSeparator(); graphMenu->addSeparator();
graphMenu->addAction(_showGraphsAction); graphMenu->addAction(_showGraphsAction);
@ -565,6 +563,7 @@ void GUI::createMenus()
displayMenu->addAction(_showWaypointLabelsAction); displayMenu->addAction(_showWaypointLabelsAction);
displayMenu->addAction(_showRouteWaypointsAction); displayMenu->addAction(_showRouteWaypointsAction);
displayMenu->addAction(_showTicksAction); displayMenu->addAction(_showTicksAction);
displayMenu->addAction(_showMarkersAction);
dataMenu->addSeparator(); dataMenu->addSeparator();
dataMenu->addAction(_showTracksAction); dataMenu->addAction(_showTracksAction);
dataMenu->addAction(_showRoutesAction); dataMenu->addAction(_showRoutesAction);
@ -662,13 +661,8 @@ void GUI::createGraphTabs()
_tabs.append(new TemperatureGraph(_graphTabWidget)); _tabs.append(new TemperatureGraph(_graphTabWidget));
_tabs.append(new GearRatioGraph(_graphTabWidget)); _tabs.append(new GearRatioGraph(_graphTabWidget));
for (int i = 0; i < _tabs.count(); i++) { connect(_tabs.first(), SIGNAL(sliderPositionChanged(qreal)), _mapView,
#if defined(Q_OS_WIN32) || defined(Q_OS_MAC) SLOT(setMarkerPosition(qreal)));
_tabs.at(i)->setFrameShape(QFrame::NoFrame);
#endif // Q_OS_WIN32 || Q_OS_MAC
connect(_tabs.at(i), SIGNAL(sliderPositionChanged(qreal)), this,
SLOT(sliderPositionChanged(qreal)));
}
} }
void GUI::createStatusBar() void GUI::createStatusBar()
@ -866,16 +860,9 @@ void GUI::loadData(const Data &data)
paths = _mapView->loadData(data); paths = _mapView->loadData(data);
for (int i = 0; i < paths.count(); i++) { for (int i = 0; i < paths.count(); i++) {
const PathItem *pi = paths.at(i); for (int j = 0; j < graphs.count(); j++)
for (int j = 0; j < graphs.count(); j++) { paths.at(i)->addGraph(graphs.at(j).at(i));
const GraphItem *gi = graphs.at(j).at(i); paths.at(i)->setGraph(_graphTabWidget->currentIndex());
if (!gi)
continue;
connect(gi, SIGNAL(sliderPositionChanged(qreal)), pi,
SLOT(moveMarker(qreal)));
connect(pi, SIGNAL(selected(bool)), gi, SLOT(hover(bool)));
connect(gi, SIGNAL(selected(bool)), pi, SLOT(hover(bool)));
}
} }
} }
@ -1308,8 +1295,6 @@ void GUI::reloadFiles()
_tabs.at(i)->clear(); _tabs.at(i)->clear();
_mapView->clear(); _mapView->clear();
_sliderPos = 0;
for (int i = 0; i < _files.size(); i++) { for (int i = 0; i < _files.size(); i++) {
if (!loadFile(_files.at(i))) { if (!loadFile(_files.at(i))) {
_files.removeAt(i); _files.removeAt(i);
@ -1338,8 +1323,6 @@ void GUI::closeFiles()
_dateRange = DateTimeRange(QDateTime(), QDateTime()); _dateRange = DateTimeRange(QDateTime(), QDateTime());
_pathName = QString(); _pathName = QString();
_sliderPos = 0;
for (int i = 0; i < _tabs.count(); i++) for (int i = 0; i < _tabs.count(); i++)
_tabs.at(i)->clear(); _tabs.at(i)->clear();
_mapView->clear(); _mapView->clear();
@ -1679,18 +1662,25 @@ void GUI::poiFileChecked(int index)
_poiFilesActions.at(index)->isChecked()); _poiFilesActions.at(index)->isChecked());
} }
void GUI::sliderPositionChanged(qreal pos)
{
_sliderPos = pos;
}
void GUI::graphChanged(int index) void GUI::graphChanged(int index)
{ {
if (index < 0) if (index < 0)
return; return;
_mapView->setGraph(index);
GraphTab *gt = static_cast<GraphTab*>(_graphTabWidget->widget(index)); GraphTab *gt = static_cast<GraphTab*>(_graphTabWidget->widget(index));
gt->setSliderPosition(_sliderPos); if (_lastGraphTab)
disconnect(_lastGraphTab, SIGNAL(sliderPositionChanged(qreal)),
_mapView, SLOT(setMarkerPosition(qreal)));
connect(gt, SIGNAL(sliderPositionChanged(qreal)), _mapView,
SLOT(setMarkerPosition(qreal)));
if (_lastGraphTab)
gt->setSliderPosition(_lastGraphTab->sliderPosition());
_lastGraphTab = gt;
} }
void GUI::updateNavigationActions() void GUI::updateNavigationActions()
@ -1769,12 +1759,8 @@ void GUI::setCoordinatesFormat(CoordinatesFormat format)
void GUI::setGraphType(GraphType type) void GUI::setGraphType(GraphType type)
{ {
_sliderPos = 0; for (int i = 0; i <_tabs.count(); i++)
for (int i = 0; i <_tabs.count(); i++) {
_tabs.at(i)->setGraphType(type); _tabs.at(i)->setGraphType(type);
_tabs.at(i)->setSliderPosition(0);
}
} }
void GUI::next() void GUI::next()
@ -1968,9 +1954,6 @@ void GUI::writeSettings()
!= SHOW_GRAPH_SLIDER_INFO_DEFAULT) != SHOW_GRAPH_SLIDER_INFO_DEFAULT)
settings.setValue(SHOW_GRAPH_SLIDER_INFO_SETTING, settings.setValue(SHOW_GRAPH_SLIDER_INFO_SETTING,
_showGraphSliderInfoAction->isChecked()); _showGraphSliderInfoAction->isChecked());
if (_showMarkersAction->isChecked() != SHOW_MARKERS_DEFAULT)
settings.setValue(SHOW_MARKERS_SETTING,
_showMarkersAction->isChecked());
settings.endGroup(); settings.endGroup();
settings.beginGroup(POI_SETTINGS_GROUP); settings.beginGroup(POI_SETTINGS_GROUP);
@ -2011,6 +1994,9 @@ void GUI::writeSettings()
if (_showTicksAction->isChecked() != SHOW_TICKS_DEFAULT) if (_showTicksAction->isChecked() != SHOW_TICKS_DEFAULT)
settings.setValue(SHOW_TICKS_SETTING, settings.setValue(SHOW_TICKS_SETTING,
_showTicksAction->isChecked()); _showTicksAction->isChecked());
if (_showMarkersAction->isChecked() != SHOW_MARKERS_DEFAULT)
settings.setValue(SHOW_MARKERS_SETTING,
_showMarkersAction->isChecked());
settings.endGroup(); settings.endGroup();
settings.beginGroup(PDF_EXPORT_SETTINGS_GROUP); settings.beginGroup(PDF_EXPORT_SETTINGS_GROUP);
@ -2238,15 +2224,11 @@ void GUI::readSettings()
showGraphSliderInfo(false); showGraphSliderInfo(false);
else else
_showGraphSliderInfoAction->setChecked(true); _showGraphSliderInfoAction->setChecked(true);
if (!settings.value(SHOW_MARKERS_SETTING, SHOW_MARKERS_DEFAULT).toBool())
_mapView->showMarkers(false);
else
_showMarkersAction->setChecked(true);
settings.endGroup(); settings.endGroup();
settings.beginGroup(POI_SETTINGS_GROUP); settings.beginGroup(POI_SETTINGS_GROUP);
if (!settings.value(OVERLAP_POI_SETTING, OVERLAP_POI_DEFAULT).toBool()) if (!settings.value(OVERLAP_POI_SETTING, OVERLAP_POI_DEFAULT).toBool())
_mapView->setPOIOverlap(false); _mapView->showOverlappedPOIs(false);
else else
_overlapPOIAction->setChecked(true); _overlapPOIAction->setChecked(true);
if (!settings.value(LABELS_POI_SETTING, LABELS_POI_DEFAULT).toBool()) if (!settings.value(LABELS_POI_SETTING, LABELS_POI_DEFAULT).toBool())
@ -2308,6 +2290,10 @@ void GUI::readSettings()
_mapView->showTicks(true); _mapView->showTicks(true);
_showTicksAction->setChecked(true); _showTicksAction->setChecked(true);
} }
if (!settings.value(SHOW_MARKERS_SETTING, SHOW_MARKERS_DEFAULT).toBool())
_mapView->showMarkers(false);
else
_showMarkersAction->setChecked(true);
settings.endGroup(); settings.endGroup();
settings.beginGroup(PDF_EXPORT_SETTINGS_GROUP); settings.beginGroup(PDF_EXPORT_SETTINGS_GROUP);

View File

@ -91,7 +91,6 @@ private slots:
void setDegreesMinutes() {setCoordinatesFormat(DegreesMinutes);} void setDegreesMinutes() {setCoordinatesFormat(DegreesMinutes);}
void setDMS() {setCoordinatesFormat(DMS);} void setDMS() {setCoordinatesFormat(DMS);}
void sliderPositionChanged(qreal pos);
void screenChanged(QScreen *screen); void screenChanged(QScreen *screen);
void logicalDotsPerInchChanged(qreal dpi); void logicalDotsPerInchChanged(qreal dpi);
@ -236,7 +235,7 @@ private:
DateTimeRange _dateRange; DateTimeRange _dateRange;
QString _pathName; QString _pathName;
qreal _sliderPos; GraphTab *_lastGraphTab;
QList<QByteArray> _windowStates; QList<QByteArray> _windowStates;
int _frameStyle; int _frameStyle;

View File

@ -412,6 +412,14 @@ void MapView::setPOI(POI *poi)
updatePOI(); updatePOI();
} }
void MapView::setGraph(int index)
{
for (int i = 0; i < _tracks.size(); i++)
_tracks.at(i)->setGraph(index);
for (int i = 0; i < _routes.size(); i++)
_routes.at(i)->setGraph(index);
}
void MapView::updatePOI() void MapView::updatePOI()
{ {
for (POIHash::const_iterator it = _pois.constBegin(); for (POIHash::const_iterator it = _pois.constBegin();
@ -840,9 +848,9 @@ void MapView::showCoordinates(bool show)
setMouseTracking(show); setMouseTracking(show);
} }
void MapView::setPOIOverlap(bool overlap) void MapView::showOverlappedPOIs(bool show)
{ {
_overlapPOIs = overlap; _overlapPOIs = show;
updatePOIVisibility(); updatePOIVisibility();
} }
@ -1039,6 +1047,14 @@ void MapView::setMarkerColor(const QColor &color)
_routes.at(i)->setMarkerColor(color); _routes.at(i)->setMarkerColor(color);
} }
void MapView::setMarkerPosition(qreal pos)
{
for (int i = 0; i < _tracks.size(); i++)
_tracks.at(i)->setMarkerPosition(pos);
for (int i = 0; i < _routes.size(); i++)
_routes.at(i)->setMarkerPosition(pos);
}
void MapView::reloadMap() void MapView::reloadMap()
{ {
_scene->invalidate(); _scene->invalidate();

View File

@ -56,6 +56,7 @@ public:
void setPalette(const Palette &palette); void setPalette(const Palette &palette);
void setPOI(POI *poi); void setPOI(POI *poi);
void setMap(Map *map); void setMap(Map *map);
void setGraph(int index);
void plot(QPainter *painter, const QRectF &target, qreal scale, void plot(QPainter *painter, const QRectF &target, qreal scale,
PlotFlags flags); PlotFlags flags);
@ -79,30 +80,30 @@ public:
void setBackgroundColor(const QColor &color); void setBackgroundColor(const QColor &color);
void useOpenGL(bool use); void useOpenGL(bool use);
void useAntiAliasing(bool use); void useAntiAliasing(bool use);
public slots:
void showMap(bool show);
void showPOI(bool show);
void setPOIOverlap(bool overlap);
void showWaypointLabels(bool show);
void showPOILabels(bool show);
void showTracks(bool show);
void showRoutes(bool show);
void showAreas(bool show);
void showWaypoints(bool show);
void showRouteWaypoints(bool show);
void showMarkers(bool show);
void showCoordinates(bool show);
void showTicks(bool show);
void clearMapCache();
void setCoordinatesFormat(CoordinatesFormat format); void setCoordinatesFormat(CoordinatesFormat format);
void setTimeZone(const QTimeZone &zone); void setTimeZone(const QTimeZone &zone);
void setDevicePixelRatio(qreal deviceRatio, qreal mapRatio); void setDevicePixelRatio(qreal deviceRatio, qreal mapRatio);
void setOutputProjection(int id); void setOutputProjection(int id);
void setInputProjection(int id); void setInputProjection(int id);
void clearMapCache();
void fitContentToSize(); void fitContentToSize();
public slots:
void showMap(bool show);
void showPOI(bool show);
void showPOILabels(bool show);
void showCoordinates(bool show);
void showTicks(bool show);
void showMarkers(bool show);
void showOverlappedPOIs(bool show);
void showWaypointLabels(bool show);
void showTracks(bool show);
void showRoutes(bool show);
void showAreas(bool show);
void showWaypoints(bool show);
void showRouteWaypoints(bool show);
void setMarkerPosition(qreal pos);
private slots: private slots:
void updatePOI(); void updatePOI();
void reloadMap(); void reloadMap();

View File

@ -6,9 +6,16 @@
#include "map/map.h" #include "map/map.h"
#include "pathtickitem.h" #include "pathtickitem.h"
#include "popup.h" #include "popup.h"
#include "graphitem.h"
#include "pathitem.h" #include "pathitem.h"
#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
#define INTERSECTS intersect
#else // QT 5.15
#define INTERSECTS intersects
#endif // QT 5.15
#define GEOGRAPHICAL_MILE 1855.3248 #define GEOGRAPHICAL_MILE 1855.3248
static inline bool isValid(const QPointF &p) static inline bool isValid(const QPointF &p)
@ -25,7 +32,7 @@ Units PathItem::_units = Metric;
QTimeZone PathItem::_timeZone = QTimeZone::utc(); QTimeZone PathItem::_timeZone = QTimeZone::utc();
PathItem::PathItem(const Path &path, Map *map, QGraphicsItem *parent) PathItem::PathItem(const Path &path, Map *map, QGraphicsItem *parent)
: GraphicsItem(parent), _path(path), _map(map) : GraphicsItem(parent), _path(path), _map(map), _graph(0)
{ {
Q_ASSERT(_path.isValid()); Q_ASSERT(_path.isValid());
@ -66,22 +73,14 @@ void PathItem::addSegment(const Coordinates &c1, const Coordinates &c2)
QLineF l(QPointF(c1.lon(), c1.lat()), QPointF(c2.lon() + 360, QLineF l(QPointF(c1.lon(), c1.lat()), QPointF(c2.lon() + 360,
c2.lat())); c2.lat()));
QLineF dl(QPointF(180, -90), QPointF(180, 90)); QLineF dl(QPointF(180, -90), QPointF(180, 90));
#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) l.INTERSECTS(dl, &p);
l.intersect(dl, &p);
#else // QT 5.15
l.intersects(dl, &p);
#endif // QT 5.15
_painterPath.lineTo(_map->ll2xy(Coordinates(180, p.y()))); _painterPath.lineTo(_map->ll2xy(Coordinates(180, p.y())));
_painterPath.moveTo(_map->ll2xy(Coordinates(-180, p.y()))); _painterPath.moveTo(_map->ll2xy(Coordinates(-180, p.y())));
} else { } else {
QLineF l(QPointF(c1.lon(), c1.lat()), QPointF(c2.lon() - 360, QLineF l(QPointF(c1.lon(), c1.lat()), QPointF(c2.lon() - 360,
c2.lat())); c2.lat()));
QLineF dl(QPointF(-180, -90), QPointF(-180, 90)); QLineF dl(QPointF(-180, -90), QPointF(-180, 90));
#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) l.INTERSECTS(dl, &p);
l.intersect(dl, &p);
#else // QT 5.15
l.intersects(dl, &p);
#endif // QT 5.15
_painterPath.lineTo(_map->ll2xy(Coordinates(-180, p.y()))); _painterPath.lineTo(_map->ll2xy(Coordinates(-180, p.y())));
_painterPath.moveTo(_map->ll2xy(Coordinates(180, p.y()))); _painterPath.moveTo(_map->ll2xy(Coordinates(180, p.y())));
} }
@ -266,14 +265,18 @@ QPointF PathItem::position(qreal x) const
} }
} }
void PathItem::moveMarker(qreal distance) void PathItem::setMarkerPosition(qreal pos)
{ {
_markerDistance = distance; qreal distance = _graph
QPointF pos(position(distance)); ? (_graph->graphType() == Time) ? _graph->distanceAtTime(pos) : pos
: NAN;
if (isValid(pos)) { _markerDistance = distance;
QPointF pp(position(distance));
if (isValid(pp)) {
_marker->setVisible(_showMarker); _marker->setVisible(_showMarker);
_marker->setPos(pos); _marker->setPos(pp);
} else } else
_marker->setVisible(false); _marker->setVisible(false);
} }
@ -362,6 +365,24 @@ void PathItem::showTicks(bool show)
updateTicks(); updateTicks();
} }
void PathItem::addGraph(GraphItem *graph)
{
_graphs.append(graph);
if (graph) {
connect(this, SIGNAL(selected(bool)), graph, SLOT(hover(bool)));
connect(graph, SIGNAL(selected(bool)), this, SLOT(hover(bool)));
if (graph->secondaryGraph())
connect(graph->secondaryGraph(), SIGNAL(selected(bool)), this,
SLOT(hover(bool)));
}
}
void PathItem::setGraph(int index)
{
_graph = _graphs.at(index);
}
void PathItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event) void PathItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
{ {
Q_UNUSED(event); Q_UNUSED(event);

View File

@ -11,6 +11,7 @@
class Map; class Map;
class PathTickItem; class PathTickItem;
class GraphItem;
class PathItem : public QObject, public GraphicsItem class PathItem : public QObject, public GraphicsItem
{ {
@ -27,7 +28,10 @@ public:
const Path &path() const {return _path;} const Path &path() const {return _path;}
void addGraph(GraphItem *graph);
void setMap(Map *map); void setMap(Map *map);
void setGraph(int index);
void setColor(const QColor &color); void setColor(const QColor &color);
void setWidth(qreal width); void setWidth(qreal width);
@ -37,13 +41,14 @@ public:
void showMarker(bool show); void showMarker(bool show);
void showTicks(bool show); void showTicks(bool show);
void setMarkerPosition(qreal pos);
void updateTicks(); void updateTicks();
static void setUnits(Units units) {_units = units;} static void setUnits(Units units) {_units = units;}
static void setTimeZone(const QTimeZone &zone) {_timeZone = zone;} static void setTimeZone(const QTimeZone &zone) {_timeZone = zone;}
public slots: public slots:
void moveMarker(qreal distance);
void hover(bool hover); void hover(bool hover);
signals: signals:
@ -69,6 +74,8 @@ private:
Path _path; Path _path;
Map *_map; Map *_map;
QList<GraphItem *> _graphs;
GraphItem *_graph;
qreal _markerDistance; qreal _markerDistance;
int _digitalZoom; int _digitalZoom;

View File

@ -30,8 +30,6 @@
#define SHOW_GRAPH_GRIDS_DEFAULT true #define SHOW_GRAPH_GRIDS_DEFAULT true
#define SHOW_GRAPH_SLIDER_INFO_SETTING "sliderInfo" #define SHOW_GRAPH_SLIDER_INFO_SETTING "sliderInfo"
#define SHOW_GRAPH_SLIDER_INFO_DEFAULT true #define SHOW_GRAPH_SLIDER_INFO_DEFAULT true
#define SHOW_MARKERS_SETTING "pathMarkers"
#define SHOW_MARKERS_DEFAULT true
#define SHOW_TICKS_SETTING "pathTicks" #define SHOW_TICKS_SETTING "pathTicks"
#define SHOW_TICKS_DEFAULT false #define SHOW_TICKS_DEFAULT false
@ -65,6 +63,8 @@
#define SHOW_ROUTE_WAYPOINTS_DEFAULT true #define SHOW_ROUTE_WAYPOINTS_DEFAULT true
#define SHOW_WAYPOINT_LABELS_SETTING "waypointLabels" #define SHOW_WAYPOINT_LABELS_SETTING "waypointLabels"
#define SHOW_WAYPOINT_LABELS_DEFAULT true #define SHOW_WAYPOINT_LABELS_DEFAULT true
#define SHOW_MARKERS_SETTING "positionMarkers"
#define SHOW_MARKERS_DEFAULT true
#define PDF_EXPORT_SETTINGS_GROUP "Export" #define PDF_EXPORT_SETTINGS_GROUP "Export"
#define PAPER_ORIENTATION_SETTING "orientation" #define PAPER_ORIENTATION_SETTING "orientation"