2 * Copyright (C) 2013-2016 Canonical Ltd.
3 * Copyright (C) 2021 UBports Foundation
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 3.
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 General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19import QtGraphicalEffects 1.12
20import Lomiri.Components 1.3
21import Lomiri.Gestures 0.1
24import BatteryMonitor 1.0
30 property real dragHandleLeftMargin
31 property real launcherOffset
32 property alias background: greeterBackground.source
33 property alias backgroundSourceSize: greeterBackground.sourceSize
34 property alias hasCustomBackground: backgroundShade.visible
35 property alias backgroundShadeOpacity: backgroundShade.opacity
36 property real panelHeight
37 property var infographicModel
38 property bool draggable: true
40 property bool showInfographic: false
41 property real infographicsLeftMargin: 0
42 property real infographicsTopMargin: 0
43 property real infographicsRightMargin: 0
44 property real infographicsBottomMargin: 0
46 readonly property real showProgress: MathUtils.clamp((width - Math.abs(x + launcherOffset)) / width, 0, 1)
51 function hideRight() {
52 d.forceRightOnNextHideAnimation = true;
56 function showErrorMessage(msg) {
58 showLabelAnimation.start();
59 errorMessageAnimation.start();
64 property bool forceRightOnNextHideAnimation: false
65 property string errorMessage
70 schema.id: "com.lomiri.touch.system"
73 prepareToHide: function () {
74 hideTranslation.from = root.x + translation.x
75 hideTranslation.to = root.x > 0 || d.forceRightOnNextHideAnimation ? root.width : -root.width;
76 d.forceRightOnNextHideAnimation = false;
79 // We don't directly bind "x" because that's owned by the DragHandle. So
80 // instead, we can get a little extra horizontal push by using transforms.
81 transform: Translate { id: translation; x: root.draggable ? launcherOffset : 0 }
83 // Eat events elsewhere on the coverpage, except mouse clicks which we pass
84 // up (they are used in the NarrowView to hide the cover page)
87 onClicked: root.clicked()
96 // In case background fails to load
103 id: greeterBackground
104 objectName: "greeterBackground"
110 // Darkens wallpaper so that we can read text on it and see infographic
113 objectName: "backgroundShade"
123 leftMargin: root.infographicsLeftMargin
124 topMargin: root.infographicsTopMargin ? root.infographicsTopMargin : root.panelHeight
125 rightMargin: root.infographicsRightMargin
126 bottomMargin: root.infographicsBottomMargin
128 bottom: parent.bottom
135 id: infographicsLoader
136 objectName: "infographicsLoader"
137 active: root.showInfographic && infographicsArea.width > units.gu(32)
138 anchors.fill: infographicsArea
140 sourceComponent:Infographics {
142 objectName: "infographics"
143 model: root.infographicModel
144 clip: true // clip large data bubbles
150 anchors.horizontalCenter: parent.horizontalCenter
151 anchors.bottom: parent.bottom
152 anchors.bottomMargin: units.gu(5)
156 var seconds = BatteryMonitor.timeToFull;
157 if (seconds == BatteryMonitor.NO_BATTERY) return ""
158 else if (seconds == BatteryMonitor.NO_TIMETOFULL) {
159 var isFullyCharged = BatteryMonitor.fullyCharged;
160 if (isFullyCharged) return i18n.tr("Fully charged")
164 var minutes = Math.floor(seconds / 60 % 60);
165 var hours = Math.floor(seconds / 60 / 60);
168 hourText = i18n.tr("%1 hour", "%1 hours", hours).arg(hours)
171 minuteText = i18n.tr("%1 minute", "%1 minutes", minutes).arg(minutes)
173 if (hours == 0 && minutes == 0) {
176 if (hourText != "" && minuteText != "") {
177 // Translators: String like "1 hour, 2 minutes until full"
178 return i18n.tr("%1, %2 until full").arg(hourText).arg(minuteText);
179 } else if (hourText == "" || minuteText == "") {
180 // Translators: String like "32 minutes until full" or "3 hours until full"
181 return i18n.tr("%1 until full").arg((hourText != "" ? hourText : minuteText))
185 font.weight: Font.Light
186 visible: gsettings.showChargingInformationWhileLocked && (BatteryMonitor.charging || BatteryMonitor.fullyCharged)
191 objectName: "swipeHint"
192 property real baseOpacity: 0.5
194 anchors.horizontalCenter: parent.horizontalCenter
195 anchors.bottom: parent.bottom
196 anchors.bottomMargin: units.gu(5)
197 text: "《 " + (d.errorMessage ? d.errorMessage : i18n.tr("Unlock")) + " 》"
199 font.weight: Font.Light
200 visible: !chargingHint.visible
202 readonly property var opacityAnimation: showLabelAnimation // for testing
204 SequentialAnimation on opacity {
205 id: showLabelAnimation
211 to: swipeHint.baseOpacity
212 duration: LomiriAnimation.SleepyDuration
214 PauseAnimation { duration: LomiriAnimation.BriskDuration }
216 from: swipeHint.baseOpacity
218 duration: LomiriAnimation.SleepyDuration
228 WrongPasswordAnimation {
229 id: errorMessageAnimation
230 objectName: "errorMessageAnimation"
236 objectName: "coverPageDragHandle"
238 anchors.leftMargin: root.dragHandleLeftMargin
239 enabled: root.draggable
240 direction: Direction.Horizontal
245 showLabelAnimation.start();
252 anchors.left: parent.right
253 anchors.top: parent.top
254 anchors.bottom: parent.bottom
256 source: "../graphics/dropshadow_right.png"
261 anchors.right: parent.left
262 anchors.top: parent.top
263 anchors.bottom: parent.bottom
265 source: "../graphics/dropshadow_left.png"
271 property bool enabled: false
273 if (enabled === __enabled) {
279 value = Qt.binding(function() { return root.width; })
281 value = Qt.binding(function() { return -root.width; })
288 property bool __enabled: false
295 hideAnimation: SequentialAnimation {
297 objectName: "hideAnimation"
298 property var target // unused, here to silence Showable warning
304 PropertyAction { target: root; property: "visible"; value: false }
305 PropertyAction { target: positionLock; property: "enabled"; value: true }
308 showAnimation: SequentialAnimation {
310 objectName: "showAnimation"
311 property var target // unused, here to silence Showable warning
312 PropertyAction { target: root; property: "visible"; value: true }
313 PropertyAction { target: positionLock; property: "enabled"; value: false }
318 duration: LomiriAnimation.FastDuration