diff options
| author | Rick Pasetto <rick@lindenlab.com> | 2010-02-16 15:43:11 -0800 | 
|---|---|---|
| committer | Rick Pasetto <rick@lindenlab.com> | 2010-02-16 15:43:11 -0800 | 
| commit | 4dfed6e353ff880fcd45b4c8b402bf0f5a2f19f2 (patch) | |
| tree | 5d620ae33a3f1914acf3996c8ba59d33ff2c49e1 | |
| parent | fb384e6af40f6a0149d93cdc38d598dd95067fbb (diff) | |
| parent | 0e234edcc67ecf534df15f088158ef236f6de102 (diff) | |
Automated merge with ssh://rick@hg.lindenlab.com/viewer/viewer-2-0
29 files changed, 2474 insertions, 146 deletions
| diff --git a/indra/llaudio/llaudioengine.cpp b/indra/llaudio/llaudioengine.cpp index a28c94d00d..ed06c85e1a 100644 --- a/indra/llaudio/llaudioengine.cpp +++ b/indra/llaudio/llaudioengine.cpp @@ -202,12 +202,12 @@ void LLAudioEngine::updateInternetStream()  }  // virtual -int LLAudioEngine::isInternetStreamPlaying() +LLAudioEngine::LLAudioPlayState LLAudioEngine::isInternetStreamPlaying()  {  	if (mStreamingAudioImpl) -		return mStreamingAudioImpl->isPlaying(); +		return (LLAudioEngine::LLAudioPlayState) mStreamingAudioImpl->isPlaying(); -	return 0; // Stopped +	return LLAudioEngine::AUDIO_STOPPED; // Stopped  } diff --git a/indra/llaudio/llaudioengine.h b/indra/llaudio/llaudioengine.h index 457fd93abe..d287104204 100644 --- a/indra/llaudio/llaudioengine.h +++ b/indra/llaudio/llaudioengine.h @@ -91,6 +91,15 @@ public:  		AUDIO_TYPE_COUNT   = 4 // last  	}; +	enum LLAudioPlayState +	{ +		// isInternetStreamPlaying() returns an *int*, with +		// 0 = stopped, 1 = playing, 2 = paused. +		AUDIO_STOPPED = 0, +		AUDIO_PLAYING = 1, +		AUDIO_PAUSED = 2 +	}; +	  	LLAudioEngine();  	virtual ~LLAudioEngine(); @@ -156,7 +165,7 @@ public:  	void stopInternetStream();  	void pauseInternetStream(int pause);  	void updateInternetStream(); // expected to be called often -	int isInternetStreamPlaying(); +	LLAudioPlayState isInternetStreamPlaying();  	// use a value from 0.0 to 1.0, inclusive  	void setInternetStreamGain(F32 vol);  	std::string getInternetStreamURL(); diff --git a/indra/llui/lldockcontrol.cpp b/indra/llui/lldockcontrol.cpp index d836a5f4cd..d738b10130 100644 --- a/indra/llui/lldockcontrol.cpp +++ b/indra/llui/lldockcontrol.cpp @@ -162,7 +162,9 @@ bool LLDockControl::isDockVisible()  			{  			case LEFT: // to keep compiler happy  				break; +			case BOTTOM:  			case TOP: +			{  				// check is dock inside parent rect  				LLRect dockParentRect =  						mDockWidget->getParent()->calcScreenRect(); @@ -173,6 +175,9 @@ bool LLDockControl::isDockVisible()  				}  				break;  			} +			default: +				break; +			}  		}  	} @@ -255,6 +260,42 @@ void LLDockControl::moveDockable()  		mDockTongueY = dockRect.mTop;  		break; +	case BOTTOM: +		x = dockRect.getCenterX() - dockableRect.getWidth() / 2; +		y = dockRect.mBottom; +		// unique docking used with dock tongue, so add tongue height o the Y coordinate +		if (use_tongue) +		{ +			y -= mDockTongue->getHeight(); +		} + +		// check is dockable inside root view rect +		if (x < rootRect.mLeft) +		{ +			x = rootRect.mLeft; +		} +		if (x + dockableRect.getWidth() > rootRect.mRight) +		{ +			x = rootRect.mRight - dockableRect.getWidth(); +		} + +		// calculate dock tongue position +		dockParentRect = mDockWidget->getParent()->calcScreenRect(); +		if (dockRect.getCenterX() < dockParentRect.mLeft) +		{ +			mDockTongueX = dockParentRect.mLeft - mDockTongue->getWidth() / 2; +		} +		else if (dockRect.getCenterX() > dockParentRect.mRight) +		{ +			mDockTongueX = dockParentRect.mRight - mDockTongue->getWidth() / 2;; +		} +		else +		{ +			mDockTongueX = dockRect.getCenterX() - mDockTongue->getWidth() / 2; +		} +		mDockTongueY = dockRect.mBottom - mDockTongue->getHeight(); + +		break;  	}  	// move dockable diff --git a/indra/llui/lldockcontrol.h b/indra/llui/lldockcontrol.h index 550955c4c5..a5caf68001 100644 --- a/indra/llui/lldockcontrol.h +++ b/indra/llui/lldockcontrol.h @@ -47,8 +47,9 @@ class LLDockControl  public:  	enum DocAt  	{ -		TOP -		,LEFT +		TOP, +		LEFT, +		BOTTOM  	};  public: diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index 478e270c98..ac4811210b 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -1388,6 +1388,8 @@ void LLScrollListCtrl::drawItems()  	LLGLSUIDefault gls_ui; +	F32 alpha = getDrawContext().mAlpha; +  	{  		LLLocalClipRect clip(mItemListRect); @@ -1463,7 +1465,7 @@ void LLScrollListCtrl::drawItems()  					bg_color = mBgReadOnlyColor.get();  				} -				item->draw(item_rect, fg_color, bg_color, highlight_color, mColumnPadding); +				item->draw(item_rect, fg_color % alpha, bg_color% alpha, highlight_color % alpha, mColumnPadding);  				cur_y -= mLineHeight;  			} diff --git a/indra/llui/lltooltip.cpp b/indra/llui/lltooltip.cpp index 173fde8e76..ed7fd02e14 100644 --- a/indra/llui/lltooltip.cpp +++ b/indra/llui/lltooltip.cpp @@ -129,12 +129,6 @@ BOOL LLToolTipView::handleScrollWheel( S32 x, S32 y, S32 clicks )  	return FALSE;  } -void LLToolTipView::onMouseLeave(S32 x, S32 y, MASK mask) -{ -	LLToolTipMgr::instance().blockToolTips(); -} - -  void LLToolTipView::drawStickyRect()  {  	gl_rect_2d(LLToolTipMgr::instance().getMouseNearRect(), LLColor4::white, false); diff --git a/indra/llui/lltooltip.h b/indra/llui/lltooltip.h index c0811c56c3..24e32b9b24 100644 --- a/indra/llui/lltooltip.h +++ b/indra/llui/lltooltip.h @@ -56,8 +56,6 @@ public:  	/*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);  	/*virtual*/ BOOL handleScrollWheel( S32 x, S32 y, S32 clicks ); -	/*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask); -  	void drawStickyRect();  	/*virtual*/ void draw(); diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index b74530e49a..6634fe5379 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -183,7 +183,6 @@ set(viewer_SOURCE_FILES      llfloatermediasettings.cpp      llfloatermemleak.cpp      llfloaternamedesc.cpp -    llfloaternearbymedia.cpp      llfloaternotificationsconsole.cpp      llfloateropenobject.cpp      llfloaterparcel.cpp @@ -323,6 +322,7 @@ set(viewer_SOURCE_FILES      llpanelmediasettingspermissions.cpp      llpanelmediasettingssecurity.cpp      llpanelme.cpp +    llpanelnearbymedia.cpp      llpanelobject.cpp      llpanelobjectinventory.cpp      llpaneloutfitsinventory.cpp @@ -683,7 +683,6 @@ set(viewer_HEADER_FILES      llfloatermediasettings.h      llfloatermemleak.h      llfloaternamedesc.h -    llfloaternearbymedia.h      llfloaternotificationsconsole.h      llfloateropenobject.h      llfloaterparcel.h @@ -818,6 +817,7 @@ set(viewer_HEADER_FILES      llpanelmediasettingspermissions.h      llpanelmediasettingssecurity.h      llpanelme.h +    llpanelnearbymedia.h      llpanelobject.h      llpanelobjectinventory.h      llpaneloutfitsinventory.h diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index c0cf8ec1ad..e962ea1815 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -4578,6 +4578,50 @@      <key>Value</key>      <integer>0</integer>    </map> +  <key>MediaShowOnOthers</key> +  <map> +    <key>Comment</key> +    <string>Whether or not to show media on other avatars</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>Boolean</string> +    <key>Value</key> +    <integer>1</integer> +  </map> +  <key>MediaShowOutsideParcel</key> +  <map> +    <key>Comment</key> +    <string>Whether or not to show media from outside the current parcel</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>Boolean</string> +    <key>Value</key> +    <integer>0</integer> +  </map> +  <key>MediaShowWithinParcel</key> +  <map> +    <key>Comment</key> +    <string>Whether or not to show media within the current parcel</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>Boolean</string> +    <key>Value</key> +    <integer>1</integer> +  </map> +  <key>MediaTentativeAutoPlay</key> +  <map> +    <key>Comment</key> +    <string>This is a tentative flag that may be temporarily set off by the user, until she teleports</string> +    <key>Persist</key> +    <integer>0</integer> +    <key>Type</key> +    <string>Boolean</string> +    <key>Value</key> +    <integer>1</integer> +  </map>    <key>MemoryLogFrequency</key>          <map>          <key>Comment</key> diff --git a/indra/newview/llpanelnearbymedia.cpp b/indra/newview/llpanelnearbymedia.cpp new file mode 100644 index 0000000000..6a88c916d7 --- /dev/null +++ b/indra/newview/llpanelnearbymedia.cpp @@ -0,0 +1,1180 @@ +/**  + * @file llpanelnearbymedia.cpp + * @brief Management interface for muting and controlling nearby media + * + * $LicenseInfo:firstyear=2005&license=viewergpl$ + *  + * Copyright (c) 2005-2009, Linden Research, Inc. + *  + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + *  + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + *  + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llpanelnearbymedia.h" + +#include "llaudioengine.h" +#include "llcheckboxctrl.h" +#include "llcombobox.h" +#include "llresizebar.h" +#include "llscrolllistctrl.h" +#include "llscrolllistitem.h" +#include "llscrolllistcell.h" +#include "llslider.h" +#include "llsliderctrl.h" +#include "llagent.h" +#include "llagentui.h" +#include "llbutton.h" +#include "lltextbox.h" +#include "llviewermedia.h" +#include "llviewerparcelmedia.h" +#include "llviewerregion.h" +#include "llviewermediafocus.h" +#include "llviewerparcelmgr.h" +#include "llparcel.h" +#include "llpluginclassmedia.h" +#include "llvovolume.h" +#include "llstatusbar.h" +#include "llsdutil.h" + +#include "llfloaterreg.h" +#include "llfloaterpreference.h" // for the gear icon +#include "lltabcontainer.h" + +#include <stringize.h> + +extern LLControlGroup gSavedSettings; + +static const LLUUID PARCEL_MEDIA_LIST_ITEM_UUID = LLUUID("CAB5920F-E484-4233-8621-384CF373A321"); +static const LLUUID PARCEL_AUDIO_LIST_ITEM_UUID = LLUUID("DF4B020D-8A24-4B95-AB5D-CA970D694822"); + +// +// LLPanelNearByMedia +// + +LLPanelNearByMedia::LLPanelNearByMedia() +:	mMediaList(NULL), +	  mEnableAllCtrl(NULL), +	  mAllMediaDisabled(false), +	  mDebugInfoVisible(false), +	  mParcelMediaItem(NULL), +	  mParcelAudioItem(NULL) +{ +	mParcelAudioAutoStart = gSavedSettings.getBOOL(LLViewerMedia::AUTO_PLAY_MEDIA_SETTING) && +							gSavedSettings.getBOOL("MediaTentativeAutoPlay"); + +	mCommitCallbackRegistrar.add("MediaListCtrl.EnableAll",		boost::bind(&LLPanelNearByMedia::onClickEnableAll, this)); +	mCommitCallbackRegistrar.add("MediaListCtrl.DisableAll",		boost::bind(&LLPanelNearByMedia::onClickDisableAll, this)); +	mCommitCallbackRegistrar.add("MediaListCtrl.GoMediaPrefs", boost::bind(&LLPanelNearByMedia::onAdvancedButtonClick, this)); +	mCommitCallbackRegistrar.add("MediaListCtrl.MoreLess", boost::bind(&LLPanelNearByMedia::onMoreLess, this)); +	mCommitCallbackRegistrar.add("SelectedMediaCtrl.Stop",		boost::bind(&LLPanelNearByMedia::onClickSelectedMediaStop, this));	 +	mCommitCallbackRegistrar.add("SelectedMediaCtrl.Play",		boost::bind(&LLPanelNearByMedia::onClickSelectedMediaPlay, this)); +	mCommitCallbackRegistrar.add("SelectedMediaCtrl.Pause",		boost::bind(&LLPanelNearByMedia::onClickSelectedMediaPause, this)); +	mCommitCallbackRegistrar.add("SelectedMediaCtrl.Mute",		boost::bind(&LLPanelNearByMedia::onClickSelectedMediaMute, this)); +	mCommitCallbackRegistrar.add("SelectedMediaCtrl.Volume",	boost::bind(&LLPanelNearByMedia::onCommitSelectedMediaVolume, this)); +	mCommitCallbackRegistrar.add("SelectedMediaCtrl.Zoom",		boost::bind(&LLPanelNearByMedia::onClickSelectedMediaZoom, this)); +	mCommitCallbackRegistrar.add("SelectedMediaCtrl.Unzoom",	boost::bind(&LLPanelNearByMedia::onClickSelectedMediaUnzoom, this)); +	 +	LLUICtrlFactory::instance().buildPanel(this, "panel_nearby_media.xml"); +} + +LLPanelNearByMedia::~LLPanelNearByMedia() +{ +} + +BOOL LLPanelNearByMedia::postBuild() +{ +	LLPanel::postBuild(); + +	const S32 RESIZE_BAR_THICKNESS = 6; +	LLResizeBar::Params p; +	p.rect = LLRect(0, RESIZE_BAR_THICKNESS, getRect().getWidth(), 0); +	p.name = "resizebar_bottom"; +	p.min_size = getRect().getHeight(); +	p.side = LLResizeBar::BOTTOM; +	p.resizing_view = this; +	addChild( LLUICtrlFactory::create<LLResizeBar>(p) ); + +	mNearbyMediaPanel = getChild<LLUICtrl>("nearby_media_panel"); +	mMediaList = getChild<LLScrollListCtrl>("media_list"); +	mEnableAllCtrl = getChild<LLUICtrl>("all_nearby_media_enable_btn"); +	mDisableAllCtrl = getChild<LLUICtrl>("all_nearby_media_disable_btn"); +	mItemCountText = getChild<LLTextBox>("media_item_count"); +	mShowCtrl = getChild<LLComboBox>("show_combo"); + +	// Dynamic (selection-dependent) controls +	mStopCtrl = getChild<LLUICtrl>("stop"); +	mPlayCtrl = getChild<LLUICtrl>("play"); +	mPauseCtrl = getChild<LLUICtrl>("pause"); +	mMuteCtrl = getChild<LLUICtrl>("mute"); +	mVolumeSliderCtrl = getChild<LLUICtrl>("volume_slider_ctrl"); +	mZoomCtrl = getChild<LLUICtrl>("zoom"); +	mUnzoomCtrl = getChild<LLUICtrl>("unzoom"); +	mVolumeSlider = getChild<LLSlider>("volume_slider"); +	mMuteBtn = getChild<LLButton>("mute_btn"); +	 +	mEmptyNameString = getString("empty_item_text"); +	mParcelMediaName = getString("parcel_media_name"); +	mParcelAudioName = getString("parcel_audio_name"); +	mPlayingString = getString("playing_suffix"); +	 +	mMediaList->setDoubleClickCallback(onZoomMedia, this); +	mMediaList->sortByColumnIndex(PROXIMITY_COLUMN, TRUE); +	mMediaList->sortByColumnIndex(VISIBILITY_COLUMN, FALSE); +	 +	refreshList(); +	updateControls(); +	updateColumns(); +	 +	LLView* minimized_controls = getChildView("minimized_controls"); +	mMoreHeight = getRect().getHeight(); +	mLessHeight = getRect().getHeight() - minimized_controls->getRect().mBottom; +	getChild<LLUICtrl>("more_less_btn")->setValue(false); +	onMoreLess(); +	 +	return TRUE; +} + +/*virtual*/ +void LLPanelNearByMedia::onMouseEnter(S32 x, S32 y, MASK mask) +{ +	mHoverTimer.stop(); +	LLPanel::onMouseEnter(x,y,mask); +} + + +/*virtual*/ +void LLPanelNearByMedia::onMouseLeave(S32 x, S32 y, MASK mask) +{ +	mHoverTimer.start(); +	LLPanel::onMouseLeave(x,y,mask); +} + +/*virtual*/  +void LLPanelNearByMedia::handleVisibilityChange ( BOOL new_visibility ) +{ +	if (new_visibility)	 +	{ +		mHoverTimer.start(); // timer will be stopped when mouse hovers over panel +		//gFocusMgr.setTopCtrl(this); +	} +	else +	{ +		mHoverTimer.stop(); +		//if (gFocusMgr.getTopCtrl() == this) +		//{ +		//	gFocusMgr.setTopCtrl(NULL); +		//} +	} +} + +/*virtual*/  +void LLPanelNearByMedia::onTopLost () +{ +	//LLUICtrl* new_top = gFocusMgr.getTopCtrl(); +	//if (!new_top || !new_top->hasAncestor(this)) +	//{ +	//	setVisible(FALSE); +	//} +} + +/*virtual*/ +void LLPanelNearByMedia::reshape(S32 width, S32 height, BOOL called_from_parent) +{ +	LLPanel::reshape(width, height, called_from_parent); + +	LLButton* more_less_btn = getChild<LLButton>("more_less_btn"); +	if (more_less_btn->getValue().asBoolean()) +	{ +		mMoreHeight = getRect().getHeight(); +	} + +} + +const F32 AUTO_CLOSE_FADE_TIME_START= 4.0f; +const F32 AUTO_CLOSE_FADE_TIME_END = 5.0f; + +void LLPanelNearByMedia::draw() +{ +	//LLUICtrl* new_top = gFocusMgr.getTopCtrl(); +	//if (new_top != this) +	//{ +	//	// reassert top ctrl +	//	gFocusMgr.setTopCtrl(this); +	//} + +	// keep bottom of panel on screen +	LLRect screen_rect = calcScreenRect(); +	if (screen_rect.mBottom < 0) +	{ +		LLRect new_rect = getRect(); +		new_rect.mBottom += 0 - screen_rect.mBottom; +		setShape(new_rect); +	} + +	mItemCountText->setValue(llformat(getString("media_item_count_format").c_str(), mMediaList->getItemCount())); +	 +	refreshList(); +	updateControls(); +	 +	F32 alpha = mHoverTimer.getStarted()  +		? clamp_rescale(mHoverTimer.getElapsedTimeF32(), AUTO_CLOSE_FADE_TIME_START, AUTO_CLOSE_FADE_TIME_END, 1.f, 0.f) +		: 1.0f; +	LLViewDrawContext context(alpha); + +	LLPanel::draw(); + +	if (alpha == 0.f) +	{ +		setVisible(false); +	} +} + +bool LLPanelNearByMedia::getParcelAudioAutoStart() +{ +	return mParcelAudioAutoStart; +} + +LLScrollListItem* LLPanelNearByMedia::addListItem(const LLUUID &id) +{ +	if (NULL == mMediaList) return NULL; +	 +	// Just set up the columns -- the values will be filled in by updateListItem(). +	 +	LLSD row; +	row["id"] = id; +	 +	LLSD &columns = row["columns"]; +	 +	columns[CHECKBOX_COLUMN]["column"] = "media_checkbox_ctrl"; +	columns[CHECKBOX_COLUMN]["type"] = "checkbox";	 +	//if(mDebugInfoVisible) +	{ +	columns[PROXIMITY_COLUMN]["column"] = "media_proximity"; +	columns[PROXIMITY_COLUMN]["value"] = ""; +		columns[VISIBILITY_COLUMN]["column"] = "media_visibility"; +		columns[VISIBILITY_COLUMN]["value"] = ""; +		columns[CLASS_COLUMN]["column"] = "media_class"; +		columns[CLASS_COLUMN]["type"] = "text"; +		columns[CLASS_COLUMN]["value"] = ""; +	} +	columns[NAME_COLUMN]["column"] = "media_name"; +	columns[NAME_COLUMN]["type"] = "text"; +	columns[NAME_COLUMN]["value"] = ""; +	//if(mDebugInfoVisible) +	{ +		columns[DEBUG_COLUMN]["column"] = "media_debug"; +		columns[DEBUG_COLUMN]["type"] = "text"; +		columns[DEBUG_COLUMN]["value"] = ""; +	} +	 +	LLScrollListItem* new_item = mMediaList->addElement(row); +	if (NULL != new_item) +	{ +		LLScrollListCheck* scroll_list_check = dynamic_cast<LLScrollListCheck*>(new_item->getColumn(CHECKBOX_COLUMN)); +		if (scroll_list_check) +		{ +			LLCheckBoxCtrl *check = scroll_list_check->getCheckBox(); +			check->setCommitCallback(boost::bind(&LLPanelNearByMedia::onCheckItem, this, _1, id)); +		} +	}	 +	return new_item; +} + +void LLPanelNearByMedia::updateListItem(LLScrollListItem* item, LLViewerMediaImpl* impl) +{ +	std::string item_name; +	std::string item_tooltip;		 +	std::string debug_str; +	LLPanelNearByMedia::MediaClass media_class = MEDIA_CLASS_ALL; +	 +	getNameAndUrlHelper(impl, item_name, item_tooltip, mEmptyNameString); +	// Focused +	if (impl->hasFocus()) +	{ +		media_class = MEDIA_CLASS_FOCUSED; +	} +	// Is attached to another avatar? +	else if (impl->isAttachedToAnotherAvatar()) +	{ +		media_class = MEDIA_CLASS_ON_OTHERS; +	} +	// Outside agent parcel +	else if (!impl->isInAgentParcel()) +	{ +		media_class = MEDIA_CLASS_OUTSIDE_PARCEL; +	} +	else { +		// inside parcel +		media_class = MEDIA_CLASS_WITHIN_PARCEL; +	} +	 +	if(mDebugInfoVisible) +	{ +		debug_str += llformat("%g/", (float)impl->getInterest()); +		 +		// proximity distance is actually distance squared -- display it as straight distance. +		debug_str += llformat("%g/", fsqrtf(impl->getProximityDistance())); +		 +		//			s += llformat("%g/", (float)impl->getCPUUsage()); +		//			s += llformat("%g/", (float)impl->getApproximateTextureInterest()); +		debug_str += llformat("%g/", (float)(NULL == impl->getSomeObject()) ? 0.0 : impl->getSomeObject()->getPixelArea()); +		 +		debug_str += LLPluginClassMedia::priorityToString(impl->getPriority()); +		 +		if(impl->hasMedia()) +		{ +			debug_str += '@'; +		} +		else if(impl->isPlayable()) +		{ +			debug_str += '+'; +		} +		else if(impl->isForcedUnloaded()) +		{ +			debug_str += '!'; +		} +	} +	 +	updateListItem(item, +				   item_name, +				   item_tooltip, +				   impl->getProximity(), +				   impl->isMediaDisabled(), +				   impl->hasMedia(), +				   impl->isMediaTimeBased() &&	impl->isMediaPlaying(), +				   media_class, +				   debug_str); +} + +void LLPanelNearByMedia::updateListItem(LLScrollListItem* item, +										  const std::string &item_name, +										  const std::string &item_tooltip, +										  S32 proximity, +										  bool is_disabled, +										  bool has_media, +										  bool is_time_based_and_playing, +										  LLPanelNearByMedia::MediaClass media_class, +										  const std::string &debug_str) +{ +	LLScrollListCell* cell = item->getColumn(PROXIMITY_COLUMN); +	if(cell) +	{ +		// since we are forced to sort by text, encode sort order as string +		std::string proximity_string = STRINGIZE(proximity); +		std::string old_proximity_string = cell->getValue().asString(); +		if(proximity_string != old_proximity_string) +		{ +			cell->setValue(proximity_string); +			mMediaList->setNeedsSort(true); +		} +	} +	 +	cell = item->getColumn(CHECKBOX_COLUMN); +	if(cell) +	{ +		cell->setValue(!is_disabled); +	} +	 +	cell = item->getColumn(VISIBILITY_COLUMN); +	if(cell) +	{ +		S32 old_visibility = cell->getValue(); +		// *HACK ALERT: force ordering of Media before Audio before the rest of the list +		S32 new_visibility =  +			item->getUUID() == PARCEL_MEDIA_LIST_ITEM_UUID ? 3 +			: item->getUUID() == PARCEL_AUDIO_LIST_ITEM_UUID ? 2 +			: (has_media) ? 1  +			: ((is_disabled) ? 0 +			: -1); +		cell->setValue(STRINGIZE(new_visibility)); +		if (new_visibility != old_visibility) +		{			 +			mMediaList->setNeedsSort(true); +		} +	} +	 +	cell = item->getColumn(NAME_COLUMN); +	if(cell) +	{ +		std::string name = item_name; +		std::string old_name = cell->getValue().asString(); +		if (has_media)  +		{ +			name += " " + mPlayingString; +		} +		if (name != old_name) +		{ +			cell->setValue(name); +		} +		cell->setToolTip(item_tooltip); +		 +		// *TODO: Make these font styles/colors configurable via XUI +		U8 font_style = LLFontGL::NORMAL; +		LLColor4 cell_color = LLColor4::white; +		 +		// Only colorize by class in debug +		if (mDebugInfoVisible) +		{ +			switch (media_class) { +				case MEDIA_CLASS_FOCUSED: +					cell_color = LLColor4::yellow; +					break; +				case MEDIA_CLASS_ON_OTHERS: +					cell_color = LLColor4::red; +					break; +				case MEDIA_CLASS_OUTSIDE_PARCEL: +					cell_color = LLColor4::orange; +					break; +				case MEDIA_CLASS_WITHIN_PARCEL: +				default: +					break; +			} +		} +		if (is_disabled) +		{ +			if (mDebugInfoVisible) +			{ +				font_style |= LLFontGL::ITALIC; +				cell_color = LLColor4::black; +			} +			else { +				// Dim it if it is disabled +				cell_color.setAlpha(0.25); +			} +		} +		// Dim it if it isn't "showing" +		else if (!has_media) +		{ +			cell_color.setAlpha(0.25); +		} +		// Bold it if it is time-based media and it is playing +		else if (is_time_based_and_playing) +		{ +			if (mDebugInfoVisible) font_style |= LLFontGL::BOLD; +		} +		cell->setColor(cell_color); +		LLScrollListText *text_cell = dynamic_cast<LLScrollListText*> (cell); +		if (text_cell) +		{ +			text_cell->setFontStyle(font_style); +		} +	} +	 +	cell = item->getColumn(CLASS_COLUMN); +	if(cell) +	{ +		// TODO: clean this up! +		cell->setValue(STRINGIZE(media_class)); +	} +	 +	if(mDebugInfoVisible) +	{ +		cell = item->getColumn(DEBUG_COLUMN); +		if(cell) +		{ +			cell->setValue(debug_str); +		} +	} +} +						  +void LLPanelNearByMedia::removeListItem(const LLUUID &id) +{ +	if (NULL == mMediaList) return; +	 +	mMediaList->deleteSingleItem(mMediaList->getItemIndex(id)); +} + +void LLPanelNearByMedia::refreshParcelItems() +{ +	// +	// First add/remove the "fake" items Parcel Media and Parcel Audio. +	// These items will have special UUIDs  +	//    PARCEL_MEDIA_LIST_ITEM_UUID +	//    PARCEL_AUDIO_LIST_ITEM_UUID +	// +	// Get the filter choice. +	const LLSD &choice_llsd = mShowCtrl->getSelectedValue(); +	MediaClass choice = (MediaClass)choice_llsd.asInteger(); +	// Only show "special parcel items" if "All" or "Within" filter +	bool should_include = choice == MEDIA_CLASS_ALL || choice == MEDIA_CLASS_WITHIN_PARCEL; +	 +	// First Parcel Media: add or remove it as necessary +	if (should_include && LLViewerMedia::hasParcelMedia()) +	{ +		// Yes, there is parcel media. +		if (NULL == mParcelMediaItem) +		{ +			mParcelMediaItem = addListItem(PARCEL_MEDIA_LIST_ITEM_UUID); +			mMediaList->setNeedsSort(true); +		} +	} +	else { +		if (NULL != mParcelMediaItem) { +			removeListItem(PARCEL_MEDIA_LIST_ITEM_UUID); +			mParcelMediaItem = NULL; +			mMediaList->setNeedsSort(true);	 +		} +	} +	 +	// ... then update it +	if (NULL != mParcelMediaItem) +	{ +		std::string name, url, tooltip; +		getNameAndUrlHelper(LLViewerParcelMedia::getParcelMedia(), name, url, ""); +		if (name.empty() || name == url) +		{ +			tooltip = url; +		} +		else { +			tooltip = name + " : " + url; +		} +		LLViewerMediaImpl *impl = LLViewerParcelMedia::getParcelMedia(); +		updateListItem(mParcelMediaItem, +					   mParcelMediaName, +					   tooltip, +					   -2, // Proximity closer than anything else, before Parcel Audio +					   impl == NULL || impl->isMediaDisabled(), +					   impl != NULL && !LLViewerParcelMedia::getURL().empty(), +					   impl != NULL && impl->isMediaTimeBased() &&	impl->isMediaPlaying(), +					   MEDIA_CLASS_ALL, +					   "parcel media"); +	} +	 +	// Next Parcel Audio: add or remove it as necessary +	if (should_include && LLViewerMedia::hasParcelAudio()) +	{ +		// Yes, there is parcel audio. +		if (NULL == mParcelAudioItem) +		{ +			mParcelAudioItem = addListItem(PARCEL_AUDIO_LIST_ITEM_UUID); +			mMediaList->setNeedsSort(true); +		} +	} +	else { +		if (NULL != mParcelAudioItem) { +			removeListItem(PARCEL_AUDIO_LIST_ITEM_UUID); +			mParcelAudioItem = NULL; +			mMediaList->setNeedsSort(true); +		} +	} +	 +	// ... then update it +	if (NULL != mParcelAudioItem) +	{ +		bool is_playing = LLViewerMedia::isParcelAudioPlaying(); +		updateListItem(mParcelAudioItem, +					   mParcelAudioName, +					   LLViewerMedia::getParcelAudioURL(), +					   -1, // Proximity after Parcel Media, but closer than anything else +					   !is_playing, +					   is_playing, +					   is_playing, +					   MEDIA_CLASS_ALL, +					   "parcel audio"); +	} +} + +void LLPanelNearByMedia::refreshList() +{ +	bool all_items_deleted = false; +		 +	if(!mMediaList) +	{ +		// None of this makes any sense if the media list isn't there. +		return; +	} +	 +	// Check whether the debug column has been shown/hidden. +	bool debug_info_visible = gSavedSettings.getBOOL("MediaPerformanceManagerDebug"); +	if(debug_info_visible != mDebugInfoVisible) +	{ +		mDebugInfoVisible = debug_info_visible; + +		// Clear all items so the list gets regenerated. +		mMediaList->deleteAllItems(); +		all_items_deleted = true; +		 +		updateColumns(); +	} +	 +	refreshParcelItems(); +	 +	// Get the canonical list from LLViewerMedia +	LLViewerMedia::impl_list impls = LLViewerMedia::getPriorityList(); +	LLViewerMedia::impl_list::iterator priority_iter; +	 +	U32 enabled_count = 0; +	U32 disabled_count = 0; +	 +	// iterate over the impl list, creating rows as necessary. +	for(priority_iter = impls.begin(); priority_iter != impls.end(); priority_iter++) +	{ +		LLViewerMediaImpl *impl = *priority_iter; +		 +		// If we just emptied out the list, every flag needs to be reset. +		if(all_items_deleted) +		{ +			impl->setInNearbyMediaList(false); +		} + +		if (!impl->isParcelMedia()) +		{ +			LLUUID media_id = impl->getMediaTextureID(); +			S32 proximity = impl->getProximity(); +			// This is expensive (i.e. a linear search) -- don't use it here.  We now use mInNearbyMediaList instead. +			//S32 index = mMediaList->getItemIndex(media_id); +			if (proximity < 0 || !shouldShow(impl)) +			{ +				if (impl->getInNearbyMediaList()) +				{ +					// There's a row for this impl -- remove it. +					removeListItem(media_id); +					impl->setInNearbyMediaList(false); +				} +			} +			else +			{ +				if (!impl->getInNearbyMediaList()) +				{ +					// We don't have a row for this impl -- add one. +					addListItem(media_id); +					impl->setInNearbyMediaList(true); +				} +			} +			// Update counts +			if (impl->isMediaDisabled()) +			{ +				disabled_count++; +			} +			else { +				enabled_count++; +		} +	} +	}	 +	mDisableAllCtrl->setEnabled(LLViewerMedia::isAnyMediaShowing() ||  +								LLViewerMedia::isParcelMediaPlaying() || +								LLViewerMedia::isParcelAudioPlaying()); +	mEnableAllCtrl->setEnabled(disabled_count > 0 || +							   // parcel media (if we have it, and it isn't playing, enable "start") +							   (LLViewerMedia::hasParcelMedia() && ! LLViewerMedia::isParcelMediaPlaying()) || +							   // parcel audio (if we have it, and it isn't playing, enable "start") +							   (LLViewerMedia::hasParcelAudio() && ! LLViewerMedia::isParcelAudioPlaying())); + +	// Iterate over the rows in the control, updating ones whose impl exists, and deleting ones whose impl has gone away. +	std::vector<LLScrollListItem*> items = mMediaList->getAllData(); + +	for (std::vector<LLScrollListItem*>::iterator item_it = items.begin(); +		item_it != items.end(); +		++item_it) +	{ +		LLScrollListItem* item = (*item_it); +		LLUUID row_id = item->getUUID(); +		 +		if (row_id != PARCEL_MEDIA_LIST_ITEM_UUID && +			row_id != PARCEL_AUDIO_LIST_ITEM_UUID) +		{ +			LLViewerMediaImpl* impl = LLViewerMedia::getMediaImplFromTextureID(row_id); +			if(impl) +			{ +				updateListItem(item, impl); +			} +			else +			{ +				// This item's impl has been deleted -- remove the row. +				// Removing the row won't throw off our iteration, since we have a local copy of the array. +				// We just need to make sure we don't access this item after the delete. +				removeListItem(row_id); +			} +		} +	} +	 +	// Set the selection to whatever media impl the media focus/hover is on.  +	// This is an experiment, and can be removed by ifdefing out these 4 lines. +	LLUUID media_target = LLViewerMediaFocus::getInstance()->getControlsMediaID(); +	if(media_target.notNull()) +	{ +		mMediaList->selectByID(media_target); +	} +} + +void LLPanelNearByMedia::updateColumns() +{ +	if (!mDebugInfoVisible) +	{ +		if (mMediaList->getColumn(CHECKBOX_COLUMN)) mMediaList->getColumn(VISIBILITY_COLUMN)->setWidth(-1); +		if (mMediaList->getColumn(VISIBILITY_COLUMN)) mMediaList->getColumn(VISIBILITY_COLUMN)->setWidth(-1); +		if (mMediaList->getColumn(PROXIMITY_COLUMN)) mMediaList->getColumn(PROXIMITY_COLUMN)->setWidth(-1); +		if (mMediaList->getColumn(CLASS_COLUMN)) mMediaList->getColumn(CLASS_COLUMN)->setWidth(-1); +		if (mMediaList->getColumn(DEBUG_COLUMN)) mMediaList->getColumn(DEBUG_COLUMN)->setWidth(-1); +	} +	else { +		if (mMediaList->getColumn(CHECKBOX_COLUMN)) mMediaList->getColumn(VISIBILITY_COLUMN)->setWidth(20); +		if (mMediaList->getColumn(VISIBILITY_COLUMN)) mMediaList->getColumn(VISIBILITY_COLUMN)->setWidth(20); +		if (mMediaList->getColumn(PROXIMITY_COLUMN)) mMediaList->getColumn(PROXIMITY_COLUMN)->setWidth(30); +		if (mMediaList->getColumn(CLASS_COLUMN)) mMediaList->getColumn(CLASS_COLUMN)->setWidth(20); +		if (mMediaList->getColumn(DEBUG_COLUMN)) mMediaList->getColumn(DEBUG_COLUMN)->setWidth(200); +	} +} + +void LLPanelNearByMedia::onClickEnableAll() +{ +	LLViewerMedia::setAllMediaEnabled(true); +} + +void LLPanelNearByMedia::onClickDisableAll() +{ +	LLViewerMedia::setAllMediaEnabled(false); +} + +void LLPanelNearByMedia::onClickEnableParcelMedia() +{	 +	if ( ! LLViewerMedia::isParcelMediaPlaying() ) +	{ +		LLViewerParcelMedia::play(LLViewerParcelMgr::getInstance()->getAgentParcel()); +	} +} + +void LLPanelNearByMedia::onClickDisableParcelMedia() +{	 +	// This actually unloads the impl, as opposed to "stop"ping the media +	LLViewerParcelMedia::stop(); +} + +void LLPanelNearByMedia::onCheckItem(LLUICtrl* ctrl, const LLUUID &row_id) +{	 +	LLCheckBoxCtrl* check = static_cast<LLCheckBoxCtrl*>(ctrl); + +	setDisabled(row_id, ! check->getValue()); +} + +bool LLPanelNearByMedia::setDisabled(const LLUUID &row_id, bool disabled) +{ +	if (row_id == PARCEL_AUDIO_LIST_ITEM_UUID) +	{ +		if (disabled) onClickParcelAudioStop(); +		else onClickParcelAudioStart(); +		return true; +	} +	else if (row_id == PARCEL_MEDIA_LIST_ITEM_UUID) +	{ +		if (disabled) onClickDisableParcelMedia(); +		else onClickEnableParcelMedia(); +		return true; +	} +	else { +		LLViewerMediaImpl* impl = LLViewerMedia::getMediaImplFromTextureID(row_id); +		if(impl) +		{ +			impl->setDisabled(disabled, true); +			return true; +		} +	} +	return false; +} +								 +//static +void LLPanelNearByMedia::onZoomMedia(void* user_data) +{ +	LLPanelNearByMedia* panelp = (LLPanelNearByMedia*)user_data; +	LLUUID media_id = panelp->mMediaList->getValue().asUUID(); +	 +	LLViewerMediaFocus::getInstance()->focusZoomOnMedia(media_id); +} + +void LLPanelNearByMedia::onClickParcelMediaPlay() +{ +	LLViewerParcelMedia::play(LLViewerParcelMgr::getInstance()->getAgentParcel()); +} + +void LLPanelNearByMedia::onClickParcelMediaStop() +{	 +	if (LLViewerParcelMedia::getParcelMedia()) +	{ +		// This stops the media playing, as opposed to unloading it like +		// LLViewerParcelMedia::stop() does +		LLViewerParcelMedia::getParcelMedia()->stop(); +	} +} + +void LLPanelNearByMedia::onClickParcelMediaPause() +{ +	LLViewerParcelMedia::pause(); +} + +void LLPanelNearByMedia::onClickParcelAudioStart() +{ +	// User *explicitly* started the internet stream, so keep the stream +	// playing and updated as they cross to other parcels etc. +	mParcelAudioAutoStart = true; +	 +	if (!gAudiop) +		return; +	 +	gAudiop->startInternetStream(LLViewerMedia::getParcelAudioURL()); +} + +void LLPanelNearByMedia::onClickParcelAudioPlay() +{ +	// User *explicitly* started the internet stream, so keep the stream +	// playing and updated as they cross to other parcels etc. +	mParcelAudioAutoStart = true; + +	if (!gAudiop) +		return; + +	if (LLAudioEngine::AUDIO_PAUSED == gAudiop->isInternetStreamPlaying()) +	{ +		// 'false' means unpause +		gAudiop->pauseInternetStream(false); +	} +	else { +		gAudiop->startInternetStream(LLViewerMedia::getParcelAudioURL()); +	} +} + +void LLPanelNearByMedia::onClickParcelAudioStop() +{ +	// User *explicitly* stopped the internet stream, so don't +	// re-start audio when i.e. they move to another parcel, until +	// they explicitly start it again. +	mParcelAudioAutoStart = false; + +	if (!gAudiop) +		return; + +	gAudiop->stopInternetStream(); +} + +void LLPanelNearByMedia::onClickParcelAudioPause() +{ +	if (!gAudiop) +		return; + +	// 'true' means pause +	gAudiop->pauseInternetStream(true); +} + +bool LLPanelNearByMedia::shouldShow(LLViewerMediaImpl* impl) +{	 +	const LLSD &choice_llsd = mShowCtrl->getSelectedValue(); +	MediaClass choice = (MediaClass)choice_llsd.asInteger(); + +	switch (choice) +	{	 +		case MEDIA_CLASS_ALL: +			return true; +			break; +		case MEDIA_CLASS_WITHIN_PARCEL: +			return impl->isInAgentParcel(); +			break; +		case MEDIA_CLASS_OUTSIDE_PARCEL: +			return ! impl->isInAgentParcel(); +			break; +		case MEDIA_CLASS_ON_OTHERS: +			return impl->isAttachedToAnotherAvatar(); +			break; +		default: +			break; +	} +	return true; +} + +void LLPanelNearByMedia::onAdvancedButtonClick() +{	 +	// bring up the prefs floater +	LLFloaterPreference* prefsfloater = dynamic_cast<LLFloaterPreference*>(LLFloaterReg::showInstance("preferences")); +	if (prefsfloater) +	{ +		// grab the 'audio' panel from the preferences floater and +		// bring it the front! +		LLTabContainer* tabcontainer = prefsfloater->getChild<LLTabContainer>("pref core"); +		LLPanel* audiopanel = prefsfloater->getChild<LLPanel>("audio"); +		if (tabcontainer && audiopanel) +		{ +			tabcontainer->selectTabPanel(audiopanel); +		} +	} +} + +void LLPanelNearByMedia::onMoreLess() +{ +	bool is_more = getChild<LLUICtrl>("more_less_btn")->getValue(); +	mNearbyMediaPanel->setVisible(is_more); + +	// enable resizing when expanded +	getChildView("resizebar_bottom")->setEnabled(is_more); + +	S32 new_height = is_more ? mMoreHeight : mLessHeight; + +	LLRect new_rect = getRect(); +	new_rect.mBottom = new_rect.mTop - new_height; + +	setShape(new_rect); +} + +void LLPanelNearByMedia::updateControls() +{ +	LLUUID selected_media_id = mMediaList->getValue().asUUID(); +	 +	if (selected_media_id == PARCEL_AUDIO_LIST_ITEM_UUID) +	{ +		showTimeBasedControls(LLViewerMedia::isParcelAudioPlaying(), +							  false, // include_zoom +							  false, // is_zoomed +							  gSavedSettings.getBOOL("MuteMusic"),  +							  gSavedSettings.getF32("AudioLevelMusic") ); +	} +	else if (selected_media_id == PARCEL_MEDIA_LIST_ITEM_UUID) +	{ +		if (!LLViewerMedia::hasParcelMedia()) +		{ +			// Shouldn't happen, but do this anyway +			showDisabledControls(); +		} +		else { +			LLViewerMediaImpl* impl = LLViewerParcelMedia::getParcelMedia(); +			if (NULL == impl) +			{ +				// Just means it hasn't started yet +				showBasicControls(false, false, false); +			} +			else if (impl->isMediaTimeBased()) +			{ +				showTimeBasedControls(impl->isMediaPlaying(),  +									  false, // include_zoom +									  false, // is_zoomed +									  impl->getVolume() == 0.0, +									  impl->getVolume() ); +			} +			else { +				// non-time-based parcel media +				showBasicControls(LLViewerMedia::isParcelMediaPlaying(), false, false); +			} +		} +	} +	else { +		LLViewerMediaImpl* impl = LLViewerMedia::getMediaImplFromTextureID(selected_media_id); +		 +		if (NULL == impl) +		{ +			showDisabledControls(); +		} +		else { +			if (impl->isMediaTimeBased()) +			{ +				showTimeBasedControls(impl->isMediaPlaying(),  +									  ! impl->isParcelMedia(),  // include_zoom +									  LLViewerMediaFocus::getInstance()->isZoomed(), +									  impl->getVolume() == 0.0, +									  impl->getVolume()); +			} +			else { +				showBasicControls(!impl->isMediaDisabled(),  +								  ! impl->isParcelMedia(),  // include_zoom +								  LLViewerMediaFocus::getInstance()->isZoomed()); +			} +		} +	} +} + +void LLPanelNearByMedia::showBasicControls(bool playing, bool include_zoom, bool is_zoomed) +{ +	mStopCtrl->setVisible(playing); +	mPlayCtrl->setVisible(!playing); +	mPauseCtrl->setVisible(false); +	mMuteCtrl->setVisible(false); +	mVolumeSliderCtrl->setVisible(false); +	mZoomCtrl->setVisible(include_zoom && !is_zoomed); +	mUnzoomCtrl->setVisible(include_zoom && is_zoomed);	 +	mStopCtrl->setEnabled(true); +	mZoomCtrl->setEnabled(true); +} + +void LLPanelNearByMedia::showTimeBasedControls(bool playing, bool include_zoom, bool is_zoomed, bool muted, F32 volume) +{ +	mStopCtrl->setVisible(true); +	mPlayCtrl->setVisible(!playing); +	mPauseCtrl->setVisible(playing); +	mMuteCtrl->setVisible(true); +	mVolumeSliderCtrl->setVisible(true); +	mZoomCtrl->setVisible(include_zoom); +	mZoomCtrl->setVisible(include_zoom && !is_zoomed); +	mUnzoomCtrl->setVisible(include_zoom && is_zoomed);	 +	mStopCtrl->setEnabled(true); +	mZoomCtrl->setEnabled(true); +	mMuteBtn->setValue(muted); +	mVolumeSlider->setValue(volume); +} + +void LLPanelNearByMedia::showDisabledControls() +{ +	mStopCtrl->setVisible(true); +	mPlayCtrl->setVisible(false); +	mPauseCtrl->setVisible(false); +	mMuteCtrl->setVisible(false); +	mVolumeSliderCtrl->setVisible(false); +	mZoomCtrl->setVisible(true); +	mUnzoomCtrl->setVisible(false);	 +	mStopCtrl->setEnabled(false); +	mZoomCtrl->setEnabled(false); +} + +void LLPanelNearByMedia::onClickSelectedMediaStop() +{ +	setDisabled(mMediaList->getValue().asUUID(), true); +} + +void LLPanelNearByMedia::onClickSelectedMediaPlay() +{ +	LLUUID selected_media_id = mMediaList->getValue().asUUID(); +	 +	// First enable it +	setDisabled(selected_media_id, false); +	 +	// Special code to make play "unpause" if time-based and playing +	if (selected_media_id != PARCEL_AUDIO_LIST_ITEM_UUID) +	{ +		LLViewerMediaImpl *impl = (selected_media_id == PARCEL_MEDIA_LIST_ITEM_UUID) ? +			((LLViewerMediaImpl*)LLViewerParcelMedia::getParcelMedia()) : LLViewerMedia::getMediaImplFromTextureID(selected_media_id); +		if (NULL != impl && impl->isMediaTimeBased() && impl->isMediaPaused()) +		{ +			// Aha!  It's really time-based media that's paused, so unpause +			impl->play(); +			return; +		} +		else if (impl->isParcelMedia()) +		{ +			LLViewerParcelMedia::play(LLViewerParcelMgr::getInstance()->getAgentParcel()); +		} +	}	 +} + +void LLPanelNearByMedia::onClickSelectedMediaPause() +{ +	LLUUID selected_media_id = mMediaList->getValue().asUUID(); +	if (selected_media_id == PARCEL_AUDIO_LIST_ITEM_UUID) +	{ +		onClickParcelAudioPause(); +	} +	else if (selected_media_id == PARCEL_MEDIA_LIST_ITEM_UUID)  +	{ +		onClickParcelMediaPause(); +	} +	else { +		LLViewerMediaImpl* impl = LLViewerMedia::getMediaImplFromTextureID(selected_media_id); +		if (NULL != impl && impl->isMediaTimeBased() && impl->isMediaPlaying()) +		{ +			impl->pause(); +		} +	} +} + +void LLPanelNearByMedia::onClickSelectedMediaMute() +{ +	LLUUID selected_media_id = mMediaList->getValue().asUUID(); +	if (selected_media_id == PARCEL_AUDIO_LIST_ITEM_UUID) +	{ +		gSavedSettings.setBOOL("MuteMusic", mMuteBtn->getValue()); +	} +	else { +		LLViewerMediaImpl* impl = (selected_media_id == PARCEL_MEDIA_LIST_ITEM_UUID) ? +			((LLViewerMediaImpl*)LLViewerParcelMedia::getParcelMedia()) : LLViewerMedia::getMediaImplFromTextureID(selected_media_id); +		if (NULL != impl && impl->isMediaTimeBased()) +		{ +			F32 volume = impl->getVolume(); +			if(volume > 0.0) +			{ +				impl->setVolume(0.0); +			} +			else if (mVolumeSlider->getValueF32() == 0.0) +			{ +				impl->setVolume(1.0); +				mVolumeSlider->setValue(1.0); +			} +			else  +			{ +				impl->setVolume(mVolumeSlider->getValueF32()); +			} +		} +	} +} + +void LLPanelNearByMedia::onCommitSelectedMediaVolume() +{ +	LLUUID selected_media_id = mMediaList->getValue().asUUID(); +	if (selected_media_id == PARCEL_AUDIO_LIST_ITEM_UUID) +	{ +		F32 vol = mVolumeSlider->getValueF32(); +		gSavedSettings.setF32("AudioLevelMusic", vol); +	} +	else { +		LLViewerMediaImpl* impl = (selected_media_id == PARCEL_MEDIA_LIST_ITEM_UUID) ? +			((LLViewerMediaImpl*)LLViewerParcelMedia::getParcelMedia()) : LLViewerMedia::getMediaImplFromTextureID(selected_media_id); +		if (NULL != impl && impl->isMediaTimeBased()) +		{ +			impl->setVolume(mVolumeSlider->getValueF32()); +		} +	} +} + +void LLPanelNearByMedia::onClickSelectedMediaZoom() +{ +	LLUUID selected_media_id = mMediaList->getValue().asUUID(); +	if (selected_media_id == PARCEL_AUDIO_LIST_ITEM_UUID || selected_media_id == PARCEL_MEDIA_LIST_ITEM_UUID) +		return; +	LLViewerMediaFocus::getInstance()->focusZoomOnMedia(selected_media_id); +} + +void LLPanelNearByMedia::onClickSelectedMediaUnzoom() +{ +	LLViewerMediaFocus::getInstance()->unZoom(); +} + + +// static +void LLPanelNearByMedia::getNameAndUrlHelper(LLViewerMediaImpl* impl, std::string& name, std::string & url, const std::string &defaultName) +{ +	if (NULL == impl) return; +	 +	name = impl->getName(); +	url = impl->getCurrentMediaURL();	// This is the URL the media impl actually has loaded +	if (url.empty()) +	{ +		url = impl->getMediaEntryURL();	// This is the current URL from the media data +	} +	if (url.empty()) +	{ +		url = impl->getHomeURL();		// This is the home URL from the media data +	} +	if (name.empty()) +	{ +		name = url; +	} +	if (name.empty()) +	{ +		name = defaultName; +	} +} + diff --git a/indra/newview/llpanelnearbymedia.h b/indra/newview/llpanelnearbymedia.h new file mode 100644 index 0000000000..eedfd447de --- /dev/null +++ b/indra/newview/llpanelnearbymedia.h @@ -0,0 +1,185 @@ +/**  + * @file llpanelnearbymedia.h + * @brief Management interface for muting and controlling nearby media + * + * $LicenseInfo:firstyear=2005&license=viewergpl$ + *  + * Copyright (c) 2005-2009, Linden Research, Inc. + *  + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + *  + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + *  + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLPANELNEARBYMEDIA_H +#define LL_LLPANELNEARBYMEDIA_H + +#include "llpanel.h" + +class LLPanelNearbyMedia; +class LLButton; +class LLScrollListCtrl; +class LLSlider; +class LLSliderCtrl; +class LLCheckBoxCtrl; +class LLTextBox; +class LLComboBox; +class LLViewerMediaImpl; + +class LLPanelNearByMedia : public LLPanel +{ +public: +	 +	/*virtual*/ BOOL postBuild(); +	/*virtual*/ void draw(); +	/*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask); +	/*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask); +	/*virtual*/ void handleVisibilityChange ( BOOL new_visibility ); +	/*virtual*/ void onTopLost (); +	/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent); + +	// this is part of the nearby media *dialog* so we can track whether +	// the user *implicitly* wants audio on or off via their *explicit* +	// interaction with our buttons. +	bool getParcelAudioAutoStart(); + +	LLPanelNearByMedia(); +	virtual ~LLPanelNearByMedia(); + +private: +	 +	enum ColumnIndex { +		CHECKBOX_COLUMN = 0, +		PROXIMITY_COLUMN = 1, +		VISIBILITY_COLUMN = 2, +		CLASS_COLUMN = 3, +		NAME_COLUMN = 4, +		DEBUG_COLUMN = 5 +	}; +	 +	// Media "class" enumeration +	enum MediaClass { +		MEDIA_CLASS_ALL = 0, +		MEDIA_CLASS_FOCUSED = 1, +		MEDIA_CLASS_WITHIN_PARCEL = 2, +		MEDIA_CLASS_OUTSIDE_PARCEL = 3, +		MEDIA_CLASS_ON_OTHERS = 4 +	}; +		 +	// Add/remove an LLViewerMediaImpl to/from the list +	LLScrollListItem* addListItem(const LLUUID &id); +	void updateListItem(LLScrollListItem* item, LLViewerMediaImpl* impl); +	void updateListItem(LLScrollListItem* item, +						const std::string &item_name, +						const std::string &item_tooltip, +						S32 proximity, +						bool is_disabled, +						bool has_media, +						bool is_time_based_and_playing, +						MediaClass media_class, +						const std::string &debug_str); +	void removeListItem(const LLUUID &id); +	 +	// Refresh the list in the UI +	void refreshList(); +	 +	void refreshParcelItems(); + +	// UI Callbacks  +	void onClickEnableAll(); +	void onClickDisableAll(); +	void onClickEnableParcelMedia(); +	void onClickDisableParcelMedia(); +	void onClickMuteParcelMedia(); +	void onParcelMediaVolumeSlider(); +	void onClickParcelMediaPlay(); +	void onClickParcelMediaStop(); +	void onClickParcelMediaPause(); +	void onClickParcelAudioPlay(); +	void onClickParcelAudioStop(); +	void onClickParcelAudioStart(); +	void onClickParcelAudioPause(); +	void onCheckAutoPlay(); +	void onAdvancedButtonClick();	 +	void onMoreLess();	 +	 +	void onCheckItem(LLUICtrl* ctrl, const LLUUID &row_id); +	 +	static void onZoomMedia(void* user_data); +	 +private: +	bool setDisabled(const LLUUID &id, bool disabled); + +	static void getNameAndUrlHelper(LLViewerMediaImpl* impl, std::string& name, std::string & url, const std::string &defaultName); +	 +	void updateColumns(); +	 +	bool shouldShow(LLViewerMediaImpl* impl); +	 +	void showBasicControls(bool playing, bool include_zoom, bool is_zoomed); +	void showTimeBasedControls(bool playing, bool include_zoom, bool is_zoomed, bool muted, F32 volume); +	void showDisabledControls(); +	void updateControls(); +	 +	void onClickSelectedMediaStop(); +	void onClickSelectedMediaPlay(); +	void onClickSelectedMediaPause(); +	void onClickSelectedMediaMute(); +	void onCommitSelectedMediaVolume(); +	void onClickSelectedMediaZoom(); +	void onClickSelectedMediaUnzoom(); +	 +	LLUICtrl*			mNearbyMediaPanel; +	LLTextBox*			mItemCountText; +	LLScrollListCtrl*		mMediaList; +	LLUICtrl*			mEnableAllCtrl; +	LLUICtrl*			mDisableAllCtrl; +	LLComboBox*			mShowCtrl; +	 +	// Dynamic (selection-dependent) controls +	LLUICtrl*			mStopCtrl; +	LLUICtrl*			mPlayCtrl; +	LLUICtrl*			mPauseCtrl; +	LLUICtrl*			mMuteCtrl; +	LLUICtrl*			mVolumeSliderCtrl; +	LLUICtrl*			mZoomCtrl; +	LLUICtrl*			mUnzoomCtrl; +	LLSlider*			mVolumeSlider; +	LLButton*			mMuteBtn; +	 +	bool				mAllMediaDisabled; +	bool				mDebugInfoVisible; +	bool				mParcelAudioAutoStart; +	std::string			mEmptyNameString; +	std::string			mPlayingString; +	std::string			mParcelMediaName; +	std::string			mParcelAudioName; +	 +	S32				mMoreHeight; +	S32				mLessHeight; +	LLFrameTimer			mHoverTimer; +	LLScrollListItem*		mParcelMediaItem; +	LLScrollListItem*		mParcelAudioItem; +}; + + +#endif // LL_LLPANELNEARBYMEDIA_H diff --git a/indra/newview/llpanelprimmediacontrols.cpp b/indra/newview/llpanelprimmediacontrols.cpp index 479769ee20..a53a3ba1ad 100644 --- a/indra/newview/llpanelprimmediacontrols.cpp +++ b/indra/newview/llpanelprimmediacontrols.cpp @@ -724,10 +724,10 @@ void LLPanelPrimMediaControls::draw()  	mMediaControlsStack->updateLayout();  	// adjust for layout stack spacing -	S32 space = mMediaControlsStack->getPanelSpacing() + 1; +	S32 space = mMediaControlsStack->getPanelSpacing() + 2;  	LLRect controls_bg_area = mMediaControlsStack->getRect(); -	controls_bg_area.mTop += space; +	controls_bg_area.mTop += space + 2;  	// adjust to ignore space from volume slider  	controls_bg_area.mBottom += mVolumeSliderCtrl->getRect().getHeight(); @@ -736,7 +736,7 @@ void LLPanelPrimMediaControls::draw()  	controls_bg_area.mLeft += mLeftBookend->getRect().getWidth() - space;  	// ignore space from right bookend padding -	controls_bg_area.mRight -= mRightBookend->getRect().getWidth() - space; +	controls_bg_area.mRight -= mRightBookend->getRect().getWidth() - space - 2;  	// draw control background UI image  	mBackgroundImage->draw( controls_bg_area, UI_VERTEX_COLOR % alpha); diff --git a/indra/newview/llpanelprimmediacontrols.h b/indra/newview/llpanelprimmediacontrols.h index 743cec70a1..2e0de7866c 100644 --- a/indra/newview/llpanelprimmediacontrols.h +++ b/indra/newview/llpanelprimmediacontrols.h @@ -58,6 +58,16 @@ public:  	void updateShape();  	bool isMouseOver(); +	 +	enum EZoomLevel +	{ +		ZOOM_NONE = 0, +		ZOOM_FAR, +		ZOOM_MEDIUM, +		ZOOM_NEAR +	}; +	 +	EZoomLevel getZoomLevel() const { return mCurrentZoom; }  	void nextZoomLevel();  	void resetZoomLevel(bool reset_camera = true);  	void close(); @@ -66,13 +76,6 @@ public:  	void setMediaFace(LLPointer<LLViewerObject> objectp, S32 face, viewer_media_t media_impl, LLVector3 pick_normal = LLVector3::zero); -	enum EZoomLevel -	{ -		ZOOM_NONE = 0, -		ZOOM_FAR, -		ZOOM_MEDIUM, -		ZOOM_NEAR -	};  	static const EZoomLevel kZoomLevels[];  	static const int kNumZoomLevels; diff --git a/indra/newview/llpanelvolumepulldown.cpp b/indra/newview/llpanelvolumepulldown.cpp index 74e37efe4e..247134ad63 100644 --- a/indra/newview/llpanelvolumepulldown.cpp +++ b/indra/newview/llpanelvolumepulldown.cpp @@ -96,7 +96,10 @@ void LLPanelVolumePulldown::handleVisibilityChange ( BOOL new_visibility )  	else  	{  		mHoverTimer.stop(); -		gFocusMgr.setTopCtrl(NULL); +		if (gFocusMgr.getTopCtrl() == this) +		{ +			gFocusMgr.setTopCtrl(NULL); +		}  	}  } diff --git a/indra/newview/llrootview.h b/indra/newview/llrootview.h index 760b1a7a4c..38029e3a9d 100644 --- a/indra/newview/llrootview.h +++ b/indra/newview/llrootview.h @@ -35,6 +35,7 @@  #include "llview.h"  #include "lluictrlfactory.h" +#include "lltooltip.h"  class LLRootViewRegistry : public LLChildRegistry<LLRootViewRegistry>  {}; diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp index bff32af228..923e1e42fb 100644 --- a/indra/newview/llstatusbar.cpp +++ b/indra/newview/llstatusbar.cpp @@ -41,6 +41,7 @@  #include "llviewercontrol.h"  #include "llfloaterbuycurrency.h"  #include "llfloaterlagmeter.h" +#include "llpanelnearbymedia.h"  #include "llpanelvolumepulldown.h"  #include "llfloaterregioninfo.h"  #include "llfloaterscriptdebug.h" @@ -49,6 +50,7 @@  #include "llkeyboard.h"  #include "lllineeditor.h"  #include "llmenugl.h" +#include "llrootview.h"  #include "llsd.h"  #include "lltextbox.h"  #include "llui.h" @@ -61,6 +63,7 @@  #include "llresmgr.h"  #include "llworld.h"  #include "llstatgraph.h" +#include "llviewermedia.h"  #include "llviewermenu.h"	// for gMenuBarView  #include "llviewerparcelmgr.h"  #include "llviewerthrottle.h" @@ -130,7 +133,6 @@ LLStatusBar::LLStatusBar(const LLRect& rect)  	// status bar can possible overlay menus?  	setMouseOpaque(FALSE); -	setIsChrome(TRUE);  	// size of day of the weeks and year  	sDays.reserve(7); @@ -140,9 +142,39 @@ LLStatusBar::LLStatusBar(const LLRect& rect)  	mHealthTimer = new LLFrameTimer();  	LLUICtrlFactory::getInstance()->buildPanel(this,"panel_status_bar.xml"); +} + +LLStatusBar::~LLStatusBar() +{ +	delete mBalanceTimer; +	mBalanceTimer = NULL; + +	delete mHealthTimer; +	mHealthTimer = NULL; + +	// LLView destructor cleans up children +} + +//----------------------------------------------------------------------- +// Overrides +//----------------------------------------------------------------------- + +// virtual +void LLStatusBar::draw() +{ +	refresh(); +	LLPanel::draw(); +} -	// status bar can never get a tab -	setFocusRoot(FALSE); +BOOL LLStatusBar::handleRightMouseDown(S32 x, S32 y, MASK mask) +{ +	show_navbar_context_menu(this,x,y); +	return TRUE; +} + +BOOL LLStatusBar::postBuild() +{ +	gMenuBarView->setRightMouseDownCallback(boost::bind(&show_navbar_context_menu, _1, _2, _3));  	// build date necessary data (must do after panel built)  	setupDate(); @@ -158,7 +190,10 @@ LLStatusBar::LLStatusBar(const LLRect& rect)  	mBtnVolume = getChild<LLButton>( "volume_btn" );  	mBtnVolume->setClickedCallback( onClickVolume, this );  	mBtnVolume->setMouseEnterCallback(boost::bind(&LLStatusBar::onMouseEnterVolume, this)); -	mBtnVolume->setIsChrome(TRUE); + +	mMediaToggle = getChild<LLButton>("media_toggle_btn"); +	mMediaToggle->setClickedCallback( &LLStatusBar::onClickMediaToggle, this ); +	mMediaToggle->setMouseEnterCallback(boost::bind(&LLStatusBar::onMouseEnterNearbyMedia, this));  	gSavedSettings.getControl("MuteAudio")->getSignal()->connect(boost::bind(&LLStatusBar::onVolumeChanged, this, _2)); @@ -207,6 +242,13 @@ LLStatusBar::LLStatusBar(const LLRect& rect)  	mPanelVolumePulldown = new LLPanelVolumePulldown();  	addChild(mPanelVolumePulldown); +	mPanelNearByMedia = new LLPanelNearByMedia(); +	LLView* popup_holder = gViewerWindow->getRootView()->getChildView("popup_holder"); +	popup_holder->addChild(mPanelNearByMedia); +	gViewerWindow->getRootView()->addMouseDownCallback(boost::bind(&LLStatusBar::onClickScreen, this, _1, _2)); +	mPanelNearByMedia->setFollows(FOLLOWS_TOP|FOLLOWS_RIGHT); +	mPanelNearByMedia->setVisible(FALSE); +  	LLRect volume_pulldown_rect = mPanelVolumePulldown->getRect();  	LLButton* volbtn =  getChild<LLButton>( "volume_btn" );  	volume_pulldown_rect.setLeftTopAndSize(volbtn->getRect().mLeft - @@ -218,39 +260,6 @@ LLStatusBar::LLStatusBar(const LLRect& rect)  	mPanelVolumePulldown->setShape(volume_pulldown_rect);  	mPanelVolumePulldown->setFollows(FOLLOWS_TOP|FOLLOWS_RIGHT);  	mPanelVolumePulldown->setVisible(FALSE); -} - -LLStatusBar::~LLStatusBar() -{ -	delete mBalanceTimer; -	mBalanceTimer = NULL; - -	delete mHealthTimer; -	mHealthTimer = NULL; - -	// LLView destructor cleans up children -} - -//----------------------------------------------------------------------- -// Overrides -//----------------------------------------------------------------------- - -// virtual -void LLStatusBar::draw() -{ -	refresh(); -	LLPanel::draw(); -} - -BOOL LLStatusBar::handleRightMouseDown(S32 x, S32 y, MASK mask) -{ -	show_navbar_context_menu(this,x,y); -	return TRUE; -} - -BOOL LLStatusBar::postBuild() -{ -	gMenuBarView->setRightMouseDownCallback(boost::bind(&show_navbar_context_menu, _1, _2, _3));  	return TRUE;  } @@ -356,6 +365,13 @@ void LLStatusBar::refresh()  	// update the master volume button state  	bool mute_audio = LLAppViewer::instance()->getMasterSystemAudioMute();  	mBtnVolume->setToggleState(mute_audio); +	 +	// Don't show media toggle if there's no media, parcel media, and no parcel audio +	mMediaToggle->setVisible(LLViewerMedia::hasInWorldMedia() || LLViewerMedia::hasParcelMedia() || LLViewerMedia::hasParcelAudio()); +	// Note the "sense" of the toggle is opposite whether media is playing or not +	mMediaToggle->setValue(! (LLViewerMedia::isAnyMediaShowing() ||  +							  LLViewerMedia::isParcelMediaPlaying() || +							  LLViewerMedia::isParcelAudioPlaying()));  }  void LLStatusBar::setVisibleForMouselook(bool visible) @@ -385,8 +401,8 @@ void LLStatusBar::setBalance(S32 balance)  	LLButton* btn_buy_currency = getChild<LLButton>("buycurrency");  	LLStringUtil::format_map_t string_args;  	string_args["[AMT]"] = llformat("%s", money_str.c_str()); -	std::string labe_str = getString("buycurrencylabel", string_args); -	btn_buy_currency->setLabel(labe_str); +	std::string label_str = getString("buycurrencylabel", string_args); +	btn_buy_currency->setLabel(label_str);  	// Resize the balance button so that the label fits it, and the button expands to the left.  	// *TODO: LLButton should have an option where to expand. @@ -513,13 +529,32 @@ static void onClickScriptDebug(void*)  	LLFloaterScriptDebug::show(LLUUID::null);  } -//static -void LLStatusBar::onMouseEnterVolume(LLUICtrl* ctrl) +void LLStatusBar::onMouseEnterVolume()  {  	// show the master volume pull-down -	gStatusBar->mPanelVolumePulldown->setVisible(TRUE); +	mPanelVolumePulldown->setVisible(TRUE);  } +void LLStatusBar::onMouseEnterNearbyMedia() +{ +	LLView* popup_holder = gViewerWindow->getRootView()->getChildView("popup_holder"); +	LLRect nearby_media_rect = mPanelNearByMedia->getRect(); +	LLButton* nearby_media_btn =  getChild<LLButton>( "media_toggle_btn" ); +	LLRect nearby_media_btn_rect = nearby_media_btn->calcScreenRect(); +	nearby_media_rect.setLeftTopAndSize(nearby_media_btn_rect.mLeft -  +		(nearby_media_rect.getWidth() - nearby_media_btn_rect.getWidth())/2, +		nearby_media_btn_rect.mBottom, +		nearby_media_rect.getWidth(), +		nearby_media_rect.getHeight()); +	// force onscreen +	nearby_media_rect.translate(popup_holder->getRect().getWidth() - nearby_media_rect.mRight, 0); + +	// show the master volume pull-down +	mPanelNearByMedia->setShape(nearby_media_rect); +	mPanelNearByMedia->setVisible(TRUE); +} + +  static void onClickVolume(void* data)  {  	// toggle the master mute setting @@ -527,6 +562,15 @@ static void onClickVolume(void* data)  	LLAppViewer::instance()->setMasterSystemAudioMute(!mute_audio);	  } +//static  +void LLStatusBar::onClickMediaToggle(void* data) +{ +	LLStatusBar *status_bar = (LLStatusBar*)data; +	// "Selected" means it was showing the "play" icon (so media was playing), and now it shows "pause", so turn off media +	bool enable = ! status_bar->mMediaToggle->getValue(); +	LLViewerMedia::setAllMediaEnabled(enable); +} +  // sets the static variables necessary for the date  void LLStatusBar::setupDate()  { @@ -596,6 +640,18 @@ void LLStatusBar::onClickStatGraph(void* data)  	LLFloaterReg::showInstance("lagmeter");  } +void LLStatusBar::onClickScreen(S32 x, S32 y) +{ +	if (mPanelNearByMedia->getVisible()) +	{ +		LLRect screen_rect = mPanelNearByMedia->calcScreenRect(); +		if (!screen_rect.pointInRect(x, y)) +		{ +			mPanelNearByMedia->setVisible(FALSE); +		} +	} +} +  BOOL can_afford_transaction(S32 cost)  {  	return((cost <= 0)||((gStatusBar) && (gStatusBar->getBalance() >=cost))); diff --git a/indra/newview/llstatusbar.h b/indra/newview/llstatusbar.h index 21a98dd753..e5240fcc3e 100644 --- a/indra/newview/llstatusbar.h +++ b/indra/newview/llstatusbar.h @@ -48,6 +48,7 @@ class LLUUID;  class LLFrameTimer;  class LLStatGraph;  class LLPanelVolumePulldown; +class LLPanelNearByMedia;  class LLStatusBar  :	public LLPanel @@ -87,6 +88,8 @@ public:  	S32 getSquareMetersCommitted() const;  	S32 getSquareMetersLeft() const; +	LLPanelNearByMedia* getNearbyMediaPanel() { return mPanelNearByMedia; } +  private:  	// simple method to setup the part that holds the date  	void setupDate(); @@ -94,9 +97,13 @@ private:  	void onClickBuyCurrency();  	void onVolumeChanged(const LLSD& newvalue); -	static void onMouseEnterVolume(LLUICtrl* ctrl); +	void onMouseEnterVolume(); +	void onMouseEnterNearbyMedia(); +	void onClickScreen(S32 x, S32 y);  	static void onClickStatGraph(void* data); +	static void onClickMediaToggle(void* data); +  private:  	LLTextBox	*mTextHealth;  	LLTextBox	*mTextTime; @@ -105,6 +112,7 @@ private:  	LLStatGraph *mSGPacketLoss;  	LLButton	*mBtnVolume; +	LLButton	*mMediaToggle;  	S32				mBalance;  	S32				mHealth; @@ -113,6 +121,7 @@ private:  	LLFrameTimer*	mBalanceTimer;  	LLFrameTimer*	mHealthTimer;  	LLPanelVolumePulldown* mPanelVolumePulldown; +	LLPanelNearByMedia*	mPanelNearByMedia;  	static std::vector<std::string> sDays;  	static std::vector<std::string> sMonths;  	static const U32 MAX_DATE_STRING_LENGTH; diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index eb070fb3ef..8370c98470 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -78,7 +78,6 @@  #include "llfloatermap.h"  #include "llfloatermemleak.h"  #include "llfloaternamedesc.h" -#include "llfloaternearbymedia.h"  #include "llfloaternotificationsconsole.h"  #include "llfloateropenobject.h"  #include "llfloaterpay.h" @@ -197,7 +196,6 @@ void LLViewerFloaterReg::registerFloaters()  	LLFloaterReg::add("mute_object_by_name", "floater_mute_object.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterGetBlockedObjectName>);  	LLFloaterReg::add("mini_map", "floater_map.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMap>); -	LLFloaterReg::add("nearby_media", "floater_nearby_media.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterNearbyMedia>);  	LLFloaterReg::add("notifications_console", "floater_notifications_console.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterNotificationConsole>);  	LLFloaterReg::add("notification_well_window", "floater_sys_well.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLNotificationWellWindow>); diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 25c843cf15..642f672faf 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -50,6 +50,9 @@  #include "llcallbacklist.h"  #include "llparcel.h"  #include "llaudioengine.h"  // for gAudiop +#include "llvoavatar.h" +#include "llvoavatarself.h" +#include "llviewerregion.h"  #include "llevent.h"		// LLSimpleListener  #include "llnotificationsutil.h" @@ -63,6 +66,10 @@  #include <boost/signals2.hpp>  /*static*/ const char* LLViewerMedia::AUTO_PLAY_MEDIA_SETTING = "ParcelMediaAutoPlayEnable"; +/*static*/ const char* LLViewerMedia::SHOW_MEDIA_ON_OTHERS_SETTING = "MediaShowOnOthers"; +/*static*/ const char* LLViewerMedia::SHOW_MEDIA_WITHIN_PARCEL_SETTING = "MediaShowWithinParcel"; +/*static*/ const char* LLViewerMedia::SHOW_MEDIA_OUTSIDE_PARCEL_SETTING = "MediaShowOutsideParcel"; +  // Move this to its own file. @@ -254,6 +261,8 @@ static LLTimer sMediaCreateTimer;  static const F32 LLVIEWERMEDIA_CREATE_DELAY = 1.0f;  static F32 sGlobalVolume = 1.0f;  static F64 sLowestLoadableImplInterest = 0.0f; +static bool sAnyMediaShowing = false; +static boost::signals2::connection sTeleportFinishConnection;  //////////////////////////////////////////////////////////////////////////////////////////  static void add_media_impl(LLViewerMediaImpl* media) @@ -366,8 +375,7 @@ viewer_media_t LLViewerMedia::updateMediaImpl(LLMediaEntry* media_entry, const s  			// The current media URL is not empty.  			// If (the media was already loaded OR the media was set to autoplay) AND this update didn't come from this agent,  			// do a navigate. -			bool auto_play = (media_impl->mMediaAutoPlay && gSavedSettings.getBOOL(AUTO_PLAY_MEDIA_SETTING)); -			 +			bool auto_play = media_impl->isAutoPlayable();			  			if((was_loaded || auto_play) && !update_from_self)  			{  				needs_navigate = url_changed; @@ -391,7 +399,7 @@ viewer_media_t LLViewerMedia::updateMediaImpl(LLMediaEntry* media_entry, const s  		media_impl->mMediaAutoPlay = media_entry->getAutoPlay();  		media_impl->mMediaEntryURL = media_entry->getCurrentURL(); -		if(media_impl->mMediaAutoPlay && gSavedSettings.getBOOL(AUTO_PLAY_MEDIA_SETTING)) +		if(media_impl->isAutoPlayable())  		{  			needs_navigate = true;  		} @@ -688,6 +696,7 @@ static bool proximity_comparitor(const LLViewerMediaImpl* i1, const LLViewerMedi  // static  void LLViewerMedia::updateMedia(void *dummy_arg)  { +	sAnyMediaShowing = false;  	impl_list::iterator iter = sViewerMediaImplList.begin();  	impl_list::iterator end = sViewerMediaImplList.end(); @@ -818,7 +827,7 @@ void LLViewerMedia::updateMedia(void *dummy_arg)  			impl_count_total++;  		} -		 +  		// Overrides if the window is minimized or we lost focus (taking care  		// not to accidentally "raise" the priority either)  		if (!gViewerWindow->getActive() /* viewer window minimized? */  @@ -840,7 +849,7 @@ void LLViewerMedia::updateMedia(void *dummy_arg)  				new_priority = LLPluginClassMedia::PRIORITY_UNLOADED;  			}  		} -		 +					  		pimpl->setPriority(new_priority);  		if(pimpl->getUsedInUI()) @@ -854,6 +863,12 @@ void LLViewerMedia::updateMedia(void *dummy_arg)  		}  		total_cpu += pimpl->getCPUUsage(); +		 +		if (!pimpl->getUsedInUI() && pimpl->hasMedia()) +		{ +			sAnyMediaShowing = true; +		} +  	}  	// Re-calculate this every time. @@ -895,9 +910,113 @@ void LLViewerMedia::updateMedia(void *dummy_arg)  //////////////////////////////////////////////////////////////////////////////////////////  // static +bool LLViewerMedia::isAnyMediaShowing() +{ +	return sAnyMediaShowing; +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMedia::setAllMediaEnabled(bool val) +{ +	// Set "tentative" autoplay first.  We need to do this here or else +	// re-enabling won't start up the media below. +	gSavedSettings.setBOOL("MediaTentativeAutoPlay", val); +	 +	// Then  +	impl_list::iterator iter = sViewerMediaImplList.begin(); +	impl_list::iterator end = sViewerMediaImplList.end(); +	 +	for(; iter != end; iter++) +	{ +		LLViewerMediaImpl* pimpl = *iter; +		if (!pimpl->getUsedInUI()) +		{ +			pimpl->setDisabled(!val); +		} +	} +	 +	// Also do Parcel Media and Parcel Audio +	if (val) +	{ +		if (!LLViewerMedia::isParcelMediaPlaying() && LLViewerMedia::hasParcelMedia()) +		{	 +			LLViewerParcelMedia::play(LLViewerParcelMgr::getInstance()->getAgentParcel()); +		} +		 +		if (!LLViewerMedia::isParcelAudioPlaying() && gAudiop && LLViewerMedia::hasParcelAudio()) +		{ +			gAudiop->startInternetStream(LLViewerMedia::getParcelAudioURL()); +		} +	} +	else { +		// This actually unloads the impl, as opposed to "stop"ping the media +		LLViewerParcelMedia::stop(); +		if (gAudiop) gAudiop->stopInternetStream(); +	} +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static +bool LLViewerMedia::isParcelMediaPlaying() +{ +	return (LLViewerMedia::hasParcelMedia() && LLViewerParcelMedia::getParcelMedia() && LLViewerParcelMedia::getParcelMedia()->hasMedia()); +} + +///////////////////////////////////////////////////////////////////////////////////////// +// static +bool LLViewerMedia::isParcelAudioPlaying() +{ +	return (LLViewerMedia::hasParcelAudio() && gAudiop && LLAudioEngine::AUDIO_PLAYING == gAudiop->isInternetStreamPlaying()); +} + +bool LLViewerMedia::hasInWorldMedia() +{ +	if (! gSavedSettings.getBOOL("AudioStreamingMedia")) return false; +	if (sInWorldMediaDisabled) return false; +	impl_list::iterator iter = sViewerMediaImplList.begin(); +	impl_list::iterator end = sViewerMediaImplList.end(); +	// This should be quick, because there should be very few non-in-world-media impls +	for (; iter != end; iter++) +	{ +		LLViewerMediaImpl* pimpl = *iter; +		if (!pimpl->getUsedInUI() && !pimpl->isParcelMedia()) +		{ +			// Found an in-world media impl +			return true; +		} +	} +	return false; +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static +bool LLViewerMedia::hasParcelMedia() +{ +	return !LLViewerParcelMedia::getURL().empty(); +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static +bool LLViewerMedia::hasParcelAudio() +{ +	return !LLViewerMedia::getParcelAudioURL().empty(); +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static +std::string LLViewerMedia::getParcelAudioURL() +{ +	return LLViewerParcelMgr::getInstance()->getAgentParcel()->getMusicURL(); +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static  void LLViewerMedia::initClass()  { -	gIdleCallbacks.addFunction(LLViewerMedia::updateMedia, NULL); +	gIdleCallbacks.addFunction(LLViewerMedia::updateMedia, NULL);	 +	sTeleportFinishConnection = LLViewerParcelMgr::getInstance()-> +		setTeleportFinishedCallback(boost::bind(&LLViewerMedia::onTeleportFinished));  }  ////////////////////////////////////////////////////////////////////////////////////////// @@ -905,6 +1024,15 @@ void LLViewerMedia::initClass()  void LLViewerMedia::cleanupClass()  {  	gIdleCallbacks.deleteFunction(LLViewerMedia::updateMedia, NULL); +	sTeleportFinishConnection.disconnect(); +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMedia::onTeleportFinished() +{ +	// On teleport, clear this setting (i.e. set it to true) +	gSavedSettings.setBOOL("MediaTentativeAutoPlay", true);  }  ////////////////////////////////////////////////////////////////////////////////////////// @@ -2057,6 +2185,21 @@ void LLViewerMediaImpl::scaleMouse(S32 *mouse_x, S32 *mouse_y)  #endif  } + + +////////////////////////////////////////////////////////////////////////////////////////// +bool LLViewerMediaImpl::isMediaTimeBased() +{ +	bool result = false; +	 +	if(mMediaSource) +	{ +		result = mMediaSource->pluginSupportsMediaTime(); +	} +	 +	return result; +} +  //////////////////////////////////////////////////////////////////////////////////////////  bool LLViewerMediaImpl::isMediaPlaying()  { @@ -2103,7 +2246,7 @@ void LLViewerMediaImpl::resetPreviousMediaState()  //////////////////////////////////////////////////////////////////////////////////////////  // -void LLViewerMediaImpl::setDisabled(bool disabled) +void LLViewerMediaImpl::setDisabled(bool disabled, bool forcePlayOnEnable)  {  	if(mIsDisabled != disabled)  	{ @@ -2118,7 +2261,7 @@ void LLViewerMediaImpl::setDisabled(bool disabled)  		else  		{  			// We just (re)enabled this media.  Do a navigate if auto-play is in order. -			if(mMediaAutoPlay && gSavedSettings.getBOOL(LLViewerMedia::AUTO_PLAY_MEDIA_SETTING)) +			if(isAutoPlayable() || forcePlayOnEnable)  			{  				navigateTo(mMediaEntryURL, "", true, true);  			} @@ -2145,6 +2288,12 @@ bool LLViewerMediaImpl::isForcedUnloaded() const  		}  	} +	// If this media's class is not supposed to be shown, unload +	if (!shouldShowBasedOnClass()) +	{ +		return true; +	} +	  	return false;  } @@ -2639,3 +2788,112 @@ void LLViewerMediaImpl::setTextureID(LLUUID id)  	}  } +////////////////////////////////////////////////////////////////////////////////////////// +// +bool LLViewerMediaImpl::isAutoPlayable() const +{ +	return (mMediaAutoPlay &&  +			gSavedSettings.getBOOL(LLViewerMedia::AUTO_PLAY_MEDIA_SETTING) && +			gSavedSettings.getBOOL("MediaTentativeAutoPlay")); +} + +////////////////////////////////////////////////////////////////////////////////////////// +// +bool LLViewerMediaImpl::shouldShowBasedOnClass() const +{ +	// If this is parcel media or in the UI, return true always +	if (getUsedInUI() || isParcelMedia()) return true; +	 +	bool attached_to_another_avatar = isAttachedToAnotherAvatar(); +	bool inside_parcel = isInAgentParcel(); +	 +	//	llinfos << " hasFocus = " << hasFocus() << +	//	" others = " << (attached_to_another_avatar && gSavedSettings.getBOOL(LLViewerMedia::SHOW_MEDIA_ON_OTHERS_SETTING)) << +	//	" within = " << (inside_parcel && gSavedSettings.getBOOL(LLViewerMedia::SHOW_MEDIA_WITHIN_PARCEL_SETTING)) << +	//	" outside = " << (!inside_parcel && gSavedSettings.getBOOL(LLViewerMedia::SHOW_MEDIA_OUTSIDE_PARCEL_SETTING)) << llendl; +	 +	// If it has focus, we should show it +	if (hasFocus()) +		return true; +	 +	// If it is attached to an avatar and the pref is off, we shouldn't show it +	if (attached_to_another_avatar) +		return gSavedSettings.getBOOL(LLViewerMedia::SHOW_MEDIA_ON_OTHERS_SETTING); +	 +	if (inside_parcel) +		return gSavedSettings.getBOOL(LLViewerMedia::SHOW_MEDIA_WITHIN_PARCEL_SETTING); +	else  +		return gSavedSettings.getBOOL(LLViewerMedia::SHOW_MEDIA_OUTSIDE_PARCEL_SETTING); +} + +////////////////////////////////////////////////////////////////////////////////////////// +// +bool LLViewerMediaImpl::isAttachedToAnotherAvatar() const +{ +	bool result = false; +	 +	std::list< LLVOVolume* >::const_iterator iter = mObjectList.begin(); +	std::list< LLVOVolume* >::const_iterator end = mObjectList.end(); +	for ( ; iter != end; iter++) +	{ +		if (isObjectAttachedToAnotherAvatar(*iter)) +		{ +			result = true; +			break; +		} +	} +	return result; +} + +////////////////////////////////////////////////////////////////////////////////////////// +// +//static +bool LLViewerMediaImpl::isObjectAttachedToAnotherAvatar(LLVOVolume *obj) +{ +	bool result = false; +	LLXform *xform = obj; +	// Walk up parent chain +	while (NULL != xform) +	{ +		LLViewerObject *object = dynamic_cast<LLViewerObject*> (xform); +		if (NULL != object) +		{ +			LLVOAvatar *avatar = object->asAvatar(); +			if (NULL != avatar && avatar != gAgent.getAvatarObject()) +			{ +				result = true; +				break; +			} +		} +		xform = xform->getParent(); +	} +	return result; +} + +////////////////////////////////////////////////////////////////////////////////////////// +// +bool LLViewerMediaImpl::isInAgentParcel() const +{ +	bool result = false; +	 +	std::list< LLVOVolume* >::const_iterator iter = mObjectList.begin(); +	std::list< LLVOVolume* >::const_iterator end = mObjectList.end(); +	for ( ; iter != end; iter++) +	{ +		LLVOVolume *object = *iter; +		if (LLViewerMediaImpl::isObjectInAgentParcel(object)) +		{ +			result = true; +			break; +		} +	} +	return result; +} + +////////////////////////////////////////////////////////////////////////////////////////// +// +// static +bool LLViewerMediaImpl::isObjectInAgentParcel(LLVOVolume *obj) +{ +	return (LLViewerParcelMgr::getInstance()->inAgentParcel(obj->getPositionGlobal())); +} diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h index daad70f14f..9dbffa78b3 100644 --- a/indra/newview/llviewermedia.h +++ b/indra/newview/llviewermedia.h @@ -48,7 +48,7 @@ class LLViewerMediaImpl;  class LLUUID;  class LLViewerMediaTexture;  class LLMediaEntry; -class LLVOVolume ; +class LLVOVolume;  class LLMimeDiscoveryResponder;  typedef LLPointer<LLViewerMediaImpl> viewer_media_t; @@ -73,50 +73,68 @@ class LLViewerMediaImpl;  class LLViewerMedia  {  	LOG_CLASS(LLViewerMedia); -	public: - -		// String to get/set media autoplay in gSavedSettings -		static const char *AUTO_PLAY_MEDIA_SETTING; +public: -		typedef std::vector<LLViewerMediaImpl*> impl_list; - -		typedef std::map<LLUUID, LLViewerMediaImpl*> impl_id_map; - -		// Special case early init for just web browser component -		// so we can show login screen.  See .cpp file for details. JC - -		static viewer_media_t newMediaImpl(const LLUUID& texture_id, -												S32 media_width = 0,  -												S32 media_height = 0,  -												U8 media_auto_scale = false, -												U8 media_loop = false); - -		static viewer_media_t updateMediaImpl(LLMediaEntry* media_entry, const std::string& previous_url, bool update_from_self); -		static LLViewerMediaImpl* getMediaImplFromTextureID(const LLUUID& texture_id); -		static std::string getCurrentUserAgent(); -		static void updateBrowserUserAgent(); -		static bool handleSkinCurrentChanged(const LLSD& /*newvalue*/); -		static bool textureHasMedia(const LLUUID& texture_id); -		static void setVolume(F32 volume); - -		static void updateMedia(void* dummy_arg = NULL); - -		static void initClass(); -		static void cleanupClass(); - -		static F32 getVolume();	 -		static void muteListChanged(); -		static void setInWorldMediaDisabled(bool disabled); -		static bool getInWorldMediaDisabled(); -				 -		static bool isInterestingEnough(const LLVOVolume* object, const F64 &object_interest); +	// String to get/set media autoplay in gSavedSettings +	static const char* AUTO_PLAY_MEDIA_SETTING; +	static const char* SHOW_MEDIA_ON_OTHERS_SETTING; +	static const char* SHOW_MEDIA_WITHIN_PARCEL_SETTING; +	static const char* SHOW_MEDIA_OUTSIDE_PARCEL_SETTING; -		// Returns the priority-sorted list of all media impls. -		static impl_list &getPriorityList(); -		 -		// This is the comparitor used to sort the list. -		static bool priorityComparitor(const LLViewerMediaImpl* i1, const LLViewerMediaImpl* i2); -		 +	typedef std::vector<LLViewerMediaImpl*> impl_list; +	 +	typedef std::map<LLUUID, LLViewerMediaImpl*> impl_id_map; +	 +	// Special case early init for just web browser component +	// so we can show login screen.  See .cpp file for details. JC +	 +	static viewer_media_t newMediaImpl(const LLUUID& texture_id, +									   S32 media_width = 0,  +									   S32 media_height = 0,  +									   U8 media_auto_scale = false, +									   U8 media_loop = false); +	 +	static viewer_media_t updateMediaImpl(LLMediaEntry* media_entry, const std::string& previous_url, bool update_from_self); +	static LLViewerMediaImpl* getMediaImplFromTextureID(const LLUUID& texture_id); +	static std::string getCurrentUserAgent(); +	static void updateBrowserUserAgent(); +	static bool handleSkinCurrentChanged(const LLSD& /*newvalue*/); +	static bool textureHasMedia(const LLUUID& texture_id); +	static void setVolume(F32 volume); +	 +	// Is any media currently "showing"?  Includes Parcel Media.  Does not include media in the UI. +	static bool isAnyMediaShowing(); +	// Set all media enabled or disabled, depending on val.   Does not include media in the UI. +	static void setAllMediaEnabled(bool val); +	 +	static void updateMedia(void* dummy_arg = NULL); +	 +	static void initClass(); +	static void cleanupClass(); +	 +	static F32 getVolume();	 +	static void muteListChanged(); +	static void setInWorldMediaDisabled(bool disabled); +	static bool getInWorldMediaDisabled(); +	 +	static bool isInterestingEnough(const LLVOVolume* object, const F64 &object_interest); +	 +	// Returns the priority-sorted list of all media impls. +	static impl_list &getPriorityList(); +	 +	// This is the comparitor used to sort the list. +	static bool priorityComparitor(const LLViewerMediaImpl* i1, const LLViewerMediaImpl* i2); +	 +	// These are just helper functions for the convenience of others working with media +	static bool hasInWorldMedia(); +	static std::string getParcelAudioURL(); +	static bool hasParcelMedia(); +	static bool hasParcelAudio(); +	static bool isParcelMediaPlaying(); +	static bool isParcelAudioPlaying(); +	 +private: +	static void onTeleportFinished();  };  // Implementation functions not exported into header file @@ -199,18 +217,20 @@ public:  	void updateImagesMediaStreams();  	LLUUID getMediaTextureID() const; -	void suspendUpdates(bool suspend) { mSuspendUpdates = suspend; }; +	void suspendUpdates(bool suspend) { mSuspendUpdates = suspend; }  	void setVisible(bool visible); -	bool getVisible() const { return mVisible; }; +	bool getVisible() const { return mVisible; } +	bool isVisible() const { return mVisible; } +	bool isMediaTimeBased();  	bool isMediaPlaying();  	bool isMediaPaused();  	bool hasMedia() const; -	bool isMediaFailed() const { return mMediaSourceFailed; }; +	bool isMediaFailed() const { return mMediaSourceFailed; }  	void setMediaFailed(bool val) { mMediaSourceFailed = val; }  	void resetPreviousMediaState(); -	void setDisabled(bool disabled); +	void setDisabled(bool disabled, bool forcePlayOnEnable = false);  	bool isMediaDisabled() const { return mIsDisabled; };  	void setInNearbyMediaList(bool in_list) { mInNearbyMediaList = in_list; } @@ -222,10 +242,10 @@ public:  	// returns true if this instance could be playable based on autoplay setting, current load state, etc.  	bool isPlayable() const; -	void setIsParcelMedia(bool is_parcel_media) { mIsParcelMedia = is_parcel_media; }; -	bool isParcelMedia() const { return mIsParcelMedia; }; +	void setIsParcelMedia(bool is_parcel_media) { mIsParcelMedia = is_parcel_media; } +	bool isParcelMedia() const { return mIsParcelMedia; } -	ECursorType getLastSetCursor() { return mLastSetCursor; }; +	ECursorType getLastSetCursor() { return mLastSetCursor; }  	// utility function to create a ready-to-use media instance from a desired media type.  	static LLPluginClassMedia* newSourceFromMediaType(std::string media_type, LLPluginClassMediaOwner *owner /* may be NULL */, S32 default_width, S32 default_height); @@ -326,6 +346,18 @@ public:  	void cancelMimeTypeProbe(); +	// Is this media attached to an avatar *not* self +	bool isAttachedToAnotherAvatar() const; +	 +	// Is this media in the agent's parcel? +	bool isInAgentParcel() const; + +private: +	bool isAutoPlayable() const; +	bool shouldShowBasedOnClass() const; +	static bool isObjectAttachedToAnotherAvatar(LLVOVolume *obj); +	static bool isObjectInAgentParcel(LLVOVolume *obj); +	  private:  	// a single media url with some data and an impl.  	LLPluginClassMedia* mMediaSource; @@ -368,7 +400,7 @@ private:  	LLMimeDiscoveryResponder *mMimeTypeProbe;  	bool mMediaAutoPlay;  	std::string mMediaEntryURL; -	bool mInNearbyMediaList;	// used by LLFloaterNearbyMedia::refreshList() for performance reasons +	bool mInNearbyMediaList;	// used by LLPanelNearbyMedia::refreshList() for performance reasons  	bool mClearCache;  	LLColor4 mBackgroundColor;  	bool mNavigateSuspended; diff --git a/indra/newview/llviewermediafocus.cpp b/indra/newview/llviewermediafocus.cpp index f508a3462a..88e7cfec86 100644 --- a/indra/newview/llviewermediafocus.cpp +++ b/indra/newview/llviewermediafocus.cpp @@ -559,6 +559,19 @@ void LLViewerMediaFocus::focusZoomOnMedia(LLUUID media_id)  	}  } +void LLViewerMediaFocus::unZoom() +{ +	if(mMediaControls.get()) +	{ +		mMediaControls.get()->resetZoomLevel(); +	} +} + +bool LLViewerMediaFocus::isZoomed() const +{ +	return (mMediaControls.get() && mMediaControls.get()->getZoomLevel() != LLPanelPrimMediaControls::ZOOM_NONE); +} +  LLUUID LLViewerMediaFocus::getControlsMediaID()  {  	if(getFocusedMediaImpl()) diff --git a/indra/newview/llviewermediafocus.h b/indra/newview/llviewermediafocus.h index 002044ea2e..d9ddc7432b 100644 --- a/indra/newview/llviewermediafocus.h +++ b/indra/newview/llviewermediafocus.h @@ -85,6 +85,9 @@ public:  	// Try to focus/zoom on the specified media (if it's on an object in world).  	void focusZoomOnMedia(LLUUID media_id); +	// Are we zoomed in? +	bool isZoomed() const; +	void unZoom();  	// Return the ID of the media instance the controls are currently attached to (either focus or hover).  	LLUUID getControlsMediaID(); diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp index 07c8867e26..1f6bbcbae8 100644 --- a/indra/newview/llviewerparcelmgr.cpp +++ b/indra/newview/llviewerparcelmgr.cpp @@ -53,7 +53,7 @@  //#include "llfirstuse.h"  #include "llfloaterbuyland.h"  #include "llfloatergroups.h" -#include "llfloaternearbymedia.h" +#include "llpanelnearbymedia.h"  #include "llfloatersellland.h"  #include "llfloatertools.h"  #include "llparcelselection.h" @@ -1795,12 +1795,13 @@ void optionally_start_music(const std::string& music_url)  	{  		// only play music when you enter a new parcel if the UI control for this  		// was not *explicitly* stopped by the user. (part of SL-4878) -		LLFloaterNearbyMedia *nearby_media_floater = LLFloaterReg::findTypedInstance<LLFloaterNearbyMedia>("nearby_media"); -		if ((nearby_media_floater && -		     nearby_media_floater->getParcelAudioAutoStart()) || +		LLPanelNearByMedia* nearby_media_panel = gStatusBar->getNearbyMediaPanel();; +		if ((nearby_media_panel && +		     nearby_media_panel->getParcelAudioAutoStart()) ||  		    // or they have expressed no opinion in the UI, but have autoplay on... -		    (!nearby_media_floater && -		     gSavedSettings.getBOOL(LLViewerMedia::AUTO_PLAY_MEDIA_SETTING))) +		    (!nearby_media_panel && +		     gSavedSettings.getBOOL(LLViewerMedia::AUTO_PLAY_MEDIA_SETTING) && +			 gSavedSettings.getBOOL("MediaTentativeAutoPlay")))  		{  			llinfos << "Starting parcel music " << music_url << llendl;  			gAudiop->startInternetStream(music_url); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 1dcc7389cb..1669ce6312 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -997,6 +997,7 @@ void LLViewerWindow::handleMouseLeave(LLWindow *window)  	// Note: we won't get this if we have captured the mouse.  	llassert( gFocusMgr.getMouseCapture() == NULL );  	mMouseInWindow = FALSE; +	LLToolTipMgr::instance().blockToolTips();  }  BOOL LLViewerWindow::handleCloseRequest(LLWindow *window) diff --git a/indra/newview/skins/default/textures/windows/Flyout_Pointer_Up.png b/indra/newview/skins/default/textures/windows/Flyout_Pointer_Up.pngBinary files differ new file mode 100644 index 0000000000..361fab59e0 --- /dev/null +++ b/indra/newview/skins/default/textures/windows/Flyout_Pointer_Up.png diff --git a/indra/newview/skins/default/xui/en/main_view.xml b/indra/newview/skins/default/xui/en/main_view.xml index 1d4377e339..7b6081d7be 100644 --- a/indra/newview/skins/default/xui/en/main_view.xml +++ b/indra/newview/skins/default/xui/en/main_view.xml @@ -162,6 +162,12 @@                 mouse_opaque="false"                 name="Menu Holder"                 width="1024"/> +  <panel top="0" +         follows="all" +         height="768" +         mouse_opaque="false" +         name="popup_holder" +         width="1024"/>    <snapshot_floater_view enabled="false"                           follows="all"                           height="768" diff --git a/indra/newview/skins/default/xui/en/panel_nearby_media.xml b/indra/newview/skins/default/xui/en/panel_nearby_media.xml new file mode 100644 index 0000000000..4a71be370e --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_nearby_media.xml @@ -0,0 +1,476 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel +	can_resize="true" +	can_close="false" +	background_opaque="true" +	background_visible="true" +	layout="topleft" +	width="270" +	height="325" +	name="nearby_media" +	help_topic="nearby_media"> +  <string name="media_item_count_format">(%ld media items)</string> +  <string name="empty_item_text"><empty></string> +  <string name="parcel_media_name">Parcel Streaming Media</string> +  <string name="parcel_audio_name">Parcel Streaming Audio</string> +  <string name="playing_suffix">(playing)</string> +  <panel +	  bevel_style="in" +	  bg_alpha_color="0 0 0 0" +	  bg_opaque_color="0 0 0 0.3" +	  bg_opaque_image="Toast_Background"   +	  follows="left|right|top" +	  top="0" +	  height="30" +	  name="minimized_controls"  +	  left="0"> +	<button +		name="all_nearby_media_disable_btn" +		follows="left" +		tool_tip="Turn all nearby media off" +		left="15" +		width="60" +		height="22" +		label="Stop All"> +	  <button.commit_callback +		  function="MediaListCtrl.DisableAll" /> +	</button> +	<button +		name="all_nearby_media_enable_btn" +		follows="left" +		tool_tip="Turn all nearby media on" +		left_pad="4" +		width="60" +		height="22" +		label="Start All"> +	  <button.commit_callback +		  function="MediaListCtrl.EnableAll" /> +	</button> +	<button +		name="open_prefs_btn" +		image_overlay="Icon_Gear_Foreground" +		image_disabled="PushButton_Disabled" +		image_disabled_selected="PushButton_Disabled" +		image_selected="PushButton_Selected" +		image_unselected="PushButton_Off" +		hover_glow_amount="0.15" +		tool_tip = "Bring up media prefs" +		top_delta="0" +		left_pad="4" +		height="22" +		min_width="28" +		width="28"> +	  <button.commit_callback +		  function="MediaListCtrl.GoMediaPrefs" /> +	</button> +	<button +		name="more_less_btn" +		follows="right" +		tool_tip="Advanced Controls" +		top_delta="0" +		right="-10" +		width="60" +		height="22" +		toggle="true" +		label="More >>" +		label_selected="Less <<"> +	  <button.commit_callback +		  function="MediaListCtrl.MoreLess" /> +	</button> +  </panel> +  <panel +	  name="nearby_media_panel" +	  bevel_style="in" +	  border_style="line" +	  bg_alpha_color="0 0 0 0" +	  bg_opaque_color="0 0 0 0.3" +	  follows="left|right|top|bottom" +	  top_delta="30" +	  right="-1" +	  left="0" +	  height="295"> +	<text +		type="string" +		length="1" +		follows="top|left" +		font="SansSerif" +		left="10" +		width="100"> +	  Nearby Media +	</text> +	<!-- nix for now +		 <text +		 bottom_delta="1" +		 type="string" +		 follows="top|left|right" +		 font="SansSerif" +		 font.style="ITALIC" +		 font.size="Small" +		 name="media_item_count" +		 left="115" +		 right="-10"> +		 (?? media items) +		 </text> +	--> +	<text +		type="string" +		length="1" +		follows="top|left" +		font="SansSerif" +		top_pad="15" +		left="10" +		width="40"> +	  Show: +	</text> +	<combo_box +		height="23" +		left="50" +		width="140" +		top_delta="-5" +		follows="left|top" +		name="show_combo"> +	  <combo_box.item +		  label="All" +		  value="0" +		  name="All" /> +	  <combo_box.item +		  label="In this Parcel" +		  value="2" +		  name="WithinParcel" /> +	  <combo_box.item +		  label="Outside this Parcel" +		  value="3" +		  name="OutsideParcel" /> +	  <combo_box.item +		  label="On other Avatars" +		  value="4" +		  ame="OnOthers" /> +	</combo_box> +	<scroll_list +		follows="left|top|bottom|right" +		column_padding="0" +		height="100" +		draw_heading="false" +		draw_stripes="true" +		bg_stripe_color="0.25 0.25 0.25 0.25" +		top_pad="8" +		left="10" +		right="-10" +		name="media_list"> +	  <scroll_list.columns +		  type="checkbox" +		  width="-1" +		  label="" +		  name="media_checkbox_ctrl" /> +	  <scroll_list.columns +		  sort_column="media_proximity" +		  width="-1" +		  label="Proximity" +		  name="media_proximity" /> +	  <scroll_list.columns +		  sort_column="media_visibility" +		  width="-1" +		  label="Visible" +		  name="media_visibility" /> +	  <scroll_list.columns +		  sort_column="media_class" +		  width="-1" +		  label="Class" +		  name="media_class" /> +	  <scroll_list.columns +		  label="Name" +		  name="media_name" /> +	  <scroll_list.columns +		  sort_column="media_debug" +		  width="-1" +		  label="Debug" +		  name="media_debug" /> +	</scroll_list> +	<panel +		bevel_style="in" +		background_visible="true"  +		bg_alpha_color="0.0 0.0 0.0 1.0" +		bg_opaque_color="0 0 0 0.3" +		follows="left|right|bottom" +		top_pad="5" +		height="30" +		left="10" +		right="-10"> +	  <layout_stack +		  name="media_controls" +		  follows="left|right|top" +		  animate="false" +		  height="75" +		  layout="topleft" +		  top="4" +		  left="10" +		  right="-10" +		  border_size="0" +		  mouse_opaque="false" +		  orientation="horizontal"> +		<layout_panel +			name="stop" +			mouse_opaque="false" +			auto_resize="false" +			user_resize="false" +			layout="topleft" +			top="0" +			height="22" +			min_width="22" +			width="22"> +		  <button +			  name="stop_btn" +			  follows="top" +			  image_overlay="Stop_Off" +			  image_disabled="PushButton_Disabled" +			  image_disabled_selected="PushButton_Disabled" +			  image_selected="PushButton_Selected" +			  image_unselected="PushButton_Off" +			  hover_glow_amount="0.15" +			  layout="topleft" +			  tool_tip="Stop selected media" +			  top="0" +			  height="22" +			  width="22"> +			<button.commit_callback +				function="SelectedMediaCtrl.Stop" /> +		  </button> +		</layout_panel> +		<layout_panel +			name="play" +			mouse_opaque="false" +			auto_resize="false" +			user_resize="false" +			layout="topleft" +			top="0" +			height="22" +			min_width="22" +			width="22"> +		  <button +			  name="play_btn" +			  follows="top" +			  image_overlay="Play_Off" +			  image_disabled="PushButton_Disabled" +			  image_disabled_selected="PushButton_Disabled" +			  image_selected="PushButton_Selected" +			  image_unselected="PushButton_Off" +			  hover_glow_amount="0.15" +			  layout="topleft" +			  tool_tip = "Play selected media" +			  top="0" +			  height="22" +			  width="22"> +			<button.commit_callback +				function="SelectedMediaCtrl.Play" /> +		  </button> +		</layout_panel> +		<layout_panel +			name="pause" +			mouse_opaque="false" +			auto_resize="false" +			user_resize="false" +			layout="topleft" +			top="0" +			min_width="22" +			width="22"> +		  <button +			  name="pause_btn" +			  follows="top" +			  image_overlay="Pause_Off" +			  image_disabled="PushButton_Disabled" +			  image_disabled_selected="PushButton_Disabled" +			  image_selected="PushButton_Selected" +			  image_unselected="PushButton_Off" +			  hover_glow_amount="0.15" +			  layout="topleft" +			  top="0" +			  height="22" +			  width="22" +			  tool_tip = "Pause selected media"> +			<button.commit_callback +				function="SelectedMediaCtrl.Pause" /> +		  </button> +		</layout_panel> +		<layout_panel +			name="volume_slider_ctrl" +			mouse_opaque="false" +			auto_resize="true" +			user_resize="false" +			follows="left|right" +			layout="topleft" +			top="0" +			height="22" +			min_width="100" +			width="200"> +		  <slider_bar +			  name="volume_slider" +			  follows="left|right|top" +			  top="0" +			  height="22" +			  increment="0.01" +			  initial_value="0.5" +			  layout="topleft" +			  tool_tip="Audio volume for selected media" +			  width="200"> +			<slider_bar.commit_callback +				function="SelectedMediaCtrl.Volume" /> +		  </slider_bar> +		</layout_panel> +		<layout_panel +			name="mute" +			mouse_opaque="false" +			auto_resize="false" +			user_resize="false" +			layout="topleft" +			top="0" +			height="72" +			min_width="22" +			width="22"> +		  <button +			  name="mute_btn" +			  follows="top" +			  image_disabled="PushButton_Disabled" +			  image_disabled_selected="PushButton_Disabled" +			  image_selected="AudioMute_Off" +			  image_unselected="Audio_Off" +			  hover_glow_amount="0.15" +			  is_toggle="true" +			  layout="topleft" +			  scale_image="false"  +			  tool_tip="Mute audio on selected media" +			  top="0" +			  height="20" +			  width="22" > +			<button.commit_callback +				function="SelectedMediaCtrl.Mute" /> +		  </button> +		</layout_panel> +		<layout_panel +			name="zoom" +			mouse_opaque="false" +			auto_resize="false" +			user_resize="false" +			layout="topleft" +			top="0" +			height="28" +			min_width="22" +			width="22"> +		  <button +			  name="zoom_btn" +			  follows="top" +			  image_overlay="Zoom_Off" +			  image_disabled="PushButton_Disabled" +			  image_disabled_selected="PushButton_Disabled" +			  image_selected="PushButton_Selected" +			  image_unselected="PushButton_Off" +			  hover_glow_amount="0.15" +			  top="0" +			  height="22" +			  layout="topleft" +			  tool_tip="Zoom into selected media" +			  width="22"> +			<button.commit_callback +				function="SelectedMediaCtrl.Zoom" /> +		  </button> +		</layout_panel> +		<layout_panel +			name="unzoom" +			mouse_opaque="false" +			auto_resize="false" +			user_resize="false" +			layout="topleft" +			top="0" +			min_width="21" +			width="21" > +		  <button +			  name="unzoom_btn" +			  follows="top" +			  image_overlay="UnZoom_Off" +			  image_disabled="PushButton_Disabled" +			  image_disabled_selected="PushButton_Disabled" +			  image_selected="PushButton_Selected" +			  image_unselected="PushButton_Off" +			  hover_glow_amount="0.15" +			  top="0" +			  height="22" +			  layout="topleft" +			  tool_tip ="Zoom back from selected media" +			  top_delta="-4" +			  width="21" > +			<button.commit_callback +				function="SelectedMediaCtrl.Unzoom" /> +		  </button> +		</layout_panel> +		<layout_panel +			name="right_bookend" +			width="0" +			mouse_opaque="false" +			user_resize="false" /> +	  </layout_stack> +	</panel> +	<panel +		bevel_style="in" +		background_visible="true"  +		bg_alpha_color="0.0 0.0 0.0 1.0" +		bg_opaque_color="0 0 0 0.3" +		follows="left|right|bottom" +		top_pad="5" +		height="90" +		left="10" +		right="-10"> +	  <check_box +		  name="media_enabled_btn" +		  control_name="AudioStreamingMedia" +		  value="true" +		  follows="left|bottom|right" +		  height="15" +		  tool_tip="Check this to enable all media" +		  label="All Media Enabled" +		  top="10" +		  left="10"/> +	  <check_box +		  name="media_auto_play_btn" +		  control_name="ParcelMediaAutoPlayEnable" +		  enabled_control="AudioStreamingMedia" +		  value="true" +		  follows="left|bottom|right" +		  height="15" +		  tool_tip="Check this to let media auto-play if it wants" +		  label="Allow Media to auto-play" +		  top_pad="5" +		  left="10"/> +	  <!-- +		  <check_box +		  name="media_show_within_parcel_btn" +		  control_name="MediaShowWithinParcel" +		  enabled_control="AudioStreamingMedia" +		  value="true" +		  follows="left|bottom|right" +		  height="15" +		  tool_tip="Uncheck this to hide media within the parcel you are standing in" +		  label="Show media within current parcel" +		  left="10"/> +	  --> +	  <check_box +		  name="media_show_outside_parcel_btn" +		  control_name="MediaShowOutsideParcel" +		  enabled_control="AudioStreamingMedia" +		  value="true" +		  follows="left|bottom|right" +		  height="15" +		  tool_tip="Uncheck this to hide media outside the parcel you are standing in" +		  label="Show media outside current parcel" +		  left="10"/> +	  <check_box +		  name="media_show_on_others_btn" +		  control_name="MediaShowOnOthers" +		  enabled_control="AudioStreamingMedia" +		  value="true" +		  follows="left|bottom|right" +		  height="15" +		  tool_tip="Uncheck this to hide media attached to other avatars nearby" +		  label="Show media attached to other avatars" +		  left="10"/> +	</panel> +  </panel> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_prim_media_controls.xml b/indra/newview/skins/default/xui/en/panel_prim_media_controls.xml index e1d8ee241d..6b5f0c3896 100644 --- a/indra/newview/skins/default/xui/en/panel_prim_media_controls.xml +++ b/indra/newview/skins/default/xui/en/panel_prim_media_controls.xml @@ -71,7 +71,7 @@  	  layout="topleft"  	  top="0"  	  left="0" -	  border_size="1" +	  border_size="0"  	  mouse_opaque="false"  	  orientation="horizontal">  	<!-- outer layout_panels center the inner one --> @@ -260,7 +260,7 @@  		top="0"  		height="22"  		min_width="22" -		width="24"> +		width="22">  	  <button  		  name="play_btn"  		  follows="top" @@ -272,7 +272,6 @@  		  hover_glow_amount="0.15"  		  layout="topleft"  		  tool_tip = "Play media" -		  left_delta="2"  		  top="0"  		  height="22"  		  width="22"> @@ -288,7 +287,7 @@  		layout="topleft"  		top="0"  		min_width="22" -		width="24"> +		width="22">  	  <button  		  name="pause_btn"  		  follows="top" @@ -302,7 +301,6 @@  		  top="0"  		  height="22"  		  width="22" -		  left_delta="-1"  		  tool_tip = "Pause media">  		<button.commit_callback  			function="MediaCtrl.Pause" /> diff --git a/indra/newview/skins/default/xui/en/panel_status_bar.xml b/indra/newview/skins/default/xui/en/panel_status_bar.xml index 5754f67045..96c61b69f5 100644 --- a/indra/newview/skins/default/xui/en/panel_status_bar.xml +++ b/indra/newview/skins/default/xui/en/panel_status_bar.xml @@ -3,6 +3,7 @@   background_opaque="true"   background_visible="true"   bg_opaque_color="MouseGray" + chrome="true"    follows="top|right"   height="19"   layout="topleft" @@ -10,6 +11,7 @@   mouse_opaque="false"   name="status"   top="19" + tab_stop="false"    width="1000">      <panel.string       name="StatBarDaysOfWeek"> @@ -73,7 +75,7 @@       pad_bottom="2"       tool_tip="Click to buy more L$"       top="2" -     width="71" /> +     width="45" />      <text       type="string"       font="SansSerifSmall" @@ -86,17 +88,31 @@       left_pad="0"       name="TimeText"       tool_tip="Current time (Pacific)" -     width="89"> +     width="80">          24:00 AM PST      </text>      <button       follows="right|top"       height="15" +     image_selected="Pause_Off" +     image_unselected="Play_Off" +     image_pressed="Play_Press" +     image_pressed_selected="Pause_Press" +     is_toggle="true" +     left_pad="15" +     top="2" +     name="media_toggle_btn" +     tool_tip="Click to toggle media" +     width="16" > +    </button> +    <button +     follows="right|top" +     height="15"       image_selected="AudioMute_Off"       image_pressed="Audio_Press"       image_unselected="Audio_Off"       is_toggle="true" -     left_pad="18" +     left_pad="5"       top="2"       name="volume_btn"       tool_tip="Global Volume Control" | 
