- added MenuAction_DisplayItem callback for plugins

- fixed various bugs in MenuAction_Display
- added an "access" parameter for IMenuManager.  better to do this now than later, even though it's not used yet
- hard bumped menu api to change the OnMenuDisplayItem callback.  sorry!

--HG--
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%401169
This commit is contained in:
David Anderson 2007-07-25 01:18:11 +00:00
parent 39f7d51747
commit 1027d151e5
7 changed files with 127 additions and 26 deletions

View File

@ -187,9 +187,9 @@ void VoteMenuHandler::OnMenuDisplay(IBaseMenu *menu, int client, IMenuPanel *dis
m_pHandler->OnMenuDisplay(menu, client, display); m_pHandler->OnMenuDisplay(menu, client, display);
} }
void VoteMenuHandler::OnMenuDisplayItem(IBaseMenu *menu, int client, unsigned int item, const char **display) unsigned int VoteMenuHandler::OnMenuDisplayItem(IBaseMenu *menu, int client, IMenuPanel *panel, unsigned int item, const ItemDrawInfo &dr)
{ {
m_pHandler->OnMenuDisplayItem(menu, client, item, display); return m_pHandler->OnMenuDisplayItem(menu, client, panel, item, dr);
} }
void VoteMenuHandler::OnMenuDrawItem(IBaseMenu *menu, int client, unsigned int item, unsigned int &style) void VoteMenuHandler::OnMenuDrawItem(IBaseMenu *menu, int client, unsigned int item, unsigned int &style)
@ -594,8 +594,11 @@ skip_search:
for (unsigned int i=0; i<foundItems; i++) for (unsigned int i=0; i<foundItems; i++)
{ {
ItemDrawInfo &dr = drawItems[i].draw; ItemDrawInfo &dr = drawItems[i].draw;
mh->OnMenuDisplayItem(menu, client, drawItems[i].position, &(dr.display)); if ((position = mh->OnMenuDisplayItem(menu, client, display, drawItems[i].position, dr)) == 0)
if ((position = display->DrawItem(dr)) != 0) {
position = display->DrawItem(dr);
}
if (position != 0)
{ {
slots[position].item = drawItems[i].position; slots[position].item = drawItems[i].position;
slots[position].type = ItemSel_Item; slots[position].type = ItemSel_Item;
@ -609,7 +612,10 @@ skip_search:
while (i--) while (i--)
{ {
ItemDrawInfo &dr = drawItems[i].draw; ItemDrawInfo &dr = drawItems[i].draw;
mh->OnMenuDisplayItem(menu, client, drawItems[i].position, &(dr.display)); if ((position = mh->OnMenuDisplayItem(menu, client, display, drawItems[i].position, dr)) == 0)
{
position = display->DrawItem(dr);
}
if ((position = display->DrawItem(dr)) != 0) if ((position = display->DrawItem(dr)) != 0)
{ {
slots[position].item = drawItems[i].position; slots[position].item = drawItems[i].position;

View File

@ -35,7 +35,7 @@ public: //IMenuHandler
void OnMenuCancel(IBaseMenu *menu, int client, MenuCancelReason reason); void OnMenuCancel(IBaseMenu *menu, int client, MenuCancelReason reason);
void OnMenuEnd(IBaseMenu *menu, MenuEndReason reason); void OnMenuEnd(IBaseMenu *menu, MenuEndReason reason);
void OnMenuDrawItem(IBaseMenu *menu, int client, unsigned int item, unsigned int &style); void OnMenuDrawItem(IBaseMenu *menu, int client, unsigned int item, unsigned int &style);
void OnMenuDisplayItem(IBaseMenu *menu, int client, unsigned int item, const char **display); unsigned int OnMenuDisplayItem(IBaseMenu *menu, int client, IMenuPanel *panel, unsigned int item, const ItemDrawInfo &dr);
public: //IVoteMenuHandler public: //IVoteMenuHandler
bool IsVoteInProgress(); bool IsVoteInProgress();
void InitializeVoting(IBaseMenu *menu); void InitializeVoting(IBaseMenu *menu);

View File

@ -427,10 +427,10 @@ bool BaseMenuStyle::DoClientMenu(int client, CBaseMenu *menu, IMenuHandler *mh,
} }
/* For the duration of this, we are going to totally ignore whether /* For the duration of this, we are going to totally ignore whether
* the player is already in a menu or not (except to cancel the old one). * the player is already in a menu or not (except to cancel the old one).
* Instead, we are simply going to ignore any further menu displays, so * Instead, we are simply going to ignore any further menu displays, so
* this display can't be interrupted. * this display can't be interrupted.
*/ */
player->bAutoIgnore = true; player->bAutoIgnore = true;
/* Cancel any old menus */ /* Cancel any old menus */
@ -564,6 +564,7 @@ bool CBaseMenu::AppendItem(const char *info, const ItemDrawInfo &draw)
item.displayString = m_Strings.AddString(draw.display); item.displayString = m_Strings.AddString(draw.display);
} }
item.style = draw.style; item.style = draw.style;
item.access = draw.access;
m_items.push_back(item); m_items.push_back(item);
@ -591,6 +592,7 @@ bool CBaseMenu::InsertItem(unsigned int position, const char *info, const ItemDr
item.displayString = m_Strings.AddString(draw.display); item.displayString = m_Strings.AddString(draw.display);
} }
item.style = draw.style; item.style = draw.style;
item.access = draw.access;
CVector<CItem>::iterator iter = m_items.iterAt(position); CVector<CItem>::iterator iter = m_items.iterAt(position);
m_items.insert(iter, item); m_items.insert(iter, item);

View File

@ -33,11 +33,13 @@ public:
infoString = -1; infoString = -1;
displayString = -1; displayString = -1;
style = 0; style = 0;
access = 0;
} }
public: public:
int infoString; int infoString;
int displayString; int displayString;
unsigned int style; unsigned int style;
unsigned int access;
}; };
class CBaseMenuPlayer class CBaseMenuPlayer

View File

@ -45,6 +45,7 @@ enum MenuAction
MenuAction_VoteStart = (1<<6), /**< (VOTE ONLY): A vote sequence has started */ MenuAction_VoteStart = (1<<6), /**< (VOTE ONLY): A vote sequence has started */
MenuAction_VoteCancel = (1<<7), /**< (VOTE ONLY): A vote sequence has been cancelled (nothing passed) */ MenuAction_VoteCancel = (1<<7), /**< (VOTE ONLY): A vote sequence has been cancelled (nothing passed) */
MenuAction_DrawItem = (1<<8), /**< A style is being drawn; return the new style (param1=client, param2=item) */ MenuAction_DrawItem = (1<<8), /**< A style is being drawn; return the new style (param1=client, param2=item) */
MenuAction_DisplayItem = (1<<9), /**< the odd duck */
}; };
class CPanelHandler : public IMenuHandler class CPanelHandler : public IMenuHandler
@ -80,6 +81,7 @@ public:
unsigned int totalVotes); unsigned int totalVotes);
void OnMenuVoteCancel(IBaseMenu *menu); void OnMenuVoteCancel(IBaseMenu *menu);
void OnMenuDrawItem(IBaseMenu *menu, int client, unsigned int item, unsigned int &style); void OnMenuDrawItem(IBaseMenu *menu, int client, unsigned int item, unsigned int &style);
unsigned int OnMenuDisplayItem(IBaseMenu *menu, int client, IMenuPanel *panel, unsigned int item, const ItemDrawInfo &dr);
#if 0 #if 0
void OnMenuDrawItem(IBaseMenu *menu, int client, unsigned int item, unsigned int &style); void OnMenuDrawItem(IBaseMenu *menu, int client, unsigned int item, unsigned int &style);
void OnMenuDisplayItem(IBaseMenu *menu, int client, unsigned int item, const char **display); void OnMenuDisplayItem(IBaseMenu *menu, int client, unsigned int item, const char **display);
@ -104,11 +106,13 @@ public:
virtual void OnSourceModAllInitialized() virtual void OnSourceModAllInitialized()
{ {
m_PanelType = g_HandleSys.CreateType("IMenuPanel", this, 0, NULL, NULL, g_pCoreIdent, NULL); m_PanelType = g_HandleSys.CreateType("IMenuPanel", this, 0, NULL, NULL, g_pCoreIdent, NULL);
m_TempPanelType = g_HandleSys.CreateType("TempIMenuPanel", this, m_PanelType, NULL, NULL, g_pCoreIdent, NULL);
g_PluginSys.AddPluginsListener(this); g_PluginSys.AddPluginsListener(this);
} }
virtual void OnSourceModShutdown() virtual void OnSourceModShutdown()
{ {
g_HandleSys.RemoveType(m_TempPanelType, g_pCoreIdent);
g_HandleSys.RemoveType(m_PanelType, g_pCoreIdent); g_HandleSys.RemoveType(m_PanelType, g_pCoreIdent);
while (!m_FreePanelHandlers.empty()) while (!m_FreePanelHandlers.empty())
@ -126,6 +130,11 @@ public:
virtual void OnHandleDestroy(HandleType_t type, void *object) virtual void OnHandleDestroy(HandleType_t type, void *object)
{ {
if (type == m_TempPanelType)
{
return;
}
IMenuPanel *panel = (IMenuPanel *)object; IMenuPanel *panel = (IMenuPanel *)object;
panel->DeleteThis(); panel->DeleteThis();
} }
@ -155,6 +164,11 @@ public:
return m_PanelType; return m_PanelType;
} }
inline HandleType_t GetTempPanelType()
{
return m_TempPanelType;
}
CPanelHandler *GetPanelHandler(IPluginFunction *pFunction) CPanelHandler *GetPanelHandler(IPluginFunction *pFunction)
{ {
CPanelHandler *handler; CPanelHandler *handler;
@ -200,6 +214,7 @@ public:
private: private:
HandleType_t m_PanelType; HandleType_t m_PanelType;
HandleType_t m_TempPanelType;
CStack<CPanelHandler *> m_FreePanelHandlers; CStack<CPanelHandler *> m_FreePanelHandlers;
CStack<CMenuHandler *> m_FreeMenuHandlers; CStack<CMenuHandler *> m_FreeMenuHandlers;
CVector<CPanelHandler *> m_PanelHandlers; CVector<CPanelHandler *> m_PanelHandlers;
@ -235,6 +250,10 @@ void CPanelHandler::OnMenuSelect(IBaseMenu *menu, int client, unsigned int item)
g_MenuHelpers.FreePanelHandler(this); g_MenuHelpers.FreePanelHandler(this);
} }
static IMenuPanel *s_pCurPanel = NULL;
static unsigned int s_CurPanelReturn = 0;
static const ItemDrawInfo *s_CurDrawInfo = NULL;
/** /**
* MENU HANDLER WRAPPER * MENU HANDLER WRAPPER
*/ */
@ -257,14 +276,14 @@ void CMenuHandler::OnMenuDisplay(IBaseMenu *menu, int client, IMenuPanel *panel)
if ((m_Flags & (int)MenuAction_Display) == (int)MenuAction_Display) if ((m_Flags & (int)MenuAction_Display) == (int)MenuAction_Display)
{ {
HandleSecurity sec; HandleSecurity sec;
sec.pIdentity = m_pBasic->GetParentContext()->GetIdentity(); sec.pIdentity = g_pCoreIdent;
sec.pOwner = g_pCoreIdent; sec.pOwner = m_pBasic->GetParentContext()->GetIdentity();
HandleAccess access; HandleAccess access;
g_HandleSys.InitAccessDefaults(NULL, &access); g_HandleSys.InitAccessDefaults(NULL, &access);
access.access[HandleAccess_Delete] = HANDLE_RESTRICT_IDENTITY|HANDLE_RESTRICT_OWNER; access.access[HandleAccess_Delete] = HANDLE_RESTRICT_IDENTITY|HANDLE_RESTRICT_OWNER;
Handle_t hndl = g_HandleSys.CreateHandleEx(g_MenuHelpers.GetPanelType(), panel, &sec, &access, NULL); Handle_t hndl = g_HandleSys.CreateHandleEx(g_MenuHelpers.GetTempPanelType(), panel, &sec, &access, NULL);
DoAction(menu, MenuAction_Display, client, hndl); DoAction(menu, MenuAction_Display, client, hndl);
@ -319,6 +338,38 @@ void CMenuHandler::OnMenuDrawItem(IBaseMenu *menu, int client, unsigned int item
} }
} }
unsigned int CMenuHandler::OnMenuDisplayItem(IBaseMenu *menu,
int client,
IMenuPanel *panel,
unsigned int item,
const ItemDrawInfo &dr)
{
if ((m_Flags & (int)MenuAction_DisplayItem) == (int)MenuAction_DisplayItem)
{
IMenuPanel *oldpanel = s_pCurPanel;
unsigned int oldret = s_CurPanelReturn;
const ItemDrawInfo *oldinfo = s_CurDrawInfo;
s_pCurPanel = panel;
s_CurPanelReturn = 0;
s_CurDrawInfo = &dr;
cell_t res = DoAction(menu, MenuAction_DisplayItem, client, item, 0);
if (!res)
{
res = s_CurPanelReturn;
}
s_pCurPanel = oldpanel;
s_CurPanelReturn = oldret;
s_CurDrawInfo = oldinfo;
return res;
}
return 0;
}
cell_t CMenuHandler::DoAction(IBaseMenu *menu, MenuAction action, cell_t param1, cell_t param2, cell_t def_res) cell_t CMenuHandler::DoAction(IBaseMenu *menu, MenuAction action, cell_t param1, cell_t param2, cell_t def_res)
{ {
#if defined MENU_DEBUG #if defined MENU_DEBUG
@ -1002,6 +1053,27 @@ static cell_t SetPanelCurrentKey(IPluginContext *pContext, const cell_t *params)
return panel->SetCurrentKey(params[2]) ? 1 : 0; return panel->SetCurrentKey(params[2]) ? 1 : 0;
} }
static cell_t RedrawMenuItem(IPluginContext *pContext, const cell_t *params)
{
if (!s_pCurPanel)
{
return pContext->ThrowNativeError("You can only call this once from a MenuAction_DisplayItem callback");
}
char *str;
pContext->LocalToString(params[1], &str);
ItemDrawInfo dr = *s_CurDrawInfo;
dr.display = str;
if ((s_CurPanelReturn = s_pCurPanel->DrawItem(dr)) != 0)
{
s_pCurPanel = NULL;
}
return s_CurPanelReturn;
}
REGISTER_NATIVES(menuNatives) REGISTER_NATIVES(menuNatives)
{ {
{"AddMenuItem", AddMenuItem}, {"AddMenuItem", AddMenuItem},
@ -1028,6 +1100,7 @@ REGISTER_NATIVES(menuNatives)
{"GetPanelStyle", GetPanelStyle}, {"GetPanelStyle", GetPanelStyle},
{"InsertMenuItem", InsertMenuItem}, {"InsertMenuItem", InsertMenuItem},
{"IsVoteInProgress", IsVoteInProgress}, {"IsVoteInProgress", IsVoteInProgress},
{"RedrawMenuItem", RedrawMenuItem},
{"RemoveAllMenuItems", RemoveAllMenuItems}, {"RemoveAllMenuItems", RemoveAllMenuItems},
{"RemoveMenuItem", RemoveMenuItem}, {"RemoveMenuItem", RemoveMenuItem},
{"SendPanelToClient", SendPanelToClient}, {"SendPanelToClient", SendPanelToClient},

View File

@ -42,6 +42,10 @@ enum MenuAction
MenuAction_VoteStart = (1<<6), /**< (VOTE ONLY): A vote sequence has started (nothing passed) */ 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) */ MenuAction_VoteCancel = (1<<7), /**< (VOTE ONLY): A vote sequence has been cancelled (nothing passed) */
MenuAction_DrawItem = (1<<8), /**< An item is being drawn; return the new style (param1=client, param2=item) */ MenuAction_DrawItem = (1<<8), /**< An item is being drawn; return the new style (param1=client, param2=item) */
MenuAction_DisplayItem = (1<<9) /**< Item text is being drawn to the display (param1=client, param2=item)
To change the text, use RedrawMenuItem().
If you do so, return its return value. Otherwise, return 0.
*/
}; };
/** Default menu actions */ /** Default menu actions */
@ -475,7 +479,8 @@ 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. * Draws a raw line of text on a panel, without any markup other than a newline.
* *
* @param panel A MenuPanel Handle. * @param panel A MenuPanel Handle, or INVALID_HANDLE if inside a
* MenuAction_DisplayItem callback.
* @param text Display text to use. * @param text Display text to use.
* @return True on success, false if raw lines are not supported. * @return True on success, false if raw lines are not supported.
* @error Invalid Handle. * @error Invalid Handle.
@ -545,6 +550,14 @@ native GetPanelCurrentKey(Handle:panel);
*/ */
native bool:SetPanelCurrentKey(Handle:panel, key); native bool:SetPanelCurrentKey(Handle:panel, key);
/**
* @brief Redraws menu text from inside a MenuAction_DisplayItem callback.
*
* @param text Menu text to draw.
* @return Item position; must be returned via the callback.
*/
native RedrawMenuItem(const String:text[]);
/** /**
* Retrieves voting information from MenuAction_VoteEnd. * Retrieves voting information from MenuAction_VoteEnd.
* *

View File

@ -23,7 +23,7 @@
#include <IHandleSys.h> #include <IHandleSys.h>
#define SMINTERFACE_MENUMANAGER_NAME "IMenuManager" #define SMINTERFACE_MENUMANAGER_NAME "IMenuManager"
#define SMINTERFACE_MENUMANAGER_VERSION 6 #define SMINTERFACE_MENUMANAGER_VERSION 7
/** /**
* @file IMenuManager.h * @file IMenuManager.h
@ -93,17 +93,14 @@ namespace SourceMod
*/ */
struct ItemDrawInfo struct ItemDrawInfo
{ {
ItemDrawInfo() ItemDrawInfo(const char *DISPLAY=NULL, unsigned int STYLE=ITEMDRAW_DEFAULT,
{ unsigned int FLAGS=0, const char *HELPTEXT=NULL)
style = 0; : display(DISPLAY), style(STYLE), access(FLAGS)
display = NULL;
}
ItemDrawInfo(const char *DISPLAY, unsigned int STYLE=ITEMDRAW_DEFAULT)
: display(DISPLAY), style(STYLE)
{ {
} }
const char *display; /**< Display text (NULL for none) */ const char *display; /**< Display text (NULL for none) */
unsigned int style; /**< ITEMDRAW style flags */ unsigned int style; /**< ITEMDRAW style flags */
unsigned int access; /**< Access flags required to see */
}; };
/** /**
@ -648,15 +645,23 @@ namespace SourceMod
} }
/** /**
* @brief Called when requesting how to draw an item's text. * @brief Called when drawing item text.
* *
* @param menu Menu pointer. * @param menu Menu pointer.
* @param client Client index receiving the menu. * @param client Client index receiving the menu.
* @param panel Panel being used to draw the menu.
* @param item Item number in the menu. * @param item Item number in the menu.
* @param display Pointer to the display text string (changeable). * @param dr Item draw information.
* @return 0 to let the render algorithm decide how to draw, otherwise,
* the return value from panel->DrawItem should be returned.
*/ */
virtual void OnMenuDisplayItem(IBaseMenu *menu, int client, unsigned int item, const char **display) virtual unsigned int OnMenuDisplayItem(IBaseMenu *menu,
int client,
IMenuPanel *panel,
unsigned int item,
const ItemDrawInfo &dr)
{ {
return 0;
} }
/** /**
@ -755,7 +760,7 @@ namespace SourceMod
} }
virtual bool IsVersionCompatible(unsigned int version) virtual bool IsVersionCompatible(unsigned int version)
{ {
if (version < 5 || version > GetInterfaceVersion()) if (version < 7 || version > GetInterfaceVersion())
{ {
return false; return false;
} }