From 5f888d54b24f16c6ad92fb81fcb8789d09a29cfd Mon Sep 17 00:00:00 2001 From: Maic Siemering Date: Thu, 11 Jan 2024 13:17:40 +0100 Subject: [PATCH] Allow adaptive width for UILayout with multiline text (#1946) --- arcade/gui/widgets/text.py | 15 +++++++++++++-- tests/unit/gui/test_uilabel.py | 9 +++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/arcade/gui/widgets/text.py b/arcade/gui/widgets/text.py index c855613df..c595a0dfd 100644 --- a/arcade/gui/widgets/text.py +++ b/arcade/gui/widgets/text.py @@ -87,6 +87,14 @@ def __init__( size_hint_max=None, **kwargs, ): + # If multiline is enabled and no width is given, we need to fit the + # size to the text. This is done by setting the width to a very + # large value and then fitting the size. + adaptive_multiline = False + if multiline and not width: + width = 999999 + adaptive_multiline = True + # Use Arcade Text wrapper of pyglet.Label for text rendering self.label = arcade.Text( start_x=0, @@ -99,10 +107,13 @@ def __init__( bold=bold, italic=italic, align=align, - anchor_y="bottom", # Position text bottom left to fit into scissor - multiline=multiline, # area + anchor_y="bottom", # Position text bottom left to fit into scissor area + multiline=multiline, **kwargs, ) + if adaptive_multiline: + # +1 is required to prevent line wrap + width = self.label.content_width + 1 super().__init__( x=x, diff --git a/tests/unit/gui/test_uilabel.py b/tests/unit/gui/test_uilabel.py index c94528344..524bc01a7 100644 --- a/tests/unit/gui/test_uilabel.py +++ b/tests/unit/gui/test_uilabel.py @@ -56,3 +56,12 @@ def test_uilabel_fixes_internal_text_to_pos_0_0(window): assert label.label.position == (0, 0) assert label.position == (10, 10) +def test_adaptive_width_support_for_multiline_text(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="Multiline\ntext\nwhich\n", multiline=True) + assert label.width < 100 + assert label.height > 20