1335 lines
38 KiB
C++
1335 lines
38 KiB
C++
/**
|
|
* @file llpanelnearbymedia.cpp
|
|
* @brief Management interface for muting and controlling nearby media
|
|
*
|
|
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
|
|
* Second Life Viewer Source Code
|
|
* Copyright (C) 2010, Linden Research, Inc.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation;
|
|
* version 2.1 of the License only.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*
|
|
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
|
* $/LicenseInfo$
|
|
*/
|
|
|
|
#include "llviewerprecompiledheaders.h"
|
|
|
|
#include "llpanelnearbymedia.h"
|
|
|
|
#include "llaudioengine.h"
|
|
#include "llcheckboxctrl.h"
|
|
#include "llcombobox.h"
|
|
#include "llresizebar.h"
|
|
#include "llresizehandle.h"
|
|
#include "llscrolllistcolumn.h"
|
|
#include "llscrolllistctrl.h"
|
|
#include "llscrolllistitem.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 "llvieweraudio.h"
|
|
#include "lluictrlfactory.h"
|
|
|
|
#include "llfloaterpreference.h" // for the gear icon
|
|
#include "lltabcontainer.h"
|
|
|
|
#include <stringize.h>
|
|
|
|
#include "lloverlaybar.h"
|
|
#include "llmediaremotectrl.h"
|
|
#include "llchatbar.h"
|
|
#include "lltoolbar.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(bool standalone_panel)
|
|
: mNearbyMediaPanel(nullptr)
|
|
, mMediaList(nullptr)
|
|
, mEnableAllCtrl(nullptr)
|
|
, mDisableAllCtrl(nullptr)
|
|
, mShowCtrl(nullptr)
|
|
, mStopCtrl(nullptr)
|
|
, mPlayCtrl(nullptr)
|
|
, mPauseCtrl(nullptr)
|
|
, mMuteCtrl(nullptr)
|
|
, mVolumeSliderCtrl(nullptr)
|
|
, mZoomCtrl(nullptr)
|
|
, mUnzoomCtrl(nullptr)
|
|
, mVolumeSlider(nullptr)
|
|
, mMuteBtn(nullptr)
|
|
, mDebugInfoVisible(false)
|
|
, mParcelMediaItem(nullptr)
|
|
, mParcelAudioItem(nullptr)
|
|
, mStandalonePanel(standalone_panel)
|
|
{
|
|
mHoverTimer.stop();
|
|
|
|
mParcelAudioAutoStart = gSavedSettings.getBOOL("MediaTentativeAutoPlay");
|
|
/*gSavedSettings.getBOOL(LLViewerMedia::AUTO_PLAY_MEDIA_SETTING) &&
|
|
gSavedSettings.getBOOL("MediaTentativeAutoPlay");*/
|
|
|
|
//gSavedSettings.getControl(LLViewerMedia::AUTO_PLAY_MEDIA_SETTING)->getSignal()->connect(boost::bind(&LLPanelNearByMedia::handleMediaAutoPlayChanged, this, _2));
|
|
|
|
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));
|
|
|
|
//buildFromFile( "panel_nearby_media.xml");
|
|
LLUICtrlFactory::getInstance()->buildPanel(this, "panel_nearby_media.xml");
|
|
}
|
|
|
|
LLPanelNearByMedia::~LLPanelNearByMedia()
|
|
{
|
|
//Wipe the mInNearbyMediaList value for all impls since we don't need them anymore.
|
|
LLViewerMedia::impl_list impls = LLViewerMedia::getPriorityList();
|
|
LLViewerMedia::impl_list::iterator priority_iter;
|
|
for(priority_iter = impls.begin(); priority_iter != impls.end(); priority_iter++)
|
|
{
|
|
(*priority_iter)->setInNearbyMediaList(false);
|
|
}
|
|
}
|
|
|
|
BOOL LLPanelNearByMedia::postBuild()
|
|
{
|
|
LLPanel::postBuild();
|
|
|
|
if(mStandalonePanel)
|
|
{
|
|
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) );
|
|
|
|
p.rect = LLRect( 0, getRect().getHeight(), RESIZE_BAR_THICKNESS, 0);
|
|
p.name = "resizebar_left";
|
|
p.min_size = getRect().getWidth();
|
|
p.side = LLResizeBar::LEFT;
|
|
addChild( LLUICtrlFactory::create<LLResizeBar>(p) );
|
|
|
|
LLResizeHandle::Params resize_handle_p;
|
|
resize_handle_p.rect = LLRect( 0, RESIZE_HANDLE_HEIGHT, RESIZE_HANDLE_WIDTH, 0 );
|
|
resize_handle_p.mouse_opaque(false);
|
|
resize_handle_p.min_width(getRect().getWidth());
|
|
resize_handle_p.min_height(getRect().getHeight());
|
|
resize_handle_p.corner(LLResizeHandle::LEFT_BOTTOM);
|
|
addChild(LLUICtrlFactory::create<LLResizeHandle>(resize_handle_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");
|
|
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");
|
|
mMoreRect = getRect();
|
|
mLessRect = getRect();
|
|
mLessRect.mBottom = minimized_controls->getRect().mBottom;
|
|
|
|
getChild<LLUICtrl>("more_btn")->setVisible(false);
|
|
onMoreLess();
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void LLPanelNearByMedia::handleMediaAutoPlayChanged(const LLSD& newvalue)
|
|
{
|
|
// update mParcelAudioAutoStart if AUTO_PLAY_MEDIA_SETTING changes
|
|
mParcelAudioAutoStart = gSavedSettings.getBOOL(LLViewerMedia::AUTO_PLAY_MEDIA_SETTING) &&
|
|
gSavedSettings.getBOOL("MediaTentativeAutoPlay");
|
|
}
|
|
|
|
/*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)
|
|
{
|
|
if(mStandalonePanel)
|
|
mHoverTimer.start();
|
|
LLPanel::onMouseLeave(x,y,mask);
|
|
}
|
|
|
|
/*virtual*/
|
|
void LLPanelNearByMedia::onTopLost()
|
|
{
|
|
setVisible(FALSE);
|
|
}
|
|
|
|
|
|
/*virtual*/
|
|
void LLPanelNearByMedia::handleVisibilityChange ( BOOL new_visibility )
|
|
{
|
|
if (mStandalonePanel && new_visibility)
|
|
{
|
|
mHoverTimer.start(); // timer will be stopped when mouse hovers over panel
|
|
}
|
|
else
|
|
{
|
|
mHoverTimer.stop();
|
|
}
|
|
}
|
|
|
|
/*virtual*/
|
|
void LLPanelNearByMedia::reshape(S32 width, S32 height, BOOL called_from_parent)
|
|
{
|
|
LLPanel::reshape(width, height, called_from_parent);
|
|
|
|
LLButton* more_btn = findChild<LLButton>("more_btn");
|
|
if (!mStandalonePanel || more_btn && more_btn->getValue().asBoolean())
|
|
{
|
|
mMoreRect = getRect();
|
|
}
|
|
|
|
}
|
|
|
|
const F32 AUTO_CLOSE_FADE_TIME_START= 4.0f;
|
|
const F32 AUTO_CLOSE_FADE_TIME_END = 5.0f;
|
|
|
|
/*virtual*/
|
|
void LLPanelNearByMedia::draw()
|
|
{
|
|
// 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);
|
|
}
|
|
|
|
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);
|
|
}
|
|
}
|
|
|
|
/*virtual*/
|
|
BOOL LLPanelNearByMedia::handleHover(S32 x, S32 y, MASK mask)
|
|
{
|
|
LLPanel::handleHover(x, y, mask);
|
|
|
|
// If we are hovering over this panel, make sure to clear any hovered media
|
|
// ID. Note that the more general solution would be to clear this ID when
|
|
// the mouse leaves the in-scene view, but that proved to be problematic.
|
|
// See EXT-5517
|
|
LLViewerMediaFocus::getInstance()->clearHover();
|
|
|
|
// Always handle
|
|
return true;
|
|
}
|
|
|
|
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]["name"]="media_checkbox_ctrl";
|
|
columns[CHECKBOX_COLUMN]["column"] = "media_checkbox_ctrl";
|
|
columns[CHECKBOX_COLUMN]["type"] = "checkbox";
|
|
//if(mDebugInfoVisible)
|
|
{
|
|
columns[PROXIMITY_COLUMN]["name"]="media_proximity";
|
|
columns[PROXIMITY_COLUMN]["column"] = "media_proximity";
|
|
columns[PROXIMITY_COLUMN]["value"] = "";
|
|
columns[VISIBILITY_COLUMN]["name"]="media_visibility";
|
|
columns[VISIBILITY_COLUMN]["column"] = "media_visibility";
|
|
columns[VISIBILITY_COLUMN]["value"] = "";
|
|
columns[CLASS_COLUMN]["name"]="media_class";
|
|
columns[CLASS_COLUMN]["column"] = "media_class";
|
|
columns[CLASS_COLUMN]["type"] = "text";
|
|
columns[CLASS_COLUMN]["value"] = "";
|
|
}
|
|
columns[NAME_COLUMN]["name"] = "media_name";
|
|
columns[NAME_COLUMN]["column"] = "media_name";
|
|
columns[NAME_COLUMN]["type"] = "text";
|
|
columns[NAME_COLUMN]["value"] = "";
|
|
//if(mDebugInfoVisible)
|
|
{
|
|
columns[DEBUG_COLUMN]["name"] = "media_debug";
|
|
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;
|
|
}
|
|
|
|
extern char const* PRIORITYToString(LLViewerMediaImpl::EPriority priority);
|
|
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/", (F32) sqrt(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 += 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 = LLUI::sColorsGroup->getColor("DefaultListText");
|
|
|
|
// 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 = LLUI::sColorsGroup->getColor("DefaultListText");
|
|
}
|
|
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
|
|
// (and if media is "enabled")
|
|
bool should_include = (choice == MEDIA_CLASS_ALL || choice == MEDIA_CLASS_WITHIN_PARCEL);
|
|
|
|
// First Parcel Media: add or remove it as necessary
|
|
if (gSavedSettings.getBOOL("AudioStreamingMedia") &&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 (don't show if disabled in prefs)
|
|
if (should_include && LLViewerMedia::hasParcelAudio() && gSavedSettings.getBOOL("AudioStreamingMusic"))
|
|
{
|
|
// 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();
|
|
|
|
std::string url;
|
|
url = LLViewerMedia::getParcelAudioURL();
|
|
|
|
updateListItem(mParcelAudioItem,
|
|
mParcelAudioName,
|
|
url,
|
|
-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();
|
|
mParcelAudioItem = NULL;
|
|
mParcelMediaItem = NULL;
|
|
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((gSavedSettings.getBOOL("AudioStreamingMusic") ||
|
|
gSavedSettings.getBOOL("AudioStreamingMedia")) &&
|
|
(LLViewerMedia::isAnyMediaShowing() ||
|
|
LLViewerMedia::isParcelMediaPlaying() ||
|
|
LLViewerMedia::isParcelAudioPlaying()));
|
|
|
|
mEnableAllCtrl->setEnabled( (gSavedSettings.getBOOL("AudioStreamingMusic") ||
|
|
gSavedSettings.getBOOL("AudioStreamingMedia")) &&
|
|
(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
|
|
{
|
|
onClickParcelAudioPlay();
|
|
}
|
|
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::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
|
|
{
|
|
LLViewerParcelMedia::playStreamingMusic(LLViewerParcelMgr::getInstance()->getAgentParcel());
|
|
}
|
|
}
|
|
|
|
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::show(NULL);
|
|
LLFloaterPreference* prefsfloater = LLFloaterPreference::sInstance;
|
|
|
|
if (prefsfloater)
|
|
{
|
|
// grab the 'audio' panel from the preferences floater and
|
|
// bring it the front!
|
|
LLTabContainer* tabcontainer = prefsfloater->getChild<LLTabContainer>("pref core");
|
|
if (tabcontainer)
|
|
{
|
|
tabcontainer->selectTabByName("Media panel");
|
|
}
|
|
}
|
|
}
|
|
|
|
void LLPanelNearByMedia::onMoreLess()
|
|
{
|
|
bool is_more = !mStandalonePanel || getChild<LLButton>("more_btn")->getToggleState();
|
|
mNearbyMediaPanel->setVisible(is_more);
|
|
|
|
// enable resizing when expanded
|
|
if(mStandalonePanel)
|
|
getChildView("resizebar_bottom")->setEnabled(is_more);
|
|
|
|
LLRect new_rect = is_more ? mMoreRect : mLessRect;
|
|
new_rect.translate(getRect().mRight - new_rect.mRight, getRect().mTop - new_rect.mTop);
|
|
|
|
setShape(new_rect);
|
|
|
|
getChild<LLUICtrl>("more_btn")->setVisible(mStandalonePanel);
|
|
}
|
|
|
|
void LLPanelNearByMedia::updateControls()
|
|
{
|
|
LLUUID selected_media_id = mMediaList->getValue().asUUID();
|
|
|
|
if (selected_media_id == PARCEL_AUDIO_LIST_ITEM_UUID)
|
|
{
|
|
if (!LLViewerMedia::hasParcelAudio() || !gSavedSettings.getBOOL("AudioStreamingMusic"))
|
|
{
|
|
// disable controls if audio streaming music is disabled from preference
|
|
showDisabledControls();
|
|
}
|
|
else {
|
|
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() || !gSavedSettings.getBOOL("AudioStreamingMedia"))
|
|
{
|
|
// disable controls if audio streaming media is disabled from preference
|
|
showDisabledControls();
|
|
}
|
|
else {
|
|
LLViewerMediaImpl* impl = LLViewerParcelMedia::getParcelMedia();
|
|
if (NULL == impl)
|
|
{
|
|
// Just means it hasn't started yet
|
|
showBasicControls(false, false, false, false, 0);
|
|
}
|
|
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,
|
|
impl->getVolume() == 0.0,
|
|
impl->getVolume());
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
LLViewerMediaImpl* impl = LLViewerMedia::getMediaImplFromTextureID(selected_media_id);
|
|
|
|
if (NULL == impl || !gSavedSettings.getBOOL("AudioStreamingMedia"))
|
|
{
|
|
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(),
|
|
impl->getVolume() == 0.0,
|
|
impl->getVolume());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void LLPanelNearByMedia::showBasicControls(bool playing, bool include_zoom, bool is_zoomed, bool muted, F32 volume)
|
|
{
|
|
mStopCtrl->setVisible(playing);
|
|
mPlayCtrl->setVisible(!playing);
|
|
mPauseCtrl->setVisible(false);
|
|
mVolumeSliderCtrl->setVisible(true);
|
|
mMuteCtrl->setVisible(true);
|
|
mMuteBtn->setValue(muted);
|
|
mVolumeSlider->setValue(volume);
|
|
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)
|
|
{
|
|
if (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)
|
|
{
|
|
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->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;
|
|
}
|
|
}
|
|
|
|
// static
|
|
void* createNearbyMediaPanel(void* userdata)
|
|
{
|
|
return new LLPanelNearByMedia(false);
|
|
}
|
|
|
|
LLFloaterNearbyMedia::LLFloaterNearbyMedia() : mPanel(NULL)
|
|
{
|
|
mFactoryMap["nearby_media"] = LLCallbackMap(createNearbyMediaPanel, this);
|
|
LLUICtrlFactory::getInstance()->buildFloater(this,"floater_nearby_media.xml",&mFactoryMap,false);
|
|
}
|
|
|
|
/*virtual*/ BOOL LLFloaterNearbyMedia::postBuild()
|
|
{
|
|
mPanel = getChild<LLPanelNearByMedia>("nearby_media",false,false);
|
|
return LLFloater::postBuild();
|
|
}
|
|
|
|
// static
|
|
void LLFloaterNearbyMedia::updateClass()
|
|
{
|
|
if(gSavedSettings.getBOOL("ShowNearbyMediaFloater"))
|
|
LLFloaterNearbyMedia::getInstance()->open();
|
|
else if(LLFloaterNearbyMedia::instanceExists())
|
|
LLFloaterNearbyMedia::getInstance()->close();
|
|
}
|
|
|
|
void LLFloaterNearbyMedia::onClose(bool app_quitting)
|
|
{
|
|
if(!app_quitting)
|
|
gSavedSettings.setBOOL("ShowNearbyMediaFloater", false);
|
|
LLFloater::onClose(app_quitting);
|
|
}
|
|
|
|
void LLFloaterNearbyMedia::onOpen()
|
|
{
|
|
//Mess around with control rect to not change unless the user actually tweaked it..
|
|
LLRect rect = gSavedSettings.getRect("FloaterNearbyMediaRect");
|
|
if(!rect.isEmpty())
|
|
{
|
|
setRectControl("FloaterNearbyMediaRect");
|
|
applyRectControl();
|
|
}
|
|
else
|
|
{
|
|
const LLRect media_rect = gOverlayBar->mMediaRemote->calcScreenRect();
|
|
setOrigin(media_rect.mLeft - getRect().getWidth(), media_rect.mBottom + gOverlayBar->mChatBar->getRect().getHeight());
|
|
}
|
|
gSavedSettings.setBOOL("ShowNearbyMediaFloater", true);
|
|
}
|
|
|
|
// virtual
|
|
void LLFloaterNearbyMedia::handleReshape(const LLRect& new_rect, bool by_user)
|
|
{
|
|
if(by_user && getRectControl().empty())
|
|
{
|
|
setRectControl("FloaterNearbyMediaRect");
|
|
}
|
|
LLFloater::handleReshape(new_rect, by_user);
|
|
}
|
|
|