feat(StatusTagSelector): Introduced readonly tags and possibility of icon

- Different tag color depending if the entry `isReadonly` or not.
- Tag disabled if the entry `isReadonly`.
- Possibility to show icon if entry contains the proper info.
- Added property `orderByReadonly` to position `isReadonly` entries in the left.

Updated sandbox project examples according to new tag updates.

Closes #694
This commit is contained in:
Noelia 2022-05-31 17:18:28 +02:00 committed by Noelia
parent 18d385cf2b
commit 70834fc187
4 changed files with 115 additions and 28 deletions

View File

@ -83,6 +83,8 @@ Column {
icon: "" icon: ""
isIdenticon: false isIdenticon: false
onlineStatus: 3 onlineStatus: 3
isReadonly: true
tagIcon: "crown"
} }
ListElement { ListElement {
publicId: "0x1" publicId: "0x1"
@ -90,6 +92,8 @@ Column {
icon: "" icon: ""
isIdenticon: false isIdenticon: false
onlineStatus: 1 onlineStatus: 1
isReadonly: false
tagIcon: ""
} }
} }
toLabelText: qsTr("To: ") toLabelText: qsTr("To: ")

View File

@ -852,6 +852,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlklEQVR4nOzW0QmDQBAG4SSkl7SUQlJGCrElq9F3QdjjVhh/5nv3cFhY9vUIYQiNITSG0BhCExPynn1gWf9bx498P7/ icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlklEQVR4nOzW0QmDQBAG4SSkl7SUQlJGCrElq9F3QdjjVhh/5nv3cFhY9vUIYQiNITSG0BhCExPynn1gWf9bx498P7/
nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC" nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC"
isIdenticon: true isIdenticon: true
isAdmin: false
ringSpecModel: [ ListElement {colorId: 13; segmentLength: 5}, ringSpecModel: [ ListElement {colorId: 13; segmentLength: 5},
ListElement {colorId: 31; segmentLength: 5}, ListElement {colorId: 31; segmentLength: 5},
ListElement {colorId: 10; segmentLength: 1}, ListElement {colorId: 10; segmentLength: 1},
@ -868,6 +869,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
isMutualContact: false isMutualContact: false
onlineStatus: false onlineStatus: false
icon: "" icon: ""
isAdmin: false
isIdenticon: false isIdenticon: false
} }
ListElement { ListElement {
@ -877,6 +879,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
trustIndicator: StatusContactVerificationIcons.TrustedType.None trustIndicator: StatusContactVerificationIcons.TrustedType.None
isMutualContact: false isMutualContact: false
onlineStatus: true onlineStatus: true
isAdmin: false
icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAiElEQVR4nOzXUQpAQBRGYWQvLNAyLJDV8C5qpiGnv/M9al5Ot27X0IUwhMYQGkNoDKGJCRlLH67bftx9X+ap/+P9VcxEDK icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAiElEQVR4nOzXUQpAQBRGYWQvLNAyLJDV8C5qpiGnv/M9al5Ot27X0IUwhMYQGkNoDKGJCRlLH67bftx9X+ap/+P9VcxEDK
ExhKZ4a9Uq3TZviZmIITSG0DRvlqcbqVbrlouZiCE0htD4h0hjCI0hNN5aNIbQGKKPxEzEEBpDaAyhMYTmDAAA//+gYCErzmCpCQAAAABJRU5ErkJggg==" ExhKZ4a9Uq3TZviZmIITSG0DRvlqcbqVbrlouZiCE0htD4h0hjCI0hNN5aNIbQGKKPxEzEEBpDaAyhMYTmDAAA//+gYCErzmCpCQAAAABJRU5ErkJggg=="
isIdenticon: true isIdenticon: true
@ -897,6 +900,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
onlineStatus: false onlineStatus: false
icon: "" icon: ""
isIdenticon: false isIdenticon: false
isAdmin: false
ringSpecModel: [ ListElement {colorId: 0; segmentLength: 1}, ringSpecModel: [ ListElement {colorId: 0; segmentLength: 1},
ListElement {colorId: 28; segmentLength: 1}, ListElement {colorId: 28; segmentLength: 1},
ListElement {colorId: 31; segmentLength: 1}, ListElement {colorId: 31; segmentLength: 1},

View File

@ -9,17 +9,21 @@ Item {
property ListModel asortedContacts: ListModel { property ListModel asortedContacts: ListModel {
ListElement { ListElement {
publicId: "0x0" publicId: "0x0"
name: "Maria" name: "emily.eth"
icon: "" icon: ""
isIdenticon: false isIdenticon: false
onlineStatus: 3 onlineStatus: 3
isReadonly: false
tagIcon: ""
} }
ListElement { ListElement {
publicId: "0x1" publicId: "0x1"
name: "James" name: "vitalikbuterin"
icon: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg" icon: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg"
isIdenticon: false isIdenticon: false
onlineStatus: 1 onlineStatus: 1
isReadonly: false
tagIcon: ""
} }
ListElement { ListElement {
publicId: "0x2" publicId: "0x2"
@ -27,13 +31,17 @@ Item {
icon: "" icon: ""
isIdenticon: false isIdenticon: false
onlineStatus: 2 onlineStatus: 2
isReadonly: false
tagIcon: ""
} }
ListElement { ListElement {
publicId: "0x3" publicId: "0x3"
name: "Tracy" name: "carmen.eth"
icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlklEQVR4nOzW0QmDQBAG4SSkl7SUQlJGCrElq9F3QdjjVhh/5nv3cFhY9vUIYQiNITSG0BhCExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC" icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlklEQVR4nOzW0QmDQBAG4SSkl7SUQlJGCrElq9F3QdjjVhh/5nv3cFhY9vUIYQiNITSG0BhCExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC"
isIdenticon: true isIdenticon: true
onlineStatus: 3 onlineStatus: 3
isReadonly: true
tagIcon: "crown"
} }
ListElement { ListElement {
publicId: "0x4" publicId: "0x4"
@ -41,6 +49,8 @@ Item {
icon: "" icon: ""
isIdenticon: false isIdenticon: false
onlineStatus: 3 onlineStatus: 3
isReadonly: false
tagIcon: ""
} }
} }

View File

@ -132,6 +132,12 @@ Item {
By default is set to false. By default is set to false.
*/ */
property bool showSortedListOnlyWhenText: false property bool showSortedListOnlyWhenText: false
/*!
\qmlproperty bool StatusTagSelector::orderByReadonly
This property will decide if the displayed tag names will be ordered from left to right starting with the items that are marked as `isReadonly`.
By default is set to true (readonly names at left).
*/
property bool orderByReadonly: true
/*! /*!
\qmlmethod \qmlmethod
@ -146,9 +152,12 @@ Item {
\qmlmethod \qmlmethod
This function is used to insert a new tag. This function is used to insert a new tag.
*/ */
function insertTag(name, id) { function insertTag(name, id, isReadonly, tagIcon) {
if (!find(namesModel, function(item) { return item.publicId === id }) && namesModel.count < root.nameCountLimit) { if (!find(namesModel, function(item) { return item.publicId === id }) && namesModel.count < root.nameCountLimit) {
namesModel.insert(namesModel.count, {"name": name, "publicId": id}); if(orderByReadonly && isReadonly)
namesModel.insert(0, {"name": name, "publicId": id, "isReadonly": !!isReadonly, "tagIcon": tagIcon ? tagIcon : ""});
else
namesModel.insert(namesModel.count, {"name": name, "publicId": id, "isReadonly": !!isReadonly, "tagIcon": tagIcon ? tagIcon : ""});
addMember(id); addMember(id);
edit.clear(); edit.clear();
} }
@ -165,11 +174,17 @@ Item {
var entry = inputModel.get(i); var entry = inputModel.get(i);
if (entry.name.toLowerCase().includes(text.toLowerCase()) && if (entry.name.toLowerCase().includes(text.toLowerCase()) &&
!find(namesModel, function(item) { return item.name === entry.name })) { !find(namesModel, function(item) { return item.name === entry.name })) {
sortedList.append({"publicId": entry.publicId, "name": entry.name, sortedList.append({"publicId": entry.publicId,
"nickName": entry.nickName, "trustIndicator": entry.trustIndicator, "name": entry.name,
"isMutualContact": entry.isMutualContact, "ringSpecModel": entry.ringSpecModel, "nickName": entry.nickName,
"icon": entry.icon, "isIdenticon": entry.isIdenticon, "trustIndicator": entry.trustIndicator,
"onlineStatus": entry.onlineStatus}); "isMutualContact": entry.isMutualContact,
"ringSpecModel": entry.ringSpecModel,
"icon": entry.icon,
"isIdenticon": entry.isIdenticon,
"onlineStatus": entry.onlineStatus,
"tagIcon": entry.tagIcon ? entry.tagIcon : "",
"isReadonly": !!entry.isReadonly});
userListView.model = sortedList; userListView.model = sortedList;
} }
} }
@ -198,11 +213,28 @@ Item {
2 * bgRect.anchors.margins + 2 * bgRect.anchors.margins +
userListView.anchors.topMargin + userListView.anchors.bottomMargin + userListView.anchors.topMargin + userListView.anchors.bottomMargin +
(userListView.model.count * 64): 0 (userListView.model.count * 64): 0
function orderNamesModel() {
if(root.orderByReadonly) {
for(var i = 0; i < namesModel.count; i++) {
var entry = namesModel.get(i)
if(entry.isReadonly) {
namesModel.move(i, 0, 1)
}
}
}
}
} }
implicitWidth: 448 implicitWidth: 448
implicitHeight: (tagSelectorRect.height + d.suggestionContainerHeight) > root.maxHeight ? root.maxHeight : (tagSelectorRect.height + d.suggestionContainerHeight) implicitHeight: (tagSelectorRect.height + d.suggestionContainerHeight) > root.maxHeight ? root.maxHeight : (tagSelectorRect.height + d.suggestionContainerHeight)
onOrderByReadonlyChanged: { d.orderNamesModel() }
Component.onCompleted: {
// Component initialization:
d.orderNamesModel()
}
Rectangle { Rectangle {
id: tagSelectorRect id: tagSelectorRect
width: parent.width width: parent.width
@ -247,29 +279,63 @@ Item {
onCountChanged: { scrollToEnd(); } onCountChanged: { scrollToEnd(); }
delegate: Rectangle { delegate: Rectangle {
id: nameDelegate id: nameDelegate
width: (nameText.contentWidth + 34)
property int tagMargins: 8
property int tagIconsSize: 20
function getTagColor(isReadonly) {
if(isReadonly) {
return Theme.palette.baseColor1
}
else {
return mouseArea.containsMouse ? Theme.palette.miscColor1 : Theme.palette.primaryColor1
}
}
width: tagRow.implicitWidth + 2 * nameDelegate.tagMargins
height: 30 height: 30
color: mouseArea.containsMouse ? Theme.palette.miscColor1 : Theme.palette.primaryColor1 color: getTagColor(model.isReadonly)
radius: 8 radius: 8
StatusBaseText { Row {
id: nameText id: tagRow
height: parent.height
anchors.left: parent.left anchors.left: parent.left
anchors.leftMargin: 8 anchors.leftMargin: nameDelegate.tagMargins
anchors.verticalCenter: parent.verticalCenter anchors.rightMargin: nameDelegate.tagMargins
color: Theme.palette.indirectColor1 spacing: 2
text: name
} StatusIcon {
StatusIcon { visible: model.tagIcon
anchors.left: nameText.right anchors.verticalCenter: parent.verticalCenter
anchors.verticalCenter: parent.verticalCenter color: Theme.palette.indirectColor1
color: Theme.palette.indirectColor1 width: model.tagIcon ? nameDelegate.tagIconsSize : 0
icon: "close" height: nameDelegate.tagIconsSize
icon: model.tagIcon
}
StatusBaseText {
id: nameText
anchors.verticalCenter: parent.verticalCenter
color: Theme.palette.indirectColor1
font.pixelSize: 15
text: name
}
StatusIcon {
id: closeIcon
visible: !model.isReadonly
anchors.leftMargin: nameDelegate.tagMargins
anchors.verticalCenter: parent.verticalCenter
color: Theme.palette.indirectColor1
width: nameDelegate.tagIconsSize
height: nameDelegate.tagIconsSize
icon: "close"
}
} }
MouseArea { MouseArea {
id: mouseArea id: mouseArea
enabled: !model.isReadonly
anchors.fill: parent anchors.fill: parent
hoverEnabled: true hoverEnabled: true
cursorShape: Qt.PointingHandCursor cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
onClicked: { onClicked: {
removeMember(publicId); removeMember(publicId);
namesModel.remove(index, 1); namesModel.remove(index, 1);
@ -299,8 +365,11 @@ Item {
namesModel.remove((namesList.count-1), 1); namesModel.remove((namesList.count-1), 1);
} }
if ((event.key === Qt.Key_Return || event.key === Qt.Key_Enter) && (sortedList.count > 0)) { if ((event.key === Qt.Key_Return || event.key === Qt.Key_Enter) && (sortedList.count > 0)) {
root.insertTag(sortedList.get(userListView.currentIndex).name, sortedList.get(userListView.currentIndex).publicId); root.insertTag(sortedList.get(userListView.currentIndex).name,
} sortedList.get(userListView.currentIndex).publicId,
sortedList.get(userListView.currentIndex).isReadonly,
sortedList.get(userListView.currentIndex).tagIcon);
}
} }
Keys.onUpPressed: { userListView.decrementCurrentIndex(); } Keys.onUpPressed: { userListView.decrementCurrentIndex(); }
Keys.onDownPressed: { userListView.incrementCurrentIndex(); } Keys.onDownPressed: { userListView.incrementCurrentIndex(); }
@ -405,7 +474,7 @@ Item {
ringSettings.ringSpecModel: root.ringSpecModelGetter(publicId) ringSettings.ringSpecModel: root.ringSpecModelGetter(publicId)
color: (sensor.containsMouse || highlighted) ? Theme.palette.baseColor2 : "transparent" color: (sensor.containsMouse || highlighted) ? Theme.palette.baseColor2 : "transparent"
onClicked: { onClicked: {
root.insertTag(model.name, model.publicId); root.insertTag(model.name, model.publicId, model.isAdmin, model.isAdmin ? "crown" : "");
} }
} }
} }