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/>.
19 import QtGraphicalEffects 1.12
20 import Lomiri.Components 1.3
21 import Lomiri.Gestures 0.1
22 import "../Components"
24 import BatteryMonitor 1.0
29 property real dragHandleLeftMargin
30 property real launcherOffset
31 property alias background: greeterBackground.source
32 property alias backgroundSourceSize: greeterBackground.sourceSize
33 property alias hasCustomBackground: backgroundShade.visible
34 property alias backgroundShadeOpacity: backgroundShade.opacity
35 property real panelHeight
36 property var infographicModel
37 property bool draggable: true
39 property bool showInfographic: false
40 property real infographicsLeftMargin: 0
41 property real infographicsTopMargin: 0
42 property real infographicsRightMargin: 0
43 property real infographicsBottomMargin: 0
45 readonly property real showProgress: MathUtils.clamp((width - Math.abs(x + launcherOffset)) / width, 0, 1)
50 function hideRight() {
51 d.forceRightOnNextHideAnimation = true;
55 function showErrorMessage(msg) {
57 showLabelAnimation.start();
58 errorMessageAnimation.start();
63 property bool forceRightOnNextHideAnimation: false
64 property string errorMessage
67 prepareToHide: function () {
68 hideTranslation.from = root.x + translation.x
69 hideTranslation.to = root.x > 0 || d.forceRightOnNextHideAnimation ? root.width : -root.width;
70 d.forceRightOnNextHideAnimation = false;
73 // We don't directly bind "x" because that's owned by the DragHandle. So
74 // instead, we can get a little extra horizontal push by using transforms.
75 transform: Translate { id: translation; x: root.draggable ? launcherOffset : 0 }
77 // Eat events elsewhere on the coverpage, except mouse clicks which we pass
78 // up (they are used in the NarrowView to hide the cover page)
81 onClicked: root.clicked()
90 // In case background fails to load
98 objectName: "greeterBackground"
104 // Darkens wallpaper so that we can read text on it and see infographic
107 objectName: "backgroundShade"
117 leftMargin: root.infographicsLeftMargin
118 topMargin: root.infographicsTopMargin ? root.infographicsTopMargin : root.panelHeight
119 rightMargin: root.infographicsRightMargin
120 bottomMargin: root.infographicsBottomMargin
122 bottom: parent.bottom
129 id: infographicsLoader
130 objectName: "infographicsLoader"
131 active: root.showInfographic && infographicsArea.width > units.gu(32)
132 anchors.fill: infographicsArea
134 sourceComponent:Infographics {
136 objectName: "infographics"
137 model: root.infographicModel
138 clip: true // clip large data bubbles
144 anchors.horizontalCenter: parent.horizontalCenter
145 anchors.bottom: parent.bottom
146 anchors.bottomMargin: units.gu(5)
150 var seconds = BatteryMonitor.timeToFull;
151 var minutes = Math.floor(seconds / 60 % 60);
152 var hours = Math.floor(seconds / 60 / 60);
155 hourText = i18n.tr("%1 hour", "%1 hours", hours).arg(hours)
158 minuteText = i18n.tr("%1 minute", "%1 minutes", minutes).arg(minutes)
160 if (hours == 0 && minutes == 0) {
161 var state = BatteryMonitor.state();
162 if (state == BatteryMonitor.FULLY_CHARGED) return i18n.tr("Fully charged")
164 if (hourText != "" && minuteText != "") {
165 // Translators: String like "1 hour, 2 minutes until full"
166 return i18n.tr("%1, %2 until full").arg(hourText).arg(minuteText);
167 } else if (hourText == "" || minuteText == "") {
168 // Translators: String like "32 minutes until full" or "3 hours until full"
169 return i18n.tr("%1 until full").arg((hourText != "" ? hourText : minuteText))
173 font.weight: Font.Light
174 visible: BatteryMonitor.charging
179 objectName: "swipeHint"
180 property real baseOpacity: 0.5
182 anchors.horizontalCenter: parent.horizontalCenter
183 anchors.bottom: parent.bottom
184 anchors.bottomMargin: units.gu(5)
185 text: "《 " + (d.errorMessage ? d.errorMessage : i18n.tr("Unlock")) + " 》"
187 font.weight: Font.Light
188 visible: !BatteryMonitor.charging
190 readonly property var opacityAnimation: showLabelAnimation // for testing
192 SequentialAnimation on opacity {
193 id: showLabelAnimation
199 to: swipeHint.baseOpacity
200 duration: LomiriAnimation.SleepyDuration
202 PauseAnimation { duration: LomiriAnimation.BriskDuration }
204 from: swipeHint.baseOpacity
206 duration: LomiriAnimation.SleepyDuration
216 WrongPasswordAnimation {
217 id: errorMessageAnimation
218 objectName: "errorMessageAnimation"
224 objectName: "coverPageDragHandle"
226 anchors.leftMargin: root.dragHandleLeftMargin
227 enabled: root.draggable
228 direction: Direction.Horizontal
233 showLabelAnimation.start();
240 anchors.left: parent.right
241 anchors.top: parent.top
242 anchors.bottom: parent.bottom
244 source: "../graphics/dropshadow_right.png"
249 anchors.right: parent.left
250 anchors.top: parent.top
251 anchors.bottom: parent.bottom
253 source: "../graphics/dropshadow_left.png"
259 property bool enabled: false
261 if (enabled === __enabled) {
267 value = Qt.binding(function() { return root.width; })
269 value = Qt.binding(function() { return -root.width; })
276 property bool __enabled: false
283 hideAnimation: SequentialAnimation {
285 objectName: "hideAnimation"
286 property var target // unused, here to silence Showable warning
292 PropertyAction { target: root; property: "visible"; value: false }
293 PropertyAction { target: positionLock; property: "enabled"; value: true }
296 showAnimation: SequentialAnimation {
298 objectName: "showAnimation"
299 property var target // unused, here to silence Showable warning
300 PropertyAction { target: root; property: "visible"; value: true }
301 PropertyAction { target: positionLock; property: "enabled"; value: false }
306 duration: LomiriAnimation.FastDuration