545 lines
13 KiB
C++
545 lines
13 KiB
C++
/**
|
|
* @file lloverlaybar.cpp
|
|
* @brief LLOverlayBar class implementation
|
|
*
|
|
* Copyright (c) 2002-$CurrentYear$, Linden Research, Inc.
|
|
* $License$
|
|
*/
|
|
|
|
// Temporary buttons that appear at the bottom of the screen when you
|
|
// are in a mode.
|
|
|
|
#include "llviewerprecompiledheaders.h"
|
|
|
|
#include "lloverlaybar.h"
|
|
|
|
#include "audioengine.h"
|
|
#include "llparcel.h"
|
|
|
|
#include "llagent.h"
|
|
#include "llbutton.h"
|
|
#include "llviewercontrol.h"
|
|
#include "llimview.h"
|
|
#include "lltextbox.h"
|
|
#include "llvoavatar.h"
|
|
#include "llmediaengine.h"
|
|
#include "viewer.h"
|
|
#include "llui.h"
|
|
#include "llviewermenu.h" // handle_reset_view()
|
|
#include "llviewerparcelmgr.h"
|
|
#include "llwebbrowserctrl.h"
|
|
#include "llvieweruictrlfactory.h"
|
|
#include "llviewerimagelist.h"
|
|
#include "llviewerwindow.h"
|
|
#include "llfocusmgr.h"
|
|
|
|
//
|
|
// Globals
|
|
//
|
|
|
|
LLOverlayBar *gOverlayBar = NULL;
|
|
|
|
extern S32 MENU_BAR_HEIGHT;
|
|
|
|
//
|
|
// Functions
|
|
//
|
|
|
|
|
|
//static
|
|
void* LLOverlayBar::createMediaRemote(void* userdata)
|
|
{
|
|
|
|
LLOverlayBar *self = (LLOverlayBar*)userdata;
|
|
|
|
|
|
self->mMediaRemote = new LLMediaRemoteCtrl ( "media_remote",
|
|
"media",
|
|
LLRect(),
|
|
"panel_media_remote.xml");
|
|
return self->mMediaRemote;
|
|
}
|
|
|
|
|
|
|
|
void* LLOverlayBar::createMusicRemote(void* userdata)
|
|
{
|
|
|
|
LLOverlayBar *self = (LLOverlayBar*)userdata;
|
|
|
|
self->mMusicRemote = new LLMediaRemoteCtrl ( "music_remote",
|
|
"music",
|
|
LLRect(),
|
|
"panel_music_remote.xml" );
|
|
return self->mMusicRemote;
|
|
}
|
|
|
|
|
|
|
|
|
|
LLOverlayBar::LLOverlayBar(const std::string& name, const LLRect& rect)
|
|
: LLPanel(name, rect, FALSE) // not bordered
|
|
{
|
|
setMouseOpaque(FALSE);
|
|
setIsChrome(TRUE);
|
|
|
|
isBuilt = FALSE;
|
|
|
|
LLCallbackMap::map_t factory_map;
|
|
factory_map["media_remote"] = LLCallbackMap(LLOverlayBar::createMediaRemote, this);
|
|
factory_map["music_remote"] = LLCallbackMap(LLOverlayBar::createMusicRemote, this);
|
|
|
|
gUICtrlFactory->buildPanel(this, "panel_overlaybar.xml", &factory_map);
|
|
|
|
childSetAction("IM Received",onClickIMReceived,this);
|
|
childSetAction("Set Not Busy",onClickSetNotBusy,this);
|
|
childSetAction("Release Keys",onClickReleaseKeys,this);
|
|
childSetAction("Mouselook",onClickMouselook,this);
|
|
childSetAction("Stand Up",onClickStandUp,this);
|
|
|
|
mMusicRemote->addObserver ( this );
|
|
|
|
if ( gAudiop )
|
|
{
|
|
mMusicRemote->setVolume ( gSavedSettings.getF32 ( "AudioLevelMusic" ) );
|
|
mMusicRemote->setTransportState ( LLMediaRemoteCtrl::Stop, FALSE );
|
|
};
|
|
|
|
mIsFocusRoot = TRUE;
|
|
|
|
mMediaRemote->addObserver ( this );
|
|
mMediaRemote->setVolume ( gSavedSettings.getF32 ( "MediaAudioVolume" ) );
|
|
|
|
isBuilt = true;
|
|
|
|
layoutButtons();
|
|
}
|
|
|
|
LLOverlayBar::~LLOverlayBar()
|
|
{
|
|
// LLView destructor cleans up children
|
|
|
|
mMusicRemote->remObserver ( this );
|
|
mMediaRemote->remObserver ( this );
|
|
}
|
|
|
|
EWidgetType LLOverlayBar::getWidgetType() const
|
|
{
|
|
return WIDGET_TYPE_OVERLAY_BAR;
|
|
}
|
|
|
|
LLString LLOverlayBar::getWidgetTag() const
|
|
{
|
|
return LL_OVERLAY_BAR_TAG;
|
|
}
|
|
|
|
// virtual
|
|
void LLOverlayBar::reshape(S32 width, S32 height, BOOL called_from_parent)
|
|
{
|
|
LLView::reshape(width, height, called_from_parent);
|
|
|
|
if (isBuilt)
|
|
{
|
|
layoutButtons();
|
|
}
|
|
}
|
|
|
|
|
|
void LLOverlayBar::layoutButtons()
|
|
{
|
|
S32 width = mRect.getWidth();
|
|
if (width > 800) width = 800;
|
|
|
|
S32 count = getChildCount();
|
|
const S32 PAD = gSavedSettings.getS32("StatusBarPad");
|
|
|
|
F32 segment_width = (F32)(width) / (F32)count;
|
|
|
|
S32 btn_width = lltrunc(segment_width - PAD);
|
|
|
|
S32 remote_width = mMusicRemote->getRect().getWidth();
|
|
|
|
// Evenly space all views
|
|
LLRect r;
|
|
S32 i = 0;
|
|
for (child_list_const_iter_t child_iter = getChildList()->begin();
|
|
child_iter != getChildList()->end(); ++child_iter)
|
|
{
|
|
LLView *view = *child_iter;
|
|
r = view->getRect();
|
|
r.mLeft = (width) - llround((i+1)*segment_width);
|
|
r.mRight = r.mLeft + btn_width;
|
|
view->setRect(r);
|
|
i++;
|
|
}
|
|
|
|
// Fix up remotes to have constant width because they can't shrink
|
|
r = mMusicRemote->getRect();
|
|
r.mRight = r.mLeft + remote_width;
|
|
mMusicRemote->setRect(r);
|
|
|
|
r = mMediaRemote->getRect();
|
|
r.mLeft = mMusicRemote->getRect().mRight + PAD;
|
|
r.mRight = r.mLeft + remote_width;
|
|
mMediaRemote->setRect(r);
|
|
|
|
updateRect();
|
|
}
|
|
|
|
void LLOverlayBar::draw()
|
|
{
|
|
// retrieve rounded rect image
|
|
LLUUID image_id;
|
|
image_id.set(gViewerArt.getString("rounded_square.tga"));
|
|
LLViewerImage* imagep = gImageList.getImage(image_id, MIPMAP_FALSE, TRUE);
|
|
|
|
if (imagep)
|
|
{
|
|
LLGLSTexture texture_enabled;
|
|
LLViewerImage::bindTexture(imagep);
|
|
|
|
const S32 PAD = gSavedSettings.getS32("StatusBarPad");
|
|
|
|
// draw rounded rect tabs behind all children
|
|
LLRect r;
|
|
// focus highlights
|
|
LLColor4 color = gColors.getColor("FloaterFocusBorderColor");
|
|
glColor4fv(color.mV);
|
|
if(gFocusMgr.childHasKeyboardFocus(gBottomPanel))
|
|
{
|
|
for (child_list_const_iter_t child_iter = getChildList()->begin();
|
|
child_iter != getChildList()->end(); ++child_iter)
|
|
{
|
|
LLView *view = *child_iter;
|
|
if(view->getEnabled() && view->getVisible())
|
|
{
|
|
r = view->getRect();
|
|
gl_segmented_rect_2d_tex(r.mLeft - PAD/3 - 1,
|
|
r.mTop + 3,
|
|
r.mRight + PAD/3 + 1,
|
|
r.mBottom,
|
|
imagep->getWidth(),
|
|
imagep->getHeight(),
|
|
16,
|
|
ROUNDED_RECT_TOP);
|
|
}
|
|
}
|
|
}
|
|
|
|
// main tabs
|
|
for (child_list_const_iter_t child_iter = getChildList()->begin();
|
|
child_iter != getChildList()->end(); ++child_iter)
|
|
{
|
|
LLView *view = *child_iter;
|
|
if(view->getEnabled() && view->getVisible())
|
|
{
|
|
r = view->getRect();
|
|
// draw a nice little pseudo-3D outline
|
|
color = gColors.getColor("DefaultShadowDark");
|
|
glColor4fv(color.mV);
|
|
gl_segmented_rect_2d_tex(r.mLeft - PAD/3 + 1, r.mTop + 2, r.mRight + PAD/3, r.mBottom,
|
|
imagep->getWidth(), imagep->getHeight(), 16, ROUNDED_RECT_TOP);
|
|
color = gColors.getColor("DefaultHighlightLight");
|
|
glColor4fv(color.mV);
|
|
gl_segmented_rect_2d_tex(r.mLeft - PAD/3, r.mTop + 2, r.mRight + PAD/3 - 3, r.mBottom,
|
|
imagep->getWidth(), imagep->getHeight(), 16, ROUNDED_RECT_TOP);
|
|
// here's the main background. Note that it overhangs on the bottom so as to hide the
|
|
// focus highlight on the bottom panel, thus producing the illusion that the focus highlight
|
|
// continues around the tabs
|
|
color = gColors.getColor("FocusBackgroundColor");
|
|
glColor4fv(color.mV);
|
|
gl_segmented_rect_2d_tex(r.mLeft - PAD/3 + 1, r.mTop + 1, r.mRight + PAD/3 - 1, r.mBottom - 1,
|
|
imagep->getWidth(), imagep->getHeight(), 16, ROUNDED_RECT_TOP);
|
|
}
|
|
}
|
|
}
|
|
|
|
// draw children on top
|
|
LLPanel::draw();
|
|
}
|
|
|
|
|
|
// Per-frame updates of visibility
|
|
void LLOverlayBar::refresh()
|
|
{
|
|
BOOL im_received = gIMView->getIMReceived();
|
|
childSetVisible("IM Received", im_received);
|
|
childSetEnabled("IM Received", im_received);
|
|
|
|
BOOL busy = gAgent.getBusy();
|
|
childSetVisible("Set Not Busy", busy);
|
|
childSetEnabled("Set Not Busy", busy);
|
|
|
|
BOOL controls_grabbed = gAgent.anyControlGrabbed();
|
|
|
|
childSetVisible("Release Keys", controls_grabbed);
|
|
childSetEnabled("Release Keys", controls_grabbed);
|
|
|
|
|
|
BOOL mouselook_grabbed;
|
|
mouselook_grabbed = gAgent.isControlGrabbed(CONTROL_ML_LBUTTON_DOWN_INDEX)
|
|
|| gAgent.isControlGrabbed(CONTROL_ML_LBUTTON_UP_INDEX);
|
|
|
|
|
|
childSetVisible("Mouselook", mouselook_grabbed);
|
|
childSetEnabled("Mouselook", mouselook_grabbed);
|
|
|
|
BOOL sitting = FALSE;
|
|
if (gAgent.getAvatarObject())
|
|
{
|
|
sitting = gAgent.getAvatarObject()->mIsSitting;
|
|
childSetVisible("Stand Up", sitting);
|
|
childSetEnabled("Stand Up", sitting);
|
|
|
|
}
|
|
|
|
if ( gAudiop )
|
|
{
|
|
LLParcel* parcel = gParcelMgr->getAgentParcel();
|
|
if (!parcel
|
|
|| !parcel->getMusicURL()
|
|
|| !parcel->getMusicURL()[0]
|
|
|| !gSavedSettings.getBOOL("AudioStreamingMusic"))
|
|
{
|
|
mMusicRemote->setVisible(FALSE);
|
|
mMusicRemote->setEnabled(FALSE);
|
|
}
|
|
else
|
|
{
|
|
mMusicRemote->setVisible(TRUE);
|
|
mMusicRemote->setEnabled(TRUE);
|
|
}
|
|
}
|
|
|
|
// if there is a url and a texture and media is enabled and available and media streaming is on... (phew!)
|
|
if ( LLMediaEngine::getInstance () &&
|
|
LLMediaEngine::getInstance ()->getUrl ().length () &&
|
|
LLMediaEngine::getInstance ()->getImageUUID ().notNull () &&
|
|
LLMediaEngine::getInstance ()->isEnabled () &&
|
|
LLMediaEngine::getInstance ()->isAvailable () &&
|
|
gSavedSettings.getBOOL ( "AudioStreamingVideo" ) )
|
|
{
|
|
// display remote control
|
|
mMediaRemote->setVisible ( TRUE );
|
|
mMediaRemote->setEnabled ( TRUE );
|
|
|
|
if ( LLMediaEngine::getInstance ()->getMediaRenderer () )
|
|
{
|
|
if ( LLMediaEngine::getInstance ()->getMediaRenderer ()->isPlaying () ||
|
|
LLMediaEngine::getInstance ()->getMediaRenderer ()->isLooping () )
|
|
{
|
|
mMediaRemote->setTransportState ( LLMediaRemoteCtrl::Pause, TRUE );
|
|
}
|
|
else
|
|
if ( LLMediaEngine::getInstance ()->getMediaRenderer ()->isPaused () )
|
|
{
|
|
mMediaRemote->setTransportState ( LLMediaRemoteCtrl::Play, TRUE );
|
|
}
|
|
else
|
|
{
|
|
mMediaRemote->setTransportState ( LLMediaRemoteCtrl::Stop, TRUE );
|
|
};
|
|
};
|
|
}
|
|
else
|
|
{
|
|
mMediaRemote->setVisible ( FALSE );
|
|
mMediaRemote->setEnabled ( FALSE );
|
|
mMediaRemote->setTransportState ( LLMediaRemoteCtrl::Stop, TRUE );
|
|
};
|
|
|
|
BOOL any_button = (childIsVisible("IM Received")
|
|
|| childIsVisible("Set Not Busy")
|
|
|| childIsVisible("Release Keys")
|
|
|| childIsVisible("Mouselook")
|
|
|| childIsVisible("Stand Up")
|
|
|| mMusicRemote->getVisible()
|
|
|| mMediaRemote->getVisible() );
|
|
|
|
|
|
// turn off the whole bar in mouselook
|
|
if (gAgent.cameraMouselook())
|
|
{
|
|
setVisible(FALSE);
|
|
}
|
|
else
|
|
{
|
|
setVisible(any_button);
|
|
};
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
// Static functions
|
|
//-----------------------------------------------------------------------
|
|
|
|
// static
|
|
void LLOverlayBar::onClickIMReceived(void*)
|
|
{
|
|
gIMView->setFloaterOpen(TRUE);
|
|
}
|
|
|
|
|
|
// static
|
|
void LLOverlayBar::onClickSetNotBusy(void*)
|
|
{
|
|
gAgent.clearBusy();
|
|
}
|
|
|
|
|
|
// static
|
|
void LLOverlayBar::onClickReleaseKeys(void*)
|
|
{
|
|
gAgent.forceReleaseControls();
|
|
}
|
|
|
|
// static
|
|
void LLOverlayBar::onClickResetView(void* data)
|
|
{
|
|
handle_reset_view();
|
|
}
|
|
|
|
//static
|
|
void LLOverlayBar::onClickMouselook(void*)
|
|
{
|
|
gAgent.changeCameraToMouselook();
|
|
}
|
|
|
|
//static
|
|
void LLOverlayBar::onClickStandUp(void*)
|
|
{
|
|
gAgent.setControlFlags(AGENT_CONTROL_STAND_UP);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
//
|
|
void
|
|
LLOverlayBar::
|
|
onVolumeChange ( const LLMediaRemoteCtrlObserver::EventType& eventIn )
|
|
{
|
|
LLUICtrl* control = eventIn.getControl ();
|
|
F32 value = eventIn.getValue ();
|
|
|
|
if ( control == mMusicRemote )
|
|
{
|
|
if (gAudiop)
|
|
{
|
|
gAudiop->setInternetStreamGain ( value );
|
|
};
|
|
gSavedSettings.setF32 ( "AudioLevelMusic", value );
|
|
}
|
|
else
|
|
if ( control == mMediaRemote )
|
|
{
|
|
LLMediaEngine::getInstance ()->setVolume ( value );
|
|
gSavedSettings.setF32 ( "MediaAudioVolume", value );
|
|
|
|
};
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
//
|
|
void
|
|
LLOverlayBar::
|
|
onStopButtonPressed ( const LLMediaRemoteCtrlObserver::EventType& eventIn )
|
|
{
|
|
LLUICtrl* control = eventIn.getControl ();
|
|
|
|
if ( control == mMusicRemote )
|
|
{
|
|
if ( gAudiop )
|
|
{
|
|
gAudiop->stopInternetStream ();
|
|
};
|
|
mMusicRemote->setTransportState ( LLMediaRemoteCtrl::Stop, FALSE );
|
|
}
|
|
else
|
|
if ( control == mMediaRemote )
|
|
{
|
|
LLMediaEngine::getInstance ()->stop ();
|
|
mMediaRemote->setTransportState ( LLMediaRemoteCtrl::Stop, TRUE );
|
|
};
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
//
|
|
void LLOverlayBar::onPlayButtonPressed( const LLMediaRemoteCtrlObserver::EventType& eventIn )
|
|
{
|
|
LLUICtrl* control = eventIn.getControl ();
|
|
|
|
LLParcel* parcel = gParcelMgr->getAgentParcel();
|
|
if ( control == mMusicRemote )
|
|
{
|
|
if (gAudiop)
|
|
{
|
|
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 )
|
|
//{
|
|
const char* music_url = parcel->getMusicURL();
|
|
|
|
gAudiop->startInternetStream(music_url);
|
|
|
|
mMusicRemote->setTransportState ( LLMediaRemoteCtrl::Play, FALSE );
|
|
//}
|
|
}
|
|
};
|
|
|
|
// CP: this is the old way of doing things (click play each time on a parcel to start stream)
|
|
//if (gAudiop)
|
|
//{
|
|
// if (gAudiop->isInternetStreamPlaying() > 0)
|
|
// {
|
|
// gAudiop->pauseInternetStream ( 0 );
|
|
// }
|
|
// else
|
|
// {
|
|
// if (parcel)
|
|
// {
|
|
// const char* music_url = parcel->getMusicURL();
|
|
// gAudiop->startInternetStream(music_url);
|
|
// }
|
|
// }
|
|
//};
|
|
//mMusicRemote->setTransportState ( LLMediaRemoteCtrl::Stop, FALSE );
|
|
}
|
|
else
|
|
if ( control == mMediaRemote )
|
|
{
|
|
LLParcel* parcel = gParcelMgr->getAgentParcel();
|
|
if (parcel)
|
|
{
|
|
LLString path( "" );
|
|
LLMediaEngine::getInstance ()->convertImageAndLoadUrl( true, false, path );
|
|
mMediaRemote->setTransportState ( LLMediaRemoteCtrl::Play, TRUE );
|
|
}
|
|
};
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
//
|
|
void LLOverlayBar::onPauseButtonPressed( const LLMediaRemoteCtrlObserver::EventType& eventIn )
|
|
{
|
|
LLUICtrl* control = eventIn.getControl ();
|
|
|
|
if ( control == mMusicRemote )
|
|
{
|
|
if (gAudiop)
|
|
{
|
|
gAudiop->pauseInternetStream ( 1 );
|
|
};
|
|
mMusicRemote->setTransportState ( LLMediaRemoteCtrl::Play, FALSE );
|
|
}
|
|
else
|
|
if ( control == mMediaRemote )
|
|
{
|
|
LLMediaEngine::getInstance ()->pause ();
|
|
mMediaRemote->setTransportState ( LLMediaRemoteCtrl::Pause, TRUE );
|
|
};
|
|
}
|