rewrite slidingpanel as a flickable

use again custom notifications applet
This commit is contained in:
Marco Martin 2017-09-01 18:35:41 +02:00
parent f35d9909af
commit 15526517ef
6 changed files with 176 additions and 228 deletions

View file

@ -29,7 +29,7 @@ MouseArea {
//actionsLayout.height*2 because the text is centered //actionsLayout.height*2 because the text is centered
//TODO: center the whole block not only the text //TODO: center the whole block not only the text
height: Math.max(messageLayout.height, icon.height) + background.margins.top + background.margins.bottom + (expanded ? actionsLayout.height*2 : 0) height: Math.max(units.gridUnit * 3, Math.max(messageLayout.height, icon.height)) + (expanded ? actionsLayout.height*2 : 0)
width: parent.width width: parent.width
anchors.bottomMargin: 10 anchors.bottomMargin: 10
drag.axis: Drag.XAxis drag.axis: Drag.XAxis
@ -39,12 +39,19 @@ MouseArea {
property string source: model.source property string source: model.source
property var actions: model.actions property var actions: model.actions
opacity: 1 - Math.abs(x) / (width/2)
Behavior on x { Behavior on x {
NumberAnimation { NumberAnimation {
easing.type: Easing.InOutQuad easing.type: Easing.InOutQuad
duration: units.longDuration duration: units.longDuration
} }
} }
Behavior on height {
NumberAnimation {
easing.type: Easing.InOutQuad
duration: units.longDuration
}
}
onReleased: { onReleased: {
if (drag.active) { if (drag.active) {
@ -66,22 +73,18 @@ MouseArea {
} }
PlasmaCore.FrameSvgItem { Rectangle {
id: background id: background
imagePath: "widgets/background" anchors.fill: parent
anchors { color: Qt.rgba(PlasmaCore.ColorScope.textColor.r, PlasmaCore.ColorScope.textColor.g, PlasmaCore.ColorScope.textColor.b, notificationItem.pressed ? 0.5 : 0.2)
fill: parent
rightMargin: -notificationItem.width
leftMargin: units.gridUnit
}
colorGroup: PlasmaCore.ColorScope.colorGroup
} }
PlasmaComponents.ToolButton { PlasmaComponents.ToolButton {
id: closeButton
anchors { anchors {
left: parent.left right: parent.right
verticalCenter: parent.verticalCenter verticalCenter: parent.verticalCenter
leftMargin: units.gridUnit / 2 rightMargin: units.gridUnit
} }
iconSource: "window-close" iconSource: "window-close"
flat: false flat: false
@ -90,52 +93,32 @@ MouseArea {
} }
} }
PlasmaComponents.Label { ColumnLayout {
id: appLabel
anchors.leftMargin: units.gridUnit * 3
color: PlasmaCore.ColorScope.textColor
text: model.appName
}
Column {
id: messageLayout id: messageLayout
anchors { anchors {
verticalCenter: parent.verticalCenter verticalCenter: parent.verticalCenter
left: parent.left left: icon.right
right: icon.left right: notificationItem.expanded ? actionsLayout.left : closeButton.left
leftMargin: units.gridUnit * 3 leftMargin: units.gridUnit
rightMargin: units.gridUnit
} }
PlasmaComponents.Label { PlasmaComponents.Label {
id: summaryLabel id: summaryLabel
anchors.right: parent.right Layout.fillWidth: true
width: messageLayout.width - appLabel.width
horizontalAlignment: Qt.AlignRight
verticalAlignment: Qt.AlignVCenter verticalAlignment: Qt.AlignVCenter
text: summary + (!notificationItem.expanded && body ? "..." : "") text: model.appName + " " + summary
wrapMode: Text.WordWrap elide: Text.ElideRight
} }
PlasmaComponents.Label { PlasmaComponents.Label {
id: bodyLabel id: bodyLabel
anchors { Layout.fillWidth: true
right: parent.right visible: text.length > 0
left: parent.left opacity: 0.8
}
visible: height > 0
height: notificationItem.expanded && body != undefined && body ? implicitHeight : 0
clip: true
horizontalAlignment: Qt.AlignRight
verticalAlignment: Qt.AlignVCenter verticalAlignment: Qt.AlignVCenter
text: body text: body
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
Behavior on height {
NumberAnimation {
duration: units.longDuration
easing.type: Easing.InOutQuad
}
}
} }
} }
@ -143,21 +126,21 @@ MouseArea {
PlasmaCore.IconItem { PlasmaCore.IconItem {
id: icon id: icon
anchors { anchors {
right: notificationItem.right
verticalCenter: parent.verticalCenter verticalCenter: parent.verticalCenter
} }
x: units.gridUnit
width: units.iconSizes.medium width: units.iconSizes.medium
height: width height: width
source: appIcon && appIcon.length > 0 ? appIcon : "preferences-desktop-notification" source: appIcon && appIcon.length > 0 ? appIcon : "preferences-desktop-notification"
colorGroup: PlasmaCore.ColorScope.colorGroup
} }
Flow { Column {
id: actionsLayout id: actionsLayout
anchors { anchors {
left: messageLayout.left right: closeButton.left
right: messageLayout.right rightMargin: units.gridUnit
top: messageLayout.bottom verticalCenter: parent.verticalCenter
topMargin: units.smallSpacing
} }
opacity: notificationItem.expanded && notificationItem.actions && notificationItem.actions.count > 0 ? 1 : 0 opacity: notificationItem.expanded && notificationItem.actions && notificationItem.actions.count > 0 ? 1 : 0
Behavior on opacity { Behavior on opacity {
@ -177,34 +160,4 @@ MouseArea {
} }
} }
} }
states: [
State {
name: "large"
when: appLabel.width + bodyLabel.paintedWidth < messageLayout.width
AnchorChanges {
target: appLabel
anchors {
verticalCenter: parent.verticalCenter
top: undefined
left: parent.left
}
}
PropertyChanges {
}
},
State {
name: "compact"
when: notificationItem.state != "large"
AnchorChanges {
target: appLabel
anchors {
verticalCenter: undefined
top: messageLayout.top
left: parent.left
}
}
}
]
} }

View file

@ -28,9 +28,12 @@ Item {
id: root id: root
property int notificationId: 0 property int notificationId: 0
Layout.minimumHeight: notificationView.contentHeight Layout.maximumHeight: notificationView.contentHeight + units.gridUnit
//todo: size of first item
Layout.minimumHeight: units.gridUnit * 4
Plasmoid.backgroundHints: PlasmaCore.Types.NoBackground Plasmoid.switchWidth: 500
Plasmoid.switchHeight: 500
function addNotification(source, data, actions) { function addNotification(source, data, actions) {
// Do not show duplicated notifications // Do not show duplicated notifications
@ -133,14 +136,40 @@ Item {
ListModel { ListModel {
id: notificationsModel id: notificationsModel
ListElement {
source: "call1Source"
appIcon: "call-start"
summary: "Missed call from Joe"
appName: "Phone"
body: "Called at 8:42 from +41 56 373 37 31"
actions: []
}
ListElement {
source: "im1Source"
appIcon: "im-google"
appName: "Message"
summary: "July: Hey! Are you around?"
actions: []
}
ListElement {
source: "im2Source"
appIcon: "im-google"
appName: "Message"
summary: "July: Hello?"
actions: []
}
} }
ListView { ListView {
id: notificationView id: notificationView
spacing: units.smallSpacing spacing: units.largeSpacing
anchors.fill: parent anchors {
fill: parent
leftMargin: units.largeSpacing
rightMargin: units.largeSpacing
}
interactive: false interactive: false
cacheBuffer: 2000 cacheBuffer: 200000
z: 1 z: 1
verticalLayoutDirection: ListView.BottomToTop verticalLayoutDirection: ListView.BottomToTop

View file

@ -68,7 +68,7 @@ Item {
text: "Settings" text: "Settings"
icon: "configure" icon: "configure"
enabled: false enabled: false
settingsCommand: "active-settings" settingsCommand: "plasma-mobile-settings"
toggleFunction: "" toggleFunction: ""
delegate: "" delegate: ""
} }

View file

@ -28,7 +28,7 @@ FullScreenPanel {
id: window id: window
property int offset: 0 property int offset: 0
property int overShoot: units.gridUnit * 2 property int peekHeight
color: "transparent" color: "transparent"
property alias contents: contentArea.data property alias contents: contentArea.data
@ -36,108 +36,108 @@ FullScreenPanel {
width: Screen.width width: Screen.width
height: Screen.height height: Screen.height
property alias fixedArea: fixedArea
function open() { function open() {
mouseArea.state = "open"; window.visible = true;
openAnim.running = true;
} }
function close() { function close() {
mouseArea.state = "closed"; closeAnim.running = true;
} }
function updateState() { function updateState() {
var delta = offset - mouseArea.startOffset; if (offset < peekHeight / 2) {
if (delta > units.gridUnit * 8) { close();
mouseArea.state = "open"; } else if (offset < peekHeight) {
} else if (delta < -units.gridUnit * 8) { open();
mouseArea.state = "closed";
} else {
mouseArea.state = mouseArea.startState;
} }
mouseArea.startState = mouseArea.state;
} }
onVisibleChanged: { onVisibleChanged: {
if (visible) { if (visible) {
mouseArea.state = "draggingFromClosed";
mouseArea.startOffset = units.gridUnit * 4;
window.width = Screen.width; window.width = Screen.width;
window.height = Screen.height; window.height = Screen.height;
} }
} }
SequentialAnimation {
MouseArea { id: closeAnim
id: mouseArea PropertyAnimation {
y: 0 target: window
width: Screen.width duration: units.longDuration
height: Screen.height easing.type: Easing.InOutQuad
//clip: true properties: "offset"
state: "closed" from: window.offset
drag.filterChildren: true to: 0
property int oldMouseY: 0
property int startOffset: units.iconSizes.large;
property int startMouseY: 0
property string startState: "closed"
onPressed: {
startMouseY = mouse.y;
if (startMouseY < contentArea.height - units.iconSizes.large) {
return;
}
startState = state;
startOffset = window.offset;
oldMouseY = mouse.y;
state = "draggingFromOpen";
window.offset = startOffset;
} }
onPositionChanged: { ScriptAction {
if (startMouseY < contentArea.height - units.iconSizes.large) { script: {
//TODO: test if we can do without this return window.visible = false;
// return;
}
var factor = (mouse.y - oldMouseY > 0) ? (1 - Math.max(0, (slidingArea.y + overShoot) / overShoot)) : 1
window.offset = window.offset + (mouse.y - oldMouseY) * factor;
oldMouseY = mouse.y;
}
onReleased: {
if (startMouseY < contentArea.height - units.iconSizes.large) {
return;
}
if (Math.abs(window.offset - mouseArea.startOffset) < units.gridUnit &&
slidingArea.y + slidingArea.height < mouse.y) {
mouseArea.state = "closed";
} else {
window.updateState();
} }
} }
}
PropertyAnimation {
id: openAnim
target: window
duration: units.longDuration
easing.type: Easing.InOutQuad
properties: "offset"
from: window.offset
to: window.peekHeight
}
Rectangle {
anchors.fill: parent
color: Qt.rgba(0, 0, 0, 0.6 * Math.min(1, offset/contentArea.height))
}
PlasmaCore.ColorScope {
id: slidingArea
anchors.fill: parent
y: Math.min(0, -height + window.offset)
colorGroup: PlasmaCore.Theme.ComplementaryColorGroup
Rectangle { Rectangle {
anchors.fill: parent anchors {
color: Qt.rgba(0, 0, 0, 0.6-Math.abs(slidingArea.y/slidingArea.height)) top: parent.top
left: parent.left
right: parent.right
}
height: contentArea.height - mainFlickable.contentY
color: PlasmaCore.ColorScope.backgroundColor
} }
PlasmaCore.ColorScope {
id: slidingArea
width: parent.width
height: parent.height/1.5
y: Math.min(0, -height + window.offset)
colorGroup: PlasmaCore.Theme.ComplementaryColorGroup
Rectangle {
anchors.fill: parent
Flickable {
id: mainFlickable
anchors.fill: parent
Binding {
target: mainFlickable
property: "contentY"
value: -window.offset + contentArea.height
when: !mainFlickable.moving && !mainFlickable.dragging && !mainFlickable.flicking
}
//no loop as those 2 values compute to exactly the same
onContentYChanged: window.offset = -contentY + contentArea.height
contentWidth: window.width
contentHeight: window.height*2
bottomMargin: window.height
onMovementEnded: window.updateState();
onFlickEnded: window.updateState();
Item {
width: window.width
height: window.height*2
Item { Item {
id: contentArea id: contentArea
anchors { anchors {
fill: parent left: parent.left
topMargin: overShoot right: parent.right
} }
height: children[0].implicitHeight
} }
color: PlasmaCore.ColorScope.backgroundColor
Rectangle { Rectangle {
height: units.gridUnit height: units.gridUnit
anchors { anchors {
left: parent.left left: parent.left
right: parent.right right: parent.right
top: parent.bottom top: contentArea.bottom
} }
gradient: Gradient { gradient: Gradient {
GradientStop { GradientStop {
@ -154,69 +154,25 @@ FullScreenPanel {
} }
} }
} }
MouseArea {
anchors {
left: parent.left
right: parent.right
top: contentArea.bottom
}
height: window.height
onClicked: window.close();
}
} }
} }
//FIXME: this empty mousearea is a workaround on https://bugreports.qt.io/browse/QTBUG-46545 Item {
MouseArea { id: fixedArea
z: -1 anchors {
anchors.fill: parent left: parent.left
onClicked: { right: parent.right
if (mouseArea.startMouseY < contentArea.height - units.iconSizes.large) { top: parent.top
return;
}
mouseArea.state = "closed";
//window.visible = false;
} }
height: childrenRect.height
} }
states: [
State {
name: "closed"
PropertyChanges {
target: window
offset: 0
}
},
State {
name: "open"
PropertyChanges {
target: window
offset: slidingArea.height - overShoot
}
},
State {
name: "draggingFromOpen"
},
State {
name: "draggingFromClosed"
PropertyChanges {
target: window
offset: units.gridUnit * 4
}
}
]
transitions: [
Transition {
to: "draggingFromOpen"
},
Transition {
SequentialAnimation {
PropertyAnimation {
target: window
duration: units.longDuration
easing.type: Easing.InOutQuad
properties: "offset"
}
ScriptAction {
script: {
if (mouseArea.state == "closed") {
window.visible = false;
}
}
}
}
}
]
} }
} }

View file

@ -61,10 +61,10 @@ PlasmaCore.ColorScope {
applet.anchors.fill = container; applet.anchors.fill = container;
applet.visible = true; applet.visible = true;
container.visible = true; container.visible = true;
if (applet.pluginName == "org.kde.plasma.notifications") { if (applet.pluginName == "org.kde.phone.notifications") {
applet.expanded = true; // applet.expanded = true;
applet.fullRepresentationItem.parent = notificationsParent; applet.fullRepresentationItem.parent = notificationsParent;
notificationsParent.applet = applet.fullRepresentationItem; notificationsParent.applet = applet;
applet.fullRepresentationItem.anchors.fill = notificationsParent; applet.fullRepresentationItem.anchors.fill = notificationsParent;
} }
} }
@ -123,10 +123,6 @@ PlasmaCore.ColorScope {
height: root.height height: root.height
color: PlasmaCore.ColorScope.backgroundColor color: PlasmaCore.ColorScope.backgroundColor
//used as is needed somebody to filter events
/*MouseArea {
anchors.fill: parent
}*/
Loader { Loader {
id: strengthLoader id: strengthLoader
height: parent.height height: parent.height
@ -205,20 +201,34 @@ PlasmaCore.ColorScope {
id: slidingPanel id: slidingPanel
width: plasmoid.availableScreenRect.width width: plasmoid.availableScreenRect.width
height: plasmoid.availableScreenRect.height height: plasmoid.availableScreenRect.height
peekHeight: quickSettingsParent.height + notificationsParent.minimumHeight + root.height
contents: Item { contents: Item {
id: panelContents id: panelContents
anchors.fill: parent anchors.fill: parent
implicitHeight: quickSettingsParent.height + notificationsParent.height + root.height
Rectangle { Rectangle {
id: quickSettingsParent id: quickSettingsParent
parent: slidingPanel.fixedArea
color: PlasmaCore.ColorScope.backgroundColor color: PlasmaCore.ColorScope.backgroundColor
z: 2 z: 2
anchors { anchors {
left: parent.left left: parent.left
top: parent.top
right: parent.right right: parent.right
} }
y: Math.min(0, slidingPanel.offset - height - root.height)
property var applet property var applet
height: applet ? applet.fullRepresentationItem.Layout.minimumHeight : 0 height: applet ? applet.fullRepresentationItem.Layout.minimumHeight : 0
Rectangle {
anchors {
left: parent.left
right: parent.right
bottom:parent.bottom
}
height: units.devicePixelRatio
color: PlasmaCore.ColorScope.textColor
opacity: 0.2
visible: slidingPanel.offset < panelContents.height
}
} }
Item { Item {
id: notificationsParent id: notificationsParent
@ -229,8 +239,8 @@ PlasmaCore.ColorScope {
bottomMargin: root.height bottomMargin: root.height
} }
property var applet property var applet
clip: true height: applet ? applet.fullRepresentationItem.Layout.maximumHeight : 0
height: panelContents.height - quickSettingsParent.height-root.height//applet ? applet.Layout.minimumHeight : 0 property int minimumHeight: applet ? applet.fullRepresentationItem.Layout.minimumHeight : 0
} }
} }
} }

View file

@ -12,7 +12,7 @@ for (var j = 0; j < desktopsArray.length; j++) {
desktopsArray[0].addWidget("org.kde.plasma.analogclock"); desktopsArray[0].addWidget("org.kde.plasma.analogclock");
var panel = new Panel("org.kde.phone.panel"); var panel = new Panel("org.kde.phone.panel");
panel.addWidget("org.kde.plasma.notifications"); panel.addWidget("org.kde.phone.notifications");
panel.addWidget("org.kde.phone.quicksettings"); panel.addWidget("org.kde.phone.quicksettings");
panel.addWidget("org.kde.plasma.networkmanagement"); panel.addWidget("org.kde.plasma.networkmanagement");
panel.addWidget("org.kde.plasma.battery"); panel.addWidget("org.kde.plasma.battery");