Automated merge with file:///home/nat/linden/viewer-headless
commit
30a772c5f1
|
|
@ -61,6 +61,8 @@
|
|||
// for XUIParse
|
||||
#include "llquaternion.h"
|
||||
#include <boost/tokenizer.hpp>
|
||||
#include <boost/algorithm/string/find_iterator.hpp>
|
||||
#include <boost/algorithm/string/finder.hpp>
|
||||
|
||||
//
|
||||
// Globals
|
||||
|
|
@ -2020,6 +2022,53 @@ void LLUI::positionViewNearMouse(LLView* view, S32 spawn_x, S32 spawn_y)
|
|||
view->translateIntoRectWithExclusion( virtual_window_rect, mouse_rect, FALSE );
|
||||
}
|
||||
|
||||
LLView* LLUI::resolvePath(LLView* context, const std::string& path)
|
||||
{
|
||||
// Nothing about resolvePath() should require non-const LLView*. If caller
|
||||
// wants non-const, call the const flavor and then cast away const-ness.
|
||||
return const_cast<LLView*>(resolvePath(const_cast<const LLView*>(context), path));
|
||||
}
|
||||
|
||||
const LLView* LLUI::resolvePath(const LLView* context, const std::string& path)
|
||||
{
|
||||
// Create an iterator over slash-separated parts of 'path'. Dereferencing
|
||||
// this iterator returns an iterator_range over the substring. Unlike
|
||||
// LLStringUtil::getTokens(), this split_iterator doesn't combine adjacent
|
||||
// delimiters: leading/trailing slash produces an empty substring, double
|
||||
// slash produces an empty substring. That's what we need.
|
||||
boost::split_iterator<std::string::const_iterator> ti(path, boost::first_finder("/")), tend;
|
||||
|
||||
if (ti == tend)
|
||||
{
|
||||
// 'path' is completely empty, no navigation
|
||||
return context;
|
||||
}
|
||||
|
||||
// leading / means "start at root"
|
||||
if (ti->empty())
|
||||
{
|
||||
context = getRootView();
|
||||
++ti;
|
||||
}
|
||||
|
||||
bool recurse = false;
|
||||
for (; ti != tend && context; ++ti)
|
||||
{
|
||||
if (ti->empty())
|
||||
{
|
||||
recurse = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string part(ti->begin(), ti->end());
|
||||
context = context->findChildView(part, recurse);
|
||||
recurse = false;
|
||||
}
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
|
||||
// LLLocalClipRect and LLScreenClipRect moved to lllocalcliprect.h/cpp
|
||||
|
||||
|
|
|
|||
|
|
@ -185,6 +185,33 @@ public:
|
|||
//helper functions (should probably move free standing rendering helper functions here)
|
||||
static LLView* getRootView() { return sRootView; }
|
||||
static void setRootView(LLView* view) { sRootView = view; }
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
static const LLView* resolvePath(const LLView* context, const std::string& path);
|
||||
static LLView* resolvePath(LLView* context, const std::string& path);
|
||||
static std::string locateSkin(const std::string& filename);
|
||||
static void setMousePositionScreen(S32 x, S32 y);
|
||||
static void getMousePositionScreen(S32 *x, S32 *y);
|
||||
|
|
|
|||
|
|
@ -34,9 +34,11 @@
|
|||
// std headers
|
||||
// external library headers
|
||||
// other Linden headers
|
||||
#include "llui.h" // getRootView(), resolvePath()
|
||||
#include "lluictrl.h"
|
||||
#include "llerror.h"
|
||||
|
||||
|
||||
LLUIListener::LLUIListener():
|
||||
LLEventAPI("UI",
|
||||
"LLUICtrl::CommitCallbackRegistry listener.\n"
|
||||
|
|
@ -47,6 +49,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,
|
||||
LLSDMap("path", LLSD())("reply", LLSD()));
|
||||
}
|
||||
|
||||
void LLUIListener::call(const LLSD& event) const
|
||||
|
|
@ -71,3 +79,23 @@ void LLUIListener::call(const LLSD& event) const
|
|||
(*func)(NULL, event["parameter"]);
|
||||
}
|
||||
}
|
||||
|
||||
void LLUIListener::getValue(const LLSD&event) const
|
||||
{
|
||||
LLSD reply = LLSD::emptyMap();
|
||||
|
||||
const LLView* root = LLUI::getRootView();
|
||||
const LLView* view = LLUI::resolvePath(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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ public:
|
|||
|
||||
private:
|
||||
void call(const LLSD& event) const;
|
||||
void getValue(const LLSD&event) const;
|
||||
};
|
||||
|
||||
#endif /* ! defined(LL_LLUILISTENER_H) */
|
||||
|
|
|
|||
Loading…
Reference in New Issue