diff options
| -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) */ | 
