feat(StatusQ.Popups): introduce StatusPopupMenu component

Usage:

```qml
import StatusQ.Popups 0.1

Button {
    onClicked: simpleMenu.popup()
}

StatusPopupMenu {
    id: simpleMenu
    StatusMenuItem {
        text: "One"
    }

    StatusMenuItem {
        text: "Two"
    }

    StatusMenuItem {
        text: "Three"
    }
}
```

Closes #96 #74
This commit is contained in:
Pascal Precht 2021-06-02 12:41:31 +02:00 committed by Michał Cieślak
parent cd2fa3d0b7
commit 82643816f6
11 changed files with 313 additions and 1 deletions

View File

@ -12,6 +12,7 @@ These modules are:
- [StatusQ.Components](https://github.com/status-im/StatusQ/blob/master/src/StatusQ/Controls/qmldir)
- [StatusQ.Controls](https://github.com/status-im/StatusQ/blob/master/src/StatusQ/Components/qmldir)
- [StatusQ.Layout](https://github.com/status-im/StatusQ/blob/master/src/StatusQ/Layout/qmldir)
- [StatusQ.Popups](https://github.com/status-im/StatusQ/blob/master/src/StatusQ/Popups/qmldir)
Provided components can be viewed and tested in the [sandbox application](#viewing-and-testing-components) that comes with this repository.
Other than that, modules and components can be used as expected.

View File

@ -6,6 +6,7 @@ import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
import StatusQ.Components 0.1
import StatusQ.Layout 0.1
import StatusQ.Popups 0.1
Rectangle {
id: demoApp
@ -180,9 +181,37 @@ Rectangle {
notificationCount: 1
onMenuButtonClicked: notificationCount += 1
onMenuButtonClicked: contextMenu.popup()
onNotificationButtonClicked: notificationCount = 0
StatusPopupMenu {
id: contextMenu
StatusMenuItem {
text: "Mute Chat"
icon.name: "notification"
}
StatusMenuItem {
text: "Mark as Read"
icon.name: "checkmark-circle"
}
StatusMenuItem {
text: "Clear History"
icon.name: "close-circle"
}
StatusMenuSeparator {}
StatusMenuItem {
text: "Leave Chat"
icon.name: "arrow-right"
icon.width: 14
iconRotation: 180
type: StatusMenuItem.Type.Danger
}
}
}
}
}
}

View File

@ -0,0 +1,72 @@
import QtQuick 2.14
import QtQuick.Layouts 1.14
import QtQuick.Controls 2.13
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
import StatusQ.Popups 0.1
GridLayout {
columns: 1
columnSpacing: 5
rowSpacing: 5
StatusButton {
text: "Simple"
onClicked: simpleMenu.popup()
}
StatusButton {
text: "Complex"
onClicked: complexMenu.popup()
}
StatusPopupMenu {
id: simpleMenu
StatusMenuItem {
text: "One"
}
StatusMenuItem {
text: "Two"
}
StatusMenuItem {
text: "Three"
}
}
StatusPopupMenu {
id: complexMenu
subMenuItemIcons: ['info']
StatusMenuItem {
text: "One"
icon.name: "info"
}
StatusMenuSeparator {}
StatusMenuItem {
text: "Two"
icon.name: "info"
}
StatusMenuItem {
text: "Three"
icon.name: "info"
}
StatusPopupMenu {
title: "Four"
StatusMenuItem {
text: "One"
icon.name: "info"
}
StatusMenuItem {
text: "Three"
icon.name: "info"
}
}
}
}

View File

@ -152,6 +152,12 @@ StatusWindow {
selected: page.sourceComponent == othersComponent
onClicked: page.sourceComponent = othersComponent
}
NavigationHeader { text: "StatusQ.Popup" }
StatusNavigationListItem {
title: "StatusPopupMenu"
selected: page.sourceComponent == popupMenuComponent
onClicked: page.sourceComponent = popupMenuComponent
}
}
}
}
@ -239,6 +245,11 @@ StatusWindow {
Buttons {}
}
Component {
id: popupMenuComponent
StatusPopupMenuPage {}
}
Component {
id: demoAppCmp

View File

@ -153,5 +153,11 @@ ThemePalette {
property QtObject statusChatInfoButton: QtObject {
property color backgroundColor: baseColor3
}
property QtObject statusPopupMenu: QtObject {
property color backgroundColor: baseColor2
property color hoverBackgroundColor: directColor7
property color separatorColor: directColor7
}
}

View File

@ -151,5 +151,11 @@ ThemePalette {
property QtObject statusChatInfoButton: QtObject {
property color backgroundColor: white
}
property QtObject statusPopupMenu: QtObject {
property color backgroundColor: white
property color hoverBackgroundColor: baseColor2
property color separatorColor: baseColor2
}
}

View File

@ -111,6 +111,13 @@ QtObject {
property QtObject statusChatInfoButton: QtObject {
property color backgroundColor
property color hoverBackgroundColor
}
property QtObject statusPopupMenu: QtObject {
property color backgroundColor
property color hoverBackgroundColor
property color separatorColor
}
function alphaColor(color, alpha) {

View File

@ -0,0 +1,15 @@
import QtQuick 2.13
import QtQuick.Controls 2.13
import StatusQ.Core 0.1
Action {
id: statusMenuItem
enum Type {
Normal,
Danger
}
property int type: StatusMenuItem.Type.Normal
property real iconRotation: 0
}

View File

@ -0,0 +1,12 @@
import QtQuick 2.13
import QtQuick.Controls 2.13
import StatusQ.Core.Theme 0.1
MenuSeparator {
contentItem: Rectangle {
implicitWidth: 176
implicitHeight: 1
color: Theme.palette.statusPopupMenu.separatorColor
}
}

View File

@ -0,0 +1,148 @@
import QtQuick 2.13
import QtQuick.Controls 2.13
import QtGraphicalEffects 1.13
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Popups 0.1
Menu {
id: statusPopupMenu
closePolicy: Popup.CloseOnReleaseOutside | Popup.CloseOnEscape
topPadding: 8
bottomPadding: 8
property int menuItemCount: 0
property var subMenuItemIcons: []
delegate: MenuItem {
id: statusPopupMenuItem
implicitHeight: 38
property int subMenuIndex
Component.onCompleted: {
if (subMenu) {
subMenuIndex = statusPopupMenu.menuItemCount
statusPopupMenu.menuItemCount += 1
}
}
action: StatusMenuItem {}
Component {
id: indicatorComponent
Item {
implicitWidth: 24
implicitHeight: 24
StatusIcon {
anchors.centerIn: parent
width: !!statusPopupMenuItem.action.icon.width ?
statusPopupMenuItem.action.icon.width : 18
rotation: statusPopupMenuItem.action.iconRotation
icon: statusPopupMenuItem.subMenu ?
statusPopupMenu.subMenuItemIcons[statusPopupMenuItem.subMenuIndex] :
statusPopupMenuItem.action.icon.name
color: {
switch (statusPopupMenuItem.action.type) {
case StatusMenuItem.Type.Danger:
return Theme.palette.dangerColor1
break;
default:
return Theme.palette.primaryColor1
}
}
}
}
}
indicator: Loader {
sourceComponent: indicatorComponent
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: 8
active: parent.subMenu && !!statusPopupMenu.subMenuItemIcons[parent.subMenuIndex] ||
!!statusPopupMenuItem.action.icon.name
}
contentItem: StatusBaseText {
anchors.left: statusPopupMenuItem.indicator.right
anchors.leftMargin: 4
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
text: statusPopupMenuItem.text
color: {
switch (statusPopupMenuItem.action.type) {
case StatusMenuItem.Type.Danger:
return Theme.palette.dangerColor1
break;
default:
return Theme.palette.directColor1
}
}
font.pixelSize: 13
elide: Text.ElideRight
}
arrow: StatusIcon {
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: 8
height: 16
visible: statusPopupMenuItem.subMenu
icon: "next"
color: Theme.palette.directColor1
}
background: Rectangle {
color: {
if (hovered) {
return statusPopupMenuItem.action.type === StatusMenuItem.Type.Danger ? Theme.palette.dangerColor3 : Theme.palette.statusPopupMenu.hoverBackgroundColor
}
return "transparent"
}
}
MouseArea {
id: sensor
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
hoverEnabled: true
onPressed: mouse.accepted = false
}
}
background: Item {
id: statusPopupMenuBackground
implicitWidth: 176
Rectangle {
id: statusPopupMenuBackgroundContent
implicitWidth: statusPopupMenuBackground.width
implicitHeight: statusPopupMenuBackground.height
color: Theme.palette.statusPopupMenu.backgroundColor
radius: 8
layer.enabled: true
layer.effect: DropShadow {
width: statusPopupMenuBackgroundContent.width
height: statusPopupMenuBackgroundContent.height
x: statusPopupMenuBackgroundContent.x
visible: statusPopupMenuBackgroundContent.visible
source: statusPopupMenuBackgroundContent
horizontalOffset: 0
verticalOffset: 4
radius: 12
samples: 25
spread: 0.2
color: Theme.palette.dropShadow
}
}
}
}

View File

@ -0,0 +1,5 @@
module StatusQ.Popups
StatusMenuSeparator 0.1 StatusMenuSeparator.qml
StatusPopupMenu 0.1 StatusPopupMenu.qml
StatusMenuItem 0.1 StatusMenuItem.qml