core/MenuStyle_Base.cpp
author David Anderson <dvander@alliedmods.net>
Tue Jun 05 16:27:45 2007 +0000 (2007-06-05)
changeset 877 898c39fbfde9
parent 825 472a11443703
child 879 f1e33b35f3b6
permissions -rw-r--r--
added experimental voting API
dvander@769
     1
/**
dvander@769
     2
 * vim: set ts=4 :
dvander@769
     3
 * ===============================================================
dvander@769
     4
 * SourceMod (C)2004-2007 AlliedModders LLC.  All rights reserved.
dvander@769
     5
 * ===============================================================
dvander@769
     6
 *
dvander@769
     7
 * This file is not open source and may not be copied without explicit
dvander@769
     8
 * written permission of AlliedModders LLC.  This file may not be redistributed 
dvander@769
     9
 * in whole or significant part.
dvander@769
    10
 * For information, see LICENSE.txt or http://www.sourcemod.net/license.php
dvander@769
    11
 *
dvander@769
    12
 * Version: $Id$
dvander@769
    13
 */
dvander@771
    14
dvander@769
    15
#include <stdarg.h>
dvander@769
    16
#include "sm_stringutil.h"
dvander@769
    17
#include "MenuStyle_Base.h"
dvander@775
    18
#include "PlayerManager.h"
dvander@775
    19
#include "MenuManager.h"
dvander@790
    20
#include "HandleSys.h"
dvander@775
    21
dvander@790
    22
BaseMenuStyle::BaseMenuStyle() : m_WatchList(256), m_hHandle(BAD_HANDLE)
dvander@790
    23
{
dvander@790
    24
}
dvander@790
    25
dvander@790
    26
Handle_t BaseMenuStyle::GetHandle()
dvander@775
    27
{
dvander@790
    28
	/* Don't create the handle until we need it */
dvander@790
    29
	if (m_hHandle == BAD_HANDLE)
dvander@790
    30
	{
dvander@790
    31
		m_hHandle = g_Menus.CreateStyleHandle(this);
dvander@790
    32
	}
dvander@790
    33
dvander@790
    34
	return m_hHandle;
dvander@775
    35
}
dvander@775
    36
dvander@775
    37
void BaseMenuStyle::AddClientToWatch(int client)
dvander@775
    38
{
dvander@775
    39
	m_WatchList.push_back(client);
dvander@775
    40
}
dvander@775
    41
dvander@775
    42
void BaseMenuStyle::RemoveClientFromWatch(int client)
dvander@775
    43
{
dvander@775
    44
	m_WatchList.remove(client);
dvander@775
    45
}
dvander@775
    46
dvander@775
    47
void BaseMenuStyle::_CancelClientMenu(int client, bool bAutoIgnore/* =false */, MenuCancelReason reason/* =MenuCancel_Interrupt */)
dvander@775
    48
{
dvander@775
    49
	CBaseMenuPlayer *player = GetMenuPlayer(client);
dvander@775
    50
	menu_states_t &states = player->states;
dvander@775
    51
dvander@775
    52
	bool bOldIgnore = player->bAutoIgnore;
dvander@775
    53
	if (bAutoIgnore)
dvander@775
    54
	{
dvander@775
    55
		player->bAutoIgnore = true;
dvander@775
    56
	}
dvander@775
    57
dvander@775
    58
	/* Save states */
dvander@775
    59
	IMenuHandler *mh = states.mh;
dvander@775
    60
	IBaseMenu *menu = states.menu;
dvander@775
    61
dvander@775
    62
	/* Clear menu */
dvander@775
    63
	player->bInMenu = false;
dvander@775
    64
	if (player->menuHoldTime)
dvander@775
    65
	{
dvander@775
    66
		RemoveClientFromWatch(client);
dvander@775
    67
	}
dvander@775
    68
dvander@775
    69
	/* Fire callbacks */
dvander@775
    70
	mh->OnMenuCancel(menu, client, reason);
dvander@790
    71
	
dvander@790
    72
	/* Only fire end if there's a valid menu */
dvander@790
    73
	if (menu)
dvander@790
    74
	{
dvander@790
    75
		mh->OnMenuEnd(menu);
dvander@790
    76
	}
dvander@775
    77
dvander@775
    78
	if (bAutoIgnore)
dvander@775
    79
	{
dvander@775
    80
		player->bAutoIgnore = bOldIgnore;
dvander@775
    81
	}
dvander@775
    82
}
dvander@775
    83
dvander@775
    84
void BaseMenuStyle::CancelMenu(CBaseMenu *menu)
dvander@775
    85
{
dvander@775
    86
	int maxClients = g_Players.GetMaxClients();
dvander@775
    87
	for (int i=1; i<=maxClients; i++)
dvander@775
    88
	{
dvander@775
    89
		CBaseMenuPlayer *player = GetMenuPlayer(i);
dvander@775
    90
		if (player->bInMenu)
dvander@775
    91
		{
dvander@775
    92
			menu_states_t &states = player->states;
dvander@775
    93
			if (states.menu == menu)
dvander@775
    94
			{
dvander@775
    95
				_CancelClientMenu(i);
dvander@775
    96
			}
dvander@775
    97
		}
dvander@775
    98
	}
dvander@775
    99
}
dvander@775
   100
dvander@775
   101
bool BaseMenuStyle::CancelClientMenu(int client, bool autoIgnore)
dvander@775
   102
{
dvander@775
   103
	if (client < 1 || client > g_Players.MaxClients())
dvander@775
   104
	{
dvander@775
   105
		return false;
dvander@775
   106
	}
dvander@775
   107
dvander@775
   108
	CBaseMenuPlayer *player = GetMenuPlayer(client);
dvander@775
   109
	if (!player->bInMenu)
dvander@775
   110
	{
dvander@775
   111
		return false;
dvander@775
   112
	}
dvander@775
   113
dvander@775
   114
	_CancelClientMenu(client, autoIgnore);
dvander@775
   115
dvander@775
   116
	return true;
dvander@775
   117
}
dvander@775
   118
dvander@775
   119
MenuSource BaseMenuStyle::GetClientMenu(int client, void **object)
dvander@775
   120
{
dvander@775
   121
	if (client < 1 || client > g_Players.GetMaxClients())
dvander@775
   122
	{
dvander@775
   123
		return MenuSource_None;
dvander@775
   124
	}
dvander@775
   125
dvander@775
   126
	CBaseMenuPlayer *player = GetMenuPlayer(client);
dvander@775
   127
dvander@775
   128
	if (player->bInMenu)
dvander@775
   129
	{
dvander@775
   130
		IBaseMenu *menu;
dvander@775
   131
		if ((menu=player->states.menu) != NULL)
dvander@775
   132
		{
dvander@775
   133
			if (object)
dvander@775
   134
			{
dvander@775
   135
				*object = menu;
dvander@775
   136
			}
dvander@775
   137
			return MenuSource_BaseMenu;
dvander@775
   138
		}
dvander@775
   139
dvander@775
   140
		return MenuSource_Display;
dvander@780
   141
	} else if (player->bInExternMenu) {
dvander@782
   142
		if (player->menuHoldTime != 0
dvander@782
   143
			&& (gpGlobals->curtime > player->menuStartTime + player->menuHoldTime))
dvander@782
   144
		{
dvander@782
   145
			player->bInExternMenu = false;
dvander@782
   146
			return MenuSource_None;
dvander@782
   147
		}
dvander@780
   148
		return MenuSource_External;
dvander@775
   149
	}
dvander@775
   150
dvander@775
   151
	return MenuSource_None;
dvander@775
   152
}
dvander@775
   153
dvander@775
   154
void BaseMenuStyle::OnClientDisconnected(int client)
dvander@775
   155
{
dvander@775
   156
	CBaseMenuPlayer *player = GetMenuPlayer(client);
dvander@775
   157
	if (!player->bInMenu)
dvander@775
   158
	{
dvander@775
   159
		return;
dvander@775
   160
	}
dvander@775
   161
dvander@775
   162
	_CancelClientMenu(client, true, MenuCancel_Disconnect);
dvander@775
   163
dvander@775
   164
	player->bInMenu = false;
dvander@790
   165
	player->bInExternMenu = false;
dvander@775
   166
}
dvander@775
   167
dvander@775
   168
static int do_lookup[256];
dvander@775
   169
void BaseMenuStyle::ProcessWatchList()
dvander@775
   170
{
dvander@775
   171
	if (!m_WatchList.size())
dvander@775
   172
	{
dvander@775
   173
		return;
dvander@775
   174
	}
dvander@775
   175
dvander@775
   176
	unsigned int total = 0;
dvander@775
   177
	for (FastLink<int>::iterator iter=m_WatchList.begin(); iter!=m_WatchList.end(); ++iter)
dvander@775
   178
	{
dvander@775
   179
		do_lookup[total++] = (*iter);
dvander@775
   180
	}
dvander@775
   181
dvander@775
   182
	int client;
dvander@775
   183
	CBaseMenuPlayer *player;
dvander@775
   184
	float curTime = gpGlobals->curtime;
dvander@775
   185
	for (unsigned int i=0; i<total; i++)
dvander@775
   186
	{
dvander@775
   187
		client = do_lookup[i];
dvander@775
   188
		player = GetMenuPlayer(client);
dvander@775
   189
		if (!player->bInMenu || !player->menuHoldTime)
dvander@775
   190
		{
dvander@825
   191
			m_WatchList.remove(client);
dvander@775
   192
			continue;
dvander@775
   193
		}
dvander@775
   194
		if (curTime > player->menuStartTime + player->menuHoldTime)
dvander@775
   195
		{
dvander@775
   196
			_CancelClientMenu(client, false);
dvander@775
   197
		}
dvander@775
   198
	}
dvander@775
   199
}
dvander@775
   200
dvander@775
   201
void BaseMenuStyle::ClientPressedKey(int client, unsigned int key_press)
dvander@775
   202
{
dvander@775
   203
	CBaseMenuPlayer *player = GetMenuPlayer(client);
dvander@775
   204
dvander@775
   205
	/* First question: Are we in a menu? */
dvander@775
   206
	if (!player->bInMenu)
dvander@775
   207
	{
dvander@775
   208
		return;
dvander@775
   209
	}
dvander@775
   210
dvander@775
   211
	bool cancel = false;
dvander@775
   212
	unsigned int item = 0;
dvander@775
   213
	MenuCancelReason reason = MenuCancel_Exit;
dvander@775
   214
	menu_states_t &states = player->states;
dvander@775
   215
dvander@775
   216
	assert(states.mh != NULL);
dvander@775
   217
dvander@775
   218
	if (states.menu == NULL)
dvander@775
   219
	{
dvander@775
   220
		item = key_press;
dvander@785
   221
	} else if (key_press < 1 || key_press > GetMaxPageItems()) {
dvander@775
   222
		cancel = true;
dvander@775
   223
	} else {
dvander@775
   224
		ItemSelection type = states.slots[key_press].type;
dvander@775
   225
dvander@775
   226
		/* For navigational items, we're going to redisplay */
dvander@775
   227
		if (type == ItemSel_Back)
dvander@775
   228
		{
dvander@775
   229
			if (!RedoClientMenu(client, ItemOrder_Descending))
dvander@775
   230
			{
dvander@775
   231
				cancel = true;
dvander@775
   232
				reason = MenuCancel_NoDisplay;
dvander@775
   233
			} else {
dvander@775
   234
				return;
dvander@775
   235
			}
dvander@775
   236
		} else if (type == ItemSel_Next) {
dvander@775
   237
			if (!RedoClientMenu(client, ItemOrder_Ascending))
dvander@775
   238
			{
dvander@775
   239
				cancel = true;						/* I like Saltines. */
dvander@775
   240
				reason = MenuCancel_NoDisplay;
dvander@775
   241
			} else {
dvander@775
   242
				return;
dvander@775
   243
			}
dvander@775
   244
		} else if (type == ItemSel_Exit || type == ItemSel_None) {
dvander@775
   245
			cancel = true;
dvander@775
   246
		} else {
dvander@775
   247
			item = states.slots[key_press].item;
dvander@775
   248
		}
dvander@775
   249
	}
dvander@775
   250
dvander@775
   251
	/* Save variables */
dvander@775
   252
	IMenuHandler *mh = states.mh;
dvander@775
   253
	IBaseMenu *menu = states.menu;
dvander@775
   254
dvander@775
   255
	/* Clear states */
dvander@775
   256
	player->bInMenu = false;
dvander@775
   257
	if (player->menuHoldTime)
dvander@775
   258
	{
dvander@775
   259
		m_WatchList.remove(client);
dvander@775
   260
	}
dvander@775
   261
dvander@775
   262
	if (cancel)
dvander@775
   263
	{
dvander@775
   264
		mh->OnMenuCancel(menu, client, reason);
dvander@775
   265
	} else {
dvander@775
   266
		mh->OnMenuSelect(menu, client, item);
dvander@775
   267
	}
dvander@775
   268
dvander@790
   269
	/* Only fire end for valid menus */
dvander@790
   270
	if (menu)
dvander@790
   271
	{
dvander@790
   272
		mh->OnMenuEnd(menu);
dvander@790
   273
	}
dvander@775
   274
}
dvander@775
   275
dvander@787
   276
bool BaseMenuStyle::DoClientMenu(int client, IMenuPanel *menu, IMenuHandler *mh, unsigned int time)
dvander@775
   277
{
dvander@775
   278
	CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
dvander@775
   279
	if (!pPlayer || pPlayer->IsFakeClient() || !pPlayer->IsInGame())
dvander@775
   280
	{
dvander@775
   281
		return false;
dvander@775
   282
	}
dvander@775
   283
dvander@775
   284
	CBaseMenuPlayer *player = GetMenuPlayer(client);
dvander@775
   285
	if (player->bAutoIgnore)
dvander@775
   286
	{
dvander@775
   287
		return false;
dvander@775
   288
	}
dvander@775
   289
dvander@775
   290
	/* For the duration of this, we are going to totally ignore whether
dvander@775
   291
	* the player is already in a menu or not (except to cancel the old one).
dvander@775
   292
	* Instead, we are simply going to ignore any further menu displays, so
dvander@775
   293
	* this display can't be interrupted.
dvander@775
   294
	*/
dvander@775
   295
	player->bAutoIgnore = true;
dvander@775
   296
dvander@775
   297
	/* Cancel any old menus */
dvander@775
   298
	menu_states_t &states = player->states;
dvander@775
   299
	if (player->bInMenu)
dvander@775
   300
	{
dvander@790
   301
		_CancelClientMenu(client, true);
dvander@775
   302
	}
dvander@775
   303
dvander@775
   304
	states.firstItem = 0;
dvander@775
   305
	states.lastItem = 0;
dvander@775
   306
	states.menu = NULL;
dvander@775
   307
	states.mh = mh;
dvander@775
   308
	states.apiVers = SMINTERFACE_MENUMANAGER_VERSION;
dvander@775
   309
	player->bInMenu = true;
dvander@790
   310
	player->bInExternMenu = false;
dvander@775
   311
	player->menuStartTime = gpGlobals->curtime;
dvander@775
   312
	player->menuHoldTime = time;
dvander@775
   313
dvander@775
   314
	if (time)
dvander@775
   315
	{
dvander@775
   316
		AddClientToWatch(client);
dvander@775
   317
	}
dvander@775
   318
dvander@775
   319
	/* Draw the display */
dvander@775
   320
	SendDisplay(client, menu);
dvander@775
   321
dvander@775
   322
	/* We can be interrupted again! */
dvander@775
   323
	player->bAutoIgnore = false;
dvander@775
   324
dvander@775
   325
	return true;
dvander@775
   326
}
dvander@775
   327
dvander@775
   328
bool BaseMenuStyle::DoClientMenu(int client, CBaseMenu *menu, IMenuHandler *mh, unsigned int time)
dvander@775
   329
{
dvander@775
   330
	mh->OnMenuStart(menu);
dvander@775
   331
dvander@775
   332
	if (!mh)
dvander@775
   333
	{
dvander@775
   334
		mh->OnMenuCancel(menu, client, MenuCancel_NoDisplay);
dvander@775
   335
		mh->OnMenuEnd(menu);
dvander@775
   336
		return false;
dvander@775
   337
	}
dvander@775
   338
dvander@775
   339
	CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
dvander@775
   340
	if (!pPlayer || pPlayer->IsFakeClient() || !pPlayer->IsInGame())
dvander@775
   341
	{
dvander@775
   342
		mh->OnMenuCancel(menu, client, MenuCancel_NoDisplay);
dvander@775
   343
		mh->OnMenuEnd(menu);
dvander@775
   344
		return false;
dvander@775
   345
	}
dvander@775
   346
dvander@775
   347
	CBaseMenuPlayer *player = GetMenuPlayer(client);
dvander@775
   348
	if (player->bAutoIgnore)
dvander@775
   349
	{
dvander@775
   350
		mh->OnMenuCancel(menu, client, MenuCancel_NoDisplay);
dvander@775
   351
		mh->OnMenuEnd(menu);
dvander@775
   352
		return false;
dvander@775
   353
	}
dvander@775
   354
dvander@775
   355
	/* For the duration of this, we are going to totally ignore whether
dvander@775
   356
	* the player is already in a menu or not (except to cancel the old one).
dvander@775
   357
	* Instead, we are simply going to ignore any further menu displays, so
dvander@775
   358
	* this display can't be interrupted.
dvander@775
   359
	*/
dvander@775
   360
	player->bAutoIgnore = true;
dvander@775
   361
dvander@775
   362
	/* Cancel any old menus */
dvander@775
   363
	menu_states_t &states = player->states;
dvander@775
   364
	if (player->bInMenu)
dvander@775
   365
	{
dvander@775
   366
		_CancelClientMenu(client, true);
dvander@775
   367
	}
dvander@775
   368
dvander@775
   369
	states.firstItem = 0;
dvander@775
   370
	states.lastItem = 0;
dvander@775
   371
	states.menu = menu;
dvander@775
   372
	states.mh = mh;
dvander@775
   373
	states.apiVers = SMINTERFACE_MENUMANAGER_VERSION;
dvander@775
   374
dvander@787
   375
	IMenuPanel *display = g_Menus.RenderMenu(client, states, ItemOrder_Ascending);
dvander@775
   376
	if (!display)
dvander@775
   377
	{
dvander@775
   378
		player->bAutoIgnore = false;
dvander@775
   379
		player->bInMenu = false;
dvander@775
   380
		mh->OnMenuCancel(menu, client, MenuCancel_NoDisplay);
dvander@775
   381
		mh->OnMenuEnd(menu);
dvander@775
   382
		return false;
dvander@775
   383
	}
dvander@775
   384
dvander@775
   385
	/* Finally, set our states */
dvander@775
   386
	player->bInMenu = true;
dvander@790
   387
	player->bInExternMenu = false;
dvander@775
   388
	player->menuStartTime = gpGlobals->curtime;
dvander@775
   389
	player->menuHoldTime = time;
dvander@775
   390
dvander@775
   391
	if (time)
dvander@775
   392
	{
dvander@775
   393
		AddClientToWatch(client);
dvander@775
   394
	}
dvander@775
   395
dvander@775
   396
	/* Draw the display */
dvander@775
   397
	SendDisplay(client, display);
dvander@775
   398
dvander@775
   399
	/* Free the display pointer */
dvander@776
   400
	display->DeleteThis();
dvander@775
   401
dvander@775
   402
	/* We can be interrupted again! */
dvander@775
   403
	player->bAutoIgnore = false;
dvander@775
   404
dvander@775
   405
	return true;
dvander@775
   406
}
dvander@775
   407
dvander@775
   408
bool BaseMenuStyle::RedoClientMenu(int client, ItemOrder order)
dvander@775
   409
{
dvander@775
   410
	CBaseMenuPlayer *player = GetMenuPlayer(client);
dvander@775
   411
	menu_states_t &states = player->states;
dvander@775
   412
dvander@775
   413
	player->bAutoIgnore = true;
dvander@787
   414
	IMenuPanel *display = g_Menus.RenderMenu(client, states, order);
dvander@775
   415
	if (!display)
dvander@775
   416
	{
dvander@775
   417
		if (player->menuHoldTime)
dvander@775
   418
		{
dvander@775
   419
			m_WatchList.remove(client);
dvander@775
   420
		}
dvander@775
   421
		player->bAutoIgnore = false;
dvander@775
   422
		return false;
dvander@775
   423
	}
dvander@775
   424
dvander@775
   425
	SendDisplay(client, display);
dvander@775
   426
dvander@776
   427
	display->DeleteThis();
dvander@775
   428
dvander@775
   429
	player->bAutoIgnore = false;
dvander@775
   430
dvander@775
   431
	return true;
dvander@775
   432
}
dvander@769
   433
dvander@790
   434
CBaseMenu::CBaseMenu(IMenuHandler *pHandler, IMenuStyle *pStyle, IdentityToken_t *pOwner) : 
dvander@790
   435
m_pStyle(pStyle), m_Strings(512), m_Pagination(7), m_ExitButton(true), 
dvander@790
   436
m_bShouldDelete(false), m_bCancelling(false), m_pOwner(pOwner ? pOwner : g_pCoreIdent), 
dvander@877
   437
m_bDeleting(false), m_bWillFreeHandle(false), m_hHandle(BAD_HANDLE), m_pHandler(pHandler),
dvander@877
   438
m_pVoteHandler(NULL)
dvander@769
   439
{
dvander@769
   440
}
dvander@769
   441
dvander@769
   442
CBaseMenu::~CBaseMenu()
dvander@769
   443
{
dvander@877
   444
	g_Menus.ReleaseVoteWrapper(m_pVoteHandler);
dvander@769
   445
}
dvander@769
   446
dvander@790
   447
Handle_t CBaseMenu::GetHandle()
dvander@790
   448
{
dvander@790
   449
	if (!m_hHandle)
dvander@790
   450
	{
dvander@790
   451
		m_hHandle = g_Menus.CreateMenuHandle(this, m_pOwner);
dvander@790
   452
	}
dvander@790
   453
dvander@790
   454
	return m_hHandle;
dvander@790
   455
}
dvander@790
   456
dvander@769
   457
bool CBaseMenu::AppendItem(const char *info, const ItemDrawInfo &draw)
dvander@769
   458
{
dvander@778
   459
	if (m_Pagination == (unsigned)MENU_NO_PAGINATION
dvander@769
   460
		&& m_items.size() >= m_pStyle->GetMaxPageItems())
dvander@769
   461
	{
dvander@769
   462
		return false;
dvander@769
   463
	}
dvander@769
   464
dvander@769
   465
	CItem item;
dvander@769
   466
dvander@769
   467
	item.infoString = m_Strings.AddString(info);
dvander@769
   468
	if (draw.display)
dvander@769
   469
	{
dvander@769
   470
		item.displayString = m_Strings.AddString(draw.display);
dvander@769
   471
	}
dvander@769
   472
	item.style = draw.style;
dvander@769
   473
dvander@769
   474
dvander@769
   475
	m_items.push_back(item);
dvander@769
   476
dvander@769
   477
	return true;
dvander@769
   478
}
dvander@769
   479
dvander@769
   480
bool CBaseMenu::InsertItem(unsigned int position, const char *info, const ItemDrawInfo &draw)
dvander@769
   481
{
dvander@778
   482
	if (m_Pagination == (unsigned)MENU_NO_PAGINATION
dvander@769
   483
		&& m_items.size() >= m_pStyle->GetMaxPageItems())
dvander@769
   484
	{
dvander@769
   485
		return false;
dvander@769
   486
	}
dvander@769
   487
dvander@769
   488
	if (position >= m_items.size())
dvander@769
   489
	{
dvander@769
   490
		return false;
dvander@769
   491
	}
dvander@769
   492
dvander@769
   493
	CItem item;
dvander@769
   494
	item.infoString = m_Strings.AddString(info);
dvander@769
   495
	if (draw.display)
dvander@769
   496
	{
dvander@769
   497
		item.displayString = m_Strings.AddString(draw.display);
dvander@769
   498
	}
dvander@769
   499
	item.style = draw.style;
dvander@769
   500
dvander@769
   501
	CVector<CItem>::iterator iter = m_items.iterAt(position);
dvander@769
   502
	m_items.insert(iter, item);
dvander@769
   503
dvander@769
   504
	return true;
dvander@769
   505
}
dvander@769
   506
dvander@769
   507
bool CBaseMenu::RemoveItem(unsigned int position)
dvander@769
   508
{
dvander@769
   509
	if (position >= m_items.size())
dvander@769
   510
	{
dvander@769
   511
		return false;
dvander@769
   512
	}
dvander@769
   513
dvander@769
   514
	m_items.erase(m_items.iterAt(position));
dvander@769
   515
dvander@769
   516
	if (m_items.size() == 0)
dvander@769
   517
	{
dvander@769
   518
		m_Strings.Reset();
dvander@769
   519
	}
dvander@769
   520
dvander@769
   521
	return true;
dvander@769
   522
}
dvander@769
   523
dvander@769
   524
void CBaseMenu::RemoveAllItems()
dvander@769
   525
{
dvander@769
   526
	m_items.clear();
dvander@769
   527
	m_Strings.Reset();
dvander@769
   528
}
dvander@769
   529
dvander@769
   530
const char *CBaseMenu::GetItemInfo(unsigned int position, ItemDrawInfo *draw/* =NULL */)
dvander@769
   531
{
dvander@769
   532
	if (position >= m_items.size())
dvander@769
   533
	{
dvander@769
   534
		return NULL;
dvander@769
   535
	}
dvander@769
   536
dvander@769
   537
	if (draw)
dvander@769
   538
	{
dvander@769
   539
		draw->display = m_Strings.GetString(m_items[position].displayString);
dvander@769
   540
		draw->style = m_items[position].style;
dvander@769
   541
	}
dvander@769
   542
dvander@769
   543
	return m_Strings.GetString(m_items[position].infoString);
dvander@769
   544
}
dvander@769
   545
dvander@769
   546
unsigned int CBaseMenu::GetItemCount()
dvander@769
   547
{
dvander@769
   548
	return m_items.size();
dvander@769
   549
}
dvander@769
   550
dvander@769
   551
bool CBaseMenu::SetPagination(unsigned int itemsPerPage)
dvander@769
   552
{
dvander@820
   553
	if (itemsPerPage > 7 || itemsPerPage == 1)
dvander@769
   554
	{
dvander@769
   555
		return false;
dvander@769
   556
	}
dvander@769
   557
dvander@769
   558
	m_Pagination = itemsPerPage;
dvander@769
   559
dvander@769
   560
	return true;
dvander@769
   561
}
dvander@769
   562
dvander@769
   563
unsigned int CBaseMenu::GetPagination()
dvander@769
   564
{
dvander@769
   565
	return m_Pagination;
dvander@769
   566
}
dvander@769
   567
dvander@769
   568
IMenuStyle *CBaseMenu::GetDrawStyle()
dvander@769
   569
{
dvander@769
   570
	return m_pStyle;
dvander@769
   571
}
dvander@769
   572
dvander@769
   573
void CBaseMenu::SetDefaultTitle(const char *message)
dvander@769
   574
{
dvander@769
   575
	m_Title.assign(message);
dvander@769
   576
}
dvander@769
   577
dvander@769
   578
const char *CBaseMenu::GetDefaultTitle()
dvander@769
   579
{
dvander@769
   580
	return m_Title.c_str();
dvander@769
   581
}
dvander@769
   582
dvander@769
   583
bool CBaseMenu::GetExitButton()
dvander@769
   584
{
dvander@769
   585
	return m_ExitButton;
dvander@769
   586
}
dvander@769
   587
dvander@769
   588
bool CBaseMenu::SetExitButton(bool set)
dvander@769
   589
{
dvander@769
   590
	m_ExitButton = set;
dvander@769
   591
	return true;
dvander@769
   592
}
dvander@775
   593
dvander@775
   594
void CBaseMenu::Cancel()
dvander@775
   595
{
dvander@775
   596
	if (m_bCancelling)
dvander@775
   597
	{
dvander@775
   598
		return;
dvander@775
   599
	}
dvander@775
   600
dvander@775
   601
	m_bCancelling = true;
dvander@775
   602
	Cancel_Finally();
dvander@775
   603
	m_bCancelling = false;
dvander@775
   604
dvander@775
   605
	if (m_bShouldDelete)
dvander@775
   606
	{
dvander@790
   607
		InternalDelete();
dvander@775
   608
	}
dvander@775
   609
}
dvander@775
   610
dvander@790
   611
void CBaseMenu::Destroy(bool releaseHandle)
dvander@775
   612
{
dvander@790
   613
	/* Check if we shouldn't be here */
dvander@790
   614
	if (m_bDeleting)
dvander@790
   615
	{
dvander@790
   616
		return;
dvander@790
   617
	}
dvander@790
   618
dvander@790
   619
	/* Save the destruction hint about our handle */
dvander@790
   620
	m_bWillFreeHandle = releaseHandle;
dvander@790
   621
dvander@790
   622
	/* Now actually do stuff */
dvander@775
   623
	if (!m_bCancelling || m_bShouldDelete)
dvander@775
   624
	{
dvander@775
   625
		Cancel();
dvander@790
   626
		InternalDelete();
dvander@775
   627
	} else {
dvander@775
   628
		m_bShouldDelete = true;
dvander@775
   629
	}
dvander@775
   630
}
dvander@775
   631
dvander@790
   632
void CBaseMenu::InternalDelete()
dvander@790
   633
{
dvander@790
   634
	if (m_bWillFreeHandle && m_hHandle != BAD_HANDLE)
dvander@790
   635
	{
dvander@790
   636
		Handle_t hndl = m_hHandle;
dvander@790
   637
		HandleSecurity sec;
dvander@790
   638
dvander@790
   639
		sec.pOwner = m_pOwner;
dvander@790
   640
		sec.pIdentity = g_pCoreIdent;
dvander@790
   641
dvander@790
   642
		m_hHandle = BAD_HANDLE;
dvander@790
   643
		m_bDeleting = true;
dvander@790
   644
		g_HandleSys.FreeHandle(hndl, &sec);
dvander@790
   645
	}
dvander@790
   646
dvander@790
   647
	m_pHandler->OnMenuDestroy(this);
dvander@790
   648
dvander@790
   649
	delete this;
dvander@790
   650
}
dvander@790
   651
dvander@877
   652
bool CBaseMenu::BroadcastVote(int clients[], 
dvander@877
   653
							  unsigned int numClients, 
dvander@877
   654
							  unsigned int maxTime,
dvander@877
   655
							  unsigned int flags)
dvander@877
   656
{
dvander@877
   657
	if (!m_pVoteHandler)
dvander@877
   658
	{
dvander@877
   659
		m_pVoteHandler = g_Menus.CreateVoteWrapper(m_pHandler);
dvander@877
   660
	} else if (m_pVoteHandler->IsVoteInProgress()) {
dvander@877
   661
		return false;
dvander@877
   662
	}
dvander@877
   663
dvander@877
   664
	m_pVoteHandler->InitializeVoting(this);
dvander@877
   665
dvander@877
   666
	for (unsigned int i=0; i<numClients; i++)
dvander@877
   667
	{
dvander@877
   668
		VoteDisplay(clients[i], maxTime);
dvander@877
   669
	}
dvander@877
   670
dvander@877
   671
	m_pVoteHandler->StartVoting();
dvander@877
   672
}