3 * ===============================================================
4 * SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved.
5 * ===============================================================
7 * This file is not open source and may not be copied without explicit
8 * written permission of AlliedModders LLC. This file may not be redistributed
9 * in whole or significant part.
10 * For information, see LICENSE.txt or http://www.sourcemod.net/license.php
15 #include "sm_globals.h"
17 #include "MenuManager.h"
18 #include "MenuStyle_Valve.h"
19 #include "MenuStyle_Radio.h"
20 #include "HandleSys.h"
21 #include "PluginSys.h"
23 #if defined CreateMenu
28 * And God said, "let there be menus," and behold, there were menus.
29 * God saw the menus and they were good. And the evening and the morning
35 MenuAction_Start = (1<<0), /**< A menu has been started (nothing passed) */
36 MenuAction_Display = (1<<1), /**< A menu is about to be displayed (param1=client, param2=MenuPanel Handle) */
37 MenuAction_Select = (1<<2), /**< An item was selected (param1=client, param2=item) */
38 MenuAction_Cancel = (1<<3), /**< The menu was cancelled (param1=client, param2=item) */
39 MenuAction_End = (1<<4), /**< A menu's display/selection cycle is complete (nothing passed). */
40 MenuAction_VoteEnd = (1<<5), /**< (VOTE ONLY): A vote sequence has ended (param1=chosen item) */
43 class CPanelHandler : public IMenuHandler
45 friend class MenuNativeHelpers;
50 void OnMenuCancel(IBaseMenu *menu, int client, MenuCancelReason reason);
51 void OnMenuSelect(IBaseMenu *menu, int client, unsigned int item);
53 IPluginFunction *m_pFunc;
57 class CMenuHandler : public IMenuHandler
59 friend class MenuNativeHelpers;
61 CMenuHandler(IPluginFunction *pBasic, int flags);
63 void OnMenuStart(IBaseMenu *menu);
64 void OnMenuDisplay(IBaseMenu *menu, int client, IMenuPanel *display);
65 void OnMenuSelect(IBaseMenu *menu, int client, unsigned int item);
66 void OnMenuCancel(IBaseMenu *menu, int client, MenuCancelReason reason);
67 void OnMenuEnd(IBaseMenu *menu);
68 void OnMenuDestroy(IBaseMenu *menu);
70 void OnMenuDrawItem(IBaseMenu *menu, int client, unsigned int item, unsigned int &style);
71 void OnMenuDisplayItem(IBaseMenu *menu, int client, unsigned int item, const char **display);
74 IPluginFunction *m_pBasic;
79 * GLOBAL CLASS FOR HELPERS
82 class MenuNativeHelpers :
84 public IHandleTypeDispatch,
85 public IPluginsListener
88 virtual void OnSourceModAllInitialized()
90 m_PanelType = g_HandleSys.CreateType("IMenuPanel", this, 0, NULL, NULL, g_pCoreIdent, NULL);
91 g_PluginSys.AddPluginsListener(this);
94 virtual void OnSourceModShutdown()
96 g_HandleSys.RemoveType(m_PanelType, g_pCoreIdent);
98 while (!m_FreePanelHandlers.empty())
100 delete m_FreePanelHandlers.front();
101 m_FreePanelHandlers.pop();
104 while (!m_FreeMenuHandlers.empty())
106 delete m_FreeMenuHandlers.front();
107 m_FreeMenuHandlers.pop();
111 virtual void OnHandleDestroy(HandleType_t type, void *object)
113 IMenuPanel *panel = (IMenuPanel *)object;
118 * It is extremely important that unloaded plugins don't crash.
119 * Thus, if a plugin unloads, we run through every handler we have.
120 * This means we do almost no runtime work for keeping track of
121 * our panel handlers (we don't have to store a list of the running
122 * ones), but when push comes to shove, we have to scan them all
123 * in case any of them are active.
125 virtual void OnPluginUnloaded(IPlugin *plugin)
127 IPluginContext *pContext = plugin->GetBaseContext();
128 for (size_t i = 0; i < m_PanelHandlers.size(); i++)
130 if (m_PanelHandlers[i]->m_pPlugin == plugin)
132 m_PanelHandlers[i]->m_pPlugin = NULL;
133 m_PanelHandlers[i]->m_pFunc = NULL;
138 inline HandleType_t GetPanelType()
143 CPanelHandler *GetPanelHandler(IPluginFunction *pFunction)
145 CPanelHandler *handler;
146 if (m_FreePanelHandlers.empty())
148 handler = new CPanelHandler;
149 m_PanelHandlers.push_back(handler);
151 handler = m_FreePanelHandlers.front();
152 m_FreePanelHandlers.pop();
154 handler->m_pFunc = pFunction;
155 handler->m_pPlugin = g_PluginSys.GetPluginByCtx(pFunction->GetParentContext()->GetContext());
159 void FreePanelHandler(CPanelHandler *handler)
161 handler->m_pFunc = NULL;
162 handler->m_pPlugin = NULL;
163 m_FreePanelHandlers.push(handler);
166 CMenuHandler *GetMenuHandler(IPluginFunction *pFunction, int flags)
168 CMenuHandler *handler;
169 if (m_FreeMenuHandlers.empty())
171 handler = new CMenuHandler(pFunction, flags);
173 handler = m_FreeMenuHandlers.front();
174 m_FreeMenuHandlers.pop();
175 handler->m_pBasic = pFunction;
176 handler->m_Flags = flags;
181 void FreeMenuHandler(CMenuHandler *handler)
183 m_FreeMenuHandlers.push(handler);
187 HandleType_t m_PanelType;
188 CStack<CPanelHandler *> m_FreePanelHandlers;
189 CStack<CMenuHandler *> m_FreeMenuHandlers;
190 CVector<CPanelHandler *> m_PanelHandlers;
194 * BASIC PANEL HANDLER WRAPPER
197 void CPanelHandler::OnMenuCancel(IBaseMenu *menu, int client, MenuCancelReason reason)
201 m_pFunc->PushCell(BAD_HANDLE);
202 m_pFunc->PushCell(MenuAction_Cancel);
203 m_pFunc->PushCell(client);
204 m_pFunc->PushCell(reason);
205 m_pFunc->Execute(NULL);
207 g_MenuHelpers.FreePanelHandler(this);
210 void CPanelHandler::OnMenuSelect(IBaseMenu *menu, int client, unsigned int item)
214 m_pFunc->PushCell(BAD_HANDLE);
215 m_pFunc->PushCell(MenuAction_Select);
216 m_pFunc->PushCell(client);
217 m_pFunc->PushCell(item);
218 m_pFunc->Execute(NULL);
220 g_MenuHelpers.FreePanelHandler(this);
224 * MENU HANDLER WRAPPER
226 CMenuHandler::CMenuHandler(IPluginFunction *pBasic, int flags) :
227 m_pBasic(pBasic), m_Flags(flags)
229 /* :TODO: We can probably cache the handle ahead of time */
232 void CMenuHandler::OnMenuStart(IBaseMenu *menu)
234 if ((m_Flags & (int)MenuAction_Start) == (int)MenuAction_Start)
236 m_pBasic->PushCell(menu->GetHandle());
237 m_pBasic->PushCell(MenuAction_Start);
238 m_pBasic->PushCell(0);
239 m_pBasic->PushCell(0);
240 m_pBasic->Execute(NULL);
244 void CMenuHandler::OnMenuDisplay(IBaseMenu *menu, int client, IMenuPanel *panel)
246 if ((m_Flags & (int)MenuAction_Display) == (int)MenuAction_Display)
249 sec.pIdentity = m_pBasic->GetParentContext()->GetIdentity();
250 sec.pOwner = g_pCoreIdent;
253 g_HandleSys.InitAccessDefaults(NULL, &access);
254 access.access[HandleAccess_Delete] = HANDLE_RESTRICT_IDENTITY|HANDLE_RESTRICT_OWNER;
256 Handle_t hndl = g_HandleSys.CreateHandleEx(g_MenuHelpers.GetPanelType(), panel, &sec, &access, NULL);
258 m_pBasic->PushCell(menu->GetHandle());
259 m_pBasic->PushCell(MenuAction_Display);
260 m_pBasic->PushCell(client);
261 m_pBasic->PushCell(hndl);
262 m_pBasic->Execute(NULL);
264 g_HandleSys.FreeHandle(hndl, &sec);
268 void CMenuHandler::OnMenuSelect(IBaseMenu *menu, int client, unsigned int item)
270 m_pBasic->PushCell(menu->GetHandle());
271 m_pBasic->PushCell(MenuAction_Select);
272 m_pBasic->PushCell(client);
273 m_pBasic->PushCell(item);
274 m_pBasic->Execute(NULL);
277 void CMenuHandler::OnMenuCancel(IBaseMenu *menu, int client, MenuCancelReason reason)
279 m_pBasic->PushCell(menu->GetHandle());
280 m_pBasic->PushCell(MenuAction_Cancel);
281 m_pBasic->PushCell(client);
282 m_pBasic->PushCell(reason);
283 m_pBasic->Execute(NULL);
286 void CMenuHandler::OnMenuEnd(IBaseMenu *menu)
288 m_pBasic->PushCell(menu->GetHandle());
289 m_pBasic->PushCell(MenuAction_End);
290 m_pBasic->PushCell(0);
291 m_pBasic->PushCell(0);
292 m_pBasic->Execute(NULL);
295 void CMenuHandler::OnMenuDestroy(IBaseMenu *menu)
297 g_MenuHelpers.FreeMenuHandler(this);
301 * INLINE FUNCTIONS FOR NATIVES
304 inline Handle_t MakePanelHandle(IMenuPanel *panel, IPluginContext *pContext)
306 return g_HandleSys.CreateHandle(g_MenuHelpers.GetPanelType(), panel, pContext->GetIdentity(), g_pCoreIdent, NULL);
309 inline HandleError ReadPanelHandle(Handle_t hndl, IMenuPanel **panel)
312 sec.pIdentity = g_pCoreIdent;
314 return g_HandleSys.ReadHandle(hndl, g_MenuHelpers.GetPanelType(), &sec, (void **)panel);
317 inline IMenuStyle *GetStyleFromCell(cell_t cell)
321 MenuStyle_Default = 0, /**< The "default" menu style for the mod */
322 MenuStyle_Valve = 1, /**< The Valve provided menu style (Used on HL2DM) */
323 MenuStyle_Radio = 2, /**< The simpler menu style commonly used on CS:S */
326 if (cell == MenuStyle_Valve)
328 return &g_ValveMenuStyle;
329 } else if (cell == MenuStyle_Radio
330 && g_RadioMenuStyle.IsSupported())
332 return &g_RadioMenuStyle;
335 return g_Menus.GetDefaultStyle();
338 /***********************************
339 **** NATIVE DEFINITIONS ***********
340 ***********************************/
342 static cell_t CreateMenu(IPluginContext *pContext, const cell_t *params)
344 IMenuStyle *style = g_Menus.GetDefaultStyle();
345 IPluginFunction *pFunction;
347 if ((pFunction=pContext->GetFunctionById(params[1])) == NULL)
349 return pContext->ThrowNativeError("Function id %x is invalid", params[1]);
352 CMenuHandler *handler = g_MenuHelpers.GetMenuHandler(pFunction, params[2]);
353 IBaseMenu *menu = style->CreateMenu(handler, pContext->GetIdentity());
355 Handle_t hndl = menu->GetHandle();
365 static cell_t DisplayMenu(IPluginContext *pContext, const cell_t *params)
367 Handle_t hndl = (Handle_t)params[1];
371 if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
373 return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
376 return menu->Display(params[2], params[3]) ? 1 : 0;
379 static cell_t AddMenuItem(IPluginContext *pContext, const cell_t *params)
381 Handle_t hndl = (Handle_t)params[1];
385 if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
387 return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
393 pContext->LocalToString(params[2], &info);
394 pContext->LocalToString(params[3], (char **)&dr.display);
395 dr.style = params[4];
397 return menu->AppendItem(info, dr) ? 1 : 0;
400 static cell_t InsertMenuItem(IPluginContext *pContext, const cell_t *params)
402 Handle_t hndl = (Handle_t)params[1];
406 if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
408 return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
414 pContext->LocalToString(params[3], &info);
415 pContext->LocalToString(params[4], (char **)&dr.display);
416 dr.style = params[5];
418 return menu->InsertItem(params[2], info, dr) ? 1 : 0;
421 static cell_t RemoveMenuItem(IPluginContext *pContext, const cell_t *params)
423 Handle_t hndl = (Handle_t)params[1];
427 if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
429 return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
432 return menu->RemoveItem(params[2]) ? 1 : 0;
435 static cell_t RemoveAllMenuItems(IPluginContext *pContext, const cell_t *params)
437 Handle_t hndl = (Handle_t)params[1];
441 if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
443 return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
446 menu->RemoveAllItems();
451 static cell_t GetMenuItem(IPluginContext *pContext, const cell_t *params)
453 Handle_t hndl = (Handle_t)params[1];
457 if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
459 return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
465 if ((info=menu->GetItemInfo(params[2], &dr)) == NULL)
470 pContext->StringToLocalUTF8(params[3], params[4], info, NULL);
471 pContext->StringToLocalUTF8(params[6], params[7], dr.display ? dr.display : "", NULL);
474 pContext->LocalToPhysAddr(params[5], &addr);
480 static cell_t SetMenuPagination(IPluginContext *pContext, const cell_t *params)
482 Handle_t hndl = (Handle_t)params[1];
486 if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
488 return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
491 return menu->SetPagination(params[2]) ? 1 : 0;
494 static cell_t GetMenuPagination(IPluginContext *pContext, const cell_t *params)
496 Handle_t hndl = (Handle_t)params[1];
500 if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
502 return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
505 return menu->GetPagination();
508 static cell_t GetMenuItemCount(IPluginContext *pContext, const cell_t *params)
510 Handle_t hndl = (Handle_t)params[1];
514 if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
516 return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
519 return menu->GetItemCount();
522 static cell_t SetMenuTitle(IPluginContext *pContext, const cell_t *params)
524 Handle_t hndl = (Handle_t)params[1];
528 if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
530 return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
534 g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
536 menu->SetDefaultTitle(buffer);
541 static cell_t CreatePanelFromMenu(IPluginContext *pContext, const cell_t *params)
543 Handle_t hndl = (Handle_t)params[1];
547 if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
549 return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
552 IMenuPanel *panel = menu->CreatePanel();
553 hndl = MakePanelHandle(panel, pContext);
562 static cell_t GetMenuExitButton(IPluginContext *pContext, const cell_t *params)
564 Handle_t hndl = (Handle_t)params[1];
568 if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
570 return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
573 return menu->GetExitButton() ? 1 : 0;
576 static cell_t SetMenuExitButton(IPluginContext *pContext, const cell_t *params)
578 Handle_t hndl = (Handle_t)params[1];
582 if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
584 return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
587 return menu->SetExitButton(params[2] ? true : false) ? 1 : 0;
590 static cell_t CancelMenu(IPluginContext *pContext, const cell_t *params)
592 Handle_t hndl = (Handle_t)params[1];
596 if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
598 return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
606 static cell_t GetMenuStyle(IPluginContext *pContext, const cell_t *params)
608 Handle_t hndl = (Handle_t)params[1];
612 if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
614 return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
617 return menu->GetDrawStyle()->GetHandle();
620 static cell_t GetMenuStyleHandle(IPluginContext *pContext, const cell_t *params)
622 IMenuStyle *style = GetStyleFromCell(params[1]);
628 return style->GetHandle();
631 static cell_t CreatePanel(IPluginContext *pContext, const cell_t *params)
633 Handle_t hndl = (Handle_t)params[1];
639 if ((err=g_Menus.ReadStyleHandle(params[1], &style)) != HandleError_None)
641 return pContext->ThrowNativeError("MenuStyle handle %x is invalid (error %d)", hndl, err);
644 style = g_Menus.GetDefaultStyle();
647 IMenuPanel *panel = style->CreatePanel();
649 hndl = MakePanelHandle(panel, pContext);
659 static cell_t CreateMenuEx(IPluginContext *pContext, const cell_t *params)
661 Handle_t hndl = (Handle_t)params[1];
667 if ((err=g_Menus.ReadStyleHandle(params[1], &style)) != HandleError_None)
669 return pContext->ThrowNativeError("MenuStyle handle %x is invalid (error %d)", hndl, err);
672 style = g_Menus.GetDefaultStyle();
675 IPluginFunction *pFunction;
676 if ((pFunction=pContext->GetFunctionById(params[2])) == NULL)
678 return pContext->ThrowNativeError("Function id %x is invalid", params[2]);
681 CMenuHandler *handler = g_MenuHelpers.GetMenuHandler(pFunction, params[3]);
683 IBaseMenu *pMenu = style->CreateMenu(handler, pContext->GetIdentity());
684 hndl = pMenu->GetHandle();
694 static cell_t GetClientMenu(IPluginContext *pContext, const cell_t *params)
696 Handle_t hndl = (Handle_t)params[2];
702 if ((err=g_Menus.ReadStyleHandle(params[1], &style)) != HandleError_None)
704 return pContext->ThrowNativeError("MenuStyle handle %x is invalid (error %d)", hndl, err);
707 style = g_Menus.GetDefaultStyle();
710 return style->GetClientMenu(params[1], NULL);
713 static cell_t CancelClientMenu(IPluginContext *pContext, const cell_t *params)
715 Handle_t hndl = (Handle_t)params[3];
721 if ((err=g_Menus.ReadStyleHandle(params[1], &style)) != HandleError_None)
723 return pContext->ThrowNativeError("MenuStyle handle %x is invalid (error %d)", hndl, err);
726 style = g_Menus.GetDefaultStyle();
729 return style->CancelClientMenu(params[1], params[2] ? true : false) ? 1 : 0;
732 static cell_t GetMaxPageItems(IPluginContext *pContext, const cell_t *params)
734 Handle_t hndl = (Handle_t)params[1];
740 if ((err=g_Menus.ReadStyleHandle(params[1], &style)) != HandleError_None)
742 return pContext->ThrowNativeError("MenuStyle handle %x is invalid (error %d)", hndl, err);
745 style = g_Menus.GetDefaultStyle();
748 return style->GetMaxPageItems();
751 static cell_t GetPanelStyle(IPluginContext *pContext, const cell_t *params)
753 Handle_t hndl = (Handle_t)params[1];
757 if ((err=ReadPanelHandle(hndl, &panel)) != HandleError_None)
759 return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
762 return panel->GetParentStyle()->GetHandle();
765 static cell_t SetPanelTitle(IPluginContext *pContext, const cell_t *params)
767 Handle_t hndl = (Handle_t)params[1];
771 if ((err=ReadPanelHandle(hndl, &panel)) != HandleError_None)
773 return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
777 pContext->LocalToString(params[2], &text);
779 panel->DrawTitle(text, params[3] ? true : false);
784 static cell_t DrawPanelItem(IPluginContext *pContext, const cell_t *params)
786 Handle_t hndl = (Handle_t)params[1];
790 if ((err=ReadPanelHandle(hndl, &panel)) != HandleError_None)
792 return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
796 pContext->LocalToString(params[2], (char **)&dr.display);
797 dr.style = params[3];
799 return panel->DrawItem(dr);
802 static cell_t DrawPanelText(IPluginContext *pContext, const cell_t *params)
804 Handle_t hndl = (Handle_t)params[1];
808 if ((err=ReadPanelHandle(hndl, &panel)) != HandleError_None)
810 return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
814 pContext->LocalToString(params[2], &text);
816 return panel->DrawRawLine(text) ? 1 : 0;
819 static cell_t CanPanelDrawFlags(IPluginContext *pContext, const cell_t *params)
821 Handle_t hndl = (Handle_t)params[1];
825 if ((err=ReadPanelHandle(hndl, &panel)) != HandleError_None)
827 return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
830 return panel->CanDrawItem(params[2]);
833 static cell_t SendPanelToClient(IPluginContext *pContext, const cell_t *params)
835 Handle_t hndl = (Handle_t)params[1];
839 if ((err=ReadPanelHandle(hndl, &panel)) != HandleError_None)
841 return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
844 IPluginFunction *pFunction;
845 if ((pFunction=pContext->GetFunctionById(params[3])) == NULL)
847 return pContext->ThrowNativeError("Function id %x is invalid", params[3]);
850 CPanelHandler *handler = g_MenuHelpers.GetPanelHandler(pFunction);
851 if (!panel->SendDisplay(params[2], handler, params[4]))
853 g_MenuHelpers.FreePanelHandler(handler);
859 REGISTER_NATIVES(menuNatives)
861 {"AddMenuItem", AddMenuItem},
862 {"CanPanelDrawFlags", CanPanelDrawFlags},
863 {"CancelClientMenu", CancelClientMenu},
864 {"CancelMenu", CancelMenu},
865 {"CreateMenu", CreateMenu},
866 {"CreateMenuEx", CreateMenuEx},
867 {"CreatePanel", CreatePanel},
868 {"CreatePanelFromMenu", CreatePanelFromMenu},\
869 {"DisplayMenu", DisplayMenu},
870 {"DrawPanelItem", DrawPanelItem},
871 {"DrawPanelText", DrawPanelText},
872 {"GetClientMenu", GetClientMenu},
873 {"GetMaxPageItems", GetMaxPageItems},
874 {"GetMenuExitButton", GetMenuExitButton},
875 {"GetMenuItem", GetMenuItem},
876 {"GetMenuItemCount", GetMenuItemCount},
877 {"GetMenuPagination", GetMenuPagination},
878 {"GetMenuStyle", GetMenuStyle},
879 {"GetMenuStyleHandle", GetMenuStyleHandle},
880 {"GetPanelStyle", GetPanelStyle},
881 {"InsertMenuItem", InsertMenuItem},
882 {"RemoveAllMenuItems", RemoveAllMenuItems},
883 {"RemoveMenuItem", RemoveMenuItem},
884 {"SendPanelToClient", SendPanelToClient},
885 {"SetMenuExitButton", SetMenuExitButton},
886 {"SetMenuPagination", SetMenuPagination},
887 {"SetMenuTitle", SetMenuTitle},
888 {"SetPanelTitle", SetPanelTitle},