From 13ec4bccb534ef55a773004bd3c5a5ac9027600b Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Fri, 6 Sep 2024 15:06:54 -0400 Subject: Add pos to 'UI' listener's 'addMenuItem' and 'addMenuSeparator' 'pos' is a 0-relative index at which to insert the desired menu item or separator. If 'pos' is omitted, the item is appended to the menu. --- indra/newview/lluilistener.cpp | 41 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/indra/newview/lluilistener.cpp b/indra/newview/lluilistener.cpp index c389d04443..44eb8461f1 100644 --- a/indra/newview/lluilistener.cpp +++ b/indra/newview/lluilistener.cpp @@ -90,12 +90,14 @@ LLUIListener::LLUIListener(): add("addMenuItem", "Add new menu item [\"name\"] with displayed [\"label\"]\n" "and call-on-click UI function [\"func\"] with optional [\"param\"]\n" - "to the [\"parent_menu\"] within the Top menu.", + "to the [\"parent_menu\"] within the Top menu.\n" + "If [\"pos\"] is present, insert at specified 0-relative position.", &LLUIListener::addMenuItem, required_args.with("func", LLSD())); add("addMenuSeparator", - "Add menu separator to the [\"parent_menu\"] within the Top menu.", + "Add menu separator to the [\"parent_menu\"] within the Top menu.\n" + "If [\"pos\"] is present, insert at specified 0-relative position.", &LLUIListener::addMenuSeparator, llsd::map("parent_menu", LLSD(), "reply", LLSD())); @@ -264,6 +266,13 @@ LLMenuGL* get_parent_menu(LLEventAPI::Response& response, const LLSD&event) return parent_menu; } +// Return event["pos"].asInteger() if passed, but clamp (0 <= pos <= size). +// Reserve -1 return to mean event has no "pos" key. +S32 get_pos(const LLSD& event, U32 size) +{ + return event["pos"].isInteger()? llclamp(event["pos"].asInteger(), 0, size) : -1; +} + void LLUIListener::addMenu(const LLSD&event) const { Response response(LLSD(), event); @@ -302,9 +311,19 @@ void LLUIListener::addMenuItem(const LLSD&event) const item_params.on_click = item_func; if(LLMenuGL* parent_menu = get_parent_menu(response, event)) { - if(!parent_menu->append(LLUICtrlFactory::create(item_params))) + auto item = LLUICtrlFactory::create(item_params); + // Clamp pos to getItemCount(), meaning append. If pos exceeds that, + // insert() will silently ignore the request. + auto pos = get_pos(event, parent_menu->getItemCount()); + if (pos >= 0) { - response.error(stringize("Menu item ", std::quoted(event["name"].asString()), " was not added")); + // insert() returns void: we just have to assume it worked. + parent_menu->insert(pos, item); + } + else if (! parent_menu->append(item)) + { + response.error(stringize("Menu item ", std::quoted(event["name"].asString()), + " was not added")); } } } @@ -314,7 +333,19 @@ void LLUIListener::addMenuSeparator(const LLSD&event) const Response response(LLSD(), event); if(LLMenuGL* parent_menu = get_parent_menu(response, event)) { - if(!parent_menu->addSeparator()) + // Clamp pos to getItemCount(), meaning append. If pos exceeds that, + // insert() will silently ignore the request. + auto pos = get_pos(event, parent_menu->getItemCount()); + if (pos >= 0) + { + // Even though addSeparator() does not accept a position, + // LLMenuItemSeparatorGL isa LLMenuItemGL, so we can use insert(). + LLMenuItemSeparatorGL::Params p; + LLMenuItemGL* separator = LLUICtrlFactory::create(p); + // insert() returns void: we just have to assume it worked. + parent_menu->insert(pos, separator); + } + else if (! parent_menu->addSeparator()) { response.error("Separator was not added"); } -- cgit v1.2.3