diff options
| author | Steven Bennetts <steve@lindenlab.com> | 2009-07-21 00:57:23 +0000 | 
|---|---|---|
| committer | Steven Bennetts <steve@lindenlab.com> | 2009-07-21 00:57:23 +0000 | 
| commit | 73a97010e6c8c7874fdc1778ab46e492f77d9394 (patch) | |
| tree | f0c8efb1cebcc6157c8e6678cf0eb39b5792a1d7 | |
| parent | dedb5be906b53d1ea8601ff6b9c4b726fda02da8 (diff) | |
merge https://svn.aws.productengine.com/secondlife/export-from-ll/viewer-2-0/indra@1059 https://svn.aws.productengine.com/secondlife/pe/stable-1/indra@1070 -> svn+ssh://svn.lindenlab.com/svn/linden/branches/viewer/viewer-2.0.0-3
56 files changed, 2156 insertions, 1765 deletions
| diff --git a/indra/llui/llui.h b/indra/llui/llui.h index 6f0da05535..9399eff2ab 100644 --- a/indra/llui/llui.h +++ b/indra/llui/llui.h @@ -397,8 +397,13 @@ public:  		delete sInstance;  		sInstance = NULL;  	} + +	static bool instanceExists() { return NULL != sInstance; }  private: +	LLUISingleton(const LLUISingleton&){} +	LLUISingleton& operator=(const LLUISingleton&){} +private:  	static T*	sInstance;  }; diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index d9d2f6f732..ac3163a1bd 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -63,6 +63,7 @@ include_directories(      )  set(viewer_SOURCE_FILES +    llaccordionctrltab.cpp      llaccordionpanel.cpp      llagent.cpp      llagentaccess.cpp @@ -75,6 +76,7 @@ set(viewer_SOURCE_FILES      llassetuploadresponders.cpp      llassetuploadqueue.cpp      llaudiosourcevo.cpp +    llavataractions.cpp      llavatariconctrl.cpp      llavatarlist.cpp      llavatarlistitem.cpp @@ -86,13 +88,11 @@ set(viewer_SOURCE_FILES      llcallingcard.cpp      llcapabilitylistener.cpp      llcaphttpsender.cpp -    llchatbar.cpp      llchathistoryscroll.cpp      llchiclet.cpp      llclassifiedinfo.cpp      llclassifiedstatsresponder.cpp      llcloud.cpp -    llcollapsiblectrl.cpp      llcolorswatch.cpp      llcommandhandler.cpp      llcommandlineparser.cpp @@ -213,7 +213,6 @@ set(viewer_SOURCE_FILES      llfolderview.cpp      llfolderviewitem.cpp      llfollowcam.cpp -    llfriendactions.cpp      llgesturemgr.cpp      llgivemoney.cpp      llglsandbox.cpp @@ -350,6 +349,7 @@ set(viewer_SOURCE_FILES      lltexturectrl.cpp      lltexturefetch.cpp      lltextureview.cpp +    lltoggleablemenu.cpp      lltoolbar.cpp      lltoolbrush.cpp      lltoolcomp.cpp @@ -483,6 +483,7 @@ endif (LINUX)  set(viewer_HEADER_FILES      CMakeLists.txt      ViewerInstall.cmake +    llaccordionctrltab.h      llaccordionpanel.h      llagent.h      llagentaccess.h @@ -496,6 +497,7 @@ set(viewer_HEADER_FILES      llassetuploadresponders.h      llassetuploadqueue.h      llaudiosourcevo.h +    llavataractions.h      llavatariconctrl.h      llavatarlist.h      llavatarlistitem.h @@ -508,13 +510,11 @@ set(viewer_HEADER_FILES      llcapabilitylistener.h      llcapabilityprovider.h      llcaphttpsender.h -    llchatbar.h      llchathistoryscroll.h      llchiclet.h      llclassifiedinfo.h      llclassifiedstatsresponder.h      llcloud.h -    llcollapsiblectrl.h      llcolorswatch.h      llcommandhandler.h      llcommandlineparser.h @@ -637,7 +637,6 @@ set(viewer_HEADER_FILES      llfoldervieweventlistener.h      llfolderviewitem.h      llfollowcam.h -    llfriendactions.h      llgesturemgr.h      llgivemoney.h      llgroupactions.h @@ -777,6 +776,7 @@ set(viewer_HEADER_FILES      lltexturectrl.h      lltexturefetch.h      lltextureview.h +    lltoggleablemenu.h      lltool.h      lltoolbar.h      lltoolbrush.h diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index cdf9a6b059..afad88770e 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -37,7 +37,6 @@  #include "llanimationstates.h"  #include "llcallingcard.h" -#include "llchatbar.h"  #include "llconsole.h"  #include "lldrawable.h"  #include "llfirstuse.h" @@ -2722,8 +2721,7 @@ void LLAgent::startTyping()  	{  		sendAnimationRequest(ANIM_AGENT_TYPE, ANIM_REQUEST_START);  	} -	if(gBottomTray) -		gBottomTray->sendChatFromViewer("", CHAT_TYPE_START, FALSE); +	LLBottomTray::getInstance()->sendChatFromViewer("", CHAT_TYPE_START, FALSE);  }  //----------------------------------------------------------------------------- @@ -2735,8 +2733,7 @@ void LLAgent::stopTyping()  	{  		clearRenderState(AGENT_STATE_TYPING);  		sendAnimationRequest(ANIM_AGENT_TYPE, ANIM_REQUEST_STOP); -		if(gBottomTray) -			gBottomTray->sendChatFromViewer("", CHAT_TYPE_STOP, FALSE); +		LLBottomTray::getInstance()->sendChatFromViewer("", CHAT_TYPE_STOP, FALSE);  	}  } @@ -2811,8 +2808,7 @@ void LLAgent::endAnimationUpdateUI()  		LLNavigationBar::getInstance()->setVisible(TRUE);  		gStatusBar->setVisibleForMouselook(true); -		if(gBottomTray) -			gBottomTray->setVisible(TRUE); +		LLBottomTray::getInstance()->setVisible(TRUE);  		LLSideTray::getInstance()->setVisible(TRUE); @@ -2902,8 +2898,7 @@ void LLAgent::endAnimationUpdateUI()  		LLNavigationBar::getInstance()->setVisible(FALSE);  		gStatusBar->setVisibleForMouselook(false); -		if(gBottomTray) -			gBottomTray->setVisible(FALSE); +		LLBottomTray::getInstance()->setVisible(FALSE);  		LLSideTray::getInstance()->setVisible(FALSE); diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp new file mode 100644 index 0000000000..2cf7298569 --- /dev/null +++ b/indra/newview/llavataractions.cpp @@ -0,0 +1,276 @@ +/**  + * @file llavataractions.cpp + * @brief Friend-related actions (add, remove, offer teleport, etc) + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + *  + * Copyright (c) 2009, Linden Research, Inc. + *  + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + *  + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + *  + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + + +#include "llviewerprecompiledheaders.h" + +#include "llavataractions.h" + +#include "llsd.h" +#include "lldarray.h" +#include "llnotifications.h" + +#include "llagent.h" +#include "llappviewer.h"		// for gLastVersionChannel +#include "llcallingcard.h"		// for LLAvatarTracker +#include "llinventorymodel.h" +#include "llimview.h"			// for gIMMgr +#include "llsidetray.h" +#include "llviewermessage.h"	// for handle_lure +#include "llviewerregion.h" + +// static +void LLAvatarActions::requestFriendshipDialog(const LLUUID& id, const std::string& name) +{ +	if(id == gAgentID) +	{ +		LLNotifications::instance().add("AddSelfFriend"); +		return; +	} + +	LLSD args; +	args["NAME"] = name; +	LLSD payload; +	payload["id"] = id; +	payload["name"] = name; +    // Look for server versions like: Second Life Server 1.24.4.95600 +	if (gLastVersionChannel.find(" 1.24.") != std::string::npos) +	{ +		// Old and busted server version, doesn't support friend +		// requests with messages. +    	LLNotifications::instance().add("AddFriend", args, payload, &callbackAddFriend); +	} +	else +	{ +    	LLNotifications::instance().add("AddFriendWithMessage", args, payload, &callbackAddFriendWithMessage); +	} +} + +// static +void LLAvatarActions::removeFriendDialog(const LLUUID& id) +{ +	if (id.isNull()) +		return; + +	std::vector<LLUUID> ids; +	ids.push_back(id); +	removeFriendsDialog(ids); +} + +// static +void LLAvatarActions::removeFriendsDialog(const std::vector<LLUUID>& ids) +{ +	if(ids.size() == 0) +		return; + +	LLSD args; +	std::string msgType; +	if(ids.size() == 1) +	{ +		LLUUID agent_id = ids[0]; +		std::string first, last; +		if(gCacheName->getName(agent_id, first, last)) +		{ +			args["FIRST_NAME"] = first; +			args["LAST_NAME"] = last;	 +		} + +		msgType = "RemoveFromFriends"; +	} +	else +	{ +		msgType = "RemoveMultipleFromFriends"; +	} + +	LLSD payload; +	for (std::vector<LLUUID>::const_iterator it = ids.begin(); it != ids.end(); ++it) +	{ +		payload["ids"].append(*it); +	} + +	LLNotifications::instance().add(msgType, +		args, +		payload, +		&handleRemove); +} + +// static +void LLAvatarActions::offerTeleport(const LLUUID& invitee) +{ +	if (invitee.isNull()) +		return; + +	LLDynamicArray<LLUUID> ids; +	ids.push_back(invitee); +	offerTeleport(ids); +} + +// static +void LLAvatarActions::offerTeleport(const std::vector<LLUUID>& ids)  +{ +	if (ids.size() > 0) +		handle_lure(ids); +} + +// static +void LLAvatarActions::startIM(const LLUUID& id) +{ +	if (id.isNull()) +		return; + +	std::string name; +	gCacheName->getFullName(id, name); +	gIMMgr->addSession(name, IM_NOTHING_SPECIAL, id); +	make_ui_sound("UISndStartIM"); +} + +// static +void LLAvatarActions::startConference(const std::vector<LLUUID>& ids) +{ +	// *HACK: Copy into dynamic array +	LLDynamicArray<LLUUID> id_array; +	for (std::vector<LLUUID>::const_iterator it = ids.begin(); it != ids.end(); ++it) +	{ +		id_array.push_back(*it); +	} +	gIMMgr->addSession("Friends Conference", IM_SESSION_CONFERENCE_START, ids[0], id_array); +	make_ui_sound("UISndStartIM"); +} + +// static +void LLAvatarActions::showProfile(const LLUUID& id) +{ +	if (id.notNull()) +	{ +		LLSD params; +		params["id"] = id; +		params["open_tab_name"] = "panel_profile"; + +		//Show own profile +		if(gAgent.getID() == id) +		{ +			LLSideTray::getInstance()->showPanel("panel_me_profile", params); +		} +		//Show other user profile +		else +		{ +			LLSideTray::getInstance()->showPanel("panel_profile_view", params); +		} +	} +} + +//== private methods ======================================================================================== + +// static +bool LLAvatarActions::handleRemove(const LLSD& notification, const LLSD& response) +{ +	S32 option = LLNotification::getSelectedOption(notification, response); + +	const LLSD& ids = notification["payload"]["ids"]; +	for (LLSD::array_const_iterator itr = ids.beginArray(); itr != ids.endArray(); ++itr) +	{ +		LLUUID id = itr->asUUID(); +		const LLRelationship* ip = LLAvatarTracker::instance().getBuddyInfo(id); +		if (ip) +		{ +			switch (option) +			{ +			case 0: // YES +				if( ip->isRightGrantedTo(LLRelationship::GRANT_MODIFY_OBJECTS)) +				{ +					LLAvatarTracker::instance().empower(id, FALSE); +					LLAvatarTracker::instance().notifyObservers(); +				} +				LLAvatarTracker::instance().terminateBuddy(id); +				LLAvatarTracker::instance().notifyObservers(); +				gInventory.addChangedMask(LLInventoryObserver::LABEL | LLInventoryObserver::CALLING_CARD, LLUUID::null); +				gInventory.notifyObservers(); +				break; + +			case 1: // NO +			default: +				llinfos << "No removal performed." << llendl; +				break; +			} +		} +	} +	return false; +} + +// static +bool LLAvatarActions::callbackAddFriendWithMessage(const LLSD& notification, const LLSD& response) +{ +	S32 option = LLNotification::getSelectedOption(notification, response); +	if (option == 0) +	{ +		requestFriendship(notification["payload"]["id"].asUUID(),  +		    notification["payload"]["name"].asString(), +		    response["message"].asString()); +	} +	return false; +} + +// static +bool LLAvatarActions::callbackAddFriend(const LLSD& notification, const LLSD& response) +{ +	S32 option = LLNotification::getSelectedOption(notification, response); +	if (option == 0) +	{ +		// Servers older than 1.25 require the text of the message to be the +		// calling card folder ID for the offering user. JC +		LLUUID calling_card_folder_id =  +			gInventory.findCategoryUUIDForType(LLAssetType::AT_CALLINGCARD); +		std::string message = calling_card_folder_id.asString(); +		requestFriendship(notification["payload"]["id"].asUUID(),  +		    notification["payload"]["name"].asString(), +		    message); +	} +    return false; +} + +// static +void LLAvatarActions::requestFriendship(const LLUUID& target_id, const std::string& target_name, const std::string& message) +{ +	LLUUID calling_card_folder_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_CALLINGCARD); +	send_improved_im(target_id, +					 target_name, +					 message, +					 IM_ONLINE, +					 IM_FRIENDSHIP_OFFERED, +					 calling_card_folder_id); +} + +//static +bool LLAvatarActions::isFriend(const LLUUID& id) +{ +	return ( NULL != LLAvatarTracker::instance().getBuddyInfo(id) ); +} diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h new file mode 100644 index 0000000000..73325d21f1 --- /dev/null +++ b/indra/newview/llavataractions.h @@ -0,0 +1,88 @@ +/**  + * @file llavataractions.h + * @brief Friend-related actions (add, remove, offer teleport, etc) + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + *  + * Copyright (c) 2009, Linden Research, Inc. + *  + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + *  + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + *  + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLAVATARACTIONS_H +#define LL_LLAVATARACTIONS_H + +/** + * Friend-related actions (add, remove, offer teleport, etc) + */ +class LLAvatarActions +{ +public: +	/** +	 * Show a dialog explaining what friendship entails, then request friendship. +	 */ +	static void requestFriendshipDialog(const LLUUID& id, const std::string& name); + +	/** +	 * Show a friend removal dialog. +	 */ +	static void removeFriendDialog(const LLUUID& id); +	static void removeFriendsDialog(const std::vector<LLUUID>& ids); +	 +	/** +	 * Show teleport offer dialog. +	 */ +	static void offerTeleport(const LLUUID& invitee); +	static void offerTeleport(const std::vector<LLUUID>& ids); + +	/** +	 * Start instant messaging session. +	 */ +	static void startIM(const LLUUID& id); + +	/** +	 * Start conference chat with the given avatars. +	 */ +	static void startConference(const std::vector<LLUUID>& ids); + +	/** +	 * Show avatar profile. +	 */ +	static void showProfile(const LLUUID& id); + +	/** +	 * Return true if avatar with "id" is a friend +	 */ +	static bool isFriend(const LLUUID& id); + +private: +	static bool callbackAddFriend(const LLSD& notification, const LLSD& response); +	static bool callbackAddFriendWithMessage(const LLSD& notification, const LLSD& response); +	static bool handleRemove(const LLSD& notification, const LLSD& response); + +	// Just request friendship, no dialog. +	static void requestFriendship(const LLUUID& target_id, const std::string& target_name, const std::string& message); +}; + +#endif // LL_LLAVATARACTIONS_H diff --git a/indra/newview/llavatariconctrl.cpp b/indra/newview/llavatariconctrl.cpp index bf18abfdb3..a3b8f6726d 100644 --- a/indra/newview/llavatariconctrl.cpp +++ b/indra/newview/llavatariconctrl.cpp @@ -36,7 +36,7 @@  #include "llavatarconstants.h"  #include "llavatariconctrl.h"  #include "llcallingcard.h" // for LLAvatarTracker -#include "llfriendactions.h" +#include "llavataractions.h"  #include "llimview.h"  #include "llmenugl.h"  #include "lluictrlfactory.h" @@ -230,7 +230,7 @@ void LLAvatarIconCtrl::onAvatarIconContextMenuItemClicked(const LLSD& userdata)  	if (level == "profile")  	{ -		LLFriendActions::showProfile(id); +		LLAvatarActions::showProfile(id);  	}  	else if (level == "im")  	{ @@ -248,10 +248,10 @@ void LLAvatarIconCtrl::onAvatarIconContextMenuItemClicked(const LLSD& userdata)  		name.append(" ");  		name.append(getLastName()); -		LLFriendActions::requestFriendshipDialog(id, name); +		LLAvatarActions::requestFriendshipDialog(id, name);  	}  	else if (level == "remove")  	{ -		LLFriendActions::removeFriendDialog(id); +		LLAvatarActions::removeFriendDialog(id);  	}  } diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp index d7fd97e067..e37b660951 100644 --- a/indra/newview/llbottomtray.cpp +++ b/indra/newview/llbottomtray.cpp @@ -40,24 +40,133 @@  #include "llgesturemgr.h"  #include "llanimationstates.h"  #include "llmultigesture.h" +#include "llviewerstats.h" +#include "llcommandhandler.h" -//FIXME: temporary, for send_chat_from_viewer() proto -#include "llchatbar.h"  //FIXME: temporary, for stand up proto  #include "llselectmgr.h"   #include "llvoavatarself.h" -// -// Globals -// -//FIXME: made it adjustable -const F32 AGENT_TYPING_TIMEOUT = 5.f;	// seconds -LLBottomTray* gBottomTray = NULL; +S32 LLBottomTray::mLastSpecialChatChannel = 0; -LLBottomTray::LLBottomTray() -	: mLastSpecialChatChannel(0) +// legacy calllback glue +void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel); + +static LLDefaultChildRegistry::Register<LLGestureComboBox> r("gesture_combo_box"); + +LLGestureComboBox::LLGestureComboBox(const LLComboBox::Params& p) +	: LLComboBox(p)  	, mGestureLabelTimer() -	, mChatBox(NULL) +{ +	setCommitCallback(boost::bind(&LLGestureComboBox::onCommitGesture, this, _1)); + +	// now register us as observer since we have a place to put the results +	gGestureManager.addObserver(this); + +	// refresh list from current active gestures +	refreshGestures(); +} + +LLGestureComboBox::~LLGestureComboBox() +{ +	gGestureManager.removeObserver(this); +} + +void LLGestureComboBox::refreshGestures() +{ +	//store current selection so we can maintain it +	std::string cur_gesture = getValue().asString(); +	selectFirstItem(); +	std::string label = getValue().asString();; +	// clear +	clearRows(); + +	// collect list of unique gestures +	std::map <std::string, BOOL> unique; +	LLGestureManager::item_map_t::iterator it; +	for (it = gGestureManager.mActive.begin(); it != gGestureManager.mActive.end(); ++it) +	{ +		LLMultiGesture* gesture = (*it).second; +		if (gesture) +		{ +			if (!gesture->mTrigger.empty()) +			{ +				unique[gesture->mTrigger] = TRUE; +			} +		} +	} + +	// add unique gestures +	std::map <std::string, BOOL>::iterator it2; +	for (it2 = unique.begin(); it2 != unique.end(); ++it2) +	{ +		addSimpleElement((*it2).first); +	} + +	sortByName(); +	// Insert label after sorting, at top, with separator below it +	addSeparator(ADD_TOP);		 +	//FIXME: get it from xml +	addSimpleElement("Gestures", ADD_TOP);	 + +	if (!cur_gesture.empty()) +	{  +		selectByValue(LLSD(cur_gesture)); +	} +	else +	{ +		selectFirstItem(); +	} +} + +void LLGestureComboBox::onCommitGesture(LLUICtrl* ctrl) +{ +	LLCtrlListInterface* gestures = getListInterface(); +	if (gestures) +	{ +		S32 index = gestures->getFirstSelectedIndex(); +		if (index == 0) +		{ +			return; +		} +		const std::string& trigger = gestures->getSelectedValue().asString(); + +		// pretend the user chatted the trigger string, to invoke +		// substitution and logging. +		std::string text(trigger); +		std::string revised_text; +		gGestureManager.triggerAndReviseString(text, &revised_text); + +		revised_text = utf8str_trim(revised_text); +		if (!revised_text.empty()) +		{ +			// Don't play nodding animation +			LLBottomTray::sendChatFromViewer(revised_text, CHAT_TYPE_NORMAL, FALSE); +		} +	} + +	mGestureLabelTimer.start(); +	// free focus back to chat bar +	setFocus(FALSE); +} + +//virtual +void LLGestureComboBox::draw() +{ +	// HACK: Leave the name of the gesture in place for a few seconds. +	const F32 SHOW_GESTURE_NAME_TIME = 2.f; +	if (mGestureLabelTimer.getStarted() && mGestureLabelTimer.getElapsedTimeF32() > SHOW_GESTURE_NAME_TIME) +	{ +		LLCtrlListInterface* gestures = getListInterface(); +		if (gestures) gestures->selectFirstItem(); +		mGestureLabelTimer.stop(); +	} + +	LLComboBox::draw(); +} + +LLBottomTray::LLBottomTray(const LLSD&) +	: mChatBox(NULL)  	, mChicletPanel(NULL)  	, mIMWell(NULL)  	, mSysWell(NULL) @@ -72,7 +181,7 @@ LLBottomTray::LLBottomTray()  	mSysWell = getChild<LLNotificationChiclet>("sys_well",TRUE,FALSE);  	mChatBox = getChild<LLLineEditor>("chat_box",TRUE,FALSE); -	mChicletPanel->setChicletClickCallback(boost::bind(&LLBottomTray::onChicletClick,this,_1)); +	mChicletPanel->setChicletClickedCallback(boost::bind(&LLBottomTray::onChicletClick,this,_1));  	if (mChatBox)  	{ @@ -91,17 +200,7 @@ LLBottomTray::LLBottomTray()  	} -	mGestureCombo = getChild<LLComboBox>( "Gesture", TRUE, FALSE); -	if (mGestureCombo) -	{ -		mGestureCombo->setCommitCallback(boost::bind(&LLBottomTray::onCommitGesture, this, _1)); - -		// now register us as observer since we have a place to put the results -		gGestureManager.addObserver(this); - -		// refresh list from current active gestures -		refreshGestures(); -	} +	mGestureCombo = getChild<LLGestureComboBox>( "Gesture", TRUE, FALSE);  	////FIXME: temporary, for stand up proto  	mStandUpBtn = getChild<LLButton> ("stand", TRUE, FALSE); @@ -116,11 +215,13 @@ LLBottomTray::LLBottomTray()  	//and thus is deleted at the end of the viewers lifetime, but to be cleanly  	//destroyed LLBottomTray requires some subsystems that are long gone  	LLUI::getRootView()->addChild(this); + +	// Necessary for focus movement among child controls +	setFocusRoot(TRUE);  }  LLBottomTray::~LLBottomTray()  { -	gGestureManager.removeObserver(this);  	if (!LLSingleton<LLIMMgr>::destroyed())  	{  		LLIMMgr::getInstance()->removeSessionObserver(this); @@ -132,7 +233,7 @@ void LLBottomTray::onChicletClick(LLUICtrl* ctrl)  	LLIMChiclet* chiclet = dynamic_cast<LLIMChiclet*>(ctrl);  	if (chiclet)  	{ -		LLFloaterReg::showInstance("communicate", chiclet->getIMSessionId()); +		LLFloaterReg::showInstance("communicate", chiclet->getSessionId());  	}  } @@ -278,30 +379,23 @@ void LLBottomTray::onChatBoxFocusLost(LLFocusableElement* caller, void* userdata  	gAgent.stopTyping();  } -void LLBottomTray::refresh() +BOOL LLBottomTray::inputEditorHasFocus()  { -	// HACK: Leave the name of the gesture in place for a few seconds. -	const F32 SHOW_GESTURE_NAME_TIME = 2.f; -	if (mGestureLabelTimer.getStarted() && mGestureLabelTimer.getElapsedTimeF32() > SHOW_GESTURE_NAME_TIME) -	{ -		LLCtrlListInterface* gestures = mGestureCombo ? mGestureCombo->getListInterface() : NULL; -		if (gestures) gestures->selectFirstItem(); -		mGestureLabelTimer.stop(); -	} +	return mChatBox && mChatBox->hasFocus(); +} -	if ((gAgent.getTypingTime() > AGENT_TYPING_TIMEOUT) && (gAgent.getRenderState() & AGENT_STATE_TYPING)) -	{ -		gAgent.stopTyping(); -	} -	 -	LLPanel::refresh(); +std::string LLBottomTray::getCurrentChat() +{ +	return mChatBox ? mChatBox->getText() : LLStringUtil::null;  } +//virtual  void LLBottomTray::draw()  {  	refreshStandUp();  	LLPanel::draw();  } +  void LLBottomTray::refreshStandUp()  {  	//FIXME: temporary, for stand up proto @@ -329,39 +423,6 @@ void LLBottomTray::updateRightPosition(const S32 new_right_position)  	}  } -void LLBottomTray::onCommitGesture(LLUICtrl* ctrl) -{ -	LLCtrlListInterface* gestures = mGestureCombo ? mGestureCombo->getListInterface() : NULL; -	if (gestures) -	{ -		S32 index = gestures->getFirstSelectedIndex(); -		if (index == 0) -		{ -			return; -		} -		const std::string& trigger = gestures->getSelectedValue().asString(); - -		// pretend the user chatted the trigger string, to invoke -		// substitution and logging. -		std::string text(trigger); -		std::string revised_text; -		gGestureManager.triggerAndReviseString(text, &revised_text); - -		revised_text = utf8str_trim(revised_text); -		if (!revised_text.empty()) -		{ -			// Don't play nodding animation -			sendChatFromViewer(revised_text, CHAT_TYPE_NORMAL, FALSE); -		} -	} -	mGestureLabelTimer.start(); -	if (mGestureCombo != NULL) -	{ -		// free focus back to chat bar -		mGestureCombo->setFocus(FALSE); -	} -} -  //FIXME: temporary, for stand up proto  void LLBottomTray::onCommitStandUp(LLUICtrl* ctrl)  { @@ -369,80 +430,56 @@ void LLBottomTray::onCommitStandUp(LLUICtrl* ctrl)  	gAgent.setControlFlags(AGENT_CONTROL_STAND_UP);  } -void LLBottomTray::refreshGestures() +//virtual +void LLBottomTray::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)  { -	if (mGestureCombo) +	if(getChicletPanel())  	{ -		 -		//store current selection so we can maintain it -		std::string cur_gesture = mGestureCombo->getValue().asString(); -		mGestureCombo->selectFirstItem(); -		std::string label = mGestureCombo->getValue().asString();; -		// clear -		mGestureCombo->clearRows(); -		 -		// collect list of unique gestures -		std::map <std::string, BOOL> unique; -		LLGestureManager::item_map_t::iterator it; -		for (it = gGestureManager.mActive.begin(); it != gGestureManager.mActive.end(); ++it) -		{ -			LLMultiGesture* gesture = (*it).second; -			if (gesture) -			{ -				if (!gesture->mTrigger.empty()) -				{ -					unique[gesture->mTrigger] = TRUE; -				} -			} -		} -		 -		// add unique gestures -		std::map <std::string, BOOL>::iterator it2; -		for (it2 = unique.begin(); it2 != unique.end(); ++it2) +		if(getChicletPanel()->findChiclet<LLChiclet>(session_id))  		{ -			mGestureCombo->addSimpleElement((*it2).first); -		} -		 -		mGestureCombo->sortByName(); -		// Insert label after sorting, at top, with separator below it -		mGestureCombo->addSeparator(ADD_TOP);		 -		mGestureCombo->addSimpleElement(getString("gesture_label"), ADD_TOP); -		 -		if (!cur_gesture.empty()) -		{  -			mGestureCombo->selectByValue(LLSD(cur_gesture)); +  		}  		else  		{ -			mGestureCombo->selectFirstItem(); +			LLIMChiclet* chicklet = getChicletPanel()->createChiclet<LLIMChiclet>(session_id); +			chicklet->setIMSessionName(name); +			chicklet->setOtherParticipantId(other_participant_id); + +			if(getChicletPanel()->getChicletCount()) +			{ +				setChicletPanelVisible(true); +			}  		}  	}  }  //virtual -void LLBottomTray::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) +void LLBottomTray::sessionRemoved(const LLUUID& session_id)  {  	if(getChicletPanel())  	{ -		if(getChicletPanel()->findIMChiclet(session_id)) -		{ +		getChicletPanel()->removeChiclet(session_id); -		} -		else +		if(0 == getChicletPanel()->getChicletCount())  		{ -			LLIMChiclet* chicklet = (LLIMChiclet *)getChicletPanel()->createChiclet(session_id); -			chicklet->setIMSessionName(name); -			chicklet->setOtherParticipantId(other_participant_id); +			setChicletPanelVisible(false);  		}  	}  } -//virtual -void LLBottomTray::sessionRemoved(const LLUUID& session_id) +void LLBottomTray::setChicletPanelVisible(bool visible)  { -	if(getChicletPanel()) +	// Chiclet panel is placed in layout_panel, which is child of layout_stack. +	// To gide chiclet panel we need to also hide layout_panel to make layout_stack resize its +	// content. +	getChicletPanel()->getParent()->setVisible(visible); +	if(visible)  	{ -		getChicletPanel()->removeIMChiclet(session_id); +		// Reshape layout stack after making chiclet panel visible +		LLView* layout = getChild<LLView>("toolbar_stack"); +		LLRect rc = layout->getRect(); +		layout->reshape(rc.getWidth(), rc.getHeight()); +		layout->setRect(rc);  	}  } @@ -503,6 +540,41 @@ void LLBottomTray::setVisible(BOOL visible)  } +// static  +void LLBottomTray::startChat(const char* line) +{ +	LLBottomTray *bt = LLBottomTray::getInstance(); + +	if(bt && bt->getChatBox()) +	{ +		bt->setVisible(TRUE); +		bt->getChatBox()->setFocus(TRUE); + +		if (line) +		{ +			std::string line_string(line); +			bt->getChatBox()->setText(line_string); +		} + +		bt->getChatBox()->setCursorToEnd(); +	} +} + +// Exit "chat mode" and do the appropriate focus changes +// static +void LLBottomTray::stopChat() +{ +	LLBottomTray *bt = LLBottomTray::getInstance(); + +	if(bt && bt->getChatBox()) +	{ +		bt->getChatBox()->setFocus(FALSE); +	} + + 	// stop typing animation + 	gAgent.stopTyping(); +} +  void LLBottomTray::sendChat( EChatType type )  {  	if (mChatBox) @@ -593,3 +665,42 @@ LLWString LLBottomTray::stripChannelNumber(const LLWString &mesg, S32* channel)  		return mesg;  	}  } + +void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel) +{ +	LLMessageSystem* msg = gMessageSystem; +	msg->newMessageFast(_PREHASH_ChatFromViewer); +	msg->nextBlockFast(_PREHASH_AgentData); +	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); +	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); +	msg->nextBlockFast(_PREHASH_ChatData); +	msg->addStringFast(_PREHASH_Message, utf8_out_text); +	msg->addU8Fast(_PREHASH_Type, type); +	msg->addS32("Channel", channel); + +	gAgent.sendReliableMessage(); + +	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_CHAT_COUNT); +} + +class LLChatHandler : public LLCommandHandler +{ +public: +	// not allowed from outside the app +	LLChatHandler() : LLCommandHandler("chat", true) { } + +    // Your code here +	bool handle(const LLSD& tokens, const LLSD& query_map, +				LLWebBrowserCtrl* web) +	{ +		if (tokens.size() < 2) return false; +		S32 channel = tokens[0].asInteger(); +		std::string mesg = tokens[1].asString(); +		send_chat_from_viewer(mesg, CHAT_TYPE_NORMAL, channel); +		return true; +	} +}; + +// Creating the object registers with the dispatcher. +LLChatHandler gChatHandler; + diff --git a/indra/newview/llbottomtray.h b/indra/newview/llbottomtray.h index 0d477122d1..1d4e271f80 100644 --- a/indra/newview/llbottomtray.h +++ b/indra/newview/llbottomtray.h @@ -37,20 +37,40 @@  #include "llimview.h"  #include "llchat.h"  #include "llgesturemgr.h" +#include "llcombobox.h"  class LLChicletPanel;  class LLNotificationChiclet;  class LLTalkButton; -class LLComboBox; -class LLBottomTray  -	: public LLPanel -	, public LLIMSessionObserver +class LLGestureComboBox +	: public LLComboBox  	, public LLGestureManagerObserver  { +protected: +	LLGestureComboBox(const LLComboBox::Params&); +	friend class LLUICtrlFactory;  public: -	LLBottomTray(); +	~LLGestureComboBox(); + +	void refreshGestures(); +	void onCommitGesture(LLUICtrl* ctrl); +	virtual void draw(); + +	// LLGestureManagerObserver trigger +	virtual void changed() { refreshGestures(); } + +protected: +	LLFrameTimer mGestureLabelTimer; +}; +class LLBottomTray  +	: public LLUISingleton<LLBottomTray> +	, public LLPanel +	, public LLIMSessionObserver +{ +	friend class LLUISingleton<LLBottomTray>; +public:  	~LLBottomTray();  	LLLineEditor*		getChatBox()	{return mChatBox;} @@ -59,12 +79,14 @@ public:  	LLNotificationChiclet*	getSysWell()	{return mSysWell;}  	void onChatBoxCommit(); -	void sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate); -	void sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate); +	static void sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate); +	static void sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate);  	static void onChatBoxKeystroke(LLLineEditor* caller, void* userdata);  	static void onChatBoxFocusLost(LLFocusableElement* caller, void* userdata); -	void refresh(); +	BOOL inputEditorHasFocus(); +	std::string getCurrentChat(); +  	/*virtual*/void draw();  	void refreshStandUp();  	void updateRightPosition(const S32 new_right_position); @@ -77,33 +99,34 @@ public:  	virtual void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);  	virtual void sessionRemoved(const LLUUID& session_id); -	// LLGestureManagerObserver trigger -	virtual void changed() { refreshGestures(); } -  	virtual void onFocusLost();  	virtual BOOL handleKeyHere(KEY key, MASK mask);  	virtual void setVisible(BOOL visible); +	static void startChat(const char* line); +	static void stopChat(); +  protected: +	LLBottomTray(const LLSD& key = LLSD()); +  	void sendChat( EChatType type ); -	LLWString stripChannelNumber(const LLWString &mesg, S32* channel); +	static LLWString stripChannelNumber(const LLWString &mesg, S32* channel);  	void onChicletClick(LLUICtrl* ctrl); +	void setChicletPanelVisible(bool visible); +  	// Which non-zero channel did we last chat on? -	S32 mLastSpecialChatChannel; +	static S32 mLastSpecialChatChannel;  	LLLineEditor*		mChatBox;  	LLChicletPanel* 	mChicletPanel;  	LLNotificationChiclet* 	mIMWell;  	LLNotificationChiclet* 	mSysWell;  	LLTalkButton* 		mTalkBtn; -	LLComboBox* 		mGestureCombo; -	LLFrameTimer 		mGestureLabelTimer; +	LLGestureComboBox*	mGestureCombo;  	LLButton*           mStandUpBtn;  }; -extern LLBottomTray* gBottomTray; -  #endif // LL_LLBOTTOMPANEL_H diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp deleted file mode 100644 index b94229704f..0000000000 --- a/indra/newview/llchatbar.cpp +++ /dev/null @@ -1,692 +0,0 @@ -/**  - * @file llchatbar.cpp - * @brief LLChatBar class implementation - * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - *  - * Copyright (c) 2002-2009, Linden Research, Inc. - *  - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab.  Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - *  - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - *  - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - *  - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" - -#include "llchatbar.h" - -#include "imageids.h" -#include "llfontgl.h" -#include "llrect.h" -#include "llerror.h" -#include "llparcel.h" -#include "llstring.h" -#include "message.h" -#include "llfocusmgr.h" - -#include "llagent.h" -#include "llbutton.h" -#include "llcombobox.h" -#include "llcommandhandler.h"	// secondlife:///app/chat/ support -#include "llviewercontrol.h" -#include "llfloaterchat.h" -#include "llgesturemgr.h" -#include "llkeyboard.h" -#include "lllineeditor.h" -#include "llstatusbar.h" -#include "lltextbox.h" -#include "lluiconstants.h" -#include "llviewergesture.h"			// for triggering gestures -#include "llviewermenu.h"		// for deleting object with DEL key -#include "llviewerstats.h" -#include "llviewerwindow.h" -#include "llframetimer.h" -#include "llresmgr.h" -#include "llworld.h" -#include "llinventorymodel.h" -#include "llmultigesture.h" -#include "llui.h" -#include "llviewermenu.h" -#include "lluictrlfactory.h" -#include "llbottomtray.h" - -// -// Globals -// -const F32 AGENT_TYPING_TIMEOUT = 5.f;	// seconds - -LLChatBar *gChatBar = NULL; - -class LLChatBarGestureObserver : public LLGestureManagerObserver -{ -public: -	LLChatBarGestureObserver(LLChatBar* chat_barp) : mChatBar(chat_barp){} -	virtual ~LLChatBarGestureObserver() {} -	virtual void changed() { mChatBar->refreshGestures(); } -private: -	LLChatBar* mChatBar; -}; - - -// -// Functions -// - -LLChatBar::LLChatBar()  -:	LLPanel(), -	mInputEditor(NULL), -	mGestureLabelTimer(), -	mLastSpecialChatChannel(0), -	mIsBuilt(FALSE), -	mGestureCombo(NULL), -	mObserver(NULL) -{ -	setIsChrome(TRUE); -	 -#if !LL_RELEASE_FOR_DOWNLOAD -	childDisplayNotFound(); -#endif -} - - -LLChatBar::~LLChatBar() -{ -	gGestureManager.removeObserver(mObserver); -	delete mObserver; -	mObserver = NULL; -	// LLView destructor cleans up children -} - -BOOL LLChatBar::postBuild() -{ -	getChild<LLUICtrl>("Say")->setCommitCallback(boost::bind(&LLChatBar::onClickSay, this, _1)); - -	// attempt to bind to an existing combo box named gesture -	setGestureCombo(getChild<LLComboBox>( "Gesture", TRUE, FALSE)); - -	mInputEditor = getChild<LLLineEditor>("Chat Editor"); -	mInputEditor->setKeystrokeCallback(&onInputEditorKeystroke, this); -	mInputEditor->setFocusLostCallback(&onInputEditorFocusLost, this); -	mInputEditor->setFocusReceivedCallback( &onInputEditorGainFocus, this ); -	mInputEditor->setCommitOnFocusLost( FALSE ); -	mInputEditor->setRevertOnEsc( FALSE ); -	mInputEditor->setIgnoreTab(TRUE); -	mInputEditor->setPassDelete(TRUE); -	mInputEditor->setReplaceNewlinesWithSpaces(FALSE); - -	mInputEditor->setMaxTextLength(1023); -	mInputEditor->setEnableLineHistory(TRUE); - -	mIsBuilt = TRUE; - -	return TRUE; -} - -//----------------------------------------------------------------------- -// Overrides -//----------------------------------------------------------------------- - -// virtual -BOOL LLChatBar::handleKeyHere( KEY key, MASK mask ) -{ -	BOOL handled = FALSE; - -	// ALT-RETURN is reserved for windowed/fullscreen toggle -	if( KEY_RETURN == key ) -	{ -		if (mask == MASK_CONTROL) -		{ -			// shout -			sendChat(CHAT_TYPE_SHOUT); -			handled = TRUE; -		} -		else if (mask == MASK_NONE) -		{ -			// say -			sendChat( CHAT_TYPE_NORMAL ); -			handled = TRUE; -		} -	} -	// only do this in main chatbar -	else if ( KEY_ESCAPE == key && gChatBar == this) -	{ -		stopChat(); - -		handled = TRUE; -	} - -	return handled; -} - -void LLChatBar::refresh() -{ -	// HACK: Leave the name of the gesture in place for a few seconds. -	const F32 SHOW_GESTURE_NAME_TIME = 2.f; -	if (mGestureLabelTimer.getStarted() && mGestureLabelTimer.getElapsedTimeF32() > SHOW_GESTURE_NAME_TIME) -	{ -		LLCtrlListInterface* gestures = mGestureCombo ? mGestureCombo->getListInterface() : NULL; -		if (gestures) gestures->selectFirstItem(); -		mGestureLabelTimer.stop(); -	} - -	if ((gAgent.getTypingTime() > AGENT_TYPING_TIMEOUT) && (gAgent.getRenderState() & AGENT_STATE_TYPING)) -	{ -		gAgent.stopTyping(); -	} - -	childSetEnabled("Say", mInputEditor->getText().size() > 0); - -} - -void LLChatBar::refreshGestures() -{ -	if (mGestureCombo) -	{ -		//store current selection so we can maintain it -		std::string cur_gesture = mGestureCombo->getValue().asString(); -		mGestureCombo->selectFirstItem(); -		std::string label = mGestureCombo->getValue().asString();; -		// clear -		mGestureCombo->clearRows(); - -		// collect list of unique gestures -		std::map <std::string, BOOL> unique; -		LLGestureManager::item_map_t::iterator it; -		for (it = gGestureManager.mActive.begin(); it != gGestureManager.mActive.end(); ++it) -		{ -			LLMultiGesture* gesture = (*it).second; -			if (gesture) -			{ -				if (!gesture->mTrigger.empty()) -				{ -					unique[gesture->mTrigger] = TRUE; -				} -			} -		} - -		// add unique gestures -		std::map <std::string, BOOL>::iterator it2; -		for (it2 = unique.begin(); it2 != unique.end(); ++it2) -		{ -			mGestureCombo->addSimpleElement((*it2).first); -		} -		 -		mGestureCombo->sortByName(); -		// Insert label after sorting, at top, with separator below it -		mGestureCombo->addSeparator(ADD_TOP); -		mGestureCombo->addSimpleElement(getString("gesture_label"), ADD_TOP); -		 -		if (!cur_gesture.empty()) -		{  -			mGestureCombo->selectByValue(LLSD(cur_gesture)); -		} -		else -		{ -			mGestureCombo->selectFirstItem(); -		} -	} -} - -// Move the cursor to the correct input field. -void LLChatBar::setKeyboardFocus(BOOL focus) -{ -	if (focus) -	{ -		if (mInputEditor) -		{ -			mInputEditor->setFocus(TRUE); -			mInputEditor->selectAll(); -		} -	} -	else if (gFocusMgr.childHasKeyboardFocus(this)) -	{ -		if (mInputEditor) -		{ -			mInputEditor->deselect(); -		} -		setFocus(FALSE); -	} -} - - -// Ignore arrow keys in chat bar -void LLChatBar::setIgnoreArrowKeys(BOOL b) -{ -	if (mInputEditor) -	{ -		mInputEditor->setIgnoreArrowKeys(b); -	} -} - -BOOL LLChatBar::inputEditorHasFocus() -{ -	return mInputEditor && mInputEditor->hasFocus(); -} - -std::string LLChatBar::getCurrentChat() -{ -	return mInputEditor ? mInputEditor->getText() : LLStringUtil::null; -} - -void LLChatBar::setGestureCombo(LLComboBox* combo) -{ -	mGestureCombo = combo; -	if (mGestureCombo) -	{ -		mGestureCombo->setCommitCallback(boost::bind(&LLChatBar::onCommitGesture, this, _1)); - -		// now register observer since we have a place to put the results -		mObserver = new LLChatBarGestureObserver(this); -		gGestureManager.addObserver(mObserver); - -		// refresh list from current active gestures -		refreshGestures(); -	} -} - -//----------------------------------------------------------------------- -// Internal functions -//----------------------------------------------------------------------- - -// If input of the form "/20foo" or "/20 foo", returns "foo" and channel 20. -// Otherwise returns input and channel 0. -LLWString LLChatBar::stripChannelNumber(const LLWString &mesg, S32* channel) -{ -	if (mesg[0] == '/' -		&& mesg[1] == '/') -	{ -		// This is a "repeat channel send" -		*channel = mLastSpecialChatChannel; -		return mesg.substr(2, mesg.length() - 2); -	} -	else if (mesg[0] == '/' -			 && mesg[1] -			 && LLStringOps::isDigit(mesg[1])) -	{ -		// This a special "/20" speak on a channel -		S32 pos = 0; - -		// Copy the channel number into a string -		LLWString channel_string; -		llwchar c; -		do -		{ -			c = mesg[pos+1]; -			channel_string.push_back(c); -			pos++; -		} -		while(c && pos < 64 && LLStringOps::isDigit(c)); -		 -		// Move the pointer forward to the first non-whitespace char -		// Check isspace before looping, so we can handle "/33foo" -		// as well as "/33 foo" -		while(c && iswspace(c)) -		{ -			c = mesg[pos+1]; -			pos++; -		} -		 -		mLastSpecialChatChannel = strtol(wstring_to_utf8str(channel_string).c_str(), NULL, 10); -		*channel = mLastSpecialChatChannel; -		return mesg.substr(pos, mesg.length() - pos); -	} -	else -	{ -		// This is normal chat. -		*channel = 0; -		return mesg; -	} -} - - -void LLChatBar::sendChat( EChatType type ) -{ -	if (mInputEditor) -	{ -		LLWString text = mInputEditor->getConvertedText(); -		if (!text.empty()) -		{ -			// store sent line in history, duplicates will get filtered -			if (mInputEditor) mInputEditor->updateHistory(); -			// Check if this is destined for another channel -			S32 channel = 0; -			stripChannelNumber(text, &channel); -			 -			std::string utf8text = wstring_to_utf8str(text); -			// Try to trigger a gesture, if not chat to a script. -			std::string utf8_revised_text; -			if (0 == channel) -			{ -				// discard returned "found" boolean -				gGestureManager.triggerAndReviseString(utf8text, &utf8_revised_text); -			} -			else -			{ -				utf8_revised_text = utf8text; -			} - -			utf8_revised_text = utf8str_trim(utf8_revised_text); - -			if (!utf8_revised_text.empty()) -			{ -				// Chat with animation -				sendChatFromViewer(utf8_revised_text, type, TRUE); -			} -		} -	} - -	childSetValue("Chat Editor", LLStringUtil::null); - -	gAgent.stopTyping(); - -	// If the user wants to stop chatting on hitting return, lose focus -	// and go out of chat mode. -	if (gChatBar == this && gSavedSettings.getBOOL("CloseChatOnReturn")) -	{ -		stopChat(); -	} -} - - -//----------------------------------------------------------------------- -// Static functions -//----------------------------------------------------------------------- - -// static  -void LLChatBar::startChat(const char* line) -{ -	//TODO* remove DUMMY chat -	if(gBottomTray && gBottomTray->getChatBox()) -	{ -		gBottomTray->setVisible(TRUE); -		gBottomTray->getChatBox()->setFocus(TRUE); -	} - -	// *TODO Vadim: Why was this code commented out? - -// 	gChatBar->setVisible(TRUE); -// 	gChatBar->setKeyboardFocus(TRUE); -// 	gSavedSettings.setBOOL("ChatVisible", TRUE); -//  -// 	if (line && gChatBar->mInputEditor) -// 	{ -// 		std::string line_string(line); -// 		gChatBar->mInputEditor->setText(line_string); -// 	} -// 	// always move cursor to end so users don't obliterate chat when accidentally hitting WASD -// 	gChatBar->mInputEditor->setCursorToEnd(); -} - - -// Exit "chat mode" and do the appropriate focus changes -// static -void LLChatBar::stopChat() -{ -	//TODO* remove DUMMY chat -	if(gBottomTray && gBottomTray->getChatBox()) -	{ -		gBottomTray->getChatBox()->setFocus(FALSE); -	} - -	// *TODO Vadim: Why was this code commented out? - -// 	// In simple UI mode, we never release focus from the chat bar -// 	gChatBar->setKeyboardFocus(FALSE); -//  -// 	// If we typed a movement key and pressed return during the -// 	// same frame, the keyboard handlers will see the key as having -// 	// gone down this frame and try to move the avatar. -// 	gKeyboard->resetKeys(); -// 	gKeyboard->resetMaskKeys(); -//  -// 	// stop typing animation -// 	gAgent.stopTyping(); -//  -// 	// hide chat bar so it doesn't grab focus back -// 	gChatBar->setVisible(FALSE); -// 	gSavedSettings.setBOOL("ChatVisible", FALSE); -} - -// static -void LLChatBar::onInputEditorKeystroke( LLLineEditor* caller, void* userdata ) -{ -	LLChatBar* self = (LLChatBar *)userdata; - -	LLWString raw_text; -	if (self->mInputEditor) raw_text = self->mInputEditor->getWText(); - -	// Can't trim the end, because that will cause autocompletion -	// to eat trailing spaces that might be part of a gesture. -	LLWStringUtil::trimHead(raw_text); - -	S32 length = raw_text.length(); - -	if( (length > 0) && (raw_text[0] != '/') )  // forward slash is used for escape (eg. emote) sequences -	{ -		gAgent.startTyping(); -	} -	else -	{ -		gAgent.stopTyping(); -	} - -	/* Doesn't work -- can't tell the difference between a backspace -	   that killed the selection vs. backspace at the end of line. -	if (length > 1  -		&& text[0] == '/' -		&& key == KEY_BACKSPACE) -	{ -		// the selection will already be deleted, but we need to trim -		// off the character before -		std::string new_text = raw_text.substr(0, length-1); -		self->mInputEditor->setText( new_text ); -		self->mInputEditor->setCursorToEnd(); -		length = length - 1; -	} -	*/ - -	KEY key = gKeyboard->currentKey(); - -	// Ignore "special" keys, like backspace, arrows, etc. -	if (length > 1  -		&& raw_text[0] == '/' -		&& key < KEY_SPECIAL) -	{ -		// we're starting a gesture, attempt to autocomplete - -		std::string utf8_trigger = wstring_to_utf8str(raw_text); -		std::string utf8_out_str(utf8_trigger); - -		if (gGestureManager.matchPrefix(utf8_trigger, &utf8_out_str)) -		{ -			if (self->mInputEditor) -			{ -				std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size()); -				self->mInputEditor->setText(utf8_trigger + rest_of_match); // keep original capitalization for user-entered part -				S32 outlength = self->mInputEditor->getLength(); // in characters -			 -				// Select to end of line, starting from the character -				// after the last one the user typed. -				self->mInputEditor->setSelection(length, outlength); -			} -		} - -		//llinfos << "GESTUREDEBUG " << trigger  -		//	<< " len " << length -		//	<< " outlen " << out_str.getLength() -		//	<< llendl; -	} -} - -// static -void LLChatBar::onInputEditorFocusLost( LLFocusableElement* caller, void* userdata) -{ -	// stop typing animation -	gAgent.stopTyping(); -} - -// static -void LLChatBar::onInputEditorGainFocus( LLFocusableElement* caller, void* userdata ) -{ -	LLFloaterChat::setHistoryCursorAndScrollToEnd(); -} - -void LLChatBar::onClickSay( LLUICtrl* ctrl ) -{ -	std::string cmd = ctrl->getValue().asString(); -	e_chat_type chat_type = CHAT_TYPE_NORMAL; -	if (cmd == "shout") -	{ -		chat_type = CHAT_TYPE_SHOUT; -	} -	else if (cmd == "whisper") -	{ -		chat_type = CHAT_TYPE_WHISPER; -	} -	sendChat(chat_type); -} - -void LLChatBar::sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate) -{ -	sendChatFromViewer(utf8str_to_wstring(utf8text), type, animate); -} - -void LLChatBar::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate) -{ -	// Look for "/20 foo" channel chats. -	S32 channel = 0; -	LLWString out_text = stripChannelNumber(wtext, &channel); -	std::string utf8_out_text = wstring_to_utf8str(out_text); -	std::string utf8_text = wstring_to_utf8str(wtext); - -	utf8_text = utf8str_trim(utf8_text); -	if (!utf8_text.empty()) -	{ -		utf8_text = utf8str_truncate(utf8_text, MAX_STRING - 1); -	} - -	// Don't animate for chats people can't hear (chat to scripts) -	if (animate && (channel == 0)) -	{ -		if (type == CHAT_TYPE_WHISPER) -		{ -			lldebugs << "You whisper " << utf8_text << llendl; -			gAgent.sendAnimationRequest(ANIM_AGENT_WHISPER, ANIM_REQUEST_START); -		} -		else if (type == CHAT_TYPE_NORMAL) -		{ -			lldebugs << "You say " << utf8_text << llendl; -			gAgent.sendAnimationRequest(ANIM_AGENT_TALK, ANIM_REQUEST_START); -		} -		else if (type == CHAT_TYPE_SHOUT) -		{ -			lldebugs << "You shout " << utf8_text << llendl; -			gAgent.sendAnimationRequest(ANIM_AGENT_SHOUT, ANIM_REQUEST_START); -		} -		else -		{ -			llinfos << "send_chat_from_viewer() - invalid volume" << llendl; -			return; -		} -	} -	else -	{ -		if (type != CHAT_TYPE_START && type != CHAT_TYPE_STOP) -		{ -			lldebugs << "Channel chat: " << utf8_text << llendl; -		} -	} - -	send_chat_from_viewer(utf8_out_text, type, channel); -} - -void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel) -{ -	LLMessageSystem* msg = gMessageSystem; -	msg->newMessageFast(_PREHASH_ChatFromViewer); -	msg->nextBlockFast(_PREHASH_AgentData); -	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); -	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); -	msg->nextBlockFast(_PREHASH_ChatData); -	msg->addStringFast(_PREHASH_Message, utf8_out_text); -	msg->addU8Fast(_PREHASH_Type, type); -	msg->addS32("Channel", channel); - -	gAgent.sendReliableMessage(); - -	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_CHAT_COUNT); -} - - -void LLChatBar::onCommitGesture(LLUICtrl* ctrl) -{ -	LLCtrlListInterface* gestures = mGestureCombo ? mGestureCombo->getListInterface() : NULL; -	if (gestures) -	{ -		S32 index = gestures->getFirstSelectedIndex(); -		if (index == 0) -		{ -			return; -		} -		const std::string& trigger = gestures->getSelectedValue().asString(); - -		// pretend the user chatted the trigger string, to invoke -		// substitution and logging. -		std::string text(trigger); -		std::string revised_text; -		gGestureManager.triggerAndReviseString(text, &revised_text); - -		revised_text = utf8str_trim(revised_text); -		if (!revised_text.empty()) -		{ -			// Don't play nodding animation -			sendChatFromViewer(revised_text, CHAT_TYPE_NORMAL, FALSE); -		} -	} -	mGestureLabelTimer.start(); -	if (mGestureCombo != NULL) -	{ -		// free focus back to chat bar -		mGestureCombo->setFocus(FALSE); -	} -} - -class LLChatHandler : public LLCommandHandler -{ -public: -	// not allowed from outside the app -	LLChatHandler() : LLCommandHandler("chat", true) { } - -    // Your code here -	bool handle(const LLSD& tokens, const LLSD& query_map, -				LLWebBrowserCtrl* web) -	{ -		if (tokens.size() < 2) return false; -		S32 channel = tokens[0].asInteger(); -		std::string mesg = tokens[1].asString(); -		send_chat_from_viewer(mesg, CHAT_TYPE_NORMAL, channel); -		return true; -	} -}; - -// Creating the object registers with the dispatcher. -LLChatHandler gChatHandler; diff --git a/indra/newview/llchatbar.h b/indra/newview/llchatbar.h deleted file mode 100644 index e0e324af6b..0000000000 --- a/indra/newview/llchatbar.h +++ /dev/null @@ -1,120 +0,0 @@ -/**  - * @file llchatbar.h - * @brief LLChatBar class definition - * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - *  - * Copyright (c) 2002-2009, Linden Research, Inc. - *  - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab.  Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - *  - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - *  - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - *  - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#ifndef LL_LLCHATBAR_H -#define LL_LLCHATBAR_H - -#include "llpanel.h" -#include "llframetimer.h" -#include "llchat.h" - -class LLLineEditor; -class LLMessageSystem; -class LLUICtrl; -class LLUUID; -class LLFrameTimer; -class LLChatBarGestureObserver; -class LLComboBox; - -// legacy calllback glue -void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel); - -class LLChatBar -:	public LLPanel -{ -public: -	// constructor for inline chat-bars (e.g. hosted in chat history window) -	LLChatBar(); -	~LLChatBar(); -	virtual BOOL postBuild(); - -	virtual BOOL handleKeyHere(KEY key, MASK mask); - -	void		refresh(); -	void		refreshGestures(); - -	// Move cursor into chat input field. -	void		setKeyboardFocus(BOOL b); - -	// Ignore arrow keys for chat bar -	void		setIgnoreArrowKeys(BOOL b); - -	BOOL		inputEditorHasFocus(); -	std::string	getCurrentChat(); - -	// since chat bar logic is reused for chat history -	// gesture combo box might not be a direct child -	void		setGestureCombo(LLComboBox* combo); - -	// Send a chat (after stripping /20foo channel chats). -	// "Animate" means the nodding animation for regular text. -	void		sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate); -	void		sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate); - -	// If input of the form "/20foo" or "/20 foo", returns "foo" and channel 20. -	// Otherwise returns input and channel 0. -	LLWString stripChannelNumber(const LLWString &mesg, S32* channel); - -	// callbacks -	void onClickSay(LLUICtrl* ctrl); - -	static void	onTabClick( void* userdata ); -	static void	onInputEditorKeystroke(LLLineEditor* caller, void* userdata); -	static void	onInputEditorFocusLost(LLFocusableElement* caller,void* userdata); -	static void	onInputEditorGainFocus(LLFocusableElement* caller,void* userdata); - -	void onCommitGesture(LLUICtrl* ctrl); - -	static void startChat(const char* line); -	static void stopChat(); - -protected: -	void sendChat(EChatType type); -	void updateChat(); - -protected: -	LLLineEditor*	mInputEditor; - -	LLFrameTimer	mGestureLabelTimer; - -	// Which non-zero channel did we last chat on? -	S32				mLastSpecialChatChannel; - -	BOOL			mIsBuilt; -	LLComboBox*		mGestureCombo; - -	LLChatBarGestureObserver* mObserver; -}; - -extern LLChatBar *gChatBar; - -#endif diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp index 4999d05e44..bd946a79d6 100644 --- a/indra/newview/llchiclet.cpp +++ b/indra/newview/llchiclet.cpp @@ -32,72 +32,58 @@  #include "llviewerprecompiledheaders.h" // must be first include  #include "llchiclet.h" -#include "llvoiceclient.h"  #include "llagent.h" -#include "lltextbox.h" -#include "lliconctrl.h" -#include "llvoicecontrolpanel.h" -#include "lloutputmonitorctrl.h" -#include "llimview.h" +#include "llavataractions.h"  #include "llbottomtray.h" +#include "llgroupactions.h" +#include "lliconctrl.h"  #include "llimpanel.h" +#include "llimview.h" +#include "llfloatergroupinfo.h" +#include "llmenugl.h" +#include "lloutputmonitorctrl.h" +#include "lltextbox.h" +#include "llvoiceclient.h" +#include "llvoicecontrolpanel.h" -static const S32 CHICLET_HEIGHT = 25; -static const S32 CHICLET_SPACING = 0; -static const S32 CHICLET_PADDING = 3; -static const S32 AVATAR_WIDTH = 25; -static const S32 SPEAKER_WIDTH = 20; -static const S32 COUNTER_WIDTH = 20; -static const S32 SCROLL_BUTTON_WIDTH = 19; -static const S32 SCROLL_BUTTON_HEIGHT = 20; -static const S32 NOTIFICATION_TEXT_TOP_PAD = 5; +static const std::string P2P_MENU_NAME = "IMChiclet P2P Menu"; +static const std::string GROUP_MENU_NAME = "IMChiclet Group Menu";  static LLDefaultChildRegistry::Register<LLChicletPanel> t1("chiclet_panel");  static LLDefaultChildRegistry::Register<LLTalkButton> t2("chiclet_talk");  static LLDefaultChildRegistry::Register<LLNotificationChiclet> t3("chiclet_notification"); -static LLDefaultChildRegistry::Register<LLChicletPanel> t4("chiclet_panel"); +static LLDefaultChildRegistry::Register<LLIMChiclet> t4("chiclet_im");  //////////////////////////////////////////////////////////////////////////  //////////////////////////////////////////////////////////////////////////  //////////////////////////////////////////////////////////////////////////  LLNotificationChiclet::Params::Params() -: image_unselected("image_unselected") -, image_selected("image_selected") -, image_overlay("image_overlay") +: button("button") +, unread_notifications("unread_notifications")  { +	button.tab_stop(FALSE); +	button.label(LLStringUtil::null); + +	unread_notifications.font(LLFontGL::getFontSansSerif()); +	unread_notifications.text_color=(LLColor4::white); +	unread_notifications.font_halign(LLFontGL::HCENTER); +	unread_notifications.mouse_opaque(FALSE);  }  LLNotificationChiclet::LLNotificationChiclet(const Params& p)  : LLChiclet(p)  , mButton(NULL) -, mCounterText(NULL) -{ -	LLRect rc(p.rect); - -	LLButton::Params button_params; -	button_params.name("btn"); -	button_params.label(LLStringUtil::null); -	button_params.rect(LLRect(0,rc.getHeight(),rc.getWidth(),0)); -	button_params.image_overlay(p.image_overlay); -	button_params.image_unselected(p.image_unselected); -	button_params.image_selected(p.image_selected); -	button_params.tab_stop(false); +, mCounterCtrl(NULL) +{ +	LLButton::Params button_params = p.button; +	button_params.rect(p.rect());  	mButton = LLUICtrlFactory::create<LLButton>(button_params);  	addChild(mButton); -	LLTextBox::Params textbox_params; -	textbox_params.name("txt"); -	textbox_params.rect(LLRect(p.label_left,rc.getHeight(), -		rc.getWidth()-p.label_left,0)); -	textbox_params.mouse_opaque(false); -	textbox_params.v_pad(NOTIFICATION_TEXT_TOP_PAD); -	textbox_params.font.style("SansSerif"); -	textbox_params.font_halign(LLFontGL::HCENTER); -	mCounterText = LLUICtrlFactory::create<LLTextBox>(textbox_params); -	addChild(mCounterText); -	mCounterText->setColor(LLColor4::white); -	mCounterText->setText(LLStringUtil::null); + 	LLChicletNotificationCounterCtrl::Params unread_params = p.unread_notifications; +	mCounterCtrl = LLUICtrlFactory::create<LLChicletNotificationCounterCtrl>(unread_params); +	addChild(mCounterCtrl);  }  LLNotificationChiclet::~LLNotificationChiclet() @@ -105,18 +91,15 @@ LLNotificationChiclet::~LLNotificationChiclet()  } -LLChiclet* LLNotificationChiclet::create(const Params& p) +void LLNotificationChiclet::setCounter(S32 counter)  { -	LLChiclet* chiclet = new LLNotificationChiclet(p); -	return chiclet; +	mCounterCtrl->setCounter(counter);  } -void LLNotificationChiclet::setCounter(S32 counter) +void LLNotificationChiclet::setShowCounter(bool show)  { -	std::stringstream stream; -	mCounter = counter; -	stream << mCounter; -	mCounterText->setText(stream.str()); +	LLChiclet::setShowCounter(show); +	mCounterCtrl->setVisible(getShowCounter());  }  boost::signals2::connection LLNotificationChiclet::setClickCallback( @@ -129,10 +112,16 @@ boost::signals2::connection LLNotificationChiclet::setClickCallback(  //////////////////////////////////////////////////////////////////////////  ////////////////////////////////////////////////////////////////////////// +LLChiclet::Params::Params() + : show_counter("show_counter") +{ +	show_counter = true; +} +  LLChiclet::LLChiclet(const Params& p)  : LLUICtrl(p) -, mCounter(0) -, mShowCounter(true) +, mSessionId(LLUUID::null) +, mShowCounter(p.show_counter)  {  } @@ -155,91 +144,133 @@ BOOL LLChiclet::handleMouseDown(S32 x, S32 y, MASK mask)  	return TRUE;  } +boost::signals2::connection LLChiclet::setChicletSizeChangedCallback( +	const chiclet_size_changed_callback_t& cb) +{ +	return mChicletSizeChangedSignal.connect(cb); +} + +void LLChiclet::onChicletSizeChanged() +{ +	mChicletSizeChangedSignal(this, getValue()); +} + +LLSD LLChiclet::getValue() const +{ +	return LLSD(getSessionId()); +} + +void LLChiclet::setValue(const LLSD& value) +{ +	if(value.isUUID()) +		setSessionId(value.asUUID()); +} +  //////////////////////////////////////////////////////////////////////////  //////////////////////////////////////////////////////////////////////////  ////////////////////////////////////////////////////////////////////////// -LLIMChiclet::LLIMChiclet(const LLChiclet::Params& p) -: LLChiclet(p) -, mAvatar(NULL) -, mCounterText(NULL) -, mSpeaker(NULL) -, mIMSessionId(LLUUID::null) -, mShowSpeaker(false) -, mSpeakerStatus(SPEAKER_IDLE) -{ -	LLAvatarIconCtrl::Params avatar_params; -	avatar_params.control_name("avatar"); -	avatar_params.draw_tooltip = FALSE; -	mAvatar = LLUICtrlFactory::create<LLAvatarIconCtrl>(avatar_params); - -	addChild(mAvatar); - -	LLTextBox::Params unread_params; -	unread_params.font.style("SansSerif"); -	unread_params.font_halign(LLFontGL::HCENTER); -	unread_params.v_pad(5); -	mCounterText = LLUICtrlFactory::create<LLTextBox>(unread_params); -	addChild(mCounterText); -	mCounterText->setColor(LLColor4::white); -	setCounter(getCounter()); +LLIMChiclet::Params::Params() +: avatar_icon("avatar_icon") +, unread_notifications("unread_notifications") +, speaker("speaker") +, show_speaker("show_speaker") +{ +	rect(LLRect(0, 25, 45, 0)); + +	avatar_icon.name("avatar_icon"); +	avatar_icon.rect(LLRect(0, 25, 25, 0)); -	LLIconCtrl::Params speaker_params; -	speaker_params.image( LLUI::getUIImage("icn_voice_ptt-on-lvl2.tga") ); -	mSpeaker = LLUICtrlFactory::create<LLIconCtrl>(speaker_params); -	addChild(mSpeaker); -	mSpeaker->setVisible(getShowSpeaker()); +	unread_notifications.name("unread"); +	unread_notifications.rect(LLRect(25, 25, 45, 0)); +	unread_notifications.font(LLFontGL::getFontSansSerif()); +	unread_notifications.font_halign(LLFontGL::HCENTER); +	unread_notifications.v_pad(5); +	unread_notifications.text_color(LLColor4::white); -	S32 left = 0; -	mAvatar->setRect(LLRect(left,CHICLET_HEIGHT,AVATAR_WIDTH,0)); -	left += AVATAR_WIDTH + CHICLET_SPACING; -	mCounterText->setRect(LLRect(left,CHICLET_HEIGHT,left + COUNTER_WIDTH,0)); -	left += COUNTER_WIDTH + CHICLET_SPACING; -	mSpeaker->setRect(LLRect(left,CHICLET_HEIGHT,left + SPEAKER_WIDTH,0)); +	speaker.name("speaker"); +	speaker.rect(LLRect(45, 25, 65, 0)); + +	show_speaker = false;  } -LLIMChiclet::~LLIMChiclet() +LLIMChiclet::LLIMChiclet(const Params& p) +: LLChiclet(p) +, mAvatarCtrl(NULL) +, mCounterCtrl(NULL) +, mSpeakerCtrl(NULL) +, mShowSpeaker(p.show_speaker) +, mPopupMenu(NULL)  { +	LLChicletAvatarIconCtrl::Params avatar_params = p.avatar_icon; +	mAvatarCtrl = LLUICtrlFactory::create<LLChicletAvatarIconCtrl>(avatar_params); +	addChild(mAvatarCtrl); + +	LLChicletNotificationCounterCtrl::Params unread_params = p.unread_notifications; +	mCounterCtrl = LLUICtrlFactory::create<LLChicletNotificationCounterCtrl>(unread_params); +	addChild(mCounterCtrl); + +	setCounter(getCounter()); +	setShowCounter(getShowCounter()); + +	LLChicletSpeakerCtrl::Params speaker_params = p.speaker; +	mSpeakerCtrl = LLUICtrlFactory::create<LLChicletSpeakerCtrl>(speaker_params); +	addChild(mSpeakerCtrl); +	setShowSpeaker(getShowSpeaker());  } -LLChiclet* LLIMChiclet::create(const LLUUID& im_session_id /* = LLUUID::null */) +LLIMChiclet::~LLIMChiclet()  { -	LLIMChiclet* chiclet = new LLIMChiclet(LLChiclet::Params()); -	chiclet->setIMSessionId(im_session_id); -	return chiclet; +  }  void LLIMChiclet::setCounter(S32 counter)  { -	mCounter = counter; -	std::stringstream stream; -	stream << mCounter; -	mCounterText->setText(stream.str()); +	mCounterCtrl->setCounter(counter); -	LLRect rc = mCounterText->getRect(); -	rc.mRight = rc.mLeft + calcCounterWidth(); -	mCounterText->setRect(rc); +	if(getShowCounter()) +	{ +		LLRect counter_rect = mCounterCtrl->getRect(); +		LLRect required_rect = mCounterCtrl->getRequiredRect(); +		bool needs_resize = required_rect.getWidth() != counter_rect.getWidth(); + +		if(needs_resize) +		{ +			counter_rect.mRight = counter_rect.mLeft + required_rect.getWidth(); +			mCounterCtrl->reshape(counter_rect.getWidth(), counter_rect.getHeight()); +			mCounterCtrl->setRect(counter_rect); + +			onChicletSizeChanged(); +		} +	}  }  LLRect LLIMChiclet::getRequiredRect()  { -	LLRect rect(0,CHICLET_HEIGHT,AVATAR_WIDTH,0); +	LLRect rect(0, 0, mAvatarCtrl->getRect().getWidth(), 0);  	if(getShowCounter())  	{ -		rect.mRight += CHICLET_SPACING + calcCounterWidth(); +		rect.mRight += mCounterCtrl->getRequiredRect().getWidth();  	}  	if(getShowSpeaker())  	{ -		rect.mRight += CHICLET_SPACING + SPEAKER_WIDTH; +		rect.mRight += mSpeakerCtrl->getRect().getWidth();  	}  	return rect;  }  void LLIMChiclet::setShowCounter(bool show)  { +	bool needs_resize = getShowCounter() != show; +  	LLChiclet::setShowCounter(show); -	mCounterText->setVisible(getShowCounter()); +	mCounterCtrl->setVisible(getShowCounter()); + +	if(needs_resize) +	{ +		onChicletSizeChanged(); +	}  }  void LLIMChiclet::setIMSessionName(const std::string& name) @@ -249,16 +280,39 @@ void LLIMChiclet::setIMSessionName(const std::string& name)  void LLIMChiclet::setOtherParticipantId(const LLUUID& other_participant_id)  { -	if (mAvatar) +	if (mAvatarCtrl)  	{ -		mAvatar->setValue(other_participant_id); +		mAvatarCtrl->setValue(other_participant_id); +	} +} + +void LLIMChiclet::updateMenuItems() +{ +	if(!mPopupMenu) +		return; +	if(getSessionId().isNull()) +		return; + +	if(P2P_MENU_NAME == mPopupMenu->getName()) +	{ +		bool is_friend = LLAvatarActions::isFriend(mAvatarCtrl->getAvatarId()); + +		mPopupMenu->getChild<LLUICtrl>("Add Friend")->setEnabled(!is_friend); +		mPopupMenu->getChild<LLUICtrl>("Remove Friend")->setEnabled(is_friend);  	}  }  void LLIMChiclet::setShowSpeaker(bool show)  { +	bool needs_resize = getShowSpeaker() != show; +  	mShowSpeaker = show; -	mSpeaker->setVisible(getShowSpeaker()); +	mSpeakerCtrl->setVisible(getShowSpeaker()); + +	if(needs_resize) +	{ +		onChicletSizeChanged(); +	}  }  void LLIMChiclet::draw() @@ -267,45 +321,140 @@ void LLIMChiclet::draw()  	gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, LLColor4(0.0f,0.0f,0.0f,1.f), FALSE);  } -S32 LLIMChiclet::calcCounterWidth() +BOOL LLIMChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask) +{ +	if(!mPopupMenu) +		createPopupMenu(); + +	updateMenuItems(); +	 +	mPopupMenu->arrangeAndClear(); + +	LLMenuGL::showPopup(this, mPopupMenu, x, y); + +	return TRUE; +} + +void LLIMChiclet::createPopupMenu()  { -	S32 font_width = mCounterText->getFont()->getWidth("0"); -	S32 text_size = mCounterText->getText().size(); +	if(mPopupMenu) +	{ +		llwarns << "Menu already exists" << llendl; +		return; +	} +	if(getSessionId().isNull()) +		return; -	return llmax(font_width * text_size, COUNTER_WIDTH); +	LLFloaterIMPanel*floater = gIMMgr->findFloaterBySession(getSessionId()); +	if(!floater) +		return; + +	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; +	registrar.add("IMChicletMenu.Action", boost::bind(&LLIMChiclet::onMenuItemClicked, this, _2)); + +	switch(floater->getDialogType()) +	{ +	case IM_SESSION_GROUP_START: +		mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL> +			("menu_imchiclet_group.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); +		break; +	case IM_NOTHING_SPECIAL: +		mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL> +			("menu_imchiclet_p2p.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); +		break; +	default: +		llwarns << "Unexpected dialog type" << llendl; +		break; +	} +} + +void LLIMChiclet::onMenuItemClicked(const LLSD& user_data) +{ +	std::string level = user_data.asString(); +	LLUUID other_participant_id = mAvatarCtrl->getAvatarId(); + +	if("profile" == level) +	{ +		LLAvatarActions::showProfile(other_participant_id); +	} +	else if("im" == level) +	{ +		LLAvatarActions::startIM(other_participant_id); +	} +	else if("add" == level) +	{ +		std::string name; +		gCacheName->getFullName(other_participant_id,name); +		LLAvatarActions::requestFriendshipDialog(other_participant_id,name); +	} +	else if("remove" == level) +	{ +		LLAvatarActions::removeFriendDialog(other_participant_id); +	} +	else if("group chat" == level) +	{ +		LLGroupActions::startChat(other_participant_id); +	} +	else if("info" == level) +	{ +		LLFloaterGroupInfo::showFromUUID(other_participant_id); +	}  }  //////////////////////////////////////////////////////////////////////////  //////////////////////////////////////////////////////////////////////////  ////////////////////////////////////////////////////////////////////////// +LLChicletPanel::Params::Params() +: chiclet_padding("chiclet_padding") +, scrolling_offset("scrolling_offset") +, left_scroll_button("left_scroll_button") +, right_scroll_button("right_scroll_button") +{ +	chiclet_padding = 3; +	scrolling_offset = 40; + +	LLRect scroll_button_rect(0, 25, 19, 5); + +	left_scroll_button.name("left_scroll"); +	left_scroll_button.label(LLStringUtil::null); +	left_scroll_button.rect(scroll_button_rect); +	left_scroll_button.tab_stop(false); +	left_scroll_button.image_selected(LLUI::getUIImage("bottom_tray_scroll_left.tga")); +	left_scroll_button.image_unselected(LLUI::getUIImage("bottom_tray_scroll_left.tga")); +	left_scroll_button.image_hover_selected(LLUI::getUIImage("bottom_tray_scroll_left.tga")); + +	right_scroll_button.name("right_scroll"); +	right_scroll_button.label(LLStringUtil::null); +	right_scroll_button.rect(scroll_button_rect); +	right_scroll_button.tab_stop(false); +	right_scroll_button.image_selected(LLUI::getUIImage("bottom_tray_scroll_right.tga")); +	right_scroll_button.image_unselected(LLUI::getUIImage("bottom_tray_scroll_right.tga")); +	right_scroll_button.image_hover_selected(LLUI::getUIImage("bottom_tray_scroll_right.tga")); +}; +  LLChicletPanel::LLChicletPanel(const Params&p)  : LLPanel(p)  , mScrollArea(NULL) -, mLeftScroll(NULL) -, mRightScroll(NULL) -{ -	LLButton::Params params; - -	params.name("scroll_left"); -	params.label(LLStringUtil::null); -	params.tab_stop(false); -	params.image_selected(LLUI::getUIImage("bottom_tray_scroll_left.tga")); -	params.image_unselected(LLUI::getUIImage("bottom_tray_scroll_left.tga")); -	params.image_hover_selected(LLUI::getUIImage("bottom_tray_scroll_left.tga")); -	mLeftScroll = LLUICtrlFactory::create<LLButton>(params); -	addChild(mLeftScroll); -	mLeftScroll->setClickedCallback(boost::bind(&LLChicletPanel::onLeftScrollClick,this)); -	mLeftScroll->setEnabled(false); - -	params.name("scroll_right"); -	params.image_selected(LLUI::getUIImage("bottom_tray_scroll_right.tga")); -	params.image_unselected(LLUI::getUIImage("bottom_tray_scroll_right.tga")); -	params.image_hover_selected(LLUI::getUIImage("bottom_tray_scroll_right.tga")); -	mRightScroll = LLUICtrlFactory::create<LLButton>(params); -	addChild(mRightScroll); -	mRightScroll->setClickedCallback(boost::bind(&LLChicletPanel::onRightScrollClick,this)); -	mRightScroll->setEnabled(false); +, mLeftScrollButton(NULL) +, mRightScrollButton(NULL) +, mChicletPadding(p.chiclet_padding) +, mScrollingOffset(p.scrolling_offset) +{ +	LLButton::Params scroll_button_params = p.left_scroll_button; + +	mLeftScrollButton = LLUICtrlFactory::create<LLButton>(scroll_button_params); +	addChild(mLeftScrollButton); + +	mLeftScrollButton->setClickedCallback(boost::bind(&LLChicletPanel::onLeftScrollClick,this)); +	mLeftScrollButton->setEnabled(false); + +	scroll_button_params = p.right_scroll_button; +	mRightScrollButton = LLUICtrlFactory::create<LLButton>(scroll_button_params); +	addChild(mRightScrollButton); + +	mRightScrollButton->setClickedCallback(boost::bind(&LLChicletPanel::onRightScrollClick,this)); +	mRightScrollButton->setEnabled(false);  	LLPanel::Params panel_params;  	mScrollArea = LLUICtrlFactory::create<LLPanel>(panel_params,this); @@ -320,7 +469,7 @@ LLChicletPanel::~LLChicletPanel()  void im_chiclet_callback(LLChicletPanel* panel, const LLSD& data){  	LLUUID session_id = data["session_id"].asUUID(); -	LLChiclet* chiclet = panel->findIMChiclet(session_id); +	LLChiclet* chiclet = panel->findChiclet<LLChiclet>(session_id);  	if (chiclet)  	{ @@ -341,38 +490,28 @@ BOOL LLChicletPanel::postBuild()  	return TRUE;  } -LLChiclet* LLChicletPanel::createChiclet(const LLUUID& im_session_id /* = LLUUID::null */, S32 pos /* = 0 */) -{ -	LLChiclet* chiclet = LLIMChiclet::create(im_session_id); -	if(!chiclet) -	{ -		assert(false); -		return NULL; -	} - -	if(!addChiclet(chiclet, pos)) -	{ -		assert(false); -		return NULL; -	} - -	return chiclet; -} - -bool LLChicletPanel::addChiclet(LLChiclet* chiclet, S32 pos) +bool LLChicletPanel::addChiclet(LLChiclet* chiclet, S32 index)  {  	if(mScrollArea->addChild(chiclet))  	{ -		// if first chiclet is scrolled left, the created one should be scrolled left too -		if(0 == pos && canScrollLeft()) +		S32 offset = 0; +		// Do not scroll chiclets if chiclets are scrolled right and new +		// chiclet is added to the beginning of the list +		if(canScrollLeft())  		{ -			LLRect first_chiclet_rect = getChiclet(0)->getRect(); -			chiclet->setRect(first_chiclet_rect); +			offset = - (chiclet->getRequiredRect().getWidth() + getChicletPadding()); +			if(0 == index) +			{ +				offset += getChiclet(0)->getRect().mLeft; +			}  		} -		mChicletList.insert(mChicletList.begin() + pos, chiclet); +		mChicletList.insert(mChicletList.begin() + index, chiclet); + +		getChiclet(0)->translate(offset, 0);  		chiclet->setLeftButtonClickCallback(boost::bind(&LLChicletPanel::onChicletClick, this, _1, _2)); +		chiclet->setChicletSizeChangedCallback(boost::bind(&LLChicletPanel::onChicletSizeChanged, this, _1, index));  		arrange();  		showScrollButtonsIfNeeded(); @@ -383,6 +522,29 @@ bool LLChicletPanel::addChiclet(LLChiclet* chiclet, S32 pos)  	return false;  } +void LLChicletPanel::onChicletSizeChanged(LLChiclet* ctrl, const LLSD& param) +{ +	S32 chiclet_width = ctrl->getRect().getWidth(); +	S32 chiclet_new_width = ctrl->getRequiredRect().getWidth(); + +	if(chiclet_new_width == chiclet_width) +	{ +		return; +	} + +	LLRect chiclet_rect = ctrl->getRect(); +	chiclet_rect.mRight = chiclet_rect.mLeft + chiclet_new_width;	 + +	ctrl->setRect(chiclet_rect); + +	S32 offset = chiclet_new_width - chiclet_width; +	S32 index = getChicletIndex(ctrl); + +	shiftChiclets(offset, index + 1); +	trimChiclets(); +	showScrollButtonsIfNeeded(); +} +  void LLChicletPanel::onChicletClick(LLUICtrl*ctrl,const LLSD¶m)  {  	LLIMChiclet* chiclet = dynamic_cast<LLIMChiclet*>(ctrl); @@ -391,66 +553,42 @@ void LLChicletPanel::onChicletClick(LLUICtrl*ctrl,const LLSD¶m)  		S32 x, y;  		LLRect rect = getRect();  		localPointToScreen(rect.getCenterX(), 0, &x, &y); -		LLIMFloater::show(chiclet->getIMSessionId(), x); +		LLIMFloater::show(chiclet->getSessionId(), x);  	}  	mCommitSignal(ctrl,param);  } -LLChiclet* LLChicletPanel::findIMChiclet(const LLUUID& im_session_id) -{ -	chiclet_list_t::const_iterator it = mChicletList.begin(); -	for( ; mChicletList.end() != it; ++it) -	{ -		// Only IM Chiclets have session id, skip non IM Chiclets -		LLIMChiclet* chiclet = dynamic_cast<LLIMChiclet*>(*it); -		if(!chiclet) -		{ -			continue; -		} - -		if(chiclet->getIMSessionId() == im_session_id) -		{ -			return chiclet; -		} -	} -	return NULL; -} - -LLChiclet* LLChicletPanel::getChiclet(S32 pos) -{ -	return mChicletList[pos]; -} -  void LLChicletPanel::removeChiclet(chiclet_list_t::iterator it)  { -	// if possible, after deletion shift chiclets right -	if(canScrollLeft() && !canScrollRight()) -	{ -		LLChiclet* chiclet = *it; -		LLRect first_chiclet_rect = getChiclet(0)->getRect(); -		S32 deleted_chiclet_width = chiclet->getRect().getWidth(); -		deleted_chiclet_width += CHICLET_PADDING; -		 -		first_chiclet_rect.mLeft += deleted_chiclet_width; -		first_chiclet_rect.mRight += deleted_chiclet_width; - -		getChiclet(0)->setRect(first_chiclet_rect); -	} -  	mScrollArea->removeChild(*it);  	mChicletList.erase(it);  	arrange(); +	trimChiclets();  	showScrollButtonsIfNeeded();  } -void LLChicletPanel::removeChiclet(S32 pos) +void LLChicletPanel::removeChiclet(S32 index)  { -	if(0 > pos || getChicletCount() <= pos) +	if(index >= 0 && index < getChicletCount())  	{ -		return; +		removeChiclet(mChicletList.begin() + index);  	} -	removeChiclet(mChicletList.begin() + pos); +} + +S32 LLChicletPanel::getChicletIndex(const LLChiclet* chiclet) +{ +	if(mChicletList.empty()) +		return -1; + +	S32 size = getChicletCount(); +	for(int n = 0; n < size; ++n) +	{ +		if(chiclet == mChicletList[n]) +			return n; +	} + +	return -1;  }  void LLChicletPanel::removeChiclet(LLChiclet*chiclet) @@ -467,19 +605,14 @@ void LLChicletPanel::removeChiclet(LLChiclet*chiclet)  	}  } -void LLChicletPanel::removeIMChiclet(const LLUUID& im_session_id) +void LLChicletPanel::removeChiclet(const LLUUID& im_session_id)  {  	chiclet_list_t::iterator it = mChicletList.begin();  	for( ; mChicletList.end() != it; ++it)  	{ -		// Only IM Chiclets have session id, skip non IM Chiclets  		LLIMChiclet* chiclet = dynamic_cast<LLIMChiclet*>(*it); -		if(!chiclet) -		{ -			continue; -		} -		if(chiclet->getIMSessionId() == im_session_id) +		if(chiclet->getSessionId() == im_session_id)  		{  			removeChiclet(it);  			return; @@ -489,7 +622,11 @@ void LLChicletPanel::removeIMChiclet(const LLUUID& im_session_id)  void LLChicletPanel::removeAll()  { -	mScrollArea->deleteAllChildren(); +	S32 size = getChicletCount(); +	for(S32 n = 0; n < size; ++n) +	{ +		mScrollArea->removeChild(mChicletList[n]); +	}  	mChicletList.erase(mChicletList.begin(), mChicletList.end()); @@ -500,75 +637,67 @@ void LLChicletPanel::reshape(S32 width, S32 height, BOOL called_from_parent )  {  	LLPanel::reshape(width,height,called_from_parent); -	mLeftScroll->setRect(LLRect(0,CHICLET_HEIGHT,SCROLL_BUTTON_WIDTH, -		CHICLET_HEIGHT - SCROLL_BUTTON_HEIGHT)); -	mRightScroll->setRect(LLRect(width-SCROLL_BUTTON_WIDTH,CHICLET_HEIGHT, -		width,CHICLET_HEIGHT - SCROLL_BUTTON_HEIGHT)); +	static const S32 SCROLL_BUTTON_PAD = 5; -	S32 old_scroll_width = mScrollArea->getRect().getWidth(); +	LLRect scroll_button_rect = mLeftScrollButton->getRect(); +	mLeftScrollButton->setRect(LLRect(0,height,scroll_button_rect.getWidth(), +		height - scroll_button_rect.getHeight())); -	mScrollArea->setRect(LLRect(SCROLL_BUTTON_WIDTH + 5,CHICLET_HEIGHT + 1, -		width - SCROLL_BUTTON_WIDTH - 5, 0)); +	scroll_button_rect = mRightScrollButton->getRect(); +	mRightScrollButton->setRect(LLRect(width - scroll_button_rect.getWidth(),height, +		width, height - scroll_button_rect.getHeight())); -	S32 current_scroll_width = mScrollArea->getRect().getWidth(); -	reshapeScrollArea(current_scroll_width - old_scroll_width); +	mScrollArea->setRect(LLRect(scroll_button_rect.getWidth() + SCROLL_BUTTON_PAD, +		height + 1, width - scroll_button_rect.getWidth() - SCROLL_BUTTON_PAD, 0)); + +	trimChiclets();  	showScrollButtonsIfNeeded();  } -void LLChicletPanel::reshapeScrollArea(S32 delta_width) +void LLChicletPanel::arrange()  {  	if(mChicletList.empty())  		return; -	S32 last_chiclet_right = (*mChicletList.rbegin())->getRect().mRight; -	S32 scroll_width = mScrollArea->getRect().getWidth(); +	S32 chiclet_left = getChiclet(0)->getRect().mLeft; -	// Align all chiclets to last chiclet -	// if there is a gap between last chiclet and scroll area right side -	// or last chiclet is at visible area right side -	if( last_chiclet_right < scroll_width  -		|| last_chiclet_right == scroll_width - delta_width) +	S32 size = getChicletCount(); +	for( int n = 0; n < size; ++n)  	{ -		LLRect first_chiclet_rect = getChiclet(0)->getRect(); -		// if we can right shift all chiclets -		if(first_chiclet_rect.mLeft < 0) -		{ -			first_chiclet_rect.mLeft += delta_width; -			first_chiclet_rect.mRight += delta_width; +		LLChiclet* chiclet = getChiclet(n); -			getChiclet(0)->setRect(first_chiclet_rect); +		S32 chiclet_width = chiclet->getRequiredRect().getWidth(); +		LLRect rect = chiclet->getRect(); +		rect.set(chiclet_left, rect.mTop, chiclet_left + chiclet_width, rect.mBottom); -			arrange(); -		} +		chiclet->setRect(rect); + +		chiclet_left += chiclet_width + getChicletPadding();  	}  } -void LLChicletPanel::arrange() +void LLChicletPanel::trimChiclets()  { -	if(mChicletList.empty()) -		return; - -	LLRect first_chiclet_rect = getChiclet(0)->getRect(); -	// don't allow gap between first chiclet and scroll area left side -	if(first_chiclet_rect.mLeft > 0) +	// trim right +	if(canScrollLeft() && !canScrollRight())  	{ -		first_chiclet_rect.mRight = first_chiclet_rect.getWidth(); -		first_chiclet_rect.mLeft = 0; +		S32 last_chiclet_right = (*mChicletList.rbegin())->getRect().mRight; +		S32 scroll_width = mScrollArea->getRect().getWidth(); +		if(last_chiclet_right < scroll_width) +		{ +			shiftChiclets(scroll_width - last_chiclet_right); +		}  	} -	S32 left = first_chiclet_rect.mLeft; - -	S32 size = getChicletCount(); -	for( int n = 0; n < size; ++n) +	// trim left +	if(!mChicletList.empty())  	{ -		LLChiclet* chiclet = getChiclet(n); -		S32 chiclet_width = chiclet->getRequiredRect().getWidth(); -		LLRect rc(left, CHICLET_HEIGHT, left + chiclet_width, 0); - -		chiclet->setRect(rc); - -		left += chiclet_width + CHICLET_PADDING; +		LLRect first_chiclet_rect = getChiclet(0)->getRect(); +		if(first_chiclet_rect.mLeft > 0) +		{ +			shiftChiclets( - first_chiclet_rect.mLeft); +		}  	}  } @@ -577,13 +706,13 @@ void LLChicletPanel::showScrollButtonsIfNeeded()  	bool can_scroll_left = canScrollLeft();  	bool can_scroll_right = canScrollRight(); -	mLeftScroll->setEnabled(can_scroll_left); -	mRightScroll->setEnabled(can_scroll_right); +	mLeftScrollButton->setEnabled(can_scroll_left); +	mRightScrollButton->setEnabled(can_scroll_right);  	bool show_scroll_buttons = can_scroll_left || can_scroll_right; -	mLeftScroll->setVisible(show_scroll_buttons); -	mRightScroll->setVisible(show_scroll_buttons); +	mLeftScrollButton->setVisible(show_scroll_buttons); +	mRightScrollButton->setVisible(show_scroll_buttons);  }  void LLChicletPanel::draw() @@ -626,42 +755,19 @@ bool LLChicletPanel::canScrollLeft()  	return getChiclet(0)->getRect().mLeft < 0;  } -void LLChicletPanel::scroll(ScrollDirection direction) +void LLChicletPanel::scroll(S32 offset)  { -	S32 first_visible_chiclet = getFirstVisibleChiclet(); -	if(-1 == first_visible_chiclet) -		return; - -	S32 offset = 0; +	shiftChiclets(offset); +} -	if(SCROLL_LEFT == direction) -	{ -		if(0 == first_visible_chiclet) -		{ -			// shift chiclets in case first chiclet is partially visible -			offset = llabs(getChiclet(first_visible_chiclet)->getRect().mLeft); -		} -		else -		{ -			offset = getChiclet(first_visible_chiclet - 1)->getRect().getWidth() + CHICLET_PADDING; -		} -	} -	else if(SCROLL_RIGHT == direction) +void LLChicletPanel::shiftChiclets(S32 offset, S32 start_index /* = 0 */) +{ +	if(start_index < 0 || start_index >= getChicletCount())  	{ -		S32 last_chiclet_right = (*mChicletList.rbegin())->getRect().mRight; -		S32 scroll_rect_width = mScrollArea->getRect().getWidth(); - -		offset = getChiclet(first_visible_chiclet)->getRect().getWidth() + CHICLET_PADDING; -		offset *= direction; -		// if after scrolling, the last chiclet will not be aligned to  -		// scroll area right side - align it. -		if( last_chiclet_right + offset < scroll_rect_width ) -		{ -			offset = scroll_rect_width - last_chiclet_right; -		} +		return;  	} -	chiclet_list_t::const_iterator it = mChicletList.begin(); +	chiclet_list_t::const_iterator it = mChicletList.begin() + start_index;  	for(;mChicletList.end() != it; ++it)  	{  		LLChiclet* chiclet = *it; @@ -669,31 +775,20 @@ void LLChicletPanel::scroll(ScrollDirection direction)  	}  } -S32 LLChicletPanel::getFirstVisibleChiclet() +void LLChicletPanel::scrollLeft()  { -	if(mChicletList.empty()) -		return -1; - -	for(int n = 0; n < getChicletCount(); ++n) +	if(canScrollLeft())  	{ -		LLRect rc = getChiclet(n)->getRect(); -		if(n > 0) -			rc.mLeft -= CHICLET_PADDING; -		// bottom left of scroll area is first visible point -		if(rc.pointInRect(0,0)) +		S32 offset = getScrollingOffset(); +		LLRect first_chiclet_rect = getChiclet(0)->getRect(); + +		// shift chiclets in case first chiclet is partially visible +		if(first_chiclet_rect.mLeft < 0 && first_chiclet_rect.mRight > 0)  		{ -			return n; +			offset = llabs(first_chiclet_rect.mLeft);  		} -	} -	return -1; -} - -void LLChicletPanel::scrollLeft() -{ -	if(canScrollLeft()) -	{ -		scroll(SCROLL_LEFT); +		scroll(offset);  		showScrollButtonsIfNeeded();  	} @@ -703,7 +798,18 @@ void LLChicletPanel::scrollRight()  {  	if(canScrollRight())  	{ -		scroll(SCROLL_RIGHT); +		S32 offset = - getScrollingOffset(); + +		S32 last_chiclet_right = (*mChicletList.rbegin())->getRect().mRight; +		S32 scroll_rect_width = mScrollArea->getRect().getWidth(); +		// if after scrolling, the last chiclet will not be aligned to  +		// scroll area right side - align it. +		if( last_chiclet_right + offset < scroll_rect_width ) +		{ +			offset = scroll_rect_width - last_chiclet_right; +		} + +		scroll(offset);  		showScrollButtonsIfNeeded();  	} @@ -719,7 +825,7 @@ void LLChicletPanel::onRightScrollClick()  	scrollRight();  } -boost::signals2::connection LLChicletPanel::setChicletClickCallback( +boost::signals2::connection LLChicletPanel::setChicletClickedCallback(  	const commit_callback_t& cb)  {  	return mCommitSignal.connect(cb); @@ -742,62 +848,83 @@ BOOL LLChicletPanel::handleScrollWheel(S32 x, S32 y, S32 clicks)  //////////////////////////////////////////////////////////////////////////  ////////////////////////////////////////////////////////////////////////// -LLTalkButton::LLTalkButton(const LLUICtrl::Params& p) +LLTalkButton::Params::Params() + : speak_button("speak_button") + , show_button("show_button") + , monitor("monitor") +{ +	speak_button.name("left"); +	speak_button.label("Speak"); +	speak_button.label_selected("Speak"); +	speak_button.font(LLFontGL::getFontSansSerifSmall()); +	speak_button.tab_stop(false); +	speak_button.is_toggle(true); +	speak_button.picture_style(true); +	speak_button.image_selected(LLUI::getUIImage("SegmentedBtn_Left_Selected")); +	speak_button.image_unselected(LLUI::getUIImage("SegmentedBtn_Left_Off")); + +	show_button.name("right"); +	show_button.label(LLStringUtil::null); +	show_button.rect(LLRect(0, 0, 20, 0)); +	show_button.tab_stop(false); +	show_button.is_toggle(true); +	show_button.picture_style(true); +	show_button.image_selected(LLUI::getUIImage("ComboButton_Selected")); +	show_button.image_unselected(LLUI::getUIImage("ComboButton_Off")); + +	monitor.name("monitor"); +	monitor.rect(LLRect(0, 10, 16, 0)); +} + +LLTalkButton::LLTalkButton(const Params& p)  : LLUICtrl(p) +, mPrivateCallPanel(NULL) +, mOutputMonitor(NULL) +, mSpeakBtn(NULL) +, mShowBtn(NULL)  { -	static S32 DROPDOWN_BTN_WIDTH = 20; - -	LLRect rc(p.rect); - -	LLButton::Params speak_params; -	speak_params.name("left"); -	speak_params.rect(LLRect(0,rc.getHeight(),rc.getWidth()-DROPDOWN_BTN_WIDTH,0)); -	speak_params.label("Speak"); -	speak_params.label_selected("Speak"); -	speak_params.font(LLFontGL::getFontSansSerifSmall()); -	speak_params.tab_stop(false); -	speak_params.is_toggle(true); -	speak_params.picture_style(true); -	speak_params.image_selected(LLUI::getUIImage("SegmentedBtn_Left_Selected"));  -	speak_params.image_unselected(LLUI::getUIImage("SegmentedBtn_Left_Off")); +	LLRect rect = p.rect(); +	LLRect speak_rect(0, rect.getHeight(), rect.getWidth(), 0); +	LLRect show_rect = p.show_button.rect(); +	show_rect.set(0, rect.getHeight(), show_rect.getWidth(), 0); + +	speak_rect.mRight -= show_rect.getWidth(); +	show_rect.mLeft = speak_rect.getWidth(); +	show_rect.mRight = rect.getWidth(); + +	LLButton::Params speak_params = p.speak_button; +	speak_params.rect(speak_rect);  	mSpeakBtn = LLUICtrlFactory::create<LLButton>(speak_params);  	addChild(mSpeakBtn);  	mSpeakBtn->setClickedCallback(boost::bind(&LLTalkButton::onClick_SpeakBtn, this)); -	mSpeakBtn->setToggleState(false); - -	LLButton::Params show_params; -	show_params.name("right"); -	show_params.rect(LLRect(rc.getWidth()-DROPDOWN_BTN_WIDTH,rc.getHeight(),rc.getWidth(),0)); -	show_params.label(""); -	show_params.tab_stop(false); -	show_params.is_toggle(true); -	show_params.picture_style(true); -	show_params.image_selected(LLUI::getUIImage("ComboButton_Selected")); -	show_params.image_unselected(LLUI::getUIImage("ComboButton_Off")); +	mSpeakBtn->setToggleState(FALSE); + +	LLButton::Params show_params = p.show_button; +	show_params.rect(show_rect);  	mShowBtn = LLUICtrlFactory::create<LLButton>(show_params);  	addChild(mShowBtn);  	mShowBtn->setClickedCallback(boost::bind(&LLTalkButton::onClick_ShowBtn, this)); -	mShowBtn->setToggleState(false); - -	mSpeakBtn->setToggleState(FALSE);  	mShowBtn->setToggleState(FALSE); -	rc = mSpeakBtn->getRect(); +	static const S32 MONITOR_RIGHT_PAD = 2; -	LLOutputMonitorCtrl::Params monitor_param; -	monitor_param.name("monitor"); -	monitor_param.draw_border(false); -	monitor_param.rect(LLRect(rc.getWidth()-20,18,rc.getWidth()-3,2)); -	monitor_param.visible(true); -	mOutputMonitor = LLUICtrlFactory::create<LLOutputMonitorCtrl>(monitor_param); -	// never show "muted" because you can't mute yourself -	mOutputMonitor->setIsMuted(false); +	LLRect monitor_rect = p.monitor.rect(); +	S32 monitor_height = monitor_rect.getHeight(); +	monitor_rect.mLeft = speak_rect.getWidth() - monitor_rect.getWidth() - MONITOR_RIGHT_PAD; +	monitor_rect.mRight = speak_rect.getWidth() - MONITOR_RIGHT_PAD; +	monitor_rect.mBottom = (rect.getHeight() / 2) - (monitor_height / 2); +	monitor_rect.mTop = monitor_rect.mBottom + monitor_height; +	LLOutputMonitorCtrl::Params monitor_params = p.monitor; +	monitor_params.draw_border(false); +	monitor_params.rect(monitor_rect); +	mOutputMonitor = LLUICtrlFactory::create<LLOutputMonitorCtrl>(monitor_params);  	mSpeakBtn->addChild(mOutputMonitor); -	mPrivateCallPanel = NULL; +	// never show "muted" because you can't mute yourself +	mOutputMonitor->setIsMuted(false);  }  LLTalkButton::~LLTalkButton() @@ -838,8 +965,7 @@ void LLTalkButton::onClick_ShowBtn()  	mPrivateCallPanel = new LLVoiceControlPanel;  	getRootView()->addChild(mPrivateCallPanel); - 	if(gBottomTray) - 		y = gBottomTray->getRect().getHeight() + mPrivateCallPanel->getRect().getHeight(); +	y = LLBottomTray::getInstance()->getRect().getHeight() + mPrivateCallPanel->getRect().getHeight();  	LLRect rect;  	rect.setLeftTopAndSize(x, y, mPrivateCallPanel->getRect().getWidth(), mPrivateCallPanel->getRect().getHeight()); @@ -857,3 +983,63 @@ void LLTalkButton::onClick_ShowBtn()  	mShowBtn->setToggleState(TRUE);  } + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +LLChicletNotificationCounterCtrl::LLChicletNotificationCounterCtrl(const Params& p) + : LLTextBox(p) + , mCounter(0) + , mInitialWidth(0) +{ +	mInitialWidth = getRect().getWidth(); +} + +void LLChicletNotificationCounterCtrl::setCounter(S32 counter) +{ +	mCounter = counter; + +	std::stringstream stream; +	stream << getCounter(); +	setText(stream.str()); +} + +LLRect LLChicletNotificationCounterCtrl::getRequiredRect() +{ +	LLRect rc; +	S32 text_width = getFont()->getWidth(getText()); + +	rc.mRight = rc.mLeft + llmax(text_width, mInitialWidth); +	 +	return rc; +} + +void LLChicletNotificationCounterCtrl::setValue(const LLSD& value) +{ +	if(value.isInteger()) +		setCounter(value.asInteger()); +} + +LLSD LLChicletNotificationCounterCtrl::getValue() const +{ +	return LLSD(getCounter()); +} + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +LLChicletAvatarIconCtrl::LLChicletAvatarIconCtrl(const Params& p) + : LLAvatarIconCtrl(p) +{ +} + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +LLChicletSpeakerCtrl::LLChicletSpeakerCtrl(const Params&p) + : LLIconCtrl(p) +{ +} diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h index ceda61adea..e467ec012a 100644 --- a/indra/newview/llchiclet.h +++ b/indra/newview/llchiclet.h @@ -33,134 +33,333 @@  #ifndef LL_LLCHICLET_H  #define LL_LLCHICLET_H +#include "llavatariconctrl.h"  #include "llpanel.h" +#include "lltextbox.h" +#include "lloutputmonitorctrl.h" -class LLTextBox; -class LLIconCtrl; -class LLAvatarIconCtrl;  class LLVoiceControlPanel; -class LLOutputMonitorCtrl; +class LLMenuGL; +/* + * Class for displaying amount of messages/notifications(unread). +*/ +class LLChicletNotificationCounterCtrl : public LLTextBox +{ +public: + +	struct Params :	public LLInitParam::Block<Params, LLTextBox::Params> +	{ +		Params() +		{}; +	}; + +	/* +	 * Sets number of notifications +	*/ +	virtual void setCounter(S32 counter); + +	/* +	 * Returns number of notifications +	*/ +	virtual S32 getCounter() const { return mCounter; } + +	/* +	 * Returns width, required to display amount of notifications in text form. +	 * Width is the only valid value. +	*/ +	/*virtual*/ LLRect getRequiredRect(); + +	/* +	 * Sets number of notifications using LLSD +	*/ +	/*virtual*/ void setValue(const LLSD& value); + +	/* +	 * Returns number of notifications wrapped in LLSD +	*/ +	/*virtual*/ LLSD getValue() const; + +protected: + +	LLChicletNotificationCounterCtrl(const Params& p); +	friend class LLUICtrlFactory; + +private: + +	S32 mCounter; +	S32 mInitialWidth; +}; + +/* + * Class for displaying avatar's icon. +*/ +class LLChicletAvatarIconCtrl : public LLAvatarIconCtrl +{ +public: + +	struct Params :	public LLInitParam::Block<Params, LLAvatarIconCtrl::Params> +	{ +		Params() +		{ +			draw_tooltip(FALSE); +			mouse_opaque(FALSE); +		}; +	}; + +protected: + +	LLChicletAvatarIconCtrl(const Params& p); +	friend class LLUICtrlFactory; +}; + +/* + * Class for displaying status of Voice Chat  +*/ +class LLChicletSpeakerCtrl : public LLIconCtrl +{ +public: + +	struct Params : public LLInitParam::Block<Params, LLIconCtrl::Params> +	{ +		Params(){}; +	}; +protected: + +	LLChicletSpeakerCtrl(const Params&p); +	friend class LLUICtrlFactory; +}; + +/* + * Base class for all chiclets. + */  class LLChiclet : public LLUICtrl  {  public:  	struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>  	{ -		Params(){}; +		Optional<bool> show_counter; + +		Params();  	}; -	virtual ~LLChiclet(); +	/*virtual*/ ~LLChiclet(); + +	/* +	 * Associates chat session id with chiclet. +	*/ +	virtual void setSessionId(const LLUUID& session_id) { mSessionId = session_id; } +	/* +	 * Returns associated chat session. +	*/ +	virtual const LLUUID& getSessionId() const { return mSessionId; } + +	/* +	 * Sets number of unread notifications. +	*/  	virtual void setCounter(S32 counter) = 0; +	/* +	 * Returns number of unread notifications. +	*/  	virtual S32 getCounter() = 0; -	virtual void setShowCounter(bool show) {mShowCounter = show;}; +	/* +	 * Sets show counter state. +	*/ +	virtual void setShowCounter(bool show) { mShowCounter = show; } +	/* +	 * Returns show counter state. +	*/  	virtual bool getShowCounter() {return mShowCounter;}; -	virtual boost::signals2::connection setLeftButtonClickCallback( +	/* +	 * Connects chiclet clicked event with callback. +	*/ +	/*virtual*/ boost::signals2::connection setLeftButtonClickCallback(  		const commit_callback_t& cb); +	typedef boost::function<void (LLChiclet* ctrl, const LLSD& param)>  +		chiclet_size_changed_callback_t; + +	/* +	 * Connects chiclets size changed event with callback. +	*/ +	virtual boost::signals2::connection setChicletSizeChangedCallback( +		const chiclet_size_changed_callback_t& cb); + +	/* +	 * Sets IM Session id using LLSD +	*/ +	/*virtual*/ LLSD getValue() const; + +	/* +	 * Returns IM Session id using LLSD +	*/ +	/*virtual*/ void setValue(const LLSD& value); +  protected:  	friend class LLUICtrlFactory;  	LLChiclet(const Params& p); -	virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); +	/* +	 * Notifies subscribers about click on chiclet. +	*/ +	/*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask); + +	/* +	 * Notifies subscribers about chiclet size changed event. +	*/ +	virtual void onChicletSizeChanged(); + +private: + +	LLUUID mSessionId; -protected: -	S32 mCounter;  	bool mShowCounter; + +	typedef boost::signals2::signal<void (LLChiclet* ctrl, const LLSD& param)>  +		chiclet_size_changed_signal_t; + +	chiclet_size_changed_signal_t mChicletSizeChangedSignal;  }; +/* +* Implements Instant Message chiclet. +* IMChiclet displays avatar's icon, number of unread messages(optional) +* and voice chat status(optional). +*/  class LLIMChiclet : public LLChiclet  {  public: -	static LLChiclet* create(const LLUUID& im_session_id = LLUUID::null); - -	void setCounter(S32); - -	S32 getCounter() {return mCounter;}; - -	const LLUUID& getIMSessionId() const {return mIMSessionId;}; +	struct Params : public LLInitParam::Block<Params, LLChiclet::Params> +	{ +		Optional<LLChicletAvatarIconCtrl::Params> avatar_icon; -	void setIMSessionId(const LLUUID& im_session_id) { mIMSessionId = im_session_id; } -	void setIMSessionName(const std::string& name); -	void setOtherParticipantId(const LLUUID& other_participant_id); +		Optional<LLChicletNotificationCounterCtrl::Params> unread_notifications; -	void setShowSpeaker(bool show); +		Optional<LLChicletSpeakerCtrl::Params> speaker; -	bool getShowSpeaker() {return mShowSpeaker;}; +		Optional<bool>	show_speaker; -	enum SpeakerStatus -	{ -		SPREAKER_ACTIVE, -		SPEAKER_IDLE +		Params();  	}; -	void setSpeakerStatus(SpeakerStatus status); - -	SpeakerStatus getSpeakerStatus() {return mSpeakerStatus;}; - -	~LLIMChiclet(); +	/*virtual*/ ~LLIMChiclet(); + +	/* +	 * Sets IM session name. This name will be displayed in chiclet tooltip. +	*/ +	virtual void setIMSessionName(const std::string& name); + +	/* +	 * Sets id of person/group user is chatting with. +	*/ +	virtual void setOtherParticipantId(const LLUUID& other_participant_id); + +	/* +	 * Shows/hides voice chat status control. +	*/ +	virtual void setShowSpeaker(bool show); + +	/* +	 * Returns voice chat status control visibility. +	*/ +	virtual bool getShowSpeaker() {return mShowSpeaker;}; + +	/* +	 * Sets number of unread messages. Will update chiclet's width if number text  +	 * exceeds size of counter and notify it's parent about size change. +	*/ +	/*virtual*/ void setCounter(S32); + +	/* +	 * Returns number of unread messages. +	*/ +	/*virtual*/ S32 getCounter() { return mCounterCtrl->getCounter(); } + +	/* +	 * Shows/hides number of unread messages. +	*/ +	/*virtual*/ void setShowCounter(bool show); + +	/* +	 * Draws border around chiclet. +	*/ +	/*virtual*/ void draw(); + +	/* +	 * Returns rect, required to display chiclet. +	 * Width is the only valid value. +	*/ +	/*virtual*/ LLRect getRequiredRect();  protected: -	LLIMChiclet(const LLChiclet::Params& p); -	friend class LLUICtrlFactory; -	S32 calcCounterWidth(); +	LLIMChiclet(const Params& p); +	friend class LLUICtrlFactory; -	//overrides -public: +	/* +	 * Creates chiclet popup menu. Will create P2P or Group IM Chat menu  +	 * based on other participant's id. +	*/ +	virtual void createPopupMenu(); -	void setShowCounter(bool show); +	/* +	 * Processes clicks on chiclet popup menu. +	*/ +	virtual void onMenuItemClicked(const LLSD& user_data); -	void draw(); +	/*  +	 * Enables/disables menus based on relationship with other participant. +	*/ +	virtual void updateMenuItems(); -	LLRect getRequiredRect(); +	/* +	 * Displays popup menu. +	*/ +	/*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);  protected: -	LLAvatarIconCtrl* mAvatar; -	LLTextBox* mCounterText; -	LLIconCtrl* mSpeaker; +	LLChicletAvatarIconCtrl* mAvatarCtrl; +	LLChicletNotificationCounterCtrl* mCounterCtrl; +	LLChicletSpeakerCtrl* mSpeakerCtrl; + +	LLMenuGL* mPopupMenu; -	LLUUID mIMSessionId;  	bool mShowSpeaker; -	SpeakerStatus mSpeakerStatus;  }; +/* + * Implements notification chiclet. Used to display total amount of unread messages  + * across all IM sessions, total amount of system notifications. +*/  class LLNotificationChiclet : public LLChiclet  {  public:  	struct Params : public LLInitParam::Block<Params, LLChiclet::Params>  	{ -		Optional<LLUIImage*>	 -			image_unselected, -			image_selected, -			image_hover_selected, -			image_hover_unselected, -			image_disabled_selected, -			image_disabled, -			image_overlay; - -		Optional<S32>			 -			label_left; +		Optional<LLButton::Params> button; + +		Optional<LLChicletNotificationCounterCtrl::Params> unread_notifications;  		Params();  	}; -	static LLChiclet* create(const Params& p); +	/*virtual*/ void setCounter(S32 counter); -	void setCounter(S32 counter); +	/*virtual*/S32 getCounter() { return mCounterCtrl->getCounter(); } -	S32 getCounter() {return mCounter;}; +	/*virtual*/ void setShowCounter(bool show);  	boost::signals2::connection setClickCallback(const commit_callback_t& cb); -	virtual ~ LLNotificationChiclet(); +	/*virtual*/ ~ LLNotificationChiclet();  protected:  	LLNotificationChiclet(const Params& p); @@ -168,112 +367,223 @@ protected:  protected:  	LLButton* mButton; -	LLTextBox* mCounterText; +	LLChicletNotificationCounterCtrl* mCounterCtrl;  }; +/* + * Storage class for all IM chiclets. Provides mechanism to display,  + * scroll, create, remove chiclets. +*/  class LLChicletPanel : public LLPanel  {  public:  	struct Params :	public LLInitParam::Block<Params, LLPanel::Params>  	{ -		Params(){}; -	}; +		Optional<S32> chiclet_padding, +					  scrolling_offset; -	~LLChicletPanel(); +		Optional<LLButton::Params> left_scroll_button, +								   right_scroll_button; -	LLChiclet* createChiclet(const LLUUID& im_session_id = LLUUID::null, S32 pos = 0); +		Params(); +	}; -	bool addChiclet(LLChiclet*, S32 pos); +	virtual ~LLChicletPanel(); -	LLChiclet* getChiclet(S32 pos); +	/* +	 * Creates chiclet and adds it to chiclet list. +	*/ +	template<class T> T* createChiclet(const LLUUID& session_id = LLUUID::null, S32 index = 0); -	LLChiclet* findIMChiclet(const LLUUID& im_session_id); +	/* +	 * Returns pointer to chiclet of specified type at specified index. +	*/ +	template<class T> T* getChiclet(S32 index); -	S32 getChicletCount() {return mChicletList.size();}; +	/* +	 * Returns pointer to LLChiclet at specified index. +	*/ +	LLChiclet* getChiclet(S32 index) { return getChiclet<LLChiclet>(index); } -	void removeChiclet(S32 pos); +	/* +	 * Searches a chiclet using IM session id. +	*/ +	template<class T> T* findChiclet(const LLUUID& im_session_id); -	void removeChiclet(LLChiclet*); - -	void removeIMChiclet(const LLUUID& im_session_id); +	/* +	 * Returns number of hosted chiclets. +	*/ +	S32 getChicletCount() {return mChicletList.size();}; +	/* +	 * Returns index of chiclet in list. +	*/ +	S32 getChicletIndex(const LLChiclet* chiclet); + +	/* +	 * Removes chiclet by index. +	*/ +	void removeChiclet(S32 index); + +	/* +	 * Removes chiclet by pointer. +	*/ +	void removeChiclet(LLChiclet* chiclet); + +	/* +	 * Removes chiclet by IM session id. +	*/ +	void removeChiclet(const LLUUID& im_session_id); + +	/* +	 * Removes all chiclets. +	*/  	void removeAll(); -	void scrollLeft(); - -	void scrollRight(); - -	void onLeftScrollClick(); - -	void onRightScrollClick(); - -	boost::signals2::connection setChicletClickCallback( +	boost::signals2::connection setChicletClickedCallback(  		const commit_callback_t& cb); -	void onChicletClick(LLUICtrl*ctrl,const LLSD¶m); - -	//overrides -public:  	/*virtual*/ BOOL postBuild(); -	void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE ); +	/* +	 * Reshapes controls and rearranges chiclets if needed. +	*/ +	/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE ); -	void draw(); +	/*virtual*/ void draw();  protected:  	LLChicletPanel(const Params&p);  	friend class LLUICtrlFactory; +	/* +	 * Adds chiclet to list and rearranges all chiclets. +	*/ +	bool addChiclet(LLChiclet*, S32 index); + +	/* +	 * Arranges chiclets. +	*/  	void arrange(); +	/* +	 * Returns true if chiclets can be scrolled right. +	*/  	bool canScrollRight(); +	/* +	* Returns true if chiclets can be scrolled left. +	*/  	bool canScrollLeft(); +	/* +	* Shows or hides chiclet scroll buttons if chiclets can or can not be scrolled. +	*/  	void showScrollButtonsIfNeeded(); -	S32 getFirstVisibleChiclet(); +	/* +	 * Shifts chiclets left or right. +	*/ +	void shiftChiclets(S32 offset, S32 start_index = 0); + +	/* +	 * Removes gaps between first chiclet and scroll area left side, +	 * last chiclet and scroll area right side. +	*/ +	void trimChiclets(); + +	/* +	 * Scrolls chiclets to right or left. +	*/ +	void scroll(S32 offset); + +	/* +	 * Verifies that chiclets can be scrolled left, then calls scroll() +	*/ +	void scrollLeft(); -	void reshapeScrollArea(S32 delta_width); +	/* +	 * Verifies that chiclets can be scrolled right, then calls scroll() +	*/ +	void scrollRight(); -	enum ScrollDirection -	{ -		SCROLL_LEFT = 1, -		SCROLL_RIGHT = -1 -	}; +	/* +	 * Callback for left scroll button clicked +	*/ +	void onLeftScrollClick(); + +	/* +	* Callback for right scroll button clicked +	*/ +	void onRightScrollClick(); -	void scroll(ScrollDirection direction); +	/* +	 * Callback for mouse wheel scrolled, calls scrollRight() or scrollLeft() +	*/ +	BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); + +	/* +	 * Notifies subscribers about click on chiclet. +	 * Do not place any code here, instead subscribe on event (see setChicletClickedCallback). +	*/ +	void onChicletClick(LLUICtrl*ctrl,const LLSD¶m); + +	/* +	 * Callback for chiclet size changed event, rearranges chiclets. +	*/ +	void onChicletSizeChanged(LLChiclet* ctrl, const LLSD& param);  	typedef std::vector<LLChiclet*> chiclet_list_t; +	/* +	 * Removes chiclet from scroll area and chiclet list. +	*/  	void removeChiclet(chiclet_list_t::iterator it); -	BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); +	S32 getChicletPadding() { return mChicletPadding; } + +	S32 getScrollingOffset() { return mScrollingOffset; }  protected:  	chiclet_list_t mChicletList; -	LLButton* mLeftScroll; -	LLButton* mRightScroll; +	LLButton* mLeftScrollButton; +	LLButton* mRightScrollButton;  	LLPanel* mScrollArea; -}; +	S32 mChicletPadding; +	S32 mScrollingOffset; +}; +/* + * Button displaying voice chat status. Displays voice chat options When clicked. +*/  class LLTalkButton : public LLUICtrl  {  public: -	virtual ~LLTalkButton(); +	struct Params :	public LLInitParam::Block<Params, LLUICtrl::Params> +	{ +		Optional<LLButton::Params>	speak_button, +									show_button; -	void onClick_SpeakBtn(); -	void onClick_ShowBtn(); +		Optional<LLOutputMonitorCtrl::Params> monitor; -	void draw(); +		Params(); +	}; + +	/*virtual*/ ~LLTalkButton(); + +	/*virtual*/ void draw();  protected:  	friend class LLUICtrlFactory; -	LLTalkButton(const LLUICtrl::Params& p); +	LLTalkButton(const Params& p); + +	void onClick_SpeakBtn(); + +	void onClick_ShowBtn();  private:  	LLButton*	mSpeakBtn; @@ -282,4 +592,68 @@ private:  	LLOutputMonitorCtrl* mOutputMonitor;  }; +template<class T>  +T* LLChicletPanel::createChiclet(const LLUUID& session_id /*= LLUUID::null*/, S32 index /*= 0*/) +{ +	typename T::Params params; +	T* chiclet = LLUICtrlFactory::create<T>(params); +	if(!chiclet) +	{ +		llwarns << "Could not create chiclet" << llendl; +		return NULL; +	} +	if(!addChiclet(chiclet, index)) +	{ +		delete chiclet; +		llwarns << "Could not add chiclet to chiclet panel" << llendl; +		return NULL; +	} + +	chiclet->setSessionId(session_id); + +	return chiclet; +} + +template<class T> +T* LLChicletPanel::findChiclet(const LLUUID& im_session_id) +{ +	if(im_session_id.isNull()) +	{ +		return NULL; +	} + +	chiclet_list_t::const_iterator it = mChicletList.begin(); +	for( ; mChicletList.end() != it; ++it) +	{ +		LLChiclet* chiclet = *it; + +		if(chiclet->getSessionId() == im_session_id) +		{ +			T* result = dynamic_cast<T*>(chiclet); +			if(!result && chiclet) +			{ +				llwarns << "Found chiclet but of wrong type " << llendl; +			} +			return result; +		} +	} +	return NULL; +} + +template<class T> T* LLChicletPanel::getChiclet(S32 index) +{ +	if(index < 0 || index >= getChicletCount()) +	{ +		return NULL; +	} + +	LLChiclet* chiclet = mChicletList[index]; +	T*result = dynamic_cast<T*>(chiclet); +	if(!result && chiclet) +	{ +		llwarns << "Found chiclet but of wrong type " << llendl; +	} +	return result; +} +  #endif // LL_LLCHICLET_H diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp index 92e2d3563a..00d4f80054 100644 --- a/indra/newview/llfavoritesbar.cpp +++ b/indra/newview/llfavoritesbar.cpp @@ -43,6 +43,8 @@  #include "llagent.h"  #include "llinventorybridge.h"  #include "llinventorymodel.h" +#include "llsidetray.h" +#include "lltoggleablemenu.h"  #include "llviewerinventory.h"  #include "llviewermenu.h"  #include "llviewermenu.h" @@ -69,41 +71,6 @@ struct LLFavoritesSort  	}  }; -class LLVisibilityTrackingMenuGL : public LLMenuGL -{ -protected: -	LLVisibilityTrackingMenuGL(const LLMenuGL::Params&); -	friend class LLUICtrlFactory; -public: -	virtual void onVisibilityChange (BOOL curVisibilityIn); -	void setChevronRect(const LLRect& rect) { mChevronRect = rect; } - -	bool getClosedByChevronClick() { return mClosedByChevronClick; } -	void resetClosedByChevronClick() { mClosedByChevronClick = false; } -	 -protected: -	bool mClosedByChevronClick; -	LLRect mChevronRect; -}; - -LLVisibilityTrackingMenuGL::LLVisibilityTrackingMenuGL(const LLMenuGL::Params& p) -:	LLMenuGL(p), -	mClosedByChevronClick(false) -{ -} - -//virtual -void LLVisibilityTrackingMenuGL::onVisibilityChange (BOOL curVisibilityIn) -{ -	S32 x,y; -	LLUI::getCursorPositionLocal(LLUI::getRootView(), &x, &y); - -	if (!curVisibilityIn && mChevronRect.pointInRect(x, y)) -	{ -		mClosedByChevronClick = true; -	} -} -  LLFavoritesBarCtrl::LLFavoritesBarCtrl(const LLFavoritesBarCtrl::Params& p)  :	LLUICtrl(p),  	mFont(p.font.isProvided() ? p.font() : LLFontGL::getFontSansSerifSmall()), @@ -269,10 +236,7 @@ void LLFavoritesBarCtrl::updateButtons(U32 bar_width)  				LLRect rect;  				rect.setOriginAndSize(bar_width - chevron_button_width - buttonHGap, buttonVGap, chevron_button_width, getRect().getHeight()-buttonVGap);  				chevron_button->setRect(rect); - -				S32 chevron_root_x, chevron_root_y; -				localPointToOtherView(rect.mLeft, rect.mBottom, &chevron_root_x, &chevron_root_y, LLUI::getRootView()); -				mChevronRect.setOriginAndSize(chevron_root_x, chevron_root_y, rect.getWidth(), rect.getHeight()); +				mChevronRect = rect;  			}  			return;  		} @@ -355,9 +319,7 @@ void LLFavoritesBarCtrl::updateButtons(U32 bar_width)  		addChildInBack(LLUICtrlFactory::create<LLButton> (bparams)); -		S32 chevron_root_x, chevron_root_y; -		localPointToOtherView(rect.mLeft, rect.mBottom, &chevron_root_x, &chevron_root_y, LLUI::getRootView()); -		mChevronRect.setOriginAndSize(chevron_root_x, chevron_root_y, rect.getWidth(), rect.getHeight()); +		mChevronRect = rect;  	}  } @@ -400,25 +362,25 @@ void LLFavoritesBarCtrl::showDropDownMenu()  		menu_p.visible(false);  		menu_p.scrollable(true); -		LLVisibilityTrackingMenuGL* menu = LLUICtrlFactory::create<LLVisibilityTrackingMenuGL>(menu_p); +		LLToggleableMenu* menu = LLUICtrlFactory::create<LLToggleableMenu>(menu_p);  		mPopupMenuHandle = menu->getHandle();  	} -	LLVisibilityTrackingMenuGL* menu = (LLVisibilityTrackingMenuGL*)mPopupMenuHandle.get(); +	LLToggleableMenu* menu = (LLToggleableMenu*)mPopupMenuHandle.get();  	if(menu)  	{ -		if (menu->getClosedByChevronClick()) +		if (menu->getClosedByButtonClick())  		{ -			menu->resetClosedByChevronClick(); +			menu->resetClosedByButtonClick();  			return;  		}  		if (menu->getVisible())  		{  			menu->setVisible(FALSE); -			menu->resetClosedByChevronClick(); +			menu->resetClosedByButtonClick();  			return;  		} @@ -449,7 +411,7 @@ void LLFavoritesBarCtrl::showDropDownMenu()  				menu->buildDrawLabels();  				menu->updateParent(LLMenuGL::sMenuContainer); -				menu->setChevronRect(mChevronRect); +				menu->setButtonRect(mChevronRect, this);  				LLMenuGL::showPopup(this, menu, getRect().getWidth() - menu->getRect().getWidth(), 0);  				return; @@ -514,7 +476,7 @@ void LLFavoritesBarCtrl::showDropDownMenu()  		menu->buildDrawLabels();  		menu->updateParent(LLMenuGL::sMenuContainer); -		menu->setChevronRect(mChevronRect); +		menu->setButtonRect(mChevronRect, this);  		LLMenuGL::showPopup(this, menu, getRect().getWidth() - max_width, 0);  	} @@ -565,7 +527,11 @@ void LLFavoritesBarCtrl::doToSelected(const LLSD& userdata)  	}  	else if (action == "about")  	{ -		LLFloaterReg::showInstance("preview_landmark", LLSD(mSelectedItemID), TAKE_FOCUS_YES); +		LLSD key; +		key["type"] = "landmark"; +		key["id"] = mSelectedItemID; + +		LLSideTray::getInstance()->showPanel("panel_places", key);  	}  	else if (action == "rename")  	{ diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h index 646e98cabb..a559692331 100644 --- a/indra/newview/llfavoritesbar.h +++ b/indra/newview/llfavoritesbar.h @@ -34,7 +34,7 @@  #define LL_LLFAVORITESBARCTRL_H  #include "lluictrl.h" -#include "lliconctrl.h" +  #include "llinventorymodel.h"  class LLFavoritesBarCtrl : public LLUICtrl, public LLInventoryObserver diff --git a/indra/newview/llfloaterchat.cpp b/indra/newview/llfloaterchat.cpp index 1bfb11e3ae..dd0df15348 100644 --- a/indra/newview/llfloaterchat.cpp +++ b/indra/newview/llfloaterchat.cpp @@ -54,7 +54,6 @@  //#include "lllineeditor.h"  #include "llmutelist.h"  //#include "llresizehandle.h" -#include "llchatbar.h"  #include "llrecentpeople.h"  #include "llstatusbar.h"  #include "llviewertexteditor.h" @@ -63,7 +62,6 @@  #include "llviewerwindow.h"  #include "llviewercontrol.h"  #include "lluictrlfactory.h" -#include "llchatbar.h"  #include "lllogchat.h"  #include "lltexteditor.h"  #include "lltextparser.h" @@ -99,7 +97,6 @@ LLFloaterChat::LLFloaterChat(const LLSD& seed)  	: LLFloater(seed),  	  mPanel(NULL)  { -	mFactoryMap["chat_panel"] = LLCallbackMap(createChatPanel, NULL);  	mFactoryMap["active_speakers_panel"] = LLCallbackMap(createSpeakersPanel, NULL);  	//Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this,"floater_chat_history.xml"); @@ -121,12 +118,6 @@ void LLFloaterChat::draw()  	childSetValue("toggle_active_speakers_btn", childIsVisible("active_speakers_panel")); -	LLChatBar* chat_barp = findChild<LLChatBar>("chat_panel", TRUE); -	if (chat_barp) -	{ -		chat_barp->refresh(); -	} -  	mPanel->refreshSpeakers();  	LLFloater::draw();  } @@ -135,12 +126,6 @@ BOOL LLFloaterChat::postBuild()  {  	mPanel = (LLPanelActiveSpeakers*)getChild<LLPanel>("active_speakers_panel"); -	LLChatBar* chat_barp = findChild<LLChatBar>("chat_panel", TRUE); -	if (chat_barp) -	{ -		chat_barp->setGestureCombo(getChild<LLComboBox>( "Gesture")); -	} -  	childSetCommitCallback("show mutes",onClickToggleShowMute,this); //show mutes  	childSetVisible("Chat History Editor with mute",FALSE);  	childSetAction("toggle_active_speakers_btn", onClickToggleActiveSpeakers, this); @@ -540,13 +525,6 @@ void* LLFloaterChat::createSpeakersPanel(void* data)  	return new LLPanelActiveSpeakers(LLLocalSpeakerMgr::getInstance(), TRUE);  } -//static -void* LLFloaterChat::createChatPanel(void* data) -{ -	LLChatBar* chatp = new LLChatBar(); -	return chatp; -} -  // static  void LLFloaterChat::onClickToggleActiveSpeakers(void* userdata)  { diff --git a/indra/newview/llfloaterchat.h b/indra/newview/llfloaterchat.h index 2bae4ea0c2..042d270aa6 100644 --- a/indra/newview/llfloaterchat.h +++ b/indra/newview/llfloaterchat.h @@ -82,7 +82,6 @@ public:  	static void chatFromLogFile(LLLogChat::ELogLineType type,std::string line, void* userdata);  	static void loadHistory();  	static void* createSpeakersPanel(void* data); -	static void* createChatPanel(void* data);  	static LLFloaterChat* getInstance(); // *TODO:Skinning Deprecate diff --git a/indra/newview/llfloaterfriends.cpp b/indra/newview/llfloaterfriends.cpp index 1e8129c7d3..1e8e7bad74 100644 --- a/indra/newview/llfloaterfriends.cpp +++ b/indra/newview/llfloaterfriends.cpp @@ -46,7 +46,7 @@  #include "llfloateravatarpicker.h"  #include "llviewerwindow.h"  #include "llbutton.h" -#include "llfriendactions.h" +#include "llavataractions.h"  #include "llinventorymodel.h"  #include "llnamelistctrl.h"  #include "llnotify.h" @@ -62,7 +62,7 @@  #include "lltextbox.h"  #include "llvoiceclient.h" -// *TODO: Move more common stuff to LLFriendActions? +// *TODO: Move more common stuff to LLAvatarActions?  //Maximum number of people you can select to do an operation on at once.  #define MAX_FRIEND_SELECT 20 @@ -546,7 +546,7 @@ void LLPanelFriends::onClickProfile(void* user_data)  	if(ids.size() > 0)  	{  		LLUUID agent_id = ids[0]; -		LLFriendActions::showProfile(agent_id); +		LLAvatarActions::showProfile(agent_id);  	}  } @@ -560,11 +560,11 @@ void LLPanelFriends::onClickIM(void* user_data)  	{  		if(ids.size() == 1)  		{ -			LLFriendActions::startIM(ids[0]); +			LLAvatarActions::startIM(ids[0]);  		}  		else  		{ -			LLFriendActions::startConference(ids); +			LLAvatarActions::startConference(ids);  		}  	}  } @@ -576,7 +576,7 @@ void LLPanelFriends::onPickAvatar(const std::vector<std::string>& names,  {  	if (names.empty()) return;  	if (ids.empty()) return; -	LLFriendActions::requestFriendshipDialog(ids[0], names[0]); +	LLAvatarActions::requestFriendshipDialog(ids[0], names[0]);  }  // static @@ -595,14 +595,14 @@ void LLPanelFriends::onClickAddFriend(void* user_data)  void LLPanelFriends::onClickRemove(void* user_data)  {  	LLPanelFriends* panelp = (LLPanelFriends*)user_data; -	LLFriendActions::removeFriendsDialog(panelp->getSelectedIDs()); +	LLAvatarActions::removeFriendsDialog(panelp->getSelectedIDs());  }  // static  void LLPanelFriends::onClickOfferTeleport(void* user_data)  {  	LLPanelFriends* panelp = (LLPanelFriends*)user_data; -	LLFriendActions::offerTeleport(panelp->getSelectedIDs()); +	LLAvatarActions::offerTeleport(panelp->getSelectedIDs());  }  // static diff --git a/indra/newview/llfloaterinspect.cpp b/indra/newview/llfloaterinspect.cpp index 972b3b9528..e26937e93f 100644 --- a/indra/newview/llfloaterinspect.cpp +++ b/indra/newview/llfloaterinspect.cpp @@ -36,7 +36,7 @@  #include "llfloaterreg.h"  #include "llfloatertools.h" -#include "llfriendactions.h" +#include "llavataractions.h"  #include "llcachename.h"  #include "llscrolllistctrl.h"  #include "llscrolllistitem.h" @@ -144,7 +144,7 @@ void LLFloaterInspect::onClickCreatorProfile()  		LLSelectNode* node = mObjectSelection->getFirstNode(&func);  		if(node)  		{ -			LLFriendActions::showProfile(node->mPermissions->getCreator()); +			LLAvatarActions::showProfile(node->mPermissions->getCreator());  		}  	}  } @@ -170,7 +170,7 @@ void LLFloaterInspect::onClickOwnerProfile()  		if(node)  		{  			const LLUUID& owner_id = node->mPermissions->getOwner(); -			LLFriendActions::showProfile(owner_id); +			LLAvatarActions::showProfile(owner_id);  		}  	}  } diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index f7e5eaadd3..4b665a789e 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -52,7 +52,7 @@  #include "llfloaterauction.h"  #include "llfloatergroups.h"  #include "llfloatergroupinfo.h" -#include "llfriendactions.h" +#include "llavataractions.h"  #include "lllineeditor.h"  #include "llnamelistctrl.h"  #include "llnotify.h" @@ -811,7 +811,7 @@ void LLPanelLandGeneral::onClickProfile(void* data)  	else  	{  		const LLUUID& avatar_id = parcel->getOwnerID(); -		LLFriendActions::showProfile(avatar_id); +		LLAvatarActions::showProfile(avatar_id);  	}  } @@ -1084,7 +1084,7 @@ void LLPanelLandObjects::onDoubleClickOwner(void *userdata)  		}  		else  		{ -			LLFriendActions::showProfile(owner_id); +			LLAvatarActions::showProfile(owner_id);  		}  	}  } diff --git a/indra/newview/llfloaterproperties.cpp b/indra/newview/llfloaterproperties.cpp index dc72b66949..efc273c6e5 100644 --- a/indra/newview/llfloaterproperties.cpp +++ b/indra/newview/llfloaterproperties.cpp @@ -44,7 +44,7 @@  #include "llbutton.h"  #include "llcheckboxctrl.h"  #include "llfloatergroupinfo.h" -#include "llfriendactions.h" +#include "llavataractions.h"  #include "llinventorymodel.h"  #include "lllineeditor.h"  #include "llradiogroup.h" @@ -611,7 +611,7 @@ void LLFloaterProperties::onClickCreator(void* data)  	if(!item) return;  	if(!item->getCreatorUUID().isNull())  	{ -		LLFriendActions::showProfile(item->getCreatorUUID()); +		LLAvatarActions::showProfile(item->getCreatorUUID());  	}  } @@ -628,7 +628,7 @@ void LLFloaterProperties::onClickOwner(void* data)  	}  	else  	{ -		LLFriendActions::showProfile(item->getPermissions().getOwner()); +		LLAvatarActions::showProfile(item->getPermissions().getOwner());  	}  } diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp index 66ed680984..8ec9eac196 100644 --- a/indra/newview/llgesturemgr.cpp +++ b/indra/newview/llgesturemgr.cpp @@ -50,7 +50,6 @@  // newview  #include "llagent.h" -#include "llchatbar.h"  #include "lldelayedgestureerror.h"  #include "llinventorymodel.h"  #include "llnotify.h" @@ -872,8 +871,7 @@ void LLGestureManager::runStep(LLMultiGesture* gesture, LLGestureStep* step)  			const BOOL animate = FALSE; -			if(gBottomTray) -				gBottomTray->sendChatFromViewer(chat_text, CHAT_TYPE_NORMAL, animate); +			LLBottomTray::getInstance()->sendChatFromViewer(chat_text, CHAT_TYPE_NORMAL, animate);  			gesture->mCurrentStep++;  			break; diff --git a/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp index 953d99c7ac..c71262c311 100644 --- a/indra/newview/llhudtext.cpp +++ b/indra/newview/llhudtext.cpp @@ -39,7 +39,6 @@  #include "llagent.h"  #include "llviewercontrol.h" -#include "llchatbar.h"  #include "llcriticaldamp.h"  #include "lldrawable.h"  #include "llfontgl.h" @@ -803,10 +802,6 @@ LLVector2 LLHUDText::updateScreenPos(LLVector2 &offset)  	LLRect world_rect = gViewerWindow->getVirtualWorldViewRect();  	S32 bottom = world_rect.mBottom + STATUS_BAR_HEIGHT; -	if (gChatBar && gChatBar->getVisible()) -	{ -		bottom += CHAT_BAR_HEIGHT; -	}  	LLVector2 screen_center;  	screen_center.mV[VX] = llclamp((F32)screen_pos_vec.mV[VX], (F32)world_rect.mLeft + mWidth * 0.5f, (F32)world_rect.mRight - mWidth * 0.5f); diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp index 9bf147584a..0652119f18 100644 --- a/indra/newview/llimpanel.cpp +++ b/indra/newview/llimpanel.cpp @@ -51,7 +51,7 @@  #include "llfloater.h"  #include "llfloatercall.h"  #include "llfloatergroupinfo.h" -#include "llfriendactions.h" +#include "llavataractions.h"  #include "llimview.h"  #include "llinventory.h"  #include "llinventorymodel.h" @@ -1569,7 +1569,7 @@ void LLFloaterIMPanel::onClickProfile( void* userdata )  	if (self->getOtherParticipantID().notNull())  	{ -		LLFriendActions::showProfile(self->getOtherParticipantID()); +		LLAvatarActions::showProfile(self->getOtherParticipantID());  	}  } diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index f8dd35e956..38335fe68f 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -51,7 +51,7 @@  #include "llresmgr.h"  #include "llfloaterchat.h"  #include "llfloaterchatterbox.h" -#include "llfriendactions.h" +#include "llavataractions.h"  #include "llhttpnode.h"  #include "llimpanel.h"  #include "llresizebar.h" diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 54d8208e9e..b705543e44 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -57,7 +57,7 @@  #include "llfloaterworldmap.h"  #include "llfocusmgr.h"  #include "llfolderview.h" -#include "llfriendactions.h" +#include "llavataractions.h"  #include "llgesturemgr.h"  #include "lliconctrl.h"  #include "llinventorymodel.h" @@ -88,6 +88,7 @@  #include "lltabcontainer.h"  #include "lluictrlfactory.h"  #include "llselectmgr.h" +#include "llsidetray.h"  #include "llfloateropenobject.h"  #include "lltrans.h" @@ -2825,7 +2826,15 @@ void LLLandmarkBridge::performAction(LLFolderView* folder, LLInventoryModel* mod  		LLViewerInventoryItem* item = getItem();  		if(item)  		{ -			LLFloaterReg::showInstance("preview_landmark", LLSD(item->getUUID()), TAKE_FOCUS_YES); +			LLSD key; +			key["type"] = "landmark"; +			key["id"] = item->getUUID(); + +			LLSideTray::getInstance()->showPanel("panel_places", key); +			 +			// Floater preview_landmark disabled,  +			// its functionality moved to Side Tray Places Panel  +			//LLFloaterReg::showInstance("preview_landmark", LLSD(item->getUUID()), TAKE_FOCUS_YES);  		}  	}  	else  @@ -2925,7 +2934,7 @@ void LLCallingCardBridge::performAction(LLFolderView* folder, LLInventoryModel*  		if (item && (item->getCreatorUUID() != gAgent.getID()) &&  			(!item->getCreatorUUID().isNull()))  		{ -			LLFriendActions::offerTeleport(item->getCreatorUUID()); +			LLAvatarActions::offerTeleport(item->getCreatorUUID());  		}  	}  	else LLItemBridge::performAction(folder, model, action); @@ -2967,7 +2976,7 @@ void LLCallingCardBridge::openItem()  	LLViewerInventoryItem* item = getItem();  	if(item && !item->getCreatorUUID().isNull())  	{ -		LLFriendActions::showProfile(item->getCreatorUUID()); +		LLAvatarActions::showProfile(item->getCreatorUUID());  	}  */  } @@ -4891,7 +4900,7 @@ void	LLCallingCardBridgeAction::doIt()  	LLViewerInventoryItem* item = getItem();  	if(item && item->getCreatorUUID().notNull())  	{ -		LLFriendActions::showProfile(item->getCreatorUUID()); +		LLAvatarActions::showProfile(item->getCreatorUUID());  	}  	LLInvFVBridgeAction::doIt(); diff --git a/indra/newview/llmenucommands.cpp b/indra/newview/llmenucommands.cpp index c0225ebfca..0c652621f4 100644 --- a/indra/newview/llmenucommands.cpp +++ b/indra/newview/llmenucommands.cpp @@ -44,7 +44,6 @@  #include "llagent.h"  #include "llcallingcard.h" -#include "llchatbar.h"  #include "llviewercontrol.h"  #include "llfirstuse.h"  #include "llfloaterchat.h" @@ -84,20 +83,20 @@ void handle_mouselook(void*)  void handle_chat(void*)  {  	// give focus to chatbar if it's open but not focused -	if (gBottomTray && gSavedSettings.getBOOL("ChatVisible") &&  -		gFocusMgr.childHasKeyboardFocus(gBottomTray->getChatBox())) +	if (gSavedSettings.getBOOL("ChatVisible") &&  +		gFocusMgr.childHasKeyboardFocus(LLBottomTray::getInstance()->getChatBox()))  	{ -		LLChatBar::stopChat(); +		LLBottomTray::stopChat();  	}  	else  	{ -		LLChatBar::startChat(NULL); +		LLBottomTray::startChat(NULL);  	}  }  void handle_slash_key(void*)  { -	// LLChatBar::startChat("/"); +	// LLBottomTray::startChat("/");  	//  	// Don't do this, it results in a double-slash in the input field.  	// Another "/" will be automatically typed for us, because the WM_KEYDOWN event @@ -107,5 +106,5 @@ void handle_slash_key(void*)  	// menu accelerators that put input focus into a field.   And Mac works  	// the same way.  JC -	LLChatBar::startChat(NULL); +	LLBottomTray::startChat(NULL);  } diff --git a/indra/newview/lloverlaybar.cpp b/indra/newview/lloverlaybar.cpp index d03e39280f..a24d1ed54a 100644 --- a/indra/newview/lloverlaybar.cpp +++ b/indra/newview/lloverlaybar.cpp @@ -41,7 +41,6 @@  #include "llrender.h"  #include "llagent.h"  #include "llbutton.h" -#include "llchatbar.h"  #include "llfocusmgr.h"  #include "llimview.h"  #include "llmediaremotectrl.h" @@ -92,12 +91,6 @@ void* LLOverlayBar::createVoiceRemote(void* userdata)  	return self->mVoiceRemote;  } -void* LLOverlayBar::createChatBar(void* userdata) -{ -	gChatBar = new LLChatBar(); -	return gChatBar; -} -  LLOverlayBar::LLOverlayBar()  	:	LLPanel(),  		mMediaRemote(NULL), @@ -111,7 +104,6 @@ LLOverlayBar::LLOverlayBar()  	mFactoryMap["media_remote"] = LLCallbackMap(LLOverlayBar::createMediaRemote, this);  	mFactoryMap["voice_remote"] = LLCallbackMap(LLOverlayBar::createVoiceRemote, this); -	mFactoryMap["chat_bar"] = LLCallbackMap(LLOverlayBar::createChatBar, this);  	LLUICtrlFactory::getInstance()->buildPanel(this, "panel_overlaybar.xml");  } diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp index e3c4167d73..868d4d9200 100644 --- a/indra/newview/llpanelavatar.cpp +++ b/indra/newview/llpanelavatar.cpp @@ -38,7 +38,7 @@  #include "llavatarconstants.h"  #include "llcallingcard.h"  #include "llcombobox.h" -#include "llfriendactions.h" +#include "llavataractions.h"  #include "llimview.h"  #include "lltexteditor.h"  #include "lltexturectrl.h" @@ -182,7 +182,7 @@ void LLPanelProfileTab::onAddFriend()  	{  		std::string name;  		gCacheName->getFullName(getAvatarId(),name); -		LLFriendActions::requestFriendshipDialog(getAvatarId(), name); +		LLAvatarActions::requestFriendshipDialog(getAvatarId(), name);  	}  } @@ -200,7 +200,7 @@ void LLPanelProfileTab::onTeleport()  {  	if(getAvatarId().notNull())  	{ -		LLFriendActions::offerTeleport(getAvatarId()); +		LLAvatarActions::offerTeleport(getAvatarId());  	}  } @@ -296,7 +296,7 @@ void LLPanelAvatarProfile::processProperties(void* data, EAvatarProcessorType ty  			bool online = avatar_data->flags & AVATAR_ONLINE; -			if(LLFriendActions::isFriend(avatar_data->avatar_id)) +			if(LLAvatarActions::isFriend(avatar_data->avatar_id))  			{  				// Online status NO could be because they are hidden  				// If they are a friend, we may know the truth! @@ -536,7 +536,7 @@ void LLPanelAvatarProfile::updateChildrenList()  		childSetVisible("partner_edit_link", false);  		//hide for friends -		childSetEnabled("add_friend", !LLFriendActions::isFriend(getAvatarId())); +		childSetEnabled("add_friend", !LLAvatarActions::isFriend(getAvatarId()));  		//need to update profile view on every activate  		mUpdated = false; @@ -730,5 +730,5 @@ void LLPanelAvatarNotes::onActivate(const LLUUID& id)  void LLPanelAvatarNotes::updateChildrenList()  {  	//hide for friends -	childSetEnabled("add_friend", !LLFriendActions::isFriend(getAvatarId())); +	childSetEnabled("add_friend", !LLAvatarActions::isFriend(getAvatarId()));  } diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp index bd4625ab11..df687ffb30 100644 --- a/indra/newview/llpanelclassified.cpp +++ b/indra/newview/llpanelclassified.cpp @@ -42,10 +42,12 @@  #include "lldispatcher.h"  #include "llfloaterreg.h"  #include "llparcel.h" +#include "lltabcontainer.h"  #include "message.h"  #include "llagent.h"  #include "llalertdialog.h" +#include "llavataractions.h"  #include "llbutton.h"  #include "llcheckboxctrl.h"  #include "llclassifiedflags.h" @@ -53,7 +55,6 @@  #include "llcommandhandler.h" // for classified HTML detail page click tracking  #include "llviewercontrol.h"  #include "lllineeditor.h" -#include "llfloateravatarinfo.h"  #include "llfloaterclassified.h"  #include "lltextbox.h"  #include "llcombobox.h" @@ -959,7 +960,7 @@ void LLPanelClassified::onClickMap(void* data)  void LLPanelClassified::onClickProfile(void* data)  {  	LLPanelClassified* self = (LLPanelClassified*)data; -	LLFloaterAvatarInfo::showFromDirectory(self->mCreatorID); +	LLAvatarActions::showProfile(self->mCreatorID);  	self->sendClassifiedClickMessage("profile");  } diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp index d495373cc4..6f8d161001 100644 --- a/indra/newview/llpanelgroupgeneral.cpp +++ b/indra/newview/llpanelgroupgeneral.cpp @@ -44,7 +44,7 @@  #include "llcheckboxctrl.h"  #include "llcombobox.h"  #include "lldbstrings.h" -#include "llfriendactions.h" +#include "llavataractions.h"  #include "lllineeditor.h"  #include "llnamebox.h"  #include "llnamelistctrl.h" @@ -375,7 +375,7 @@ void LLPanelGroupGeneral::openProfile(void* data)  		LLScrollListItem* selected = self->mListVisibleMembers->getFirstSelected();  		if (selected)  		{ -			LLFriendActions::showProfile(selected->getUUID()); +			LLAvatarActions::showProfile(selected->getUUID());  		}  	}  } diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp index 365f07e4b6..1c52c3cea4 100644 --- a/indra/newview/llpanelgrouproles.cpp +++ b/indra/newview/llpanelgrouproles.cpp @@ -37,7 +37,7 @@  #include "llagent.h"  #include "llbutton.h"  #include "llfloatergroupinvite.h" -#include "llfriendactions.h" +#include "llavataractions.h"  #include "lliconctrl.h"  #include "lllineeditor.h"  #include "llnamelistctrl.h" @@ -1289,7 +1289,7 @@ void LLPanelGroupMembersSubTab::handleMemberDoubleClick()  	LLScrollListItem* selected = mMembersList->getFirstSelected();  	if (selected)  	{ -		LLFriendActions::showProfile(selected->getUUID()); +		LLAvatarActions::showProfile(selected->getUUID());  	}  } diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp index 6fad582eee..453183ad74 100644 --- a/indra/newview/llpanellandmarks.cpp +++ b/indra/newview/llpanellandmarks.cpp @@ -268,3 +268,8 @@ void LLLandmarksPanel::onSelectorButtonClicked()  		LLSideTray::getInstance()->showPanel("panel_places", key);  	}  } + +void LLLandmarksPanel::setSelectedItem(const LLUUID& obj_id) +{ +	mInventoryPanel->setSelection(obj_id, FALSE); +} diff --git a/indra/newview/llpanellandmarks.h b/indra/newview/llpanellandmarks.h index 8889a99925..0b11270fb5 100644 --- a/indra/newview/llpanellandmarks.h +++ b/indra/newview/llpanellandmarks.h @@ -52,6 +52,7 @@ public:  	void onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action);  	void onSelectorButtonClicked(); +	void setSelectedItem(const LLUUID& obj_id);  private:  	LLInventoryPanel*			mInventoryPanel; diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp index 82c8f97d4d..d2879a675f 100644 --- a/indra/newview/llpanelpeople.cpp +++ b/indra/newview/llpanelpeople.cpp @@ -47,7 +47,7 @@  #include "llcallingcard.h"			// for LLAvatarTracker  #include "llfloateravatarpicker.h"  #include "llfloaterminiinspector.h" -#include "llfriendactions.h" +#include "llavataractions.h"  #include "llgroupactions.h"  #include "llgrouplist.h"  #include "llrecentpeople.h" @@ -508,17 +508,19 @@ void LLPanelPeople::updateButtons()  	if (group_tab_active)  	{ +		bool item_selected = mGroupList->getFirstSelected() != NULL;  		bool cur_group_active = true; -		selected_id = mGroupList->getCurrentID(); -		if (selected_id.notNull()) +		if (item_selected) +		{ +			selected_id = mGroupList->getCurrentID();  			cur_group_active = (gAgent.getGroupID() == selected_id); - -		bool item_selected = selected_id.notNull(); +		} +	  		LLPanel* groups_panel = mTabContainer->getCurrentPanel(); -		groups_panel->childSetEnabled("activate_btn",	!item_selected || !cur_group_active); // "none" or a non-active group selected +		groups_panel->childSetEnabled("activate_btn",	item_selected && !cur_group_active); // "none" or a non-active group selected  		groups_panel->childSetEnabled("plus_btn",		item_selected); -		groups_panel->childSetEnabled("minus_btn",		item_selected); +		groups_panel->childSetEnabled("minus_btn",		item_selected && selected_id.notNull());  	}  	else  	{ @@ -623,6 +625,8 @@ void LLPanelPeople::onSearchEdit(const std::string& search_string)  	filterFriendList();  	filterRecentList();  	updateGroupList(); + +	updateButtons();  }  void LLPanelPeople::onTabSelected(const LLSD& param) @@ -653,7 +657,7 @@ void LLPanelPeople::onAvatarListCommitted(LLAvatarList* list)  void LLPanelPeople::onViewProfileButtonClicked()  {  	LLUUID id = getCurrentItemID(); -	LLFriendActions::showProfile(id); +	LLAvatarActions::showProfile(id);  }  void LLPanelPeople::onAddFriendButtonClicked() @@ -663,7 +667,7 @@ void LLPanelPeople::onAddFriendButtonClicked()  	{  		std::string name;  		gCacheName->getFullName(id, name); -		LLFriendActions::requestFriendshipDialog(id, name); +		LLAvatarActions::requestFriendshipDialog(id, name);  	}  } @@ -680,7 +684,7 @@ void LLPanelPeople::onAddFriendWizButtonClicked()  void LLPanelPeople::onDeleteFriendButtonClicked()  { -	LLFriendActions::removeFriendDialog(getCurrentItemID()); +	LLAvatarActions::removeFriendDialog(getCurrentItemID());  }  void LLPanelPeople::onGroupInfoButtonClicked() @@ -702,7 +706,7 @@ void LLPanelPeople::onImButtonClicked()  	LLUUID id = getCurrentItemID();  	if (id.notNull())  	{ -		LLFriendActions::startIM(id); +		LLAvatarActions::startIM(id);  	}  } @@ -718,7 +722,7 @@ void LLPanelPeople::onAvatarPicked(  		void*)  {  	if (!names.empty() && !ids.empty()) -		LLFriendActions::requestFriendshipDialog(ids[0], names[0]); +		LLAvatarActions::requestFriendshipDialog(ids[0], names[0]);  }  bool LLPanelPeople::onFriendListUpdate(U32 changed_mask) @@ -765,7 +769,7 @@ void LLPanelPeople::onCallButtonClicked()  void LLPanelPeople::onTeleportButtonClicked()  { -	LLFriendActions::offerTeleport(getCurrentItemID()); +	LLAvatarActions::offerTeleport(getCurrentItemID());  }  void LLPanelPeople::onShareButtonClicked() diff --git a/indra/newview/llpanelpermissions.cpp b/indra/newview/llpanelpermissions.cpp index 9fdde9e757..96e8cbfd71 100644 --- a/indra/newview/llpanelpermissions.cpp +++ b/indra/newview/llpanelpermissions.cpp @@ -59,7 +59,7 @@  #include "lldbstrings.h"  #include "llfloatergroupinfo.h"  #include "llfloatergroups.h" -#include "llfriendactions.h" +#include "llavataractions.h"  #include "llnamebox.h"  #include "llviewercontrol.h"  #include "lluictrlfactory.h" @@ -811,7 +811,7 @@ void LLPanelPermissions::onClickCreator(void *data)  {  	LLPanelPermissions *self = (LLPanelPermissions *)data; -	LLFriendActions::showProfile(self->mCreatorID); +	LLAvatarActions::showProfile(self->mCreatorID);  }  // static @@ -827,7 +827,7 @@ void LLPanelPermissions::onClickOwner(void *data)  	}  	else  	{ -		LLFriendActions::showProfile(self->mOwnerID); +		LLAvatarActions::showProfile(self->mOwnerID);  	}  } diff --git a/indra/newview/llpanelpick.cpp b/indra/newview/llpanelpick.cpp index b1efb71abb..961c54d667 100644 --- a/indra/newview/llpanelpick.cpp +++ b/indra/newview/llpanelpick.cpp @@ -219,9 +219,6 @@ void LLPanelPick::setEditMode( BOOL edit_mode )  	mEditMode = edit_mode;  	// preserve data before killing controls -	std::string name = getPickName(); -	std::string desc = getPickDesc(); -	std::string location = getPickLocation();  	LLUUID snapshot_id = mSnapshotCtrl->getImageAssetID();  	LLRect old_rect = getRect(); @@ -242,9 +239,9 @@ void LLPanelPick::setEditMode( BOOL edit_mode )  	setRect(old_rect);  	// time to restore data -	setPickName(name); -	setPickDesc(desc); -	setPickLocation(location); +	setPickName(mName); +	setPickDesc(mDesc); +	setPickLocation(mLocation);  	mSnapshotCtrl->setImageAssetID(snapshot_id);  	updateButtons(); @@ -260,6 +257,9 @@ void LLPanelPick::setPickName(std::string name)  	{  		childSetWrappedText(XML_NAME, name);  	} +	 +	//preserving non-wrapped text for info/edit modes switching +	mName = name;  }  void LLPanelPick::setPickDesc(std::string desc) @@ -272,11 +272,17 @@ void LLPanelPick::setPickDesc(std::string desc)  	{  		childSetWrappedText(XML_DESC, desc);  	} + +	//preserving non-wrapped text for info/edit modes switching +	mDesc = desc;  }  void LLPanelPick::setPickLocation(std::string location)  {  	childSetWrappedText(XML_LOCATION, location); + +	//preserving non-wrapped text for info/edit modes switching +	mLocation = location;  }  std::string LLPanelPick::getPickName() diff --git a/indra/newview/llpanelpick.h b/indra/newview/llpanelpick.h index db943f4eaf..15b0d6c541 100644 --- a/indra/newview/llpanelpick.h +++ b/indra/newview/llpanelpick.h @@ -122,6 +122,11 @@ protected:  	LLUUID mParcelId;  	std::string mSimName; +	//These strings are used to keep non-wrapped text +	std::string mName; +	std::string mDesc; +	std::string mLocation; +  	commit_callback_t mBackCb;  }; diff --git a/indra/newview/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp index 5bbcf4207f..590eae555e 100644 --- a/indra/newview/llpanelplaceinfo.cpp +++ b/indra/newview/llpanelplaceinfo.cpp @@ -235,27 +235,46 @@ void LLPanelPlaceInfo::setInfoType(INFO_TYPE type)  	if (!mInfoPanel)  	    return; -	if (type == PLACE) +	switch(type)  	{ -		mCurrentTitle = getString("title_place"); -	} -	else -	{ -		mCurrentTitle = getString("title_landmark"); +		case PLACE: +			mCurrentTitle = getString("title_place"); + +			if (!isMediaPanelVisible()) +			{ +				mTitle->setText(mCurrentTitle); +			} +		break; + +		// Hide Media Panel if showing information about +		// a landmark or a teleport history item +		case LANDMARK: +			mCurrentTitle = getString("title_landmark"); + +			toggleMediaPanel(FALSE); +		break; +		 +		case TELEPORT_HISTORY: +			mCurrentTitle = getString("title_place"); +  +			toggleMediaPanel(FALSE); +		break;  	} +} + +BOOL LLPanelPlaceInfo::isMediaPanelVisible() +{ +	if (!mMediaPanel) +		return FALSE; -	if (mInfoPanel->getVisible()) -	{ -		mTitle->setText(mCurrentTitle); -	} +	return mMediaPanel->getVisible();  } -void LLPanelPlaceInfo::toggleMediaPanel() +void LLPanelPlaceInfo::toggleMediaPanel(BOOL visible)  {      if (!(mMediaPanel && mInfoPanel))          return; -    bool visible = mInfoPanel->getVisible();      if (visible)  	{  		mTitle->setText(getString("title_media")); diff --git a/indra/newview/llpanelplaceinfo.h b/indra/newview/llpanelplaceinfo.h index 8b00507ba0..7f98b6cb76 100644 --- a/indra/newview/llpanelplaceinfo.h +++ b/indra/newview/llpanelplaceinfo.h @@ -56,7 +56,8 @@ public:  	enum INFO_TYPE  	{  		PLACE, -		LANDMARK +		LANDMARK, +		TELEPORT_HISTORY  	};  	LLPanelPlaceInfo(); @@ -77,7 +78,8 @@ public:  	// sets a corresponding title and contents.  	void setInfoType(INFO_TYPE type); -	void toggleMediaPanel(); +	BOOL isMediaPanelVisible(); +	void toggleMediaPanel(BOOL visible);  	void displayItemInfo(const LLInventoryItem* pItem);  	/*virtual*/ void setErrorStatus(U32 status, const std::string& reason); diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp index f5e225c51b..c162a9ba33 100644 --- a/indra/newview/llpanelplaces.cpp +++ b/indra/newview/llpanelplaces.cpp @@ -44,8 +44,23 @@  #include "llpanelplaces.h"  #include "llpanellandmarks.h"  #include "llpanelteleporthistory.h" +#include "llsidetray.h" +#include "llviewerparcelmgr.h"  #include "llviewerregion.h" +LLPanelPlaces::LLParcelUpdateTimer::LLParcelUpdateTimer(F32 period) +:	LLEventTimer(period) +{ +}; + +// virtual +BOOL LLPanelPlaces::LLParcelUpdateTimer::tick() +{ +	LLSideTray::getInstance()->showPanel("panel_places", LLSD().insert("type", "agent")); +	 +	return TRUE; +} +  static LLRegisterPanelClassWrapper<LLPanelPlaces> t_places("panel_places");  LLPanelPlaces::LLPanelPlaces() @@ -57,6 +72,9 @@ LLPanelPlaces::LLPanelPlaces()  {  	gInventory.addObserver(this); +	LLViewerParcelMgr::getInstance()->setAgentParcelChangedCallback( +			boost::bind(&LLPanelPlaces::onAgentParcelChange, this)); +  	//LLUICtrlFactory::getInstance()->buildPanel(this, "panel_places.xml"); // Called from LLRegisterPanelClass::defaultPanelClassBuilder()  } @@ -90,7 +108,7 @@ BOOL LLPanelPlaces::postBuild()  		}  		// *TODO: Assign the action to an appropriate event. -		childSetAction("overflow_btn", boost::bind(&LLPanelPlaceInfo::toggleMediaPanel, mPlaceInfo), this); +		childSetAction("overflow_btn", boost::bind(&LLPanelPlaces::toggleMediaPanel, this), this);  	}  	//childSetAction("share_btn", boost::bind(&LLPanelPlaces::onShareButtonClicked, this), this); @@ -100,19 +118,14 @@ BOOL LLPanelPlaces::postBuild()  	return TRUE;  } -void LLPanelPlaces::draw() -{ -	LLPanel::draw(); -} -  void LLPanelPlaces::onOpen(const LLSD& key)  {  	if(key.size() == 0)  		return; -	togglePlaceInfoPanel(TRUE); -  	mPlaceInfoType = key["type"].asString(); +	 +	togglePlaceInfoPanel(TRUE);  	if (mPlaceInfoType == "agent")  	{ @@ -127,7 +140,8 @@ void LLPanelPlaces::onOpen(const LLSD& key)  	}  	else if (mPlaceInfoType == "landmark")  	{ -		LLInventoryItem* item = gInventory.getItem(key["id"].asUUID()); +		LLUUID item_uuid = key["id"].asUUID(); +		LLInventoryItem* item = gInventory.getItem(item_uuid);  		if (!item)  			return; @@ -138,6 +152,12 @@ void LLPanelPlaces::onOpen(const LLSD& key)  		if (!landmark)  			return; +		// Select Landmarks tab and set selection to requested landmark so that +		// context dependent Verbs buttons update properly. +		mTabContainer->selectFirstTab(); // Assume that first tab is Landmarks tab. +		LLLandmarksPanel* landmarks_panel = dynamic_cast<LLLandmarksPanel*>(mTabContainer->getCurrentPanel()); +		landmarks_panel->setSelectedItem(item_uuid); +  		LLUUID region_id;  		landmark->getRegionID(region_id);  		LLVector3d pos_global; @@ -145,7 +165,6 @@ void LLPanelPlaces::onOpen(const LLSD& key)  		mPlaceInfo->displayParcelInfo(landmark->getRegionPos(),  									  region_id,  									  pos_global); -  	}  	else if (mPlaceInfoType == "teleport_history")  	{ @@ -161,7 +180,7 @@ void LLPanelPlaces::onOpen(const LLSD& key)  		LLVector3 pos_local(region_x, region_y, (F32)pos_global.mdV[VZ]); -		mPlaceInfo->setInfoType(LLPanelPlaceInfo::PLACE); +		mPlaceInfo->setInfoType(LLPanelPlaceInfo::TELEPORT_HISTORY);  		mPlaceInfo->displayParcelInfo(pos_local,  									  hist_items[index].mRegionID,  									  pos_global); @@ -186,11 +205,11 @@ void LLPanelPlaces::onSearchEdit(const std::string& search_string)  void LLPanelPlaces::onTabSelected()  {  	mActivePanel = dynamic_cast<LLPanelPlacesTab*>(mTabContainer->getCurrentPanel()); -	if (mActivePanel) -	{ -		mActivePanel->onSearchEdit(mFilterSubString); -		mActivePanel->updateVerbs(); -	} +	if (!mActivePanel) +		return; + +	onSearchEdit(mFilterSubString);	 +	mActivePanel->updateVerbs();  }  void LLPanelPlaces::onShareButtonClicked() @@ -242,6 +261,13 @@ void LLPanelPlaces::onBackButtonClicked()  	togglePlaceInfoPanel(FALSE);  } +void LLPanelPlaces::toggleMediaPanel() +{ +	if (!mPlaceInfo) +			return; + +	mPlaceInfo->toggleMediaPanel(!mPlaceInfo->isMediaPanelVisible()); +}  void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible)  {  	if (!mPlaceInfo) @@ -250,6 +276,9 @@ void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible)  	mPlaceInfo->setVisible(visible);  	mSearchEditor->setVisible(!visible);  	mTabContainer->setVisible(!visible); +	 +	// Enable overflow button only for the information about agent's current location. +	getChild<LLButton>("overflow_btn")->setEnabled(visible && mPlaceInfoType == "agent");  	if (visible)  	{ @@ -275,7 +304,7 @@ void LLPanelPlaces::changed(U32 mask)  		mTabContainer->addTabPanel(  			LLTabContainer::TabPanelParams().  			panel(landmarks_panel). -			label("Landmarks"). +			label(getString("landmarks_tab_title")).  			insert_at(LLTabContainer::END));  	} @@ -287,7 +316,7 @@ void LLPanelPlaces::changed(U32 mask)  		mTabContainer->addTabPanel(  			LLTabContainer::TabPanelParams().  			panel(teleport_history_panel). -			label("Teleport History"). +			label(getString("teleport_history_tab_title")).  			insert_at(LLTabContainer::END));  	} @@ -299,3 +328,13 @@ void LLPanelPlaces::changed(U32 mask)  	// so remove the observer  	gInventory.removeObserver(this);  } + +void LLPanelPlaces::onAgentParcelChange() +{ +	if (mPlaceInfo->getVisible() && mPlaceInfoType == "agent") +	{ +		// Using timer to delay obtaining agent's coordinates +		// not to get the coordinates of previous parcel. +		new LLParcelUpdateTimer(.5); +	} +} diff --git a/indra/newview/llpanelplaces.h b/indra/newview/llpanelplaces.h index 89758fc34f..6fbb7562c9 100644 --- a/indra/newview/llpanelplaces.h +++ b/indra/newview/llpanelplaces.h @@ -32,6 +32,8 @@  #ifndef LL_LLPANELPLACES_H  #define LL_LLPANELPLACES_H +#include "lltimer.h" +  #include "llpanel.h"  #include "llinventory.h" @@ -50,7 +52,6 @@ public:  	virtual ~LLPanelPlaces();  	/*virtual*/ BOOL postBuild(); -	/*virtual*/ void draw();  	/*virtual*/ void changed(U32 mask);  	/*virtual*/ void onOpen(const LLSD& key); @@ -62,7 +63,9 @@ public:  	void onTeleportButtonClicked();  	void onShowOnMapButtonClicked();  	void onBackButtonClicked(); +	void toggleMediaPanel();  	void togglePlaceInfoPanel(BOOL visible); +	void onAgentParcelChange();  private:  	LLSearchEditor*			mSearchEditor; @@ -73,6 +76,17 @@ private:  	// Place information type currently shown in Information panel  	std::string				mPlaceInfoType; + +	// Helper class to delay the coordinates update  +	// when agent changes parcel +	class LLParcelUpdateTimer : public LLEventTimer +	{ +	public: +		LLParcelUpdateTimer(F32 period); +		virtual ~LLParcelUpdateTimer() {}; + +		virtual BOOL tick(); +	};  };  #endif //LL_LLPANELPLACES_H diff --git a/indra/newview/llsidetray.cpp b/indra/newview/llsidetray.cpp index f50f5a3db0..d8be1386c3 100644 --- a/indra/newview/llsidetray.cpp +++ b/indra/newview/llsidetray.cpp @@ -40,7 +40,7 @@  #include "llfocusmgr.h"  #include "llrootview.h" -#include "llcollapsiblectrl.h" +#include "llaccordionctrltab.h"  #include "llfloater.h" //for gFloaterView  #include "lliconctrl.h"//for Home tab icon @@ -664,7 +664,7 @@ void LLSideTray::createHomeTab()  		panel->setCommitCallback(boost::bind(&LLSideTray::onTabButtonClick, this, sidebar_tab->getName())); -		LLCollapsibleCtrl::Params panel_params;  +		LLAccordionCtrlTab::Params panel_params;   		panel_params.display_children(true);  		panel_params.collapsible(false);  		panel_params.header_visible(false); @@ -676,7 +676,7 @@ void LLSideTray::createHomeTab()  		panel_params.padding_bottom(5);  		panel_params.name(sidebar_tab->getTabTitle()); -		LLCollapsibleCtrl* ctrl = LLUICtrlFactory::create<LLCollapsibleCtrl>(panel_params); +		LLAccordionCtrlTab* ctrl = LLUICtrlFactory::create<LLAccordionCtrlTab>(panel_params);  		ctrl->setPanel(panel); diff --git a/indra/newview/llviewergesture.cpp b/indra/newview/llviewergesture.cpp index bbd34835ca..62ed861c86 100644 --- a/indra/newview/llviewergesture.cpp +++ b/indra/newview/llviewergesture.cpp @@ -39,7 +39,6 @@  #include "llviewerinventory.h"  #include "sound_ids.h"		// for testing -#include "llchatbar.h"  #include "llkeyboard.h"		// for key shortcuts for testing  #include "llinventorymodel.h"  #include "llvoavatar.h" @@ -133,11 +132,11 @@ void LLViewerGesture::doTrigger( BOOL send_chat )  		}  	} -	if (gBottomTray && send_chat && !mOutputString.empty()) +	if (send_chat && !mOutputString.empty())  	{  		// Don't play nodding animation, since that might not blend  		// with the gesture animation. -		gBottomTray->sendChatFromViewer(mOutputString, CHAT_TYPE_NORMAL, FALSE); +		LLBottomTray::getInstance()->sendChatFromViewer(mOutputString, CHAT_TYPE_NORMAL, FALSE);  	}  } diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp index ab5cdeba44..63234c2990 100644 --- a/indra/newview/llviewerkeyboard.cpp +++ b/indra/newview/llviewerkeyboard.cpp @@ -36,7 +36,7 @@  #include "llviewerkeyboard.h"  #include "llmath.h"  #include "llagent.h" -#include "llchatbar.h" +#include "llbottomtray.h"  #include "llviewercontrol.h"  #include "llfocusmgr.h"  #include "llmorphview.h" @@ -500,8 +500,7 @@ void stop_moving( EKeystate s )  void start_chat( EKeystate s )  {  	// start chat -	LLChatBar::startChat(NULL); -//	gChatBar->startChat(NULL); +	LLBottomTray::startChat(NULL);  }  void start_gesture( EKeystate s ) @@ -509,18 +508,16 @@ void start_gesture( EKeystate s )  	if (KEYSTATE_UP == s &&  		!(gFocusMgr.getKeyboardFocus() && gFocusMgr.getKeyboardFocus()->acceptsTextInput()))  	{ -		//TODO* remove DUMMY chatbar -		LLChatBar::startChat(NULL); -// 		if (gChatBar->getCurrentChat().empty()) -// 		{ -// 			// No existing chat in chat editor, insert '/' -// 			gChatBar->startChat("/"); -// 		} -// 		else -// 		{ -// 			// Don't overwrite existing text in chat editor -// 			gChatBar->startChat(NULL); -// 		} + 		if (LLBottomTray::getInstance()->getCurrentChat().empty()) + 		{ + 			// No existing chat in chat editor, insert '/' + 			LLBottomTray::getInstance()->startChat("/"); + 		} + 		else + 		{ + 			// Don't overwrite existing text in chat editor + 			LLBottomTray::getInstance()->startChat(NULL); + 		}  	}  } diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 63854abfea..e06e180ed5 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -131,7 +131,7 @@  #include "llfloaterworldmap.h"  #include "llfloatermemleak.h"  #include "llfasttimerview.h" -#include "llfriendactions.h" +#include "llavataractions.h"  #include "llmemoryview.h"  #include "llgivemoney.h"  #include "llgroupmgr.h" @@ -3607,7 +3607,7 @@ bool LLHaveCallingcard::operator()(LLInventoryCategory* cat,  BOOL is_agent_mappable(const LLUUID& agent_id)  { -	return (LLFriendActions::isFriend(agent_id) && +	return (LLAvatarActions::isFriend(agent_id) &&  		LLAvatarTracker::instance().getBuddyInfo(agent_id)->isOnline() &&  		LLAvatarTracker::instance().getBuddyInfo(agent_id)->isRightGrantedFrom(LLRelationship::GRANT_MAP_LOCATION)  		); @@ -3620,7 +3620,7 @@ class LLAvatarEnableAddFriend : public view_listener_t  	bool handleEvent(const LLSD& userdata)  	{  		LLVOAvatar* avatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()); -		bool new_value = avatar && !LLFriendActions::isFriend(avatar->getID()); +		bool new_value = avatar && !LLAvatarActions::isFriend(avatar->getID());  		return new_value;  	}  }; @@ -3644,7 +3644,7 @@ void request_friendship(const LLUUID& dest_id)  		}  		if (!fullname.empty())  		{ -			LLFriendActions::requestFriendshipDialog(dest_id, fullname); +			LLAvatarActions::requestFriendshipDialog(dest_id, fullname);  		}  		else  		{ @@ -5376,7 +5376,7 @@ class LLAvatarAddFriend : public view_listener_t  	bool handleEvent(const LLSD& userdata)  	{  		LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() ); -		if(avatar && !LLFriendActions::isFriend(avatar->getID())) +		if(avatar && !LLAvatarActions::isFriend(avatar->getID()))  		{  			request_friendship(avatar->getID());  		} @@ -5720,7 +5720,7 @@ class LLShowAgentProfile : public view_listener_t  		LLVOAvatar* avatar = find_avatar_from_object(agent_id);  		if (avatar)  		{ -			LLFriendActions::showProfile(avatar->getID()); +			LLAvatarActions::showProfile(avatar->getID());  		}  		return true;  	} diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 039faa2bf9..1468b376b0 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -78,7 +78,6 @@  #include "llagent.h"  #include "llalertdialog.h"  #include "llbox.h" -#include "llchatbar.h"  #include "llconsole.h"  #include "llviewercontrol.h"  #include "llcylinder.h" @@ -1557,13 +1556,12 @@ void LLViewerWindow::initWorldUI()  	getRootView()->sendChildToFront(gSnapshotFloaterView);  	// new bottom panel -	gBottomTray = new LLBottomTray(); -	LLRect rc = gBottomTray->getRect(); +	LLRect rc = LLBottomTray::getInstance()->getRect();  	rc.mLeft = 0;  	rc.mRight = mRootView->getRect().getWidth(); -	mRootView->addChild(gBottomTray); -	gBottomTray->reshape(rc.getWidth(),rc.getHeight(),FALSE); -	gBottomTray->setRect(rc); +	mRootView->addChild(LLBottomTray::getInstance()); +	LLBottomTray::getInstance()->reshape(rc.getWidth(),rc.getHeight(),FALSE); +	LLBottomTray::getInstance()->setRect(rc);  	// View for hover information  	LLHoverView::Params hvp; @@ -1595,9 +1593,9 @@ void LLViewerWindow::initWorldUI()  	LLRect floater_view_rect = gFloaterView->getRect();  	LLRect notify_view_rect = gNotifyBoxView->getRect();  	floater_view_rect.mTop -= NAVIGATION_BAR_HEIGHT; -	floater_view_rect.mBottom += gBottomTray->getRect().getHeight(); +	floater_view_rect.mBottom += LLBottomTray::getInstance()->getRect().getHeight();  	notify_view_rect.mTop -= NAVIGATION_BAR_HEIGHT; -	notify_view_rect.mBottom += gBottomTray->getRect().getHeight(); +	notify_view_rect.mBottom += LLBottomTray::getInstance()->getRect().getHeight();  	gFloaterView->setRect(floater_view_rect);  	gNotifyBoxView->setRect(notify_view_rect); @@ -1854,10 +1852,10 @@ void LLViewerWindow::reshape(S32 width, S32 height)  // Hide normal UI when a logon fails  void LLViewerWindow::setNormalControlsVisible( BOOL visible )  { -	if(gBottomTray) +	if(LLBottomTray::instanceExists())  	{ -		gBottomTray->setVisible(visible); -		gBottomTray->setEnabled(visible); +		LLBottomTray::getInstance()->setVisible(visible); +		LLBottomTray::getInstance()->setEnabled(visible);  	}  	if ( gMenuBarView ) @@ -2165,11 +2163,11 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)  	LLUICtrl* keyboard_focus = gFocusMgr.getKeyboardFocus();  	if( keyboard_focus )  	{ -		LLLineEditor* chat_bar = gBottomTray ? gBottomTray->getChatBox() : NULL; +		LLLineEditor* chat_editor = LLBottomTray::instanceExists() ? LLBottomTray::getInstance()->getChatBox() : NULL;  		// arrow keys move avatar while chatting hack -		if (chat_bar && chat_bar->hasFocus()) +		if (chat_editor && chat_editor->hasFocus())  		{ -			if (chat_bar->getText().empty() || gSavedSettings.getBOOL("ArrowKeysMoveAvatar")) +			if (chat_editor->getText().empty() || gSavedSettings.getBOOL("ArrowKeysMoveAvatar"))  			{  				switch(key)  				{ @@ -2399,10 +2397,14 @@ void LLViewerWindow::updateUI()  	updateWorldViewRect(); -	if(gBottomTray && LLSideTray::instanceCreated()) +	if(LLBottomTray::instanceExists() && LLSideTray::instanceCreated())  	{ -		S32 delta = llround((F32)LLSideTray::getInstance()->getTrayWidth() * mDisplayScale.mV[VX]); -		gBottomTray->updateRightPosition(mWindowRect.mRight - delta); +		S32 delta = 0; +		if(LLSideTray::getInstance()->getVisible()) +		{ +			delta = llround((F32)LLSideTray::getInstance()->getTrayWidth() * mDisplayScale.mV[VX]); +		} +		LLBottomTray::getInstance()->updateRightPosition(mWindowRect.mRight - delta);  	}  	LLView::sMouseHandlerMessage.clear(); @@ -2939,19 +2941,6 @@ void LLViewerWindow::updateKeyboardFocus()  	if(LLSideTray::instanceCreated())//just getInstance will create sidetray. we don't want this  		LLSideTray::getInstance()->highlightFocused(); - -	//NOTE: this behavior is no longer desirable with a permanently visible chat batr -	// which would *always* steal focus, disallowing navigation of the world via WASD controls --RN -	 -	//if (gSavedSettings.getBOOL("ChatBarStealsFocus")  -	//	&& gChatBar  -	//	&& gFocusMgr.getKeyboardFocus() == NULL  -	//	&& gChatBar->isInVisibleChain()) -	//{ -	//	gChatBar->startChat(NULL); -	//} - -  }  void LLViewerWindow::updateWorldViewRect(bool use_full_window) @@ -4912,8 +4901,8 @@ S32 LLViewerWindow::getChatConsoleBottomPad()  {  	S32 offset = 0; -	if(gBottomTray) -		offset += gBottomTray->getRect().getHeight(); +	if(LLBottomTray::instanceExists()) +		offset += LLBottomTray::getInstance()->getRect().getHeight();  	return offset;  } diff --git a/indra/newview/skins/default/xui/en/accordion_drag.xml b/indra/newview/skins/default/xui/en/accordion_drag.xml new file mode 100644 index 0000000000..94839a7593 --- /dev/null +++ b/indra/newview/skins/default/xui/en/accordion_drag.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel  border_thickness="2" visible ="true" name="splitter_drag" +  width="100" +  height="5" +  left="50" +  top="50" +  follows="left|bottom|right" background_visible="true" label="splitter_drag" title=""> +</panel> diff --git a/indra/newview/skins/default/xui/en/menu_imchiclet_group.xml b/indra/newview/skins/default/xui/en/menu_imchiclet_group.xml new file mode 100644 index 0000000000..542e319792 --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_imchiclet_group.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<menu + height="101" + layout="topleft" + left="100" + mouse_opaque="false" + name="IMChiclet Group Menu" + top="724" + visible="false" + width="128"> +    <menu_item_call +     label="Chat..." +     layout="topleft" +     name="Chat"> +        <menu_item_call.on_click +         function="IMChicletMenu.Action" +         parameter="group chat" /> +    </menu_item_call> +    <menu_item_call +     label="Info..." +     layout="topleft" +     name="Show Profile"> +        <menu_item_call.on_click +         function="IMChicletMenu.Action" +         parameter="info" /> +    </menu_item_call> +</menu> diff --git a/indra/newview/skins/default/xui/en/menu_imchiclet_p2p.xml b/indra/newview/skins/default/xui/en/menu_imchiclet_p2p.xml new file mode 100644 index 0000000000..bad6e1e212 --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_imchiclet_p2p.xml @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<menu + height="101" + layout="topleft" + left="100" + mouse_opaque="false" + name="IMChiclet P2P Menu" + top="724" + visible="false" + width="128"> +    <menu_item_call +     label="Show Profile..." +     layout="topleft" +     name="Show Profile"> +        <menu_item_call.on_click +         function="IMChicletMenu.Action" +         parameter="profile" /> +    </menu_item_call> +    <menu_item_call +     label="Send IM..." +     layout="topleft" +     name="Send IM"> +        <menu_item_call.on_click +         function="IMChicletMenu.Action" +         parameter="im" /> +    </menu_item_call> +    <menu_item_call +     label="Add Friend..." +     layout="topleft" +     name="Add Friend"> +        <menu_item_call.on_click +         function="IMChicletMenu.Action" +         parameter="add" /> +    </menu_item_call> +    <menu_item_call +     label="Remove Friend..." +     layout="topleft" +     name="Remove Friend"> +        <menu_item_call.on_click +         function="IMChicletMenu.Action" +         parameter="remove" /> +    </menu_item_call> +</menu> diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index ef6f2237ad..d890edcfed 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -3068,9 +3068,10 @@ Are you sure you want to teleport?     type="alertmodal">  Teleport to [PICK]?      <usetemplate -     name="okcancelbuttons" +     ignoretext="When teleporting from double-clicking a pick" +     name="okcancelignore"       notext="Cancel" -     yestext="OK"/> +     yestext="Teleport"/>    </notification>    <notification diff --git a/indra/newview/skins/default/xui/en/panel_bottomtray.xml b/indra/newview/skins/default/xui/en/panel_bottomtray.xml index 6c4f47a34f..7006203dcd 100644 --- a/indra/newview/skins/default/xui/en/panel_bottomtray.xml +++ b/indra/newview/skins/default/xui/en/panel_bottomtray.xml @@ -11,10 +11,6 @@   top="28"   border_visible="true"   width="1000"> -    <panel.string -     name="gesture_label"> -        Gestures -    </panel.string>      <layout_stack       border_size="0"       follows="left|right|bottom|top" @@ -53,7 +49,7 @@               layout="topleft"               left="0"               name="chat_box" -				     right="-39" +             right="-39"               top="3"               width="250" />              <button follows="right" width="36" top="3" left="214" resize="false" @@ -131,7 +127,7 @@           width="90"           top="0"           min_width="90"> -            <combo_box +            <gesture_combo_box               bottom="22"               follows="right"               height="20" @@ -192,8 +188,8 @@           min_height="28"           top="0"           name="chiclet_list_panel" -         width="250" -         min_width="100"> +         width="150" +         min_width="70">              <chiclet_panel               follows="left|right"               height="25" @@ -201,7 +197,9 @@               left="0"               name="chiclet_list"               top="1" -             width="250" /> +             chiclet_padding="3" +             scrolling_offset="40" +             width="150" />          </layout_panel>          <icon           auto_resize="false" @@ -227,13 +225,19 @@              <chiclet_notification               follows="right"               height="25" -             image_selected="im_notifications.tga" -             image_unselected="im_notifications.tga"               layout="topleft"               left="0"               name="im_well"               top="1" -             width="40" > +             width="40"> +              <button +               image_selected="im_notifications.tga" +               image_unselected="im_notifications.tga"/> +              <unread_notifications +               width="20" +               height="20" +               left="18" +               top="23"/>  			  <chiclet_notification.commit_callback  				 function="Notification.Show"  				 parameter="ClickUnimplemented" /> @@ -254,7 +258,7 @@           auto_resize="false"           bevel_style="in"           follows="left|right" -         height="30" +         height="28"           layout="topleft"           left="270"           name="well_separator" @@ -284,13 +288,19 @@              <chiclet_notification               follows="right"               height="25" -             image_selected="bottom_tray_sys_notifications.tga" -             image_unselected="bottom_tray_sys_notifications.tga"               layout="topleft"               left="0"               name="sys_well"               top="1" -             width="48" > +             width="48"> +              <button +               image_selected="bottom_tray_sys_notifications.tga" +               image_unselected="bottom_tray_sys_notifications.tga"/> +              <unread_notifications +               width="20" +               height="20" +               left="22" +               top="23"/>  			  <chiclet_notification.commit_callback  				 function="Notification.Show"  				 parameter="ClickUnimplemented" /> diff --git a/indra/newview/skins/default/xui/en/panel_edit_pick.xml b/indra/newview/skins/default/xui/en/panel_edit_pick.xml index a017e7398e..9cc3a00696 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_pick.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_pick.xml @@ -77,6 +77,7 @@           height="20"           layout="topleft"           left="10" +         max_length="63"           name="pick_name"           right="-10"           text_color="black" diff --git a/indra/newview/skins/default/xui/en/panel_pick_list_item.xml b/indra/newview/skins/default/xui/en/panel_pick_list_item.xml index 6a819d0ef4..686dc931d3 100644 --- a/indra/newview/skins/default/xui/en/panel_pick_list_item.xml +++ b/indra/newview/skins/default/xui/en/panel_pick_list_item.xml @@ -32,7 +32,8 @@       name="picture_name"       text_color="black"       top="5" -     width="170" /> +     use_ellipses="true" +     width="170"/>      <text       follows="right"       font="SansSerif" diff --git a/indra/newview/skins/default/xui/en/panel_places.xml b/indra/newview/skins/default/xui/en/panel_places.xml index 2aa566543f..366c3ecf6c 100644 --- a/indra/newview/skins/default/xui/en/panel_places.xml +++ b/indra/newview/skins/default/xui/en/panel_places.xml @@ -12,6 +12,14 @@   name="places panel"   top="400"   width="355"> +    <panel.string +     name="landmarks_tab_title"> +        Landmarks +    </panel.string> +    <panel.string +     name="teleport_history_tab_title"> +        Teleport History +    </panel.string>      <search_editor       follows="left|top|right"       height="16" @@ -73,7 +81,7 @@       top_delta="0"       width="60" />      <button -     enabled="true" +     enabled="false"       follows="bottom|right"       font="SansSerifSmallBold"       height="25" diff --git a/indra/newview/skins/default/xui/en/panel_side_tray.xml b/indra/newview/skins/default/xui/en/panel_side_tray.xml index feba6a7d02..01052f4bbe 100644 --- a/indra/newview/skins/default/xui/en/panel_side_tray.xml +++ b/indra/newview/skins/default/xui/en/panel_side_tray.xml @@ -17,7 +17,7 @@      background_visible="true"       bg_opaque_color="0.5 0.5 0.5 1.0"    > -    <collapsible_ctrl  +    <accordionctrl_tab         name="people_accordion"         title="People"         collapsable="true"  @@ -35,7 +35,7 @@          label="People"           border="true"         /> -    </collapsible_ctrl> +    </accordionctrl_tab>    </sidetray_tab>    <!-- *TODO Vadim: isn't the sidetray_tab "label" attribute redundant since we have "tab_title" ? -->    <sidetray_tab  @@ -48,7 +48,7 @@      background_visible="true"       bg_opaque_color="0.5 0.5 0.5 1.0"    > -    <collapsible_ctrl  +    <accordionctrl_tab         name="places_accordian"         title="Places"         collapsable="true"  @@ -63,7 +63,7 @@          label="Places"           border="true"        /> -    </collapsible_ctrl> +    </accordionctrl_tab>    </sidetray_tab>    <sidetray_tab  @@ -75,7 +75,7 @@      background_visible="true"       bg_opaque_color="0.5 0.5 0.5 1.0"    > -    <collapsible_ctrl  +    <accordionctrl_tab         name="me_accordion"         title="Me"         collapsable="false"  @@ -90,7 +90,7 @@          label="Me"           border="true"        /> -    </collapsible_ctrl> +    </accordionctrl_tab>    </sidetray_tab>    <!-- @@ -103,7 +103,7 @@      tab_title="Groups"      description="Manage Groups."    > -    <collapsible_ctrl  +    <accordionctrl_tab         name="group_accordion"         title="Group General"        expanded="true" @@ -119,12 +119,12 @@          label="Group"           border="true"        /> -    </collapsible_ctrl> -     <collapsible_ctrl  +    </accordionctrl_tab> +     <accordionctrl_tab         name="groupland_accordion"         title="Group Land and Money"        expanded="false" -      collapsable="true"  +      collapsible="true"         min_width="200"         min_height="200"         header_visible="true" @@ -136,12 +136,12 @@          label="Group"           border="true"        /> -    </collapsible_ctrl> -     <collapsible_ctrl  +    </accordionctrl_tab> +     <accordionctrl_tab         name="groupnotices_accordion"         title="Group Notices"        expanded="false" -      collapsable="true"  +      collapsible="true"         min_width="200"         min_height="200"         header_visible="true" @@ -153,12 +153,12 @@          label="Group"           border="true"        /> -    </collapsible_ctrl> -     <collapsible_ctrl  +    </accordionctrl_tab> +     <accordionctrl_tab         name="grouproles_accordion"         title="Group Roles"        expanded="false" -      collapsable="true"  +      collapsible="true"         min_width="200"         min_height="200"         header_visible="true" @@ -170,7 +170,7 @@          label="Group"           border="true"        /> -    </collapsible_ctrl> +    </accordionctrl_tab>    </sidetray_tab>   @@ -184,7 +184,7 @@      tab_title="Previews"      description="Previews."    > -    <collapsible_ctrl  +    <accordionctrl_tab         name="floater_preview_animation"         title="Preview Animation"         collapsable="true" @@ -202,8 +202,8 @@          label="Preview_Animation"           border="true"         /> -    </collapsible_ctrl> -    <collapsible_ctrl  +    </accordionctrl_tab> +    <accordionctrl_tab         name="floater_preview_gesture"         title="Preview Gesture"         collapsable="true" @@ -221,8 +221,8 @@          label="Preview_Gesture"           border="true"         /> -    </collapsible_ctrl> -    <collapsible_ctrl  +    </accordionctrl_tab> +    <accordionctrl_tab         name="floater_preview_existing_landmark"         title="Preview Existing Landmark"         collapsable="true" @@ -240,8 +240,8 @@          label="Preview_Existing_Landmark"           border="true"         /> -    </collapsible_ctrl> -    <collapsible_ctrl  +    </accordionctrl_tab> +    <accordionctrl_tab         name="floater_preview_sound"         title="Preview Sound"         collapsable="true" @@ -259,8 +259,8 @@          label="Preview_Sound"           border="true"         /> -    </collapsible_ctrl> -    <collapsible_ctrl  +    </accordionctrl_tab> +    <accordionctrl_tab         name="floater_preview_url"         title="Preview URL"         collapsable="true" @@ -278,8 +278,8 @@          label="Preview_URL"           border="true"         /> -    </collapsible_ctrl> -    <collapsible_ctrl  +    </accordionctrl_tab> +    <accordionctrl_tab         name="floater_URL_entry"         title="URL Entry"         collapsable="true" @@ -297,7 +297,7 @@          label="URL_entry"           border="true"         /> -    </collapsible_ctrl> +    </accordionctrl_tab>    </sidetray_tab>    <sidetray_tab 	 @@ -310,7 +310,7 @@      tab_title="Region"      description="Region."    > -    <collapsible_ctrl  +    <accordionctrl_tab         name="panel_region_covenant"         title="Region Covenant"         collapsable="true"  @@ -328,8 +328,8 @@          label="Panel_Region_Covenant"           border="true"         /> -    </collapsible_ctrl> -    <collapsible_ctrl  +    </accordionctrl_tab> +    <accordionctrl_tab         name="panel_region_debug"         title="Region Debug"         collapsable="true"  @@ -347,8 +347,8 @@          label="Panel_Region_Debug"           border="true"         /> -    </collapsible_ctrl> -  <collapsible_ctrl  +    </accordionctrl_tab> +  <accordionctrl_tab         name="panel_region_estate"         title="Region Estate"         collapsable="true"  @@ -366,8 +366,8 @@          label="Panel_Region_Estate"           border="true"         /> -    </collapsible_ctrl> -  <collapsible_ctrl  +    </accordionctrl_tab> +  <accordionctrl_tab         name="panel_region_general"         title="Region General"         collapsable="true"  @@ -385,8 +385,8 @@          label="Panel_Region_General"           border="true"         /> -    </collapsible_ctrl> -  <collapsible_ctrl  +    </accordionctrl_tab> +  <accordionctrl_tab         name="panel_region_terrain"         title="Region Terrain"         collapsable="true"  @@ -404,8 +404,8 @@          label="Panel_Region_Terrain"           border="true"         /> -    </collapsible_ctrl> -  <collapsible_ctrl  +    </accordionctrl_tab> +  <accordionctrl_tab         name="panel_region_texture"         title="Region Texture"         collapsable="true"  @@ -423,8 +423,8 @@          label="Panel_Region_Texture"           border="true"         /> -    </collapsible_ctrl> -  <collapsible_ctrl  +    </accordionctrl_tab> +  <accordionctrl_tab         name="floater_region_info"         title="Region Info"         collapsable="true"  @@ -442,7 +442,7 @@          label="Floater_Region_Info"           border="true"         /> -    </collapsible_ctrl> +    </accordionctrl_tab>    </sidetray_tab>    <sidetray_tab 	 @@ -455,7 +455,7 @@      tab_title="Build"      description="Build"    > -    <collapsible_ctrl  +    <accordionctrl_tab         name="floater_tools"         title="Tools"         collapsable="true"  @@ -473,8 +473,8 @@          label="Tools"           border="true"         /> -    </collapsible_ctrl> -    <collapsible_ctrl  +    </accordionctrl_tab> +    <accordionctrl_tab         name="floater_bulk_perms"         title="Bulk Perms"         collapsable="true"  @@ -492,8 +492,8 @@          label="Tools"           border="true"         /> -    </collapsible_ctrl> -    <collapsible_ctrl  +    </accordionctrl_tab> +    <accordionctrl_tab         name="floater_build_options"         title="Build Options"         collapsable="true"  @@ -511,7 +511,7 @@          label="Tools"           border="true"         /> -    </collapsible_ctrl> +    </accordionctrl_tab>    </sidetray_tab> @@ -525,7 +525,7 @@      tab_title="Other Tools"      description="Other Tools"    > -    <collapsible_ctrl  +    <accordionctrl_tab         name="floater_gesture"         title="Gestures"         collapsable="true"  @@ -543,9 +543,9 @@          label="Gesture"           border="true"         /> -    </collapsible_ctrl> +    </accordionctrl_tab> -    <collapsible_ctrl  +    <accordionctrl_tab         name="floater_buy_contents"         title="Buy Contents"         collapsable="true"  @@ -563,8 +563,8 @@          label="buy_contents"           border="true"         /> -    </collapsible_ctrl> -    <collapsible_ctrl  +    </accordionctrl_tab> +    <accordionctrl_tab         name="floater_buy_object"         title="Buy Object"         collapsable="true"  @@ -583,7 +583,7 @@          border="true"         />      </collapsible_ctrl> -    <collapsible_ctrl  +    <accordionctrl_tab         name="floater_inventory_view_finder"         title="Inventory View Finder"         collapsable="true"  @@ -601,8 +601,8 @@          label="view_finder"           border="true"         /> -    </collapsible_ctrl> -    <collapsible_ctrl  +    </accordionctrl_tab> +    <accordionctrl_tab         name="floater_mute"         title="Mute"         collapsable="true"  @@ -620,8 +620,8 @@          label="mute"           border="true"         /> -    </collapsible_ctrl> -     <collapsible_ctrl  +    </accordionctrl_tab> +     <accordionctrl_tab         name="floater_sell_land"         title="Sell Land"         collapsable="true"  @@ -639,8 +639,8 @@          label="sell_land"           border="true"         /> -    </collapsible_ctrl> -     <collapsible_ctrl  +    </accordionctrl_tab> +     <accordionctrl_tab         name="floater_telehub"         title="Telehub"         collapsable="true"  @@ -658,7 +658,7 @@          label="telehub"           border="true"         /> -    </collapsible_ctrl> +    </accordionctrl_tab>    </sidetray_tab>   -->  diff --git a/indra/newview/skins/default/xui/en/widgets/gesture_combo_box.xml b/indra/newview/skins/default/xui/en/widgets/gesture_combo_box.xml new file mode 100644 index 0000000000..45b1e1eb9f --- /dev/null +++ b/indra/newview/skins/default/xui/en/widgets/gesture_combo_box.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<combo_box font="SansSerifSmall" +           list_position="below" +           max_chars="20" +           follows="right|top"> +  <combo_box.combo_button name="Combobox Button" +                          label="" +                          hover_glow_amount="0.15" +                          font="SansSerifSmall" +                          scale_image="true" +                          image_unselected="ComboButton_Off" +                          image_selected="ComboButton_Selected" +                          image_disabled="ComboButton_Disabled" +                          image_disabled_selected="ComboButton_Disabled_Selected" /> +  <combo_box.drop_down_button name="Drop Down Button" +                              label="" +                              hover_glow_amount="0.15" +                              font="SansSerifSmall" +                              scale_image="true" +                              pad_right="24" +                              image_unselected="DropDown_Off" +                              image_selected="DropDown_Selected" +                              image_disabled="DropDown_Disabled" +                              image_disabled_selected="DropDown_Disabled_Selected" /> +  <combo_box.combo_list bg_writeable_color="white" /> +  <combo_box.combo_editor name="Combo Text Entry" +                          select_on_focus="true" +                          font="SansSerifSmall" /> +</combo_box> | 
