Merge lp:~nik90/ubuntu-clock-app/14-sync-listitem-actions-oct5 into lp:ubuntu-clock-app

Proposed by Nekhelesh Ramananthan
Status: Merged
Approved by: Nekhelesh Ramananthan
Approved revision: 114
Merged at revision: 137
Proposed branch: lp:~nik90/ubuntu-clock-app/14-sync-listitem-actions-oct5
Merge into: lp:ubuntu-clock-app
Prerequisite: lp:~nik90/ubuntu-clock-app/13-next-alarm-bottomedge
Diff against target: 376 lines (+147/-52)
3 files modified
app/upstreamcomponents/ListItemWithActions.qml (+130/-49)
debian/changelog (+1/-0)
tests/unit/tst_alarm.qml (+16/-3)
To merge this branch: bzr merge lp:~nik90/ubuntu-clock-app/14-sync-listitem-actions-oct5
Reviewer Review Type Date Requested Status
Ubuntu Phone Apps Jenkins Bot continuous-integration Approve
Nekhelesh Ramananthan Approve
Riccardo Padovani Approve
Review via email: mp+237189@code.launchpad.net

Commit message

Just a regular sync of ListItemWithActions.qml with upstream component.

Description of the change

Just a regular sync of ListItemWithActions.qml with upstream component.

To post a comment you must log in.
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Nekhelesh Ramananthan (nik90) wrote :

#blocked on Jenkins. This requires a patch to the Jenkins environment since the xvfb package which is used to run the clock app tests takes input focus away from the clock app when it is launched. This is causing the AP tests to be pass. Francis and Nicholas have been informed. Once jenkins is fixed, we should be good to merge this branch.

review: Needs Fixing
Revision history for this message
Riccardo Padovani (rpadovani) wrote :

lgtm

review: Approve
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
114. By Nekhelesh Ramananthan

Updated debian changelog

Revision history for this message
Nekhelesh Ramananthan (nik90) wrote :

#unblocked Test failures fixed! Approving!

review: Approve
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'app/upstreamcomponents/ListItemWithActions.qml'
2--- app/upstreamcomponents/ListItemWithActions.qml 2014-09-20 10:47:21 +0000
3+++ app/upstreamcomponents/ListItemWithActions.qml 2014-10-10 10:19:22 +0000
4@@ -34,63 +34,80 @@
5 property alias internalAnchors: mainContents.anchors
6 default property alias contents: mainContents.children
7
8- readonly property double actionWidth: units.gu(5)
9+ readonly property double actionWidth: units.gu(4)
10 readonly property double leftActionWidth: units.gu(10)
11 readonly property double actionThreshold: actionWidth * 0.4
12 readonly property double threshold: 0.4
13 readonly property string swipeState: main.x == 0 ? "Normal" : main.x > 0 ? "LeftToRight" : "RightToLeft"
14 readonly property alias swipping: mainItemMoving.running
15+ readonly property bool _showActions: mouseArea.pressed || swipeState != "Normal" || swipping
16+
17+ /* internal */
18+ property var _visibleRightSideActions: filterVisibleActions(rightSideActions)
19
20 signal itemClicked(var mouse)
21 signal itemPressAndHold(var mouse)
22
23- function returnToBoundsRTL()
24+ function returnToBoundsRTL(direction)
25 {
26 var actionFullWidth = actionWidth + units.gu(2)
27+
28+ // go back to normal state if swipping reverse
29+ if (direction === "LTR") {
30+ updatePosition(0)
31+ return
32+ } else if (!triggerActionOnMouseRelease) {
33+ updatePosition(-rightActionsView.width + units.gu(2))
34+ return
35+ }
36+
37 var xOffset = Math.abs(main.x)
38- var index = Math.min(Math.floor(xOffset / actionFullWidth), rightSideActions.length)
39-
40- if (index < 1) {
41- main.x = 0
42- } else if (index === rightSideActions.length) {
43- main.x = -rightActionsView.width
44- } else {
45- main.x = -(actionFullWidth * index)
46+ var index = Math.min(Math.floor(xOffset / actionFullWidth), _visibleRightSideActions.length)
47+ var newX = 0
48+ if (index === _visibleRightSideActions.length) {
49+ newX = -(rightActionsView.width - units.gu(2))
50+ } else if (index >= 1) {
51+ newX = -(actionFullWidth * index)
52 }
53+ updatePosition(newX)
54 }
55
56- function returnToBoundsLTR()
57+ function returnToBoundsLTR(direction)
58 {
59 var finalX = leftActionWidth
60- if (main.x > (finalX * root.threshold))
61- main.x = finalX
62- else
63- main.x = 0
64+ if ((direction === "RTL") || (main.x <= (finalX * root.threshold)))
65+ finalX = 0
66+ updatePosition(finalX)
67 }
68
69- function returnToBounds()
70+ function returnToBounds(direction)
71 {
72 if (main.x < 0) {
73- returnToBoundsRTL()
74+ returnToBoundsRTL(direction)
75 } else if (main.x > 0) {
76- returnToBoundsLTR()
77+ returnToBoundsLTR(direction)
78+ } else {
79+ updatePosition(0)
80 }
81 }
82
83- function contains(item, point)
84+ function contains(item, point, marginX)
85 {
86- return (point.x >= item.x) && (point.x <= (item.x + item.width)) && (point.y >= item.y) && (point.y <= (item.y + item.height));
87+ var itemStartX = item.x - marginX
88+ var itemEndX = item.x + item.width + marginX
89+ return (point.x >= itemStartX) && (point.x <= itemEndX) &&
90+ (point.y >= item.y) && (point.y <= (item.y + item.height));
91 }
92
93 function getActionAt(point)
94 {
95- if (contains(leftActionView, point)) {
96+ if (contains(leftActionView, point, 0)) {
97 return leftSideAction
98- } else if (contains(rightActionsView, point)) {
99+ } else if (contains(rightActionsView, point, 0)) {
100 var newPoint = root.mapToItem(rightActionsView, point.x, point.y)
101 for (var i = 0; i < rightActionsRepeater.count; i++) {
102 var child = rightActionsRepeater.itemAt(i)
103- if (contains(child, newPoint)) {
104+ if (contains(child, newPoint, units.gu(1))) {
105 return i
106 }
107 }
108@@ -100,15 +117,16 @@
109
110 function updateActiveAction()
111 {
112- if ((main.x <= -root.actionWidth) &&
113- (main.x > -rightActionsView.width)) {
114+ if (triggerActionOnMouseRelease &&
115+ (main.x <= -(root.actionWidth + units.gu(2))) &&
116+ (main.x > -(rightActionsView.width - units.gu(2)))) {
117 var actionFullWidth = actionWidth + units.gu(2)
118 var xOffset = Math.abs(main.x)
119- var index = Math.min(Math.floor(xOffset / actionFullWidth), rightSideActions.length)
120+ var index = Math.min(Math.floor(xOffset / actionFullWidth), _visibleRightSideActions.length)
121 index = index - 1
122 if (index > -1) {
123 root.activeItem = rightActionsRepeater.itemAt(index)
124- root.activeAction = root.rightSideActions[index]
125+ root.activeAction = root._visibleRightSideActions[index]
126 }
127 } else {
128 root.activeAction = null
129@@ -117,7 +135,29 @@
130
131 function resetSwipe()
132 {
133- main.x = 0
134+ updatePosition(0)
135+ }
136+
137+ function filterVisibleActions(actions)
138+ {
139+ var visibleActions = []
140+ for(var i = 0; i < actions.length; i++) {
141+ var action = actions[i]
142+ if (action.visible) {
143+ visibleActions.push(action)
144+ }
145+ }
146+ return visibleActions
147+ }
148+
149+ function updatePosition(pos)
150+ {
151+ if (!root.triggerActionOnMouseRelease && (pos !== 0)) {
152+ mouseArea.state = pos > 0 ? "RightToLeft" : "LeftToRight"
153+ } else {
154+ mouseArea.state = ""
155+ }
156+ main.x = pos
157 }
158
159 states: [
160@@ -153,45 +193,49 @@
161 }
162 width: root.leftActionWidth + actionThreshold
163 visible: leftSideAction
164- color: "red"
165+ color: UbuntuColors.red
166
167 Icon {
168 anchors {
169 centerIn: parent
170 horizontalCenterOffset: actionThreshold / 2
171 }
172- name: leftSideAction ? leftSideAction.iconName : ""
173+ name: leftSideAction && _showActions ? leftSideAction.iconName : ""
174 color: Theme.palette.selected.field
175 height: units.gu(3)
176 width: units.gu(3)
177 }
178 }
179
180- Item {
181+ Rectangle {
182 id: rightActionsView
183
184 anchors {
185 top: main.top
186 left: main.right
187- leftMargin: units.gu(1)
188 bottom: main.bottom
189 }
190- visible: rightSideActions.length > 0
191- width: rightActionsRepeater.count > 0 ? rightActionsRepeater.count * (root.actionWidth + units.gu(2)) + actionThreshold : 0
192+ visible: _visibleRightSideActions.length > 0
193+ width: rightActionsRepeater.count > 0 ? rightActionsRepeater.count * (root.actionWidth + units.gu(2)) + root.actionThreshold + units.gu(2) : 0
194+ color: "white"
195 Row {
196- anchors.fill: parent
197+ anchors{
198+ top: parent.top
199+ left: parent.left
200+ leftMargin: units.gu(2)
201+ right: parent.right
202+ rightMargin: units.gu(2)
203+ bottom: parent.bottom
204+ }
205 spacing: units.gu(2)
206 Repeater {
207 id: rightActionsRepeater
208
209- model: rightSideActions
210+ model: _showActions ? _visibleRightSideActions : []
211 Item {
212 property alias image: img
213
214- anchors {
215- top: parent.top
216- bottom: parent.bottom
217- }
218+ height: rightActionsView.height
219 width: root.actionWidth
220
221 Icon {
222@@ -200,10 +244,10 @@
223 anchors.centerIn: parent
224 width: units.gu(3)
225 height: units.gu(3)
226- name: iconName
227- color: root.activeAction === modelData || !root.triggerActionOnMouseRelease ? UbuntuColors.lightAubergine : Theme.palette.selected.background
228+ name: modelData.iconName
229+ color: root.activeAction === modelData ? UbuntuColors.lightAubergine : UbuntuColors.lightGrey
230 }
231- }
232+ }
233 }
234 }
235 }
236@@ -262,7 +306,6 @@
237 }
238 }
239 Behavior on color {
240- enabled: (root.color != root.selectedColor)
241 ColorAnimation {}
242 }
243 }
244@@ -302,7 +345,10 @@
245 value: 1.0
246 }
247 ScriptAction {
248- script: root.activeAction.triggered(root)
249+ script: {
250+ root.activeAction.triggered(root)
251+ mouseArea.state = ""
252+ }
253 }
254 PauseAnimation {
255 duration: 500
256@@ -318,24 +364,59 @@
257 MouseArea {
258 id: mouseArea
259
260- property bool locked: root.locked || ((root.leftSideAction === null) && (root.rightSideActions.count === 0))
261+ property bool locked: root.locked || ((root.leftSideAction === null) && (root._visibleRightSideActions.count === 0))
262 property bool manual: false
263+ property string direction: "None"
264+ property real lastX: -1
265
266 anchors.fill: parent
267 drag {
268 target: locked ? null : main
269 axis: Drag.XAxis
270- minimumX: rightActionsView.visible ? -(rightActionsView.width + root.actionThreshold) : 0
271+ minimumX: rightActionsView.visible ? -(rightActionsView.width) : 0
272 maximumX: leftActionView.visible ? leftActionView.width : 0
273+ threshold: root.actionThreshold
274+ }
275+
276+ states: [
277+ State {
278+ name: "LeftToRight"
279+ PropertyChanges {
280+ target: mouseArea
281+ drag.maximumX: 0
282+ }
283+ },
284+ State {
285+ name: "RightToLeft"
286+ PropertyChanges {
287+ target: mouseArea
288+ drag.minimumX: 0
289+ }
290+ }
291+ ]
292+
293+ onMouseXChanged: {
294+ var offset = (lastX - mouseX)
295+ if (Math.abs(offset) <= root.actionThreshold) {
296+ return
297+ }
298+ lastX = mouseX
299+ direction = offset > 0 ? "RTL" : "LTR";
300+ }
301+
302+ onPressed: {
303+ lastX = mouse.x
304 }
305
306 onReleased: {
307 if (root.triggerActionOnMouseRelease && root.activeAction) {
308 triggerAction.start()
309 } else {
310- root.returnToBounds()
311+ root.returnToBounds(direction)
312 root.activeAction = null
313 }
314+ lastX = -1
315+ direction = "None"
316 }
317 onClicked: {
318 if (main.x === 0) {
319@@ -349,7 +430,7 @@
320 var actionIndex = getActionAt(Qt.point(mouse.x, mouse.y))
321 if (actionIndex !== -1) {
322 root.activeItem = rightActionsRepeater.itemAt(actionIndex)
323- root.activeAction = root.rightSideActions[actionIndex]
324+ root.activeAction = root._visibleRightSideActions[actionIndex]
325 triggerAction.start()
326 return
327 }
328
329=== modified file 'debian/changelog'
330--- debian/changelog 2014-10-09 19:14:27 +0000
331+++ debian/changelog 2014-10-10 10:19:22 +0000
332@@ -9,6 +9,7 @@
333 * Design tweak to always show the remaining time to an alarm for one-time alarms
334 only. (LP: #1377538)
335 * Tweaked bottom edge to show the time to the next active alarm (LP: #1290793)
336+ * Synced ListItemWithActions with upstream
337
338 [Akiva Shammai Avraham]
339 * Improved the analog clock performance by updating the clock hands every second
340
341=== modified file 'tests/unit/tst_alarm.qml'
342--- tests/unit/tst_alarm.qml 2014-10-05 16:00:28 +0000
343+++ tests/unit/tst_alarm.qml 2014-10-10 10:19:22 +0000
344@@ -174,6 +174,21 @@
345 }
346 }
347
348+ function _swipeToDeleteItem(item)
349+ {
350+ var startX = item.threshold
351+ var startY = item.height / 2
352+ var endX = item.width
353+ var endY = startY
354+ mousePress(item, startX, startY)
355+ mouseMoveSlowly(item,
356+ startX, startY,
357+ endX - startX, endY - startY,
358+ 10, 100)
359+ mouseRelease(item, endX, endY)
360+ mouseClick(item, startX, startY)
361+ }
362+
363 function _deleteAlarm(label, repeat, time, status) {
364 var alarmsList = findChild(alarmPage, "alarmListView")
365 var oldCount = alarmsList.count
366@@ -182,9 +197,7 @@
367 var alarmObject = findChild(alarmsList, "alarm"+index)
368
369 if (index !== -1) {
370- mouseDrag(alarmObject, alarmObject.width/4, alarmObject.height/2, units.gu(10), 0)
371- mouseRelease(alarmObject, alarmObject.width/4+units.gu(10), alarmObject.height/2)
372- mouseClick(alarmObject, units.gu(5), alarmObject.height/2)
373+ _swipeToDeleteItem(alarmObject)
374 }
375
376 tryCompare(alarmsList, "count", oldCount-1, 10000, "Alarm count did not decrease after deleting the alarm")

Subscribers

People subscribed via source and target branches