Beispiel #1
0
    def set_alignment(self, align):
        """
        Set the alignment of the widget.

        :param align: Widget align, see locals
        :type align: str
        :return: None
        """
        assert_alignment(align)
        self._alignment = align
Beispiel #2
0
    def _get(params, key, allowed_types=None, default=None):
        """
        Return a value from a dictionary.

        :param params: parameters dictionary
        :type params: dict
        :param key: key to look for
        :type key: str
        :param allowed_types: list of allowed types
        :type allowed_types: any
        :param default: default value to return
        :type default: any
        :return: The value associated to the key
        :rtype: any
        """
        if key not in params:
            return default

        value = params.pop(key)
        if allowed_types:
            if not isinstance(allowed_types, (tuple, list)):
                allowed_types = (allowed_types, )
            for valtype in allowed_types:
                if valtype == 'color':
                    _utils.assert_color(value)
                elif valtype == 'color_none':
                    if value is None:
                        return value
                    _utils.assert_color(value)
                elif valtype == 'color_image':
                    if isinstance(value, BaseImage):
                        return value
                    _utils.assert_color(value)
                elif valtype == 'color_image_none':
                    if value is None:
                        return value
                    elif isinstance(value, BaseImage):
                        return value
                    _utils.assert_color(value)
                elif valtype == 'position':
                    _utils.assert_position(value)
                elif valtype == 'alignment':
                    _utils.assert_alignment(value)
                elif valtype == 'tuple2':
                    _utils.assert_vector2(value)

            all_types = ('color', 'color_none', 'color_image',
                         'color_image_none', 'position', 'alignment', 'tuple2')
            others = tuple(t for t in allowed_types if t not in all_types)
            if others:
                msg = 'Theme.{} type shall be in {} types (got {})'.format(
                    key, others, type(value))
                assert isinstance(value, others), msg
        return value
Beispiel #3
0
    def _check_cell_style(align: str, background_color: ColorInputType,
                          border_color: ColorInputType,
                          border_position: WidgetBorderPositionType,
                          border_width: int, padding: PaddingType,
                          vertical_position: str) -> None:
        """
        Assert cell style.

        :param align: Horizontal align of each cell. See :py:mod:`pygame_menu.locals`
        :param background_color: Background color
        :param border_color: Border color of each cell
        :param border_position: Border position of each cell. Valid only: north, south, east, and west. See :py:mod:`pygame_menu.locals`
        :param border_width: Border width in px of each cell
        :param padding: Cell padding according to CSS rules. General shape: (top, right, bottom, left)
        :param vertical_position: Vertical position of each cell. Only valid: north, center, and south. See :py:mod:`pygame_menu.locals`
        :return: None
        """
        # Alignment
        assert_alignment(align)

        # Background color
        if background_color is not None:
            assert_color(background_color)

        # Padding
        parse_padding(padding)

        # Vertical position
        assert_position(vertical_position)
        assert vertical_position in (POSITION_NORTH, POSITION_CENTER, POSITION_SOUTH), \
            'cell vertical position must be NORTH, CENTER, or SOUTH'

        # Border color
        assert isinstance(border_width, int) and border_width >= 0
        if border_color is not None:
            assert_color(border_color)

        # Border position
        assert isinstance(border_position, (str, VectorInstance))
        if isinstance(border_position, str):
            border_position = [border_position]

        # Border positioning
        for pos in border_position:
            assert pos in (POSITION_NORTH, POSITION_SOUTH, POSITION_EAST, POSITION_WEST), \
                'only north, south, east, and west border positions are valid, ' \
                'but received "{0}"'.format(pos)
Beispiel #4
0
    def _get(params: Dict[str, Any],
             key: str,
             allowed_types: Optional[Union[Type, str, List[Type],
                                           Tuple[Type, ...]]] = None,
             default: Any = None) -> Any:
        """
        Return a value from a dictionary.

        Custom types (str)
            -   alignment           – pygame-menu alignment (locals)
            -   callable            – Is callable type, same as ``"function"``
            -   color               – Check color
            -   color_image         – Color or :py:class:`pygame_menu.baseimage.BaseImage`
            -   color_image_none    – Color, :py:class:`pygame_menu.baseimage.BaseImage`, or None
            -   color_none          – Color or None
            -   cursor              – Cursor object (pygame)
            -   font                – Font type
            -   image               – Value must be ``BaseImage``
            -   none                – None only
            -   position            – pygame-menu position (locals)
            -   position_vector     – pygame-menu position (str or vector)
            -   tuple2              – Only valid numeric tuples ``(x, y)`` or ``[x, y]``
            -   tuple2int           – Only valid integer tuples ``(x, y)`` or ``[x, y]``
            -   tuple3              – Only valid numeric tuples ``(x, y, z)`` or ``[x, y, z]``
            -   tuple3int           – Only valid integer tuples ``(x, y, z)`` or ``[x, y, z]``
            -   type                – Type-class (bool, str, etc...)

        :param params: Parameters dictionary
        :param key: Key to look for
        :param allowed_types: List of allowed types
        :param default: Default value to return
        :return: The value associated to the key
        """
        value = params.pop(key, default)
        if allowed_types is not None:
            other_types = []  # Contain other types to check from
            if not isinstance(allowed_types, VectorInstance):
                allowed_types = (allowed_types, )
            for val_type in allowed_types:

                if val_type == 'alignment':
                    assert_alignment(value)

                elif val_type == callable or val_type == 'function' or val_type == 'callable':
                    assert is_callable(value), \
                        'value must be callable type'

                elif val_type == 'color':
                    value = assert_color(value)

                elif val_type == 'color_image':
                    if not isinstance(value, BaseImage):
                        value = assert_color(value)

                elif val_type == 'color_image_none':
                    if not (value is None or isinstance(value, BaseImage)):
                        value = assert_color(value)

                elif val_type == 'color_none':
                    if value is not None:
                        value = assert_color(value)

                elif val_type == 'cursor':
                    assert_cursor(value)

                elif val_type == 'font':
                    assert_font(value)

                elif val_type == 'image':
                    assert isinstance(value, BaseImage), \
                        'value must be BaseImage type'

                elif val_type == 'none':
                    assert value is None

                elif val_type == 'position':
                    assert_position(value)

                elif val_type == 'position_vector':
                    assert_position_vector(value)

                elif val_type == 'type':
                    assert isinstance(value, type), \
                        'value is not type-class'

                elif val_type == 'tuple2':
                    assert_vector(value, 2)

                elif val_type == 'tuple2int':
                    assert_vector(value, 2, int)

                elif val_type == 'tuple3':
                    assert_vector(value, 3)

                elif val_type == 'tuple3int':
                    assert_vector(value, 3, int)

                else:  # Unknown type
                    assert isinstance(val_type, type), \
                        'allowed type "{0}" is not a type-class'.format(val_type)
                    other_types.append(val_type)

            # Check other types
            if len(other_types) > 0:
                others = tuple(other_types)
                assert isinstance(value, others), \
                    'Theme.{} type shall be in {} types (got {})'.format(key, others, type(value))

        return value
Beispiel #5
0
    def validate(self) -> 'Theme':
        """
        Validate the values of the theme. If there's a invalid parameter throws an
        ``AssertionError``.

        This function also converts all lists to tuples. This is done because lists
        are mutable.

        :return: Self reference
        """
        if self._disable_validation:
            return self

        # Boolean asserts
        assert isinstance(self.scrollbar_shadow, bool)
        assert isinstance(self.title_bar_modify_scrollarea, bool)
        assert isinstance(self.title_close_button, bool)
        assert isinstance(self.title_font_antialias, bool)
        assert isinstance(self.title_font_shadow, bool)
        assert isinstance(self.widget_font_antialias, bool)
        assert isinstance(self.widget_font_background_color_from_menu, bool)
        assert isinstance(self.widget_font_shadow, bool)

        # Value type checks
        assert_alignment(self.widget_alignment)
        assert_cursor(self.scrollbar_cursor)
        assert_cursor(self.title_close_button_cursor)
        assert_cursor(self.widget_cursor)
        assert_font(self.title_font)
        assert_font(self.widget_font)
        assert_position(self.scrollbar_shadow_position)
        assert_position(self.title_font_shadow_position)
        assert_position(self.widget_font_shadow_position)
        assert_position_vector(self.widget_border_position)

        assert _check_menubar_style(self.title_bar_style)
        assert get_scrollbars_from_position(
            self.scrollarea_position) is not None

        # Check selection effect if None
        if self.widget_selection_effect is None:
            self.widget_selection_effect = NoneSelection()

        assert isinstance(self.cursor_switch_ms, NumberInstance)
        assert isinstance(self.fps, NumberInstance)
        assert isinstance(self.scrollbar_shadow_offset, int)
        assert isinstance(self.scrollbar_slider_pad, NumberInstance)
        assert isinstance(self.scrollbar_thick, int)
        assert isinstance(self.title, bool)
        assert isinstance(self.title_fixed, bool)
        assert isinstance(self.title_floating, bool)
        assert isinstance(self.title_font_shadow_offset, int)
        assert isinstance(self.title_font_size, int)
        assert isinstance(self.title_updates_pygame_display, bool)
        assert isinstance(self.widget_background_inflate_to_selection, bool)
        assert isinstance(self.widget_border_width, int)
        assert isinstance(self.widget_box_border_width, int)
        assert isinstance(self.widget_font_shadow_offset, int)
        assert isinstance(self.widget_font_size, int)
        assert isinstance(self.widget_padding, PaddingInstance)
        assert isinstance(self.widget_selection_effect, Selection)
        assert isinstance(self.widget_tab_size, int)

        # Format colors, this converts all color lists to tuples automatically,
        # if image, return the same object
        self.background_color = self._format_color_opacity(
            self.background_color)
        self.cursor_color = self._format_color_opacity(self.cursor_color)
        self.cursor_selection_color = self._format_color_opacity(
            self.cursor_selection_color)
        self.focus_background_color = self._format_color_opacity(
            self.focus_background_color)
        self.readonly_color = self._format_color_opacity(self.readonly_color)
        self.readonly_selected_color = self._format_color_opacity(
            self.readonly_selected_color)
        self.scrollbar_color = self._format_color_opacity(self.scrollbar_color)
        self.scrollbar_shadow_color = self._format_color_opacity(
            self.scrollbar_shadow_color)
        self.scrollbar_slider_color = self._format_color_opacity(
            self.scrollbar_slider_color)
        self.scrollbar_slider_hover_color = self._format_color_opacity(
            self.scrollbar_slider_hover_color)
        self.selection_color = self._format_color_opacity(self.selection_color)
        self.surface_clear_color = self._format_color_opacity(
            self.surface_clear_color)
        self.title_background_color = self._format_color_opacity(
            self.title_background_color)
        self.title_close_button_background_color = self._format_color_opacity(
            self.title_close_button_background_color)
        self.title_font_color = self._format_color_opacity(
            self.title_font_color)
        self.title_font_shadow_color = self._format_color_opacity(
            self.title_font_shadow_color)
        self.widget_background_color = self._format_color_opacity(
            self.widget_background_color, none=True)
        self.widget_border_color = self._format_color_opacity(
            self.widget_border_color)
        self.widget_box_arrow_color = self._format_color_opacity(
            self.widget_box_arrow_color)
        self.widget_box_background_color = self._format_color_opacity(
            self.widget_box_background_color)
        self.widget_box_border_color = self._format_color_opacity(
            self.widget_box_border_color)
        self.widget_font_background_color = self._format_color_opacity(
            self.widget_font_background_color, none=True)
        self.widget_font_color = self._format_color_opacity(
            self.widget_font_color)
        self.widget_font_shadow_color = self._format_color_opacity(
            self.widget_font_shadow_color)
        self.widget_url_color = self._format_color_opacity(
            self.widget_url_color)

        # List to tuple
        self.scrollarea_outer_margin = self._vec_to_tuple(
            self.scrollarea_outer_margin, 2, NumberInstance)
        self.title_offset = self._vec_to_tuple(self.title_offset, 2,
                                               NumberInstance)
        self.widget_background_inflate = self._vec_to_tuple(
            self.widget_background_inflate, 2, int)
        self.widget_border_inflate = self._vec_to_tuple(
            self.widget_border_inflate, 2, int)
        self.widget_box_arrow_margin = self._vec_to_tuple(
            self.widget_box_arrow_margin, 3, int)
        self.widget_box_inflate = self._vec_to_tuple(self.widget_box_inflate,
                                                     2, int)
        self.widget_box_margin = self._vec_to_tuple(self.widget_box_margin, 2,
                                                    NumberInstance)
        self.widget_margin = self._vec_to_tuple(self.widget_margin, 2,
                                                NumberInstance)
        if isinstance(self.widget_padding, VectorInstance):
            self.widget_padding = self._vec_to_tuple(self.widget_padding)
            assert 2 <= len(self.widget_padding) <= 4, \
                'widget padding tuple length must be 2, 3 or 4'
            for p in self.widget_padding:
                assert isinstance(p, NumberInstance), \
                    'each padding element must be numeric (integer or float)'
                assert p >= 0, \
                    'all padding elements must be equal or greater than zero'
        else:
            assert self.widget_padding >= 0, 'padding cannot be a negative number'
        self.widget_offset = self._vec_to_tuple(self.widget_offset, 2,
                                                NumberInstance)

        # Check sizes
        assert self.scrollarea_outer_margin[0] >= 0 and self.scrollarea_outer_margin[1] >= 0, \
            'scroll area outer margin must be equal or greater than zero on both axis'
        assert self.widget_offset[0] >= 0 and self.widget_offset[1] >= 0, \
            'widget offset must be equal or greater than zero'
        assert self.widget_background_inflate[0] >= 0 and self.widget_background_inflate[1] >= 0, \
            'widget background inflate must be equal or greater than zero on both axis'
        assert self.widget_border_inflate[0] >= 0 and self.widget_border_inflate[1] >= 0, \
            'widget border inflate must be equal or greater than zero on both axis'
        assert self.widget_box_inflate[0] >= 0 and self.widget_box_inflate[1] >= 0, \
            'widget box inflate inflate must be equal or greater than zero on both axis'

        assert self.cursor_switch_ms > 0, 'cursor switch ms must be greater than zero'
        assert self.fps >= 0, 'fps must be equal or greater than zero'
        assert self.scrollbar_shadow_offset > 0, 'scrollbar shadow offset must be greater than zero'
        assert self.scrollbar_slider_pad >= 0, 'slider pad must be equal or greater than zero'
        assert self.scrollbar_thick > 0, 'scrollbar thickness must be greater than zero'
        assert self.title_font_size > 0, 'title font size must be greater than zero'
        assert self.widget_border_width >= 0, 'widget border width must be equal or greater than zero'
        assert self.widget_box_border_width >= 0, 'widget border box width must be equal or greater than zero'
        assert self.widget_font_shadow_offset > 0, 'widget font shadow offset must be greater than zero'
        assert self.widget_font_size > 0, 'widget font size must be greater than zero'
        assert self.widget_tab_size >= 0, 'widget tab size must be equal or greater than zero'

        # Color asserts
        assert self.focus_background_color[3] != 0, \
            'focus background color cannot be fully transparent, suggested opacity between 1 and 255'

        return self
Beispiel #6
0
    def _get(params: Dict[str, Any], key: str,
             allowed_types: Optional[Union[Type, str, List[Type], Tuple[Type, ...]]] = None,
             default: Any = None) -> Any:
        """
        Return a value from a dictionary.

        Custom types (str)
            -   alignment           pygame-menu alignment (locals)
            -   callable            Is callable type, same as ``'function'``
            -   color               Check color
            -   color_image         Color or :py:class:`pygame_menu.baseimage.BaseImage`
            -   color_image_none    Color, :py:class:`pygame_menu.baseimage.BaseImage`, or None
            -   color_none          Color or None
            -   image               Value must be ``BaseImage``
            -   none                None only
            -   position            pygame-menu position (locals)}
            -   type                Type-class (bool, str, etc...)
            -   tuple2              Only valid numeric tuples ``(x,y)`` or ``[x,y]``
            -   tuple3              Only valid numeric tuples ``(x,y,z)`` or ``[x,y,z]``

        :param params: Parameters dictionary
        :param key: Key to look for
        :param allowed_types: List of allowed types
        :param default: Default value to return
        :return: The value associated to the key
        """
        value = params.pop(key, default)
        if allowed_types is not None:
            other_types = []  # Contain other types to check from
            if not isinstance(allowed_types, (tuple, list)):
                allowed_types = (allowed_types,)
            for valtype in allowed_types:

                if valtype == 'alignment':
                    _utils.assert_alignment(value)

                elif valtype == callable or valtype == 'function' or valtype == 'callable':
                    assert _utils.is_callable(value), 'value must be callable type'

                elif valtype == 'color':
                    _utils.assert_color(value)

                elif valtype == 'color_image':
                    if isinstance(value, BaseImage):
                        return value
                    _utils.assert_color(value)

                elif valtype == 'color_image_none':
                    if value is None or isinstance(value, BaseImage):
                        return value
                    _utils.assert_color(value)

                elif valtype == 'color_none':
                    if value is None:
                        return value
                    _utils.assert_color(value)

                elif valtype == 'image':
                    assert isinstance(value, BaseImage), 'value must be BaseImage type'

                elif valtype == 'none':
                    assert value is None

                elif valtype == 'position':
                    _utils.assert_position(value)

                elif valtype == 'type':
                    assert isinstance(value, type), 'value is not type-class'

                elif valtype == 'tuple2':
                    _utils.assert_vector(value, 2)

                elif valtype == 'tuple3':
                    _utils.assert_vector(value, 3)

                else:  # Unknown type
                    assert isinstance(valtype, type), \
                        'allowed type "{0}" is not a type-class'.format(valtype)
                    other_types.append(valtype)

            # Check other types
            if len(other_types) > 0:
                others = tuple(other_types)
                msg = 'Theme.{} type shall be in {} types (got {})'.format(key, others, type(value))
                assert isinstance(value, others), msg

        return value
Beispiel #7
0
    def validate(self) -> 'Theme':
        """
        Validate the values of the theme. If there's a invalid parameter throws an
        ``AssertionError``.

        This function also converts all lists to tuples. This is done because lists
        are mutable.

        :return: Self reference
        """
        if self._disable_validation:
            return self

        # Boolean asserts
        assert isinstance(self.title_close_button, bool)
        assert isinstance(self.title_bar_modify_scrollarea, bool)
        assert isinstance(self.title_font_antialias, bool)
        assert isinstance(self.title_shadow, bool)
        assert isinstance(self.scrollbar_shadow, bool)
        assert isinstance(self.widget_font_antialias, bool)
        assert isinstance(self.widget_font_background_color_from_menu, bool)
        assert isinstance(self.widget_shadow, bool)

        # Value type checks
        _utils.assert_alignment(self.widget_alignment)
        _utils.assert_position(self.scrollbar_shadow_position)
        _utils.assert_position(self.title_shadow_position)
        _utils.assert_position(self.widget_shadow_position)
        assert _check_menubar_style(self.title_bar_style)
        assert get_scrollbars_from_position(self.scrollarea_position) is not None

        assert isinstance(self.cursor_switch_ms, (int, float))
        assert isinstance(self.fps, (int, float))
        assert isinstance(self.scrollbar_shadow_offset, (int, float))
        assert isinstance(self.scrollbar_slider_pad, (int, float))
        assert isinstance(self.scrollbar_thick, (int, float))
        assert isinstance(self.title_floating, bool)
        assert isinstance(self.title_font, str)
        assert isinstance(self.title_font_size, int)
        assert isinstance(self.title_shadow_offset, (int, float))
        assert isinstance(self.title_updates_pygame_display, bool)
        assert isinstance(self.widget_border_width, int)
        assert isinstance(self.widget_font, str)
        assert isinstance(self.widget_font_size, int)
        assert isinstance(self.widget_padding, (int, float, tuple, list))
        assert isinstance(self.widget_selection_effect, _widgets.core.Selection)
        assert isinstance(self.widget_shadow_offset, (int, float))

        # Format colors, this converts all color lists to tuples automatically
        self.background_color = self._format_opacity(self.background_color)
        self.cursor_color = self._format_opacity(self.cursor_color)
        self.cursor_selection_color = self._format_opacity(self.cursor_selection_color)
        self.focus_background_color = self._format_opacity(self.focus_background_color)
        self.readonly_color = self._format_opacity(self.readonly_color)
        self.readonly_selected_color = self._format_opacity(self.readonly_selected_color)
        self.scrollbar_color = self._format_opacity(self.scrollbar_color)
        self.scrollbar_shadow_color = self._format_opacity(self.scrollbar_shadow_color)
        self.scrollbar_slider_color = self._format_opacity(self.scrollbar_slider_color)
        self.selection_color = self._format_opacity(self.selection_color)
        self.surface_clear_color = self._format_opacity(self.surface_clear_color)
        self.title_background_color = self._format_opacity(self.title_background_color)
        self.widget_border_color = self._format_opacity(self.widget_border_color)
        self.title_font_color = self._format_opacity(self.title_font_color)
        self.title_shadow_color = self._format_opacity(self.title_shadow_color)
        self.widget_background_color = self._format_opacity(self.widget_background_color)
        self.widget_font_background_color = self._format_opacity(self.widget_font_background_color)
        self.widget_font_color = self._format_opacity(self.widget_font_color)

        # List to tuple
        self.scrollarea_outer_margin = self._vec_to_tuple(self.scrollarea_outer_margin, 2)
        self.title_offset = self._vec_to_tuple(self.title_offset, 2)
        self.widget_background_inflate = self._vec_to_tuple(self.widget_background_inflate, 2)
        self.widget_border_inflate = self._vec_to_tuple(self.widget_border_inflate, 2)
        self.widget_margin = self._vec_to_tuple(self.widget_margin, 2)
        if isinstance(self.widget_padding, (tuple, list)):
            self.widget_padding = self._vec_to_tuple(self.widget_padding)
            assert 2 <= len(self.widget_padding) <= 4, 'widget padding tuple length must be 2, 3 or 4'
            for p in self.widget_padding:
                assert p >= 0, 'all padding elements must be equal or greater than zero'
        else:
            assert self.widget_padding >= 0, 'padding cannot be a negative number'
        self.widget_offset = self._vec_to_tuple(self.widget_offset, 2)

        # Check sizes
        assert self.scrollarea_outer_margin[0] >= 0 and self.scrollarea_outer_margin[1] >= 0, \
            'scroll area outer margin must be equal or greater than zero in both axis'
        assert self.widget_offset[0] >= 0 and self.widget_offset[1] >= 0, \
            'widget offset must be equal or greater than zero'
        assert self.widget_border_inflate[0] >= 0 and self.widget_border_inflate[1] >= 0, \
            'widget border inflate must be equal or greater than zero in both axis'

        assert self.cursor_switch_ms > 0, 'cursor switch ms must be greater than zero'
        assert self.fps >= 0, 'fps must be equal or greater than zero'
        assert self.scrollbar_shadow_offset > 0, 'scrollbar shadow offset must be greater than zero'
        assert self.scrollbar_slider_pad >= 0, 'slider pad must be equal or greater than zero'
        assert self.scrollbar_thick > 0, 'scrollbar thickness must be greater than zero'
        assert self.title_font_size > 0, 'title font size must be greater than zero'
        assert self.widget_font_size > 0, 'widget font size must be greater than zero'
        assert self.widget_shadow_offset > 0, 'widget shadow offset must be greater than zero'

        # Configs
        self.widget_selection_effect.set_color(self.selection_color)

        # Color asserts
        assert self.focus_background_color[3] != 0, \
            'focus background color cannot be fully transparent, suggested opacity between 1 and 255'

        return self
Beispiel #8
0
    def __init__(
            self,
            title: Any,
            progressbar_id: str = '',
            default: NumberType = 0,
            width: int = 150,
            onselect: CallbackType = None,
            box_background_color: ColorInputType = (255, 255, 255),
            box_border_color: ColorInputType = (0, 0, 0),
            box_border_width: int = 1,
            box_margin: Tuple2IntType = (25, 0),
            box_progress_color: ColorInputType = (0, 255, 0),
            box_progress_padding: PaddingType = (1, 1),
            progress_text_align: str = ALIGN_CENTER,
            progress_text_enabled: bool = True,
            progress_text_font: Optional[FontType] = None,
            progress_text_font_color: ColorInputType = (0, 0, 0),
            progress_text_font_hfactor: float = 0.8,
            progress_text_format: ProgressBarTextFormatType = lambda x: str(round(x, 1)),
            progress_text_margin: Tuple2IntType = (0, 0),
            progress_text_placeholder: str = '{0} %',
            *args,
            **kwargs
    ) -> None:
        super(ProgressBar, self).__init__(
            args=args,
            kwargs=kwargs,
            onselect=onselect,
            title=title,
            widget_id=progressbar_id
        )

        # Check the value
        assert isinstance(default, NumberInstance)
        assert 0 <= default <= 100, 'default value must range from 0 to 100'

        # Check fonts
        if progress_text_font is not None:
            assert_font(progress_text_font)
        assert isinstance(progress_text_font_hfactor, NumberInstance)
        assert progress_text_font_hfactor > 0, \
            'progress text font height factor must be greater than zero'

        # Check colors
        box_background_color = assert_color(box_background_color)
        box_border_color = assert_color(box_border_color)
        box_progress_color = assert_color(box_progress_color)
        progress_text_font_color = assert_color(progress_text_font_color)

        # Check dimensions and sizes
        assert isinstance(box_border_width, int)
        assert box_border_width >= 0, \
            'box border width must be equal or greater than zero'
        assert_vector(box_margin, 2, int)
        assert_vector(progress_text_margin, 2, int)
        assert isinstance(width, int)
        assert width > 0, 'width must be greater than zero'
        box_progress_padding = parse_padding(box_progress_padding)
        self._box_progress_padding = box_progress_padding

        # Check progress text
        assert isinstance(progress_text_enabled, bool)
        assert is_callable(progress_text_format)
        assert isinstance(progress_text_format(0), str)
        assert isinstance(progress_text_placeholder, str)
        assert_alignment(progress_text_align)

        # Store properties
        self._default_value = default
        self._box_background_color = box_background_color
        self._box_border_color = box_border_color
        self._box_border_width = box_border_width
        self._box_margin = box_margin
        self._box_progress_color = box_progress_color
        self._progress = default
        self._progress_text_align = progress_text_align
        self._progress_text_enabled = progress_text_enabled
        self._progress_text_font = progress_text_font
        self._progress_text_font_color = progress_text_font_color
        self._progress_text_font_height = 0
        self._progress_text_font_height_factor = progress_text_font_hfactor
        self._progress_text_format = progress_text_format
        self._progress_text_margin = progress_text_margin
        self._progress_text_placeholder = progress_text_placeholder
        self._width = width
Beispiel #9
0
    def pack(
        self,
        widget: Union['Widget', List['Widget'], Tuple['Widget', ...]],
        alignment: str = _locals.ALIGN_LEFT,
        vertical_position: str = _locals.POSITION_NORTH,
        margin: Vector2NumberType = (0, 0)
    ) -> Union['Widget', List['Widget'], Tuple['Widget', ...], Any]:
        """
        Packs widget in the frame line. To pack a widget it has to be already
        appended to Menu, and the Menu must be the same as the frame.

        Packing is added to the same line, for example if three LEFT widgets are added:

            .. code-block:: python

                <frame horizontal>
                frame.pack(W1, alignment=ALIGN_LEFT, vertical_position=POSITION_NORTH)
                frame.pack(W2, alignment=ALIGN_LEFT, vertical_position=POSITION_CENTER)
                frame.pack(W3, alignment=ALIGN_LEFT, vertical_position=POSITION_SOUTH)

                ----------------
                |W1            |
                |   W2         |
                |      W3      |
                ----------------

        Another example:

            .. code-block:: python

                <frame horizontal>
                frame.pack(W1, alignment=ALIGN_LEFT)
                frame.pack(W2, alignment=ALIGN_CENTER)
                frame.pack(W3, alignment=ALIGN_RIGHT)

                ----------------
                |W1    W2    W3|
                ----------------

            .. code-block:: python

                <frame vertical>
                frame.pack(W1, alignment=ALIGN_LEFT)
                frame.pack(W2, alignment=ALIGN_CENTER)
                frame.pack(W3, alignment=ALIGN_RIGHT)

                --------
                |W1    |
                |  W2  |
                |    W3|
                --------

        .. note::

            Frame does not consider previous widget margin. For such purpose, use
            ``margin`` pack parameter.

        .. note::

            It is recommended to force menu rendering after packing all widgets.

        .. note::

            Packing applies a virtual translation to the widget, previous translation
            is not modified.

        .. note::

            Widget floating is also considered within frames. If a widget is floating,
            it does not add any size to the respective positioning.

        :param widget: Widget to be packed
        :param alignment: Widget alignment
        :param vertical_position: Vertical position of the widget within frame. See :py:mod:`pygame_menu.locals`
        :param margin: (left, top) margin of added widget in px. It overrides the previous widget margin
        :return: Added widget references
        """
        assert self._menu is not None, \
            'frame menu must be set before packing widgets'
        if isinstance(widget, (tuple, list)):
            for w in widget:
                self.pack(widget=w,
                          alignment=alignment,
                          vertical_position=vertical_position)
            return widget
        assert isinstance(widget, Widget)
        if isinstance(widget, Frame):
            assert widget.get_menu() is not None, \
                '{0} menu cannot be None'.format(widget.get_class_id())
        assert widget.get_id() not in self._widgets.keys(), \
            '{0} already exists in {1}'.format(widget.get_class_id(), self.get_class_id())
        assert widget.get_menu() == self._menu or widget.get_menu() is None, \
            'widget menu to be added to frame must be in same menu as frame, or it can have any Menu instance'
        assert widget.get_frame() is None, \
            '{0} is already packed in {1}'.format(widget.get_class_id(), widget.get_frame().get_class_id())
        assert_alignment(alignment)
        assert vertical_position in (_locals.POSITION_NORTH, _locals.POSITION_CENTER, _locals.POSITION_SOUTH), \
            'vertical position must be NORTH, CENTER, or SOUTH'
        assert_vector(margin, 2)
        assert widget.configured, 'widget must be configured before packing'

        if widget.get_margin() != (0, 0) and self._pack_margin_warning:
            msg = '{0} margin should be (0, 0) if packed, but received {1}; {2}.pack() does not consider ' \
                  'previous widget margin. Set frame._pack_margin_warning=False to hide this warning' \
                  ''.format(widget.get_class_id(), widget.get_margin(), self.get_class_id())
            warnings.warn(msg)

        if isinstance(widget, Frame):
            widget.update_indices()

        widget.set_frame(self)
        widget.set_margin(*margin)
        if self._frame_scrollarea is not None:
            widget.set_scrollarea(self._frame_scrollarea)
            self._sort_menu_scrollable_frames()
        else:
            widget.set_scrollarea(self._scrollarea)
        self._widgets[widget.get_id()] = widget
        self._widgets_props[widget.get_id()] = (alignment, vertical_position)

        # Sort widgets to keep selection order
        menu_widgets = self._menu._widgets
        if widget.get_menu() is not None and widget in menu_widgets:
            self._menu._validate_frame_widgetmove = False
            widgets_list = list(self._widgets.values())

            # Move frame to last
            if len(self._widgets) > 1:
                wlast = widgets_list[-2]  # -1 is the last added
                for i in range(2, len(self._widgets)):
                    if wlast.get_menu() is None and len(self._widgets) > 2:
                        wlast = widgets_list[-(i + 1)]
                    else:
                        break

                # Check for last if wlast is frame
                while True:
                    if not (isinstance(wlast, Frame) and wlast.get_indices() !=
                            (-1, -1)) or wlast.get_menu() is None:
                        break
                    wlast = menu_widgets[wlast.last_index]

                if wlast.get_menu() == self._menu:
                    self._menu.move_widget_index(self, wlast, render=False)

            # Swap
            self._menu.move_widget_index(widget, self, render=False)
            if isinstance(widget, Frame):
                reverse = menu_widgets.index(widget) == len(menu_widgets) - 1
                widgs = widget.get_widgets(unpack_subframes_include_frame=True,
                                           reverse=reverse)
                for w in widgs:
                    if w.get_menu() is None:
                        continue
                    self._menu.move_widget_index(w, self, render=False)
                if len(widgs) >= 1:
                    swap_target = widgs[-1]
                    if not reverse:
                        swap_target = widgs[0]
                    menu_widgets.remove(widget)
                    menu_widgets.insert(menu_widgets.index(swap_target),
                                        widget)

            # Move widget to first
            menu_widgets.remove(self)
            for k in range(len(widgets_list)):
                if widgets_list[k].get_menu() == self._menu:
                    menu_widgets.insert(menu_widgets.index(widgets_list[k]),
                                        self)
                    break
            self._menu._validate_frame_widgetmove = True

            # Update control widget
            if self._control_widget is None:
                self._control_widget = widget
                self._control_widget_last_pos = self._control_widget.get_position(
                )

        if isinstance(widget, Frame):
            self._has_frames = True

        # Update menu selected widget
        self._menu.move_widget_index(None, update_selected_index=True)

        # Render is mandatory as it modifies row/column layout
        try:
            self.update_position()
            self._menu._render()
        except _FrameSizeException:
            self.unpack(widget)
            raise

        # Request scroll if widget is selected
        if widget.is_selected():
            widget.scroll_to_widget()
            widget.scroll_to_widget()

        return widget
Beispiel #10
0
    def pack(
        self,
        widget: Union['Widget', List['Widget'], Tuple['Widget', ...]],
        alignment: str = _locals.ALIGN_LEFT,
        vertical_position: PackPositionTypes = _locals.POSITION_NORTH,
        margin: Vector2NumberType = (0, 0)
    ) -> Union['Widget', List['Widget'], Tuple['Widget', ...]]:
        """
        Packs widget in the frame line. To pack a widget it has to be already
        appended to Menu, and the Menu must be the same as the frame.

        Packing is added to the same line, for example if three LEFT widgets are added:

            .. code-block:: python

                <frame horizontal>
                frame.pack(W1, alignment=ALIGN_LEFT, vertical_position=POSITION_NORTH)
                frame.pack(W2, alignment=ALIGN_LEFT, vertical_position=POSITION_CENTER)
                frame.pack(W3, alignment=ALIGN_LEFT, vertical_position=POSITION_SOUTH)

                ----------------
                |W1            |
                |   W2         |
                |      W3      |
                ----------------

        Another example:

            .. code-block:: python

                <frame horizontal>
                frame.pack(W1, alignment=ALIGN_LEFT)
                frame.pack(W2, alignment=ALIGN_CENTER)
                frame.pack(W3, alignment=ALIGN_RIGHT)

                ----------------
                |W1    W2    W3|
                ----------------

            .. code-block:: python

                <frame vertical>
                frame.pack(W1, alignment=ALIGN_LEFT)
                frame.pack(W2, alignment=ALIGN_CENTER)
                frame.pack(W3, alignment=ALIGN_RIGHT)

                --------
                |W1    |
                |  W2  |
                |    W3|
                --------

        .. note::

            It is recommended to force menu rendering after packing all widgets.

        :param widget: Widget to be packed
        :param alignment: Widget alignment
        :param vertical_position: Vertical position of the widget
        :param margin: *(left, top)* margin of added widget in px. It overrides the previous widget margin
        :return: Added widget reference
        """
        menu = self.get_menu()
        assert menu is not None, \
            'menu must be set before packing widgets'
        if isinstance(widget, (list, tuple)):
            for w in widget:
                self.pack(widget=w,
                          alignment=alignment,
                          vertical_position=vertical_position)
            return widget
        assert isinstance(widget, Widget)
        assert widget.get_id() not in self._widgets.keys(), \
            'widget already in frame'
        assert widget.get_menu() == menu, \
            'widget menu to be added to frame must be in same menu as frame'
        assert widget.get_frame() is None, \
            'widget already is in another frame'
        assert_alignment(alignment)
        assert vertical_position in (_locals.POSITION_NORTH, _locals.POSITION_CENTER, _locals.POSITION_SOUTH), \
            'vertical position must be NORTH, CENTER, or SOUTH'
        assert widget._translate[0] == 0 and widget._translate[1] == 0, \
            'widget cannot have a previous translation if appended. Frame overrides translation'
        assert_vector(margin, 2)

        widget.set_frame(self)
        widget.set_float()
        widget.set_margin(*margin)
        self._widgets[widget.get_id()] = (widget, alignment, vertical_position)

        # Notify menu and sort widgets to keep selection order
        # noinspection PyProtectedMember
        menu_widgets = menu._widgets

        frame_index = menu_widgets.index(self)
        widgt_index = menu_widgets.index(widget)
        assert widgt_index > frame_index, 'widget cannot be appended before frame'
        menu_widgets.pop(widgt_index)
        menu_widgets.insert(frame_index, widget)
        if widget.is_selected():
            widget.select(False)
            menu.select_widget(widget)

        if self._control_widget is None:
            self._control_widget = widget
            self._control_widget_last_pos = self._control_widget.get_position()

        # Render is mandatory as it modifies row/column layout
        try:
            menu.render()
        except _FrameSizeException:
            self.unpack(widget)
            raise
        self.update_indices()

        return widget