diff options
author | Camila <hello@camila.codes> | 2021-06-21 21:50:49 +0300 |
---|---|---|
committer | Camila <hello@camila.codes> | 2021-07-21 18:03:26 +0300 |
commit | 6886d6213afa008e91c4b28e3c98325dab71ec2b (patch) | |
tree | 2cb42632cf9d35eb32334b4a366fd6ede22bf943 | |
parent | 79dd4f73fe9745c7c9c480c9c62ef9af780f9c10 (diff) |
Add custom component ActivityItem.
That also addresses QML warnings.
Signed-off-by: Camila <hello@camila.codes>
-rw-r--r-- | resources.qrc | 1 | ||||
-rw-r--r-- | src/gui/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/gui/tray/ActivityActionButton.qml | 2 | ||||
-rw-r--r-- | src/gui/tray/ActivityItem.qml | 262 | ||||
-rw-r--r-- | src/gui/tray/Window.qml | 293 | ||||
-rw-r--r-- | theme/Style/Style.qml | 1 |
6 files changed, 270 insertions, 290 deletions
diff --git a/resources.qrc b/resources.qrc index f2f122987..54c4b5cd9 100644 --- a/resources.qrc +++ b/resources.qrc @@ -6,5 +6,6 @@ <file>theme/Style/Style.qml</file> <file>theme/Style/qmldir</file> <file>src/gui/tray/ActivityActionButton.qml</file> + <file>src/gui/tray/ActivityItem.qml</file> </qresource> </RCC> diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index 6b04723c2..0368dd197 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -36,6 +36,7 @@ set(client_UI_SRCS proxyauthdialog.ui mnemonicdialog.ui tray/ActivityActionButton.qml + tray/ActivityItem.qml tray/Window.qml tray/UserLine.qml wizard/flow2authwidget.ui diff --git a/src/gui/tray/ActivityActionButton.qml b/src/gui/tray/ActivityActionButton.qml index e75522f4c..6cf3d3495 100644 --- a/src/gui/tray/ActivityActionButton.qml +++ b/src/gui/tray/ActivityActionButton.qml @@ -11,7 +11,7 @@ Item { property string text: "" // font value - property string font: label.font + property var font: label.font // icon value property string imageSource: "" diff --git a/src/gui/tray/ActivityItem.qml b/src/gui/tray/ActivityItem.qml new file mode 100644 index 000000000..c107583ee --- /dev/null +++ b/src/gui/tray/ActivityItem.qml @@ -0,0 +1,262 @@ +import QtQml 2.12 +import QtQuick 2.9 +import QtQuick.Controls 2.2 +import QtQuick.Layouts 1.2 +import Style 1.0 +import com.nextcloud.desktopclient 1.0 + +MouseArea { + id: activityMouseArea + enabled: (path !== "" || link !== "") + hoverEnabled: true + + Rectangle { + anchors.left: activityMouseArea.left + anchors.margins: 2 + width: Style.trayWindowMouseAreaWidth + height: Style.trayWindowHeaderHeight + color: (parent.containsMouse ? Style.lightHover : "transparent") + } + + RowLayout { + id: activityItem + + readonly property variant links: model.links + + readonly property int itemIndex: model.index + + width: activityMouseArea.width + height: Style.trayWindowHeaderHeight + spacing: 0 + + Accessible.role: Accessible.ListItem + Accessible.name: path !== "" ? qsTr("Open %1 locally").arg(displayPath) + : message + Accessible.onPressAction: activityMouseArea.clicked() + + Image { + id: activityIcon + Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter + Layout.leftMargin: 8 + Layout.preferredWidth: shareButton.icon.width + Layout.preferredHeight: shareButton.icon.height + verticalAlignment: Qt.AlignCenter + cache: true + source: icon + sourceSize.height: 64 + sourceSize.width: 64 + } + + Column { + id: activityTextColumn + Layout.leftMargin: 8 + Layout.topMargin: 4 + Layout.bottomMargin: 4 + Layout.fillWidth: true + Layout.fillHeight: true + spacing: 4 + Layout.alignment: Qt.AlignLeft + + Text { + id: activityTextTitle + text: (type === "Activity" || type === "Notification") ? subject : message + width: parent.width + elide: Text.ElideRight + font.pixelSize: Style.topLinePixelSize + color: activityTextTitleColor + } + + Text { + id: activityTextInfo + text: (type === "Sync") ? displayPath + : (type === "File") ? subject + : (type === "Notification") ? message + : "" + height: (text === "") ? 0 : activityTextTitle.height + width: parent.width + elide: Text.ElideRight + font.pixelSize: Style.subLinePixelSize + } + + Text { + id: activityTextDateTime + text: dateTime + height: (text === "") ? 0 : activityTextTitle.height + width: parent.width + elide: Text.ElideRight + font.pixelSize: Style.subLinePixelSize + color: "#808080" + } + } + + RowLayout { + id: activityActionsLayout + spacing: 0 + Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter + Layout.minimumWidth: 28 + Layout.fillWidth: true + + function actionButtonIcon(actionIndex) { + const verb = String(model.links[actionIndex].verb); + if (verb === "WEB" && (model.objectType === "chat" || model.objectType === "call")) { + return "qrc:///client/theme/reply.svg"; + } else if (verb === "DELETE") { + return "qrc:///client/theme/close.svg"; + } + + return "qrc:///client/theme/confirm.svg"; + } + + Repeater { + model: activityItem.links.length > activityListView.maxActionButtons ? 1 : activityItem.links.length + + ActivityActionButton { + id: activityActionButton + + readonly property int actionIndex: model.index + readonly property bool primary: model.index === 0 && String(activityItem.links[actionIndex].verb) !== "DELETE" + + Layout.fillHeight: true + + text: !primary ? "" : activityItem.links[actionIndex].label + + imageSource: !primary ? activityActionsLayout.actionButtonIcon(actionIndex) : "" + + textColor: primary ? Style.ncBlue : "black" + textColorHovered: Style.lightHover + + textBorderColor: Style.ncBlue + + textBgColor: "transparent" + textBgColorHovered: Style.ncBlue + + tooltipText: activityItem.links[actionIndex].label + + Layout.minimumWidth: primary ? 80 : -1 + Layout.minimumHeight: parent.height + + Layout.preferredWidth: primary ? -1 : parent.height + + onClicked: activityModel.triggerAction(activityItem.itemIndex, actionIndex) + } + + } + + Button { + id: moreActionsButton + + Layout.preferredWidth: parent.height + Layout.preferredHeight: parent.height + Layout.alignment: Qt.AlignRight + + flat: true + hoverEnabled: true + visible: activityItem.links.length > activityListView.maxActionButtons + display: AbstractButton.IconOnly + icon.source: "qrc:///client/theme/more.svg" + icon.color: "transparent" + background: Rectangle { + color: parent.hovered ? Style.lightHover : "transparent" + } + ToolTip.visible: hovered + ToolTip.delay: 1000 + ToolTip.text: qsTr("Show more actions") + + Accessible.role: Accessible.Button + Accessible.name: qsTr("Show more actions") + Accessible.onPressAction: moreActionsButton.clicked() + + onClicked: moreActionsButtonContextMenu.popup(); + + Connections { + target: trayWindow + onActiveChanged: { + if (!trayWindow.active) { + moreActionsButtonContextMenu.close(); + } + } + } + + Connections { + target: activityListView + + onMovementStarted: { + moreActionsButtonContextMenu.close(); + } + } + + Container { + id: moreActionsButtonContextMenuContainer + visible: moreActionsButtonContextMenu.opened + + width: moreActionsButtonContextMenu.width + height: moreActionsButtonContextMenu.height + anchors.right: moreActionsButton.right + anchors.top: moreActionsButton.top + + Menu { + id: moreActionsButtonContextMenu + anchors.centerIn: parent + + // transform model to contain indexed actions with primary action filtered out + function actionListToContextMenuList(actionList) { + // early out with non-altered data + if (activityItem.links.length <= activityListView.maxActionButtons) { + return actionList; + } + + // add index to every action and filter 'primary' action out + var reducedActionList = actionList.reduce(function(reduced, action, index) { + if (!action.primary) { + var actionWithIndex = { actionIndex: index, label: action.label }; + reduced.push(actionWithIndex); + } + return reduced; + }, []); + + + return reducedActionList; + } + + Repeater { + id: moreActionsButtonContextMenuRepeater + + model: moreActionsButtonContextMenu.actionListToContextMenuList(activityItem.links) + + delegate: MenuItem { + id: moreActionsButtonContextMenuEntry + text: model.modelData.label + onTriggered: activityModel.triggerAction(activityItem.itemIndex, model.modelData.actionIndex) + } + } + } + } + } + + Button { + id: shareButton + + Layout.preferredWidth: (path === "") ? 0 : parent.height + Layout.preferredHeight: parent.height + Layout.alignment: Qt.AlignRight + flat: true + hoverEnabled: true + visible: (path === "") ? false : true + display: AbstractButton.IconOnly + icon.source: "qrc:///client/theme/share.svg" + icon.color: "transparent" + background: Rectangle { + color: parent.hovered ? Style.lightHover : "transparent" + } + ToolTip.visible: hovered + ToolTip.delay: 1000 + ToolTip.text: qsTr("Open share dialog") + onClicked: Systray.openShareDialog(displayPath,absolutePath) + + Accessible.role: Accessible.Button + Accessible.name: qsTr("Share %1").arg(displayPath) + Accessible.onPressAction: shareButton.clicked() + } + } + } +} diff --git a/src/gui/tray/Window.qml b/src/gui/tray/Window.qml index 6f87772fa..2069f2ae6 100644 --- a/src/gui/tray/Window.qml +++ b/src/gui/tray/Window.qml @@ -1,4 +1,4 @@ -import QtQml 2.1
+import QtQml 2.12
import QtQml.Models 2.1
import QtQuick 2.9
import QtQuick.Window 2.3
@@ -579,296 +579,11 @@ Window { model: activityModel
- delegate: RowLayout {
- id: activityItem
-
- readonly property variant links: model.links
-
- readonly property int itemIndex: model.index
-
- width: parent.width
+ delegate: ActivityItem {
+ width: activityListView.width
height: Style.trayWindowHeaderHeight
- spacing: 0
-
- Accessible.role: Accessible.ListItem
- Accessible.name: path !== "" ? qsTr("Open %1 locally").arg(displayPath)
- : message
- Accessible.onPressAction: activityMouseArea.clicked()
-
- MouseArea {
- id: activityMouseArea
- enabled: (path !== "" || link !== "")
- anchors.left: activityItem.left
- anchors.right: activityActionsLayout.right
- height: parent.height
- anchors.margins: 2
- hoverEnabled: true
- onClicked: activityModel.triggerDefaultAction(model.index)
-
- Rectangle {
- anchors.fill: parent
- color: (parent.containsMouse ? Style.lightHover : "transparent")
- }
- }
-
- Image {
- id: activityIcon
- anchors.left: activityItem.left
- anchors.leftMargin: 8
- anchors.rightMargin: 8
- Layout.preferredWidth: shareButton.icon.width
- Layout.preferredHeight: shareButton.icon.height
- verticalAlignment: Qt.AlignCenter
- cache: true
- source: icon
- sourceSize.height: 64
- sourceSize.width: 64
- }
-
- Column {
- id: activityTextColumn
- anchors.left: activityIcon.right
- anchors.right: activityActionsLayout.left
- anchors.leftMargin: 8
- spacing: 4
- Layout.alignment: Qt.AlignLeft
- Text {
- id: activityTextTitle
- text: (type === "Activity" || type === "Notification") ? subject : message
- width: parent.width
- elide: Text.ElideRight
- font.pixelSize: Style.topLinePixelSize
- color: activityTextTitleColor
- }
-
- Text {
- id: activityTextInfo
- text: (type === "Sync") ? displayPath
- : (type === "File") ? subject
- : (type === "Notification") ? message
- : ""
- height: (text === "") ? 0 : activityTextTitle.height
- width: parent.width
- elide: Text.ElideRight
- font.pixelSize: Style.subLinePixelSize
- }
-
- Text {
- id: activityTextDateTime
- text: dateTime
- height: (text === "") ? 0 : activityTextTitle.height
- width: parent.width
- elide: Text.ElideRight
- font.pixelSize: Style.subLinePixelSize
- color: "#808080"
- }
-
- ToolTip {
- id: toolTip
- visible: activityMouseArea.containsMouse
- text: activityTextTitle.text + ((activityTextInfo.text !== "") ? "\n\n" + activityTextInfo.text : "")
- delay: 250
- timeout: 10000
- // Can be dropped on more recent Qt, but on 5.12 it doesn't wrap...
- contentItem: Text {
- text: toolTip.text
- font: toolTip.font
- wrapMode: Text.Wrap
- color: toolTip.palette.toolTipText
- }
- }
- }
- RowLayout {
- id: activityActionsLayout
- anchors.right: activityItem.right
- spacing: 0
- Layout.alignment: Qt.AlignRight
-
- function actionButtonIcon(actionIndex) {
- const verb = String(model.links[actionIndex].verb);
- if (verb === "WEB" && (model.objectType === "chat" || model.objectType === "call")) {
- return "qrc:///client/theme/reply.svg";
- } else if (verb === "DELETE") {
- return "qrc:///client/theme/close.svg";
- }
-
- return "qrc:///client/theme/confirm.svg";
- }
-
- Repeater {
- model: activityItem.links.length > activityListView.maxActionButtons ? 1 : activityItem.links.length
-
- ActivityActionButton {
- id: activityActionButton
-
- readonly property int actionIndex: model.index
- readonly property bool primary: model.index === 0 && String(activityItem.links[actionIndex].verb) !== "DELETE"
-
- height: activityItem.height
-
- text: !primary ? "" : activityItem.links[actionIndex].label
-
- imageSource: !primary ? activityActionsLayout.actionButtonIcon(actionIndex) : ""
-
- textColor: primary ? Style.ncBlue : "black"
- textColorHovered: Style.lightHover
-
- textBorderColor: Style.ncBlue
-
- textBgColor: "transparent"
- textBgColorHovered: Style.ncBlue
-
- tooltipText: activityItem.links[actionIndex].label
-
- Layout.minimumWidth: primary ? 80 : -1
- Layout.minimumHeight: parent.height
-
- Layout.preferredWidth: primary ? -1 : parent.height
-
- onClicked: activityModel.triggerAction(activityItem.itemIndex, actionIndex)
- }
-
- }
-
- Button {
- id: moreActionsButton
-
- Layout.preferredWidth: parent.height
- Layout.preferredHeight: parent.height
- Layout.alignment: Qt.AlignRight
-
- flat: true
- hoverEnabled: true
- visible: activityItem.links.length > activityListView.maxActionButtons
- display: AbstractButton.IconOnly
- icon.source: "qrc:///client/theme/more.svg"
- icon.color: "transparent"
- background: Rectangle {
- color: parent.hovered ? Style.lightHover : "transparent"
- }
- ToolTip.visible: hovered
- ToolTip.delay: 1000
- ToolTip.text: qsTr("Show more actions")
-
- Accessible.role: Accessible.Button
- Accessible.name: qsTr("Show more actions")
- Accessible.onPressAction: moreActionsButton.clicked()
-
- onClicked: moreActionsButtonContextMenu.popup();
-
- Connections {
- target: trayWindow
- onActiveChanged: {
- if (!trayWindow.active) {
- moreActionsButtonContextMenu.close();
- }
- }
- }
-
- Connections {
- target: activityListView
-
- onMovementStarted: {
- moreActionsButtonContextMenu.close();
- }
- }
-
- Container {
- id: moreActionsButtonContextMenuContainer
- visible: moreActionsButtonContextMenu.opened
-
- width: moreActionsButtonContextMenu.width
- height: moreActionsButtonContextMenu.height
- anchors.right: moreActionsButton.right
- anchors.top: moreActionsButton.top
-
- Menu {
- id: moreActionsButtonContextMenu
- anchors.centerIn: parent
-
- // transform model to contain indexed actions with primary action filtered out
- function actionListToContextMenuList(actionList) {
- // early out with non-altered data
- if (activityItem.links.length <= activityListView.maxActionButtons) {
- return actionList;
- }
-
- // add index to every action and filter 'primary' action out
- var reducedActionList = actionList.reduce(function(reduced, action, index) {
- if (!action.primary) {
- var actionWithIndex = { actionIndex: index, label: action.label };
- reduced.push(actionWithIndex);
- }
- return reduced;
- }, []);
-
-
- return reducedActionList;
- }
-
- Repeater {
- id: moreActionsButtonContextMenuRepeater
-
- model: moreActionsButtonContextMenu.actionListToContextMenuList(activityItem.links)
-
- delegate: MenuItem {
- id: moreActionsButtonContextMenuEntry
- readonly property int actionIndex: model.modelData.actionIndex
- readonly property string label: model.modelData.label
- text: label
- onTriggered: activityModel.triggerAction(activityItem.itemIndex, actionIndex)
- }
- }
- }
- }
- }
-
- Button {
- id: shareButton
-
- Layout.preferredWidth: (path === "") ? 0 : parent.height
- Layout.preferredHeight: parent.height
- Layout.alignment: Qt.AlignRight
- flat: true
- hoverEnabled: true
- visible: (path === "") ? false : true
- display: AbstractButton.IconOnly
- icon.source: "qrc:///client/theme/share.svg"
- icon.color: "transparent"
- background: Rectangle {
- color: parent.hovered ? Style.lightHover : "transparent"
- }
- ToolTip.visible: hovered
- ToolTip.delay: 1000
- ToolTip.text: qsTr("Open share dialog")
- onClicked: Systray.openShareDialog(displayPath,absolutePath)
-
- Accessible.role: Accessible.Button
- Accessible.name: qsTr("Share %1").arg(displayPath)
- Accessible.onPressAction: shareButton.clicked()
- }
- }
- }
-
- /*add: Transition {
- NumberAnimation { properties: "y"; from: -60; duration: 100; easing.type: Easing.Linear }
- }
-
- remove: Transition {
- NumberAnimation { property: "opacity"; from: 1.0; to: 0; duration: 100 }
+ onClicked: activityModel.triggerDefaultAction(model.index)
}
-
- removeDisplaced: Transition {
- SequentialAnimation {
- PauseAnimation { duration: 100}
- NumberAnimation { properties: "y"; duration: 100; easing.type: Easing.Linear }
- }
- }
-
- displaced: Transition {
- NumberAnimation { properties: "y"; duration: 100; easing.type: Easing.Linear }
- }*/
}
-
} // Rectangle trayWindowBackground
}
diff --git a/theme/Style/Style.qml b/theme/Style/Style.qml index ea5aabde0..a1468d727 100644 --- a/theme/Style/Style.qml +++ b/theme/Style/Style.qml @@ -19,6 +19,7 @@ QtObject { // Dimensions and sizes
property int trayWindowWidth: 400
+ property int trayWindowMouseAreaWidth: 396
property int trayWindowHeight: 510
property int trayWindowRadius: 10
property int trayWindowBorderWidth: 1
|