Skip to content
Merged

Chore #236

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion examples/Gallery for siui/start.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import siui
from siui.core import SiGlobal

#
# siui.gui.set_scale_factor(1)


Expand All @@ -17,13 +18,23 @@ def show_version_message(window):
text="You are currently running v1.14.514\n"
"Click this message box to check out what's new.",
msg_type=1,
icon=SiGlobal.siui.iconpack.get("ic_fluent_hand_wave_regular"),
icon=SiGlobal.siui.iconpack.get("ic_fluent_hand_wave_filled"),
fold_after=5000,
slot=lambda: window.LayerRightMessageSidebar().send("Oops, it seems that nothing will happen due to the fact "
"that this function is currently not completed.",
icon=SiGlobal.siui.iconpack.get("ic_fluent_info_regular"))
)

window.LayerRightMessageSidebar().send(
title="Refactoring in Progress",
text="To optimize the project structure, "
"we are currently undergoing a refactoring process.\n\n"
"We strongly discourage you from using any deprecated components "
'other than those displayed on the "Refactored Components" page.',
msg_type=4,
icon=SiGlobal.siui.iconpack.get("ic_fluent_warning_filled"),
)


if __name__ == "__main__":
app = QApplication(sys.argv)
Expand Down
111 changes: 108 additions & 3 deletions siui/components/editbox.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
from __future__ import annotations

import difflib
import random
from dataclasses import dataclass

import numpy
from PyQt5.QtCore import QEvent, QPoint, QRectF, QSize, Qt, pyqtProperty, QPointF
from PyQt5.QtCore import QEvent, QPoint, QRectF, QSize, Qt, pyqtProperty, QPointF, QObject
from PyQt5.QtGui import (
QColor,
QDoubleValidator,
Expand Down Expand Up @@ -334,6 +335,64 @@ def leaveEvent(self, a0):
hideToolTip(self)


class AnimatedCharObject(QObject):

class Property:
TextOpacity = "textOpacity"
TextPosition = "textPosition"

def __init__(self, parent, text, start_pos: QPointF):
super().__init__(parent)

self._text = text
self._start_pos = start_pos

self._text_opacity = 1
self._text_pos_p = 0

self.opacity_ani = SiExpAnimationRefactor(self, self.Property.TextOpacity)
self.opacity_ani.init(1/4, 0.0001, 1, 1)

self.position_ani = SiExpAnimationRefactor(self, self.Property.TextPosition)
self.position_ani.init(0, 0.05, self._text_pos_p, self._text_pos_p)

@pyqtProperty(float)
def textOpacity(self):
return self._text_opacity

@textOpacity.setter
def textOpacity(self, value: float):
self._text_opacity = value

@pyqtProperty(float)
def textPosition(self):
return self._text_pos_p

@textPosition.setter
def textPosition(self, value: float):
self._text_pos_p = value

def disappear(self):
self.position_ani.setEndValue(1)
self.opacity_ani.setEndValue(0)

self.position_ani.start()
self.opacity_ani.start()

def isDone(self):
return self.opacity_ani.currentValue() == 0

def text(self) -> str:
return self._text

def opacity(self) -> float:
return self._text_opacity

def position(self) -> QPointF:
p = self._text_pos_p ** 2
return self._start_pos + QPointF(0, 10) * p


class SiCustomLineEdit(QLineEdit):
class Property:
CharProgress = "charProgress"
Expand All @@ -345,14 +404,18 @@ def __init__(self, parent: T_WidgetParent = None) -> None:
self._max_supported_length = 1000 # supported maximum length is 1000 chars
self._char_progress = [0] * 1000
self._cursor_x = 0
self._animated_chars = []
self._prev_text = ""

self.char_prog_ani = SiExpAnimationRefactor(self, self.Property.CharProgress)
self.char_prog_ani.init(1/4, 0.001, self._char_progress, self._char_progress)

self.cursor_x_ani = SiExpAnimationRefactor(self, self.Property.CursorX)
self.cursor_x_ani.init(1/2, 0.001, self._cursor_x, self._cursor_x)

self.setFont(SiFont.getFont(size=14))
font = SiFont.getFont(size=14)
font.setLetterSpacing(QFont.AbsoluteSpacing, 0)
self.setFont(font)
self.setMaxLength(100)

self.textChanged.connect(self._onTextChanged)
Expand Down Expand Up @@ -401,7 +464,7 @@ def _drawCursorRect(self, painter: QPainter, line_rect: QRectF) -> None:
if self.hasFocus():
path = QPainterPath()
path.addRoundedRect(self._cursor_x + 1, (line_rect.height() - 20) / 2, 5, 20, 2.0, 2.0)
painter.setBrush(QColor("#90EDE1F4"))
painter.setBrush(QColor("#30EDE1F4"))
painter.setPen(Qt.NoPen)
painter.drawPath(path)

Expand All @@ -411,6 +474,12 @@ def _drawBackgroundRect(self, painter: QPainter, rect: QRectF) -> None:
painter.setBrush(QColor("#252229"))
painter.drawPath(path)

def _drawAnimatedChar(self, painter: QPainter, rect: QRectF, obj: AnimatedCharObject):
color = QColor("#EDE1F4")
color.setAlphaF(obj.opacity())
painter.setPen(color)
painter.drawText(obj.position() + QPointF(1, 24), obj.text())

def paintEvent(self, a0):
text_rect = self.rect()
background_rect = QRectF(0, 0, self.rect().width(), self.rect().height())
Expand All @@ -420,11 +489,41 @@ def paintEvent(self, a0):
self._drawTextChar(painter, text_rect)
self._drawCursorRect(painter, text_rect)

new_list = []
for obj in self._animated_chars:
if obj.isDone() is False:
self._drawAnimatedChar(painter, text_rect, obj)
new_list.append(obj)

self._animated_chars = new_list

@staticmethod
def _findDeletedText(old_text, new_text):
"""使用 difflib 计算被删除的文本"""
deleted = []
seq = difflib.SequenceMatcher(None, old_text, new_text)

for tag, i1, i2, j1, j2 in seq.get_opcodes():
if tag == "delete": # 标记删除的部分
deleted.append(old_text[i1:i2])

return "".join(deleted)

def _onTextChanged(self, text) -> None:
m = self._max_supported_length
self.char_prog_ani.setEndValue([1] * len(text) + [0] * (m - len(text)))
self.char_prog_ani.start()

metrics = QFontMetrics(self.font())
cursor_x = sum([metrics.width(char) for char in self.text()[:self.cursorPosition()]]) + self._origin_point.x() - 1

deleted_text = self._findDeletedText(self._prev_text, text)
obj = AnimatedCharObject(self, deleted_text, QPointF(cursor_x, 0))
obj.disappear()

self._animated_chars.append(obj)
self._prev_text = text

def _onCursorPositionChanged(self, old, new) -> None:
metrics = QFontMetrics(self.font())
cursor_x = sum([metrics.width(char) for char in self.text()[:new]]) + self._origin_point.x() - 1
Expand All @@ -433,6 +532,12 @@ def _onCursorPositionChanged(self, old, new) -> None:
self.cursor_x_ani.start()








class SiCapsuleEdit(QLineEdit):
class Property:
TitleColor = "titleColor"
Expand Down
Loading