Skip to content

Latest commit

 

History

History
701 lines (491 loc) · 20.6 KB

add_widgets.rst

File metadata and controls

701 lines (491 loc) · 20.6 KB

Adding widgets

For adding new widgets to the Menu you can create new instances of the respective widget class. Or you can use the :py:class:`pygame_menu._widgetmanager.WidgetManager` class stored in Menu.add property. These methods configure the widget and add to the Menu in a simple way.

Add a button

A button is a text that fire action when the user trigger it. An action is linked to a button by defining the action parameter with one of the three values:

Example:

../_static/widget_button.png

menu = pygame_menu.Menu(...)
about_menu = pygame_menu.Menu(...)

def func(name):
    print('Hello world from', name)  # Name will be 'foo'

menu.add.button('Exec', func, 'foo',                   # Execute a function
                align=pygame_menu.locals.ALIGN_LEFT)
menu.add.button(about_menu.get_title(), about_menu,    # Open a sub-menu
                shadow=True, shadow_color=(0, 0, 100))
menu.add.button('Exit', pygame_menu.events.EXIT,       # Link to exit action
                align=pygame_menu.locals.ALIGN_RIGHT)
.. automethod:: pygame_menu._widgetmanager.WidgetManager.button


Add a choices list (selector)

A selector gives the possibility choose a value in a predefined list. An item of a selector is a tuple: the first element is the text displayed, the others are the arguments passed to the callbacks onchange and onreturn.

Example:

../_static/widget_selector.png

menu = pygame_menu.Menu(...)

def change_background_color(selected_value, color, **kwargs):
    value_tuple, index = selected_value
    print('Change widget color to', value_tuple[0])  # selected_value ('Color', surface, color)
    if color == (-1, -1, -1):  # Generate a random color
        color = (randrange(0, 255), randrange(0, 255), randrange(0, 255))
    widget: 'pygame_menu.widgets.Selector' = kwargs.get('widget')
    widget.update_font({'selected_color': color})
    widget.get_selection_effect().color = color

items = [('Default', (255, 255, 255)),
         ('Black', (0, 0, 0)),
         ('Blue', (0, 0, 255)),
         ('Random', (-1, -1, -1))]
selector = menu.add.selector(
    title='Current color:\t',
    items=items,
    onreturn=change_background_color,  # User press "Return" button
    onchange=change_background_color  # User changes value with left/right keys
)
selector.add_self_to_kwargs()  # Callbacks will receive widget as parameter
selector2 = menu.add.selector(
    title='New color:',
    items=items,
    style=pygame_menu.widgets.SELECTOR_STYLE_FANCY
)
.. automethod:: pygame_menu._widgetmanager.WidgetManager.selector


Add a clock

A clock is a simple label object which updates the title text with a generator that retrieves the clock/date string from time.strftime.

Example:

../_static/widget_clock.png

menu = pygame_menu.Menu(...)

clock = menu.add.clock(font_size=25, font_name=pygame_menu.font.FONT_DIGITAL)
.. automethod:: pygame_menu._widgetmanager.WidgetManager.clock


Add a color entry

A color input is similar as a text input but with a limited choice of characters to enter a RGB value of HEX decimal one. There is also a area to show the current color. By default the RGB integers separator is a comma (,).

Example:

../_static/widget_colorinput.png

menu = pygame_menu.Menu(...)

def check_color(value):
    print('New color:', value)

menu.add.color_input('RGB color 1: ',
                     color_type=pygame_menu.widgets.COLORINPUT_TYPE_RGB,
                     default=(255, 0, 255), font_size=18)
menu.add.color_input('RGB color 2: ',
                     color_type=pygame_menu.widgets.COLORINPUT_TYPE_RGB,
                     input_separator='-', font_size=18)
menu.add.color_input('HEX color 3: ',
                     color_type=pygame_menu.widgets.COLORINPUT_TYPE_HEX,
                     default='#ffaa11', font_size=18)
.. automethod:: pygame_menu._widgetmanager.WidgetManager.color_input


Add a drop selection

A drop selector gives the possibility choose a value in a predefined list. An item of a drop selector is a tuple: the first element is the text displayed, the others are the arguments passed to the callbacks onchange and onreturn.

Example:

../_static/widget_dropselect.png

menu = pygame_menu.Menu(...)

selector_epic = menu.add.dropselect(
    title='Is pygame-menu epic?',
    items=[('Yes', 0),
           ('Absolutely Yes', 1)],
    font_size=16,
    selection_option_font_size=20
)
selector_sum = menu.add.dropselect(
    title='What is the value of π?',
    items=[('3 (Engineer)', 0),
           ('3.1415926535897932384626433832795028841971693993751058209', 1),
           ('4', 2),
           ('I don\'t know what is π', 3)],
    font_size=16,
    selection_box_width=173,
    selection_option_padding=(0, 5),
    selection_option_font_size=20
)
selector_country = menu.add.dropselect(
    title='Pick a country',
    items=[('Argentina', 'ar'),
           ('Australia', 'au'),
           ('Bolivia', 'bo'),
           ('Chile', 'ch'),
           ('China', 'cn'),
           ('Finland', 'fi'),
           ('France', 'fr'),
           ('Germany', 'de'),
           ('Italy', 'it'),
           ('Japan', 'jp'),
           ('Mexico', 'mx'),
           ('Peru', 'pe'),
           ('United States', 'us')],
    font_size=20,
    default=3,
    open_middle=True,  # Opens in the middle of the menu
    selection_box_height=5,
    selection_box_width=212,
    selection_infinite=True,
    selection_option_font_size=20
)
.. automethod:: pygame_menu._widgetmanager.WidgetManager.dropselect


Add a drop selection multiple

A multiple drop selector gives the possibility choose a value in a predefined list. An item of a drop selector is a tuple: the first element is the text displayed, the others are the arguments passed to the callbacks onchange and onreturn.

Example:

../_static/widget_dropselect_multiple.png

menu = pygame_menu.Menu(...)

selector = menu.add.dropselect_multiple(
    title='Pick 3 colors',
    items=[('Black', (0, 0, 0)),
           ('Blue', (0, 0, 255)),
           ('Cyan', (0, 255, 255)),
           ('Fuchsia', (255, 0, 255)),
           ('Green', (0, 255, 0)),
           ('Red', (255, 0, 0)),
           ('White', (255, 255, 255)),
           ('Yellow', (255, 255, 0))],
    font_size=23,
    max_selected=3,
    selection_option_font_size=23
)
.. automethod:: pygame_menu._widgetmanager.WidgetManager.dropselect_multiple


Add a frame

Frame is a widget container, it can pack many widgets both horizontally or vertically. All widgets within a same Frame count as one widget position, so using Frames is useful when designing column/row layout. Frames can contain widgets or even more frames.

There is two types of frames, horizontal (h) and vertical (v) ones. These change the way the widgets are added to the frame (packed).

Example:

../_static/widget_frame.png

menu = pygame_menu.Menu(...)

frame = menu.add.frame_v(250, 150, background_color=(50, 50, 50), padding=0)
frame_title = menu.add.frame_h(250, 29, background_color=(180, 180, 180), padding=0)
frame_content = menu.add.frame_v(250, 120, padding=0)
frame.pack(frame_title)
frame.pack(frame_content)

frame_title.pack(menu.add.label('Settings', padding=0), margin=(2, 2))
frame_title.pack(
    menu.add.button('Close', pygame_menu.events.EXIT, padding=(0, 5),
                    background_color=(100, 100, 100)),
    align=pygame_menu.locals.ALIGN_RIGHT, margin=(2, 2))
frame_content.pack(
    menu.add.label('Pick a number', font_color=(150, 150, 150)),
    align=pygame_menu.locals.ALIGN_CENTER)
frame_numbers = menu.add.frame_h(250, 41, padding=0)
frame_content.pack(frame_numbers)
for i in range(9):
    frame_numbers.pack(
        menu.add.button(i, font_color=(5 * i, 11 * i, 13 * i),
                        padding=(0, 5), font_size=30),
        align=pygame_menu.locals.ALIGN_CENTER)
frame_content.pack(menu.add.vertical_margin(15))
frame_content.pack(
    menu.add.toggle_switch('Nice toggle', False, width=100,
                           font_color=(150, 150, 150), padding=0),
    align=pygame_menu.locals.ALIGN_CENTER)

Example:

../_static/widget_frame_title.png

menu = pygame_menu.Menu(...)

frame = menu.add.frame_v(400, 800, background_color=(50, 50, 50), padding=0,
                         max_width=300, max_height=100)
frame.set_title('My Frame App', title_font_color='white', padding_inner=(2, 5))

frame.pack(menu.add.dropselect(
    title='Is pygame-menu epic?',
    items=[('Yes', 0),
           ('Absolutely Yes', 1)],
    font_color='white',
    font_size=16,
    selection_option_font_size=20
))
for i in range(20):
    frame.pack(menu.add.button(i, font_color='white', button_id=f'b{i}'))
.. automethod:: pygame_menu._widgetmanager.WidgetManager.frame_h

.. automethod:: pygame_menu._widgetmanager.WidgetManager.frame_v


Add a generic widget

A user-created widget can also be added to the menu. The widget must be fully configured before the addition.

Example:

def check_color(value):
    print('New color:', value)

menu = pygame_menu.Menu(...)

widget_label = pygame_menu.widgets.Label(...)
widget_image = pygame_menu.widgets.Image(...)

# This applies menu default widget configuration
menu.add.generic_widget(widget_label, configure_defaults=True)

# Adds menu without default configuration
menu.add.generic_widget(widget_image)
.. automethod:: pygame_menu._widgetmanager.WidgetManager.generic_widget


Add a label

A label is used to display a text. If the text is too large, it can be wrapped in order to fit the menu size.

Example:

../_static/widget_label.png

menu = pygame_menu.Menu(...)

HELP = 'Press ESC to enable/disable Menu ' \
       'Press ENTER to access a Sub-Menu or use an option ' \
       'Press UP/DOWN to move through Menu ' \
       'Press LEFT/RIGHT to move through Selectors.'
menu.add.label(HELP, max_char=-1, font_size=20)
.. automethod:: pygame_menu._widgetmanager.WidgetManager.label


Add a menu link

Menu links are widgets that opens a new Menu within the parent Menu without using a button. Links can be opened using the open method.

Example:

../_static/widget_menulink.png

menu = pygame_menu.Menu(...)
menu1 = pygame_menu.Menu(...)
menu2 = pygame_menu.Menu(...)
menu3 = pygame_menu.Menu(...)

def open_link(*args) -> None:
    link: 'pygame_menu.widgets.MenuLink' = args[-1]
    link.open()

# Create the links
link1 = menu.add.menu_link(menu1)
link2 = menu.add.menu_link(menu2)
link3 = menu.add.menu_link(menu3)

# Add a selection object, which opens the links
sel = menu.add.selector('Change menu ', [
    ('Menu 1', link1),
    ('Menu 2', link2),
    ('Menu 3', link3)
], onreturn=open_link)
.. automethod:: pygame_menu._widgetmanager.WidgetManager.menu_link


Add a none widget

A none widget is used to fill column/row layout, store information or even add drawing callbacks for being executed on each menu draw.

menu = pygame_menu.Menu(...)

menu.add.none_widget()
.. automethod:: pygame_menu._widgetmanager.WidgetManager.none_widget


Add a progress bar

A progress bar widget, which accepts a percentage from 0 to 100.

Example:

../_static/widget_progressbar.png

menu = pygame_menu.Menu(...)

progress1 = menu.add.progress_bar('My Progress', default=75.6)
progress2 = menu.add.progress_bar('Pygame-menu epicness?', default=99.9)
.. automethod:: pygame_menu._widgetmanager.WidgetManager.progress_bar


Add a range slider

A range slider offers 1 or 2 sliders for defining a unique value or a range of numeric ones; values can be continuous or discrete.

Example:

../_static/widget_rangeslider.png

menu = pygame_menu.Menu(...)

# Single value
menu.add.range_slider('Choose a number', 50, (0, 100), 1,
                      rangeslider_id='range_slider',
                      value_format=lambda x: str(int(x)))

# Range
menu.add.range_slider('Pick a range', (7, 10), (1, 10), 1)

# Discrete value
range_values_discrete = {0: 'A', 1: 'B', 2: 'C', 3: 'D', 4: 'E', 5: 'F'}
menu.add.range_slider('Pick a letter', 0, list(range_values_discrete.keys()),
                      slider_text_value_enabled=False,
                      value_format=lambda x: range_values_discrete[x])

# Numeric discrete range
menu.add.range_slider('Pick a discrete range', (2, 4), [0, 1, 2, 3, 4, 5], 1)
.. automethod:: pygame_menu._widgetmanager.WidgetManager.range_slider


Add a surface

A surface widget only accepts an external surface which is drawn on the Menu. The widget size is the same as the surface, considering also the margin and the padding.

Example:

../_static/widget_surface.png

menu = pygame_menu.Menu(...)

new_surface = pygame.Surface((160, 160))
new_surface.fill((255, 192, 203))
inner_surface = pygame.Surface((80, 80))
inner_surface.fill((75, 0, 130))
new_surface.blit(inner_surface, (40, 40))
menu.add.surface(new_surface)
.. automethod:: pygame_menu._widgetmanager.WidgetManager.surface


Add a table

A table is a frame which packs widgets in a structured way. Tables can contain a text, numbers, or even more widgets (Frames, Tables, Images, etc). All widgets are read-only, them do not accept any event, only scrollable frames work.

Example:

../_static/widget_table.png

menu = pygame_menu.Menu(...)

table = menu.add.table(table_id='my_table', font_size=20)
table.default_cell_padding = 5
table.default_row_background_color = 'white'
table.add_row(['First item', 'Second item', 'Third item'],
              cell_font=pygame_menu.font.FONT_OPEN_SANS_BOLD)
table.add_row(['A', 'B', 1])
table.add_row(['α', 'β', 'γ'], cell_align=pygame_menu.locals.ALIGN_CENTER)

The following example show an advanced example, featuring tables within a table, and a widget (Image):

../_static/widget_table_advanced.png

menu = pygame_menu.Menu(...)

table = menu.add.table(font_size=20)
table.default_cell_padding = 5
table.default_cell_align = pygame_menu.locals.ALIGN_CENTER
table.default_row_background_color = 'white'
table.add_row(['A', 'B', 'C'],
              cell_font=pygame_menu.font.FONT_OPEN_SANS_BOLD)

# Sub-table
table_2 = menu.add.table(font_size=20)
table_2.default_cell_padding = 20
table_2.add_row([1, 2])
table_2.add_row([3, 4])

# Sub image
image = menu.add.image(pygame_menu.baseimage.IMAGE_EXAMPLE_PYGAME_MENU)
image.scale(0.25, 0.25)

# Add the sub-table and the image
table.add_row([table_2, '', image],
              cell_vertical_position=pygame_menu.locals.POSITION_CENTER)
table.update_cell_style(1, 2, padding=0)  # Disable padding for cell column 1, row 2 (table_2)
table.update_cell_style(2, 2, border_position=pygame_menu.locals.POSITION_SOUTH)
table.update_cell_style(3, 2, border_position=(pygame_menu.locals.POSITION_SOUTH,
                                               pygame_menu.locals.POSITION_EAST))
.. automethod:: pygame_menu._widgetmanager.WidgetManager.table


Add a text entry

A text input permits to enter a string using a keyboard. Restriction on entered characters can be set using input_type, maxchar, maxwidth and valid_chars parameters.

Example:

../_static/widget_textinput.png

menu = pygame_menu.Menu(...)

def check_name(value):
    print('User name:', value)

menu.add.text_input('First name: ', default='John', onreturn=check_name)
menu.add.text_input('Last name: ', default='Doe', maxchar=10, input_underline='_')
menu.add.text_input('Password: ', input_type=pygame_menu.locals.INPUT_INT, password=True)
.. automethod:: pygame_menu._widgetmanager.WidgetManager.text_input


Add a toggle switch

A fully customizable switch between two states (On, Off). If you need more options, take a look at the ToggleSwitch widget class.

Example:

../_static/widget_toggleswitch.png

menu = pygame_menu.Menu(...)

menu.add.toggle_switch('First Switch', False, toggleswitch_id='first_switch')
menu.add.toggle_switch('Other Switch', True, toggleswitch_id='second_switch',
                       state_text=('Apagado', 'Encencido'), state_text_font_size=18)
.. automethod:: pygame_menu._widgetmanager.WidgetManager.toggle_switch


Add a vertical spacer

A vertical spacer can be added between two widgets to have a better visual rendering of the menu.

Example:

../_static/widget_vmargin.png

menu = pygame_menu.Menu(...)

menu.add.label('Text #1')
menu.add.vertical_margin(100)
menu.add.label('Text #2')
.. automethod:: pygame_menu._widgetmanager.WidgetManager.vertical_margin


Add a url link

Adds a clickable url link.

Example:

../_static/widget_url.png

menu = pygame_menu.Menu(...)

menu.add.url('https://github.com/ppizarror/pygame-menu')
menu.add.url('https://github.com/ppizarror/pygame-menu', 'The best menu ever')
menu.add.url('https://pygame-menu.readthedocs.io/en/master/', 'pygame-menu documentation')
.. automethod:: pygame_menu._widgetmanager.WidgetManager.url


Add an image

An image can be displayed on a menu. The scale parameter represent the scaling ratio of the image width and height. When scale_smooth=True, the rendering is better but it requires more CPU resources.

Example:

../_static/widget_image.png

menu = pygame_menu.Menu(...)

image_path = pygame_menu.baseimage.IMAGE_EXAMPLE_PYGAME_MENU
menu.add.image(image_path, angle=10, scale=(0.15, 0.15))
menu.add.image(image_path, angle=-10, scale=(0.15, 0.15))
.. automethod:: pygame_menu._widgetmanager.WidgetManager.image