diff options
Diffstat (limited to 'indra/newview')
-rw-r--r-- | indra/newview/lluilistener.cpp | 109 | ||||
-rw-r--r-- | indra/newview/lluilistener.h | 1 |
2 files changed, 110 insertions, 0 deletions
diff --git a/indra/newview/lluilistener.cpp b/indra/newview/lluilistener.cpp index 4d6eac4958..d02d126cb5 100644 --- a/indra/newview/lluilistener.cpp +++ b/indra/newview/lluilistener.cpp @@ -32,11 +32,14 @@ #include "lluilistener.h" // STL headers // std headers +#include <sstream> // external library headers // other Linden headers +#include "llviewerwindow.h" // to get root view #include "lluictrl.h" #include "llerror.h" + LLUIListener::LLUIListener(): LLEventAPI("UI", "LLUICtrl::CommitCallbackRegistry listener.\n" @@ -47,6 +50,12 @@ LLUIListener::LLUIListener(): "as if from a user gesture on a menu -- or a button click.", &LLUIListener::call, LLSD().with("function", LLSD())); + + add("getValue", + "For the UI control identified by the path in [\"path\"], return the control's\n" + "current value as [\"value\"] reply.", + &LLUIListener::getValue, + LLSD().with("path", LLSD())); } void LLUIListener::call(const LLSD& event) const @@ -71,3 +80,103 @@ void LLUIListener::call(const LLSD& event) const (*func)(NULL, event["parameter"]); } } + +// Split string given a single character delimiter. +// Note that this returns empty strings for leading, trailing, and adjacent +// delimiters, such as "/foo/bar//baz/" -> ["", "foo", "bar", "", "baz", "" ] +std::vector<std::string> split(const std::string& s, char delim) +{ + std::stringstream ss(s); + std::string item; + std::vector<std::string> items; + while (std::getline(ss, item, delim)) + { + items.push_back(item); + } + return items; +} + +// Walk the LLView tree to resolve a path +// Paths can be discovered using Develop > XUI > Show XUI Paths +// +// A leading "/" indicates the root of the tree is the starting +// position of the search, (otherwise the context node is used) +// +// Adjacent "//" mean that the next level of the search is done +// recursively ("descendant" rather than "child"). +// +// Return values: If no match is found, NULL is returned, +// otherwise the matching LLView* is returned. +// +// Examples: +// +// "/" -> return the root view +// "/foo" -> find "foo" as a direct child of the root +// "foo" -> find "foo" as a direct child of the context node +// "//foo" -> find the first "foo" child anywhere in the tree +// "/foo/bar" -> find "foo" as direct child of the root, and +// "bar" as a direct child of "foo" +// "//foo//bar/baz" -> find the first "foo" anywhere in the +// tree, the first "bar" anywhere under it, and "baz" +// as a direct child of that +// +const LLView* resolve_path(const LLView* context, const std::string path) +{ + std::vector<std::string> parts = split(path, '/'); + + if (parts.size() == 0) + { + return context; + } + + std::vector<std::string>::iterator it = parts.begin(); + + // leading / means "start at root" + if ((*it).length() == 0) + { + context = (LLView*)(gViewerWindow->getRootView()); + it++; + } + + bool recurse = false; + for (; it != parts.end() && context; it++) + { + std::string part = *it; + + if (part.length() == 0) + { + recurse = true; + } + else + { + const LLView* found = context->findChildView(part, recurse); + if (!found) + return NULL; + + context = found; + recurse = false; + } + } + + return context; +} + +void LLUIListener::getValue(const LLSD&event) const +{ + LLSD reply = LLSD::emptyMap(); + + const LLView* root = (LLView*)(gViewerWindow->getRootView()); + const LLView* view = resolve_path(root, event["path"].asString()); + const LLUICtrl* ctrl(dynamic_cast<const LLUICtrl*>(view)); + + if (ctrl) + { + reply["value"] = ctrl->getValue(); + } + else + { + // *TODO: ??? return something indicating failure to resolve + } + + sendReply(reply, event); +} diff --git a/indra/newview/lluilistener.h b/indra/newview/lluilistener.h index e7847f01e8..08724024dc 100644 --- a/indra/newview/lluilistener.h +++ b/indra/newview/lluilistener.h @@ -41,6 +41,7 @@ public: private: void call(const LLSD& event) const; + void getValue(const LLSD&event) const; }; #endif /* ! defined(LL_LLUILISTENER_H) */ |