chore(StatusListPicker): remove imperative updateInputListModel

closes: status-im/status-desktop#6500
This commit is contained in:
Patryk Osmaczko 2022-07-22 13:37:40 +02:00 committed by Michał Cieślak
parent 56d42bb229
commit 8fa740b12a
2 changed files with 51 additions and 49 deletions

View File

@ -34,6 +34,7 @@ GridLayout {
inputList: Models.languageNoImagePickerModel inputList: Models.languageNoImagePickerModel
placeholderSearchText: qsTr("Search Languages") placeholderSearchText: qsTr("Search Languages")
menuAlignment: StatusListPicker.MenuAlignment.Center menuAlignment: StatusListPicker.MenuAlignment.Center
multiSelection: true
} }
StatusListPicker { StatusListPicker {
@ -60,7 +61,7 @@ GridLayout {
width: 500 width: 500
text: "4 different configurations for the `StatusListPicker` component:\n text: "4 different configurations for the `StatusListPicker` component:\n
* Single selection. \n * Single selection. \n
* Single selection but dynamically changed to multiple selection (model provides multiple selected items).\n * Multiple selection without images.\n
* Multiple selection.\n * Multiple selection.\n
* Multiple selection and displayed name is the symbol + shortName\n" * Multiple selection and displayed name is the symbol + shortName\n"
color: Theme.palette.baseColor1 color: Theme.palette.baseColor1

View File

@ -17,7 +17,7 @@ import SortFilterProxyModel 0.2
The \c StatusListPicker is populated with a data model. The data model is commonly a JavaScript array or a ListModel object. The \c StatusListPicker is populated with a data model. The data model is commonly a JavaScript array or a ListModel object.
StatusListPicker can be made as a single or multiple options picker by setting its StatusListPicker::multiSelection property properly or will be auto-set if the model contains / provides more than one selected items. StatusListPicker can be made as a single or multiple options picker by setting its StatusListPicker::multiSelection property properly.
The StatusPickerButton text holds the text of the current item selected in the list picker. If there is more than one item selected, a string composed will be displayed. The StatusPickerButton text holds the text of the current item selected in the list picker. If there is more than one item selected, a string composed will be displayed.
The drop-down list incorporates a searcher by the following model roles: `name` or / and `shortName`. The drop-down list incorporates a searcher by the following model roles: `name` or / and `shortName`.
@ -46,6 +46,7 @@ Item {
This property holds the data that will be populated in the list picker. This property holds the data that will be populated in the list picker.
NOTE: This model property should not change so it is an in / out property where the selected role will be dynamically changed according to user actions. NOTE: This model property should not change so it is an in / out property where the selected role will be dynamically changed according to user actions.
NOTE: Be sure provided model is compatible with StatusListPicker::multiSelection property.
Here an example of the model roles expected: Here an example of the model roles expected:
\qml \qml
@ -154,56 +155,64 @@ Item {
QtObject { QtObject {
id: d id: d
function formatSymbolShortNameText(symbol, shortName) { readonly property SortFilterProxyModel selectedItems: SortFilterProxyModel {
var formattedText = "" sourceModel: root.inputList
if(root.printSymbol && symbol) // NOTE: ValueFilter would crash if source model does not contain given role
formattedText = symbol + shortName // FIXME: use ValueFilter when its fixed
else filters: ExpressionFilter {
formattedText = shortName expression: model.selected
return formattedText }
} }
function getSelectedItemsText() { readonly property string selectedItemsText: {
function formatSymbolShortNameText(symbol, shortName) {
var formattedText = ""
if(root.printSymbol && symbol)
formattedText = symbol + shortName
else
formattedText = shortName
return formattedText
}
var res = "" var res = ""
for(var i = 0; i < root.inputList.count; i++) { for(var i = 0; i < selectedItems.count; i++) {
var item = root.inputList.get(i) var item = selectedItems.get(i)
if(item.selected) { if(res != "")
if(res != "") res += ", "
res += ", " res += formatSymbolShortNameText(item.symbol, item.shortName)
res += d.formatSymbolShortNameText(item.symbol, item.shortName)
}
} }
return res return res
} }
// Used to update the base input list model with the new selected property
function updateInputListModel(key, selected, isSingleSelection) {
// If it is a single selection we must ensure that when a new key is selected others are cleared.
// It must be done manually because as there is the option of filterning, the model visualized changes
// and it could be possible to have a filtered list without an element selected (but in the base model
// it is) so, the binding to not selected will not be executed, as in the current filtered model
// there are no changes to update, just only the selected one.
for(var i = 0; i < root.inputList.count; i++) {
if(root.inputList.get(i).key === key) {
root.inputList.get(i).selected = selected
}
else if(isSingleSelection && selected) {
// Clear all the list
root.inputList.get(i).selected = false
}
}
}
} }
width: 110 width: 110
height: 38 height: 38
Repeater {
// Used to update the base input list model with the new selected property
// If it is a single selection we must ensure that when a new key is selected others are cleared.
id: itemsSelectorHelper
signal selectItem(var key, bool checked)
model: root.inputList
delegate: Item {
Connections {
target: itemsSelectorHelper
function onSelectItem(key, checked) {
if (model.key === key) model.selected = checked
else if (!root.multiSelection && checked) model.selected = false
}
}
}
}
StatusPickerButton { StatusPickerButton {
id: btn id: btn
anchors.fill: parent anchors.fill: parent
bgColor: Theme.palette.primaryColor3 bgColor: Theme.palette.primaryColor3
contentColor: Theme.palette.primaryColor1 contentColor: Theme.palette.primaryColor1
text: picker.selectedItemsText text: d.selectedItemsText
font.pixelSize: 13 font.pixelSize: 13
type: StatusPickerButton.Type.Down type: StatusPickerButton.Type.Down
@ -219,8 +228,6 @@ Item {
Rectangle { Rectangle {
id: picker id: picker
property string selectedItemsText: ""
width: content.itemWidth width: content.itemWidth
height: Math.min(content.contentHeight + content.anchors.topMargin + content.anchors.bottomMargin, root.maxPickerHeight) height: Math.min(content.contentHeight + content.anchors.topMargin + content.anchors.bottomMargin, root.maxPickerHeight)
anchors.left: root.menuAlignment === StatusListPicker.MenuAlignment.Left ? btn.left : undefined anchors.left: root.menuAlignment === StatusListPicker.MenuAlignment.Left ? btn.left : undefined
@ -243,7 +250,7 @@ Item {
} }
ListView { ListView {
id: content id: content
property int itemHeight: 40 property int itemHeight: 40
property int itemWidth: 360 property int itemWidth: 360
@ -254,8 +261,8 @@ Item {
filters: ExpressionFilter { filters: ExpressionFilter {
expression: { expression: {
root.searchText // ensure expression is reevaluated when searchText changes root.searchText // ensure expression is reevaluated when searchText changes
return model.name.toLowerCase().startsWith(root.searchText.toLowerCase()) || return model.name.toLowerCase().includes(root.searchText.toLowerCase()) ||
model.shortName.toLowerCase().startsWith(root.searchText.toLowerCase()) model.shortName.toLowerCase().includes(root.searchText.toLowerCase())
} }
} }
} }
@ -307,14 +314,8 @@ Item {
radioGroup: radioBtnGroup radioGroup: radioBtnGroup
onCheckedChanged: { onCheckedChanged: {
d.updateInputListModel(model.key, checked, selectorType === StatusItemPicker.SelectorType.RadioButton) if (checked !== model.selected) {
if(selectorType === StatusItemPicker.SelectorType.RadioButton && checked) { itemsSelectorHelper.selectItem(model.key, checked)
// Update selected item text
picker.selectedItemsText = d.formatSymbolShortNameText(model.symbol, model.shortName)
}
else {
// Update selected items text (multiple selection, text chain).
picker.selectedItemsText = d.getSelectedItemsText()
} }
// Used to notify selected property changes in the specific item picker. // Used to notify selected property changes in the specific item picker.