diff --git a/amxmodx/meta_api.cpp b/amxmodx/meta_api.cpp index 76f2337e..c1247737 100755 --- a/amxmodx/meta_api.cpp +++ b/amxmodx/meta_api.cpp @@ -1113,8 +1113,14 @@ void C_ClientCommand(edict_t *pEntity) int item = pMenu->PagekeyToItem(pPlayer->page, pressed_key+1); if (item == MENU_BACK) { + if (pMenu->pageCallback >= 0) + executeForwards(pMenu->pageCallback, static_cast(pPlayer->index), static_cast(MENU_BACK)); + pMenu->Display(pPlayer->index, pPlayer->page - 1); } else if (item == MENU_MORE) { + if (pMenu->pageCallback >= 0) + executeForwards(pMenu->pageCallback, static_cast(pPlayer->index), static_cast(MENU_MORE)); + pMenu->Display(pPlayer->index, pPlayer->page + 1); } else { ret = executeForwards(pMenu->func, static_cast(pPlayer->index), static_cast(menu), static_cast(item)); diff --git a/amxmodx/newmenus.cpp b/amxmodx/newmenus.cpp index 61400f3b..9b16b235 100755 --- a/amxmodx/newmenus.cpp +++ b/amxmodx/newmenus.cpp @@ -92,7 +92,7 @@ bool CloseNewMenus(CPlayer *pPlayer) Menu::Menu(const char *title, AMX *amx, int fid) : m_Title(title), m_ItemColor("\\r"), m_NeverExit(false), m_AutoColors(g_coloredmenus), thisId(0), func(fid), -isDestroying(false), items_per_page(7) +isDestroying(false), pageCallback(-1), items_per_page(7) { CPluginMngr::CPlugin *pPlugin = g_plugins.findPluginFast(amx); menuId = g_menucmds.registerMenuId(title, amx); @@ -125,6 +125,7 @@ Menu::~Menu() } unregisterSPForward(this->func); + unregisterSPForward(this->pageCallback); m_Items.clear(); } @@ -954,6 +955,28 @@ static cell AMX_NATIVE_CALL menu_setprop(AMX *amx, cell *params) switch (params[2]) { + case MPROP_PAGE_CALLBACK: + { + const char *str = get_amxstring_null(amx, params[3], 0, len); + if (str == nullptr) + { + unregisterSPForward(pMenu->pageCallback); + pMenu->pageCallback = -1; + break; + } + + int callback = registerSPForwardByName(amx, str, FP_CELL, FP_CELL, FP_DONE); + if (callback < 0) + { + LogError(amx, AMX_ERR_NATIVE, "Function %s not present", str); + return 0; + } + + unregisterSPForward(pMenu->pageCallback); + pMenu->pageCallback = callback; + + break; + } case MPROP_SET_NUMBER_COLOR: { char *str = get_amxstring(amx, params[3], 0, len); diff --git a/amxmodx/newmenus.h b/amxmodx/newmenus.h index 1991c7ff..936188c3 100755 --- a/amxmodx/newmenus.h +++ b/amxmodx/newmenus.h @@ -30,6 +30,7 @@ #define MPROP_NOCOLORS 8 #define MPROP_PADMENU 9 #define MPROP_SET_NUMBER_COLOR 10 +#define MPROP_PAGE_CALLBACK 11 typedef int (*MENUITEM_CALLBACK)(int, int, int); @@ -123,6 +124,7 @@ public: int thisId; int func; bool isDestroying; + int pageCallback; public: unsigned int items_per_page; }; diff --git a/plugins/include/newmenus.inc b/plugins/include/newmenus.inc index 88af28f4..5d42cb19 100644 --- a/plugins/include/newmenus.inc +++ b/plugins/include/newmenus.inc @@ -27,6 +27,9 @@ #define MPROP_EXIT 6 /* Exit functionality (param1 = number, see MEXIT constants) */ #define MPROP_NOCOLORS 8 /* Sets whether colors are not auto (param1 = number, 0=default) */ #define MPROP_NUMBER_COLOR 10 /* Color indicator to use for numbers (param1 = string, "\r"=default) */ +#define MPROP_PAGE_CALLBACK 11 /* Function to be called on Back and Next (param1 = string) */ + /* public function(id, status); where status is either MENU_BACK or MENU_MORE */ + /* Pass NULL_STRING to disable the callback */ #define MEXIT_NORMAL 0 /* DEPRECATED, do not use (has no effect) */ #define MENUPAD_NONE 0 /* DEPRECATED, do not use (has no effect) */ diff --git a/plugins/testsuite/menu_page_callback_test.sma b/plugins/testsuite/menu_page_callback_test.sma new file mode 100644 index 00000000..fa116b70 --- /dev/null +++ b/plugins/testsuite/menu_page_callback_test.sma @@ -0,0 +1,76 @@ +#include + +new g_menuHandle; +new bool:g_isCallbackSet = false; + +public plugin_init() +{ + register_plugin("Menu Pagination Callback Test", "1.0.0", "KliPPy"); + + register_clcmd("say testmenu", "@Command_TestMenu"); + register_clcmd("say togglecallback", "@Command_ToggleCallback"); + + g_menuHandle = menu_create("Test menu", "@MenuHandler_TestMenu"); + menu_additem(g_menuHandle, "Item 1"); + menu_additem(g_menuHandle, "Item 2"); + menu_additem(g_menuHandle, "Item 3"); + menu_additem(g_menuHandle, "Item 4"); + menu_additem(g_menuHandle, "Item 5"); + menu_additem(g_menuHandle, "Item 6"); + menu_additem(g_menuHandle, "Item 7"); + menu_additem(g_menuHandle, "item 8"); + + menu_setprop(g_menuHandle, MPROP_PERPAGE, 2); +} + +public plugin_end() +{ + menu_destroy(g_menuHandle); +} + +@MenuHandler_TestMenu(id, menu, item) +{ + if(item == MENU_EXIT) + return PLUGIN_HANDLED; + + new dump1, dump2[1], dump3; + new itemName[32]; + menu_item_getinfo(menu, item, dump1, dump2, 0, itemName, charsmax(itemName), dump3); + + client_print(id, print_chat, "Selected: %s", itemName); + + return PLUGIN_HANDLED; +} + +@PageCallback_TestMenu(id, status) +{ + if(status == MENU_BACK) + client_print(id, print_chat, "Selected: MENU_BACK"); + else + client_print(id, print_chat, "Selected: MENU_MORE"); +} + +@Command_TestMenu(id) +{ + menu_display(id, g_menuHandle); + + return PLUGIN_HANDLED; +} + +@Command_ToggleCallback(id) +{ + if(g_isCallbackSet) + { + menu_setprop(g_menuHandle, MPROP_PAGE_CALLBACK, NULL_STRING); + g_isCallbackSet = false; + + client_print(id, print_chat, "Callback set to OFF"); + } + else + { + menu_setprop(g_menuHandle, MPROP_PAGE_CALLBACK, "@PageCallback_TestMenu"); + g_isCallbackSet = true; + + client_print(id, print_chat, "Callback set to ON"); + } +} \ No newline at end of file diff --git a/support/PackageScript b/support/PackageScript index 6f4ae94c..e6986d4e 100644 --- a/support/PackageScript +++ b/support/PackageScript @@ -268,6 +268,7 @@ scripting_files = [ 'testsuite/textparse_test.cfg', 'testsuite/textparse_test.ini', 'testsuite/request_frame_test.sma', + 'testsuite/menu_page_callback_test.sma', 'include/amxconst.inc', 'include/amxmisc.inc', 'include/amxmodx.inc',