1.1 --- a/extensions/topmenus/TopMenu.cpp Mon Oct 22 06:23:58 2007 +0000
1.2 +++ b/extensions/topmenus/TopMenu.cpp Mon Oct 22 06:56:17 2007 +0000
1.3 @@ -125,6 +125,18 @@
1.4 FlagBits flags,
1.5 unsigned int parent)
1.6 {
1.7 + return AddToMenu2(name, type, callbacks, owner, cmdname, flags, parent, NULL);
1.8 +}
1.9 +
1.10 +unsigned int TopMenu::AddToMenu2(const char *name,
1.11 + TopMenuObjectType type,
1.12 + ITopMenuObjectCallbacks *callbacks,
1.13 + IdentityToken_t *owner,
1.14 + const char *cmdname,
1.15 + FlagBits flags,
1.16 + unsigned int parent,
1.17 + const char *info_string)
1.18 +{
1.19 /* Sanity checks */
1.20 if (type == TopMenuObject_Category && parent != 0)
1.21 {
1.22 @@ -202,6 +214,7 @@
1.23 obj->parent = parent_obj;
1.24 strncopy(obj->name, name, sizeof(obj->name));
1.25 strncopy(obj->cmdname, cmdname ? cmdname : "", sizeof(obj->cmdname));
1.26 + strncopy(obj->info, info_string ? info_string : "", sizeof(obj->info));
1.27
1.28 if (obj->type == TopMenuObject_Category)
1.29 {
1.30 @@ -239,6 +252,20 @@
1.31 return obj->object_id;
1.32 }
1.33
1.34 +const char *TopMenu::GetObjectInfoString(unsigned int object_id)
1.35 +{
1.36 + if (object_id == 0
1.37 + || object_id > m_Objects.size()
1.38 + || m_Objects[object_id - 1]->is_free)
1.39 + {
1.40 + return NULL;
1.41 + }
1.42 +
1.43 + topmenu_object_t *obj = m_Objects[object_id - 1];
1.44 +
1.45 + return obj->info;
1.46 +}
1.47 +
1.48 void TopMenu::RemoveFromMenu(unsigned int object_id)
1.49 {
1.50 if (object_id == 0
1.51 @@ -320,11 +347,11 @@
1.52 }
1.53 }
1.54
1.55 + /* The callbacks pointer is still valid, so fire away! */
1.56 + obj->callbacks->OnTopMenuObjectRemoved(this, object_id);
1.57 +
1.58 /* Finally, mark the object as free. */
1.59 obj->is_free = true;
1.60 -
1.61 - /* The callbacks pointer is still valid, so fire away! */
1.62 - obj->callbacks->OnTopMenuObjectRemoved(this, object_id);
1.63 }
1.64
1.65 bool TopMenu::DisplayMenu(int client, unsigned int hold_time, TopMenuPosition position)
2.1 --- a/extensions/topmenus/TopMenu.h Mon Oct 22 06:23:58 2007 +0000
2.2 +++ b/extensions/topmenus/TopMenu.h Mon Oct 22 06:56:17 2007 +0000
2.3 @@ -68,6 +68,7 @@
2.4 topmenu_object_t *parent; /** Parent, if any */
2.5 TopMenuObjectType type; /** Object Type */
2.6 bool is_free; /** Free or not? */
2.7 + char info[255]; /** Info string */
2.8 };
2.9
2.10 struct topmenu_category_t
2.11 @@ -115,12 +116,21 @@
2.12 const char *cmdname,
2.13 FlagBits flags,
2.14 unsigned int parent);
2.15 + unsigned int AddToMenu2(const char *name,
2.16 + TopMenuObjectType type,
2.17 + ITopMenuObjectCallbacks *callbacks,
2.18 + IdentityToken_t *owner,
2.19 + const char *cmdname,
2.20 + FlagBits flags,
2.21 + unsigned int parent,
2.22 + const char *info_string);
2.23 virtual void RemoveFromMenu(unsigned int object_id);
2.24 virtual bool DisplayMenu(int client,
2.25 unsigned int hold_time,
2.26 TopMenuPosition position);
2.27 virtual bool LoadConfiguration(const char *file, char *error, size_t maxlength);
2.28 virtual unsigned int FindCategory(const char *name);
2.29 + const char *GetObjectInfoString(unsigned int object_id);
2.30 public: //IMenuHandler
2.31 virtual void OnMenuSelect2(IBaseMenu *menu, int client, unsigned int item, unsigned int item_on_page);
2.32 virtual void OnMenuDrawItem(IBaseMenu *menu, int client, unsigned int item, unsigned int &style);
2.33 @@ -166,4 +176,6 @@
2.34 bool m_bCatsNeedResort; /* True if categories need a resort */
2.35 };
2.36
2.37 +unsigned int strncopy(char *dest, const char *src, size_t count);
2.38 +
2.39 #endif //_INCLUDE_SOURCEMOD_TOP_MENU_H_
3.1 --- a/extensions/topmenus/smn_topmenus.cpp Mon Oct 22 06:23:58 2007 +0000
3.2 +++ b/extensions/topmenus/smn_topmenus.cpp Mon Oct 22 06:56:17 2007 +0000
3.3 @@ -67,6 +67,7 @@
3.4 TopMenuAction_DisplayTitle = 1,
3.5 TopMenuAction_SelectOption = 2,
3.6 TopMenuAction_DrawOption = 3,
3.7 + TopMenuAction_RemoveObject = 4,
3.8 };
3.9
3.10 class TopMenuCallbacks : public ITopMenuObjectCallbacks
3.11 @@ -138,6 +139,14 @@
3.12
3.13 void OnTopMenuObjectRemoved(ITopMenu *menu, unsigned int object_id)
3.14 {
3.15 + m_pFunction->PushCell(m_hMenuHandle);
3.16 + m_pFunction->PushCell(TopMenuAction_RemoveObject);
3.17 + m_pFunction->PushCell(object_id);
3.18 + m_pFunction->PushCell(0);
3.19 + m_pFunction->PushString("");
3.20 + m_pFunction->PushCell(0);
3.21 + m_pFunction->Execute(NULL);
3.22 +
3.23 delete this;
3.24 }
3.25
3.26 @@ -221,20 +230,26 @@
3.27
3.28 TopMenuCallbacks *cb = new TopMenuCallbacks(func);
3.29
3.30 - char *name, *cmdname;
3.31 + char *name, *cmdname, *info_string;
3.32 pContext->LocalToString(params[2], &name);
3.33 pContext->LocalToString(params[6], &cmdname);
3.34
3.35 + if (params[0] >= 8)
3.36 + {
3.37 + pContext->LocalToString(params[8], &info_string);
3.38 + }
3.39 +
3.40 TopMenuObjectType obj_type = (TopMenuObjectType)params[3];
3.41
3.42 unsigned int object_id;
3.43 - if ((object_id = pMenu->AddToMenu(name,
3.44 + if ((object_id = pMenu->AddToMenu2(name,
3.45 obj_type,
3.46 cb,
3.47 pContext->GetIdentity(),
3.48 cmdname,
3.49 params[7],
3.50 - params[5])) == 0)
3.51 + params[5],
3.52 + info_string)) == 0)
3.53 {
3.54 delete cb;
3.55 return 0;
3.56 @@ -306,13 +321,38 @@
3.57 return pMenu->DisplayMenu(client, 0, (TopMenuPosition)params[3]);
3.58 }
3.59
3.60 +static cell_t GetTopMenuInfoString(IPluginContext *pContext, const cell_t *params)
3.61 +{
3.62 + HandleError err;
3.63 + ITopMenu *pMenu;
3.64 + HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity());
3.65 +
3.66 + if ((err = handlesys->ReadHandle(params[1], hTopMenuType, &sec, (void **)&pMenu))
3.67 + != HandleError_None)
3.68 + {
3.69 + return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
3.70 + }
3.71 +
3.72 + const char *str;
3.73 + if ((str = pMenu->GetObjectInfoString(params[2])) == NULL)
3.74 + {
3.75 + return pContext->ThrowNativeError("Invalid menu object %d", params[2]);
3.76 + }
3.77 +
3.78 + char *buffer;
3.79 + pContext->LocalToString(params[3], &buffer);
3.80 +
3.81 + return strncopy(buffer, str, params[4]);
3.82 +}
3.83 +
3.84 sp_nativeinfo_t g_TopMenuNatives[] =
3.85 {
3.86 - {"AddToTopMenu", AddToTopMenu},
3.87 - {"CreateTopMenu", CreateTopMenu},
3.88 - {"DisplayTopMenu", DisplayTopMenu},
3.89 - {"LoadTopMenuConfig", LoadTopMenuConfig},
3.90 - {"RemoveFromTopMenu", RemoveFromTopMenu},
3.91 - {"FindTopMenuCategory", FindTopMenuCategory},
3.92 + {"AddToTopMenu", AddToTopMenu},
3.93 + {"CreateTopMenu", CreateTopMenu},
3.94 + {"DisplayTopMenu", DisplayTopMenu},
3.95 + {"LoadTopMenuConfig", LoadTopMenuConfig},
3.96 + {"RemoveFromTopMenu", RemoveFromTopMenu},
3.97 + {"FindTopMenuCategory", FindTopMenuCategory},
3.98 + {"GetTopMenuInfoString", GetTopMenuInfoString},
3.99 {NULL, NULL},
3.100 };
4.1 --- a/plugins/include/topmenus.inc Mon Oct 22 06:23:58 2007 +0000
4.2 +++ b/plugins/include/topmenus.inc Mon Oct 22 06:56:17 2007 +0000
4.3 @@ -79,6 +79,14 @@
4.4 * ITEMDRAW_DEFAULT.
4.5 */
4.6 TopMenuAction_DrawOption = 3,
4.7 +
4.8 + /**
4.9 + * Called when an object is being removed from the menu.
4.10 + * This can be used to clean up data stored in the info string.
4.11 + *
4.12 + * INPUT : TopMenu Handle, object ID.
4.13 + */
4.14 + TopMenuAction_RemoveObject = 4,
4.15 };
4.16
4.17 /**
4.18 @@ -175,6 +183,7 @@
4.19 * @param parent Parent object ID, or INVALID_TOPMENUOBJECT for none.
4.20 * Items must have a category parent.
4.21 * Categories must not have a parent.
4.22 + * @param info_string Arbitrary storage (max 255 bytes).
4.23 * @return A new TopMenuObject ID, or INVALID_TOPMENUOBJECT on
4.24 * failure.
4.25 * @error Invalid TopMenu Handle.
4.26 @@ -185,7 +194,21 @@
4.27 TopMenuHandler:handler,
4.28 TopMenuObject:parent,
4.29 const String:cmdname[]="",
4.30 - flags=0);
4.31 + flags=0,
4.32 + const String:info_string[]="");
4.33 +
4.34 +/**
4.35 + * Retrieves the info string of a top menu item.
4.36 + *
4.37 + * @param topmenu TopMenu Handle.
4.38 + * @param object TopMenuObject ID.
4.39 + * @param buffer Buffer to store info string.
4.40 + * @param maxlength Maximum size of info string.
4.41 + * @return Number of bytes written, not including the
4.42 + * null terminator.
4.43 + * @error Invalid TopMenu Handle or TopMenuObject ID.
4.44 + */
4.45 +native GetTopMenuInfoString(Handle:topmenu, TopMenuObject:parent, String:buffer[], maxlength);
4.46
4.47 /**
4.48 * Removes an object from a TopMenu.
5.1 --- a/public/extensions/ITopMenus.h Mon Oct 22 06:23:58 2007 +0000
5.2 +++ b/public/extensions/ITopMenus.h Mon Oct 22 06:56:17 2007 +0000
5.3 @@ -43,7 +43,7 @@
5.4 */
5.5
5.6 #define SMINTERFACE_TOPMENUS_NAME "ITopMenus"
5.7 -#define SMINTERFACE_TOPMENUS_VERSION 2
5.8 +#define SMINTERFACE_TOPMENUS_VERSION 3
5.9
5.10 namespace SourceMod
5.11 {
5.12 @@ -233,6 +233,41 @@
5.13 * @return Object ID of the category, or 0 if none.
5.14 */
5.15 virtual unsigned int FindCategory(const char *name) =0;
5.16 +
5.17 + /**
5.18 + * @brief Creates and adds an object type type to the top menu.
5.19 + *
5.20 + * @param name Unique, string name to give the object.
5.21 + * @param type Object type.
5.22 + * @param callbacks ITopMenuObjectCallbacks pointer.
5.23 + * @param owner IdentityToken_t owner of the object.
5.24 + * @param cmdname Command name used for override access checks.
5.25 + * If NULL or empty, access will not be Checked.
5.26 + * @param flags Default flag(s) to use for access checks.
5.27 + * @param parent Parent object, or 0 if none.
5.28 + * Currently, categories cannot have a parent,
5.29 + * and items must have a category parent.
5.30 + * @param info_string Optional info string to attach to the object.
5.31 + * Only 255 bytes of the string (including null
5.32 + * terminator) will be stored.
5.33 + * @return An object ID, or 0 on failure.
5.34 + */
5.35 + virtual unsigned int AddToMenu2(const char *name,
5.36 + TopMenuObjectType type,
5.37 + ITopMenuObjectCallbacks *callbacks,
5.38 + IdentityToken_t *owner,
5.39 + const char *cmdname,
5.40 + FlagBits flags,
5.41 + unsigned int parent,
5.42 + const char *info_string) =0;
5.43 +
5.44 + /**
5.45 + * @brief Returns an object's info string.
5.46 + *
5.47 + * @param object_id Object ID.
5.48 + * @return Object's info string, or NULL if none.
5.49 + */
5.50 + virtual const char *GetObjectInfoString(unsigned int object_id) =0;
5.51 };
5.52
5.53 /**