Unity 8
 All Classes Functions
Greeter.qml
1 /*
2  * Copyright (C) 2013 Canonical, Ltd.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; version 3.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  */
16 
17 import QtQuick 2.0
18 import Ubuntu.Components 0.1
19 import Ubuntu.Gestures 0.1
20 import LightDM 0.1 as LightDM
21 import "../Components"
22 
23 Showable {
24  id: greeter
25  enabled: shown
26  created: greeterContentLoader.status == Loader.Ready && greeterContentLoader.item.ready
27 
28  property url background
29  property bool loadContent: required
30 
31  // 1 when fully shown and 0 when fully hidden
32  property real showProgress: MathUtils.clamp((width - Math.abs(x)) / width, 0, 1)
33 
34  showAnimation: StandardAnimation { property: "x"; to: 0; duration: UbuntuAnimation.FastDuration }
35  hideAnimation: __leftHideAnimation
36 
37  property alias dragHandleWidth: dragHandle.width
38  property alias model: greeterContentLoader.model
39  property bool locked: true
40 
41  readonly property bool narrowMode: !multiUser && height > width
42  readonly property bool multiUser: LightDM.Users.count > 1
43 
44  readonly property int currentIndex: greeterContentLoader.currentIndex
45 
46  property var __leftHideAnimation: StandardAnimation { property: "x"; to: -width }
47  property var __rightHideAnimation: StandardAnimation { property: "x"; to: width }
48 
49  signal selected(int uid)
50  signal unlocked(int uid)
51  signal tease()
52 
53  function hideRight() {
54  if (shown) {
55  hideAnimation = __rightHideAnimation
56  hide()
57  }
58  }
59 
60  function tryToUnlock() {
61  if (created) {
62  greeterContentLoader.item.tryToUnlock()
63  }
64  }
65 
66  function reset() {
67  if (created) {
68  greeterContentLoader.item.reset()
69  }
70  }
71 
72  onRequiredChanged: {
73  // Reset hide animation to default once we're finished with it
74  if (required) {
75  // Reset hide animation so that a hide() call is reliably left
76  hideAnimation = __leftHideAnimation
77  }
78  }
79 
80  // Bi-directional revealer
81  DraggingArea {
82  id: dragHandle
83  anchors.fill: parent
84  enabled: (greeter.narrowMode || !greeter.locked) && greeter.enabled && greeter.shown
85  orientation: Qt.Horizontal
86  propagateComposedEvents: true
87 
88  Component.onCompleted: {
89  // set evaluators to baseline of dragValue == 0
90  leftEvaluator.reset()
91  rightEvaluator.reset()
92  }
93 
94  function maybeTease() {
95  if (!greeter.locked || greeter.narrowMode)
96  greeter.tease();
97  }
98 
99  onClicked: maybeTease()
100  onDragStart: maybeTease()
101  onPressAndHold: {} // eat event, but no need to tease, as drag will cover it
102 
103  onDragEnd: {
104  if (greeter.x > 0 && rightEvaluator.shouldAutoComplete()) {
105  greeter.hideRight()
106  } else if (greeter.x < 0 && leftEvaluator.shouldAutoComplete()) {
107  greeter.hide();
108  } else {
109  greeter.show(); // undo drag
110  }
111  }
112 
113  onDragValueChanged: {
114  // dragValue is kept as a "step" value since we do this x adjusting on the fly
115  greeter.x += dragValue
116  }
117 
118  EdgeDragEvaluator {
119  id: rightEvaluator
120  trackedPosition: dragHandle.dragValue + greeter.x
121  maxDragDistance: parent.width
122  direction: Direction.Rightwards
123  }
124 
125  EdgeDragEvaluator {
126  id: leftEvaluator
127  trackedPosition: dragHandle.dragValue + greeter.x
128  maxDragDistance: parent.width
129  direction: Direction.Leftwards
130  }
131  }
132  TouchGate {
133  targetItem: dragHandle
134  anchors.fill: targetItem
135  enabled: targetItem.enabled
136  }
137 
138  Loader {
139  id: greeterContentLoader
140  objectName: "greeterContentLoader"
141  anchors.fill: parent
142  property var model: LightDM.Users
143  property int currentIndex: 0
144  property var infographicModel: LightDM.Infographic
145  readonly property int backgroundTopMargin: -greeter.y
146 
147  source: loadContent ? "GreeterContent.qml" : ""
148 
149  onLoaded: {
150  selected(currentIndex);
151  }
152 
153  Connections {
154  target: greeterContentLoader.item
155 
156  onSelected: {
157  greeter.selected(uid);
158  greeterContentLoader.currentIndex = uid;
159  }
160  onUnlocked: greeter.unlocked(uid);
161  }
162  }
163 
164  onTease: showLabelAnimation.start()
165 
166  Label {
167  id: swipeHint
168  visible: greeter.shown
169  property real baseOpacity: 0.5
170  opacity: 0.0
171  anchors.horizontalCenter: parent.horizontalCenter
172  anchors.bottom: parent.bottom
173  anchors.bottomMargin: units.gu(5)
174  text: "《 " + i18n.tr("Unlock") + " 》"
175  color: "white"
176  font.weight: Font.Light
177 
178  SequentialAnimation on opacity {
179  id: showLabelAnimation
180  running: false
181  loops: 2
182 
183  StandardAnimation {
184  from: 0.0
185  to: swipeHint.baseOpacity
186  duration: UbuntuAnimation.SleepyDuration
187  }
188  PauseAnimation { duration: UbuntuAnimation.BriskDuration }
189  StandardAnimation {
190  from: swipeHint.baseOpacity
191  to: 0.0
192  duration: UbuntuAnimation.SleepyDuration
193  }
194  }
195  }
196 
197  // right side shadow
198  Image {
199  anchors.left: parent.right
200  anchors.top: parent.top
201  anchors.bottom: parent.bottom
202  visible: parent.required
203  fillMode: Image.Tile
204  source: "../graphics/dropshadow_right.png"
205  }
206 
207  // left side shadow
208  Image {
209  anchors.right: parent.left
210  anchors.top: parent.top
211  anchors.bottom: parent.bottom
212  visible: parent.required
213  fillMode: Image.Tile
214  source: "../graphics/dropshadow_left.png"
215  }
216 }