Unity 8
CoverPage.qml
1 /*
2  * Copyright (C) 2013-2016 Canonical, Ltd.
3  * Copyright (C) 2021 UBports Foundation
4  *
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.
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 General Public License for more details.
13  *
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/>.
16  */
17 
18 import QtQuick 2.12
19 import QtGraphicalEffects 1.12
20 import Ubuntu.Components 1.3
21 import Ubuntu.Gestures 0.1
22 import "../Components"
23 
24 Showable {
25  id: root
26 
27  property real dragHandleLeftMargin
28  property real launcherOffset
29  property alias background: greeterBackground.source
30  property alias backgroundSourceSize: greeterBackground.sourceSize
31  property alias hasCustomBackground: backgroundShade.visible
32  property alias backgroundShadeOpacity: backgroundShade.opacity
33  property real panelHeight
34  property var infographicModel
35  property bool draggable: true
36 
37  property bool showInfographic: false
38  property real infographicsLeftMargin: 0
39  property real infographicsTopMargin: 0
40  property real infographicsRightMargin: 0
41  property real infographicsBottomMargin: 0
42 
43  readonly property real showProgress: MathUtils.clamp((width - Math.abs(x + launcherOffset)) / width, 0, 1)
44 
45  signal tease()
46  signal clicked()
47 
48  function hideRight() {
49  d.forceRightOnNextHideAnimation = true;
50  hide();
51  }
52 
53  function showErrorMessage(msg) {
54  d.errorMessage = msg;
55  showLabelAnimation.start();
56  errorMessageAnimation.start();
57  }
58 
59  QtObject {
60  id: d
61  property bool forceRightOnNextHideAnimation: false
62  property string errorMessage
63  }
64 
65  prepareToHide: function () {
66  hideTranslation.from = root.x + translation.x
67  hideTranslation.to = root.x > 0 || d.forceRightOnNextHideAnimation ? root.width : -root.width;
68  d.forceRightOnNextHideAnimation = false;
69  }
70 
71  // We don't directly bind "x" because that's owned by the DragHandle. So
72  // instead, we can get a little extra horizontal push by using transforms.
73  transform: Translate { id: translation; x: root.draggable ? launcherOffset : 0 }
74 
75  // Eat events elsewhere on the coverpage, except mouse clicks which we pass
76  // up (they are used in the NarrowView to hide the cover page)
77  MouseArea {
78  anchors.fill: parent
79  onClicked: root.clicked()
80 
81  MultiPointTouchArea {
82  anchors.fill: parent
83  mouseEnabled: false
84  }
85  }
86 
87  Rectangle {
88  // In case background fails to load
89  id: backgroundBackup
90  anchors.fill: parent
91  color: "black"
92  }
93 
94  Wallpaper {
95  id: greeterBackground
96  objectName: "greeterBackground"
97  anchors {
98  fill: parent
99  }
100  }
101 
102  // Darkens wallpaper so that we can read text on it and see infographic
103  Rectangle {
104  id: backgroundShade
105  objectName: "backgroundShade"
106  anchors.fill: parent
107  color: "black"
108  visible: false
109  }
110 
111  Item {
112  id: infographicsArea
113 
114  anchors {
115  leftMargin: root.infographicsLeftMargin
116  topMargin: root.infographicsTopMargin ? root.infographicsTopMargin : root.panelHeight
117  rightMargin: root.infographicsRightMargin
118  bottomMargin: root.infographicsBottomMargin
119  top: parent.top
120  bottom: parent.bottom
121  left: parent.left
122  right: parent.right
123  }
124  }
125 
126  Loader {
127  id: infographicsLoader
128  objectName: "infographicsLoader"
129  active: root.showInfographic && infographicsArea.width > units.gu(32)
130  anchors.fill: infographicsArea
131 
132  sourceComponent:Infographics {
133  id: infographics
134  objectName: "infographics"
135  model: root.infographicModel
136  clip: true // clip large data bubbles
137  }
138  }
139 
140  Label {
141  id: swipeHint
142  objectName: "swipeHint"
143  property real baseOpacity: 0.5
144  opacity: 0.0
145  anchors.horizontalCenter: parent.horizontalCenter
146  anchors.bottom: parent.bottom
147  anchors.bottomMargin: units.gu(5)
148  text: "《 " + (d.errorMessage ? d.errorMessage : i18n.tr("Unlock")) + " 》"
149  color: "white"
150  font.weight: Font.Light
151 
152  readonly property var opacityAnimation: showLabelAnimation // for testing
153 
154  SequentialAnimation on opacity {
155  id: showLabelAnimation
156  running: false
157  loops: 2
158 
159  StandardAnimation {
160  from: 0.0
161  to: swipeHint.baseOpacity
162  duration: UbuntuAnimation.SleepyDuration
163  }
164  PauseAnimation { duration: UbuntuAnimation.BriskDuration }
165  StandardAnimation {
166  from: swipeHint.baseOpacity
167  to: 0.0
168  duration: UbuntuAnimation.SleepyDuration
169  }
170 
171  onRunningChanged: {
172  if (!running)
173  d.errorMessage = "";
174  }
175  }
176  }
177 
178  WrongPasswordAnimation {
179  id: errorMessageAnimation
180  objectName: "errorMessageAnimation"
181  target: swipeHint
182  }
183 
184  DragHandle {
185  id: dragHandle
186  objectName: "coverPageDragHandle"
187  anchors.fill: parent
188  anchors.leftMargin: root.dragHandleLeftMargin
189  enabled: root.draggable
190  direction: Direction.Horizontal
191 
192  onPressedChanged: {
193  if (pressed) {
194  root.tease();
195  showLabelAnimation.start();
196  }
197  }
198  }
199 
200  // right side shadow
201  Image {
202  anchors.left: parent.right
203  anchors.top: parent.top
204  anchors.bottom: parent.bottom
205  fillMode: Image.Tile
206  source: "../graphics/dropshadow_right.png"
207  }
208 
209  // left side shadow
210  Image {
211  anchors.right: parent.left
212  anchors.top: parent.top
213  anchors.bottom: parent.bottom
214  fillMode: Image.Tile
215  source: "../graphics/dropshadow_left.png"
216  }
217 
218  Binding {
219  id: positionLock
220 
221  property bool enabled: false
222  onEnabledChanged: {
223  if (enabled === __enabled) {
224  return;
225  }
226 
227  if (enabled) {
228  if (root.x > 0) {
229  value = Qt.binding(function() { return root.width; })
230  } else {
231  value = Qt.binding(function() { return -root.width; })
232  }
233  }
234 
235  __enabled = enabled;
236  }
237 
238  property bool __enabled: false
239 
240  target: root
241  when: __enabled
242  property: "x"
243  }
244 
245  hideAnimation: SequentialAnimation {
246  id: hideAnimation
247  objectName: "hideAnimation"
248  property var target // unused, here to silence Showable warning
249  StandardAnimation {
250  id: hideTranslation
251  property: "x"
252  target: root
253  }
254  PropertyAction { target: root; property: "visible"; value: false }
255  PropertyAction { target: positionLock; property: "enabled"; value: true }
256  }
257 
258  showAnimation: SequentialAnimation {
259  id: showAnimation
260  objectName: "showAnimation"
261  property var target // unused, here to silence Showable warning
262  PropertyAction { target: root; property: "visible"; value: true }
263  PropertyAction { target: positionLock; property: "enabled"; value: false }
264  StandardAnimation {
265  property: "x"
266  target: root
267  to: 0
268  duration: UbuntuAnimation.FastDuration
269  }
270  }
271 }