Mercurial > ~darius > hgwebdir.cgi > OverviewJD
comparison main.qml.orig @ 0:57ffb39f29d4
First commit of new carousel page to allow battery charging current to
be adjusted.
author | Daniel O'Connor <darius@dons.net.au> |
---|---|
date | Mon, 13 Dec 2021 23:05:38 +1030 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:57ffb39f29d4 |
---|---|
1 import QtQuick 1.1 | |
2 | |
3 import Qt.labs.components.native 1.0 | |
4 import com.victron.velib 1.0 | |
5 import "utils.js" as Utils | |
6 | |
7 PageStackWindow { | |
8 id: rootWindow | |
9 | |
10 gpsConnected: gpsFix.value === 1 | |
11 onCompletedChanged: checkAlarm() | |
12 initialPage: PageMain {} | |
13 | |
14 property VeQuickItem gpsService: VeQuickItem { uid: "dbus/com.victronenergy.system/GpsService" } | |
15 property VeQuickItem gpsFix: VeQuickItem { uid: Utils.path("dbus/", gpsService.value, "/Fix") } | |
16 property bool completed: false | |
17 property bool showAlert: NotificationCenter.alert | |
18 property bool alarm: NotificationCenter.alarm | |
19 property bool overviewsLoaded: defaultOverview.valid && generatorOverview.valid && mobileOverview.valid && tanksOverview.valid && startWithMenu.valid | |
20 property string bindPrefix: "com.victronenergy.settings" | |
21 | |
22 property bool isNotificationPage: pageStack.currentPage && pageStack.currentPage.title === qsTr("Notifications") | |
23 property bool isOverviewPage: pageStack.currentPage && pageStack.currentPage.model === overviewModel; | |
24 property bool isOfflineFwUpdatePage: pageStack.currentPage && pageStack.currentPage.objectName === "offlineFwUpdatePage"; | |
25 | |
26 | |
27 property string hubOverviewType: theSystem.systemType.valid ? | |
28 withoutGridMeter.value === 1 ? "Hub" : theSystem.systemType.value : "" | |
29 | |
30 // Keep track of the current view (menu/overview) to show as default next time the | |
31 // CCGX is restarted | |
32 onIsOverviewPageChanged: startWithMenu.setValue(isOverviewPage ? 0 : 1) | |
33 | |
34 // Add the correct OverviewHub page | |
35 onHubOverviewTypeChanged: { | |
36 switch(hubOverviewType){ | |
37 case "Hub": | |
38 case "Hub-1": | |
39 case "Hub-2": | |
40 case "Hub-3": | |
41 replaceOverview("OverviewGridParallel.qml", "OverviewHub.qml"); | |
42 break; | |
43 case "Hub-4": | |
44 case "ESS": | |
45 replaceOverview("OverviewHub.qml", "OverviewGridParallel.qml"); | |
46 break; | |
47 default: | |
48 break; | |
49 } | |
50 // Workaround the QTBUG-17012 (only the first sentence in each case of Switch Statement can be executed) | |
51 // by adding a return statement | |
52 return | |
53 } | |
54 | |
55 VBusItem { | |
56 id: generatorOverview | |
57 bind: "com.victronenergy.settings/Settings/Relay/Function" | |
58 onValueChanged: extraOverview("OverviewGeneratorRelay.qml", value === 1) | |
59 } | |
60 | |
61 VBusItem { | |
62 id: fischerPandaGenOverview | |
63 bind: "com.victronenergy.settings/Settings/Services/FischerPandaAutoStartStop" | |
64 onValueChanged: extraOverview("OverviewGeneratorFp.qml", value === 1) | |
65 } | |
66 | |
67 VBusItem { | |
68 id: mobileOverview | |
69 bind: "com.victronenergy.settings/Settings/Gui/MobileOverview" | |
70 onValueChanged:{ | |
71 extraOverview("OverviewMobile.qml", value === 1) | |
72 } | |
73 } | |
74 VBusItem { | |
75 id: tanksOverview | |
76 bind: "com.victronenergy.settings/Settings/Gui/TanksOverview" | |
77 onValueChanged:{ | |
78 extraOverview("OverviewTanks.qml", value === 1) | |
79 } | |
80 } | |
81 | |
82 VBusItem { | |
83 id: startWithMenu | |
84 bind: "com.victronenergy.settings/Settings/Gui/StartWithMenuView" | |
85 } | |
86 | |
87 VBusItem { | |
88 id: withoutGridMeter | |
89 bind: "com.victronenergy.settings/Settings/CGwacs/RunWithoutGridMeter" | |
90 } | |
91 | |
92 | |
93 VBusItem { | |
94 id: defaultOverview | |
95 bind: "com.victronenergy.settings/Settings/Gui/DefaultOverview" | |
96 } | |
97 | |
98 // Note: finding a firmware image on the storage device is error 4 for vrm storage | |
99 // since it should not be used for logging. That fact is used here to determine if | |
100 // there is a firmware image. | |
101 Connections { | |
102 target: storageEvents | |
103 onVrmStorageError: { | |
104 if (error === 4) { | |
105 setTopPage(offlineFwUpdates) | |
106 } | |
107 } | |
108 } | |
109 | |
110 onAlarmChanged: { | |
111 if (completed) | |
112 checkAlarm() | |
113 } | |
114 | |
115 // always keep track of system information | |
116 HubData { | |
117 id: theSystem | |
118 } | |
119 | |
120 // note: used for leaving the overviews as well | |
121 function backToMainMenu() | |
122 { | |
123 pageStack.pop(initialPage); | |
124 } | |
125 | |
126 Toast { | |
127 id: toast | |
128 transform: Scale { | |
129 xScale: screen.scaleX | |
130 yScale: screen.scaleY | |
131 origin.x: toast.width / 2 | |
132 origin.y: toast.height / 2 | |
133 } | |
134 } | |
135 | |
136 SignalToaster {} | |
137 | |
138 ToolbarHandlerPages { | |
139 id: mainToolbarHandler | |
140 isDefault: true | |
141 } | |
142 | |
143 ToolBarLayout { | |
144 id: mbTools | |
145 height: parent.height | |
146 | |
147 Item { | |
148 anchors.verticalCenter: parent.verticalCenter | |
149 anchors.left: mbTools.left | |
150 height: mbTools.height | |
151 width: 200 | |
152 | |
153 MouseArea { | |
154 anchors.fill: parent | |
155 onClicked: { | |
156 if (pageStack.currentPage) | |
157 pageStack.currentPage.toolbarHandler.leftAction(true) | |
158 } | |
159 } | |
160 | |
161 Row { | |
162 anchors.centerIn: parent | |
163 | |
164 MbIcon { | |
165 anchors.verticalCenter: parent.verticalCenter | |
166 iconId: pageStack.currentPage ? pageStack.currentPage.leftIcon : "" | |
167 } | |
168 | |
169 Text { | |
170 anchors.verticalCenter: parent.verticalCenter | |
171 text: pageStack.currentPage ? pageStack.currentPage.leftText : "" | |
172 color: "white" | |
173 font.bold: true | |
174 font.pixelSize: 16 | |
175 } | |
176 } | |
177 } | |
178 | |
179 MbIcon { | |
180 id: centerScrollIndicator | |
181 | |
182 anchors { | |
183 horizontalCenter: parent.horizontalCenter | |
184 verticalCenter: mbTools.verticalCenter | |
185 } | |
186 iconId: pageStack.currentPage ? pageStack.currentPage.scrollIndicator : "" | |
187 } | |
188 | |
189 Item { | |
190 anchors.verticalCenter: parent.verticalCenter | |
191 height: mbTools.height | |
192 anchors.right: mbTools.right | |
193 width: 200 | |
194 | |
195 MouseArea { | |
196 anchors.fill: parent | |
197 onClicked: { | |
198 if (pageStack.currentPage) | |
199 pageStack.currentPage.toolbarHandler.rightAction(true) | |
200 } | |
201 } | |
202 | |
203 Row { | |
204 anchors.centerIn: parent | |
205 | |
206 MbIcon { | |
207 iconId: pageStack.currentPage ? pageStack.currentPage.rightIcon : "" | |
208 anchors.verticalCenter: parent.verticalCenter | |
209 } | |
210 | |
211 Text { | |
212 text: pageStack.currentPage ? pageStack.currentPage.rightText : "" | |
213 anchors.verticalCenter: parent.verticalCenter | |
214 color: "white" | |
215 font.bold: true | |
216 font.pixelSize: 16 | |
217 } | |
218 } | |
219 } | |
220 } | |
221 | |
222 Component.onCompleted: { | |
223 completed = true | |
224 } | |
225 | |
226 ListModel { | |
227 id: overviewModel | |
228 ListElement { | |
229 pageSource: "OverviewHub.qml" | |
230 } | |
231 ListElement { | |
232 pageSource: "OverviewTiles.qml" | |
233 } | |
234 } | |
235 | |
236 Component { | |
237 id: overviewComponent | |
238 PageFlow { | |
239 // Display default overview when loaded | |
240 defaultIndex: getDefaultOverviewIndex() | |
241 // Store the current overview page as default | |
242 onCurrentIndexChanged: if (active) defaultOverview.setValue(overviewModel.get(currentIndex).pageSource.replace(".qml", "")) | |
243 model: overviewModel | |
244 } | |
245 } | |
246 | |
247 // When all the related settings items are valid, show the overview page if was the last oppened page | |
248 // before restarting | |
249 Timer { | |
250 interval: 2000 | |
251 running: completed && overviewsLoaded && startWithMenu.valid | |
252 onTriggered: if (startWithMenu.value === 0) showOverview() | |
253 } | |
254 | |
255 function getDefaultOverviewIndex() | |
256 { | |
257 if(!defaultOverview.valid) | |
258 return 0 | |
259 for (var i = 0; i < overviewModel.count; i++){ | |
260 if (overviewModel.get(i).pageSource.replace(".qml", "") === defaultOverview.value) { | |
261 return i | |
262 } | |
263 } | |
264 return 0 | |
265 } | |
266 | |
267 Component { | |
268 id: noticationsComponent | |
269 PageNotifications {} | |
270 } | |
271 | |
272 Component { | |
273 id: offlineFwUpdates | |
274 PageSettingsFirmwareOffline { checkOnCompleted: true} | |
275 | |
276 } | |
277 | |
278 // Add or remove extra overviews. for example, generator overview | |
279 // shouldn't be shown if the start/stop functionality is not enabled. | |
280 // Index parameter is optional, usefull to keep an order. | |
281 function extraOverview(name, show, index) | |
282 { | |
283 var i = 0 | |
284 if (show) { | |
285 if (index !== undefined) { | |
286 if (overviewModel.get(index).pageSource === name) | |
287 return | |
288 // First append the page | |
289 overviewModel.append({"pageSource": name}) | |
290 // Then move all the pages behind index | |
291 overviewModel.move(index, overviewModel.count - 2, overviewModel.count - 2) | |
292 } else { | |
293 for (i = 0; i < overviewModel.count; i++) | |
294 if (overviewModel.get(i).pageSource === name) | |
295 // Don't append if already exists | |
296 return | |
297 overviewModel.append({"pageSource": name}) | |
298 } | |
299 } else { | |
300 for (i = 0; i < overviewModel.count; i++) | |
301 if (overviewModel.get(i).pageSource === name) | |
302 overviewModel.remove(i) | |
303 } | |
304 } | |
305 | |
306 function replaceOverview(oldPage, newPage) | |
307 { | |
308 for (var i = 0; i < overviewModel.count; i++) | |
309 if (overviewModel.get(i).pageSource === oldPage) | |
310 overviewModel.get(i).pageSource = newPage | |
311 } | |
312 | |
313 // Central mover for the ball animation on the overviews | |
314 // Instead of using a timer per line, using a central one | |
315 // reduces the CPU usage a little bit and makes the animations | |
316 // smoother. | |
317 Timer { | |
318 id: mover | |
319 property double pos: _counter / _loops | |
320 property int _counter | |
321 property int _loops: 13 | |
322 | |
323 interval: 100 | |
324 running: true | |
325 repeat: true | |
326 onTriggered: if (_counter >= (_loops - 1)) _counter = 0; else _counter++ | |
327 } | |
328 | |
329 // If an overview or notifications is active, the new page will replace it | |
330 // instead to be pushed. This way we prevent an unwanted stackpage depth | |
331 // increment everytime another page wants to be on top. | |
332 function setTopPage(page) | |
333 { | |
334 if (isNotificationPage || isOverviewPage || isOfflineFwUpdatePage) | |
335 rootWindow.pageStack.replace(page); | |
336 else | |
337 rootWindow.pageStack.push(page); | |
338 } | |
339 | |
340 function spuriousKeyPress() | |
341 { | |
342 return !pageStack.currentPage || !pageStack.currentPage.active | |
343 } | |
344 | |
345 function showOverview() | |
346 { | |
347 if (spuriousKeyPress() || isOverviewPage) | |
348 return | |
349 setTopPage(overviewComponent) | |
350 } | |
351 | |
352 function showPageNotifications() | |
353 { | |
354 if (spuriousKeyPress() || isNotificationPage) | |
355 return | |
356 setTopPage(noticationsComponent) | |
357 } | |
358 | |
359 function checkAlarm() | |
360 { | |
361 if (alarm) | |
362 showPageNotifications() | |
363 } | |
364 } |