From 9ce2eedde6bcc9cb18abc0a9362d9ef0e0dec964 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 15 Jul 2021 16:01:59 +0200 Subject: [PATCH] implemented card view of instances --- openpype/tools/new_publisher/widgets.py | 171 ++++++++++++++++++++++++ 1 file changed, 171 insertions(+) diff --git a/openpype/tools/new_publisher/widgets.py b/openpype/tools/new_publisher/widgets.py index b8a56619ac..648cbac697 100644 --- a/openpype/tools/new_publisher/widgets.py +++ b/openpype/tools/new_publisher/widgets.py @@ -741,3 +741,174 @@ class CreateDialog(QtWidgets.QDialog): if self.auto_close_checkbox.isChecked(): self.hide() + + +class InstanceCardWidget(QtWidgets.QWidget): + active_changed = QtCore.Signal(str, bool) + + def __init__(self, instance, item, parent): + super(InstanceCardWidget, self).__init__(parent) + + self.instance = instance + self.item = item + + subset_name_label = QtWidgets.QLabel(instance.data["subset"], self) + active_checkbox = QtWidgets.QCheckBox(self) + active_checkbox.setStyleSheet("background: transparent;") + active_checkbox.setChecked(instance.data["active"]) + + expand_btn = QtWidgets.QToolButton(self) + expand_btn.setArrowType(QtCore.Qt.DownArrow) + expand_btn.setMaximumWidth(14) + expand_btn.setEnabled(False) + + detail_widget = QtWidgets.QWidget(self) + detail_widget.setVisible(False) + self.detail_widget = detail_widget + + top_layout = QtWidgets.QHBoxLayout() + top_layout.addWidget(subset_name_label) + top_layout.addStretch(1) + top_layout.addWidget(active_checkbox) + top_layout.addWidget(expand_btn) + + layout = QtWidgets.QVBoxLayout(self) + layout.setContentsMargins(2, 2, 2, 2) + layout.addLayout(top_layout) + layout.addWidget(detail_widget) + + self.setAttribute(QtCore.Qt.WA_TranslucentBackground) + subset_name_label.setAttribute(QtCore.Qt.WA_TranslucentBackground) + active_checkbox.setAttribute(QtCore.Qt.WA_TranslucentBackground) + expand_btn.setAttribute(QtCore.Qt.WA_TranslucentBackground) + + active_checkbox.stateChanged.connect(self._on_active_change) + expand_btn.clicked.connect(self._on_expend_clicked) + + self.subset_name_label = subset_name_label + self.active_checkbox = active_checkbox + self.expand_btn = expand_btn + + def set_active(self, new_value): + checkbox_value = self.active_checkbox.isChecked() + instance_value = self.instance.data["active"] + if instance_value == checkbox_value == new_value: + return + + # First change instance value and them change checkbox + # - prevent to trigger `active_changed` signal + self.instance.data["active"] = new_value + self.active_checkbox.setChecked(new_value) + + def update_instance(self, instance): + self.instance = instance + self.set_active(instance.data["active"]) + + def _set_expanded(self, expanded=None): + if expanded is None: + expanded = not self.detail_widget.isVisible() + self.detail_widget.setVisible(expanded) + self.item.setSizeHint(self.sizeHint()) + + def showEvent(self, event): + super(InstanceCardWidget, self).showEvent(event) + self.item.setSizeHint(self.sizeHint()) + + def _on_active_change(self): + new_value = self.active_checkbox.isChecked() + old_value = self.instance.data["active"] + if new_value == old_value: + return + + self.instance.data["active"] = new_value + self.active_changed.emit(self.instance.data["uuid"], new_value) + + def _on_expend_clicked(self): + self._set_expanded() + + +class InstanceCardView(QtWidgets.QWidget): + selection_changed = QtCore.Signal() + + def __init__(self, controller, parent): + super(InstanceCardView, self).__init__(parent) + + self.controller = controller + + list_widget = QtWidgets.QListWidget(self) + list_widget.setSelectionMode( + QtWidgets.QAbstractItemView.ExtendedSelection + ) + list_widget.setResizeMode(QtWidgets.QListView.Adjust) + + layout = QtWidgets.QHBoxLayout(self) + layout.setContentsMargins(0, 0, 0, 0) + layout.addWidget(list_widget, 1) + + list_widget.selectionModel().selectionChanged.connect( + self._on_selection_change + ) + + self._items_by_id = {} + self._widgets_by_id = {} + + self.list_widget = list_widget + + def refresh(self): + instances_by_id = {} + for instance in self.controller.instances: + instance_id = instance.data["uuid"] + instances_by_id[instance_id] = instance + + for instance_id in tuple(self._items_by_id.keys()): + if instance_id not in instances_by_id: + item = self._items_by_id.pop(instance_id) + self.list_widget.removeItemWidget(item) + widget = self._widgets_by_id.pop(instance_id) + widget.deleteLater() + row = self.list_widget.row(item) + self.list_widget.takeItem(row) + + for instance_id, instance in instances_by_id.items(): + if instance_id in self._items_by_id: + widget = self._widgets_by_id[instance_id] + widget.update_instance(instance) + + else: + item = QtWidgets.QListWidgetItem(self.list_widget) + widget = InstanceCardWidget(instance, item, self) + widget.active_changed.connect(self._on_active_changed) + item.setData(QtCore.Qt.UserRole, instance_id) + self.list_widget.addItem(item) + self.list_widget.setItemWidget(item, widget) + self._items_by_id[instance_id] = item + self._widgets_by_id[instance_id] = widget + + def _on_active_changed(self, changed_instance_id, new_value): + selected_ids = set() + found = False + for item in self.list_widget.selectedItems(): + instance_id = item.data(QtCore.Qt.UserRole) + selected_ids.add(instance_id) + if not found and instance_id == changed_instance_id: + found = True + + if not found: + return + + for instance_id in selected_ids: + widget = self._widgets_by_id.get(instance_id) + if widget: + widget.set_active(new_value) + + def _on_selection_change(self, *_args): + self.selection_changed.emit() + + def get_selected_instances(self): + instances = [] + for item in self.list_widget.selectedItems(): + instance_id = item.data(QtCore.Qt.UserRole) + widget = self._widgets_by_id.get(instance_id) + if widget: + instances.append(widget.instance) + return instances