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,13 +8,18 @@ import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1 import StatusQ.Controls 0.1
import StatusQ.Popups 0.1 import StatusQ.Popups 0.1
Column { Column {
spacing: 8 spacing: 8
StatusAccountSelector { StatusAccountSelector {
id: accountSelector id: selector1
accounts: ListModel { width: 300
accounts: accountsModel
}
ListModel {
id: accountsModel
ListElement { ListElement {
name: "Pascal" name: "Pascal"
address: "0x1234567891011" address: "0x1234567891011"
@ -34,7 +39,7 @@ Column {
publicKey: "" publicKey: ""
walletType: "generated" walletType: "generated"
isChat: "" isChat: ""
currencyBalance: "0" currencyBalance: "42.42"
assets: [] assets: []
} }
ListElement { ListElement {
@ -54,11 +59,10 @@ Column {
path: "" path: ""
color: "blue" color: "blue"
publicKey: "" publicKey: ""
walletType: "generated" walletType: "watch" // Will be automatically filtered by StatusAccountSelector
isChat: "" isChat: ""
currencyBalance: "0" currencyBalance: "0"
assets: [] assets: []
} }
} }
} }
}

View File

@ -19,9 +19,24 @@ Item {
spacing: 20 spacing: 20
RowLayout { RowLayout {
StatusSelect { Layout.fillWidth: true
id: select
label: "Select Card State" 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 { model: ListModel {
ListElement { ListElement {
name: "default" name: "default"
@ -36,47 +51,18 @@ Item {
name: "unpreferred" 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 { StatusCheckBox {
Layout.alignment: Qt.AlignVCenter
text: "advancedMode" text: "advancedMode"
font.family: Theme.palette.monoFont.name
onClicked: { onClicked: {
card.advancedMode = checked 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 { Rectangle {
height: 1 height: 1
width: 700 width: 700

View File

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

View File

@ -39,10 +39,10 @@ Column {
label: "ComboBox with custom delegate" label: "ComboBox with custom delegate"
model: commmonModel model: commmonModel
delegate: StatusItemDelegate { delegate: StatusItemDelegate {
width: comboBox1.comboBox.width width: comboBox1.control.width
highlighted: comboBox1.comboBox.highlightedIndex === index highlighted: comboBox1.control.highlightedIndex === index
text: modelData text: modelData
font: comboBox1.comboBox.font font: comboBox1.control.font
icon { icon {
name: "filled-account" name: "filled-account"
color: Theme.palette.primaryColor1 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 { StatusSelect {
id: select id: select
label: "Some label" label: "Some label"

View File

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

View File

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

View File

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