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) */
41 MenuAction_VoteStart = (1<<6), /**< (VOTE ONLY): A vote sequence has started */
42 MenuAction_VoteCancel = (1<<7), /**< (VOTE ONLY): A vote sequence has been cancelled (nothing passed) */
45 class CPanelHandler : public IMenuHandler
47 friend class MenuNativeHelpers;
52 void OnMenuCancel(IBaseMenu *menu, int client, MenuCancelReason reason);
53 void OnMenuSelect(IBaseMenu *menu, int client, unsigned int item);
55 IPluginFunction *m_pFunc;
59 class CMenuHandler : public IMenuHandler
61 friend class MenuNativeHelpers;
63 CMenuHandler(IPluginFunction *pBasic, int flags);
65 void OnMenuStart(IBaseMenu *menu);
66 void OnMenuDisplay(IBaseMenu *menu, int client, IMenuPanel *display);
67 void OnMenuSelect(IBaseMenu *menu, int client, unsigned int item);
68 void OnMenuCancel(IBaseMenu *menu, int client, MenuCancelReason reason);
69 void OnMenuEnd(IBaseMenu *menu);
70 void OnMenuDestroy(IBaseMenu *menu);
71 void OnMenuVoteStart(IBaseMenu *menu);
72 void OnMenuVoteEnd(IBaseMenu *menu, unsigned int item);
73 void OnMenuVoteCancel(IBaseMenu *menu);
75 void OnMenuDrawItem(IBaseMenu *menu, int client, unsigned int item, unsigned int &style);
76 void OnMenuDisplayItem(IBaseMenu *menu, int client, unsigned int item, const char **display);
79 void DoAction(IBaseMenu *menu, MenuAction action, cell_t param1, cell_t param2);
81 IPluginFunction *m_pBasic;
86 * GLOBAL CLASS FOR HELPERS
89 class MenuNativeHelpers :
91 public IHandleTypeDispatch,
92 public IPluginsListener
95 virtual void OnSourceModAllInitialized()
97 m_PanelType = g_HandleSys.CreateType("IMenuPanel", this, 0, NULL, NULL, g_pCoreIdent, NULL);
98 g_PluginSys.AddPluginsListener(this);
101 virtual void OnSourceModShutdown()
103 g_HandleSys.RemoveType(m_PanelType, g_pCoreIdent);
105 while (!m_FreePanelHandlers.empty())
107 delete m_FreePanelHandlers.front();
108 m_FreePanelHandlers.pop();
111 while (!m_FreeMenuHandlers.empty())
113 delete m_FreeMenuHandlers.front();
114 m_FreeMenuHandlers.pop();
118 virtual void OnHandleDestroy(HandleType_t type, void *object)
120 IMenuPanel *panel = (IMenuPanel *)object;
125 * It is extremely important that unloaded plugins don't crash.
126 * Thus, if a plugin unloads, we run through every handler we have.
127 * This means we do almost no runtime work for keeping track of
128 * our panel handlers (we don't have to store a list of the running
129 * ones), but when push comes to shove, we have to scan them all
130 * in case any of them are active.
132 virtual void OnPluginUnloaded(IPlugin *plugin)
134 for (size_t i = 0; i < m_PanelHandlers.size(); i++)
136 if (m_PanelHandlers[i]->m_pPlugin == plugin)
138 m_PanelHandlers[i]->m_pPlugin = NULL;
139 m_PanelHandlers[i]->m_pFunc = NULL;
144 inline HandleType_t GetPanelType()
149 CPanelHandler *GetPanelHandler(IPluginFunction *pFunction)
151 CPanelHandler *handler;
152 if (m_FreePanelHandlers.empty())
154 handler = new CPanelHandler;
155 m_PanelHandlers.push_back(handler);
157 handler = m_FreePanelHandlers.front();
158 m_FreePanelHandlers.pop();
160 handler->m_pFunc = pFunction;
161 handler->m_pPlugin = g_PluginSys.GetPluginByCtx(pFunction->GetParentContext()->GetContext());
165 void FreePanelHandler(CPanelHandler *handler)
167 handler->m_pFunc = NULL;
168 handler->m_pPlugin = NULL;
169 m_FreePanelHandlers.push(handler);
172 CMenuHandler *GetMenuHandler(IPluginFunction *pFunction, int flags)
174 CMenuHandler *handler;
175 if (m_FreeMenuHandlers.empty())
177 handler = new CMenuHandler(pFunction, flags);
179 handler = m_FreeMenuHandlers.front();
180 m_FreeMenuHandlers.pop();
181 handler->m_pBasic = pFunction;
182 handler->m_Flags = flags;
187 void FreeMenuHandler(CMenuHandler *handler)
189 m_FreeMenuHandlers.push(handler);
193 HandleType_t m_PanelType;
194 CStack<CPanelHandler *> m_FreePanelHandlers;
195 CStack<CMenuHandler *> m_FreeMenuHandlers;
196 CVector<CPanelHandler *> m_PanelHandlers;
200 * BASIC PANEL HANDLER WRAPPER
203 void CPanelHandler::OnMenuCancel(IBaseMenu *menu, int client, MenuCancelReason reason)
207 m_pFunc->PushCell(BAD_HANDLE);
208 m_pFunc->PushCell(MenuAction_Cancel);
209 m_pFunc->PushCell(client);
210 m_pFunc->PushCell(reason);
211 m_pFunc->Execute(NULL);
213 g_MenuHelpers.FreePanelHandler(this);
216 void CPanelHandler::OnMenuSelect(IBaseMenu *menu, int client, unsigned int item)
220 m_pFunc->PushCell(BAD_HANDLE);
221 m_pFunc->PushCell(MenuAction_Select);
222 m_pFunc->PushCell(client);
223 m_pFunc->PushCell(item);
224 m_pFunc->Execute(NULL);
226 g_MenuHelpers.FreePanelHandler(this);
230 * MENU HANDLER WRAPPER
232 CMenuHandler::CMenuHandler(IPluginFunction *pBasic, int flags) :
233 m_pBasic(pBasic), m_Flags(flags)
235 /* :TODO: We can probably cache the handle ahead of time */
238 void CMenuHandler::OnMenuStart(IBaseMenu *menu)
240 if ((m_Flags & (int)MenuAction_Start) == (int)MenuAction_Start)
242 DoAction(menu, MenuAction_Start, 0, 0);
246 void CMenuHandler::OnMenuDisplay(IBaseMenu *menu, int client, IMenuPanel *panel)
248 if ((m_Flags & (int)MenuAction_Display) == (int)MenuAction_Display)
251 sec.pIdentity = m_pBasic->GetParentContext()->GetIdentity();
252 sec.pOwner = g_pCoreIdent;
255 g_HandleSys.InitAccessDefaults(NULL, &access);
256 access.access[HandleAccess_Delete] = HANDLE_RESTRICT_IDENTITY|HANDLE_RESTRICT_OWNER;
258 Handle_t hndl = g_HandleSys.CreateHandleEx(g_MenuHelpers.GetPanelType(), panel, &sec, &access, NULL);
260 DoAction(menu, MenuAction_Display, client, hndl);
262 g_HandleSys.FreeHandle(hndl, &sec);
266 void CMenuHandler::OnMenuSelect(IBaseMenu *menu, int client, unsigned int item)
268 DoAction(menu, MenuAction_Select, client, item);
271 void CMenuHandler::OnMenuCancel(IBaseMenu *menu, int client, MenuCancelReason reason)
273 DoAction(menu, MenuAction_Cancel, client, (cell_t)reason);
276 void CMenuHandler::OnMenuEnd(IBaseMenu *menu)
278 DoAction(menu, MenuAction_End, 0, 0);
281 void CMenuHandler::OnMenuDestroy(IBaseMenu *menu)
283 g_MenuHelpers.FreeMenuHandler(this);
286 void CMenuHandler::OnMenuVoteStart(IBaseMenu *menu)
288 DoAction(menu, MenuAction_VoteStart, 0, 0);
291 void CMenuHandler::OnMenuVoteEnd(IBaseMenu *menu, unsigned int item)
293 DoAction(menu, MenuAction_VoteEnd, item, 0);
296 void CMenuHandler::OnMenuVoteCancel(IBaseMenu *menu)
298 DoAction(menu, MenuAction_VoteCancel, 0, 0);
301 void CMenuHandler::DoAction(IBaseMenu *menu, MenuAction action, cell_t param1, cell_t param2)
303 m_pBasic->PushCell(menu->GetHandle());
304 m_pBasic->PushCell((cell_t)action);
305 m_pBasic->PushCell(param1);
306 m_pBasic->PushCell(param2);
307 m_pBasic->Execute(NULL);
311 * INLINE FUNCTIONS FOR NATIVES
314 inline Handle_t MakePanelHandle(IMenuPanel *panel, IPluginContext *pContext)
316 return g_HandleSys.CreateHandle(g_MenuHelpers.GetPanelType(), panel, pContext->GetIdentity(), g_pCoreIdent, NULL);
319 inline HandleError ReadPanelHandle(Handle_t hndl, IMenuPanel **panel)
322 sec.pIdentity = g_pCoreIdent;
324 return g_HandleSys.ReadHandle(hndl, g_MenuHelpers.GetPanelType(), &sec, (void **)panel);
327 inline IMenuStyle *GetStyleFromCell(cell_t cell)
331 MenuStyle_Default = 0, /**< The "default" menu style for the mod */
332 MenuStyle_Valve = 1, /**< The Valve provided menu style (Used on HL2DM) */
333 MenuStyle_Radio = 2, /**< The simpler menu style commonly used on CS:S */
336 if (cell == MenuStyle_Valve)
338 return &g_ValveMenuStyle;
339 } else if (cell == MenuStyle_Radio
340 && g_RadioMenuStyle.IsSupported())
342 return &g_RadioMenuStyle;
345 return g_Menus.GetDefaultStyle();
348 /***********************************
349 **** NATIVE DEFINITIONS ***********
350 ***********************************/
352 static cell_t CreateMenu(IPluginContext *pContext, const cell_t *params)
354 IMenuStyle *style = g_Menus.GetDefaultStyle();
355 IPluginFunction *pFunction;
357 if ((pFunction=pContext->GetFunctionById(params[1])) == NULL)
359 return pContext->ThrowNativeError("Function id %x is invalid", params[1]);
362 CMenuHandler *handler = g_MenuHelpers.GetMenuHandler(pFunction, params[2]);
363 IBaseMenu *menu = style->CreateMenu(handler, pContext->GetIdentity());
365 Handle_t hndl = menu->GetHandle();
375 static cell_t DisplayMenu(IPluginContext *pContext, const cell_t *params)
377 Handle_t hndl = (Handle_t)params[1];
381 if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
383 return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
386 return menu->Display(params[2], params[3]) ? 1 : 0;
389 static cell_t VoteMenu(IPluginContext *pContext, const cell_t *params)
391 Handle_t hndl = (Handle_t)params[1];
395 if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
397 return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
401 pContext->LocalToPhysAddr(params[2], &addr);
403 return menu->BroadcastVote(addr, params[3], params[4]) ? 1 : 0;
406 static cell_t AddMenuItem(IPluginContext *pContext, const cell_t *params)
408 Handle_t hndl = (Handle_t)params[1];
412 if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
414 return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
420 pContext->LocalToString(params[2], &info);
421 pContext->LocalToString(params[3], (char **)&dr.display);
422 dr.style = params[4];
424 return menu->AppendItem(info, dr) ? 1 : 0;
427 static cell_t InsertMenuItem(IPluginContext *pContext, const cell_t *params)
429 Handle_t hndl = (Handle_t)params[1];
433 if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
435 return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
441 pContext->LocalToString(params[3], &info);
442 pContext->LocalToString(params[4], (char **)&dr.display);
443 dr.style = params[5];
445 return menu->InsertItem(params[2], info, dr) ? 1 : 0;
448 static cell_t RemoveMenuItem(IPluginContext *pContext, const cell_t *params)
450 Handle_t hndl = (Handle_t)params[1];
454 if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
456 return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
459 return menu->RemoveItem(params[2]) ? 1 : 0;
462 static cell_t RemoveAllMenuItems(IPluginContext *pContext, const cell_t *params)
464 Handle_t hndl = (Handle_t)params[1];
468 if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
470 return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
473 menu->RemoveAllItems();
478 static cell_t GetMenuItem(IPluginContext *pContext, const cell_t *params)
480 Handle_t hndl = (Handle_t)params[1];
484 if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
486 return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
492 if ((info=menu->GetItemInfo(params[2], &dr)) == NULL)
497 pContext->StringToLocalUTF8(params[3], params[4], info, NULL);
498 pContext->StringToLocalUTF8(params[6], params[7], dr.display ? dr.display : "", NULL);
501 pContext->LocalToPhysAddr(params[5], &addr);
507 static cell_t SetMenuPagination(IPluginContext *pContext, const cell_t *params)
509 Handle_t hndl = (Handle_t)params[1];
513 if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
515 return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
518 return menu->SetPagination(params[2]) ? 1 : 0;
521 static cell_t GetMenuPagination(IPluginContext *pContext, const cell_t *params)
523 Handle_t hndl = (Handle_t)params[1];
527 if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
529 return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
532 return menu->GetPagination();
535 static cell_t GetMenuItemCount(IPluginContext *pContext, const cell_t *params)
537 Handle_t hndl = (Handle_t)params[1];
541 if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
543 return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
546 return menu->GetItemCount();
549 static cell_t SetMenuTitle(IPluginContext *pContext, const cell_t *params)
551 Handle_t hndl = (Handle_t)params[1];
555 if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
557 return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
561 g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
563 menu->SetDefaultTitle(buffer);
568 static cell_t CreatePanelFromMenu(IPluginContext *pContext, const cell_t *params)
570 Handle_t hndl = (Handle_t)params[1];
574 if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
576 return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
579 IMenuPanel *panel = menu->CreatePanel();
580 hndl = MakePanelHandle(panel, pContext);
589 static cell_t GetMenuExitButton(IPluginContext *pContext, const cell_t *params)
591 Handle_t hndl = (Handle_t)params[1];
595 if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
597 return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
600 return menu->GetExitButton() ? 1 : 0;
603 static cell_t SetMenuExitButton(IPluginContext *pContext, const cell_t *params)
605 Handle_t hndl = (Handle_t)params[1];
609 if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
611 return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
614 return menu->SetExitButton(params[2] ? true : false) ? 1 : 0;
617 static cell_t CancelMenu(IPluginContext *pContext, const cell_t *params)
619 Handle_t hndl = (Handle_t)params[1];
623 if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
625 return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
633 static cell_t IsVoteInProgress(IPluginContext *pContext, const cell_t *params)
635 Handle_t hndl = (Handle_t)params[1];
639 if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
641 return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
644 return menu->IsVoteInProgress() ? 1 : 0;
647 static cell_t GetMenuStyle(IPluginContext *pContext, const cell_t *params)
649 Handle_t hndl = (Handle_t)params[1];
653 if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
655 return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
658 return menu->GetDrawStyle()->GetHandle();
661 static cell_t GetMenuStyleHandle(IPluginContext *pContext, const cell_t *params)
663 IMenuStyle *style = GetStyleFromCell(params[1]);
669 return style->GetHandle();
672 static cell_t CreatePanel(IPluginContext *pContext, const cell_t *params)
674 Handle_t hndl = (Handle_t)params[1];
680 if ((err=g_Menus.ReadStyleHandle(params[1], &style)) != HandleError_None)
682 return pContext->ThrowNativeError("MenuStyle handle %x is invalid (error %d)", hndl, err);
685 style = g_Menus.GetDefaultStyle();
688 IMenuPanel *panel = style->CreatePanel();
690 hndl = MakePanelHandle(panel, pContext);
700 static cell_t CreateMenuEx(IPluginContext *pContext, const cell_t *params)
702 Handle_t hndl = (Handle_t)params[1];
708 if ((err=g_Menus.ReadStyleHandle(params[1], &style)) != HandleError_None)
710 return pContext->ThrowNativeError("MenuStyle handle %x is invalid (error %d)", hndl, err);
713 style = g_Menus.GetDefaultStyle();
716 IPluginFunction *pFunction;
717 if ((pFunction=pContext->GetFunctionById(params[2])) == NULL)
719 return pContext->ThrowNativeError("Function id %x is invalid", params[2]);
722 CMenuHandler *handler = g_MenuHelpers.GetMenuHandler(pFunction, params[3]);
724 IBaseMenu *pMenu = style->CreateMenu(handler, pContext->GetIdentity());
725 hndl = pMenu->GetHandle();
735 static cell_t GetClientMenu(IPluginContext *pContext, const cell_t *params)
737 Handle_t hndl = (Handle_t)params[2];
743 if ((err=g_Menus.ReadStyleHandle(params[1], &style)) != HandleError_None)
745 return pContext->ThrowNativeError("MenuStyle handle %x is invalid (error %d)", hndl, err);
748 style = g_Menus.GetDefaultStyle();
751 return style->GetClientMenu(params[1], NULL);
754 static cell_t CancelClientMenu(IPluginContext *pContext, const cell_t *params)
756 Handle_t hndl = (Handle_t)params[3];
762 if ((err=g_Menus.ReadStyleHandle(params[1], &style)) != HandleError_None)
764 return pContext->ThrowNativeError("MenuStyle handle %x is invalid (error %d)", hndl, err);
767 style = g_Menus.GetDefaultStyle();
770 return style->CancelClientMenu(params[1], params[2] ? true : false) ? 1 : 0;
773 static cell_t GetMaxPageItems(IPluginContext *pContext, const cell_t *params)
775 Handle_t hndl = (Handle_t)params[1];
781 if ((err=g_Menus.ReadStyleHandle(params[1], &style)) != HandleError_None)
783 return pContext->ThrowNativeError("MenuStyle handle %x is invalid (error %d)", hndl, err);
786 style = g_Menus.GetDefaultStyle();
789 return style->GetMaxPageItems();
792 static cell_t GetPanelStyle(IPluginContext *pContext, const cell_t *params)
794 Handle_t hndl = (Handle_t)params[1];
798 if ((err=ReadPanelHandle(hndl, &panel)) != HandleError_None)
800 return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
803 return panel->GetParentStyle()->GetHandle();
806 static cell_t SetPanelTitle(IPluginContext *pContext, const cell_t *params)
808 Handle_t hndl = (Handle_t)params[1];
812 if ((err=ReadPanelHandle(hndl, &panel)) != HandleError_None)
814 return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
818 pContext->LocalToString(params[2], &text);
820 panel->DrawTitle(text, params[3] ? true : false);
825 static cell_t DrawPanelItem(IPluginContext *pContext, const cell_t *params)
827 Handle_t hndl = (Handle_t)params[1];
831 if ((err=ReadPanelHandle(hndl, &panel)) != HandleError_None)
833 return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
837 pContext->LocalToString(params[2], (char **)&dr.display);
838 dr.style = params[3];
840 return panel->DrawItem(dr);
843 static cell_t DrawPanelText(IPluginContext *pContext, const cell_t *params)
845 Handle_t hndl = (Handle_t)params[1];
849 if ((err=ReadPanelHandle(hndl, &panel)) != HandleError_None)
851 return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
855 pContext->LocalToString(params[2], &text);
857 return panel->DrawRawLine(text) ? 1 : 0;
860 static cell_t CanPanelDrawFlags(IPluginContext *pContext, const cell_t *params)
862 Handle_t hndl = (Handle_t)params[1];
866 if ((err=ReadPanelHandle(hndl, &panel)) != HandleError_None)
868 return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
871 return panel->CanDrawItem(params[2]);
874 static cell_t SendPanelToClient(IPluginContext *pContext, const cell_t *params)
876 Handle_t hndl = (Handle_t)params[1];
880 if ((err=ReadPanelHandle(hndl, &panel)) != HandleError_None)
882 return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
885 IPluginFunction *pFunction;
886 if ((pFunction=pContext->GetFunctionById(params[3])) == NULL)
888 return pContext->ThrowNativeError("Function id %x is invalid", params[3]);
891 CPanelHandler *handler = g_MenuHelpers.GetPanelHandler(pFunction);
892 if (!panel->SendDisplay(params[2], handler, params[4]))
894 g_MenuHelpers.FreePanelHandler(handler);
900 static cell_t SetPanelKeys(IPluginContext *pContext, const cell_t *params)
902 Handle_t hndl = (Handle_t)params[1];
906 if ((err=ReadPanelHandle(hndl, &panel)) != HandleError_None)
908 return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
911 return panel->SetSelectableKeys(params[2]);
914 static cell_t GetPanelCurrentKey(IPluginContext *pContext, const cell_t *params)
916 Handle_t hndl = (Handle_t)params[1];
920 if ((err=ReadPanelHandle(hndl, &panel)) != HandleError_None)
922 return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
925 return panel->GetCurrentKey();
928 static cell_t SetPanelCurrentKey(IPluginContext *pContext, const cell_t *params)
930 Handle_t hndl = (Handle_t)params[1];
934 if ((err=ReadPanelHandle(hndl, &panel)) != HandleError_None)
936 return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
939 return panel->SetCurrentKey(params[2]) ? 1 : 0;
942 REGISTER_NATIVES(menuNatives)
944 {"AddMenuItem", AddMenuItem},
945 {"CanPanelDrawFlags", CanPanelDrawFlags},
946 {"CancelClientMenu", CancelClientMenu},
947 {"CancelMenu", CancelMenu},
948 {"CreateMenu", CreateMenu},
949 {"CreateMenuEx", CreateMenuEx},
950 {"CreatePanel", CreatePanel},
951 {"CreatePanelFromMenu", CreatePanelFromMenu},
952 {"DisplayMenu", DisplayMenu},
953 {"DrawPanelItem", DrawPanelItem},
954 {"DrawPanelText", DrawPanelText},
955 {"GetClientMenu", GetClientMenu},
956 {"GetMaxPageItems", GetMaxPageItems},
957 {"GetMenuExitButton", GetMenuExitButton},
958 {"GetMenuItem", GetMenuItem},
959 {"GetMenuItemCount", GetMenuItemCount},
960 {"GetMenuPagination", GetMenuPagination},
961 {"GetMenuStyle", GetMenuStyle},
962 {"GetMenuStyleHandle", GetMenuStyleHandle},
963 {"GetPanelCurrentKey", GetPanelCurrentKey},
964 {"GetPanelStyle", GetPanelStyle},
965 {"InsertMenuItem", InsertMenuItem},
966 {"IsVoteInProgress", IsVoteInProgress},
967 {"RemoveAllMenuItems", RemoveAllMenuItems},
968 {"RemoveMenuItem", RemoveMenuItem},
969 {"SendPanelToClient", SendPanelToClient},
970 {"SetMenuExitButton", SetMenuExitButton},
971 {"SetMenuPagination", SetMenuPagination},
972 {"SetMenuTitle", SetMenuTitle},
973 {"SetPanelCurrentKey", SetPanelCurrentKey},
974 {"SetPanelTitle", SetPanelTitle},
975 {"SetPanelKeys", SetPanelKeys},
976 {"VoteMenu", VoteMenu},