From 16499785913cb611226052c4ecd9a0200b4230c6 Mon Sep 17 00:00:00 2001 From: Maic Siemering Date: Fri, 24 May 2024 19:50:42 +0200 Subject: [PATCH] feat(gui): UILabel avoids full render if background set --- arcade/gui/widgets/text.py | 9 ++++++++- tests/unit/gui/test_uilabel.py | 31 +++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/arcade/gui/widgets/text.py b/arcade/gui/widgets/text.py index d7cebcb0c..abdd7f0b6 100644 --- a/arcade/gui/widgets/text.py +++ b/arcade/gui/widgets/text.py @@ -35,6 +35,9 @@ class UILabel(UIWidget): By default, a label will fit its initial content. If the text is changed use :py:meth:`~arcade.gui.UILabel.fit_content` to adjust the size. + If the text changes frequently, ensure to set a background color or texture, which will + prevent a full rendering of the whole UI and only render the label itself. + :param text: Text displayed on the label. :param x: x position (default anchor is bottom-left). :param y: y position (default anchor is bottom-left). @@ -166,7 +169,11 @@ def text(self, value): self.label.text = value self._update_layout() self._update_size_hint_min() - self.trigger_full_render() + + if self._bg_color or self._bg_tex: + self.trigger_render() + else: + self.trigger_full_render() def _update_layout(self): # Update Pyglet layout size diff --git a/tests/unit/gui/test_uilabel.py b/tests/unit/gui/test_uilabel.py index f87757deb..bf57adccf 100644 --- a/tests/unit/gui/test_uilabel.py +++ b/tests/unit/gui/test_uilabel.py @@ -1,6 +1,9 @@ +from unittest.mock import Mock + import pytest from arcade.gui import UILabel, Rect +from arcade.types import Color def test_uilabel_inits_with_text_size(window): @@ -64,3 +67,31 @@ def test_adaptive_width_support_for_multiline_text(window): label = UILabel(text="Multiline\ntext\nwhich\n", multiline=True) assert label.width < 100 assert label.height > 20 + + +def test_change_text_does_full_render_without_background(window): + """ + This test is a bit tricky. Enabling multiline without a width + should fit the size to the text. This is not natively supported by either arcade.Text or pyglet.Label. + Because text length variates between different os, we can only test boundaries, which indicate a proper implementation. + """ + + label = UILabel(text="First Text") + label.parent = Mock() + + label.text = "Second Text" + label.parent.trigger_render.assert_called_once() + + +def test_change_text_does_normal_render_with_background(window): + """ + This test is a bit tricky. Enabling multiline without a width + should fit the size to the text. This is not natively supported by either arcade.Text or pyglet.Label. + Because text length variates between different os, we can only test boundaries, which indicate a proper implementation. + """ + + label = UILabel(text="First Text").with_background(color=Color(255, 255, 255, 255)) + label.parent = Mock() + + label.text = "Second Text" + label.parent.trigger_render.assert_not_called()