From 154005006878941378bd18a8492dc72317f95276 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 27 Nov 2020 11:23:11 +0100 Subject: [PATCH 01/39] modified `initial_attributes` renamed variable `input_data` to `schema_data` which are stored to item also "key" is required key --- .../settings/settings/widgets/item_types.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index 472a5b111c..eacfb94046 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -134,7 +134,7 @@ class SettingObject: role_name = self.user_role return role_name in self._roles - def initial_attributes(self, input_data, parent, as_widget): + def initial_attributes(self, schema_data, parent, as_widget): """Prepare attributes based on entered arguments. This method should be same for each item type. Few item types @@ -142,23 +142,25 @@ class SettingObject: """ self._set_default_attributes() + self.schema_data = schema_data + self._parent = parent self._as_widget = as_widget - self._roles = input_data.get("roles") + self._roles = schema_data.get("roles") if self._roles is not None and not isinstance(self._roles, list): self._roles = [self._roles] - self._is_group = input_data.get("is_group", False) - self._env_group_key = input_data.get("env_group_key") + self._is_group = schema_data.get("is_group", False) + self._env_group_key = schema_data.get("env_group_key") # TODO not implemented yet - self._is_nullable = input_data.get("is_nullable", False) + self._is_nullable = schema_data.get("is_nullable", False) if self.is_environ: if not self.allow_to_environment: raise TypeError(( "Item {} does not allow to store environment values" - ).format(input_data["type"])) + ).format(schema_data["type"])) self.add_environ_field(self) @@ -178,6 +180,9 @@ class SettingObject: self.hide() self.hidden_by_role = True + if not self.as_widget: + self.key = self.schema_data["key"] + @property def user_role(self): """Tool is running with any user role. From 76bfb6a578ff1a8e0e2389e84cc328241a170260 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 27 Nov 2020 11:31:50 +0100 Subject: [PATCH 02/39] split items creation to initialization in `__init__` and `create_ui` methods --- .../settings/widgets/anatomy_types.py | 18 +- pype/tools/settings/settings/widgets/base.py | 2 + .../settings/settings/widgets/item_types.py | 307 +++++++++--------- 3 files changed, 160 insertions(+), 167 deletions(-) diff --git a/pype/tools/settings/settings/widgets/anatomy_types.py b/pype/tools/settings/settings/widgets/anatomy_types.py index e1a726187c..3eb2bc0d3e 100644 --- a/pype/tools/settings/settings/widgets/anatomy_types.py +++ b/pype/tools/settings/settings/widgets/anatomy_types.py @@ -34,7 +34,7 @@ class AnatomyWidget(QtWidgets.QWidget, SettingObject): } def __init__( - self, input_data, parent, as_widget=False, label_widget=None + self, schema_data, parent, as_widget=False ): if as_widget: raise TypeError( @@ -43,11 +43,12 @@ class AnatomyWidget(QtWidgets.QWidget, SettingObject): super(AnatomyWidget, self).__init__(parent) self.setObjectName("AnatomyWidget") - self.initial_attributes(input_data, parent, as_widget) + self.initial_attributes(schema_data, parent, as_widget) - self.key = input_data["key"] + self.key = schema_data["key"] - children_data = input_data["children"] + def create_ui(self, label_widget=None): + children_data = self.schema_data["children"] roots_input_data = {} templates_input_data = {} for child in children_data: @@ -269,6 +270,7 @@ class RootsWidget(QtWidgets.QWidget, SettingObject): path_widget_data, self, as_widget=True, parent_widget=content_widget ) + singleroot_widget.create_ui() multiroot_data = { "key": self.key, "expandable": False, @@ -281,6 +283,7 @@ class RootsWidget(QtWidgets.QWidget, SettingObject): multiroot_data, self, as_widget=True, parent_widget=content_widget ) + multiroot_widget.create_ui() content_layout = QtWidgets.QVBoxLayout(content_widget) content_layout.setContentsMargins(0, 0, 0, 0) @@ -638,10 +641,9 @@ class TemplatesWidget(QtWidgets.QWidget, SettingObject): } self.body_widget = body_widget self.label_widget = body_widget.label_widget - self.value_input = RawJsonWidget( - template_input_data, self, - label_widget=self.label_widget - ) + self.value_input = RawJsonWidget(template_input_data, self) + self.value_input.create_ui(label_widget=self.label_widget) + content_layout.addWidget(self.value_input) layout = QtWidgets.QVBoxLayout(self) diff --git a/pype/tools/settings/settings/widgets/base.py b/pype/tools/settings/settings/widgets/base.py index 3f842602ca..ff35dc254c 100644 --- a/pype/tools/settings/settings/widgets/base.py +++ b/pype/tools/settings/settings/widgets/base.py @@ -321,6 +321,7 @@ class SystemWidget(QtWidgets.QWidget): item_type = child_configuration["type"] klass = lib.TypeToKlass.types.get(item_type) item = klass(child_configuration, self) + item.create_ui() self.input_fields.append(item) self.content_layout.addWidget(item, 0) @@ -587,6 +588,7 @@ class ProjectWidget(QtWidgets.QWidget): item_type = child_configuration["type"] klass = lib.TypeToKlass.types.get(item_type) item = klass(child_configuration, self) + item.create_ui() self.input_fields.append(item) self.content_layout.addWidget(item, 0) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index eacfb94046..387398a32b 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -916,7 +916,7 @@ class BooleanWidget(QtWidgets.QWidget, InputObject): def __init__( self, input_data, parent, - as_widget=False, label_widget=None, parent_widget=None + as_widget=False, parent_widget=None ): if parent_widget is None: parent_widget = parent @@ -924,17 +924,16 @@ class BooleanWidget(QtWidgets.QWidget, InputObject): self.initial_attributes(input_data, parent, as_widget) + def create_ui(self, label_widget=None): layout = QtWidgets.QHBoxLayout(self) layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(5) - if not self.as_widget: - self.key = input_data["key"] - if not label_widget: - label = input_data["label"] - label_widget = QtWidgets.QLabel(label) - label_widget.setAttribute(QtCore.Qt.WA_TranslucentBackground) - layout.addWidget(label_widget, 0) + if not self.as_widget and not label_widget: + label = self.schema_data["label"] + label_widget = QtWidgets.QLabel(label) + label_widget.setAttribute(QtCore.Qt.WA_TranslucentBackground) + layout.addWidget(label_widget, 0) self.label_widget = label_widget checkbox_height = self.style().pixelMetric( @@ -969,34 +968,32 @@ class NumberWidget(QtWidgets.QWidget, InputObject): valid_value_types = (int, float) def __init__( - self, input_data, parent, - as_widget=False, label_widget=None, parent_widget=None + self, schema_data, parent, as_widget=False, parent_widget=None ): if parent_widget is None: parent_widget = parent super(NumberWidget, self).__init__(parent_widget) - self.initial_attributes(input_data, parent, as_widget) + self.initial_attributes(schema_data, parent, as_widget) + def create_ui(self, label_widget=None): layout = QtWidgets.QHBoxLayout(self) layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(5) kwargs = { - modifier: input_data.get(modifier) + modifier: self.schema_data.get(modifier) for modifier in self.input_modifiers - if input_data.get(modifier) + if self.schema_data.get(modifier) } self.input_field = NumberSpinBox(self, **kwargs) self.setFocusProxy(self.input_field) - if not self._as_widget: - self.key = input_data["key"] - if not label_widget: - label = input_data["label"] - label_widget = QtWidgets.QLabel(label) - layout.addWidget(label_widget, 0) + if not self._as_widget and not label_widget: + label = self.schema_data["label"] + label_widget = QtWidgets.QLabel(label) + layout.addWidget(label_widget, 0) self.label_widget = label_widget layout.addWidget(self.input_field, 1) @@ -1017,17 +1014,17 @@ class TextWidget(QtWidgets.QWidget, InputObject): valid_value_types = (str, ) def __init__( - self, input_data, parent, - as_widget=False, label_widget=None, parent_widget=None + self, schema_data, parent, as_widget=False, parent_widget=None ): if parent_widget is None: parent_widget = parent super(TextWidget, self).__init__(parent_widget) - self.initial_attributes(input_data, parent, as_widget) - self.multiline = input_data.get("multiline", False) - placeholder = input_data.get("placeholder") + self.initial_attributes(schema_data, parent, as_widget) + self.multiline = schema_data.get("multiline", False) + self.placeholder_text = schema_data.get("placeholder") + def create_ui(self, label_widget=None): layout = QtWidgets.QHBoxLayout(self) layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(5) @@ -1037,8 +1034,8 @@ class TextWidget(QtWidgets.QWidget, InputObject): else: self.input_field = QtWidgets.QLineEdit(self) - if placeholder: - self.input_field.setPlaceholderText(placeholder) + if self.placeholder_text: + self.input_field.setPlaceholderText(self.placeholder_text) self.setFocusProxy(self.input_field) @@ -1046,12 +1043,10 @@ class TextWidget(QtWidgets.QWidget, InputObject): if self.multiline: layout_kwargs["alignment"] = QtCore.Qt.AlignTop - if not self._as_widget: - self.key = input_data["key"] - if not label_widget: - label = input_data["label"] - label_widget = QtWidgets.QLabel(label) - layout.addWidget(label_widget, 0, **layout_kwargs) + if not self._as_widget and not label_widget: + label = self.schema_data["label"] + label_widget = QtWidgets.QLabel(label) + layout.addWidget(label_widget, 0, **layout_kwargs) self.label_widget = label_widget layout.addWidget(self.input_field, 1, **layout_kwargs) @@ -1078,25 +1073,23 @@ class PathInputWidget(QtWidgets.QWidget, InputObject): valid_value_types = (str, ) def __init__( - self, input_data, parent, - as_widget=False, label_widget=None, parent_widget=None + self, schema_data, parent, as_widget=False, parent_widget=None ): if parent_widget is None: parent_widget = parent super(PathInputWidget, self).__init__(parent_widget) - self.initial_attributes(input_data, parent, as_widget) + self.initial_attributes(schema_data, parent, as_widget) + def create_ui(self, label_widget=None): layout = QtWidgets.QHBoxLayout(self) layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(5) - if not self._as_widget: - self.key = input_data["key"] - if not label_widget: - label = input_data["label"] - label_widget = QtWidgets.QLabel(label) - layout.addWidget(label_widget, 0) + if not self._as_widget and not label_widget: + label = self.schema_data["label"] + label_widget = QtWidgets.QLabel(label) + layout.addWidget(label_widget, 0) self.label_widget = label_widget self.input_field = PathInput(self) @@ -1122,34 +1115,32 @@ class EnumeratorWidget(QtWidgets.QWidget, InputObject): value_changed = QtCore.Signal(object) def __init__( - self, input_data, parent, - as_widget=False, label_widget=None, parent_widget=None + self, schema_data, parent, as_widget=False, parent_widget=None ): if parent_widget is None: parent_widget = parent super(EnumeratorWidget, self).__init__(parent_widget) - self.initial_attributes(input_data, parent, as_widget) - self.multiselection = input_data.get("multiselection") - self.enum_items = input_data["enum_items"] + self.initial_attributes(schema_data, parent, as_widget) + self.multiselection = schema_data.get("multiselection") + self.enum_items = schema_data["enum_items"] if not self.enum_items: raise ValueError("Attribute `enum_items` is not defined.") + def create_ui(self, label_widget=None): layout = QtWidgets.QHBoxLayout(self) layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(5) - if not self._as_widget: - self.key = input_data["key"] - if not label_widget: - label = input_data["label"] - label_widget = QtWidgets.QLabel(label) - label_widget.setAttribute(QtCore.Qt.WA_TranslucentBackground) - layout.addWidget(label_widget, 0) + if not self._as_widget and not label_widget: + label = self.schema_data["label"] + label_widget = QtWidgets.QLabel(label) + label_widget.setAttribute(QtCore.Qt.WA_TranslucentBackground) + layout.addWidget(label_widget, 0) self.label_widget = label_widget if self.multiselection: - placeholder = input_data.get("placeholder") + placeholder = self.schema_data.get("placeholder") self.input_field = MultiSelectionComboBox( placeholder=placeholder, parent=self ) @@ -1276,15 +1267,17 @@ class RawJsonWidget(QtWidgets.QWidget, InputObject): allow_to_environment = True def __init__( - self, input_data, parent, - as_widget=False, label_widget=None, parent_widget=None + self, schema_data, parent, as_widget=False, parent_widget=None ): if parent_widget is None: parent_widget = parent super(RawJsonWidget, self).__init__(parent_widget) - self.initial_attributes(input_data, parent, as_widget) + self.initial_attributes(schema_data, parent, as_widget) + # By default must be invalid + self._is_invalid = True + def create_ui(self, label_widget=None): layout = QtWidgets.QHBoxLayout(self) layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(5) @@ -1294,16 +1287,13 @@ class RawJsonWidget(QtWidgets.QWidget, InputObject): QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.MinimumExpanding ) - self._is_invalid = self.input_field.has_invalid_value() self.setFocusProxy(self.input_field) - if not self.as_widget: - self.key = input_data["key"] - if not label_widget: - label = input_data["label"] - label_widget = QtWidgets.QLabel(label) - layout.addWidget(label_widget, 0, alignment=QtCore.Qt.AlignTop) + if not self.as_widget and not label_widget: + label = self.schema_data["label"] + label_widget = QtWidgets.QLabel(label) + layout.addWidget(label_widget, 0, alignment=QtCore.Qt.AlignTop) self.label_widget = label_widget layout.addWidget(self.input_field, 1, alignment=QtCore.Qt.AlignTop) @@ -1408,9 +1398,9 @@ class ListItem(QtWidgets.QWidget, SettingObject): self.value_input = ItemKlass( item_schema, self, - as_widget=True, - label_widget=None + as_widget=True ) + self.value_input.create_ui() layout.addWidget(self.value_input, 1) @@ -1540,17 +1530,18 @@ class ListWidget(QtWidgets.QWidget, InputObject): valid_value_types = (list, ) def __init__( - self, input_data, parent, - as_widget=False, label_widget=None, parent_widget=None + self, schema_data, parent, as_widget=False, parent_widget=None ): if parent_widget is None: parent_widget = parent super(ListWidget, self).__init__(parent_widget) self.setObjectName("ListWidget") - self.initial_attributes(input_data, parent, as_widget) + self.initial_attributes(schema_data, parent, as_widget) - object_type = input_data["object_type"] + self.input_fields = [] + + object_type = schema_data["object_type"] if isinstance(object_type, dict): self.item_schema = object_type else: @@ -1558,7 +1549,7 @@ class ListWidget(QtWidgets.QWidget, InputObject): "type": object_type } # Backwards compatibility - input_modifiers = input_data.get("input_modifiers") or {} + input_modifiers = schema_data.get("input_modifiers") or {} if input_modifiers: self.log.warning(( "Used deprecated key `input_modifiers` to define item." @@ -1566,17 +1557,14 @@ class ListWidget(QtWidgets.QWidget, InputObject): )) self.item_schema.update(input_modifiers) - self.input_fields = [] - + def create_ui(self, label_widget=None): layout = QtWidgets.QHBoxLayout(self) layout.setContentsMargins(0, 0, 0, 5) layout.setSpacing(5) - if not self.as_widget: - self.key = input_data["key"] - if not label_widget: - label_widget = QtWidgets.QLabel(input_data["label"], self) - layout.addWidget(label_widget, alignment=QtCore.Qt.AlignTop) + if not self.as_widget and not label_widget: + label_widget = QtWidgets.QLabel(self.schema_data["label"], self) + layout.addWidget(label_widget, alignment=QtCore.Qt.AlignTop) self.label_widget = label_widget @@ -1788,39 +1776,39 @@ class ListStrictWidget(QtWidgets.QWidget, InputObject): valid_value_types = (list, ) def __init__( - self, input_data, parent, - as_widget=False, label_widget=None, parent_widget=None + self, schema_data, parent, as_widget=False, parent_widget=None ): if parent_widget is None: parent_widget = parent super(ListStrictWidget, self).__init__(parent_widget) self.setObjectName("ListStrictWidget") - self.initial_attributes(input_data, parent, as_widget) + self.initial_attributes(schema_data, parent, as_widget) + + self.is_horizontal = schema_data.get("horizontal", True) + self.object_types = self.schema_data["object_types"] self.input_fields = [] + def create_ui(self, label_widget=None): layout = QtWidgets.QHBoxLayout(self) layout.setContentsMargins(0, 0, 0, 5) layout.setSpacing(5) - if not self.as_widget: - self.key = input_data["key"] - if not label_widget: - label_widget = QtWidgets.QLabel(input_data["label"], self) - layout.addWidget(label_widget, alignment=QtCore.Qt.AlignTop) + if not self.as_widget and not label_widget: + label_widget = QtWidgets.QLabel(self.schema_data["label"], self) + layout.addWidget(label_widget, alignment=QtCore.Qt.AlignTop) self.label_widget = label_widget - self._add_children(layout, input_data) + self._add_children(layout) - def _add_children(self, layout, input_data): + def _add_children(self, layout): inputs_widget = QtWidgets.QWidget(self) inputs_widget.setAttribute(QtCore.Qt.WA_TranslucentBackground) layout.addWidget(inputs_widget) - horizontal = input_data.get("horizontal", True) - if horizontal: + if self.is_horizontal: inputs_layout = QtWidgets.QHBoxLayout(inputs_widget) else: inputs_layout = QtWidgets.QGridLayout(inputs_widget) @@ -1832,7 +1820,7 @@ class ListStrictWidget(QtWidgets.QWidget, InputObject): self.inputs_layout = inputs_layout children_item_mapping = [] - for child_configuration in input_data["object_types"]: + for child_configuration in self.object_types: item_widget = ListItem( child_configuration, self, self.inputs_widget, is_strict=True ) @@ -1847,7 +1835,7 @@ class ListStrictWidget(QtWidgets.QWidget, InputObject): children_item_mapping.append((label_widget, item_widget)) - if horizontal: + if self.is_horizontal: self._add_children_horizontally(children_item_mapping) else: self._add_children_vertically(children_item_mapping) @@ -1977,9 +1965,10 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): self.value_input = ItemKlass( item_schema, self, - as_widget=True, - label_widget=None + as_widget=True ) + self.value_input.create_ui() + self.add_btn = QtWidgets.QPushButton("+") self.remove_btn = QtWidgets.QPushButton("-") @@ -2138,22 +2127,25 @@ class ModifiableDict(QtWidgets.QWidget, InputObject): valid_value_types = (dict, ) def __init__( - self, input_data, parent, - as_widget=False, label_widget=None, parent_widget=None + self, schema_data, parent, as_widget=False, parent_widget=None ): if parent_widget is None: parent_widget = parent super(ModifiableDict, self).__init__(parent_widget) self.setObjectName("ModifiableDict") - self.initial_attributes(input_data, parent, as_widget) + self.initial_attributes(schema_data, parent, as_widget) self.input_fields = [] - self.key = input_data["key"] - self.value_is_env_group = input_data.get("value_is_env_group") or False + # Validation of "key" key + self.key = schema_data["key"] + self.value_is_env_group = ( + schema_data.get("value_is_env_group") or False + ) + self.hightlight_content = self.schema_data.get("highlight_content") - object_type = input_data["object_type"] + object_type = schema_data["object_type"] if isinstance(object_type, dict): self.item_schema = object_type else: @@ -2161,7 +2153,7 @@ class ModifiableDict(QtWidgets.QWidget, InputObject): self.item_schema = { "type": object_type } - input_modifiers = input_data.get("input_modifiers") or {} + input_modifiers = schema_data.get("input_modifiers") or {} if input_modifiers: self.log.warning(( "Used deprecated key `input_modifiers` to define item." @@ -2172,7 +2164,8 @@ class ModifiableDict(QtWidgets.QWidget, InputObject): if self.value_is_env_group: self.item_schema["env_group_key"] = "" - if input_data.get("highlight_content", False): + def create_ui(self, label_widget=None): + if self.hightlight_content: content_state = "hightlighted" bottom_margin = 5 else: @@ -2183,9 +2176,9 @@ class ModifiableDict(QtWidgets.QWidget, InputObject): main_layout.setContentsMargins(0, 0, 0, 0) main_layout.setSpacing(0) - label = input_data.get("label") + label = self.schema_data.get("label") - if as_widget: + if self.as_widget: body_widget = None self.label_widget = label_widget @@ -2193,7 +2186,7 @@ class ModifiableDict(QtWidgets.QWidget, InputObject): body_widget = None self.label_widget = None else: - body_widget = ExpandingWidget(input_data["label"], self) + body_widget = ExpandingWidget(self.schema_data["label"], self) main_layout.addWidget(body_widget) self.label_widget = body_widget.label_widget @@ -2221,9 +2214,9 @@ class ModifiableDict(QtWidgets.QWidget, InputObject): self.content_layout = content_layout if body_widget: - collapsable = input_data.get("collapsable", True) + collapsable = self.schema_data.get("collapsable", True) if collapsable: - collapsed = input_data.get("collapsed", True) + collapsed = self.schema_data.get("collapsed", True) if not collapsed: body_widget.toggle_content() @@ -2416,29 +2409,31 @@ class DictWidget(QtWidgets.QWidget, SettingObject): valid_value_types = (dict, type(NOT_SET)) def __init__( - self, input_data, parent, - as_widget=False, label_widget=None, parent_widget=None + self, schema_data, parent, as_widget=False, parent_widget=None ): if parent_widget is None: parent_widget = parent super(DictWidget, self).__init__(parent_widget) - self.initial_attributes(input_data, parent, as_widget) + self.initial_attributes(schema_data, parent, as_widget) self.input_fields = [] self.checkbox_widget = None - self.checkbox_key = input_data.get("checkbox_key") + self.checkbox_key = schema_data.get("checkbox_key") - if not self.as_widget: - self.key = input_data["key"] + self.highlight_content = schema_data.get("highlight_content", False) + self.show_borders = schema_data.get("show_borders", True) + self.collapsable = schema_data.get("collapsable", True) + self.collapsed = schema_data.get("collapsed", True) - if not self.as_widget and input_data.get("label") is None: + def create_ui(self, label_widget=None): + if not self.as_widget and self.schema_data.get("label") is None: self._ui_item_without_label() else: - self._ui_item_or_as_widget(input_data, label_widget) + self._ui_item_or_as_widget(label_widget) - for child_data in input_data.get("children", []): + for child_data in self.schema_data.get("children", []): self.add_children_gui(child_data) any_visible = False @@ -2464,14 +2459,12 @@ class DictWidget(QtWidgets.QWidget, SettingObject): self.content_layout.setContentsMargins(0, 0, 0, 0) self.content_layout.setSpacing(5) - def _ui_item_or_as_widget(self, input_data, label_widget): + def _ui_item_or_as_widget(self, label_widget): content_widget = QtWidgets.QWidget(self) if self.as_widget: content_widget.setObjectName("DictAsWidgetBody") - show_borders = str( - int(input_data.get("show_borders", True)) - ) + show_borders = str(int(self.show_borders)) content_widget.setProperty("show_borders", show_borders) content_layout_margins = (5, 5, 5, 5) main_layout_spacing = 5 @@ -2479,7 +2472,7 @@ class DictWidget(QtWidgets.QWidget, SettingObject): else: content_widget.setObjectName("ContentWidget") - if input_data.get("highlight_content", False): + if self.highlight_content: content_state = "hightlighted" bottom_margin = 5 else: @@ -2489,7 +2482,7 @@ class DictWidget(QtWidgets.QWidget, SettingObject): content_layout_margins = (CHILD_OFFSET, 5, 0, bottom_margin) main_layout_spacing = 0 - body_widget = ExpandingWidget(input_data["label"], self) + body_widget = ExpandingWidget(self.schema_data["label"], self) label_widget = body_widget.label_widget body_widget.set_content_widget(content_widget) @@ -2509,13 +2502,11 @@ class DictWidget(QtWidgets.QWidget, SettingObject): self.content_layout = content_layout if body_widget: - collapsable = input_data.get("collapsable", True) if len(self.input_fields) == 1 and self.checkbox_widget: body_widget.hide_toolbox(hide_content=True) - elif collapsable: - collapsed = input_data.get("collapsed", True) - if not collapsed: + elif self.collapsable: + if not self.collapsed: body_widget.toggle_content() else: body_widget.hide_toolbox(hide_content=False) @@ -2547,13 +2538,14 @@ class DictWidget(QtWidgets.QWidget, SettingObject): return self._add_checkbox_child(child_configuration) label_widget = None - if not klass.expand_in_grid: + item = klass(child_configuration, self) + if not item.expand_in_grid: label = child_configuration.get("label") if label is not None: label_widget = GridLabelWidget(label, self) self.content_layout.addWidget(label_widget, row, 0, 1, 1) - item = klass(child_configuration, self, label_widget=label_widget) + item.create_ui(label_widget=label_widget) item.value_changed.connect(self._on_value_change) if label_widget: @@ -2569,8 +2561,9 @@ class DictWidget(QtWidgets.QWidget, SettingObject): def _add_checkbox_child(self, child_configuration): item = BooleanWidget( - child_configuration, self, label_widget=self.label_widget + child_configuration, self ) + item.create_ui(label_widget=self.label_widget) item.value_changed.connect(self._on_value_change) self.body_widget.add_widget_before_label(item) @@ -2872,14 +2865,13 @@ class PathWidget(QtWidgets.QWidget, SettingObject): } def __init__( - self, input_data, parent, - as_widget=False, label_widget=None, parent_widget=None + self, schema_data, parent, as_widget=False, parent_widget=None ): if parent_widget is None: parent_widget = parent super(PathWidget, self).__init__(parent_widget) - self.initial_attributes(input_data, parent, as_widget) + self.initial_attributes(schema_data, parent, as_widget) # This is partial input and dictionary input if not self.any_parent_is_group and not self._as_widget: @@ -2887,22 +2879,20 @@ class PathWidget(QtWidgets.QWidget, SettingObject): else: self._is_group = False - self.multiplatform = input_data.get("multiplatform", False) - self.multipath = input_data.get("multipath", False) + self.multiplatform = schema_data.get("multiplatform", False) + self.multipath = schema_data.get("multipath", False) self.input_field = None + def create_ui(self, label_widget=None): layout = QtWidgets.QHBoxLayout(self) layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(5) - if not self.as_widget: - self.key = input_data["key"] - if not label_widget: - label = input_data["label"] - label_widget = QtWidgets.QLabel(label) - label_widget.setAttribute(QtCore.Qt.WA_TranslucentBackground) - layout.addWidget(label_widget, 0, alignment=QtCore.Qt.AlignTop) + if not self.as_widget and not label_widget: + label_widget = QtWidgets.QLabel(self.schema_data["label"]) + label_widget.setAttribute(QtCore.Qt.WA_TranslucentBackground) + layout.addWidget(label_widget, 0, alignment=QtCore.Qt.AlignTop) self.label_widget = label_widget self.content_widget = QtWidgets.QWidget(self) @@ -2912,7 +2902,7 @@ class PathWidget(QtWidgets.QWidget, SettingObject): layout.addWidget(self.content_widget) - self.create_gui() + self.create_ui_inputs() @property def default_input_value(self): @@ -2928,13 +2918,12 @@ class PathWidget(QtWidgets.QWidget, SettingObject): } return value_type() - def create_gui(self): + def create_ui_inputs(self): if not self.multiplatform and not self.multipath: input_data = {"key": self.key} - path_input = PathInputWidget( - input_data, self, - as_widget=True, label_widget=self.label_widget - ) + path_input = PathInputWidget(input_data, self, as_widget=True) + path_input.create_ui(label_widget=self.label_widget) + self.setFocusProxy(path_input) self.content_layout.addWidget(path_input) self.input_field = path_input @@ -2946,10 +2935,8 @@ class PathWidget(QtWidgets.QWidget, SettingObject): "key": self.key, "object_type": "path-input" } - input_widget = ListWidget( - item_schema, self, - as_widget=True, label_widget=self.label_widget - ) + input_widget = ListWidget(item_schema, self, as_widget=True) + input_widget.create_ui(label_widget=self.label_widget) self.setFocusProxy(input_widget) self.content_layout.addWidget(input_widget) self.input_field = input_widget @@ -2975,9 +2962,9 @@ class PathWidget(QtWidgets.QWidget, SettingObject): item_schema["children"].append(child_item) - input_widget = DictWidget( - item_schema, self, as_widget=True, label_widget=self.label_widget - ) + input_widget = DictWidget(item_schema, self, as_widget=True) + input_widget.create_ui(label_widget=self.label_widget) + self.content_layout.addWidget(input_widget) self.input_field = input_widget input_widget.value_changed.connect(self._on_value_change) @@ -3221,23 +3208,24 @@ class DictFormWidget(QtWidgets.QWidget, SettingObject): expand_in_grid = True def __init__( - self, input_data, parent, - as_widget=False, label_widget=None, parent_widget=None + self, schema_data, parent, as_widget=False, parent_widget=None ): if parent_widget is None: parent_widget = parent super(DictFormWidget, self).__init__(parent_widget) - self.initial_attributes(input_data, parent, as_widget) + self.initial_attributes(schema_data, parent, as_widget) self._as_widget = False self._is_group = False self.input_fields = [] + + def create_ui(self, label_widget=None): self.content_layout = QtWidgets.QFormLayout(self) self.content_layout.setContentsMargins(0, 0, 0, 0) - for child_data in input_data.get("children", []): + for child_data in self.schema_data.get("children", []): self.add_children_gui(child_data) self.setAttribute(QtCore.Qt.WA_TranslucentBackground) @@ -3260,7 +3248,8 @@ class DictFormWidget(QtWidgets.QWidget, SettingObject): label_widget = FormLabel(label, self) - item = klass(child_configuration, self, label_widget=label_widget) + item = klass(child_configuration, self) + item.create_ui(label_widget=label_widget) label_widget.item = item if item.hidden_by_role: From 5877e2246d8b324b87520b1a251b3a30f077512b Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 27 Nov 2020 11:49:30 +0100 Subject: [PATCH 03/39] added `is_wrapper_item` to determine if item may have any clue about it's `key` --- .../settings/settings/widgets/item_types.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index 387398a32b..318f264f40 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -37,6 +37,9 @@ class SettingObject: """Partially abstract class for Setting's item type workflow.""" # `is_input_type` attribute says if has implemented item type methods is_input_type = True + # `is_wrapper_item` attribute says if item will never hold `key` + # information and is just visually different + is_wrapper_item = False # Each input must have implemented default value for development # when defaults are not filled yet. default_input_value = NOT_SET @@ -180,7 +183,17 @@ class SettingObject: self.hide() self.hidden_by_role = True - if not self.as_widget: + if ( + self.is_input_type + and not self.as_widget + and not self.is_wrapper_item + ): + if "key" not in self.schema_data: + error_msg = "Missing \"key\" in schema data. {}".format( + str(schema_data).replace("'", '"') + ) + raise KeyError(error_msg) + self.key = self.schema_data["key"] @property @@ -3206,6 +3219,7 @@ class DictFormWidget(QtWidgets.QWidget, SettingObject): value_changed = QtCore.Signal(object) allow_actions = False expand_in_grid = True + is_wrapper_item = True def __init__( self, schema_data, parent, as_widget=False, parent_widget=None From 170d1b01883ae9103f90e0f538b118f5e2b5e2ea Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 27 Nov 2020 14:25:56 +0100 Subject: [PATCH 04/39] fixed Expanding widget --- pype/tools/settings/settings/widgets/widgets.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/pype/tools/settings/settings/widgets/widgets.py b/pype/tools/settings/settings/widgets/widgets.py index b64b1aa8ac..6135f8dcb2 100644 --- a/pype/tools/settings/settings/widgets/widgets.py +++ b/pype/tools/settings/settings/widgets/widgets.py @@ -112,7 +112,7 @@ class ExpandingWidget(QtWidgets.QWidget): before_label_layout.setContentsMargins(0, 0, 0, 0) after_label_widget = QtWidgets.QWidget(side_line_widget) - after_label_layout = QtWidgets.QVBoxLayout(after_label_widget) + after_label_layout = QtWidgets.QHBoxLayout(after_label_widget) after_label_layout.setContentsMargins(0, 0, 0, 0) spacer_widget = QtWidgets.QWidget(side_line_widget) @@ -158,6 +158,12 @@ class ExpandingWidget(QtWidgets.QWidget): self.content_widget.setVisible(not hide_content) self.parent().updateGeometry() + def show_toolbox(self): + self.toolbox_hidden = False + self.toggle_content(self.button_toggle.isChecked()) + + self.parent().updateGeometry() + def set_content_widget(self, content_widget): content_widget.setVisible(False) self.main_layout.addWidget(content_widget) From 3c0de1cbd42a1e64af76d700580eb41e6e971431 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 27 Nov 2020 14:33:38 +0100 Subject: [PATCH 05/39] preparations for labeled item --- .../settings/settings/widgets/item_types.py | 38 ++++++++++++++----- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index 318f264f40..f83e406815 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -1970,11 +1970,11 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(3) - ItemKlass = TypeToKlass.types[item_schema["type"]] self.key_input = QtWidgets.QLineEdit(self) self.key_input.setObjectName("DictKey") + ItemKlass = TypeToKlass.types[item_schema["type"]] self.value_input = ItemKlass( item_schema, self, @@ -2013,6 +2013,10 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): self.origin_key = NOT_SET + @property + def labeled_items(self): + return self._parent.labeled_items + def key_value(self): return self.key_input.text() @@ -2028,8 +2032,9 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): return False def _on_key_change(self): + value = self.key_input.text() if self.value_is_env_group: - self.value_input.env_group_key = self.key_input.text() + self.value_input.env_group_key = value self._on_value_change() def _on_value_change(self, item=None): @@ -2066,6 +2071,9 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): self._parent.add_row(row=self.row() + 1) def on_remove_clicked(self): + self.remove_row() + + def remove_row(self): self._parent.remove_row(self) def set_as_empty(self, is_empty=True): @@ -2156,7 +2164,8 @@ class ModifiableDict(QtWidgets.QWidget, InputObject): self.value_is_env_group = ( schema_data.get("value_is_env_group") or False ) - self.hightlight_content = self.schema_data.get("highlight_content") + self.hightlight_content = schema_data.get("highlight_content") or False + self.labeled_items = schema_data.get("labeled_items") or False object_type = schema_data["object_type"] if isinstance(object_type, dict): @@ -2365,15 +2374,24 @@ class ModifiableDict(QtWidgets.QWidget, InputObject): self.input_fields.insert(row, item_widget) previous_input = None - for input_field in self.input_fields: - if previous_input is not None: + if self.labeled_items: + for input_field in self.input_fields: + if previous_input is not None: + self.setTabOrder( + previous_input, input_field.value_input + ) + previous_input = input_field.value_input.focusProxy() + + else: + for input_field in self.input_fields: + if previous_input is not None: + self.setTabOrder( + previous_input, input_field.key_input + ) + previous_input = input_field.value_input.focusProxy() self.setTabOrder( - previous_input, input_field.key_input + input_field.key_input, previous_input ) - previous_input = input_field.value_input.focusProxy() - self.setTabOrder( - input_field.key_input, previous_input - ) # Set value if entered value is not None # else (when add button clicked) trigger `_on_value_change` From 6f6678a5bf50c5dbb6f5c9fcb14fda6ee227e97d Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 27 Nov 2020 14:35:58 +0100 Subject: [PATCH 06/39] moved key input --- pype/tools/settings/settings/widgets/item_types.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index f83e406815..c35ae96635 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -1971,8 +1971,6 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): layout.setSpacing(3) - self.key_input = QtWidgets.QLineEdit(self) - self.key_input.setObjectName("DictKey") ItemKlass = TypeToKlass.types[item_schema["type"]] self.value_input = ItemKlass( @@ -1984,6 +1982,8 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): self.add_btn = QtWidgets.QPushButton("+") self.remove_btn = QtWidgets.QPushButton("-") + self.key_input = QtWidgets.QLineEdit(self.wrapper_widget or self) + self.key_input.setObjectName("DictKey") self.add_btn.setFocusPolicy(QtCore.Qt.ClickFocus) self.remove_btn.setFocusPolicy(QtCore.Qt.ClickFocus) From d7289f0fc091ca7b9d4a94bd99f21a70b624c9ce Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 27 Nov 2020 14:36:15 +0100 Subject: [PATCH 07/39] different init if labeld item --- .../settings/settings/widgets/item_types.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index c35ae96635..716b63cf91 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -1966,11 +1966,25 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): self._is_empty = False self.is_key_duplicated = False - layout = QtWidgets.QHBoxLayout(self) + if self.labeled_items: + layout = QtWidgets.QVBoxLayout(self) + else: + layout = QtWidgets.QHBoxLayout(self) + layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(3) + self.wrapper_widget = None + if self.labeled_items: + self.wrapper_widget = ExpandingWidget("", self) + layout.addWidget(self.wrapper_widget) + content_widget = QtWidgets.QWidget(self.wrapper_widget) + content_layout = QtWidgets.QHBoxLayout(content_widget) + content_layout.setContentsMargins(0, 0, 0, 0) + content_layout.setSpacing(3) + + self.wrapper_widget.set_content_widget(content_widget) ItemKlass = TypeToKlass.types[item_schema["type"]] self.value_input = ItemKlass( From c9c23658112a10f053a09378fda9d7236f80217f Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 27 Nov 2020 14:48:15 +0100 Subject: [PATCH 08/39] set_as_empty has separated logic --- .../settings/settings/widgets/item_types.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index 716b63cf91..aa265caec9 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -2093,10 +2093,22 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): def set_as_empty(self, is_empty=True): self._is_empty = is_empty - self.key_input.setVisible(not is_empty) self.value_input.setVisible(not is_empty) - self.remove_btn.setEnabled(not is_empty) - self.spacer_widget.setVisible(is_empty) + self.add_btn.setVisible(is_empty) + if not self.labeled_items: + self.key_input.setVisible(not is_empty) + self.remove_btn.setEnabled(not is_empty) + self.spacer_widget.setVisible(is_empty) + + else: + self.key_input.setVisible(is_empty) + self.edit_btn.setVisible(not is_empty) + + self.wrapper_widget.label_widget.setVisible(not is_empty) + if is_empty: + self.wrapper_widget.hide_toolbox() + else: + self.wrapper_widget.show_toolbox() self._on_value_change() @property From aae2d448dd4f14e88eee8eb17dea5b788bb55251 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 27 Nov 2020 14:49:00 +0100 Subject: [PATCH 09/39] add_clicked has separated logic --- .../settings/settings/widgets/item_types.py | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index aa265caec9..e16fd0700c 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -2079,10 +2079,21 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): return self._parent.is_group def on_add_clicked(self): - if self._is_empty: - self.set_as_empty(False) - else: - self._parent.add_row(row=self.row() + 1) + if not self.labeled_items: + if self._is_empty: + self.set_as_empty(False) + else: + self._parent.add_row(row=self.row() + 1) + return + + if not self._is_empty: + return + + if not self.key_value(): + return + + self.set_as_empty(False) + self._parent.add_row(row=self.row() + 1, is_empty=True) def on_remove_clicked(self): self.remove_row() From ea19cfcae075b8d46ece5e242422e0fc03310310 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 27 Nov 2020 14:49:22 +0100 Subject: [PATCH 10/39] change_key_label implemented to change label --- pype/tools/settings/settings/widgets/item_types.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index e16fd0700c..db8f8aa973 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -2049,6 +2049,7 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): value = self.key_input.text() if self.value_is_env_group: self.value_input.env_group_key = value + self.change_key_label(value) self._on_value_change() def _on_value_change(self, item=None): @@ -2078,6 +2079,10 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): def is_group(self): return self._parent.is_group + def change_key_label(self, label): + if self.wrapper_widget: + self.wrapper_widget.label_widget.setText(label) + def on_add_clicked(self): if not self.labeled_items: if self._is_empty: From 96b8916147d2cf1780df8c7ed4cd7a103023e971 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 27 Nov 2020 14:50:06 +0100 Subject: [PATCH 11/39] implemented empty `on_edit_clicked` method --- pype/tools/settings/settings/widgets/item_types.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index db8f8aa973..aac2c6aa37 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -2100,6 +2100,9 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): self.set_as_empty(False) self._parent.add_row(row=self.row() + 1, is_empty=True) + def on_edit_clicked(self): + print("Edit triggered") + def on_remove_clicked(self): self.remove_row() From f69ec9f45ef04d9bbb185c1800a665ef2a7e3b2f Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 27 Nov 2020 14:50:19 +0100 Subject: [PATCH 12/39] separated item initialization --- .../settings/settings/widgets/item_types.py | 109 +++++++++++------- 1 file changed, 70 insertions(+), 39 deletions(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index aac2c6aa37..265911f914 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -1966,6 +1966,8 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): self._is_empty = False self.is_key_duplicated = False + self.origin_key = NOT_SET + if self.labeled_items: layout = QtWidgets.QVBoxLayout(self) else: @@ -1974,58 +1976,87 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(3) - self.wrapper_widget = None - if self.labeled_items: - self.wrapper_widget = ExpandingWidget("", self) - layout.addWidget(self.wrapper_widget) - - content_widget = QtWidgets.QWidget(self.wrapper_widget) - content_layout = QtWidgets.QHBoxLayout(content_widget) - content_layout.setContentsMargins(0, 0, 0, 0) - content_layout.setSpacing(3) - - self.wrapper_widget.set_content_widget(content_widget) - ItemKlass = TypeToKlass.types[item_schema["type"]] - self.value_input = ItemKlass( + value_input = ItemKlass( item_schema, self, as_widget=True ) - self.value_input.create_ui() + value_input.create_ui() - self.add_btn = QtWidgets.QPushButton("+") - self.remove_btn = QtWidgets.QPushButton("-") - self.key_input = QtWidgets.QLineEdit(self.wrapper_widget or self) - self.key_input.setObjectName("DictKey") + wrapper_widget = None + if self.labeled_items: + wrapper_widget = ExpandingWidget("", self) + layout.addWidget(wrapper_widget) - self.add_btn.setFocusPolicy(QtCore.Qt.ClickFocus) - self.remove_btn.setFocusPolicy(QtCore.Qt.ClickFocus) + content_widget = QtWidgets.QWidget(wrapper_widget) + content_layout = QtWidgets.QHBoxLayout(content_widget) + content_layout.setContentsMargins(0, 0, 0, 0) + content_layout.setSpacing(3) - self.add_btn.setProperty("btn-type", "tool-item") - self.remove_btn.setProperty("btn-type", "tool-item") + wrapper_widget.set_content_widget(content_widget) - self.spacer_widget = QtWidgets.QWidget(self) - self.spacer_widget.setAttribute(QtCore.Qt.WA_TranslucentBackground) - self.spacer_widget.setVisible(False) + content_layout.addWidget(value_input) - layout.addWidget(self.add_btn, 0) - layout.addWidget(self.remove_btn, 0) - layout.addWidget(self.key_input, 0) - layout.addWidget(self.spacer_widget, 1) - layout.addWidget(self.value_input, 1) + key_input = QtWidgets.QLineEdit(wrapper_widget or self) + key_input.setObjectName("DictKey") - self.setFocusProxy(self.value_input) + spacer_widget = None + if not self.labeled_items: + spacer_widget = QtWidgets.QWidget(self) + spacer_widget.setAttribute(QtCore.Qt.WA_TranslucentBackground) + spacer_widget.setVisible(False) - self.add_btn.setFixedSize(self._btn_size, self._btn_size) - self.remove_btn.setFixedSize(self._btn_size, self._btn_size) - self.add_btn.clicked.connect(self.on_add_clicked) - self.remove_btn.clicked.connect(self.on_remove_clicked) + add_btn = QtWidgets.QPushButton("+") + add_btn.setFocusPolicy(QtCore.Qt.ClickFocus) + add_btn.setProperty("btn-type", "tool-item") + add_btn.setFixedSize(self._btn_size, self._btn_size) - self.key_input.textChanged.connect(self._on_key_change) - self.value_input.value_changed.connect(self._on_value_change) + edit_btn = None + remove_btn = None + if self.labeled_items: + edit_btn = QtWidgets.QPushButton("Edit") + edit_btn.setFocusPolicy(QtCore.Qt.ClickFocus) + edit_btn.setProperty("btn-type", "tool-item") + edit_btn.setFixedSize(self._btn_size, self._btn_size) + else: + remove_btn = QtWidgets.QPushButton("-") + remove_btn.setFocusPolicy(QtCore.Qt.ClickFocus) + remove_btn.setProperty("btn-type", "tool-item") + remove_btn.setFixedSize(self._btn_size, self._btn_size) - self.origin_key = NOT_SET + if self.labeled_items: + wrapper_widget.add_widget_after_label(key_input) + wrapper_widget.add_widget_after_label(add_btn) + wrapper_widget.add_widget_after_label(edit_btn) + + else: + layout.addWidget(add_btn, 0) + layout.addWidget(remove_btn, 0) + layout.addWidget(key_input, 0) + layout.addWidget(spacer_widget, 1) + layout.addWidget(value_input, 1) + + self.setFocusProxy(value_input) + + key_input.textChanged.connect(self._on_key_change) + value_input.value_changed.connect(self._on_value_change) + add_btn.clicked.connect(self.on_add_clicked) + if edit_btn: + edit_btn.clicked.connect(self.on_edit_clicked) + if remove_btn: + remove_btn.clicked.connect(self.on_remove_clicked) + + self.key_input = key_input + self.value_input = value_input + + self.wrapper_widget = wrapper_widget + + self.spacer_widget = spacer_widget + + self.add_btn = add_btn + self.edit_btn = edit_btn + self.remove_btn = remove_btn @property def labeled_items(self): @@ -2101,7 +2132,7 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): self._parent.add_row(row=self.row() + 1, is_empty=True) def on_edit_clicked(self): - print("Edit triggered") + pass def on_remove_clicked(self): self.remove_row() From 6a98818834f663ca147001e94c61827514004ded Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 27 Nov 2020 15:03:13 +0100 Subject: [PATCH 13/39] handledimplemented basic adding new items --- .../settings/settings/widgets/item_types.py | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index 265911f914..e678651545 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -2000,6 +2000,11 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): key_input = QtWidgets.QLineEdit(wrapper_widget or self) key_input.setObjectName("DictKey") + if self.labeled_items: + def focused_out(event): + super(QtWidgets.QLineEdit, key_input).focusOutEvent(event) + self._on_enter_press() + key_input.focusOutEvent = focused_out spacer_widget = None if not self.labeled_items: @@ -2040,6 +2045,7 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): self.setFocusProxy(value_input) key_input.textChanged.connect(self._on_key_change) + key_input.returnPressed.connect(self._on_enter_press) value_input.value_changed.connect(self._on_value_change) add_btn.clicked.connect(self.on_add_clicked) if edit_btn: @@ -2076,6 +2082,15 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): return True return False + def _on_enter_press(self): + if not self.labeled_items: + return + + if self._is_empty: + self.on_add_clicked() + else: + self.set_edit_mode(False) + def _on_key_change(self): value = self.key_input.text() if self.value_is_env_group: @@ -2132,7 +2147,11 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): self._parent.add_row(row=self.row() + 1, is_empty=True) def on_edit_clicked(self): - pass + self.set_edit_mode() + + def set_edit_mode(self, enabled=True): + self.key_input.setVisible(enabled) + self.wrapper_widget.label_widget.setVisible(not enabled) def on_remove_clicked(self): self.remove_row() From 06413e5a1bf0a525a0e687438d81a9d14c3e71f0 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 27 Nov 2020 15:09:58 +0100 Subject: [PATCH 14/39] fixed state styles --- pype/tools/settings/settings/widgets/item_types.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index e678651545..cd586a71ea 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -1998,7 +1998,7 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): content_layout.addWidget(value_input) - key_input = QtWidgets.QLineEdit(wrapper_widget or self) + key_input = QtWidgets.QLineEdit(self) key_input.setObjectName("DictKey") if self.labeled_items: def focused_out(event): From f6885cdd9cadc41cbeb89e58f99efa95a6d5ebf9 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 27 Nov 2020 15:10:16 +0100 Subject: [PATCH 15/39] fixed focus out --- pype/tools/settings/settings/widgets/item_types.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index cd586a71ea..e23390a7e4 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -2002,8 +2002,9 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): key_input.setObjectName("DictKey") if self.labeled_items: def focused_out(event): - super(QtWidgets.QLineEdit, key_input).focusOutEvent(event) + QtWidgets.QLineEdit.focusOutEvent(key_input, event) self._on_enter_press() + key_input.focusOutEvent = focused_out spacer_widget = None @@ -2150,8 +2151,10 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): self.set_edit_mode() def set_edit_mode(self, enabled=True): - self.key_input.setVisible(enabled) self.wrapper_widget.label_widget.setVisible(not enabled) + self.key_input.setVisible(enabled) + if enabled: + self.key_input.setFocus() def on_remove_clicked(self): self.remove_row() From caf4d94b567a0ea922c18a185c9fc9979b3649b6 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 27 Nov 2020 15:29:33 +0100 Subject: [PATCH 16/39] key dulication is handled better --- .../settings/settings/widgets/item_types.py | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index e23390a7e4..775408cb25 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -1964,7 +1964,7 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): self._any_parent_is_group = True self._is_empty = False - self.is_key_duplicated = False + self._is_key_duplicated = False self.origin_key = NOT_SET @@ -2079,10 +2079,19 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): if self.key_value() == "": return True - if self.is_key_duplicated: + if self._is_key_duplicated: return True return False + def set_key_is_duplicated(self, duplicated): + if duplicated == self._is_key_duplicated: + return + + self._is_key_duplicated = duplicated + if duplicated and self.labeled_items: + self.set_edit_mode(True) + self.update_style() + def _on_enter_press(self): if not self.labeled_items: return @@ -2151,6 +2160,8 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): self.set_edit_mode() def set_edit_mode(self, enabled=True): + if self.is_invalid and not enabled: + return self.wrapper_widget.label_widget.setVisible(not enabled) self.key_input.setVisible(enabled) if enabled: @@ -2375,13 +2386,10 @@ class ModifiableDict(QtWidgets.QWidget, InputObject): for fields in fields_by_keys.values(): if len(fields) == 1: field = fields[0] - if field.is_key_duplicated: - field.is_key_duplicated = False - field.update_style() + field.set_key_is_duplicated(False) else: for field in fields: - field.is_key_duplicated = True - field.update_style() + field.set_key_is_duplicated(True) if self.is_overidable: self._is_overriden = True From 8c6ad61256c7b2cc27a196abc169bb4cfa8cc8f0 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 27 Nov 2020 15:29:44 +0100 Subject: [PATCH 17/39] content layout has better margins --- pype/tools/settings/settings/widgets/item_types.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index 775408cb25..8b689ecd1a 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -1991,8 +1991,8 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): content_widget = QtWidgets.QWidget(wrapper_widget) content_layout = QtWidgets.QHBoxLayout(content_widget) - content_layout.setContentsMargins(0, 0, 0, 0) - content_layout.setSpacing(3) + content_layout.setContentsMargins(CHILD_OFFSET, 5, 0, 0) + content_layout.setSpacing(5) wrapper_widget.set_content_widget(content_widget) From b7480065c5c0b55dd015b79fd8c8faedfeefeb0a Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 27 Nov 2020 16:44:30 +0100 Subject: [PATCH 18/39] few minor fixes --- .../settings/settings/widgets/item_types.py | 27 +++++++++++++------ 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index 8b689ecd1a..cb7a310945 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -1984,6 +1984,9 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): ) value_input.create_ui() + key_input = QtWidgets.QLineEdit(self) + key_input.setObjectName("DictKey") + wrapper_widget = None if self.labeled_items: wrapper_widget = ExpandingWidget("", self) @@ -1998,12 +2001,9 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): content_layout.addWidget(value_input) - key_input = QtWidgets.QLineEdit(self) - key_input.setObjectName("DictKey") - if self.labeled_items: def focused_out(event): QtWidgets.QLineEdit.focusOutEvent(key_input, event) - self._on_enter_press() + self._on_focus_lose() key_input.focusOutEvent = focused_out @@ -2034,7 +2034,7 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): if self.labeled_items: wrapper_widget.add_widget_after_label(key_input) wrapper_widget.add_widget_after_label(add_btn) - wrapper_widget.add_widget_after_label(edit_btn) + wrapper_widget.add_widget_before_label(edit_btn) else: layout.addWidget(add_btn, 0) @@ -2050,7 +2050,7 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): value_input.value_changed.connect(self._on_value_change) add_btn.clicked.connect(self.on_add_clicked) if edit_btn: - edit_btn.clicked.connect(self.on_edit_clicked) + edit_btn.clicked.connect(self.on_edit_pressed) if remove_btn: remove_btn.clicked.connect(self.on_remove_clicked) @@ -2092,6 +2092,14 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): self.set_edit_mode(True) self.update_style() + def _on_focus_lose(self): + if ( + self.key_input.hasFocus() + or self.edit_btn.hasFocus() + ): + return + self._on_enter_press() + def _on_enter_press(self): if not self.labeled_items: return @@ -2156,8 +2164,11 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): self.set_as_empty(False) self._parent.add_row(row=self.row() + 1, is_empty=True) - def on_edit_clicked(self): - self.set_edit_mode() + def on_edit_pressed(self): + if not self.key_input.isVisible(): + self.set_edit_mode() + else: + self.key_input.setFocus() def set_edit_mode(self, enabled=True): if self.is_invalid and not enabled: From 51f50cc5f4ef7e8411e137c1020ce1cfd0c27f7d Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 27 Nov 2020 16:45:54 +0100 Subject: [PATCH 19/39] implemented IconButton that just change color on hover --- .../settings/settings/widgets/widgets.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/pype/tools/settings/settings/widgets/widgets.py b/pype/tools/settings/settings/widgets/widgets.py index 6135f8dcb2..1ff5ce2fdc 100644 --- a/pype/tools/settings/settings/widgets/widgets.py +++ b/pype/tools/settings/settings/widgets/widgets.py @@ -1,4 +1,23 @@ from Qt import QtWidgets, QtCore, QtGui +from avalon.vendor import qtawesome + + +class IconButton(QtWidgets.QPushButton): + def __init__(self, icon_name, color, hover_color, *args, **kwargs): + super(IconButton, self).__init__(*args, **kwargs) + + self.icon = qtawesome.icon(icon_name, color=color) + self.hover_icon = qtawesome.icon(icon_name, color=hover_color) + + self.setIcon(self.icon) + + def enterEvent(self, event): + self.setIcon(self.hover_icon) + super(IconButton, self).enterEvent(event) + + def leaveEvent(self, event): + self.setIcon(self.icon) + super(IconButton, self).leaveEvent(event) class NumberSpinBox(QtWidgets.QDoubleSpinBox): From 012e62c370aa4d3595110bf3725688ddea09a195 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 27 Nov 2020 16:46:17 +0100 Subject: [PATCH 20/39] used IconButton for edit --- pype/tools/settings/settings/style/style.css | 5 +++++ pype/tools/settings/settings/widgets/item_types.py | 9 ++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/pype/tools/settings/settings/style/style.css b/pype/tools/settings/settings/style/style.css index dcc7a5effe..38fcd14448 100644 --- a/pype/tools/settings/settings/style/style.css +++ b/pype/tools/settings/settings/style/style.css @@ -97,6 +97,11 @@ QPushButton[btn-type="tool-item"]:hover { background-color: transparent; } +QPushButton[btn-type="tool-item-icon"] { + border: 0px solid #bfccd6; + background-color: transparent; +} + QPushButton[btn-type="expand-toggle"] { background: #1d272f; } diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index cb7a310945..e00f21a1e2 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -2,6 +2,7 @@ import json import collections from Qt import QtWidgets, QtCore, QtGui from .widgets import ( + IconButton, ExpandingWidget, NumberSpinBox, PathInput, @@ -2021,10 +2022,12 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): edit_btn = None remove_btn = None if self.labeled_items: - edit_btn = QtWidgets.QPushButton("Edit") + edit_btn = IconButton( + "fa.edit", QtCore.Qt.lightGray, QtCore.Qt.white + ) edit_btn.setFocusPolicy(QtCore.Qt.ClickFocus) - edit_btn.setProperty("btn-type", "tool-item") - edit_btn.setFixedSize(self._btn_size, self._btn_size) + edit_btn.setProperty("btn-type", "tool-item-icon") + edit_btn.setFixedHeight(self._btn_size) else: remove_btn = QtWidgets.QPushButton("-") remove_btn.setFocusPolicy(QtCore.Qt.ClickFocus) From 8ceeabc21bd5a34997ce5aa6260c7bee46ddda5e Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 27 Nov 2020 17:02:16 +0100 Subject: [PATCH 21/39] added label input --- .../settings/settings/widgets/item_types.py | 60 ++++++++++++++----- 1 file changed, 46 insertions(+), 14 deletions(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index e00f21a1e2..5b92754752 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -1988,8 +1988,11 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): key_input = QtWidgets.QLineEdit(self) key_input.setObjectName("DictKey") + key_label_input = None wrapper_widget = None if self.labeled_items: + key_label_input = QtWidgets.QLineEdit(self) + wrapper_widget = ExpandingWidget("", self) layout.addWidget(wrapper_widget) @@ -2002,11 +2005,16 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): content_layout.addWidget(value_input) - def focused_out(event): + def key_input_focused_out(event): QtWidgets.QLineEdit.focusOutEvent(key_input, event) self._on_focus_lose() - key_input.focusOutEvent = focused_out + def key_label_input_focused_out(event): + QtWidgets.QLineEdit.focusOutEvent(key_label_input, event) + self._on_focus_lose() + + key_input.focusOutEvent = key_input_focused_out + key_label_input.focusOutEvent = key_label_input_focused_out spacer_widget = None if not self.labeled_items: @@ -2035,9 +2043,10 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): remove_btn.setFixedSize(self._btn_size, self._btn_size) if self.labeled_items: - wrapper_widget.add_widget_after_label(key_input) - wrapper_widget.add_widget_after_label(add_btn) + wrapper_widget.add_widget_before_label(add_btn) wrapper_widget.add_widget_before_label(edit_btn) + wrapper_widget.add_widget_after_label(key_input) + wrapper_widget.add_widget_after_label(key_label_input) else: layout.addWidget(add_btn, 0) @@ -2050,7 +2059,12 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): key_input.textChanged.connect(self._on_key_change) key_input.returnPressed.connect(self._on_enter_press) + if key_label_input: + key_label_input.textChanged.connect(self._on_key_change) + key_label_input.returnPressed.connect(self._on_enter_press) + value_input.value_changed.connect(self._on_value_change) + add_btn.clicked.connect(self.on_add_clicked) if edit_btn: edit_btn.clicked.connect(self.on_edit_pressed) @@ -2058,6 +2072,7 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): remove_btn.clicked.connect(self.on_remove_clicked) self.key_input = key_input + self.key_label_input = key_label_input self.value_input = value_input self.wrapper_widget = wrapper_widget @@ -2091,14 +2106,18 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): return self._is_key_duplicated = duplicated - if duplicated and self.labeled_items: - self.set_edit_mode(True) + if self.labeled_items: + if duplicated: + self.set_edit_mode(True) + else: + self._on_focus_lose() self.update_style() def _on_focus_lose(self): if ( - self.key_input.hasFocus() - or self.edit_btn.hasFocus() + self.edit_btn.hasFocus() + or self.key_input.hasFocus() + or self.key_label_input.hasFocus() ): return self._on_enter_press() @@ -2112,11 +2131,15 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): else: self.set_edit_mode(False) + def _on_key_label_change(self): + self.update_key_label() + def _on_key_change(self): - value = self.key_input.text() if self.value_is_env_group: - self.value_input.env_group_key = value - self.change_key_label(value) + self.value_input.env_group_key = self.key_input.text() + + self.update_key_label() + self._on_value_change() def _on_value_change(self, item=None): @@ -2146,9 +2169,16 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): def is_group(self): return self._parent.is_group - def change_key_label(self, label): - if self.wrapper_widget: - self.wrapper_widget.label_widget.setText(label) + def update_key_label(self): + if not self.wrapper_widget: + return + key_value = self.key_input.text() + key_label_value = self.key_label_input.text() + if key_label_value: + label = "{} ({})".format(key_label_value, key_value) + else: + label = key_value + self.wrapper_widget.label_widget.setText(label) def on_add_clicked(self): if not self.labeled_items: @@ -2178,6 +2208,7 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): return self.wrapper_widget.label_widget.setVisible(not enabled) self.key_input.setVisible(enabled) + self.key_label_input.setVisible(enabled) if enabled: self.key_input.setFocus() @@ -2199,6 +2230,7 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): else: self.key_input.setVisible(is_empty) + self.key_label_input.setVisible(is_empty) self.edit_btn.setVisible(not is_empty) self.wrapper_widget.label_widget.setVisible(not is_empty) From 61ecb05a591f050366be770e4d6987c61d843322 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 27 Nov 2020 17:10:26 +0100 Subject: [PATCH 22/39] adde remove btn on edit mode --- .../settings/settings/widgets/item_types.py | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index 5b92754752..f76b9d2730 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -2036,17 +2036,18 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): edit_btn.setFocusPolicy(QtCore.Qt.ClickFocus) edit_btn.setProperty("btn-type", "tool-item-icon") edit_btn.setFixedHeight(self._btn_size) - else: - remove_btn = QtWidgets.QPushButton("-") - remove_btn.setFocusPolicy(QtCore.Qt.ClickFocus) - remove_btn.setProperty("btn-type", "tool-item") - remove_btn.setFixedSize(self._btn_size, self._btn_size) + + remove_btn = QtWidgets.QPushButton("-") + remove_btn.setFocusPolicy(QtCore.Qt.ClickFocus) + remove_btn.setProperty("btn-type", "tool-item") + remove_btn.setFixedSize(self._btn_size, self._btn_size) if self.labeled_items: wrapper_widget.add_widget_before_label(add_btn) wrapper_widget.add_widget_before_label(edit_btn) wrapper_widget.add_widget_after_label(key_input) wrapper_widget.add_widget_after_label(key_label_input) + wrapper_widget.add_widget_after_label(remove_btn) else: layout.addWidget(add_btn, 0) @@ -2068,8 +2069,7 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): add_btn.clicked.connect(self.on_add_clicked) if edit_btn: edit_btn.clicked.connect(self.on_edit_pressed) - if remove_btn: - remove_btn.clicked.connect(self.on_remove_clicked) + remove_btn.clicked.connect(self.on_remove_clicked) self.key_input = key_input self.key_label_input = key_label_input @@ -2118,6 +2118,7 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): self.edit_btn.hasFocus() or self.key_input.hasFocus() or self.key_label_input.hasFocus() + or self.remove_btn.hasFocus() ): return self._on_enter_press() @@ -2209,13 +2210,11 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): self.wrapper_widget.label_widget.setVisible(not enabled) self.key_input.setVisible(enabled) self.key_label_input.setVisible(enabled) + self.remove_btn.setVisible(enabled) if enabled: self.key_input.setFocus() def on_remove_clicked(self): - self.remove_row() - - def remove_row(self): self._parent.remove_row(self) def set_as_empty(self, is_empty=True): @@ -2229,6 +2228,7 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): self.spacer_widget.setVisible(is_empty) else: + self.remove_btn.setVisible(False) self.key_input.setVisible(is_empty) self.key_label_input.setVisible(is_empty) self.edit_btn.setVisible(not is_empty) From a24f2a15343e31f43fc42eabb899cd3f1d14ca61 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 27 Nov 2020 17:17:23 +0100 Subject: [PATCH 23/39] minor styles fixes --- pype/tools/settings/settings/widgets/item_types.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index f76b9d2730..f2d42cdadf 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -1997,6 +1997,7 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): layout.addWidget(wrapper_widget) content_widget = QtWidgets.QWidget(wrapper_widget) + content_widget.setObjectName("ContentWidget") content_layout = QtWidgets.QHBoxLayout(content_widget) content_layout.setContentsMargins(CHILD_OFFSET, 5, 0, 0) content_layout.setSpacing(5) @@ -2379,7 +2380,7 @@ class ModifiableDict(QtWidgets.QWidget, InputObject): content_widget.setObjectName("ContentWidget") content_widget.setProperty("content_state", content_state) content_layout = QtWidgets.QVBoxLayout(content_widget) - content_layout.setContentsMargins(CHILD_OFFSET, 3, 0, bottom_margin) + content_layout.setContentsMargins(CHILD_OFFSET, 5, 0, bottom_margin) if body_widget is None: main_layout.addWidget(content_widget) From 5fb35c8f5b0bbcedb827b51bee2756b932356d69 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 27 Nov 2020 17:33:50 +0100 Subject: [PATCH 24/39] fix layout --- pype/tools/settings/settings/widgets/widgets.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pype/tools/settings/settings/widgets/widgets.py b/pype/tools/settings/settings/widgets/widgets.py index 1ff5ce2fdc..66afa565a3 100644 --- a/pype/tools/settings/settings/widgets/widgets.py +++ b/pype/tools/settings/settings/widgets/widgets.py @@ -127,7 +127,7 @@ class ExpandingWidget(QtWidgets.QWidget): label_widget.setObjectName("DictLabel") before_label_widget = QtWidgets.QWidget(side_line_widget) - before_label_layout = QtWidgets.QVBoxLayout(before_label_widget) + before_label_layout = QtWidgets.QHBoxLayout(before_label_widget) before_label_layout.setContentsMargins(0, 0, 0, 0) after_label_widget = QtWidgets.QWidget(side_line_widget) From d49c683eec36e258e6a23cd9f59a3493bad56cd3 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 27 Nov 2020 17:35:27 +0100 Subject: [PATCH 25/39] added storing label value in metadata --- .../settings/settings/widgets/item_types.py | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index f2d42cdadf..ee4bbde5ca 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -2281,6 +2281,9 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): def row(self): return self._parent.input_fields.index(self) + def label_value(self): + return self.key_label_input.text() + def item_value(self): key = self.key_input.text() value = self.value_input.item_value() @@ -2503,12 +2506,29 @@ class ModifiableDict(QtWidgets.QWidget, InputObject): output.update(item.item_value()) return output + def item_value_with_metadata(self): + output = {} + labels_by_key = {} + for item in self.input_fields: + labels_by_key[item.key_value()] = item.label_value() + output.update(item.config_value()) + + output[METADATA_KEY] = { + "dynamic_key_label": labels_by_key + } + return output + def item_value(self): output = {} for item in self.input_fields: output.update(item.config_value()) return output + def config_value(self): + if not self.labeled_items: + return super(ModifiableDict, self).config_value() + return {self.key: self.item_value_with_metadata()} + def add_row(self, row=None, key=None, value=None, is_empty=False): # Create new item item_widget = ModifiableDictItem( From 500df0a052e30b974ac003c5e75c6112efb5fd73 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 27 Nov 2020 17:49:35 +0100 Subject: [PATCH 26/39] little bit safer metadata storing --- .../settings/settings/widgets/item_types.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index 3ffba4893d..d2efb703f1 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -1342,10 +1342,10 @@ class RawJsonWidget(QtWidgets.QWidget, InputObject): def config_value(self): value = self.item_value() if self.is_environ: - value[METADATA_KEY] = { - "environments": { - self.env_group_key: list(value.keys()) - } + if METADATA_KEY not in value: + value[METADATA_KEY] = {} + value[METADATA_KEY]["environments"] = { + self.env_group_key: list(value.keys()) } return {self.key: value} @@ -3617,7 +3617,9 @@ class DictFormWidget(QtWidgets.QWidget, SettingObject): if is_group: groups.extend(value.keys()) if groups: - values[METADATA_KEY] = {"groups": groups} + if METADATA_KEY not in values: + values[METADATA_KEY] = {} + values[METADATA_KEY]["groups"] = groups return values, self.is_group def overrides(self): @@ -3633,7 +3635,9 @@ class DictFormWidget(QtWidgets.QWidget, SettingObject): if is_group: groups.extend(value.keys()) if groups: - values[METADATA_KEY] = {"groups": groups} + if METADATA_KEY not in values: + values[METADATA_KEY] = {} + values[METADATA_KEY]["groups"] = groups return values, self.is_group From a4a684f32f5764a46598ed8530994892a94f3266 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 27 Nov 2020 17:50:02 +0100 Subject: [PATCH 27/39] unified method for getting modifiable dict item value with metadata --- .../settings/settings/widgets/item_types.py | 40 ++++++++++--------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index d2efb703f1..db62beddf8 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -2506,15 +2506,28 @@ class ModifiableDict(QtWidgets.QWidget, InputObject): return output def item_value_with_metadata(self): - output = {} - labels_by_key = {} - for item in self.input_fields: - labels_by_key[item.key_value()] = item.label_value() - output.update(item.config_value()) + metadata = {} + if not self.labeled_items: + output = self.item_value() + + else: + output = {} + labels_by_key = {} + for item in self.input_fields: + labels_by_key[item.key_value()] = item.label_value() + output.update(item.config_value()) + metadata["dynamic_key_label"] = labels_by_key + + if self.value_is_env_group: + for key, value in tuple(output.items()): + metadata["environments"] = {key: list(value.keys())} + output[key] = value + + if metadata: + if METADATA_KEY not in output: + output[METADATA_KEY] = {} + output[METADATA_KEY].update(metadata) - output[METADATA_KEY] = { - "dynamic_key_label": labels_by_key - } return output def item_value(self): @@ -2524,16 +2537,7 @@ class ModifiableDict(QtWidgets.QWidget, InputObject): return output def config_value(self): - output = self.item_value() - if self.value_is_env_group: - for key, value in tuple(output.items()): - value[METADATA_KEY] = { - "environments": { - key: list(value.keys()) - } - } - output[key] = value - return {self.key: output} + return {self.key: self.item_value_with_metadata()} def add_row(self, row=None, key=None, value=None, is_empty=False): # Create new item From b79d8b65ffc96e106fe35178c76f9e9616713fef Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 27 Nov 2020 17:55:10 +0100 Subject: [PATCH 28/39] fix anatomy creation --- pype/tools/settings/settings/widgets/anatomy_types.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pype/tools/settings/settings/widgets/anatomy_types.py b/pype/tools/settings/settings/widgets/anatomy_types.py index 680db140a6..83183e7943 100644 --- a/pype/tools/settings/settings/widgets/anatomy_types.py +++ b/pype/tools/settings/settings/widgets/anatomy_types.py @@ -67,6 +67,7 @@ class AnatomyWidget(QtWidgets.QWidget, SettingObject): self.root_widget = RootsWidget(roots_input_data, self) self.templates_widget = TemplatesWidget(templates_input_data, self) self.imageio_widget = DictWidget(imageio_input_data, self) + self.imageio_widget.create_ui() self.setAttribute(QtCore.Qt.WA_StyledBackground) From 3e23b9ab1b78f2c842505bcb3a7b09b9be2e535a Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 27 Nov 2020 18:12:57 +0100 Subject: [PATCH 29/39] fixed env group metadata storing --- .../settings/settings/widgets/item_types.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index db62beddf8..8bfb1dd091 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -2506,7 +2506,6 @@ class ModifiableDict(QtWidgets.QWidget, InputObject): return output def item_value_with_metadata(self): - metadata = {} if not self.labeled_items: output = self.item_value() @@ -2516,18 +2515,18 @@ class ModifiableDict(QtWidgets.QWidget, InputObject): for item in self.input_fields: labels_by_key[item.key_value()] = item.label_value() output.update(item.config_value()) - metadata["dynamic_key_label"] = labels_by_key + if METADATA_KEY not in output: + output[METADATA_KEY] = {} + output[METADATA_KEY]["dynamic_key_label"] = labels_by_key if self.value_is_env_group: for key, value in tuple(output.items()): - metadata["environments"] = {key: list(value.keys())} + if METADATA_KEY not in value: + value[METADATA_KEY] = {} + value[METADATA_KEY]["environments"] = { + key: list(value.keys()) + } output[key] = value - - if metadata: - if METADATA_KEY not in output: - output[METADATA_KEY] = {} - output[METADATA_KEY].update(metadata) - return output def item_value(self): From 6903865976f404df6dbde84c13261cdaebb0eb38 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 27 Nov 2020 18:34:26 +0100 Subject: [PATCH 30/39] fixed metadata --- .../settings/settings/widgets/item_types.py | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index 8bfb1dd091..5a02497f71 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -1344,8 +1344,14 @@ class RawJsonWidget(QtWidgets.QWidget, InputObject): if self.is_environ: if METADATA_KEY not in value: value[METADATA_KEY] = {} + + env_keys = [] + for key in value.keys(): + if key is not METADATA_KEY: + env_keys.append(key) + value[METADATA_KEY]["environments"] = { - self.env_group_key: list(value.keys()) + self.env_group_key: env_keys } return {self.key: value} @@ -2520,13 +2526,17 @@ class ModifiableDict(QtWidgets.QWidget, InputObject): output[METADATA_KEY]["dynamic_key_label"] = labels_by_key if self.value_is_env_group: - for key, value in tuple(output.items()): + for env_group_key, value in tuple(output.items()): + env_keys = [] + for key in value.keys(): + if key is not METADATA_KEY: + env_keys.append(key) + if METADATA_KEY not in value: value[METADATA_KEY] = {} - value[METADATA_KEY]["environments"] = { - key: list(value.keys()) - } - output[key] = value + + value[METADATA_KEY]["environments"] = {env_group_key: env_keys} + output[env_group_key] = value return output def item_value(self): From 0b18f1cce3238665bc7f97ffd8de550eed23ac90 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 27 Nov 2020 19:01:25 +0100 Subject: [PATCH 31/39] fixed few issues of loaded data --- pype/settings/lib.py | 2 ++ pype/tools/settings/settings/widgets/item_types.py | 6 +++++- pype/tools/settings/settings/widgets/lib.py | 13 ++++++++++++- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/pype/settings/lib.py b/pype/settings/lib.py index a50d7793b5..ebd0d86df4 100644 --- a/pype/settings/lib.py +++ b/pype/settings/lib.py @@ -9,6 +9,8 @@ log = logging.getLogger(__name__) M_OVERRIDEN_KEY = "__overriden_keys__" # Metadata key for storing information about environments M_ENVIRONMENT_KEY = "__environment_keys__" +# Metadata key for storing dynamic created labels +M_DYNAMIC_KEY_LABEL = "__dynamic_keys_labels__" # NOTE key popping not implemented yet M_POP_KEY = "__pop_key__" diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index 5a02497f71..ca4d28ccbc 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -2034,7 +2034,6 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): add_btn.setFixedSize(self._btn_size, self._btn_size) edit_btn = None - remove_btn = None if self.labeled_items: edit_btn = IconButton( "fa.edit", QtCore.Qt.lightGray, QtCore.Qt.white @@ -2049,6 +2048,9 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): remove_btn.setFixedSize(self._btn_size, self._btn_size) if self.labeled_items: + add_btn.setVisible(False) + remove_btn.setVisible(False) + wrapper_widget.add_widget_before_label(add_btn) wrapper_widget.add_widget_before_label(edit_btn) wrapper_widget.add_widget_after_label(key_input) @@ -2422,6 +2424,8 @@ class ModifiableDict(QtWidgets.QWidget, InputObject): previous_inputs = tuple(self.input_fields) for item_key, item_value in value.items(): self.add_row(key=item_key, value=item_value) + if self.labeled_items: + self.add_row(is_empty=True) for input_field in previous_inputs: self.remove_row(input_field) diff --git a/pype/tools/settings/settings/widgets/lib.py b/pype/tools/settings/settings/widgets/lib.py index f112a6e975..9a6331009b 100644 --- a/pype/tools/settings/settings/widgets/lib.py +++ b/pype/tools/settings/settings/widgets/lib.py @@ -2,7 +2,11 @@ import os import re import json import copy -from pype.settings.lib import M_OVERRIDEN_KEY, M_ENVIRONMENT_KEY +from pype.settings.lib import ( + M_OVERRIDEN_KEY, + M_ENVIRONMENT_KEY, + M_DYNAMIC_KEY_LABEL +) from queue import Queue @@ -35,6 +39,8 @@ def convert_gui_data_with_metadata(data, ignored_keys=None): if key == "environments": output[M_ENVIRONMENT_KEY] = value + elif key == "dynamic_key_label": + output[M_DYNAMIC_KEY_LABEL] = value else: raise KeyError("Unknown metadata key \"{}\"".format(key)) @@ -51,6 +57,11 @@ def convert_data_to_gui_data(data, first=True): if M_ENVIRONMENT_KEY in data: data.pop(M_ENVIRONMENT_KEY) + if M_DYNAMIC_KEY_LABEL in data: + if METADATA_KEY not in data: + data[METADATA_KEY] = {} + data[METADATA_KEY]["dynamic_key_label"] = data.pop(M_DYNAMIC_KEY_LABEL) + for key, value in data.items(): output[key] = convert_data_to_gui_data(value, False) From 295f89a730deada88fce45bf8ad37b9f2ec0daeb Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 27 Nov 2020 19:02:56 +0100 Subject: [PATCH 32/39] add_row can enter label --- .../settings/settings/widgets/item_types.py | 29 ++++++++++++++----- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index ca4d28ccbc..11c8fdeaa9 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -2155,19 +2155,25 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): self.update_style() self.value_changed.emit(self) - def update_default_values(self, key, value): + def update_default_values(self, key, label, value): self.origin_key = key self.key_input.setText(key) + if self.key_label_input: + self.key_label_input.setText(label or "") self.value_input.update_default_values(value) - def update_studio_values(self, key, value): + def update_studio_values(self, key, label, value): self.origin_key = key self.key_input.setText(key) + if self.key_label_input: + self.key_label_input.setText(label or "") self.value_input.update_studio_values(value) - def apply_overrides(self, key, value): + def apply_overrides(self, key, label, value): self.origin_key = key self.key_input.setText(key) + if self.key_label_input: + self.key_label_input.setText(label or "") self.value_input.apply_overrides(value) @property @@ -2421,9 +2427,14 @@ class ModifiableDict(QtWidgets.QWidget, InputObject): def set_value(self, value): self.validate_value(value) + metadata = value.pop(METADATA_KEY, {}) + dynamic_key_labels = metadata.get("dynamic_key_label") or {} + previous_inputs = tuple(self.input_fields) for item_key, item_value in value.items(): - self.add_row(key=item_key, value=item_value) + label = dynamic_key_labels.get(item_key) + self.add_row(key=item_key, label=label, value=item_value) + if self.labeled_items: self.add_row(is_empty=True) @@ -2552,7 +2563,9 @@ class ModifiableDict(QtWidgets.QWidget, InputObject): def config_value(self): return {self.key: self.item_value_with_metadata()} - def add_row(self, row=None, key=None, value=None, is_empty=False): + def add_row( + self, row=None, key=None, label=None, value=None, is_empty=False + ): # Create new item item_widget = ModifiableDictItem( self.item_schema, self, self.content_widget @@ -2593,11 +2606,11 @@ class ModifiableDict(QtWidgets.QWidget, InputObject): # else (when add button clicked) trigger `_on_value_change` if value is not None and key is not None: if not self._has_studio_override: - item_widget.update_default_values(key, value) + item_widget.update_default_values(key, label, value) elif self._is_overriden: - item_widget.apply_overrides(key, value) + item_widget.apply_overrides(key, label, value) else: - item_widget.update_studio_values(key, value) + item_widget.update_studio_values(key, label, value) self.hierarchical_style_update() else: self._on_value_change() From 4bceafe3e569bab0820702e15e35be62f0de1d6a Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 27 Nov 2020 19:04:50 +0100 Subject: [PATCH 33/39] better initial state of modifiable dict item --- pype/tools/settings/settings/widgets/item_types.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index 11c8fdeaa9..1c70b67bdb 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -2048,9 +2048,6 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): remove_btn.setFixedSize(self._btn_size, self._btn_size) if self.labeled_items: - add_btn.setVisible(False) - remove_btn.setVisible(False) - wrapper_widget.add_widget_before_label(add_btn) wrapper_widget.add_widget_before_label(edit_btn) wrapper_widget.add_widget_after_label(key_input) @@ -2091,6 +2088,8 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): self.edit_btn = edit_btn self.remove_btn = remove_btn + self.set_as_empty(self._is_empty) + @property def labeled_items(self): return self._parent.labeled_items From dc353e03a805fcdf253b24fc2bb1f3dc76b1cfc2 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 27 Nov 2020 19:08:57 +0100 Subject: [PATCH 34/39] do not pop metadata key, just skip it --- pype/tools/settings/settings/widgets/item_types.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index 1c70b67bdb..faaf9de4bb 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -2426,11 +2426,12 @@ class ModifiableDict(QtWidgets.QWidget, InputObject): def set_value(self, value): self.validate_value(value) - metadata = value.pop(METADATA_KEY, {}) + metadata = value.get(METADATA_KEY, {}) dynamic_key_labels = metadata.get("dynamic_key_label") or {} - previous_inputs = tuple(self.input_fields) for item_key, item_value in value.items(): + if item_key is METADATA_KEY: + continue label = dynamic_key_labels.get(item_key) self.add_row(key=item_key, label=label, value=item_value) From 6cd6d9ef9036adb9aa0dab1fa043193432eb9f5d Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 27 Nov 2020 19:40:10 +0100 Subject: [PATCH 35/39] proper stylesheets and key label modifications --- .../settings/settings/widgets/item_types.py | 81 ++++++++++++++++--- 1 file changed, 70 insertions(+), 11 deletions(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index faaf9de4bb..1eadd843a3 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -1973,6 +1973,7 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): self._is_key_duplicated = False self.origin_key = NOT_SET + self.origin_key_label = NOT_SET if self.labeled_items: layout = QtWidgets.QVBoxLayout(self) @@ -2090,6 +2091,23 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): self.set_as_empty(self._is_empty) + def _style_state(self): + if self.as_widget: + state = self.style_state( + False, + self._is_invalid, + False, + self.is_modified + ) + else: + state = self.style_state( + self.has_studio_override, + self.is_invalid, + self.is_overriden, + self.is_modified + ) + return state + @property def labeled_items(self): return self._parent.labeled_items @@ -2158,21 +2176,27 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): self.origin_key = key self.key_input.setText(key) if self.key_label_input: - self.key_label_input.setText(label or "") + label = label or "" + self.origin_key_label = label + self.key_label_input.setText(label) self.value_input.update_default_values(value) def update_studio_values(self, key, label, value): self.origin_key = key self.key_input.setText(key) if self.key_label_input: - self.key_label_input.setText(label or "") + label = label or "" + self.origin_key_label = label + self.key_label_input.setText(label) self.value_input.update_studio_values(value) def apply_overrides(self, key, label, value): self.origin_key = key self.key_input.setText(key) if self.key_label_input: - self.key_label_input.setText(label or "") + label = label or "" + self.origin_key_label = label + self.key_label_input.setText(label) self.value_input.apply_overrides(value) @property @@ -2260,6 +2284,9 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): def is_key_modified(self): return self.key_value() != self.origin_key + def is_key_label_modified(self): + return self.key_label_value() != self.origin_key_label + def is_value_modified(self): return self.value_input.is_modified @@ -2267,7 +2294,11 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): def is_modified(self): if self._is_empty: return False - return self.is_value_modified() or self.is_key_modified() + return ( + self.is_value_modified() + or self.is_key_modified() + or self.is_key_label_modified() + ) def hierarchical_style_update(self): self.value_input.hierarchical_style_update() @@ -2280,21 +2311,49 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): return self.is_key_invalid() or self.value_input.is_invalid def update_style(self): - state = "" + key_input_state = "" if not self._is_empty: if self.is_key_invalid(): - state = "invalid" + key_input_state = "invalid" elif self.is_key_modified(): - state = "modified" + key_input_state = "modified" - self.key_input.setProperty("state", state) + self.key_input.setProperty("state", key_input_state) self.key_input.style().polish(self.key_input) + if not self.wrapper_widget: + return + + state = self._style_state() + + if self._state == state: + return + + self._state = state + + if self.wrapper_widget.label_widget: + self.wrapper_widget.label_widget.setProperty("state", state) + self.wrapper_widget.label_widget.style().polish( + self.wrapper_widget.label_widget + ) + + if state: + child_state = "child-{}".format(state) + else: + child_state = "" + + self.wrapper_widget.side_line_widget.setProperty("state", child_state) + self.wrapper_widget.side_line_widget.style().polish( + self.wrapper_widget.side_line_widget + ) + def row(self): return self._parent.input_fields.index(self) - def label_value(self): - return self.key_label_input.text() + def key_label_value(self): + if self.labeled_items: + return self.key_label_input.text() + return NOT_SET def item_value(self): key = self.key_input.text() @@ -2534,7 +2593,7 @@ class ModifiableDict(QtWidgets.QWidget, InputObject): output = {} labels_by_key = {} for item in self.input_fields: - labels_by_key[item.key_value()] = item.label_value() + labels_by_key[item.key_value()] = item.key_label_value() output.update(item.config_value()) if METADATA_KEY not in output: output[METADATA_KEY] = {} From ccc758cdced307c7eaa134099fca74e5e94a78ea Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 27 Nov 2020 19:44:22 +0100 Subject: [PATCH 36/39] added labels to inputs --- pype/tools/settings/settings/widgets/item_types.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index 1eadd843a3..d4942e04d2 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -2048,10 +2048,16 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): remove_btn.setProperty("btn-type", "tool-item") remove_btn.setFixedSize(self._btn_size, self._btn_size) + key_input_label_widget = None + key_label_input_label_widget = None if self.labeled_items: + key_input_label_widget = QtWidgets.QLabel("Key:") + key_label_input_label_widget = QtWidgets.QLabel("Label:") wrapper_widget.add_widget_before_label(add_btn) wrapper_widget.add_widget_before_label(edit_btn) + wrapper_widget.add_widget_after_label(key_input_label_widget) wrapper_widget.add_widget_after_label(key_input) + wrapper_widget.add_widget_after_label(key_label_input_label_widget) wrapper_widget.add_widget_after_label(key_label_input) wrapper_widget.add_widget_after_label(remove_btn) @@ -2078,9 +2084,10 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): remove_btn.clicked.connect(self.on_remove_clicked) self.key_input = key_input + self.key_input_label_widget = key_input_label_widget self.key_label_input = key_label_input + self.key_label_input_label_widget = key_label_input_label_widget self.value_input = value_input - self.wrapper_widget = wrapper_widget self.spacer_widget = spacer_widget @@ -2245,7 +2252,9 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): if self.is_invalid and not enabled: return self.wrapper_widget.label_widget.setVisible(not enabled) + self.key_label_input_label_widget.setVisible(enabled) self.key_input.setVisible(enabled) + self.key_input_label_widget.setVisible(enabled) self.key_label_input.setVisible(enabled) self.remove_btn.setVisible(enabled) if enabled: @@ -2266,7 +2275,9 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): else: self.remove_btn.setVisible(False) + self.key_input_label_widget.setVisible(is_empty) self.key_input.setVisible(is_empty) + self.key_label_input_label_widget.setVisible(is_empty) self.key_label_input.setVisible(is_empty) self.edit_btn.setVisible(not is_empty) From e99fc55bd4c233adbb6bedc71f0a124a55bb516c Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 30 Nov 2020 17:39:56 +0100 Subject: [PATCH 37/39] renamed labeled_items to collapsable_key --- .../settings/settings/widgets/item_types.py | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/pype/tools/settings/settings/widgets/item_types.py b/pype/tools/settings/settings/widgets/item_types.py index d4942e04d2..25bbe4a515 100644 --- a/pype/tools/settings/settings/widgets/item_types.py +++ b/pype/tools/settings/settings/widgets/item_types.py @@ -1975,7 +1975,7 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): self.origin_key = NOT_SET self.origin_key_label = NOT_SET - if self.labeled_items: + if self.collapsable_key: layout = QtWidgets.QVBoxLayout(self) else: layout = QtWidgets.QHBoxLayout(self) @@ -1996,7 +1996,7 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): key_label_input = None wrapper_widget = None - if self.labeled_items: + if self.collapsable_key: key_label_input = QtWidgets.QLineEdit(self) wrapper_widget = ExpandingWidget("", self) @@ -2024,7 +2024,7 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): key_label_input.focusOutEvent = key_label_input_focused_out spacer_widget = None - if not self.labeled_items: + if not self.collapsable_key: spacer_widget = QtWidgets.QWidget(self) spacer_widget.setAttribute(QtCore.Qt.WA_TranslucentBackground) spacer_widget.setVisible(False) @@ -2035,7 +2035,7 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): add_btn.setFixedSize(self._btn_size, self._btn_size) edit_btn = None - if self.labeled_items: + if self.collapsable_key: edit_btn = IconButton( "fa.edit", QtCore.Qt.lightGray, QtCore.Qt.white ) @@ -2050,7 +2050,7 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): key_input_label_widget = None key_label_input_label_widget = None - if self.labeled_items: + if self.collapsable_key: key_input_label_widget = QtWidgets.QLabel("Key:") key_label_input_label_widget = QtWidgets.QLabel("Label:") wrapper_widget.add_widget_before_label(add_btn) @@ -2116,8 +2116,8 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): return state @property - def labeled_items(self): - return self._parent.labeled_items + def collapsable_key(self): + return self._parent.collapsable_key def key_value(self): return self.key_input.text() @@ -2138,7 +2138,7 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): return self._is_key_duplicated = duplicated - if self.labeled_items: + if self.collapsable_key: if duplicated: self.set_edit_mode(True) else: @@ -2156,7 +2156,7 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): self._on_enter_press() def _on_enter_press(self): - if not self.labeled_items: + if not self.collapsable_key: return if self._is_empty: @@ -2226,7 +2226,7 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): self.wrapper_widget.label_widget.setText(label) def on_add_clicked(self): - if not self.labeled_items: + if not self.collapsable_key: if self._is_empty: self.set_as_empty(False) else: @@ -2268,7 +2268,7 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): self.value_input.setVisible(not is_empty) self.add_btn.setVisible(is_empty) - if not self.labeled_items: + if not self.collapsable_key: self.key_input.setVisible(not is_empty) self.remove_btn.setEnabled(not is_empty) self.spacer_widget.setVisible(is_empty) @@ -2362,7 +2362,7 @@ class ModifiableDictItem(QtWidgets.QWidget, SettingObject): return self._parent.input_fields.index(self) def key_label_value(self): - if self.labeled_items: + if self.collapsable_key: return self.key_label_input.text() return NOT_SET @@ -2406,7 +2406,7 @@ class ModifiableDict(QtWidgets.QWidget, InputObject): schema_data.get("value_is_env_group") or False ) self.hightlight_content = schema_data.get("highlight_content") or False - self.labeled_items = schema_data.get("labeled_items") or False + self.collapsable_key = schema_data.get("collapsable_key") or False object_type = schema_data["object_type"] if isinstance(object_type, dict): @@ -2505,7 +2505,7 @@ class ModifiableDict(QtWidgets.QWidget, InputObject): label = dynamic_key_labels.get(item_key) self.add_row(key=item_key, label=label, value=item_value) - if self.labeled_items: + if self.collapsable_key: self.add_row(is_empty=True) for input_field in previous_inputs: @@ -2597,7 +2597,7 @@ class ModifiableDict(QtWidgets.QWidget, InputObject): return output def item_value_with_metadata(self): - if not self.labeled_items: + if not self.collapsable_key: output = self.item_value() else: @@ -2653,7 +2653,7 @@ class ModifiableDict(QtWidgets.QWidget, InputObject): self.input_fields.insert(row, item_widget) previous_input = None - if self.labeled_items: + if self.collapsable_key: for input_field in self.input_fields: if previous_input is not None: self.setTabOrder( From 529bca3f9c08779573066ca0dff2790b7cfc16b7 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 1 Dec 2020 17:09:41 +0100 Subject: [PATCH 38/39] fixed defaults save in projects --- pype/tools/settings/settings/widgets/base.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/pype/tools/settings/settings/widgets/base.py b/pype/tools/settings/settings/widgets/base.py index d3128d7546..2e5c2f356b 100644 --- a/pype/tools/settings/settings/widgets/base.py +++ b/pype/tools/settings/settings/widgets/base.py @@ -239,14 +239,6 @@ class SystemWidget(QtWidgets.QWidget): if not self.items_are_valid(): return - output = {} - for item in self.input_fields: - output.update(item.config_value()) - - for key in reversed(self.keys): - _output = {key: output} - output = _output - all_values = {} for item in self.input_fields: all_values.update(item.config_value()) @@ -626,6 +618,8 @@ class ProjectWidget(QtWidgets.QWidget): for item in self.input_fields: all_values.update(item.config_value()) + all_values = lib.convert_gui_data_with_metadata(all_values) + for key in reversed(self.keys): _all_values = {key: all_values} all_values = _all_values From d2a110c1a98579af79f31334a5ddb4eb7881b2b5 Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Tue, 1 Dec 2020 18:06:24 +0100 Subject: [PATCH 39/39] update standalon publisher with collapsible keys --- .../defaults/project_anatomy/imageio.json | 239 +++++++++--------- .../project_settings/standalonepublisher.json | 14 +- .../schema_project_standalonepublisher.json | 1 + 3 files changed, 137 insertions(+), 117 deletions(-) diff --git a/pype/settings/defaults/project_anatomy/imageio.json b/pype/settings/defaults/project_anatomy/imageio.json index 98ded33370..4e98463ee4 100644 --- a/pype/settings/defaults/project_anatomy/imageio.json +++ b/pype/settings/defaults/project_anatomy/imageio.json @@ -1,122 +1,129 @@ { - "hiero": { - "workfile": { - "ocioConfigName": "nuke-default", - "ocioconfigpath": { - "windows": [], - "darwin": [], - "linux": [] - }, - "workingSpace": "linear", - "sixteenBitLut": "sRGB", - "eightBitLut": "sRGB", - "floatLut": "linear", - "logLut": "Cineon", - "viewerLut": "sRGB", - "thumbnailLut": "sRGB" - }, - "regexInputs": { - "inputs": [{ - "regex": "[^-a-zA-Z0-9](plateRef).*(?=mp4)", - "colorspace": "sRGB" - }] - } - }, - "nuke": { - "workfile": { - "colorManagement": "Nuke", - "OCIO_config": "nuke-default", - "customOCIOConfigPath": { - "windows": [], - "darwin": [], - "linux": [] - }, - "workingSpaceLUT": "linear", - "monitorLut": "sRGB", - "int8Lut": "sRGB", - "int16Lut": "sRGB", - "logLut": "Cineon", - "floatLut": "linear" - }, - "nodes": { - "requiredNodes": [{ - "plugins": [ - "CreateWriteRender" - ], - "nukeNodeClass": "Write", - "knobs": [{ - "name": "file_type", - "value": "exr" + "hiero": { + "workfile": { + "ocioConfigName": "nuke-default", + "ocioconfigpath": { + "windows": [], + "darwin": [], + "linux": [] }, - { - "name": "datatype", - "value": "16 bit half" - }, - { - "name": "compression", - "value": "Zip (1 scanline)" - }, - { - "name": "autocrop", - "value": "True" - }, - { - "name": "tile_color", - "value": "0xff0000ff" - }, - { - "name": "channels", - "value": "rgb" - }, - { - "name": "colorspace", - "value": "linear" - } - ] + "workingSpace": "linear", + "sixteenBitLut": "sRGB", + "eightBitLut": "sRGB", + "floatLut": "linear", + "logLut": "Cineon", + "viewerLut": "sRGB", + "thumbnailLut": "sRGB" }, - { - "plugins": [ - "CreateWritePrerender" - ], - "nukeNodeClass": "Write", - "knobs": [{ - "name": "file_type", - "value": "exr" - }, - { - "name": "datatype", - "value": "16 bit half" - }, - { - "name": "compression", - "value": "Zip (1 scanline)" - }, - { - "name": "autocrop", - "value": "False" - }, - { - "name": "tile_color", - "value": "0xff0000ff" - }, - { - "name": "channels", - "value": "rgb" - }, - { - "name": "colorspace", - "value": "linear" - } - ] + "regexInputs": { + "inputs": [ + { + "regex": "[^-a-zA-Z0-9](plateRef).*(?=mp4)", + "colorspace": "sRGB" + } + ] } - ], - "customNodes": [] }, - "regexInputs": { - "inputs": [{ - "regex": "[^-a-zA-Z0-9]beauty[^-a-zA-Z0-9]", - "colorspace": "linear" - }] + "nuke": { + "workfile": { + "colorManagement": "Nuke", + "OCIO_config": "nuke-default", + "customOCIOConfigPath": { + "windows": [], + "darwin": [], + "linux": [] + }, + "workingSpaceLUT": "linear", + "monitorLut": "sRGB", + "int8Lut": "sRGB", + "int16Lut": "sRGB", + "logLut": "Cineon", + "floatLut": "linear" + }, + "nodes": { + "requiredNodes": [ + { + "plugins": [ + "CreateWriteRender" + ], + "nukeNodeClass": "Write", + "knobs": [ + { + "name": "file_type", + "value": "exr" + }, + { + "name": "datatype", + "value": "16 bit half" + }, + { + "name": "compression", + "value": "Zip (1 scanline)" + }, + { + "name": "autocrop", + "value": "True" + }, + { + "name": "tile_color", + "value": "0xff0000ff" + }, + { + "name": "channels", + "value": "rgb" + }, + { + "name": "colorspace", + "value": "linear" + } + ] + }, + { + "plugins": [ + "CreateWritePrerender" + ], + "nukeNodeClass": "Write", + "knobs": [ + { + "name": "file_type", + "value": "exr" + }, + { + "name": "datatype", + "value": "16 bit half" + }, + { + "name": "compression", + "value": "Zip (1 scanline)" + }, + { + "name": "autocrop", + "value": "False" + }, + { + "name": "tile_color", + "value": "0xff0000ff" + }, + { + "name": "channels", + "value": "rgb" + }, + { + "name": "colorspace", + "value": "linear" + } + ] + } + ], + "customNodes": [] + }, + "regexInputs": { + "inputs": [ + { + "regex": "[^-a-zA-Z0-9]beauty[^-a-zA-Z0-9]", + "colorspace": "linear" + } + ] + } } - } -} +} \ No newline at end of file diff --git a/pype/settings/defaults/project_settings/standalonepublisher.json b/pype/settings/defaults/project_settings/standalonepublisher.json index 2b5db54a4f..877055ceef 100644 --- a/pype/settings/defaults/project_settings/standalonepublisher.json +++ b/pype/settings/defaults/project_settings/standalonepublisher.json @@ -10,6 +10,18 @@ } }, "create": { + "__dynamic_keys_labels__": { + "create_workfile": "Workfile", + "create_model": "Model", + "create_rig": "Rig", + "create_pointcache": "Pointcache", + "create_plate": "Plate", + "create_camera": "Camera", + "create_editorial": "Editorial", + "create_image": "Image", + "create_matchmove": "matchmove", + "": "" + }, "create_workfile": { "name": "workfile", "label": "Workfile", @@ -21,7 +33,7 @@ "help": "Working scene backup" }, "create_model": { - "name": "mode", + "name": "model", "label": "Model", "family": "model", "icon": "cube", diff --git a/pype/tools/settings/settings/gui_schemas/projects_schema/schema_project_standalonepublisher.json b/pype/tools/settings/settings/gui_schemas/projects_schema/schema_project_standalonepublisher.json index 4a6e5f76ec..1241620dea 100644 --- a/pype/tools/settings/settings/gui_schemas/projects_schema/schema_project_standalonepublisher.json +++ b/pype/tools/settings/settings/gui_schemas/projects_schema/schema_project_standalonepublisher.json @@ -45,6 +45,7 @@ "collapsable": true, "key": "create", "label": "Creator plugins", + "collapsable_key": true, "is_file": true, "object_type": {