core/smn_menus.cpp
author Scott Ehlert <ds@alliedmods.net>
Wed Aug 15 06:19:30 2007 +0000 (2007-08-15)
changeset 1330 ab94316bb52b
parent 1296 0197a1212cb8
child 1361 591f6d2fd11d
permissions -rw-r--r--
Updated license headers on virtually all files with extremely minor changes in the name of some sort of strange consistency.
All plugin and include file headers also have been changed to say about GPL3 instead of GPL2.

(This day shall henceforth be known as the Eighty Column Massacre of '07)
dvander@790
     1
/**
dvander@790
     2
 * vim: set ts=4 :
ds@1330
     3
 * =============================================================================
dvander@1231
     4
 * SourceMod
dvander@1231
     5
 * Copyright (C) 2004-2007 AlliedModders LLC.  All rights reserved.
ds@1330
     6
 * =============================================================================
dvander@790
     7
 *
ds@1330
     8
 * This program is free software; you can redistribute it and/or modify it under
ds@1330
     9
 * the terms of the GNU General Public License, version 3.0, as published by the
ds@1330
    10
 * Free Software Foundation.
dvander@1231
    11
 * 
ds@1330
    12
 * This program is distributed in the hope that it will be useful, but WITHOUT
ds@1330
    13
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
ds@1330
    14
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
ds@1330
    15
 * details.
dvander@1231
    16
 *
ds@1330
    17
 * You should have received a copy of the GNU General Public License along with
ds@1330
    18
 * this program.  If not, see <http://www.gnu.org/licenses/>.
dvander@1231
    19
 *
ds@1330
    20
 * As a special exception, AlliedModders LLC gives you permission to link the
ds@1330
    21
 * code of this program (as well as its derivative works) to "Half-Life 2," the
ds@1330
    22
 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
ds@1330
    23
 * by the Valve Corporation.  You must obey the GNU General Public License in
ds@1330
    24
 * all respects for all other code used.  Additionally, AlliedModders LLC grants
ds@1330
    25
 * this exception to all derivative works.  AlliedModders LLC defines further
ds@1330
    26
 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
ds@1330
    27
 * or <http://www.sourcemod.net/license.php>.
dvander@790
    28
 *
dvander@790
    29
 * Version: $Id$
dvander@790
    30
 */
dvander@790
    31
dvander@790
    32
#include "sm_globals.h"
dvander@790
    33
#include <sh_stack.h>
dvander@1269
    34
#include "DebugReporter.h"
dvander@790
    35
#include "MenuManager.h"
dvander@790
    36
#include "MenuStyle_Valve.h"
dvander@790
    37
#include "MenuStyle_Radio.h"
dvander@790
    38
#include "HandleSys.h"
dvander@790
    39
#include "PluginSys.h"
dvander@1011
    40
#include "sm_stringutil.h"
dvander@1291
    41
#include "sourcemm_api.h"
dvander@970
    42
#if defined MENU_DEBUG
dvander@970
    43
#include "Logger.h"
dvander@970
    44
#endif
dvander@790
    45
dvander@790
    46
#if defined CreateMenu
dvander@790
    47
#undef CreateMenu
dvander@790
    48
#endif
dvander@790
    49
dvander@790
    50
/**
dvander@790
    51
 * And God said, "let there be menus," and behold, there were menus.  
dvander@790
    52
 * God saw the menus and they were good.  And the evening and the morning
dvander@790
    53
 * were the third day.
dvander@790
    54
 */
dvander@790
    55
dvander@790
    56
enum MenuAction
dvander@790
    57
{
dvander@790
    58
	MenuAction_Start = (1<<0),		/**< A menu has been started (nothing passed) */
dvander@790
    59
	MenuAction_Display = (1<<1),	/**< A menu is about to be displayed (param1=client, param2=MenuPanel Handle) */
dvander@790
    60
	MenuAction_Select = (1<<2),		/**< An item was selected (param1=client, param2=item) */
dvander@790
    61
	MenuAction_Cancel = (1<<3),		/**< The menu was cancelled (param1=client, param2=item) */
dvander@790
    62
	MenuAction_End = (1<<4),		/**< A menu's display/selection cycle is complete (nothing passed). */
dvander@790
    63
	MenuAction_VoteEnd = (1<<5),	/**< (VOTE ONLY): A vote sequence has ended (param1=chosen item) */
dvander@878
    64
	MenuAction_VoteStart = (1<<6), 	/**< (VOTE ONLY): A vote sequence has started */
dvander@885
    65
	MenuAction_VoteCancel = (1<<7),	/**< (VOTE ONLY): A vote sequence has been cancelled (nothing passed) */
dvander@1006
    66
	MenuAction_DrawItem = (1<<8),	/**< A style is being drawn; return the new style (param1=client, param2=item) */
dvander@1163
    67
	MenuAction_DisplayItem = (1<<9),	/**< the odd duck */
dvander@790
    68
};
dvander@790
    69
dvander@790
    70
class CPanelHandler : public IMenuHandler
dvander@790
    71
{
dvander@790
    72
	friend class MenuNativeHelpers;
dvander@790
    73
public:
dvander@790
    74
	CPanelHandler()
dvander@790
    75
	{
dvander@790
    76
	}
dvander@790
    77
	void OnMenuCancel(IBaseMenu *menu, int client, MenuCancelReason reason);
dvander@790
    78
	void OnMenuSelect(IBaseMenu *menu, int client, unsigned int item);
dvander@790
    79
private:
dvander@790
    80
	IPluginFunction *m_pFunc;
dvander@790
    81
	IPlugin *m_pPlugin;
dvander@790
    82
};
dvander@790
    83
dvander@790
    84
class CMenuHandler : public IMenuHandler
dvander@790
    85
{
dvander@790
    86
	friend class MenuNativeHelpers;
dvander@790
    87
public:
dvander@790
    88
	CMenuHandler(IPluginFunction *pBasic, int flags);
dvander@790
    89
public:
dvander@790
    90
	void OnMenuStart(IBaseMenu *menu);
dvander@790
    91
	void OnMenuDisplay(IBaseMenu *menu, int client, IMenuPanel *display);
dvander@790
    92
	void OnMenuSelect(IBaseMenu *menu, int client, unsigned int item);
dvander@790
    93
	void OnMenuCancel(IBaseMenu *menu, int client, MenuCancelReason reason);
dvander@997
    94
	void OnMenuEnd(IBaseMenu *menu, MenuEndReason reason);
dvander@790
    95
	void OnMenuDestroy(IBaseMenu *menu);
dvander@878
    96
	void OnMenuVoteStart(IBaseMenu *menu);
dvander@1269
    97
	void OnMenuVoteResults(IBaseMenu *menu, const menu_vote_result_t *results);
dvander@1296
    98
	void OnMenuVoteCancel(IBaseMenu *menu, VoteCancelReason reason);
dvander@1006
    99
	void OnMenuDrawItem(IBaseMenu *menu, int client, unsigned int item, unsigned int &style);
dvander@1163
   100
	unsigned int OnMenuDisplayItem(IBaseMenu *menu, int client, IMenuPanel *panel, unsigned int item, const ItemDrawInfo &dr);
dvander@1269
   101
	bool OnSetHandlerOption(const char *option, const void *data);
dvander@790
   102
#if 0
dvander@790
   103
	void OnMenuDrawItem(IBaseMenu *menu, int client, unsigned int item, unsigned int &style);
dvander@790
   104
	void OnMenuDisplayItem(IBaseMenu *menu, int client, unsigned int item, const char **display);
dvander@790
   105
#endif
dvander@790
   106
private:
dvander@1006
   107
	cell_t DoAction(IBaseMenu *menu, MenuAction action, cell_t param1, cell_t param2, cell_t def_res=0);
dvander@878
   108
private:
dvander@790
   109
	IPluginFunction *m_pBasic;
dvander@790
   110
	int m_Flags;
dvander@1269
   111
	IPluginFunction *m_pVoteResults;
dvander@1269
   112
	cell_t m_fnVoteResult;
dvander@790
   113
};
dvander@790
   114
dvander@790
   115
/**
dvander@790
   116
 * GLOBAL CLASS FOR HELPERS
dvander@790
   117
 */
dvander@790
   118
dvander@790
   119
class MenuNativeHelpers : 
dvander@790
   120
	public SMGlobalClass,
dvander@790
   121
	public IHandleTypeDispatch,
dvander@790
   122
	public IPluginsListener
dvander@790
   123
{
dvander@790
   124
public:
dvander@790
   125
	virtual void OnSourceModAllInitialized()
dvander@790
   126
	{
dvander@790
   127
		m_PanelType = g_HandleSys.CreateType("IMenuPanel", this, 0, NULL, NULL, g_pCoreIdent, NULL);
dvander@1163
   128
		m_TempPanelType = g_HandleSys.CreateType("TempIMenuPanel", this, m_PanelType, NULL, NULL, g_pCoreIdent, NULL);
dvander@790
   129
		g_PluginSys.AddPluginsListener(this);
dvander@790
   130
	}
dvander@790
   131
dvander@790
   132
	virtual void OnSourceModShutdown()
dvander@790
   133
	{
dvander@1163
   134
		g_HandleSys.RemoveType(m_TempPanelType, g_pCoreIdent);
dvander@790
   135
		g_HandleSys.RemoveType(m_PanelType, g_pCoreIdent);
dvander@790
   136
dvander@790
   137
		while (!m_FreePanelHandlers.empty())
dvander@790
   138
		{
dvander@790
   139
			delete m_FreePanelHandlers.front();
dvander@790
   140
			m_FreePanelHandlers.pop();
dvander@790
   141
		}
dvander@790
   142
dvander@790
   143
		while (!m_FreeMenuHandlers.empty())
dvander@790
   144
		{
dvander@790
   145
			delete m_FreeMenuHandlers.front();
dvander@790
   146
			m_FreeMenuHandlers.pop();
dvander@790
   147
		}
dvander@790
   148
	}
dvander@790
   149
dvander@790
   150
	virtual void OnHandleDestroy(HandleType_t type, void *object)
dvander@790
   151
	{
dvander@1163
   152
		if (type == m_TempPanelType)
dvander@1163
   153
		{
dvander@1163
   154
			return;
dvander@1163
   155
		}
dvander@1163
   156
dvander@790
   157
		IMenuPanel *panel = (IMenuPanel *)object;
dvander@790
   158
		panel->DeleteThis();
dvander@790
   159
	}
dvander@790
   160
dvander@790
   161
	/**
dvander@1269
   162
	 * It is extremely important that unloaded plugins don't crash.
dvander@790
   163
	 * Thus, if a plugin unloads, we run through every handler we have.
dvander@790
   164
	 * This means we do almost no runtime work for keeping track of
dvander@790
   165
	 * our panel handlers (we don't have to store a list of the running 
dvander@790
   166
	 * ones), but when push comes to shove, we have to scan them all
dvander@790
   167
	 * in case any of them are active.
dvander@790
   168
	 */
dvander@790
   169
	virtual void OnPluginUnloaded(IPlugin *plugin)
dvander@790
   170
	{
dvander@790
   171
		for (size_t i = 0; i < m_PanelHandlers.size(); i++)
dvander@790
   172
		{
dvander@790
   173
			if (m_PanelHandlers[i]->m_pPlugin == plugin)
dvander@790
   174
			{
dvander@790
   175
				m_PanelHandlers[i]->m_pPlugin = NULL;
dvander@790
   176
				m_PanelHandlers[i]->m_pFunc = NULL;
dvander@790
   177
			}
dvander@790
   178
		}
dvander@790
   179
	}
dvander@790
   180
dvander@790
   181
	inline HandleType_t GetPanelType()
dvander@790
   182
	{
dvander@790
   183
		return m_PanelType;
dvander@790
   184
	}
dvander@790
   185
dvander@1163
   186
	inline HandleType_t GetTempPanelType()
dvander@1163
   187
	{
dvander@1163
   188
		return m_TempPanelType;
dvander@1163
   189
	}
dvander@1163
   190
dvander@790
   191
	CPanelHandler *GetPanelHandler(IPluginFunction *pFunction)
dvander@790
   192
	{
dvander@790
   193
		CPanelHandler *handler;
dvander@790
   194
		if (m_FreePanelHandlers.empty())
dvander@790
   195
		{
dvander@790
   196
			handler = new CPanelHandler;
dvander@790
   197
			m_PanelHandlers.push_back(handler);
dvander@790
   198
		} else {
dvander@790
   199
			handler = m_FreePanelHandlers.front();
dvander@790
   200
			m_FreePanelHandlers.pop();
dvander@790
   201
		}
dvander@790
   202
		handler->m_pFunc = pFunction;
dvander@790
   203
		handler->m_pPlugin = g_PluginSys.GetPluginByCtx(pFunction->GetParentContext()->GetContext());
dvander@790
   204
		return handler;
dvander@790
   205
	}
dvander@790
   206
dvander@790
   207
	void FreePanelHandler(CPanelHandler *handler)
dvander@790
   208
	{
dvander@790
   209
		handler->m_pFunc = NULL;
dvander@790
   210
		handler->m_pPlugin = NULL;
dvander@790
   211
		m_FreePanelHandlers.push(handler);
dvander@790
   212
	}
dvander@790
   213
dvander@790
   214
	CMenuHandler *GetMenuHandler(IPluginFunction *pFunction, int flags)
dvander@790
   215
	{
dvander@790
   216
		CMenuHandler *handler;
dvander@790
   217
		if (m_FreeMenuHandlers.empty())
dvander@790
   218
		{
dvander@790
   219
			handler = new CMenuHandler(pFunction, flags);
dvander@790
   220
		} else {
dvander@790
   221
			handler = m_FreeMenuHandlers.front();
dvander@790
   222
			m_FreeMenuHandlers.pop();
dvander@790
   223
			handler->m_pBasic = pFunction;
dvander@790
   224
			handler->m_Flags = flags;
dvander@1269
   225
			handler->m_pVoteResults = NULL;
dvander@790
   226
		}
dvander@790
   227
		return handler;
dvander@790
   228
	}
dvander@790
   229
dvander@790
   230
	void FreeMenuHandler(CMenuHandler *handler)
dvander@790
   231
	{
dvander@790
   232
		m_FreeMenuHandlers.push(handler);
dvander@790
   233
	}
dvander@790
   234
dvander@790
   235
private:
dvander@790
   236
	HandleType_t m_PanelType;
dvander@1163
   237
	HandleType_t m_TempPanelType;
dvander@790
   238
	CStack<CPanelHandler *> m_FreePanelHandlers;
dvander@790
   239
	CStack<CMenuHandler *> m_FreeMenuHandlers;
dvander@790
   240
	CVector<CPanelHandler *> m_PanelHandlers;
dvander@790
   241
} g_MenuHelpers;
dvander@790
   242
dvander@790
   243
/**
dvander@790
   244
 * BASIC PANEL HANDLER WRAPPER
dvander@790
   245
 */
dvander@790
   246
dvander@790
   247
void CPanelHandler::OnMenuCancel(IBaseMenu *menu, int client, MenuCancelReason reason)
dvander@790
   248
{
dvander@790
   249
	if (m_pFunc)
dvander@790
   250
	{
dvander@790
   251
		m_pFunc->PushCell(BAD_HANDLE);
dvander@790
   252
		m_pFunc->PushCell(MenuAction_Cancel);
dvander@790
   253
		m_pFunc->PushCell(client);
dvander@790
   254
		m_pFunc->PushCell(reason);
dvander@790
   255
		m_pFunc->Execute(NULL);
dvander@790
   256
	}
dvander@790
   257
	g_MenuHelpers.FreePanelHandler(this);
dvander@790
   258
}
dvander@790
   259
dvander@790
   260
void CPanelHandler::OnMenuSelect(IBaseMenu *menu, int client, unsigned int item)
dvander@790
   261
{
dvander@790
   262
	if (m_pFunc)
dvander@790
   263
	{
dvander@790
   264
		m_pFunc->PushCell(BAD_HANDLE);
dvander@790
   265
		m_pFunc->PushCell(MenuAction_Select);
dvander@790
   266
		m_pFunc->PushCell(client);
dvander@790
   267
		m_pFunc->PushCell(item);
dvander@790
   268
		m_pFunc->Execute(NULL);
dvander@790
   269
	}
dvander@790
   270
	g_MenuHelpers.FreePanelHandler(this);
dvander@790
   271
}
dvander@790
   272
dvander@1163
   273
static IMenuPanel *s_pCurPanel = NULL;
dvander@1163
   274
static unsigned int s_CurPanelReturn = 0;
dvander@1163
   275
static const ItemDrawInfo *s_CurDrawInfo = NULL;
dvander@1163
   276
dvander@790
   277
/**
dvander@790
   278
 * MENU HANDLER WRAPPER
dvander@790
   279
 */
dvander@790
   280
CMenuHandler::CMenuHandler(IPluginFunction *pBasic, int flags) : 
dvander@1269
   281
	m_pBasic(pBasic), m_Flags(flags), m_pVoteResults(NULL)
dvander@790
   282
{
dvander@790
   283
	/* :TODO: We can probably cache the handle ahead of time */
dvander@790
   284
}
dvander@790
   285
dvander@790
   286
void CMenuHandler::OnMenuStart(IBaseMenu *menu)
dvander@790
   287
{
dvander@790
   288
	if ((m_Flags & (int)MenuAction_Start) == (int)MenuAction_Start)
dvander@790
   289
	{
dvander@878
   290
		DoAction(menu, MenuAction_Start, 0, 0);
dvander@790
   291
	}
dvander@790
   292
}
dvander@790
   293
dvander@790
   294
void CMenuHandler::OnMenuDisplay(IBaseMenu *menu, int client, IMenuPanel *panel)
dvander@790
   295
{
dvander@790
   296
	if ((m_Flags & (int)MenuAction_Display) == (int)MenuAction_Display)
dvander@790
   297
	{
dvander@790
   298
		HandleSecurity sec;
dvander@1163
   299
		sec.pIdentity = g_pCoreIdent;
dvander@1163
   300
		sec.pOwner = m_pBasic->GetParentContext()->GetIdentity();
dvander@790
   301
	
dvander@790
   302
		HandleAccess access;
dvander@790
   303
		g_HandleSys.InitAccessDefaults(NULL, &access);
dvander@790
   304
		access.access[HandleAccess_Delete] = HANDLE_RESTRICT_IDENTITY|HANDLE_RESTRICT_OWNER;
dvander@790
   305
dvander@1163
   306
		Handle_t hndl = g_HandleSys.CreateHandleEx(g_MenuHelpers.GetTempPanelType(), panel, &sec, &access, NULL);
dvander@790
   307
dvander@878
   308
		DoAction(menu, MenuAction_Display, client, hndl);
dvander@790
   309
dvander@790
   310
		g_HandleSys.FreeHandle(hndl, &sec);
dvander@790
   311
	}
dvander@790
   312
}
dvander@790
   313
dvander@790
   314
void CMenuHandler::OnMenuSelect(IBaseMenu *menu, int client, unsigned int item)
dvander@790
   315
{
dvander@878
   316
	DoAction(menu, MenuAction_Select, client, item);
dvander@790
   317
}
dvander@790
   318
dvander@790
   319
void CMenuHandler::OnMenuCancel(IBaseMenu *menu, int client, MenuCancelReason reason)
dvander@790
   320
{
dvander@878
   321
	DoAction(menu, MenuAction_Cancel, client, (cell_t)reason);
dvander@790
   322
}
dvander@790
   323
dvander@997
   324
void CMenuHandler::OnMenuEnd(IBaseMenu *menu, MenuEndReason reason)
dvander@790
   325
{
dvander@997
   326
	DoAction(menu, MenuAction_End, reason, 0);
dvander@790
   327
}
dvander@790
   328
dvander@790
   329
void CMenuHandler::OnMenuDestroy(IBaseMenu *menu)
dvander@790
   330
{
dvander@790
   331
	g_MenuHelpers.FreeMenuHandler(this);
dvander@790
   332
}
dvander@790
   333
dvander@878
   334
void CMenuHandler::OnMenuVoteStart(IBaseMenu *menu)
dvander@878
   335
{
dvander@878
   336
	DoAction(menu, MenuAction_VoteStart, 0, 0);
dvander@878
   337
}
dvander@878
   338
dvander@1296
   339
void CMenuHandler::OnMenuVoteCancel(IBaseMenu *menu, VoteCancelReason reason)
dvander@885
   340
{
dvander@1296
   341
	DoAction(menu, MenuAction_VoteCancel, reason, 0);
dvander@885
   342
}
dvander@885
   343
dvander@1006
   344
void CMenuHandler::OnMenuDrawItem(IBaseMenu *menu, int client, unsigned int item, unsigned int &style)
dvander@1006
   345
{
dvander@1006
   346
	if ((m_Flags & (int)MenuAction_DrawItem) == (int)MenuAction_DrawItem)
dvander@1006
   347
	{
dvander@1006
   348
		cell_t result = DoAction(menu, MenuAction_DrawItem, client, item, style);
dvander@1006
   349
		style = (unsigned int)result;
dvander@1006
   350
	}
dvander@1006
   351
}
dvander@1006
   352
dvander@1163
   353
unsigned int CMenuHandler::OnMenuDisplayItem(IBaseMenu *menu,
dvander@1163
   354
									 int client,
dvander@1163
   355
									 IMenuPanel *panel,
dvander@1163
   356
									 unsigned int item,
dvander@1163
   357
									 const ItemDrawInfo &dr)
dvander@1163
   358
{
dvander@1163
   359
	if ((m_Flags & (int)MenuAction_DisplayItem) == (int)MenuAction_DisplayItem)
dvander@1163
   360
	{
dvander@1163
   361
		IMenuPanel *oldpanel = s_pCurPanel;
dvander@1163
   362
		unsigned int oldret = s_CurPanelReturn;
dvander@1163
   363
		const ItemDrawInfo *oldinfo = s_CurDrawInfo;
dvander@1163
   364
		s_pCurPanel = panel;
dvander@1163
   365
		s_CurPanelReturn = 0;
dvander@1163
   366
		s_CurDrawInfo = &dr;
dvander@1163
   367
dvander@1163
   368
		cell_t res = DoAction(menu, MenuAction_DisplayItem, client, item, 0);
dvander@1163
   369
dvander@1163
   370
		if (!res)
dvander@1163
   371
		{
dvander@1163
   372
			res = s_CurPanelReturn;
dvander@1163
   373
		}
dvander@1163
   374
dvander@1163
   375
		s_pCurPanel = oldpanel;
dvander@1163
   376
		s_CurPanelReturn = oldret;
dvander@1163
   377
		s_CurDrawInfo = oldinfo;
dvander@1163
   378
dvander@1163
   379
		return res;
dvander@1163
   380
	}
dvander@1163
   381
dvander@1163
   382
	return 0;
dvander@1163
   383
}
dvander@1163
   384
dvander@1006
   385
cell_t CMenuHandler::DoAction(IBaseMenu *menu, MenuAction action, cell_t param1, cell_t param2, cell_t def_res)
dvander@878
   386
{
dvander@970
   387
#if defined MENU_DEBUG
dvander@970
   388
	g_Logger.LogMessage("[SM_MENU] CMenuHandler::DoAction() (menu %p/%08x) (action %d) (param1 %d) (param2 %d)",
dvander@970
   389
		menu,
dvander@970
   390
		menu->GetHandle(),
dvander@970
   391
		action,
dvander@970
   392
		param1,
dvander@970
   393
		param2);
dvander@970
   394
#endif
dvander@1006
   395
	cell_t res = def_res;
dvander@878
   396
	m_pBasic->PushCell(menu->GetHandle());
dvander@878
   397
	m_pBasic->PushCell((cell_t)action);
dvander@878
   398
	m_pBasic->PushCell(param1);
dvander@878
   399
	m_pBasic->PushCell(param2);
dvander@1006
   400
	m_pBasic->Execute(&res);
dvander@1006
   401
	return res;
dvander@878
   402
}
dvander@878
   403
dvander@1269
   404
void CMenuHandler::OnMenuVoteResults(IBaseMenu *menu, const menu_vote_result_t *results)
dvander@1269
   405
{
dvander@1269
   406
	if (!m_pVoteResults)
dvander@1269
   407
	{
dvander@1269
   408
		/* Call MenuAction_VoteEnd instead.  See if there are any extra winners. */
dvander@1269
   409
		unsigned int num_items = 1;
dvander@1269
   410
		for (unsigned int i=1; i<results->num_items; i++)
dvander@1269
   411
		{
dvander@1269
   412
			if (results->item_list[i].count != results->item_list[0].count)
dvander@1269
   413
			{
dvander@1269
   414
				break;
dvander@1269
   415
			}
dvander@1269
   416
			num_items++;
dvander@1269
   417
		}
dvander@1269
   418
dvander@1269
   419
		/* See if we need to pick a random winner. */
dvander@1269
   420
		unsigned int winning_item;
dvander@1269
   421
		if (num_items > 1)
dvander@1269
   422
		{
dvander@1269
   423
			/* Yes, we do. */
dvander@1269
   424
			srand(time(NULL));
dvander@1269
   425
			winning_item = rand() % num_items;
dvander@1269
   426
			winning_item = results->item_list[winning_item].item;
dvander@1269
   427
		} else {
dvander@1269
   428
			/* No, take the first. */
dvander@1269
   429
			winning_item = results->item_list[0].item;
dvander@1269
   430
		}
dvander@1269
   431
dvander@1269
   432
		unsigned int total_votes = results->num_votes;
dvander@1269
   433
		unsigned int winning_votes = results->item_list[0].count;
dvander@1269
   434
dvander@1269
   435
		DoAction(menu, MenuAction_VoteEnd, winning_item, (total_votes << 16) | (winning_votes & 0xFFFF));
dvander@1269
   436
	} else {
dvander@1269
   437
		IPluginContext *pContext = m_pVoteResults->GetParentContext();
dvander@1269
   438
		bool no_call = false;
dvander@1269
   439
		int err;
dvander@1269
   440
dvander@1269
   441
		/* First array */
dvander@1269
   442
		cell_t client_array_address = -1;
dvander@1269
   443
		cell_t *client_array_base = NULL;
dvander@1269
   444
		cell_t client_array_size = results->num_clients + (results->num_clients * 2);
dvander@1269
   445
		if (client_array_size)
dvander@1269
   446
		{
dvander@1269
   447
			if ((err = pContext->HeapAlloc(client_array_size, &client_array_address, &client_array_base))
dvander@1269
   448
				!= SP_ERROR_NONE)
dvander@1269
   449
			{
dvander@1269
   450
				g_DbgReporter.GenerateError(pContext, m_fnVoteResult, err, "Menu callback could not allocate %d bytes for client list.", client_array_size * sizeof(cell_t));
dvander@1269
   451
				no_call = true;
dvander@1269
   452
			} else {
dvander@1269
   453
				cell_t target_offs = sizeof(cell_t) * results->num_clients;
dvander@1269
   454
				cell_t *cur_index = client_array_base;
dvander@1269
   455
				cell_t *cur_array;
dvander@1269
   456
				for (unsigned int i=0; i<results->num_clients; i++)
dvander@1269
   457
				{
dvander@1269
   458
					/* Copy the array index */
dvander@1269
   459
					*cur_index = target_offs;
dvander@1269
   460
					/* Get the current array address */
dvander@1269
   461
					cur_array = (cell_t *)((char *)cur_index + target_offs);
dvander@1269
   462
					/* Store information */
dvander@1269
   463
					cur_array[0] = results->client_list[i].client;
dvander@1269
   464
					cur_array[1] = results->client_list[i].item;
dvander@1269
   465
					/* Adjust for the new target by subtracting one indirection
dvander@1269
   466
					 * and adding one array.
dvander@1269
   467
					 */
dvander@1269
   468
					target_offs += (sizeof(cell_t) * 2) - sizeof(cell_t);
dvander@1269
   469
					cur_index++;
dvander@1269
   470
				}
dvander@1269
   471
			}
dvander@1269
   472
		}
dvander@1269
   473
dvander@1269
   474
		/* Second array */
dvander@1269
   475
		cell_t item_array_address = -1;
dvander@1269
   476
		cell_t *item_array_base = NULL;
dvander@1269
   477
		cell_t item_array_size = results->num_items + (results->num_items * 2);
dvander@1269
   478
		if (item_array_size)
dvander@1269
   479
		{
dvander@1269
   480
			if ((err = pContext->HeapAlloc(item_array_size, &item_array_address, &item_array_base))
dvander@1269
   481
				!= SP_ERROR_NONE)
dvander@1269
   482
			{
dvander@1269
   483
				g_DbgReporter.GenerateError(pContext, m_fnVoteResult, err, "Menu callback could not allocate %d bytes for item list.", item_array_size);
dvander@1269
   484
				no_call = true;
dvander@1269
   485
			} else {
dvander@1269
   486
				cell_t target_offs = sizeof(cell_t) * results->num_items;
dvander@1269
   487
				cell_t *cur_index = item_array_base;
dvander@1269
   488
				cell_t *cur_array;
dvander@1269
   489
				for (unsigned int i=0; i<results->num_items; i++)
dvander@1269
   490
				{
dvander@1269
   491
					/* Copy the array index */
dvander@1269
   492
					*cur_index = target_offs;
dvander@1269
   493
					/* Get the current array address */
dvander@1269
   494
					cur_array = (cell_t *)((char *)cur_index + target_offs);
dvander@1269
   495
					/* Store information */
dvander@1269
   496
					cur_array[0] = results->item_list[i].item;
dvander@1269
   497
					cur_array[1] = results->item_list[i].count;
dvander@1269
   498
					/* Adjust for the new target by subtracting one indirection
dvander@1269
   499
					 * and adding one array.
dvander@1269
   500
					 */
dvander@1269
   501
					target_offs += (sizeof(cell_t) * 2) - sizeof(cell_t);
dvander@1269
   502
					cur_index++;
dvander@1269
   503
				}
dvander@1269
   504
			}
dvander@1269
   505
		}
dvander@1269
   506
dvander@1269
   507
		/* Finally, push everything */
dvander@1269
   508
		if (!no_call)
dvander@1269
   509
		{
dvander@1271
   510
			m_pVoteResults->PushCell(menu->GetHandle());
dvander@1269
   511
			m_pVoteResults->PushCell(results->num_votes);
dvander@1269
   512
			m_pVoteResults->PushCell(results->num_clients);
dvander@1269
   513
			m_pVoteResults->PushCell(client_array_address);
dvander@1269
   514
			m_pVoteResults->PushCell(results->num_items);
dvander@1269
   515
			m_pVoteResults->PushCell(item_array_address);
dvander@1269
   516
			m_pVoteResults->Execute(NULL);
dvander@1269
   517
		}
dvander@1269
   518
dvander@1269
   519
		/* Free what we allocated, in reverse order as required */
dvander@1269
   520
		if (item_array_address != -1)
dvander@1269
   521
		{
dvander@1269
   522
			pContext->HeapPop(item_array_address);
dvander@1269
   523
		}
dvander@1269
   524
		if (client_array_address != -1)
dvander@1269
   525
		{
dvander@1269
   526
			pContext->HeapPop(client_array_address);
dvander@1269
   527
		}
dvander@1269
   528
	}
dvander@1269
   529
}
dvander@1269
   530
dvander@1269
   531
bool CMenuHandler::OnSetHandlerOption(const char *option, const void *data)
dvander@1269
   532
{
dvander@1269
   533
	if (strcmp(option, "set_vote_results_handler") == 0)
dvander@1269
   534
	{
dvander@1269
   535
		void **array = (void **)data;
dvander@1269
   536
		m_pVoteResults = (IPluginFunction *)array[0];
dvander@1269
   537
		m_fnVoteResult = *(cell_t *)((cell_t *)array[1]);
dvander@1269
   538
		return true;
dvander@1269
   539
	}
dvander@1269
   540
dvander@1269
   541
	return false;
dvander@1269
   542
}
dvander@1269
   543
dvander@790
   544
/**
dvander@790
   545
 * INLINE FUNCTIONS FOR NATIVES
dvander@790
   546
 */
dvander@790
   547
dvander@790
   548
inline Handle_t MakePanelHandle(IMenuPanel *panel, IPluginContext *pContext)
dvander@790
   549
{
dvander@790
   550
	return g_HandleSys.CreateHandle(g_MenuHelpers.GetPanelType(), panel, pContext->GetIdentity(), g_pCoreIdent, NULL);
dvander@790
   551
}
dvander@790
   552
dvander@790
   553
inline HandleError ReadPanelHandle(Handle_t hndl, IMenuPanel **panel)
dvander@790
   554
{
dvander@790
   555
	HandleSecurity sec;
dvander@790
   556
	sec.pIdentity = g_pCoreIdent;
dvander@790
   557
	sec.pOwner = NULL;
dvander@790
   558
	return g_HandleSys.ReadHandle(hndl, g_MenuHelpers.GetPanelType(), &sec, (void **)panel);
dvander@790
   559
}
dvander@790
   560
dvander@790
   561
inline IMenuStyle *GetStyleFromCell(cell_t cell)
dvander@790
   562
{
dvander@790
   563
	enum MenuStyle
dvander@790
   564
	{
dvander@790
   565
		MenuStyle_Default = 0,		/**< The "default" menu style for the mod */
dvander@790
   566
		MenuStyle_Valve = 1,		/**< The Valve provided menu style (Used on HL2DM) */
dvander@790
   567
		MenuStyle_Radio = 2,		/**< The simpler menu style commonly used on CS:S */
dvander@790
   568
	};
dvander@790
   569
dvander@790
   570
	if (cell == MenuStyle_Valve)
dvander@790
   571
	{
dvander@790
   572
		return &g_ValveMenuStyle;
dvander@790
   573
	} else if (cell == MenuStyle_Radio
dvander@790
   574
			   && g_RadioMenuStyle.IsSupported())
dvander@790
   575
	{
dvander@790
   576
		return &g_RadioMenuStyle;
dvander@790
   577
	}
dvander@790
   578
dvander@790
   579
	return g_Menus.GetDefaultStyle();
dvander@790
   580
}
dvander@790
   581
dvander@790
   582
/***********************************
dvander@790
   583
 **** NATIVE DEFINITIONS ***********
dvander@790
   584
 ***********************************/
dvander@790
   585
dvander@790
   586
static cell_t CreateMenu(IPluginContext *pContext, const cell_t *params)
dvander@790
   587
{
dvander@790
   588
	IMenuStyle *style = g_Menus.GetDefaultStyle();
dvander@790
   589
	IPluginFunction *pFunction;
dvander@790
   590
dvander@790
   591
	if ((pFunction=pContext->GetFunctionById(params[1])) == NULL)
dvander@790
   592
	{
dvander@790
   593
		return pContext->ThrowNativeError("Function id %x is invalid", params[1]);
dvander@790
   594
	}
dvander@790
   595
dvander@790
   596
	CMenuHandler *handler = g_MenuHelpers.GetMenuHandler(pFunction, params[2]);
dvander@790
   597
	IBaseMenu *menu = style->CreateMenu(handler, pContext->GetIdentity());
dvander@790
   598
dvander@790
   599
	Handle_t hndl = menu->GetHandle();
dvander@790
   600
	if (!hndl)
dvander@790
   601
	{
dvander@790
   602
		menu->Destroy();
dvander@790
   603
		return BAD_HANDLE;
dvander@790
   604
	}
dvander@790
   605
dvander@790
   606
	return hndl;
dvander@790
   607
}
dvander@790
   608
dvander@790
   609
static cell_t DisplayMenu(IPluginContext *pContext, const cell_t *params)
dvander@790
   610
{
dvander@790
   611
	Handle_t hndl = (Handle_t)params[1];
dvander@790
   612
	HandleError err;
dvander@790
   613
	IBaseMenu *menu;
dvander@790
   614
dvander@790
   615
	if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
dvander@790
   616
	{
dvander@790
   617
		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
dvander@790
   618
	}
dvander@790
   619
dvander@790
   620
	return menu->Display(params[2], params[3]) ? 1 : 0;
dvander@790
   621
}
dvander@790
   622
dvander@878
   623
static cell_t VoteMenu(IPluginContext *pContext, const cell_t *params)
dvander@878
   624
{
dvander@1269
   625
	if (g_Menus.IsVoteInProgress())
dvander@1269
   626
	{
dvander@1269
   627
		return pContext->ThrowNativeError("A vote is already in progress");
dvander@1269
   628
	}
dvander@1269
   629
dvander@878
   630
	Handle_t hndl = (Handle_t)params[1];
dvander@878
   631
	HandleError err;
dvander@878
   632
	IBaseMenu *menu;
dvander@878
   633
dvander@878
   634
	if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
dvander@878
   635
	{
dvander@878
   636
		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
dvander@878
   637
	}
dvander@878
   638
dvander@878
   639
	cell_t *addr;
dvander@878
   640
	pContext->LocalToPhysAddr(params[2], &addr);
dvander@878
   641
dvander@1269
   642
	if (!g_Menus.StartVote(menu, params[3], addr, params[4]))
dvander@1269
   643
	{
dvander@1269
   644
		return 0;
dvander@1269
   645
	}
dvander@1269
   646
dvander@1269
   647
	return 1;
dvander@878
   648
}
dvander@878
   649
dvander@790
   650
static cell_t AddMenuItem(IPluginContext *pContext, const cell_t *params)
dvander@790
   651
{
dvander@790
   652
	Handle_t hndl = (Handle_t)params[1];
dvander@790
   653
	HandleError err;
dvander@790
   654
	IBaseMenu *menu;
dvander@790
   655
dvander@790
   656
	if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
dvander@790
   657
	{
dvander@790
   658
		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
dvander@790
   659
	}
dvander@790
   660
dvander@790
   661
	char *info;
dvander@790
   662
	ItemDrawInfo dr;
dvander@790
   663
dvander@790
   664
	pContext->LocalToString(params[2], &info);
dvander@790
   665
	pContext->LocalToString(params[3], (char **)&dr.display);
dvander@790
   666
	dr.style = params[4];
dvander@790
   667
dvander@790
   668
	return menu->AppendItem(info, dr) ? 1 : 0;
dvander@790
   669
}
dvander@790
   670
dvander@790
   671
static cell_t InsertMenuItem(IPluginContext *pContext, const cell_t *params)
dvander@790
   672
{
dvander@790
   673
	Handle_t hndl = (Handle_t)params[1];
dvander@790
   674
	HandleError err;
dvander@790
   675
	IBaseMenu *menu;
dvander@790
   676
dvander@790
   677
	if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
dvander@790
   678
	{
dvander@790
   679
		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
dvander@790
   680
	}
dvander@790
   681
dvander@790
   682
	char *info;
dvander@790
   683
	ItemDrawInfo dr;
dvander@790
   684
dvander@790
   685
	pContext->LocalToString(params[3], &info);
dvander@790
   686
	pContext->LocalToString(params[4], (char **)&dr.display);
dvander@790
   687
	dr.style = params[5];
dvander@790
   688
dvander@790
   689
	return menu->InsertItem(params[2], info, dr) ? 1 : 0;
dvander@790
   690
}
dvander@790
   691
dvander@790
   692
static cell_t RemoveMenuItem(IPluginContext *pContext, const cell_t *params)
dvander@790
   693
{
dvander@790
   694
	Handle_t hndl = (Handle_t)params[1];
dvander@790
   695
	HandleError err;
dvander@790
   696
	IBaseMenu *menu;
dvander@790
   697
dvander@790
   698
	if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
dvander@790
   699
	{
dvander@790
   700
		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
dvander@790
   701
	}
dvander@790
   702
dvander@790
   703
	return menu->RemoveItem(params[2]) ? 1 : 0;
dvander@790
   704
}
dvander@790
   705
dvander@790
   706
static cell_t RemoveAllMenuItems(IPluginContext *pContext, const cell_t *params)
dvander@790
   707
{
dvander@790
   708
	Handle_t hndl = (Handle_t)params[1];
dvander@790
   709
	HandleError err;
dvander@790
   710
	IBaseMenu *menu;
dvander@790
   711
dvander@790
   712
	if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
dvander@790
   713
	{
dvander@790
   714
		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
dvander@790
   715
	}
dvander@790
   716
dvander@790
   717
	menu->RemoveAllItems();
dvander@790
   718
dvander@790
   719
	return 1;
dvander@790
   720
}
dvander@790
   721
dvander@790
   722
static cell_t GetMenuItem(IPluginContext *pContext, const cell_t *params)
dvander@790
   723
{
dvander@790
   724
	Handle_t hndl = (Handle_t)params[1];
dvander@790
   725
	HandleError err;
dvander@790
   726
	IBaseMenu *menu;
dvander@790
   727
dvander@790
   728
	if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
dvander@790
   729
	{
dvander@790
   730
		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
dvander@790
   731
	}
dvander@790
   732
dvander@790
   733
	ItemDrawInfo dr;
dvander@790
   734
	const char *info;
dvander@790
   735
dvander@790
   736
	if ((info=menu->GetItemInfo(params[2], &dr)) == NULL)
dvander@790
   737
	{
dvander@790
   738
		return 0;
dvander@790
   739
	}
dvander@790
   740
dvander@790
   741
	pContext->StringToLocalUTF8(params[3], params[4], info, NULL);
dvander@790
   742
	pContext->StringToLocalUTF8(params[6], params[7], dr.display ? dr.display : "", NULL);
dvander@790
   743
dvander@790
   744
	cell_t *addr;
dvander@790
   745
	pContext->LocalToPhysAddr(params[5], &addr);
dvander@790
   746
	*addr = dr.style;
dvander@790
   747
dvander@790
   748
	return 1;
dvander@790
   749
}
dvander@790
   750
dvander@790
   751
static cell_t SetMenuPagination(IPluginContext *pContext, const cell_t *params)
dvander@790
   752
{
dvander@790
   753
	Handle_t hndl = (Handle_t)params[1];
dvander@790
   754
	HandleError err;
dvander@790
   755
	IBaseMenu *menu;
dvander@790
   756
dvander@790
   757
	if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
dvander@790
   758
	{
dvander@790
   759
		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
dvander@790
   760
	}
dvander@790
   761
dvander@790
   762
	return menu->SetPagination(params[2]) ? 1 : 0;
dvander@790
   763
}
dvander@790
   764
dvander@790
   765
static cell_t GetMenuPagination(IPluginContext *pContext, const cell_t *params)
dvander@790
   766
{
dvander@790
   767
	Handle_t hndl = (Handle_t)params[1];
dvander@790
   768
	HandleError err;
dvander@790
   769
	IBaseMenu *menu;
dvander@790
   770
dvander@790
   771
	if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
dvander@790
   772
	{
dvander@790
   773
		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
dvander@790
   774
	}
dvander@790
   775
dvander@790
   776
	return menu->GetPagination();
dvander@790
   777
}
dvander@790
   778
dvander@790
   779
static cell_t GetMenuItemCount(IPluginContext *pContext, const cell_t *params)
dvander@790
   780
{
dvander@790
   781
	Handle_t hndl = (Handle_t)params[1];
dvander@790
   782
	HandleError err;
dvander@790
   783
	IBaseMenu *menu;
dvander@790
   784
dvander@790
   785
	if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
dvander@790
   786
	{
dvander@790
   787
		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
dvander@790
   788
	}
dvander@790
   789
dvander@790
   790
	return menu->GetItemCount();
dvander@790
   791
}
dvander@790
   792
dvander@790
   793
static cell_t SetMenuTitle(IPluginContext *pContext, const cell_t *params)
dvander@790
   794
{
dvander@790
   795
	Handle_t hndl = (Handle_t)params[1];
dvander@790
   796
	HandleError err;
dvander@790
   797
	IBaseMenu *menu;
dvander@790
   798
dvander@790
   799
	if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
dvander@790
   800
	{
dvander@790
   801
		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
dvander@790
   802
	}
dvander@790
   803
dvander@1011
   804
	g_SourceMod.SetGlobalTarget(LANG_SERVER);
dvander@1011
   805
dvander@790
   806
	char buffer[1024];
dvander@790
   807
	g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
dvander@790
   808
dvander@790
   809
	menu->SetDefaultTitle(buffer);
dvander@790
   810
dvander@790
   811
	return 1;
dvander@790
   812
}
dvander@790
   813
dvander@1290
   814
static cell_t GetMenuTitle(IPluginContext *pContext, const cell_t *params)
dvander@1290
   815
{
dvander@1290
   816
	Handle_t hndl = (Handle_t)params[1];
dvander@1290
   817
	HandleError err;
dvander@1290
   818
	IBaseMenu *menu;
dvander@1290
   819
dvander@1290
   820
	if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
dvander@1290
   821
	{
dvander@1290
   822
		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
dvander@1290
   823
	}
dvander@1290
   824
dvander@1290
   825
	size_t written;
dvander@1290
   826
	const char *title = menu->GetDefaultTitle();
dvander@1290
   827
	pContext->StringToLocalUTF8(params[2], params[3], title, &written);
dvander@1290
   828
dvander@1290
   829
	return (cell_t)written;
dvander@1290
   830
}
dvander@1290
   831
dvander@1290
   832
dvander@790
   833
static cell_t CreatePanelFromMenu(IPluginContext *pContext, const cell_t *params)
dvander@790
   834
{
dvander@790
   835
	Handle_t hndl = (Handle_t)params[1];
dvander@790
   836
	HandleError err;
dvander@790
   837
	IBaseMenu *menu;
dvander@790
   838
dvander@790
   839
	if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
dvander@790
   840
	{
dvander@790
   841
		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
dvander@790
   842
	}
dvander@790
   843
dvander@790
   844
	IMenuPanel *panel = menu->CreatePanel();
dvander@790
   845
	hndl = MakePanelHandle(panel, pContext);
dvander@790
   846
	if (!hndl)
dvander@790
   847
	{
dvander@790
   848
		panel->DeleteThis();
dvander@790
   849
	}
dvander@790
   850
dvander@790
   851
	return hndl;
dvander@790
   852
}
dvander@790
   853
dvander@790
   854
static cell_t GetMenuExitButton(IPluginContext *pContext, const cell_t *params)
dvander@790
   855
{
dvander@790
   856
	Handle_t hndl = (Handle_t)params[1];
dvander@790
   857
	HandleError err;
dvander@790
   858
	IBaseMenu *menu;
dvander@790
   859
dvander@790
   860
	if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
dvander@790
   861
	{
dvander@790
   862
		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
dvander@790
   863
	}
dvander@790
   864
dvander@1269
   865
	return ((menu->GetMenuOptionFlags() & MENUFLAG_BUTTON_EXIT) == MENUFLAG_BUTTON_EXIT) ? 1 : 0;
dvander@790
   866
}
dvander@790
   867
dvander@1005
   868
static cell_t GetMenuExitBackButton(IPluginContext *pContext, const cell_t *params)
dvander@1005
   869
{
dvander@1005
   870
	Handle_t hndl = (Handle_t)params[1];
dvander@1005
   871
	HandleError err;
dvander@1005
   872
	IBaseMenu *menu;
dvander@1005
   873
dvander@1005
   874
	if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
dvander@1005
   875
	{
dvander@1005
   876
		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
dvander@1005
   877
	}
dvander@1005
   878
dvander@1269
   879
	return ((menu->GetMenuOptionFlags() & MENUFLAG_BUTTON_EXITBACK) == MENUFLAG_BUTTON_EXIT) ? 1 : 0;
dvander@1005
   880
}
dvander@1005
   881
dvander@790
   882
static cell_t SetMenuExitButton(IPluginContext *pContext, const cell_t *params)
dvander@790
   883
{
dvander@790
   884
	Handle_t hndl = (Handle_t)params[1];
dvander@790
   885
	HandleError err;
dvander@790
   886
	IBaseMenu *menu;
dvander@790
   887
dvander@790
   888
	if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
dvander@790
   889
	{
dvander@790
   890
		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
dvander@790
   891
	}
dvander@790
   892
dvander@1269
   893
	unsigned int flags = menu->GetMenuOptionFlags();
dvander@1269
   894
	flags |= MENUFLAG_BUTTON_EXIT;
dvander@1269
   895
	menu->SetMenuOptionFlags(flags);
dvander@1269
   896
	flags = menu->GetMenuOptionFlags();
dvander@1269
   897
	return ((flags & MENUFLAG_BUTTON_EXIT) == MENUFLAG_BUTTON_EXIT) ? 1 : 0;
dvander@790
   898
}
dvander@790
   899
dvander@1005
   900
static cell_t SetMenuExitBackButton(IPluginContext *pContext, const cell_t *params)
dvander@1005
   901
{
dvander@1005
   902
	Handle_t hndl = (Handle_t)params[1];
dvander@1005
   903
	HandleError err;
dvander@1005
   904
	IBaseMenu *menu;
dvander@1005
   905
dvander@1005
   906
	if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
dvander@1005
   907
	{
dvander@1005
   908
		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
dvander@1005
   909
	}
dvander@1005
   910
dvander@1269
   911
	unsigned int flags = menu->GetMenuOptionFlags();
dvander@1269
   912
	flags |= MENUFLAG_BUTTON_EXITBACK;
dvander@1269
   913
	menu->SetMenuOptionFlags(flags);
dvander@1005
   914
dvander@1005
   915
	return 1;
dvander@1005
   916
}
dvander@1005
   917
dvander@790
   918
static cell_t CancelMenu(IPluginContext *pContext, const cell_t *params)
dvander@790
   919
{
dvander@790
   920
	Handle_t hndl = (Handle_t)params[1];
dvander@790
   921
	HandleError err;
dvander@790
   922
	IBaseMenu *menu;
dvander@790
   923
dvander@790
   924
	if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
dvander@790
   925
	{
dvander@790
   926
		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
dvander@790
   927
	}
dvander@790
   928
dvander@1269
   929
	g_Menus.CancelMenu(menu);
dvander@790
   930
dvander@790
   931
	return 1;
dvander@790
   932
}
dvander@790
   933
dvander@885
   934
static cell_t IsVoteInProgress(IPluginContext *pContext, const cell_t *params)
dvander@885
   935
{
dvander@1269
   936
	return g_Menus.IsVoteInProgress() ? 1 : 0;
dvander@885
   937
}
dvander@885
   938
dvander@790
   939
static cell_t GetMenuStyle(IPluginContext *pContext, const cell_t *params)
dvander@790
   940
{
dvander@790
   941
	Handle_t hndl = (Handle_t)params[1];
dvander@790
   942
	HandleError err;
dvander@790
   943
	IBaseMenu *menu;
dvander@790
   944
dvander@790
   945
	if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
dvander@790
   946
	{
dvander@790
   947
		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
dvander@790
   948
	}
dvander@790
   949
dvander@790
   950
	return menu->GetDrawStyle()->GetHandle();
dvander@790
   951
}
dvander@790
   952
dvander@790
   953
static cell_t GetMenuStyleHandle(IPluginContext *pContext, const cell_t *params)
dvander@790
   954
{
dvander@790
   955
	IMenuStyle *style = GetStyleFromCell(params[1]);
dvander@790
   956
	if (!style)
dvander@790
   957
	{
dvander@790
   958
		return BAD_HANDLE;
dvander@790
   959
	}
dvander@790
   960
dvander@790
   961
	return style->GetHandle();
dvander@790
   962
}
dvander@790
   963
dvander@790
   964
static cell_t CreatePanel(IPluginContext *pContext, const cell_t *params)
dvander@790
   965
{
dvander@790
   966
	Handle_t hndl = (Handle_t)params[1];
dvander@790
   967
	HandleError err;
dvander@790
   968
	IMenuStyle *style;
dvander@790
   969
dvander@790
   970
	if (hndl != 0)
dvander@790
   971
	{
dvander@790
   972
		if ((err=g_Menus.ReadStyleHandle(params[1], &style)) != HandleError_None)
dvander@790
   973
		{
dvander@790
   974
			return pContext->ThrowNativeError("MenuStyle handle %x is invalid (error %d)", hndl, err);
dvander@790
   975
		}
dvander@790
   976
	} else {
dvander@790
   977
		style = g_Menus.GetDefaultStyle();
dvander@790
   978
	}
dvander@790
   979
dvander@790
   980
	IMenuPanel *panel = style->CreatePanel();
dvander@790
   981
dvander@790
   982
	hndl = MakePanelHandle(panel, pContext);
dvander@790
   983
	if (!hndl)
dvander@790
   984
	{
dvander@790
   985
		panel->DeleteThis();
dvander@790
   986
		return BAD_HANDLE;
dvander@790
   987
	}
dvander@790
   988
dvander@790
   989
	return hndl;
dvander@790
   990
}
dvander@790
   991
dvander@790
   992
static cell_t CreateMenuEx(IPluginContext *pContext, const cell_t *params)
dvander@790
   993
{
dvander@790
   994
	Handle_t hndl = (Handle_t)params[1];
dvander@790
   995
	HandleError err;
dvander@790
   996
	IMenuStyle *style;
dvander@790
   997
dvander@790
   998
	if (hndl != 0)
dvander@790
   999
	{
dvander@790
  1000
		if ((err=g_Menus.ReadStyleHandle(params[1], &style)) != HandleError_None)
dvander@790
  1001
		{
dvander@790
  1002
			return pContext->ThrowNativeError("MenuStyle handle %x is invalid (error %d)", hndl, err);
dvander@790
  1003
		}
dvander@790
  1004
	} else {
dvander@790
  1005
		style = g_Menus.GetDefaultStyle();
dvander@790
  1006
	}
dvander@790
  1007
dvander@790
  1008
	IPluginFunction *pFunction;
dvander@790
  1009
	if ((pFunction=pContext->GetFunctionById(params[2])) == NULL)
dvander@790
  1010
	{
dvander@790
  1011
		return pContext->ThrowNativeError("Function id %x is invalid", params[2]);
dvander@790
  1012
	}
dvander@790
  1013
dvander@790
  1014
	CMenuHandler *handler = g_MenuHelpers.GetMenuHandler(pFunction, params[3]);
dvander@790
  1015
dvander@790
  1016
	IBaseMenu *pMenu = style->CreateMenu(handler, pContext->GetIdentity());
dvander@790
  1017
	hndl = pMenu->GetHandle();
dvander@790
  1018
	if (!hndl)
dvander@790
  1019
	{
dvander@790
  1020
		pMenu->Destroy();
dvander@790
  1021
		return BAD_HANDLE;
dvander@790
  1022
	}
dvander@790
  1023
dvander@790
  1024
	return hndl;
dvander@790
  1025
}
dvander@790
  1026
dvander@790
  1027
static cell_t GetClientMenu(IPluginContext *pContext, const cell_t *params)
dvander@790
  1028
{
dvander@790
  1029
	Handle_t hndl = (Handle_t)params[2];
dvander@790
  1030
	HandleError err;
dvander@790
  1031
	IMenuStyle *style;
dvander@790
  1032
dvander@790
  1033
	if (hndl != 0)
dvander@790
  1034
	{
dvander@790
  1035
		if ((err=g_Menus.ReadStyleHandle(params[1], &style)) != HandleError_None)
dvander@790
  1036
		{
dvander@790
  1037
			return pContext->ThrowNativeError("MenuStyle handle %x is invalid (error %d)", hndl, err);
dvander@790
  1038
		}
dvander@790
  1039
	} else {
dvander@790
  1040
		style = g_Menus.GetDefaultStyle();
dvander@790
  1041
	}
dvander@790
  1042
dvander@790
  1043
	return style->GetClientMenu(params[1], NULL);
dvander@790
  1044
}
dvander@790
  1045
dvander@790
  1046
static cell_t CancelClientMenu(IPluginContext *pContext, const cell_t *params)
dvander@790
  1047
{
dvander@790
  1048
	Handle_t hndl = (Handle_t)params[3];
dvander@790
  1049
	HandleError err;
dvander@790
  1050
	IMenuStyle *style;
dvander@790
  1051
dvander@790
  1052
	if (hndl != 0)
dvander@790
  1053
	{
dvander@790
  1054
		if ((err=g_Menus.ReadStyleHandle(params[1], &style)) != HandleError_None)
dvander@790
  1055
		{
dvander@790
  1056
			return pContext->ThrowNativeError("MenuStyle handle %x is invalid (error %d)", hndl, err);
dvander@790
  1057
		}
dvander@790
  1058
	} else {
dvander@790
  1059
		style = g_Menus.GetDefaultStyle();
dvander@790
  1060
	}
dvander@790
  1061
dvander@790
  1062
	return style->CancelClientMenu(params[1], params[2] ? true : false) ? 1 : 0;
dvander@790
  1063
}
dvander@790
  1064
dvander@790
  1065
static cell_t GetMaxPageItems(IPluginContext *pContext, const cell_t *params)
dvander@790
  1066
{
dvander@790
  1067
	Handle_t hndl = (Handle_t)params[1];
dvander@790
  1068
	HandleError err;
dvander@790
  1069
	IMenuStyle *style;
dvander@790
  1070
dvander@790
  1071
	if (hndl != 0)
dvander@790
  1072
	{
dvander@790
  1073
		if ((err=g_Menus.ReadStyleHandle(params[1], &style)) != HandleError_None)
dvander@790
  1074
		{
dvander@790
  1075
			return pContext->ThrowNativeError("MenuStyle handle %x is invalid (error %d)", hndl, err);
dvander@790
  1076
		}
dvander@790
  1077
	} else {
dvander@790
  1078
		style = g_Menus.GetDefaultStyle();
dvander@790
  1079
	}
dvander@790
  1080
dvander@790
  1081
	return style->GetMaxPageItems();
dvander@790
  1082
}
dvander@790
  1083
dvander@790
  1084
static cell_t GetPanelStyle(IPluginContext *pContext, const cell_t *params)
dvander@790
  1085
{
dvander@790
  1086
	Handle_t hndl = (Handle_t)params[1];
dvander@790
  1087
	HandleError err;
dvander@790
  1088
	IMenuPanel *panel;
dvander@790
  1089
dvander@790
  1090
	if ((err=ReadPanelHandle(hndl, &panel)) != HandleError_None)
dvander@790
  1091
	{
dvander@790
  1092
		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
dvander@790
  1093
	}
dvander@790
  1094
dvander@790
  1095
	return panel->GetParentStyle()->GetHandle();
dvander@790
  1096
}
dvander@790
  1097
dvander@790
  1098
static cell_t SetPanelTitle(IPluginContext *pContext, const cell_t *params)
dvander@790
  1099
{
dvander@790
  1100
	Handle_t hndl = (Handle_t)params[1];
dvander@790
  1101
	HandleError err;
dvander@790
  1102
	IMenuPanel *panel;
dvander@790
  1103
dvander@790
  1104
	if ((err=ReadPanelHandle(hndl, &panel)) != HandleError_None)
dvander@790
  1105
	{
dvander@790
  1106
		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
dvander@790
  1107
	}
dvander@790
  1108
dvander@790
  1109
	char *text;
dvander@790
  1110
	pContext->LocalToString(params[2], &text);
dvander@790
  1111
dvander@790
  1112
	panel->DrawTitle(text, params[3] ? true : false);
dvander@790
  1113
dvander@790
  1114
	return 1;
dvander@790
  1115
}
dvander@790
  1116
dvander@790
  1117
static cell_t DrawPanelItem(IPluginContext *pContext, const cell_t *params)
dvander@790
  1118
{
dvander@790
  1119
	Handle_t hndl = (Handle_t)params[1];
dvander@790
  1120
	HandleError err;
dvander@790
  1121
	IMenuPanel *panel;
dvander@790
  1122
dvander@790
  1123
	if ((err=ReadPanelHandle(hndl, &panel)) != HandleError_None)
dvander@790
  1124
	{
dvander@790
  1125
		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
dvander@790
  1126
	}
dvander@790
  1127
dvander@790
  1128
	ItemDrawInfo dr;
dvander@790
  1129
	pContext->LocalToString(params[2], (char **)&dr.display);
dvander@790
  1130
	dr.style = params[3];
dvander@790
  1131
dvander@790
  1132
	return panel->DrawItem(dr);
dvander@790
  1133
}
dvander@790
  1134
dvander@790
  1135
static cell_t DrawPanelText(IPluginContext *pContext, const cell_t *params)
dvander@790
  1136
{
dvander@790
  1137
	Handle_t hndl = (Handle_t)params[1];
dvander@790
  1138
	HandleError err;
dvander@790
  1139
	IMenuPanel *panel;
dvander@790
  1140
dvander@790
  1141
	if ((err=ReadPanelHandle(hndl, &panel)) != HandleError_None)
dvander@790
  1142
	{
dvander@790
  1143
		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
dvander@790
  1144
	}
dvander@790
  1145
dvander@790
  1146
	char *text;
dvander@790
  1147
	pContext->LocalToString(params[2], &text);
dvander@790
  1148
dvander@790
  1149
	return panel->DrawRawLine(text) ? 1 : 0;
dvander@790
  1150
}
dvander@790
  1151
dvander@790
  1152
static cell_t CanPanelDrawFlags(IPluginContext *pContext, const cell_t *params)
dvander@790
  1153
{
dvander@790
  1154
	Handle_t hndl = (Handle_t)params[1];
dvander@790
  1155
	HandleError err;
dvander@790
  1156
	IMenuPanel *panel;
dvander@790
  1157
dvander@790
  1158
	if ((err=ReadPanelHandle(hndl, &panel)) != HandleError_None)
dvander@790
  1159
	{
dvander@790
  1160
		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
dvander@790
  1161
	}
dvander@790
  1162
dvander@790
  1163
	return panel->CanDrawItem(params[2]);
dvander@790
  1164
}
dvander@790
  1165
dvander@790
  1166
static cell_t SendPanelToClient(IPluginContext *pContext, const cell_t *params)
dvander@790
  1167
{
dvander@790
  1168
	Handle_t hndl = (Handle_t)params[1];
dvander@790
  1169
	HandleError err;
dvander@790
  1170
	IMenuPanel *panel;
dvander@790
  1171
dvander@790
  1172
	if ((err=ReadPanelHandle(hndl, &panel)) != HandleError_None)
dvander@790
  1173
	{
dvander@790
  1174
		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
dvander@790
  1175
	}
dvander@790
  1176
dvander@790
  1177
	IPluginFunction *pFunction;
dvander@790
  1178
	if ((pFunction=pContext->GetFunctionById(params[3])) == NULL)
dvander@790
  1179
	{
dvander@790
  1180
		return pContext->ThrowNativeError("Function id %x is invalid", params[3]);
dvander@790
  1181
	}
dvander@790
  1182
dvander@790
  1183
	CPanelHandler *handler = g_MenuHelpers.GetPanelHandler(pFunction);
dvander@790
  1184
	if (!panel->SendDisplay(params[2], handler, params[4]))
dvander@790
  1185
	{
dvander@790
  1186
		g_MenuHelpers.FreePanelHandler(handler);
dvander@790
  1187
	}
dvander@790
  1188
dvander@790
  1189
	return 1;
dvander@790
  1190
}
dvander@790
  1191
dvander@819
  1192
static cell_t SetPanelKeys(IPluginContext *pContext, const cell_t *params)
dvander@819
  1193
{
dvander@819
  1194
	Handle_t hndl = (Handle_t)params[1];
dvander@819
  1195
	HandleError err;
dvander@819
  1196
	IMenuPanel *panel;
dvander@819
  1197
dvander@819
  1198
	if ((err=ReadPanelHandle(hndl, &panel)) != HandleError_None)
dvander@819
  1199
	{
dvander@819
  1200
		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
dvander@819
  1201
	}
dvander@819
  1202
dvander@819
  1203
	return panel->SetSelectableKeys(params[2]);
dvander@819
  1204
}
dvander@819
  1205
dvander@840
  1206
static cell_t GetPanelCurrentKey(IPluginContext *pContext, const cell_t *params)
dvander@840
  1207
{
dvander@840
  1208
	Handle_t hndl = (Handle_t)params[1];
dvander@840
  1209
	HandleError err;
dvander@840
  1210
	IMenuPanel *panel;
dvander@840
  1211
dvander@840
  1212
	if ((err=ReadPanelHandle(hndl, &panel)) != HandleError_None)
dvander@840
  1213
	{
dvander@840
  1214
		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
dvander@840
  1215
	}
dvander@840
  1216
dvander@840
  1217
	return panel->GetCurrentKey();
dvander@840
  1218
}
dvander@840
  1219
dvander@840
  1220
static cell_t SetPanelCurrentKey(IPluginContext *pContext, const cell_t *params)
dvander@840
  1221
{
dvander@840
  1222
	Handle_t hndl = (Handle_t)params[1];
dvander@840
  1223
	HandleError err;
dvander@840
  1224
	IMenuPanel *panel;
dvander@840
  1225
dvander@840
  1226
	if ((err=ReadPanelHandle(hndl, &panel)) != HandleError_None)
dvander@840
  1227
	{
dvander@840
  1228
		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
dvander@840
  1229
	}
dvander@840
  1230
dvander@840
  1231
	return panel->SetCurrentKey(params[2]) ? 1 : 0;
dvander@840
  1232
}
dvander@840
  1233
dvander@1163
  1234
static cell_t RedrawMenuItem(IPluginContext *pContext, const cell_t *params)
dvander@1163
  1235
{
dvander@1163
  1236
	if (!s_pCurPanel)
dvander@1163
  1237
	{
dvander@1163
  1238
		return pContext->ThrowNativeError("You can only call this once from a MenuAction_DisplayItem callback");
dvander@1163
  1239
	}
dvander@1163
  1240
dvander@1163
  1241
	char *str;
dvander@1163
  1242
	pContext->LocalToString(params[1], &str);
dvander@1163
  1243
dvander@1163
  1244
	ItemDrawInfo dr = *s_CurDrawInfo;
dvander@1163
  1245
	dr.display = str;
dvander@1163
  1246
dvander@1163
  1247
	if ((s_CurPanelReturn = s_pCurPanel->DrawItem(dr)) != 0)
dvander@1163
  1248
	{
dvander@1163
  1249
		s_pCurPanel = NULL;
dvander@1163
  1250
	}
dvander@1163
  1251
dvander@1163
  1252
	return s_CurPanelReturn;
dvander@1163
  1253
}
dvander@1163
  1254
dvander@1259
  1255
static cell_t GetMenuOptionFlags(IPluginContext *pContext, const cell_t *params)
dvander@1259
  1256
{
dvander@1259
  1257
	Handle_t hndl = (Handle_t)params[1];
dvander@1259
  1258
	HandleError err;
dvander@1259
  1259
	IBaseMenu *menu;
dvander@1259
  1260
dvander@1259
  1261
	if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
dvander@1259
  1262
	{
dvander@1259
  1263
		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
dvander@1259
  1264
	}
dvander@1259
  1265
dvander@1259
  1266
	return menu->GetMenuOptionFlags();
dvander@1259
  1267
}
dvander@1259
  1268
dvander@1259
  1269
static cell_t SetMenuOptionFlags(IPluginContext *pContext, const cell_t *params)
dvander@1259
  1270
{
dvander@1259
  1271
	Handle_t hndl = (Handle_t)params[1];
dvander@1259
  1272
	HandleError err;
dvander@1259
  1273
	IBaseMenu *menu;
dvander@1259
  1274
dvander@1259
  1275
	if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
dvander@1259
  1276
	{
dvander@1259
  1277
		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
dvander@1259
  1278
	}
dvander@1259
  1279
dvander@1259
  1280
	menu->SetMenuOptionFlags(params[2]);
dvander@1259
  1281
dvander@1259
  1282
	return 1;
dvander@1259
  1283
}
dvander@1259
  1284
dvander@1269
  1285
static cell_t CancelVote(IPluginContext *pContxt, const cell_t *params)
dvander@1269
  1286
{
dvander@1269
  1287
	if (!g_Menus.IsVoteInProgress())
dvander@1269
  1288
	{
dvander@1269
  1289
		return pContxt->ThrowNativeError("No vote is in progress");
dvander@1269
  1290
	}
dvander@1269
  1291
dvander@1269
  1292
	g_Menus.CancelVoting();
dvander@1269
  1293
dvander@1269
  1294
	return 1;
dvander@1269
  1295
}
dvander@1269
  1296
dvander@1269
  1297
static cell_t SetVoteResultCallback(IPluginContext *pContext, const cell_t *params)
dvander@1269
  1298
{
dvander@1269
  1299
	Handle_t hndl = (Handle_t)params[1];
dvander@1269
  1300
	HandleError err;
dvander@1269
  1301
	IBaseMenu *menu;
dvander@1269
  1302
dvander@1269
  1303
	if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
dvander@1269
  1304
	{
dvander@1269
  1305
		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
dvander@1269
  1306
	}
dvander@1269
  1307
dvander@1269
  1308
	IPluginFunction *pFunction = pContext->GetFunctionById(params[2]);
dvander@1269
  1309
	if (!pFunction)
dvander@1269
  1310
	{
dvander@1269
  1311
		return pContext->ThrowNativeError("Invalid function %x", params[2]);
dvander@1269
  1312
	}
dvander@1269
  1313
dvander@1269
  1314
	void *array[2];
dvander@1269
  1315
	array[0] = pFunction;
dvander@1269
  1316
	array[1] = (void *)&params[2];
dvander@1269
  1317
dvander@1269
  1318
	IMenuHandler *pHandler = menu->GetHandler();
dvander@1269
  1319
	if (!pHandler->OnSetHandlerOption("set_vote_results_handler", (const void *)array))
dvander@1269
  1320
	{
dvander@1269
  1321
		return pContext->ThrowNativeError("The given menu does not support this option");
dvander@1269
  1322
	}
dvander@1269
  1323
dvander@1269
  1324
	return 1;
dvander@1269
  1325
}
dvander@1269
  1326
dvander@1291
  1327
static cell_t CheckVoteDelay(IPluginContext *pContext, const cell_t *params)
dvander@1291
  1328
{
dvander@1291
  1329
	return g_Menus.GetRemainingVoteDelay();
dvander@1291
  1330
}
dvander@1291
  1331
dvander@790
  1332
REGISTER_NATIVES(menuNatives)
dvander@790
  1333
{
dvander@790
  1334
	{"AddMenuItem",				AddMenuItem},
dvander@790
  1335
	{"CanPanelDrawFlags",		CanPanelDrawFlags},
dvander@790
  1336
	{"CancelClientMenu",		CancelClientMenu},
dvander@790
  1337
	{"CancelMenu",				CancelMenu},
dvander@1269
  1338
	{"CancelVote",				CancelVote},
dvander@1291
  1339
	{"CheckVoteDelay",			CheckVoteDelay},
dvander@790
  1340
	{"CreateMenu",				CreateMenu},
dvander@790
  1341
	{"CreateMenuEx",			CreateMenuEx},
dvander@790
  1342
	{"CreatePanel",				CreatePanel},
ds@874
  1343
	{"CreatePanelFromMenu",		CreatePanelFromMenu},
dvander@790
  1344
	{"DisplayMenu",				DisplayMenu},
dvander@790
  1345
	{"DrawPanelItem",			DrawPanelItem},
dvander@790
  1346
	{"DrawPanelText",			DrawPanelText},
dvander@790
  1347
	{"GetClientMenu",			GetClientMenu},
dvander@790
  1348
	{"GetMaxPageItems",			GetMaxPageItems},
dvander@1005
  1349
	{"GetMenuExitBackButton",	GetMenuExitBackButton},
dvander@790
  1350
	{"GetMenuExitButton",		GetMenuExitButton},
dvander@790
  1351
	{"GetMenuItem",				GetMenuItem},
dvander@790
  1352
	{"GetMenuItemCount",		GetMenuItemCount},
dvander@1259
  1353
	{"GetMenuOptionFlags",		GetMenuOptionFlags},
dvander@790
  1354
	{"GetMenuPagination",		GetMenuPagination},
dvander@790
  1355
	{"GetMenuStyle",			GetMenuStyle},
dvander@790
  1356
	{"GetMenuStyleHandle",		GetMenuStyleHandle},
dvander@1290
  1357
	{"GetMenuTitle",			GetMenuTitle},
dvander@840
  1358
	{"GetPanelCurrentKey",		GetPanelCurrentKey},
dvander@790
  1359
	{"GetPanelStyle",			GetPanelStyle},
dvander@790
  1360
	{"InsertMenuItem",			InsertMenuItem},
dvander@885
  1361
	{"IsVoteInProgress",		IsVoteInProgress},
dvander@1163
  1362
	{"RedrawMenuItem",			RedrawMenuItem},
dvander@790
  1363
	{"RemoveAllMenuItems",		RemoveAllMenuItems},
dvander@790
  1364
	{"RemoveMenuItem",			RemoveMenuItem},
dvander@790
  1365
	{"SendPanelToClient",		SendPanelToClient},
dvander@1005
  1366
	{"SetMenuExitBackButton",	SetMenuExitBackButton},
dvander@790
  1367
	{"SetMenuExitButton",		SetMenuExitButton},
dvander@1259
  1368
	{"SetMenuOptionFlags",		SetMenuOptionFlags},
dvander@790
  1369
	{"SetMenuPagination",		SetMenuPagination},
dvander@790
  1370
	{"SetMenuTitle",			SetMenuTitle},
dvander@840
  1371
	{"SetPanelCurrentKey",		SetPanelCurrentKey},
dvander@790
  1372
	{"SetPanelTitle",			SetPanelTitle},
dvander@819
  1373
	{"SetPanelKeys",			SetPanelKeys},
dvander@1269
  1374
	{"SetVoteResultCallback",	SetVoteResultCallback},
dvander@878
  1375
	{"VoteMenu",				VoteMenu},
dvander@790
  1376
	{NULL,						NULL},
dvander@790
  1377
};