From 2c4d37d1bfef0b83134bd00775b00815493366cc Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 31 Oct 2022 19:23:22 +0100 Subject: [PATCH 01/19] added create next overlay widget --- openpype/tools/publisher/widgets/__init__.py | 2 + openpype/tools/publisher/widgets/widgets.py | 201 +++++++++++++++++++ 2 files changed, 203 insertions(+) diff --git a/openpype/tools/publisher/widgets/__init__.py b/openpype/tools/publisher/widgets/__init__.py index a02c69d5e0..042985b007 100644 --- a/openpype/tools/publisher/widgets/__init__.py +++ b/openpype/tools/publisher/widgets/__init__.py @@ -8,6 +8,7 @@ from .widgets import ( ResetBtn, ValidateBtn, PublishBtn, + CreateNextPageOverlay, ) from .help_widget import ( HelpButton, @@ -28,6 +29,7 @@ __all__ = ( "ResetBtn", "ValidateBtn", "PublishBtn", + "CreateNextPageOverlay", "HelpButton", "HelpDialog", diff --git a/openpype/tools/publisher/widgets/widgets.py b/openpype/tools/publisher/widgets/widgets.py index d4c2623790..507ecedb0f 100644 --- a/openpype/tools/publisher/widgets/widgets.py +++ b/openpype/tools/publisher/widgets/widgets.py @@ -1652,3 +1652,204 @@ class ThumbnailWidget(QtWidgets.QWidget): self.thumbnail_label = thumbnail_label self.default_pix = default_pix self.current_pix = None + + +class CreateNextPageOverlay(QtWidgets.QWidget): + max_value = 100.0 + clicked = QtCore.Signal() + + def __init__(self, parent): + super(CreateNextPageOverlay, self).__init__(parent) + + self._bg_color = QtGui.QColor(127, 127, 255) + self._arrow_color = QtGui.QColor(255, 255, 255) + + change_anim = QtCore.QVariantAnimation() + change_anim.setStartValue(0.0) + change_anim.setEndValue(self.max_value) + change_anim.setDuration(200) + change_anim.setEasingCurve(QtCore.QEasingCurve.InOutQuad) + + change_anim.valueChanged.connect(self._on_anim) + + self._change_anim = change_anim + self._is_visible = None + self._anim_value = 0.0 + self._increasing = False + self._under_mouse = None + self._handle_show_on_own = True + self._mouse_pressed = False + self.set_visible(True) + + def set_increasing(self, increasing): + if self._increasing is increasing: + return + self._increasing = increasing + if increasing: + self._change_anim.setDirection(self._change_anim.Forward) + else: + self._change_anim.setDirection(self._change_anim.Backward) + + if self._change_anim.state() != self._change_anim.Running: + self._change_anim.start() + + def set_visible(self, visible): + if self._is_visible is visible: + return + + self._is_visible = visible + if not visible: + self.set_increasing(False) + if not self._is_anim_finished(): + return + + self.setVisible(visible) + self._check_anim_timer() + + def _is_anim_finished(self): + if self._increasing: + return self._anim_value == self.max_value + return self._anim_value == 0.0 + + def _on_anim(self, value): + self._check_anim_timer() + + self._anim_value = value + + self.update() + + if not self._is_anim_finished(): + return + + if not self._is_visible: + self.setVisible(False) + + def set_handle_show_on_own(self, handle): + if self._handle_show_on_own is handle: + return + self._handle_show_on_own = handle + self._under_mouse = None + self._check_anim_timer() + + def set_under_mouse(self, under_mouse): + if self._under_mouse is under_mouse: + return + + if self._handle_show_on_own: + self._handle_show_on_own = False + self._under_mouse = under_mouse + self.set_increasing(under_mouse) + + def _is_under_mouse(self): + mouse_pos = self.mapFromGlobal(QtGui.QCursor.pos()) + under_mouse = self.rect().contains(mouse_pos) + return under_mouse + + def _check_anim_timer(self): + if not self.isVisible(): + return + + if self._handle_show_on_own: + under_mouse = self._is_under_mouse() + else: + under_mouse = self._under_mouse + + self.set_increasing(under_mouse) + + def enterEvent(self, event): + super(CreateNextPageOverlay, self).enterEvent(event) + if self._handle_show_on_own: + self._check_anim_timer() + + def leaveEvent(self, event): + super(CreateNextPageOverlay, self).leaveEvent(event) + if self._handle_show_on_own: + self._check_anim_timer() + + def mousePressEvent(self, event): + if event.button() == QtCore.Qt.LeftButton: + self._mouse_pressed = True + super(CreateNextPageOverlay, self).mousePressEvent(event) + + def mouseReleaseEvent(self, event): + if self._mouse_pressed: + self._mouse_pressed = False + if self.rect().contains(event.pos()): + self.clicked.emit() + + super(CreateNextPageOverlay, self).mouseReleaseEvent(event) + + def paintEvent(self, event): + painter = QtGui.QPainter() + painter.begin(self) + if self._anim_value == 0.0: + painter.end() + return + painter.setRenderHints( + painter.Antialiasing + | painter.SmoothPixmapTransform + ) + + pen = QtGui.QPen() + pen.setWidth(0) + painter.setPen(pen) + rect = QtCore.QRect(self.rect()) + + offset = rect.width() - int( + float(rect.width()) * 0.01 * self._anim_value + ) + + pos_y = rect.center().y() + left = rect.left() + offset + right = rect.right() + top = rect.top() + bottom = rect.bottom() + width = right - left + height = bottom - top + + q_height = height * 0.15 + + arrow_half_height = width * 0.2 + arrow_x_start = left + (width * 0.4) + arrow_x_end = arrow_x_start + arrow_half_height + arrow_top_y_boundry = arrow_half_height + q_height + arrow_bottom_y_boundry = height - (arrow_half_height + q_height) + offset = 0 + if pos_y < arrow_top_y_boundry: + pos_y = arrow_top_y_boundry + elif pos_y > arrow_bottom_y_boundry: + pos_y = arrow_bottom_y_boundry + + top_cubic_y = pos_y - q_height + bottom_cubic_y = pos_y + q_height + + path = QtGui.QPainterPath() + path.moveTo(right, top) + path.lineTo(right, bottom) + + path.cubicTo( + right, bottom, + left, bottom_cubic_y, + left, pos_y + ) + path.cubicTo( + left, top_cubic_y, + right, top, + right, top + ) + path.closeSubpath() + + painter.fillPath(path, self._bg_color) + + src_arrow_path = QtGui.QPainterPath() + src_arrow_path.moveTo(arrow_x_start, pos_y - arrow_half_height) + src_arrow_path.lineTo(arrow_x_end, pos_y) + src_arrow_path.lineTo(arrow_x_start, pos_y + arrow_half_height) + + arrow_stroker = QtGui.QPainterPathStroker() + arrow_stroker.setWidth(min(4, arrow_half_height * 0.2)) + arrow_path = arrow_stroker.createStroke(src_arrow_path) + + painter.fillPath(arrow_path, self._arrow_color) + + painter.end() From 30789058b34e0445da3c6a4a1bb12fafb073c3b9 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 31 Oct 2022 19:23:38 +0100 Subject: [PATCH 02/19] overview widget can return global geo of subset view widget --- openpype/tools/publisher/widgets/overview_widget.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/openpype/tools/publisher/widgets/overview_widget.py b/openpype/tools/publisher/widgets/overview_widget.py index be3839b90b..1c924d1631 100644 --- a/openpype/tools/publisher/widgets/overview_widget.py +++ b/openpype/tools/publisher/widgets/overview_widget.py @@ -195,6 +195,16 @@ class OverviewWidget(QtWidgets.QFrame): self._subset_views_widget.setMaximumWidth(view_width) self._change_anim.start() + def get_subset_views_geo(self): + parent = self._subset_views_widget.parent() + global_pos = parent.mapToGlobal(self._subset_views_widget.pos()) + return QtCore.QRect( + global_pos.x(), + global_pos.y(), + self._subset_views_widget.width(), + self._subset_views_widget.height() + ) + def _on_create_clicked(self): """Pass signal to parent widget which should care about changing state. From 90d0dd718bce3a4537ffe8d2301484369cd67e84 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 31 Oct 2022 19:24:35 +0100 Subject: [PATCH 03/19] prepared methods for set/check current tab --- openpype/tools/publisher/window.py | 31 +++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/openpype/tools/publisher/window.py b/openpype/tools/publisher/window.py index d8a69bbeb0..7a0c34e298 100644 --- a/openpype/tools/publisher/window.py +++ b/openpype/tools/publisher/window.py @@ -403,7 +403,7 @@ class PublisherWindow(QtWidgets.QDialog): self._context_label.setText(label) def _update_publish_details_widget(self, force=False): - if not force and self._tabs_widget.current_tab() != "details": + if not force and not self._is_current_tab("details"): return report_data = self.controller.get_publish_report() @@ -434,7 +434,7 @@ class PublisherWindow(QtWidgets.QDialog): ) def _on_tab_change(self, old_tab, new_tab): - if old_tab == "details": + if old_tab != "details": self._publish_details_widget.close_details_popup() if new_tab in ("create", "publish"): @@ -463,14 +463,23 @@ class PublisherWindow(QtWidgets.QDialog): def _on_create_request(self): self._go_to_create_tab() + def _set_current_tab(self, identifier): + self._tabs_widget.set_current_tab(identifier) + + def _is_current_tab(self, identifier): + return self._tabs_widget.is_current_tab(identifier) + def _go_to_create_tab(self): - self._tabs_widget.set_current_tab("create") + self._set_current_tab("create") + + def _go_to_publish_tab(self): + self._set_current_tab("publish") def _go_to_details_tab(self): - self._tabs_widget.set_current_tab("details") + self._set_current_tab("details") def _go_to_report_tab(self): - self._tabs_widget.set_current_tab("report") + self._set_current_tab("report") def _set_publish_overlay_visibility(self, visible): if visible: @@ -523,10 +532,10 @@ class PublisherWindow(QtWidgets.QDialog): self._set_footer_enabled(False) self._update_publish_details_widget() if ( - not self._tabs_widget.is_current_tab("create") - and not self._tabs_widget.is_current_tab("publish") + not self._is_current_tab("create") + and not self._is_current_tab("publish") ): - self._tabs_widget.set_current_tab("publish") + self._set_current_tab("publish") def _on_publish_start(self): self._create_tab.setEnabled(False) @@ -542,8 +551,8 @@ class PublisherWindow(QtWidgets.QDialog): self._publish_details_widget.close_details_popup() - if self._tabs_widget.is_current_tab(self._create_tab): - self._tabs_widget.set_current_tab("publish") + if self._is_current_tab(self._create_tab): + self._set_current_tab("publish") def _on_publish_validated_change(self, event): if event["value"]: @@ -556,7 +565,7 @@ class PublisherWindow(QtWidgets.QDialog): publish_has_crashed = self._controller.publish_has_crashed validate_enabled = not publish_has_crashed publish_enabled = not publish_has_crashed - if self._tabs_widget.is_current_tab("publish"): + if self._is_current_tab("publish"): self._go_to_report_tab() if validate_enabled: From ee94f7c46c707846277a8faf4fb3bcf6087f1edf Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 31 Oct 2022 19:24:56 +0100 Subject: [PATCH 04/19] added overlay widget and necessary parts to window --- openpype/tools/publisher/window.py | 85 +++++++++++++++++++++++++++--- 1 file changed, 78 insertions(+), 7 deletions(-) diff --git a/openpype/tools/publisher/window.py b/openpype/tools/publisher/window.py index 7a0c34e298..ddac19f2e5 100644 --- a/openpype/tools/publisher/window.py +++ b/openpype/tools/publisher/window.py @@ -29,6 +29,8 @@ from .widgets import ( HelpButton, HelpDialog, + + CreateNextPageOverlay, ) @@ -225,8 +227,9 @@ class PublisherWindow(QtWidgets.QDialog): # Floating publish frame publish_frame = PublishFrame(controller, self.footer_border, self) - # Timer started on show -> connected to timer counter - # - helps to deffer on show logic by 3 event loops + create_overlay_button = CreateNextPageOverlay(self) + create_overlay_button.set_handle_show_on_own(False) + show_timer = QtCore.QTimer() show_timer.setInterval(1) show_timer.timeout.connect(self._on_show_timer) @@ -255,6 +258,7 @@ class PublisherWindow(QtWidgets.QDialog): publish_btn.clicked.connect(self._on_publish_clicked) publish_frame.details_page_requested.connect(self._go_to_details_tab) + create_overlay_button.clicked.connect(self._go_to_publish_tab) controller.event_system.add_callback( "instances.refresh.finished", self._on_instances_refresh @@ -310,6 +314,7 @@ class PublisherWindow(QtWidgets.QDialog): self._publish_overlay = publish_overlay self._publish_frame = publish_frame + self._content_widget = content_widget self._content_stacked_layout = content_stacked_layout self._overview_widget = overview_widget @@ -342,6 +347,9 @@ class PublisherWindow(QtWidgets.QDialog): self._set_publish_visibility(False) + self._create_overlay_button = create_overlay_button + self._app_event_listener_installed = False + self._show_timer = show_timer self._show_counter = 0 @@ -355,11 +363,38 @@ class PublisherWindow(QtWidgets.QDialog): self._first_show = False self._on_first_show() + self._show_counter = 0 self._show_timer.start() def resizeEvent(self, event): super(PublisherWindow, self).resizeEvent(event) self._update_publish_frame_rect() + self._update_create_overlay_size() + + def closeEvent(self, event): + self._uninstall_app_event_listener() + self.save_changes() + self._reset_on_show = True + super(PublisherWindow, self).closeEvent(event) + + def eventFilter(self, obj, event): + if event.type() == QtCore.QEvent.MouseMove: + self._update_create_overlay_visibility(event.globalPos()) + return super(PublisherWindow, self).eventFilter(obj, event) + + def _install_app_event_listener(self): + if self._app_event_listener_installed: + return + self._app_event_listener_installed = True + app = QtWidgets.QApplication.instance() + app.installEventFilter(self) + + def _uninstall_app_event_listener(self): + if not self._app_event_listener_installed: + return + self._app_event_listener_installed = False + app = QtWidgets.QApplication.instance() + app.removeEventFilter(self) def _on_overlay_message(self, event): self._overlay_object.add_message( @@ -383,16 +418,16 @@ class PublisherWindow(QtWidgets.QDialog): # Reset counter when done for next show event self._show_counter = 0 + self._update_create_overlay_size() + self._update_create_overlay_visibility() + if self._is_current_tab("create"): + self._install_app_event_listener() + # Reset if requested if self._reset_on_show: self._reset_on_show = False self.reset() - def closeEvent(self, event): - self.save_changes() - self._reset_on_show = True - super(PublisherWindow, self).closeEvent(event) - def save_changes(self): self._controller.save_changes() @@ -457,6 +492,13 @@ class PublisherWindow(QtWidgets.QDialog): self._report_widget ) + is_create = new_tab == "create" + if is_create: + self._install_app_event_listener() + else: + self._uninstall_app_event_listener() + self._create_overlay_button.set_visible(is_create) + def _on_context_or_active_change(self): self._validate_create_instances() @@ -669,6 +711,35 @@ class PublisherWindow(QtWidgets.QDialog): event["title"], new_failed_info, "Convertor:" ) + def _update_create_overlay_size(self): + height = self._content_widget.height() + metrics = self._create_overlay_button.fontMetrics() + width = int(metrics.height() * 3) + pos_x = self.width() - width + + tab_pos = self._tabs_widget.parent().mapTo( + self, self._tabs_widget.pos() + ) + tab_height = self._tabs_widget.height() + pos_y = tab_pos.y() + tab_height + + self._create_overlay_button.setGeometry( + pos_x, pos_y, + width, height + ) + + def _update_create_overlay_visibility(self, global_pos=None): + if global_pos is None: + global_pos = QtGui.QCursor.pos() + + under_mouse = False + my_pos = self.mapFromGlobal(global_pos) + if self.rect().contains(my_pos): + widget_geo = self._overview_widget.get_subset_views_geo() + widget_x = widget_geo.left() + (widget_geo.width() * 0.5) + under_mouse = widget_x < global_pos.x() + self._create_overlay_button.set_under_mouse(under_mouse) + class ErrorsMessageBox(ErrorMessageBox): def __init__(self, error_title, failed_info, message_start, parent): From ea6e924dd95b86053092af0f08790b8e8a77be83 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 31 Oct 2022 19:31:53 +0100 Subject: [PATCH 05/19] use gradient and different color --- openpype/tools/publisher/widgets/widgets.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/openpype/tools/publisher/widgets/widgets.py b/openpype/tools/publisher/widgets/widgets.py index 507ecedb0f..975a1faa06 100644 --- a/openpype/tools/publisher/widgets/widgets.py +++ b/openpype/tools/publisher/widgets/widgets.py @@ -1661,7 +1661,6 @@ class CreateNextPageOverlay(QtWidgets.QWidget): def __init__(self, parent): super(CreateNextPageOverlay, self).__init__(parent) - self._bg_color = QtGui.QColor(127, 127, 255) self._arrow_color = QtGui.QColor(255, 255, 255) change_anim = QtCore.QVariantAnimation() @@ -1839,7 +1838,11 @@ class CreateNextPageOverlay(QtWidgets.QWidget): ) path.closeSubpath() - painter.fillPath(path, self._bg_color) + gradient = QtGui.QLinearGradient(left, pos_y, right, pos_y) + gradient.setColorAt(0, QtGui.QColor(22, 25, 29)) + gradient.setColorAt(1, QtGui.QColor(33, 37, 43)) + + painter.fillPath(path, gradient) src_arrow_path = QtGui.QPainterPath() src_arrow_path.moveTo(arrow_x_start, pos_y - arrow_half_height) From 42b1012e7c320ec783df7ce5c76b76a24e18896e Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 31 Oct 2022 19:41:12 +0100 Subject: [PATCH 06/19] use radial gradient --- openpype/tools/publisher/widgets/widgets.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/openpype/tools/publisher/widgets/widgets.py b/openpype/tools/publisher/widgets/widgets.py index 975a1faa06..c4481d4d9d 100644 --- a/openpype/tools/publisher/widgets/widgets.py +++ b/openpype/tools/publisher/widgets/widgets.py @@ -1838,7 +1838,10 @@ class CreateNextPageOverlay(QtWidgets.QWidget): ) path.closeSubpath() - gradient = QtGui.QLinearGradient(left, pos_y, right, pos_y) + radius = height * 0.7 + focal = QtCore.QPointF(left, pos_y) + start_p = QtCore.QPointF(right - (width * 0.5), pos_y) + gradient = QtGui.QRadialGradient(start_p, radius, focal) gradient.setColorAt(0, QtGui.QColor(22, 25, 29)) gradient.setColorAt(1, QtGui.QColor(33, 37, 43)) From e4e6044198a7240e21387c2931926f7d0cffdbc2 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 1 Nov 2022 11:56:27 +0100 Subject: [PATCH 07/19] fix last pixel --- openpype/tools/publisher/widgets/widgets.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/openpype/tools/publisher/widgets/widgets.py b/openpype/tools/publisher/widgets/widgets.py index c4481d4d9d..b8fb2d38b9 100644 --- a/openpype/tools/publisher/widgets/widgets.py +++ b/openpype/tools/publisher/widgets/widgets.py @@ -1800,9 +1800,10 @@ class CreateNextPageOverlay(QtWidgets.QWidget): pos_y = rect.center().y() left = rect.left() + offset - right = rect.right() top = rect.top() - bottom = rect.bottom() + # Right and bootm is pixel index + right = rect.right() + 1 + bottom = rect.bottom() + 1 width = right - left height = bottom - top From 049de296240198cdf296d0ff411c2601f1568589 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 1 Nov 2022 11:57:32 +0100 Subject: [PATCH 08/19] handle leave event --- openpype/tools/publisher/window.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/openpype/tools/publisher/window.py b/openpype/tools/publisher/window.py index ddac19f2e5..2063cdab96 100644 --- a/openpype/tools/publisher/window.py +++ b/openpype/tools/publisher/window.py @@ -377,6 +377,10 @@ class PublisherWindow(QtWidgets.QDialog): self._reset_on_show = True super(PublisherWindow, self).closeEvent(event) + def leaveEvent(self, event): + super(PublisherWindow, self).leaveEvent(event) + self._update_create_overlay_visibility() + def eventFilter(self, obj, event): if event.type() == QtCore.QEvent.MouseMove: self._update_create_overlay_visibility(event.globalPos()) From d655a53136e724179da0889d0e508b607d9d173c Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 1 Nov 2022 18:45:07 +0100 Subject: [PATCH 09/19] use objected colors from styles --- openpype/tools/publisher/widgets/widgets.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/openpype/tools/publisher/widgets/widgets.py b/openpype/tools/publisher/widgets/widgets.py index b8fb2d38b9..444ad4c7dc 100644 --- a/openpype/tools/publisher/widgets/widgets.py +++ b/openpype/tools/publisher/widgets/widgets.py @@ -1661,7 +1661,15 @@ class CreateNextPageOverlay(QtWidgets.QWidget): def __init__(self, parent): super(CreateNextPageOverlay, self).__init__(parent) - self._arrow_color = QtGui.QColor(255, 255, 255) + self._arrow_color = ( + get_objected_colors("bg-buttons").get_qcolor() + ) + self._gradient_start_color = ( + get_objected_colors("publisher", "tab-bg").get_qcolor() + ) + self._gradient_end_color = ( + get_objected_colors("bg-inputs").get_qcolor() + ) change_anim = QtCore.QVariantAnimation() change_anim.setStartValue(0.0) @@ -1843,8 +1851,8 @@ class CreateNextPageOverlay(QtWidgets.QWidget): focal = QtCore.QPointF(left, pos_y) start_p = QtCore.QPointF(right - (width * 0.5), pos_y) gradient = QtGui.QRadialGradient(start_p, radius, focal) - gradient.setColorAt(0, QtGui.QColor(22, 25, 29)) - gradient.setColorAt(1, QtGui.QColor(33, 37, 43)) + gradient.setColorAt(0, self._gradient_start_color) + gradient.setColorAt(1, self._gradient_end_color) painter.fillPath(path, gradient) From befd6889ccf35216e1153eec5742d0b16edcceed Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 4 Nov 2022 21:25:12 +0100 Subject: [PATCH 10/19] use much simpler UI for the button --- openpype/tools/publisher/widgets/widgets.py | 112 +++++--------------- openpype/tools/publisher/window.py | 19 ++-- 2 files changed, 35 insertions(+), 96 deletions(-) diff --git a/openpype/tools/publisher/widgets/widgets.py b/openpype/tools/publisher/widgets/widgets.py index 444ad4c7dc..a180107380 100644 --- a/openpype/tools/publisher/widgets/widgets.py +++ b/openpype/tools/publisher/widgets/widgets.py @@ -1660,22 +1660,19 @@ class CreateNextPageOverlay(QtWidgets.QWidget): def __init__(self, parent): super(CreateNextPageOverlay, self).__init__(parent) - + self.setCursor(QtCore.Qt.PointingHandCursor) self._arrow_color = ( get_objected_colors("bg-buttons").get_qcolor() ) - self._gradient_start_color = ( + self._bg_color = ( get_objected_colors("publisher", "tab-bg").get_qcolor() ) - self._gradient_end_color = ( - get_objected_colors("bg-inputs").get_qcolor() - ) change_anim = QtCore.QVariantAnimation() change_anim.setStartValue(0.0) change_anim.setEndValue(self.max_value) - change_anim.setDuration(200) - change_anim.setEasingCurve(QtCore.QEasingCurve.InOutQuad) + change_anim.setDuration(400) + change_anim.setEasingCurve(QtCore.QEasingCurve.OutBounce) change_anim.valueChanged.connect(self._on_anim) @@ -1731,19 +1728,10 @@ class CreateNextPageOverlay(QtWidgets.QWidget): if not self._is_visible: self.setVisible(False) - def set_handle_show_on_own(self, handle): - if self._handle_show_on_own is handle: - return - self._handle_show_on_own = handle - self._under_mouse = None - self._check_anim_timer() - def set_under_mouse(self, under_mouse): if self._under_mouse is under_mouse: return - if self._handle_show_on_own: - self._handle_show_on_own = False self._under_mouse = under_mouse self.set_increasing(under_mouse) @@ -1756,22 +1744,7 @@ class CreateNextPageOverlay(QtWidgets.QWidget): if not self.isVisible(): return - if self._handle_show_on_own: - under_mouse = self._is_under_mouse() - else: - under_mouse = self._under_mouse - - self.set_increasing(under_mouse) - - def enterEvent(self, event): - super(CreateNextPageOverlay, self).enterEvent(event) - if self._handle_show_on_own: - self._check_anim_timer() - - def leaveEvent(self, event): - super(CreateNextPageOverlay, self).leaveEvent(event) - if self._handle_show_on_own: - self._check_anim_timer() + self.set_increasing(self._under_mouse) def mousePressEvent(self, event): if event.button() == QtCore.Qt.LeftButton: @@ -1792,74 +1765,41 @@ class CreateNextPageOverlay(QtWidgets.QWidget): if self._anim_value == 0.0: painter.end() return + + painter.setClipRect(event.rect()) painter.setRenderHints( painter.Antialiasing | painter.SmoothPixmapTransform ) - pen = QtGui.QPen() - pen.setWidth(0) - painter.setPen(pen) + painter.setPen(QtCore.Qt.NoPen) + rect = QtCore.QRect(self.rect()) + rect_width = rect.width() + rect_height = rect.height() - offset = rect.width() - int( - float(rect.width()) * 0.01 * self._anim_value - ) + size = rect_width * 0.9 - pos_y = rect.center().y() - left = rect.left() + offset - top = rect.top() - # Right and bootm is pixel index - right = rect.right() + 1 - bottom = rect.bottom() + 1 - width = right - left - height = bottom - top + x_offset = (rect_width - size) * 0.5 + y_offset = (rect_height - size) * 0.5 + if self._anim_value != self.max_value: + x_offset += rect_width - (rect_width * 0.01 * self._anim_value) - q_height = height * 0.15 - - arrow_half_height = width * 0.2 - arrow_x_start = left + (width * 0.4) + arrow_half_height = size * 0.2 + arrow_x_start = x_offset + (size * 0.4) arrow_x_end = arrow_x_start + arrow_half_height - arrow_top_y_boundry = arrow_half_height + q_height - arrow_bottom_y_boundry = height - (arrow_half_height + q_height) - offset = 0 - if pos_y < arrow_top_y_boundry: - pos_y = arrow_top_y_boundry - elif pos_y > arrow_bottom_y_boundry: - pos_y = arrow_bottom_y_boundry + center_y = rect.center().y() - top_cubic_y = pos_y - q_height - bottom_cubic_y = pos_y + q_height - - path = QtGui.QPainterPath() - path.moveTo(right, top) - path.lineTo(right, bottom) - - path.cubicTo( - right, bottom, - left, bottom_cubic_y, - left, pos_y + painter.setBrush(self._bg_color) + painter.drawEllipse( + x_offset, y_offset, + size, size ) - path.cubicTo( - left, top_cubic_y, - right, top, - right, top - ) - path.closeSubpath() - - radius = height * 0.7 - focal = QtCore.QPointF(left, pos_y) - start_p = QtCore.QPointF(right - (width * 0.5), pos_y) - gradient = QtGui.QRadialGradient(start_p, radius, focal) - gradient.setColorAt(0, self._gradient_start_color) - gradient.setColorAt(1, self._gradient_end_color) - - painter.fillPath(path, gradient) src_arrow_path = QtGui.QPainterPath() - src_arrow_path.moveTo(arrow_x_start, pos_y - arrow_half_height) - src_arrow_path.lineTo(arrow_x_end, pos_y) - src_arrow_path.lineTo(arrow_x_start, pos_y + arrow_half_height) + src_arrow_path.moveTo(arrow_x_start, center_y - arrow_half_height) + src_arrow_path.lineTo(arrow_x_end, center_y) + src_arrow_path.lineTo(arrow_x_start, center_y + arrow_half_height) arrow_stroker = QtGui.QPainterPathStroker() arrow_stroker.setWidth(min(4, arrow_half_height * 0.2)) diff --git a/openpype/tools/publisher/window.py b/openpype/tools/publisher/window.py index 2063cdab96..82a2576ff4 100644 --- a/openpype/tools/publisher/window.py +++ b/openpype/tools/publisher/window.py @@ -228,7 +228,6 @@ class PublisherWindow(QtWidgets.QDialog): publish_frame = PublishFrame(controller, self.footer_border, self) create_overlay_button = CreateNextPageOverlay(self) - create_overlay_button.set_handle_show_on_own(False) show_timer = QtCore.QTimer() show_timer.setInterval(1) @@ -716,20 +715,20 @@ class PublisherWindow(QtWidgets.QDialog): ) def _update_create_overlay_size(self): - height = self._content_widget.height() metrics = self._create_overlay_button.fontMetrics() - width = int(metrics.height() * 3) - pos_x = self.width() - width + size = int(metrics.height() * 3) + end_pos_x = self.width() + start_pos_x = end_pos_x - size - tab_pos = self._tabs_widget.parent().mapTo( - self, self._tabs_widget.pos() + center = self._content_widget.parent().mapTo( + self, + self._content_widget.rect().center() ) - tab_height = self._tabs_widget.height() - pos_y = tab_pos.y() + tab_height + pos_y = center.y() - (size * 0.5) self._create_overlay_button.setGeometry( - pos_x, pos_y, - width, height + start_pos_x, pos_y, + size, size ) def _update_create_overlay_visibility(self, global_pos=None): From 9ec78651547738a2d2ed3cf266ebb9428b44a6b6 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 4 Nov 2022 21:32:09 +0100 Subject: [PATCH 11/19] removred unnecessary restart --- openpype/tools/publisher/window.py | 1 - 1 file changed, 1 deletion(-) diff --git a/openpype/tools/publisher/window.py b/openpype/tools/publisher/window.py index 7cf3ae0da8..0daa31938d 100644 --- a/openpype/tools/publisher/window.py +++ b/openpype/tools/publisher/window.py @@ -362,7 +362,6 @@ class PublisherWindow(QtWidgets.QDialog): self._first_show = False self._on_first_show() - self._show_counter = 0 self._show_timer.start() def resizeEvent(self, event): From a852973e1139e5f2bba380f5c1e103ab3a817a54 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 4 Nov 2022 21:32:56 +0100 Subject: [PATCH 12/19] fix details dialog close --- openpype/tools/publisher/window.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/tools/publisher/window.py b/openpype/tools/publisher/window.py index 0daa31938d..281c7ad2a1 100644 --- a/openpype/tools/publisher/window.py +++ b/openpype/tools/publisher/window.py @@ -472,7 +472,7 @@ class PublisherWindow(QtWidgets.QDialog): ) def _on_tab_change(self, old_tab, new_tab): - if old_tab != "details": + if old_tab == "details": self._publish_details_widget.close_details_popup() if new_tab in ("create", "publish"): From 017ec79552eeb000edc6159960867dc781275655 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 7 Nov 2022 23:20:29 +0100 Subject: [PATCH 13/19] change colors --- openpype/tools/publisher/widgets/widgets.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/tools/publisher/widgets/widgets.py b/openpype/tools/publisher/widgets/widgets.py index 6c8ee3b332..ece27cd8cc 100644 --- a/openpype/tools/publisher/widgets/widgets.py +++ b/openpype/tools/publisher/widgets/widgets.py @@ -1718,10 +1718,10 @@ class CreateNextPageOverlay(QtWidgets.QWidget): super(CreateNextPageOverlay, self).__init__(parent) self.setCursor(QtCore.Qt.PointingHandCursor) self._arrow_color = ( - get_objected_colors("bg-buttons").get_qcolor() + get_objected_colors("font").get_qcolor() ) self._bg_color = ( - get_objected_colors("publisher", "tab-bg").get_qcolor() + get_objected_colors("bg-buttons").get_qcolor() ) change_anim = QtCore.QVariantAnimation() From b75356d631f26048330e65ff24e78107dc0bbd0c Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 7 Nov 2022 23:20:35 +0100 Subject: [PATCH 14/19] change easing curve --- openpype/tools/publisher/widgets/widgets.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/tools/publisher/widgets/widgets.py b/openpype/tools/publisher/widgets/widgets.py index ece27cd8cc..f170992c1a 100644 --- a/openpype/tools/publisher/widgets/widgets.py +++ b/openpype/tools/publisher/widgets/widgets.py @@ -1728,7 +1728,7 @@ class CreateNextPageOverlay(QtWidgets.QWidget): change_anim.setStartValue(0.0) change_anim.setEndValue(self.max_value) change_anim.setDuration(400) - change_anim.setEasingCurve(QtCore.QEasingCurve.OutBounce) + change_anim.setEasingCurve(QtCore.QEasingCurve.OutCubic) change_anim.valueChanged.connect(self._on_anim) From 3dbfa8ee5143d411adf6bbe2357966078cb819e4 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 8 Nov 2022 16:30:40 +0100 Subject: [PATCH 15/19] removed max value and use 1.0 --- openpype/tools/publisher/widgets/widgets.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/openpype/tools/publisher/widgets/widgets.py b/openpype/tools/publisher/widgets/widgets.py index f170992c1a..7ab6294817 100644 --- a/openpype/tools/publisher/widgets/widgets.py +++ b/openpype/tools/publisher/widgets/widgets.py @@ -1711,7 +1711,6 @@ class SubsetAttributesWidget(QtWidgets.QWidget): class CreateNextPageOverlay(QtWidgets.QWidget): - max_value = 100.0 clicked = QtCore.Signal() def __init__(self, parent): @@ -1726,7 +1725,7 @@ class CreateNextPageOverlay(QtWidgets.QWidget): change_anim = QtCore.QVariantAnimation() change_anim.setStartValue(0.0) - change_anim.setEndValue(self.max_value) + change_anim.setEndValue(1.0) change_anim.setDuration(400) change_anim.setEasingCurve(QtCore.QEasingCurve.OutCubic) @@ -1768,7 +1767,7 @@ class CreateNextPageOverlay(QtWidgets.QWidget): def _is_anim_finished(self): if self._increasing: - return self._anim_value == self.max_value + return self._anim_value == 1.0 return self._anim_value == 0.0 def _on_anim(self, value): @@ -1838,8 +1837,8 @@ class CreateNextPageOverlay(QtWidgets.QWidget): x_offset = (rect_width - size) * 0.5 y_offset = (rect_height - size) * 0.5 - if self._anim_value != self.max_value: - x_offset += rect_width - (rect_width * 0.01 * self._anim_value) + if self._anim_value != 1.0: + x_offset += rect_width - (rect_width * self._anim_value) arrow_half_height = size * 0.2 arrow_x_start = x_offset + (size * 0.4) From 3cd1918f04ef5c13ab10e003064699b1659f8fb0 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 10 Nov 2022 11:23:32 +0100 Subject: [PATCH 16/19] shorter animation --- openpype/tools/publisher/widgets/widgets.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/tools/publisher/widgets/widgets.py b/openpype/tools/publisher/widgets/widgets.py index a33e6e7565..71f476c4ef 100644 --- a/openpype/tools/publisher/widgets/widgets.py +++ b/openpype/tools/publisher/widgets/widgets.py @@ -1726,7 +1726,7 @@ class CreateNextPageOverlay(QtWidgets.QWidget): change_anim = QtCore.QVariantAnimation() change_anim.setStartValue(0.0) change_anim.setEndValue(1.0) - change_anim.setDuration(400) + change_anim.setDuration(200) change_anim.setEasingCurve(QtCore.QEasingCurve.OutCubic) change_anim.valueChanged.connect(self._on_anim) From fbd7531a311d1a0287c45babb12a7b029cd50a7d Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 15 Nov 2022 18:42:46 +0100 Subject: [PATCH 17/19] change label of stopped publishing --- openpype/tools/publisher/widgets/validations_widget.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/tools/publisher/widgets/validations_widget.py b/openpype/tools/publisher/widgets/validations_widget.py index 8c483e8088..935a12bc73 100644 --- a/openpype/tools/publisher/widgets/validations_widget.py +++ b/openpype/tools/publisher/widgets/validations_widget.py @@ -511,7 +511,7 @@ class ValidationsWidget(QtWidgets.QFrame): ) # After success publishing publish_started_widget = ValidationArtistMessage( - "Publishing went smoothly", self + "So far so good", self ) # After success publishing publish_stop_ok_widget = ValidationArtistMessage( From 0645089ad61f0a893ce717a5cf4574ca81cd8ef2 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 16 Nov 2022 10:38:08 +0100 Subject: [PATCH 18/19] size of button is fully defined by style --- openpype/style/style.css | 4 ++++ openpype/tools/publisher/window.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/openpype/style/style.css b/openpype/style/style.css index 887c044dae..a7a48cdb9d 100644 --- a/openpype/style/style.css +++ b/openpype/style/style.css @@ -1126,6 +1126,10 @@ ValidationArtistMessage QLabel { background: transparent; } +CreateNextPageOverlay { + font-size: 32pt; +} + /* Settings - NOT USED YET - we need to define font family for settings UI */ diff --git a/openpype/tools/publisher/window.py b/openpype/tools/publisher/window.py index 281c7ad2a1..febf55b919 100644 --- a/openpype/tools/publisher/window.py +++ b/openpype/tools/publisher/window.py @@ -716,7 +716,7 @@ class PublisherWindow(QtWidgets.QDialog): def _update_create_overlay_size(self): metrics = self._create_overlay_button.fontMetrics() - size = int(metrics.height() * 3) + size = int(metrics.height()) end_pos_x = self.width() start_pos_x = end_pos_x - size From 20dacc342b5b4f5ff407fd616d0dc7818c551844 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 16 Nov 2022 10:40:22 +0100 Subject: [PATCH 19/19] change style of button --- openpype/tools/publisher/widgets/widgets.py | 17 +++++++++-------- openpype/tools/publisher/window.py | 17 ++++++++++++----- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/openpype/tools/publisher/widgets/widgets.py b/openpype/tools/publisher/widgets/widgets.py index 71f476c4ef..ce3d91ce63 100644 --- a/openpype/tools/publisher/widgets/widgets.py +++ b/openpype/tools/publisher/widgets/widgets.py @@ -1832,23 +1832,24 @@ class CreateNextPageOverlay(QtWidgets.QWidget): rect = QtCore.QRect(self.rect()) rect_width = rect.width() rect_height = rect.height() + radius = rect_width * 0.2 - size = rect_width * 0.9 - - x_offset = (rect_width - size) * 0.5 - y_offset = (rect_height - size) * 0.5 + x_offset = 0 + y_offset = 0 if self._anim_value != 1.0: x_offset += rect_width - (rect_width * self._anim_value) - arrow_half_height = size * 0.2 - arrow_x_start = x_offset + (size * 0.4) + arrow_height = rect_height * 0.4 + arrow_half_height = arrow_height * 0.5 + arrow_x_start = x_offset + ((rect_width - arrow_half_height) * 0.5) arrow_x_end = arrow_x_start + arrow_half_height center_y = rect.center().y() painter.setBrush(self._bg_color) - painter.drawEllipse( + painter.drawRoundedRect( x_offset, y_offset, - size, size + rect_width + radius, rect_height, + radius, radius ) src_arrow_path = QtGui.QPainterPath() diff --git a/openpype/tools/publisher/window.py b/openpype/tools/publisher/window.py index febf55b919..de26630312 100644 --- a/openpype/tools/publisher/window.py +++ b/openpype/tools/publisher/window.py @@ -257,7 +257,9 @@ class PublisherWindow(QtWidgets.QDialog): publish_btn.clicked.connect(self._on_publish_clicked) publish_frame.details_page_requested.connect(self._go_to_details_tab) - create_overlay_button.clicked.connect(self._go_to_publish_tab) + create_overlay_button.clicked.connect( + self._on_create_overlay_button_click + ) controller.event_system.add_callback( "instances.refresh.finished", self._on_instances_refresh @@ -471,6 +473,10 @@ class PublisherWindow(QtWidgets.QDialog): self._help_dialog.width(), self._help_dialog.height() ) + def _on_create_overlay_button_click(self): + self._create_overlay_button.set_under_mouse(False) + self._go_to_publish_tab() + def _on_tab_change(self, old_tab, new_tab): if old_tab == "details": self._publish_details_widget.close_details_popup() @@ -716,19 +722,20 @@ class PublisherWindow(QtWidgets.QDialog): def _update_create_overlay_size(self): metrics = self._create_overlay_button.fontMetrics() - size = int(metrics.height()) + height = int(metrics.height()) + width = int(height * 0.7) end_pos_x = self.width() - start_pos_x = end_pos_x - size + start_pos_x = end_pos_x - width center = self._content_widget.parent().mapTo( self, self._content_widget.rect().center() ) - pos_y = center.y() - (size * 0.5) + pos_y = center.y() - (height * 0.5) self._create_overlay_button.setGeometry( start_pos_x, pos_y, - size, size + width, height ) def _update_create_overlay_visibility(self, global_pos=None):