3 * ================================================================
5 * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
6 * ================================================================
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License,
10 * version 3.0, as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 * As a special exception, AlliedModders LLC gives you permission to
21 * link the code of this program (as well as its derivative works) to
22 * "Half-Life 2," the "Source Engine," the "SourcePawn JIT," and any
23 * Game MODs that run on software by the Valve Corporation. You must
24 * obey the GNU General Public License in all respects for all other
25 * code used. Additionally, AlliedModders LLC grants this exception
26 * to all derivative works. AlliedModders LLC defines further
27 * exceptions, found in LICENSE.txt (as of this writing, version
28 * JULY-31-2007), or <http://www.sourcemod.net/license.php>.
33 #ifndef _INCLUDE_SOURCEMOD_MENU_SYSTEM_H_
34 #define _INCLUDE_SOURCEMOD_MENU_SYSTEM_H_
36 #include <IShareSys.h>
37 #include <IHandleSys.h>
39 #define SMINTERFACE_MENUMANAGER_NAME "IMenuManager"
40 #define SMINTERFACE_MENUMANAGER_VERSION 9
43 * @file IMenuManager.h
44 * @brief Abstracts on-screen menus for clients.
50 * @brief Used to determine how an item selection is interpreted.
54 ItemSel_None, /**< Invalid selection */
55 ItemSel_Back, /**< Go back one page (really "Previous") */
56 ItemSel_Next, /**< Go forward one page */
57 ItemSel_Exit, /**< Menu was exited */
58 ItemSel_Item, /**< Valid item selection */
59 ItemSel_ExitBack, /**< Sends MenuEnd_ExitBack */
63 * @brief Used to determine which order to search for items in.
67 ItemOrder_Ascending, /**< Items should be drawn ascendingly */
68 ItemOrder_Descending, /**< Items should be drawn descendingly */
72 * @brief Pairs an item type with an item menu position.
76 ItemSelection type; /**< Item selection type */
77 unsigned int item; /**< Item position, if applicable */
85 * @brief Describes menu display information.
89 unsigned int apiVers; /**< Must be filled with the API version */
90 IBaseMenu *menu; /**< Menu pointer, or NULL if there is only a display */
91 IMenuHandler *mh; /**< Menu callbacks handler */
92 unsigned int firstItem; /**< MENU ONLY: First item displayed on the last page */
93 unsigned int lastItem; /**< MENU ONLY: Last item displayed on the last page */
94 menu_slots_t slots[11]; /**< MENU ONLY: Item selection table (first index is 1) */
97 #define ITEMDRAW_DEFAULT (0) /**< Item should be drawn normally */
98 #define ITEMDRAW_DISABLED (1<<0) /**< Item is drawn but not selectable */
99 #define ITEMDRAW_RAWLINE (1<<1) /**< Item should be a raw line, without a slot */
100 #define ITEMDRAW_NOTEXT (1<<2) /**< No text should be drawn */
101 #define ITEMDRAW_SPACER (1<<3) /**< Item should be drawn as a spacer, if possible */
102 #define ITEMDRAW_IGNORE ((1<<1)|(1<<2)) /**< Item should be completely ignored (rawline + notext) */
103 #define ITEMDRAW_CONTROL (1<<4) /**< Item is control text (back/next/exit) */
106 * @brief Information about item drawing.
110 ItemDrawInfo(const char *DISPLAY=NULL, unsigned int STYLE=ITEMDRAW_DEFAULT,
111 unsigned int FLAGS=0, const char *HELPTEXT=NULL)
112 : display(DISPLAY), style(STYLE), access(FLAGS)
115 const char *display; /**< Display text (NULL for none) */
116 unsigned int style; /**< ITEMDRAW style flags */
117 unsigned int access; /**< Access flags required to see */
121 * @brief Contains information about a vote result.
123 struct menu_vote_result_t
125 unsigned int num_clients; /**< Number of clients the menu was displayed to */
126 unsigned int num_votes; /**< Number of votes received */
127 struct menu_client_vote_t
129 int client; /**< Client index */
130 int item; /**< Item # (or -1 for none) */
131 } *client_list; /**< Array of size num_clients */
132 unsigned int num_items; /**< Number of items voted for */
133 struct menu_item_vote_t
135 unsigned int item; /**< Item index */
136 unsigned int count; /**< Number of votes */
137 } *item_list; /**< Array of size num_items, sorted by count,
142 * @brief Reasons for a menu dying.
144 enum MenuCancelReason
146 MenuCancel_Disconnected = -1, /**< Client dropped from the server */
147 MenuCancel_Interrupted = -2, /**< Client was interrupted with another menu */
148 MenuCancel_Exit = -3, /**< Client selected "exit" on a paginated menu */
149 MenuCancel_NoDisplay = -4, /**< Menu could not be displayed to the client */
150 MenuCancel_Timeout = -5, /**< Menu timed out */
151 MenuCancel_ExitBack = -6, /**< Client selected "exit back" on a paginated menu */
155 * @brief Reasons a menu ended.
159 MenuEnd_Selected = 0, /**< Menu item was selected */
160 MenuEnd_VotingDone = -1, /**< Voting finished */
161 MenuEnd_VotingCancelled = -2, /**< Voting was cancelled */
162 MenuEnd_Cancelled = -3, /**< Menu was uncleanly cancelled */
163 MenuEnd_Exit = -4, /**< Menu was cleanly exited via "exit" */
164 MenuEnd_ExitBack = -5, /**< Menu was cleanly exited via "back" */
165 MenuEnd_NoVotes = -6, /**< No votes received */
169 #define MENU_NO_PAGINATION 0 /**< Menu should not be paginated (10 items max) */
170 #define MENU_TIME_FOREVER 0 /**< Menu should be displayed as long as possible */
172 #define MENUFLAG_BUTTON_EXIT (1<<0) /**< Menu has an "exit" button */
173 #define MENUFLAG_BUTTON_EXITBACK (1<<1) /**< Menu has an "exit back" button */
174 #define MENUFLAG_NO_SOUND (1<<2) /**< Menu will not have any select sounds */
177 * @brief Extended menu options.
181 MenuOption_IntroMessage, /**< CONST CHAR *: Valve menus only; defaults to:
182 "You have a menu, hit ESC"
184 MenuOption_IntroColor, /**< INT[4]: Valve menus only; specifies the intro message colour
185 using R,G,B,A (defaults to 255,0,0,255)
187 MenuOption_Priority, /**< INT *: Valve menus only; priority (less is higher) */
191 * @brief Describes the menu a player is viewing.
195 MenuSource_None = 0, /**< No menu is being displayed */
196 MenuSource_External = 1, /**< External menu, no pointer */
197 MenuSource_BaseMenu = 2, /**< An IBaseMenu pointer. */
198 MenuSource_Display = 3, /**< IMenuPanel source, no pointer */
204 * @brief Sets how a raw menu should be drawn.
210 * @brief Returns the parent IMenuStyle pointer.
212 * @return IMenuStyle pointer which created
215 virtual IMenuStyle *GetParentStyle() =0;
218 * @brief Resets/clears the cached display text.
220 virtual void Reset() =0;
223 * @brief Sets how the title should be drawn.
225 * @param text Text string to display for the title.
226 * @param onlyIfEmpty Only sets the title if one does not already
229 virtual void DrawTitle(const char *text, bool onlyIfEmpty=false) =0;
232 * @brief Adds an item to the menu and returns the position (1-10).
234 * Note: Item will fail to draw if there are too many items,
235 * or the item is not drawable (for example, invisible).
237 * @return Item draw position, or 0 on failure.
239 virtual unsigned int DrawItem(const ItemDrawInfo &item) =0;
242 * @brief Draws a raw line of text, if supported. The line does not
243 * need to be newline terminated.
245 * @return True on success, false if not supported.
247 virtual bool DrawRawLine(const char *rawline) =0;
250 * @brief Sets an extended menu option.
252 * @param option Option type.
253 * @param valuePtr Pointer of the type expected by the option.
254 * @return True on success, false if option or value is not supported.
256 virtual bool SetExtOption(MenuOption option, const void *valuePtr) =0;
259 * @brief Returns whether the display is capable of rendering an item
260 * with the given flags.
262 * @param flags ITEMDRAW flags.
263 * @return True if renderable, false otherwise.
265 virtual bool CanDrawItem(unsigned int drawFlags) =0;
268 * @brief Sends the menu display to a client.
270 * @param client Client index to display to.
271 * @param handler Menu handler to use.
272 * @param time Time to hold menu for.
273 * @return True on success, false otherwise.
275 virtual bool SendDisplay(int client, IMenuHandler *handler, unsigned int time) =0;
278 * @brief Destroys the display object.
280 virtual void DeleteThis() =0;
283 * @brief Sets the selectable key map. Returns false if the function
286 * @param keys A bit string where each bit N-1 specifies
287 * that key N is selectable (key 0 is bit 9).
288 * If the selectable key map is 0, it will be
289 * automatically set to allow 0.
290 * @return True on success, false if not supported.
292 virtual bool SetSelectableKeys(unsigned int keymap) =0;
295 * @brief Returns the current key position.
297 * @return Current key position starting at 1.
299 virtual unsigned int GetCurrentKey() =0;
302 * @brief Sets the next key position. This cannot be used
303 * to traverse backwards.
305 * @param key Key that is greater or equal to
307 * @return True on success, false otherwise.
309 virtual bool SetCurrentKey(unsigned int key) =0;
313 * @brief Describes a "MenuStyle" system which manages
314 * menu drawing and construction.
320 * @brief Returns the style API version.
322 * @return API version.
324 virtual unsigned int GetStyleAPIVersion()
326 return SMINTERFACE_MENUMANAGER_VERSION;
330 * @brief Returns the name of the menu style.
332 * @return String containing the style name.
334 virtual const char *GetStyleName() =0;
337 * @brief Creates an IMenuPanel object.
339 * Note: the object should be freed using ::DeleteThis.
341 * @return IMenuPanel object.
343 virtual IMenuPanel *CreatePanel() =0;
346 * @brief Creates an IBaseMenu object of this style.
348 * Note: the object should be freed using IBaseMenu::Destroy.
350 * @param handler IMenuHandler pointer.
351 * @param pOwner Optional IdentityToken_t owner for handle
353 * @return An IBaseMenu pointer.
355 virtual IBaseMenu *CreateMenu(IMenuHandler *handler, IdentityToken_t *pOwner=NULL) =0;
358 * @brief Returns the maximum number of items per page.
360 * @return Number of items per page.
362 virtual unsigned int GetMaxPageItems() =0;
365 * @brief Returns whether or not a client is viewing a menu.
367 * @param client Client index.
368 * @param object Optional pointer to retrieve menu object,
370 * @return MenuSource value.
372 virtual MenuSource GetClientMenu(int client, void **object) =0;
375 * @brief Cancels a client's menu.
377 * @param client Client index.
378 * @param autoIgnore If true, no menus can be created during
379 * the cancellation process.
380 * @return True if a menu was cancelled, false otherwise.
382 virtual bool CancelClientMenu(int client, bool autoIgnore=false) =0;
385 * @brief Returns a Handle the IMenuStyle object.
387 * @return Handle_t pointing to this object.
389 virtual Handle_t GetHandle() =0;
393 * @brief High-level interface for building menus.
399 * @brief Appends an item to the end of a menu.
401 * @param info Item information string.
402 * @param draw Default drawing information.
403 * @return True on success, false on item limit reached.
405 virtual bool AppendItem(const char *info, const ItemDrawInfo &draw) =0;
408 * @brief Inserts an item into the menu before a certain position;
409 * the new item will be at the given position and all next items
412 * @param position Position, starting from 0.
413 * @param info Item information string.
414 * @param draw Default item draw info.
415 * @return True on success, false on invalid menu position
417 virtual bool InsertItem(unsigned int position, const char *info, const ItemDrawInfo &draw) =0;
420 * @brief Removes an item from the menu.
422 * @param position Position, starting from 0.
423 * @return True on success, false on invalid menu position.
425 virtual bool RemoveItem(unsigned int position) =0;
428 * @brief Removes all items from the menu.
430 virtual void RemoveAllItems() =0;
433 * @brief Returns an item's info.
435 * @param position Position, starting from 0.
436 * @param draw Optional pointer to store a draw information.
437 * @return Info string pointer, or NULL if position was invalid.
439 virtual const char *GetItemInfo(unsigned int position, ItemDrawInfo *draw) =0;
442 * @brief Returns the number of items.
444 * @return Number of items in the menu.
446 virtual unsigned int GetItemCount() =0;
449 * @brief Sets the menu's pagination,.
451 * @param itemsPerPage Number of items per page, or MENU_NO_PAGINATION.
452 * @return True on success, false if itemsPerPage is too large.
454 virtual bool SetPagination(unsigned int itemsPerPage) =0;
457 * @brief Returns an item's pagination.
459 * @return Pagination setting.
461 virtual unsigned int GetPagination() =0;
464 * @brief Returns the menu style.
466 * @return Menu style.
468 virtual IMenuStyle *GetDrawStyle() =0;
471 * @brief Sets the menu's display title/message.
473 * @param message Message (format options allowed).
475 virtual void SetDefaultTitle(const char *message) =0;
478 * @brief Returns the menu's display/title message.
480 * @return Message string.
482 virtual const char *GetDefaultTitle() =0;
485 * @brief Sets an extended menu option.
487 * @param option Option type.
488 * @param valuePtr Pointer of the type expected by the option.
489 * @return True on success, false if option or value is not supported.
491 virtual bool SetExtOption(MenuOption option, const void *valuePtr) =0;
494 * @brief Creates a new IMenuPanel object using extended options specific
495 * to the IMenuStyle parent. Titles, items, etc, are not copied.
497 * Note: The object should be freed with IMenuPanel::DeleteThis.
499 * @return IMenuPanel pointer.
501 virtual IMenuPanel *CreatePanel() =0;
504 * @brief Sends the menu to a client.
506 * @param client Client index to display to.
507 * @param time Time to hold menu for.
508 * @param alt_handler Alternate IMenuHandler.
509 * @return True on success, false otherwise.
511 virtual bool Display(int client, unsigned int time, IMenuHandler *alt_handler=NULL) =0;
514 * @brief Destroys the menu and frees all associated resources.
516 * @param releaseHandle If true, the Handle will be released
517 * in the destructor. This should be set
518 * to true except for IHandleTypeDispatch
521 virtual void Destroy(bool releaseHandle=true) =0;
524 * @brief Cancels the menu on all client's displays. While the menu is
525 * being cancelled, the menu may not be re-displayed to any clients.
526 * If a vote menu is currently active, it will be cancelled as well.
528 * @return Number of menus cancelled.
530 virtual void Cancel() =0;
533 * @brief Returns the menu's Handle. The Handle is automatically
534 * removed when the menu is destroyed.
536 * @return Handle_t handle value.
538 virtual Handle_t GetHandle() =0;
541 * @brief Returns menu option flags.
543 * @return Menu option flags.
545 virtual unsigned int GetMenuOptionFlags() =0;
548 * @brief Sets menu option flags.
550 * @param flags Menu option flags.
552 virtual void SetMenuOptionFlags(unsigned int flags) =0;
555 * @brief Returns the menu's handler.
557 * @return IMenuHandler of the menu.
559 virtual IMenuHandler *GetHandler() =0;
563 * @brief Contains callbacks for menu actions.
569 * @brief Returns the menu api verison.
571 * @return Menu API version.
573 virtual unsigned int GetMenuAPIVersion2()
575 return SMINTERFACE_MENUMANAGER_VERSION;
579 * @brief A display/selection cycle has started.
581 * @param menu Menu pointer.
583 virtual void OnMenuStart(IBaseMenu *menu)
588 * @brief Called before a menu is being displayed. This is where
589 * you can set an alternate title on the menu.
591 * @param menu Menu pointer.
592 * @param client Client index.
593 * @param display IMenuPanel pointer.
595 virtual void OnMenuDisplay(IBaseMenu *menu, int client, IMenuPanel *display)
600 * @brief Called when an item is selected.
602 * @param menu Menu pointer.
603 * @param client Client that selected the item.
604 * @param item Item number.
606 virtual void OnMenuSelect(IBaseMenu *menu, int client, unsigned int item)
611 * @brief An active menu display was dropped from a client.
613 * @param menu Menu pointer.
614 * @param client Client that had the menu.
615 * @param reason Menu cancellation reason.
617 virtual void OnMenuCancel(IBaseMenu *menu, int client, MenuCancelReason reason)
622 * @brief A display/selection cycle has ended.
624 * @param menu Menu pointer.
626 virtual void OnMenuEnd(IBaseMenu *menu, MenuEndReason reason)
631 * @brief Called when the menu object is destroyed.
633 * @param menu Menu pointer.
635 virtual void OnMenuDestroy(IBaseMenu *menu)
640 * @brief Called when requesting how to render an item.
642 * @param menu Menu pointer.
643 * @param client Client index receiving the menu.
644 * @param item Item number in the menu.
645 * @param style ITEMSTYLE flags, by reference for modification.
647 virtual void OnMenuDrawItem(IBaseMenu *menu, int client, unsigned int item, unsigned int &style)
652 * @brief Called when drawing item text.
654 * @param menu Menu pointer.
655 * @param client Client index receiving the menu.
656 * @param panel Panel being used to draw the menu.
657 * @param item Item number in the menu.
658 * @param dr Item draw information.
659 * @return 0 to let the render algorithm decide how to draw, otherwise,
660 * the return value from panel->DrawItem should be returned.
662 virtual unsigned int OnMenuDisplayItem(IBaseMenu *menu,
666 const ItemDrawInfo &dr)
672 * @brief Called when a vote has been started and displayed to
673 * clients. This is called after OnMenuStart() and OnMenuDisplay(),
674 * but before OnMenuSelect().
676 * @param menu Menu pointer.
678 virtual void OnMenuVoteStart(IBaseMenu *menu)
683 * @brief Called when a vote ends. This is automatically called by the
684 * wrapper, and never needs to called from a style implementation.
686 * This function does not replace OnMenuEnd(), nor does it have the
687 * same meaning as OnMenuEnd(), meaning you should not destroy a menu
688 * while it is in this function.
690 * @param menu Menu pointer.
691 * @param results Menu vote results.
693 virtual void OnMenuVoteResults(IBaseMenu *menu, const menu_vote_result_t *results)
698 * @brief Called when a vote is cancelled. If this is called, then
699 * OnMenuVoteResults() will not be called. In both cases, OnMenuEnd will
702 * @param menu Menu pointer.
704 virtual void OnMenuVoteCancel(IBaseMenu *menu)
709 * @brief Call to set private handler stuff.
711 * @param option Option name.
712 * @param data Private data.
713 * @return True if set, false if invalid or unrecognized.
715 virtual bool OnSetHandlerOption(const char *option, const void *data)
722 * @brief Manages menu creation and displaying.
724 class IMenuManager : public SMInterface
727 virtual const char *GetInterfaceName()
729 return SMINTERFACE_MENUMANAGER_NAME;
731 virtual unsigned int GetInterfaceVersion()
733 return SMINTERFACE_MENUMANAGER_VERSION;
735 virtual bool IsVersionCompatible(unsigned int version)
737 if (version < 9 || version > GetInterfaceVersion())
745 * @brief Finds a style by name.
747 * @param name Name of the style (case insensitive).
748 * @return IMenuStyle pointer, or NULL if not found.
750 virtual IMenuStyle *FindStyleByName(const char *name) =0;
753 * @brief Returns the default draw style Core is using.
755 * @return Menu style pointer.
757 virtual IMenuStyle *GetDefaultStyle() =0;
760 * @brief Given a set of menu states, converts it to an IMenuPanel object.
762 * The state parameter is both INPUT and OUTPUT.
763 * INPUT: menu, mh, firstItem, lastItem
764 * OUTPUT: display, firstItem, lastItem, slots
766 * @param client Client index.
767 * @param states Menu states.
768 * @return IMenuPanel pointer, or NULL if no items could be
769 * found in the IBaseMenu pointer, or NULL if any
770 * other error occurred. Any valid pointer must
771 * be freed using IMenuPanel::DeleteThis.
773 virtual IMenuPanel *RenderMenu(int client, menu_states_t &states, ItemOrder order) =0;
776 * @brief Cancels a menu. Calls IBaseMenu::Cancel() after doing some preparatory
777 * work. This should always be used instead of directly calling Cancel().
779 * @param menu IBaseMenu pointer.
781 virtual void CancelMenu(IBaseMenu *menu) =0;
784 * @brief Displays a menu as a vote.
786 * @param menu IBaseMenu pointer.
787 * @param num_clients Number of clients to display to.
788 * @param clients Client index array.
789 * @param max_time Maximum time to hold menu for.
790 * @param flags Vote flags (currently unused).
791 * @return True on success, false if a vote is in progress.
793 virtual bool StartVote(IBaseMenu *menu,
794 unsigned int num_clients,
796 unsigned int max_time,
797 unsigned int flags=0) =0;
800 * @brief Returns whether or not a vote is in progress.
802 * @return True if a vote is in progress, false otherwise.
804 virtual bool IsVoteInProgress() =0;
807 * @brief Cancels the vote in progress. This calls IBaseMenu::Cancel().
809 virtual void CancelVoting() =0;
812 * @brief Returns the remaining vote delay from the last menu. This delay is
813 * a suggestion for all public votes, and is not enforced.
815 * @return Number of seconds to wait.
817 virtual unsigned int GetRemainingVoteDelay() =0;
821 #endif //_INCLUDE_SOURCEMOD_MENU_SYSTEM_H_