diff options
-rw-r--r-- | indra/llui/llmenugl.h | 16 | ||||
-rw-r--r-- | indra/newview/llfloaterluadebug.cpp | 12 | ||||
-rw-r--r-- | indra/newview/llfloaterluadebug.h | 1 | ||||
-rw-r--r-- | indra/newview/llinventoryfunctions.cpp | 13 | ||||
-rw-r--r-- | indra/newview/llinventoryfunctions.h | 16 | ||||
-rw-r--r-- | indra/newview/llinventorymodel.cpp | 11 | ||||
-rw-r--r-- | indra/newview/llluamanager.cpp | 227 | ||||
-rw-r--r-- | indra/newview/lluilistener.cpp | 2 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/floater_lua_debug.xml | 19 | ||||
-rw-r--r-- | scripts/lua/avatar.lua | 14 |
10 files changed, 305 insertions, 26 deletions
diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h index 9d3be8d94f..4f1098b1d8 100644 --- a/indra/llui/llmenugl.h +++ b/indra/llui/llmenugl.h @@ -555,14 +555,15 @@ public: // add a context menu branch BOOL appendContextSubMenu(LLMenuGL *menu); + // Add the menu item to this menu. + virtual BOOL append( LLMenuItemGL* item ); + + // add a menu - this will create a cascading menu + virtual BOOL appendMenu(LLMenuGL *menu); + protected: void createSpilloverBranch(); void cleanupSpilloverBranch(); - // Add the menu item to this menu. - virtual BOOL append( LLMenuItemGL* item ); - - // add a menu - this will create a cascading menu - virtual BOOL appendMenu( LLMenuGL* menu ); // Used in LLContextMenu and in LLTogleableMenu // to add an item of context menu branch @@ -798,9 +799,10 @@ public: void resetMenuTrigger() { mAltKeyTrigger = FALSE; } + // add a menu - this will create a drop down menu. + virtual BOOL appendMenu(LLMenuGL *menu); + private: - // add a menu - this will create a drop down menu. - virtual BOOL appendMenu( LLMenuGL* menu ); // rearrange the child rects so they fit the shape of the menu // bar. virtual void arrange( void ); diff --git a/indra/newview/llfloaterluadebug.cpp b/indra/newview/llfloaterluadebug.cpp index e7d220c503..9ca554d4ad 100644 --- a/indra/newview/llfloaterluadebug.cpp +++ b/indra/newview/llfloaterluadebug.cpp @@ -57,6 +57,7 @@ BOOL LLFloaterLUADebug::postBuild() getChild<LLButton>("execute_btn")->setClickedCallback(boost::bind(&LLFloaterLUADebug::onExecuteClicked, this)); getChild<LLButton>("browse_btn")->setClickedCallback(boost::bind(&LLFloaterLUADebug::onBtnBrowse, this)); + getChild<LLButton>("run_btn")->setClickedCallback(boost::bind(&LLFloaterLUADebug::onBtnRun, this)); #if !LL_WINDOWS getChild<LLButton>("execute_btn")->setEnabled(false); @@ -85,6 +86,17 @@ void LLFloaterLUADebug::onBtnBrowse() (new LLFilePickerReplyThread(boost::bind(&LLFloaterLUADebug::runSelectedScript, this, _1), LLFilePicker::FFLOAD_LUA, false))->getFile(); } +void LLFloaterLUADebug::onBtnRun() +{ + std::vector<std::string> filenames; + std::string filepath = mScriptPath->getText(); + if (!filepath.empty()) + { + filenames.push_back(filepath); + runSelectedScript(filenames); + } +} + void LLFloaterLUADebug::runSelectedScript(const std::vector<std::string> &filenames) { mResultOutput->setValue(""); diff --git a/indra/newview/llfloaterluadebug.h b/indra/newview/llfloaterluadebug.h index a7a3b695d4..300d954aea 100644 --- a/indra/newview/llfloaterluadebug.h +++ b/indra/newview/llfloaterluadebug.h @@ -49,6 +49,7 @@ class LLFloaterLUADebug : void onExecuteClicked(); void onBtnBrowse(); + void onBtnRun(); void runSelectedScript(const std::vector<std::string> &filenames); diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 145814ab41..bf8b49e1e0 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -2155,6 +2155,19 @@ bool LLNameCategoryCollector::operator()( return false; } +bool LLNameItemCollector::operator()( + LLInventoryCategory* cat, LLInventoryItem* item) +{ + if(item) + { + if (!LLStringUtil::compareInsensitive(mName, item->getName())) + { + return true; + } + } + return false; +} + bool LLFindCOFValidItems::operator()(LLInventoryCategory* cat, LLInventoryItem* item) { diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h index 8c8bd789c2..1bfd0f2b93 100644 --- a/indra/newview/llinventoryfunctions.h +++ b/indra/newview/llinventoryfunctions.h @@ -313,6 +313,22 @@ protected: }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Class LLNameItemCollector +// +// Collects items based on case-insensitive match of prefix +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +class LLNameItemCollector : public LLInventoryCollectFunctor +{ +public: + LLNameItemCollector(const std::string& name) : mName(name) {} + virtual ~LLNameItemCollector() {} + virtual bool operator()(LLInventoryCategory* cat, + LLInventoryItem* item); +protected: + std::string mName; +}; + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLFindCOFValidItems // // Collects items that can be legitimately linked to in the COF. diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 9c4e122481..bbac9f4123 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -4421,6 +4421,17 @@ std::string LLInventoryModel::getFullPath(const LLInventoryObject *obj) const return result; } +/* +const LLInventoryObject* LLInventoryModel::findByFullPath(const std::string& path) +{ + vector<std::string> path_elts; + boost::algorithm::split(path_elts, path, boost::is_any_of("/")); + for(path_elts, auto e) + { + } +} +*/ + ///---------------------------------------------------------------------------- /// Local function definitions ///---------------------------------------------------------------------------- diff --git a/indra/newview/llluamanager.cpp b/indra/newview/llluamanager.cpp index c4603e493c..0f984ca0ca 100644 --- a/indra/newview/llluamanager.cpp +++ b/indra/newview/llluamanager.cpp @@ -34,11 +34,14 @@ #include "llfloaterreg.h" #include "llfloaterimnearbychat.h" #include "llfloatersidepanelcontainer.h" +#include "llnotificationsutil.h" #include "llvoavatarself.h" #include "llviewermenu.h" #include "llviewermenufile.h" #include "llviewerwindow.h" #include "lluilistener.h" +#include "llanimationstates.h" +#include "llinventoryfunctions.h" #include <boost/algorithm/string/replace.hpp> @@ -66,6 +69,37 @@ int lua_printWarning(lua_State *L) return 1; } +bool checkLua(lua_State *L, int r, std::string &error_msg) +{ + if (r != LUA_OK) + { + error_msg = lua_tostring(L, -1); + + LL_WARNS() << error_msg << LL_ENDL; + return false; + } + return true; +} + +LLSD luatable_to_llsd_string(lua_State *L, S32 idx) +{ + LLSD args; + + // push first key + lua_pushnil(L); + while (lua_next(L, idx) != 0) + { + // right now -2 is key, -1 is value + lua_rawgeti(L, -1, 1); + lua_rawgeti(L, -2, 2); + std::string key = lua_tostring(L, -2); + std::string value = lua_tostring(L, -1); + args[key] = value; + lua_pop(L, 3); + } + return args; +} + int lua_avatar_sit(lua_State *L) { gAgent.sitDown(); @@ -109,12 +143,38 @@ int lua_open_floater(lua_State *L) return 1; } +int lua_close_floater(lua_State *L) +{ + std::string floater_name(lua_tostring(L, 1)); + + LLSD key; + if (floater_name == "profile") + { + key["id"] = gAgentID; + } + LLFloaterReg::hideInstance(floater_name, key); + + return 1; +} + int lua_close_all_floaters(lua_State *L) { close_all_windows(); return 1; } +int lua_click_child(lua_State *L) +{ + std::string parent_name(lua_tostring(L, 1)); + std::string child_name(lua_tostring(L, 2)); + + LLFloater *floater = LLFloaterReg::findInstance(parent_name); + LLUICtrl *child = floater->getChild<LLUICtrl>(child_name, true); + child->onCommit(); + + return 1; +} + int lua_snapshot_to_file(lua_State *L) { std::string filename(lua_tostring(L, 1)); @@ -150,7 +210,7 @@ int lua_set_debug_setting_bool(lua_State *L) return 1; } - int lua_get_avatar_name(lua_State *L) +int lua_get_avatar_name(lua_State *L) { std::string name = gAgentAvatarp->getFullname(); lua_pushstring(L, name.c_str()); @@ -163,12 +223,156 @@ int lua_is_avatar_flying(lua_State *L) return 1; } +int lua_play_animation(lua_State *L) +{ + std::string anim_name = lua_tostring(L,1); + + EAnimRequest req = ANIM_REQUEST_START; + if (lua_gettop(L) > 1) + { + req = (EAnimRequest) (int) lua_tonumber(L, 2); + } + + LLInventoryModel::cat_array_t cat_array; + LLInventoryModel::item_array_t item_array; + LLNameItemCollector has_name(anim_name); + gInventory.collectDescendentsIf(gInventory.getRootFolderID(), + cat_array, + item_array, + LLInventoryModel::EXCLUDE_TRASH, + has_name); + for (auto& item: item_array) + { + if (item->getType() == LLAssetType::AT_ANIMATION) + { + LLUUID anim_id = item->getAssetUUID(); + LL_INFOS() << "Playing animation " << anim_id << LL_ENDL; + gAgent.sendAnimationRequest(anim_id, req); + return 1; + } + } + LL_WARNS() << "No animation found for name " << anim_name << LL_ENDL; + + return 1; +} + int lua_env_setting_event(lua_State *L) { handle_env_setting_event(lua_tostring(L, 1)); return 1; } +void handle_notification_dialog(const LLSD ¬ification, const LLSD &response, lua_State *L, std::string response_cb) +{ + if (!response_cb.empty()) + { + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + + lua_pushinteger(L, option); + lua_setglobal(L, response_cb.c_str()); + } +} + +int lua_show_notification(lua_State *L) +{ + std::string notification(lua_tostring(L, 1)); + + if (lua_type(L, 2) == LUA_TTABLE) + { + LLSD args = luatable_to_llsd_string(L, 2); + + std::string response_cb; + if (lua_type(L, 3) == LUA_TSTRING) + { + response_cb = lua_tostring(L, 3); + } + + LLNotificationsUtil::add(notification, args, LLSD(), boost::bind(handle_notification_dialog, _1, _2, L, response_cb)); + } + else if (lua_type(L, 2) == LUA_TSTRING) + { + std::string response_cb = lua_tostring(L, 2); + LLNotificationsUtil::add(notification, LLSD(), LLSD(), boost::bind(handle_notification_dialog, _1, _2, L, response_cb)); + } + else + { + LLNotificationsUtil::add(notification); + } + + return 1; +} + +int lua_add_menu_item(lua_State *L) +{ + std::string menu(lua_tostring(L, 1)); + if (lua_type(L, 2) == LUA_TTABLE) + { + LLSD args = luatable_to_llsd_string(L, 2); + + LLMenuItemCallGL::Params item_params; + item_params.name = args["name"]; + item_params.label = args["label"]; + + LLUICtrl::CommitCallbackParam item_func; + item_func.function_name = args["function"]; + if (args.has("parameter")) + { + item_func.parameter = args["parameter"]; + } + item_params.on_click = item_func; + + LLMenuItemCallGL *menu_item = LLUICtrlFactory::create<LLMenuItemCallGL>(item_params); + gMenuBarView->findChildMenuByName(menu, true)->append(menu_item); + } + + return 1; +} + +int lua_add_menu_separator(lua_State *L) +{ + std::string menu(lua_tostring(L, 1)); + gMenuBarView->findChildMenuByName(menu, true)->addSeparator(); + + return 1; +} + +int lua_add_menu(lua_State *L) +{ + if (lua_type(L, 1) == LUA_TTABLE) + { + LLSD args = luatable_to_llsd_string(L, 1); + + LLMenuGL::Params item_params; + item_params.name = args["name"]; + item_params.label = args["label"]; + item_params.can_tear_off = args["tear_off"]; + + LLMenuGL *menu = LLUICtrlFactory::create<LLMenuGL>(item_params); + gMenuBarView->appendMenu(menu); + } + + return 1; +} + +int lua_add_branch(lua_State *L) +{ + std::string menu(lua_tostring(L, 1)); + if (lua_type(L, 2) == LUA_TTABLE) + { + LLSD args = luatable_to_llsd_string(L, 2); + + LLMenuGL::Params item_params; + item_params.name = args["name"]; + item_params.label = args["label"]; + item_params.can_tear_off = args["tear_off"]; + + LLMenuGL *branch = LLUICtrlFactory::create<LLMenuGL>(item_params); + gMenuBarView->findChildMenuByName(menu, true)->appendMenu(branch); + } + + return 1; +} + int lua_run_ui_command(lua_State *L) { int top = lua_gettop(L); @@ -194,18 +398,6 @@ int lua_run_ui_command(lua_State *L) return 1; } -bool checkLua(lua_State *L, int r, std::string &error_msg) -{ - if (r != LUA_OK) - { - error_msg = lua_tostring(L, -1); - - LL_WARNS() << error_msg << LL_ENDL; - return false; - } - return true; -} - void initLUA(lua_State *L) { lua_register(L, "print_warning", lua_printWarning); @@ -216,16 +408,25 @@ void initLUA(lua_State *L) lua_register(L, "nearby_chat_send", lua_nearby_chat_send); lua_register(L, "wear_by_name", lua_wear_by_name); lua_register(L, "open_floater", lua_open_floater); + lua_register(L, "close_floater", lua_close_floater); lua_register(L, "close_all_floaters", lua_close_all_floaters); + lua_register(L, "click_child", lua_click_child); lua_register(L, "open_wearing_tab", lua_open_wearing_tab); lua_register(L, "snapshot_to_file", lua_snapshot_to_file); lua_register(L, "get_avatar_name", lua_get_avatar_name); lua_register(L, "is_avatar_flying", lua_is_avatar_flying); + lua_register(L, "play_animation", lua_play_animation); lua_register(L, "env_setting_event", lua_env_setting_event); lua_register(L, "set_debug_setting_bool", lua_set_debug_setting_bool); + lua_register(L, "show_notification", lua_show_notification); + lua_register(L, "add_menu_separator", lua_add_menu_separator); + lua_register(L, "add_menu_item", lua_add_menu_item); + lua_register(L, "add_menu", lua_add_menu); + lua_register(L, "add_branch", lua_add_branch); + lua_register(L, "run_ui_command", lua_run_ui_command); } diff --git a/indra/newview/lluilistener.cpp b/indra/newview/lluilistener.cpp index 956f5cf187..97a2be6aa3 100644 --- a/indra/newview/lluilistener.cpp +++ b/indra/newview/lluilistener.cpp @@ -67,7 +67,7 @@ void LLUIListener::call(const LLSD& event) const // API: we provide no reply. Therefore, a typo in the script will // provide no feedback whatsoever to that script. To rub the coder's // nose in such an error, crump rather than quietly ignoring it. - LL_ERRS("LLUIListener") << "function '" << event["function"] << "' not found" << LL_ENDL; + LL_WARNS("LLUIListener") << "function '" << event["function"] << "' not found" << LL_ENDL; } else { diff --git a/indra/newview/skins/default/xui/en/floater_lua_debug.xml b/indra/newview/skins/default/xui/en/floater_lua_debug.xml index 7ed6c35151..0de26161e7 100644 --- a/indra/newview/skins/default/xui/en/floater_lua_debug.xml +++ b/indra/newview/skins/default/xui/en/floater_lua_debug.xml @@ -10,7 +10,7 @@ save_rect="true" title="LUA DEBUG" single_instance="true" - width="530"> + width="535"> <text type="string" length="1" @@ -37,7 +37,7 @@ name="lua_cmd" select_on_focus="true" top_delta="30" - width="415" /> + width="435" /> <button follows="left|bottom" height="25" @@ -55,7 +55,7 @@ layout="topleft" name="result_text" follows="left|top" - width="495" + width="515" top_delta="40" word_wrap="true" /> <text @@ -84,7 +84,7 @@ name="script_path" select_on_focus="true" top_delta="-2" - width="315" /> + width="320" /> <button follows="left|bottom" height="25" @@ -94,5 +94,14 @@ left_pad="5" name="browse_btn" top_delta="-2" - width="75" /> + width="70" /> + <button + follows="left|bottom" + height="25" + label="Run" + label_selected="Run" + layout="topleft" + left_pad="5" + name="run_btn" + width="50" /> </floater> diff --git a/scripts/lua/avatar.lua b/scripts/lua/avatar.lua new file mode 100644 index 0000000000..7c419a740c --- /dev/null +++ b/scripts/lua/avatar.lua @@ -0,0 +1,14 @@ +function call_once_func()
+ run_ui_command("World.EnvSettings", "midnight")
+ sleep(1)
+ run_ui_command("World.EnvSettings", "noon")
+ sleep(1)
+ wear_by_name("* AVL")
+ run_ui_command("Avatar.ResetSelfSkeletonAndAnimations")
+ sleep(5)
+ wear_by_name("* Elephant")
+ sleep(5)
+ play_animation("Elephant_Fly");
+ sleep(5)
+ play_animation("Elephant_Fly",1);
+end
\ No newline at end of file |