├── .editorconfig ├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ └── ci.yml ├── .gitignore ├── .readthedocs.yml ├── .replit ├── LICENSE ├── MANIFEST.in ├── README.rst ├── build.py ├── codecov.yml ├── docs ├── Makefile ├── _source │ ├── add_sounds.rst │ ├── add_widgets.rst │ ├── add_widgets_manager.rst │ ├── advanced.rst │ ├── advanced_controller.rst │ ├── advanced_selection.rst │ ├── advanced_widget.rst │ ├── base.rst │ ├── baseimage.rst │ ├── contributors.rst │ ├── create_menu.rst │ ├── events.rst │ ├── gallery.rst │ ├── license.rst │ ├── migration_guide_2_to_3.rst │ ├── migration_guide_3_to_4.rst │ ├── scrollarea.rst │ ├── themes.rst │ ├── widgets_button.rst │ ├── widgets_colorinput.rst │ ├── widgets_dropselect.rst │ ├── widgets_dropselect_multiple.rst │ ├── widgets_frame.rst │ ├── widgets_hmargin.rst │ ├── widgets_image.rst │ ├── widgets_label.rst │ ├── widgets_menubar.rst │ ├── widgets_menulink.rst │ ├── widgets_none.rst │ ├── widgets_progressbar.rst │ ├── widgets_rangeslider.rst │ ├── widgets_scrollbar.rst │ ├── widgets_selector.rst │ ├── widgets_surface.rst │ ├── widgets_table.rst │ ├── widgets_textinput.rst │ ├── widgets_toggleswitch.rst │ ├── widgets_vfill.rst │ └── widgets_vmargin.rst ├── _static │ ├── example_game_selector.gif │ ├── example_multi_input.gif │ ├── example_other_calculator.gif │ ├── example_other_dynamic_button_append.gif │ ├── example_other_dynamic_widget_update.gif │ ├── example_other_image_background.gif │ ├── example_other_maze.gif │ ├── example_other_solar_system.gif │ ├── example_other_widget_positioning.png │ ├── example_scroll_menu.gif │ ├── example_simple.gif │ ├── example_timer_clock.gif │ ├── example_window_resize.gif │ ├── first_steps.png │ ├── font_8bit.png │ ├── font_bebas.png │ ├── font_comic_neue.png │ ├── font_digital.png │ ├── font_firacode.png │ ├── font_firacode_bold.png │ ├── font_firacode_bold_italic.png │ ├── font_firacode_italic.png │ ├── font_franchise.png │ ├── font_helvetica.png │ ├── font_munro.png │ ├── font_nevis.png │ ├── font_open_sans.png │ ├── font_open_sans_bold.png │ ├── font_open_sans_italic.png │ ├── font_open_sans_light.png │ ├── font_pt_serif.png │ ├── menubar_adaptive.png │ ├── menubar_none.png │ ├── menubar_simple.png │ ├── menubar_title_only.png │ ├── menubar_title_only_diagonal.png │ ├── menubar_underline.png │ ├── menubar_underline_title.png │ ├── pygame_menu.png │ ├── pygame_menu_small.png │ ├── theme_blue.png │ ├── theme_dark.png │ ├── theme_default.png │ ├── theme_green.png │ ├── theme_orange.png │ ├── theme_solarized.png │ ├── widget_banner.png │ ├── widget_button.png │ ├── widget_clock.png │ ├── widget_colorinput.png │ ├── widget_dropselect.png │ ├── widget_dropselect_multiple.png │ ├── widget_frame.png │ ├── widget_frame_title.png │ ├── widget_image.png │ ├── widget_label.png │ ├── widget_menulink.png │ ├── widget_progressbar.png │ ├── widget_rangeslider.png │ ├── widget_selector.png │ ├── widget_surface.png │ ├── widget_table.png │ ├── widget_table_advanced.png │ ├── widget_textinput.png │ ├── widget_toggleswitch.png │ ├── widget_url.png │ ├── widget_vfill.png │ └── widget_vmargin.png ├── add_widgets.py ├── build.bat ├── conf.py ├── generate_resources.py ├── index.rst └── make.bat ├── pygame_menu ├── __init__.py ├── __pyinstaller │ ├── __init__.py │ └── hook-pygame_menu.py ├── _base.py ├── _decorator.py ├── _scrollarea.py ├── _types.py ├── _widgetmanager.py ├── baseimage.py ├── controls.py ├── events.py ├── examples │ ├── __init__.py │ ├── _resources.py │ ├── game_selector.py │ ├── multi_input.py │ ├── other │ │ ├── __init__.py │ │ ├── calculator.py │ │ ├── dynamic_button_append.py │ │ ├── dynamic_widget_update.py │ │ ├── image_background.py │ │ ├── maze.py │ │ ├── scrollbar.py │ │ ├── scrollbar_area.py │ │ ├── ui_solar_system.py │ │ └── widget_positioning.py │ ├── scroll_menu.py │ ├── simple.py │ ├── timer_clock.py │ └── window_resize.py ├── font.py ├── locals.py ├── menu.py ├── py.typed ├── resources │ ├── fonts │ │ ├── 8bit.ttf │ │ ├── FiraCode-Bold.ttf │ │ ├── FiraCode-Regular.ttf │ │ ├── FiraMono-BoldItalic.ttf │ │ ├── FiraMono-Italic.ttf │ │ ├── LICENSE_DIGITAL.txt │ │ ├── LICENSE_FiraCode.txt │ │ ├── LICENSE_OPENSANS.txt │ │ ├── LICENSE_PTSERIF.txt │ │ ├── bebas.ttf │ │ ├── comic_neue.ttf │ │ ├── digital.ttf │ │ ├── franchise.ttf │ │ ├── helvetica.ttf │ │ ├── munro.ttf │ │ ├── nevis.ttf │ │ ├── opensans_bold.ttf │ │ ├── opensans_italic.ttf │ │ ├── opensans_light.ttf │ │ ├── opensans_regular.ttf │ │ └── ptserif_regular.ttf │ ├── images │ │ ├── carbon_fiber.png │ │ ├── gray_lines.png │ │ ├── metal.png │ │ ├── pygame_menu.png │ │ ├── python.svg │ │ ├── tiled_border.png │ │ └── wallpaper.jpg │ └── sounds │ │ ├── click_mouse.ogg │ │ ├── close_menu.ogg │ │ ├── error.ogg │ │ ├── event.ogg │ │ ├── event_error.ogg │ │ ├── key_add.ogg │ │ ├── key_delete.ogg │ │ ├── open_menu.ogg │ │ └── widget_selection.ogg ├── sound.py ├── themes.py ├── utils.py ├── version.py └── widgets │ ├── __init__.py │ ├── core │ ├── __init__.py │ ├── selection.py │ └── widget.py │ ├── selection │ ├── __init__.py │ ├── arrow_selection.py │ ├── highlight.py │ ├── left_arrow.py │ ├── none.py │ ├── right_arrow.py │ └── simple.py │ └── widget │ ├── __init__.py │ ├── button.py │ ├── colorinput.py │ ├── dropselect.py │ ├── dropselect_multiple.py │ ├── frame.py │ ├── hmargin.py │ ├── image.py │ ├── label.py │ ├── menubar.py │ ├── menulink.py │ ├── none.py │ ├── progressbar.py │ ├── rangeslider.py │ ├── scrollbar.py │ ├── selector.py │ ├── surface.py │ ├── table.py │ ├── textinput.py │ ├── toggleswitch.py │ ├── vfill.py │ └── vmargin.py ├── requirements.txt ├── setup.py └── test ├── __init__.py ├── _utils.py ├── test_base.py ├── test_baseimage.py ├── test_controls.py ├── test_decorator.py ├── test_examples.py ├── test_font.py ├── test_menu.py ├── test_scrollarea.py ├── test_selection.py ├── test_sound.py ├── test_themes.py ├── test_utils.py ├── test_version.py ├── test_widget_button.py ├── test_widget_dropselect.py ├── test_widget_frame.py ├── test_widget_image.py ├── test_widget_label.py ├── test_widget_menubar.py ├── test_widget_none.py ├── test_widget_progressbar.py ├── test_widget_rangeslider.py ├── test_widget_scrollbar.py ├── test_widget_selector.py ├── test_widget_surface.py ├── test_widget_table.py ├── test_widget_textinput.py ├── test_widget_toggleswitch.py └── test_widgets.py /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: https://EditorConfig.org 2 | 3 | # Top-most EditorConfig file 4 | root = true 5 | 6 | # Unix-style newlines 7 | [*] 8 | charset = utf-8 9 | end_of_line = lf 10 | insert_final_newline = false 11 | 12 | # Configure languages 13 | [*.py] 14 | indent_size = 4 15 | indent_style = space 16 | 17 | [{*.json,*.yml}] 18 | indent_size = 2 19 | indent_style = space -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: ppizarror 4 | patreon: # Patreon 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: ppizarror 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Environment information** 11 | Describe your environment information, such as: 12 | 13 | - OS: win/linux 14 | - python version: v3.x 15 | - pygame version: v2.x 16 | - pygame-menu version: v3.x.x 17 | 18 | **Describe the bug** 19 | A clear and concise description of what the bug is. 20 | 21 | **To Reproduce** 22 | Please provide a **minimal** reproducible example that developers can run to investigate the problem. 23 | You can find help for creating such an example [here](https://stackoverflow.com/help/minimal-reproducible-example). 24 | 25 | **Expected behavior** 26 | A clear and concise description of what you expected to happen. 27 | 28 | **Additional context** 29 | Add any other context about the problem here. 30 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | concurrency: 4 | cancel-in-progress: true 5 | group: ${{ github.repository }}-${{ github.workflow }}-${{ github.ref }} 6 | 7 | on: 8 | push: 9 | branches: 10 | - master 11 | pull_request: 12 | branches: 13 | - master 14 | 15 | jobs: 16 | test: 17 | uses: ppizarror/workflow-actions/.github/workflows/test_python.yml@master 18 | strategy: 19 | matrix: 20 | python: [ 3.8, 3.9, '3.10', '3.11', '3.12', '3.13' ] 21 | with: 22 | env-vars: | 23 | SDL_AUDIODRIVER=disk 24 | SDL_VIDEODRIVER=dummy 25 | install-extras: test 26 | os: ubuntu-latest 27 | python-version: ${{ matrix.python }} 28 | 29 | codeql: 30 | uses: ppizarror/workflow-actions/.github/workflows/codeql.yml@master 31 | with: 32 | language: python -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Pycharm files 2 | .idea/ 3 | .ropeproject/ 4 | venv/ 5 | 6 | # Vscode files 7 | .vscode/ 8 | 9 | # Zip files 10 | *.zip 11 | 12 | # Compiled python files 13 | */__pycache__/ 14 | *.pyc 15 | 16 | # Distribution files 17 | *.egg-info 18 | *.spec 19 | build/ 20 | dist/ 21 | 22 | # Other 23 | pygame_menu/examples/other/_test** 24 | pygame_menu/examples/other/sources/** 25 | run_gource.bat 26 | 27 | # Tox 28 | tox.ini 29 | 30 | # Pyproject 31 | pyproject_update.py 32 | pyproject.toml 33 | 34 | # Lock file 35 | *.lock 36 | 37 | # MacOS files 38 | .DS_Store 39 | **._* -------------------------------------------------------------------------------- /.readthedocs.yml: -------------------------------------------------------------------------------- 1 | # .readthedocs.yml 2 | # Read the Docs configuration file 3 | # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details 4 | 5 | # Required 6 | version: 2 7 | 8 | # Configure os 9 | build: 10 | os: ubuntu-22.04 11 | tools: 12 | python: '3.8' 13 | 14 | # Build documentation in the docs/ directory with Sphinx 15 | sphinx: 16 | configuration: docs/conf.py 17 | 18 | # Build PDF & ePub 19 | formats: 20 | - epub 21 | - pdf 22 | 23 | # Optionally set the version of Python and requirements required to build your docs 24 | python: 25 | install: 26 | - method: pip 27 | path: . 28 | extra_requirements: 29 | - docs -------------------------------------------------------------------------------- /.replit: -------------------------------------------------------------------------------- 1 | onBoot = "python setup.py install; clear" 2 | language = "python3" 3 | run = "python pygame_menu/examples/simple.py" 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright 2017 Pablo Pizarro R. @ppizarror 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a 6 | copy of this software and associated documentation files (the "Software"), 7 | to deal in the Software without restriction, including without limitation 8 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 | and/or sell copies of the Software, and to permit persons to whom the Software 10 | is furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 19 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | Note: See included fonts licensing individually. -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | exclude *.bat 2 | exclude *.yml 3 | exclude .github/ISSUE_TEMPLATE/* 4 | exclude .gitignore 5 | exclude .replit 6 | exclude docs/* 7 | exclude docs/_source/* 8 | exclude docs/_static/* 9 | exclude pygame_menu/examples/other/_test*.py 10 | exclude test/*.py 11 | 12 | include requirements.txt 13 | include pygame_menu/py.typed 14 | 15 | recursive-include pygame_menu/resources/fonts *.ttf 16 | recursive-include pygame_menu/resources/fonts *.txt 17 | recursive-include pygame_menu/resources/images *.jpg 18 | recursive-include pygame_menu/resources/images *.png 19 | recursive-include pygame_menu/resources/images *.svg 20 | recursive-include pygame_menu/resources/sounds *.ogg -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | =========== 2 | pygame-menu 3 | =========== 4 | 5 | .. image:: docs/_static/pygame_menu_small.png 6 | :align: center 7 | :alt: 8 | 9 | .. image:: https://img.shields.io/badge/author-Pablo%20Pizarro%20R.-lightgray.svg 10 | :target: https://ppizarror.com 11 | :alt: @ppizarror 12 | 13 | .. image:: https://img.shields.io/badge/license-MIT-blue.svg 14 | :target: https://opensource.org/licenses/MIT 15 | :alt: License MIT 16 | 17 | .. image:: https://img.shields.io/badge/python-3.8+-red.svg 18 | :target: https://www.python.org/downloads 19 | :alt: Python 3.8+ 20 | 21 | .. image:: https://img.shields.io/badge/pygame-1.9.3%2B%2F2.0%2B-orange 22 | :target: https://www.pygame.org 23 | :alt: Pygame 1.9.3+/2.0+ 24 | 25 | .. image:: https://badge.fury.io/py/pygame-menu.svg 26 | :target: https://pypi.org/project/pygame-menu 27 | :alt: PyPi package 28 | 29 | .. image:: https://img.shields.io/github/actions/workflow/status/ppizarror/pygame-menu/ci.yml?branch=master 30 | :target: https://github.com/ppizarror/pygame-menu/actions/workflows/ci.yml 31 | :alt: Build status 32 | 33 | .. image:: https://app.fossa.com/api/projects/git%2Bgithub.com%2Fppizarror%2Fpygame-menu.svg?type=shield 34 | :target: https://app.fossa.com/projects/git%2Bgithub.com%2Fppizarror%2Fpygame-menu?ref=badge_shield 35 | :alt: FOSSA Status 36 | 37 | .. image:: https://readthedocs.org/projects/pygame-menu/badge/?version=latest 38 | :target: https://pygame-menu.readthedocs.io 39 | :alt: Documentation Status 40 | 41 | .. image:: https://codecov.io/gh/ppizarror/pygame-menu/branch/master/graph/badge.svg 42 | :target: https://codecov.io/gh/ppizarror/pygame-menu 43 | :alt: Codecov 44 | 45 | .. image:: https://img.shields.io/github/issues/ppizarror/pygame-menu 46 | :target: https://github.com/ppizarror/pygame-menu/issues 47 | :alt: Open issues 48 | 49 | .. image:: https://img.shields.io/pypi/dm/pygame-menu?color=purple 50 | :target: https://pypi.org/project/pygame-menu/ 51 | :alt: PyPi downloads 52 | 53 | .. image:: https://static.pepy.tech/personalized-badge/pygame-menu?period=total&units=international_system&left_color=grey&right_color=lightgrey&left_text=total%20downloads 54 | :target: https://pepy.tech/project/pygame-menu 55 | :alt: Total downloads 56 | 57 | .. image:: https://img.shields.io/badge/buy%20me%20a-Ko--fi-02b9fe 58 | :target: https://ko-fi.com/ppizarror 59 | :alt: Buy me a Ko-fi 60 | 61 | Source repo on `GitHub `_, 62 | and run it on `Repl.it `_ 63 | 64 | 65 | Introduction 66 | ------------ 67 | 68 | Pygame-menu is a `python-pygame `_ library for creating menus and GUIs. 69 | It supports several widgets, such as buttons, color inputs, clock objects, drop selectors, 70 | frames, images, labels, selectors, tables, text inputs, color switches, and many 71 | more, with multiple customization options. 72 | 73 | Comprehensive documentation for the latest version is available at 74 | https://pygame-menu.readthedocs.io 75 | 76 | **Note**: For `pygame-ce`, check out `pygame-menu-ce `_. 77 | 78 | 79 | Install Instructions 80 | -------------------- 81 | 82 | Pygame-menu can be installed via pip. Simply run: 83 | 84 | .. code-block:: bash 85 | 86 | $> pip install pygame-menu -U 87 | 88 | To build the documentation from a Git repository: 89 | 90 | .. code-block:: bash 91 | 92 | $> clone https://github.com/ppizarror/pygame-menu 93 | $> cd pygame-menu 94 | $> pip install -e ."[docs]" 95 | $> cd docs 96 | $> make html 97 | -------------------------------------------------------------------------------- /build.py: -------------------------------------------------------------------------------- 1 | """ 2 | pygame-menu 3 | https://github.com/ppizarror/pygame-menu 4 | 5 | BUILD 6 | Build file. 7 | """ 8 | 9 | import os 10 | import shutil 11 | import sys 12 | 13 | assert len(sys.argv) == 2, 'Argument is required, usage: build.py pip/twine' 14 | mode: str = sys.argv[1].strip() 15 | 16 | if mode == 'pip': 17 | if os.path.isdir('dist'): 18 | for k in os.listdir('dist'): 19 | if 'pygame_menu-' in k or 'pygame-menu-' in k: 20 | os.remove(f'dist/{k}') 21 | if os.path.isdir('build'): 22 | for k in os.listdir('build'): 23 | if 'bdist.' in k or k == 'lib': 24 | shutil.rmtree(f'build/{k}') 25 | os.system(f'python setup.py sdist bdist_wheel') 26 | 27 | elif mode == 'twine': 28 | if os.path.isdir('dist'): 29 | os.system(f'python -m twine upload dist/*') 30 | else: 31 | raise FileNotFoundError('Not distribution has been found, execute build.py pip') 32 | 33 | else: 34 | raise ValueError(f'Unknown mode {mode}') 35 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | ignore: 2 | - "build.py" 3 | - "docs/*.py" 4 | - "pygame_menu/__pyinstaller/*py" 5 | - "pygame_menu/examples/*.py" 6 | - "pygame_menu/examples/other/*.py" 7 | - "setup.py" 8 | - "test/*.py" -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line, and also 5 | # from the environment for the first two. 6 | SPHINXOPTS ?= 7 | SPHINXBUILD ?= sphinx-build 8 | SOURCEDIR = . 9 | BUILDDIR = build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 21 | -------------------------------------------------------------------------------- /docs/_source/add_sounds.rst: -------------------------------------------------------------------------------- 1 | .. module:: pygame_menu.sound 2 | 3 | ============= 4 | Adding sounds 5 | ============= 6 | 7 | A sound engine can be created using the :py:class:`Sound` class. The sound engine 8 | can be customized by setting a sound file to several sounds defined by a type. 9 | 10 | **Example:** 11 | 12 | .. code-block:: python 13 | 14 | import pygame_menu 15 | from pygame_menu import sound 16 | 17 | engine = sound.Sound() 18 | engine.set_sound(sound.SOUND_TYPE_CLICK_MOUSE, '/home/me/click.ogg') 19 | engine.set_sound(sound.SOUND_TYPE_OPEN_MENU, '/home/me/open.ogg') 20 | 21 | menu = pygame_menu.Menu(...) 22 | menu.set_sound(engine, recursive=True) # Apply on menu and all sub-menus 23 | 24 | Sound types are the following: 25 | 26 | ======================================================== ========================= 27 | Type Description 28 | ======================================================== ========================= 29 | :py:data:`pygame_menu.sound.SOUND_TYPE_CLICK_MOUSE` Mouse click 30 | :py:data:`pygame_menu.sound.SOUND_TYPE_CLICK_TOUCH` Touch click 31 | :py:data:`pygame_menu.sound.SOUND_TYPE_CLOSE_MENU` A menu is closed 32 | :py:data:`pygame_menu.sound.SOUND_TYPE_ERROR` Generic error 33 | :py:data:`pygame_menu.sound.SOUND_TYPE_EVENT` Generic event 34 | :py:data:`pygame_menu.sound.SOUND_TYPE_EVENT_ERROR` Error generated by user 35 | :py:data:`pygame_menu.sound.SOUND_TYPE_KEY_ADDITION` User type a key 36 | :py:data:`pygame_menu.sound.SOUND_TYPE_KEY_DELETION` User deletes with a key 37 | :py:data:`pygame_menu.sound.SOUND_TYPE_OPEN_MENU` A menu is opened 38 | :py:data:`pygame_menu.sound.SOUND_TYPE_WIDGET_SELECTION` A widget is selected 39 | ======================================================== ========================= 40 | 41 | .. autoclass:: Sound 42 | :members: 43 | -------------------------------------------------------------------------------- /docs/_source/add_widgets_manager.rst: -------------------------------------------------------------------------------- 1 | :orphan: 2 | 3 | .. module:: pygame_menu._widgetmanager 4 | 5 | ============= 6 | WidgetManager 7 | ============= 8 | 9 | .. autoclass:: pygame_menu._widgetmanager.WidgetManager 10 | :members: 11 | :noindex: 12 | -------------------------------------------------------------------------------- /docs/_source/advanced_controller.rst: -------------------------------------------------------------------------------- 1 | ==================== 2 | Configure controller 3 | ==================== 4 | 5 | The pygame-menu driver controller is very simple, and can be modified in two 6 | different ways. 7 | 8 | First, in ``pygame_menu.controls`` there are different constants to modify each 9 | key to different events, such as apply on a widget, scroll left or right, among 10 | others. If any constant is modified it will apply to the whole library. 11 | 12 | =============================================== =========================== 13 | Event Description 14 | =============================================== =========================== 15 | :py:data:`pygame_menu.controls.KEY_APPLY` Apply on widget 16 | :py:data:`pygame_menu.controls.KEY_BACK` Move back on menu or widget 17 | :py:data:`pygame_menu.controls.KEY_CLOSE_MENU` Close menu 18 | :py:data:`pygame_menu.controls.KEY_LEFT` Move left 19 | :py:data:`pygame_menu.controls.KEY_MOVE_DOWN` Move down 20 | :py:data:`pygame_menu.controls.KEY_MOVE_UP` Move up 21 | :py:data:`pygame_menu.controls.KEY_RIGHT` Move right 22 | :py:data:`pygame_menu.controls.KEY_TAB` Apply tab 23 | =============================================== =========================== 24 | 25 | Note: See ``pygame_menu.controls`` module for more information. 26 | 27 | The following example changes the return key from ``RETURN`` to ``A``: 28 | 29 | .. code-block:: python 30 | 31 | import pygame_menu.controls as ctrl 32 | ctrl.KEY_APPLY = pygame.K_a 33 | 34 | ... 35 | menu.add.button('button', lambda: print('Clicked!')) 36 | 37 | As you might have seen, this procedure to change events is very simple, but limited. 38 | For such reason, pygame-menu provides another way to change the controls, by using 39 | the ``Controller`` object. 40 | 41 | This class can be passed to widgets or menu by calling ``object.set_controller(controller)``. 42 | Controller class defines several functions that can be overriden, or you can create 43 | a subclass using inheritance. For example, the following example changes ``apply`` 44 | event to keys ``A``, ``B`` or ``C``, and additionally this changes the menu background 45 | color on demand. Methods must return ``True`` if satisfy the event condition. 46 | 47 | .. code-block:: python 48 | 49 | from pygame_menu.controls import Controller 50 | from random import randrange 51 | 52 | # Create a controller 53 | custom_controller = Controller() 54 | 55 | def btn_apply(event, menu_object): 56 | applied = event.key in (pygame.K_a, pygame.K_b, pygame.K_c) 57 | if applied: 58 | random_color = (randrange(0, 255), randrange(0, 255), randrange(0, 255)) 59 | menu_object.get_scrollarea().update_area_color(random_color) 60 | return applied 61 | 62 | custom_controller.apply = btn_apply 63 | 64 | ... 65 | button = menu.add.button('My button', lambda: print('Clicked!')) 66 | button.set_controller(custom_controller) # Pass new controller to object 67 | 68 | .. autoclass:: pygame_menu.controls.Controller 69 | :members: -------------------------------------------------------------------------------- /docs/_source/advanced_selection.rst: -------------------------------------------------------------------------------- 1 | :orphan: 2 | 3 | ======================== 4 | Widget selection effects 5 | ======================== 6 | 7 | Core Class 8 | ---------------- 9 | 10 | .. module:: pygame_menu.widgets.core.selection 11 | 12 | .. autoclass:: pygame_menu.widgets.core.Selection 13 | :members: 14 | 15 | 16 | Highlight Selection 17 | ------------------- 18 | 19 | .. module:: pygame_menu.widgets.selection.highlight 20 | 21 | .. autoclass:: pygame_menu.widgets.HighlightSelection 22 | :members: 23 | :show-inheritance: 24 | 25 | 26 | Left Arrow Selection 27 | -------------------- 28 | 29 | .. module:: pygame_menu.widgets.selection.left_arrow 30 | 31 | .. autoclass:: pygame_menu.widgets.LeftArrowSelection 32 | :members: 33 | :show-inheritance: 34 | 35 | 36 | None Selection 37 | -------------- 38 | 39 | .. module:: pygame_menu.widgets.selection.none 40 | 41 | .. autoclass:: pygame_menu.widgets.NoneSelection 42 | :members: 43 | :show-inheritance: 44 | 45 | 46 | Right Arrow Selection 47 | --------------------- 48 | 49 | .. module:: pygame_menu.widgets.selection.right_arrow 50 | 51 | .. autoclass:: pygame_menu.widgets.RightArrowSelection 52 | :members: 53 | :show-inheritance: 54 | 55 | 56 | Simple Selection 57 | ---------------- 58 | 59 | .. module:: pygame_menu.widgets.selection.simple 60 | 61 | .. autoclass:: pygame_menu.widgets.SimpleSelection 62 | :members: 63 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_source/advanced_widget.rst: -------------------------------------------------------------------------------- 1 | :orphan: 2 | 3 | .. module:: pygame_menu.widgets.core.widget 4 | 5 | ====== 6 | Widget 7 | ====== 8 | 9 | .. autoclass:: pygame_menu.widgets.core.widget.Widget 10 | :members: 11 | -------------------------------------------------------------------------------- /docs/_source/base.rst: -------------------------------------------------------------------------------- 1 | :orphan: 2 | 3 | .. module:: pygame_menu._base 4 | 5 | ==== 6 | Base 7 | ==== 8 | 9 | .. autoclass:: pygame_menu._base.Base 10 | :members: 11 | :noindex: 12 | -------------------------------------------------------------------------------- /docs/_source/baseimage.rst: -------------------------------------------------------------------------------- 1 | ========= 2 | BaseImage 3 | ========= 4 | 5 | Image class used by ``pygame-menu``. 6 | 7 | 8 | Drawing image modes 9 | ------------------- 10 | 11 | ===================================================== =========================================== 12 | Drawing mode Description 13 | ===================================================== =========================================== 14 | :py:data:`pygame_menu.baseimage.IMAGE_MODE_CENTER` Image is drawn at the center of the surface 15 | :py:data:`pygame_menu.baseimage.IMAGE_MODE_FILL` Image fills the surface 16 | :py:data:`pygame_menu.baseimage.IMAGE_MODE_REPEAT_X` Image repeats on X axis 17 | :py:data:`pygame_menu.baseimage.IMAGE_MODE_REPEAT_XY` Image repeats on both axis 18 | :py:data:`pygame_menu.baseimage.IMAGE_MODE_REPEAT_Y` Image repeats on Y axis 19 | :py:data:`pygame_menu.baseimage.IMAGE_MODE_SIMPLE` Just place the image in the top/left corner 20 | ===================================================== =========================================== 21 | 22 | 23 | BaseImage - API 24 | --------------- 25 | 26 | .. module:: pygame_menu.baseimage 27 | 28 | .. autoclass:: pygame_menu.baseimage.BaseImage 29 | :members: 30 | -------------------------------------------------------------------------------- /docs/_source/contributors.rst: -------------------------------------------------------------------------------- 1 | ============ 2 | Contributors 3 | ============ 4 | 5 | Core developers: 6 | 7 | - `Pablo Pizarro R. `_ 8 | 9 | Main contributors: 10 | 11 | - `anxuae `_ 12 | - `eforgacs `_ 13 | 14 | Other contributors: 15 | 16 | - `apuly `_ 17 | - `arpruss `_ 18 | - `asierrayk `_ 19 | - `DA820 `_ 20 | - `i96751414 `_ 21 | - `ironsmile `_ 22 | - `jwllee `_ 23 | - `maditnerd `_ 24 | - `MayuSakurai `_ 25 | - `mrkprdo `_ 26 | - `notrurs `_ 27 | - `NullP01nt `_ 28 | - `PandaRoux8 `_ 29 | - `Rifqi31 `_ 30 | - `ThePeeps191 `_ 31 | - `thisIsMikeKane `_ 32 | - `vnmabus `_ 33 | - `werdeil `_ 34 | - `zPaw `_ 35 | - `neilsimp1 `_ 36 | 37 | Ideas and contributions are always welcome. Any found bugs or enhancement 38 | suggestions should be posted on the `GitHub project page `_. -------------------------------------------------------------------------------- /docs/_source/create_menu.rst: -------------------------------------------------------------------------------- 1 | .. module:: pygame_menu.menu 2 | 3 | ============== 4 | Creating menus 5 | ============== 6 | 7 | Ready to go deeper into menu usage? 8 | 9 | 10 | Configuring the menu 11 | -------------------- 12 | 13 | The :py:class:`pygame_menu.menu.Menu` is the base class to draw the graphical items 14 | on the screen. It offers many parameters to let you adapt the behavior and the visual 15 | aspects of the menu. 16 | 17 | The less trivial ones are explained here. 18 | 19 | 20 | Widget position 21 | ^^^^^^^^^^^^^^^ 22 | 23 | By default, the widgets are centered horizontally by theme, included in a virtual 24 | rectangle positioned at 0 pixel below the title bar and 0 pixel from the left border 25 | (``widget_offset=(0, 0)``). 26 | 27 | In the same way, an offset can be defined for the title using the parameter 28 | ``title_offset``. 29 | 30 | The content of the menu can be centered vertically after all widgets have been 31 | added by calling the method :py:meth:`pygame_menu.menu.Menu.center_content`: 32 | 33 | .. code-block:: python 34 | :emphasize-lines: 6 35 | 36 | menu = pygame_menu.Menu(...) 37 | 38 | menu.add.text_input(...) 39 | menu.add.selector(...) 40 | menu.add.button(...) 41 | menu.center_content() 42 | 43 | 44 | .. note:: 45 | 46 | If the menu size is insufficient to show all of the widgets, horizontal and/or 47 | vertical scrollbar(s) will appear automatically. 48 | 49 | 50 | Column and row 51 | ^^^^^^^^^^^^^^ 52 | 53 | By default, the widgets are arranged in one unique column. But using the 54 | ``columns`` and ``rows`` parameters, it is possible to arrange them in a grid. 55 | 56 | The defined grid of ``columns`` x ``rows`` cells will be completed with the 57 | widgets (in order of definition) **column by column** starting at the **top-left** 58 | corner of the menu. 59 | 60 | Also the width of each column can be set using ``column_max_width`` and 61 | ``column_min_width`` Menu parameters. 62 | 63 | 64 | On-close callback 65 | ^^^^^^^^^^^^^^^^^ 66 | 67 | A callback can be defined using the ``onclose`` parameter; it will be called when 68 | the menu (end sub-menu) is closing. Closing the menu is the same as *disabling* 69 | it, but with callback firing. 70 | 71 | ``onclose`` parameter can take one of these three types of values: 72 | 73 | - ``None``, the menu don't disables if :py:meth:`pygame_menu.menu.Menu.close` 74 | is called 75 | - A python callable object (a function, a method) that will be called without 76 | any arguments, or with the ``Menu`` instance. 77 | - A specific event of :py:mod:`pygame_menu`. The possible events are the 78 | following: 79 | 80 | =========================================== ======================================================== 81 | Event Description 82 | =========================================== ======================================================== 83 | :py:data:`pygame_menu.events.BACK` Go back to the previous menu and disable the current 84 | :py:data:`pygame_menu.events.CLOSE` Only disables the current menu 85 | :py:data:`pygame_menu.events.NONE` The same as ``onclose=None`` 86 | :py:data:`pygame_menu.events.EXIT` Exit the program (not only the menu) 87 | :py:data:`pygame_menu.events.RESET` Go back to the first opened menu and disable the current 88 | =========================================== ======================================================== 89 | 90 | 91 | Display a menu 92 | -------------- 93 | 94 | The :ref:`First steps` chapter shows the way to display the menu, this method lets 95 | `pygame-menu` managing the event loop by calling the 96 | :py:meth:`pygame_menu.menu.Menu.mainloop`: 97 | 98 | .. code-block:: python 99 | :emphasize-lines: 6 100 | 101 | def draw_background(): 102 | ... 103 | 104 | mymenu = Menu(...) 105 | 106 | mymenu.mainloop(surface, bgfun=draw_background) 107 | 108 | There is a second way that gives more flexibility to the application because the 109 | events loop remains managed outside of the menu. In this case the application is 110 | in charge to update and draw the menu when it is necessary. 111 | 112 | .. code-block:: python 113 | :emphasize-lines: 15,16,17 114 | 115 | def draw_background(): 116 | ... 117 | 118 | mymenu = Menu(...) 119 | 120 | while True: 121 | 122 | draw_background() 123 | 124 | events = pygame.event.get() 125 | for event in events: 126 | if event.type == pygame.QUIT: 127 | exit() 128 | 129 | if mymenu.is_enabled(): 130 | mymenu.draw(surface) 131 | mymenu.update(events) 132 | 133 | pygame.display.update() 134 | 135 | 136 | Menu API 137 | -------- 138 | 139 | .. Document here only the members relative to the menu itself, members 140 | .. for adding widgets are documented in another chapter. 141 | 142 | .. autoclass:: Menu 143 | :members: 144 | :exclude-members: add_button, add_color_input, add_image, add_label, add_text_input, add_selector, add_vertical_margin, add_generic_widget 145 | -------------------------------------------------------------------------------- /docs/_source/events.rst: -------------------------------------------------------------------------------- 1 | :orphan: 2 | 3 | .. module:: pygame_menu.events 4 | 5 | ====== 6 | Events 7 | ====== 8 | 9 | .. autoclass:: pygame_menu.events.MenuAction 10 | :members: 11 | :show-inheritance: 12 | -------------------------------------------------------------------------------- /docs/_source/license.rst: -------------------------------------------------------------------------------- 1 | ======= 2 | License 3 | ======= 4 | 5 | .. include:: ../../LICENSE 6 | 7 | The official license can be retrieved `here `_. 8 | -------------------------------------------------------------------------------- /docs/_source/migration_guide_2_to_3.rst: -------------------------------------------------------------------------------- 1 | ========================== 2 | Migration Guide - v2 to v3 3 | ========================== 4 | 5 | - Removed from library 6 | - Renamed library ``pygameMenu`` to ``pygame_menu`` 7 | - Removed all configuration variables from ``pygameMenu.config`` 8 | - Removed ``TextMenu``, use ``Menu`` and ``add_label()`` method instead 9 | - New Menu behaviour 10 | - Menu manage the event loop and drawing using ``Menu.mainloop(surface, bgfun, disable_loop=False, fps_limit=0)`` 11 | - User's application manage the event loop, using ``Menu.update(events)`` and ``Menu.draw(surface)`` 12 | - Removed from Menu class 13 | - ``add_option()``, use ``add_button()`` instead 14 | - ``set_fps()``, use ``fps_limit`` from ``mainloop()`` instead 15 | - Constructor parameters: 16 | - ``bgfun``, now this function is required by ``Menu.mainloop()`` 17 | - ``color_selected``, moved to ``selection_color`` of :py:class:`pygame_menu.themes.Theme` 18 | - ``dopause``, now user can control this behaviour using ``update()`` or ``mainloop()`` 19 | - ``draw_region_x``, moved to ``widget_offset`` of :py:class:`pygame_menu.themes.Theme` 20 | - ``draw_region_y``, moved to ``widget_offset`` of :py:class:`pygame_menu.themes.Theme` 21 | - ``draw_select``, moved to ``widget_selection_effect`` of :py:class:`pygame_menu.themes.Theme` 22 | - ``font_color``, moved to ``widget_font_color`` of :py:class:`pygame_menu.themes.Theme` 23 | - ``font_size_title``, moved to ``title_font_size`` of :py:class:`pygame_menu.themes.Theme` 24 | - ``font_size``, moved to ``widget_font_size`` of :py:class:`pygame_menu.themes.Theme` 25 | - ``font_title``, moved to ``title_font`` of :py:class:`pygame_menu.themes.Theme` 26 | - ``font``, moved to ``widget_font`` of :py:class:`pygame_menu.themes.Theme` 27 | - ``fps``, use ``fps_limit`` from ``mainloop()`` instead 28 | - ``menu_alpha``, now each color of :py:class:`pygame_menu.themes.Theme` can be defined with opacity 29 | - ``menu_color_title``, moved to ``title_background_color`` of :py:class:`pygame_menu.themes.Theme` 30 | - ``menu_color``, moved to ``background_color`` of :py:class:`pygame_menu.themes.Theme` 31 | - ``menu_height``, use ``height`` 32 | - ``menu_width``, use ``width`` 33 | - ``option_margin``, moved to ``widget_margin`` of :py:class:`pygame_menu.themes.Theme` 34 | - ``option_shadow_offset``, moved to ``widget_shadow_offset`` of :py:class:`pygame_menu.themes.Theme` 35 | - ``option_shadow_position``, moved to ``widget_shadow_position`` of :py:class:`pygame_menu.themes.Theme` 36 | - ``option_shadow``, moved to ``widget_shadow`` of :py:class:`pygame_menu.themes.Theme` 37 | - ``rect_width``, now change selection effect from :py:class:`pygame_menu.themes.Theme` 38 | - ``surface``, now pygame surface is only required by ``mainloop()`` and ``update()`` 39 | - ``title_offsetx``, moved to ``title_offset`` of :py:class:`pygame_menu.themes.Theme` 40 | - ``title_offsety``, moved to ``title_offset`` of :py:class:`pygame_menu.themes.Theme` 41 | - ``window_width`` and ``window_height`` parameters 42 | - Renamed Menu method parameters 43 | - ``element_name`` and ``element`` from ``add_button()`` to ``title`` and ``action`` 44 | - ``values`` from ``add_selector()`` to ``items`` 45 | - ``widget_id`` from ``add_button()`` to ``button_id`` 46 | -------------------------------------------------------------------------------- /docs/_source/migration_guide_3_to_4.rst: -------------------------------------------------------------------------------- 1 | ========================== 2 | Migration Guide - v3 to v4 3 | ========================== 4 | 5 | - ``pygame_menu v4`` no longer python 2.7 to 3.5. 6 | - ``VMargin`` widget now updates it's height rather than modifying the margin. 7 | - Added ``__all__`` to module, then some usage cases importing with * may fail. 8 | - All locals inner value have changed. If you used the value as-is you'll get an error. 9 | - BaseImage applies ``smooth`` by default, also rotation applies on checkpointed surface. 10 | - Menu ``add_button``, ``add_color_input``, ``add_image``, ``add_label``, ``add_selector``, ``add_text_input``, ``add_vertical_margin`` and ``add_generic_widget`` were moved to ``WidgetManager`` class. 11 | - Menu ``add_image`` method parameter ``scale_smooth`` is now ``True`` by default. 12 | - Menu ``clear`` method now receives ``reset`` optional argument. 13 | - Menu ``mainloop``, ``update`` and ``draw`` now raises ``RuntimeError`` if it's disabled. This behaviour can be changed though Menu private property ``_runtime_errors``. 14 | - Menu column/row positioning has changed, now ``column_max_width`` has a different behaviour. For setting the minimum width of columns use ``column_min_width``. Expect some minor changes to the global layout. Now is much more consistent. 15 | - Menu constructor changed from ``Menu(height, width, title, ...)`` to ``Menu(title, width, height, ...)``. 16 | - Menu method ``get_width()`` changes to``get_width(inner=False, widget=False)``. 17 | - Moved ``previsualization_width`` colorinput method to ``kwargs``. 18 | - Removed ``column_force_fit_text`` from ``Menu`` constructor. Use Widget ``set_max_width`` or ``set_max_height`` instead. 19 | - Removed ``dummy_function`` from ``pygame_menu.utils``. 20 | - Removed ``events.DISABLE_CLOSE``, use ``None`` or ``events.NONE`` instead. 21 | - Removed ``Widget`` method ``surface_needs_update()``. Now use method ``force_menu_surface_update`` if needed. 22 | - Renamed ``ColorInput`` constants ``TYPE_HEX``, ``TYPE_RGB``, ``HEX_FORMAT_LOWER``, ``HEX_FORMAT_NONE``, and ``HEX_FORMAT_UPPER``, to ``COLORINPUT_*``. 23 | - Renamed ``touchscreen_enabled`` to ``touchscreen`` in ``Menu`` constructor. 24 | - Renamed ``Widget`` method from ``set_selected(selected=True)`` to ``select(status=True, update_menu=False)``. 25 | - Renamed Menu constructor parameter ``menu_position`` to ``position``. 26 | - Renamed Selector ``elements`` to ``items``. 27 | - Renamed Selector ``update_elements`` to ``update_items``. 28 | - Renamed Theme ``menubar_close_button`` to ``title_close_button``. 29 | - Renamed Theme ``title_shadow_color`` to ``title_font_shadow_color``. 30 | - Renamed Theme ``title_shadow_offset`` to ``title_font_shadow_offset``. 31 | - Renamed Theme ``title_shadow_position` to ``title_font_shadow_position``. 32 | - Renamed Theme ``title_shadow`` to ``title_font_shadow``. 33 | - Renamed Theme ``widget_shadow_color`` to ``widget_font_shadow_color``. 34 | - Renamed Theme ``widget_shadow_offset`` to ``widget_font_shadow_offset``. 35 | - Renamed Theme ``widget_shadow_position` to ``widget_font_shadow_position``. 36 | - Renamed Theme ``widget_shadow`` to ``widget_font_shadow``. 37 | - Renamed Widget ``_force_menu_surface_update`` method to ``force_menu_surface_update``. 38 | - Renamed Widget ``_force_menu_surface_update`` method to ``force_menu_surface_update``. 39 | - Renamed Widget ``expand_background_inflate_to_selection_effect`` method to ``background_inflate_to_selection_effect``. 40 | - Widget ``selected`` property is now private. Use ``is_selected()`` to check selection status, and ``select(...)`` to modify it. 41 | - Widget ``shadow_offset`` now cannot be ``None`` or ``float``, only ``int`` allowed. 42 | - Widget ``sound`` property is now private. Use ``.get_sound()`` or ``.set_sound()``. 43 | - Widget ``visible`` property is now private. Use ``.is_visible()`` to check visibility status, and ``.show()`` or ``.hide()`` to modify it. 44 | - Widget ``VMargin`` now inherits from ``NoneWidget``. 45 | - Widget properties ``joystick_enabled``, ``mouse_enabled``, ``touchscreen_enabled`` and ``sound`` are now private. 46 | - WidgetManager methods renamed ``shadow`` to ``font_shadow`` for each shadow-related optional arguments. 47 | - Widgets now must define only ``_draw``, ``draw()`` is reserved to Widget core class only. 48 | -------------------------------------------------------------------------------- /docs/_source/scrollarea.rst: -------------------------------------------------------------------------------- 1 | .. module:: pygame_menu._scrollarea 2 | 3 | ========== 4 | ScrollArea 5 | ========== 6 | 7 | .. autoclass:: pygame_menu._scrollarea.ScrollArea 8 | :members: 9 | -------------------------------------------------------------------------------- /docs/_source/widgets_button.rst: -------------------------------------------------------------------------------- 1 | .. module:: pygame_menu.widgets.widget.button 2 | 3 | ====== 4 | Button 5 | ====== 6 | 7 | .. autoclass:: pygame_menu.widgets.Button 8 | :members: 9 | :show-inheritance: 10 | :inherited-members: 11 | :exclude-members: change, draw_after_if_selected, get_value, reset_value, set_default_value, set_onchange, set_value, value_changed 12 | -------------------------------------------------------------------------------- /docs/_source/widgets_colorinput.rst: -------------------------------------------------------------------------------- 1 | .. module:: pygame_menu.widgets.widget.colorinput 2 | 3 | ========== 4 | ColorInput 5 | ========== 6 | 7 | .. autoclass:: pygame_menu.widgets.ColorInput 8 | :members: 9 | :show-inheritance: 10 | :inherited-members: 11 | :exclude-members: draw_after_if_selected, resize, rotate, scale, set_max_height, set_max_width 12 | -------------------------------------------------------------------------------- /docs/_source/widgets_dropselect.rst: -------------------------------------------------------------------------------- 1 | .. module:: pygame_menu.widgets.widget.dropselect 2 | 3 | ========== 4 | DropSelect 5 | ========== 6 | 7 | .. autoclass:: pygame_menu.widgets.DropSelect 8 | :members: 9 | :show-inheritance: 10 | :inherited-members: 11 | :exclude-members: flip, resize, rotate, scale, set_max_height, set_max_width 12 | -------------------------------------------------------------------------------- /docs/_source/widgets_dropselect_multiple.rst: -------------------------------------------------------------------------------- 1 | .. module:: pygame_menu.widgets.widget.dropselect_multiple 2 | 3 | ================== 4 | DropSelectMultiple 5 | ================== 6 | 7 | .. autoclass:: pygame_menu.widgets.DropSelectMultiple 8 | :members: 9 | :show-inheritance: 10 | :inherited-members: 11 | :exclude-members: flip, resize, rotate, scale, set_max_height, set_max_width 12 | -------------------------------------------------------------------------------- /docs/_source/widgets_frame.rst: -------------------------------------------------------------------------------- 1 | .. module:: pygame_menu.widgets.widget.frame 2 | 3 | ===== 4 | Frame 5 | ===== 6 | 7 | .. autoclass:: pygame_menu.widgets.Frame 8 | :members: 9 | :show-inheritance: 10 | :inherited-members: 11 | :exclude-members: apply, background_inflate_to_selection_effect, change, draw_after_if_selected, flip, get_font_color_status, get_selected_time, get_selection_effect, get_sound, get_value, is_selected, reset_value, rotate, scale, select, set_default_value, set_max_height, set_max_width, set_onchange, set_onreturn, set_onselect, set_selection_effect, set_shadow, set_sound, set_value, value_changed 12 | -------------------------------------------------------------------------------- /docs/_source/widgets_hmargin.rst: -------------------------------------------------------------------------------- 1 | .. module:: pygame_menu.widgets.widget.hmargin 2 | 3 | ======= 4 | HMargin 5 | ======= 6 | 7 | .. autoclass:: pygame_menu.widgets.HMargin 8 | :members: 9 | :show-inheritance: 10 | :inherited-members: 11 | :exclude-members: add_self_to_kwargs, apply, background_inflate_to_selection_effect, change, draw_after_if_selected, flip, get_border, get_focus_rect, get_font_color_status, get_font_info, get_height, get_margin, get_padding, get_rect, get_selected_time, get_selection_effect, get_size, get_sound, get_surface, get_title, get_translate, get_value, get_width, is_selected, mouseleave, mouseover, render, reset_value, resize, rotate, scale, select, set_background_color, set_border, set_controls, set_cursor, set_default_value, set_font, set_font_shadow, set_margin, set_max_height, set_max_width, set_onchange, set_onmouseleave, set_onmouseover, set_onreturn, set_onselect, set_padding, set_position, set_selection_effect, set_shadow, set_sound, set_tab_size, set_title, set_value, shadow, translate, update_font, value_changed, update 12 | -------------------------------------------------------------------------------- /docs/_source/widgets_image.rst: -------------------------------------------------------------------------------- 1 | .. module:: pygame_menu.widgets.widget.image 2 | 3 | ====== 4 | Image 5 | ====== 6 | 7 | .. autoclass:: pygame_menu.widgets.Image 8 | :members: 9 | :show-inheritance: 10 | :inherited-members: 11 | :exclude-members: apply, change, draw_after_if_selected, get_font_color_status, get_font_info, get_sound, get_title, get_value, reset_value, set_default_value, set_font, set_font_shadow, set_onchange, set_onreturn, set_sound, set_tab_size, set_title, set_value, update, update_font, value_changed 12 | -------------------------------------------------------------------------------- /docs/_source/widgets_label.rst: -------------------------------------------------------------------------------- 1 | .. module:: pygame_menu.widgets.widget.label 2 | 3 | ===== 4 | Label 5 | ===== 6 | 7 | .. autoclass:: pygame_menu.widgets.Label 8 | :members: 9 | :show-inheritance: 10 | :inherited-members: 11 | :exclude-members: apply, change, draw_after_if_selected, get_sound, get_value, reset_value, set_default_value, set_onchange, set_onreturn, set_sound, set_value, update, value_changed 12 | -------------------------------------------------------------------------------- /docs/_source/widgets_menubar.rst: -------------------------------------------------------------------------------- 1 | .. module:: pygame_menu.widgets.widget.menubar 2 | 3 | ======= 4 | MenuBar 5 | ======= 6 | 7 | .. autoclass:: pygame_menu.widgets.MenuBar 8 | :members: 9 | :show-inheritance: 10 | :inherited-members: 11 | :exclude-members: change, draw_after_if_selected, flip, get_value, reset_value, resize, rotate, scale, select, set_border, set_default_value, set_max_height, set_max_width, set_onchange, set_onselect, set_padding, set_selection_effect, set_value, value_changed 12 | -------------------------------------------------------------------------------- /docs/_source/widgets_menulink.rst: -------------------------------------------------------------------------------- 1 | .. module:: pygame_menu.widgets.widget.menulink 2 | 3 | ======== 4 | MenuLink 5 | ======== 6 | 7 | .. autoclass:: pygame_menu.widgets.MenuLink 8 | :members: 9 | :show-inheritance: 10 | :inherited-members: 11 | :exclude-members: add_draw_callback, add_self_to_kwargs, add_update_callback, apply, apply_draw_callbacks, apply_update_callbacks, background_inflate_to_selection_effect, change, draw, draw_after_if_selected, flip, get_alignment, get_border, get_decorator, get_focus_rect, get_font_color_status, get_font_info, get_frame, get_frame_depth, get_height, get_margin, get_padding, get_position, get_rect, get_selected_time, get_selection_effect, get_size, get_sound, get_surface, get_title, get_translate, get_value, get_width, is_selected, mouseleave, mouseover, remove_draw_callback, remove_update_callback, reset_value, resize, rotate, scale, select, set_alignment, set_background_color, set_border, set_controls, set_cursor, set_default_value, set_float, set_font, set_font_shadow, set_frame, set_margin, set_max_height, set_max_width, set_onchange, set_onmouseleave, set_onmouseover, set_onreturn, set_onselect, set_padding, set_position, set_selection_effect, set_shadow, set_sound, set_tab_size, set_title, set_value, translate, update, update_font, value_changed 12 | -------------------------------------------------------------------------------- /docs/_source/widgets_none.rst: -------------------------------------------------------------------------------- 1 | .. module:: pygame_menu.widgets.widget.none 2 | 3 | ========== 4 | NoneWidget 5 | ========== 6 | 7 | .. autoclass:: pygame_menu.widgets.NoneWidget 8 | :members: 9 | :show-inheritance: 10 | :inherited-members: 11 | :exclude-members: add_self_to_kwargs, apply, background_inflate_to_selection_effect, change, draw_after_if_selected, flip, get_border, get_focus_rect, get_font_color_status, get_font_info, get_height, get_margin, get_padding, get_rect, get_selected_time, get_selection_effect, get_size, get_sound, get_surface, get_title, get_translate, get_value, get_width, is_selected, mouseleave, mouseover, render, reset_value, resize, rotate, scale, select, set_background_color, set_border, set_controls, set_cursor, set_default_value, set_font, set_font_shadow, set_margin, set_max_height, set_max_width, set_onchange, set_onmouseleave, set_onmouseover, set_onreturn, set_onselect, set_padding, set_position, set_selection_effect, set_shadow, set_sound, set_tab_size, set_title, set_value, shadow, translate, update_font, value_changed, update 12 | -------------------------------------------------------------------------------- /docs/_source/widgets_progressbar.rst: -------------------------------------------------------------------------------- 1 | .. module:: pygame_menu.widgets.widget.progressbar 2 | 3 | =========== 4 | ProgressBar 5 | =========== 6 | 7 | .. autoclass:: pygame_menu.widgets.ProgressBar 8 | :members: 9 | :show-inheritance: 10 | :inherited-members: 11 | :exclude-members: add_self_to_kwargs, apply, change, draw_after_if_selected, flip, get_sound, resize, rotate, scale, set_max_height, set_max_width, set_onchange, set_onreturn, set_sound 12 | -------------------------------------------------------------------------------- /docs/_source/widgets_rangeslider.rst: -------------------------------------------------------------------------------- 1 | .. module:: pygame_menu.widgets.widget.rangeslider 2 | 3 | =========== 4 | RangeSlider 5 | =========== 6 | 7 | .. autoclass:: pygame_menu.widgets.RangeSlider 8 | :members: 9 | :show-inheritance: 10 | :inherited-members: 11 | :exclude-members: flip, resize, rotate, scale, set_max_height, set_max_width 12 | -------------------------------------------------------------------------------- /docs/_source/widgets_scrollbar.rst: -------------------------------------------------------------------------------- 1 | .. module:: pygame_menu.widgets.widget.scrollbar 2 | 3 | ========= 4 | ScrollBar 5 | ========= 6 | 7 | .. autoclass:: pygame_menu.widgets.ScrollBar 8 | :members: 9 | :show-inheritance: 10 | :inherited-members: 11 | :exclude-members: apply, background_inflate_to_selection_effect, draw_after_if_selected, flip, get_font_color_status, get_selected_time, get_selection_effect, resize, rotate, scale, select, set_font, set_font_shadow, set_max_height, set_max_width, set_onreturn, set_onselect, set_padding, set_selection_effect, set_title, update_font 12 | -------------------------------------------------------------------------------- /docs/_source/widgets_selector.rst: -------------------------------------------------------------------------------- 1 | .. module:: pygame_menu.widgets.widget.selector 2 | 3 | ======== 4 | Selector 5 | ======== 6 | 7 | .. autoclass:: pygame_menu.widgets.Selector 8 | :members: 9 | :show-inheritance: 10 | :inherited-members: 11 | :exclude-members: draw_after_if_selected 12 | -------------------------------------------------------------------------------- /docs/_source/widgets_surface.rst: -------------------------------------------------------------------------------- 1 | .. module:: pygame_menu.widgets.widget.surface 2 | 3 | ============= 4 | SurfaceWidget 5 | ============= 6 | 7 | .. autoclass:: pygame_menu.widgets.SurfaceWidget 8 | :members: 9 | :show-inheritance: 10 | :inherited-members: 11 | :exclude-members: apply, change, draw_after_if_selected, flip, get_font_color_status, get_font_info, get_sound, get_title, get_value, reset_value, resize, rotate, scale, set_controls, set_default_value, set_font, set_font_shadow, set_max_height, set_max_width, set_onchange, set_onreturn, set_padding, set_sound, set_tab_size, set_title, set_value, update_font, value_changed 12 | -------------------------------------------------------------------------------- /docs/_source/widgets_table.rst: -------------------------------------------------------------------------------- 1 | .. module:: pygame_menu.widgets.widget.table 2 | 3 | ===== 4 | Table 5 | ===== 6 | 7 | .. autoclass:: pygame_menu.widgets.Table 8 | :members: 9 | :show-inheritance: 10 | :inherited-members: 11 | :exclude-members: add_title_button, add_title_generic_button, apply, background_inflate_to_selection_effect, change, contains_widget, draw_after_if_selected, flip, get_index, get_indices, get_scroll_value_percentage, get_selected_time, get_selection_effect, get_sound, get_title, get_value, is_selected, make_scrollarea, pack, remove_title, reset_value, rotate, scale, scrollh, scrollv, select, set_default_value, set_max_height, set_max_width, set_onchange, set_onreturn, set_onselect, set_selection_effect, set_shadow, set_sound, set_tab_size, set_title, set_value, sort_menu_update_frames, unpack, update_indices, value_changed 12 | -------------------------------------------------------------------------------- /docs/_source/widgets_textinput.rst: -------------------------------------------------------------------------------- 1 | .. module:: pygame_menu.widgets.widget.textinput 2 | 3 | ========= 4 | TextInput 5 | ========= 6 | 7 | .. autoclass:: pygame_menu.widgets.TextInput 8 | :members: 9 | :show-inheritance: 10 | :inherited-members: 11 | :exclude-members: draw_after_if_selected, resize, rotate, scale, set_max_height, set_max_width 12 | -------------------------------------------------------------------------------- /docs/_source/widgets_toggleswitch.rst: -------------------------------------------------------------------------------- 1 | .. module:: pygame_menu.widgets.widget.toggleswitch 2 | 3 | ============ 4 | ToggleSwitch 5 | ============ 6 | 7 | .. autoclass:: pygame_menu.widgets.ToggleSwitch 8 | :members: 9 | :show-inheritance: 10 | :inherited-members: 11 | :exclude-members: draw_after_if_selected, flip, resize, rotate, scale, set_max_height, set_max_width 12 | -------------------------------------------------------------------------------- /docs/_source/widgets_vfill.rst: -------------------------------------------------------------------------------- 1 | .. module:: pygame_menu.widgets.widget.vfill 2 | 3 | ===== 4 | VFill 5 | ===== 6 | 7 | .. autoclass:: pygame_menu.widgets.VFill 8 | :members: 9 | :show-inheritance: 10 | :inherited-members: 11 | :exclude-members: add_self_to_kwargs, apply, background_inflate_to_selection_effect, change, draw_after_if_selected, flip, get_border, get_focus_rect, get_font_color_status, get_font_info, get_height, get_margin, get_padding, get_rect, get_selected_time, get_selection_effect, get_size, get_sound, get_surface, get_title, get_translate, get_value, get_width, is_selected, mouseleave, mouseover, render, reset_value, resize, rotate, scale, select, set_background_color, set_border, set_controls, set_cursor, set_default_value, set_font, set_font_shadow, set_margin, set_max_height, set_max_width, set_onchange, set_onmouseleave, set_onmouseover, set_onreturn, set_onselect, set_padding, set_position, set_selection_effect, set_shadow, set_sound, set_tab_size, set_title, set_value, shadow, translate, update_font, value_changed, update 12 | -------------------------------------------------------------------------------- /docs/_source/widgets_vmargin.rst: -------------------------------------------------------------------------------- 1 | .. module:: pygame_menu.widgets.widget.vmargin 2 | 3 | ======= 4 | VMargin 5 | ======= 6 | 7 | .. autoclass:: pygame_menu.widgets.VMargin 8 | :members: 9 | :show-inheritance: 10 | :inherited-members: 11 | :exclude-members: add_self_to_kwargs, apply, background_inflate_to_selection_effect, change, draw_after_if_selected, flip, get_border, get_focus_rect, get_font_color_status, get_font_info, get_height, get_margin, get_padding, get_rect, get_selected_time, get_selection_effect, get_size, get_sound, get_surface, get_title, get_translate, get_value, get_width, is_selected, mouseleave, mouseover, render, reset_value, resize, rotate, scale, select, set_background_color, set_border, set_controls, set_cursor, set_default_value, set_font, set_font_shadow, set_margin, set_max_height, set_max_width, set_onchange, set_onmouseleave, set_onmouseover, set_onreturn, set_onselect, set_padding, set_position, set_selection_effect, set_shadow, set_sound, set_tab_size, set_title, set_value, shadow, translate, update_font, value_changed, update 12 | -------------------------------------------------------------------------------- /docs/_static/example_game_selector.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/example_game_selector.gif -------------------------------------------------------------------------------- /docs/_static/example_multi_input.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/example_multi_input.gif -------------------------------------------------------------------------------- /docs/_static/example_other_calculator.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/example_other_calculator.gif -------------------------------------------------------------------------------- /docs/_static/example_other_dynamic_button_append.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/example_other_dynamic_button_append.gif -------------------------------------------------------------------------------- /docs/_static/example_other_dynamic_widget_update.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/example_other_dynamic_widget_update.gif -------------------------------------------------------------------------------- /docs/_static/example_other_image_background.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/example_other_image_background.gif -------------------------------------------------------------------------------- /docs/_static/example_other_maze.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/example_other_maze.gif -------------------------------------------------------------------------------- /docs/_static/example_other_solar_system.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/example_other_solar_system.gif -------------------------------------------------------------------------------- /docs/_static/example_other_widget_positioning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/example_other_widget_positioning.png -------------------------------------------------------------------------------- /docs/_static/example_scroll_menu.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/example_scroll_menu.gif -------------------------------------------------------------------------------- /docs/_static/example_simple.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/example_simple.gif -------------------------------------------------------------------------------- /docs/_static/example_timer_clock.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/example_timer_clock.gif -------------------------------------------------------------------------------- /docs/_static/example_window_resize.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/example_window_resize.gif -------------------------------------------------------------------------------- /docs/_static/first_steps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/first_steps.png -------------------------------------------------------------------------------- /docs/_static/font_8bit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/font_8bit.png -------------------------------------------------------------------------------- /docs/_static/font_bebas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/font_bebas.png -------------------------------------------------------------------------------- /docs/_static/font_comic_neue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/font_comic_neue.png -------------------------------------------------------------------------------- /docs/_static/font_digital.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/font_digital.png -------------------------------------------------------------------------------- /docs/_static/font_firacode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/font_firacode.png -------------------------------------------------------------------------------- /docs/_static/font_firacode_bold.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/font_firacode_bold.png -------------------------------------------------------------------------------- /docs/_static/font_firacode_bold_italic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/font_firacode_bold_italic.png -------------------------------------------------------------------------------- /docs/_static/font_firacode_italic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/font_firacode_italic.png -------------------------------------------------------------------------------- /docs/_static/font_franchise.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/font_franchise.png -------------------------------------------------------------------------------- /docs/_static/font_helvetica.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/font_helvetica.png -------------------------------------------------------------------------------- /docs/_static/font_munro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/font_munro.png -------------------------------------------------------------------------------- /docs/_static/font_nevis.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/font_nevis.png -------------------------------------------------------------------------------- /docs/_static/font_open_sans.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/font_open_sans.png -------------------------------------------------------------------------------- /docs/_static/font_open_sans_bold.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/font_open_sans_bold.png -------------------------------------------------------------------------------- /docs/_static/font_open_sans_italic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/font_open_sans_italic.png -------------------------------------------------------------------------------- /docs/_static/font_open_sans_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/font_open_sans_light.png -------------------------------------------------------------------------------- /docs/_static/font_pt_serif.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/font_pt_serif.png -------------------------------------------------------------------------------- /docs/_static/menubar_adaptive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/menubar_adaptive.png -------------------------------------------------------------------------------- /docs/_static/menubar_none.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/menubar_none.png -------------------------------------------------------------------------------- /docs/_static/menubar_simple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/menubar_simple.png -------------------------------------------------------------------------------- /docs/_static/menubar_title_only.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/menubar_title_only.png -------------------------------------------------------------------------------- /docs/_static/menubar_title_only_diagonal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/menubar_title_only_diagonal.png -------------------------------------------------------------------------------- /docs/_static/menubar_underline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/menubar_underline.png -------------------------------------------------------------------------------- /docs/_static/menubar_underline_title.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/menubar_underline_title.png -------------------------------------------------------------------------------- /docs/_static/pygame_menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/pygame_menu.png -------------------------------------------------------------------------------- /docs/_static/pygame_menu_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/pygame_menu_small.png -------------------------------------------------------------------------------- /docs/_static/theme_blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/theme_blue.png -------------------------------------------------------------------------------- /docs/_static/theme_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/theme_dark.png -------------------------------------------------------------------------------- /docs/_static/theme_default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/theme_default.png -------------------------------------------------------------------------------- /docs/_static/theme_green.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/theme_green.png -------------------------------------------------------------------------------- /docs/_static/theme_orange.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/theme_orange.png -------------------------------------------------------------------------------- /docs/_static/theme_solarized.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/theme_solarized.png -------------------------------------------------------------------------------- /docs/_static/widget_banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/widget_banner.png -------------------------------------------------------------------------------- /docs/_static/widget_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/widget_button.png -------------------------------------------------------------------------------- /docs/_static/widget_clock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/widget_clock.png -------------------------------------------------------------------------------- /docs/_static/widget_colorinput.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/widget_colorinput.png -------------------------------------------------------------------------------- /docs/_static/widget_dropselect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/widget_dropselect.png -------------------------------------------------------------------------------- /docs/_static/widget_dropselect_multiple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/widget_dropselect_multiple.png -------------------------------------------------------------------------------- /docs/_static/widget_frame.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/widget_frame.png -------------------------------------------------------------------------------- /docs/_static/widget_frame_title.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/widget_frame_title.png -------------------------------------------------------------------------------- /docs/_static/widget_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/widget_image.png -------------------------------------------------------------------------------- /docs/_static/widget_label.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/widget_label.png -------------------------------------------------------------------------------- /docs/_static/widget_menulink.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/widget_menulink.png -------------------------------------------------------------------------------- /docs/_static/widget_progressbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/widget_progressbar.png -------------------------------------------------------------------------------- /docs/_static/widget_rangeslider.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/widget_rangeslider.png -------------------------------------------------------------------------------- /docs/_static/widget_selector.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/widget_selector.png -------------------------------------------------------------------------------- /docs/_static/widget_surface.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/widget_surface.png -------------------------------------------------------------------------------- /docs/_static/widget_table.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/widget_table.png -------------------------------------------------------------------------------- /docs/_static/widget_table_advanced.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/widget_table_advanced.png -------------------------------------------------------------------------------- /docs/_static/widget_textinput.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/widget_textinput.png -------------------------------------------------------------------------------- /docs/_static/widget_toggleswitch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/widget_toggleswitch.png -------------------------------------------------------------------------------- /docs/_static/widget_url.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/widget_url.png -------------------------------------------------------------------------------- /docs/_static/widget_vfill.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/widget_vfill.png -------------------------------------------------------------------------------- /docs/_static/widget_vmargin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/docs/_static/widget_vmargin.png -------------------------------------------------------------------------------- /docs/build.bat: -------------------------------------------------------------------------------- 1 | del build\*.* /s /q 2 | make html -------------------------------------------------------------------------------- /docs/conf.py: -------------------------------------------------------------------------------- 1 | """ 2 | pygame-menu 3 | https://github.com/ppizarror/pygame-menu 4 | 5 | CONF 6 | Configuration file for the Sphinx documentation builder. 7 | 8 | This file only contains a selection of the most common options. For a full 9 | list see the documentation: 10 | https://www.sphinx-doc.org/en/master/usage/configuration.html 11 | """ 12 | 13 | # -- Path setup --------------------------------------------------------------- 14 | 15 | # If extensions (or modules to document with autodoc) are in another directory, 16 | # add these directories to sys.path here. If the directory is relative to the 17 | # documentation root, use os.path.abspath to make it absolute, like shown here 18 | # 19 | import os 20 | import sys 21 | 22 | sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) 23 | 24 | import pygame_menu 25 | 26 | # -- Project information ------------------------------------------------------ 27 | 28 | project = pygame_menu.__module_name__ 29 | # noinspection PyShadowingBuiltins 30 | copyright = pygame_menu.__copyright__ 31 | author = pygame_menu.__author__ 32 | 33 | # The full version, including alpha/beta/rc tags 34 | release = pygame_menu.__version__ 35 | 36 | # -- General configuration ---------------------------------------------------- 37 | 38 | # Add any Sphinx extension module names here, as strings. They can be 39 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 40 | # ones 41 | extensions = ['sphinx.ext.autodoc', 42 | 'sphinx.ext.viewcode', 43 | 'sphinx.ext.intersphinx', 44 | 'sphinx.ext.autosectionlabel', 45 | 'sphinx_autodoc_typehints' 46 | ] 47 | 48 | # autodoc_default_options = { 49 | # 'private-members': False 50 | # } 51 | 52 | # Add any paths that contain templates here, relative to this directory 53 | templates_path = ['_templates'] 54 | 55 | # The document name of the "master" document, that is, the document that 56 | # contains the root toc-tree directive. Default is 'index' 57 | master_doc = 'index' 58 | 59 | # List of patterns, relative to source directory, that match files and 60 | # directories to ignore when looking for source files 61 | # This pattern also affects html_static_path and html_extra_path 62 | exclude_patterns = ['build', 'Thumbs.db', '.DS_Store'] 63 | 64 | # -- Intersphinx configuration ------------------------------------------------ 65 | 66 | intersphinx_mapping = { 67 | 'python': ('https://docs.python.org/3.9', None), 68 | 'pygame': ('https://www.pygame.org/docs', None), 69 | } 70 | 71 | # -- Options for HTML output -------------------------------------------------- 72 | 73 | # The theme to use for HTML and HTML Help pages. See the documentation for 74 | # a list of builtin themes 75 | html_theme = 'sphinx_rtd_theme' 76 | 77 | # Add any paths that contain custom static files (such as style sheets) here, 78 | # relative to this directory. They are copied after the builtin static files, 79 | # so a file named "default.css" will overwrite the builtin "default.css" 80 | html_static_path = ['_static'] 81 | 82 | html_title = f'{project} {release} Documentation' 83 | 84 | html_logo = '_static/pygame_menu_small.png' 85 | 86 | html_theme_options = { 87 | 'prev_next_buttons_location': None 88 | } 89 | 90 | # -- Options for LaTeX output ------------------------------------------------- 91 | 92 | # noinspection SpellCheckingInspection 93 | latex_elements = { 94 | 'papersize': 'a4paper', 95 | 'pointsize': '10pt', 96 | 'preamble': r'\def\thempfootnote{\arabic{mpfootnote}}' # workaround sphinx issue #2530 97 | } 98 | 99 | latex_documents = [ 100 | ( 101 | 'index', # source start file 102 | f'{project}.tex', # target filename 103 | f'{project} Documentation', # title 104 | author, # author 105 | 'manual', # documentclass 106 | True, # documents ref'd from toc-tree only 107 | ), 108 | ] 109 | 110 | latex_show_pagerefs = True 111 | 112 | # -- Options for autodoc - typehints --- 113 | 114 | set_type_checking_flag = True 115 | -------------------------------------------------------------------------------- /docs/generate_resources.py: -------------------------------------------------------------------------------- 1 | """ 2 | pygame-menu 3 | https://github.com/ppizarror/pygame-menu 4 | 5 | GENERATE RESOURCES 6 | Generate resources for docs. 7 | """ 8 | 9 | __all__ = ['save_font_image', 'generate_fonts_doc'] 10 | 11 | import pygame 12 | import pygame_menu 13 | 14 | pygame.init() 15 | 16 | 17 | def save_font_image( 18 | font_name: str, 19 | text: str, 20 | filename: str, 21 | font_size: int = 50, 22 | image_height: int = 26 23 | ) -> None: 24 | """ 25 | Generate a font image and save as a png. 26 | 27 | :param font_name: Font name 28 | :param text: Text to render 29 | :param filename: File to save the font 30 | :param font_size: Font size 31 | :param image_height: Image size in px 32 | """ 33 | assert isinstance(font_size, int) 34 | assert isinstance(image_height, int) 35 | assert font_size > 0 and image_height > 0 36 | font = pygame_menu.font.get_font(font_name, font_size) 37 | surf = font.render(text, True, (0, 0, 0)) 38 | h, w = surf.get_height(), surf.get_width() 39 | new_width = int(w * (float(image_height) / h)) 40 | surf2 = pygame.transform.smoothscale(surf, (new_width, image_height)) 41 | pygame.image.save(surf2, filename) 42 | 43 | 44 | def generate_fonts_doc() -> None: 45 | """ 46 | Generate images for all fonts. 47 | """ 48 | text = 'pygame menu' 49 | save_font_image(pygame_menu.font.FONT_8BIT, text, '_static/font_8bit.png') 50 | save_font_image(pygame_menu.font.FONT_BEBAS, text, '_static/font_bebas.png') 51 | save_font_image(pygame_menu.font.FONT_COMIC_NEUE, text, '_static/font_comic_neue.png') 52 | save_font_image(pygame_menu.font.FONT_DIGITAL, text, '_static/font_digital.png') 53 | save_font_image(pygame_menu.font.FONT_FIRACODE, text, '_static/font_firacode.png') 54 | save_font_image(pygame_menu.font.FONT_FIRACODE_BOLD, text, '_static/font_firacode_bold.png') 55 | save_font_image(pygame_menu.font.FONT_FIRACODE_BOLD_ITALIC, text, '_static/font_firacode_bold_italic.png') 56 | save_font_image(pygame_menu.font.FONT_FIRACODE_ITALIC, text, '_static/font_firacode_italic.png') 57 | save_font_image(pygame_menu.font.FONT_FRANCHISE, text, '_static/font_franchise.png') 58 | save_font_image(pygame_menu.font.FONT_HELVETICA, text, '_static/font_helvetica.png') 59 | save_font_image(pygame_menu.font.FONT_MUNRO, text, '_static/font_munro.png') 60 | save_font_image(pygame_menu.font.FONT_NEVIS, text, '_static/font_nevis.png') 61 | save_font_image(pygame_menu.font.FONT_OPEN_SANS, text, '_static/font_open_sans.png') 62 | save_font_image(pygame_menu.font.FONT_OPEN_SANS_BOLD, text, '_static/font_open_sans_bold.png') 63 | save_font_image(pygame_menu.font.FONT_OPEN_SANS_ITALIC, text, '_static/font_open_sans_italic.png') 64 | save_font_image(pygame_menu.font.FONT_OPEN_SANS_LIGHT, text, '_static/font_open_sans_light.png') 65 | save_font_image(pygame_menu.font.FONT_PT_SERIF, text, '_static/font_pt_serif.png') 66 | 67 | 68 | if __name__ == '__main__': 69 | generate_fonts_doc() 70 | -------------------------------------------------------------------------------- /docs/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | set SOURCEDIR=. 11 | set BUILDDIR=build 12 | 13 | if "%1" == "" goto help 14 | 15 | %SPHINXBUILD% >NUL 2>NUL 16 | if errorlevel 9009 ( 17 | echo. 18 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 19 | echo.installed, then set the SPHINXBUILD environment variable to point 20 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 21 | echo.may add the Sphinx directory to PATH. 22 | echo. 23 | echo.If you don't have Sphinx installed, grab it from 24 | echo.http://sphinx-doc.org/ 25 | exit /b 1 26 | ) 27 | 28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 29 | goto end 30 | 31 | :help 32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 33 | 34 | :end 35 | popd 36 | -------------------------------------------------------------------------------- /pygame_menu/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | pygame-menu 3 | https://github.com/ppizarror/pygame-menu 4 | 5 | PYGAME-MENU 6 | A menu for pygame. Simple, and easy to use. 7 | """ 8 | 9 | __all__ = [ 10 | 11 | # Common classes 12 | 'BaseImage', 13 | 'Menu', 14 | 'Sound', 15 | 'Theme' 16 | 17 | ] 18 | 19 | # Check if pygame exists, if not maybe the module is being used by setup.py 20 | __pygame_version__ = None 21 | try: 22 | from pygame import version as __pygame_version__ 23 | 24 | __pygame_version__ = __pygame_version__.vernum 25 | except (ModuleNotFoundError, ImportError): 26 | pass 27 | 28 | # Import modules that require pygame 29 | if __pygame_version__ is not None: 30 | """ 31 | BaseImage: Provides basic image loading and manipulation with pygame 32 | """ 33 | import pygame_menu.baseimage 34 | from pygame_menu.baseimage import BaseImage 35 | 36 | """ 37 | Controls: Default controls of menu object and key definition 38 | """ 39 | import pygame_menu.controls 40 | 41 | """ 42 | Events: Menu events definition and locals 43 | """ 44 | import pygame_menu.events 45 | 46 | """ 47 | Fonts: Menu fonts 48 | """ 49 | import pygame_menu.font 50 | 51 | """ 52 | Locals: Local constants 53 | """ 54 | import pygame_menu.locals 55 | 56 | """ 57 | Menu: Menu class 58 | """ 59 | from pygame_menu.menu import Menu 60 | 61 | """ 62 | ScrollArea: Scrollarea class 63 | """ 64 | import pygame_menu._scrollarea 65 | 66 | """ 67 | Sound: Sound class 68 | """ 69 | import pygame_menu.sound 70 | from pygame_menu.sound import Sound 71 | 72 | """ 73 | Themes: Menu themes 74 | """ 75 | import pygame_menu.themes 76 | from pygame_menu.themes import Theme 77 | 78 | """ 79 | Widgets: Menu widgets 80 | """ 81 | import pygame_menu.widgets 82 | 83 | """ 84 | Version: Library version 85 | """ 86 | import pygame_menu.version 87 | 88 | """ 89 | Metadata: Information about the project 90 | """ 91 | __author__ = 'Pablo Pizarro R.' 92 | __contributors__ = [ 93 | 94 | # Author 95 | 'ppizarror', 96 | 97 | # Contributors 98 | 'anxuae', 99 | 'apuly', 100 | 'arpruss', 101 | 'asierrayk', 102 | 'DA820', 103 | 'eforgacs', 104 | 'i96751414', 105 | 'ironsmile', 106 | 'jwllee', 107 | 'maditnerd', 108 | 'MayuSakurai', 109 | 'mrkprdo', 110 | 'neilsimp1', 111 | 'notrurs', 112 | 'NullP01nt', 113 | 'PandaRoux8', 114 | 'Rifqi31', 115 | 'ThePeeps191', 116 | 'thisIsMikeKane', 117 | 'vnmabus', 118 | 'werdeil', 119 | 'zPaw' 120 | 121 | ] 122 | __copyright__ = 'Copyright 2017 Pablo Pizarro R. @ppizarror' 123 | __description__ = 'A menu for pygame. Simple, and easy to use' 124 | __email__ = 'pablo@ppizarror.com' 125 | __keywords__ = 'pygame menu menus gui widget input button pygame-menu image sound ui' 126 | __license__ = 'MIT' 127 | __module_name__ = 'pygame-menu' 128 | __url__ = 'https://pygame-menu.readthedocs.io' 129 | __url_bug_tracker__ = 'https://github.com/ppizarror/pygame-menu/issues' 130 | __url_documentation__ = 'https://pygame-menu.readthedocs.io' 131 | __url_source_code__ = 'https://github.com/ppizarror/pygame-menu' 132 | __version__ = pygame_menu.version.ver 133 | 134 | """ 135 | Print pygame-menu version. 136 | """ 137 | import os 138 | 139 | if 'PYGAME_MENU_HIDE_VERSION' not in os.environ and 'PYGAME_HIDE_SUPPORT_PROMPT' not in os.environ: 140 | print(f'{__module_name__} {__version__}') 141 | 142 | # Cleanup namespace 143 | del os 144 | -------------------------------------------------------------------------------- /pygame_menu/__pyinstaller/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | pygame-menu 3 | https://github.com/ppizarror/pygame-menu 4 | 5 | PYINSTALLER 6 | Module for pyinstaller. 7 | """ 8 | 9 | __all__ = ['get_hook_dirs'] 10 | 11 | import os 12 | from typing import List 13 | 14 | 15 | def get_hook_dirs() -> List[str]: 16 | """ 17 | Return hook dirs to PyInstaller. 18 | 19 | :return: Hook dir list 20 | """ 21 | return [os.path.dirname(__file__)] 22 | -------------------------------------------------------------------------------- /pygame_menu/__pyinstaller/hook-pygame_menu.py: -------------------------------------------------------------------------------- 1 | """ 2 | pygame-menu 3 | https://github.com/ppizarror/pygame-menu 4 | 5 | PYGAME-MENU HOOK 6 | Used by Pyinstaller. 7 | """ 8 | 9 | import os 10 | 11 | # noinspection PyProtectedMember 12 | from pygame_menu import __file__ as pygame_menu_main_file 13 | 14 | # Get pygame_menu's folder 15 | pygame_menu_folder = os.path.dirname(os.path.abspath(pygame_menu_main_file)) 16 | 17 | # datas is the variable that pyinstaller looks for while processing hooks 18 | datas = [] 19 | 20 | 21 | # A helper to append the relative path of a resource to hook variable - datas 22 | def _append_to_datas(file_path: str, target_folder: str, base_target_folder: str = 'pygame_menu', 23 | relative: bool = True) -> None: 24 | """ 25 | Add path to datas. 26 | 27 | :param file_path: File path 28 | :param target_folder: Folder to paste the resources. If empty uses the containing folder of the file as ``base_target_folder+target_folder`` 29 | :param base_target_folder: Base folder of the resource 30 | :param relative: If ``True`` append ``pygame_menu_folder`` 31 | """ 32 | global datas 33 | if relative: 34 | res_path = os.path.join(pygame_menu_folder, file_path) 35 | else: 36 | res_path = file_path 37 | if target_folder == '': 38 | target_folder = os.path.basename(os.path.dirname(res_path)) 39 | if os.path.exists(res_path): 40 | datas.append((res_path, os.path.join(base_target_folder, target_folder))) 41 | 42 | 43 | # Append data 44 | from pygame_menu.font import FONT_EXAMPLES 45 | from pygame_menu.baseimage import IMAGE_EXAMPLES 46 | from pygame_menu.sound import SOUND_EXAMPLES 47 | 48 | pygame_menu_resources = os.path.join('pygame_menu', 'resources') 49 | for f in FONT_EXAMPLES: 50 | _append_to_datas(f, target_folder='', base_target_folder=pygame_menu_resources) 51 | for f in IMAGE_EXAMPLES: 52 | _append_to_datas(f, target_folder='', base_target_folder=pygame_menu_resources) 53 | for f in SOUND_EXAMPLES: 54 | _append_to_datas(f, target_folder='', base_target_folder=pygame_menu_resources) 55 | -------------------------------------------------------------------------------- /pygame_menu/_base.py: -------------------------------------------------------------------------------- 1 | """ 2 | pygame-menu 3 | https://github.com/ppizarror/pygame-menu 4 | 5 | BASE 6 | Base object. Provides common methods used by all library objects. 7 | """ 8 | 9 | __all__ = ['Base'] 10 | 11 | from pygame_menu.utils import uuid4 12 | 13 | from pygame_menu._types import Dict, Any, NumberInstance, NumberType, Optional 14 | 15 | 16 | class Base(object): 17 | """ 18 | Base object. 19 | """ 20 | _attributes: Optional[Dict[str, Any]] 21 | _class_id__repr__: bool 22 | _id: str 23 | _id__repr__: bool 24 | _verbose: bool 25 | 26 | def __init__(self, object_id: str, verbose: bool = True) -> None: 27 | """ 28 | Base constructor. 29 | 30 | :param object_id: Object ID 31 | :param verbose: Enable verbose mode (errors/warnings) 32 | """ 33 | assert isinstance(object_id, str) 34 | assert isinstance(verbose, bool) 35 | if len(object_id) == 0: 36 | object_id = uuid4() 37 | self._attributes = None 38 | self._class_id__repr__ = False # If True, repr/str of the object is class id 39 | self._id = object_id 40 | self._id__repr__ = False # If True, repr/str of the object adds object id 41 | self._verbose = verbose 42 | 43 | def __repr__(self) -> str: 44 | """ 45 | Repr print of object. 46 | 47 | :return: Object str status 48 | """ 49 | sup_repr = super(Base, self).__repr__() 50 | assert not (self._class_id__repr__ and self._id__repr__), \ 51 | 'class id and id __repr__ cannot be True at the same time' 52 | if self._class_id__repr__: 53 | return self.get_class_id() 54 | elif self._id__repr__: 55 | return sup_repr.replace(' object at ', f'["{self.get_id()}"] object at ') 56 | return sup_repr 57 | 58 | def _update__repr___(self, obj: 'Base') -> None: 59 | """ 60 | Update __repr__ from other Base object. 61 | 62 | :param obj: External base object to copy from 63 | """ 64 | self._class_id__repr__ = obj._class_id__repr__ 65 | self._id__repr__ = obj._id__repr__ 66 | 67 | def set_attribute(self, key: str, value: Any = None) -> 'Base': 68 | """ 69 | Set an attribute. 70 | 71 | :param key: Key of the attribute 72 | :param value: Value of the attribute 73 | :return: Self reference 74 | """ 75 | assert isinstance(key, str) 76 | if self._attributes is None: 77 | self._attributes = {} 78 | self._attributes[key] = value 79 | return self 80 | 81 | def get_counter_attribute(self, key: str, incr: Any = 0, default: Any = 0) -> NumberType: 82 | """ 83 | Get counter attribute. 84 | 85 | :param key: Key of the attribute 86 | :param incr: Increase value 87 | :param default: Default vale to start with, by default it's zero 88 | :return: New increase value 89 | """ 90 | if not isinstance(incr, NumberInstance): 91 | incr = float(incr) 92 | if not isinstance(default, NumberInstance): 93 | if isinstance(incr, float): 94 | default = float(default) 95 | else: 96 | try: 97 | default = int(default) 98 | except ValueError: 99 | default = float(default) 100 | if not self.has_attribute(key): 101 | self.set_attribute(key, default + incr) 102 | return default + incr 103 | new = self.get_attribute(key) + incr 104 | self.set_attribute(key, new) 105 | return new 106 | 107 | def get_attribute(self, key: str, default: Any = None) -> Any: 108 | """ 109 | Get an attribute value. 110 | 111 | :param key: Key of the attribute 112 | :param default: Value if it does not exist 113 | :return: Attribute data 114 | """ 115 | assert isinstance(key, str) 116 | if not self.has_attribute(key): 117 | return default 118 | return self._attributes[key] 119 | 120 | def has_attribute(self, key: str) -> bool: 121 | """ 122 | Return ``True`` if the object has the given attribute. 123 | 124 | :param key: Key of the attribute 125 | :return: ``True`` if exists 126 | """ 127 | assert isinstance(key, str) 128 | if self._attributes is None: 129 | return False 130 | return key in self._attributes.keys() 131 | 132 | def remove_attribute(self, key: str) -> 'Base': 133 | """ 134 | Removes the given attribute from the object. Throws ``IndexError`` if 135 | the given key does not exist. 136 | 137 | :param key: Key of the attribute 138 | :return: Self reference 139 | """ 140 | if not self.has_attribute(key): 141 | raise IndexError(f'attribute "{key}" does not exists on object') 142 | del self._attributes[key] 143 | return self 144 | 145 | def get_class_id(self) -> str: 146 | """ 147 | Return the Class+ID as a string. 148 | 149 | :return: Class+ID format 150 | """ 151 | return f'{self.__class__.__name__}<"{self._id}">' 152 | 153 | def get_id(self) -> str: 154 | """ 155 | Return the object ID. 156 | 157 | :return: Object ID 158 | """ 159 | return self._id 160 | -------------------------------------------------------------------------------- /pygame_menu/_types.py: -------------------------------------------------------------------------------- 1 | """ 2 | pygame-menu 3 | https://github.com/ppizarror/pygame-menu 4 | 5 | TYPES 6 | Defines common pygame-menu types. 7 | """ 8 | 9 | from pygame.color import Color as __Color 10 | from pygame.event import Event as EventType 11 | 12 | from typing import Union, List, Tuple, Any, Callable, Sequence, Mapping, Optional 13 | 14 | # noinspection PyUnresolvedReferences 15 | from typing import Dict, Type 16 | 17 | # noinspection PyUnresolvedReferences 18 | from typing_extensions import Literal 19 | 20 | # Common types 21 | ArgsType = Optional[Sequence[Any]] 22 | CallableNoArgsType = Callable[[], Any] 23 | CallbackType = Optional[Callable] 24 | EventListType = List[EventType] 25 | EventVectorType = Union[EventListType, Tuple[EventType]] 26 | KwargsType = Optional[Mapping[Any, Any]] 27 | NumberType = Union[int, float] 28 | 29 | # Colors 30 | ColorType = Union[Tuple[int, int, int], Tuple[int, int, int, int]] 31 | ColorInputType = Union[ColorType, str, int, __Color] 32 | 33 | # Color input gradient; from, to, vertical, forward 34 | ColorInputGradientType = Tuple[ColorInputType, ColorInputType, bool, bool] 35 | 36 | # Vectors 37 | Vector2BoolType = Union[Tuple[bool, bool], List[bool]] 38 | Vector2IntType = Union[Tuple[int, int], List[int]] 39 | Vector2FloatType = Union[Tuple[float, float], List[float]] 40 | Vector2NumberType = Union[Tuple[NumberType, NumberType], List[NumberType]] 41 | 42 | # Generic length 43 | VectorTupleType = Tuple[NumberType, ...] 44 | VectorListType = List[NumberType] 45 | VectorType = Union[VectorTupleType, VectorListType] 46 | VectorIntType = Union[Tuple[int, ...], List[int]] 47 | 48 | # Tuples 49 | Tuple2BoolType = Tuple[bool, bool] 50 | Tuple2IntType = Tuple[int, int] 51 | Tuple2NumberType = Tuple[NumberType, NumberType] 52 | Tuple3IntType = Tuple[int, int, int] 53 | Tuple4IntType = Tuple[int, int, int, int] 54 | Tuple4NumberType = Tuple[NumberType, NumberType, NumberType, NumberType] 55 | Tuple4Tuple2IntType = Tuple[Tuple2IntType, Tuple2IntType, Tuple2IntType, Tuple2IntType] 56 | TupleIntType = Tuple[int, ...] 57 | 58 | # Menu constructor types 59 | MenuColumnMaxWidthType = Optional[Union[int, float, VectorType]] 60 | MenuColumnMinWidthType = Union[int, float, VectorType] 61 | MenuRowsType = Optional[Union[int, VectorIntType]] 62 | 63 | # Other 64 | PaddingType = Optional[Union[NumberType, List[NumberType], Tuple[NumberType], Tuple2NumberType, Tuple4NumberType]] 65 | StringVector = Union[str, Tuple[str, ...], List[str]] 66 | 67 | # Instances 68 | ColorInputInstance = (int, str, tuple, list, __Color) 69 | NumberInstance = (int, float) 70 | PaddingInstance = (int, float, tuple, list, type(None)) 71 | VectorInstance = (tuple, list) 72 | 73 | # Cursor 74 | try: 75 | # noinspection PyUnresolvedReferences 76 | from pygame.cursors import Cursor as __Cursor 77 | 78 | CursorInputType = Optional[Union[int, __Cursor]] 79 | CursorInputInstance = (int, __Cursor, type(None)) 80 | 81 | except (AttributeError, ImportError): 82 | CursorInputType, CursorInputInstance = Optional[int], (int, type(None)) 83 | CursorType = CursorInputType 84 | -------------------------------------------------------------------------------- /pygame_menu/events.py: -------------------------------------------------------------------------------- 1 | """ 2 | pygame-menu 3 | https://github.com/ppizarror/pygame-menu 4 | 5 | EVENTS 6 | Menu events definition and locals. 7 | """ 8 | 9 | __all__ = [ 10 | 11 | # Class 12 | 'MenuAction', 13 | 14 | # Utils 15 | 'is_event', 16 | 17 | # Menu events 18 | 'BACK', 19 | 'CLOSE', 20 | 'EXIT', 21 | 'NONE', 22 | 'RESET', 23 | 24 | # Last menu events 25 | 'MENU_LAST_DISABLE_UPDATE', 26 | 'MENU_LAST_FRAMES', 27 | 'MENU_LAST_JOY_REPEAT', 28 | 'MENU_LAST_MENU_BACK', 29 | 'MENU_LAST_MENU_CLOSE', 30 | 'MENU_LAST_MENUBAR', 31 | 'MENU_LAST_MOUSE_ENTER_MENU', 32 | 'MENU_LAST_MOUSE_ENTER_WINDOW', 33 | 'MENU_LAST_MOUSE_LEAVE_MENU', 34 | 'MENU_LAST_MOUSE_LEAVE_WINDOW', 35 | 'MENU_LAST_MOVE_DOWN', 36 | 'MENU_LAST_MOVE_LEFT', 37 | 'MENU_LAST_MOVE_RIGHT', 38 | 'MENU_LAST_MOVE_UP', 39 | 'MENU_LAST_NONE', 40 | 'MENU_LAST_QUIT', 41 | 'MENU_LAST_SCROLL_AREA', 42 | 'MENU_LAST_SELECTED_WIDGET_BUTTON_UP', 43 | 'MENU_LAST_SELECTED_WIDGET_EVENT', 44 | 'MENU_LAST_SELECTED_WIDGET_FINGER_UP', 45 | 'MENU_LAST_WIDGET_DISABLE_ACTIVE_STATE', 46 | 'MENU_LAST_WIDGET_SELECT', 47 | 'MENU_LAST_WIDGET_SELECT_MOTION', 48 | 49 | # Pygame events 50 | 'PYGAME_QUIT', 51 | 'PYGAME_WINDOWCLOSE' 52 | 53 | ] 54 | 55 | from typing import Any 56 | import pygame.locals as __locals 57 | 58 | 59 | class MenuAction(object): 60 | """ 61 | Pygame-menu events. 62 | 63 | :param action: Action identifier 64 | """ 65 | _action: int 66 | 67 | def __init__(self, action: int) -> None: 68 | assert isinstance(action, int) 69 | self._action = action 70 | 71 | def __eq__(self, other: object) -> bool: 72 | if isinstance(other, MenuAction): 73 | return self._action == other._action 74 | return False 75 | 76 | 77 | def is_event(event: Any) -> bool: 78 | """ 79 | Check if event is pygame_menu event type. 80 | 81 | :param event: Event 82 | :return: ``True`` if it's an event 83 | """ 84 | return isinstance(event, MenuAction) or str(type(event)) == "" 85 | 86 | 87 | # Events 88 | BACK = MenuAction(0) # Menu back 89 | CLOSE = MenuAction(1) # Close Menu 90 | EXIT = MenuAction(3) # Menu exit program 91 | NONE = MenuAction(4) # None action. It's the same as 'None' 92 | RESET = MenuAction(5) # Menu reset 93 | 94 | # Pygame events 95 | PYGAME_QUIT = __locals.QUIT 96 | PYGAME_WINDOWCLOSE = -1 97 | if hasattr(__locals, 'WINDOWCLOSE'): 98 | PYGAME_WINDOWCLOSE = __locals.WINDOWCLOSE 99 | elif hasattr(__locals, 'WINDOWEVENT_CLOSE'): 100 | PYGAME_WINDOWCLOSE = __locals.WINDOWEVENT_CLOSE 101 | 102 | # Menu last event types. Returned by menu.get_last_update_mode() 103 | MENU_LAST_DISABLE_UPDATE = 'DISABLE_UPDATE' 104 | MENU_LAST_FRAMES = 'FRAMES' 105 | MENU_LAST_JOY_REPEAT = 'JOY_REPEAT' 106 | MENU_LAST_MENU_BACK = 'MENU_BACK' 107 | MENU_LAST_MENU_CLOSE = 'MENU_CLOSE' 108 | MENU_LAST_MENUBAR = 'MENUBAR' 109 | MENU_LAST_MOUSE_ENTER_MENU = 'MOUSE_ENTER_MENU' 110 | MENU_LAST_MOUSE_ENTER_WINDOW = 'MOUSE_ENTER_WINDOW' 111 | MENU_LAST_MOUSE_LEAVE_MENU = 'MOUSE_LEAVE_MENU' 112 | MENU_LAST_MOUSE_LEAVE_WINDOW = 'MOUSE_LEAVE_WINDOW' 113 | MENU_LAST_MOVE_DOWN = 'MOVE_DOWN' 114 | MENU_LAST_MOVE_LEFT = 'MOVE_LEFT' 115 | MENU_LAST_MOVE_RIGHT = 'MOVE_RIGHT' 116 | MENU_LAST_MOVE_UP = 'MOVE_UP' 117 | MENU_LAST_NONE = 'NONE' 118 | MENU_LAST_QUIT = 'QUIT' 119 | MENU_LAST_SCROLL_AREA = 'SCROLL_AREA' 120 | MENU_LAST_SELECTED_WIDGET_BUTTON_UP = 'SELECTED_WIDGET_BUTTON_UP' 121 | MENU_LAST_SELECTED_WIDGET_EVENT = 'SELECTED_WIDGET_EVENT' 122 | MENU_LAST_SELECTED_WIDGET_FINGER_UP = 'SELECTED_WIDGET_FINGER_UP' 123 | MENU_LAST_WIDGET_DISABLE_ACTIVE_STATE = 'WIDGET_DISABLE_ACTIVE_STATE' 124 | MENU_LAST_WIDGET_SELECT = 'WIDGET_SELECT' 125 | MENU_LAST_WIDGET_SELECT_MOTION = 'WIDGET_SELECT_MOTION' 126 | -------------------------------------------------------------------------------- /pygame_menu/examples/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | pygame-menu 3 | https://github.com/ppizarror/pygame-menu 4 | 5 | EXAMPLES 6 | Example file directory. 7 | """ 8 | 9 | __all__ = ['create_example_window'] 10 | 11 | import pygame 12 | import sys 13 | 14 | from typing import Tuple 15 | 16 | _PYGAME_ICON = [None] 17 | 18 | 19 | # noinspection PyTypeChecker 20 | def create_example_window( 21 | title: str, 22 | window_size: Tuple[int, int], 23 | pygame_menu_icon: bool = True, 24 | init_pygame: bool = True, 25 | center_window: bool = True, 26 | **kwargs 27 | ) -> 'pygame.Surface': 28 | """ 29 | Set pygame window. 30 | 31 | :param title: Window title 32 | :param window_size: Window size 33 | :param pygame_menu_icon: Use pygame menu icon 34 | :param init_pygame: Init pygame 35 | :param center_window: Center the window 36 | :param kwargs: Optional keyword arguments received by display set_mode 37 | :return: Pygame surface from created display 38 | """ 39 | assert len(title) > 0, 'title cannot be empty' 40 | assert len(window_size) == 2, 'window size shape must be (width, height)' 41 | assert isinstance(window_size[0], int), 'width must be an integer' 42 | assert isinstance(window_size[1], int), 'height must be an integer' 43 | 44 | from pygame_menu.baseimage import IMAGE_EXAMPLE_PYGAME_MENU, BaseImage 45 | import os 46 | 47 | if init_pygame: 48 | pygame.init() 49 | if center_window: 50 | os.environ['SDL_VIDEO_CENTERED'] = '1' 51 | 52 | # Create pygame screen and objects 53 | if sys.platform == 'darwin': 54 | kwargs = {} 55 | 56 | try: 57 | surface = pygame.display.set_mode(window_size, **kwargs) 58 | except TypeError: 59 | surface = pygame.display.set_mode(window_size) 60 | pygame.display.set_caption(title) 61 | 62 | if pygame_menu_icon: 63 | # noinspection PyBroadException 64 | try: 65 | if _PYGAME_ICON[0] is not None: 66 | pygame.display.set_icon(_PYGAME_ICON[0]) 67 | else: 68 | icon = BaseImage(IMAGE_EXAMPLE_PYGAME_MENU).get_surface(new=False) 69 | pygame.display.set_icon(icon) 70 | _PYGAME_ICON[0] = icon 71 | except BaseException: 72 | pass 73 | 74 | return surface 75 | -------------------------------------------------------------------------------- /pygame_menu/examples/other/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | pygame-menu 3 | https://github.com/ppizarror/pygame-menu 4 | 5 | EXAMPLES / OTHER 6 | Example file directory. 7 | """ 8 | -------------------------------------------------------------------------------- /pygame_menu/examples/other/dynamic_button_append.py: -------------------------------------------------------------------------------- 1 | """ 2 | pygame-menu 3 | https://github.com/ppizarror/pygame-menu 4 | 5 | EXAMPLE - DYNAMIC BUTTON 6 | Menu with dynamic buttons. 7 | """ 8 | 9 | __all__ = ['main'] 10 | 11 | import pygame_menu 12 | from pygame_menu.examples import create_example_window 13 | 14 | from random import randrange 15 | 16 | surface = create_example_window('Example - Dynamic Button Append', (600, 400)) 17 | menu = pygame_menu.Menu( 18 | height=300, 19 | theme=pygame_menu.themes.THEME_BLUE, 20 | title='Welcome', 21 | width=400 22 | ) 23 | 24 | 25 | def add_dynamic_button() -> 'pygame_menu.widgets.Button': 26 | """ 27 | Append a button to the menu on demand. 28 | 29 | :return: Appended button 30 | """ 31 | print(f'Adding a button dynamically, total: {len(menu.get_widgets()) - 2}') 32 | btn = menu.add.button(randrange(0, 10)) 33 | 34 | def _update_button() -> None: 35 | count = btn.get_counter_attribute('count', 1, btn.get_title()) 36 | btn.set_title(str(count)) 37 | 38 | btn.update_callback(_update_button) 39 | return btn 40 | 41 | 42 | menu.add.text_input('Name: ', default='John Doe') 43 | menu.add.button('Play', add_dynamic_button) 44 | menu.add.button('Quit', pygame_menu.events.EXIT) 45 | 46 | 47 | def main(test: bool = False) -> None: 48 | """ 49 | Main function. 50 | 51 | :param test: Indicate function is being tested 52 | """ 53 | menu.mainloop(surface, disable_loop=test) 54 | 55 | 56 | if __name__ == '__main__': 57 | main() 58 | -------------------------------------------------------------------------------- /pygame_menu/examples/other/image_background.py: -------------------------------------------------------------------------------- 1 | """ 2 | pygame-menu 3 | https://github.com/ppizarror/pygame-menu 4 | 5 | EXAMPLE - IMAGE BACKGROUND 6 | Menu using background image + BaseImage object. 7 | """ 8 | 9 | __all__ = ['main'] 10 | 11 | import pygame 12 | import pygame_menu 13 | from pygame_menu.examples import create_example_window 14 | 15 | from typing import Optional 16 | 17 | # Constants and global variables 18 | FPS = 60 19 | WINDOW_SIZE = (640, 480) 20 | 21 | sound: Optional['pygame_menu.sound.Sound'] = None 22 | surface: Optional['pygame.Surface'] = None 23 | main_menu: Optional['pygame_menu.Menu'] = None 24 | 25 | # Load image 26 | background_image = pygame_menu.BaseImage( 27 | image_path=pygame_menu.baseimage.IMAGE_EXAMPLE_WALLPAPER 28 | ) 29 | 30 | 31 | def main_background() -> None: 32 | """ 33 | Background color of the main menu, on this function user can plot 34 | images, play sounds, etc. 35 | """ 36 | background_image.draw(surface) 37 | 38 | 39 | def main(test: bool = False) -> None: 40 | """ 41 | Main program. 42 | 43 | :param test: Indicate function is being tested 44 | """ 45 | global main_menu 46 | global sound 47 | global surface 48 | 49 | # Create window 50 | surface = create_example_window('Example - Image Background', WINDOW_SIZE) 51 | clock = pygame.time.Clock() 52 | 53 | # Create menus: Main menu 54 | main_menu_theme = pygame_menu.themes.THEME_ORANGE.copy() 55 | main_menu_theme.set_background_color_opacity(0.5) # 50% opacity 56 | 57 | main_menu = pygame_menu.Menu( 58 | height=WINDOW_SIZE[1] * 0.7, 59 | onclose=pygame_menu.events.EXIT, # User press ESC button 60 | theme=main_menu_theme, 61 | title='Epic Menu', 62 | width=WINDOW_SIZE[0] * 0.8 63 | ) 64 | 65 | theme_bg_image = main_menu_theme.copy() 66 | theme_bg_image.background_color = pygame_menu.BaseImage( 67 | image_path=pygame_menu.baseimage.IMAGE_EXAMPLE_CARBON_FIBER 68 | ) 69 | theme_bg_image.title_font_size = 25 70 | menu_with_bg_image = pygame_menu.Menu( 71 | height=WINDOW_SIZE[1] * 0.7, 72 | onclose=pygame_menu.events.EXIT, 73 | theme=theme_bg_image, 74 | title='Menu with background image', 75 | width=WINDOW_SIZE[0] * 0.8 76 | ) 77 | menu_with_bg_image.add.button('Back', pygame_menu.events.BACK) 78 | 79 | widget_colors_theme = pygame_menu.themes.THEME_ORANGE.copy() 80 | widget_colors_theme.widget_margin = (0, 10) 81 | widget_colors_theme.widget_padding = 0 82 | widget_colors_theme.widget_selection_effect.margin_xy(10, 5) 83 | widget_colors_theme.widget_font_size = 20 84 | widget_colors_theme.set_background_color_opacity(0.5) # 50% opacity 85 | 86 | widget_colors = pygame_menu.Menu( 87 | height=WINDOW_SIZE[1] * 0.7, 88 | theme=widget_colors_theme, 89 | title='Widget backgrounds', 90 | width=WINDOW_SIZE[0] * 0.8 91 | ) 92 | 93 | button_image = pygame_menu.BaseImage(pygame_menu.baseimage.IMAGE_EXAMPLE_CARBON_FIBER) 94 | 95 | widget_colors.add.button('Opaque color button', 96 | background_color=(100, 100, 100)) 97 | widget_colors.add.button('Transparent color button', 98 | background_color=(50, 50, 50, 200), font_size=40) 99 | widget_colors.add.button('Transparent background inflate to selection effect', 100 | background_color=(50, 50, 50, 200), 101 | margin=(0, 15)).background_inflate_to_selection_effect() 102 | widget_colors.add.button('Background inflate + font background color', 103 | background_color=(50, 50, 50, 200), 104 | font_background_color=(200, 200, 200) 105 | ).background_inflate_to_selection_effect() 106 | widget_colors.add.button('This inflates background to match selection effect', 107 | background_color=button_image, 108 | font_color=(255, 255, 255), font_size=15 109 | ).selection_expand_background = True 110 | widget_colors.add.button('This is already inflated to match selection effect', 111 | background_color=button_image, 112 | font_color=(255, 255, 255), font_size=15 113 | ).background_inflate_to_selection_effect() 114 | 115 | main_menu.add.button('Menu with background image', menu_with_bg_image) 116 | main_menu.add.button('Test different widget colors', widget_colors) 117 | main_menu.add.button('Another fancy button', lambda: print('This button has been pressed')) 118 | main_menu.add.button('Quit', pygame_menu.events.EXIT) 119 | 120 | # Main loop 121 | while True: 122 | 123 | # Tick 124 | clock.tick(FPS) 125 | 126 | # Main menu 127 | main_menu.mainloop(surface, main_background, disable_loop=test, fps_limit=FPS) 128 | 129 | # Flip surface 130 | pygame.display.flip() 131 | 132 | # At first loop returns 133 | if test: 134 | break 135 | 136 | 137 | if __name__ == '__main__': 138 | main() 139 | -------------------------------------------------------------------------------- /pygame_menu/examples/other/scrollbar.py: -------------------------------------------------------------------------------- 1 | """ 2 | pygame-menu 3 | https://github.com/ppizarror/pygame-menu 4 | 5 | EXAMPLE - USE SCROLLBAR WIDGET 6 | Shows how the ScrollBar can be used on a surface. 7 | """ 8 | 9 | __all__ = ['main'] 10 | 11 | import pygame 12 | import pygame_menu 13 | 14 | from pygame_menu.examples import create_example_window 15 | from pygame_menu.utils import make_surface 16 | from pygame_menu.widgets import ScrollBar 17 | 18 | 19 | def make_world(width: int, height: int) -> 'pygame.Surface': 20 | """ 21 | Create a test surface. 22 | 23 | :param width: Width in pixels 24 | :param height: Height in pixels 25 | :return: World surface 26 | """ 27 | world = make_surface(width, height) 28 | world.fill((200, 200, 200)) 29 | 30 | color = [70, 20, 20] 31 | max_x = len(list(range(100, width, 200))) 32 | max_y = len(list(range(100, height, 200))) 33 | number_x = 0 34 | for x in range(100, width, 200): 35 | number_y = 0 36 | for y in range(100, height, 200): 37 | if number_x in (0, max_x - 1) or number_y in (0, max_y - 1): 38 | # White circles to delimit world boundaries 39 | pygame.draw.circle(world, (255, 255, 255), (x, y), 100, 10) 40 | else: 41 | pygame.draw.circle(world, color, (x, y), 100, 10) 42 | if color[0] + 15 < 255: 43 | color[0] += 15 44 | elif color[1] + 15 < 255: 45 | color[1] += 15 46 | else: 47 | color[2] += 15 48 | number_y += 1 49 | number_x += 1 50 | 51 | return world 52 | 53 | 54 | def h_changed(value: int) -> None: 55 | """ 56 | :param value: Value data 57 | """ 58 | print('Horizontal position changed:', value) 59 | 60 | 61 | def v_changed(value: int) -> None: 62 | """ 63 | :param value: Value data 64 | """ 65 | print('Vertical position changed:', value) 66 | 67 | 68 | def main(test: bool = False) -> None: 69 | """ 70 | Main function. 71 | 72 | :param test: Indicate function is being tested 73 | """ 74 | scr_size = (480, 480) 75 | screen = create_example_window('Example - Scrollbar', scr_size) 76 | world = make_world(int(scr_size[0] * 4), scr_size[1] * 3) 77 | screen.fill((120, 90, 130)) 78 | 79 | thick_h = 20 80 | thick_v = 40 81 | 82 | # Horizontal ScrollBar 83 | sb_h = ScrollBar( 84 | length=scr_size[0] - thick_v, 85 | values_range=(50, world.get_width() - scr_size[0] + thick_v), 86 | slider_pad=2, 87 | page_ctrl_thick=thick_h, 88 | onchange=h_changed 89 | ) 90 | sb_h.set_shadow( 91 | color=(0, 0, 0), 92 | position=pygame_menu.locals.POSITION_SOUTHEAST 93 | ) 94 | sb_h.set_controls(False) 95 | sb_h.set_position(0, scr_size[1] - thick_h) 96 | sb_h.set_page_step(scr_size[0] - thick_v) 97 | 98 | # Vertical ScrollBar 99 | sb_v = ScrollBar( 100 | length=scr_size[1] - thick_h, 101 | values_range=(0, world.get_height() - scr_size[1] + thick_h), 102 | orientation=pygame_menu.locals.ORIENTATION_VERTICAL, 103 | slider_pad=6, 104 | slider_color=(135, 193, 180), 105 | slider_hover_color=(180, 180, 180), 106 | page_ctrl_thick=thick_v, 107 | page_ctrl_color=(253, 246, 220), 108 | onchange=v_changed 109 | ) 110 | sb_v.set_shadow( 111 | color=(52, 54, 56), 112 | position=pygame_menu.locals.POSITION_NORTHWEST, 113 | offset=4 114 | ) 115 | sb_v.set_controls(False) 116 | sb_v.set_position(scr_size[0] - thick_v, 0) 117 | sb_v.set_page_step(scr_size[1] - thick_h) 118 | clock = pygame.time.Clock() 119 | 120 | # ------------------------------------------------------------------------- 121 | # Main loop 122 | # ------------------------------------------------------------------------- 123 | while True: 124 | 125 | # Clock tick 126 | clock.tick(60) 127 | 128 | # Application events 129 | events = pygame.event.get() 130 | for event in events: 131 | if event.type == pygame.QUIT: 132 | exit() 133 | 134 | if event.type == pygame.KEYDOWN and event.key == pygame.K_h: 135 | sb_h.set_value(100) 136 | 137 | if event.type == pygame.KEYDOWN and event.key == pygame.K_v: 138 | sb_v.set_value(200) 139 | 140 | sb_h.update([event]) 141 | sb_h.draw(screen) 142 | sb_v.update([event]) 143 | sb_v.draw(screen) 144 | 145 | trunc_world_orig = (sb_h.get_value(), sb_v.get_value()) 146 | trunc_world = (scr_size[0] - thick_v, scr_size[1] - thick_h) 147 | 148 | # noinspection PyTypeChecker 149 | screen.blit(world, (0, 0), (trunc_world_orig, trunc_world)) 150 | pygame.display.update() 151 | 152 | # At first loop returns 153 | if test: 154 | break 155 | 156 | 157 | if __name__ == '__main__': 158 | main() 159 | -------------------------------------------------------------------------------- /pygame_menu/examples/other/scrollbar_area.py: -------------------------------------------------------------------------------- 1 | """ 2 | pygame-menu 3 | https://github.com/ppizarror/pygame-menu 4 | 5 | EXAMPLE - SCROLL AREA 6 | Shows ScrollArea widget usage. 7 | """ 8 | 9 | __all__ = ['main'] 10 | 11 | import pygame 12 | from pygame_menu import locals 13 | from pygame_menu.examples import create_example_window 14 | from pygame_menu._scrollarea import ScrollArea 15 | from pygame_menu.utils import make_surface 16 | 17 | import itertools 18 | from typing import Generator 19 | 20 | FPS = 30 21 | W_SIZE = 800 # Width of window size 22 | H_SIZE = 600 # Height of window size 23 | COLOR_BACKGROUND = (128, 230, 198) 24 | LEGEND = 'Area {}x{}\nWorld {}x{}\nPress [ESC] to change' 25 | 26 | WORLDS = { 27 | '1': {'pos': (0, 0), 28 | 'win': (W_SIZE, H_SIZE), 29 | 'size': (W_SIZE * 2, H_SIZE * 3)}, 30 | '2': {'pos': (200, 100), 31 | 'win': (W_SIZE // 2, H_SIZE // 2), 32 | 'size': (W_SIZE * 2, H_SIZE * 3)}, 33 | '3': {'pos': (50, 250), 34 | 'win': (W_SIZE // 2, H_SIZE // 2), 35 | 'size': (200, 200)}, 36 | '4': {'pos': (350, 250), 37 | 'win': (W_SIZE // 2, H_SIZE // 2), 38 | 'size': (W_SIZE // 2, H_SIZE // 2)}, 39 | '5': {'pos': (200, 200), 40 | 'win': (W_SIZE // 2, H_SIZE // 2), 41 | 'size': (W_SIZE // 2, H_SIZE // 2 + 10)}, 42 | '6': {'pos': (10, 10), 43 | 'win': (W_SIZE - 300, H_SIZE // 2), 44 | 'size': (W_SIZE - 200, H_SIZE // 2 - 10)} 45 | } 46 | 47 | 48 | def make_world(width: int, height: int, text: str = '') -> 'pygame.Surface': 49 | """ 50 | Create a test surface. 51 | 52 | :param width: Width in pixels 53 | :param height: Height in pixels 54 | :param text: Text to write 55 | :return: World surface 56 | """ 57 | world = make_surface(width, height) 58 | world.fill((210, 210, 210)) 59 | font = pygame.font.SysFont('arial', 20) 60 | 61 | posy = 60 62 | for line in text.splitlines(): 63 | text = font.render(str(line), True, (0, 0, 0)) 64 | world.blit(text, (60, posy)) 65 | posy += text.get_height() + 10 66 | 67 | for x in range(0, width, 10): 68 | if x % 100 == 0 and x != 0: 69 | pygame.draw.line(world, (255, 0, 0), (x, 0), (x, 20)) 70 | pygame.draw.line(world, (180, 180, 180), (x, 80), (x, height)) 71 | tick = font.render(str(x), True, (255, 0, 0)) 72 | world.blit(tick, (int(x - tick.get_width() / 2), 25)) 73 | else: 74 | pygame.draw.line(world, (255, 0, 0), (x, 0), (x, 10)) 75 | for y in range(0, height, 10): 76 | if y % 100 == 0 and y != 0: 77 | pygame.draw.line(world, (255, 0, 0), (0, y), (20, y)) 78 | pygame.draw.line(world, (180, 180, 180), (80, y), (width, y)) 79 | tick = font.render(str(y), True, (255, 0, 0)) 80 | world.blit(tick, (25, int(y - tick.get_height() / 2))) 81 | else: 82 | pygame.draw.line(world, (255, 0, 0), (0, y), (10, y)) 83 | 84 | return world 85 | 86 | 87 | # noinspection PyProtectedMember 88 | def iter_world(area: 'ScrollArea') -> Generator: 89 | """ 90 | Iterate through worlds. 91 | 92 | :param area: Scroll area 93 | """ 94 | for name in itertools.cycle(WORLDS): 95 | params = WORLDS[name] 96 | area._rect.width = params['win'][0] 97 | area._rect.height = params['win'][1] 98 | text = LEGEND.format(params['win'][0], params['win'][1], params['size'][0], params['size'][1]) 99 | area.set_world(make_world(params['size'][0], params['size'][1], text)) 100 | area.set_position(*params['pos']) 101 | yield params 102 | 103 | 104 | def main(test: bool = False) -> None: 105 | """ 106 | Main function. 107 | 108 | :param test: Indicate function is being tested 109 | """ 110 | screen = create_example_window('Example - Scrolling Area', (W_SIZE, H_SIZE)) 111 | clock = pygame.time.Clock() 112 | 113 | area = ScrollArea( 114 | W_SIZE, H_SIZE, 115 | scrollbars=( 116 | locals.POSITION_SOUTH, 117 | locals.POSITION_EAST, 118 | locals.POSITION_WEST, 119 | locals.POSITION_NORTH 120 | ) 121 | ) 122 | 123 | worlds = iter_world(area) 124 | next(worlds) 125 | 126 | # ------------------------------------------------------------------------- 127 | # Main loop 128 | # ------------------------------------------------------------------------- 129 | while True: 130 | 131 | # Tick 132 | clock.tick(FPS) 133 | 134 | # Paint background 135 | screen.fill(COLOR_BACKGROUND) 136 | 137 | pygame.draw.rect( 138 | screen, 139 | (20, 89, 20), 140 | area.get_rect().inflate(20, 20) # Inflate to see area overflow in case of bug 141 | ) 142 | 143 | # Application events 144 | events = pygame.event.get() 145 | for event in events: 146 | if event.type == pygame.QUIT: 147 | exit(0) 148 | elif event.type == pygame.KEYDOWN: 149 | if event.key == pygame.K_ESCAPE: 150 | next(worlds) 151 | 152 | area.update(events) 153 | area.draw(screen) 154 | 155 | # Update surface 156 | pygame.display.flip() 157 | 158 | # At first loop returns 159 | if test: 160 | break 161 | 162 | 163 | if __name__ == '__main__': 164 | main() 165 | -------------------------------------------------------------------------------- /pygame_menu/examples/other/widget_positioning.py: -------------------------------------------------------------------------------- 1 | """ 2 | pygame-menu 3 | https://github.com/ppizarror/pygame-menu 4 | 5 | EXAMPLE - WIDGET POSITIONING 6 | Test widget positioning example. 7 | """ 8 | 9 | import pygame_menu 10 | from pygame_menu.examples import create_example_window 11 | 12 | # Create the surface 13 | surface = create_example_window('Example - Widget Positioning', (640, 480)) 14 | 15 | # Create a custom theme 16 | my_theme = pygame_menu.themes.THEME_DARK.copy() 17 | my_theme.title = False # Hide the menu title 18 | 19 | menu = pygame_menu.Menu( 20 | height=480, # Use full-screen 21 | theme=my_theme, 22 | title='', 23 | center_content=False, 24 | width=640 25 | ) 26 | 27 | menu.add.label( 28 | 'My App', 29 | background_color='#333', 30 | background_inflate=(30, 0), 31 | float=True # Widget does not add size to the menu 32 | ).translate(0, 10) 33 | 34 | label = menu.add.label( 35 | 'Lorem ipsum', 36 | float=True, 37 | font_name=pygame_menu.font.FONT_OPEN_SANS_ITALIC, 38 | font_size=25) 39 | label.rotate(90) 40 | label.translate(300, 160) 41 | 42 | # Button options 43 | b1 = menu.add.button( 44 | 'Main Menu', 45 | lambda: print(f'My method'), 46 | align=pygame_menu.locals.ALIGN_LEFT, 47 | float=True, 48 | selection_color='#fff' 49 | ) 50 | b1.translate(10, 170) 51 | b2 = menu.add.button( 52 | 'Exit', 53 | pygame_menu.events.EXIT, 54 | align=pygame_menu.locals.ALIGN_LEFT, 55 | float=True, 56 | selection_color='#fff' 57 | ) 58 | b2.translate(10, 235) 59 | 60 | # Bottom scrollable text 61 | f = menu.add.frame_v( 62 | background_color='#6b6e5e', 63 | border_color='#36372f', 64 | border_width=1, 65 | float=True, 66 | height=480, 67 | max_height=100, 68 | width=200 69 | ) 70 | f.translate(220, 390) 71 | labels = [menu.add.label(f' Lorem ipsum #{i}', font_size=15, font_color='#000000', padding=0) for i in range(20)] 72 | for j in labels: 73 | f.pack(j) 74 | 75 | if __name__ == '__main__': 76 | menu.mainloop(surface) 77 | -------------------------------------------------------------------------------- /pygame_menu/examples/scroll_menu.py: -------------------------------------------------------------------------------- 1 | """ 2 | pygame-menu 3 | https://github.com/ppizarror/pygame-menu 4 | 5 | EXAMPLE - SCROLL MENU 6 | Shows scrolling in menu. 7 | """ 8 | 9 | __all__ = ['main'] 10 | 11 | import pygame 12 | import pygame_menu 13 | from pygame_menu.examples import create_example_window 14 | 15 | from typing import Any 16 | from functools import partial 17 | 18 | FPS = 30 19 | WINDOW_SIZE = (800, 600) 20 | 21 | 22 | def on_button_click(value: str, text: Any = None) -> None: 23 | """ 24 | Button event on menus. 25 | 26 | :param value: Button value 27 | :param text: Button text 28 | """ 29 | if not text: 30 | print(f'Hello from {value}') 31 | else: 32 | print(f'Hello from {text} with {value}') 33 | 34 | 35 | def paint_background(surface: 'pygame.Surface') -> None: 36 | """ 37 | Paints a given surface with background color. 38 | 39 | :param surface: Pygame surface 40 | """ 41 | surface.fill((128, 230, 198)) 42 | 43 | 44 | def make_long_menu() -> 'pygame_menu.Menu': 45 | """ 46 | Create a long scrolling menu. 47 | 48 | :return: Menu 49 | """ 50 | theme_menu = pygame_menu.themes.THEME_BLUE.copy() 51 | theme_menu.scrollbar_cursor = pygame_menu.locals.CURSOR_HAND 52 | 53 | # Main menu, pauses execution of the application 54 | menu = pygame_menu.Menu( 55 | height=400, 56 | onclose=pygame_menu.events.EXIT, 57 | theme=theme_menu, 58 | title='Main Menu', 59 | width=600 60 | ) 61 | 62 | menu_sub = pygame_menu.Menu( 63 | columns=4, 64 | height=400, 65 | onclose=pygame_menu.events.EXIT, 66 | rows=3, 67 | theme=pygame_menu.themes.THEME_GREEN, 68 | title='Menu with columns', 69 | width=600 70 | ) 71 | 72 | menu_contributors = pygame_menu.Menu( 73 | height=400, 74 | onclose=pygame_menu.events.EXIT, 75 | theme=pygame_menu.themes.THEME_SOLARIZED, 76 | title='Contributors', 77 | width=600 78 | ) 79 | 80 | # Add table to contributors 81 | table_contrib = menu_contributors.add.table() 82 | table_contrib.default_cell_padding = 5 83 | table_contrib.default_row_background_color = 'white' 84 | bold_font = pygame_menu.font.FONT_OPEN_SANS_BOLD 85 | table_contrib.add_row(['N°', 'Github User'], cell_font=bold_font) 86 | for i in range(len(pygame_menu.__contributors__)): 87 | table_contrib.add_row([i + 1, pygame_menu.__contributors__[i]], cell_font=bold_font if i == 0 else None) 88 | 89 | table_contrib.update_cell_style(-1, -1, font_size=15) # Update all column/row 90 | table_contrib.update_cell_style(1, [2, -1], font=pygame_menu.font.FONT_OPEN_SANS_ITALIC) 91 | 92 | menu_text = pygame_menu.Menu( 93 | height=400, 94 | onclose=pygame_menu.events.EXIT, 95 | theme=pygame_menu.themes.THEME_DARK, 96 | title='Text with scroll', 97 | width=600 98 | ) 99 | 100 | menu.add.button('Rows and Columns', menu_sub) 101 | menu.add.button('Text scrolled', menu_text) 102 | menu.add.button('Pygame-menu contributors', menu_contributors) 103 | menu.add.vertical_margin(20) # Adds margin 104 | 105 | label1 = 'Button n°{}' 106 | label2 = 'Text n°{}: ' 107 | for i in range(1, 20): 108 | if i % 2 == 0: 109 | menu.add.button(label1.format(i), 110 | on_button_click, 111 | f'Button n°{i}') 112 | else: 113 | menu.add.text_input(label2.format(i), 114 | onchange=on_button_click, 115 | text=f'Text n°{i}') 116 | menu.add.button('Exit', pygame_menu.events.EXIT) 117 | 118 | label = 'Button n°{}' 119 | for i in range(1, 11): 120 | # Test large button 121 | if i == 5: 122 | txt = 'This is a very long button!' 123 | else: 124 | txt = label.format(100 * i) 125 | menu_sub.add.button(txt, on_button_click, 100 * i) 126 | menu_sub.add.button('Back', pygame_menu.events.BACK) 127 | 128 | # noinspection SpellCheckingInspection 129 | menu_text.add.label( 130 | 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod ' 131 | 'tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim ' 132 | 'veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea ' 133 | 'commodo consequat. Duis aute irure dolor in reprehenderit in voluptate ' 134 | 'velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat ' 135 | 'cupidatat non proident, sunt in culpa qui officia deserunt mollit anim ' 136 | 'id est laborum.', 137 | max_char=33, 138 | align=pygame_menu.locals.ALIGN_LEFT, 139 | margin=(0, -1) 140 | ) 141 | return menu 142 | 143 | 144 | def main(test: bool = False) -> None: 145 | """ 146 | Main function. 147 | 148 | :param test: Indicate function is being tested 149 | """ 150 | screen = create_example_window('Example - Scrolling Menu', WINDOW_SIZE) 151 | 152 | clock = pygame.time.Clock() 153 | menu = make_long_menu() 154 | 155 | # ------------------------------------------------------------------------- 156 | # Main loop 157 | # ------------------------------------------------------------------------- 158 | while True: 159 | 160 | # Tick 161 | clock.tick(FPS) 162 | 163 | # Paint background 164 | paint_background(screen) 165 | 166 | # Execute main from principal menu if is enabled 167 | menu.mainloop( 168 | surface=screen, 169 | bgfun=partial(paint_background, screen), 170 | disable_loop=test, 171 | fps_limit=FPS 172 | ) 173 | 174 | # Update surface 175 | pygame.display.flip() 176 | 177 | # At first loop returns 178 | if test: 179 | break 180 | 181 | 182 | if __name__ == '__main__': 183 | main() 184 | -------------------------------------------------------------------------------- /pygame_menu/examples/simple.py: -------------------------------------------------------------------------------- 1 | """ 2 | pygame-menu 3 | https://github.com/ppizarror/pygame-menu 4 | 5 | EXAMPLE - SIMPLE 6 | Super simple example of pygame-menu usage, featuring a selector and a button. 7 | """ 8 | 9 | import pygame_menu 10 | from pygame_menu.examples import create_example_window 11 | 12 | from typing import Tuple, Any 13 | 14 | surface = create_example_window('Example - Simple', (600, 400)) 15 | 16 | 17 | def set_difficulty(selected: Tuple, value: Any) -> None: 18 | """ 19 | Set the difficulty of the game. 20 | """ 21 | print(f'Set difficulty to {selected[0]} ({value})') 22 | 23 | 24 | def start_the_game() -> None: 25 | """ 26 | Function that starts a game. This is raised by the menu button, 27 | here menu can be disabled, etc. 28 | """ 29 | global user_name 30 | print(f'{user_name.get_value()}, Do the job here!') 31 | 32 | 33 | menu = pygame_menu.Menu( 34 | height=300, 35 | theme=pygame_menu.themes.THEME_BLUE, 36 | title='Welcome', 37 | width=400 38 | ) 39 | 40 | user_name = menu.add.text_input('Name: ', default='John Doe', maxchar=10) 41 | menu.add.selector('Difficulty: ', [('Hard', 1), ('Easy', 2)], onchange=set_difficulty) 42 | menu.add.button('Play', start_the_game) 43 | menu.add.button('Quit', pygame_menu.events.EXIT) 44 | 45 | if __name__ == '__main__': 46 | menu.mainloop(surface) 47 | -------------------------------------------------------------------------------- /pygame_menu/examples/window_resize.py: -------------------------------------------------------------------------------- 1 | """ 2 | pygame-menu 3 | https://github.com/ppizarror/pygame-menu 4 | 5 | EXAMPLE - WINDOW RESIZE 6 | Resize the menu when the window is resized. 7 | """ 8 | 9 | import pygame 10 | import pygame_menu 11 | 12 | pygame.init() 13 | 14 | surface = pygame.display.set_mode((600, 400), pygame.RESIZABLE) 15 | pygame.display.set_caption("Example resizable window") 16 | 17 | menu = pygame_menu.Menu( 18 | height=100, 19 | theme=pygame_menu.themes.THEME_BLUE, 20 | title='Welcome', 21 | width=100 22 | ) 23 | 24 | 25 | def on_resize() -> None: 26 | """ 27 | Function checked if the window is resized. 28 | """ 29 | window_size = surface.get_size() 30 | new_w, new_h = 0.75 * window_size[0], 0.7 * window_size[1] 31 | menu.resize(new_w, new_h) 32 | print(f'New menu size: {menu.get_size()}') 33 | 34 | 35 | menu.add.label('Resize the window!') 36 | user_name = menu.add.text_input('Name: ', default='John Doe', maxchar=10) 37 | menu.add.selector('Difficulty: ', [('Hard', 1), ('Easy', 2)]) 38 | menu.add.button('Quit', pygame_menu.events.EXIT) 39 | menu.enable() 40 | on_resize() # Set initial size 41 | 42 | if __name__ == '__main__': 43 | while True: 44 | events = pygame.event.get() 45 | for event in events: 46 | if event.type == pygame.QUIT: 47 | pygame.quit() 48 | break 49 | if event.type == pygame.VIDEORESIZE: 50 | # Update the surface 51 | surface = pygame.display.set_mode((event.w, event.h), pygame.RESIZABLE) 52 | # Call the menu event 53 | on_resize() 54 | 55 | # Draw the menu 56 | surface.fill((25, 0, 50)) 57 | 58 | menu.update(events) 59 | menu.draw(surface) 60 | 61 | pygame.display.flip() 62 | -------------------------------------------------------------------------------- /pygame_menu/locals.py: -------------------------------------------------------------------------------- 1 | """ 2 | pygame-menu 3 | https://github.com/ppizarror/pygame-menu 4 | 5 | LOCALS 6 | Local constants. 7 | """ 8 | 9 | __all__ = [ 10 | 11 | # Alignment 12 | 'ALIGN_CENTER', 13 | 'ALIGN_LEFT', 14 | 'ALIGN_RIGHT', 15 | 16 | # Data types 17 | 'INPUT_FLOAT', 18 | 'INPUT_INT', 19 | 'INPUT_TEXT', 20 | 21 | # Positioning 22 | 'POSITION_CENTER', 23 | 'POSITION_EAST', 24 | 'POSITION_NORTH', 25 | 'POSITION_NORTHEAST', 26 | 'POSITION_SOUTHWEST', 27 | 'POSITION_SOUTH', 28 | 'POSITION_SOUTHEAST', 29 | 'POSITION_NORTHWEST', 30 | 'POSITION_WEST', 31 | 32 | # Orientation 33 | 'ORIENTATION_HORIZONTAL', 34 | 'ORIENTATION_VERTICAL', 35 | 36 | # Scrollarea 37 | 'SCROLLAREA_POSITION_BOTH_HORIZONTAL', 38 | 'SCROLLAREA_POSITION_BOTH_VERTICAL', 39 | 'SCROLLAREA_POSITION_FULL', 40 | 'SCROLLAREA_POSITION_NONE', 41 | 42 | # Cursors 43 | 'CURSOR_ARROW', 44 | 'CURSOR_CROSSHAIR', 45 | 'CURSOR_HAND', 46 | 'CURSOR_IBEAM', 47 | 'CURSOR_NO', 48 | 'CURSOR_SIZEALL', 49 | 'CURSOR_SIZENESW', 50 | 'CURSOR_SIZENS', 51 | 'CURSOR_SIZENWSE', 52 | 'CURSOR_SIZEWE', 53 | 'CURSOR_WAIT', 54 | 'CURSOR_WAITARROW', 55 | 56 | # Event compatibility 57 | 'FINGERDOWN', 58 | 'FINGERMOTION', 59 | 'FINGERUP' 60 | 61 | ] 62 | 63 | import pygame as __pygame 64 | 65 | # Alignment 66 | ALIGN_CENTER = 'align-center' 67 | ALIGN_LEFT = 'align-left' 68 | ALIGN_RIGHT = 'align-right' 69 | 70 | # Input data type 71 | INPUT_FLOAT = 'input-float' 72 | INPUT_INT = 'input-int' 73 | INPUT_TEXT = 'input-text' 74 | 75 | # Position 76 | POSITION_CENTER = 'position-center' 77 | POSITION_EAST = 'position-east' 78 | POSITION_NORTH = 'position-north' 79 | POSITION_NORTHEAST = 'position-northeast' 80 | POSITION_NORTHWEST = 'position-northwest' 81 | POSITION_SOUTH = 'position-south' 82 | POSITION_SOUTHEAST = 'position-southeast' 83 | POSITION_SOUTHWEST = 'position-southwest' 84 | POSITION_WEST = 'position-west' 85 | 86 | # Menu ScrollArea position 87 | SCROLLAREA_POSITION_BOTH_HORIZONTAL = 'scrollarea-position-both-horizontal' 88 | SCROLLAREA_POSITION_BOTH_VERTICAL = 'scrollarea_position-both-vertical' 89 | SCROLLAREA_POSITION_FULL = 'scrollarea-position-full' 90 | SCROLLAREA_POSITION_NONE = 'scrollarea-position-none' 91 | 92 | # Orientation 93 | ORIENTATION_HORIZONTAL = 'orientation-horizontal' 94 | ORIENTATION_VERTICAL = 'orientation-vertical' 95 | 96 | # Cursors 97 | CURSOR_ARROW = None if not hasattr(__pygame, 'SYSTEM_CURSOR_ARROW') else __pygame.SYSTEM_CURSOR_ARROW 98 | CURSOR_CROSSHAIR = None if not hasattr(__pygame, 'SYSTEM_CURSOR_CROSSHAIR') else __pygame.SYSTEM_CURSOR_CROSSHAIR 99 | CURSOR_HAND = None if not hasattr(__pygame, 'SYSTEM_CURSOR_HAND') else __pygame.SYSTEM_CURSOR_HAND 100 | CURSOR_IBEAM = None if not hasattr(__pygame, 'SYSTEM_CURSOR_IBEAM') else __pygame.SYSTEM_CURSOR_IBEAM 101 | CURSOR_NO = None if not hasattr(__pygame, 'SYSTEM_CURSOR_NO') else __pygame.SYSTEM_CURSOR_NO 102 | CURSOR_SIZEALL = None if not hasattr(__pygame, 'SYSTEM_CURSOR_SIZEALL') else __pygame.SYSTEM_CURSOR_SIZEALL 103 | CURSOR_SIZENESW = None if not hasattr(__pygame, 'SYSTEM_CURSOR_SIZENESW') else __pygame.SYSTEM_CURSOR_SIZENESW 104 | CURSOR_SIZENS = None if not hasattr(__pygame, 'SYSTEM_CURSOR_SIZENS') else __pygame.SYSTEM_CURSOR_SIZENS 105 | CURSOR_SIZENWSE = None if not hasattr(__pygame, 'SYSTEM_CURSOR_SIZENWSE') else __pygame.SYSTEM_CURSOR_SIZENWSE 106 | CURSOR_SIZEWE = None if not hasattr(__pygame, 'SYSTEM_CURSOR_SIZEWE') else __pygame.SYSTEM_CURSOR_SIZEWE 107 | CURSOR_WAIT = None if not hasattr(__pygame, 'SYSTEM_CURSOR_WAIT') else __pygame.SYSTEM_CURSOR_WAIT 108 | CURSOR_WAITARROW = None if not hasattr(__pygame, 'SYSTEM_CURSOR_WAITARROW') else __pygame.SYSTEM_CURSOR_WAITARROW 109 | 110 | # Events compatibility with lower pygame versions 111 | FINGERDOWN = -1 if not hasattr(__pygame, 'FINGERDOWN') else __pygame.FINGERDOWN 112 | FINGERMOTION = -1 if not hasattr(__pygame, 'FINGERMOTION') else __pygame.FINGERMOTION 113 | FINGERUP = -1 if not hasattr(__pygame, 'FINGERUP') else __pygame.FINGERUP 114 | -------------------------------------------------------------------------------- /pygame_menu/py.typed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/pygame_menu/py.typed -------------------------------------------------------------------------------- /pygame_menu/resources/fonts/8bit.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/pygame_menu/resources/fonts/8bit.ttf -------------------------------------------------------------------------------- /pygame_menu/resources/fonts/FiraCode-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/pygame_menu/resources/fonts/FiraCode-Bold.ttf -------------------------------------------------------------------------------- /pygame_menu/resources/fonts/FiraCode-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/pygame_menu/resources/fonts/FiraCode-Regular.ttf -------------------------------------------------------------------------------- /pygame_menu/resources/fonts/FiraMono-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/pygame_menu/resources/fonts/FiraMono-BoldItalic.ttf -------------------------------------------------------------------------------- /pygame_menu/resources/fonts/FiraMono-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/pygame_menu/resources/fonts/FiraMono-Italic.ttf -------------------------------------------------------------------------------- /pygame_menu/resources/fonts/LICENSE_DIGITAL.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) , (), 2 | with Reserved Font Name . 3 | Copyright (c) , (), 4 | with Reserved Font Name . 5 | Copyright (c) , (). 6 | 7 | This Font Software is licensed under the SIL Open Font License, Version 1.1. 8 | This license is copied below, and is also available with a FAQ at: 9 | http://scripts.sil.org/OFL 10 | 11 | 12 | ----------------------------------------------------------- 13 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 14 | ----------------------------------------------------------- 15 | 16 | PREAMBLE 17 | The goals of the Open Font License (OFL) are to stimulate worldwide 18 | development of collaborative font projects, to support the font creation 19 | efforts of academic and linguistic communities, and to provide a free and 20 | open framework in which fonts may be shared and improved in partnership 21 | with others. 22 | 23 | The OFL allows the licensed fonts to be used, studied, modified and 24 | redistributed freely as long as they are not sold by themselves. The 25 | fonts, including any derivative works, can be bundled, embedded, 26 | redistributed and/or sold with any software provided that any reserved 27 | names are not used by derivative works. The fonts and derivatives, 28 | however, cannot be released under any other type of license. The 29 | requirement for fonts to remain under this license does not apply 30 | to any document created using the fonts or their derivatives. 31 | 32 | DEFINITIONS 33 | "Font Software" refers to the set of files released by the Copyright 34 | Holder(s) under this license and clearly marked as such. This may 35 | include source files, build scripts and documentation. 36 | 37 | "Reserved Font Name" refers to any names specified as such after the 38 | copyright statement(s). 39 | 40 | "Original Version" refers to the collection of Font Software components as 41 | distributed by the Copyright Holder(s). 42 | 43 | "Modified Version" refers to any derivative made by adding to, deleting, 44 | or substituting -- in part or in whole -- any of the components of the 45 | Original Version, by changing formats or by porting the Font Software to a 46 | new environment. 47 | 48 | "Author" refers to any designer, engineer, programmer, technical 49 | writer or other person who contributed to the Font Software. 50 | 51 | PERMISSION & CONDITIONS 52 | Permission is hereby granted, free of charge, to any person obtaining 53 | a copy of the Font Software, to use, study, copy, merge, embed, modify, 54 | redistribute, and sell modified and unmodified copies of the Font 55 | Software, subject to the following conditions: 56 | 57 | 1) Neither the Font Software nor any of its individual components, 58 | in Original or Modified Versions, may be sold by itself. 59 | 60 | 2) Original or Modified Versions of the Font Software may be bundled, 61 | redistributed and/or sold with any software, provided that each copy 62 | contains the above copyright notice and this license. These can be 63 | included either as stand-alone text files, human-readable headers or 64 | in the appropriate machine-readable metadata fields within text or 65 | binary files as long as those fields can be easily viewed by the user. 66 | 67 | 3) No Modified Version of the Font Software may use the Reserved Font 68 | Name(s) unless explicit written permission is granted by the corresponding 69 | Copyright Holder. This restriction only applies to the primary font name as 70 | presented to the users. 71 | 72 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font 73 | Software shall not be used to promote, endorse or advertise any 74 | Modified Version, except to acknowledge the contribution(s) of the 75 | Copyright Holder(s) and the Author(s) or with their explicit written 76 | permission. 77 | 78 | 5) The Font Software, modified or unmodified, in part or in whole, 79 | must be distributed entirely under this license, and must not be 80 | distributed under any other license. The requirement for fonts to 81 | remain under this license does not apply to any document created 82 | using the Font Software. 83 | 84 | TERMINATION 85 | This license becomes null and void if any of the above conditions are 86 | not met. 87 | 88 | DISCLAIMER 89 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 90 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF 91 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 92 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE 93 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 94 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL 95 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 96 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM 97 | OTHER DEALINGS IN THE FONT SOFTWARE. 98 | -------------------------------------------------------------------------------- /pygame_menu/resources/fonts/LICENSE_FiraCode.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014, The Fira Code Project Authors (https://github.com/tonsky/FiraCode) 2 | 3 | This Font Software is licensed under the SIL Open Font License, Version 1.1. 4 | This license is copied below, and is also available with a FAQ at: 5 | http://scripts.sil.org/OFL 6 | 7 | 8 | ----------------------------------------------------------- 9 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 10 | ----------------------------------------------------------- 11 | 12 | PREAMBLE 13 | The goals of the Open Font License (OFL) are to stimulate worldwide 14 | development of collaborative font projects, to support the font creation 15 | efforts of academic and linguistic communities, and to provide a free and 16 | open framework in which fonts may be shared and improved in partnership 17 | with others. 18 | 19 | The OFL allows the licensed fonts to be used, studied, modified and 20 | redistributed freely as long as they are not sold by themselves. The 21 | fonts, including any derivative works, can be bundled, embedded, 22 | redistributed and/or sold with any software provided that any reserved 23 | names are not used by derivative works. The fonts and derivatives, 24 | however, cannot be released under any other type of license. The 25 | requirement for fonts to remain under this license does not apply 26 | to any document created using the fonts or their derivatives. 27 | 28 | DEFINITIONS 29 | "Font Software" refers to the set of files released by the Copyright 30 | Holder(s) under this license and clearly marked as such. This may 31 | include source files, build scripts and documentation. 32 | 33 | "Reserved Font Name" refers to any names specified as such after the 34 | copyright statement(s). 35 | 36 | "Original Version" refers to the collection of Font Software components as 37 | distributed by the Copyright Holder(s). 38 | 39 | "Modified Version" refers to any derivative made by adding to, deleting, 40 | or substituting -- in part or in whole -- any of the components of the 41 | Original Version, by changing formats or by porting the Font Software to a 42 | new environment. 43 | 44 | "Author" refers to any designer, engineer, programmer, technical 45 | writer or other person who contributed to the Font Software. 46 | 47 | PERMISSION & CONDITIONS 48 | Permission is hereby granted, free of charge, to any person obtaining 49 | a copy of the Font Software, to use, study, copy, merge, embed, modify, 50 | redistribute, and sell modified and unmodified copies of the Font 51 | Software, subject to the following conditions: 52 | 53 | 1) Neither the Font Software nor any of its individual components, 54 | in Original or Modified Versions, may be sold by itself. 55 | 56 | 2) Original or Modified Versions of the Font Software may be bundled, 57 | redistributed and/or sold with any software, provided that each copy 58 | contains the above copyright notice and this license. These can be 59 | included either as stand-alone text files, human-readable headers or 60 | in the appropriate machine-readable metadata fields within text or 61 | binary files as long as those fields can be easily viewed by the user. 62 | 63 | 3) No Modified Version of the Font Software may use the Reserved Font 64 | Name(s) unless explicit written permission is granted by the corresponding 65 | Copyright Holder. This restriction only applies to the primary font name as 66 | presented to the users. 67 | 68 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font 69 | Software shall not be used to promote, endorse or advertise any 70 | Modified Version, except to acknowledge the contribution(s) of the 71 | Copyright Holder(s) and the Author(s) or with their explicit written 72 | permission. 73 | 74 | 5) The Font Software, modified or unmodified, in part or in whole, 75 | must be distributed entirely under this license, and must not be 76 | distributed under any other license. The requirement for fonts to 77 | remain under this license does not apply to any document created 78 | using the Font Software. 79 | 80 | TERMINATION 81 | This license becomes null and void if any of the above conditions are 82 | not met. 83 | 84 | DISCLAIMER 85 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 86 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF 87 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 88 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE 89 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 90 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL 91 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 92 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM 93 | OTHER DEALINGS IN THE FONT SOFTWARE. -------------------------------------------------------------------------------- /pygame_menu/resources/fonts/LICENSE_PTSERIF.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2010, ParaType Ltd. (http://www.paratype.com/public), 2 | with Reserved Font Names "PT Sans", "PT Serif" and "ParaType". 3 | 4 | This Font Software is licensed under the SIL Open Font License, Version 1.1. 5 | This license is copied below, and is also available with a FAQ at: 6 | http://scripts.sil.org/OFL 7 | 8 | 9 | ----------------------------------------------------------- 10 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 11 | ----------------------------------------------------------- 12 | 13 | PREAMBLE 14 | The goals of the Open Font License (OFL) are to stimulate worldwide 15 | development of collaborative font projects, to support the font creation 16 | efforts of academic and linguistic communities, and to provide a free and 17 | open framework in which fonts may be shared and improved in partnership 18 | with others. 19 | 20 | The OFL allows the licensed fonts to be used, studied, modified and 21 | redistributed freely as long as they are not sold by themselves. The 22 | fonts, including any derivative works, can be bundled, embedded, 23 | redistributed and/or sold with any software provided that any reserved 24 | names are not used by derivative works. The fonts and derivatives, 25 | however, cannot be released under any other type of license. The 26 | requirement for fonts to remain under this license does not apply 27 | to any document created using the fonts or their derivatives. 28 | 29 | DEFINITIONS 30 | "Font Software" refers to the set of files released by the Copyright 31 | Holder(s) under this license and clearly marked as such. This may 32 | include source files, build scripts and documentation. 33 | 34 | "Reserved Font Name" refers to any names specified as such after the 35 | copyright statement(s). 36 | 37 | "Original Version" refers to the collection of Font Software components as 38 | distributed by the Copyright Holder(s). 39 | 40 | "Modified Version" refers to any derivative made by adding to, deleting, 41 | or substituting -- in part or in whole -- any of the components of the 42 | Original Version, by changing formats or by porting the Font Software to a 43 | new environment. 44 | 45 | "Author" refers to any designer, engineer, programmer, technical 46 | writer or other person who contributed to the Font Software. 47 | 48 | PERMISSION & CONDITIONS 49 | Permission is hereby granted, free of charge, to any person obtaining 50 | a copy of the Font Software, to use, study, copy, merge, embed, modify, 51 | redistribute, and sell modified and unmodified copies of the Font 52 | Software, subject to the following conditions: 53 | 54 | 1) Neither the Font Software nor any of its individual components, 55 | in Original or Modified Versions, may be sold by itself. 56 | 57 | 2) Original or Modified Versions of the Font Software may be bundled, 58 | redistributed and/or sold with any software, provided that each copy 59 | contains the above copyright notice and this license. These can be 60 | included either as stand-alone text files, human-readable headers or 61 | in the appropriate machine-readable metadata fields within text or 62 | binary files as long as those fields can be easily viewed by the user. 63 | 64 | 3) No Modified Version of the Font Software may use the Reserved Font 65 | Name(s) unless explicit written permission is granted by the corresponding 66 | Copyright Holder. This restriction only applies to the primary font name as 67 | presented to the users. 68 | 69 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font 70 | Software shall not be used to promote, endorse or advertise any 71 | Modified Version, except to acknowledge the contribution(s) of the 72 | Copyright Holder(s) and the Author(s) or with their explicit written 73 | permission. 74 | 75 | 5) The Font Software, modified or unmodified, in part or in whole, 76 | must be distributed entirely under this license, and must not be 77 | distributed under any other license. The requirement for fonts to 78 | remain under this license does not apply to any document created 79 | using the Font Software. 80 | 81 | TERMINATION 82 | This license becomes null and void if any of the above conditions are 83 | not met. 84 | 85 | DISCLAIMER 86 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 87 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF 88 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 89 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE 90 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 91 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL 92 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 93 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM 94 | OTHER DEALINGS IN THE FONT SOFTWARE. 95 | -------------------------------------------------------------------------------- /pygame_menu/resources/fonts/bebas.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/pygame_menu/resources/fonts/bebas.ttf -------------------------------------------------------------------------------- /pygame_menu/resources/fonts/comic_neue.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/pygame_menu/resources/fonts/comic_neue.ttf -------------------------------------------------------------------------------- /pygame_menu/resources/fonts/digital.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/pygame_menu/resources/fonts/digital.ttf -------------------------------------------------------------------------------- /pygame_menu/resources/fonts/franchise.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/pygame_menu/resources/fonts/franchise.ttf -------------------------------------------------------------------------------- /pygame_menu/resources/fonts/helvetica.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/pygame_menu/resources/fonts/helvetica.ttf -------------------------------------------------------------------------------- /pygame_menu/resources/fonts/munro.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/pygame_menu/resources/fonts/munro.ttf -------------------------------------------------------------------------------- /pygame_menu/resources/fonts/nevis.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/pygame_menu/resources/fonts/nevis.ttf -------------------------------------------------------------------------------- /pygame_menu/resources/fonts/opensans_bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/pygame_menu/resources/fonts/opensans_bold.ttf -------------------------------------------------------------------------------- /pygame_menu/resources/fonts/opensans_italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/pygame_menu/resources/fonts/opensans_italic.ttf -------------------------------------------------------------------------------- /pygame_menu/resources/fonts/opensans_light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/pygame_menu/resources/fonts/opensans_light.ttf -------------------------------------------------------------------------------- /pygame_menu/resources/fonts/opensans_regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/pygame_menu/resources/fonts/opensans_regular.ttf -------------------------------------------------------------------------------- /pygame_menu/resources/fonts/ptserif_regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/pygame_menu/resources/fonts/ptserif_regular.ttf -------------------------------------------------------------------------------- /pygame_menu/resources/images/carbon_fiber.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/pygame_menu/resources/images/carbon_fiber.png -------------------------------------------------------------------------------- /pygame_menu/resources/images/gray_lines.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/pygame_menu/resources/images/gray_lines.png -------------------------------------------------------------------------------- /pygame_menu/resources/images/metal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/pygame_menu/resources/images/metal.png -------------------------------------------------------------------------------- /pygame_menu/resources/images/pygame_menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/pygame_menu/resources/images/pygame_menu.png -------------------------------------------------------------------------------- /pygame_menu/resources/images/python.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pygame_menu/resources/images/tiled_border.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/pygame_menu/resources/images/tiled_border.png -------------------------------------------------------------------------------- /pygame_menu/resources/images/wallpaper.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/pygame_menu/resources/images/wallpaper.jpg -------------------------------------------------------------------------------- /pygame_menu/resources/sounds/click_mouse.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/pygame_menu/resources/sounds/click_mouse.ogg -------------------------------------------------------------------------------- /pygame_menu/resources/sounds/close_menu.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/pygame_menu/resources/sounds/close_menu.ogg -------------------------------------------------------------------------------- /pygame_menu/resources/sounds/error.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/pygame_menu/resources/sounds/error.ogg -------------------------------------------------------------------------------- /pygame_menu/resources/sounds/event.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/pygame_menu/resources/sounds/event.ogg -------------------------------------------------------------------------------- /pygame_menu/resources/sounds/event_error.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/pygame_menu/resources/sounds/event_error.ogg -------------------------------------------------------------------------------- /pygame_menu/resources/sounds/key_add.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/pygame_menu/resources/sounds/key_add.ogg -------------------------------------------------------------------------------- /pygame_menu/resources/sounds/key_delete.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/pygame_menu/resources/sounds/key_delete.ogg -------------------------------------------------------------------------------- /pygame_menu/resources/sounds/open_menu.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/pygame_menu/resources/sounds/open_menu.ogg -------------------------------------------------------------------------------- /pygame_menu/resources/sounds/widget_selection.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppizarror/pygame-menu/6211d301f3c9450e6885fdf7bf3c4117df25944d/pygame_menu/resources/sounds/widget_selection.ogg -------------------------------------------------------------------------------- /pygame_menu/version.py: -------------------------------------------------------------------------------- 1 | """ 2 | pygame-menu 3 | https://github.com/ppizarror/pygame-menu 4 | 5 | VERSION 6 | Library version. 7 | """ 8 | 9 | __all__ = ['Version', 'vernum', 'ver', 'rev'] 10 | 11 | 12 | class Version(tuple): 13 | """ 14 | Version class. 15 | """ 16 | 17 | __slots__ = () 18 | fields = 'major', 'minor', 'patch' 19 | 20 | def __new__(cls, major, minor, patch) -> 'Version': 21 | # noinspection PyTypeChecker 22 | return tuple.__new__(cls, (major, minor, patch)) 23 | 24 | def __repr__(self) -> str: 25 | fields = (f'{fld}={val}' for fld, val in zip(self.fields, self)) 26 | return f'{self.__class__.__name__}({", ".join(fields)})' 27 | 28 | def __str__(self) -> str: 29 | return '{}.{}.{}'.format(*self) 30 | 31 | major = property(lambda self: self[0]) 32 | minor = property(lambda self: self[1]) 33 | patch = property(lambda self: self[2]) 34 | 35 | 36 | vernum = Version(4, 5, 4) 37 | ver = str(vernum) 38 | rev = '' 39 | -------------------------------------------------------------------------------- /pygame_menu/widgets/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | pygame-menu 3 | https://github.com/ppizarror/pygame-menu 4 | 5 | WIDGETS 6 | Widgets elements that can be added to the Menu. 7 | """ 8 | 9 | # Widgets core 10 | import pygame_menu.widgets.core 11 | from pygame_menu.widgets.core import Widget 12 | 13 | # Selection 14 | from pygame_menu.widgets.selection import HighlightSelection, LeftArrowSelection, \ 15 | NoneSelection, RightArrowSelection, SimpleSelection 16 | 17 | # Widgets 18 | from pygame_menu.widgets.widget import Button, ColorInput, DropSelect, \ 19 | DropSelectMultiple, Frame, HMargin, Image, Label, MenuBar, MenuLink, NoneWidget, \ 20 | ProgressBar, RangeSlider, ScrollBar, Selector, SurfaceWidget, Table, TextInput, \ 21 | ToggleSwitch, VFill, VMargin 22 | 23 | # Widget constants 24 | from pygame_menu.widgets.widget.colorinput import COLORINPUT_TYPE_RGB, \ 25 | COLORINPUT_TYPE_HEX, COLORINPUT_HEX_FORMAT_UPPER, COLORINPUT_HEX_FORMAT_NONE, \ 26 | COLORINPUT_HEX_FORMAT_LOWER 27 | 28 | from pygame_menu.widgets.widget.dropselect_multiple import \ 29 | DROPSELECT_MULTIPLE_SFORMAT_TOTAL, DROPSELECT_MULTIPLE_SFORMAT_LIST_COMMA, \ 30 | DROPSELECT_MULTIPLE_SFORMAT_LIST_HYPHEN 31 | 32 | from pygame_menu.widgets.widget.frame import FRAME_DEFAULT_TITLE_BACKGROUND_COLOR, \ 33 | FRAME_TITLE_BUTTON_CLOSE, FRAME_TITLE_BUTTON_MAXIMIZE, FRAME_TITLE_BUTTON_MINIMIZE 34 | 35 | from pygame_menu.widgets.widget.menubar import MENUBAR_STYLE_ADAPTIVE, \ 36 | MENUBAR_STYLE_SIMPLE, MENUBAR_STYLE_TITLE_ONLY, MENUBAR_STYLE_TITLE_ONLY_DIAGONAL, \ 37 | MENUBAR_STYLE_NONE, MENUBAR_STYLE_UNDERLINE, MENUBAR_STYLE_UNDERLINE_TITLE 38 | 39 | from pygame_menu.widgets.widget.selector import SELECTOR_STYLE_CLASSIC, \ 40 | SELECTOR_STYLE_FANCY 41 | -------------------------------------------------------------------------------- /pygame_menu/widgets/core/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | pygame-menu 3 | https://github.com/ppizarror/pygame-menu 4 | 5 | CORE 6 | This module contains the widget core classes. 7 | """ 8 | 9 | from pygame_menu.widgets.core.widget import Widget 10 | from pygame_menu.widgets.core.selection import Selection 11 | -------------------------------------------------------------------------------- /pygame_menu/widgets/selection/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | pygame-menu 3 | https://github.com/ppizarror/pygame-menu 4 | 5 | SELECTION 6 | This module contains the widget highlight effects. 7 | """ 8 | 9 | from pygame_menu.widgets.selection.highlight import HighlightSelection 10 | from pygame_menu.widgets.selection.left_arrow import LeftArrowSelection 11 | from pygame_menu.widgets.selection.none import NoneSelection 12 | from pygame_menu.widgets.selection.right_arrow import RightArrowSelection 13 | from pygame_menu.widgets.selection.simple import SimpleSelection 14 | -------------------------------------------------------------------------------- /pygame_menu/widgets/selection/arrow_selection.py: -------------------------------------------------------------------------------- 1 | """ 2 | pygame-menu 3 | https://github.com/ppizarror/pygame-menu 4 | 5 | LEFT ARROW CLASS 6 | Selector with a left arrow on the item. 7 | """ 8 | 9 | __all__ = ['ArrowSelection'] 10 | 11 | import pygame 12 | import pygame_menu 13 | 14 | from pygame_menu.utils import assert_vector 15 | from pygame_menu.widgets.core import Selection 16 | 17 | from pygame_menu._types import NumberType, Tuple2IntType, Optional, NumberInstance 18 | 19 | SELECTOR_CLOCK = pygame.time.Clock() 20 | 21 | 22 | class ArrowSelection(Selection): 23 | """ 24 | Widget selection arrow class. 25 | Parent class for left and right arrow selection classes. 26 | 27 | :param margin_left: Left margin (px) 28 | :param margin_right: Right margin (px) 29 | :param margin_top: Top margin (px) 30 | :param margin_bottom: Bottom margin (px) 31 | :param arrow_size: Size of arrow on x-axis and y-axis (width, height) in px 32 | :param arrow_vertical_offset: Vertical offset of the arrow (px) 33 | :param blink_ms: Milliseconds between each blink; if ``0`` blinking is disabled 34 | """ 35 | _arrow_vertical_offset: int 36 | _arrow_size: Tuple2IntType 37 | _blink_ms: NumberType 38 | _blink_time: NumberType 39 | _blink_status: bool 40 | _last_widget: Optional['pygame_menu.widgets.Widget'] 41 | 42 | def __init__( 43 | self, 44 | margin_left: NumberType, 45 | margin_right: NumberType, 46 | margin_top: NumberType, 47 | margin_bottom: NumberType, 48 | arrow_size: Tuple2IntType = (10, 15), 49 | arrow_vertical_offset: NumberType = 0, 50 | blink_ms: NumberType = 0 51 | ) -> None: 52 | super(ArrowSelection, self).__init__( 53 | margin_left=margin_left, 54 | margin_right=margin_right, 55 | margin_top=margin_top, 56 | margin_bottom=margin_bottom 57 | ) 58 | 59 | assert_vector(arrow_size, 2, int) 60 | assert isinstance(arrow_vertical_offset, NumberInstance) 61 | assert isinstance(blink_ms, int) 62 | assert arrow_size[0] > 0 and arrow_size[1] > 0, 'arrow size must be greater than zero' 63 | assert blink_ms >= 0, 'blinking milliseconds must be greater than or equal to zero' 64 | 65 | self._arrow_vertical_offset = int(arrow_vertical_offset) 66 | self._arrow_size = (arrow_size[0], arrow_size[1]) 67 | self._blink_ms = blink_ms 68 | self._blink_time = 0 69 | self._blink_status = True 70 | self._last_widget = None 71 | 72 | # noinspection PyMissingOrEmptyDocstring 73 | def draw(self, surface: 'pygame.Surface', widget: 'pygame_menu.widgets.Widget') -> 'ArrowSelection': 74 | raise NotImplementedError('override is mandatory') 75 | 76 | def _draw_arrow( 77 | self, 78 | surface: 'pygame.Surface', 79 | widget: 'pygame_menu.widgets.Widget', 80 | a: Tuple2IntType, 81 | b: Tuple2IntType, 82 | c: Tuple2IntType 83 | ) -> None: 84 | """ 85 | Draw the selection arrow. 86 | 87 | :param surface: Surface to draw 88 | :param widget: Widget object 89 | :param a: Arrow coord A 90 | :param b: Arrow coord B 91 | :param c: Arrow coord C 92 | """ 93 | SELECTOR_CLOCK.tick(60) 94 | self._blink_time += SELECTOR_CLOCK.get_time() 95 | 96 | # Switch the blinking if the time exceeded or the widget has changed 97 | if self._blink_ms != 0 and (self._blink_time > self._blink_ms or self._last_widget != widget): 98 | self._blink_status = not self._blink_status or self._last_widget != widget 99 | self._blink_time = 0 100 | self._last_widget = widget 101 | 102 | # Draw the arrow only if blinking is enabled 103 | if self._blink_status: 104 | pygame.draw.polygon(surface, self.color, [a, b, c]) 105 | -------------------------------------------------------------------------------- /pygame_menu/widgets/selection/highlight.py: -------------------------------------------------------------------------------- 1 | """ 2 | pygame-menu 3 | https://github.com/ppizarror/pygame-menu 4 | 5 | HIGHLIGHT 6 | Widget selection highlight box effect. 7 | """ 8 | 9 | __all__ = ['HighlightSelection'] 10 | 11 | import pygame 12 | import pygame_menu 13 | 14 | from pygame_menu.widgets.core import Selection 15 | 16 | from pygame_menu._types import NumberType 17 | 18 | 19 | class HighlightSelection(Selection): 20 | """ 21 | Widget selection highlight class. 22 | 23 | .. note:: 24 | 25 | Widget background color may not reach the entire selection area. 26 | 27 | :param border_width: Border width of the highlight box (px) 28 | :param margin_x: X margin of selected highlight box (px) 29 | :param margin_y: Y margin of selected highlight box (px) 30 | """ 31 | _border_width: int 32 | 33 | def __init__( 34 | self, 35 | border_width: int = 1, 36 | margin_x: NumberType = 16, 37 | margin_y: NumberType = 8 38 | ) -> None: 39 | assert isinstance(border_width, int) 40 | assert margin_x >= 0 and margin_y >= 0 41 | assert border_width >= 0 42 | 43 | margin_x = float(margin_x) 44 | margin_y = float(margin_y) 45 | super(HighlightSelection, self).__init__( 46 | margin_left=margin_x / 2, 47 | margin_right=margin_x / 2, 48 | margin_top=margin_y / 2, 49 | margin_bottom=margin_y / 2 50 | ) 51 | 52 | self._border_width = border_width 53 | 54 | # noinspection PyMissingOrEmptyDocstring 55 | def draw(self, surface: 'pygame.Surface', widget: 'pygame_menu.widgets.Widget') -> 'HighlightSelection': 56 | if self._border_width == 0: 57 | return self 58 | pygame.draw.rect( 59 | surface, 60 | self.color, 61 | self.inflate(widget.get_rect()), 62 | self._border_width 63 | ) 64 | return self 65 | -------------------------------------------------------------------------------- /pygame_menu/widgets/selection/left_arrow.py: -------------------------------------------------------------------------------- 1 | """ 2 | pygame-menu 3 | https://github.com/ppizarror/pygame-menu 4 | 5 | LEFT ARROW CLASS 6 | Selector with a left arrow on the item. 7 | """ 8 | 9 | __all__ = ['LeftArrowSelection'] 10 | 11 | import pygame 12 | import pygame_menu 13 | 14 | from pygame_menu.widgets.selection.arrow_selection import ArrowSelection 15 | 16 | from pygame_menu._types import Tuple2IntType, NumberType, NumberInstance 17 | 18 | 19 | class LeftArrowSelection(ArrowSelection): 20 | """ 21 | Widget selection left arrow class. 22 | Creates an arrow to the left of the selected Menu item. 23 | 24 | :param arrow_size: Size of arrow on x-axis and y-axis (width, height) in px 25 | :param arrow_right_margin: Distance from the arrow to the widget (px) 26 | :param arrow_vertical_offset: Vertical offset of the arrow (px) 27 | :param blink_ms: Milliseconds between each blink; if ``0`` blinking is disabled 28 | """ 29 | _arrow_right_margin: int 30 | 31 | def __init__( 32 | self, 33 | arrow_size: Tuple2IntType = (10, 15), 34 | arrow_right_margin: int = 5, 35 | arrow_vertical_offset: int = 0, 36 | blink_ms: NumberType = 0 37 | ) -> None: 38 | assert isinstance(arrow_right_margin, NumberInstance) 39 | assert arrow_right_margin >= 0, 'margin cannot be negative' 40 | 41 | super(LeftArrowSelection, self).__init__( 42 | margin_left=arrow_size[0] + arrow_right_margin, 43 | margin_right=0, 44 | margin_top=0, 45 | margin_bottom=0, 46 | arrow_vertical_offset=arrow_vertical_offset, 47 | blink_ms=blink_ms 48 | ) 49 | 50 | self._arrow_right_margin = arrow_right_margin 51 | 52 | # noinspection PyMissingOrEmptyDocstring 53 | def draw(self, surface: 'pygame.Surface', widget: 'pygame_menu.widgets.Widget') -> 'LeftArrowSelection': 54 | # A 55 | # \B widget 56 | # C / 57 | # <------> 58 | # margin 59 | rect = widget.get_rect() 60 | a = (rect.topleft[0] - self._arrow_size[0] - self._arrow_right_margin, 61 | int(rect.midleft[1] - self._arrow_size[1] / 2 + self._arrow_vertical_offset)) 62 | b = (rect.midleft[0] - self._arrow_right_margin, 63 | rect.midleft[1] + self._arrow_vertical_offset) 64 | c = (rect.bottomleft[0] - self._arrow_size[0] - self._arrow_right_margin, 65 | int(rect.midleft[1] + self._arrow_size[1] / 2 + self._arrow_vertical_offset)) 66 | super(LeftArrowSelection, self)._draw_arrow(surface, widget, a, b, c) 67 | return self 68 | -------------------------------------------------------------------------------- /pygame_menu/widgets/selection/none.py: -------------------------------------------------------------------------------- 1 | """ 2 | pygame-menu 3 | https://github.com/ppizarror/pygame-menu 4 | 5 | NONE 6 | No selection effect. 7 | """ 8 | 9 | __all__ = ['NoneSelection'] 10 | 11 | import pygame 12 | import pygame_menu 13 | 14 | from pygame_menu.widgets.selection.simple import SimpleSelection 15 | 16 | 17 | class NoneSelection(SimpleSelection): 18 | """ 19 | No selection effect. 20 | """ 21 | 22 | def __init__(self) -> None: 23 | super(NoneSelection, self).__init__() 24 | self.widget_apply_font_color = False 25 | 26 | # noinspection PyMissingOrEmptyDocstring 27 | def draw(self, surface: 'pygame.Surface', widget: 'pygame_menu.widgets.Widget') -> 'NoneSelection': 28 | return self 29 | -------------------------------------------------------------------------------- /pygame_menu/widgets/selection/right_arrow.py: -------------------------------------------------------------------------------- 1 | """ 2 | pygame-menu 3 | https://github.com/ppizarror/pygame-menu 4 | 5 | RIGHT ARROW CLASS 6 | Selector with a right arrow on the item. 7 | """ 8 | 9 | __all__ = ['RightArrowSelection'] 10 | 11 | import pygame 12 | import pygame_menu 13 | 14 | from pygame_menu.widgets.selection.arrow_selection import ArrowSelection 15 | 16 | from pygame_menu._types import Tuple2IntType, NumberType, NumberInstance 17 | 18 | 19 | class RightArrowSelection(ArrowSelection): 20 | """ 21 | Widget selection right arrow class. Creates an arrow to the right of the 22 | selected Menu item. 23 | 24 | :param arrow_size: Size of arrow on x-axis and y-axis (width, height) in px 25 | :param arrow_left_margin: Distance from the arrow to the widget (px) 26 | :param arrow_vertical_offset: Vertical offset of the arrow (px) 27 | :param blink_ms: Milliseconds between each blink; if ``0`` blinking is disabled 28 | """ 29 | _arrow_left_margin: int 30 | 31 | def __init__( 32 | self, 33 | arrow_size: Tuple2IntType = (10, 15), 34 | arrow_left_margin: int = 3, 35 | arrow_vertical_offset: int = 0, 36 | blink_ms: NumberType = 0 37 | ) -> None: 38 | assert isinstance(arrow_left_margin, NumberInstance) 39 | assert arrow_left_margin >= 0, 'margin cannot be negative' 40 | 41 | super(RightArrowSelection, self).__init__( 42 | margin_left=0, 43 | margin_right=arrow_size[0] + arrow_left_margin, 44 | margin_top=0, 45 | margin_bottom=0, 46 | arrow_vertical_offset=arrow_vertical_offset, 47 | blink_ms=blink_ms 48 | ) 49 | 50 | self._arrow_left_margin = arrow_left_margin 51 | 52 | # noinspection PyMissingOrEmptyDocstring 53 | def draw(self, surface: 'pygame.Surface', widget: 'pygame_menu.widgets.Widget') -> 'RightArrowSelection': 54 | # /A 55 | # widget B 56 | # \ C 57 | # <------> 58 | # margin 59 | rect = widget.get_rect() 60 | a = (rect.topright[0] + self._arrow_size[0] + self._arrow_left_margin, 61 | int(rect.midright[1] - self._arrow_size[1] / 2 + self._arrow_vertical_offset)) 62 | b = (rect.midright[0] + self._arrow_left_margin, 63 | rect.midright[1] + self._arrow_vertical_offset) 64 | c = (rect.bottomright[0] + self._arrow_size[0] + self._arrow_left_margin, 65 | int(rect.midright[1] + self._arrow_size[1] / 2 + self._arrow_vertical_offset)) 66 | super(RightArrowSelection, self)._draw_arrow(surface, widget, a, b, c) 67 | return self 68 | -------------------------------------------------------------------------------- /pygame_menu/widgets/selection/simple.py: -------------------------------------------------------------------------------- 1 | """ 2 | pygame-menu 3 | https://github.com/ppizarror/pygame-menu 4 | 5 | SIMPLE 6 | Simple selection effect. 7 | """ 8 | 9 | __all__ = ['SimpleSelection'] 10 | 11 | import pygame 12 | import pygame_menu 13 | 14 | from pygame_menu.widgets.core import Selection 15 | 16 | 17 | class SimpleSelection(Selection): 18 | """ 19 | This selection effect only tells widget to apply selection color to font if 20 | selected. 21 | """ 22 | 23 | def __init__(self) -> None: 24 | super(SimpleSelection, self).__init__( 25 | margin_left=0, margin_right=0, margin_top=0, margin_bottom=0 26 | ) 27 | 28 | # noinspection PyMissingOrEmptyDocstring 29 | def draw(self, surface: 'pygame.Surface', widget: 'pygame_menu.widgets.Widget') -> 'SimpleSelection': 30 | return self 31 | -------------------------------------------------------------------------------- /pygame_menu/widgets/widget/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | pygame-menu 3 | https://github.com/ppizarror/pygame-menu 4 | 5 | WIDGET 6 | This module contains the widgets of pygame-menu. 7 | """ 8 | 9 | from pygame_menu.widgets.widget.button import Button 10 | from pygame_menu.widgets.widget.colorinput import ColorInput 11 | from pygame_menu.widgets.widget.dropselect import DropSelect 12 | from pygame_menu.widgets.widget.dropselect_multiple import DropSelectMultiple 13 | from pygame_menu.widgets.widget.frame import Frame 14 | from pygame_menu.widgets.widget.hmargin import HMargin 15 | from pygame_menu.widgets.widget.image import Image 16 | from pygame_menu.widgets.widget.label import Label 17 | from pygame_menu.widgets.widget.menubar import MenuBar 18 | from pygame_menu.widgets.widget.menulink import MenuLink 19 | from pygame_menu.widgets.widget.none import NoneWidget 20 | from pygame_menu.widgets.widget.progressbar import ProgressBar 21 | from pygame_menu.widgets.widget.rangeslider import RangeSlider 22 | from pygame_menu.widgets.widget.scrollbar import ScrollBar 23 | from pygame_menu.widgets.widget.selector import Selector 24 | from pygame_menu.widgets.widget.surface import SurfaceWidget 25 | from pygame_menu.widgets.widget.table import Table 26 | from pygame_menu.widgets.widget.textinput import TextInput 27 | from pygame_menu.widgets.widget.toggleswitch import ToggleSwitch 28 | from pygame_menu.widgets.widget.vfill import VFill 29 | from pygame_menu.widgets.widget.vmargin import VMargin 30 | -------------------------------------------------------------------------------- /pygame_menu/widgets/widget/hmargin.py: -------------------------------------------------------------------------------- 1 | """ 2 | pygame-menu 3 | https://github.com/ppizarror/pygame-menu 4 | 5 | HORIZONTAL MARGIN 6 | Horizontal box margin. 7 | """ 8 | 9 | __all__ = [ 10 | 'HMargin', 11 | 'HMarginManager' 12 | ] 13 | 14 | import pygame 15 | import pygame_menu 16 | 17 | from abc import ABC 18 | from pygame_menu.widgets.core.widget import AbstractWidgetManager 19 | from pygame_menu.widgets.widget.none import NoneWidget 20 | 21 | from pygame_menu._types import NumberType, NumberInstance 22 | 23 | 24 | class HMargin(NoneWidget): 25 | """ 26 | Horizontal margin widget. 27 | 28 | .. note:: 29 | 30 | HMargin does not accept transformations. 31 | 32 | :param margin: Horizontal margin in px 33 | :param widget_id: ID of the widget 34 | """ 35 | 36 | def __init__( 37 | self, 38 | margin: NumberType, 39 | widget_id: str = '' 40 | ) -> None: 41 | assert isinstance(margin, NumberInstance) 42 | assert margin > 0, \ 43 | 'zero margin is not valid, prefer adding a NoneWidget menu.add.none_widget()' 44 | super(HMargin, self).__init__(widget_id=widget_id) 45 | self._rect.width = int(margin) 46 | self._rect.height = 0 47 | 48 | def get_rect(self, *args, **kwargs) -> 'pygame.Rect': 49 | return self._rect.copy() 50 | 51 | 52 | class HMarginManager(AbstractWidgetManager, ABC): 53 | """ 54 | HMargin manager. 55 | """ 56 | 57 | def horizontal_margin( 58 | self, 59 | margin: NumberType, 60 | margin_id: str = '' 61 | ) -> 'pygame_menu.widgets.HMargin': 62 | """ 63 | Adds a horizontal margin to the Menu. Only useful in frames. 64 | 65 | .. note:: 66 | 67 | This is applied only to the base Menu (not the currently displayed, 68 | stored in ``_current`` pointer); for such behaviour apply to 69 | :py:meth:`pygame_menu.menu.Menu.get_current` object. 70 | 71 | :param margin: Horizontal margin in px 72 | :param margin_id: ID of the horizontal margin 73 | :return: Widget object 74 | :rtype: :py:class:`pygame_menu.widgets.HMargin` 75 | """ 76 | attributes = self._filter_widget_attributes({}) 77 | widget = HMargin(margin, widget_id=margin_id) 78 | self._configure_widget(widget=widget, **attributes) 79 | self._append_widget(widget) 80 | 81 | return widget 82 | -------------------------------------------------------------------------------- /pygame_menu/widgets/widget/menulink.py: -------------------------------------------------------------------------------- 1 | """ 2 | pygame-menu 3 | https://github.com/ppizarror/pygame-menu 4 | 5 | MENULINK 6 | Similar to a Button that opens a Menu, MenuLink is a widget that contains a Menu 7 | reference. This Menu can be opened with .open() method. 8 | """ 9 | 10 | __all__ = [ 11 | 'MenuLink', 12 | 'MenuLinkManager' 13 | ] 14 | 15 | import pygame_menu 16 | 17 | from abc import ABC 18 | from pygame_menu.widgets.core.widget import AbstractWidgetManager 19 | from pygame_menu.widgets.widget.none import NoneWidget 20 | 21 | from pygame_menu._types import Callable 22 | 23 | 24 | class MenuLink(NoneWidget): 25 | """ 26 | Menu link widget; adds a link to another Menu. The behaviour is similar to a 27 | button, but this widget is invisible, and cannot be selectable. 28 | 29 | .. note:: 30 | 31 | MenuLink does not accept transformations. 32 | 33 | :param link_id: Link ID 34 | :param menu_opener_handler: Callback for opening the menu object 35 | :param menu: Menu object 36 | """ 37 | menu: 'pygame_menu.Menu' 38 | 39 | def __init__( 40 | self, 41 | menu: 'pygame_menu.Menu', 42 | menu_opener_handler: Callable, 43 | link_id: str = '' 44 | ) -> None: 45 | assert isinstance(menu, pygame_menu.Menu) 46 | assert callable(menu_opener_handler), \ 47 | 'menu opener handler must be callable (a function)' 48 | super(MenuLink, self).__init__( 49 | widget_id=link_id 50 | ) 51 | self.menu = menu 52 | self._onreturn = menu_opener_handler 53 | self._visible = False 54 | self.is_selectable = False 55 | 56 | def hide(self) -> 'MenuLink': 57 | pass 58 | 59 | def show(self) -> 'MenuLink': 60 | pass 61 | 62 | def open(self) -> None: 63 | """ 64 | Open the menu link. 65 | """ 66 | return self._onreturn(self.menu) 67 | 68 | 69 | class MenuLinkManager(AbstractWidgetManager, ABC): 70 | """ 71 | MenuLink manager. 72 | """ 73 | 74 | def menu_link( 75 | self, 76 | menu: 'pygame_menu.Menu', 77 | link_id: str = '' 78 | ) -> 'pygame_menu.widgets.MenuLink': 79 | """ 80 | Adds a link to another Menu. The behaviour is similar to a button, but 81 | this widget is invisible, and cannot be selectable. 82 | 83 | Added menus can be opened using the ``.open()`` method. Opened menus change 84 | the state of the parent Menu (the current pointer). 85 | 86 | .. note:: 87 | 88 | This is applied only to the base Menu (not the currently displayed, 89 | stored in ``_current`` pointer); for such behaviour apply to 90 | :py:meth:`pygame_menu.menu.Menu.get_current` object. 91 | 92 | :param menu: Menu to be added as a link (the new submenu) 93 | :param link_id: ID of the menu link 94 | :return: Menu link widget 95 | :rtype: :py:class:`pygame_menu.widgets.MenuLink` 96 | """ 97 | if isinstance(menu, (pygame_menu.Menu, type(self._menu))): 98 | # Check for recursive 99 | if menu == self._menu or menu.in_submenu(self._menu, recursive=True): 100 | raise ValueError( 101 | f'Menu "{menu.get_title()}" is already on submenu structure,' 102 | f' recursive menus lead to unexpected behaviours. For ' 103 | f'returning to previous menu use pygame_menu.events.BACK ' 104 | f'event defining an optional back_count number of menus to ' 105 | f'return from, default is 1' 106 | ) 107 | 108 | else: 109 | raise ValueError('menu object is not a pygame_menu.Menu class') 110 | 111 | # noinspection PyProtectedMember 112 | widget = MenuLink( 113 | menu=menu, 114 | menu_opener_handler=self._menu._open, 115 | link_id=link_id 116 | ) 117 | self.configure_defaults_widget(widget) 118 | self._append_widget(widget) 119 | self._add_submenu(menu, widget) 120 | 121 | return widget 122 | -------------------------------------------------------------------------------- /pygame_menu/widgets/widget/vfill.py: -------------------------------------------------------------------------------- 1 | """ 2 | pygame-menu 3 | https://github.com/ppizarror/pygame-menu 4 | 5 | VERTICAL VILL 6 | Vertical fill box. Fills all available vertical space. 7 | """ 8 | 9 | __all__ = [ 10 | 'VFill', 11 | 'VFillManager' 12 | ] 13 | 14 | import pygame 15 | import pygame_menu 16 | 17 | from abc import ABC 18 | from pygame_menu.widgets.core.widget import AbstractWidgetManager 19 | from pygame_menu.widgets.widget.none import NoneWidget 20 | 21 | from pygame_menu._types import NumberType, NumberInstance 22 | 23 | 24 | class VFill(NoneWidget): 25 | """ 26 | Vertical fill widget. This widget fills all vertical space if available, else, 27 | it uses the min height. 28 | 29 | .. note:: 30 | 31 | VFill does not accept transformations. 32 | 33 | :param min_height: Minimum height in px 34 | :param widget_id: ID of the widget 35 | """ 36 | _min_height: int 37 | 38 | def __init__( 39 | self, 40 | min_height: NumberType, 41 | widget_id: str = '' 42 | ) -> None: 43 | assert isinstance(min_height, NumberInstance) 44 | assert min_height >= 0, 'negative min height is not valid' 45 | super(VFill, self).__init__(widget_id=widget_id) 46 | self._min_height = min_height 47 | 48 | def get_rect(self, *args, **kwargs) -> 'pygame.Rect': 49 | # Get all menu widgets, and for those in the same column store the total 50 | # size (without considering other vfills). Then, divide all available height 51 | # in the total vfills found 52 | c = self.get_col_row_index()[0] 53 | if c == -1: 54 | self._rect.height = self._min_height 55 | return self._rect 56 | menu_widgets_col = self.get_menu().get_widgets_column(c) 57 | available_height: int = self.get_menu().get_height(inner=True) 58 | total_column_height: int = 0 59 | total_vfills: int = 0 60 | column_vfills = [] 61 | 62 | for w in menu_widgets_col: 63 | if not isinstance(w, VFill): 64 | total_column_height += w.get_height() 65 | else: 66 | column_vfills.append(w) 67 | total_column_height += w._min_height 68 | total_vfills += 1 69 | 70 | vfill_height = ((available_height - total_column_height) / total_vfills) if total_vfills > 0 else 0 71 | 72 | # Discount 1px only to last 73 | if self == column_vfills[-1] and vfill_height > 0: 74 | vfill_height -= 1 75 | 76 | vfill_height = max(0, vfill_height) 77 | self._rect.height = self._min_height + vfill_height 78 | 79 | return self._rect 80 | 81 | 82 | class VFillManager(AbstractWidgetManager, ABC): 83 | """ 84 | VFill manager. 85 | """ 86 | 87 | def vertical_fill( 88 | self, 89 | min_height: NumberType = 0, 90 | vfill_id: str = '' 91 | ) -> 'pygame_menu.widgets.VFill': 92 | """ 93 | Adds a vertical fill to the Menu. This widget fills all vertical space 94 | if available, else, it uses the min height. 95 | 96 | .. note:: 97 | 98 | This is applied only to the base Menu (not the currently displayed, 99 | stored in ``_current`` pointer); for such behaviour apply to 100 | :py:meth:`pygame_menu.menu.Menu.get_current` object. 101 | 102 | :param min_height: Minimum height in px 103 | :param vfill_id: ID of the vertical fill 104 | :return: Widget object 105 | :rtype: :py:class:`pygame_menu.widgets.VFill` 106 | """ 107 | attributes = self._filter_widget_attributes({}) 108 | widget = VFill(min_height, widget_id=vfill_id) 109 | self._configure_widget(widget=widget, **attributes) 110 | self._append_widget(widget) 111 | return widget 112 | -------------------------------------------------------------------------------- /pygame_menu/widgets/widget/vmargin.py: -------------------------------------------------------------------------------- 1 | """ 2 | pygame-menu 3 | https://github.com/ppizarror/pygame-menu 4 | 5 | VERTICAL MARGIN 6 | Vertical box margin. 7 | """ 8 | 9 | __all__ = [ 10 | 'VMargin', 11 | 'VMarginManager' 12 | ] 13 | 14 | import pygame 15 | import pygame_menu 16 | 17 | from abc import ABC 18 | from pygame_menu.widgets.core.widget import AbstractWidgetManager 19 | from pygame_menu.widgets.widget.none import NoneWidget 20 | 21 | from pygame_menu._types import NumberType, NumberInstance 22 | 23 | 24 | class VMargin(NoneWidget): 25 | """ 26 | Vertical margin widget. VMargin only accepts margin, not padding. 27 | 28 | .. note:: 29 | 30 | VMargin does not accept transformations. 31 | 32 | :param margin: Vertical margin in px 33 | :param widget_id: ID of the widget 34 | """ 35 | 36 | def __init__( 37 | self, 38 | margin: NumberType, 39 | widget_id: str = '' 40 | ) -> None: 41 | assert isinstance(margin, NumberInstance) 42 | assert margin > 0, 'negative or zero margin is not valid' 43 | super(VMargin, self).__init__(widget_id=widget_id) 44 | self._rect.width = 0 45 | self._rect.height = int(margin) 46 | 47 | def get_rect(self, *args, **kwargs) -> 'pygame.Rect': 48 | return self._rect.copy() 49 | 50 | 51 | class VMarginManager(AbstractWidgetManager, ABC): 52 | """ 53 | VMargin manager. 54 | """ 55 | 56 | def vertical_margin( 57 | self, 58 | margin: NumberType, 59 | margin_id: str = '' 60 | ) -> 'pygame_menu.widgets.VMargin': 61 | """ 62 | Adds a vertical margin to the Menu. 63 | 64 | .. note:: 65 | 66 | This is applied only to the base Menu (not the currently displayed, 67 | stored in ``_current`` pointer); for such behaviour apply to 68 | :py:meth:`pygame_menu.menu.Menu.get_current` object. 69 | 70 | :param margin: Vertical margin in px 71 | :param margin_id: ID of the vertical margin 72 | :return: Widget object 73 | :rtype: :py:class:`pygame_menu.widgets.VMargin` 74 | """ 75 | attributes = self._filter_widget_attributes({}) 76 | widget = VMargin(margin, widget_id=margin_id) 77 | self._configure_widget(widget=widget, **attributes) 78 | self._append_widget(widget) 79 | return widget 80 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | pygame>=1.9.3 2 | pyperclip 3 | typing_extensions -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | """ 2 | pygame-menu 3 | https://github.com/ppizarror/pygame-menu 4 | 5 | SETUP DISTRIBUTION 6 | Create setup for PyPi. 7 | 8 | License: 9 | ------------------------------------------------------------------------------- 10 | The MIT License (MIT) 11 | Copyright 2017 Pablo Pizarro R. @ppizarror 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a 14 | copy of this software and associated documentation files (the "Software"), 15 | to deal in the Software without restriction, including without limitation 16 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 17 | and/or sell copies of the Software, and to permit persons to whom the Software 18 | is furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 26 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 27 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 28 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 29 | ------------------------------------------------------------------------------- 30 | """ 31 | 32 | from setuptools import setup, find_packages 33 | import pygame_menu 34 | 35 | # Load readme 36 | with open('README.rst') as f: 37 | long_description = f.read() 38 | 39 | # Load requirements 40 | with open('requirements.txt') as f: 41 | requirements = [] 42 | for line in f: 43 | requirements.append(line.strip()) 44 | 45 | # Setup library 46 | setup( 47 | name=pygame_menu.__module_name__, 48 | version=pygame_menu.__version__, 49 | author=pygame_menu.__author__, 50 | author_email=pygame_menu.__email__, 51 | description=pygame_menu.__description__, 52 | long_description=long_description, 53 | url=pygame_menu.__url__, 54 | project_urls={ 55 | 'Bug Tracker': pygame_menu.__url_bug_tracker__, 56 | 'Documentation': pygame_menu.__url_documentation__, 57 | 'Source Code': pygame_menu.__url_source_code__ 58 | }, 59 | license=pygame_menu.__license__, 60 | platforms=['any'], 61 | keywords=pygame_menu.__keywords__, 62 | classifiers=[ 63 | 'License :: OSI Approved :: MIT License', 64 | 'Natural Language :: English', 65 | 'Operating System :: OS Independent', 66 | 'Programming Language :: Python :: 3.8', 67 | 'Programming Language :: Python :: 3.9', 68 | 'Programming Language :: Python :: 3.10', 69 | 'Programming Language :: Python :: 3.11', 70 | 'Programming Language :: Python :: 3.12', 71 | 'Programming Language :: Python :: 3.13', 72 | 'Programming Language :: Python', 73 | 'Topic :: Games/Entertainment', 74 | 'Topic :: Multimedia', 75 | 'Topic :: Software Development :: Libraries :: pygame', 76 | 'Topic :: Text Processing' 77 | ], 78 | include_package_data=True, 79 | packages=find_packages(exclude=['test']), 80 | python_requires='>=3.8, <4', 81 | install_requires=requirements, 82 | extras_require={ 83 | 'docs': ['sphinx<7', 'sphinx-autodoc-typehints>=1.2.0', 'sphinx-rtd-theme'], 84 | 'test': ['nose2[coverage_plugin]', 'pytest'] 85 | }, 86 | setup_requires=[ 87 | 'setuptools', 88 | ], 89 | options={ 90 | 'bdist_wheel': {'universal': False} 91 | }, 92 | entry_points={ 93 | 'pyinstaller40': ['hook-dirs = pygame_menu.__pyinstaller:get_hook_dirs'] 94 | } 95 | ) 96 | -------------------------------------------------------------------------------- /test/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | pygame-menu 3 | https://github.com/ppizarror/pygame-menu 4 | 5 | TEST 6 | This directory contains all project tests files. 7 | """ 8 | -------------------------------------------------------------------------------- /test/test_base.py: -------------------------------------------------------------------------------- 1 | """ 2 | pygame-menu 3 | https://github.com/ppizarror/pygame-menu 4 | 5 | TEST BASE 6 | Test base class. 7 | """ 8 | 9 | __all__ = ['BaseTest'] 10 | 11 | from test._utils import BaseTest as _BaseTest 12 | 13 | # noinspection PyProtectedMember 14 | from pygame_menu._base import Base 15 | 16 | 17 | class BaseTest(_BaseTest): 18 | 19 | def test_counter(self) -> None: 20 | """ 21 | Test counter. 22 | """ 23 | obj = Base('') 24 | self.assertEqual(obj.get_counter_attribute('count', 1), 1) 25 | self.assertEqual(obj.get_counter_attribute('count', 1), 2) 26 | self.assertEqual(obj.get_counter_attribute('count', 1), 3) 27 | self.assertEqual(obj.get_counter_attribute('count', 1), 4) 28 | self.assertEqual(obj.get_counter_attribute('count', 1), 5) 29 | self.assertEqual(obj.get_counter_attribute('count', 1), 6) 30 | 31 | self.assertAlmostEqual(obj.get_counter_attribute('count_epic', 1, '3.14'), 4.14) 32 | self.assertAlmostEqual(obj.get_counter_attribute('count_epic', 1, '3.14'), 5.14) 33 | self.assertAlmostEqual(obj.get_counter_attribute('count_epic', 1, '3.14'), 6.14) 34 | 35 | # Test check instance 36 | self.assertEqual(obj.get_counter_attribute('count1', 1, '1'), 2) 37 | self.assertEqual(obj.get_counter_attribute('count1', 1, '1'), 3) 38 | 39 | # Test check instance 40 | self.assertEqual(obj.get_counter_attribute('count2', 1.0, '1'), 2.0) 41 | self.assertEqual(obj.get_counter_attribute('count2', 1.0, '1'), 3.0) 42 | 43 | def test_classid(self) -> None: 44 | """ 45 | Test class id. 46 | """ 47 | obj = Base('id') 48 | self.assertEqual(obj.get_class_id(), 'Base<"id">') 49 | 50 | def test_attributes(self) -> None: 51 | """ 52 | Test attributes. 53 | """ 54 | obj = Base('') 55 | self.assertFalse(obj.has_attribute('epic')) 56 | self.assertRaises(IndexError, lambda: obj.remove_attribute('epic')) 57 | obj.set_attribute('epic', True) 58 | self.assertTrue(obj.has_attribute('epic')) 59 | self.assertTrue(obj.get_attribute('epic')) 60 | obj.set_attribute('epic', False) 61 | self.assertFalse(obj.get_attribute('epic')) 62 | obj.remove_attribute('epic') 63 | self.assertFalse(obj.has_attribute('epic')) 64 | self.assertEqual(obj.get_attribute('epic', 420), 420) 65 | 66 | def test_repr(self) -> None: 67 | """ 68 | Test base repr. 69 | """ 70 | obj = Base('id') 71 | self.assertNotIn('["id"]', str(obj)) 72 | obj._id__repr__ = True 73 | self.assertIn('["id"]', str(obj)) 74 | obj = Base('id2') 75 | obj._class_id__repr__ = True 76 | self.assertEqual(str(obj), 'Base<"id2">') 77 | -------------------------------------------------------------------------------- /test/test_font.py: -------------------------------------------------------------------------------- 1 | """ 2 | pygame-menu 3 | https://github.com/ppizarror/pygame-menu 4 | 5 | TEST FONT 6 | Test font management. 7 | """ 8 | 9 | __all__ = ['FontTest'] 10 | 11 | from pathlib import Path 12 | from test._utils import MenuUtils, BaseTest 13 | 14 | import pygame 15 | import pygame_menu 16 | 17 | 18 | class FontTest(BaseTest): 19 | 20 | def test_font_load(self) -> None: 21 | """ 22 | Load a font from a file. 23 | """ 24 | font = MenuUtils.get_font(pygame_menu.font.FONT_8BIT, 5) 25 | self.assertIsNotNone(font) 26 | self.assertEqual(font, pygame_menu.font.get_font(font, 5)) 27 | self.assertRaises(ValueError, lambda: MenuUtils.get_font('', 0)) 28 | self.assertRaises(ValueError, lambda: MenuUtils.get_font('sys', 0)) 29 | 30 | def test_pathlib(self) -> None: 31 | """ 32 | Test font load with pathlib. 33 | """ 34 | path_font = Path(pygame_menu.font.FONT_8BIT) 35 | self.assertRaises(ValueError, lambda: pygame_menu.font.get_font(path_font, 0)) 36 | font = pygame_menu.font.get_font(path_font, 10) 37 | assert font is not None 38 | 39 | def test_system_load(self) -> None: 40 | """ 41 | Test fonts from system. 42 | """ 43 | font_sys = MenuUtils.random_system_font() 44 | font = MenuUtils.get_font(font_sys, 5) 45 | self.assertIsNotNone(font) 46 | 47 | # Modify the system font and load, this will raise an exception 48 | self.assertRaises(ValueError, lambda: MenuUtils.get_font('invalid font', 5)) 49 | 50 | def test_font_argument(self) -> None: 51 | """ 52 | Test font pass as argument. 53 | """ 54 | menu = MenuUtils.generic_menu() 55 | f0 = pygame.font.SysFont(pygame.font.get_fonts()[0], 20) 56 | 57 | # Widget with custom font 58 | text = menu.add.text_input('First name: ', default='John', font_name=f0) 59 | self.assertEqual(text.get_font_info()['name'], f0) 60 | 61 | # Test widgets with default font, check are equal 62 | text2 = menu.add.text_input('First name: ', default='John') 63 | self.assertEqual(text2.get_font_info()['name'], menu.get_theme().widget_font) 64 | -------------------------------------------------------------------------------- /test/test_selection.py: -------------------------------------------------------------------------------- 1 | """ 2 | pygame-menu 3 | https://github.com/ppizarror/pygame-menu 4 | 5 | TEST WIDGET SELECTION. 6 | Test widget selection effects. 7 | """ 8 | 9 | __all__ = ['SelectionTest'] 10 | 11 | from test._utils import MenuUtils, surface, BaseTest 12 | import copy 13 | 14 | from pygame_menu.widgets import Button 15 | from pygame_menu.widgets.selection import LeftArrowSelection, RightArrowSelection, \ 16 | HighlightSelection, NoneSelection, SimpleSelection 17 | 18 | from pygame_menu.widgets.core.selection import Selection 19 | from pygame_menu.widgets.selection.arrow_selection import ArrowSelection 20 | 21 | 22 | class SelectionTest(BaseTest): 23 | 24 | def setUp(self) -> None: 25 | """ 26 | Setup sound engine. 27 | """ 28 | self.menu = MenuUtils.generic_menu() 29 | self.menu.enable() 30 | 31 | def test_copy(self) -> None: 32 | """ 33 | Test copy. 34 | """ 35 | s = LeftArrowSelection() 36 | s1 = copy.copy(s) 37 | s2 = copy.deepcopy(s) 38 | s3 = s.copy() 39 | self.assertNotEqual(s, s1) 40 | self.assertNotEqual(s, s2) 41 | self.assertNotEqual(s, s3) 42 | 43 | def test_abstracts(self) -> None: 44 | """ 45 | Test abstract objects errors. 46 | """ 47 | w = Button('epic') 48 | 49 | # Create abstract selection object 50 | sel = Selection(0, 0, 0, 0) 51 | self.assertRaises(NotImplementedError, lambda: sel.draw(surface, w)) 52 | 53 | # Create abstract arrow selection 54 | arrow = ArrowSelection(0, 0, 0, 0) 55 | self.assertRaises(NotImplementedError, lambda: arrow.draw(surface, w)) 56 | 57 | def test_arrow(self) -> None: 58 | """ 59 | Test arrow selection. 60 | """ 61 | w = Button('epic') 62 | w.set_selection_effect(LeftArrowSelection()) 63 | self.menu.add.generic_widget(w) 64 | self.menu.draw(surface) 65 | w.set_selection_effect(RightArrowSelection()) 66 | self.menu.draw(surface) 67 | 68 | # Create abstract arrow selection 69 | arrow = ArrowSelection(0, 0, 0, 0) 70 | self.assertRaises(NotImplementedError, lambda: arrow.draw(surface, w)) 71 | 72 | def test_highlight(self) -> None: 73 | """ 74 | Test highlight selection. 75 | """ 76 | w = Button('epic') 77 | border_width = 1 78 | margin_x = 18 79 | margin_y = 10 80 | w.set_selection_effect(HighlightSelection( 81 | border_width=border_width, 82 | margin_x=margin_x, 83 | margin_y=margin_y 84 | )) 85 | self.menu.add.generic_widget(w) 86 | self.menu.draw(surface) 87 | 88 | # noinspection PyTypeChecker 89 | sel: 'HighlightSelection' = w.get_selection_effect() 90 | self.assertEqual(sel.get_height(), margin_y) 91 | self.assertEqual(sel.get_width(), margin_x) 92 | 93 | # Test inflate 94 | rect = w.get_rect() 95 | inflate_rect = sel.inflate(rect) 96 | self.assertEqual(-inflate_rect.x + rect.x, sel.get_width() / 2) 97 | self.assertEqual(-inflate_rect.y + rect.y, sel.get_height() / 2) 98 | 99 | # Test margin xy 100 | sel.margin_xy(10, 20) 101 | self.assertEqual(sel.margin_left, 10) 102 | self.assertEqual(sel.margin_right, 10) 103 | self.assertEqual(sel.margin_top, 20) 104 | self.assertEqual(sel.margin_bottom, 20) 105 | 106 | # Test null border 107 | sel._border_width = 0 108 | sel.draw(surface, w) 109 | 110 | # Test background color 111 | sel.set_background_color('red') 112 | self.assertEqual(sel.get_background_color(), (255, 0, 0, 255)) 113 | 114 | def test_none(self) -> None: 115 | """ 116 | Test none selection. 117 | """ 118 | w = Button('epic') 119 | w.set_selection_effect(NoneSelection()) 120 | self.menu.add.generic_widget(w) 121 | self.menu.draw(surface) 122 | 123 | rect = w.get_rect() 124 | new_rect = w.get_selection_effect().inflate(rect) 125 | self.assertEqual(rect, new_rect) 126 | self.assertFalse(w.get_selection_effect().widget_apply_font_color) 127 | 128 | # Widgets default selection effect is None 129 | last_selection = w.get_selection_effect() 130 | w.set_selection_effect() 131 | self.assertIsInstance(w.get_selection_effect(), NoneSelection) 132 | self.assertNotEqual(w.get_selection_effect(), last_selection) 133 | 134 | def test_simple(self) -> None: 135 | """ 136 | Test simple selection. 137 | """ 138 | w = Button('epic') 139 | w.set_selection_effect(SimpleSelection()) 140 | self.menu.add.generic_widget(w) 141 | self.menu.draw(surface) 142 | 143 | rect = w.get_rect() 144 | new_rect = w.get_selection_effect().inflate(rect) 145 | self.assertEqual(rect, new_rect) 146 | self.assertTrue(w.get_selection_effect().widget_apply_font_color) 147 | -------------------------------------------------------------------------------- /test/test_sound.py: -------------------------------------------------------------------------------- 1 | """ 2 | pygame-menu 3 | https://github.com/ppizarror/pygame-menu 4 | 5 | TEST SOUND 6 | Test sound management. 7 | """ 8 | 9 | __all__ = ['SoundTest'] 10 | 11 | from test._utils import MenuUtils, BaseTest 12 | import copy 13 | 14 | import pygame_menu 15 | 16 | 17 | class SoundTest(BaseTest): 18 | 19 | def setUp(self) -> None: 20 | """ 21 | Setup sound engine. 22 | """ 23 | self.sound = pygame_menu.sound.Sound(force_init=True) 24 | 25 | def test_copy(self) -> None: 26 | """ 27 | Test sound copy. 28 | """ 29 | sound_src = pygame_menu.sound.Sound() 30 | sound_src.load_example_sounds() 31 | 32 | sound = copy.copy(sound_src) 33 | sound_deep = copy.deepcopy(sound_src) 34 | 35 | # Check if sounds are different 36 | t = pygame_menu.sound.SOUND_TYPE_CLICK_MOUSE 37 | self.assertNotEqual(sound_src._sound[t]['file'], sound._sound[t]['file']) 38 | self.assertNotEqual(sound_src._sound[t]['file'], sound_deep._sound[t]['file']) 39 | 40 | def test_none_channel(self) -> None: 41 | """ 42 | Test none channel. 43 | """ 44 | new_sound = pygame_menu.sound.Sound(uniquechannel=False) 45 | new_sound.load_example_sounds() 46 | new_sound.play_widget_selection() 47 | new_sound._channel = None 48 | new_sound.stop() 49 | new_sound.pause() 50 | new_sound.unpause() 51 | new_sound.play_error() 52 | self.assertEqual(len(new_sound.get_channel_info()), 5) 53 | 54 | def test_channel(self) -> None: 55 | """ 56 | Test channel. 57 | """ 58 | new_sound = pygame_menu.sound.Sound(uniquechannel=False) 59 | new_sound.get_channel() 60 | self.sound.get_channel_info() 61 | self.sound.pause() 62 | self.sound.unpause() 63 | self.sound.stop() 64 | 65 | def test_load_sound(self) -> None: 66 | """ 67 | Test load sounds. 68 | """ 69 | self.assertFalse(self.sound.set_sound(pygame_menu.sound.SOUND_TYPE_CLICK_MOUSE, None)) 70 | self.assertRaises(ValueError, lambda: self.sound.set_sound('none', None)) 71 | self.assertRaises(IOError, lambda: self.sound.set_sound(pygame_menu.sound.SOUND_TYPE_CLICK_MOUSE, 'bad_file')) 72 | self.assertFalse(self.sound._play_sound(None)) 73 | self.assertFalse(self.sound.set_sound(pygame_menu.sound.SOUND_TYPE_ERROR, pygame_menu.font.FONT_PT_SERIF)) 74 | 75 | def test_example_sounds(self) -> None: 76 | """ 77 | Test example sounds. 78 | """ 79 | self.sound.load_example_sounds() 80 | 81 | self.sound.play_click_mouse() 82 | self.sound.play_click_touch() 83 | self.sound.play_close_menu() 84 | self.sound.play_error() 85 | self.sound.play_event() 86 | self.sound.play_event_error() 87 | self.sound.play_key_add() 88 | self.sound.play_key_del() 89 | self.sound.play_open_menu() 90 | 91 | def test_sound_menu(self) -> None: 92 | """ 93 | Test sounds in menu. 94 | """ 95 | menu = MenuUtils.generic_menu() 96 | submenu = MenuUtils.generic_menu() 97 | 98 | menu.add.button('submenu', submenu) 99 | button = menu.add.button('button', lambda: None) 100 | menu.set_sound(self.sound, True) 101 | self.assertEqual(button.get_sound(), self.sound) 102 | 103 | # This will remove the sound engine 104 | menu.set_sound(None, True) 105 | self.assertNotEqual(button.get_sound(), self.sound) 106 | self.assertEqual(menu.get_sound(), menu._sound) 107 | 108 | def test_set_sound_volume(self) -> None: 109 | """ 110 | Test sound volume. 111 | """ 112 | self.sound.load_example_sounds() 113 | self.assertTrue(self.sound.set_sound_volume(pygame_menu.sound.SOUND_TYPE_CLICK_MOUSE, 0.5)) 114 | self.assertEqual(self.sound._sound[pygame_menu.sound.SOUND_TYPE_CLICK_MOUSE]['volume'], 0.5) 115 | self.assertFalse(self.sound.set_sound_volume('bad_sound', 0.5)) 116 | self.assertTrue(self.sound.set_sound_volume(pygame_menu.sound.SOUND_TYPE_CLICK_MOUSE, 1.0)) 117 | self.assertEqual(self.sound._sound[pygame_menu.sound.SOUND_TYPE_CLICK_MOUSE]['volume'], 1.0) 118 | self.assertTrue(self.sound.set_sound_volume(pygame_menu.sound.SOUND_TYPE_CLICK_MOUSE, 0.0)) 119 | self.assertEqual(self.sound._sound[pygame_menu.sound.SOUND_TYPE_CLICK_MOUSE]['volume'], 0.0) 120 | -------------------------------------------------------------------------------- /test/test_utils.py: -------------------------------------------------------------------------------- 1 | """ 2 | pygame-menu 3 | https://github.com/ppizarror/pygame-menu 4 | 5 | TEST UTILS 6 | Library utils. 7 | """ 8 | 9 | __all__ = ['UtilsTest'] 10 | 11 | from test._utils import BaseTest 12 | 13 | from pygame_menu.locals import POSITION_NORTHWEST 14 | 15 | import pygame_menu 16 | import pygame_menu.utils as ut 17 | 18 | 19 | class UtilsTest(BaseTest): 20 | 21 | def test_alpha(self) -> None: 22 | """ 23 | Configure alpha state. 24 | """ 25 | self.assertTrue(ut._ALPHA_CHANNEL[0]) 26 | ut.configure_alpha(False) 27 | self.assertFalse(ut._ALPHA_CHANNEL[0]) 28 | ut.configure_alpha(True) 29 | self.assertTrue(ut._ALPHA_CHANNEL[0]) 30 | 31 | def test_callable(self) -> None: 32 | """ 33 | Test is callable. 34 | """ 35 | self.assertTrue(ut.is_callable(bool)) 36 | self.assertFalse(ut.is_callable(1)) 37 | 38 | def test_position_str(self) -> None: 39 | """ 40 | Test position assert values as str. 41 | """ 42 | self.assertIsNone(ut.assert_position_vector(POSITION_NORTHWEST)) 43 | 44 | def test_padding(self) -> None: 45 | """ 46 | Padding test. 47 | """ 48 | self.assertEqual(ut.parse_padding(1.0), (1, 1, 1, 1)) 49 | self.assertEqual(ut.parse_padding(1.05), (1, 1, 1, 1)) 50 | self.assertEqual(ut.parse_padding([1.0]), (1, 1, 1, 1)) 51 | self.assertEqual(ut.parse_padding((1.0,)), (1, 1, 1, 1)) 52 | 53 | def test_terminal_widget_title(self) -> None: 54 | """ 55 | Test terminal title. 56 | """ 57 | w = pygame_menu.widgets.Button('epic') 58 | w.hide() 59 | s = ut.widget_terminal_title(w) 60 | self.assertIn('╳', s) 61 | 62 | def test_shadows(self) -> None: 63 | """ 64 | Test shadows. 65 | """ 66 | shadow = ut.ShadowGenerator() 67 | s1 = shadow.create_new_rectangle_shadow(100, 100, 15, 25) 68 | s2 = shadow.create_new_ellipse_shadow(100, 100, 10) 69 | shadow.create_new_ellipse_shadow(100, 100, 10) 70 | self.assertIsNone(shadow.create_new_ellipse_shadow(100, 100, 0)) 71 | self.assertEqual(s1.get_size(), (100, 100)) 72 | self.assertEqual(s2.get_size(), (100, 100)) 73 | # Use cache 74 | shadow.create_new_rectangle_shadow(100, 100, 15, 25) 75 | shadow.create_new_rectangle_shadow(100, 150, 15, 25) 76 | # Remove cache 77 | shadow.clear_short_term_caches(force=True) 78 | -------------------------------------------------------------------------------- /test/test_version.py: -------------------------------------------------------------------------------- 1 | """ 2 | pygame-menu 3 | https://github.com/ppizarror/pygame-menu 4 | 5 | TEST VERSION 6 | Test version management. 7 | """ 8 | 9 | __all__ = ['VersionTest'] 10 | 11 | from test._utils import BaseTest 12 | 13 | import pygame_menu 14 | 15 | 16 | class VersionTest(BaseTest): 17 | 18 | def test_version(self) -> None: 19 | """ 20 | Test version. 21 | """ 22 | self.assertTrue(isinstance(pygame_menu.version.ver, str)) 23 | self.assertTrue(isinstance(repr(pygame_menu.version.vernum), str)) 24 | self.assertTrue(isinstance(str(pygame_menu.version.vernum), str)) 25 | -------------------------------------------------------------------------------- /test/test_widget_image.py: -------------------------------------------------------------------------------- 1 | """ 2 | pygame-menu 3 | https://github.com/ppizarror/pygame-menu 4 | 5 | TEST WIDGET - IMAGE 6 | Test Image widget. 7 | """ 8 | 9 | __all__ = ['ImageWidgetTest'] 10 | 11 | from test._utils import MenuUtils, surface, PygameEventUtils, BaseTest 12 | import pygame_menu 13 | 14 | 15 | class ImageWidgetTest(BaseTest): 16 | 17 | def test_image_widget(self) -> None: 18 | """ 19 | Test image widget. 20 | """ 21 | menu = MenuUtils.generic_menu() 22 | image = menu.add.image(pygame_menu.baseimage.IMAGE_EXAMPLE_GRAY_LINES, font_color=(2, 9)) 23 | 24 | image.set_title('epic') 25 | self.assertEqual(image.get_title(), '') 26 | self.assertEqual(image.get_image(), image._image) 27 | image.update(PygameEventUtils.mouse_motion(image)) 28 | 29 | self.assertEqual(image.get_height(apply_selection=True), 264) 30 | self.assertFalse(image._selected) 31 | self.assertEqual(image.get_selected_time(), 0) 32 | 33 | # Test transformations 34 | self.assertEqual(image.get_size(), (272, 264)) 35 | image.scale(2, 2) 36 | self.assertEqual(image.get_size(), (528, 520)) 37 | image.resize(500, 500) 38 | 39 | # Remove padding 40 | image.set_padding(0) 41 | self.assertEqual(image.get_size(), (500, 500)) 42 | 43 | # Set max width 44 | image.set_max_width(400) 45 | self.assertEqual(image.get_size(), (400, 500)) 46 | image.set_max_width(800) 47 | self.assertEqual(image.get_size(), (400, 500)) 48 | image.set_max_width(300, scale_height=True) 49 | self.assertEqual(image.get_size(), (300, 375)) 50 | 51 | # Set max height 52 | image.set_max_height(400) 53 | self.assertEqual(image.get_size(), (300, 375)) 54 | image.set_max_height(300) 55 | self.assertEqual(image.get_size(), (300, 300)) 56 | image.set_max_height(200, scale_width=True) 57 | self.assertEqual(image.get_size(), (200, 200)) 58 | 59 | self.assertEqual(image.get_angle(), 0) 60 | image.rotate(90) 61 | self.assertEqual(image.get_angle(), 90) 62 | image.rotate(60) 63 | self.assertEqual(image.get_angle(), 60) 64 | 65 | # Flip 66 | image.flip(True, True) 67 | self.assertEqual(image._flip, (True, True)) 68 | image.flip(False, False) 69 | self.assertEqual(image._flip, (False, False)) 70 | image.draw(surface) 71 | 72 | def test_value(self) -> None: 73 | """ 74 | Test image value. 75 | """ 76 | menu = MenuUtils.generic_menu() 77 | image = menu.add.image(pygame_menu.baseimage.IMAGE_EXAMPLE_GRAY_LINES) 78 | self.assertRaises(ValueError, lambda: image.get_value()) 79 | self.assertRaises(ValueError, lambda: image.set_value('value')) 80 | self.assertFalse(image.value_changed()) 81 | image.reset_value() 82 | -------------------------------------------------------------------------------- /test/test_widget_progressbar.py: -------------------------------------------------------------------------------- 1 | """ 2 | pygame-menu 3 | https://github.com/ppizarror/pygame-menu 4 | 5 | TEST WIDGET - PROGRESSBAR 6 | Test ProgressBar widget. 7 | """ 8 | 9 | __all__ = ['ProgressBarWidgetTest'] 10 | 11 | from test._utils import MenuUtils, surface, BaseTest, PYGAME_V2 12 | 13 | import pygame_menu 14 | 15 | from pygame_menu.widgets.core.widget import WidgetTransformationNotImplemented 16 | 17 | 18 | class ProgressBarWidgetTest(BaseTest): 19 | 20 | def test_progressbar(self) -> None: 21 | """ 22 | Test progressbar slider. 23 | """ 24 | menu = MenuUtils.generic_menu() 25 | pb = pygame_menu.widgets.ProgressBar('progress', 26 | progress_text_font=pygame_menu.font.FONT_BEBAS) 27 | menu.add.generic_widget(pb, configure_defaults=True) 28 | menu.draw(surface) 29 | 30 | self.assertRaises(AssertionError, lambda: pygame_menu.widgets.ProgressBar( 31 | 'progress', default=-1)) 32 | 33 | self.assertEqual(pb.get_size(), (312, 49)) 34 | self.assertEqual(pb._width, 150) 35 | 36 | # Test invalid transforms 37 | self.assertRaises(WidgetTransformationNotImplemented, lambda: pb.rotate()) 38 | self.assertRaises(WidgetTransformationNotImplemented, lambda: pb.flip()) 39 | self.assertRaises(WidgetTransformationNotImplemented, lambda: pb.scale()) 40 | self.assertRaises(WidgetTransformationNotImplemented, lambda: pb.resize()) 41 | self.assertRaises(WidgetTransformationNotImplemented, lambda: pb.set_max_width()) 42 | self.assertRaises(WidgetTransformationNotImplemented, lambda: pb.set_max_height()) 43 | 44 | self.assertFalse(pb.update([])) 45 | 46 | # noinspection PyTypeChecker 47 | def test_value(self) -> None: 48 | """ 49 | Test progressbar value. 50 | """ 51 | menu = MenuUtils.generic_menu() 52 | pb = menu.add.progress_bar('progress', default=50, progress_text_align=pygame_menu.locals.ALIGN_LEFT) 53 | self.assertRaises(AssertionError, lambda: pb.set_value(-1)) 54 | self.assertRaises(AssertionError, lambda: pb.set_value('a')) 55 | self.assertEqual(pb.get_value(), 50) 56 | self.assertFalse(pb.value_changed()) 57 | pb.set_value(75) 58 | self.assertEqual(pb.get_value(), 75) 59 | self.assertTrue(pb.value_changed()) 60 | pb.reset_value() 61 | self.assertEqual(pb.get_value(), 50) 62 | self.assertFalse(pb.value_changed()) 63 | 64 | def test_empty_title(self) -> None: 65 | """ 66 | Test empty title. 67 | """ 68 | menu = MenuUtils.generic_menu() 69 | pb = menu.add.progress_bar('', box_margin=(0, 0), padding=0, progress_text_align=pygame_menu.locals.ALIGN_RIGHT) 70 | self.assertEqual(pb.get_size(), (150, 41 if PYGAME_V2 else 42)) 71 | self.assertFalse(pb.is_selected()) 72 | -------------------------------------------------------------------------------- /test/test_widget_surface.py: -------------------------------------------------------------------------------- 1 | """ 2 | pygame-menu 3 | https://github.com/ppizarror/pygame-menu 4 | 5 | TEST WIDGET - SURFACE 6 | Test Surface widget. 7 | """ 8 | 9 | __all__ = ['SurfaceWidgetTest'] 10 | 11 | from test._utils import MenuUtils, surface, PygameEventUtils, BaseTest 12 | import pygame 13 | 14 | from pygame_menu.widgets.core.widget import WidgetTransformationNotImplemented 15 | 16 | 17 | class SurfaceWidgetTest(BaseTest): 18 | 19 | def test_surface_widget(self) -> None: 20 | """ 21 | Test surface widget. 22 | """ 23 | menu = MenuUtils.generic_menu() 24 | surf = pygame.Surface((150, 150)) 25 | surf.fill((255, 192, 203)) 26 | surf_widget = menu.add.surface(surf, font_color='red') 27 | 28 | self.assertEqual(surf_widget.get_size(), (166, 158)) 29 | self.assertEqual(surf_widget.get_size(apply_padding=False), (150, 150)) 30 | self.assertEqual(surf_widget.get_surface(), surf) 31 | self.assertEqual(surf_widget._font_color, (70, 70, 70, 255)) # not red 32 | 33 | self.assertRaises(WidgetTransformationNotImplemented, lambda: surf_widget.rotate(10)) 34 | self.assertEqual(surf_widget._angle, 0) 35 | 36 | self.assertRaises(WidgetTransformationNotImplemented, lambda: surf_widget.resize(10, 10)) 37 | self.assertFalse(surf_widget._scale[0]) 38 | self.assertEqual(surf_widget._scale[1], 1) 39 | self.assertEqual(surf_widget._scale[2], 1) 40 | 41 | self.assertRaises(WidgetTransformationNotImplemented, lambda: surf_widget.scale(100, 100)) 42 | self.assertFalse(surf_widget._scale[0]) 43 | self.assertEqual(surf_widget._scale[1], 1) 44 | self.assertEqual(surf_widget._scale[2], 1) 45 | 46 | self.assertRaises(WidgetTransformationNotImplemented, lambda: surf_widget.flip(True, True)) 47 | self.assertFalse(surf_widget._flip[0]) 48 | self.assertFalse(surf_widget._flip[1]) 49 | 50 | self.assertRaises(WidgetTransformationNotImplemented, lambda: surf_widget.set_max_width(100)) 51 | self.assertIsNone(surf_widget._max_width[0]) 52 | 53 | self.assertRaises(WidgetTransformationNotImplemented, lambda: surf_widget.set_max_height(100)) 54 | self.assertIsNone(surf_widget._max_height[0]) 55 | 56 | surf_widget.set_title('epic') 57 | self.assertEqual(surf_widget.get_title(), '') 58 | 59 | new_surface = pygame.Surface((160, 160)) 60 | new_surface.fill((255, 192, 203)) 61 | inner_surface = pygame.Surface((80, 80)) 62 | inner_surface.fill((75, 0, 130)) 63 | new_surface.blit(inner_surface, (40, 40)) 64 | surf_widget.set_surface(new_surface) 65 | self.assertEqual(surf_widget.get_size(apply_padding=False), (160, 160)) 66 | menu.draw(surface) 67 | surf_widget.update(PygameEventUtils.mouse_motion(surf_widget)) 68 | surf_widget.draw(surface) 69 | 70 | def test_value(self) -> None: 71 | """ 72 | Test surface value. 73 | """ 74 | menu = MenuUtils.generic_menu() 75 | surf = menu.add.surface(pygame.Surface((150, 150))) 76 | self.assertRaises(ValueError, lambda: surf.get_value()) 77 | self.assertRaises(ValueError, lambda: surf.set_value('value')) 78 | self.assertFalse(surf.value_changed()) 79 | surf.reset_value() 80 | --------------------------------------------------------------------------------