1.1 --- a/core/MenuStyle_Base.cpp Fri Mar 28 06:21:34 2008 +0000
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,830 +0,0 @@
1.4 -/**
1.5 - * vim: set ts=4 :
1.6 - * =============================================================================
1.7 - * SourceMod
1.8 - * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
1.9 - * =============================================================================
1.10 - *
1.11 - * This program is free software; you can redistribute it and/or modify it under
1.12 - * the terms of the GNU General Public License, version 3.0, as published by the
1.13 - * Free Software Foundation.
1.14 - *
1.15 - * This program is distributed in the hope that it will be useful, but WITHOUT
1.16 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
1.18 - * details.
1.19 - *
1.20 - * You should have received a copy of the GNU General Public License along with
1.21 - * this program. If not, see <http://www.gnu.org/licenses/>.
1.22 - *
1.23 - * As a special exception, AlliedModders LLC gives you permission to link the
1.24 - * code of this program (as well as its derivative works) to "Half-Life 2," the
1.25 - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
1.26 - * by the Valve Corporation. You must obey the GNU General Public License in
1.27 - * all respects for all other code used. Additionally, AlliedModders LLC grants
1.28 - * this exception to all derivative works. AlliedModders LLC defines further
1.29 - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
1.30 - * or <http://www.sourcemod.net/license.php>.
1.31 - *
1.32 - * Version: $Id$
1.33 - */
1.34 -
1.35 -#include <stdarg.h>
1.36 -#include "sm_stringutil.h"
1.37 -#include "MenuStyle_Base.h"
1.38 -#include "PlayerManager.h"
1.39 -#include "MenuManager.h"
1.40 -#include "HandleSys.h"
1.41 -#include "CellRecipientFilter.h"
1.42 -#if defined MENU_DEBUG
1.43 -#include "Logger.h"
1.44 -#endif
1.45 -
1.46 -BaseMenuStyle::BaseMenuStyle() : m_WatchList(256), m_hHandle(BAD_HANDLE)
1.47 -{
1.48 -}
1.49 -
1.50 -Handle_t BaseMenuStyle::GetHandle()
1.51 -{
1.52 - /* Don't create the handle until we need it */
1.53 - if (m_hHandle == BAD_HANDLE)
1.54 - {
1.55 - m_hHandle = g_Menus.CreateStyleHandle(this);
1.56 - }
1.57 -
1.58 - return m_hHandle;
1.59 -}
1.60 -
1.61 -void BaseMenuStyle::AddClientToWatch(int client)
1.62 -{
1.63 -#if defined MENU_DEBUG
1.64 - g_Logger.LogMessage("[SM_MENU] AddClientToWatch(%d)", client);
1.65 -#endif
1.66 - m_WatchList.push_back(client);
1.67 -}
1.68 -
1.69 -void BaseMenuStyle::RemoveClientFromWatch(int client)
1.70 -{
1.71 -#if defined MENU_DEBUG
1.72 - g_Logger.LogMessage("[SM_MENU] RemoveClientFromWatch(%d)", client);
1.73 -#endif
1.74 - m_WatchList.remove(client);
1.75 -}
1.76 -
1.77 -void BaseMenuStyle::_CancelClientMenu(int client, MenuCancelReason reason, bool bAutoIgnore/* =false */)
1.78 -{
1.79 -#if defined MENU_DEBUG
1.80 - g_Logger.LogMessage("[SM_MENU] _CancelClientMenu() (client %d) (bAutoIgnore %d) (reason %d)", client, bAutoIgnore, reason);
1.81 -#endif
1.82 - CBaseMenuPlayer *player = GetMenuPlayer(client);
1.83 - menu_states_t &states = player->states;
1.84 -
1.85 - bool bOldIgnore = player->bAutoIgnore;
1.86 - if (bAutoIgnore)
1.87 - {
1.88 - player->bAutoIgnore = true;
1.89 - }
1.90 -
1.91 - /* Save states */
1.92 - IMenuHandler *mh = states.mh;
1.93 - IBaseMenu *menu = states.menu;
1.94 -
1.95 - /* Clear menu */
1.96 - player->bInMenu = false;
1.97 - if (player->menuHoldTime)
1.98 - {
1.99 - RemoveClientFromWatch(client);
1.100 - }
1.101 -
1.102 - /* Fire callbacks */
1.103 - mh->OnMenuCancel(menu, client, reason);
1.104 -
1.105 - /* Only fire end if there's a valid menu */
1.106 - if (menu)
1.107 - {
1.108 - mh->OnMenuEnd(menu, MenuEnd_Cancelled);
1.109 - }
1.110 -
1.111 - if (bAutoIgnore)
1.112 - {
1.113 - player->bAutoIgnore = bOldIgnore;
1.114 - }
1.115 -}
1.116 -
1.117 -void BaseMenuStyle::CancelMenu(CBaseMenu *menu)
1.118 -{
1.119 -#if defined MENU_DEBUG
1.120 - g_Logger.LogMessage("[SM_MENU] CancelMenu() (menu %p)", menu);
1.121 -#endif
1.122 - int maxClients = g_Players.GetMaxClients();
1.123 - for (int i=1; i<=maxClients; i++)
1.124 - {
1.125 - CBaseMenuPlayer *player = GetMenuPlayer(i);
1.126 - if (player->bInMenu)
1.127 - {
1.128 - menu_states_t &states = player->states;
1.129 - if (states.menu == menu)
1.130 - {
1.131 - _CancelClientMenu(i, MenuCancel_Interrupted);
1.132 - }
1.133 - }
1.134 - }
1.135 -}
1.136 -
1.137 -bool BaseMenuStyle::CancelClientMenu(int client, bool autoIgnore)
1.138 -{
1.139 -#if defined MENU_DEBUG
1.140 - g_Logger.LogMessage("[SM_MENU] CancelClientMenu() (client %d) (bAutoIgnore %d)", client, autoIgnore);
1.141 -#endif
1.142 - if (client < 1 || client > g_Players.MaxClients())
1.143 - {
1.144 - return false;
1.145 - }
1.146 -
1.147 - CBaseMenuPlayer *player = GetMenuPlayer(client);
1.148 - if (!player->bInMenu)
1.149 - {
1.150 - return false;
1.151 - }
1.152 -
1.153 - _CancelClientMenu(client, MenuCancel_Interrupted, autoIgnore);
1.154 -
1.155 - return true;
1.156 -}
1.157 -
1.158 -MenuSource BaseMenuStyle::GetClientMenu(int client, void **object)
1.159 -{
1.160 - if (client < 1 || client > g_Players.GetMaxClients())
1.161 - {
1.162 - return MenuSource_None;
1.163 - }
1.164 -
1.165 - CBaseMenuPlayer *player = GetMenuPlayer(client);
1.166 -
1.167 - if (player->bInMenu)
1.168 - {
1.169 - IBaseMenu *menu;
1.170 - if ((menu=player->states.menu) != NULL)
1.171 - {
1.172 - if (object)
1.173 - {
1.174 - *object = menu;
1.175 - }
1.176 - return MenuSource_BaseMenu;
1.177 - }
1.178 -
1.179 - return MenuSource_Display;
1.180 - } else if (player->bInExternMenu) {
1.181 - if (player->menuHoldTime != 0
1.182 - && (gpGlobals->curtime > player->menuStartTime + player->menuHoldTime))
1.183 - {
1.184 - player->bInExternMenu = false;
1.185 - return MenuSource_None;
1.186 - }
1.187 - return MenuSource_External;
1.188 - }
1.189 -
1.190 - return MenuSource_None;
1.191 -}
1.192 -
1.193 -void BaseMenuStyle::OnClientDisconnected(int client)
1.194 -{
1.195 -#if defined MENU_DEBUG
1.196 - g_Logger.LogMessage("[SM_MENU] OnClientDisconnected(%d)", client);
1.197 -#endif
1.198 - CBaseMenuPlayer *player = GetMenuPlayer(client);
1.199 - if (!player->bInMenu)
1.200 - {
1.201 - return;
1.202 - }
1.203 -
1.204 - _CancelClientMenu(client, MenuCancel_Disconnected, true);
1.205 -
1.206 - player->bInMenu = false;
1.207 - player->bInExternMenu = false;
1.208 -}
1.209 -
1.210 -static int do_lookup[256];
1.211 -void BaseMenuStyle::ProcessWatchList()
1.212 -{
1.213 - if (!m_WatchList.size())
1.214 - {
1.215 - return;
1.216 - }
1.217 -
1.218 -#if defined MENU_DEBUG
1.219 - g_Logger.LogMessage("BaseMenuStyle::ProcessWatchList(%d,%d,%d,%d,%d,%p)",
1.220 - m_WatchList.m_Size,
1.221 - m_WatchList.m_FirstLink,
1.222 - m_WatchList.m_FreeNodes,
1.223 - m_WatchList.m_LastLink,
1.224 - m_WatchList.m_MaxSize,
1.225 - m_WatchList.m_Nodes);
1.226 -#endif
1.227 -
1.228 - unsigned int total = 0;
1.229 - for (FastLink<int>::iterator iter=m_WatchList.begin(); iter!=m_WatchList.end(); ++iter)
1.230 - {
1.231 - do_lookup[total++] = (*iter);
1.232 - }
1.233 -
1.234 -#if defined MENU_DEBUG
1.235 - if (total)
1.236 - {
1.237 - g_Logger.LogMessage("[SM_MENU] ProcessWatchList() found %d clients", total);
1.238 - }
1.239 -#endif
1.240 -
1.241 - int client;
1.242 - CBaseMenuPlayer *player;
1.243 - float curTime = gpGlobals->curtime;
1.244 - for (unsigned int i=0; i<total; i++)
1.245 - {
1.246 - client = do_lookup[i];
1.247 - player = GetMenuPlayer(client);
1.248 -#if defined MENU_DEBUG
1.249 - g_Logger.LogMessage("[SM_MENU] ProcessWatchList() (client %d) (bInMenu %d) (menuHoldTime %d) (curTime %f) (menuStartTime %f)",
1.250 - client,
1.251 - player->bInMenu,
1.252 - player->menuHoldTime,
1.253 - curTime,
1.254 - player->menuStartTime);
1.255 -#endif
1.256 - if (!player->bInMenu || !player->menuHoldTime)
1.257 - {
1.258 -#if defined MENU_DEBUG
1.259 - g_Logger.LogMessage("[SM_MENU] ProcessWatchList() removing client %d", client);
1.260 -#endif
1.261 - m_WatchList.remove(client);
1.262 - continue;
1.263 - }
1.264 - if (curTime > player->menuStartTime + player->menuHoldTime)
1.265 - {
1.266 - _CancelClientMenu(client, MenuCancel_Timeout, false);
1.267 - }
1.268 - }
1.269 -}
1.270 -
1.271 -void BaseMenuStyle::ClientPressedKey(int client, unsigned int key_press)
1.272 -{
1.273 -#if defined MENU_DEBUG
1.274 - g_Logger.LogMessage("[SM_MENU] ClientPressedKey() (client %d) (key_press %d)", client, key_press);
1.275 -#endif
1.276 - CBaseMenuPlayer *player = GetMenuPlayer(client);
1.277 -
1.278 - /* First question: Are we in a menu? */
1.279 - if (!player->bInMenu)
1.280 - {
1.281 - return;
1.282 - }
1.283 -
1.284 - bool cancel = false;
1.285 - unsigned int item = 0;
1.286 - MenuCancelReason reason = MenuCancel_Exit;
1.287 - MenuEndReason end_reason = MenuEnd_Selected;
1.288 - menu_states_t &states = player->states;
1.289 -
1.290 - /* Save variables */
1.291 - IMenuHandler *mh = states.mh;
1.292 - IBaseMenu *menu = states.menu;
1.293 -
1.294 - unsigned int item_on_page = states.item_on_page;
1.295 -
1.296 - assert(mh != NULL);
1.297 -
1.298 - if (menu == NULL)
1.299 - {
1.300 - item = key_press;
1.301 - } else if (key_press < 1 || key_press > GetMaxPageItems()) {
1.302 - cancel = true;
1.303 - } else {
1.304 - ItemSelection type = states.slots[key_press].type;
1.305 -
1.306 - /* Check if we should play a sound about the type */
1.307 - if (g_Menus.MenuSoundsEnabled() &&
1.308 - (!menu || (menu->GetMenuOptionFlags() & MENUFLAG_NO_SOUND) != MENUFLAG_NO_SOUND))
1.309 - {
1.310 - CellRecipientFilter filter;
1.311 - cell_t clients[1];
1.312 -
1.313 - clients[0] = client;
1.314 - filter.Initialize(clients, 1);
1.315 -
1.316 - const char *sound = g_Menus.GetMenuSound(type);
1.317 -
1.318 - if (sound != NULL)
1.319 - {
1.320 - edict_t *pEdict = engine->PEntityOfEntIndex(client);
1.321 - if (pEdict)
1.322 - {
1.323 - ICollideable *pCollideable = pEdict->GetCollideable();
1.324 -
1.325 - if (pCollideable)
1.326 - {
1.327 - const Vector & pos = pCollideable->GetCollisionOrigin();
1.328 -
1.329 - enginesound->EmitSound(filter,
1.330 - client,
1.331 - CHAN_AUTO,
1.332 - sound,
1.333 - VOL_NORM,
1.334 - ATTN_NORM,
1.335 - 0,
1.336 - PITCH_NORM,
1.337 - &pos);
1.338 - }
1.339 - }
1.340 - }
1.341 - }
1.342 -
1.343 - /* For navigational items, we're going to redisplay */
1.344 - if (type == ItemSel_Back)
1.345 - {
1.346 - if (!RedoClientMenu(client, ItemOrder_Descending))
1.347 - {
1.348 - cancel = true;
1.349 - reason = MenuCancel_NoDisplay;
1.350 - end_reason = MenuEnd_Cancelled;
1.351 - } else {
1.352 - return;
1.353 - }
1.354 - } else if (type == ItemSel_Next) {
1.355 - if (!RedoClientMenu(client, ItemOrder_Ascending))
1.356 - {
1.357 - cancel = true; /* I like Saltines. */
1.358 - reason = MenuCancel_NoDisplay;
1.359 - end_reason = MenuEnd_Cancelled;
1.360 - } else {
1.361 - return;
1.362 - }
1.363 - } else if (type == ItemSel_Exit || type == ItemSel_None) {
1.364 - cancel = true;
1.365 - reason = MenuCancel_Exit;
1.366 - end_reason = MenuEnd_Exit;
1.367 - } else if (type == ItemSel_ExitBack) {
1.368 - cancel = true;
1.369 - reason = MenuCancel_ExitBack;
1.370 - end_reason = MenuEnd_ExitBack;
1.371 - } else {
1.372 - item = states.slots[key_press].item;
1.373 - }
1.374 - }
1.375 -
1.376 - /* Clear states */
1.377 - player->bInMenu = false;
1.378 - if (player->menuHoldTime)
1.379 - {
1.380 - RemoveClientFromWatch(client);
1.381 - }
1.382 -
1.383 - if (cancel)
1.384 - {
1.385 - mh->OnMenuCancel(menu, client, reason);
1.386 - } else {
1.387 - mh->OnMenuSelect(menu, client, item);
1.388 - if (mh->GetMenuAPIVersion2() >= 13)
1.389 - {
1.390 - mh->OnMenuSelect2(menu, client, item, item_on_page);
1.391 - }
1.392 - }
1.393 -
1.394 - /* Only fire end for valid menus */
1.395 - if (menu)
1.396 - {
1.397 - mh->OnMenuEnd(menu, end_reason);
1.398 - }
1.399 -}
1.400 -
1.401 -bool BaseMenuStyle::DoClientMenu(int client, IMenuPanel *menu, IMenuHandler *mh, unsigned int time)
1.402 -{
1.403 -#if defined MENU_DEBUG
1.404 - g_Logger.LogMessage("[SM_MENU] DoClientMenu() (client %d) (panel %p) (mh %p) (time %d)",
1.405 - client,
1.406 - menu,
1.407 - mh,
1.408 - time);
1.409 -#endif
1.410 - CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
1.411 - if (!pPlayer || pPlayer->IsFakeClient() || !pPlayer->IsInGame())
1.412 - {
1.413 - return false;
1.414 - }
1.415 -
1.416 - CBaseMenuPlayer *player = GetMenuPlayer(client);
1.417 - if (player->bAutoIgnore)
1.418 - {
1.419 - return false;
1.420 - }
1.421 -
1.422 - /* For the duration of this, we are going to totally ignore whether
1.423 - * the player is already in a menu or not (except to cancel the old one).
1.424 - * Instead, we are simply going to ignore any further menu displays, so
1.425 - * this display can't be interrupted.
1.426 - */
1.427 - player->bAutoIgnore = true;
1.428 -
1.429 - /* Cancel any old menus */
1.430 - menu_states_t &states = player->states;
1.431 - if (player->bInMenu)
1.432 - {
1.433 - _CancelClientMenu(client, MenuCancel_Interrupted, true);
1.434 - }
1.435 -
1.436 - states.firstItem = 0;
1.437 - states.lastItem = 0;
1.438 - states.menu = NULL;
1.439 - states.mh = mh;
1.440 - states.apiVers = SMINTERFACE_MENUMANAGER_VERSION;
1.441 - player->bInMenu = true;
1.442 - player->bInExternMenu = false;
1.443 - player->menuStartTime = gpGlobals->curtime;
1.444 - player->menuHoldTime = time;
1.445 -
1.446 - if (time)
1.447 - {
1.448 - AddClientToWatch(client);
1.449 - }
1.450 -
1.451 - /* Draw the display */
1.452 - SendDisplay(client, menu);
1.453 -
1.454 - /* We can be interrupted again! */
1.455 - player->bAutoIgnore = false;
1.456 -
1.457 - return true;
1.458 -}
1.459 -
1.460 -bool BaseMenuStyle::DoClientMenu(int client,
1.461 - CBaseMenu *menu,
1.462 - unsigned int first_item,
1.463 - IMenuHandler *mh,
1.464 - unsigned int time)
1.465 -{
1.466 -#if defined MENU_DEBUG
1.467 - g_Logger.LogMessage("[SM_MENU] DoClientMenu() (client %d) (menu %p) (mh %p) (time %d)",
1.468 - client,
1.469 - menu,
1.470 - mh,
1.471 - time);
1.472 -#endif
1.473 - mh->OnMenuStart(menu);
1.474 -
1.475 - CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
1.476 - if (!pPlayer || pPlayer->IsFakeClient() || !pPlayer->IsInGame())
1.477 - {
1.478 -#if defined MENU_DEBUG
1.479 - g_Logger.LogMessage("[SM_MENU] DoClientMenu(): Failed to display to client %d", client);
1.480 -#endif
1.481 - mh->OnMenuCancel(menu, client, MenuCancel_NoDisplay);
1.482 - mh->OnMenuEnd(menu, MenuEnd_Cancelled);
1.483 - return false;
1.484 - }
1.485 -
1.486 - CBaseMenuPlayer *player = GetMenuPlayer(client);
1.487 - if (player->bAutoIgnore)
1.488 - {
1.489 -#if defined MENU_DEBUG
1.490 - g_Logger.LogMessage("[SM_MENU] DoClientMenu(): Client %d is autoIgnoring", client);
1.491 -#endif
1.492 - mh->OnMenuCancel(menu, client, MenuCancel_NoDisplay);
1.493 - mh->OnMenuEnd(menu, MenuEnd_Cancelled);
1.494 - return false;
1.495 - }
1.496 -
1.497 - /* For the duration of this, we are going to totally ignore whether
1.498 - * the player is already in a menu or not (except to cancel the old one).
1.499 - * Instead, we are simply going to ignore any further menu displays, so
1.500 - * this display can't be interrupted.
1.501 - */
1.502 - player->bAutoIgnore = true;
1.503 -
1.504 - /* Cancel any old menus */
1.505 - menu_states_t &states = player->states;
1.506 - if (player->bInMenu)
1.507 - {
1.508 -#if defined MENU_DEBUG
1.509 - g_Logger.LogMessage("[SM_MENU] DoClientMenu(): Cancelling old menu to client %d", client);
1.510 -#endif
1.511 - _CancelClientMenu(client, MenuCancel_Interrupted, true);
1.512 - }
1.513 -
1.514 - states.firstItem = 0;
1.515 - states.lastItem = first_item;
1.516 - states.menu = menu;
1.517 - states.mh = mh;
1.518 - states.apiVers = SMINTERFACE_MENUMANAGER_VERSION;
1.519 -
1.520 - IMenuPanel *display = g_Menus.RenderMenu(client, states, ItemOrder_Ascending);
1.521 - if (!display)
1.522 - {
1.523 -#if defined MENU_DEBUG
1.524 - g_Logger.LogMessage("[SM_MENU] DoClientMenu(): Failed to render to client %d", client);
1.525 -#endif
1.526 - player->bAutoIgnore = false;
1.527 - player->bInMenu = false;
1.528 - mh->OnMenuCancel(menu, client, MenuCancel_NoDisplay);
1.529 - mh->OnMenuEnd(menu, MenuEnd_Cancelled);
1.530 - return false;
1.531 - }
1.532 -
1.533 - /* Finally, set our states */
1.534 - player->bInMenu = true;
1.535 - player->bInExternMenu = false;
1.536 - player->menuStartTime = gpGlobals->curtime;
1.537 - player->menuHoldTime = time;
1.538 -
1.539 - if (time)
1.540 - {
1.541 - AddClientToWatch(client);
1.542 - }
1.543 -
1.544 - /* Draw the display */
1.545 - SendDisplay(client, display);
1.546 -
1.547 - /* Free the display pointer */
1.548 - display->DeleteThis();
1.549 -
1.550 - /* We can be interrupted again! */
1.551 - player->bAutoIgnore = false;
1.552 -
1.553 -#if defined MENU_DEBUG
1.554 - g_Logger.LogMessage("[SM_MENU] DoClientMenu() finished successfully (client %d)", client);
1.555 -#endif
1.556 -
1.557 - return true;
1.558 -}
1.559 -
1.560 -bool BaseMenuStyle::RedoClientMenu(int client, ItemOrder order)
1.561 -{
1.562 -#if defined MENU_DEBUG
1.563 - g_Logger.LogMessage("[SM_MENU] RedoClientMenu() (client %d) (order %d)", client, order);
1.564 -#endif
1.565 - CBaseMenuPlayer *player = GetMenuPlayer(client);
1.566 - menu_states_t &states = player->states;
1.567 -
1.568 - player->bAutoIgnore = true;
1.569 - IMenuPanel *display = g_Menus.RenderMenu(client, states, order);
1.570 - if (!display)
1.571 - {
1.572 -#if defined MENU_DEBUG
1.573 - g_Logger.LogMessage("[SM_MENU] RedoClientMenu(): Failed to render menu");
1.574 -#endif
1.575 - if (player->menuHoldTime)
1.576 - {
1.577 - RemoveClientFromWatch(client);
1.578 - }
1.579 - player->bAutoIgnore = false;
1.580 - return false;
1.581 - }
1.582 -
1.583 - SendDisplay(client, display);
1.584 -
1.585 - display->DeleteThis();
1.586 -
1.587 - player->bAutoIgnore = false;
1.588 -
1.589 -#if defined MENU_DEBUG
1.590 - g_Logger.LogMessage("[SM_MENU] RedoClientMenu(): Succeeded to client %d", client);
1.591 -#endif
1.592 -
1.593 - return true;
1.594 -}
1.595 -
1.596 -CBaseMenu::CBaseMenu(IMenuHandler *pHandler, IMenuStyle *pStyle, IdentityToken_t *pOwner) :
1.597 -m_pStyle(pStyle), m_Strings(512), m_Pagination(7), m_bShouldDelete(false), m_bCancelling(false),
1.598 -m_pOwner(pOwner ? pOwner : g_pCoreIdent), m_bDeleting(false), m_bWillFreeHandle(false),
1.599 -m_hHandle(BAD_HANDLE), m_pHandler(pHandler), m_nFlags(MENUFLAG_BUTTON_EXIT)
1.600 -{
1.601 -}
1.602 -
1.603 -CBaseMenu::~CBaseMenu()
1.604 -{
1.605 -}
1.606 -
1.607 -Handle_t CBaseMenu::GetHandle()
1.608 -{
1.609 - if (!m_hHandle)
1.610 - {
1.611 - m_hHandle = g_Menus.CreateMenuHandle(this, m_pOwner);
1.612 - }
1.613 -
1.614 - return m_hHandle;
1.615 -}
1.616 -
1.617 -bool CBaseMenu::AppendItem(const char *info, const ItemDrawInfo &draw)
1.618 -{
1.619 - if (m_Pagination == (unsigned)MENU_NO_PAGINATION
1.620 - && m_items.size() >= m_pStyle->GetMaxPageItems())
1.621 - {
1.622 - return false;
1.623 - }
1.624 -
1.625 - CItem item;
1.626 -
1.627 - item.infoString = m_Strings.AddString(info);
1.628 - if (draw.display)
1.629 - {
1.630 - item.displayString = m_Strings.AddString(draw.display);
1.631 - }
1.632 - item.style = draw.style;
1.633 -
1.634 - m_items.push_back(item);
1.635 -
1.636 - return true;
1.637 -}
1.638 -
1.639 -bool CBaseMenu::InsertItem(unsigned int position, const char *info, const ItemDrawInfo &draw)
1.640 -{
1.641 - if (m_Pagination == (unsigned)MENU_NO_PAGINATION
1.642 - && m_items.size() >= m_pStyle->GetMaxPageItems())
1.643 - {
1.644 - return false;
1.645 - }
1.646 -
1.647 - if (position >= m_items.size())
1.648 - {
1.649 - return false;
1.650 - }
1.651 -
1.652 - CItem item;
1.653 - item.infoString = m_Strings.AddString(info);
1.654 - if (draw.display)
1.655 - {
1.656 - item.displayString = m_Strings.AddString(draw.display);
1.657 - }
1.658 - item.style = draw.style;
1.659 -
1.660 - CVector<CItem>::iterator iter = m_items.iterAt(position);
1.661 - m_items.insert(iter, item);
1.662 -
1.663 - return true;
1.664 -}
1.665 -
1.666 -bool CBaseMenu::RemoveItem(unsigned int position)
1.667 -{
1.668 - if (position >= m_items.size())
1.669 - {
1.670 - return false;
1.671 - }
1.672 -
1.673 - m_items.erase(m_items.iterAt(position));
1.674 -
1.675 - if (m_items.size() == 0)
1.676 - {
1.677 - m_Strings.Reset();
1.678 - }
1.679 -
1.680 - return true;
1.681 -}
1.682 -
1.683 -void CBaseMenu::RemoveAllItems()
1.684 -{
1.685 - m_items.clear();
1.686 - m_Strings.Reset();
1.687 -}
1.688 -
1.689 -const char *CBaseMenu::GetItemInfo(unsigned int position, ItemDrawInfo *draw/* =NULL */)
1.690 -{
1.691 - if (position >= m_items.size())
1.692 - {
1.693 - return NULL;
1.694 - }
1.695 -
1.696 - if (draw)
1.697 - {
1.698 - draw->display = m_Strings.GetString(m_items[position].displayString);
1.699 - draw->style = m_items[position].style;
1.700 - }
1.701 -
1.702 - return m_Strings.GetString(m_items[position].infoString);
1.703 -}
1.704 -
1.705 -unsigned int CBaseMenu::GetItemCount()
1.706 -{
1.707 - return m_items.size();
1.708 -}
1.709 -
1.710 -bool CBaseMenu::SetPagination(unsigned int itemsPerPage)
1.711 -{
1.712 - if (itemsPerPage > 7 || itemsPerPage == 1)
1.713 - {
1.714 - return false;
1.715 - }
1.716 -
1.717 - if (itemsPerPage == MENU_NO_PAGINATION
1.718 - && m_Pagination != MENU_NO_PAGINATION)
1.719 - {
1.720 - m_nFlags &= ~MENUFLAG_BUTTON_EXIT;
1.721 - }
1.722 -
1.723 - m_Pagination = itemsPerPage;
1.724 -
1.725 - return true;
1.726 -}
1.727 -
1.728 -unsigned int CBaseMenu::GetPagination()
1.729 -{
1.730 - return m_Pagination;
1.731 -}
1.732 -
1.733 -IMenuStyle *CBaseMenu::GetDrawStyle()
1.734 -{
1.735 - return m_pStyle;
1.736 -}
1.737 -
1.738 -void CBaseMenu::SetDefaultTitle(const char *message)
1.739 -{
1.740 - m_Title.assign(message);
1.741 -}
1.742 -
1.743 -const char *CBaseMenu::GetDefaultTitle()
1.744 -{
1.745 - return m_Title.c_str();
1.746 -}
1.747 -
1.748 -void CBaseMenu::Cancel()
1.749 -{
1.750 - if (m_bCancelling)
1.751 - {
1.752 - return;
1.753 - }
1.754 -
1.755 -#if defined MENU_DEBUG
1.756 - g_Logger.LogMessage("[SM_MENU] CBaseMenu::Cancel(%p) (m_bShouldDelete %d)",
1.757 - this,
1.758 - m_bShouldDelete);
1.759 -#endif
1.760 -
1.761 - m_bCancelling = true;
1.762 - Cancel_Finally();
1.763 - m_bCancelling = false;
1.764 -
1.765 - if (m_bShouldDelete)
1.766 - {
1.767 - InternalDelete();
1.768 - }
1.769 -}
1.770 -
1.771 -void CBaseMenu::Destroy(bool releaseHandle)
1.772 -{
1.773 - /* Check if we shouldn't be here */
1.774 - if (m_bDeleting)
1.775 - {
1.776 - return;
1.777 - }
1.778 -
1.779 -#if defined MENU_DEBUG
1.780 - g_Logger.LogMessage("[SM_MENU] CBaseMenu::Destroy(%p) (release %d) (m_bCancelling %d) (m_bShouldDelete %d)",
1.781 - this,
1.782 - releaseHandle,
1.783 - m_bCancelling,
1.784 - m_bShouldDelete);
1.785 -#endif
1.786 -
1.787 - /* Save the destruction hint about our handle */
1.788 - m_bWillFreeHandle = releaseHandle;
1.789 -
1.790 - /* Now actually do stuff */
1.791 - if (!m_bCancelling || m_bShouldDelete)
1.792 - {
1.793 - Cancel();
1.794 - InternalDelete();
1.795 - } else {
1.796 - m_bShouldDelete = true;
1.797 - }
1.798 -}
1.799 -
1.800 -void CBaseMenu::InternalDelete()
1.801 -{
1.802 - if (m_bWillFreeHandle && m_hHandle != BAD_HANDLE)
1.803 - {
1.804 - Handle_t hndl = m_hHandle;
1.805 - HandleSecurity sec;
1.806 -
1.807 - sec.pOwner = m_pOwner;
1.808 - sec.pIdentity = g_pCoreIdent;
1.809 -
1.810 - m_hHandle = BAD_HANDLE;
1.811 - m_bDeleting = true;
1.812 - g_HandleSys.FreeHandle(hndl, &sec);
1.813 - }
1.814 -
1.815 - m_pHandler->OnMenuDestroy(this);
1.816 -
1.817 - delete this;
1.818 -}
1.819 -
1.820 -unsigned int CBaseMenu::GetMenuOptionFlags()
1.821 -{
1.822 - return m_nFlags;
1.823 -}
1.824 -
1.825 -void CBaseMenu::SetMenuOptionFlags(unsigned int flags)
1.826 -{
1.827 - m_nFlags = flags;
1.828 -}
1.829 -
1.830 -IMenuHandler *CBaseMenu::GetHandler()
1.831 -{
1.832 - return m_pHandler;
1.833 -}