- 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);
}
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)
@ -594,8 +594,11 @@ skip_search:
for (unsigned int i=0; i<foundItems; i++)
{
ItemDrawInfo &dr = drawItems[i].draw;
mh->OnMenuDisplayItem(menu, client, drawItems[i].position, &(dr.display));
if ((position = display->DrawItem(dr)) != 0)
if ((position = mh->OnMenuDisplayItem(menu, client, display, drawItems[i].position, dr)) == 0)
{
position = display->DrawItem(dr);
}
if (position != 0)
{
slots[position].item = drawItems[i].position;
slots[position].type = ItemSel_Item;
@ -609,7 +612,10 @@ skip_search:
while (i--)
{
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)
{
slots[position].item = drawItems[i].position;

View File

@ -35,7 +35,7 @@ public: //IMenuHandler
void OnMenuCancel(IBaseMenu *menu, int client, MenuCancelReason reason);
void OnMenuEnd(IBaseMenu *menu, MenuEndReason reason);
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
bool IsVoteInProgress();
void InitializeVoting(IBaseMenu *menu);

View File

@ -564,6 +564,7 @@ bool CBaseMenu::AppendItem(const char *info, const ItemDrawInfo &draw)
item.displayString = m_Strings.AddString(draw.display);
}
item.style = draw.style;
item.access = draw.access;
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.style = draw.style;
item.access = draw.access;
CVector<CItem>::iterator iter = m_items.iterAt(position);
m_items.insert(iter, item);

View File

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

View File

@ -45,6 +45,7 @@ enum MenuAction
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_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
@ -80,6 +81,7 @@ public:
unsigned int totalVotes);
void OnMenuVoteCancel(IBaseMenu *menu);
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
void OnMenuDrawItem(IBaseMenu *menu, int client, unsigned int item, unsigned int &style);
void OnMenuDisplayItem(IBaseMenu *menu, int client, unsigned int item, const char **display);
@ -104,11 +106,13 @@ public:
virtual void OnSourceModAllInitialized()
{
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);
}
virtual void OnSourceModShutdown()
{
g_HandleSys.RemoveType(m_TempPanelType, g_pCoreIdent);
g_HandleSys.RemoveType(m_PanelType, g_pCoreIdent);
while (!m_FreePanelHandlers.empty())
@ -126,6 +130,11 @@ public:
virtual void OnHandleDestroy(HandleType_t type, void *object)
{
if (type == m_TempPanelType)
{
return;
}
IMenuPanel *panel = (IMenuPanel *)object;
panel->DeleteThis();
}
@ -155,6 +164,11 @@ public:
return m_PanelType;
}
inline HandleType_t GetTempPanelType()
{
return m_TempPanelType;
}
CPanelHandler *GetPanelHandler(IPluginFunction *pFunction)
{
CPanelHandler *handler;
@ -200,6 +214,7 @@ public:
private:
HandleType_t m_PanelType;
HandleType_t m_TempPanelType;
CStack<CPanelHandler *> m_FreePanelHandlers;
CStack<CMenuHandler *> m_FreeMenuHandlers;
CVector<CPanelHandler *> m_PanelHandlers;
@ -235,6 +250,10 @@ void CPanelHandler::OnMenuSelect(IBaseMenu *menu, int client, unsigned int item)
g_MenuHelpers.FreePanelHandler(this);
}
static IMenuPanel *s_pCurPanel = NULL;
static unsigned int s_CurPanelReturn = 0;
static const ItemDrawInfo *s_CurDrawInfo = NULL;
/**
* 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)
{
HandleSecurity sec;
sec.pIdentity = m_pBasic->GetParentContext()->GetIdentity();
sec.pOwner = g_pCoreIdent;
sec.pIdentity = g_pCoreIdent;
sec.pOwner = m_pBasic->GetParentContext()->GetIdentity();
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);
Handle_t hndl = g_HandleSys.CreateHandleEx(g_MenuHelpers.GetTempPanelType(), panel, &sec, &access, NULL);
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)
{
#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;
}
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)
{
{"AddMenuItem", AddMenuItem},
@ -1028,6 +1100,7 @@ REGISTER_NATIVES(menuNatives)
{"GetPanelStyle", GetPanelStyle},
{"InsertMenuItem", InsertMenuItem},
{"IsVoteInProgress", IsVoteInProgress},
{"RedrawMenuItem", RedrawMenuItem},
{"RemoveAllMenuItems", RemoveAllMenuItems},
{"RemoveMenuItem", RemoveMenuItem},
{"SendPanelToClient", SendPanelToClient},

View File

@ -42,6 +42,10 @@ enum MenuAction
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_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 */
@ -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.
*
* @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.
* @return True on success, false if raw lines are not supported.
* @error Invalid Handle.
@ -545,6 +550,14 @@ native GetPanelCurrentKey(Handle:panel);
*/
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.
*

View File

@ -23,7 +23,7 @@
#include <IHandleSys.h>
#define SMINTERFACE_MENUMANAGER_NAME "IMenuManager"
#define SMINTERFACE_MENUMANAGER_VERSION 6
#define SMINTERFACE_MENUMANAGER_VERSION 7
/**
* @file IMenuManager.h
@ -93,17 +93,14 @@ namespace SourceMod
*/
struct ItemDrawInfo
{
ItemDrawInfo()
{
style = 0;
display = NULL;
}
ItemDrawInfo(const char *DISPLAY, unsigned int STYLE=ITEMDRAW_DEFAULT)
: display(DISPLAY), style(STYLE)
ItemDrawInfo(const char *DISPLAY=NULL, unsigned int STYLE=ITEMDRAW_DEFAULT,
unsigned int FLAGS=0, const char *HELPTEXT=NULL)
: display(DISPLAY), style(STYLE), access(FLAGS)
{
}
const char *display; /**< Display text (NULL for none) */
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 client Client index receiving the menu.
* @param panel Panel being used to draw 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)
{
if (version < 5 || version > GetInterfaceVersion())
if (version < 7 || version > GetInterfaceVersion())
{
return false;
}