The CartesianAxis used a simple method to put things on screen which is wrong for almost any case besides the 'current value here' since we store things in milimeters on the axis, we need to convert those to meters before showing on the profile. Signed-off-by: Tomaz Canabrava <tcanabrava@kde.org> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
186 lines
4.7 KiB
C++
186 lines
4.7 KiB
C++
#include "divecartesianaxis.h"
|
|
#include "divelineitem.h"
|
|
#include "divetextitem.h"
|
|
#include "helpers.h"
|
|
|
|
#include <QPen>
|
|
#include <QGraphicsScene>
|
|
#include <QDebug>
|
|
#include <QPropertyAnimation>
|
|
#include <QGraphicsView>
|
|
#include <QStyleOption>
|
|
|
|
void DiveCartesianAxis::setMaximum(double maximum)
|
|
{
|
|
max = maximum;
|
|
}
|
|
|
|
void DiveCartesianAxis::setMinimum(double minimum)
|
|
{
|
|
min = minimum;
|
|
}
|
|
|
|
void DiveCartesianAxis::setTextColor(const QColor& color)
|
|
{
|
|
textColor = color;
|
|
}
|
|
|
|
DiveCartesianAxis::DiveCartesianAxis() : orientation(Qt::Horizontal)
|
|
{
|
|
}
|
|
|
|
DiveCartesianAxis::~DiveCartesianAxis()
|
|
{
|
|
|
|
}
|
|
|
|
void DiveCartesianAxis::setOrientation(Qt::Orientation o)
|
|
{
|
|
orientation = o;
|
|
// position the elements on the screen.
|
|
setMinimum(minimum());
|
|
setMaximum(maximum());
|
|
}
|
|
|
|
void DiveCartesianAxis::updateTicks()
|
|
{
|
|
QLineF m = line();
|
|
QGraphicsView *view = scene()->views().first();
|
|
double steps = (max - min) / interval;
|
|
double currValue = min;
|
|
|
|
// Remove the uneeded Ticks / Texts.
|
|
if (ticks.size() > steps){
|
|
while (ticks.size() > steps){
|
|
DiveLineItem *removedLine = ticks.takeLast();
|
|
removedLine->animatedHide();
|
|
DiveTextItem *removedText = labels.takeLast();
|
|
removedText->animatedHide();
|
|
}
|
|
}
|
|
|
|
// Move the remaining Ticks / Text to it's corerct position
|
|
// Regartind the possibly new values for the Axis
|
|
qreal begin = orientation == Qt::Horizontal ? m.x1() : m.y1();
|
|
qreal end = orientation == Qt::Horizontal ? m.x2() : m.y2();
|
|
double stepSize = orientation == Qt::Horizontal ? (m.x2() - m.x1()) : (m.y2() - m.y1());
|
|
stepSize = stepSize / steps;
|
|
for(int i = 0, count = ticks.size(); i < count; i++, currValue += interval){
|
|
qreal childPos = begin + i * stepSize;
|
|
labels[i]->setText(textForValue(currValue));
|
|
if ( orientation == Qt::Horizontal ){
|
|
ticks[i]->animateMoveTo(childPos, m.y1() + tickSize);
|
|
labels[i]->animateMoveTo(childPos, m.y1() + tickSize);
|
|
}
|
|
else{
|
|
ticks[i]->animateMoveTo(m.x1() - tickSize, childPos);
|
|
labels[i]->animateMoveTo(m.x1() - tickSize, childPos);
|
|
}
|
|
}
|
|
|
|
// Add's the rest of the needed Ticks / Text.
|
|
for(int i = ticks.size(); i < steps; i++, currValue += interval){
|
|
qreal childPos = begin + i * stepSize;
|
|
DiveLineItem *item = new DiveLineItem(this);
|
|
item->setPen(pen());
|
|
ticks.push_back(item);
|
|
|
|
DiveTextItem *label = new DiveTextItem(this);
|
|
label->setText(textForValue(currValue));
|
|
label->setBrush(QBrush(textColor));
|
|
|
|
labels.push_back(label);
|
|
if(orientation == Qt::Horizontal){
|
|
item->setLine(0, 0, 0, tickSize);
|
|
item->setPos(scene()->sceneRect().width() + 10, m.y1() + tickSize); // position it outside of the scene
|
|
item->animateMoveTo(childPos, m.y1() + tickSize); // anim it to scene.
|
|
label->setAlignment(Qt::AlignBottom | Qt::AlignHCenter);
|
|
label->setPos(scene()->sceneRect().width() + 10, m.y1() + tickSize); // position it outside of the scene);
|
|
label->animateMoveTo(childPos, m.y1() + tickSize);
|
|
}
|
|
else{
|
|
item->setLine(0, 0, tickSize, 0);
|
|
item->setPos(m.x1() - tickSize, scene()->sceneRect().height() + 10);
|
|
item->animateMoveTo(m.x1() - tickSize, childPos);
|
|
label->setAlignment(Qt::AlignVCenter| Qt::AlignRight);
|
|
label->setPos(m.x1() - tickSize, scene()->sceneRect().height() + 10);
|
|
label->animateMoveTo(m.x1() - tickSize, childPos);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
QString DiveCartesianAxis::textForValue(double value)
|
|
{
|
|
return QString::number(value);
|
|
}
|
|
|
|
void DiveCartesianAxis::setTickSize(qreal size)
|
|
{
|
|
tickSize = size;
|
|
}
|
|
|
|
void DiveCartesianAxis::setTickInterval(double i)
|
|
{
|
|
interval = i;
|
|
}
|
|
|
|
qreal DiveCartesianAxis::valueAt(const QPointF& p)
|
|
{
|
|
QLineF m = line();
|
|
double retValue = orientation == Qt::Horizontal ?
|
|
max * (p.x() - m.x1()) / (m.x2() - m.x1()) :
|
|
max * (p.y() - m.y1()) / (m.y2() - m.y1());
|
|
return retValue;
|
|
}
|
|
|
|
qreal DiveCartesianAxis::posAtValue(qreal value)
|
|
{
|
|
QLineF m = line();
|
|
QPointF p = pos();
|
|
|
|
double size = max - min;
|
|
double percent = value / size;
|
|
double realSize = orientation == Qt::Horizontal ?
|
|
m.x2() - m.x1() :
|
|
m.y2() - m.y1();
|
|
double retValue = realSize * percent;
|
|
retValue = (orientation == Qt::Horizontal) ?
|
|
retValue + m.x1() + p.x():
|
|
retValue + m.y1() + p.y();
|
|
return retValue;
|
|
}
|
|
|
|
qreal DiveCartesianAxis::percentAt(const QPointF& p)
|
|
{
|
|
qreal value = valueAt(p);
|
|
double size = max - min;
|
|
double percent = value / size;
|
|
return percent;
|
|
}
|
|
|
|
double DiveCartesianAxis::maximum() const
|
|
{
|
|
return max;
|
|
}
|
|
|
|
double DiveCartesianAxis::minimum() const
|
|
{
|
|
return min;
|
|
}
|
|
|
|
void DiveCartesianAxis::setColor(const QColor& color)
|
|
{
|
|
QPen defaultPen(color);
|
|
defaultPen.setJoinStyle(Qt::RoundJoin);
|
|
defaultPen.setCapStyle(Qt::RoundCap);
|
|
defaultPen.setWidth(2);
|
|
defaultPen.setCosmetic(true);
|
|
setPen(defaultPen);
|
|
}
|
|
|
|
QString DepthAxis::textForValue(double value)
|
|
{
|
|
return get_depth_string(value, false, false);
|
|
}
|