chore(StatusItemSelector): Use StatusFlowSelector as a base component

Closes: #9851
This commit is contained in:
Michał Cieślak 2023-03-13 11:02:41 +01:00 committed by Michał
parent 7df80bfa1c
commit bef14365aa
4 changed files with 97 additions and 123 deletions

View File

@ -14,11 +14,11 @@ ColumnLayout {
id: selector
icon: Style.png("tokens/SNT")
iconSize: 24
title: "Item Selector Title"
defaultItemText: "Example: Empty items"
itemsModel: ListModel {
placeholderText: "Example: Empty items"
model: ListModel {
id: model
}
@ -65,6 +65,6 @@ ColumnLayout {
Layout.alignment: Qt.AlignHCenter
text: "Clear list"
onClicked: { selector.itemsModel.clear() }
onClicked: model.clear()
}
}

View File

@ -3,17 +3,19 @@ import QtQuick.Layouts 1.14
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
import StatusQ.Core.Utils 0.1
/*!
\qmltype StatusItemSelector
\inherits Rectangle
\inherits StatusFlowSelector
\inqmlmodule StatusQ.Components
\since StatusQ.Components 0.1
\brief It allows to add items and display them as a tag item with an image and text. It also allows to store and display logical `and` / `or` operators into the list. Inherits \l{https://doc.qt.io/qt-6/qml-qtquick-rectangle.html}{Item}.
\brief It allows to add items and display them as a tag item with an image
and text. It also allows to store and display logical `and` / `or` operators
into the list.
The \c StatusItemSelector is populated with a data model. The data model is commonly a JavaScript array or a ListModel object with specific expected roles.
The \c StatusItemSelector is populated with a data model. The data model is
commonly a JavaScript array or a ListModel object with specific expected roles.
Example of how the component looks like:
\image status_item_selector.png
@ -40,45 +42,41 @@ import StatusQ.Core.Utils 0.1
\endqml
For a list of components available see StatusQ.
*/
StatusGroupBox {
StatusFlowSelector {
id: root
/*!
\qmlproperty string StatusItemSelector::defaultItemText
This property holds the default item text shown when the list of items is empty.
*/
property string defaultItemText
/*!
\qmlproperty url StatusItemSelector::defaultItemImageSource
This property holds the default item icon shown when the list of items is empty.
*/
property url defaultItemImageSource: ""
/*!
\qmlproperty StatusRoundButton StatusItemSelector::addButton
This property holds an alias to the `add` button.
*/
readonly property alias addButton: addItemButton
/*!
\qmlproperty ListModel StatusItemSelector::itemsModel
\qmlproperty ListModel StatusItemSelector::model
This property holds the data that will be populated in the items selector.
Here an example of the model roles expected:
\qml
itemsModel: ListModel {
model: ListModel {
ListElement {
text: "Socks"
imageSource: "qrc:imports/assets/png/tokens/SOCKS.png"
color: ""
emoji: ""
operator: Utils.Operator.None
}
ListElement {
text: "ZRX"
imageSource: "qrc:imports/assets/png/tokens/ZRX.png"
color: ""
emoji: ""
operator: Utils.Operator.Or
}
ListElement {
text: "Custom Token"
imageSource: ""
color: "red"
emoji: "⚽"
operator: Utils.Operator.Or
}
}
\endqml
*/
property var itemsModel: ListModel { }
property alias model: repeater.model
/*!
\qmlproperty bool StatusItemSelector::useIcons
This property determines if the imageSource role from the model will be handled as
@ -115,84 +113,58 @@ StatusGroupBox {
*/
signal itemClicked(var item, int index, var mouse)
placeholderItem.visible: repeater.count === 0
implicitWidth: 560
clip: true
Flow {
id: flow
Repeater {
id: repeater
clip: true
width: root.availableWidth
spacing: 6
RowLayout {
spacing: flowSpacing
StatusListItemTag {
bgColor: Theme.palette.baseColor2
visible: !itemsModel || itemsModel.count === 0
title: root.defaultItemText
asset.name: root.defaultItemImageSource
asset.isImage: true
closeButtonVisible: false
titleText.color: Theme.palette.baseColor1
titleText.font.pixelSize: 15
}
Repeater {
model: itemsModel
RowLayout {
spacing: flow.spacing
StatusBaseText {
visible: model.operator !== OperatorsUtils.Operators.None
Layout.alignment: Qt.AlignVCenter
text: OperatorsUtils.setOperatorTextFormat(model.operator)
color: Theme.palette.primaryColor1
font.pixelSize: 17
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: {
// Switch operator
if(model.operator === OperatorsUtils.Operators.And)
model.operator = OperatorsUtils.Operators.Or
else
model.operator = OperatorsUtils.Operators.And
}
}
}
StatusListItemTag {
title: model.text
asset.height: root.asset.height
asset.width: root.asset.width
asset.name: root.useLetterIdenticons ? model.text : (model.imageSource ?? "")
asset.isImage: root.asset.isImage
asset.bgColor: root.asset.bgColor
asset.emoji: model.emoji ? model.emoji : ""
asset.color: model.color ? model.color : ""
asset.isLetterIdenticon: root.useLetterIdenticons
//color: Theme.palette.primaryColor3
closeButtonVisible: false
titleText.color: Theme.palette.primaryColor1
titleText.font.pixelSize: 15
leftPadding: root.tagLeftPadding
MouseArea {
anchors.fill: parent
enabled: root.itemsClickable
cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
acceptedButtons: Qt.LeftButton | Qt.RightButton
onClicked: root.itemClicked(parent, model.index, mouse)
StatusBaseText {
visible: model.operator !== OperatorsUtils.Operators.None
Layout.alignment: Qt.AlignVCenter
text: OperatorsUtils.setOperatorTextFormat(model.operator)
color: Theme.palette.primaryColor1
font.pixelSize: 17
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: {
// Switch operator
if(model.operator === OperatorsUtils.Operators.And)
model.operator = OperatorsUtils.Operators.Or
else
model.operator = OperatorsUtils.Operators.And
}
}
}
}
StatusRoundButton {
id: addItemButton
implicitHeight: 32
implicitWidth: implicitHeight
height: width
type: StatusRoundButton.Type.Secondary
icon.name: "add"
StatusListItemTag {
title: model.text
asset.height: root.asset.height
asset.width: root.asset.width
asset.name: root.useLetterIdenticons ? model.text : (model.imageSource ?? "")
asset.isImage: root.asset.isImage
asset.bgColor: root.asset.bgColor
asset.emoji: model.emoji ? model.emoji : ""
asset.color: model.color ? model.color : ""
asset.isLetterIdenticon: root.useLetterIdenticons
closeButtonVisible: false
titleText.color: Theme.palette.primaryColor1
titleText.font.pixelSize: 15
leftPadding: root.tagLeftPadding
MouseArea {
anchors.fill: parent
enabled: root.itemsClickable
cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
acceptedButtons: Qt.LeftButton | Qt.RightButton
onClicked: root.itemClicked(parent, model.index, mouse)
}
}
}
}
}

View File

@ -29,7 +29,7 @@ StatusScrollView {
property var selectedHoldingsModel: ListModel {}
readonly property bool isFullyFilled: selectedHoldingsModel.count > 0 &&
addressess.itemsModel.count > 0
addressess.model.count > 0
signal airdropClicked(var airdropTokens, string address)
@ -57,13 +57,13 @@ StatusScrollView {
Layout.fillWidth: true
icon: Style.svg("token")
title: qsTr("What")
defaultItemText: qsTr("Example: 1 SOCK")
placeholderText: qsTr("Example: 1 SOCK")
tagLeftPadding: 2
asset.height: 28
asset.width: asset.height
addButton.visible: itemsModel.count < d.maxAirdropTokens
addButton.visible: model.count < d.maxAirdropTokens
itemsModel: HoldingsSelectionModel {
model: HoldingsSelectionModel {
sourceModel: root.selectedHoldingsModel
assetsModel: root.assetsModel
@ -163,7 +163,7 @@ StatusScrollView {
dropdown.x = mouse.x + d.dropdownHorizontalOffset
dropdown.y = d.dropdownVerticalOffset
const modelItem = tokensSelector.itemsModel.get(index)
const modelItem = tokensSelector.model.get(index)
switch(modelItem.type) {
case HoldingTypes.Type.Asset:
@ -213,17 +213,19 @@ StatusScrollView {
Layout.fillWidth: true
icon: Style.svg("member")
title: qsTr("To")
defaultItemText: qsTr("Example: 12 addresses and 3 members")
placeholderText: qsTr("Example: 12 addresses and 3 members")
tagLeftPadding: 2
asset.height: 28
asset.width: asset.height
model: ListModel {}
addButton.onClicked: {
if(addressInput.text.length > 0)
itemsModel.append({text: addressInput.text})
model.append({text: addressInput.text})
}
onItemClicked: addressess.itemsModel.remove(index)
onItemClicked: addressess.model.remove(index)
}
StatusButton {
@ -239,7 +241,7 @@ StatusScrollView {
root.selectedHoldingsModel,
["key", "type", "amount"])
root.airdropClicked(airdropTokens, addressess.itemsModel)
root.airdropClicked(airdropTokens, addressess.model)
}
}
}

View File

@ -96,11 +96,11 @@ StatusScrollView {
if (isCommunityPermission) {
d.dirtyValues.selectedChannelsModel.clear()
inSelector.wholeCommunitySelected = true
inSelector.itemsModel = inModelCommunity
inSelector.model = inModelCommunity
} else {
inSelector.itemsModel = 0
inSelector.model = 0
inSelector.wholeCommunitySelected = false
inSelector.itemsModel = channelsSelectionModel
inSelector.model = channelsSelectionModel
}
}
@ -152,10 +152,10 @@ StatusScrollView {
(root.selectedChannelsModel.rowCount()
|| d.dirtyValues.permissionType === PermissionTypes.Type.None)) {
inSelector.wholeCommunitySelected = false
inSelector.itemsModel = channelsSelectionModel
inSelector.model = channelsSelectionModel
} else {
inSelector.wholeCommunitySelected = true
inSelector.itemsModel = inModelCommunity
inSelector.model = inModelCommunity
}
// Is private permission
@ -187,13 +187,13 @@ StatusScrollView {
Layout.fillWidth: true
icon: Style.svg("contact_verified")
title: qsTr("Who holds")
defaultItemText: qsTr("Example: 10 SNT")
placeholderText: qsTr("Example: 10 SNT")
tagLeftPadding: 2
asset.height: 28
asset.width: asset.height
addButton.visible: itemsModel.count < d.maxHoldingsItems
addButton.visible: model.count < d.maxHoldingsItems
itemsModel: HoldingsSelectionModel {
model: HoldingsSelectionModel {
sourceModel: d.dirtyValues.selectedHoldingsModel
assetsModel: root.assetsModel
@ -305,7 +305,7 @@ StatusScrollView {
dropdown.x = mouse.x + d.dropdownHorizontalOffset
dropdown.y = d.dropdownVerticalOffset
const modelItem = tokensSelector.itemsModel.get(index)
const modelItem = tokensSelector.model.get(index)
switch(modelItem.type) {
case HoldingTypes.Type.Asset:
@ -343,7 +343,7 @@ StatusScrollView {
iconSize: 24
useIcons: true
title: qsTr("Is allowed to")
defaultItemText: qsTr("Example: View and post")
placeholderText: qsTr("Example: View and post")
QtObject {
id: permissionItemModelData
@ -353,8 +353,8 @@ StatusScrollView {
readonly property string imageSource: PermissionTypes.getIcon(key)
}
itemsModel: d.dirtyValues.permissionType !== PermissionTypes.Type.None
? permissionItemModelData : null
model: d.dirtyValues.permissionType !== PermissionTypes.Type.None
? permissionItemModelData : null
addButton.visible: d.dirtyValues.permissionType === PermissionTypes.Type.None
@ -413,7 +413,7 @@ StatusScrollView {
icon: d.isCommunityPermission ? Style.svg("communities") : Style.svg("create-category")
iconSize: 24
title: qsTr("In")
defaultItemText: qsTr("Example: `#general` channel")
placeholderText: qsTr("Example: `#general` channel")
useLetterIdenticons: !wholeCommunitySelected || !inDropdown.communityImage
@ -474,20 +474,20 @@ StatusScrollView {
onChannelsSelected: {
d.dirtyValues.selectedChannelsModel.clear()
inSelector.itemsModel = 0
inSelector.model = 0
inSelector.wholeCommunitySelected = false
const modelData = channels.map(key => ({ key }))
d.dirtyValues.selectedChannelsModel.append(modelData)
inSelector.itemsModel = channelsSelectionModel
inSelector.model = channelsSelectionModel
close()
}
onCommunitySelected: {
d.dirtyValues.selectedChannelsModel.clear()
inSelector.wholeCommunitySelected = true
inSelector.itemsModel = inModelCommunity
inSelector.model = inModelCommunity
close()
}
}