refactoring(NetworkSelectItemDelegate): Remove backend dependency and clean the API
This is the first step in refactoring the NetworkFilter, by cleaning the base component that handles the check states. This component supports multiple configurations: 1. Single selection with or without radio button 2. Multiple selection with or without checkbox 3. Automatic handling of the check state. The component will change the check state based on user clicks 4. Manual handling of the check state. The component will not change the check state, but offers a toggled signal and expects the user to change the check state based on external flows + Fix minor bugs
This commit is contained in:
parent
5bdda2e6d9
commit
429203cd66
|
@ -54,6 +54,8 @@ SplitView {
|
|||
sourceModel: NetworksModel.flatNetworks
|
||||
filters: ValueFilter { roleName: "isTest"; value: areTestNetworksEnabledCheckbox.checked }
|
||||
}
|
||||
|
||||
property var filteredFlatModel: networks
|
||||
property bool areTestNetworksEnabled: areTestNetworksEnabledCheckbox.checked
|
||||
function toggleNetwork(chainId) {
|
||||
}
|
||||
|
@ -72,6 +74,13 @@ SplitView {
|
|||
|
||||
function processPreferredSharingNetworkToggle(preferredSharingNetworksArray, network) {
|
||||
console.warn("processPreferredSharingNetworkToggle :: preferredSharingNetworksArray ::", preferredSharingNetworksArray, "network :: ", network)
|
||||
const chainId = network.chainId.toString()
|
||||
if (preferredSharingNetworksArray.includes(chainId)) {
|
||||
preferredSharingNetworksArray.splice(preferredSharingNetworksArray.indexOf(chainId), 1)
|
||||
} else {
|
||||
preferredSharingNetworksArray.push(chainId)
|
||||
}
|
||||
return [...preferredSharingNetworksArray]
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ import SortFilterProxyModel 0.2
|
|||
|
||||
import AppLayouts.stores 1.0
|
||||
import AppLayouts.Wallet.controls 1.0
|
||||
import AppLayouts.Wallet.views 1.0
|
||||
|
||||
SplitView {
|
||||
id: root
|
||||
|
@ -32,10 +33,10 @@ SplitView {
|
|||
roles: ["chainId", "layer", "chainName", "isTest", "isEnabled", "iconUrl", "shortName", "chainColor"]
|
||||
rolesOverride: [{ role: "enabledState", transform: (mD) => {
|
||||
return simulatedNimModel.areAllEnabled(sourceModel)
|
||||
? NetworkSelectItemDelegate.UxEnabledState.AllEnabled
|
||||
? NetworkSelectionView.UxEnabledState.AllEnabled
|
||||
: mD.isEnabled
|
||||
? NetworkSelectItemDelegate.UxEnabledState.Enabled
|
||||
: NetworkSelectItemDelegate.UxEnabledState.Disabled
|
||||
? NetworkSelectionView.UxEnabledState.Enabled
|
||||
: NetworkSelectionView.UxEnabledState.Disabled
|
||||
}
|
||||
}]
|
||||
|
||||
|
@ -47,11 +48,11 @@ SplitView {
|
|||
let allEnabled = true
|
||||
for (let i = 0; i < simulatedNimModel.count; i++) {
|
||||
const item = simulatedNimModel.get(i)
|
||||
if(item.enabledState === NetworkSelectItemDelegate.UxEnabledState.Enabled) {
|
||||
if(item.enabledState === NetworkSelectionView.UxEnabledState.Enabled) {
|
||||
if(item.chainId !== chainId) {
|
||||
chainIdOnlyEnabled = false
|
||||
}
|
||||
} else if(item.enabledState === NetworkSelectItemDelegate.UxEnabledState.Disabled) {
|
||||
} else if(item.enabledState === NetworkSelectionView.UxEnabledState.Disabled) {
|
||||
if(item.chainId !== chainId) {
|
||||
chainIdOnlyDisabled = false
|
||||
}
|
||||
|
@ -66,15 +67,15 @@ SplitView {
|
|||
for (let i = 0; i < simulatedNimModel.count; i++) {
|
||||
const item = simulatedNimModel.get(i)
|
||||
if(allEnabled) {
|
||||
simulatedNimModel.setProperty(i, "enabledState", item.chainId === chainId ? NetworkSelectItemDelegate.UxEnabledState.Enabled : NetworkSelectItemDelegate.UxEnabledState.Disabled)
|
||||
simulatedNimModel.setProperty(i, "enabledState", item.chainId === chainId ? NetworkSelectionView.UxEnabledState.Enabled : NetworkSelectionView.UxEnabledState.Disabled)
|
||||
} else if(chainIdOnlyEnabled || chainIdOnlyDisabled) {
|
||||
simulatedNimModel.setProperty(i, "enabledState", NetworkSelectItemDelegate.UxEnabledState.AllEnabled)
|
||||
simulatedNimModel.setProperty(i, "enabledState", NetworkSelectionView.UxEnabledState.AllEnabled)
|
||||
} else if(item.chainId === chainId) {
|
||||
simulatedNimModel.setProperty(i, "enabledState", item.enabledState === NetworkSelectItemDelegate.UxEnabledState.Enabled
|
||||
? NetworkSelectItemDelegate.UxEnabledState.Disabled
|
||||
: NetworkSelectItemDelegate.UxEnabledState.Enabled)
|
||||
simulatedNimModel.setProperty(i, "enabledState", item.enabledState === NetworkSelectionView.UxEnabledState.Enabled
|
||||
? NetworkSelectionView.UxEnabledState.Disabled
|
||||
: NetworkSelectionView.UxEnabledState.Enabled)
|
||||
}
|
||||
const haveEnabled = item.enabledState !== NetworkSelectItemDelegate.UxEnabledState.Disabled
|
||||
const haveEnabled = item.enabledState !== NetworkSelectionView.UxEnabledState.Disabled
|
||||
if(item.isEnabled !== haveEnabled) {
|
||||
simulatedNimModel.setProperty(i, "isEnabled", haveEnabled)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
import QtQml 2.15
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Utils 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Components 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
|
||||
import AppLayouts.Wallet.controls 1.0
|
||||
|
||||
import Models 1.0
|
||||
import Storybook 1.0
|
||||
|
||||
import SortFilterProxyModel 0.2
|
||||
|
||||
import utils 1.0
|
||||
|
||||
SplitView {
|
||||
id: root
|
||||
|
||||
Item {
|
||||
implicitWidth: delegate.width
|
||||
NetworkSelectItemDelegate {
|
||||
id: delegate
|
||||
title: "Ethereum"
|
||||
iconUrl: Style.svg("network/Network=Ethereum")
|
||||
showIndicator: true
|
||||
multiSelection: true
|
||||
checkState: checkStateSelector.checkState
|
||||
nextCheckState: checkState === Qt.Unchecked ? Qt.PartiallyChecked :
|
||||
checkState === Qt.PartiallyChecked ? Qt.Checked : Qt.Unchecked
|
||||
|
||||
onCheckStateChanged: {
|
||||
checkStateSelector.checkState = checkState
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Pane {
|
||||
id: pane
|
||||
SplitView.fillWidth: true
|
||||
ColumnLayout {
|
||||
CheckBox {
|
||||
text: "showIndicator"
|
||||
checked: delegate.showIndicator
|
||||
onCheckedChanged: {
|
||||
delegate.showIndicator = checked
|
||||
}
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
text: "multiSelection"
|
||||
checked: delegate.multiSelection
|
||||
onCheckedChanged: {
|
||||
delegate.multiSelection = checked
|
||||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
text: "title"
|
||||
}
|
||||
TextField {
|
||||
text: delegate.title
|
||||
onTextChanged: {
|
||||
delegate.title = text
|
||||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
text: "iconUrl"
|
||||
}
|
||||
TextField {
|
||||
text: delegate.iconUrl
|
||||
onTextChanged: {
|
||||
delegate.iconUrl = text
|
||||
}
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
id: checkStateSelector
|
||||
text: "checkedState"
|
||||
tristate: true
|
||||
checked: true
|
||||
onCheckStateChanged: {
|
||||
if(delegate.checkState !== checkState) {
|
||||
delegate.checkState = checkState
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// category: Controls
|
|
@ -10,6 +10,7 @@ import utils 1.0
|
|||
|
||||
import AppLayouts.Wallet.popups 1.0
|
||||
import AppLayouts.Wallet.controls 1.0
|
||||
import AppLayouts.Wallet.views 1.0
|
||||
import AppLayouts.stores 1.0
|
||||
|
||||
import Models 1.0
|
||||
|
@ -219,10 +220,10 @@ SplitView {
|
|||
roles: ["chainId", "layer", "chainName", "isTest", "isEnabled", "iconUrl", "shortName", "chainColor"]
|
||||
rolesOverride: [{ role: "enabledState", transform: (mD) => {
|
||||
return simulatedNimModel.areAllEnabled(sourceModel)
|
||||
? NetworkSelectItemDelegate.UxEnabledState.AllEnabled
|
||||
? NetworkSelectionView.UxEnabledState.AllEnabled
|
||||
: mD.isEnabled
|
||||
? NetworkSelectItemDelegate.UxEnabledState.Enabled
|
||||
: NetworkSelectItemDelegate.UxEnabledState.Disabled
|
||||
? NetworkSelectionView.UxEnabledState.Enabled
|
||||
: NetworkSelectionView.UxEnabledState.Disabled
|
||||
}
|
||||
}]
|
||||
|
||||
|
@ -234,11 +235,11 @@ SplitView {
|
|||
let allEnabled = true
|
||||
for (let i = 0; i < simulatedNimModel.count; i++) {
|
||||
const item = simulatedNimModel.get(i)
|
||||
if(item.enabledState === NetworkSelectItemDelegate.UxEnabledState.Enabled) {
|
||||
if(item.enabledState === NetworkSelectionView.UxEnabledState.Enabled) {
|
||||
if(item.chainId !== chainId) {
|
||||
chainIdOnlyEnabled = false
|
||||
}
|
||||
} else if(item.enabledState === NetworkSelectItemDelegate.UxEnabledState.Disabled) {
|
||||
} else if(item.enabledState === NetworkSelectionView.UxEnabledState.Disabled) {
|
||||
if(item.chainId !== chainId) {
|
||||
chainIdOnlyDisabled = false
|
||||
}
|
||||
|
@ -253,15 +254,15 @@ SplitView {
|
|||
for (let i = 0; i < simulatedNimModel.count; i++) {
|
||||
const item = simulatedNimModel.get(i)
|
||||
if(allEnabled) {
|
||||
simulatedNimModel.setProperty(i, "enabledState", item.chainId === chainId ? NetworkSelectItemDelegate.UxEnabledState.Enabled : NetworkSelectItemDelegate.UxEnabledState.Disabled)
|
||||
simulatedNimModel.setProperty(i, "enabledState", item.chainId === chainId ? NetworkSelectionView.UxEnabledState.Enabled : NetworkSelectionView.UxEnabledState.Disabled)
|
||||
} else if(chainIdOnlyEnabled || chainIdOnlyDisabled) {
|
||||
simulatedNimModel.setProperty(i, "enabledState", NetworkSelectItemDelegate.UxEnabledState.AllEnabled)
|
||||
simulatedNimModel.setProperty(i, "enabledState", NetworkSelectionView.UxEnabledState.AllEnabled)
|
||||
} else if(item.chainId === chainId) {
|
||||
simulatedNimModel.setProperty(i, "enabledState", item.enabledState === NetworkSelectItemDelegate.UxEnabledState.Enabled
|
||||
? NetworkSelectItemDelegate.UxEnabledState.Disabled
|
||||
:NetworkSelectItemDelegate.UxEnabledState.Enabled)
|
||||
simulatedNimModel.setProperty(i, "enabledState", item.enabledState === NetworkSelectionView.UxEnabledState.Enabled
|
||||
? NetworkSelectionView.UxEnabledState.Disabled
|
||||
:NetworkSelectionView.UxEnabledState.Enabled)
|
||||
}
|
||||
const haveEnabled = item.enabledState !== NetworkSelectItemDelegate.UxEnabledState.Disabled
|
||||
const haveEnabled = item.enabledState !== NetworkSelectionView.UxEnabledState.Disabled
|
||||
if(item.isEnabled !== haveEnabled) {
|
||||
simulatedNimModel.setProperty(i, "isEnabled", haveEnabled)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,260 @@
|
|||
import QtQuick 2.15
|
||||
import QtTest 1.15
|
||||
|
||||
import AppLayouts.Wallet.controls 1.0
|
||||
|
||||
import utils 1.0
|
||||
|
||||
|
||||
Item {
|
||||
id: root
|
||||
width: 600
|
||||
height: 400
|
||||
|
||||
Component {
|
||||
id: componentUnderTest
|
||||
NetworkSelectItemDelegate {
|
||||
anchors.centerIn: parent
|
||||
title: "Ethereum"
|
||||
iconUrl: Style.svg("network/Network=Ethereum")
|
||||
onToggled: root.onToggledHandler()
|
||||
}
|
||||
}
|
||||
|
||||
SignalSpy {
|
||||
id: toggledSpy
|
||||
target: controlUnderTest
|
||||
signalName: "toggled"
|
||||
}
|
||||
|
||||
SignalSpy {
|
||||
id: checkStateChangedSpy
|
||||
target: controlUnderTest
|
||||
signalName: "checkStateChanged"
|
||||
}
|
||||
|
||||
property NetworkSelectItemDelegate controlUnderTest: null
|
||||
property var onToggledHandler: function(){}
|
||||
property int externalCheckState: Qt.Unchecked
|
||||
|
||||
TestCase {
|
||||
name: "NetworkSelectItemDelegate"
|
||||
when: windowShown
|
||||
|
||||
function init() {
|
||||
controlUnderTest = createTemporaryObject(componentUnderTest, root)
|
||||
toggledSpy.clear()
|
||||
checkStateChangedSpy.clear()
|
||||
onToggledHandler = function() {}
|
||||
}
|
||||
|
||||
function test_basicGeometry() {
|
||||
verify(!!controlUnderTest)
|
||||
verify(controlUnderTest.width > 0)
|
||||
verify(controlUnderTest.height > 0)
|
||||
}
|
||||
|
||||
function test_title() {
|
||||
verify(!!controlUnderTest)
|
||||
compare(controlUnderTest.title, "Ethereum")
|
||||
controlUnderTest.title = "Polygon"
|
||||
compare(controlUnderTest.title, "Polygon")
|
||||
controlUnderTest.title = ""
|
||||
compare(controlUnderTest.title, "")
|
||||
controlUnderTest.title = "Ethereum"
|
||||
}
|
||||
|
||||
function test_icon() {
|
||||
verify(!!controlUnderTest)
|
||||
compare(controlUnderTest.iconUrl, Style.svg("network/Network=Ethereum"))
|
||||
compare(findChild(controlUnderTest, "statusRoundImage").image.source, Style.svg("network/Network=Ethereum"))
|
||||
controlUnderTest.iconUrl = Style.svg("network/Network=Polygon")
|
||||
compare(controlUnderTest.iconUrl, Style.svg("network/Network=Polygon"))
|
||||
compare(findChild(controlUnderTest, "statusRoundImage").image.source, Style.svg("network/Network=Polygon"))
|
||||
}
|
||||
|
||||
function test_indicatorConfig() {
|
||||
verify(!!controlUnderTest)
|
||||
verify(!!findChild(controlUnderTest, "networkSelectionRadioButton_Ethereum"))
|
||||
verify(!findChild(controlUnderTest, "networkSelectionCheckbox_Ethereum"))
|
||||
compare(controlUnderTest.showIndicator, true)
|
||||
compare(controlUnderTest.multiSelection, false)
|
||||
|
||||
//changing to multiselect -> indicator switches to checkbox
|
||||
controlUnderTest.multiSelection = true
|
||||
waitForRendering(controlUnderTest)
|
||||
waitForItemPolished(controlUnderTest)
|
||||
verify(!!findChild(controlUnderTest, "networkSelectionCheckbox_Ethereum"))
|
||||
verify(!findChild(controlUnderTest, "networkSelectionRadioButton_Ethereum"))
|
||||
|
||||
//changing removing indicator
|
||||
controlUnderTest.showIndicator = false
|
||||
waitForRendering(controlUnderTest)
|
||||
waitForItemPolished(controlUnderTest)
|
||||
verify(!findChild(controlUnderTest, "networkSelectionCheckbox_Ethereum"))
|
||||
verify(!findChild(controlUnderTest, "networkSelectionRadioButton_Ethereum"))
|
||||
}
|
||||
|
||||
function test_toggleByClick() {
|
||||
verify(!!controlUnderTest)
|
||||
mouseClick(controlUnderTest)
|
||||
tryCompare(toggledSpy, "count", 1)
|
||||
|
||||
const image = findChild(controlUnderTest, "statusRoundImage")
|
||||
mouseClick(image)
|
||||
tryCompare(toggledSpy, "count", 2)
|
||||
|
||||
const radioButton = findChild(controlUnderTest, "networkSelectionRadioButton_Ethereum")
|
||||
mouseClick(radioButton)
|
||||
tryCompare(toggledSpy, "count", 3)
|
||||
|
||||
controlUnderTest.multiSelection = true
|
||||
waitForItemPolished(controlUnderTest)
|
||||
const checkBox = findChild(controlUnderTest, "networkSelectionCheckbox_Ethereum")
|
||||
mouseClick(checkBox)
|
||||
tryCompare(toggledSpy, "count", 4)
|
||||
}
|
||||
|
||||
function test_autoCheckStateChanges() {
|
||||
verify(!!controlUnderTest)
|
||||
compare(controlUnderTest.checkState, Qt.Unchecked)
|
||||
mouseClick(controlUnderTest)
|
||||
compare(controlUnderTest.checkState, Qt.Checked)
|
||||
mouseClick(controlUnderTest)
|
||||
compare(controlUnderTest.checkState, Qt.Unchecked)
|
||||
const radioButton = findChild(controlUnderTest, "networkSelectionRadioButton_Ethereum")
|
||||
mouseClick(radioButton)
|
||||
compare(controlUnderTest.checkState, Qt.Checked)
|
||||
mouseClick(radioButton)
|
||||
compare(controlUnderTest.checkState, Qt.Unchecked)
|
||||
|
||||
controlUnderTest.multiSelection = true
|
||||
waitForItemPolished(controlUnderTest)
|
||||
compare(controlUnderTest.checkState, Qt.Unchecked)
|
||||
const checkBox = findChild(controlUnderTest, "networkSelectionCheckbox_Ethereum")
|
||||
mouseClick(checkBox)
|
||||
waitForItemPolished(controlUnderTest)
|
||||
compare(controlUnderTest.checkState, Qt.Checked)
|
||||
mouseClick(checkBox)
|
||||
compare(controlUnderTest.checkState, Qt.Unchecked)
|
||||
mouseClick(controlUnderTest)
|
||||
compare(controlUnderTest.checkState, Qt.Checked)
|
||||
mouseClick(controlUnderTest)
|
||||
compare(controlUnderTest.checkState, Qt.Unchecked)
|
||||
}
|
||||
|
||||
function test_manualCheckStateChanges() {
|
||||
verify(!!controlUnderTest)
|
||||
// checkState is not bound to nextCheckState => no automatic check changes
|
||||
controlUnderTest.nextCheckState = Qt.binding(() => controlUnderTest.checkState)
|
||||
compare(controlUnderTest.checkState, Qt.Unchecked)
|
||||
|
||||
mouseClick(controlUnderTest)
|
||||
compare(controlUnderTest.checkState, Qt.Unchecked)
|
||||
let radioButton = findChild(controlUnderTest, "networkSelectionRadioButton_Ethereum")
|
||||
mouseClick(radioButton)
|
||||
compare(controlUnderTest.checkState, Qt.Unchecked)
|
||||
|
||||
controlUnderTest.multiSelection = true
|
||||
waitForItemPolished(controlUnderTest)
|
||||
compare(controlUnderTest.checkState, Qt.Unchecked)
|
||||
let checkBox = findChild(controlUnderTest, "networkSelectionCheckbox_Ethereum")
|
||||
mouseClick(checkBox)
|
||||
compare(controlUnderTest.checkState, Qt.Unchecked)
|
||||
|
||||
controlUnderTest.multiSelection = false
|
||||
waitForItemPolished(controlUnderTest)
|
||||
compare(controlUnderTest.checkState, Qt.Unchecked)
|
||||
|
||||
root.onToggledHandler = function() {
|
||||
controlUnderTest.checkState = controlUnderTest.checkState === Qt.Checked ? Qt.Unchecked : Qt.Checked
|
||||
}
|
||||
|
||||
mouseClick(controlUnderTest)
|
||||
compare(controlUnderTest.checkState, Qt.Checked)
|
||||
|
||||
radioButton = findChild(controlUnderTest, "networkSelectionRadioButton_Ethereum")
|
||||
mouseClick(radioButton)
|
||||
compare(controlUnderTest.checkState, Qt.Unchecked)
|
||||
|
||||
controlUnderTest.multiSelection = true
|
||||
root.onToggledHandler = function() {
|
||||
controlUnderTest.checkState = controlUnderTest.checkState === Qt.Unchecked ? Qt.PartiallyChecked :
|
||||
controlUnderTest.checkState === Qt.Checked ? Qt.Unchecked : Qt.Checked
|
||||
}
|
||||
|
||||
mouseClick(controlUnderTest)
|
||||
compare(controlUnderTest.checkState, Qt.PartiallyChecked)
|
||||
mouseClick(controlUnderTest)
|
||||
compare(controlUnderTest.checkState, Qt.Checked)
|
||||
mouseClick(controlUnderTest)
|
||||
compare(controlUnderTest.checkState, Qt.Unchecked)
|
||||
|
||||
checkBox = findChild(controlUnderTest, "networkSelectionCheckbox_Ethereum")
|
||||
mouseClick(checkBox)
|
||||
compare(controlUnderTest.checkState, Qt.PartiallyChecked)
|
||||
mouseClick(checkBox)
|
||||
compare(controlUnderTest.checkState, Qt.Checked)
|
||||
mouseClick(checkBox)
|
||||
compare(controlUnderTest.checkState, Qt.Unchecked)
|
||||
}
|
||||
|
||||
function test_checkStateBindings() {
|
||||
verify(!!controlUnderTest)
|
||||
compare(controlUnderTest.checkState, Qt.Unchecked)
|
||||
compare(root.externalCheckState, Qt.Unchecked)
|
||||
|
||||
controlUnderTest.checkState = Qt.binding(() => root.externalCheckState)
|
||||
compare(controlUnderTest.checkState, root.externalCheckState)
|
||||
tryCompare(checkStateChangedSpy, "count", 0)
|
||||
|
||||
root.externalCheckState = Qt.Checked
|
||||
compare(controlUnderTest.checkState, Qt.Checked)
|
||||
tryCompare(checkStateChangedSpy, "count", 1)
|
||||
|
||||
root.externalCheckState = Qt.Unchecked
|
||||
compare(controlUnderTest.checkState, Qt.Unchecked)
|
||||
tryCompare(checkStateChangedSpy, "count", 2)
|
||||
}
|
||||
|
||||
function test_interactiveConfig() {
|
||||
verify(!!controlUnderTest)
|
||||
compare(controlUnderTest.interactive, true)
|
||||
controlUnderTest.interactive = false
|
||||
compare(controlUnderTest.checkState, Qt.Unchecked)
|
||||
|
||||
mouseClick(controlUnderTest)
|
||||
compare(controlUnderTest.checkState, Qt.Unchecked)
|
||||
|
||||
let radioButton = findChild(controlUnderTest, "networkSelectionRadioButton_Ethereum")
|
||||
mouseClick(radioButton)
|
||||
compare(controlUnderTest.checkState, Qt.Unchecked)
|
||||
|
||||
controlUnderTest.multiSelection = true
|
||||
waitForItemPolished(controlUnderTest)
|
||||
|
||||
mouseClick(controlUnderTest)
|
||||
compare(controlUnderTest.checkState, Qt.Unchecked)
|
||||
|
||||
let checkBox = findChild(controlUnderTest, "networkSelectionCheckbox_Ethereum")
|
||||
mouseClick(checkBox)
|
||||
compare(controlUnderTest.checkState, Qt.Unchecked)
|
||||
|
||||
controlUnderTest.showIndicator = false
|
||||
|
||||
mouseClick(controlUnderTest)
|
||||
compare(controlUnderTest.checkState, Qt.Unchecked)
|
||||
|
||||
mouseMove(controlUnderTest, controlUnderTest.width / 2, controlUnderTest.height / 2)
|
||||
waitForRendering(controlUnderTest)
|
||||
waitForItemPolished(controlUnderTest)
|
||||
compare(controlUnderTest.sensor.containsMouse, true)
|
||||
|
||||
// manual selection works
|
||||
controlUnderTest.checkState = Qt.Checked
|
||||
compare(controlUnderTest.checkState, Qt.Checked)
|
||||
controlUnderTest.checkState = Qt.Unchecked
|
||||
compare(controlUnderTest.checkState, Qt.Unchecked)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -50,6 +50,7 @@ Loader {
|
|||
|
||||
StatusRoundedImage {
|
||||
id: statusRoundImage
|
||||
objectName: "statusRoundImage"
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
image.source: root.asset.isImage ? root.asset.name : ""
|
||||
|
@ -80,6 +81,7 @@ Loader {
|
|||
id: roundedIcon
|
||||
|
||||
StatusRoundIcon {
|
||||
objectName: "statusRoundIcon"
|
||||
asset.bgRadius: root.asset.bgRadius
|
||||
asset.bgWidth: root.asset.bgWidth
|
||||
asset.bgHeight: root.asset.bgHeight
|
||||
|
|
|
@ -59,7 +59,8 @@ StatusComboBox {
|
|||
root.multiSelection
|
||||
NetworkModelHelpers.getChainIconUrl(root.flatNetworks, d.currentIndex)
|
||||
}
|
||||
readonly property bool allSelected: enabledFlatNetworks.count === root.flatNetworks.count
|
||||
readonly property bool allSelected: root.preferredNetworksMode ? root.preferredSharingNetworks.length === root.flatNetworks.count :
|
||||
enabledFlatNetworks.count === root.flatNetworks.count
|
||||
readonly property bool noneSelected: enabledFlatNetworks.count === 0
|
||||
|
||||
// Persist selection between selectPopupLoader reloads
|
||||
|
@ -67,7 +68,14 @@ StatusComboBox {
|
|||
|
||||
property SortFilterProxyModel enabledFlatNetworks: SortFilterProxyModel {
|
||||
sourceModel: root.flatNetworks
|
||||
filters: ValueFilter { roleName: "isEnabled"; value: true; enabled: !root.preferredNetworksMode }
|
||||
filters: [
|
||||
ValueFilter { roleName: "isEnabled"; value: true; enabled: !root.preferredNetworksMode },
|
||||
FastExpressionFilter {
|
||||
expression: root.preferredSharingNetworks.includes(chainId.toString())
|
||||
expectedRoles: ["chainId"]
|
||||
enabled: root.preferredNetworksMode
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -128,7 +136,7 @@ StatusComboBox {
|
|||
visible: (!d.allSelected || !root.showAllSelectedText) && chainRepeater.count > 0
|
||||
Repeater {
|
||||
id: chainRepeater
|
||||
model: root.preferredNetworksMode ? root.flatNetworks: root.multiSelection ? d.enabledFlatNetworks: []
|
||||
model: root.multiSelection ? d.enabledFlatNetworks: []
|
||||
delegate: StatusRoundedImage {
|
||||
id: delegateItem
|
||||
width: 24
|
||||
|
|
|
@ -1,96 +1,119 @@
|
|||
import QtQuick 2.15
|
||||
import QtQml 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtGraphicalEffects 1.15
|
||||
|
||||
import StatusQ.Components 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
|
||||
import utils 1.0
|
||||
|
||||
import "../stores/NetworkSelectPopup"
|
||||
|
||||
StatusListItem {
|
||||
id: root
|
||||
|
||||
property var networkModel: null
|
||||
property var singleSelection
|
||||
property var radioButtonGroup
|
||||
property bool useEnabledRole: true
|
||||
property bool showCheckboxes: true
|
||||
property bool showRadioButtons: true
|
||||
// input/output property
|
||||
property int checkState: Qt.Unchecked
|
||||
|
||||
// Needed for preferred sharing networks
|
||||
property bool preferredNetworksMode: false
|
||||
property var preferredSharingNetworks: []
|
||||
property bool allChecked: true
|
||||
//input property
|
||||
// Defines the next state of the checkbox when clicked
|
||||
// By default, it toggles between checked and unchecked
|
||||
property int nextCheckState: checkState === Qt.Checked ? Qt.Unchecked : Qt.Checked
|
||||
|
||||
signal toggleNetwork(var network, var model, int index)
|
||||
required property string iconUrl
|
||||
property bool showIndicator: true
|
||||
property bool multiSelection: false
|
||||
property bool interactive: true
|
||||
|
||||
/// Mirrors Nim's UxEnabledState enum from networks/item.nim
|
||||
enum UxEnabledState {
|
||||
Enabled,
|
||||
AllEnabled,
|
||||
Disabled
|
||||
}
|
||||
// output signal
|
||||
// Emitted when the checkbox is clicked
|
||||
// This signal is useful when the check state needs to change
|
||||
// only after processing the toggle event E.g backend call
|
||||
signal toggled
|
||||
|
||||
objectName: model.chainName
|
||||
title: model.chainName
|
||||
objectName: root.title
|
||||
asset.height: 24
|
||||
asset.width: 24
|
||||
asset.isImage: true
|
||||
asset.name: Style.svg(model.iconUrl)
|
||||
asset.name: root.iconUrl
|
||||
onClicked: {
|
||||
if(!root.singleSelection.enabled) {
|
||||
checkBox.nextCheckState()
|
||||
} else if(!radioButton.checked) { // Don't allow uncheck
|
||||
root.toggleNetwork(({chainId: model.chainId, chainName: model.chainName, iconUrl: model.iconUrl}), root.networkModel, model.index)
|
||||
d.toggled()
|
||||
}
|
||||
|
||||
leftPadding: 16
|
||||
rightPadding: 16
|
||||
statusListItemTitleArea.anchors.leftMargin: 12
|
||||
highlighted: (d.checkState !== Qt.Unchecked && !showIndicator)
|
||||
|
||||
Binding on bgColor {
|
||||
when: highlighted && !root.sensor.containsMouse
|
||||
value: root.interactive ? Theme.palette.baseColor4 : Theme.palette.primaryColor3
|
||||
restoreMode: Binding.RestoreBindingOrValue
|
||||
}
|
||||
|
||||
onCheckStateChanged: {
|
||||
if (checkState !== d.checkState) {
|
||||
d.checkState = checkState
|
||||
}
|
||||
}
|
||||
|
||||
leftPadding: 12
|
||||
rightPadding: 0
|
||||
statusListItemTitleArea.anchors.leftMargin: 12
|
||||
|
||||
components: [
|
||||
StatusCheckBox {
|
||||
id: checkBox
|
||||
objectName: "networkSelectionCheckbox_" + model.chainName
|
||||
tristate: true
|
||||
visible: !root.singleSelection.enabled && root.showCheckboxes
|
||||
|
||||
checkState: {
|
||||
if(root.preferredNetworksMode) {
|
||||
return root.allChecked ? Qt.PartiallyChecked : preferredSharingNetworks.includes(model.chainId.toString()) ? Qt.Checked : Qt.Unchecked
|
||||
}
|
||||
else if(root.useEnabledRole) {
|
||||
return model.isEnabled ? Qt.Checked : Qt.Unchecked
|
||||
} else if (model.enabledState === NetworkSelectItemDelegate.UxEnabledState.Enabled) {
|
||||
return Qt.Checked
|
||||
} else {
|
||||
if( model.enabledState === NetworkSelectItemDelegate.UxEnabledState.AllEnabled) {
|
||||
return Qt.PartiallyChecked
|
||||
} else {
|
||||
return Qt.Unchecked
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nextCheckState: () => {
|
||||
Qt.callLater(root.toggleNetwork, model, root.networkModel, model.index)
|
||||
return Qt.PartiallyChecked
|
||||
}
|
||||
},
|
||||
StatusRadioButton {
|
||||
id: radioButton
|
||||
visible: root.singleSelection.enabled && root.showRadioButtons
|
||||
size: StatusRadioButton.Size.Large
|
||||
ButtonGroup.group: root.radioButtonGroup
|
||||
checked: root.singleSelection.currentModel === root.networkModel && root.singleSelection.currentIndex === model.index
|
||||
|
||||
onToggled: {
|
||||
if(checked) {
|
||||
root.toggleNetwork(({chainId: model.chainId, chainName: model.chainName, iconUrl: model.iconUrl}), root.networkModel, model.index)
|
||||
}
|
||||
}
|
||||
Loader {
|
||||
id: indicatorLoader
|
||||
sourceComponent: root.multiSelection ? checkBoxComponent : radioButtonComponent
|
||||
active: root.showIndicator
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
Component {
|
||||
id: checkBoxComponent
|
||||
StatusCheckBox {
|
||||
id: checkBox
|
||||
|
||||
objectName: "networkSelectionCheckbox_" + root.title
|
||||
checkState: d.checkState
|
||||
tristate: true
|
||||
nextCheckState: () => d.checkState
|
||||
enabled: root.interactive
|
||||
|
||||
onClicked: {
|
||||
d.toggled()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: radioButtonComponent
|
||||
StatusRadioButton {
|
||||
id: radioButton
|
||||
objectName: "networkSelectionRadioButton_" + root.title
|
||||
size: StatusRadioButton.Size.Large
|
||||
checked: d.checkState !== Qt.Unchecked
|
||||
enabled: root.interactive
|
||||
|
||||
onClicked: {
|
||||
d.toggled()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
property int checkState: root.checkState
|
||||
|
||||
function toggled() {
|
||||
if (!root.interactive) {
|
||||
return
|
||||
}
|
||||
d.checkState = root.nextCheckState
|
||||
root.toggled()
|
||||
}
|
||||
|
||||
onCheckStateChanged: {
|
||||
if (checkState !== root.checkState) {
|
||||
root.checkState = checkState
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ StatusDialog {
|
|||
preferredSharingNetworks: root.preferredSharingNetworks
|
||||
useEnabledRole: root.useEnabledRole
|
||||
singleSelection: d.singleSelection
|
||||
onToggleNetwork: {
|
||||
onToggleNetwork: (network, index) => {
|
||||
root.toggleNetwork(network, index)
|
||||
if(d.singleSelection.enabled)
|
||||
close()
|
||||
|
|
|
@ -136,6 +136,13 @@ StatusDialog {
|
|||
networkFilter.setChain(root.swapInputParamsForm.selectedNetworkChainId)
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: root.swapInputParamsForm
|
||||
function onSelectedNetworkChainIdChanged() {
|
||||
networkFilter.setChain(root.swapInputParamsForm.selectedNetworkChainId)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
|
||||
import StatusQ 0.1
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
|
||||
|
@ -24,21 +25,71 @@ StatusListView {
|
|||
|
||||
signal toggleNetwork(var network, int index)
|
||||
|
||||
/// Mirrors Nim's UxEnabledState enum from networks/item.nim
|
||||
enum UxEnabledState {
|
||||
Enabled,
|
||||
AllEnabled,
|
||||
Disabled
|
||||
}
|
||||
|
||||
model: root.flatNetworks
|
||||
|
||||
delegate: NetworkSelectItemDelegate {
|
||||
id: delegateItem
|
||||
|
||||
required property var model
|
||||
readonly property int multiSelectCheckState: {
|
||||
if(root.preferredNetworksMode) {
|
||||
return root.preferredSharingNetworks.length === root.count ?
|
||||
Qt.PartiallyChecked :
|
||||
root.preferredSharingNetworks.includes(model.chainId.toString()) ? Qt.Checked : Qt.Unchecked
|
||||
}
|
||||
else if(root.useEnabledRole) {
|
||||
return model.isEnabled ? Qt.Checked : Qt.Unchecked
|
||||
} else if (model.enabledState === NetworkSelectionView.UxEnabledState.Enabled) {
|
||||
return Qt.Checked
|
||||
} else {
|
||||
if( model.enabledState === NetworkSelectionView.UxEnabledState.AllEnabled) {
|
||||
return Qt.PartiallyChecked
|
||||
} else {
|
||||
return Qt.Unchecked
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
readonly property int singleSelectCheckState: {
|
||||
if (root.singleSelection.currentModel === root.model && root.singleSelection.currentIndex === model.index)
|
||||
return Qt.Checked
|
||||
return Qt.Unchecked
|
||||
}
|
||||
|
||||
|
||||
implicitHeight: 48
|
||||
implicitWidth: root.width
|
||||
radioButtonGroup: radioBtnGroup
|
||||
networkModel: root.model
|
||||
useEnabledRole: root.useEnabledRole
|
||||
singleSelection: root.singleSelection
|
||||
onToggleNetwork: (network, model, index) => root.toggleNetwork(network, index)
|
||||
preferredNetworksMode: root.preferredNetworksMode
|
||||
preferredSharingNetworks: root.preferredSharingNetworks
|
||||
allChecked: root.preferredSharingNetworks.length === root.count
|
||||
showCheckboxes: root.showCheckboxes
|
||||
showRadioButtons: root.showRadioButtons
|
||||
title: model.chainName
|
||||
iconUrl: Style.svg(model.iconUrl)
|
||||
showIndicator: (multiSelection && root.showCheckboxes) || (!multiSelection && root.showRadioButtons)
|
||||
multiSelection: !root.singleSelection.enabled
|
||||
|
||||
Binding on checkState {
|
||||
when: root.singleSelection.enabled
|
||||
value: singleSelectCheckState
|
||||
}
|
||||
|
||||
Binding on checkState {
|
||||
when: !root.singleSelection.enabled
|
||||
value: multiSelectCheckState
|
||||
}
|
||||
|
||||
nextCheckState: checkState
|
||||
onToggled: {
|
||||
if(!root.singleSelection.enabled) {
|
||||
Qt.callLater(root.toggleNetwork, delegateItem.model, delegateItem.model.index)
|
||||
} else if(!checkState !== Qt.Checked) { // Don't allow uncheck
|
||||
checkState = checkState === Qt.Checked ? Qt.Unchecked : Qt.Checked
|
||||
root.toggleNetwork(delegateItem.model, model.index)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
section {
|
||||
|
@ -62,8 +113,4 @@ StatusListView {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
ButtonGroup {
|
||||
id: radioBtnGroup
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
AssetsDetailView 1.0 AssetsDetailView.qml
|
||||
CollectiblesView 1.0 CollectiblesView.qml
|
||||
NetworkSelectionView 1.0 NetworkSelectionView.qml
|
||||
SavedAddresses 1.0 SavedAddresses.qml
|
||||
TokenSelectorAssetDelegate 1.0 TokenSelectorAssetDelegate.qml
|
||||
TokenSelectorView 1.0 TokenSelectorView.qml
|
||||
|
|
Loading…
Reference in New Issue