feat: Send transaction component -- Account selector
Fixes #670. Component spec based on https://www.notion.so/emizzle/Wallet-transaction-components-2003b78a8d0d41c4ab3d21eb2496fb20. Changes the current Select shared component to a model databound component. This means we can bind directly to `QAbstractListModel`'s coming from Nim instead of needing manipulating the data in to javascript objects. The changes to the Select component will be used for the upcoming Asset selector shared component.
This commit is contained in:
parent
cb92c1dc14
commit
9374be5857
|
@ -1,9 +1,11 @@
|
|||
import NimQml, Tables, random
|
||||
import NimQml, Tables, random, strformat, json_serialization
|
||||
import sequtils as sequtils
|
||||
import account_item
|
||||
import account_item, asset_list
|
||||
from ../../../status/wallet import WalletAccount
|
||||
|
||||
const accountColors* = ["#9B832F", "#D37EF4", "#1D806F", "#FA6565", "#7CDA00", "#887af9", "#8B3131"]
|
||||
type
|
||||
AccountView* = tuple[account: WalletAccount, assets: AssetList]
|
||||
|
||||
type
|
||||
AccountRoles {.pure.} = enum
|
||||
|
@ -11,10 +13,12 @@ type
|
|||
Address = UserRole + 2,
|
||||
Color = UserRole + 3,
|
||||
Balance = UserRole + 4
|
||||
FiatBalance = UserRole + 5
|
||||
Assets = UserRole + 6
|
||||
|
||||
QtObject:
|
||||
type AccountList* = ref object of QAbstractListModel
|
||||
accounts*: seq[WalletAccount]
|
||||
accounts*: seq[AccountView]
|
||||
|
||||
proc setup(self: AccountList) = self.QAbstractListModel.setup
|
||||
|
||||
|
@ -27,12 +31,14 @@ QtObject:
|
|||
result.accounts = @[]
|
||||
result.setup
|
||||
|
||||
proc getAccount*(self: AccountList, index: int): WalletAccount = self.accounts[index]
|
||||
proc getAccount*(self: AccountList, index: int): WalletAccount = self.accounts[index].account
|
||||
|
||||
proc rowData(self: AccountList, index: int, column: string): string {.slot.} =
|
||||
if (index >= self.accounts.len):
|
||||
return
|
||||
let account = self.accounts[index]
|
||||
let
|
||||
accountView = self.accounts[index]
|
||||
account = accountView.account
|
||||
case column:
|
||||
of "name": result = account.name
|
||||
of "address": result = account.address
|
||||
|
@ -40,11 +46,12 @@ QtObject:
|
|||
of "balance": result = account.balance
|
||||
of "path": result = account.path
|
||||
of "walletType": result = account.walletType
|
||||
of "fiatBalance": result = fmt"{account.realFiatBalance:>.2f}"
|
||||
|
||||
proc getAccountindexByAddress*(self: AccountList, address: string): int =
|
||||
var i = 0
|
||||
for account in self.accounts:
|
||||
if (account.address == address):
|
||||
for accountView in self.accounts:
|
||||
if (accountView.account.address == address):
|
||||
return i
|
||||
i = i + 1
|
||||
return -1
|
||||
|
@ -60,26 +67,33 @@ QtObject:
|
|||
return
|
||||
if index.row < 0 or index.row >= self.accounts.len:
|
||||
return
|
||||
let account = self.accounts[index.row]
|
||||
let accountView = self.accounts[index.row]
|
||||
let account = accountView.account
|
||||
let accountRole = role.AccountRoles
|
||||
case accountRole:
|
||||
of AccountRoles.Name: result = newQVariant(account.name)
|
||||
of AccountRoles.Address: result = newQVariant(account.address)
|
||||
of AccountRoles.Color: result = newQVariant(account.iconColor)
|
||||
of AccountRoles.Balance: result = newQVariant(account.balance)
|
||||
of AccountRoles.FiatBalance: result = newQVariant(fmt"{account.realFiatBalance:>.2f}")
|
||||
of AccountRoles.Assets: result = newQVariant(accountView.assets)
|
||||
|
||||
method roleNames(self: AccountList): Table[int, string] =
|
||||
{ AccountRoles.Name.int:"name",
|
||||
AccountRoles.Address.int:"address",
|
||||
AccountRoles.Color.int:"iconColor",
|
||||
AccountRoles.Balance.int:"balance" }.toTable
|
||||
AccountRoles.Balance.int:"balance",
|
||||
AccountRoles.FiatBalance.int:"fiatBalance",
|
||||
AccountRoles.Assets.int:"assets" }.toTable
|
||||
|
||||
proc addAccountToList*(self: AccountList, account: WalletAccount) =
|
||||
if account.iconColor == "":
|
||||
randomize()
|
||||
account.iconColor = accountColors[rand(accountColors.len - 1)]
|
||||
let assets = newAssetList()
|
||||
assets.setNewData(account.assetList)
|
||||
self.beginInsertRows(newQModelIndex(), self.accounts.len, self.accounts.len)
|
||||
self.accounts.add(account)
|
||||
self.accounts.add((account: account, assets: assets))
|
||||
self.endInsertRows()
|
||||
|
||||
proc forceUpdate*(self: AccountList) =
|
||||
|
|
|
@ -33,20 +33,37 @@ Item {
|
|||
text: qsTr("Language")
|
||||
}
|
||||
Select {
|
||||
id: select
|
||||
selectedText: languageSetting.currentLocale
|
||||
anchors.right: undefined
|
||||
anchors.left: undefined
|
||||
width: 100
|
||||
Layout.leftMargin: Style.current.padding
|
||||
selectOptions: Locales_JSON.locales.map(locale => {
|
||||
return {
|
||||
label: locale,
|
||||
onClicked: function () {
|
||||
model: Locales_JSON.locales
|
||||
menu.delegate: Component {
|
||||
MenuItem {
|
||||
id: menuItem
|
||||
height: itemText.height + 4
|
||||
width: parent.width
|
||||
padding: 10
|
||||
onTriggered: function () {
|
||||
const locale = Locales_JSON.locales[index]
|
||||
profileModel.changeLocale(locale)
|
||||
appSettings.locale = locale
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
StyledText {
|
||||
id: itemText
|
||||
text: Locales_JSON.locales[index]
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 5
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
background: Rectangle {
|
||||
color: menuItem.highlighted ? Style.current.backgroundHover : Style.current.transparent
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@ ModalPopup {
|
|||
height: 675
|
||||
|
||||
property int marginBetweenInputs: 35
|
||||
property string selectedColor: currentAccount.iconColor
|
||||
property string accountNameValidationError: ""
|
||||
|
||||
function validate() {
|
||||
|
@ -43,23 +42,14 @@ ModalPopup {
|
|||
validationError: popup.accountNameValidationError
|
||||
}
|
||||
|
||||
Select {
|
||||
ColorSelector {
|
||||
id: accountColorInput
|
||||
selectedColor: currentAccount.iconColor
|
||||
model: Constants.accountColors
|
||||
anchors.top: accountNameInput.bottom
|
||||
anchors.topMargin: marginBetweenInputs
|
||||
bgColor: selectedColor
|
||||
//% "Account color"
|
||||
label: qsTrId("account-color")
|
||||
selectOptions: Constants.accountColors.map(color => {
|
||||
return {
|
||||
text: "",
|
||||
bgColor: color,
|
||||
height: 52,
|
||||
onClicked: function () {
|
||||
selectedColor = color
|
||||
}
|
||||
}
|
||||
})
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
}
|
||||
|
||||
TextWithLabel {
|
||||
|
@ -181,7 +171,7 @@ ModalPopup {
|
|||
return
|
||||
}
|
||||
|
||||
const error = walletModel.changeAccountSettings(currentAccount.address, accountNameInput.text, selectedColor);
|
||||
const error = walletModel.changeAccountSettings(currentAccount.address, accountNameInput.text, accountColorInput.selectedColor);
|
||||
|
||||
if (error) {
|
||||
errorSound.play()
|
||||
|
|
|
@ -17,17 +17,6 @@ ModalPopup {
|
|||
sendModalContent.amountInput.text = ""
|
||||
sendModalContent.passwordInput.text = ""
|
||||
sendModalContent.amountInput.forceActiveFocus(Qt.MouseFocusReason)
|
||||
const accounts = walletModel.accounts
|
||||
const numAccounts = accounts.rowCount()
|
||||
const accountsData = []
|
||||
for (let i = 0; i < numAccounts; i++) {
|
||||
accountsData.push({
|
||||
name: accounts.rowData(i, 'name'),
|
||||
address: accounts.rowData(i, 'address'),
|
||||
iconColor: accounts.rowData(i, 'iconColor')
|
||||
})
|
||||
}
|
||||
sendModalContent.accounts = accountsData
|
||||
|
||||
const assets = walletModel.assets
|
||||
const numAssets = assets.rowCount()
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import QtQuick 2.13
|
||||
import QtQuick.Controls 2.13
|
||||
import QtQuick.Dialogs 1.3
|
||||
import "../../../../imports"
|
||||
import "../../../../shared"
|
||||
|
@ -10,7 +11,6 @@ ModalPopup {
|
|||
height: 600
|
||||
|
||||
property int marginBetweenInputs: 38
|
||||
property string selectedColor: Constants.accountColors[0]
|
||||
property string passwordValidationError: ""
|
||||
property string privateKeyValidationError: ""
|
||||
property string accountNameValidationError: ""
|
||||
|
@ -86,23 +86,14 @@ ModalPopup {
|
|||
validationError: popup.accountNameValidationError
|
||||
}
|
||||
|
||||
Select {
|
||||
ColorSelector {
|
||||
id: accountColorInput
|
||||
selectedColor: Constants.accountColors[0]
|
||||
model: Constants.accountColors
|
||||
anchors.top: accountNameInput.bottom
|
||||
anchors.topMargin: marginBetweenInputs
|
||||
bgColor: selectedColor
|
||||
//% "Account color"
|
||||
label: qsTrId("account-color")
|
||||
selectOptions: Constants.accountColors.map(color => {
|
||||
return {
|
||||
text: "",
|
||||
bgColor: color,
|
||||
height: 52,
|
||||
onClicked: function () {
|
||||
selectedColor = color
|
||||
}
|
||||
}
|
||||
})
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
}
|
||||
|
||||
footer: StyledButton {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import QtQuick 2.13
|
||||
import QtQuick.Controls 2.13
|
||||
import QtQuick.Dialogs 1.3
|
||||
import "../../../../imports"
|
||||
import "../../../../shared"
|
||||
|
@ -8,7 +9,6 @@ ModalPopup {
|
|||
height: 600
|
||||
|
||||
property int marginBetweenInputs: 38
|
||||
property string selectedColor: Constants.accountColors[0]
|
||||
property string passwordValidationError: ""
|
||||
property string seedValidationError: ""
|
||||
property string accountNameValidationError: ""
|
||||
|
@ -87,23 +87,14 @@ ModalPopup {
|
|||
validationError: popup.accountNameValidationError
|
||||
}
|
||||
|
||||
Select {
|
||||
ColorSelector {
|
||||
id: accountColorInput
|
||||
selectedColor: Constants.accountColors[0]
|
||||
model: Constants.accountColors
|
||||
anchors.top: accountNameInput.bottom
|
||||
anchors.topMargin: marginBetweenInputs
|
||||
bgColor: selectedColor
|
||||
//% "Account color"
|
||||
label: qsTrId("account-color")
|
||||
selectOptions: Constants.accountColors.map(color => {
|
||||
return {
|
||||
text: "",
|
||||
bgColor: color,
|
||||
height: 52,
|
||||
onClicked: function () {
|
||||
selectedColor = color
|
||||
}
|
||||
}
|
||||
})
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
}
|
||||
|
||||
footer: StyledButton {
|
||||
|
@ -133,7 +124,7 @@ ModalPopup {
|
|||
return loading = false
|
||||
}
|
||||
|
||||
const error = walletModel.addAccountsFromSeed(accountSeedInput.text, passwordInput.text, accountNameInput.text, selectedColor)
|
||||
const error = walletModel.addAccountsFromSeed(accountSeedInput.text, passwordInput.text, accountNameInput.text, accountColorInput.selectedColor)
|
||||
loading = false
|
||||
if (error) {
|
||||
errorSound.play()
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import QtQuick 2.13
|
||||
import QtQuick.Controls 2.13
|
||||
import QtQuick.Dialogs 1.3
|
||||
import "../../../../imports"
|
||||
import "../../../../shared"
|
||||
|
@ -9,7 +10,6 @@ ModalPopup {
|
|||
title: qsTrId("add-watch-account")
|
||||
|
||||
property int marginBetweenInputs: 38
|
||||
property string selectedColor: Constants.accountColors[0]
|
||||
property string addressError: ""
|
||||
property string accountNameValidationError: ""
|
||||
property bool loading: false
|
||||
|
@ -61,23 +61,14 @@ ModalPopup {
|
|||
validationError: popup.accountNameValidationError
|
||||
}
|
||||
|
||||
Select {
|
||||
ColorSelector {
|
||||
id: accountColorInput
|
||||
selectedColor: Constants.accountColors[0]
|
||||
model: Constants.accountColors
|
||||
anchors.top: accountNameInput.bottom
|
||||
anchors.topMargin: marginBetweenInputs
|
||||
bgColor: selectedColor
|
||||
//% "Account color"
|
||||
label: qsTrId("account-color")
|
||||
selectOptions: Constants.accountColors.map(color => {
|
||||
return {
|
||||
text: "",
|
||||
bgColor: color,
|
||||
height: 52,
|
||||
onClicked: function () {
|
||||
selectedColor = color
|
||||
}
|
||||
}
|
||||
})
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
}
|
||||
|
||||
footer: StyledButton {
|
||||
|
@ -107,7 +98,7 @@ ModalPopup {
|
|||
return loading = false
|
||||
}
|
||||
|
||||
const error = walletModel.addWatchOnlyAccount(addressInput.text, accountNameInput.text, selectedColor);
|
||||
const error = walletModel.addWatchOnlyAccount(addressInput.text, accountNameInput.text, accountColorInput.selectedColor);
|
||||
loading = false
|
||||
if (error) {
|
||||
errorSound.play()
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import QtQuick 2.13
|
||||
import QtQuick.Controls 2.13
|
||||
import QtQuick.Dialogs 1.3
|
||||
import "../../../../imports"
|
||||
import "../../../../shared"
|
||||
|
@ -9,7 +10,6 @@ ModalPopup {
|
|||
title: qsTrId("generate-a-new-account")
|
||||
|
||||
property int marginBetweenInputs: 38
|
||||
property string selectedColor: Constants.accountColors[0]
|
||||
property string passwordValidationError: ""
|
||||
property string accountNameValidationError: ""
|
||||
property bool loading: false
|
||||
|
@ -61,23 +61,14 @@ ModalPopup {
|
|||
validationError: popup.accountNameValidationError
|
||||
}
|
||||
|
||||
Select {
|
||||
ColorSelector {
|
||||
id: accountColorInput
|
||||
selectedColor: Constants.accountColors[0]
|
||||
model: Constants.accountColors
|
||||
anchors.top: accountNameInput.bottom
|
||||
anchors.topMargin: marginBetweenInputs
|
||||
bgColor: selectedColor
|
||||
//% "Account color"
|
||||
label: qsTrId("account-color")
|
||||
selectOptions: Constants.accountColors.map(color => {
|
||||
return {
|
||||
text: "",
|
||||
bgColor: color,
|
||||
height: 52,
|
||||
onClicked: function () {
|
||||
selectedColor = color
|
||||
}
|
||||
}
|
||||
})
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
}
|
||||
|
||||
footer: StyledButton {
|
||||
|
@ -107,7 +98,7 @@ ModalPopup {
|
|||
return loading = false
|
||||
}
|
||||
|
||||
const error = walletModel.generateNewAccount(passwordInput.text, accountNameInput.text, selectedColor)
|
||||
const error = walletModel.generateNewAccount(passwordInput.text, accountNameInput.text, accountColorInput.selectedColor)
|
||||
loading = false
|
||||
if (error) {
|
||||
errorSound.play()
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import QtQuick 2.13
|
||||
import QtQuick.Controls 2.13
|
||||
import QtQuick.Dialogs 1.3
|
||||
import "../../../../imports"
|
||||
import "../../../../shared"
|
||||
|
@ -8,14 +9,8 @@ Item {
|
|||
property var closePopup: function(){}
|
||||
property alias amountInput: txtAmount
|
||||
property alias passwordInput: txtPassword
|
||||
property var accounts: []
|
||||
property var assets: []
|
||||
|
||||
property int selectedAccountIndex: 0
|
||||
property string selectedAccountAddress: accounts && accounts.length ? accounts[selectedAccountIndex].address : ""
|
||||
property string selectedAccountName: accounts && accounts.length ? accounts[selectedAccountIndex].name : ""
|
||||
property string selectedAccountIconColor: accounts && accounts.length ? accounts[selectedAccountIndex].iconColor : ""
|
||||
|
||||
property int selectedAssetIndex: 0
|
||||
property string selectedAssetName: assets && assets.length ? assets[selectedAssetIndex].name : ""
|
||||
property string selectedAssetAddress: assets && assets.length ? assets[selectedAssetIndex].address : ""
|
||||
|
@ -30,8 +25,7 @@ Item {
|
|||
if (!validate()) {
|
||||
return;
|
||||
}
|
||||
|
||||
let result = walletModel.onSendTransaction(selectedAccountAddress,
|
||||
let result = walletModel.onSendTransaction(selectFromAccount.selectedAccount.address,
|
||||
txtTo.text,
|
||||
selectedAssetAddress,
|
||||
txtAmount.text,
|
||||
|
@ -125,14 +119,27 @@ Item {
|
|||
anchors.top: txtAmount.bottom
|
||||
anchors.topMargin: Style.current.padding
|
||||
selectedText: selectedAssetName
|
||||
selectOptions: sendModalContent.assets.map(function (asset, index) {
|
||||
return {
|
||||
text: asset.name,
|
||||
onClicked: function () {
|
||||
model: sendModalContent.assets
|
||||
menu.delegate: Component {
|
||||
MenuItem {
|
||||
|
||||
height: itemText.height + 4
|
||||
width: parent ? parent.width : selectMenu.width
|
||||
padding: 10
|
||||
|
||||
StyledText {
|
||||
id: itemText
|
||||
text: sendModalContent.assets[index].name
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 5
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
onTriggered: function () {
|
||||
selectedAssetIndex = index
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
StyledText {
|
||||
|
@ -147,38 +154,14 @@ Item {
|
|||
anchors.rightMargin: 0
|
||||
}
|
||||
|
||||
Select {
|
||||
id: txtFrom
|
||||
iconHeight: 12
|
||||
iconWidth: 12
|
||||
icon: "../../../img/walletIcon.svg"
|
||||
iconColor: selectedAccountIconColor
|
||||
//% "From account"
|
||||
label: qsTrId("from-account")
|
||||
|
||||
AccountSelector {
|
||||
id: selectFromAccount
|
||||
accounts: walletModel.accounts
|
||||
anchors.top: assetTypeSelect.bottom
|
||||
anchors.topMargin: Style.current.padding
|
||||
selectedText: selectedAccountName
|
||||
selectOptions: sendModalContent.accounts.map(function (account, index) {
|
||||
return {
|
||||
text: account.name,
|
||||
onClicked: function () {
|
||||
selectedAccountIndex = index
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
StyledText {
|
||||
id: textSelectAccountAddress
|
||||
text: selectedAccountAddress
|
||||
font.family: Style.current.fontHexRegular.name
|
||||
anchors.right: parent.right
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 2
|
||||
elide: Text.ElideMiddle
|
||||
anchors.top: txtFrom.bottom
|
||||
font.pixelSize: 12
|
||||
color: Style.current.darkGrey
|
||||
anchors.right: parent.right
|
||||
}
|
||||
|
||||
Input {
|
||||
|
@ -187,7 +170,7 @@ Item {
|
|||
label: qsTrId("recipient")
|
||||
//% "Send to"
|
||||
placeholderText: qsTrId("send-to")
|
||||
anchors.top: textSelectAccountAddress.bottom
|
||||
anchors.top: selectFromAccount.bottom
|
||||
anchors.topMargin: Style.current.padding
|
||||
validationError: toValidationError
|
||||
}
|
||||
|
|
|
@ -25,4 +25,8 @@ Theme {
|
|||
property color inputBackground: secondaryBackground
|
||||
property color inputColor: darkGrey
|
||||
property color modalBackground: background
|
||||
property color backgroundHover: "#252528"
|
||||
property color secondaryText: darkGrey
|
||||
property color secondaryHover: Qt.rgba(255, 255, 255, 0.1)
|
||||
property color danger: red
|
||||
}
|
||||
|
|
|
@ -25,4 +25,8 @@ Theme {
|
|||
property color inputBackground: grey
|
||||
property color inputColor: black
|
||||
property color modalBackground: white2
|
||||
property color backgroundHover: grey
|
||||
property color secondaryText: darkGrey
|
||||
property color secondaryHover: Qt.rgba(0, 0, 0, 0.1)
|
||||
property color danger: red
|
||||
}
|
||||
|
|
|
@ -309,6 +309,7 @@ DISTFILES += \
|
|||
onboarding/img/wallet@2x.jpg \
|
||||
onboarding/img/wallet@3x.jpg \
|
||||
onboarding/qmldir \
|
||||
shared/AccountSelector.qml \
|
||||
shared/AddButton.qml \
|
||||
shared/IconButton.qml \
|
||||
shared/Input.qml \
|
||||
|
|
|
@ -0,0 +1,190 @@
|
|||
import QtQuick 2.13
|
||||
import QtQuick.Controls 2.13
|
||||
import QtQuick.Layouts 1.13
|
||||
import QtGraphicalEffects 1.13
|
||||
import "../imports"
|
||||
|
||||
Item {
|
||||
id: root
|
||||
property string label: qsTr("Choose account")
|
||||
property var accounts
|
||||
property var selectedAccount: {
|
||||
"address": "", "name": "", "iconColor": "", "fiatBalance": ""
|
||||
}
|
||||
height: select.height + selectedAccountDetails.height
|
||||
// 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
|
||||
property string showAssetBalance: ""
|
||||
|
||||
Repeater {
|
||||
visible: showAssetBalance !== ""
|
||||
model: selectedAccount.assets
|
||||
delegate: StyledText {
|
||||
visible: symbol === root.showAssetBalance.toUpperCase()
|
||||
anchors.bottom: select.top
|
||||
anchors.bottomMargin: -18
|
||||
anchors.right: parent.right
|
||||
text: "Balance: " + (parseFloat(value) === 0.0 ? "0" : value) + " " + symbol
|
||||
color: parseFloat(value) === 0.0 ? Style.current.danger : Style.current.secondaryText
|
||||
font.pixelSize: 13
|
||||
height: 18
|
||||
}
|
||||
}
|
||||
Select {
|
||||
id: select
|
||||
icon: "../app/img/walletIcon.svg"
|
||||
iconColor: selectedAccount.iconColor || Style.current.blue
|
||||
label: root.label
|
||||
selectedText: selectedAccount.name
|
||||
model: root.accounts
|
||||
|
||||
menu.delegate: menuItem
|
||||
menu.onOpened: {
|
||||
selectedAccountDetails.visible = false
|
||||
}
|
||||
menu.onClosed: {
|
||||
selectedAccountDetails.visible = true
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
id: selectedAccountDetails
|
||||
anchors.top: select.bottom
|
||||
anchors.topMargin: 8
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 2
|
||||
|
||||
StyledText {
|
||||
id: textSelectedAddress
|
||||
text: selectedAccount.address
|
||||
font.pixelSize: 12
|
||||
elide: Text.ElideMiddle
|
||||
height: 16
|
||||
width: 85
|
||||
color: Style.current.secondaryText
|
||||
}
|
||||
StyledText {
|
||||
id: separator
|
||||
text: "• "
|
||||
font.pixelSize: 12
|
||||
height: 16
|
||||
color: Style.current.secondaryText
|
||||
}
|
||||
StyledText {
|
||||
text: selectedAccount.fiatBalance + " " + walletModel.defaultCurrency.toUpperCase()
|
||||
font.pixelSize: 12
|
||||
height: 16
|
||||
color: Style.current.secondaryText
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: menuItem
|
||||
MenuItem {
|
||||
id: itemContainer
|
||||
property bool isFirstItem: index === 0
|
||||
property bool isLastItem: index === accounts.rowCount() - 1
|
||||
|
||||
Component.onCompleted: {
|
||||
if (root.selectedAccount.address === "") {
|
||||
root.selectedAccount = { address, name, iconColor, assets, fiatBalance }
|
||||
}
|
||||
}
|
||||
|
||||
height: accountName.height + 14 + accountAddress.height + 14
|
||||
SVGImage {
|
||||
id: iconImg
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Style.current.padding
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: select.iconWidth
|
||||
height: select.iconHeight
|
||||
sourceSize.height: select.iconHeight
|
||||
sourceSize.width: select.iconWidth
|
||||
fillMode: Image.PreserveAspectFit
|
||||
source: select.icon
|
||||
}
|
||||
ColorOverlay {
|
||||
anchors.fill: iconImg
|
||||
source: iconImg
|
||||
color: iconColor
|
||||
}
|
||||
Column {
|
||||
anchors.left: iconImg.right
|
||||
anchors.leftMargin: 14
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
StyledText {
|
||||
id: accountName
|
||||
text: name
|
||||
font.pixelSize: 15
|
||||
height: 22
|
||||
}
|
||||
|
||||
StyledText {
|
||||
id: accountAddress
|
||||
text: address
|
||||
elide: Text.ElideMiddle
|
||||
width: 80
|
||||
color: Style.current.secondaryText
|
||||
font.pixelSize: 12
|
||||
height: 16
|
||||
}
|
||||
}
|
||||
StyledText {
|
||||
anchors.right: fiatCurrencySymbol.left
|
||||
anchors.rightMargin: 4
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
font.pixelSize: 15
|
||||
height: 22
|
||||
text: fiatBalance
|
||||
}
|
||||
StyledText {
|
||||
id: fiatCurrencySymbol
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Style.current.padding
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
font.pixelSize: 15
|
||||
height: 22
|
||||
color: Style.current.secondaryText
|
||||
text: walletModel.defaultCurrency.toUpperCase()
|
||||
}
|
||||
background: Rectangle {
|
||||
color: itemContainer.highlighted ? Style.current.backgroundHover : Style.current.background
|
||||
radius: Style.current.radius
|
||||
|
||||
// cover bottom left/right corners with square corners
|
||||
Rectangle {
|
||||
visible: !isLastItem
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
height: parent.radius
|
||||
color: parent.color
|
||||
}
|
||||
|
||||
// cover top left/right corners with square corners
|
||||
Rectangle {
|
||||
visible: !isFirstItem
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
height: parent.radius
|
||||
color: parent.color
|
||||
}
|
||||
}
|
||||
MouseArea {
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
anchors.fill: itemContainer
|
||||
onClicked: {
|
||||
root.selectedAccount = { address, name, iconColor, assets, fiatBalance }
|
||||
select.menu.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
import QtQuick 2.13
|
||||
import QtQuick.Controls 2.13
|
||||
import "../imports"
|
||||
|
||||
Item {
|
||||
id: root
|
||||
property string selectedColor
|
||||
//% "Account color"
|
||||
property string label: qsTrId("account-color")
|
||||
property var model
|
||||
height: accountColorInput.height
|
||||
|
||||
Select {
|
||||
id: accountColorInput
|
||||
bgColor: selectedColor
|
||||
label: root.label
|
||||
model: root.model
|
||||
|
||||
menu.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] || Style.current.transparent
|
||||
radius: Style.current.radius
|
||||
|
||||
// cover bottom left/right corners with square corners
|
||||
Rectangle {
|
||||
visible: !isLastItem
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
height: parent.radius
|
||||
color: parent.color
|
||||
}
|
||||
|
||||
// cover top left/right corners with square corners
|
||||
Rectangle {
|
||||
visible: !isFirstItem
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
height: parent.radius
|
||||
color: parent.color
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,34 +9,32 @@ Item {
|
|||
readonly property bool hasLabel: label !== ""
|
||||
property color bgColor: Style.current.inputBackground
|
||||
readonly property int labelMargin: 7
|
||||
property var selectOptions
|
||||
property int customHeight: 44
|
||||
property var model
|
||||
property int customHeight: 56
|
||||
property string selectedText: ""
|
||||
property url icon: ""
|
||||
property int iconHeight: 24
|
||||
property int iconWidth: 24
|
||||
property int iconHeight: 12
|
||||
property int iconWidth: 12
|
||||
property color iconColor: Style.current.transparent
|
||||
property alias menu: selectMenu
|
||||
|
||||
readonly property bool hasIcon: icon.toString() !== ""
|
||||
|
||||
id: inputBox
|
||||
id: root
|
||||
height: inputRectangle.height + (hasLabel ? inputLabel.height + labelMargin : 0)
|
||||
anchors.right: parent.right
|
||||
anchors.left: parent.left
|
||||
|
||||
onSelectOptionsChanged: {
|
||||
selectMenu.setupMenuItems()
|
||||
}
|
||||
|
||||
StyledText {
|
||||
id: inputLabel
|
||||
text: inputBox.label
|
||||
text: root.label
|
||||
font.weight: Font.Medium
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 0
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 0
|
||||
font.pixelSize: 13
|
||||
height: 18
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
|
@ -44,20 +42,21 @@ Item {
|
|||
height: customHeight
|
||||
color: bgColor
|
||||
radius: Style.current.radius
|
||||
anchors.top: inputBox.hasLabel ? inputLabel.bottom : parent.top
|
||||
anchors.topMargin: inputBox.hasLabel ? inputBox.labelMargin : 0
|
||||
anchors.top: root.hasLabel ? inputLabel.bottom : parent.top
|
||||
anchors.topMargin: root.hasLabel ? root.labelMargin : 0
|
||||
anchors.right: parent.right
|
||||
anchors.left: parent.left
|
||||
|
||||
SVGImage {
|
||||
id: iconImg
|
||||
visible: root.hasIcon
|
||||
sourceSize.height: iconHeight
|
||||
sourceSize.width: iconWidth
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Style.current.smallPadding
|
||||
anchors.leftMargin: Style.current.padding
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
fillMode: Image.PreserveAspectFit
|
||||
source: inputBox.icon
|
||||
source: root.icon
|
||||
}
|
||||
ColorOverlay {
|
||||
anchors.fill: iconImg
|
||||
|
@ -67,12 +66,13 @@ Item {
|
|||
|
||||
StyledText {
|
||||
id: selectedTextField
|
||||
visible: inputBox.selectedText !== ""
|
||||
text: inputBox.selectedText
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: inputBox.hasIcon ? iconWidth + 20 : Style.current.padding
|
||||
visible: root.selectedText !== ""
|
||||
text: root.selectedText
|
||||
anchors.left: iconImg.right
|
||||
anchors.leftMargin: hasIcon ? 8 : 0
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
font.pixelSize: 15
|
||||
height: 22
|
||||
}
|
||||
|
||||
SVGImage {
|
||||
|
@ -88,80 +88,61 @@ Item {
|
|||
ColorOverlay {
|
||||
anchors.fill: caret
|
||||
source: caret
|
||||
color: Style.current.darkGrey
|
||||
}
|
||||
|
||||
Menu {
|
||||
property var items: []
|
||||
|
||||
id: selectMenu
|
||||
width: parent.width
|
||||
padding: 10
|
||||
background: Rectangle {
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
color: Style.current.inputBackground
|
||||
radius: Style.current.radius
|
||||
}
|
||||
|
||||
function setupMenuItems() {
|
||||
if (selectMenu.items.length) {
|
||||
// Remove old items
|
||||
selectMenu.items.forEach(function (item) {
|
||||
selectMenu.removeItem(item)
|
||||
})
|
||||
selectMenu.items = []
|
||||
}
|
||||
if (!selectOptions) {
|
||||
return
|
||||
}
|
||||
|
||||
selectOptions.forEach(function (element) {
|
||||
var item = menuItem.createObject(undefined, element)
|
||||
selectMenu.items.push(item)
|
||||
selectMenu.addItem(item)
|
||||
})
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
setupMenuItems()
|
||||
}
|
||||
|
||||
Component {
|
||||
id: menuItem
|
||||
MenuItem {
|
||||
id: itemContainer
|
||||
property var onClicked: function () {}
|
||||
property string label: ""
|
||||
property color bgColor: Style.current.transparent
|
||||
|
||||
height: itemText.height + 4
|
||||
width: parent ? parent.width : selectMenu.width
|
||||
|
||||
StyledText {
|
||||
id: itemText
|
||||
text: itemContainer.label
|
||||
anchors.left: parent ? parent.left : undefined
|
||||
anchors.leftMargin: 5
|
||||
anchors.verticalCenter: parent ? parent.verticalCenter : undefined
|
||||
}
|
||||
|
||||
onTriggered: function () {
|
||||
onClicked()
|
||||
}
|
||||
background: Rectangle {
|
||||
color: bgColor
|
||||
}
|
||||
}
|
||||
}
|
||||
color: Style.current.secondaryText
|
||||
}
|
||||
}
|
||||
|
||||
// create a drop shadow externally so that it is not clipped by the
|
||||
// rounded corners of the menu background
|
||||
Rectangle {
|
||||
width: selectMenu.width
|
||||
height: selectMenu.height
|
||||
x: selectMenu.x
|
||||
y: selectMenu.y
|
||||
visible: selectMenu.opened
|
||||
color: Style.current.background
|
||||
radius: Style.current.radius
|
||||
border.color: Style.current.border
|
||||
layer.enabled: true
|
||||
layer.effect: DropShadow {
|
||||
verticalOffset: 3
|
||||
radius: Style.current.radius
|
||||
samples: 15
|
||||
fast: true
|
||||
cached: true
|
||||
color: "#22000000"
|
||||
}
|
||||
}
|
||||
|
||||
Menu {
|
||||
id: selectMenu
|
||||
property var items: []
|
||||
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent
|
||||
width: parent.width
|
||||
background: Rectangle {
|
||||
// do not add a drop shadow effect here or it will be clipped
|
||||
radius: Style.current.radius
|
||||
color: Style.current.background
|
||||
}
|
||||
clip: true
|
||||
delegate: menuItem
|
||||
|
||||
Repeater {
|
||||
id: menuItems
|
||||
model: root.model
|
||||
delegate: selectMenu.delegate
|
||||
}
|
||||
}
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
anchors.fill: inputRectangle
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
selectMenu.open()
|
||||
if (selectMenu.opened) {
|
||||
selectMenu.close()
|
||||
} else {
|
||||
selectMenu.popup(inputRectangle.x, inputRectangle.y + inputRectangle.height + 8)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue