QmlDesigner: Add support for adding an extra button to EditableListView

Will be used to add a button to open material editor from material rows
in a Quick3DModel properties sheet. But can be utilized for more
future usecases.

Task-number: QDS-9408
Change-Id: I540479cc1a88cdfe287f244efd7cd65c895db467
Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
Reviewed-by: Henning Gründl <henning.gruendl@qt.io>
This commit is contained in:
Mahmoud Badri
2023-03-15 20:21:44 +02:00
parent 0e4e82d7aa
commit 315abe7e9c

View File

@@ -7,11 +7,11 @@ import StudioControls 1.0 as StudioControls
import StudioTheme 1.0 as StudioTheme import StudioTheme 1.0 as StudioTheme
Item { Item {
id: editableListView id: root
ExtendedFunctionLogic { ExtendedFunctionLogic {
id: extFuncLogic id: extFuncLogic
backendValue: editableListView.backendValue backendValue: root.backendValue
} }
property var backendValue property var backendValue
@@ -29,6 +29,10 @@ Item {
property bool delegateHover: false property bool delegateHover: false
property string extraButtonIcon: "" // setting this will show an extra button
property string extraButtonToolTip: ""
signal extraButtonClicked(int idx)
signal add(string value) signal add(string value)
signal remove(int idx) signal remove(int idx)
signal replace(int idx, string value) signal replace(int idx, string value)
@@ -50,10 +54,10 @@ Item {
validator: RegExpValidator { regExp: /(^[a-z_]\w*|^[A-Z]\w*\.{1}([a-z_]\w*\.?)+)/ } validator: RegExpValidator { regExp: /(^[a-z_]\w*|^[A-Z]\w*\.{1}([a-z_]\w*\.?)+)/ }
actionIndicatorVisible: false actionIndicatorVisible: false
typeFilter: editableListView.typeFilter typeFilter: root.typeFilter
initialModelData: modelData initialModelData: modelData
textRole: editableListView.textRole textRole: root.textRole
valueRole: editableListView.valueRole valueRole: root.valueRole
implicitWidth: StudioTheme.Values.singleControlColumnWidth implicitWidth: StudioTheme.Values.singleControlColumnWidth
width: implicitWidth width: implicitWidth
@@ -64,26 +68,34 @@ Item {
var curValue = itemFilterComboBox.availableValue() var curValue = itemFilterComboBox.availableValue()
if (itemFilterComboBox.empty && curValue !== "") { if (itemFilterComboBox.empty && curValue !== "") {
myRepeater.dirty = false myRepeater.dirty = false
editableListView.add(curValue) root.add(curValue)
} }
} }
onCompressedActivated: function(index, reason) { onCompressedActivated: function(index, reason) {
editableListView.activatedReason = reason root.activatedReason = reason
var curValue = itemFilterComboBox.availableValue() var curValue = itemFilterComboBox.availableValue()
if (itemFilterComboBox.empty && curValue) { if (itemFilterComboBox.empty && curValue) {
myRepeater.dirty = false myRepeater.dirty = false
editableListView.add(curValue) root.add(curValue)
} else { } else {
editableListView.replace(itemFilterComboBox.myIndex, curValue) root.replace(itemFilterComboBox.myIndex, curValue)
} }
} }
onHoverChanged: editableListView.delegateHover = itemFilterComboBox.hover onHoverChanged: root.delegateHover = itemFilterComboBox.hover
} }
Spacer { implicitWidth: StudioTheme.Values.twoControlColumnGap } Spacer { implicitWidth: extraButton.visible ? 5 : StudioTheme.Values.twoControlColumnGap }
IconIndicator {
id: extraButton
icon: root.extraButtonIcon
tooltip: root.extraButtonToolTip
onClicked: root.extraButtonClicked(index)
visible: root.extraButtonIcon !== ""
}
IconIndicator { IconIndicator {
id: closeIndicator id: closeIndicator
@@ -95,12 +107,12 @@ Item {
myRepeater.dirty = false myRepeater.dirty = false
myRepeater.model = myRepeater.localModel // trigger on change handler myRepeater.model = myRepeater.localModel // trigger on change handler
} else { } else {
editableListView.remove(index) root.remove(index)
} }
if (!lastItem) if (!lastItem)
myColumn.currentIndex = index - 1 myColumn.currentIndex = index - 1
} }
onHoveredChanged: editableListView.delegateHover = closeIndicator.hovered onHoveredChanged: root.delegateHover = closeIndicator.hovered
} }
} }
} }
@@ -108,7 +120,7 @@ Item {
Row { Row {
ActionIndicator { ActionIndicator {
id: actionIndicator id: actionIndicator
icon.visible: editableListView.delegateHover icon.visible: root.delegateHover
icon.color: extFuncLogic.color icon.color: extFuncLogic.color
icon.text: extFuncLogic.glyph icon.text: extFuncLogic.glyph
onClicked: extFuncLogic.show() onClicked: extFuncLogic.show()
@@ -146,7 +158,7 @@ Item {
myColumn.currentIndex = -1 myColumn.currentIndex = -1
myRepeater.localModel = [] myRepeater.localModel = []
editableListView.model.forEach(function(item) { root.model.forEach(function(item) {
myRepeater.localModel.push(item) myRepeater.localModel.push(item)
}); });
@@ -163,7 +175,7 @@ Item {
else else
myColumn.currentIndex = myRepeater.localModel.length - 1 myColumn.currentIndex = myRepeater.localModel.length - 1
if (editableListView.activatedReason === ComboBox.ActivatedReason.Other if (root.activatedReason === ComboBox.ActivatedReason.Other
&& myColumn.currentItem !== null) && myColumn.currentItem !== null)
myColumn.currentItem.forceActiveFocus() myColumn.currentItem.forceActiveFocus()
} }
@@ -174,36 +186,36 @@ Item {
visible: myRepeater.count === 0 visible: myRepeater.count === 0
validator: RegExpValidator { regExp: /(^[a-z_]\w*|^[A-Z]\w*\.{1}([a-z_]\w*\.?)+)/ } validator: RegExpValidator { regExp: /(^[a-z_]\w*|^[A-Z]\w*\.{1}([a-z_]\w*\.?)+)/ }
actionIndicatorVisible: false actionIndicatorVisible: false
typeFilter: editableListView.typeFilter typeFilter: root.typeFilter
textRole: editableListView.textRole textRole: root.textRole
valueRole: editableListView.valueRole valueRole: root.valueRole
implicitWidth: StudioTheme.Values.singleControlColumnWidth implicitWidth: StudioTheme.Values.singleControlColumnWidth
width: implicitWidth width: implicitWidth
onFocusChanged: { onFocusChanged: {
var curValue = dummyComboBox.availableValue() var curValue = dummyComboBox.availableValue()
if (curValue !== "") if (curValue !== "")
editableListView.add(curValue) root.add(curValue)
} }
onCompressedActivated: { onCompressedActivated: {
editableListView.activatedReason = reason root.activatedReason = reason
var curValue = dummyComboBox.availableValue() var curValue = dummyComboBox.availableValue()
if (curValue !== "") if (curValue !== "")
editableListView.add(curValue) root.add(curValue)
else else
editableListView.replace(dummyComboBox.myIndex, curValue) root.replace(dummyComboBox.myIndex, curValue)
} }
onHoverChanged: editableListView.delegateHover = dummyComboBox.hover onHoverChanged: root.delegateHover = dummyComboBox.hover
} }
StudioControls.AbstractButton { StudioControls.AbstractButton {
id: plusButton id: plusButton
buttonIcon: StudioTheme.Constants.plus buttonIcon: StudioTheme.Constants.plus
enabled: !myRepeater.dirty && !(editableListView.backendValue.isInModel enabled: !myRepeater.dirty && !(root.backendValue.isInModel
&& !editableListView.backendValue.isIdList) && !root.backendValue.isIdList)
onClicked: { onClicked: {
var idx = myRepeater.localModel.push("") - 1 var idx = myRepeater.localModel.push("") - 1
myRepeater.model = myRepeater.localModel // trigger on change handler myRepeater.model = myRepeater.localModel // trigger on change handler
@@ -212,7 +224,7 @@ Item {
myColumn.currentItem.forceActiveFocus() myColumn.currentItem.forceActiveFocus()
} }
onHoveredChanged: editableListView.delegateHover = plusButton.hovered onHoveredChanged: root.delegateHover = plusButton.hovered
} }
} }
} }