Merge lp:~rpadovani/ubuntu-calculator-app/favouriteImplementation20150128 into lp:ubuntu-calculator-app
- favouriteImplementation20150128
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Bartosz Kosiorek |
Approved revision: | 80 |
Merged at revision: | 85 |
Proposed branch: | lp:~rpadovani/ubuntu-calculator-app/favouriteImplementation20150128 |
Merge into: | lp:ubuntu-calculator-app |
Diff against target: |
1341 lines (+940/-297) 5 files modified
app/engine/CalculationHistory.qml (+36/-9) app/ubuntu-calculator-app.qml (+405/-287) app/ui/FavouritePage.qml (+91/-0) app/ui/PortraitKeyboard.qml (+1/-1) app/upstreamcomponents/PageWithBottomEdge.qml (+407/-0) |
To merge this branch: | bzr merge lp:~rpadovani/ubuntu-calculator-app/favouriteImplementation20150128 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ubuntu Phone Apps Jenkins Bot | continuous-integration | Approve | |
Bartosz Kosiorek | Approve | ||
Review via email: mp+247900@code.launchpad.net |
Commit message
Implemented favourite feature as per design.
Description of the change
Implemented favourite feature as per design.
I appreciate the diff is huge, so I suggest to look to the diff of commits 72, 75, and 77
73 is a merge, so I don't think I did damages there
74 is the implementation of pagestack, most of differences are due different tabulation
77 is the creation of PageWithBottomEdge. I imported it from upstream, so there shouldn't be errors here
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
Bartosz Kosiorek (gang65) wrote : | # |
Thanks Riccardo.
I'm impressed with the work you made.
You have added scrollable TextField! It is huge improvement.
Some first look remarks:
1. During adding I missed button to confirm favourite description.
2. The star could change colour after pressing. Maybe yellow or even blue, it is up to you.
3. We really need some autopilot tests for that. Please create ticket for that after merge.
Did you change PageWithBottomE
In my opinion we should integrate this branch to get feedback from users and UX designers.
Riccardo Padovani (rpadovani) wrote : | # |
> Some first look remarks:
> 1. During adding I missed button to confirm favourite description.
Added
> 2. The star could change colour after pressing. Maybe yellow or even blue, it
> is up to you.
I tried with Ubuntu Orange - what do you think? :-)
> 3. We really need some autopilot tests for that. Please create ticket for that
> after merge.
Yes, I'm going to open bugs
> Did you change PageWithBottomE
It is the default one
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
PASSED: Continuous integration, rev:78
http://
Executed test runs:
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Bartosz Kosiorek (gang65) wrote : | # |
Looks ok to me.
Thanks Riccardo
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
FAILED: Autolanding.
More details in the following jenkins job:
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
- 79. By Riccardo Padovani
-
Merged from trunk
- 80. By Riccardo Padovani
-
Fixing buttonRatio
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
PASSED: Continuous integration, rev:80
http://
Executed test runs:
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Preview Diff
1 | === modified file 'app/engine/CalculationHistory.qml' |
2 | --- app/engine/CalculationHistory.qml 2015-01-15 13:45:19 +0000 |
3 | +++ app/engine/CalculationHistory.qml 2015-01-30 10:41:41 +0000 |
4 | @@ -25,6 +25,14 @@ |
5 | |
6 | Component.onCompleted: { |
7 | getCalculations(function(calc) { |
8 | + // Also if isFavourite is set as BOOL, LocalStorage saves it as |
9 | + // int, so we need to convert it before adding the calc to |
10 | + // the history |
11 | + if (calc.isFavourite === 1) { |
12 | + calc.isFavourite = true; |
13 | + } else { |
14 | + calc.isFavourite = false; |
15 | + } |
16 | history.append(calc); |
17 | }); |
18 | } |
19 | @@ -34,7 +42,7 @@ |
20 | formula: '' |
21 | result: '' |
22 | date: 0 |
23 | - isFavourite: 0 |
24 | + isFavourite: false |
25 | favouriteText: '' |
26 | } |
27 | } |
28 | @@ -104,7 +112,7 @@ |
29 | ); |
30 | } |
31 | |
32 | - function addCalculationToScreen(formula, result) { |
33 | + function addCalculationToScreen(formula, result, isFavourite, favouriteText) { |
34 | // The function add the last formula to the model, and leave to |
35 | // addCalculationToDatabase the job to add it to the database |
36 | // that is called only after the element has been added to the |
37 | @@ -113,27 +121,25 @@ |
38 | history.append({"formula": formula, |
39 | "result": result, |
40 | "date": date, |
41 | - "isFavourite": 0, |
42 | - "favouriteText": ''}); |
43 | - |
44 | + "isFavourite": isFavourite, |
45 | + "favouriteText": favouriteText}); |
46 | var index = history.count - 1; |
47 | // TODO: move this function to a plave that retards the execution to |
48 | // improve performances |
49 | timer.execute.push(function() { |
50 | - calculationHistory.addCalculationToDatabase(formula, result, date, index); |
51 | + calculationHistory.addCalculationToDatabase(formula, result, date, index, isFavourite, favouriteText); |
52 | }); |
53 | timer.start(); |
54 | } |
55 | |
56 | - function addCalculationToDatabase(formula, result, date, index) { |
57 | + function addCalculationToDatabase(formula, result, date, index, isFavourite, favouriteText) { |
58 | openDatabase(); |
59 | - |
60 | calculationHistoryDatabase.transaction( |
61 | function (tx) { |
62 | var results = tx.executeSql('INSERT INTO Calculations ( |
63 | formula, result, date, isFavourite, favouriteText) VALUES( |
64 | ?, ?, ?, ?, ?)', |
65 | - [formula, result, date, false, ''] |
66 | + [formula, result, date, isFavourite, favouriteText] |
67 | ); |
68 | // we need to update the listmodel unless we would have dbId = 0 on the |
69 | // last inserted item |
70 | @@ -160,4 +166,25 @@ |
71 | }); |
72 | timer.start(); |
73 | } |
74 | + |
75 | + function removeFavourites(removedFavourites) { |
76 | + openDatabase(); |
77 | + var sql = "UPDATE Calculations SET isFavourite = 'false' WHERE dbId IN ("; |
78 | + var removed = removedFavourites[0]; |
79 | + history.setProperty(removedFavourites[0], "isFavourite", false); |
80 | + removedFavourites.splice(0, 1); |
81 | + |
82 | + for (var index in removedFavourites) { |
83 | + history.setProperty(removedFavourites[index], "isFavourite", false); |
84 | + removed += "," + removedFavourites[index]; |
85 | + } |
86 | + |
87 | + sql += removed + ")"; |
88 | + |
89 | + calculationHistoryDatabase.transaction( |
90 | + function (tx) { |
91 | + var result = tx.executeSql(sql); |
92 | + } |
93 | + ); |
94 | + } |
95 | } |
96 | |
97 | === modified file 'app/ubuntu-calculator-app.qml' |
98 | --- app/ubuntu-calculator-app.qml 2015-01-30 09:42:00 +0000 |
99 | +++ app/ubuntu-calculator-app.qml 2015-01-30 10:41:41 +0000 |
100 | @@ -62,33 +62,12 @@ |
101 | |
102 | property var decimalPoint: Qt.locale().decimalPoint |
103 | |
104 | + // Var used to save favourite calcs |
105 | + property bool isFavourite: false |
106 | + |
107 | // By default we delete selected calculation from history |
108 | property bool deleteSelectedCalculation: true; |
109 | |
110 | - state: visualModel.isInSelectionMode ? "selection" : "default" |
111 | - states: [ |
112 | - State { |
113 | - name: "default" |
114 | - StateChangeScript { |
115 | - script: header.hide() |
116 | - } |
117 | - PropertyChanges { |
118 | - target: scrollableView |
119 | - clip: false |
120 | - } |
121 | - }, |
122 | - State { |
123 | - name: "selection" |
124 | - StateChangeScript { |
125 | - script: header.show() |
126 | - } |
127 | - PropertyChanges { |
128 | - target: scrollableView |
129 | - clip: true |
130 | - } |
131 | - } |
132 | - ] |
133 | - |
134 | /** |
135 | * The function calls the Formula.deleteLastFormulaElement function and |
136 | * place the result in right vars |
137 | @@ -208,281 +187,420 @@ |
138 | } |
139 | |
140 | |
141 | - calculationHistory.addCalculationToScreen(longFormula, result); |
142 | + if (!isFavourite) { |
143 | + favouriteTextField.text = ""; |
144 | + } |
145 | + |
146 | + calculationHistory.addCalculationToScreen(longFormula, result, isFavourite, favouriteTextField.text); |
147 | longFormula = result; |
148 | shortFormula = result; |
149 | + favouriteTextField.text = ""; |
150 | + isFavourite = false; |
151 | displayedInputText = result; |
152 | } |
153 | |
154 | - CalculationHistory { |
155 | - id: calculationHistory |
156 | - } |
157 | - |
158 | - Keys.onPressed: { |
159 | - keyboardLoader.item.pressedKey = event.key; |
160 | - keyboardLoader.item.pressedKeyText = event.text; |
161 | - } |
162 | - |
163 | - Keys.onReleased: { |
164 | - keyboardLoader.item.pressedKey = -1; |
165 | - keyboardLoader.item.pressedKeyText = ""; |
166 | - } |
167 | - |
168 | - Header { |
169 | - id: header |
170 | - visible: true |
171 | - useDeprecatedToolbar: false |
172 | - property color dividerColor: "#babbbc" |
173 | - property color panelColor: "white" |
174 | - config: PageHeadConfiguration { |
175 | - backAction: Action { |
176 | - objectName: "cancelSelectionAction" |
177 | - iconName: "close" |
178 | - text: i18n.tr("Cancel") |
179 | - onTriggered: visualModel.cancelSelection() |
180 | + PageStack { |
181 | + id: mainStack |
182 | + |
183 | + Component.onCompleted: push(calculatorPage) |
184 | + |
185 | + PageWithBottomEdge { |
186 | + id: calculatorPage |
187 | + |
188 | + bottomEdgeTitle: i18n.tr("Favorite") |
189 | + |
190 | + bottomEdgePageComponent: FavouritePage { |
191 | + anchors.fill: parent |
192 | + |
193 | + title: i18n.tr("Favorite") |
194 | } |
195 | - actions: [ |
196 | - Action { |
197 | - id: selectAllAction |
198 | - objectName: "selectAllAction" |
199 | - iconName: "select" |
200 | - text: i18n.tr("Select All") |
201 | - onTriggered: visualModel.selectAll() |
202 | - }, |
203 | - Action { |
204 | - id: copySelectedAction |
205 | - objectName: "copySelectedAction" |
206 | - iconName: "edit-copy" |
207 | - text: i18n.tr("Copy") |
208 | - onTriggered: copySelectedCalculations() |
209 | - }, |
210 | - Action { |
211 | - id: multiDeleteAction |
212 | - objectName: "multiDeleteAction" |
213 | - iconName: "delete" |
214 | - text: i18n.tr("Delete") |
215 | - onTriggered: deleteSelectedCalculations() |
216 | + |
217 | + state: visualModel.isInSelectionMode ? "selection" : "default" |
218 | + states: [ |
219 | + State { |
220 | + name: "default" |
221 | + StateChangeScript { |
222 | + script: header.hide() |
223 | + } |
224 | + PropertyChanges { |
225 | + target: scrollableView |
226 | + clip: false |
227 | + } |
228 | + }, |
229 | + State { |
230 | + name: "selection" |
231 | + StateChangeScript { |
232 | + script: header.show() |
233 | + } |
234 | + PropertyChanges { |
235 | + target: scrollableView |
236 | + clip: true |
237 | + } |
238 | } |
239 | ] |
240 | - } |
241 | - } |
242 | - |
243 | - Component { |
244 | - id: emptyDelegate |
245 | - Item { } |
246 | - } |
247 | - |
248 | - Component { |
249 | - id: screenDelegateComponent |
250 | - Screen { |
251 | - id: screenDelegate |
252 | - width: parent ? parent.width : 0 |
253 | - |
254 | - property var model: itemModel |
255 | - visible: model.dbId !== -1 |
256 | - |
257 | - selectionMode: visualModel.isInSelectionMode |
258 | - selected: visualModel.isSelected(visualDelegate) |
259 | - |
260 | - property var removalAnimation |
261 | - function remove() { |
262 | - removalAnimation.start(); |
263 | - } |
264 | - |
265 | - // parent is the loader component |
266 | - property var visualDelegate: parent ? parent : null |
267 | - |
268 | - onSwippingChanged: { |
269 | - visualModel.updateSwipeState(screenDelegate); |
270 | - } |
271 | - |
272 | - onSwipeStateChanged: { |
273 | - visualModel.updateSwipeState(screenDelegate); |
274 | - } |
275 | - |
276 | - onItemClicked: { |
277 | - if (visualModel.isInSelectionMode) { |
278 | - if (!visualModel.selectItem(visualDelegate)) { |
279 | - visualModel.deselectItem(visualDelegate); |
280 | - } |
281 | - } |
282 | - } |
283 | - |
284 | - onItemPressAndHold: { |
285 | - visualModel.startSelection(); |
286 | - visualModel.selectItem(visualDelegate); |
287 | - } |
288 | - |
289 | - rightSideActions: [ screenDelegateCopyAction.item ] |
290 | - leftSideAction: screenDelegateDeleteAction.item |
291 | - |
292 | - Loader { |
293 | - id: screenDelegateCopyAction |
294 | - sourceComponent: Action { |
295 | - iconName: "edit-copy" |
296 | - text: i18n.tr("Copy") |
297 | - onTriggered: { |
298 | + |
299 | + CalculationHistory { |
300 | + id: calculationHistory |
301 | + } |
302 | + |
303 | + Keys.onPressed: { |
304 | + keyboardLoader.item.pressedKey = event.key; |
305 | + keyboardLoader.item.pressedKeyText = event.text; |
306 | + } |
307 | + |
308 | + Keys.onReleased: { |
309 | + keyboardLoader.item.pressedKey = -1; |
310 | + keyboardLoader.item.pressedKeyText = ""; |
311 | + } |
312 | + |
313 | + Header { |
314 | + id: header |
315 | + visible: true |
316 | + useDeprecatedToolbar: false |
317 | + property color dividerColor: "#babbbc" |
318 | + property color panelColor: "white" |
319 | + config: PageHeadConfiguration { |
320 | + backAction: Action { |
321 | + objectName: "cancelSelectionAction" |
322 | + iconName: "close" |
323 | + text: i18n.tr("Cancel") |
324 | + onTriggered: visualModel.cancelSelection() |
325 | + } |
326 | + actions: [ |
327 | + Action { |
328 | + id: selectAllAction |
329 | + objectName: "selectAllAction" |
330 | + iconName: "select" |
331 | + text: i18n.tr("Select All") |
332 | + onTriggered: visualModel.selectAll() |
333 | + }, |
334 | + Action { |
335 | + id: copySelectedAction |
336 | + objectName: "copySelectedAction" |
337 | + iconName: "edit-copy" |
338 | + text: i18n.tr("Copy") |
339 | + onTriggered: copySelectedCalculations() |
340 | + }, |
341 | + Action { |
342 | + id: multiDeleteAction |
343 | + objectName: "multiDeleteAction" |
344 | + iconName: "delete" |
345 | + text: i18n.tr("Delete") |
346 | + onTriggered: deleteSelectedCalculations() |
347 | + } |
348 | + ] |
349 | + } |
350 | + } |
351 | + |
352 | + Component { |
353 | + id: emptyDelegate |
354 | + Item { } |
355 | + } |
356 | + |
357 | + Component { |
358 | + id: screenDelegateComponent |
359 | + Screen { |
360 | + id: screenDelegate |
361 | + width: parent ? parent.width : 0 |
362 | + |
363 | + property var model: itemModel |
364 | + visible: model.dbId !== -1 |
365 | + |
366 | + selectionMode: visualModel.isInSelectionMode |
367 | + selected: visualModel.isSelected(visualDelegate) |
368 | + |
369 | + property var removalAnimation |
370 | + function remove() { |
371 | + removalAnimation.start(); |
372 | + } |
373 | + |
374 | + // parent is the loader component |
375 | + property var visualDelegate: parent ? parent : null |
376 | + |
377 | + onSwippingChanged: { |
378 | + visualModel.updateSwipeState(screenDelegate); |
379 | + } |
380 | + |
381 | + onSwipeStateChanged: { |
382 | + visualModel.updateSwipeState(screenDelegate); |
383 | + } |
384 | + |
385 | + onItemClicked: { |
386 | + if (visualModel.isInSelectionMode) { |
387 | + if (!visualModel.selectItem(visualDelegate)) { |
388 | + visualModel.deselectItem(visualDelegate); |
389 | + } |
390 | + } |
391 | + } |
392 | + |
393 | + onItemPressAndHold: { |
394 | + visualModel.startSelection(); |
395 | + visualModel.selectItem(visualDelegate); |
396 | + } |
397 | + |
398 | + rightSideActions: [ screenDelegateCopyAction.item ] |
399 | + leftSideAction: screenDelegateDeleteAction.item |
400 | + |
401 | + Loader { |
402 | + id: screenDelegateCopyAction |
403 | + sourceComponent: Action { |
404 | + iconName: "edit-copy" |
405 | + text: i18n.tr("Copy") |
406 | + onTriggered: { |
407 | + var mimeData = Clipboard.newData(); |
408 | + mimeData.text = model.formula + "=" + model.result; |
409 | + Clipboard.push(mimeData); |
410 | + } |
411 | + } |
412 | + } |
413 | + |
414 | + Loader { |
415 | + id: screenDelegateDeleteAction |
416 | + sourceComponent: Action { |
417 | + iconName: "delete" |
418 | + text: i18n.tr("Delete") |
419 | + onTriggered: { |
420 | + screenDelegate.remove(); |
421 | + } |
422 | + } |
423 | + } |
424 | + |
425 | + removalAnimation: SequentialAnimation { |
426 | + alwaysRunToEnd: true |
427 | + |
428 | + ScriptAction { |
429 | + script: { |
430 | + if (visualModel.currentSwipedItem === screenDelegate) { |
431 | + visualModel.currentSwipedItem = null; |
432 | + } |
433 | + } |
434 | + } |
435 | + |
436 | + UbuntuNumberAnimation { |
437 | + target: screenDelegate |
438 | + property: "height" |
439 | + to: 0 |
440 | + } |
441 | + |
442 | + ScriptAction { |
443 | + script: { |
444 | + calculationHistory.deleteCalc(model.dbId, model.index); |
445 | + } |
446 | + } |
447 | + } |
448 | + } |
449 | + } |
450 | + |
451 | + function deleteSelectedCalculations() { |
452 | + deleteSelectedCalculation = true; |
453 | + visualModel.endSelection(); |
454 | + } |
455 | + |
456 | + function copySelectedCalculations() { |
457 | + deleteSelectedCalculation = false; |
458 | + visualModel.endSelection(); |
459 | + } |
460 | + |
461 | + MultipleSelectionVisualModel { |
462 | + id: visualModel |
463 | + model: calculationHistory.getContents() |
464 | + |
465 | + onSelectionDone: { |
466 | + if(deleteSelectedCalculation === true) { |
467 | + for(var i = 0; i < items.count; i++) { |
468 | + calculationHistory.deleteCalc(items.get(i).model.dbId, items.get(i).model.index); |
469 | + } |
470 | + } else { |
471 | var mimeData = Clipboard.newData(); |
472 | - mimeData.text = model.formula + "=" + model.result; |
473 | + mimeData.text = ""; |
474 | + for(var j = 0; j < items.count; j++) { |
475 | + if (items.get(j).model.dbId !== -1) { |
476 | + mimeData.text = mimeData.text + items.get(j).model.formula + "=" + items.get(j).model.result + "\n"; |
477 | + } |
478 | + } |
479 | Clipboard.push(mimeData); |
480 | } |
481 | } |
482 | - } |
483 | - |
484 | - Loader { |
485 | - id: screenDelegateDeleteAction |
486 | - sourceComponent: Action { |
487 | - iconName: "delete" |
488 | - text: i18n.tr("Delete") |
489 | - onTriggered: { |
490 | - screenDelegate.remove(); |
491 | - } |
492 | - } |
493 | - } |
494 | - |
495 | - removalAnimation: SequentialAnimation { |
496 | - alwaysRunToEnd: true |
497 | - |
498 | - ScriptAction { |
499 | - script: { |
500 | - if (visualModel.currentSwipedItem === screenDelegate) { |
501 | - visualModel.currentSwipedItem = null; |
502 | - } |
503 | - } |
504 | - } |
505 | - |
506 | - UbuntuNumberAnimation { |
507 | - target: screenDelegate |
508 | - property: "height" |
509 | - to: 0 |
510 | - } |
511 | - |
512 | - ScriptAction { |
513 | - script: { |
514 | - calculationHistory.deleteCalc(model.dbId, model.index); |
515 | - } |
516 | - } |
517 | - } |
518 | - } |
519 | - } |
520 | - |
521 | - function deleteSelectedCalculations() { |
522 | - deleteSelectedCalculation = true; |
523 | - visualModel.endSelection(); |
524 | - } |
525 | - |
526 | - function copySelectedCalculations() { |
527 | - deleteSelectedCalculation = false; |
528 | - visualModel.endSelection(); |
529 | - } |
530 | - |
531 | - MultipleSelectionVisualModel { |
532 | - id: visualModel |
533 | - model: calculationHistory.getContents() |
534 | - |
535 | - onSelectionDone: { |
536 | - if(deleteSelectedCalculation === true) { |
537 | - for(var i = 0; i < items.count; i++) { |
538 | - calculationHistory.deleteCalc(items.get(i).model.dbId, items.get(i).model.index); |
539 | - } |
540 | - } else { |
541 | - var mimeData = Clipboard.newData(); |
542 | - mimeData.text = ""; |
543 | - for(var j = 0; j < items.count; j++) { |
544 | - if (items.get(j).model.dbId !== -1) { |
545 | - mimeData.text = mimeData.text + items.get(j).model.formula + "=" + items.get(j).model.result + "\n"; |
546 | - } |
547 | - } |
548 | - Clipboard.push(mimeData); |
549 | - } |
550 | - } |
551 | - |
552 | - delegate: Component { |
553 | - Loader { |
554 | - property var itemModel: model |
555 | - width: parent.width |
556 | - height: model.dbId !== -1 ? item.height : 0; |
557 | - sourceComponent: screenDelegateComponent |
558 | - opacity: ((y + height) >= scrollableView.contentY) && (y <= (scrollableView.contentY + scrollableView.height)) ? 1 : 0 |
559 | - onOpacityChanged: { |
560 | - if (this.hasOwnProperty('item') && this.item !== null) { |
561 | - if (opacity > 0) { |
562 | - sourceComponent = screenDelegateComponent; |
563 | - } else { |
564 | - this.item.visible = false; |
565 | - sourceComponent = emptyDelegate; |
566 | - } |
567 | - } |
568 | - } |
569 | - } |
570 | - } |
571 | - } |
572 | - |
573 | - ScrollableView { |
574 | - anchors { |
575 | - top: header.bottom |
576 | - bottom: parent.bottom |
577 | - left: parent.left |
578 | - right: parent.right |
579 | - } |
580 | - id: scrollableView |
581 | - objectName: "scrollableView" |
582 | - |
583 | - Component.onCompleted: { |
584 | - // FIXME: workaround for qtubuntu not returning values depending on the grid unit definition |
585 | - // for Flickable.maximumFlickVelocity and Flickable.flickDeceleration |
586 | - var scaleFactor = units.gridUnit / 8; |
587 | - maximumFlickVelocity = maximumFlickVelocity * scaleFactor; |
588 | - flickDeceleration = flickDeceleration * scaleFactor; |
589 | - } |
590 | - |
591 | - Repeater { |
592 | - id: formulaView |
593 | - model: visualModel |
594 | - } |
595 | - |
596 | - TextField { |
597 | - id: textInputField |
598 | - objectName: "textInputField" |
599 | - width: contentWidth + units.gu(3) |
600 | - // TODO: Make sure this bug gets fixed in SDK: |
601 | - // https://bugs.launchpad.net/ubuntu/+source/ubuntu-ui-toolkit/+bug/1320885 |
602 | - //width: parent.width |
603 | - height: units.gu(6) |
604 | - |
605 | - // remove ubuntu shape |
606 | - style: TextFieldStyle { |
607 | - background: Item { |
608 | - } |
609 | - } |
610 | - |
611 | - text: Formula.returnFormulaToDisplay(displayedInputText) |
612 | - font.pixelSize: height * 0.7 |
613 | - //horizontalAlignment: TextInput.AlignRight |
614 | - anchors { |
615 | - right: parent.right |
616 | - rightMargin: units.gu(1) |
617 | - } |
618 | - |
619 | - readOnly: true |
620 | - selectByMouse: true |
621 | - cursorVisible: true |
622 | - onCursorPositionChanged: |
623 | - if (cursorPosition !== length ) { |
624 | - // Count cursor position from the end of line |
625 | - var preservedCursorPosition = length - cursorPosition; |
626 | - displayedInputText = longFormula; |
627 | - cursorPosition = length - preservedCursorPosition; |
628 | - } else { |
629 | - displayedInputText = shortFormula; |
630 | - } |
631 | - } |
632 | - |
633 | - Loader { |
634 | - id: keyboardLoader |
635 | - width: parent.width |
636 | - source: scrollableView.width > scrollableView.height ? "ui/LandscapeKeyboard.qml" : "ui/PortraitKeyboard.qml" |
637 | - opacity: ((y+height) >= scrollableView.contentY) && (y <= (scrollableView.contentY + scrollableView.height)) ? 1 : 0 |
638 | + |
639 | + delegate: Component { |
640 | + Loader { |
641 | + property var itemModel: model |
642 | + width: parent.width |
643 | + height: model.dbId !== -1 ? item.height : 0; |
644 | + sourceComponent: screenDelegateComponent |
645 | + opacity: ((y + height) >= scrollableView.contentY) && (y <= (scrollableView.contentY + scrollableView.height)) ? 1 : 0 |
646 | + onOpacityChanged: { |
647 | + if (this.hasOwnProperty('item') && this.item !== null) { |
648 | + if (opacity > 0) { |
649 | + sourceComponent = screenDelegateComponent; |
650 | + } else { |
651 | + this.item.visible = false; |
652 | + sourceComponent = emptyDelegate; |
653 | + } |
654 | + } |
655 | + } |
656 | + } |
657 | + } |
658 | + } |
659 | + |
660 | + ScrollableView { |
661 | + anchors { |
662 | + top: header.bottom |
663 | + bottom: parent.bottom |
664 | + left: parent.left |
665 | + right: parent.right |
666 | + } |
667 | + id: scrollableView |
668 | + objectName: "scrollableView" |
669 | + |
670 | + Component.onCompleted: { |
671 | + // FIXME: workaround for qtubuntu not returning values depending on the grid unit definition |
672 | + // for Flickable.maximumFlickVelocity and Flickable.flickDeceleration |
673 | + var scaleFactor = units.gridUnit / 8; |
674 | + maximumFlickVelocity = maximumFlickVelocity * scaleFactor; |
675 | + flickDeceleration = flickDeceleration * scaleFactor; |
676 | + } |
677 | + |
678 | + Repeater { |
679 | + id: formulaView |
680 | + model: visualModel |
681 | + } |
682 | + |
683 | + Rectangle { |
684 | + width: parent.width |
685 | + height: units.gu(6) |
686 | + |
687 | + Icon { |
688 | + id: favouriteIcon |
689 | + height: parent.height - units.gu(2) |
690 | + width: height |
691 | + |
692 | + anchors { |
693 | + left: parent.left |
694 | + leftMargin: units.gu(1) |
695 | + top: parent.top |
696 | + topMargin: units.gu(1) |
697 | + } |
698 | + |
699 | + name: isFavourite ? "starred" : "non-starred" |
700 | + color: isFavourite ? "#dd4814" : "#808080" |
701 | + |
702 | + MouseArea { |
703 | + anchors.fill: parent |
704 | + onClicked: { |
705 | + if (isFavourite) { |
706 | + textInputField.visible = true; |
707 | + textInputField.forceActiveFocus(); |
708 | + } else { |
709 | + textInputField.visible = false; |
710 | + favouriteTextField.forceActiveFocus(); |
711 | + } |
712 | + isFavourite = !isFavourite; |
713 | + } |
714 | + } |
715 | + } |
716 | + |
717 | + TextField { |
718 | + id: favouriteTextField |
719 | + |
720 | + anchors { |
721 | + right: confirmFavourite.left |
722 | + rightMargin: units.gu(1) |
723 | + } |
724 | + width: parent.width - favouriteIcon.width - confirmFavourite.width - units.gu(3) |
725 | + height: parent.height |
726 | + visible: !textInputField.visible |
727 | + |
728 | + font.italic: true |
729 | + font.pixelSize: height * 0.5 |
730 | + verticalAlignment: TextInput.AlignVCenter |
731 | + |
732 | + // TRANSLATORS: this is a time formatting string, see |
733 | + // http://qt-project.org/doc/qt-5/qml-qtqml-date.html#details for |
734 | + // valid expressions |
735 | + placeholderText: Qt.formatDateTime(new Date(), i18n.tr("dd MMM yyyy")) |
736 | + |
737 | + // remove ubuntu shape |
738 | + style: TextFieldStyle { |
739 | + background: Item { |
740 | + } |
741 | + } |
742 | + |
743 | + InverseMouseArea { |
744 | + anchors.fill: parent |
745 | + |
746 | + onClicked: { |
747 | + textInputField.visible = true; |
748 | + textInputField.forceActiveFocus(); |
749 | + } |
750 | + } |
751 | + } |
752 | + |
753 | + Icon { |
754 | + id: confirmFavourite |
755 | + visible: favouriteTextField.visible |
756 | + |
757 | + name: "keyboard-enter" |
758 | + |
759 | + anchors { |
760 | + right: parent.right |
761 | + rightMargin: units.gu(1) |
762 | + top: parent.top |
763 | + topMargin: units.gu(1) |
764 | + } |
765 | + |
766 | + height: parent.height - units.gu(2) |
767 | + width: height |
768 | + } |
769 | + |
770 | + TextField { |
771 | + id: textInputField |
772 | + objectName: "textInputField" |
773 | + // TODO: Make sure this bug gets fixed in SDK: |
774 | + // https://bugs.launchpad.net/ubuntu/+source/ubuntu-ui-toolkit/+bug/1320885 |
775 | + // It has been fixed in vivid - wait until it becomes the stable |
776 | + // version before removing this |
777 | + width: parent.width - favouriteIcon.width - units.gu(2) |
778 | + //width: Math.min(contentWidth + units.gu(3), parent.width - favouriteIcon.width - units.gu(2)) |
779 | + height: parent.height |
780 | + |
781 | + // remove ubuntu shape |
782 | + style: TextFieldStyle { |
783 | + background: Item { |
784 | + } |
785 | + } |
786 | + |
787 | + text: Formula.returnFormulaToDisplay(displayedInputText) |
788 | + font.pixelSize: height * 0.7 |
789 | + horizontalAlignment: TextInput.AlignRight |
790 | + anchors { |
791 | + right: parent.right |
792 | + rightMargin: units.gu(1) |
793 | + } |
794 | + |
795 | + readOnly: true |
796 | + selectByMouse: true |
797 | + cursorVisible: true |
798 | + onCursorPositionChanged: |
799 | + if (cursorPosition !== length ) { |
800 | + // Count cursor position from the end of line |
801 | + var preservedCursorPosition = length - cursorPosition; |
802 | + displayedInputText = longFormula; |
803 | + cursorPosition = length - preservedCursorPosition; |
804 | + } else { |
805 | + displayedInputText = shortFormula; |
806 | + } |
807 | + } |
808 | + } |
809 | + |
810 | + Loader { |
811 | + id: keyboardLoader |
812 | + width: parent.width |
813 | + visible: textInputField.visible |
814 | + source: scrollableView.width > scrollableView.height ? "ui/LandscapeKeyboard.qml" : "ui/PortraitKeyboard.qml" |
815 | + opacity: ((y+height) >= scrollableView.contentY) && (y <= (scrollableView.contentY + scrollableView.height)) ? 1 : 0 |
816 | + } |
817 | + } |
818 | } |
819 | } |
820 | } |
821 | |
822 | === added file 'app/ui/FavouritePage.qml' |
823 | --- app/ui/FavouritePage.qml 1970-01-01 00:00:00 +0000 |
824 | +++ app/ui/FavouritePage.qml 2015-01-30 10:41:41 +0000 |
825 | @@ -0,0 +1,91 @@ |
826 | +/* |
827 | + * Copyright (C) 2015 Canonical Ltd |
828 | + * |
829 | + * This file is part of Ubuntu Calculator App |
830 | + * |
831 | + * Ubuntu Calculator App is free software: you can redistribute it and/or modify |
832 | + * it under the terms of the GNU General Public License version 3 as |
833 | + * published by the Free Software Foundation. |
834 | + * |
835 | + * Ubuntu Calculator App is distributed in the hope that it will be useful, |
836 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
837 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
838 | + * GNU General Public License for more details. |
839 | + * |
840 | + * You should have received a copy of the GNU General Public License |
841 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
842 | + */ |
843 | +import QtQuick 2.3 |
844 | +import QtQuick.Layouts 1.1 |
845 | +import Ubuntu.Components 1.1 |
846 | +import Ubuntu.Components.ListItems 1.0 as ListItem |
847 | + |
848 | +import "../engine" |
849 | + |
850 | +Page { |
851 | + anchors.fill: parent |
852 | + |
853 | + property var removedFavourites: [] |
854 | + |
855 | + head.backAction: Action { |
856 | + iconName: "back" |
857 | + onTriggered: { |
858 | + if (removedFavourites.length > 0) { |
859 | + calculationHistory.removeFavourites(removedFavourites); |
860 | + } |
861 | + mainStack.pop(); |
862 | + } |
863 | + } |
864 | + |
865 | + ListView { |
866 | + id: favouriteListview |
867 | + anchors.fill: parent |
868 | + model: calculationHistory.getContents(); |
869 | + |
870 | + delegate: ListItem.Empty { |
871 | + visible: model.isFavourite |
872 | + height: visible ? units.gu(6) : 0 |
873 | + |
874 | + MouseArea { |
875 | + anchors.fill: parent |
876 | + |
877 | + onClicked: { |
878 | + if (favouriteIcon.name == "starred") { |
879 | + favouriteIcon.name = "non-starred"; |
880 | + removedFavourites.push(model.dbId); |
881 | + } |
882 | + else { |
883 | + favouriteIcon.name = "starred"; |
884 | + removedFavourites.splice(removedFavourites.indexOf(model.dbId), 1); |
885 | + } |
886 | + } |
887 | + } |
888 | + |
889 | + RowLayout { |
890 | + height: units.gu(5) |
891 | + spacing: units.gu(2) |
892 | + width: parent.width - units.gu(4) |
893 | + anchors.horizontalCenter: parent.horizontalCenter |
894 | + Icon { |
895 | + id: favouriteIcon |
896 | + height: parent.height - units.gu(2) |
897 | + width: height |
898 | + |
899 | + Layout.alignment: Qt.AlignVCenter |
900 | + |
901 | + name: "starred" |
902 | + } |
903 | + |
904 | + Text { |
905 | + text: model.favouriteText |
906 | + Layout.fillWidth: true |
907 | + } |
908 | + |
909 | + Text { |
910 | + text: model.result |
911 | + font.bold: true |
912 | + } |
913 | + } |
914 | + } |
915 | + } |
916 | +} |
917 | |
918 | === modified file 'app/ui/PortraitKeyboard.qml' |
919 | --- app/ui/PortraitKeyboard.qml 2015-01-29 22:17:33 +0000 |
920 | +++ app/ui/PortraitKeyboard.qml 2015-01-30 10:41:41 +0000 |
921 | @@ -31,7 +31,7 @@ |
922 | } |
923 | |
924 | KeyboardPage { |
925 | - buttonRatio: 0.7 |
926 | + buttonRatio: 0.6 |
927 | buttonMaxHeight: scrollableView.height / 10.0 |
928 | |
929 | keyboardModel: new Array( |
930 | |
931 | === added file 'app/upstreamcomponents/PageWithBottomEdge.qml' |
932 | --- app/upstreamcomponents/PageWithBottomEdge.qml 1970-01-01 00:00:00 +0000 |
933 | +++ app/upstreamcomponents/PageWithBottomEdge.qml 2015-01-30 10:41:41 +0000 |
934 | @@ -0,0 +1,407 @@ |
935 | +/* |
936 | + * Copyright (C) 2014 Canonical, Ltd. |
937 | + * |
938 | + * This program is free software; you can redistribute it and/or modify |
939 | + * it under the terms of the GNU General Public License as published by |
940 | + * the Free Software Foundation; version 3. |
941 | + * |
942 | + * This program is distributed in the hope that it will be useful, |
943 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
944 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
945 | + * GNU General Public License for more details. |
946 | + * |
947 | + * You should have received a copy of the GNU General Public License |
948 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
949 | + */ |
950 | + |
951 | +/* |
952 | + Example: |
953 | + |
954 | + MainView { |
955 | + objectName: "mainView" |
956 | + |
957 | + applicationName: "com.ubuntu.developer.boiko.bottomedge" |
958 | + |
959 | + width: units.gu(100) |
960 | + height: units.gu(75) |
961 | + |
962 | + Component { |
963 | + id: pageComponent |
964 | + |
965 | + PageWithBottomEdge { |
966 | + id: mainPage |
967 | + title: i18n.tr("Main Page") |
968 | + |
969 | + Rectangle { |
970 | + anchors.fill: parent |
971 | + color: "white" |
972 | + } |
973 | + |
974 | + bottomEdgePageComponent: Page { |
975 | + title: "Contents" |
976 | + anchors.fill: parent |
977 | + //anchors.topMargin: contentsPage.flickable.contentY |
978 | + |
979 | + ListView { |
980 | + anchors.fill: parent |
981 | + model: 50 |
982 | + delegate: ListItems.Standard { |
983 | + text: "One Content Item: " + index |
984 | + } |
985 | + } |
986 | + } |
987 | + bottomEdgeTitle: i18n.tr("Bottom edge action") |
988 | + } |
989 | + } |
990 | + |
991 | + PageStack { |
992 | + id: stack |
993 | + Component.onCompleted: stack.push(pageComponent) |
994 | + } |
995 | + } |
996 | + |
997 | +*/ |
998 | + |
999 | +import QtQuick 2.2 |
1000 | +import Ubuntu.Components 1.1 |
1001 | + |
1002 | +Page { |
1003 | + id: page |
1004 | + |
1005 | + property alias bottomEdgePageComponent: edgeLoader.sourceComponent |
1006 | + property alias bottomEdgePageSource: edgeLoader.source |
1007 | + property alias bottomEdgeTitle: tipLabel.text |
1008 | + property bool bottomEdgeEnabled: true |
1009 | + property int bottomEdgeExpandThreshold: page.height * 0.2 |
1010 | + property int bottomEdgeExposedArea: bottomEdge.state !== "expanded" ? (page.height - bottomEdge.y - bottomEdge.tipHeight) : _areaWhenExpanded |
1011 | + property bool reloadBottomEdgePage: true |
1012 | + |
1013 | + readonly property alias bottomEdgePage: edgeLoader.item |
1014 | + readonly property bool isReady: ((bottomEdge.y === 0) && bottomEdgePageLoaded && edgeLoader.item.active) |
1015 | + readonly property bool isCollapsed: (bottomEdge.y === page.height) |
1016 | + readonly property bool bottomEdgePageLoaded: (edgeLoader.status == Loader.Ready) |
1017 | + |
1018 | + property bool _showEdgePageWhenReady: false |
1019 | + property int _areaWhenExpanded: 0 |
1020 | + |
1021 | + signal bottomEdgeReleased() |
1022 | + signal bottomEdgeDismissed() |
1023 | + |
1024 | + |
1025 | + function showBottomEdgePage(source, properties) |
1026 | + { |
1027 | + edgeLoader.setSource(source, properties) |
1028 | + _showEdgePageWhenReady = true |
1029 | + } |
1030 | + |
1031 | + function setBottomEdgePage(source, properties) |
1032 | + { |
1033 | + edgeLoader.setSource(source, properties) |
1034 | + } |
1035 | + |
1036 | + function _pushPage() |
1037 | + { |
1038 | + if (edgeLoader.status === Loader.Ready) { |
1039 | + edgeLoader.item.active = true |
1040 | + page.pageStack.push(edgeLoader.item) |
1041 | + if (edgeLoader.item.flickable) { |
1042 | + edgeLoader.item.flickable.contentY = -page.header.height |
1043 | + edgeLoader.item.flickable.returnToBounds() |
1044 | + } |
1045 | + if (edgeLoader.item.ready) |
1046 | + edgeLoader.item.ready() |
1047 | + } |
1048 | + } |
1049 | + |
1050 | + |
1051 | + Component.onCompleted: { |
1052 | + // avoid a binding on the expanded height value |
1053 | + var expandedHeight = height; |
1054 | + _areaWhenExpanded = expandedHeight; |
1055 | + } |
1056 | + |
1057 | + onActiveChanged: { |
1058 | + if (active) { |
1059 | + bottomEdge.state = "collapsed" |
1060 | + } |
1061 | + } |
1062 | + |
1063 | + onBottomEdgePageLoadedChanged: { |
1064 | + if (_showEdgePageWhenReady && bottomEdgePageLoaded) { |
1065 | + bottomEdge.state = "expanded" |
1066 | + _showEdgePageWhenReady = false |
1067 | + } |
1068 | + } |
1069 | + |
1070 | + Rectangle { |
1071 | + id: bgVisual |
1072 | + |
1073 | + color: "black" |
1074 | + anchors.fill: page |
1075 | + opacity: 0.7 * ((page.height - bottomEdge.y) / page.height) |
1076 | + z: 1 |
1077 | + } |
1078 | + |
1079 | + UbuntuShape { |
1080 | + id: tip |
1081 | + objectName: "bottomEdgeTip" |
1082 | + |
1083 | + property bool hidden: (activeFocus === false) || ((bottomEdge.y - units.gu(1)) < tip.y) |
1084 | + |
1085 | + enabled: mouseArea.enabled |
1086 | + visible: page.bottomEdgeEnabled |
1087 | + anchors { |
1088 | + bottom: parent.bottom |
1089 | + horizontalCenter: bottomEdge.horizontalCenter |
1090 | + bottomMargin: hidden ? - height + units.gu(1) : -units.gu(1) |
1091 | + Behavior on bottomMargin { |
1092 | + SequentialAnimation { |
1093 | + // wait some msecs in case of the focus change again, to avoid flickering |
1094 | + PauseAnimation { |
1095 | + duration: 300 |
1096 | + } |
1097 | + UbuntuNumberAnimation { |
1098 | + duration: UbuntuAnimation.SnapDuration |
1099 | + } |
1100 | + } |
1101 | + } |
1102 | + } |
1103 | + |
1104 | + z: 1 |
1105 | + width: tipLabel.paintedWidth + units.gu(6) |
1106 | + height: bottomEdge.tipHeight + units.gu(1) |
1107 | + color: Theme.palette.normal.overlay |
1108 | + Label { |
1109 | + id: tipLabel |
1110 | + |
1111 | + anchors { |
1112 | + top: parent.top |
1113 | + left: parent.left |
1114 | + right: parent.right |
1115 | + } |
1116 | + height: bottomEdge.tipHeight |
1117 | + verticalAlignment: Text.AlignVCenter |
1118 | + horizontalAlignment: Text.AlignHCenter |
1119 | + opacity: tip.hidden ? 0.0 : 1.0 |
1120 | + Behavior on opacity { |
1121 | + UbuntuNumberAnimation { |
1122 | + duration: UbuntuAnimation.SnapDuration |
1123 | + } |
1124 | + } |
1125 | + } |
1126 | + } |
1127 | + |
1128 | + Rectangle { |
1129 | + id: shadow |
1130 | + |
1131 | + anchors { |
1132 | + left: parent.left |
1133 | + right: parent.right |
1134 | + bottom: parent.bottom |
1135 | + } |
1136 | + height: units.gu(1) |
1137 | + z: 1 |
1138 | + opacity: 0.0 |
1139 | + gradient: Gradient { |
1140 | + GradientStop { position: 0.0; color: "transparent" } |
1141 | + GradientStop { position: 1.0; color: Qt.rgba(0, 0, 0, 0.2) } |
1142 | + } |
1143 | + } |
1144 | + |
1145 | + MouseArea { |
1146 | + id: mouseArea |
1147 | + |
1148 | + property real previousY: -1 |
1149 | + property string dragDirection: "None" |
1150 | + |
1151 | + preventStealing: true |
1152 | + drag { |
1153 | + axis: Drag.YAxis |
1154 | + target: bottomEdge |
1155 | + minimumY: bottomEdge.pageStartY |
1156 | + maximumY: page.height |
1157 | + } |
1158 | + enabled: edgeLoader.status == Loader.Ready |
1159 | + visible: page.bottomEdgeEnabled |
1160 | + |
1161 | + anchors { |
1162 | + left: parent.left |
1163 | + right: parent.right |
1164 | + bottom: parent.bottom |
1165 | + |
1166 | + } |
1167 | + height: bottomEdge.tipHeight |
1168 | + z: 1 |
1169 | + |
1170 | + onReleased: { |
1171 | + page.bottomEdgeReleased() |
1172 | + if ((dragDirection === "BottomToTop") && |
1173 | + bottomEdge.y < (page.height - bottomEdgeExpandThreshold - bottomEdge.tipHeight)) { |
1174 | + bottomEdge.state = "expanded" |
1175 | + } else { |
1176 | + bottomEdge.state = "collapsed" |
1177 | + } |
1178 | + previousY = -1 |
1179 | + dragDirection = "None" |
1180 | + } |
1181 | + |
1182 | + onPressed: { |
1183 | + previousY = mouse.y |
1184 | + tip.forceActiveFocus() |
1185 | + } |
1186 | + |
1187 | + onMouseYChanged: { |
1188 | + var yOffset = previousY - mouseY |
1189 | + // skip if was a small move |
1190 | + if (Math.abs(yOffset) <= units.gu(2)) { |
1191 | + return |
1192 | + } |
1193 | + previousY = mouseY |
1194 | + dragDirection = yOffset > 0 ? "BottomToTop" : "TopToBottom" |
1195 | + } |
1196 | + } |
1197 | + |
1198 | + Rectangle { |
1199 | + id: bottomEdge |
1200 | + objectName: "bottomEdge" |
1201 | + |
1202 | + readonly property int tipHeight: units.gu(3) |
1203 | + readonly property int pageStartY: 0 |
1204 | + |
1205 | + z: 1 |
1206 | + color: Theme.palette.normal.background |
1207 | + clip: true |
1208 | + anchors { |
1209 | + left: parent.left |
1210 | + right: parent.right |
1211 | + } |
1212 | + height: page.height |
1213 | + y: height |
1214 | + visible: !page.isCollapsed |
1215 | + state: "collapsed" |
1216 | + states: [ |
1217 | + State { |
1218 | + name: "collapsed" |
1219 | + PropertyChanges { |
1220 | + target: bottomEdge |
1221 | + y: bottomEdge.height |
1222 | + } |
1223 | + }, |
1224 | + State { |
1225 | + name: "expanded" |
1226 | + PropertyChanges { |
1227 | + target: bottomEdge |
1228 | + y: bottomEdge.pageStartY |
1229 | + } |
1230 | + }, |
1231 | + State { |
1232 | + name: "floating" |
1233 | + when: mouseArea.drag.active |
1234 | + PropertyChanges { |
1235 | + target: shadow |
1236 | + opacity: 1.0 |
1237 | + } |
1238 | + } |
1239 | + ] |
1240 | + |
1241 | + transitions: [ |
1242 | + Transition { |
1243 | + to: "expanded" |
1244 | + SequentialAnimation { |
1245 | + alwaysRunToEnd: true |
1246 | + |
1247 | + SmoothedAnimation { |
1248 | + target: bottomEdge |
1249 | + property: "y" |
1250 | + duration: UbuntuAnimation.FastDuration |
1251 | + easing.type: Easing.Linear |
1252 | + } |
1253 | + SmoothedAnimation { |
1254 | + target: edgeLoader |
1255 | + property: "anchors.topMargin" |
1256 | + to: - units.gu(4) |
1257 | + duration: UbuntuAnimation.FastDuration |
1258 | + easing.type: Easing.Linear |
1259 | + } |
1260 | + SmoothedAnimation { |
1261 | + target: edgeLoader |
1262 | + property: "anchors.topMargin" |
1263 | + to: 0 |
1264 | + duration: UbuntuAnimation.FastDuration |
1265 | + easing: UbuntuAnimation.StandardEasing |
1266 | + } |
1267 | + ScriptAction { |
1268 | + script: page._pushPage() |
1269 | + } |
1270 | + } |
1271 | + }, |
1272 | + Transition { |
1273 | + from: "expanded" |
1274 | + to: "collapsed" |
1275 | + SequentialAnimation { |
1276 | + alwaysRunToEnd: true |
1277 | + |
1278 | + ScriptAction { |
1279 | + script: { |
1280 | + Qt.inputMethod.hide() |
1281 | + edgeLoader.item.parent = edgeLoader |
1282 | + edgeLoader.item.anchors.fill = edgeLoader |
1283 | + edgeLoader.item.active = false |
1284 | + } |
1285 | + } |
1286 | + SmoothedAnimation { |
1287 | + target: bottomEdge |
1288 | + property: "y" |
1289 | + duration: UbuntuAnimation.SlowDuration |
1290 | + } |
1291 | + ScriptAction { |
1292 | + script: { |
1293 | + // destroy current bottom page |
1294 | + if (page.reloadBottomEdgePage) { |
1295 | + edgeLoader.active = false |
1296 | + // tip will receive focus on page active true |
1297 | + } else { |
1298 | + tip.forceActiveFocus() |
1299 | + } |
1300 | + |
1301 | + // notify |
1302 | + page.bottomEdgeDismissed() |
1303 | + |
1304 | + edgeLoader.active = true |
1305 | + } |
1306 | + } |
1307 | + } |
1308 | + }, |
1309 | + Transition { |
1310 | + from: "floating" |
1311 | + to: "collapsed" |
1312 | + SmoothedAnimation { |
1313 | + target: bottomEdge |
1314 | + property: "y" |
1315 | + duration: UbuntuAnimation.FastDuration |
1316 | + } |
1317 | + } |
1318 | + ] |
1319 | + |
1320 | + Loader { |
1321 | + id: edgeLoader |
1322 | + |
1323 | + asynchronous: true |
1324 | + anchors.fill: parent |
1325 | + //WORKAROUND: The SDK move the page contents down to allocate space for the header we need to avoid that during the page dragging |
1326 | + Binding { |
1327 | + target: edgeLoader.status === Loader.Ready ? edgeLoader : null |
1328 | + property: "anchors.topMargin" |
1329 | + value: edgeLoader.item && edgeLoader.item.flickable ? edgeLoader.item.flickable.contentY : 0 |
1330 | + when: !page.isReady |
1331 | + } |
1332 | + |
1333 | + onLoaded: { |
1334 | + tip.forceActiveFocus() |
1335 | + if (page.isReady && edgeLoader.item.active !== true) { |
1336 | + page._pushPage() |
1337 | + } |
1338 | + } |
1339 | + } |
1340 | + } |
1341 | +} |
PASSED: Continuous integration, rev:77 91.189. 93.70:8080/ job/ubuntu- calculator- app-reboot- ci/76/ 91.189. 93.70:8080/ job/generic- mediumtests- vivid/853 91.189. 93.70:8080/ job/generic- mediumtests- vivid/853/ artifact/ work/output/ *zip*/output. zip 91.189. 93.70:8080/ job/ubuntu- calculator- app-reboot- vivid-amd64- ci/76
http://
Executed test runs:
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild: 91.189. 93.70:8080/ job/ubuntu- calculator- app-reboot- ci/76/rebuild
http://