diff options
57 files changed, 892 insertions, 413 deletions
@@ -370,6 +370,7 @@ then if [ x"$package" != x ] then upload_item installer "$package" binary/octet-stream + upload_item quicklink "$package" binary/octet-stream else record_failure "Failed to upload $package_id package ($package::$additional_package_name)." fi diff --git a/doc/contributions.txt b/doc/contributions.txt index 2f9d0c2c86..89390d9977 100755 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -180,6 +180,9 @@ Ansariel Hiller MAINT-2368 STORM-1931 MAINT-2773 + BUG-3764 + STORM-1984 + STORM-1979 Aralara Rajal Arare Chantilly CHUIBUG-191 @@ -307,6 +310,7 @@ Christopher Organiser Ciaran Laval Cinder Roxley BUG-2326 + BUG-3863 OPEN-185 STORM-1703 STORM-1948 @@ -674,6 +678,19 @@ Jonathan Yap OPEN-161 STORM-1953 STORM-1957 + STORM-1993 + STORM-1980 + OPEN-113 + STORM-1975 + STORM-1982 + STORM-1975 + STORM-1987 + STORM-1982 + STORM-1992 + STORM-1989 + STORM-1987 + STORM-1986 + STORM-1981 Kadah Coba STORM-1060 STORM-1843 @@ -1140,6 +1157,7 @@ snowy Sidran Sovereign Engineer MAINT-2334 OPEN-189 + OPEN-195 SpacedOut Frye VWR-34 VWR-45 @@ -1259,6 +1277,8 @@ Tofu Buzzard Tony Kembia Tonya Souther STORM-1905 + BUG-3875 + BUG-3968 Torben Trautman TouchaHoney Perhaps TraductoresAnonimos Alter diff --git a/indra/lib/python/indra/base/lluuid.py b/indra/lib/python/indra/base/lluuid.py index 369ae4e92f..7413ffe10d 100755 --- a/indra/lib/python/indra/base/lluuid.py +++ b/indra/lib/python/indra/base/lluuid.py @@ -72,7 +72,7 @@ class UUID(object): ip = '' try: ip = socket.gethostbyname(socket.gethostname()) - except(socket.gaierror): + except(socket.gaierror, socket.error): # no ip address, so just default to somewhere in 10.x.x.x ip = '10' for i in range(3): diff --git a/indra/llaudio/llaudiodecodemgr.cpp b/indra/llaudio/llaudiodecodemgr.cpp index 6c97a64ed7..8c31f8b4de 100755 --- a/indra/llaudio/llaudiodecodemgr.cpp +++ b/indra/llaudio/llaudiodecodemgr.cpp @@ -135,7 +135,7 @@ int vfs_seek(void *datasource, ogg_int64_t offset, int whence) origin = -1; break; default: - llerrs << "Invalid whence argument to vfs_seek" << llendl; + LL_ERRS("AudioEngine") << "Invalid whence argument to vfs_seek" << LL_ENDL; return -1; } @@ -197,12 +197,12 @@ BOOL LLVorbisDecodeState::initDecode() vfs_callbacks.close_func = vfs_close; vfs_callbacks.tell_func = vfs_tell; - //llinfos << "Initing decode from vfile: " << mUUID << llendl; + LL_DEBUGS("AudioEngine") << "Initing decode from vfile: " << mUUID << LL_ENDL; mInFilep = new LLVFile(gVFS, mUUID, LLAssetType::AT_SOUND); if (!mInFilep || !mInFilep->getSize()) { - llwarns << "unable to open vorbis source vfile for reading" << llendl; + LL_WARNS("AudioEngine") << "unable to open vorbis source vfile for reading" << LL_ENDL; delete mInFilep; mInFilep = NULL; return FALSE; @@ -211,7 +211,7 @@ BOOL LLVorbisDecodeState::initDecode() int r = ov_open_callbacks(mInFilep, &mVF, NULL, 0, vfs_callbacks); if(r < 0) { - llwarns << r << " Input to vorbis decode does not appear to be an Ogg bitstream: " << mUUID << llendl; + LL_WARNS("AudioEngine") << r << " Input to vorbis decode does not appear to be an Ogg bitstream: " << mUUID << LL_ENDL; return(FALSE); } @@ -229,36 +229,36 @@ BOOL LLVorbisDecodeState::initDecode() if( vi->channels < 1 || vi->channels > LLVORBIS_CLIP_MAX_CHANNELS ) { abort_decode = true; - llwarns << "Bad channel count: " << vi->channels << llendl; + LL_WARNS("AudioEngine") << "Bad channel count: " << vi->channels << LL_ENDL; } } else // !vi { abort_decode = true; - llwarns << "No default bitstream found" << llendl; + LL_WARNS("AudioEngine") << "No default bitstream found" << LL_ENDL; } if( (size_t)sample_count > LLVORBIS_CLIP_REJECT_SAMPLES || (size_t)sample_count <= 0) { abort_decode = true; - llwarns << "Illegal sample count: " << sample_count << llendl; + LL_WARNS("AudioEngine") << "Illegal sample count: " << sample_count << LL_ENDL; } if( size_guess > LLVORBIS_CLIP_REJECT_SIZE || size_guess < 0) { abort_decode = true; - llwarns << "Illegal sample size: " << size_guess << llendl; + LL_WARNS("AudioEngine") << "Illegal sample size: " << size_guess << LL_ENDL; } if( abort_decode ) { - llwarns << "Canceling initDecode. Bad asset: " << mUUID << llendl; + LL_WARNS("AudioEngine") << "Canceling initDecode. Bad asset: " << mUUID << LL_ENDL; vorbis_comment* comment = ov_comment(&mVF,-1); if (comment && comment->vendor) { - llwarns << "Bad asset encoded by: " << comment->vendor << llendl; + LL_WARNS("AudioEngine") << "Bad asset encoded by: " << comment->vendor << LL_ENDL; } delete mInFilep; mInFilep = NULL; @@ -359,12 +359,12 @@ BOOL LLVorbisDecodeState::decodeSection() { if (!mInFilep) { - llwarns << "No VFS file to decode in vorbis!" << llendl; + LL_WARNS("AudioEngine") << "No VFS file to decode in vorbis!" << LL_ENDL; return TRUE; } if (mDone) { -// llwarns << "Already done with decode, aborting!" << llendl; +// LL_WARNS("AudioEngine") << "Already done with decode, aborting!" << LL_ENDL; return TRUE; } char pcmout[4096]; /*Flawfinder: ignore*/ @@ -377,14 +377,14 @@ BOOL LLVorbisDecodeState::decodeSection() eof = TRUE; mDone = TRUE; mValid = TRUE; -// llinfos << "Vorbis EOF" << llendl; +// LL_INFOS("AudioEngine") << "Vorbis EOF" << LL_ENDL; } else if (ret < 0) { /* error in the stream. Not a problem, just reporting it in case we (the app) cares. In this case, we don't. */ - llwarns << "BAD vorbis decode in decodeSection." << llendl; + LL_WARNS("AudioEngine") << "BAD vorbis decode in decodeSection." << LL_ENDL; mValid = FALSE; mDone = TRUE; @@ -393,7 +393,7 @@ BOOL LLVorbisDecodeState::decodeSection() } else { -// llinfos << "Vorbis read " << ret << "bytes" << llendl; +// LL_INFOS("AudioEngine") << "Vorbis read " << ret << "bytes" << LL_ENDL; /* we don't bother dealing with sample rate changes, etc, but. you'll have to*/ std::copy(pcmout, pcmout+ret, std::back_inserter(mWAVBuffer)); @@ -405,7 +405,7 @@ BOOL LLVorbisDecodeState::finishDecode() { if (!isValid()) { - llwarns << "Bogus vorbis decode state for " << getUUID() << ", aborting!" << llendl; + LL_WARNS("AudioEngine") << "Bogus vorbis decode state for " << getUUID() << ", aborting!" << LL_ENDL; return TRUE; // We've finished } @@ -480,7 +480,7 @@ BOOL LLVorbisDecodeState::finishDecode() if (36 == data_length) { - llwarns << "BAD Vorbis decode in finishDecode!" << llendl; + LL_WARNS("AudioEngine") << "BAD Vorbis decode in finishDecode!" << LL_ENDL; mValid = FALSE; return TRUE; // we've finished } @@ -497,7 +497,7 @@ BOOL LLVorbisDecodeState::finishDecode() { if (mBytesRead == 0) { - llwarns << "Unable to write file in LLVorbisDecodeState::finishDecode" << llendl; + LL_WARNS("AudioEngine") << "Unable to write file in LLVorbisDecodeState::finishDecode" << LL_ENDL; mValid = FALSE; return TRUE; // we've finished } @@ -515,7 +515,7 @@ BOOL LLVorbisDecodeState::finishDecode() LLVFile output(gVFS, mUUID, LLAssetType::AT_SOUND_WAV); output.write(&mWAVBuffer[0], mWAVBuffer.size()); #endif - //llinfos << "Finished decode for " << getUUID() << llendl; + LL_DEBUGS("AudioEngine") << "Finished decode for " << getUUID() << LL_ENDL; return TRUE; } @@ -524,7 +524,7 @@ void LLVorbisDecodeState::flushBadFile() { if (mInFilep) { - llwarns << "Flushing bad vorbis file from VFS for " << mUUID << llendl; + LL_WARNS("AudioEngine") << "Flushing bad vorbis file from VFS for " << mUUID << LL_ENDL; mInFilep->remove(); } } @@ -568,7 +568,7 @@ void LLAudioDecodeMgr::Impl::processQueue(const F32 num_secs) if (mCurrentDecodep->isDone() && !mCurrentDecodep->isValid()) { // We had an error when decoding, abort. - llwarns << mCurrentDecodep->getUUID() << " has invalid vorbis data, aborting decode" << llendl; + LL_WARNS("AudioEngine") << mCurrentDecodep->getUUID() << " has invalid vorbis data, aborting decode" << LL_ENDL; mCurrentDecodep->flushBadFile(); LLAudioData *adp = gAudiop->getAudioData(mCurrentDecodep->getUUID()); adp->setHasValidData(false); @@ -590,7 +590,7 @@ void LLAudioDecodeMgr::Impl::processQueue(const F32 num_secs) LLAudioData *adp = gAudiop->getAudioData(mCurrentDecodep->getUUID()); if (!adp) { - llwarns << "Missing LLAudioData for decode of " << mCurrentDecodep->getUUID() << llendl; + LL_WARNS("AudioEngine") << "Missing LLAudioData for decode of " << mCurrentDecodep->getUUID() << LL_ENDL; } else if (mCurrentDecodep->isValid() && mCurrentDecodep->isDone()) { @@ -601,12 +601,12 @@ void LLAudioDecodeMgr::Impl::processQueue(const F32 num_secs) // At this point, we could see if anyone needs this sound immediately, but // I'm not sure that there's a reason to - we need to poll all of the playing // sounds anyway. - //llinfos << "Finished the vorbis decode, now what?" << llendl; + //LL_INFOS("AudioEngine") << "Finished the vorbis decode, now what?" << LL_ENDL; } else { adp->setHasCompletedDecode(true); - llinfos << "Vorbis decode failed for " << mCurrentDecodep->getUUID() << llendl; + LL_INFOS("AudioEngine") << "Vorbis decode failed for " << mCurrentDecodep->getUUID() << LL_ENDL; } mCurrentDecodep = NULL; } @@ -631,7 +631,7 @@ void LLAudioDecodeMgr::Impl::processQueue(const F32 num_secs) continue; } - lldebugs << "Decoding " << uuid << " from audio queue!" << llendl; + lldebugs << "Decoding " << uuid << " from audio queue!" << LL_ENDL; std::string uuid_str; std::string d_path; @@ -674,19 +674,19 @@ BOOL LLAudioDecodeMgr::addDecodeRequest(const LLUUID &uuid) if (gAudiop->hasDecodedFile(uuid)) { // Already have a decoded version, don't need to decode it. - //llinfos << "addDecodeRequest for " << uuid << " has decoded file already" << llendl; + LL_DEBUGS("AudioEngine") << "addDecodeRequest for " << uuid << " has decoded file already" << LL_ENDL; return TRUE; } if (gAssetStorage->hasLocalAsset(uuid, LLAssetType::AT_SOUND)) { // Just put it on the decode queue. - //llinfos << "addDecodeRequest for " << uuid << " has local asset file already" << llendl; + LL_DEBUGS("AudioEngine") << "addDecodeRequest for " << uuid << " has local asset file already" << LL_ENDL; mImpl->mDecodeQueue.push(uuid); return TRUE; } - //llinfos << "addDecodeRequest for " << uuid << " no file available" << llendl; + LL_DEBUGS("AudioEngine") << "addDecodeRequest for " << uuid << " no file available" << LL_ENDL; return FALSE; } diff --git a/indra/llaudio/llaudioengine.cpp b/indra/llaudio/llaudioengine.cpp index 06e752cf34..ca614f5395 100755 --- a/indra/llaudio/llaudioengine.cpp +++ b/indra/llaudio/llaudioengine.cpp @@ -123,7 +123,7 @@ bool LLAudioEngine::init(const S32 num_channels, void* userdata) // Initialize the decode manager gAudioDecodeMgrp = new LLAudioDecodeMgr; - llinfos << "LLAudioEngine::init() AudioEngine successfully initialized" << llendl; + LL_INFOS("AudioEngine") << "LLAudioEngine::init() AudioEngine successfully initialized" << LL_ENDL; return true; } @@ -308,7 +308,7 @@ void LLAudioEngine::idle(F32 max_decode_time) LLAudioChannel *channelp = getFreeChannel(max_priority); if (channelp) { - //llinfos << "Replacing source in channel due to priority!" << llendl; + LL_DEBUGS("AudioEngine") << "Replacing source in channel due to priority!" << LL_ENDL; max_sourcep->setChannel(channelp); channelp->setSource(max_sourcep); if (max_sourcep->isSyncSlave()) @@ -479,7 +479,7 @@ void LLAudioEngine::idle(F32 max_decode_time) { if (!mBuffers[i]->mInUse && mBuffers[i]->mLastUseTimer.getElapsedTimeF32() > 30.f) { - //llinfos << "Flushing unused buffer!" << llendl; + LL_DEBUGS("AudioEngine") << "Flushing unused buffer!" << LL_ENDL; mBuffers[i]->mAudioDatap->mBufferp = NULL; delete mBuffers[i]; mBuffers[i] = NULL; @@ -591,8 +591,8 @@ LLAudioBuffer * LLAudioEngine::getFreeBuffer() if (buffer_id >= 0) { - lldebugs << "Taking over unused buffer " << buffer_id << llendl; - //llinfos << "Flushing unused buffer!" << llendl; + lldebugs << "Taking over unused buffer " << buffer_id << LL_ENDL; + LL_DEBUGS("AudioEngine") << "Flushing unused buffer!" << LL_ENDL; mBuffers[buffer_id]->mAudioDatap->mBufferp = NULL; delete mBuffers[buffer_id]; mBuffers[buffer_id] = createBuffer(); @@ -673,6 +673,8 @@ void LLAudioEngine::cleanupBuffer(LLAudioBuffer *bufferp) bool LLAudioEngine::preloadSound(const LLUUID &uuid) { + LL_DEBUGS("AudioEngine")<<"( "<<uuid<<" )"<<LL_ENDL; + gAudiop->getAudioData(uuid); // We don't care about the return value, this is just to make sure // that we have an entry, which will mean that the audio engine knows about this @@ -684,7 +686,7 @@ bool LLAudioEngine::preloadSound(const LLUUID &uuid) // At some point we need to have the audio/asset system check the static VFS // before it goes off and fetches stuff from the server. - //llwarns << "Used internal preload for non-local sound" << llendl; + LL_DEBUGS("AudioEngine") << "Used internal preload for non-local sound "<< uuid << LL_ENDL; return false; } @@ -815,7 +817,7 @@ void LLAudioEngine::triggerSound(const LLUUID &audio_uuid, const LLUUID& owner_i const S32 type, const LLVector3d &pos_global) { // Create a new source (since this can't be associated with an existing source. - //llinfos << "Localized: " << audio_uuid << llendl; + LL_DEBUGS("AudioEngine") << "Localized: " << audio_uuid << LL_ENDL; if (mMuted) { @@ -982,11 +984,14 @@ void LLAudioEngine::cleanupAudioSource(LLAudioSource *asp) iter = mAllSources.find(asp->getID()); if (iter == mAllSources.end()) { - llwarns << "Cleaning up unknown audio source!" << llendl; - return; + LL_WARNS("AudioEngine") << "Cleaning up unknown audio source!" << LL_ENDL; + } + else + { + LL_DEBUGS("AudioEngine") << "Cleaning up audio sources for "<< asp->getID() <<LL_ENDL; + delete asp; + mAllSources.erase(iter); } - delete asp; - mAllSources.erase(iter); } @@ -1013,16 +1018,18 @@ bool LLAudioEngine::hasDecodedFile(const LLUUID &uuid) bool LLAudioEngine::hasLocalFile(const LLUUID &uuid) { // See if it's in the VFS. - return gVFS->getExists(uuid, LLAssetType::AT_SOUND); + bool have_local = gVFS->getExists(uuid, LLAssetType::AT_SOUND); + LL_DEBUGS("AudioEngine") << "sound uuid "<<uuid<<" exists in VFS"<<LL_ENDL; + return have_local; } void LLAudioEngine::startNextTransfer() { - //llinfos << "LLAudioEngine::startNextTransfer()" << llendl; + //LL_DEBUGS("AudioEngine") << "LLAudioEngine::startNextTransfer()" << LL_ENDL; if (mCurrentTransfer.notNull() || getMuted()) { - //llinfos << "Transfer in progress, aborting" << llendl; + //LL_DEBUGS("AudioEngine") << "Transfer in progress, aborting" << LL_ENDL; return; } @@ -1203,7 +1210,7 @@ void LLAudioEngine::startNextTransfer() if (asset_id.notNull()) { - llinfos << "Getting asset data for: " << asset_id << llendl; + LL_INFOS("AudioEngine") << "Getting audio asset data for: " << asset_id << LL_ENDL; gAudiop->mCurrentTransfer = asset_id; gAudiop->mCurrentTransferTimer.reset(); gAssetStorage->getAssetData(asset_id, LLAssetType::AT_SOUND, @@ -1211,7 +1218,7 @@ void LLAudioEngine::startNextTransfer() } else { - //llinfos << "No pending transfers?" << llendl; + //LL_DEBUGS("AudioEngine") << "No pending transfers?" << LL_ENDL; } } @@ -1221,7 +1228,7 @@ void LLAudioEngine::assetCallback(LLVFS *vfs, const LLUUID &uuid, LLAssetType::E { if (result_code) { - llinfos << "Boom, error in audio file transfer: " << LLAssetStorage::getErrorString( result_code ) << " (" << result_code << ")" << llendl; + LL_INFOS("AudioEngine") << "Boom, error in audio file transfer: " << LLAssetStorage::getErrorString( result_code ) << " (" << result_code << ")" << LL_ENDL; // Need to mark data as bad to avoid constant rerequests. LLAudioData *adp = gAudiop->getAudioData(uuid); if (adp) @@ -1238,11 +1245,11 @@ void LLAudioEngine::assetCallback(LLVFS *vfs, const LLUUID &uuid, LLAssetType::E if (!adp) { // Should never happen - llwarns << "Got asset callback without audio data for " << uuid << llendl; + LL_WARNS("AudioEngine") << "Got asset callback without audio data for " << uuid << LL_ENDL; } else { - // llinfos << "Got asset callback with good audio data for " << uuid << ", making decode request" << llendl; + LL_DEBUGS("AudioEngine") << "Got asset callback with good audio data for " << uuid << ", making decode request" << LL_ENDL; adp->setHasValidData(true); adp->setHasLocalData(true); gAudioDecodeMgrp->addDecodeRequest(uuid); @@ -1321,7 +1328,7 @@ void LLAudioSource::update() } else if (adp->hasCompletedDecode()) // Only mark corrupted after decode is done { - llwarns << "Marking LLAudioSource corrupted for " << adp->getID() << llendl; + LL_WARNS("AudioEngine") << "Marking LLAudioSource corrupted for " << adp->getID() << LL_ENDL; mCorrupted = true ; } } @@ -1357,7 +1364,6 @@ bool LLAudioSource::setupChannel() if (!adp->getBuffer()) { // We're not ready to play back the sound yet, so don't try and allocate a channel for it. - //llwarns << "Aborting, no buffer" << llendl; return false; } @@ -1375,7 +1381,7 @@ bool LLAudioSource::setupChannel() // Ugh, we don't have any free channels. // Now we have to reprioritize. // For now, just don't play the sound. - //llwarns << "Aborting, no free channels" << llendl; + //llwarns << "Aborting, no free channels" << LL_ENDL; return false; } @@ -1474,7 +1480,7 @@ bool LLAudioSource::isDone() const { // We don't have a channel assigned, and it's been // over 15 seconds since we tried to play it. Don't bother. - //llinfos << "No channel assigned, source is done" << llendl; + LL_DEBUGS("AudioEngine") << "No channel assigned, source is done" << LL_ENDL; return true; } else @@ -1640,7 +1646,7 @@ LLAudioChannel::LLAudioChannel() : LLAudioChannel::~LLAudioChannel() { // Need to disconnect any sources which are using this channel. - //llinfos << "Cleaning up audio channel" << llendl; + LL_DEBUGS("AudioEngine") << "Cleaning up audio channel" << LL_ENDL; if (mCurrentSourcep) { mCurrentSourcep->setChannel(NULL); @@ -1651,29 +1657,29 @@ LLAudioChannel::~LLAudioChannel() void LLAudioChannel::setSource(LLAudioSource *sourcep) { - //llinfos << this << ": setSource(" << sourcep << ")" << llendl; - if (!sourcep) { // Clearing the source for this channel, don't need to do anything. - //llinfos << "Clearing source for channel" << llendl; + LL_DEBUGS("AudioEngine") << "Clearing source" << ( mCurrentSourcep ? mCurrentSourcep->getID() : LLUUID::null ) << LL_ENDL; cleanup(); mCurrentSourcep = NULL; mWaiting = false; - return; } - - if (sourcep == mCurrentSourcep) + else { - // Don't reallocate the channel, this will make FMOD goofy. - //llinfos << "Calling setSource with same source!" << llendl; - } - - mCurrentSourcep = sourcep; + LL_DEBUGS("AudioEngine") << "( id: " << sourcep->getID() << ")" << LL_ENDL; + if (sourcep == mCurrentSourcep) + { + // Don't reallocate the channel, this will make FMOD goofy. + //LL_DEBUGS("AudioEngine") << "Calling setSource with same source!" << LL_ENDL; + } - updateBuffer(); - update3DPosition(); + mCurrentSourcep = sourcep; + + updateBuffer(); + update3DPosition(); + } } @@ -1768,7 +1774,7 @@ bool LLAudioData::load() if (mBufferp) { // We already have this sound in a buffer, don't do anything. - llinfos << "Already have a buffer for this sound, don't bother loading!" << llendl; + LL_INFOS("AudioEngine") << "Already have a buffer for this sound, don't bother loading!" << LL_ENDL; return true; } @@ -1776,7 +1782,7 @@ bool LLAudioData::load() if (!mBufferp) { // No free buffers, abort. - llinfos << "Not able to allocate a new audio buffer, aborting." << llendl; + LL_INFOS("AudioEngine") << "Not able to allocate a new audio buffer, aborting." << LL_ENDL; return true; } diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index f74c934b21..cc5742ff7a 100755 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -6747,7 +6747,7 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) return TRUE; } -//adapted from Lengyel, Eric. “Computing Tangent Space Basis Vectors for an Arbitrary Mesh”. Terathon Software 3D Graphics Library, 2001. http://www.terathon.com/code/tangent.html +//adapted from Lengyel, Eric. "Computing Tangent Space Basis Vectors for an Arbitrary Mesh". Terathon Software 3D Graphics Library, 2001. http://www.terathon.com/code/tangent.html void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal, const LLVector2 *texcoord, U32 triangleCount, const U16* index_array, LLVector4a *tangent) { diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp index 50ac511d18..3cfe5ac57f 100755 --- a/indra/llui/llbutton.cpp +++ b/indra/llui/llbutton.cpp @@ -641,7 +641,7 @@ void LLButton::draw() bool use_glow_effect = FALSE; LLColor4 highlighting_color = LLColor4::white; - LLColor4 glow_color; + LLColor4 glow_color = LLColor4::white; LLRender::eBlendType glow_type = LLRender::BT_ADD_WITH_ALPHA; LLUIImage* imagep = NULL; diff --git a/indra/llui/llcommandmanager.cpp b/indra/llui/llcommandmanager.cpp index 49cfb2255e..625fb8e870 100755 --- a/indra/llui/llcommandmanager.cpp +++ b/indra/llui/llcommandmanager.cpp @@ -50,8 +50,6 @@ const LLCommandId LLCommandId::null = LLCommandId("null command"); LLCommand::Params::Params() : available_in_toybox("available_in_toybox", false) , icon("icon") - , hover_icon_unselected("hover_icon_unselected") - , hover_icon_selected("hover_icon_selected") , label_ref("label_ref") , name("name") , tooltip_ref("tooltip_ref") @@ -73,8 +71,6 @@ LLCommand::LLCommand(const LLCommand::Params& p) : mIdentifier(p.name) , mAvailableInToybox(p.available_in_toybox) , mIcon(p.icon) - , mHoverIconUnselected(p.hover_icon_unselected) - , mHoverIconSelected(p.hover_icon_selected) , mLabelRef(p.label_ref) , mName(p.name) , mTooltipRef(p.tooltip_ref) diff --git a/indra/llui/llcommandmanager.h b/indra/llui/llcommandmanager.h index 9f276f712d..ff5a8a3257 100755 --- a/indra/llui/llcommandmanager.h +++ b/indra/llui/llcommandmanager.h @@ -96,9 +96,6 @@ public: Mandatory<std::string> name; Mandatory<std::string> tooltip_ref; - Optional<std::string> hover_icon_selected; - Optional<std::string> hover_icon_unselected; - Mandatory<std::string> execute_function; Optional<LLSD> execute_parameters; @@ -127,8 +124,6 @@ public: const std::string& labelRef() const { return mLabelRef; } const std::string& name() const { return mName; } const std::string& tooltipRef() const { return mTooltipRef; } - const std::string& hoverIconUnselected() const {return mHoverIconUnselected; } - const std::string& hoverIconSelected() const {return mHoverIconSelected; } const std::string& executeFunctionName() const { return mExecuteFunction; } const LLSD& executeParameters() const { return mExecuteParameters; } @@ -155,8 +150,6 @@ private: std::string mLabelRef; std::string mName; std::string mTooltipRef; - std::string mHoverIconUnselected; - std::string mHoverIconSelected; std::string mExecuteFunction; LLSD mExecuteParameters; diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp index 6fd2bb1b36..76ba53ec32 100755 --- a/indra/llui/lltabcontainer.cpp +++ b/indra/llui/lltabcontainer.cpp @@ -193,15 +193,12 @@ LLTabContainer::TabParams::TabParams() : tab_top_image_unselected("tab_top_image_unselected"), tab_top_image_selected("tab_top_image_selected"), tab_top_image_flash("tab_top_image_flash"), - tab_top_image_hovered("tab_top_image_hovered"), tab_bottom_image_unselected("tab_bottom_image_unselected"), tab_bottom_image_selected("tab_bottom_image_selected"), tab_bottom_image_flash("tab_bottom_image_flash"), - tab_bottom_image_hovered("tab_bottom_image_hovered"), tab_left_image_unselected("tab_left_image_unselected"), tab_left_image_selected("tab_left_image_selected"), - tab_left_image_flash("tab_left_image_flash"), - tab_left_image_hovered("tab_left_image_hovered") + tab_left_image_flash("tab_left_image_flash") {} LLTabContainer::Params::Params() @@ -221,8 +218,7 @@ LLTabContainer::Params::Params() open_tabs_on_drag_and_drop("open_tabs_on_drag_and_drop", false), tab_icon_ctrl_pad("tab_icon_ctrl_pad", 0), use_ellipses("use_ellipses"), - font_halign("halign"), - use_highlighting_on_hover("use_highlighting_on_hover",false) + font_halign("halign") {} LLTabContainer::LLTabContainer(const LLTabContainer::Params& p) @@ -258,8 +254,7 @@ LLTabContainer::LLTabContainer(const LLTabContainer::Params& p) mCustomIconCtrlUsed(p.use_custom_icon_ctrl), mOpenTabsOnDragAndDrop(p.open_tabs_on_drag_and_drop), mTabIconCtrlPad(p.tab_icon_ctrl_pad), - mUseTabEllipses(p.use_ellipses), - mUseHighlightingOnHover(p.use_highlighting_on_hover) + mUseTabEllipses(p.use_ellipses) { static LLUICachedControl<S32> tabcntr_vert_tab_min_width ("UITabCntrVertTabMinWidth", 0); @@ -908,30 +903,18 @@ void LLTabContainer::update_images(LLTabTuple* tuple, TabParams params, LLTabCon tuple->mButton->setImageUnselected(static_cast<LLUIImage*>(params.tab_top_image_unselected)); tuple->mButton->setImageSelected(static_cast<LLUIImage*>(params.tab_top_image_selected)); tuple->mButton->setImageFlash(static_cast<LLUIImage*>(params.tab_top_image_flash)); - if(mUseHighlightingOnHover) - { - tuple->mButton->setImageHoverUnselected(static_cast<LLUIImage*>(params.tab_top_image_hovered)); - } } else if (pos == LLTabContainer::BOTTOM) { tuple->mButton->setImageUnselected(static_cast<LLUIImage*>(params.tab_bottom_image_unselected)); tuple->mButton->setImageSelected(static_cast<LLUIImage*>(params.tab_bottom_image_selected)); tuple->mButton->setImageFlash(static_cast<LLUIImage*>(params.tab_bottom_image_flash)); - if(mUseHighlightingOnHover) - { - tuple->mButton->setImageHoverUnselected(static_cast<LLUIImage*>(params.tab_bottom_image_hovered)); - } } else if (pos == LLTabContainer::LEFT) { tuple->mButton->setImageUnselected(static_cast<LLUIImage*>(params.tab_left_image_unselected)); tuple->mButton->setImageSelected(static_cast<LLUIImage*>(params.tab_left_image_selected)); tuple->mButton->setImageFlash(static_cast<LLUIImage*>(params.tab_left_image_flash)); - if(mUseHighlightingOnHover) - { - tuple->mButton->setImageHoverUnselected(static_cast<LLUIImage*>(params.tab_left_image_hovered)); - } } } } diff --git a/indra/llui/lltabcontainer.h b/indra/llui/lltabcontainer.h index 7e7d4ac6e6..57862fc626 100755 --- a/indra/llui/lltabcontainer.h +++ b/indra/llui/lltabcontainer.h @@ -62,15 +62,12 @@ public: Optional<LLUIImage*> tab_top_image_unselected, tab_top_image_selected, tab_top_image_flash, - tab_top_image_hovered, tab_bottom_image_unselected, tab_bottom_image_selected, tab_bottom_image_flash, - tab_bottom_image_hovered, tab_left_image_unselected, tab_left_image_selected, - tab_left_image_flash, - tab_left_image_hovered; + tab_left_image_flash; TabParams(); }; @@ -117,11 +114,6 @@ public: */ Optional<S32> tab_icon_ctrl_pad; - /** - * This variable is used to found out should we highlight tab button on hover - */ - Optional<bool> use_highlighting_on_hover; - Params(); }; @@ -315,7 +307,6 @@ private: bool mOpenTabsOnDragAndDrop; S32 mTabIconCtrlPad; bool mUseTabEllipses; - bool mUseHighlightingOnHover; }; #endif // LL_TABCONTAINER_H diff --git a/indra/llui/lltoolbar.cpp b/indra/llui/lltoolbar.cpp index 6bfe113933..928e82cb8c 100755 --- a/indra/llui/lltoolbar.cpp +++ b/indra/llui/lltoolbar.cpp @@ -928,8 +928,6 @@ LLToolBarButton* LLToolBar::createButton(const LLCommandId& id) button_p.label = LLTrans::getString(commandp->labelRef()); button_p.tool_tip = LLTrans::getString(commandp->tooltipRef()); button_p.image_overlay = LLUI::getUIImage(commandp->icon()); - button_p.image_hover_unselected = LLUI::getUIImage(commandp->hoverIconUnselected()); - button_p.image_hover_selected = LLUI::getUIImage(commandp->hoverIconSelected()); button_p.button_flash_enable = commandp->isFlashingAllowed(); button_p.overwriteFrom(mButtonParams[mButtonType]); LLToolBarButton* button = LLUICtrlFactory::create<LLToolBarButton>(button_p); diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm index 7415c9d8dc..b393a3796d 100644 --- a/indra/llwindow/llopenglview-objc.mm +++ b/indra/llwindow/llopenglview-objc.mm @@ -376,13 +376,6 @@ attributedStringInfo getSegments(NSAttributedString *str) [[self inputContext] handleEvent:theEvent]; } - if ([[theEvent charactersIgnoringModifiers] characterAtIndex:0] == NSCarriageReturnCharacter || - [[theEvent charactersIgnoringModifiers] characterAtIndex:0] == NSEnterCharacter) - { - // callKeyDown won't return the value we expect for enter or return. Handle them as a separate case. - [[self inputContext] handleEvent:theEvent]; - } - // OS X intentionally does not send us key-up information on cmd-key combinations. // This behaviour is not a bug, and only applies to cmd-combinations (no others). // Since SL assumes we receive those, we fake it here. diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index c5e1cde4e6..17e340d136 100755 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -267,6 +267,7 @@ set(viewer_SOURCE_FILES llfloaterregiondebugconsole.cpp llfloaterregioninfo.cpp llfloaterreporter.cpp + llfloaterregionrestarting.cpp llfloaterscriptdebug.cpp llfloaterscriptlimits.cpp llfloatersearch.cpp @@ -855,6 +856,7 @@ set(viewer_HEADER_FILES llfloaterregiondebugconsole.h llfloaterregioninfo.h llfloaterreporter.h + llfloaterregionrestarting.h llfloaterscriptdebug.h llfloaterscriptlimits.h llfloatersearch.h diff --git a/indra/newview/app_settings/commands.xml b/indra/newview/app_settings/commands.xml index ce878f156b..60c942094a 100755 --- a/indra/newview/app_settings/commands.xml +++ b/indra/newview/app_settings/commands.xml @@ -3,8 +3,6 @@ <command name="aboutland" available_in_toybox="true" icon="Command_AboutLand_Icon" - hover_icon_unselected="Command_Highlighting_Icon" - hover_icon_selected="Command_Highlighting_Selected_Icon" label_ref="Command_AboutLand_Label" tooltip_ref="Command_AboutLand_Tooltip" execute_function="Floater.ToggleOrBringToFront" @@ -15,8 +13,6 @@ <command name="appearance" available_in_toybox="true" icon="Command_Appearance_Icon" - hover_icon_unselected="Command_Highlighting_Icon" - hover_icon_selected="Command_Highlighting_Selected_Icon" label_ref="Command_Appearance_Label" tooltip_ref="Command_Appearance_Tooltip" execute_function="Floater.ToggleOrBringToFront" @@ -27,8 +23,6 @@ <command name="avatar" available_in_toybox="true" icon="Command_Avatar_Icon" - hover_icon_unselected="Command_Highlighting_Icon" - hover_icon_selected="Command_Highlighting_Selected_Icon" label_ref="Command_Avatar_Label" tooltip_ref="Command_Avatar_Tooltip" execute_function="Floater.ToggleOrBringToFront" @@ -39,8 +33,6 @@ <command name="build" available_in_toybox="true" icon="Command_Build_Icon" - hover_icon_unselected="Command_Highlighting_Icon" - hover_icon_selected="Command_Highlighting_Selected_Icon" label_ref="Command_Build_Label" tooltip_ref="Command_Build_Tooltip" execute_function="Build.Toggle" @@ -54,8 +46,6 @@ available_in_toybox="true" is_flashing_allowed="true" icon="Command_Chat_Icon" - hover_icon_unselected="Command_Highlighting_Icon" - hover_icon_selected="Command_Highlighting_Selected_Icon" label_ref="Command_Chat_Label" tooltip_ref="Command_Conversations_Tooltip" execute_function="Floater.ToggleOrBringToFront" @@ -66,8 +56,6 @@ <command name="compass" available_in_toybox="false" icon="Command_Compass_Icon" - hover_icon_unselected="Command_Highlighting_Icon" - hover_icon_selected="Command_Highlighting_Selected_Icon" label_ref="Command_Compass_Label" tooltip_ref="Command_Compass_Tooltip" execute_function="Floater.ToggleOrBringToFront" @@ -78,8 +66,6 @@ <command name="destinations" available_in_toybox="true" icon="Command_Destinations_Icon" - hover_icon_unselected="Command_Highlighting_Icon" - hover_icon_selected="Command_Highlighting_Selected_Icon" label_ref="Command_Destinations_Label" tooltip_ref="Command_Destinations_Tooltip" execute_function="Floater.ToggleOrBringToFront" @@ -90,8 +76,6 @@ <command name="gestures" available_in_toybox="true" icon="Command_Gestures_Icon" - hover_icon_unselected="Command_Highlighting_Icon" - hover_icon_selected="Command_Highlighting_Selected_Icon" label_ref="Command_Gestures_Label" tooltip_ref="Command_Gestures_Tooltip" execute_function="Floater.ToggleOrBringToFront" @@ -102,8 +86,6 @@ <command name="howto" available_in_toybox="true" icon="Command_HowTo_Icon" - hover_icon_unselected="Command_Highlighting_Icon" - hover_icon_selected="Command_Highlighting_Selected_Icon" label_ref="Command_HowTo_Label" tooltip_ref="Command_HowTo_Tooltip" execute_function="Help.ToggleHowTo" @@ -112,8 +94,6 @@ <command name="inventory" available_in_toybox="true" icon="Command_Inventory_Icon" - hover_icon_unselected="Command_Highlighting_Icon" - hover_icon_selected="Command_Highlighting_Selected_Icon" label_ref="Command_Inventory_Label" tooltip_ref="Command_Inventory_Tooltip" execute_function="Floater.ToggleOrBringToFront" @@ -124,8 +104,6 @@ <command name="map" available_in_toybox="true" icon="Command_Map_Icon" - hover_icon_unselected="Command_Highlighting_Icon" - hover_icon_selected="Command_Highlighting_Selected_Icon" label_ref="Command_Map_Label" tooltip_ref="Command_Map_Tooltip" execute_function="Floater.ToggleOrBringToFront" @@ -136,8 +114,6 @@ <command name="marketplace" available_in_toybox="false" icon="Command_Marketplace_Icon" - hover_icon_unselected="Command_Highlighting_Icon" - hover_icon_selected="Command_Highlighting_Selected_Icon" label_ref="Command_Marketplace_Label" tooltip_ref="Command_Marketplace_Tooltip" execute_function="Avatar.OpenMarketplace" @@ -145,8 +121,6 @@ <command name="minimap" available_in_toybox="true" icon="Command_MiniMap_Icon" - hover_icon_unselected="Command_Highlighting_Icon" - hover_icon_selected="Command_Highlighting_Selected_Icon" label_ref="Command_MiniMap_Label" tooltip_ref="Command_MiniMap_Tooltip" execute_function="Floater.ToggleOrBringToFront" @@ -157,8 +131,6 @@ <command name="move" available_in_toybox="true" icon="Command_Move_Icon" - hover_icon_unselected="Command_Highlighting_Icon" - hover_icon_selected="Command_Highlighting_Selected_Icon" label_ref="Command_Move_Label" tooltip_ref="Command_Move_Tooltip" execute_function="Floater.ToggleOrBringToFront" @@ -169,8 +141,6 @@ <command name="outbox" available_in_toybox="false" icon="Command_Outbox_Icon" - hover_icon_unselected="Command_Highlighting_Icon" - hover_icon_selected="Command_Highlighting_Selected_Icon" label_ref="Command_Outbox_Label" tooltip_ref="Command_Outbox_Tooltip" execute_function="Floater.ToggleOrBringToFront" @@ -181,8 +151,6 @@ <command name="people" available_in_toybox="true" icon="Command_People_Icon" - hover_icon_unselected="Command_Highlighting_Icon" - hover_icon_selected="Command_Highlighting_Selected_Icon" label_ref="Command_People_Label" tooltip_ref="Command_People_Tooltip" execute_function="Floater.ToggleOrBringToFront" @@ -193,8 +161,6 @@ <command name="picks" available_in_toybox="true" icon="Command_Picks_Icon" - hover_icon_unselected="Command_Highlighting_Icon" - hover_icon_selected="Command_Highlighting_Selected_Icon" label_ref="Command_Picks_Label" tooltip_ref="Command_Picks_Tooltip" execute_function="Floater.ToggleOrBringToFront" @@ -205,8 +171,6 @@ <command name="places" available_in_toybox="true" icon="Command_Places_Icon" - hover_icon_unselected="Command_Highlighting_Icon" - hover_icon_selected="Command_Highlighting_Selected_Icon" label_ref="Command_Places_Label" tooltip_ref="Command_Places_Tooltip" execute_function="Floater.ToggleOrBringToFront" @@ -217,8 +181,6 @@ <command name="preferences" available_in_toybox="true" icon="Command_Preferences_Icon" - hover_icon_unselected="Command_Highlighting_Icon" - hover_icon_selected="Command_Highlighting_Selected_Icon" label_ref="Command_Preferences_Label" tooltip_ref="Command_Preferences_Tooltip" execute_function="Floater.ToggleOrBringToFront" @@ -229,8 +191,6 @@ <command name="profile" available_in_toybox="true" icon="Command_Profile_Icon" - hover_icon_unselected="Command_Highlighting_Icon" - hover_icon_selected="Command_Highlighting_Selected_Icon" label_ref="Command_Profile_Label" tooltip_ref="Command_Profile_Tooltip" execute_function="Avatar.ToggleMyProfile" @@ -239,8 +199,6 @@ <command name="search" available_in_toybox="true" icon="Command_Search_Icon" - hover_icon_unselected="Command_Highlighting_Icon" - hover_icon_selected="Command_Highlighting_Selected_Icon" label_ref="Command_Search_Label" tooltip_ref="Command_Search_Tooltip" execute_function="Floater.ToggleOrBringToFront" @@ -251,8 +209,6 @@ <command name="snapshot" available_in_toybox="true" icon="Command_Snapshot_Icon" - hover_icon_unselected="Command_Highlighting_Icon" - hover_icon_selected="Command_Highlighting_Selected_Icon" label_ref="Command_Snapshot_Label" tooltip_ref="Command_Snapshot_Tooltip" execute_function="Floater.ToggleOrBringToFront" @@ -273,8 +229,6 @@ <command name="speak" available_in_toybox="true" icon="Command_Speak_Icon" - hover_icon_unselected="Command_Highlighting_Icon" - hover_icon_selected="Command_Highlighting_Selected_Icon" label_ref="Command_Speak_Label" tooltip_ref="Command_Speak_Tooltip" execute_function="Agent.PressMicrophone" @@ -289,8 +243,6 @@ <command name="view" available_in_toybox="true" icon="Command_View_Icon" - hover_icon_unselected="Command_Highlighting_Icon" - hover_icon_selected="Command_Highlighting_Selected_Icon" label_ref="Command_View_Label" tooltip_ref="Command_View_Tooltip" execute_function="Floater.ToggleOrBringToFront" diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index d9093c2a6d..db151817e0 100755 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -12632,6 +12632,17 @@ <key>Value</key> <string>00000000-0000-0000-0000-000000000000</string> </map> + <key>UISndRestart</key> + <map> + <key>Comment</key> + <string>Sound file for region restarting (uuid for sound asset)</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>String</string> + <key>Value</key> + <string>b92a0f64-7709-8811-40c5-16afd624a45f</string> + </map> <key>UISndSnapshot</key> <map> <key>Comment</key> @@ -14871,17 +14882,6 @@ <key>Value</key> <integer>0</integer> </map> - <key>DisablePrecacheDelayAfterTeleporting</key> - <map> - <key>Comment</key> - <string>Disables the artificial delay in the viewer that precaches some incoming assets</string> - <key>Persist</key> - <integer>0</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>0</integer> - </map> <key>FMODExProfilerEnable</key> <map> <key>Comment</key> diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 79da9e5873..f150ceda67 100755 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -259,11 +259,9 @@ bool handleSlowMotionAnimation(const LLSD& newvalue) return true; } -// static -void LLAgent::parcelChangedCallback() +void LLAgent::setCanEditParcel() // called via mParcelChangedSignal { bool can_edit = LLToolMgr::getInstance()->canEdit(); - gAgent.mCanEditParcel = can_edit; } @@ -425,6 +423,8 @@ LLAgent::LLAgent() : mListener.reset(new LLAgentListener(*this)); + addParcelChangedCallback(&setCanEditParcel); + mMoveTimer.stop(); } @@ -451,8 +451,6 @@ void LLAgent::init() mLastKnownRequestMaturity = mLastKnownResponseMaturity; mIsDoSendMaturityPreferenceToServer = true; - LLViewerParcelMgr::getInstance()->addAgentParcelChangedCallback(boost::bind(&LLAgent::parcelChangedCallback)); - if (!mTeleportFinishedSlot.connected()) { mTeleportFinishedSlot = LLViewerParcelMgr::getInstance()->setTeleportFinishedCallback(boost::bind(&LLAgent::handleTeleportFinished, this)); @@ -835,22 +833,33 @@ void LLAgent::handleServerBakeRegionTransition(const LLUUID& region_id) } } +void LLAgent::changeParcels() +{ + LL_DEBUGS("AgentLocation") << "Calling ParcelChanged callbacks" << LL_ENDL; + // Notify anything that wants to know about parcel changes + mParcelChangedSignal(); +} + +boost::signals2::connection LLAgent::addParcelChangedCallback(parcel_changed_callback_t cb) +{ + return mParcelChangedSignal.connect(cb); +} + //----------------------------------------------------------------------------- // setRegion() //----------------------------------------------------------------------------- void LLAgent::setRegion(LLViewerRegion *regionp) { - bool teleport = true; - + bool notifyRegionChange; + llassert(regionp); if (mRegionp != regionp) { - // std::string host_name; - // host_name = regionp->getHost().getHostName(); - + notifyRegionChange = true; + std::string ip = regionp->getHost().getString(); - llinfos << "Moving agent into region: " << regionp->getName() - << " located at " << ip << llendl; + LL_INFOS("AgentLocation") << "Moving agent into region: " << regionp->getName() + << " located at " << ip << LL_ENDL; if (mRegionp) { // We've changed regions, we're now going to change our agent coordinate frame. @@ -878,9 +887,6 @@ void LLAgent::setRegion(LLViewerRegion *regionp) { gSky.mVOGroundp->setRegion(regionp); } - - // Notify windlight managers - teleport = (gAgent.getTeleportState() != LLAgent::TELEPORT_NONE); } else { @@ -902,8 +908,14 @@ void LLAgent::setRegion(LLViewerRegion *regionp) // Pass new region along to metrics components that care about this level of detail. LLAppViewer::metricsUpdateRegion(regionp->getHandle()); } + else + { + notifyRegionChange = false; + } mRegionp = regionp; + // TODO - most of what follows probably should be moved into callbacks + // Pass the region host to LLUrlEntryParcel to resolve parcel name // with a server request. LLUrlEntryParcel::setRegionHost(getRegionHost()); @@ -922,15 +934,6 @@ void LLAgent::setRegion(LLViewerRegion *regionp) LLFloaterMove::sUpdateFlyingStatus(); - if (teleport) - { - LLEnvManagerNew::instance().onTeleport(); - } - else - { - LLEnvManagerNew::instance().onRegionCrossing(); - } - // If the newly entered region is using server bakes, and our // current appearance is non-baked, request appearance update from // server. @@ -943,6 +946,12 @@ void LLAgent::setRegion(LLViewerRegion *regionp) // Need to handle via callback after caps arrive. mRegionp->setCapabilitiesReceivedCallback(boost::bind(&LLAgent::handleServerBakeRegionTransition,this,_1)); } + + if (notifyRegionChange) + { + LL_DEBUGS("AgentLocation") << "Calling RegionChanged callbacks" << LL_ENDL; + mRegionChangedSignal(); + } } @@ -967,6 +976,16 @@ LLHost LLAgent::getRegionHost() const } } +boost::signals2::connection LLAgent::addRegionChangedCallback(const region_changed_signal_t::slot_type& cb) +{ + return mRegionChangedSignal.connect(cb); +} + +void LLAgent::removeRegionChangedCallback(boost::signals2::connection callback) +{ + mRegionChangedSignal.disconnect(callback); +} + //----------------------------------------------------------------------------- // inPrelude() //----------------------------------------------------------------------------- diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index 7fac17d098..0766407494 100755 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -231,15 +231,54 @@ private: LLVector3 mHomePosRegion; //-------------------------------------------------------------------- - // Region + // Parcel //-------------------------------------------------------------------- public: + void changeParcels(); // called by LLViewerParcelMgr when we cross a parcel boundary + + // Register a boost callback to be called when the agent changes parcels + typedef boost::function<void()> parcel_changed_callback_t; + boost::signals2::connection addParcelChangedCallback(parcel_changed_callback_t); + +private: + typedef boost::signals2::signal<void()> parcel_changed_signal_t; + parcel_changed_signal_t mParcelChangedSignal; + + //-------------------------------------------------------------------- + // Region + //-------------------------------------------------------------------- + public: void setRegion(LLViewerRegion *regionp); LLViewerRegion *getRegion() const; LLHost getRegionHost() const; BOOL inPrelude(); -private: + + /** + * Register a boost callback to be called when the agent changes regions + * Note that if you need to access a capability for the region, you may need to wait + * for the capabilities to be received, since in some cases your region changed + * callback will be called before the capabilities have been received. Your callback + * may need to look something like: + * + * LLViewerRegion* region = gAgent.getRegion(); + * if (region->capabilitiesReceived()) + * { + * useCapability(region); + * } + * else // Need to handle via callback after caps arrive. + * { + * region->setCapabilitiesReceivedCallback(boost::bind(&useCapability,region,_1)); + * // you may or may not want to remove that callback + * } + */ + typedef boost::signals2::signal<void()> region_changed_signal_t; + + boost::signals2::connection addRegionChangedCallback(const region_changed_signal_t::slot_type& cb); + void removeRegionChangedCallback(boost::signals2::connection callback); + + private: LLViewerRegion *mRegionp; + region_changed_signal_t mRegionChangedSignal; //-------------------------------------------------------------------- // History @@ -640,9 +679,10 @@ private: public: bool canEditParcel() const { return mCanEditParcel; } private: + static void setCanEditParcel(); bool mCanEditParcel; - static void parcelChangedCallback(); + /******************************************************************************** ** ** diff --git a/indra/newview/llenvmanager.cpp b/indra/newview/llenvmanager.cpp index 86fe6754dc..589cf28615 100755 --- a/indra/newview/llenvmanager.cpp +++ b/indra/newview/llenvmanager.cpp @@ -92,9 +92,11 @@ void LLEnvPrefs::setUseDayCycle(const std::string& name) } //============================================================================= -LLEnvManagerNew::LLEnvManagerNew() +LLEnvManagerNew::LLEnvManagerNew(): + mInterpNextChangeMessage(true), + mCurRegionUUID(LLUUID::null), + mLastReceivedID(LLUUID::null) { - mInterpNextChangeMessage = true; // Set default environment settings. mUserPrefs.mUseRegionSettings = true; @@ -102,6 +104,9 @@ LLEnvManagerNew::LLEnvManagerNew() mUserPrefs.mWaterPresetName = "Default"; mUserPrefs.mSkyPresetName = "Default"; mUserPrefs.mDayCycleName = "Default"; + + LL_DEBUGS("Windlight")<<LL_ENDL; + gAgent.addRegionChangedCallback(boost::bind(&LLEnvManagerNew::onRegionChange, this)); } bool LLEnvManagerNew::getUseRegionSettings() const @@ -300,6 +305,11 @@ void LLEnvManagerNew::loadUserPrefs() mUserPrefs.mUseRegionSettings = gSavedSettings.getBOOL("UseEnvironmentFromRegion"); mUserPrefs.mUseDayCycle = gSavedSettings.getBOOL("UseDayCycle"); + + if (mUserPrefs.mUseRegionSettings) + { + requestRegionSettings(); + } } void LLEnvManagerNew::saveUserPrefs() @@ -398,6 +408,7 @@ void LLEnvManagerNew::dumpPresets() void LLEnvManagerNew::requestRegionSettings() { + LL_DEBUGS("Windlight") << LL_ENDL; LLEnvironmentRequest::initiate(); } @@ -422,11 +433,6 @@ boost::signals2::connection LLEnvManagerNew::setRegionSettingsChangeCallback(con return mRegionSettingsChangeSignal.connect(cb); } -boost::signals2::connection LLEnvManagerNew::setRegionChangeCallback(const region_change_signal_t::slot_type& cb) -{ - return mRegionChangeSignal.connect(cb); -} - boost::signals2::connection LLEnvManagerNew::setRegionSettingsAppliedCallback(const region_settings_applied_signal_t::slot_type& cb) { return mRegionSettingsAppliedSignal.connect(cb); @@ -457,25 +463,13 @@ const std::string LLEnvManagerNew::getScopeString(LLEnvKey::EScope scope) } } -void LLEnvManagerNew::onRegionCrossing() -{ - LL_DEBUGS("Windlight") << "Crossed region" << LL_ENDL; - onRegionChange(true); -} - -void LLEnvManagerNew::onTeleport() -{ - LL_DEBUGS("Windlight") << "Teleported" << LL_ENDL; - onRegionChange(false); -} - void LLEnvManagerNew::onRegionSettingsResponse(const LLSD& content) { // If the message was valid, grab the UUID from it and save it for next outbound update message. mLastReceivedID = content[0]["messageID"].asUUID(); // Refresh cached region settings. - LL_DEBUGS("Windlight") << "Caching region environment settings: " << content << LL_ENDL; + LL_DEBUGS("Windlight") << "Received region environment settings: " << content << LL_ENDL; F32 sun_hour = 0; // *TODO LLEnvironmentSettings new_settings(content[1], content[2], content[3], sun_hour); mCachedRegionPrefs = new_settings; @@ -594,6 +588,7 @@ void LLEnvManagerNew::updateWaterFromPrefs(bool interpolate) void LLEnvManagerNew::updateManagersFromPrefs(bool interpolate) { + LL_DEBUGS("Windlight")<<LL_ENDL; // Apply water settings. updateWaterFromPrefs(interpolate); @@ -651,28 +646,35 @@ bool LLEnvManagerNew::useDefaultWater() } -void LLEnvManagerNew::onRegionChange(bool interpolate) +void LLEnvManagerNew::onRegionChange() { // Avoid duplicating region setting requests // by checking whether the region is actually changing. LLViewerRegion* regionp = gAgent.getRegion(); LLUUID region_uuid = regionp ? regionp->getRegionID() : LLUUID::null; - if (region_uuid == mCurRegionUUID) + if (region_uuid != mCurRegionUUID) { - return; + // Clear locally modified region settings. + mNewRegionPrefs.clear(); + + // *TODO: clear environment settings of the previous region? + + // Request environment settings of the new region. + mCurRegionUUID = region_uuid; + // for region crossings, interpolate the change; for teleports, don't + mInterpNextChangeMessage = (gAgent.getTeleportState() == LLAgent::TELEPORT_NONE); + LL_DEBUGS("Windlight") << (mInterpNextChangeMessage ? "Crossed" : "Teleported") + << " to new region: " << region_uuid + << LL_ENDL; + requestRegionSettings(); + } + else + { + LL_DEBUGS("Windlight") << "disregarding region change; interp: " + << (mInterpNextChangeMessage ? "true" : "false") + << " regionp: " << regionp + << " old: " << mCurRegionUUID + << " new: " << region_uuid + << LL_ENDL; } - - // Clear locally modified region settings. - mNewRegionPrefs.clear(); - - // *TODO: clear environment settings of the previous region? - - // Request environment settings of the new region. - LL_DEBUGS("Windlight") << "New viewer region: " << region_uuid << LL_ENDL; - mCurRegionUUID = region_uuid; - mInterpNextChangeMessage = interpolate; - requestRegionSettings(); - - // Let interested parties know agent region has been changed. - mRegionChangeSignal(); } diff --git a/indra/newview/llenvmanager.h b/indra/newview/llenvmanager.h index ad56761bc7..c7877303fc 100755 --- a/indra/newview/llenvmanager.h +++ b/indra/newview/llenvmanager.h @@ -166,7 +166,6 @@ class LLEnvManagerNew : public LLSingleton<LLEnvManagerNew> public: typedef boost::signals2::signal<void()> prefs_change_signal_t; typedef boost::signals2::signal<void()> region_settings_change_signal_t; - typedef boost::signals2::signal<void()> region_change_signal_t; typedef boost::signals2::signal<void(bool)> region_settings_applied_signal_t; LLEnvManagerNew(); @@ -222,15 +221,12 @@ public: bool sendRegionSettings(const LLEnvironmentSettings& new_settings); boost::signals2::connection setPreferencesChangeCallback(const prefs_change_signal_t::slot_type& cb); boost::signals2::connection setRegionSettingsChangeCallback(const region_settings_change_signal_t::slot_type& cb); - boost::signals2::connection setRegionChangeCallback(const region_change_signal_t::slot_type& cb); boost::signals2::connection setRegionSettingsAppliedCallback(const region_settings_applied_signal_t::slot_type& cb); static bool canEditRegionSettings(); /// @return true if we have access to editing region environment static const std::string getScopeString(LLEnvKey::EScope scope); // Public callbacks. - void onRegionCrossing(); - void onTeleport(); void onRegionSettingsResponse(const LLSD& content); void onRegionSettingsApplyResponse(bool ok); @@ -251,7 +247,7 @@ private: bool useDefaultSky(); bool useDefaultWater(); - void onRegionChange(bool interpolate); + void onRegionChange(); /// Emitted when user environment preferences change. prefs_change_signal_t mUsePrefsChangeSignal; @@ -260,9 +256,6 @@ private: region_settings_change_signal_t mRegionSettingsChangeSignal; /// Emitted when agent region changes. Move to LLAgent? - region_change_signal_t mRegionChangeSignal; - - /// Emitted when agent region changes. Move to LLAgent? region_settings_applied_signal_t mRegionSettingsAppliedSignal; LLEnvPrefs mUserPrefs; /// User environment preferences. diff --git a/indra/newview/llfloatereditdaycycle.cpp b/indra/newview/llfloatereditdaycycle.cpp index b63677b258..78e20e3bf0 100755 --- a/indra/newview/llfloatereditdaycycle.cpp +++ b/indra/newview/llfloatereditdaycycle.cpp @@ -145,7 +145,7 @@ void LLFloaterEditDayCycle::initCallbacks(void) // Connect to env manager events. LLEnvManagerNew& env_mgr = LLEnvManagerNew::instance(); env_mgr.setRegionSettingsChangeCallback(boost::bind(&LLFloaterEditDayCycle::onRegionSettingsChange, this)); - env_mgr.setRegionChangeCallback(boost::bind(&LLFloaterEditDayCycle::onRegionChange, this)); + gAgent.addRegionChangedCallback(boost::bind(&LLFloaterEditDayCycle::onRegionChange, this)); env_mgr.setRegionSettingsAppliedCallback(boost::bind(&LLFloaterEditDayCycle::onRegionSettingsApplied, this, _1)); // Connect to day cycle manager events. diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp index 14e1a486d3..84921849d0 100755 --- a/indra/newview/llfloaterimsession.cpp +++ b/indra/newview/llfloaterimsession.cpp @@ -61,6 +61,9 @@ #include "llnotificationmanager.h" #include "llautoreplace.h" +const F32 ME_TYPING_TIMEOUT = 4.0f; +const F32 OTHER_TYPING_TIMEOUT = 9.0f; + floater_showed_signal_t LLFloaterIMSession::sIMFloaterShowedSignal; LLFloaterIMSession::LLFloaterIMSession(const LLUUID& session_id) @@ -75,7 +78,10 @@ LLFloaterIMSession::LLFloaterIMSession(const LLUUID& session_id) mTypingTimer(), mTypingTimeoutTimer(), mPositioned(false), - mSessionInitialized(false) + mSessionInitialized(false), + mMeTypingTimer(), + mOtherTypingTimer(), + mImInfo() { mIsNearbyChat = false; @@ -96,13 +102,31 @@ LLFloaterIMSession::LLFloaterIMSession(const LLUUID& session_id) void LLFloaterIMSession::refresh() { if (mMeTyping) -{ + { + // Send an additional Start Typing packet every ME_TYPING_TIMEOUT seconds + if (mMeTypingTimer.getElapsedTimeF32() > ME_TYPING_TIMEOUT && false == mShouldSendTypingState) + { + LL_DEBUGS("TypingMsgs") << "Send additional Start Typing packet" << LL_ENDL; + LLIMModel::instance().sendTypingState(mSessionID, mOtherParticipantUUID, TRUE); + mMeTypingTimer.reset(); + } + // Time out if user hasn't typed for a while. if (mTypingTimeoutTimer.getElapsedTimeF32() > LLAgent::TYPING_TIMEOUT_SECS) { - setTyping(false); + setTyping(false); + LL_DEBUGS("TypingMsgs") << "Send stop typing due to timeout" << LL_ENDL; } } + + // Clear <name is typing> message if no data received for OTHER_TYPING_TIMEOUT seconds + if (mOtherTyping && mOtherTypingTimer.getElapsedTimeF32() > OTHER_TYPING_TIMEOUT) + { + LL_DEBUGS("TypingMsgs") << "Received: is typing cleared due to timeout" << LL_ENDL; + removeTypingIndicator(mImInfo); + mOtherTyping = false; + } + } // virtual @@ -953,13 +977,21 @@ void LLFloaterIMSession::setTyping(bool typing) // much network traffic. Only send in person-to-person IMs. if ( mShouldSendTypingState && mDialog == IM_NOTHING_SPECIAL ) { - // Still typing, send 'start typing' notification or - // send 'stop typing' notification immediately - if (!mMeTyping || mTypingTimer.getElapsedTimeF32() > 1.f) + if ( mMeTyping ) { - LLIMModel::instance().sendTypingState(mSessionID, - mOtherParticipantUUID, mMeTyping); - mShouldSendTypingState = false; + if ( mTypingTimer.getElapsedTimeF32() > 1.f ) + { + // Still typing, send 'start typing' notification + LLIMModel::instance().sendTypingState(mSessionID, mOtherParticipantUUID, TRUE); + mShouldSendTypingState = false; + mMeTypingTimer.reset(); + } + } + else + { + // Send 'stop typing' notification immediately + LLIMModel::instance().sendTypingState(mSessionID, mOtherParticipantUUID, FALSE); + mShouldSendTypingState = false; } } @@ -975,10 +1007,12 @@ void LLFloaterIMSession::setTyping(bool typing) void LLFloaterIMSession::processIMTyping(const LLIMInfo* im_info, BOOL typing) { + LL_DEBUGS("TypingMsgs") << "typing=" << typing << LL_ENDL; if ( typing ) { // other user started typing addTypingIndicator(im_info); + mOtherTypingTimer.reset(); } else { @@ -1202,10 +1236,40 @@ BOOL LLFloaterIMSession::inviteToSession(const uuid_vec_t& ids) void LLFloaterIMSession::addTypingIndicator(const LLIMInfo* im_info) { +/* Operation of "<name> is typing" state machine: +Not Typing state: + + User types in P2P IM chat ... Send Start Typing, save Started time, + start Idle Timer (N seconds) go to Typing state + +Typing State: + + User enters a non-return character: if Now - Started > ME_TYPING_TIMEOUT, send + Start Typing, restart Idle Timer + User enters a return character: stop Idle Timer, send IM and Stop + Typing, go to Not Typing state + Idle Timer expires: send Stop Typing, go to Not Typing state + +The recipient has a complementary state machine in which a Start Typing +that is not followed by either an IM or another Start Typing within OTHER_TYPING_TIMEOUT +seconds switches the sender out of typing state. + +This has the nice quality of being self-healing for lost start/stop +messages while adding messages only for the (relatively rare) case of a +user who types a very long message (one that takes more than ME_TYPING_TIMEOUT seconds +to type). + +Note: OTHER_TYPING_TIMEOUT must be > ME_TYPING_TIMEOUT for proper operation of the state machine + +*/ + // We may have lost a "stop-typing" packet, don't add it twice if (im_info && !mOtherTyping) { mOtherTyping = true; + mOtherTypingTimer.reset(); + // Save im_info so that removeTypingIndicator can be properly called because a timeout has occurred + mImInfo = im_info; // Update speaker LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID); diff --git a/indra/newview/llfloaterimsession.h b/indra/newview/llfloaterimsession.h index d6718843ca..2b9d06e744 100755 --- a/indra/newview/llfloaterimsession.h +++ b/indra/newview/llfloaterimsession.h @@ -187,6 +187,8 @@ private: LLFrameTimer mTypingTimer; LLFrameTimer mTypingTimeoutTimer; bool mSessionNameUpdatedForTyping; + LLFrameTimer mMeTypingTimer; + LLFrameTimer mOtherTypingTimer; bool mSessionInitialized; LLSD mQueuedMsgsForInit; @@ -196,6 +198,8 @@ private: // connection to voice channel state change signal boost::signals2::connection mVoiceChannelStateChangeConnection; + + const LLIMInfo* mImInfo; }; #endif // LL_FLOATERIMSESSION_H diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index 6c8e81e563..b16ef6dd79 100755 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -1791,10 +1791,15 @@ void LLPanelLandObjects::onCommitClean(LLUICtrl *caller, void* user_data) LLParcel* parcel = lop->mParcel->getParcel(); if (parcel) { - lop->mOtherTime = atoi(lop->mCleanOtherObjectsTime->getText().c_str()); + S32 return_time = atoi(lop->mCleanOtherObjectsTime->getText().c_str()); + // Only send return time if it has changed + if (return_time != lop->mOtherTime) + { + lop->mOtherTime = return_time; - parcel->setCleanOtherTime(lop->mOtherTime); - send_other_clean_time_message(parcel->getLocalID(), lop->mOtherTime); + parcel->setCleanOtherTime(lop->mOtherTime); + send_other_clean_time_message(parcel->getLocalID(), lop->mOtherTime); + } } } diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 19cec55837..855836af7a 100755 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -535,9 +535,16 @@ BOOL LLFloaterModelPreview::postBuild() mUploadBtn = getChild<LLButton>("ok_btn"); mCalculateBtn = getChild<LLButton>("calculate_btn"); - mCalculateBtn->setClickedCallback(boost::bind(&LLFloaterModelPreview::onClickCalculateBtn, this)); + if (LLConvexDecomposition::getInstance() != NULL) + { + mCalculateBtn->setClickedCallback(boost::bind(&LLFloaterModelPreview::onClickCalculateBtn, this)); - toggleCalculateButton(true); + toggleCalculateButton(true); + } + else + { + mCalculateBtn->setEnabled(false); + } return TRUE; } diff --git a/indra/newview/llfloaterpathfindingconsole.cpp b/indra/newview/llfloaterpathfindingconsole.cpp index 298454724b..161259d049 100755 --- a/indra/newview/llfloaterpathfindingconsole.cpp +++ b/indra/newview/llfloaterpathfindingconsole.cpp @@ -34,11 +34,11 @@ #include <boost/signals2.hpp> +#include "llagent.h" #include "llbutton.h" #include "llcheckboxctrl.h" #include "llcombobox.h" #include "llcontrol.h" -#include "llenvmanager.h" #include "llfloaterpathfindingcharacters.h" #include "llfloaterpathfindinglinksets.h" #include "llfloaterreg.h" @@ -224,7 +224,7 @@ void LLFloaterPathfindingConsole::onOpen(const LLSD& pKey) if (!mRegionBoundarySlot.connected()) { - mRegionBoundarySlot = LLEnvManagerNew::instance().setRegionChangeCallback(boost::bind(&LLFloaterPathfindingConsole::onRegionBoundaryCross, this)); + mRegionBoundarySlot = gAgent.addRegionChangedCallback(boost::bind(&LLFloaterPathfindingConsole::onRegionBoundaryCross, this)); } if (!mTeleportFailedSlot.connected()) diff --git a/indra/newview/llfloaterpathfindingobjects.cpp b/indra/newview/llfloaterpathfindingobjects.cpp index 20c1215bcb..d72ee073e1 100755 --- a/indra/newview/llfloaterpathfindingobjects.cpp +++ b/indra/newview/llfloaterpathfindingobjects.cpp @@ -41,7 +41,6 @@ #include "llavatarnamecache.h" #include "llbutton.h" #include "llcheckboxctrl.h" -#include "llenvmanager.h" #include "llfloater.h" #include "llfontgl.h" #include "llnotifications.h" @@ -85,7 +84,7 @@ void LLFloaterPathfindingObjects::onOpen(const LLSD &pKey) if (!mRegionBoundaryCrossingSlot.connected()) { - mRegionBoundaryCrossingSlot = LLEnvManagerNew::getInstance()->setRegionChangeCallback(boost::bind(&LLFloaterPathfindingObjects::onRegionBoundaryCrossed, this)); + mRegionBoundaryCrossingSlot = gAgent.addRegionChangedCallback(boost::bind(&LLFloaterPathfindingObjects::onRegionBoundaryCrossed, this)); } if (!mGodLevelChangeSlot.connected()) diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index 66bf49331b..73c0963a1d 100755 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -91,6 +91,7 @@ #include "lltrans.h" #include "llagentui.h" #include "llmeshrepository.h" +#include "llfloaterregionrestarting.h" const S32 TERRAIN_TEXTURE_COUNT = 4; const S32 CORNER_COUNT = 4; @@ -219,7 +220,7 @@ BOOL LLFloaterRegionInfo::postBuild() &processEstateOwnerRequest); // Request region info when agent region changes. - LLEnvManagerNew::instance().setRegionChangeCallback(boost::bind(&LLFloaterRegionInfo::requestRegionInfo, this)); + gAgent.addRegionChangedCallback(boost::bind(&LLFloaterRegionInfo::requestRegionInfo, this)); return TRUE; } diff --git a/indra/newview/llfloaterregionrestarting.cpp b/indra/newview/llfloaterregionrestarting.cpp new file mode 100644 index 0000000000..95d4265bb4 --- /dev/null +++ b/indra/newview/llfloaterregionrestarting.cpp @@ -0,0 +1,176 @@ +/** + * @file llfloaterregionrestarting.cpp + * @brief Shows countdown timer during region restart + * + * $LicenseInfo:firstyear=2006&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 "llfloaterregionrestarting.h" + +#include "llfloaterreg.h" +#include "lluictrl.h" +#include "llagent.h" +#include "llagentcamera.h" +#include "llviewerwindow.h" + +static S32 sSeconds; +static U32 sShakeState; + +LLFloaterRegionRestarting::LLFloaterRegionRestarting(const LLSD& key) : + LLFloater(key), + LLEventTimer(1) +{ + mName = (std::string)key["NAME"]; + sSeconds = (LLSD::Integer)key["SECONDS"]; +} + +LLFloaterRegionRestarting::~LLFloaterRegionRestarting() +{ + mRegionChangedConnection.disconnect(); +} + +BOOL LLFloaterRegionRestarting::postBuild() +{ + mRegionChangedConnection = gAgent.addRegionChangedCallback(boost::bind(&LLFloaterRegionRestarting::regionChange, this)); + + LLStringUtil::format_map_t args; + std::string text; + + args["[NAME]"] = mName; + text = getString("RegionName", args); + LLTextBox* textbox = getChild<LLTextBox>("region_name"); + textbox->setValue(text); + + sShakeState = SHAKE_START; + + refresh(); + + return TRUE; +} + +void LLFloaterRegionRestarting::regionChange() +{ + close(); +} + +BOOL LLFloaterRegionRestarting::tick() +{ + refresh(); + + return FALSE; +} + +void LLFloaterRegionRestarting::refresh() +{ + LLStringUtil::format_map_t args; + std::string text; + + args["[SECONDS]"] = llformat("%d", sSeconds); + getChild<LLTextBox>("restart_seconds")->setValue(getString("RestartSeconds", args)); + + sSeconds = sSeconds - 1; + if(sSeconds < 0.0) + { + sSeconds = 0; + } +} + +void LLFloaterRegionRestarting::draw() +{ + LLFloater::draw(); + + const F32 SHAKE_INTERVAL = 0.025; + const F32 SHAKE_TOTAL_DURATION = 1.8; // the length of the default alert tone for this + const F32 SHAKE_INITIAL_MAGNITUDE = 1.5; + const F32 SHAKE_HORIZONTAL_BIAS = 0.25; + F32 time_shaking; + + if(SHAKE_START == sShakeState) + { + mShakeTimer.setTimerExpirySec(SHAKE_INTERVAL); + sShakeState = SHAKE_LEFT; + mShakeIterations = 0; + mShakeMagnitude = SHAKE_INITIAL_MAGNITUDE; + } + + if(SHAKE_DONE != sShakeState && mShakeTimer.hasExpired()) + { + gAgentCamera.unlockView(); + + switch(sShakeState) + { + case SHAKE_LEFT: + gAgentCamera.setPanLeftKey(mShakeMagnitude * SHAKE_HORIZONTAL_BIAS); + sShakeState = SHAKE_UP; + break; + + case SHAKE_UP: + gAgentCamera.setPanUpKey(mShakeMagnitude); + sShakeState = SHAKE_RIGHT; + break; + + case SHAKE_RIGHT: + gAgentCamera.setPanRightKey(mShakeMagnitude * SHAKE_HORIZONTAL_BIAS); + sShakeState = SHAKE_DOWN; + break; + + case SHAKE_DOWN: + gAgentCamera.setPanDownKey(mShakeMagnitude); + mShakeIterations++; + time_shaking = SHAKE_INTERVAL * (mShakeIterations * 4 /* left, up, right, down */); + if(SHAKE_TOTAL_DURATION <= time_shaking) + { + sShakeState = SHAKE_DONE; + mShakeMagnitude = 0.0; + } + else + { + sShakeState = SHAKE_LEFT; + F32 percent_done_shaking = (SHAKE_TOTAL_DURATION - time_shaking) / SHAKE_TOTAL_DURATION; + mShakeMagnitude = SHAKE_INITIAL_MAGNITUDE * (percent_done_shaking * percent_done_shaking); // exponential decay + } + break; + + default: + break; + } + mShakeTimer.setTimerExpirySec(SHAKE_INTERVAL); + } +} + +void LLFloaterRegionRestarting::close() +{ + LLFloaterRegionRestarting* floaterp = LLFloaterReg::findTypedInstance<LLFloaterRegionRestarting>("region_restarting"); + + if (floaterp) + { + floaterp->closeFloater(); + } +} + +void LLFloaterRegionRestarting::updateTime(S32 time) +{ + sSeconds = time; + sShakeState = SHAKE_START; +} diff --git a/indra/newview/llfloaterregionrestarting.h b/indra/newview/llfloaterregionrestarting.h new file mode 100644 index 0000000000..46416db2c8 --- /dev/null +++ b/indra/newview/llfloaterregionrestarting.h @@ -0,0 +1,69 @@ +/** + * @file llfloaterregionrestarting.h + * @brief Shows countdown timer during region restart + * + * $LicenseInfo:firstyear=2006&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_LLFLOATERREGIONRESTARTING_H +#define LL_LLFLOATERREGIONRESTARTING_H + +#include "llfloater.h" +#include "lltextbox.h" +#include "lleventtimer.h" + +class LLFloaterRegionRestarting : public LLFloater, public LLEventTimer +{ + friend class LLFloaterReg; + +public: + static void close(); + static void updateTime(S32 time); + +private: + LLFloaterRegionRestarting(const LLSD& key); + virtual ~LLFloaterRegionRestarting(); + virtual BOOL postBuild(); + virtual BOOL tick(); + virtual void refresh(); + virtual void draw(); + virtual void regionChange(); + + std::string mName; + U32 mShakeIterations; + F32 mShakeMagnitude; + LLTimer mShakeTimer; + + boost::signals2::connection mRegionChangedConnection; + + enum + { + SHAKE_START, + SHAKE_LEFT, + SHAKE_UP, + SHAKE_RIGHT, + SHAKE_DOWN, + SHAKE_DONE + }; +}; + +#endif // LL_LLFLOATERREGIONRESTARTING_H diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp index 137b5446cf..cb637c7162 100755 --- a/indra/newview/llfloaterworldmap.cpp +++ b/indra/newview/llfloaterworldmap.cpp @@ -627,8 +627,8 @@ void LLFloaterWorldMap::trackLocation(const LLVector3d& pos_global) if (!sim_info) { // We haven't found a region for that point yet, leave the tracking to the world map - LLWorldMap::getInstance()->setTracking(pos_global); LLTracker::stopTracking(NULL); + LLWorldMap::getInstance()->setTracking(pos_global); S32 world_x = S32(pos_global.mdV[0] / 256); S32 world_y = S32(pos_global.mdV[1] / 256); LLWorldMapMessage::getInstance()->sendMapBlockRequest(world_x, world_y, world_x, world_y, true); @@ -643,9 +643,9 @@ void LLFloaterWorldMap::trackLocation(const LLVector3d& pos_global) { // Down region. Show the blue circle of death! // i.e. let the world map that this and tell it it's invalid + LLTracker::stopTracking(NULL); LLWorldMap::getInstance()->setTracking(pos_global); LLWorldMap::getInstance()->setTrackingInvalid(); - LLTracker::stopTracking(NULL); setDefaultBtn(""); // clicked on a down region - turn off coord display @@ -665,8 +665,8 @@ void LLFloaterWorldMap::trackLocation(const LLVector3d& pos_global) std::string tooltip(""); mTrackedStatus = LLTracker::TRACKING_LOCATION; - LLTracker::trackLocation(pos_global, full_name, tooltip); LLWorldMap::getInstance()->cancelTracking(); // The floater is taking over the tracking + LLTracker::trackLocation(pos_global, full_name, tooltip); LLVector3d coord_pos = LLTracker::getTrackedPositionGlobal(); updateTeleportCoordsDisplay( coord_pos ); diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 80ef506272..44943d8722 100755 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -74,6 +74,7 @@ #include "llvoavatarself.h" #include "llwearablelist.h" #include "lllandmarkactions.h" +#include "llpanellandmarks.h" void copy_slurl_to_clipboard_callback_inv(const std::string& slurl); @@ -1449,6 +1450,38 @@ void LLItemBridge::performAction(LLInventoryModel* model, std::string action) } } } + else if ("show_on_map" == action) + { + doActionOnCurSelectedLandmark(boost::bind(&LLItemBridge::doShowOnMap, this, _1)); + } +} + +void LLItemBridge::doActionOnCurSelectedLandmark(LLLandmarkList::loaded_callback_t cb) +{ + LLViewerInventoryItem* cur_item = getItem(); + if(cur_item && cur_item->getInventoryType() == LLInventoryType::IT_LANDMARK) + { + LLLandmark* landmark = LLLandmarkActions::getLandmark(cur_item->getUUID(), cb); + if (landmark) + { + cb(landmark); + } + } +} + +void LLItemBridge::doShowOnMap(LLLandmark* landmark) +{ + LLVector3d landmark_global_pos; + // landmark has already been tested for NULL by calling routine + if (landmark->getGlobalPos(landmark_global_pos)) + { + LLFloaterWorldMap* worldmap_instance = LLFloaterWorldMap::getInstance(); + if (!landmark_global_pos.isExactlyZero() && worldmap_instance) + { + worldmap_instance->trackLocation(landmark_global_pos); + LLFloaterReg::showInstance("world_map", "center"); + } + } } void copy_slurl_to_clipboard_callback_inv(const std::string& slurl) @@ -4580,6 +4613,7 @@ void LLLandmarkBridge::buildContextMenu(LLMenuGL& menu, U32 flags) items.push_back(std::string("Landmark Separator")); items.push_back(std::string("url_copy")); items.push_back(std::string("About Landmark")); + items.push_back(std::string("show_on_map")); } // Disable "About Landmark" menu item for diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index 517153e171..bc875e8f37 100755 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -36,6 +36,7 @@ #include "llviewercontrol.h" #include "llviewerwearable.h" #include "lltooldraganddrop.h" +#include "lllandmarklist.h" class LLInventoryFilter; class LLInventoryPanel; @@ -239,7 +240,10 @@ protected: BOOL confirmRemoveItem(const LLSD& notification, const LLSD& response); virtual BOOL isItemPermissive() const; virtual void buildDisplayName() const; + void doActionOnCurSelectedLandmark(LLLandmarkList::loaded_callback_t cb); +private: + void doShowOnMap(LLLandmark* landmark); }; class LLFolderBridge : public LLInvFVBridge diff --git a/indra/newview/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp index 5022dba934..dbdff11f11 100755 --- a/indra/newview/lllocationinputctrl.cpp +++ b/indra/newview/lllocationinputctrl.cpp @@ -407,14 +407,14 @@ LLLocationInputCtrl::LLLocationInputCtrl(const LLLocationInputCtrl::Params& p) // - Make the "Add landmark" button updated when either current parcel gets changed // or a landmark gets created or removed from the inventory. // - Update the location string on parcel change. - mParcelMgrConnection = LLViewerParcelMgr::getInstance()->addAgentParcelChangedCallback( + mParcelMgrConnection = gAgent.addParcelChangedCallback( boost::bind(&LLLocationInputCtrl::onAgentParcelChange, this)); // LLLocationHistory instance is being created before the location input control, so we have to update initial state of button manually. mButton->setEnabled(LLLocationHistory::instance().getItemCount() > 0); mLocationHistoryConnection = LLLocationHistory::getInstance()->setChangedCallback( boost::bind(&LLLocationInputCtrl::onLocationHistoryChanged, this,_1)); - mRegionCrossingSlot = LLEnvManagerNew::getInstance()->setRegionChangeCallback(boost::bind(&LLLocationInputCtrl::onRegionBoundaryCrossed, this)); + mRegionCrossingSlot = gAgent.addRegionChangedCallback(boost::bind(&LLLocationInputCtrl::onRegionBoundaryCrossed, this)); createNavMeshStatusListenerForCurrentRegion(); mRemoveLandmarkObserver = new LLRemoveLandmarkObserver(this); diff --git a/indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp b/indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp index a567d1217a..8879cfd7fb 100755 --- a/indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp +++ b/indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp @@ -79,7 +79,7 @@ void LLMenuOptionPathfindingRebakeNavmesh::initialize() if ( !mRegionCrossingSlot.connected() ) { - mRegionCrossingSlot = LLEnvManagerNew::getInstance()->setRegionChangeCallback(boost::bind(&LLMenuOptionPathfindingRebakeNavmesh::handleRegionBoundaryCrossed, this)); + mRegionCrossingSlot = gAgent.addRegionChangedCallback(boost::bind(&LLMenuOptionPathfindingRebakeNavmesh::handleRegionBoundaryCrossed, this)); } if (!mAgentStateSlot.connected()) diff --git a/indra/newview/llmoveview.cpp b/indra/newview/llmoveview.cpp index eb6591eb39..32b168b8c5 100755 --- a/indra/newview/llmoveview.cpp +++ b/indra/newview/llmoveview.cpp @@ -140,7 +140,7 @@ BOOL LLFloaterMove::postBuild() initMovementMode(); - LLViewerParcelMgr::getInstance()->addAgentParcelChangedCallback(LLFloaterMove::sUpdateFlyingStatus); + gAgent.addParcelChangedCallback(LLFloaterMove::sUpdateFlyingStatus); return TRUE; } diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp index 6c2a01fc82..8bb3ace2d9 100755 --- a/indra/newview/llpanelplaces.cpp +++ b/indra/newview/llpanelplaces.cpp @@ -251,7 +251,7 @@ LLPanelPlaces::LLPanelPlaces() gInventory.addObserver(mInventoryObserver); - mAgentParcelChangedConnection = LLViewerParcelMgr::getInstance()->addAgentParcelChangedCallback( + mAgentParcelChangedConnection = gAgent.addParcelChangedCallback( boost::bind(&LLPanelPlaces::updateVerbs, this)); //buildFromFile( "panel_places.xml"); // Called from LLRegisterPanelClass::defaultPanelClassBuilder() diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp index 0756faf5c0..9c380f63bd 100755 --- a/indra/newview/llpanelteleporthistory.cpp +++ b/indra/newview/llpanelteleporthistory.cpp @@ -359,6 +359,11 @@ void LLTeleportHistoryPanel::ContextMenu::onInfo() void LLTeleportHistoryPanel::ContextMenu::gotSLURLCallback(const std::string& slurl) { LLClipboard::instance().copyToClipboard(utf8str_to_wstring(slurl),0,slurl.size()); + + LLSD args; + args["SLURL"] = slurl; + + LLNotificationsUtil::add("CopySLURL", args); } void LLTeleportHistoryPanel::ContextMenu::onCopyToClipboard() diff --git a/indra/newview/llpaneltopinfobar.cpp b/indra/newview/llpaneltopinfobar.cpp index 9dd665198f..0d09f0bbfc 100755 --- a/indra/newview/llpaneltopinfobar.cpp +++ b/indra/newview/llpaneltopinfobar.cpp @@ -166,7 +166,7 @@ BOOL LLPanelTopInfoBar::postBuild() mShowCoordsCtrlConnection = ctrl->getSignal()->connect(boost::bind(&LLPanelTopInfoBar::onNavBarShowParcelPropertiesCtrlChanged, this)); } - mParcelMgrConnection = LLViewerParcelMgr::getInstance()->addAgentParcelChangedCallback( + mParcelMgrConnection = gAgent.addParcelChangedCallback( boost::bind(&LLPanelTopInfoBar::onAgentParcelChange, this)); setVisibleCallback(boost::bind(&LLPanelTopInfoBar::onVisibilityChange, this, _2)); diff --git a/indra/newview/lltracker.cpp b/indra/newview/lltracker.cpp index cbd16e873d..73ceb783b5 100755 --- a/indra/newview/lltracker.cpp +++ b/indra/newview/lltracker.cpp @@ -167,6 +167,7 @@ void LLTracker::render3D() } static LLUIColor map_track_color = LLUIColorTable::instance().getColor("MapTrackColor", LLColor4::white); + static LLUIColor map_track_color_under = LLUIColorTable::instance().getColor("MapTrackColorUnder", LLColor4::white); // Arbitary location beacon if( instance()->mIsTrackingLocation ) @@ -187,7 +188,7 @@ void LLTracker::render3D() } else { - renderBeacon( instance()->mTrackedPositionGlobal, map_track_color, + renderBeacon( instance()->mTrackedPositionGlobal, map_track_color, map_track_color_under, instance()->mBeaconText, instance()->mTrackedLocationName ); } } @@ -229,7 +230,7 @@ void LLTracker::render3D() // and back again instance()->mHasReachedLandmark = FALSE; } - renderBeacon( instance()->mTrackedPositionGlobal, map_track_color, + renderBeacon( instance()->mTrackedPositionGlobal, map_track_color, map_track_color_under, instance()->mBeaconText, instance()->mTrackedLandmarkName ); } } @@ -258,7 +259,7 @@ void LLTracker::render3D() } else { - renderBeacon( av_tracker.getGlobalPos(), map_track_color, + renderBeacon( av_tracker.getGlobalPos(), map_track_color, map_track_color_under, instance()->mBeaconText, av_tracker.getName() ); } } @@ -412,7 +413,7 @@ const std::string& LLTracker::getTrackedLocationName() return instance()->mTrackedLocationName; } -F32 pulse_func(F32 t, F32 z) +F32 pulse_func(F32 t, F32 z, bool tracking_avatar, std::string direction) { if (!LLTracker::sCheesyBeacon) { @@ -420,8 +421,15 @@ F32 pulse_func(F32 t, F32 z) } t *= F_PI; - z -= t*64.f - 256.f; - + if ("DOWN" == direction) + { + z += t*64.f - 256.f; + } + else + { + z -= t*64.f - 256.f; + } + F32 a = cosf(z*F_PI/512.f)*10.0f; a = llmax(a, 9.9f); a -= 9.9f; @@ -474,10 +482,78 @@ void draw_shockwave(F32 center_z, F32 t, S32 steps, LLColor4 color) gGL.end(); } +void LLTracker::drawBeacon(LLVector3 pos_agent, std::string direction, LLColor4 fogged_color, F32 dist) +{ + const U32 BEACON_VERTS = 256; + F32 step; + + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.pushMatrix(); + + if ("DOWN" == direction) + { + gGL.translatef(pos_agent.mV[0], pos_agent.mV[1], pos_agent.mV[2]); + draw_shockwave(1024.f, gRenderStartTime.getElapsedTimeF32(), 32, fogged_color); + step = (5020.0f - pos_agent.mV[2]) / BEACON_VERTS; + } + else + { + gGL.translatef(pos_agent.mV[0], pos_agent.mV[1], 0); + step = pos_agent.mV[2] / BEACON_VERTS; + } + + gGL.color4fv(fogged_color.mV); + + LLVector3 x_axis = LLViewerCamera::getInstance()->getLeftAxis(); + F32 t = gRenderStartTime.getElapsedTimeF32(); + + for (U32 i = 0; i < BEACON_VERTS; i++) + { + F32 x = x_axis.mV[0]; + F32 y = x_axis.mV[1]; + + F32 z = i * step; + F32 z_next = (i+1)*step; + + bool tracking_avatar = getTrackingStatus() == TRACKING_AVATAR; + F32 a = pulse_func(t, z, tracking_avatar, direction); + F32 an = pulse_func(t, z_next, tracking_avatar, direction); + + LLColor4 c_col = fogged_color + LLColor4(a,a,a,a); + LLColor4 col_next = fogged_color + LLColor4(an,an,an,an); + LLColor4 col_edge = fogged_color * LLColor4(a,a,a,0.0f); + LLColor4 col_edge_next = fogged_color * LLColor4(an,an,an,0.0f); + + a *= 2.f; + a += 1.0f; + + an *= 2.f; + an += 1.0f; + + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.color4fv(col_edge.mV); + gGL.vertex3f(-x*a, -y*a, z); + gGL.color4fv(col_edge_next.mV); + gGL.vertex3f(-x*an, -y*an, z_next); + + gGL.color4fv(c_col.mV); + gGL.vertex3f(0, 0, z); + gGL.color4fv(col_next.mV); + gGL.vertex3f(0, 0, z_next); + + gGL.color4fv(col_edge.mV); + gGL.vertex3f(x*a,y*a,z); + gGL.color4fv(col_edge_next.mV); + gGL.vertex3f(x*an,y*an,z_next); + gGL.end(); + } + gGL.popMatrix(); +} // static void LLTracker::renderBeacon(LLVector3d pos_global, - const LLColor4& color, + const LLColor4& color, + const LLColor4& color_under, LLHUDText* hud_textp, const std::string& label ) { @@ -497,9 +573,11 @@ void LLTracker::renderBeacon(LLVector3d pos_global, } LLColor4 fogged_color = color_frac * color + (1 - color_frac)*gSky.getFogColor(); + LLColor4 fogged_color_under = color_frac * color_under + (1 - color_frac) * gSky.getFogColor(); F32 FADE_DIST = 3.f; fogged_color.mV[3] = llmax(0.2f, llmin(0.5f,(dist-FADE_DIST)/FADE_DIST)); + fogged_color_under.mV[3] = llmax(0.2f, llmin(0.5f,(dist-FADE_DIST)/FADE_DIST)); LLVector3 pos_agent = gAgent.getPosAgentFromGlobal(pos_global); @@ -508,64 +586,8 @@ void LLTracker::renderBeacon(LLVector3d pos_global, LLGLDisable cull_face(GL_CULL_FACE); LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); - - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.pushMatrix(); - { - gGL.translatef(pos_agent.mV[0], pos_agent.mV[1], pos_agent.mV[2]); - - draw_shockwave(1024.f, gRenderStartTime.getElapsedTimeF32(), 32, fogged_color); - - gGL.color4fv(fogged_color.mV); - const U32 BEACON_VERTS = 256; - const F32 step = 1024.0f/BEACON_VERTS; - - LLVector3 x_axis = LLViewerCamera::getInstance()->getLeftAxis(); - F32 t = gRenderStartTime.getElapsedTimeF32(); - F32 dr = dist/LLViewerCamera::getInstance()->getFar(); - - for (U32 i = 0; i < BEACON_VERTS; i++) - { - F32 x = x_axis.mV[0]; - F32 y = x_axis.mV[1]; - - F32 z = i * step; - F32 z_next = (i+1)*step; - - F32 a = pulse_func(t, z); - F32 an = pulse_func(t, z_next); - - LLColor4 c_col = fogged_color + LLColor4(a,a,a,a); - LLColor4 col_next = fogged_color + LLColor4(an,an,an,an); - LLColor4 col_edge = fogged_color * LLColor4(a,a,a,0.0f); - LLColor4 col_edge_next = fogged_color * LLColor4(an,an,an,0.0f); - - a *= 2.f; - a += 1.0f+dr; - - an *= 2.f; - an += 1.0f+dr; - - gGL.begin(LLRender::TRIANGLE_STRIP); - gGL.color4fv(col_edge.mV); - gGL.vertex3f(-x*a, -y*a, z); - gGL.color4fv(col_edge_next.mV); - gGL.vertex3f(-x*an, -y*an, z_next); - - gGL.color4fv(c_col.mV); - gGL.vertex3f(0, 0, z); - gGL.color4fv(col_next.mV); - gGL.vertex3f(0, 0, z_next); - - gGL.color4fv(col_edge.mV); - gGL.vertex3f(x*a,y*a,z); - gGL.color4fv(col_edge_next.mV); - gGL.vertex3f(x*an,y*an,z_next); - - gGL.end(); - } - } - gGL.popMatrix(); + LLTracker::drawBeacon(pos_agent, "DOWN", fogged_color, dist); + LLTracker::drawBeacon(pos_agent, "UP", fogged_color_under, dist); std::string text; text = llformat( "%.0f m", to_vec.magVec()); diff --git a/indra/newview/lltracker.h b/indra/newview/lltracker.h index 8e916af315..d8d5803787 100755 --- a/indra/newview/lltracker.h +++ b/indra/newview/lltracker.h @@ -108,8 +108,10 @@ protected: LLTracker(); ~LLTracker(); + static void drawBeacon(LLVector3 pos_agent, std::string direction, LLColor4 fogged_color, F32 dist); static void renderBeacon( LLVector3d pos_global, const LLColor4& color, + const LLColor4& color_under, LLHUDText* hud_textp, const std::string& label ); diff --git a/indra/newview/llvieweraudio.cpp b/indra/newview/llvieweraudio.cpp index 3da934b148..826d296117 100755 --- a/indra/newview/llvieweraudio.cpp +++ b/indra/newview/llvieweraudio.cpp @@ -368,6 +368,7 @@ void init_audio() gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndTyping"))); gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndWindowClose"))); gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndWindowOpen"))); + gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndRestart"))); } audio_update_volume(true); diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 4ce049df03..a8eeddb798 100755 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -95,6 +95,7 @@ #include "llfloaterproperties.h" #include "llfloaterregiondebugconsole.h" #include "llfloaterregioninfo.h" +#include "llfloaterregionrestarting.h" #include "llfloaterreporter.h" #include "llfloaterscriptdebug.h" #include "llfloaterscriptlimits.h" @@ -296,6 +297,7 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("reset_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterResetQueue>); LLFloaterReg::add("region_debug_console", "floater_region_debug_console.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterRegionDebugConsole>); LLFloaterReg::add("region_info", "floater_region_info.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterRegionInfo>); + LLFloaterReg::add("region_restarting", "floater_region_restarting.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterRegionRestarting>); LLFloaterReg::add("script_debug", "floater_script_debug.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterScriptDebug>); LLFloaterReg::add("script_debug_output", "floater_script_debug_panel.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterScriptDebugOutput>); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 3574d37adf..267aa9532c 100755 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -111,6 +111,7 @@ #include "llpanelblockedlist.h" #include "llpanelplaceprofile.h" #include "llviewerregion.h" +#include "llfloaterregionrestarting.h" #include <boost/algorithm/string/split.hpp> // #include <boost/regex.hpp> @@ -5741,7 +5742,6 @@ bool handle_special_notification(std::string notificationID, LLSD& llsdBlock) std::string regionMaturity = LLViewerRegion::accessToString(regionAccess); LLStringUtil::toLower(regionMaturity); llsdBlock["REGIONMATURITY"] = regionMaturity; - bool returnValue = false; LLNotificationPtr maturityLevelNotification; std::string notifySuffix = "_Notify"; @@ -5911,6 +5911,7 @@ bool attempt_standard_notification(LLMessageSystem* msgsystem) (notificationID == "RegionEntryAccessBlocked") || (notificationID == "LandClaimAccessBlocked") || (notificationID == "LandBuyAccessBlocked") + ) { /*--------------------------------------------------------------------- @@ -5952,7 +5953,41 @@ bool attempt_standard_notification(LLMessageSystem* msgsystem) snap_filename += SCREEN_HOME_FILENAME; gViewerWindow->saveSnapshot(snap_filename, gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw(), FALSE, FALSE); } - + + if (notificationID == "RegionRestartMinutes" || + notificationID == "RegionRestartSeconds") + { + S32 seconds; + if (notificationID == "RegionRestartMinutes") + { + seconds = 60 * static_cast<S32>(llsdBlock["MINUTES"].asInteger()); + } + else + { + seconds = static_cast<S32>(llsdBlock["SECONDS"].asInteger()); + } + + LLFloaterRegionRestarting* floaterp = LLFloaterReg::findTypedInstance<LLFloaterRegionRestarting>("region_restarting"); + + if (floaterp) + { + LLFloaterRegionRestarting::updateTime(seconds); + } + else + { + LLSD params; + params["NAME"] = llsdBlock["NAME"]; + params["SECONDS"] = (LLSD::Integer)seconds; + LLFloaterRegionRestarting* restarting_floater = dynamic_cast<LLFloaterRegionRestarting*>(LLFloaterReg::showInstance("region_restarting", params)); + if(restarting_floater) + { + restarting_floater->center(); + } + } + + send_sound_trigger(LLUUID(gSavedSettings.getString("UISndRestart")), 1.0f); + } + LLNotificationsUtil::add(notificationID, llsdBlock); return true; } @@ -6012,7 +6047,6 @@ void process_alert_message(LLMessageSystem *msgsystem, void **user_data) std::string message; msgsystem->getStringFast(_PREHASH_AlertData, _PREHASH_Message, message); - process_special_alert_messages(message); if (!attempt_standard_notification(msgsystem)) @@ -6036,7 +6070,6 @@ bool handle_not_age_verified_alert(const std::string &pAlertName) bool handle_special_alerts(const std::string &pAlertName) { bool isHandled = false; - if (LLStringUtil::compareStrings(pAlertName, "NotAgeVerified") == 0) { @@ -6072,26 +6105,17 @@ void process_alert_core(const std::string& message, BOOL modal) // System message is important, show in upper-right box not tip std::string text(message.substr(1)); LLSD args; - if (text.substr(0,17) == "RESTART_X_MINUTES") - { - S32 mins = 0; - LLStringUtil::convertToS32(text.substr(18), mins); - args["MINUTES"] = llformat("%d",mins); - LLNotificationsUtil::add("RegionRestartMinutes", args); - } - else if (text.substr(0,17) == "RESTART_X_SECONDS") - { - S32 secs = 0; - LLStringUtil::convertToS32(text.substr(18), secs); - args["SECONDS"] = llformat("%d",secs); - LLNotificationsUtil::add("RegionRestartSeconds", args); - } - else + + // *NOTE: If the text from the server ever changes this line will need to be adjusted. + std::string restart_cancelled = "Region restart cancelled."; + if (text.substr(0, restart_cancelled.length()) == restart_cancelled) { - std::string new_msg =LLNotifications::instance().getGlobalString(text); - args["MESSAGE"] = new_msg; - LLNotificationsUtil::add("SystemMessage", args); + LLFloaterRegionRestarting::close(); } + + std::string new_msg =LLNotifications::instance().getGlobalString(text); + args["MESSAGE"] = new_msg; + LLNotificationsUtil::add("SystemMessage", args); } else if (modal) { diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp index 4cdb568d17..e361fad9de 100755 --- a/indra/newview/llviewerparcelmgr.cpp +++ b/indra/newview/llviewerparcelmgr.cpp @@ -1580,7 +1580,8 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use // Let interesting parties know about agent parcel change. LLViewerParcelMgr* instance = LLViewerParcelMgr::getInstance(); - instance->mAgentParcelChangedSignal(); + // Notify anything that wants to know when the agent changes parcels + gAgent.changeParcels(); if (instance->mTeleportInProgress) { @@ -2458,10 +2459,6 @@ LLViewerTexture* LLViewerParcelMgr::getPassImage() const return sPassImage; } -boost::signals2::connection LLViewerParcelMgr::addAgentParcelChangedCallback(parcel_changed_callback_t cb) -{ - return mAgentParcelChangedSignal.connect(cb); -} /* * Set finish teleport callback. You can use it to observe all teleport events. * NOTE: @@ -2475,7 +2472,7 @@ boost::signals2::connection LLViewerParcelMgr::setTeleportFinishedCallback(telep return mTeleportFinishedSignal.connect(cb); } -boost::signals2::connection LLViewerParcelMgr::setTeleportFailedCallback(parcel_changed_callback_t cb) +boost::signals2::connection LLViewerParcelMgr::setTeleportFailedCallback(teleport_failed_callback_t cb) { return mTeleportFailedSignal.connect(cb); } diff --git a/indra/newview/llviewerparcelmgr.h b/indra/newview/llviewerparcelmgr.h index 6183b7e90e..9da49bb3f3 100755 --- a/indra/newview/llviewerparcelmgr.h +++ b/indra/newview/llviewerparcelmgr.h @@ -80,8 +80,8 @@ class LLViewerParcelMgr : public LLSingleton<LLViewerParcelMgr> public: typedef boost::function<void (const LLVector3d&, const bool& local)> teleport_finished_callback_t; typedef boost::signals2::signal<void (const LLVector3d&, const bool&)> teleport_finished_signal_t; - typedef boost::function<void()> parcel_changed_callback_t; - typedef boost::signals2::signal<void()> parcel_changed_signal_t; + typedef boost::function<void()> teleport_failed_callback_t; + typedef boost::signals2::signal<void()> teleport_failed_signal_t; LLViewerParcelMgr(); ~LLViewerParcelMgr(); @@ -283,9 +283,8 @@ public: // the agent is banned or not in the allowed group BOOL isCollisionBanned(); - boost::signals2::connection addAgentParcelChangedCallback(parcel_changed_callback_t cb); boost::signals2::connection setTeleportFinishedCallback(teleport_finished_callback_t cb); - boost::signals2::connection setTeleportFailedCallback(parcel_changed_callback_t cb); + boost::signals2::connection setTeleportFailedCallback(teleport_failed_callback_t cb); void onTeleportFinished(bool local, const LLVector3d& new_pos); void onTeleportFailed(); @@ -338,8 +337,7 @@ private: BOOL mTeleportInProgress; teleport_finished_signal_t mTeleportFinishedSignal; - parcel_changed_signal_t mTeleportFailedSignal; - parcel_changed_signal_t mAgentParcelChangedSignal; + teleport_failed_signal_t mTeleportFailedSignal; // Array of pieces of parcel edges to potentially draw // Has (parcels_per_edge + 1) * (parcels_per_edge + 1) elements so diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index f53995732f..3ebb64e3fa 100755 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -122,6 +122,9 @@ <color name="Blue_80" value="0 0 1 0.8" /> + <color + name="Orange" + value="1 .82 .46 1" /> <!-- This color name makes potentially unused colors show up bright purple. Leave this here until all Unused? are removed below, otherwise @@ -511,6 +514,9 @@ name="MapTrackColor" reference="Red" /> <color + name="MapTrackColorUnder" + reference="Blue" /> + <color name="MapTrackDisabledColor" value="0.5 0 0 1" /> <color diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index bb891996c9..94c187e21a 100755 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -153,8 +153,6 @@ with the same filename but different name <texture name="Command_Speak_Icon" file_name="toolbar_icons/speak.png" preload="true" /> <texture name="Command_View_Icon" file_name="toolbar_icons/view.png" preload="true" /> <texture name="Command_Voice_Icon" file_name="toolbar_icons/nearbyvoice.png" preload="true" /> - <texture name="Command_Highlighting_Icon" file_name="toolbar_icons/highlighting.png" preload="true" scale.left="4" scale.top="19" scale.right="28" scale.bottom="4" /> - <texture name="Command_Highlighting_Selected_Icon" file_name="toolbar_icons/highlighting_selected.png" preload="true" scale.left="4" scale.top="19" scale.right="28" scale.bottom="4" /> <texture name="Caret_Bottom_Icon" file_name="toolbar_icons/caret_bottom.png" preload="true" scale.left="1" scale.top="23" scale.right="15" scale.bottom="1" /> <texture name="Caret_Right_Icon" file_name="toolbar_icons/caret_right.png" preload="true" scale.left="5" scale.top="15" scale.right="28" scale.bottom="1" /> <texture name="Caret_Left_Icon" file_name="toolbar_icons/caret_left.png" preload="true" scale.left="1" scale.top="15" scale.right="23" scale.bottom="1" /> @@ -165,7 +163,6 @@ with the same filename but different name <texture name="ComboButton_On" file_name="widgets/ComboButton_On.png" preload="true" scale.left="2" scale.top="19" scale.right="18" scale.bottom="2" /> <texture name="ComboButton_Off" file_name="widgets/ComboButton_Off.png" preload="true" scale.left="2" scale.top="19" scale.right="18" scale.bottom="2" /> <texture name="ComboButton_UpOff" file_name="widgets/ComboButton_UpOff.png" preload="true" scale.left="2" scale.top="19" scale.right="18" scale.bottom="2" /> - <texture name="ComboButton_Hovered" file_name="widgets/ComboButton_Hover.png" preload="true" scale.left="2" scale.top="19" scale.right="18" scale.bottom="2" /> <texture name="Container" file_name="containers/Container.png" preload="false" /> diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml index 43d0f2fb18..7076de55e3 100755 --- a/indra/newview/skins/default/xui/en/floater_im_session.xml +++ b/indra/newview/skins/default/xui/en/floater_im_session.xml @@ -210,7 +210,7 @@ default_tab_group="3" tab_group="2" name="right_part_holder" - min_width="172"> + min_width="230"> <layout_stack animate="true" default_tab_group="2" diff --git a/indra/newview/skins/default/xui/en/floater_model_preview.xml b/indra/newview/skins/default/xui/en/floater_model_preview.xml index 5e92a12251..9fa416012c 100755 --- a/indra/newview/skins/default/xui/en/floater_model_preview.xml +++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml @@ -212,11 +212,11 @@ follows="top|left" height="20" layout="topleft" - left="215" + left="222" name="lod_mode_high" top_delta="0" visible="false" - width="135"> + width="130"> <item name="Triangle Limit" value="Triangle Limit" /> @@ -230,7 +230,7 @@ height="20" increment="10" layout="topleft" - left_pad="5" + left_pad="3" name="lod_triangle_limit_high" visible="false" width="55" /> @@ -342,10 +342,10 @@ follows="top|left" height="20" layout="topleft" - left="215" + left="222" name="lod_mode_medium" top_delta="0" - width="135"> + width="130"> <item name="Triangle Limit" value="Triangle Limit" /> @@ -359,7 +359,7 @@ height="20" increment="10" layout="topleft" - left_pad="5" + left_pad="3" name="lod_triangle_limit_medium" width="55" /> <spinner @@ -470,10 +470,10 @@ follows="top|left" height="20" layout="topleft" - left="215" + left="222" name="lod_mode_low" top_delta="0" - width="135"> + width="130"> <item name="Triangle Limit" value="Triangle Limit" /> @@ -487,7 +487,7 @@ height="20" increment="10" layout="topleft" - left_pad="5" + left_pad="3" name="lod_triangle_limit_low" width="55" /> <spinner @@ -598,10 +598,10 @@ follows="top|left" height="20" layout="topleft" - left="215" + left="222" name="lod_mode_lowest" top_delta="0" - width="135"> + width="130"> <item name="Triangle Limit" value="Triangle Limit" /> @@ -615,7 +615,7 @@ height="20" increment="10" layout="topleft" - left_pad="5" + left_pad="3" name="lod_triangle_limit_lowest" width="55" /> <spinner diff --git a/indra/newview/skins/default/xui/en/floater_region_restarting.xml b/indra/newview/skins/default/xui/en/floater_region_restarting.xml new file mode 100644 index 0000000000..2fe4d0190a --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_region_restarting.xml @@ -0,0 +1,75 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + height="150" + width="290" + layout="topleft" + name="region_restarting" + help_topic="floater_region_restarting" + single_instance="true" + reuse_instance="false" + title="REGION RESTARTING"> + <string name="RegionName"> + The region you are in now ([NAME]) is about to restart. + +If you stay in this region you will be logged out. + </string> + <string name="RestartSeconds"> + Seconds until restart +[SECONDS] + </string> + <panel + name="layout_panel_1" + height="150" + width="290" + follows="right|top" + top="0" + left="0" + background_visible="true" + bg_opaque_color="Orange" + bg_alpha_color="Orange"> + + <icon color="1.0 1.0 1.0 1.0" + tab_stop="false" + mouse_opaque="false" + name="icon" + width="32" + height="32" + image_name="notify_caution_icon.tga" + follows="left|top"> + </icon> + + <text + type="string" + length="1" + follows="top|left" + layout="topleft" + name="region_name" + text_color="Black" + font="SansSerifBold" + word_wrap="true" + height="100" + top="5" + left="40" + width="230"> + The region you are in now (-The longest region name-) is about to restart. + +If you stay in this region you will be logged out. + </text> + <text + type="string" + length="1" + follows="top|left" + layout="topleft" + name="restart_seconds" + text_color="Black" + font="SansSerifLargeBold" + height="40" + top="110" + left="0" + halign="center" + width="290"> + Seconds until restart + 32767 + </text> + </panel> + </floater> diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml index 512205ba43..6fa45d7d66 100755 --- a/indra/newview/skins/default/xui/en/menu_inventory.xml +++ b/indra/newview/skins/default/xui/en/menu_inventory.xml @@ -552,6 +552,14 @@ function="Inventory.DoToSelected" parameter="about" /> </menu_item_call> + <menu_item_call + label="Show on Map" + layout="topleft" + name="show_on_map"> + <menu_item_call.on_click + function="Inventory.DoToSelected" + parameter="show_on_map" /> + </menu_item_call> <menu_item_separator layout="topleft" name="Animation Separator" /> diff --git a/indra/newview/skins/default/xui/en/menu_teleport_history_item.xml b/indra/newview/skins/default/xui/en/menu_teleport_history_item.xml index 0160d52b17..f939c3996d 100755 --- a/indra/newview/skins/default/xui/en/menu_teleport_history_item.xml +++ b/indra/newview/skins/default/xui/en/menu_teleport_history_item.xml @@ -17,7 +17,7 @@ function="TeleportHistory.MoreInformation" /> </menu_item_call> <menu_item_call - label="Copy to Clipboard" + label="Copy SLurl" layout="topleft" name="CopyToClipboard"> <menu_item_call.on_click diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 35f2e7b31e..a93601f5fd 100755 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -6893,8 +6893,8 @@ This will add a bookmark in your inventory so you can quickly IM this Resident. <notification icon="notify.tga" name="RegionRestartMinutes" + show_toast="false" priority="high" - sound="UISndAlert" type="notify"> The region "[NAME]" will restart in [MINUTES] minutes. If you stay in this region you will be logged out. @@ -6903,8 +6903,8 @@ If you stay in this region you will be logged out. <notification icon="notify.tga" name="RegionRestartSeconds" + show_toast="false" priority="high" - sound="UISndAlert" type="notify"> The region "[NAME]" will restart in [SECONDS] seconds. If you stay in this region you will be logged out. diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml index 3caf2b3d7e..d2caf63052 100755 --- a/indra/newview/skins/default/xui/en/panel_people.xml +++ b/indra/newview/skins/default/xui/en/panel_people.xml @@ -66,8 +66,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M tab_position="top" top="0" halign="center" - right="-5" - use_highlighting_on_hover="true"> + right="-5"> <!-- ================================= NEARBY tab =========================== --> @@ -507,6 +506,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M right="-10" top_pad="4" left="3" + use_ellipses="true" name="groupcount"> You belong to [COUNT] groups, and can join [REMAINING] more. </text> diff --git a/indra/newview/skins/default/xui/en/widgets/location_input.xml b/indra/newview/skins/default/xui/en/widgets/location_input.xml index 4ea1aa6efb..61ec046649 100755 --- a/indra/newview/skins/default/xui/en/widgets/location_input.xml +++ b/indra/newview/skins/default/xui/en/widgets/location_input.xml @@ -150,7 +150,6 @@ <combo_button name="Location History" label="" - image_hover_unselected="ComboButton_Hovered" pad_right="0"/> <combo_list bg_writeable_color="MenuDefaultBgColor" diff --git a/indra/newview/skins/default/xui/en/widgets/tab_container.xml b/indra/newview/skins/default/xui/en/widgets/tab_container.xml index 9559be214a..0586119681 100755 --- a/indra/newview/skins/default/xui/en/widgets/tab_container.xml +++ b/indra/newview/skins/default/xui/en/widgets/tab_container.xml @@ -24,26 +24,17 @@ label_pad_left - padding to the left of tab button labels tab_bottom_image_unselected="Toolbar_Left_Off" tab_bottom_image_selected="Toolbar_Left_Selected" tab_left_image_unselected="SegmentedBtn_Left_Disabled" - tab_left_image_selected="SegmentedBtn_Left_Selected_Over" - tab_top_image_hovered="TabTop_Left_Selected" - tab_button_image_hovered="Toolbar_Left_Selected" - tab_left_image_hovered="SegmentedBtn_Left_Selected_Over"/> + tab_left_image_selected="SegmentedBtn_Left_Selected_Over"/> <middle_tab tab_top_image_unselected="TabTop_Middle_Off" tab_top_image_selected="TabTop_Middle_Selected" tab_bottom_image_unselected="Toolbar_Middle_Off" tab_bottom_image_selected="Toolbar_Middle_Selected" tab_left_image_unselected="SegmentedBtn_Left_Disabled" - tab_left_image_selected="SegmentedBtn_Left_Selected_Over" - tab_top_image_hovered="TabTop_Middle_Selected" - tab_button_image_hovered="Toolbar_Middle_Selected" - tab_left_image_hovered="SegmentedBtn_Left_Selected_Over"/> + tab_left_image_selected="SegmentedBtn_Left_Selected_Over"/> <last_tab tab_top_image_unselected="TabTop_Right_Off" tab_top_image_selected="TabTop_Right_Selected" tab_bottom_image_unselected="Toolbar_Right_Off" tab_bottom_image_selected="Toolbar_Right_Selected" tab_left_image_unselected="SegmentedBtn_Left_Disabled" - tab_left_image_selected="SegmentedBtn_Left_Selected_Over" - tab_top_image_hovered="TabTop_Right_Selected" - tab_button_image_hovered="Toolbar_Right_Selected" - tab_left_image_hovered="SegmentedBtn_Left_Selected_Over"/> + tab_left_image_selected="SegmentedBtn_Left_Selected_Over"/> </tab_container> |