This page provides a basic planner input and output page with editable
ListView items for cylinders, waypoints and deco stops.

It is not yet connected to the core planner c++ and c code. The ListModels
should be replaced with Qt models, sharings as much as possible with existing
models.

Signed-off-by: Rick Walsh <[email protected]>
---
 qt-mobile/qml/Planner.qml          | 476 +++++++++++++++++++++++++++++++++++++
 qt-mobile/qml/mobile-resources.qrc |   1 +
 2 files changed, 477 insertions(+)
 create mode 100644 qt-mobile/qml/Planner.qml

diff --git a/qt-mobile/qml/Planner.qml b/qt-mobile/qml/Planner.qml
new file mode 100644
index 0000000..212218f
--- /dev/null
+++ b/qt-mobile/qml/Planner.qml
@@ -0,0 +1,476 @@
+import QtQuick 2.4
+import QtQuick.Controls 1.2
+import QtQuick.Layouts 1.2
+import QtQuick.Window 2.2
+import QtQuick.Dialogs 1.2
+import org.kde.plasma.mobilecomponents 0.2 as MobileComponents
+import org.subsurfacedivelog.mobile 1.0
+
+MobileComponents.Page {
+       id: planner
+       objectName: "DivePlanner"
+       color: MobileComponents.Theme.viewBackgroundColor
+
+       property double cylinderSizeNew
+       property double cylinderWorkingPressureNew
+       property string cylinderDescriptionNew
+       property double pcO2New
+       property double pcHeNew
+       property string pressureStartNew
+       property double pressureEndNew
+       property double gasDepthNew
+       property bool newCylinder
+       property int cylinderIndex
+       property int stdColWidth: content.width * 0.2
+       property int horizontalPadding: MobileComponents.Units.smallSpacing
+       property int labelRowHeight: MobileComponents.Units.gridUnit * 1.6
+       property int inputRowHeight: MobileComponents.Units.gridUnit * 1.8
+
+
+       ScrollView {
+               anchors.fill: parent
+               Flickable {
+                       id: flick
+                       anchors.fill: parent
+                       contentHeight: content.height
+                       interactive: contentHeight > height
+                       clip: true
+
+                       Column {
+                               id: content
+                               anchors {
+                                       left: parent.left
+                                       leftMargin: 
MobileComponents.Units.gridUnit * 0.5
+                                       right: parent.right
+                               }
+
+                               MobileComponents.Heading {
+                                       text: "Dive planner"
+                                       level: 2
+                               }
+
+                               ListView {
+                                       id: inputCylinders
+                                       anchors {
+                                               left: parent.left
+                                               right: parent.right
+                                       }
+                                       height: headerItem.height + 
footerItem.height + labelRowHeight * Math.min(inputCylinders.count, 3)
+                                       model: gasModel
+                                       currentIndex: -1
+                                       delegate: cylinderListDelegate
+                                       boundsBehavior: Flickable.StopAtBounds
+                                       maximumFlickVelocity: parent.height * 5
+                                       cacheBuffer: parent.height * 5
+                                       focus: true
+                                       clip: true
+                                       header: MobileComponents.Heading {
+                                               height: paintedHeight + 
MobileComponents.Units.gridUnit / 2
+                                               verticalAlignment: 
Text.AlignBottom
+                                               text: "Cylinders and gases"
+                                               level: 4
+                                       }
+                                       footer: Button {
+                                               text: "Add cylinder"
+                                               action: addCylinder
+                                       }
+                               }
+
+                               ListView {
+                                       id: inputWaypoints
+                                       anchors {
+                                               left: parent.left
+                                               right: parent.right
+                                       }
+                                       height: headerItem.height + 
inputRowHeight * inputPointsModel.count + MobileComponents.Units.smallSpacing
+                                       model: inputPointsModel
+                                       currentIndex: -1
+                                       delegate: waypointsDelegate
+                                       boundsBehavior: Flickable.StopAtBounds
+                                       maximumFlickVelocity: parent.height * 5
+                                       interactive: false //flickable 
unnecessary as listview resizes to fit. Disabling allows scrolling the whole 
page
+                                       cacheBuffer: parent.height * 5
+                                       focus: true
+                                       clip: true
+
+                                       header: Column {
+                                               height: childrenRect.height
+                                               MobileComponents.Heading {
+                                                       height: paintedHeight + 
MobileComponents.Units.gridUnit / 2
+                                                       Layout.bottomMargin: 
MobileComponents.Units.largeSpacing / 2
+                                                       verticalAlignment: 
Text.AlignTop
+                                                       text: "Waypoints"
+                                                       level: 4
+                                               }
+                                               Row {
+                                                       anchors {
+                                                               left: 
parent.left
+                                                               leftMargin: 
horizontalPadding * 2
+                                                               right: 
parent.right
+                                                               rightMargin: 
horizontalPadding
+                                                       }
+                                                       Text {
+                                                               text: 'Depth'
+                                                               
horizontalAlignment: Text.AlignHCenter
+                                                               width: 
stdColWidth
+                                                               opacity: 0.6
+                                                               font.pointSize: 
subsurfaceTheme.smallPointSize
+                                                       }
+                                                       Text {
+                                                               text: 'Duration'
+                                                               
horizontalAlignment: Text.AlignHCenter
+                                                               width: 
stdColWidth
+                                                               opacity: 0.6
+                                                               font.pointSize: 
subsurfaceTheme.smallPointSize
+                                                       }
+                                                       Text {
+                                                               text: 'Runtime'
+                                                               
horizontalAlignment: Text.AlignHCenter
+                                                               width: 
stdColWidth
+                                                               opacity: 0.6
+                                                               font.pointSize: 
subsurfaceTheme.smallPointSize
+                                                       }
+                                                       Text {
+                                                               text: 'Gas'
+                                                               opacity: 0.6
+                                                               font.pointSize: 
subsurfaceTheme.smallPointSize
+                                                       }
+                                               }
+                                       }
+                               }
+                               ListView {
+                                       id: decoStops
+                                       anchors {
+                                               left: parent.left
+                                               right: parent.right
+                                       }
+                                       height: headerItem.height + 
inputRowHeight * Math.max(decoStopsModel.count, 8)
+                                       model: decoStopsModel
+                                       currentIndex: -1
+                                       delegate: decoStopsDelegate
+                                       boundsBehavior: Flickable.StopAtBounds
+                                       maximumFlickVelocity: parent.height * 5
+                                       interactive: false //flickable 
unnecessary as listview resizes to fit. Disabling allows scrolling the whole 
page
+                                       cacheBuffer: parent.height * 5
+                                       focus: true
+                                       clip: true
+
+                                       header: Column {
+                                               height: childrenRect.height
+                                               MobileComponents.Heading {
+                                                       height: paintedHeight + 
MobileComponents.Units.gridUnit / 2
+                                                       Layout.bottomMargin: 
MobileComponents.Units.largeSpacing / 2
+                                                       verticalAlignment: 
Text.AlignTop
+                                                       text: "Decompression 
stops"
+                                                       level: 4
+                                               }
+                                               Row {
+                                                       anchors {
+                                                               left: 
parent.left
+                                                               leftMargin: 
horizontalPadding * 2
+                                                               right: 
parent.right
+                                                               rightMargin: 
horizontalPadding
+                                                       }
+                                                       Text {
+                                                               text: 'Depth'
+                                                               
horizontalAlignment: Text.AlignHCenter
+                                                               width: 
stdColWidth
+                                                               opacity: 0.6
+                                                               font.pointSize: 
subsurfaceTheme.smallPointSize
+                                                       }
+                                                       Text {
+                                                               text: 'Duration'
+                                                               
horizontalAlignment: Text.AlignHCenter
+                                                               width: 
stdColWidth
+                                                               opacity: 0.6
+                                                               font.pointSize: 
subsurfaceTheme.smallPointSize
+                                                       }
+                                                       Text {
+                                                               text: 'Runtime'
+                                                               
horizontalAlignment: Text.AlignHCenter
+                                                               width: 
stdColWidth
+                                                               opacity: 0.6
+                                                               font.pointSize: 
subsurfaceTheme.smallPointSize
+                                                       }
+                                                       Text {
+                                                               text: 'Gas'
+                                                               opacity: 0.6
+                                                               font.pointSize: 
subsurfaceTheme.smallPointSize
+                                                       }
+                                               }
+                                       }
+                               }
+                               Item {
+                                       width: parent.width
+                                       Layout.fillHeight: true
+                               }
+                       }
+               }
+       }
+
+// TODO use Qt models instead so we can interact directly with core planner 
code
+       ListModel {
+               id: gasModel
+
+               ListElement {
+                       cylinderType: "D12.2 232 bar"
+                       cylinderSizeMl: 24400
+                       gasName: "air"
+                       gasDepthMm: 66000
+                       o2Pm: 210
+                       hePm: 0
+               }
+       }
+       ListModel {
+               id: inputPointsModel
+               ListElement {
+                       property double depth: 15000
+                       property int runtime: 1200
+                       property int gasIndex: 0
+               }
+       }
+
+// Dummy model for the time being
+       ListModel {
+               id: decoStopsModel
+               ListElement {
+                       property double depth: 15000
+                       property int runtime: 3000
+                       property int gasIndex: 0
+               }
+       }
+       Component {
+               id: cylinderListDelegate
+               MobileComponents.ListItemWithActions {
+                       enabled: true
+                       width: parent.width
+
+                       Item {
+                               width: parent.width - 
MobileComponents.Units.gridUnit
+                               height: labelRowHeight - 
MobileComponents.Units.smallSpacing * 2
+
+                               Row {
+                                       anchors {
+                                               left: parent.left
+                                               leftMargin: horizontalPadding
+                                               right: parent.right
+                                               rightMargin: horizontalPadding
+                                       }
+                                       MobileComponents.Label {
+                                               text: cylinderType
+                                               width: stdColWidth * 1.5
+                                               font.pointSize: 
subsurfaceTheme.smallPointSize
+                                       }
+                                       MobileComponents.Label {
+                                               text: 'Gas: '
+                                               width: stdColWidth * 0.4
+                                               Layout.alignment: Qt.AlignRight
+                                               opacity: 0.6
+                                               font.pointSize: 
subsurfaceTheme.smallPointSize
+                                       }
+                                       MobileComponents.Label {
+                                               text: gasName
+                                               width: stdColWidth * 0.8
+                                               font.pointSize: 
subsurfaceTheme.smallPointSize
+                                       }
+                                       MobileComponents.Label {
+                                               text: 'Switch at: '
+                                               width: stdColWidth
+                                               Layout.alignment: Qt.AlignRight
+                                               opacity: 0.6
+                                               font.pointSize: 
subsurfaceTheme.smallPointSize
+                                       }
+                                       MobileComponents.Label {
+                                               text: 0.001 * gasDepthMm + "m"
+                                               font.pointSize: 
subsurfaceTheme.smallPointSize
+                                       }
+                               }
+                       }
+                       function cylinderEdit() {
+                               cylinderIndex = model.index
+                               newCylinder = false
+                               cylinderDetailsWindow.isPlanner = true
+                               cylinderDetailsWindow.cylinderDescriptionText = 
gasModel.get(cylinderIndex).cylinderType
+                               cylinderDetailsWindow.cylinderSizeText = 0.001 
* gasModel.get(cylinderIndex).cylinderSizeMl
+                               cylinderDetailsWindow.pcO2Text = 0.1 * 
gasModel.get(cylinderIndex).o2Pm
+                               cylinderDetailsWindow.pcHeText = 0.1 * 
gasModel.get(cylinderIndex).hePm
+                               
cylinderDetailsWindow.setGas(gasModel.get(cylinderIndex).cylinderType)
+                               stackView.push(cylinderDetailsWindow)
+                       }
+
+                       onClicked: {
+                               cylinderEdit()
+                       }
+                       actions: [
+                               Action {
+                                       iconName: "trash-empty"
+                                       onTriggered: {
+                                               gasModel.remove(model.index)
+                                       }
+                               },
+                               Action {
+                                       iconName: "document-edit"
+                                       onTriggered: {
+                                               cylinderEdit()
+                                       }
+                               }
+
+                       ]
+               }
+       }
+
+// TODO: we shouldn't permit negative durations - either sort model by runtime 
(in c++) or have data validation
+       Component {
+               id: waypointsDelegate
+               MobileComponents.ListItemWithActions {
+                       enabled: true
+                       width: parent.width
+
+                       Item {
+                               width: parent.width - 
MobileComponents.Units.gridUnit
+                               height: inputRowHeight - 
MobileComponents.Units.smallSpacing * 2
+
+                               Row {
+                                       anchors {
+                                               left: parent.left
+                                               leftMargin: horizontalPadding
+                                               right: parent.right
+                                               rightMargin: horizontalPadding
+                                       }
+                                       TextField {
+                                               id: txtDepth
+                                               inputMethodHints: 
Qt.ImhDigitsOnly
+                                               validator: DoubleValidator 
{bottom: 0; top: 200; decimals:0; notation: DoubleValidator.StandardNotation}
+                                               horizontalAlignment: 
TextInput.AlignHCenter
+                                               width: stdColWidth
+                                               font.pointSize: 
subsurfaceTheme.smallPointSize
+                                               onEditingFinished: {
+                                                       
inputPointsModel.set(model.index, {depth: 1000 * Number(text)})
+                                                       if (model.index == 
inputPointsModel.count - 1)
+                                                               
inputPointsModel.append({})
+                                               }
+                                       }
+                                       MobileComponents.Label {
+                                               id: txtDuration
+                                               text: {
+                                                       if 
(inputPointsModel.get(model.index).runtime > 0) {
+                                                               if (model.index 
== 0)
+                                                                       return 
inputPointsModel.get(model.index).runtime / 60
+                                                               else if 
(inputPointsModel.get(model.index - 1).runtime > 0)
+                                                                       return 
(inputPointsModel.get(model.index).runtime
+                                                                               
- inputPointsModel.get(model.index - 1).runtime) / 60
+                                                       } else {
+                                                       return undefined
+                                                       }
+                                               }
+                                               horizontalAlignment: 
Text.AlignHCenter
+                                               width: stdColWidth
+                                               font.pointSize: 
subsurfaceTheme.smallPointSize
+                                       }
+                                       TextField {
+                                               id: txtRuntime
+                                               inputMethodHints: 
Qt.ImhDigitsOnly
+                                               validator: DoubleValidator 
{bottom: 0; top: 200; decimals:0; notation: DoubleValidator.StandardNotation}
+                                               horizontalAlignment: 
TextInput.AlignHCenter
+                                               width: stdColWidth
+                                               font.pointSize: 
subsurfaceTheme.smallPointSize
+                                               onEditingFinished: {
+                                                       
inputPointsModel.set(model.index, {runtime: 60 * Number(text)})
+                                                       if (model.index == 
inputPointsModel.count - 1)
+                                                               
inputPointsModel.append({})
+                                               }
+                                       }
+                                       MobileComponents.Label {
+                                               text: "Gas"
+                                               font.pointSize: 
subsurfaceTheme.smallPointSize
+                                       }
+                               }
+                       }
+                       actions: [
+                               Action {
+                                       iconName: "trash-empty"
+                                       onTriggered: {
+                                               print("delete waypoint")
+                                               
inputPointsModel.remove(model.index)
+                                       }
+                               }
+                       ]
+               }
+       }
+       Component {
+               id: decoStopsDelegate
+               MobileComponents.ListItem {
+                       enabled: true
+                       width: parent.width
+
+                       Item {
+                               width: parent.width - 
MobileComponents.Units.gridUnit
+                               height: labelRowHeight - 
MobileComponents.Units.smallSpacing * 2
+
+                               Row {
+                                       anchors {
+                                               left: parent.left
+                                               leftMargin: horizontalPadding
+                                               right: parent.right
+                                               rightMargin: horizontalPadding
+                                       }
+                                       MobileComponents.Label {
+                                               id: txtDecoDepth
+                                               text: depth * 0.001
+                                               horizontalAlignment: 
TextInput.AlignHCenter
+                                               width: stdColWidth
+                                               font.pointSize: 
subsurfaceTheme.smallPointSize
+                                       }
+                                       MobileComponents.Label {
+                                               id: txtDuration
+                                               horizontalAlignment: 
Text.AlignHCenter
+                                               width: stdColWidth
+                                               font.pointSize: 
subsurfaceTheme.smallPointSize
+                                       }
+                                       MobileComponents.Label {
+                                               id: txtDecoRuntime
+                                               text: runtime / 60
+                                               horizontalAlignment: 
TextInput.AlignHCenter
+                                               width: stdColWidth
+                                               font.pointSize: 
subsurfaceTheme.smallPointSize
+                                       }
+                                       MobileComponents.Label {
+                                               text: 
gasModel.get(gasIndex).gasName
+                                               font.pointSize: 
subsurfaceTheme.smallPointSize
+                                       }
+                               }
+                       }
+               }
+       }
+       Action {
+               id: addCylinder
+               onTriggered: {
+                       newCylinder = true
+                       cylinderDetailsWindow.isPlanner = true
+                       stackView.push(cylinderDetailsWindow)
+               }
+       }
+       CylinderDetailsEdit {
+               id: cylinderDetailsWindow
+               visible: false
+               onCylinderOk: {
+                       if (newCylinder) {
+                               gasModel.append({
+                                       cylinderType: 
cylinderDetailsWindow.cylinderDescriptionText,
+                                       o2Pm: cylinderDetailsWindow.o2Pm,
+                                       hePm: cylinderDetailsWindow.hePm,
+                                       gasName: 
cylinderDetailsWindow.gasNameText,
+                                       gasDepthMm: 
Number(cylinderDetailsWindow.gasDepthMm)
+                               })
+                       } else {
+                               gasModel.set(cylinderIndex, {
+                                       cylinderType: 
cylinderDetailsWindow.cylinderDescriptionText,
+                                       o2Pm: cylinderDetailsWindow.o2Pm,
+                                       hePm: cylinderDetailsWindow.hePm,
+                                       gasName: 
cylinderDetailsWindow.gasNameText,
+                                       gasDepthMm: 
Number(cylinderDetailsWindow.gasDepthMm)
+                               })
+                       }
+               }
+       }
+}
diff --git a/qt-mobile/qml/mobile-resources.qrc 
b/qt-mobile/qml/mobile-resources.qrc
index 77ec4ff..eb8fdc5 100644
--- a/qt-mobile/qml/mobile-resources.qrc
+++ b/qt-mobile/qml/mobile-resources.qrc
@@ -9,6 +9,7 @@
                <file>DiveDetailsEdit.qml</file>
                <file>DiveDetailsView.qml</file>
                <file>DownloadFromDiveComputer.qml</file>
+               <file>Planner.qml</file>
                <file>CylinderDetailsEdit.qml</file>
                <file>GpsList.qml</file>
                <file>Log.qml</file>
-- 
2.5.0

_______________________________________________
subsurface mailing list
[email protected]
http://lists.subsurface-divelog.org/cgi-bin/mailman/listinfo/subsurface

Reply via email to