diff options
| author | Richard Linden <none@none> | 2011-06-23 11:28:23 -0700 | 
|---|---|---|
| committer | Richard Linden <none@none> | 2011-06-23 11:28:23 -0700 | 
| commit | 70fc5af53ffc39c3c0ef32b99a6c83e972b8a117 (patch) | |
| tree | ddc8da9d6365611c777c324b38a91f5346c6228e /indra | |
| parent | b343d25d19a7d21470027da379c7f16bc7fcb9fc (diff) | |
| parent | 715cb3cc0ca968002af247d0ba67a5d3bed76756 (diff) | |
Automated merge with http://hg.secondlife.com/viewer-development
Diffstat (limited to 'indra')
105 files changed, 3001 insertions, 713 deletions
| diff --git a/indra/llcommon/llfoldertype.cpp b/indra/llcommon/llfoldertype.cpp index c2cfb7286e..c6b52e1e3e 100644 --- a/indra/llcommon/llfoldertype.cpp +++ b/indra/llcommon/llfoldertype.cpp @@ -93,6 +93,7 @@ LLFolderDictionary::LLFolderDictionary()  	addEntry(LLFolderType::FT_MESH, 				new FolderEntry("mesh",	TRUE));  	addEntry(LLFolderType::FT_INBOX, 				new FolderEntry("inbox",	TRUE)); +	addEntry(LLFolderType::FT_OUTBOX, 				new FolderEntry("outbox",	TRUE));  	addEntry(LLFolderType::FT_NONE, 				new FolderEntry("-1",		FALSE));  }; diff --git a/indra/llcommon/llfoldertype.h b/indra/llcommon/llfoldertype.h index cb32cb075b..811e58e2f8 100644 --- a/indra/llcommon/llfoldertype.h +++ b/indra/llcommon/llfoldertype.h @@ -83,8 +83,9 @@ public:  		FT_MESH = 49,  		FT_INBOX = 50, +		FT_OUTBOX = 51, -		FT_COUNT = 51, +		FT_COUNT,  		FT_NONE = -1  	}; diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt index 684e393cba..3be7033993 100644 --- a/indra/llui/CMakeLists.txt +++ b/indra/llui/CMakeLists.txt @@ -28,6 +28,8 @@ include_directories(  set(llui_SOURCE_FILES      llaccordionctrl.cpp      llaccordionctrltab.cpp +    llbadge.cpp +    llbadgeowner.cpp      llbutton.cpp      llcheckboxctrl.cpp      llclipboard.cpp @@ -119,6 +121,8 @@ set(llui_HEADER_FILES      llaccordionctrl.h      llaccordionctrltab.h +    llbadge.h +    llbadgeowner.h      llbutton.h      llcallbackmap.h      llcheckboxctrl.h @@ -245,11 +249,11 @@ target_link_libraries(llui      )  # Add tests -if (LL_TESTS) -	include(LLAddBuildTest) -	SET(llui_TEST_SOURCE_FILES -		llurlmatch.cpp -		llurlentry.cpp -		) -	LL_ADD_PROJECT_UNIT_TESTS(llui "${llui_TEST_SOURCE_FILES}") -endif (LL_TESTS)
\ No newline at end of file +if(LL_TESTS) +  include(LLAddBuildTest) +  SET(llui_TEST_SOURCE_FILES +      llurlmatch.cpp +      llurlentry.cpp +      ) +  LL_ADD_PROJECT_UNIT_TESTS(llui "${llui_TEST_SOURCE_FILES}") +endif(LL_TESTS) diff --git a/indra/llui/llaccordionctrltab.cpp b/indra/llui/llaccordionctrltab.cpp index 9e4849c58b..6afe276379 100644 --- a/indra/llui/llaccordionctrltab.cpp +++ b/indra/llui/llaccordionctrltab.cpp @@ -1022,7 +1022,7 @@ void	LLAccordionCtrlTab::updateLayout	( const LLRect& child_rect )  	S32 panel_width = child_rect.getWidth();  	static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0); -	if(mScrollbar->getVisible() != false) +	if(mScrollbar && mScrollbar->getVisible() != false)  	{  		panel_top+=mScrollbar->getDocPos();  		panel_width-=scrollbar_size; diff --git a/indra/llui/llbadge.cpp b/indra/llui/llbadge.cpp new file mode 100644 index 0000000000..c28a947a7f --- /dev/null +++ b/indra/llui/llbadge.cpp @@ -0,0 +1,274 @@ +/**  + * @file llbadge.cpp + * @brief Implementation for badges + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#define LLBADGE_CPP +#include "llbadge.h" + +#include "lluictrlfactory.h" + + +static LLDefaultChildRegistry::Register<LLBadge> r("badge"); + +// Compiler optimization, generate extern template +template class LLBadge* LLView::getChild<class LLBadge>(const std::string& name, BOOL recurse) const; + + +LLBadge::Params::Params() +	: image("image") +	, border_image("border_image") +	, border_color("border_color") +	, image_color("image_color") +	, label("label") +	, label_color("label_color") +	, location("location", LLRelPos::TOP_LEFT) +	, location_percent_hcenter("location_percent_hcenter") +	, location_percent_vcenter("location_percent_vcenter") +	, padding_horiz("padding_horiz") +	, padding_vert("padding_vert") +{ +	// We set a name here so the name isn't necessary in any xml files that use badges +	name = "badge"; +} + +bool LLBadge::Params::equals(const Params& a) const +{ +	bool comp = true; +	 +	// skip owner in comparison on purpose +	 +	comp &= (border_image() == a.border_image()); +	comp &= (border_color() == a.border_color()); +	comp &= (image() == a.image()); +	comp &= (image_color() == a.image_color()); +	comp &= (label() == a.label()); +	comp &= (label_color() == a.label_color()); +	comp &= (location() == a.location()); +	comp &= (location_percent_hcenter() == a.location_percent_hcenter()); +	comp &= (location_percent_vcenter() == a.location_percent_vcenter()); +	comp &= (padding_horiz() == a.padding_horiz()); +	comp &= (padding_vert() == a.padding_vert()); +	 +	return comp; +} + +LLBadge::LLBadge(const LLBadge::Params& p) +	: LLUICtrl(p) +	, mOwner(p.owner) +	, mBorderImage(p.border_image) +	, mBorderColor(p.border_color) +	, mGLFont(p.font) +	, mImage(p.image) +	, mImageColor(p.image_color) +	, mLabel(p.label) +	, mLabelColor(p.label_color) +	, mLocation(p.location) +	, mLocationPercentHCenter(0.5f) +	, mLocationPercentVCenter(0.5f) +	, mPaddingHoriz(p.padding_horiz) +	, mPaddingVert(p.padding_vert) +{ +	if (mImage.isNull()) +	{ +		llwarns << "Badge: " << getName() << " with no image!" << llendl; +	} + +	// +	// The following logic is to set the mLocationPercentHCenter and mLocationPercentVCenter +	// based on the Location enum and our horizontal and vertical location percentages.  The +	// draw code then uses this on the owner rectangle to compute the screen location for +	// the badge. +	// + +	if (!LLRelPos::IsCenter(mLocation)) +	{ +		F32 h_center = p.location_percent_hcenter * 0.01f; +		F32 v_center = p.location_percent_vcenter * 0.01f; + +		if (LLRelPos::IsRight(mLocation)) +		{ +			mLocationPercentHCenter = 0.5f * (1.0f + h_center); +		} +		else if (LLRelPos::IsLeft(mLocation)) +		{ +			mLocationPercentHCenter = 0.5f * (1.0f - h_center); +		} +			 +		if (LLRelPos::IsTop(mLocation)) +		{ +			mLocationPercentVCenter = 0.5f * (1.0f + v_center); +		} +		else if (LLRelPos::IsBottom(mLocation)) +		{ +			mLocationPercentVCenter = 0.5f * (1.0f - v_center); +		} +	} +} + +LLBadge::~LLBadge() +{ +} + +void LLBadge::setLabel(const LLStringExplicit& label) +{ +	mLabel = label; +} + +// +// This is a fallback function to render a rectangle for badges without a valid image +// +void renderBadgeBackground(F32 centerX, F32 centerY, F32 width, F32 height, const LLColor4U &color) +{ +	gGL.pushUIMatrix(); +	gGL.loadUIIdentity(); +	gGL.setSceneBlendType(LLRender::BT_REPLACE); +	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); +	 +	gGL.color4ubv(color.mV); +	gGL.texCoord2i(0, 0); +	 +	F32 x = LLFontGL::sCurOrigin.mX + centerX - width * 0.5f; +	F32 y = LLFontGL::sCurOrigin.mY + centerY - height * 0.5f; +	 +	LLRectf screen_rect(llround(x), +						llround(y), +						llround(x) + width, +						llround(y) + height); +	 +	LLVector3 vertices[4]; +	vertices[0] = LLVector3(screen_rect.mRight, screen_rect.mTop,    1.0f); +	vertices[1] = LLVector3(screen_rect.mLeft,  screen_rect.mTop,    1.0f); +	vertices[2] = LLVector3(screen_rect.mLeft,  screen_rect.mBottom, 1.0f); +	vertices[3] = LLVector3(screen_rect.mRight, screen_rect.mBottom, 1.0f); +	 +	gGL.begin(LLRender::QUADS); +	{ +		gGL.vertexBatchPreTransformed(vertices, 4); +	} +	gGL.end(); +	 +	gGL.popUIMatrix(); +} + + +// virtual +void LLBadge::draw() +{ +	if (!mLabel.empty()) +	{ +		LLView* owner_view = mOwner.get(); + +		if (owner_view) +		{ +			// +			// Calculate badge position based on owner +			// +			 +			LLRect owner_rect; +			owner_view->localRectToOtherView(owner_view->getLocalRect(), & owner_rect, this); +			 +			F32 badge_center_x = owner_rect.mLeft + owner_rect.getWidth() * mLocationPercentHCenter; +			F32 badge_center_y = owner_rect.mBottom + owner_rect.getHeight() * mLocationPercentVCenter; + +			// +			// Calculate badge size based on label text +			// + +			LLWString badge_label_wstring = mLabel; +			 +			S32 badge_label_begin_offset = 0; +			S32 badge_char_length = S32_MAX; +			S32 badge_pixel_length = S32_MAX; +			F32 *right_position_out = NULL; +			BOOL do_not_use_ellipses = false; + +			F32 badge_width = (2.0f * mPaddingHoriz) + +				mGLFont->getWidthF32(badge_label_wstring.c_str(), badge_label_begin_offset, badge_char_length); + +			F32 badge_height = (2.0f * mPaddingVert) + mGLFont->getLineHeight(); + +			// +			// Draw button image, if available. +			// Otherwise draw basic rectangular button. +			// + +			F32 alpha = getDrawContext().mAlpha; + +			if (!mImage.isNull()) +			{ +				F32 badge_x = badge_center_x - badge_width * 0.5f; +				F32 badge_y = badge_center_y - badge_height * 0.5f; +			 +				mImage->drawSolid((S32) badge_x, (S32) badge_y, (S32) badge_width, (S32) badge_height, mImageColor % alpha); + +				if (!mBorderImage.isNull()) +				{ +					mBorderImage->drawSolid((S32) badge_x, (S32) badge_y, (S32) badge_width, (S32) badge_height, mBorderColor % alpha); +				} +			} +			else +			{ +				lldebugs << "No image for badge " << getName() << " on owner " << owner_view->getName() << llendl; +				 +				renderBadgeBackground(badge_center_x, badge_center_y, +									  badge_width, badge_height, +									  mImageColor % alpha); +			} + +			// +			// Draw the label +			// + +			mGLFont->render(badge_label_wstring, badge_label_begin_offset, +							badge_center_x, badge_center_y, +							mLabelColor % alpha, +							LLFontGL::HCENTER, LLFontGL::VCENTER, // centered around the position +							LLFontGL::NORMAL, // normal text (not bold, italics, etc.) +							LLFontGL::DROP_SHADOW_SOFT, +							badge_char_length, badge_pixel_length, +							right_position_out, do_not_use_ellipses); +		} +	} +} + + +namespace LLInitParam +{ +	void TypeValues<LLRelPos::Location>::declareValues() +	{ +		declare("bottom",		LLRelPos::BOTTOM); +		declare("bottom_left",	LLRelPos::BOTTOM_LEFT); +		declare("bottom_right", LLRelPos::BOTTOM_RIGHT); +		declare("center",		LLRelPos::CENTER); +		declare("left",			LLRelPos::LEFT); +		declare("right",		LLRelPos::RIGHT); +		declare("top",			LLRelPos::TOP); +		declare("top_left",		LLRelPos::TOP_LEFT); +		declare("top_right",	LLRelPos::TOP_RIGHT); +	} +} + + +// eof diff --git a/indra/llui/llbadge.h b/indra/llui/llbadge.h new file mode 100644 index 0000000000..0f923ef01b --- /dev/null +++ b/indra/llui/llbadge.h @@ -0,0 +1,159 @@ +/**  + * @file llbadge.h + * @brief Header for badges + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLBADGE_H +#define LL_LLBADGE_H + +#include <string> + +#include "lluicolor.h" +#include "lluictrl.h" +#include "llstring.h" +#include "lluiimage.h" +#include "llview.h" + +// +// Declarations +// + +class LLUICtrlFactory; +class LLFontGL; + +// +// Relative Position Alignment +// + +namespace LLRelPos +{ +	enum Location +	{ +		CENTER	= 0, + +		LEFT	= (1 << 0), +		RIGHT	= (1 << 1), + +		TOP		= (1 << 2), +		BOTTOM	= (1 << 3), + +		BOTTOM_LEFT		= (BOTTOM | LEFT), +		BOTTOM_RIGHT	= (BOTTOM | RIGHT), + +		TOP_LEFT		= (TOP | LEFT), +		TOP_RIGHT		= (TOP | RIGHT), +	}; + +	inline bool IsBottom(Location relPos)	{ return (relPos & BOTTOM) == BOTTOM; } +	inline bool IsCenter(Location relPos)	{ return (relPos == CENTER); } +	inline bool IsLeft(Location relPos)		{ return (relPos & LEFT) == LEFT; } +	inline bool IsRight(Location relPos)	{ return (relPos & RIGHT) == RIGHT; } +	inline bool IsTop(Location relPos)		{ return (relPos & TOP) == TOP; } +} + +// NOTE: This needs to occur before Optional<LLRelPos::Location> declaration for proper compilation. +namespace LLInitParam +{ +	template<> +	struct TypeValues<LLRelPos::Location> : public TypeValuesHelper<LLRelPos::Location> +	{ +		static void declareValues(); +	}; +} + +// +// Classes +// + +class LLBadge +: public LLUICtrl +{ +public: +	struct Params  +	: public LLInitParam::Block<Params, LLUICtrl::Params> +	{ +		Optional< LLHandle<LLView> >	owner;	// Mandatory in code but not in xml +		 +		Optional< LLUIImage* >			border_image; +		Optional< LLUIColor >			border_color; + +		Optional< LLUIImage* >			image; +		Optional< LLUIColor >			image_color; +		 +		Optional< std::string >			label; +		Optional< LLUIColor >			label_color; + +		Optional< LLRelPos::Location >	location; +		Optional< U32 >					location_percent_hcenter; +		Optional< U32 >					location_percent_vcenter; + +		Optional< F32 >					padding_horiz; +		Optional< F32 >					padding_vert; +		 +		Params(); +		 +		bool equals(const Params&) const; +	}; +	 +protected: +	friend class LLUICtrlFactory; +	LLBadge(const Params& p); + +public: + +	~LLBadge(); +	 +	virtual void		draw(); + +	const std::string	getLabel() const { return wstring_to_utf8str(mLabel); } +	void				setLabel( const LLStringExplicit& label); + +private: +	LLPointer< LLUIImage >	mBorderImage; +	LLUIColor				mBorderColor; + +	const LLFontGL*			mGLFont; +	 +	LLPointer< LLUIImage >	mImage; +	LLUIColor				mImageColor; +	 +	LLUIString				mLabel; +	LLUIColor				mLabelColor; + +	LLRelPos::Location		mLocation; +	F32						mLocationPercentHCenter; +	F32						mLocationPercentVCenter; +	 +	LLHandle< LLView >		mOwner; + +	F32						mPaddingHoriz; +	F32						mPaddingVert; +}; + +// Build time optimization, generate once in .cpp file +#ifndef LLBADGE_CPP +extern template class LLBadge* LLView::getChild<class LLBadge>(const std::string& name, BOOL recurse) const; +#endif + +#endif  // LL_LLBADGE_H diff --git a/indra/llui/llbadgeowner.cpp b/indra/llui/llbadgeowner.cpp new file mode 100644 index 0000000000..3d63fc7f60 --- /dev/null +++ b/indra/llui/llbadgeowner.cpp @@ -0,0 +1,118 @@ +/**  + * @file llbadgeowner.cpp + * @brief Class to manage badges attached to a UI control + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "llbadgeowner.h" +#include "llpanel.h" + +// +// Classes +// + +LLBadgeOwner::LLBadgeOwner(LLHandle< LLView > viewHandle) +	: mBadge(NULL) +	, mBadgeOwnerView(viewHandle) +{ +} + +void LLBadgeOwner::initBadgeParams(const LLBadge::Params& p) +{ +	if (!p.equals(LLUICtrlFactory::getDefaultParams<LLBadge>())) +	{ +		mBadge = createBadge(p); +	} +} + +void LLBadgeOwner::setBadgeLabel(const LLStringExplicit& label) +{ +	if (mBadge == NULL) +	{ +		mBadge = createBadge(LLUICtrlFactory::getDefaultParams<LLBadge>()); + +		addBadgeToParentPanel(); +	} + +	if (mBadge) +	{ +		mBadge->setLabel(label); + +		// +		// Push the badge to the front so it renders on top +		// + +		LLView * parent = mBadge->getParent(); + +		if (parent) +		{ +			parent->sendChildToFront(mBadge); +		} +	} +} + +void LLBadgeOwner::addBadgeToParentPanel() +{ +	LLView * owner_view = mBadgeOwnerView.get(); +	 +	if (mBadge && owner_view) +	{ +		// Badge parent is badge owner by default +		LLView * badge_parent = owner_view; + +		// Find the appropriate parent for the badge +		LLView * parent = owner_view->getParent(); + +		while (parent) +		{ +			LLPanel * parent_panel = dynamic_cast<LLPanel *>(parent); + +			if (parent_panel && parent_panel->acceptsBadge()) +			{ +				badge_parent = parent; +				break; +			} + +			parent = parent->getParent(); +		} + +		if (badge_parent) +		{ +			badge_parent->addChild(mBadge); +		} +		else +		{ +			llwarns << "Unable to find parent panel for badge " << mBadge->getName() << " on " << owner_view->getName() << llendl; +		} +	} +} + +LLBadge* LLBadgeOwner::createBadge(const LLBadge::Params& p) +{ +	LLBadge::Params badge_params(p); +	badge_params.owner = mBadgeOwnerView; + +	return LLUICtrlFactory::create<LLBadge>(badge_params); +} diff --git a/indra/llui/llbadgeowner.h b/indra/llui/llbadgeowner.h new file mode 100644 index 0000000000..456ef90c13 --- /dev/null +++ b/indra/llui/llbadgeowner.h @@ -0,0 +1,58 @@ +/**  + * @file llbadgeowner.h + * @brief Header for badge owners + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLBADGEOWNER_H +#define LL_LLBADGEOWNER_H + +#include "llbadge.h" +#include "llview.h" + +// +// Classes +// + +class LLBadgeOwner +{ +public: + +	LLBadgeOwner(LLHandle< LLView > viewHandle); + +	void initBadgeParams(const LLBadge::Params& p); +	void addBadgeToParentPanel(); + +	void setBadgeLabel(const LLStringExplicit& label); + +private: + +	LLBadge* createBadge(const LLBadge::Params& p); + +private: + +	LLBadge*			mBadge; +	LLHandle< LLView >	mBadgeOwnerView; +}; + +#endif  // LL_LLBADGEOWNER_H diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp index 45ceaff696..7b015bd576 100644 --- a/indra/llui/llbutton.cpp +++ b/indra/llui/llbutton.cpp @@ -99,7 +99,9 @@ LLButton::Params::Params()  	scale_image("scale_image", true),  	hover_glow_amount("hover_glow_amount"),  	commit_on_return("commit_on_return", true), -	use_draw_context_alpha("use_draw_context_alpha", true) +	use_draw_context_alpha("use_draw_context_alpha", true), +	badge("badge"), +	handle_right_mouse("handle_right_mouse")  {  	addSynonym(is_toggle, "toggle");  	held_down_delay.seconds = 0.5f; @@ -109,6 +111,7 @@ LLButton::Params::Params()  LLButton::LLButton(const LLButton::Params& p)  :	LLUICtrl(p), +	LLBadgeOwner(LLView::getHandle()),  	mMouseDownFrame(0),  	mMouseHeldDownCount(0),  	mBorderEnabled( FALSE ), @@ -160,8 +163,8 @@ LLButton::LLButton(const LLButton::Params& p)  	mMouseDownSignal(NULL),  	mMouseUpSignal(NULL),  	mHeldDownSignal(NULL), -	mUseDrawContextAlpha(p.use_draw_context_alpha) - +	mUseDrawContextAlpha(p.use_draw_context_alpha), +	mHandleRightMouse(p.handle_right_mouse)  {  	static LLUICachedControl<S32> llbutton_orig_h_pad ("UIButtonOrigHPad", 0);  	static Params default_params(LLUICtrlFactory::getDefaultParams<LLButton>()); @@ -244,6 +247,11 @@ LLButton::LLButton(const LLButton::Params& p)  	{  		setHeldDownCallback(initCommitCallback(p.mouse_held_callback));  	} + +	if (p.badge.isProvided()) +	{ +		LLBadgeOwner::initBadgeParams(p.badge()); +	}  }  LLButton::~LLButton() @@ -327,8 +335,12 @@ boost::signals2::connection LLButton::setHeldDownCallback( button_callback_t cb,  BOOL LLButton::postBuild()  {  	autoResize(); -	return TRUE; + +	addBadgeToParentPanel(); + +	return LLUICtrl::postBuild();  } +  BOOL LLButton::handleUnicodeCharHere(llwchar uni_char)  {  	BOOL handled = FALSE; @@ -447,7 +459,7 @@ BOOL LLButton::handleMouseUp(S32 x, S32 y, MASK mask)  BOOL	LLButton::handleRightMouseDown(S32 x, S32 y, MASK mask)  { -	if (!childrenHandleRightMouseDown(x, y, mask)) +	if (mHandleRightMouse && !childrenHandleRightMouseDown(x, y, mask))  	{  		// Route future Mouse messages here preemptively.  (Release on mouse up.)  		gFocusMgr.setMouseCapture( this ); @@ -460,37 +472,42 @@ BOOL	LLButton::handleRightMouseDown(S32 x, S32 y, MASK mask)  //		if (pointInView(x, y))  //		{  //		} +		// send the mouse down signal +		LLUICtrl::handleRightMouseDown(x,y,mask); +		// *TODO: Return result of LLUICtrl call above?  Should defer to base class +		// but this might change the mouse handling of existing buttons in a bad way +		// if they are not mouse opaque.  	} -	// send the mouse down signal -	LLUICtrl::handleRightMouseDown(x,y,mask); -	// *TODO: Return result of LLUICtrl call above?  Should defer to base class -	// but this might change the mouse handling of existing buttons in a bad way -	// if they are not mouse opaque. +  	return TRUE;  }  BOOL	LLButton::handleRightMouseUp(S32 x, S32 y, MASK mask)  { -	// We only handle the click if the click both started and ended within us -	if( hasMouseCapture() ) +	if (mHandleRightMouse)  	{ -		// Always release the mouse -		gFocusMgr.setMouseCapture( NULL ); +		// We only handle the click if the click both started and ended within us +		if( hasMouseCapture() ) +		{ +			// Always release the mouse +			gFocusMgr.setMouseCapture( NULL ); -//		if (pointInView(x, y)) -//		{ -//			mRightMouseUpSignal(this, x,y,mask); -//		} -	} -	else  -	{ -		childrenHandleRightMouseUp(x, y, mask); +	//		if (pointInView(x, y)) +	//		{ +	//			mRightMouseUpSignal(this, x,y,mask); +	//		} +		} +		else  +		{ +			childrenHandleRightMouseUp(x, y, mask); +		} +	 +		// send the mouse up signal +		LLUICtrl::handleRightMouseUp(x,y,mask); +		// *TODO: Return result of LLUICtrl call above?  Should defer to base class +		// but this might change the mouse handling of existing buttons in a bad way. +		// if they are not mouse opaque.  	} -	// send the mouse up signal -	LLUICtrl::handleRightMouseUp(x,y,mask); -	// *TODO: Return result of LLUICtrl call above?  Should defer to base class -	// but this might change the mouse handling of existing buttons in a bad way. -	// if they are not mouse opaque.  	return TRUE;  } diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h index 0cfc393e05..5968916006 100644 --- a/indra/llui/llbutton.h +++ b/indra/llui/llbutton.h @@ -27,6 +27,8 @@  #ifndef LL_LLBUTTON_H  #define LL_LLBUTTON_H +#include "lluuid.h" +#include "llbadgeowner.h"  #include "llcontrol.h"  #include "lluictrl.h"  #include "v4color.h" @@ -52,15 +54,13 @@ S32 round_up(S32 grid, S32 value);  class LLUICtrlFactory; -class LLUIImage; -class LLUUID;  //  // Classes  //  class LLButton -: public LLUICtrl +: public LLUICtrl, public LLBadgeOwner  {  public:  	struct Params  @@ -125,7 +125,11 @@ public:  		Optional<F32>				hover_glow_amount;  		Optional<TimeIntervalParam>	held_down_delay; -		Optional<bool>			use_draw_context_alpha; +		Optional<bool>				use_draw_context_alpha; +		 +		Optional<LLBadge::Params>	badge; + +		Optional<bool>				handle_right_mouse;  		Params();  	}; @@ -249,7 +253,7 @@ public:  	void			setImageDisabledSelected(LLPointer<LLUIImage> image);  	void			setImageFlash(LLPointer<LLUIImage> image);  	void			setImagePressed(LLPointer<LLUIImage> image); - +	  	void			setCommitOnReturn(BOOL commit) { mCommitOnReturn = commit; }  	BOOL			getCommitOnReturn() const { return mCommitOnReturn; } @@ -357,6 +361,8 @@ private:  	bool						mForcePressedState;  	LLFrameTimer				mFlashingTimer; + +	bool						mHandleRightMouse;  };  // Build time optimization, generate once in .cpp file diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp index 9b6830a816..d87ee428aa 100644 --- a/indra/llui/lllayoutstack.cpp +++ b/indra/llui/lllayoutstack.cpp @@ -49,6 +49,8 @@ void LLLayoutStack::OrientationNames::declareValues()  //  LLLayoutPanel::LLLayoutPanel(const Params& p)	  :	LLPanel(p), +	mExpandedMinDimSpecified(false), +	mExpandedMinDim(p.min_dim),   	mMinDim(p.min_dim),    	mMaxDim(p.max_dim),    	mAutoResize(p.auto_resize), @@ -58,6 +60,13 @@ LLLayoutPanel::LLLayoutPanel(const Params& p)  	mVisibleAmt(1.f), // default to fully visible  	mResizeBar(NULL)   { +	// Set the expanded min dim if it is provided, otherwise it gets the p.min_dim value +	if (p.expanded_min_dim.isProvided()) +	{ +		mExpandedMinDimSpecified = true; +		mExpandedMinDim = p.expanded_min_dim(); +	} +	  	// panels initialized as hidden should not start out partially visible  	if (!getVisible())  	{ @@ -78,20 +87,20 @@ LLLayoutPanel::~LLLayoutPanel()  	delete mResizeBar;  	mResizeBar = NULL;  } -	 +  F32 LLLayoutPanel::getCollapseFactor(LLLayoutStack::ELayoutOrientation orientation)  {  	if (orientation == LLLayoutStack::HORIZONTAL)  	{  		F32 collapse_amt =  -		clamp_rescale(mCollapseAmt, 0.f, 1.f, 1.f, (F32)mMinDim / (F32)llmax(1, getRect().getWidth())); +			clamp_rescale(mCollapseAmt, 0.f, 1.f, 1.f, getRelevantMinDim() / (F32)llmax(1, getRect().getWidth()));  		return mVisibleAmt * collapse_amt;  	}  	else  	{ -			F32 collapse_amt =  -			clamp_rescale(mCollapseAmt, 0.f, 1.f, 1.f, llmin(1.f, (F32)mMinDim / (F32)llmax(1, getRect().getHeight()))); -			return mVisibleAmt * collapse_amt; +		F32 collapse_amt =  +			clamp_rescale(mCollapseAmt, 0.f, 1.f, 1.f, llmin(1.f, getRelevantMinDim() / (F32)llmax(1, getRect().getHeight()))); +		return mVisibleAmt * collapse_amt;  	}  } @@ -182,14 +191,14 @@ BOOL LLLayoutStack::postBuild()  }  bool LLLayoutStack::addChild(LLView* child, S32 tab_group) -		{ +{  	LLLayoutPanel* panelp = dynamic_cast<LLLayoutPanel*>(child); -			if (panelp) -			{ +	if (panelp) +	{  		mPanels.push_back(panelp); -			} +	}  	return LLView::addChild(child, tab_group); -		} +}  S32 LLLayoutStack::getDefaultHeight(S32 cur_height) @@ -281,9 +290,9 @@ bool LLLayoutStack::getPanelMinSize(const std::string& panel_name, S32* min_dimp  {  	LLLayoutPanel* panel = findEmbeddedPanelByName(panel_name); -	if (panel) +	if (panel && min_dimp)  	{ -		if (min_dimp) *min_dimp = panel->mMinDim; +		*min_dimp = panel->getRelevantMinDim();  	}  	return NULL != panel; @@ -316,7 +325,7 @@ void LLLayoutStack::updateLayout(BOOL force_resize)  	e_panel_list_t::iterator panel_it;  	for (panel_it = mPanels.begin(); panel_it != mPanels.end();	++panel_it)  	{ -		LLPanel* panelp = (*panel_it); +		LLLayoutPanel* panelp = (*panel_it);  		if (panelp->getVisible())   		{  			if (mAnimate) @@ -366,9 +375,9 @@ void LLLayoutStack::updateLayout(BOOL force_resize)  		if (mOrientation == HORIZONTAL)  		{  			// enforce minimize size constraint by default -			if (panelp->getRect().getWidth() < (*panel_it)->mMinDim) +			if (panelp->getRect().getWidth() < (*panel_it)->getRelevantMinDim())  			{ -				panelp->reshape((*panel_it)->mMinDim, panelp->getRect().getHeight()); +				panelp->reshape((*panel_it)->getRelevantMinDim(), panelp->getRect().getHeight());  			}          	total_width += llround(panelp->getRect().getWidth() * (*panel_it)->getCollapseFactor(mOrientation));          	// want n-1 panel gaps for n panels @@ -380,9 +389,9 @@ void LLLayoutStack::updateLayout(BOOL force_resize)  		else //VERTICAL  		{  			// enforce minimize size constraint by default -			if (panelp->getRect().getHeight() < (*panel_it)->mMinDim) +			if (panelp->getRect().getHeight() < (*panel_it)->getRelevantMinDim())  			{ -				panelp->reshape(panelp->getRect().getWidth(), (*panel_it)->mMinDim); +				panelp->reshape(panelp->getRect().getWidth(), (*panel_it)->getRelevantMinDim());  			}  			total_height += llround(panelp->getRect().getHeight() * (*panel_it)->getCollapseFactor(mOrientation));  			if (panel_it != mPanels.begin()) @@ -409,28 +418,20 @@ void LLLayoutStack::updateLayout(BOOL force_resize)  			|| (!(*panel_it)->mAutoResize   				&& !force_resize))  		{ -			if (mOrientation == HORIZONTAL) -			{ -				shrink_headroom_total += (*panel_it)->getRect().getWidth() - (*panel_it)->mMinDim; -			} -			else //VERTICAL -			{ -				shrink_headroom_total += (*panel_it)->getRect().getHeight() - (*panel_it)->mMinDim; -			} +			S32 relevant_dimension = (mOrientation == HORIZONTAL) ? (*panel_it)->getRect().getWidth() : (*panel_it)->getRect().getHeight(); +			F32 relevant_min = ((*panel_it)->mCollapsed ? (*panel_it)->getRelevantMinDim() : (*panel_it)->mExpandedMinDim); +			 +			shrink_headroom_total += relevant_dimension - relevant_min;  		}  		else  		{  			num_resizable_panels++; -			if (mOrientation == HORIZONTAL) -			{ -				shrink_headroom_available += (*panel_it)->getRect().getWidth() - (*panel_it)->mMinDim; -				shrink_headroom_total += (*panel_it)->getRect().getWidth() - (*panel_it)->mMinDim; -			} -			else //VERTICAL -			{ -				shrink_headroom_available += (*panel_it)->getRect().getHeight() - (*panel_it)->mMinDim; -				shrink_headroom_total += (*panel_it)->getRect().getHeight() - (*panel_it)->mMinDim; -			} + +			S32 relevant_dimension = (mOrientation == HORIZONTAL) ? (*panel_it)->getRect().getWidth() : (*panel_it)->getRect().getHeight(); +			F32 relevant_min = ((*panel_it)->mCollapsed ? (*panel_it)->getRelevantMinDim() : (*panel_it)->mExpandedMinDim); +			 +			shrink_headroom_available += relevant_dimension - relevant_min; +			shrink_headroom_total += relevant_dimension - relevant_min;  		}  	} @@ -452,27 +453,28 @@ void LLLayoutStack::updateLayout(BOOL force_resize)  	for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)  	{ -		LLPanel* panelp = (*panel_it); +		LLLayoutPanel* panelp = (*panel_it);  		S32 cur_width = panelp->getRect().getWidth();  		S32 cur_height = panelp->getRect().getHeight();  		S32 new_width = cur_width; -		S32 new_height = cur_height;  +		S32 new_height = cur_height; +		S32 relevant_min = (S32) panelp->getRelevantMinDim();  		if (mOrientation == HORIZONTAL)  		{ -			new_width = llmax((*panel_it)->mMinDim, new_width); +			new_width = llmax(relevant_min, new_width);  		}  		else  		{ -			new_height = llmax((*panel_it)->mMinDim, new_height); +			new_height = llmax(relevant_min, new_height);  		}  		S32 delta_size = 0;  		// if panel can automatically resize (not animating, and resize flag set)... -		if ((*panel_it)->getCollapseFactor(mOrientation) == 1.f  -			&& (force_resize || (*panel_it)->mAutoResize)  -			&& !(*panel_it)->mResizeBar->hasMouseCapture())  +		if (panelp->getCollapseFactor(mOrientation) == 1.f  +			&& (force_resize || panelp->mAutoResize)  +			&& !panelp->mResizeBar->hasMouseCapture())   		{  			if (mOrientation == HORIZONTAL)  			{ @@ -481,8 +483,8 @@ void LLLayoutStack::updateLayout(BOOL force_resize)  				{  					// shrink proportionally to amount over minimum  					// so we can do this in one pass -					delta_size = (shrink_headroom_available > 0) ? llround((F32)pixels_to_distribute * ((F32)(cur_width - (*panel_it)->mMinDim) / (F32)shrink_headroom_available)) : 0; -					shrink_headroom_available -= (cur_width - (*panel_it)->mMinDim); +					delta_size = (shrink_headroom_available > 0) ? llround((F32)pixels_to_distribute * ((F32)(cur_width - panelp->getRelevantMinDim()) / (F32)shrink_headroom_available)) : 0; +					shrink_headroom_available -= (cur_width - relevant_min);  				}  				else  				{ @@ -491,7 +493,7 @@ void LLLayoutStack::updateLayout(BOOL force_resize)  					num_resizable_panels--;  				}  				pixels_to_distribute -= delta_size; -				new_width = llmax((*panel_it)->mMinDim, cur_width + delta_size); +				new_width = llmax(relevant_min, cur_width + delta_size);  			}  			else  			{ @@ -504,8 +506,8 @@ void LLLayoutStack::updateLayout(BOOL force_resize)  				{  					// shrink proportionally to amount over minimum  					// so we can do this in one pass -					delta_size = (shrink_headroom_available > 0) ? llround((F32)pixels_to_distribute * ((F32)(cur_height - (*panel_it)->mMinDim) / (F32)shrink_headroom_available)) : 0; -					shrink_headroom_available -= (cur_height - (*panel_it)->mMinDim); +					delta_size = (shrink_headroom_available > 0) ? llround((F32)pixels_to_distribute * ((F32)(cur_height - relevant_min) / (F32)shrink_headroom_available)) : 0; +					shrink_headroom_available -= (cur_height - relevant_min);  				}  				else  				{ @@ -513,7 +515,7 @@ void LLLayoutStack::updateLayout(BOOL force_resize)  					num_resizable_panels--;  				}  				pixels_to_distribute -= delta_size; -				new_height = llmax((*panel_it)->mMinDim, cur_height + delta_size); +				new_height = llmax(relevant_min, cur_height + delta_size);  			}  			else  			{ @@ -566,19 +568,20 @@ void LLLayoutStack::updateLayout(BOOL force_resize)  	LLLayoutPanel* last_resizeable_panel = NULL;  	for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)  	{ -		LLPanel* panelp = (*panel_it); +		LLLayoutPanel* panelp = (*panel_it); +		F32 relevant_min = panelp->getRelevantMinDim();  		if (mOrientation == HORIZONTAL)  		{  			(*panel_it)->mResizeBar->setResizeLimits( -				(*panel_it)->mMinDim,  -				(*panel_it)->mMinDim + shrink_headroom_total); +				relevant_min,  +				relevant_min + shrink_headroom_total);  		}  		else //VERTICAL  		{  			(*panel_it)->mResizeBar->setResizeLimits( -				(*panel_it)->mMinDim,  -				(*panel_it)->mMinDim + shrink_headroom_total); +				relevant_min,  +				relevant_min + shrink_headroom_total);  		}  		// toggle resize bars based on panel visibility, resizability, etc @@ -658,7 +661,7 @@ void LLLayoutStack::calcMinExtents()  	{  		if (mOrientation == HORIZONTAL)  		{ -            mMinWidth += (*panel_it)->mMinDim; +            mMinWidth += (*panel_it)->getRelevantMinDim();  			if (panel_it != mPanels.begin())  			{  				mMinWidth += mPanelSpacing; @@ -666,7 +669,7 @@ void LLLayoutStack::calcMinExtents()  		}  		else //VERTICAL  		{ -			mMinHeight += (*panel_it)->mMinDim; +			mMinHeight += (*panel_it)->getRelevantMinDim();  			if (panel_it != mPanels.begin())  			{  				mMinHeight += mPanelSpacing; diff --git a/indra/llui/lllayoutstack.h b/indra/llui/lllayoutstack.h index 4ac8ef0ee9..d8ef0aeaca 100644 --- a/indra/llui/lllayoutstack.h +++ b/indra/llui/lllayoutstack.h @@ -30,10 +30,10 @@  #include "llpanel.h" -class LLPanel;  class LLLayoutPanel; +  class LLLayoutStack : public LLView, public LLInstanceTracker<LLLayoutStack>  {  public: @@ -149,6 +149,7 @@ private:  	F32 mCloseTimeConstant;  }; // end class LLLayoutStack +  class LLLayoutPanel : public LLPanel  {  friend class LLLayoutStack; @@ -156,13 +157,15 @@ friend class LLUICtrlFactory;  public:  	struct Params : public LLInitParam::Block<Params, LLPanel::Params>  	{ -		Optional<S32>			min_dim, +		Optional<S32>			expanded_min_dim, +								min_dim,  								max_dim;  		Optional<bool>			user_resize,  								auto_resize;  		Params() -		:	min_dim("min_dim", 0), +		:	expanded_min_dim("expanded_min_dim", 0), +			min_dim("min_dim", 0),  			max_dim("max_dim", 0),  			user_resize("user_resize", true),  			auto_resize("auto_resize", true) @@ -177,15 +180,36 @@ public:  	~LLLayoutPanel();  	void initFromParams(const Params& p); -	void setMinDim(S32 value) { mMinDim = value; } + +	S32 getMinDim() const { return mMinDim; } +	void setMinDim(S32 value) { mMinDim = value; if (!mExpandedMinDimSpecified) mExpandedMinDim = value; } + +	S32 getMaxDim() const { return mMaxDim; }  	void setMaxDim(S32 value) { mMaxDim = value; } -protected: -	LLLayoutPanel(const Params& p)	; +	S32 getExpandedMinDim() const { return mExpandedMinDim; } +	void setExpandedMinDim(S32 value) { mExpandedMinDim = value; mExpandedMinDimSpecified = true; } +	 +	S32 getRelevantMinDim() const +	{ +		S32 min_dim = mMinDim; +		 +		if (!mCollapsed) +		{ +			min_dim = mExpandedMinDim; +		} +		 +		return min_dim; +	} +protected: +	LLLayoutPanel(const Params& p);  	F32 getCollapseFactor(LLLayoutStack::ELayoutOrientation orientation); +	bool mExpandedMinDimSpecified; +	S32 mExpandedMinDim; +	  	S32 mMinDim;  	S32 mMaxDim;  	BOOL mAutoResize; diff --git a/indra/llui/llloadingindicator.h b/indra/llui/llloadingindicator.h index 4c47cc267c..7c44478848 100644 --- a/indra/llui/llloadingindicator.h +++ b/indra/llui/llloadingindicator.h @@ -86,6 +86,8 @@ public:  	 */  	void start(); +	void reset() { mCurImageIdx = 0; } +  private:  	LLLoadingIndicator(const Params&);  	void initFromParams(const Params&); diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp index b2383106a8..1dcdd79efa 100644 --- a/indra/llui/llpanel.cpp +++ b/indra/llui/llpanel.cpp @@ -87,7 +87,8 @@ LLPanel::Params::Params()  	filename("filename"),  	class_name("class"),  	help_topic("help_topic"), -	visible_callback("visible_callback") +	visible_callback("visible_callback"), +	accepts_badge("accepts_badge")  {  	name = "panel";  	addSynonym(background_visible, "bg_visible"); @@ -113,7 +114,8 @@ LLPanel::LLPanel(const LLPanel::Params& p)  	mCommitCallbackRegistrar(false),  	mEnableCallbackRegistrar(false),  	mXMLFilename(p.filename), -	mVisibleSignal(NULL) +	mVisibleSignal(NULL), +	mAcceptsBadge(p.accepts_badge)  	// *NOTE: Be sure to also change LLPanel::initFromParams().  We have too  	// many classes derived from LLPanel to retrofit them all to pass in params.  { @@ -485,6 +487,8 @@ void LLPanel::initFromParams(const LLPanel::Params& p)  	mBgAlphaImage = p.bg_alpha_image();  	mBgOpaqueImageOverlay = p.bg_opaque_image_overlay;  	mBgAlphaImageOverlay = p.bg_alpha_image_overlay; + +	mAcceptsBadge = p.accepts_badge;  }  static LLFastTimer::DeclareTimer FTM_PANEL_SETUP("Panel Setup"); diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h index 7bbbeaf709..67674fab7e 100644 --- a/indra/llui/llpanel.h +++ b/indra/llui/llpanel.h @@ -89,6 +89,8 @@ public:  		Multiple<LocalizedString>	strings;  		Optional<CommitCallbackParam> visible_callback; + +		Optional<bool>			accepts_badge;  		Params();  	}; @@ -250,6 +252,8 @@ public:  	boost::signals2::connection setVisibleCallback( const commit_signal_t::slot_type& cb ); +	bool acceptsBadge() const { return mAcceptsBadge; } +  protected:  	// Override to set not found list  	LLButton*		getDefaultButton() { return mDefaultBtn; } @@ -264,6 +268,7 @@ protected:  	static factory_stack_t	sFactoryStack;  private: +	bool			mAcceptsBadge;  	BOOL			mBgVisible;				// any background at all?  	BOOL			mBgOpaque;				// use opaque color or image  	LLUIColor		mBgOpaqueColor; diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp index 0a06b5e74f..d58df5801b 100644 --- a/indra/llui/lluictrl.cpp +++ b/indra/llui/lluictrl.cpp @@ -68,6 +68,7 @@ LLUICtrl::ControlVisibility::ControlVisibility()  LLUICtrl::Params::Params()  :	tab_stop("tab_stop", true),  	chrome("chrome", false), +	requests_front("requests_front", false),  	label("label"),  	initial_value("value"),  	init_callback("init_callback"), @@ -96,9 +97,10 @@ const LLUICtrl::Params& LLUICtrl::getDefaultParams()  LLUICtrl::LLUICtrl(const LLUICtrl::Params& p, const LLViewModelPtr& viewmodel)   :	LLView(p), -	mTentative(FALSE),  	mIsChrome(FALSE), +	mRequestsFront(p.requests_front),  	mTabStop(FALSE), +	mTentative(FALSE),      mViewModel(viewmodel),  	mControlVariable(NULL),  	mEnabledControlVariable(NULL), @@ -123,6 +125,8 @@ void LLUICtrl::initFromParams(const Params& p)  {  	LLView::initFromParams(p); +	mRequestsFront = p.requests_front; +  	setIsChrome(p.chrome);  	setControlName(p.control_name);  	if(p.enabled_controls.isProvided()) @@ -403,6 +407,36 @@ LLViewModel* LLUICtrl::getViewModel() const  	return mViewModel;  } +//virtual +BOOL LLUICtrl::postBuild() +{ +	// +	// Find all of the children that want to be in front and move them to the front +	// + +	if (getChildCount() > 0) +	{ +		std::vector<LLUICtrl*> childrenToMoveToFront; + +		for (LLView::child_list_const_iter_t child_it = beginChild(); child_it != endChild(); ++child_it) +		{ +			LLUICtrl* uictrl = dynamic_cast<LLUICtrl*>(*child_it); + +			if (uictrl && uictrl->mRequestsFront) +			{ +				childrenToMoveToFront.push_back(uictrl); +			} +		} + +		for (std::vector<LLUICtrl*>::iterator it = childrenToMoveToFront.begin(); it != childrenToMoveToFront.end(); ++it) +		{ +			sendChildToFront(*it); +		} +	} + +	return LLView::postBuild(); +} +  bool LLUICtrl::setControlValue(const LLSD& value)  {  	if (mControlVariable) diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h index b37e9f6b1b..09bed9b958 100644 --- a/indra/llui/lluictrl.h +++ b/indra/llui/lluictrl.h @@ -94,7 +94,8 @@ public:  	{  		Optional<std::string>			label;  		Optional<bool>					tab_stop, -										chrome; +										chrome, +										requests_front;  		Optional<LLSD>					initial_value;  		Optional<CommitCallbackParam>	init_callback, @@ -143,6 +144,8 @@ protected:  	virtual LLViewModel* getViewModel() const;      // We shouldn't ever need to set this directly      //virtual void    setViewModel(const LLViewModelPtr&); + +	virtual BOOL	postBuild();  public:  	// LLView interface @@ -301,8 +304,9 @@ protected:  private: -	BOOL			mTabStop;  	BOOL			mIsChrome; +	BOOL			mRequestsFront; +	BOOL			mTabStop;  	BOOL			mTentative;  	LLRootHandle<LLUICtrl> mUICtrlHandle; diff --git a/indra/llui/tests/llurlmatch_test.cpp b/indra/llui/tests/llurlmatch_test.cpp index e09ef33d49..3cd61e574e 100644 --- a/indra/llui/tests/llurlmatch_test.cpp +++ b/indra/llui/tests/llurlmatch_test.cpp @@ -95,7 +95,7 @@ namespace LLInitParam  	{  		const U8* my_addr = reinterpret_cast<const U8*>(this);  		const U8* block_addr = reinterpret_cast<const U8*>(enclosing_block); -		mEnclosingBlockOffset = (U16)(my_addr - block_addr); +		mEnclosingBlockOffset = 0x7FFFffff & ((U32)(my_addr - block_addr));  	}  	bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, S32 generation){ return true; } diff --git a/indra/llxuixml/llinitparam.cpp b/indra/llxuixml/llinitparam.cpp index b3312798dd..c024fd405e 100644 --- a/indra/llxuixml/llinitparam.cpp +++ b/indra/llxuixml/llinitparam.cpp @@ -40,7 +40,7 @@ namespace LLInitParam  	{  		const U8* my_addr = reinterpret_cast<const U8*>(this);  		const U8* block_addr = reinterpret_cast<const U8*>(enclosing_block); -		mEnclosingBlockOffset = (U16)(my_addr - block_addr); +		mEnclosingBlockOffset = 0x7FFFffff & ((U32)(my_addr - block_addr));  	}  	// diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h index a853999e94..35c889b69f 100644 --- a/indra/llxuixml/llinitparam.h +++ b/indra/llxuixml/llinitparam.h @@ -34,6 +34,8 @@  #include <boost/unordered_map.hpp>  #include <boost/shared_ptr.hpp> +#include "llerror.h" +  namespace LLInitParam  {  	template<typename T> const T& defaultValue() { static T value; return value; } @@ -302,8 +304,9 @@ namespace LLInitParam  	private:  		friend class BaseBlock; -		U16			mEnclosingBlockOffset; -		bool		mIsProvided; +		U32		mEnclosingBlockOffset:31; +		U32		mIsProvided:1; +  	};  	// various callbacks and constraints associated with an individual param diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 523ea8a394..d79d3f1f72 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -361,6 +361,8 @@ set(viewer_SOURCE_FILES      llpanellogin.cpp      llpanelloginlistener.cpp      llpanelmaininventory.cpp +	llpanelmarketplaceinbox.cpp +	llpanelmarketplaceoutbox.cpp      llpanelmediasettingsgeneral.cpp      llpanelmediasettingspermissions.cpp      llpanelmediasettingssecurity.cpp @@ -909,6 +911,8 @@ set(viewer_HEADER_FILES      llpanellogin.h      llpanelloginlistener.h      llpanelmaininventory.h +	llpanelmarketplaceinbox.h +	llpanelmarketplaceoutbox.h      llpanelmediasettingsgeneral.h      llpanelmediasettingspermissions.h      llpanelmediasettingssecurity.h @@ -1465,7 +1469,7 @@ set(PACKAGE ON CACHE BOOL      "Add a package target that builds an installer package.")  if (WINDOWS) -	set_target_properties(${VIEWER_BINARY_NAME} +    set_target_properties(${VIEWER_BINARY_NAME}          PROPERTIES          # *TODO -reenable this once we get server usage sorted out          #LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:WINDOWS /INCLUDE:\"__tcmalloc\"" diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 76fecdf05e..34a179f95b 100755 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -4180,6 +4180,28 @@        <key>Value</key>        <real>1.0</real>      </map> +    <key>InventoryDisplayInbox</key> +    <map> +        <key>Comment</key> +        <string>Override received items inventory inbox display</string> +        <key>Persist</key> +        <integer>0</integer> +        <key>Type</key> +        <string>Boolean</string> +        <key>Value</key> +        <integer>0</integer> +    </map> +    <key>InventoryDisplayOutbox</key> +    <map> +        <key>Comment</key> +        <string>Override merchant inventory outbox display</string> +        <key>Persist</key> +        <integer>0</integer> +        <key>Type</key> +        <string>Boolean</string> +        <key>Value</key> +        <integer>0</integer> +    </map>  	<key>InventoryLinking</key>  	<map>  		<key>Comment</key> @@ -4422,6 +4444,17 @@        <key>Value</key>          <real>2.0</real>      </map> +    <key>LastInventoryInboxExpand</key> +    <map> +        <key>Comment</key> +        <string>The last time the received items inbox was expanded.</string> +        <key>Persist</key> +        <integer>1</integer> +        <key>Type</key> +        <string>String</string> +        <key>Value</key> +        <string /> +    </map>      <key>LCDDestination</key>      <map>        <key>Comment</key> @@ -6546,7 +6579,28 @@        <key>Value</key>        <integer>0</integer>      </map> - +   <key>PostFirstLoginIntroURL</key> +   <map> +     <key>Comment</key> +     <string>URL of intro presenatation after first time users first login</string> +     <key>Persist</key> +     <integer>1</integer> +     <key>Type</key> +     <string>String</string> +     <key>Value</key> +     <string></string> +   </map> +  <key>PostFirstLoginIntroViewed</key> +  <map> +    <key>Comment</key> +    <string>Flag indicating if user has seen intro presenatation after first time users first login</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>Boolean</string> +    <key>Value</key> +    <string>0</string> +  </map>      <key>PrecachingDelay</key>      <map>        <key>Comment</key> @@ -7182,7 +7236,7 @@      </array>    </map> -  <key>RenderAnisotropic</key> +    <key>RenderAnisotropic</key>      <map>        <key>Comment</key>        <string>Render textures using anisotropic filtering</string> diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index cbbdcb2983..eeb4ec8458 100755 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -69,6 +69,7 @@  #include "lltrans.h"  #include "llcallingcard.h"  #include "llslurl.h"			// IDEVO +#include "llsidepanelinventory.h"  // static  void LLAvatarActions::requestFriendshipDialog(const LLUUID& id, const std::string& name) @@ -444,8 +445,6 @@ void LLAvatarActions::share(const LLUUID& id)  namespace action_give_inventory  { -	typedef std::set<LLUUID> uuid_set_t; -  	/**  	 * Returns a pointer to 'Add More' inventory panel of Edit Outfit SP.  	 */ @@ -475,18 +474,16 @@ namespace action_give_inventory  	/**  	 * Checks My Inventory visibility.  	 */ +  	static bool is_give_inventory_acceptable()  	{ -		LLInventoryPanel* active_panel = get_active_inventory_panel(); -		if (!active_panel) return false; -  		// check selection in the panel -		const uuid_set_t inventory_selected_uuids = active_panel->getRootFolder()->getSelectionList(); +		const std::set<LLUUID> inventory_selected_uuids = LLAvatarActions::getInventorySelectedUUIDs();  		if (inventory_selected_uuids.empty()) return false; // nothing selected  		bool acceptable = false; -		uuid_set_t::const_iterator it = inventory_selected_uuids.begin(); -		const uuid_set_t::const_iterator it_end = inventory_selected_uuids.end(); +		std::set<LLUUID>::const_iterator it = inventory_selected_uuids.begin(); +		const std::set<LLUUID>::const_iterator it_end = inventory_selected_uuids.end();  		for (; it != it_end; ++it)  		{  			LLViewerInventoryCategory* inv_cat = gInventory.getCategory(*it); @@ -529,12 +526,12 @@ namespace action_give_inventory  		}  	} -	static void build_items_string(const uuid_set_t& inventory_selected_uuids , std::string& items_string) +	static void build_items_string(const std::set<LLUUID>& inventory_selected_uuids , std::string& items_string)  	{  		llassert(inventory_selected_uuids.size() > 0);  		const std::string& separator = LLTrans::getString("words_separator"); -		for (uuid_set_t::const_iterator it = inventory_selected_uuids.begin(); ; ) +		for (std::set<LLUUID>::const_iterator it = inventory_selected_uuids.begin(); ; )  		{  			LLViewerInventoryCategory* inv_cat = gInventory.getCategory(*it);  			if (NULL != inv_cat) @@ -570,10 +567,7 @@ namespace action_give_inventory  			return;  		} -		LLInventoryPanel* active_panel = get_active_inventory_panel(); -		if (!active_panel) return; - -		const uuid_set_t inventory_selected_uuids = active_panel->getRootFolder()->getSelectionList(); +		const std::set<LLUUID> inventory_selected_uuids = LLAvatarActions::getInventorySelectedUUIDs();  		if (inventory_selected_uuids.empty())  		{  			return; @@ -590,8 +584,8 @@ namespace action_give_inventory  			// We souldn't open IM session, just calculate session ID for logging purpose. See EXT-6710  			const LLUUID session_id = gIMMgr->computeSessionID(IM_NOTHING_SPECIAL, avatar_uuid); -			uuid_set_t::const_iterator it = inventory_selected_uuids.begin(); -			const uuid_set_t::const_iterator it_end = inventory_selected_uuids.end(); +			std::set<LLUUID>::const_iterator it = inventory_selected_uuids.begin(); +			const std::set<LLUUID>::const_iterator it_end = inventory_selected_uuids.end();  			const std::string& separator = LLTrans::getString("words_separator");  			std::string noncopy_item_names; @@ -654,10 +648,7 @@ namespace action_give_inventory  	{  		llassert(avatar_names.size() == avatar_uuids.size()); -		LLInventoryPanel* active_panel = get_active_inventory_panel(); -		if (!active_panel) return; - -		const uuid_set_t inventory_selected_uuids = active_panel->getRootFolder()->getSelectionList(); +		const std::set<LLUUID> inventory_selected_uuids = LLAvatarActions::getInventorySelectedUUIDs();  		if (inventory_selected_uuids.empty())  		{  			return; @@ -678,6 +669,33 @@ namespace action_give_inventory  	}  } + + +//static +std::set<LLUUID> LLAvatarActions::getInventorySelectedUUIDs() +{ +	std::set<LLUUID> inventory_selected_uuids; + +	LLInventoryPanel* active_panel = action_give_inventory::get_active_inventory_panel(); +	if (active_panel) +	{ +		inventory_selected_uuids = active_panel->getRootFolder()->getSelectionList(); +	} + +	if (inventory_selected_uuids.empty()) +	{ +		LLSidepanelInventory * sidepanel_inventory = LLSideTray::getInstance()->getPanel<LLSidepanelInventory>("sidepanel_inventory"); +		LLInventoryPanel * inbox = sidepanel_inventory->findChild<LLInventoryPanel>("inventory_inbox"); +		if (inbox) +		{ +			inventory_selected_uuids = inbox->getRootFolder()->getSelectionList(); +		} + +	} + +	return inventory_selected_uuids; +} +  //static  void LLAvatarActions::shareWithAvatars()  { @@ -705,12 +723,12 @@ bool LLAvatarActions::canShareSelectedItems(LLInventoryPanel* inv_panel /* = NUL  	// check selection in the panel  	LLFolderView* root_folder = inv_panel->getRootFolder(); -	const uuid_set_t inventory_selected_uuids = root_folder->getSelectionList(); +	const std::set<LLUUID> inventory_selected_uuids = root_folder->getSelectionList();  	if (inventory_selected_uuids.empty()) return false; // nothing selected  	bool can_share = true; -	uuid_set_t::const_iterator it = inventory_selected_uuids.begin(); -	const uuid_set_t::const_iterator it_end = inventory_selected_uuids.end(); +	std::set<LLUUID>::const_iterator it = inventory_selected_uuids.begin(); +	const std::set<LLUUID>::const_iterator it_end = inventory_selected_uuids.end();  	for (; it != it_end; ++it)  	{  		LLViewerInventoryCategory* inv_cat = gInventory.getCategory(*it); diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h index 956fed7461..fbfd815f41 100644 --- a/indra/newview/llavataractions.h +++ b/indra/newview/llavataractions.h @@ -36,6 +36,7 @@  class LLInventoryPanel; +  /**   * Friend-related actions (add, remove, offer teleport, etc)   */ @@ -196,6 +197,8 @@ public:  	 */  	static bool canShareSelectedItems(LLInventoryPanel* inv_panel = NULL); +	static std::set<LLUUID> getInventorySelectedUUIDs(); +  private:  	static bool callbackAddFriendWithMessage(const LLSD& notification, const LLSD& response);  	static bool handleRemove(const LLSD& notification, const LLSD& response); diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp index 3884b94b60..866eae8d3d 100644 --- a/indra/newview/llfolderview.cpp +++ b/indra/newview/llfolderview.cpp @@ -167,13 +167,22 @@ void LLCloseAllFoldersFunctor::doItem(LLFolderViewItem* item)  ///----------------------------------------------------------------------------  /// Class LLFolderView  ///---------------------------------------------------------------------------- +LLFolderView::Params::Params() +:	task_id("task_id"), +	title("title"), +	use_label_suffix("use_label_suffix"), +	allow_multiselect("allow_multiselect", true), +	use_ellipses("use_ellipses", false) +{ +} +  // Default constructor  LLFolderView::LLFolderView(const Params& p)  :	LLFolderViewFolder(p),  	mScrollContainer( NULL ),  	mPopupMenuHandle(), -	mAllowMultiSelect(TRUE), +	mAllowMultiSelect(p.allow_multiselect),  	mShowFolderHierarchy(FALSE),  	mSourceID(p.task_id),  	mRenameItem( NULL ), @@ -194,10 +203,12 @@ LLFolderView::LLFolderView(const Params& p)  	mDragAndDropThisFrame(FALSE),  	mCallbackRegistrar(NULL),  	mParentPanel(p.parent_panel), -	mUseEllipses(false), +	mUseEllipses(p.use_ellipses),  	mDraggingOverItem(NULL),  	mStatusTextBox(NULL)  { +	mRoot = this; +  	LLRect rect = p.rect;  	LLRect new_rect(rect.mLeft, rect.mBottom + getRect().getHeight(), rect.mLeft + getRect().getWidth(), rect.mBottom);  	setRect( rect ); @@ -424,11 +435,7 @@ S32 LLFolderView::arrange( S32* unused_width, S32* unused_height, S32 filter_gen  									(folderp->getFiltered(filter_generation) || folderp->hasFilteredDescendants(filter_generation))); // passed filter or has descendants that passed filter  		} -		// Need to call arrange regardless of visibility, since children's visibility -		// might need to be changed too (e.g. even though a folder is invisible, its -		// children also need to be set invisible for state-tracking purposes, e.g. -		// llfolderviewitem::filter). -		// if (folderp->getVisible()) +		if (folderp->getVisible())  		{  			S32 child_height = 0;  			S32 child_width = 0; @@ -764,7 +771,7 @@ void LLFolderView::sanitizeSelection()  		}  		// Don't allow invisible items (such as root folders) to be selected. -		if (item->getHidden()) +		if (item == getRoot())  		{  			items_to_remove.push_back(item);  		} @@ -787,7 +794,7 @@ void LLFolderView::sanitizeSelection()  				parent_folder;  				parent_folder = parent_folder->getParentFolder())  			{ -				if (parent_folder->potentiallyVisible() && !parent_folder->getHidden()) +				if (parent_folder->potentiallyVisible())  				{  					// give initial selection to first ancestor folder that potentially passes the filter  					if (!new_selection) @@ -962,7 +969,9 @@ void LLFolderView::draw()  	} -	LLFolderViewFolder::draw(); +	// skip over LLFolderViewFolder::draw since we don't want the folder icon, label,  +	// and arrow for the root folder +	LLView::draw();  	mDragAndDropThisFrame = FALSE;  } @@ -1642,12 +1651,8 @@ BOOL LLFolderView::handleKeyHere( KEY key, MASK mask )  			LLFolderViewItem* parent_folder = last_selected->getParentFolder();  			if (!last_selected->isOpen() && parent_folder && parent_folder->getParentFolder())  			{ -				// Don't change selectin to hidden folder. See EXT-5328. -				if (!parent_folder->getHidden()) -				{  					setSelection(parent_folder, FALSE, TRUE);  				} -			}  			else  			{  				last_selected->setOpen( FALSE ); @@ -2031,7 +2036,7 @@ void LLFolderView::removeItemID(const LLUUID& id)  LLFolderViewItem* LLFolderView::getItemByID(const LLUUID& id)  { -	if (id.isNull()) +	if (id == getListener()->getUUID())  	{  		return this;  	} @@ -2048,7 +2053,7 @@ LLFolderViewItem* LLFolderView::getItemByID(const LLUUID& id)  LLFolderViewFolder* LLFolderView::getFolderByID(const LLUUID& id)  { -	if (id.isNull()) +	if (id == getListener()->getUUID())  	{  		return this;  	} @@ -2496,11 +2501,6 @@ BOOL LLFolderView::isFilterModified()  	return mFilter->isNotDefault();  } -BOOL LLFolderView::getAllowMultiSelect() -{ -	return mAllowMultiSelect; -} -  void delete_selected_item(void* user_data)  {  	if(user_data) diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h index 1464a058d8..12f6170a7d 100644 --- a/indra/newview/llfolderview.h +++ b/indra/newview/llfolderview.h @@ -89,7 +89,11 @@ public:  		Mandatory<LLPanel*>	    parent_panel;  		Optional<LLUUID>        task_id;  		Optional<std::string>   title; -		Optional<bool>			use_label_suffix; +		Optional<bool>			use_label_suffix, +								allow_multiselect, +								use_ellipses; + +		Params();  	};  	LLFolderView(const Params&);  	virtual ~LLFolderView( void ); @@ -102,7 +106,6 @@ public:  	// and resort the items if necessary.  	void setSortOrder(U32 order);  	void setFilterPermMask(PermissionMask filter_perm_mask); -	void setAllowMultiSelect(BOOL allow) { mAllowMultiSelect = allow; }  	typedef boost::signals2::signal<void (const std::deque<LLFolderViewItem*>& items, BOOL user_action)> signal_t;  	void setSelectCallback(const signal_t::slot_type& cb) { mSelectSignal.connect(cb); } @@ -117,7 +120,6 @@ public:  	//LLInventoryFilter::EFolderShow getShowFolderState();  	U32 getSortOrder() const;  	BOOL isFilterModified(); -	BOOL getAllowMultiSelect();  	// Close all folders in the view  	void closeAllFolders(); @@ -238,7 +240,6 @@ public:  	void setShowSingleSelection(BOOL show);  	BOOL getShowSingleSelection() { return mShowSingleSelection; }  	F32  getSelectionFadeElapsedTime() { return mMultiSelectionFadeTimer.getElapsedTimeF32(); } -	void setUseEllipses(bool use_ellipses) { mUseEllipses = use_ellipses; }  	bool getUseEllipses() { return mUseEllipses; }  	void addItemID(const LLUUID& id, LLFolderViewItem* itemp); diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp index e9d1ad3a9e..38b36af6f0 100644 --- a/indra/newview/llfolderviewitem.cpp +++ b/indra/newview/llfolderviewitem.cpp @@ -30,6 +30,7 @@  // viewer includes  #include "llfolderview.h"		// Items depend extensively on LLFolderViews  #include "llfoldervieweventlistener.h" +#include "llviewerfoldertype.h"  #include "llinventorybridge.h"	// for LLItemBridge in LLInventorySort::operator()  #include "llinventoryfilter.h"  #include "llinventorymodelbackgroundfetch.h" @@ -130,10 +131,14 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)  	mIconOpen(p.icon_open),  	mIconOverlay(p.icon_overlay),  	mListener(p.listener), -	mHidden(false),  	mShowLoadStatus(false)  { +} + +BOOL LLFolderViewItem::postBuild() +{  	refresh(); +	return TRUE;  }  // Destroys the object @@ -195,7 +200,7 @@ LLFolderViewItem* LLFolderViewItem::getPreviousOpenNode(BOOL include_children)  	LLFolderViewItem* itemp = mParentFolder->getPreviousFromChild( this, include_children );  	// Skip over items that are invisible or are hidden from the UI. -	while(itemp && (!itemp->getVisible() || itemp->getHidden())) +	while(itemp && !itemp->getVisible())  	{  		LLFolderViewItem* next_itemp = itemp->mParentFolder->getPreviousFromChild( itemp, include_children );  		if (itemp == next_itemp)  @@ -351,7 +356,10 @@ void LLFolderViewItem::arrangeAndSet(BOOL set_selection,  									 BOOL take_keyboard_focus)  {  	LLFolderView* root = getRoot(); +	if (getParentFolder()) +	{  	getParentFolder()->requestArrange(); +	}  	if(set_selection)  	{  		setSelectionFromRoot(this, TRUE, take_keyboard_focus); @@ -442,23 +450,20 @@ S32 LLFolderViewItem::arrange( S32* width, S32* height, S32 filter_generation)  S32 LLFolderViewItem::getItemHeight()  { -	if (getHidden()) return 0; -  	return mItemHeight;  }  void LLFolderViewItem::filter( LLInventoryFilter& filter)  {  	const BOOL previous_passed_filter = mPassedFilter; -	const BOOL passed_filter = mListener && filter.check(this); +	const BOOL passed_filter = filter.check(this);  	// If our visibility will change as a result of this filter, then  	// we need to be rearranged in our parent folder  	if (mParentFolder)  	{ -		if (getVisible() != passed_filter) -			mParentFolder->requestArrange(); -		if (passed_filter != previous_passed_filter) +		if (getVisible() != passed_filter +			||	previous_passed_filter != passed_filter )  			mParentFolder->requestArrange();  	} @@ -863,11 +868,6 @@ BOOL LLFolderViewItem::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,  void LLFolderViewItem::draw()  { -	if (getHidden()) -	{ -		return; -	} -  	static LLUIColor sFgColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);  	static LLUIColor sHighlightBgColor = LLUIColorTable::instance().getColor("MenuItemHighlightBgColor", DEFAULT_WHITE);  	static LLUIColor sHighlightFgColor = LLUIColorTable::instance().getColor("MenuItemHighlightFgColor", DEFAULT_WHITE); @@ -891,8 +891,8 @@ void LLFolderViewItem::draw()  	// Draw open folder arrow  	//  	const bool up_to_date = mListener && mListener->isUpToDate(); -	const bool possibly_has_children = ((up_to_date && hasVisibleChildren()) || // we fetched our children and some of them have passed the filter... -										(!up_to_date && mListener && mListener->hasChildren())); // ...or we know we have children but haven't fetched them (doesn't obey filter) +	const bool possibly_has_children = ((up_to_date && hasVisibleChildren()) // we fetched our children and some of them have passed the filter... +										|| (!up_to_date && mListener && mListener->hasChildren())); // ...or we know we have children but haven't fetched them (doesn't obey filter)  	if (possibly_has_children)  	{  		LLUIImage* arrow_image = default_params.folder_arrow_image; @@ -1054,8 +1054,11 @@ void LLFolderViewItem::draw()  	{  		root_is_loading = LLInventoryModelBackgroundFetch::instance().libraryFetchInProgress();  	} -	if ((mIsLoading && mTimeSinceRequestStart.getElapsedTimeF32() >= gSavedSettings.getF32("FolderLoadingMessageWaitTime")) || -		(LLInventoryModelBackgroundFetch::instance().backgroundFetchActive() && root_is_loading && (mShowLoadStatus || mHidden))) +	if ((mIsLoading +		&&	mTimeSinceRequestStart.getElapsedTimeF32() >= gSavedSettings.getF32("FolderLoadingMessageWaitTime")) +			||	(LLInventoryModelBackgroundFetch::instance().backgroundFetchActive() +				&&	root_is_loading +				&&	mShowLoadStatus))  	{  		std::string load_string = " ( " + LLTrans::getString("LoadingData") + " ) ";  		font->renderUTF8(load_string, 0, right_x, y, sSearchStatusColor, @@ -1119,7 +1122,8 @@ LLFolderViewFolder::LLFolderViewFolder( const LLFolderViewItem::Params& p ):  	mLastCalculatedWidth(0),  	mCompletedFilterGeneration(-1),  	mMostFilteredDescendantGeneration(-1), -	mNeedsSort(false) +	mNeedsSort(false), +	mPassedFolderFilter(FALSE)  {  } @@ -1131,6 +1135,17 @@ LLFolderViewFolder::~LLFolderViewFolder( void )  	gFocusMgr.releaseFocusIfNeeded( this ); // calls onCommit()  } +void LLFolderViewFolder::setFilteredFolder(bool filtered, S32 filter_generation) +{ +	mPassedFolderFilter = filtered; +	mLastFilterGeneration = filter_generation; +} + +bool LLFolderViewFolder::getFilteredFolder(S32 filter_generation) +{ +	return mPassedFolderFilter && mLastFilterGeneration >= getRoot()->getFilter()->getMinRequiredGeneration(); +} +  // addToFolder() returns TRUE if it succeeds. FALSE otherwise  BOOL LLFolderViewFolder::addToFolder(LLFolderViewFolder* folder, LLFolderView* root)  { @@ -1157,8 +1172,6 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height, S32 filter_generation)  	mHasVisibleChildren = hasFilteredDescendants(filter_generation); -	LLInventoryFilter::EFolderShow show_folder_state = getRoot()->getFilter()->getShowFolderState(); -  	// calculate height as a single item (without any children), and reshapes rectangle to match  	LLFolderViewItem::arrange( width, height, filter_generation ); @@ -1190,8 +1203,11 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height, S32 filter_generation)  				}  				else  				{ -					folderp->setVisible(show_folder_state == LLInventoryFilter::SHOW_ALL_FOLDERS || // always show folders? -						(folderp->getFiltered(filter_generation) || folderp->hasFilteredDescendants(filter_generation))); // passed filter or has descendants that passed filter +					bool is_hidden = folderp->getListener() && LLViewerFolderType::lookupIsHiddenType(folderp->getListener()->getPreferredType()); + +					folderp->setVisible( !is_hidden  +										&&	(show_folder_state == LLInventoryFilter::SHOW_ALL_FOLDERS  +											|| (folderp->getFiltered(filter_generation) || folderp->hasFilteredDescendants(filter_generation)))); // passed filter or has descendants that passed filter  				}  				if (folderp->getVisible()) @@ -1311,7 +1327,9 @@ void LLFolderViewFolder::setCompletedFilterGeneration(S32 generation, BOOL recur  	mMostFilteredDescendantGeneration = llmin(mMostFilteredDescendantGeneration, generation);  	mCompletedFilterGeneration = generation;  	// only aggregate up if we are a lower (older) value -	if (recurse_up && mParentFolder && generation < mParentFolder->getCompletedFilterGeneration()) +	if (recurse_up +		&& mParentFolder +		&& generation < mParentFolder->getCompletedFilterGeneration())  	{  		mParentFolder->setCompletedFilterGeneration(generation, TRUE);  	} @@ -1336,21 +1354,19 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter)  	// filter folder itself  	if (getLastFilterGeneration() < filter_generation)  	{ -		if (getLastFilterGeneration() >= must_pass_generation &&		// folder has been compared to a valid precursor filter -			!mPassedFilter)													// and did not pass the filter +		if (getLastFilterGeneration() >= must_pass_generation	// folder has been compared to a valid precursor filter +			&& !mPassedFilter)									// and did not pass the filter  		{  			// go ahead and flag this folder as done  			mLastFilterGeneration = filter_generation;			  		} -		else +		else // filter self only on first pass through  		{ -			// filter self only on first pass through +			// filter against folder rules +			filterFolder(filter); +			// and then item rules  			LLFolderViewItem::filter( filter );  		} -		if (mHidden) -		{ -			setOpen(); -		}  	}  	if (getRoot()->getDebugFilters()) @@ -1377,7 +1393,10 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter)  	}  	// when applying a filter, matching folders get their contents downloaded first -	if (filter.isNotDefault() && getFiltered(filter.getMinRequiredGeneration()) && (mListener && !gInventory.isCategoryComplete(mListener->getUUID()))) +	if (filter.isNotDefault() +		&& getFiltered(filter.getMinRequiredGeneration()) +		&&	(mListener +			&& !gInventory.isCategoryComplete(mListener->getUUID())))  	{  		LLInventoryModelBackgroundFetch::instance().start(mListener->getUUID());  	} @@ -1467,6 +1486,31 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter)  	}  } +void LLFolderViewFolder::filterFolder(LLInventoryFilter& filter) +{ +	const BOOL previous_passed_filter = mPassedFolderFilter; +	const BOOL passed_filter = filter.checkFolder(this); + +	// If our visibility will change as a result of this filter, then +	// we need to be rearranged in our parent folder +	if (mParentFolder) +	{ +		if (getVisible() != passed_filter +			|| previous_passed_filter != passed_filter ) +		{ +			mParentFolder->requestArrange(); +		} +	} + +	setFilteredFolder(passed_filter, filter.getCurrentGeneration()); +	filter.decrementFilterCount(); + +	if (getRoot()->getDebugFilters()) +	{ +		mStatusText = llformat("%d", mLastFilterGeneration); +	} +} +  void LLFolderViewFolder::setFiltered(BOOL filtered, S32 filter_generation)  {  	// if this folder is now filtered, but wasn't before @@ -1981,6 +2025,13 @@ BOOL LLFolderViewFolder::addItem(LLFolderViewItem* item)  	item->dirtyFilter();  	requestArrange();  	requestSort(); +	LLFolderViewFolder* parentp = getParentFolder(); +	while (parentp && !parentp->getCreationDate()) +	{ +		// parent folder doesn't have a time stamp yet, so get it from us +		parentp->requestSort(); +		parentp = parentp->getParentFolder(); +	}  	return TRUE;  } @@ -2000,6 +2051,13 @@ BOOL LLFolderViewFolder::addFolder(LLFolderViewFolder* folder)  	// rearrange all descendants too, as our indentation level might have changed  	folder->requestArrange(TRUE);  	requestSort(); +	LLFolderViewFolder* parentp = getParentFolder(); +	while (parentp && !parentp->getCreationDate()) +	{ +		// parent folder doesn't have a time stamp yet, so get it from us +		parentp->requestSort(); +		parentp = parentp->getParentFolder(); +	}  	return TRUE;  } @@ -2059,7 +2117,9 @@ void LLFolderViewFolder::setOpenArrangeRecursively(BOOL openitem, ERecurseType r  			(*fit)->setOpenArrangeRecursively(openitem, RECURSE_DOWN);		/* Flawfinder: ignore */  		}  	} -	if (mParentFolder && (recurse == RECURSE_UP || recurse == RECURSE_UP_DOWN)) +	if (mParentFolder +		&&	(recurse == RECURSE_UP +			|| recurse == RECURSE_UP_DOWN))  	{  		mParentFolder->setOpenArrangeRecursively(openitem, RECURSE_UP);  	} @@ -2301,13 +2361,16 @@ void LLFolderViewFolder::draw()  	bool possibly_has_children = false;  	bool up_to_date = mListener && mListener->isUpToDate(); -	if(!up_to_date && mListener && mListener->hasChildren()) // we know we have children but haven't fetched them (doesn't obey filter) +	if(!up_to_date +		&& mListener->hasChildren()) // we know we have children but haven't fetched them (doesn't obey filter)  	{  		possibly_has_children = true;  	} -	BOOL loading = ( mIsOpen && possibly_has_children && !up_to_date ); +	BOOL loading = (mIsOpen +					&& possibly_has_children +					&& !up_to_date );  	if ( loading && !mIsLoading )  	{ @@ -2330,6 +2393,21 @@ void LLFolderViewFolder::draw()  time_t LLFolderViewFolder::getCreationDate() const  { +	// folders have no creation date so use first non-folder descendent's date +	if (!mCreationDate) +	{ +		for(items_t::const_iterator iit = mItems.begin(); +			iit != mItems.end(); ++iit) +		{ +			LLFolderViewItem* itemp = (*iit); +			if (itemp->getCreationDate()) +			{ +				mCreationDate = itemp->getCreationDate(); +				break; +			} +		} +	} +  	return llmax<time_t>(mCreationDate, mSubtreeCreationDate);  } @@ -2573,7 +2651,8 @@ bool LLInventorySort::operator()(const LLFolderViewItem* const& a, const LLFolde  {  	// ignore sort order for landmarks in the Favorites folder.  	// they should be always sorted as in Favorites bar. See EXT-719 -	if (a->getSortGroup() == SG_ITEM && b->getSortGroup() == SG_ITEM +	if (a->getSortGroup() == SG_ITEM +		&& b->getSortGroup() == SG_ITEM  		&& a->getListener()->getInventoryType() == LLInventoryType::IT_LANDMARK  		&& b->getListener()->getInventoryType() == LLInventoryType::IT_LANDMARK)  	{ diff --git a/indra/newview/llfolderviewitem.h b/indra/newview/llfolderviewitem.h index fc941510ab..40c8eaa0a4 100644 --- a/indra/newview/llfolderviewitem.h +++ b/indra/newview/llfolderviewitem.h @@ -135,7 +135,7 @@ protected:  	std::string					mSearchableLabel;  	S32							mLabelWidth;  	bool						mLabelWidthDirty; -	time_t						mCreationDate; +	mutable time_t				mCreationDate;  	LLFolderViewFolder*			mParentFolder;  	LLFolderViewEventListener*	mListener;  	BOOL						mIsCurSelection; @@ -157,7 +157,6 @@ protected:  	BOOL						mDragAndDropTarget;  	BOOL                        mIsLoading;  	LLTimer                     mTimeSinceRequestStart; -	bool						mHidden;  	bool						mShowLoadStatus;  	// helper function to change the selection from the root. @@ -167,13 +166,15 @@ protected:  	void extendSelectionFromRoot(LLFolderViewItem* selection);  	// this is an internal method used for adding items to folders. A -	// no-op at this leve, but reimplemented in derived classes. +	// no-op at this level, but reimplemented in derived classes.  	virtual BOOL addItem(LLFolderViewItem*) { return FALSE; }  	virtual BOOL addFolder(LLFolderViewFolder*) { return FALSE; }  	static LLFontGL* getLabelFontForStyle(U8 style);  public: +	BOOL postBuild(); +  	// This function clears the currently selected item, and records  	// the specified selected item appropriately for display and use  	// in the UI. If open is TRUE, then folders are opened up along @@ -202,11 +203,6 @@ public:  	virtual S32 arrange( S32* width, S32* height, S32 filter_generation );  	virtual S32 getItemHeight(); -	// Hide the folder from the UI, such as if you want to hide the root -	// folder in an inventory panel. -	void setHidden(bool hidden) { mHidden = hidden; } -	bool getHidden() const { return mHidden; } -  	// applies filters to control visibility of inventory items  	virtual void filter( LLInventoryFilter& filter); @@ -366,6 +362,9 @@ public:  		UNKNOWN, TRASH, NOT_TRASH  	} ETrash; +	typedef std::list<LLFolderViewItem*> items_t; +	typedef std::list<LLFolderViewFolder*> folders_t; +  private:  	S32		mNumDescendantsSelected; @@ -374,8 +373,6 @@ public:		// Accessed needed by LLFolderViewItem  	S32 numSelected(void) const { return mNumDescendantsSelected + (isSelected() ? 1 : 0); }  protected: -	typedef std::list<LLFolderViewItem*> items_t; -	typedef std::list<LLFolderViewFolder*> folders_t;  	items_t mItems;  	folders_t mFolders;  	LLInventorySort	mSortFunction; @@ -392,6 +389,8 @@ protected:  	S32			mCompletedFilterGeneration;  	S32			mMostFilteredDescendantGeneration;  	bool		mNeedsSort; +	bool		mPassedFolderFilter; +  public:  	typedef enum e_recurse_type  	{ @@ -433,6 +432,11 @@ public:  	virtual void setFiltered(BOOL filtered, S32 filter_generation);  	virtual void dirtyFilter(); +	// folder-specific filtering (filter status propagates top down instead of bottom up) +	void filterFolder(LLInventoryFilter& filter); +	void setFilteredFolder(bool filtered, S32 filter_generation); +	bool getFilteredFolder(S32 filter_generation); +  	// Passes selection information on to children and record  	// selection information if necessary.  	// Returns TRUE if this object (or a child) ends up being selected. @@ -537,6 +541,9 @@ public:  	time_t getCreationDate() const;  	bool isTrash() const;  	S32 getNumSelectedDescendants(void) const { return mNumDescendantsSelected; } + +	folders_t::const_iterator getFoldersBegin() const { return mFolders.begin(); } +	folders_t::const_iterator getFoldersEnd() const { return mFolders.end(); }  };  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 86c8a1a9b5..58579bdf4f 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -571,8 +571,8 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,  		}  	} -	// Don't allow items to be pasted directly into the COF. -	if (!isCOFFolder()) +	// Don't allow items to be pasted directly into the COF or the inbox +	if (!isCOFFolder() && !isInboxFolder())  	{  		items.push_back(std::string("Paste"));  	} @@ -781,6 +781,18 @@ BOOL LLInvFVBridge::isCOFFolder() const  	return LLAppearanceMgr::instance().getIsInCOF(mUUID);  } +BOOL LLInvFVBridge::isInboxFolder() const +{ +	const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, false, false); +	 +	if (inbox_id.isNull()) +	{ +		return FALSE; +	} +	 +	return gInventory.isObjectDescendentOf(mUUID, inbox_id); +} +  BOOL LLInvFVBridge::isItemPermissive() const  {  	return FALSE; @@ -2525,6 +2537,7 @@ void LLFolderBridge::folderOptionsMenu()  			{  				mItems.push_back(std::string("Add To Outfit"));  			} +  			mItems.push_back(std::string("Replace Outfit"));  		}  		if (is_ensemble) @@ -2614,15 +2627,17 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)  		// Not sure what the right thing is to do here.  		if (!isCOFFolder() && cat && (cat->getPreferredType() != LLFolderType::FT_OUTFIT))  		{ -			// Do not allow to create 2-level subfolder in the Calling Card/Friends folder. EXT-694. -			if (!LLFriendCardsManager::instance().isCategoryInFriendFolder(cat)) -				mItems.push_back(std::string("New Folder")); -			mItems.push_back(std::string("New Script")); -			mItems.push_back(std::string("New Note")); -			mItems.push_back(std::string("New Gesture")); -			mItems.push_back(std::string("New Clothes")); -			mItems.push_back(std::string("New Body Parts")); - +			if (!isInboxFolder()) // don't allow creation in inbox +			{ +				// Do not allow to create 2-level subfolder in the Calling Card/Friends folder. EXT-694. +				if (!LLFriendCardsManager::instance().isCategoryInFriendFolder(cat)) +					mItems.push_back(std::string("New Folder")); +				mItems.push_back(std::string("New Script")); +				mItems.push_back(std::string("New Note")); +				mItems.push_back(std::string("New Gesture")); +				mItems.push_back(std::string("New Clothes")); +				mItems.push_back(std::string("New Body Parts")); +			}  #if SUPPORT_ENSEMBLES  			// Changing folder types is an unfinished unsupported feature  			// and can lead to unexpected behavior if enabled. diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index 1e849c8812..15629c0c75 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -139,6 +139,7 @@ protected:  	BOOL isAgentInventory() const; // false if lost or in the inventory library  	BOOL isCOFFolder() const; // true if COF or descendent of +	BOOL isInboxFolder() const; // true if COF or descendent of marketplace inbox  	virtual BOOL isItemPermissive() const;  	static void changeItemParent(LLInventoryModel* model,  								 LLViewerInventoryItem* item, @@ -584,6 +585,9 @@ protected:  }; +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Recent Inventory Panel related classes +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  // Overridden version of the Inventory-Folder-View-Bridge for Folders  class LLRecentItemsFolderBridge : public LLFolderBridge diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp index dee15a1efd..49e0ab33e5 100644 --- a/indra/newview/llinventoryfilter.cpp +++ b/indra/newview/llinventoryfilter.cpp @@ -107,6 +107,31 @@ BOOL LLInventoryFilter::check(const LLFolderViewItem* item)  	return passed;  } +bool LLInventoryFilter::checkFolder(const LLFolderViewFolder* folder) +{ +	// we're showing all folders, overriding filter +	if (mFilterOps.mShowFolderState == LLInventoryFilter::SHOW_ALL_FOLDERS) +	{ +		return true; +	} + +	const LLFolderViewEventListener* listener = folder->getListener(); +	const LLUUID folder_id = listener->getUUID(); + +	if (mFilterOps.mFilterTypes & FILTERTYPE_CATEGORY) +	{ +		// Can only filter categories for items in your inventory +		// (e.g. versus in-world object contents). +		const LLViewerInventoryCategory *cat = gInventory.getCategory(folder_id); +		if (!cat) +			return false; +		if ((1LL << cat->getPreferredType() & mFilterOps.mFilterCategoryTypes) == U64(0)) +			return false; +	} + +	return true; +} +  BOOL LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) const  {  	const LLFolderViewEventListener* listener = item->getListener(); @@ -137,30 +162,6 @@ BOOL LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) con  		}  	} -	 -	//////////////////////////////////////////////////////////////////////////////// -	// FILTERTYPE_CATEGORY -	// Pass if this item is a category of the filter type, or -	// if its parent is a category of the filter type. -	if (filterTypes & FILTERTYPE_CATEGORY) -	{ -		// Can only filter categories for items in your inventory  -		// (e.g. versus in-world object contents). -		if (!object) return FALSE; - -		LLUUID cat_id = object_id; -		if (listener->getInventoryType() != LLInventoryType::IT_CATEGORY) -		{ -			cat_id = object->getParentUUID(); -		} -		const LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id); -		if (!cat)  -			return FALSE; -		if ((1LL << cat->getPreferredType() & mFilterOps.mFilterCategoryTypes) == U64(0)) -			return FALSE; -	} - -  	////////////////////////////////////////////////////////////////////////////////  	// FILTERTYPE_UUID  	// Pass if this item is the target UUID or if it links to the target UUID @@ -172,7 +173,6 @@ BOOL LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) con  			return FALSE;  	} -  	////////////////////////////////////////////////////////////////////////////////  	// FILTERTYPE_DATE  	// Pass if this item is within the date range. @@ -293,15 +293,15 @@ BOOL LLInventoryFilter::isModifiedAndClear()  	return ret;  } -void LLInventoryFilter::setFilterObjectTypes(U64 types) +void LLInventoryFilter::updateFilterTypes(U64 types, U64& current_types)  { -	if (mFilterOps.mFilterObjectTypes != types) +	if (current_types != types)  	{  		// keep current items only if no type bits getting turned off -		BOOL fewer_bits_set = (mFilterOps.mFilterObjectTypes & ~types); -		BOOL more_bits_set = (~mFilterOps.mFilterObjectTypes & types); +		BOOL fewer_bits_set = (current_types & ~types); +		BOOL more_bits_set = (~current_types & types); -		mFilterOps.mFilterObjectTypes = types; +		current_types = types;  		if (more_bits_set && fewer_bits_set)  		{  			// neither less or more restrive, both simultaneously @@ -318,62 +318,23 @@ void LLInventoryFilter::setFilterObjectTypes(U64 types)  			setModified(FILTER_MORE_RESTRICTIVE);  		}  	} +} + +void LLInventoryFilter::setFilterObjectTypes(U64 types) +{ +	updateFilterTypes(types, mFilterOps.mFilterObjectTypes);  	mFilterOps.mFilterTypes |= FILTERTYPE_OBJECT;  }  void LLInventoryFilter::setFilterCategoryTypes(U64 types)  { -	if (mFilterOps.mFilterCategoryTypes != types) -	{ -		// keep current items only if no type bits getting turned off -		BOOL fewer_bits_set = (mFilterOps.mFilterCategoryTypes & ~types); -		BOOL more_bits_set = (~mFilterOps.mFilterCategoryTypes & types); - -		mFilterOps.mFilterCategoryTypes = types; -		if (more_bits_set && fewer_bits_set) -		{ -			// neither less or more restrive, both simultaneously -			// so we need to filter from scratch -			setModified(FILTER_RESTART); -		} -		else if (more_bits_set) -		{ -			// target is only one of all requested types so more type bits == less restrictive -			setModified(FILTER_LESS_RESTRICTIVE); -		} -		else if (fewer_bits_set) -		{ -			setModified(FILTER_MORE_RESTRICTIVE); -		} -	} -	mFilterOps.mFilterTypes |= FILTERTYPE_OBJECT; +	updateFilterTypes(types, mFilterOps.mFilterCategoryTypes); +	mFilterOps.mFilterTypes |= FILTERTYPE_CATEGORY;  }  void LLInventoryFilter::setFilterWearableTypes(U64 types)  { -	if (mFilterOps.mFilterWearableTypes != types) -	{ -		// keep current items only if no type bits getting turned off -		BOOL fewer_bits_set = (mFilterOps.mFilterWearableTypes & ~types); -		BOOL more_bits_set = (~mFilterOps.mFilterWearableTypes & types); - -		mFilterOps.mFilterWearableTypes = types; -		if (more_bits_set && fewer_bits_set) -		{ -			// neither less or more restrive, both simultaneously -			// so we need to filter from scratch -			setModified(FILTER_RESTART); -		} -		else if (more_bits_set) -		{ -			// target is only one of all requested types so more type bits == less restrictive -			setModified(FILTER_LESS_RESTRICTIVE); -		} -		else if (fewer_bits_set) -		{ -			setModified(FILTER_MORE_RESTRICTIVE); -		} -	} +	updateFilterTypes(types, mFilterOps.mFilterWearableTypes);  	mFilterOps.mFilterTypes |= FILTERTYPE_WEARABLE;  } @@ -898,11 +859,16 @@ void LLInventoryFilter::fromLLSD(LLSD& data)  	}  } -U32 LLInventoryFilter::getFilterObjectTypes() const +U64 LLInventoryFilter::getFilterObjectTypes() const  {  	return mFilterOps.mFilterObjectTypes;  } +U64 LLInventoryFilter::getFilterCategoryTypes() const +{ +	return mFilterOps.mFilterCategoryTypes; +} +  BOOL LLInventoryFilter::hasFilterString() const  {  	return mFilterSubString.size() > 0; diff --git a/indra/newview/llinventoryfilter.h b/indra/newview/llinventoryfilter.h index 39e6f797a2..f9460822f7 100644 --- a/indra/newview/llinventoryfilter.h +++ b/indra/newview/llinventoryfilter.h @@ -31,6 +31,7 @@  #include "llpermissionsflags.h"  class LLFolderViewItem; +class LLFolderViewFolder;  class LLInventoryFilter  { @@ -81,11 +82,13 @@ public:  	// + Parameters  	// +-------------------------------------------------------------------+  	void 				setFilterObjectTypes(U64 types); -	U32 				getFilterObjectTypes() const; +	U64 				getFilterObjectTypes() const; +	U64					getFilterCategoryTypes() const;  	BOOL 				isFilterObjectTypesWith(LLInventoryType::EType t) const;  	void 				setFilterCategoryTypes(U64 types);  	void 				setFilterUUID(const LLUUID &object_id);  	void				setFilterWearableTypes(U64 types); +	void				updateFilterTypes(U64 types, U64& current_types);  	void 				setFilterSubString(const std::string& string);  	const std::string& 	getFilterSubString(BOOL trim = FALSE) const; @@ -110,6 +113,7 @@ public:  	// + Execution And Results  	// +-------------------------------------------------------------------+  	BOOL 				check(const LLFolderViewItem* item); +	bool				checkFolder(const LLFolderViewFolder* folder);  	BOOL 				checkAgainstFilterType(const LLFolderViewItem* item) const;  	BOOL 				checkAgainstPermissions(const LLFolderViewItem* item) const;  	BOOL 				checkAgainstFilterLinks(const LLFolderViewItem* item) const; diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index 1dcb91ad4d..61dec963c5 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -42,7 +42,6 @@  #include "llinventorymodelbackgroundfetch.h"  #include "llsidepanelinventory.h"  #include "llsidetray.h" -#include "llscrollcontainer.h"  #include "llviewerattachmenu.h"  #include "llviewerfoldertype.h"  #include "llvoavatarself.h" @@ -132,8 +131,6 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :  	mAllowMultiSelect(p.allow_multi_select),  	mShowItemLinkOverlays(p.show_item_link_overlays),  	mViewsInitialized(false), -	mStartFolderString(p.start_folder),	 -	mBuildDefaultHierarchy(true),  	mInvFVBridgeBuilder(NULL)  {  	mInvFVBridgeBuilder = &INVENTORY_BRIDGE_BUILDER; @@ -147,20 +144,27 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :  	mCommitCallbackRegistrar.add("Inventory.BeginIMSession", boost::bind(&LLInventoryPanel::beginIMSession, this));  	mCommitCallbackRegistrar.add("Inventory.Share",  boost::bind(&LLAvatarActions::shareWithAvatars)); -	if (mStartFolderString != "") -	{ -		mBuildDefaultHierarchy = false; -	}  } -void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params) +void LLInventoryPanel::buildFolderView(const LLInventoryPanel::Params& params)  { -	LLMemType mt(LLMemType::MTYPE_INVENTORY_POST_BUILD); +	// Determine the root folder in case specified, and +	// build the views starting with that folder. +	const LLFolderType::EType preferred_type = LLViewerFolderType::lookupTypeFromNewCategoryName(params.start_folder); -	mCommitCallbackRegistrar.pushScope(); // registered as a widget; need to push callback scope ourselves +	LLUUID root_id; -	// Create root folder +	if ("LIBRARY" == params.start_folder())  	{ +		root_id = gInventory.getLibraryRootFolderID(); +	} +	else +	{ +		root_id = (preferred_type != LLFolderType::FT_NONE) +				? gInventory.findCategoryUUIDForType(preferred_type, false, false)  +				: LLUUID::null; +	} +  		LLRect folder_rect(0,  						   0,  						   getRect().getWidth(), @@ -171,11 +175,26 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)  		p.rect = folder_rect;  		p.parent_panel = this;  		p.tool_tip = p.name; +	p.listener =  mInvFVBridgeBuilder->createBridge(LLAssetType::AT_CATEGORY, +													LLAssetType::AT_CATEGORY, +													LLInventoryType::IT_CATEGORY, +													this, +													NULL, +													root_id);  		p.use_label_suffix = params.use_label_suffix; +	p.allow_multiselect = mAllowMultiSelect;  		mFolderRoot = LLUICtrlFactory::create<LLFolderView>(p); -		mFolderRoot->setAllowMultiSelect(mAllowMultiSelect); +	  	} +void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params) +{ +	LLMemType mt(LLMemType::MTYPE_INVENTORY_POST_BUILD); + +	mCommitCallbackRegistrar.pushScope(); // registered as a widget; need to push callback scope ourselves +	 +	buildFolderView(params); +  	mCommitCallbackRegistrar.popScope();  	mFolderRoot->setCallbackRegistrar(&mCommitCallbackRegistrar); @@ -184,13 +203,9 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)  	{  		LLRect scroller_view_rect = getRect();  		scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom); -		LLScrollContainer::Params p; -		p.name("Inventory Scroller"); -		p.rect(scroller_view_rect); -		p.follows.flags(FOLLOWS_ALL); -		p.reserve_scroll_corner(true); -		p.tab_stop(true); -		mScroller = LLUICtrlFactory::create<LLScrollContainer>(p); +		LLScrollContainer::Params scroller_params(params.scroll()); +		scroller_params.rect(scroller_view_rect); +		mScroller = LLUICtrlFactory::create<LLScrollContainer>(scroller_params);  		addChild(mScroller);  		mScroller->addChild(mFolderRoot);  		mFolderRoot->setScrollContainer(mScroller); @@ -206,7 +221,7 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)  	// Build view of inventory if we need default full hierarchy and inventory ready,  	// otherwise wait for idle callback. -	if (mBuildDefaultHierarchy && mInventory->isInventoryUsable() && !mViewsInitialized) +	if (mInventory->isInventoryUsable() && !mViewsInitialized)  	{  		initializeViews();  	} @@ -264,6 +279,15 @@ LLInventoryFilter* LLInventoryPanel::getFilter()  	return NULL;  } +const LLInventoryFilter* LLInventoryPanel::getFilter() const +{ +	if (mFolderRoot) +	{ +		return mFolderRoot->getFilter(); +	} +	return NULL; +} +  void LLInventoryPanel::setFilterTypes(U64 types, LLInventoryFilter::EFilterType filter_type)  {  	if (filter_type == LLInventoryFilter::FILTERTYPE_OBJECT) @@ -488,23 +512,16 @@ void LLInventoryPanel::onIdle(void *userdata)  	}  } +const LLUUID& LLInventoryPanel::getRootFolderID() const +{ +	return mFolderRoot->getListener()->getUUID(); +} +  void LLInventoryPanel::initializeViews()  {  	if (!gInventory.isInventoryUsable()) return; -	// Determine the root folder in case specified, and -	// build the views starting with that folder. -	const LLFolderType::EType preferred_type = LLViewerFolderType::lookupTypeFromNewCategoryName(mStartFolderString); - -	if ("LIBRARY" == mStartFolderString) -	{ -		mStartFolderID = gInventory.getLibraryRootFolderID(); -	} -	else -	{ -		mStartFolderID = (preferred_type != LLFolderType::FT_NONE ? gInventory.findCategoryUUIDForType(preferred_type) : LLUUID::null); -	} -	rebuildViewsFor(mStartFolderID); +	rebuildViewsFor(getRootFolderID());  	mViewsInitialized = true; @@ -533,7 +550,7 @@ void LLInventoryPanel::rebuildViewsFor(const LLUUID& id)  {  	// Destroy the old view for this ID so we can rebuild it.  	LLFolderViewItem* old_view = mFolderRoot->getItemByID(id); -	if (old_view && id.notNull()) +	if (old_view && old_view != mFolderRoot)  	{  		old_view->destroyView();  	} @@ -543,28 +560,27 @@ void LLInventoryPanel::rebuildViewsFor(const LLUUID& id)  void LLInventoryPanel::buildNewViews(const LLUUID& id)  { -	LLMemType mt(LLMemType::MTYPE_INVENTORY_BUILD_NEW_VIEWS); -	LLFolderViewItem* itemp = NULL; -	LLInventoryObject* objectp = gInventory.getObject(id); -	if (objectp) -	{ -		const LLUUID &parent_id = objectp->getParentUUID(); -		LLFolderViewFolder* parent_folder = (LLFolderViewFolder*)mFolderRoot->getItemByID(parent_id); -		if (id == mStartFolderID) + 	LLInventoryObject const* objectp = gInventory.getObject(id); + 	LLUUID root_id = mFolderRoot->getListener()->getUUID(); + 	LLFolderViewFolder* parent_folder = NULL; +  + 	if (id == root_id)  		{  			parent_folder = mFolderRoot;  		} -		else if ((mStartFolderID != LLUUID::null) && (!gInventory.isObjectDescendentOf(id, mStartFolderID))) + 	else if (objectp)  		{ -			// This item exists outside the inventory's hierarchy, so don't add it. -			return; -		} + 		LLFolderViewItem* itemp = NULL; + 		const LLUUID &parent_id = objectp->getParentUUID(); + 		parent_folder = (LLFolderViewFolder*)mFolderRoot->getItemByID(parent_id); +  		if (parent_folder) +  		{  		if (objectp->getType() <= LLAssetType::AT_NONE ||  			objectp->getType() >= LLAssetType::AT_COUNT)  		{  			llwarns << "LLInventoryPanel::buildNewViews called with invalid objectp->mType : " -					<< ((S32) objectp->getType()) << " name " << objectp->getName() << " UUID " << objectp->getUUID()  +  						<< ((S32) objectp->getType()) << " name " << objectp->getName() << " UUID " << objectp->getUUID()  					<< llendl;  			return;  		} @@ -594,21 +610,9 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id)  				LLFolderViewFolder* folderp = LLUICtrlFactory::create<LLFolderViewFolder>(params);  				folderp->setItemSortOrder(mFolderRoot->getSortOrder());  				itemp = folderp; - -				// Hide the root folder, so we can show the contents of a folder flat -				// but still have the parent folder present for listener-related operations. -				if (id == mStartFolderID) -				{ -					folderp->setHidden(TRUE); -				} -				const LLViewerInventoryCategory *cat = dynamic_cast<LLViewerInventoryCategory *>(objectp); -				if (cat && getIsHiddenFolderType(cat->getPreferredType())) -				{ -					folderp->setHidden(TRUE);  				}  			} -		} -		else  +  			else  		{  			// Build new view for item.  			LLInventoryItem* item = (LLInventoryItem*)objectp; @@ -642,19 +646,15 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id)  		if (itemp)  		{  			itemp->addToFolder(parent_folder, mFolderRoot); - -			// Don't add children of hidden folders unless this is the panel's root folder. -			if (itemp->getHidden() && (id != mStartFolderID)) -			{ -				return;  			}  		}  	}  	// If this is a folder, add the children of the folder and recursively add any   	// child folders. -	if ((id == mStartFolderID) || -		(objectp && objectp->getType() == LLAssetType::AT_CATEGORY)) +	if (id.isNull() +		||	(objectp +			&& objectp->getType() == LLAssetType::AT_CATEGORY))  	{  		LLViewerInventoryCategory::cat_array_t* categories;  		LLViewerInventoryItem::item_array_t* items; @@ -671,7 +671,7 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id)  			}  		} -		if(items) +		if(items && parent_folder)  		{  			for (LLViewerInventoryItem::item_array_t::const_iterator item_iter = items->begin();  				 item_iter != items->end(); @@ -688,18 +688,13 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id)  // bit of a hack to make sure the inventory is open.  void LLInventoryPanel::openStartFolderOrMyInventory()  { -	if (mStartFolderString != "") -	{ -		mFolderRoot->openFolder(mStartFolderString); -	} -	else -	{  		// Find My Inventory folder and open it up by name  		for (LLView *child = mFolderRoot->getFirstChild(); child; child = mFolderRoot->findNextSibling(child))  		{  			LLFolderViewFolder *fchild = dynamic_cast<LLFolderViewFolder*>(child); -			if (fchild && fchild->getListener() && -				(fchild->getListener()->getUUID() == gInventory.getRootFolderID())) +		if (fchild +			&& fchild->getListener() +				&& fchild->getListener()->getUUID() == gInventory.getRootFolderID())  			{  				const std::string& child_name = child->getName();  				mFolderRoot->openFolder(child_name); @@ -707,7 +702,6 @@ void LLInventoryPanel::openStartFolderOrMyInventory()  			}  		}  	} -}  void LLInventoryPanel::onItemsCompletion()  { @@ -1067,15 +1061,12 @@ LLInventoryPanel* LLInventoryPanel::getActiveInventoryPanel(BOOL auto_open)  void LLInventoryPanel::addHideFolderType(LLFolderType::EType folder_type)  { -	if (!getIsHiddenFolderType(folder_type)) -	{ -		mHiddenFolderTypes.push_back(folder_type); -	} +	getFilter()->setFilterCategoryTypes(getFilter()->getFilterCategoryTypes() & ~(1ULL << folder_type));  }  BOOL LLInventoryPanel::getIsHiddenFolderType(LLFolderType::EType folder_type) const  { -	return (std::find(mHiddenFolderTypes.begin(), mHiddenFolderTypes.end(), folder_type) != mHiddenFolderTypes.end()); +	return !(getFilter()->getFilterCategoryTypes() & (1ULL << folder_type));  } diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h index 9da9f7d8ba..864c403397 100644 --- a/indra/newview/llinventorypanel.h +++ b/indra/newview/llinventorypanel.h @@ -35,6 +35,7 @@  #include "llinventoryfilter.h"  #include "llfolderview.h"  #include "llinventorymodel.h" +#include "llscrollcontainer.h"  #include "lluictrlfactory.h"  #include <set> @@ -46,7 +47,6 @@ class LLInventoryFVBridgeBuilder;  class LLMenuBarGL;  class LLCheckBoxCtrl;  class LLSpinCtrl; -class LLScrollContainer;  class LLTextBox;  class LLIconCtrl;  class LLSaveFolderState; @@ -83,6 +83,7 @@ public:  		Optional<Filter>					filter;  		Optional<std::string>               start_folder;  		Optional<bool>						use_label_suffix; +		Optional<LLScrollContainer::Params>	scroll;  		Params()  		:	sort_order_setting("sort_order_setting"), @@ -91,7 +92,8 @@ public:  			show_item_link_overlays("show_item_link_overlays", false),  			filter("filter"),  			start_folder("start_folder"), -			use_label_suffix("use_label_suffix", true) +			use_label_suffix("use_label_suffix", true), +			scroll("scroll")  		{}  	}; @@ -126,6 +128,7 @@ public:  	void setSelectCallback(const LLFolderView::signal_t::slot_type& cb);  	void clearSelection();  	LLInventoryFilter* getFilter(); +	const LLInventoryFilter* getFilter() const;  	void setFilterTypes(U64 filter, LLInventoryFilter::EFilterType = LLInventoryFilter::FILTERTYPE_OBJECT);  	U32 getFilterObjectTypes() const { return mFolderRoot->getFilterObjectTypes(); }  	void setFilterPermMask(PermissionMask filter_perm_mask); @@ -140,7 +143,6 @@ public:  	void setShowFolderState(LLInventoryFilter::EFolderShow show);  	LLInventoryFilter::EFolderShow getShowFolderState(); -	void setAllowMultiSelect(BOOL allow) { mFolderRoot->setAllowMultiSelect(allow); }  	// This method is called when something has changed about the inventory.  	void modelChanged(U32 mask);  	LLFolderView* getRootFolder() { return mFolderRoot; } @@ -207,23 +209,18 @@ private:  	//--------------------------------------------------------------------  public:  	void addHideFolderType(LLFolderType::EType folder_type); -protected: -	BOOL getIsHiddenFolderType(LLFolderType::EType folder_type) const; -private: -	std::vector<LLFolderType::EType> mHiddenFolderTypes; -	//-------------------------------------------------------------------- -	// Initialization routines for building up the UI ("views") -	//--------------------------------------------------------------------  public:  	BOOL 				getIsViewsInitialized() const { return mViewsInitialized; } -	const LLUUID&		getStartFolderID() const { return mStartFolderID; } -	const std::string&  getStartFolderString() { return mStartFolderString; } +	const LLUUID&		getRootFolderID() const;  protected:  	// Builds the UI.  Call this once the inventory is usable.  	void 				initializeViews(); -	void rebuildViewsFor(const LLUUID& id); // Given the id and the parent, build all of the folder views. -	virtual void buildNewViews(const LLUUID& id); +	void				rebuildViewsFor(const LLUUID& id); // Given the id and the parent, build all of the folder views. + +	virtual void		buildFolderView(const LLInventoryPanel::Params& params); +	virtual void		buildNewViews(const LLUUID& id); +	BOOL				getIsHiddenFolderType(LLFolderType::EType folder_type) const;  private:  	BOOL				mBuildDefaultHierarchy; // default inventory hierarchy should be created in postBuild()  	BOOL				mViewsInitialized; // Views have been generated diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp index b3ad9efeb2..03ccabc994 100644 --- a/indra/newview/llmediactrl.cpp +++ b/indra/newview/llmediactrl.cpp @@ -38,6 +38,7 @@  #include "llviewermedia.h"  #include "llviewertexture.h"  #include "llviewerwindow.h" +#include "lldebugmessagebox.h"  #include "llweb.h"  #include "llrender.h"  #include "llpluginclassmedia.h" @@ -708,6 +709,8 @@ LLPluginClassMedia* LLMediaCtrl::getMediaPlugin()  //  void LLMediaCtrl::draw()  { +	F32 alpha = getDrawContext().mAlpha; +  	if ( gRestoreGL == 1 )  	{  		LLRect r = getRect(); @@ -746,21 +749,11 @@ void LLMediaCtrl::draw()  		}  	} -//	if(mHidingInitialLoad) -//	{ -//		// If we're hiding loading, don't draw at all. -//		draw_media = false; -//	} -	  	bool background_visible = isBackgroundVisible();  	bool background_opaque = isBackgroundOpaque();  	if(draw_media)  	{ -		// alpha off for this -		LLGLSUIDefault gls_ui; -		LLGLDisable gls_alphaTest( GL_ALPHA_TEST ); -  		gGL.pushUIMatrix();  		{  			if (mIgnoreUIScale) @@ -775,7 +768,8 @@ void LLMediaCtrl::draw()  			// scale texture to fit the space using texture coords  			gGL.getTexUnit(0)->bind(media_texture); -			gGL.color4fv( LLColor4::white.mV ); +			LLColor4 media_color = LLColor4::white % alpha; +			gGL.color4fv( media_color.mV );  			F32 max_u = ( F32 )media_plugin->getWidth() / ( F32 )media_plugin->getTextureWidth();  			F32 max_v = ( F32 )media_plugin->getHeight() / ( F32 )media_plugin->getTextureHeight(); @@ -827,7 +821,6 @@ void LLMediaCtrl::draw()  			}  			// draw the browser -			gGL.setSceneBlendType(LLRender::BT_REPLACE);  			gGL.begin( LLRender::QUADS );  			if (! media_plugin->getTextureCoordsOpenGL())  			{ @@ -860,7 +853,6 @@ void LLMediaCtrl::draw()  				gGL.vertex2i( x_offset + width, y_offset );  			}  			gGL.end(); -			gGL.setSceneBlendType(LLRender::BT_ALPHA);  		}  		gGL.popUIMatrix(); diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp index 6435126fc0..10887aa53a 100644 --- a/indra/newview/lloutfitslist.cpp +++ b/indra/newview/lloutfitslist.cpp @@ -364,8 +364,8 @@ LLOutfitsList::~LLOutfitsList()  	if (gInventory.containsObserver(mCategoriesObserver))  	{  		gInventory.removeObserver(mCategoriesObserver); -		delete mCategoriesObserver;  	} +	delete mCategoriesObserver;  }  BOOL LLOutfitsList::postBuild() diff --git a/indra/newview/llpanelimcontrolpanel.cpp b/indra/newview/llpanelimcontrolpanel.cpp index 0cc5dcda82..e370f2f622 100644 --- a/indra/newview/llpanelimcontrolpanel.cpp +++ b/indra/newview/llpanelimcontrolpanel.cpp @@ -71,7 +71,7 @@ void LLPanelChatControlPanel::onChange(EStatusType status, const std::string &ch  void LLPanelChatControlPanel::onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state)  { -	updateButtons(new_state >= LLVoiceChannel::STATE_CALL_STARTED); +	updateButtons(new_state);  }  void LLPanelChatControlPanel::updateCallButton() @@ -96,11 +96,15 @@ void LLPanelChatControlPanel::updateCallButton()  	getChildView("call_btn")->setEnabled(enable_connect);  } -void LLPanelChatControlPanel::updateButtons(bool is_call_started) +void LLPanelChatControlPanel::updateButtons(LLVoiceChannel::EState state)  { +	bool is_call_started = state >= LLVoiceChannel::STATE_CALL_STARTED;  	getChildView("end_call_btn_panel")->setVisible( is_call_started); -	getChildView("voice_ctrls_btn_panel")->setVisible( is_call_started); +	getChildView("voice_ctrls_btn_panel")->setVisible( is_call_started && findChild<LLView>("voice_ctrls_btn_panel"));  	getChildView("call_btn_panel")->setVisible( ! is_call_started); +	 +	getChildView("volume_ctrl_panel")->setVisible(state == LLVoiceChannel::STATE_CONNECTED); +	  	updateCallButton();  } @@ -135,7 +139,7 @@ void LLPanelChatControlPanel::setSessionId(const LLUUID& session_id)  		mVoiceChannelStateChangeConnection = voice_channel->setStateChangedCallback(boost::bind(&LLPanelChatControlPanel::onVoiceChannelStateChanged, this, _1, _2));  		//call (either p2p, group or ad-hoc) can be already in started state -		updateButtons(voice_channel->getState() >= LLVoiceChannel::STATE_CALL_STARTED); +		updateButtons(voice_channel->getState());  	}  } @@ -156,6 +160,13 @@ BOOL LLPanelIMControlPanel::postBuild()  	childSetAction("share_btn", boost::bind(&LLPanelIMControlPanel::onShareButtonClicked, this));  	childSetAction("teleport_btn", boost::bind(&LLPanelIMControlPanel::onTeleportButtonClicked, this));  	childSetAction("pay_btn", boost::bind(&LLPanelIMControlPanel::onPayButtonClicked, this)); + +	childSetAction("mute_btn", boost::bind(&LLPanelIMControlPanel::onClickMuteVolume, this)); +	childSetAction("block_btn", boost::bind(&LLPanelIMControlPanel::onClickBlock, this)); +	childSetAction("unblock_btn", boost::bind(&LLPanelIMControlPanel::onClickUnblock, this)); +	 +	getChild<LLUICtrl>("volume_slider")->setCommitCallback(boost::bind(&LLPanelIMControlPanel::onVolumeChange, this, _2)); +  	getChildView("add_friend_btn")->setEnabled(!LLAvatarActions::isFriend(getChild<LLAvatarIconCtrl>("avatar_icon")->getAvatarId()));  	setFocusReceivedCallback(boost::bind(&LLPanelIMControlPanel::onFocusReceived, this)); @@ -163,6 +174,79 @@ BOOL LLPanelIMControlPanel::postBuild()  	return LLPanelChatControlPanel::postBuild();  } +void LLPanelIMControlPanel::draw() +{ +	bool is_muted = LLMuteList::getInstance()->isMuted(mAvatarID); + +	getChild<LLUICtrl>("block_btn_panel")->setVisible(!is_muted); +	getChild<LLUICtrl>("unblock_btn_panel")->setVisible(is_muted); + +	if (getChildView("volume_ctrl_panel")->getVisible()) +	{ + +		bool is_muted_voice = LLMuteList::getInstance()->isMuted(mAvatarID, LLMute::flagVoiceChat); + +		LLUICtrl* mute_btn = getChild<LLUICtrl>("mute_btn"); +		mute_btn->setValue( is_muted_voice ); + +		LLUICtrl* volume_slider = getChild<LLUICtrl>("volume_slider"); +		volume_slider->setEnabled( !is_muted_voice ); + +		F32 volume; + +		if (is_muted_voice) +		{ +			// it's clearer to display their volume as zero +			volume = 0.f; +		} +		else +		{ +			// actual volume +			volume = LLVoiceClient::getInstance()->getUserVolume(mAvatarID); +		} +		volume_slider->setValue( (F64)volume ); +	} + +	LLPanelChatControlPanel::draw(); +} + +void LLPanelIMControlPanel::onClickMuteVolume() +{ +	// By convention, we only display and toggle voice mutes, not all mutes +	LLMuteList* mute_list = LLMuteList::getInstance(); +	bool is_muted = mute_list->isMuted(mAvatarID, LLMute::flagVoiceChat); + +	LLMute mute(mAvatarID, getChild<LLTextBox>("avatar_name")->getText(), LLMute::AGENT); +	if (!is_muted) +	{ +		mute_list->add(mute, LLMute::flagVoiceChat); +	} +	else +	{ +		mute_list->remove(mute, LLMute::flagVoiceChat); +	} +} + +void LLPanelIMControlPanel::onClickBlock() +{ +	LLMute mute(mAvatarID, getChild<LLTextBox>("avatar_name")->getText(), LLMute::AGENT); +	 +	LLMuteList::getInstance()->add(mute); +} + +void LLPanelIMControlPanel::onClickUnblock() +{ +	LLMute mute(mAvatarID, getChild<LLTextBox>("avatar_name")->getText(), LLMute::AGENT); + +	LLMuteList::getInstance()->remove(mute); +} + +void LLPanelIMControlPanel::onVolumeChange(const LLSD& data) +{ +	F32 volume = (F32)data.asReal(); +	LLVoiceClient::getInstance()->setUserVolume(mAvatarID, volume); +} +  void LLPanelIMControlPanel::onTeleportButtonClicked()  {  	LLAvatarActions::offerTeleport(mAvatarID); @@ -262,6 +346,9 @@ void LLPanelIMControlPanel::onNameCache(const LLUUID& id, const std::string& ful  		std::string avatar_name = full_name;  		getChild<LLTextBox>("avatar_name")->setValue(avatar_name);  		getChild<LLTextBox>("avatar_name")->setToolTip(avatar_name); + +		bool is_linden = LLStringUtil::endsWith(full_name, " Linden"); +		getChild<LLUICtrl>("mute_btn")->setEnabled( !is_linden);  	}  } diff --git a/indra/newview/llpanelimcontrolpanel.h b/indra/newview/llpanelimcontrolpanel.h index 3bbe24ecb9..bba847b5d4 100644 --- a/indra/newview/llpanelimcontrolpanel.h +++ b/indra/newview/llpanelimcontrolpanel.h @@ -54,7 +54,7 @@ public:  	virtual void onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state); -	void updateButtons(bool is_call_started); +	void updateButtons(LLVoiceChannel::EState state);  	// Enables/disables call button depending on voice availability  	void updateCallButton(); @@ -94,6 +94,12 @@ private:  	void onPayButtonClicked();  	void onFocusReceived(); +	void onClickMuteVolume(); +	void onClickBlock(); +	void onClickUnblock(); +	/*virtual*/ void draw(); +	void onVolumeChange(const LLSD& data); +  	LLUUID mAvatarID;  }; diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp index c2729fa19b..81de6d6f73 100644 --- a/indra/newview/llpanellandmarks.cpp +++ b/indra/newview/llpanellandmarks.cpp @@ -645,7 +645,7 @@ void LLLandmarksPanel::onAccordionExpandedCollapsed(const LLSD& param, LLPlacesI  	// Start background fetch, mostly for My Inventory and Library  	if (expanded)  	{ -		const LLUUID &cat_id = inventory_list->getStartFolderID(); +		const LLUUID &cat_id = inventory_list->getRootFolderID();  		// Just because the category itself has been fetched, doesn't mean its child folders have.  		/*  		  if (!gInventory.isCategoryComplete(cat_id)) @@ -1414,7 +1414,7 @@ static void filter_list(LLPlacesInventoryPanel* inventory_list, const std::strin  static bool category_has_descendents(LLPlacesInventoryPanel* inventory_list)  { -	LLViewerInventoryCategory* category = gInventory.getCategory(inventory_list->getStartFolderID()); +	LLViewerInventoryCategory* category = gInventory.getCategory(inventory_list->getRootFolderID());  	if (category)  	{  		return category->getDescendentCount() > 0; diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp index bc4998dd0c..728642e4c7 100644 --- a/indra/newview/llpanelmaininventory.cpp +++ b/indra/newview/llpanelmaininventory.cpp @@ -193,6 +193,9 @@ BOOL LLPanelMainInventory::postBuild()  	mMenuAdd->getChild<LLMenuItemGL>("Upload Animation")->setLabelArg("[COST]", upload_cost);  	mMenuAdd->getChild<LLMenuItemGL>("Bulk Upload")->setLabelArg("[COST]", upload_cost); +	// Trigger callback for focus received so we can deselect items in inbox/outbox +	LLFocusableElement::setFocusReceivedCallback(boost::bind(&LLPanelMainInventory::onFocusReceived, this)); +  	return TRUE;  } @@ -572,6 +575,25 @@ void LLPanelMainInventory::updateItemcountText()  	getChild<LLUICtrl>("ItemcountText")->setValue(text);  } +void LLPanelMainInventory::onFocusReceived() +{ +	LLSidepanelInventory * sidepanel_inventory = LLSideTray::getInstance()->getPanel<LLSidepanelInventory>("sidepanel_inventory"); + +	LLInventoryPanel * inbox_panel = sidepanel_inventory->findChild<LLInventoryPanel>("inventory_inbox"); + +	if (inbox_panel) +	{ +		inbox_panel->clearSelection(); +	} + +	LLInventoryPanel * outbox_panel = sidepanel_inventory->findChild<LLInventoryPanel>("inventory_outbox"); + +	if (outbox_panel) +	{ +		outbox_panel->clearSelection(); +	} +} +  void LLPanelMainInventory::setFilterTextFromFilter()   {   	mFilterText = mActivePanel->getFilter()->getFilterText();  diff --git a/indra/newview/llpanelmaininventory.h b/indra/newview/llpanelmaininventory.h index 2b2ee1c0c9..86b2c87e0b 100644 --- a/indra/newview/llpanelmaininventory.h +++ b/indra/newview/llpanelmaininventory.h @@ -114,6 +114,8 @@ protected:  	bool isSaveTextureEnabled(const LLSD& userdata);  	void updateItemcountText(); +	void onFocusReceived(); +  private:  	LLFloaterInventoryFinder* getFinder(); diff --git a/indra/newview/llpanelmarketplaceinbox.cpp b/indra/newview/llpanelmarketplaceinbox.cpp new file mode 100644 index 0000000000..14c4c46fe7 --- /dev/null +++ b/indra/newview/llpanelmarketplaceinbox.cpp @@ -0,0 +1,222 @@ +/** 
 + * @file llpanelmarketplaceinbox.cpp
 + * @brief Panel for marketplace inbox
 + *
 +* $LicenseInfo:firstyear=2011&license=viewerlgpl$
 + * Second Life Viewer Source Code
 + * Copyright (C) 2010, Linden Research, Inc.
 + * 
 + * This library is free software; you can redistribute it and/or
 + * modify it under the terms of the GNU Lesser General Public
 + * License as published by the Free Software Foundation;
 + * version 2.1 of the License only.
 + * 
 + * This library is distributed in the hope that it will be useful,
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 + * Lesser General Public License for more details.
 + * 
 + * You should have received a copy of the GNU Lesser General Public
 + * License along with this library; if not, write to the Free Software
 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 + * 
 + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 + * $/LicenseInfo$
 + */
 +
 +#include "llviewerprecompiledheaders.h"
 +
 +#include "llpanelmarketplaceinbox.h"
 +
 +#include "llappviewer.h"
 +#include "llbutton.h"
 +#include "llinventorypanel.h"
 +#include "llsidepanelinventory.h"
 +
 +
 +#define SUPPORTING_FRESH_ITEM_COUNT	0
 +
 +
 +static LLRegisterPanelClassWrapper<LLPanelMarketplaceInbox> t_panel_marketplace_inbox("panel_marketplace_inbox");
 +
 +const LLPanelMarketplaceInbox::Params& LLPanelMarketplaceInbox::getDefaultParams() 
 +{ 
 +	return LLUICtrlFactory::getDefaultParams<LLPanelMarketplaceInbox>(); 
 +}
 +
 +// protected
 +LLPanelMarketplaceInbox::LLPanelMarketplaceInbox(const Params& p)
 +	: LLPanel(p)
 +	, mInventoryPanel(NULL)
 +{
 +}
 +
 +LLPanelMarketplaceInbox::~LLPanelMarketplaceInbox()
 +{
 +}
 +
 +// virtual
 +BOOL LLPanelMarketplaceInbox::postBuild()
 +{
 +	mInventoryPanel = getChild<LLInventoryPanel>("inventory_inbox");
 +
 +	mInventoryPanel->setSortOrder(LLInventoryFilter::SO_DATE);
 +
 +	LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLPanelMarketplaceInbox::handleLoginComplete, this));
 +
 +	LLFocusableElement::setFocusReceivedCallback(boost::bind(&LLPanelMarketplaceInbox::onFocusReceived, this));
 +
 +	mInventoryPanel->setSelectCallback(boost::bind(&LLPanelMarketplaceInbox::onSelectionChange, this));
 +
 +	return TRUE;
 +}
 +
 +void LLPanelMarketplaceInbox::onSelectionChange()
 +{
 +	LLSidepanelInventory* sidepanel_inventory = dynamic_cast<LLSidepanelInventory*>(LLSideTray::getInstance()->getPanel("sidepanel_inventory"));
 +		
 +	sidepanel_inventory->updateVerbs();
 +}
 +
 +
 +void LLPanelMarketplaceInbox::handleLoginComplete()
 +{
 +	// Set us up as the class to drive the badge value for the sidebar_inventory button
 +	LLSideTray::getInstance()->setTabButtonBadgeDriver("sidebar_inventory", this);
 +}
 +
 +void LLPanelMarketplaceInbox::onFocusReceived()
 +{
 +	LLSidepanelInventory * sidepanel_inventory = LLSideTray::getInstance()->getPanel<LLSidepanelInventory>("sidepanel_inventory");
 +
 +	if (sidepanel_inventory)
 +	{
 +		LLInventoryPanel * inv_panel = sidepanel_inventory->getActivePanel();
 +
 +		if (inv_panel)
 +		{
 +			inv_panel->clearSelection();
 +		}
 +	
 +		LLInventoryPanel * outbox_panel = sidepanel_inventory->findChild<LLInventoryPanel>("inventory_outbox");
 +
 +		if (outbox_panel)
 +		{
 +			outbox_panel->clearSelection();
 +		}
 +	}
 +}
 +
 +BOOL LLPanelMarketplaceInbox::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void *cargo_data, EAcceptance *accept, std::string& tooltip_msg)
 +{
 +	*accept = ACCEPT_NO;
 +	return TRUE;
 +}
 +
 +U32 LLPanelMarketplaceInbox::getFreshItemCount() const
 +{
 +#if SUPPORTING_FRESH_ITEM_COUNT
 +	U32 fresh_item_count = 0;
 +
 +	LLFolderView * root_folder = mInventoryPanel->getRootFolder();
 +
 +	const LLFolderViewFolder * inbox_folder = *(root_folder->getFoldersBegin());
 +
 +	LLFolderViewFolder::folders_t::const_iterator folders_it = inbox_folder->getFoldersBegin();
 +	LLFolderViewFolder::folders_t::const_iterator folders_end = inbox_folder->getFoldersEnd();
 +
 +	for (; folders_it != folders_end; ++folders_it)
 +	{
 +		const LLFolderViewFolder * folder = *folders_it;
 +
 +		if (folder->getCreationDate() > 1500)
 +		{
 +			fresh_item_count++;
 +		}
 +	}
 +
 +	return fresh_item_count;
 +#else
 +	return getTotalItemCount();
 +#endif
 +}
 +
 +U32 LLPanelMarketplaceInbox::getTotalItemCount() const
 +{
 +	LLInventoryModel* model = mInventoryPanel->getModel();
 +
 +	LLInventoryModel::cat_array_t* cats;
 +	LLInventoryModel::item_array_t* items;
 +
 +	model->getDirectDescendentsOf(model->findCategoryUUIDForType(LLFolderType::FT_INBOX, false, false), cats, items);
 +
 +	U32 item_count = 0;
 +
 +	if (cats)
 +	{
 +		item_count += cats->size();
 +	}
 +
 +	if (items)
 +	{
 +		item_count += items->size();
 +	}
 +
 +	return item_count;
 +}
 +
 +std::string LLPanelMarketplaceInbox::getBadgeString() const
 +{
 +	std::string item_count_str("");
 +
 +	// If the inbox is visible, and the side panel is collapsed or expanded and not the inventory panel
 +	if (getParent()->getVisible() &&
 +		(LLSideTray::getInstance()->getCollapsed() || !LLSideTray::getInstance()->isPanelActive("sidepanel_inventory")))
 +	{
 +		U32 item_count = getFreshItemCount();
 +
 +		if (item_count)
 +		{
 +			item_count_str = llformat("%d", item_count);
 +		}
 +	}
 +
 +	return item_count_str;
 +}
 +
 +void LLPanelMarketplaceInbox::draw()
 +{
 +	U32 item_count = getTotalItemCount();
 +
 +	LLView * fresh_new_count_view = getChildView("inbox_fresh_new_count");
 +
 +	if (item_count > 0)
 +	{
 +		std::string item_count_str = llformat("%d", item_count);
 +
 +		LLStringUtil::format_map_t args;
 +		args["[NUM]"] = item_count_str;
 +		getChild<LLButton>("inbox_btn")->setLabel(getString("InboxLabelWithArg", args));
 +
 +#if SUPPORTING_FRESH_ITEM_COUNT
 +		// set green text to fresh item count
 +		U32 fresh_item_count = getFreshItemCount();
 +		fresh_new_count_view->setVisible((fresh_item_count > 0));
 +
 +		if (fresh_item_count > 0)
 +		{
 +			getChild<LLUICtrl>("inbox_fresh_new_count")->setTextArg("[NUM]", llformat("%d", fresh_item_count));
 +		}
 +#else
 +		fresh_new_count_view->setVisible(FALSE);
 +#endif
 +	}
 +	else
 +	{
 +		getChild<LLButton>("inbox_btn")->setLabel(getString("InboxLabelNoArg"));
 +
 +		fresh_new_count_view->setVisible(FALSE);
 +	}
 +		
 +	LLPanel::draw();
 +}
 diff --git a/indra/newview/llpanelmarketplaceinbox.h b/indra/newview/llpanelmarketplaceinbox.h new file mode 100644 index 0000000000..b176d57d3f --- /dev/null +++ b/indra/newview/llpanelmarketplaceinbox.h @@ -0,0 +1,76 @@ +/**  + * @file llpanelmarketplaceinbox.h + * @brief Panel for marketplace inbox + * +* $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLPANELMARKETPLACEINBOX_H +#define LL_LLPANELMARKETPLACEINBOX_H + +#include "llpanel.h" +#include "llsidetray.h" + +class LLInventoryPanel; + +class LLPanelMarketplaceInbox : public LLPanel, public LLSideTrayTabBadgeDriver +{ +public: + +	struct Params :	public LLInitParam::Block<Params, LLPanel::Params> +	{ +		Params() {} +	}; + +	LOG_CLASS(LLPanelMarketplaceInbox); + +	// RN: for some reason you can't just use LLUICtrlFactory::getDefaultParams as a default argument in VC8 +	static const LLPanelMarketplaceInbox::Params& getDefaultParams(); + +	LLPanelMarketplaceInbox(const Params& p = getDefaultParams()); +	~LLPanelMarketplaceInbox(); + +	/*virtual*/ BOOL postBuild(); +	 +	/*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void *cargo_data, EAcceptance *accept, std::string& tooltip_msg); + +	/*virtual*/ void draw(); + +	U32 getFreshItemCount() const; +	U32 getTotalItemCount() const; + +	std::string getBadgeString() const; + +private: +	void handleLoginComplete(); + +	void onSelectionChange(); + +	void onFocusReceived(); + +private: +	LLInventoryPanel* mInventoryPanel; +}; + + +#endif //LL_LLPANELMARKETPLACEINBOX_H + diff --git a/indra/newview/llpanelmarketplaceoutbox.cpp b/indra/newview/llpanelmarketplaceoutbox.cpp new file mode 100644 index 0000000000..c8752b3e0f --- /dev/null +++ b/indra/newview/llpanelmarketplaceoutbox.cpp @@ -0,0 +1,164 @@ +/**  + * @file llpanelmarketplaceoutbox.cpp + * @brief Panel for marketplace outbox + * +* $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llpanelmarketplaceoutbox.h" + +#include "llbutton.h" +#include "llcoros.h" +#include "lleventcoro.h" +#include "llinventorypanel.h" +#include "llloadingindicator.h" +#include "llpanelmarketplaceinbox.h" +#include "llsidepanelinventory.h" +#include "llsidetray.h" +#include "lltimer.h" + + +static LLRegisterPanelClassWrapper<LLPanelMarketplaceOutbox> t_panel_marketplace_outbox("panel_marketplace_outbox"); + +// protected +LLPanelMarketplaceOutbox::LLPanelMarketplaceOutbox() +	: LLPanel() +	, mSyncButton(NULL) +	, mSyncIndicator(NULL) +	, mSyncInProgress(false) +{ +} + +LLPanelMarketplaceOutbox::~LLPanelMarketplaceOutbox() +{ +} + +// virtual +BOOL LLPanelMarketplaceOutbox::postBuild() +{ +	mSyncButton = getChild<LLButton>("outbox_sync_btn"); +	mSyncButton->setCommitCallback(boost::bind(&LLPanelMarketplaceOutbox::onSyncButtonClicked, this)); + +	mSyncIndicator = getChild<LLLoadingIndicator>("outbox_sync_indicator"); + +	mSyncButton->setEnabled(!isOutboxEmpty()); + +	LLFocusableElement::setFocusReceivedCallback(boost::bind(&LLPanelMarketplaceOutbox::onFocusReceived, this)); + +	return TRUE; +} + +void LLPanelMarketplaceOutbox::onFocusReceived() +{ +	LLSidepanelInventory * sidepanel_inventory = LLSideTray::getInstance()->getPanel<LLSidepanelInventory>("sidepanel_inventory"); + +	if (sidepanel_inventory) +	{ +		LLInventoryPanel * inv_panel = sidepanel_inventory->getActivePanel(); + +		if (inv_panel) +		{ +			inv_panel->clearSelection(); +		} + +		LLInventoryPanel * inbox_panel = sidepanel_inventory->findChild<LLInventoryPanel>("inventory_inbox"); + +		if (inbox_panel) +		{ +			inbox_panel->clearSelection(); +		} +	} +} + +bool LLPanelMarketplaceOutbox::isOutboxEmpty() const +{ +	// TODO: Check for contents of outbox + +	return false; +} + +bool LLPanelMarketplaceOutbox::isSyncInProgress() const +{ +	return mSyncInProgress; +} + + +std::string gTimeDelayDebugFunc = ""; + +void timeDelay(LLCoros::self& self, LLPanelMarketplaceOutbox* outboxPanel) +{ +	waitForEventOn(self, "mainloop"); + +	LLTimer delayTimer; +	delayTimer.reset(); +	delayTimer.setTimerExpirySec(5.0f); + +	while (!delayTimer.hasExpired()) +	{ +		waitForEventOn(self, "mainloop"); +	} + +	outboxPanel->onSyncComplete(); + +	gTimeDelayDebugFunc = ""; +} + +void LLPanelMarketplaceOutbox::onSyncButtonClicked() +{ +	// TODO: Actually trigger sync to marketplace + +	mSyncInProgress = true; +	updateSyncButtonStatus(); + +	// Set a timer (for testing only) + +    gTimeDelayDebugFunc = LLCoros::instance().launch("LLPanelMarketplaceOutbox timeDelay", boost::bind(&timeDelay, _1, this)); +} + +void LLPanelMarketplaceOutbox::onSyncComplete() +{ +	mSyncInProgress = false; + +	updateSyncButtonStatus(); +} + +void LLPanelMarketplaceOutbox::updateSyncButtonStatus() +{ +	if (isSyncInProgress()) +	{ +		mSyncButton->setVisible(false); + +		mSyncIndicator->setVisible(true); +		mSyncIndicator->reset(); +		mSyncIndicator->start(); +	} +	else +	{ +		mSyncIndicator->stop(); +		mSyncIndicator->setVisible(false); + +		mSyncButton->setVisible(true); +		mSyncButton->setEnabled(!isOutboxEmpty()); +	} +} diff --git a/indra/newview/llpanelmarketplaceoutbox.h b/indra/newview/llpanelmarketplaceoutbox.h new file mode 100644 index 0000000000..94bc066224 --- /dev/null +++ b/indra/newview/llpanelmarketplaceoutbox.h @@ -0,0 +1,67 @@ +/**  + * @file llpanelmarketplaceoutbox.h + * @brief Panel for marketplace outbox + * +* $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLPANELMARKETPLACEOUTBOX_H +#define LL_LLPANELMARKETPLACEOUTBOX_H + +#include "llpanel.h" + + +class LLButton; +class LLLoadingIndicator; + + +class LLPanelMarketplaceOutbox : public LLPanel +{ +public: + +	LOG_CLASS(LLPanelMarketplaceOutbox); + +	LLPanelMarketplaceOutbox(); +	~LLPanelMarketplaceOutbox(); + +	/*virtual*/ BOOL postBuild(); + +	bool isOutboxEmpty() const; +	bool isSyncInProgress() const; + +	void onSyncComplete(); + +protected: +	void onSyncButtonClicked(); +	void updateSyncButtonStatus(); + +	void onFocusReceived(); + +private: +	LLButton *				mSyncButton; +	LLLoadingIndicator *	mSyncIndicator; +	bool					mSyncInProgress; +}; + + +#endif //LL_LLPANELMARKETPLACEOUTBOX_H + diff --git a/indra/newview/llpanelwearing.cpp b/indra/newview/llpanelwearing.cpp index 911a9e5dda..0645fd8a54 100644 --- a/indra/newview/llpanelwearing.cpp +++ b/indra/newview/llpanelwearing.cpp @@ -174,8 +174,8 @@ LLPanelWearing::~LLPanelWearing()  	if (gInventory.containsObserver(mCategoriesObserver))  	{  		gInventory.removeObserver(mCategoriesObserver); -		delete mCategoriesObserver;  	} +	delete mCategoriesObserver;  }  BOOL LLPanelWearing::postBuild() diff --git a/indra/newview/llplacesinventorypanel.cpp b/indra/newview/llplacesinventorypanel.cpp index 29e262199e..f7823f4fe8 100644 --- a/indra/newview/llplacesinventorypanel.cpp +++ b/indra/newview/llplacesinventorypanel.cpp @@ -35,6 +35,7 @@  #include "llinventoryfunctions.h"  #include "llpanellandmarks.h"  #include "llplacesinventorybridge.h" +#include "llviewerfoldertype.h"  static LLDefaultChildRegistry::Register<LLPlacesInventoryPanel> r("places_inventory_panel"); @@ -56,72 +57,44 @@ LLPlacesInventoryPanel::~LLPlacesInventoryPanel()  	delete mSavedFolderState;  } -BOOL LLPlacesInventoryPanel::postBuild() +void LLPlacesInventoryPanel::buildFolderView(const LLInventoryPanel::Params& params)  { -	LLInventoryPanel::postBuild(); +	// Determine the root folder in case specified, and +	// build the views starting with that folder. +	const LLFolderType::EType preferred_type = LLViewerFolderType::lookupTypeFromNewCategoryName(params.start_folder); -	// clear Contents(); -	{ -		mFolderRoot->destroyView(); -		mFolderRoot->getParent()->removeChild(mFolderRoot); -		mFolderRoot->die(); - -		if( mScroller ) -		{ -			removeChild( mScroller ); -			mScroller->die(); -			mScroller = NULL; -		} -		mFolderRoot = NULL; -	} - - -	mCommitCallbackRegistrar.pushScope(); // registered as a widget; need to push callback scope ourselves +	LLUUID root_id; -	// create root folder +	if ("LIBRARY" == params.start_folder())  	{ -		LLRect folder_rect(0, -			0, -			getRect().getWidth(), -			0); -		LLPlacesFolderView::Params p; -		p.name = getName(); -		p.title = getLabel(); -		p.rect = folder_rect; -		p.parent_panel = this; -		mFolderRoot = (LLFolderView*)LLUICtrlFactory::create<LLPlacesFolderView>(p); -		mFolderRoot->setAllowMultiSelect(mAllowMultiSelect); +		root_id = gInventory.getLibraryRootFolderID();  	} - -	mCommitCallbackRegistrar.popScope(); - -	mFolderRoot->setCallbackRegistrar(&mCommitCallbackRegistrar); - -	// scroller +	else  	{ -		LLRect scroller_view_rect = getRect(); -		scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom); -		LLScrollContainer::Params p; -		p.name("Inventory Scroller"); -		p.rect(scroller_view_rect); -		p.follows.flags(FOLLOWS_ALL); -		p.reserve_scroll_corner(true); -		p.tab_stop(true); -		mScroller = LLUICtrlFactory::create<LLScrollContainer>(p); +		root_id = (preferred_type != LLFolderType::FT_NONE ? gInventory.findCategoryUUIDForType(preferred_type) : LLUUID::null);  	} -	addChild(mScroller); -	mScroller->addChild(mFolderRoot); - -	mFolderRoot->setScrollContainer(mScroller); -	mFolderRoot->addChild(mFolderRoot->mStatusTextBox); - -	// cut subitems -	mFolderRoot->setUseEllipses(true); - -	return TRUE; +	LLRect folder_rect(0, +		0, +		getRect().getWidth(), +		0); +	LLPlacesFolderView::Params p; +	p.name = getName(); +	p.title = getLabel(); +	p.rect = folder_rect; +	p.listener =  mInvFVBridgeBuilder->createBridge(LLAssetType::AT_CATEGORY, +													LLAssetType::AT_CATEGORY, +													LLInventoryType::IT_CATEGORY, +													this, +													NULL, +													root_id); +	p.parent_panel = this; +	p.allow_multiselect = mAllowMultiSelect; +	p.use_ellipses = true;	// truncate inventory item text so remove horizontal scroller +	mFolderRoot = (LLFolderView*)LLUICtrlFactory::create<LLPlacesFolderView>(p);  } +  // save current folder open state  void LLPlacesInventoryPanel::saveFolderState()  { diff --git a/indra/newview/llplacesinventorypanel.h b/indra/newview/llplacesinventorypanel.h index 6641871a0b..f647e7f970 100644 --- a/indra/newview/llplacesinventorypanel.h +++ b/indra/newview/llplacesinventorypanel.h @@ -46,7 +46,7 @@ public:  	LLPlacesInventoryPanel(const Params& p);  	~LLPlacesInventoryPanel(); -	/*virtual*/ BOOL postBuild(); +	/*virtual*/ void buildFolderView(const LLInventoryPanel::Params& params);  	void saveFolderState();  	void restoreFolderState(); diff --git a/indra/newview/llprogressview.cpp b/indra/newview/llprogressview.cpp index 31fde5d58a..028891a90e 100644 --- a/indra/newview/llprogressview.cpp +++ b/indra/newview/llprogressview.cpp @@ -55,23 +55,18 @@ LLProgressView* LLProgressView::sInstance = NULL;  S32 gStartImageWidth = 1;  S32 gStartImageHeight = 1; -const F32 FADE_IN_TIME = 1.f; - -const std::string ANIMATION_FILENAME = "Login Sequence "; -const std::string ANIMATION_SUFFIX = ".jpg"; -const F32 TOTAL_LOGIN_TIME = 10.f;	// seconds, wild guess at time from GL context to actual world view -S32 gLastStartAnimationFrame = 0;	// human-style indexing, first image = 1 -const S32 ANIMATION_FRAMES = 1; //13; +const F32 FADE_TO_WORLD_TIME = 1.0f;  static LLRegisterPanelClassWrapper<LLProgressView> r("progress_view"); -  // XUI: Translate  LLProgressView::LLProgressView()   :	LLPanel(),  	mPercentDone( 0.f ), +	mMediaCtrl( NULL ),  	mMouseDownInActiveArea( false ), -	mUpdateEvents("LLProgressView") +	mUpdateEvents("LLProgressView"), +	mFadeToWorldTimer()  {  	mUpdateEvents.listen("self", boost::bind(&LLProgressView::handleUpdate, this, _1));  } @@ -80,9 +75,14 @@ BOOL LLProgressView::postBuild()  {  	mProgressBar = getChild<LLProgressBar>("login_progress_bar"); +	// media control that is used to play intro video +	mMediaCtrl = getChild<LLMediaCtrl>("login_media_panel"); +	mMediaCtrl->setVisible( false );		// hidden initially +	mMediaCtrl->addObserver( this );		// watch events +  	mCancelBtn = getChild<LLButton>("cancel_btn");  	mCancelBtn->setClickedCallback(  LLProgressView::onCancelButtonClicked, NULL ); -	mFadeTimer.stop(); +	mFadeToWorldTimer.stop();  	getChild<LLTextBox>("title_text")->setText(LLStringExplicit(LLAppViewer::instance()->getSecondLifeTitle())); @@ -125,24 +125,43 @@ BOOL LLProgressView::handleKeyHere(KEY key, MASK mask)  	return TRUE;  } +void LLProgressView::revealIntroPanel() +{ +	// if user hasn't yet seen intro video +	std::string intro_url = gSavedSettings.getString("PostFirstLoginIntroURL"); +	if ( intro_url.length() > 0 &&  +			gSavedSettings.getBOOL("PostFirstLoginIntroViewed" ) == FALSE ) +	{ +		// navigate to intro URL and reveal widget  +		mMediaCtrl->navigateTo( intro_url );	 +		mMediaCtrl->setVisible( TRUE ); + +		// flag as having seen the new user post login intro +		gSavedSettings.setBOOL("PostFirstLoginIntroViewed", TRUE ); +	} +	else +	{ +		// start the timer that will control the fade through to the world view  +		mFadeToWorldTimer.start(); +	} +} +  void LLProgressView::setVisible(BOOL visible)  {  	// hiding progress view  	if (getVisible() && !visible)  	{ -		mFadeTimer.start(); +		LLPanel::setVisible(FALSE);  	}  	// showing progress view -	else if (visible && (!getVisible() || mFadeTimer.getStarted())) +	else if (visible && (!getVisible() || mFadeToWorldTimer.getStarted()))  	{  		setFocus(TRUE); -		mFadeTimer.stop(); -		mProgressTimer.start(); +		mFadeToWorldTimer.stop();  		LLPanel::setVisible(TRUE);  	}   } -  void LLProgressView::draw()  {  	static LLTimer timer; @@ -153,7 +172,7 @@ void LLProgressView::draw()  	{  		LLGLSUIDefault gls_ui;  		gGL.getTexUnit(0)->bind(gStartTexture.get()); -		gGL.color4f(1.f, 1.f, 1.f, mFadeTimer.getStarted() ? clamp_rescale(mFadeTimer.getElapsedTimeF32(), 0.f, FADE_IN_TIME, 1.f, 0.f) : 1.f); +		gGL.color4f(1.f, 1.f, 1.f, 1.f);  		F32 image_aspect = (F32)gStartImageWidth / (F32)gStartImageHeight;  		S32 width = getRect().getWidth();  		S32 height = getRect().getHeight(); @@ -180,16 +199,36 @@ void LLProgressView::draw()  	}  	glPopMatrix(); -	// Handle fade-in animation -	if (mFadeTimer.getStarted()) +	// handle fade out to world view when we're asked to +	if (mFadeToWorldTimer.getStarted())  	{ +		// draw fading panel +		F32 alpha = clamp_rescale(mFadeToWorldTimer.getElapsedTimeF32(), 0.f, FADE_TO_WORLD_TIME, 1.f, 0.f); +		LLViewDrawContext context(alpha);  		LLPanel::draw(); -		if (mFadeTimer.getElapsedTimeF32() > FADE_IN_TIME) + +		// faded out completely - remove panel and reveal world +		if (mFadeToWorldTimer.getElapsedTimeF32() > FADE_TO_WORLD_TIME )  		{ +			mFadeToWorldTimer.stop(); +  			// Fade is complete, release focus  			gFocusMgr.releaseFocusIfNeeded( this ); + +			// turn off panel that hosts intro so we see the world  			LLPanel::setVisible(FALSE); -			mFadeTimer.stop(); + +			// stop observing events since we no longer care +			mMediaCtrl->remObserver( this ); + +			// hide the intro +			mMediaCtrl->setVisible( false ); + +			// navigate away from intro page to something innocuous since 'unload' is broken right now +			//mMediaCtrl->navigateTo( "about:blank" ); + +			// FIXME: this causes a crash that i haven't been able to fix +			mMediaCtrl->unloadMediaSource();	  			gStartTexture = NULL;  		} @@ -307,3 +346,12 @@ bool LLProgressView::onAlertModal(const LLSD& notify)  	}  	return false;  } + +void LLProgressView::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) +{ +	if( event == MEDIA_EVENT_CLOSE_REQUEST ) +	{ +		// the intro web content calls javascript::window.close() when it's done +		mFadeToWorldTimer.start(); +	} +} diff --git a/indra/newview/llprogressview.h b/indra/newview/llprogressview.h index be1744f08a..73dd478e98 100644 --- a/indra/newview/llprogressview.h +++ b/indra/newview/llprogressview.h @@ -28,6 +28,7 @@  #define LL_LLPROGRESSVIEW_H  #include "llpanel.h" +#include "llmediactrl.h"  #include "llframetimer.h"  #include "llevents.h" @@ -35,7 +36,10 @@ class LLImageRaw;  class LLButton;  class LLProgressBar; -class LLProgressView : public LLPanel +class LLProgressView :  +	public LLPanel, +	public LLViewerMediaObserver +  {  public:  	LLProgressView(); @@ -49,25 +53,35 @@ public:  	/*virtual*/ BOOL handleKeyHere(KEY key, MASK mask);  	/*virtual*/ void setVisible(BOOL visible); +	// inherited from LLViewerMediaObserver +	/*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event); +  	void setText(const std::string& text);  	void setPercent(const F32 percent);  	// Set it to NULL when you want to eliminate the message.  	void setMessage(const std::string& msg); +	// turns on (under certain circumstances) the into video after login +	void revealIntroPanel(); +  	void setCancelButtonVisible(BOOL b, const std::string& label);  	static void onCancelButtonClicked( void* );  	static void onClickMessage(void*);  	bool onAlertModal(const LLSD& sd); +	// note - this is not just hiding the intro panel - it also hides the parent panel +	// and is used when the intro is finished and we want to show the world +	void removeIntroPanel(); +  protected:  	LLProgressBar* mProgressBar; +	LLMediaCtrl* mMediaCtrl;  	F32 mPercentDone;  	std::string mMessage;  	LLButton*	mCancelBtn; -	LLFrameTimer	mFadeTimer; -	LLFrameTimer mProgressTimer; +	LLFrameTimer mFadeToWorldTimer;  	LLRect mOutlineRect;  	bool mMouseDownInActiveArea; diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp index 31ea542743..f9e029be19 100644 --- a/indra/newview/llsidepanelinventory.cpp +++ b/indra/newview/llsidepanelinventory.cpp @@ -29,33 +29,87 @@  #include "llagent.h"  #include "llappearancemgr.h" +#include "llappviewer.h"  #include "llavataractions.h"  #include "llbutton.h" +#include "lldate.h"  #include "llfirstuse.h" +#include "llfoldertype.h" +#include "llhttpclient.h"  #include "llinventorybridge.h"  #include "llinventoryfunctions.h" +#include "llinventorymodel.h" +#include "llinventorymodelbackgroundfetch.h" +#include "llinventoryobserver.h"  #include "llinventorypanel.h" +#include "lllayoutstack.h"  #include "lloutfitobserver.h"  #include "llpanelmaininventory.h" +#include "llpanelmarketplaceinbox.h" +#include "llselectmgr.h"  #include "llsidepaneliteminfo.h"  #include "llsidepaneltaskinfo.h" +#include "llstring.h"  #include "lltabcontainer.h" -#include "llselectmgr.h" +#include "llviewermedia.h"  #include "llweb.h"  static LLRegisterPanelClassWrapper<LLSidepanelInventory> t_inventory("sidepanel_inventory"); +// +// Constants +// + +static const char * const INBOX_EXPAND_TIME_SETTING = "LastInventoryInboxExpand"; + +static const char * const INBOX_BUTTON_NAME = "inbox_btn"; +static const char * const OUTBOX_BUTTON_NAME = "outbox_btn"; + +static const char * const INBOX_LAYOUT_PANEL_NAME = "inbox_layout_panel"; +static const char * const OUTBOX_LAYOUT_PANEL_NAME = "outbox_layout_panel"; +static const char * const MAIN_INVENTORY_LAYOUT_PANEL = "main_inventory_layout_panel"; + +static const char * const INBOX_INVENTORY_PANEL = "inventory_inbox"; +static const char * const OUTBOX_INVENTORY_PANEL = "inventory_outbox"; + +static const char * const INVENTORY_LAYOUT_STACK_NAME = "inventory_layout_stack"; + +static const char * const MARKETPLACE_INBOX_PANEL = "marketplace_inbox"; + +// +// Helpers +// + + +// +// Implementation +// +  LLSidepanelInventory::LLSidepanelInventory() -	:	LLPanel(), -		mItemPanel(NULL), -		mPanelMainInventory(NULL) +	: LLPanel() +	, mItemPanel(NULL) +	, mPanelMainInventory(NULL) +	, mInboxEnabled(false) +	, mOutboxEnabled(false) +	, mCategoriesObserver(NULL)  { -  	//buildFromFile( "panel_inventory.xml"); // Called from LLRegisterPanelClass::defaultPanelClassBuilder()  }  LLSidepanelInventory::~LLSidepanelInventory()  { +	if (mCategoriesObserver && gInventory.containsObserver(mCategoriesObserver)) +	{ +		gInventory.removeObserver(mCategoriesObserver); +	} +	delete mCategoriesObserver; +} + +void handleInventoryDisplayInboxChanged() +{ +	LLSidepanelInventory* sidepanel_inventory = dynamic_cast<LLSidepanelInventory*>(LLSideTray::getInstance()->getPanel("sidepanel_inventory")); + +	sidepanel_inventory->enableInbox(gSavedSettings.getBOOL("InventoryDisplayInbox"));  }  BOOL LLSidepanelInventory::postBuild() @@ -119,13 +173,171 @@ BOOL LLSidepanelInventory::postBuild()  		}  	} +	// Marketplace inbox/outbox setup +	{ +		LLLayoutStack* stack = getChild<LLLayoutStack>(INVENTORY_LAYOUT_STACK_NAME); + +		LLLayoutPanel * inbox_panel = getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME); +		LLLayoutPanel * outbox_panel = getChild<LLLayoutPanel>(OUTBOX_LAYOUT_PANEL_NAME); + +		stack->collapsePanel(inbox_panel, true); +		stack->collapsePanel(outbox_panel, true); +		 +		// Disable user_resize on main inventory panel by default +		stack->setPanelUserResize(MAIN_INVENTORY_LAYOUT_PANEL, false); + +		LLButton * inbox_button = getChild<LLButton>(INBOX_BUTTON_NAME); +		LLButton * outbox_button = getChild<LLButton>(OUTBOX_BUTTON_NAME); + +		inbox_button->setToggleState(false); +		outbox_button->setToggleState(false); + +		inbox_button->setCommitCallback(boost::bind(&LLSidepanelInventory::onToggleInboxBtn, this)); +		outbox_button->setCommitCallback(boost::bind(&LLSidepanelInventory::onToggleOutboxBtn, this)); + +		// Set the inbox and outbox visible based on debug settings (final setting comes from http request below) +		enableInbox(gSavedSettings.getBOOL("InventoryDisplayInbox")); +		enableOutbox(gSavedSettings.getBOOL("InventoryDisplayOutbox")); + +		// Trigger callback for after login so we can setup to track inbox and outbox changes after initial inventory load +		LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLSidepanelInventory::handleLoginComplete, this)); +	} + +	gSavedSettings.getControl("InventoryDisplayInbox")->getCommitSignal()->connect(boost::bind(&handleInventoryDisplayInboxChanged)); +  	return TRUE;  } +void LLSidepanelInventory::handleLoginComplete() +{ +	// +	// Track inbox and outbox folder changes +	// + +	const bool do_not_create_folder = false; +	const bool do_not_find_in_library = false; + +	const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, do_not_create_folder, do_not_find_in_library); +	const LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, do_not_create_folder, do_not_find_in_library); + +	mCategoriesObserver = new LLInventoryCategoriesObserver(); +	gInventory.addObserver(mCategoriesObserver); + +	mCategoriesObserver->addCategory(inbox_id, boost::bind(&LLSidepanelInventory::onInboxChanged, this, inbox_id)); +	mCategoriesObserver->addCategory(outbox_id, boost::bind(&LLSidepanelInventory::onOutboxChanged, this, outbox_id)); + +	// +	// Trigger a load for the entire contents of the Inbox +	// + +	LLInventoryModelBackgroundFetch::instance().start(inbox_id); +} + +void LLSidepanelInventory::enableInbox(bool enabled) +{ +	mInboxEnabled = enabled; +	getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME)->setVisible(enabled); +} + +void LLSidepanelInventory::enableOutbox(bool enabled) +{ +	mOutboxEnabled = enabled; +	getChild<LLLayoutPanel>(OUTBOX_LAYOUT_PANEL_NAME)->setVisible(enabled); +} + +void LLSidepanelInventory::onInboxChanged(const LLUUID& inbox_id) +{ +	// Trigger a load of the entire inbox so we always know the contents and their creation dates for sorting +	LLInventoryModelBackgroundFetch::instance().start(inbox_id); +	 +	// Expand the inbox since we have fresh items +	LLPanelMarketplaceInbox * inbox = getChild<LLPanelMarketplaceInbox>(MARKETPLACE_INBOX_PANEL); +	if (inbox && (inbox->getFreshItemCount() > 0)) +	{ +		getChild<LLButton>(INBOX_BUTTON_NAME)->setToggleState(true); +		onToggleInboxBtn(); +	}	 +} + +void LLSidepanelInventory::onOutboxChanged(const LLUUID& outbox_id) +{ +	// Perhaps use this to track outbox changes? +} + +bool manageInboxOutboxPanels(LLLayoutStack * stack, +							 LLButton * pressedButton, LLLayoutPanel * pressedPanel, +							 LLButton * otherButton, LLLayoutPanel * otherPanel) +{ +	bool expand = pressedButton->getToggleState(); +	bool otherExpanded = otherButton->getToggleState(); + +	// +	// NOTE: Ideally we could have two panel sizes stored for a collapsed and expanded minimum size. +	//       For now, leave this code disabled because it creates some bad artifacts when expanding +	//       and collapsing the inbox/outbox. +	// +	//S32 smallMinSize = (expand ? pressedPanel->getMinDim() : otherPanel->getMinDim()); +	//S32 pressedMinSize = (expand ? 2 * smallMinSize : smallMinSize); +	//otherPanel->setMinDim(smallMinSize); +	//pressedPanel->setMinDim(pressedMinSize); + +	if (expand && otherExpanded) +	{ +		// Reshape pressedPanel to the otherPanel's height so we preserve the marketplace panel size +		pressedPanel->reshape(pressedPanel->getRect().getWidth(), otherPanel->getRect().getHeight()); + +		stack->collapsePanel(otherPanel, true); +		otherButton->setToggleState(false); +	} + +	stack->collapsePanel(pressedPanel, !expand); + +	// Enable user_resize on main inventory panel only when a marketplace box is expanded +	stack->setPanelUserResize(MAIN_INVENTORY_LAYOUT_PANEL, expand); + +	return expand; +} + +void LLSidepanelInventory::onToggleInboxBtn() +{ +	LLLayoutStack* stack = getChild<LLLayoutStack>(INVENTORY_LAYOUT_STACK_NAME); +	LLButton* pressedButton = getChild<LLButton>(INBOX_BUTTON_NAME); +	LLLayoutPanel* pressedPanel = getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME); +	LLButton* otherButton = getChild<LLButton>(OUTBOX_BUTTON_NAME); +	LLLayoutPanel* otherPanel = getChild<LLLayoutPanel>(OUTBOX_LAYOUT_PANEL_NAME); + +	bool inboxExpanded = manageInboxOutboxPanels(stack, pressedButton, pressedPanel, otherButton, otherPanel); + +	if (inboxExpanded) +	{ +		// Save current time as a setting for future new-ness tests +		gSavedSettings.setString(INBOX_EXPAND_TIME_SETTING, LLDate::now().asString()); +	} +} + +void LLSidepanelInventory::onToggleOutboxBtn() +{ +	LLLayoutStack* stack = getChild<LLLayoutStack>(INVENTORY_LAYOUT_STACK_NAME); +	LLButton* pressedButton = getChild<LLButton>(OUTBOX_BUTTON_NAME); +	LLLayoutPanel* pressedPanel = getChild<LLLayoutPanel>(OUTBOX_LAYOUT_PANEL_NAME); +	LLButton* otherButton = getChild<LLButton>(INBOX_BUTTON_NAME); +	LLLayoutPanel* otherPanel = getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME); + +	manageInboxOutboxPanels(stack, pressedButton, pressedPanel, otherButton, otherPanel); +} +  void LLSidepanelInventory::onOpen(const LLSD& key)  {  	LLFirstUse::newInventory(false); +	// Expand the inbox if we have fresh items +	LLPanelMarketplaceInbox * inbox = getChild<LLPanelMarketplaceInbox>(MARKETPLACE_INBOX_PANEL); +	if (inbox && (inbox->getFreshItemCount() > 0)) +	{ +		getChild<LLButton>(INBOX_BUTTON_NAME)->setToggleState(true); +		onToggleInboxBtn(); +	} +  	if(key.size() == 0)  		return; @@ -175,22 +387,24 @@ void LLSidepanelInventory::performActionOnSelection(const std::string &action)  	LLFolderViewItem* current_item = panel_main_inventory->getActivePanel()->getRootFolder()->getCurSelectedItem();  	if (!current_item)  	{ -		return; +		LLInventoryPanel* inbox = findChild<LLInventoryPanel>("inventory_inbox"); +		if (inbox) +		{ +			current_item = inbox->getRootFolder()->getCurSelectedItem(); +			if (!current_item) +			{ +				return; +			} +		}  	} +  	current_item->getListener()->performAction(panel_main_inventory->getActivePanel()->getModel(), action);  }  void LLSidepanelInventory::onWearButtonClicked()  { -	LLPanelMainInventory *panel_main_inventory = mInventoryPanel->findChild<LLPanelMainInventory>("panel_main_inventory"); -	if (!panel_main_inventory) -	{ -		llassert(panel_main_inventory != NULL); -		return; -	} -  	// Get selected items set. -	const std::set<LLUUID> selected_uuids_set = panel_main_inventory->getActivePanel()->getRootFolder()->getSelectionList(); +	const std::set<LLUUID> selected_uuids_set = LLAvatarActions::getInventorySelectedUUIDs();  	if (selected_uuids_set.empty()) return; // nothing selected  	// Convert the set to a vector. @@ -329,31 +543,24 @@ bool LLSidepanelInventory::canShare()  	LLPanelMainInventory* panel_main_inventory =  		mInventoryPanel->findChild<LLPanelMainInventory>("panel_main_inventory"); -	if (!panel_main_inventory) -	{ -		llwarns << "Failed to get the main inventory panel" << llendl; -		return false; -	} +	LLInventoryPanel* inbox = findChild<LLInventoryPanel>("inventory_inbox"); -	LLInventoryPanel* active_panel = panel_main_inventory->getActivePanel(); +	return ( (panel_main_inventory ? LLAvatarActions::canShareSelectedItems(panel_main_inventory->getActivePanel()) : false) +			|| (inbox ? LLAvatarActions::canShareSelectedItems(inbox) : false) ); +		  	// Avoid flicker in the Recent tab while inventory is being loaded. -	if (!active_panel->getRootFolder()->hasVisibleChildren()) return false; - -	return LLAvatarActions::canShareSelectedItems(active_panel); +	//if (!active_panel->getRootFolder()->hasVisibleChildren()) return false;  } +  bool LLSidepanelInventory::canWearSelected()  { -	LLPanelMainInventory* panel_main_inventory = -		mInventoryPanel->findChild<LLPanelMainInventory>("panel_main_inventory"); -	if (!panel_main_inventory) -	{ -		llassert(panel_main_inventory != NULL); +	std::set<LLUUID> selected_uuids = LLAvatarActions::getInventorySelectedUUIDs(); + +	if (selected_uuids.empty())  		return false; -	} -	std::set<LLUUID> selected_uuids = panel_main_inventory->getActivePanel()->getRootFolder()->getSelectionList();  	for (std::set<LLUUID>::const_iterator it = selected_uuids.begin();  		it != selected_uuids.end();  		++it) @@ -370,7 +577,15 @@ LLInventoryItem *LLSidepanelInventory::getSelectedItem()  	LLFolderViewItem* current_item = panel_main_inventory->getActivePanel()->getRootFolder()->getCurSelectedItem();  	if (!current_item)  	{ -		return NULL; +		LLInventoryPanel* inbox = findChild<LLInventoryPanel>("inventory_inbox"); +		if (inbox) +		{ +			current_item = inbox->getRootFolder()->getCurSelectedItem(); +			if (!current_item) +			{ +				return NULL; +			} +		}  	}  	const LLUUID &item_id = current_item->getListener()->getUUID();  	LLInventoryItem *item = gInventory.getItem(item_id); @@ -379,9 +594,20 @@ LLInventoryItem *LLSidepanelInventory::getSelectedItem()  U32 LLSidepanelInventory::getSelectedCount()  { +	int count = 0; +  	LLPanelMainInventory *panel_main_inventory = mInventoryPanel->findChild<LLPanelMainInventory>("panel_main_inventory");  	std::set<LLUUID> selection_list = panel_main_inventory->getActivePanel()->getRootFolder()->getSelectionList(); -	return selection_list.size(); +	count += selection_list.size(); + +	LLInventoryPanel* inbox = findChild<LLInventoryPanel>("inventory_inbox"); +	if (inbox) +	{ +		selection_list = inbox->getRootFolder()->getSelectionList(); +		count += selection_list.size(); +	} + +	return count;  }  LLInventoryPanel *LLSidepanelInventory::getActivePanel() diff --git a/indra/newview/llsidepanelinventory.h b/indra/newview/llsidepanelinventory.h index 32c98bc034..df29cbceba 100644 --- a/indra/newview/llsidepanelinventory.h +++ b/indra/newview/llsidepanelinventory.h @@ -30,6 +30,7 @@  #include "llpanel.h"  class LLFolderViewItem; +class LLInventoryCategoriesObserver;  class LLInventoryItem;  class LLInventoryPanel;  class LLPanelMainInventory; @@ -42,6 +43,10 @@ public:  	LLSidepanelInventory();  	virtual ~LLSidepanelInventory(); +private: +	void handleLoginComplete(); + +public:  	/*virtual*/ BOOL postBuild();  	/*virtual*/ void onOpen(const LLSD& key); @@ -56,6 +61,17 @@ public:  	// checks can share selected item(s)  	bool canShare(); +	void onToggleInboxBtn(); +	void onToggleOutboxBtn(); + +	void enableInbox(bool enabled); +	void enableOutbox(bool enabled); + +	bool isInboxEnabled() const { return mInboxEnabled; } +	bool isOutboxEnabled() const { return mOutboxEnabled; } + +	void updateVerbs(); +  protected:  	// Tracks highlighted (selected) item in inventory panel.  	LLInventoryItem *getSelectedItem(); @@ -63,10 +79,12 @@ protected:  	void onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action);  	// "wear", "teleport", etc.  	void performActionOnSelection(const std::string &action); -	void updateVerbs();  	bool canWearSelected(); // check whether selected items can be worn +	void onInboxChanged(const LLUUID& inbox_id); +	void onOutboxChanged(const LLUUID& outbox_id); +  	//  	// UI Elements  	// @@ -85,6 +103,7 @@ protected:  	void 						onTeleportButtonClicked();  	void 						onOverflowButtonClicked();  	void 						onBackButtonClicked(); +  private:  	LLButton*					mInfoBtn;  	LLButton*					mShareBtn; @@ -94,6 +113,10 @@ private:  	LLButton*					mOverflowBtn;  	LLButton*					mShopBtn; +	bool						mInboxEnabled; +	bool						mOutboxEnabled; + +	LLInventoryCategoriesObserver* 			mCategoriesObserver;  };  #endif //LL_LLSIDEPANELINVENTORY_H diff --git a/indra/newview/llsidetray.cpp b/indra/newview/llsidetray.cpp index 631b244785..651897a217 100644 --- a/indra/newview/llsidetray.cpp +++ b/indra/newview/llsidetray.cpp @@ -30,6 +30,7 @@  #include "llagentcamera.h"  #include "llappviewer.h" +#include "llbadge.h"  #include "llbottomtray.h"  #include "llfloaterreg.h"  #include "llfirstuse.h" @@ -40,6 +41,7 @@  #include "llfocusmgr.h"  #include "llrootview.h"  #include "llnavigationbar.h" +#include "llpanelmarketplaceinbox.h"  #include "llaccordionctrltab.h" @@ -113,11 +115,14 @@ public:  		Optional<std::string>		image_selected;  		Optional<std::string>		tab_title;  		Optional<std::string>		description; +		Optional<LLBadge::Params>	badge; +		  		Params()  		:	image("image"),  			image_selected("image_selected"),  			tab_title("tab_title","no title"), -			description("description","no description") +			description("description","no description"), +			badge("badge")  		{};  	};  protected: @@ -140,7 +145,6 @@ public:  	static LLSideTrayTab*  createInstance	();  	const std::string& getDescription () const { return mDescription;} -	const std::string& getTabTitle() const { return mTabTitle;}  	void			onOpen		(const LLSD& key); @@ -150,7 +154,10 @@ public:  	BOOL			handleScrollWheel(S32 x, S32 y, S32 clicks); -	LLPanel *getPanel(); +	LLPanel*		getPanel(); + +	LLButton*		createButton(bool allowTearOff, LLUICtrl::commit_callback_t callback); +  private:  	std::string mTabTitle;  	std::string mImage; @@ -158,6 +165,9 @@ private:  	std::string	mDescription;  	LLView*	mMainPanel; + +	bool			mHasBadge; +	LLBadge::Params	mBadgeParams;  };  LLSideTrayTab::LLSideTrayTab(const Params& p) @@ -166,8 +176,10 @@ LLSideTrayTab::LLSideTrayTab(const Params& p)  	mImage(p.image),  	mImageSelected(p.image_selected),  	mDescription(p.description), -	mMainPanel(NULL) +	mMainPanel(NULL), +	mBadgeParams(p.badge)  { +	mHasBadge = p.badge.isProvided();  }  LLSideTrayTab::~LLSideTrayTab() @@ -182,8 +194,6 @@ bool LLSideTrayTab::addChild(LLView* view, S32 tab_group)  	//return res;  } - -  //virtual   BOOL LLSideTrayTab::postBuild()  { @@ -196,7 +206,7 @@ BOOL LLSideTrayTab::postBuild()  	getChild<LLButton>("undock")->setCommitCallback(boost::bind(&LLSideTrayTab::setDocked, this, false));  	getChild<LLButton>("dock")->setCommitCallback(boost::bind(&LLSideTrayTab::setDocked, this, true)); -	return true; +	return LLPanel::postBuild();  }  static const S32 splitter_margin = 1; @@ -523,18 +533,36 @@ public:  		return FALSE;  	} +	void setBadgeDriver(LLSideTrayTabBadgeDriver* driver) +	{ +		mBadgeDriver = driver; +	} +  protected:  	LLSideTrayButton(const LLButton::Params& p) -	: LLButton(p) -	, mDragLastScreenX(0) -	, mDragLastScreenY(0) +		: LLButton(p) +		, mDragLastScreenX(0) +		, mDragLastScreenY(0) +		, mBadgeDriver(NULL)  	{}  	friend class LLUICtrlFactory; +	void draw() +	{ +		if (mBadgeDriver) +		{ +			setBadgeLabel(mBadgeDriver->getBadgeString()); +		} + +		LLButton::draw(); +	} +  private:  	S32		mDragLastScreenX;  	S32		mDragLastScreenY; + +	LLSideTrayTabBadgeDriver*	mBadgeDriver;  };  ////////////////////////////////////////////////////////////////////////////// @@ -615,11 +643,31 @@ BOOL LLSideTray::postBuild()  	return true;  } +void LLSideTray::setTabButtonBadgeDriver(std::string tabName, LLSideTrayTabBadgeDriver* driver) +{ +	mTabButtonBadgeDrivers[tabName] = driver; +} +  void LLSideTray::handleLoginComplete()  {  	//reset tab to "home" tab if it was changesd during login process  	selectTabByName("sidebar_home"); +	for (badge_map_t::iterator it = mTabButtonBadgeDrivers.begin(); it != mTabButtonBadgeDrivers.end(); ++it) +	{ +		LLButton* button = mTabButtons[it->first]; +		LLSideTrayButton* side_button = dynamic_cast<LLSideTrayButton*>(button); + +		if (side_button) +		{ +			side_button->setBadgeDriver(it->second); +		} +		else +		{ +			llwarns << "Unable to find button " << it->first << " to set the badge driver. " << llendl; +		} +	} +  	detachTabs();  } @@ -766,51 +814,6 @@ bool LLSideTray::selectTabByName(const std::string& name, bool keep_prev_visible  	return true;  } -LLButton* LLSideTray::createButton	(const std::string& name,const std::string& image,const std::string& tooltip, -									 LLUICtrl::commit_callback_t callback) -{ -	static LLSideTray::Params sidetray_params(LLUICtrlFactory::getDefaultParams<LLSideTray>());	 -	 -	LLButton::Params bparams; - -	LLRect rect; -	rect.setOriginAndSize(0, 0, sidetray_params.default_button_width, sidetray_params.default_button_height);  - -	bparams.name(name); -	bparams.follows.flags (FOLLOWS_LEFT | FOLLOWS_TOP); -	bparams.rect (rect); -	bparams.tab_stop(false); -	bparams.image_unselected(sidetray_params.tab_btn_image_normal); -	bparams.image_selected(sidetray_params.tab_btn_image_selected); -	bparams.image_disabled(sidetray_params.tab_btn_image_normal); -	bparams.image_disabled_selected(sidetray_params.tab_btn_image_selected); - -	LLButton* button; -	if (name == "sidebar_openclose") -	{ -		// "Open/Close" button shouldn't allow "tear off" -		// hence it is created as LLButton instance. -		button = LLUICtrlFactory::create<LLButton>(bparams); -	} -	else -	{ -		button = LLUICtrlFactory::create<LLSideTrayButton>(bparams); -	} - -	button->setClickedCallback(callback); - -	button->setToolTip(tooltip); -	 -	if(image.length()) -	{ -		button->setImageOverlay(image); -	} - -	mButtonsPanel->addChildInBack(button); - -	return button; -} -  bool LLSideTray::addChild(LLView* view, S32 tab_group)  {  	LLSideTrayTab* tab_panel = dynamic_cast<LLSideTrayTab*>(view); @@ -938,7 +941,56 @@ bool LLSideTray::addTab(LLSideTrayTab* tab)  	return true;  } -void	LLSideTray::createButtons	() +LLButton* LLSideTrayTab::createButton(bool allowTearOff, LLUICtrl::commit_callback_t callback) +{ +	static LLSideTray::Params sidetray_params(LLUICtrlFactory::getDefaultParams<LLSideTray>());	 + +	LLRect rect; +	rect.setOriginAndSize(0, 0, sidetray_params.default_button_width, sidetray_params.default_button_height);  + +	LLButton::Params bparams; + +	// Append "_button" to the side tray tab name +	std::string button_name = getName() + "_button"; +	bparams.name(button_name); +	bparams.follows.flags (FOLLOWS_LEFT | FOLLOWS_TOP); +	bparams.rect (rect); +	bparams.tab_stop(false); +	bparams.image_unselected(sidetray_params.tab_btn_image_normal); +	bparams.image_selected(sidetray_params.tab_btn_image_selected); +	bparams.image_disabled(sidetray_params.tab_btn_image_normal); +	bparams.image_disabled_selected(sidetray_params.tab_btn_image_selected); + +	if (mHasBadge) +	{ +		bparams.badge = mBadgeParams; +	} + +	LLButton* button; +	if (allowTearOff) +	{ +		button = LLUICtrlFactory::create<LLSideTrayButton>(bparams); +	} +	else +	{ +		// "Open/Close" button shouldn't allow "tear off" +		// hence it is created as LLButton instance. +		button = LLUICtrlFactory::create<LLButton>(bparams); +	} + +	button->setClickedCallback(callback); + +	button->setToolTip(mTabTitle); + +	if(mImage.length()) +	{ +		button->setImageOverlay(mImage); +	} + +	return button; +} + +void LLSideTray::createButtons()  {  	//create buttons for tabs  	child_vector_const_iter_t child_it = mTabs.begin(); @@ -951,17 +1003,22 @@ void	LLSideTray::createButtons	()  		// The "OpenClose" button will open/close the whole panel  		if (name == "sidebar_openclose")  		{ -			mCollapseButton = createButton(name,sidebar_tab->mImage,sidebar_tab->getTabTitle(), -				boost::bind(&LLSideTray::onToggleCollapse, this)); +			mCollapseButton = sidebar_tab->createButton(false, boost::bind(&LLSideTray::onToggleCollapse, this)); + +			mButtonsPanel->addChildInBack(mCollapseButton); +  			LLHints::registerHintTarget("side_panel_btn", mCollapseButton->getHandle());  		}  		else  		{ -			LLButton* button = createButton(name,sidebar_tab->mImage,sidebar_tab->getTabTitle(), -				boost::bind(&LLSideTray::onTabButtonClick, this, name)); +			LLButton* button = sidebar_tab->createButton(true, boost::bind(&LLSideTray::onTabButtonClick, this, name)); + +			mButtonsPanel->addChildInBack(button); +  			mTabButtons[name] = button;  		}  	} +  	LLHints::registerHintTarget("inventory_btn", mTabButtons["sidebar_inventory"]->getHandle());  } diff --git a/indra/newview/llsidetray.h b/indra/newview/llsidetray.h index 24882411f4..17158329dc 100644 --- a/indra/newview/llsidetray.h +++ b/indra/newview/llsidetray.h @@ -33,6 +33,13 @@  class LLAccordionCtrl;  class LLSideTrayTab; +// Define an interface for side tab button badge values +class LLSideTrayTabBadgeDriver +{ +public: +	virtual std::string getBadgeString() const = 0; +}; +  // Deal with LLSideTrayTab being opaque. Generic do-nothing cast...  template <class T>  T tab_cast(LLSideTrayTab* tab) { return tab; } @@ -166,6 +173,8 @@ public:  	bool		getCollapsed() { return mCollapsed; } +	void		setTabButtonBadgeDriver(std::string tabName, LLSideTrayTabBadgeDriver* driver); +  public:  	virtual ~LLSideTray(){}; @@ -204,8 +213,6 @@ protected:  	void		createButtons	(); -	LLButton*	createButton	(const std::string& name,const std::string& image,const std::string& tooltip, -									LLUICtrl::commit_callback_t callback);  	void		arrange			();  	void		detachTabs		();  	void		reflectCollapseChange(); @@ -234,6 +241,8 @@ private:  	LLPanel*						mButtonsPanel;  	typedef std::map<std::string,LLButton*> button_map_t;  	button_map_t					mTabButtons; +	typedef std::map<std::string,LLSideTrayTabBadgeDriver*> badge_map_t; +	badge_map_t						mTabButtonBadgeDrivers;  	child_vector_t					mTabs;  	child_vector_t					mDetachedTabs;  	tab_order_vector_t				mOriginalTabOrder; diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 86b09473ab..167dd68f08 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -1953,7 +1953,8 @@ bool idle_startup()  		gViewerWindow->getWindow()->resetBusyCount();  		gViewerWindow->getWindow()->setCursor(UI_CURSOR_ARROW);  		LL_DEBUGS("AppInit") << "Done releasing bitmap" << LL_ENDL; -		gViewerWindow->setShowProgress(FALSE); +		gViewerWindow->revealIntroPanel(); +		//gViewerWindow->setShowProgress(FALSE);  // reveal intro video now handles this  		gViewerWindow->setProgressCancelButtonVisible(FALSE);  		// We're not away from keyboard, even though login might have taken diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 1023a4339b..b182c15dd0 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -420,7 +420,6 @@ BOOL LLFloaterTexturePicker::postBuild()  		mInventoryPanel->setFilterPermMask(mImmediateFilterPermMask);  		mInventoryPanel->setSelectCallback(boost::bind(&LLFloaterTexturePicker::onSelectionChange, this, _1, _2));  		mInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS); -		mInventoryPanel->setAllowMultiSelect(FALSE);  		// Disable auto selecting first filtered item because it takes away  		// selection from the item set by LLTextureCtrl owning this floater. diff --git a/indra/newview/llviewerfoldertype.cpp b/indra/newview/llviewerfoldertype.cpp index 42f780a8a3..0ddbe8c040 100644 --- a/indra/newview/llviewerfoldertype.cpp +++ b/indra/newview/llviewerfoldertype.cpp @@ -40,6 +40,7 @@ struct ViewerFolderEntry : public LLDictionaryEntry  					  const std::string &icon_name_open,	// name of the folder icon  					  const std::string &icon_name_closed,  					  BOOL is_quiet,						// folder doesn't need a UI update when changed +					  bool is_hidden = false,  					  const std::string &dictionary_name = empty_string // no reverse lookup needed on non-ensembles, so in most cases just leave this blank  		)   		: @@ -47,7 +48,8 @@ struct ViewerFolderEntry : public LLDictionaryEntry  		mNewCategoryName(new_category_name),  		mIconNameOpen(icon_name_open),  		mIconNameClosed(icon_name_closed), -		mIsQuiet(is_quiet) +		mIsQuiet(is_quiet), +		mIsHidden(is_hidden)  	{  		mAllowedNames.clear();  	} @@ -66,7 +68,8 @@ struct ViewerFolderEntry : public LLDictionaryEntry  		*/  		mIconNameOpen("Inv_FolderOpen"), mIconNameClosed("Inv_FolderClosed"),  		mNewCategoryName(new_category_name), -		mIsQuiet(FALSE) +		mIsQuiet(FALSE), +		mIsHidden(false)  	{  		const std::string delims (",");  		LLStringUtilBase<char>::getTokens(allowed_names, mAllowedNames, delims); @@ -91,6 +94,7 @@ struct ViewerFolderEntry : public LLDictionaryEntry  	typedef std::vector<std::string> name_vec_t;  	name_vec_t mAllowedNames;  	BOOL mIsQuiet; +	bool mIsHidden;  };  class LLViewerFolderDictionary : public LLSingleton<LLViewerFolderDictionary>, @@ -128,10 +132,10 @@ LLViewerFolderDictionary::LLViewerFolderDictionary()  	addEntry(LLFolderType::FT_MY_OUTFITS, 			new ViewerFolderEntry("My Outfits",				"Inv_SysOpen",			"Inv_SysClosed",		TRUE));  	addEntry(LLFolderType::FT_MESH, 				new ViewerFolderEntry("Meshes",					"Inv_SysOpen",			"Inv_SysClosed",		FALSE)); - -	addEntry(LLFolderType::FT_INBOX, 				new ViewerFolderEntry("Inbox",					"Inv_SysOpen",			"Inv_SysClosed",		FALSE)); +	addEntry(LLFolderType::FT_INBOX, 				new ViewerFolderEntry("Inbox",					"Inv_SysOpen",			"Inv_SysClosed",		FALSE, true)); +	addEntry(LLFolderType::FT_OUTBOX, 				new ViewerFolderEntry("Outbox",					"Inv_SysOpen",			"Inv_SysClosed",		FALSE, true)); -	addEntry(LLFolderType::FT_NONE, 				new ViewerFolderEntry("New Folder",				"Inv_FolderOpen",		"Inv_FolderClosed",		FALSE, "default")); +	addEntry(LLFolderType::FT_NONE, 				new ViewerFolderEntry("New Folder",				"Inv_FolderOpen",		"Inv_FolderClosed",		FALSE, false, "default"));  #if SUPPORT_ENSEMBLES  	initEnsemblesFromFile(); @@ -258,6 +262,17 @@ BOOL LLViewerFolderType::lookupIsQuietType(LLFolderType::EType folder_type)  } +BOOL LLViewerFolderType::lookupIsHiddenType(LLFolderType::EType folder_type) +{ +	const ViewerFolderEntry *entry = LLViewerFolderDictionary::getInstance()->lookup(folder_type); +	if (entry) +	{ +		return entry->mIsHidden; +	} +	return FALSE; +} + +  const std::string &LLViewerFolderType::lookupNewCategoryName(LLFolderType::EType folder_type)  {  	const ViewerFolderEntry *entry = LLViewerFolderDictionary::getInstance()->lookup(folder_type); diff --git a/indra/newview/llviewerfoldertype.h b/indra/newview/llviewerfoldertype.h index f5938de619..a348274e8f 100644 --- a/indra/newview/llviewerfoldertype.h +++ b/indra/newview/llviewerfoldertype.h @@ -40,6 +40,7 @@ public:  	static const std::string&   lookupIconName(EType folder_type, BOOL is_open = FALSE); // folder icon name  	static BOOL					lookupIsQuietType(EType folder_type); // folder doesn't require UI update when changes have occured +	static BOOL					lookupIsHiddenType(EType folder_type); // folder doesn't require UI update when changes have occured  	static const std::string&	lookupNewCategoryName(EType folder_type); // default name when creating new category  	static LLFolderType::EType	lookupTypeFromNewCategoryName(const std::string& name); // default name when creating new category diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index 9e58acdcd3..22666cec0d 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -1269,7 +1269,7 @@ void menu_create_inventory_item(LLFolderView* root, LLFolderBridge *bridge, cons  {  	std::string type_name = userdata.asString(); -	if (("category" == type_name) || ("current" == type_name) || ("outfit" == type_name) || ("my_otfts" == type_name)) +	if (("inbox" == type_name) || ("outbox" == type_name) || ("category" == type_name) || ("current" == type_name) || ("outfit" == type_name) || ("my_otfts" == type_name))  	{  		LLFolderType::EType preferred_type = LLFolderType::lookup(type_name); diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 1e53274cd6..4be39bb88e 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -64,8 +64,10 @@  #include "llappviewer.h"  #include "lllogininstance.h"   //#include "llfirstuse.h" +#include "llviewernetwork.h"  #include "llwindow.h" +  #include "llfloatermediabrowser.h"	// for handling window close requests and geometry change requests in media browser windows.  #include "llfloaterwebcontent.h"	// for handling window close requests and geometry change requests in media browser windows. @@ -1360,6 +1362,34 @@ void LLViewerMedia::removeCookie(const std::string &name, const std::string &dom  } +class LLInventoryUserStatusResponder : public LLHTTPClient::Responder +{ +public: +	LLInventoryUserStatusResponder() +		: LLCurl::Responder() +	{ +	} + +	void completed(U32 status, const std::string& reason, const LLSD& content) +	{ +		if (isGoodStatus(status)) +		{ +			// Complete success +			gSavedSettings.setBOOL("InventoryDisplayInbox", true); +		} +		else if (status == 401) +		{ +			// API is available for use but OpenID authorization failed +			gSavedSettings.setBOOL("InventoryDisplayInbox", true); +		} +		else +		{ +			// API in unavailable +			llinfos << "Marketplace API is unavailable -- Inbox Disabled" << llendl; +		} +	} +}; +  /////////////////////////////////////////////////////////////////////////////////////////  // static  void LLViewerMedia::setOpenIDCookie() @@ -1406,6 +1436,25 @@ void LLViewerMedia::setOpenIDCookie()  		LLHTTPClient::get(profile_url,    			new LLViewerMediaWebProfileResponder(raw_profile_url.getAuthority()),  			headers); + +		std::string url = "https://marketplace.secondlife.com/"; + +		if (!LLGridManager::getInstance()->isInProductionGrid()) +		{ +			std::string gridLabel = LLGridManager::getInstance()->getGridLabel(); +			url = llformat("https://marketplace.%s.lindenlab.com/", utf8str_tolower(gridLabel).c_str()); +		} +	 +		url += "api/1/users/"; +		url += gAgent.getID().getString(); +		url += "/user_status"; + +		headers = LLSD::emptyMap(); +		headers["Accept"] = "*/*"; +		headers["Cookie"] = sOpenIDCookie; +		headers["User-Agent"] = getCurrentUserAgent(); + +		LLHTTPClient::get(url, new LLInventoryUserStatusResponder(), headers);  	}  } diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 7ab335314a..fa394e55b3 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -936,7 +936,6 @@ protected:  //one global instance to bind them  LLOpenTaskOffer* gNewInventoryObserver=NULL; -  class LLNewInventoryHintObserver : public LLInventoryAddedObserver  {  protected: @@ -946,6 +945,8 @@ protected:  	}  }; +LLNewInventoryHintObserver* gNewInventoryHintObserver=NULL; +  void start_new_inventory_observer()  {  	if (!gNewInventoryObserver) //task offer observer  @@ -962,7 +963,12 @@ void start_new_inventory_observer()  		gInventory.addObserver(gInventoryMoveObserver);  	} -	gInventory.addObserver(new LLNewInventoryHintObserver()); +	if (!gNewInventoryHintObserver) +	{ +		// Observer is deleted by gInventory +		gNewInventoryHintObserver = new LLNewInventoryHintObserver(); +		gInventory.addObserver(gNewInventoryHintObserver); +	}  }  class LLDiscardAgentOffer : public LLInventoryFetchItemsObserver @@ -4324,7 +4330,7 @@ void process_sound_trigger(LLMessageSystem *msg, void **)  	{  		return;  	} - +		  	// Don't play sounds from gestures if they are not enabled.  	if (!gSavedSettings.getBOOL("EnableGestureSounds")) return; @@ -6484,7 +6490,7 @@ void process_script_dialog(LLMessageSystem* msg, void**)      LLUUID owner_id;  	if (gMessageSystem->getNumberOfBlocks("OwnerData") > 0)  	{ -		msg->getUUID("OwnerData", "OwnerID", owner_id); +    msg->getUUID("OwnerData", "OwnerID", owner_id);  	}  	if (LLMuteList::getInstance()->isMuted(object_id) || LLMuteList::getInstance()->isMuted(owner_id)) diff --git a/indra/newview/llviewerprecompiledheaders.h b/indra/newview/llviewerprecompiledheaders.h index faa86d43dd..252183b6d7 100644 --- a/indra/newview/llviewerprecompiledheaders.h +++ b/indra/newview/llviewerprecompiledheaders.h @@ -33,6 +33,8 @@  // in viewer.  // It is used to precompile headers for improved build speed. +#include <boost/coroutine/coroutine.hpp> +  #include "linden_common.h"  // Work around stupid Microsoft STL warning @@ -118,8 +120,8 @@  // Library includes from llvfs  #include "lldir.h" - -// Library includes from llmessage project +
 +// Library includes from llmessage project
  #include "llcachename.h"  #endif diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index b1441cc281..cff166b825 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1979,7 +1979,10 @@ void LLViewerWindow::shutdownViews()  	// destroy the nav bar, not currently part of gViewerWindow  	// *TODO: Make LLNavigationBar part of gViewerWindow +	if (LLNavigationBar::instanceExists()) +	{  	delete LLNavigationBar::getInstance(); +	}  	// destroy menus after instantiating navbar above, as it needs  	// access to gMenuHolder @@ -4512,6 +4515,14 @@ void LLViewerWindow::setup3DViewport(S32 x_offset, S32 y_offset)  	glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);  } +void LLViewerWindow::revealIntroPanel() +{ +	if (mProgressView) +	{ +		mProgressView->revealIntroPanel(); +	} +} +  void LLViewerWindow::setShowProgress(const BOOL show)  {  	if (mProgressView) diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index df6928aa1d..ff49ed1f62 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -271,6 +271,7 @@ public:  	void			setProgressMessage(const std::string& msg);  	void			setProgressCancelButtonVisible( BOOL b, const std::string& label = LLStringUtil::null );  	LLProgressView *getProgressView() const; +	void			revealIntroPanel();  	void			updateObjectUnderCursor(); diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index 973df6998a..dc810cbf7c 100644 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -133,6 +133,15 @@       name="AvatarListItemIconVoiceLeftColor"       reference="AvatarListItemIconOfflineColor" />      <color +     name="BadgeImageColor" +     value="0.44 0.69 0.56 1.0" /> +    <color +     name="BadgeBorderColor" +     value="0.9 0.9 0.9 1.0" /> +    <color +     name="BadgeLabelColor" +     reference="White" /> +    <color       name="ButtonBorderColor"       reference="Unused?" />      <color @@ -760,7 +769,7 @@      <color       name="MenuBarProjectBgColor"       reference="MdBlue" /> - +        <color        name="MeshImportTableNormalColor"        value="1 1 1 1"/> diff --git a/indra/newview/skins/default/textures/icons/Inv_Gift.png b/indra/newview/skins/default/textures/icons/Inv_Gift.pngBinary files differ new file mode 100644 index 0000000000..5afe85d72d --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_Gift.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Disabled.png b/indra/newview/skins/default/textures/icons/OutboxPush_Disabled.pngBinary files differ new file mode 100644 index 0000000000..be58114aa1 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Disabled.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Off.png b/indra/newview/skins/default/textures/icons/OutboxPush_Off.pngBinary files differ new file mode 100644 index 0000000000..e6b9480ab1 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Off.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_On.png b/indra/newview/skins/default/textures/icons/OutboxPush_On.pngBinary files differ new file mode 100644 index 0000000000..ffda2e92d4 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/OutboxPush_On.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_On_Over.png b/indra/newview/skins/default/textures/icons/OutboxPush_On_Over.pngBinary files differ new file mode 100644 index 0000000000..6b5911014f --- /dev/null +++ b/indra/newview/skins/default/textures/icons/OutboxPush_On_Over.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_On_Selected.png b/indra/newview/skins/default/textures/icons/OutboxPush_On_Selected.pngBinary files differ new file mode 100644 index 0000000000..0e60b417b0 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/OutboxPush_On_Selected.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Over.png b/indra/newview/skins/default/textures/icons/OutboxPush_Over.pngBinary files differ new file mode 100644 index 0000000000..9c26b92e73 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Over.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Press.png b/indra/newview/skins/default/textures/icons/OutboxPush_Press.pngBinary files differ new file mode 100644 index 0000000000..3b5d462975 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Press.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Progress_1.png b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_1.pngBinary files differ new file mode 100644 index 0000000000..f85be047b0 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_1.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Progress_2.png b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_2.pngBinary files differ new file mode 100644 index 0000000000..cd4e482216 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_2.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Progress_3.png b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_3.pngBinary files differ new file mode 100644 index 0000000000..d212a871ce --- /dev/null +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_3.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Progress_4.png b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_4.pngBinary files differ new file mode 100644 index 0000000000..e5b6023e36 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_4.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Progress_5.png b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_5.pngBinary files differ new file mode 100644 index 0000000000..e1911a092f --- /dev/null +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_5.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Progress_6.png b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_6.pngBinary files differ new file mode 100644 index 0000000000..9e59f7843a --- /dev/null +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_6.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Selected.png b/indra/newview/skins/default/textures/icons/OutboxPush_Selected.pngBinary files differ new file mode 100644 index 0000000000..51e8bff646 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Selected.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Disabled.png b/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Disabled.pngBinary files differ new file mode 100644 index 0000000000..300e2e69e1 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Disabled.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Over.png b/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Over.pngBinary files differ new file mode 100644 index 0000000000..32fb236381 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Over.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Press.png b/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Press.pngBinary files differ new file mode 100644 index 0000000000..827f343b1e --- /dev/null +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Press.png diff --git a/indra/newview/skins/default/textures/icons/Sync_Disabled.png b/indra/newview/skins/default/textures/icons/Sync_Disabled.pngBinary files differ new file mode 100644 index 0000000000..ca2e8def97 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Sync_Disabled.png diff --git a/indra/newview/skins/default/textures/icons/Sync_Enabled.png b/indra/newview/skins/default/textures/icons/Sync_Enabled.pngBinary files differ new file mode 100644 index 0000000000..bc236c8b98 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Sync_Enabled.png diff --git a/indra/newview/skins/default/textures/icons/Sync_Progress_1.png b/indra/newview/skins/default/textures/icons/Sync_Progress_1.pngBinary files differ new file mode 100644 index 0000000000..624e556376 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Sync_Progress_1.png diff --git a/indra/newview/skins/default/textures/icons/Sync_Progress_2.png b/indra/newview/skins/default/textures/icons/Sync_Progress_2.pngBinary files differ new file mode 100644 index 0000000000..5769803b3f --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Sync_Progress_2.png diff --git a/indra/newview/skins/default/textures/icons/Sync_Progress_3.png b/indra/newview/skins/default/textures/icons/Sync_Progress_3.pngBinary files differ new file mode 100644 index 0000000000..92d4bfb020 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Sync_Progress_3.png diff --git a/indra/newview/skins/default/textures/icons/Sync_Progress_4.png b/indra/newview/skins/default/textures/icons/Sync_Progress_4.pngBinary files differ new file mode 100644 index 0000000000..6d43eb3a9f --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Sync_Progress_4.png diff --git a/indra/newview/skins/default/textures/icons/Sync_Progress_5.png b/indra/newview/skins/default/textures/icons/Sync_Progress_5.pngBinary files differ new file mode 100644 index 0000000000..766d063c99 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Sync_Progress_5.png diff --git a/indra/newview/skins/default/textures/icons/Sync_Progress_6.png b/indra/newview/skins/default/textures/icons/Sync_Progress_6.pngBinary files differ new file mode 100644 index 0000000000..dfe7f68b72 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Sync_Progress_6.png diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index cc7cce99c9..c2757f2c94 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -72,8 +72,11 @@ with the same filename but different name    <texture name="BackButton_Over" file_name="icons/back_arrow_over.png" preload="false" scale.left="22" scale.top="12" scale.right="25" scale.bottom="12" />    <texture name="BackButton_Press" file_name="icons/back_arrow_press.png" preload="false" scale.left="22" scale.top="12" scale.right="25" scale.bottom="12" /> +  <texture name="Badge_Background" file_name="widgets/Badge_Background.png" preload="true" scale.left="9" scale.top="12" scale.right="248" scale.bottom="12" /> +  <texture name="Badge_Border" file_name="widgets/Badge_Border.png" preload="true" scale.left="9" scale.top="12" scale.right="248" scale.bottom="12" /> +    <texture name="Blank" file_name="Blank.png" preload="false" /> -	 +    <texture name="BreadCrumbBtn_Left_Disabled" file_name="widgets/BreadCrumbBtn_Left_Disabled.png" preload="false"/>    <texture name="BreadCrumbBtn_Left_Off" file_name="widgets/BreadCrumbBtn_Left_Off.png" preload="false"/>    <texture name="BreadCrumbBtn_Left_Over" file_name="widgets/BreadCrumbBtn_Left_Over.png" preload="false"/> @@ -88,7 +91,6 @@ with the same filename but different name    <texture name="BreadCrumbBtn_Right_Off" file_name="widgets/BreadCrumbBtn_Right_Off.png" preload="false"/>    <texture name="BreadCrumbBtn_Right_Over" file_name="widgets/BreadCrumbBtn_Right_Over.png" preload="false"/>    <texture name="BreadCrumbBtn_Right_Press" file_name="widgets/BreadCrumbBtn_Right_Press.png" preload="false"/> -     <texture name="BuyArrow_Over" file_name="navbar/BuyArrow_Over.png" preload="true" scale.left="0" scale.top="1" scale.right="0" scale.bottom="0"  />    <texture name="BuyArrow_Press" file_name="navbar/BuyArrow_Press.png" preload="true" scale.left="1" scale.top="1" scale.right="0" scale.bottom="0"  /> @@ -266,6 +268,8 @@ with the same filename but different name    <texture name="Locked_Icon" file_name="icons/Locked_Icon.png" preload="false" /> +  <texture name="MarketplaceBtn_Off" file_name="widgets/MarketplaceBtn_Off.png" preload="true" scale.left="30" scale.top="19" scale.right="35" scale.bottom="4" /> +  <texture name="MarketplaceBtn_Selected" file_name="widgets/MarketplaceBtn_Selected.png" preload="true" scale.left="30" scale.top="19" scale.right="35" scale.bottom="4" />    <texture name="Microphone_On" file_name="icons/Microphone_On.png" preload="false" /> @@ -349,6 +353,23 @@ with the same filename but different name    <texture name="OptionsMenu_Off" file_name="icons/OptionsMenu_Off.png" preload="false" />    <texture name="OptionsMenu_Press" file_name="icons/OptionsMenu_Press.png" preload="false" /> +  <texture name="OutboxPush_Disabled" file_name="icons/OutboxPush_Disabled.png" preload="true" /> +  <texture name="OutboxPush_Off" file_name="icons/OutboxPush_Off.png" preload="true" /> +  <texture name="OutboxPush_On" file_name="icons/OutboxPush_On.png" preload="true" /> +  <texture name="OutboxPush_On_Over" file_name="icons/OutboxPush_On_Over.png" preload="true" /> +  <texture name="OutboxPush_Over" file_name="icons/OutboxPush_Over.png" preload="true" /> +  <texture name="OutboxPush_Press" file_name="icons/OutboxPush_Press.png" preload="true" /> +  <texture name="OutboxPush_Progress_1" file_name="icons/OutboxPush_Progress_1.png" preload="true" /> +  <texture name="OutboxPush_Progress_2" file_name="icons/OutboxPush_Progress_2.png" preload="true" /> +  <texture name="OutboxPush_Progress_3" file_name="icons/OutboxPush_Progress_3.png" preload="true" /> +  <texture name="OutboxPush_Progress_4" file_name="icons/OutboxPush_Progress_4.png" preload="true" /> +  <texture name="OutboxPush_Progress_5" file_name="icons/OutboxPush_Progress_5.png" preload="true" /> +  <texture name="OutboxPush_Progress_6" file_name="icons/OutboxPush_Progress_6.png" preload="true" /> +  <texture name="OutboxPush_Selected" file_name="icons/OutboxPush_Selected.png" preload="true" /> +  <texture name="OutboxPush_Selected_Disabled" file_name="icons/OutboxPush_Selected_Disabled.png" preload="true" /> +  <texture name="OutboxPush_Selected_Over" file_name="icons/OutboxPush_Selected_Over.png" preload="true" /> +  <texture name="OutboxPush_Selected_Press" file_name="icons/OutboxPush_Selected_Press.png" preload="true" /> +    <texture name="PanOrbit_Off" file_name="bottomtray/PanOrbit_Off.png" preload="false" />    <texture name="Parcel_Exp_Color" file_name="icons/Parcel_Exp_Color.png" preload="false" /> @@ -496,6 +517,15 @@ with the same filename but different name    <texture name="StopReload_Off" file_name="icons/StopReload_Off.png" preload="false" />    <texture name="StopReload_Over" file_name="icons/StopReload_Over.png" preload="false" /> +  <texture name="Sync_Disabled" file_name="icons/Sync_Disabled.png" preload="true" /> +  <texture name="Sync_Enabled" file_name="icons/Sync_Enabled.png" preload="true" /> +  <texture name="Sync_Progress_1" file_name="icons/Sync_Progress_1.png" preload="true" /> +  <texture name="Sync_Progress_2" file_name="icons/Sync_Progress_2.png" preload="true" /> +  <texture name="Sync_Progress_3" file_name="icons/Sync_Progress_3.png" preload="true" /> +  <texture name="Sync_Progress_4" file_name="icons/Sync_Progress_4.png" preload="true" /> +  <texture name="Sync_Progress_5" file_name="icons/Sync_Progress_5.png" preload="true" /> +  <texture name="Sync_Progress_6" file_name="icons/Sync_Progress_6.png" preload="true" /> +    <texture name="TabIcon_Appearance_Off" file_name="taskpanel/TabIcon_Appearance_Off.png" preload="false" />    <texture name="TabIcon_Appearance_Selected" file_name="taskpanel/TabIcon_Appearance_Selected.png" preload="false" />    <texture name="TabIcon_Close_Off" file_name="taskpanel/TabIcon_Close_Off.png" preload="false" /> @@ -649,6 +679,7 @@ with the same filename but different name    <texture name="inv_folder_mesh.tga"/>    <texture name="inv_item_mesh.tga"/> +    <texture name="lag_status_critical.tga" />    <texture name="lag_status_good.tga" />    <texture name="lag_status_warning.tga" /> diff --git a/indra/newview/skins/default/textures/widgets/Badge_Background.png b/indra/newview/skins/default/textures/widgets/Badge_Background.pngBinary files differ new file mode 100644 index 0000000000..5089c30312 --- /dev/null +++ b/indra/newview/skins/default/textures/widgets/Badge_Background.png diff --git a/indra/newview/skins/default/textures/widgets/Badge_Border.png b/indra/newview/skins/default/textures/widgets/Badge_Border.pngBinary files differ new file mode 100644 index 0000000000..4b086a63fb --- /dev/null +++ b/indra/newview/skins/default/textures/widgets/Badge_Border.png diff --git a/indra/newview/skins/default/textures/widgets/MarketplaceBtn_Off.png b/indra/newview/skins/default/textures/widgets/MarketplaceBtn_Off.pngBinary files differ new file mode 100644 index 0000000000..e603c44384 --- /dev/null +++ b/indra/newview/skins/default/textures/widgets/MarketplaceBtn_Off.png diff --git a/indra/newview/skins/default/textures/widgets/MarketplaceBtn_Selected.png b/indra/newview/skins/default/textures/widgets/MarketplaceBtn_Selected.pngBinary files differ new file mode 100644 index 0000000000..fbc164123f --- /dev/null +++ b/indra/newview/skins/default/textures/widgets/MarketplaceBtn_Selected.png diff --git a/indra/newview/skins/default/xui/en/menu_inventory_add.xml b/indra/newview/skins/default/xui/en/menu_inventory_add.xml index b36b82ebd8..e0ccb18c08 100644 --- a/indra/newview/skins/default/xui/en/menu_inventory_add.xml +++ b/indra/newview/skins/default/xui/en/menu_inventory_add.xml @@ -42,7 +42,7 @@                      <menu_item_call.on_enable                       function="File.EnableUpload" />                  </menu_item_call> -		<menu_item_call +                <menu_item_call                   label="Model..."                   layout="topleft"                   name="Upload Model"> @@ -263,4 +263,4 @@                       parameter="eyes" />                  </menu_item_call>              </menu> -</menu> +</menu>
\ No newline at end of file diff --git a/indra/newview/skins/default/xui/en/panel_progress.xml b/indra/newview/skins/default/xui/en/panel_progress.xml index 2868d91cc7..4535c56339 100644 --- a/indra/newview/skins/default/xui/en/panel_progress.xml +++ b/indra/newview/skins/default/xui/en/panel_progress.xml @@ -132,4 +132,12 @@       name="cancel_btn"       top="700"       width="90" /> +  <web_browser +   follows="all" +   layout="topleft" +   left="0" +   name="login_media_panel" +   width="1024" +   height="768" +   top="0"/>  </panel> 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 6ef93406ec..0f330a7b98 100644 --- a/indra/newview/skins/default/xui/en/panel_side_tray.xml +++ b/indra/newview/skins/default/xui/en/panel_side_tray.xml @@ -142,6 +142,7 @@      mouse_opaque="false"      background_visible="true"    > +      <badge location="top_left" location_percent_vcenter="50" location_percent_hcenter="95" />        <panel          class="sidepanel_inventory"          name="sidepanel_inventory" diff --git a/indra/newview/skins/default/xui/en/sidepanel_inventory.xml b/indra/newview/skins/default/xui/en/sidepanel_inventory.xml index 8997c1a6d7..00f3135035 100644 --- a/indra/newview/skins/default/xui/en/sidepanel_inventory.xml +++ b/indra/newview/skins/default/xui/en/sidepanel_inventory.xml @@ -9,7 +9,7 @@  	  min_width="240"  	  name="objects panel"  	  width="333"> -	 <panel +    <panel  		 follows="all"  		 layout="topleft"  		 left="0" @@ -19,24 +19,234 @@  		 height="570"  		 visible="true"  		 width="330"> -		<panel -			 class="panel_main_inventory" -			 filename="panel_main_inventory.xml" -			 follows="all" -			 layout="topleft" -			 left="0" -			 name="panel_main_inventory" -			 top="0" -			 label="" -			 height="545" -			 width="330" /> +         <layout_stack +              follows="left|right|top|bottom" +              layout="topleft" +              left="0" +              top="0" +              orientation="vertical" +              name="inventory_layout_stack" +              height="535" +              width="330"> +             <layout_panel +                 name="main_inventory_layout_panel" +                 min_dim="150" +                 width="330" +                 follows="bottom|left|right" +                 user_resize="false" +                 height="480"> +                 <panel +                      class="panel_main_inventory" +                      filename="panel_main_inventory.xml" +                      follows="all" +                      layout="topleft" +                      left="0" +                      name="panel_main_inventory" +                      top="0" +                      label="" +                      height="480" +                      width="330" /> +             </layout_panel> +             <layout_panel +                 width="330" +                 auto_resize="true" +                 user_resize="false" +                 follows="bottom|left|right" +                 name="inbox_layout_panel" +                 min_dim="35" +                 max_dim="200" +				 expanded_min_dim="90" +                 height="200"> +                 <panel +                      follows="all" +                      layout="topleft" +                      left="0" +                      name="marketplace_inbox" +                      class="panel_marketplace_inbox" +                      top="0" +                      label="" +                      height="200" +                      width="330"> +                     <string name="InboxLabelWithArg">Received Items ([NUM])</string> +                     <string name="InboxLabelNoArg">Received Items</string> +                     <button +                        label="Received Items" +                        name="inbox_btn" +                        height="35" +                        width="308" +                        image_unselected="MarketplaceBtn_Off" +                        image_selected="MarketplaceBtn_Selected" +                        halign="left" +                        handle_right_mouse="false" +                        follows="top|left|right" +                        is_toggle="true" +                        tab_stop="false" +                        pad_left="35" +                        top="0" +                        left="10" /> +                     <text +                        type="string" +                        length="1" +                        follows="right|top" +                        layout="topleft" +                        height="13" +                        top="10" +                        right="-20" +                        name="inbox_fresh_new_count" +                        font="SansSerifMedium" +                        halign="right" +                        text_color="EmphasisColor" +                        top_pad="0" +                        width="300"> +                        [NUM] New +                     </text> +                     <panel +                        follows="all" +                        left="10" +                        bottom="200" +                        width="308" +                        top="35" +                        bg_opaque_color="InventoryBackgroundColor" +                        background_visible="true" +                        background_opaque="true" +                        tool_tip="Drag and drop items to your inventory to manage and use them" +                        > +                        <inventory_panel +                            bg_opaque_color="DkGray2" +                            bg_alpha_color="DkGray2" +                            background_visible="true" +                            background_opaque="true" +                            border="false" +                            bevel_style="none" +                            follows="all" +                            top="0" +                            height="165" +                            start_folder="Inbox" +                            layout="topleft" +                            left="0" +                            name="inventory_inbox" +                            sort_order_setting="InventorySortOrder" +                            show_item_link_overlays="true" +                            top_pad="0" +                            width="308"> +                            <scroll reserve_scroll_corner="false" /> +                        </inventory_panel> +                    </panel> +                 </panel> +             </layout_panel> +             <layout_panel +                width="330" +                auto_resize="true" +                user_resize="false" +                follows="bottom|left|right" +                name="outbox_layout_panel" +                min_dim="35" +                max_dim="200" +				expanded_min_dim="90" +                height="200"> +                 <panel +                      follows="all" +                      layout="topleft" +                      left="10" +                      name="marketplace_outbox" +                      class="panel_marketplace_outbox" +                      top="0" +                      label="" +                      height="200" +                      width="310"> +                     <button +                        label="Merchant Outbox" +                        is_toggle="true" +                        handle_right_mouse="false" +                        name="outbox_btn" +                        follows="top|left|right" +                        image_unselected="MarketplaceBtn_Off" +                        image_selected="MarketplaceBtn_Selected" +                        height="35" +                        tab_stop="false" +                        width="308" +                        halign="left" +                        pad_left="35" +                        top="0" +                        left="0" /> +                     <button +                         image_unselected="OutboxPush_Off" +                         image_selected="OutboxPush_Selected" +                         image_hover_selected="OutboxPush_Selected_Over" +                         image_hover_unselected="OutboxPush_Over" +                         image_disabled_selected="OutboxPush_Selected_Disabled" +                         image_disabled="OutboxPush_Disabled" +                         image_pressed="OutboxPush_Press" +                         image_pressed_selected="OutboxPush_Selected_Press" +                         label="" +                         tool_tip="Push to my Marketplace Storefront" +                         is_toggle="false" +                         name="outbox_sync_btn" +                         follows="top|right" +                         tab_stop="false" +                         halign="center" +                         top="6" +                         left="-50" +                         height="23" +                         width="32" +                         enabled="false" /> +                     <loading_indicator +                        follows="top|right" +                        name="outbox_sync_indicator" +                        top="6" +                        left="-50" +                        height="23" +                        width="32" +                        images_per_sec="1.15" +                        tab_stop="false" +                        visible="false"> +                         <images> +                             <image name="OutboxPush_Progress_1"/> +                             <image name="OutboxPush_Progress_2"/> +                             <image name="OutboxPush_Progress_3"/> +                             <image name="OutboxPush_Progress_4"/> +                             <image name="OutboxPush_Progress_5"/> +                             <image name="OutboxPush_Progress_6"/> +                         </images> +                     </loading_indicator> +                     <panel +                         follows="all" +                         left="0" +                         bottom="200" +                         width="330" +                         top="35" +                           > +                         <inventory_panel +                              bg_opaque_color="DkGray2" +                              bg_alpha_color="DkGray2" +                              background_visible="true" +                              background_opaque="true" +                              border="false" +                              bevel_style="none" +                              follows="all" +                              height="165" +                              start_folder="Outbox" +                              layout="topleft" +                              left="0" +                              name="inventory_outbox" +                              sort_order_setting="InventorySortOrder" +                              show_item_link_overlays="true" +                              top="0" +                              width="308"> +                             <scroll reserve_scroll_corner="false" /> +                         </inventory_panel> +                     </panel> + +                 </panel> +             </layout_panel> +         </layout_stack>  		<panel  		     follows="bottom|left|right" -			 height="25" +			 height="30"  			 layout="topleft"  			 name="button_panel"  			 left="9" -			 top_pad="-2" +             top_pad="7"  			 width="308">  			<layout_stack       	         follows="bottom|left|right" diff --git a/indra/newview/skins/default/xui/en/widgets/badge.xml b/indra/newview/skins/default/xui/en/widgets/badge.xml new file mode 100644 index 0000000000..f77c4b7178 --- /dev/null +++ b/indra/newview/skins/default/xui/en/widgets/badge.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<!-- Additional attributes: +   --> +<badge border_image="Badge_Border" +       border_color="BadgeBorderColor" +       font="SansSerifSmall" +       image="Badge_Background" +       image_color="BadgeImageColor" +       label_color="BadgeLabelColor" +       location="top_left" +       location_percent_hcenter="85" +       location_percent_vcenter="85" +       padding_horiz="7" +       padding_vert="4" +       requests_front="true" +       > +</badge> diff --git a/indra/newview/skins/default/xui/en/widgets/button.xml b/indra/newview/skins/default/xui/en/widgets/button.xml index 16241ed84e..302014eb24 100644 --- a/indra/newview/skins/default/xui/en/widgets/button.xml +++ b/indra/newview/skins/default/xui/en/widgets/button.xml @@ -25,5 +25,6 @@          pad_bottom="3"           height="23"          scale_image="true" +        handle_right_mouse="true"          use_draw_context_alpha="true">  </button> diff --git a/indra/newview/skins/default/xui/en/widgets/inventory_panel.xml b/indra/newview/skins/default/xui/en/widgets/inventory_panel.xml index 93875d66e6..3164cc5eba 100644 --- a/indra/newview/skins/default/xui/en/widgets/inventory_panel.xml +++ b/indra/newview/skins/default/xui/en/widgets/inventory_panel.xml @@ -3,4 +3,11 @@    bg_opaque_color="InventoryBackgroundColor"    background_visible="true"    background_opaque="true" -  /> +  > +    <scroll +		name="Inventory Scroller" +        follows="all" +		reserve_scroll_corner="true" +        tab_stop="true" +        /> +</panel> diff --git a/indra/newview/skins/default/xui/en/widgets/panel.xml b/indra/newview/skins/default/xui/en/widgets/panel.xml index 9bf99fa363..47a210d9b7 100644 --- a/indra/newview/skins/default/xui/en/widgets/panel.xml +++ b/indra/newview/skins/default/xui/en/widgets/panel.xml @@ -10,4 +10,5 @@         bg_alpha_image_overlay="White"         background_visible="false"         background_opaque="false" -       chrome="false"/>
\ No newline at end of file +       chrome="false" +       accepts_badge="true"/>
\ No newline at end of file diff --git a/indra/newview/skins/minimal/xui/en/panel_im_control_panel.xml b/indra/newview/skins/minimal/xui/en/panel_im_control_panel.xml index be13bc1bb7..2cb77bcdf3 100644 --- a/indra/newview/skins/minimal/xui/en/panel_im_control_panel.xml +++ b/indra/newview/skins/minimal/xui/en/panel_im_control_panel.xml @@ -23,102 +23,172 @@       orientation="vertical"       top_pad="5"       width="145"> -      <layout_panel -       auto_resize="false" -       follows="top|left|right" -       height="20" -       layout="topleft" -       left="2" -       min_height="20" -       width="140" -       name="view_profile_btn_panel" -       top="0" -       user_resize="false"> -        <button -         follows="left|top|right" -         height="23" -         label="Profile" -         name="view_profile_btn" +        <layout_panel +         auto_resize="false" +         follows="top|left|right" +         height="20" +         layout="topleft" +         left="2" +         min_height="20" +         width="140" +         name="view_profile_btn_panel"           top="0" -         width="140" /> -      </layout_panel> -      <layout_panel -       auto_resize="false" -       follows="top|left|right" -       height="25" -       layout="topleft" -       min_height="25" -       width="140" -       name="add_friend_btn_panel" -       user_resize="false"> -        <button -         follows="left|top|right" -         height="23" -         label="Add Friend" -         name="add_friend_btn" -         top="5" -         width="140" /> -      </layout_panel> -      <layout_panel -       auto_resize="false" -       follows="top|left|right" -       height="25" -       layout="topleft" -       min_height="25" -       width="140" -       name="teleport_btn_panel" -       user_resize="false"> -        <button -             auto_resize="false" +         user_resize="false"> +            <button +             follows="left|top|right" +             height="23" +             label="Profile" +             name="view_profile_btn" +             top="0" +             width="140" /> +        </layout_panel> +        <layout_panel +         auto_resize="false" +         follows="top|left|right" +         height="25" +         layout="topleft" +         min_height="25" +         width="140" +         name="add_friend_btn_panel" +         user_resize="false"> +            <button               follows="left|top|right"               height="23" -             label="Teleport" -             name="teleport_btn" -             tool_tip = "Offer to teleport this person" +             label="Add Friend" +             name="add_friend_btn" +             top="5"               width="140" /> -      </layout_panel> -      <layout_panel +        </layout_panel> +        <layout_panel           auto_resize="false"           follows="top|left|right"           height="25"           layout="topleft"           min_height="25"           width="140" -         name="call_btn_panel" +         name="teleport_btn_panel"           user_resize="false"> -        <button -         follows="left|top|right" -         height="23" -         label="Call" -         name="call_btn" -         width="140" /> -      </layout_panel> -      <layout_panel -       auto_resize="false" -       follows="top|left|right" -       height="25" -       layout="topleft" -       min_height="25" -       width="140" -       name="end_call_btn_panel" -       user_resize="false" -       visible="false"> -        <button -         follows="left|top|right" -         height="23" -         label="End Call" -         name="end_call_btn" -         width="140" /> -      </layout_panel> -      <layout_panel -       mouse_opaque="false" -       auto_resize="true" -       follows="top|left" -       height="0" -       layout="topleft" -       min_height="0" -       width="140" -       name="spacer" -       user_resize="false" /> +            <button +                 auto_resize="false" +                 follows="left|top|right" +                 height="23" +                 label="Teleport" +                 name="teleport_btn" +                 tool_tip = "Offer to teleport this person" +                 width="140" /> +        </layout_panel> +        <layout_panel +           auto_resize="false" +           follows="top|left|right" +           height="25" +           layout="topleft" +           min_height="25" +           width="140" +           name="call_btn_panel" +           user_resize="false"> +            <button +             follows="left|top|right" +             height="23" +             label="Call" +             name="call_btn" +             width="140" /> +        </layout_panel> +        <layout_panel +         auto_resize="false" +         follows="top|left|right" +         height="25" +         layout="topleft" +         min_height="25" +         width="140" +         name="end_call_btn_panel" +         user_resize="false" +         visible="false"> +            <button +             follows="left|top|right" +             height="23" +             label="End Call" +             name="end_call_btn" +             width="140" /> +        </layout_panel> +        <layout_panel +         auto_resize="false" +         follows="top|left|right" +         height="25" +         layout="topleft" +         min_height="25" +         width="140" +         name="block_btn_panel" +         user_resize="false"> +            <button +             follows="left|top|right" +             height="23" +             label="Block" +             name="block_btn" +             width="140" /> +        </layout_panel> +        <layout_panel +         auto_resize="false" +         follows="top|left|right" +         height="25" +         layout="topleft" +         min_height="25" +         width="140" +         name="unblock_btn_panel" +         user_resize="false" +         visible="false"> +            <button +             follows="left|top|right" +             height="23" +             label="Unblock" +             name="unblock_btn" +             width="140" /> +        </layout_panel> +        <layout_panel +         auto_resize="false" +         follows="top|left|right" +         height="25" +         layout="topleft" +         min_height="54" +         width="140" +         name="volume_ctrl_panel" +         visible="false"  +         user_resize="false"> +            <slider +             follows="top|left" +             height="23" +             increment="0.01" +             left="0" +             max_val="0.95" +             min_val="0.05" +             name="volume_slider" +             show_text="false" +             tool_tip="Call Volume" +             top_pad="32" +             value="0.5" +             width="125" /> +            <button +             follows="top|left" +             height="16" +             image_disabled="Audio_Off" +             image_disabled_selected="AudioMute_Off" +             image_hover_selected="AudioMute_Over" +             image_selected="AudioMute_Off" +             image_unselected="Audio_Off" +             is_toggle="true" +             left_pad="0" +             top_delta="4" +             name="mute_btn" +             width="16" /> +        </layout_panel> +        <layout_panel +         mouse_opaque="false" +         auto_resize="true" +         follows="top|left" +         height="0" +         layout="topleft" +         min_height="0" +         width="140" +         name="spacer" +         user_resize="false" />      </layout_stack>  </panel> | 
