diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..b5cf2dfb --- /dev/null +++ b/.editorconfig @@ -0,0 +1,19 @@ +# EditorConfig is awesome: https://EditorConfig.org + +# Top-most EditorConfig file +root = true + +# Unix-style newlines +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = false + +# Configure languages +[*.py] +indent_size = 4 +indent_style = space + +[{*.json, *.yml}] +indent_size = 2 +indent_style = space \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 47ffdc4f..3f150556 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -9,6 +9,7 @@ assignees: '' **Environment information** Describe your environment information, such as: + - OS: win/linux - python version: v3.x - pygame version: v2.x diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8a3a027f..127253c3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,7 +17,7 @@ jobs: uses: ppizarror/workflow-actions/.github/workflows/test_python.yml@master strategy: matrix: - python: [3.7, 3.8, 3.9, '3.10'] + python: [ 3.7, 3.8, 3.9, '3.10' ] with: env-vars: | SDL_AUDIODRIVER=disk diff --git a/README.rst b/README.rst index 8ed7178e..f96d12ae 100644 --- a/README.rst +++ b/README.rst @@ -1,4 +1,3 @@ - =========== pygame-menu =========== diff --git a/docs/_source/add_sounds.rst b/docs/_source/add_sounds.rst index a180955c..e481add1 100644 --- a/docs/_source/add_sounds.rst +++ b/docs/_source/add_sounds.rst @@ -1,4 +1,3 @@ - .. module:: pygame_menu.sound ============= diff --git a/docs/_source/add_widgets.rst b/docs/_source/add_widgets.rst index 85f16ab1..7a5eaf52 100644 --- a/docs/_source/add_widgets.rst +++ b/docs/_source/add_widgets.rst @@ -1,4 +1,3 @@ - ============== Adding widgets ============== diff --git a/docs/_source/add_widgets_manager.rst b/docs/_source/add_widgets_manager.rst index 5ac0025e..ca2f0afa 100644 --- a/docs/_source/add_widgets_manager.rst +++ b/docs/_source/add_widgets_manager.rst @@ -1,4 +1,3 @@ - :orphan: .. module:: pygame_menu._widgetmanager diff --git a/docs/_source/advanced.rst b/docs/_source/advanced.rst index 8e03d673..ed66e73d 100644 --- a/docs/_source/advanced.rst +++ b/docs/_source/advanced.rst @@ -1,4 +1,3 @@ - ==================== Package organization ==================== diff --git a/docs/_source/advanced_controller.rst b/docs/_source/advanced_controller.rst index e894e2ef..10377358 100644 --- a/docs/_source/advanced_controller.rst +++ b/docs/_source/advanced_controller.rst @@ -1,4 +1,3 @@ - ==================== Configure controller ==================== diff --git a/docs/_source/advanced_selection.rst b/docs/_source/advanced_selection.rst index 75c66b5a..49f2e557 100644 --- a/docs/_source/advanced_selection.rst +++ b/docs/_source/advanced_selection.rst @@ -1,4 +1,3 @@ - :orphan: ======================== diff --git a/docs/_source/advanced_widget.rst b/docs/_source/advanced_widget.rst index c276e014..2794a66a 100644 --- a/docs/_source/advanced_widget.rst +++ b/docs/_source/advanced_widget.rst @@ -1,4 +1,3 @@ - :orphan: .. module:: pygame_menu.widgets.core.widget diff --git a/docs/_source/base.rst b/docs/_source/base.rst index f7b51d13..a56118d3 100644 --- a/docs/_source/base.rst +++ b/docs/_source/base.rst @@ -1,4 +1,3 @@ - :orphan: .. module:: pygame_menu._base diff --git a/docs/_source/baseimage.rst b/docs/_source/baseimage.rst index 5b79ed2b..c6745e06 100644 --- a/docs/_source/baseimage.rst +++ b/docs/_source/baseimage.rst @@ -1,4 +1,3 @@ - ========= BaseImage ========= diff --git a/docs/_source/contributors.rst b/docs/_source/contributors.rst index 64f1990b..5ff35bc7 100644 --- a/docs/_source/contributors.rst +++ b/docs/_source/contributors.rst @@ -1,4 +1,3 @@ - ============ Contributors ============ diff --git a/docs/_source/create_menu.rst b/docs/_source/create_menu.rst index bf509b03..a4833793 100644 --- a/docs/_source/create_menu.rst +++ b/docs/_source/create_menu.rst @@ -1,4 +1,3 @@ - .. module:: pygame_menu.menu ============== diff --git a/docs/_source/events.rst b/docs/_source/events.rst index ee2d67bd..14be729e 100644 --- a/docs/_source/events.rst +++ b/docs/_source/events.rst @@ -1,4 +1,3 @@ - :orphan: .. module:: pygame_menu.events diff --git a/docs/_source/gallery.rst b/docs/_source/gallery.rst index 84e410fe..7a47bbc3 100644 --- a/docs/_source/gallery.rst +++ b/docs/_source/gallery.rst @@ -1,4 +1,3 @@ - ================== Gallery / Examples ================== diff --git a/docs/_source/license.rst b/docs/_source/license.rst index 9bbd52b7..d801afd9 100644 --- a/docs/_source/license.rst +++ b/docs/_source/license.rst @@ -1,4 +1,3 @@ - ======= License ======= diff --git a/docs/_source/migration_guide_2_to_3.rst b/docs/_source/migration_guide_2_to_3.rst index f9dbd800..b8b59407 100644 --- a/docs/_source/migration_guide_2_to_3.rst +++ b/docs/_source/migration_guide_2_to_3.rst @@ -1,4 +1,3 @@ - ========================== Migration Guide - v2 to v3 ========================== diff --git a/docs/_source/migration_guide_3_to_4.rst b/docs/_source/migration_guide_3_to_4.rst index ba44e5a7..840e6c5b 100644 --- a/docs/_source/migration_guide_3_to_4.rst +++ b/docs/_source/migration_guide_3_to_4.rst @@ -1,4 +1,3 @@ - ========================== Migration Guide - v3 to v4 ========================== diff --git a/docs/_source/scrollarea.rst b/docs/_source/scrollarea.rst index e833eff0..1c6e0ba4 100644 --- a/docs/_source/scrollarea.rst +++ b/docs/_source/scrollarea.rst @@ -1,4 +1,3 @@ - .. module:: pygame_menu._scrollarea ========== diff --git a/docs/_source/themes.rst b/docs/_source/themes.rst index 57f96f1d..14ca686e 100644 --- a/docs/_source/themes.rst +++ b/docs/_source/themes.rst @@ -1,4 +1,3 @@ - .. module:: pygame_menu.themes =============== diff --git a/docs/_source/widgets_button.rst b/docs/_source/widgets_button.rst index 8d68fa91..f64b9805 100644 --- a/docs/_source/widgets_button.rst +++ b/docs/_source/widgets_button.rst @@ -1,4 +1,3 @@ - .. module:: pygame_menu.widgets.widget.button ====== diff --git a/docs/_source/widgets_colorinput.rst b/docs/_source/widgets_colorinput.rst index 72cd7d29..32a4ca34 100644 --- a/docs/_source/widgets_colorinput.rst +++ b/docs/_source/widgets_colorinput.rst @@ -1,4 +1,3 @@ - .. module:: pygame_menu.widgets.widget.colorinput ========== diff --git a/docs/_source/widgets_dropselect.rst b/docs/_source/widgets_dropselect.rst index 5b06869a..33693361 100644 --- a/docs/_source/widgets_dropselect.rst +++ b/docs/_source/widgets_dropselect.rst @@ -1,4 +1,3 @@ - .. module:: pygame_menu.widgets.widget.dropselect ========== diff --git a/docs/_source/widgets_dropselect_multiple.rst b/docs/_source/widgets_dropselect_multiple.rst index 0f0c02fa..24e74ca3 100644 --- a/docs/_source/widgets_dropselect_multiple.rst +++ b/docs/_source/widgets_dropselect_multiple.rst @@ -1,4 +1,3 @@ - .. module:: pygame_menu.widgets.widget.dropselect_multiple ================== diff --git a/docs/_source/widgets_frame.rst b/docs/_source/widgets_frame.rst index 3b6c6dab..5b156c2a 100644 --- a/docs/_source/widgets_frame.rst +++ b/docs/_source/widgets_frame.rst @@ -1,4 +1,3 @@ - .. module:: pygame_menu.widgets.widget.frame ===== diff --git a/docs/_source/widgets_hmargin.rst b/docs/_source/widgets_hmargin.rst index f6667707..fbe32c21 100644 --- a/docs/_source/widgets_hmargin.rst +++ b/docs/_source/widgets_hmargin.rst @@ -1,4 +1,3 @@ - .. module:: pygame_menu.widgets.widget.hmargin ======= diff --git a/docs/_source/widgets_image.rst b/docs/_source/widgets_image.rst index 840c4602..d0b63a70 100644 --- a/docs/_source/widgets_image.rst +++ b/docs/_source/widgets_image.rst @@ -1,4 +1,3 @@ - .. module:: pygame_menu.widgets.widget.image ====== diff --git a/docs/_source/widgets_label.rst b/docs/_source/widgets_label.rst index 0085ef8a..10c47bc2 100644 --- a/docs/_source/widgets_label.rst +++ b/docs/_source/widgets_label.rst @@ -1,4 +1,3 @@ - .. module:: pygame_menu.widgets.widget.label ===== diff --git a/docs/_source/widgets_menubar.rst b/docs/_source/widgets_menubar.rst index 30aed0f3..17b2d17d 100644 --- a/docs/_source/widgets_menubar.rst +++ b/docs/_source/widgets_menubar.rst @@ -1,4 +1,3 @@ - .. module:: pygame_menu.widgets.widget.menubar ======= diff --git a/docs/_source/widgets_menulink.rst b/docs/_source/widgets_menulink.rst index c351deac..134fcbce 100644 --- a/docs/_source/widgets_menulink.rst +++ b/docs/_source/widgets_menulink.rst @@ -1,4 +1,3 @@ - .. module:: pygame_menu.widgets.widget.menulink ======== diff --git a/docs/_source/widgets_none.rst b/docs/_source/widgets_none.rst index e95d4043..7a95af99 100644 --- a/docs/_source/widgets_none.rst +++ b/docs/_source/widgets_none.rst @@ -1,4 +1,3 @@ - .. module:: pygame_menu.widgets.widget.none ========== diff --git a/docs/_source/widgets_progressbar.rst b/docs/_source/widgets_progressbar.rst index 11f2d885..ba53001b 100644 --- a/docs/_source/widgets_progressbar.rst +++ b/docs/_source/widgets_progressbar.rst @@ -1,4 +1,3 @@ - .. module:: pygame_menu.widgets.widget.progressbar =========== diff --git a/docs/_source/widgets_rangeslider.rst b/docs/_source/widgets_rangeslider.rst index 808e1e37..91c8f12d 100644 --- a/docs/_source/widgets_rangeslider.rst +++ b/docs/_source/widgets_rangeslider.rst @@ -1,4 +1,3 @@ - .. module:: pygame_menu.widgets.widget.rangeslider =========== diff --git a/docs/_source/widgets_scrollbar.rst b/docs/_source/widgets_scrollbar.rst index 47c32f1d..f37b9255 100644 --- a/docs/_source/widgets_scrollbar.rst +++ b/docs/_source/widgets_scrollbar.rst @@ -1,4 +1,3 @@ - .. module:: pygame_menu.widgets.widget.scrollbar ========= diff --git a/docs/_source/widgets_selector.rst b/docs/_source/widgets_selector.rst index 4c4553fa..60c3a6c6 100644 --- a/docs/_source/widgets_selector.rst +++ b/docs/_source/widgets_selector.rst @@ -1,4 +1,3 @@ - .. module:: pygame_menu.widgets.widget.selector ======== diff --git a/docs/_source/widgets_surface.rst b/docs/_source/widgets_surface.rst index ee24b7a3..7d86513c 100644 --- a/docs/_source/widgets_surface.rst +++ b/docs/_source/widgets_surface.rst @@ -1,4 +1,3 @@ - .. module:: pygame_menu.widgets.widget.surface ============= diff --git a/docs/_source/widgets_table.rst b/docs/_source/widgets_table.rst index 2f7de2ca..2a9583a0 100644 --- a/docs/_source/widgets_table.rst +++ b/docs/_source/widgets_table.rst @@ -1,4 +1,3 @@ - .. module:: pygame_menu.widgets.widget.table ===== diff --git a/docs/_source/widgets_textinput.rst b/docs/_source/widgets_textinput.rst index 85b356ce..80b71f03 100644 --- a/docs/_source/widgets_textinput.rst +++ b/docs/_source/widgets_textinput.rst @@ -1,4 +1,3 @@ - .. module:: pygame_menu.widgets.widget.textinput ========= diff --git a/docs/_source/widgets_toggleswitch.rst b/docs/_source/widgets_toggleswitch.rst index c057ccb8..f3e99ba0 100644 --- a/docs/_source/widgets_toggleswitch.rst +++ b/docs/_source/widgets_toggleswitch.rst @@ -1,4 +1,3 @@ - .. module:: pygame_menu.widgets.widget.toggleswitch ============ diff --git a/docs/_source/widgets_vfill.rst b/docs/_source/widgets_vfill.rst index 5077585f..27a89ba5 100644 --- a/docs/_source/widgets_vfill.rst +++ b/docs/_source/widgets_vfill.rst @@ -1,4 +1,3 @@ - .. module:: pygame_menu.widgets.widget.vfill ===== diff --git a/docs/_source/widgets_vmargin.rst b/docs/_source/widgets_vmargin.rst index 44002f78..74f1f197 100644 --- a/docs/_source/widgets_vmargin.rst +++ b/docs/_source/widgets_vmargin.rst @@ -1,4 +1,3 @@ - .. module:: pygame_menu.widgets.widget.vmargin ======= diff --git a/docs/add_widgets.py b/docs/add_widgets.py index 8c51ad5e..b1a5dd41 100644 --- a/docs/add_widgets.py +++ b/docs/add_widgets.py @@ -32,10 +32,10 @@ def make_menu( - menu_theme: 'pygame_menu.themes.Theme', - title: str, - center: bool = True, - widget_font_size: int = 25 + menu_theme: 'pygame_menu.themes.Theme', + title: str, + center: bool = True, + widget_font_size: int = 25 ) -> 'pygame_menu.Menu': """ Make menu. diff --git a/docs/generate_resources.py b/docs/generate_resources.py index 376c9e37..8d10db37 100644 --- a/docs/generate_resources.py +++ b/docs/generate_resources.py @@ -15,11 +15,11 @@ def save_font_image( - font_name: str, - text: str, - filename: str, - font_size: int = 50, - image_height: int = 26 + font_name: str, + text: str, + filename: str, + font_size: int = 50, + image_height: int = 26 ) -> None: """ Generate a font image and save as a png. diff --git a/docs/index.rst b/docs/index.rst index 731c22ff..54482ab0 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,4 +1,3 @@ - :orphan: .. This page is orphan because its content concerns the internal working of the diff --git a/pygame_menu/__init__.py b/pygame_menu/__init__.py index c8c3c42a..dd97d7d0 100644 --- a/pygame_menu/__init__.py +++ b/pygame_menu/__init__.py @@ -135,8 +135,7 @@ """ import os -if 'PYGAME_MENU_HIDE_VERSION' not in os.environ and \ - 'PYGAME_HIDE_SUPPORT_PROMPT' not in os.environ: +if 'PYGAME_MENU_HIDE_VERSION' not in os.environ and 'PYGAME_HIDE_SUPPORT_PROMPT' not in os.environ: print(f'{__module_name__} {__version__}') # Cleanup namespace diff --git a/pygame_menu/_decorator.py b/pygame_menu/_decorator.py index fa17e4a8..9670a681 100644 --- a/pygame_menu/_decorator.py +++ b/pygame_menu/_decorator.py @@ -71,9 +71,9 @@ class Decorator(Base): cache: bool def __init__( - self, - obj: Union['pygame_menu.widgets.Widget', 'pygame_menu._scrollarea.ScrollArea', 'pygame_menu.Menu'], - decorator_id: str = '' + self, + obj: Union['pygame_menu.widgets.Widget', 'pygame_menu._scrollarea.ScrollArea', 'pygame_menu.Menu'], + decorator_id: str = '' ) -> None: super(Decorator, self).__init__(object_id=decorator_id) @@ -190,14 +190,14 @@ def force_cache_update(self, prev: Optional[bool] = None) -> 'Decorator': return self def add_polygon( - self, - coords: Union[List[Tuple2NumberType], Tuple[Tuple2NumberType, ...]], - color: ColorInputType, - filled: bool, - width: int = 0, - prev: bool = True, - gfx: bool = True, - **kwargs + self, + coords: Union[List[Tuple2NumberType], Tuple[Tuple2NumberType, ...]], + color: ColorInputType, + filled: bool, + width: int = 0, + prev: bool = True, + gfx: bool = True, + **kwargs ) -> str: """ Adds a polygon. @@ -230,12 +230,12 @@ def add_polygon( ) def add_bezier( - self, - coords: Union[List[Tuple2NumberType], Tuple[Tuple2NumberType, ...]], - color: ColorInputType, - steps: int = 5, - prev: bool = True, - **kwargs + self, + coords: Union[List[Tuple2NumberType], Tuple[Tuple2NumberType, ...]], + color: ColorInputType, + steps: int = 5, + prev: bool = True, + **kwargs ) -> str: """ Adds a Bézier curve. @@ -259,16 +259,16 @@ def add_bezier( ) def add_circle( - self, - x: NumberType, - y: NumberType, - radius: NumberType, - color: ColorInputType, - filled: bool, - width: int = 0, - prev: bool = True, - gfx: bool = True, - **kwargs + self, + x: NumberType, + y: NumberType, + radius: NumberType, + color: ColorInputType, + filled: bool, + width: int = 0, + prev: bool = True, + gfx: bool = True, + **kwargs ) -> str: """ Adds a circle. @@ -304,17 +304,17 @@ def add_circle( ) def add_arc( - self, - x: NumberType, - y: NumberType, - radius: NumberType, - init_angle: NumberType, - final_angle: NumberType, - color: ColorInputType, - width: int = 0, - prev: bool = True, - gfx: bool = True, - **kwargs + self, + x: NumberType, + y: NumberType, + radius: NumberType, + init_angle: NumberType, + final_angle: NumberType, + color: ColorInputType, + width: int = 0, + prev: bool = True, + gfx: bool = True, + **kwargs ) -> str: """ Adds an arc. @@ -349,15 +349,15 @@ def add_arc( ) def add_pie( - self, - x: NumberType, - y: NumberType, - radius: NumberType, - init_angle: NumberType, - final_angle: NumberType, - color: ColorInputType, - prev: bool = True, - **kwargs + self, + x: NumberType, + y: NumberType, + radius: NumberType, + init_angle: NumberType, + final_angle: NumberType, + color: ColorInputType, + prev: bool = True, + **kwargs ) -> str: """ Adds an unfilled pie. @@ -388,13 +388,13 @@ def add_pie( ) def add_surface( - self, - x: NumberType, - y: NumberType, - surface: 'pygame.Surface', - prev: bool = True, - centered: bool = False, - **kwargs + self, + x: NumberType, + y: NumberType, + surface: 'pygame.Surface', + prev: bool = True, + centered: bool = False, + **kwargs ) -> str: """ Adds a surface. @@ -419,13 +419,13 @@ def add_surface( ) def add_baseimage( - self, - x: NumberType, - y: NumberType, - image: 'pygame_menu.BaseImage', - prev: bool = True, - centered: bool = False, - **kwargs + self, + x: NumberType, + y: NumberType, + image: 'pygame_menu.BaseImage', + prev: bool = True, + centered: bool = False, + **kwargs ) -> str: """ Adds a :py:class:`pygame_menu.baseimage.BaseImage` object. @@ -455,14 +455,14 @@ def add_baseimage( ) def add_rect( - self, - x: NumberType, - y: NumberType, - rect: 'pygame.Rect', - color: ColorInputType, - width: int = 0, - prev: bool = True, - **kwargs + self, + x: NumberType, + y: NumberType, + rect: 'pygame.Rect', + color: ColorInputType, + width: int = 0, + prev: bool = True, + **kwargs ) -> str: """ Adds a BaseImage object. @@ -489,15 +489,15 @@ def add_rect( ) def add_rectangle( - self, - x: NumberType, - y: NumberType, - width: NumberType, - height: NumberType, - color: ColorInputType, - border: int = 0, - prev: bool = True, - **kwargs + self, + x: NumberType, + y: NumberType, + width: NumberType, + height: NumberType, + color: ColorInputType, + border: int = 0, + prev: bool = True, + **kwargs ) -> str: """ Adds a BaseImage object. @@ -521,17 +521,17 @@ def add_rectangle( return self.add_rect(x, y, rect, color, border, prev, **kwargs) def add_text( - self, - x: NumberType, - y: NumberType, - text: str, - font: FontType, - size: int, - color: ColorInputType, - prev: bool = True, - antialias=True, - centered=False, - **kwargs + self, + x: NumberType, + y: NumberType, + text: str, + font: FontType, + size: int, + color: ColorInputType, + prev: bool = True, + antialias=True, + centered=False, + **kwargs ) -> str: """ Adds a text. @@ -568,15 +568,15 @@ def add_text( ) def add_ellipse( - self, - x: NumberType, - y: NumberType, - rx: NumberType, - ry: NumberType, - color: ColorInputType, - filled: bool, - prev: bool = True, - **kwargs + self, + x: NumberType, + y: NumberType, + rx: NumberType, + ry: NumberType, + color: ColorInputType, + filled: bool, + prev: bool = True, + **kwargs ) -> str: """ Adds an ellipse. @@ -605,12 +605,12 @@ def add_ellipse( ) def add_pixel( - self, - x: NumberType, - y: NumberType, - color: ColorInputType, - prev: bool = True, - **kwargs + self, + x: NumberType, + y: NumberType, + color: ColorInputType, + prev: bool = True, + **kwargs ) -> str: """ Adds a pixel. @@ -633,10 +633,10 @@ def add_pixel( ) def add_callable( - self, - fun: Union[Callable[['pygame.Surface', Any], Any], CallableNoArgsType], - prev: bool = True, - pass_args: bool = True + self, + fun: Union[Callable[['pygame.Surface', Any], Any], CallableNoArgsType], + prev: bool = True, + pass_args: bool = True ) -> str: """ Adds a callable method. The function receives the surface and the object; @@ -666,13 +666,13 @@ def add_callable( return self._add_decor(DECORATION_CALLABLE_NO_ARGS, prev, fun) def add_textured_polygon( - self, - coords: Union[List[Tuple2NumberType], Tuple[Tuple2NumberType, ...]], - texture: Union['pygame.Surface', 'pygame_menu.BaseImage'], - tx: int = 0, - ty: int = 0, - prev: bool = True, - **kwargs + self, + coords: Union[List[Tuple2NumberType], Tuple[Tuple2NumberType, ...]], + texture: Union['pygame.Surface', 'pygame_menu.BaseImage'], + tx: int = 0, + ty: int = 0, + prev: bool = True, + **kwargs ) -> str: """ Adds a textured polygon. @@ -703,13 +703,13 @@ def add_textured_polygon( ) def add_line( - self, - pos1: Tuple2NumberType, - pos2: Tuple2NumberType, - color: ColorInputType, - width: int = 1, - prev: bool = True, - **kwargs + self, + pos1: Tuple2NumberType, + pos2: Tuple2NumberType, + color: ColorInputType, + width: int = 1, + prev: bool = True, + **kwargs ) -> str: """ Adds a line. @@ -736,9 +736,9 @@ def add_line( ) def add_fill( - self, - color: ColorInputType, - prev: bool = True + self, + color: ColorInputType, + prev: bool = True ) -> str: """ Fills the decorator rect object. @@ -753,14 +753,14 @@ def add_fill( return self._add_decor(DECORATION_FILL, prev, assert_color(color)) def add_hline( - self, - x1: NumberType, - x2: NumberType, - y: NumberType, - color: ColorInputType, - width: int = 1, - prev: bool = True, - **kwargs + self, + x1: NumberType, + x2: NumberType, + y: NumberType, + color: ColorInputType, + width: int = 1, + prev: bool = True, + **kwargs ) -> str: """ Adds a horizontal line. @@ -781,14 +781,14 @@ def add_hline( return self.add_line((x1, y), (x2, y), color, width, prev, **kwargs) def add_vline( - self, - x: NumberType, - y1: NumberType, - y2: NumberType, - color: ColorInputType, - width: int = 1, - prev: bool = True, - **kwargs + self, + x: NumberType, + y1: NumberType, + y2: NumberType, + color: ColorInputType, + width: int = 1, + prev: bool = True, + **kwargs ) -> str: """ Adds a vertical line. @@ -888,10 +888,10 @@ def remove_all(self, prev: Optional[bool] = None) -> 'Decorator': return self def _draw_assemble_cache( - self, - prev: str, - deco: List[Tuple[int, str, Any]], - surface: 'pygame.Surface' + self, + prev: str, + deco: List[Tuple[int, str, Any]], + surface: 'pygame.Surface' ) -> None: """ Draw cache, assemble if needed. @@ -914,8 +914,12 @@ def _draw_assemble_cache( self._cache_last_status[prev][4] != rect.width or \ self._cache_last_status[prev][5] != rect.height - if self._cache_needs_update[prev] or prev_surf_changed or prev_rect_changed or \ - self._cache_surface[prev] is None: + if ( + self._cache_needs_update[prev] or + prev_surf_changed or + prev_rect_changed or + self._cache_surface[prev] is None + ): self._cache_last_status[prev] = (w, h, rect.x, rect.y, rect.width, rect.height) del self._cache_surface[prev] self._cache_surface[prev] = make_surface(surface.get_width(), surface.get_height()) @@ -1071,11 +1075,11 @@ def _draw(self, deco: List[Tuple[int, str, Any]], surface: 'pygame.Surface') -> raise ValueError('unknown decoration type') def _update_pos_list( - self, - rect: 'pygame.Rect', - decoid: str, - pos: Union[Tuple2NumberType, Tuple[Tuple2NumberType, ...]], # only (x, y) or ((x1,y1), ... - use_center_positioning=True + self, + rect: 'pygame.Rect', + decoid: str, + pos: Union[Tuple2NumberType, Tuple[Tuple2NumberType, ...]], # only (x, y) or ((x1,y1), ... + use_center_positioning=True ) -> Union[Tuple[Tuple2IntType, ...], Tuple2IntType]: """ Updates position list based on rect center. If position of the rect changes, diff --git a/pygame_menu/_scrollarea.py b/pygame_menu/_scrollarea.py index 55b62936..17136d83 100644 --- a/pygame_menu/_scrollarea.py +++ b/pygame_menu/_scrollarea.py @@ -37,7 +37,7 @@ def get_scrollbars_from_position( - position: str + position: str ) -> Union[str, Tuple[str, str], Tuple[str, str, str, str]]: """ Return the scrollbars from the given position. @@ -139,33 +139,33 @@ class ScrollArea(Base): _world: 'pygame.Surface' 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 + 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) @@ -205,8 +205,7 @@ def __init__( assert_position(shadow_position) - assert area_width > 0 and area_height > 0, \ - 'area size must be greater than zero' + assert area_width > 0 and area_height > 0, 'area size must be greater than zero' assert isinstance(scrollbars, (str, VectorInstance)) unique_scrolls = [] @@ -319,9 +318,11 @@ def _make_background_surface(self) -> None: Create background surface. """ # If bg surface is created, and it's the same size - if self._bg_surface is not None and \ - self._bg_surface.get_width() == self._rect.width and \ - self._bg_surface.get_height() == self._rect.height: + if ( + self._bg_surface is not None and + self._bg_surface.get_width() == self._rect.width and + self._bg_surface.get_height() == self._rect.height + ): return # Make surface @@ -334,8 +335,8 @@ def _make_background_surface(self) -> None: self._bg_surface.fill(assert_color(self._area_color)) def update_area_color( - self, - color: Optional[Union[ColorInputType, 'pygame_menu.BaseImage']] + self, + color: Optional[Union[ColorInputType, 'pygame_menu.BaseImage']] ) -> 'ScrollArea': """ Updates area color (background). @@ -700,8 +701,7 @@ def get_view_rect(self) -> 'pygame.Rect': return rect # All scrollbars: the world is too large - if self._world.get_height() > self._rect.height \ - and self._world.get_width() > self._rect.width: + if self._world.get_height() > self._rect.height and self._world.get_width() > self._rect.width: for sbar in self._scrollbars: if not sbar.is_visible(): continue @@ -843,9 +843,11 @@ def _on_horizontal_scroll(self, value: NumberType) -> None: :param value: New position of the slider """ for sbar in self._scrollbars: - if sbar.get_orientation() == ORIENTATION_HORIZONTAL \ - and self.get_hidden_width() != 0 \ - and sbar.get_value() != value: + if ( + sbar.get_orientation() == ORIENTATION_HORIZONTAL and + self.get_hidden_width() != 0 and + sbar.get_value() != value + ): sbar.set_value(value) def _on_vertical_scroll(self, value: NumberType) -> None: @@ -856,9 +858,11 @@ def _on_vertical_scroll(self, value: NumberType) -> None: :param value: New position of the slider """ for sbar in self._scrollbars: - if sbar.get_orientation() == ORIENTATION_VERTICAL \ - and self.get_hidden_height() != 0 \ - and sbar.get_value() != value: + if ( + sbar.get_orientation() == ORIENTATION_VERTICAL and + self.get_hidden_height() != 0 and + sbar.get_value() != value + ): sbar.set_value(value) def get_parent_scroll_value_percentage(self, orientation: str) -> Tuple[float]: @@ -922,10 +926,10 @@ def scroll_to(self, orientation: str, value: NumberType) -> 'ScrollArea': # noinspection PyTypeChecker def scroll_to_rect( - self, - rect: 'pygame.Rect', - margin: Tuple2NumberType = (0, 0), - scroll_parent: bool = True + self, + rect: 'pygame.Rect', + margin: Tuple2NumberType = (0, 0), + scroll_parent: bool = True ) -> bool: """ Ensure that the given rect is in the viewable area. @@ -936,8 +940,7 @@ def scroll_to_rect( :return: Scrollarea scrolled to rect. If ``False`` the rect was already inside the visible area """ # Check if visible - if self.to_real_position(rect, visible=True).height == 0 and \ - self._parent_scrollarea is not None and scroll_parent: + if self.to_real_position(rect, visible=True).height == 0 and self._parent_scrollarea is not None and scroll_parent: self._parent_scrollarea.scroll_to_rect(self._parent_scrollarea.get_rect(), margin, scroll_parent) self._parent_scrollarea.scroll_to_rect(self.get_rect(), margin, scroll_parent) @@ -951,10 +954,12 @@ def scroll_to_rect( sx = self.get_scrollbar_thickness(ORIENTATION_VERTICAL) sy = self.get_scrollbar_thickness(ORIENTATION_HORIZONTAL) view_rect = self.get_absolute_view_rect() - if view_rect.topleft[0] <= real_rect.topleft[0] + sx \ - and view_rect.topleft[1] <= real_rect.topleft[1] + sy \ - and view_rect.bottomright[0] + sx >= real_rect.bottomright[0] \ - and view_rect.bottomright[1] + sy >= real_rect.bottomright[1]: + if ( + view_rect.topleft[0] <= real_rect.topleft[0] + sx and + view_rect.topleft[1] <= real_rect.topleft[1] + sy and + view_rect.bottomright[0] + sx >= real_rect.bottomright[0] and + view_rect.bottomright[1] + sy >= real_rect.bottomright[1] + ): return False for sbar in self._scrollbars: @@ -998,8 +1003,8 @@ def get_position(self) -> Tuple2IntType: return self._rect.x, self._rect.y def get_widget_position_relative_to_view_rect( - self, - widget: 'pygame_menu.widgets.Widget' + self, + widget: 'pygame_menu.widgets.Widget' ) -> Tuple2NumberType: """ Get widget position relative to view rect on x-axis and y-axis. On each axis, @@ -1126,9 +1131,9 @@ def get_absolute_view_rect(self) -> 'pygame.Rect': return view_rect_absolute def to_real_position( - self, - virtual: Union['pygame.Rect', Tuple2NumberType], - visible: bool = False + self, + virtual: Union['pygame.Rect', Tuple2NumberType], + visible: bool = False ) -> Union['pygame.Rect', Tuple2IntType]: """ Return the real position/Rect according to the ScrollArea origin of a @@ -1160,8 +1165,8 @@ def to_real_position( return int(x_coord), int(y_coord) def to_world_position( - self, - real: Union['pygame.Rect', Tuple2NumberType] + self, + real: Union['pygame.Rect', Tuple2NumberType] ) -> Union['pygame.Rect', Tuple2IntType]: """ Return the position/Rect in the world surface reference of a real @@ -1211,11 +1216,9 @@ def update(self, events: EventVectorType) -> bool: for sbar in self._scrollbars: if not sbar.is_visible(): continue - if self.get_hidden_width() and not updated[0] and \ - sbar.get_orientation() == ORIENTATION_HORIZONTAL: + if self.get_hidden_width() and not updated[0] and sbar.get_orientation() == ORIENTATION_HORIZONTAL: updated[0] = sbar.update(events) - elif self.get_hidden_height() and not updated[1] and \ - sbar.get_orientation() == ORIENTATION_VERTICAL: + elif self.get_hidden_height() and not updated[1] and sbar.get_orientation() == ORIENTATION_VERTICAL: updated[1] = sbar.update(events) return updated[0] or updated[1] @@ -1240,9 +1243,9 @@ def get_menu(self) -> Optional['pygame_menu.Menu']: return self._menu def collide( - self, - widget: Union['pygame_menu.widgets.Widget', 'pygame.Rect'], - event: EventType + self, + widget: Union['pygame_menu.widgets.Widget', 'pygame.Rect'], + event: EventType ) -> bool: """ If user event collides a widget within the ScrollArea respect to the diff --git a/pygame_menu/_types.py b/pygame_menu/_types.py index 3718fd64..c63ebd29 100644 --- a/pygame_menu/_types.py +++ b/pygame_menu/_types.py @@ -51,6 +51,7 @@ Tuple2NumberType = Tuple[NumberType, NumberType] Tuple3IntType = Tuple[int, int, int] Tuple4IntType = Tuple[int, int, int, int] +Tuple4NumberType = Tuple[NumberType, NumberType, NumberType, NumberType] Tuple4Tuple2IntType = Tuple[Tuple2IntType, Tuple2IntType, Tuple2IntType, Tuple2IntType] TupleIntType = Tuple[int, ...] @@ -60,10 +61,7 @@ MenuRowsType = Optional[Union[int, VectorIntType]] # Other -PaddingType = Optional[Union[NumberType, List[NumberType], Tuple[NumberType], - Tuple[NumberType, NumberType], - Tuple[NumberType, NumberType, NumberType, NumberType], - Tuple[NumberType, NumberType, NumberType, NumberType]]] +PaddingType = Optional[Union[NumberType, List[NumberType], Tuple[NumberType], Tuple2NumberType, Tuple4NumberType]] StringVector = Union[str, Tuple[str, ...], List[str]] # Instances diff --git a/pygame_menu/_widgetmanager.py b/pygame_menu/_widgetmanager.py index 2c2df22f..fe8a05eb 100644 --- a/pygame_menu/_widgetmanager.py +++ b/pygame_menu/_widgetmanager.py @@ -161,9 +161,11 @@ def _filter_widget_attributes(self, kwargs: Dict) -> Dict[str, Any]: # font_background_color font_background_color = kwargs.pop('font_background_color', self._theme.widget_font_background_color) - if font_background_color is None and \ - self._theme.widget_font_background_color_from_menu and \ - not background_is_color: + if ( + font_background_color is None and + self._theme.widget_font_background_color_from_menu and + not background_is_color + ): if not isinstance(self._theme.background_color, pygame_menu.BaseImage): font_background_color = assert_color(self._theme.background_color) attributes['font_background_color'] = font_background_color @@ -390,9 +392,9 @@ def configure_defaults_widget(self, widget: 'Widget') -> None: self._configure_widget(widget, **self._filter_widget_attributes({})) def generic_widget( - self, - widget: 'Widget', - configure_defaults: bool = False + self, + widget: 'Widget', + configure_defaults: bool = False ) -> 'Widget': """ Add generic widget to the Menu. diff --git a/pygame_menu/baseimage.py b/pygame_menu/baseimage.py index 153a079b..5109e473 100644 --- a/pygame_menu/baseimage.py +++ b/pygame_menu/baseimage.py @@ -115,14 +115,14 @@ class BaseImage(Base): smooth_scaling: bool def __init__( - self, - image_path: Union[str, 'Path', 'BytesIO'], - drawing_mode: int = IMAGE_MODE_FILL, - drawing_offset: Vector2NumberType = (0, 0), - drawing_position: str = POSITION_NORTHWEST, - load_from_file: bool = True, - frombase64: bool = False, - image_id: str = '' + self, + image_path: Union[str, 'Path', 'BytesIO'], + drawing_mode: int = IMAGE_MODE_FILL, + drawing_offset: Vector2NumberType = (0, 0), + drawing_position: str = POSITION_NORTHWEST, + load_from_file: bool = True, + frombase64: bool = False, + image_id: str = '' ) -> None: super(BaseImage, self).__init__(object_id=image_id) @@ -241,11 +241,11 @@ def set_alpha(self, value: Optional[int], flags: int = 0) -> 'BaseImage': return self def crop( - self, - x: NumberType, - y: NumberType, - width: NumberType, - height: NumberType + self, + x: NumberType, + y: NumberType, + width: NumberType, + height: NumberType ) -> 'BaseImage': """ Crops the image from coordinate on x-axis and y-axis (x, y). @@ -269,11 +269,11 @@ def get_crop_rect(self, rect: 'pygame.Rect') -> 'pygame.Surface': return self._surface.subsurface(rect) def get_crop( - self, - x: NumberType, - y: NumberType, - width: NumberType, - height: NumberType + self, + x: NumberType, + y: NumberType, + width: NumberType, + height: NumberType ) -> 'pygame.Surface': """ Get a crop of the image from coordinate on x-axis and y-axis (x, y). @@ -421,9 +421,9 @@ def get_size(self) -> Tuple2IntType: return self.get_width(), self.get_height() def get_at( - self, - pos: Tuple2NumberType, - ignore_alpha: bool = False + self, + pos: Tuple2NumberType, + ignore_alpha: bool = False ) -> Union[Tuple3IntType, Tuple4IntType]: """ Get the color from a certain position in image on x-axis and y-axis (x, y). @@ -528,8 +528,8 @@ def checkpoint(self) -> 'BaseImage': return self def apply_image_function( - self, - image_function: Callable[[int, int, int, int], Tuple4IntType] + self, + image_function: Callable[[int, int, int, int], Tuple4IntType] ) -> 'BaseImage': """ Apply a function to each pixel of the image. The function will receive the @@ -624,10 +624,10 @@ def flip(self, x: bool, y: bool) -> 'BaseImage': return self def scale( - self, - width: NumberType, - height: NumberType, - smooth: bool = True + self, + width: NumberType, + height: NumberType, + smooth: bool = True ) -> 'BaseImage': """ Scale the image to a desired width and height factor. @@ -681,10 +681,10 @@ def scale4x(self) -> 'BaseImage': return self.scale2x().scale2x() def resize( - self, - width: NumberType, - height: NumberType, - smooth: bool = True + self, + width: NumberType, + height: NumberType, + smooth: bool = True ) -> 'BaseImage': """ Resize the image to a desired (width, height) size in pixels. @@ -794,10 +794,10 @@ def _get_position_delta(self) -> Tuple2IntType: raise ValueError('unknown drawing position') def draw( - self, - surface: 'pygame.Surface', - area: Optional['pygame.Rect'] = None, - position: Tuple2IntType = (0, 0) + self, + surface: 'pygame.Surface', + area: Optional['pygame.Rect'] = None, + position: Tuple2IntType = (0, 0) ) -> 'BaseImage': """ Draw the image in a given surface. @@ -825,8 +825,11 @@ def draw( if self._drawing_mode == IMAGE_MODE_FILL: # Check if exists the transformed surface - if area.width == self._last_transform[0] and area.height == self._last_transform[1] and \ - self._last_transform[2] is not None: + if ( + area.width == self._last_transform[0] and + area.height == self._last_transform[1] and + self._last_transform[2] is not None + ): surf = self._last_transform[2] else: # Transform scale if self.smooth_scaling and self._surface.get_bitsize() > 8: diff --git a/pygame_menu/events.py b/pygame_menu/events.py index 5bdbbde8..b8e86b8e 100644 --- a/pygame_menu/events.py +++ b/pygame_menu/events.py @@ -81,8 +81,7 @@ def is_event(event: Any) -> bool: :param event: Event :return: ``True`` if it's an event """ - return isinstance(event, MenuAction) or \ - str(type(event)) == "" + return isinstance(event, MenuAction) or str(type(event)) == "" # Events diff --git a/pygame_menu/examples/__init__.py b/pygame_menu/examples/__init__.py index 4c125fcd..accb9b9a 100644 --- a/pygame_menu/examples/__init__.py +++ b/pygame_menu/examples/__init__.py @@ -18,12 +18,12 @@ # noinspection PyTypeChecker def create_example_window( - title: str, - window_size: Tuple[int, int], - pygame_menu_icon: bool = True, - init_pygame: bool = True, - center_window: bool = True, - **kwargs + title: str, + window_size: Tuple[int, int], + pygame_menu_icon: bool = True, + init_pygame: bool = True, + center_window: bool = True, + **kwargs ) -> 'pygame.Surface': """ Set pygame window. diff --git a/pygame_menu/examples/other/dynamic_widget_update.py b/pygame_menu/examples/other/dynamic_widget_update.py index bb76bcb3..c8dbd73c 100644 --- a/pygame_menu/examples/other/dynamic_widget_update.py +++ b/pygame_menu/examples/other/dynamic_widget_update.py @@ -106,9 +106,9 @@ def __init__(self) -> None: self._update_from_selection(int(self.selector_widget.get_value()[0][1])) def animate_quit_button( - self, - widget: 'pygame_menu.widgets.Widget', - menu: 'pygame_menu.Menu' + self, + widget: 'pygame_menu.widgets.Widget', + menu: 'pygame_menu.Menu' ) -> None: """ Animate widgets if the last option is selected. diff --git a/pygame_menu/examples/other/maze.py b/pygame_menu/examples/other/maze.py index 9f9b3897..b5b445c6 100644 --- a/pygame_menu/examples/other/maze.py +++ b/pygame_menu/examples/other/maze.py @@ -133,13 +133,13 @@ def __init__(self, nodetype: str, colors: dict = colors, dmf: dict = distance_mo self.color = self.pcolor if self.is_path else self.vcolor if self.is_visited else self.rcolor def update( - self, - nodetype: Union[bool, str] = False, - is_visited: Union[bool, str] = 'unchanged', - is_path: Union[bool, str] = 'unchanged', - colors: dict = colors, - dmf: dict = distance_modifiers, - nodetypes: dict = nodetypes + self, + nodetype: Union[bool, str] = False, + is_visited: Union[bool, str] = 'unchanged', + is_path: Union[bool, str] = 'unchanged', + colors: dict = colors, + dmf: dict = distance_modifiers, + nodetypes: dict = nodetypes ) -> None: """ Update the node. @@ -190,10 +190,10 @@ class MazeApp(object): _width: int def __init__( - self, - width: int = 8, - rows: int = 75, - margin: int = 0 + self, + width: int = 8, + rows: int = 75, + margin: int = 0 ) -> None: """ Creates the maze. @@ -744,9 +744,9 @@ def _prim(self, mazearray: Optional[_MazeType] = None, start_point: Optional[_Po return mazearray def _recursive_division( - self, - chamber: Optional[Tuple[int, int, int, int]] = None, - halving=True + self, + chamber: Optional[Tuple[int, int, int, int]] = None, + halving=True ) -> None: """ Performs recursive division. @@ -967,9 +967,9 @@ def _update_path(self) -> Union[bool, _MazeType]: return path_found def _get_neighbours( - self, - node: _Point2, - max_width: Optional[int] = None + self, + node: _Point2, + max_width: Optional[int] = None ) -> Generator[Tuple[_Point2, str], Any, None]: """ Get the neighbours. @@ -1040,11 +1040,11 @@ def _update_square(self, row: int, column: int) -> None: pygame.event.pump() def _dijkstra( - self, - mazearray: _MazeType, - start_point: _Point2 = (0, 0), - goal_node: Optional[_Point2] = None, - astar: bool = False + self, + mazearray: _MazeType, + start_point: _Point2 = (0, 0), + goal_node: Optional[_Point2] = None, + astar: bool = False ) -> bool: """ Dijkstra's pathfinding algorithm, with the option to switch to A* by diff --git a/pygame_menu/examples/other/ui_solar_system.py b/pygame_menu/examples/other/ui_solar_system.py index a3eb0185..044aef06 100644 --- a/pygame_menu/examples/other/ui_solar_system.py +++ b/pygame_menu/examples/other/ui_solar_system.py @@ -33,13 +33,13 @@ class Planet(object): url: str def __init__( - self, - image: 'pygame_menu.BaseImage', - info: str, - url: str, - radius: float, - period: float, - fontsize: Union[int, float] + self, + image: 'pygame_menu.BaseImage', + info: str, + url: str, + radius: float, + period: float, + fontsize: Union[int, float] ) -> None: """ Create a planet. diff --git a/pygame_menu/menu.py b/pygame_menu/menu.py index d92287cc..cad6cfd4 100644 --- a/pygame_menu/menu.py +++ b/pygame_menu/menu.py @@ -181,32 +181,32 @@ class Menu(Base): add: 'WidgetManager' def __init__( - self, - title: str, - width: NumberType, - height: NumberType, - center_content: bool = True, - column_max_width: MenuColumnMaxWidthType = None, - column_min_width: MenuColumnMinWidthType = 0, - columns: int = 1, - enabled: bool = True, - joystick_enabled: bool = True, - keyboard_enabled: bool = True, - keyboard_ignore_nonphysical: bool = True, - menu_id: str = '', - mouse_enabled: bool = True, - mouse_motion_selection: bool = False, - mouse_visible: bool = True, - onclose: Optional[Union['_events.MenuAction', Callable[['Menu'], Any], CallableNoArgsType]] = None, - onreset: Optional[Union[Callable[['Menu'], Any], CallableNoArgsType]] = None, - overflow: Union[Vector2BoolType, bool] = (True, True), - position: Union[Vector2NumberType, Tuple[NumberType, NumberType, bool]] = (50, 50, True), - rows: MenuRowsType = None, - screen_dimension: Optional[Vector2IntType] = None, - theme: 'Theme' = THEME_DEFAULT.copy(), - touchscreen: bool = False, - touchscreen_motion_selection: bool = False, - verbose: bool = True + self, + title: str, + width: NumberType, + height: NumberType, + center_content: bool = True, + column_max_width: MenuColumnMaxWidthType = None, + column_min_width: MenuColumnMinWidthType = 0, + columns: int = 1, + enabled: bool = True, + joystick_enabled: bool = True, + keyboard_enabled: bool = True, + keyboard_ignore_nonphysical: bool = True, + menu_id: str = '', + mouse_enabled: bool = True, + mouse_motion_selection: bool = False, + mouse_visible: bool = True, + onclose: Optional[Union['_events.MenuAction', Callable[['Menu'], Any], CallableNoArgsType]] = None, + onreset: Optional[Union[Callable[['Menu'], Any], CallableNoArgsType]] = None, + overflow: Union[Vector2BoolType, bool] = (True, True), + position: Union[Vector2NumberType, Tuple[NumberType, NumberType, bool]] = (50, 50, True), + rows: MenuRowsType = None, + screen_dimension: Optional[Vector2IntType] = None, + theme: 'Theme' = THEME_DEFAULT.copy(), + touchscreen: bool = False, + touchscreen_motion_selection: bool = False, + verbose: bool = True ) -> None: super(Menu, self).__init__(object_id=menu_id) self._verbose = verbose @@ -599,11 +599,11 @@ def __init__( self._sound._verbose = verbose def resize( - self, - width: NumberType, - height: NumberType, - screen_dimension: Optional[Vector2IntType] = None, - position: Optional[Union[Vector2NumberType, Tuple[NumberType, NumberType, bool]]] = None + self, + width: NumberType, + height: NumberType, + screen_dimension: Optional[Vector2IntType] = None, + position: Optional[Union[Vector2NumberType, Tuple[NumberType, NumberType, bool]]] = None ) -> 'Menu': """ Resize the menu to another width/height @@ -782,12 +782,15 @@ def force_surface_cache_update(self) -> 'Menu': return self def set_onbeforeopen( - self, - onbeforeopen: Optional[Callable[['Menu', 'Menu'], Any]] + self, + onbeforeopen: Optional[Callable[['Menu', 'Menu'], Any]] ) -> 'Menu': """ Set ``onbeforeopen`` callback. Callback is executed before opening the - Menu, it receives the current Menu and the next Menu: + Menu, it receives the current Menu and the next Menu. This method is only + executed programatically (by calling ``menu._open``) or by applying to + certain widgets, like :py:class:`pygame_menu.widgets.Button`. Rendering, or + drawing the current Menu does not trigger this event. .. code-block:: python @@ -808,8 +811,8 @@ def set_onbeforeopen( return self def set_onupdate( - self, - onupdate: Optional[Union[Callable[[EventListType, 'Menu'], Any], CallableNoArgsType]] + self, + onupdate: Optional[Union[Callable[[EventListType, 'Menu'], Any], CallableNoArgsType]] ) -> 'Menu': """ Set ``onupdate`` callback. Callback is executed before updating the Menu, @@ -835,8 +838,8 @@ def set_onupdate( return self def set_onclose( - self, - onclose: Optional[Union['_events.MenuAction', Callable[['Menu'], Any], CallableNoArgsType]] + self, + onclose: Optional[Union['_events.MenuAction', Callable[['Menu'], Any], CallableNoArgsType]] ) -> 'Menu': """ Set ``onclose`` callback. Callback can only receive 1 argument maximum @@ -863,8 +866,8 @@ def set_onclose( return self def set_onreset( - self, - onreset: Optional[Union[Callable[['Menu'], Any], CallableNoArgsType]] + self, + onreset: Optional[Union[Callable[['Menu'], Any], CallableNoArgsType]] ) -> 'Menu': """ Set ``onreset`` callback. Callback can only receive 1 argument maximum @@ -889,8 +892,8 @@ def set_onreset( return self def set_onwindowmouseover( - self, - onwindowmouseover: Optional[Union[Callable[['Menu'], Any], CallableNoArgsType]] + self, + onwindowmouseover: Optional[Union[Callable[['Menu'], Any], CallableNoArgsType]] ) -> 'Menu': """ Set ``onwindowmouseover`` callback. This method is executed in @@ -911,8 +914,8 @@ def set_onwindowmouseover( return self def set_onwindowmouseleave( - self, - onwindowmouseleave: Optional[Union[Callable[['Menu'], Any], CallableNoArgsType]] + self, + onwindowmouseleave: Optional[Union[Callable[['Menu'], Any], CallableNoArgsType]] ) -> 'Menu': """ Set ``onwindowmouseleave`` callback. This method is executed in @@ -933,8 +936,8 @@ def set_onwindowmouseleave( return self def set_onwidgetchange( - self, - onwidgetchange: Optional[Callable[['Menu', 'Widget'], Any]] + self, + onwidgetchange: Optional[Callable[['Menu', 'Widget'], Any]] ) -> 'Menu': """ Set ``onwidgetchange`` callback. This method is executed if any appended @@ -955,8 +958,8 @@ def set_onwidgetchange( return self def set_onmouseover( - self, - onmouseover: Optional[Union[Callable[['Menu', EventType], Any], CallableNoArgsType]] + self, + onmouseover: Optional[Union[Callable[['Menu', EventType], Any], CallableNoArgsType]] ) -> 'Menu': """ Set ``onmouseover`` callback. This method is executed in @@ -977,8 +980,8 @@ def set_onmouseover( return self def set_onmouseleave( - self, - onmouseleave: Optional[Union[Callable[['Menu', EventType], Any], CallableNoArgsType]] + self, + onmouseleave: Optional[Union[Callable[['Menu', EventType], Any], CallableNoArgsType]] ) -> 'Menu': """ Set ``onmouseleave`` callback. This method is executed in @@ -1167,9 +1170,9 @@ def get_sound(self) -> 'Sound': return self._sound def _update_after_remove_or_hidden( - self, - index: int, - update_surface: bool = True + self, + index: int, + update_surface: bool = True ) -> None: """ Update widgets after removal or hidden. @@ -1522,9 +1525,11 @@ def get_rect(wid: 'Widget') -> 'pygame.Rect': _, r, _ = r_widget.get_col_row_index() if r >= row: break - if r_widget.is_visible() and \ - not r_widget.is_floating() and \ - not r_widget.get_frame() is not None: + if ( + r_widget.is_visible() and + not r_widget.is_floating() and + not r_widget.get_frame() is not None + ): y_sum += get_rect(r_widget).height # Height y_sum += r_widget.get_margin()[1] # Vertical margin (bottom) @@ -1633,8 +1638,7 @@ def _build_widget_surface(self) -> None: height = int(height) # Get the previous surface if the width/height is the same - if width == self._widgets_surface_last[0] and \ - height == self._widgets_surface_last[1]: + if width == self._widgets_surface_last[0] and height == self._widgets_surface_last[1]: self._widgets_surface = self._widgets_surface_last[2] else: self._widgets_surface = make_surface(width, height) @@ -1646,8 +1650,7 @@ def _build_widget_surface(self) -> None: # Check if the scrollbars changed sx, sy = self._get_scrollbar_thickness() - if (sx, sy) != self._last_scroll_thickness[0] and \ - self._last_scroll_thickness[1] == 0: + if (sx, sy) != self._last_scroll_thickness[0] and self._last_scroll_thickness[1] == 0: self._last_scroll_thickness[0] = (sx, sy) self._last_scroll_thickness[1] += 1 self._widgets_surface_need_update = True @@ -2032,8 +2035,7 @@ def draw(self, surface: 'pygame.Surface', clear_surface: bool = False) -> 'Menu' render = self._current._render() # Updates title - if self._current._theme.title_updates_pygame_display and \ - pygame.display.get_caption()[0] != self._current.get_title(): + if self._current._theme.title_updates_pygame_display and pygame.display.get_caption()[0] != self._current.get_title(): pygame.display.set_caption(self._current.get_title()) # Clear surface @@ -2051,9 +2053,11 @@ def draw(self, surface: 'pygame.Surface', clear_surface: bool = False) -> 'Menu' self._current._decorator.draw_prev(surface) # Draw widgets, update cache if enabled - if not self._current._widget_surface_cache_enabled or \ - (render or self._current._widget_surface_cache_need_update): - + if ( + not self._current._widget_surface_cache_enabled or + render or + self._current._widget_surface_cache_need_update + ): # This should be updated before drawing widgets. As widget # draw may trigger surface cache updating. Don't move this # line or unexpected errors may occur @@ -2099,10 +2103,10 @@ def draw(self, surface: 'pygame.Surface', clear_surface: bool = False) -> 'Menu' return self._current def _draw_focus_widget( - self, - surface: 'pygame.Surface', - widget: Optional['Widget'], - force: bool = False + self, + surface: 'pygame.Surface', + widget: Optional['Widget'], + force: bool = False ) -> Optional[Dict[int, Tuple4Tuple2IntType]]: """ Draw the focus background from a given widget. Widget must be selectable, @@ -2482,11 +2486,10 @@ def update(self, events: EventVectorType) -> bool: mouse_motion_event = None selected_widget = self._current.get_selected_widget() - selected_widget_disable_frame_update = \ - (False if selected_widget is None else selected_widget.active) and \ - self._current._mouse_motion_selection or \ - selected_widget is not None and selected_widget.active and \ - selected_widget.force_menu_draw_focus + selected_widget_disable_frame_update = ( + (False if selected_widget is None else selected_widget.active) and self._current._mouse_motion_selection or + selected_widget is not None and selected_widget.active and selected_widget.force_menu_draw_focus + ) selected_widget_scrollarea = None if selected_widget is None else selected_widget.get_scrollarea() # First, check update frames @@ -2516,8 +2519,11 @@ def update(self, events: EventVectorType) -> bool: updated = True # Check selected widget - elif selected_widget is not None and self._current._widget_selected_update and \ - selected_widget.update_menu(events): + elif ( + selected_widget is not None and + self._current._widget_selected_update and + selected_widget.update_menu(events) + ): self._current._last_update_mode.append( f'{_events.MENU_LAST_SELECTED_WIDGET_EVENT}#{selected_widget.get_id()}' ) @@ -2532,8 +2538,11 @@ def update(self, events: EventVectorType) -> bool: for event in events: # User closes window - close_altf4 = event.type == pygame.KEYDOWN and event.key == pygame.K_F4 and ( - event.mod == pygame.KMOD_LALT or event.mod == pygame.KMOD_RALT) + close_altf4 = ( + event.type == pygame.KEYDOWN and + event.key == pygame.K_F4 and + (event.mod == pygame.KMOD_LALT or event.mod == pygame.KMOD_RALT) + ) if event.type == _events.PYGAME_QUIT or close_altf4 or event.type == _events.PYGAME_WINDOWCLOSE: self._current._last_update_mode.append(_events.MENU_LAST_QUIT) self._current._exit() @@ -2608,8 +2617,7 @@ def update(self, events: EventVectorType) -> bool: break # User moves joy axis motion - elif event.type == pygame.JOYAXISMOTION and self._current._joystick and \ - hasattr(event, 'axis'): + elif event.type == pygame.JOYAXISMOTION and self._current._joystick and hasattr(event, 'axis'): prev = self._current._joy_event self._current._joy_event = 0 @@ -2651,8 +2659,7 @@ def update(self, events: EventVectorType) -> bool: pygame.time.set_timer(self._current._joy_event_repeat, 0) # Select widget by clicking - elif event.type == pygame.MOUSEBUTTONDOWN and self._current._mouse and \ - event.button in (1, 2, 3): # Don't consider the mouse wheel (button 4 & 5) + elif event.type == pygame.MOUSEBUTTONDOWN and self._current._mouse and event.button in (1, 2, 3): # Don't consider the mouse wheel (button 4 & 5) # If the mouse motion selection is disabled then select a widget by clicking if not self._current._mouse_motion_selection: @@ -2661,8 +2668,7 @@ def update(self, events: EventVectorType) -> bool: widget = self._current._widgets[index] if isinstance(widget, Frame): # Frame does not accept click continue - if widget.is_selectable and widget.is_visible() and \ - widget.get_scrollarea().collide(widget, event): + if widget.is_selectable and widget.is_visible() and widget.get_scrollarea().collide(widget, event): sel = self._current._select(index, 1, SELECT_MOUSE_BUTTON_DOWN, True) break @@ -2742,8 +2748,7 @@ def update(self, events: EventVectorType) -> bool: # If selected widget is active then motion should not select # or change mouseover widget - if self._current._mouse_motion_selection and \ - selected_widget is not None and selected_widget.active: + if self._current._mouse_motion_selection and selected_widget is not None and selected_widget.active: continue # Check if "rel" exists within the event @@ -2755,9 +2760,7 @@ def update(self, events: EventVectorType) -> bool: for index in range(len(self._current._widgets)): widget = self._current._widgets[index] if widget.is_visible() and widget.get_scrollarea().collide(widget, event): - if self._current._mouse_motion_selection and \ - widget.is_selectable and \ - not isinstance(widget, Frame): + if self._current._mouse_motion_selection and widget.is_selectable and not isinstance(widget, Frame): sel = self._current._select(index, 1, SELECT_MOUSE_MOTION, True) # noinspection PyProtectedMember widget._check_mouseover(event) @@ -2771,8 +2774,7 @@ def update(self, events: EventVectorType) -> bool: break # Mouse events in selected widget; don't consider the mouse wheel (button 4 & 5) - elif event.type == pygame.MOUSEBUTTONUP and self._current._mouse and \ - selected_widget is not None and event.button in (1, 2, 3): + elif event.type == pygame.MOUSEBUTTONUP and self._current._mouse and selected_widget is not None and event.button in (1, 2, 3): self._current._sound.play_click_mouse() if selected_widget_scrollarea.collide(selected_widget, event): updated = selected_widget.update_menu([event]) @@ -2792,8 +2794,7 @@ def update(self, events: EventVectorType) -> bool: widget = self._current._widgets[index] if isinstance(widget, Frame): # Frame does not accept touch continue - if widget.is_selectable and widget.is_visible() and \ - widget.get_scrollarea().collide(widget, event): + if widget.is_selectable and widget.is_visible() and widget.get_scrollarea().collide(widget, event): sel = self._current._select(index, 1, SELECT_TOUCH, True) if not isinstance(widget, Frame): break @@ -2818,8 +2819,7 @@ def update(self, events: EventVectorType) -> bool: break # Touchscreen events in selected widget - elif event.type == FINGERUP and self._current._touchscreen and \ - selected_widget is not None: + elif event.type == FINGERUP and self._current._touchscreen and selected_widget is not None: self._current._sound.play_click_touch() if selected_widget_scrollarea.collide(selected_widget, event): updated = selected_widget.update_menu([event]) @@ -2843,8 +2843,7 @@ def update(self, events: EventVectorType) -> bool: widget = self._current._widgets[index] if isinstance(widget, Frame): # Frame does not accept touch continue - if widget.is_selectable and widget.is_visible() and \ - widget.get_scrollarea().collide(widget, event): + if widget.is_selectable and widget.is_visible() and widget.get_scrollarea().collide(widget, event): sel = self._current._select(index, 1, SELECT_TOUCH, True) if not isinstance(widget, Frame): break @@ -2884,10 +2883,10 @@ def collide(self, event: EventType) -> bool: return bool(self.get_rect().collidepoint(*get_finger_pos(self, event))) def mainloop( - self, - surface: 'pygame.Surface', - bgfun: Optional[Union[Callable[['Menu'], Any], CallableNoArgsType]] = None, - **kwargs + self, + surface: 'pygame.Surface', + bgfun: Optional[Union[Callable[['Menu'], Any], CallableNoArgsType]] = None, + **kwargs ) -> 'Menu': """ Main loop of the **current** Menu. In this function, the Menu handle @@ -3181,13 +3180,13 @@ def _open(self, menu: 'Menu') -> None: self._top._current = menu._current self._top._prev = [self._top._prev, current] + # Select the first widget + self._current._select(0, 1, SELECT_OPEN, False, update_mouse_position=False) + # Call event if menu._onbeforeopen is not None: menu._onbeforeopen(current, menu) - # Select the first widget - self._current._select(0, 1, SELECT_OPEN, False, update_mouse_position=False) - # Re-render menu check_widget_mouseleave(force=True) self._render() @@ -3236,12 +3235,12 @@ def reset(self, total: int) -> 'Menu': return self._current def _select( - self, - new_index: int, - dwidget: int, - select_type: str, - apply_sound: bool, - **kwargs + self, + new_index: int, + dwidget: int, + select_type: str, + apply_sound: bool, + **kwargs ) -> bool: """ Select the widget at the given index and unselect others. Selection forces @@ -3330,20 +3329,22 @@ def _select( self._sound.play_widget_selection() # Update mouse position if selected using keys - if select_type in (SELECT_KEY, SELECT_RECURSIVE) and \ - self._mouse_motion_selection and \ - not self._disable_widget_update_mousepos_mouseselection and \ - not new_widget.is_floating() and \ - self._mouseover and \ - kwargs.get('update_mouse_position', True): + if ( + select_type in (SELECT_KEY, SELECT_RECURSIVE) and + self._mouse_motion_selection and + not self._disable_widget_update_mousepos_mouseselection and + not new_widget.is_floating() and + self._mouseover and + kwargs.get('update_mouse_position', True) + ): pygame.mouse.set_pos(new_widget.get_rect(to_real_position=True).center) return True def scroll_to_widget( - self, - widget: Optional['Widget'], - scroll_parent: bool = True + self, + widget: Optional['Widget'], + scroll_parent: bool = True ) -> 'Menu': """ Scroll the Menu to the given widget. @@ -3479,9 +3480,9 @@ def get_scrollarea(self) -> 'ScrollArea': return self._scrollarea def get_widget( - self, - widget_id: str, - recursive: bool = False + self, + widget_id: str, + recursive: bool = False ) -> Optional['Widget']: """ Return a widget by a given ID from the Menu. @@ -3586,10 +3587,10 @@ def in_submenu(self, menu: 'Menu', recursive: bool = False) -> bool: return False def _remove_submenu( - self, - menu: 'Menu', - hook: 'Widget', - recursive: bool = False + self, + menu: 'Menu', + hook: 'Widget', + recursive: bool = False ) -> bool: """ Removes Menu from submenu if ``menu`` is a submenu of the Menu. @@ -3750,11 +3751,11 @@ def _test_widgets_status(self) -> Tuple[Tuple[Any, ...], ...]: # noinspection PyProtectedMember def move_widget_index( - self, - widget: Optional['Widget'], - index: Optional[Union['Widget', int]] = None, - render: bool = True, - **kwargs + self, + widget: Optional['Widget'], + index: Optional[Union['Widget', int]] = None, + render: bool = True, + **kwargs ) -> Optional[Tuple2IntType]: """ Move a given widget to a certain index. ``index`` can be another widget, @@ -3871,24 +3872,19 @@ def move_widget_index( target_index = w_last.last_index w_last = self._widgets[w_last.last_index] target_widget = w_last - if not (isinstance(w_last, Frame) and w_last.get_indices() != (-1, -1)) or \ - w_last.get_menu() is None: + if not (isinstance(w_last, Frame) and w_last.get_indices() != (-1, -1)) or w_last.get_menu() is None: break to_last_position = target_index == len(self._widgets) - 1 if not to_last_position and check_if_last: target_index = index target_widget = self._widgets[target_index] - if both_frames and self._validate_frame_widgetmove and \ - not kwargs.get('swap_search', False): - return self.move_widget_index( - target_widget, widget, render=render, swap_search=True, depth=depth + 1 - ) + if both_frames and self._validate_frame_widgetmove and not kwargs.get('swap_search', False): + return self.move_widget_index(target_widget, widget, render=render, swap_search=True, depth=depth + 1) # Check both widgets are within frame if widget to move is frame if self._validate_frame_widgetmove and not to_last_position and not both_frames: - assert widget.get_frame() == target_widget.get_frame(), \ - 'both widgets must be within same frame' + assert widget.get_frame() == target_widget.get_frame(), 'both widgets must be within same frame' self._widgets.pop(widget_index) self._widgets.insert(target_index, widget) @@ -3954,8 +3950,7 @@ def move_widget_index( widget.get_frame()._widgets = new_dict # Update selected widget - if selected_widget is not None and selected_widget.is_selectable and \ - self._validate_frame_widgetmove: + if selected_widget is not None and selected_widget.is_selectable and self._validate_frame_widgetmove: self._index = -1 selected_widget.select(False) self._select(self._widgets.index(selected_widget), 1, SELECT_MOVE, False) diff --git a/pygame_menu/sound.py b/pygame_menu/sound.py index dc9718a9..2f9376ce 100644 --- a/pygame_menu/sound.py +++ b/pygame_menu/sound.py @@ -134,16 +134,16 @@ class Sound(Base): _uniquechannel: bool def __init__( - self, - allowedchanges: int = AUDIO_ALLOW_CHANNELS_CHANGE | AUDIO_ALLOW_FREQUENCY_CHANGE, - buffer: int = 4096, - channels: int = 2, - devicename: str = '', - force_init: bool = False, - frequency: int = 22050, - size: int = -16, - sound_id: str = '', - uniquechannel: bool = True + self, + allowedchanges: int = AUDIO_ALLOW_CHANNELS_CHANGE | AUDIO_ALLOW_FREQUENCY_CHANGE, + buffer: int = 4096, + channels: int = 2, + devicename: str = '', + force_init: bool = False, + frequency: int = 22050, + size: int = -16, + sound_id: str = '', + uniquechannel: bool = True ) -> None: super(Sound, self).__init__(object_id=sound_id) @@ -169,10 +169,7 @@ def __init__( SOUND_INITIALIZED[1] = False # Initialize sounds if not initialized - if not mixer_missing and \ - ((mixer.get_init() is None and not SOUND_INITIALIZED[0]) or - force_init): - + if not mixer_missing and ((mixer.get_init() is None and not SOUND_INITIALIZED[0]) or force_init): # Set sound as initialized globally SOUND_INITIALIZED[0] = True @@ -286,13 +283,13 @@ def get_channel(self) -> 'mixer.Channel': return self._channel def set_sound( - self, - sound_type: str, - sound_file: Optional[Union[str, 'Path']], - volume: float = 0.5, - loops: int = 0, - maxtime: NumberType = 0, - fade_ms: NumberType = 0 + self, + sound_type: str, + sound_file: Optional[Union[str, 'Path']], + volume: float = 0.5, + loops: int = 0, + maxtime: NumberType = 0, + fade_ms: NumberType = 0 ) -> bool: """ Link a sound file to a sound type. @@ -387,8 +384,11 @@ def _play_sound(self, sound: Optional[Dict[str, Any]]) -> bool: sound_time = time.time() # If the previous sound is the same and has not ended (max 10% overlap) - if sound['type'] != self._last_play or \ - sound_time - self._last_time >= 0.1 * sound['length'] or self._uniquechannel: + if ( + sound['type'] != self._last_play or + sound_time - self._last_time >= 0.1 * sound['length'] or + self._uniquechannel + ): try: if self._uniquechannel: # Stop the current channel if it's unique channel.stop() diff --git a/pygame_menu/themes.py b/pygame_menu/themes.py index 680df55c..ff7a814f 100644 --- a/pygame_menu/themes.py +++ b/pygame_menu/themes.py @@ -637,8 +637,8 @@ def __copy__(self) -> 'Theme': @staticmethod def _format_color_opacity( - color: Optional[Union[ColorInputType, 'BaseImage']], - none: bool = False + color: Optional[Union[ColorInputType, 'BaseImage']], + none: bool = False ) -> Optional[Union[ColorType, 'BaseImage']]: """ Adds opacity to a 3 channel color. (R,G,B) -> (R,G,B,A) if the color diff --git a/pygame_menu/utils.py b/pygame_menu/utils.py index adc369bd..cd4c94a1 100644 --- a/pygame_menu/utils.py +++ b/pygame_menu/utils.py @@ -75,8 +75,8 @@ def assert_alignment(align: str) -> None: def assert_color( - color: Union[ColorInputType, List[int]], - warn_if_invalid: bool = True + color: Union[ColorInputType, List[int]], + warn_if_invalid: bool = True ) -> ColorType: """ Assert that a certain color is valid. @@ -174,9 +174,9 @@ def assert_position_vector(position: Union[str, List[str], Tuple[str, ...]]) -> def assert_vector( - num_vector: VectorType, - length: int, - instance: type = NumberInstance + num_vector: VectorType, + length: int, + instance: type = NumberInstance ) -> None: """ Assert that a fixed length vector is numeric. @@ -219,12 +219,12 @@ def check_key_pressed_valid(event: EventType) -> bool: def fill_gradient( - surface: 'pygame.Surface', - color: ColorInputType, - gradient: ColorInputType, - rect: Optional['pygame.Rect'] = None, - vertical: bool = True, - forward: bool = True + surface: 'pygame.Surface', + color: ColorInputType, + gradient: ColorInputType, + rect: Optional['pygame.Rect'] = None, + vertical: bool = True, + forward: bool = True ) -> None: """ Fill a surface with a gradient pattern. @@ -275,8 +275,8 @@ def fill_gradient( def format_color( - color: Union[ColorInputType, Any], - warn_if_invalid: bool = True + color: Union[ColorInputType, Any], + warn_if_invalid: bool = True ) -> Union[ColorType, Any]: """ Format color from string, int, or tuple to tuple type. @@ -409,10 +409,10 @@ def load_pygame_image_file(image_path: str, **kwargs) -> 'pygame.Surface': def make_surface( - width: NumberType, - height: NumberType, - alpha: bool = False, - fill_color: Optional[ColorInputType] = None + width: NumberType, + height: NumberType, + alpha: bool = False, + fill_color: Optional[ColorInputType] = None ) -> 'pygame.Surface': """ Creates a pygame surface object. @@ -489,8 +489,8 @@ def parse_padding(padding: PaddingType) -> Tuple4IntType: def print_menu_widget_structure( - widgets: List['pygame_menu.widgets.Widget'], - index: int + widgets: List['pygame_menu.widgets.Widget'], + index: int ) -> None: """ Test printing widgets order. @@ -638,9 +638,9 @@ def warn(message: str, print_stack: bool = True) -> None: def widget_terminal_title( - widget: 'pygame_menu.widgets.Widget', - widget_index: int = -1, - current_index: int = -1 + widget: 'pygame_menu.widgets.Widget', + widget_index: int = -1, + current_index: int = -1 ) -> str: """ Return widget title to be printed on terminals. @@ -763,11 +763,11 @@ def clear_short_term_caches(self, force: bool = False) -> None: self._short_term_rect_cache.clear() def _create_shadow_corners( - self, - shadow_width_param: int, - corner_radius_param: int, - color: Tuple3IntType, - aa_amount: int = 4 + self, + shadow_width_param: int, + corner_radius_param: int, + color: Tuple3IntType, + aa_amount: int = 4 ) -> Dict[str, 'pygame.Surface']: """ Create corners for our rectangular shadows. These can be used across many @@ -841,11 +841,11 @@ def _create_shadow_corners( @staticmethod def _create_single_corner_and_edge( - aa_amount: int, - corner_radius_param: int, - corner_rect: 'pygame.Rect', - shadow_width_param: int, - color: Tuple3IntType + aa_amount: int, + corner_radius_param: int, + corner_rect: 'pygame.Rect', + shadow_width_param: int, + color: Tuple3IntType ) -> Tuple['pygame.Surface', 'pygame.Surface']: """ Creates a single corner surface and a single edge surface for a shadow. @@ -915,13 +915,13 @@ def _create_single_corner_and_edge( return final_corner_surface, final_edge_surface def create_new_rectangle_shadow( - self, - width: int, - height: int, - shadow_width_param: int, - corner_radius_param: int, - aa_amount: int = 4, - color: Tuple3IntType = (0, 0, 0) + self, + width: int, + height: int, + shadow_width_param: int, + corner_radius_param: int, + aa_amount: int = 4, + color: Tuple3IntType = (0, 0, 0) ) -> Optional['pygame.Surface']: """ Creates a rectangular shadow surface at the specified size and stores it for later use. @@ -938,7 +938,7 @@ def create_new_rectangle_shadow( assert isinstance(height, int) assert_vector(color, 3, int) shadow_width_param, corner_radius_param, aa_amount = int(shadow_width_param), \ - int(corner_radius_param), int(aa_amount) + int(corner_radius_param), int(aa_amount) if width < corner_radius_param or height < corner_radius_param or shadow_width_param == 0: return None r, g, b = color @@ -994,12 +994,12 @@ def create_new_rectangle_shadow( return final_surface def create_new_ellipse_shadow( - self, - width: int, - height: int, - shadow_width_param: int, - aa_amount: int = 4, - color: Tuple3IntType = (0, 0, 0) + self, + width: int, + height: int, + shadow_width_param: int, + aa_amount: int = 4, + color: Tuple3IntType = (0, 0, 0) ) -> Optional['pygame.Surface']: """ Creates an ellipse shaped shadow surface at the specified size and stores it for later use. diff --git a/pygame_menu/version.py b/pygame_menu/version.py index 6253a458..d3e1ebe1 100644 --- a/pygame_menu/version.py +++ b/pygame_menu/version.py @@ -34,6 +34,6 @@ def __str__(self) -> str: patch = property(lambda self: self[2]) -vernum = Version(4, 3, 6) +vernum = Version(4, 3, 7) ver = str(vernum) rev = '' diff --git a/pygame_menu/widgets/core/selection.py b/pygame_menu/widgets/core/selection.py index 8060b3b2..4feca4f9 100644 --- a/pygame_menu/widgets/core/selection.py +++ b/pygame_menu/widgets/core/selection.py @@ -40,11 +40,11 @@ class Selection(object): widget_apply_font_color: bool def __init__( - self, - margin_left: NumberType, - margin_right: NumberType, - margin_top: NumberType, - margin_bottom: NumberType + self, + margin_left: NumberType, + margin_right: NumberType, + margin_top: NumberType, + margin_bottom: NumberType ) -> None: assert isinstance(margin_left, NumberInstance) assert isinstance(margin_right, NumberInstance) @@ -173,8 +173,8 @@ def get_height(self) -> int: return t + b def inflate( - self, - rect: 'pygame.Rect', inflate: Optional[Tuple2IntType] = None + self, + rect: 'pygame.Rect', inflate: Optional[Tuple2IntType] = None ) -> 'pygame.Rect': """ Grow or shrink the rectangle size according to margins. diff --git a/pygame_menu/widgets/core/widget.py b/pygame_menu/widgets/core/widget.py index 51d6b82c..82ce5247 100644 --- a/pygame_menu/widgets/core/widget.py +++ b/pygame_menu/widgets/core/widget.py @@ -91,9 +91,9 @@ def check_widget_mouseleave(event: Optional[EventType] = None, force: bool = Fal # noinspection PyProtectedMember def _check_widget_mouseleave( - event: Optional[EventType] = None, - force: bool = False, - recursive: bool = False + event: Optional[EventType] = None, + force: bool = False, + recursive: bool = False ) -> None: """ Check if the active widget (WIDGET_MOUSEOVER[0]) is still over, else, execute @@ -162,8 +162,7 @@ def _check_widget_mouseleave( _check_widget_mouseleave(event, force, recursive=True) # Check sublist - if len(WIDGET_MOUSEOVER[1]) == 3 and len(WIDGET_MOUSEOVER[1][2]) > 0 and \ - not recursive and not force: + if len(WIDGET_MOUSEOVER[1]) == 3 and len(WIDGET_MOUSEOVER[1][2]) > 0 and not recursive and not force: prev: List[Any] = WIDGET_MOUSEOVER[1][2] # [widget, cursor, [widget, cursor, [...]]] while True: if len(prev) == 0: @@ -307,16 +306,16 @@ class Widget(Base): selection_expand_background: bool def __init__( - self, - title: Any = '', - widget_id: str = '', - onchange: CallbackType = None, - onmouseleave: Optional[Callable[['Widget', EventType], Any]] = None, - onmouseover: Optional[Callable[['Widget', EventType], Any]] = None, - onreturn: CallbackType = None, - onselect: Optional[Callable[[bool, 'Widget', 'pygame_menu.Menu'], Any]] = None, - args=None, - kwargs=None + self, + title: Any = '', + widget_id: str = '', + onchange: CallbackType = None, + onmouseleave: Optional[Callable[['Widget', EventType], Any]] = None, + onmouseover: Optional[Callable[['Widget', EventType], Any]] = None, + onreturn: CallbackType = None, + onselect: Optional[Callable[[bool, 'Widget', 'pygame_menu.Menu'], Any]] = None, + args=None, + kwargs=None ) -> None: super(Widget, self).__init__(object_id=widget_id) @@ -568,9 +567,9 @@ def set_onmouseleave(self, onmouseleave: CallbackMouseType) -> 'Widget': return self def mouseover( - self, - event: EventType, - check_all_widget_mouseleave: bool = True + self, + event: EventType, + check_all_widget_mouseleave: bool = True ) -> 'Widget': """ Run the ``onmouseover`` if the mouse is placed over the Widget. The @@ -635,9 +634,9 @@ def mouseover( return self def mouseleave( - self, - event: EventType, - check_all_widget_mouseleave: bool = True + self, + event: EventType, + check_all_widget_mouseleave: bool = True ) -> 'Widget': """ Run the ``onmouseleave`` callback if the mouse is placed outside the Widget. @@ -671,10 +670,10 @@ def mouseleave( return self def _check_mouseover( - self, - event: EventType, - rect: Optional['pygame.Rect'] = None, - check_all_widget_mouseleave: bool = True + self, + event: EventType, + rect: Optional['pygame.Rect'] = None, + check_all_widget_mouseleave: bool = True ) -> bool: """ Check the mouse is over the widget. If so, execute the methods. @@ -703,10 +702,13 @@ def _check_mouseover( menu_enabled = True if self._menu is None else self._menu.is_enabled() # Check if mouse is over the widget, the widget must be visible - if self.is_visible() and \ - self._mouse_enabled and \ - hasattr(event, 'pos') and rect.collidepoint(*event.pos) and \ - menu_enabled: + if ( + self.is_visible() and + self._mouse_enabled and + hasattr(event, 'pos') and + rect.collidepoint(*event.pos) and + menu_enabled + ): if not self._mouseover: self._mouseover = True self.mouseover(event, check_all_widget_mouseleave) @@ -966,9 +968,9 @@ def get_title(self) -> str: return self._title def set_background_color( - self, - color: Optional[Union[ColorInputType, 'pygame_menu.BaseImage']], - inflate: Optional[Tuple2IntType] = (0, 0) + self, + color: Optional[Union[ColorInputType, 'pygame_menu.BaseImage']], + inflate: Optional[Tuple2IntType] = (0, 0) ) -> 'Widget': """ Set the Widget background color. @@ -1027,9 +1029,9 @@ def _get_background_inflate(self) -> Tuple[int, int]: return inflate def _draw_background_color( - self, - surface: 'pygame.Surface', - rect: Optional['pygame.Rect'] = None + self, + surface: 'pygame.Surface', + rect: Optional['pygame.Rect'] = None ) -> None: """ Fill a surface with the widget background color. @@ -1047,8 +1049,11 @@ def _draw_background_color( rect = self.get_rect(inflate=self._get_background_inflate()) # Create the background surface if none, if the rect changed, or if the background color changed - if self._background_surface is None or self._background_surface[0] != rect or \ - self._background_surface[2] != bg: + if ( + self._background_surface is None or + self._background_surface[0] != rect or + self._background_surface[2] != bg + ): background_surface = make_surface(rect.width, rect.height, alpha=True) if isinstance(bg, pygame_menu.BaseImage): bg.draw( @@ -1133,11 +1138,11 @@ def _draw_border(self, surface: 'pygame.Surface') -> None: ) def set_border( - self, - width: int, - color: Optional[ColorInputType], - inflate: Tuple2IntType = (0, 0), - position: WidgetBorderPositionType = WIDGET_FULL_BORDER + self, + width: int, + color: Optional[ColorInputType], + inflate: Tuple2IntType = (0, 0), + position: WidgetBorderPositionType = WIDGET_FULL_BORDER ) -> 'Widget': """ Set the Widget border. @@ -1164,8 +1169,7 @@ def set_border( position = [position] # Check positioning - if POSITION_WEST in position and POSITION_SOUTH in position and \ - POSITION_NORTH in position and POSITION_EAST in position: + if POSITION_WEST in position and POSITION_SOUTH in position and POSITION_NORTH in position and POSITION_EAST in position: position = WIDGET_BORDER_POSITION_FULL else: @@ -1307,8 +1311,8 @@ def value_changed(self) -> bool: return False def _draw_shadow( - self, - surface: 'pygame.Surface', rect: Optional['pygame.Rect'] = None + self, + surface: 'pygame.Surface', rect: Optional['pygame.Rect'] = None ) -> None: """ Draw the widget shadow. @@ -1500,8 +1504,7 @@ def scroll_to_widget(self, margin: Tuple2NumberType = (0, 0), scroll_parent: boo """ if self.has_attribute('ignore_scroll_to_widget'): return self - if self._frame is not None and self._frame.is_scrollable and \ - self._frame.get_scrollarea() is not None: + if self._frame is not None and self._frame.is_scrollable and self._frame.get_scrollarea() is not None: self._frame.get_scrollarea().scroll_to_rect(self.get_frame().get_rect(), margin, scroll_parent) if self._scrollarea is not None: rect = self.get_rect() @@ -1518,14 +1521,14 @@ def get_focus_rect(self) -> 'pygame.Rect': return self.get_rect(to_real_position=True) def get_rect( - self, - inflate: Optional[Tuple2IntType] = None, - apply_padding: bool = True, - use_transformed_padding: bool = True, - to_real_position: bool = False, - to_absolute_position: bool = False, - render: bool = False, - real_position_visible: bool = True + self, + inflate: Optional[Tuple2IntType] = None, + apply_padding: bool = True, + use_transformed_padding: bool = True, + to_real_position: bool = False, + to_absolute_position: bool = False, + render: bool = False, + real_position_visible: bool = True ) -> 'pygame.Rect': """ Return the :py:class:`pygame.Rect` object of the Widget. This method @@ -1666,10 +1669,10 @@ def _apply_transforms(self) -> None: int(self._padding[3] * pad_width)) def _font_render_string( - self, - text: str, - color: ColorInputType = (0, 0, 0), - use_background_color: bool = True + self, + text: str, + color: ColorInputType = (0, 0, 0), + use_background_color: bool = True ) -> 'pygame.Surface': """ Render text. If the font is not defined returns a zero-width surface. @@ -1724,12 +1727,12 @@ def _render_string(self, string: str, color: ColorInputType) -> 'pygame.Surface' return surface def shadow( - self, - shadow_type: str = WIDGET_SHADOW_TYPE_RECTANGULAR, - shadow_width: int = 10, - corner_radius: int = 0, - color: ColorInputType = (0, 0, 0), - aa_amount: int = 4 + self, + shadow_type: str = WIDGET_SHADOW_TYPE_RECTANGULAR, + shadow_width: int = 10, + corner_radius: int = 0, + color: ColorInputType = (0, 0, 0), + aa_amount: int = 4 ) -> 'Widget': """ Configure the widget shadow. @@ -1767,15 +1770,15 @@ def get_font_color_status(self, check_selection: bool = True) -> ColorType: return self._font_color def set_font( - self, - font: FontType, - font_size: int, - color: ColorInputType, - selected_color: ColorInputType, - readonly_color: ColorInputType, - readonly_selected_color: ColorInputType, - background_color: Optional[ColorInputType], - antialias: bool = True + self, + font: FontType, + font_size: int, + color: ColorInputType, + selected_color: ColorInputType, + readonly_color: ColorInputType, + readonly_selected_color: ColorInputType, + background_color: Optional[ColorInputType], + antialias: bool = True ) -> 'Widget': """ Set the Widget font. @@ -1824,11 +1827,11 @@ def set_font( return self def set_font_shadow( - self, - enabled: bool = True, - color: Optional[ColorInputType] = None, - position: Optional[str] = None, - offset: int = 2 + self, + enabled: bool = True, + color: Optional[ColorInputType] = None, + position: Optional[str] = None, + offset: int = 2 ) -> 'Widget': """ Set the Widget font shadow. @@ -2051,12 +2054,12 @@ def set_position(self, x: NumberType, y: NumberType) -> 'Widget': return self def get_position( - self, - apply_padding: bool = False, - use_transformed_padding: bool = True, - to_real_position: bool = False, - to_absolute_position: bool = False, - real_position_visible: bool = True + self, + apply_padding: bool = False, + use_transformed_padding: bool = True, + to_real_position: bool = False, + to_absolute_position: bool = False, + real_position_visible: bool = True ) -> Tuple2IntType: """ Return the widget position tuple on x-axis and y-axis (x, y) in px. @@ -2117,10 +2120,10 @@ def _disable_scale(self) -> None: self.render() def _scale_warn( - self, - scale: bool = True, - maxwidth: bool = True, - maxheight: bool = True + self, + scale: bool = True, + maxwidth: bool = True, + maxheight: bool = True ) -> None: """ Warns user about overriding properties of scale/maxwidth/maxheight. @@ -2146,10 +2149,10 @@ def _scale_warn( ) def set_max_width( - self, - width: Optional[NumberType], - scale_height: NumberType = False, - smooth: bool = True + self, + width: Optional[NumberType], + scale_height: NumberType = False, + smooth: bool = True ) -> 'Widget': """ Transformation: Set the Widget max width, it applies a scaling factor if @@ -2207,10 +2210,10 @@ def set_max_width( return self def set_max_height( - self, - height: Optional[NumberType], - scale_width: NumberType = False, - smooth: bool = True + self, + height: Optional[NumberType], + scale_width: NumberType = False, + smooth: bool = True ) -> 'Widget': """ Transformation: Set the Widget max height, it applies a scaling factor @@ -2263,10 +2266,10 @@ def set_max_height( return self def scale( - self, - width: NumberType, - height: NumberType, - smooth: bool = True + self, + width: NumberType, + height: NumberType, + smooth: bool = True ) -> 'Widget': """ Transformation: Scale the Widget to a desired width and height factor. @@ -2317,10 +2320,10 @@ def scale( return self def resize( - self, - width: NumberType, - height: NumberType, - smooth: bool = True + self, + width: NumberType, + height: NumberType, + smooth: bool = True ) -> 'Widget': """ Transformation: Set the Widget size to another size. @@ -2550,9 +2553,9 @@ def get_surface(self) -> 'pygame.Surface': return self._surface def get_width( - self, - apply_padding: bool = True, - apply_selection: bool = False + self, + apply_padding: bool = True, + apply_selection: bool = False ) -> int: """ Return the Widget width. @@ -2574,9 +2577,9 @@ def get_width( return int(width) def get_height( - self, - apply_padding: bool = True, - apply_selection: bool = False + self, + apply_padding: bool = True, + apply_selection: bool = False ) -> int: """ Return the Widget height. @@ -2598,9 +2601,9 @@ def get_height( return int(height) def get_size( - self, - apply_padding: bool = True, - apply_selection: bool = False + self, + apply_padding: bool = True, + apply_selection: bool = False ) -> Tuple2IntType: """ Return the Widget size. @@ -2652,11 +2655,11 @@ def set_sound(self, sound: 'Sound') -> 'Widget': return self def set_controls( - self, - joystick: bool = True, - mouse: bool = True, - touchscreen: bool = True, - keyboard: bool = True + self, + joystick: bool = True, + mouse: bool = True, + touchscreen: bool = True, + keyboard: bool = True ) -> 'Widget': """ Enable interfaces to control the Widget. @@ -2756,8 +2759,8 @@ def update_menu(self, events: EventVectorType) -> bool: return self.update(events) def add_draw_callback( - self, - draw_callback: Callable[['Widget', 'pygame_menu.Menu'], Any] + self, + draw_callback: Callable[['Widget', 'pygame_menu.Menu'], Any] ) -> str: """ Adds a function to the Widget to be executed each time the widget is drawn. @@ -2825,8 +2828,8 @@ def apply_draw_callbacks(self) -> 'Widget': return self def add_update_callback( - self, - update_callback: Callable[[EventListType, 'Widget', 'pygame_menu.Menu'], Any] + self, + update_callback: Callable[[EventListType, 'Widget', 'pygame_menu.Menu'], Any] ) -> str: """ Adds a function to the Widget to be executed each time the Widget is @@ -2910,10 +2913,10 @@ def _merge_events(self, events: EventListType) -> EventListType: return copy_events def set_float( - self, - float_status: bool = True, - menu_render: bool = False, - origin_position: bool = False + self, + float_status: bool = True, + menu_render: bool = False, + origin_position: bool = False ) -> 'Widget': """ Set the floating status. If ``True`` the Widget don't contribute its diff --git a/pygame_menu/widgets/selection/arrow_selection.py b/pygame_menu/widgets/selection/arrow_selection.py index 66e92b70..247ef58b 100644 --- a/pygame_menu/widgets/selection/arrow_selection.py +++ b/pygame_menu/widgets/selection/arrow_selection.py @@ -40,14 +40,14 @@ class ArrowSelection(Selection): _last_widget: Optional['pygame_menu.widgets.Widget'] def __init__( - self, - margin_left: NumberType, - margin_right: NumberType, - margin_top: NumberType, - margin_bottom: NumberType, - arrow_size: Tuple2IntType = (10, 15), - arrow_vertical_offset: NumberType = 0, - blink_ms: NumberType = 0 + self, + margin_left: NumberType, + margin_right: NumberType, + margin_top: NumberType, + margin_bottom: NumberType, + arrow_size: Tuple2IntType = (10, 15), + arrow_vertical_offset: NumberType = 0, + blink_ms: NumberType = 0 ) -> None: super(ArrowSelection, self).__init__( margin_left=margin_left, @@ -74,12 +74,12 @@ def draw(self, surface: 'pygame.Surface', widget: 'pygame_menu.widgets.Widget') raise NotImplementedError('override is mandatory') def _draw_arrow( - self, - surface: 'pygame.Surface', - widget: 'pygame_menu.widgets.Widget', - a: Tuple2IntType, - b: Tuple2IntType, - c: Tuple2IntType + self, + surface: 'pygame.Surface', + widget: 'pygame_menu.widgets.Widget', + a: Tuple2IntType, + b: Tuple2IntType, + c: Tuple2IntType ) -> None: """ Draw the selection arrow. diff --git a/pygame_menu/widgets/selection/highlight.py b/pygame_menu/widgets/selection/highlight.py index 71284625..09ed4f90 100644 --- a/pygame_menu/widgets/selection/highlight.py +++ b/pygame_menu/widgets/selection/highlight.py @@ -31,10 +31,10 @@ class HighlightSelection(Selection): _border_width: int def __init__( - self, - border_width: int = 1, - margin_x: NumberType = 16, - margin_y: NumberType = 8 + self, + border_width: int = 1, + margin_x: NumberType = 16, + margin_y: NumberType = 8 ) -> None: assert isinstance(border_width, int) assert margin_x >= 0 and margin_y >= 0 diff --git a/pygame_menu/widgets/selection/left_arrow.py b/pygame_menu/widgets/selection/left_arrow.py index 7796e8da..9a724c1d 100644 --- a/pygame_menu/widgets/selection/left_arrow.py +++ b/pygame_menu/widgets/selection/left_arrow.py @@ -29,11 +29,11 @@ class LeftArrowSelection(ArrowSelection): _arrow_right_margin: int def __init__( - self, - arrow_size: Tuple2IntType = (10, 15), - arrow_right_margin: int = 5, - arrow_vertical_offset: int = 0, - blink_ms: NumberType = 0 + self, + arrow_size: Tuple2IntType = (10, 15), + arrow_right_margin: int = 5, + arrow_vertical_offset: int = 0, + blink_ms: NumberType = 0 ) -> None: assert isinstance(arrow_right_margin, NumberInstance) assert arrow_right_margin >= 0, 'margin cannot be negative' diff --git a/pygame_menu/widgets/selection/right_arrow.py b/pygame_menu/widgets/selection/right_arrow.py index 1ff9fff7..1dda5abf 100644 --- a/pygame_menu/widgets/selection/right_arrow.py +++ b/pygame_menu/widgets/selection/right_arrow.py @@ -29,11 +29,11 @@ class RightArrowSelection(ArrowSelection): _arrow_left_margin: int def __init__( - self, - arrow_size: Tuple2IntType = (10, 15), - arrow_left_margin: int = 3, - arrow_vertical_offset: int = 0, - blink_ms: NumberType = 0 + self, + arrow_size: Tuple2IntType = (10, 15), + arrow_left_margin: int = 3, + arrow_vertical_offset: int = 0, + blink_ms: NumberType = 0 ) -> None: assert isinstance(arrow_left_margin, NumberInstance) assert arrow_left_margin >= 0, 'margin cannot be negative' diff --git a/pygame_menu/widgets/widget/button.py b/pygame_menu/widgets/widget/button.py index 77f3a7a4..6ab0a8a0 100644 --- a/pygame_menu/widgets/widget/button.py +++ b/pygame_menu/widgets/widget/button.py @@ -52,12 +52,12 @@ class Button(Widget): to_menu: bool def __init__( - self, - title: Any, - button_id: str = '', - onreturn: CallbackType = None, - *args, - **kwargs + self, + title: Any, + button_id: str = '', + onreturn: CallbackType = None, + *args, + **kwargs ) -> None: super(Button, self).__init__( args=args, @@ -74,8 +74,8 @@ def _apply_font(self) -> None: pass def set_selection_callback( - self, - callback: Optional[Callable[[bool, 'Widget', 'pygame_menu.Menu'], Any]] + self, + callback: Optional[Callable[[bool, 'Widget', 'pygame_menu.Menu'], Any]] ) -> None: """ Update the button selection callback, once button is selected, the callback @@ -124,11 +124,11 @@ def update_callback(self, callback: Callable, *args) -> None: self._onreturn = callback def add_underline( - self, - color: ColorInputType, - offset: int, - width: int, - force_render: bool = False + self, + color: ColorInputType, + offset: int, + width: int, + force_render: bool = False ) -> 'Button': """ Adds an underline to text. This is added if widget is rendered. @@ -162,9 +162,7 @@ def _draw(self, surface: 'pygame.Surface') -> None: surface.blit(self._surface, self._rect.topleft) def _render(self) -> Optional[bool]: - if not self._render_hash_changed( - self._selected, self._title, self._visible, self.readonly, - self._last_underline[1]): + if not self._render_hash_changed(self._selected, self._title, self._visible, self.readonly, self._last_underline[1]): return True # Render surface @@ -202,10 +200,10 @@ def update(self, events: EventVectorType) -> bool: self._check_mouseover(event, rect) # User applies with key - if event.type == pygame.KEYDOWN and self._keyboard_enabled and \ - self._ctrl.apply(event, self) or \ - event.type == pygame.JOYBUTTONDOWN and self._joystick_enabled and \ - self._ctrl.joy_select(event, self): + if ( + event.type == pygame.KEYDOWN and self._keyboard_enabled and self._ctrl.apply(event, self) or + event.type == pygame.JOYBUTTONDOWN and self._joystick_enabled and self._ctrl.joy_select(event, self) + ): if self.to_menu: self._sound.play_open_menu() else: @@ -214,10 +212,10 @@ def update(self, events: EventVectorType) -> bool: return True # User clicks the button; don't consider the mouse wheel (button 4 & 5) - elif event.type == pygame.MOUSEBUTTONUP and self._mouse_enabled and \ - event.button in (1, 2, 3) or \ - event.type == FINGERUP and self._touchscreen_enabled and \ - self._menu is not None: + elif ( + event.type == pygame.MOUSEBUTTONUP and self._mouse_enabled and event.button in (1, 2, 3) or + event.type == FINGERUP and self._touchscreen_enabled and self._menu is not None + ): if event.type == pygame.MOUSEBUTTONUP: self._sound.play_click_mouse() else: @@ -238,11 +236,11 @@ class ButtonManager(AbstractWidgetManager, ABC): # noinspection PyProtectedMember def banner( - self, - image: 'pygame_menu.BaseImage', - action: Optional[Union['pygame_menu.Menu', '_events.MenuAction', Callable, int]] = None, - *args, - **kwargs + self, + image: 'pygame_menu.BaseImage', + action: Optional[Union['pygame_menu.Menu', '_events.MenuAction', Callable, int]] = None, + *args, + **kwargs ) -> 'pygame_menu.widgets.Button': """ Adds a clickeable image to the Menu with same behaviour as a Button. @@ -322,11 +320,11 @@ def banner( # noinspection PyProtectedMember def button( - self, - title: Any, - action: Optional[Union['pygame_menu.Menu', '_events.MenuAction', Callable, int]] = None, - *args, - **kwargs + self, + title: Any, + action: Optional[Union['pygame_menu.Menu', '_events.MenuAction', Callable, int]] = None, + *args, + **kwargs ) -> 'pygame_menu.widgets.Button': """ Adds a button to the Menu. @@ -511,10 +509,10 @@ def button( return widget def url( - self, - href: str, - title: str = '', - **kwargs + self, + href: str, + title: str = '', + **kwargs ) -> 'pygame_menu.widgets.Button': """ Adds a Button url to the Menu. Clicking the widget will open the link. diff --git a/pygame_menu/widgets/widget/colorinput.py b/pygame_menu/widgets/widget/colorinput.py index 06a10198..c8c4a105 100644 --- a/pygame_menu/widgets/widget/colorinput.py +++ b/pygame_menu/widgets/widget/colorinput.py @@ -106,27 +106,27 @@ class ColorInput(TextInput): _separator: str def __init__( - self, - title: Any, - colorinput_id: str = '', - color_type: ColorInputColorType = COLORINPUT_TYPE_RGB, - cursor_color: Tuple3IntType = (0, 0, 0), - cursor_switch_ms: NumberType = 500, - dynamic_width: bool = True, - hex_format: ColorInputHexFormatType = COLORINPUT_HEX_FORMAT_NONE, - input_separator: str = ',', - input_underline: str = '_', - input_underline_vmargin: int = 0, - onchange: CallbackType = None, - onreturn: CallbackType = None, - onselect: CallbackType = None, - prev_margin: int = 10, - prev_width_factor: NumberType = 3, - repeat_keys_initial_ms: NumberType = 450, - repeat_keys_interval_ms: NumberType = 80, - repeat_mouse_interval_ms: NumberType = 100, - *args, - **kwargs + self, + title: Any, + colorinput_id: str = '', + color_type: ColorInputColorType = COLORINPUT_TYPE_RGB, + cursor_color: Tuple3IntType = (0, 0, 0), + cursor_switch_ms: NumberType = 500, + dynamic_width: bool = True, + hex_format: ColorInputHexFormatType = COLORINPUT_HEX_FORMAT_NONE, + input_separator: str = ',', + input_underline: str = '_', + input_underline_vmargin: int = 0, + onchange: CallbackType = None, + onreturn: CallbackType = None, + onselect: CallbackType = None, + prev_margin: int = 10, + prev_width_factor: NumberType = 3, + repeat_keys_initial_ms: NumberType = 450, + repeat_keys_interval_ms: NumberType = 80, + repeat_mouse_interval_ms: NumberType = 100, + *args, + **kwargs ) -> None: assert isinstance(color_type, str) assert isinstance(colorinput_id, str) @@ -359,8 +359,7 @@ def _render(self) -> Optional[bool]: # Maybe TextInput did not render, so this has to be changed self._rect.width, self._rect.height = self._surface.get_size() - if not self._dynamic_width or \ - (self._dynamic_width and self._previsualization_surface is not None): + if not self._dynamic_width or (self._dynamic_width and self._previsualization_surface is not None): self._rect.width += self._prev_width_factor * self._rect.height + self._prev_margin # Render the previsualization box @@ -370,8 +369,7 @@ def _render(self) -> Optional[bool]: return render_text # If previsualization surface is None or the color changed - if self._last_r != r or self._last_b != b or self._last_g != g or \ - self._previsualization_surface is None: + if self._last_r != r or self._last_b != b or self._last_g != g or self._previsualization_surface is None: width = self._prev_width_factor * self._rect.height if width == 0 or self._rect.height == 0: self._previsualization_surface = None @@ -390,8 +388,7 @@ def _format_hex(self) -> None: """ Apply hex format. """ - if self._color_type != COLORINPUT_TYPE_HEX or \ - self._hex_format == COLORINPUT_HEX_FORMAT_NONE: + if self._color_type != COLORINPUT_TYPE_HEX or self._hex_format == COLORINPUT_HEX_FORMAT_NONE: return elif self._hex_format == COLORINPUT_HEX_FORMAT_LOWER: self._input_string = self._input_string.lower() @@ -420,16 +417,13 @@ def update(self, events: EventVectorType) -> bool: if self._ignores_keyboard_nonphysical() and not check_key_pressed_valid(event): continue - if disable_remove_separator and len(input_str) > 0 and \ - len(input_str) > cursor_pos and ( - f'{self._separator}{self._separator}' not in input_str or - input_str[cursor_pos] == self._separator and - len(input_str) == cursor_pos + 1 + if disable_remove_separator and len(input_str) > 0 and len(input_str) > cursor_pos and ( + f'{self._separator}{self._separator}' not in input_str or + input_str[cursor_pos] == self._separator and len(input_str) == cursor_pos + 1 ): # Backspace button, delete text from right if self._ctrl.back(event, self): - if len(input_str) >= 1 and \ - input_str[cursor_pos - 1] == self._separator: + if len(input_str) >= 1 and input_str[cursor_pos - 1] == self._separator: return True # Delete button, delete text from left @@ -442,9 +436,9 @@ def update(self, events: EventVectorType) -> bool: key = str(event.unicode) if key in self._valid_chars: new_string = ( - self._input_string[:self._cursor_position] - + key - + self._input_string[self._cursor_position:] + self._input_string[:self._cursor_position] + + key + + self._input_string[self._cursor_position:] ) # Cannot be separator at first @@ -493,7 +487,6 @@ def update(self, events: EventVectorType) -> bool: self._format_hex() for event in events: - # User writes if event.type == pygame.KEYDOWN and self._keyboard_enabled: # Check if any key is pressed @@ -530,11 +523,10 @@ def update(self, events: EventVectorType) -> bool: total_separator += 1 # Adds auto separator - if key == '0' and len(self._input_string) == self._cursor_position and \ - total_separator < 2 and \ - (len(self._input_string) == 1 or - (len(self._input_string) > 2 and self._input_string[ - self._cursor_position - 2] == self._separator)): + if key == '0' and len(self._input_string) == self._cursor_position and total_separator < 2 and ( + len(self._input_string) == 1 or + len(self._input_string) > 2 and self._input_string[self._cursor_position - 2] == self._separator + ): self._push_key_input(self._separator, sounds=False) # This calls .onchange() # Check number is valid (fix) because sometimes the user can type @@ -554,16 +546,18 @@ def update(self, events: EventVectorType) -> bool: if total_separator < 2 and len(self._input_string) == self._cursor_position: auto_pos = len(colors) - 1 last_num = colors[auto_pos] - if (len(last_num) == 2 and int(last_num) > 25 or len(last_num) == 3 and - int(last_num) <= 255) and \ - auto_pos not in self._auto_separator_pos: + if ( + ((len(last_num) == 2 and int(last_num) > 25) or (len(last_num) == 3 and int(last_num) <= 255)) and + auto_pos not in self._auto_separator_pos + ): self._push_key_input(self._separator, sounds=False) # This calls .onchange() self._auto_separator_pos.append(auto_pos) # If the user cleared all the string, reset auto separator - if total_separator == 0 and \ - (len(self._input_string) < 2 or len(self._input_string) == 2 and - int(colors[0]) <= 25): + if total_separator == 0 and ( + len(self._input_string) < 2 or + len(self._input_string) == 2 and int(colors[0]) <= 25 + ): self._auto_separator_pos = [] return updated @@ -575,18 +569,18 @@ class ColorInputManager(AbstractWidgetManager, ABC): """ def color_input( - self, - title: Union[str, Any], - color_type: ColorInputColorType, - color_id: str = '', - default: Union[str, Tuple3IntType] = '', - hex_format: ColorInputHexFormatType = COLORINPUT_HEX_FORMAT_NONE, - input_separator: str = ',', - input_underline: str = '_', - onchange: CallbackType = None, - onreturn: CallbackType = None, - onselect: Optional[Callable[[bool, 'Widget', 'pygame_menu.Menu'], Any]] = None, - **kwargs + self, + title: Union[str, Any], + color_type: ColorInputColorType, + color_id: str = '', + default: Union[str, Tuple3IntType] = '', + hex_format: ColorInputHexFormatType = COLORINPUT_HEX_FORMAT_NONE, + input_separator: str = ',', + input_underline: str = '_', + onchange: CallbackType = None, + onreturn: CallbackType = None, + onselect: Optional[Callable[[bool, 'Widget', 'pygame_menu.Menu'], Any]] = None, + **kwargs ) -> 'pygame_menu.widgets.ColorInput': """ Add a color widget with RGB or HEX format to the Menu. diff --git a/pygame_menu/widgets/widget/dropselect.py b/pygame_menu/widgets/widget/dropselect.py index 4e347452..1a243320 100644 --- a/pygame_menu/widgets/widget/dropselect.py +++ b/pygame_menu/widgets/widget/dropselect.py @@ -150,50 +150,50 @@ class DropSelect(Widget): _title_size: Tuple2IntType def __init__( - self, - title: Any, - items: Union[List[Tuple[Any, ...]], List[str]], - dropselect_id: str = '', - default: Optional[int] = None, - onchange: CallbackType = None, - onreturn: CallbackType = None, - onselect: CallbackType = None, - open_middle: bool = False, - placeholder: str = 'Select an option', - placeholder_add_to_selection_box: bool = True, - scrollbar_color: ColorInputType = (235, 235, 235), - scrollbar_cursor: CursorInputType = None, - scrollbar_shadow: bool = False, - scrollbar_shadow_color: ColorInputType = (0, 0, 0), - scrollbar_shadow_offset: int = 2, - scrollbar_shadow_position: str = POSITION_NORTHWEST, - scrollbar_slider_color: ColorInputType = (200, 200, 200), - scrollbar_slider_hover_color: ColorInputType = (170, 170, 170), - scrollbar_slider_pad: NumberType = 0, - scrollbar_thick: int = 20, - scrollbars: str = POSITION_SOUTHEAST, - selection_box_arrow_color: ColorInputType = (150, 150, 150), - selection_box_arrow_margin: Tuple3IntType = (5, 5, 0), - selection_box_bgcolor: ColorInputType = (255, 255, 255), - selection_box_border_color: ColorInputType = (150, 150, 150), - selection_box_border_width: int = 1, - selection_box_height: int = 3, - selection_box_inflate: Tuple2IntType = (0, 0), - selection_box_margin: Tuple2NumberType = (25, 0), - selection_box_text_margin: int = 5, - selection_box_width: int = 0, - selection_infinite: bool = False, - selection_option_border_color: ColorInputType = (220, 220, 220), - selection_option_border_width: int = 1, - selection_option_cursor: CursorInputType = None, - selection_option_font: Optional[FontType] = None, - selection_option_font_color: ColorInputType = (0, 0, 0), - selection_option_font_size: Optional[int] = None, - selection_option_padding: PaddingType = 5, - selection_option_selected_bgcolor: ColorInputType = (188, 227, 244), - selection_option_selected_font_color: ColorInputType = (0, 0, 0), - *args, - **kwargs + self, + title: Any, + items: Union[List[Tuple[Any, ...]], List[str]], + dropselect_id: str = '', + default: Optional[int] = None, + onchange: CallbackType = None, + onreturn: CallbackType = None, + onselect: CallbackType = None, + open_middle: bool = False, + placeholder: str = 'Select an option', + placeholder_add_to_selection_box: bool = True, + scrollbar_color: ColorInputType = (235, 235, 235), + scrollbar_cursor: CursorInputType = None, + scrollbar_shadow: bool = False, + scrollbar_shadow_color: ColorInputType = (0, 0, 0), + scrollbar_shadow_offset: int = 2, + scrollbar_shadow_position: str = POSITION_NORTHWEST, + scrollbar_slider_color: ColorInputType = (200, 200, 200), + scrollbar_slider_hover_color: ColorInputType = (170, 170, 170), + scrollbar_slider_pad: NumberType = 0, + scrollbar_thick: int = 20, + scrollbars: str = POSITION_SOUTHEAST, + selection_box_arrow_color: ColorInputType = (150, 150, 150), + selection_box_arrow_margin: Tuple3IntType = (5, 5, 0), + selection_box_bgcolor: ColorInputType = (255, 255, 255), + selection_box_border_color: ColorInputType = (150, 150, 150), + selection_box_border_width: int = 1, + selection_box_height: int = 3, + selection_box_inflate: Tuple2IntType = (0, 0), + selection_box_margin: Tuple2NumberType = (25, 0), + selection_box_text_margin: int = 5, + selection_box_width: int = 0, + selection_infinite: bool = False, + selection_option_border_color: ColorInputType = (220, 220, 220), + selection_option_border_width: int = 1, + selection_option_cursor: CursorInputType = None, + selection_option_font: Optional[FontType] = None, + selection_option_font_color: ColorInputType = (0, 0, 0), + selection_option_font_size: Optional[int] = None, + selection_option_padding: PaddingType = 5, + selection_option_selected_bgcolor: ColorInputType = (188, 227, 244), + selection_option_selected_font_color: ColorInputType = (0, 0, 0), + *args, + **kwargs ) -> None: assert isinstance(default, (int, type(None))) assert isinstance(dropselect_id, str) @@ -716,11 +716,9 @@ def _render(self) -> Optional[bool]: menu_height = 0 if self._menu is None else self._menu.get_height(widget=True) current_selected = self._get_current_selected_text() - if not self._render_hash_changed( - current_selected, self._selected, self._visible, self._index, - self.readonly, self.active, self._open_bottom, scroll_v, - menu_height, self._open_middle, len(self._items), self._rect.x, - self._rect.y): + if not self._render_hash_changed(current_selected, self._selected, self._visible, self._index, + self.readonly, self.active, self._open_bottom, scroll_v, + menu_height, self._open_middle, len(self._items), self._rect.x, self._rect.y): return True title = self._render_string(self._title, self.get_font_color_status()) @@ -1111,18 +1109,22 @@ def update(self, events: EventVectorType) -> bool: joy_button_down = self._joystick_enabled and event.type == pygame.JOYBUTTONDOWN # Left button - if keydown and self._ctrl.move_down(event, self) or \ - joy_hatmotion and self._ctrl.joy_left(event, self) or \ - joy_axismotion and self._ctrl.joy_axis_x_left(event, self): + if ( + keydown and self._ctrl.move_down(event, self) or + joy_hatmotion and self._ctrl.joy_left(event, self) or + joy_axismotion and self._ctrl.joy_axis_x_left(event, self) + ): if not self.active: continue self._down() return True # Right button - elif keydown and self._ctrl.move_up(event, self) or \ - joy_hatmotion and self._ctrl.joy_right(event, self) or \ - joy_axismotion and self._ctrl.joy_axis_x_right(event, self): + elif ( + keydown and self._ctrl.move_up(event, self) or + joy_hatmotion and self._ctrl.joy_right(event, self) or + joy_axismotion and self._ctrl.joy_axis_x_right(event, self) + ): if not self.active: continue self._up() @@ -1150,21 +1152,18 @@ def update(self, events: EventVectorType) -> bool: # Click on dropselect; don't consider the mouse wheel (button 4 & 5) elif self.active and ( - event.type == pygame.MOUSEBUTTONDOWN and self._mouse_enabled and - event.button in (1, 2, 3) or - event.type == FINGERDOWN and self._touchscreen_enabled and - self._menu is not None and not self._drop_frame_scrolling() + event.type == pygame.MOUSEBUTTONDOWN and self._mouse_enabled and event.button in (1, 2, 3) or + event.type == FINGERDOWN and self._touchscreen_enabled and self._menu is not None and not self._drop_frame_scrolling() ): event_pos = get_finger_pos(self._menu, event) if self._drop_frame.get_rect(apply_padding=False, to_real_position=True).collidepoint(*event_pos): return True # Click on dropselect; don't consider the mouse wheel (button 4 & 5) - elif event.type == pygame.MOUSEBUTTONUP and self._mouse_enabled and \ - event.button in (1, 2, 3) or \ - event.type == FINGERUP and self._touchscreen_enabled and \ - self._menu is not None and not self._drop_frame_scrolling(): - + elif ( + event.type == pygame.MOUSEBUTTONUP and self._mouse_enabled and event.button in (1, 2, 3) or + event.type == FINGERUP and self._touchscreen_enabled and self._menu is not None and not self._drop_frame_scrolling() + ): # Check for mouse clicks within if self.active: for btn in self._option_buttons: @@ -1218,18 +1217,18 @@ class DropSelectManager(AbstractWidgetManager, ABC): """ def dropselect( - self, - title: Any, - items: Union[List[Tuple[Any, ...]], List[str]], - default: Optional[int] = None, - dropselect_id: str = '', - onchange: CallbackType = None, - onreturn: CallbackType = None, - onselect: Optional[Callable[[bool, 'Widget', 'pygame_menu.Menu'], Any]] = None, - open_middle: bool = False, - placeholder: str = 'Select an option', - placeholder_add_to_selection_box: bool = True, - **kwargs + self, + title: Any, + items: Union[List[Tuple[Any, ...]], List[str]], + default: Optional[int] = None, + dropselect_id: str = '', + onchange: CallbackType = None, + onreturn: CallbackType = None, + onselect: Optional[Callable[[bool, 'Widget', 'pygame_menu.Menu'], Any]] = None, + open_middle: bool = False, + placeholder: str = 'Select an option', + placeholder_add_to_selection_box: bool = True, + **kwargs ) -> 'pygame_menu.widgets.DropSelect': """ Add a dropselect to the Menu: Drop select is a selector within a Frame. diff --git a/pygame_menu/widgets/widget/dropselect_multiple.py b/pygame_menu/widgets/widget/dropselect_multiple.py index 8555c548..6e812007 100644 --- a/pygame_menu/widgets/widget/dropselect_multiple.py +++ b/pygame_menu/widgets/widget/dropselect_multiple.py @@ -136,60 +136,60 @@ class DropSelectMultiple(DropSelect): _selection_placeholder_format: DropSelectMultipleSFormatType def __init__( - self, - title: Any, - items: Union[List[Tuple[Any, ...]], List[str]], - dropselect_id: str = '', - default: Optional[Union[int, List[int]]] = None, - max_selected: int = 0, - onchange: CallbackType = None, - onreturn: CallbackType = None, - onselect: CallbackType = None, - open_middle: bool = False, - placeholder: str = 'Select an option', - placeholder_add_to_selection_box: bool = True, - placeholder_selected: str = '{0} selected', - scrollbar_color: ColorInputType = (235, 235, 235), - scrollbar_cursor: CursorInputType = None, - scrollbar_shadow: bool = False, - scrollbar_shadow_color: ColorInputType = (0, 0, 0), - scrollbar_shadow_offset: int = 2, - scrollbar_shadow_position: str = POSITION_NORTHWEST, - scrollbar_slider_color: ColorInputType = (200, 200, 200), - scrollbar_slider_hover_color: ColorInputType = (170, 170, 170), - scrollbar_slider_pad: NumberType = 0, - scrollbar_thick: int = 20, - scrollbars: str = POSITION_SOUTHEAST, - selection_box_arrow_color: ColorInputType = (150, 150, 150), - selection_box_arrow_margin: Tuple3IntType = (5, 5, 0), - selection_box_bgcolor: ColorInputType = (255, 255, 255), - selection_box_border_color: ColorInputType = (150, 150, 150), - selection_box_border_width: int = 1, - selection_box_height: int = 3, - selection_box_inflate: Tuple2IntType = (0, 0), - selection_box_margin: Tuple2NumberType = (25, 0), - selection_box_text_margin: int = 5, - selection_box_width: int = 0, - selection_infinite: bool = False, - selection_option_active_bgcolor: ColorInputType = (188, 227, 244), - selection_option_active_font_color: ColorInputType = (0, 0, 0), - selection_option_border_color: ColorInputType = (220, 220, 220), - selection_option_border_width: int = 1, - selection_option_cursor: CursorInputType = None, - selection_option_font: Optional[FontType] = None, - selection_option_font_color: ColorInputType = (0, 0, 0), - selection_option_font_size: Optional[int] = None, - selection_option_padding: PaddingType = 5, - selection_option_selected_bgcolor: ColorInputType = (142, 247, 141), - selection_option_selected_box: bool = True, - selection_option_selected_box_border: int = 1, - selection_option_selected_box_color: ColorInputType = (150, 150, 150), - selection_option_selected_box_height: float = 0.5, - selection_option_selected_box_margin: Tuple3IntType = (0, 5, 0), - selection_option_selected_font_color: ColorInputType = (0, 0, 0), - selection_placeholder_format: DropSelectMultipleSFormatType = DROPSELECT_MULTIPLE_SFORMAT_TOTAL, - *args, - **kwargs + self, + title: Any, + items: Union[List[Tuple[Any, ...]], List[str]], + dropselect_id: str = '', + default: Optional[Union[int, List[int]]] = None, + max_selected: int = 0, + onchange: CallbackType = None, + onreturn: CallbackType = None, + onselect: CallbackType = None, + open_middle: bool = False, + placeholder: str = 'Select an option', + placeholder_add_to_selection_box: bool = True, + placeholder_selected: str = '{0} selected', + scrollbar_color: ColorInputType = (235, 235, 235), + scrollbar_cursor: CursorInputType = None, + scrollbar_shadow: bool = False, + scrollbar_shadow_color: ColorInputType = (0, 0, 0), + scrollbar_shadow_offset: int = 2, + scrollbar_shadow_position: str = POSITION_NORTHWEST, + scrollbar_slider_color: ColorInputType = (200, 200, 200), + scrollbar_slider_hover_color: ColorInputType = (170, 170, 170), + scrollbar_slider_pad: NumberType = 0, + scrollbar_thick: int = 20, + scrollbars: str = POSITION_SOUTHEAST, + selection_box_arrow_color: ColorInputType = (150, 150, 150), + selection_box_arrow_margin: Tuple3IntType = (5, 5, 0), + selection_box_bgcolor: ColorInputType = (255, 255, 255), + selection_box_border_color: ColorInputType = (150, 150, 150), + selection_box_border_width: int = 1, + selection_box_height: int = 3, + selection_box_inflate: Tuple2IntType = (0, 0), + selection_box_margin: Tuple2NumberType = (25, 0), + selection_box_text_margin: int = 5, + selection_box_width: int = 0, + selection_infinite: bool = False, + selection_option_active_bgcolor: ColorInputType = (188, 227, 244), + selection_option_active_font_color: ColorInputType = (0, 0, 0), + selection_option_border_color: ColorInputType = (220, 220, 220), + selection_option_border_width: int = 1, + selection_option_cursor: CursorInputType = None, + selection_option_font: Optional[FontType] = None, + selection_option_font_color: ColorInputType = (0, 0, 0), + selection_option_font_size: Optional[int] = None, + selection_option_padding: PaddingType = 5, + selection_option_selected_bgcolor: ColorInputType = (142, 247, 141), + selection_option_selected_box: bool = True, + selection_option_selected_box_border: int = 1, + selection_option_selected_box_color: ColorInputType = (150, 150, 150), + selection_option_selected_box_height: float = 0.5, + selection_option_selected_box_margin: Tuple3IntType = (0, 5, 0), + selection_option_selected_font_color: ColorInputType = (0, 0, 0), + selection_placeholder_format: DropSelectMultipleSFormatType = DROPSELECT_MULTIPLE_SFORMAT_TOTAL, + *args, + **kwargs ) -> None: super(DropSelectMultiple, self).__init__( dropselect_id=dropselect_id, @@ -275,9 +275,11 @@ def get_index(self) -> List[int]: def _render_option_string(self, text: str) -> 'pygame.Surface': color = self._selection_option_font_style['color'] - if self.readonly or \ - len(self._selected_indices) == 0 or \ - self._max_selected != 0 and len(self._selected_indices) == self._max_selected: + if ( + self.readonly or + len(self._selected_indices) == 0 or + self._max_selected != 0 and len(self._selected_indices) == self._max_selected + ): color = self._font_readonly_color text = text.replace('\t', ' ' * self._tab_size) return self._option_font.render(text, self._font_antialias, color) @@ -536,21 +538,21 @@ class DropSelectMultipleManager(AbstractWidgetManager, ABC): """ def dropselect_multiple( - self, - title: Any, - items: Union[List[Tuple[Any, ...]], List[str]], - default: Optional[Union[int, List[int]]] = None, - dropselect_multiple_id: str = '', - max_selected: int = 0, - onchange: CallbackType = None, - onreturn: CallbackType = None, - onselect: Optional[Callable[[bool, 'Widget', 'pygame_menu.Menu'], Any]] = None, - open_middle: bool = False, - placeholder: str = 'Select an option', - placeholder_add_to_selection_box: bool = True, - placeholder_selected: str = '{0} selected', - selection_placeholder_format: DropSelectMultipleSFormatType = DROPSELECT_MULTIPLE_SFORMAT_TOTAL, - **kwargs + self, + title: Any, + items: Union[List[Tuple[Any, ...]], List[str]], + default: Optional[Union[int, List[int]]] = None, + dropselect_multiple_id: str = '', + max_selected: int = 0, + onchange: CallbackType = None, + onreturn: CallbackType = None, + onselect: Optional[Callable[[bool, 'Widget', 'pygame_menu.Menu'], Any]] = None, + open_middle: bool = False, + placeholder: str = 'Select an option', + placeholder_add_to_selection_box: bool = True, + placeholder_selected: str = '{0} selected', + selection_placeholder_format: DropSelectMultipleSFormatType = DROPSELECT_MULTIPLE_SFORMAT_TOTAL, + **kwargs ) -> 'pygame_menu.widgets.DropSelectMultiple': """ Add a dropselect multiple to the Menu: Drop select multiple is a drop diff --git a/pygame_menu/widgets/widget/frame.py b/pygame_menu/widgets/widget/frame.py index 51d1c2a7..8ce5f938 100644 --- a/pygame_menu/widgets/widget/frame.py +++ b/pygame_menu/widgets/widget/frame.py @@ -124,11 +124,11 @@ class Frame(Widget): last_index: int # Last selectable widget index def __init__( - self, - width: NumberType, - height: NumberType, - orientation: str, - frame_id: str = '' + self, + width: NumberType, + height: NumberType, + orientation: str, + frame_id: str = '' ) -> None: super(Frame, self).__init__(widget_id=frame_id) assert isinstance(width, NumberInstance) @@ -172,18 +172,18 @@ def __init__( self.last_index = -1 def set_title( - self, - title: str, - cursor: CursorInputType = None, - background_color: FrameTitleBackgroundColorType = FRAME_DEFAULT_TITLE_BACKGROUND_COLOR, - draggable: bool = False, - padding_inner: PaddingType = 0, - padding_outer: PaddingType = 0, - title_alignment: str = ALIGN_LEFT, - title_buttons_alignment: str = ALIGN_RIGHT, - title_font: Optional[FontType] = None, - title_font_color: Optional[ColorInputType] = None, - title_font_size: Optional[int] = None + self, + title: str, + cursor: CursorInputType = None, + background_color: FrameTitleBackgroundColorType = FRAME_DEFAULT_TITLE_BACKGROUND_COLOR, + draggable: bool = False, + padding_inner: PaddingType = 0, + padding_outer: PaddingType = 0, + title_alignment: str = ALIGN_LEFT, + title_buttons_alignment: str = ALIGN_RIGHT, + title_font: Optional[FontType] = None, + title_font_color: Optional[ColorInputType] = None, + title_font_size: Optional[int] = None ) -> 'Frame': """ Add a title to the frame. @@ -367,9 +367,9 @@ def remove_title(self) -> 'Frame': return self def add_title_generic_button( - self, - button: 'Button', - margin: Vector2NumberType = (0, 0) + self, + button: 'Button', + margin: Vector2NumberType = (0, 0) ) -> 'Frame': """ Add button to title. Button kwargs receive the ``button`` reference and @@ -419,15 +419,15 @@ def add_title_generic_button( return self def add_title_button( - self, - style: FrameTitleButtonType, - callback: CallbackType, - background_color: ColorInputType = (150, 150, 150), - cursor: CursorInputType = CURSOR_HAND, - margin: Vector2NumberType = (4, 0), - symbol_color: ColorInputType = (0, 0, 0), - symbol_height: NumberType = 0.75, - symbol_margin: int = 4 + self, + style: FrameTitleButtonType, + callback: CallbackType, + background_color: ColorInputType = (150, 150, 150), + cursor: CursorInputType = CURSOR_HAND, + margin: Vector2NumberType = (4, 0), + symbol_color: ColorInputType = (0, 0, 0), + symbol_height: NumberType = 0.75, + symbol_margin: int = 4 ) -> 'Button': """ Add predefined button to title. The button kwargs receive the ``button`` @@ -615,21 +615,21 @@ def get_max_size(self) -> Tuple2IntType: return self.get_size() def make_scrollarea( - self, - max_width: Optional[NumberType], - max_height: Optional[NumberType], - scrollarea_color: Optional[Union[ColorInputType, 'pygame_menu.BaseImage']], - scrollbar_color: ColorInputType, - scrollbar_cursor: CursorInputType, - scrollbar_shadow: bool, - scrollbar_shadow_color: ColorInputType, - scrollbar_shadow_offset: int, - scrollbar_shadow_position: str, - scrollbar_slider_color: ColorInputType, - scrollbar_slider_hover_color: ColorInputType, - scrollbar_slider_pad: NumberType, - scrollbar_thick: NumberType, - scrollbars: Union[str, Tuple[str, ...]] + self, + max_width: Optional[NumberType], + max_height: Optional[NumberType], + scrollarea_color: Optional[Union[ColorInputType, 'pygame_menu.BaseImage']], + scrollbar_color: ColorInputType, + scrollbar_cursor: CursorInputType, + scrollbar_shadow: bool, + scrollbar_shadow_color: ColorInputType, + scrollbar_shadow_offset: int, + scrollbar_shadow_position: str, + scrollbar_slider_color: ColorInputType, + scrollbar_slider_hover_color: ColorInputType, + scrollbar_slider_pad: NumberType, + scrollbar_thick: NumberType, + scrollbars: Union[str, Tuple[str, ...]] ) -> 'Frame': """ Make the scrollarea of the frame. @@ -1096,10 +1096,10 @@ def update_position(self) -> 'Frame': return self def get_widgets( - self, - unpack_subframes: bool = True, - unpack_subframes_include_frame: bool = False, - reverse: bool = False + self, + unpack_subframes: bool = True, + unpack_subframes_include_frame: bool = False, + reverse: bool = False ) -> Tuple['Widget', ...]: """ Get widgets as a tuple. @@ -1139,11 +1139,11 @@ def clear(self) -> Union['Widget', Tuple['Widget', ...]]: return tuple(unpacked) def resize( - self, - width: NumberType, - height: NumberType, - max_width: Optional[NumberType] = None, - max_height: Optional[NumberType] = None + self, + width: NumberType, + height: NumberType, + max_width: Optional[NumberType] = None, + max_height: Optional[NumberType] = None ) -> 'Frame': """ Resize the Frame. @@ -1421,11 +1421,11 @@ def unpack(self, widget: 'Widget') -> 'Frame': return widget def pack( - self, - widget: Union['Widget', List['Widget'], Tuple['Widget', ...]], - align: str = ALIGN_LEFT, - vertical_position: str = POSITION_NORTH, - margin: Vector2NumberType = (0, 0) + self, + widget: Union['Widget', List['Widget'], Tuple['Widget', ...]], + align: str = ALIGN_LEFT, + vertical_position: str = 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 @@ -1562,9 +1562,7 @@ def pack( # Check for last if w_last is frame while True: - if not (isinstance(w_last, Frame) and - w_last.get_indices() != (-1, -1)) or \ - w_last.get_menu() is None: + if not (isinstance(w_last, Frame) and w_last.get_indices() != (-1, -1)) or w_last.get_menu() is None: break w_last = menu_widgets[w_last.last_index] @@ -1676,8 +1674,7 @@ def _update_indices(self) -> None: self.first_index = -1 self.last_index = -1 for widget in self.get_widgets(unpack_subframes=False): - if (widget.is_selectable or isinstance(widget, Frame)) and \ - widget.get_menu() is not None: + if (widget.is_selectable or isinstance(widget, Frame)) and widget.get_menu() is not None: if isinstance(widget, Frame) and widget.get_indices() == (-1, -1): continue # Frames with not selectable indices are not counted windex = widget.get_col_row_index()[2] @@ -1711,9 +1708,10 @@ def update(self, events: EventVectorType) -> bool: self._frame_title._check_mouseover(event) # If clicked in title - if (event.type == pygame.MOUSEBUTTONDOWN and self._mouse_enabled and event.button in - (1, 2, 3) or event.type == FINGERDOWN and self._touchscreen_enabled and self._menu is not None) and \ - self._draggable: + if self._draggable and ( + event.type == pygame.MOUSEBUTTONDOWN and self._mouse_enabled and event.button in (1, 2, 3) or + event.type == FINGERDOWN and self._touchscreen_enabled and self._menu is not None + ): event_pos = get_finger_pos(self._menu, event) if self._frame_title.get_rect(to_real_position=True).collidepoint(*event_pos): @@ -1722,9 +1720,10 @@ def update(self, events: EventVectorType) -> bool: updated = True # User releases the button - elif event.type == pygame.MOUSEBUTTONUP and self._mouse_enabled and \ - event.button in (1, 2, 3) or \ - event.type == FINGERUP and self._touchscreen_enabled: + elif ( + event.type == pygame.MOUSEBUTTONUP and self._mouse_enabled and event.button in (1, 2, 3) or + event.type == FINGERUP and self._touchscreen_enabled + ): self._frame_title.set_attribute('drag', False) # Mouse out from window @@ -1734,8 +1733,10 @@ def update(self, events: EventVectorType) -> bool: # break # User moves the mouse while drag - elif event.type == pygame.MOUSEMOTION and hasattr(event, 'rel') or \ - event.type == FINGERMOTION and self._touchscreen_enabled and self._menu is not None: + elif ( + event.type == pygame.MOUSEMOTION and hasattr(event, 'rel') or + event.type == FINGERMOTION and self._touchscreen_enabled and self._menu is not None + ): if self._frame_title.get_attribute('drag', False) and self._draggable: # Get relative movement @@ -1814,12 +1815,12 @@ class FrameManager(AbstractWidgetManager, ABC): """ def _frame( - self, - width: NumberType, - height: NumberType, - orientation: str, - frame_id: str = '', - **kwargs + self, + width: NumberType, + height: NumberType, + orientation: str, + frame_id: str = '', + **kwargs ) -> 'pygame_menu.widgets.Frame': """ Adds a frame to the Menu. @@ -1889,11 +1890,11 @@ def _frame( return widget def frame_h( - self, - width: NumberType, - height: NumberType, - frame_id: str = '', - **kwargs + self, + width: NumberType, + height: NumberType, + frame_id: str = '', + **kwargs ) -> 'pygame_menu.widgets.Frame': """ Adds a horizontal frame to the Menu. Frame is a widget container that @@ -1987,11 +1988,11 @@ def frame_h( return self._frame(width, height, ORIENTATION_HORIZONTAL, frame_id, **kwargs) def frame_v( - self, - width: NumberType, - height: NumberType, - frame_id: str = '', - **kwargs + self, + width: NumberType, + height: NumberType, + frame_id: str = '', + **kwargs ) -> 'pygame_menu.widgets.Frame': """ Adds a vertical frame to the Menu. Frame is a widget container that packs diff --git a/pygame_menu/widgets/widget/hmargin.py b/pygame_menu/widgets/widget/hmargin.py index beabe6dd..8570d5cc 100644 --- a/pygame_menu/widgets/widget/hmargin.py +++ b/pygame_menu/widgets/widget/hmargin.py @@ -35,9 +35,9 @@ class HMargin(NoneWidget): """ def __init__( - self, - margin: NumberType, - widget_id: str = '' + self, + margin: NumberType, + widget_id: str = '' ) -> None: assert isinstance(margin, NumberInstance) assert margin > 0, \ @@ -56,9 +56,9 @@ class HMarginManager(AbstractWidgetManager, ABC): """ def horizontal_margin( - self, - margin: NumberType, - margin_id: str = '' + self, + margin: NumberType, + margin_id: str = '' ) -> 'pygame_menu.widgets.HMargin': """ Adds a horizontal margin to the Menu. Only useful in frames. diff --git a/pygame_menu/widgets/widget/image.py b/pygame_menu/widgets/widget/image.py index 3bddb6ce..f60bd08e 100644 --- a/pygame_menu/widgets/widget/image.py +++ b/pygame_menu/widgets/widget/image.py @@ -45,13 +45,13 @@ class Image(Widget): _image: 'BaseImage' def __init__( - self, - image_path: Union[str, 'BaseImage', 'Path', 'BytesIO'], - angle: NumberType = 0, - image_id: str = '', - onselect: CallbackType = None, - scale: Tuple2NumberType = (1, 1), - scale_smooth: bool = True + self, + image_path: Union[str, 'BaseImage', 'Path', 'BytesIO'], + angle: NumberType = 0, + image_id: str = '', + onselect: CallbackType = None, + scale: Tuple2NumberType = (1, 1), + scale_smooth: bool = True ) -> None: assert isinstance(image_path, (str, Path, BaseImage, BytesIO)) assert isinstance(image_id, str) @@ -181,15 +181,15 @@ class ImageManager(AbstractWidgetManager, ABC): """ def image( - self, - image_path: Union[str, 'Path', 'pygame_menu.BaseImage', 'BytesIO'], - angle: NumberType = 0, - image_id: str = '', - onselect: Optional[Callable[[bool, 'Widget', 'pygame_menu.Menu'], Any]] = None, - scale: Vector2NumberType = (1, 1), - scale_smooth: bool = True, - selectable: bool = False, - **kwargs + self, + image_path: Union[str, 'Path', 'pygame_menu.BaseImage', 'BytesIO'], + angle: NumberType = 0, + image_id: str = '', + onselect: Optional[Callable[[bool, 'Widget', 'pygame_menu.Menu'], Any]] = None, + scale: Vector2NumberType = (1, 1), + scale_smooth: bool = True, + selectable: bool = False, + **kwargs ) -> 'pygame_menu.widgets.Image': """ Add a simple image to the Menu. diff --git a/pygame_menu/widgets/widget/label.py b/pygame_menu/widgets/widget/label.py index f3755e21..9c6c9518 100644 --- a/pygame_menu/widgets/widget/label.py +++ b/pygame_menu/widgets/widget/label.py @@ -51,13 +51,13 @@ class Label(Widget): _wordwrap: bool def __init__( - self, - title: Any, - label_id: str = '', - onselect: CallbackType = None, - wordwrap: bool = False, - leading: Optional[int] = None, - max_nlines: Optional[int] = None + self, + title: Any, + label_id: str = '', + onselect: CallbackType = None, + wordwrap: bool = False, + leading: Optional[int] = None, + max_nlines: Optional[int] = None ) -> None: assert isinstance(leading, (type(None), int)) assert isinstance(max_nlines, (type(None), int)) @@ -75,11 +75,11 @@ def __init__( self._wordwrap = wordwrap def add_underline( - self, - color: ColorInputType, - offset: int, - width: int, - force_render: bool = False + self, + color: ColorInputType, + offset: int, + width: int, + force_render: bool = False ) -> 'Label': """ Adds an underline to text. This is added if widget is rendered. Underline @@ -176,10 +176,10 @@ def get_lines(self) -> List[str]: @staticmethod def _wordwrap_line( - line: str, - font: pygame.font.Font, - max_width: int, - tab_size: int, + line: str, + font: pygame.font.Font, + max_width: int, + tab_size: int, ) -> List[str]: """ Wordwraps line. @@ -242,9 +242,8 @@ def get_overflow_lines(self) -> List[str]: return self._overflow_lines def _render(self) -> Optional[bool]: - if not self._render_hash_changed( - self._title, self._font_color, self._visible, self._menu, self._font, - self._last_underline[1], self._padding, self._selection_effect.get_width()): + if not self._render_hash_changed(self._title, self._font_color, self._visible, self._menu, self._font, + self._last_underline[1], self._padding, self._selection_effect.get_width()): return True self._lines = [] @@ -342,14 +341,14 @@ class LabelManager(AbstractWidgetManager, ABC): # noinspection PyProtectedMember def label( - self, - title: Any, - label_id: str = '', - max_char: int = 0, - onselect: Optional[Callable[[bool, 'Widget', 'pygame_menu.Menu'], Any]] = None, - selectable: bool = False, - wordwrap: bool = False, - **kwargs + self, + title: Any, + label_id: str = '', + max_char: int = 0, + onselect: Optional[Callable[[bool, 'Widget', 'pygame_menu.Menu'], Any]] = None, + selectable: bool = False, + wordwrap: bool = False, + **kwargs ) -> Union['pygame_menu.widgets.Label', List['pygame_menu.widgets.Label']]: """ Add a simple text to the Menu. @@ -506,14 +505,14 @@ def label( return widget def clock( - self, - clock_format: str = '%Y/%m/%d %H:%M:%S', - clock_id: str = '', - onselect: Optional[Callable[[bool, 'Widget', 'pygame_menu.Menu'], Any]] = None, - selectable: bool = False, - title_format: str = '{0}', - wordwrap: bool = False, - **kwargs + self, + clock_format: str = '%Y/%m/%d %H:%M:%S', + clock_id: str = '', + onselect: Optional[Callable[[bool, 'Widget', 'pygame_menu.Menu'], Any]] = None, + selectable: bool = False, + title_format: str = '{0}', + wordwrap: bool = False, + **kwargs ) -> 'pygame_menu.widgets.Label': """ Add a clock label to the Menu. This creates a Label with a text generator diff --git a/pygame_menu/widgets/widget/menubar.py b/pygame_menu/widgets/widget/menubar.py index 408de891..d0274db5 100644 --- a/pygame_menu/widgets/widget/menubar.py +++ b/pygame_menu/widgets/widget/menubar.py @@ -101,20 +101,20 @@ class MenuBar(Widget): fixed: bool def __init__( - self, - title: Any, - width: NumberType, - background_color: ColorInputType, - menubar_id: str = '', - back_box: bool = False, - back_box_background_color: ColorInputType = (0, 0, 0), - mode: MenuBarStyleModeType = MENUBAR_STYLE_ADAPTIVE, - modify_scrollarea: bool = True, - offsetx: NumberType = 0, - offsety: NumberType = 0, - onreturn: CallbackType = None, - *args, - **kwargs + self, + title: Any, + width: NumberType, + background_color: ColorInputType, + menubar_id: str = '', + back_box: bool = False, + back_box_background_color: ColorInputType = (0, 0, 0), + mode: MenuBarStyleModeType = MENUBAR_STYLE_ADAPTIVE, + modify_scrollarea: bool = True, + offsetx: NumberType = 0, + offsety: NumberType = 0, + onreturn: CallbackType = None, + *args, + **kwargs ) -> None: assert isinstance(width, NumberInstance) assert isinstance(back_box, bool) @@ -300,9 +300,8 @@ def _render(self) -> Optional[bool]: # noinspection PyProtectedMember menu_prev_condition = not self._menu or not self._menu._top or not self._menu._top._prev - if not self._render_hash_changed( - self._menu.get_id(), self._rect.x, self._rect.y, self._title, self._width, - self._visible, self._font_selected_color, menu_prev_condition): + if not self._render_hash_changed(self._menu.get_id(), self._rect.x, self._rect.y, self._title, self._width, + self._visible, self._font_selected_color, menu_prev_condition): return True # Update box mode @@ -529,10 +528,10 @@ def update(self, events: EventVectorType) -> bool: self._check_mouseover(event) # User clicks/touches the backbox rect; don't consider the mouse wheel (button 4 & 5) - if event.type == pygame.MOUSEBUTTONUP and self._mouse_enabled and \ - event.button in (1, 2, 3) or \ - event.type == FINGERUP and self._touchscreen_enabled and \ - self._menu is not None: + if ( + event.type == pygame.MOUSEBUTTONUP and self._mouse_enabled and event.button in (1, 2, 3) or + event.type == FINGERUP and self._touchscreen_enabled and self._menu is not None + ): event_pos = get_finger_pos(self._menu, event) if self._backbox_visible() and self._backbox_rect.collidepoint(*event_pos): if event.type == pygame.MOUSEBUTTONUP: diff --git a/pygame_menu/widgets/widget/menulink.py b/pygame_menu/widgets/widget/menulink.py index 85c8f198..8c5d671e 100644 --- a/pygame_menu/widgets/widget/menulink.py +++ b/pygame_menu/widgets/widget/menulink.py @@ -38,10 +38,10 @@ class MenuLink(NoneWidget): menu: 'pygame_menu.Menu' def __init__( - self, - menu: 'pygame_menu.Menu', - menu_opener_handler: Callable, - link_id: str = '' + self, + menu: 'pygame_menu.Menu', + menu_opener_handler: Callable, + link_id: str = '' ) -> None: assert isinstance(menu, pygame_menu.Menu) assert callable(menu_opener_handler), \ @@ -70,9 +70,9 @@ class MenuLinkManager(AbstractWidgetManager, ABC): """ def menu_link( - self, - menu: 'pygame_menu.Menu', - link_id: str = '' + self, + menu: 'pygame_menu.Menu', + link_id: str = '' ) -> 'pygame_menu.widgets.MenuLink': """ Adds a link to another Menu. The behaviour is similar to a button, but diff --git a/pygame_menu/widgets/widget/none.py b/pygame_menu/widgets/widget/none.py index 4d4f4796..27fce498 100644 --- a/pygame_menu/widgets/widget/none.py +++ b/pygame_menu/widgets/widget/none.py @@ -38,8 +38,8 @@ class NoneWidget(Widget): """ def __init__( - self, - widget_id: str = '' + self, + widget_id: str = '' ) -> None: super(NoneWidget, self).__init__(widget_id=widget_id) self.is_selectable = False @@ -185,8 +185,8 @@ class NoneWidgetManager(AbstractWidgetManager, ABC): """ def none_widget( - self, - widget_id: str = '' + self, + widget_id: str = '' ) -> 'pygame_menu.widgets.NoneWidget': """ Add a none widget to the Menu. diff --git a/pygame_menu/widgets/widget/progressbar.py b/pygame_menu/widgets/widget/progressbar.py index 3896c960..622446a2 100644 --- a/pygame_menu/widgets/widget/progressbar.py +++ b/pygame_menu/widgets/widget/progressbar.py @@ -89,28 +89,28 @@ class ProgressBar(Widget): _width: int 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 + 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, @@ -144,7 +144,8 @@ def __init__( 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' + assert width > 0, \ + 'width must be greater than zero' box_progress_padding = parse_padding(box_progress_padding) self._box_progress_padding = box_progress_padding @@ -228,9 +229,7 @@ def _render(self) -> Optional[bool]: if not hasattr(self, '_progress_font'): return False - if not self._render_hash_changed( - self._selected, self._title, self._visible, self.readonly, - self._progress): + if not self._render_hash_changed(self._selected, self._title, self._visible, self.readonly, self._progress): return True # Create basic title @@ -282,15 +281,15 @@ class ProgressBarManager(AbstractWidgetManager, ABC): """ def progress_bar( - self, - title: Any, - default: NumberType = 0, - onselect: CallbackType = None, - progressbar_id: str = '', - progress_text_format: ProgressBarTextFormatType = lambda x: str(round(x, 1)), - selectable: bool = False, - width: int = 150, - **kwargs + self, + title: Any, + default: NumberType = 0, + onselect: CallbackType = None, + progressbar_id: str = '', + progress_text_format: ProgressBarTextFormatType = lambda x: str(round(x, 1)), + selectable: bool = False, + width: int = 150, + **kwargs ) -> 'pygame_menu.widgets.ProgressBar': """ Add a progress bar, which offers a bar that accepts a percentage from diff --git a/pygame_menu/widgets/widget/rangeslider.py b/pygame_menu/widgets/widget/rangeslider.py index acc77ebc..c11397df 100644 --- a/pygame_menu/widgets/widget/rangeslider.py +++ b/pygame_menu/widgets/widget/rangeslider.py @@ -191,58 +191,58 @@ class RangeSlider(Widget): _value_hidden: List[NumberType] # Hidden value of the slider, modified by events def __init__( - self, - title: Any, - rangeslider_id: str = '', - default_value: RangeSliderValueType = 0, - range_values: RangeSliderRangeValueType = (0, 1), - range_width: int = 150, - increment: NumberType = 0.1, - onchange: CallbackType = None, - onreturn: CallbackType = None, - onselect: CallbackType = None, - range_box_color: ColorInputType = (6, 119, 206, 170), - range_box_color_readonly: ColorInputType = (200, 200, 200, 170), - range_box_enabled: bool = True, - range_box_height_factor: NumberType = 0.45, - range_box_single_slider: bool = False, - range_line_color: ColorInputType = (100, 100, 100), - range_line_height: int = 2, - range_margin: Tuple2IntType = (25, 0), - range_text_value_color: ColorInputType = (80, 80, 80), - range_text_value_enabled: bool = True, - range_text_value_font: Optional[FontType] = None, - range_text_value_font_height: NumberType = 0.4, - range_text_value_margin_f: NumberType = 0.8, - range_text_value_position: str = POSITION_SOUTH, - range_text_value_tick_color: ColorInputType = (60, 60, 60), - range_text_value_tick_enabled: bool = True, - range_text_value_tick_hfactor: NumberType = 0.35, - range_text_value_tick_number: int = 2, - range_text_value_tick_thick: int = 1, - repeat_keys: bool = True, - repeat_keys_initial_ms: NumberType = 400, - repeat_keys_interval_ms: NumberType = 50, - slider_color: ColorInputType = (120, 120, 120), - slider_height_factor: NumberType = 0.7, - slider_sel_highlight_color: ColorInputType = (0, 0, 0), - slider_sel_highlight_enabled: bool = True, - slider_sel_highlight_thick: int = 1, - slider_selected_color: ColorInputType = (180, 180, 180), - slider_text_value_bgcolor: ColorInputType = (140, 140, 140), - slider_text_value_color: ColorInputType = (0, 0, 0), - slider_text_value_enabled: bool = True, - slider_text_value_font: Optional[FontType] = None, - slider_text_value_font_height: NumberType = 0.4, - slider_text_value_margin_f: NumberType = 1, - slider_text_value_padding: PaddingType = (0, 4), - slider_text_value_position: str = POSITION_NORTH, - slider_text_value_triangle: bool = True, - slider_thickness: int = 15, - slider_vmargin: NumberType = 0, - value_format: RangeSliderValueFormatType = lambda x: str(round(x, 3)), - *args, - **kwargs + self, + title: Any, + rangeslider_id: str = '', + default_value: RangeSliderValueType = 0, + range_values: RangeSliderRangeValueType = (0, 1), + range_width: int = 150, + increment: NumberType = 0.1, + onchange: CallbackType = None, + onreturn: CallbackType = None, + onselect: CallbackType = None, + range_box_color: ColorInputType = (6, 119, 206, 170), + range_box_color_readonly: ColorInputType = (200, 200, 200, 170), + range_box_enabled: bool = True, + range_box_height_factor: NumberType = 0.45, + range_box_single_slider: bool = False, + range_line_color: ColorInputType = (100, 100, 100), + range_line_height: int = 2, + range_margin: Tuple2IntType = (25, 0), + range_text_value_color: ColorInputType = (80, 80, 80), + range_text_value_enabled: bool = True, + range_text_value_font: Optional[FontType] = None, + range_text_value_font_height: NumberType = 0.4, + range_text_value_margin_f: NumberType = 0.8, + range_text_value_position: str = POSITION_SOUTH, + range_text_value_tick_color: ColorInputType = (60, 60, 60), + range_text_value_tick_enabled: bool = True, + range_text_value_tick_hfactor: NumberType = 0.35, + range_text_value_tick_number: int = 2, + range_text_value_tick_thick: int = 1, + repeat_keys: bool = True, + repeat_keys_initial_ms: NumberType = 400, + repeat_keys_interval_ms: NumberType = 50, + slider_color: ColorInputType = (120, 120, 120), + slider_height_factor: NumberType = 0.7, + slider_sel_highlight_color: ColorInputType = (0, 0, 0), + slider_sel_highlight_enabled: bool = True, + slider_sel_highlight_thick: int = 1, + slider_selected_color: ColorInputType = (180, 180, 180), + slider_text_value_bgcolor: ColorInputType = (140, 140, 140), + slider_text_value_color: ColorInputType = (0, 0, 0), + slider_text_value_enabled: bool = True, + slider_text_value_font: Optional[FontType] = None, + slider_text_value_font_height: NumberType = 0.4, + slider_text_value_margin_f: NumberType = 1, + slider_text_value_padding: PaddingType = (0, 4), + slider_text_value_position: str = POSITION_NORTH, + slider_text_value_triangle: bool = True, + slider_thickness: int = 15, + slider_vmargin: NumberType = 0, + value_format: RangeSliderValueFormatType = lambda x: str(round(x, 3)), + *args, + **kwargs ) -> None: super(RangeSlider, self).__init__( args=args, @@ -607,12 +607,12 @@ def draw_after_if_selected(self, surface: Optional['pygame.Surface']) -> 'RangeS return self def _get_slider_inflate_rect( - self, - pos: int, - inflate: Optional[Tuple2IntType] = None, - to_real_position: bool = False, - to_absolute_position: bool = False, - real_position_visible: bool = True + self, + pos: int, + inflate: Optional[Tuple2IntType] = None, + to_real_position: bool = False, + to_absolute_position: bool = False, + real_position_visible: bool = True ) -> 'pygame.Rect': """ Return the slider inflate rect. @@ -652,10 +652,9 @@ def _render(self) -> Optional[bool]: if not hasattr(self, '_font_range_value'): return False - if not self._render_hash_changed( - self._selected, self._title, self._visible, self.readonly, - self._range_values, self._slider_selected, self._value[0], - self._value[1], self._scrolling, self._selected_mouse): + if not self._render_hash_changed(self._selected, self._title, self._visible, self.readonly, + self._range_values, self._slider_selected, self._value[0], + self._value[1], self._scrolling, self._selected_mouse): return True # Create basic title @@ -955,22 +954,28 @@ def update(self, events: EventVectorType) -> bool: joy_button_down = self._joystick_enabled and event.type == pygame.JOYBUTTONDOWN # Left button - if keydown and self._ctrl.left(event, self) or \ - joy_hatmotion and self._ctrl.joy_left(event, self) or \ - joy_axismotion and self._ctrl.joy_axis_x_left(event, self): + if ( + keydown and self._ctrl.left(event, self) or + joy_hatmotion and self._ctrl.joy_left(event, self) or + joy_axismotion and self._ctrl.joy_axis_x_left(event, self) + ): if self._left_right(event, True): return True # Right button - elif keydown and self._ctrl.right(event, self) or \ - joy_hatmotion and self._ctrl.joy_right(event, self) or \ - joy_axismotion and self._ctrl.joy_axis_x_right(event, self): + elif ( + keydown and self._ctrl.right(event, self) or + joy_hatmotion and self._ctrl.joy_right(event, self) or + joy_axismotion and self._ctrl.joy_axis_x_right(event, self) + ): if self._left_right(event, False): return True # Press enter - elif keydown and self._ctrl.apply(event, self) or \ - joy_button_down and self._ctrl.joy_select(event, self): + elif ( + keydown and self._ctrl.apply(event, self) or + joy_button_down and self._ctrl.joy_select(event, self) + ): self.apply() return True @@ -987,9 +992,10 @@ def update(self, events: EventVectorType) -> bool: del self._keyrepeat_counters[event.key] # User clicks the slider rect - elif event.type == pygame.MOUSEBUTTONDOWN and self._mouse_enabled or \ - event.type == FINGERDOWN and self._touchscreen_enabled and \ - self._menu is not None: + elif ( + event.type == pygame.MOUSEBUTTONDOWN and self._mouse_enabled or + event.type == FINGERDOWN and self._touchscreen_enabled and self._menu is not None + ): event_pos = get_finger_pos(self._menu, event) # Check which slider is clicked @@ -1019,10 +1025,10 @@ def update(self, events: EventVectorType) -> bool: self._selected_mouse = True # User releases the mouse - elif event.type == pygame.MOUSEBUTTONUP and self._mouse_enabled and \ - event.button in (1, 2, 3) or \ - event.type == FINGERUP and self._touchscreen_enabled and \ - self._menu is not None: + elif ( + event.type == pygame.MOUSEBUTTONUP and self._mouse_enabled and event.button in (1, 2, 3) or + event.type == FINGERUP and self._touchscreen_enabled and self._menu is not None + ): event_pos = get_finger_pos(self._menu, event) # If collides and not scroll, update the value to the clicked position @@ -1054,16 +1060,15 @@ def update(self, events: EventVectorType) -> bool: updated = True # User scrolls clicked slider - elif (event.type == pygame.MOUSEMOTION and self._mouse_enabled and hasattr(event, 'rel') or - event.type == FINGERMOTION and self._touchscreen_enabled and self._menu is not None) and \ - self._scrolling and self._selected_mouse: - rel = event.rel[0] if event.type == pygame.MOUSEMOTION else \ - event.dx * 2 * self._menu.get_window_size()[0] + elif self._scrolling and self._selected_mouse and ( + event.type == pygame.MOUSEMOTION and self._mouse_enabled and hasattr(event, 'rel') or + event.type == FINGERMOTION and self._touchscreen_enabled and self._menu is not None + ): + rel = event.rel[0] if event.type == pygame.MOUSEMOTION else event.dx * 2 * self._menu.get_window_size()[0] delta = (self._range_values[-1] - self._range_values[0]) * rel / self._range_width # Check mouse position - mx, my = event.pos if event.type == pygame.MOUSEMOTION else \ - get_finger_pos(self._menu, event) + mx, my = event.pos if event.type == pygame.MOUSEMOTION else get_finger_pos(self._menu, event) rect = self.get_rect(to_real_position=True, apply_padding=False) # Compute position of mouse within valid range @@ -1108,18 +1113,18 @@ class RangeSliderManager(AbstractWidgetManager, ABC): """ def range_slider( - self, - title: str, - default: RangeSliderValueType, - range_values: RangeSliderRangeValueType, - increment: Optional[NumberType] = None, - onchange: CallbackType = None, - onreturn: CallbackType = None, - onselect: Optional[Callable[[bool, 'Widget', 'pygame_menu.Menu'], Any]] = None, - rangeslider_id: str = '', - value_format: RangeSliderValueFormatType = lambda x: str(round(x, 3)), - width: int = 150, - **kwargs + self, + title: str, + default: RangeSliderValueType, + range_values: RangeSliderRangeValueType, + increment: Optional[NumberType] = None, + onchange: CallbackType = None, + onreturn: CallbackType = None, + onselect: Optional[Callable[[bool, 'Widget', 'pygame_menu.Menu'], Any]] = None, + rangeslider_id: str = '', + value_format: RangeSliderValueFormatType = lambda x: str(round(x, 3)), + width: int = 150, + **kwargs ) -> 'pygame_menu.widgets.RangeSlider': """ Add a range slider to the Menu: Offers 1 or 2 sliders for defining a unique diff --git a/pygame_menu/widgets/widget/scrollbar.py b/pygame_menu/widgets/widget/scrollbar.py index 9fa419c7..329e2d55 100644 --- a/pygame_menu/widgets/widget/scrollbar.py +++ b/pygame_menu/widgets/widget/scrollbar.py @@ -71,19 +71,19 @@ class ScrollBar(Widget): scrolling: bool def __init__( - self, - length: NumberType, - values_range: VectorIntType, - scrollbar_id: str = '', - orientation: str = ORIENTATION_HORIZONTAL, - slider_pad: NumberType = 0, - slider_color: ColorInputType = (200, 200, 200), - slider_hover_color: ColorInputType = (180, 180, 180), - page_ctrl_thick: int = 20, - page_ctrl_color: ColorInputType = (235, 235, 235), - onchange: CallbackType = None, - *args, - **kwargs + self, + length: NumberType, + values_range: VectorIntType, + scrollbar_id: str = '', + orientation: str = ORIENTATION_HORIZONTAL, + slider_pad: NumberType = 0, + slider_color: ColorInputType = (200, 200, 200), + slider_hover_color: ColorInputType = (180, 180, 180), + page_ctrl_thick: int = 20, + page_ctrl_color: ColorInputType = (235, 235, 235), + onchange: CallbackType = None, + *args, + **kwargs ) -> None: assert isinstance(length, NumberInstance) assert isinstance(values_range, VectorInstance) @@ -192,11 +192,11 @@ def _apply_size_changes(self) -> None: self._slider_rect = self._slider_rect.inflate(-2 * self._slider_pad, -2 * self._slider_pad) def set_shadow( - self, - enabled: bool = True, - color: Optional[ColorInputType] = None, - position: Optional[str] = None, - offset: int = 2 + self, + enabled: bool = True, + color: Optional[ColorInputType] = None, + position: Optional[str] = None, + offset: int = 2 ) -> 'ScrollBar': """ Set the scrollbars shadow. @@ -299,10 +299,9 @@ def get_value(self) -> int: def _render(self) -> Optional[bool]: width, height = self._rect.width + self._rect_size_delta[0], self._rect.height + self._rect_size_delta[1] - if not self._render_hash_changed( - width, height, self._slider_rect.x, self._slider_rect.y, - self.readonly, self._slider_rect.width, self._slider_rect.height, - self.scrolling, self._mouseover, self._clicked): + if not self._render_hash_changed(width, height, self._slider_rect.x, self._slider_rect.y, + self.readonly, self._slider_rect.width, self._slider_rect.height, + self.scrolling, self._mouseover, self._clicked): return True self._surface = make_surface(width, height) @@ -527,10 +526,13 @@ def update(self, events: EventVectorType) -> bool: self._check_mouseover(event) # User press PAGEUP or PAGEDOWN - if event.type == pygame.KEYDOWN and \ - event.key in (pygame.K_PAGEUP, pygame.K_PAGEDOWN) and \ - self._keyboard_enabled and self._orientation == 1 and \ - not self.scrolling: + if ( + event.type == pygame.KEYDOWN and + event.key in (pygame.K_PAGEUP, pygame.K_PAGEDOWN) and + self._keyboard_enabled and + self._orientation == 1 and + not self.scrolling + ): direction = 1 if event.key == pygame.K_PAGEDOWN else -1 keys_pressed = pygame.key.get_pressed() step = self._page_step @@ -542,9 +544,10 @@ def update(self, events: EventVectorType) -> bool: return True # User moves mouse while scrolling - elif (event.type == pygame.MOUSEMOTION and self._mouse_enabled and hasattr(event, 'rel') or - event.type == FINGERMOTION and self._touchscreen_enabled and self._menu is not None) and \ - self.scrolling: + elif self.scrolling and ( + event.type == pygame.MOUSEMOTION and self._mouse_enabled and hasattr(event, 'rel') or + event.type == FINGERMOTION and self._touchscreen_enabled and self._menu is not None + ): # Get relative movement h = self.get_orientation() == ORIENTATION_HORIZONTAL rel = event.rel[self._orientation] if event.type == pygame.MOUSEMOTION else ( @@ -555,9 +558,11 @@ def update(self, events: EventVectorType) -> bool: # If mouse outside region and scroll is on limits, ignore mx, my = event.pos if event.type == pygame.MOUSEMOTION else \ get_finger_pos(self._menu, event) - if self.get_value_percentage() in (0, 1) and \ - self.get_scrollarea() is not None and \ - self.get_scrollarea().get_parent() is not None: + if ( + self.get_value_percentage() in (0, 1) and + self.get_scrollarea() is not None and + self.get_scrollarea().get_parent() is not None + ): if self._orientation == 1: # Vertical h = self._slider_rect.height / 2 if my > (rect.bottom - h) or my < (rect.top + h): @@ -589,15 +594,21 @@ def update(self, events: EventVectorType) -> bool: self._scroll(rect, my - lmy) # User clicks the slider rect - elif event.type == pygame.MOUSEBUTTONDOWN and self._mouse_enabled or \ - event.type == FINGERDOWN and self._touchscreen_enabled and \ - self._menu is not None: + elif ( + event.type == pygame.MOUSEBUTTONDOWN and self._mouse_enabled or + event.type == FINGERDOWN and self._touchscreen_enabled and self._menu is not None + ): # Vertical bar: scroll down (4) or up (5). Mouse must be placed # over the area to enable this feature - if not event.type == FINGERDOWN and \ - event.button in (4, 5) and self._orientation == 1 and \ - (self._scrollarea is not None and - self._scrollarea.mouse_is_over() or self._scrollarea is None): + if ( + not event.type == FINGERDOWN and + event.button in (4, 5) and + self._orientation == 1 and + ( + self._scrollarea is not None and self._scrollarea.mouse_is_over() or + self._scrollarea is None + ) + ): direction = -1 if event.button == 4 else 1 if self._scroll(rect, direction * self._single_step): self.change() diff --git a/pygame_menu/widgets/widget/selector.py b/pygame_menu/widgets/widget/selector.py index 1cfd25cc..4e8d6543 100644 --- a/pygame_menu/widgets/widget/selector.py +++ b/pygame_menu/widgets/widget/selector.py @@ -118,24 +118,24 @@ class Selector(Widget): _title_size: int def __init__( - self, - title: Any, - items: Union[List[Tuple[Any, ...]], List[str]], - selector_id: str = '', - default: int = 0, - onchange: CallbackType = None, - onreturn: CallbackType = None, - onselect: CallbackType = None, - style: SelectorStyleType = SELECTOR_STYLE_CLASSIC, - style_fancy_arrow_color: ColorInputType = (160, 160, 160), - style_fancy_arrow_margin: Tuple3IntType = (5, 5, 0), - style_fancy_bgcolor: ColorInputType = (180, 180, 180), - style_fancy_bordercolor: ColorInputType = (0, 0, 0), - style_fancy_borderwidth: int = 1, - style_fancy_box_inflate: Tuple2IntType = (0, 0), - style_fancy_box_margin: Tuple2NumberType = (25, 0), - *args, - **kwargs + self, + title: Any, + items: Union[List[Tuple[Any, ...]], List[str]], + selector_id: str = '', + default: int = 0, + onchange: CallbackType = None, + onreturn: CallbackType = None, + onselect: CallbackType = None, + style: SelectorStyleType = SELECTOR_STYLE_CLASSIC, + style_fancy_arrow_color: ColorInputType = (160, 160, 160), + style_fancy_arrow_margin: Tuple3IntType = (5, 5, 0), + style_fancy_bgcolor: ColorInputType = (180, 180, 180), + style_fancy_bordercolor: ColorInputType = (0, 0, 0), + style_fancy_borderwidth: int = 1, + style_fancy_box_inflate: Tuple2IntType = (0, 0), + style_fancy_box_margin: Tuple2NumberType = (25, 0), + *args, + **kwargs ) -> None: assert isinstance(items, list) assert isinstance(selector_id, str) @@ -229,9 +229,7 @@ def _draw(self, surface: 'pygame.Surface') -> None: def _render(self) -> Optional[bool]: current_selected = self.get_value()[0][0] - if not self._render_hash_changed( - current_selected, self._selected, self._visible, self._index, - self.readonly): + if not self._render_hash_changed(current_selected, self._selected, self._visible, self._index, self.readonly): return True color = self.get_font_color_status() @@ -449,31 +447,37 @@ def update(self, events: EventVectorType) -> bool: joy_button_down = self._joystick_enabled and event.type == pygame.JOYBUTTONDOWN # Left button - if keydown and self._ctrl.left(event, self) or \ - joy_hatmotion and self._ctrl.joy_left(event, self) or \ - joy_axismotion and self._ctrl.joy_axis_x_left(event, self): + if ( + keydown and self._ctrl.left(event, self) or + joy_hatmotion and self._ctrl.joy_left(event, self) or + joy_axismotion and self._ctrl.joy_axis_x_left(event, self) + ): self._left() return True # Right button - elif keydown and self._ctrl.right(event, self) or \ - joy_hatmotion and self._ctrl.joy_right(event, self) or \ - joy_axismotion and self._ctrl.joy_axis_x_right(event, self): + elif ( + keydown and self._ctrl.right(event, self) or + joy_hatmotion and self._ctrl.joy_right(event, self) or + joy_axismotion and self._ctrl.joy_axis_x_right(event, self) + ): self._right() return True # Press enter - elif keydown and self._ctrl.apply(event, self) or \ - joy_button_down and self._ctrl.joy_select(event, self): + elif ( + keydown and self._ctrl.apply(event, self) or + joy_button_down and self._ctrl.joy_select(event, self) + ): self._sound.play_key_add() self.apply(*self._items[self._index][1:]) return True # Click on selector; don't consider the mouse wheel (button 4 & 5) - elif event.type == pygame.MOUSEBUTTONUP and self._mouse_enabled and \ - event.button in (1, 2, 3) or \ - event.type == FINGERUP and self._touchscreen_enabled and \ - self._menu is not None: + elif ( + event.type == pygame.MOUSEBUTTONUP and self._mouse_enabled and event.button in (1, 2, 3) or + event.type == FINGERUP and self._touchscreen_enabled and self._menu is not None + ): event_pos = get_finger_pos(self._menu, event) # If collides @@ -503,16 +507,16 @@ class SelectorManager(AbstractWidgetManager, ABC): """ def selector( - self, - title: Any, - items: Union[List[Tuple[Any, ...]], List[str]], - default: int = 0, - onchange: CallbackType = None, - onreturn: CallbackType = None, - onselect: Optional[Callable[[bool, 'Widget', 'pygame_menu.Menu'], Any]] = None, - selector_id: str = '', - style: SelectorStyleType = SELECTOR_STYLE_CLASSIC, - **kwargs + self, + title: Any, + items: Union[List[Tuple[Any, ...]], List[str]], + default: int = 0, + onchange: CallbackType = None, + onreturn: CallbackType = None, + onselect: Optional[Callable[[bool, 'Widget', 'pygame_menu.Menu'], Any]] = None, + selector_id: str = '', + style: SelectorStyleType = SELECTOR_STYLE_CLASSIC, + **kwargs ) -> 'pygame_menu.widgets.Selector': """ Add a selector to the Menu: several items and two functions that are diff --git a/pygame_menu/widgets/widget/surface.py b/pygame_menu/widgets/widget/surface.py index 12bcab1a..049a1e8d 100644 --- a/pygame_menu/widgets/widget/surface.py +++ b/pygame_menu/widgets/widget/surface.py @@ -38,10 +38,10 @@ class SurfaceWidget(Widget): _surface_obj: 'pygame.Surface' def __init__( - self, - surface: 'pygame.Surface', - surface_id: str = '', - onselect: CallbackType = None + self, + surface: 'pygame.Surface', + surface_id: str = '', + onselect: CallbackType = None ) -> None: assert isinstance(surface, pygame.Surface) assert isinstance(surface_id, str) @@ -113,12 +113,12 @@ class SurfaceWidgetManager(AbstractWidgetManager, ABC): """ def surface( - self, - surface: 'pygame.Surface', - surface_id: str = '', - onselect: Optional[Callable[[bool, 'Widget', 'pygame_menu.Menu'], Any]] = None, - selectable: bool = False, - **kwargs + self, + surface: 'pygame.Surface', + surface_id: str = '', + onselect: Optional[Callable[[bool, 'Widget', 'pygame_menu.Menu'], Any]] = None, + selectable: bool = False, + **kwargs ) -> 'pygame_menu.widgets.SurfaceWidget': """ Add a surface widget to the Menu. diff --git a/pygame_menu/widgets/widget/table.py b/pygame_menu/widgets/widget/table.py index 66ee17c7..976e04e1 100644 --- a/pygame_menu/widgets/widget/table.py +++ b/pygame_menu/widgets/widget/table.py @@ -63,8 +63,8 @@ class Table(Frame): default_row_background_color: Optional[ColorInputType] def __init__( - self, - table_id: str = '' + self, + table_id: str = '' ) -> None: super(Table, self).__init__( width=1, @@ -143,13 +143,13 @@ def unpack(self, row: 'Frame') -> None: @staticmethod def _check_cell_style( - align: str, - background_color: ColorInputType, - border_color: ColorInputType, - border_position: WidgetBorderPositionType, - border_width: int, - padding: PaddingType, - vertical_position: str + align: str, + background_color: ColorInputType, + border_color: ColorInputType, + border_position: WidgetBorderPositionType, + border_width: int, + padding: PaddingType, + vertical_position: str ) -> None: """ Assert cell style. @@ -194,18 +194,18 @@ def _check_cell_style( f'but received "{pos}"' def add_row( - self, - cells: Union[ColumnInputType, 'Widget'], - cell_align: Optional[str] = None, - cell_border_color: Optional[ColorInputType] = None, - cell_border_position: Optional[WidgetBorderPositionType] = None, - cell_border_width: Optional[int] = None, - cell_font: Optional[FontType] = None, - cell_font_color: Optional[ColorInputType] = None, - cell_font_size: Optional[int] = None, - cell_padding: PaddingType = None, - cell_vertical_position: Optional[str] = None, - row_background_color: Optional[ColorInputType] = None + self, + cells: Union[ColumnInputType, 'Widget'], + cell_align: Optional[str] = None, + cell_border_color: Optional[ColorInputType] = None, + cell_border_position: Optional[WidgetBorderPositionType] = None, + cell_border_width: Optional[int] = None, + cell_font: Optional[FontType] = None, + cell_font_color: Optional[ColorInputType] = None, + cell_font_size: Optional[int] = None, + cell_padding: PaddingType = None, + cell_vertical_position: Optional[str] = None, + row_background_color: Optional[ColorInputType] = None ) -> 'Frame': """ Add row to table. @@ -602,8 +602,7 @@ def _draw_cell_borders(self, surface: 'pygame.Surface') -> None: col += 1 # Draw the border - if border_position == WIDGET_BORDER_POSITION_NONE or \ - border_width == 0: + if border_position == WIDGET_BORDER_POSITION_NONE or border_width == 0: continue for pos in border_position: if pos == POSITION_NORTH: @@ -662,19 +661,19 @@ def is_rectangular(self) -> bool: return True def update_cell_style( - self, - column: Union[int, Vector2IntType], - row: Union[int, Vector2IntType], - align: Optional[str] = None, - background_color: Optional[ColorInputType] = None, - border_color: Optional[ColorInputType] = None, - border_position: Optional[WidgetBorderPositionType] = None, - border_width: Optional[int] = None, - font: Optional[FontType] = None, - font_color: Optional[ColorInputType] = None, - font_size: Optional[int] = None, - padding: Optional[PaddingType] = None, - vertical_position: Optional[str] = None + self, + column: Union[int, Vector2IntType], + row: Union[int, Vector2IntType], + align: Optional[str] = None, + background_color: Optional[ColorInputType] = None, + border_color: Optional[ColorInputType] = None, + border_position: Optional[WidgetBorderPositionType] = None, + border_width: Optional[int] = None, + font: Optional[FontType] = None, + font_color: Optional[ColorInputType] = None, + font_size: Optional[int] = None, + padding: Optional[PaddingType] = None, + vertical_position: Optional[str] = None ) -> Union['Widget', List['Widget']]: """ Update cell style. If a parameter is ``None`` the default cell property @@ -897,9 +896,9 @@ class TableManager(AbstractWidgetManager, ABC): """ def table( - self, - table_id: str = '', - **kwargs + self, + table_id: str = '', + **kwargs ) -> 'pygame_menu.widgets.Table': """ Adds a Table to the Menu. A table is a frame which can pack widgets in a diff --git a/pygame_menu/widgets/widget/textinput.py b/pygame_menu/widgets/widget/textinput.py index f4c69687..c9da2e4a 100644 --- a/pygame_menu/widgets/widget/textinput.py +++ b/pygame_menu/widgets/widget/textinput.py @@ -161,36 +161,36 @@ class TextInput(Widget): _valid_chars: Optional[List[str]] def __init__( - self, - title: Any, - textinput_id: str = '', - copy_paste_enable: bool = True, - cursor_color: ColorInputType = (0, 0, 0), - cursor_selection_color: ColorInputType = (30, 30, 30, 100), - cursor_selection_enable: bool = True, - cursor_size: Optional[Tuple2IntType] = None, - cursor_switch_ms: NumberType = 500, - history: int = 50, - input_type: str = INPUT_TEXT, - input_underline: str = '', - input_underline_len: int = 0, - input_underline_vmargin: int = 0, - maxchar: int = 0, - maxwidth: int = 0, - maxwidth_dynamically_update: bool = True, - onchange: CallbackType = None, - onreturn: CallbackType = None, - onselect: CallbackType = None, - password: bool = False, - password_char: str = '*', - repeat_keys: bool = True, - repeat_keys_initial_ms: NumberType = 400, - repeat_keys_interval_ms: NumberType = 50, - repeat_mouse_interval_ms: NumberType = 400, - text_ellipsis: str = '...', - valid_chars: Optional[List[str]] = None, - *args, - **kwargs + self, + title: Any, + textinput_id: str = '', + copy_paste_enable: bool = True, + cursor_color: ColorInputType = (0, 0, 0), + cursor_selection_color: ColorInputType = (30, 30, 30, 100), + cursor_selection_enable: bool = True, + cursor_size: Optional[Tuple2IntType] = None, + cursor_switch_ms: NumberType = 500, + history: int = 50, + input_type: str = INPUT_TEXT, + input_underline: str = '', + input_underline_len: int = 0, + input_underline_vmargin: int = 0, + maxchar: int = 0, + maxwidth: int = 0, + maxwidth_dynamically_update: bool = True, + onchange: CallbackType = None, + onreturn: CallbackType = None, + onselect: CallbackType = None, + password: bool = False, + password_char: str = '*', + repeat_keys: bool = True, + repeat_keys_initial_ms: NumberType = 400, + repeat_keys_interval_ms: NumberType = 50, + repeat_mouse_interval_ms: NumberType = 400, + text_ellipsis: str = '...', + valid_chars: Optional[List[str]] = None, + *args, + **kwargs ) -> None: assert isinstance(copy_paste_enable, bool) assert isinstance(cursor_selection_enable, bool) @@ -447,9 +447,12 @@ def _draw(self, surface: 'pygame.Surface') -> None: surface.blit(self._surface, (self._rect.x, self._rect.y)) # Draw string # Draw cursor - if self._selected and self._cursor_surface and \ - (self._cursor_visible or self._key_is_pressed) and \ - not self.readonly: + if ( + self._selected and + self._cursor_surface and + (self._cursor_visible or self._key_is_pressed) and + not self.readonly + ): x = self._rect.x + self._cursor_surface_pos[0] if self._flip[0]: # Flip on x-axis (bug) x = self._surface.get_width() - x @@ -463,14 +466,13 @@ def _render(self) -> Optional[bool]: if max_cont_width != 0: self._last_container_width = max_cont_width - if not self._render_hash_changed( - string, self._selected, self._cursor_render, self._cursor_position, - self._selection_enabled, self.active, self._visible, self.readonly, - self._last_container_width, self._selection_box[0], self._menu, - self._selection_box[1], self._last_selection_render[0], self._padding, - self._last_selection_render[1], self._renderbox[0], self._renderbox[1], - self._renderbox[2], self._cursor_visible, self._title_size, - self._selection_effect.get_width()): + if not self._render_hash_changed(string, self._selected, self._cursor_render, self._cursor_position, + self._selection_enabled, self.active, self._visible, self.readonly, + self._last_container_width, self._selection_box[0], self._menu, + self._selection_box[1], self._last_selection_render[0], self._padding, + self._last_selection_render[1], self._renderbox[0], self._renderbox[1], + self._renderbox[2], self._cursor_visible, self._title_size, + self._selection_effect.get_width()): return True # Apply underline if exists @@ -501,10 +503,10 @@ def _render_selection_box(self, force: bool = False) -> None: if not self._selection_enabled: return - if self._selection_active and \ - (self._last_selection_render[0] != self._selection_box[0] or - self._last_selection_render[1] != self._selection_box[1]) or force: - + if force or self._selection_active and ( + self._last_selection_render[0] != self._selection_box[0] or + self._last_selection_render[1] != self._selection_box[1] + ): # If there's no limit pos = [0, 0] if self._maxwidth == 0: @@ -780,13 +782,13 @@ def _get_input_string(self, add_ellipsis: bool = True) -> str: return string def _update_renderbox( - self, - left: int = 0, - right: int = 0, - addition: bool = False, - end: bool = False, - start: bool = False, - update_maxwidth: bool = True + self, + left: int = 0, + right: int = 0, + addition: bool = False, + end: bool = False, + start: bool = False, + update_maxwidth: bool = True ) -> None: """ Update renderbox position. @@ -1196,10 +1198,10 @@ def _update_input_string(self, new_string: str, update_history: bool = True) -> l_history = len(self._history) # If last edition is different from the new one -> updates the history - if update_history and \ - ((l_history > 0 and self._history[ - l_history - 1] != new_string) or l_history == 0) and self._max_history > 0: - + if update_history and self._max_history > 0 and ( + (l_history > 0 and self._history[l_history - 1] != new_string) or + l_history == 0 + ): # If index is not at last add the current status as new if self._history_index != l_history: last_string = self._history[self._history_index] @@ -1408,8 +1410,8 @@ def _backspace(self, update_history=True) -> None: :param update_history: Updates history on deletion """ new_string = ( - self._input_string[:max(self._cursor_position - 1, 0)] - + self._input_string[self._cursor_position:] + self._input_string[:max(self._cursor_position - 1, 0)] + + self._input_string[self._cursor_position:] ) self._update_input_string(new_string, update_history=update_history) self._update_renderbox(left=-1, addition=True) @@ -1424,8 +1426,8 @@ def _delete(self, update_history: bool = True) -> None: :param update_history: Updates history on deletion """ new_string = ( - self._input_string[:self._cursor_position] - + self._input_string[self._cursor_position + 1:] + self._input_string[:self._cursor_position] + + self._input_string[self._cursor_position + 1:] ) self._update_input_string(new_string, update_history=update_history) self._update_renderbox(right=-1, addition=True) @@ -1464,9 +1466,9 @@ def _push_key_input(self, keychar: str, sounds: bool = True) -> bool: # If no special key is pressed, add unicode of key to input_string new_string = ( - self._input_string[:self._cursor_position] - + keychar - + self._input_string[self._cursor_position:] + self._input_string[:self._cursor_position] + + keychar + + self._input_string[self._cursor_position:] ) # If unwanted escape sequences @@ -1550,9 +1552,11 @@ def update(self, events: EventVectorType) -> bool: self._last_key = event.key # If None exist, create counter for that key: - if event.key not in self._keyrepeat_counters and \ - event.key not in self._ignore_keys and \ - 'unicode' in event.dict: + if ( + event.key not in self._keyrepeat_counters and + event.key not in self._ignore_keys and + 'unicode' in event.dict + ): self._keyrepeat_counters[event.key] = [0, event.unicode] # User press ctrl+something @@ -1628,8 +1632,10 @@ def update(self, events: EventVectorType) -> bool: break # User press alt+x get the unicode char from string - if pygame.key.get_mods() in (pygame.KMOD_ALT, pygame.KMOD_LALT) and \ - event.key == pygame.K_x and self._alt_x_enabled: + if ( + pygame.key.get_mods() in (pygame.KMOD_ALT, pygame.KMOD_LALT) and + event.key == pygame.K_x and self._alt_x_enabled + ): # Get the last hex value last_space = self._input_string.rfind(' ') if last_space == -1: # space not found, try 0x @@ -1640,8 +1646,8 @@ def update(self, events: EventVectorType) -> bool: last_space = 0 for j in range(len(self._input_string)): if self._input_string[j].lower() not in \ - ('0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'): + ('0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'): last_space = j + 1 if last_space >= len(self._input_string): last_space = -1 @@ -1848,12 +1854,12 @@ def update(self, events: EventVectorType) -> bool: # User releases the mouse button or finger; don't consider the mouse # wheel (button 4 & 5) - elif event.type == pygame.MOUSEBUTTONUP and self._mouse_enabled and \ - event.button in (1, 2, 3) or \ - event.type == FINGERUP and self._touchscreen_enabled and self._menu is not None: + elif ( + event.type == pygame.MOUSEBUTTONUP and self._mouse_enabled and event.button in (1, 2, 3) or + event.type == FINGERUP and self._touchscreen_enabled and self._menu is not None + ): event_pos = get_finger_pos(self._menu, event) - if rect.collidepoint(*event_pos) and \ - self.get_selected_time() > 1.5 * self._keyrepeat_mouse_interval_ms: + if rect.collidepoint(*event_pos) and self.get_selected_time() > 1.5 * self._keyrepeat_mouse_interval_ms: self._selection_active = False self._check_mouse_collide_input(event_pos) self._cursor_ms_counter = 0 @@ -1861,9 +1867,10 @@ def update(self, events: EventVectorType) -> bool: # User press the mouse button or finger; don't consider the mouse # wheel (button 4 & 5) - elif event.type == pygame.MOUSEBUTTONDOWN and self._mouse_enabled and \ - event.button in (1, 2, 3) or \ - event.type == FINGERDOWN and self._touchscreen_enabled: + elif ( + event.type == pygame.MOUSEBUTTONDOWN and self._mouse_enabled and event.button in (1, 2, 3) or + event.type == FINGERDOWN and self._touchscreen_enabled + ): if self.get_selected_time() > self._keyrepeat_mouse_interval_ms or hasattr(event, 'test'): if self._selection_active: self._unselect_text() @@ -1909,24 +1916,24 @@ class TextInputManager(AbstractWidgetManager, ABC): """ def text_input( - self, - title: Any, - default: Union[str, int, float] = '', - copy_paste_enable: bool = True, - cursor_selection_enable: bool = True, - cursor_size: Optional[Tuple2IntType] = None, - input_type: str = INPUT_TEXT, - input_underline: str = '', - input_underline_len: int = 0, - maxchar: int = 0, - maxwidth: int = 0, - onchange: CallbackType = None, - onreturn: CallbackType = None, - onselect: Optional[Callable[[bool, 'Widget', 'pygame_menu.Menu'], Any]] = None, - password: bool = False, - textinput_id: str = '', - valid_chars: Optional[List[str]] = None, - **kwargs + self, + title: Any, + default: Union[str, int, float] = '', + copy_paste_enable: bool = True, + cursor_selection_enable: bool = True, + cursor_size: Optional[Tuple2IntType] = None, + input_type: str = INPUT_TEXT, + input_underline: str = '', + input_underline_len: int = 0, + maxchar: int = 0, + maxwidth: int = 0, + onchange: CallbackType = None, + onreturn: CallbackType = None, + onselect: Optional[Callable[[bool, 'Widget', 'pygame_menu.Menu'], Any]] = None, + password: bool = False, + textinput_id: str = '', + valid_chars: Optional[List[str]] = None, + **kwargs ) -> 'pygame_menu.widgets.TextInput': """ Add a text input to the Menu: free text area and two functions that diff --git a/pygame_menu/widgets/widget/toggleswitch.py b/pygame_menu/widgets/widget/toggleswitch.py index 864f2176..1d7d4840 100644 --- a/pygame_menu/widgets/widget/toggleswitch.py +++ b/pygame_menu/widgets/widget/toggleswitch.py @@ -103,33 +103,33 @@ class ToggleSwitch(Widget): _total_states: int def __init__( - self, - title: Any, - toggleswitch_id: str = '', - default_state: int = 0, - infinite: bool = False, - onchange: CallbackType = None, - onselect: CallbackType = None, - single_click: bool = False, - single_click_dir: bool = True, - slider_color: ColorInputType = (255, 255, 255), - slider_height_factor: NumberType = 1, - slider_thickness: int = 25, - slider_vmargin: NumberType = 0, - state_color: Tuple[ColorInputType, ...] = ((178, 178, 178), (117, 185, 54)), - state_text: Tuple[str, ...] = ('Off', 'On'), - state_text_font: Optional[FontType] = None, - state_text_font_color: Tuple[ColorInputType, ...] = ((255, 255, 255), (255, 255, 255)), - state_text_font_size: Optional[int] = None, - state_text_position: Tuple2NumberType = (0.5, 0.5), - state_values: Tuple[Any, ...] = (False, True), - state_width: Union[Tuple[int, ...], int] = 150, - switch_border_color: ColorInputType = (40, 40, 40), - switch_border_width: int = 1, - switch_height: NumberType = 1.25, - switch_margin: Tuple2IntType = (25, 0), - *args, - **kwargs + self, + title: Any, + toggleswitch_id: str = '', + default_state: int = 0, + infinite: bool = False, + onchange: CallbackType = None, + onselect: CallbackType = None, + single_click: bool = False, + single_click_dir: bool = True, + slider_color: ColorInputType = (255, 255, 255), + slider_height_factor: NumberType = 1, + slider_thickness: int = 25, + slider_vmargin: NumberType = 0, + state_color: Tuple[ColorInputType, ...] = ((178, 178, 178), (117, 185, 54)), + state_text: Tuple[str, ...] = ('Off', 'On'), + state_text_font: Optional[FontType] = None, + state_text_font_color: Tuple[ColorInputType, ...] = ((255, 255, 255), (255, 255, 255)), + state_text_font_size: Optional[int] = None, + state_text_position: Tuple2NumberType = (0.5, 0.5), + state_values: Tuple[Any, ...] = (False, True), + state_width: Union[Tuple[int, ...], int] = 150, + switch_border_color: ColorInputType = (40, 40, 40), + switch_border_width: int = 1, + switch_height: NumberType = 1.25, + switch_margin: Tuple2IntType = (25, 0), + *args, + **kwargs ) -> None: super(ToggleSwitch, self).__init__( args=args, @@ -328,9 +328,7 @@ def _draw(self, surface: 'pygame.Surface') -> None: surface.blit(self._slider, (slider_x, slider_y)) def _render(self) -> Optional[bool]: - if not self._render_hash_changed( - self._selected, self._title, self._visible, self.readonly, - self._state): + if not self._render_hash_changed(self._selected, self._title, self._visible, self.readonly, self._state): return True # Create basic title @@ -405,23 +403,28 @@ def update(self, events: EventVectorType) -> bool: joy_axismotion = self._joystick_enabled and event.type == pygame.JOYAXISMOTION # Left button - if keydown and self._ctrl.left(event, self) or \ - joy_hatmotion and self._ctrl.joy_left(event, self) or \ - joy_axismotion and self._ctrl.joy_axis_x_left(event, self): + if ( + keydown and self._ctrl.left(event, self) or + joy_hatmotion and self._ctrl.joy_left(event, self) or + joy_axismotion and self._ctrl.joy_axis_x_left(event, self) + ): self._left() return True # Right button - elif keydown and self._ctrl.right(event, self) or \ - joy_hatmotion and self._ctrl.joy_right(event, self) or \ - joy_axismotion and self._ctrl.joy_axis_x_right(event, self): + elif ( + keydown and self._ctrl.right(event, self) or + joy_hatmotion and self._ctrl.joy_right(event, self) or + joy_axismotion and self._ctrl.joy_axis_x_right(event, self) + ): self._right() return True # Press enter - elif keydown and self._ctrl.apply(event, self) and self._total_states == 2 or \ - event.type == pygame.JOYBUTTONDOWN and self._joystick_enabled and \ - self._ctrl.joy_select(event, self) and self._total_states == 2: + elif ( + keydown and self._ctrl.apply(event, self) and self._total_states == 2 or + event.type == pygame.JOYBUTTONDOWN and self._joystick_enabled and self._ctrl.joy_select(event, self) and self._total_states == 2 + ): self._sound.play_key_add() self._state = int(not self._state) self.change() @@ -429,10 +432,10 @@ def update(self, events: EventVectorType) -> bool: return True # Click on switch; don't consider the mouse wheel (button 4 & 5) - elif event.type == pygame.MOUSEBUTTONUP and self._mouse_enabled and \ - event.button in (1, 2, 3) or \ - event.type == FINGERUP and self._touchscreen_enabled and \ - self._menu is not None: + elif ( + event.type == pygame.MOUSEBUTTONUP and self._mouse_enabled and event.button in (1, 2, 3) or + event.type == FINGERUP and self._touchscreen_enabled and self._menu is not None + ): event_pos = get_finger_pos(self._menu, event) # If collides @@ -479,17 +482,17 @@ class ToggleSwitchManager(AbstractWidgetManager, ABC): """ def toggle_switch( - self, - title: Any, - default: Union[int, bool] = 0, - onchange: CallbackType = None, - onselect: Optional[Callable[[bool, 'Widget', 'pygame_menu.Menu'], Any]] = None, - toggleswitch_id: str = '', - single_click: bool = True, - state_text: Tuple[str, ...] = ('Off', 'On'), - state_values: Tuple[Any, ...] = (False, True), - width: int = 150, - **kwargs + self, + title: Any, + default: Union[int, bool] = 0, + onchange: CallbackType = None, + onselect: Optional[Callable[[bool, 'Widget', 'pygame_menu.Menu'], Any]] = None, + toggleswitch_id: str = '', + single_click: bool = True, + state_text: Tuple[str, ...] = ('Off', 'On'), + state_values: Tuple[Any, ...] = (False, True), + width: int = 150, + **kwargs ) -> 'pygame_menu.widgets.ToggleSwitch': """ Add a toggle switch to the Menu: It can switch between two states. diff --git a/pygame_menu/widgets/widget/vfill.py b/pygame_menu/widgets/widget/vfill.py index d898430f..6549486c 100644 --- a/pygame_menu/widgets/widget/vfill.py +++ b/pygame_menu/widgets/widget/vfill.py @@ -37,9 +37,9 @@ class VFill(NoneWidget): _min_height: int def __init__( - self, - min_height: NumberType, - widget_id: str = '' + self, + min_height: NumberType, + widget_id: str = '' ) -> None: assert isinstance(min_height, NumberInstance) assert min_height >= 0, 'negative min height is not valid' @@ -86,9 +86,9 @@ class VFillManager(AbstractWidgetManager, ABC): """ def vertical_fill( - self, - min_height: NumberType = 0, - vfill_id: str = '' + self, + min_height: NumberType = 0, + vfill_id: str = '' ) -> 'pygame_menu.widgets.VFill': """ Adds a vertical fill to the Menu. This widget fills all vertical space diff --git a/pygame_menu/widgets/widget/vmargin.py b/pygame_menu/widgets/widget/vmargin.py index 493782be..7e78e15b 100644 --- a/pygame_menu/widgets/widget/vmargin.py +++ b/pygame_menu/widgets/widget/vmargin.py @@ -35,9 +35,9 @@ class VMargin(NoneWidget): """ def __init__( - self, - margin: NumberType, - widget_id: str = '' + self, + margin: NumberType, + widget_id: str = '' ) -> None: assert isinstance(margin, NumberInstance) assert margin > 0, 'negative or zero margin is not valid' @@ -55,9 +55,9 @@ class VMarginManager(AbstractWidgetManager, ABC): """ def vertical_margin( - self, - margin: NumberType, - margin_id: str = '' + self, + margin: NumberType, + margin_id: str = '' ) -> 'pygame_menu.widgets.VMargin': """ Adds a vertical margin to the Menu. diff --git a/test/_utils.py b/test/_utils.py index 134b5199..72b0350e 100644 --- a/test/_utils.py +++ b/test/_utils.py @@ -114,10 +114,10 @@ class PygameEventUtils(object): @staticmethod def joy_motion( - x: NumberType = 0, - y: NumberType = 0, - inlist: bool = True, - testmode: bool = True + x: NumberType = 0, + y: NumberType = 0, + inlist: bool = True, + testmode: bool = True ) -> EventListType: """ Create a pygame joy controller motion event. @@ -154,8 +154,8 @@ def joy_motion( @staticmethod def joy_center( - testmode: bool = True, - inlist: bool = True + testmode: bool = True, + inlist: bool = True ) -> EventListType: """ Centers the joy. @@ -176,9 +176,9 @@ def joy_center( @staticmethod def joy_hat_motion( - key: Tuple[int, int], - inlist: bool = True, - testmode: bool = True + key: Tuple[int, int], + inlist: bool = True, + testmode: bool = True ) -> EventListType: """ Create a pygame joy controller key event. @@ -199,10 +199,10 @@ def joy_hat_motion( @staticmethod def joy_button( - button: int, - evtype: int = pygame.JOYBUTTONDOWN, - inlist: bool = True, - testmode: bool = True + button: int, + evtype: int = pygame.JOYBUTTONDOWN, + inlist: bool = True, + testmode: bool = True ) -> EventListType: """ Create a pygame joy controller key event. @@ -224,8 +224,8 @@ def joy_button( @staticmethod def test_widget_key_press( - widget: 'pygame_menu.widgets.Widget', - testmode: bool = True + widget: 'pygame_menu.widgets.Widget', + testmode: bool = True ) -> None: """ Test keypress widget. @@ -242,9 +242,9 @@ def test_widget_key_press( @staticmethod def keydown_mod_ctrl( - key: int, - inlist: bool = True, - testmode: bool = True + key: int, + inlist: bool = True, + testmode: bool = True ) -> EventListType: """ Create a mod ctrl keydown event (Ctrl+Key). @@ -275,9 +275,9 @@ def release_key_mod() -> None: @staticmethod def keydown_mod_alt( - key: int, - inlist: bool = True, - testmode: bool = True + key: int, + inlist: bool = True, + testmode: bool = True ) -> EventListType: """ Create a mod alt keydown event (Alt+Key). @@ -300,9 +300,9 @@ def keydown_mod_alt( @staticmethod def keydown( - key: Union[int, VectorIntType], - testmode: bool = True, - inlist: bool = True + key: Union[int, VectorIntType], + testmode: bool = True, + inlist: bool = True ) -> EventListType: """ Keydown list. @@ -325,12 +325,12 @@ def keydown( @staticmethod def key( - key: int, - char: str = ' ', - inlist: bool = True, - keydown: bool = False, - keyup: bool = False, - testmode: bool = True + key: int, + char: str = ' ', + inlist: bool = True, + keydown: bool = False, + keyup: bool = False, + testmode: bool = True ) -> EventListType: """ Create a keyboard event. @@ -393,14 +393,14 @@ def leave_window(inlist: bool = True, testmode: bool = True) -> EventListType: @staticmethod def mouse_click( - x: NumberType, - y: NumberType, - inlist: bool = True, - evtype: int = pygame.MOUSEBUTTONUP, - rel: Tuple2IntType = (0, 0), - button: int = 3, - testmode: bool = True, - update_mouse: bool = False + x: NumberType, + y: NumberType, + inlist: bool = True, + evtype: int = pygame.MOUSEBUTTONUP, + rel: Tuple2IntType = (0, 0), + button: int = 3, + testmode: bool = True, + update_mouse: bool = False ) -> EventListType: """ Generate a mouse click event. @@ -437,14 +437,14 @@ def mouse_click( @staticmethod def touch_click( - x: NumberType, - y: NumberType, - inlist: bool = True, - evtype: int = FINGERUP, - rel: Tuple2IntType = (0, 0), - normalize: bool = True, - menu: Union['pygame_menu.Menu', None] = None, - testmode: bool = True + x: NumberType, + y: NumberType, + inlist: bool = True, + evtype: int = FINGERUP, + rel: Tuple2IntType = (0, 0), + normalize: bool = True, + menu: Union['pygame_menu.Menu', None] = None, + testmode: bool = True ) -> EventListType: """ Generate a mouse click event. @@ -481,11 +481,11 @@ def touch_click( @staticmethod def topleft_rect_mouse_motion( - rect: Union['pygame_menu.widgets.Widget', 'pygame.Rect', Tuple2NumberType], - inlist: bool = True, - delta: Tuple2IntType = (0, 0), - testmode: bool = True, - update_mouse: bool = False + rect: Union['pygame_menu.widgets.Widget', 'pygame.Rect', Tuple2NumberType], + inlist: bool = True, + delta: Tuple2IntType = (0, 0), + testmode: bool = True, + update_mouse: bool = False ) -> EventListType: """ Mouse motion event. @@ -516,12 +516,12 @@ def topleft_rect_mouse_motion( @staticmethod def mouse_motion( - rect: Union['pygame_menu.widgets.Widget', 'pygame.Rect', Tuple2NumberType], - inlist: bool = True, - rel: Tuple2IntType = (0, 0), - delta: Tuple2IntType = (0, 0), - testmode: bool = True, - update_mouse: bool = False + rect: Union['pygame_menu.widgets.Widget', 'pygame.Rect', Tuple2NumberType], + inlist: bool = True, + rel: Tuple2IntType = (0, 0), + delta: Tuple2IntType = (0, 0), + testmode: bool = True, + update_mouse: bool = False ) -> EventListType: """ Mouse motion event. @@ -546,15 +546,15 @@ def mouse_motion( @staticmethod def middle_rect_click( - rect: Union['pygame_menu.widgets.Widget', 'pygame.Rect', Tuple2NumberType], - menu: Optional['pygame_menu.Menu'] = None, - evtype: int = pygame.MOUSEBUTTONUP, - inlist: bool = True, - rel: Tuple2IntType = (0, 0), - button: int = 3, - delta: Tuple2IntType = (0, 0), - testmode: bool = True, - update_mouse: bool = False + rect: Union['pygame_menu.widgets.Widget', 'pygame.Rect', Tuple2NumberType], + menu: Optional['pygame_menu.Menu'] = None, + evtype: int = pygame.MOUSEBUTTONUP, + inlist: bool = True, + rel: Tuple2IntType = (0, 0), + button: int = 3, + delta: Tuple2IntType = (0, 0), + testmode: bool = True, + update_mouse: bool = False ) -> EventListType: """ Return event clicking the middle of a given rect. @@ -660,24 +660,24 @@ def random_system_font() -> str: @staticmethod def generic_menu( - center_content: bool = True, - column_max_width: MenuColumnMaxWidthType = None, - column_min_width: MenuColumnMinWidthType = 0, - columns: int = 1, - enabled: bool = True, - height: NumberType = 400, - mouse_visible: bool = True, - mouse_motion_selection: bool = False, - onclose: Any = None, - onreset: Any = None, - position_x: NumberType = 50, - position_y: NumberType = 50, - rows: MenuRowsType = None, - theme: 'pygame_menu.themes.Theme' = pygame_menu.themes.THEME_DEFAULT, - title: str = '', - width: NumberType = 600, - *args, - **kwargs + center_content: bool = True, + column_max_width: MenuColumnMaxWidthType = None, + column_min_width: MenuColumnMinWidthType = 0, + columns: int = 1, + enabled: bool = True, + height: NumberType = 400, + mouse_visible: bool = True, + mouse_motion_selection: bool = False, + onclose: Any = None, + onreset: Any = None, + position_x: NumberType = 50, + position_y: NumberType = 50, + rows: MenuRowsType = None, + theme: 'pygame_menu.themes.Theme' = pygame_menu.themes.THEME_DEFAULT, + title: str = '', + width: NumberType = 600, + *args, + **kwargs ) -> 'pygame_menu.Menu': """ Generate a generic test menu. diff --git a/test/test_menu.py b/test/test_menu.py index 94b94bff..4a390646 100644 --- a/test/test_menu.py +++ b/test/test_menu.py @@ -1467,6 +1467,26 @@ def onbeforeopen(menu_from: 'pygame_menu.Menu', menu_to: 'pygame_menu.Menu') -> menu.add.button('to2', menu2).apply() self.assertTrue(test[0]) + # Test select widget + def onbeforeopen_select_widget(_from: 'pygame_menu.Menu', _to: 'pygame_menu.Menu'): + """ + Selects widget before opening. + """ + _to.select_widget('option2') + + menu = MenuUtils.generic_menu() + submenu = MenuUtils.generic_menu() + submenu.add.button('Option 1', button_id='option1') + submenu.add.button('Option 2', button_id='option2') + submenu.add.button('Option 3', button_id='option3') + submenu.set_onbeforeopen(onbeforeopen_select_widget) + btn_submenu = menu.add.button('Submenu', submenu) + + # Test applying to submenu, which should trigger onbeforeopen + self.assertEqual(submenu.get_selected_widget().get_id(), 'option1') # By default, submenu always start as 0 + btn_submenu.apply() + self.assertEqual(submenu.get_selected_widget().get_id(), 'option2') # Test if onbeforeopen did its work + def test_focus(self) -> None: """ Test menu focus effect.