From 745507f8d692c5ddcb8ff5e70be3ed3eff30f043 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 16 Mar 2021 22:40:37 +0100 Subject: [PATCH] implemented animation itself --- pype/tools/launcher/delegates.py | 58 ++++++++++++++++++++++++++++++++ pype/tools/launcher/widgets.py | 39 ++++++++++++++++++++- 2 files changed, 96 insertions(+), 1 deletion(-) diff --git a/pype/tools/launcher/delegates.py b/pype/tools/launcher/delegates.py index e2eecc6ad5..9b88903bc1 100644 --- a/pype/tools/launcher/delegates.py +++ b/pype/tools/launcher/delegates.py @@ -1,4 +1,10 @@ +import time from Qt import QtCore, QtWidgets, QtGui +from .constants import ( + ANIMATION_LEN, + ANIMATION_START_ROLE, + ANIMATION_STATE_ROLE +) class ActionDelegate(QtWidgets.QStyledItemDelegate): @@ -9,8 +15,60 @@ class ActionDelegate(QtWidgets.QStyledItemDelegate): def __init__(self, group_roles, *args, **kwargs): super(ActionDelegate, self).__init__(*args, **kwargs) self.group_roles = group_roles + self._anim_start_color = QtGui.QColor(178, 255, 246) + self._anim_end_color = QtGui.QColor(5, 44, 50) + + def _draw_animation(self, painter, option, index): + grid_size = option.widget.gridSize() + x_offset = int( + (grid_size.width() / 2) + - (option.rect.width() / 2) + ) + item_x = option.rect.x() - x_offset + rect_offset = grid_size.width() / 20 + size = grid_size.width() - (rect_offset * 2) + anim_rect = QtCore.QRect( + item_x + rect_offset, + option.rect.y() + rect_offset, + size, + size + ) + + painter.save() + + painter.setBrush(QtCore.Qt.transparent) + painter.setRenderHint(QtGui.QPainter.Antialiasing) + + gradient = QtGui.QConicalGradient() + gradient.setCenter(anim_rect.center()) + gradient.setColorAt(0, self._anim_start_color) + gradient.setColorAt(1, self._anim_end_color) + + time_diff = time.time() - index.data(ANIMATION_START_ROLE) + + # Repeat 4 times + part_anim = ANIMATION_LEN / 4 + part_time = time_diff % part_anim + offset = (part_time / part_anim) * 360 + angle = (offset + 90) % 360 + + gradient.setAngle(-angle) + + pen = QtGui.QPen(QtGui.QBrush(gradient), rect_offset) + pen.setCapStyle(QtCore.Qt.RoundCap) + painter.setPen(pen) + painter.drawArc( + anim_rect, + -16 * (angle + 10), + -16 * offset + ) + + painter.restore() def paint(self, painter, option, index): + if index.data(ANIMATION_STATE_ROLE): + self._draw_animation(painter, option, index) + super(ActionDelegate, self).paint(painter, option, index) is_group = False for group_role in self.group_roles: diff --git a/pype/tools/launcher/widgets.py b/pype/tools/launcher/widgets.py index 06c2daef9c..62545fb966 100644 --- a/pype/tools/launcher/widgets.py +++ b/pype/tools/launcher/widgets.py @@ -1,4 +1,5 @@ import copy +import time import collections from Qt import QtWidgets, QtCore, QtGui from avalon.vendor import qtawesome @@ -124,6 +125,13 @@ class ActionBar(QtWidgets.QWidget): self.model = model self.view = view + self._animated_items = set() + + animation_timer = QtCore.QTimer() + animation_timer.setInterval(50) + animation_timer.timeout.connect(self._on_animation) + self._animation_timer = animation_timer + # Make view flickable flick = FlickCharm(parent=view) flick.activateOn(view) @@ -141,8 +149,35 @@ class ActionBar(QtWidgets.QWidget): def set_row_height(self, rows): self.setMinimumHeight(rows * 75) + def _on_animation(self): + time_now = time.time() + for action_id in tuple(self._animated_items): + item = self.model.items_by_id.get(action_id) + if not item: + self._animated_items.remove(action_id) + continue + + start_time = item.data(ANIMATION_START_ROLE) + if (time_now - start_time) > ANIMATION_LEN: + item.setData(0, ANIMATION_STATE_ROLE) + self._animated_items.remove(action_id) + + if not self._animated_items: + self._animation_timer.stop() + + self.update() + + def _start_animation(self, index): + action_id = index.data(ACTION_ID_ROLE) + item = self.model.items_by_id.get(action_id) + if item: + item.setData(time.time(), ANIMATION_START_ROLE) + item.setData(1, ANIMATION_STATE_ROLE) + self._animated_items.add(action_id) + self._animation_timer.start() + def on_clicked(self, index): - if not index.isValid(): + if not index or not index.isValid(): return is_group = index.data(GROUP_ROLE) @@ -150,6 +185,7 @@ class ActionBar(QtWidgets.QWidget): if not is_group and not is_variant_group: action = index.data(ACTION_ROLE) self.action_clicked.emit(action) + self._start_animation(index) return actions = index.data(ACTION_ROLE) @@ -213,6 +249,7 @@ class ActionBar(QtWidgets.QWidget): if result: action = actions_mapping[result] self.action_clicked.emit(action) + self._start_animation(index) class TasksWidget(QtWidgets.QWidget):