예제 #1
0
    def set_shadow(self, enabled=True, color=None, position=None, offset=None):
        """
        Show text shadow.

        :param enabled: Shadow is enabled or not
        :type enabled: bool
        :param color: Shadow color
        :type color: list, None
        :param position: Shadow position
        :type position: str, None
        :param offset: Shadow offset
        :type offset: int, float, None
        :return: None
        """
        self._shadow = enabled
        if color is not None:
            assert_color(color)
            self._shadow_color = color
        if position is not None:
            assert_position(position)
            self._shadow_position = position
        if offset is not None:
            assert isinstance(offset, (int, float))
            if offset <= 0:
                raise ValueError('shadow offset must be greater than zero')
            self._shadow_offset = offset

        # Create shadow tuple position
        self._create_shadow_tuple()
예제 #2
0
파일: themes.py 프로젝트: Kollaider/snake
    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
예제 #3
0
    def set_drawing_position(self, position: str) -> 'BaseImage':
        """
        Set the image position.

        .. note::

            See :py:mod:`pygame_menu.locals` for valid ``position`` values.

        :param position: Image position
        :return: Self reference
        """
        assert_position(position)
        self._drawing_position = position
        return self
예제 #4
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)
예제 #5
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
예제 #6
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
예제 #7
0
    def __init__(self,
                 area_width,
                 area_height,
                 area_color=None,
                 extend_x=0,
                 extend_y=0,
                 scrollbar_color=(235, 235, 235),
                 scrollbar_slider_color=(200, 200, 200),
                 scrollbar_slider_pad=0,
                 scrollbar_thick=20,
                 scrollbars=(_locals.POSITION_SOUTH, _locals.POSITION_EAST),
                 shadow=False,
                 shadow_color=(0, 0, 0),
                 shadow_offset=2,
                 shadow_position=_locals.POSITION_SOUTHEAST,
                 world=None,
                 ):
        assert isinstance(area_width, (int, float))
        assert isinstance(area_height, (int, float))
        assert isinstance(scrollbar_slider_pad, (int, float))
        assert isinstance(scrollbar_thick, (int, float))
        assert isinstance(shadow, bool)
        assert isinstance(shadow_offset, (int, float))

        assert_color(scrollbar_color)
        assert_color(scrollbar_slider_color)
        assert_color(shadow_color)
        assert_position(shadow_position)

        assert area_width > 0 and area_height > 0, \
            'area size must be greater than zero'

        self._rect = pygame.Rect(0.0, 0.0, area_width, area_height)
        self._world = world  # type: pygame.Surface
        self._scrollbars = []
        self._scrollbar_positions = tuple(set(scrollbars))  # Ensure unique
        self._scrollbar_thick = scrollbar_thick
        self._bg_surface = None

        self._extend_x = extend_x
        self._extend_y = extend_y

        if area_color:
            self._bg_surface = make_surface(width=area_width + extend_x,
                                            height=area_height + self._extend_y)
            if isinstance(area_color, _baseimage.BaseImage):
                area_color.draw(surface=self._bg_surface, area=self._bg_surface.get_rect())
            else:
                self._bg_surface.fill(area_color)

        self._view_rect = self.get_view_rect()

        for pos in self._scrollbar_positions:  # type:str
            assert_position(pos)
            if pos == _locals.POSITION_EAST or pos == _locals.POSITION_WEST:
                sbar = ScrollBar(self._view_rect.height, (0, max(1, self.get_hidden_height())),
                                 orientation=_locals.ORIENTATION_VERTICAL,
                                 slider_pad=scrollbar_slider_pad,
                                 slider_color=scrollbar_slider_color,
                                 page_ctrl_thick=scrollbar_thick,
                                 page_ctrl_color=scrollbar_color,
                                 onchange=self._on_vertical_scroll)
            else:
                sbar = ScrollBar(self._view_rect.width, (0, max(1, self.get_hidden_width())),
                                 slider_pad=scrollbar_slider_pad,
                                 slider_color=scrollbar_slider_color,
                                 page_ctrl_thick=scrollbar_thick,
                                 page_ctrl_color=scrollbar_color,
                                 onchange=self._on_horizontal_scroll)
            sbar.set_shadow(enabled=shadow,
                            color=shadow_color,
                            position=shadow_position,
                            offset=shadow_offset)
            sbar.set_controls(joystick=False)

            self._scrollbars.append(sbar)

        self._apply_size_changes()
예제 #8
0
    def __init__(
            self,
            area_width: int,
            area_height: int,
            area_color: Optional[Union[ColorInputType, 'pygame_menu.BaseImage']] = None,
            extend_x: int = 0,
            extend_y: int = 0,
            menubar: Optional['pygame_menu.widgets.MenuBar'] = None,
            parent_scrollarea: Optional['ScrollArea'] = None,
            scrollarea_id: str = '',
            scrollbar_color: ColorInputType = (235, 235, 235),
            scrollbar_cursor: CursorInputType = None,
            scrollbar_slider_color: ColorInputType = (200, 200, 200),
            scrollbar_slider_hover_color: ColorInputType = (180, 180, 180),
            scrollbar_slider_pad: NumberType = 0,
            scrollbar_thick: int = 20,
            scrollbars: StringVector = DEFAULT_SCROLLBARS,
            shadow: bool = False,
            shadow_color: ColorInputType = (0, 0, 0),
            shadow_offset: int = 2,
            shadow_position: str = POSITION_SOUTHEAST,
            world: Optional['pygame.Surface'] = None
    ) -> None:
        super(ScrollArea, self).__init__(object_id=scrollarea_id)

        assert isinstance(area_height, int)
        assert isinstance(area_width, int)
        assert isinstance(extend_x, int)
        assert isinstance(extend_y, int)
        assert isinstance(scrollbar_slider_pad, NumberInstance)
        assert isinstance(scrollbar_thick, int)
        assert isinstance(shadow, bool)
        assert isinstance(shadow_offset, int)
        assert isinstance(world, (pygame.Surface, type(None)))

        if area_color is not None and not isinstance(area_color, pygame_menu.BaseImage):
            area_color = assert_color(area_color)

        scrollbar_color = assert_color(scrollbar_color)
        scrollbar_slider_color = assert_color(scrollbar_slider_color)
        shadow_color = assert_color(shadow_color)

        assert_position(shadow_position)

        assert area_width > 0 and area_height > 0, \
            'area size must be greater than zero'

        assert isinstance(scrollbars, (str, VectorInstance))
        unique_scrolls = []
        if isinstance(scrollbars, str):
            unique_scrolls.append(scrollbars)
        else:
            for s in scrollbars:
                if s not in unique_scrolls:
                    unique_scrolls.append(s)

        self._area_color = area_color
        self._bg_surface = None
        self._bg_surface = None
        self._decorator = Decorator(self)
        self._rect = pygame.Rect(0, 0, int(area_width), int(area_height))
        self._scrollbar_positions = tuple(unique_scrolls)  # Ensure unique
        self._scrollbar_thick = scrollbar_thick
        self._scrollbars = []
        self._translate = (0, 0)
        self._world = world

        self._extend_x = extend_x
        self._extend_y = extend_y
        self._menubar = menubar

        self.set_parent_scrollarea(parent_scrollarea)
        self._view_rect = self.get_view_rect()

        for pos in self._scrollbar_positions:
            assert_position(pos)

            if pos == POSITION_EAST or pos == POSITION_WEST:
                sbar = ScrollBar(
                    length=self._view_rect.height,
                    onchange=self._on_vertical_scroll,
                    orientation=ORIENTATION_VERTICAL,
                    page_ctrl_color=scrollbar_color,
                    page_ctrl_thick=scrollbar_thick,
                    slider_color=scrollbar_slider_color,
                    slider_hover_color=scrollbar_slider_hover_color,
                    slider_pad=scrollbar_slider_pad,
                    values_range=(0, max(1, self.get_hidden_height()))
                )
            else:
                sbar = ScrollBar(
                    length=self._view_rect.width,
                    onchange=self._on_horizontal_scroll,
                    page_ctrl_color=scrollbar_color,
                    page_ctrl_thick=scrollbar_thick,
                    slider_color=scrollbar_slider_color,
                    slider_hover_color=scrollbar_slider_hover_color,
                    slider_pad=scrollbar_slider_pad,
                    values_range=(0, max(1, self.get_hidden_width()))
                )
            sbar.set_shadow(
                enabled=shadow,
                color=shadow_color,
                position=shadow_position,
                offset=shadow_offset
            )
            sbar.set_controls(joystick=False)
            sbar.set_cursor(cursor=scrollbar_cursor)
            sbar.set_scrollarea(self)
            sbar.configured = True
            sbar.hide()

            self._scrollbars.append(sbar)

        self._apply_size_changes()

        # Menu reference
        self._menu = None
예제 #9
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
예제 #10
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
예제 #11
0
    def __init__(self,
                 area_width: int,
                 area_height: int,
                 area_color: Optional[Union[ColorType, '_baseimage.BaseImage']] = None,
                 extend_x: int = 0,
                 extend_y: int = 0,
                 menubar: Optional['MenuBar'] = None,
                 scrollbar_color: ColorType = (235, 235, 235),
                 scrollbar_slider_color: ColorType = (200, 200, 200),
                 scrollbar_slider_pad: NumberType = 0,
                 scrollbar_thick: NumberType = 20,
                 scrollbars: Union[str, Tuple[str, ...]] = get_scrollbars_from_position(_locals.POSITION_SOUTHEAST),
                 shadow: bool = False,
                 shadow_color: ColorType = (0, 0, 0),
                 shadow_offset: NumberType = 2,
                 shadow_position: str = _locals.POSITION_SOUTHEAST,
                 world: Optional['pygame.Surface'] = None
                 ) -> None:
        assert isinstance(area_width, int)
        assert isinstance(area_height, int)
        assert isinstance(scrollbar_slider_pad, (int, float))
        assert isinstance(scrollbar_thick, (int, float))
        assert isinstance(shadow, bool)
        assert isinstance(shadow_offset, (int, float))
        assert isinstance(world, (pygame.Surface, type(None)))

        assert_color(scrollbar_color)
        assert_color(scrollbar_slider_color)
        assert_color(shadow_color)
        assert_position(shadow_position)

        assert area_width > 0 and area_height > 0, \
            'area size must be greater than zero'

        self._bg_surface = None
        self._decorator = Decorator(self)
        self._rect = pygame.Rect(0, 0, int(area_width), int(area_height))
        self._scrollbar_positions = tuple(set(scrollbars))  # Ensure unique
        self._scrollbar_thick = scrollbar_thick
        self._scrollbars = []
        self._world = world

        self._extend_x = extend_x
        self._extend_y = extend_y
        self._menubar = menubar

        if area_color:
            self._bg_surface = make_surface(width=area_width + extend_x,
                                            height=area_height + self._extend_y)
            if isinstance(area_color, _baseimage.BaseImage):
                area_color.draw(surface=self._bg_surface, area=self._bg_surface.get_rect())
            else:
                self._bg_surface.fill(area_color)

        self._view_rect = self.get_view_rect()

        for pos in self._scrollbar_positions:
            assert_position(pos)

            if pos == _locals.POSITION_EAST or pos == _locals.POSITION_WEST:
                sbar = ScrollBar(
                    length=self._view_rect.height,
                    values_range=(0, max(1, self.get_hidden_height())),
                    orientation=_locals.ORIENTATION_VERTICAL,
                    slider_pad=scrollbar_slider_pad,
                    slider_color=scrollbar_slider_color,
                    page_ctrl_thick=scrollbar_thick,
                    page_ctrl_color=scrollbar_color,
                    onchange=self._on_vertical_scroll
                )
            else:
                sbar = ScrollBar(
                    length=self._view_rect.width,
                    values_range=(0, max(1, self.get_hidden_width())),
                    slider_pad=scrollbar_slider_pad,
                    slider_color=scrollbar_slider_color,
                    page_ctrl_thick=scrollbar_thick,
                    page_ctrl_color=scrollbar_color,
                    onchange=self._on_horizontal_scroll
                )
            sbar.set_shadow(
                enabled=shadow,
                color=shadow_color,
                position=shadow_position,
                offset=shadow_offset
            )
            sbar.set_controls(joystick=False)

            self._scrollbars.append(sbar)

        self._apply_size_changes()

        # Menu reference
        self._menu = None
예제 #12
0
    def create_rect(self, width: int, height: int) -> None:
        """
        Create rect object.

        :param width: Area width
        :param height: Area height
        """
        assert isinstance(width, int)
        assert isinstance(height, int)
        self._rect = pygame.Rect(0, 0, int(width), int(height))
        self._scrollbars = []
        self._view_rect = self.get_view_rect()

        # Unpack properties
        (scrollbar_color, scrollbar_thick, scrollbar_slider_color,
         scrollbar_slider_hover_color, scrollbar_slider_pad, scrollbar_cursor,
         shadow, shadow_color, shadow_position, shadow_offset,
         controls_joystick, controls_mouse, controls_touchscreen,
         controls_keyboard) = self._scrollbars_props

        for pos in self._scrollbar_positions:
            assert_position(pos)

            if pos == POSITION_EAST or pos == POSITION_WEST:
                sbar = ScrollBar(
                    length=self._view_rect.height,
                    onchange=self._on_vertical_scroll,
                    orientation=ORIENTATION_VERTICAL,
                    page_ctrl_color=scrollbar_color,
                    page_ctrl_thick=scrollbar_thick,
                    slider_color=scrollbar_slider_color,
                    slider_hover_color=scrollbar_slider_hover_color,
                    slider_pad=scrollbar_slider_pad,
                    values_range=(0, max(1, self.get_hidden_height())))

            else:
                sbar = ScrollBar(
                    length=self._view_rect.width,
                    onchange=self._on_horizontal_scroll,
                    page_ctrl_color=scrollbar_color,
                    page_ctrl_thick=scrollbar_thick,
                    slider_color=scrollbar_slider_color,
                    slider_hover_color=scrollbar_slider_hover_color,
                    slider_pad=scrollbar_slider_pad,
                    values_range=(0, max(1, self.get_hidden_width())))

            sbar.set_shadow(enabled=shadow,
                            color=shadow_color,
                            position=shadow_position,
                            offset=shadow_offset)
            sbar.set_controls(joystick=controls_joystick,
                              mouse=controls_mouse,
                              touchscreen=controls_touchscreen,
                              keyboard=controls_keyboard)
            sbar.set_cursor(cursor=scrollbar_cursor)
            sbar.set_scrollarea(self)
            sbar.configured = True
            sbar.hide()

            self._scrollbars.append(sbar)

        self._apply_size_changes()
예제 #13
0
    def __init__(self,
                 area_width: int,
                 area_height: int,
                 area_color: Optional[Union[ColorInputType,
                                            'pygame_menu.BaseImage']] = None,
                 border_color: Optional[Union[ColorInputType,
                                              'pygame_menu.BaseImage']] = None,
                 border_width: int = 0,
                 controls_joystick: bool = True,
                 controls_keyboard: bool = True,
                 controls_mouse: bool = True,
                 controls_touchscreen: bool = True,
                 extend_x: int = 0,
                 extend_y: int = 0,
                 menubar: Optional['pygame_menu.widgets.MenuBar'] = None,
                 parent_scrollarea: Optional['ScrollArea'] = None,
                 scrollarea_id: str = '',
                 scrollbar_color: ColorInputType = (235, 235, 235),
                 scrollbar_cursor: CursorInputType = None,
                 scrollbar_slider_color: ColorInputType = (200, 200, 200),
                 scrollbar_slider_hover_color: ColorInputType = (180, 180,
                                                                 180),
                 scrollbar_slider_pad: NumberType = 0,
                 scrollbar_thick: int = 20,
                 scrollbars: StringVector = DEFAULT_SCROLLBARS,
                 shadow: bool = False,
                 shadow_color: ColorInputType = (0, 0, 0),
                 shadow_offset: int = 2,
                 shadow_position: str = POSITION_SOUTHEAST,
                 world: Optional['pygame.Surface'] = None) -> None:
        super(ScrollArea, self).__init__(object_id=scrollarea_id)

        assert isinstance(area_height, int)
        assert isinstance(area_width, int)
        assert isinstance(border_width, int)
        assert isinstance(controls_joystick, bool)
        assert isinstance(controls_keyboard, bool)
        assert isinstance(controls_mouse, bool)
        assert isinstance(controls_touchscreen, bool)
        assert isinstance(extend_x, int)
        assert isinstance(extend_y, int)
        assert isinstance(scrollbar_slider_pad, NumberInstance)
        assert isinstance(scrollbar_thick, int)
        assert isinstance(shadow, bool)
        assert isinstance(shadow_offset, int)
        assert isinstance(world, (pygame.Surface, type(None)))

        if area_color is not None and not isinstance(area_color,
                                                     pygame_menu.BaseImage):
            area_color = assert_color(area_color)
        if border_color is not None and not isinstance(border_color,
                                                       pygame_menu.BaseImage):
            border_color = assert_color(border_color)

        # Create tiles
        if isinstance(border_color, pygame_menu.BaseImage):
            iw, ih = border_color.get_size()
            tw, th = iw // 3, ih // 3
            self._border_tiles_size = tw, th
            self._border_tiles = [
                border_color.subsurface((x, y, tw, th))
                for x, y in product(range(0, iw, tw), range(0, ih, th))
            ]

        scrollbar_color = assert_color(scrollbar_color)
        scrollbar_slider_color = assert_color(scrollbar_slider_color)
        shadow_color = assert_color(shadow_color)

        assert_position(shadow_position)

        assert area_width > 0 and area_height > 0, \
            'area size must be greater than zero'

        assert isinstance(scrollbars, (str, VectorInstance))
        unique_scrolls = []
        if isinstance(scrollbars, str):
            unique_scrolls.append(scrollbars)
        else:
            for s in scrollbars:
                if s not in unique_scrolls:
                    unique_scrolls.append(s)

        # Remove none position
        if '' in unique_scrolls:
            unique_scrolls.pop(unique_scrolls.index(''))

        self._area_color = area_color
        self._border_color = border_color
        self._border_width = border_width
        self._bg_surface = None
        self._decorator = Decorator(self)
        self._scrollbar_positions = tuple(unique_scrolls)  # Ensure unique
        self._translate = (0, 0)
        self._world = world

        self._extend_x = extend_x
        self._extend_y = extend_y
        self._menubar = menubar

        self._scrollbars_props = (scrollbar_color, scrollbar_thick,
                                  scrollbar_slider_color,
                                  scrollbar_slider_hover_color,
                                  scrollbar_slider_pad, scrollbar_cursor,
                                  shadow, shadow_color, shadow_position,
                                  shadow_offset, controls_joystick,
                                  controls_mouse, controls_touchscreen,
                                  controls_keyboard)
        self.set_parent_scrollarea(parent_scrollarea)
        self.create_rect(area_width, area_height)

        # Menu reference
        self._menu = None