redid API yet again - IMenuHandler is now bound to an IBaseMenu instance
implemented MOST natives removed broadcasting/voting handlers for the time being fixed a crash bug in basecontext when i didn't obey the api moved radio displays to a caching stack --HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40796
This commit is contained in:
parent
d1dea716a6
commit
49369d07bc
@ -21,6 +21,7 @@
|
|||||||
#include "PlayerManager.h"
|
#include "PlayerManager.h"
|
||||||
#include "MenuStyle_Valve.h"
|
#include "MenuStyle_Valve.h"
|
||||||
#include "ShareSys.h"
|
#include "ShareSys.h"
|
||||||
|
#include "HandleSys.h"
|
||||||
|
|
||||||
MenuManager g_Menus;
|
MenuManager g_Menus;
|
||||||
|
|
||||||
@ -150,10 +151,24 @@ MenuManager::MenuManager()
|
|||||||
void MenuManager::OnSourceModAllInitialized()
|
void MenuManager::OnSourceModAllInitialized()
|
||||||
{
|
{
|
||||||
g_ShareSys.AddInterface(NULL, this);
|
g_ShareSys.AddInterface(NULL, this);
|
||||||
|
|
||||||
|
HandleAccess access;
|
||||||
|
g_HandleSys.InitAccessDefaults(NULL, &access);
|
||||||
|
|
||||||
|
/* Deny cloning to menus */
|
||||||
|
access.access[HandleAccess_Clone] = HANDLE_RESTRICT_OWNER|HANDLE_RESTRICT_IDENTITY;
|
||||||
|
m_MenuType = g_HandleSys.CreateType("IBaseMenu", this, 0, NULL, &access, g_pCoreIdent, NULL);
|
||||||
|
|
||||||
|
/* Also deny deletion to styles */
|
||||||
|
access.access[HandleAccess_Delete] = HANDLE_RESTRICT_OWNER|HANDLE_RESTRICT_IDENTITY;
|
||||||
|
m_StyleType = g_HandleSys.CreateType("IMenuStyle", this, 0, NULL, &access, g_pCoreIdent, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuManager::OnSourceModAllShutdown()
|
void MenuManager::OnSourceModAllShutdown()
|
||||||
{
|
{
|
||||||
|
g_HandleSys.RemoveType(m_MenuType, g_pCoreIdent);
|
||||||
|
g_HandleSys.RemoveType(m_StyleType, g_pCoreIdent);
|
||||||
|
|
||||||
while (!m_BroadcastHandlers.empty())
|
while (!m_BroadcastHandlers.empty())
|
||||||
{
|
{
|
||||||
delete m_BroadcastHandlers.front();
|
delete m_BroadcastHandlers.front();
|
||||||
@ -167,6 +182,57 @@ void MenuManager::OnSourceModAllShutdown()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MenuManager::OnHandleDestroy(HandleType_t type, void *object)
|
||||||
|
{
|
||||||
|
if (type == m_MenuType)
|
||||||
|
{
|
||||||
|
IBaseMenu *menu = (IBaseMenu *)object;
|
||||||
|
menu->Destroy(false);
|
||||||
|
} else if (type == m_StyleType) {
|
||||||
|
/* Do nothing */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Handle_t MenuManager::CreateMenuHandle(IBaseMenu *menu, IdentityToken_t *pOwner)
|
||||||
|
{
|
||||||
|
if (m_MenuType == NO_HANDLE_TYPE)
|
||||||
|
{
|
||||||
|
return BAD_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return g_HandleSys.CreateHandle(m_MenuType, menu, pOwner, g_pCoreIdent, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
Handle_t MenuManager::CreateStyleHandle(IMenuStyle *style)
|
||||||
|
{
|
||||||
|
if (m_StyleType == NO_HANDLE_TYPE)
|
||||||
|
{
|
||||||
|
return BAD_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return g_HandleSys.CreateHandle(m_StyleType, style, g_pCoreIdent, g_pCoreIdent, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
HandleError MenuManager::ReadMenuHandle(Handle_t handle, IBaseMenu **menu)
|
||||||
|
{
|
||||||
|
HandleSecurity sec;
|
||||||
|
|
||||||
|
sec.pIdentity = g_pCoreIdent;
|
||||||
|
sec.pOwner = NULL;
|
||||||
|
|
||||||
|
return g_HandleSys.ReadHandle(handle, m_MenuType, &sec, (void **)menu);
|
||||||
|
}
|
||||||
|
|
||||||
|
HandleError MenuManager::ReadStyleHandle(Handle_t handle, IMenuStyle **style)
|
||||||
|
{
|
||||||
|
HandleSecurity sec;
|
||||||
|
|
||||||
|
sec.pIdentity = g_pCoreIdent;
|
||||||
|
sec.pOwner = g_pCoreIdent;
|
||||||
|
|
||||||
|
return g_HandleSys.ReadHandle(handle, m_StyleType, &sec, (void **)style);
|
||||||
|
}
|
||||||
|
|
||||||
bool MenuManager::SetDefaultStyle(IMenuStyle *style)
|
bool MenuManager::SetDefaultStyle(IMenuStyle *style)
|
||||||
{
|
{
|
||||||
if (!style)
|
if (!style)
|
||||||
@ -503,6 +569,13 @@ skip_search:
|
|||||||
ItemDrawInfo padItem(NULL, ITEMDRAW_SPACER);
|
ItemDrawInfo padItem(NULL, ITEMDRAW_SPACER);
|
||||||
if (exitButton || (displayNext || displayPrev))
|
if (exitButton || (displayNext || displayPrev))
|
||||||
{
|
{
|
||||||
|
/* If there are no control options,
|
||||||
|
* Instead just pad with invisible slots.
|
||||||
|
*/
|
||||||
|
if (!displayPrev && !displayPrev)
|
||||||
|
{
|
||||||
|
padItem.style = ITEMDRAW_NOTEXT;
|
||||||
|
}
|
||||||
/* Add spacers so we can pad to the end */
|
/* Add spacers so we can pad to the end */
|
||||||
for (unsigned int i=0; i<padding; i++)
|
for (unsigned int i=0; i<padding; i++)
|
||||||
{
|
{
|
||||||
@ -585,6 +658,7 @@ skip_search:
|
|||||||
return display;
|
return display;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
unsigned int MenuManager::BroadcastMenu(IBaseMenu *menu,
|
unsigned int MenuManager::BroadcastMenu(IBaseMenu *menu,
|
||||||
IMenuHandler *handler,
|
IMenuHandler *handler,
|
||||||
int clients[],
|
int clients[],
|
||||||
@ -683,6 +757,7 @@ unsigned int MenuManager::VoteMenu(IBaseMenu *menu,
|
|||||||
|
|
||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void MenuManager::FreeBroadcastHandler(BroadcastHandler *bh)
|
void MenuManager::FreeBroadcastHandler(BroadcastHandler *bh)
|
||||||
{
|
{
|
||||||
|
@ -59,10 +59,13 @@ private:
|
|||||||
|
|
||||||
class MenuManager :
|
class MenuManager :
|
||||||
public IMenuManager,
|
public IMenuManager,
|
||||||
public SMGlobalClass
|
public SMGlobalClass,
|
||||||
|
public IHandleTypeDispatch
|
||||||
{
|
{
|
||||||
friend class BroadcastHandler;
|
friend class BroadcastHandler;
|
||||||
friend class VoteHandler;
|
friend class VoteHandler;
|
||||||
|
friend class CBaseMenu;
|
||||||
|
friend class BaseMenuStyle;
|
||||||
public:
|
public:
|
||||||
MenuManager();
|
MenuManager();
|
||||||
public: //SMGlobalClass
|
public: //SMGlobalClass
|
||||||
@ -95,15 +98,24 @@ public:
|
|||||||
void AddStyle(IMenuStyle *style);
|
void AddStyle(IMenuStyle *style);
|
||||||
bool SetDefaultStyle(IMenuStyle *style);
|
bool SetDefaultStyle(IMenuStyle *style);
|
||||||
IMenuPanel *RenderMenu(int client, menu_states_t &states, ItemOrder order);
|
IMenuPanel *RenderMenu(int client, menu_states_t &states, ItemOrder order);
|
||||||
|
public: //IHandleTypeDispatch
|
||||||
|
void OnHandleDestroy(HandleType_t type, void *object);
|
||||||
|
public:
|
||||||
|
HandleError ReadMenuHandle(Handle_t handle, IBaseMenu **menu);
|
||||||
|
HandleError ReadStyleHandle(Handle_t handle, IMenuStyle **style);
|
||||||
protected:
|
protected:
|
||||||
void FreeBroadcastHandler(BroadcastHandler *bh);
|
void FreeBroadcastHandler(BroadcastHandler *bh);
|
||||||
void FreeVoteHandler(VoteHandler *vh);
|
void FreeVoteHandler(VoteHandler *vh);
|
||||||
|
Handle_t CreateMenuHandle(IBaseMenu *menu, IdentityToken_t *pOwner);
|
||||||
|
Handle_t CreateStyleHandle(IMenuStyle *style);
|
||||||
private:
|
private:
|
||||||
int m_ShowMenu;
|
int m_ShowMenu;
|
||||||
IMenuStyle *m_pDefaultStyle;
|
IMenuStyle *m_pDefaultStyle;
|
||||||
CStack<BroadcastHandler *> m_BroadcastHandlers;
|
CStack<BroadcastHandler *> m_BroadcastHandlers;
|
||||||
CStack<VoteHandler *> m_VoteHandlers;
|
CStack<VoteHandler *> m_VoteHandlers;
|
||||||
CVector<IMenuStyle *> m_Styles;
|
CVector<IMenuStyle *> m_Styles;
|
||||||
|
HandleType_t m_StyleType;
|
||||||
|
HandleType_t m_MenuType;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern MenuManager g_Menus;
|
extern MenuManager g_Menus;
|
||||||
|
@ -17,11 +17,23 @@
|
|||||||
#include "MenuStyle_Base.h"
|
#include "MenuStyle_Base.h"
|
||||||
#include "PlayerManager.h"
|
#include "PlayerManager.h"
|
||||||
#include "MenuManager.h"
|
#include "MenuManager.h"
|
||||||
|
#include "HandleSys.h"
|
||||||
|
|
||||||
BaseMenuStyle::BaseMenuStyle() : m_WatchList(256)
|
BaseMenuStyle::BaseMenuStyle() : m_WatchList(256), m_hHandle(BAD_HANDLE)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Handle_t BaseMenuStyle::GetHandle()
|
||||||
|
{
|
||||||
|
/* Don't create the handle until we need it */
|
||||||
|
if (m_hHandle == BAD_HANDLE)
|
||||||
|
{
|
||||||
|
m_hHandle = g_Menus.CreateStyleHandle(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_hHandle;
|
||||||
|
}
|
||||||
|
|
||||||
void BaseMenuStyle::AddClientToWatch(int client)
|
void BaseMenuStyle::AddClientToWatch(int client)
|
||||||
{
|
{
|
||||||
m_WatchList.push_back(client);
|
m_WatchList.push_back(client);
|
||||||
@ -56,7 +68,12 @@ void BaseMenuStyle::_CancelClientMenu(int client, bool bAutoIgnore/* =false */,
|
|||||||
|
|
||||||
/* Fire callbacks */
|
/* Fire callbacks */
|
||||||
mh->OnMenuCancel(menu, client, reason);
|
mh->OnMenuCancel(menu, client, reason);
|
||||||
mh->OnMenuEnd(menu);
|
|
||||||
|
/* Only fire end if there's a valid menu */
|
||||||
|
if (menu)
|
||||||
|
{
|
||||||
|
mh->OnMenuEnd(menu);
|
||||||
|
}
|
||||||
|
|
||||||
if (bAutoIgnore)
|
if (bAutoIgnore)
|
||||||
{
|
{
|
||||||
@ -145,6 +162,7 @@ void BaseMenuStyle::OnClientDisconnected(int client)
|
|||||||
_CancelClientMenu(client, true, MenuCancel_Disconnect);
|
_CancelClientMenu(client, true, MenuCancel_Disconnect);
|
||||||
|
|
||||||
player->bInMenu = false;
|
player->bInMenu = false;
|
||||||
|
player->bInExternMenu = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_lookup[256];
|
static int do_lookup[256];
|
||||||
@ -248,7 +266,11 @@ void BaseMenuStyle::ClientPressedKey(int client, unsigned int key_press)
|
|||||||
mh->OnMenuSelect(menu, client, item);
|
mh->OnMenuSelect(menu, client, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
mh->OnMenuEnd(menu);
|
/* Only fire end for valid menus */
|
||||||
|
if (menu)
|
||||||
|
{
|
||||||
|
mh->OnMenuEnd(menu);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BaseMenuStyle::DoClientMenu(int client, IMenuPanel *menu, IMenuHandler *mh, unsigned int time)
|
bool BaseMenuStyle::DoClientMenu(int client, IMenuPanel *menu, IMenuHandler *mh, unsigned int time)
|
||||||
@ -276,13 +298,7 @@ bool BaseMenuStyle::DoClientMenu(int client, IMenuPanel *menu, IMenuHandler *mh,
|
|||||||
menu_states_t &states = player->states;
|
menu_states_t &states = player->states;
|
||||||
if (player->bInMenu)
|
if (player->bInMenu)
|
||||||
{
|
{
|
||||||
/* We need to cancel the old menu */
|
_CancelClientMenu(client, true);
|
||||||
if (player->menuHoldTime)
|
|
||||||
{
|
|
||||||
RemoveClientFromWatch(client);
|
|
||||||
}
|
|
||||||
states.mh->OnMenuCancel(states.menu, client, MenuCancel_Interrupt);
|
|
||||||
states.mh->OnMenuEnd(states.menu);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
states.firstItem = 0;
|
states.firstItem = 0;
|
||||||
@ -291,6 +307,7 @@ bool BaseMenuStyle::DoClientMenu(int client, IMenuPanel *menu, IMenuHandler *mh,
|
|||||||
states.mh = mh;
|
states.mh = mh;
|
||||||
states.apiVers = SMINTERFACE_MENUMANAGER_VERSION;
|
states.apiVers = SMINTERFACE_MENUMANAGER_VERSION;
|
||||||
player->bInMenu = true;
|
player->bInMenu = true;
|
||||||
|
player->bInExternMenu = false;
|
||||||
player->menuStartTime = gpGlobals->curtime;
|
player->menuStartTime = gpGlobals->curtime;
|
||||||
player->menuHoldTime = time;
|
player->menuHoldTime = time;
|
||||||
|
|
||||||
@ -367,6 +384,7 @@ bool BaseMenuStyle::DoClientMenu(int client, CBaseMenu *menu, IMenuHandler *mh,
|
|||||||
|
|
||||||
/* Finally, set our states */
|
/* Finally, set our states */
|
||||||
player->bInMenu = true;
|
player->bInMenu = true;
|
||||||
|
player->bInExternMenu = false;
|
||||||
player->menuStartTime = gpGlobals->curtime;
|
player->menuStartTime = gpGlobals->curtime;
|
||||||
player->menuHoldTime = time;
|
player->menuHoldTime = time;
|
||||||
|
|
||||||
@ -413,8 +431,10 @@ bool BaseMenuStyle::RedoClientMenu(int client, ItemOrder order)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
CBaseMenu::CBaseMenu(IMenuStyle *pStyle) :
|
CBaseMenu::CBaseMenu(IMenuHandler *pHandler, IMenuStyle *pStyle, IdentityToken_t *pOwner) :
|
||||||
m_pStyle(pStyle), m_Strings(512), m_Pagination(7), m_ExitButton(true), m_bShouldDelete(false), m_bCancelling(false)
|
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)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -422,6 +442,16 @@ CBaseMenu::~CBaseMenu()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Handle_t CBaseMenu::GetHandle()
|
||||||
|
{
|
||||||
|
if (!m_hHandle)
|
||||||
|
{
|
||||||
|
m_hHandle = g_Menus.CreateMenuHandle(this, m_pOwner);
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_hHandle;
|
||||||
|
}
|
||||||
|
|
||||||
bool CBaseMenu::AppendItem(const char *info, const ItemDrawInfo &draw)
|
bool CBaseMenu::AppendItem(const char *info, const ItemDrawInfo &draw)
|
||||||
{
|
{
|
||||||
if (m_Pagination == (unsigned)MENU_NO_PAGINATION
|
if (m_Pagination == (unsigned)MENU_NO_PAGINATION
|
||||||
@ -572,18 +602,48 @@ void CBaseMenu::Cancel()
|
|||||||
|
|
||||||
if (m_bShouldDelete)
|
if (m_bShouldDelete)
|
||||||
{
|
{
|
||||||
delete this;
|
InternalDelete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBaseMenu::Destroy()
|
void CBaseMenu::Destroy(bool releaseHandle)
|
||||||
{
|
{
|
||||||
|
/* Check if we shouldn't be here */
|
||||||
|
if (m_bDeleting)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Save the destruction hint about our handle */
|
||||||
|
m_bWillFreeHandle = releaseHandle;
|
||||||
|
|
||||||
|
/* Now actually do stuff */
|
||||||
if (!m_bCancelling || m_bShouldDelete)
|
if (!m_bCancelling || m_bShouldDelete)
|
||||||
{
|
{
|
||||||
Cancel();
|
Cancel();
|
||||||
delete this;
|
InternalDelete();
|
||||||
} else {
|
} else {
|
||||||
m_bShouldDelete = true;
|
m_bShouldDelete = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CBaseMenu::InternalDelete()
|
||||||
|
{
|
||||||
|
if (m_bWillFreeHandle && m_hHandle != BAD_HANDLE)
|
||||||
|
{
|
||||||
|
Handle_t hndl = m_hHandle;
|
||||||
|
HandleSecurity sec;
|
||||||
|
|
||||||
|
sec.pOwner = m_pOwner;
|
||||||
|
sec.pIdentity = g_pCoreIdent;
|
||||||
|
|
||||||
|
m_hHandle = BAD_HANDLE;
|
||||||
|
m_bDeleting = true;
|
||||||
|
g_HandleSys.FreeHandle(hndl, &sec);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_pHandler->OnMenuDestroy(this);
|
||||||
|
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -65,6 +65,7 @@ public:
|
|||||||
public: //IMenuStyle
|
public: //IMenuStyle
|
||||||
bool CancelClientMenu(int client, bool autoIgnore/* =false */);
|
bool CancelClientMenu(int client, bool autoIgnore/* =false */);
|
||||||
MenuSource GetClientMenu(int client, void **object);
|
MenuSource GetClientMenu(int client, void **object);
|
||||||
|
Handle_t GetHandle();
|
||||||
public: //IClientListener
|
public: //IClientListener
|
||||||
void OnClientDisconnected(int client);
|
void OnClientDisconnected(int client);
|
||||||
public: //what derived must implement
|
public: //what derived must implement
|
||||||
@ -84,12 +85,13 @@ protected:
|
|||||||
bool RedoClientMenu(int client, ItemOrder order);
|
bool RedoClientMenu(int client, ItemOrder order);
|
||||||
protected:
|
protected:
|
||||||
FastLink<int> m_WatchList;
|
FastLink<int> m_WatchList;
|
||||||
|
Handle_t m_hHandle;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CBaseMenu : public IBaseMenu
|
class CBaseMenu : public IBaseMenu
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CBaseMenu(IMenuStyle *pStyle);
|
CBaseMenu(IMenuHandler *pHandler, IMenuStyle *pStyle, IdentityToken_t *pOwner);
|
||||||
virtual ~CBaseMenu();
|
virtual ~CBaseMenu();
|
||||||
public:
|
public:
|
||||||
virtual bool AppendItem(const char *info, const ItemDrawInfo &draw);
|
virtual bool AppendItem(const char *info, const ItemDrawInfo &draw);
|
||||||
@ -106,8 +108,11 @@ public:
|
|||||||
virtual bool GetExitButton();
|
virtual bool GetExitButton();
|
||||||
virtual bool SetExitButton(bool set);
|
virtual bool SetExitButton(bool set);
|
||||||
virtual void Cancel();
|
virtual void Cancel();
|
||||||
virtual void Destroy();
|
virtual void Destroy(bool releaseHandle);
|
||||||
virtual void Cancel_Finally() =0;
|
virtual void Cancel_Finally() =0;
|
||||||
|
virtual Handle_t GetHandle();
|
||||||
|
private:
|
||||||
|
void InternalDelete();
|
||||||
protected:
|
protected:
|
||||||
String m_Title;
|
String m_Title;
|
||||||
IMenuStyle *m_pStyle;
|
IMenuStyle *m_pStyle;
|
||||||
@ -117,6 +122,11 @@ protected:
|
|||||||
bool m_ExitButton;
|
bool m_ExitButton;
|
||||||
bool m_bShouldDelete;
|
bool m_bShouldDelete;
|
||||||
bool m_bCancelling;
|
bool m_bCancelling;
|
||||||
|
bool m_bDeleting;
|
||||||
|
bool m_bWillFreeHandle;
|
||||||
|
IdentityToken_t *m_pOwner;
|
||||||
|
Handle_t m_hHandle;
|
||||||
|
IMenuHandler *m_pHandler;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //_INCLUDE_MENUSTYLE_BASE_H
|
#endif //_INCLUDE_MENUSTYLE_BASE_H
|
||||||
|
@ -56,6 +56,12 @@ void CRadioStyle::OnSourceModLevelChange(const char *mapName)
|
|||||||
void CRadioStyle::OnSourceModShutdown()
|
void CRadioStyle::OnSourceModShutdown()
|
||||||
{
|
{
|
||||||
g_UserMsgs.UnhookUserMessage(g_ShowMenuId, this, false);
|
g_UserMsgs.UnhookUserMessage(g_ShowMenuId, this, false);
|
||||||
|
|
||||||
|
while (!m_FreeDisplays.empty())
|
||||||
|
{
|
||||||
|
delete m_FreeDisplays.front();
|
||||||
|
m_FreeDisplays.pop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CRadioStyle::IsSupported()
|
bool CRadioStyle::IsSupported()
|
||||||
@ -125,12 +131,12 @@ void CRadioStyle::SendDisplay(int client, IMenuPanel *display)
|
|||||||
|
|
||||||
IMenuPanel *CRadioStyle::CreatePanel()
|
IMenuPanel *CRadioStyle::CreatePanel()
|
||||||
{
|
{
|
||||||
return new CRadioDisplay();
|
return g_RadioMenuStyle.MakeRadioDisplay();
|
||||||
}
|
}
|
||||||
|
|
||||||
IBaseMenu *CRadioStyle::CreateMenu()
|
IBaseMenu *CRadioStyle::CreateMenu(IMenuHandler *pHandler, IdentityToken_t *pOwner)
|
||||||
{
|
{
|
||||||
return new CRadioMenu();
|
return new CRadioMenu(pHandler, pOwner);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int CRadioStyle::GetMaxPageItems()
|
unsigned int CRadioStyle::GetMaxPageItems()
|
||||||
@ -148,6 +154,25 @@ CBaseMenuPlayer *CRadioStyle::GetMenuPlayer(int client)
|
|||||||
return &m_players[client];
|
return &m_players[client];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CRadioDisplay *CRadioStyle::MakeRadioDisplay(CRadioMenu *menu)
|
||||||
|
{
|
||||||
|
CRadioDisplay *display;
|
||||||
|
if (m_FreeDisplays.empty())
|
||||||
|
{
|
||||||
|
display = new CRadioDisplay();
|
||||||
|
} else {
|
||||||
|
display = m_FreeDisplays.front();
|
||||||
|
m_FreeDisplays.pop();
|
||||||
|
display->Reset();
|
||||||
|
}
|
||||||
|
return display;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CRadioStyle::FreeRadioDisplay(CRadioDisplay *display)
|
||||||
|
{
|
||||||
|
m_FreeDisplays.push(display);
|
||||||
|
}
|
||||||
|
|
||||||
CRadioDisplay::CRadioDisplay()
|
CRadioDisplay::CRadioDisplay()
|
||||||
{
|
{
|
||||||
Reset();
|
Reset();
|
||||||
@ -292,7 +317,8 @@ void CRadioDisplay::DeleteThis()
|
|||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
|
|
||||||
CRadioMenu::CRadioMenu() : CBaseMenu(&g_RadioMenuStyle)
|
CRadioMenu::CRadioMenu(IMenuHandler *pHandler, IdentityToken_t *pOwner) :
|
||||||
|
CBaseMenu(pHandler, &g_RadioMenuStyle, pOwner)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -303,12 +329,12 @@ bool CRadioMenu::SetExtOption(MenuOption option, const void *valuePtr)
|
|||||||
|
|
||||||
IMenuPanel *CRadioMenu::CreatePanel()
|
IMenuPanel *CRadioMenu::CreatePanel()
|
||||||
{
|
{
|
||||||
return new CRadioDisplay(this);
|
return g_RadioMenuStyle.MakeRadioDisplay(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CRadioMenu::Display(int client, IMenuHandler *handler, unsigned int time)
|
bool CRadioMenu::Display(int client, unsigned int time)
|
||||||
{
|
{
|
||||||
return g_RadioMenuStyle.DoClientMenu(client, this, handler, time);
|
return g_RadioMenuStyle.DoClientMenu(client, this, m_pHandler, time);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CRadioMenu::Cancel_Finally()
|
void CRadioMenu::Cancel_Finally()
|
||||||
|
@ -22,9 +22,13 @@
|
|||||||
#include <IPlayerHelpers.h>
|
#include <IPlayerHelpers.h>
|
||||||
#include <IUserMessages.h>
|
#include <IUserMessages.h>
|
||||||
#include "sm_fastlink.h"
|
#include "sm_fastlink.h"
|
||||||
|
#include <sh_stack.h>
|
||||||
|
|
||||||
using namespace SourceMod;
|
using namespace SourceMod;
|
||||||
|
|
||||||
|
class CRadioDisplay;
|
||||||
|
class CRadioMenu;
|
||||||
|
|
||||||
class CRadioStyle :
|
class CRadioStyle :
|
||||||
public BaseMenuStyle,
|
public BaseMenuStyle,
|
||||||
public SMGlobalClass,
|
public SMGlobalClass,
|
||||||
@ -41,7 +45,7 @@ public: //BaseMenuStyle
|
|||||||
public: //IMenuStyle
|
public: //IMenuStyle
|
||||||
const char *GetStyleName();
|
const char *GetStyleName();
|
||||||
IMenuPanel *CreatePanel();
|
IMenuPanel *CreatePanel();
|
||||||
IBaseMenu *CreateMenu();
|
IBaseMenu *CreateMenu(IMenuHandler *pHandler, IdentityToken_t *pOwner);
|
||||||
unsigned int GetMaxPageItems();
|
unsigned int GetMaxPageItems();
|
||||||
public: //IUserMessageListener
|
public: //IUserMessageListener
|
||||||
void OnUserMessage(int msg_id, bf_write *bf, IRecipientFilter *pFilter);
|
void OnUserMessage(int msg_id, bf_write *bf, IRecipientFilter *pFilter);
|
||||||
@ -49,14 +53,17 @@ public: //IUserMessageListener
|
|||||||
public:
|
public:
|
||||||
bool IsSupported();
|
bool IsSupported();
|
||||||
bool OnClientCommand(int client);
|
bool OnClientCommand(int client);
|
||||||
|
public:
|
||||||
|
CRadioDisplay *MakeRadioDisplay(CRadioMenu *menu=NULL);
|
||||||
|
void FreeRadioDisplay(CRadioDisplay *display);
|
||||||
private:
|
private:
|
||||||
CBaseMenuPlayer *m_players;
|
CBaseMenuPlayer *m_players;
|
||||||
|
CStack<CRadioDisplay *> m_FreeDisplays;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CRadioMenu;
|
|
||||||
|
|
||||||
class CRadioDisplay : public IMenuPanel
|
class CRadioDisplay : public IMenuPanel
|
||||||
{
|
{
|
||||||
|
friend class CRadioStyle;
|
||||||
public:
|
public:
|
||||||
CRadioDisplay();
|
CRadioDisplay();
|
||||||
CRadioDisplay(CRadioMenu *menu);
|
CRadioDisplay(CRadioMenu *menu);
|
||||||
@ -81,11 +88,11 @@ private:
|
|||||||
class CRadioMenu : public CBaseMenu
|
class CRadioMenu : public CBaseMenu
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CRadioMenu();
|
CRadioMenu(IMenuHandler *pHandler, IdentityToken_t *pOwner);
|
||||||
public:
|
public:
|
||||||
bool SetExtOption(MenuOption option, const void *valuePtr);
|
bool SetExtOption(MenuOption option, const void *valuePtr);
|
||||||
IMenuPanel *CreatePanel();
|
IMenuPanel *CreatePanel();
|
||||||
bool Display(int client, IMenuHandler *handler, unsigned int time);
|
bool Display(int client, unsigned int time);
|
||||||
void Cancel_Finally();
|
void Cancel_Finally();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -109,9 +109,9 @@ IMenuPanel *ValveMenuStyle::CreatePanel()
|
|||||||
return new CValveMenuDisplay();
|
return new CValveMenuDisplay();
|
||||||
}
|
}
|
||||||
|
|
||||||
IBaseMenu *ValveMenuStyle::CreateMenu()
|
IBaseMenu *ValveMenuStyle::CreateMenu(IMenuHandler *pHandler, IdentityToken_t *pOwner)
|
||||||
{
|
{
|
||||||
return new CValveMenu();
|
return new CValveMenu(pHandler, pOwner);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *ValveMenuStyle::GetStyleName()
|
const char *ValveMenuStyle::GetStyleName()
|
||||||
@ -305,7 +305,8 @@ bool CValveMenuDisplay::SendDisplay(int client, IMenuHandler *handler, unsigned
|
|||||||
return g_ValveMenuStyle.DoClientMenu(client, this, handler, time);
|
return g_ValveMenuStyle.DoClientMenu(client, this, handler, time);
|
||||||
}
|
}
|
||||||
|
|
||||||
CValveMenu::CValveMenu() : CBaseMenu(&g_ValveMenuStyle),
|
CValveMenu::CValveMenu(IMenuHandler *pHandler, IdentityToken_t *pOwner) :
|
||||||
|
CBaseMenu(pHandler, &g_ValveMenuStyle, pOwner),
|
||||||
m_IntroColor(255, 0, 0, 255)
|
m_IntroColor(255, 0, 0, 255)
|
||||||
{
|
{
|
||||||
strcpy(m_IntroMsg, "You have a menu, press ESC");
|
strcpy(m_IntroMsg, "You have a menu, press ESC");
|
||||||
@ -344,14 +345,14 @@ bool CValveMenu::SetExtOption(MenuOption option, const void *valuePtr)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CValveMenu::Display(int client, IMenuHandler *handler, unsigned int time)
|
bool CValveMenu::Display(int client, unsigned int time)
|
||||||
{
|
{
|
||||||
if (m_bCancelling)
|
if (m_bCancelling)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return g_ValveMenuStyle.DoClientMenu(client, this, handler, time);
|
return g_ValveMenuStyle.DoClientMenu(client, this, m_pHandler, time);
|
||||||
}
|
}
|
||||||
|
|
||||||
IMenuPanel *CValveMenu::CreatePanel()
|
IMenuPanel *CValveMenu::CreatePanel()
|
||||||
|
@ -55,7 +55,7 @@ public: //SMGlobalClass
|
|||||||
public: //IMenuStyle
|
public: //IMenuStyle
|
||||||
const char *GetStyleName();
|
const char *GetStyleName();
|
||||||
IMenuPanel *CreatePanel();
|
IMenuPanel *CreatePanel();
|
||||||
IBaseMenu *CreateMenu();
|
IBaseMenu *CreateMenu(IMenuHandler *pHandler, IdentityToken_t *pOwner);
|
||||||
unsigned int GetMaxPageItems();
|
unsigned int GetMaxPageItems();
|
||||||
private:
|
private:
|
||||||
void HookCreateMessage(edict_t *pEdict, DIALOG_TYPE type, KeyValues *kv, IServerPluginCallbacks *plugin);
|
void HookCreateMessage(edict_t *pEdict, DIALOG_TYPE type, KeyValues *kv, IServerPluginCallbacks *plugin);
|
||||||
@ -92,14 +92,14 @@ class CValveMenu : public CBaseMenu
|
|||||||
{
|
{
|
||||||
friend class CValveMenuDisplay;
|
friend class CValveMenuDisplay;
|
||||||
public:
|
public:
|
||||||
CValveMenu();
|
CValveMenu(IMenuHandler *pHandler, IdentityToken_t *pOwner);
|
||||||
public: //IBaseMenu
|
public: //IBaseMenu
|
||||||
bool SetExtOption(MenuOption option, const void *valuePtr);
|
bool SetExtOption(MenuOption option, const void *valuePtr);
|
||||||
IMenuPanel *CreatePanel();
|
IMenuPanel *CreatePanel();
|
||||||
bool GetExitButton();
|
bool GetExitButton();
|
||||||
bool SetExitButton(bool set);
|
bool SetExitButton(bool set);
|
||||||
bool SetPagination(unsigned int itemsPerPage);
|
bool SetPagination(unsigned int itemsPerPage);
|
||||||
bool Display(int client, IMenuHandler *handler, unsigned int time);
|
bool Display(int client, unsigned int time);
|
||||||
public: //CBaseMenu
|
public: //CBaseMenu
|
||||||
void Cancel_Finally();
|
void Cancel_Finally();
|
||||||
private:
|
private:
|
||||||
|
@ -842,6 +842,10 @@
|
|||||||
RelativePath="..\smn_lang.cpp"
|
RelativePath="..\smn_lang.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\smn_menus.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\smn_player.cpp"
|
RelativePath="..\smn_player.cpp"
|
||||||
>
|
>
|
||||||
|
890
core/smn_menus.cpp
Normal file
890
core/smn_menus.cpp
Normal file
@ -0,0 +1,890 @@
|
|||||||
|
/**
|
||||||
|
* vim: set ts=4 :
|
||||||
|
* ===============================================================
|
||||||
|
* SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved.
|
||||||
|
* ===============================================================
|
||||||
|
*
|
||||||
|
* This file is not open source and may not be copied without explicit
|
||||||
|
* written permission of AlliedModders LLC. This file may not be redistributed
|
||||||
|
* in whole or significant part.
|
||||||
|
* For information, see LICENSE.txt or http://www.sourcemod.net/license.php
|
||||||
|
*
|
||||||
|
* Version: $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "sm_globals.h"
|
||||||
|
#include <sh_stack.h>
|
||||||
|
#include "MenuManager.h"
|
||||||
|
#include "MenuStyle_Valve.h"
|
||||||
|
#include "MenuStyle_Radio.h"
|
||||||
|
#include "HandleSys.h"
|
||||||
|
#include "PluginSys.h"
|
||||||
|
|
||||||
|
#if defined CreateMenu
|
||||||
|
#undef CreateMenu
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* And God said, "let there be menus," and behold, there were menus.
|
||||||
|
* God saw the menus and they were good. And the evening and the morning
|
||||||
|
* were the third day.
|
||||||
|
*/
|
||||||
|
|
||||||
|
enum MenuAction
|
||||||
|
{
|
||||||
|
MenuAction_Start = (1<<0), /**< A menu has been started (nothing passed) */
|
||||||
|
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=item) */
|
||||||
|
MenuAction_End = (1<<4), /**< A menu's display/selection cycle is complete (nothing passed). */
|
||||||
|
MenuAction_VoteEnd = (1<<5), /**< (VOTE ONLY): A vote sequence has ended (param1=chosen item) */
|
||||||
|
};
|
||||||
|
|
||||||
|
class CPanelHandler : public IMenuHandler
|
||||||
|
{
|
||||||
|
friend class MenuNativeHelpers;
|
||||||
|
public:
|
||||||
|
CPanelHandler()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
void OnMenuCancel(IBaseMenu *menu, int client, MenuCancelReason reason);
|
||||||
|
void OnMenuSelect(IBaseMenu *menu, int client, unsigned int item);
|
||||||
|
private:
|
||||||
|
IPluginFunction *m_pFunc;
|
||||||
|
IPlugin *m_pPlugin;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CMenuHandler : public IMenuHandler
|
||||||
|
{
|
||||||
|
friend class MenuNativeHelpers;
|
||||||
|
public:
|
||||||
|
CMenuHandler(IPluginFunction *pBasic, int flags);
|
||||||
|
public:
|
||||||
|
void OnMenuStart(IBaseMenu *menu);
|
||||||
|
void OnMenuDisplay(IBaseMenu *menu, int client, IMenuPanel *display);
|
||||||
|
void OnMenuSelect(IBaseMenu *menu, int client, unsigned int item);
|
||||||
|
void OnMenuCancel(IBaseMenu *menu, int client, MenuCancelReason reason);
|
||||||
|
void OnMenuEnd(IBaseMenu *menu);
|
||||||
|
void OnMenuDestroy(IBaseMenu *menu);
|
||||||
|
#if 0
|
||||||
|
void OnMenuDrawItem(IBaseMenu *menu, int client, unsigned int item, unsigned int &style);
|
||||||
|
void OnMenuDisplayItem(IBaseMenu *menu, int client, unsigned int item, const char **display);
|
||||||
|
#endif
|
||||||
|
private:
|
||||||
|
IPluginFunction *m_pBasic;
|
||||||
|
int m_Flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GLOBAL CLASS FOR HELPERS
|
||||||
|
*/
|
||||||
|
|
||||||
|
class MenuNativeHelpers :
|
||||||
|
public SMGlobalClass,
|
||||||
|
public IHandleTypeDispatch,
|
||||||
|
public IPluginsListener
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void OnSourceModAllInitialized()
|
||||||
|
{
|
||||||
|
m_PanelType = g_HandleSys.CreateType("IMenuPanel", this, 0, NULL, NULL, g_pCoreIdent, NULL);
|
||||||
|
g_PluginSys.AddPluginsListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void OnSourceModShutdown()
|
||||||
|
{
|
||||||
|
g_HandleSys.RemoveType(m_PanelType, g_pCoreIdent);
|
||||||
|
|
||||||
|
while (!m_FreePanelHandlers.empty())
|
||||||
|
{
|
||||||
|
delete m_FreePanelHandlers.front();
|
||||||
|
m_FreePanelHandlers.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!m_FreeMenuHandlers.empty())
|
||||||
|
{
|
||||||
|
delete m_FreeMenuHandlers.front();
|
||||||
|
m_FreeMenuHandlers.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void OnHandleDestroy(HandleType_t type, void *object)
|
||||||
|
{
|
||||||
|
IMenuPanel *panel = (IMenuPanel *)object;
|
||||||
|
panel->DeleteThis();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* It is extremely important that unloaded plugins don't crash.
|
||||||
|
* Thus, if a plugin unloads, we run through every handler we have.
|
||||||
|
* This means we do almost no runtime work for keeping track of
|
||||||
|
* our panel handlers (we don't have to store a list of the running
|
||||||
|
* ones), but when push comes to shove, we have to scan them all
|
||||||
|
* in case any of them are active.
|
||||||
|
*/
|
||||||
|
virtual void OnPluginUnloaded(IPlugin *plugin)
|
||||||
|
{
|
||||||
|
IPluginContext *pContext = plugin->GetBaseContext();
|
||||||
|
for (size_t i = 0; i < m_PanelHandlers.size(); i++)
|
||||||
|
{
|
||||||
|
if (m_PanelHandlers[i]->m_pPlugin == plugin)
|
||||||
|
{
|
||||||
|
m_PanelHandlers[i]->m_pPlugin = NULL;
|
||||||
|
m_PanelHandlers[i]->m_pFunc = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline HandleType_t GetPanelType()
|
||||||
|
{
|
||||||
|
return m_PanelType;
|
||||||
|
}
|
||||||
|
|
||||||
|
CPanelHandler *GetPanelHandler(IPluginFunction *pFunction)
|
||||||
|
{
|
||||||
|
CPanelHandler *handler;
|
||||||
|
if (m_FreePanelHandlers.empty())
|
||||||
|
{
|
||||||
|
handler = new CPanelHandler;
|
||||||
|
m_PanelHandlers.push_back(handler);
|
||||||
|
} else {
|
||||||
|
handler = m_FreePanelHandlers.front();
|
||||||
|
m_FreePanelHandlers.pop();
|
||||||
|
}
|
||||||
|
handler->m_pFunc = pFunction;
|
||||||
|
handler->m_pPlugin = g_PluginSys.GetPluginByCtx(pFunction->GetParentContext()->GetContext());
|
||||||
|
return handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FreePanelHandler(CPanelHandler *handler)
|
||||||
|
{
|
||||||
|
handler->m_pFunc = NULL;
|
||||||
|
handler->m_pPlugin = NULL;
|
||||||
|
m_FreePanelHandlers.push(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
CMenuHandler *GetMenuHandler(IPluginFunction *pFunction, int flags)
|
||||||
|
{
|
||||||
|
CMenuHandler *handler;
|
||||||
|
if (m_FreeMenuHandlers.empty())
|
||||||
|
{
|
||||||
|
handler = new CMenuHandler(pFunction, flags);
|
||||||
|
} else {
|
||||||
|
handler = m_FreeMenuHandlers.front();
|
||||||
|
m_FreeMenuHandlers.pop();
|
||||||
|
handler->m_pBasic = pFunction;
|
||||||
|
handler->m_Flags = flags;
|
||||||
|
}
|
||||||
|
return handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FreeMenuHandler(CMenuHandler *handler)
|
||||||
|
{
|
||||||
|
m_FreeMenuHandlers.push(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
HandleType_t m_PanelType;
|
||||||
|
CStack<CPanelHandler *> m_FreePanelHandlers;
|
||||||
|
CStack<CMenuHandler *> m_FreeMenuHandlers;
|
||||||
|
CVector<CPanelHandler *> m_PanelHandlers;
|
||||||
|
} g_MenuHelpers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BASIC PANEL HANDLER WRAPPER
|
||||||
|
*/
|
||||||
|
|
||||||
|
void CPanelHandler::OnMenuCancel(IBaseMenu *menu, int client, MenuCancelReason reason)
|
||||||
|
{
|
||||||
|
if (m_pFunc)
|
||||||
|
{
|
||||||
|
m_pFunc->PushCell(BAD_HANDLE);
|
||||||
|
m_pFunc->PushCell(MenuAction_Cancel);
|
||||||
|
m_pFunc->PushCell(client);
|
||||||
|
m_pFunc->PushCell(reason);
|
||||||
|
m_pFunc->Execute(NULL);
|
||||||
|
}
|
||||||
|
g_MenuHelpers.FreePanelHandler(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPanelHandler::OnMenuSelect(IBaseMenu *menu, int client, unsigned int item)
|
||||||
|
{
|
||||||
|
if (m_pFunc)
|
||||||
|
{
|
||||||
|
m_pFunc->PushCell(BAD_HANDLE);
|
||||||
|
m_pFunc->PushCell(MenuAction_Select);
|
||||||
|
m_pFunc->PushCell(client);
|
||||||
|
m_pFunc->PushCell(item);
|
||||||
|
m_pFunc->Execute(NULL);
|
||||||
|
}
|
||||||
|
g_MenuHelpers.FreePanelHandler(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MENU HANDLER WRAPPER
|
||||||
|
*/
|
||||||
|
CMenuHandler::CMenuHandler(IPluginFunction *pBasic, int flags) :
|
||||||
|
m_pBasic(pBasic), m_Flags(flags)
|
||||||
|
{
|
||||||
|
/* :TODO: We can probably cache the handle ahead of time */
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMenuHandler::OnMenuStart(IBaseMenu *menu)
|
||||||
|
{
|
||||||
|
if ((m_Flags & (int)MenuAction_Start) == (int)MenuAction_Start)
|
||||||
|
{
|
||||||
|
m_pBasic->PushCell(menu->GetHandle());
|
||||||
|
m_pBasic->PushCell(MenuAction_Start);
|
||||||
|
m_pBasic->PushCell(0);
|
||||||
|
m_pBasic->PushCell(0);
|
||||||
|
m_pBasic->Execute(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMenuHandler::OnMenuDisplay(IBaseMenu *menu, int client, IMenuPanel *panel)
|
||||||
|
{
|
||||||
|
if ((m_Flags & (int)MenuAction_Display) == (int)MenuAction_Display)
|
||||||
|
{
|
||||||
|
HandleSecurity sec;
|
||||||
|
sec.pIdentity = m_pBasic->GetParentContext()->GetIdentity();
|
||||||
|
sec.pOwner = g_pCoreIdent;
|
||||||
|
|
||||||
|
HandleAccess access;
|
||||||
|
g_HandleSys.InitAccessDefaults(NULL, &access);
|
||||||
|
access.access[HandleAccess_Delete] = HANDLE_RESTRICT_IDENTITY|HANDLE_RESTRICT_OWNER;
|
||||||
|
|
||||||
|
Handle_t hndl = g_HandleSys.CreateHandleEx(g_MenuHelpers.GetPanelType(), panel, &sec, &access, NULL);
|
||||||
|
|
||||||
|
m_pBasic->PushCell(menu->GetHandle());
|
||||||
|
m_pBasic->PushCell(MenuAction_Display);
|
||||||
|
m_pBasic->PushCell(client);
|
||||||
|
m_pBasic->PushCell(hndl);
|
||||||
|
m_pBasic->Execute(NULL);
|
||||||
|
|
||||||
|
g_HandleSys.FreeHandle(hndl, &sec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMenuHandler::OnMenuSelect(IBaseMenu *menu, int client, unsigned int item)
|
||||||
|
{
|
||||||
|
m_pBasic->PushCell(menu->GetHandle());
|
||||||
|
m_pBasic->PushCell(MenuAction_Select);
|
||||||
|
m_pBasic->PushCell(client);
|
||||||
|
m_pBasic->PushCell(item);
|
||||||
|
m_pBasic->Execute(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMenuHandler::OnMenuCancel(IBaseMenu *menu, int client, MenuCancelReason reason)
|
||||||
|
{
|
||||||
|
m_pBasic->PushCell(menu->GetHandle());
|
||||||
|
m_pBasic->PushCell(MenuAction_Cancel);
|
||||||
|
m_pBasic->PushCell(client);
|
||||||
|
m_pBasic->PushCell(reason);
|
||||||
|
m_pBasic->Execute(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMenuHandler::OnMenuEnd(IBaseMenu *menu)
|
||||||
|
{
|
||||||
|
m_pBasic->PushCell(menu->GetHandle());
|
||||||
|
m_pBasic->PushCell(MenuAction_End);
|
||||||
|
m_pBasic->PushCell(0);
|
||||||
|
m_pBasic->PushCell(0);
|
||||||
|
m_pBasic->Execute(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMenuHandler::OnMenuDestroy(IBaseMenu *menu)
|
||||||
|
{
|
||||||
|
g_MenuHelpers.FreeMenuHandler(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* INLINE FUNCTIONS FOR NATIVES
|
||||||
|
*/
|
||||||
|
|
||||||
|
inline Handle_t MakePanelHandle(IMenuPanel *panel, IPluginContext *pContext)
|
||||||
|
{
|
||||||
|
return g_HandleSys.CreateHandle(g_MenuHelpers.GetPanelType(), panel, pContext->GetIdentity(), g_pCoreIdent, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline HandleError ReadPanelHandle(Handle_t hndl, IMenuPanel **panel)
|
||||||
|
{
|
||||||
|
HandleSecurity sec;
|
||||||
|
sec.pIdentity = g_pCoreIdent;
|
||||||
|
sec.pOwner = NULL;
|
||||||
|
return g_HandleSys.ReadHandle(hndl, g_MenuHelpers.GetPanelType(), &sec, (void **)panel);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline IMenuStyle *GetStyleFromCell(cell_t cell)
|
||||||
|
{
|
||||||
|
enum MenuStyle
|
||||||
|
{
|
||||||
|
MenuStyle_Default = 0, /**< The "default" menu style for the mod */
|
||||||
|
MenuStyle_Valve = 1, /**< The Valve provided menu style (Used on HL2DM) */
|
||||||
|
MenuStyle_Radio = 2, /**< The simpler menu style commonly used on CS:S */
|
||||||
|
};
|
||||||
|
|
||||||
|
if (cell == MenuStyle_Valve)
|
||||||
|
{
|
||||||
|
return &g_ValveMenuStyle;
|
||||||
|
} else if (cell == MenuStyle_Radio
|
||||||
|
&& g_RadioMenuStyle.IsSupported())
|
||||||
|
{
|
||||||
|
return &g_RadioMenuStyle;
|
||||||
|
}
|
||||||
|
|
||||||
|
return g_Menus.GetDefaultStyle();
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************
|
||||||
|
**** NATIVE DEFINITIONS ***********
|
||||||
|
***********************************/
|
||||||
|
|
||||||
|
static cell_t CreateMenu(IPluginContext *pContext, const cell_t *params)
|
||||||
|
{
|
||||||
|
IMenuStyle *style = g_Menus.GetDefaultStyle();
|
||||||
|
IPluginFunction *pFunction;
|
||||||
|
|
||||||
|
if ((pFunction=pContext->GetFunctionById(params[1])) == NULL)
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Function id %x is invalid", params[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
CMenuHandler *handler = g_MenuHelpers.GetMenuHandler(pFunction, params[2]);
|
||||||
|
IBaseMenu *menu = style->CreateMenu(handler, pContext->GetIdentity());
|
||||||
|
|
||||||
|
Handle_t hndl = menu->GetHandle();
|
||||||
|
if (!hndl)
|
||||||
|
{
|
||||||
|
menu->Destroy();
|
||||||
|
return BAD_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hndl;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t DisplayMenu(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->Display(params[2], params[3]) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t AddMenuItem(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);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *info;
|
||||||
|
ItemDrawInfo dr;
|
||||||
|
|
||||||
|
pContext->LocalToString(params[2], &info);
|
||||||
|
pContext->LocalToString(params[3], (char **)&dr.display);
|
||||||
|
dr.style = params[4];
|
||||||
|
|
||||||
|
return menu->AppendItem(info, dr) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t InsertMenuItem(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);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *info;
|
||||||
|
ItemDrawInfo dr;
|
||||||
|
|
||||||
|
pContext->LocalToString(params[3], &info);
|
||||||
|
pContext->LocalToString(params[4], (char **)&dr.display);
|
||||||
|
dr.style = params[5];
|
||||||
|
|
||||||
|
return menu->InsertItem(params[2], info, dr) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t RemoveMenuItem(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->RemoveItem(params[2]) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t RemoveAllMenuItems(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->RemoveAllItems();
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t GetMenuItem(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);
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemDrawInfo dr;
|
||||||
|
const char *info;
|
||||||
|
|
||||||
|
if ((info=menu->GetItemInfo(params[2], &dr)) == NULL)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pContext->StringToLocalUTF8(params[3], params[4], info, NULL);
|
||||||
|
pContext->StringToLocalUTF8(params[6], params[7], dr.display ? dr.display : "", NULL);
|
||||||
|
|
||||||
|
cell_t *addr;
|
||||||
|
pContext->LocalToPhysAddr(params[5], &addr);
|
||||||
|
*addr = dr.style;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t SetMenuPagination(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->SetPagination(params[2]) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t GetMenuPagination(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->GetPagination();
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t GetMenuItemCount(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->GetItemCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t SetMenuTitle(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);
|
||||||
|
}
|
||||||
|
|
||||||
|
char buffer[1024];
|
||||||
|
g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
|
||||||
|
|
||||||
|
menu->SetDefaultTitle(buffer);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t CreatePanelFromMenu(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);
|
||||||
|
}
|
||||||
|
|
||||||
|
IMenuPanel *panel = menu->CreatePanel();
|
||||||
|
hndl = MakePanelHandle(panel, pContext);
|
||||||
|
if (!hndl)
|
||||||
|
{
|
||||||
|
panel->DeleteThis();
|
||||||
|
}
|
||||||
|
|
||||||
|
return hndl;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t GetMenuExitButton(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->GetExitButton() ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t SetMenuExitButton(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->SetExitButton(params[2] ? true : false) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t CancelMenu(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->Cancel();
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t GetMenuStyle(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->GetDrawStyle()->GetHandle();
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t GetMenuStyleHandle(IPluginContext *pContext, const cell_t *params)
|
||||||
|
{
|
||||||
|
IMenuStyle *style = GetStyleFromCell(params[1]);
|
||||||
|
if (!style)
|
||||||
|
{
|
||||||
|
return BAD_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return style->GetHandle();
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t CreatePanel(IPluginContext *pContext, const cell_t *params)
|
||||||
|
{
|
||||||
|
Handle_t hndl = (Handle_t)params[1];
|
||||||
|
HandleError err;
|
||||||
|
IMenuStyle *style;
|
||||||
|
|
||||||
|
if (hndl != 0)
|
||||||
|
{
|
||||||
|
if ((err=g_Menus.ReadStyleHandle(params[1], &style)) != HandleError_None)
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("MenuStyle handle %x is invalid (error %d)", hndl, err);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
style = g_Menus.GetDefaultStyle();
|
||||||
|
}
|
||||||
|
|
||||||
|
IMenuPanel *panel = style->CreatePanel();
|
||||||
|
|
||||||
|
hndl = MakePanelHandle(panel, pContext);
|
||||||
|
if (!hndl)
|
||||||
|
{
|
||||||
|
panel->DeleteThis();
|
||||||
|
return BAD_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hndl;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t CreateMenuEx(IPluginContext *pContext, const cell_t *params)
|
||||||
|
{
|
||||||
|
Handle_t hndl = (Handle_t)params[1];
|
||||||
|
HandleError err;
|
||||||
|
IMenuStyle *style;
|
||||||
|
|
||||||
|
if (hndl != 0)
|
||||||
|
{
|
||||||
|
if ((err=g_Menus.ReadStyleHandle(params[1], &style)) != HandleError_None)
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("MenuStyle handle %x is invalid (error %d)", hndl, err);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
style = g_Menus.GetDefaultStyle();
|
||||||
|
}
|
||||||
|
|
||||||
|
IPluginFunction *pFunction;
|
||||||
|
if ((pFunction=pContext->GetFunctionById(params[2])) == NULL)
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Function id %x is invalid", params[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
CMenuHandler *handler = g_MenuHelpers.GetMenuHandler(pFunction, params[3]);
|
||||||
|
|
||||||
|
IBaseMenu *pMenu = style->CreateMenu(handler, pContext->GetIdentity());
|
||||||
|
hndl = pMenu->GetHandle();
|
||||||
|
if (!hndl)
|
||||||
|
{
|
||||||
|
pMenu->Destroy();
|
||||||
|
return BAD_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hndl;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t GetClientMenu(IPluginContext *pContext, const cell_t *params)
|
||||||
|
{
|
||||||
|
Handle_t hndl = (Handle_t)params[2];
|
||||||
|
HandleError err;
|
||||||
|
IMenuStyle *style;
|
||||||
|
|
||||||
|
if (hndl != 0)
|
||||||
|
{
|
||||||
|
if ((err=g_Menus.ReadStyleHandle(params[1], &style)) != HandleError_None)
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("MenuStyle handle %x is invalid (error %d)", hndl, err);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
style = g_Menus.GetDefaultStyle();
|
||||||
|
}
|
||||||
|
|
||||||
|
return style->GetClientMenu(params[1], NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t CancelClientMenu(IPluginContext *pContext, const cell_t *params)
|
||||||
|
{
|
||||||
|
Handle_t hndl = (Handle_t)params[3];
|
||||||
|
HandleError err;
|
||||||
|
IMenuStyle *style;
|
||||||
|
|
||||||
|
if (hndl != 0)
|
||||||
|
{
|
||||||
|
if ((err=g_Menus.ReadStyleHandle(params[1], &style)) != HandleError_None)
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("MenuStyle handle %x is invalid (error %d)", hndl, err);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
style = g_Menus.GetDefaultStyle();
|
||||||
|
}
|
||||||
|
|
||||||
|
return style->CancelClientMenu(params[1], params[2] ? true : false) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t GetMaxPageItems(IPluginContext *pContext, const cell_t *params)
|
||||||
|
{
|
||||||
|
Handle_t hndl = (Handle_t)params[1];
|
||||||
|
HandleError err;
|
||||||
|
IMenuStyle *style;
|
||||||
|
|
||||||
|
if (hndl != 0)
|
||||||
|
{
|
||||||
|
if ((err=g_Menus.ReadStyleHandle(params[1], &style)) != HandleError_None)
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("MenuStyle handle %x is invalid (error %d)", hndl, err);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
style = g_Menus.GetDefaultStyle();
|
||||||
|
}
|
||||||
|
|
||||||
|
return style->GetMaxPageItems();
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t GetPanelStyle(IPluginContext *pContext, const cell_t *params)
|
||||||
|
{
|
||||||
|
Handle_t hndl = (Handle_t)params[1];
|
||||||
|
HandleError err;
|
||||||
|
IMenuPanel *panel;
|
||||||
|
|
||||||
|
if ((err=ReadPanelHandle(hndl, &panel)) != HandleError_None)
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
|
||||||
|
}
|
||||||
|
|
||||||
|
return panel->GetParentStyle()->GetHandle();
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t SetPanelTitle(IPluginContext *pContext, const cell_t *params)
|
||||||
|
{
|
||||||
|
Handle_t hndl = (Handle_t)params[1];
|
||||||
|
HandleError err;
|
||||||
|
IMenuPanel *panel;
|
||||||
|
|
||||||
|
if ((err=ReadPanelHandle(hndl, &panel)) != HandleError_None)
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *text;
|
||||||
|
pContext->LocalToString(params[2], &text);
|
||||||
|
|
||||||
|
panel->DrawTitle(text, params[3] ? true : false);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t DrawPanelItem(IPluginContext *pContext, const cell_t *params)
|
||||||
|
{
|
||||||
|
Handle_t hndl = (Handle_t)params[1];
|
||||||
|
HandleError err;
|
||||||
|
IMenuPanel *panel;
|
||||||
|
|
||||||
|
if ((err=ReadPanelHandle(hndl, &panel)) != HandleError_None)
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemDrawInfo dr;
|
||||||
|
pContext->LocalToString(params[2], (char **)&dr.display);
|
||||||
|
dr.style = params[3];
|
||||||
|
|
||||||
|
return panel->DrawItem(dr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t DrawPanelText(IPluginContext *pContext, const cell_t *params)
|
||||||
|
{
|
||||||
|
Handle_t hndl = (Handle_t)params[1];
|
||||||
|
HandleError err;
|
||||||
|
IMenuPanel *panel;
|
||||||
|
|
||||||
|
if ((err=ReadPanelHandle(hndl, &panel)) != HandleError_None)
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *text;
|
||||||
|
pContext->LocalToString(params[2], &text);
|
||||||
|
|
||||||
|
return panel->DrawRawLine(text) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t CanPanelDrawFlags(IPluginContext *pContext, const cell_t *params)
|
||||||
|
{
|
||||||
|
Handle_t hndl = (Handle_t)params[1];
|
||||||
|
HandleError err;
|
||||||
|
IMenuPanel *panel;
|
||||||
|
|
||||||
|
if ((err=ReadPanelHandle(hndl, &panel)) != HandleError_None)
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
|
||||||
|
}
|
||||||
|
|
||||||
|
return panel->CanDrawItem(params[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t SendPanelToClient(IPluginContext *pContext, const cell_t *params)
|
||||||
|
{
|
||||||
|
Handle_t hndl = (Handle_t)params[1];
|
||||||
|
HandleError err;
|
||||||
|
IMenuPanel *panel;
|
||||||
|
|
||||||
|
if ((err=ReadPanelHandle(hndl, &panel)) != HandleError_None)
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
|
||||||
|
}
|
||||||
|
|
||||||
|
IPluginFunction *pFunction;
|
||||||
|
if ((pFunction=pContext->GetFunctionById(params[3])) == NULL)
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Function id %x is invalid", params[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
CPanelHandler *handler = g_MenuHelpers.GetPanelHandler(pFunction);
|
||||||
|
if (!panel->SendDisplay(params[2], handler, params[4]))
|
||||||
|
{
|
||||||
|
g_MenuHelpers.FreePanelHandler(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
REGISTER_NATIVES(menuNatives)
|
||||||
|
{
|
||||||
|
{"AddMenuItem", AddMenuItem},
|
||||||
|
{"CanPanelDrawFlags", CanPanelDrawFlags},
|
||||||
|
{"CancelClientMenu", CancelClientMenu},
|
||||||
|
{"CancelMenu", CancelMenu},
|
||||||
|
{"CreateMenu", CreateMenu},
|
||||||
|
{"CreateMenuEx", CreateMenuEx},
|
||||||
|
{"CreatePanel", CreatePanel},
|
||||||
|
{"CreatePanelFromMenu", CreatePanelFromMenu},\
|
||||||
|
{"DisplayMenu", DisplayMenu},
|
||||||
|
{"DrawPanelItem", DrawPanelItem},
|
||||||
|
{"DrawPanelText", DrawPanelText},
|
||||||
|
{"GetClientMenu", GetClientMenu},
|
||||||
|
{"GetMaxPageItems", GetMaxPageItems},
|
||||||
|
{"GetMenuExitButton", GetMenuExitButton},
|
||||||
|
{"GetMenuItem", GetMenuItem},
|
||||||
|
{"GetMenuItemCount", GetMenuItemCount},
|
||||||
|
{"GetMenuPagination", GetMenuPagination},
|
||||||
|
{"GetMenuStyle", GetMenuStyle},
|
||||||
|
{"GetMenuStyleHandle", GetMenuStyleHandle},
|
||||||
|
{"GetPanelStyle", GetPanelStyle},
|
||||||
|
{"InsertMenuItem", InsertMenuItem},
|
||||||
|
{"RemoveAllMenuItems", RemoveAllMenuItems},
|
||||||
|
{"RemoveMenuItem", RemoveMenuItem},
|
||||||
|
{"SendPanelToClient", SendPanelToClient},
|
||||||
|
{"SetMenuExitButton", SetMenuExitButton},
|
||||||
|
{"SetMenuPagination", SetMenuPagination},
|
||||||
|
{"SetMenuTitle", SetMenuTitle},
|
||||||
|
{"SetPanelTitle", SetPanelTitle},
|
||||||
|
{NULL, NULL},
|
||||||
|
};
|
@ -194,6 +194,13 @@ int BaseContext::Execute(uint32_t code_addr, cell_t *result)
|
|||||||
return SP_ERROR_NOT_RUNNABLE;
|
return SP_ERROR_NOT_RUNNABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* tada, prevent a crash */
|
||||||
|
cell_t _ignore_result;
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
result = &_ignore_result;
|
||||||
|
}
|
||||||
|
|
||||||
IVirtualMachine *vm = (IVirtualMachine *)ctx->vmbase;
|
IVirtualMachine *vm = (IVirtualMachine *)ctx->vmbase;
|
||||||
|
|
||||||
uint32_t pushcount = ctx->pushcount;
|
uint32_t pushcount = ctx->pushcount;
|
||||||
|
500
plugins/include/menus.inc
Normal file
500
plugins/include/menus.inc
Normal file
@ -0,0 +1,500 @@
|
|||||||
|
/**
|
||||||
|
* vim: set ts=4 :
|
||||||
|
* ===============================================================
|
||||||
|
* SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved.
|
||||||
|
* ===============================================================
|
||||||
|
*
|
||||||
|
* This file is part of the SourceMod/SourcePawn SDK. This file may only be used
|
||||||
|
* or modified under the Terms and Conditions of its License Agreement, which is found
|
||||||
|
* in LICENSE.txt. The Terms and Conditions for making SourceMod extensions/plugins
|
||||||
|
* may change at any time. To view the latest information, see:
|
||||||
|
* http://www.sourcemod.net/license.php
|
||||||
|
*
|
||||||
|
* Version: $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined _menus_included
|
||||||
|
#endinput
|
||||||
|
#endif
|
||||||
|
#define _menus_included
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Low-level drawing style of the menu.
|
||||||
|
*/
|
||||||
|
enum MenuStyle
|
||||||
|
{
|
||||||
|
MenuStyle_Default = 0, /**< The "default" menu style for the mod */
|
||||||
|
MenuStyle_Valve = 1, /**< The Valve provided menu style (Used on HL2DM) */
|
||||||
|
MenuStyle_Radio = 2, /**< The simpler menu style commonly used on CS:S */
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Different actions for the menu "pump" callback
|
||||||
|
*/
|
||||||
|
enum MenuAction
|
||||||
|
{
|
||||||
|
MenuAction_Start = (1<<0), /**< A menu has been started (nothing passed) */
|
||||||
|
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=item) */
|
||||||
|
MenuAction_End = (1<<4), /**< A menu's display/selection cycle is complete (nothing passed). */
|
||||||
|
MenuAction_VoteEnd = (1<<5), /**< (VOTE ONLY): A vote sequence has ended (param1=chosen item) */
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Default menu actions */
|
||||||
|
#define MENU_ACTIONS_DEFAULT MenuAction_Select|MenuAction_Cancel|MenuAction_End
|
||||||
|
/** All menu actions */
|
||||||
|
#define MENU_ACTIONS_ALL -1
|
||||||
|
|
||||||
|
#define MENU_NO_PAGINATION 0 /**< Menu should not be paginated (10 items max) */
|
||||||
|
#define MENU_TIME_FOREVER 0 /**< Menu should be displayed as long as possible */
|
||||||
|
|
||||||
|
#define ITEMDRAW_DEFAULT (0) /**< Item should be drawn normally */
|
||||||
|
#define ITEMDRAW_DISABLED (1<<0) /**< Item is drawn but not selectable */
|
||||||
|
#define ITEMDRAW_RAWLINE (1<<1) /**< Item should be a raw line, without a slot */
|
||||||
|
#define ITEMDRAW_NOTEXT (1<<2) /**< No text should be drawn */
|
||||||
|
#define ITEMDRAW_SPACER (1<<3) /**< Item should be drawn as a spacer, if possible */
|
||||||
|
#define ITEMDRAW_IGNORE ((1<<1)|(1<<2)) /**< Item should be completely ignored (rawline + notext) */
|
||||||
|
#define ITEMDRAW_CONTROL (1<<4) /**< Item is control text (back/next/exit) */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reasons a menu can be cancelled.
|
||||||
|
*/
|
||||||
|
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 */
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Describes a menu's source
|
||||||
|
*/
|
||||||
|
enum MenuSource
|
||||||
|
{
|
||||||
|
MenuSource_None = 0, /**< No menu is being displayed */
|
||||||
|
MenuSource_External = 1, /**< External menu */
|
||||||
|
MenuSource_Normal = 2, /**< A basic menu is being displayed */
|
||||||
|
MenuSource_RawPanel = 3, /**< A display is active, but it is not tied to a menu */
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a menu action is completed.
|
||||||
|
*
|
||||||
|
* @param menu The menu being acted upon.
|
||||||
|
* @param action The action of the menu.
|
||||||
|
* @param param1 First action parameter (usually the client).
|
||||||
|
* @param param2 Second action parameter (usually the item).
|
||||||
|
* @noreturn
|
||||||
|
*/
|
||||||
|
functag MenuHandler public(Handle:menu, MenuAction:action, param1, param2);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new, empty menu using the default style.
|
||||||
|
*
|
||||||
|
* @param handler Function which will receive menu actions.
|
||||||
|
* @param actions Optionally set which actions to receive. Select,
|
||||||
|
* Cancel, and End will always be received regardless
|
||||||
|
* of whether they are set or not. They are also
|
||||||
|
* the only default actions.
|
||||||
|
* @return A new menu Handle.
|
||||||
|
*/
|
||||||
|
native Handle:CreateMenu(MenuHandler:handler, MenuAction:actions=MENU_ACTIONS_DEFAULT);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays a menu to a client.
|
||||||
|
*
|
||||||
|
* @param menu Menu Handle.
|
||||||
|
* @param client Client index.
|
||||||
|
* @param time Maximum time to leave menu on the screen.
|
||||||
|
* @return True on success, false on failure.
|
||||||
|
* @error Invalid Handle or client not in game.
|
||||||
|
*/
|
||||||
|
native bool:DisplayMenu(Handle:menu, client, time);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Appends a new item to the end of a menu.
|
||||||
|
*
|
||||||
|
* @param menu Menu Handle.
|
||||||
|
* @param info Item information string.
|
||||||
|
* @param display Default item display string.
|
||||||
|
* @param style Drawing style flags.
|
||||||
|
* @return True on success, false on failure.
|
||||||
|
* @error Invalid Handle or item limit reached.
|
||||||
|
*/
|
||||||
|
native AddMenuItem(Handle:menu,
|
||||||
|
const String:info[],
|
||||||
|
const String:display[],
|
||||||
|
style=ITEMDRAW_DEFAULT);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts an item into the menu before a certain position; the new item will
|
||||||
|
* be at the given position and all next items pushed forward.
|
||||||
|
*
|
||||||
|
* @param menu Menu Handle.
|
||||||
|
* @param position Position, starting from 0.
|
||||||
|
* @param info Item information string.
|
||||||
|
* @param display Default item display string.
|
||||||
|
* @param style Drawing style flags.
|
||||||
|
* @return True on success, false on failure.
|
||||||
|
* @error Invalid Handle or menu position.
|
||||||
|
*/
|
||||||
|
native bool:InsertMenuItem(Handle:menu,
|
||||||
|
position,
|
||||||
|
const String:info[],
|
||||||
|
const String:display[],
|
||||||
|
style=ITEMDRAW_DEFAULT);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes an item from the menu.
|
||||||
|
*
|
||||||
|
* @param menu Menu Handle.
|
||||||
|
* @param position Position, starting from 0.
|
||||||
|
* @return True on success, false on failure.
|
||||||
|
* @error Invalid Handle or menu position.
|
||||||
|
*/
|
||||||
|
native bool:RemoveMenuItem(Handle:menu, position);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes all items from a menu.
|
||||||
|
*
|
||||||
|
* @param menu Menu Handle.
|
||||||
|
* @noreturn
|
||||||
|
* @error Invalid Handle or menu position.
|
||||||
|
*/
|
||||||
|
native RemoveAllMenuItems(Handle:menu);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves information about a menu item.
|
||||||
|
*
|
||||||
|
* @param menu Menu Handle.
|
||||||
|
* @param position Position, starting from 0.
|
||||||
|
* @param infoBuf Info buffer.
|
||||||
|
* @param infoBufLen Maximum length of the info buffer.
|
||||||
|
* @param style By-reference variable to store drawing flags.
|
||||||
|
* @param dispBuf Display buffer.
|
||||||
|
* @param dispBufLen Maximum length of the display buffer.
|
||||||
|
* @return True on success, false if position is invalid.
|
||||||
|
* @error Invalid Handle.
|
||||||
|
*/
|
||||||
|
native bool:GetMenuItem(Handle:menu, position, String:infoBuf[], infoBufLen, &style=0, String:dispBuf[]="", dispBufLen=0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of items in a menu.
|
||||||
|
*
|
||||||
|
* @param menu Menu Handle.
|
||||||
|
* @return Number of items in the menu.
|
||||||
|
* @error Invalid Handle.
|
||||||
|
*/
|
||||||
|
native GetMenuItemCount(Handle:menu);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether the menu should be paginated or not.
|
||||||
|
*
|
||||||
|
* @param menu Handle to the menu.
|
||||||
|
* @param itemsPerPage Number of items per page, or MENU_NO_PAGINATION.
|
||||||
|
* @return True on success, false if pagination is too high or low.
|
||||||
|
* @error Invalid Handle.
|
||||||
|
*/
|
||||||
|
native bool:SetMenuPagination(Handle:menu, itemsPerPage);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a menu's pagination setting.
|
||||||
|
*
|
||||||
|
* @param menu Handle to the menu.
|
||||||
|
* @return Pagination setting.
|
||||||
|
* @error Invalid Handle.
|
||||||
|
*/
|
||||||
|
native GetMenuPagination(Handle:menu);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a menu's MenuStyle Handle. The Handle
|
||||||
|
* is global and cannot be freed.
|
||||||
|
*
|
||||||
|
* @param menu Handle to the menu.
|
||||||
|
* @return Handle to the menu's draw style.
|
||||||
|
* @error Invalid Handle.
|
||||||
|
*/
|
||||||
|
native Handle:GetMenuStyle(Handle:menu);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the menu's default title/instruction message.
|
||||||
|
*
|
||||||
|
* @param menu Menu Handle.
|
||||||
|
* @param fmt Message string format
|
||||||
|
* @param ... Message string arguments.
|
||||||
|
* @noreturn
|
||||||
|
* @error Invalid Handle.
|
||||||
|
*/
|
||||||
|
native SetMenuTitle(Handle:menu, const String:fmt[], any:...);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a raw MenuPanel based off the menu's style.
|
||||||
|
* The Handle must be freed with CloseHandle().
|
||||||
|
*
|
||||||
|
* @return A new MenuPanel Handle.
|
||||||
|
* @error Invalid Handle.
|
||||||
|
*/
|
||||||
|
native Handle:CreatePanelFromMenu(Handle:menu);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether or not the menu has an exit button.
|
||||||
|
* By default, menus have an exit button.
|
||||||
|
*
|
||||||
|
* @param menu Menu Handle.
|
||||||
|
* @return True if the menu has an exit button; false otherwise.
|
||||||
|
* @error Invalid Handle.
|
||||||
|
*/
|
||||||
|
native bool:GetMenuExitButton(Handle:menu);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether or not the menu has an exit button.
|
||||||
|
* By default, menus have an exit button.
|
||||||
|
*
|
||||||
|
* @param menu Menu Handle.
|
||||||
|
* @param button True to enable the button, false to remove it.
|
||||||
|
* @return True if allowed; false on failure.
|
||||||
|
* @error Invalid Handle.
|
||||||
|
*/
|
||||||
|
native bool:SetMenuExitButton(Handle:menu, bool:button);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancels a menu from displaying on all clients. While the
|
||||||
|
* cancellation is in progress, this menu cannot be re-displayed
|
||||||
|
* to any clients.
|
||||||
|
*
|
||||||
|
* The menu may still exist on the client's screen after this command.
|
||||||
|
* This simply verifies that the menu is not being used anywhere.
|
||||||
|
*
|
||||||
|
* @param menu Menu Handle.
|
||||||
|
* @noreturn
|
||||||
|
* @error Invalid Handle.
|
||||||
|
*/
|
||||||
|
native CancelMenu(Handle:menu);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/**
|
||||||
|
* Broadcasts a menu to a list of clients.
|
||||||
|
*
|
||||||
|
* @param menu Menu Handle.
|
||||||
|
* @param handler MenuHandler callback to receive actions.
|
||||||
|
* @param players Array of players to broadcast to.
|
||||||
|
* @param numPlayers Number of players in the array.
|
||||||
|
* @param time Maximum time to leave menu on the screen.
|
||||||
|
* @return Number of clients that broadcast will wait upon.
|
||||||
|
* @error Invalid Handle.
|
||||||
|
*/
|
||||||
|
native BroadcastMenu(Handle:menu, MenuHandler:handler, players[], numPlayers, time);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Broadcasts a menu to a list of clients. The most selected
|
||||||
|
* item will be returned through MenuAction_End. On a tie, a random
|
||||||
|
* item will be returned.
|
||||||
|
*
|
||||||
|
* @param menu Menu Handle.
|
||||||
|
* @param handler MenuHandler callback to receive actions.
|
||||||
|
* @param players Array of players to broadcast to.
|
||||||
|
* @param numPlayers Number of players in the array.
|
||||||
|
* @param time Maximum time to leave menu on the screen.
|
||||||
|
* @return Number of clients that vote will wait upon.
|
||||||
|
* @error Invalid Handle.
|
||||||
|
*/
|
||||||
|
native VoteMenu(Handle:menu, MenuHandler:handler, players[], numPlayers, time);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Broadcasts a menu to all clients.
|
||||||
|
*
|
||||||
|
* @param menu Menu Handle.
|
||||||
|
* @param handler MenuHandler callback to receive actions.
|
||||||
|
* @param time Maximum time to leave menu on the screen.
|
||||||
|
* @return Number of clients that broadcast will wait upon.
|
||||||
|
* @error Invalid Handle.
|
||||||
|
*/
|
||||||
|
stock BroadcastMenuToAll(Handle:menu, MenuHandler:handler, time)
|
||||||
|
{
|
||||||
|
new num = GetMaxClients();
|
||||||
|
new total;
|
||||||
|
decl players[num];
|
||||||
|
|
||||||
|
for (new i=1; i<=num; i++)
|
||||||
|
{
|
||||||
|
if (!IsClientConnected(i))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
players[total++] = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return BroadcastMenu(menu, handler, players, total, time);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Broadcasts a menu to all clients. The most selected item will
|
||||||
|
* be returned through MenuAction_End. On a tie, a random item
|
||||||
|
* will be returned.
|
||||||
|
*
|
||||||
|
* @param menu Menu Handle.
|
||||||
|
* @param handler MenuHandler callback to receive actions.
|
||||||
|
* @param time Maximum time to leave menu on the screen.
|
||||||
|
* @return Number of clients that the vote will wait upon.
|
||||||
|
* @error Invalid Handle.
|
||||||
|
*/
|
||||||
|
native VoteMenuToAll(Handle:menu, MenuHandler:handler, time)
|
||||||
|
{
|
||||||
|
new num = GetMaxClients();
|
||||||
|
new total;
|
||||||
|
decl players[num];
|
||||||
|
|
||||||
|
for (new i=1; i<=num; i++)
|
||||||
|
{
|
||||||
|
if (!IsClientConnected(i))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
players[total++] = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return VoteMenu(menu, handler, players, total, time);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a style's global Handle.
|
||||||
|
*
|
||||||
|
* @param style Menu Style.
|
||||||
|
* @return A Handle, or INVALID_HANDLE if not found or unusable.
|
||||||
|
*/
|
||||||
|
native Handle:GetMenuStyleHandle(MenuStyle:style);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a MenuPanel from a MenuStyle. Panels are used for drawing raw
|
||||||
|
* menus without any extra helper functions. The Handle must be closed
|
||||||
|
* with CloseHandle().
|
||||||
|
*
|
||||||
|
* @param hStyle MenuStyle Handle, or INVALID_HANDLE to use the default style.
|
||||||
|
* @return A new MenuPanel Handle.
|
||||||
|
* @error Invalid Handle other than INVALID_HANDLE.
|
||||||
|
*/
|
||||||
|
native Handle:CreatePanel(Handle:hStyle=INVALID_HANDLE);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a Menu from a MenuStyle. The Handle must be closed with
|
||||||
|
* CloseHandle().
|
||||||
|
*
|
||||||
|
* @parma hStyle MenuStyle Handle, or INVALID_HANDLE to use the default style.
|
||||||
|
* @param handler Function which will receive menu actions.
|
||||||
|
* @param actions Optionally set which actions to receive. Select,
|
||||||
|
* Cancel, and End will always be received regardless
|
||||||
|
* of whether they are set or not. They are also
|
||||||
|
* the only default actions.
|
||||||
|
* @return A new menu Handle.
|
||||||
|
* @error Invalid Handle other than INVALID_HANDLE.
|
||||||
|
*/
|
||||||
|
native Handle:CreateMenuEx(Handle:hStyle=INVALID_HANDLE, MenuHandler:handler, MenuAction:actions=MENU_ACTIONS_DEFAULT);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether a client is viewing a menu. If the menu source
|
||||||
|
* is MenuSource_Normal, a menu Handle will also be returned.
|
||||||
|
*
|
||||||
|
* @param client Client index.
|
||||||
|
* @param hStyle MenuStyle Handle, or INVALID_HANDLE to use the default style.
|
||||||
|
* @return A MenuSource value.
|
||||||
|
* @error Invalid Handle other than INVALID_HANDLE.
|
||||||
|
*/
|
||||||
|
native MenuSource:GetClientMenu(client, Handle:hStyle=INVALID_HANDLE);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancels a menu on a client. This will only affect non-external menus.
|
||||||
|
*
|
||||||
|
* @param hstyle MenuStyle Handle, or INVALID_HANDLE to use the default style.
|
||||||
|
* @param client Client index.
|
||||||
|
* @param autoIgnore If true, no menus can be re-drawn on the client during
|
||||||
|
* the cancellation process.
|
||||||
|
* @return True if a menu was cancelled, false otherwise.
|
||||||
|
*/
|
||||||
|
native bool:CancelClientMenu(client, bool:autoIgnore=false, Handle:hStyle=INVALID_HANDLE);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a style's maximum items per page.
|
||||||
|
*
|
||||||
|
* @param hStyle MenuStyle Handle, or INVALID_HANDLE to use the default style.
|
||||||
|
* @return Maximum items per page.
|
||||||
|
* @error Invalid Handle other than INVALID_HANDLE.
|
||||||
|
*/
|
||||||
|
native GetMaxPageItems(Handle:hStyle=INVALID_HANDLE);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a MenuPanel's parent style.
|
||||||
|
*
|
||||||
|
* @param panel A MenuPanel Handle.
|
||||||
|
* @return The MenuStyle Handle that created the panel.
|
||||||
|
* @error Invalid Handle.
|
||||||
|
*/
|
||||||
|
native Handle:GetPanelStyle(Handle:panel);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the panel's title.
|
||||||
|
*
|
||||||
|
* @param panel A MenuPanel Handle.
|
||||||
|
* @param title Text to set as the title.
|
||||||
|
* @param onlyIfEmpty If true, the title will only be set if no title is set.
|
||||||
|
* @noreturn
|
||||||
|
* @error Invalid Handle.
|
||||||
|
*/
|
||||||
|
native Handle:SetPanelTitle(Handle:panel, const String:text[], bool:onlyIfEmpty=false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draws an item on a panel. If the item takes up a slot, the position
|
||||||
|
* is returned.
|
||||||
|
*
|
||||||
|
* @param panel A MenuPanel Handle.
|
||||||
|
* @param text Display text to use. If not a raw line,
|
||||||
|
* the style may automatically add color markup.
|
||||||
|
* No numbering or newlines are needed.
|
||||||
|
* @param style ITEMDRAW style flags.
|
||||||
|
* @return A slot position, or 0 if item was a rawline or could not be drawn.
|
||||||
|
* @error Invalid Handle.
|
||||||
|
*/
|
||||||
|
native DrawPanelItem(Handle:panel, const String:text[], style=ITEMDRAW_DEFAULT);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draws a raw line of text on a panel, without any markup other than a newline.
|
||||||
|
*
|
||||||
|
* @param panel A MenuPanel Handle.
|
||||||
|
* @param text Display text to use.
|
||||||
|
* @return True on success, false if raw lines are not supported.
|
||||||
|
* @error Invalid Handle.
|
||||||
|
*/
|
||||||
|
native DrawPanelText(Handle:panel, const String:text[]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether or not the given drawing flags are supported by
|
||||||
|
* the menu style.
|
||||||
|
*
|
||||||
|
* @param panel A MenuPanel Handle.
|
||||||
|
* @param style ITEMDRAW style flags.
|
||||||
|
* @return True if item is drawable, false otherwise.
|
||||||
|
* @error Invalid Handle.
|
||||||
|
*/
|
||||||
|
native CanPanelDrawFlags(Handle:panel, style);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a panel to a client. Unlike full menus, the handler
|
||||||
|
* function will only receive the following actions, both of
|
||||||
|
* which will have INVALID_HANDLE for a menu, and the client
|
||||||
|
* as param1.
|
||||||
|
*
|
||||||
|
* MenuAction_Select (param2 will be the key pressed)
|
||||||
|
* MenuAction_Cancel (param2 will be the reason)
|
||||||
|
*
|
||||||
|
* Also, if the menu fails to display, no callbacks will be called.
|
||||||
|
*
|
||||||
|
* @param panel A MenuPanel Handle.
|
||||||
|
* @param client A client to draw to.
|
||||||
|
* @param handler The MenuHandler function to catch actions with.
|
||||||
|
* @param time Time to hold the menu for.
|
||||||
|
* @return True on success, false on failure.
|
||||||
|
* @error Invalid Handle.
|
||||||
|
*/
|
||||||
|
native bool:SendPanelToClient(Handle:panel, client, MenuHandler:handler, time);
|
@ -20,6 +20,7 @@
|
|||||||
#define _INCLUDE_SOURCEMOD_MENU_SYSTEM_H_
|
#define _INCLUDE_SOURCEMOD_MENU_SYSTEM_H_
|
||||||
|
|
||||||
#include <IShareSys.h>
|
#include <IShareSys.h>
|
||||||
|
#include <IHandleSys.h>
|
||||||
|
|
||||||
#define SMINTERFACE_MENUMANAGER_NAME "IMenuManager"
|
#define SMINTERFACE_MENUMANAGER_NAME "IMenuManager"
|
||||||
#define SMINTERFACE_MENUMANAGER_VERSION 1
|
#define SMINTERFACE_MENUMANAGER_VERSION 1
|
||||||
@ -263,9 +264,12 @@ namespace SourceMod
|
|||||||
*
|
*
|
||||||
* Note: the object should be freed using IBaseMenu::Destroy.
|
* Note: the object should be freed using IBaseMenu::Destroy.
|
||||||
*
|
*
|
||||||
|
* @param handler IMenuHandler pointer.
|
||||||
|
* @param pOwner Optional IdentityToken_t owner for handle
|
||||||
|
* creation.
|
||||||
* @return An IBaseMenu pointer.
|
* @return An IBaseMenu pointer.
|
||||||
*/
|
*/
|
||||||
virtual IBaseMenu *CreateMenu() =0;
|
virtual IBaseMenu *CreateMenu(IMenuHandler *handler, IdentityToken_t *pOwner=NULL) =0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns the maximum number of items per page.
|
* @brief Returns the maximum number of items per page.
|
||||||
@ -293,6 +297,13 @@ namespace SourceMod
|
|||||||
* @return True if a menu was cancelled, false otherwise.
|
* @return True if a menu was cancelled, false otherwise.
|
||||||
*/
|
*/
|
||||||
virtual bool CancelClientMenu(int client, bool autoIgnore=false) =0;
|
virtual bool CancelClientMenu(int client, bool autoIgnore=false) =0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns a Handle the IMenuStyle object.
|
||||||
|
*
|
||||||
|
* @return Handle_t pointing to this object.
|
||||||
|
*/
|
||||||
|
virtual Handle_t GetHandle() =0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -428,16 +439,20 @@ namespace SourceMod
|
|||||||
* @brief Sends the menu to a client.
|
* @brief Sends the menu to a client.
|
||||||
*
|
*
|
||||||
* @param client Client index to display to.
|
* @param client Client index to display to.
|
||||||
* @param handler Menu handler to use.
|
|
||||||
* @param time Time to hold menu for.
|
* @param time Time to hold menu for.
|
||||||
* @return True on success, false otherwise.
|
* @return True on success, false otherwise.
|
||||||
*/
|
*/
|
||||||
virtual bool Display(int client, IMenuHandler *handler, unsigned int time) =0;
|
virtual bool Display(int client, unsigned int time) =0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Destroys the menu and frees all associated resources.1
|
* @brief Destroys the menu and frees all associated resources.
|
||||||
|
*
|
||||||
|
* @param releaseHandle If true, the Handle will be released
|
||||||
|
* in the destructor. This should be set
|
||||||
|
* to true except for IHandleTypeDispatch
|
||||||
|
* destructors.
|
||||||
*/
|
*/
|
||||||
virtual void Destroy() =0;
|
virtual void Destroy(bool releaseHandle=true) =0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Cancels the menu on all client's displays. While the menu is
|
* @brief Cancels the menu on all client's displays. While the menu is
|
||||||
@ -446,6 +461,14 @@ namespace SourceMod
|
|||||||
* @return Number of menus cancelled.
|
* @return Number of menus cancelled.
|
||||||
*/
|
*/
|
||||||
virtual void Cancel() =0;
|
virtual void Cancel() =0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the menu's Handle. The Handle is automatically
|
||||||
|
* removed when the menu is destroyed.
|
||||||
|
*
|
||||||
|
* @return Handle_t handle value.
|
||||||
|
*/
|
||||||
|
virtual Handle_t GetHandle() =0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -516,6 +539,15 @@ namespace SourceMod
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Called when the menu object is destroyed.
|
||||||
|
*
|
||||||
|
* @param menu Menu pointer.
|
||||||
|
*/
|
||||||
|
virtual void OnMenuDestroy(IBaseMenu *menu)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Called when requesting how to render an item.
|
* @brief Called when requesting how to render an item.
|
||||||
*
|
*
|
||||||
@ -579,11 +611,11 @@ namespace SourceMod
|
|||||||
*/
|
*/
|
||||||
virtual IMenuStyle *FindStyleByName(const char *name) =0;
|
virtual IMenuStyle *FindStyleByName(const char *name) =0;
|
||||||
|
|
||||||
|
#if 0
|
||||||
/**
|
/**
|
||||||
* @brief Broadcasts a menu to a number of clients.
|
* @brief Broadcasts a menu to a number of clients.
|
||||||
*
|
*
|
||||||
* @param menu Menu pointer.
|
* @param menu Menu pointer.
|
||||||
* @param handler IMenuHandler pointer.
|
|
||||||
* @param clients Array of client indexes.
|
* @param clients Array of client indexes.
|
||||||
* @param numClients Number of clients in the array.
|
* @param numClients Number of clients in the array.
|
||||||
* @param time Time to hold the menu.
|
* @param time Time to hold the menu.
|
||||||
@ -610,6 +642,7 @@ namespace SourceMod
|
|||||||
int clients[],
|
int clients[],
|
||||||
unsigned int numClients,
|
unsigned int numClients,
|
||||||
unsigned int time) =0;
|
unsigned int time) =0;
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns the default draw style Core is using.
|
* @brief Returns the default draw style Core is using.
|
||||||
|
Loading…
Reference in New Issue
Block a user