Add DisplayTopMenuCategory native (bug 6033, r=dvander).

This commit is contained in:
Peace-Maker 2014-05-09 12:32:49 -07:00
parent 530078b3ae
commit e9b4a6e96c
4 changed files with 121 additions and 18 deletions

View File

@ -186,28 +186,14 @@ unsigned int TopMenu::AddToMenu2(const char *name,
topmenu_category_t *parent_cat = NULL; topmenu_category_t *parent_cat = NULL;
if (type == TopMenuObject_Item) if (type == TopMenuObject_Item)
{ {
/* Check parent index. Note it will be >= 1 here. */ size_t category_id;
if (parent > m_Objects.size() || m_Objects[parent - 1]->is_free) if (!FindCategoryByObject(parent, &category_id))
{ {
return 0; return 0;
} }
parent_obj = m_Objects[parent - 1]; parent_obj = m_Objects[parent - 1];
parent_cat = m_Categories[category_id];
/* Find an equivalent pointer in the category array. */
for (size_t i = 0; i < m_Categories.size(); i++)
{
if (m_Categories[i]->obj == parent_obj)
{
parent_cat = m_Categories[i];
break;
}
}
/* If none was found, leave. */
if (parent_cat == NULL)
{
return 0;
}
} }
/* Re-use an old object pointer if we can. */ /* Re-use an old object pointer if we can. */
@ -454,6 +440,82 @@ bool TopMenu::DisplayMenu(int client, unsigned int hold_time, TopMenuPosition po
return return_value; return return_value;
} }
bool TopMenu::DisplayMenuAtCategory(int client, unsigned int object_id)
{
if (m_clients == NULL)
{
return false;
}
IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(client);
if (!pPlayer->IsInGame())
{
return false;
}
// Get the category this object is in.
size_t category_id;
if (!FindCategoryByObject(object_id, &category_id))
{
return false;
}
topmenu_category_t *category = m_Categories[category_id];
UpdateClientRoot(client, pPlayer);
topmenu_player_t *pClient = &m_clients[client];
if (pClient->root == NULL)
{
return false;
}
if (!m_bCacheTitles)
{
char renderbuf[128];
m_pTitle->OnTopMenuDisplayTitle(this, client, 0, renderbuf, sizeof(renderbuf));
pClient->root->SetDefaultTitle(renderbuf);
}
bool return_value = false;
return_value = DisplayCategory(client, category_id, 0, true);
if (!return_value)
{
return_value = pClient->root->DisplayAtItem(client, 0, pClient->last_root_pos);
}
return return_value;
}
bool TopMenu::FindCategoryByObject(unsigned int obj_id, size_t *index)
{
if (obj_id == 0
|| obj_id > m_Objects.size()
|| m_Objects[obj_id - 1]->is_free)
{
return false;
}
topmenu_object_t *obj = m_Objects[obj_id - 1];
if (obj->type != TopMenuObject_Category)
{
return false;
}
/* Find an equivalent pointer in the category array. */
for (size_t i = 0; i < m_Categories.size(); i++)
{
if (m_Categories[i]->obj == obj)
{
*index = i;
return true;
}
}
return false;
}
bool TopMenu::DisplayCategory(int client, unsigned int category, unsigned int hold_time, bool last_position) bool TopMenu::DisplayCategory(int client, unsigned int category, unsigned int hold_time, bool last_position)
{ {
UpdateClientCategory(client, category); UpdateClientCategory(client, category);

View File

@ -155,6 +155,7 @@ public: //ITextListener_SMC
public: public:
unsigned int CalcMemUsage(); unsigned int CalcMemUsage();
void SetTitleCaching(bool cache_titles); void SetTitleCaching(bool cache_titles);
bool DisplayMenuAtCategory(int client, unsigned int object_id);
private: private:
void SortCategoriesIfNeeded(); void SortCategoriesIfNeeded();
void SortCategoryIfNeeded(unsigned int category); void SortCategoryIfNeeded(unsigned int category);
@ -164,6 +165,7 @@ private:
void UpdateClientRoot(int client, IGamePlayer *pGamePlayer=NULL); void UpdateClientRoot(int client, IGamePlayer *pGamePlayer=NULL);
void UpdateClientCategory(int client, unsigned int category, bool bSkipRootCheck=false); void UpdateClientCategory(int client, unsigned int category, bool bSkipRootCheck=false);
void TearDownClient(topmenu_player_t *player); void TearDownClient(topmenu_player_t *player);
bool FindCategoryByObject(unsigned int obj_id, size_t *index);
private: private:
void OnClientConnected(int client); void OnClientConnected(int client);
void OnClientDisconnected(int client); void OnClientDisconnected(int client);

View File

@ -326,6 +326,32 @@ static cell_t DisplayTopMenu(IPluginContext *pContext, const cell_t *params)
return pMenu->DisplayMenu(client, 0, (TopMenuPosition)params[3]); return pMenu->DisplayMenu(client, 0, (TopMenuPosition)params[3]);
} }
static cell_t DisplayTopMenuCategory(IPluginContext *pContext, const cell_t *params)
{
HandleError err;
TopMenu *pMenu;
HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity());
if ((err = handlesys->ReadHandle(params[1], hTopMenuType, &sec, (void **)&pMenu))
!= HandleError_None)
{
return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
}
int client = params[3];
IGamePlayer *player = playerhelpers->GetGamePlayer(client);
if (!player)
{
return pContext->ThrowNativeError("Invalid client index %d", client);
}
else if (!player->IsInGame())
{
return pContext->ThrowNativeError("Client %d is not in game", client);
}
return pMenu->DisplayMenuAtCategory(client, params[2]);
}
static cell_t GetTopMenuInfoString(IPluginContext *pContext, const cell_t *params) static cell_t GetTopMenuInfoString(IPluginContext *pContext, const cell_t *params)
{ {
HandleError err; HandleError err;
@ -396,6 +422,7 @@ sp_nativeinfo_t g_TopMenuNatives[] =
{"AddToTopMenu", AddToTopMenu}, {"AddToTopMenu", AddToTopMenu},
{"CreateTopMenu", CreateTopMenu}, {"CreateTopMenu", CreateTopMenu},
{"DisplayTopMenu", DisplayTopMenu}, {"DisplayTopMenu", DisplayTopMenu},
{"DisplayTopMenuCategory", DisplayTopMenuCategory},
{"LoadTopMenuConfig", LoadTopMenuConfig}, {"LoadTopMenuConfig", LoadTopMenuConfig},
{"RemoveFromTopMenu", RemoveFromTopMenu}, {"RemoveFromTopMenu", RemoveFromTopMenu},
{"FindTopMenuCategory", FindTopMenuCategory}, {"FindTopMenuCategory", FindTopMenuCategory},

View File

@ -247,6 +247,17 @@ native RemoveFromTopMenu(Handle:topmenu, TopMenuObject:object);
*/ */
native bool:DisplayTopMenu(Handle:topmenu, client, TopMenuPosition:position); native bool:DisplayTopMenu(Handle:topmenu, client, TopMenuPosition:position);
/**
* Displays a TopMenu category to a client.
*
* @param topmenu TopMenu Handle.
* @param category Category object id.
* @param client Client index.
* @return True on success, false on failure.
* @error Invalid TopMenu Handle or client not in game.
*/
native bool:DisplayTopMenuCategory(Handle:topmenu, TopMenuObject:category, client);
/** /**
* Finds a category's object ID in a TopMenu. * Finds a category's object ID in a TopMenu.
* *
@ -296,6 +307,7 @@ public __ext_topmenus_SetNTVOptional()
MarkNativeAsOptional("AddToTopMenu"); MarkNativeAsOptional("AddToTopMenu");
MarkNativeAsOptional("RemoveFromTopMenu"); MarkNativeAsOptional("RemoveFromTopMenu");
MarkNativeAsOptional("DisplayTopMenu"); MarkNativeAsOptional("DisplayTopMenu");
MarkNativeAsOptional("DisplayTopMenuCategory");
MarkNativeAsOptional("FindTopMenuCategory"); MarkNativeAsOptional("FindTopMenuCategory");
MarkNativeAsOptional("SetTopMenuTitleCaching"); MarkNativeAsOptional("SetTopMenuTitleCaching");
} }