Added media ticker to Singularity menu. Will be greyed out for anything not FMOD based. Consider implementing in other sound libraries as a to-do. FMOD Ex also displays an oscillator (making fmod3 do this is too dirty, so that's not going to be backported).
This commit is contained in:
@@ -53,7 +53,11 @@ class LLStreamingAudioInterface
|
|||||||
virtual void setGain(F32 vol) = 0;
|
virtual void setGain(F32 vol) = 0;
|
||||||
virtual F32 getGain() = 0;
|
virtual F32 getGain() = 0;
|
||||||
virtual std::string getURL() = 0;
|
virtual std::string getURL() = 0;
|
||||||
virtual const LLSD *getMetaData() = 0; //return NULL if not supported.
|
|
||||||
|
virtual bool supportsMetaData() = 0;
|
||||||
|
virtual const LLSD *getMetaData() = 0;
|
||||||
|
virtual bool supportsWaveData() = 0;
|
||||||
|
virtual bool getWaveData(float* arr, S32 count, S32 stride = 1) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // LL_STREAMINGAUDIO_H
|
#endif // LL_STREAMINGAUDIO_H
|
||||||
|
|||||||
@@ -54,8 +54,11 @@ class LLStreamingAudio_FMOD : public LLStreamingAudioInterface
|
|||||||
/*virtual*/ void setGain(F32 vol);
|
/*virtual*/ void setGain(F32 vol);
|
||||||
/*virtual*/ F32 getGain();
|
/*virtual*/ F32 getGain();
|
||||||
/*virtual*/ std::string getURL();
|
/*virtual*/ std::string getURL();
|
||||||
/*virtual*/ const LLSD *getMetaData(){return mMetaData;} //return NULL if not supported.
|
|
||||||
|
|
||||||
|
/*virtual*/ bool supportsMetaData(){return true;}
|
||||||
|
/*virtual*/ const LLSD *getMetaData(){return mMetaData;} //return NULL if not playing.
|
||||||
|
/*virtual*/ bool supportsWaveData(){return false;}
|
||||||
|
/*virtual*/ bool getWaveData(float* arr, S32 count, S32 stride = 1){return false};
|
||||||
private:
|
private:
|
||||||
LLAudioStreamManagerFMOD *mCurrentInternetStreamp;
|
LLAudioStreamManagerFMOD *mCurrentInternetStreamp;
|
||||||
int mFMODInternetStreamChannel;
|
int mFMODInternetStreamChannel;
|
||||||
|
|||||||
@@ -334,6 +334,27 @@ void LLStreamingAudio_FMODEX::setGain(F32 vol)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*virtual*/ bool LLStreamingAudio_FMODEX::getWaveData(float* arr, S32 count, S32 stride/*=1*/)
|
||||||
|
{
|
||||||
|
if(!mFMODInternetStreamChannelp || !mCurrentInternetStreamp)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
static std::vector<float> local_array(count); //Have to have an extra buffer to mix channels. Bleh.
|
||||||
|
if(count > (S32)local_array.size()) //Expand the array if needed. Try to minimize allocation calls, so don't ever shrink.
|
||||||
|
local_array.resize(count);
|
||||||
|
|
||||||
|
if( mFMODInternetStreamChannelp->getWaveData(&local_array[0],count,0) == FMOD_OK &&
|
||||||
|
mFMODInternetStreamChannelp->getWaveData(&arr[0],count,1) == FMOD_OK )
|
||||||
|
{
|
||||||
|
for(S32 i = count;i>=0;i-=stride)
|
||||||
|
{
|
||||||
|
arr[i] += local_array[i];
|
||||||
|
arr[i] *= .5f;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////
|
||||||
// manager of possibly-multiple internet audio streams
|
// manager of possibly-multiple internet audio streams
|
||||||
|
|||||||
@@ -61,8 +61,11 @@ class LLStreamingAudio_FMODEX : public LLStreamingAudioInterface
|
|||||||
/*virtual*/ void setGain(F32 vol);
|
/*virtual*/ void setGain(F32 vol);
|
||||||
/*virtual*/ F32 getGain();
|
/*virtual*/ F32 getGain();
|
||||||
/*virtual*/ std::string getURL();
|
/*virtual*/ std::string getURL();
|
||||||
/*virtual*/ const LLSD *getMetaData(){return mMetaData;} //return NULL if not supported.
|
|
||||||
|
|
||||||
|
/*virtual*/ bool supportsMetaData(){return true;}
|
||||||
|
/*virtual*/ const LLSD *getMetaData(){return mMetaData;} //return NULL if not playing.
|
||||||
|
/*virtual*/ bool supportsWaveData(){return true;}
|
||||||
|
/*virtual*/ bool getWaveData(float* arr, S32 count, S32 stride = 1);
|
||||||
private:
|
private:
|
||||||
FMOD::System *mSystem;
|
FMOD::System *mSystem;
|
||||||
|
|
||||||
|
|||||||
@@ -537,6 +537,7 @@ set(viewer_SOURCE_FILES
|
|||||||
rlvfloaterbehaviour.cpp
|
rlvfloaterbehaviour.cpp
|
||||||
rlvviewer2.cpp
|
rlvviewer2.cpp
|
||||||
shcommandhandler.cpp
|
shcommandhandler.cpp
|
||||||
|
shfloatermediaticker.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
# This gets renamed in the packaging step
|
# This gets renamed in the packaging step
|
||||||
@@ -1019,6 +1020,7 @@ set(viewer_HEADER_FILES
|
|||||||
rlvfloaterbehaviour.h
|
rlvfloaterbehaviour.h
|
||||||
rlvviewer2.h
|
rlvviewer2.h
|
||||||
shcommandhandler.h
|
shcommandhandler.h
|
||||||
|
shfloatermediaticker.h
|
||||||
)
|
)
|
||||||
|
|
||||||
source_group("CMake Rules" FILES ViewerInstall.cmake)
|
source_group("CMake Rules" FILES ViewerInstall.cmake)
|
||||||
|
|||||||
@@ -1,6 +1,35 @@
|
|||||||
<?xml version="1.0" ?>
|
<?xml version="1.0" ?>
|
||||||
<llsd>
|
<llsd>
|
||||||
<map>
|
<map>
|
||||||
|
|
||||||
|
<key>SHShowMediaTicker</key>
|
||||||
|
<map>
|
||||||
|
<key>Comment</key>
|
||||||
|
<string>Enable media ticker tool for supported audio libraries</string>
|
||||||
|
<key>Persist</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
<key>Type</key>
|
||||||
|
<string>Boolean</string>
|
||||||
|
<key>Value</key>
|
||||||
|
<integer>0</integer>
|
||||||
|
</map>
|
||||||
|
<key>SHMediaTickerRect</key>
|
||||||
|
<map>
|
||||||
|
<key>Comment</key>
|
||||||
|
<string>Rectangle for media ticker</string>
|
||||||
|
<key>Persist</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
<key>Type</key>
|
||||||
|
<string>Rect</string>
|
||||||
|
<key>Value</key>
|
||||||
|
<array>
|
||||||
|
<integer>200</integer>
|
||||||
|
<integer>82</integer>
|
||||||
|
<integer>456</integer>
|
||||||
|
<integer>50</integer>
|
||||||
|
</array>
|
||||||
|
</map>
|
||||||
|
|
||||||
<key>SHEnableFMODExProfiler</key>
|
<key>SHEnableFMODExProfiler</key>
|
||||||
<map>
|
<map>
|
||||||
<key>Comment</key>
|
<key>Comment</key>
|
||||||
|
|||||||
@@ -214,6 +214,7 @@
|
|||||||
#include "ascentdaycyclemanager.h"
|
#include "ascentdaycyclemanager.h"
|
||||||
#include "llfloaterblacklist.h"
|
#include "llfloaterblacklist.h"
|
||||||
#include "scriptcounter.h"
|
#include "scriptcounter.h"
|
||||||
|
#include "shfloatermediaticker.h"
|
||||||
// </edit>
|
// </edit>
|
||||||
|
|
||||||
#include "llavatarnamecache.h"
|
#include "llavatarnamecache.h"
|
||||||
@@ -2053,6 +2054,10 @@ bool idle_startup()
|
|||||||
{
|
{
|
||||||
LLFloaterAvatarList::createInstance(false);
|
LLFloaterAvatarList::createInstance(false);
|
||||||
}
|
}
|
||||||
|
if (gSavedSettings.getBOOL("SHShowMediaTicker"))
|
||||||
|
{
|
||||||
|
SHFloaterMediaTicker::showInstance();
|
||||||
|
}
|
||||||
// </edit>
|
// </edit>
|
||||||
if (gSavedSettings.getBOOL("ShowCameraControls"))
|
if (gSavedSettings.getBOOL("ShowCameraControls"))
|
||||||
{
|
{
|
||||||
@@ -2073,6 +2078,8 @@ bool idle_startup()
|
|||||||
LLFloaterBeacons::showInstance();
|
LLFloaterBeacons::showInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (!gNoRender)
|
if (!gNoRender)
|
||||||
{
|
{
|
||||||
//Set up cloud rendertypes. Passed argument is unused.
|
//Set up cloud rendertypes. Passed argument is unused.
|
||||||
|
|||||||
@@ -51,6 +51,7 @@
|
|||||||
#include "chatbar_as_cmdline.h"
|
#include "chatbar_as_cmdline.h"
|
||||||
|
|
||||||
#if SHY_MOD //Command handler
|
#if SHY_MOD //Command handler
|
||||||
|
#include "llvoavatarself.h"
|
||||||
#include "shcommandhandler.h"
|
#include "shcommandhandler.h"
|
||||||
#endif //shy_mod
|
#endif //shy_mod
|
||||||
|
|
||||||
@@ -109,7 +110,6 @@ BOOL LLViewerGesture::trigger(const std::string &trigger_string)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// private
|
// private
|
||||||
void LLViewerGesture::doTrigger( BOOL send_chat )
|
void LLViewerGesture::doTrigger( BOOL send_chat )
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -55,7 +55,11 @@ class LLStreamingAudio_MediaPlugins : public LLStreamingAudioInterface
|
|||||||
/*virtual*/ void setGain(F32 vol);
|
/*virtual*/ void setGain(F32 vol);
|
||||||
/*virtual*/ F32 getGain();
|
/*virtual*/ F32 getGain();
|
||||||
/*virtual*/ std::string getURL();
|
/*virtual*/ std::string getURL();
|
||||||
/*virtual*/ LLSD *getMetaData(){return NULL;} //return NULL if not supported.
|
|
||||||
|
/*virtual*/ bool supportsMetaData(){return false;}
|
||||||
|
/*virtual*/ LLSD *getMetaData(){return NULL;} //return NULL if not playing.
|
||||||
|
/*virtual*/ virtual bool supportsWaveData(){return false;}
|
||||||
|
/*virtual*/ virtual bool getWaveData(float* arr, S32 count, S32 stride = 1){return false;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
LLPluginClassMedia* initializeMedia(const std::string& media_type);
|
LLPluginClassMedia* initializeMedia(const std::string& media_type);
|
||||||
|
|||||||
@@ -247,6 +247,7 @@
|
|||||||
#include "llfloatermessagelog.h"
|
#include "llfloatermessagelog.h"
|
||||||
#include "llfloatervfs.h"
|
#include "llfloatervfs.h"
|
||||||
#include "llfloatervfsexplorer.h"
|
#include "llfloatervfsexplorer.h"
|
||||||
|
#include "shfloatermediaticker.h"
|
||||||
// </edit>
|
// </edit>
|
||||||
|
|
||||||
#include "scriptcounter.h"
|
#include "scriptcounter.h"
|
||||||
@@ -825,6 +826,8 @@ void init_menus()
|
|||||||
&handle_sounds_explorer, NULL));
|
&handle_sounds_explorer, NULL));
|
||||||
menu->append(new LLMenuItemCallGL( "Asset Blacklist",
|
menu->append(new LLMenuItemCallGL( "Asset Blacklist",
|
||||||
&handle_blacklist, NULL));
|
&handle_blacklist, NULL));
|
||||||
|
menu->append(new LLMenuItemCheckGL( "Streaming Audio Display",
|
||||||
|
&handle_ticker_toggle, &handle_ticker_enabled, &handle_ticker_check, NULL ));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
262
indra/newview/shfloatermediaticker.cpp
Normal file
262
indra/newview/shfloatermediaticker.cpp
Normal file
@@ -0,0 +1,262 @@
|
|||||||
|
|
||||||
|
#include "llviewerprecompiledheaders.h"
|
||||||
|
|
||||||
|
#include "shfloatermediaticker.h"
|
||||||
|
|
||||||
|
// Library includes
|
||||||
|
#include "llaudioengine.h"
|
||||||
|
#include "lliconctrl.h"
|
||||||
|
#include "llstreamingaudio.h"
|
||||||
|
#include "lluictrlfactory.h"
|
||||||
|
|
||||||
|
// Viewer includes
|
||||||
|
#include "llviewercontrol.h"
|
||||||
|
|
||||||
|
|
||||||
|
SHFloaterMediaTicker::SHFloaterMediaTicker() : LLFloater()/*, LLSingleton<SHFloaterMediaTicker>()*/,
|
||||||
|
mPlayState(STATE_PAUSED),
|
||||||
|
mArtistScrollChars(0),
|
||||||
|
mTitleScrollChars(0),
|
||||||
|
mCurScrollChar(0),
|
||||||
|
mTickerBackground(NULL),
|
||||||
|
mArtistText(NULL),
|
||||||
|
mTitleText(NULL),
|
||||||
|
mVisualizer(NULL)
|
||||||
|
{
|
||||||
|
setIsChrome(TRUE);
|
||||||
|
LLUICtrlFactory::getInstance()->buildFloater(this, "sh_floater_media_ticker.xml");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*virtual*/ BOOL SHFloaterMediaTicker::postBuild()
|
||||||
|
{
|
||||||
|
mTickerBackground = getChild<LLIconCtrl>("ticker_background");
|
||||||
|
mArtistText = getChild<LLTextBox>("artist_text",true,false);
|
||||||
|
mTitleText = getChild<LLTextBox>("title_text",true,false);
|
||||||
|
mVisualizer = getChild<LLUICtrl>("visualizer_box",true,false);
|
||||||
|
mszLoading = getString("loading");
|
||||||
|
mszPaused = getString("paused");
|
||||||
|
|
||||||
|
if(mArtistText) mArtistText->setText(mszPaused);
|
||||||
|
if(mTitleText) mTitleText->setText(mszPaused);
|
||||||
|
|
||||||
|
if(!gAudiop->getStreamingAudioImpl()->supportsWaveData()) //Can't visualize. Extend textboxes.
|
||||||
|
{
|
||||||
|
if(mArtistText)
|
||||||
|
{
|
||||||
|
LLRect text_rect = mArtistText->getRect();
|
||||||
|
text_rect.mRight = llmax(mTickerBackground->getRect().mRight-2,text_rect.mRight);
|
||||||
|
mArtistText->setRect(text_rect);
|
||||||
|
}
|
||||||
|
if(mTitleText)
|
||||||
|
{
|
||||||
|
LLRect text_rect = mTitleText->getRect();
|
||||||
|
text_rect.mRight = llmax(mTickerBackground->getRect().mRight-2,text_rect.mRight);
|
||||||
|
mArtistText->setRect(text_rect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return LLFloater::postBuild();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*virtual*/ void SHFloaterMediaTicker::draw()
|
||||||
|
{
|
||||||
|
updateTickerText();
|
||||||
|
LLFloater::draw();
|
||||||
|
drawOscilloscope();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*virtual*/ void SHFloaterMediaTicker::onOpen()
|
||||||
|
{
|
||||||
|
LLFloater::onOpen();
|
||||||
|
|
||||||
|
gSavedSettings.setBOOL("SHShowMediaTicker", TRUE);
|
||||||
|
}
|
||||||
|
/*virtual*/ void SHFloaterMediaTicker::onClose(bool app_quitting)
|
||||||
|
{
|
||||||
|
LLFloater::onClose(app_quitting);
|
||||||
|
|
||||||
|
if (!app_quitting)
|
||||||
|
{
|
||||||
|
gSavedSettings.setBOOL("SHShowMediaTicker", FALSE);
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHFloaterMediaTicker::updateTickerText() //called via draw.
|
||||||
|
{
|
||||||
|
bool stream_paused = gAudiop->getStreamingAudioImpl()->isPlaying() != 1; //will return 1 if playing.
|
||||||
|
|
||||||
|
bool dirty = setPaused(stream_paused);
|
||||||
|
if(!stream_paused)
|
||||||
|
{
|
||||||
|
const LLSD* metadata = gAudiop->getStreamingAudioImpl()->getMetaData();
|
||||||
|
LLSD artist = metadata ? metadata->get("ARTIST") : LLSD();
|
||||||
|
LLSD title = metadata ? metadata->get("TITLE") : LLSD();
|
||||||
|
|
||||||
|
dirty |= setArtist(artist.isDefined() ? artist.asString() : mszLoading);
|
||||||
|
dirty |= setTitle(title.isDefined() ? title.asString() : mszLoading);
|
||||||
|
|
||||||
|
if(dirty)
|
||||||
|
resetTicker();
|
||||||
|
else iterateTickerOffset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHFloaterMediaTicker::drawOscilloscope() //called via draw.
|
||||||
|
{
|
||||||
|
if(!mVisualizer || !gAudiop->getStreamingAudioImpl()->supportsWaveData())
|
||||||
|
return;
|
||||||
|
|
||||||
|
static const S32 NUM_LINE_STRIPS = 64; //How many lines to draw. 64 is more than enough.
|
||||||
|
static const S32 WAVE_DATA_STEP_SIZE = 4; //Increase to provide more history at expense of cpu/memory.
|
||||||
|
|
||||||
|
static const S32 NUM_WAVE_DATA_VALUES = NUM_LINE_STRIPS*WAVE_DATA_STEP_SIZE; //Actual buffer size. Don't toy with this. Change above vars to tweak.
|
||||||
|
static F32 buf[NUM_WAVE_DATA_VALUES];
|
||||||
|
|
||||||
|
if(!gAudiop->getStreamingAudioImpl()->getWaveData(&buf[0],NUM_WAVE_DATA_VALUES,WAVE_DATA_STEP_SIZE))
|
||||||
|
return;
|
||||||
|
|
||||||
|
LLRect root_rect = mVisualizer->getRect();
|
||||||
|
|
||||||
|
F32 height = root_rect.getHeight();
|
||||||
|
F32 height_scale = height / 2.f; //WaveData ranges from 1 to -1, so height_scale = height / 2
|
||||||
|
F32 width_scale = root_rect.getWidth() / (F32)NUM_WAVE_DATA_VALUES;
|
||||||
|
|
||||||
|
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||||
|
gGL.color4f(0.f,0.f,0.f,.75f);
|
||||||
|
gGL.pushMatrix();
|
||||||
|
gGL.translatef((F32)root_rect.mLeft, (F32)root_rect.mBottom + height*.5f, 0.f);
|
||||||
|
gGL.begin( LLRender::LINE_STRIP );
|
||||||
|
if((mPlayState != STATE_PAUSED))
|
||||||
|
{
|
||||||
|
for(S32 i = NUM_WAVE_DATA_VALUES; i>=0;i-=WAVE_DATA_STEP_SIZE)
|
||||||
|
gGL.vertex2f((F32)i * width_scale, buf[i]*height_scale);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gGL.vertex2f(0.f, 0.f);
|
||||||
|
gGL.vertex2f(root_rect.getWidth(), 0.f);
|
||||||
|
}
|
||||||
|
gGL.end();
|
||||||
|
gGL.popMatrix();
|
||||||
|
gGL.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHFloaterMediaTicker::setPaused(bool pause)
|
||||||
|
{
|
||||||
|
if(pause == (mPlayState == STATE_PAUSED))
|
||||||
|
return false;
|
||||||
|
mPlayState = pause ? STATE_PAUSED : STATE_PLAYING;
|
||||||
|
if(pause)
|
||||||
|
{
|
||||||
|
if(mArtistText) mArtistText->setText(mszPaused);
|
||||||
|
if(mTitleText) mTitleText->setText(mszPaused);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHFloaterMediaTicker::resetTicker()
|
||||||
|
{
|
||||||
|
mScrollTimer.reset();
|
||||||
|
mCurScrollChar=0;
|
||||||
|
if(mArtistText) mArtistText->setText(LLStringExplicit(mszArtist.substr(0,mszArtist.length()-mArtistScrollChars)));
|
||||||
|
if(mTitleText) mTitleText->setText(LLStringExplicit(mszTitle.substr(0,mszTitle.length()-mTitleScrollChars)));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHFloaterMediaTicker::setArtist(const std::string &artist)
|
||||||
|
{
|
||||||
|
if(!mArtistText || mszArtist == artist)
|
||||||
|
return false;
|
||||||
|
mszArtist = artist;
|
||||||
|
mArtistText->setText(mszArtist);
|
||||||
|
mArtistScrollChars = countExtraChars(mArtistText,mszArtist);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHFloaterMediaTicker::setTitle(const std::string &title)
|
||||||
|
{
|
||||||
|
if(!mTitleText || mszTitle == title)
|
||||||
|
return false;
|
||||||
|
mszTitle=title;
|
||||||
|
mTitleText->setText(mszTitle);
|
||||||
|
mTitleScrollChars = countExtraChars(mTitleText,mszTitle);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
S32 SHFloaterMediaTicker::countExtraChars(LLTextBox *texbox, const std::string &text)
|
||||||
|
{
|
||||||
|
S32 text_width = texbox->getTextPixelWidth();
|
||||||
|
S32 box_width = texbox->getRect().getWidth();
|
||||||
|
if(text_width > box_width)
|
||||||
|
{
|
||||||
|
const LLFontGL* font = texbox->getFont();
|
||||||
|
for(S32 count = 1;count<(S32)text.length();count++)
|
||||||
|
{
|
||||||
|
//This isn't very efficient...
|
||||||
|
const std::string substr = text.substr(0,text.length()-count);
|
||||||
|
if(font->getWidth(substr) <= box_width)
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHFloaterMediaTicker::iterateTickerOffset()
|
||||||
|
{
|
||||||
|
if( (mPlayState != STATE_PAUSED) &&
|
||||||
|
(mArtistScrollChars || mTitleScrollChars) &&
|
||||||
|
((!mCurScrollChar && mScrollTimer.getElapsedTimeF32() >= 5.f) ||
|
||||||
|
( mCurScrollChar && mScrollTimer.getElapsedTimeF32() >= .5f)))
|
||||||
|
{
|
||||||
|
if(++mCurScrollChar > llmax(mArtistScrollChars, mTitleScrollChars))
|
||||||
|
{
|
||||||
|
if(mScrollTimer.getElapsedTimeF32() >= 2.f) //pause for a bit when it reaches beyond last character.
|
||||||
|
resetTicker();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mScrollTimer.reset();
|
||||||
|
if(mArtistText && mCurScrollChar <= mArtistScrollChars)
|
||||||
|
{
|
||||||
|
mArtistText->setText(LLStringExplicit(mszArtist.substr(mCurScrollChar,mszArtist.length()-mArtistScrollChars+mCurScrollChar)));
|
||||||
|
}
|
||||||
|
if(mTitleText && mCurScrollChar <= mTitleScrollChars)
|
||||||
|
{
|
||||||
|
mTitleText->setText(LLStringExplicit(mszTitle.substr(mCurScrollChar,mszTitle.length()-mTitleScrollChars+mCurScrollChar)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*static*/
|
||||||
|
void SHFloaterMediaTicker::showInstance()
|
||||||
|
{
|
||||||
|
if(!handle_ticker_enabled(NULL))
|
||||||
|
return;
|
||||||
|
if(!SHFloaterMediaTicker::instanceExists())
|
||||||
|
{
|
||||||
|
SHFloaterMediaTicker::getInstance();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL handle_ticker_enabled(void *)
|
||||||
|
{
|
||||||
|
return gAudiop && gAudiop->getStreamingAudioImpl() && gAudiop->getStreamingAudioImpl()->supportsMetaData();
|
||||||
|
}
|
||||||
|
BOOL handle_ticker_check(void *)
|
||||||
|
{
|
||||||
|
return SHFloaterMediaTicker::instanceExists();
|
||||||
|
}
|
||||||
|
void handle_ticker_toggle(void *)
|
||||||
|
{
|
||||||
|
if(!handle_ticker_enabled(NULL))
|
||||||
|
return;
|
||||||
|
if(!SHFloaterMediaTicker::instanceExists())
|
||||||
|
{
|
||||||
|
SHFloaterMediaTicker::getInstance();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SHFloaterMediaTicker::getInstance()->close();
|
||||||
|
}
|
||||||
|
}
|
||||||
55
indra/newview/shfloatermediaticker.h
Normal file
55
indra/newview/shfloatermediaticker.h
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
#include "llfloater.h"
|
||||||
|
|
||||||
|
class LLIconCtrl;
|
||||||
|
|
||||||
|
class SHFloaterMediaTicker : public LLFloater, public LLSingleton<SHFloaterMediaTicker>
|
||||||
|
{
|
||||||
|
friend class LLSingleton<SHFloaterMediaTicker>;
|
||||||
|
public:
|
||||||
|
SHFloaterMediaTicker(); //ctor
|
||||||
|
|
||||||
|
virtual ~SHFloaterMediaTicker() {}
|
||||||
|
/*virtual*/ BOOL postBuild();
|
||||||
|
/*virtual*/ void draw();
|
||||||
|
/*virtual*/ void onOpen();
|
||||||
|
/*virtual*/ void onClose(bool app_quitting);
|
||||||
|
|
||||||
|
static void showInstance(); //use to create.
|
||||||
|
private:
|
||||||
|
void updateTickerText(); //called via draw.
|
||||||
|
void drawOscilloscope(); //called via draw.
|
||||||
|
bool setPaused(bool pause); //returns true on state change.
|
||||||
|
void resetTicker(); //Resets tickers to their innitial values (no offset).
|
||||||
|
bool setArtist(const std::string &artist); //returns true on change
|
||||||
|
bool setTitle(const std::string &title); //returns true on change
|
||||||
|
S32 countExtraChars(LLTextBox *texbox, const std::string &text); //calculates how many characters are truncated by bounds.
|
||||||
|
void iterateTickerOffset(); //Logic that actually shuffles the text to the left.
|
||||||
|
|
||||||
|
enum ePlayState
|
||||||
|
{
|
||||||
|
STATE_PAUSED,
|
||||||
|
STATE_PLAYING
|
||||||
|
};
|
||||||
|
|
||||||
|
ePlayState mPlayState;
|
||||||
|
std::string mszLoading;
|
||||||
|
std::string mszPaused;
|
||||||
|
std::string mszArtist;
|
||||||
|
std::string mszTitle;
|
||||||
|
LLTimer mScrollTimer;
|
||||||
|
S32 mArtistScrollChars;
|
||||||
|
S32 mTitleScrollChars;
|
||||||
|
S32 mCurScrollChar;
|
||||||
|
|
||||||
|
//UI elements
|
||||||
|
LLIconCtrl* mTickerBackground;
|
||||||
|
LLTextBox* mArtistText;
|
||||||
|
LLTextBox* mTitleText;
|
||||||
|
LLUICtrl* mVisualizer;
|
||||||
|
};
|
||||||
|
|
||||||
|
//Menu callbacks.
|
||||||
|
BOOL handle_ticker_enabled(void *);
|
||||||
|
BOOL handle_ticker_check(void *);
|
||||||
|
void handle_ticker_toggle(void *);
|
||||||
|
|
||||||
BIN
indra/newview/skins/default/textures/ticker_background_small.tga
Normal file
BIN
indra/newview/skins/default/textures/ticker_background_small.tga
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
@@ -0,0 +1,39 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||||
|
<floater can_close="true" can_drag_on_left="false" can_minimize="false" can_resize="false"
|
||||||
|
height="32" min_height="32" min_width="256" name="mediaticker" rect_control="SHMediaTickerRect" control_name="SHShowMediaTicker"
|
||||||
|
title="" width="256">
|
||||||
|
<icon bottom="-30" color="1, 1, 1, 1" follows="top|right" height="28"
|
||||||
|
image_name="ticker_background_small.tga" left="2" mouse_opaque="false" name="ticker_background"
|
||||||
|
width="234" />
|
||||||
|
<text text_color="0,0,0,1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
|
||||||
|
bottom="-18" drop_shadow_visible="true" follows="top|right"
|
||||||
|
font="SansSerifBold" h_pad="0" halign="left" height="16" left="4"
|
||||||
|
mouse_opaque="true" name="artist_label" v_pad="0" width="50">
|
||||||
|
Artist:
|
||||||
|
</text>
|
||||||
|
<text text_color="0,0,0,1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
|
||||||
|
bottom="-18" drop_shadow_visible="true" follows="top|right"
|
||||||
|
font="SansSerifBold" h_pad="0" halign="left" height="16" left="50"
|
||||||
|
mouse_opaque="true" name="artist_text" v_pad="0" width="125">
|
||||||
|
</text>
|
||||||
|
<text text_color="0,0,0,1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
|
||||||
|
bottom="-32" drop_shadow_visible="true" follows="top|right"
|
||||||
|
font="SansSerifBold" h_pad="0" halign="left" height="16" left="4"
|
||||||
|
mouse_opaque="true" name="title_label" v_pad="0" width="50">
|
||||||
|
Title:
|
||||||
|
</text>
|
||||||
|
<text text_color="0,0,0,1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
|
||||||
|
bottom="-32" drop_shadow_visible="true" follows="top|right"
|
||||||
|
font="SansSerifBold" h_pad="0" halign="left" height="16" left="50"
|
||||||
|
mouse_opaque="true" name="title_text" v_pad="0" width="125">
|
||||||
|
</text>
|
||||||
|
|
||||||
|
<locate bottom="-28" height="24" left="177" name="visualizer_box" width="58"/>
|
||||||
|
|
||||||
|
<string name="paused">
|
||||||
|
(not playing)
|
||||||
|
</string>
|
||||||
|
<string name="loading">
|
||||||
|
(loading...)
|
||||||
|
</string>
|
||||||
|
</floater>
|
||||||
Reference in New Issue
Block a user