desktop icon indicating copy to clipboard operation
desktop copied to clipboard

Implement keyboard navigation for ActivityList in tray Window

Open allexzander opened this issue 3 years ago • 2 comments
trafficstars

How to use GitHub

  • Please use the 👍 reaction to show that you want to have the same feature implemented.
  • Please don't comment if you have no relevant information to add. It's just extra noise for everyone subscribed to this issue.
  • Subscribe to receive notifications on status change and new comments.

Feature description

We need to implement keyboard navigation in the ActivityList in the tray window. This includes focusing with Tab and navigation with arrows.

Suggestions from @CarlSchwan and his patch - in the first comment

allexzander avatar Jan 28 '22 15:01 allexzander

diff --git a/src/gui/tray/ActivityActionButton.qml b/src/gui/tray/ActivityActionButton.qml index 8b828eed2..03ce9ca8b 100644 --- a/src/gui/tray/ActivityActionButton.qml +++ b/src/gui/tray/ActivityActionButton.qml @@ -17,6 +17,8 @@ Item { property color textColor: Style.unifiedSearchResulTitleColor property color textColorHovered: Style.unifiedSearchResulSublineColor

  • property bool isCurrentItem: false

  • signal clicked()

    Loader { @@ -31,6 +33,7 @@ Item {

            textColor: root.textColor
            textColorHovered: root.textColorHovered
    
  •         activeFocusOnTab: isCurrentItem
    
            onClicked: root.clicked()
       }
    

@@ -60,6 +63,7 @@ Item { bgColor: Style.ncBlue

         onClicked: root.clicked()
  •        activeFocusOnTab: isCurrentItem
       }
    
    } } diff --git a/src/gui/tray/ActivityItem.qml b/src/gui/tray/ActivityItem.qml index 3de983ab7..ce1150507 100644 --- a/src/gui/tray/ActivityItem.qml +++ b/src/gui/tray/ActivityItem.qml @@ -1,10 +1,10 @@ import QtQml 2.15 import QtQuick 2.15 -import QtQuick.Controls 2.3 +import QtQuick.Controls 2.12 import QtQuick.Layouts 1.2 import Style 1.0

-MouseArea { +ItemDelegate { id: root

 readonly property int maxActionButtons: 2

@@ -32,30 +32,27 @@ MouseArea { signal fileActivityButtonClicked(string absolutePath)

 enabled: (model.path !== "" || model.link !== "" || model.isCurrentUserFileActivity === true)
  • hoverEnabled: true

  • height: childrenRect.height

    ToolTip.visible: containsMouse && !activityContent.childHovered && model.displayLocation !== "" ToolTip.delay: Qt.styleHints.mousePressAndHoldInterval ToolTip.text: qsTr("In %1").arg(model.displayLocation)

  • Accessible.role: Accessible.ListItem Accessible.name: (model.path !== "" && model.displayPath !== "") ? qsTr("Open %1 locally").arg(model.displayPath) : model.message

  • Accessible.onPressAction: root.clicked()

  • Rectangle {

  • background: Rectangle { id: activityHover
  •    anchors.fill: parent
    
  •    color: (parent.containsMouse ? Style.lightHover : "transparent")
    
  •    color: root.hovered || root.visualFocus || root.highlighted ? Style.lightHover : "transparent"
    
    }
  • ColumnLayout {
  •    anchors.left: root.left
    
  •    anchors.right: root.right
    
  •    anchors.leftMargin: 15
    
  •    anchors.rightMargin: 10
    
  • leftPadding: 15

  • rightPadding: 10

  • topPadding: 5

  • bottomPadding: 5

  • topInset: 0

  • bottomInset: 0

  • highlighted: ListView.isCurrentItem

  • KeyNavigation.right: activityActions

  • contentItem: ColumnLayout { spacing: 0

    ActivityItemContent {
    

@@ -71,6 +68,7 @@ MouseArea {

         onShareButtonClicked: Systray.openShareDialog(model.displayPath, model.absolutePath)
         onDismissButtonClicked: root.shareButtonClicked()
  •        isCurrentItem: root.ListView.isCurrentItem
       }
    
       ActivityItemActions {
    

@@ -93,6 +91,7 @@ MouseArea { flickable: root.flickable

         onTriggerAction: activityModel.triggerAction(model.index, actionIndex)
  •        isCurrentItem: root.ListView.isCurrentItem
       }
    

    } } diff --git a/src/gui/tray/ActivityItemActions.qml b/src/gui/tray/ActivityItemActions.qml index a8bcbc2a9..e642dd20e 100644 --- a/src/gui/tray/ActivityItemActions.qml +++ b/src/gui/tray/ActivityItemActions.qml @@ -16,6 +16,7 @@ RowLayout { property color moreActionsButtonColor: "transparent"

    property int maxActionButtons: 0

  • property bool isCurrentItem: false

    property Flickable flickable

@@ -68,6 +69,7 @@ RowLayout { textColorHovered: imageSource !== "" ? Style.lightHover : Style.unifiedSearchResulTitleColor

         bold: primary
  •        isCurrentItem: root.isCurrentItem
    
           onClicked: root.triggerAction(actionIndex)
       }
    

@@ -92,7 +94,7 @@ RowLayout { icon.source: "qrc:///client/theme/more.svg"

         background: Rectangle {
  •            color: parent.hovered ? "white" : root.moreActionsButtonColor
    
  •            color: parent.hovered || parent.visualFocus ? "white" : root.moreActionsButtonColor
               radius: 25
           }
    

@@ -105,6 +107,7 @@ RowLayout { Accessible.onPressAction: moreActionsButton.clicked()

         onClicked:  moreActionsButtonContextMenuContainer.open();
  •        activeFocusOnTab: root.isCurrentItem
    
           Connections {
               target: root.flickable
    

diff --git a/src/gui/tray/ActivityItemContent.qml b/src/gui/tray/ActivityItemContent.qml index a0a2bb6a6..75806b44c 100644 --- a/src/gui/tray/ActivityItemContent.qml +++ b/src/gui/tray/ActivityItemContent.qml @@ -15,6 +15,7 @@ RowLayout { property bool showDismissButton: false

 property bool childHovered: shareButton.hovered || dismissActionButton.hovered
  • property bool isCurrentItem: false

    signal dismissButtonClicked() signal shareButtonClicked() @@ -29,7 +30,7 @@ RowLayout { Layout.preferredHeight: 32

    verticalAlignment: Qt.AlignCenter
    
  •    source: icon
    
  •    source: model.icon
       sourceSize.height: 64
       sourceSize.width: 64
    
    } @@ -75,42 +76,34 @@ RowLayout { } }
  • Column {
  •    id: dismissActionButtonContainer
    
  •    Layout.preferredWidth: parent.height * 0.70
    
  •    Layout.preferredHeight: parent.height * 0.70
    
  •    Button {
    
  •        id: dismissActionButton
    
  • Button {
  •    id: dismissActionButton
    
  •        anchors.fill: parent
    
  •    Layout.minimumWidth: implicitWidth
    
  •    Layout.maximumWidth: implicitWidth
    
  •    Layout.minimumHeight: implicitWidth
    
  •    Layout.maximumHeight: implicitWidth
    
  •    Layout.alignment: Qt.AligntCenter
    
  •    padding: 10
    
  •        anchors.margins: 10
    
  •    ToolTip.visible: hovered
    
  •    ToolTip.delay: Qt.styleHints.mousePressAndHoldInterval
    
  •    ToolTip.text: qsTr("Dismiss")
    
  •        ToolTip.visible: hovered
    
  •        ToolTip.delay: Qt.styleHints.mousePressAndHoldInterval
    
  •        ToolTip.text: qsTr("Dismiss")
    
  •    Accessible.name: ToolTip.text
    
  •        Accessible.role: Accessible.Button
    
  •        Accessible.name: qsTr("Dismiss")
    
  •        Accessible.onPressAction: dismissActionButton.clicked()
    
  •    visible: root.showDismissButton && !shareButton.visible
    
  •    activeFocusOnTab: root.isCurrentItem
    
  •        visible: root.showDismissButton && !shareButton.visible
    
  •        background: Rectangle {
    
  •            color: "transparent"
    
  •        }
    
  •        contentItem: Image {
    
  •            anchors.fill: parent
    
  •            source: parent.hovered ? "image://svgimage-custom-color/clear.svg" + "/" + "black" : "image://svgimage-custom-color/clear.svg" + "/" + "grey"
    
  •            sourceSize.width: 24
    
  •            sourceSize.height: 24
    
  •        }
    
  •        onClicked: activityModel.triggerDismiss(model.index)
    
  •    background: Image {
    
  •        width: 24
    
  •        height: 24
    
  •        source: "image://svgimage-custom-color/clear.svg/" + (parent.hovered || parent.visualFocus ? "black" : "grey")
    
  •        sourceSize.width: 24
    
  •        sourceSize.height: 24
       }
    
  •    onClicked: activityModel.triggerDismiss(model.index)
    

    }

    CustomButton { @@ -129,5 +122,6 @@ RowLayout { bgColor: Style.ncBlue

       onClicked: root.dismissButtonClicked()
    
  •    activeFocusOnTab: root.isCurrentItem
    

    } } diff --git a/src/gui/tray/ActivityList.qml b/src/gui/tray/ActivityList.qml index cad72114e..44e767dbd 100644 --- a/src/gui/tray/ActivityList.qml +++ b/src/gui/tray/ActivityList.qml @@ -20,6 +20,12 @@ ScrollView { data: NC.WheelHandler { target: controlRoot.contentItem }

  • onActiveFocusChanged: if (activeFocus) {

  •    activityList.forceActiveFocus();
    
  •    if (activityList.currentIndex === -1) {
    
  •        activityList.currentIndex = 0;
    
  •    }
    
  • }

    ListView { id: activityList @@ -31,7 +37,8 @@ ScrollView {

       clip: true
    
  •    spacing: 10
    
  •    spacing: 0
    
  •    currentIndex: -1
    
       delegate: ActivityItem {
           isFileActivityList: controlRoot.isFileActivityList
    

diff --git a/src/gui/tray/CustomButton.qml b/src/gui/tray/CustomButton.qml index ae461eb9b..6d10f1808 100644 --- a/src/gui/tray/CustomButton.qml +++ b/src/gui/tray/CustomButton.qml @@ -19,22 +19,19 @@ Button {

 background: Rectangle {
     color: root.bgColor
  •    opacity: parent.hovered ? 1.0 : 0.3
    
  •    opacity: parent.visualFocus || parent.hovered ? 1.0 : 0.3
       radius: 25
    

    }

  • leftPadding: root.text === "" ? 5 : 10

  • rightPadding: root.text === "" ? 5 : 10

    contentItem: RowLayout {

  •    anchors.left: parent.left
    
  •    anchors.right: parent.right
    
  •    anchors.leftMargin: root.text === "" ? 5 : 10
    
  •    anchors.rightMargin: root.text === "" ? 5 : 10
    
  •    Image {
           id: icon
    
           Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
    
  •        source: root.hovered ? root.imageSourceHover : root.imageSource
    
  •        source: root.hovered || root.visualFocus ? root.imageSourceHover : root.imageSource
       }
    
       Label {
    

@@ -46,7 +43,7 @@ Button {

         visible: root.text !== ""
  •        color: root.hovered ? root.textColorHovered : root.textColor
    
  •        color: root.hovered || root.visualFocus ? root.textColorHovered : root.textColor
    
           horizontalAlignment: Text.AlignHCenter
           verticalAlignment: Text.AlignVCenter
    

@@ -58,6 +55,6 @@ Button { ToolTip { text: root.toolTipText delay: 1000

  •    visible: root.toolTipText !== "" && root.hovered
    
  •    visible: root.toolTipText !== "" && (root.hovered || root.visualFocus)
    
    } } diff --git a/src/gui/tray/CustomTextButton.qml b/src/gui/tray/CustomTextButton.qml index fa62c4fd3..7f36f0581 100644 --- a/src/gui/tray/CustomTextButton.qml +++ b/src/gui/tray/CustomTextButton.qml @@ -1,31 +1,23 @@ import QtQuick 2.15 -import QtQuick.Controls 2.3 +import QtQuick.Controls 2.12 import Style 1.0

-Item { +AbstractButton { id: root

  • property string text: "" property string toolTipText: ""

    property color textColor: Style.unifiedSearchResulTitleColor property color textColorHovered: Style.unifiedSearchResulSublineColor

  • property alias hovered: mouseArea.containsMouse

  • signal clicked()

  • Accessible.role: Accessible.Button Accessible.name: root.text !== "" ? root.text : (root.toolTipText !== "" ? root.toolTipText : qsTr("Activity action button"))

  • Accessible.onPressAction: root.clicked()

  • Label {

  • contentItem: Label { id: label visible: root.text !== "" text: root.text font.underline: true
  •    color: root.hovered ? root.textColorHovered : root.textColor
    
  •    anchors.centerIn: parent
    
  •    color: root.hovered || parent.visualFocus ? root.textColorHovered : root.textColor
       width: parent.width
    
       horizontalAlignment: Text.AlignLeft
    

@@ -36,13 +28,6 @@ Item { ToolTip { text: root.toolTipText delay: 1000

  •    visible: root.toolTipText !== "" && root.hovered
    
  • }
  • MouseArea {
  •    id: mouseArea
    
  •    anchors.fill: label
    
  •    onClicked: root.clicked()
    
  •    hoverEnabled: true
    
  •    visible: root.toolTipText !== "" && (root.hovered || root.visualFocus)
    
    } }

allexzander avatar Jan 28 '22 15:01 allexzander

How much time is this? I would assume <2 wk and thus it can be done when time permits?

tobiasKaminsky avatar Jul 26 '22 11:07 tobiasKaminsky