Skip to content

Commit

Permalink
chore(StatusListPicker): remove imperative updateInputListModel
Browse files Browse the repository at this point in the history
  • Loading branch information
osmaczko authored and micieslak committed Sep 21, 2022
1 parent 56d42bb commit 8fa740b
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 47 deletions.
3 changes: 2 additions & 1 deletion ui/StatusQ/sandbox/pages/StatusListPickerPage.qml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ GridLayout {
inputList: Models.languageNoImagePickerModel
placeholderSearchText: qsTr("Search Languages")
menuAlignment: StatusListPicker.MenuAlignment.Center
multiSelection: true
}

StatusListPicker {
Expand All @@ -60,7 +61,7 @@ GridLayout {
width: 500
text: "4 different configurations for the `StatusListPicker` component:\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 and displayed name is the symbol + shortName\n"
color: Theme.palette.baseColor1
Expand Down
93 changes: 47 additions & 46 deletions ui/StatusQ/src/StatusQ/Components/StatusListPicker.qml
Original file line number Diff line number Diff line change
Expand Up @@ -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.
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 drop-down list incorporates a searcher by the following model roles: `name` or / and `shortName`.
Expand Down Expand Up @@ -46,6 +46,7 @@ Item {
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: Be sure provided model is compatible with StatusListPicker::multiSelection property.
Here an example of the model roles expected:
\qml
Expand Down Expand Up @@ -154,56 +155,64 @@ Item {
QtObject {
id: d

function formatSymbolShortNameText(symbol, shortName) {
var formattedText = ""
if(root.printSymbol && symbol)
formattedText = symbol + shortName
else
formattedText = shortName
return formattedText
readonly property SortFilterProxyModel selectedItems: SortFilterProxyModel {
sourceModel: root.inputList
// NOTE: ValueFilter would crash if source model does not contain given role
// FIXME: use ValueFilter when its fixed
filters: ExpressionFilter {
expression: model.selected
}
}

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 = ""
for(var i = 0; i < root.inputList.count; i++) {
var item = root.inputList.get(i)
if(item.selected) {
if(res != "")
res += ", "
res += d.formatSymbolShortNameText(item.symbol, item.shortName)
}
for(var i = 0; i < selectedItems.count; i++) {
var item = selectedItems.get(i)
if(res != "")
res += ", "
res += formatSymbolShortNameText(item.symbol, item.shortName)
}
return res
}
}

width: 110
height: 38

Repeater {
// 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
// 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
}
}
}
}

width: 110
height: 38

StatusPickerButton {
id: btn
anchors.fill: parent
bgColor: Theme.palette.primaryColor3
contentColor: Theme.palette.primaryColor1
text: picker.selectedItemsText
text: d.selectedItemsText
font.pixelSize: 13
type: StatusPickerButton.Type.Down

Expand All @@ -219,8 +228,6 @@ Item {
Rectangle {
id: picker

property string selectedItemsText: ""

width: content.itemWidth
height: Math.min(content.contentHeight + content.anchors.topMargin + content.anchors.bottomMargin, root.maxPickerHeight)
anchors.left: root.menuAlignment === StatusListPicker.MenuAlignment.Left ? btn.left : undefined
Expand All @@ -243,7 +250,7 @@ Item {
}

ListView {
id: content
id: content

property int itemHeight: 40
property int itemWidth: 360
Expand All @@ -254,8 +261,8 @@ Item {
filters: ExpressionFilter {
expression: {
root.searchText // ensure expression is reevaluated when searchText changes
return model.name.toLowerCase().startsWith(root.searchText.toLowerCase()) ||
model.shortName.toLowerCase().startsWith(root.searchText.toLowerCase())
return model.name.toLowerCase().includes(root.searchText.toLowerCase()) ||
model.shortName.toLowerCase().includes(root.searchText.toLowerCase())
}
}
}
Expand Down Expand Up @@ -307,14 +314,8 @@ Item {
radioGroup: radioBtnGroup

onCheckedChanged: {
d.updateInputListModel(model.key, checked, selectorType === StatusItemPicker.SelectorType.RadioButton)
if(selectorType === StatusItemPicker.SelectorType.RadioButton && 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()
if (checked !== model.selected) {
itemsSelectorHelper.selectItem(model.key, checked)
}

// Used to notify selected property changes in the specific item picker.
Expand Down

0 comments on commit 8fa740b

Please sign in to comment.