phoenix-firestorm/indra/newview/lloverlaybar.cpp

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 );
};
}