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.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
ListElement { accounts: accountsModel
name: "Pascal" }
address: "0x1234567891011"
path: "" ListModel {
color: "red" id: accountsModel
publicKey: ""
walletType: "generated" ListElement {
isChat: "" name: "Pascal"
currencyBalance: "1199.02" address: "0x1234567891011"
assets: [] path: ""
} color: "red"
ListElement { publicKey: ""
name: "Boris" walletType: "generated"
address: "0x123" isChat: ""
path: "" currencyBalance: "1199.02"
color: "red" assets: []
publicKey: "" }
walletType: "generated" ListElement {
isChat: "" name: "Boris"
currencyBalance: "0" address: "0x123"
assets: [] path: ""
} color: "red"
ListElement { publicKey: ""
name: "Alexandra" walletType: "generated"
address: "0x123" isChat: ""
path: "" currencyBalance: "42.42"
color: "yellow" assets: []
publicKey: "" }
walletType: "generated" ListElement {
isChat: "" name: "Alexandra"
currencyBalance: "0" address: "0x123"
assets: [] path: ""
} color: "yellow"
ListElement { publicKey: ""
name: "Khushboo" walletType: "generated"
address: "0x123" isChat: ""
path: "" currencyBalance: "0"
color: "blue" assets: []
publicKey: "" }
walletType: "generated" ListElement {
isChat: "" name: "Khushboo"
currencyBalance: "0" address: "0x123"
assets: [] 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 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
}
}
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 id: selectedAccountDetails
visible: root.showAccountDetails visible: root.showAccountDetails
anchors.top: select.bottom anchors.top: comboBox.bottom
anchors.topMargin: 8 anchors.topMargin: 8
anchors.left: parent.left anchors.left: parent.left
anchors.leftMargin: 2 anchors.leftMargin: 2
anchors.right: parent.right
anchors.rightMargin: 4
spacing: 2
StatusBaseText { StatusBaseText {
id: textSelectedAddress id: textSelectedAddress
Layout.maximumWidth: 80
font.pixelSize: 12 font.pixelSize: 12
elide: Text.ElideMiddle elide: Text.ElideMiddle
width: 90
color: Theme.palette.baseColor1 color: Theme.palette.baseColor1
} }
StatusBaseText { StatusBaseText {
id: textSelectedAddressFiatBalance
font.pixelSize: 12 font.pixelSize: 12
color: Theme.palette.baseColor1 color: Theme.palette.baseColor1
text: "•"
} }
} StatusBaseText {
id: textSelectedAddressFiatBalance
Component { Layout.fillWidth: true
id: menuItem font.pixelSize: 12
MenuItem { color: Theme.palette.baseColor1
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()
}
}
} }
} }
} }

View File

@ -2,36 +2,28 @@ 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"
property var model
height: accountColorInput.height
implicitWidth: 448
StatusSelect { label: qsTr("Color")
id: accountColorInput
bgColor: selectedColor
label: root.label
model: root.model
selectMenu.delegate: Component { control.popup.horizontalPadding: 0
MenuItem {
property bool isFirstItem: index === 0 contentItem: null
property bool isLastItem: index === root.model.length - 1
height: 52 control.background: Rectangle {
width: parent.width implicitWidth: 448
padding: 10 radius: 8
onTriggered: function () { color: root.control.currentValue
const selectedColor = root.model[index] }
root.selectedColor = selectedColor
} delegate: StatusItemDelegate {
background: Rectangle { width: parent.width
color: root.model[index] || "transparent" background: Rectangle {
} 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