Skip to content

Commit

Permalink
feat: impl button scaling ani
Browse files Browse the repository at this point in the history
  • Loading branch information
ChinaIceF committed Nov 16, 2024
1 parent 8483db5 commit 94533bf
Show file tree
Hide file tree
Showing 2 changed files with 140 additions and 34 deletions.
150 changes: 118 additions & 32 deletions siui/components/button.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,20 @@
# replace button once it's done. Now it's draft, code may be ugly and verbose temporarily.
from __future__ import annotations

import dataclasses
from dataclasses import dataclass, fields

from PyQt5.QtCore import QEvent, QObject, QRect, QRectF, QSize, Qt, QTimer, pyqtProperty, pyqtSignal
from dataclasses import dataclass

from PyQt5.QtCore import (
QEvent,
QObject,
QPointF,
QRect,
QRectF,
QSize,
Qt,
QTimer,
pyqtProperty,
pyqtSignal,
)
from PyQt5.QtGui import (
QColor,
QFont,
Expand Down Expand Up @@ -70,16 +80,18 @@ class Theme:
SA.BorderHeight: 3,
SA.IconTextGap: 4,
},
"FlatButtonStyleData": {
SA.ButtonColor: QColor("#004C4554")
},
"LongPressButtonStyleData": {
SA.ProgressColor: QColor("#DA3462"),
SA.ButtonColor: QColor("#932a48"),
SA.BackgroundColor: QColor("#642d41"),
SA.ClickColor: QColor("#40FFFFFF"),
},
"ToggleButtonStyleData": {},
"FlatButtonStyleData": {
SA.ButtonColor: QColor("#004C4554")
},
"ToggleButtonStyleData": {
SA.ButtonColor: QColor("#004C4554"),
},
"PushButtonStyleData": {},
"ProgressPushButtonStyleData": {},
}
Expand Down Expand Up @@ -163,6 +175,7 @@ class ToggleButtonStyleData(ButtonStyleData):

class ABCButton(QPushButton):
class Property:
ScaleFactor = "scaleFactor"
TextColor = "textColor"
ButtonRectColor = "buttonRectColor"
ProgressRectColor = "progressRectColor"
Expand All @@ -175,6 +188,7 @@ def __init__(self, parent: QWidget | None = None) -> None:

self.style_data = None
self._progress = 0
self._scale_factor = 1
self._highlight_rect_color = QColor("#00FFFFFF")
self._progress_rect_color = None
self._background_rect_color = None
Expand All @@ -186,6 +200,15 @@ def __init__(self, parent: QWidget | None = None) -> None:

self.clicked.connect(self._onButtonClicked)

@pyqtProperty(float)
def scaleFactor(self):
return self._scale_factor

@scaleFactor.setter
def scaleFactor(self, value: float):
self._scale_factor = value
self.update()

@pyqtProperty(QColor)
def highlightRectColor(self):
return self._highlight_rect_color
Expand Down Expand Up @@ -299,9 +322,6 @@ def _updateToolTip(self) -> None:
if tool_tip_window is not None and tool_tip_window.nowInsideOf() == self:
tool_tip_window.setText(self.toolTip())

def _onAnimationTicked(self, _) -> None:
raise NotImplementedError()

def _onButtonClicked(self) -> None:
raise NotImplementedError()

Expand All @@ -326,11 +346,29 @@ def __init__(self, parent: QWidget | None = None) -> None:

self.style_data = PushButtonStyleData()
self._initStyle()
self._scale_factor = 1

self.scale_factor_ani = SiExpAnimationRefactor(self, self.Property.ScaleFactor)
self.scale_factor_ani.init(1/16, 0, 1, 1)

def _initStyle(self):
self.setFont(self.style_data.font)
self.setIconSize(QSize(20, 20))

def mousePressEvent(self, e):
super().mousePressEvent(e)
self.scale_factor_ani.setFactor(1/16)
self.scale_factor_ani.setBias(0)
self.scale_factor_ani.setEndValue(0.9)
self.scale_factor_ani.start()

def mouseReleaseEvent(self, e):
super().mouseReleaseEvent(e)
self.scale_factor_ani.setFactor(1/4)
self.scale_factor_ani.setBias(0.001)
self.scale_factor_ani.setEndValue(1)
self.scale_factor_ani.start()

@classmethod
def withText(cls, text: str, parent: QWidget | None = None):
obj = cls(parent)
Expand Down Expand Up @@ -425,19 +463,35 @@ def leaveEvent(self, event) -> None:
self._hideToolTip()

def paintEvent(self, event: QPaintEvent) -> None:
rect = self.rect()
text_rect, icon_rect = self.textRectAndIconRect()
device_pixel_ratio = self.devicePixelRatioF()

buffer = QPixmap(rect.size() * device_pixel_ratio)
buffer.setDevicePixelRatio(device_pixel_ratio)
buffer.fill(Qt.transparent)

buffer_painter = QPainter(buffer)
buffer_painter.setRenderHint(QPainter.RenderHint.SmoothPixmapTransform)
buffer_painter.setRenderHint(QPainter.RenderHint.TextAntialiasing)
buffer_painter.setRenderHint(QPainter.RenderHint.Antialiasing)
buffer_painter.setPen(Qt.PenStyle.NoPen)

self._drawBackgroundRect(buffer_painter, rect)
self._drawButtonRect(buffer_painter, rect)
self._drawHighLightRect(buffer_painter, rect)
self._drawPixmapRect(buffer_painter, icon_rect)
self._drawTextRect(buffer_painter, text_rect)
buffer_painter.end()

a = self._scale_factor
painter = QPainter(self)
painter.setRenderHint(QPainter.RenderHint.SmoothPixmapTransform)
painter.setRenderHint(QPainter.RenderHint.TextAntialiasing)
painter.setRenderHint(QPainter.RenderHint.Antialiasing)
painter.setPen(Qt.PenStyle.NoPen)
painter.translate(QPointF(rect.width() * (1-a) / 2, rect.height() * (1-a) / 2))
painter.scale(a, a)

rect = self.rect()
text_rect, icon_rect = self.textRectAndIconRect()
self._drawBackgroundRect(painter, rect)
self._drawButtonRect(painter, rect)
self._drawHighLightRect(painter, rect)
self._drawTextRect(painter, text_rect)
self._drawPixmapRect(painter, icon_rect)
painter.drawPixmap(0, 0, buffer)


class SiProgressPushButton(SiPushButtonRefactor):
Expand Down Expand Up @@ -501,7 +555,6 @@ def __init__(self, parent: QWidget | None = None) -> None:

self.progress_ani = SiExpAnimationRefactor(self, self.Property.Progress)
self.progress_ani.init(-1 / 16, 0.12, 0, 0)
# self.progress_ani.valueChanged.connect(print)

self.go_backwards_timer = QTimer(self)
self.go_backwards_timer.setSingleShot(True)
Expand Down Expand Up @@ -581,6 +634,10 @@ def __init__(self, parent: QWidget | None = None) -> None:

self.style_data = FlatButtonStyleData()
self._initStyle()
self._scale_factor = 1

self.scale_factor_ani = SiExpAnimationRefactor(self, self.Property.ScaleFactor)
self.scale_factor_ani.init(1/16, 0, 1, 1)

def _initStyle(self):
self.setFont(self.style_data.font)
Expand Down Expand Up @@ -630,26 +687,39 @@ def textRectAndIconRect(self) -> (QRectF, QRect):

return text_rect, pixmap_rect

def _onAnimationTicked(self, _) -> None:
self.update()

def _onButtonClicked(self) -> None:
self.highlight_ani.setCurrentValue(self.style_data.click_color)
self.highlight_ani.start()

def paintEvent(self, event: QPaintEvent) -> None:
rect = self.rect()
text_rect, icon_rect = self.textRectAndIconRect()
device_pixel_ratio = self.devicePixelRatioF()

buffer = QPixmap(rect.size() * device_pixel_ratio)
buffer.setDevicePixelRatio(device_pixel_ratio)
buffer.fill(Qt.transparent)

buffer_painter = QPainter(buffer)
buffer_painter.setRenderHint(QPainter.RenderHint.SmoothPixmapTransform)
buffer_painter.setRenderHint(QPainter.RenderHint.TextAntialiasing)
buffer_painter.setRenderHint(QPainter.RenderHint.Antialiasing)
buffer_painter.setPen(Qt.PenStyle.NoPen)

self._drawButtonRect(buffer_painter, rect)
self._drawHighLightRect(buffer_painter, rect)
self._drawPixmapRect(buffer_painter, icon_rect)
self._drawTextRect(buffer_painter, text_rect)
buffer_painter.end()

a = self._scale_factor
painter = QPainter(self)
painter.setRenderHint(QPainter.RenderHint.SmoothPixmapTransform)
painter.setRenderHint(QPainter.RenderHint.TextAntialiasing)
painter.setRenderHint(QPainter.RenderHint.Antialiasing)
painter.setPen(Qt.PenStyle.NoPen)
painter.translate(QPointF(rect.width() * (1-a) / 2, rect.height() * (1-a) / 2))
painter.scale(a, a)

rect = self.rect()
text_rect, icon_rect = self.textRectAndIconRect()
self._drawButtonRect(painter, rect)
self._drawHighLightRect(painter, rect)
self._drawTextRect(painter, text_rect)
self._drawPixmapRect(painter, icon_rect)
painter.drawPixmap(0, 0, buffer)

def enterEvent(self, event) -> None:
super().enterEvent(event)
Expand All @@ -664,6 +734,22 @@ def leaveEvent(self, event) -> None:
self.highlight_ani.start()
self._hideToolTip()

def mousePressEvent(self, e):
super().mousePressEvent(e)
self.scale_factor_ani.setFactor(1/16)
self.scale_factor_ani.setBias(0)
self.scale_factor_ani.setEndValue(0.9)
self.scale_factor_ani.start()

def mouseReleaseEvent(self, e):
super().mouseReleaseEvent(e)
self.scale_factor_ani.setFactor(1/4)
self.scale_factor_ani.setBias(0.001)
self.scale_factor_ani.setEndValue(1)
self.scale_factor_ani.start()




class SiToggleButtonRefactor(SiFlatButton):
def __init__(self, parent: QWidget | None = None) -> None:
Expand Down
24 changes: 22 additions & 2 deletions siui/core/animation.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
from typing import Any

import numpy
from PyQt5.QtCore import QAbstractAnimation, QObject, QPoint, QPointF, QRect, QRectF, QSize, QSizeF, QTimer, pyqtSignal
from PyQt5.QtCore import (
QAbstractAnimation,
QObject,
QPoint,
QPointF,
QRect,
QRectF,
QSize,
QSizeF,
QTimer,
pyqtSignal,
)
from PyQt5.QtGui import QColor

global_fps = 60
Expand Down Expand Up @@ -439,6 +450,12 @@ def init(self, factor: float, bias: float, current_value, end_value) -> None:
self.setCurrentValue(current_value)
self.setEndValue(end_value)

def setFactor(self, factor: float):
self.factor = factor

def setBias(self, bias: float):
self.bias = bias

def target(self) -> QObject:
return self._target

Expand Down Expand Up @@ -510,8 +527,11 @@ def updateCurrentTime(self, _) -> None:
step = step * (1 - flag) + distance * flag # 差距小于偏置的项,返回差距

self._current_value = self._current_value + step
self._target.setProperty(self._property_name, self._out_func(self._current_value))
self.valueChanged.emit(self._current_value)
try:
self._target.setProperty(self._property_name, self._out_func(self._current_value))
except RuntimeError:
pass

def _loadConversionFuncs(self) -> None:
if self._property_type.__name__ in TypeConversionFuncs.functions.keys():
Expand Down

0 comments on commit 94533bf

Please sign in to comment.