merge changes for storm-591
commit
f54caff1e4
|
|
@ -583,6 +583,7 @@ Jonathan Yap
|
|||
STORM-1639
|
||||
STORM-910
|
||||
STORM-1642
|
||||
STORM-591
|
||||
STORM-1105
|
||||
STORM-1679
|
||||
STORM-1222
|
||||
|
|
@ -924,6 +925,7 @@ Robin Cornelius
|
|||
SNOW-599
|
||||
SNOW-747
|
||||
STORM-422
|
||||
STORM-591
|
||||
STORM-960
|
||||
STORM-1019
|
||||
STORM-1095
|
||||
|
|
|
|||
|
|
@ -1,378 +0,0 @@
|
|||
/**
|
||||
* @file lloverlaybar.cpp
|
||||
* @brief LLOverlayBar class implementation
|
||||
*
|
||||
* $LicenseInfo:firstyear=2002&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$
|
||||
*/
|
||||
|
||||
// Temporary buttons that appear at the bottom of the screen when you
|
||||
// are in a mode.
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "lloverlaybar.h"
|
||||
|
||||
#include "llaudioengine.h"
|
||||
#include "llrender.h"
|
||||
#include "llagent.h"
|
||||
#include "llbutton.h"
|
||||
#include "llfocusmgr.h"
|
||||
#include "llimview.h"
|
||||
#include "llmediaremotectrl.h"
|
||||
#include "llparcel.h"
|
||||
#include "lltextbox.h"
|
||||
#include "llui.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "llviewertexturelist.h"
|
||||
#include "llviewerjoystick.h"
|
||||
#include "llviewermedia.h"
|
||||
#include "llviewermenu.h" // handle_reset_view()
|
||||
#include "llviewermedia.h"
|
||||
#include "llviewerparcelmedia.h"
|
||||
#include "llviewerparcelmgr.h"
|
||||
#include "lluictrlfactory.h"
|
||||
#include "llviewerwindow.h"
|
||||
#include "llvoiceclient.h"
|
||||
#include "llvoavatarself.h"
|
||||
#include "llvoiceremotectrl.h"
|
||||
#include "llmediactrl.h"
|
||||
#include "llselectmgr.h"
|
||||
|
||||
//
|
||||
// Globals
|
||||
//
|
||||
|
||||
LLOverlayBar *gOverlayBar = NULL;
|
||||
|
||||
extern S32 MENU_BAR_HEIGHT;
|
||||
|
||||
//
|
||||
// Functions
|
||||
//
|
||||
|
||||
|
||||
|
||||
void* LLOverlayBar::createMediaRemote(void* userdata)
|
||||
{
|
||||
LLOverlayBar *self = (LLOverlayBar*)userdata;
|
||||
self->mMediaRemote = new LLMediaRemoteCtrl ();
|
||||
return self->mMediaRemote;
|
||||
}
|
||||
|
||||
void* LLOverlayBar::createVoiceRemote(void* userdata)
|
||||
{
|
||||
LLOverlayBar *self = (LLOverlayBar*)userdata;
|
||||
self->mVoiceRemote = new LLVoiceRemoteCtrl();
|
||||
return self->mVoiceRemote;
|
||||
}
|
||||
|
||||
LLOverlayBar::LLOverlayBar()
|
||||
: LLPanel(),
|
||||
mMediaRemote(NULL),
|
||||
mVoiceRemote(NULL),
|
||||
mMusicState(STOPPED)
|
||||
{
|
||||
setMouseOpaque(FALSE);
|
||||
setIsChrome(TRUE);
|
||||
|
||||
mBuilt = false;
|
||||
|
||||
mFactoryMap["media_remote"] = LLCallbackMap(LLOverlayBar::createMediaRemote, this);
|
||||
mFactoryMap["voice_remote"] = LLCallbackMap(LLOverlayBar::createVoiceRemote, this);
|
||||
|
||||
LLUICtrlFactory::getInstance()->buildPanel(this, "panel_overlaybar.xml");
|
||||
}
|
||||
|
||||
BOOL LLOverlayBar::postBuild()
|
||||
{
|
||||
childSetAction("Set Not Busy",onClickSetNotBusy,this);
|
||||
childSetAction("Mouselook",onClickMouselook,this);
|
||||
childSetAction("Stand Up",onClickStandUp,this);
|
||||
childSetAction("Flycam",onClickFlycam,this);
|
||||
childSetVisible("chat_bar", gSavedSettings.getBOOL("ChatVisible"));
|
||||
|
||||
mVoiceRemote->expandOrCollapse();
|
||||
mMediaRemote->expandOrCollapse();
|
||||
|
||||
setFocusRoot(TRUE);
|
||||
mBuilt = true;
|
||||
|
||||
layoutButtons();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
LLOverlayBar::~LLOverlayBar()
|
||||
{
|
||||
// LLView destructor cleans up children
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLOverlayBar::reshape(S32 width, S32 height, BOOL called_from_parent)
|
||||
{
|
||||
LLView::reshape(width, height, called_from_parent);
|
||||
|
||||
if (mBuilt)
|
||||
{
|
||||
layoutButtons();
|
||||
}
|
||||
}
|
||||
|
||||
void LLOverlayBar::layoutButtons()
|
||||
{
|
||||
LLView* state_buttons_panel = getChildView("state_buttons");
|
||||
|
||||
if (state_buttons_panel->getVisible())
|
||||
{
|
||||
LLViewQuery query;
|
||||
LLWidgetTypeFilter<LLButton> widget_filter;
|
||||
query.addPreFilter(LLEnabledFilter::getInstance());
|
||||
query.addPreFilter(&widget_filter);
|
||||
|
||||
child_list_t button_list = query(state_buttons_panel);
|
||||
|
||||
const S32 MAX_BAR_WIDTH = 600;
|
||||
S32 bar_width = llclamp(state_buttons_panel->getRect().getWidth(), 0, MAX_BAR_WIDTH);
|
||||
|
||||
// calculate button widths
|
||||
const S32 MAX_BUTTON_WIDTH = 150;
|
||||
const S32 STATUS_BAR_PAD = 10;
|
||||
S32 segment_width = llclamp(lltrunc((F32)(bar_width) / (F32)button_list.size()), 0, MAX_BUTTON_WIDTH);
|
||||
S32 btn_width = segment_width - STATUS_BAR_PAD;
|
||||
|
||||
// Evenly space all buttons, starting from left
|
||||
S32 left = 0;
|
||||
S32 bottom = 1;
|
||||
|
||||
for (child_list_reverse_iter_t child_iter = button_list.rbegin();
|
||||
child_iter != button_list.rend(); ++child_iter)
|
||||
{
|
||||
LLView *view = *child_iter;
|
||||
LLRect r = view->getRect();
|
||||
r.setOriginAndSize(left, bottom, btn_width, r.getHeight());
|
||||
view->setRect(r);
|
||||
left += segment_width;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Per-frame updates of visibility
|
||||
void LLOverlayBar::refresh()
|
||||
{
|
||||
BOOL buttons_changed = FALSE;
|
||||
|
||||
BOOL im_received = gIMMgr->getIMReceived();
|
||||
LLButton* button = getChild<LLButton>("IM Received");
|
||||
if (button && button->getVisible() != im_received)
|
||||
{
|
||||
button->setVisible(im_received);
|
||||
sendChildToFront(button);
|
||||
moveChildToBackOfTabGroup(button);
|
||||
buttons_changed = TRUE;
|
||||
}
|
||||
|
||||
BOOL busy = gAgent.getBusy();
|
||||
button = getChild<LLButton>("Set Not Busy");
|
||||
if (button && button->getVisible() != busy)
|
||||
{
|
||||
button->setVisible(busy);
|
||||
sendChildToFront(button);
|
||||
moveChildToBackOfTabGroup(button);
|
||||
buttons_changed = TRUE;
|
||||
}
|
||||
|
||||
BOOL flycam = LLViewerJoystick::getInstance()->getOverrideCamera();
|
||||
button = getChild<LLButton>("Flycam");
|
||||
if (button && button->getVisible() != flycam)
|
||||
{
|
||||
button->setVisible(flycam);
|
||||
sendChildToFront(button);
|
||||
moveChildToBackOfTabGroup(button);
|
||||
buttons_changed = TRUE;
|
||||
}
|
||||
|
||||
BOOL mouselook_grabbed;
|
||||
mouselook_grabbed = gAgent.isControlGrabbed(CONTROL_ML_LBUTTON_DOWN_INDEX)
|
||||
|| gAgent.isControlGrabbed(CONTROL_ML_LBUTTON_UP_INDEX);
|
||||
button = getChild<LLButton>("Mouselook");
|
||||
|
||||
if (button && button->getVisible() != mouselook_grabbed)
|
||||
{
|
||||
button->setVisible(mouselook_grabbed);
|
||||
sendChildToFront(button);
|
||||
moveChildToBackOfTabGroup(button);
|
||||
buttons_changed = TRUE;
|
||||
}
|
||||
|
||||
BOOL sitting = FALSE;
|
||||
if (gAgent.getAvatarObject())
|
||||
{
|
||||
sitting = gAgent.getAvatarObject()->isSitting();
|
||||
}
|
||||
button = getChild<LLButton>("Stand Up");
|
||||
|
||||
if (button && button->getVisible() != sitting)
|
||||
{
|
||||
button->setVisible(sitting);
|
||||
sendChildToFront(button);
|
||||
moveChildToBackOfTabGroup(button);
|
||||
buttons_changed = TRUE;
|
||||
}
|
||||
|
||||
|
||||
moveChildToBackOfTabGroup(mMediaRemote);
|
||||
moveChildToBackOfTabGroup(mVoiceRemote);
|
||||
|
||||
// turn off the whole bar in mouselook
|
||||
if (gAgent.cameraMouselook())
|
||||
{
|
||||
childSetVisible("media_remote_container", FALSE);
|
||||
childSetVisible("voice_remote_container", FALSE);
|
||||
childSetVisible("state_buttons", FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
// update "remotes"
|
||||
childSetVisible("media_remote_container", TRUE);
|
||||
childSetVisible("voice_remote_container", LLVoiceClient::getInstance()->voiceEnabled());
|
||||
childSetVisible("state_buttons", TRUE);
|
||||
}
|
||||
|
||||
// always let user toggle into and out of chatbar
|
||||
childSetVisible("chat_bar", gSavedSettings.getBOOL("ChatVisible"));
|
||||
|
||||
if (buttons_changed)
|
||||
{
|
||||
layoutButtons();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// Static functions
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
// static
|
||||
void LLOverlayBar::onClickSetNotBusy(void*)
|
||||
{
|
||||
gAgent.clearBusy();
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
void LLOverlayBar::onClickFlycam(void*)
|
||||
{
|
||||
LLViewerJoystick::getInstance()->toggleFlycam();
|
||||
}
|
||||
|
||||
// static
|
||||
void LLOverlayBar::onClickResetView(void* data)
|
||||
{
|
||||
handle_reset_view();
|
||||
}
|
||||
|
||||
//static
|
||||
void LLOverlayBar::onClickMouselook(void*)
|
||||
{
|
||||
gAgent.changeCameraToMouselook();
|
||||
}
|
||||
|
||||
//static
|
||||
void LLOverlayBar::onClickStandUp(void*)
|
||||
{
|
||||
LLSelectMgr::getInstance()->deselectAllForStandingUp();
|
||||
gAgent.setControlFlags(AGENT_CONTROL_STAND_UP);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// static media helpers
|
||||
// *TODO: Move this into an audio manager abstraction
|
||||
//static
|
||||
void LLOverlayBar::mediaStop(void*)
|
||||
{
|
||||
if (!gOverlayBar)
|
||||
{
|
||||
// return;
|
||||
}
|
||||
LLViewerParcelMedia::stop();
|
||||
}
|
||||
//static
|
||||
void LLOverlayBar::toggleMediaPlay(void*)
|
||||
{
|
||||
if (!gOverlayBar)
|
||||
{
|
||||
// return;
|
||||
}
|
||||
|
||||
|
||||
if (LLViewerParcelMedia::getStatus() == LLViewerMediaImpl::MEDIA_PAUSED)
|
||||
{
|
||||
LLViewerParcelMedia::start();
|
||||
}
|
||||
else if(LLViewerParcelMedia::getStatus() == LLViewerMediaImpl::MEDIA_PLAYING)
|
||||
{
|
||||
LLViewerParcelMedia::pause();
|
||||
}
|
||||
else
|
||||
{
|
||||
LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
|
||||
if (parcel)
|
||||
{
|
||||
LLViewerParcelMedia::play(parcel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
void LLOverlayBar::toggleMusicPlay(void*)
|
||||
{
|
||||
if (gAudiop->isInternetStreamPlaying() != 1)
|
||||
{
|
||||
if (gAudiop)
|
||||
{
|
||||
LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
|
||||
if ( parcel )
|
||||
{
|
||||
// this doesn't work properly when crossing parcel boundaries - even when the
|
||||
// stream is stopped, it doesn't return the right thing - commenting out for now.
|
||||
// if ( gAudiop->isInternetStreamPlaying() == 0 )
|
||||
{
|
||||
gAudiop->startInternetStream(parcel->getMusicURL());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//else
|
||||
//{
|
||||
// gOverlayBar->mMusicState = PAUSED; // desired state
|
||||
// if (gAudiop)
|
||||
// {
|
||||
// gAudiop->pauseInternetStream(1);
|
||||
// }
|
||||
//}
|
||||
else
|
||||
{
|
||||
if (gAudiop)
|
||||
{
|
||||
gAudiop->stopInternetStream();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,95 +0,0 @@
|
|||
/**
|
||||
* @file lloverlaybar.h
|
||||
* @brief LLOverlayBar class definition
|
||||
*
|
||||
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLOVERLAYBAR_H
|
||||
#define LL_LLOVERLAYBAR_H
|
||||
|
||||
#include "llpanel.h"
|
||||
|
||||
// "Constants" loaded from settings.xml at start time
|
||||
extern S32 STATUS_BAR_HEIGHT;
|
||||
|
||||
class LLButton;
|
||||
class LLLineEditor;
|
||||
class LLMediaRemoteCtrl;
|
||||
class LLMessageSystem;
|
||||
class LLTextBox;
|
||||
class LLTextEditor;
|
||||
class LLUICtrl;
|
||||
class LLUUID;
|
||||
class LLFrameTimer;
|
||||
class LLStatGraph;
|
||||
class LLSlider;
|
||||
class LLVoiceRemoteCtrl;
|
||||
|
||||
class LLOverlayBar
|
||||
: public LLPanel
|
||||
{
|
||||
public:
|
||||
LLOverlayBar();
|
||||
~LLOverlayBar();
|
||||
|
||||
/*virtual*/ void refresh();
|
||||
/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
|
||||
/*virtual*/ BOOL postBuild();
|
||||
|
||||
void layoutButtons();
|
||||
|
||||
// helpers for returning desired state
|
||||
BOOL musicPlaying() { return mMusicState == PLAYING; }
|
||||
|
||||
static void onClickSetNotBusy(void* data);
|
||||
static void onClickMouselook(void* data);
|
||||
static void onClickStandUp(void* data);
|
||||
static void onClickResetView(void* data);
|
||||
static void onClickFlycam(void* data);
|
||||
|
||||
//static media helper functions
|
||||
static void toggleMediaPlay(void*);
|
||||
static void toggleMusicPlay(void*);
|
||||
static void musicPause(void*);
|
||||
static void musicStop(void*);
|
||||
static void mediaStop(void*);
|
||||
|
||||
static void toggleAudioVolumeFloater(void*);
|
||||
|
||||
protected:
|
||||
static void* createMediaRemote(void* userdata);
|
||||
static void* createVoiceRemote(void* userdata);
|
||||
|
||||
void enableMediaButtons();
|
||||
|
||||
protected:
|
||||
LLMediaRemoteCtrl* mMediaRemote;
|
||||
LLVoiceRemoteCtrl* mVoiceRemote;
|
||||
bool mBuilt; // dialog constructed yet?
|
||||
enum { STOPPED=0, PLAYING=1, PAUSED=2 };
|
||||
S32 mMusicState;
|
||||
};
|
||||
|
||||
extern LLOverlayBar* gOverlayBar;
|
||||
|
||||
#endif
|
||||
|
|
@ -52,6 +52,7 @@
|
|||
#include "llvovolume.h"
|
||||
#include "llstatusbar.h"
|
||||
#include "llsdutil.h"
|
||||
#include "llvieweraudio.h"
|
||||
|
||||
#include "llfloaterreg.h"
|
||||
#include "llfloaterpreference.h" // for the gear icon
|
||||
|
|
@ -807,14 +808,26 @@ bool LLPanelNearByMedia::setDisabled(const LLUUID &row_id, bool disabled)
|
|||
{
|
||||
if (row_id == PARCEL_AUDIO_LIST_ITEM_UUID)
|
||||
{
|
||||
if (disabled) onClickParcelAudioStop();
|
||||
else onClickParcelAudioStart();
|
||||
if (disabled)
|
||||
{
|
||||
onClickParcelAudioStop();
|
||||
}
|
||||
else
|
||||
{
|
||||
onClickParcelAudioPlay();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if (row_id == PARCEL_MEDIA_LIST_ITEM_UUID)
|
||||
{
|
||||
if (disabled) onClickDisableParcelMedia();
|
||||
else onClickEnableParcelMedia();
|
||||
if (disabled)
|
||||
{
|
||||
onClickDisableParcelMedia();
|
||||
}
|
||||
else
|
||||
{
|
||||
onClickEnableParcelMedia();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
|
|
@ -857,24 +870,11 @@ 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;
|
||||
|
||||
|
|
@ -883,8 +883,9 @@ void LLPanelNearByMedia::onClickParcelAudioPlay()
|
|||
// 'false' means unpause
|
||||
gAudiop->pauseInternetStream(false);
|
||||
}
|
||||
else {
|
||||
gAudiop->startInternetStream(LLViewerMedia::getParcelAudioURL());
|
||||
else
|
||||
{
|
||||
LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLViewerMedia::getParcelAudioURL());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -894,11 +895,10 @@ void LLPanelNearByMedia::onClickParcelAudioStop()
|
|||
// re-start audio when i.e. they move to another parcel, until
|
||||
// they explicitly start it again.
|
||||
mParcelAudioAutoStart = false;
|
||||
|
||||
if (!gAudiop)
|
||||
return;
|
||||
|
||||
gAudiop->stopInternetStream();
|
||||
LLViewerAudio::getInstance()->stopInternetStreamWithAutoFade();
|
||||
}
|
||||
|
||||
void LLPanelNearByMedia::onClickParcelAudioPause()
|
||||
|
|
|
|||
|
|
@ -115,7 +115,6 @@ private:
|
|||
void onClickParcelMediaPause();
|
||||
void onClickParcelAudioPlay();
|
||||
void onClickParcelAudioStop();
|
||||
void onClickParcelAudioStart();
|
||||
void onClickParcelAudioPause();
|
||||
void onCheckAutoPlay();
|
||||
void onAdvancedButtonClick();
|
||||
|
|
|
|||
|
|
@ -37,9 +37,226 @@
|
|||
#include "llvoiceclient.h"
|
||||
#include "llviewermedia.h"
|
||||
#include "llprogressview.h"
|
||||
#include "llcallbacklist.h"
|
||||
#include "llstartup.h"
|
||||
#include "llviewerparcelmgr.h"
|
||||
#include "llparcel.h"
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
|
||||
LLViewerAudio::LLViewerAudio() :
|
||||
mDone(true),
|
||||
mFadeState(FADE_IDLE),
|
||||
mFadeTime(),
|
||||
mIdleListnerActive(false),
|
||||
mForcedTeleportFade(false)
|
||||
{
|
||||
mTeleportFailedConnection = LLViewerParcelMgr::getInstance()->
|
||||
setTeleportFailedCallback(boost::bind(&LLViewerAudio::onTeleportFailed, this));
|
||||
}
|
||||
|
||||
LLViewerAudio::~LLViewerAudio()
|
||||
{
|
||||
mTeleportFailedConnection.disconnect();
|
||||
}
|
||||
|
||||
void LLViewerAudio::registerIdleListener()
|
||||
{
|
||||
if(mIdleListnerActive==false)
|
||||
{
|
||||
mIdleListnerActive = true;
|
||||
doOnIdleRepeating(boost::bind(boost::bind(&LLViewerAudio::onIdleUpdate, this)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void LLViewerAudio::startInternetStreamWithAutoFade(std::string streamURI)
|
||||
{
|
||||
// Old and new stream are identical
|
||||
if (mNextStreamURI == streamURI)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Record the URI we are going to be switching to
|
||||
mNextStreamURI = streamURI;
|
||||
|
||||
switch (mFadeState)
|
||||
{
|
||||
case FADE_IDLE:
|
||||
// If a stream is playing fade it out first
|
||||
if (!gAudiop->getInternetStreamURL().empty())
|
||||
{
|
||||
// The order of these tests is important, state FADE_OUT will be processed below
|
||||
mFadeState = FADE_OUT;
|
||||
}
|
||||
// Otherwise the new stream can be faded in
|
||||
else
|
||||
{
|
||||
mFadeState = FADE_IN;
|
||||
gAudiop->startInternetStream(mNextStreamURI);
|
||||
startFading();
|
||||
registerIdleListener();
|
||||
break;
|
||||
}
|
||||
|
||||
case FADE_OUT:
|
||||
startFading();
|
||||
registerIdleListener();
|
||||
break;
|
||||
|
||||
case FADE_IN:
|
||||
registerIdleListener();
|
||||
break;
|
||||
|
||||
default:
|
||||
llwarns << "Unknown fading state: " << mFadeState << llendl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// A return of false from onIdleUpdate means it will be called again next idle update.
|
||||
// A return of true means we have finished with it and the callback will be deleted.
|
||||
bool LLViewerAudio::onIdleUpdate()
|
||||
{
|
||||
bool fadeIsFinished = false;
|
||||
|
||||
// There is a delay in the login sequence between when the parcel information has
|
||||
// arrived and the music stream is started and when the audio system is called to set
|
||||
// initial volume levels. This code extends the fade time so you hear a full fade in.
|
||||
if ((LLStartUp::getStartupState() < STATE_STARTED))
|
||||
{
|
||||
stream_fade_timer.reset();
|
||||
stream_fade_timer.setTimerExpirySec(mFadeTime);
|
||||
}
|
||||
|
||||
if (mDone)
|
||||
{
|
||||
// This should be a rare or never occurring state.
|
||||
if (mFadeState == FADE_IDLE)
|
||||
{
|
||||
deregisterIdleListener();
|
||||
fadeIsFinished = true; // Stop calling onIdleUpdate
|
||||
}
|
||||
|
||||
// we have finished the current fade operation
|
||||
if (mFadeState == FADE_OUT)
|
||||
{
|
||||
// Clear URI
|
||||
gAudiop->startInternetStream(LLStringUtil::null);
|
||||
gAudiop->stopInternetStream();
|
||||
|
||||
if (!mNextStreamURI.empty())
|
||||
{
|
||||
mFadeState = FADE_IN;
|
||||
gAudiop->startInternetStream(mNextStreamURI);
|
||||
startFading();
|
||||
}
|
||||
else
|
||||
{
|
||||
mFadeState = FADE_IDLE;
|
||||
deregisterIdleListener();
|
||||
fadeIsFinished = true; // Stop calling onIdleUpdate
|
||||
}
|
||||
}
|
||||
else if (mFadeState == FADE_IN)
|
||||
{
|
||||
if (mNextStreamURI != gAudiop->getInternetStreamURL())
|
||||
{
|
||||
mFadeState = FADE_OUT;
|
||||
startFading();
|
||||
}
|
||||
else
|
||||
{
|
||||
mFadeState = FADE_IDLE;
|
||||
deregisterIdleListener();
|
||||
fadeIsFinished = true; // Stop calling onIdleUpdate
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return fadeIsFinished;
|
||||
}
|
||||
|
||||
void LLViewerAudio::stopInternetStreamWithAutoFade()
|
||||
{
|
||||
mFadeState = FADE_IDLE;
|
||||
mNextStreamURI = LLStringUtil::null;
|
||||
mDone = true;
|
||||
|
||||
gAudiop->startInternetStream(LLStringUtil::null);
|
||||
gAudiop->stopInternetStream();
|
||||
}
|
||||
|
||||
void LLViewerAudio::startFading()
|
||||
{
|
||||
const F32 AUDIO_MUSIC_FADE_IN_TIME = 3.0f;
|
||||
const F32 AUDIO_MUSIC_FADE_OUT_TIME = 2.0f;
|
||||
// This minimum fade time prevents divide by zero and negative times
|
||||
const F32 AUDIO_MUSIC_MINIMUM_FADE_TIME = 0.01f;
|
||||
|
||||
if(mDone)
|
||||
{
|
||||
// The fade state here should only be one of FADE_IN or FADE_OUT, but, in case it is not,
|
||||
// rather than check for both states assume a fade in and check for the fade out case.
|
||||
mFadeTime = AUDIO_MUSIC_FADE_IN_TIME;
|
||||
if (LLViewerAudio::getInstance()->getFadeState() == LLViewerAudio::FADE_OUT)
|
||||
{
|
||||
mFadeTime = AUDIO_MUSIC_FADE_OUT_TIME;
|
||||
}
|
||||
|
||||
// Prevent invalid fade time
|
||||
mFadeTime = llmax(mFadeTime, AUDIO_MUSIC_MINIMUM_FADE_TIME);
|
||||
|
||||
stream_fade_timer.reset();
|
||||
stream_fade_timer.setTimerExpirySec(mFadeTime);
|
||||
mDone = false;
|
||||
}
|
||||
}
|
||||
|
||||
F32 LLViewerAudio::getFadeVolume()
|
||||
{
|
||||
F32 fade_volume = 1.0f;
|
||||
|
||||
if (stream_fade_timer.hasExpired())
|
||||
{
|
||||
mDone = true;
|
||||
// If we have been fading out set volume to 0 until the next fade state occurs to prevent
|
||||
// an audio transient.
|
||||
if (LLViewerAudio::getInstance()->getFadeState() == LLViewerAudio::FADE_OUT)
|
||||
{
|
||||
fade_volume = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
if (!mDone)
|
||||
{
|
||||
// Calculate how far we are into the fade time
|
||||
fade_volume = stream_fade_timer.getElapsedTimeF32() / mFadeTime;
|
||||
|
||||
if (LLViewerAudio::getInstance()->getFadeState() == LLViewerAudio::FADE_OUT)
|
||||
{
|
||||
// If we are not fading in then we are fading out, so invert the fade
|
||||
// direction; start loud and move towards zero volume.
|
||||
fade_volume = 1.0f - fade_volume;
|
||||
}
|
||||
}
|
||||
|
||||
return fade_volume;
|
||||
}
|
||||
|
||||
void LLViewerAudio::onTeleportFailed()
|
||||
{
|
||||
if (gAudiop)
|
||||
{
|
||||
LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
|
||||
if (parcel)
|
||||
{
|
||||
mNextStreamURI = parcel->getMusicURL();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void init_audio()
|
||||
{
|
||||
if (!gAudiop)
|
||||
|
|
@ -142,12 +359,25 @@ void audio_update_volume(bool force_update)
|
|||
|
||||
// Streaming Music
|
||||
if (gAudiop)
|
||||
{
|
||||
{
|
||||
if (progress_view_visible && !LLViewerAudio::getInstance()->getForcedTeleportFade())
|
||||
{
|
||||
LLViewerAudio::getInstance()->setForcedTeleportFade(true);
|
||||
LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLStringUtil::null);
|
||||
LLViewerAudio::getInstance()->setNextStreamURI(LLStringUtil::null);
|
||||
}
|
||||
|
||||
if (!progress_view_visible && LLViewerAudio::getInstance()->getForcedTeleportFade() == true)
|
||||
{
|
||||
LLViewerAudio::getInstance()->setForcedTeleportFade(false);
|
||||
}
|
||||
|
||||
F32 music_volume = gSavedSettings.getF32("AudioLevelMusic");
|
||||
BOOL music_muted = gSavedSettings.getBOOL("MuteMusic");
|
||||
music_volume = mute_volume * master_volume * music_volume;
|
||||
gAudiop->setInternetStreamGain ( music_muted || progress_view_visible ? 0.f : music_volume );
|
||||
|
||||
F32 fade_volume = LLViewerAudio::getInstance()->getFadeVolume();
|
||||
|
||||
music_volume = mute_volume * master_volume * music_volume * fade_volume;
|
||||
gAudiop->setInternetStreamGain (music_muted ? 0.f : music_volume);
|
||||
}
|
||||
|
||||
// Streaming Media
|
||||
|
|
|
|||
|
|
@ -27,6 +27,9 @@
|
|||
#ifndef LL_VIEWERAUDIO_H
|
||||
#define LL_VIEWERAUDIO_H
|
||||
|
||||
#include "llframetimer.h"
|
||||
#include "llsingleton.h"
|
||||
|
||||
// comment out to turn off wind
|
||||
#define kAUDIO_ENABLE_WIND
|
||||
//#define kAUDIO_ENABLE_WATER 1 // comment out to turn off water
|
||||
|
|
@ -38,4 +41,48 @@ void audio_update_volume(bool force_update = true);
|
|||
void audio_update_listener();
|
||||
void audio_update_wind(bool force_update = true);
|
||||
|
||||
class LLViewerAudio : public LLSingleton<LLViewerAudio>
|
||||
{
|
||||
public:
|
||||
|
||||
enum EFadeState
|
||||
{
|
||||
FADE_IDLE,
|
||||
FADE_IN,
|
||||
FADE_OUT,
|
||||
};
|
||||
|
||||
LLViewerAudio();
|
||||
virtual ~LLViewerAudio();
|
||||
|
||||
void startInternetStreamWithAutoFade(std::string streamURI);
|
||||
void stopInternetStreamWithAutoFade();
|
||||
|
||||
bool onIdleUpdate();
|
||||
|
||||
EFadeState getFadeState() { return mFadeState; }
|
||||
bool isDone() { return mDone; };
|
||||
F32 getFadeVolume();
|
||||
bool getForcedTeleportFade() { return mForcedTeleportFade; };
|
||||
void setForcedTeleportFade(bool fade) { mForcedTeleportFade = fade;} ;
|
||||
void setNextStreamURI(std::string stream) { mNextStreamURI = stream; } ;
|
||||
|
||||
private:
|
||||
|
||||
bool mDone;
|
||||
F32 mFadeTime;
|
||||
std::string mNextStreamURI;
|
||||
EFadeState mFadeState;
|
||||
LLFrameTimer stream_fade_timer;
|
||||
bool mIdleListnerActive;
|
||||
bool mForcedTeleportFade;
|
||||
boost::signals2::connection mTeleportFailedConnection;
|
||||
|
||||
void registerIdleListener();
|
||||
void deregisterIdleListener() { mIdleListnerActive = false; };
|
||||
void startFading();
|
||||
void onTeleportFailed();
|
||||
|
||||
};
|
||||
|
||||
#endif //LL_VIEWER_H
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@
|
|||
//#include "llfirstuse.h"
|
||||
#include "llviewernetwork.h"
|
||||
#include "llwindow.h"
|
||||
|
||||
#include "llvieweraudio.h"
|
||||
|
||||
#include "llfloaterwebcontent.h" // for handling window close requests and geometry change requests in media browser windows.
|
||||
|
||||
|
|
@ -986,7 +986,7 @@ void LLViewerMedia::updateMedia(void *dummy_arg)
|
|||
{
|
||||
if(LLViewerMedia::isParcelAudioPlaying() && gAudiop && LLViewerMedia::hasParcelAudio())
|
||||
{
|
||||
gAudiop->stopInternetStream();
|
||||
LLViewerAudio::getInstance()->stopInternetStreamWithAutoFade();
|
||||
}
|
||||
}
|
||||
pimpl->setPriority(new_priority);
|
||||
|
|
@ -1090,13 +1090,24 @@ void LLViewerMedia::setAllMediaEnabled(bool val)
|
|||
gAudiop &&
|
||||
LLViewerMedia::hasParcelAudio())
|
||||
{
|
||||
gAudiop->startInternetStream(LLViewerMedia::getParcelAudioURL());
|
||||
if (LLAudioEngine::AUDIO_PAUSED == gAudiop->isInternetStreamPlaying())
|
||||
{
|
||||
// 'false' means unpause
|
||||
gAudiop->pauseInternetStream(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLViewerMedia::getParcelAudioURL());
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// This actually unloads the impl, as opposed to "stop"ping the media
|
||||
LLViewerParcelMedia::stop();
|
||||
if (gAudiop) gAudiop->stopInternetStream();
|
||||
if (gAudiop)
|
||||
{
|
||||
LLViewerAudio::getInstance()->stopInternetStreamWithAutoFade();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@
|
|||
#include "llworld.h"
|
||||
#include "roles_constants.h"
|
||||
#include "llweb.h"
|
||||
#include "llvieweraudio.h"
|
||||
|
||||
const F32 PARCEL_COLLISION_DRAW_SECS = 1.f;
|
||||
|
||||
|
|
@ -1725,7 +1726,10 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
|
|||
}
|
||||
else
|
||||
{
|
||||
// look for music.
|
||||
// Check for video
|
||||
LLViewerParcelMedia::update(parcel);
|
||||
|
||||
// Then check for music
|
||||
if (gAudiop)
|
||||
{
|
||||
if (parcel)
|
||||
|
|
@ -1736,46 +1740,34 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
|
|||
std::string music_url = music_url_raw;
|
||||
LLStringUtil::trim(music_url);
|
||||
|
||||
// On entering a new parcel, stop the last stream if the
|
||||
// new parcel has a different music url. (Empty URL counts
|
||||
// as different.)
|
||||
const std::string& stream_url = gAudiop->getInternetStreamURL();
|
||||
|
||||
if (music_url.empty() || music_url != stream_url)
|
||||
// If there is a new music URL and it's valid, play it.
|
||||
if (music_url.size() > 12)
|
||||
{
|
||||
// URL is different from one currently playing.
|
||||
gAudiop->stopInternetStream();
|
||||
|
||||
// If there is a new music URL and it's valid, play it.
|
||||
if (music_url.size() > 12)
|
||||
if (music_url.substr(0,7) == "http://")
|
||||
{
|
||||
if (music_url.substr(0,7) == "http://")
|
||||
{
|
||||
optionally_start_music(music_url);
|
||||
}
|
||||
else
|
||||
{
|
||||
llinfos << "Stopping parcel music (invalid audio stream URL)" << llendl;
|
||||
// clears the URL
|
||||
gAudiop->startInternetStream(LLStringUtil::null);
|
||||
}
|
||||
optionally_start_music(music_url);
|
||||
}
|
||||
else if (!gAudiop->getInternetStreamURL().empty())
|
||||
else
|
||||
{
|
||||
llinfos << "Stopping parcel music (parcel stream URL is empty)" << llendl;
|
||||
gAudiop->startInternetStream(LLStringUtil::null);
|
||||
llinfos << "Stopping parcel music (invalid audio stream URL)" << llendl;
|
||||
// clears the URL
|
||||
// null value causes fade out
|
||||
LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLStringUtil::null);
|
||||
}
|
||||
}
|
||||
else if (!gAudiop->getInternetStreamURL().empty())
|
||||
{
|
||||
llinfos << "Stopping parcel music (parcel stream URL is empty)" << llendl;
|
||||
// null value causes fade out
|
||||
LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLStringUtil::null);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Public land has no music
|
||||
gAudiop->stopInternetStream();
|
||||
LLViewerAudio::getInstance()->stopInternetStreamWithAutoFade();
|
||||
}
|
||||
}//if gAudiop
|
||||
|
||||
// now check for video
|
||||
LLViewerParcelMedia::update( parcel );
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -1794,7 +1786,11 @@ void optionally_start_music(const std::string& music_url)
|
|||
gSavedSettings.getBOOL("MediaTentativeAutoPlay")))
|
||||
{
|
||||
llinfos << "Starting parcel music " << music_url << llendl;
|
||||
gAudiop->startInternetStream(music_url);
|
||||
LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(music_url);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLStringUtil::null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue