summaryrefslogtreecommitdiffstats
path: root/qt-ui
diff options
context:
space:
mode:
authorGravatar Dirk Hohndel <dirk@hohndel.org>2013-06-22 15:57:26 -0700
committerGravatar Dirk Hohndel <dirk@hohndel.org>2013-06-22 15:57:26 -0700
commit31449dca22873e500842ab1cfcca3a211764d98a (patch)
tree51142e5b4148f25d5e416b6b621ed83447cc43cc /qt-ui
parent81858167ac3f69e99a1108fa305f2865417e2b81 (diff)
parent880b98ed35c2dbf3b5a015784323894c59bc7feb (diff)
downloadsubsurface-31449dca22873e500842ab1cfcca3a211764d98a.tar.gz
Merge branch 'divePlannerTry3' of github.com:tcanabrava/subsurface
Diffstat (limited to 'qt-ui')
-rw-r--r--qt-ui/diveplanner.cpp385
-rw-r--r--qt-ui/diveplanner.h106
-rw-r--r--qt-ui/diveplanner.ui74
-rw-r--r--qt-ui/mainwindow.cpp11
-rw-r--r--qt-ui/mainwindow.h1
-rw-r--r--qt-ui/mainwindow.ui9
6 files changed, 585 insertions, 1 deletions
diff --git a/qt-ui/diveplanner.cpp b/qt-ui/diveplanner.cpp
new file mode 100644
index 000000000..d6096f4bb
--- /dev/null
+++ b/qt-ui/diveplanner.cpp
@@ -0,0 +1,385 @@
+#include "diveplanner.h"
+#include <cmath>
+#include <QMouseEvent>
+#include <QDebug>
+#include "ui_diveplanner.h"
+
+DivePlannerGraphics::DivePlannerGraphics(QWidget* parent): QGraphicsView(parent), activeDraggedHandler(0)
+{
+ setMouseTracking(true);
+ setScene( new QGraphicsScene());
+ scene()->setSceneRect(0,0,100,100);
+
+ verticalLine = new QGraphicsLineItem(0,0,0, 100);
+ verticalLine->setPen(QPen(Qt::DotLine));
+ scene()->addItem(verticalLine);
+
+ horizontalLine = new QGraphicsLineItem(0,0,100,0);
+ horizontalLine->setPen(QPen(Qt::DotLine));
+ scene()->addItem(horizontalLine);
+
+ timeLine = new Ruler();
+ timeLine->setMinimum(0);
+ timeLine->setMaximum(20);
+ timeLine->setTickInterval(10);
+ timeLine->setLine( 10, 90, 99, 90);
+ timeLine->setOrientation(Qt::Horizontal);
+ timeLine->updateTicks();
+ scene()->addItem(timeLine);
+
+ depthLine = new Ruler();
+ depthLine->setMinimum(0);
+ depthLine->setMaximum(10);
+ depthLine->setTickInterval(10);
+ depthLine->setLine( 10, 1, 10, 90);
+ depthLine->setOrientation(Qt::Vertical);
+ depthLine->updateTicks();
+ scene()->addItem(depthLine);
+
+ timeString = new QGraphicsSimpleTextItem();
+ timeString->setFlag(QGraphicsItem::ItemIgnoresTransformations);
+ scene()->addItem(timeString);
+
+ depthString = new QGraphicsSimpleTextItem();
+ depthString->setFlag(QGraphicsItem::ItemIgnoresTransformations);
+ scene()->addItem(depthString);
+
+ plusDepth = new Button();
+ plusDepth->setPos(15, 1);
+ scene()->addItem(plusDepth);
+ connect(plusDepth, SIGNAL(clicked()), this, SLOT(increaseDepth()));
+
+ plusTime = new Button();
+ plusTime->setPos( 95, 90);
+ scene()->addItem(plusTime);
+ connect(plusTime, SIGNAL(clicked()), this, SLOT(increaseTime()));
+}
+
+void DivePlannerGraphics::increaseDepth()
+{
+ qDebug() << "Increase Depth Clicked";
+}
+
+void DivePlannerGraphics::increaseTime()
+{
+ qDebug() << "Increase Time Clicked";
+}
+
+void DivePlannerGraphics::mouseDoubleClickEvent(QMouseEvent* event)
+{
+ QPointF mappedPos = mapToScene(event->pos());
+ if(isPointOutOfBoundaries(mappedPos))
+ return;
+
+ if(handles.count() && handles.last()->x() > mappedPos.x()){
+ return;
+ }
+
+ DiveHandler *item = new DiveHandler ();
+ item->setRect(-5,-5,10,10);
+ item->setFlag(QGraphicsItem::ItemIgnoresTransformations);
+
+ double xpos = timeLine->posAtValue(rint(timeLine->valueAt(mappedPos)));
+ double ypos = depthLine->posAtValue(rint(depthLine->valueAt(mappedPos)));
+ item->setPos( QPointF(xpos, ypos));
+ scene()->addItem(item);
+ handles << item;
+
+ if (lines.empty()){
+ double xpos = timeLine->posAtValue(0);
+ double ypos = depthLine->posAtValue(0);
+ QGraphicsLineItem *first = new QGraphicsLineItem(xpos,ypos, mappedPos.x(), mappedPos.y());
+ item->from = first;
+ lines.push_back(first);
+ create_deco_stop();
+ scene()->addItem(first);
+ }else{
+ clear_generated_deco();
+ DiveHandler *prevHandle = handles.at( handles.count()-2);
+ QGraphicsLineItem *line = new QGraphicsLineItem(prevHandle->x(), prevHandle->y(), item->x(), item->y());
+ prevHandle->to = line;
+ item->from = line;
+ lines.push_back(line);
+ scene()->addItem(line);
+ create_deco_stop();
+ }
+ item->time = (timeLine->valueAt(mappedPos));
+ item->depth = (depthLine->valueAt(mappedPos));
+}
+
+void DivePlannerGraphics::clear_generated_deco()
+{
+ for(int i = handles.count(); i <= lines.count(); i++){
+ scene()->removeItem(lines.last());
+ delete lines.last();
+ lines.removeLast();
+ }
+}
+
+void DivePlannerGraphics::create_deco_stop()
+{
+ // This needs to be done in the following steps:
+ // Get the user-input and calculate the dive info
+ Q_FOREACH(DiveHandler *h, handles){
+ // use this somewhere.
+ h->time;
+ h->depth;
+ }
+ // create the dive info here.
+
+ // set the new 'end time' of the dive.
+ // note that this is not the user end,
+ // but the real end of the dive.
+ timeLine->setMaximum(60);
+ timeLine->updateTicks();
+
+ // Re-position the user generated dive handlers
+ Q_FOREACH(DiveHandler *h, handles){
+ // uncomment this as soon as the posAtValue is implemented.
+ // h->setPos( timeLine->posAtValue(h->time),
+ // depthLine->posAtValue(h->depth));
+ }
+
+ // Create all 'deco' GraphicsLineItems and put it on the canvas.This following three lines will
+ // most probably need to enter on a loop.
+ double xpos = timeLine->posAtValue(timeLine->maximum());
+ double ypos = depthLine->posAtValue(depthLine->minimum());
+ QGraphicsLineItem *item = new QGraphicsLineItem(handles.last()->x(), handles.last()->y(), xpos, ypos);
+ scene()->addItem(item);
+ lines << item;
+}
+
+void DivePlannerGraphics::resizeEvent(QResizeEvent* event)
+{
+ QGraphicsView::resizeEvent(event);
+ fitInView(sceneRect(), Qt::KeepAspectRatio);
+}
+
+void DivePlannerGraphics::showEvent(QShowEvent* event)
+{
+ QGraphicsView::showEvent(event);
+ fitInView(sceneRect(), Qt::KeepAspectRatio);
+}
+
+void DivePlannerGraphics::mouseMoveEvent(QMouseEvent* event)
+{
+ QPointF mappedPos = mapToScene(event->pos());
+ if (isPointOutOfBoundaries(mappedPos))
+ return;
+
+ verticalLine->setLine(mappedPos.x(), 0, mappedPos.x(), 100);
+ horizontalLine->setLine(0, mappedPos.y(), 100, mappedPos.y());
+ depthString->setText(QString::number( (int) depthLine->valueAt(mappedPos)) + "m" );
+ depthString->setPos(0, mappedPos.y());
+ timeString->setText(QString::number( (int) timeLine->valueAt(mappedPos)) + "min");
+ timeString->setPos(mappedPos.x()+1, 90);
+
+ if(activeDraggedHandler)
+ moveActiveHandler(mappedPos);
+ if (!handles.count())
+ return;
+
+ if (handles.last()->x() > mappedPos.x()){
+ verticalLine->setPen( QPen(QBrush(Qt::red), 0, Qt::SolidLine));
+ horizontalLine->setPen( QPen(QBrush(Qt::red), 0, Qt::SolidLine));
+ }else{
+ verticalLine->setPen(QPen(Qt::DotLine));
+ horizontalLine->setPen(QPen(Qt::DotLine));
+ }
+}
+
+void DivePlannerGraphics::moveActiveHandler(const QPointF& pos)
+{
+ int idx = handles.indexOf(activeDraggedHandler);
+
+ double xpos = timeLine->posAtValue(rint(timeLine->valueAt(pos)));
+ double ypos = depthLine->posAtValue(rint(depthLine->valueAt(pos)));
+
+ QPointF newPos(xpos, ypos);
+ bool moveLines = false;;
+ // do not allow it to move between handlers.
+ if (handles.count() > 1){
+ if (idx == 0 ){ // first
+ if (newPos.x() < handles[1]->x()){
+ activeDraggedHandler->setPos(newPos);
+ moveLines = true;
+ }
+ }else if (idx == handles.count()-1){ // last
+ if (newPos.x() > handles[idx-1]->x()){
+ activeDraggedHandler->setPos(newPos);
+ moveLines = true;
+ }
+ }else{ // middle
+ if (newPos.x() > handles[idx-1]->x() && newPos.x() < handles[idx+1]->x()){
+ activeDraggedHandler->setPos(newPos);
+ moveLines = true;
+ }
+ }
+ }else{
+ activeDraggedHandler->setPos(newPos);
+ moveLines = true;
+ }
+ if (moveLines){
+ if (activeDraggedHandler->from){
+ QLineF f = activeDraggedHandler->from->line();
+ activeDraggedHandler->from->setLine(f.x1(), f.y1(), newPos.x(), newPos.y());
+ }
+
+ if (activeDraggedHandler->to){
+ QLineF f = activeDraggedHandler->to->line();
+ activeDraggedHandler->to->setLine(newPos.x(), newPos.y(), f.x2(), f.y2());
+ }
+
+ if(activeDraggedHandler == handles.last()){
+ clear_generated_deco();
+ create_deco_stop();
+ }
+ }
+}
+
+bool DivePlannerGraphics::isPointOutOfBoundaries(const QPointF& point)
+{
+ double xpos = timeLine->valueAt(point);
+ double ypos = depthLine->valueAt(point);
+
+ if (xpos > timeLine->maximum()
+ || xpos < timeLine->minimum()
+ || ypos > depthLine->maximum()
+ || ypos < depthLine->minimum())
+ {
+ return true;
+ }
+ return false;
+}
+
+void DivePlannerGraphics::mousePressEvent(QMouseEvent* event)
+{
+ QPointF mappedPos = mapToScene(event->pos());
+ Q_FOREACH(QGraphicsItem *item, scene()->items(mappedPos)){
+ if (DiveHandler *h = qgraphicsitem_cast<DiveHandler*>(item)){
+ activeDraggedHandler = h;
+ activeDraggedHandler->setBrush(Qt::red);
+ }
+ }
+ QGraphicsView::mousePressEvent(event);
+}
+
+void DivePlannerGraphics::mouseReleaseEvent(QMouseEvent* event)
+{
+ if (activeDraggedHandler){
+ QPointF mappedPos = mapToScene(event->pos());
+ activeDraggedHandler->time = (timeLine->valueAt(mappedPos));
+ activeDraggedHandler->depth = (depthLine->valueAt(mappedPos));
+ activeDraggedHandler->setBrush(QBrush());
+ activeDraggedHandler = 0;
+ }
+}
+
+DiveHandler::DiveHandler(): QGraphicsEllipseItem(), from(0), to(0)
+{
+}
+
+void Ruler::setMaximum(double maximum)
+{
+ max = maximum;
+}
+
+void Ruler::setMinimum(double minimum)
+{
+ min = minimum;
+}
+
+Ruler::Ruler() : orientation(Qt::Horizontal)
+{
+}
+
+void Ruler::setOrientation(Qt::Orientation o)
+{
+ orientation = o;
+}
+
+void Ruler::updateTicks()
+{
+ qDeleteAll(ticks);
+ QLineF m = line();
+ if(orientation == Qt::Horizontal){
+ double steps = (max - min) / interval;
+ double stepSize = (m.x2() - m.x1()) / steps;
+ for(qreal pos = m.x1(); pos < m.x2(); pos += stepSize){
+ QGraphicsLineItem *l = new QGraphicsLineItem(pos, m.y1(), pos, m.y1() + 1, this);
+
+ }
+ }else{
+ double steps = (max - min) / interval;
+ double stepSize = (m.y2() - m.y1()) / steps;
+ for(qreal pos = m.y1(); pos < m.y2(); pos += stepSize){
+ QGraphicsLineItem *l = new QGraphicsLineItem(m.x1(), pos, m.x1() - 1, pos, this);
+ }
+ }
+}
+
+void Ruler::setTickInterval(double i)
+{
+ interval = i;
+}
+
+qreal Ruler::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 Ruler::posAtValue(qreal value)
+{
+ QLineF m = line();
+ 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()
+ : retValue + m.y1();
+ return retValue;
+}
+
+DivePlanner::DivePlanner() : ui(new Ui::DivePlanner())
+{
+ ui->setupUi(this);
+}
+
+struct dive* DivePlanner::getDive()
+{
+ return 0;
+}
+
+DivePlanner* DivePlanner::instance()
+{
+ static DivePlanner *self = new DivePlanner();
+ return self;
+}
+
+double Ruler::maximum() const
+{
+ return max;
+}
+
+double Ruler::minimum() const
+{
+ return min;
+}
+
+Button::Button(QObject* parent): QObject(parent), QGraphicsPixmapItem()
+{
+ setPixmap(QPixmap(":plus").scaled(20,20));
+ setFlag(ItemIgnoresTransformations);
+}
+
+void Button::mousePressEvent(QGraphicsSceneMouseEvent* event)
+{
+ emit clicked();
+}
diff --git a/qt-ui/diveplanner.h b/qt-ui/diveplanner.h
new file mode 100644
index 000000000..453cec63e
--- /dev/null
+++ b/qt-ui/diveplanner.h
@@ -0,0 +1,106 @@
+#ifndef DIVEPLANNER_H
+#define DIVEPLANNER_H
+
+#include <QGraphicsView>
+#include <QGraphicsPathItem>
+#include <QDialog>
+
+class Button : public QObject, public QGraphicsPixmapItem {
+ Q_OBJECT
+public:
+ explicit Button(QObject* parent = 0);
+protected:
+ virtual void mousePressEvent(QGraphicsSceneMouseEvent* event);
+signals:
+ void clicked();
+};
+
+class DiveHandler : public QGraphicsEllipseItem{
+public:
+ DiveHandler();
+ QGraphicsLineItem *from;
+ QGraphicsLineItem *to;
+ qreal time;
+ qreal depth;
+};
+
+class Ruler : public QGraphicsLineItem{
+public:
+ Ruler();
+ void setMinimum(double minimum);
+ void setMaximum(double maximum);
+ void setTickInterval(double interval);
+ void setOrientation(Qt::Orientation orientation);
+ void updateTicks();
+ double minimum() const;
+ double maximum() const;
+ qreal valueAt(const QPointF& p);
+ qreal posAtValue(qreal value);
+
+private:
+ Qt::Orientation orientation;
+ QList<QGraphicsLineItem*> ticks;
+ double min;
+ double max;
+ double interval;
+ double posBegin;
+ double posEnd;
+};
+
+class DivePlannerGraphics : public QGraphicsView {
+ Q_OBJECT
+public:
+ DivePlannerGraphics(QWidget* parent = 0);
+protected:
+ virtual void mouseDoubleClickEvent(QMouseEvent* event);
+ virtual void showEvent(QShowEvent* event);
+ virtual void resizeEvent(QResizeEvent* event);
+ virtual void mouseMoveEvent(QMouseEvent* event);
+ virtual void mousePressEvent(QMouseEvent* event);
+ virtual void mouseReleaseEvent(QMouseEvent* event);
+
+ void clear_generated_deco();
+ void create_deco_stop();
+ bool isPointOutOfBoundaries(const QPointF& point);
+
+private slots:
+ void increaseTime();
+ void increaseDepth();
+
+private:
+
+ void moveActiveHandler(const QPointF& pos);
+ QList<QGraphicsLineItem*> lines;
+ QList<DiveHandler *> handles;
+ QGraphicsLineItem *verticalLine;
+ QGraphicsLineItem *horizontalLine;
+ DiveHandler *activeDraggedHandler;
+
+ Ruler *timeLine;
+ QGraphicsSimpleTextItem *timeString;
+
+ Ruler *depthLine;
+ QGraphicsSimpleTextItem *depthString;
+
+ Button *plusTime;
+ Button *plusDepth;
+ Button *lessTime;
+ Button *lessDepth;
+
+};
+
+namespace Ui{
+ class DivePlanner;
+}
+
+class DivePlanner : public QDialog{
+ Q_OBJECT
+public:
+ static DivePlanner *instance();
+ struct dive* getDive();
+
+private:
+ DivePlanner();
+ Ui::DivePlanner *ui;
+};
+#endif
diff --git a/qt-ui/diveplanner.ui b/qt-ui/diveplanner.ui
new file mode 100644
index 000000000..e4903f0f8
--- /dev/null
+++ b/qt-ui/diveplanner.ui
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>DivePlanner</class>
+ <widget class="QDialog" name="DivePlanner">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>575</width>
+ <height>451</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Dialog</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="DivePlannerGraphics" name="graphicsView"/>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>DivePlannerGraphics</class>
+ <extends>QGraphicsView</extends>
+ <header>diveplanner.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>DivePlanner</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>DivePlanner</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/qt-ui/mainwindow.cpp b/qt-ui/mainwindow.cpp
index 06e6b7734..b61f962c4 100644
--- a/qt-ui/mainwindow.cpp
+++ b/qt-ui/mainwindow.cpp
@@ -32,6 +32,7 @@
#include "subsurfacewebservices.h"
#include "divecomputermanagementdialog.h"
#include "simplewidgets.h"
+#include "diveplanner.h"
static MainWindow* instance = 0;
@@ -181,6 +182,16 @@ void MainWindow::on_actionPrint_triggered()
qDebug("actionPrint");
}
+void MainWindow::on_actionDivePlanner_triggered()
+{
+ DivePlanner *planner = DivePlanner::instance();
+ if (planner->exec() == QDialog::Accepted){
+ struct dive *d = planner->getDive();
+ qDebug() << "Finish me.";
+ }
+}
+
+
void MainWindow::on_actionPreferences_triggered()
{
PreferencesDialog::instance()->show();
diff --git a/qt-ui/mainwindow.h b/qt-ui/mainwindow.h
index 0693f07fd..85825958d 100644
--- a/qt-ui/mainwindow.h
+++ b/qt-ui/mainwindow.h
@@ -83,6 +83,7 @@ private slots:
void on_actionInputPlan_triggered();
void on_actionAboutSubsurface_triggered();
void on_actionUserManual_triggered();
+ void on_actionDivePlanner_triggered();
void current_dive_changed(int divenr);
void initialUiSetup();
diff --git a/qt-ui/mainwindow.ui b/qt-ui/mainwindow.ui
index 1a985f812..1dfb8a27b 100644
--- a/qt-ui/mainwindow.ui
+++ b/qt-ui/mainwindow.ui
@@ -103,7 +103,7 @@
<x>0</x>
<y>0</y>
<width>763</width>
- <height>34</height>
+ <height>20</height>
</rect>
</property>
<widget class="QMenu" name="menuFile">
@@ -152,6 +152,8 @@
<addaction name="separator"/>
<addaction name="actionPreviousDC"/>
<addaction name="actionNextDC"/>
+ <addaction name="separator"/>
+ <addaction name="actionDivePlanner"/>
</widget>
<widget class="QMenu" name="menuFilter">
<property name="title">
@@ -368,6 +370,11 @@
<string>Ctrl+4</string>
</property>
</action>
+ <action name="actionDivePlanner">
+ <property name="text">
+ <string>Dive Planner</string>
+ </property>
+ </action>
</widget>
<customwidgets>
<customwidget>