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
//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
anchors.bottomMargin: 10
drag.axis: Drag.XAxis
@ -39,12 +39,19 @@ MouseArea {
property string source: model.source
property var actions: model.actions
opacity: 1 - Math.abs(x) / (width/2)
Behavior on x {
NumberAnimation {
easing.type: Easing.InOutQuad
duration: units.longDuration
}
}
Behavior on height {
NumberAnimation {
easing.type: Easing.InOutQuad
duration: units.longDuration
}
}
onReleased: {
if (drag.active) {
@ -66,22 +73,18 @@ MouseArea {
}
PlasmaCore.FrameSvgItem {
Rectangle {
id: background
imagePath: "widgets/background"
anchors {
fill: parent
rightMargin: -notificationItem.width
leftMargin: units.gridUnit
}
colorGroup: PlasmaCore.ColorScope.colorGroup
anchors.fill: parent
color: Qt.rgba(PlasmaCore.ColorScope.textColor.r, PlasmaCore.ColorScope.textColor.g, PlasmaCore.ColorScope.textColor.b, notificationItem.pressed ? 0.5 : 0.2)
}
PlasmaComponents.ToolButton {
id: closeButton
anchors {
left: parent.left
right: parent.right
verticalCenter: parent.verticalCenter
leftMargin: units.gridUnit / 2
rightMargin: units.gridUnit
}
iconSource: "window-close"
flat: false
@ -90,52 +93,32 @@ MouseArea {
}
}
PlasmaComponents.Label {
id: appLabel
anchors.leftMargin: units.gridUnit * 3
color: PlasmaCore.ColorScope.textColor
text: model.appName
}
Column {
ColumnLayout {
id: messageLayout
anchors {
verticalCenter: parent.verticalCenter
left: parent.left
right: icon.left
leftMargin: units.gridUnit * 3
left: icon.right
right: notificationItem.expanded ? actionsLayout.left : closeButton.left
leftMargin: units.gridUnit
rightMargin: units.gridUnit
}
PlasmaComponents.Label {
id: summaryLabel
anchors.right: parent.right
width: messageLayout.width - appLabel.width
horizontalAlignment: Qt.AlignRight
Layout.fillWidth: true
verticalAlignment: Qt.AlignVCenter
text: summary + (!notificationItem.expanded && body ? "..." : "")
wrapMode: Text.WordWrap
text: model.appName + " " + summary
elide: Text.ElideRight
}
PlasmaComponents.Label {
id: bodyLabel
anchors {
right: parent.right
left: parent.left
}
visible: height > 0
height: notificationItem.expanded && body != undefined && body ? implicitHeight : 0
clip: true
horizontalAlignment: Qt.AlignRight
Layout.fillWidth: true
visible: text.length > 0
opacity: 0.8
verticalAlignment: Qt.AlignVCenter
text: body
wrapMode: Text.WordWrap
Behavior on height {
NumberAnimation {
duration: units.longDuration
easing.type: Easing.InOutQuad
}
}
}
}
@ -143,21 +126,21 @@ MouseArea {
PlasmaCore.IconItem {
id: icon
anchors {
right: notificationItem.right
verticalCenter: parent.verticalCenter
}
x: units.gridUnit
width: units.iconSizes.medium
height: width
source: appIcon && appIcon.length > 0 ? appIcon : "preferences-desktop-notification"
colorGroup: PlasmaCore.ColorScope.colorGroup
}
Flow {
Column {
id: actionsLayout
anchors {
left: messageLayout.left
right: messageLayout.right
top: messageLayout.bottom
topMargin: units.smallSpacing
right: closeButton.left
rightMargin: units.gridUnit
verticalCenter: parent.verticalCenter
}
opacity: notificationItem.expanded && notificationItem.actions && notificationItem.actions.count > 0 ? 1 : 0
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
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) {
// Do not show duplicated notifications
@ -133,14 +136,40 @@ Item {
ListModel {
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
spacing: units.smallSpacing
anchors.fill: parent
spacing: units.largeSpacing
anchors {
fill: parent
leftMargin: units.largeSpacing
rightMargin: units.largeSpacing
}
interactive: false
cacheBuffer: 2000
cacheBuffer: 200000
z: 1
verticalLayoutDirection: ListView.BottomToTop

View file

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

View file

@ -28,7 +28,7 @@ FullScreenPanel {
id: window
property int offset: 0
property int overShoot: units.gridUnit * 2
property int peekHeight
color: "transparent"
property alias contents: contentArea.data
@ -36,108 +36,108 @@ FullScreenPanel {
width: Screen.width
height: Screen.height
property alias fixedArea: fixedArea
function open() {
mouseArea.state = "open";
window.visible = true;
openAnim.running = true;
}
function close() {
mouseArea.state = "closed";
closeAnim.running = true;
}
function updateState() {
var delta = offset - mouseArea.startOffset;
if (delta > units.gridUnit * 8) {
mouseArea.state = "open";
} else if (delta < -units.gridUnit * 8) {
mouseArea.state = "closed";
} else {
mouseArea.state = mouseArea.startState;
if (offset < peekHeight / 2) {
close();
} else if (offset < peekHeight) {
open();
}
mouseArea.startState = mouseArea.state;
}
onVisibleChanged: {
if (visible) {
mouseArea.state = "draggingFromClosed";
mouseArea.startOffset = units.gridUnit * 4;
window.width = Screen.width;
window.height = Screen.height;
}
}
MouseArea {
id: mouseArea
y: 0
width: Screen.width
height: Screen.height
//clip: true
state: "closed"
drag.filterChildren: true
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;
SequentialAnimation {
id: closeAnim
PropertyAnimation {
target: window
duration: units.longDuration
easing.type: Easing.InOutQuad
properties: "offset"
from: window.offset
to: 0
}
onPositionChanged: {
if (startMouseY < contentArea.height - units.iconSizes.large) {
//TODO: test if we can do without this return
// 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();
ScriptAction {
script: {
window.visible = false;
}
}
}
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 {
anchors.fill: parent
color: Qt.rgba(0, 0, 0, 0.6-Math.abs(slidingArea.y/slidingArea.height))
anchors {
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 {
id: contentArea
anchors {
fill: parent
topMargin: overShoot
left: parent.left
right: parent.right
}
height: children[0].implicitHeight
}
color: PlasmaCore.ColorScope.backgroundColor
Rectangle {
height: units.gridUnit
anchors {
left: parent.left
right: parent.right
top: parent.bottom
top: contentArea.bottom
}
gradient: Gradient {
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
MouseArea {
z: -1
anchors.fill: parent
onClicked: {
if (mouseArea.startMouseY < contentArea.height - units.iconSizes.large) {
return;
}
mouseArea.state = "closed";
//window.visible = false;
Item {
id: fixedArea
anchors {
left: parent.left
right: parent.right
top: parent.top
}
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.visible = true;
container.visible = true;
if (applet.pluginName == "org.kde.plasma.notifications") {
applet.expanded = true;
if (applet.pluginName == "org.kde.phone.notifications") {
// applet.expanded = true;
applet.fullRepresentationItem.parent = notificationsParent;
notificationsParent.applet = applet.fullRepresentationItem;
notificationsParent.applet = applet;
applet.fullRepresentationItem.anchors.fill = notificationsParent;
}
}
@ -123,10 +123,6 @@ PlasmaCore.ColorScope {
height: root.height
color: PlasmaCore.ColorScope.backgroundColor
//used as is needed somebody to filter events
/*MouseArea {
anchors.fill: parent
}*/
Loader {
id: strengthLoader
height: parent.height
@ -205,20 +201,34 @@ PlasmaCore.ColorScope {
id: slidingPanel
width: plasmoid.availableScreenRect.width
height: plasmoid.availableScreenRect.height
peekHeight: quickSettingsParent.height + notificationsParent.minimumHeight + root.height
contents: Item {
id: panelContents
anchors.fill: parent
implicitHeight: quickSettingsParent.height + notificationsParent.height + root.height
Rectangle {
id: quickSettingsParent
parent: slidingPanel.fixedArea
color: PlasmaCore.ColorScope.backgroundColor
z: 2
anchors {
left: parent.left
top: parent.top
right: parent.right
}
y: Math.min(0, slidingPanel.offset - height - root.height)
property var applet
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 {
id: notificationsParent
@ -229,8 +239,8 @@ PlasmaCore.ColorScope {
bottomMargin: root.height
}
property var applet
clip: true
height: panelContents.height - quickSettingsParent.height-root.height//applet ? applet.Layout.minimumHeight : 0
height: applet ? applet.fullRepresentationItem.Layout.maximumHeight : 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");
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.plasma.networkmanagement");
panel.addWidget("org.kde.plasma.battery");