on xenial help sign in
Make sessionList look nice
2ed43d3Josh Arenson
qml/Components/UnitySelectorDelegate.qmlnew file+357
@@ -0,0 +1,357 @@
1+/*
2+ * Copyright 2016 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+/*
18+ * This component is based on Ubuntu.Components 1.3 OptionSelectorDelegate
19+ * It affords the user slightly more control over certain visual attributes
20+ */
21+
22+import QtQuick 2.4
23+import Ubuntu.Components.ListItems 1.3 as ListItem
24+import Ubuntu.Components 1.3 as Toolkit
25+
26+ListItem.Empty {
27+ id: option
28+
29+ __height: units.gu(5)
30+
31+ /*!
32+ Subtext which appears below the main text.
33+ */
34+ property string subText
35+
36+ /*!
37+ \deprecated
38+
39+ \b{Use iconName or iconSource instead.}
40+
41+ Left icon url.
42+ */
43+ property url icon: iconSource
44+ onIconChanged: if (icon != iconSource) {
45+ console.warn("WARNING: OptionSelectorDelegate.icon is DEPRECATED. " +
46+ "Use iconName and iconSource instead.")
47+ }
48+
49+ /*!
50+ Constrains the size of the image to nothing greater than that of the delegate. Changes fillMode to Image.PreserveAspectFit.
51+ */
52+ property bool constrainImage: false
53+
54+ /*!
55+ Whether or not left image is colored by our theme.
56+ */
57+ property bool colorImage: listView.container.colourImage
58+
59+ /*!
60+ Color of left image.
61+ */
62+ property color assetColor: listView.container.themeColour
63+
64+ /*!
65+ Color of the primary text
66+ */
67+ property color textColor: theme.palette.normal.raisedText
68+
69+ /*!
70+ OptionSelector's ListView.
71+ */
72+ readonly property ListView listView: ListView.view
73+
74+ /*!
75+ Colorising fragment shader.
76+ */
77+ readonly property string fragColorShader:
78+ "varying highp vec2 qt_TexCoord0;
79+ uniform sampler2D source;
80+ uniform lowp vec4 color;
81+ uniform lowp float qt_Opacity;
82+
83+ void main() {
84+ lowp vec4 sourceColor = texture2D(source, qt_TexCoord0);
85+ gl_FragColor = color * sourceColor.a * qt_Opacity;
86+ }"
87+
88+ showDivider: index !== listView.count - 1 ? 1 : 0
89+ highlightWhenPressed: false
90+ selected: ListView.isCurrentItem
91+ anchors {
92+ left: parent.left
93+ right: parent.right
94+ }
95+ onClicked: {
96+ if (listView.container.currentlyExpanded) {
97+ listView.delegateClicked(index);
98+
99+ if (!listView.multiSelection) {
100+ listView.previousIndex = listView.currentIndex;
101+ listView.currentIndex = index;
102+ } else {
103+ selected = !selected;
104+ }
105+ }
106+
107+ if (!listView.expanded && !listView.multiSelection) {
108+ listView.container.currentlyExpanded = !listView.container.currentlyExpanded;
109+ }
110+ }
111+
112+ property color originalBackground: "transparent"
113+ Component.onCompleted: {
114+ height = listView.itemHeight = Qt.binding(function() { return childrenRect.height; });
115+ }
116+
117+ //Since we don't want to add states to our divider, we use the exposed alias provided in Empty to access it and alter it's opacity from here.
118+ states: [ State {
119+ name: "dividerExpanded"
120+ when: listView.container.state === "expanded" && index === listView.currentIndex
121+ PropertyChanges {
122+ target: option.divider
123+ opacity: 1
124+ }
125+ }, State {
126+ name: "dividerCollapsed"
127+ when: listView.container.state === "collapsed" && index === listView.currentIndex
128+ PropertyChanges {
129+ target: option.divider
130+ opacity: 0
131+ }
132+ }
133+ ]
134+
135+ //As with our states, we apply the transition with our divider as the target.
136+ transitions: [ Transition {
137+ from: "dividerExpanded"
138+ to: "dividerCollapsed"
139+ Toolkit.UbuntuNumberAnimation {
140+ target: option.divider
141+ properties: "opacity"
142+ duration: Toolkit.UbuntuAnimation.SlowDuration
143+ }
144+ }
145+ ]
146+
147+ resources: [
148+ Connections {
149+ target: listView.container
150+ ignoreUnknownSignals: true
151+ onCurrentlyExpandedChanged: {
152+ imageExpansion.stop();
153+ selectedImageCollapse.stop();
154+ deselectedImageCollapse.stop();
155+
156+ if (listView.container.currentlyExpanded === true) {
157+ if (!option.selected) {
158+ optionExpansion.start();
159+
160+ //Ensure a source change. This solves a bug which happens occasionaly when source is switched correctly. Probably related to the image.source binding.
161+ image.source = listView.container.tick
162+ } else {
163+ imageExpansion.start();
164+ }
165+ } else {
166+ if (!option.selected) {
167+ optionCollapse.start();
168+ } else {
169+ if (listView.previousIndex !== listView.currentIndex)
170+ selectedImageCollapse.start();
171+ else {
172+ deselectedImageCollapse.start();
173+ }
174+ }
175+ }
176+ }
177+ }, SequentialAnimation {
178+ id: imageExpansion
179+
180+ PropertyAnimation {
181+ target: image
182+ properties: "opacity"
183+ from : 1.0
184+ to: 0.0
185+ duration: Toolkit.UbuntuAnimation.FastDuration
186+ }
187+ PauseAnimation { duration: Toolkit.UbuntuAnimation.BriskDuration - Toolkit.UbuntuAnimation.FastDuration }
188+ PropertyAction {
189+ target: image
190+ property: "source"
191+ value: listView.container.tick
192+ }
193+ PropertyAnimation {
194+ target: image
195+ properties: "opacity"
196+ from : 0.0
197+ to: 1.0
198+ duration: Toolkit.UbuntuAnimation.FastDuration
199+ }
200+ }, PropertyAnimation {
201+ id: optionExpansion
202+
203+ target: option
204+ properties: "opacity"
205+ from : 0.0
206+ to: 1.0
207+ duration: Toolkit.UbuntuAnimation.SlowDuration
208+ }, SequentialAnimation {
209+ id: deselectedImageCollapse
210+
211+ PauseAnimation { duration: Toolkit.UbuntuAnimation.BriskDuration }
212+ PropertyAnimation {
213+ target: image
214+ properties: "opacity"
215+ from : 1.0
216+ to: 0.0
217+ duration: Toolkit.UbuntuAnimation.FastDuration
218+ }
219+ PauseAnimation { duration: Toolkit.UbuntuAnimation.FastDuration }
220+ PropertyAction {
221+ target: image
222+ property: "source"
223+ value: listView.container.chevron
224+ }
225+ PropertyAnimation {
226+ target: image
227+ properties: "opacity"
228+ from : 0.0
229+ to: 1.0
230+ duration: Toolkit.UbuntuAnimation.FastDuration
231+ }
232+ }, SequentialAnimation {
233+ id: selectedImageCollapse
234+
235+ PropertyAnimation {
236+ target: image
237+ properties: "opacity"
238+ from : 0.0
239+ to: 1.0
240+ duration: Toolkit.UbuntuAnimation.FastDuration
241+ }
242+ PauseAnimation { duration: Toolkit.UbuntuAnimation.BriskDuration - Toolkit.UbuntuAnimation.FastDuration }
243+ PropertyAnimation {
244+ target: image
245+ properties: "opacity"
246+ from : 1.0
247+ to: 0.0
248+ duration: Toolkit.UbuntuAnimation.FastDuration
249+ }
250+ PauseAnimation { duration: Toolkit.UbuntuAnimation.FastDuration }
251+ PropertyAction {
252+ target: image
253+ property: "source"
254+ value: listView.container.chevron
255+ }
256+ PropertyAnimation {
257+ target: image
258+ properties: "opacity"
259+ from : 0.0
260+ to: 1.0
261+ duration: Toolkit.UbuntuAnimation.FastDuration
262+ }
263+ }, PropertyAnimation {
264+ id: optionCollapse
265+ target: option
266+ properties: "opacity"
267+ from : 1.0
268+ to: 0.0
269+ duration: Toolkit.UbuntuAnimation.SlowDuration
270+ }
271+ ]
272+
273+ Row {
274+ spacing: units.gu(1)
275+
276+ anchors {
277+ left: parent.left
278+ leftMargin: units.gu(2)
279+ verticalCenter: parent.verticalCenter
280+ }
281+
282+ Image {
283+ id: leftIcon
284+ objectName: "icon"
285+
286+ height: constrainImage ? option.height : sourceSize.height
287+ source: option.iconSource
288+ fillMode: constrainImage ? Image.PreserveAspectFit : Image.Stretch
289+
290+ ShaderEffect {
291+ property color color: assetColor
292+ property Image source: parent
293+
294+ width: source.width
295+ height: source.height
296+ visible: colorImage
297+
298+ fragmentShader: fragColorShader
299+ }
300+ }
301+
302+ Column {
303+ anchors {
304+ verticalCenter: parent.verticalCenter
305+ }
306+ clip: true
307+ width: option.width - leftIcon.width - image.width
308+ - parent.spacing * 2 - parent.anchors.leftMargin
309+
310+ Toolkit.Label {
311+ text: option.text === "" ? modelData : option.text
312+ width: parent.width
313+ elide: Text.ElideRight
314+ color: option.textColor
315+ }
316+ Toolkit.Label {
317+ text: option.subText
318+ width: parent.width
319+ elide: Text.ElideRight
320+ visible: option.subText !== "" ? true : false
321+ textSize: Toolkit.Label.Small
322+ }
323+ }
324+
325+ Image {
326+ id: image
327+
328+ width: units.gu(2)
329+ height: units.gu(2)
330+ source: listView.expanded || listView.multiSelection ? listView.container.tick : listView.container.chevron
331+ opacity: option.selected ? 1.0 : 0.0
332+ anchors {
333+ verticalCenter: parent.verticalCenter
334+ }
335+
336+ //Our behaviour is only enabled for our expanded list due to flickering bugs in relation to all this other animations running on the expanding version.
337+ Behavior on opacity {
338+ enabled: listView.expanded
339+
340+ Toolkit.UbuntuNumberAnimation {
341+ properties: "opacity"
342+ duration: Toolkit.UbuntuAnimation.FastDuration
343+ }
344+ }
345+
346+ ShaderEffect {
347+ property color color: assetColor
348+ property Image source: parent
349+
350+ width: source.width
351+ height: source.height
352+
353+ fragmentShader: fragColorShader
354+ }
355+ }
356+ }
357+}
qml/Greeter/LoginList.qml−5
@@ -244,11 +244,6 @@ StyledItem {
244 source: LightDMService.sessions.iconUrl(root.currentSession)
244 source: LightDMService.sessions.iconUrl(root.currentSession)
245 }
245 }
246
246
247− Component.onCompleted: {
248− console.log("JOSH-> count: " + LightDMService.sessions.count);
249− console.log("JOSH-> visible: " + visible)
250− }
251−
252 onClicked: {
247 onClicked: {
253 sessionChooserButtonClicked();
248 sessionChooserButtonClicked();
254 }
249 }
qml/Greeter/SessionsList.qml+3−12
@@ -18,6 +18,7 @@ import QtQuick 2.4
18import Ubuntu.Components 1.3
18import Ubuntu.Components 1.3
19import Ubuntu.Components.ListItems 1.3
19import Ubuntu.Components.ListItems 1.3
20import "." 0.1
20import "." 0.1
21+import "../Components"
21
22
22Item {
23Item {
23 id: root
24 id: root
@@ -40,29 +41,19 @@ Item {
40 id: sessionsList
41 id: sessionsList
41 objectName: "sessionsListSelector"
42 objectName: "sessionsListSelector"
42
43
43− property color originalBackground
44 anchors.centerIn: parent
44 anchors.centerIn: parent
45 width: parent.width - units.gu(1)
45 width: parent.width - units.gu(1)
46 expanded:true
46 expanded:true
47− style: Item{}
48
47
49 model: LightDMService.sessions
48 model: LightDMService.sessions
50− delegate: OptionSelectorDelegate {
49+ delegate: UnitySelectorDelegate {
51 objectName: "sessionDelegate" + index
50 objectName: "sessionDelegate" + index
52 iconSource: icon_url
51 iconSource: icon_url
53 text: display
52 text: display
53+ textColor: selected ? theme.palette.normal.selectionText : theme.palette.normal.raisedText
54 selected: key === initiallySelectedSession
54 selected: key === initiallySelectedSession
55 }
55 }
56
56
57− Component.onCompleted: {
58− // Disbale the highlighting since it leaks outside of rounded corners
59− originalBackground = theme.palette.selected.background
60− theme.palette.selected.background = "transparent"
61− }
62− Component.onDestruction: {
63− theme.palette.selected.background = originalBackground
64− }
65−
66 onDelegateClicked: {
57 onDelegateClicked: {
67 sessionSelected(sessionsList.model.data(index,
58 sessionSelected(sessionsList.model.data(index,
68 LightDMService.sessionRoles.KeyRole));
59 LightDMService.sessionRoles.KeyRole));