Browse Source

BrewPlot 1.0 release

Neal Wilson 7 years ago
commit
5b790d98f4

+ 36
- 0
BrewPlot.pro View File

@@ -0,0 +1,36 @@
1
+# Add more folders to ship with the application, here
2
+folder_01.source = qml/BrewPlot
3
+folder_01.target = qml
4
+DEPLOYMENTFOLDERS = folder_01
5
+
6
+# Additional import path used to resolve QML modules in Creator's code model
7
+QML_IMPORT_PATH =
8
+
9
+symbian:TARGET.UID3 = 0xE41BFE6C
10
+
11
+# Allow network access on Symbian
12
+symbian:TARGET.CAPABILITY += NetworkServices
13
+
14
+# Define QMLJSDEBUGGER to allow debugging of QML in debug builds
15
+# (This might significantly increase build time)
16
+# DEFINES += QMLJSDEBUGGER
17
+
18
+# If your application uses the Qt Mobility libraries, uncomment
19
+# the following lines and add the respective components to the 
20
+# MOBILITY variable. 
21
+# CONFIG += mobility
22
+# MOBILITY +=
23
+
24
+# The .cpp file which was generated for your project. Feel free to hack it.
25
+SOURCES += main.cpp \
26
+    qmllineitem.cpp
27
+
28
+# Please do not modify the following two lines. Required for deployment.
29
+include(qmlapplicationviewer/qmlapplicationviewer.pri)
30
+qtcAddDeployment()
31
+
32
+HEADERS += \
33
+    qmllineitem.h
34
+
35
+RESOURCES += \
36
+    qmlfiles.qrc

+ 59
- 0
main.cpp View File

@@ -0,0 +1,59 @@
1
+#include <QtGui>
2
+#include <QtDeclarative>
3
+#include "qmlapplicationviewer.h"
4
+#include "qmllineitem.h"
5
+
6
+class QmlWindow : public QMainWindow
7
+{
8
+    Q_OBJECT
9
+public:
10
+    QmlWindow(QWidget *parent = NULL);
11
+    Q_INVOKABLE QAction *addMenuItem(QString menu, QString item);
12
+private:
13
+    QHash<QString,QMenu *> menus;
14
+};
15
+
16
+QmlWindow::QmlWindow(QWidget *parent) : QMainWindow(parent)
17
+{
18
+
19
+}
20
+
21
+QAction *QmlWindow::addMenuItem(QString menu, QString item)
22
+{
23
+    QMenu *theMenu;
24
+    if(menus.contains(menu))
25
+    {
26
+        theMenu = menus.value(menu);
27
+    }
28
+    else
29
+    {
30
+        theMenu = menuBar()->addMenu(menu);
31
+        menus.insert(menu, theMenu);
32
+    }
33
+    return theMenu->addAction(item);
34
+}
35
+
36
+QML_DECLARE_TYPE(QmlWindow)
37
+
38
+int main(int argc, char *argv[])
39
+{
40
+    QApplication app(argc, argv);
41
+
42
+    qmlRegisterType<QmlLineItem>("CustomComponents", 1, 0, "Line");
43
+    qmlRegisterType<QmlWindow>("CustomComponents", 1, 0, "Window");
44
+
45
+    QmlWindow *window = new QmlWindow(NULL);
46
+    window->setWindowTitle("BrewPlot");
47
+    QmlApplicationViewer *viewer = new QmlApplicationViewer;
48
+    viewer->setOrientation(QmlApplicationViewer::ScreenOrientationAuto);
49
+    viewer->rootContext()->setContextProperty("window", window);
50
+    viewer->setSource(QUrl("qrc:/qml/qml/BrewPlot/main.qml"));
51
+    app.connect(viewer->engine(), SIGNAL(quit()), SLOT(quit()));
52
+    window->setCentralWidget(viewer);
53
+    viewer->setMinimumSize(viewer->sizeHint());
54
+    window->show();
55
+
56
+    return app.exec();
57
+}
58
+
59
+#include "moc_main.cpp"

+ 272
- 0
qml/BrewPlot/BrewingControlChart.qml View File

@@ -0,0 +1,272 @@
1
+import CustomComponents 1.0
2
+import QtQuick 1.0
3
+
4
+Item {
5
+	id: chartOuter
6
+
7
+	function plotPoint(px, py, pcolor) {
8
+		chart.plotPoint(px, py, pcolor);
9
+	}
10
+	function setFit(x1, y1, x2, y2) {
11
+		chart.setFit(x1, y1, x2, y2)
12
+	}
13
+	function setFitVisible(visible) {
14
+		fitline.visible = visible
15
+	}
16
+	function setFitColor(color) {
17
+		fitline.color = color
18
+	}
19
+	function clear() {
20
+		points.clear();
21
+	}
22
+
23
+	Item {
24
+		id: chart
25
+		height: parent.height
26
+		width: parent.width
27
+
28
+		function plotPoint(px, py, pcolor) {
29
+			points.append({"px": px, "py": py, "pcolor": pcolor});
30
+		}
31
+		function mapToX(px) {
32
+			return (chart.width / xrange) * (px - xmin)
33
+		}
34
+		function mapToY(py) {
35
+			return chart.height - ((chart.height / yrange) * (py - ymin))
36
+		}
37
+		function setFit(x1, y1, x2, y2) {
38
+			fitline.x1 = mapToX(x1);
39
+			fitline.x2 = mapToX(x2);
40
+			fitline.y1 = mapToY(y1);
41
+			fitline.y2 = mapToY(y2);
42
+		}
43
+		Line {
44
+			id: fitline
45
+
46
+			x1: 0
47
+			x2: 0
48
+			y1: 0
49
+			y2: 0
50
+			color: "red"
51
+			visible: false
52
+		}
53
+		ListModel {
54
+			id: xGridLines
55
+		}
56
+		ListModel {
57
+			id: yGridLines
58
+		}
59
+		ListModel {
60
+			id: points
61
+		}
62
+
63
+		Repeater {
64
+			model: xGridLines
65
+
66
+			Line {
67
+				x1: (chart.width / xrange) * (value - xmin)
68
+				x2: x1
69
+				y1: 0
70
+				y2: chart.height
71
+				penWidth: pwidth
72
+				color: "black"
73
+			}
74
+		}
75
+		Repeater {
76
+			model: yGridLines
77
+
78
+			Line {
79
+				x1: 0
80
+				x2: chart.width
81
+				y1: chart.height - ((chart.height / yrange) * (value - ymin))
82
+				y2: y1
83
+				penWidth: pwidth
84
+				color: "black"
85
+			}
86
+		}
87
+		Repeater {
88
+			model: points
89
+
90
+			Item {
91
+				Rectangle {
92
+					x: ((chart.width / xrange) * (px - xmin)) - (width / 2)
93
+					y: chart.height - ((chart.height / yrange) * (py - ymin)) - (height / 2)
94
+					width: 5
95
+					height: 5
96
+					color: pcolor
97
+					smooth: true
98
+				}
99
+			}
100
+		}
101
+	}
102
+	
103
+	property real xmin: 0.14
104
+	property real xmax: 0.26
105
+	property real ymin: 0.008
106
+	property real ymax: 0.016
107
+	property real xrange: xmax - xmin
108
+	property real yrange: ymax - ymin
109
+	
110
+	Item {
111
+		id: yLabels
112
+
113
+        anchors.right: chart.left
114
+        anchors.rightMargin: 10
115
+        y: chart.y
116
+        Text {
117
+            text: "0.8%"
118
+            y: chart.mapToY(0.008) - (height/2)
119
+            x: -width
120
+        }
121
+        Text {
122
+            text: "0.9%"
123
+            y: chart.mapToY(0.009) - (height/2)
124
+            x: -width
125
+        }
126
+        Text {
127
+            text: "1.0%"
128
+            y: chart.mapToY(0.01) - (height/2)
129
+            x: -width
130
+        }
131
+        Text {
132
+            text: "1.1%"
133
+            y: chart.mapToY(0.011) - (height/2)
134
+            x: -width
135
+        }
136
+        Text {
137
+            text: "1.2%"
138
+            y: chart.mapToY(0.012) - (height/2)
139
+            x: -width
140
+        }
141
+        Text {
142
+            text: "1.3%"
143
+            y: chart.mapToY(0.013) - (height/2)
144
+            x: -width
145
+        }
146
+        Text {
147
+            text: "1.4%"
148
+            y: chart.mapToY(0.014) - (height/2)
149
+            x: -width
150
+        }
151
+        Text {
152
+            text: "1.5%"
153
+            y: chart.mapToY(0.015) - (height/2)
154
+            x: -width
155
+        }
156
+        Text {
157
+            text: "1.6%"
158
+            y: chart.mapToY(0.016) - (height/2)
159
+            x: -width
160
+        }
161
+    }
162
+    Item {
163
+        id: xLabels
164
+
165
+        x: chart.x
166
+        anchors.top: chart.bottom
167
+        anchors.topMargin: 10
168
+        Text {
169
+            text: "14%"
170
+            x: chart.mapToX(0.14) - (width/2)
171
+        }
172
+        Text {
173
+            text: "15%"
174
+            x: chart.mapToX(0.15) - (width/2)
175
+        }
176
+        Text {
177
+            text: "16%"
178
+            x: chart.mapToX(0.16) - (width/2)
179
+        }
180
+        Text {
181
+            text: "17%"
182
+            x: chart.mapToX(0.17) - (width/2)
183
+        }
184
+        Text {
185
+            text: "18%"
186
+            x: chart.mapToX(0.18) - (width/2)
187
+        }
188
+        Text {
189
+            text: "19%"
190
+            x: chart.mapToX(0.19) - (width/2)
191
+        }
192
+        Text {
193
+            text: "20%"
194
+            x: chart.mapToX(0.2) - (width/2)
195
+        }
196
+        Text {
197
+            text: "21%"
198
+            x: chart.mapToX(0.21) - (width/2)
199
+        }
200
+        Text {
201
+            text: "22%"
202
+            x: chart.mapToX(0.22) - (width/2)
203
+        }
204
+        Text {
205
+            text: "23%"
206
+            x: chart.mapToX(0.23) - (width/2)
207
+        }
208
+        Text {
209
+            text: "24%"
210
+            x: chart.mapToX(0.24) - (width/2)
211
+        }
212
+        Text {
213
+            text: "25%"
214
+            x: chart.mapToX(0.25) - (width/2)
215
+        }
216
+        Text {
217
+            text: "26%"
218
+            x: chart.mapToX(0.26) - (width/2)
219
+        }
220
+    }
221
+    Text {
222
+        text: "EXTRACTION - Solubles Yield"
223
+        x: chart.x + (chart.width/2) - (width/2)
224
+        anchors.top: xLabels.bottom
225
+        anchors.topMargin: 20
226
+    }
227
+    Item {
228
+        anchors.right: yLabels.left
229
+        anchors.rightMargin: 40
230
+        y: chart.y + (chart.height/2) - (strengthLabel.height/2)
231
+        Text {
232
+            id: strengthLabel
233
+
234
+            text: "STRENGTH - Solubles Concentration (%TDS)"
235
+            rotation: -90
236
+            x: -(width/2)
237
+        }
238
+    }
239
+	Component.onCompleted: {
240
+		xGridLines.append({"value": 0.14, "pwidth": 1})
241
+		xGridLines.append({"value": 0.15, "pwidth": 1})
242
+		xGridLines.append({"value": 0.16, "pwidth": 1})
243
+		xGridLines.append({"value": 0.17, "pwidth": 1})
244
+		xGridLines.append({"value": 0.18, "pwidth": 2})
245
+		xGridLines.append({"value": 0.19, "pwidth": 1})
246
+		xGridLines.append({"value": 0.20, "pwidth": 1})
247
+		xGridLines.append({"value": 0.21, "pwidth": 1})
248
+		xGridLines.append({"value": 0.22, "pwidth": 2})
249
+		xGridLines.append({"value": 0.23, "pwidth": 1})
250
+		xGridLines.append({"value": 0.24, "pwidth": 1})
251
+		xGridLines.append({"value": 0.25, "pwidth": 1})
252
+		xGridLines.append({"value": 0.26, "pwidth": 1})
253
+		
254
+		yGridLines.append({"value": 0.008, "pwidth": 1})
255
+		yGridLines.append({"value": 0.0085, "pwidth": 1})
256
+		yGridLines.append({"value": 0.009, "pwidth": 1})
257
+		yGridLines.append({"value": 0.0095, "pwidth": 1})
258
+		yGridLines.append({"value": 0.01, "pwidth": 1})
259
+		yGridLines.append({"value": 0.0105, "pwidth": 1})
260
+		yGridLines.append({"value": 0.011, "pwidth": 1})
261
+		yGridLines.append({"value": 0.0115, "pwidth": 2})
262
+		yGridLines.append({"value": 0.012, "pwidth": 1})
263
+		yGridLines.append({"value": 0.0125, "pwidth": 1})
264
+		yGridLines.append({"value": 0.013, "pwidth": 1})
265
+		yGridLines.append({"value": 0.0135, "pwidth": 2})
266
+		yGridLines.append({"value": 0.014, "pwidth": 1})
267
+		yGridLines.append({"value": 0.0145, "pwidth": 1})
268
+		yGridLines.append({"value": 0.015, "pwidth": 1})
269
+		yGridLines.append({"value": 0.0155, "pwidth": 1})
270
+		yGridLines.append({"value": 0.016, "pwidth": 1})
271
+	}
272
+}

+ 74
- 0
qml/BrewPlot/ColorPicker.qml View File

@@ -0,0 +1,74 @@
1
+import QtQuick 1.0
2
+
3
+Rectangle {
4
+	id: colorpicker
5
+	
6
+	color: "red"
7
+	Rectangle {
8
+		id: pickControl
9
+		
10
+		x: 40
11
+		y: 0
12
+		z: 10
13
+		width: 260
14
+		height: 50
15
+		color: "white"
16
+		border.color: "black"
17
+		border.width: 3
18
+		radius: 5
19
+		opacity: 0
20
+		
21
+		Behavior on opacity {
22
+			PropertyAnimation {
23
+				duration: 250
24
+			}
25
+		}
26
+		Repeater {
27
+			model: ListModel {
28
+			
29
+				ListElement {
30
+					theColor: "red"
31
+				}
32
+				ListElement {
33
+					theColor: "orange"
34
+				}
35
+				ListElement {
36
+					theColor: "yellow"
37
+				}
38
+				ListElement {
39
+					theColor: "green"
40
+				}
41
+				ListElement {
42
+					theColor: "blue"
43
+				}
44
+				ListElement {
45
+					theColor: "indigo"
46
+				}
47
+				ListElement {
48
+					theColor: "violet"
49
+				}
50
+			}
51
+			Rectangle {
52
+				width: 30
53
+				height: 30
54
+				x: (35*index)+10
55
+				y: 10
56
+				color: theColor
57
+				opacity: 1
58
+				MouseArea {
59
+					anchors.fill: parent
60
+					onClicked: {
61
+						pickControl.opacity = 0
62
+						colorpicker.color = parent.color
63
+					}
64
+				}
65
+			}
66
+		}
67
+	}
68
+	MouseArea {
69
+		anchors.fill: parent
70
+		onClicked: {
71
+			pickControl.opacity = 1
72
+		}
73
+	}
74
+}

+ 238
- 0
qml/BrewPlot/main.qml View File

@@ -0,0 +1,238 @@
1
+import CustomComponents 1.0
2
+import QtQuick 1.0
3
+
4
+Rectangle {
5
+    id: root
6
+
7
+    property real sumy : 0
8
+    property real sumxsq : 0
9
+    property real sumx : 0
10
+    property real sumxy : 0
11
+    property int n : 0
12
+
13
+    width: 720
14
+    height: 680
15
+    Component.onCompleted: {
16
+        var quitItem = window.addMenuItem("File", "Quit");
17
+        quitItem.shortcut = "Ctrl+Q";
18
+        quitItem.triggered.connect(function() {
19
+                                       Qt.quit();
20
+                                   });
21
+        var clearItem = window.addMenuItem("Plotting", "Clear Data");
22
+        clearItem.triggered.connect(function() {
23
+                                        graph.clear();
24
+                                        dataViewModel.clear();
25
+                                        root.sumy = 0;
26
+                                        root.sumxsq = 0;
27
+                                        root.sumx = 0;
28
+                                        root.sumxy = 0;
29
+                                        root.n = 0;
30
+                                        graph.setFit(0, 0, 0, 0);
31
+                                    });
32
+        var showLeastSquares = window.addMenuItem("Plotting", "Least Squares Fit");
33
+        showLeastSquares.checkable = true;
34
+        showLeastSquares.triggered.connect(function() {
35
+                                               graph.setFitVisible(showLeastSquares.checked);
36
+                                               lsfrow.visible = showLeastSquares.checked;
37
+                                           });
38
+    }
39
+    BrewingControlChart {
40
+        id: graph
41
+
42
+        width: 450
43
+        height: 600
44
+        anchors.right: parent.right
45
+        anchors.rightMargin: 20
46
+        anchors.top: parent.top
47
+        anchors.topMargin: 20
48
+    }
49
+    Item {
50
+        anchors.left: parent.left
51
+        anchors.leftMargin: 10
52
+        anchors.top: parent.top
53
+        anchors.topMargin: 10
54
+        Column {
55
+            spacing: 8
56
+            Row {
57
+                spacing: 5
58
+                Text {
59
+                    text: "Mass of ground coffee: "
60
+                }
61
+                TextInput {
62
+                    id: groundMass
63
+
64
+                    width: 30
65
+                    validator: DoubleValidator {
66
+                        bottom: 0
67
+                        decimals: 2
68
+                        notation: DoubleValidator.StandardNotation
69
+                    }
70
+
71
+                    Line {
72
+                        x1: -3
73
+                        x2: 33
74
+                        y1: groundMass.height
75
+                        y2: y1
76
+                        penWidth: 1
77
+                        color: "black"
78
+                    }
79
+                }
80
+            }
81
+            Row {
82
+                spacing: 5
83
+                Text {
84
+                    text: "Mass of brewed coffee:"
85
+                }
86
+                TextInput {
87
+                    id: brewedMass
88
+
89
+                    width: 30
90
+                    validator: DoubleValidator {
91
+                        bottom: 0
92
+                        decimals: 2
93
+                        notation: DoubleValidator.StandardNotation
94
+                    }
95
+
96
+                    Line {
97
+                        x1: -3
98
+                        x2: 33
99
+                        y1: brewedMass.height
100
+                        y2: y1
101
+                        penWidth: 1
102
+                        color: "black"
103
+                    }
104
+                }
105
+            }
106
+            Row {
107
+                spacing: 56
108
+                Text {
109
+                    text: "Percent TDS:"
110
+                }
111
+                TextInput {
112
+                    id: ptds
113
+                    width: 30
114
+                    validator: DoubleValidator {
115
+                        bottom: 0
116
+                        top: 100
117
+                        decimals: 2
118
+                        notation: DoubleValidator.StandardNotation
119
+                    }
120
+                    Line {
121
+                        x1: -3
122
+                        x2: 33
123
+                        y1: ptds.height
124
+                        y2: y1
125
+                        penWidth: 1
126
+                        color: "black"
127
+                    }
128
+                }
129
+            }
130
+            Row {
131
+                spacing: 87
132
+                Text {
133
+                    id: colorlabel
134
+                    text: "Color:"
135
+                }
136
+                ColorPicker {
137
+                    id: colorpicker
138
+                    width: 37
139
+                    height: colorlabel.height
140
+                }
141
+            }
142
+            Row {
143
+                id: lsfrow
144
+                visible: false
145
+
146
+                spacing: 1
147
+                Text {
148
+                    id: fitcolorlabel
149
+                    text: "Least Squares Fit Color:"
150
+                }
151
+                ColorPicker {
152
+                    id: fitcolorpicker
153
+                    width: 37
154
+                    height: colorlabel.height
155
+                    onColorChanged: {
156
+                        graph.setFitColor(color)
157
+                    }
158
+                }
159
+            }
160
+            Rectangle {
161
+                z: 0
162
+                anchors.horizontalCenter: parent.horizontalCenter
163
+                height: buttonText.height + 20
164
+                width: buttonText.width + 40
165
+                border.color: "black"
166
+                radius: 10
167
+                Text {
168
+                    id: buttonText
169
+
170
+                    text: "Plot This Brew"
171
+                    anchors.horizontalCenter: parent.horizontalCenter
172
+                    anchors.verticalCenter: parent.verticalCenter
173
+                }
174
+                MouseArea {
175
+                    anchors.fill: parent
176
+                    onClicked: {
177
+                        var extraction = (brewedMass.text * (ptds.text / 100)) / groundMass.text
178
+                        graph.plotPoint(extraction, (ptds.text / 100), colorpicker.color)
179
+                        dataViewModel.append({"color": colorpicker.color, "ptds": ptds.text, "extraction": extraction})
180
+                        root.n += 1
181
+                        root.sumy += (ptds.text / 100)
182
+                        root.sumx += extraction
183
+                        root.sumxy += ((ptds.text / 100) * extraction)
184
+                        root.sumxsq += Math.pow(extraction, 2)
185
+                        if(root.n > 1) {
186
+                            var a = ((root.sumy * root.sumxsq)-(root.sumx * root.sumxy))/((root.n * root.sumxsq)-Math.pow(root.sumx, 2))
187
+                            var b = ((root.n * root.sumxy)-(root.sumx * root.sumy))/((root.n * root.sumxsq) - Math.pow(root.sumx, 2))
188
+                            var x1 = 0.14
189
+                            var x2 = 0.26
190
+                            var y1 = a + (b * x1)
191
+                            var y2 = a + (b * x2)
192
+                            if(y1 < 0.008) {
193
+                                x1 = (0.008 - a) / b
194
+                                y1 = 0.008
195
+                            }
196
+                            if(y2 < 0.008) {
197
+                                x2 = (0.008 - a) / b
198
+                                y2 = 0.008
199
+                            }
200
+                            if(y1 > 0.016) {
201
+                                x1 = (0.016 - a) / b
202
+                                y1 = 0.016
203
+                            }
204
+                            if(y2 > 0.016) {
205
+                                x2 = (0.016 - a) / b
206
+                                y2 = 0.016
207
+                            }
208
+                            graph.setFit(x1, y1, x2, y2);
209
+                        }
210
+                    }
211
+                }
212
+            }
213
+            Repeater {
214
+                id: dataView
215
+
216
+                model: ListModel {
217
+                    id: dataViewModel
218
+                }
219
+                delegate: Row {
220
+                    spacing: 3
221
+                    Rectangle {
222
+                        width: 30
223
+                        height: 30
224
+                        color: dataViewModel.get(index).color
225
+                    }
226
+                    Column {
227
+                        Text {
228
+                            text: "Strength: "+dataViewModel.get(index).ptds+"% TDS"
229
+                        }
230
+                        Text {
231
+                            text: "Extraction: "+Number(dataViewModel.get(index).extraction*100).toFixed(2)+"%"
232
+                        }
233
+                    }
234
+                }
235
+            }
236
+        }
237
+    }
238
+}

+ 174
- 0
qmlapplicationviewer/qmlapplicationviewer.cpp View File

@@ -0,0 +1,174 @@
1
+// checksum 0x3fbf version 0x70013
2
+/*
3
+  This file was generated by the Qt Quick Application wizard of Qt Creator.
4
+  QmlApplicationViewer is a convenience class containing mobile device specific
5
+  code such as screen orientation handling. Also QML paths and debugging are
6
+  handled here.
7
+  It is recommended not to modify this file, since newer versions of Qt Creator
8
+  may offer an updated version of it.
9
+*/
10
+
11
+#include "qmlapplicationviewer.h"
12
+
13
+#include <QDir>
14
+#include <QFileInfo>
15
+#include <QApplication>
16
+#include <QDeclarativeComponent>
17
+#include <QDeclarativeEngine>
18
+#include <QDeclarativeContext>
19
+
20
+#include <qplatformdefs.h> // MEEGO_EDITION_HARMATTAN
21
+
22
+#ifdef HARMATTAN_BOOSTER
23
+#include <MDeclarativeCache>
24
+#endif
25
+
26
+#if defined(QMLJSDEBUGGER) && QT_VERSION < 0x040800
27
+
28
+#include <qt_private/qdeclarativedebughelper_p.h>
29
+
30
+#if !defined(NO_JSDEBUGGER)
31
+#include <jsdebuggeragent.h>
32
+#endif
33
+#if !defined(NO_QMLOBSERVER)
34
+#include <qdeclarativeviewobserver.h>
35
+#endif
36
+
37
+// Enable debugging before any QDeclarativeEngine is created
38
+struct QmlJsDebuggingEnabler
39
+{
40
+    QmlJsDebuggingEnabler()
41
+    {
42
+        QDeclarativeDebugHelper::enableDebugging();
43
+    }
44
+};
45
+
46
+// Execute code in constructor before first QDeclarativeEngine is instantiated
47
+static QmlJsDebuggingEnabler enableDebuggingHelper;
48
+
49
+#endif // QMLJSDEBUGGER
50
+
51
+class QmlApplicationViewerPrivate
52
+{
53
+    QString mainQmlFile;
54
+    friend class QmlApplicationViewer;
55
+    static QString adjustPath(const QString &path);
56
+};
57
+
58
+QString QmlApplicationViewerPrivate::adjustPath(const QString &path)
59
+{
60
+#ifdef Q_OS_UNIX
61
+#ifdef Q_OS_MAC
62
+    if (!QDir::isAbsolutePath(path))
63
+        return QString::fromLatin1("%1/../Resources/%2")
64
+                .arg(QCoreApplication::applicationDirPath(), path);
65
+#else
66
+    const QString pathInInstallDir =
67
+            QString::fromLatin1("%1/../%2").arg(QCoreApplication::applicationDirPath(), path);
68
+    if (QFileInfo(pathInInstallDir).exists())
69
+        return pathInInstallDir;
70
+#endif
71
+#endif
72
+    return path;
73
+}
74
+
75
+QmlApplicationViewer::QmlApplicationViewer(QWidget *parent)
76
+    : QDeclarativeView(parent)
77
+    , d(new QmlApplicationViewerPrivate())
78
+{
79
+    connect(engine(), SIGNAL(quit()), SLOT(close()));
80
+    setResizeMode(QDeclarativeView::SizeRootObjectToView);
81
+    // Qt versions prior to 4.8.0 don't have QML/JS debugging services built in
82
+#if defined(QMLJSDEBUGGER) && QT_VERSION < 0x040800
83
+#if !defined(NO_JSDEBUGGER)
84
+    new QmlJSDebugger::JSDebuggerAgent(engine());
85
+#endif
86
+#if !defined(NO_QMLOBSERVER)
87
+    new QmlJSDebugger::QDeclarativeViewObserver(this, this);
88
+#endif
89
+#endif
90
+}
91
+
92
+QmlApplicationViewer::~QmlApplicationViewer()
93
+{
94
+    delete d;
95
+}
96
+
97
+QmlApplicationViewer *QmlApplicationViewer::create()
98
+{
99
+    return new QmlApplicationViewer();
100
+}
101
+
102
+void QmlApplicationViewer::setMainQmlFile(const QString &file)
103
+{
104
+    d->mainQmlFile = QmlApplicationViewerPrivate::adjustPath(file);
105
+    setSource(QUrl::fromLocalFile(d->mainQmlFile));
106
+}
107
+
108
+void QmlApplicationViewer::addImportPath(const QString &path)
109
+{
110
+    engine()->addImportPath(QmlApplicationViewerPrivate::adjustPath(path));
111
+}
112
+
113
+void QmlApplicationViewer::setOrientation(ScreenOrientation orientation)
114
+{
115
+#if defined(Q_OS_SYMBIAN)
116
+    // If the version of Qt on the device is < 4.7.2, that attribute won't work
117
+    if (orientation != ScreenOrientationAuto) {
118
+        const QStringList v = QString::fromLatin1(qVersion()).split(QLatin1Char('.'));
119
+        if (v.count() == 3 && (v.at(0).toInt() << 16 | v.at(1).toInt() << 8 | v.at(2).toInt()) < 0x040702) {
120
+            qWarning("Screen orientation locking only supported with Qt 4.7.2 and above");
121
+            return;
122
+        }
123
+    }
124
+#endif // Q_OS_SYMBIAN
125
+
126
+    Qt::WidgetAttribute attribute;
127
+    switch (orientation) {
128
+#if QT_VERSION < 0x040702
129
+    // Qt < 4.7.2 does not yet have the Qt::WA_*Orientation attributes
130
+    case ScreenOrientationLockPortrait:
131
+        attribute = static_cast<Qt::WidgetAttribute>(128);
132
+        break;
133
+    case ScreenOrientationLockLandscape:
134
+        attribute = static_cast<Qt::WidgetAttribute>(129);
135
+        break;
136
+    default:
137
+    case ScreenOrientationAuto:
138
+        attribute = static_cast<Qt::WidgetAttribute>(130);
139
+        break;
140
+#else // QT_VERSION < 0x040702
141
+    case ScreenOrientationLockPortrait:
142
+        attribute = Qt::WA_LockPortraitOrientation;
143
+        break;
144
+    case ScreenOrientationLockLandscape:
145
+        attribute = Qt::WA_LockLandscapeOrientation;
146
+        break;
147
+    default:
148
+    case ScreenOrientationAuto:
149
+        attribute = Qt::WA_AutoOrientation;
150
+        break;
151
+#endif // QT_VERSION < 0x040702
152
+    };
153
+    setAttribute(attribute, true);
154
+}
155
+
156
+void QmlApplicationViewer::showExpanded()
157
+{
158
+#if defined(Q_OS_SYMBIAN) || defined(MEEGO_EDITION_HARMATTAN) || defined(Q_WS_SIMULATOR)
159
+    showFullScreen();
160
+#elif defined(Q_WS_MAEMO_5)
161
+    showMaximized();
162
+#else
163
+    show();
164
+#endif
165
+}
166
+
167
+QApplication *createApplication(int &argc, char **argv)
168
+{
169
+#ifdef HARMATTAN_BOOSTER
170
+    return MDeclarativeCache::qApplication(argc, argv);
171
+#else
172
+    return new QApplication(argc, argv);
173
+#endif
174
+}

+ 46
- 0
qmlapplicationviewer/qmlapplicationviewer.h View File

@@ -0,0 +1,46 @@
1
+// checksum 0x734b version 0x70013
2
+/*
3
+  This file was generated by the Qt Quick Application wizard of Qt Creator.
4
+  QmlApplicationViewer is a convenience class containing mobile device specific
5
+  code such as screen orientation handling. Also QML paths and debugging are
6
+  handled here.
7
+  It is recommended not to modify this file, since newer versions of Qt Creator
8
+  may offer an updated version of it.
9
+*/
10
+
11
+#ifndef QMLAPPLICATIONVIEWER_H
12
+#define QMLAPPLICATIONVIEWER_H
13
+
14
+#include <QDeclarativeView>
15
+
16
+class QmlApplicationViewer : public QDeclarativeView
17
+{
18
+    Q_OBJECT
19
+
20
+public:
21
+    enum ScreenOrientation {
22
+        ScreenOrientationLockPortrait,
23
+        ScreenOrientationLockLandscape,
24
+        ScreenOrientationAuto
25
+    };
26
+
27
+    explicit QmlApplicationViewer(QWidget *parent = 0);
28
+    virtual ~QmlApplicationViewer();
29
+
30
+    static QmlApplicationViewer *create();
31
+
32
+    void setMainQmlFile(const QString &file);
33
+    void addImportPath(const QString &path);
34
+
35
+    // Note that this will only have an effect on Symbian and Fremantle.
36
+    void setOrientation(ScreenOrientation orientation);
37
+
38
+    void showExpanded();
39
+
40
+private:
41
+    class QmlApplicationViewerPrivate *d;
42
+};
43
+
44
+QApplication *createApplication(int &argc, char **argv);
45
+
46
+#endif // QMLAPPLICATIONVIEWER_H

+ 148
- 0
qmlapplicationviewer/qmlapplicationviewer.pri View File

@@ -0,0 +1,148 @@
1
+# checksum 0x5b42 version 0x70013
2
+# This file was generated by the Qt Quick Application wizard of Qt Creator.
3
+# The code below adds the QmlApplicationViewer to the project and handles the
4
+# activation of QML debugging.
5
+# It is recommended not to modify this file, since newer versions of Qt Creator
6
+# may offer an updated version of it.
7
+
8
+QT += declarative
9
+
10
+SOURCES += $$PWD/qmlapplicationviewer.cpp
11
+HEADERS += $$PWD/qmlapplicationviewer.h
12
+INCLUDEPATH += $$PWD
13
+
14
+# Include JS debugger library if QMLJSDEBUGGER_PATH is set
15
+!isEmpty(QMLJSDEBUGGER_PATH) {
16
+    include($$QMLJSDEBUGGER_PATH/qmljsdebugger-lib.pri)
17
+} else {
18
+    DEFINES -= QMLJSDEBUGGER
19
+}
20
+
21
+contains(CONFIG,qdeclarative-boostable):contains(MEEGO_EDITION,harmattan) {
22
+    DEFINES += HARMATTAN_BOOSTER
23
+}
24
+# This file was generated by an application wizard of Qt Creator.
25
+# The code below handles deployment to Symbian and Maemo, aswell as copying
26
+# of the application data to shadow build directories on desktop.
27
+# It is recommended not to modify this file, since newer versions of Qt Creator
28
+# may offer an updated version of it.
29
+
30
+defineTest(qtcAddDeployment) {
31
+for(deploymentfolder, DEPLOYMENTFOLDERS) {
32
+    item = item$${deploymentfolder}
33
+    itemsources = $${item}.sources
34
+    $$itemsources = $$eval($${deploymentfolder}.source)
35
+    itempath = $${item}.path
36
+    $$itempath= $$eval($${deploymentfolder}.target)
37
+    export($$itemsources)
38
+    export($$itempath)
39
+    DEPLOYMENT += $$item
40
+}
41
+
42
+MAINPROFILEPWD = $$PWD
43
+
44
+symbian {
45
+    isEmpty(ICON):exists($${TARGET}.svg):ICON = $${TARGET}.svg
46
+    isEmpty(TARGET.EPOCHEAPSIZE):TARGET.EPOCHEAPSIZE = 0x20000 0x2000000
47
+} else:win32 {
48
+    copyCommand =
49
+    for(deploymentfolder, DEPLOYMENTFOLDERS) {
50
+        source = $$MAINPROFILEPWD/$$eval($${deploymentfolder}.source)
51
+        source = $$replace(source, /, \\)
52
+        sourcePathSegments = $$split(source, \\)
53
+        target = $$OUT_PWD/$$eval($${deploymentfolder}.target)/$$last(sourcePathSegments)
54
+        target = $$replace(target, /, \\)
55
+        target ~= s,\\\\\\.?\\\\,\\,
56
+        !isEqual(source,$$target) {
57
+            !isEmpty(copyCommand):copyCommand += &&
58
+            isEqual(QMAKE_DIR_SEP, \\) {
59
+                copyCommand += $(COPY_DIR) \"$$source\" \"$$target\"
60
+            } else {
61
+                source = $$replace(source, \\\\, /)
62
+                target = $$OUT_PWD/$$eval($${deploymentfolder}.target)
63
+                target = $$replace(target, \\\\, /)
64
+                copyCommand += test -d \"$$target\" || mkdir -p \"$$target\" && cp -r \"$$source\" \"$$target\"
65
+            }
66
+        }
67
+    }
68
+    !isEmpty(copyCommand) {
69
+        copyCommand = @echo Copying application data... && $$copyCommand
70
+        copydeploymentfolders.commands = $$copyCommand
71
+        first.depends = $(first) copydeploymentfolders
72
+        export(first.depends)
73
+        export(copydeploymentfolders.commands)
74
+        QMAKE_EXTRA_TARGETS += first copydeploymentfolders
75
+    }
76
+} else:unix {
77
+    maemo5 {
78
+        desktopfile.files = $${TARGET}.desktop
79
+        desktopfile.path = /usr/share/applications/hildon
80
+        icon.files = $${TARGET}64.png
81
+        icon.path = /usr/share/icons/hicolor/64x64/apps
82
+    } else:!isEmpty(MEEGO_VERSION_MAJOR) {
83
+        desktopfile.files = $${TARGET}_harmattan.desktop
84
+        desktopfile.path = /usr/share/applications
85
+        icon.files = $${TARGET}80.png
86
+        icon.path = /usr/share/icons/hicolor/80x80/apps
87
+    } else { # Assumed to be a Desktop Unix
88
+        copyCommand =
89
+        for(deploymentfolder, DEPLOYMENTFOLDERS) {
90
+            source = $$MAINPROFILEPWD/$$eval($${deploymentfolder}.source)
91
+            source = $$replace(source, \\\\, /)
92
+            macx {
93
+                target = $$OUT_PWD/$${TARGET}.app/Contents/Resources/$$eval($${deploymentfolder}.target)
94
+            } else {
95
+                target = $$OUT_PWD/$$eval($${deploymentfolder}.target)
96
+            }
97
+            target = $$replace(target, \\\\, /)
98
+            sourcePathSegments = $$split(source, /)
99
+            targetFullPath = $$target/$$last(sourcePathSegments)
100
+            targetFullPath ~= s,/\\.?/,/,
101
+            !isEqual(source,$$targetFullPath) {
102
+                !isEmpty(copyCommand):copyCommand += &&
103
+                copyCommand += $(MKDIR) \"$$target\"
104
+                copyCommand += && $(COPY_DIR) \"$$source\" \"$$target\"
105
+            }
106
+        }
107
+        !isEmpty(copyCommand) {
108
+            copyCommand = @echo Copying application data... && $$copyCommand
109
+            copydeploymentfolders.commands = $$copyCommand
110
+            first.depends = $(first) copydeploymentfolders
111
+            export(first.depends)
112
+            export(copydeploymentfolders.commands)
113
+            QMAKE_EXTRA_TARGETS += first copydeploymentfolders
114
+        }
115
+    }
116
+    installPrefix = /opt/$${TARGET}
117
+    for(deploymentfolder, DEPLOYMENTFOLDERS) {
118
+        item = item$${deploymentfolder}
119
+        itemfiles = $${item}.files
120
+        $$itemfiles = $$eval($${deploymentfolder}.source)
121
+        itempath = $${item}.path
122
+        $$itempath = $${installPrefix}/$$eval($${deploymentfolder}.target)
123
+        export($$itemfiles)
124
+        export($$itempath)
125
+        INSTALLS += $$item
126
+    }
127
+
128
+    !isEmpty(desktopfile.path) {
129
+        export(icon.files)
130
+        export(icon.path)
131
+        export(desktopfile.files)
132
+        export(desktopfile.path)
133
+        INSTALLS += icon desktopfile
134
+    }
135
+
136
+    target.path = $${installPrefix}/bin
137
+    export(target.path)
138
+    INSTALLS += target
139
+}
140
+
141
+export (ICON)
142
+export (INSTALLS)
143
+export (DEPLOYMENT)
144
+export (TARGET.EPOCHEAPSIZE)
145
+export (TARGET.CAPABILITY)
146
+export (LIBS)
147
+export (QMAKE_EXTRA_TARGETS)
148
+}

+ 7
- 0
qmlfiles.qrc View File

@@ -0,0 +1,7 @@
1
+<RCC>
2
+    <qresource prefix="/qml">
3
+        <file>qml/BrewPlot/BrewingControlChart.qml</file>
4
+        <file>qml/BrewPlot/ColorPicker.qml</file>
5
+        <file>qml/BrewPlot/main.qml</file>
6
+    </qresource>
7
+</RCC>

+ 133
- 0
qmllineitem.cpp View File

@@ -0,0 +1,133 @@
1
+#include "qmllineitem.h"
2
+
3
+QmlLineItem::QmlLineItem(QDeclarativeItem *parent) :
4
+    QDeclarativeItem(parent), m_x1(0), m_y1(0), m_x2(0), m_y2(0),
5
+    m_color(Qt::black), m_penWidth(1)
6
+{
7
+    setFlag(QGraphicsItem::ItemHasNoContents, false);
8
+}
9
+
10
+void QmlLineItem::paint(QPainter *painter,
11
+                        const QStyleOptionGraphicsItem *option,
12
+                        QWidget *widget)
13
+{
14
+    QPen pen(m_color, m_penWidth);
15
+    painter->setPen(pen);
16
+    if(smooth() == true)
17
+    {
18
+        painter->setRenderHint(QPainter::Antialiasing, true);
19
+    }
20
+    int x = qMin(m_x1, m_x2) - m_penWidth/2;
21
+    int y = qMin(m_y1, m_y2) - m_penWidth/2;
22
+    painter->drawLine(m_x1 - x, m_y1 - y, m_x2 - x, m_y2 - y);
23
+}
24
+
25
+int QmlLineItem::x1() const
26
+{
27
+    return m_x1;
28
+}
29
+
30
+int QmlLineItem::y1() const
31
+{
32
+    return m_y1;
33
+}
34
+
35
+int QmlLineItem::x2() const
36
+{
37
+    return m_x2;
38
+}
39
+
40
+int QmlLineItem::y2() const
41
+{
42
+    return m_y2;
43
+}
44
+
45
+QColor QmlLineItem::color() const
46
+{
47
+    return m_color;
48
+}
49
+
50
+int QmlLineItem::penWidth() const
51
+{
52
+    return m_penWidth;
53
+}
54
+
55
+
56
+void QmlLineItem::setX1(int x1)
57
+{
58
+    if(m_x1 == x1)
59
+    {
60
+        return;
61
+    }
62
+    m_x1 = x1;
63
+    updateSize();
64
+    emit x1Changed();
65
+    update();
66
+}
67
+
68
+void QmlLineItem::setY1(int y1)
69
+{
70
+    if(m_y1 == y1)
71
+    {
72
+        return;
73
+    }
74
+    m_y1 = y1;
75
+    updateSize();
76
+    emit y1Changed();
77
+    update();
78
+}
79
+
80
+void QmlLineItem::setX2(int x2)
81
+{
82
+    if(m_x2 == x2)
83
+    {
84
+        return;
85
+    }
86
+    m_x2 = x2;
87
+    updateSize();
88
+    emit x2Changed();
89
+    update();
90
+}
91
+
92
+void QmlLineItem::setY2(int y2)
93
+{
94
+    if(m_y2 == y2)
95
+    {
96
+        return;
97
+    }
98
+    m_y2 = y2;
99
+    updateSize();
100
+    emit y2Changed();
101
+    update();
102
+}
103
+
104
+void QmlLineItem::setColor(const QColor &color)
105
+{
106
+    if(m_color == color)
107
+    {
108
+        return;
109
+    }
110
+    m_color = color;
111
+    emit colorChanged();
112
+    update();
113
+}
114
+
115
+void QmlLineItem::setPenWidth(int newWidth)
116
+{
117
+    if(m_penWidth == newWidth)
118
+    {
119
+        return;
120
+    }
121
+    m_penWidth = newWidth;
122
+    updateSize();
123
+    emit penWidthChanged();
124
+    update();
125
+}
126
+
127
+void QmlLineItem::updateSize()
128
+{
129
+    setX(qMin(m_x1, m_x2) - m_penWidth/2);
130
+    setY(qMin(m_y1, m_y2) - m_penWidth/2);
131
+    setWidth(qAbs(m_x2 - m_x1) + m_penWidth);
132
+    setHeight(qAbs(m_y2 - m_y1) + m_penWidth);
133
+}

+ 53
- 0
qmllineitem.h View File

@@ -0,0 +1,53 @@
1
+#ifndef QMLLINEITEM_H
2
+#define QMLLINEITEM_H
3
+
4
+#include <QDeclarativeItem>
5
+#include <QPainter>
6
+
7
+class QmlLineItem : public QDeclarativeItem
8
+{
9
+    Q_OBJECT
10
+    Q_PROPERTY(int x1 READ x1 WRITE setX1 NOTIFY x1Changed);
11
+    Q_PROPERTY(int y1 READ y1 WRITE setY1 NOTIFY y1Changed);
12
+    Q_PROPERTY(int x2 READ x2 WRITE setX2 NOTIFY x2Changed);
13
+    Q_PROPERTY(int y2 READ y2 WRITE setY2 NOTIFY y2Changed);
14
+    Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged);
15
+    Q_PROPERTY(int penWidth READ penWidth WRITE setPenWidth NOTIFY penWidthChanged);
16
+public:
17
+    QmlLineItem(QDeclarativeItem *parent = NULL);
18
+    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
19
+               QWidget *widget);
20
+    int x1() const;
21
+    int y1() const;
22
+    int x2() const;
23
+    int y2() const;
24
+    QColor color() const;
25
+    int penWidth() const;
26
+    void setX1(int x1);
27
+    void setY1(int y1);
28
+    void setX2(int x2);
29
+    void setY2(int y2);
30
+    void setColor(const QColor &color);
31
+    void setPenWidth(int newWidth);
32
+
33
+signals:
34
+    void x1Changed();
35
+    void y1Changed();
36
+    void x2Changed();
37
+    void y2Changed();
38
+    void colorChanged();
39
+    void penWidthChanged();
40
+
41
+private:
42
+    void updateSize();
43
+    int m_x1;
44
+    int m_y1;
45
+    int m_x2;
46
+    int m_y2;
47
+    QColor m_color;
48
+    int m_penWidth;
49
+};
50
+
51
+QML_DECLARE_TYPE(QmlLineItem)
52
+
53
+#endif

Loading…
Cancel
Save