Menu API (SourceMod)

From AlliedModders Wiki
Revision as of 16:12, 14 May 2007 by BAILOPAN (talk | contribs) (New page: SourceMod has an extensive API for building and displaying menus to clients. Unlike AMX Mod X, this API is highly state driven. Menus are based on callbacks which are guaranteed to be fi...)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

SourceMod has an extensive API for building and displaying menus to clients. Unlike AMX Mod X, this API is highly state driven. Menus are based on callbacks which are guaranteed to be fired.

For C++, the Menu API can be found in public/IMenuManager.h. For SourcePawn, it is in plugins/include/menus.inc.

Objects

The SourceMod Menu System is based on an object oriented hierarchy. Understanding this hierarchy, even for scripting, is critical to understanding how to use the menu system efficiently.

Styles

The top level object is a MenuStyle (IMenuStyle in C++). Styles describe a unique menu system. There are two such styles built into SourceMod:

  • Valve Style, also called "ESC" menus; 8 items per page, no raw/disabled text can be rendered
  • Radio Style, also called "AMX" menus; 10 items per page, raw/disabled text can be rendered

Each MenuStyle has its own rules and properties. You can think of them as existing on separate "channels." For example, a menu can exist on a player as both a Valve menu and a Radio menu at the same time, and SourceMod will be able to manage both without any problems. This is because each style keeps track of its own menus separately.

Panels

Menus are drawn with a lower level interface called Panels (IMenuPanel in C++). Panels describe exactly one "frame," or display text, of a menu. Both selectable items and raw text can be added to a panel as long as its parent style supports the contents you're trying to draw. For example, the Valve Style does not support drawing raw text or disabled items.

Panels are considered temporary objects. They are created, rendered, displayed, and destroyed. Although they can be saved indefinitely, it is not necessary to do so.

Valve Style drawing rules/limitations:

  • Max items per page is 8.
  • Disabled items cannot be drawn.
  • Raw text cannot be drawn.
  • Spacers do not add a space/newline, giving a "cramped" feel.
  • Users must press "ESC" or be at their console to view the menu.

Radio Style drawing rules/limitations:

  • Max items per page is 10.
  • Titles appear white; items appear yellow, unless disabled, in which case they are white.
  • The 0th item is always white. For consistency, this means navigational controls explained in the next section are always white, and simply not drawn if disabled.

Menus

Lastly, there are plain Menus (IBaseMenu in C++). These are helper objects designed for storing a menu based on selectable items. Unlike low-level panels, menus are containers, and can only contain items which are selectable (i.e., do not contain raw text). They fall into two categories:

  • Non-paginated: The menu can only have a certain number of items on it, and no control/navigation options will be added, except for an "Exit" button which will always be in the last position supported by the style.
    • Valve Style maximum items: 8
    • Radio Style maximum items: 10
  • Paginated: The menu can have any number of items. When displayed, only a certain number of items will be drawn at a time. Automatic navigation controls are added so players can easily move back and forth to different "pages" of items in the menu.
    • "Previous" is always drawn as the first navigation item, third from the last supported position. This will not be drawn if the menu only contains one page. If there are no previous pages, the text will not be drawn on either style; if possible, the menu will be padded so spacing is consistent.
      • Valve Style position: 6
      • Radio Style position: 8
    • "Next" is always drawn as the second navigation item, second from the last supported position. This will not be drawn if the menu only contains one page. If there are no further pages, the text will not be drawn on either style; if possible, the menu will be padded so spacing is consistent.
      • Valve Style position: 7
      • Radio Style position: 9
    • "Exit" is drawn if the menu has the exit button property set. It is always the last supported item position.
      • Valve Style position: 8
      • Radio Style position: 10

Menus do not allow for adding raw text as items; however, we will see later that it is still possible to achieve this.

Internally, menus are drawn via a RenderMenu algorithm. This algorithm creates a temporary panel and fills it with items from menus. This panel is then displayed to a client. The algorithm attempts to create a consistent feel across all menus, and across all styles. Thus any menu displayed via the IBaseMenu class, or Menu Handles, will look and act the same.


Callbacks

Overview

Menus are a callback based system. Each callback represents an action that occurs during a menu display cycle. A cycle consists of a number of notifications:

  • Start notification.
    • Display notification if the menu can be displayed to the client.
    • Either an item select or menu cancel notification.
  • End notification.

Since End signifies the end of a full display cycle, it is usually used to destroy temporary menus.

Specification

A detailed explanation of these events is below. For C++, an IBaseMenu pointer is always available. For SourcePawn, a Menu Handle and a MenuAction are always set in the MenuHandler callback. Unlike C++, the SourcePawn API allows certain actions to only be called if they are requested at menu creation time. This is an optimization. However, certain actions cannot be prevented from being called.

  • Start. The menu has been acknowledged. This does not mean it will be displayed; however, it guarantees that "OnMenuEnd" will be called.
    • OnMenuStart() in C++.
    • MenuAction_Start in SourcePawn. This action is not triggered unless requested.
      • param1: Ignored (always 0).
      • param2: Ignored (always 0).
  • Display. The menu is being displayed to a client.
    • OnMenuDisplay() in C++. An IMenuPanel pointer and client index are available.
    • MenuAction_Display in SourcePawn. This action is not triggered unless requested.
      • param1: A client index.
      • param2: A Handle to a menu panel.
  • Select. An item on the menu has been selected. The item position given will be the position in the menu, rather than the key pressed (unless the menu is a raw panel).
    • OnMenuSelect() in C++. A client index and item position are passed.
    • MenuAction_Select in SourcePawn. This action is always triggerable, whether requested or not.
      • param1: A client index.
      • param2: An item position.
  • Cancel. The menu's display to one client has been cancelled.
    • OnMenuCancel() in C++. A reason for cancellation is provided.
    • MenuAction_Cancel in SourcePawn. This action is always triggerable, whether requested or not.
      • param1: A client index.
      • param2: A menu cancellation reason code.
  • End. The menu's display cycle has finished; this means that the "Start" action has occurred, and either "Select" or "Cancel" has occurred thereafter. This is typically where menu resources are removed/deleted.
    • OnMenuEnd() in C++.
    • MenuAction_End in SourcePawn. This action is always triggered, whether requested or not.
      • param1: Ignored (always 0).
      • param2: Ignored (always 0).

Panels

For panels, the callback rules change. Panels only receive two of the above callbacks, and it is guaranteed that only one of them will be called for a given display cycle. For C++, the IBaseMenu pointer will always be NULL. For SourcePawn, the menu Handle will always be INVALID_HANDLE.

  • Select. A key has been pressed. This can be any number and should not be considered as reliably in bounds. For example, even if you only had 2 items in your panel, a client could trigger a key press of "43."
    • OnMenuSelect() in C++. A client index and key number pressed are passed.
    • MenuAction_Select in SourcePawn.
      • param1: A client index.
      • param2: Number of the key pressed.
  • Cancel. The menu's display to one client has been cancelled.
    • OnMenuCancel() in C++. A reason for cancellation is provided.
    • MenuAction_Cancel in SourcePawn.
      • param1: A client index.
      • param2: A menu cancellation reason code.