diff options
Diffstat (limited to 'indra/llui')
| -rw-r--r-- | indra/llui/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | indra/llui/llbutton.cpp | 8 | ||||
| -rw-r--r-- | indra/llui/llchat.h | 6 | ||||
| -rw-r--r-- | indra/llui/llfloater.cpp | 27 | ||||
| -rw-r--r-- | indra/llui/llfloater.h | 6 | ||||
| -rw-r--r-- | indra/llui/llfloaterreg.cpp | 8 | ||||
| -rw-r--r-- | indra/llui/llfloaterreg.h | 1 | ||||
| -rw-r--r-- | indra/llui/lllineeditor.h | 3 | ||||
| -rw-r--r-- | indra/llui/llmenugl.cpp | 4 | ||||
| -rw-r--r-- | indra/llui/llnotifications.cpp | 1 | ||||
| -rw-r--r-- | indra/llui/llnotifications.h | 1 | ||||
| -rw-r--r-- | indra/llui/llsearcheditor.cpp | 22 | ||||
| -rw-r--r-- | indra/llui/llsearcheditor.h | 20 | ||||
| -rw-r--r-- | indra/llui/lltabcontainer.cpp | 3 | ||||
| -rw-r--r-- | indra/llui/lltoolbar.cpp | 4 | ||||
| -rw-r--r-- | indra/llui/lluictrl.cpp | 22 | ||||
| -rw-r--r-- | indra/llui/lluictrl.h | 4 | ||||
| -rw-r--r-- | indra/llui/lluiusage.cpp | 146 | ||||
| -rw-r--r-- | indra/llui/lluiusage.h | 57 | ||||
| -rw-r--r-- | indra/llui/llvirtualtrackball.cpp | 40 | ||||
| -rw-r--r-- | indra/llui/llvirtualtrackball.h | 3 | 
21 files changed, 377 insertions, 11 deletions
| diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt index 7401e6130a..d96824bbf8 100644 --- a/indra/llui/CMakeLists.txt +++ b/indra/llui/CMakeLists.txt @@ -122,6 +122,7 @@ set(llui_SOURCE_FILES      lluictrl.cpp      lluictrlfactory.cpp      lluistring.cpp +    lluiusage.cpp      llundo.cpp      llurlaction.cpp      llurlentry.cpp @@ -241,6 +242,7 @@ set(llui_HEADER_FILES      llui.h      lluicolor.h      lluistring.h +    lluiusage.h      llundo.h      llurlaction.h      llurlentry.h diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp index 9682c3bc10..0e59fdf519 100644 --- a/indra/llui/llbutton.cpp +++ b/indra/llui/llbutton.cpp @@ -47,6 +47,7 @@  #include "llnotificationsutil.h"  #include "llrender.h"  #include "lluictrlfactory.h" +#include "lluiusage.h"  #include "llhelp.h"  #include "lldockablefloater.h"  #include "llviewereventrecorder.h" @@ -437,6 +438,13 @@ BOOL LLButton::handleMouseDown(S32 x, S32 y, MASK mask)  			setFocus(TRUE);  		} +		if (!mFunctionName.empty()) +		{ +			LL_DEBUGS("UIUsage") << "calling mouse down function " << mFunctionName << LL_ENDL; +			LLUIUsage::instance().logCommand(mFunctionName); +			LLUIUsage::instance().logControl(getPathname()); +		} +  		/*  		 * ATTENTION! This call fires another mouse down callback.  		 * If you wish to remove this call emit that signal directly diff --git a/indra/llui/llchat.h b/indra/llui/llchat.h index f5b242fdfc..c39e44200c 100644 --- a/indra/llui/llchat.h +++ b/indra/llui/llchat.h @@ -37,7 +37,8 @@ typedef enum e_chat_source_type  	CHAT_SOURCE_SYSTEM = 0,  	CHAT_SOURCE_AGENT = 1,  	CHAT_SOURCE_OBJECT = 2, -	CHAT_SOURCE_UNKNOWN = 3 +	CHAT_SOURCE_TELEPORT = 3, +	CHAT_SOURCE_UNKNOWN = 4  } EChatSourceType;  typedef enum e_chat_type @@ -64,7 +65,8 @@ typedef enum e_chat_style  {  	CHAT_STYLE_NORMAL,  	CHAT_STYLE_IRC, -	CHAT_STYLE_HISTORY +	CHAT_STYLE_HISTORY, +	CHAT_STYLE_TELEPORT_SEP  }EChatStyle;  // A piece of chat diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index e9c980ad9a..8ceb411ede 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -58,6 +58,7 @@  #include "llhelp.h"  #include "llmultifloater.h"  #include "llsdutil.h" +#include "lluiusage.h"  #include <boost/foreach.hpp> @@ -198,7 +199,9 @@ LLFloater::Params::Params()  	help_pressed_image("help_pressed_image"),  	open_callback("open_callback"),  	close_callback("close_callback"), -	follows("follows") +	follows("follows"), +	rel_x("rel_x", 0), +	rel_y("rel_y", 0)  {  	changeDefault(visible, false);  } @@ -267,6 +270,8 @@ LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p)  	mHasBeenDraggedWhileMinimized(FALSE),  	mPreviousMinimizedBottom(0),  	mPreviousMinimizedLeft(0), +	mDefaultRelativeX(p.rel_x), +	mDefaultRelativeY(p.rel_y),  	mMinimizeSignal(NULL)  //	mNotificationContext(NULL)  { @@ -505,7 +510,12 @@ void LLFloater::destroy()  // virtual  LLFloater::~LLFloater()  { -	LLFloaterReg::removeInstance(mInstanceName, mKey); +    if (!isDead()) +    { +        // If it's dead, instance is supposed to be already removed, and +        // in case of single instance we can remove new one by accident +        LLFloaterReg::removeInstance(mInstanceName, mKey); +    }  	if( gFocusMgr.childHasKeyboardFocus(this))  	{ @@ -934,6 +944,15 @@ bool LLFloater::applyRectControl()  			saved_rect = true;  		} +		else if ((mDefaultRelativeX != 0) && (mDefaultRelativeY != 0)) +		{ +			mPosition.mX = mDefaultRelativeX; +			mPosition.mY = mDefaultRelativeY; +			mPositioning = LLFloaterEnums::POSITIONING_RELATIVE; +			applyRelativePosition(); + +			saved_rect = true; +		}  		// remember updated position  		if (rect_specified) @@ -1631,6 +1650,7 @@ void LLFloater::bringToFront( S32 x, S32 y )  // virtual  void LLFloater::setVisibleAndFrontmost(BOOL take_focus,const LLSD& key)  { +	LLUIUsage::instance().logFloater(getInstanceName());  	LLMultiFloater* hostp = getHost();  	if (hostp)  	{ @@ -3198,6 +3218,9 @@ void LLFloater::initFromParams(const LLFloater::Params& p)  	mSingleInstance = p.single_instance;  	mReuseInstance = p.reuse_instance.isProvided() ? p.reuse_instance : p.single_instance; +	mDefaultRelativeX = p.rel_x; +	mDefaultRelativeY = p.rel_y; +  	mPositioning = p.positioning;  	mSaveRect = p.save_rect; diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h index f8c04e8a2f..2672d600c6 100644 --- a/indra/llui/llfloater.h +++ b/indra/llui/llfloater.h @@ -172,6 +172,9 @@ public:  		Optional<S32>			header_height,  								legacy_header_height; // HACK see initFromXML() +		Optional<F32>			rel_x, +								rel_y; +  		// Images for top-right controls  		Optional<LLUIImage*>	close_image,  								restore_image, @@ -521,6 +524,9 @@ private:  	BOOL			mHasBeenDraggedWhileMinimized;  	S32				mPreviousMinimizedBottom;  	S32				mPreviousMinimizedLeft; + +	F32				mDefaultRelativeX; +	F32				mDefaultRelativeY;  }; diff --git a/indra/llui/llfloaterreg.cpp b/indra/llui/llfloaterreg.cpp index 85e07fc6a6..36a0cb0fd0 100644 --- a/indra/llui/llfloaterreg.cpp +++ b/indra/llui/llfloaterreg.cpp @@ -32,6 +32,7 @@  #include "llfloater.h"  #include "llmultifloater.h"  #include "llfloaterreglistener.h" +#include "lluiusage.h"  //******************************************************* @@ -57,6 +58,12 @@ void LLFloaterReg::add(const std::string& name, const std::string& filename, con  }  //static +bool LLFloaterReg::isRegistered(const std::string& name) +{ +    return sBuildMap.find(name) != sBuildMap.end(); +} + +//static  LLFloater* LLFloaterReg::getLastFloaterInGroup(const std::string& name)  {  	const std::string& groupname = sGroupMap[name]; @@ -472,7 +479,6 @@ void LLFloaterReg::toggleInstanceOrBringToFront(const LLSD& sdname, const LLSD&  	std::string name = sdname.asString();  	LLFloater* instance = getInstance(name, key);  -  	if (!instance)  	{  		LL_DEBUGS() << "Unable to get instance of floater '" << name << "'" << LL_ENDL; diff --git a/indra/llui/llfloaterreg.h b/indra/llui/llfloaterreg.h index e3b17dcb4f..a457a15673 100644 --- a/indra/llui/llfloaterreg.h +++ b/indra/llui/llfloaterreg.h @@ -85,6 +85,7 @@ public:  	static void add(const std::string& name, const std::string& file, const LLFloaterBuildFunc& func,  					const std::string& groupname = LLStringUtil::null); +	static bool isRegistered(const std::string& name);  	// Helpers  	static LLFloater* getLastFloaterInGroup(const std::string& name); diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h index aa5779d45f..f84625bea7 100644 --- a/indra/llui/lllineeditor.h +++ b/indra/llui/lllineeditor.h @@ -283,6 +283,9 @@ public:  	void			resetContextMenu() { setContextMenu(NULL); }; +	void			setBgImage(LLPointer<LLUIImage> image) { mBgImage = image; } +	void			setBgImageFocused(LLPointer<LLUIImage> image) { mBgImageFocused = image; } +  private:  	// private helper methods diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index 37dbe9b40e..cdaf03ebde 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -79,7 +79,7 @@ const U32 LEFT_PAD_PIXELS = 3;  const U32 LEFT_WIDTH_PIXELS = 15;  const U32 LEFT_PLAIN_PIXELS = LEFT_PAD_PIXELS + LEFT_WIDTH_PIXELS; -const U32 RIGHT_PAD_PIXELS = 2; +const U32 RIGHT_PAD_PIXELS = 7;  const U32 RIGHT_WIDTH_PIXELS = 15;  const U32 RIGHT_PLAIN_PIXELS = RIGHT_PAD_PIXELS + RIGHT_WIDTH_PIXELS; @@ -95,7 +95,7 @@ const std::string SEPARATOR_NAME("separator");  const std::string VERTICAL_SEPARATOR_LABEL( "|" );  const std::string LLMenuGL::BOOLEAN_TRUE_PREFIX( "\xE2\x9C\x94" ); // U+2714 HEAVY CHECK MARK -const std::string LLMenuGL::BRANCH_SUFFIX( "\xE2\x96\xB6" ); // U+25B6 BLACK RIGHT-POINTING TRIANGLE +const std::string LLMenuGL::BRANCH_SUFFIX( "\xe2\x96\xb8" ); // U+25B6 BLACK RIGHT-POINTING TRIANGLE  const std::string LLMenuGL::ARROW_UP  ("^^^^^^^");  const std::string LLMenuGL::ARROW_DOWN("vvvvvvv"); diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index 06ec648178..b791a19c2b 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -77,6 +77,7 @@ LLNotificationForm::FormButton::FormButton()  	text("text"),  	ignore("ignore"),  	is_default("default"), +	width("width", 0),  	type("type")  {  	// set type here so it gets serialized diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h index 2f4578da17..b0b56cf599 100644 --- a/indra/llui/llnotifications.h +++ b/indra/llui/llnotifications.h @@ -191,6 +191,7 @@ public:  		Mandatory<std::string>	text;  		Optional<std::string>	ignore;  		Optional<bool>			is_default; +		Optional<S32>			width;  		Mandatory<std::string>	type; diff --git a/indra/llui/llsearcheditor.cpp b/indra/llui/llsearcheditor.cpp index 1fdd05a11c..bafeef41fb 100644 --- a/indra/llui/llsearcheditor.cpp +++ b/indra/llui/llsearcheditor.cpp @@ -34,7 +34,11 @@  LLSearchEditor::LLSearchEditor(const LLSearchEditor::Params& p)  :	LLUICtrl(p),  	mSearchButton(NULL), -	mClearButton(NULL) +	mClearButton(NULL), +	mEditorImage(p.background_image), +	mEditorImageFocused(p.background_image_focused), +	mEditorSearchImage(p.background_image_highlight), +	mHighlightTextField(p.highlight_text_field)  {  	S32 srch_btn_top = p.search_button.top_pad + p.search_button.rect.height;  	S32 srch_btn_right = p.search_button.rect.width + p.search_button.left_pad; @@ -57,6 +61,8 @@ LLSearchEditor::LLSearchEditor(const LLSearchEditor::Params& p)  	// Set up line editor.  	LLLineEditor::Params line_editor_params(p);  	line_editor_params.name("filter edit box"); +	line_editor_params.background_image(p.background_image); +	line_editor_params.background_image_focused(p.background_image_focused);  	line_editor_params.rect(getLocalRect());  	line_editor_params.follows.flags(FOLLOWS_ALL);  	line_editor_params.text_pad_left(text_pad_left); @@ -104,6 +110,20 @@ void LLSearchEditor::draw()  	if (mClearButton)  		mClearButton->setVisible(!mSearchEditor->getWText().empty()); +	if (mHighlightTextField) +	{	 +		if (!mSearchEditor->getWText().empty()) +		{ +			mSearchEditor->setBgImage(mEditorSearchImage); +			mSearchEditor->setBgImageFocused(mEditorSearchImage); +		} +		else +		{ +			mSearchEditor->setBgImage(mEditorImage); +			mSearchEditor->setBgImageFocused(mEditorImageFocused); +		} +	} +  	LLUICtrl::draw();  } diff --git a/indra/llui/llsearcheditor.h b/indra/llui/llsearcheditor.h index 3b12868225..c0f3c1d60c 100644 --- a/indra/llui/llsearcheditor.h +++ b/indra/llui/llsearcheditor.h @@ -47,14 +47,23 @@ public:  		Optional<LLButton::Params>	search_button,   									clear_button;  		Optional<bool>				search_button_visible,  -									clear_button_visible; +									clear_button_visible, +									highlight_text_field;  		Optional<commit_callback_t> keystroke_callback; +		Optional<LLUIImage*>		background_image, +									background_image_focused, +									background_image_highlight; +  		Params()  		:	search_button("search_button"),  			search_button_visible("search_button_visible"),  			clear_button("clear_button"),  -			clear_button_visible("clear_button_visible") +			clear_button_visible("clear_button_visible"), +			highlight_text_field("highlight_text_field"), +			background_image("background_image"), +			background_image_focused("background_image_focused"), +			background_image_highlight("background_image_highlight")  		{}  	}; @@ -93,6 +102,13 @@ protected:  	LLLineEditor* mSearchEditor;  	LLButton* mSearchButton;  	LLButton* mClearButton; + +	LLPointer<LLUIImage> mEditorImage; +	LLPointer<LLUIImage> mEditorImageFocused; +	LLPointer<LLUIImage> mEditorSearchImage; +	LLPointer<LLUIImage> mEditorSearchImageFocused; + +	bool mHighlightTextField;  };  #endif  // LL_SEARCHEDITOR_H diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp index e6b43da8e5..459fdcf2ae 100644 --- a/indra/llui/lltabcontainer.cpp +++ b/indra/llui/lltabcontainer.cpp @@ -38,6 +38,7 @@  #include "llrender.h"  #include "llfloater.h"  #include "lltrans.h" +#include "lluiusage.h"  //---------------------------------------------------------------------------- @@ -1556,6 +1557,8 @@ BOOL LLTabContainer::setTab(S32 which)  			if (is_selected)  			{ +				LLUIUsage::instance().logPanel(tuple->mTabPanel->getName()); +  				// Make sure selected tab is within scroll region  				if (mIsVertical)  				{ diff --git a/indra/llui/lltoolbar.cpp b/indra/llui/lltoolbar.cpp index e6f466ec78..4868c66d1b 100644 --- a/indra/llui/lltoolbar.cpp +++ b/indra/llui/lltoolbar.cpp @@ -967,6 +967,8 @@ LLToolBarButton* LLToolBar::createButton(const LLCommandId& id)  			executeStopParam.function_name = executeStopFunction;  			executeStopParam.parameter = commandp->executeStopParameters();  			LLUICtrl::commit_callback_t execute_func = initCommitCallback(executeParam); +			button->setFunctionName(commandp->executeFunctionName()); +			LL_DEBUGS("UIUsage") << "button function name a -> " << commandp->executeFunctionName() << LL_ENDL;  			LLUICtrl::commit_callback_t stop_func = initCommitCallback(executeStopParam);  			button->setMouseDownCallback(boost::bind(&LLToolBarButton::callIfEnabled, button, execute_func, _1, _2)); @@ -974,6 +976,8 @@ LLToolBarButton* LLToolBar::createButton(const LLCommandId& id)  		}  		else  		{ +			button->setFunctionName(commandp->executeFunctionName()); +			LL_DEBUGS("UIUsage") << "button function name b -> " << commandp->executeFunctionName() << LL_ENDL;  			button->setCommitCallback(executeParam);  		} diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp index 544a76e8d5..5924542a19 100644 --- a/indra/llui/lluictrl.cpp +++ b/indra/llui/lluictrl.cpp @@ -35,6 +35,7 @@  #include "lluictrlfactory.h"  #include "lltabcontainer.h"  #include "llaccordionctrltab.h" +#include "lluiusage.h"  static LLDefaultChildRegistry::Register<LLUICtrl> r("ui_ctrl"); @@ -282,6 +283,7 @@ LLUICtrl::commit_signal_t::slot_type LLUICtrl::initCommitCallback(const CommitCa  	else  	{  		std::string function_name = cb.function_name; +		setFunctionName(function_name);  		commit_callback_t* func = (CommitCallbackRegistry::getValue(function_name));  		if (func)  		{ @@ -422,7 +424,19 @@ BOOL LLUICtrl::canFocusChildren() const  void LLUICtrl::onCommit()  {  	if (mCommitSignal) -	(*mCommitSignal)(this, getValue()); +	{ +		if (!mFunctionName.empty()) +		{ +			LL_DEBUGS("UIUsage") << "calling commit function " << mFunctionName << LL_ENDL; +			LLUIUsage::instance().logCommand(mFunctionName); +			LLUIUsage::instance().logControl(getPathname()); +		} +		else +		{ +			//LL_DEBUGS("UIUsage") << "calling commit function " << "UNKNOWN" << LL_ENDL; +		} +		(*mCommitSignal)(this, getValue()); +	}  }  //virtual @@ -597,6 +611,12 @@ void LLUICtrl::setMakeInvisibleControlVariable(LLControlVariable* control)  		setVisible(!(mMakeInvisibleControlVariable->getValue().asBoolean()));  	}  } + +void LLUICtrl::setFunctionName(const std::string& function_name) +{ +	mFunctionName = function_name; +} +  // static  bool LLUICtrl::controlListener(const LLSD& newvalue, LLHandle<LLUICtrl> handle, std::string type)  { diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h index 7360bd7659..67dd24341c 100644 --- a/indra/llui/lluictrl.h +++ b/indra/llui/lluictrl.h @@ -183,6 +183,8 @@ public:  	void setMakeVisibleControlVariable(LLControlVariable* control);  	void setMakeInvisibleControlVariable(LLControlVariable* control); +	void setFunctionName(const std::string& function_name); +	  	virtual void	setTentative(BOOL b);  	virtual BOOL	getTentative() const;  	virtual void	setValue(const LLSD& value); @@ -310,6 +312,8 @@ protected:  	LLControlVariable* mMakeInvisibleControlVariable;  	boost::signals2::connection mMakeInvisibleControlConnection; +	std::string mFunctionName; +  	static F32 sActiveControlTransparency;  	static F32 sInactiveControlTransparency; diff --git a/indra/llui/lluiusage.cpp b/indra/llui/lluiusage.cpp new file mode 100644 index 0000000000..ccae6643b9 --- /dev/null +++ b/indra/llui/lluiusage.cpp @@ -0,0 +1,146 @@ +/** +* @file lluiuisage.cpp +* @brief Source file for LLUIUsage +* +* $LicenseInfo:firstyear=2021&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2021, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA +* $/LicenseInfo$ +*/ + +#include "linden_common.h" +#include "lluiusage.h" +#include <boost/algorithm/string.hpp> + +LLUIUsage::LLUIUsage() +{ +} + +LLUIUsage::~LLUIUsage() +{ +} + +// static +std::string LLUIUsage::sanitized(const std::string& s) +{ +	// Remove characters that make the ViewerStats db unhappy +	std::string result(s); +	std::replace(result.begin(), result.end(), '.', '_'); +	std::replace(result.begin(), result.end(), ' ', '_'); +	return result; +} + +// static +void LLUIUsage::setLLSDPath(LLSD& sd, const std::string& path, S32 max_elts, const LLSD& val) +{ +	// Keep the last max_elts components of the specified path +	std::vector<std::string> fields; +	boost::split(fields, path, boost::is_any_of("/")); +	auto first_pos = std::max(fields.begin(), fields.end() - max_elts); +	auto end_pos = fields.end(); +	std::vector<std::string> last_fields(first_pos,end_pos); + +	setLLSDNested(sd, last_fields, val); +} + +// setLLSDNested() +// Accomplish the equivalent of  +//   sd[fields[0]][fields[1]]... = val; +// for an arbitrary number of fields. +// This might be useful as an LLSD utility function; is not specific to LLUIUsage +//  +// static +void LLUIUsage::setLLSDNested(LLSD& sd, const std::vector<std::string>& fields, const LLSD& val) +{ +	LLSD* fsd = &sd; +	for (auto it=fields.begin(); it!=fields.end(); ++it) +	{ +		if (it == fields.end()-1) +		{ +			(*fsd)[*it] = val; +		} +		else +		{ +			if (!(*fsd)[*it].isMap()) +			{ +				(*fsd)[*it] = LLSD::emptyMap(); +			} +			fsd = &(*fsd)[*it]; +		} +	} +} + +void LLUIUsage::logCommand(const std::string& command) +{ +	mCommandCounts[sanitized(command)]++; +	LL_DEBUGS("UIUsage") << "command " << command << LL_ENDL; +} + +void LLUIUsage::logControl(const std::string& control) +{ +	mControlCounts[sanitized(control)]++; +	LL_DEBUGS("UIUsage") << "control " << control << LL_ENDL; +} + + +void LLUIUsage::logFloater(const std::string& floater) +{ +	mFloaterCounts[sanitized(floater)]++; +	LL_DEBUGS("UIUsage") << "floater " << floater << LL_ENDL; +} + +void LLUIUsage::logPanel(const std::string& p) +{ +	mPanelCounts[sanitized(p)]++; +	LL_DEBUGS("UIUsage") << "panel " << p << LL_ENDL; +} + +LLSD LLUIUsage::asLLSD() const +{ +	LLSD result; +	for (auto const& it : mCommandCounts) +	{ +		result["commands"][it.first] = LLSD::Integer(it.second); +	} +	for (auto const& it : mControlCounts) +	{ +		setLLSDPath(result["controls"], it.first, 2, LLSD::Integer(it.second)); +	} +	for (auto const& it : mFloaterCounts) +	{ +		result["floaters"][it.first] = LLSD::Integer(it.second); +	} +	for (auto const& it : mPanelCounts) +	{ +		result["panels"][it.first] = LLSD::Integer(it.second); +	} +	return result; +} + +// Clear up some junk content generated during initial login/UI initialization +void LLUIUsage::clear() +{ + +	LL_DEBUGS("UIUsage") << "clear" << LL_ENDL; +	mCommandCounts.clear(); +	mControlCounts.clear(); +	mFloaterCounts.clear(); +	mPanelCounts.clear(); +} + diff --git a/indra/llui/lluiusage.h b/indra/llui/lluiusage.h new file mode 100644 index 0000000000..a30cd80db3 --- /dev/null +++ b/indra/llui/lluiusage.h @@ -0,0 +1,57 @@ +/** +* @file lluiuisage.h +* @brief Header file for LLUIUsage +* +* $LicenseInfo:firstyear=2021&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2021, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA +* $/LicenseInfo$ +*/ + +#ifndef LL_LLUIUSAGE_H +#define LL_LLUIUSAGE_H + +#include <map> +#include "llsd.h" +#include "llsingleton.h" + +// UIUsage tracking to see which operations and UI elements are most popular in a session +class LLUIUsage : public LLSingleton<LLUIUsage> +{ +public: +	LLSINGLETON(LLUIUsage); +	~LLUIUsage(); +public: +	static std::string sanitized(const std::string& s); +	static void setLLSDPath(LLSD& sd, const std::string& path, S32 max_elts, const LLSD& val); +	static void setLLSDNested(LLSD& sd, const std::vector<std::string>& fields, const LLSD& val); +	void logCommand(const std::string& command); +	void logControl(const std::string& control); +	void logFloater(const std::string& floater); +	void logPanel(const std::string& p); +	LLSD asLLSD() const; +	void clear(); +private: +	std::map<std::string,U32> mCommandCounts; +	std::map<std::string,U32> mControlCounts; +	std::map<std::string,U32> mFloaterCounts; +	std::map<std::string,U32> mPanelCounts; +}; + +#endif // LLUIUIUSAGE.h diff --git a/indra/llui/llvirtualtrackball.cpp b/indra/llui/llvirtualtrackball.cpp index 723643dd25..6e0aef740d 100644 --- a/indra/llui/llvirtualtrackball.cpp +++ b/indra/llui/llvirtualtrackball.cpp @@ -348,6 +348,42 @@ LLQuaternion LLVirtualTrackball::getRotation() const  	return mValue;  } +// static +void LLVirtualTrackball::getAzimuthAndElevation(const LLQuaternion &quat, F32 &azimuth, F32 &elevation) +{ +    // LLQuaternion has own function to get azimuth, but it doesn't appear to return correct values (meant for 2d?) +    LLVector3 point = VectorZero * quat; + +    if (!is_approx_zero(point.mV[VX]) || !is_approx_zero(point.mV[VY])) +    { +        azimuth = atan2f(point.mV[VX], point.mV[VY]); +    } +    else +    { +        azimuth = 0; +    } + +    azimuth -= F_PI_BY_TWO; + +    if (azimuth < 0) +    { +        azimuth += F_PI * 2; +    } + +    // while vector is '1', F32 is not sufficiently precise and we can get +    // values like 1.0000012 which will result in -90deg angle instead of 90deg +    F32 z = llclamp(point.mV[VZ], -1.f, 1.f); +    elevation = asin(z); // because VectorZero's length is '1' +} + +// static +void LLVirtualTrackball::getAzimuthAndElevationDeg(const LLQuaternion &quat, F32 &azimuth, F32 &elevation) +{ +    getAzimuthAndElevation(quat, azimuth, elevation); +    azimuth *= RAD_TO_DEG; +    elevation *= RAD_TO_DEG; +} +  BOOL LLVirtualTrackball::handleHover(S32 x, S32 y, MASK mask)  {      if (hasMouseCapture()) @@ -409,6 +445,10 @@ BOOL LLVirtualTrackball::handleHover(S32 x, S32 y, MASK mask)              mValue *= az_quat;          } +        // we are doing a lot of F32 mathematical operations with loss of precision, +        // re-normalize to compensate +        mValue.normalize(); +          mPrevX = x;          mPrevY = y;          onCommit(); diff --git a/indra/llui/llvirtualtrackball.h b/indra/llui/llvirtualtrackball.h index 2d4b1ece17..c7a893877b 100644 --- a/indra/llui/llvirtualtrackball.h +++ b/indra/llui/llvirtualtrackball.h @@ -96,6 +96,9 @@ public:      void            setRotation(const LLQuaternion &value);      LLQuaternion    getRotation() const; +    static void             getAzimuthAndElevation(const LLQuaternion &quat, F32 &azimuth, F32 &elevation); +    static void             getAzimuthAndElevationDeg(const LLQuaternion &quat, F32 &azimuth, F32 &elevation); +  protected:      friend class LLUICtrlFactory;      LLVirtualTrackball(const Params&); | 
