Skip to content

Commit

Permalink
add UIElement fixes to dynamic sizing
Browse files Browse the repository at this point in the history
  • Loading branch information
MyreMylar committed Apr 16, 2023
1 parent 2fa1be3 commit d2582c4
Showing 1 changed file with 55 additions and 2 deletions.
57 changes: 55 additions & 2 deletions pygame_gui/core/ui_element.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,17 +44,26 @@ def __init__(self, relative_rect: Union[pygame.Rect, Tuple[int, int, int, int]],

self._layer = 0
self.ui_manager = manager
self.ui_container = None
if self.ui_manager is None:
self.ui_manager = get_default_manager()
if self.ui_manager is None:
raise ValueError("Need to create at least one UIManager to create UIElements")

super().__init__(self.ui_manager.get_sprite_group())

self.minimum_dimensions = (-1, -1)
relative_rect.size = self._get_clamped_to_minimum_dimensions(relative_rect.size)

if isinstance(relative_rect, pygame.Rect):
self.relative_rect = relative_rect.copy()
else:
self.relative_rect = pygame.Rect(relative_rect)
self.rect = self.relative_rect.copy()

self.dynamic_width = True if self.relative_rect.width == -1 else False
self.dynamic_height = True if self.relative_rect.height == -1 else False

self.ui_group = self.ui_manager.get_sprite_group()
self.ui_theme = self.ui_manager.get_theme()

Expand Down Expand Up @@ -139,7 +148,6 @@ def __init__(self, relative_rect: Union[pygame.Rect, Tuple[int, int, int, int]],
self.border_width = None # type: Union[None, int]
self.shape_corner_radius = None # type: Union[None, int]

self.ui_container = None
self._setup_container(container)

self.dirty = 1
Expand All @@ -152,6 +160,26 @@ def __init__(self, relative_rect: Union[pygame.Rect, Tuple[int, int, int, int]],

self._focus_set = {self}

def _get_clamped_to_minimum_dimensions(self, dimensions, clamp_to_container=False):
if self.ui_container is not None and clamp_to_container:
dimensions = (min(self.ui_container.rect.width,
max(self.minimum_dimensions[0],
int(dimensions[0]))),
min(self.ui_container.rect.height,
max(self.minimum_dimensions[1],
int(dimensions[1]))))
else:
dimensions = (max(self.minimum_dimensions[0], int(dimensions[0])),
max(self.minimum_dimensions[1], int(dimensions[1])))
return dimensions

def _on_contents_changed(self):
if self.dynamic_width or self.dynamic_height:
self._calc_dynamic_size()

def _calc_dynamic_size(self):
pass

@staticmethod
def _validate_horizontal_anchors(anchors: Dict[str, Union[str, 'UIElement']]):
# first make a dictionary of just the horizontal anchors
Expand Down Expand Up @@ -462,6 +490,7 @@ def _update_absolute_rect_position_from_anchors(self, recalculate_margins=False)
self.rect.top = new_top
new_height = new_bottom - new_top
new_width = new_right - new_left
new_width, new_height = self._get_clamped_to_minimum_dimensions((new_width, new_height))
if (new_height != self.relative_rect.height) or (new_width != self.relative_rect.width):
self.set_dimensions((new_width, new_height))

Expand Down Expand Up @@ -649,18 +678,42 @@ def set_position(self, position: Union[pygame.math.Vector2,
self._update_container_clip()
self.ui_container.on_anchor_target_changed(self)

def set_minimum_dimensions(self, dimensions: Union[pygame.math.Vector2,
Tuple[int, int],
Tuple[float, float]]):
"""
If this window is resizable, then the dimensions we set here will be the minimum that
users can change the window to. They are also used as the minimum size when
'set_dimensions' is called.
:param dimensions: The new minimum dimension for the window.
"""
self.minimum_dimensions = (min(self.ui_container.rect.width, int(dimensions[0])),
min(self.ui_container.rect.height, int(dimensions[1])))

if ((self.rect.width < self.minimum_dimensions[0]) or
(self.rect.height < self.minimum_dimensions[1])):
new_width = max(self.minimum_dimensions[0], self.rect.width)
new_height = max(self.minimum_dimensions[1], self.rect.height)
self.set_dimensions((new_width, new_height))

def set_dimensions(self, dimensions: Union[pygame.math.Vector2,
Tuple[int, int],
Tuple[float, float]]):
Tuple[float, float]],
clamp_to_container: bool = False):
"""
Method to directly set the dimensions of an element.
NOTE: Using this on elements inside containers with non-default anchoring arrangements
may make a mess of them.
:param dimensions: The new dimensions to set.
:param clamp_to_container: Whether we should clamp the dimensions to the
dimensions of the container or not.
"""
dimensions = self._get_clamped_to_minimum_dimensions(dimensions, clamp_to_container)
self.relative_rect.width = int(dimensions[0])
self.relative_rect.height = int(dimensions[1])
self.rect.size = self.relative_rect.size
Expand Down

0 comments on commit d2582c4

Please sign in to comment.