"""
pygame-menu
https://github.com/ppizarror/pygame-menu
VERTICAL VILL
Vertical fill box. Fills all available vertical space.
"""
from __future__ import annotations
__all__ = ["VFill", "VFillManager"]
from abc import ABC
from typing import TYPE_CHECKING
from pygame_menu._types import NumberInstance, NumberType
from pygame_menu.widgets.core.widget import AbstractWidgetManager
from pygame_menu.widgets.widget.none import NoneWidget
if TYPE_CHECKING:
import pygame
import pygame_menu
[docs]
class VFill(NoneWidget):
"""
Vertical fill widget. This widget fills all vertical space if available, else,
it uses the min height.
.. note::
VFill does not accept transformations.
:param min_height: Minimum height in px
:param widget_id: ID of the widget
"""
_min_height: int
def __init__(self, min_height: NumberType, widget_id: str = "") -> None:
assert isinstance(min_height, NumberInstance)
assert min_height >= 0, "negative min height is not valid"
super().__init__(widget_id=widget_id)
self._min_height = min_height
def get_rect(self, *args, **kwargs) -> pygame.Rect:
# Get all menu widgets, and for those in the same column store the total
# size (without considering other vfills). Then, divide all available height
# in the total vfills found
c = self.get_col_row_index()[0]
if c == -1:
self._rect.height = self._min_height
return self._rect
menu_widgets_col = self.get_menu().get_widgets_column(c)
available_height: int = self.get_menu().get_height(inner=True)
total_column_height: int = 0
total_vfills: int = 0
column_vfills = []
for w in menu_widgets_col:
if not isinstance(w, VFill):
total_column_height += w.get_height()
else:
column_vfills.append(w)
total_column_height += w._min_height
total_vfills += 1
vfill_height = (
((available_height - total_column_height) / total_vfills)
if total_vfills > 0
else 0
)
# Discount 1px only to last
if self == column_vfills[-1] and vfill_height > 0:
vfill_height -= 1
vfill_height = max(0, vfill_height)
self._rect.height = self._min_height + vfill_height
return self._rect
class VFillManager(AbstractWidgetManager, ABC):
"""
VFill manager.
"""
def vertical_fill(
self, min_height: NumberType = 0, vfill_id: str = ""
) -> pygame_menu.widgets.VFill:
"""
Adds a vertical fill to the Menu. This widget fills all vertical space
if available, else, it uses the min height.
.. note::
This is applied only to the base Menu (not the currently displayed,
stored in ``_current`` pointer); for such behavior apply to
:py:meth:`pygame_menu.menu.Menu.get_current` object.
:param min_height: Minimum height in px
:param vfill_id: ID of the vertical fill
:return: Widget object
:rtype: :py:class:`pygame_menu.widgets.VFill`
"""
attributes = self._filter_widget_attributes({})
widget = VFill(min_height, widget_id=vfill_id)
self._configure_widget(widget=widget, **attributes)
self._append_widget(widget)
return widget