[ui] improve atts filtering and add search bar ...

...for node attributes and 3D inspector

- add search bar for node attributes
- add search bar for 3D inspector
- improve attributes filtering by adding more flexibility
and fixing some issues
This commit is contained in:
Abdelrahman AL MAROUK 2023-07-03 09:25:17 +02:00
parent 6c2e9eb583
commit b5093ac3a0
6 changed files with 408 additions and 301 deletions

View file

@ -112,6 +112,10 @@ class Attribute(BaseObject):
def getLabel(self): def getLabel(self):
return self._label return self._label
@Slot(str, result=bool)
def matchText(self, text):
return self.fullLabel.lower().find(text.lower()) > -1
def getFullLabel(self): def getFullLabel(self):
""" Full Label includes the name of all parent groups, e.g. 'groupLabel subGroupLabel Label' """ """ Full Label includes the name of all parent groups, e.g. 'groupLabel subGroupLabel Label' """
if isinstance(self.root, ListAttribute): if isinstance(self.root, ListAttribute):
@ -349,6 +353,7 @@ class Attribute(BaseObject):
isOutput = Property(bool, isOutput.fget, constant=True) isOutput = Property(bool, isOutput.fget, constant=True)
isLinkChanged = Signal() isLinkChanged = Signal()
isLink = Property(bool, isLink.fget, notify=isLinkChanged) isLink = Property(bool, isLink.fget, notify=isLinkChanged)
isLinkNested = isLink
hasOutputConnectionsChanged = Signal() hasOutputConnectionsChanged = Signal()
hasOutputConnections = Property(bool, hasOutputConnections.fget, notify=hasOutputConnectionsChanged) hasOutputConnections = Property(bool, hasOutputConnections.fget, notify=hasOutputConnectionsChanged)
isDefault = Property(bool, _isDefault, notify=valueChanged) isDefault = Property(bool, _isDefault, notify=valueChanged)
@ -502,10 +507,19 @@ class ListAttribute(Attribute):
for attr in self._value: for attr in self._value:
attr.updateInternals() attr.updateInternals()
@property
def isLinkNested(self):
""" Whether the attribute or any of its elements is a link to another attribute. """
# note: directly use self.node.graph._edges to avoid using the property that may become invalid at some point
return self.isLink \
or self.node.graph and self.isInput and self.node.graph._edges \
and any(v in self.node.graph._edges.keys() for v in self._value)
# Override value property setter # Override value property setter
value = Property(Variant, Attribute._get_value, _set_value, notify=Attribute.valueChanged) value = Property(Variant, Attribute._get_value, _set_value, notify=Attribute.valueChanged)
isDefault = Property(bool, _isDefault, notify=Attribute.valueChanged) isDefault = Property(bool, _isDefault, notify=Attribute.valueChanged)
baseType = Property(str, getBaseType, constant=True) baseType = Property(str, getBaseType, constant=True)
isLinkNested = Property(bool, isLinkNested.fget)
class GroupAttribute(Attribute): class GroupAttribute(Attribute):
@ -622,6 +636,10 @@ class GroupAttribute(Attribute):
for attr in self._value: for attr in self._value:
attr.updateInternals() attr.updateInternals()
@Slot(str, result=bool)
def matchText(self, text):
return super().matchText(text) or any(c.matchText(text) for c in self._value)
# Override value property # Override value property
value = Property(Variant, Attribute._get_value, _set_value, notify=Attribute.valueChanged) value = Property(Variant, Attribute._get_value, _set_value, notify=Attribute.valueChanged)
isDefault = Property(bool, _isDefault, notify=Attribute.valueChanged) isDefault = Property(bool, _isDefault, notify=Attribute.valueChanged)

View file

@ -13,6 +13,7 @@ ListView {
property bool readOnly: false property bool readOnly: false
property int labelWidth: 180 property int labelWidth: 180
property bool objectsHideable: true property bool objectsHideable: true
property string filterText: ""
signal upgradeRequest() signal upgradeRequest()
signal attributeDoubleClicked(var mouse, var attribute) signal attributeDoubleClicked(var mouse, var attribute)
@ -24,21 +25,21 @@ ListView {
ScrollBar.vertical: ScrollBar { id: scrollBar } ScrollBar.vertical: ScrollBar { id: scrollBar }
delegate: Loader { delegate: Loader {
active: { active: object.enabled && (
object.enabled !objectsHideable
&& (!object.desc.advanced || GraphEditorSettings.showAdvancedAttributes) || ((!object.desc.advanced || GraphEditorSettings.showAdvancedAttributes)
&& ( && (object.isDefault && GraphEditorSettings.showDefaultAttributes || !object.isDefault && GraphEditorSettings.showModifiedAttributes)
!(object.isDefault || object.isOutput || object.isLink) && (object.isOutput && GraphEditorSettings.showOutputAttributes || !object.isOutput && GraphEditorSettings.showInputAttributes)
|| !GraphEditorSettings.showOnlyModifiedAttributes && (object.isLinkNested && GraphEditorSettings.showLinkAttributes || !object.isLink && GraphEditorSettings.showNotLinkAttributes))
|| !objectsHideable ) && object.matchText(filterText)
)
}
visible: active visible: active
sourceComponent: AttributeItemDelegate { sourceComponent: AttributeItemDelegate {
width: root.width - scrollBar.width width: root.width - scrollBar.width
readOnly: root.readOnly readOnly: root.readOnly
labelWidth: root.labelWidth labelWidth: root.labelWidth
filterText: root.filterText
objectsHideable: root.objectsHideable
attribute: object attribute: object
onDoubleClicked: root.attributeDoubleClicked(mouse, attr) onDoubleClicked: root.attributeDoubleClicked(mouse, attr)
} }

View file

@ -13,6 +13,8 @@ RowLayout {
property variant attribute: null property variant attribute: null
property bool readOnly: false // whether the attribute's value can be modified property bool readOnly: false // whether the attribute's value can be modified
property bool objectsHideable: true
property string filterText: ""
property alias label: parameterLabel // accessor to the internal Label (attribute's name) property alias label: parameterLabel // accessor to the internal Label (attribute's name)
property int labelWidth // shortcut to set the fixed size of the Label property int labelWidth // shortcut to set the fixed size of the Label
@ -489,7 +491,13 @@ RowLayout {
ScrollBar.vertical: ScrollBar { id: sb } ScrollBar.vertical: ScrollBar { id: sb }
delegate: RowLayout { delegate: Loader{
active: !objectsHideable
|| ((object.isDefault && GraphEditorSettings.showDefaultAttributes || !object.isDefault && GraphEditorSettings.showModifiedAttributes)
&& (object.isLinkNested && GraphEditorSettings.showLinkAttributes || !object.isLinkNested && GraphEditorSettings.showNotLinkAttributes))
visible: active
height: item ? implicitHeight : -spacing // compensate for spacing if item is hidden
sourceComponent: RowLayout {
id: item id: item
property var childAttrib: object property var childAttrib: object
layoutDirection: Qt.RightToLeft layoutDirection: Qt.RightToLeft
@ -520,6 +528,7 @@ RowLayout {
} }
} }
} }
}
Component { Component {
id: groupAttribute_component id: groupAttribute_component
@ -531,6 +540,8 @@ RowLayout {
{'model': Qt.binding(function() { return attribute.value }), {'model': Qt.binding(function() { return attribute.value }),
'readOnly': Qt.binding(function() { return root.readOnly }), 'readOnly': Qt.binding(function() { return root.readOnly }),
'labelWidth': 100, // reduce label width for children (space gain) 'labelWidth': 100, // reduce label width for children (space gain)
'objectsHideable': Qt.binding(function() { return root.objectsHideable }),
'filterText': Qt.binding(function() { return root.filterText }),
}) })
obj.Layout.fillWidth = true; obj.Layout.fillWidth = true;
obj.attributeDoubleClicked.connect(function(attr) {root.doubleClicked(attr)}) obj.attributeDoubleClicked.connect(function(attr) {root.doubleClicked(attr)})

View file

@ -8,6 +8,11 @@ import Qt.labs.settings 1.0
Settings { Settings {
category: 'GraphEditor' category: 'GraphEditor'
property bool showAdvancedAttributes: false property bool showAdvancedAttributes: false
property bool showOnlyModifiedAttributes: false property bool showDefaultAttributes: true
property bool showModifiedAttributes: true
property bool showInputAttributes: true
property bool showOutputAttributes: true
property bool showLinkAttributes: true
property bool showNotLinkAttributes: true
property bool lockOnCompute: true property bool lockOnCompute: true
} }

View file

@ -86,6 +86,12 @@ Panel {
} }
} }
SearchBar {
id: searchBar
width: 150
enabled: tabBar.currentIndex === 0 || tabBar.currentIndex === 5
}
MaterialToolButton { MaterialToolButton {
text: MaterialIcons.more_vert text: MaterialIcons.more_vert
font.pointSize: 11 font.pointSize: 11
@ -96,9 +102,69 @@ Panel {
Menu { Menu {
id: settingsMenu id: settingsMenu
y: parent.height y: parent.height
MenuItem { Menu {
id: filterAttributesMenu
title: "Filter Attributes"
RowLayout {
CheckBox {
id: outputToggle
text: "Output"
checkable: true
checked: GraphEditorSettings.showOutputAttributes
onClicked: GraphEditorSettings.showOutputAttributes = !GraphEditorSettings.showOutputAttributes
enabled: tabBar.currentIndex === 0
}
CheckBox {
id: inputToggle
text: "Input"
checkable: true
checked: GraphEditorSettings.showInputAttributes
onClicked: GraphEditorSettings.showInputAttributes = !GraphEditorSettings.showInputAttributes
enabled: tabBar.currentIndex === 0
}
}
MenuSeparator {}
RowLayout {
CheckBox {
id: defaultToggle
text: "Default"
checkable: true
checked: GraphEditorSettings.showDefaultAttributes
onClicked: GraphEditorSettings.showDefaultAttributes = !GraphEditorSettings.showDefaultAttributes
enabled: tabBar.currentIndex === 0
}
CheckBox {
id: modifiedToggle
text: "Modified"
checkable: true
checked: GraphEditorSettings.showModifiedAttributes
onClicked: GraphEditorSettings.showModifiedAttributes = !GraphEditorSettings.showModifiedAttributes
enabled: tabBar.currentIndex === 0
}
}
MenuSeparator {}
RowLayout {
CheckBox {
id: linkToggle
text: "Link"
checkable: true
checked: GraphEditorSettings.showLinkAttributes
onClicked: GraphEditorSettings.showLinkAttributes = !GraphEditorSettings.showLinkAttributes
enabled: tabBar.currentIndex === 0
}
CheckBox {
id: notLinkToggle
text: "Not Link"
checkable: true
checked: GraphEditorSettings.showNotLinkAttributes
onClicked: GraphEditorSettings.showNotLinkAttributes = !GraphEditorSettings.showNotLinkAttributes
enabled: tabBar.currentIndex === 0
}
}
MenuSeparator {}
CheckBox {
id: advancedToggle id: advancedToggle
text: "Advanced Attributes" text: "Advanced"
MaterialLabel { MaterialLabel {
anchors.right: parent.right; anchors.rightMargin: parent.padding; anchors.right: parent.right; anchors.rightMargin: parent.padding;
text: MaterialIcons.build text: MaterialIcons.build
@ -109,19 +175,6 @@ Panel {
checked: GraphEditorSettings.showAdvancedAttributes checked: GraphEditorSettings.showAdvancedAttributes
onClicked: GraphEditorSettings.showAdvancedAttributes = !GraphEditorSettings.showAdvancedAttributes onClicked: GraphEditorSettings.showAdvancedAttributes = !GraphEditorSettings.showAdvancedAttributes
} }
MenuItem {
id: modifiedToggle
text: "Only Modified Attributes"
MaterialLabel {
anchors.right: parent.right; anchors.rightMargin: parent.padding;
text: MaterialIcons.edit
anchors.verticalCenter: parent.verticalCenter
font.pointSize: 8
}
checkable: true
checked: GraphEditorSettings.showOnlyModifiedAttributes
onClicked: GraphEditorSettings.showOnlyModifiedAttributes = !GraphEditorSettings.showOnlyModifiedAttributes
enabled: tabBar.currentIndex === 0
} }
MenuItem { MenuItem {
text: "Open Cache Folder" text: "Open Cache Folder"
@ -207,6 +260,7 @@ Panel {
readOnly: root.readOnly || root.isCompatibilityNode readOnly: root.readOnly || root.isCompatibilityNode
onAttributeDoubleClicked: root.attributeDoubleClicked(mouse, attribute) onAttributeDoubleClicked: root.attributeDoubleClicked(mouse, attribute)
onUpgradeRequest: root.upgradeRequest() onUpgradeRequest: root.upgradeRequest()
filterText: searchBar.text
} }
Loader { Loader {
@ -273,6 +327,7 @@ Panel {
readOnly: root.readOnly || root.isCompatibilityNode readOnly: root.readOnly || root.isCompatibilityNode
onAttributeDoubleClicked: root.attributeDoubleClicked(mouse, attribute) onAttributeDoubleClicked: root.attributeDoubleClicked(mouse, attribute)
onUpgradeRequest: root.upgradeRequest() onUpgradeRequest: root.upgradeRequest()
filterText: searchBar.text
} }
} }
} }

View file

@ -172,11 +172,22 @@ FloatingPane {
checked: true checked: true
} }
ColumnLayout {
anchors.fill: parent
SearchBar {
id: searchBar
Layout.minimumWidth: 150
Layout.fillWidth: true
Layout.rightMargin: 10
Layout.leftMargin: 10
}
ListView { ListView {
id: mediaListView id: mediaListView
anchors.fill: parent Layout.fillHeight: true
Layout.fillWidth: true
clip: true clip: true
model: mediaLibrary.model
spacing: 4 spacing: 4
ScrollBar.vertical: ScrollBar { id: scrollBar } ScrollBar.vertical: ScrollBar { id: scrollBar }
@ -197,6 +208,10 @@ FloatingPane {
} }
} }
model: SortFilterDelegateModel {
model: mediaLibrary.model
sortRole: "label"
filters: [{role: "label", value: searchBar.text}]
delegate: MouseArea { delegate: MouseArea {
id: mediaDelegate id: mediaDelegate
// add mediaLibrary.count in the binding to ensure 'entity' // add mediaLibrary.count in the binding to ensure 'entity'
@ -445,4 +460,6 @@ FloatingPane {
} }
} }
} }
}
}
} }