diff options
Diffstat (limited to 'indra')
84 files changed, 2433 insertions, 393 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/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 218a0534e6..bae127d217 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -4180,7 +4180,29 @@        <key>Value</key>        <real>1.0</real>      </map> -	<key>InventoryLinking</key> +    <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>  		<string>Enable ability to create links to folders and items via "Paste as link".</string> @@ -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> diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index cbbdcb2983..eeb4ec8458 100644 --- 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 260693ebc7..866eae8d3d 100644 --- a/indra/newview/llfolderview.cpp +++ b/indra/newview/llfolderview.cpp @@ -815,6 +815,11 @@ void LLFolderView::sanitizeSelection()  		{  			// nothing selected to start with, so pick "My Inventory" as best guess  			new_selection = getItemByID(gInventory.getRootFolderID()); +			// ... except if it's hidden from the UI. +			if (new_selection && new_selection->getHidden()) +			{ +				new_selection = NULL; +			}  		}  		if (new_selection) @@ -1646,8 +1651,8 @@ BOOL LLFolderView::handleKeyHere( KEY key, MASK mask )  			LLFolderViewItem* parent_folder = last_selected->getParentFolder();  			if (!last_selected->isOpen() && parent_folder && parent_folder->getParentFolder())  			{ -				setSelection(parent_folder, FALSE, TRUE); -			} +					setSelection(parent_folder, FALSE, TRUE); +				}  			else  			{  				last_selected->setOpen( FALSE ); diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp index 1f53586ccc..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" @@ -357,7 +358,7 @@ void LLFolderViewItem::arrangeAndSet(BOOL set_selection,  	LLFolderView* root = getRoot();  	if (getParentFolder())  	{ -		getParentFolder()->requestArrange(); +	getParentFolder()->requestArrange();  	}  	if(set_selection)  	{ @@ -1202,10 +1203,11 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height, S32 filter_generation)  				}  				else  				{ -					folderp->setVisible( -						folderp->getFilteredFolder(filter_generation)					// folder must pass folder filters -						&&	(folderp->getFiltered(filter_generation) -							||	folderp->hasFilteredDescendants(filter_generation)));	// passed item 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()) @@ -2023,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;  } @@ -2042,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;  } @@ -2377,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);  } @@ -2648,8 +2679,8 @@ bool LLInventorySort::operator()(const LLFolderViewItem* const& a, const LLFolde  	// We sort by name if we aren't sorting by date  	// OR if these are folders and we are sorting folders by name.  	bool by_name = (!mByDate  -					|| (mFoldersByName  -						&& (a->getSortGroup() != SG_ITEM))); +		|| (mFoldersByName  +		&& (a->getSortGroup() != SG_ITEM)));  	if (a->getSortGroup() != b->getSortGroup())  	{ diff --git a/indra/newview/llfolderviewitem.h b/indra/newview/llfolderviewitem.h index 7d640adf2e..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; @@ -166,7 +166,7 @@ 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; } @@ -362,6 +362,9 @@ public:  		UNKNOWN, TRASH, NOT_TRASH  	} ETrash; +	typedef std::list<LLFolderViewItem*> items_t; +	typedef std::list<LLFolderViewFolder*> folders_t; +  private:  	S32		mNumDescendantsSelected; @@ -370,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; @@ -430,7 +431,7 @@ public:  	virtual void filter( LLInventoryFilter& filter);  	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); @@ -540,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/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index 1ff423056a..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" @@ -144,7 +143,7 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :  	mCommitCallbackRegistrar.add("Inventory.AttachObject", boost::bind(&LLInventoryPanel::attachObject, this, _2));  	mCommitCallbackRegistrar.add("Inventory.BeginIMSession", boost::bind(&LLInventoryPanel::beginIMSession, this));  	mCommitCallbackRegistrar.add("Inventory.Share",  boost::bind(&LLAvatarActions::shareWithAvatars)); - +	  }  void LLInventoryPanel::buildFolderView(const LLInventoryPanel::Params& params) @@ -154,7 +153,7 @@ void LLInventoryPanel::buildFolderView(const LLInventoryPanel::Params& params)  	const LLFolderType::EType preferred_type = LLViewerFolderType::lookupTypeFromNewCategoryName(params.start_folder);  	LLUUID root_id; - +	  	if ("LIBRARY" == params.start_folder())  	{  		root_id = gInventory.getLibraryRootFolderID(); @@ -162,31 +161,31 @@ void LLInventoryPanel::buildFolderView(const LLInventoryPanel::Params& params)  	else  	{  		root_id = (preferred_type != LLFolderType::FT_NONE) -				? gInventory.findCategoryUUIDForType(preferred_type)  +				? gInventory.findCategoryUUIDForType(preferred_type, false, false)   				: LLUUID::null;  	} -	LLRect folder_rect(0, -						0, -						getRect().getWidth(), -						0); -	LLFolderView::Params p; -	p.name = getName(); -	p.title = getLabel(); -	p.rect = folder_rect; -	p.parent_panel = this; -	p.tool_tip = p.name; +		LLRect folder_rect(0, +						   0, +						   getRect().getWidth(), +						   0); +		LLFolderView::Params p; +		p.name = getName(); +		p.title = getLabel(); +		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.use_label_suffix = params.use_label_suffix;  	p.allow_multiselect = mAllowMultiSelect; -	mFolderRoot = LLUICtrlFactory::create<LLFolderView>(p); +		mFolderRoot = LLUICtrlFactory::create<LLFolderView>(p); -} +	}  void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)  { @@ -204,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); @@ -570,88 +565,88 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id)   	LLFolderViewFolder* parent_folder = NULL;   	if (id == root_id) - 	{ - 		parent_folder = mFolderRoot; - 	} +		{ +			parent_folder = mFolderRoot; +		}   	else if (objectp) - 	{ +		{   		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 : " +		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() -  						<< llendl; -  				return; -  			} -  		 -  			if ((objectp->getType() == LLAssetType::AT_CATEGORY) && -  				(objectp->getActualType() != LLAssetType::AT_LINK_FOLDER)) -  			{ -  				LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(objectp->getType(), -  																				objectp->getType(), -  																				LLInventoryType::IT_CATEGORY, -  																				this, -  																				mFolderRoot, -  																				objectp->getUUID()); -  				if (new_listener) -  				{ -  					LLFolderViewFolder::Params params; -  					params.name = new_listener->getDisplayName(); -  					params.icon = new_listener->getIcon(); -  					params.icon_open = new_listener->getOpenIcon(); -  					if (mShowItemLinkOverlays) // if false, then links show up just like normal items -  					{ -  						params.icon_overlay = LLUI::getUIImage("Inv_Link"); -  					} -  					params.root = mFolderRoot; -  					params.listener = new_listener; -  					params.tool_tip = params.name; -  					LLFolderViewFolder* folderp = LLUICtrlFactory::create<LLFolderViewFolder>(params); -  					folderp->setItemSortOrder(mFolderRoot->getSortOrder()); -  					itemp = folderp; -  				} -  			} +					<< llendl; +			return; +		} +		 +		if ((objectp->getType() == LLAssetType::AT_CATEGORY) && +			(objectp->getActualType() != LLAssetType::AT_LINK_FOLDER)) +		{ +			LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(objectp->getType(), +																			objectp->getType(), +																			LLInventoryType::IT_CATEGORY, +																			this, +																			mFolderRoot, +																			objectp->getUUID()); +			if (new_listener) +			{ +				LLFolderViewFolder::Params params; +				params.name = new_listener->getDisplayName(); +				params.icon = new_listener->getIcon(); +				params.icon_open = new_listener->getOpenIcon(); +				if (mShowItemLinkOverlays) // if false, then links show up just like normal items +				{ +					params.icon_overlay = LLUI::getUIImage("Inv_Link"); +				} +				params.root = mFolderRoot; +				params.listener = new_listener; +				params.tool_tip = params.name; +				LLFolderViewFolder* folderp = LLUICtrlFactory::create<LLFolderViewFolder>(params); +				folderp->setItemSortOrder(mFolderRoot->getSortOrder()); +				itemp = folderp; +				} +			}    			else -  			{ -  				// Build new view for item. -  				LLInventoryItem* item = (LLInventoryItem*)objectp; -  				LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(item->getType(), -  																				item->getActualType(), -  																				item->getInventoryType(), -  																				this, -  																				mFolderRoot, -  																				item->getUUID(), -  																				item->getFlags()); -  -  				if (new_listener) -  				{ -  					LLFolderViewItem::Params params; -  					params.name = new_listener->getDisplayName(); -  					params.icon = new_listener->getIcon(); -  					params.icon_open = new_listener->getOpenIcon(); -  					if (mShowItemLinkOverlays) // if false, then links show up just like normal items -  					{ -  						params.icon_overlay = LLUI::getUIImage("Inv_Link"); -  					} -  					params.creation_date = new_listener->getCreationDate(); -  					params.root = mFolderRoot; -  					params.listener = new_listener; -  					params.rect = LLRect (0, 0, 0, 0); -  					params.tool_tip = params.name; -  					itemp = LLUICtrlFactory::create<LLFolderViewItem> (params); -  				} -  			} -  -  			if (itemp) -  			{ -  				itemp->addToFolder(parent_folder, mFolderRoot); -   			} +		{ +			// Build new view for item. +			LLInventoryItem* item = (LLInventoryItem*)objectp; +			LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(item->getType(), +																			item->getActualType(), +																			item->getInventoryType(), +																			this, +																			mFolderRoot, +																			item->getUUID(), +																			item->getFlags()); + +			if (new_listener) +			{ +				LLFolderViewItem::Params params; +				params.name = new_listener->getDisplayName(); +				params.icon = new_listener->getIcon(); +				params.icon_open = new_listener->getOpenIcon(); +				if (mShowItemLinkOverlays) // if false, then links show up just like normal items +				{ +					params.icon_overlay = LLUI::getUIImage("Inv_Link"); +				} +				params.creation_date = new_listener->getCreationDate(); +				params.root = mFolderRoot; +				params.listener = new_listener; +				params.rect = LLRect (0, 0, 0, 0); +				params.tool_tip = params.name; +				itemp = LLUICtrlFactory::create<LLFolderViewItem> (params); +			} +		} + +		if (itemp) +		{ +			itemp->addToFolder(parent_folder, mFolderRoot); +			}  		}  	} @@ -693,20 +688,20 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id)  // bit of a hack to make sure the inventory is open.  void LLInventoryPanel::openStartFolderOrMyInventory()  { -	// 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); +		// 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()) -		{ -			const std::string& child_name = child->getName(); -			mFolderRoot->openFolder(child_name); -			break; +			{ +				const std::string& child_name = child->getName(); +				mFolderRoot->openFolder(child_name); +				break; +			}  		}  	} -}  void LLInventoryPanel::onItemsCompletion()  { diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h index da67da13b2..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")  		{}  	}; 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/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/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/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/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/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_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 | 
