merge master into menu_handler

This commit is contained in:
GT Team 2018-11-03 11:21:48 +01:00
commit d47339cc10
5 changed files with 160 additions and 95 deletions

View File

@ -1143,17 +1143,24 @@ void C_ClientCommand(edict_t *pEntity)
executeForwards(pMenu->pageCallback, static_cast<cell>(pPlayer->index), static_cast<cell>(MENU_BACK));
pMenu->Display(pPlayer->index, pPlayer->page - 1);
} else if (item == MENU_MORE) {
}
else if (item == MENU_MORE)
{
if (pMenu->pageCallback >= 0)
executeForwards(pMenu->pageCallback, static_cast<cell>(pPlayer->index), static_cast<cell>(MENU_MORE));
pMenu->Display(pPlayer->index, pPlayer->page + 1);
} else {
ret = executeForwards(pMenu->func, static_cast<cell>(pPlayer->index), static_cast<cell>(menu), static_cast<cell>(item));
}
else
{
auto pItem = pMenu->GetMenuItem(static_cast<item_t>(item));
ret = executeForwards(pMenu->func, static_cast<cell>(pPlayer->index), static_cast<cell>(menu), static_cast<cell>(item), pItem ? static_cast<cell>(pItem->data) : 0);
if (ret & 2)
{
result = MRES_SUPERCEDE;
} else if (ret & 1) {
}
else if (ret & 1)
{
RETURN_META(MRES_SUPERCEDE);
}
}

View File

@ -11,6 +11,7 @@
#include "CMenu.h"
#include "newmenus.h"
#include "format.h"
#include "CDataPack.h"
ke::Vector<Menu *> g_NewMenus;
CStack<int> g_MenuFreeStack;
@ -120,9 +121,12 @@ isDestroying(false), pageCallback(-1), showPageNumber(true), useMultilingual(use
Menu::~Menu()
{
for (size_t i = 0; i < m_Items.length(); i++)
for (auto &item : m_Items)
{
delete m_Items[i];
if (item->isDataDataPack && item->data > 0)
DataPackHandles.destroy(item->data);
delete item;
}
unregisterSPForward(this->func);
@ -131,7 +135,7 @@ Menu::~Menu()
m_Items.clear();
}
menuitem *Menu::AddItem(const char *name, const char *cmd, int access)
menuitem *Menu::AddItem(const char *name, const char *cmd, int access, int handler = -1)
{
menuitem *pItem = new menuitem;
@ -139,7 +143,7 @@ menuitem *Menu::AddItem(const char *name, const char *cmd, int access)
pItem->cmd = cmd;
pItem->access = access;
pItem->id = m_Items.length();
pItem->handler = -1;
pItem->handler = handler;
pItem->isBlank = false;
pItem->pfn = NULL;
@ -441,22 +445,26 @@ const char *Menu::GetTextString(int player, page_t page, int &keys)
if (pItem->handler != -1)
{
ret = executeForwards(pItem->handler, static_cast<cell>(player), static_cast<cell>(thisId), static_cast<cell>(i));
ret = executeForwards(pItem->handler, static_cast<cell>(player), static_cast<cell>(thisId), static_cast<cell>(i), static_cast<cell>(pItem->data));
if (ret == ITEM_ENABLED)
{
enabled = true;
} else if (ret == ITEM_DISABLED) {
}
else if (ret == ITEM_DISABLED)
{
enabled = false;
}
}
if (pItem->pfn)
{
ret = (pItem->pfn)(player, thisId, i);
ret = (pItem->pfn)(player, thisId, i, pItem->data);
if (ret == ITEM_ENABLED)
{
enabled = true;
} else if (ret == ITEM_DISABLED) {
}
else if (ret == ITEM_DISABLED)
{
enabled = false;
}
}
@ -795,8 +803,6 @@ static cell AMX_NATIVE_CALL menu_addtext2(AMX *amx, cell *params)
static cell AMX_NATIVE_CALL menu_additem(AMX *amx, cell *params)
{
int len;
char *name, *cmd;
int access;
GETMENU(params[1]);
@ -806,14 +812,36 @@ static cell AMX_NATIVE_CALL menu_additem(AMX *amx, cell *params)
return 0;
}
name = get_amxstring(amx, params[2], 0, len);
auto name = get_amxstring(amx, params[2], 0, len);
validate_menu_text(name);
cmd = get_amxstring(amx, params[3], 1, len);
access = params[4];
auto cmd = get_amxstring(amx, params[3], 1, len);
menuitem *pItem = pMenu->AddItem(name, cmd, access);
pMenu->AddItem(name, cmd, params[4], params[5]);
pItem->handler = params[5];
return 1;
}
//Adds an item to the menu
//native menu_additem2(menu, const name[], any:data = 0, access = 0, callback = -1, bool:dp_data = false);
static cell AMX_NATIVE_CALL menu_additem2(AMX *amx, cell *params)
{
int len;
GETMENU(params[1]);
if (!pMenu->items_per_page && pMenu->GetItemCount() >= 10)
{
LogError(amx, AMX_ERR_NATIVE, "Non-paginated menus are limited to 10 items.");
return 0;
}
auto name = get_amxstring(amx, params[2], 0, len);
validate_menu_text(name);
auto pItem = pMenu->AddItem(name, "", params[4], params[5]);
pItem->data = params[3];
pItem->isDataDataPack = params[6] != 0;
return 1;
}
@ -928,9 +956,9 @@ static cell AMX_NATIVE_CALL menu_item_getinfo(AMX *amx, cell *params)
static cell AMX_NATIVE_CALL menu_makecallback(AMX *amx, cell *params)
{
int len;
char *name = get_amxstring(amx, params[1], 0, len);
auto name = get_amxstring(amx, params[1], 0, len);
int id = registerSPForwardByName(amx, name, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
auto id = registerSPForwardByName(amx, name, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
if (id == -1)
{
@ -979,6 +1007,24 @@ static cell AMX_NATIVE_CALL menu_item_setcmd(AMX *amx, cell *params)
return 1;
}
static cell AMX_NATIVE_CALL menu_item_setdata(AMX *amx, cell *params)
{
GETMENU(params[1]);
auto pItem = pMenu->GetMenuItem(static_cast<item_t>(params[2]));
if (!pItem)
return 0;
if (pItem->isDataDataPack && pItem->data > 0)
DataPackHandles.destroy(pItem->data);
pItem->data = params[3];
pItem->isDataDataPack = params[4] != 0;
return 1;
}
static cell AMX_NATIVE_CALL menu_item_setcall(AMX *amx, cell *params)
{
GETMENU(params[1]);
@ -1215,6 +1261,7 @@ AMX_NATIVE_INFO g_NewMenuNatives[] =
{
{"menu_create", menu_create},
{"menu_additem", menu_additem},
{"menu_additem2", menu_additem2},
{"menu_addblank", menu_addblank},
{"menu_addtext", menu_addtext},
{"menu_pages", menu_pages},
@ -1225,6 +1272,7 @@ AMX_NATIVE_INFO g_NewMenuNatives[] =
{"menu_makecallback", menu_makecallback},
{"menu_item_setcall", menu_item_setcall},
{"menu_item_setcmd", menu_item_setcmd},
{"menu_item_setdata", menu_item_setdata},
{"menu_item_setname", menu_item_setname},
{"menu_destroy", menu_destroy},
{"menu_setprop", menu_setprop},

View File

@ -33,7 +33,7 @@
#define MPROP_PAGE_CALLBACK 11
#define MPROP_SHOWPAGE 12
typedef int (*MENUITEM_CALLBACK)(int, int, int);
typedef int (*MENUITEM_CALLBACK)(int, int, int, int);
class BlankItem
{
@ -81,6 +81,8 @@ struct menuitem
int access;
int handler;
bool isBlank;
int data;
bool isDataDataPack;
MENUITEM_CALLBACK pfn;
size_t id;
@ -101,7 +103,7 @@ public:
menuitem *GetMenuItem(item_t item);
size_t GetPageCount();
size_t GetItemCount();
menuitem *AddItem(const char *name, const char *cmd, int access);
menuitem *AddItem(const char *name, const char *cmd, int access, int handler);
const char *GetTextString(int player, page_t page, int &keys);
bool Display(int player, page_t page);

View File

@ -102,13 +102,14 @@
*
* The handler function should be prototyped as:
*
* public <function>(id, menu, item)
* public <function>(id, menu, item, any:data)
* id - Client the menu is being acted upon.
* menu - Menu resource identifier.
* item - Item the client selected. If less than 0, the menu was
* cancelled and the item is a status code. menu_display
* should never be called immediately if the item is a status
* code, for re-entrancy reasons.
* data - Item's data the client selected.
*
* The handler function should always return PLUGIN_HANDLED to block
* any old menu handlers from potentially feeding on the menu, unless
@ -131,10 +132,11 @@ native menu_create(const title[], const handler[], bool:ml = false);
*
* The handler function should be prototyped as:
*
* public <function>(id, menu, item)
* public <function>(id, menu, item, any:data)
* id - Client index being displayed to.
* menu - Menu resource identifier.
* item - Item being drawn.
* data - Item's data.
* <return> - ITEM_IGNORE to use the default functionality. ITEM_ENABLED to
* explicitly enable or ITEM_DISABLED to explicitly disable.
*
@ -157,6 +159,22 @@ native menu_makecallback(const function[]);
*/
native menu_additem(menu, const name[], const info[]="", paccess=0, callback=-1);
/**
* Adds an item to a menu.
*
* @param menu Menu resource identifier.
* @param name Item text to display.
* @param info Item data for internal information.
* @param paccess Access required by the player viewing the menu.
* @param callback If set to a valid ID from menu_makecallback(), the
* callback will be invoked before drawing the item.
* @param dp_data If true, item's data will be treated as DataPack and be destroyed
* along with the menu.
* @noreturn
* @error Invalid menu resource.
*/
native menu_additem2(menu, const name[], any:data = 0, access = 0, callback = -1, bool:dp_data = false);
/**
* Returns the number of pages in a menu.
*
@ -246,6 +264,19 @@ native menu_item_setname(menu, item, const name[]);
*/
native menu_item_setcmd(menu, item, const info[]);
/**
* Sets an item's data.
*
* @param menu Menu resource identifier.
* @param item Item identifier.
* @param data New item data.
* @param dp_data If true, item's data will be treated as DataPack and be destroyed
* along with the menu.
* @return 1 on success, 0 on failure.
* @error Invalid menu resource.
*/
native menu_item_setdata(menu, item, any:data = 0, bool:dp_data = false);
/**
* Sets an item's callback.
*

View File

@ -121,8 +121,8 @@ stock DisplayPluginMenu(id,const MenuText[], const Handler[], const Command[], c
new PluginName[64];
new func=get_func_id(Callback);
new tally;
new PluginCmd[64];
new MenuText[64];
new DataPack:itemData;
for (new i=0, max=get_pluginsnum();
i<max;
i++)
@ -135,17 +135,19 @@ stock DisplayPluginMenu(id,const MenuText[], const Handler[], const Command[], c
get_plugin(i,"",0,PluginName,charsmax(PluginName),"",0,"",0,PluginState,charsmax(PluginState));
// Command syntax is: "# Function", # being plugin ID, function being public function to call.
formatex(PluginCmd,charsmax(PluginCmd),"%d %s",i,Command);
formatex(MenuText,charsmax(MenuText),"%s - %d",PluginName,tally);
// If the plugin is running, add this as an activated menu item.
if (strcmp(PluginState,"running",true)==0 ||
strcmp(PluginState,"debug", true)==0)
{
menu_additem(Menu,MenuText,PluginCmd,EnabledCallback);
itemData = CreateDataPack();
WritePackCell(itemData, i);
WritePackString(itemData, Command);
menu_additem2(Menu, MenuText, itemData, 0, EnabledCallback, true);
}
else
{
menu_additem(Menu,MenuText,"",_,DisabledCallback);
menu_additem2(Menu, MenuText, .callback = DisabledCallback);
}
}
}
@ -319,8 +321,9 @@ public AlwaysEnableCallback(playerid, menuid, itemid)
* @param id The client selecting an item.
* @param menu The menu handle.
* @param item The item number that was selected.
* @param data Item's data.
*/
public PluginMenuSelection(id, menu, item)
public PluginMenuSelection(id, menu, item, any:data)
{
if (item==MENU_EXIT)
{
@ -330,9 +333,8 @@ public PluginMenuSelection(id, menu, item)
{
return PLUGIN_HANDLED;
}
new Command[64];
new Dummy[1];
ResetPack(data);
// All of the commands set for each item is the public
// function that we want to call after the item is selected.
@ -340,22 +342,11 @@ public PluginMenuSelection(id, menu, item)
// Note the menu is destroyed BEFORE the command
// gets executed.
// The command retrieved is in the format: "PLID Command"
menu_item_getinfo(menu, item, Dummy[0], Command, charsmax(Command),Dummy,0,Dummy[0]);
new plid = ReadPackCell(data); //Plugin id
new plid=str_to_num(Command);
new Function[32];
for (new i=0;i<charsmax(Command);i++)
{
if (Command[i]==' ')
{
// we're at the break. move up one space.
i++;
copy(Function,charsmax(Function),Command[i]);
break;
}
}
ReadPackString(data, Function, charsmax(Function)); //Function name
menu_destroy(menu);
@ -458,8 +449,9 @@ public CommandChangeCvar(id)
* @param id The client who chose an item.
* @param menu The menu handle.
* @param item The item that has been selected.
* @param data Item's data.
*/
public CvarMenuSelection(id, menu, item)
public CvarMenuSelection(id, menu, item, any:data)
{
if (item==MENU_EXIT)
@ -484,12 +476,11 @@ public CvarMenuSelection(id, menu, item)
else
{
new CvarName[64];
new Command[32];
new Dummy[1];
// pcvar pointer is stored in command, extract the name of the cvar from the name field.
menu_item_getinfo(menu, item, Dummy[0], Command, charsmax(Command),CvarName,charsmax(CvarName),Dummy[0]);
ResetPack(data);
CurrentCvar[id]=str_to_num(Command);
CurrentCvar[id] = ReadPackCell(data); //cvar ptr
ReadPackString(data, CvarName, charsmax(CvarName)); //cvar name
if (CurrentCvar[id]==0) // This should never happen, but just incase..
{
@ -498,15 +489,6 @@ public CvarMenuSelection(id, menu, item)
}
// TODO: ML this
// Scan up "CvarName" and stop at the first space
for (new i=0;i<charsmax(CvarName);i++)
{
if (CvarName[i]==' ')
{
CvarName[i]='^0';
break;
}
}
copy(CurrentCvarName[id],charsmax(CurrentCvarName[]),CvarName);
client_print(id,print_chat,"[AMXX] Type in the new value for %s, or !cancel to cancel.",CvarName);
client_cmd(id,"messagemode amx_changecvar");
@ -538,6 +520,7 @@ public DisplayCvarMenu(id, plid, page)
new CvarText[64];
new CvarData[32];
new CvarPtr;
new DataPack:itemData;
for (new i=0, max=get_plugins_cvarsnum();
i<max;
@ -553,12 +536,14 @@ public DisplayCvarMenu(id, plid, page)
formatex(CvarText,charsmax(CvarText),"%s - %s",Cvar,CvarData);
// Now store the pcvar data in Cvar
num_to_str(CvarPtr,Cvar,charsmax(Cvar));
menu_additem(Menu,CvarText,Cvar,_,EnabledCallback);
itemData = CreateDataPack();
WritePackCell(itemData, CvarPtr);
WritePackString(itemData, Cvar);
menu_additem2(Menu, CvarText, itemData, _, EnabledCallback, true);
}
else
{
menu_additem(Menu,Cvar,"",_,DisabledCallback);
menu_additem2(Menu, Cvar, .callback = DisabledCallback);
}
}
@ -614,8 +599,9 @@ public CvarMenuCommand(id, level, cid)
* @param id Id of the client.
* @param menu Menu handle.
* @param item Item that was selected.
* @param data Item's data.
*/
public SpecificCommandHandler(id,menu,item)
public SpecificCommandHandler(id, menu, item, any:data)
{
// Exit was called, return to the previous menu.
if (item<0)
@ -631,18 +617,19 @@ public SpecificCommandHandler(id,menu,item)
return PLUGIN_HANDLED;
}
ResetPack(data);
ReadPackString(data, CurrentCommand[id], charsmax(CurrentCommand[]));
if (CurrentCommand[id][0]==0) // This should never happen, but just incase..
{
client_print(id,print_chat,"[AMXX] There was an error extracting the command name.");
return PLUGIN_HANDLED;
}
// TODO: ML this
new Dummy[1];
if (item==0) // "With params"
{
menu_item_getinfo(menu, item, Dummy[0], CurrentCommand[id], charsmax(CurrentCommand[]),"",0,Dummy[0]);
if (CurrentCommand[id][0]==0) // This should never happen, but just incase..
{
client_print(id,print_chat,"[AMXX] There was an error extracting the command name.");
return PLUGIN_HANDLED;
}
// TODO: ML this
client_print(id,print_chat,"[AMXX] Type in the parameters for %s, or !cancel to cancel.",CurrentCommand[id]);
client_cmd(id,"messagemode amx_executecmd");
@ -652,14 +639,6 @@ public SpecificCommandHandler(id,menu,item)
}
else if (item==1) // "No params"
{
menu_item_getinfo(menu, item, Dummy[0], CurrentCommand[id], charsmax(CurrentCommand[]),"",0,Dummy[0]);
if (CurrentCommand[id][0]==0) // This should never happen, but just incase..
{
client_print(id,print_chat,"[AMXX] There was an error extracting the command name.");
return PLUGIN_HANDLED;
}
// TODO: ML this
// Now redraw the menu for the client BEFORE the command is executed, incase
// that menu brings up a menu of its own.
if (CurrentMenuFunction[id]!=-1 && callfunc_begin_i(CurrentMenuFunction[id])==1)
@ -696,6 +675,7 @@ stock DisplaySpecificCommand(id,cid)
new CommandTitle[256];
new CommandAccess;
new Menu;
new DataPack:itemData = CreateDataPack();
get_concmd(cid,CommandName,charsmax(CommandName),CommandAccess, CommandDesc, charsmax(CommandDesc), -1, -1);
@ -708,8 +688,11 @@ stock DisplaySpecificCommand(id,cid)
{
Menu=menu_create(CommandName,"SpecificCommandHandler");
}
menu_additem(Menu,"Execute with parameters.",CommandName,_,EnabledCallback);
menu_additem(Menu,"Execute with no parameters.",CommandName,_,EnabledCallback);
WritePackString(itemData, CommandName);
menu_additem2(Menu, "Execute with parameters.", itemData, _, EnabledCallback, true);
menu_additem2(Menu, "Execute with no parameters.", itemData, _, EnabledCallback, true);
menu_setprop(Menu,MPROP_NUMBER_COLOR,"\y");
menu_display(id,Menu,0);
@ -778,8 +761,9 @@ public CommandExecuteCommand(id)
* @param id id of the client who made the selection.
* @param menu The menu handle.
* @param item The item that was selected.
* @param data Item's data
*/
public CommandMenuSelection(id, menu, item)
public CommandMenuSelection(id, menu, item, any:data)
{
if (item==MENU_EXIT)
{
@ -805,14 +789,9 @@ public CommandMenuSelection(id, menu, item)
}
else
{
new Command[32];
new Dummy[1];
// pcvar pointer is stored in command, extract the name of the cvar from the name field.
menu_item_getinfo(menu, item, Dummy[0], Command, charsmax(Command),"",0,Dummy[0]);
menu_destroy(menu);
DisplaySpecificCommand(id,str_to_num(Command));
DisplaySpecificCommand(id, data);
}
return PLUGIN_HANDLED;
@ -851,7 +830,6 @@ public DisplayCmdMenu(id, plid, page)
new Menu=menu_create(MenuTitle,"CommandMenuSelection");
new Command[64];
new CidString[32];
new CommandAccess;
new userflags=get_user_flags(id);
new bool:isadmin=bool:is_user_admin(id);
@ -872,12 +850,11 @@ public DisplayCmdMenu(id, plid, page)
CommandAccess==ADMIN_USER ||
CommandAccess==ADMIN_ALL)
{
num_to_str(i,CidString,charsmax(CidString));
menu_additem(Menu,Command,CidString,0,EnabledCallback);
menu_additem2(Menu, Command, i, .callback = EnabledCallback);
}
else
{
menu_additem(Menu,Command,"",0,DisabledCallback);
menu_additem2(Menu, Command, .callback = DisabledCallback);
}
}
}