From 74161e931e17a736c3dae6ae24678f9db4d497d0 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Thu, 11 Aug 2022 18:02:47 +0200 Subject: [PATCH 01/12] Show whether a subset is loaded into the current scene --- openpype/tools/loader/model.py | 157 +++++++++++++++++++------------ openpype/tools/loader/widgets.py | 3 +- 2 files changed, 101 insertions(+), 59 deletions(-) diff --git a/openpype/tools/loader/model.py b/openpype/tools/loader/model.py index a5174bd804..3130f879df 100644 --- a/openpype/tools/loader/model.py +++ b/openpype/tools/loader/model.py @@ -14,9 +14,11 @@ from openpype.client import ( get_versions, get_hero_versions, get_version_by_name, - get_representations + get_representations, + get_representations_parents ) from openpype.pipeline import ( + registered_host, HeroVersionType, schema, ) @@ -136,7 +138,8 @@ class SubsetsModel(TreeModel, BaseRepresentationModel): "duration", "handles", "step", - "repre_info" + "repre_info", + "loaded_in_scene" ] column_labels_mapping = { @@ -150,7 +153,8 @@ class SubsetsModel(TreeModel, BaseRepresentationModel): "duration": "Duration", "handles": "Handles", "step": "Step", - "repre_info": "Availability" + "repre_info": "Availability", + "loaded_in_scene": "In scene" } SortAscendingRole = QtCore.Qt.UserRole + 2 @@ -231,8 +235,14 @@ class SubsetsModel(TreeModel, BaseRepresentationModel): self._doc_fetching_stop = False self._doc_payload = {} - self.doc_fetched.connect(self._on_doc_fetched) + self._host = registered_host() + self._loaded_representation_ids = set() + # Refresh loaded scene containers only every 3 seconds at most + self._host_loaded_refresh_timeout = 3 + self._host_loaded_refresh_time = 0 + + self.doc_fetched.connect(self._on_doc_fetched) self.refresh() def get_item_by_id(self, item_id): @@ -472,6 +482,29 @@ class SubsetsModel(TreeModel, BaseRepresentationModel): last_versions_by_subset_id[subset_id] = hero_version + # Check loaded subsets + subsets_loaded_by_id = set() + ids = self._loaded_representation_ids + if ids: + if self._doc_fetching_stop: + return + + # Get subsets from representations + # todo: optimize with aggregation query to distinct subset id + representations = get_representations(project_name, + representation_ids=ids, + fields=["parent"]) + parents_by_repre_id = get_representations_parents( + project_name, + representations=representations + ) + for repre_id, repre_parents in parents_by_repre_id.items(): + _, repre_subset, _, _ = repre_parents + subsets_loaded_by_id.add(repre_subset["_id"]) + + if self._doc_fetching_stop: + return + repre_info = {} if self.sync_server.enabled: version_ids = set() @@ -494,7 +527,8 @@ class SubsetsModel(TreeModel, BaseRepresentationModel): "subset_docs_by_id": subset_docs_by_id, "subset_families": subset_families, "last_versions_by_subset_id": last_versions_by_subset_id, - "repre_info_by_version_id": repre_info + "repre_info_by_version_id": repre_info, + "subsets_loaded_by_id": subsets_loaded_by_id } self.doc_fetched.emit() @@ -526,6 +560,17 @@ class SubsetsModel(TreeModel, BaseRepresentationModel): self.doc_fetched.emit() return + # Collect scene container representations to compare loaded state + # This runs in the main thread because it involves the host DCC + if self._host: + time_since_refresh = time.time() - self._host_loaded_refresh_time + print(time_since_refresh) + if time_since_refresh > self._host_loaded_refresh_timeout: + repre_ids = {con.get("representation") + for con in self._host.ls()} + self._loaded_representation_ids = repre_ids + self._host_loaded_refresh_time = time.time() + self.fetch_subset_and_version() def _on_doc_fetched(self): @@ -547,6 +592,10 @@ class SubsetsModel(TreeModel, BaseRepresentationModel): "repre_info_by_version_id" ) + subsets_loaded_by_id = self._doc_payload.get( + "subsets_loaded_by_id" + ) + if ( asset_docs_by_id is None or subset_docs_by_id is None @@ -561,7 +610,8 @@ class SubsetsModel(TreeModel, BaseRepresentationModel): asset_docs_by_id, subset_docs_by_id, last_versions_by_subset_id, - repre_info_by_version_id + repre_info_by_version_id, + subsets_loaded_by_id ) self.endResetModel() self.refreshed.emit(True) @@ -589,8 +639,12 @@ class SubsetsModel(TreeModel, BaseRepresentationModel): return merge_group def _fill_subset_items( - self, asset_docs_by_id, subset_docs_by_id, last_versions_by_subset_id, - repre_info_by_version_id + self, + asset_docs_by_id, + subset_docs_by_id, + last_versions_by_subset_id, + repre_info_by_version_id, + subsets_loaded_by_id ): _groups_tuple = self.groups_config.split_subsets_for_groups( subset_docs_by_id.values(), self._grouping @@ -614,6 +668,37 @@ class SubsetsModel(TreeModel, BaseRepresentationModel): "index": self.index(group_item.row(), 0) } + def _add_subset_item(subset_doc, parent_item, parent_index): + last_version = last_versions_by_subset_id.get( + subset_doc["_id"] + ) + # do not show subset without version + if not last_version: + return + + data = copy.deepcopy(subset_doc) + data["subset"] = subset_doc["name"] + + asset_id = subset_doc["parent"] + data["asset"] = asset_docs_by_id[asset_id]["name"] + + data["last_version"] = last_version + + loaded = subset_doc["_id"] in subsets_loaded_by_id + data["loaded_in_scene"] = "yes" if loaded else "no" + + # Sync server data + data.update( + self._get_last_repre_info(repre_info_by_version_id, + last_version["_id"])) + + item = Item() + item.update(data) + self.add_child(item, parent_item) + + index = self.index(item.row(), 0, parent_index) + self.set_version(index, last_version) + subset_counter = 0 for group_name, subset_docs_by_name in subset_docs_by_group.items(): parent_item = group_item_by_name[group_name]["item"] @@ -636,31 +721,9 @@ class SubsetsModel(TreeModel, BaseRepresentationModel): _parent_index = parent_index for subset_doc in subset_docs: - asset_id = subset_doc["parent"] - - data = copy.deepcopy(subset_doc) - data["subset"] = subset_name - data["asset"] = asset_docs_by_id[asset_id]["name"] - - last_version = last_versions_by_subset_id.get( - subset_doc["_id"] - ) - data["last_version"] = last_version - - # do not show subset without version - if not last_version: - continue - - data.update( - self._get_last_repre_info(repre_info_by_version_id, - last_version["_id"])) - - item = Item() - item.update(data) - self.add_child(item, _parent_item) - - index = self.index(item.row(), 0, _parent_index) - self.set_version(index, last_version) + _add_subset_item(subset_doc, + parent_item=_parent_item, + parent_index=_parent_index) for subset_name in sorted(subset_docs_without_group.keys()): subset_docs = subset_docs_without_group[subset_name] @@ -675,31 +738,9 @@ class SubsetsModel(TreeModel, BaseRepresentationModel): subset_counter += 1 for subset_doc in subset_docs: - asset_id = subset_doc["parent"] - - data = copy.deepcopy(subset_doc) - data["subset"] = subset_name - data["asset"] = asset_docs_by_id[asset_id]["name"] - - last_version = last_versions_by_subset_id.get( - subset_doc["_id"] - ) - data["last_version"] = last_version - - # do not show subset without version - if not last_version: - continue - - data.update( - self._get_last_repre_info(repre_info_by_version_id, - last_version["_id"])) - - item = Item() - item.update(data) - self.add_child(item, parent_item) - - index = self.index(item.row(), 0, parent_index) - self.set_version(index, last_version) + _add_subset_item(subset_doc, + parent_item=parent_item, + parent_index=parent_index) def data(self, index, role): if not index.isValid(): diff --git a/openpype/tools/loader/widgets.py b/openpype/tools/loader/widgets.py index 48c038418a..3c4a89aa0f 100644 --- a/openpype/tools/loader/widgets.py +++ b/openpype/tools/loader/widgets.py @@ -168,7 +168,8 @@ class SubsetWidget(QtWidgets.QWidget): ("duration", 60), ("handles", 55), ("step", 10), - ("repre_info", 65) + ("repre_info", 65), + ("loaded_in_scene", 20) ) def __init__( From a07650226a3fe54eb3becfbc16881acf7e8ae6cf Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Thu, 11 Aug 2022 18:09:19 +0200 Subject: [PATCH 02/12] Remove unused variables --- openpype/tools/loader/model.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/tools/loader/model.py b/openpype/tools/loader/model.py index 3130f879df..6cb9ba2c6d 100644 --- a/openpype/tools/loader/model.py +++ b/openpype/tools/loader/model.py @@ -498,8 +498,8 @@ class SubsetsModel(TreeModel, BaseRepresentationModel): project_name, representations=representations ) - for repre_id, repre_parents in parents_by_repre_id.items(): - _, repre_subset, _, _ = repre_parents + for repre_parents in parents_by_repre_id.values(): + repre_subset = repre_parents[1] subsets_loaded_by_id.add(repre_subset["_id"]) if self._doc_fetching_stop: From b3517a2da945b72b6b13eff292fa7d6ed63861b0 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Fri, 12 Aug 2022 09:47:21 +0200 Subject: [PATCH 03/12] Remove print statement --- openpype/tools/loader/model.py | 1 - 1 file changed, 1 deletion(-) diff --git a/openpype/tools/loader/model.py b/openpype/tools/loader/model.py index 6cb9ba2c6d..d9b1c708e0 100644 --- a/openpype/tools/loader/model.py +++ b/openpype/tools/loader/model.py @@ -564,7 +564,6 @@ class SubsetsModel(TreeModel, BaseRepresentationModel): # This runs in the main thread because it involves the host DCC if self._host: time_since_refresh = time.time() - self._host_loaded_refresh_time - print(time_since_refresh) if time_since_refresh > self._host_loaded_refresh_timeout: repre_ids = {con.get("representation") for con in self._host.ls()} From ca40a71f5c33a1f557039661bbbdd8db5d22738b Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Fri, 12 Aug 2022 09:48:52 +0200 Subject: [PATCH 04/12] Reduce queries to get loaded subset ids --- openpype/tools/loader/model.py | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/openpype/tools/loader/model.py b/openpype/tools/loader/model.py index d9b1c708e0..9d1f1e045c 100644 --- a/openpype/tools/loader/model.py +++ b/openpype/tools/loader/model.py @@ -483,24 +483,22 @@ class SubsetsModel(TreeModel, BaseRepresentationModel): last_versions_by_subset_id[subset_id] = hero_version # Check loaded subsets - subsets_loaded_by_id = set() + loaded_subset_ids = set() ids = self._loaded_representation_ids if ids: if self._doc_fetching_stop: return - # Get subsets from representations + # Get subset ids from loaded representations in workfile # todo: optimize with aggregation query to distinct subset id representations = get_representations(project_name, representation_ids=ids, fields=["parent"]) - parents_by_repre_id = get_representations_parents( - project_name, - representations=representations - ) - for repre_parents in parents_by_repre_id.values(): - repre_subset = repre_parents[1] - subsets_loaded_by_id.add(repre_subset["_id"]) + version_ids = set(repre["parent"] for repre in representations) + versions = get_versions(project_name, + version_ids=version_ids, + fields=["parent"]) + loaded_subset_ids = set(version["parent"] for version in versions) if self._doc_fetching_stop: return @@ -528,7 +526,7 @@ class SubsetsModel(TreeModel, BaseRepresentationModel): "subset_families": subset_families, "last_versions_by_subset_id": last_versions_by_subset_id, "repre_info_by_version_id": repre_info, - "subsets_loaded_by_id": subsets_loaded_by_id + "subsets_loaded_by_id": loaded_subset_ids } self.doc_fetched.emit() From ff149b68215adc8c0211d7248d94b17376496ad1 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Thu, 8 Sep 2022 19:42:55 +0200 Subject: [PATCH 05/12] Remove unused import --- openpype/tools/loader/model.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/openpype/tools/loader/model.py b/openpype/tools/loader/model.py index 9d1f1e045c..19b135bfc5 100644 --- a/openpype/tools/loader/model.py +++ b/openpype/tools/loader/model.py @@ -14,8 +14,7 @@ from openpype.client import ( get_versions, get_hero_versions, get_version_by_name, - get_representations, - get_representations_parents + get_representations ) from openpype.pipeline import ( registered_host, From dc903c752014348bda4fd4a2a05600ab7ec66f87 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Thu, 8 Sep 2022 19:49:17 +0200 Subject: [PATCH 06/12] Store `loaded_in_scene` as `bool` in model --- openpype/tools/loader/model.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/openpype/tools/loader/model.py b/openpype/tools/loader/model.py index 19b135bfc5..8543672617 100644 --- a/openpype/tools/loader/model.py +++ b/openpype/tools/loader/model.py @@ -679,9 +679,7 @@ class SubsetsModel(TreeModel, BaseRepresentationModel): data["asset"] = asset_docs_by_id[asset_id]["name"] data["last_version"] = last_version - - loaded = subset_doc["_id"] in subsets_loaded_by_id - data["loaded_in_scene"] = "yes" if loaded else "no" + data["loaded_in_scene"] = subset_doc["_id"] in subsets_loaded_by_id # Sync server data data.update( From 9ebd602a91a21e427cbd063bdd3841a0370d6b22 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Thu, 8 Sep 2022 20:06:34 +0200 Subject: [PATCH 07/12] Add delegate to loaded in scene column for "yes/no" and colorized column --- openpype/tools/loader/widgets.py | 7 ++++++- openpype/tools/utils/delegates.py | 27 +++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/openpype/tools/loader/widgets.py b/openpype/tools/loader/widgets.py index 3c4a89aa0f..e27d7e6a12 100644 --- a/openpype/tools/loader/widgets.py +++ b/openpype/tools/loader/widgets.py @@ -36,7 +36,8 @@ from openpype.tools.utils import ( ) from openpype.tools.utils.delegates import ( VersionDelegate, - PrettyTimeDelegate + PrettyTimeDelegate, + LoadedInSceneDelegate ) from openpype.tools.utils.widgets import ( OptionalMenu, @@ -234,6 +235,10 @@ class SubsetWidget(QtWidgets.QWidget): column = model.Columns.index("repre_info") view.setItemDelegateForColumn(column, avail_delegate) + loaded_in_scene_delegate = LoadedInSceneDelegate(view) + column = model.Columns.index("loaded_in_scene") + view.setItemDelegateForColumn(column, loaded_in_scene_delegate) + layout = QtWidgets.QVBoxLayout(self) layout.setContentsMargins(0, 0, 0, 0) layout.addLayout(top_bar_layout) diff --git a/openpype/tools/utils/delegates.py b/openpype/tools/utils/delegates.py index d6c2d69e76..3547251282 100644 --- a/openpype/tools/utils/delegates.py +++ b/openpype/tools/utils/delegates.py @@ -291,3 +291,30 @@ class PrettyTimeDelegate(QtWidgets.QStyledItemDelegate): def displayText(self, value, locale): if value is not None: return pretty_timestamp(value) + + +class LoadedInSceneDelegate(QtWidgets.QStyledItemDelegate): + """Delegate for Loaded in Scene state columns. + + Shows "yes" or "no" for True or False values + Colorizes green or dark grey based on True or False values + + """ + + def __init__(self, *args, **kwargs): + super(LoadedInSceneDelegate, self).__init__(*args, **kwargs) + self._colors = { + True: QtGui.QColor(80, 170, 80), + False: QtGui.QColor(90, 90, 90) + } + + def displayText(self, value, locale): + return "yes" if value else "no" + + def initStyleOption(self, option, index): + super(LoadedInSceneDelegate, self).initStyleOption(option, index) + + # Colorize based on value + value = index.data(QtCore.Qt.DisplayRole) + color = self._colors[bool(value)] + option.palette.setBrush(QtGui.QPalette.Text, color) From d5cb828edc611f9ed9f98b61ae5ae3591d797640 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 14 Sep 2022 11:45:44 +0200 Subject: [PATCH 08/12] Move LoadedInSceneDelegate into Loader tool since it's specific to loader --- openpype/tools/loader/delegates.py | 28 ++++++++++++++++++++++++++++ openpype/tools/loader/widgets.py | 4 ++-- openpype/tools/utils/delegates.py | 27 --------------------------- 3 files changed, 30 insertions(+), 29 deletions(-) create mode 100644 openpype/tools/loader/delegates.py diff --git a/openpype/tools/loader/delegates.py b/openpype/tools/loader/delegates.py new file mode 100644 index 0000000000..e6663d48f1 --- /dev/null +++ b/openpype/tools/loader/delegates.py @@ -0,0 +1,28 @@ +from Qt import QtWidgets, QtGui, QtCore + + +class LoadedInSceneDelegate(QtWidgets.QStyledItemDelegate): + """Delegate for Loaded in Scene state columns. + + Shows "yes" or "no" for True or False values + Colorizes green or dark grey based on True or False values + + """ + + def __init__(self, *args, **kwargs): + super(LoadedInSceneDelegate, self).__init__(*args, **kwargs) + self._colors = { + True: QtGui.QColor(80, 170, 80), + False: QtGui.QColor(90, 90, 90) + } + + def displayText(self, value, locale): + return "yes" if value else "no" + + def initStyleOption(self, option, index): + super(LoadedInSceneDelegate, self).initStyleOption(option, index) + + # Colorize based on value + value = index.data(QtCore.Qt.DisplayRole) + color = self._colors[bool(value)] + option.palette.setBrush(QtGui.QPalette.Text, color) diff --git a/openpype/tools/loader/widgets.py b/openpype/tools/loader/widgets.py index 615f28f04d..98522c48ce 100644 --- a/openpype/tools/loader/widgets.py +++ b/openpype/tools/loader/widgets.py @@ -37,8 +37,7 @@ from openpype.tools.utils import ( ) from openpype.tools.utils.delegates import ( VersionDelegate, - PrettyTimeDelegate, - LoadedInSceneDelegate + PrettyTimeDelegate ) from openpype.tools.utils.widgets import ( OptionalMenu, @@ -59,6 +58,7 @@ from .model import ( ITEM_ID_ROLE ) from . import lib +from .delegates import LoadedInSceneDelegate from openpype.tools.utils.constants import ( LOCAL_PROVIDER_ROLE, diff --git a/openpype/tools/utils/delegates.py b/openpype/tools/utils/delegates.py index 3547251282..d6c2d69e76 100644 --- a/openpype/tools/utils/delegates.py +++ b/openpype/tools/utils/delegates.py @@ -291,30 +291,3 @@ class PrettyTimeDelegate(QtWidgets.QStyledItemDelegate): def displayText(self, value, locale): if value is not None: return pretty_timestamp(value) - - -class LoadedInSceneDelegate(QtWidgets.QStyledItemDelegate): - """Delegate for Loaded in Scene state columns. - - Shows "yes" or "no" for True or False values - Colorizes green or dark grey based on True or False values - - """ - - def __init__(self, *args, **kwargs): - super(LoadedInSceneDelegate, self).__init__(*args, **kwargs) - self._colors = { - True: QtGui.QColor(80, 170, 80), - False: QtGui.QColor(90, 90, 90) - } - - def displayText(self, value, locale): - return "yes" if value else "no" - - def initStyleOption(self, option, index): - super(LoadedInSceneDelegate, self).initStyleOption(option, index) - - # Colorize based on value - value = index.data(QtCore.Qt.DisplayRole) - color = self._colors[bool(value)] - option.palette.setBrush(QtGui.QPalette.Text, color) From d84b175efbc60c226609c6393dddedbf9960c7be Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 14 Sep 2022 11:47:52 +0200 Subject: [PATCH 09/12] Support ILoadHost hosts Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- openpype/tools/loader/model.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/openpype/tools/loader/model.py b/openpype/tools/loader/model.py index 58d6787507..17af7bb2f7 100644 --- a/openpype/tools/loader/model.py +++ b/openpype/tools/loader/model.py @@ -569,6 +569,11 @@ class SubsetsModel(TreeModel, BaseRepresentationModel): if self._host: time_since_refresh = time.time() - self._host_loaded_refresh_time if time_since_refresh > self._host_loaded_refresh_timeout: + if isinstance(self._host, ILoadHost): + containers = self._host.get_containers() + else: + containers = self._host.ls() + repre_ids = {con.get("representation") for con in self._host.ls()} self._loaded_representation_ids = repre_ids From a8909889c4662764042288245ef2d901d1218055 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 14 Sep 2022 11:49:52 +0200 Subject: [PATCH 10/12] Fix refactored code --- openpype/tools/loader/model.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openpype/tools/loader/model.py b/openpype/tools/loader/model.py index 17af7bb2f7..1c078325f3 100644 --- a/openpype/tools/loader/model.py +++ b/openpype/tools/loader/model.py @@ -25,6 +25,7 @@ from openpype.pipeline import ( from openpype.style import get_default_entity_icon_color from openpype.tools.utils.models import TreeModel, Item from openpype.tools.utils import lib +from openpype.host import ILoadHost from openpype.modules import ModulesManager from openpype.tools.utils.constants import ( @@ -573,9 +574,8 @@ class SubsetsModel(TreeModel, BaseRepresentationModel): containers = self._host.get_containers() else: containers = self._host.ls() - - repre_ids = {con.get("representation") - for con in self._host.ls()} + + repre_ids = {con.get("representation") for con in containers} self._loaded_representation_ids = repre_ids self._host_loaded_refresh_time = time.time() From 1eae84fd49af6930eb7865451c17557bf1d4d8b6 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 14 Sep 2022 11:58:10 +0200 Subject: [PATCH 11/12] Switch columns --- openpype/tools/loader/model.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openpype/tools/loader/model.py b/openpype/tools/loader/model.py index 1c078325f3..77a8669c46 100644 --- a/openpype/tools/loader/model.py +++ b/openpype/tools/loader/model.py @@ -138,8 +138,8 @@ class SubsetsModel(TreeModel, BaseRepresentationModel): "duration", "handles", "step", - "repre_info", - "loaded_in_scene" + "loaded_in_scene", + "repre_info" ] column_labels_mapping = { @@ -153,8 +153,8 @@ class SubsetsModel(TreeModel, BaseRepresentationModel): "duration": "Duration", "handles": "Handles", "step": "Step", - "repre_info": "Availability", - "loaded_in_scene": "In scene" + "loaded_in_scene": "In scene", + "repre_info": "Availability" } SortAscendingRole = QtCore.Qt.UserRole + 2 From c3588e2f9d337109aea3c2630fb12079b617d81d Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 14 Sep 2022 12:37:46 +0200 Subject: [PATCH 12/12] Make `loaded_in_scene` column 5 pixels wider + reorder to match with column order --- openpype/tools/loader/widgets.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/tools/loader/widgets.py b/openpype/tools/loader/widgets.py index 98522c48ce..c028aa4174 100644 --- a/openpype/tools/loader/widgets.py +++ b/openpype/tools/loader/widgets.py @@ -170,8 +170,8 @@ class SubsetWidget(QtWidgets.QWidget): ("duration", 60), ("handles", 55), ("step", 10), - ("repre_info", 65), - ("loaded_in_scene", 20) + ("loaded_in_scene", 25), + ("repre_info", 65) ) def __init__(