1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2024-10-06 23:03:22 +02:00
GPXSee/src/axisitem.cpp

198 lines
4.5 KiB
C++
Raw Normal View History

2015-10-05 01:43:48 +02:00
#include <cmath>
#include <QPainter>
2015-10-17 01:33:02 +02:00
#include "config.h"
2016-07-25 19:32:36 +02:00
#include "misc.h"
2015-10-05 01:43:48 +02:00
#include "axisitem.h"
#define TICK 6
#define PADDING 6
#define XTICKS 15
#define YTICKS 10
struct Label {
double min;
double max;
double d;
};
static struct Label label(double min, double max, int ticks)
{
double range;
struct Label l;
range = niceNum(max - min, 0);
l.d = niceNum(range / ticks, 1);
l.min = ceil(min / l.d) * l.d;
l.max = floor(max / l.d) * l.d;
return l;
}
2015-10-17 01:33:02 +02:00
AxisItem::AxisItem(Type type, QGraphicsItem *parent) : QGraphicsItem(parent)
2015-10-05 01:43:48 +02:00
{
_type = type;
_size = 0;
2016-09-11 17:15:23 +02:00
setCacheMode(QGraphicsItem::DeviceCoordinateCache);
2015-10-05 01:43:48 +02:00
}
2016-03-27 13:23:00 +02:00
void AxisItem::setRange(const RangeF &range)
2015-10-05 01:43:48 +02:00
{
2016-04-01 21:20:23 +02:00
prepareGeometryChange();
2015-10-05 01:43:48 +02:00
_range = range;
updateBoundingRect();
}
void AxisItem::setSize(qreal size)
{
2016-04-01 21:20:23 +02:00
prepareGeometryChange();
2015-10-05 01:43:48 +02:00
_size = size;
updateBoundingRect();
}
void AxisItem::setLabel(const QString& label)
{
2016-04-01 21:20:23 +02:00
prepareGeometryChange();
2015-10-05 01:43:48 +02:00
_label = label;
updateBoundingRect();
}
void AxisItem::updateBoundingRect()
{
QFont font;
font.setPixelSize(FONT_SIZE);
font.setFamily(FONT_FAMILY);
QFontMetrics fm(font);
QRect ss, es, ls;
struct Label l;
2016-03-27 13:23:00 +02:00
l = label(_range.min(), _range.max(), (_type == X) ? XTICKS : YTICKS);
2015-10-05 01:43:48 +02:00
es = fm.tightBoundingRect(QString::number(l.max));
ss = fm.tightBoundingRect(QString::number(l.min));
ls = fm.tightBoundingRect(_label);
if (_type == X) {
_boundingRect = QRectF(-ss.width()/2, -TICK/2,
_size + es.width()/2 + ss.width()/2,
ls.height() + es.height() - fm.descent() + TICK + 2*PADDING);
} else {
2016-03-22 06:48:49 +01:00
int mtw = 0;
QRect ts;
qreal val;
for (int i = 0; i < ((l.max - l.min) / l.d) + 1; i++) {
val = l.min + i * l.d;
QString str = QString::number(val);
ts = fm.tightBoundingRect(str);
mtw = qMax(ts.width(), mtw);
}
_boundingRect = QRectF(-(ls.height() + mtw + 2*PADDING
2015-10-05 01:43:48 +02:00
- fm.descent() + TICK/2), -(_size + es.height()/2
2016-03-23 09:47:02 +01:00
+ fm.descent()), ls.height() -fm.descent() + mtw + 2*PADDING
2015-10-05 01:43:48 +02:00
+ TICK, _size + es.height()/2 + fm.descent() + ss.height()/2);
}
}
void AxisItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QWidget *widget)
{
Q_UNUSED(option);
Q_UNUSED(widget);
QFont font;
font.setPixelSize(FONT_SIZE);
font.setFamily(FONT_FAMILY);
QFontMetrics fm(font);
QRect ts, ls;
struct Label l;
2016-03-27 13:23:00 +02:00
qreal range = _range.size();
2015-10-05 01:43:48 +02:00
qreal val;
2016-01-14 00:37:51 +01:00
painter->setFont(font);
2015-10-05 01:43:48 +02:00
ls = fm.tightBoundingRect(_label);
if (_type == X) {
painter->drawLine(0, 0, _size, 0);
2016-03-27 13:23:00 +02:00
l = label(_range.min(), _range.max(), XTICKS);
2015-10-05 01:43:48 +02:00
for (int i = 0; i < ((l.max - l.min) / l.d) + 1; i++) {
val = l.min + i * l.d;
QString str = QString::number(val);
2016-03-27 13:23:00 +02:00
painter->drawLine((_size/range) * (val - _range.min()), TICK/2,
(_size/range) * (val - _range.min()), -TICK/2);
2015-10-05 01:43:48 +02:00
ts = fm.tightBoundingRect(str);
2016-03-27 13:23:00 +02:00
painter->drawText(((_size/range) * (val - _range.min()))
2015-10-05 01:43:48 +02:00
- (ts.width()/2), ts.height() + TICK/2 + PADDING, str);
}
painter->drawText(_size/2 - ls.width()/2, ls.height() + ts.height()
- 2*fm.descent() + TICK/2 + 2*PADDING, _label);
} else {
painter->drawLine(0, 0, 0, -_size);
2016-03-27 13:23:00 +02:00
l = label(_range.min(), _range.max(), YTICKS);
2016-03-22 06:48:49 +01:00
int mtw = 0;
2015-10-05 01:43:48 +02:00
for (int i = 0; i < ((l.max - l.min) / l.d) + 1; i++) {
val = l.min + i * l.d;
QString str = QString::number(val);
2016-03-27 13:23:00 +02:00
painter->drawLine(TICK/2, -((_size/range) * (val - _range.min())),
-TICK/2, -((_size/range) * (val - _range.min())));
2015-10-05 01:43:48 +02:00
ts = fm.tightBoundingRect(str);
2016-03-22 06:48:49 +01:00
mtw = qMax(ts.width(), mtw);
2015-10-05 01:43:48 +02:00
painter->drawText(-(ts.width() + PADDING + TICK/2), -((_size/range)
2016-03-27 13:23:00 +02:00
* (val - _range.min())) + (ts.height()/2), str);
2015-10-05 01:43:48 +02:00
}
painter->rotate(-90);
2016-03-22 06:48:49 +01:00
painter->drawText(_size/2 - ls.width()/2, -(mtw + 2*PADDING + TICK/2),
_label);
2015-10-05 01:43:48 +02:00
painter->rotate(90);
}
/*
painter->setPen(Qt::red);
painter->drawRect(boundingRect());
*/
}
2016-03-19 17:24:53 +01:00
QSizeF AxisItem::margin() const
2015-10-05 01:43:48 +02:00
{
QFont font;
font.setPixelSize(FONT_SIZE);
QFontMetrics fm(font);
QRect ss, es, ls;
struct Label l;
2016-03-27 13:23:00 +02:00
l = label(_range.min(), _range.max(), (_type == X) ? XTICKS : YTICKS);
2015-10-05 01:43:48 +02:00
es = fm.tightBoundingRect(QString::number(l.max));
ss = fm.tightBoundingRect(QString::number(l.min));
ls = fm.tightBoundingRect(_label);
if (_type == X) {
return QSizeF(es.width()/2,
ls.height() + es.height() - fm.descent() + TICK/2 + 2*PADDING);
} else {
2016-03-22 06:48:49 +01:00
int mtw = 0;
QRect ts;
qreal val;
for (int i = 0; i < ((l.max - l.min) / l.d) + 1; i++) {
val = l.min + i * l.d;
QString str = QString::number(val);
ts = fm.tightBoundingRect(str);
mtw = qMax(ts.width(), mtw);
}
return QSizeF(ls.height() -fm.descent() + mtw + 2*PADDING
2015-10-05 01:43:48 +02:00
+ TICK/2, es.height()/2 + fm.descent());
}
}