Skip to content

Commit

Permalink
feat(gui): UILabel avoids full render if background set
Browse files Browse the repository at this point in the history
  • Loading branch information
eruvanos committed May 24, 2024
1 parent b8cd74a commit 1649978
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 1 deletion.
9 changes: 8 additions & 1 deletion arcade/gui/widgets/text.py
Original file line number Diff line number Diff line change
Expand Up @@ -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).
Expand Down Expand Up @@ -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
Expand Down
31 changes: 31 additions & 0 deletions tests/unit/gui/test_uilabel.py
Original file line number Diff line number Diff line change
@@ -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):
Expand Down Expand Up @@ -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()

0 comments on commit 1649978

Please sign in to comment.