Skip to content

Commit 1605f39

Browse files
Robert0MartRobeMartinsHugoCLSC
authored andcommitted
Bugfix label overlap (#121)
* bugfix: label overlapping when stoped * Upd: rollback some parts * ADD: added delay to marquee effect * bugfix: text when marquee wasnt needed and glow effect * Refactor: Ran ruff formatter * Remove unecessary lambda expression * Add docstring to paintEvent method --------- Co-authored-by: Roberto <roberto.martins@blockstec.com> Co-authored-by: Hugo Costa <hugo.santos.costa@gmail.com>
1 parent 1f970cc commit 1605f39

1 file changed

Lines changed: 63 additions & 112 deletions

File tree

‎BlocksScreen/lib/utils/blocks_label.py‎

Lines changed: 63 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,13 @@ def __init__(self, parent: QtWidgets.QWidget = None, *args, **kwargs):
1515
self._marquee: bool = True
1616
self.timer = QtCore.QTimer()
1717
self.timer.timeout.connect(self._scroll_text)
18-
self.delay_timer = QtCore.QTimer()
19-
self.delay_timer.setSingleShot(True)
20-
self.delay_timer.timeout.connect(self._start_marquee)
21-
2218
self.scroll_pos = 0.0
23-
self.marquee_spacing = 20
19+
self.marquee_spacing = 40
20+
self.scroll_speed = 40
21+
self.scroll_animation_speed = 30
22+
self.max_loops = 2
23+
self.loop_count = 0
2424
self.paused = False
25-
self.scroll_speed = 20
26-
self.scroll_animation_speed = 50
2725
self.setMouseTracking(True)
2826
self.setTabletTracking(True)
2927
self.setSizePolicy(
@@ -41,8 +39,8 @@ def __init__(self, parent: QtWidgets.QWidget = None, *args, **kwargs):
4139
self.glow_animation.finished.connect(self.repaint)
4240

4341
self.total_scroll_width: float = 0.0
44-
self.marquee_delay = 5000
45-
self.loop_count = 0
42+
self.text_width: float = 0.0
43+
self.label_width: float = 0.0
4644
self.first_run = True
4745

4846
def resizeEvent(self, a0: QtGui.QResizeEvent) -> None:
@@ -67,6 +65,7 @@ def setPixmap(self, a0: QtGui.QPixmap) -> None:
6765
def setText(self, text: str) -> None:
6866
"""Set widget text"""
6967
self._text = text
68+
self.scroll_pos = 0.0
7069
self.update_text_metrics()
7170

7271
@property
@@ -102,7 +101,7 @@ def marquee(self) -> bool:
102101
return self._marquee
103102

104103
@marquee.setter
105-
def marquee(self, activate) -> None:
104+
def marquee(self, activate: bool) -> None:
106105
self._marquee = activate
107106
self.update_text_metrics()
108107

@@ -130,10 +129,9 @@ def start_glow_animation(self) -> None:
130129
"""Start glow animation"""
131130
self.glow_animation.setDuration(self.animation_speed)
132131
start_color = QtGui.QColor("#00000000")
132+
end_color = QtGui.QColor("#E95757")
133133
self.glow_animation.setStartValue(start_color)
134-
base_end_color = QtGui.QColor("#E95757")
135-
self.glow_animation.setEndValue(base_end_color)
136-
134+
self.glow_animation.setEndValue(end_color)
137135
self.glow_animation.setDirection(QtCore.QPropertyAnimation.Direction.Forward)
138136
self.glow_animation.setLoopCount(-1)
139137
self.glow_animation.start()
@@ -155,145 +153,98 @@ def update_text_metrics(self) -> None:
155153
self.total_scroll_width = float(self.text_width + self.marquee_spacing)
156154

157155
if self._marquee and self.text_width > self.label_width:
158-
self.start_scroll()
156+
self.scroll_pos = 0.0
157+
QtCore.QTimer.singleShot(2000, self.start_scroll)
159158
else:
160159
self.stop_scroll()
161160
self.scroll_pos = 0.0
162161
self.update()
163162

164163
def start_scroll(self) -> None:
165-
"""Start marquee text scroll effect"""
166-
if not self.delay_timer.isActive() and not self.timer.isActive():
164+
"""Start or restart the scrolling."""
165+
if not self.timer.isActive():
167166
self.scroll_pos = 0
168167
self.loop_count = 0
169-
if self.first_run:
170-
self.delay_timer.start(self.marquee_delay)
171-
self.first_run = False
172-
else:
173-
self._start_marquee()
174-
175-
def _start_marquee(self) -> None:
176-
"""Starts the actual marquee animation after the delay or immediately."""
177-
if not self.timer.isActive():
178168
self.timer.start(self.scroll_animation_speed)
179169

180170
def stop_scroll(self) -> None:
181171
"""Stop marquee text scroll effect"""
182172
self.timer.stop()
183-
self.delay_timer.stop()
173+
self.repaint()
184174

185175
def _scroll_text(self) -> None:
186-
if self.paused:
176+
"""Smoothly scroll the text leftwards."""
177+
if not self._marquee or self.paused:
187178
return
188-
189179
p_to_m = self.scroll_speed * (self.scroll_animation_speed / 1000.0)
190180
self.scroll_pos -= p_to_m
191-
192181
if self.scroll_pos <= -self.total_scroll_width:
193182
self.loop_count += 1
194-
if self.loop_count >= 2:
183+
if self.loop_count >= self.max_loops:
195184
self.stop_scroll()
196-
else:
197-
self.scroll_pos = 0
198-
199-
self.repaint()
185+
self.scroll_pos = 0.0
186+
self.update()
200187

201188
def paintEvent(self, a0: QtGui.QPaintEvent) -> None:
202189
"""Re-implemented method, paint widget"""
203-
qp = QtWidgets.QStylePainter(self)
204-
opt = QtWidgets.QStyleOption()
205-
opt.initFrom(self)
206-
190+
qp = QtGui.QPainter(self)
207191
qp.setRenderHint(qp.RenderHint.Antialiasing, True)
208192
qp.setRenderHint(qp.RenderHint.SmoothPixmapTransform, True)
209193
qp.setRenderHint(qp.RenderHint.LosslessImageRendering, True)
210-
_rect = self.rect()
211-
_style = self.style()
212-
213-
icon_margin = _style.pixelMetric(_style.PixelMetric.PM_HeaderMargin, opt, self)
214-
if not _style or _rect.isNull():
215-
return
194+
rect = self.contentsRect()
195+
if self._background_color:
196+
qp.setBrush(self._background_color)
197+
qp.setPen(QtCore.Qt.PenStyle.NoPen)
198+
if self._rounded:
199+
path = QtGui.QPainterPath()
200+
path.addRoundedRect(QtCore.QRectF(rect), 10, 10)
201+
qp.fillPath(path, self._background_color)
202+
else:
203+
qp.fillRect(rect, self._background_color)
216204

217205
if self.icon_pixmap:
218-
qp.setCompositionMode(qp.CompositionMode.CompositionMode_SourceOver)
219-
_icon_rect = QtCore.QRectF(
220-
0.0 + icon_margin,
221-
0.0 + icon_margin,
222-
self.width() - icon_margin,
223-
self.height() - icon_margin,
224-
)
225-
_icon_scaled = self.icon_pixmap.scaled(
226-
_icon_rect.size().toSize(),
206+
icon_rect = QtCore.QRectF(0, 0, self.height(), self.height())
207+
scaled = self.icon_pixmap.scaled(
208+
icon_rect.size().toSize(),
227209
QtCore.Qt.AspectRatioMode.KeepAspectRatio,
228210
QtCore.Qt.TransformationMode.SmoothTransformation,
229211
)
230-
scaled_width = _icon_scaled.width()
231-
scaled_height = _icon_scaled.height()
232-
adjusted_x = (_icon_rect.width() - scaled_width) / 2.0
233-
adjusted_y = (_icon_rect.height() - scaled_height) / 2.0
234-
adjusted_icon_rect = QtCore.QRectF(
235-
_icon_rect.x() + adjusted_x,
236-
_icon_rect.y() + adjusted_y,
237-
scaled_width,
238-
scaled_height,
239-
)
240-
qp.drawPixmap(
241-
adjusted_icon_rect, _icon_scaled, _icon_scaled.rect().toRectF()
242-
)
243-
244-
big_rect = QtGui.QPainterPath()
245-
rect = self.contentsRect().toRectF()
246-
big_rect.addRoundedRect(rect, 10.0, 10.0, QtCore.Qt.SizeMode.AbsoluteSize)
247-
mini_rect = QtCore.QRectF(
248-
(rect.width() - rect.width() * 0.99) / 2,
249-
(rect.height() - rect.height() * 0.85) / 2,
250-
rect.width() * 0.99,
251-
rect.height() * 0.85,
252-
)
253-
mini_path = QtGui.QPainterPath()
254-
mini_path.addRoundedRect(mini_rect, 10.0, 10.0, QtCore.Qt.SizeMode.AbsoluteSize)
255-
subtracted = big_rect.subtracted(mini_path)
256-
212+
qp.drawPixmap(icon_rect.toRect(), scaled)
257213
if self.glow_animation.state() == self.glow_animation.State.Running:
258-
qp.setCompositionMode(qp.CompositionMode.CompositionMode_SourceAtop)
259-
subtracted.setFillRule(QtCore.Qt.FillRule.OddEvenFill)
260-
qp.fillPath(subtracted, self.glow_color)
214+
path = QtGui.QPainterPath()
215+
path.addRoundedRect(QtCore.QRectF(rect), 10, 10)
216+
qp.fillPath(path, self.glow_color)
261217
if self._text:
262-
qp.setCompositionMode(qp.CompositionMode.CompositionMode_SourceOver)
263-
264-
text_rect = self.contentsRect()
265-
text_rect.translate(int(self.scroll_pos), 0)
266-
text_path = QtGui.QPainterPath()
267-
text_path.addRect(self.contentsRect().toRectF())
268-
qp.setClipPath(text_path)
269-
270218
text_option = QtGui.QTextOption(self.alignment())
271219
text_option.setWrapMode(QtGui.QTextOption.WrapMode.NoWrap)
272-
qp.drawText(
273-
QtCore.QRectF(text_rect),
274-
self._text,
275-
text_option,
220+
qp.save()
221+
qp.setClipRect(rect)
222+
baseline_y = (
223+
rect.y()
224+
+ (
225+
rect.height()
226+
+ self.fontMetrics().ascent()
227+
- self.fontMetrics().descent()
228+
)
229+
/ 2
276230
)
277-
if self._marquee and self.text_width > self.label_width:
278-
second_text_rect = self.rect()
279-
second_text_rect.translate(
280-
int(self.scroll_pos + self.text_width + self.label_width / 2),
281-
0,
231+
232+
if self.text_width > self.label_width:
233+
qp.drawText(
234+
QtCore.QPointF(rect.x() + self.scroll_pos, baseline_y), self._text
282235
)
283-
qp.drawText(QtCore.QRectF(second_text_rect), self._text, text_option)
284-
draw_rect = QtCore.QRectF(
285-
self.contentsRect().x()
286-
+ self.scroll_pos
287-
+ self.text_width
288-
+ self.marquee_spacing,
289-
self.contentsRect().y(),
290-
self.text_width,
291-
self.contentsRect().height(),
236+
# Draw scrolling repeater text
237+
qp.drawText(
238+
QtCore.QPointF(
239+
rect.x() + self.scroll_pos + self.total_scroll_width, baseline_y
240+
),
241+
self._text,
292242
)
293-
qp.drawText(draw_rect, self._text, text_option)
294243
else:
295-
text_rect = self.contentsRect().toRectF()
296-
qp.drawText(text_rect, self._text, text_option)
244+
center_x = rect.x() + (rect.width() - self.text_width) / 2
245+
246+
qp.drawText(QtCore.QPointF(center_x, baseline_y), self._text)
247+
qp.restore()
297248

298249
qp.end()
299250

0 commit comments

Comments
 (0)