on xenial help sign in
Added support for utilization of the ComboButton SDK-element for snap-decision notifications with many actions.

Approved by: Michał Sawicz, PS Jenkins bot

commit7c9eb3ba6dac8ecfd0e83b7115c902f967b1ed59 authorMirco Müller <mirco.mueller@ubuntu.com> dateMon 14 Jul 2014, 18:20 (12 years ago) parente1249223e5b916
4 files changed+133−116
debian/control+1−1 qml/Notifications/Notification.qml+104−79 tests/autopilot/unity8/shell/tests/test_notifications.py+10−13 tests/qmltests/Notifications/tst_Notifications.qml+18−23
debian/control+1−1
@@ -103,7 +103,7 @@ Package: unity8-common
103103Architecture: all
104104Depends: qtdeclarative5-ubuntu-thumbnailer0.1 | ubuntu-thumbnailer-impl,
105105 qtdeclarative5-ubuntu-ui-toolkit-plugin (>= 0.1.49) | qtdeclarative5-ubuntu-ui-toolkit-plugin-gles (>= 0.1.49),
106− qtdeclarative5-unity-notifications-plugin | unity-notifications-impl,
106+ qtdeclarative5-unity-notifications-plugin (>= 0.1.2) | unity-notifications-impl,
107107 ubuntu-thumbnailer-impl-0,
108108 unity-application-impl-2,
109109 unity-notifications-impl-3,
qml/Notifications/Notification.qml+104−79
@@ -16,11 +16,13 @@
1616
1717import QtQuick 2.0
1818import QtMultimedia 5.0
19−import Ubuntu.Components 0.1
19+import Ubuntu.Components 1.1
2020import Unity.Notifications 1.0
2121import QMenuModel 0.1
2222import Utils 0.1
2323
24+import Ubuntu.Components.ListItems 0.1 as ListItem
25+
2426Item {
2527 id: notification
2628
@@ -37,6 +39,14 @@ Item {
3739 property bool fullscreen
3840 property int maxHeight
3941 property int margins
42+ property Gradient greenGradient : Gradient {
43+ GradientStop { position: 0.0; color: "#3fb24f" }
44+ GradientStop { position: 1.0; color: "#3fb24f" }
45+ }
46+ property Gradient darkgreyGradient: Gradient {
47+ GradientStop { position: 0.0; color: "#4d4745" }
48+ GradientStop { position: 1.0; color: "#4d4745" }
49+ }
4050
4151 fullscreen: false
4252 objectName: "background"
@@ -291,7 +301,7 @@ Item {
291301 }
292302 }
293303
294− Item {
304+ Row {
295305 id: buttonRow
296306
297307 objectName: "buttonRow"
@@ -300,70 +310,8 @@ Item {
300310 right: parent.right
301311 }
302312 visible: notification.type == Notification.SnapDecision && actionRepeater.count > 0
303− height: units.gu(5)
304−
305− property real buttonWidth: (width - contentColumn.spacing) / 2
306− property bool expanded
307−
308− Button {
309− id: leftButton
310−
311− objectName: "button1"
312− width: parent.expanded ? parent.width : parent.buttonWidth
313− anchors {
314− top: parent.top
315− bottom: parent.bottom
316− }
317− text: notification.type == Notification.SnapDecision && actionRepeater.count >= 2 ? actionRepeater.itemAt(1).actionLabel : ""
318− gradient: UbuntuColors.greyGradient
319− onClicked: {
320− if (actionRepeater.count > 2) {
321− buttonRow.expanded = !buttonRow.expanded
322− } else {
323− notification.notification.invokeAction(actionRepeater.itemAt(1).actionId)
324− }
325− }
326−
327− Behavior on width {
328− UbuntuNumberAnimation {
329− duration: UbuntuAnimation.SnapDuration
330− }
331− }
332− }
333−
334− Button {
335− id: rightButton
336−
337− objectName: "button0"
338− anchors {
339− left: leftButton.right
340− leftMargin: contentColumn.spacing
341− right: parent.right
342− }
343− text: notification.type == Notification.SnapDecision && actionRepeater.count >= 1 ? actionRepeater.itemAt(0).actionLabel : ""
344− anchors {
345− top: parent.top
346− bottom: parent.bottom
347− }
348− gradient: notification.hints["x-canonical-private-button-tint"] == "true" ? UbuntuColors.orangeGradient : UbuntuColors.greyGradient
349− visible: width > 0
350− onClicked: notification.notification.invokeAction(actionRepeater.itemAt(0).actionId)
351− }
352− }
353−
354− Column {
355− objectName: "buttonColumn"
356− spacing: contentColumn.spacing
357− anchors {
358− left: parent.left
359− right: parent.right
360− }
361−
362− // calculate initial position before Column takes over
363− y: buttonRow.y + buttonRow.height + contentColumn.spacing
364−
365− visible: notification.type == Notification.SnapDecision && buttonRow.expanded
366− height: buttonRow.expanded ? implicitHeight : 0
313+ spacing: units.gu(1)
314+ layoutDirection: Qt.RightToLeft
367315
368316 Repeater {
369317 id: actionRepeater
@@ -375,28 +323,105 @@ Item {
375323 property string actionId: id
376324 property string actionLabel: label
377325
378− anchors {
379− left: parent.left
380− right: parent.right
381− }
382−
383326 Component {
384327 id: actionButton
385328
386329 Button {
387330 objectName: "button" + index
388− anchors {
389− left: parent.left
390− right: parent.right
391− }
392−
331+ width: buttonRow.width / 2 - spacing
393332 text: loader.actionLabel
394− height: units.gu(5)
395− gradient: UbuntuColors.greyGradient
333+ gradient: notification.hints["x-canonical-private-button-tint"] == "true" && index == 0 ? greenGradient : darkgreyGradient
396334 onClicked: notification.notification.invokeAction(loader.actionId)
397335 }
398336 }
399− sourceComponent: (index == 0 || index == 1) ? undefined : actionButton
337+ sourceComponent: (index == 0 || index == 1) ? actionButton : undefined
338+ }
339+ }
340+ }
341+
342+ ComboButton {
343+ id: comboButton
344+
345+ objectName: "button2"
346+ width: parent.width
347+ visible: notification.type == Notification.SnapDecision && actionRepeater.count > 3
348+ gradient: darkgreyGradient
349+ onClicked: notification.notification.invokeAction(comboRepeater.itemAt(2).actionId)
350+ expanded: false
351+ expandedHeight: (comboRepeater.count - 2) * units.gu(4) + units.gu(.5)
352+ comboList: Flickable {
353+ // this has to be wrapped inside a flickable
354+ // to work around a feature/bug? of the
355+ // ComboButton SDK-element, making a regular
356+ // unwrapped Column item flickable
357+ // see LP: #1332590
358+ interactive: false
359+ Column {
360+ Repeater {
361+ id: comboRepeater
362+
363+ onVisibleChanged: {
364+ comboButton.text = comboRepeater.itemAt(2).actionLabel
365+ }
366+
367+ model: notification.actions
368+ delegate: Loader {
369+ id: comboLoader
370+
371+ asynchronous: true
372+ visible: status == Loader.Ready
373+ property string actionId: id
374+ property string actionLabel: label
375+ readonly property var splitLabel: actionLabel.match(/(^([-a-z0-9]+):)?(.*)$/)
376+ Component {
377+ id: comboEntry
378+
379+ MouseArea {
380+ id: comboInputArea
381+
382+ objectName: "button" + index
383+ width: comboButton.width
384+ height: comboIcon.height + units.gu(2)
385+
386+ onClicked: {
387+ notification.notification.invokeAction(actionId)
388+ }
389+
390+ ListItem.ThinDivider {
391+ visible: index > 3
392+ }
393+
394+ Icon {
395+ id: comboIcon
396+
397+ anchors {
398+ left: parent.left
399+ leftMargin: units.gu(.5)
400+ verticalCenter: parent.verticalCenter
401+ }
402+ width: units.gu(2)
403+ height: units.gu(2)
404+ color: "white"
405+ name: splitLabel[2]
406+ }
407+
408+ Label {
409+ id: comboLabel
410+
411+ anchors {
412+ left: comboIcon.right
413+ leftMargin: units.gu(1)
414+ verticalCenter: comboIcon.verticalCenter
415+ }
416+ fontSize: "small"
417+ color: "white"
418+ text: splitLabel[3]
419+ }
420+ }
421+ }
422+ sourceComponent: (index > 2) ? comboEntry : undefined
423+ }
424+ }
400425 }
401426 }
402427 }
tests/autopilot/unity8/shell/tests/test_notifications.py+10−13
@@ -178,11 +178,13 @@ class InteractiveNotificationBase(NotificationsBase):
178178 ]
179179
180180 actions = [
181− ('action_accept', 'Accept'),
182− ('action_decline_1', 'Decline'),
183− ('action_decline_2', '"Can\'t talk now, what\'s up?"'),
184− ('action_decline_3', '"I call you back."'),
185− ('action_decline_4', 'Send custom message...'),
181+ ('action_accept', 'Hold + Answer'),
182+ ('action_decline_1', 'End + Answer'),
183+ ('action_decline_2', 'Decline'),
184+ ('action_decline_3', 'messages:I missed your call - can you call me now?'),
185+ ('action_decline_4', 'messages:I\'m running late. I\'m on my way.'),
186+ ('action_decline_5', 'messages:I\'m busy at the moment. I\'ll call later.'),
187+ ('action_decline_6', 'edit:Custom'),
186188 ]
187189
188190 self._create_interactive_notification(
@@ -200,14 +202,9 @@ class InteractiveNotificationBase(NotificationsBase):
200202 notification = get_notification()
201203 self._assert_notification(notification, summary, body, True, True, 1.0)
202204 initial_height = notification.height
203− self.touch.tap_object(notification.select_single(objectName="button1"))
204− self.assertThat(
205− notification.height,
206− Eventually(Equals(initial_height +
207− 3 * notification.select_single(
208− objectName="buttonColumn").spacing +
209− 3 * notification.select_single(
210− objectName="button4").height)))
205+ self.touch.tap_object(notification.select_single(objectName="combobutton_dropdown"))
206+ self.assertThat(notification.select_single(objectName="button2").expanded, Eventually(Equals(True)))
207+ time.sleep(2)
211208 self.touch.tap_object(notification.select_single(objectName="button4"))
212209 self.assert_notification_action_id_was_called("action_decline_4")
213210
tests/qmltests/Notifications/tst_Notifications.qml+18−23
@@ -72,8 +72,8 @@ Row {
7272 actions: [{ id: "ok_id", label: "Ok"},
7373 { id: "cancel_id", label: "Cancel"},
7474 { id: "notreally_id", label: "Not really"},
75− { id: "noway_id", label: "No way"},
76− { id: "nada_id", label: "Nada"}]
75+ { id: "noway_id", label: "messages:No way"},
76+ { id: "nada_id", label: "messages:Nada"}]
7777 }
7878
7979 mockModel.append(n)
@@ -237,8 +237,8 @@ Row {
237237 actions: [{ id: "ok_id", label: "Ok"},
238238 { id: "cancel_id", label: "Cancel"},
239239 { id: "notreally_id", label: "Not really"},
240− { id: "noway_id", label: "No way"},
241− { id: "nada_id", label: "Nada"}],
240+ { id: "noway_id", label: "messages:No way"},
241+ { id: "nada_id", label: "messages:Nada"}],
242242 summaryVisible: true,
243243 bodyVisible: true,
244244 iconVisible: true,
@@ -456,32 +456,27 @@ Row {
456456 actionSpy.clear()
457457 waitForRendering(notification)
458458
459− // check if there's more than one negative choice
459+ // check if there's a ComboButton created due to more actions being passed
460460 if (data.actions.length > 2) {
461− var initialHeight = notification.implicitHeight
461+ var comboButton = findChild(notification, "button2")
462+ tryCompareFunction(function() { return comboButton.expanded == false; }, true);
462463
463464 // click to expand
464− mouseClick(buttonCancel, buttonCancel.width / 2, buttonCancel.height / 2)
465− var contentColumn = findChild(notification, "contentColumn")
466− var collapsedContentColumnHeight = contentColumn.height;
467− // Waiting for the inner column to change height because buttons appear
468− tryCompareFunction(function() { return collapsedContentColumnHeight != contentColumn.height; }, true);
469− // Waiting for notification to reach its target size
470− tryCompare(notification, "height", contentColumn.height + contentColumn.spacing * 2)
465+ tryCompareFunction(function() { mouseClick(comboButton, comboButton.width - comboButton.__styleInstance.dropDownWidth / 2, comboButton.height / 2); return comboButton.expanded == true; }, true);
466+
467+ // try clicking on choices in expanded comboList
468+ var choiceButton1 = findChild(notification, "button3")
469+ tryCompareFunction(function() { mouseClick(choiceButton1, choiceButton1.width / 2, choiceButton1.height / 2); return actionSpy.signalArguments.length > 0; }, true);
470+ compare(actionSpy.signalArguments[0][0], data.actions[3]["id"], "got wrong id choice action 1")
471471 actionSpy.clear()
472472
473− // test the additional buttons
474− for (var i = 2; i < data.actions.length; i++) {
475− var buttonColumn = findChild(notification, "buttonColumn")
476− var button = findChild(buttonColumn, "button" + i)
477− mouseClick(button, button.width / 2, button.height / 2)
478− compare(actionSpy.signalArguments[0][0], data.actions[i]["id"], "got wrong id for additional negative action")
479− actionSpy.clear()
480− }
473+ var choiceButton2 = findChild(notification, "button4")
474+ tryCompareFunction(function() { mouseClick(choiceButton2, choiceButton2.width / 2, choiceButton2.height / 2); return actionSpy.signalArguments.length > 0; }, true);
475+ compare(actionSpy.signalArguments[0][0], data.actions[4]["id"], "got wrong id choice action 2")
476+ actionSpy.clear()
481477
482478 // click to collapse
483− mouseClick(buttonCancel, buttonCancel.width / 2, buttonCancel.height / 2)
484− tryCompare(notification, "height", initialHeight)
479+ //tryCompareFunction(function() { mouseClick(comboButton, comboButton.width - comboButton.__styleInstance.dropDownWidth / 2, comboButton.height / 2); return comboButton.expanded == false; }, true);
485480 } else {
486481 mouseClick(buttonCancel, buttonCancel.width / 2, buttonCancel.height / 2)
487482 compare(actionSpy.signalArguments[0][0], data.actions[1]["id"], "got wrong id for negative action")