feat(StatusPopupMenu): add support for letter identicons, identicons and images
This extends the popup menu to accept image or icon configurations a la `StatusIconSettings` and `StatusImageSettings` in menu items, as well as nested menus. Usage: ```qml StatusPopupMenu { StatusMenuItem { text: "Custom Image icon" image.source: // image source } StatusMenuItem { text: "Custom identicon icon" image.source: // identicon source image.isIdenticon: true } StatusMenuItem { text: "Custom letter identicon" iconSettings.isLetterIdenticon: true iconSettings.background.color: "red" } } ``` Few things to note: - Because `StatusMenuItem` is an `Action` type, we can't extend its `icon` property, so we have to introduce our own (`iconSettings`) which can be of type `StatusIconSettings` - Where possible, `StatusPopupMenu` will prefer `iconSettings.[...]` over `icon.[...]`, which means, both would work: `icon.name` and `iconSettings.name`. This is for consistency's sake. Consumers can switch completely to `iconSettings` if desired. - When `isLetterIdenticon` is true, `iconSettings.background.color` must be set, similar to how it work in any other StatusQ component that makes use of this configuration type. Closes #263
This commit is contained in:
parent
246bec0d97
commit
3c4c7f040a
|
@ -22,6 +22,13 @@ GridLayout {
|
||||||
onClicked: complexMenu.popup()
|
onClicked: complexMenu.popup()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
StatusButton {
|
||||||
|
text: "Menu with custom images and icons"
|
||||||
|
onClicked: customMenu.popup()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
StatusPopupMenu {
|
StatusPopupMenu {
|
||||||
id: simpleMenu
|
id: simpleMenu
|
||||||
StatusMenuItem {
|
StatusMenuItem {
|
||||||
|
@ -40,32 +47,103 @@ GridLayout {
|
||||||
StatusPopupMenu {
|
StatusPopupMenu {
|
||||||
id: complexMenu
|
id: complexMenu
|
||||||
subMenuItemIcons: ['info']
|
subMenuItemIcons: ['info']
|
||||||
|
|
||||||
StatusMenuItem {
|
StatusMenuItem {
|
||||||
text: "One"
|
text: "One"
|
||||||
icon.name: "info"
|
iconSettings.name: "info"
|
||||||
}
|
}
|
||||||
|
|
||||||
StatusMenuSeparator {}
|
StatusMenuSeparator {}
|
||||||
|
|
||||||
StatusMenuItem {
|
StatusMenuItem {
|
||||||
text: "Two"
|
text: "Two"
|
||||||
icon.name: "info"
|
iconSettings.name: "info"
|
||||||
}
|
}
|
||||||
|
|
||||||
StatusMenuItem {
|
StatusMenuItem {
|
||||||
text: "Three"
|
text: "Three"
|
||||||
icon.name: "info"
|
iconSettings.name: "info"
|
||||||
}
|
}
|
||||||
|
|
||||||
StatusPopupMenu {
|
StatusPopupMenu {
|
||||||
title: "Four"
|
title: "Four"
|
||||||
StatusMenuItem {
|
StatusMenuItem {
|
||||||
text: "One"
|
text: "One"
|
||||||
icon.name: "info"
|
iconSettings.name: "info"
|
||||||
}
|
}
|
||||||
StatusMenuItem {
|
StatusMenuItem {
|
||||||
text: "Three"
|
text: "Three"
|
||||||
icon.name: "info"
|
iconSettings.name: "info"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusPopupMenu {
|
||||||
|
id: customMenu
|
||||||
|
|
||||||
|
subMenuItemIcons: [
|
||||||
|
"chat",
|
||||||
|
{
|
||||||
|
source: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
isLetterIdenticon: true,
|
||||||
|
color: "red"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
StatusMenuItem {
|
||||||
|
text: "Anywhere"
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusMenuSeparator {}
|
||||||
|
|
||||||
|
StatusPopupMenu {
|
||||||
|
title: "Chat"
|
||||||
|
|
||||||
|
StatusMenuItem {
|
||||||
|
text: "vitalik.eth"
|
||||||
|
image.source: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlklEQVR4nOzW0QmDQBAG4SSkl7SUQlJGCrElq9F3QdjjVhh/5nv3cFhY9vUIYQiNITSG0Bh
|
||||||
|
CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC"
|
||||||
|
image.isIdenticon: true
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusMenuItem {
|
||||||
|
text: "Pascal"
|
||||||
|
image.source: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusPopupMenu {
|
||||||
|
title: "Cryptokitties"
|
||||||
|
|
||||||
|
StatusMenuItem {
|
||||||
|
text: "welcome"
|
||||||
|
iconSettings.name: "channel"
|
||||||
|
iconSettings.color: Theme.palette.directColor1
|
||||||
|
}
|
||||||
|
StatusMenuItem {
|
||||||
|
text: "support"
|
||||||
|
iconSettings.name: "channel"
|
||||||
|
iconSettings.color: Theme.palette.directColor1
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusMenuHeadline { text: "Public" }
|
||||||
|
|
||||||
|
StatusMenuItem {
|
||||||
|
text: "news"
|
||||||
|
iconSettings.name: "channel"
|
||||||
|
iconSettings.color: Theme.palette.directColor1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusPopupMenu {
|
||||||
|
title: "Another community"
|
||||||
|
|
||||||
|
StatusMenuItem {
|
||||||
|
text: "welcome"
|
||||||
|
iconSettings.isLetterIdenticon: true
|
||||||
|
iconSettings.background.color: "red"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,17 @@ Action {
|
||||||
Normal,
|
Normal,
|
||||||
Danger
|
Danger
|
||||||
}
|
}
|
||||||
|
icon.color: "transparent"
|
||||||
property int type: StatusMenuItem.Type.Normal
|
property int type: StatusMenuItem.Type.Normal
|
||||||
property real iconRotation: 0
|
property real iconRotation: 0
|
||||||
|
property StatusImageSettings image: StatusImageSettings {
|
||||||
|
height: 16
|
||||||
|
width: 16
|
||||||
|
isIdenticon: false
|
||||||
|
}
|
||||||
|
property StatusIconSettings iconSettings: StatusIconSettings {
|
||||||
|
isLetterIdenticon: false
|
||||||
|
background: StatusIconBackgroundSettings {}
|
||||||
|
color: "transparent"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import QtGraphicalEffects 1.13
|
||||||
|
|
||||||
import StatusQ.Core 0.1
|
import StatusQ.Core 0.1
|
||||||
import StatusQ.Core.Theme 0.1
|
import StatusQ.Core.Theme 0.1
|
||||||
|
import StatusQ.Components 0.1
|
||||||
import StatusQ.Popups 0.1
|
import StatusQ.Popups 0.1
|
||||||
|
|
||||||
|
|
||||||
|
@ -54,13 +55,27 @@ Menu {
|
||||||
implicitHeight: 24
|
implicitHeight: 24
|
||||||
StatusIcon {
|
StatusIcon {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
width: !!statusPopupMenuItem.action.icon.width ?
|
width: {
|
||||||
statusPopupMenuItem.action.icon.width : 18
|
let width = statusPopupMenuItem.action.icon.width ||
|
||||||
|
statusPopupMenuItem.action.iconSettings.width
|
||||||
|
|
||||||
|
return !!width ? width : 18
|
||||||
|
}
|
||||||
rotation: statusPopupMenuItem.action.iconRotation
|
rotation: statusPopupMenuItem.action.iconRotation
|
||||||
icon: statusPopupMenuItem.subMenu ?
|
icon: {
|
||||||
statusPopupMenu.subMenuItemIcons[statusPopupMenuItem.subMenuIndex] :
|
if (statusPopupMenuItem.subMenu) {
|
||||||
statusPopupMenuItem.action.icon.name
|
return statusPopupMenu.subMenuItemIcons[statusPopupMenuItem.subMenuIndex]
|
||||||
|
}
|
||||||
|
return statusPopupMenuItem.action.icon.name ||
|
||||||
|
statusPopupMenuItem.action.iconSettings.name
|
||||||
|
}
|
||||||
color: {
|
color: {
|
||||||
|
let c = statusPopupMenuItem.action.iconSettings.color ||
|
||||||
|
statusPopupMenuItem.action.icon.color
|
||||||
|
|
||||||
|
if (!Qt.colorEqual(c, "transparent")) {
|
||||||
|
return c
|
||||||
|
}
|
||||||
switch (statusPopupMenuItem.action.type) {
|
switch (statusPopupMenuItem.action.type) {
|
||||||
case StatusMenuItem.Type.Danger:
|
case StatusMenuItem.Type.Danger:
|
||||||
return Theme.palette.dangerColor1
|
return Theme.palette.dangerColor1
|
||||||
|
@ -73,13 +88,66 @@ Menu {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: statusLetterIdenticonCmp
|
||||||
|
Item {
|
||||||
|
implicitWidth: 24
|
||||||
|
implicitHeight: 24
|
||||||
|
|
||||||
|
StatusLetterIdenticon {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
width: 16
|
||||||
|
height: 16
|
||||||
|
color: {
|
||||||
|
let subMenuItemIcon = statusPopupMenu.subMenuItemIcons[statusPopupMenuItem.subMenuIndex]
|
||||||
|
return subMenuItemIcon && subMenuItemIcon.color ? subMenuItemIcon.color : statusPopupMenuItem.action.iconSettings.background.color
|
||||||
|
}
|
||||||
|
name: statusPopupMenuItem.text
|
||||||
|
letterSize: 11
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: statusRoundImageCmp
|
||||||
|
|
||||||
|
Item {
|
||||||
|
implicitWidth: 24
|
||||||
|
implicitHeight: 24
|
||||||
|
StatusRoundedImage {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
width: statusPopupMenuItem.action.image.width
|
||||||
|
height: statusPopupMenuItem.action.image.height
|
||||||
|
image.source: statusPopupMenuItem.subMenu ?
|
||||||
|
statusPopupMenu.subMenuItemIcons[statusPopupMenuItem.subMenuIndex].source :
|
||||||
|
statusPopupMenuItem.action.image.source
|
||||||
|
border.width: (statusPopupMenuItem.subMenu && statusPopupMenu.subMenuItemIcons[statusPopupMenuItem.subMenuIndex].isIdenticon) ||
|
||||||
|
statusPopupMenuItem.action.image.isIdenticon ? 1 : 0
|
||||||
|
border.color: Theme.palette.directColor7
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
indicator: Loader {
|
indicator: Loader {
|
||||||
sourceComponent: indicatorComponent
|
sourceComponent: {
|
||||||
|
let subMenuItemIcon = statusPopupMenu.subMenuItemIcons[parent.subMenuIndex]
|
||||||
|
|
||||||
|
if ((parent.subMenu && subMenuItemIcon && subMenuItemIcon.source) || !!statusPopupMenuItem.action.image.source.toString()) {
|
||||||
|
return statusRoundImageCmp
|
||||||
|
}
|
||||||
|
|
||||||
|
return (parent.subMenu && subMenuItemIcon && subMenuItemIcon.isLetterIdenticon) ||
|
||||||
|
statusPopupMenuItem.action.iconSettings.isLetterIdenticon ?
|
||||||
|
statusLetterIdenticonCmp : indicatorComponent
|
||||||
|
}
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.leftMargin: 8
|
anchors.leftMargin: 8
|
||||||
active: (parent.subMenu && !!statusPopupMenu.subMenuItemIcons[parent.subMenuIndex] ||
|
active: (parent.subMenu && !!statusPopupMenu.subMenuItemIcons[parent.subMenuIndex] ||
|
||||||
!!statusPopupMenuItem.action.icon.name) &&
|
(!!statusPopupMenuItem.action.icon.name ||
|
||||||
|
!!statusPopupMenuItem.action.iconSettings.name) ||
|
||||||
|
!!statusPopupMenuItem.action.iconSettings.isLetterIdenticon ||
|
||||||
|
!!statusPopupMenuItem.action.image.source.toString()) &&
|
||||||
statusPopupMenuItem.action.enabled
|
statusPopupMenuItem.action.enabled
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,5 +231,4 @@ Menu {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue