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 0000000000..64abb04bd4 Binary files /dev/null and b/ui/StatusQ/doc/src/images/status_identicon_ring.png differ 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