Unity 8
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 real dragHandleLeftMargin: 0
29  property alias dragging: dragHandle.dragging
30 
31  property url background
32 
33  // so that it can be replaced in tests with a mock object
34  property var inputMethod: Qt.inputMethod
35 
36  prepareToHide: function () {
37  hideTranslation.to = greeter.x > 0 || d.forceRightOnNextHideAnimation ? greeter.width : -greeter.width;
38  d.forceRightOnNextHideAnimation = false;
39  }
40 
41  QtObject {
42  id: d
43  property bool forceRightOnNextHideAnimation: false
44  }
45 
46  property bool loadContent: required
47 
48  // 1 when fully shown and 0 when fully hidden
49  property real showProgress: visible ? MathUtils.clamp((width - Math.abs(x)) / width, 0, 1) : 0
50 
51  property alias model: greeterContentLoader.model
52  property bool locked: true
53 
54  readonly property bool narrowMode: !multiUser && height > width
55  readonly property bool multiUser: LightDM.Users.count > 1
56 
57  readonly property int currentIndex: greeterContentLoader.currentIndex
58 
59  signal selected(int uid)
60  signal unlocked(int uid)
61  signal tapped()
62 
63  function hideRight() {
64  d.forceRightOnNextHideAnimation = true;
65  hide();
66  }
67 
68  function tryToUnlock() {
69  if (created) {
70  greeterContentLoader.item.tryToUnlock()
71  }
72  }
73 
74  function reset() {
75  if (created) {
76  greeterContentLoader.item.reset()
77  }
78  }
79 
80  // event eater
81  // Nothing should leak to items behind the greeter
82  MouseArea { anchors.fill: parent }
83 
84  Loader {
85  id: greeterContentLoader
86  objectName: "greeterContentLoader"
87  anchors.fill: parent
88  property var model: LightDM.Users
89  property int currentIndex: 0
90  property var infographicModel: LightDM.Infographic
91  readonly property int backgroundTopMargin: -greeter.y
92 
93  source: loadContent ? "GreeterContent.qml" : ""
94 
95  onLoaded: {
96  selected(currentIndex);
97  }
98 
99  Connections {
100  target: greeterContentLoader.item
101 
102  onSelected: {
103  greeter.selected(uid);
104  greeterContentLoader.currentIndex = uid;
105  }
106  onUnlocked: greeter.unlocked(uid);
107  }
108  Binding {
109  target: greeterContentLoader.item
110  property: "inputMethod"
111  value: greeter.inputMethod
112  }
113  }
114 
115  DragHandle {
116  id: dragHandle
117  anchors.fill: parent
118  anchors.leftMargin: greeter.dragHandleLeftMargin
119  enabled: (greeter.narrowMode || !greeter.locked) && greeter.enabled && greeter.shown
120  direction: Direction.Horizontal
121 
122  onTapped: {
123  greeter.tapped();
124  showLabelAnimation.start();
125  }
126 
127  onDraggingChanged: {
128  if (dragging) {
129  showLabelAnimation.start();
130  }
131  }
132  }
133 
134  Label {
135  id: swipeHint
136  property real baseOpacity: 0.5
137  opacity: 0.0
138  anchors.horizontalCenter: parent.horizontalCenter
139  anchors.bottom: parent.bottom
140  anchors.bottomMargin: units.gu(5)
141  text: "《 " + i18n.tr("Unlock") + " 》"
142  color: "white"
143  font.weight: Font.Light
144 
145  SequentialAnimation on opacity {
146  id: showLabelAnimation
147  running: false
148  loops: 2
149 
150  StandardAnimation {
151  from: 0.0
152  to: swipeHint.baseOpacity
153  duration: UbuntuAnimation.SleepyDuration
154  }
155  PauseAnimation { duration: UbuntuAnimation.BriskDuration }
156  StandardAnimation {
157  from: swipeHint.baseOpacity
158  to: 0.0
159  duration: UbuntuAnimation.SleepyDuration
160  }
161  }
162  }
163 
164  // right side shadow
165  Image {
166  anchors.left: parent.right
167  anchors.top: parent.top
168  anchors.bottom: parent.bottom
169  fillMode: Image.Tile
170  source: "../graphics/dropshadow_right.png"
171  }
172 
173  // left side shadow
174  Image {
175  anchors.right: parent.left
176  anchors.top: parent.top
177  anchors.bottom: parent.bottom
178  fillMode: Image.Tile
179  source: "../graphics/dropshadow_left.png"
180  }
181 
182  Binding {
183  id: positionLock
184 
185  property bool enabled: false
186  onEnabledChanged: {
187  if (enabled === __enabled) {
188  return;
189  }
190 
191  if (enabled) {
192  if (greeter.x > 0) {
193  value = Qt.binding(function() { return greeter.width; })
194  } else {
195  value = Qt.binding(function() { return -greeter.width; })
196  }
197  }
198 
199  __enabled = enabled;
200  }
201 
202  property bool __enabled: false
203 
204  target: greeter
205  when: __enabled
206  property: "x"
207  }
208 
209  hideAnimation: SequentialAnimation {
210  id: hideAnimation
211  objectName: "hideAnimation"
212  StandardAnimation {
213  id: hideTranslation
214  property: "x"
215  target: greeter
216  }
217  PropertyAction { target: greeter; property: "visible"; value: false }
218  PropertyAction { target: positionLock; property: "enabled"; value: true }
219  }
220 
221  showAnimation: SequentialAnimation {
222  id: showAnimation
223  objectName: "showAnimation"
224  PropertyAction { target: greeter; property: "visible"; value: true }
225  PropertyAction { target: positionLock; property: "enabled"; value: false }
226  StandardAnimation {
227  property: "x"
228  target: greeter
229  to: 0
230  duration: UbuntuAnimation.FastDuration
231  }
232  }
233 }