forked from victronenergy/gui-v2
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMain.qml
More file actions
189 lines (160 loc) · 5.55 KB
/
Main.qml
File metadata and controls
189 lines (160 loc) · 5.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
/*
** Copyright (C) 2023 Victron Energy B.V.
** See LICENSE.txt for license information.
*/
import QtQuick
import QtQuick.Window
// *** This file cannot be edited directly on the cerbo filesystem. It is loaded from the binary ***
Window {
id: root
//: Application title
//% "Venus OS GUI"
//~ Context only shown on desktop systems
title: qsTrId("venus_os_gui")
color: Global.allPagesLoaded && !!guiLoader.item ? guiLoader.item.mainView.backgroundColor : Theme.color_page_background
width: Qt.platform.os != "wasm" ? Theme.geometry_screen_width/scaleFactor : Screen.width/scaleFactor
height: Qt.platform.os != "wasm" ? Theme.geometry_screen_height/scaleFactor : Screen.height/scaleFactor
// Automatically decide if rotation is required (portrait -> landscape)
readonly property bool requiresRotation: Global.isGxDevice && root.height > root.width
property bool isDesktop: false
property real scaleFactor: 1.0
onIsDesktopChanged: Global.isDesktop = root.isDesktop
// Uncomment for key navigation debugging
// onActiveFocusItemChanged: console.info("** Active focused:", activeFocusItem, activeFocusItem?.title ?? activeFocusItem?.text ?? "")
function skipSplashScreen() {
Global.splashScreenVisible = false
}
function rebuildUi() {
console.info("Main: UI rebuild required")
if (Global.mainView) {
Global.mainView.clearUi()
}
const demoModeChange = dataManagerLoader.active && dataManagerLoader.connectionReady
if (demoModeChange) {
// we haven't lost backend connection.
// we must be rebuilding UI due to demo mode change.
// manually cycle the data manager loader.
console.info("Main: resetting data manager due to demo mode change")
dataManagerLoader.active = false
}
Global.reset()
if (demoModeChange) {
dataManagerLoader.active = true
}
gc()
console.info("Main: UI rebuild started successfully")
}
function ensureApplicationActive() {
Global.applicationActive = true
appIdleTimer.restart()
}
function keyNavigationTimeout() {
// Disable key nav when app is inactive; user can re-enable it later by pressing a
// navigation key. Do not disable key nav when a dialog is shown, because the user
// cannot re-enable it within a modal dialog, as ModalDialog focus is only enabled when
// keyNavigationEnabled=true.
if (!Global.dialogLayer?.currentDialog) {
Global.keyNavigationEnabled = false
}
}
Component.onCompleted: Global.main = root
Loader {
id: dataManagerLoader
readonly property bool connectionReady: Global.backendReady
onConnectionReadyChanged: {
if (connectionReady) {
active = true
} else if (active && !Global.needPageReload) {
root.rebuildUi()
active = false
}
}
asynchronous: true
active: false
sourceComponent: Component {
DataManager { }
}
}
contentItem {
// show the GUI always centered in the window
transformOrigin: Item.Center
// Apply rotation
transform: Rotation {
origin.x: root.width / 2
origin.y: root.height / 2
angle: root.requiresRotation ? 90 : 0
}
// Adjust scale depending on the rotation
readonly property real rotatedScale: root.requiresRotation
? Math.min(root.width / Theme.geometry_screen_height, root.height / Theme.geometry_screen_width)
: Math.min(root.width / Theme.geometry_screen_width, root.height / Theme.geometry_screen_height)
scale: rotatedScale
// Center only if rotated
x: root.requiresRotation ? (root.width - Theme.geometry_screen_height * contentItem.scale) / 2 : 0
y: root.requiresRotation ? (root.height - Theme.geometry_screen_width * contentItem.scale) / 2 : 0
// In WebAssembly builds, if we are displaying on a low-dpi mobile
// device, it may not have enough pixels to display the UI natively.
// To fix, we need to downscale everything by the appropriate factor,
// and take into account browser chrome stealing real-estate also.
onScaleChanged: Global.scalingRatio = contentItem.scale
Keys.onPressed: function(event) {
// If a key press is not handled by an item higher up in the hierarchy:
// Enable key navigation when an arrow or tab/backtab key is pressed.
if (!Global.keyNavigationEnabled) {
switch (event.key) {
case Qt.Key_Left:
case Qt.Key_Right:
case Qt.Key_Up:
case Qt.Key_Down:
case Qt.Key_Tab:
case Qt.Key_Backtab:
case Qt.Key_Space:
Global.keyNavigationEnabled = true
event.accepted = true
return
}
}
event.accepted = false
}
}
Loader {
id: guiLoader
// Receive key events if key navigation is enabled.
focus: Global.keyNavigationEnabled
// Do not receive focus while a dialog is open, as the key events will cause the
// focus item to change in the main UI.
&& !Global.dialogLayer?.currentDialog
clip: Qt.platform.os == "wasm" || Global.isDesktop
width: Theme.geometry_screen_width
height: Theme.geometry_screen_height
anchors.centerIn: parent
asynchronous: true
active: Global.dataManagerLoaded
onActiveChanged: if (active) console.info("Main: data manager finished loading; now loading application content")
sourceComponent: ApplicationContent {
anchors.centerIn: parent
focus: true
}
}
Loader {
id: splashLoader
clip: Qt.platform.os == "wasm"
width: Theme.geometry_screen_width
height: Theme.geometry_screen_height
anchors.centerIn: parent
active: Global.splashScreenVisible
sourceComponent: SplashView {
anchors.centerIn: parent
}
}
Timer {
id: appIdleTimer
running: !Global.splashScreenVisible && Global.timersEnabled
interval: 60000
onTriggered: {
Global.applicationActive = false
root.keyNavigationTimeout()
}
}
FrameRateVisualizer {}
}