Solarus quests  1.6
Quest maker's reference
Menus

To display various information such as a title screen, a dialog box, a HUD (head-up display) or a pause screen, you can use one or several menus.

A menu is an arbitrary Lua table. A menu belongs to a context that may be the current map, the current game, the sol.main table or even another menu. This context is the lifetime of your menu. As long as your menu is active, the engine will call events that are defined in your table, i.e. callback methods like menu:on_started() menu:on_draw(), menu:on_key_pressed(), etc., to notify your menu of something (the player pressed a key, your menu needs to be redrawn, etc.).

This menu API does not provide anything fundamental: indeed, the map, game and sol.main APIs already provide the necessary features, so you could do what you want from there manually. But the API described on this page makes your life easier because menus automatically receive events whenever they need to be notified, and automatically stop being active when their context no longer exists.

Functions of sol.menu

sol.menu.start(context, menu, [on_top])

Starts a menu in a context.

The Solarus engine will then call the appropriate events on your menu until it is stopped.

  • context (map, game or table): The context your menu will belong to. Similarly to the case of timers, the context determines the lifetime of your menu. The context must be one of the following four objects:
    • If you make a map menu, your menu will be drawn above the map surface. It will be stopped when the player goes to another map. This may be useful to show head-up information local to a precise map.
      Example: a counter or a mini-game that only exists on a specific map.
    • If you make a game menu, your menu will be global to all maps. As long as the game is running, it will persist accross map changes.
      Example: the player's life counter.
    • If you make a main menu, your menu will be global to the whole program. It can exist outside a game (and it even persists during the game if you don't stop it).
      Example: the title screen.
    • If you set the context to another menu, then its lifetime will be limited to this other menu. This allows to make nested menus. Example: a popup that shows some information above another menu.
  • menu (table): The menu to activate. It can be any table. The only thing that makes it special is the presence of callback functions (events) as described in section Events of a menu.
  • on_top (boolean, optional): Whether this menu should be drawn on top of other existing menus of the same context or behind them. If true, the on_draw() event of your menu will be the last to be called if there are several menus in the context. If false, it will be the first one. No value means true.

sol.menu.stop(menu)

Stops a menu previously activated with sol.menu.start().

After this call, the Solarus engine will no longer call events on your menu. But you can restart it later if you want.

Nothing happens is the menu was already stopped or never started.

  • menu (table): The menu to stop.

sol.menu.stop_all(context)

Stops all menus that are currently running in a context.

  • context (map, game, sol.main or table): The context where you want to stop menus.

This function is not often needed since menus are already automatically stopped when their context is closed.

sol.menu.is_started(menu)

Returns whether a table is a currently active menu.

  • menu (table): The menu to test.
  • Return value (boolean): true if this is an active menu.

sol.menu.bring_to_front(menu)

Places this menu in front of other menus of the same context.

Your menu will then be the first one to receive input events (keyboard, joypad and mouse events) and the last one to be drawn.

  • menu (table): The menu to bring to the front.

sol.menu.bring_to_back(menu)

Places this menu behind other menus of the same context.

Your menu will then be the last one to receive input events (keyboard, joypad and mouse events) and the first one to be drawn.

  • menu (table): The menu to bring to the back.

Events of a menu

Events are callback methods automatically called by the engine if you define them.

menu:on_started()

Called when your menu is started.

This event is triggered when you call sol.menu.start().

menu:on_finished()

Called when your menu is stopped.

This event is triggered when you call sol.menu.stop() or when the context of your menu finishes.

menu:on_update()

Called at each cycle of the main loop while your menu is active.

Menus of are updated in the following order:

  1. Map menus (only during a game).
  2. Game menus (only during a game).
  3. Main menus (the more general ones).

When several menus exist in the same context, they are updated from the back one to the front one. You can control this order thanks to the on_top parameter of menu:start() when you start a menu.

Remarks
As this function is called at each cycle, it is recommended to use other solutions when possible, like timers and other events.

menu:on_draw(dst_surface)

Called when your menu has to be redrawn.

Use this event to draw your menu.

  • dst_surface (surface): The surface where you should draw your menu.

Menus of are drawn in the following order:

  1. Map menus (only during a game).
  2. Game menus (only during a game).
  3. Main menus (the more general ones).

When several menus exist in the same context, they are drawn from the back one to the front one. You can control this order thanks to the on_top parameter of sol.menu.start() when you start a menu, or with sol.menu.bring_to_front() and sol.menu.bring_to_back()

menu:on_key_pressed(key, modifiers)

Called when the user presses a keyboard key while your menu is active.

  • key (string): Name of the raw key that was pressed.
  • modifiers (table): A table whose keys indicate what modifiers were down during the event. Possible table keys are "shift", "control" and "alt". Table values are true.
  • Return value (boolean): Indicates whether the event was handled. If you return true, the event won't be propagated to other objects (like other menus or the built-in game commands).

For all keyboard, joypad and mouse events, menus are notified from the front one to the back one. For example, if some dialog box is shown during the pause menu and appears above that pause menu, it will naturally receive keyboard and joypad events first.

When a menu handles the event, it should return true to make the event stop being propagated. Menus (and other objects) below it won't be notified then. On the contrary, if no script has handled the event, then the engine can handle it with a built-in behavior.

Remarks
This event indicates the raw key pressed. If you want the corresponding character instead (if any), see menu:on_character_pressed().

menu:on_key_released(key)

Called when the user releases a keyboard key while your menu is active. Menus on top are notified first.

  • key (string): Name of the raw key that was released.
  • Return value (boolean): Indicates whether the event was handled. If you return true, the event won't be propagated to other objects (like other menus or the built-in game commands).

menu:on_character_pressed(character)

Called when the user enters text while your menu is active. Menus on top are notified first.

  • character (string): A utf-8 string representing the character that was pressed.
  • Return value (boolean): Indicates whether the event was handled. If you return true, the event won't be propagated to other objects (like other menus).
Remarks
When a character key is pressed, two events are called: menu:on_key_pressed() (indicating the raw key) and menu:on_character_pressed() (indicating the utf-8 character). If your menu needs to input text from the user, menu:on_character_pressed() is what you want because it considers the keyboard's layout and gives you international utf-8 strings.

menu:on_joypad_button_pressed(button)

Called when the user presses a joypad button while your menu is active. Menus on top are notified first.

  • button (number): Index of the button that was pressed.
  • Return value (boolean): Indicates whether the event was handled. If you return true, the event won't be propagated to other objects (like other menus or the built-in game commands).

menu:on_joypad_button_released(button)

Called when the user releases a joypad button while your menu is active. Menus on top are notified first.

  • button (number): Index of the button that was released.
  • Return value (boolean): Indicates whether the event was handled. If you return true, the event won't be propagated to other objects (like other menus or the built-in game commands).

menu:on_joypad_axis_moved(axis, state)

Called when the user moves a joypad axis while your menu is active. Menus on top are notified first.

  • axis (number): Index of the axis that was moved. Usually, 0 is an horizontal axis and 1 is a vertical axis.
  • state (number): The new state of the axis that was moved. -1 means left or up, 0 means centered and 1 means right or down.
  • Return value (boolean): Indicates whether the event was handled. If you return true, the event won't be propagated to other objects (like other menus or the built-in game commands).

menu:on_joypad_hat_moved(hat, direction8)

Called when the user moves a joypad hat while your menu is active. Menus on top are notified first.

  • hat (number): Index of the hat that was moved.
  • direction8 (number): The new direction of the hat. -1 means that the hat is centered. 0 to 7 indicates that the hat is in one of the eight main directions.
  • Return value (boolean): Indicates whether the event was handled. If you return true, the event won't be propagated to other objects (like other menus or the built-in game commands).

menu:on_command_pressed(command)

Called during a game when the player presses a game command (a keyboard key or a joypad action mapped to a built-in game behavior). You can use this event to override the normal built-in behavior of the game command. Menus on top are notified first.

  • command (string): Name of the built-in game command that was pressed (see the game API for the list of existing game commands).
  • Return value (boolean): Indicates whether the event was handled. If you return true, the event won't be propagated to other objects (you are overriding the built-in behavior of pressing this game command).
Remarks
As the notion of game commands only exist during a game, this event is only called for game menus and map menus.
This event is not triggered if you already handled the underlying low-level keyboard or joypad event.

menu:on_command_released(command)

Called during a game when the player released a game command (a keyboard key or a joypad action mapped to a built-in game behavior). You can use this event to override the normal built-in behavior of the game command. Menus on top are notified first.

  • command (string): Name of the built-in game command that was released (see the game API for the list of existing game commands).
  • Return value (boolean): Indicates whether the event was handled. If you return true, the event won't be propagated to other objects (you are overriding the built-in behavior of releasing this game command).
Remarks
As the notion of game commands only exist during a game, this event is only called for game menus and map menus.
This event is not triggered if you already handled the underlying low-level keyboard or joypad event.

menu:on_mouse_pressed(button, x, y)

Called when the user presses a mouse button while this menu is active. Menus on top are notified first.

  • button (string): Name of the mouse button that was pressed. Possible values are "left", "middle", "right", "x1" and "x2".
  • x (integer): The x position of the mouse in quest size coordinates.
  • y (integer): The y position of the mouse in quest size coordinates.
  • Return value (boolean): Indicates whether the event was handled. If you return true, the event won't be propagated to other objects (like other menus).

menu:on_mouse_released(button, x, y)

Called when the user releases a mouse button while this menu is active.

  • button (string): Name of the mouse button that was released. Possible values are "left", "middle", "right", "x1" and "x2".
  • x (integer): The x position of the mouse in quest size coordinates.
  • y (integer): The y position of the mouse in quest size coordinates.
  • Return value (boolean): Indicates whether the event was handled. If you return true, the event won't be propagated to other objects (like other menus).

menu:on_finger_pressed(finger, x, y, pressure)

Called when the user presses a finger while the menu is running.

  • finger (integer): ID of the finger that was pressed.
  • x (integer): The x position of the finger in quest size coordinates.
  • y (integer): The y position of the finger in quest size coordinates.
  • pressure (number): The pressure of the finger, normalized between 0 and 1.
  • Return value (boolean): Indicates whether the event was handled. If you return true, the event won't be propagated to other objects.

menu:on_finger_released(finger, x, y, pressure)

Called when the user releases a finger while the menu is running.

  • finger (integer): ID of the finger that was pressed.
  • x (integer): The x position of the finger in quest size coordinates.
  • y (integer): The y position of the finger in quest size coordinates.
  • pressure (number): The pressure of the finger, normalized between 0 and 1.
  • Return value (boolean): Indicates whether the event was handled. If you return true, the event won't be propagated to other objects.

menu:on_finger_moved(finger, x, y, dx, dy, pressure)

Called when the user moves a finger while the menu is running.

  • finger (integer): ID of the finger that was pressed.
  • x (integer): The x position of the finger in quest size coordinates.
  • y (integer): The y position of the finger in quest size coordinates.
  • dx (integer): The horizontal distance moved by finger in quest size coordinates.
  • dy (integer): The vertical distance moved by finger in quest size coordinates.
  • pressure (number): The pressure of the finger, normalized between 0 and 1.
  • Return value (boolean): Indicates whether the event was handled. If you return true, the event won't be propagated to other objects.