Automated merge with file:///home/nat/linden/viewer-headless

master
Nat Goodspeed 2011-02-23 20:50:10 -05:00
commit 30a772c5f1
4 changed files with 105 additions and 0 deletions

View File

@ -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

View File

@ -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);

View File

@ -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);
}

View File

@ -41,6 +41,7 @@ public:
private:
void call(const LLSD& event) const;
void getValue(const LLSD&event) const;
};
#endif /* ! defined(LL_LLUILISTENER_H) */