Merge lp:~rpadovani/ubuntu-calculator-app/delegateImprovement141203 into lp:ubuntu-calculator-app
- delegateImprovement141203
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | 24 |
Proposed branch: | lp:~rpadovani/ubuntu-calculator-app/delegateImprovement141203 |
Merge into: | lp:ubuntu-calculator-app |
Diff against target: |
731 lines (+614/-27) 8 files modified
app/CMakeLists.txt (+1/-0) app/engine/CalculationHistory.qml (+1/-1) app/ubuntu-calculator-app.qml (+79/-1) app/ui/Screen.qml (+45/-13) app/upstreamcomponents/CMakeLists.txt (+6/-0) app/upstreamcomponents/ListItemWithActions.qml (+453/-0) app/upstreamcomponents/ListItemWithActionsCheckBox.qml (+25/-0) po/ubuntu-calculator-app.pot (+4/-12) |
To merge this branch: | bzr merge lp:~rpadovani/ubuntu-calculator-app/delegateImprovement141203 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Bartosz Kosiorek | Approve | ||
Review via email: mp+243743@code.launchpad.net |
Commit message
Added swipe to delete action, improved delegates
Description of the change
Added swipe to delete action, improved delegates
Bartosz Kosiorek (gang65) wrote : | # |
During run the warning :
"ShaderEffect: Property 'source' is not assigned a valid texture provider (QQuickImage*)."
is displayed.
There is an issue with formula, which exceed screen width. Currently it is not possible scroll it, and check what it contains. Maybe we should contact with User Interface team?
In my opinion equation mark should be the same size as formula.
From user perspective, the most important is result. That's why the size of result should be bigger, and the rest should be smaller.
Bartosz Kosiorek (gang65) wrote : | # |
Please update "pot" and resolve conflict in "app/ubuntu-
- 24. By Riccardo Padovani
-
Merged from upstream
- 25. By Riccardo Padovani
-
Addressed some bugs
Riccardo Padovani (rpadovani) wrote : | # |
> Instead of storing text to display, we should store formula. It will allow us to edit calculations.
Done
> We could also consider (for performance reasons) to store both "formula" and "text to display". But it needs to be tested on device/phone.
I think we could address that in another branch
> During run the warning : "ShaderEffect: Property 'source' is not assigned a valid texture provider (QQuickImage*)." is displayed.
I'm investigating on this. Anyway, I think could be addressed in another branch because it's only a warning
> There is an issue with formula, which exceed screen width. Currently it is not possible scroll it, and check what it contains. Maybe we should contact with User Interface team?
Yes, as soon as this branch is merged I create a click package and send it to gventuri of Design team
> In my opinion equation mark should be the same size as formula.
Done
> Please update "pot" and resolve conflict in "app/ubuntu-
Done
> Can we just increase "spacing" to "spacing: units.gu(3)"?
The result is a bit different, I prefer this one because is smaller, but if you want I can modify it
Preview Diff
1 | === modified file 'app/CMakeLists.txt' |
2 | --- app/CMakeLists.txt 2014-11-28 00:01:50 +0000 |
3 | +++ app/CMakeLists.txt 2014-12-08 13:30:38 +0000 |
4 | @@ -14,6 +14,7 @@ |
5 | |
6 | add_subdirectory(engine) |
7 | add_subdirectory(ui) |
8 | +add_subdirectory(upstreamcomponents) |
9 | |
10 | # Make the autpilot files visible in qtcreator |
11 | file(GLOB_RECURSE AUTOPILOT_TEST_FILES *.py) |
12 | |
13 | === modified file 'app/engine/CalculationHistory.qml' |
14 | --- app/engine/CalculationHistory.qml 2014-12-03 22:51:38 +0000 |
15 | +++ app/engine/CalculationHistory.qml 2014-12-08 13:30:38 +0000 |
16 | @@ -44,7 +44,7 @@ |
17 | id: sortedHistory |
18 | model: query |
19 | sort.property: "docId" |
20 | - sort.order: Qt.DescendingOrder |
21 | + sort.order: Qt.AscendingOrder |
22 | } |
23 | |
24 | function addCalculationToDatabase(formula, result) { |
25 | |
26 | === modified file 'app/ubuntu-calculator-app.qml' |
27 | --- app/ubuntu-calculator-app.qml 2014-12-04 22:51:08 +0000 |
28 | +++ app/ubuntu-calculator-app.qml 2014-12-08 13:30:38 +0000 |
29 | @@ -226,7 +226,7 @@ |
30 | return; |
31 | } |
32 | |
33 | - calculationHistory.addCalculationToDatabase(returnFormulaToDisplay(longFormula), displayedInputText); |
34 | + calculationHistory.addCalculationToDatabase(longFormula, result); |
35 | longFormula = result; |
36 | shortFormula = result; |
37 | numberOfOpenedBrackets = 0; |
38 | @@ -274,8 +274,86 @@ |
39 | model: calculationHistory.getContents() |
40 | interactive: false |
41 | |
42 | + property var _currentSwipedItem: null |
43 | + |
44 | delegate: Screen { |
45 | + id: screenDelegate |
46 | width: parent.width |
47 | + |
48 | + property var removalAnimation |
49 | + function remove() { |
50 | + removalAnimation.start(); |
51 | + } |
52 | + |
53 | + onSwippingChanged: { |
54 | + formulaView._updateSwipeState(screenDelegate); |
55 | + } |
56 | + |
57 | + onSwipeStateChanged: { |
58 | + formulaView._updateSwipeState(screenDelegate); |
59 | + } |
60 | + |
61 | + leftSideAction: Action { |
62 | + iconName: "delete" |
63 | + text: i18n.tr("Delete") |
64 | + onTriggered: { |
65 | + screenDelegate.remove(); |
66 | + } |
67 | + } |
68 | + |
69 | + ListView.onRemove: ScriptAction { |
70 | + script: { |
71 | + if (formulaView._currentSwipedItem === screenDelegate) { |
72 | + formulaView._currentSwipedItem = null; |
73 | + } |
74 | + } |
75 | + } |
76 | + |
77 | + removalAnimation: SequentialAnimation { |
78 | + alwaysRunToEnd: true |
79 | + |
80 | + PropertyAction { |
81 | + target: screenDelegate |
82 | + property: "ListView.delayRemove" |
83 | + value: true |
84 | + } |
85 | + |
86 | + UbuntuNumberAnimation { |
87 | + target: screenDelegate |
88 | + property: "height" |
89 | + to: 0 |
90 | + } |
91 | + |
92 | + PropertyAction { |
93 | + target: screenDelegate |
94 | + property: "ListView.delayRemove" |
95 | + value: false |
96 | + } |
97 | + |
98 | + ScriptAction { |
99 | + script: { |
100 | + calculationHistory.deleteCalc(docId); |
101 | + } |
102 | + } |
103 | + } |
104 | + } |
105 | + |
106 | + function _updateSwipeState(item) { |
107 | + if (item.swipping) { |
108 | + return |
109 | + } |
110 | + |
111 | + if (item.swipeState !== "Normal") { |
112 | + if (formulaView._currentSwipedItem !== item) { |
113 | + if (formulaView._currentSwipedItem) { |
114 | + formulaView._currentSwipedItem.resetSwipe() |
115 | + } |
116 | + formulaView._currentSwipedItem = item |
117 | + } else if (item.swipeState !== "Normal" |
118 | + && formulaView._currentSwipedItem === item) { |
119 | + formulaView._currentSwipedItem = null |
120 | + } |
121 | + } |
122 | } |
123 | } |
124 | } |
125 | |
126 | === modified file 'app/ui/Screen.qml' |
127 | --- app/ui/Screen.qml 2014-12-04 22:32:31 +0000 |
128 | +++ app/ui/Screen.qml 2014-12-08 13:30:38 +0000 |
129 | @@ -15,26 +15,58 @@ |
130 | * You should have received a copy of the GNU General Public License |
131 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
132 | */ |
133 | - |
134 | import QtQuick 2.3 |
135 | import Ubuntu.Components 1.1 |
136 | -import Ubuntu.Components.ListItems 1.0 as ListItem |
137 | - |
138 | -ListItem.Standard { |
139 | + |
140 | +import "../upstreamcomponents" |
141 | + |
142 | +ListItemWithActions { |
143 | id: root |
144 | + |
145 | + color: "white" |
146 | Row { |
147 | id: row |
148 | + width: parent.width |
149 | + anchors.right: parent.right |
150 | + |
151 | layoutDirection: Qt.RightToLeft |
152 | spacing: units.gu(1) |
153 | - Text { |
154 | - text: contents.result |
155 | - font.bold: true |
156 | - } |
157 | - Text { |
158 | - text: "="; |
159 | - } |
160 | - Text { |
161 | - text: contents.formula |
162 | + |
163 | + Text { |
164 | + id: result |
165 | + |
166 | + anchors.bottom: formula.bottom |
167 | + |
168 | + text: Number(model.contents.result).toLocaleString(Qt.locale(), "f", 0) |
169 | + font.pixelSize: units.gu(4) |
170 | + lineHeight: units.gu(2) |
171 | + lineHeightMode: Text.FixedHeight |
172 | + } |
173 | + |
174 | + Text { |
175 | + id: equal |
176 | + |
177 | + anchors.bottom: formula.bottom |
178 | + |
179 | + text: " = " |
180 | + font.pixelSize: units.gu(3) |
181 | + lineHeight: units.gu(1) + 1 |
182 | + lineHeightMode: Text.FixedHeight |
183 | + } |
184 | + |
185 | + Text { |
186 | + id: formula |
187 | + |
188 | + width: parent.width - equal.width - result.width |
189 | + anchors.bottom: parent.bottom |
190 | + |
191 | + text: returnFormulaToDisplay(model.contents.formula) |
192 | + font.pixelSize: units.gu(3) |
193 | + lineHeight: units.gu(1) + 1 |
194 | + lineHeightMode: Text.FixedHeight |
195 | + |
196 | + elide: Text.ElideLeft |
197 | + horizontalAlignment: Text.AlignRight |
198 | } |
199 | } |
200 | } |
201 | |
202 | === added directory 'app/upstreamcomponents' |
203 | === added file 'app/upstreamcomponents/CMakeLists.txt' |
204 | --- app/upstreamcomponents/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
205 | +++ app/upstreamcomponents/CMakeLists.txt 2014-12-08 13:30:38 +0000 |
206 | @@ -0,0 +1,6 @@ |
207 | +file(GLOB UPSTREAMCOMPONENTS_QML_JS_FILES *.qml *.js) |
208 | + |
209 | +# Make the files visible in the qtcreator tree |
210 | +add_custom_target(ubuntu-calculator-app_upstreamcomponents_QMlFiles ALL SOURCES ${UPSTREAMCOMPONENTS_QML_JS_FILES}) |
211 | + |
212 | +install(FILES ${UPSTREAMCOMPONENTS_QML_JS_FILES} DESTINATION ${UBUNTU-CALCULATOR-APP_DIR}/upstreamcomponents) |
213 | |
214 | === added file 'app/upstreamcomponents/ListItemWithActions.qml' |
215 | --- app/upstreamcomponents/ListItemWithActions.qml 1970-01-01 00:00:00 +0000 |
216 | +++ app/upstreamcomponents/ListItemWithActions.qml 2014-12-08 13:30:38 +0000 |
217 | @@ -0,0 +1,453 @@ |
218 | +/* |
219 | + * Copyright (C) 2012-2014 Canonical, Ltd. |
220 | + * |
221 | + * This program is free software; you can redistribute it and/or modify |
222 | + * it under the terms of the GNU General Public License as published by |
223 | + * the Free Software Foundation; version 3. |
224 | + * |
225 | + * This program is distributed in the hope that it will be useful, |
226 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
227 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
228 | + * GNU General Public License for more details. |
229 | + * |
230 | + * You should have received a copy of the GNU General Public License |
231 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
232 | + */ |
233 | + |
234 | +import QtQuick 2.2 |
235 | +import Ubuntu.Components 1.1 |
236 | + |
237 | +Item { |
238 | + id: root |
239 | + |
240 | + property Action leftSideAction: null |
241 | + property list<Action> rightSideActions |
242 | + property double defaultHeight: units.gu(8) |
243 | + property bool locked: false |
244 | + property Action activeAction: null |
245 | + property var activeItem: null |
246 | + property bool triggerActionOnMouseRelease: false |
247 | + property color color: Theme.palette.normal.background |
248 | + property color selectedColor: "#E6E6E6" |
249 | + property bool selected: false |
250 | + property bool selectionMode: false |
251 | + property alias internalAnchors: mainContents.anchors |
252 | + default property alias contents: mainContents.children |
253 | + |
254 | + readonly property double actionWidth: units.gu(4) |
255 | + readonly property double leftActionWidth: units.gu(10) |
256 | + readonly property double actionThreshold: actionWidth * 0.4 |
257 | + readonly property double threshold: 0.4 |
258 | + readonly property string swipeState: main.x == 0 ? "Normal" : main.x > 0 ? "LeftToRight" : "RightToLeft" |
259 | + readonly property alias swipping: mainItemMoving.running |
260 | + readonly property bool _showActions: mouseArea.pressed || swipeState != "Normal" || swipping |
261 | + |
262 | + /* internal */ |
263 | + property var _visibleRightSideActions: filterVisibleActions(rightSideActions) |
264 | + |
265 | + signal itemClicked(var mouse) |
266 | + signal itemPressAndHold(var mouse) |
267 | + |
268 | + function returnToBoundsRTL(direction) |
269 | + { |
270 | + var actionFullWidth = actionWidth + units.gu(2) |
271 | + |
272 | + // go back to normal state if swipping reverse |
273 | + if (direction === "LTR") { |
274 | + updatePosition(0) |
275 | + return |
276 | + } else if (!triggerActionOnMouseRelease) { |
277 | + updatePosition(-rightActionsView.width + units.gu(2)) |
278 | + return |
279 | + } |
280 | + |
281 | + var xOffset = Math.abs(main.x) |
282 | + var index = Math.min(Math.floor(xOffset / actionFullWidth), _visibleRightSideActions.length) |
283 | + var newX = 0 |
284 | + if (index === _visibleRightSideActions.length) { |
285 | + newX = -(rightActionsView.width - units.gu(2)) |
286 | + } else if (index >= 1) { |
287 | + newX = -(actionFullWidth * index) |
288 | + } |
289 | + updatePosition(newX) |
290 | + } |
291 | + |
292 | + function returnToBoundsLTR(direction) |
293 | + { |
294 | + var finalX = leftActionWidth |
295 | + if ((direction === "RTL") || (main.x <= (finalX * root.threshold))) |
296 | + finalX = 0 |
297 | + updatePosition(finalX) |
298 | + } |
299 | + |
300 | + function returnToBounds(direction) |
301 | + { |
302 | + if (main.x < 0) { |
303 | + returnToBoundsRTL(direction) |
304 | + } else if (main.x > 0) { |
305 | + returnToBoundsLTR(direction) |
306 | + } else { |
307 | + updatePosition(0) |
308 | + } |
309 | + } |
310 | + |
311 | + function contains(item, point, marginX) |
312 | + { |
313 | + var itemStartX = item.x - marginX |
314 | + var itemEndX = item.x + item.width + marginX |
315 | + return (point.x >= itemStartX) && (point.x <= itemEndX) && |
316 | + (point.y >= item.y) && (point.y <= (item.y + item.height)); |
317 | + } |
318 | + |
319 | + function getActionAt(point) |
320 | + { |
321 | + if (contains(leftActionView, point, 0)) { |
322 | + return leftSideAction |
323 | + } else if (contains(rightActionsView, point, 0)) { |
324 | + var newPoint = root.mapToItem(rightActionsView, point.x, point.y) |
325 | + for (var i = 0; i < rightActionsRepeater.count; i++) { |
326 | + var child = rightActionsRepeater.itemAt(i) |
327 | + if (contains(child, newPoint, units.gu(1))) { |
328 | + return i |
329 | + } |
330 | + } |
331 | + } |
332 | + return -1 |
333 | + } |
334 | + |
335 | + function updateActiveAction() |
336 | + { |
337 | + if (triggerActionOnMouseRelease && |
338 | + (main.x <= -(root.actionWidth + units.gu(2))) && |
339 | + (main.x > -(rightActionsView.width - units.gu(2)))) { |
340 | + var actionFullWidth = actionWidth + units.gu(2) |
341 | + var xOffset = Math.abs(main.x) |
342 | + var index = Math.min(Math.floor(xOffset / actionFullWidth), _visibleRightSideActions.length) |
343 | + index = index - 1 |
344 | + if (index > -1) { |
345 | + root.activeItem = rightActionsRepeater.itemAt(index) |
346 | + root.activeAction = root._visibleRightSideActions[index] |
347 | + } |
348 | + } else { |
349 | + root.activeAction = null |
350 | + } |
351 | + } |
352 | + |
353 | + function resetSwipe() |
354 | + { |
355 | + updatePosition(0) |
356 | + } |
357 | + |
358 | + function filterVisibleActions(actions) |
359 | + { |
360 | + var visibleActions = [] |
361 | + for(var i = 0; i < actions.length; i++) { |
362 | + var action = actions[i] |
363 | + if (action.visible) { |
364 | + visibleActions.push(action) |
365 | + } |
366 | + } |
367 | + return visibleActions |
368 | + } |
369 | + |
370 | + function updatePosition(pos) |
371 | + { |
372 | + if (!root.triggerActionOnMouseRelease && (pos !== 0)) { |
373 | + mouseArea.state = pos > 0 ? "RightToLeft" : "LeftToRight" |
374 | + } else { |
375 | + mouseArea.state = "" |
376 | + } |
377 | + main.x = pos |
378 | + } |
379 | + |
380 | + states: [ |
381 | + State { |
382 | + name: "select" |
383 | + when: selectionMode || selected |
384 | + PropertyChanges { |
385 | + target: selectionIcon |
386 | + source: Qt.resolvedUrl("ListItemWithActionsCheckBox.qml") |
387 | + anchors.leftMargin: units.gu(2) |
388 | + } |
389 | + PropertyChanges { |
390 | + target: root |
391 | + locked: true |
392 | + } |
393 | + PropertyChanges { |
394 | + target: main |
395 | + x: 0 |
396 | + } |
397 | + } |
398 | + ] |
399 | + |
400 | + height: defaultHeight |
401 | + clip: height !== defaultHeight |
402 | + |
403 | + Rectangle { |
404 | + id: leftActionView |
405 | + |
406 | + anchors { |
407 | + top: parent.top |
408 | + bottom: parent.bottom |
409 | + right: main.left |
410 | + } |
411 | + width: root.leftActionWidth + actionThreshold |
412 | + visible: leftSideAction |
413 | + color: UbuntuColors.red |
414 | + |
415 | + Icon { |
416 | + anchors { |
417 | + centerIn: parent |
418 | + horizontalCenterOffset: actionThreshold / 2 |
419 | + } |
420 | + name: leftSideAction && _showActions ? leftSideAction.iconName : "" |
421 | + color: Theme.palette.selected.field |
422 | + height: units.gu(3) |
423 | + width: units.gu(3) |
424 | + } |
425 | + } |
426 | + |
427 | + Rectangle { |
428 | + id: rightActionsView |
429 | + |
430 | + anchors { |
431 | + top: main.top |
432 | + left: main.right |
433 | + bottom: main.bottom |
434 | + } |
435 | + visible: _visibleRightSideActions.length > 0 |
436 | + width: rightActionsRepeater.count > 0 ? rightActionsRepeater.count * (root.actionWidth + units.gu(2)) + root.actionThreshold + units.gu(2) : 0 |
437 | + color: "white" |
438 | + Row { |
439 | + anchors{ |
440 | + top: parent.top |
441 | + left: parent.left |
442 | + leftMargin: units.gu(2) |
443 | + right: parent.right |
444 | + rightMargin: units.gu(2) |
445 | + bottom: parent.bottom |
446 | + } |
447 | + spacing: units.gu(2) |
448 | + Repeater { |
449 | + id: rightActionsRepeater |
450 | + |
451 | + model: _showActions ? _visibleRightSideActions : [] |
452 | + Item { |
453 | + property alias image: img |
454 | + |
455 | + height: rightActionsView.height |
456 | + width: root.actionWidth |
457 | + |
458 | + Icon { |
459 | + id: img |
460 | + |
461 | + anchors.centerIn: parent |
462 | + width: units.gu(3) |
463 | + height: units.gu(3) |
464 | + name: modelData.iconName |
465 | + color: root.activeAction === modelData ? UbuntuColors.lightAubergine : UbuntuColors.lightGrey |
466 | + } |
467 | + } |
468 | + } |
469 | + } |
470 | + } |
471 | + |
472 | + |
473 | + Rectangle { |
474 | + id: main |
475 | + objectName: "mainItem" |
476 | + |
477 | + anchors { |
478 | + top: parent.top |
479 | + bottom: parent.bottom |
480 | + } |
481 | + |
482 | + width: parent.width |
483 | + color: root.selected ? root.selectedColor : root.color |
484 | + |
485 | + Loader { |
486 | + id: selectionIcon |
487 | + |
488 | + anchors { |
489 | + left: main.left |
490 | + verticalCenter: main.verticalCenter |
491 | + } |
492 | + width: (status === Loader.Ready) ? item.implicitWidth : 0 |
493 | + visible: (status === Loader.Ready) && (item.width === item.implicitWidth) |
494 | + Behavior on width { |
495 | + NumberAnimation { |
496 | + duration: UbuntuAnimation.SnapDuration |
497 | + } |
498 | + } |
499 | + } |
500 | + |
501 | + |
502 | + Item { |
503 | + id: mainContents |
504 | + |
505 | + anchors { |
506 | + left: selectionIcon.right |
507 | + leftMargin: units.gu(2) |
508 | + top: parent.top |
509 | + topMargin: units.gu(1) |
510 | + right: parent.right |
511 | + rightMargin: units.gu(2) |
512 | + bottom: parent.bottom |
513 | + bottomMargin: units.gu(1) |
514 | + } |
515 | + } |
516 | + |
517 | + Behavior on x { |
518 | + UbuntuNumberAnimation { |
519 | + id: mainItemMoving |
520 | + |
521 | + easing.type: Easing.OutElastic |
522 | + duration: UbuntuAnimation.SlowDuration |
523 | + } |
524 | + } |
525 | + Behavior on color { |
526 | + ColorAnimation {} |
527 | + } |
528 | + } |
529 | + |
530 | + SequentialAnimation { |
531 | + id: triggerAction |
532 | + |
533 | + property var currentItem: root.activeItem ? root.activeItem.image : null |
534 | + |
535 | + running: false |
536 | + ParallelAnimation { |
537 | + UbuntuNumberAnimation { |
538 | + target: triggerAction.currentItem |
539 | + property: "opacity" |
540 | + from: 1.0 |
541 | + to: 0.0 |
542 | + duration: UbuntuAnimation.SlowDuration |
543 | + easing {type: Easing.InOutBack; } |
544 | + } |
545 | + UbuntuNumberAnimation { |
546 | + target: triggerAction.currentItem |
547 | + properties: "width, height" |
548 | + from: units.gu(3) |
549 | + to: root.actionWidth |
550 | + duration: UbuntuAnimation.SlowDuration |
551 | + easing {type: Easing.InOutBack; } |
552 | + } |
553 | + } |
554 | + PropertyAction { |
555 | + target: triggerAction.currentItem |
556 | + properties: "width, height" |
557 | + value: units.gu(3) |
558 | + } |
559 | + PropertyAction { |
560 | + target: triggerAction.currentItem |
561 | + properties: "opacity" |
562 | + value: 1.0 |
563 | + } |
564 | + ScriptAction { |
565 | + script: { |
566 | + root.activeAction.triggered(root) |
567 | + mouseArea.state = "" |
568 | + } |
569 | + } |
570 | + PauseAnimation { |
571 | + duration: 500 |
572 | + } |
573 | + UbuntuNumberAnimation { |
574 | + target: main |
575 | + property: "x" |
576 | + to: 0 |
577 | + |
578 | + } |
579 | + } |
580 | + |
581 | + MouseArea { |
582 | + id: mouseArea |
583 | + |
584 | + property bool locked: root.locked || ((root.leftSideAction === null) && (root._visibleRightSideActions.count === 0)) |
585 | + property bool manual: false |
586 | + property string direction: "None" |
587 | + property real lastX: -1 |
588 | + |
589 | + anchors.fill: parent |
590 | + drag { |
591 | + target: locked ? null : main |
592 | + axis: Drag.XAxis |
593 | + minimumX: rightActionsView.visible ? -(rightActionsView.width) : 0 |
594 | + maximumX: leftActionView.visible ? leftActionView.width : 0 |
595 | + threshold: root.actionThreshold |
596 | + } |
597 | + |
598 | + states: [ |
599 | + State { |
600 | + name: "LeftToRight" |
601 | + PropertyChanges { |
602 | + target: mouseArea |
603 | + drag.maximumX: 0 |
604 | + } |
605 | + }, |
606 | + State { |
607 | + name: "RightToLeft" |
608 | + PropertyChanges { |
609 | + target: mouseArea |
610 | + drag.minimumX: 0 |
611 | + } |
612 | + } |
613 | + ] |
614 | + |
615 | + onMouseXChanged: { |
616 | + var offset = (lastX - mouseX) |
617 | + if (Math.abs(offset) <= root.actionThreshold) { |
618 | + return |
619 | + } |
620 | + lastX = mouseX |
621 | + direction = offset > 0 ? "RTL" : "LTR"; |
622 | + } |
623 | + |
624 | + onPressed: { |
625 | + lastX = mouse.x |
626 | + } |
627 | + |
628 | + onReleased: { |
629 | + if (root.triggerActionOnMouseRelease && root.activeAction) { |
630 | + triggerAction.start() |
631 | + } else { |
632 | + root.returnToBounds(direction) |
633 | + root.activeAction = null |
634 | + } |
635 | + lastX = -1 |
636 | + direction = "None" |
637 | + } |
638 | + onClicked: { |
639 | + if (main.x === 0) { |
640 | + root.itemClicked(mouse) |
641 | + } else if (main.x > 0) { |
642 | + var action = getActionAt(Qt.point(mouse.x, mouse.y)) |
643 | + if (action && action !== -1) { |
644 | + action.triggered(root) |
645 | + } |
646 | + } else { |
647 | + var actionIndex = getActionAt(Qt.point(mouse.x, mouse.y)) |
648 | + if (actionIndex !== -1) { |
649 | + root.activeItem = rightActionsRepeater.itemAt(actionIndex) |
650 | + root.activeAction = root._visibleRightSideActions[actionIndex] |
651 | + triggerAction.start() |
652 | + return |
653 | + } |
654 | + } |
655 | + root.resetSwipe() |
656 | + } |
657 | + |
658 | + onPositionChanged: { |
659 | + if (mouseArea.pressed) { |
660 | + updateActiveAction() |
661 | + } |
662 | + } |
663 | + onPressAndHold: { |
664 | + if (main.x === 0) { |
665 | + root.itemPressAndHold(mouse) |
666 | + } |
667 | + } |
668 | + z: -1 |
669 | + } |
670 | +} |
671 | |
672 | === added file 'app/upstreamcomponents/ListItemWithActionsCheckBox.qml' |
673 | --- app/upstreamcomponents/ListItemWithActionsCheckBox.qml 1970-01-01 00:00:00 +0000 |
674 | +++ app/upstreamcomponents/ListItemWithActionsCheckBox.qml 2014-12-08 13:30:38 +0000 |
675 | @@ -0,0 +1,25 @@ |
676 | +/* |
677 | + * Copyright (C) 2012-2014 Canonical, Ltd. |
678 | + * |
679 | + * This program is free software; you can redistribute it and/or modify |
680 | + * it under the terms of the GNU General Public License as published by |
681 | + * the Free Software Foundation; version 3. |
682 | + * |
683 | + * This program is distributed in the hope that it will be useful, |
684 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
685 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
686 | + * GNU General Public License for more details. |
687 | + * |
688 | + * You should have received a copy of the GNU General Public License |
689 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
690 | + */ |
691 | + |
692 | +import QtQuick 2.2 |
693 | +import Ubuntu.Components 1.1 |
694 | + |
695 | +CheckBox { |
696 | + checked: root.selected |
697 | + width: implicitWidth |
698 | + // disable item mouse area to avoid conflicts with parent mouse area |
699 | + __mouseArea.enabled: false |
700 | +} |
701 | |
702 | === modified file 'po/ubuntu-calculator-app.pot' |
703 | --- po/ubuntu-calculator-app.pot 2014-12-04 22:51:08 +0000 |
704 | +++ po/ubuntu-calculator-app.pot 2014-12-08 13:30:38 +0000 |
705 | @@ -21,6 +21,10 @@ |
706 | msgid "NaN" |
707 | msgstr "" |
708 | |
709 | +#: ../app/ubuntu-calculator-app.qml:296 |
710 | +msgid "Delete" |
711 | +msgstr "" |
712 | + |
713 | #: ../app/ui/LandscapeKeyboard.qml:19 ../app/ui/PortraiKeyboard.qml:39 |
714 | msgid "log" |
715 | msgstr "" |
716 | @@ -28,15 +32,3 @@ |
717 | #: ../app/ui/LandscapeKeyboard.qml:26 ../app/ui/PortraiKeyboard.qml:42 |
718 | msgid "mod" |
719 | msgstr "" |
720 | - |
721 | -#: /tmp/tmp.rKpWslWyww/po/ubuntu-calculator-app.desktop.in.h:1 |
722 | -msgid "Calculator" |
723 | -msgstr "" |
724 | - |
725 | -#: /tmp/tmp.rKpWslWyww/po/ubuntu-calculator-app.desktop.in.h:2 |
726 | -msgid "A calculator for Ubuntu." |
727 | -msgstr "" |
728 | - |
729 | -#: /tmp/tmp.rKpWslWyww/po/ubuntu-calculator-app.desktop.in.h:3 |
730 | -msgid "math;addition;subtraction;multiplication;division;" |
731 | -msgstr "" |
Nice work Riccardo!
Instead of storing text to display, we should store formula. It will allow us to edit calculations.
We could also consider (for performance reasons) to store both "formula" and "text to display". But it needs to be tested on device/phone.