From 38f95fc63dfd4a013afeb89b8959d482547133b3 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Fri, 22 Jun 2007 21:04:13 +0000 Subject: [PATCH] - added request amb426 - "Back" is now "Previous" and "Back" is used for ExitBack - menu api got bumped again, but will be compat --HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%401011 --- core/MenuManager.cpp | 28 ++++++++++++++++++---- core/MenuStyle_Base.cpp | 43 ++++++++++++++++++++------------- core/MenuStyle_Base.h | 9 ++++--- core/MenuStyle_Radio.cpp | 2 +- core/MenuStyle_Valve.cpp | 2 +- core/smn_menus.cpp | 32 +++++++++++++++++++++++++ plugins/include/menus.inc | 50 ++++++++++++++++++++++++++++++--------- public/IMenuManager.h | 42 +++++++++++++++++++++++--------- translations/core.cfg | 5 ++++ 9 files changed, 166 insertions(+), 47 deletions(-) diff --git a/core/MenuManager.cpp b/core/MenuManager.cpp index ae08708d..1490e798 100644 --- a/core/MenuManager.cpp +++ b/core/MenuManager.cpp @@ -625,6 +625,7 @@ skip_search: { bool canDrawDisabled = display->CanDrawItem(ITEMDRAW_DISABLED|ITEMDRAW_CONTROL); bool exitButton = menu->GetExitButton(); + bool exitBackButton = menu->GetExitBackButton(); char text[50]; /* Calculate how many items we are allowed for control stuff */ @@ -650,6 +651,17 @@ skip_search: /* Subtract two slots for the displayNext/displayPrev padding */ padding -= 2; + /* If we have an "Exit Back" button and the space to draw it, do so. */ + if (exitBackButton) + { + if (!displayPrev) + { + displayPrev = true; + } else { + exitBackButton = false; + } + } + /** * We allow next/prev to be undrawn if neither exists. * Thus, we only need padding if one of them will be drawn, @@ -690,10 +702,18 @@ skip_search: ItemDrawInfo padCtrlItem(NULL, ITEMDRAW_SPACER|ITEMDRAW_CONTROL); if (displayPrev || canDrawDisabled) { - CorePlayerTranslate(client, text, sizeof(text), "Back", NULL); - dr.style = (displayPrev ? 0 : ITEMDRAW_DISABLED)|ITEMDRAW_CONTROL; - position = display->DrawItem(dr); - slots[position].type = ItemSel_Back; + if (exitBackButton) + { + CorePlayerTranslate(client, text, sizeof(text), "Back", NULL); + dr.style = ITEMDRAW_CONTROL; + position = display->DrawItem(dr); + slots[position].type = ItemSel_ExitBack; + } else { + CorePlayerTranslate(client, text, sizeof(text), "Previous", NULL); + dr.style = (displayPrev ? 0 : ITEMDRAW_DISABLED)|ITEMDRAW_CONTROL; + position = display->DrawItem(dr); + slots[position].type = ItemSel_Back; + } } else if (displayNext || exitButton) { /* If we can't display this, and there is an exit button, * we need to pad! diff --git a/core/MenuStyle_Base.cpp b/core/MenuStyle_Base.cpp index 8ec4c648..9c4d27fe 100644 --- a/core/MenuStyle_Base.cpp +++ b/core/MenuStyle_Base.cpp @@ -53,7 +53,7 @@ void BaseMenuStyle::RemoveClientFromWatch(int client) m_WatchList.remove(client); } -void BaseMenuStyle::_CancelClientMenu(int client, bool bAutoIgnore/* =false */, MenuCancelReason reason/* =MenuCancel_Interrupt */) +void BaseMenuStyle::_CancelClientMenu(int client, MenuCancelReason reason, bool bAutoIgnore/* =false */) { #if defined MENU_DEBUG g_Logger.LogMessage("[SM_MENU] _CancelClientMenu() (client %d) (bAutoIgnore %d) (reason %d)", client, bAutoIgnore, reason); @@ -107,7 +107,7 @@ void BaseMenuStyle::CancelMenu(CBaseMenu *menu) menu_states_t &states = player->states; if (states.menu == menu) { - _CancelClientMenu(i); + _CancelClientMenu(i, MenuCancel_Interrupted); } } } @@ -129,7 +129,7 @@ bool BaseMenuStyle::CancelClientMenu(int client, bool autoIgnore) return false; } - _CancelClientMenu(client, autoIgnore); + _CancelClientMenu(client, MenuCancel_Interrupted, autoIgnore); return true; } @@ -180,7 +180,7 @@ void BaseMenuStyle::OnClientDisconnected(int client) return; } - _CancelClientMenu(client, true, MenuCancel_Disconnect); + _CancelClientMenu(client, MenuCancel_Disconnected, true); player->bInMenu = false; player->bInExternMenu = false; @@ -232,7 +232,7 @@ void BaseMenuStyle::ProcessWatchList() } if (curTime > player->menuStartTime + player->menuHoldTime) { - _CancelClientMenu(client, false); + _CancelClientMenu(client, MenuCancel_Timeout, false); } } } @@ -253,6 +253,7 @@ void BaseMenuStyle::ClientPressedKey(int client, unsigned int key_press) bool cancel = false; unsigned int item = 0; MenuCancelReason reason = MenuCancel_Exit; + MenuEndReason end_reason = MenuEnd_Selected; menu_states_t &states = player->states; assert(states.mh != NULL); @@ -272,6 +273,7 @@ void BaseMenuStyle::ClientPressedKey(int client, unsigned int key_press) { cancel = true; reason = MenuCancel_NoDisplay; + end_reason = MenuEnd_Cancelled; } else { return; } @@ -280,11 +282,18 @@ void BaseMenuStyle::ClientPressedKey(int client, unsigned int key_press) { cancel = true; /* I like Saltines. */ reason = MenuCancel_NoDisplay; + end_reason = MenuEnd_Cancelled; } else { return; } } else if (type == ItemSel_Exit || type == ItemSel_None) { cancel = true; + reason = MenuCancel_Exit; + end_reason = MenuEnd_Exit; + } else if (type == ItemSel_ExitBack) { + cancel = true; + reason = MenuCancel_ExitBack; + end_reason = MenuEnd_ExitBack; } else { item = states.slots[key_press].item; } @@ -311,14 +320,6 @@ void BaseMenuStyle::ClientPressedKey(int client, unsigned int key_press) /* Only fire end for valid menus */ if (menu) { - MenuEndReason end_reason = - (cancel ? - MenuEnd_Selected - : - (reason == MenuCancel_Exit ? - MenuEnd_Exit - : - MenuEnd_Cancelled)); mh->OnMenuEnd(menu, end_reason); } } @@ -355,7 +356,7 @@ bool BaseMenuStyle::DoClientMenu(int client, IMenuPanel *menu, IMenuHandler *mh, menu_states_t &states = player->states; if (player->bInMenu) { - _CancelClientMenu(client, true); + _CancelClientMenu(client, MenuCancel_Interrupted, true); } states.firstItem = 0; @@ -429,7 +430,7 @@ bool BaseMenuStyle::DoClientMenu(int client, CBaseMenu *menu, IMenuHandler *mh, #if defined MENU_DEBUG g_Logger.LogMessage("[SM_MENU] DoClientMenu(): Cancelling old menu to client %d", client); #endif - _CancelClientMenu(client, true); + _CancelClientMenu(client, MenuCancel_Interrupted, true); } states.firstItem = 0; @@ -518,7 +519,7 @@ CBaseMenu::CBaseMenu(IMenuHandler *pHandler, IMenuStyle *pStyle, IdentityToken_t m_pStyle(pStyle), m_Strings(512), m_Pagination(7), m_ExitButton(true), m_bShouldDelete(false), m_bCancelling(false), m_pOwner(pOwner ? pOwner : g_pCoreIdent), m_bDeleting(false), m_bWillFreeHandle(false), m_hHandle(BAD_HANDLE), m_pHandler(pHandler), -m_pVoteHandler(NULL) +m_pVoteHandler(NULL), m_ExitBackButton(false) { } @@ -789,3 +790,13 @@ bool CBaseMenu::IsVoteInProgress() { return (m_pVoteHandler && m_pVoteHandler->IsVoteInProgress()); } + +bool CBaseMenu::GetExitBackButton() +{ + return m_ExitBackButton; +} + +void CBaseMenu::SetExitBackButton(bool set) +{ + m_ExitBackButton = set; +} diff --git a/core/MenuStyle_Base.h b/core/MenuStyle_Base.h index b68d25b2..08bcd608 100644 --- a/core/MenuStyle_Base.h +++ b/core/MenuStyle_Base.h @@ -81,7 +81,7 @@ public: //helpers void CancelMenu(CBaseMenu *menu); void ClientPressedKey(int client, unsigned int key_press); protected: - void _CancelClientMenu(int client, bool bAutoIgnore=false, MenuCancelReason reason=MenuCancel_Interrupt); + void _CancelClientMenu(int client, MenuCancelReason reason, bool bAutoIgnore=false); bool RedoClientMenu(int client, ItemOrder order); protected: FastLink m_WatchList; @@ -111,11 +111,13 @@ public: virtual void Destroy(bool releaseHandle); virtual void Cancel_Finally() =0; virtual Handle_t GetHandle(); - bool BroadcastVote(int clients[], + virtual bool BroadcastVote(int clients[], unsigned int numClients, unsigned int maxTime, unsigned int flags=0); - bool IsVoteInProgress(); + virtual bool IsVoteInProgress(); + virtual bool GetExitBackButton(); + virtual void SetExitBackButton(bool set); public: virtual void VoteDisplay(int client, unsigned int maxTime) =0; private: @@ -135,6 +137,7 @@ protected: Handle_t m_hHandle; IMenuHandler *m_pHandler; IVoteMenuHandler *m_pVoteHandler; + bool m_ExitBackButton; }; #endif //_INCLUDE_MENUSTYLE_BASE_H diff --git a/core/MenuStyle_Radio.cpp b/core/MenuStyle_Radio.cpp index bf2c52b1..d680a267 100644 --- a/core/MenuStyle_Radio.cpp +++ b/core/MenuStyle_Radio.cpp @@ -130,7 +130,7 @@ void CRadioStyle::OnUserMessageSent(int msg_id) #endif if (m_players[client].bInMenu) { - _CancelClientMenu(client, true); + _CancelClientMenu(client, MenuCancel_Interrupted, true); } m_players[client].bInExternMenu = true; m_players[client].menuHoldTime = g_last_holdtime; diff --git a/core/MenuStyle_Valve.cpp b/core/MenuStyle_Valve.cpp index 7aec30af..ae7ee02c 100644 --- a/core/MenuStyle_Valve.cpp +++ b/core/MenuStyle_Valve.cpp @@ -95,7 +95,7 @@ void ValveMenuStyle::HookCreateMessage(edict_t *pEdict, * day to avenge its grandfather, killed in the great Menu Interruption * battle. */ - _CancelClientMenu(client, true); + _CancelClientMenu(client, MenuCancel_Interrupted, true); } } diff --git a/core/smn_menus.cpp b/core/smn_menus.cpp index decb11e2..d5be9637 100644 --- a/core/smn_menus.cpp +++ b/core/smn_menus.cpp @@ -617,6 +617,20 @@ static cell_t GetMenuExitButton(IPluginContext *pContext, const cell_t *params) return menu->GetExitButton() ? 1 : 0; } +static cell_t GetMenuExitBackButton(IPluginContext *pContext, const cell_t *params) +{ + Handle_t hndl = (Handle_t)params[1]; + HandleError err; + IBaseMenu *menu; + + if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None) + { + return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err); + } + + return menu->GetExitBackButton() ? 1 : 0; +} + static cell_t SetMenuExitButton(IPluginContext *pContext, const cell_t *params) { Handle_t hndl = (Handle_t)params[1]; @@ -631,6 +645,22 @@ static cell_t SetMenuExitButton(IPluginContext *pContext, const cell_t *params) return menu->SetExitButton(params[2] ? true : false) ? 1 : 0; } +static cell_t SetMenuExitBackButton(IPluginContext *pContext, const cell_t *params) +{ + Handle_t hndl = (Handle_t)params[1]; + HandleError err; + IBaseMenu *menu; + + if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None) + { + return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err); + } + + menu->SetExitBackButton(params[2] ? true : false); + + return 1; +} + static cell_t CancelMenu(IPluginContext *pContext, const cell_t *params) { Handle_t hndl = (Handle_t)params[1]; @@ -971,6 +1001,7 @@ REGISTER_NATIVES(menuNatives) {"DrawPanelText", DrawPanelText}, {"GetClientMenu", GetClientMenu}, {"GetMaxPageItems", GetMaxPageItems}, + {"GetMenuExitBackButton", GetMenuExitBackButton}, {"GetMenuExitButton", GetMenuExitButton}, {"GetMenuItem", GetMenuItem}, {"GetMenuItemCount", GetMenuItemCount}, @@ -984,6 +1015,7 @@ REGISTER_NATIVES(menuNatives) {"RemoveAllMenuItems", RemoveAllMenuItems}, {"RemoveMenuItem", RemoveMenuItem}, {"SendPanelToClient", SendPanelToClient}, + {"SetMenuExitBackButton", SetMenuExitBackButton}, {"SetMenuExitButton", SetMenuExitButton}, {"SetMenuPagination", SetMenuPagination}, {"SetMenuTitle", SetMenuTitle}, diff --git a/plugins/include/menus.inc b/plugins/include/menus.inc index e931bb0d..1b7b7e3b 100644 --- a/plugins/include/menus.inc +++ b/plugins/include/menus.inc @@ -37,7 +37,7 @@ enum MenuAction MenuAction_Display = (1<<1), /**< A menu is about to be displayed (param1=client, param2=MenuPanel Handle) */ MenuAction_Select = (1<<2), /**< An item was selected (param1=client, param2=item) */ MenuAction_Cancel = (1<<3), /**< The menu was cancelled (param1=client, param2=reason) */ - MenuAction_End = (1<<4), /**< A menu display has fully ended (param1=reason) */ + MenuAction_End = (1<<4), /**< A menu display has fully ended (param1=reason, param2=cancel reason) */ MenuAction_VoteEnd = (1<<5), /**< (VOTE ONLY): A vote sequence has succeeded (param1=chosen item) */ MenuAction_VoteStart = (1<<6), /**< (VOTE ONLY): A vote sequence has started (nothing passed) */ MenuAction_VoteCancel = (1<<7), /**< (VOTE ONLY): A vote sequence has been cancelled (nothing passed) */ @@ -64,22 +64,25 @@ enum MenuAction */ enum { - MenuCancel_Disconnect = -1, /**< Client dropped from the server */ - MenuCancel_Interrupt = -2, /**< Client was interrupted with another menu */ - MenuCancel_Exit = -3, /**< Client selected "exit" on a paginated menu */ - MenuCancel_NoDisplay = -4, /**< Menu could not be displayed to the client */ + MenuCancel_Disconnected = -1, /**< Client dropped from the server */ + MenuCancel_Interrupted = -2, /**< Client was interrupted with another menu */ + MenuCancel_Exit = -3, /**< Client exited via "exit" */ + MenuCancel_NoDisplay = -4, /**< Menu could not be displayed to the client */ + MenuCancel_Timeout = -5, /**< Menu timed out */ + MenuCancel_ExitBack = -6, /**< Client selected "exit back" on a paginated menu */ }; /** * Reasons a menu ended. */ -enum +enum MenuEndReason { - MenuEnd_Cancelled = -1, /**< Menu was cancelled, reason was passed in MenuAction_Cancel */ - MenuEnd_Exit = -2, /**< Menu was cleanly exited (but cancelled) */ - MenuEnd_Selected = -3, /**< Menu item was selected and thus the menu is finished */ - MenuEnd_VotingDone = -4, /**< Voting finished */ - MenuEnd_VotingCancelled = -5, /**< Voting was cancelled */ + MenuEnd_Selected = 0, /**< Menu item was selected */ + MenuEnd_VotingDone = -1, /**< Voting finished */ + MenuEnd_VotingCancelled = -2, /**< Voting was cancelled */ + MenuEnd_Cancelled = -3, /**< Menu was cancelled (reason in param2) */ + MenuEnd_Exit = -4, /**< Menu was cleanly exited via "exit" */ + MenuEnd_ExitBack = -5, /**< Menu was cleanly exited via "back" */ }; /** @@ -273,6 +276,31 @@ native bool:GetMenuExitButton(Handle:menu); */ native bool:SetMenuExitButton(Handle:menu, bool:button); +/** + * Returns whether or not the menu has an "exit back" button. + * By default, menus do not have an exit back button. + * Exit Back buttons appear as "Back" on page 1 of paginated menus and + * have functionality defined by the user in MenuEnd_ExitBack. + * + * @param menu Menu Handle. + * @return True if the menu has an exit back button; false otherwise. + * @error Invalid Handle. + */ +native bool:GetMenuExitBackButton(Handle:menu); + +/** + * Sets whether or not the menu has an "exit back" button. + * By default, menus do not have an exit back button. + * Exit Back buttons appear as "Back" on page 1 of paginated menus and + * have functionality defined by the user in MenuEnd_ExitBack. + * + * @param menu Menu Handle. + * @param button True to enable the button, false to remove it. + * @error Invalid Handle. + */ +native SetMenuExitBackButton(Handle:menu, bool:button); + + /** * Cancels a menu from displaying on all clients. While the * cancellation is in progress, this menu cannot be re-displayed diff --git a/public/IMenuManager.h b/public/IMenuManager.h index 02cc851e..f2d9b708 100644 --- a/public/IMenuManager.h +++ b/public/IMenuManager.h @@ -23,7 +23,7 @@ #include #define SMINTERFACE_MENUMANAGER_NAME "IMenuManager" -#define SMINTERFACE_MENUMANAGER_VERSION 5 +#define SMINTERFACE_MENUMANAGER_VERSION 6 /** * @file IMenuManager.h @@ -38,10 +38,11 @@ namespace SourceMod enum ItemSelection { ItemSel_None, /**< Invalid selection */ - ItemSel_Back, /**< Go back one page */ + ItemSel_Back, /**< Go back one page (really "Previous") */ ItemSel_Next, /**< Go forward one page */ ItemSel_Exit, /**< Menu was exited */ ItemSel_Item, /**< Valid item selection */ + ItemSel_ExitBack, /**< Sends MenuEnd_ExitBack */ }; /** @@ -110,10 +111,12 @@ namespace SourceMod */ enum MenuCancelReason { - MenuCancel_Disconnect = -1, /**< Client dropped from the server */ - MenuCancel_Interrupt = -2, /**< Client was interrupted with another menu */ - MenuCancel_Exit = -3, /**< Client selected "exit" on a paginated menu */ - MenuCancel_NoDisplay = -4, /**< Menu could not be displayed to the client */ + MenuCancel_Disconnected = -1, /**< Client dropped from the server */ + MenuCancel_Interrupted = -2, /**< Client was interrupted with another menu */ + MenuCancel_Exit = -3, /**< Client selected "exit" on a paginated menu */ + MenuCancel_NoDisplay = -4, /**< Menu could not be displayed to the client */ + MenuCancel_Timeout = -5, /**< Menu timed out */ + MenuCancel_ExitBack = -6, /**< Client selected "exit back" on a paginated menu */ }; /** @@ -121,11 +124,12 @@ namespace SourceMod */ enum MenuEndReason { - MenuEnd_Cancelled = -1, /**< Menu was cancelled, reason was passed in MenuAction_Cancel */ - MenuEnd_Exit = -2, /**< Menu was cleanly exited (but cancelled) */ - MenuEnd_Selected = -3, /**< Menu item was selected and thus the menu is finished */ - MenuEnd_VotingDone = -4, /**< Voting finished */ - MenuEnd_VotingCancelled = -5, /**< Voting was cancelled */ + MenuEnd_Selected = 0, /**< Menu item was selected */ + MenuEnd_VotingDone = -1, /**< Voting finished */ + MenuEnd_VotingCancelled = -2, /**< Voting was cancelled */ + MenuEnd_Cancelled = -3, /**< Menu was uncleanly cancelled */ + MenuEnd_Exit = -4, /**< Menu was cleanly exited via "exit" */ + MenuEnd_ExitBack = -5, /**< Menu was cleanly exited via "back" */ }; @@ -536,6 +540,22 @@ namespace SourceMod * @return True if a vote menu is active, false otherwise. */ virtual bool IsVoteInProgress() =0; + + /** + * @brief Returns whether to draw a "Back" button on the first page. + * ExitBack buttons are disabled by default. + * + * @return True if enabled, false otherwise. + */ + virtual bool GetExitBackButton() =0; + + /** + * @brief Sets whether to draw a "Back" button on the first page. + * ExitBack buttons are disabled by default. + * + * @param set True to enable, false to disable. + */ + virtual void SetExitBackButton(bool set) =0; }; /** diff --git a/translations/core.cfg b/translations/core.cfg index d096fadb..2ee6f2c8 100644 --- a/translations/core.cfg +++ b/translations/core.cfg @@ -19,4 +19,9 @@ { "en" "Exit" } + + "Previous" + { + "en" "Previous" + } }