mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 21:04:40 +01:00
Merge pull request #536 from pypeclub/feature/dict_items_merge
Feature/dict items merge
This commit is contained in:
commit
8fe06d27f7
4 changed files with 111 additions and 142 deletions
|
|
@ -54,13 +54,18 @@
|
|||
|
||||
## dict
|
||||
- this is another dictionary input wrapping more inputs but visually makes them different
|
||||
- required keys are `"key"` under which will be stored and `"label"` which will be shown in GUI
|
||||
- this input can be expandable
|
||||
- that can be set with key `"expandable"` as `True`/`False` (Default: `True`)
|
||||
- with key `"expanded"` as `True`/`False` can be set that is expanded when GUI is opened (Default: `False`)
|
||||
- it is possible to add darker background with `"highlight_content"` (Default: `False`)
|
||||
- darker background has limits of maximum applies after 3-4 nested highlighted items there is not difference in the color
|
||||
- item may be used as widget (in `list` or `dict-modifiable`)
|
||||
- in that case the only key modifier is `children` which is list of it's keys
|
||||
- USAGE: e.g. List of dictionaries where each dictionary have same structure.
|
||||
- item options if is not used as widget
|
||||
- required keys are `"key"` under which will be stored and `"label"` which will be shown in GUI
|
||||
- this input can be expandable
|
||||
- that can be set with key `"expandable"` as `True`/`False` (Default: `True`)
|
||||
- with key `"expanded"` as `True`/`False` can be set that is expanded when GUI is opened (Default: `False`)
|
||||
- it is possible to add darker background with `"highlight_content"` (Default: `False`)
|
||||
- darker background has limits of maximum applies after 3-4 nested highlighted items there is not difference in the color
|
||||
```
|
||||
# Example
|
||||
{
|
||||
"key": "applications",
|
||||
"type": "dict",
|
||||
|
|
@ -73,6 +78,30 @@
|
|||
...ITEMS...
|
||||
]
|
||||
}
|
||||
|
||||
# When used as widget
|
||||
{
|
||||
"type": "list",
|
||||
"key": "profiles",
|
||||
"label": "Profiles",
|
||||
"object_type": "dict-item",
|
||||
"input_modifiers": {
|
||||
"children": [
|
||||
{
|
||||
"key": "families",
|
||||
"label": "Families",
|
||||
"type": "list",
|
||||
"object_type": "text"
|
||||
}, {
|
||||
"key": "hosts",
|
||||
"label": "Hosts",
|
||||
"type": "list",
|
||||
"object_type": "text"
|
||||
}
|
||||
...
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Inputs for setting any kind of value (`Pure` inputs)
|
||||
|
|
@ -280,7 +309,7 @@
|
|||
- should wraps multiple inputs only visually
|
||||
- these does not have `"key"` key and do not allow to have `"is_file"` or `"is_group"` modifiers enabled
|
||||
|
||||
### dict-form
|
||||
### form
|
||||
- DEPRECATED
|
||||
- may be used only in `dict` and `dict-invisible` where is currently used grid layout so form is not needed
|
||||
- item is kept as still may be used in specific cases
|
||||
|
|
|
|||
|
|
@ -172,7 +172,7 @@
|
|||
"type": "list",
|
||||
"key": "profiles",
|
||||
"label": "Profiles",
|
||||
"object_type": "dict-item",
|
||||
"object_type": "dict",
|
||||
"input_modifiers": {
|
||||
"children": [
|
||||
{
|
||||
|
|
@ -192,7 +192,7 @@
|
|||
"label": "Output Definitions",
|
||||
"type": "dict-modifiable",
|
||||
"highlight_content": true,
|
||||
"object_type": "dict-item",
|
||||
"object_type": "dict",
|
||||
"input_modifiers": {
|
||||
"children": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ QPushButton[btn-type="expand-toggle"] {
|
|||
background: #141a1f;
|
||||
}
|
||||
|
||||
#DictItemWidgetBody{
|
||||
#DictAsWidgetBody{
|
||||
background: transparent;
|
||||
border: 2px solid #cccccc;
|
||||
border-radius: 5px;
|
||||
|
|
|
|||
|
|
@ -1199,101 +1199,6 @@ class RawJsonWidget(QtWidgets.QWidget, InputObject):
|
|||
return self.text_input.json_value()
|
||||
|
||||
|
||||
class DictItemWidget(QtWidgets.QWidget, SettingObject):
|
||||
default_input_value = True
|
||||
value_changed = QtCore.Signal(object)
|
||||
|
||||
def __init__(
|
||||
self, input_data, parent,
|
||||
as_widget=False, label_widget=None, parent_widget=None
|
||||
):
|
||||
if parent_widget is None:
|
||||
parent_widget = parent
|
||||
super(DictItemWidget, self).__init__(parent_widget)
|
||||
|
||||
self.initial_attributes(input_data, parent, as_widget)
|
||||
|
||||
if not self._as_widget:
|
||||
raise TypeError("{} can be used only as widget.".format(
|
||||
self.__class__.__name__
|
||||
))
|
||||
|
||||
self.input_fields = []
|
||||
|
||||
body = QtWidgets.QWidget(self)
|
||||
body.setObjectName("DictItemWidgetBody")
|
||||
|
||||
content_layout = QtWidgets.QGridLayout(body)
|
||||
content_layout.setContentsMargins(5, 5, 5, 5)
|
||||
self.content_layout = content_layout
|
||||
|
||||
layout = QtWidgets.QHBoxLayout(self)
|
||||
layout.setContentsMargins(0, 0, 0, 0)
|
||||
layout.setSpacing(5)
|
||||
layout.addWidget(body)
|
||||
|
||||
self.label_widget = label_widget
|
||||
|
||||
for child_configuration in input_data["children"]:
|
||||
self.add_children_gui(child_configuration)
|
||||
|
||||
def add_children_gui(self, child_configuration):
|
||||
item_type = child_configuration["type"]
|
||||
klass = TypeToKlass.types.get(item_type)
|
||||
|
||||
row = self.content_layout.rowCount()
|
||||
if not getattr(klass, "is_input_type", False):
|
||||
item = klass(child_configuration, self)
|
||||
self.content_layout.addWidget(item, row, 0, 1, 2)
|
||||
return item
|
||||
|
||||
label_widget = None
|
||||
if not klass.expand_in_grid:
|
||||
label = child_configuration.get("label")
|
||||
if label is not None:
|
||||
label_widget = QtWidgets.QLabel(label, self)
|
||||
self.content_layout.addWidget(
|
||||
label_widget, row, 0, 1, 1,
|
||||
alignment=QtCore.Qt.AlignRight | QtCore.Qt.AlignTop
|
||||
)
|
||||
|
||||
item = klass(child_configuration, self, label_widget=label_widget)
|
||||
item.value_changed.connect(self._on_value_change)
|
||||
|
||||
if label_widget:
|
||||
self.content_layout.addWidget(item, row, 1, 1, 1)
|
||||
else:
|
||||
self.content_layout.addWidget(item, row, 0, 1, 2)
|
||||
|
||||
self.input_fields.append(item)
|
||||
return item
|
||||
|
||||
def hierarchical_style_update(self):
|
||||
for input_field in self.input_fields:
|
||||
input_field.hierarchical_style_update()
|
||||
|
||||
def _on_value_change(self, item=None):
|
||||
self.value_changed.emit(self)
|
||||
|
||||
def update_default_values(self, parent_values):
|
||||
for input_field in self.input_fields:
|
||||
input_field.update_default_values(parent_values)
|
||||
|
||||
def update_studio_values(self, parent_values):
|
||||
for input_field in self.input_fields:
|
||||
input_field.update_studio_values(parent_values)
|
||||
|
||||
def apply_overrides(self, parent_values):
|
||||
for input_field in self.input_fields:
|
||||
input_field.apply_overrides(parent_values)
|
||||
|
||||
def item_value(self):
|
||||
output = {}
|
||||
for input_field in self.input_fields:
|
||||
output.update(input_field.config_value())
|
||||
return output
|
||||
|
||||
|
||||
class ListItem(QtWidgets.QWidget, SettingObject):
|
||||
_btn_size = 20
|
||||
value_changed = QtCore.Signal(object)
|
||||
|
|
@ -2325,18 +2230,26 @@ class DictWidget(QtWidgets.QWidget, SettingObject):
|
|||
self, input_data, parent,
|
||||
as_widget=False, label_widget=None, parent_widget=None
|
||||
):
|
||||
if as_widget:
|
||||
raise TypeError("Can't use \"{}\" as widget item.".format(
|
||||
self.__class__.__name__
|
||||
))
|
||||
|
||||
if parent_widget is None:
|
||||
parent_widget = parent
|
||||
super(DictWidget, self).__init__(parent_widget)
|
||||
self.setObjectName("DictWidget")
|
||||
|
||||
self.initial_attributes(input_data, parent, as_widget)
|
||||
|
||||
self.input_fields = []
|
||||
|
||||
self.checkbox_widget = None
|
||||
self.checkbox_key = input_data.get("checkbox_key")
|
||||
|
||||
self.label_widget = label_widget
|
||||
|
||||
if self.as_widget:
|
||||
self._ui_as_widget(input_data)
|
||||
else:
|
||||
self._ui_as_item(input_data)
|
||||
|
||||
def _ui_as_item(self, input_data):
|
||||
self.key = input_data["key"]
|
||||
if input_data.get("highlight_content", False):
|
||||
content_state = "hightlighted"
|
||||
bottom_margin = 5
|
||||
|
|
@ -2344,10 +2257,6 @@ class DictWidget(QtWidgets.QWidget, SettingObject):
|
|||
content_state = ""
|
||||
bottom_margin = 0
|
||||
|
||||
self.input_fields = []
|
||||
|
||||
self.key = input_data["key"]
|
||||
|
||||
main_layout = QtWidgets.QHBoxLayout(self)
|
||||
main_layout.setContentsMargins(0, 0, 0, 0)
|
||||
main_layout.setSpacing(0)
|
||||
|
|
@ -2370,9 +2279,6 @@ class DictWidget(QtWidgets.QWidget, SettingObject):
|
|||
|
||||
self.label_widget = body_widget.label_widget
|
||||
|
||||
self.checkbox_widget = None
|
||||
self.checkbox_key = input_data.get("checkbox_key")
|
||||
|
||||
for child_data in input_data.get("children", []):
|
||||
self.add_children_gui(child_data)
|
||||
|
||||
|
|
@ -2387,6 +2293,22 @@ class DictWidget(QtWidgets.QWidget, SettingObject):
|
|||
else:
|
||||
body_widget.hide_toolbox(hide_content=False)
|
||||
|
||||
def _ui_as_widget(self, input_data):
|
||||
body = QtWidgets.QWidget(self)
|
||||
body.setObjectName("DictAsWidgetBody")
|
||||
|
||||
content_layout = QtWidgets.QGridLayout(body)
|
||||
content_layout.setContentsMargins(5, 5, 5, 5)
|
||||
self.content_layout = content_layout
|
||||
|
||||
layout = QtWidgets.QHBoxLayout(self)
|
||||
layout.setContentsMargins(0, 0, 0, 0)
|
||||
layout.setSpacing(5)
|
||||
layout.addWidget(body)
|
||||
|
||||
for child_configuration in input_data["children"]:
|
||||
self.add_children_gui(child_configuration)
|
||||
|
||||
def add_children_gui(self, child_configuration):
|
||||
item_type = child_configuration["type"]
|
||||
klass = TypeToKlass.types.get(item_type)
|
||||
|
|
@ -2473,8 +2395,12 @@ class DictWidget(QtWidgets.QWidget, SettingObject):
|
|||
item.set_as_overriden()
|
||||
|
||||
def update_default_values(self, parent_values):
|
||||
# Make sure this is set to False
|
||||
self._state = None
|
||||
self._child_state = None
|
||||
|
||||
value = NOT_SET
|
||||
if self._as_widget:
|
||||
if self.as_widget:
|
||||
value = parent_values
|
||||
elif parent_values is not NOT_SET:
|
||||
value = parent_values.get(self.key, NOT_SET)
|
||||
|
|
@ -2483,15 +2409,21 @@ class DictWidget(QtWidgets.QWidget, SettingObject):
|
|||
item.update_default_values(value)
|
||||
|
||||
def update_studio_values(self, parent_values):
|
||||
# Make sure this is set to False
|
||||
self._state = None
|
||||
self._child_state = None
|
||||
value = NOT_SET
|
||||
if parent_values is not NOT_SET:
|
||||
value = parent_values.get(self.key, NOT_SET)
|
||||
if self.as_widget:
|
||||
value = parent_values
|
||||
else:
|
||||
if parent_values is not NOT_SET:
|
||||
value = parent_values.get(self.key, NOT_SET)
|
||||
|
||||
self._has_studio_override = False
|
||||
if self.is_group and value is not NOT_SET:
|
||||
self._has_studio_override = True
|
||||
self._has_studio_override = False
|
||||
if self.is_group and value is not NOT_SET:
|
||||
self._has_studio_override = True
|
||||
|
||||
self._had_studio_override = bool(self._has_studio_override)
|
||||
self._had_studio_override = bool(self._has_studio_override)
|
||||
|
||||
for item in self.input_fields:
|
||||
item.update_studio_values(value)
|
||||
|
|
@ -2501,37 +2433,40 @@ class DictWidget(QtWidgets.QWidget, SettingObject):
|
|||
self._state = None
|
||||
self._child_state = None
|
||||
|
||||
metadata = {}
|
||||
groups = tuple()
|
||||
override_values = NOT_SET
|
||||
if parent_values is not NOT_SET:
|
||||
metadata = parent_values.get(METADATA_KEY) or metadata
|
||||
groups = metadata.get("groups") or groups
|
||||
override_values = parent_values.get(self.key, override_values)
|
||||
if not self.as_widget:
|
||||
metadata = {}
|
||||
groups = tuple()
|
||||
override_values = NOT_SET
|
||||
if parent_values is not NOT_SET:
|
||||
metadata = parent_values.get(METADATA_KEY) or metadata
|
||||
groups = metadata.get("groups") or groups
|
||||
override_values = parent_values.get(self.key, override_values)
|
||||
|
||||
self._is_overriden = self.key in groups
|
||||
self._is_overriden = self.key in groups
|
||||
|
||||
for item in self.input_fields:
|
||||
item.apply_overrides(override_values)
|
||||
|
||||
if not self._is_overriden:
|
||||
self._is_overriden = (
|
||||
self.is_group
|
||||
and self.is_overidable
|
||||
and self.child_overriden
|
||||
)
|
||||
self._was_overriden = bool(self._is_overriden)
|
||||
if not self.as_widget:
|
||||
if not self._is_overriden:
|
||||
self._is_overriden = (
|
||||
self.is_group
|
||||
and self.is_overidable
|
||||
and self.child_overriden
|
||||
)
|
||||
self._was_overriden = bool(self._is_overriden)
|
||||
|
||||
def _on_value_change(self, item=None):
|
||||
if self.ignore_value_changes:
|
||||
return
|
||||
|
||||
if self.is_group and not self.any_parent_as_widget:
|
||||
if self.is_group and not (self.as_widget or self.any_parent_as_widget):
|
||||
if self.is_overidable:
|
||||
self._is_overriden = True
|
||||
else:
|
||||
self._has_studio_override = True
|
||||
|
||||
# TODO check if this is required
|
||||
self.hierarchical_style_update()
|
||||
|
||||
self.value_changed.emit(self)
|
||||
|
|
@ -2544,6 +2479,10 @@ class DictWidget(QtWidgets.QWidget, SettingObject):
|
|||
self.update_style()
|
||||
|
||||
def update_style(self, is_overriden=None):
|
||||
# TODO add style update when used as widget
|
||||
if self.as_widget:
|
||||
return
|
||||
|
||||
child_has_studio_override = self.child_has_studio_override
|
||||
child_modified = self.child_modified
|
||||
child_invalid = self.child_invalid
|
||||
|
|
@ -3549,7 +3488,8 @@ TypeToKlass.types["raw-json"] = RawJsonWidget
|
|||
TypeToKlass.types["list"] = ListWidget
|
||||
TypeToKlass.types["list-strict"] = ListStrictWidget
|
||||
TypeToKlass.types["dict-modifiable"] = ModifiableDict
|
||||
TypeToKlass.types["dict-item"] = DictItemWidget
|
||||
# DEPRECATED - remove when removed from schemas
|
||||
TypeToKlass.types["dict-item"] = DictWidget
|
||||
TypeToKlass.types["dict"] = DictWidget
|
||||
TypeToKlass.types["dict-invisible"] = DictInvisible
|
||||
TypeToKlass.types["path-widget"] = PathWidget
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue