Reimplemented components using `StatusComboBox` (#815)

* fix(StatusAccountSelector): Refactored and reimplemented using `StatusComboBox`
* fix(StatusAssetSelector): Refactored and reimplemented using `StatusComboBox`
* fix(StatusColorSelector): Reimplemented using `StatusComboBox`
* fix(StatusCardPage): Replaced `StatusSelect` with `StatusComboBox`
This commit is contained in:
Igor Sirotin 2022-08-03 15:13:31 +03:00 committed by Michał Cieślak
parent cb13839f95
commit 5b31926939
9 changed files with 263 additions and 260 deletions

View File

@ -8,57 +8,61 @@ import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
import StatusQ.Popups 0.1
Column {
spacing: 8
StatusAccountSelector {
id: accountSelector
accounts: ListModel {
ListElement {
name: "Pascal"
address: "0x1234567891011"
path: ""
color: "red"
publicKey: ""
walletType: "generated"
isChat: ""
currencyBalance: "1199.02"
assets: []
}
ListElement {
name: "Boris"
address: "0x123"
path: ""
color: "red"
publicKey: ""
walletType: "generated"
isChat: ""
currencyBalance: "0"
assets: []
}
ListElement {
name: "Alexandra"
address: "0x123"
path: ""
color: "yellow"
publicKey: ""
walletType: "generated"
isChat: ""
currencyBalance: "0"
assets: []
}
ListElement {
name: "Khushboo"
address: "0x123"
path: ""
color: "blue"
publicKey: ""
walletType: "generated"
isChat: ""
currencyBalance: "0"
assets: []
}
id: selector1
width: 300
accounts: accountsModel
}
ListModel {
id: accountsModel
ListElement {
name: "Pascal"
address: "0x1234567891011"
path: ""
color: "red"
publicKey: ""
walletType: "generated"
isChat: ""
currencyBalance: "1199.02"
assets: []
}
ListElement {
name: "Boris"
address: "0x123"
path: ""
color: "red"
publicKey: ""
walletType: "generated"
isChat: ""
currencyBalance: "42.42"
assets: []
}
ListElement {
name: "Alexandra"
address: "0x123"
path: ""
color: "yellow"
publicKey: ""
walletType: "generated"
isChat: ""
currencyBalance: "0"
assets: []
}
ListElement {
name: "Khushboo"
address: "0x123"
path: ""
color: "blue"
publicKey: ""
walletType: "watch" // Will be automatically filtered by StatusAccountSelector
isChat: ""
currencyBalance: "0"
assets: []
}
}
}

View File

@ -19,9 +19,24 @@ Item {
spacing: 20
RowLayout {
StatusSelect {
id: select
label: "Select Card State"
Layout.fillWidth: true
StatusCard {
id: card
Layout.alignment: Qt.AlignVCenter
primaryText: "Mainnet"
secondaryText: state === "unavailable" ? "No Gas" : "75"
tertiaryText: state === "unpreferred" ? "UNPREFERRED" : "BALANCE: " + 250
cardIconName: "status"
advancedInputText: "75"
disabledText: "Disabled"
}
StatusComboBox {
Layout.alignment: Qt.AlignVCenter
Layout.maximumWidth: 200
label: "Card State"
onCurrentValueChanged: card.state = currentValue
model: ListModel {
ListElement {
name: "default"
@ -36,47 +51,18 @@ Item {
name: "unpreferred"
}
}
selectMenu.delegate: StatusMenuItemDelegate {
statusPopupMenu: select
action: StatusMenuItem {
text: name
onTriggered: {
selectedItem.text = name
card.state = name
}
}
}
selectedItemComponent: Item {
id: selectedItem
anchors.fill: parent
property string text: "default"
StatusBaseText {
text: selectedItem.text
anchors.centerIn: parent
color: Theme.palette.directColor1
}
}
}
StatusCheckBox {
Layout.alignment: Qt.AlignVCenter
text: "advancedMode"
font.family: Theme.palette.monoFont.name
onClicked: {
card.advancedMode = checked
}
}
}
StatusCard {
id: card
primaryText: "Mainnet"
secondaryText: state === "unavailable" ? "No Gas" : "75"
tertiaryText: state === "unpreferred" ? "UNPREFERRED" : "BALANCE: " + 250
cardIconName: "status"
advancedInputText: "75"
disabledText: "Disabled"
}
Rectangle {
height: 1
width: 700

View File

@ -8,7 +8,7 @@ import StatusQ.Controls 0.1
import Sandbox 0.1
Column {
Row {
spacing: 8
StatusColorSelector {

View File

@ -39,10 +39,10 @@ Column {
label: "ComboBox with custom delegate"
model: commmonModel
delegate: StatusItemDelegate {
width: comboBox1.comboBox.width
highlighted: comboBox1.comboBox.highlightedIndex === index
width: comboBox1.control.width
highlighted: comboBox1.control.highlightedIndex === index
text: modelData
font: comboBox1.comboBox.font
font: comboBox1.control.font
icon {
name: "filled-account"
color: Theme.palette.primaryColor1

View File

@ -28,6 +28,13 @@ Column {
}
}
StatusBaseText {
font.pixelSize: 16
color: Theme.palette.dangerColor1
text: "This component should no longer be used.<br />Please, use `StatusComboBox` instead."
textFormat: Text.MarkdownText
}
StatusSelect {
id: select
label: "Some label"

View File

@ -8,17 +8,17 @@ import StatusQ.Core.Theme 0.1
import StatusQ.Core.Utils 0.1
import StatusQ.Controls 0.1
import SortFilterProxyModel 0.2
Item {
id: root
property string label: "Choose account"
property bool showAccountDetails: !!selectedAccount
property var accounts
property var selectedAccount
property string currency: "usd"
property alias selectField: select
implicitWidth: 448
height: select.height +
(selectedAccountDetails.visible ? selectedAccountDetails.height + selectedAccountDetails.anchors.topMargin : 0)
// set to asset symbol to display asset's balance top right
// NOTE: if this asset is not selected as a wallet token in the UI, then
// nothing will be displayed
@ -27,10 +27,10 @@ Item {
property double minRequiredAssetBalance: 0
property int dropdownWidth: width
property int chainId: 0
property alias dropdownAlignment: select.menuAlignment
property bool isValid: true
property bool readOnly: false
property var assetBalanceTextFn: function (foundValue) {
return "Balance: " + (parseFloat(foundValue) === 0.0 ? "0" : Utils.stripTrailingZeros(foundValue))
}
@ -51,18 +51,23 @@ Item {
return root.isValid
}
implicitWidth: 448
implicitHeight: comboBox.height +
(selectedAccountDetails.visible ? selectedAccountDetails.height + selectedAccountDetails.anchors.topMargin
: 0)
onSelectedAccountChanged: {
if (!selectedAccount) {
return
}
if (selectedAccount.color) {
selectedIconImg.color = Utils.getThemeAccountColor(selectedAccount.color, Theme.palette.userCustomizationColors) || Theme.palette.userCustomizationColors[0]
d.selectedIconColor = Utils.getThemeAccountColor(selectedAccount.color, Theme.palette.userCustomizationColors) || Theme.palette.userCustomizationColors[0]
}
if (selectedAccount.name) {
selectedTextField.text = selectedAccount.name
d.selectedText = selectedAccount.name
}
if (selectedAccount.address) {
textSelectedAddress.text = selectedAccount.address + " •"
textSelectedAddress.text = selectedAccount.address
}
if (selectedAccount.currencyBalance) {
textSelectedAddressFiatBalance.text = selectedAccount.currencyBalance + " " + currency.toUpperCase()
@ -87,14 +92,20 @@ Item {
txtAssetSymbol.text = " " + assetFound.symbol
}
QtObject {
id: d
property color selectedIconColor: "transparent"
property string selectedText: ""
}
StatusBaseText {
id: txtAssetBalance
visible: root.assetFound !== undefined
anchors.bottom: select.top
anchors.bottom: comboBox.top
anchors.bottomMargin: -18
anchors.right: txtAssetSymbol.left
anchors.left: select.left
anchors.leftMargin: select.width / 2.5
anchors.left: comboBox.left
anchors.leftMargin: comboBox.width / 2.5
color: !root.isValid ? Theme.palette.dangerColor1 : Theme.palette.baseColor1
elide: Text.ElideRight
@ -116,6 +127,7 @@ Item {
onExited: assetTooltip.visible = false
}
}
StatusBaseText {
id: txtAssetSymbol
visible: txtAssetBalance.visible
@ -126,152 +138,149 @@ Item {
font.pixelSize: 13
height: txtAssetBalance.height
}
StatusSelect {
id: select
StatusComboBox {
id: comboBox
label: root.label
model: root.accounts
width: parent.width
menuAlignment: StatusSelect.MenuAlignment.Left
selectMenu.delegate: menuItem
selectMenu.width: dropdownWidth
selectedItemComponent: Item {
anchors.fill: parent
model: SortFilterProxyModel {
sourceModel: root.accounts
filters: [
ValueFilter {
roleName: "walletType"
value: root.watchWalletType
inverted: true
}
]
}
contentItem: RowLayout {
spacing: 8
StatusIcon {
id: selectedIconImg
anchors.left: parent.left
anchors.leftMargin: 16
anchors.verticalCenter: parent.verticalCenter
width: 20
height: 20
Layout.alignment: Qt.AlignVCenter
Layout.preferredWidth: 20
Layout.preferredHeight: 20
icon: "filled-account"
color: d.selectedIconColor
}
StatusBaseText {
id: selectedTextField
elide: Text.ElideRight
anchors.left: selectedIconImg.right
anchors.leftMargin: 8
anchors.right: parent.right
anchors.rightMargin: select.selectedItemRightMargin
anchors.verticalCenter: parent.verticalCenter
Layout.fillWidth: true
Layout.fillHeight: true
font.pixelSize: 15
verticalAlignment: Text.AlignVCenter
height: 22
color: Theme.palette.directColor1
text: d.selectedText
}
}
delegate: StatusItemDelegate {
highlighted: index === comboBox.control.highlightedIndex
width: comboBox.width
padding: 16
onClicked: {
// WARNING: Settings comboBox value from delegate is wrong.
// ComboBox must have a single role as "value"
// This should be refactored later. Probably roleValue should be 'address'.
// All other needed values should be retrived from model by the user of component.
root.selectedAccount = { address, name, color: model.color, assets, currencyBalance };
}
Component.onCompleted: {
// WARNING: Same here, this is wrong, check comment above.
if (!root.selectedAccount && index === 0) {
root.selectedAccount = { address, name, color: model.color, assets, currencyBalance }
}
}
contentItem: RowLayout {
spacing: 0
StatusIcon {
id: iconImg
Layout.preferredWidth: 20
Layout.preferredHeight: 20
icon: "filled-account"
color: Utils.getThemeAccountColor(model.color, Theme.palette.userCustomizationColors) ||
Theme.palette.userCustomizationColors[0]
}
ColumnLayout {
id: column
Layout.fillWidth: true
Layout.leftMargin: 14
Layout.rightMargin: 8
spacing: 0
StatusBaseText {
id: accountName
Layout.fillWidth: true
text: model.name
elide: Text.ElideRight
font.pixelSize: 15
color: Theme.palette.directColor1
}
StatusBaseText {
id: accountAddress
Layout.fillWidth: true
Layout.maximumWidth: 80
text: address
elide: Text.ElideMiddle
color: Theme.palette.baseColor1
font.pixelSize: 12
}
}
StatusBaseText {
id: txtFiatBalance
Layout.rightMargin: 4
font.pixelSize: 15
text: currencyBalance
color: Theme.palette.directColor1
}
StatusBaseText {
id: fiatCurrencySymbol
font.pixelSize: 15
color: Theme.palette.baseColor1
text: root.currency.toUpperCase()
}
}
}
}
Row {
RowLayout {
id: selectedAccountDetails
visible: root.showAccountDetails
anchors.top: select.bottom
anchors.top: comboBox.bottom
anchors.topMargin: 8
anchors.left: parent.left
anchors.leftMargin: 2
anchors.right: parent.right
anchors.rightMargin: 4
spacing: 2
StatusBaseText {
id: textSelectedAddress
Layout.maximumWidth: 80
font.pixelSize: 12
elide: Text.ElideMiddle
width: 90
color: Theme.palette.baseColor1
}
StatusBaseText {
id: textSelectedAddressFiatBalance
font.pixelSize: 12
color: Theme.palette.baseColor1
text: "•"
}
}
Component {
id: menuItem
MenuItem {
id: itemContainer
visible: walletType !== root.watchWalletType
property bool isFirstItem: index === 0
property bool isLastItem: index === accounts.rowCount() - 1
Component.onCompleted: {
if (!root.selectedAccount && isFirstItem) {
root.selectedAccount = { address, name, color: model.color, assets, currencyBalance }
}
}
height: walletType === root.watchWalletType ? 0 : (accountName.height + 14 + accountAddress.height + 14)
StatusIcon {
id: iconImg
anchors.left: parent.left
anchors.leftMargin: 16
anchors.verticalCenter: parent.verticalCenter
width: 20
height: 20
icon: "filled-account"
color: Utils.getThemeAccountColor(model.color, Theme.palette.userCustomizationColors) || Theme.palette.userCustomizationColors[0]
}
Column {
id: column
anchors.left: iconImg.right
anchors.leftMargin: 14
anchors.right: txtFiatBalance.left
anchors.rightMargin: 8
anchors.verticalCenter: parent.verticalCenter
StatusBaseText {
id: accountName
text: model.name
elide: Text.ElideRight
font.pixelSize: 15
anchors.left: parent.left
anchors.right: parent.right
height: 22
color: Theme.palette.directColor1
}
StatusBaseText {
id: accountAddress
text: address
elide: Text.ElideMiddle
width: 80
color: Theme.palette.baseColor1
font.pixelSize: 12
height: 16
}
}
StatusBaseText {
id: txtFiatBalance
anchors.right: fiatCurrencySymbol.left
anchors.rightMargin: 4
anchors.verticalCenter: parent.verticalCenter
font.pixelSize: 15
height: 22
text: currencyBalance
color: Theme.palette.directColor1
}
StatusBaseText {
id: fiatCurrencySymbol
anchors.right: parent.right
anchors.rightMargin: 16
anchors.verticalCenter: parent.verticalCenter
font.pixelSize: 15
height: 22
color: Theme.palette.baseColor1
text: root.currency.toUpperCase()
}
background: Rectangle {
color: itemContainer.highlighted ? Theme.palette.statusSelect.menuItemHoverBackgroundColor : Theme.palette.statusSelect.menuItemBackgroundColor
}
MouseArea {
cursorShape: Qt.PointingHandCursor
anchors.fill: itemContainer
onClicked: {
root.selectedAccount = { address, name, color: model.color, assets, currencyBalance }
select.selectMenu.close()
}
}
StatusBaseText {
id: textSelectedAddressFiatBalance
Layout.fillWidth: true
font.pixelSize: 12
color: Theme.palette.baseColor1
}
}
}

View File

@ -2,36 +2,28 @@ import QtQuick 2.13
import QtQuick.Controls 2.13
import StatusQ.Controls 0.1
Item {
id: root
property string selectedColor
property string label: "Color"
property var model
height: accountColorInput.height
implicitWidth: 448
StatusComboBox {
id: root
StatusSelect {
id: accountColorInput
bgColor: selectedColor
label: root.label
model: root.model
label: qsTr("Color")
selectMenu.delegate: Component {
MenuItem {
property bool isFirstItem: index === 0
property bool isLastItem: index === root.model.length - 1
height: 52
width: parent.width
padding: 10
onTriggered: function () {
const selectedColor = root.model[index]
root.selectedColor = selectedColor
}
background: Rectangle {
color: root.model[index] || "transparent"
}
}
}
}
control.popup.horizontalPadding: 0
contentItem: null
control.background: Rectangle {
implicitWidth: 448
radius: 8
color: root.control.currentValue
}
delegate: StatusItemDelegate {
width: parent.width
background: Rectangle {
width: parent.width
implicitHeight: 52
color: modelData
}
}
}

View File

@ -1,4 +1,5 @@
import QtQuick 2.14
import QtQuick.Window 2.14
import QtQuick.Controls 2.14
import QtQuick.Layouts 1.14
import QtGraphicalEffects 1.13
@ -12,11 +13,14 @@ import QtQuick.Templates 2.14 as T
Item {
id: root
property alias comboBox: comboBox
property alias control: comboBox
property alias model: comboBox.model
property alias delegate: comboBox.delegate
property alias contentItem: comboBox.contentItem
property alias currentIndex: comboBox.currentIndex
property alias currentValue: comboBox.currentValue
property alias label: labelItem.text
property alias validationError: validationErrorItem.text
@ -46,7 +50,8 @@ Item {
property color bgColorHover: bgColor
Layout.fillWidth: true
Layout.topMargin: 7
Layout.fillHeight: true
Layout.topMargin: labelItem.visible ? 7 : 0
enabled: root.enabled
@ -91,24 +96,15 @@ Item {
popup: Popup {
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent
y: comboBox.height + 8
width: comboBox.width
implicitHeight: contentItem.implicitHeight + topPadding + bottomPadding
height: Math.min(contentItem.implicitHeight + topPadding + bottomPadding,
comboBox.Window.height - topMargin - bottomMargin)
margins: 8
padding: 1
verticalPadding: 8
contentItem: ListView { // TODO: Replace with StatusListView
id: listView
clip: true
implicitHeight: contentHeight
model: comboBox.popup.visible ? comboBox.delegateModel : null
currentIndex: comboBox.highlightedIndex
boundsBehavior: Flickable.StopAtBounds
synchronousDrag: true
ScrollIndicator.vertical: ScrollIndicator { }
}
background: Rectangle {
id: backgroundItem
color: Theme.palette.statusSelect.menuItemBackgroundColor
@ -124,13 +120,26 @@ Item {
color: Theme.palette.dropShadow
}
}
contentItem: StatusListView {
id: listView
implicitWidth: contentWidth
implicitHeight: contentHeight
model: comboBox.popup.visible ? comboBox.delegateModel : null
currentIndex: comboBox.highlightedIndex
}
}
delegate: StatusItemDelegate {
width: comboBox.width
highlighted: comboBox.highlightedIndex === index
font: comboBox.font
text: modelData
text: control.textRole ? (Array.isArray(control.model)
? modelData[control.textRole]
: model[control.textRole])
: modelData
}
}

View File

@ -102,10 +102,6 @@ Item {
}
}
// ListView {
// id: selectMenu
// }
StatusPopupMenu {
id: selectMenu
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent