feat(StatusItemSelector): Component improvements

-  Added `popupItem` property
- Replaced `GridLayout` to `Flow`.
- Added add item logic.
- Added operators logic.
- Added basic documentation.
- Added to sandbox.
This commit is contained in:
Noelia 2022-06-27 12:51:12 +02:00 committed by Michał Cieślak
parent cd0e458ad2
commit e106f93c4d
8 changed files with 232 additions and 18 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -20,6 +20,7 @@
\li \l{StatusChatToolBar} \li \l{StatusChatToolBar}
\li \l{StatusContactRequestsIndicatorListItem} \li \l{StatusContactRequestsIndicatorListItem}
\li \l{StatusDescriptionListItem} \li \l{StatusDescriptionListItem}
\li \l{StatusItemSelector}
\li \l{StatusLetterIdenticon} \li \l{StatusLetterIdenticon}
\li \l{StatusListItem} \li \l{StatusListItem}
\li \l{StatusListPicker} \li \l{StatusListPicker}

View File

@ -294,6 +294,11 @@ StatusWindow {
selected: viewLoader.source.toString().includes(title) selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page(title); onClicked: mainPageView.page(title);
} }
StatusNavigationListItem {
title: "StatusItemSelector"
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page(title);
}
StatusListSectionHeadline { text: "StatusQ.Popup" } StatusListSectionHeadline { text: "StatusQ.Popup" }
StatusNavigationListItem { StatusNavigationListItem {
title: "StatusPopupMenu" title: "StatusPopupMenu"

View File

@ -0,0 +1,44 @@
import QtQuick 2.0
import QtQuick.Layouts 1.14
import StatusQ.Components 0.1
import StatusQ.Controls 0.1
import StatusQ.Core.Utils 0.1
ColumnLayout {
spacing: 20
StatusItemSelector {
id: selector
icon: "qrc:/images/SNT.png"
iconSize: 24
title: "Item Selector Title"
defaultItemText: "Example: Empty items"
andOperatorText: "and"
orOperatorText: "or"
popupItem: StatusDropdown {
id: dropdown
width: 200
contentItem: ColumnLayout {
spacing: 10
StatusInput {
id: input
Layout.fillWidth: true
}
StatusButton {
Layout.alignment: Qt.AlignHCenter
text: "Add element"
onClicked: {
selector.addItem(input.text, "qrc:/images/SNT.png", selector.itemsModel.count > 0 ? Utils.Operators.Or : Utils.Operators.None)
dropdown.close()
}
}
}
}
}
StatusButton {
Layout.alignment: Qt.AlignHCenter
text: "Clear list"
onClicked: { selector.itemsModel.clear() }
}
}

View File

@ -68,5 +68,6 @@
<file>images/SuperRareCommunityBanner.png</file> <file>images/SuperRareCommunityBanner.png</file>
<file>images/RARI.png</file> <file>images/RARI.png</file>
<file>images/SRToken.png</file> <file>images/SRToken.png</file>
<file>pages/StatusItemSelectorPage.qml</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@ -1,32 +1,150 @@
import QtQuick 2.14 import QtQuick 2.14
import QtQuick.Layouts 1.14 import QtQuick.Layouts 1.14
import QtQuick.Controls 2.14 as QC
import StatusQ.Core 0.1 import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1 import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1 import StatusQ.Controls 0.1
import StatusQ.Core.Utils 0.1
/*!
\qmltype StatusItemSelector
\inherits Rectangle
\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}.
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
Example of how to use it:
\qml
StatusItemSelector {
icon: Style.svg("contact_verified")
title: qsTr("Who holds")
defaultItemText: qsTr("Example: 10 SNT")
andOperatorText: qsTr("and")
orOperatorText: qsTr("or")
popupItem: CustomPopup {
id: customPopup
onAddItem: {
tokensSelector.addItem(itemText, itemImage, operator)
customPopup.close()
}
}
}
\endqml
For a list of components available see StatusQ.
*/
Rectangle { Rectangle {
id: root id: root
/*!
\qmlproperty string StatusItemSelector::icon
This property holds the icon name for the icon represented on top of the component as a title icon.
*/
property string icon property string icon
/*!
\qmlproperty int StatusItemSelector::iconSize
This property holds the icon size for the icon represented on top of the component as a title icon.
*/
property int iconSize: 18 property int iconSize: 18
/*!
\qmlproperty string StatusItemSelector::title
This property holds the titel shown on top of the component.
*/
property string title property string title
/*!
\qmlproperty string StatusItemSelector::defaultItemText
This property holds the default item text shown when the list of items is empty.
*/
property string defaultItemText 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 QC.Popup StatusItemSelector::popupItem
This property holds a custom popup item to be opened near the `add` button in order to select new items.
*/
property QC.Popup popupItem
/*!
\qmlproperty ListModel StatusItemSelector::itemsModel
This property holds the data that will be populated in the items selector.
signal addItem() Here an example of the model roles expected:
\qml
itemsModel: ListModel {
ListElement {
text: "Socks"
imageSource: "qrc:imports/assets/png/tokens/SOCKS.png"
operator: Utils.Operator.None
}
ListElement {
text: "ZRX"
imageSource: "qrc:imports/assets/png/tokens/ZRX.png"
operator: Utils.Operator.Or
}
}
\endqml
*/
property ListModel itemsModel: ListModel { }
/*!
\qmlproperty string StatusItemSelector::andOperatorText
This property holds the string text representation for an `AND` logical operator.
*/
property string andOperatorText: qsTr("and")
/*!
\qmlproperty string StatusItemSelector::orOperatorText
This property holds the string text representation for an `OR` logical operator.
*/
property string orOperatorText: qsTr("or")
/*
\qmlmethod StatusItemSelector::addItem()
It is used to add new items into the selector control. The expected arguments are:
string `text`, url `imageSource` and int `operator` (None = 0, And = 1 and Or = 2)
*/
function addItem(text, imageSource, operator) {
itemsModel.insert(itemsModel.count, { "text": text, "imageSource": imageSource.toString(), "operator": operator })
}
QtObject {
id: d
function operatorTextFormat(operator) {
switch(operator)
{
case Utils.Operators.And:
return root.andOperatorText
case Utils.Operators.Or:
return root.orOperatorText
case Utils.Operators.None:
return ""
}
}
}
color: Theme.palette.baseColor4 color: Theme.palette.baseColor4
height: column.implicitHeight + column.anchors.topMargin + column.anchors.bottomMargin implicitHeight: columnLayout.implicitHeight + columnLayout.anchors.topMargin + columnLayout.anchors.bottomMargin
implicitWidth: 560
radius: 16 radius: 16
clip: true
ColumnLayout { ColumnLayout {
id: column id: columnLayout
anchors.top: parent.top anchors.top: parent.top
anchors.topMargin: 12 anchors.topMargin: 12
anchors.bottomMargin: anchors.topMargin anchors.bottomMargin: anchors.topMargin
anchors.left: parent.left anchors.left: parent.left
anchors.leftMargin: 16 anchors.leftMargin: 16
anchors.right: parent.right
anchors.rightMargin: 16
spacing: 12 spacing: 12
clip: true
RowLayout { RowLayout {
id: headerRow
spacing: 8 spacing: 8
Image { Image {
sourceSize.width: width || undefined sourceSize.width: width || undefined
@ -44,28 +162,65 @@ Rectangle {
color: Theme.palette.directColor1 color: Theme.palette.directColor1
font.pixelSize: 17 font.pixelSize: 17
} }
} }
// TODO: Next component iteration - model and selector Flow {
GridLayout { id: flow
rowSpacing: 6 Layout.fillWidth: true
columnSpacing: 12 spacing: 6
StatusListItemTag {
visible: itemsModel.count === 0
title: root.defaultItemText
image.source: root.defaultItemImageSource
color: Theme.palette.baseColor2
closeButtonVisible: false
titleText.color: Theme.palette.baseColor1
titleText.font.pixelSize: 15
}
Repeater { Repeater {
model: 1 model: itemsModel
StatusListItemTag { RowLayout {
title: root.defaultItemText spacing: flow.spacing
color: Theme.palette.baseColor2 StatusBaseText {
closeButtonVisible: false visible: model.operator !== Utils.Operators.None
titleText.color: Theme.palette.baseColor1 Layout.alignment: Qt.AlignVCenter
titleText.font.pixelSize: 15 text: d.operatorTextFormat(model.operator)
color: Theme.palette.primaryColor1
font.pixelSize: 17
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: {
// Switch operator
if(model.operator === Utils.Operators.And)
model.operator = Utils.Operators.Or
else
model.operator = Utils.Operators.And
}
}
}
StatusListItemTag {
title: model.text
image.source: model.imageSource
color: Theme.palette.primaryColor3
closeButtonVisible: false
titleText.color: Theme.palette.primaryColor1
titleText.font.pixelSize: 15
//onClicked: // TODO: Open remove or edit dialog
}
} }
} }
StatusRoundButton { StatusRoundButton {
id: addItemButton
implicitHeight: 32 implicitHeight: 32
implicitWidth: implicitHeight implicitWidth: implicitHeight
height: width height: width
type: StatusRoundButton.Type.Secondary type: StatusRoundButton.Type.Secondary
icon.name: "add" icon.name: "add"
onClicked: root.addItem() onClicked: {
root.popupItem.x = addItemButton.x + addItemButton.width + 4 * flow.spacing
root.popupItem.y = addItemButton.y + addItemButton.height
root.popupItem.open()
}
} }
} }
} }

View File

@ -37,4 +37,4 @@ StatusImageCropPanel 0.1 StatusImageCropPanel.qml
StatusColorSpace 0.0 StatusColorSpace.qml StatusColorSpace 0.0 StatusColorSpace.qml
StatusCommunityCard 0.1 StatusCommunityCard.qml StatusCommunityCard 0.1 StatusCommunityCard.qml
StatusCommunityTags 0.1 StatusCommunityTags.qml StatusCommunityTags 0.1 StatusCommunityTags.qml
StatusItemSelector 0.1 StatusItemSelector.qml StatusItemSelector 0.1 StatusItemSelector.qml

View File

@ -3,6 +3,14 @@ pragma Singleton
import QtQuick 2.13 import QtQuick 2.13
QtObject { QtObject {
// Logical operators
enum Operators {
None,
And,
Or
}
function getAbsolutePosition(node) { function getAbsolutePosition(node) {
var returnPos = {}; var returnPos = {};
returnPos.x = 0; returnPos.x = 0;