From 0df69a8f51ea730b42bbcca063c915177b1167ec Mon Sep 17 00:00:00 2001 From: Noelia <97019400+noeliaSD@users.noreply.github.com> Date: Thu, 17 Feb 2022 09:20:17 +0100 Subject: [PATCH] feat(StatusSmartIdenticon): Add support for color rings in StatusSmartIdenticon (#553) Created new control `StatusIdenticonRing` and used in `StatusSmartIdenticon` component. Added property assignments in sandbox models to display the `StatusIdenticonRing` when needed. Added first documentation approach for `StatusIdenticonRing` and `StatusIdenticonRingSettings`. Closes #517 --- ui/StatusQ/.gitignore | 1 + .../doc/src/images/status_identicon_ring.png | Bin 0 -> 2375 bytes ui/StatusQ/doc/src/statusqcontrols.qdoc | 1 + ui/StatusQ/doc/src/statusqcore.qdoc | 1 + ui/StatusQ/sandbox/controls/ListItems.qml | 12 ++ .../demoapp/StatusAppCommunityView.qml | 3 + ui/StatusQ/sandbox/demoapp/data/Models.qml | 33 +++++- .../src/StatusQ/Components/StatusListItem.qml | 6 + .../Components/StatusSmartIdenticon.qml | 17 ++- .../StatusQ/Controls/StatusIdenticonRing.qml | 108 ++++++++++++++++++ ui/StatusQ/src/StatusQ/Controls/qmldir | 1 + .../Core/StatusIdenticonRingSettings.qml | 78 +++++++++++++ .../StatusQ/Core/Theme/StatusDarkTheme.qml | 7 ++ .../StatusQ/Core/Theme/StatusLightTheme.qml | 7 ++ .../src/StatusQ/Core/Theme/ThemePalette.qml | 2 + ui/StatusQ/src/StatusQ/Core/qmldir | 1 + ui/StatusQ/statusq.qrc | 2 + 17 files changed, 275 insertions(+), 5 deletions(-) create mode 100644 ui/StatusQ/doc/src/images/status_identicon_ring.png create mode 100644 ui/StatusQ/src/StatusQ/Controls/StatusIdenticonRing.qml create mode 100644 ui/StatusQ/src/StatusQ/Core/StatusIdenticonRingSettings.qml diff --git a/ui/StatusQ/.gitignore b/ui/StatusQ/.gitignore index 03a5506e18..a7255d0a4b 100644 --- a/ui/StatusQ/.gitignore +++ b/ui/StatusQ/.gitignore @@ -13,3 +13,4 @@ Makefile *_qml.cpp *_qmlcache.qrc sandbox/qmlcache_loader.cpp +doc/html \ No newline at end of file diff --git a/ui/StatusQ/doc/src/images/status_identicon_ring.png b/ui/StatusQ/doc/src/images/status_identicon_ring.png new file mode 100644 index 0000000000000000000000000000000000000000..64abb04bd43b3b26560538f3b86c7ffc62a42bb3 GIT binary patch literal 2375 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 literal 0 HcmV?d00001 diff --git a/ui/StatusQ/doc/src/statusqcontrols.qdoc b/ui/StatusQ/doc/src/statusqcontrols.qdoc index 0199031913..fb4fcd5f89 100644 --- a/ui/StatusQ/doc/src/statusqcontrols.qdoc +++ b/ui/StatusQ/doc/src/statusqcontrols.qdoc @@ -30,6 +30,7 @@ \li \l{StatusSlider} \li \l{StatusSelect} \li \l{StatusBaseInput} + \li \l{StatusIdenticonRing} \li \l{StatusInput} \li \l{StatusPickerButton} \li \l{StatusProgressBar} diff --git a/ui/StatusQ/doc/src/statusqcore.qdoc b/ui/StatusQ/doc/src/statusqcore.qdoc index a0b91e4131..0c90f020d2 100644 --- a/ui/StatusQ/doc/src/statusqcore.qdoc +++ b/ui/StatusQ/doc/src/statusqcore.qdoc @@ -15,6 +15,7 @@ \li \l{StatusIcon} \li \l{StatusIconBackgroundSettings} \li \l{StatusIconSettings} + \li \l{StatusIdenticonRingSettings} \li \l{StatusImageSettings} \li \l{StatusModalHeaderSettings} \li \l{StatusTooltipSettings} diff --git a/ui/StatusQ/sandbox/controls/ListItems.qml b/ui/StatusQ/sandbox/controls/ListItems.qml index 8cbe855636..fc46456cf3 100644 --- a/ui/StatusQ/sandbox/controls/ListItems.qml +++ b/ui/StatusQ/sandbox/controls/ListItems.qml @@ -357,6 +357,18 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC" image.isIdenticon: true isOnline: true + ringSettings.ringSpecModel: + ListModel { + ListElement {colorId: 13; segmentLength: 5} + ListElement {colorId: 31; segmentLength: 5} + ListElement {colorId: 10; segmentLength: 1} + ListElement {colorId: 2; segmentLength: 5} + ListElement {colorId: 26; segmentLength: 2} + ListElement {colorId: 19; segmentLength: 4} + ListElement {colorId: 28; segmentLength: 3} + } + ringSettings.distinctiveColors: Theme.palette.identiconRingColors + ringSettings.totalRingUnits: 25 } StatusMemberListItem { diff --git a/ui/StatusQ/sandbox/demoapp/StatusAppCommunityView.qml b/ui/StatusQ/sandbox/demoapp/StatusAppCommunityView.qml index 278974653c..7991b4ec74 100644 --- a/ui/StatusQ/sandbox/demoapp/StatusAppCommunityView.qml +++ b/ui/StatusQ/sandbox/demoapp/StatusAppCommunityView.qml @@ -266,6 +266,9 @@ StatusAppThreePanelLayout { image.source: model.source image.isIdenticon: model.isIdenticon isOnline: model.isOnline + ringSettings.ringSpecModel: model.ringSpecModel + ringSettings.distinctiveColors: Theme.palette.identiconRingColors + ringSettings.totalRingUnits: model.totalRingUnits } } } diff --git a/ui/StatusQ/sandbox/demoapp/data/Models.qml b/ui/StatusQ/sandbox/demoapp/data/Models.qml index 09689de93a..a4506e3411 100644 --- a/ui/StatusQ/sandbox/demoapp/data/Models.qml +++ b/ui/StatusQ/sandbox/demoapp/data/Models.qml @@ -903,6 +903,14 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I source: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlklEQVR4nOzW0QmDQBAG4SSkl7SUQlJGCrElq9F3QdjjVhh/5nv3cFhY9vUIYQiNITSG0BhCExPynn1gWf9bx498P7/ nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC" isIdenticon: true + totalRingUnits: 25 + ringSpecModel: [ ListElement {colorId: 13; segmentLength: 5}, + ListElement {colorId: 31; segmentLength: 5}, + ListElement {colorId: 10; segmentLength: 1}, + ListElement {colorId: 2; segmentLength: 5}, + ListElement {colorId: 26; segmentLength: 2}, + ListElement {colorId: 19; segmentLength: 4}, + ListElement {colorId: 28; segmentLength: 3} ] } ListElement { nickName: "carmen.eth" @@ -912,7 +920,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I isMutualContact: false isOnline: false source: "" - isIdenticon: false + isIdenticon: false } ListElement { nickName: "This girl I know from work" @@ -924,6 +932,14 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I source: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAiElEQVR4nOzXUQpAQBRGYWQvLNAyLJDV8C5qpiGnv/M9al5Ot27X0IUwhMYQGkNoDKGJCRlLH67bftx9X+ap/+P9VcxEDK ExhKZ4a9Uq3TZviZmIITSG0DRvlqcbqVbrlouZiCE0htD4h0hjCI0hNN5aNIbQGKKPxEzEEBpDaAyhMYTmDAAA//+gYCErzmCpCQAAAABJRU5ErkJggg==" isIdenticon: true + totalRingUnits: 25 + ringSpecModel: [ ListElement {colorId: 11; segmentLength: 1}, + ListElement {colorId: 23; segmentLength: 5}, + ListElement {colorId: 23; segmentLength: 5}, + ListElement {colorId: 10; segmentLength: 4}, + ListElement {colorId: 15; segmentLength: 3}, + ListElement {colorId: 26; segmentLength: 2}, + ListElement {colorId: 29; segmentLength: 5} ] } ListElement { nickName: "Mark Cuban" @@ -932,9 +948,18 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I trustIndicator: StatusContactVerificationIcons.TrustedType.Untrustworthy isMutualContact: true isOnline: false - source: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlklEQVR4nOzW0QmDQBAG4SSkl7SUQlJGCrElq9F3QdjjVhh/5nv3cFhY9vUIYQiNITSG0BhCExPynn1gWf9bx498P7/ - nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC" - isIdenticon: true + source: "" + isIdenticon: false + totalRingUnits: 25 + ringSpecModel: [ ListElement {colorId: 0; segmentLength: 1}, + ListElement {colorId: 28; segmentLength: 1}, + ListElement {colorId: 31; segmentLength: 1}, + ListElement {colorId: 22; segmentLength: 4}, + ListElement {colorId: 28; segmentLength: 3}, + ListElement {colorId: 27; segmentLength: 5}, + ListElement {colorId: 7; segmentLength: 5}, + ListElement {colorId: 13; segmentLength: 1}, + ListElement {colorId: 25; segmentLength: 4}] } } diff --git a/ui/StatusQ/src/StatusQ/Components/StatusListItem.qml b/ui/StatusQ/src/StatusQ/Components/StatusListItem.qml index 5788b66c9e..61f48e3512 100644 --- a/ui/StatusQ/src/StatusQ/Components/StatusListItem.qml +++ b/ui/StatusQ/src/StatusQ/Components/StatusListItem.qml @@ -50,6 +50,11 @@ Rectangle { height: 40 isIdenticon: false } + property StatusIdenticonRingSettings ringSettings: StatusIdenticonRingSettings { + totalRingUnits: 1 + initalAngleRad: 0 + ringPxSize: 1.5 + } property alias sensor: sensor property alias badge: statusListItemBadge @@ -123,6 +128,7 @@ Rectangle { !!statusListItem.icon.name || !!statusListItem.image.source.toString() badge.border.color: statusListItem.color + ringSettings: statusListItem.ringSettings } Item { diff --git a/ui/StatusQ/src/StatusQ/Components/StatusSmartIdenticon.qml b/ui/StatusQ/src/StatusQ/Components/StatusSmartIdenticon.qml index 9e053b6951..f80e5c06c9 100644 --- a/ui/StatusQ/src/StatusQ/Components/StatusSmartIdenticon.qml +++ b/ui/StatusQ/src/StatusQ/Components/StatusSmartIdenticon.qml @@ -1,11 +1,13 @@ import QtQuick 2.13 import StatusQ.Core 0.1 import StatusQ.Core.Theme 0.1 +import StatusQ.Controls 0.1 Loader { id: statusSmartIdenticon property string name: "" + property int dZ: 100 // Badge color properties must be set if badgeItem.visible = true property alias badge: statusBadge @@ -20,6 +22,12 @@ Loader { height: 40 } + property StatusIdenticonRingSettings ringSettings: StatusIdenticonRingSettings { + totalRingUnits: 1 + initalAngleRad: 0 + ringPxSize: 1.5 + } + sourceComponent: statusSmartIdenticon.icon.isLetterIdenticon ? letterIdenticon : !!statusSmartIdenticon.image.source.toString() ? roundedImage : !!statusSmartIdenticon.icon.name.toString() ? roundedIcon : letterIdenticon @@ -79,6 +87,13 @@ Loader { } } + // Next components are painted above main sourceComponent + StatusIdenticonRing { + settings: statusSmartIdenticon.ringSettings + anchors.fill: parent + z: statusSmartIdenticon.dZ/2 + } + // State component StatusBadge { id: statusBadge @@ -88,6 +103,6 @@ Loader { border.width: 3 implicitHeight: 15 implicitWidth: 15 - z: 100 + z: statusSmartIdenticon.dZ } } diff --git a/ui/StatusQ/src/StatusQ/Controls/StatusIdenticonRing.qml b/ui/StatusQ/src/StatusQ/Controls/StatusIdenticonRing.qml new file mode 100644 index 0000000000..7dace66b46 --- /dev/null +++ b/ui/StatusQ/src/StatusQ/Controls/StatusIdenticonRing.qml @@ -0,0 +1,108 @@ +import QtQuick 2.0 +import QtQuick.Layouts 1.0 + +import StatusQ.Core 0.1 +/*! + \qmltype StatusIdenticonRing + \inherits Item + \inqmlmodule StatusQ.Controls + \since StatusQ.Controls 0.1 + \brief It provides lines wrapped into a ring around another component like avatars. + + The \c StatusIdenticonRing item displays lines wrapped into a ring. The line is rendered clockwise. + + N segments and M distinctive colors compose identicon lines. + + Example of how the component looks like: + \image status_identicon_ring.png + + Example of how to use it: + + \qml + StatusIdenticonRing { + anchors.fill: parent + settings: StatusIdenticonRingSettings { + totalRingUnits: 25 + initalAngleRad: 0 + ringPxSize: 1.5 + ringSpecModel: [ ListElement {colorId: 0; segmentLength: 1}, + ListElement {colorId: 28; segmentLength: 1}, + ListElement {colorId: 31; segmentLength: 1}, + ListElement {colorId: 22; segmentLength: 4}, + ListElement {colorId: 28; segmentLength: 3}, + ListElement {colorId: 27; segmentLength: 5}, + ListElement {colorId: 7; segmentLength: 5}, + ListElement {colorId: 13; segmentLength: 1}, + ListElement {colorId: 25; segmentLength: 4}] + distinctiveColors: ["#000000", "#726F6F", "#C4C4C4", + "#E7E7E7", "#FFFFFF", "#00FF00", + "#009800", "#B8FFBB", "#FFC413", + "#9F5947", "#FFFF00", "#A8AC00", + "#FFFFB0", "#FF5733", "#FF0000", + "#9A0000", "#FF9D9D", "#FF0099", + "#C80078", "#FF00FF", "#900090", + "#FFB0FF", "#9E00FF", "#0000FF", + "#000086", "#9B81FF", "#3FAEF9", + "#9A6600", "#00FFFF", "#008694", + "#C2FFFF", "#00F0B6"] + } + } + \endqml + + For a list of components available see StatusQ. +*/ +Item { + id: identiconRing + + /*! + \qmlproperty StatusIdenticonRingSettings StatusIdenticonRing::settings + This property holds a set of settings for building the ring. + */ + property StatusIdenticonRingSettings settings: StatusIdenticonRingSettings { + totalRingUnits: 1 + initalAngleRad: 0 + ringPxSize: 1.5 + } + + /*! + \qmlproperty real StatusIdenticonRing::segmentRadLen + This property holds the total ring line length in radians. It depends on totalRingUnits value of settings object. + */ + readonly property real segmentRadLen: 2 * Math.PI / settings.totalRingUnits + + visible: settings.ringSpecModel !== undefined + + Canvas { + function printArcSegment(context, xPos, yPos, radius, color, startAngle, arcAngleLen, lineWidth) { + context.beginPath() + context.arc(xPos, yPos, radius, startAngle, startAngle + arcAngleLen, false/*anticlockwise*/) + context.strokeStyle = color + context.lineWidth = lineWidth + context.stroke() + } + + anchors.fill: parent + onPaint: { + const context = getContext("2d") + const radius = (height - settings.ringPxSize) / 2 + const xPos = width / 2 + const yPos = height / 2 + let arcPos = settings.initalAngleRad + context.reset() + if(settings.ringSpecModel) { + for (let i=0; isrc/StatusQ/Components/StatusToastMessage.qml src/StatusQ/Components/StatusWizardStepper.qml src/StatusQ/Components/StatusContactVerificationIcons.qml + src/StatusQ/Controls/StatusIdenticonRing.qml + src/StatusQ/Core/StatusIdenticonRingSettings.qml