mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
profile: replace orientation by inverted flag
There were two somewhat redundant flags for the axes: the position (left, right, bottom) and the orientation (up-down, left-right, etc). Replace the latter by an inverted flag: if true, the axis is up-down or right-left, i.e. the opposite of what one would expect for a normal graph. Set the flag in the constructor and remove the setOrientation() function. Sadly, the code is a bit complex, because screen coordinates are top-to-bottom. Who thought that would be a good idea? Note: this also fixes the placement of the ticks of the time axis. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
parent
3a79f3e78a
commit
2f9c0c04b5
3 changed files with 44 additions and 85 deletions
|
@ -18,15 +18,15 @@ void DiveCartesianAxis::setBounds(double minimum, double maximum)
|
||||||
dataMax = max = maximum;
|
dataMax = max = maximum;
|
||||||
}
|
}
|
||||||
|
|
||||||
DiveCartesianAxis::DiveCartesianAxis(Position position, int integralDigits, int fractionalDigits, color_index_t gridColor,
|
DiveCartesianAxis::DiveCartesianAxis(Position position, bool inverted, int integralDigits, int fractionalDigits, color_index_t gridColor,
|
||||||
QColor textColor, bool textVisible, bool linesVisible,
|
QColor textColor, bool textVisible, bool linesVisible,
|
||||||
double dpr, double labelScale, bool printMode, bool isGrayscale, ProfileScene &scene) :
|
double dpr, double labelScale, bool printMode, bool isGrayscale, ProfileScene &scene) :
|
||||||
printMode(printMode),
|
printMode(printMode),
|
||||||
position(position),
|
position(position),
|
||||||
|
inverted(inverted),
|
||||||
fractionalDigits(fractionalDigits),
|
fractionalDigits(fractionalDigits),
|
||||||
textColor(textColor),
|
textColor(textColor),
|
||||||
scene(scene),
|
scene(scene),
|
||||||
orientation(LeftToRight),
|
|
||||||
min(0),
|
min(0),
|
||||||
max(0),
|
max(0),
|
||||||
textVisibility(textVisible),
|
textVisibility(textVisible),
|
||||||
|
@ -73,12 +73,6 @@ DiveCartesianAxis::~DiveCartesianAxis()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void DiveCartesianAxis::setOrientation(Orientation o)
|
|
||||||
{
|
|
||||||
orientation = o;
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DiveCartesianAxis::setTransform(double a, double b)
|
void DiveCartesianAxis::setTransform(double a, double b)
|
||||||
{
|
{
|
||||||
transform.a = a;
|
transform.a = a;
|
||||||
|
@ -182,23 +176,21 @@ void DiveCartesianAxis::updateTicks(int animSpeed)
|
||||||
if (numTicks == 0)
|
if (numTicks == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
double internalToScreen = size / (max - min);
|
||||||
stepValue = position == Position::Bottom ?
|
stepValue = position == Position::Bottom ?
|
||||||
intervalDisplay / transform.a : // special case for time axis.
|
intervalDisplay / transform.a : // special case for time axis.
|
||||||
numTicks > 1 ? (max - min) / (numTicks - 1) : 0;
|
numTicks > 1 ? (max - min) / (numTicks - 1) : 0;
|
||||||
double stepScreen = stepValue * size / (max - min);
|
double stepScreen = stepValue * internalToScreen;
|
||||||
|
|
||||||
|
// The ticks of the time axis don't necessarily start at the beginning.
|
||||||
|
double offsetScreen = position == Position::Bottom ?
|
||||||
|
(firstValue - min) * internalToScreen : 0.0;
|
||||||
|
|
||||||
// Move the remaining grid lines / labels to their correct positions
|
// Move the remaining grid lines / labels to their correct positions
|
||||||
// regarding the possible new values for the axis
|
// regarding the possible new values for the axis.
|
||||||
double firstPosScreen;
|
double firstPosScreen = position == Position::Bottom ?
|
||||||
if (orientation == TopToBottom) {
|
(inverted ? m.x2() - offsetScreen : m.x1() + offsetScreen) :
|
||||||
firstPosScreen = m.y1();
|
(inverted ? m.y1() + offsetScreen : m.y2() - offsetScreen);
|
||||||
} else if (orientation == BottomToTop) {
|
|
||||||
firstPosScreen = m.y2();
|
|
||||||
} else if (orientation == LeftToRight) {
|
|
||||||
firstPosScreen = m.x1();
|
|
||||||
} else /* if (orientation == RightToLeft) */ {
|
|
||||||
firstPosScreen = m.x2();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (textVisibility)
|
if (textVisibility)
|
||||||
updateLabels(numTicks, firstPosScreen, firstValue, stepScreen, stepValue, animSpeed);
|
updateLabels(numTicks, firstPosScreen, firstValue, stepScreen, stepValue, animSpeed);
|
||||||
|
@ -210,10 +202,9 @@ void DiveCartesianAxis::updateTicks(int animSpeed)
|
||||||
void DiveCartesianAxis::updateLabels(int numTicks, double firstPosScreen, double firstValue, double stepScreen, double stepValue, int animSpeed)
|
void DiveCartesianAxis::updateLabels(int numTicks, double firstPosScreen, double firstValue, double stepScreen, double stepValue, int animSpeed)
|
||||||
{
|
{
|
||||||
for (int i = 0, count = labels.size(); i < count; i++, firstValue += stepValue) {
|
for (int i = 0, count = labels.size(); i < count; i++, firstValue += stepValue) {
|
||||||
double childPos = (orientation == TopToBottom || orientation == LeftToRight) ?
|
double childPos = ((position == Position::Bottom) != inverted) ?
|
||||||
firstPosScreen + i * stepScreen :
|
firstPosScreen + i * stepScreen :
|
||||||
firstPosScreen - i * stepScreen;
|
firstPosScreen - i * stepScreen;
|
||||||
|
|
||||||
labels[i]->set(textForValue(firstValue), textColor);
|
labels[i]->set(textForValue(firstValue), textColor);
|
||||||
switch (position) {
|
switch (position) {
|
||||||
default:
|
default:
|
||||||
|
@ -231,12 +222,9 @@ void DiveCartesianAxis::updateLabels(int numTicks, double firstPosScreen, double
|
||||||
|
|
||||||
// Add the rest of the needed labels.
|
// Add the rest of the needed labels.
|
||||||
for (int i = labels.size(); i < numTicks; i++, firstValue += stepValue) {
|
for (int i = labels.size(); i < numTicks; i++, firstValue += stepValue) {
|
||||||
double childPos;
|
double childPos = ((position == Position::Bottom) != inverted) ?
|
||||||
if (orientation == TopToBottom || orientation == LeftToRight) {
|
firstPosScreen + i * stepScreen :
|
||||||
childPos = firstPosScreen + i * stepScreen;
|
firstPosScreen - i * stepScreen;
|
||||||
} else {
|
|
||||||
childPos = firstPosScreen - i * stepScreen;
|
|
||||||
}
|
|
||||||
int alignFlags = position == Position::Bottom ? Qt::AlignTop | Qt::AlignHCenter :
|
int alignFlags = position == Position::Bottom ? Qt::AlignTop | Qt::AlignHCenter :
|
||||||
position == Position::Left ? Qt::AlignVCenter | Qt::AlignLeft:
|
position == Position::Left ? Qt::AlignVCenter | Qt::AlignLeft:
|
||||||
Qt::AlignVCenter | Qt::AlignRight;
|
Qt::AlignVCenter | Qt::AlignRight;
|
||||||
|
@ -265,9 +253,9 @@ void DiveCartesianAxis::updateLabels(int numTicks, double firstPosScreen, double
|
||||||
void DiveCartesianAxis::updateLines(int numTicks, double firstPosScreen, double stepScreen, int animSpeed)
|
void DiveCartesianAxis::updateLines(int numTicks, double firstPosScreen, double stepScreen, int animSpeed)
|
||||||
{
|
{
|
||||||
for (int i = 0, count = lines.size(); i < count; i++) {
|
for (int i = 0, count = lines.size(); i < count; i++) {
|
||||||
double childPos = (orientation == TopToBottom || orientation == LeftToRight) ?
|
double childPos = ((position == Position::Bottom) != inverted) ?
|
||||||
firstPosScreen + i * stepScreen :
|
firstPosScreen + i * stepScreen :
|
||||||
firstPosScreen - i * stepScreen;
|
firstPosScreen - i * stepScreen;
|
||||||
|
|
||||||
if (position == Position::Bottom) {
|
if (position == Position::Bottom) {
|
||||||
// Fix size in case the scene changed
|
// Fix size in case the scene changed
|
||||||
|
@ -284,12 +272,9 @@ void DiveCartesianAxis::updateLines(int numTicks, double firstPosScreen, double
|
||||||
|
|
||||||
// Add the rest of the needed grid lines.
|
// Add the rest of the needed grid lines.
|
||||||
for (int i = lines.size(); i < numTicks; i++) {
|
for (int i = lines.size(); i < numTicks; i++) {
|
||||||
double childPos;
|
double childPos = ((position == Position::Bottom) != inverted) ?
|
||||||
if (orientation == TopToBottom || orientation == LeftToRight) {
|
firstPosScreen + i * stepScreen :
|
||||||
childPos = firstPosScreen + i * stepScreen;
|
firstPosScreen - i * stepScreen;
|
||||||
} else {
|
|
||||||
childPos = firstPosScreen - i * stepScreen;
|
|
||||||
}
|
|
||||||
DiveLineItem *line = new DiveLineItem(this);
|
DiveLineItem *line = new DiveLineItem(this);
|
||||||
line->setPen(gridPen);
|
line->setPen(gridPen);
|
||||||
line->setZValue(0);
|
line->setZValue(0);
|
||||||
|
@ -349,18 +334,16 @@ QString DiveCartesianAxis::textForValue(double value) const
|
||||||
|
|
||||||
qreal DiveCartesianAxis::valueAt(const QPointF &p) const
|
qreal DiveCartesianAxis::valueAt(const QPointF &p) const
|
||||||
{
|
{
|
||||||
double fraction;
|
|
||||||
QLineF m = line();
|
QLineF m = line();
|
||||||
QPointF relativePosition = p;
|
QPointF relativePosition = p;
|
||||||
relativePosition -= pos(); // normalize p based on the axis' offset on screen
|
relativePosition -= pos(); // normalize p based on the axis' offset on screen
|
||||||
|
|
||||||
if (orientation == LeftToRight || orientation == RightToLeft)
|
double fraction = position == Position::Bottom ?
|
||||||
fraction = (relativePosition.x() - m.x1()) / (m.x2() - m.x1());
|
(relativePosition.x() - m.x1()) / (m.x2() - m.x1()) :
|
||||||
else
|
(relativePosition.y() - m.y1()) / (m.y2() - m.y1());
|
||||||
fraction = (relativePosition.y() - m.y1()) / (m.y2() - m.y1());
|
|
||||||
|
|
||||||
if (orientation == RightToLeft || orientation == BottomToTop)
|
if ((position == Position::Bottom) == inverted)
|
||||||
fraction = 1 - fraction;
|
fraction = 1.0 - fraction;
|
||||||
return fraction * (max - min) + min;
|
return fraction * (max - min) + min;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -375,20 +358,18 @@ qreal DiveCartesianAxis::posAtValue(qreal value) const
|
||||||
double percent = IS_FP_SAME(min, max) ? 0.0 : (value - min) / size;
|
double percent = IS_FP_SAME(min, max) ? 0.0 : (value - min) / size;
|
||||||
|
|
||||||
|
|
||||||
double realSize = orientation == LeftToRight || orientation == RightToLeft ?
|
double realSize = position == Position::Bottom ?
|
||||||
m.x2() - m.x1() :
|
m.x2() - m.x1() :
|
||||||
m.y2() - m.y1();
|
m.y2() - m.y1();
|
||||||
|
|
||||||
// Inverted axis, just invert the percentage.
|
// Inverted axis, just invert the percentage.
|
||||||
if (orientation == RightToLeft || orientation == BottomToTop)
|
if ((position == Position::Bottom) == inverted)
|
||||||
percent = 1 - percent;
|
percent = 1.0 - percent;
|
||||||
|
|
||||||
double retValue = realSize * percent;
|
double retValue = realSize * percent;
|
||||||
double adjusted =
|
double adjusted = position == Position::Bottom ?
|
||||||
orientation == LeftToRight ? retValue + m.x1() + p.x() :
|
retValue + m.x1() + p.x() :
|
||||||
orientation == RightToLeft ? retValue + m.x1() + p.x() :
|
retValue + m.y1() + p.y();
|
||||||
orientation == TopToBottom ? retValue + m.y1() + p.y() :
|
|
||||||
/* entation == BottomToTop */ retValue + m.y1() + p.y();
|
|
||||||
return adjusted;
|
return adjusted;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,23 +23,16 @@ class DiveCartesianAxis : public QObject, public QGraphicsLineItem {
|
||||||
private:
|
private:
|
||||||
bool printMode;
|
bool printMode;
|
||||||
public:
|
public:
|
||||||
enum Orientation {
|
|
||||||
TopToBottom,
|
|
||||||
BottomToTop,
|
|
||||||
LeftToRight,
|
|
||||||
RightToLeft
|
|
||||||
};
|
|
||||||
enum class Position {
|
enum class Position {
|
||||||
Left, Right, Bottom
|
Left, Right, Bottom
|
||||||
};
|
};
|
||||||
|
|
||||||
DiveCartesianAxis(Position position, int integralDigits, int fractionalDigits, color_index_t gridColor,
|
DiveCartesianAxis(Position position, bool inverted, int integralDigits, int fractionalDigits, color_index_t gridColor,
|
||||||
QColor textColor, bool textVisible, bool linesVisible,
|
QColor textColor, bool textVisible, bool linesVisible,
|
||||||
double dpr, double labelScale, bool printMode, bool isGrayscale, ProfileScene &scene);
|
double dpr, double labelScale, bool printMode, bool isGrayscale, ProfileScene &scene);
|
||||||
~DiveCartesianAxis();
|
~DiveCartesianAxis();
|
||||||
void setBounds(double min, double max);
|
void setBounds(double min, double max);
|
||||||
void setTransform(double a, double b = 0.0);
|
void setTransform(double a, double b = 0.0);
|
||||||
void setOrientation(Orientation orientation);
|
|
||||||
double minimum() const;
|
double minimum() const;
|
||||||
double maximum() const;
|
double maximum() const;
|
||||||
std::pair<double, double> screenMinMax() const;
|
std::pair<double, double> screenMinMax() const;
|
||||||
|
@ -54,13 +47,13 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Position position;
|
Position position;
|
||||||
|
bool inverted; // Top-to-bottom or right-to-left axis.
|
||||||
int fractionalDigits;
|
int fractionalDigits;
|
||||||
QRectF rect; // Rectangle to fill with grid lines
|
QRectF rect; // Rectangle to fill with grid lines
|
||||||
QPen gridPen;
|
QPen gridPen;
|
||||||
QColor textColor;
|
QColor textColor;
|
||||||
ProfileScene &scene;
|
ProfileScene &scene;
|
||||||
QString textForValue(double value) const;
|
QString textForValue(double value) const;
|
||||||
Orientation orientation;
|
|
||||||
QList<DiveTextItem *> labels;
|
QList<DiveTextItem *> labels;
|
||||||
QList<DiveLineItem *> lines;
|
QList<DiveLineItem *> lines;
|
||||||
double dataMin, dataMax;
|
double dataMin, dataMax;
|
||||||
|
|
|
@ -47,19 +47,19 @@ ProfileScene::ProfileScene(double dpr, bool printMode, bool isGrayscale) :
|
||||||
maxtime(-1),
|
maxtime(-1),
|
||||||
maxdepth(-1),
|
maxdepth(-1),
|
||||||
dataModel(new DivePlotDataModel(this)),
|
dataModel(new DivePlotDataModel(this)),
|
||||||
profileYAxis(new DiveCartesianAxis(DiveCartesianAxis::Position::Left, 3, 0, TIME_GRID, Qt::red, true, true,
|
profileYAxis(new DiveCartesianAxis(DiveCartesianAxis::Position::Left, true, 3, 0, TIME_GRID, Qt::red, true, true,
|
||||||
dpr, 1.0, printMode, isGrayscale, *this)),
|
dpr, 1.0, printMode, isGrayscale, *this)),
|
||||||
gasYAxis(new DiveCartesianAxis(DiveCartesianAxis::Position::Right, 1, 2, TIME_GRID, Qt::black, true, true,
|
gasYAxis(new DiveCartesianAxis(DiveCartesianAxis::Position::Right, false, 1, 2, TIME_GRID, Qt::black, true, true,
|
||||||
dpr, 0.7, printMode, isGrayscale, *this)),
|
dpr, 0.7, printMode, isGrayscale, *this)),
|
||||||
temperatureAxis(new DiveCartesianAxis(DiveCartesianAxis::Position::Right, 3, 0, TIME_GRID, Qt::black, false, false,
|
temperatureAxis(new DiveCartesianAxis(DiveCartesianAxis::Position::Right, false, 3, 0, TIME_GRID, Qt::black, false, false,
|
||||||
dpr, 1.0, printMode, isGrayscale, *this)),
|
dpr, 1.0, printMode, isGrayscale, *this)),
|
||||||
timeAxis(new DiveCartesianAxis(DiveCartesianAxis::Position::Bottom, 2, 2, TIME_GRID, Qt::blue, true, true,
|
timeAxis(new DiveCartesianAxis(DiveCartesianAxis::Position::Bottom, false, 2, 2, TIME_GRID, Qt::blue, true, true,
|
||||||
dpr, 1.0, printMode, isGrayscale, *this)),
|
dpr, 1.0, printMode, isGrayscale, *this)),
|
||||||
cylinderPressureAxis(new DiveCartesianAxis(DiveCartesianAxis::Position::Right, 4, 0, TIME_GRID, Qt::black, false, false,
|
cylinderPressureAxis(new DiveCartesianAxis(DiveCartesianAxis::Position::Right, false, 4, 0, TIME_GRID, Qt::black, false, false,
|
||||||
dpr, 1.0, printMode, isGrayscale, *this)),
|
dpr, 1.0, printMode, isGrayscale, *this)),
|
||||||
heartBeatAxis(new DiveCartesianAxis(DiveCartesianAxis::Position::Left, 3, 0, HR_AXIS, Qt::black, true, true,
|
heartBeatAxis(new DiveCartesianAxis(DiveCartesianAxis::Position::Left, false, 3, 0, HR_AXIS, Qt::black, true, true,
|
||||||
dpr, 0.7, printMode, isGrayscale, *this)),
|
dpr, 0.7, printMode, isGrayscale, *this)),
|
||||||
percentageAxis(new DiveCartesianAxis(DiveCartesianAxis::Position::Right, 2, 0, TIME_GRID, Qt::black, false, false,
|
percentageAxis(new DiveCartesianAxis(DiveCartesianAxis::Position::Right, false, 2, 0, TIME_GRID, Qt::black, false, false,
|
||||||
dpr, 0.7, printMode, isGrayscale, *this)),
|
dpr, 0.7, printMode, isGrayscale, *this)),
|
||||||
diveProfileItem(createItem<DiveProfileItem>(*profileYAxis, DivePlotDataModel::DEPTH, 0, dpr)),
|
diveProfileItem(createItem<DiveProfileItem>(*profileYAxis, DivePlotDataModel::DEPTH, 0, dpr)),
|
||||||
temperatureItem(createItem<DiveTemperatureItem>(*temperatureAxis, DivePlotDataModel::TEMPERATURE, 1, dpr)),
|
temperatureItem(createItem<DiveTemperatureItem>(*temperatureAxis, DivePlotDataModel::TEMPERATURE, 1, dpr)),
|
||||||
|
@ -87,21 +87,6 @@ ProfileScene::ProfileScene(double dpr, bool printMode, bool isGrayscale) :
|
||||||
setSceneRect(0, 0, 100, 100);
|
setSceneRect(0, 0, 100, 100);
|
||||||
setItemIndexMethod(QGraphicsScene::NoIndex);
|
setItemIndexMethod(QGraphicsScene::NoIndex);
|
||||||
|
|
||||||
// Initialize axes. Perhaps part of this should be moved down to the axes code?
|
|
||||||
profileYAxis->setOrientation(DiveCartesianAxis::TopToBottom);
|
|
||||||
|
|
||||||
gasYAxis->setOrientation(DiveCartesianAxis::BottomToTop);
|
|
||||||
|
|
||||||
#ifndef SUBSURFACE_MOBILE
|
|
||||||
heartBeatAxis->setOrientation(DiveCartesianAxis::BottomToTop);
|
|
||||||
|
|
||||||
percentageAxis->setOrientation(DiveCartesianAxis::BottomToTop);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
temperatureAxis->setOrientation(DiveCartesianAxis::BottomToTop);
|
|
||||||
|
|
||||||
cylinderPressureAxis->setOrientation(DiveCartesianAxis::BottomToTop);
|
|
||||||
|
|
||||||
gasYAxis->setZValue(timeAxis->zValue() + 1);
|
gasYAxis->setZValue(timeAxis->zValue() + 1);
|
||||||
tankItem->setZValue(100);
|
tankItem->setZValue(100);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue