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()
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
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
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)
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
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
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()
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
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
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
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
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()
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