From 5b3192693913835bf72f5e0f7002b3fd38714175 Mon Sep 17 00:00:00 2001 From: Igor Sirotin Date: Wed, 3 Aug 2022 15:13:31 +0300 Subject: [PATCH] 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` --- .../pages/StatusAccountSelectorPage.qml | 98 +++---- ui/StatusQ/sandbox/pages/StatusCardPage.qml | 54 ++-- .../sandbox/pages/StatusColorSelectorPage.qml | 2 +- .../sandbox/pages/StatusComboBoxPage.qml | 6 +- ui/StatusQ/sandbox/pages/StatusSelectPage.qml | 7 + .../Controls/StatusAccountSelector.qml | 259 +++++++++--------- .../StatusQ/Controls/StatusColorSelector.qml | 50 ++-- .../src/StatusQ/Controls/StatusComboBox.qml | 43 +-- .../src/StatusQ/Controls/StatusSelect.qml | 4 - 9 files changed, 263 insertions(+), 260 deletions(-) diff --git a/ui/StatusQ/sandbox/pages/StatusAccountSelectorPage.qml b/ui/StatusQ/sandbox/pages/StatusAccountSelectorPage.qml index ab1bce4660..bcdf648053 100644 --- a/ui/StatusQ/sandbox/pages/StatusAccountSelectorPage.qml +++ b/ui/StatusQ/sandbox/pages/StatusAccountSelectorPage.qml @@ -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: [] } } } diff --git a/ui/StatusQ/sandbox/pages/StatusCardPage.qml b/ui/StatusQ/sandbox/pages/StatusCardPage.qml index 9ecdb538df..2ad8e13403 100644 --- a/ui/StatusQ/sandbox/pages/StatusCardPage.qml +++ b/ui/StatusQ/sandbox/pages/StatusCardPage.qml @@ -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 diff --git a/ui/StatusQ/sandbox/pages/StatusColorSelectorPage.qml b/ui/StatusQ/sandbox/pages/StatusColorSelectorPage.qml index 01f56c2a1e..8cb095234c 100644 --- a/ui/StatusQ/sandbox/pages/StatusColorSelectorPage.qml +++ b/ui/StatusQ/sandbox/pages/StatusColorSelectorPage.qml @@ -8,7 +8,7 @@ import StatusQ.Controls 0.1 import Sandbox 0.1 -Column { +Row { spacing: 8 StatusColorSelector { diff --git a/ui/StatusQ/sandbox/pages/StatusComboBoxPage.qml b/ui/StatusQ/sandbox/pages/StatusComboBoxPage.qml index 6cbfda6d42..ab709ef649 100644 --- a/ui/StatusQ/sandbox/pages/StatusComboBoxPage.qml +++ b/ui/StatusQ/sandbox/pages/StatusComboBoxPage.qml @@ -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 diff --git a/ui/StatusQ/sandbox/pages/StatusSelectPage.qml b/ui/StatusQ/sandbox/pages/StatusSelectPage.qml index cd841e27b6..fc48c0ea00 100644 --- a/ui/StatusQ/sandbox/pages/StatusSelectPage.qml +++ b/ui/StatusQ/sandbox/pages/StatusSelectPage.qml @@ -28,6 +28,13 @@ Column { } } + StatusBaseText { + font.pixelSize: 16 + color: Theme.palette.dangerColor1 + text: "This component should no longer be used.
Please, use `StatusComboBox` instead." + textFormat: Text.MarkdownText + } + StatusSelect { id: select label: "Some label" diff --git a/ui/StatusQ/src/StatusQ/Controls/StatusAccountSelector.qml b/ui/StatusQ/src/StatusQ/Controls/StatusAccountSelector.qml index 60967fd301..875980516b 100644 --- a/ui/StatusQ/src/StatusQ/Controls/StatusAccountSelector.qml +++ b/ui/StatusQ/src/StatusQ/Controls/StatusAccountSelector.qml @@ -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 } } } diff --git a/ui/StatusQ/src/StatusQ/Controls/StatusColorSelector.qml b/ui/StatusQ/src/StatusQ/Controls/StatusColorSelector.qml index 847ab60b3d..bc278b050e 100644 --- a/ui/StatusQ/src/StatusQ/Controls/StatusColorSelector.qml +++ b/ui/StatusQ/src/StatusQ/Controls/StatusColorSelector.qml @@ -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 + } + } } diff --git a/ui/StatusQ/src/StatusQ/Controls/StatusComboBox.qml b/ui/StatusQ/src/StatusQ/Controls/StatusComboBox.qml index bd0a2c13f5..5105ac8772 100644 --- a/ui/StatusQ/src/StatusQ/Controls/StatusComboBox.qml +++ b/ui/StatusQ/src/StatusQ/Controls/StatusComboBox.qml @@ -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 } } diff --git a/ui/StatusQ/src/StatusQ/Controls/StatusSelect.qml b/ui/StatusQ/src/StatusQ/Controls/StatusSelect.qml index b695aa0b2d..dc03a663c8 100644 --- a/ui/StatusQ/src/StatusQ/Controls/StatusSelect.qml +++ b/ui/StatusQ/src/StatusQ/Controls/StatusSelect.qml @@ -102,10 +102,6 @@ Item { } } -// ListView { -// id: selectMenu -// } - StatusPopupMenu { id: selectMenu closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent