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/>.
20import QtGraphicalEffects 1.12
21import Lomiri.Components 1.3
22import Lomiri.Gestures 0.1
25import BatteryMonitor 1.0
31 property real dragHandleLeftMargin
32 property real launcherOffset
33 property alias background: greeterBackground.source
34 property alias backgroundSourceSize: greeterBackground.sourceSize
35 property alias hasCustomBackground: backgroundShade.visible
36 property alias backgroundShadeOpacity: backgroundShade.opacity
37 property real panelHeight
38 property var infographicModel
39 property bool draggable: true
41 property bool showInfographic: false
42 property real infographicsLeftMargin: 0
43 property real infographicsTopMargin: 0
44 property real infographicsRightMargin: 0
45 property real infographicsBottomMargin: 0
47 readonly property real showProgress: MathUtils.clamp((width - Math.abs(x + launcherOffset)) / width, 0, 1)
52 function hideRight() {
53 d.forceRightOnNextHideAnimation = true;
57 function showErrorMessage(msg) {
59 showLabelAnimation.start();
60 errorMessageAnimation.start();
65 property bool forceRightOnNextHideAnimation: false
66 property string errorMessage
71 schema.id: "com.lomiri.touch.system"
74 prepareToHide: function () {
75 hideTranslation.from = root.x + translation.x
76 hideTranslation.to = root.x > 0 || d.forceRightOnNextHideAnimation ? root.width : -root.width;
77 d.forceRightOnNextHideAnimation = false;
80 // We don't directly bind "x" because that's owned by the DragHandle. So
81 // instead, we can get a little extra horizontal push by using transforms.
82 transform: Translate { id: translation; x: root.draggable ? launcherOffset : 0 }
84 // Eat events elsewhere on the coverpage, except mouse clicks which we pass
85 // up (they are used in the NarrowView to hide the cover page)
88 onClicked: root.clicked()
97 // In case background fails to load
104 id: greeterBackground
105 objectName: "greeterBackground"
111 // Darkens wallpaper so that we can read text on it and see infographic
114 objectName: "backgroundShade"
124 leftMargin: root.infographicsLeftMargin
125 topMargin: root.infographicsTopMargin ? root.infographicsTopMargin : root.panelHeight
126 rightMargin: root.infographicsRightMargin
127 bottomMargin: root.infographicsBottomMargin
129 bottom: parent.bottom
136 id: infographicsLoader
137 objectName: "infographicsLoader"
138 active: root.showInfographic && infographicsArea.width > units.gu(32)
139 anchors.fill: infographicsArea
141 sourceComponent:Infographics {
143 objectName: "infographics"
144 model: root.infographicModel
145 clip: true // clip large data bubbles
151 anchors.horizontalCenter: parent.horizontalCenter
152 anchors.bottom: parent.bottom
153 anchors.bottomMargin: units.gu(5)
157 var seconds = BatteryMonitor.timeToFull;
158 if (seconds == BatteryMonitor.NO_BATTERY) return ""
159 else if (seconds == BatteryMonitor.NO_TIMETOFULL) {
160 var isFullyCharged = BatteryMonitor.fullyCharged;
161 if (isFullyCharged) return i18n.tr("Fully charged")
165 var minutes = Math.floor(seconds / 60 % 60);
166 var hours = Math.floor(seconds / 60 / 60);
169 hourText = i18n.tr("%1 hour", "%1 hours", hours).arg(hours)
172 minuteText = i18n.tr("%1 minute", "%1 minutes", minutes).arg(minutes)
174 if (hours == 0 && minutes == 0) {
177 if (hourText != "" && minuteText != "") {
178 // Translators: String like "1 hour, 2 minutes until full"
179 return i18n.tr("%1, %2 until full").arg(hourText).arg(minuteText);
180 } else if (hourText == "" || minuteText == "") {
181 // Translators: String like "32 minutes until full" or "3 hours until full"
182 return i18n.tr("%1 until full").arg((hourText != "" ? hourText : minuteText))
186 font.weight: Font.Light
187 visible: gsettings.showChargingInformationWhileLocked && (BatteryMonitor.charging || BatteryMonitor.fullyCharged)
192 objectName: "swipeHint"
193 property real baseOpacity: 0.5
195 anchors.horizontalCenter: parent.horizontalCenter
196 anchors.bottom: parent.bottom
197 anchors.bottomMargin: units.gu(5)
198 text: "《 " + (d.errorMessage ? d.errorMessage : i18n.tr("Unlock")) + " 》"
200 font.weight: Font.Light
201 visible: !chargingHint.visible
203 readonly property var opacityAnimation: showLabelAnimation // for testing
205 SequentialAnimation on opacity {
206 id: showLabelAnimation
212 to: swipeHint.baseOpacity
213 duration: LomiriAnimation.SleepyDuration
215 PauseAnimation { duration: LomiriAnimation.BriskDuration }
217 from: swipeHint.baseOpacity
219 duration: LomiriAnimation.SleepyDuration
229 WrongPasswordAnimation {
230 id: errorMessageAnimation
231 objectName: "errorMessageAnimation"
237 objectName: "coverPageDragHandle"
239 anchors.leftMargin: root.dragHandleLeftMargin
240 enabled: root.draggable
241 direction: Direction.Horizontal
246 showLabelAnimation.start();
253 anchors.left: parent.right
254 anchors.top: parent.top
255 anchors.bottom: parent.bottom
257 source: "../graphics/dropshadow_right.png"
262 anchors.right: parent.left
263 anchors.top: parent.top
264 anchors.bottom: parent.bottom
266 source: "../graphics/dropshadow_left.png"
272 property bool enabled: false
274 if (enabled === __enabled) {
280 value = Qt.binding(function() { return root.width; })
282 value = Qt.binding(function() { return -root.width; })
289 property bool __enabled: false
294 restoreMode: Binding.RestoreBinding
297 hideAnimation: SequentialAnimation {
299 objectName: "hideAnimation"
300 property var target // unused, here to silence Showable warning
306 PropertyAction { target: root; property: "visible"; value: false }
307 PropertyAction { target: positionLock; property: "enabled"; value: true }
310 showAnimation: SequentialAnimation {
312 objectName: "showAnimation"
313 property var target // unused, here to silence Showable warning
314 PropertyAction { target: root; property: "visible"; value: true }
315 PropertyAction { target: positionLock; property: "enabled"; value: false }
320 duration: LomiriAnimation.FastDuration