"""
pygame-menu
https://github.com/ppizarror/pygame-menu
VERTICAL VILL
Vertical fill box. Fills all available vertical space.
"""
__all__ = [
'VFill',
'VFillManager'
]
import pygame
import pygame_menu
from abc import ABC
from pygame_menu.widgets.core.widget import AbstractWidgetManager
from pygame_menu.widgets.widget.none import NoneWidget
from pygame_menu._types import NumberType, NumberInstance
# noinspection PyMissingOrEmptyDocstring
[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 any transformation.
: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(VFill, self).__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 = self.get_menu().get_height(inner=True)
total_column_height = 0
total_vfills = 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 behaviour 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