Skip to content

Commit

Permalink
Add Frame awareness while computing max wordwrap width
Browse files Browse the repository at this point in the history
  • Loading branch information
ppizarror committed Dec 23, 2024
1 parent e6debae commit 96f8a7a
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 17 deletions.
46 changes: 29 additions & 17 deletions pygame_menu/widgets/widget/label.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,15 +190,14 @@ def _wordwrap_line(
:param tab_size: Tab size
:return: List of strings
"""
final_lines = []
words = line.split(' ')
i, current_line = 0, ''
final_lines: List[str] = []
words: List[str] = line.split(' ')

while True:
split_line = False
split_line: bool = False
current_line: str
for i, _ in enumerate(words):
current_line = ' '.join(words[:i + 1])
current_line = current_line.replace('\t', ' ' * tab_size)
current_line = ' '.join(words[:i + 1]).replace('\t', ' ' * tab_size)
current_line_size = font.size(current_line)
if current_line_size[0] > max_width:
split_line = True
Expand All @@ -216,19 +215,23 @@ def _wordwrap_line(

def _get_max_container_width(self) -> int:
"""
Return the maximum label container width. It can be the column width,
menu width or frame width if horizontal.
Return the maximum container width. It can be the column width,
menu width or frame width.
:return: Container width
:return: Container width (px)
"""
menu = self._menu
max_width: int = 0
if menu is None:
return 0
try:
# noinspection PyProtectedMember
max_width = menu._column_widths[self.get_col_row_index()[0]]
except IndexError:
max_width = menu.get_width(inner=True)
elif self._frame is not None:
max_width = self._frame.get_width()
else: # Infers width from container Menu
try:
# noinspection PyProtectedMember
max_width = menu._column_widths[self.get_col_row_index()[0]]
except IndexError:
max_width = menu.get_width(inner=True)
return max_width - self._padding[1] - self._padding[3] - self._selection_effect.get_width()

def get_overflow_lines(self) -> List[str]:
Expand All @@ -245,11 +248,12 @@ def _render(self) -> Optional[bool]:
font_color: ColorType = self.get_font_color_status()
if not self._render_hash_changed(self._title, font_color, self._visible, self._menu, self._font,
self._last_underline[1], self._padding, self._selection_effect.get_width(),
self.readonly):
self.readonly, self._frame):
return True
self._lines.clear()

# Generate surface
max_width: int = 0
if not self._wordwrap:
self._surface = self._render_string(self._title, font_color)
self._lines.append(self._title)
Expand All @@ -259,12 +263,13 @@ def _render(self) -> Optional[bool]:
if self._font is None or self._menu is None:
self._surface = make_surface(0, 0, alpha=True)
else:
lines = sum(
max_width = self._get_max_container_width()
lines: List[str] = sum(
(
self._wordwrap_line(
line=line,
font=self._font,
max_width=self._get_max_container_width(),
max_width=max_width,
tab_size=self._tab_size
)
for line in self._title.split('\n')
Expand Down Expand Up @@ -299,6 +304,13 @@ def _render(self) -> Optional[bool]:
if n_line + 1 == num_lines:
break

# Apply max width if wordwrap exceeds size
if self._wordwrap and self.get_width() > max_width > 0:
verbose_prev: bool = self._verbose
self._verbose = False # Disable auto-warns while setting max width
self.set_max_width(max_width, render=False)
self._verbose = verbose_prev

# Update rect object
self._apply_transforms()
self._rect.width, self._rect.height = self._surface.get_size()
Expand Down
8 changes: 8 additions & 0 deletions test/test_widget_button.py
Original file line number Diff line number Diff line change
Expand Up @@ -338,3 +338,11 @@ def test_multiline(self) -> None:
self.assertEqual(len(button.get_lines()), 3) # The widget needs 4 lines, but maximum is 3
self.assertEqual(button.get_height(), 131)
self.assertEqual(button.get_overflow_lines(), ['important nice a test is required'])

# Test multiline within Frame
f1 = menu.add.frame_h(200, 200)
f1.pack(button)
self.assertEqual(button.get_overflow_lines(),
['required', 'nice a test is', 'important', 'was very', 'amet this', 'dolor sit',
'lorem ipsum', 'required', 'nice a test is', 'important', 'was very'])
self.assertLessEqual(abs(button.get_width() - button._get_max_container_width()), 2)

0 comments on commit 96f8a7a

Please sign in to comment.