summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/llui/llmenugl.h16
-rw-r--r--indra/newview/llfloaterluadebug.cpp12
-rw-r--r--indra/newview/llfloaterluadebug.h1
-rw-r--r--indra/newview/llinventoryfunctions.cpp13
-rw-r--r--indra/newview/llinventoryfunctions.h16
-rw-r--r--indra/newview/llinventorymodel.cpp11
-rw-r--r--indra/newview/llluamanager.cpp227
-rw-r--r--indra/newview/lluilistener.cpp2
-rw-r--r--indra/newview/skins/default/xui/en/floater_lua_debug.xml19
-rw-r--r--scripts/lua/avatar.lua14
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 &notification, 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