summaryrefslogblamecommitdiffstats
path: root/qt-ui/profile/divecartesianaxis.cpp
blob: 8a1b1890d43eb0eb5f6f98aef9e44b2ea6a334de (plain) (tree)
1
2
3
4
5
6
7
8
9
10


                              
                        

                         
                        
                    
 





                                          

                                                  
                           



                                                  
                           





                                                         
                                                                                                  
 
                          





                                       
                                                     
                        
 



                                                     
                                     
                          
                                                          
                                              
                               



                                           




                                                                              
                                                                   












                                                 
                                    
 
                                                                                       




                                                                               
                                                            
                                                                                
                                                                              
                        


                                                                              
                                                     
                                                                             




                                                                               
                                           
 


                                                                
                                                                  
                 
                                        
                                                                               
 



                                                                                                                                          
                        



                                                                                                     
                 
 





                                                                










                                               
















                                                     
                                                                     









                                                                            
                                                   
                                                                           
                                                                                   
                                                 
                                                     
                                                                     
                                      
 
                                             



                                                                         
                        



























                                                     



                                                     
 




                                             

















                                                                                                                    




                                            
                                            
                                           
 
                                                   
                                                           

 
















                                                                        
                                                            


















                                                       
                                                        







                                                                             
                                                                        
                                                                       
                                                                           













                                                                                                    
                                        







                                                                                                                          
                                        

                                              
 
#include "divecartesianaxis.h"
#include "divelineitem.h"
#include "divetextitem.h"
#include "helpers.h"
#include "preferences.h"
#include <QPen>
#include <QGraphicsScene>
#include <QDebug>
#include <QGraphicsView>
#include <QStyleOption>
#include <QSettings>

static QPen gridPen(){
	QPen pen;
	pen.setColor(getColor(TIME_GRID));
	pen.setWidth(2);
	pen.setCosmetic(true);
	return pen;
}
void DiveCartesianAxis::setMaximum(double maximum)
{
	max = maximum;
	emit sizeChanged();
}

void DiveCartesianAxis::setMinimum(double minimum)
{
	min = minimum;
	emit sizeChanged();
}

void DiveCartesianAxis::setTextColor(const QColor& color)
{
	textColor = color;
}

DiveCartesianAxis::DiveCartesianAxis() : orientation(LeftToRight), showTicks(true), showText(true)
{
	setPen(gridPen());
}

DiveCartesianAxis::~DiveCartesianAxis()
{

}

void DiveCartesianAxis::setOrientation(Orientation o)
{
	orientation = o;
}

QColor DiveCartesianAxis::colorForValue(double value)
{
	return QColor(Qt::black);
}

void DiveCartesianAxis::updateTicks()
{
	QLineF m = line();
	// unused so far:
	// QGraphicsView *view = scene()->views().first();
	double steps = (max - min) / interval;
	double currValue = min;

	if(!showText && !labels.empty()){
			qDeleteAll(labels);
			labels.clear();
	}

	if (!labels.isEmpty() && labels.size() > steps) {
		while (labels.size() > steps) {
				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, stepSize;
	if (orientation == TopToBottom) {
		begin = m.y1();
		stepSize = (m.y2() - m.y1());
	} else if (orientation == BottomToTop) {
		begin = m.y2();
		stepSize = (m.y2() - m.y1());
	} else if (orientation == LeftToRight ) {
		begin = m.x1();
		stepSize = (m.x2() - m.x1());
	} else if (orientation == RightToLeft) {
		begin = m.x2();
		stepSize = (m.x2() - m.x1());
	}
	stepSize = stepSize / steps;

	for (int i = 0, count = labels.size(); i < count; i++, currValue += interval) {
		qreal childPos;
		if (orientation == TopToBottom || orientation == LeftToRight) {
			childPos = begin + i * stepSize;
		} else {
			childPos = begin - i * stepSize;
		}
		labels[i]->setText(textForValue(currValue));
		if ( orientation == LeftToRight || orientation == RightToLeft) {
			labels[i]->animateMoveTo(childPos, m.y1() + tickSize);
		} else {
			labels[i]->animateMoveTo(m.x1() - tickSize, childPos);
		}
	}

	// Add's the rest of the needed Ticks / Text.
	for (int i = labels.size(); i < steps; i++,  currValue += interval) {
		qreal childPos;
		if (orientation == TopToBottom || orientation == LeftToRight) {
		childPos = begin + i * stepSize;
		} else {
			childPos = begin - i * stepSize;
		}
		DiveTextItem *label = NULL;

		if (showText){
			label = new DiveTextItem(this);
			label->setText(textForValue(currValue));
			label->setBrush(QBrush(textColor));
			label->setBrush(colorForValue(currValue));
		}
		labels.push_back(label);
		if (orientation == RightToLeft || orientation == LeftToRight) {

			if(showText){
				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 {
			if(showText){
				label->setAlignment(Qt::AlignVCenter| Qt::AlignRight);
				label->setPos(m.x1() - tickSize, scene()->sceneRect().height() + 10);
				label->animateMoveTo(m.x1() - tickSize, childPos);
			}
		}
	}
}

void DiveCartesianAxis::animateChangeLine(const QLineF& newLine)
{
	setLine(newLine);
	updateTicks();
	sizeChanged();
}

void DiveCartesianAxis::setShowText(bool show)
{
	showText = show;
	updateTicks();
}

void DiveCartesianAxis::setShowTicks(bool show)
{
	showTicks = show;
	updateTicks();
}

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 == LeftToRight || RightToLeft?
				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;
	// unused for now:
	// double distanceFromOrigin = value - min;
	double percent =  IS_FP_SAME(min,max) ? 0.0 : (value - min) / size;


	double realSize = orientation == LeftToRight || orientation == RightToLeft?
				m.x2() - m.x1() :
				m.y2() - m.y1();

	// Inverted axis, just invert the percentage.
	if (orientation == RightToLeft || orientation == BottomToTop)
		percent = 1 - percent;

	double retValue = realSize * percent;
	double adjusted =
		orientation == LeftToRight ?  retValue + m.x1() + p.x() :
		orientation == RightToLeft ?  retValue + m.x1() + p.x() :
		orientation == TopToBottom ?  retValue + m.y1() + p.y() :
		/* entation == BottomToTop */ retValue + m.y1() + p.y() ;
	return adjusted;
}

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);
}

QColor DepthAxis::colorForValue(double value)
{
	Q_UNUSED(value);
	return QColor(Qt::red);
}

DepthAxis::DepthAxis()
{
	connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), this, SLOT(settingsChanged()));
	settingsChanged(); // force the correct size of the line.
}

void DepthAxis::settingsChanged()
{
	QSettings s;

	s.beginGroup("TecDetails");
	bool ppGraph = s.value("phegraph").toBool() || s.value("po2graph").toBool() || s.value("pn2graph").toBool();
	if (ppGraph) {
		animateChangeLine(QLineF(0,2,0,60));
	} else {
		animateChangeLine(QLineF(0,2,0,98));
	}
}

QColor TimeAxis::colorForValue(double value)
{
	Q_UNUSED(value);
	return QColor(Qt::blue);
}

QString TimeAxis::textForValue(double value)
{
	return QString::number(value / 60);
}

QString TemperatureAxis::textForValue(double value)
{
	return QString::number(mkelvin_to_C( (int) value));
}


void DiveCartesianPlane::setLeftAxis(DiveCartesianAxis* axis)
{
	leftAxis = axis;
	connect(leftAxis, SIGNAL(sizeChanged()), this, SLOT(setup()));
	if (bottomAxis)
		setup();
}

void DiveCartesianPlane::setBottomAxis(DiveCartesianAxis* axis)
{
	bottomAxis = axis;
	connect(bottomAxis, SIGNAL(sizeChanged()), this, SLOT(setup()));
	if (leftAxis)
		setup();
}

QLineF DiveCartesianPlane::horizontalLine() const
{
	return (bottomAxis) ? bottomAxis->line() : QLineF();
}

void DiveCartesianPlane::setHorizontalLine(QLineF line)
{
	if ( horizontalSize == line.length())
		return;
	horizontalSize = line.length();
	setup();
}

void DiveCartesianPlane::setVerticalLine(QLineF line)
{
	if (verticalSize == line.length())
		return;
	verticalSize = line.length();
	setup();
}

QLineF DiveCartesianPlane::verticalLine() const
{
	return (leftAxis) ? leftAxis->line() : QLineF();
}

void DiveCartesianPlane::setup()
{
	if (!leftAxis || !bottomAxis || !scene())
		return;

	// This creates a Grid around the axis, creating the cartesian plane.
	const int top = leftAxis->posAtValue(leftAxis->minimum());
	// unused for now:
	// const int bottom = leftAxis->posAtValue(leftAxis->maximum());
	const int left = bottomAxis->posAtValue(bottomAxis->minimum());
	// unused for now:
	// const int right = bottomAxis->posAtValue(bottomAxis->maximum());

	setRect(0, 0, horizontalSize, verticalSize);
	setPos(left, top);

	qDeleteAll(horizontalLines);
	qDeleteAll(verticalLines);
	horizontalLines.clear();
	verticalLines.clear();

	// DEPTH is M_OR_FEET(10,30), Minutes are 600, per line.
	for (int i = leftAxis->minimum(), max = leftAxis->maximum(); i < max; i += M_OR_FT(10,30)) {
		DiveLineItem *line = new DiveLineItem();
		line->setLine(0, 0, horizontalSize, 0);
		line->setPos(left,leftAxis->posAtValue(i));
		line->setZValue(-1);
		line->setPen(gridPen());
		horizontalLines.push_back(line);
		scene()->addItem(line);
	}

	for (int i = bottomAxis->minimum(), max = bottomAxis->maximum(); i < max; i += 600) { // increments by 10 minutes.
		DiveLineItem *line = new DiveLineItem();
		line->setLine(0, 0, 0, verticalSize);
		line->setPos(bottomAxis->posAtValue(i), top);
		line->setZValue(-1);
		line->setPen(gridPen());
		verticalLines.push_back(line);
		scene()->addItem(line);
	}
}