diff options
author | Grigorii Zimin <gzimin@luxoft.com> | 2020-03-02 14:50:28 +0300 |
---|---|---|
committer | Grigorii Zimin <gzimin@luxoft.com> | 2020-03-04 11:03:58 +0000 |
commit | 17a05c081f6db560e5d0120323955937d8ce06b3 (patch) | |
tree | 6378548e23d326b5ccd79f97500e9ab8a71eada9 /sysui | |
parent | 225dcefc572c779ab9580227a24f3234ef415bed (diff) |
[notifications] fix notification drag behavior
also this patch makes sure, that we always see the last notification
Change-Id: I95208eb802f7dee1ec8bbd8a1fc72c582be5112e
Reviewed-by: Egor Nemtsev <enemtsev@luxoft.com>
Diffstat (limited to 'sysui')
-rw-r--r-- | sysui/notification/NotificationCenter.qml | 143 | ||||
-rw-r--r-- | sysui/notification/NotificationContent.qml | 52 | ||||
-rw-r--r-- | sysui/notification/NotificationHandle.qml | 64 |
3 files changed, 156 insertions, 103 deletions
diff --git a/sysui/notification/NotificationCenter.qml b/sysui/notification/NotificationCenter.qml index 34bd0399..21af195d 100644 --- a/sysui/notification/NotificationCenter.qml +++ b/sysui/notification/NotificationCenter.qml @@ -45,29 +45,45 @@ Item { state: "closed" states: [ State { - when: root.incomingNoti + name: "closed" PropertyChanges { target: root - height: (Sizes.dp(150) + notificationToast.height) - y: 0 + y: -allNotificationsHeight + height: allNotificationsHeight } PropertyChanges { target: notificationToast - opacity: 1.0 - visible: true + opacity: 0.0 + visible: false + } + PropertyChanges { + target: notificationCenterBG + opacity: 0.0 + } + PropertyChanges { + target: notificationLabelOnBG + opacity: 0.0 } PropertyChanges { target: notificationListItem opacity: 0.0 visible: false } + PropertyChanges { + target: clearListButton + opacity: 0.0 + } }, State { - when: root.openNotificationCenter + name: "intermediate_from_closed" + PropertyChanges { + target: notificationCenterBG + opacity: 1.0 + } PropertyChanges { target: root - height: (root.totalContentHeight + notificationDefaultMargin + notificationBottomMargin) - y: 0 + y: -allNotificationsHeight + height: allNotificationsHeight } PropertyChanges { target: notificationToast @@ -81,95 +97,137 @@ Item { } }, State { - name: "closed" - when: (!root.incomingNoti && !root.openNotificationCenter) + name: "incomingNotification" + PropertyChanges { + target: notificationCenterBG + opacity: 1.0 + } PropertyChanges { target: root - height: (root.totalContentHeight + notificationDefaultMargin + notificationBottomMargin) - y: -root.height + height: oneIncomingNotificationHeight + y: 0 } PropertyChanges { target: notificationToast + opacity: 1.0 + visible: true + } + PropertyChanges { + target: notificationListItem opacity: 0.0 visible: false } PropertyChanges { - target: notificationCenterBg + target: clearListButton opacity: 0.0 } + }, + State { + name: "intermediate_from_all" + extend: "allNotifications" + }, + State { + name: "allNotifications" PropertyChanges { - target: notificationLabelOnBG - opacity: 0.0 + target: root + y: 0 + height: allNotificationsHeight } PropertyChanges { - target: notificationListItem + target: notificationCenterBG + opacity: 1.0 + } + PropertyChanges { + target: notificationToast opacity: 0.0 visible: false } + PropertyChanges { + target: notificationListItem + opacity: 1.0 + visible: true + } } ] - transitions: Transition { - PropertyAnimation { properties: "y, height"; easing.type: Easing.InOutQuad } - PropertyAnimation { properties: "opacity"; duration: 400 } - } + transitions: [ + Transition {from: "*"; to: "intermediate_from_closed"} + , Transition {from: "*"; to: "intermediate_from_all"} + , Transition { + PropertyAnimation { + properties: "y, height"; + easing.type: Easing.InOutQuad; + } + PropertyAnimation { properties: "opacity"; duration: 400 } + } + ] - readonly property int totalMaxContentHeight: (parent.height - Config.statusBarHeight - root.notificationDefaultMargin - root.notificationBottomMargin) - readonly property int totalContentHeight: (notificationList.contentHeight > root.totalMaxContentHeight) ? root.totalMaxContentHeight : notificationList.contentHeight - readonly property int listviewHeight: Math.min((root.notificationModel.count * Sizes.dp(120)), root.totalContentHeight) + readonly property int oneIncomingNotificationHeight: Sizes.dp(100) + notificationToast.height + readonly property int allNotificationsHeight: root.totalContentHeight + + root.notificationDefaultMargin + + root.notificationBottomMargin + + readonly property int totalMaxContentHeight: parent.height + - Config.statusBarHeight + - root.notificationDefaultMargin + - root.notificationBottomMargin + readonly property int totalContentHeight: + notificationList.contentHeight > root.totalMaxContentHeight + ? root.totalMaxContentHeight + : notificationList.contentHeight + readonly property int listviewHeight: + Math.min((root.notificationModel.count * Sizes.dp(120)), root.totalContentHeight) readonly property int notificationDefaultMargin: Sizes.dp(40) readonly property int notificationBottomMargin: Sizes.dp(110) readonly property int defaultTimeout: 2000 property NotificationModel notificationModel - property bool incomingNoti: false - property bool openNotificationCenter: false function closeNotificationCenter() { // reset helper properties&timer - root.incomingNoti = false; - root.openNotificationCenter = false; notificationShowTimer.stop(); notificationShowTimer.interval = root.defaultTimeout; + state = "closed" } Rectangle { - id: notificationCenterBg + id: notificationCenterBG anchors.fill: parent color: Style.offMainColor + visible: opacity > 0.0 Behavior on opacity { DefaultNumberAnimation { } } } Timer { id: notificationShowTimer onTriggered: { - root.incomingNoti = false; + if (root.state == "incomingNotification") + root.state = "closed"; } } Connections { target: root.notificationModel onCountChanged: { - if (root.incomingNoti && (root.notificationModel.count === 0)) { - root.incomingNoti = false; + if (root.notificationModel.count === 0) { + root.state = "closed"; } } onNotificationAdded: { - root.incomingNoti = true; + state = "incomingNotification"; notificationShowTimer.stop(); - var currentNotification = root.notificationModel.model.get(root.notificationModel.count - 1); - if (currentNotification.timeout > root.defaultTimeout) { - notificationShowTimer.interval = currentNotification.timeout; - } else { - notificationShowTimer.interval = root.defaultTimeout; - } + var notification = root.notificationModel.model.get(root.notificationModel.count - 1); + notificationShowTimer.interval = (notification.timeout > root.defaultTimeout) + ? notification.timeout + : root.defaultTimeout; + notificationShowTimer.start(); } onNotificationClosed: { - root.incomingNoti = false; + root.state = "closed"; } } @@ -190,19 +248,22 @@ Item { interactive: (contentHeight > root.listviewHeight) model: root.notificationModel.model ScrollIndicator.vertical: ScrollIndicator { } + onCountChanged: { + positionViewAtEnd(); + } delegate: NotificationItem { width: notificationList.width notificationIcon: model.icon notificationText: model.summary notificationSubtext: model.body notificationImage: model.image - notificationActionText: (model.actions.length > 0) ? model.actions[0].actionText : "" + notificationActionText: model.actions.length > 0 ? model.actions[0].actionText : "" onCloseClicked: { root.notificationModel.removeNotification(model.id); } onButtonClicked: { root.notificationModel.buttonClicked(model.id); - root.openNotificationCenter = false; + root.state = "closed"; } } } diff --git a/sysui/notification/NotificationContent.qml b/sysui/notification/NotificationContent.qml index d8f64b24..62100f68 100644 --- a/sysui/notification/NotificationContent.qml +++ b/sysui/notification/NotificationContent.qml @@ -39,7 +39,7 @@ import shared.Sizes 1.0 ModalOverlay { id: root - showModalOverlay: notificationCenter.openNotificationCenter + showModalOverlay: notificationCenter.state === "allNotifications" onOverlayClicked: { notificationCenter.closeNotificationCenter(); } @@ -66,45 +66,25 @@ ModalOverlay { anchors.horizontalCenter: root.horizontalCenter anchors.top: notificationCenter.bottom notificationCount: notificationModel.count - notificationCounterVisible: ((notificationCount > 0) && !notificationCenter.openNotificationCenter) + notificationCounterVisible: notificationCount > 0 + && notificationCenter.state !== "allNotifications" dragTarget: notificationCenter - minimumY: -notificationCenter.height - maximumY: 0 - onActiveChanged: { - if (active) { - notificationHandle.prevDragY = notificationHandle.dragTarget.y; - } else { - if (!notificationHandle.dragActive && notificationHandle.swipe) { - if (notificationCenter.openNotificationCenter && notificationHandle.dragDelta > 0) { - notificationCenter.openNotificationCenter = true; - } else if (notificationCenter.openNotificationCenter && notificationHandle.dragDelta < 0) { - notificationCenter.openNotificationCenter = false; - } else { - notificationCenter.openNotificationCenter = !notificationCenter.openNotificationCenter; - } + parentRotation: root.rotation + + onReleased: { + if (notificationCenter.state === "intermediate_from_closed" + || notificationCenter.state === "intermediate_from_all") + { + if (-notificationCenter.y < notificationCenter.allNotificationsHeight / 2) { + notificationCenter.state = "allNotifications"; } else { - notificationCenter.openNotificationCenter = !notificationCenter.openNotificationCenter; + notificationCenter.state = "closed"; } - - // stop drag filter timer - notificationHandle.dragFilterTimer.running = false; - notificationHandle.dragDelta = (notificationCenter.y - notificationHandle.dragOrigin + Sizes.dp(130)); + } else if (notificationCenter.state === "allNotifications") { + notificationCenter.state = "closed"; + } else { + notificationCenter.state = "allNotifications"; } } - - onClicked: { - //open notificationCenter - notificationCenter.openNotificationCenter = !notificationCenter.openNotificationCenter; - } - - onPressed: { - // reset values - notificationHandle.dragDelta = 0; - notificationHandle.dragOrigin = notificationHandle.dragTarget.y; - notificationHandle.prevDragY = notificationHandle.dragTarget.y; - - // start drag filter timer - notificationHandle.dragFilterTimer.running = true; - } } } diff --git a/sysui/notification/NotificationHandle.qml b/sysui/notification/NotificationHandle.qml index 00fb8ff8..25fcb875 100644 --- a/sysui/notification/NotificationHandle.qml +++ b/sysui/notification/NotificationHandle.qml @@ -43,30 +43,51 @@ ToolButton { implicitWidth: root.notificationCounterVisible ? Sizes.dp(255) : Sizes.dp(205) implicitHeight: Sizes.dp(Config.statusBarHeight) - property alias dragActive: handler.active - property alias dragTarget: handler.target - property int prevDragY: 0 - property int dragDelta: 0 - property int dragOrigin: 0 - property int minimumY: 0 - property int maximumY: 0 - - property bool swipe: Math.abs(root.prevDragY - root.dragTarget.y) > 0 - - property alias dragFilterTimer: dragFilterTimer - property int notificationCount property bool notificationCounterVisible - signal activeChanged(var active) + property var dragTarget + property int parentRotation + + QtObject { + id: d + property int prevDragY + } DragHandler { id: handler - target: root.dragTarget - yAxis.minimum: root.minimumY - yAxis.maximum: root.maximumY + target: root + onTranslationChanged: { + var dt = Math.sin(parentRotation* (180 / Math.PI)) * translation.x + + Math.cos(parentRotation* (180 / Math.PI)) * translation.y ; + if (dragTarget.state === "intermediate_from_closed") { + if (dt > 0) { // from close -> open + var delta = dt < dragTarget.allNotificationsHeight + ? dt + : dragTarget.allNotificationsHeight; + dragTarget.y = d.prevDragY + delta; + } + } else if (dragTarget.state === "intermediate_from_all") { + if (dt < 0) { // from open -> close + delta = (dt + dragTarget.allNotificationsHeight) > 0 + ? dt + : -dragTarget.allNotificationsHeight; + dragTarget.y = d.prevDragY + delta; + } + } + } onActiveChanged: { - root.activeChanged(active); + if (active) { + if (dragTarget.state === "closed") { + dragTarget.state = "intermediate_from_closed"; + d.prevDragY = dragTarget.y; + } else if (dragTarget.state === "allNotifications") { + dragTarget.state = "intermediate_from_all"; + d.prevDragY = dragTarget.y; + } + } else { + root.released() + } } } @@ -113,15 +134,6 @@ ToolButton { } } - Timer { - id: dragFilterTimer - interval: 100 - repeat: true - onTriggered: { - root.prevDragY = root.dragTarget.y; - } - } - states: [ State { name: "notificationCounterVisible" |