documentation index ◦ reference manual ◦ function index

# UI Functions

While the say and menu statements are often enough for many games, there are times when more complex user interfaces are desired. For example, dating sim games can require more complex scheduling screens. These screens can be built using the UI functions.

Most of the UI functions create widgets and add them to the screen. The UI functions manage the complexity of nesting widgets. The screen can then be shown to the user with ui.interact, and a value returned and used by the game script.

To start, let's give a script snippet that uses the UI functions. The following displays a window containing three buttons, arraigned horizontally. The string assigned to `choice` varies depending on which of the three is picked.

    $ ui.window()
    $ ui.hbox()

    $ ui.textbutton("A", clicked=ui.returns("A"))
    $ ui.textbutton("B", clicked=ui.returns("B"))
    $ ui.textbutton("C", clicked=ui.returns("C"))

    $ ui.close()
    $ choice = ui.interact(suppress_overlay=True)

There are three kinds of widgets that can be created by the UI functions.

- The first kind of widget (of which ui.window is one), takes a single child widget. When this kind of widget is open, the next widget to be created is added to it, and it then closes automatically.

- The second kind of widget can take an arbitrary number of child widgets. This kind of widget is exemplified by the layout widgets: vbox, hbox, and fixed. New widgets are added to this kind of widget until a matching call to ui.close occurs, unless they are instead added to an open child of this widget.

- The third kind of widget cannot take any children. This kind of widget is exemplified by ui.textbutton.

There is also a set of functions that are used to manage the interaction, and a set of functions that can be used to perform various actions when buttons are clicked.

## Single-Child Widgets

Function: | ui.button | (clicked=None, **properties):

This creates a button that can be clicked by the user. When this button is clicked or otherwise selected, the function supplied as the clicked argument is called. If it returns a value, that value is returned from ui.interact.

Buttons created with this function contain another widget, specifically the next widget to be added. As a convenience, one can use ui.textbutton to create a button with a text label. See also ui.imagebutton, which creates a button in the form of an image.

clicked - A function that is called with no arguments when this button is clicked. If it returns a non-None value, then that value is returned from ui.interact. If clicked itself is None, the button is displayed in the "insensitive" (disabled) style.

hovered - A function that is called with no arguments when this button is focused. If it returns a non-None value, then that value is returned from ui.interact.

unhovered - A function that is called with no arguments when the button loses focus. It's also called at least once per interaction, when a button is not focused at the start of the interaction. The return value is currently ignored, but should be None.

role - The role this button undertakes. This can be the empty string, or "selected_".

Note that code in the clicked, hovered, and unhovered methods is run inside the current interaction. This means that the screen is not cleared while this code is run. Displayables may be added or removed from the current interaction, provided renpy.restart_interaction is called to let Ren'Py know that the interaction has been changed. You should not run code that causes a new interaction from inside these functions, except inside a new context using renpy.call_in_new_context, renpy.invoke_in_new_context, or ui.callsinnewcontext.

Function: | ui.frame | (**properties):

A frame contains a single widget. This is similar to a window, but may be styled differently.

Function: | ui.sizer | (maxwidth=None, maxheight=None, **properties):

This is a widget that can shrink the size allocated to the next widget added. If maxwidth or maxheight is not None, then the space allocated to the child in the appropriate direction is limited to the given amount.

Please note that this only works with child widgets that can have a limited area allocated to them (like text), and not with ones that use a fixed area (like images).

maxwidth - The maximum width of the child widget, or None to not affect width.

maxheight - The maximum height of the child widget, or None ot not affect height.

Function: | ui.window | (**properties):

A window contains a single widget. It draws that window atop a background and with appropriate amounts of margin and padding, taken from the window properties supplied to this call. The next widget created is added to this window.

Function: | ui.viewport | (child_size=(None, None), xadjustment=None, yadjustment=None, set_adjustments=True, mousewheel=False, draggable=False, style='viewport', **properties):

Displays a viewport on the screen. A viewport restricts the size of its child, and allows the child to be displayed at an offset.

child_size - The x and y size of the area the child is asked to render. If either is None, defaults to the size of this viewport.

xadjustment - A ui.adjustment that's used for the x-axis of the viewpoert.

yadjustment - A ui.adjustment that's used for the y-axis of the viewport.

set_adjustments - If true, the range and page size of the adjustments will be set by this viewport.

mousewheel - If true, the mouse wheel can be used to scroll the viewport.

draggable - If true, the mouse can be used to drag around the viewport.

If xadjustment or yadjustment are None, adjustments are created automatically. These adjustments are available through the xadjustment and yadjustment properies of a viewport.

In general, viewports are only useful when the xmaximum and ymaximum properties are specified. You'll also want to set clipping=True on the style, although this is part of the default viewport style.

## Multiple-Child Widgets

Function: | ui.fixed | (**properties):

This creates a layout that places widgets at fixed locations relative to the origin of the enclosing widget. The layout takes up the entire area allocated to it. New widgets are added to this widget until the next call to ui.close.

Function: | ui.grid | (cols, rows, padding=0, transpose=False, **properties):

This creates a layout that places widgets in an evenly spaced grid. New widgets are added to this grid until ui.close is called. Widgets are added by going from left to right within a single row, and down to the start of the next row when a row is full. All cells must be filled (that is, exactly col * rows widgets must be added to the grid.)

The children of this widget should have a fixed size that does not vary based on the space allocated to them. Failure to observe this restriction could lead to really odd layouts, or things being rendered off screen. This condition is relaxed in the appropriate dimension if xfill or yfill is set.

Each cell of the grid is exactly the same size. By default, the grid is the smallest size that can accommodate all of its children, but it can be expanded to consume all available space in a given dimension by setting xfill or yfill to True, as appropriate. (Otherwise, xfill and yfill are inherited from the style.)

cols - The number of columns in this grid.

rows - The number of rows in this grid.

padding - The amount of space to leave between rows and columns.

xfill - True if the grid should consume all available width.

yfill - True if the grid should consume all available height.

transpose - If True, grid will fill down columns before filling across rows.

Function: | ui.hbox | (spacing=None, style='hbox', **properties):

This creates a layout that places widgets next to each other, from left to right. New widgets are added to this hbox until ui.close is called.

spacing - The number of pixels to leave between widgets. If None, take the amount of spacing from the style.

Function: | ui.vbox | (spacing=None, style='vbox', **properties):

This creates a layout that places widgets next to each other, from top to bottom. New widgets are added to this vbox until ui.close is called.

spacing - The number of pixels to leave between widgets. If None, take the amount of spacing from the style.

Function: | ui.side | (places, style='default', **properties):

This positions child widgets so that they surround a parent widget. It takes a single argument, places, which controls where each child widget is placed. Places is expected to be iterable, and each element should be in the list:

'c', 't', 'b', 'l', 'r', 'tl', 'tr', 'bl', 'br'

'c' means center, 't' top, 'tl' top left, 'br' bottom right, and so on. A side should be given the same number of children as the number of entries in the places list.

The top and bottom children are rendered with a 0 requested height, while the left and right children are rendered with a 0 requested width. It is therefore suggested that you enforce a minimum width on the children that are placed in these slots.

The center widget is rendered before the others. Other than that, the order widgets are rendered in is undefined.

## No-Child Widgets

Function: | ui.bar | (range=None, value=None, changed=None, step=None, page=None, adjustment=None, style='bar', **properties):

This creates a bar widget. The bar widget can be used to display data in a bar graph format, and optionally to report when the user clicks on a location in that bar.

adjustment - This should always be given as a keyword argument. If not none, it should be a ui.adjustment that is to used by this bar, and the following arguments are ignored. If None, a new ui.adjustment is created from the range, value, changed, step, and page arguments.

style - The style of this bar. As of 6.2.0, there are four styles that you can use:

- bar - A horizontal bar, with the largest value to the right.
- scrollbar - A horizontal scrollbar, with the largest value to the right.
- vbar - A vertical bar, with the largest value to the top.
- vscrollbar - A vertical scrollbar, with the largest value to the bottom.

The width and height should be set with the xmaximum and ymaximum properties. For best results, if clicked is set then width should be at least twice as big as range.

Function: | ui.image | (im, **properties):

This loads an image, and displays it as a widget. The image may be the name of a file containing the image, or an arbitrary displayable.

Function: | ui.imagebutton | (idle_image, hover_image, clicked=None, image_style='image_button_image', **properties):

This creates a button that contains two images. The first is the idle image, which is used when the mouse is not over the image, while the second is the hover image, which is used when the mouse is over the image. If the button is clicked or otherwise selected, then the clicked argument is called. If it returns a value, that value is returned from ui.interact.

idle_image - The file name of the image used when this button is idle (doesn't have the mouse pointer over it, or focus from keyboard or joystick). Must be specified.

hover_image - The file name of the image used when this button is hovered (the mouse pointer is over it, or the user has focused it with keyboard or joystick). Must be specified.

clicked - The function that is called when this button is clicked.

hovered - A function that is called with no arguments when this button is clicked. If it returns a non-None value, then that value is returned from ui.interact.

unhovered - A function that is called with no arguments when this button loses focus.

image_style - The style that is applied to the images that are used as part of the imagebutton.

role - The role this button undertakes. This can be the empty string, or "selected_".

insensitive_image - If specified, the file name of the image used when this button is disabled (clicked is None).

activate_image - If specified, the file name of the image used when this button is activated (the mouse button is being held down over it, or equivalents for keyboard and joystick).

selected_idle_image, selected_hover_image, selected_insensitive_image and selected_activate_image also exist. They are the equivalents of idle_image, hover_image, insensitive_image and activate_image which are used when this button is selected (represents the current state, like the "Save Game" button on the save game screen).

Function: | ui.imagemap | (ground, selected, hotspots, unselected=None, style='imagemap', button_style='imagemap_button', **properties):

This is called to create imagemaps. Parameters are roughly the same as renpy.imagemap. The value of the hotspot is returned when ui.interact returns.

Function: | ui.keymap | (**keymap):

This is a psuedo-widget that adds a keymap to the screen. This function takes as keyword arguments the names of bindings or keysyms. These keywords should be given as their arguments a function, which is called with zero arguments when an appropriate keysym is pressed.

Function: | ui.menu | (menuitems, style='menu', caption_style='menu_caption', choice_style='menu_choice', choice_chosen_style='menu_choice_chosen', choice_button_style='menu_choice_button', choice_chosen_button_style='menu_choice_chosen_button', location=None, focus=None, default=False, **properties):

This creates a new menu widget. Unlike the `menu` statement or renpy.menu function, this menu widget is not enclosed in any sort of window. You'd have to do that yourself, if it is desired.

menuitems - A list of tuples that are the items to be added to this menu. The first element of a tuple is a string that is used for this menuitem. The second element is the value to be returned from ui.interact if this item is selected, or None if this item is a non-selectable caption.

location - Some serializable and hashable object that represents the location of this menu in the game. (Normally, this is the name of the statement executing the menu.) If provided, then this logs which menuitems have been chosen, and changes the style of those menuitems to the choice_seen_style.

Function: | ui.null | (width=0, height=0, **properties):

This widget displays nothing on the screen. Why would one want to do this? If a widget requires contents, but you don't have any contents to provide it. It can also be used to create empty space, by giving non-zero width and heigh arguments.

Function: | ui.pausebehavior | (delay, result=False):

This is a pseudo-widget that adds the pause behavior to the screen. The pause behavior is to return the supplied result when the given number of seconds elapses. This widget should not be added to any other widget, but should instead be only added to the screen itself.

Please note that this widget will always pause for the given amount of time. If you want a pause that can be interrupted by the user, add in a saybehavior.

delay - The amount of time to pause, in seconds.

result - The result that will be retuned after the delay time elapses.

Function: | ui.saybehavior | (afm=None, dismiss=[ 'dismiss' ], allow_dismiss=None):

This is a pseudo-widget that adds the say behavior to the screen. The say behavior is to return True if the left mouse is clicked or enter is pressed. It also returns True in various other cases, such as if the current statement has already been seen. This widget should not be added to any other widget, but should instead be only added to the screen itself.

If afm is present, it is a block of text, that's given to the auto forwarding mode algorithm to determine the auto-forwarding timeout.

If dismiss is present, it is a list of names of keybindings that are used to dismiss this saybehavior.

If allow_dismiss is present, it should be a function. This function is called without any arguments each time the user initiates a dismiss request. If the function returns True, the dismiss request is allowed, otherwise it is ignored. Added in 5.6.6.

There should only be one saybehavior shown at a time, otherwise they will fight for focus.

## Changes

The dismiss parameter was changed in 5.6.1 from a single keybinding to a list of keybindings.

Function: | ui.text | (label, **properties):

This creates a widget displaying a text label.

label - The text that will be displayed on the screen. It uses font properties. The label can also be a list containing both text strings in widgets, in the case of a widget, the widget is displayed as if it was text of the enclosing font. The height of the area allocated is that of the font, with the width being taked from a render of the widget.

slow - If True, the text will be typed at the screen at a rate determined by the slow_cps property, if set, or the "Text Speed" preference. If None (the default), then it will be typed at a speed determined by the slow_cps property. If False, then it will appear instantly.

slow_speed - If slow is True, then this is the number of cps the text is displayed at, overriding the preference.

slow_done - If not None and slow is True, this is a callback that is called when we're done displaying text on the screen.

Function: | ui.timer | (seconds, function, repeat=False, args=(), kwargs={):

}

This sets up a timer that will call function after seconds seconds have elapsed. If repeat is true, then the function is called every seconds seconds thereafter.

args and kwargs are the positional and keyword arguments supplied to the function, respectively.

## Management Functions

Function: | ui.add | (w, make_current=False, once=False):

This is used to add a displayable to the current widget. If make_current is True, then the widget is made the current widget. If once is True, then the displayable will be made the current widget, but only for the next widget to be added.

Function: | ui.at | (position):

The ui.at function takes a position or motion, and applies it to the next widget created using a ui function.

Function: | ui.clear | ():

Clears the current layer of widgets. Not particularly useful in practice, and basically duplicative of renpy.scene.

Function: | ui.close | ():

This closes the currently open widget or layer. If a widget is closed, then we start adding to its parent, or the layer if no parent is open. If a layer is closed, we return to the previously open layer. An error is thrown if we close the last open layer.

Function: | ui.interact | (**kwargs):

Displays the current scene to the user, waits for a widget to indicate a return value, and returns that value to the user. As a side-effect, disables fast skip mode when executed.

Some useful keyword arguments are:

type - The type of this interaction. See renpy.last_interact_type for more details.

show_mouse - Should the mouse be shown during this interaction? Only advisory, as this doesn't work reliably.

suppress_overlay - This suppresses the display of the overlay during this interaction.

suppress_underlay - This suppresses the underlay during this interaction. The underlay contains the key and mouse bindings that let the user access the game menu. (As well as a number of other useful in-game functions.)

roll_forward - The value returned if the user tries to roll forward. This is normally used in conjunction with renpy.roll_forward_info and renpy.checkpoint.

clear - If True, the transient layer will be cleared at the end of the interaction.

Function: | ui.layer | (name):

This causes widgets to be added to the named layer, until a matching call to ui.close.

Function: | ui.remove | (d):

This removes the displayable d from the current layer. This can only remove things from the layer directly, not from a displayable.

## Clicked Action Functions

The result of these functions is suitable for use as the clicked argument used by ui.button, ui.imagebutton, and ui.textbutton.

Function: | ui.callsinnewcontext | (label, *args, **kwargs):

This function returns a function that, when called, calls the supplied label in a new context. Additional positional and keyword arguments are passed in to the called label.

Function: | ui.jumps | (label):

This function returns a function that, when called, jumps the game to the given label, ending the current interaction in the process. It's best used to supply the clicked argument to the various button widgets.

Function: | ui.jumpsoutofcontext | (label):

This function returns a function that, when called, exits the current context, and in the parent context jumps to the named label. It's intended to be used as the clicked argument to a button.

Function: | ui.returns | (value):

This function returns a function that, when called, returns the supplied value. It's best used to supply the clicked argument to the various button widgets.

## Adjustment

Function: | ui.adjustment | (range=1, value=0, step=None, page=0, changed=None, adjustable=False, ranged=None):

Adjustment objects are used to represent a numeric value that can vary between 0 and a defined number. They also contain information on the steps the value can be adjusted by.

range is the limit of the range of the value. This may be an integer or a float.

value is the initial value of the adjustment.

step is the size of the steps the value can be adjusted by. The default for this value depends on page and range. If page is set, this defaults to 1/10 page. If range is a float, it defaults to 1/20th of the range, otherwise it defaults to 1 pixel.

page is the size of a page, used when the bar is in paging mode. If not set, defaults to 1/10th of the range.

These four arguments correspond to fields on the adjustment object. The fields can be safely set before anything using the adjustment has been rendered. After that, they should be treated as read-only.

changed is a function that's called when the adjustment is changed. The function is called with one argument, the new value of the adjustment. This should be present for the bar to be adjustable.

adjustable controls whether bars without any changed functions are adjustable. If changed is not None, the bar is always adjustable, and this argument is ignored.

ranged is a function that is called with this adjustment as an argument when the adjustment's range has is set. (new in 6.6.0)

Adjustment objects have one method:

Method: | Adjustment.change | (value):

Call this to set the value of the adjustment to value. This will redraw all displayables affected by this change.

documentation index ◦ reference manual ◦ function index