Lomiri
Loading...
Searching...
No Matches
IndicatorsLight.qml
1/*
2 * Copyright 2014 Canonical Ltd.
3 * Copyright 2019 UBports Foundation
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public License as published by
7 * the Free Software Foundation; version 3.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authors:
18 * Renato Araujo Oliveira Filho <renato@canonical.com>
19 */
20
21import QtQuick 2.12
22import Powerd 0.1
23import Hfd 0.1
24import QMenuModel 1.0 as QMenuModel
25import Lomiri.Indicators 0.1 as Indicators
26import Wizard 0.1
27
28import "../../.."
29
30Item {
31 id: root
32
33 property bool supportsMultiColorLed: true
34
35 property string indicatorState: "INDICATOR_OFF"
36
37 property color color: "darkgreen"
38 property int onMillisec: 1000
39 property int offMillisec: 3000
40
41 property double batteryLevel: 0
42 property string deviceState: ""
43 property alias hasMessages: _rootState.hasMessages
44
45 property string batteryIconName: Status.batteryIcon
46 property string displayStatus: Powerd.status
47
48 onSupportsMultiColorLedChanged: {
49 updateLightState("onSupportsMultiColorLedChanged")
50 }
51
52 onDisplayStatusChanged: {
53 updateLightState("onDisplayStatusChanged")
54 }
55
56 onBatteryIconNameChanged: {
57 updateLightState("onBatteryIconNameChanged")
58 }
59
60 function updateLightState(msg) {
61 console.log("updateLightState: " + msg
62 + ", indicatorState: " + indicatorState
63 + ", supportsMultiColorLed: " + supportsMultiColorLed
64 + ", hasMessages: " + hasMessages
65 + ", icon: " + batteryIconName
66 + ", displayStatus: " + displayStatus
67 + ", deviceState: " + deviceState
68 + ", batteryLevel: " + batteryLevel)
69
70 //
71 // priorities:
72 // unread messsages (highest), full&charging, charging, low
73 //
74 // Icons: (see device.s from indicator-power)
75 // %s-empty-symbolic empty
76 // %s-caution-charging-symbolic charging [ 0..10)
77 // %s-low-charging-symbolic charging [10..30)
78 // %s-good-charging-symbolic charging [30..60)
79 // %s-full-charging-symbolic charging [60..100]
80 // %s-full-charged-symbolic fully charged
81 // %s-low-symbolic ?
82 // %s-full-symbolic ?
83 //
84 // device-state: (see system-settings\plugins\battery)
85 // fully-charged
86 // charging
87 // discharging
88 //
89 // Indicators:
90 // unread notifications : darkgreen pulsing (1000/3000)
91 // charging : white continuously
92 // battery full : green continuously
93 // battery low : orangered pulsing (500/3000)
94 //
95 // Notes:
96 // Icon name 'full-charged' comes late (45m after 100%)
97 // so also check device-state and battery-level
98 //
99 // Battery low warning dialog on screen shows up at 10%
100 // but 'caution' icon at 9%.
101 //
102
103 // only show led when display is off
104 if (displayStatus == Powerd.On) {
105 indicatorState = "INDICATOR_OFF"
106 return
107 }
108
109 // unread messsages have highest priority
110 if (hasMessages) {
111 indicatorState = "HAS_MESSAGES"
112 return
113 }
114
115 // if device does not support a multi color led set led off
116 if(!supportsMultiColorLed) {
117console.log("no support for Multicolor LED. " + indicatorState)
118 indicatorState = "INDICATOR_OFF"
119 return
120 }
121
122 var isCharging = batteryIconName.indexOf("charging") >= 0
123 || deviceState == "charging"
124 || deviceState == "fully-charged"
125
126 var isFull = batteryIconName.indexOf("full-charged") >= 0
127 || deviceState == "fully-charged"
128 || batteryLevel >= 100
129
130 if (isCharging && isFull) {
131 indicatorState = "BATTERY_FULL"
132 } else if (isCharging) {
133 indicatorState = "BATTERY_CHARGING"
134 } else if (batteryIconName.indexOf("caution") >= 0
135 || batteryIconName.indexOf("empty") >= 0) {
136 indicatorState = "BATTERY_LOW"
137 } else {
138 indicatorState = "INDICATOR_OFF"
139 }
140 }
141
142 onIndicatorStateChanged: {
143 console.log("onIndicatorStateChange: " + indicatorState)
144
145 switch (indicatorState) {
146 case "INDICATOR_OFF":
147 break;
148 case "HAS_MESSAGES":
149 color = "darkgreen"
150 onMillisec = 1000
151 offMillisec = 3000
152 break;
153 case "BATTERY_FULL":
154 color = "green"
155 onMillisec = 1000
156 offMillisec = 0
157 break;
158 case "BATTERY_CHARGING":
159 color = "white"
160 onMillisec = 1000
161 offMillisec = 0
162 break;
163 case "BATTERY_LOW":
164 color = "orangered"
165 onMillisec = 500
166 offMillisec = 3000
167 break;
168 default:
169 console.log("ERROR onIndicatorStateChange: unknown state: " + indicatorState)
170 break;
171 }
172
173 // HACK: led is only updated after turn on so first always turn off
174 Leds.state = Leds.Off
175 if (indicatorState != "INDICATOR_OFF")
176 Leds.state = Leds.On
177 }
178
179 // Existence of unread notifications is determined by checking for a specific icon name in a dbus signal.
180 property var _actionGroup: QMenuModel.QDBusActionGroup {
181 busType: 1
182 busName: "org.ayatana.indicator.messages"
183 objectPath: "/org/ayatana/indicator/messages"
184 }
185
186 Indicators.ActionRootState {
187 id: _rootState
188 actionGroup: _actionGroup
189 actionName: "messages"
190 Component.onCompleted: actionGroup.start()
191 property bool hasMessages: (String(icons).indexOf("indicator-messages-new") != -1) && valid
192 onHasMessagesChanged: updateLightState("onHasMessagesChanged")
193 }
194
195 // Charging state and battery level are determined by listening to dbus signals from upower.
196 // See also system-settings battery plugin.
197 property var _ipag: QMenuModel.QDBusActionGroup {
198 busType: 1
199 busName: "org.ayatana.indicator.power"
200 objectPath: "/org/ayatana/indicator/power"
201 property variant batteryLevel: action("battery-level").state
202 property variant deviceState: action("device-state").state
203 Component.onCompleted: start()
204 onBatteryLevelChanged: {
205 root.batteryLevel = batteryLevel ? batteryLevel : 0.00
206 updateLightState("onBatteryLevelChanged")
207 }
208 onDeviceStateChanged: {
209 root.deviceState = deviceState ? deviceState : "unknown"
210 updateLightState("onDeviceStateChanged")
211 }
212 }
213
214 Component.onCompleted: Leds.state = Leds.Off
215 Component.onDestruction: Leds.state = Leds.Off
216
217 property var _colorBinding: Binding {
218 target: Leds
219 property: "color"
220 value: root.color
221 }
222
223 property var _onMillisecBinding: Binding {
224 target: Leds
225 property: "onMillisec"
226 value: root.onMillisec
227 }
228
229 property var _offMillisecBinding: Binding {
230 target: Leds
231 property: "offMillisec"
232 value: root.offMillisec
233 }
234}