Merge branch 'UICleanup' of git://github.com/Shyotl/SingularityViewer
Conflicts: indra/llappearance/llwearable.h indra/llui/llcombobox.h indra/newview/jcfloaterareasearch.cpp indra/newview/jcfloaterareasearch.h indra/newview/llpanelgrouproles.cpp indra/newview/llpanelgrouproles.h indra/newview/llviewermenu.cpp - Plugged in new MenuFloaterDict for AssetBlacklist and SoundExplorer in menu_viewer.xml and removed the old listeners for them. indra/newview/skins/default/xui/es/floater_inventory.xml Compile Fixes: indra/llcommon/llstl.h - error: expected nested-name-specifier before ‘const’ indra/llui/llmultisliderctrl.cpp:283:12: error: ‘caller’ was not declared in this scope indra/llui/lltexteditor.cpp - error: operands to ?: have different types ‘const LLPointer<LLTextSegment>’ and ‘long int’ - error: passing ‘const LLPointer<LLTextSegment>’ as ‘this’ argument of ‘LLPointer<Type>& LLPointer<Type>::operator=(const LLPointer<Type>&) [with Type = LLTextSegment]’ discards qualifiers indra/newview/llfloaterpermissionsmgr.cpp - Silly Shyotl, boost bind, not std bind. indra/newview/llfloaterproperties.* - error: ‘LLInstanceTracker<LLFloaterProperties, LLUUID>’ is an inaccessible base of ‘LLFloaterProperties’ indra/newview/llgivemoney.cpp - Again, boost::ref, not std::ref indra/newview/llpreviewscript.cpp - no known conversion for argument 1 from ‘std::vector<const LLPointer<LLTextSegment> >’ to ‘std::vector<LLPointer<LLTextSegment> >&
This commit is contained in:
@@ -731,6 +731,7 @@ LLVisualParam* LLWearable::getVisualParam(S32 index) const
|
||||
|
||||
void LLWearable::getVisualParams(visual_param_vec_t &list)
|
||||
{
|
||||
list.reserve(mVisualParamIndexMap.size());
|
||||
visual_param_index_map_t::iterator iter = mVisualParamIndexMap.begin();
|
||||
visual_param_index_map_t::iterator end = mVisualParamIndexMap.end();
|
||||
|
||||
@@ -783,7 +784,7 @@ void LLWearable::writeToAvatar(LLAvatarAppearance* avatarp)
|
||||
if (!avatarp) return;
|
||||
|
||||
// Pull params
|
||||
for( LLVisualParam* param = avatarp->getFirstVisualParam(); param; param = avatarp->getNextVisualParam() )
|
||||
/*for( LLVisualParam* param = avatarp->getFirstVisualParam(); param; param = avatarp->getNextVisualParam() )
|
||||
{
|
||||
// cross-wearable parameters are not authoritative, as they are driven by a different wearable. So don't copy the values to the
|
||||
// avatar object if cross wearable. Cross wearable params get their values from the avatar, they shouldn't write the other way.
|
||||
@@ -794,6 +795,12 @@ void LLWearable::writeToAvatar(LLAvatarAppearance* avatarp)
|
||||
|
||||
avatarp->setVisualParamWeight( param_id, weight, FALSE );
|
||||
}
|
||||
}*/
|
||||
for( visual_param_index_map_t::iterator it = mVisualParamIndexMap.begin(); it != mVisualParamIndexMap.end(); ++it )
|
||||
{
|
||||
LLVisualParam* param = it->second;
|
||||
if(!((LLViewerVisualParam*)param)->getCrossWearable())
|
||||
avatarp->setVisualParamWeight( param->getID(), param->getWeight(), FALSE );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "llextendedstatus.h"
|
||||
#include "llpermissions.h"
|
||||
#include "llsaleinfo.h"
|
||||
#include "llsortedvector.h"
|
||||
#include "llwearabletype.h"
|
||||
#include "lllocaltextureobject.h"
|
||||
|
||||
@@ -136,10 +137,7 @@ protected:
|
||||
typedef std::map<S32, F32> param_map_t;
|
||||
param_map_t mSavedVisualParamMap; // last saved version of visual params
|
||||
|
||||
public:
|
||||
typedef std::map<S32, LLVisualParam *> visual_param_index_map_t;
|
||||
|
||||
protected:
|
||||
typedef LLSortedVector<S32, LLVisualParam *> visual_param_index_map_t;
|
||||
visual_param_index_map_t mVisualParamIndexMap;
|
||||
|
||||
te_map_t mTEMap; // maps TE to LocalTextureObject
|
||||
|
||||
@@ -267,8 +267,7 @@ BOOL LLWearableData::isOnTop(LLWearable* wearable) const
|
||||
|
||||
const LLWearable* LLWearableData::getWearable(const LLWearableType::EType type, U32 index) const
|
||||
{
|
||||
//llassert_always(index == 0);
|
||||
wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type);
|
||||
/*wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type);
|
||||
if (wearable_iter == mWearableDatas.end())
|
||||
{
|
||||
return NULL;
|
||||
@@ -281,49 +280,79 @@ const LLWearable* LLWearableData::getWearable(const LLWearableType::EType type,
|
||||
else
|
||||
{
|
||||
return wearable_vec[index];
|
||||
}*/
|
||||
wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type);
|
||||
if (wearable_iter != mWearableDatas.end() && index < wearable_iter->second.size())
|
||||
{
|
||||
return wearable_iter->second[index];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LLWearable* LLWearableData::getTopWearable(const LLWearableType::EType type)
|
||||
{
|
||||
U32 count = getWearableCount(type);
|
||||
/*U32 count = getWearableCount(type);
|
||||
if ( count == 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return getWearable(type, count-1);
|
||||
return getWearable(type, count-1);*/
|
||||
wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type);
|
||||
if (wearable_iter != mWearableDatas.end() && !wearable_iter->second.empty())
|
||||
{
|
||||
return wearable_iter->second.back();
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const LLWearable* LLWearableData::getTopWearable(const LLWearableType::EType type) const
|
||||
{
|
||||
U32 count = getWearableCount(type);
|
||||
/*U32 count = getWearableCount(type);
|
||||
if ( count == 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return getWearable(type, count-1);
|
||||
return getWearable(type, count-1);*/
|
||||
wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type);
|
||||
if (wearable_iter != mWearableDatas.end() && !wearable_iter->second.empty())
|
||||
{
|
||||
return wearable_iter->second.back();
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LLWearable* LLWearableData::getBottomWearable(const LLWearableType::EType type)
|
||||
{
|
||||
if (getWearableCount(type) == 0)
|
||||
/*if (getWearableCount(type) == 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return getWearable(type, 0);
|
||||
return getWearable(type, 0);*/
|
||||
wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type);
|
||||
if (wearable_iter != mWearableDatas.end() && !wearable_iter->second.empty())
|
||||
{
|
||||
return wearable_iter->second.front();
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const LLWearable* LLWearableData::getBottomWearable(const LLWearableType::EType type) const
|
||||
{
|
||||
if (getWearableCount(type) == 0)
|
||||
/*if (getWearableCount(type) == 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return getWearable(type, 0);
|
||||
return getWearable(type, 0);*/
|
||||
wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type);
|
||||
if (wearable_iter != mWearableDatas.end() && !wearable_iter->second.empty())
|
||||
{
|
||||
return wearable_iter->second.front();
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
U32 LLWearableData::getWearableCount(const LLWearableType::EType type) const
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "llavatarappearancedefines.h"
|
||||
#include "llwearable.h"
|
||||
#include "llerror.h"
|
||||
#include <boost/array.hpp>
|
||||
|
||||
class LLAvatarAppearance;
|
||||
|
||||
@@ -98,8 +99,34 @@ protected:
|
||||
protected:
|
||||
LLAvatarAppearance* mAvatarAppearance;
|
||||
typedef std::vector<LLWearable*> wearableentry_vec_t; // all wearables of a certain type (EG all shirts)
|
||||
typedef std::map<LLWearableType::EType, wearableentry_vec_t> wearableentry_map_t; // wearable "categories" arranged by wearable type
|
||||
wearableentry_map_t mWearableDatas;
|
||||
//typedef std::map<LLWearableType::EType, wearableentry_vec_t> wearableentry_map_t; // wearable "categories" arranged by wearable type
|
||||
|
||||
//Why this weird structure? LLWearableType::WT_COUNT small and known, therefore it's more efficient to make an array of vectors, indexed
|
||||
//by wearable type. This allows O(1) lookups. This structure simply lets us plug in this optimization without touching any code elsewhere.
|
||||
typedef boost::array<std::pair<LLWearableType::EType,wearableentry_vec_t>,LLWearableType::WT_COUNT> wearable_array_t;
|
||||
struct wearableentry_map_t : public wearable_array_t
|
||||
{
|
||||
wearableentry_map_t()
|
||||
{
|
||||
for(wearable_array_t::size_type i=0;i<size();++i)
|
||||
at(i).first = (LLWearableType::EType)i;
|
||||
}
|
||||
wearable_array_t::iterator find(const LLWearableType::EType& index)
|
||||
{
|
||||
if(index < 0 || index >= (S32)size())
|
||||
return end();
|
||||
return begin() + index;
|
||||
}
|
||||
wearable_array_t::const_iterator find(const LLWearableType::EType& index) const
|
||||
{
|
||||
if(index < 0 || index >= (S32)size())
|
||||
return end();
|
||||
return begin() + index;
|
||||
}
|
||||
wearableentry_vec_t& operator [] (const S32 index) { return at(index).second; }
|
||||
const wearableentry_vec_t& operator [] (const S32 index) const { return at(index).second; }
|
||||
};
|
||||
wearableentry_map_t mWearableDatas; //Array for quicker lookups.
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -368,7 +368,7 @@ void LLAudioEngine::idle(F32 max_decode_time)
|
||||
if (channelp)
|
||||
{
|
||||
channelp->updateBuffer();
|
||||
sourcep->getChannel()->play();
|
||||
channelp->play();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@@ -391,8 +391,12 @@ void LLAudioEngine::idle(F32 max_decode_time)
|
||||
|
||||
// Actually play the associated data.
|
||||
sourcep->setupChannel();
|
||||
channelp->updateBuffer();
|
||||
sourcep->getChannel()->play();
|
||||
channelp = sourcep->getChannel();
|
||||
if (channelp)
|
||||
{
|
||||
channelp->updateBuffer();
|
||||
channelp->play();
|
||||
}
|
||||
}
|
||||
else if (sourcep->isLoop())
|
||||
{
|
||||
@@ -405,7 +409,12 @@ void LLAudioEngine::idle(F32 max_decode_time)
|
||||
// Actually, should do a time sync so if we're a loop master/slave
|
||||
// we don't drift away.
|
||||
sourcep->setupChannel();
|
||||
sourcep->getChannel()->play();
|
||||
channelp = sourcep->getChannel();
|
||||
if (channelp)
|
||||
{
|
||||
channelp->updateBuffer();
|
||||
channelp->play();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -597,6 +606,14 @@ LLAudioBuffer * LLAudioEngine::getFreeBuffer()
|
||||
lldebugs << "Taking over unused buffer " << buffer_id << llendl;
|
||||
//llinfos << "Flushing unused buffer!" << llendl;
|
||||
mBuffers[buffer_id]->mAudioDatap->mBufferp = NULL;
|
||||
for (U32 i = 0; i < MAX_CHANNELS; i++)
|
||||
{
|
||||
LLAudioChannel* channelp = mChannels[i];
|
||||
if(channelp && channelp->mCurrentBufferp == mBuffers[buffer_id])
|
||||
{
|
||||
channelp->cleanup();
|
||||
}
|
||||
}
|
||||
delete mBuffers[buffer_id];
|
||||
mBuffers[buffer_id] = createBuffer();
|
||||
return mBuffers[buffer_id];
|
||||
@@ -1374,14 +1391,14 @@ void LLAudioSource::update()
|
||||
return ; //no need to update
|
||||
}
|
||||
|
||||
if (!getCurrentBuffer())
|
||||
//if (!getCurrentBuffer()) // Same as !adp->getBuffer()
|
||||
{
|
||||
LLAudioData *adp = getCurrentData();
|
||||
if (adp)
|
||||
if (adp && !adp->getBuffer())
|
||||
{
|
||||
// Hack - try and load the sound. Will do this as a callback
|
||||
// on decode later.
|
||||
if (adp->load() && adp->getBuffer())
|
||||
if (adp->load())
|
||||
{
|
||||
play(adp->getID());
|
||||
}
|
||||
@@ -1847,8 +1864,8 @@ bool LLAudioData::load()
|
||||
if (!mBufferp)
|
||||
{
|
||||
// No free buffers, abort.
|
||||
llinfos << "Not able to allocate a new audio buffer, aborting." << llendl;
|
||||
return true;
|
||||
lldebugs << "Not able to allocate a new audio buffer, aborting." << llendl;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string uuid_str;
|
||||
|
||||
@@ -478,6 +478,7 @@ protected:
|
||||
class LLAudioBuffer
|
||||
{
|
||||
public:
|
||||
LLAudioBuffer() : mInUse(true), mAudioDatap(NULL) { mLastUseTimer.reset(); }
|
||||
virtual ~LLAudioBuffer() {};
|
||||
virtual bool loadWAV(const std::string& filename) = 0;
|
||||
virtual U32 getLength() = 0;
|
||||
|
||||
@@ -647,7 +647,7 @@ bool LLAudioChannelFMOD::isPlaying()
|
||||
//
|
||||
|
||||
|
||||
LLAudioBufferFMOD::LLAudioBufferFMOD()
|
||||
LLAudioBufferFMOD::LLAudioBufferFMOD() : LLAudioBuffer()
|
||||
{
|
||||
mSamplep = NULL;
|
||||
}
|
||||
|
||||
@@ -525,15 +525,16 @@ bool LLAudioChannelFMODEX::updateBuffer()
|
||||
}
|
||||
|
||||
// If we have a source for the channel, we need to update its gain.
|
||||
if (mCurrentSourcep)
|
||||
if (mCurrentSourcep && mChannelp)
|
||||
{
|
||||
// SJB: warnings can spam and hurt framerate, disabling
|
||||
FMOD_RESULT result;
|
||||
|
||||
result = mChannelp->setVolume(getSecondaryGain() * mCurrentSourcep->getGain());
|
||||
//Check_FMOD_Error(result, "FMOD::Channel::setVolume");
|
||||
|
||||
result = mChannelp->setVolume(getSecondaryGain() * mCurrentSourcep->getGain());
|
||||
Check_FMOD_Error(result, "FMOD::Channel::setVolume");
|
||||
result = mChannelp->setMode(mCurrentSourcep->isLoop() ? FMOD_LOOP_NORMAL : FMOD_LOOP_OFF);
|
||||
Check_FMOD_Error(result, "FMOD::Channel::setMode");
|
||||
/*if(Check_FMOD_Error(result, "FMOD::Channel::setMode"))
|
||||
{
|
||||
S32 index;
|
||||
@@ -595,7 +596,7 @@ void LLAudioChannelFMODEX::updateLoop()
|
||||
// yield false negatives.
|
||||
//
|
||||
U32 cur_pos;
|
||||
mChannelp->getPosition(&cur_pos,FMOD_TIMEUNIT_PCMBYTES);
|
||||
Check_FMOD_Error(mChannelp->getPosition(&cur_pos,FMOD_TIMEUNIT_PCMBYTES),"FMOD::Channel::getPosition");
|
||||
|
||||
if (cur_pos < (U32)mLastSamplePos)
|
||||
{
|
||||
@@ -629,12 +630,12 @@ void LLAudioChannelFMODEX::play()
|
||||
return;
|
||||
}
|
||||
|
||||
Check_FMOD_Error(mChannelp->setPaused(false), "FMOD::Channel::pause");
|
||||
Check_FMOD_Error(mChannelp->setPaused(false), "FMOD::Channel::setPaused");
|
||||
|
||||
getSource()->setPlayedOnce(true);
|
||||
|
||||
if(LLAudioEngine_FMODEX::mChannelGroups[getSource()->getType()])
|
||||
mChannelp->setChannelGroup(LLAudioEngine_FMODEX::mChannelGroups[getSource()->getType()]);
|
||||
Check_FMOD_Error(mChannelp->setChannelGroup(LLAudioEngine_FMODEX::mChannelGroups[getSource()->getType()]),"FMOD::Channel::setChannelGroup");
|
||||
}
|
||||
|
||||
|
||||
@@ -669,8 +670,8 @@ bool LLAudioChannelFMODEX::isPlaying()
|
||||
}
|
||||
|
||||
bool paused, playing;
|
||||
mChannelp->getPaused(&paused);
|
||||
mChannelp->isPlaying(&playing);
|
||||
Check_FMOD_Error(mChannelp->getPaused(&paused),"FMOD::Channel::getPaused");
|
||||
Check_FMOD_Error(mChannelp->isPlaying(&playing),"FMOD::Channel::isPlaying");
|
||||
return !paused && playing;
|
||||
}
|
||||
|
||||
@@ -680,7 +681,7 @@ bool LLAudioChannelFMODEX::isPlaying()
|
||||
//
|
||||
|
||||
|
||||
LLAudioBufferFMODEX::LLAudioBufferFMODEX(FMOD::System *system) : mSystemp(system), mSoundp(NULL)
|
||||
LLAudioBufferFMODEX::LLAudioBufferFMODEX(FMOD::System *system) : LLAudioBuffer(), mSystemp(system), mSoundp(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -689,7 +690,7 @@ LLAudioBufferFMODEX::~LLAudioBufferFMODEX()
|
||||
{
|
||||
if(mSoundp)
|
||||
{
|
||||
mSoundp->release();
|
||||
Check_FMOD_Error(mSoundp->release(),"FMOD::Sound::Release");
|
||||
mSoundp = NULL;
|
||||
}
|
||||
}
|
||||
@@ -714,7 +715,7 @@ bool LLAudioBufferFMODEX::loadWAV(const std::string& filename)
|
||||
if (mSoundp)
|
||||
{
|
||||
// If there's already something loaded in this buffer, clean it up.
|
||||
mSoundp->release();
|
||||
Check_FMOD_Error(mSoundp->release(),"FMOD::Sound::release");
|
||||
mSoundp = NULL;
|
||||
}
|
||||
|
||||
@@ -757,7 +758,7 @@ U32 LLAudioBufferFMODEX::getLength()
|
||||
}
|
||||
|
||||
U32 length;
|
||||
mSoundp->getLength(&length, FMOD_TIMEUNIT_PCMBYTES);
|
||||
Check_FMOD_Error(mSoundp->getLength(&length, FMOD_TIMEUNIT_PCMBYTES),"FMOD::Sound::getLength");
|
||||
return length;
|
||||
}
|
||||
|
||||
@@ -765,7 +766,7 @@ U32 LLAudioBufferFMODEX::getLength()
|
||||
void LLAudioChannelFMODEX::set3DMode(bool use3d)
|
||||
{
|
||||
FMOD_MODE current_mode;
|
||||
if(mChannelp->getMode(¤t_mode) != FMOD_OK)
|
||||
if(Check_FMOD_Error(mChannelp->getMode(¤t_mode),"FMOD::Channel::getMode"))
|
||||
return;
|
||||
FMOD_MODE new_mode = current_mode;
|
||||
new_mode &= ~(use3d ? FMOD_2D : FMOD_3D);
|
||||
@@ -773,7 +774,7 @@ void LLAudioChannelFMODEX::set3DMode(bool use3d)
|
||||
|
||||
if(current_mode != new_mode)
|
||||
{
|
||||
mChannelp->setMode(new_mode);
|
||||
Check_FMOD_Error(mChannelp->setMode(new_mode),"FMOD::Channel::setMode");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -314,7 +314,7 @@ void LLAudioChannelOpenAL::update3DPosition()
|
||||
alSourcef(mALSource, AL_GAIN, mCurrentSourcep->getGain() * getSecondaryGain());
|
||||
}
|
||||
|
||||
LLAudioBufferOpenAL::LLAudioBufferOpenAL()
|
||||
LLAudioBufferOpenAL::LLAudioBufferOpenAL() : LLAudioBuffer()
|
||||
{
|
||||
mALBuffer = AL_NONE;
|
||||
}
|
||||
|
||||
@@ -107,10 +107,18 @@ void LLStreamingAudio_FMODEX::start(const std::string& url)
|
||||
|
||||
if (!url.empty())
|
||||
{
|
||||
llinfos << "Starting internet stream: " << url << llendl;
|
||||
mCurrentInternetStreamp = new LLAudioStreamManagerFMODEX(mSystem,url);
|
||||
mURL = url;
|
||||
mMetaData = new LLSD;
|
||||
if(mDeadStreams.empty())
|
||||
{
|
||||
llinfos << "Starting internet stream: " << url << llendl;
|
||||
mCurrentInternetStreamp = new LLAudioStreamManagerFMODEX(mSystem,url);
|
||||
mURL = url;
|
||||
mMetaData = new LLSD;
|
||||
}
|
||||
else
|
||||
{
|
||||
llinfos << "Deferring stream load until buffer release: " << url << llendl;
|
||||
mPendingURL = url;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -139,6 +147,22 @@ void LLStreamingAudio_FMODEX::update()
|
||||
}
|
||||
}
|
||||
|
||||
if(!mDeadStreams.empty())
|
||||
{
|
||||
llassert_always(mCurrentInternetStreamp == NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
if(!mPendingURL.empty())
|
||||
{
|
||||
llassert_always(mCurrentInternetStreamp == NULL);
|
||||
llinfos << "Starting internet stream: " << mPendingURL << llendl;
|
||||
mCurrentInternetStreamp = new LLAudioStreamManagerFMODEX(mSystem,mPendingURL);
|
||||
mURL = mPendingURL;
|
||||
mMetaData = new LLSD;
|
||||
mPendingURL.clear();
|
||||
}
|
||||
|
||||
// Don't do anything if there are no streams playing
|
||||
if (!mCurrentInternetStreamp)
|
||||
{
|
||||
@@ -269,6 +293,8 @@ void LLStreamingAudio_FMODEX::update()
|
||||
|
||||
void LLStreamingAudio_FMODEX::stop()
|
||||
{
|
||||
mPendingURL.clear();
|
||||
|
||||
if(mMetaData)
|
||||
{
|
||||
delete mMetaData;
|
||||
@@ -327,7 +353,7 @@ int LLStreamingAudio_FMODEX::isPlaying()
|
||||
{
|
||||
return 1; // Active and playing
|
||||
}
|
||||
else if (!mURL.empty())
|
||||
else if (!mURL.empty() || !mPendingURL.empty())
|
||||
{
|
||||
return 2; // "Paused"
|
||||
}
|
||||
@@ -439,8 +465,6 @@ bool LLAudioStreamManagerFMODEX::stopStream()
|
||||
{
|
||||
if (mInternetStream)
|
||||
{
|
||||
|
||||
|
||||
bool close = true;
|
||||
switch (getOpenState())
|
||||
{
|
||||
@@ -455,9 +479,8 @@ bool LLAudioStreamManagerFMODEX::stopStream()
|
||||
close = true;
|
||||
}
|
||||
|
||||
if (close)
|
||||
if (close && mInternetStream->release() == FMOD_OK)
|
||||
{
|
||||
mInternetStream->release();
|
||||
mStreamChannel = NULL;
|
||||
mInternetStream = NULL;
|
||||
return true;
|
||||
|
||||
@@ -77,6 +77,7 @@ private:
|
||||
std::list<LLAudioStreamManagerFMODEX *> mDeadStreams;
|
||||
|
||||
std::string mURL;
|
||||
std::string mPendingURL;
|
||||
F32 mGain;
|
||||
|
||||
LLSD *mMetaData;
|
||||
|
||||
@@ -469,6 +469,7 @@ void LLCharacter::addSharedVisualParam(LLVisualParam *param)
|
||||
void LLCharacter::addVisualParam(LLVisualParam *param)
|
||||
{
|
||||
S32 index = param->getID();
|
||||
|
||||
// Add Index map
|
||||
std::pair<visual_param_index_map_t::iterator, bool> idxres;
|
||||
idxres = mVisualParamIndexMap.insert(visual_param_index_map_t::value_type(index, param));
|
||||
@@ -479,6 +480,8 @@ void LLCharacter::addVisualParam(LLVisualParam *param)
|
||||
visual_param_index_map_t::iterator index_iter = idxres.first;
|
||||
index_iter->second = param;
|
||||
}
|
||||
|
||||
mVisualParamSortedVector[index] = param;
|
||||
|
||||
if (param->getInfo())
|
||||
{
|
||||
|
||||
@@ -38,6 +38,8 @@
|
||||
#include "string_table.h"
|
||||
#include "llpointer.h"
|
||||
#include "llthread.h"
|
||||
#include "llsortedvector.h"
|
||||
#include <boost/unordered_map.hpp>
|
||||
|
||||
class LLPolyMesh;
|
||||
|
||||
@@ -208,21 +210,21 @@ public:
|
||||
// visual parameter accessors
|
||||
LLVisualParam* getFirstVisualParam()
|
||||
{
|
||||
mCurIterator = mVisualParamIndexMap.begin();
|
||||
mCurIterator = mVisualParamSortedVector.begin();
|
||||
return getNextVisualParam();
|
||||
}
|
||||
LLVisualParam* getNextVisualParam()
|
||||
{
|
||||
if (mCurIterator == mVisualParamIndexMap.end())
|
||||
if (mCurIterator == mVisualParamSortedVector.end())
|
||||
return 0;
|
||||
return (mCurIterator++)->second;
|
||||
}
|
||||
|
||||
|
||||
S32 getVisualParamCountInGroup(const EVisualParamGroup group) const
|
||||
{
|
||||
S32 rtn = 0;
|
||||
for (visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.begin();
|
||||
iter != mVisualParamIndexMap.end();
|
||||
for (visual_param_sorted_vec_t::const_iterator iter = mVisualParamSortedVector.begin();
|
||||
iter != mVisualParamSortedVector.end();
|
||||
/* */ )
|
||||
{
|
||||
if ((iter++)->second->getGroup() == group)
|
||||
@@ -238,7 +240,7 @@ public:
|
||||
visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.find(id);
|
||||
return (iter == mVisualParamIndexMap.end()) ? 0 : iter->second;
|
||||
}
|
||||
S32 getVisualParamID(LLVisualParam *id)
|
||||
/*S32 getVisualParamID(LLVisualParam *id)
|
||||
{
|
||||
visual_param_index_map_t::iterator iter;
|
||||
for (iter = mVisualParamIndexMap.begin(); iter != mVisualParamIndexMap.end(); iter++)
|
||||
@@ -247,7 +249,7 @@ public:
|
||||
return iter->first;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}*/
|
||||
S32 getVisualParamCount() const { return (S32)mVisualParamIndexMap.size(); }
|
||||
LLVisualParam* getVisualParam(const char *name);
|
||||
|
||||
@@ -278,13 +280,15 @@ protected:
|
||||
|
||||
private:
|
||||
// visual parameter stuff
|
||||
typedef std::map<S32, LLVisualParam *> visual_param_index_map_t;
|
||||
typedef std::map<char *, LLVisualParam *> visual_param_name_map_t;
|
||||
|
||||
visual_param_index_map_t::iterator mCurIterator;
|
||||
visual_param_index_map_t mVisualParamIndexMap;
|
||||
visual_param_name_map_t mVisualParamNameMap;
|
||||
//typedef std::map<S32, LLVisualParam *> visual_param_index_map_t;
|
||||
typedef boost::unordered_map<S32, LLVisualParam *> visual_param_index_map_t; //Hash map for fast lookup.
|
||||
typedef LLSortedVector<S32,LLVisualParam *> visual_param_sorted_vec_t; //Contiguous sorted array.
|
||||
typedef std::map<char *, LLVisualParam *> visual_param_name_map_t;
|
||||
|
||||
visual_param_sorted_vec_t::iterator mCurIterator;
|
||||
visual_param_sorted_vec_t mVisualParamSortedVector;
|
||||
visual_param_index_map_t mVisualParamIndexMap;
|
||||
visual_param_name_map_t mVisualParamNameMap;
|
||||
static LLStringTable sVisualParamNames;
|
||||
};
|
||||
|
||||
|
||||
@@ -83,13 +83,7 @@ LLMotionRegistry::~LLMotionRegistry()
|
||||
BOOL LLMotionRegistry::registerMotion( const LLUUID& id, LLMotionConstructor constructor )
|
||||
{
|
||||
// llinfos << "Registering motion: " << name << llendl;
|
||||
if (!is_in_map(mMotionTable, id))
|
||||
{
|
||||
mMotionTable[id] = constructor;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
return mMotionTable.insert(std::make_pair(id,constructor)).second;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@@ -54,7 +54,10 @@ protected:
|
||||
template<typename STATICDATA, class TRACKED>
|
||||
static STATICDATA& getStatic()
|
||||
{
|
||||
void *& instances = getInstances(typeid(TRACKED));
|
||||
//Singu note: Don't de-static the instances variable. getInstances is incredibly
|
||||
//expensive. Calling getInstances once and caching the result is sufficient
|
||||
//to avoid the instance-per-module issue noted above.
|
||||
static void *& instances = getInstances(typeid(TRACKED));
|
||||
if (! instances)
|
||||
{
|
||||
instances = new STATICDATA;
|
||||
|
||||
@@ -109,6 +109,16 @@ public:
|
||||
return const_cast<self*>(this)->find(key);
|
||||
}
|
||||
|
||||
//For easy insertion shorthand. Eases std::map => LLSortedVector drop-in replacement.
|
||||
mapped_type& operator[] (const key_type& key)
|
||||
{
|
||||
return insert(std::make_pair(key,mapped_type())).first->second;
|
||||
}
|
||||
const mapped_type& operator[] (const key_type& key) const
|
||||
{
|
||||
return insert(std::make_pair(key,mapped_type())).first->second;
|
||||
}
|
||||
|
||||
private:
|
||||
// Define our own 'less' comparator so we can specialize without messing
|
||||
// with std::less.
|
||||
|
||||
@@ -175,33 +175,10 @@ struct CopyNewPointer
|
||||
}
|
||||
};
|
||||
|
||||
// Simple function to help with finding pointers in maps.
|
||||
// For example:
|
||||
// typedef map_t;
|
||||
// std::map<int, const char*> foo;
|
||||
// foo[18] = "there";
|
||||
// foo[2] = "hello";
|
||||
// const char* bar = get_ptr_in_map(foo, 2); // bar -> "hello"
|
||||
// const char* baz = get_ptr_in_map(foo, 3); // baz == NULL
|
||||
template <typename K, typename T>
|
||||
inline T* get_ptr_in_map(const std::map<K,T*>& inmap, const K& key)
|
||||
{
|
||||
// Typedef here avoids warnings because of new c++ naming rules.
|
||||
typedef typename std::map<K,T*>::const_iterator map_iter;
|
||||
map_iter iter = inmap.find(key);
|
||||
if(iter == inmap.end())
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
return iter->second;
|
||||
}
|
||||
};
|
||||
|
||||
// helper function which returns true if key is in inmap.
|
||||
template <typename K, typename T>
|
||||
inline bool is_in_map(const std::map<K,T>& inmap, const K& key)
|
||||
template <typename T>
|
||||
//Singu note: This has been generalized to support a broader range of map-esque containers
|
||||
inline bool is_in_map(const T& inmap, typename T::key_type const& key)
|
||||
{
|
||||
if(inmap.find(key) == inmap.end())
|
||||
{
|
||||
@@ -217,11 +194,13 @@ inline bool is_in_map(const std::map<K,T>& inmap, const K& key)
|
||||
// To replace LLSkipMap getIfThere, use:
|
||||
// get_if_there(map, key, 0)
|
||||
// WARNING: Make sure default_value (generally 0) is not a valid map entry!
|
||||
template <typename K, typename T>
|
||||
inline T get_if_there(const std::map<K,T>& inmap, const K& key, T default_value)
|
||||
//
|
||||
//Singu note: This has been generalized to support a broader range of map-esque containers.
|
||||
template <typename T>
|
||||
inline typename T::mapped_type get_if_there(const T& inmap, typename T::key_type const& key, typename T::mapped_type default_value)
|
||||
{
|
||||
// Typedef here avoids warnings because of new c++ naming rules.
|
||||
typedef typename std::map<K,T>::const_iterator map_iter;
|
||||
typedef typename T::const_iterator map_iter;
|
||||
map_iter iter = inmap.find(key);
|
||||
if(iter == inmap.end())
|
||||
{
|
||||
@@ -233,6 +212,21 @@ inline T get_if_there(const std::map<K,T>& inmap, const K& key, T default_value)
|
||||
}
|
||||
};
|
||||
|
||||
// Simple function to help with finding pointers in maps.
|
||||
// For example:
|
||||
// typedef map_t;
|
||||
// std::map<int, const char*> foo;
|
||||
// foo[18] = "there";
|
||||
// foo[2] = "hello";
|
||||
// const char* bar = get_ptr_in_map(foo, 2); // bar -> "hello"
|
||||
// const char* baz = get_ptr_in_map(foo, 3); // baz == NULL
|
||||
//Singu note: This has been generalized to support a broader range of map-esque containers
|
||||
template <typename T>
|
||||
inline typename T::mapped_type get_ptr_in_map(const T& inmap, typename T::key_type const& key)
|
||||
{
|
||||
return get_if_there(inmap,key,NULL);
|
||||
};
|
||||
|
||||
// Useful for replacing the removeObj() functionality of LLDynamicArray
|
||||
// Example:
|
||||
// for (std::vector<T>::iterator iter = mList.begin(); iter != mList.end(); )
|
||||
@@ -242,10 +236,12 @@ inline T get_if_there(const std::map<K,T>& inmap, const K& key, T default_value)
|
||||
// else
|
||||
// ++iter;
|
||||
// }
|
||||
template <typename T, typename Iter>
|
||||
inline Iter vector_replace_with_last(std::vector<T>& invec, Iter iter)
|
||||
//
|
||||
//Singu note: This has been generalized to support a broader range of sequence containers
|
||||
template <typename T>
|
||||
inline typename T::iterator vector_replace_with_last(T& invec, typename T::iterator& iter)
|
||||
{
|
||||
typename std::vector<T>::iterator last = invec.end(); --last;
|
||||
typename T::iterator last = invec.end(); --last;
|
||||
if (iter == invec.end())
|
||||
{
|
||||
return iter;
|
||||
@@ -266,13 +262,15 @@ inline Iter vector_replace_with_last(std::vector<T>& invec, Iter iter)
|
||||
// Useful for replacing the removeObj() functionality of LLDynamicArray
|
||||
// Example:
|
||||
// vector_replace_with_last(mList, x);
|
||||
//
|
||||
//Singu note: This has been generalized to support a broader range of sequence containers
|
||||
template <typename T>
|
||||
inline bool vector_replace_with_last(std::vector<T>& invec, const T& val)
|
||||
inline bool vector_replace_with_last(T& invec, typename T::value_type const& val)
|
||||
{
|
||||
typename std::vector<T>::iterator iter = std::find(invec.begin(), invec.end(), val);
|
||||
typename T::iterator iter = std::find(invec.begin(), invec.end(), val);
|
||||
if (iter != invec.end())
|
||||
{
|
||||
typename std::vector<T>::iterator last = invec.end(); --last;
|
||||
typename T::iterator last = invec.end(); --last;
|
||||
*iter = *last;
|
||||
invec.pop_back();
|
||||
return true;
|
||||
|
||||
@@ -219,17 +219,15 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
|
||||
}
|
||||
}
|
||||
|
||||
gGL.pushMatrix();
|
||||
gGL.loadIdentity();
|
||||
gGL.translatef(floorf(sCurOrigin.mX*sScaleX), floorf(sCurOrigin.mY*sScaleY), sCurDepth);
|
||||
gGL.pushUIMatrix();
|
||||
|
||||
// this code snaps the text origin to a pixel grid to start with
|
||||
F32 pixel_offset_x = llround((F32)sCurOrigin.mX) - (sCurOrigin.mX);
|
||||
F32 pixel_offset_y = llround((F32)sCurOrigin.mY) - (sCurOrigin.mY);
|
||||
gGL.translatef(-pixel_offset_x, -pixel_offset_y, 0.f);
|
||||
gGL.loadUIIdentity();
|
||||
|
||||
LLVector2 origin(floorf(sCurOrigin.mX*sScaleX), floorf(sCurOrigin.mY*sScaleY));
|
||||
|
||||
|
||||
gGL.color4fv( color.mV );
|
||||
// Depth translation, so that floating text appears 'in-world'
|
||||
// and is correctly occluded.
|
||||
gGL.translatef(0.f,0.f,sCurDepth);
|
||||
|
||||
S32 chars_drawn = 0;
|
||||
S32 i;
|
||||
@@ -249,20 +247,21 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
|
||||
// Not guaranteed to be set correctly
|
||||
gGL.setSceneBlendType(LLRender::BT_ALPHA);
|
||||
|
||||
cur_x = ((F32)x * sScaleX);
|
||||
cur_y = ((F32)y * sScaleY);
|
||||
cur_x = ((F32)x * sScaleX) + origin.mV[VX];
|
||||
cur_y = ((F32)y * sScaleY) + origin.mV[VY];
|
||||
|
||||
// Offset y by vertical alignment.
|
||||
// use unscaled font metrics here
|
||||
switch (valign)
|
||||
{
|
||||
case TOP:
|
||||
cur_y -= mAscender;
|
||||
cur_y -= llceil(mAscender);
|
||||
break;
|
||||
case BOTTOM:
|
||||
cur_y += mDescender;
|
||||
cur_y += llceil(mDescender);
|
||||
break;
|
||||
case VCENTER:
|
||||
cur_y -= ((mAscender - mDescender)/2.f);
|
||||
cur_y -= llceil((llceil(mAscender) - llceil(mDescender))/2.f);
|
||||
break;
|
||||
case BASELINE:
|
||||
// Baseline, do nothing.
|
||||
@@ -276,10 +275,10 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
|
||||
case LEFT:
|
||||
break;
|
||||
case RIGHT:
|
||||
cur_x -= llmin(scaled_max_pixels, llround(getWidthF32(wstr.c_str(), 0, length) * sScaleX));
|
||||
cur_x -= llmin(scaled_max_pixels, llround(getWidthF32(wstr.c_str(), begin_offset, length) * sScaleX));
|
||||
break;
|
||||
case HCENTER:
|
||||
cur_x -= llmin(scaled_max_pixels, llround(getWidthF32(wstr.c_str(), 0, length) * sScaleX)) / 2;
|
||||
cur_x -= llmin(scaled_max_pixels, llround(getWidthF32(wstr.c_str(), begin_offset, length) * sScaleX)) / 2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -288,10 +287,12 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
|
||||
cur_render_y = cur_y;
|
||||
cur_render_x = cur_x;
|
||||
|
||||
F32 start_x = cur_x;
|
||||
F32 start_x = (F32)llround(cur_x);
|
||||
|
||||
F32 inv_width = 1.f / mFontBitmapCachep->getBitmapWidth();
|
||||
F32 inv_height = 1.f / mFontBitmapCachep->getBitmapHeight();
|
||||
const LLFontBitmapCache* font_bitmap_cache = mFontBitmapCachep;
|
||||
|
||||
F32 inv_width = 1.f / font_bitmap_cache->getBitmapWidth();
|
||||
F32 inv_height = 1.f / font_bitmap_cache->getBitmapHeight();
|
||||
|
||||
const S32 LAST_CHARACTER = LLFontFreetype::LAST_CHAR_FULL;
|
||||
|
||||
@@ -300,7 +301,8 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
|
||||
if (use_ellipses && halign == LEFT)
|
||||
{
|
||||
// check for too long of a string
|
||||
if (getWidthF32(wstr.c_str(), 0, max_chars) * sScaleX > scaled_max_pixels)
|
||||
S32 string_width = llround(getWidthF32(wstr.c_str(), begin_offset, max_chars) * sScaleX);
|
||||
if (string_width > scaled_max_pixels)
|
||||
{
|
||||
// use four dots for ellipsis width to generate padding
|
||||
const LLWString dots(utf8str_to_wstring(std::string("....")));
|
||||
@@ -358,12 +360,9 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
|
||||
if (!label.empty())
|
||||
{
|
||||
gGL.pushMatrix();
|
||||
//gGL.loadIdentity();
|
||||
//gGL.translatef(sCurOrigin.mX, sCurOrigin.mY, 0.0f);
|
||||
//gGL.scalef(sScaleX, sScaleY, 1.f);
|
||||
getFontExtChar()->render(label, 0,
|
||||
/*llfloor*/((ext_x + (F32)ext_image->getWidth() + EXT_X_BEARING) / sScaleX),
|
||||
/*llfloor*/(cur_y / sScaleY),
|
||||
/*llfloor*/(ext_x / sScaleX) + ext_image->getWidth() + EXT_X_BEARING - sCurOrigin.mX,
|
||||
/*llfloor*/(cur_render_y / sScaleY) - sCurOrigin.mY,
|
||||
color,
|
||||
halign, BASELINE, NORMAL, NO_SHADOW, S32_MAX, S32_MAX, NULL,
|
||||
TRUE );
|
||||
@@ -412,12 +411,12 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
|
||||
LLRectf uv_rect((fgi->mXBitmapOffset) * inv_width,
|
||||
(fgi->mYBitmapOffset + fgi->mHeight + PAD_UVY) * inv_height,
|
||||
(fgi->mXBitmapOffset + fgi->mWidth) * inv_width,
|
||||
(fgi->mYBitmapOffset - PAD_UVY) * inv_height);
|
||||
// snap glyph origin to whole screen pixel
|
||||
LLRectf screen_rect(llround(cur_render_x + (F32)fgi->mXBearing),
|
||||
llround(cur_render_y + (F32)fgi->mYBearing),
|
||||
llround(cur_render_x + (F32)fgi->mXBearing) + (F32)fgi->mWidth,
|
||||
llround(cur_render_y + (F32)fgi->mYBearing) - (F32)fgi->mHeight);
|
||||
(fgi->mYBitmapOffset - PAD_UVY) * inv_height);
|
||||
// snap glyph origin to whole screen pixel
|
||||
LLRectf screen_rect((F32)llround(cur_render_x + (F32)fgi->mXBearing),
|
||||
(F32)llround(cur_render_y + (F32)fgi->mYBearing),
|
||||
(F32)llround(cur_render_x + (F32)fgi->mXBearing) + (F32)fgi->mWidth,
|
||||
(F32)llround(cur_render_y + (F32)fgi->mYBearing) - (F32)fgi->mHeight);
|
||||
|
||||
drawGlyph(screen_rect, uv_rect, color, style, shadow, drop_shadow_strength);
|
||||
|
||||
@@ -440,8 +439,8 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
|
||||
// Must do this to cur_x, not just to cur_render_x, otherwise you
|
||||
// will squish sub-pixel kerned characters too close together.
|
||||
// For example, "CCCCC" looks bad.
|
||||
cur_x = (F32)llfloor(cur_x + 0.5f);
|
||||
//cur_y = (F32)llfloor(cur_y + 0.5f);
|
||||
cur_x = (F32)llround(cur_x);
|
||||
//cur_y = (F32)llround(cur_y);
|
||||
|
||||
cur_render_x = cur_x;
|
||||
cur_render_y = cur_y;
|
||||
@@ -450,41 +449,40 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
|
||||
|
||||
if (right_x)
|
||||
{
|
||||
*right_x = cur_x / sScaleX;
|
||||
*right_x = (cur_x - origin.mV[VX]) / sScaleX;
|
||||
}
|
||||
|
||||
if (style & UNDERLINE)
|
||||
{
|
||||
F32 descender = (F32)llfloor(mDescender);
|
||||
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
gGL.begin(LLRender::LINES);
|
||||
gGL.vertex2f(start_x, cur_y - (mDescender));
|
||||
gGL.vertex2f(cur_x, cur_y - (mDescender));
|
||||
gGL.vertex2f(start_x, cur_y - descender);
|
||||
gGL.vertex2f(cur_x, cur_y - descender);
|
||||
gGL.end();
|
||||
}
|
||||
|
||||
// *FIX: get this working in all alignment cases, etc.
|
||||
if (draw_ellipses)
|
||||
{
|
||||
|
||||
// recursively render ellipses at end of string
|
||||
// we've already reserved enough room
|
||||
gGL.pushMatrix();
|
||||
//gGL.loadIdentity();
|
||||
//gGL.translatef(sCurOrigin.mX, sCurOrigin.mY, 0.0f);
|
||||
//gGL.scalef(sScaleX, sScaleY, 1.f);
|
||||
gGL.pushUIMatrix();
|
||||
renderUTF8(std::string("..."),
|
||||
0,
|
||||
cur_x / sScaleX, (F32)y,
|
||||
(cur_x - origin.mV[VX]) / sScaleX, (F32)y,
|
||||
color,
|
||||
LEFT, valign,
|
||||
style,
|
||||
LLFontGL::NO_SHADOW,
|
||||
shadow,
|
||||
S32_MAX, max_pixels,
|
||||
right_x,
|
||||
FALSE);
|
||||
gGL.popMatrix();
|
||||
gGL.popUIMatrix();
|
||||
}
|
||||
|
||||
gGL.popMatrix();
|
||||
gGL.popUIMatrix();
|
||||
|
||||
return chars_drawn;
|
||||
}
|
||||
@@ -578,7 +576,7 @@ F32 LLFontGL::getWidthF32(const llwchar* wchars, const S32 begin_offset, const S
|
||||
cur_x += getXAdvance(wch);
|
||||
llwchar next_char = wchars[i+1];
|
||||
|
||||
if (((i + 1) < max_chars)
|
||||
if (((i + 1) < begin_offset + max_chars)
|
||||
&& next_char
|
||||
&& (next_char < LAST_CHARACTER))
|
||||
{
|
||||
@@ -587,7 +585,7 @@ F32 LLFontGL::getWidthF32(const llwchar* wchars, const S32 begin_offset, const S
|
||||
}
|
||||
}
|
||||
// Round after kerning.
|
||||
cur_x = (F32)llfloor(cur_x + 0.5f);
|
||||
cur_x = (F32)llround(cur_x);
|
||||
}
|
||||
|
||||
return cur_x / sScaleX;
|
||||
@@ -694,7 +692,7 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch
|
||||
}
|
||||
}
|
||||
// Round after kerning.
|
||||
cur_x = (F32)llfloor(cur_x + 0.5f);
|
||||
cur_x = (F32)llround(cur_x);
|
||||
drawn_x = cur_x;
|
||||
}
|
||||
|
||||
@@ -871,7 +869,7 @@ S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, const S32 begin_offset,
|
||||
}
|
||||
|
||||
// Round after kerning.
|
||||
cur_x = (F32)llfloor(cur_x + 0.5f);
|
||||
cur_x = (F32)llround(cur_x);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -100,22 +100,21 @@ void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, const LL
|
||||
|
||||
void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, S32 pixel_offset, BOOL filled)
|
||||
{
|
||||
gGL.pushMatrix();
|
||||
gGL.pushUIMatrix();
|
||||
left += LLFontGL::sCurOrigin.mX;
|
||||
right += LLFontGL::sCurOrigin.mX;
|
||||
bottom += LLFontGL::sCurOrigin.mY;
|
||||
top += LLFontGL::sCurOrigin.mY;
|
||||
|
||||
gGL.loadIdentity();
|
||||
gGL.loadUIIdentity();
|
||||
gl_rect_2d(llfloor((F32)left * LLRender2D::sGLScaleFactor.mV[VX]) - pixel_offset,
|
||||
llfloor((F32)top * LLRender2D::sGLScaleFactor.mV[VY]) + pixel_offset,
|
||||
llfloor((F32)right * LLRender2D::sGLScaleFactor.mV[VX]) + pixel_offset,
|
||||
llfloor((F32)bottom * LLRender2D::sGLScaleFactor.mV[VY]) - pixel_offset,
|
||||
filled);
|
||||
gGL.popMatrix();
|
||||
gGL.popUIMatrix();
|
||||
}
|
||||
|
||||
|
||||
void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, BOOL filled )
|
||||
{
|
||||
stop_glerror();
|
||||
@@ -386,8 +385,8 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTex
|
||||
}
|
||||
|
||||
// add in offset of current image to current UI translation
|
||||
const LLVector3 ui_scale = LLVector3(1.f,1.f,1.f);//gGL.getUIScale();
|
||||
const LLVector3 ui_translation = LLVector3(x,y,0.f);//(gGL.getUITranslation() + LLVector3(x, y, 0.f)).scaledVec(ui_scale);
|
||||
const LLVector3 ui_scale = gGL.getUIScale();
|
||||
const LLVector3 ui_translation = (gGL.getUITranslation() + LLVector3(x, y, 0.f)).scaledVec(ui_scale);
|
||||
|
||||
F32 uv_width = uv_outer_rect.getWidth();
|
||||
F32 uv_height = uv_outer_rect.getHeight();
|
||||
@@ -659,8 +658,8 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre
|
||||
|
||||
gGL.begin(LLRender::QUADS);
|
||||
{
|
||||
LLVector3 ui_scale = LLVector3(1.f,1.f,1.f);//gGL.getUIScale();
|
||||
LLVector3 ui_translation = LLVector3(0.f,0.f,0.f); //gGL.getUITranslation();
|
||||
LLVector3 ui_scale = gGL.getUIScale();
|
||||
LLVector3 ui_translation = gGL.getUITranslation();
|
||||
ui_translation.mV[VX] += x;
|
||||
ui_translation.mV[VY] += y;
|
||||
ui_translation.scaleVec(ui_scale);
|
||||
@@ -690,13 +689,13 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre
|
||||
}
|
||||
else
|
||||
{
|
||||
gGL.pushMatrix();
|
||||
gGL.translatef((F32)x, (F32)y, 0.f);
|
||||
gGL.pushUIMatrix();
|
||||
gGL.translateUI((F32)x, (F32)y, 0.f);
|
||||
|
||||
F32 offset_x = F32(width/2);
|
||||
F32 offset_y = F32(height/2);
|
||||
|
||||
gGL.translatef(offset_x, offset_y, 0.f);
|
||||
gGL.translateUI(offset_x, offset_y, 0.f);
|
||||
|
||||
LLMatrix3 quat(0.f, 0.f, degrees*DEG_TO_RAD);
|
||||
|
||||
@@ -725,7 +724,7 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre
|
||||
gGL.vertex2f(v.mV[0], v.mV[1] );
|
||||
}
|
||||
gGL.end();
|
||||
gGL.popMatrix();
|
||||
gGL.popUIMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -766,9 +765,9 @@ void gl_arc_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled, F
|
||||
end_angle += F_TWO_PI;
|
||||
}
|
||||
|
||||
gGL.pushMatrix();
|
||||
gGL.pushUIMatrix();
|
||||
{
|
||||
gGL.translatef(center_x, center_y, 0.f);
|
||||
gGL.translateUI(center_x, center_y, 0.f);
|
||||
|
||||
// Inexact, but reasonably fast.
|
||||
F32 delta = (end_angle - start_angle) / steps;
|
||||
@@ -799,15 +798,15 @@ void gl_arc_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled, F
|
||||
}
|
||||
gGL.end();
|
||||
}
|
||||
gGL.popMatrix();
|
||||
gGL.popUIMatrix();
|
||||
}
|
||||
|
||||
void gl_circle_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled)
|
||||
{
|
||||
gGL.pushMatrix();
|
||||
gGL.pushUIMatrix();
|
||||
{
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
gGL.translatef(center_x, center_y, 0.f);
|
||||
gGL.translateUI(center_x, center_y, 0.f);
|
||||
|
||||
// Inexact, but reasonably fast.
|
||||
F32 delta = F_TWO_PI / steps;
|
||||
@@ -838,7 +837,7 @@ void gl_circle_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled
|
||||
}
|
||||
gGL.end();
|
||||
}
|
||||
gGL.popMatrix();
|
||||
gGL.popUIMatrix();
|
||||
}
|
||||
|
||||
// Renders a ring with sides (tube shape)
|
||||
@@ -865,9 +864,9 @@ void gl_deep_circle( F32 radius, F32 depth, S32 steps )
|
||||
|
||||
void gl_ring( F32 radius, F32 width, const LLColor4& center_color, const LLColor4& side_color, S32 steps, BOOL render_center )
|
||||
{
|
||||
gGL.pushMatrix();
|
||||
gGL.pushUIMatrix();
|
||||
{
|
||||
gGL.translatef(0.f, 0.f, -width / 2);
|
||||
gGL.translateUI(0.f, 0.f, -width / 2);
|
||||
if( render_center )
|
||||
{
|
||||
gGL.color4fv(center_color.mV);
|
||||
@@ -878,11 +877,11 @@ void gl_ring( F32 radius, F32 width, const LLColor4& center_color, const LLColor
|
||||
{
|
||||
gGL.diffuseColor4fv(side_color.mV);
|
||||
gl_washer_2d(radius, radius - width, steps, side_color, side_color);
|
||||
gGL.translatef(0.f, 0.f, width);
|
||||
gGL.translateUI(0.f, 0.f, width);
|
||||
gl_washer_2d(radius - width, radius, steps, side_color, side_color);
|
||||
}
|
||||
}
|
||||
gGL.popMatrix();
|
||||
gGL.popUIMatrix();
|
||||
}
|
||||
|
||||
// Draw gray and white checkerboard with black border
|
||||
@@ -1057,9 +1056,9 @@ void gl_segmented_rect_2d_tex(const S32 left,
|
||||
S32 width = llabs(right - left);
|
||||
S32 height = llabs(top - bottom);
|
||||
|
||||
gGL.pushMatrix();
|
||||
gGL.pushUIMatrix();
|
||||
|
||||
gGL.translatef((F32)left, (F32)bottom, 0.f);
|
||||
gGL.translateUI((F32)left, (F32)bottom, 0.f);
|
||||
LLVector2 border_uv_scale((F32)border_size / (F32)texture_width, (F32)border_size / (F32)texture_height);
|
||||
|
||||
if (border_uv_scale.mV[VX] > 0.5f)
|
||||
@@ -1200,7 +1199,7 @@ void gl_segmented_rect_2d_tex(const S32 left,
|
||||
}
|
||||
gGL.end();
|
||||
|
||||
gGL.popMatrix();
|
||||
gGL.popUIMatrix();
|
||||
}
|
||||
|
||||
//FIXME: rewrite to use scissor?
|
||||
@@ -1218,9 +1217,9 @@ void gl_segmented_rect_2d_fragment_tex(const S32 left,
|
||||
S32 width = llabs(right - left);
|
||||
S32 height = llabs(top - bottom);
|
||||
|
||||
gGL.pushMatrix();
|
||||
gGL.pushUIMatrix();
|
||||
|
||||
gGL.translatef((F32)left, (F32)bottom, 0.f);
|
||||
gGL.translateUI((F32)left, (F32)bottom, 0.f);
|
||||
LLVector2 border_uv_scale((F32)border_size / (F32)texture_width, (F32)border_size / (F32)texture_height);
|
||||
|
||||
if (border_uv_scale.mV[VX] > 0.5f)
|
||||
@@ -1391,7 +1390,7 @@ void gl_segmented_rect_2d_fragment_tex(const S32 left,
|
||||
}
|
||||
gGL.end();
|
||||
|
||||
gGL.popMatrix();
|
||||
gGL.popUIMatrix();
|
||||
}
|
||||
|
||||
void gl_segmented_rect_3d_tex(const LLVector2& border_scale, const LLVector3& border_width,
|
||||
@@ -1554,7 +1553,7 @@ void LLRender2D::cleanupClass()
|
||||
//static
|
||||
void LLRender2D::translate(F32 x, F32 y, F32 z)
|
||||
{
|
||||
gGL.translatef(x,y,z);
|
||||
gGL.translateUI(x,y,z);
|
||||
LLFontGL::sCurOrigin.mX += (S32) x;
|
||||
LLFontGL::sCurOrigin.mY += (S32) y;
|
||||
LLFontGL::sCurDepth += z;
|
||||
@@ -1563,14 +1562,14 @@ void LLRender2D::translate(F32 x, F32 y, F32 z)
|
||||
//static
|
||||
void LLRender2D::pushMatrix()
|
||||
{
|
||||
gGL.pushMatrix();
|
||||
gGL.pushUIMatrix();
|
||||
LLFontGL::sOriginStack.push_back(std::make_pair(LLFontGL::sCurOrigin, LLFontGL::sCurDepth));
|
||||
}
|
||||
|
||||
//static
|
||||
void LLRender2D::popMatrix()
|
||||
{
|
||||
gGL.popMatrix();
|
||||
gGL.popUIMatrix();
|
||||
LLFontGL::sCurOrigin = LLFontGL::sOriginStack.back().first;
|
||||
LLFontGL::sCurDepth = LLFontGL::sOriginStack.back().second;
|
||||
LLFontGL::sOriginStack.pop_back();
|
||||
@@ -1579,7 +1578,7 @@ void LLRender2D::popMatrix()
|
||||
//static
|
||||
void LLRender2D::loadIdentity()
|
||||
{
|
||||
gGL.loadIdentity();
|
||||
gGL.loadUIIdentity();
|
||||
LLFontGL::sCurOrigin.mX = 0;
|
||||
LLFontGL::sCurOrigin.mY = 0;
|
||||
LLFontGL::sCurDepth = 0.f;
|
||||
|
||||
@@ -36,9 +36,6 @@
|
||||
#include "llshadermgr.h"
|
||||
#include "llglslshader.h"
|
||||
#include "llmemory.h"
|
||||
#include "llfasttimer.h"
|
||||
|
||||
#define LL_VBO_POOLING 0
|
||||
|
||||
//Next Highest Power Of Two
|
||||
//helper function, returns first number > v that is a power of 2, or v if v is already a power of 2
|
||||
@@ -67,6 +64,7 @@ U32 wpo2(U32 i)
|
||||
|
||||
|
||||
const U32 LL_VBO_BLOCK_SIZE = 2048;
|
||||
const U32 LL_VBO_POOL_MAX_SEED_SIZE = 256*1024;
|
||||
|
||||
U32 vbo_block_size(U32 size)
|
||||
{ //what block size will fit size?
|
||||
@@ -79,6 +77,7 @@ U32 vbo_block_index(U32 size)
|
||||
return vbo_block_size(size)/LL_VBO_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
const U32 LL_VBO_POOL_SEED_COUNT = vbo_block_index(LL_VBO_POOL_MAX_SEED_SIZE);
|
||||
|
||||
|
||||
//============================================================================
|
||||
@@ -91,6 +90,11 @@ LLVBOPool LLVertexBuffer::sDynamicIBOPool(GL_DYNAMIC_DRAW_ARB, GL_ELEMENT_ARRAY_
|
||||
|
||||
U32 LLVBOPool::sBytesPooled = 0;
|
||||
U32 LLVBOPool::sIndexBytesPooled = 0;
|
||||
U32 LLVBOPool::sCurGLName = 1;
|
||||
|
||||
std::list<U32> LLVertexBuffer::sAvailableVAOName;
|
||||
U32 LLVertexBuffer::sCurVAOName = 1;
|
||||
|
||||
U32 LLVertexBuffer::sAllocatedIndexBytes = 0;
|
||||
U32 LLVertexBuffer::sIndexCount = 0;
|
||||
|
||||
@@ -116,14 +120,54 @@ bool LLVertexBuffer::sUseVAO = false;
|
||||
bool LLVertexBuffer::sPreferStreamDraw = false;
|
||||
|
||||
|
||||
volatile U8* LLVBOPool::allocate(U32& name, U32 size)
|
||||
U32 LLVBOPool::genBuffer()
|
||||
{
|
||||
U32 ret = 0;
|
||||
|
||||
if (mGLNamePool.empty())
|
||||
{
|
||||
ret = sCurGLName++;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = mGLNamePool.front();
|
||||
mGLNamePool.pop_front();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void LLVBOPool::deleteBuffer(U32 name)
|
||||
{
|
||||
if (gGLManager.mInited)
|
||||
{
|
||||
LLVertexBuffer::unbind();
|
||||
|
||||
glBindBufferARB(mType, name);
|
||||
glBufferDataARB(mType, 0, NULL, mUsage);
|
||||
|
||||
llassert(std::find(mGLNamePool.begin(), mGLNamePool.end(), name) == mGLNamePool.end());
|
||||
|
||||
mGLNamePool.push_back(name);
|
||||
|
||||
glBindBufferARB(mType, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LLVBOPool::LLVBOPool(U32 vboUsage, U32 vboType)
|
||||
: mUsage(vboUsage), mType(vboType)
|
||||
{
|
||||
mMissCount.resize(LL_VBO_POOL_SEED_COUNT);
|
||||
std::fill(mMissCount.begin(), mMissCount.end(), 0);
|
||||
}
|
||||
|
||||
volatile U8* LLVBOPool::allocate(U32& name, U32 size, bool for_seed)
|
||||
{
|
||||
llassert(vbo_block_size(size) == size);
|
||||
|
||||
volatile U8* ret = NULL;
|
||||
|
||||
#if LL_VBO_POOLING
|
||||
|
||||
U32 i = vbo_block_index(size);
|
||||
|
||||
if (mFreeList.size() <= i)
|
||||
@@ -131,12 +175,18 @@ volatile U8* LLVBOPool::allocate(U32& name, U32 size)
|
||||
mFreeList.resize(i+1);
|
||||
}
|
||||
|
||||
if (mFreeList[i].empty())
|
||||
if (mFreeList[i].empty() || for_seed)
|
||||
{
|
||||
//make a new buffer
|
||||
glGenBuffersARB(1, &name);
|
||||
name = genBuffer();
|
||||
|
||||
glBindBufferARB(mType, name);
|
||||
|
||||
if (!for_seed && i < LL_VBO_POOL_SEED_COUNT)
|
||||
{ //record this miss
|
||||
mMissCount[i]++;
|
||||
}
|
||||
|
||||
if (mType == GL_ARRAY_BUFFER_ARB)
|
||||
{
|
||||
LLVertexBuffer::sAllocatedBytes += size;
|
||||
@@ -157,6 +207,25 @@ volatile U8* LLVBOPool::allocate(U32& name, U32 size)
|
||||
}
|
||||
|
||||
glBindBufferARB(mType, 0);
|
||||
|
||||
if (for_seed)
|
||||
{ //put into pool for future use
|
||||
llassert(mFreeList.size() > i);
|
||||
|
||||
Record rec;
|
||||
rec.mGLName = name;
|
||||
rec.mClientData = ret;
|
||||
|
||||
if (mType == GL_ARRAY_BUFFER_ARB)
|
||||
{
|
||||
sBytesPooled += size;
|
||||
}
|
||||
else
|
||||
{
|
||||
sIndexBytesPooled += size;
|
||||
}
|
||||
mFreeList[i].push_back(rec);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -174,33 +243,6 @@ volatile U8* LLVBOPool::allocate(U32& name, U32 size)
|
||||
|
||||
mFreeList[i].pop_front();
|
||||
}
|
||||
#else //no pooling
|
||||
|
||||
glGenBuffersARB(1, &name);
|
||||
glBindBufferARB(mType, name);
|
||||
|
||||
if (mType == GL_ARRAY_BUFFER_ARB)
|
||||
{
|
||||
LLVertexBuffer::sAllocatedBytes += size;
|
||||
}
|
||||
else
|
||||
{
|
||||
LLVertexBuffer::sAllocatedIndexBytes += size;
|
||||
}
|
||||
|
||||
if (LLVertexBuffer::sDisableVBOMapping || mUsage != GL_DYNAMIC_DRAW_ARB)
|
||||
{
|
||||
glBufferDataARB(mType, size, 0, mUsage);
|
||||
ret = (U8*) ll_aligned_malloc_16(size);
|
||||
}
|
||||
else
|
||||
{ //always use a true hint of static draw when allocating non-client-backed buffers
|
||||
glBufferDataARB(mType, size, 0, GL_STATIC_DRAW_ARB);
|
||||
}
|
||||
|
||||
glBindBufferARB(mType, 0);
|
||||
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -209,34 +251,7 @@ void LLVBOPool::release(U32 name, volatile U8* buffer, U32 size)
|
||||
{
|
||||
llassert(vbo_block_size(size) == size);
|
||||
|
||||
#if LL_VBO_POOLING
|
||||
|
||||
U32 i = vbo_block_index(size);
|
||||
|
||||
llassert(mFreeList.size() > i);
|
||||
|
||||
Record rec;
|
||||
rec.mGLName = name;
|
||||
rec.mClientData = buffer;
|
||||
|
||||
if (buffer == NULL)
|
||||
{
|
||||
glDeleteBuffersARB(1, &rec.mGLName);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mType == GL_ARRAY_BUFFER_ARB)
|
||||
{
|
||||
sBytesPooled += size;
|
||||
}
|
||||
else
|
||||
{
|
||||
sIndexBytesPooled += size;
|
||||
}
|
||||
mFreeList[i].push_back(rec);
|
||||
}
|
||||
#else //no pooling
|
||||
glDeleteBuffersARB(1, &name);
|
||||
deleteBuffer(name);
|
||||
ll_aligned_free_16((U8*) buffer);
|
||||
|
||||
if (mType == GL_ARRAY_BUFFER_ARB)
|
||||
@@ -247,12 +262,37 @@ void LLVBOPool::release(U32 name, volatile U8* buffer, U32 size)
|
||||
{
|
||||
LLVertexBuffer::sAllocatedIndexBytes -= size;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void LLVBOPool::seedPool()
|
||||
{
|
||||
U32 dummy_name = 0;
|
||||
|
||||
if (mFreeList.size() < LL_VBO_POOL_SEED_COUNT)
|
||||
{
|
||||
mFreeList.resize(LL_VBO_POOL_SEED_COUNT);
|
||||
}
|
||||
|
||||
for (U32 i = 0; i < LL_VBO_POOL_SEED_COUNT; i++)
|
||||
{
|
||||
if (mMissCount[i] > mFreeList[i].size())
|
||||
{
|
||||
U32 size = i*LL_VBO_BLOCK_SIZE;
|
||||
|
||||
S32 count = mMissCount[i] - mFreeList[i].size();
|
||||
for (S32 j = 0; j < count; ++j)
|
||||
{
|
||||
allocate(dummy_name, size, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LLVBOPool::cleanup()
|
||||
{
|
||||
U32 size = 1;
|
||||
U32 size = LL_VBO_BLOCK_SIZE;
|
||||
|
||||
for (U32 i = 0; i < mFreeList.size(); ++i)
|
||||
{
|
||||
@@ -262,8 +302,8 @@ void LLVBOPool::cleanup()
|
||||
{
|
||||
Record& r = l.front();
|
||||
|
||||
glDeleteBuffersARB(1, &r.mGLName);
|
||||
|
||||
deleteBuffer(r.mGLName);
|
||||
|
||||
if (r.mClientData)
|
||||
{
|
||||
ll_aligned_free_16((void*) r.mClientData);
|
||||
@@ -283,8 +323,11 @@ void LLVBOPool::cleanup()
|
||||
}
|
||||
}
|
||||
|
||||
size *= 2;
|
||||
size += LL_VBO_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
//reset miss counts
|
||||
std::fill(mMissCount.begin(), mMissCount.end(), 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -318,6 +361,41 @@ U32 LLVertexBuffer::sGLMode[LLRender::NUM_MODES] =
|
||||
GL_LINE_LOOP,
|
||||
};
|
||||
|
||||
//static
|
||||
U32 LLVertexBuffer::getVAOName()
|
||||
{
|
||||
U32 ret = 0;
|
||||
|
||||
if (!sAvailableVAOName.empty())
|
||||
{
|
||||
ret = sAvailableVAOName.front();
|
||||
sAvailableVAOName.pop_front();
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef GL_ARB_vertex_array_object
|
||||
glGenVertexArrays(1, &ret);
|
||||
#endif
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
//static
|
||||
void LLVertexBuffer::releaseVAOName(U32 name)
|
||||
{
|
||||
sAvailableVAOName.push_back(name);
|
||||
}
|
||||
|
||||
|
||||
//static
|
||||
void LLVertexBuffer::seedPools()
|
||||
{
|
||||
sStreamVBOPool.seedPool();
|
||||
sDynamicVBOPool.seedPool();
|
||||
sStreamIBOPool.seedPool();
|
||||
sDynamicIBOPool.seedPool();
|
||||
}
|
||||
|
||||
//static
|
||||
void LLVertexBuffer::setupClientArrays(U32 data_mask)
|
||||
@@ -473,8 +551,21 @@ void LLVertexBuffer::drawArrays(U32 mode, const std::vector<LLVector3>& pos, con
|
||||
gGL.syncMatrices();
|
||||
|
||||
U32 count = pos.size();
|
||||
llassert_always(norm.size() >= pos.size());
|
||||
llassert_always(count > 0);
|
||||
|
||||
llassert(norm.size() >= pos.size());
|
||||
llassert(count > 0);
|
||||
|
||||
if( count == 0 )
|
||||
{
|
||||
llwarns << "Called drawArrays with 0 vertices" << llendl;
|
||||
return;
|
||||
}
|
||||
|
||||
if( norm.size() < pos.size() )
|
||||
{
|
||||
llwarns << "Called drawArrays with #" << norm.size() << " normals and #" << pos.size() << " vertices" << llendl;
|
||||
return;
|
||||
}
|
||||
|
||||
unbind();
|
||||
|
||||
@@ -690,6 +781,7 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
|
||||
placeFence();
|
||||
}
|
||||
|
||||
static LLFastTimer::DeclareTimer FTM_GL_DRAW_ARRAYS("GL draw arrays");
|
||||
void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
|
||||
{
|
||||
llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL);
|
||||
@@ -724,8 +816,11 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
|
||||
return;
|
||||
}
|
||||
|
||||
stop_glerror();
|
||||
glDrawArrays(sGLMode[mode], first, count);
|
||||
{
|
||||
LLFastTimer t2(FTM_GL_DRAW_ARRAYS);
|
||||
stop_glerror();
|
||||
glDrawArrays(sGLMode[mode], first, count);
|
||||
}
|
||||
stop_glerror();
|
||||
placeFence();
|
||||
}
|
||||
@@ -920,7 +1015,7 @@ LLVertexBuffer::~LLVertexBuffer()
|
||||
if (mGLArray)
|
||||
{
|
||||
#if GL_ARB_vertex_array_object
|
||||
glDeleteVertexArrays(1, &mGLArray);
|
||||
releaseVAOName(mGLArray);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1193,7 +1288,7 @@ void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)
|
||||
if (gGLManager.mHasVertexArrayObject && useVBOs() && (LLRender::sGLCoreProfile || sUseVAO))
|
||||
{
|
||||
#if GL_ARB_vertex_array_object
|
||||
glGenVertexArrays(1, &mGLArray);
|
||||
mGLArray = getVAOName();
|
||||
#endif
|
||||
setupVertexArray();
|
||||
}
|
||||
|
||||
@@ -56,24 +56,29 @@ class LLVBOPool
|
||||
public:
|
||||
static U32 sBytesPooled;
|
||||
static U32 sIndexBytesPooled;
|
||||
|
||||
static U32 sCurGLName;
|
||||
|
||||
LLVBOPool(U32 vboUsage, U32 vboType)
|
||||
: mUsage(vboUsage)
|
||||
, mType(vboType)
|
||||
{}
|
||||
|
||||
LLVBOPool(U32 vboUsage, U32 vboType);
|
||||
|
||||
const U32 mUsage;
|
||||
const U32 mType;
|
||||
|
||||
//size MUST be a power of 2
|
||||
volatile U8* allocate(U32& name, U32 size);
|
||||
volatile U8* allocate(U32& name, U32 size, bool for_seed = false);
|
||||
|
||||
//size MUST be the size provided to allocate that returned the given name
|
||||
void release(U32 name, volatile U8* buffer, U32 size);
|
||||
|
||||
//batch allocate buffers to be provided to the application on demand
|
||||
void seedPool();
|
||||
|
||||
//destroy all records in mFreeList
|
||||
void cleanup();
|
||||
|
||||
U32 genBuffer();
|
||||
void deleteBuffer(U32 name);
|
||||
|
||||
class Record
|
||||
{
|
||||
public:
|
||||
@@ -81,8 +86,12 @@ public:
|
||||
volatile U8* mClientData;
|
||||
};
|
||||
|
||||
std::list<U32> mGLNamePool;
|
||||
|
||||
typedef std::list<Record> record_list_t;
|
||||
std::vector<record_list_t> mFreeList;
|
||||
std::vector<U32> mMissCount;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -119,10 +128,18 @@ public:
|
||||
static LLVBOPool sStreamIBOPool;
|
||||
static LLVBOPool sDynamicIBOPool;
|
||||
|
||||
static std::list<U32> sAvailableVAOName;
|
||||
static U32 sCurVAOName;
|
||||
|
||||
static bool sUseStreamDraw;
|
||||
static bool sUseVAO;
|
||||
static bool sPreferStreamDraw;
|
||||
|
||||
static void seedPools();
|
||||
|
||||
static U32 getVAOName();
|
||||
static void releaseVAOName(U32 name);
|
||||
|
||||
static void initClass(bool use_vbo, bool no_vbo_mapping);
|
||||
static void cleanupClass();
|
||||
static void setupClientArrays(U32 data_mask);
|
||||
|
||||
@@ -29,9 +29,11 @@ set(llui_SOURCE_FILES
|
||||
llcheckboxctrl.cpp
|
||||
llclipboard.cpp
|
||||
llcombobox.cpp
|
||||
llcontainerview.cpp
|
||||
llctrlselectioninterface.cpp
|
||||
lldraghandle.cpp
|
||||
lleditmenuhandler.cpp
|
||||
llfiltereditor.cpp
|
||||
llfloater.cpp
|
||||
llfocusmgr.cpp
|
||||
llfunctorregistry.cpp
|
||||
@@ -57,9 +59,13 @@ set(llui_SOURCE_FILES
|
||||
llscrollcontainer.cpp
|
||||
llscrollingpanellist.cpp
|
||||
llscrolllistctrl.cpp
|
||||
llsearcheditor.cpp
|
||||
llslider.cpp
|
||||
llsliderctrl.cpp
|
||||
llspinctrl.cpp
|
||||
llstatbar.cpp
|
||||
llstatgraph.cpp
|
||||
llstatview.cpp
|
||||
llstyle.cpp
|
||||
lltabcontainer.cpp
|
||||
lltextbox.cpp
|
||||
@@ -88,9 +94,11 @@ set(llui_HEADER_FILES
|
||||
llcheckboxctrl.h
|
||||
llclipboard.h
|
||||
llcombobox.h
|
||||
llcontainerview.h
|
||||
llctrlselectioninterface.h
|
||||
lldraghandle.h
|
||||
lleditmenuhandler.h
|
||||
llfiltereditor.h
|
||||
llfloater.h
|
||||
llfocusmgr.h
|
||||
llfunctorregistry.h
|
||||
@@ -116,6 +124,7 @@ set(llui_HEADER_FILES
|
||||
llresizehandle.h
|
||||
llresmgr.h
|
||||
llrootview.h
|
||||
llsearcheditor.h
|
||||
llscrollbar.h
|
||||
llscrollcontainer.h
|
||||
llscrollingpanellist.h
|
||||
@@ -123,6 +132,9 @@ set(llui_HEADER_FILES
|
||||
llslider.h
|
||||
llsliderctrl.h
|
||||
llspinctrl.h
|
||||
llstatbar.h
|
||||
llstatgraph.h
|
||||
llstatview.h
|
||||
llstyle.h
|
||||
lltabcontainer.h
|
||||
lltextbox.h
|
||||
|
||||
@@ -251,7 +251,7 @@ LLAlertDialog::LLAlertDialog( LLNotificationPtr notification, bool modal)
|
||||
LLButton* btn = new LLButton(
|
||||
button_data.mName, button_rect,
|
||||
"","", "",
|
||||
NULL, NULL,
|
||||
NULL,
|
||||
font,
|
||||
button_data.mText,
|
||||
button_data.mText);
|
||||
@@ -369,8 +369,7 @@ bool LLAlertDialog::setCheckBox( const std::string& check_title, const std::stri
|
||||
check_rect.setOriginAndSize(msg_x, VPAD+BTN_HEIGHT+LINE_HEIGHT/2,
|
||||
max_msg_width, LINE_HEIGHT);
|
||||
|
||||
mCheck = new LLCheckboxCtrl(std::string("check"), check_rect, check_title, font);
|
||||
mCheck->setCommitCallback(boost::bind(&LLAlertDialog::onClickIgnore, this, _1));
|
||||
mCheck = new LLCheckboxCtrl(std::string("check"), check_rect, check_title, font, boost::bind(&LLAlertDialog::onClickIgnore, this, _1));
|
||||
addChild(mCheck);
|
||||
|
||||
return true;
|
||||
|
||||
@@ -61,8 +61,8 @@ S32 BTN_HEIGHT = 0;
|
||||
S32 BTN_GRID = 12;
|
||||
S32 BORDER_SIZE = 1;
|
||||
|
||||
LLButton::LLButton( const std::string& name, const LLRect& rect, const std::string& control_name, void (*click_callback)(void*), void *callback_data)
|
||||
: LLUICtrl(name, rect, TRUE, NULL, NULL),
|
||||
LLButton::LLButton( const std::string& name, const LLRect& rect, const std::string& control_name, commit_callback_t commit_callback)
|
||||
: LLUICtrl(name, rect, TRUE, commit_callback),
|
||||
|
||||
mMouseDownFrame( 0 ),
|
||||
mMouseHeldDownCount(0),
|
||||
@@ -120,7 +120,7 @@ LLButton::LLButton( const std::string& name, const LLRect& rect, const std::stri
|
||||
mButtonFlashRate(LLUI::sConfigGroup->getF32("ButtonFlashRate")),
|
||||
mAlpha(1.f)
|
||||
{
|
||||
init(click_callback, callback_data, control_name);
|
||||
init(control_name);
|
||||
}
|
||||
|
||||
|
||||
@@ -128,12 +128,11 @@ LLButton::LLButton(const std::string& name, const LLRect& rect,
|
||||
const std::string &unselected_image_name,
|
||||
const std::string &selected_image_name,
|
||||
const std::string& control_name,
|
||||
void (*click_callback)(void*),
|
||||
void *callback_data,
|
||||
commit_callback_t commit_callback,
|
||||
const LLFontGL *font,
|
||||
const std::string& unselected_label,
|
||||
const std::string& selected_label )
|
||||
: LLUICtrl(name, rect, TRUE, NULL, NULL),
|
||||
: LLUICtrl(name, rect, TRUE, commit_callback),
|
||||
mMouseDownFrame( 0 ),
|
||||
mMouseHeldDownCount(0),
|
||||
mBorderEnabled( FALSE ),
|
||||
@@ -215,10 +214,10 @@ LLButton::LLButton(const std::string& name, const LLRect& rect,
|
||||
mImagePressed = mImageSelected;
|
||||
}
|
||||
|
||||
init(click_callback, callback_data, control_name);
|
||||
init(control_name);
|
||||
}
|
||||
|
||||
void LLButton::init(void (*click_callback)(void*), void *callback_data, const std::string& control_name)
|
||||
void LLButton::init(const std::string& control_name)
|
||||
{
|
||||
// Hack to make sure there is space for at least one character
|
||||
if (getRect().getWidth() - (mRightHPad + mLeftHPad) < mGLFont->getWidth(std::string(" ")))
|
||||
@@ -230,11 +229,7 @@ void LLButton::init(void (*click_callback)(void*), void *callback_data, const st
|
||||
|
||||
mMouseDownTimer.stop();
|
||||
|
||||
if(click_callback)
|
||||
setClickedCallback(click_callback, callback_data);
|
||||
|
||||
setControlName(control_name, NULL);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1219,7 +1214,6 @@ LLView* LLButton::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *fa
|
||||
image_selected,
|
||||
LLStringUtil::null,
|
||||
NULL,
|
||||
parent,
|
||||
font,
|
||||
label,
|
||||
label_selected);
|
||||
|
||||
@@ -75,15 +75,14 @@ class LLButton
|
||||
{
|
||||
public:
|
||||
// simple button with text label
|
||||
LLButton(const std::string& name, const LLRect &rect, const std::string& control_name = std::string(),
|
||||
void (*on_click)(void*) = NULL, void *data = NULL);
|
||||
LLButton(const std::string& name, const LLRect &rect = LLRect(), const std::string& control_name = std::string(),
|
||||
commit_callback_t commit_callback = NULL);
|
||||
|
||||
LLButton(const std::string& name, const LLRect& rect,
|
||||
const std::string &unselected_image,
|
||||
const std::string &selected_image,
|
||||
const std::string& control_name,
|
||||
void (*click_callback)(void*),
|
||||
void *callback_data = NULL,
|
||||
commit_callback_t commit_callback,
|
||||
const LLFontGL* mGLFont = NULL,
|
||||
const std::string& unselected_label = LLStringUtil::null,
|
||||
const std::string& selected_label = LLStringUtil::null );
|
||||
@@ -94,7 +93,7 @@ public:
|
||||
typedef boost::function<void(void*)> button_callback_t;
|
||||
|
||||
void addImageAttributeToXML(LLXMLNodePtr node, const LLPointer<LLUIImage>, const std::string& xmlTagName) const;
|
||||
void init(void (*click_callback)(void*), void *callback_data, const std::string& control_name);
|
||||
void init(const std::string& control_name);
|
||||
virtual LLXMLNodePtr getXML(bool save_children = true) const;
|
||||
static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
|
||||
|
||||
|
||||
@@ -30,24 +30,25 @@
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_CALLBACK_MAP_H
|
||||
#define LL_CALLBACK_MAP_H
|
||||
#ifndef LLCALLBACKMAP_H
|
||||
#define LLCALLBACKMAP_H
|
||||
|
||||
#include <map>
|
||||
#include "llstring.h"
|
||||
#include <string>
|
||||
#include <boost/function.hpp>
|
||||
|
||||
class LLCallbackMap
|
||||
{
|
||||
public:
|
||||
// callback definition.
|
||||
typedef void* (*callback_t)(void* data);
|
||||
typedef boost::function<void* (void* data)> callback_t;
|
||||
|
||||
typedef std::map<std::string, LLCallbackMap> map_t;
|
||||
typedef map_t::iterator map_iter_t;
|
||||
typedef map_t::const_iterator map_const_iter_t;
|
||||
|
||||
LLCallbackMap() : mCallback(NULL), mData(NULL) { }
|
||||
LLCallbackMap(callback_t callback, void* data) : mCallback(callback), mData(data) { }
|
||||
LLCallbackMap(callback_t callback, void* data = NULL) : mCallback(callback), mData(data) { }
|
||||
|
||||
callback_t mCallback;
|
||||
void* mData;
|
||||
|
||||
@@ -55,12 +55,11 @@ static LLRegisterWidget<LLCheckBoxCtrl> r("check_box");
|
||||
LLCheckBoxCtrl::LLCheckBoxCtrl(const std::string& name, const LLRect& rect,
|
||||
const std::string& label,
|
||||
const LLFontGL* font,
|
||||
void (*commit_callback)(LLUICtrl* ctrl, void* userdata),
|
||||
void* callback_user_data,
|
||||
commit_callback_t commit_callback,
|
||||
BOOL initial_value,
|
||||
BOOL use_radio_style,
|
||||
const std::string& control_which)
|
||||
: LLUICtrl(name, rect, TRUE, commit_callback, callback_user_data, FOLLOWS_LEFT | FOLLOWS_TOP),
|
||||
: LLUICtrl(name, rect, TRUE, commit_callback, FOLLOWS_LEFT | FOLLOWS_TOP),
|
||||
mTextEnabledColor( LLUI::sColorsGroup->getColor( "LabelTextColor" ) ),
|
||||
mTextDisabledColor( LLUI::sColorsGroup->getColor( "LabelDisabledColor" ) ),
|
||||
mRadioStyle( use_radio_style ),
|
||||
@@ -122,7 +121,7 @@ LLCheckBoxCtrl::LLCheckBoxCtrl(const std::string& name, const LLRect& rect,
|
||||
|
||||
mButton = new LLButton( button_name, btn_rect,
|
||||
active_false_id, active_true_id, control_which,
|
||||
&LLCheckBoxCtrl::onButtonPress, this, LLFontGL::getFontSansSerif() );
|
||||
boost::bind(&LLCheckBoxCtrl::onButtonPress, this, _2), LLFontGL::getFontSansSerif() );
|
||||
|
||||
mButton->setImageDisabledSelected(LLUI::getUIImage(inactive_true_id));
|
||||
mButton->setImageDisabled(LLUI::getUIImage(inactive_false_id));
|
||||
@@ -144,10 +143,14 @@ LLCheckBoxCtrl::~LLCheckBoxCtrl()
|
||||
|
||||
|
||||
// static
|
||||
void LLCheckBoxCtrl::onButtonPress( void *userdata )
|
||||
void LLCheckBoxCtrl::onButtonPress( const LLSD& data )
|
||||
{
|
||||
LLCheckBoxCtrl* self = (LLCheckBoxCtrl*)userdata;
|
||||
self->onCommit();
|
||||
//if (mRadioStyle)
|
||||
//{
|
||||
// setValue(TRUE);
|
||||
//}
|
||||
|
||||
onCommit();
|
||||
}
|
||||
|
||||
void LLCheckBoxCtrl::onCommit()
|
||||
@@ -315,8 +318,6 @@ LLView* LLCheckBoxCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFacto
|
||||
BOOL radio_style = FALSE;
|
||||
node->getAttributeBOOL("radio_style", radio_style);
|
||||
|
||||
LLUICtrlCallback callback = NULL;
|
||||
|
||||
if (label.empty())
|
||||
{
|
||||
label.assign(node->getTextContents());
|
||||
@@ -329,7 +330,6 @@ LLView* LLCheckBoxCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFacto
|
||||
rect,
|
||||
label,
|
||||
font,
|
||||
callback,
|
||||
NULL,
|
||||
FALSE,
|
||||
radio_style); // if true, draw radio button style icons
|
||||
|
||||
@@ -68,8 +68,7 @@ class LLCheckBoxCtrl
|
||||
public:
|
||||
LLCheckBoxCtrl(const std::string& name, const LLRect& rect, const std::string& label,
|
||||
const LLFontGL* font = NULL,
|
||||
void (*commit_callback)(LLUICtrl*, void*) = NULL,
|
||||
void* callback_userdata = NULL,
|
||||
commit_callback_t commit_callback = NULL,
|
||||
BOOL initial_value = FALSE,
|
||||
BOOL use_radio_style = FALSE, // if true, draw radio button style icons
|
||||
const std::string& control_which = LLStringUtil::null);
|
||||
@@ -113,7 +112,7 @@ public:
|
||||
virtual void setControlName(const std::string& control_name, LLView* context);
|
||||
virtual std::string getControlName() const;
|
||||
|
||||
static void onButtonPress(void *userdata);
|
||||
void onButtonPress(const LLSD& data);
|
||||
|
||||
virtual BOOL isDirty() const; // Returns TRUE if the user has modified this control.
|
||||
virtual void resetDirty(); // Clear dirty state
|
||||
|
||||
@@ -61,11 +61,8 @@ S32 MAX_COMBO_WIDTH = 500;
|
||||
static LLRegisterWidget<LLComboBox> r1("combo_box");
|
||||
|
||||
LLComboBox::LLComboBox( const std::string& name, const LLRect &rect, const std::string& label,
|
||||
void (*commit_callback)(LLUICtrl*,void*),
|
||||
void *callback_userdata
|
||||
)
|
||||
: LLUICtrl(name, rect, TRUE, commit_callback, callback_userdata,
|
||||
FOLLOWS_LEFT | FOLLOWS_TOP),
|
||||
commit_callback_t commit_callback)
|
||||
: LLUICtrl(name, rect, TRUE, commit_callback, FOLLOWS_LEFT | FOLLOWS_TOP),
|
||||
mTextEntry(NULL),
|
||||
mArrowImage(NULL),
|
||||
mAllowTextEntry(FALSE),
|
||||
@@ -83,15 +80,14 @@ LLComboBox::LLComboBox( const std::string& name, const LLRect &rect, const std::
|
||||
// Text label button
|
||||
mButton = new LLButton(mLabel,
|
||||
LLRect(),
|
||||
LLStringUtil::null,
|
||||
NULL, this);
|
||||
LLStringUtil::null);
|
||||
mButton->setImageUnselected(LLUI::getUIImage("square_btn_32x128.tga"));
|
||||
mButton->setImageSelected(LLUI::getUIImage("square_btn_selected_32x128.tga"));
|
||||
mButton->setImageDisabled(LLUI::getUIImage("square_btn_32x128.tga"));
|
||||
mButton->setImageDisabledSelected(LLUI::getUIImage("square_btn_selected_32x128.tga"));
|
||||
mButton->setScaleImage(TRUE);
|
||||
|
||||
mButton->setMouseDownCallback(boost::bind(&LLComboBox::onButtonDown,this));
|
||||
mButton->setMouseDownCallback(boost::bind(&LLComboBox::onButtonMouseDown,this));
|
||||
mButton->setFont(LLFontGL::getFontSansSerifSmall());
|
||||
mButton->setFollows(FOLLOWS_LEFT | FOLLOWS_BOTTOM | FOLLOWS_RIGHT);
|
||||
mButton->setHAlign( LLFontGL::LEFT );
|
||||
@@ -100,7 +96,7 @@ LLComboBox::LLComboBox( const std::string& name, const LLRect &rect, const std::
|
||||
|
||||
// disallow multiple selection
|
||||
mList = new LLScrollListCtrl(std::string("ComboBox"), LLRect(),
|
||||
&LLComboBox::onItemSelected, this, FALSE);
|
||||
boost::bind(&LLComboBox::onItemSelected, this), FALSE);
|
||||
mList->setVisible(FALSE);
|
||||
mList->setBgWriteableColor(mListColor);
|
||||
mList->setCommitOnKeyboardMovement(FALSE);
|
||||
@@ -168,13 +164,9 @@ LLView* LLComboBox::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *
|
||||
S32 max_chars = 20;
|
||||
node->getAttributeS32("max_chars", max_chars);
|
||||
|
||||
LLUICtrlCallback callback = NULL;
|
||||
|
||||
LLComboBox* combo_box = new LLComboBox(name,
|
||||
rect,
|
||||
label,
|
||||
callback,
|
||||
NULL);
|
||||
label);
|
||||
combo_box->setAllowTextEntry(allow_text_entry, max_chars);
|
||||
|
||||
const std::string& contents = node->getValue();
|
||||
@@ -550,10 +542,8 @@ void LLComboBox::updateLayout()
|
||||
LLStringUtil::null,
|
||||
LLFontGL::getFontSansSerifSmall(),
|
||||
mMaxChars,
|
||||
onTextCommit,
|
||||
onTextEntry,
|
||||
NULL,
|
||||
this);
|
||||
boost::bind(&LLComboBox::onTextCommit, this, _2),
|
||||
boost::bind(&LLComboBox::onTextEntry, this, _1));
|
||||
mTextEntry->setSelectAllonFocusReceived(TRUE);
|
||||
mTextEntry->setHandleEditKeysDirectly(TRUE);
|
||||
mTextEntry->setCommitOnFocusLost(FALSE);
|
||||
@@ -720,31 +710,27 @@ void LLComboBox::hideList()
|
||||
// static functions
|
||||
//------------------------------------------------------------------
|
||||
|
||||
// static
|
||||
void LLComboBox::onButtonDown(void *userdata)
|
||||
void LLComboBox::onButtonMouseDown()
|
||||
{
|
||||
LLComboBox *self = (LLComboBox *)userdata;
|
||||
|
||||
if (!self->mList->getVisible())
|
||||
if (!mList->getVisible())
|
||||
{
|
||||
LLScrollListItem* last_selected_item = self->mList->getLastSelectedItem();
|
||||
// this might change selection, so do it first
|
||||
prearrangeList();
|
||||
|
||||
// highlight the last selected item from the original selection before potentially selecting a new item
|
||||
// as visual cue to original value of combo box
|
||||
LLScrollListItem* last_selected_item = mList->getLastSelectedItem();
|
||||
if (last_selected_item)
|
||||
{
|
||||
// highlight the original selection before potentially selecting a new item
|
||||
self->mList->mouseOverHighlightNthItem(self->mList->getItemIndex(last_selected_item));
|
||||
mList->mouseOverHighlightNthItem(mList->getItemIndex(last_selected_item));
|
||||
}
|
||||
|
||||
if( self->mPrearrangeCallback )
|
||||
if (mList->getItemCount() != 0)
|
||||
{
|
||||
self->mPrearrangeCallback( self, self->mCallbackUserData );
|
||||
showList();
|
||||
}
|
||||
|
||||
if (self->mList->getItemCount() != 0)
|
||||
{
|
||||
self->showList();
|
||||
}
|
||||
|
||||
self->setFocus( TRUE );
|
||||
setFocus( TRUE );
|
||||
|
||||
// pass mouse capture on to list if button is depressed
|
||||
/*if (self->mButton->hasMouseCapture())
|
||||
@@ -754,36 +740,33 @@ void LLComboBox::onButtonDown(void *userdata)
|
||||
}
|
||||
else
|
||||
{
|
||||
self->hideList();
|
||||
hideList();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// static
|
||||
void LLComboBox::onItemSelected(LLUICtrl* item, void *userdata)
|
||||
void LLComboBox::onItemSelected()
|
||||
{
|
||||
// Note: item is the LLScrollListCtrl
|
||||
LLComboBox *self = (LLComboBox *) userdata;
|
||||
const std::string name = mList->getSelectedItemLabel();
|
||||
|
||||
const std::string name = self->mList->getSelectedItemLabel();
|
||||
|
||||
S32 cur_id = self->getCurrentIndex();
|
||||
S32 cur_id = getCurrentIndex();
|
||||
if (cur_id != -1)
|
||||
{
|
||||
self->setLabel(name);
|
||||
setLabel(name);
|
||||
|
||||
if (self->mAllowTextEntry)
|
||||
if (mAllowTextEntry)
|
||||
{
|
||||
gFocusMgr.setKeyboardFocus(self->mTextEntry);
|
||||
self->mTextEntry->selectAll();
|
||||
gFocusMgr.setKeyboardFocus(mTextEntry);
|
||||
mTextEntry->selectAll();
|
||||
}
|
||||
}
|
||||
|
||||
// hiding the list reasserts the old value stored in the text editor/dropdown button
|
||||
self->hideList();
|
||||
hideList();
|
||||
|
||||
// commit does the reverse, asserting the value in the list
|
||||
self->onCommit();
|
||||
onCommit();
|
||||
}
|
||||
|
||||
BOOL LLComboBox::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect_screen)
|
||||
@@ -908,28 +891,26 @@ const std::string LLComboBox::getTextEntry() const
|
||||
return mTextEntry->getText();
|
||||
}
|
||||
|
||||
//static
|
||||
void LLComboBox::onTextEntry(LLLineEditor* line_editor, void* user_data)
|
||||
void LLComboBox::onTextEntry(LLLineEditor* line_editor)
|
||||
{
|
||||
LLComboBox* self = (LLComboBox*)user_data;
|
||||
|
||||
if (self->mTextEntryCallback)
|
||||
if (mTextEntryCallback != NULL)
|
||||
{
|
||||
(*self->mTextEntryCallback)(line_editor, self->mCallbackUserData);
|
||||
(mTextEntryCallback)(line_editor, LLSD());
|
||||
}
|
||||
|
||||
KEY key = gKeyboard->currentKey();
|
||||
if (key == KEY_BACKSPACE ||
|
||||
key == KEY_DELETE)
|
||||
{
|
||||
if (self->mList->selectItemByLabel(line_editor->getText(), FALSE))
|
||||
if (mList->selectItemByLabel(line_editor->getText(), FALSE))
|
||||
{
|
||||
line_editor->setTentative(FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!self->mSuppressTentative) line_editor->setTentative(self->mTextEntryTentative);
|
||||
self->mList->deselectAllItems();
|
||||
if (!mSuppressTentative)
|
||||
line_editor->setTentative(mTextEntryTentative);
|
||||
mList->deselectAllItems();
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -942,17 +923,14 @@ void LLComboBox::onTextEntry(LLLineEditor* line_editor, void* user_data)
|
||||
|
||||
if (key == KEY_DOWN)
|
||||
{
|
||||
self->setCurrentByIndex(llmin(self->getItemCount() - 1, self->getCurrentIndex() + 1));
|
||||
if (!self->mList->getVisible())
|
||||
setCurrentByIndex(llmin(getItemCount() - 1, getCurrentIndex() + 1));
|
||||
if (!mList->getVisible())
|
||||
{
|
||||
if( self->mPrearrangeCallback )
|
||||
{
|
||||
self->mPrearrangeCallback( self, self->mCallbackUserData );
|
||||
}
|
||||
prearrangeList();
|
||||
|
||||
if (self->mList->getItemCount() != 0)
|
||||
if (mList->getItemCount() != 0)
|
||||
{
|
||||
self->showList();
|
||||
showList();
|
||||
}
|
||||
}
|
||||
line_editor->selectAll();
|
||||
@@ -960,17 +938,14 @@ void LLComboBox::onTextEntry(LLLineEditor* line_editor, void* user_data)
|
||||
}
|
||||
else if (key == KEY_UP)
|
||||
{
|
||||
self->setCurrentByIndex(llmax(0, self->getCurrentIndex() - 1));
|
||||
if (!self->mList->getVisible())
|
||||
setCurrentByIndex(llmax(0, getCurrentIndex() - 1));
|
||||
if (!mList->getVisible())
|
||||
{
|
||||
if( self->mPrearrangeCallback )
|
||||
{
|
||||
self->mPrearrangeCallback( self, self->mCallbackUserData );
|
||||
}
|
||||
prearrangeList();
|
||||
|
||||
if (self->mList->getItemCount() != 0)
|
||||
if (mList->getItemCount() != 0)
|
||||
{
|
||||
self->showList();
|
||||
showList();
|
||||
}
|
||||
}
|
||||
line_editor->selectAll();
|
||||
@@ -979,7 +954,7 @@ void LLComboBox::onTextEntry(LLLineEditor* line_editor, void* user_data)
|
||||
else
|
||||
{
|
||||
// RN: presumably text entry
|
||||
self->updateSelection();
|
||||
updateSelection();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1000,10 +975,7 @@ void LLComboBox::updateSelection()
|
||||
// callback to populate content
|
||||
if( mTextEntry->getWText().size() == 1 )
|
||||
{
|
||||
if (mPrearrangeCallback)
|
||||
{
|
||||
mPrearrangeCallback( this, mCallbackUserData );
|
||||
}
|
||||
prearrangeList(mTextEntry->getText());
|
||||
}
|
||||
|
||||
if (mList->selectItemByLabel(full_string, FALSE))
|
||||
@@ -1027,14 +999,12 @@ void LLComboBox::updateSelection()
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
void LLComboBox::onTextCommit(LLUICtrl* caller, void* user_data)
|
||||
void LLComboBox::onTextCommit(const LLSD& data)
|
||||
{
|
||||
LLComboBox* self = (LLComboBox*)user_data;
|
||||
std::string text = self->mTextEntry->getText();
|
||||
self->setSimple(text);
|
||||
self->onCommit();
|
||||
self->mTextEntry->selectAll();
|
||||
std::string text = mTextEntry->getText();
|
||||
setSimple(text);
|
||||
onCommit();
|
||||
mTextEntry->selectAll();
|
||||
}
|
||||
|
||||
void LLComboBox::setSuppressTentative(bool suppress)
|
||||
@@ -1081,6 +1051,14 @@ void LLComboBox::setPrevalidate( BOOL (*func)(const LLWString &) )
|
||||
if (mTextEntry) mTextEntry->setPrevalidate(func);
|
||||
}
|
||||
|
||||
void LLComboBox::prearrangeList(std::string filter)
|
||||
{
|
||||
if (mPrearrangeCallback)
|
||||
{
|
||||
mPrearrangeCallback(this, LLSD(filter));
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
// LLCtrlListInterface functions
|
||||
|
||||
@@ -1201,20 +1179,16 @@ const S32 FLYOUT_BUTTON_ARROW_WIDTH = 24;
|
||||
LLFlyoutButton::LLFlyoutButton(
|
||||
const std::string& name,
|
||||
const LLRect &rect,
|
||||
const std::string& label,
|
||||
void (*commit_callback)(LLUICtrl*, void*) ,
|
||||
void *callback_userdata)
|
||||
: LLComboBox(name, rect, LLStringUtil::null, commit_callback, callback_userdata),
|
||||
const std::string& label)
|
||||
: LLComboBox(name, rect, LLStringUtil::null),
|
||||
mToggleState(FALSE),
|
||||
mActionButton(NULL)
|
||||
{
|
||||
// Always use text box
|
||||
// Text label button
|
||||
mActionButton = new LLButton(label,
|
||||
LLRect(), LLStringUtil::null, NULL, this);
|
||||
LLRect(), LLStringUtil::null, boost::bind(&LLFlyoutButton::onActionButtonClick, this));
|
||||
mActionButton->setScaleImage(TRUE);
|
||||
|
||||
mActionButton->setClickedCallback(boost::bind(&LLFlyoutButton::onActionButtonClick, this));
|
||||
mActionButton->setFollowsAll();
|
||||
mActionButton->setHAlign( LLFontGL::HCENTER );
|
||||
mActionButton->setLabel(label);
|
||||
@@ -1280,13 +1254,9 @@ LLView* LLFlyoutButton::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFacto
|
||||
LLRect rect;
|
||||
createRect(node, rect, parent, LLRect());
|
||||
|
||||
LLUICtrlCallback callback = NULL;
|
||||
|
||||
LLFlyoutButton* flyout_button = new LLFlyoutButton(name,
|
||||
rect,
|
||||
label,
|
||||
callback,
|
||||
NULL);
|
||||
label);
|
||||
|
||||
std::string list_position;
|
||||
node->getAttributeString("list_position", list_position);
|
||||
@@ -1335,13 +1305,11 @@ void LLFlyoutButton::updateLayout()
|
||||
mActionButton->reshape(getRect().getWidth() - FLYOUT_BUTTON_ARROW_WIDTH, getRect().getHeight());
|
||||
}
|
||||
|
||||
//static
|
||||
void LLFlyoutButton::onActionButtonClick(void *user_data)
|
||||
void LLFlyoutButton::onActionButtonClick()
|
||||
{
|
||||
LLFlyoutButton* buttonp = (LLFlyoutButton*)user_data;
|
||||
// remember last list selection?
|
||||
buttonp->mList->deselect();
|
||||
buttonp->onCommit();
|
||||
mList->deselect();
|
||||
onCommit();
|
||||
}
|
||||
|
||||
void LLFlyoutButton::draw()
|
||||
|
||||
@@ -68,11 +68,13 @@ public:
|
||||
const std::string& name,
|
||||
const LLRect &rect,
|
||||
const std::string& label,
|
||||
void (*commit_callback)(LLUICtrl*, void*) = NULL,
|
||||
void *callback_userdata = NULL
|
||||
commit_callback_t commit_callback = NULL
|
||||
);
|
||||
virtual ~LLComboBox();
|
||||
protected:
|
||||
void prearrangeList(std::string filter = "");
|
||||
|
||||
public:
|
||||
// LLView interface
|
||||
|
||||
virtual LLXMLNodePtr getXML(bool save_children = true) const;
|
||||
@@ -176,15 +178,16 @@ public:
|
||||
|
||||
void* getCurrentUserdata();
|
||||
|
||||
void setPrearrangeCallback( void (*cb)(LLUICtrl*,void*) ) { mPrearrangeCallback = cb; }
|
||||
void setTextEntryCallback( void (*cb)(LLLineEditor*, void*) ) { mTextEntryCallback = cb; }
|
||||
void setPrearrangeCallback( commit_callback_t cb ) { mPrearrangeCallback = cb; }
|
||||
void setTextEntryCallback( commit_callback_t cb ) { mTextEntryCallback = cb; }
|
||||
|
||||
|
||||
void setButtonVisible(BOOL visible);
|
||||
|
||||
static void onButtonDown(void *userdata);
|
||||
static void onItemSelected(LLUICtrl* item, void *userdata);
|
||||
static void onTextEntry(LLLineEditor* line_editor, void* user_data);
|
||||
static void onTextCommit(LLUICtrl* caller, void* user_data);
|
||||
void onButtonMouseDown();
|
||||
void onItemSelected();
|
||||
|
||||
void onTextCommit(const LLSD& data);
|
||||
|
||||
void setSuppressTentative(bool suppress);
|
||||
void setSuppressAutoComplete(bool suppress);
|
||||
@@ -193,8 +196,11 @@ public:
|
||||
virtual void showList();
|
||||
virtual void hideList();
|
||||
|
||||
virtual void onTextEntry(LLLineEditor* line_editor);
|
||||
|
||||
protected:
|
||||
LLButton* mButton;
|
||||
LLLineEditor* mTextEntry;
|
||||
LLScrollListCtrl* mList;
|
||||
EPreferredPosition mListPosition;
|
||||
LLPointer<LLUIImage> mArrowImage;
|
||||
@@ -202,14 +208,14 @@ protected:
|
||||
LLColor4 mListColor;
|
||||
|
||||
private:
|
||||
LLLineEditor* mTextEntry;
|
||||
S32 mButtonPadding;
|
||||
BOOL mAllowTextEntry;
|
||||
S32 mMaxChars;
|
||||
BOOL mTextEntryTentative;
|
||||
bool mSuppressAutoComplete;
|
||||
bool mSuppressTentative;
|
||||
void (*mPrearrangeCallback)(LLUICtrl*,void*);
|
||||
void (*mTextEntryCallback)(LLLineEditor*, void*);
|
||||
commit_callback_t mPrearrangeCallback;
|
||||
commit_callback_t mTextEntryCallback;
|
||||
boost::signals2::connection mTopLostSignalConnection;
|
||||
};
|
||||
|
||||
@@ -219,9 +225,7 @@ public:
|
||||
LLFlyoutButton(
|
||||
const std::string& name,
|
||||
const LLRect &rect,
|
||||
const std::string& label,
|
||||
void (*commit_callback)(LLUICtrl*, void*) = NULL,
|
||||
void *callback_userdata = NULL);
|
||||
const std::string& label);
|
||||
|
||||
virtual void updateLayout();
|
||||
virtual void draw();
|
||||
@@ -231,8 +235,8 @@ public:
|
||||
|
||||
virtual LLXMLNodePtr getXML(bool save_children = true) const;
|
||||
static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
|
||||
static void onActionButtonClick(void *userdata);
|
||||
static void onSelectAction(LLUICtrl* ctrl, void *userdata);
|
||||
void onActionButtonClick();
|
||||
void onSelectAction(LLUICtrl* ctrl);
|
||||
|
||||
protected:
|
||||
LLButton* mActionButton;
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
#include "linden_common.h"
|
||||
|
||||
#include "llcontainerview.h"
|
||||
|
||||
@@ -41,13 +41,15 @@
|
||||
#include "llresmgr.h"
|
||||
#include "llstring.h"
|
||||
#include "llscrollcontainer.h"
|
||||
#include "lluictrlfactory.h"
|
||||
|
||||
LLContainerView::LLContainerView(const std::string& name, const LLRect& rect)
|
||||
: LLView(name, rect, FALSE)
|
||||
LLContainerView::LLContainerView(const LLContainerView::Params& p)
|
||||
: LLView(p),
|
||||
mShowLabel(p.show_label),
|
||||
mLabel(p.label),
|
||||
mDisplayChildren(p.display_children)
|
||||
{
|
||||
mShowLabel = TRUE;
|
||||
mCollapsible = TRUE;
|
||||
mDisplayChildren = TRUE;
|
||||
mScrollContainer = NULL;
|
||||
}
|
||||
|
||||
@@ -56,6 +58,13 @@ LLContainerView::~LLContainerView()
|
||||
// Children all cleaned up by default view destructor.
|
||||
}
|
||||
|
||||
BOOL LLContainerView::postBuild()
|
||||
{
|
||||
setDisplayChildren(mDisplayChildren);
|
||||
reshape(getRect().getWidth(), getRect().getHeight(), FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL LLContainerView::handleMouseDown(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
BOOL handled = FALSE;
|
||||
@@ -279,7 +288,7 @@ void LLContainerView::setDisplayChildren(const BOOL displayChildren)
|
||||
}
|
||||
}
|
||||
|
||||
void LLContainerView::setScrollContainer(LLScrollableContainerView* scroll)
|
||||
void LLContainerView::setScrollContainer(LLScrollContainer* scroll)
|
||||
{
|
||||
mScrollContainer = scroll;
|
||||
scroll->setPassBackToChildren(false);
|
||||
@@ -36,36 +36,56 @@
|
||||
#include "stdtypes.h"
|
||||
#include "lltextbox.h"
|
||||
#include "llstatbar.h"
|
||||
#include "llview.h"
|
||||
|
||||
class LLScrollableContainerView;
|
||||
class LLScrollContainer;
|
||||
|
||||
class LLContainerView : public LLView
|
||||
{
|
||||
public:
|
||||
struct Params : public LLInitParam::Block<Params, LLView::Params>
|
||||
{
|
||||
Optional<std::string> label;
|
||||
Optional<bool> show_label;
|
||||
Optional<bool> display_children;
|
||||
Params()
|
||||
: label("label"),
|
||||
show_label("show_label", FALSE),
|
||||
display_children("display_children", TRUE)
|
||||
{
|
||||
changeDefault(mouse_opaque, false);
|
||||
}
|
||||
};
|
||||
protected:
|
||||
BOOL mDisplayChildren;
|
||||
std::string mLabel;
|
||||
LLContainerView(const Params& p);
|
||||
friend class LLUICtrlFactory;
|
||||
public:
|
||||
BOOL mCollapsible;
|
||||
public:
|
||||
LLContainerView(const std::string& name, const LLRect& rect);
|
||||
~LLContainerView();
|
||||
|
||||
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
|
||||
virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
|
||||
/*virtual*/ BOOL postBuild();
|
||||
/*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
|
||||
/*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask);
|
||||
|
||||
virtual void draw();
|
||||
virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
|
||||
virtual LLRect getRequiredRect(); // Return the height of this object, given the set options.
|
||||
/*virtual*/ void draw();
|
||||
/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
|
||||
/*virtual*/ LLRect getRequiredRect(); // Return the height of this object, given the set options.
|
||||
|
||||
void setLabel(const std::string& label);
|
||||
void showLabel(BOOL show) { mShowLabel = show; }
|
||||
void setDisplayChildren(const BOOL displayChildren);
|
||||
BOOL getDisplayChildren() { return mDisplayChildren; }
|
||||
void setScrollContainer(LLScrollableContainerView* scroll);
|
||||
void setScrollContainer(LLScrollContainer* scroll);
|
||||
|
||||
private:
|
||||
LLScrollableContainerView* mScrollContainer;
|
||||
LLScrollContainer* mScrollContainer;
|
||||
void arrange(S32 width, S32 height, BOOL called_from_parent = TRUE);
|
||||
BOOL mShowLabel;
|
||||
|
||||
protected:
|
||||
BOOL mDisplayChildren;
|
||||
std::string mLabel;
|
||||
public:
|
||||
BOOL mCollapsible;
|
||||
|
||||
};
|
||||
#endif // LL_CONTAINERVIEW_
|
||||
81
indra/llui/llfiltereditor.cpp
Normal file
81
indra/llui/llfiltereditor.cpp
Normal file
@@ -0,0 +1,81 @@
|
||||
/**
|
||||
* @file llfiltereditor.cpp
|
||||
* @brief LLFilterEditor implementation
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&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$
|
||||
*/
|
||||
|
||||
// Text editor widget to let users enter a single line.
|
||||
|
||||
#include "linden_common.h"
|
||||
|
||||
#include "llfiltereditor.h"
|
||||
|
||||
static LLRegisterWidget<LLFilterEditor> r2("filter_editor");
|
||||
|
||||
LLFilterEditor::LLFilterEditor(const std::string& name,
|
||||
const LLRect& rect,
|
||||
S32 max_length_bytes)
|
||||
: LLSearchEditor(name,rect,max_length_bytes)
|
||||
{
|
||||
setCommitOnFocusLost(FALSE); // we'll commit on every keystroke, don't re-commit when we take focus away (i.e. we go to interact with the actual results!)
|
||||
}
|
||||
|
||||
|
||||
void LLFilterEditor::handleKeystroke()
|
||||
{
|
||||
this->LLSearchEditor::handleKeystroke();
|
||||
|
||||
// Commit on every keystroke.
|
||||
onCommit();
|
||||
}
|
||||
|
||||
// static
|
||||
LLView* LLFilterEditor::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
|
||||
{
|
||||
std::string name("filter_editor");
|
||||
node->getAttributeString("name", name);
|
||||
|
||||
LLRect rect;
|
||||
createRect(node, rect, parent, LLRect());
|
||||
|
||||
S32 max_text_length = 128;
|
||||
node->getAttributeS32("max_length", max_text_length);
|
||||
|
||||
std::string text = node->getValue().substr(0, max_text_length - 1);
|
||||
|
||||
LLFilterEditor* search_editor = new LLFilterEditor(name,
|
||||
rect,
|
||||
max_text_length);
|
||||
|
||||
std::string label;
|
||||
if(node->getAttributeString("label", label))
|
||||
{
|
||||
search_editor->setLabel(label);
|
||||
}
|
||||
|
||||
search_editor->setText(text);
|
||||
|
||||
search_editor->initFromXML(node, parent);
|
||||
|
||||
return search_editor;
|
||||
}
|
||||
54
indra/llui/llfiltereditor.h
Normal file
54
indra/llui/llfiltereditor.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* @file llfiltereditor.h
|
||||
* @brief Text editor widget that represents a filter operation
|
||||
*
|
||||
* Features:
|
||||
* Text entry of a single line (text, delete, left and right arrow, insert, return).
|
||||
* Callbacks either on every keystroke or just on the return key.
|
||||
* Focus (allow multiple text entry widgets)
|
||||
* Clipboard (cut, copy, and paste)
|
||||
* Horizontal scrolling to allow strings longer than widget size allows
|
||||
* Pre-validation (limit which keys can be used)
|
||||
* Optional line history so previous entries can be recalled by CTRL UP/DOWN
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&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_FILTEREDITOR_H
|
||||
#define LL_FILTEREDITOR_H
|
||||
|
||||
#include "llsearcheditor.h"
|
||||
|
||||
class LLFilterEditor : public LLSearchEditor
|
||||
{
|
||||
public:
|
||||
LLFilterEditor(const std::string& name,
|
||||
const LLRect& rect,
|
||||
S32 max_length_bytes);
|
||||
static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
|
||||
protected:
|
||||
friend class LLUICtrlFactory;
|
||||
|
||||
/*virtual*/ void handleKeystroke();
|
||||
};
|
||||
|
||||
#endif // LL_FILTEREDITOR_H
|
||||
@@ -113,13 +113,14 @@ std::string LLFloater::sButtonToolTips[BUTTON_COUNT] =
|
||||
"Edit", //BUTTON_EDIT
|
||||
};
|
||||
|
||||
LLFloater::click_callback LLFloater::sButtonCallbacks[BUTTON_COUNT] =
|
||||
|
||||
LLFloater::button_callback LLFloater::sButtonCallbacks[BUTTON_COUNT] =
|
||||
{
|
||||
LLFloater::onClickClose, //BUTTON_CLOSE
|
||||
LLFloater::onClickMinimize, //BUTTON_RESTORE
|
||||
LLFloater::onClickMinimize, //BUTTON_MINIMIZE
|
||||
LLFloater::onClickTearOff, //BUTTON_TEAR_OFF
|
||||
LLFloater::onClickEdit, //BUTTON_EDIT
|
||||
&LLFloater::onClickClose, //BUTTON_CLOSE
|
||||
&LLFloater::onClickMinimize, //BUTTON_RESTORE
|
||||
&LLFloater::onClickMinimize, //BUTTON_MINIMIZE
|
||||
&LLFloater::onClickTearOff, //BUTTON_TEAR_OFF
|
||||
&LLFloater::onClickEdit, //BUTTON_EDIT
|
||||
};
|
||||
|
||||
LLMultiFloater* LLFloater::sHostp = NULL;
|
||||
@@ -313,67 +314,7 @@ void LLFloater::initFloater(const std::string& title,
|
||||
|
||||
if( mResizable )
|
||||
{
|
||||
// Resize bars (sides)
|
||||
const S32 RESIZE_BAR_THICKNESS = 3;
|
||||
mResizeBar[LLResizeBar::LEFT] = new LLResizeBar(
|
||||
std::string("resizebar_left"),
|
||||
this,
|
||||
LLRect( 0, getRect().getHeight(), RESIZE_BAR_THICKNESS, 0),
|
||||
min_width, S32_MAX, LLResizeBar::LEFT );
|
||||
addChild( mResizeBar[0] );
|
||||
|
||||
mResizeBar[LLResizeBar::TOP] = new LLResizeBar(
|
||||
std::string("resizebar_top"),
|
||||
this,
|
||||
LLRect( 0, getRect().getHeight(), getRect().getWidth(), getRect().getHeight() - RESIZE_BAR_THICKNESS),
|
||||
min_height, S32_MAX, LLResizeBar::TOP );
|
||||
addChild( mResizeBar[1] );
|
||||
|
||||
mResizeBar[LLResizeBar::RIGHT] = new LLResizeBar(
|
||||
std::string("resizebar_right"),
|
||||
this,
|
||||
LLRect( getRect().getWidth() - RESIZE_BAR_THICKNESS, getRect().getHeight(), getRect().getWidth(), 0),
|
||||
min_width, S32_MAX, LLResizeBar::RIGHT );
|
||||
addChild( mResizeBar[2] );
|
||||
|
||||
mResizeBar[LLResizeBar::BOTTOM] = new LLResizeBar(
|
||||
std::string("resizebar_bottom"),
|
||||
this,
|
||||
LLRect( 0, RESIZE_BAR_THICKNESS, getRect().getWidth(), 0),
|
||||
min_height, S32_MAX, LLResizeBar::BOTTOM );
|
||||
addChild( mResizeBar[3] );
|
||||
|
||||
|
||||
// Resize handles (corners)
|
||||
mResizeHandle[0] = new LLResizeHandle(
|
||||
std::string("Resize Handle"),
|
||||
LLRect( getRect().getWidth() - RESIZE_HANDLE_WIDTH, RESIZE_HANDLE_HEIGHT, getRect().getWidth(), 0),
|
||||
min_width,
|
||||
min_height,
|
||||
LLResizeHandle::RIGHT_BOTTOM);
|
||||
addChild(mResizeHandle[0]);
|
||||
|
||||
mResizeHandle[1] = new LLResizeHandle(
|
||||
std::string("resize"),
|
||||
LLRect( getRect().getWidth() - RESIZE_HANDLE_WIDTH, getRect().getHeight(), getRect().getWidth(), getRect().getHeight() - RESIZE_HANDLE_HEIGHT),
|
||||
min_width,
|
||||
min_height,
|
||||
LLResizeHandle::RIGHT_TOP );
|
||||
addChild(mResizeHandle[1]);
|
||||
|
||||
mResizeHandle[2] = new LLResizeHandle( std::string("resize"),
|
||||
LLRect( 0, RESIZE_HANDLE_HEIGHT, RESIZE_HANDLE_WIDTH, 0 ),
|
||||
min_width,
|
||||
min_height,
|
||||
LLResizeHandle::LEFT_BOTTOM );
|
||||
addChild(mResizeHandle[2]);
|
||||
|
||||
mResizeHandle[3] = new LLResizeHandle( std::string("resize"),
|
||||
LLRect( 0, getRect().getHeight(), RESIZE_HANDLE_WIDTH, getRect().getHeight() - RESIZE_HANDLE_HEIGHT ),
|
||||
min_width,
|
||||
min_height,
|
||||
LLResizeHandle::LEFT_TOP );
|
||||
addChild(mResizeHandle[3]);
|
||||
addResizeCtrls();
|
||||
}
|
||||
|
||||
// Close button.
|
||||
@@ -413,6 +354,94 @@ void LLFloater::initFloater(const std::string& title,
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloater::addResizeCtrls()
|
||||
{
|
||||
// Resize bars (sides)
|
||||
LLResizeBar::Params p;
|
||||
p.name("resizebar_left");
|
||||
p.resizing_view(this);
|
||||
p.min_size(mMinWidth);
|
||||
p.side(LLResizeBar::LEFT);
|
||||
mResizeBar[LLResizeBar::LEFT] = LLUICtrlFactory::create<LLResizeBar>(p);
|
||||
addChild( mResizeBar[LLResizeBar::LEFT] );
|
||||
|
||||
p.name("resizebar_top");
|
||||
p.min_size(mMinHeight);
|
||||
p.side(LLResizeBar::TOP);
|
||||
|
||||
mResizeBar[LLResizeBar::TOP] = LLUICtrlFactory::create<LLResizeBar>(p);
|
||||
addChild( mResizeBar[LLResizeBar::TOP] );
|
||||
|
||||
p.name("resizebar_right");
|
||||
p.min_size(mMinWidth);
|
||||
p.side(LLResizeBar::RIGHT);
|
||||
mResizeBar[LLResizeBar::RIGHT] = LLUICtrlFactory::create<LLResizeBar>(p);
|
||||
addChild( mResizeBar[LLResizeBar::RIGHT] );
|
||||
|
||||
p.name("resizebar_bottom");
|
||||
p.min_size(mMinHeight);
|
||||
p.side(LLResizeBar::BOTTOM);
|
||||
mResizeBar[LLResizeBar::BOTTOM] = LLUICtrlFactory::create<LLResizeBar>(p);
|
||||
addChild( mResizeBar[LLResizeBar::BOTTOM] );
|
||||
|
||||
// Resize handles (corners)
|
||||
LLResizeHandle::Params handle_p;
|
||||
// handles must not be mouse-opaque, otherwise they block hover events
|
||||
// to other buttons like the close box. JC
|
||||
handle_p.mouse_opaque(false);
|
||||
handle_p.min_width(mMinWidth);
|
||||
handle_p.min_height(mMinHeight);
|
||||
handle_p.corner(LLResizeHandle::RIGHT_BOTTOM);
|
||||
mResizeHandle[0] = LLUICtrlFactory::create<LLResizeHandle>(handle_p);
|
||||
addChild(mResizeHandle[0]);
|
||||
|
||||
handle_p.corner(LLResizeHandle::RIGHT_TOP);
|
||||
mResizeHandle[1] = LLUICtrlFactory::create<LLResizeHandle>(handle_p);
|
||||
addChild(mResizeHandle[1]);
|
||||
|
||||
handle_p.corner(LLResizeHandle::LEFT_BOTTOM);
|
||||
mResizeHandle[2] = LLUICtrlFactory::create<LLResizeHandle>(handle_p);
|
||||
addChild(mResizeHandle[2]);
|
||||
|
||||
handle_p.corner(LLResizeHandle::LEFT_TOP);
|
||||
mResizeHandle[3] = LLUICtrlFactory::create<LLResizeHandle>(handle_p);
|
||||
addChild(mResizeHandle[3]);
|
||||
|
||||
layoutResizeCtrls();
|
||||
}
|
||||
|
||||
void LLFloater::layoutResizeCtrls()
|
||||
{
|
||||
LLRect rect;
|
||||
|
||||
// Resize bars (sides)
|
||||
const S32 RESIZE_BAR_THICKNESS = 3;
|
||||
rect = LLRect( 0, getRect().getHeight(), RESIZE_BAR_THICKNESS, 0);
|
||||
mResizeBar[LLResizeBar::LEFT]->setRect(rect);
|
||||
|
||||
rect = LLRect( 0, getRect().getHeight(), getRect().getWidth(), getRect().getHeight() - RESIZE_BAR_THICKNESS);
|
||||
mResizeBar[LLResizeBar::TOP]->setRect(rect);
|
||||
|
||||
rect = LLRect(getRect().getWidth() - RESIZE_BAR_THICKNESS, getRect().getHeight(), getRect().getWidth(), 0);
|
||||
mResizeBar[LLResizeBar::RIGHT]->setRect(rect);
|
||||
|
||||
rect = LLRect(0, RESIZE_BAR_THICKNESS, getRect().getWidth(), 0);
|
||||
mResizeBar[LLResizeBar::BOTTOM]->setRect(rect);
|
||||
|
||||
// Resize handles (corners)
|
||||
rect = LLRect( getRect().getWidth() - RESIZE_HANDLE_WIDTH, RESIZE_HANDLE_HEIGHT, getRect().getWidth(), 0);
|
||||
mResizeHandle[0]->setRect(rect);
|
||||
|
||||
rect = LLRect( getRect().getWidth() - RESIZE_HANDLE_WIDTH, getRect().getHeight(), getRect().getWidth(), getRect().getHeight() - RESIZE_HANDLE_HEIGHT);
|
||||
mResizeHandle[1]->setRect(rect);
|
||||
|
||||
rect = LLRect( 0, RESIZE_HANDLE_HEIGHT, RESIZE_HANDLE_WIDTH, 0 );
|
||||
mResizeHandle[2]->setRect(rect);
|
||||
|
||||
rect = LLRect( 0, getRect().getHeight(), RESIZE_HANDLE_WIDTH, getRect().getHeight() - RESIZE_HANDLE_HEIGHT );
|
||||
mResizeHandle[3]->setRect(rect);
|
||||
}
|
||||
|
||||
void LLFloater::enableResizeCtrls(bool enable, bool width, bool height)
|
||||
{
|
||||
mResizeBar[LLResizeBar::LEFT]->setVisible(enable && width);
|
||||
@@ -1286,60 +1315,49 @@ void LLFloater::setEditModeEnabled(BOOL enable)
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
void LLFloater::onClickMinimize(void *userdata)
|
||||
void LLFloater::onClickMinimize()
|
||||
{
|
||||
LLFloater* self = (LLFloater*) userdata;
|
||||
if (!self) return;
|
||||
|
||||
self->setMinimized( !self->isMinimized() );
|
||||
setMinimized( !isMinimized() );
|
||||
}
|
||||
|
||||
void LLFloater::onClickTearOff(void *userdata)
|
||||
void LLFloater::onClickTearOff()
|
||||
{
|
||||
LLFloater* self = (LLFloater*) userdata;
|
||||
if (!self) return;
|
||||
|
||||
LLMultiFloater* host_floater = self->getHost();
|
||||
LLMultiFloater* host_floater = getHost();
|
||||
if (host_floater) //Tear off
|
||||
{
|
||||
LLRect new_rect;
|
||||
host_floater->removeFloater(self);
|
||||
host_floater->removeFloater(this);
|
||||
// reparent to floater view
|
||||
gFloaterView->addChild(self);
|
||||
gFloaterView->addChild(this);
|
||||
|
||||
self->open(); /* Flawfinder: ignore */
|
||||
open(); /* Flawfinder: ignore */
|
||||
|
||||
// only force position for floaters that don't have that data saved
|
||||
if (self->getRectControl().empty())
|
||||
if (getRectControl().empty())
|
||||
{
|
||||
new_rect.setLeftTopAndSize(host_floater->getRect().mLeft + 5, host_floater->getRect().mTop - LLFLOATER_HEADER_SIZE - 5, self->getRect().getWidth(), self->getRect().getHeight());
|
||||
self->setRect(new_rect);
|
||||
new_rect.setLeftTopAndSize(host_floater->getRect().mLeft + 5, host_floater->getRect().mTop - LLFLOATER_HEADER_SIZE - 5, getRect().getWidth(), getRect().getHeight());
|
||||
setRect(new_rect);
|
||||
}
|
||||
gFloaterView->adjustToFitScreen(self, FALSE);
|
||||
gFloaterView->adjustToFitScreen(this, FALSE);
|
||||
// give focus to new window to keep continuity for the user
|
||||
self->setFocus(TRUE);
|
||||
setFocus(TRUE);
|
||||
}
|
||||
else //Attach to parent.
|
||||
{
|
||||
LLMultiFloater* new_host = (LLMultiFloater*)self->mLastHostHandle.get();
|
||||
LLMultiFloater* new_host = (LLMultiFloater*)mLastHostHandle.get();
|
||||
if (new_host)
|
||||
{
|
||||
self->setMinimized(FALSE); // to reenable minimize button if it was minimized
|
||||
new_host->showFloater(self);
|
||||
setMinimized(FALSE); // to reenable minimize button if it was minimized
|
||||
new_host->showFloater(this);
|
||||
// make sure host is visible
|
||||
new_host->open();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLFloater::onClickEdit(void *userdata)
|
||||
void LLFloater::onClickEdit()
|
||||
{
|
||||
LLFloater* self = (LLFloater*) userdata;
|
||||
if (!self) return;
|
||||
|
||||
self->mEditing = self->mEditing ? FALSE : TRUE;
|
||||
mEditing = mEditing ? FALSE : TRUE;
|
||||
}
|
||||
|
||||
// static
|
||||
@@ -1393,13 +1411,9 @@ void LLFloater::closeFocusedFloater()
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
void LLFloater::onClickClose( void* userdata )
|
||||
void LLFloater::onClickClose()
|
||||
{
|
||||
LLFloater* self = (LLFloater*) userdata;
|
||||
if (!self) return;
|
||||
|
||||
self->close();
|
||||
close();
|
||||
}
|
||||
|
||||
|
||||
@@ -1561,66 +1575,7 @@ void LLFloater::setCanResize(BOOL can_resize)
|
||||
}
|
||||
else if (!mResizable && can_resize)
|
||||
{
|
||||
// Resize bars (sides)
|
||||
const S32 RESIZE_BAR_THICKNESS = 3;
|
||||
mResizeBar[0] = new LLResizeBar(
|
||||
std::string("resizebar_left"),
|
||||
this,
|
||||
LLRect( 0, getRect().getHeight(), RESIZE_BAR_THICKNESS, 0),
|
||||
mMinWidth, S32_MAX, LLResizeBar::LEFT );
|
||||
addChild( mResizeBar[0] );
|
||||
|
||||
mResizeBar[1] = new LLResizeBar(
|
||||
std::string("resizebar_top"),
|
||||
this,
|
||||
LLRect( 0, getRect().getHeight(), getRect().getWidth(), getRect().getHeight() - RESIZE_BAR_THICKNESS),
|
||||
mMinHeight, S32_MAX, LLResizeBar::TOP );
|
||||
addChild( mResizeBar[1] );
|
||||
|
||||
mResizeBar[2] = new LLResizeBar(
|
||||
std::string("resizebar_right"),
|
||||
this,
|
||||
LLRect( getRect().getWidth() - RESIZE_BAR_THICKNESS, getRect().getHeight(), getRect().getWidth(), 0),
|
||||
mMinWidth, S32_MAX, LLResizeBar::RIGHT );
|
||||
addChild( mResizeBar[2] );
|
||||
|
||||
mResizeBar[3] = new LLResizeBar(
|
||||
std::string("resizebar_bottom"),
|
||||
this,
|
||||
LLRect( 0, RESIZE_BAR_THICKNESS, getRect().getWidth(), 0),
|
||||
mMinHeight, S32_MAX, LLResizeBar::BOTTOM );
|
||||
addChild( mResizeBar[3] );
|
||||
|
||||
|
||||
// Resize handles (corners)
|
||||
mResizeHandle[0] = new LLResizeHandle(
|
||||
std::string("Resize Handle"),
|
||||
LLRect( getRect().getWidth() - RESIZE_HANDLE_WIDTH, RESIZE_HANDLE_HEIGHT, getRect().getWidth(), 0),
|
||||
mMinWidth,
|
||||
mMinHeight,
|
||||
LLResizeHandle::RIGHT_BOTTOM);
|
||||
addChild(mResizeHandle[0]);
|
||||
|
||||
mResizeHandle[1] = new LLResizeHandle( std::string("resize"),
|
||||
LLRect( getRect().getWidth() - RESIZE_HANDLE_WIDTH, getRect().getHeight(), getRect().getWidth(), getRect().getHeight() - RESIZE_HANDLE_HEIGHT),
|
||||
mMinWidth,
|
||||
mMinHeight,
|
||||
LLResizeHandle::RIGHT_TOP );
|
||||
addChild(mResizeHandle[1]);
|
||||
|
||||
mResizeHandle[2] = new LLResizeHandle( std::string("resize"),
|
||||
LLRect( 0, RESIZE_HANDLE_HEIGHT, RESIZE_HANDLE_WIDTH, 0 ),
|
||||
mMinWidth,
|
||||
mMinHeight,
|
||||
LLResizeHandle::LEFT_BOTTOM );
|
||||
addChild(mResizeHandle[2]);
|
||||
|
||||
mResizeHandle[3] = new LLResizeHandle( std::string("resize"),
|
||||
LLRect( 0, getRect().getHeight(), RESIZE_HANDLE_WIDTH, getRect().getHeight() - RESIZE_HANDLE_HEIGHT ),
|
||||
mMinWidth,
|
||||
mMinHeight,
|
||||
LLResizeHandle::LEFT_TOP );
|
||||
addChild(mResizeHandle[3]);
|
||||
addResizeCtrls();
|
||||
enableResizeCtrls(can_resize);
|
||||
}
|
||||
mResizable = can_resize;
|
||||
@@ -1716,8 +1671,7 @@ void LLFloater::buildButtons()
|
||||
sButtonActiveImageNames[i],
|
||||
sButtonPressedImageNames[i],
|
||||
LLStringUtil::null,
|
||||
sButtonCallbacks[i],
|
||||
this,
|
||||
boost::bind(sButtonCallbacks[i],this),
|
||||
LLFontGL::getFontSansSerif());
|
||||
|
||||
buttonp->setTabStop(FALSE);
|
||||
@@ -1740,7 +1694,7 @@ void LLFloater::buildButtons()
|
||||
// LLFloaterView
|
||||
|
||||
LLFloaterView::LLFloaterView( const std::string& name, const LLRect& rect )
|
||||
: LLUICtrl( name, rect, FALSE, NULL, NULL, FOLLOWS_ALL ),
|
||||
: LLUICtrl( name, rect, FALSE, NULL, FOLLOWS_ALL ),
|
||||
mFocusCycleMode(FALSE),
|
||||
mSnapOffsetBottom(0)
|
||||
{
|
||||
|
||||
@@ -237,10 +237,10 @@ public:
|
||||
return LLNotification::Params(name).context(mNotificationContext);
|
||||
}
|
||||
|
||||
static void onClickClose(void *userdata);
|
||||
static void onClickMinimize(void *userdata);
|
||||
static void onClickTearOff(void *userdata);
|
||||
static void onClickEdit(void *userdata);
|
||||
void onClickClose();
|
||||
void onClickMinimize();
|
||||
void onClickTearOff();
|
||||
void onClickEdit();
|
||||
|
||||
static void setFloaterHost(LLMultiFloater* hostp) {sHostp = hostp; }
|
||||
static void setEditModeEnabled(BOOL enable);
|
||||
@@ -269,6 +269,8 @@ private:
|
||||
void updateButtons();
|
||||
void buildButtons();
|
||||
BOOL offerClickToButton(S32 x, S32 y, MASK mask, EFloaterButtons index);
|
||||
void addResizeCtrls();
|
||||
void layoutResizeCtrls();
|
||||
|
||||
LLRect mExpandedRect;
|
||||
LLDragHandle* mDragHandle;
|
||||
@@ -313,8 +315,10 @@ private:
|
||||
static std::string sButtonPressedImageNames[BUTTON_COUNT];
|
||||
static std::string sButtonNames[BUTTON_COUNT];
|
||||
static std::string sButtonToolTips[BUTTON_COUNT];
|
||||
typedef void (*click_callback)(void *);
|
||||
static click_callback sButtonCallbacks[BUTTON_COUNT];
|
||||
|
||||
typedef void (LLFloater::*button_callback)();
|
||||
|
||||
static button_callback sButtonCallbacks[BUTTON_COUNT];
|
||||
|
||||
typedef std::map<LLHandle<LLFloater>, LLFloater*> handle_map_t;
|
||||
typedef std::map<LLHandle<LLFloater>, LLFloater*>::iterator handle_map_iter_t;
|
||||
|
||||
@@ -49,7 +49,7 @@ LLIconCtrl::LLIconCtrl(const std::string& name, const LLRect &rect, const LLUUID
|
||||
: LLUICtrl(name,
|
||||
rect,
|
||||
FALSE, // mouse opaque
|
||||
NULL, NULL,
|
||||
NULL,
|
||||
FOLLOWS_LEFT | FOLLOWS_TOP),
|
||||
mColor( LLColor4::white )
|
||||
{
|
||||
@@ -61,7 +61,7 @@ LLIconCtrl::LLIconCtrl(const std::string& name, const LLRect &rect, const std::s
|
||||
: LLUICtrl(name,
|
||||
rect,
|
||||
FALSE, // mouse opaque
|
||||
NULL, NULL,
|
||||
NULL,
|
||||
FOLLOWS_LEFT | FOLLOWS_TOP),
|
||||
mColor( LLColor4::white ),
|
||||
mImageName(image_name)
|
||||
|
||||
@@ -42,31 +42,25 @@
|
||||
|
||||
const U32 KEYWORD_FILE_CURRENT_VERSION = 2;
|
||||
|
||||
inline BOOL LLKeywordToken::isHead(const llwchar* s, bool search_end_c_comment) const
|
||||
inline BOOL LLKeywordToken::isHead(const llwchar* s) const
|
||||
{
|
||||
// strncmp is much faster than string compare
|
||||
BOOL res = TRUE;
|
||||
const llwchar* t = mToken.c_str();
|
||||
S32 len = mToken.size();
|
||||
if (search_end_c_comment && len == 2 && t[0] == '/' && t[1] == '*')
|
||||
{
|
||||
// Special case for C-like */ end comment token
|
||||
if (s[0] == '*' && s[1] == '/')
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
for (S32 i = 0; i < len; i++)
|
||||
for (S32 i=0; i<len; i++)
|
||||
{
|
||||
if (s[i] != t[i])
|
||||
{
|
||||
return FALSE;
|
||||
res = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
return res;
|
||||
}
|
||||
|
||||
LLKeywords::LLKeywords() : mLoaded(FALSE)
|
||||
{
|
||||
}
|
||||
|
||||
inline BOOL LLKeywordToken::isTail(const llwchar* s) const
|
||||
@@ -85,10 +79,6 @@ inline BOOL LLKeywordToken::isTail(const llwchar* s) const
|
||||
return res;
|
||||
}
|
||||
|
||||
LLKeywords::LLKeywords() : mLoaded(FALSE)
|
||||
{
|
||||
}
|
||||
|
||||
LLKeywords::~LLKeywords()
|
||||
{
|
||||
std::for_each(mWordTokenMap.begin(), mWordTokenMap.end(), DeletePairedPointer());
|
||||
@@ -138,7 +128,7 @@ BOOL LLKeywords::loadFromFile( const std::string& filename )
|
||||
std::string SOL_LINE("[line ");
|
||||
std::string SOL_ONE_SIDED_DELIMITER("[one_sided_delimiter ");
|
||||
std::string SOL_TWO_SIDED_DELIMITER("[two_sided_delimiter ");
|
||||
std::string SOL_TWO_SIDED_DELIMITER_ESC("[two_sided_delimiter_esc ");
|
||||
std::string SOL_DOUBLE_QUOTATION_MARKS("[double_quotation_marks ");
|
||||
|
||||
LLColor3 cur_color( 1, 0, 0 );
|
||||
LLKeywordToken::TOKEN_TYPE cur_type = LLKeywordToken::WORD;
|
||||
@@ -170,10 +160,10 @@ BOOL LLKeywords::loadFromFile( const std::string& filename )
|
||||
cur_type = LLKeywordToken::TWO_SIDED_DELIMITER;
|
||||
continue;
|
||||
}
|
||||
else if( line.find(SOL_TWO_SIDED_DELIMITER_ESC) == 0 )
|
||||
else if( line.find(SOL_DOUBLE_QUOTATION_MARKS) == 0 )
|
||||
{
|
||||
cur_color = readColor( line.substr(SOL_TWO_SIDED_DELIMITER_ESC.size()) );
|
||||
cur_type = LLKeywordToken::TWO_SIDED_DELIMITER_ESC;
|
||||
cur_color = readColor( line.substr(SOL_DOUBLE_QUOTATION_MARKS.size()) );
|
||||
cur_type = LLKeywordToken::DOUBLE_QUOTATION_MARKS;
|
||||
continue;
|
||||
}
|
||||
else if( line.find(SOL_ONE_SIDED_DELIMITER) == 0 )
|
||||
@@ -193,13 +183,13 @@ BOOL LLKeywords::loadFromFile( const std::string& filename )
|
||||
|
||||
if( !token_buffer.empty() && token_word_iter != word_tokens.end() )
|
||||
{
|
||||
// first word is keyword
|
||||
// first word is the keyword or a left delimiter
|
||||
std::string keyword = (*token_word_iter);
|
||||
LLStringUtil::trim(keyword);
|
||||
// second word may be right delimiter
|
||||
|
||||
// second word may be a right delimiter
|
||||
std::string delimiter;
|
||||
if (cur_type == LLKeywordToken::TWO_SIDED_DELIMITER || cur_type == LLKeywordToken::TWO_SIDED_DELIMITER_ESC)
|
||||
if (cur_type == LLKeywordToken::TWO_SIDED_DELIMITER)
|
||||
{
|
||||
while (delimiter.length() == 0 && ++token_word_iter != word_tokens.end())
|
||||
{
|
||||
@@ -207,6 +197,11 @@ BOOL LLKeywords::loadFromFile( const std::string& filename )
|
||||
LLStringUtil::trim(delimiter);
|
||||
}
|
||||
}
|
||||
else if (cur_type == LLKeywordToken::DOUBLE_QUOTATION_MARKS)
|
||||
{
|
||||
// Closing delimiter is identical to the opening one.
|
||||
delimiter = keyword;
|
||||
}
|
||||
|
||||
// following words are tooltip
|
||||
std::string tool_tip;
|
||||
@@ -256,7 +251,7 @@ void LLKeywords::addToken(LLKeywordToken::TOKEN_TYPE type,
|
||||
break;
|
||||
|
||||
case LLKeywordToken::TWO_SIDED_DELIMITER:
|
||||
case LLKeywordToken::TWO_SIDED_DELIMITER_ESC:
|
||||
case LLKeywordToken::DOUBLE_QUOTATION_MARKS:
|
||||
case LLKeywordToken::ONE_SIDED_DELIMITER:
|
||||
mDelimiterTokenList.push_front(new LLKeywordToken(type, color, key, tool_tip, delimiter));
|
||||
break;
|
||||
@@ -265,24 +260,106 @@ void LLKeywords::addToken(LLKeywordToken::TOKEN_TYPE type,
|
||||
llassert(0);
|
||||
}
|
||||
}
|
||||
LLKeywords::WStringMapIndex::WStringMapIndex(const WStringMapIndex& other)
|
||||
{
|
||||
if(other.mOwner)
|
||||
{
|
||||
copyData(other.mData, other.mLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
mOwner = false;
|
||||
mLength = other.mLength;
|
||||
mData = other.mData;
|
||||
}
|
||||
}
|
||||
|
||||
LLKeywords::WStringMapIndex::WStringMapIndex(const LLWString& str)
|
||||
{
|
||||
copyData(str.data(), str.size());
|
||||
}
|
||||
|
||||
LLKeywords::WStringMapIndex::WStringMapIndex(const llwchar *start, size_t length):
|
||||
mData(start), mLength(length), mOwner(false)
|
||||
{
|
||||
}
|
||||
|
||||
LLKeywords::WStringMapIndex::~WStringMapIndex()
|
||||
{
|
||||
if(mOwner)
|
||||
delete[] mData;
|
||||
}
|
||||
|
||||
void LLKeywords::WStringMapIndex::copyData(const llwchar *start, size_t length)
|
||||
{
|
||||
llwchar *data = new llwchar[length];
|
||||
memcpy((void*)data, (const void*)start, length * sizeof(llwchar));
|
||||
|
||||
mOwner = true;
|
||||
mLength = length;
|
||||
mData = data;
|
||||
}
|
||||
|
||||
bool LLKeywords::WStringMapIndex::operator<(const LLKeywords::WStringMapIndex &other) const
|
||||
{
|
||||
// NOTE: Since this is only used to organize a std::map, it doesn't matter if it uses correct collate order or not.
|
||||
// The comparison only needs to strictly order all possible strings, and be stable.
|
||||
|
||||
bool result = false;
|
||||
const llwchar* self_iter = mData;
|
||||
const llwchar* self_end = mData + mLength;
|
||||
const llwchar* other_iter = other.mData;
|
||||
const llwchar* other_end = other.mData + other.mLength;
|
||||
|
||||
while(true)
|
||||
{
|
||||
if(other_iter >= other_end)
|
||||
{
|
||||
// We've hit the end of other.
|
||||
// This covers two cases: other being shorter than self, or the strings being equal.
|
||||
// In either case, we want to return false.
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
else if(self_iter >= self_end)
|
||||
{
|
||||
// self is shorter than other.
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
else if(*self_iter != *other_iter)
|
||||
{
|
||||
// The current character differs. The strings are not equal.
|
||||
result = *self_iter < *other_iter;
|
||||
break;
|
||||
}
|
||||
|
||||
self_iter++;
|
||||
other_iter++;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
LLColor3 LLKeywords::readColor( const std::string& s )
|
||||
{
|
||||
F32 r, g, b;
|
||||
r = g = b = 0.0f;
|
||||
S32 read = sscanf(s.c_str(), "%f, %f, %f]", &r, &g, &b );
|
||||
if( read != 3 ) /* Flawfinder: ignore */
|
||||
S32 values_read = sscanf(s.c_str(), "%f, %f, %f]", &r, &g, &b );
|
||||
if( values_read != 3 )
|
||||
{
|
||||
llinfos << " poorly formed color in keyword file" << llendl;
|
||||
}
|
||||
return LLColor3( r, g, b );
|
||||
}
|
||||
|
||||
LLFastTimer::DeclareTimer FTM_SYNTAX_COLORING("Syntax Coloring");
|
||||
|
||||
// Walk through a string, applying the rules specified by the keyword token list and
|
||||
// create a list of color segments.
|
||||
void LLKeywords::findSegments(std::vector<LLTextSegment *>* seg_list, const LLWString& wtext, const LLColor4 &defaultColor)
|
||||
void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLWString& wtext, const LLColor4 &defaultColor)
|
||||
{
|
||||
std::for_each(seg_list->begin(), seg_list->end(), DeletePointer());
|
||||
LLFastTimer ft(FTM_SYNTAX_COLORING);
|
||||
seg_list->clear();
|
||||
|
||||
if( wtext.empty() )
|
||||
@@ -290,7 +367,7 @@ void LLKeywords::findSegments(std::vector<LLTextSegment *>* seg_list, const LLWS
|
||||
return;
|
||||
}
|
||||
|
||||
S32 text_len = wtext.size();
|
||||
S32 text_len = wtext.size() + 1;
|
||||
|
||||
seg_list->push_back( new LLTextSegment( LLColor3(defaultColor), 0, text_len ) );
|
||||
|
||||
@@ -343,9 +420,9 @@ void LLKeywords::findSegments(std::vector<LLTextSegment *>* seg_list, const LLWS
|
||||
}
|
||||
S32 seg_end = cur - base;
|
||||
|
||||
LLTextSegment* text_segment = new LLTextSegment( cur_token->getColor(), seg_start, seg_end );
|
||||
LLTextSegmentPtr text_segment = new LLTextSegment( cur_token->getColor(), seg_start, seg_end );
|
||||
text_segment->setToken( cur_token );
|
||||
insertSegment( seg_list, text_segment, text_len, defaultColor);
|
||||
insertSegment( *seg_list, text_segment, text_len, defaultColor);
|
||||
line_done = TRUE; // to break out of second loop.
|
||||
break;
|
||||
}
|
||||
@@ -387,17 +464,15 @@ void LLKeywords::findSegments(std::vector<LLTextSegment *>* seg_list, const LLWS
|
||||
S32 seg_end = 0;
|
||||
|
||||
seg_start = cur - base;
|
||||
cur += cur_delimiter->getLength();
|
||||
cur += cur_delimiter->getLengthHead();
|
||||
|
||||
//if( cur_delimiter->getType() == LLKeywordToken::TWO_SIDED_DELIMITER )
|
||||
LLKeywordToken::TOKEN_TYPE type = cur_delimiter->getType();
|
||||
if( type == LLKeywordToken::TWO_SIDED_DELIMITER || type == LLKeywordToken::TWO_SIDED_DELIMITER_ESC )
|
||||
if( type == LLKeywordToken::TWO_SIDED_DELIMITER || type == LLKeywordToken::DOUBLE_QUOTATION_MARKS )
|
||||
{
|
||||
//llassert( cur_delimiter->getDelimiter() != NULL );
|
||||
while( *cur && !cur_delimiter->isTail(cur) )
|
||||
while( *cur && !cur_delimiter->isTail(cur))
|
||||
{
|
||||
// Check for an escape sequence.
|
||||
if (type == LLKeywordToken::TWO_SIDED_DELIMITER_ESC && *cur == '\\')
|
||||
if (type == LLKeywordToken::DOUBLE_QUOTATION_MARKS && *cur == '\\')
|
||||
{
|
||||
// Count the number of backslashes.
|
||||
S32 num_backslashes = 0;
|
||||
@@ -433,13 +508,13 @@ void LLKeywords::findSegments(std::vector<LLTextSegment *>* seg_list, const LLWS
|
||||
|
||||
if( *cur )
|
||||
{
|
||||
cur += cur_delimiter->getLength();
|
||||
seg_end = seg_start + between_delimiters + cur_delimiter->getLength() + cur_delimiter->getLength2();
|
||||
cur += cur_delimiter->getLengthHead();
|
||||
seg_end = seg_start + between_delimiters + cur_delimiter->getLengthHead() + cur_delimiter->getLengthTail();
|
||||
}
|
||||
else
|
||||
{
|
||||
// eof
|
||||
seg_end = seg_start + between_delimiters + cur_delimiter->getLength();
|
||||
seg_end = seg_start + between_delimiters + cur_delimiter->getLengthHead();
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -451,13 +526,13 @@ void LLKeywords::findSegments(std::vector<LLTextSegment *>* seg_list, const LLWS
|
||||
between_delimiters++;
|
||||
cur++;
|
||||
}
|
||||
seg_end = seg_start + between_delimiters + cur_delimiter->getLength();
|
||||
seg_end = seg_start + between_delimiters + cur_delimiter->getLengthHead();
|
||||
}
|
||||
|
||||
|
||||
LLTextSegment* text_segment = new LLTextSegment( cur_delimiter->getColor(), seg_start, seg_end );
|
||||
LLTextSegmentPtr text_segment = new LLTextSegment( cur_delimiter->getColor(), seg_start, seg_end );
|
||||
text_segment->setToken( cur_delimiter );
|
||||
insertSegment( seg_list, text_segment, text_len, defaultColor);
|
||||
insertSegment( *seg_list, text_segment, text_len, defaultColor);
|
||||
|
||||
// Note: we don't increment cur, since the end of one delimited seg may be immediately
|
||||
// followed by the start of another one.
|
||||
@@ -477,7 +552,7 @@ void LLKeywords::findSegments(std::vector<LLTextSegment *>* seg_list, const LLWS
|
||||
S32 seg_len = p - cur;
|
||||
if( seg_len > 0 )
|
||||
{
|
||||
LLWString word( cur, 0, seg_len );
|
||||
WStringMapIndex word( cur, seg_len );
|
||||
word_token_map_t::iterator map_iter = mWordTokenMap.find(word);
|
||||
if( map_iter != mWordTokenMap.end() )
|
||||
{
|
||||
@@ -488,9 +563,9 @@ void LLKeywords::findSegments(std::vector<LLTextSegment *>* seg_list, const LLWS
|
||||
// llinfos << "Seg: [" << word.c_str() << "]" << llendl;
|
||||
|
||||
|
||||
LLTextSegment* text_segment = new LLTextSegment( cur_token->getColor(), seg_start, seg_end );
|
||||
LLTextSegmentPtr text_segment = new LLTextSegment( cur_token->getColor(), seg_start, seg_end );
|
||||
text_segment->setToken( cur_token );
|
||||
insertSegment( seg_list, text_segment, text_len, defaultColor);
|
||||
insertSegment( *seg_list, text_segment, text_len, defaultColor);
|
||||
}
|
||||
cur += seg_len;
|
||||
continue;
|
||||
@@ -505,25 +580,24 @@ void LLKeywords::findSegments(std::vector<LLTextSegment *>* seg_list, const LLWS
|
||||
}
|
||||
}
|
||||
|
||||
void LLKeywords::insertSegment(std::vector<LLTextSegment*>* seg_list, LLTextSegment* new_segment, S32 text_len, const LLColor4 &defaultColor )
|
||||
void LLKeywords::insertSegment(std::vector<LLTextSegmentPtr>& seg_list, LLTextSegmentPtr new_segment, S32 text_len, const LLColor4 &defaultColor )
|
||||
{
|
||||
LLTextSegment* last = seg_list->back();
|
||||
LLTextSegmentPtr last = seg_list.back();
|
||||
S32 new_seg_end = new_segment->getEnd();
|
||||
|
||||
if( new_segment->getStart() == last->getStart() )
|
||||
{
|
||||
*last = *new_segment;
|
||||
delete new_segment;
|
||||
seg_list.pop_back();
|
||||
}
|
||||
else
|
||||
{
|
||||
last->setEnd( new_segment->getStart() );
|
||||
seg_list->push_back( new_segment );
|
||||
}
|
||||
seg_list.push_back( new_segment );
|
||||
|
||||
if( new_seg_end < text_len )
|
||||
{
|
||||
seg_list->push_back( new LLTextSegment( defaultColor, new_seg_end, text_len ) );
|
||||
seg_list.push_back( new LLTextSegment( defaultColor, new_seg_end, text_len ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,14 +39,32 @@
|
||||
#include <map>
|
||||
#include <list>
|
||||
#include <deque>
|
||||
#include "llpointer.h"
|
||||
|
||||
class LLTextSegment;
|
||||
|
||||
typedef LLPointer<LLTextSegment> LLTextSegmentPtr;
|
||||
|
||||
class LLKeywordToken
|
||||
{
|
||||
public:
|
||||
enum TOKEN_TYPE { WORD, LINE, TWO_SIDED_DELIMITER, ONE_SIDED_DELIMITER, TWO_SIDED_DELIMITER_ESC };
|
||||
/**
|
||||
* @brief Types of tokens/delimters being parsed.
|
||||
*
|
||||
* @desc Tokens/delimiters that need to be identified/highlighted. All are terminated if an EOF is encountered.
|
||||
* - WORD are keywords in the normal sense, i.e. constants, events, etc.
|
||||
* - LINE are for entire lines (currently only flow control labels use this).
|
||||
* - ONE_SIDED_DELIMITER are for open-ended delimiters which are terminated by EOL.
|
||||
* - TWO_SIDED_DELIMITER are for delimiters that end with a different delimiter than they open with.
|
||||
* - DOUBLE_QUOTATION_MARKS are for delimiting areas using the same delimiter to open and close.
|
||||
*/
|
||||
enum TOKEN_TYPE
|
||||
{
|
||||
WORD,
|
||||
LINE,
|
||||
TWO_SIDED_DELIMITER,
|
||||
ONE_SIDED_DELIMITER,
|
||||
DOUBLE_QUOTATION_MARKS
|
||||
};
|
||||
|
||||
LLKeywordToken( TOKEN_TYPE type, const LLColor3& color, const LLWString& token, const LLWString& tool_tip, const LLWString& delimiter )
|
||||
:
|
||||
@@ -58,9 +76,9 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
S32 getLength() const { return mToken.size(); }
|
||||
S32 getLength2() const { return mDelimiter.size(); }
|
||||
BOOL isHead(const llwchar* s, bool search_end_c_comment = false) const;
|
||||
S32 getLengthHead() const { return mToken.size(); }
|
||||
S32 getLengthTail() const { return mDelimiter.size(); }
|
||||
BOOL isHead(const llwchar* s) const;
|
||||
BOOL isTail(const llwchar* s) const;
|
||||
const LLWString& getToken() const { return mToken; }
|
||||
const LLColor3& getColor() const { return mColor; }
|
||||
@@ -89,7 +107,7 @@ public:
|
||||
BOOL loadFromFile(const std::string& filename);
|
||||
BOOL isLoaded() const { return mLoaded; }
|
||||
|
||||
void findSegments(std::vector<LLTextSegment *> *seg_list, const LLWString& text, const LLColor4 &defaultColor );
|
||||
void findSegments(std::vector<LLTextSegmentPtr> *seg_list, const LLWString& text, const LLColor4 &defaultColor );
|
||||
|
||||
// Add the token as described
|
||||
void addToken(LLKeywordToken::TOKEN_TYPE type,
|
||||
@@ -97,8 +115,33 @@ public:
|
||||
const LLColor3& color,
|
||||
const std::string& tool_tip = LLStringUtil::null,
|
||||
const std::string& delimiter = LLStringUtil::null);
|
||||
|
||||
// This class is here as a performance optimization.
|
||||
// The word token map used to be defined as std::map<LLWString, LLKeywordToken*>.
|
||||
// This worked, but caused a performance bottleneck due to memory allocation and string copies
|
||||
// because it's not possible to search such a map without creating an LLWString.
|
||||
// Using this class as the map index instead allows us to search using segments of an existing
|
||||
// text run without copying them first, which greatly reduces overhead in LLKeywords::findSegments().
|
||||
class WStringMapIndex
|
||||
{
|
||||
public:
|
||||
// copy constructor
|
||||
WStringMapIndex(const WStringMapIndex& other);
|
||||
// constructor from a string (copies the string's data into the new object)
|
||||
WStringMapIndex(const LLWString& str);
|
||||
// constructor from pointer and length
|
||||
// NOTE: does NOT copy data, caller must ensure that the lifetime of the pointer exceeds that of the new object!
|
||||
WStringMapIndex(const llwchar *start, size_t length);
|
||||
~WStringMapIndex();
|
||||
bool operator<(const WStringMapIndex &other) const;
|
||||
private:
|
||||
void copyData(const llwchar *start, size_t length);
|
||||
const llwchar *mData;
|
||||
size_t mLength;
|
||||
bool mOwner;
|
||||
};
|
||||
|
||||
typedef std::map<LLWString, LLKeywordToken*> word_token_map_t;
|
||||
typedef std::map<WStringMapIndex, LLKeywordToken*> word_token_map_t;
|
||||
typedef word_token_map_t::const_iterator keyword_iterator_t;
|
||||
keyword_iterator_t begin() const { return mWordTokenMap.begin(); }
|
||||
keyword_iterator_t end() const { return mWordTokenMap.end(); }
|
||||
@@ -109,7 +152,7 @@ public:
|
||||
|
||||
private:
|
||||
LLColor3 readColor(const std::string& s);
|
||||
void insertSegment(std::vector<LLTextSegment *> *seg_list, LLTextSegment* new_segment, S32 text_len, const LLColor4 &defaultColor);
|
||||
void insertSegment(std::vector<LLTextSegmentPtr>& seg_list, LLTextSegmentPtr new_segment, S32 text_len, const LLColor4 &defaultColor);
|
||||
|
||||
BOOL mLoaded;
|
||||
word_token_map_t mWordTokenMap;
|
||||
|
||||
@@ -93,16 +93,15 @@ static LLRegisterWidget<LLLineEditor> r1("line_editor");
|
||||
LLLineEditor::LLLineEditor(const std::string& name, const LLRect& rect,
|
||||
const std::string& default_text, const LLFontGL* font,
|
||||
S32 max_length_bytes,
|
||||
void (*commit_callback)(LLUICtrl* caller, void* user_data ),
|
||||
void (*keystroke_callback)(LLLineEditor* caller, void* user_data ),
|
||||
void (*focus_lost_callback)(LLFocusableElement* caller, void* user_data ),
|
||||
void* userdata,
|
||||
LLLinePrevalidateFunc prevalidate_func,
|
||||
commit_callback_t commit_callback,
|
||||
keystroke_callback_t keystroke_callback,
|
||||
focus_lost_callback_t focus_lost_callback,
|
||||
validate_func_t prevalidate_func,
|
||||
LLViewBorder::EBevel border_bevel,
|
||||
LLViewBorder::EStyle border_style,
|
||||
S32 border_thickness)
|
||||
:
|
||||
LLUICtrl( name, rect, TRUE, commit_callback, userdata, FOLLOWS_TOP | FOLLOWS_LEFT ),
|
||||
LLUICtrl( name, rect, TRUE, commit_callback, FOLLOWS_TOP | FOLLOWS_LEFT ),
|
||||
mMaxLengthBytes(max_length_bytes),
|
||||
mCursorPos( 0 ),
|
||||
mScrollHPos( 0 ),
|
||||
@@ -142,6 +141,9 @@ LLLineEditor::LLLineEditor(const std::string& name, const LLRect& rect,
|
||||
mSpellCheckable( FALSE ),
|
||||
mContextMenuHandle()
|
||||
{
|
||||
if(focus_lost_callback)
|
||||
setFocusLostCallback(focus_lost_callback);
|
||||
|
||||
llassert( max_length_bytes > 0 );
|
||||
|
||||
// Initialize current history line iterator
|
||||
@@ -156,9 +158,6 @@ LLLineEditor::LLLineEditor(const std::string& name, const LLRect& rect,
|
||||
mGLFont = LLFontGL::getFontSansSerifSmall();
|
||||
}
|
||||
|
||||
if(focus_lost_callback)
|
||||
setFocusLostCallback(boost::bind(focus_lost_callback,_1,(void*)NULL));
|
||||
|
||||
setTextPadding(0, 0);
|
||||
|
||||
mScrollTimer.reset();
|
||||
@@ -1112,9 +1111,8 @@ void LLLineEditor::cut()
|
||||
reportBadKeystroke();
|
||||
}
|
||||
else
|
||||
if( mKeystrokeCallback )
|
||||
{
|
||||
mKeystrokeCallback( this, mCallbackUserData );
|
||||
onKeystroke();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1160,8 +1158,10 @@ void LLLineEditor::insert(std::string what, S32 wher)
|
||||
rollback.doRollback( this );
|
||||
reportBadKeystroke();
|
||||
}
|
||||
else if( mKeystrokeCallback )
|
||||
mKeystrokeCallback( this, mCallbackUserData );
|
||||
else
|
||||
{
|
||||
onKeystroke();
|
||||
}
|
||||
}
|
||||
|
||||
BOOL LLLineEditor::canPaste() const
|
||||
@@ -1261,9 +1261,8 @@ void LLLineEditor::pasteHelper(bool is_primary)
|
||||
reportBadKeystroke();
|
||||
}
|
||||
else
|
||||
if( mKeystrokeCallback )
|
||||
{
|
||||
mKeystrokeCallback( this, mCallbackUserData );
|
||||
onKeystroke();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1582,10 +1581,7 @@ BOOL LLLineEditor::handleKeyHere(KEY key, MASK mask )
|
||||
// Notify owner if requested
|
||||
if (!need_to_rollback && handled)
|
||||
{
|
||||
if (mKeystrokeCallback)
|
||||
{
|
||||
mKeystrokeCallback(this, mCallbackUserData);
|
||||
}
|
||||
onKeystroke();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1637,12 +1633,10 @@ BOOL LLLineEditor::handleUnicodeCharHere(llwchar uni_char)
|
||||
// Notify owner if requested
|
||||
if( !need_to_rollback && handled )
|
||||
{
|
||||
if( mKeystrokeCallback )
|
||||
{
|
||||
// HACK! The only usage of this callback doesn't do anything with the character.
|
||||
// We'll have to do something about this if something ever changes! - Doug
|
||||
mKeystrokeCallback( this, mCallbackUserData );
|
||||
}
|
||||
// HACK! The only usage of this callback doesn't do anything with the character.
|
||||
// We'll have to do something about this if something ever changes! - Doug
|
||||
onKeystroke();
|
||||
|
||||
}
|
||||
}
|
||||
return handled;
|
||||
@@ -1651,7 +1645,7 @@ BOOL LLLineEditor::handleUnicodeCharHere(llwchar uni_char)
|
||||
|
||||
BOOL LLLineEditor::canDoDelete() const
|
||||
{
|
||||
return ( !mReadOnly && (!mPassDelete || (hasSelection() || (getCursor() < mText.length()))) );
|
||||
return ( !mReadOnly && mText.length() > 0 && (!mPassDelete || (hasSelection() || (getCursor() < mText.length()))) );
|
||||
}
|
||||
|
||||
void LLLineEditor::doDelete()
|
||||
@@ -1680,10 +1674,7 @@ void LLLineEditor::doDelete()
|
||||
}
|
||||
else
|
||||
{
|
||||
if( mKeystrokeCallback )
|
||||
{
|
||||
mKeystrokeCallback( this, mCallbackUserData );
|
||||
}
|
||||
onKeystroke();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1757,7 +1748,8 @@ void LLLineEditor::draw()
|
||||
}
|
||||
|
||||
// draw rectangle for the background
|
||||
LLRect background( 0, getRect().getHeight(), getRect().getWidth(), 0 );
|
||||
//LLRect background( 0, getRect().getHeight(), getRect().getWidth(), 0 );
|
||||
LLRect background = getLocalRect();
|
||||
background.stretch( -mBorderThickness );
|
||||
|
||||
LLColor4 bg_color = mReadOnlyBgColor;
|
||||
@@ -2131,7 +2123,7 @@ void LLLineEditor::setRect(const LLRect& rect)
|
||||
}
|
||||
}
|
||||
|
||||
void LLLineEditor::setPrevalidate(BOOL (*func)(const LLWString &))
|
||||
void LLLineEditor::setPrevalidate(LLLineEditor::validate_func_t func)
|
||||
{
|
||||
mPrevalidateFunc = func;
|
||||
updateAllowingLanguageInput();
|
||||
@@ -2483,12 +2475,21 @@ void LLLineEditor::setSelectAllonFocusReceived(BOOL b)
|
||||
mSelectAllonFocusReceived = b;
|
||||
}
|
||||
|
||||
|
||||
void LLLineEditor::setKeystrokeCallback(void (*keystroke_callback)(LLLineEditor* caller, void* user_data))
|
||||
void LLLineEditor::onKeystroke()
|
||||
{
|
||||
mKeystrokeCallback = keystroke_callback;
|
||||
if (mKeystrokeCallback)
|
||||
{
|
||||
mKeystrokeCallback(this);
|
||||
}
|
||||
}
|
||||
|
||||
void LLLineEditor::setKeystrokeCallback(keystroke_callback_t callback)
|
||||
{
|
||||
mKeystrokeCallback = callback;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// virtual
|
||||
LLXMLNodePtr LLLineEditor::getXML(bool save_children) const
|
||||
{
|
||||
@@ -2579,14 +2580,11 @@ LLView* LLLineEditor::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory
|
||||
S32 border_thickness = 1;
|
||||
node->getAttributeS32("border_thickness", border_thickness);
|
||||
|
||||
LLUICtrlCallback commit_callback = NULL;
|
||||
|
||||
LLLineEditor* line_editor = new LLLineEditor(name,
|
||||
rect,
|
||||
text,
|
||||
font,
|
||||
max_text_length,
|
||||
commit_callback,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
@@ -2833,10 +2831,8 @@ void LLLineEditor::updatePreedit(const LLWString &preedit_string,
|
||||
|
||||
// Update of the preedit should be caused by some key strokes.
|
||||
mKeystrokeTimer.reset();
|
||||
if( mKeystrokeCallback )
|
||||
{
|
||||
mKeystrokeCallback( this, mCallbackUserData );
|
||||
}
|
||||
onKeystroke();
|
||||
|
||||
}
|
||||
|
||||
BOOL LLLineEditor::getPreeditLocation(S32 query_offset, LLCoordGL *coord, LLRect *bounds, LLRect *control) const
|
||||
@@ -3093,156 +3089,3 @@ void LLLineEditor::setContextMenu(LLMenuGL* new_context_menu)
|
||||
mContextMenuHandle.markDead();
|
||||
}
|
||||
|
||||
static LLRegisterWidget<LLSearchEditor> r2("search_editor");
|
||||
|
||||
|
||||
LLSearchEditor::LLSearchEditor(const std::string& name,
|
||||
const LLRect& rect,
|
||||
S32 max_length_bytes,
|
||||
void (*search_callback)(const std::string& search_string, void* user_data),
|
||||
void* userdata)
|
||||
:
|
||||
LLUICtrl(name, rect, TRUE, NULL, userdata),
|
||||
mSearchCallback(search_callback)
|
||||
{
|
||||
LLRect search_edit_rect(0, getRect().getHeight(), getRect().getWidth(), 0);
|
||||
mSearchEdit = new LLLineEditor(std::string("search edit"),
|
||||
search_edit_rect,
|
||||
LLStringUtil::null,
|
||||
NULL,
|
||||
max_length_bytes,
|
||||
NULL,
|
||||
onSearchEdit,
|
||||
NULL,
|
||||
this);
|
||||
|
||||
mSearchEdit->setFollowsAll();
|
||||
mSearchEdit->setSelectAllonFocusReceived(TRUE);
|
||||
|
||||
addChild(mSearchEdit);
|
||||
|
||||
S32 btn_width = rect.getHeight(); // button is square, and as tall as search editor
|
||||
LLRect clear_btn_rect(rect.getWidth() - btn_width, rect.getHeight(), rect.getWidth(), 0);
|
||||
mClearSearchButton = new LLButton(std::string("clear search"),
|
||||
clear_btn_rect,
|
||||
std::string("icn_clear_lineeditor.tga"),
|
||||
std::string("UIImgBtnCloseInactiveUUID"),
|
||||
LLStringUtil::null,
|
||||
onClearSearch,
|
||||
this,
|
||||
NULL,
|
||||
LLStringUtil::null);
|
||||
mClearSearchButton->setFollowsRight();
|
||||
mClearSearchButton->setFollowsTop();
|
||||
mClearSearchButton->setImageColor(LLUI::sColorsGroup->getColor("TextFgTentativeColor"));
|
||||
mClearSearchButton->setTabStop(FALSE);
|
||||
mSearchEdit->addChild(mClearSearchButton);
|
||||
|
||||
mSearchEdit->setTextPadding(0, btn_width);
|
||||
}
|
||||
|
||||
|
||||
//virtual
|
||||
void LLSearchEditor::setValue(const LLSD& value )
|
||||
{
|
||||
mSearchEdit->setValue(value);
|
||||
}
|
||||
|
||||
//virtual
|
||||
LLSD LLSearchEditor::getValue() const
|
||||
{
|
||||
return mSearchEdit->getValue();
|
||||
}
|
||||
|
||||
//virtual
|
||||
BOOL LLSearchEditor::setTextArg( const std::string& key, const LLStringExplicit& text )
|
||||
{
|
||||
return mSearchEdit->setTextArg(key, text);
|
||||
}
|
||||
|
||||
//virtual
|
||||
BOOL LLSearchEditor::setLabelArg( const std::string& key, const LLStringExplicit& text )
|
||||
{
|
||||
return mSearchEdit->setLabelArg(key, text);
|
||||
}
|
||||
|
||||
//virtual
|
||||
void LLSearchEditor::clear()
|
||||
{
|
||||
if (mSearchEdit)
|
||||
{
|
||||
mSearchEdit->clear();
|
||||
}
|
||||
}
|
||||
|
||||
void LLSearchEditor::draw()
|
||||
{
|
||||
mClearSearchButton->setVisible(!mSearchEdit->getWText().empty());
|
||||
|
||||
LLUICtrl::draw();
|
||||
}
|
||||
|
||||
|
||||
//static
|
||||
void LLSearchEditor::onSearchEdit(LLLineEditor* caller, void* user_data )
|
||||
{
|
||||
LLSearchEditor* search_editor = (LLSearchEditor*)user_data;
|
||||
if (search_editor->mSearchCallback)
|
||||
{
|
||||
search_editor->mSearchCallback(caller->getText(), search_editor->mCallbackUserData);
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
void LLSearchEditor::onClearSearch(void* user_data)
|
||||
{
|
||||
LLSearchEditor* search_editor = (LLSearchEditor*)user_data;
|
||||
|
||||
search_editor->setText(LLStringUtil::null);
|
||||
if (search_editor->mSearchCallback)
|
||||
{
|
||||
search_editor->mSearchCallback(LLStringUtil::null, search_editor->mCallbackUserData);
|
||||
}
|
||||
}
|
||||
|
||||
// virtual
|
||||
LLXMLNodePtr LLSearchEditor::getXML(bool save_children) const
|
||||
{
|
||||
LLXMLNodePtr node = LLUICtrl::getXML();
|
||||
|
||||
node->setName(LL_SEARCH_EDITOR_TAG);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
// static
|
||||
LLView* LLSearchEditor::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
|
||||
{
|
||||
std::string name("search_editor");
|
||||
node->getAttributeString("name", name);
|
||||
|
||||
LLRect rect;
|
||||
createRect(node, rect, parent, LLRect());
|
||||
|
||||
S32 max_text_length = 128;
|
||||
node->getAttributeS32("max_length", max_text_length);
|
||||
|
||||
std::string text = node->getValue().substr(0, max_text_length - 1);
|
||||
|
||||
LLSearchEditor* search_editor = new LLSearchEditor(name,
|
||||
rect,
|
||||
max_text_length,
|
||||
NULL, NULL);
|
||||
|
||||
std::string label;
|
||||
if(node->getAttributeString("label", label))
|
||||
{
|
||||
search_editor->mSearchEdit->setLabel(label);
|
||||
}
|
||||
|
||||
search_editor->setText(text);
|
||||
|
||||
search_editor->initFromXML(node, parent);
|
||||
|
||||
return search_editor;
|
||||
}
|
||||
|
||||
@@ -58,24 +58,24 @@ class LLLineEditorRollback;
|
||||
class LLButton;
|
||||
class LLMenuGL;
|
||||
|
||||
typedef BOOL (*LLLinePrevalidateFunc)(const LLWString &wstr);
|
||||
|
||||
|
||||
class LLLineEditor
|
||||
: public LLUICtrl, public LLEditMenuHandler, protected LLPreeditor
|
||||
{
|
||||
|
||||
public:
|
||||
typedef boost::function<void (LLLineEditor* caller)> keystroke_callback_t;
|
||||
typedef boost::function<void (LLFocusableElement*)> focus_lost_callback_t;
|
||||
typedef boost::function<BOOL (const LLWString &wstr)> validate_func_t;
|
||||
|
||||
LLLineEditor(const std::string& name,
|
||||
const LLRect& rect,
|
||||
const std::string& default_text = LLStringUtil::null,
|
||||
const LLFontGL* glfont = NULL,
|
||||
S32 max_length_bytes = 254,
|
||||
void (*commit_callback)(LLUICtrl* caller, void* user_data) = NULL,
|
||||
void (*keystroke_callback)(LLLineEditor* caller, void* user_data) = NULL,
|
||||
void (*focus_lost_callback)(LLFocusableElement* caller, void* user_data) = NULL,
|
||||
void* userdata = NULL,
|
||||
LLLinePrevalidateFunc prevalidate_func = NULL,
|
||||
commit_callback_t commit_callback = NULL,
|
||||
keystroke_callback_t keystroke_callback = NULL,
|
||||
focus_lost_callback_t focus_lost_callback = NULL,
|
||||
validate_func_t prevalidate_func = NULL,
|
||||
LLViewBorder::EBevel border_bevel = LLViewBorder::BEVEL_IN,
|
||||
LLViewBorder::EStyle border_style = LLViewBorder::STYLE_LINE,
|
||||
S32 border_thickness = 1);
|
||||
@@ -230,13 +230,14 @@ public:
|
||||
void setSelectAllonFocusReceived(BOOL b);
|
||||
void setSelectAllonCommit(BOOL b) { mSelectAllonCommit = b; }
|
||||
|
||||
void setKeystrokeCallback(void (*keystroke_callback)(LLLineEditor* caller, void* user_data));
|
||||
void onKeystroke();
|
||||
void setKeystrokeCallback(keystroke_callback_t callback);
|
||||
|
||||
void setMaxTextLength(S32 max_text_length);
|
||||
void setTextPadding(S32 left, S32 right); // Used to specify room for children before or after text.
|
||||
|
||||
// Prevalidation controls which keystrokes can affect the editor
|
||||
void setPrevalidate( BOOL (*func)(const LLWString &) );
|
||||
void setPrevalidate( validate_func_t func );
|
||||
static BOOL prevalidateFloat(const LLWString &str );
|
||||
static BOOL prevalidateInt(const LLWString &str );
|
||||
static BOOL prevalidatePositiveS32(const LLWString &str);
|
||||
@@ -323,7 +324,7 @@ protected:
|
||||
BOOL mCommitOnFocusLost;
|
||||
BOOL mRevertOnEsc;
|
||||
|
||||
void (*mKeystrokeCallback)( LLLineEditor* caller, void* userdata );
|
||||
keystroke_callback_t mKeystrokeCallback;
|
||||
|
||||
BOOL mIsSelecting; // Selection for clipboard operations
|
||||
S32 mSelectionStart;
|
||||
@@ -333,8 +334,7 @@ protected:
|
||||
S32 mLastSelectionStart;
|
||||
S32 mLastSelectionEnd;
|
||||
|
||||
S32 (*mPrevalidateFunc)(const LLWString &str);
|
||||
|
||||
validate_func_t mPrevalidateFunc;
|
||||
LLFrameTimer mKeystrokeTimer;
|
||||
|
||||
LLColor4 mCursorColor;
|
||||
@@ -418,46 +418,4 @@ private:
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* @brief A line editor with a button to clear it and a callback to call on every edit event.
|
||||
*/
|
||||
class LLSearchEditor : public LLUICtrl
|
||||
{
|
||||
public:
|
||||
LLSearchEditor(const std::string& name,
|
||||
const LLRect& rect,
|
||||
S32 max_length_bytes,
|
||||
void (*search_callback)(const std::string& search_string, void* user_data),
|
||||
void* userdata);
|
||||
|
||||
virtual ~LLSearchEditor() {}
|
||||
|
||||
/*virtual*/ void draw();
|
||||
|
||||
virtual LLXMLNodePtr getXML(bool save_children = true) const;
|
||||
static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
|
||||
|
||||
void setText(const LLStringExplicit &new_text) { mSearchEdit->setText(new_text); }
|
||||
|
||||
typedef boost::function<void (const std::string&, void *)> search_callback_t;
|
||||
void setSearchCallback(search_callback_t cb,void *user_data) { mSearchCallback = boost::bind(cb,_1,user_data); }
|
||||
|
||||
// LLUICtrl interface
|
||||
virtual void setValue(const LLSD& value );
|
||||
virtual LLSD getValue() const;
|
||||
virtual BOOL setTextArg( const std::string& key, const LLStringExplicit& text );
|
||||
virtual BOOL setLabelArg( const std::string& key, const LLStringExplicit& text );
|
||||
virtual void clear();
|
||||
|
||||
private:
|
||||
static void onSearchEdit(LLLineEditor* caller, void* user_data );
|
||||
static void onClearSearch(void* user_data);
|
||||
|
||||
LLLineEditor* mSearchEdit;
|
||||
class LLButton* mClearSearchButton;
|
||||
|
||||
search_callback_t mSearchCallback;
|
||||
|
||||
};
|
||||
|
||||
#endif // LL_LINEEDITOR_
|
||||
|
||||
@@ -136,7 +136,7 @@ const F32 ACTIVATE_HIGHLIGHT_TIME = 0.3f;
|
||||
|
||||
// Default constructor
|
||||
LLMenuItemGL::LLMenuItemGL( const std::string& name, const std::string& label, KEY key, MASK mask ) :
|
||||
LLUICtrl( name, LLRect(), TRUE, NULL, NULL ),
|
||||
LLUICtrl( name ),
|
||||
mJumpKey(KEY_NONE),
|
||||
mAllowKeyRepeat(FALSE),
|
||||
mHighlight( FALSE ),
|
||||
@@ -268,19 +268,6 @@ BOOL LLMenuItemGL::addToAcceleratorList(std::list <LLKeyBinding*> *listp)
|
||||
accelerator = *list_it;
|
||||
if ((accelerator->mKey == mAcceleratorKey) && (accelerator->mMask == (mAcceleratorMask & MASK_NORMALKEYS)))
|
||||
{
|
||||
|
||||
// *NOTE: get calling code to throw up warning or route
|
||||
// warning messages back to app-provided output
|
||||
// std::string warning;
|
||||
// warning.append("Duplicate key binding <");
|
||||
// appendAcceleratorString( warning );
|
||||
// warning.append("> for menu items:\n ");
|
||||
// warning.append(accelerator->mName);
|
||||
// warning.append("\n ");
|
||||
// warning.append(mLabel);
|
||||
|
||||
// llwarns << warning << llendl;
|
||||
// LLAlertDialog::modalAlert(warning);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
@@ -1826,7 +1813,7 @@ static LLRegisterWidget<LLMenuGL> r1("menu");
|
||||
|
||||
// Default constructor
|
||||
LLMenuGL::LLMenuGL( const std::string& name, const std::string& label )
|
||||
: LLUICtrl( name, LLRect(), FALSE, NULL, NULL ),
|
||||
: LLUICtrl( name, LLRect(), FALSE),
|
||||
mBackgroundColor( sDefaultBackgroundColor ),
|
||||
mBgVisible( TRUE ),
|
||||
mHasSelection( FALSE ),
|
||||
@@ -1852,7 +1839,7 @@ LLMenuGL::LLMenuGL( const std::string& name, const std::string& label )
|
||||
}
|
||||
|
||||
LLMenuGL::LLMenuGL( const std::string& label)
|
||||
: LLUICtrl( label, LLRect(), FALSE, NULL, NULL ),
|
||||
: LLUICtrl( label, LLRect(), FALSE),
|
||||
mBackgroundColor( sDefaultBackgroundColor ),
|
||||
mBgVisible( TRUE ),
|
||||
mHasSelection( FALSE ),
|
||||
@@ -2257,6 +2244,11 @@ void LLMenuGL::removeChild( LLView* ctrl)
|
||||
return LLUICtrl::removeChild(ctrl);
|
||||
}
|
||||
|
||||
BOOL LLMenuGL::postBuild()
|
||||
{
|
||||
return LLUICtrl::postBuild();
|
||||
}
|
||||
|
||||
// are we the childmost active menu and hence our jump keys should be enabled?
|
||||
// or are we a free-standing torn-off menu (which uses jump keys too)
|
||||
BOOL LLMenuGL::jumpKeysActive()
|
||||
|
||||
@@ -57,8 +57,7 @@ S32 LLMultiSlider::mNameCounter = 0;
|
||||
LLMultiSlider::LLMultiSlider(
|
||||
const std::string& name,
|
||||
const LLRect& rect,
|
||||
void (*on_commit_callback)(LLUICtrl* ctrl, void* userdata),
|
||||
void* callback_userdata,
|
||||
commit_callback_t commit_callback,
|
||||
F32 initial_value,
|
||||
F32 min_value,
|
||||
F32 max_value,
|
||||
@@ -69,8 +68,7 @@ LLMultiSlider::LLMultiSlider(
|
||||
BOOL use_triangle,
|
||||
const std::string& control_name)
|
||||
:
|
||||
LLUICtrl( name, rect, TRUE, on_commit_callback, callback_userdata,
|
||||
FOLLOWS_LEFT | FOLLOWS_TOP),
|
||||
LLUICtrl( name, rect, TRUE, commit_callback, FOLLOWS_LEFT | FOLLOWS_TOP),
|
||||
|
||||
mInitialValue( initial_value ),
|
||||
mMinValue( min_value ),
|
||||
@@ -659,7 +657,6 @@ LLView* LLMultiSlider::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactor
|
||||
LLMultiSlider* multiSlider = new LLMultiSlider(name,
|
||||
rect,
|
||||
NULL,
|
||||
NULL,
|
||||
initial_value,
|
||||
min_value,
|
||||
max_value,
|
||||
|
||||
@@ -44,8 +44,7 @@ public:
|
||||
LLMultiSlider(
|
||||
const std::string& name,
|
||||
const LLRect& rect,
|
||||
void (*on_commit_callback)(LLUICtrl* ctrl, void* userdata),
|
||||
void* callback_userdata,
|
||||
commit_callback_t commit_callback,
|
||||
F32 initial_value,
|
||||
F32 min_value,
|
||||
F32 max_value,
|
||||
|
||||
@@ -60,14 +60,12 @@ LLMultiSliderCtrl::LLMultiSliderCtrl(const std::string& name, const LLRect& rect
|
||||
S32 text_left,
|
||||
BOOL show_text,
|
||||
BOOL can_edit_text,
|
||||
void (*commit_callback)(LLUICtrl*, void*),
|
||||
void* callback_user_data,
|
||||
F32 initial_value, F32 min_value, F32 max_value, F32 increment,
|
||||
S32 max_sliders, BOOL allow_overlap,
|
||||
BOOL draw_track,
|
||||
BOOL use_triangle,
|
||||
const std::string& control_which)
|
||||
: LLUICtrl(name, rect, TRUE, commit_callback, callback_user_data ),
|
||||
: LLUICtrl(name, rect, TRUE ),
|
||||
mFont(font),
|
||||
mShowText( show_text ),
|
||||
mCanEditText( can_edit_text ),
|
||||
@@ -107,7 +105,7 @@ LLMultiSliderCtrl::LLMultiSliderCtrl(const std::string& name, const LLRect& rect
|
||||
mMultiSlider = new LLMultiSlider(
|
||||
std::string("multi_slider"),
|
||||
slider_rect,
|
||||
LLMultiSliderCtrl::onSliderCommit, this,
|
||||
boost::bind(&LLMultiSliderCtrl::onSliderCommit,this,_2),
|
||||
initial_value, min_value, max_value, increment,
|
||||
max_sliders, allow_overlap, draw_track,
|
||||
use_triangle,
|
||||
@@ -123,8 +121,10 @@ LLMultiSliderCtrl::LLMultiSliderCtrl(const std::string& name, const LLRect& rect
|
||||
mEditor = new LLLineEditor( std::string("MultiSliderCtrl Editor"), text_rect,
|
||||
LLStringUtil::null, font,
|
||||
MAX_STRING_LENGTH,
|
||||
&LLMultiSliderCtrl::onEditorCommit, NULL, NULL, this,
|
||||
&LLLineEditor::prevalidateFloat );
|
||||
boost::bind(&LLMultiSliderCtrl::onEditorCommit,this,_2),
|
||||
NULL,
|
||||
NULL,
|
||||
boost::bind(&LLLineEditor::prevalidateFloat, _1) );
|
||||
mEditor->setFollowsLeft();
|
||||
mEditor->setFollowsBottom();
|
||||
mEditor->setFocusReceivedCallback( boost::bind(&LLMultiSliderCtrl::onFocusReceived, this) );
|
||||
@@ -278,26 +278,22 @@ void LLMultiSliderCtrl::updateText()
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLMultiSliderCtrl::onEditorCommit( LLUICtrl* caller, void *userdata )
|
||||
void LLMultiSliderCtrl::onEditorCommit(const LLSD& value)
|
||||
{
|
||||
LLMultiSliderCtrl* self = (LLMultiSliderCtrl*) userdata;
|
||||
llassert( caller == self->mEditor );
|
||||
|
||||
BOOL success = FALSE;
|
||||
F32 val = self->mCurValue;
|
||||
F32 saved_val = self->mCurValue;
|
||||
F32 val = mCurValue;
|
||||
F32 saved_val = mCurValue;
|
||||
|
||||
std::string text = self->mEditor->getText();
|
||||
std::string text = value.asString();
|
||||
if( LLLineEditor::postvalidateFloat( text ) )
|
||||
{
|
||||
LLLocale locale(LLLocale::USER_LOCALE);
|
||||
val = (F32) atof( text.c_str() );
|
||||
if( self->mMultiSlider->getMinValue() <= val && val <= self->mMultiSlider->getMaxValue() )
|
||||
if( mMultiSlider->getMinValue() <= val && val <= mMultiSlider->getMaxValue() )
|
||||
{
|
||||
self->setCurSliderValue( val );
|
||||
if( (!self->mValidateCallback || self->mValidateCallback( self, self->mCallbackUserData )) &&
|
||||
(!self->mValidateSignal || (*(self->mValidateSignal))(self, val)))
|
||||
setCurSliderValue( val );
|
||||
if( (!mValidateCallback || mValidateCallback( this, mCallbackUserData )) &&
|
||||
(!mValidateSignal || (*(mValidateSignal))(this, val)))
|
||||
{
|
||||
success = TRUE;
|
||||
}
|
||||
@@ -306,49 +302,45 @@ void LLMultiSliderCtrl::onEditorCommit( LLUICtrl* caller, void *userdata )
|
||||
|
||||
if( success )
|
||||
{
|
||||
self->onCommit();
|
||||
onCommit();
|
||||
}
|
||||
else
|
||||
{
|
||||
if( self->getCurSliderValue() != saved_val )
|
||||
if( getCurSliderValue() != saved_val )
|
||||
{
|
||||
self->setCurSliderValue( saved_val );
|
||||
setCurSliderValue( saved_val );
|
||||
}
|
||||
self->reportInvalidData();
|
||||
reportInvalidData();
|
||||
}
|
||||
self->updateText();
|
||||
updateText();
|
||||
}
|
||||
|
||||
// static
|
||||
void LLMultiSliderCtrl::onSliderCommit( LLUICtrl* caller, void *userdata )
|
||||
void LLMultiSliderCtrl::onSliderCommit(const LLSD& value)
|
||||
{
|
||||
LLMultiSliderCtrl* self = (LLMultiSliderCtrl*) userdata;
|
||||
//llassert( caller == self->mSlider );
|
||||
|
||||
BOOL success = FALSE;
|
||||
F32 saved_val = self->mCurValue;
|
||||
F32 new_val = self->mMultiSlider->getCurSliderValue();
|
||||
F32 saved_val = mCurValue;
|
||||
F32 new_val = mMultiSlider->getCurSliderValue();
|
||||
|
||||
self->mCurValue = new_val; // set the value temporarily so that the callback can retrieve it.
|
||||
if( (!self->mValidateCallback || self->mValidateCallback( self, self->mCallbackUserData )) &&
|
||||
(!self->mValidateSignal || (*(self->mValidateSignal))(self, new_val )))
|
||||
mCurValue = new_val; // set the value temporarily so that the callback can retrieve it.
|
||||
if( (!mValidateCallback || mValidateCallback( this, mCallbackUserData )) &&
|
||||
(!mValidateSignal || (*mValidateSignal)(this, new_val ) ))
|
||||
{
|
||||
success = TRUE;
|
||||
}
|
||||
|
||||
if( success )
|
||||
{
|
||||
self->onCommit();
|
||||
onCommit();
|
||||
}
|
||||
else
|
||||
{
|
||||
if( self->mCurValue != saved_val )
|
||||
if( mCurValue != saved_val )
|
||||
{
|
||||
self->setCurSliderValue( saved_val );
|
||||
setCurSliderValue( saved_val );
|
||||
}
|
||||
self->reportInvalidData();
|
||||
reportInvalidData();
|
||||
}
|
||||
self->updateText();
|
||||
updateText();
|
||||
}
|
||||
|
||||
void LLMultiSliderCtrl::setEnabled(BOOL b)
|
||||
@@ -561,8 +553,6 @@ LLView* LLMultiSliderCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFa
|
||||
}
|
||||
}
|
||||
|
||||
LLUICtrlCallback callback = NULL;
|
||||
|
||||
if (label.empty())
|
||||
{
|
||||
label.assign(node->getTextContents());
|
||||
@@ -576,8 +566,6 @@ LLView* LLMultiSliderCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFa
|
||||
rect.getWidth() - text_left,
|
||||
show_text,
|
||||
can_edit_text,
|
||||
callback,
|
||||
NULL,
|
||||
initial_value,
|
||||
min_value,
|
||||
max_value,
|
||||
|
||||
@@ -64,8 +64,6 @@ public:
|
||||
S32 text_left,
|
||||
BOOL show_text,
|
||||
BOOL can_edit_text,
|
||||
void (*commit_callback)(LLUICtrl*, void*),
|
||||
void* callback_userdata,
|
||||
F32 initial_value, F32 min_value, F32 max_value, F32 increment,
|
||||
S32 max_sliders, BOOL allow_overlap, BOOL draw_track,
|
||||
BOOL use_triangle,
|
||||
@@ -123,10 +121,9 @@ public:
|
||||
virtual void setControlName(const std::string& control_name, LLView* context);
|
||||
virtual std::string getControlName() const;
|
||||
|
||||
static void onSliderCommit(LLUICtrl* caller, void* userdata);
|
||||
void onSliderCommit(const LLSD& value);
|
||||
|
||||
static void onEditorCommit(LLUICtrl* ctrl, void* userdata);
|
||||
static void onEditorChangeFocus(LLUICtrl* caller, S32 direction, void *userdata);
|
||||
void onEditorCommit(const LLSD& value);
|
||||
|
||||
private:
|
||||
void updateText();
|
||||
|
||||
@@ -880,6 +880,7 @@ bool LLNotificationChannelBase::updateItem(const LLSD& payload, LLNotificationPt
|
||||
assert(!wasFound);
|
||||
if (passesFilter)
|
||||
{
|
||||
llinfos << "Inserting " << pNotification->getName() << llendl;
|
||||
// not in our list, add it and say so
|
||||
mItems.insert(pNotification);
|
||||
abortProcessing = mChanged(payload);
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
|
||||
#include "llpanel.h"
|
||||
|
||||
#include "llalertdialog.h"
|
||||
#include "llfocusmgr.h"
|
||||
#include "llfontgl.h"
|
||||
#include "lllocalcliprect.h"
|
||||
@@ -92,7 +91,7 @@ LLPanel::LLPanel()
|
||||
}
|
||||
|
||||
LLPanel::LLPanel(const std::string& name)
|
||||
: LLUICtrl(name, LLRect(0, 0, 0, 0), TRUE, NULL, NULL),
|
||||
: LLUICtrl(name),
|
||||
mRectControl()
|
||||
{
|
||||
init();
|
||||
@@ -100,7 +99,7 @@ LLPanel::LLPanel(const std::string& name)
|
||||
|
||||
|
||||
LLPanel::LLPanel(const std::string& name, const LLRect& rect, BOOL bordered)
|
||||
: LLUICtrl(name, rect, TRUE, NULL, NULL),
|
||||
: LLUICtrl(name,rect),
|
||||
mRectControl()
|
||||
{
|
||||
init();
|
||||
@@ -112,7 +111,7 @@ LLPanel::LLPanel(const std::string& name, const LLRect& rect, BOOL bordered)
|
||||
|
||||
|
||||
LLPanel::LLPanel(const std::string& name, const std::string& rect_control, BOOL bordered)
|
||||
: LLUICtrl(name, LLUI::sConfigGroup->getRect(rect_control), TRUE, NULL, NULL),
|
||||
: LLUICtrl(name, LLUI::sConfigGroup->getRect(rect_control)),
|
||||
mRectControl( rect_control )
|
||||
{
|
||||
init();
|
||||
@@ -186,19 +185,14 @@ void LLPanel::draw()
|
||||
// draw background
|
||||
if( mBgVisible )
|
||||
{
|
||||
//RN: I don't see the point of this
|
||||
S32 left = 0;//LLPANEL_BORDER_WIDTH;
|
||||
S32 top = getRect().getHeight();// - LLPANEL_BORDER_WIDTH;
|
||||
S32 right = getRect().getWidth();// - LLPANEL_BORDER_WIDTH;
|
||||
S32 bottom = 0;//LLPANEL_BORDER_WIDTH;
|
||||
|
||||
LLRect local_rect = getLocalRect();
|
||||
if (mBgOpaque )
|
||||
{
|
||||
gl_rect_2d( left, top, right, bottom, mBgColorOpaque );
|
||||
gl_rect_2d( local_rect, mBgColorOpaque );
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_rect_2d( left, top, right, bottom, mBgColorAlpha );
|
||||
gl_rect_2d( local_rect, mBgColorAlpha );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -611,6 +605,11 @@ void LLPanel::setPanelParameters(LLXMLNodePtr node, LLView* parent)
|
||||
setLabel(label);
|
||||
}
|
||||
|
||||
bool LLPanel::hasString(const std::string& name)
|
||||
{
|
||||
return mUIStrings.find(name) != mUIStrings.end();
|
||||
}
|
||||
|
||||
std::string LLPanel::getString(const std::string& name, const LLStringUtil::format_map_t& args) const
|
||||
{
|
||||
ui_string_map_t::const_iterator found_it = mUIStrings.find(name);
|
||||
@@ -916,29 +915,6 @@ LLPanel *LLPanel::childGetVisibleTab(const std::string& id) const
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void LLPanel::childSetKeystrokeCallback(const std::string& id, void (*keystroke_callback)(LLLineEditor* caller, void* user_data), void *user_data)
|
||||
{
|
||||
LLLineEditor* child = getChild<LLLineEditor>(id);
|
||||
if (child)
|
||||
{
|
||||
child->setKeystrokeCallback(keystroke_callback);
|
||||
if (user_data)
|
||||
{
|
||||
child->setCallbackUserData(user_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanel::childSetPrevalidate(const std::string& id, BOOL (*func)(const LLWString &) )
|
||||
{
|
||||
LLLineEditor* child = getChild<LLLineEditor>(id);
|
||||
if (child)
|
||||
{
|
||||
child->setPrevalidate(func);
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanel::childSetWrappedText(const std::string& id, const std::string& text, bool visible)
|
||||
{
|
||||
LLTextBox* child = getChild<LLTextBox>(id);
|
||||
@@ -949,14 +925,7 @@ void LLPanel::childSetWrappedText(const std::string& id, const std::string& text
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanel::childSetAction(const std::string& id, boost::function<void(void*)> function, void* value)
|
||||
{
|
||||
LLButton* button = getChild<LLButton>(id);
|
||||
if (button)
|
||||
{
|
||||
button->setClickedCallback(function, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LLPanel::childSetAction(const std::string& id, const commit_signal_t::slot_type& function)
|
||||
{
|
||||
@@ -967,12 +936,21 @@ void LLPanel::childSetAction(const std::string& id, const commit_signal_t::slot_
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanel::childSetActionTextbox(const std::string& id, void(*function)(void*), void* value)
|
||||
void LLPanel::childSetAction(const std::string& id, boost::function<void(void*)> function, void* value)
|
||||
{
|
||||
LLButton* button = getChild<LLButton>(id);
|
||||
if (button)
|
||||
{
|
||||
button->setClickedCallback(boost::bind(function, value));
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanel::childSetActionTextbox(const std::string& id, boost::function<void(void*)> function, void* value)
|
||||
{
|
||||
LLTextBox* textbox = getChild<LLTextBox>(id);
|
||||
if (textbox)
|
||||
{
|
||||
textbox->setClickedCallback(function, value);
|
||||
textbox->setClickedCallback(boost::bind(function, value));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1075,7 +1053,13 @@ struct LLLayoutStack::LLEmbeddedPanel
|
||||
{
|
||||
min_dim = mMinWidth;
|
||||
}
|
||||
mResizeBar = new LLResizeBar(std::string("resizer"), mPanel, LLRect(), min_dim, S32_MAX, side);
|
||||
LLResizeBar::Params p;
|
||||
p.name = "resizer";
|
||||
p.resizing_view = mPanel;
|
||||
p.min_size = min_dim;
|
||||
p.max_size = S32_MAX;
|
||||
p.side = side;
|
||||
mResizeBar = LLUICtrlFactory::create<LLResizeBar>(p);
|
||||
mResizeBar->setEnableSnapping(FALSE);
|
||||
// panels initialized as hidden should not start out partially visible
|
||||
if (!mPanel->getVisible())
|
||||
|
||||
@@ -144,6 +144,7 @@ public:
|
||||
void initChildrenXML(LLXMLNodePtr node, LLUICtrlFactory* factory);
|
||||
void setPanelParameters(LLXMLNodePtr node, LLView *parentp);
|
||||
|
||||
bool hasString(const std::string& name);
|
||||
std::string getString(const std::string& name, const LLStringUtil::format_map_t& args) const;
|
||||
std::string getString(const std::string& name) const;
|
||||
|
||||
@@ -205,14 +206,13 @@ public:
|
||||
void childSetText(const std::string& id, const LLStringExplicit& text) { childSetValue(id, LLSD(text)); }
|
||||
std::string childGetText(const std::string& id) const { return childGetValue(id).asString(); }
|
||||
|
||||
// LLLineEditor
|
||||
void childSetKeystrokeCallback(const std::string& id, void (*keystroke_callback)(LLLineEditor* caller, void* user_data), void *user_data);
|
||||
void childSetPrevalidate(const std::string& id, BOOL (*func)(const LLWString &) );
|
||||
|
||||
// LLButton
|
||||
void childSetAction(const std::string& id, boost::function<void(void*)> function, void* value);
|
||||
void childSetAction(const std::string& id, const commit_signal_t::slot_type& function);
|
||||
void childSetActionTextbox(const std::string& id, void(*function)(void*), void* value = NULL);
|
||||
|
||||
// LLTextBox
|
||||
void childSetActionTextbox(const std::string& id, boost::function<void(void*)> function, void* value = NULL);
|
||||
|
||||
void childSetControlName(const std::string& id, const std::string& control_name);
|
||||
|
||||
// Error reporting
|
||||
|
||||
@@ -47,19 +47,9 @@
|
||||
static LLRegisterWidget<LLRadioGroup> r("radio_group");
|
||||
|
||||
LLRadioGroup::LLRadioGroup(const std::string& name, const LLRect& rect,
|
||||
const std::string& control_name, LLUICtrlCallback callback,
|
||||
void* userdata, BOOL border) :
|
||||
LLUICtrl(name, rect, TRUE, callback, userdata, FOLLOWS_LEFT | FOLLOWS_TOP),
|
||||
mSelectedIndex(0)
|
||||
{
|
||||
setControlName(control_name, NULL);
|
||||
init(border);
|
||||
}
|
||||
|
||||
LLRadioGroup::LLRadioGroup(const std::string& name, const LLRect& rect,
|
||||
S32 initial_index, LLUICtrlCallback callback,
|
||||
void* userdata, BOOL border) :
|
||||
LLUICtrl(name, rect, TRUE, callback, userdata, FOLLOWS_LEFT | FOLLOWS_TOP),
|
||||
S32 initial_index, commit_callback_t commit_callback,
|
||||
BOOL border) :
|
||||
LLUICtrl(name, rect, TRUE, commit_callback, FOLLOWS_LEFT | FOLLOWS_TOP),
|
||||
mSelectedIndex(initial_index)
|
||||
{
|
||||
init(border);
|
||||
@@ -251,7 +241,7 @@ void LLRadioGroup::draw()
|
||||
LLRadioCtrl* LLRadioGroup::addRadioButton(const std::string& name, const std::string& label, const LLRect& rect, const LLFontGL* font )
|
||||
{
|
||||
// Highlight will get fixed in draw method above
|
||||
LLRadioCtrl* radio = new LLRadioCtrl(name, rect, label, font, onClickButton, this);
|
||||
LLRadioCtrl* radio = new LLRadioCtrl(name, rect, label, font, boost::bind(&LLRadioGroup::onClickButton, this, _1));
|
||||
addChild(radio);
|
||||
mRadioButtons.push_back(radio);
|
||||
return radio;
|
||||
@@ -260,32 +250,30 @@ LLRadioCtrl* LLRadioGroup::addRadioButton(const std::string& name, const std::st
|
||||
// Handle one button being clicked. All child buttons must have this
|
||||
// function as their callback function.
|
||||
|
||||
// static
|
||||
void LLRadioGroup::onClickButton(LLUICtrl* ui_ctrl, void* userdata)
|
||||
void LLRadioGroup::onClickButton(LLUICtrl* ctrl)
|
||||
{
|
||||
// llinfos << "LLRadioGroup::onClickButton" << llendl;
|
||||
|
||||
LLRadioCtrl* clickedRadio = (LLRadioCtrl*) ui_ctrl;
|
||||
LLRadioGroup* self = (LLRadioGroup*) userdata;
|
||||
|
||||
S32 counter = 0;
|
||||
for (button_list_t::iterator iter = self->mRadioButtons.begin();
|
||||
iter != self->mRadioButtons.end(); ++iter)
|
||||
LLRadioCtrl* clicked_radio = dynamic_cast<LLRadioCtrl*>(ctrl);
|
||||
if (!clicked_radio)
|
||||
return;
|
||||
S32 index = 0;
|
||||
for (button_list_t::iterator iter = mRadioButtons.begin();
|
||||
iter != mRadioButtons.end(); ++iter)
|
||||
{
|
||||
LLRadioCtrl* radio = *iter;
|
||||
if (radio == clickedRadio)
|
||||
if (radio == clicked_radio)
|
||||
{
|
||||
// llinfos << "clicked button " << counter << llendl;
|
||||
self->setSelectedIndex(counter);
|
||||
self->setControlValue(counter);
|
||||
setSelectedIndex(index);
|
||||
setControlValue(index);
|
||||
|
||||
// BUG: Calls click callback even if button didn't actually change
|
||||
self->onCommit();
|
||||
onCommit();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
counter++;
|
||||
index++;
|
||||
}
|
||||
|
||||
llwarns << "LLRadioGroup::onClickButton - clicked button that isn't a child" << llendl;
|
||||
@@ -380,7 +368,6 @@ LLView* LLRadioGroup::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory
|
||||
rect,
|
||||
initial_value,
|
||||
NULL,
|
||||
NULL,
|
||||
draw_border);
|
||||
|
||||
const std::string& contents = node->getValue();
|
||||
|
||||
@@ -45,8 +45,8 @@ class LLRadioCtrl : public LLCheckBoxCtrl
|
||||
{
|
||||
public:
|
||||
LLRadioCtrl(const std::string& name, const LLRect& rect, const std::string& label, const LLFontGL* font = NULL,
|
||||
void (*commit_callback)(LLUICtrl*, void*) = NULL, void* callback_userdata = NULL) :
|
||||
LLCheckBoxCtrl(name, rect, label, font, commit_callback, callback_userdata, FALSE, RADIO_STYLE)
|
||||
commit_callback_t commit_callback = NULL) :
|
||||
LLCheckBoxCtrl(name, rect, label, font, commit_callback, FALSE, RADIO_STYLE)
|
||||
{
|
||||
setTabStop(FALSE);
|
||||
}
|
||||
@@ -66,21 +66,11 @@ class LLRadioGroup
|
||||
: public LLUICtrl, public LLCtrlSelectionInterface
|
||||
{
|
||||
public:
|
||||
// Build a radio group. The number (0...n-1) of the currently selected
|
||||
// element will be stored in the named control. After the control is
|
||||
// changed the callback will be called.
|
||||
LLRadioGroup(const std::string& name, const LLRect& rect,
|
||||
const std::string& control_name,
|
||||
LLUICtrlCallback callback = NULL,
|
||||
void* userdata = NULL,
|
||||
BOOL border = TRUE);
|
||||
|
||||
// Another radio group constructor, but this one doesn't rely on
|
||||
// Radio group constructor. Doesn't rely on
|
||||
// needing a control
|
||||
LLRadioGroup(const std::string& name, const LLRect& rect,
|
||||
S32 initial_index,
|
||||
LLUICtrlCallback callback = NULL,
|
||||
void* userdata = NULL,
|
||||
commit_callback_t commit_callback,
|
||||
BOOL border = TRUE);
|
||||
|
||||
virtual ~LLRadioGroup();
|
||||
@@ -111,7 +101,7 @@ public:
|
||||
LLRadioCtrl* addRadioButton(const std::string& name, const std::string& label, const LLRect& rect, const LLFontGL* font);
|
||||
LLRadioCtrl* getRadioButton(const S32& index) { return mRadioButtons[index]; }
|
||||
// Update the control as needed. Userdata must be a pointer to the button.
|
||||
static void onClickButton(LLUICtrl* radio, void* userdata);
|
||||
void onClickButton(LLUICtrl* clicked_radio);
|
||||
|
||||
//========================================================================
|
||||
LLCtrlSelectionInterface* getSelectionInterface() { return (LLCtrlSelectionInterface*)this; };
|
||||
|
||||
@@ -40,23 +40,22 @@
|
||||
#include "llfocusmgr.h"
|
||||
#include "llwindow.h"
|
||||
|
||||
LLResizeBar::LLResizeBar( const std::string& name, LLView* resizing_view, const LLRect& rect, S32 min_size, S32 max_size, Side side )
|
||||
:
|
||||
LLView( name, rect, TRUE ),
|
||||
LLResizeBar::LLResizeBar(const LLResizeBar::Params& p)
|
||||
: LLView(p),
|
||||
mDragLastScreenX( 0 ),
|
||||
mDragLastScreenY( 0 ),
|
||||
mLastMouseScreenX( 0 ),
|
||||
mLastMouseScreenY( 0 ),
|
||||
mMinSize( min_size ),
|
||||
mMaxSize( max_size ),
|
||||
mSide( side ),
|
||||
mSnappingEnabled(TRUE),
|
||||
mAllowDoubleClickSnapping(TRUE),
|
||||
mResizingView(resizing_view)
|
||||
mMinSize( p.min_size ),
|
||||
mMaxSize( p.max_size ),
|
||||
mSide( p.side ),
|
||||
mSnappingEnabled(p.snapping_enabled),
|
||||
mAllowDoubleClickSnapping(p.allow_double_click_snapping),
|
||||
mResizingView(p.resizing_view)
|
||||
{
|
||||
setFollowsNone();
|
||||
// set up some generically good follow code.
|
||||
switch( side )
|
||||
switch( mSide )
|
||||
{
|
||||
case LEFT:
|
||||
setFollowsLeft();
|
||||
@@ -180,6 +179,11 @@ BOOL LLResizeBar::handleHover(S32 x, S32 y, MASK mask)
|
||||
break;
|
||||
}
|
||||
|
||||
notifyParent(LLSD().with("action", "resize")
|
||||
.with("view_name", mResizingView->getName())
|
||||
.with("new_height", new_height)
|
||||
.with("new_width", new_width));
|
||||
|
||||
scaled_rect.mTop = scaled_rect.mBottom + new_height;
|
||||
scaled_rect.mRight = scaled_rect.mLeft + new_width;
|
||||
mResizingView->setRect(scaled_rect);
|
||||
@@ -188,8 +192,7 @@ BOOL LLResizeBar::handleHover(S32 x, S32 y, MASK mask)
|
||||
|
||||
if (mSnappingEnabled)
|
||||
{
|
||||
//static LLCachedControl<S32> snap_margin (*LLUI::sConfigGroup,"SnapMargin", 0);
|
||||
S32 snap_margin = LLUI::sConfigGroup->getS32("SnapMargin");
|
||||
static LLUICachedControl<S32> snap_margin ("SnapMargin", 0);
|
||||
switch( mSide )
|
||||
{
|
||||
case LEFT:
|
||||
@@ -220,17 +223,62 @@ BOOL LLResizeBar::handleHover(S32 x, S32 y, MASK mask)
|
||||
switch(mSide)
|
||||
{
|
||||
case LEFT:
|
||||
mDragLastScreenX += new_rect.mLeft - orig_rect.mLeft;
|
||||
{
|
||||
S32 actual_delta_x = new_rect.mLeft - orig_rect.mLeft;
|
||||
if (actual_delta_x != delta_x)
|
||||
{
|
||||
// restore everything by left
|
||||
new_rect.mBottom = orig_rect.mBottom;
|
||||
new_rect.mTop = orig_rect.mTop;
|
||||
new_rect.mRight = orig_rect.mRight;
|
||||
mResizingView->setShape(new_rect, true);
|
||||
}
|
||||
mDragLastScreenX += actual_delta_x;
|
||||
|
||||
break;
|
||||
}
|
||||
case RIGHT:
|
||||
{
|
||||
S32 actual_delta_x = new_rect.mRight - orig_rect.mRight;
|
||||
if (actual_delta_x != delta_x)
|
||||
{
|
||||
// restore everything by left
|
||||
new_rect.mBottom = orig_rect.mBottom;
|
||||
new_rect.mTop = orig_rect.mTop;
|
||||
new_rect.mLeft = orig_rect.mLeft;
|
||||
mResizingView->setShape(new_rect, true);
|
||||
}
|
||||
mDragLastScreenX += new_rect.mRight - orig_rect.mRight;
|
||||
break;
|
||||
}
|
||||
case TOP:
|
||||
{
|
||||
S32 actual_delta_y = new_rect.mTop - orig_rect.mTop;
|
||||
if (actual_delta_y != delta_y)
|
||||
{
|
||||
// restore everything by left
|
||||
new_rect.mBottom = orig_rect.mBottom;
|
||||
new_rect.mLeft = orig_rect.mLeft;
|
||||
new_rect.mRight = orig_rect.mRight;
|
||||
mResizingView->setShape(new_rect, true);
|
||||
}
|
||||
mDragLastScreenY += new_rect.mTop - orig_rect.mTop;
|
||||
break;
|
||||
}
|
||||
case BOTTOM:
|
||||
{
|
||||
S32 actual_delta_y = new_rect.mBottom - orig_rect.mBottom;
|
||||
if (actual_delta_y != delta_y)
|
||||
{
|
||||
// restore everything by left
|
||||
new_rect.mTop = orig_rect.mTop;
|
||||
new_rect.mLeft = orig_rect.mLeft;
|
||||
new_rect.mRight = orig_rect.mRight;
|
||||
mResizingView->setShape(new_rect, true);
|
||||
}
|
||||
mDragLastScreenY += new_rect.mBottom- orig_rect.mBottom;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -41,7 +41,31 @@ class LLResizeBar : public LLView
|
||||
public:
|
||||
enum Side { LEFT, TOP, RIGHT, BOTTOM };
|
||||
|
||||
LLResizeBar(const std::string& name, LLView* resizing_view, const LLRect& rect, S32 min_size, S32 max_size, Side side );
|
||||
struct Params : public LLInitParam::Block<Params, LLView::Params>
|
||||
{
|
||||
Mandatory<LLView*> resizing_view;
|
||||
Mandatory<Side> side;
|
||||
|
||||
Optional<S32> min_size;
|
||||
Optional<S32> max_size;
|
||||
Optional<bool> snapping_enabled;
|
||||
Optional<bool> allow_double_click_snapping;
|
||||
|
||||
Params()
|
||||
: max_size("max_size", S32_MAX),
|
||||
snapping_enabled("snapping_enabled", true),
|
||||
resizing_view("resizing_view"),
|
||||
side("side"),
|
||||
allow_double_click_snapping("allow_double_click_snapping", true)
|
||||
{
|
||||
name = "resize_bar";
|
||||
}
|
||||
};
|
||||
|
||||
protected:
|
||||
LLResizeBar(const LLResizeBar::Params& p);
|
||||
friend class LLUICtrlFactory;
|
||||
public:
|
||||
|
||||
// virtual void draw(); No appearance
|
||||
virtual BOOL handleHover(S32 x, S32 y, MASK mask);
|
||||
|
||||
@@ -44,31 +44,36 @@
|
||||
|
||||
const S32 RESIZE_BORDER_WIDTH = 3;
|
||||
|
||||
LLResizeHandle::LLResizeHandle( const std::string& name, const LLRect& rect, S32 min_width, S32 min_height, ECorner corner )
|
||||
:
|
||||
LLView( name, rect, FALSE ),
|
||||
LLResizeHandle::Params::Params()
|
||||
: corner("corner"),
|
||||
min_width("min_width"),
|
||||
min_height("min_height")
|
||||
{
|
||||
name = "resize_handle";
|
||||
}
|
||||
|
||||
LLResizeHandle::LLResizeHandle(const LLResizeHandle::Params& p)
|
||||
: LLView(p),
|
||||
mDragLastScreenX( 0 ),
|
||||
mDragLastScreenY( 0 ),
|
||||
mLastMouseScreenX( 0 ),
|
||||
mLastMouseScreenY( 0 ),
|
||||
mImage( NULL ),
|
||||
mMinWidth( min_width ),
|
||||
mMinHeight( min_height ),
|
||||
mCorner( corner )
|
||||
mMinWidth( p.min_width ),
|
||||
mMinHeight( p.min_height ),
|
||||
mCorner( p.corner )
|
||||
{
|
||||
setSaveToXML(false);
|
||||
|
||||
if( RIGHT_BOTTOM == mCorner)
|
||||
{
|
||||
mImage = LLUI::getUIImage("UIImgResizeBottomRightUUID");
|
||||
}
|
||||
|
||||
switch( mCorner )
|
||||
switch( p.corner )
|
||||
{
|
||||
case LEFT_TOP: setFollows( FOLLOWS_LEFT | FOLLOWS_TOP ); break;
|
||||
case LEFT_BOTTOM: setFollows( FOLLOWS_LEFT | FOLLOWS_BOTTOM ); break;
|
||||
case RIGHT_TOP: setFollows( FOLLOWS_RIGHT | FOLLOWS_TOP ); break;
|
||||
case RIGHT_BOTTOM: setFollows( FOLLOWS_RIGHT | FOLLOWS_BOTTOM ); break;
|
||||
case LEFT_TOP: setFollows( FOLLOWS_LEFT | FOLLOWS_TOP ); break;
|
||||
case LEFT_BOTTOM: setFollows( FOLLOWS_LEFT | FOLLOWS_BOTTOM ); break;
|
||||
case RIGHT_TOP: setFollows( FOLLOWS_RIGHT | FOLLOWS_TOP ); break;
|
||||
case RIGHT_BOTTOM: setFollows( FOLLOWS_RIGHT | FOLLOWS_BOTTOM ); break;
|
||||
}
|
||||
|
||||
// decorator object, don't serialize
|
||||
@@ -205,8 +210,7 @@ BOOL LLResizeHandle::handleHover(S32 x, S32 y, MASK mask)
|
||||
LLView* snap_view = NULL;
|
||||
LLView* test_view = NULL;
|
||||
|
||||
//static LLCachedControl<S32> snap_margin (*LLUI::sConfigGroup,"SnapMargin", 0);
|
||||
S32 snap_margin = LLUI::sConfigGroup->getS32("SnapMargin");
|
||||
static LLUICachedControl<S32> snap_margin ("SnapMargin", 0);
|
||||
// now do snapping
|
||||
switch(mCorner)
|
||||
{
|
||||
@@ -255,23 +259,65 @@ BOOL LLResizeHandle::handleHover(S32 x, S32 y, MASK mask)
|
||||
|
||||
// update last valid mouse cursor position based on resized view's actual size
|
||||
LLRect new_rect = resizing_view->getRect();
|
||||
S32 actual_delta_x = 0;
|
||||
S32 actual_delta_y = 0;
|
||||
switch(mCorner)
|
||||
{
|
||||
case LEFT_TOP:
|
||||
mDragLastScreenX += new_rect.mLeft - orig_rect.mLeft;
|
||||
mDragLastScreenY += new_rect.mTop - orig_rect.mTop;
|
||||
actual_delta_x = new_rect.mLeft - orig_rect.mLeft;
|
||||
actual_delta_y = new_rect.mTop - orig_rect.mTop;
|
||||
if (actual_delta_x != delta_x
|
||||
|| actual_delta_y != delta_y)
|
||||
{
|
||||
new_rect.mRight = orig_rect.mRight;
|
||||
new_rect.mBottom = orig_rect.mBottom;
|
||||
resizing_view->setShape(new_rect, true);
|
||||
}
|
||||
|
||||
mDragLastScreenX += actual_delta_x;
|
||||
mDragLastScreenY += actual_delta_y;
|
||||
break;
|
||||
case LEFT_BOTTOM:
|
||||
mDragLastScreenX += new_rect.mLeft - orig_rect.mLeft;
|
||||
mDragLastScreenY += new_rect.mBottom- orig_rect.mBottom;
|
||||
actual_delta_x = new_rect.mLeft - orig_rect.mLeft;
|
||||
actual_delta_y = new_rect.mBottom - orig_rect.mBottom;
|
||||
if (actual_delta_x != delta_x
|
||||
|| actual_delta_y != delta_y)
|
||||
{
|
||||
new_rect.mRight = orig_rect.mRight;
|
||||
new_rect.mTop = orig_rect.mTop;
|
||||
resizing_view->setShape(new_rect, true);
|
||||
}
|
||||
|
||||
mDragLastScreenX += actual_delta_x;
|
||||
mDragLastScreenY += actual_delta_y;
|
||||
break;
|
||||
case RIGHT_TOP:
|
||||
mDragLastScreenX += new_rect.mRight - orig_rect.mRight;
|
||||
mDragLastScreenY += new_rect.mTop - orig_rect.mTop;
|
||||
actual_delta_x = new_rect.mRight - orig_rect.mRight;
|
||||
actual_delta_y = new_rect.mTop - orig_rect.mTop;
|
||||
if (actual_delta_x != delta_x
|
||||
|| actual_delta_y != delta_y)
|
||||
{
|
||||
new_rect.mLeft = orig_rect.mLeft;
|
||||
new_rect.mBottom = orig_rect.mBottom;
|
||||
resizing_view->setShape(new_rect, true);
|
||||
}
|
||||
|
||||
mDragLastScreenX += actual_delta_x;
|
||||
mDragLastScreenY += actual_delta_y;
|
||||
break;
|
||||
case RIGHT_BOTTOM:
|
||||
mDragLastScreenX += new_rect.mRight - orig_rect.mRight;
|
||||
mDragLastScreenY += new_rect.mBottom- orig_rect.mBottom;
|
||||
actual_delta_x = new_rect.mRight - orig_rect.mRight;
|
||||
actual_delta_y = new_rect.mBottom - orig_rect.mBottom;
|
||||
if (actual_delta_x != delta_x
|
||||
|| actual_delta_y != delta_y)
|
||||
{
|
||||
new_rect.mLeft = orig_rect.mLeft;
|
||||
new_rect.mTop = orig_rect.mTop;
|
||||
resizing_view->setShape(new_rect, true);
|
||||
}
|
||||
|
||||
mDragLastScreenX += actual_delta_x;
|
||||
mDragLastScreenY += actual_delta_y;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
|
||||
#include "stdtypes.h"
|
||||
#include "llview.h"
|
||||
#include "llimagegl.h"
|
||||
#include "llcoord.h"
|
||||
|
||||
|
||||
@@ -44,9 +43,18 @@ class LLResizeHandle : public LLView
|
||||
public:
|
||||
enum ECorner { LEFT_TOP, LEFT_BOTTOM, RIGHT_TOP, RIGHT_BOTTOM };
|
||||
|
||||
|
||||
LLResizeHandle(const std::string& name, const LLRect& rect, S32 min_width, S32 min_height, ECorner corner = RIGHT_BOTTOM );
|
||||
struct Params : public LLInitParam::Block<Params, LLView::Params>
|
||||
{
|
||||
Mandatory<ECorner> corner;
|
||||
Optional<S32> min_width;
|
||||
Optional<S32> min_height;
|
||||
Params();
|
||||
};
|
||||
|
||||
protected:
|
||||
LLResizeHandle(const LLResizeHandle::Params&);
|
||||
friend class LLUICtrlFactory;
|
||||
public:
|
||||
virtual void draw();
|
||||
virtual BOOL handleHover(S32 x, S32 y, MASK mask);
|
||||
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
|
||||
|
||||
@@ -33,8 +33,7 @@
|
||||
|
||||
#include "llrootview.h"
|
||||
|
||||
LLRootView::LLRootView(const std::string& name, const LLRect& rect, BOOL mouse_opaque, U32 follows)
|
||||
: LLView(name,rect,mouse_opaque,follows)
|
||||
{ }
|
||||
|
||||
LLRootView::LLRootView(const Params& p)
|
||||
: LLView(p)
|
||||
{}
|
||||
// pretty exciting file, eh?
|
||||
|
||||
@@ -30,15 +30,15 @@
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LLROOTVIEW_H
|
||||
#define LLROOTVIEW_H
|
||||
#ifndef LL_LLROOTVIEW_H
|
||||
#define LL_LLROOTVIEW_H
|
||||
|
||||
#include "llview.h"
|
||||
|
||||
class LLRootView : public LLView
|
||||
{
|
||||
public:
|
||||
LLRootView(const std::string& name, const LLRect& rect, BOOL mouse_opaque, U32 follows=FOLLOWS_NONE);
|
||||
LLRootView(const Params& p) ;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -51,13 +51,11 @@ LLScrollbar::LLScrollbar(
|
||||
const std::string& name, LLRect rect,
|
||||
LLScrollbar::ORIENTATION orientation,
|
||||
S32 doc_size, S32 doc_pos, S32 page_size,
|
||||
void (*change_callback)( S32 new_pos, LLScrollbar* self, void* userdata ),
|
||||
void* callback_user_data,
|
||||
callback_t change_callback,
|
||||
S32 step_size)
|
||||
: LLUICtrl( name, rect, TRUE, NULL, NULL ),
|
||||
: LLUICtrl( name, rect ),
|
||||
|
||||
mChangeCallback( change_callback ),
|
||||
mCallbackUserData( callback_user_data ),
|
||||
mOrientation( orientation ),
|
||||
mDocSize( doc_size ),
|
||||
mDocPos( doc_pos ),
|
||||
@@ -115,7 +113,7 @@ LLScrollbar::LLScrollbar(
|
||||
|
||||
LLButton* line_up_btn = new LLButton(std::string("Line Up"), line_up_rect,
|
||||
line_up_img, line_up_selected_img, LLStringUtil::null,
|
||||
&LLScrollbar::onLineUpBtnPressed, this, LLFontGL::getFontSansSerif() );
|
||||
boost::bind(&LLScrollbar::onLineUpBtnPressed, this, _2), LLFontGL::getFontSansSerif() );
|
||||
if( LLScrollbar::VERTICAL == mOrientation )
|
||||
{
|
||||
line_up_btn->setFollowsRight();
|
||||
@@ -127,7 +125,7 @@ LLScrollbar::LLScrollbar(
|
||||
line_up_btn->setFollowsLeft();
|
||||
line_up_btn->setFollowsBottom();
|
||||
}
|
||||
line_up_btn->setHeldDownCallback( boost::bind(&LLScrollbar::onLineUpBtnPressed, (void*)this) );
|
||||
line_up_btn->setHeldDownCallback( boost::bind(&LLScrollbar::onLineUpBtnPressed, this, _2) );
|
||||
line_up_btn->setTabStop(FALSE);
|
||||
line_up_btn->setScaleImage(TRUE);
|
||||
|
||||
@@ -135,10 +133,10 @@ LLScrollbar::LLScrollbar(
|
||||
|
||||
LLButton* line_down_btn = new LLButton(std::string("Line Down"), line_down_rect,
|
||||
line_down_img, line_down_selected_img, LLStringUtil::null,
|
||||
&LLScrollbar::onLineDownBtnPressed, this, LLFontGL::getFontSansSerif() );
|
||||
boost::bind(&LLScrollbar::onLineDownBtnPressed, this, _2), LLFontGL::getFontSansSerif() );
|
||||
line_down_btn->setFollowsRight();
|
||||
line_down_btn->setFollowsBottom();
|
||||
line_down_btn->setHeldDownCallback( boost::bind(&LLScrollbar::onLineDownBtnPressed, this) );
|
||||
line_down_btn->setHeldDownCallback( boost::bind(&LLScrollbar::onLineDownBtnPressed, this, _2) );
|
||||
line_down_btn->setTabStop(FALSE);
|
||||
line_down_btn->setScaleImage(TRUE);
|
||||
addChild(line_down_btn);
|
||||
@@ -170,7 +168,7 @@ bool LLScrollbar::setDocPos(S32 pos, BOOL update_thumb)
|
||||
|
||||
if( mChangeCallback )
|
||||
{
|
||||
mChangeCallback( mDocPos, this, mCallbackUserData );
|
||||
mChangeCallback( mDocPos, this );
|
||||
}
|
||||
|
||||
if( update_thumb )
|
||||
@@ -629,19 +627,12 @@ void LLScrollbar::pageDown(S32 overlap)
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLScrollbar::onLineUpBtnPressed( void* userdata )
|
||||
void LLScrollbar::onLineUpBtnPressed( const LLSD& data )
|
||||
{
|
||||
LLScrollbar* self = (LLScrollbar*) userdata;
|
||||
|
||||
self->changeLine( - self->mStepSize, TRUE );
|
||||
changeLine( -mStepSize, TRUE );
|
||||
}
|
||||
|
||||
// static
|
||||
void LLScrollbar::onLineDownBtnPressed( void* userdata )
|
||||
void LLScrollbar::onLineDownBtnPressed( const LLSD& data )
|
||||
{
|
||||
LLScrollbar* self = (LLScrollbar*) userdata;
|
||||
self->changeLine( self->mStepSize, TRUE );
|
||||
changeLine( mStepSize, TRUE );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -52,11 +52,11 @@ class LLScrollbar
|
||||
public:
|
||||
enum ORIENTATION { HORIZONTAL, VERTICAL };
|
||||
|
||||
typedef boost::function<void (S32, LLScrollbar*)> callback_t;
|
||||
LLScrollbar(const std::string& name, LLRect rect,
|
||||
ORIENTATION orientation,
|
||||
S32 doc_size, S32 doc_pos, S32 page_size,
|
||||
void(*change_callback)( S32 new_pos, LLScrollbar* self, void* userdata ),
|
||||
void* callback_user_data = NULL,
|
||||
callback_t change_callback,
|
||||
S32 step_size = 1);
|
||||
|
||||
virtual ~LLScrollbar();
|
||||
@@ -101,8 +101,8 @@ public:
|
||||
void pageUp(S32 overlap);
|
||||
void pageDown(S32 overlap);
|
||||
|
||||
static void onLineUpBtnPressed(void* userdata);
|
||||
static void onLineDownBtnPressed(void* userdata);
|
||||
void onLineUpBtnPressed(const LLSD& data);
|
||||
void onLineDownBtnPressed(const LLSD& data);
|
||||
|
||||
void setTrackColor( const LLColor4& color ) { mTrackColor = color; }
|
||||
void setThumbColor( const LLColor4& color ) { mThumbColor = color; }
|
||||
@@ -115,8 +115,7 @@ private:
|
||||
void updateThumbRect();
|
||||
bool changeLine(S32 delta, BOOL update_thumb );
|
||||
|
||||
void (*mChangeCallback)( S32 new_pos, LLScrollbar* self, void* userdata );
|
||||
void* mCallbackUserData;
|
||||
callback_t mChangeCallback;
|
||||
|
||||
const ORIENTATION mOrientation;
|
||||
S32 mDocSize; // Size of the document that the scrollbar is modeling. Units depend on the user. 0 <= mDocSize.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @file llscrollcontainer.cpp
|
||||
* @brief LLScrollableContainerView base class
|
||||
* @brief LLScrollContainer base class
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewergpl$
|
||||
*
|
||||
@@ -33,8 +33,10 @@
|
||||
|
||||
#include "linden_common.h"
|
||||
|
||||
#include "llrender.h"
|
||||
#include "llscrollcontainer.h"
|
||||
|
||||
#include "llrender.h"
|
||||
#include "llcontainerview.h"
|
||||
#include "lllocalcliprect.h"
|
||||
#include "llscrollbar.h"
|
||||
#include "llui.h"
|
||||
@@ -44,6 +46,7 @@
|
||||
#include "llfocusmgr.h"
|
||||
#include "llframetimer.h"
|
||||
#include "lluictrlfactory.h"
|
||||
#include "llpanel.h"
|
||||
#include "llfontgl.h"
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
@@ -57,18 +60,18 @@ static const F32 MAX_AUTO_SCROLL_RATE = 500.f;
|
||||
static const F32 AUTO_SCROLL_RATE_ACCEL = 120.f;
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
/// Class LLScrollableContainerView
|
||||
/// Class LLScrollContainer
|
||||
///----------------------------------------------------------------------------
|
||||
|
||||
static LLRegisterWidget<LLScrollableContainerView> r("scroll_container");
|
||||
static LLRegisterWidget<LLScrollContainer> r("scroll_container");
|
||||
|
||||
// Default constructor
|
||||
LLScrollableContainerView::LLScrollableContainerView( const std::string& name,
|
||||
LLScrollContainer::LLScrollContainer( const std::string& name,
|
||||
const LLRect& rect,
|
||||
LLView* scrolled_view,
|
||||
BOOL is_opaque,
|
||||
const LLColor4& bg_color ) :
|
||||
LLUICtrl( name, rect, FALSE, NULL, NULL ),
|
||||
LLUICtrl( name, rect, FALSE ),
|
||||
mAutoScrolling( FALSE ),
|
||||
mAutoScrollRate( 0.f ),
|
||||
mBackgroundColor( bg_color ),
|
||||
@@ -101,7 +104,7 @@ LLScrollableContainerView::LLScrollableContainerView( const std::string& name,
|
||||
mInnerRect.getHeight(),
|
||||
0,
|
||||
mInnerRect.getHeight(),
|
||||
NULL, this,
|
||||
NULL,
|
||||
VERTICAL_MULTIPLE);
|
||||
LLView::addChild( mScrollbar[VERTICAL] );
|
||||
mScrollbar[VERTICAL]->setVisible( FALSE );
|
||||
@@ -117,7 +120,7 @@ LLScrollableContainerView::LLScrollableContainerView( const std::string& name,
|
||||
mInnerRect.getWidth(),
|
||||
0,
|
||||
mInnerRect.getWidth(),
|
||||
NULL, this,
|
||||
NULL,
|
||||
HORIZONTAL_MULTIPLE);
|
||||
LLView::addChild( mScrollbar[HORIZONTAL] );
|
||||
mScrollbar[HORIZONTAL]->setVisible( FALSE );
|
||||
@@ -128,7 +131,7 @@ LLScrollableContainerView::LLScrollableContainerView( const std::string& name,
|
||||
}
|
||||
|
||||
// Destroys the object
|
||||
LLScrollableContainerView::~LLScrollableContainerView( void )
|
||||
LLScrollContainer::~LLScrollContainer( void )
|
||||
{
|
||||
// mScrolledView and mScrollbar are child views, so the LLView
|
||||
// destructor takes care of memory deallocation.
|
||||
@@ -141,9 +144,9 @@ LLScrollableContainerView::~LLScrollableContainerView( void )
|
||||
|
||||
// internal scrollbar handlers
|
||||
// virtual
|
||||
void LLScrollableContainerView::scrollHorizontal( S32 new_pos )
|
||||
void LLScrollContainer::scrollHorizontal( S32 new_pos )
|
||||
{
|
||||
//llinfos << "LLScrollableContainerView::scrollHorizontal()" << llendl;
|
||||
//llinfos << "LLScrollContainer::scrollHorizontal()" << llendl;
|
||||
if( mScrolledView )
|
||||
{
|
||||
LLRect doc_rect = mScrolledView->getRect();
|
||||
@@ -153,9 +156,9 @@ void LLScrollableContainerView::scrollHorizontal( S32 new_pos )
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLScrollableContainerView::scrollVertical( S32 new_pos )
|
||||
void LLScrollContainer::scrollVertical( S32 new_pos )
|
||||
{
|
||||
// llinfos << "LLScrollableContainerView::scrollVertical() " << new_pos << llendl;
|
||||
// llinfos << "LLScrollContainer::scrollVertical() " << new_pos << llendl;
|
||||
if( mScrolledView )
|
||||
{
|
||||
LLRect doc_rect = mScrolledView->getRect();
|
||||
@@ -165,7 +168,7 @@ void LLScrollableContainerView::scrollVertical( S32 new_pos )
|
||||
}
|
||||
|
||||
// LLView functionality
|
||||
void LLScrollableContainerView::reshape(S32 width, S32 height,
|
||||
void LLScrollContainer::reshape(S32 width, S32 height,
|
||||
BOOL called_from_parent)
|
||||
{
|
||||
LLUICtrl::reshape( width, height, called_from_parent );
|
||||
@@ -192,7 +195,7 @@ void LLScrollableContainerView::reshape(S32 width, S32 height,
|
||||
}
|
||||
}
|
||||
|
||||
BOOL LLScrollableContainerView::handleKeyHere(KEY key, MASK mask)
|
||||
BOOL LLScrollContainer::handleKeyHere(KEY key, MASK mask)
|
||||
{
|
||||
// allow scrolled view to handle keystrokes in case it delegated keyboard focus
|
||||
// to the scroll container.
|
||||
@@ -215,7 +218,7 @@ BOOL LLScrollableContainerView::handleKeyHere(KEY key, MASK mask)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL LLScrollableContainerView::handleScrollWheel( S32 x, S32 y, S32 clicks )
|
||||
BOOL LLScrollContainer::handleScrollWheel( S32 x, S32 y, S32 clicks )
|
||||
{
|
||||
// Give event to my child views - they may have scroll bars
|
||||
// (Bad UI design, but technically possible.)
|
||||
@@ -252,7 +255,7 @@ BOOL LLScrollableContainerView::handleScrollWheel( S32 x, S32 y, S32 clicks )
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL LLScrollableContainerView::handleDragAndDrop(S32 x, S32 y, MASK mask,
|
||||
BOOL LLScrollContainer::handleDragAndDrop(S32 x, S32 y, MASK mask,
|
||||
BOOL drop,
|
||||
EDragAndDropType cargo_type,
|
||||
void* cargo_data,
|
||||
@@ -273,7 +276,7 @@ BOOL LLScrollableContainerView::handleDragAndDrop(S32 x, S32 y, MASK mask,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool LLScrollableContainerView::autoScroll(S32 x, S32 y)
|
||||
bool LLScrollContainer::autoScroll(S32 x, S32 y)
|
||||
{
|
||||
S32 scrollbar_size = SCROLLBAR_SIZE;
|
||||
|
||||
@@ -346,7 +349,7 @@ bool LLScrollableContainerView::autoScroll(S32 x, S32 y)
|
||||
}
|
||||
|
||||
|
||||
BOOL LLScrollableContainerView::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect)
|
||||
BOOL LLScrollContainer::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect)
|
||||
{
|
||||
S32 local_x, local_y;
|
||||
for( S32 i = 0; i < SCROLLBAR_COUNT; i++ )
|
||||
@@ -373,7 +376,7 @@ BOOL LLScrollableContainerView::handleToolTip(S32 x, S32 y, std::string& msg, LL
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void LLScrollableContainerView::calcVisibleSize( S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const
|
||||
void LLScrollContainer::calcVisibleSize( S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const
|
||||
{
|
||||
const LLRect& doc_rect = getScrolledViewRect();
|
||||
S32 scrollbar_size = SCROLLBAR_SIZE;
|
||||
@@ -410,7 +413,7 @@ void LLScrollableContainerView::calcVisibleSize( S32 *visible_width, S32 *visibl
|
||||
}
|
||||
}
|
||||
|
||||
void LLScrollableContainerView::draw()
|
||||
void LLScrollContainer::draw()
|
||||
{
|
||||
S32 scrollbar_size = SCROLLBAR_SIZE;
|
||||
if (mAutoScrolling)
|
||||
@@ -503,7 +506,7 @@ void LLScrollableContainerView::draw()
|
||||
|
||||
} // end draw
|
||||
|
||||
bool LLScrollableContainerView::addChild(LLView* view, S32 tab_group)
|
||||
bool LLScrollContainer::addChild(LLView* view, S32 tab_group)
|
||||
{
|
||||
if (!mScrolledView)
|
||||
{
|
||||
@@ -520,7 +523,7 @@ bool LLScrollableContainerView::addChild(LLView* view, S32 tab_group)
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
void LLScrollableContainerView::updateScroll()
|
||||
void LLScrollContainer::updateScroll()
|
||||
{
|
||||
if (!mScrolledView)
|
||||
{
|
||||
@@ -607,7 +610,7 @@ void LLScrollableContainerView::updateScroll()
|
||||
mScrollbar[VERTICAL]->setPageSize( visible_height );
|
||||
} // end updateScroll
|
||||
|
||||
void LLScrollableContainerView::setBorderVisible(BOOL b)
|
||||
void LLScrollContainer::setBorderVisible(BOOL b)
|
||||
{
|
||||
mBorder->setVisible( b );
|
||||
// Recompute inner rect, as border visibility changes it
|
||||
@@ -615,7 +618,7 @@ void LLScrollableContainerView::setBorderVisible(BOOL b)
|
||||
mInnerRect.stretch( -getBorderWidth() );
|
||||
}
|
||||
|
||||
LLRect LLScrollableContainerView::getVisibleContentRect()
|
||||
LLRect LLScrollContainer::getVisibleContentRect()
|
||||
{
|
||||
updateScroll();
|
||||
LLRect visible_rect = getContentWindowRect();
|
||||
@@ -623,7 +626,7 @@ LLRect LLScrollableContainerView::getVisibleContentRect()
|
||||
visible_rect.translate(-contents_rect.mLeft, -contents_rect.mBottom);
|
||||
return visible_rect;
|
||||
}
|
||||
LLRect LLScrollableContainerView::getContentWindowRect()
|
||||
LLRect LLScrollContainer::getContentWindowRect()
|
||||
{
|
||||
updateScroll();
|
||||
LLRect scroller_view_rect;
|
||||
@@ -641,7 +644,7 @@ LLRect LLScrollableContainerView::getContentWindowRect()
|
||||
}
|
||||
|
||||
// rect is in document coordinates, constraint is in display coordinates relative to content window rect
|
||||
void LLScrollableContainerView::scrollToShowRect(const LLRect& rect, const LLRect& constraint)
|
||||
void LLScrollContainer::scrollToShowRect(const LLRect& rect, const LLRect& constraint)
|
||||
{
|
||||
if (!mScrolledView)
|
||||
{
|
||||
@@ -692,31 +695,31 @@ void LLScrollableContainerView::scrollToShowRect(const LLRect& rect, const LLRec
|
||||
notifyParent(LLSD().with("scrollToShowRect",screen_rc.getValue()));
|
||||
}
|
||||
|
||||
void LLScrollableContainerView::pageUp(S32 overlap)
|
||||
void LLScrollContainer::pageUp(S32 overlap)
|
||||
{
|
||||
mScrollbar[VERTICAL]->pageUp(overlap);
|
||||
updateScroll();
|
||||
}
|
||||
|
||||
void LLScrollableContainerView::pageDown(S32 overlap)
|
||||
void LLScrollContainer::pageDown(S32 overlap)
|
||||
{
|
||||
mScrollbar[VERTICAL]->pageDown(overlap);
|
||||
updateScroll();
|
||||
}
|
||||
|
||||
void LLScrollableContainerView::goToTop()
|
||||
void LLScrollContainer::goToTop()
|
||||
{
|
||||
mScrollbar[VERTICAL]->setDocPos(0);
|
||||
updateScroll();
|
||||
}
|
||||
|
||||
void LLScrollableContainerView::goToBottom()
|
||||
void LLScrollContainer::goToBottom()
|
||||
{
|
||||
mScrollbar[VERTICAL]->setDocPos(mScrollbar[VERTICAL]->getDocSize());
|
||||
updateScroll();
|
||||
}
|
||||
|
||||
S32 LLScrollableContainerView::getBorderWidth() const
|
||||
S32 LLScrollContainer::getBorderWidth() const
|
||||
{
|
||||
if (mBorder && mBorder->getVisible())
|
||||
{
|
||||
@@ -727,7 +730,7 @@ S32 LLScrollableContainerView::getBorderWidth() const
|
||||
}
|
||||
|
||||
// virtual
|
||||
LLXMLNodePtr LLScrollableContainerView::getXML(bool save_children) const
|
||||
LLXMLNodePtr LLScrollContainer::getXML(bool save_children) const
|
||||
{
|
||||
LLXMLNodePtr node = LLUICtrl::getXML();
|
||||
|
||||
@@ -751,7 +754,7 @@ LLXMLNodePtr LLScrollableContainerView::getXML(bool save_children) const
|
||||
return node;
|
||||
}
|
||||
|
||||
LLView* LLScrollableContainerView::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
|
||||
LLView* LLScrollContainer::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
|
||||
{
|
||||
std::string name("scroll_container");
|
||||
node->getAttributeString("name", name);
|
||||
@@ -766,7 +769,7 @@ LLView* LLScrollableContainerView::fromXML(LLXMLNodePtr node, LLView *parent, LL
|
||||
LLUICtrlFactory::getAttributeColor(node,"color", color);
|
||||
|
||||
// Create the scroll view
|
||||
LLScrollableContainerView *ret = new LLScrollableContainerView(name, rect, (LLPanel*)NULL, opaque, color);
|
||||
LLScrollContainer *ret = new LLScrollContainer(name, rect, (LLPanel*)NULL, opaque, color);
|
||||
|
||||
LLPanel* panelp = NULL;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @file llscrollcontainer.h
|
||||
* @brief LLScrollableContainerView class header file.
|
||||
* @brief LLScrollContainer class header file.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewergpl$
|
||||
*
|
||||
@@ -53,17 +53,17 @@ class LLUICtrlFactory;
|
||||
* the width and height of the view you're scrolling.
|
||||
*
|
||||
*****************************************************************************/
|
||||
class LLScrollableContainerView : public LLUICtrl
|
||||
class LLScrollContainer : public LLUICtrl
|
||||
{
|
||||
public:
|
||||
// Note: vertical comes before horizontal because vertical
|
||||
// scrollbars have priority for mouse and keyboard events.
|
||||
enum SCROLL_ORIENTATION { VERTICAL, HORIZONTAL, SCROLLBAR_COUNT };
|
||||
|
||||
LLScrollableContainerView( const std::string& name, const LLRect& rect,
|
||||
LLScrollContainer( const std::string& name, const LLRect& rect,
|
||||
LLView* scrolled_view, BOOL is_opaque = FALSE,
|
||||
const LLColor4& bg_color = LLColor4(0,0,0,0) );
|
||||
virtual ~LLScrollableContainerView( void );
|
||||
virtual ~LLScrollContainer( void );
|
||||
|
||||
void setScrolledView(LLView* view) { mScrolledView = view; }
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ class LLScrollingPanelList : public LLUICtrl
|
||||
{
|
||||
public:
|
||||
LLScrollingPanelList(const std::string& name, const LLRect& rect)
|
||||
: LLUICtrl(name, rect, TRUE, NULL, NULL, FOLLOWS_LEFT | FOLLOWS_BOTTOM ) {}
|
||||
: LLUICtrl(name, rect, TRUE, NULL, FOLLOWS_LEFT | FOLLOWS_BOTTOM ) {}
|
||||
|
||||
typedef std::deque<LLScrollingPanel*> panel_list_t;
|
||||
|
||||
|
||||
@@ -662,13 +662,12 @@ public:
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
LLScrollListCtrl::LLScrollListCtrl(const std::string& name, const LLRect& rect,
|
||||
void (*commit_callback)(LLUICtrl* ctrl, void* userdata),
|
||||
void* callback_user_data,
|
||||
commit_callback_t commit_callback,
|
||||
BOOL allow_multiple_selection,
|
||||
BOOL show_border,
|
||||
bool draw_heading
|
||||
)
|
||||
: LLUICtrl(name, rect, TRUE, commit_callback, callback_user_data),
|
||||
: LLUICtrl(name, rect, TRUE, commit_callback),
|
||||
mLineHeight(0),
|
||||
mScrollLines(0),
|
||||
mMouseWheelOpaque(true),
|
||||
@@ -735,7 +734,7 @@ LLScrollListCtrl::LLScrollListCtrl(const std::string& name, const LLRect& rect,
|
||||
getItemCount(),
|
||||
mScrollLines,
|
||||
getLinesPerPage(),
|
||||
&LLScrollListCtrl::onScrollChange, this );
|
||||
boost::bind(&LLScrollListCtrl::onScrollChange, this, _1, _2) );
|
||||
mScrollbar->setFollowsRight();
|
||||
mScrollbar->setFollowsTop();
|
||||
mScrollbar->setFollowsBottom();
|
||||
@@ -2853,11 +2852,9 @@ S32 LLScrollListCtrl::getLinesPerPage()
|
||||
}
|
||||
|
||||
// Called by scrollbar
|
||||
//static
|
||||
void LLScrollListCtrl::onScrollChange( S32 new_pos, LLScrollbar* scrollbar, void* userdata )
|
||||
void LLScrollListCtrl::onScrollChange( S32 new_pos, LLScrollbar* scrollbar )
|
||||
{
|
||||
LLScrollListCtrl* self = (LLScrollListCtrl*) userdata;
|
||||
self->mScrollLines = new_pos;
|
||||
mScrollLines = new_pos;
|
||||
}
|
||||
|
||||
|
||||
@@ -2932,7 +2929,7 @@ void LLScrollListCtrl::setScrollPos( S32 pos )
|
||||
{
|
||||
mScrollbar->setDocPos( pos );
|
||||
|
||||
onScrollChange(mScrollbar->getDocPos(), mScrollbar, this);
|
||||
onScrollChange(mScrollbar->getDocPos(), mScrollbar);
|
||||
}
|
||||
|
||||
|
||||
@@ -3134,12 +3131,9 @@ LLView* LLScrollListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFac
|
||||
BOOL mouse_wheel_opaque = TRUE;
|
||||
node->getAttributeBOOL("mouse_wheel_opaque", mouse_wheel_opaque);
|
||||
|
||||
LLUICtrlCallback callback = NULL;
|
||||
|
||||
LLScrollListCtrl* scroll_list = new LLScrollListCtrl(
|
||||
name,
|
||||
rect,
|
||||
callback,
|
||||
NULL,
|
||||
multi_select,
|
||||
draw_border,
|
||||
@@ -3868,7 +3862,7 @@ void LLScrollListCtrl::onFocusLost()
|
||||
}
|
||||
|
||||
LLScrollColumnHeader::LLScrollColumnHeader(const std::string& label, const LLRect &rect, LLScrollListColumn* column, const LLFontGL* fontp) :
|
||||
LLComboBox(label, rect, label, NULL, NULL),
|
||||
LLComboBox(label, rect, label),
|
||||
mColumn(column),
|
||||
mOrigLabel(label),
|
||||
mShowSortOptions(FALSE),
|
||||
@@ -3894,11 +3888,14 @@ LLScrollColumnHeader::LLScrollColumnHeader(const std::string& label, const LLRec
|
||||
|
||||
// resize handles on left and right
|
||||
const S32 RESIZE_BAR_THICKNESS = 3;
|
||||
mResizeBar = new LLResizeBar(
|
||||
std::string("resizebar"),
|
||||
this,
|
||||
LLRect( getRect().getWidth() - RESIZE_BAR_THICKNESS, getRect().getHeight(), getRect().getWidth(), 0),
|
||||
MIN_COLUMN_WIDTH, S32_MAX, LLResizeBar::RIGHT );
|
||||
LLResizeBar::Params p;
|
||||
p.name = "resizebar";
|
||||
p.resizing_view = this;
|
||||
p.rect = LLRect( getRect().getWidth() - RESIZE_BAR_THICKNESS, getRect().getHeight(), getRect().getWidth(), 0);
|
||||
p.min_size = MIN_COLUMN_WIDTH;
|
||||
p.max_size = S32_MAX;
|
||||
p.side = LLResizeBar::RIGHT;
|
||||
mResizeBar = LLUICtrlFactory::create<LLResizeBar>(p);
|
||||
addChild(mResizeBar);
|
||||
|
||||
mResizeBar->setEnabled(FALSE);
|
||||
|
||||
@@ -390,8 +390,7 @@ public:
|
||||
LLScrollListCtrl(
|
||||
const std::string& name,
|
||||
const LLRect& rect,
|
||||
void (*commit_callback)(LLUICtrl*, void*),
|
||||
void* callback_userdata,
|
||||
commit_callback_t commit_callback,
|
||||
BOOL allow_multiple_selection,
|
||||
BOOL draw_border = TRUE, bool draw_heading = false);
|
||||
|
||||
@@ -594,7 +593,7 @@ public:
|
||||
LLRect getCellRect(S32 row_index, S32 column_index);
|
||||
|
||||
// Used "internally" by the scroll bar.
|
||||
static void onScrollChange( S32 new_pos, LLScrollbar* src, void* userdata );
|
||||
void onScrollChange( S32 new_pos, LLScrollbar* src);
|
||||
|
||||
static void onClickColumn(void *userdata);
|
||||
|
||||
|
||||
176
indra/llui/llsearcheditor.cpp
Normal file
176
indra/llui/llsearcheditor.cpp
Normal file
@@ -0,0 +1,176 @@
|
||||
/**
|
||||
* @file llsearcheditor.cpp
|
||||
* @brief LLSearchEditor implementation
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&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$
|
||||
*/
|
||||
|
||||
// Text editor widget to let users enter a single line.
|
||||
|
||||
#include "linden_common.h"
|
||||
|
||||
#include "llsearcheditor.h"
|
||||
|
||||
static LLRegisterWidget<LLSearchEditor> r2("search_editor");
|
||||
|
||||
|
||||
LLSearchEditor::LLSearchEditor(const std::string& name,
|
||||
const LLRect& rect,
|
||||
S32 max_length_bytes)
|
||||
:
|
||||
LLUICtrl(name, rect),
|
||||
mSearchEditor(NULL),
|
||||
mClearButton(NULL)
|
||||
{
|
||||
mSearchEditor = new LLLineEditor(std::string("filter edit box"),
|
||||
getLocalRect(),
|
||||
LLStringUtil::null,
|
||||
NULL,
|
||||
max_length_bytes,
|
||||
boost::bind(&LLUICtrl::onCommit, this),
|
||||
boost::bind(&LLSearchEditor::handleKeystroke, this));
|
||||
|
||||
mSearchEditor->setFollowsAll();
|
||||
mSearchEditor->setSelectAllonFocusReceived(TRUE);
|
||||
mSearchEditor->setRevertOnEsc( FALSE );
|
||||
mSearchEditor->setPassDelete(TRUE);
|
||||
|
||||
addChild(mSearchEditor);
|
||||
|
||||
S32 btn_width = rect.getHeight(); // button is square, and as tall as search editor
|
||||
LLRect clear_btn_rect(rect.getWidth() - btn_width, rect.getHeight(), rect.getWidth(), 0);
|
||||
mClearButton = new LLButton(std::string("clear button"),
|
||||
clear_btn_rect,
|
||||
std::string("icn_clear_lineeditor.tga"),
|
||||
std::string("UIImgBtnCloseInactiveUUID"),
|
||||
LLStringUtil::null,
|
||||
boost::bind(&LLSearchEditor::onClearButtonClick, this, _2));
|
||||
mClearButton->setFollowsRight();
|
||||
mClearButton->setFollowsTop();
|
||||
mClearButton->setImageColor(LLUI::sColorsGroup->getColor("TextFgTentativeColor"));
|
||||
mClearButton->setTabStop(FALSE);
|
||||
mSearchEditor->addChild(mClearButton);
|
||||
|
||||
mSearchEditor->setTextPadding(0, btn_width);
|
||||
}
|
||||
|
||||
//virtual
|
||||
void LLSearchEditor::draw()
|
||||
{
|
||||
if (mClearButton)
|
||||
mClearButton->setVisible(!mSearchEditor->getWText().empty());
|
||||
|
||||
LLUICtrl::draw();
|
||||
}
|
||||
|
||||
//virtual
|
||||
void LLSearchEditor::setValue(const LLSD& value )
|
||||
{
|
||||
mSearchEditor->setValue(value);
|
||||
}
|
||||
|
||||
//virtual
|
||||
LLSD LLSearchEditor::getValue() const
|
||||
{
|
||||
return mSearchEditor->getValue();
|
||||
}
|
||||
|
||||
//virtual
|
||||
BOOL LLSearchEditor::setTextArg( const std::string& key, const LLStringExplicit& text )
|
||||
{
|
||||
return mSearchEditor->setTextArg(key, text);
|
||||
}
|
||||
|
||||
//virtual
|
||||
BOOL LLSearchEditor::setLabelArg( const std::string& key, const LLStringExplicit& text )
|
||||
{
|
||||
return mSearchEditor->setLabelArg(key, text);
|
||||
}
|
||||
|
||||
//virtual
|
||||
void LLSearchEditor::setLabel( const LLStringExplicit &new_label )
|
||||
{
|
||||
mSearchEditor->setLabel(new_label);
|
||||
}
|
||||
|
||||
//virtual
|
||||
void LLSearchEditor::clear()
|
||||
{
|
||||
if (mSearchEditor)
|
||||
{
|
||||
mSearchEditor->clear();
|
||||
}
|
||||
}
|
||||
|
||||
//virtual
|
||||
void LLSearchEditor::setFocus( BOOL b )
|
||||
{
|
||||
if (mSearchEditor)
|
||||
{
|
||||
mSearchEditor->setFocus(b);
|
||||
}
|
||||
}
|
||||
|
||||
void LLSearchEditor::onClearButtonClick(const LLSD& data)
|
||||
{
|
||||
setText(LLStringUtil::null);
|
||||
mSearchEditor->onCommit(); // force keystroke callback
|
||||
}
|
||||
|
||||
void LLSearchEditor::handleKeystroke()
|
||||
{
|
||||
if (mKeystrokeCallback)
|
||||
{
|
||||
mKeystrokeCallback(this, getValue());
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
LLView* LLSearchEditor::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
|
||||
{
|
||||
std::string name("search_editor");
|
||||
node->getAttributeString("name", name);
|
||||
|
||||
LLRect rect;
|
||||
createRect(node, rect, parent, LLRect());
|
||||
|
||||
S32 max_text_length = 128;
|
||||
node->getAttributeS32("max_length", max_text_length);
|
||||
|
||||
std::string text = node->getValue().substr(0, max_text_length - 1);
|
||||
|
||||
LLSearchEditor* search_editor = new LLSearchEditor(name,
|
||||
rect,
|
||||
max_text_length);
|
||||
|
||||
std::string label;
|
||||
if(node->getAttributeString("label", label))
|
||||
{
|
||||
search_editor->setLabel(label);
|
||||
}
|
||||
|
||||
search_editor->setText(text);
|
||||
|
||||
search_editor->initFromXML(node, parent);
|
||||
|
||||
return search_editor;
|
||||
}
|
||||
80
indra/llui/llsearcheditor.h
Normal file
80
indra/llui/llsearcheditor.h
Normal file
@@ -0,0 +1,80 @@
|
||||
/**
|
||||
* @file llsearcheditor.h
|
||||
* @brief Text editor widget that represents a search operation
|
||||
*
|
||||
* Features:
|
||||
* Text entry of a single line (text, delete, left and right arrow, insert, return).
|
||||
* Callbacks either on every keystroke or just on the return key.
|
||||
* Focus (allow multiple text entry widgets)
|
||||
* Clipboard (cut, copy, and paste)
|
||||
* Horizontal scrolling to allow strings longer than widget size allows
|
||||
* Pre-validation (limit which keys can be used)
|
||||
* Optional line history so previous entries can be recalled by CTRL UP/DOWN
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&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_SEARCHEDITOR_H
|
||||
#define LL_SEARCHEDITOR_H
|
||||
|
||||
#include "lllineeditor.h"
|
||||
#include "llbutton.h"
|
||||
|
||||
class LLSearchEditor : public LLUICtrl
|
||||
{
|
||||
public:
|
||||
LLSearchEditor(const std::string& name,
|
||||
const LLRect& rect,
|
||||
S32 max_length_bytes);
|
||||
|
||||
void setCommitOnFocusLost(BOOL b) { if (mSearchEditor) mSearchEditor->setCommitOnFocusLost(b); }
|
||||
|
||||
virtual ~LLSearchEditor() {}
|
||||
|
||||
/*virtual*/ void draw();
|
||||
|
||||
static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
|
||||
|
||||
void setText(const LLStringExplicit &new_text) { mSearchEditor->setText(new_text); }
|
||||
const std::string& getText() const { return mSearchEditor->getText(); }
|
||||
|
||||
// LLUICtrl interface
|
||||
virtual void setValue(const LLSD& value );
|
||||
virtual LLSD getValue() const;
|
||||
virtual BOOL setTextArg( const std::string& key, const LLStringExplicit& text );
|
||||
virtual BOOL setLabelArg( const std::string& key, const LLStringExplicit& text );
|
||||
virtual void setLabel( const LLStringExplicit &new_label );
|
||||
virtual void clear();
|
||||
virtual void setFocus( BOOL b );
|
||||
|
||||
void setKeystrokeCallback( commit_callback_t cb ) { mKeystrokeCallback = cb; }
|
||||
|
||||
protected:
|
||||
void onClearButtonClick(const LLSD& data);
|
||||
virtual void handleKeystroke();
|
||||
|
||||
commit_callback_t mKeystrokeCallback;
|
||||
LLLineEditor* mSearchEditor;
|
||||
LLButton* mClearButton;
|
||||
};
|
||||
|
||||
#endif //LL_SEARCHEDITOR_H
|
||||
@@ -49,8 +49,7 @@ static LLRegisterWidget<LLSlider> r2("volume_slider");
|
||||
LLSlider::LLSlider(
|
||||
const std::string& name,
|
||||
const LLRect& rect,
|
||||
void (*on_commit_callback)(LLUICtrl* ctrl, void* userdata),
|
||||
void* callback_userdata,
|
||||
commit_callback_t commit_callback,
|
||||
F32 initial_value,
|
||||
F32 min_value,
|
||||
F32 max_value,
|
||||
@@ -58,7 +57,7 @@ LLSlider::LLSlider(
|
||||
BOOL volume,
|
||||
const std::string& control_name)
|
||||
:
|
||||
LLUICtrl( name, rect, TRUE, on_commit_callback, callback_userdata,
|
||||
LLUICtrl( name, rect, TRUE, commit_callback,
|
||||
FOLLOWS_LEFT | FOLLOWS_TOP),
|
||||
mValue( initial_value ),
|
||||
mInitialValue( initial_value ),
|
||||
@@ -350,7 +349,6 @@ LLView* LLSlider::fromXML(LLXMLNodePtr node, LLView *parent, class LLUICtrlFacto
|
||||
LLSlider* slider = new LLSlider(name,
|
||||
rect,
|
||||
NULL,
|
||||
NULL,
|
||||
initial_value,
|
||||
min_value,
|
||||
max_value,
|
||||
|
||||
@@ -43,8 +43,7 @@ public:
|
||||
LLSlider(
|
||||
const std::string& name,
|
||||
const LLRect& rect,
|
||||
void (*on_commit_callback)(LLUICtrl* ctrl, void* userdata),
|
||||
void* callback_userdata,
|
||||
commit_callback_t commit_callback,
|
||||
F32 initial_value,
|
||||
F32 min_value,
|
||||
F32 max_value,
|
||||
|
||||
@@ -60,11 +60,10 @@ LLSliderCtrl::LLSliderCtrl(const std::string& name, const LLRect& rect,
|
||||
BOOL show_text,
|
||||
BOOL can_edit_text,
|
||||
BOOL volume,
|
||||
void (*commit_callback)(LLUICtrl*, void*),
|
||||
void* callback_user_data,
|
||||
commit_callback_t commit_callback,
|
||||
F32 initial_value, F32 min_value, F32 max_value, F32 increment,
|
||||
const std::string& control_which)
|
||||
: LLUICtrl(name, rect, TRUE, commit_callback, callback_user_data ),
|
||||
: LLUICtrl(name, rect, TRUE, commit_callback ),
|
||||
mFont(font),
|
||||
mShowText( show_text ),
|
||||
mCanEditText( can_edit_text ),
|
||||
@@ -104,7 +103,7 @@ LLSliderCtrl::LLSliderCtrl(const std::string& name, const LLRect& rect,
|
||||
LLRect slider_rect( slider_left, top, slider_right, bottom );
|
||||
mSlider = new LLSlider(std::string("slider"),
|
||||
slider_rect,
|
||||
LLSliderCtrl::onSliderCommit, this,
|
||||
boost::bind(&LLSliderCtrl::onSliderCommit,_1,_2),
|
||||
initial_value, min_value, max_value, increment, volume,
|
||||
control_which );
|
||||
addChild( mSlider );
|
||||
@@ -117,7 +116,9 @@ LLSliderCtrl::LLSliderCtrl(const std::string& name, const LLRect& rect,
|
||||
mEditor = new LLLineEditor( std::string("SliderCtrl Editor"), text_rect,
|
||||
LLStringUtil::null, font,
|
||||
MAX_STRING_LENGTH,
|
||||
&LLSliderCtrl::onEditorCommit, NULL, NULL, this,
|
||||
&LLSliderCtrl::onEditorCommit,
|
||||
NULL,
|
||||
NULL,
|
||||
&LLLineEditor::prevalidateFloat );
|
||||
mEditor->setFollowsLeft();
|
||||
mEditor->setFollowsBottom();
|
||||
@@ -209,10 +210,11 @@ void LLSliderCtrl::updateText()
|
||||
}
|
||||
|
||||
// static
|
||||
void LLSliderCtrl::onEditorCommit( LLUICtrl* caller, void *userdata )
|
||||
void LLSliderCtrl::onEditorCommit( LLUICtrl* ctrl, const LLSD& userdata )
|
||||
{
|
||||
LLSliderCtrl* self = (LLSliderCtrl*) userdata;
|
||||
llassert( caller == self->mEditor );
|
||||
LLSliderCtrl* self = dynamic_cast<LLSliderCtrl*>(ctrl->getParent());
|
||||
if (!self)
|
||||
return;
|
||||
|
||||
BOOL success = FALSE;
|
||||
F32 val = self->mValue;
|
||||
@@ -250,10 +252,11 @@ void LLSliderCtrl::onEditorCommit( LLUICtrl* caller, void *userdata )
|
||||
}
|
||||
|
||||
// static
|
||||
void LLSliderCtrl::onSliderCommit( LLUICtrl* caller, void *userdata )
|
||||
void LLSliderCtrl::onSliderCommit( LLUICtrl* ctrl, const LLSD& userdata )
|
||||
{
|
||||
LLSliderCtrl* self = (LLSliderCtrl*) userdata;
|
||||
llassert( caller == self->mSlider );
|
||||
LLSliderCtrl* self = dynamic_cast<LLSliderCtrl*>(ctrl->getParent());
|
||||
if (!self)
|
||||
return;
|
||||
|
||||
BOOL success = FALSE;
|
||||
F32 saved_val = self->mValue;
|
||||
@@ -472,8 +475,6 @@ LLView* LLSliderCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory
|
||||
}
|
||||
}
|
||||
|
||||
LLUICtrlCallback callback = NULL;
|
||||
|
||||
if (label.empty())
|
||||
{
|
||||
label.assign(node->getTextContents());
|
||||
@@ -488,7 +489,6 @@ LLView* LLSliderCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory
|
||||
show_text,
|
||||
can_edit_text,
|
||||
volume,
|
||||
callback,
|
||||
NULL,
|
||||
initial_value,
|
||||
min_value,
|
||||
|
||||
@@ -58,8 +58,7 @@ public:
|
||||
BOOL show_text,
|
||||
BOOL can_edit_text,
|
||||
BOOL volume, //TODO: create a "volume" slider sub-class or just use image art, no? -MG
|
||||
void (*commit_callback)(LLUICtrl*, void*),
|
||||
void* callback_userdata,
|
||||
commit_callback_t commit_callback,
|
||||
F32 initial_value, F32 min_value, F32 max_value, F32 increment,
|
||||
const std::string& control_which = LLStringUtil::null );
|
||||
|
||||
@@ -114,10 +113,9 @@ public:
|
||||
|
||||
virtual std::string getControlName() const { return mSlider->getControlName(); }
|
||||
|
||||
static void onSliderCommit(LLUICtrl* caller, void* userdata);
|
||||
static void onSliderCommit(LLUICtrl* ctrl, const LLSD& userdata);
|
||||
|
||||
static void onEditorCommit(LLUICtrl* caller, void* userdata);
|
||||
static void onEditorChangeFocus(LLUICtrl* caller, S32 direction, void *userdata);
|
||||
static void onEditorCommit(LLUICtrl* ctrl, const LLSD& userdata);
|
||||
|
||||
private:
|
||||
void updateText();
|
||||
|
||||
@@ -54,13 +54,12 @@ const U32 MAX_STRING_LENGTH = 32;
|
||||
static LLRegisterWidget<LLSpinCtrl> r2("spinner");
|
||||
|
||||
LLSpinCtrl::LLSpinCtrl( const std::string& name, const LLRect& rect, const std::string& label, const LLFontGL* font,
|
||||
void (*commit_callback)(LLUICtrl*, void*),
|
||||
void* callback_user_data,
|
||||
commit_callback_t commit_callback,
|
||||
F32 initial_value, F32 min_value, F32 max_value, F32 increment,
|
||||
const std::string& control_name,
|
||||
S32 label_width)
|
||||
:
|
||||
LLUICtrl(name, rect, TRUE, commit_callback, callback_user_data, FOLLOWS_LEFT | FOLLOWS_TOP ),
|
||||
LLUICtrl(name, rect, TRUE, commit_callback, FOLLOWS_LEFT | FOLLOWS_TOP ),
|
||||
mValue( initial_value ),
|
||||
mInitialValue( initial_value ),
|
||||
mMaxValue( max_value ),
|
||||
@@ -98,10 +97,10 @@ LLSpinCtrl::LLSpinCtrl( const std::string& name, const LLRect& rect, const std::
|
||||
out_id,
|
||||
in_id,
|
||||
LLStringUtil::null,
|
||||
&LLSpinCtrl::onUpBtn, this, LLFontGL::getFontSansSerif() );
|
||||
boost::bind(&LLSpinCtrl::onUpBtn, this, _2), LLFontGL::getFontSansSerif() );
|
||||
mUpBtn->setFollowsLeft();
|
||||
mUpBtn->setFollowsBottom();
|
||||
mUpBtn->setHeldDownCallback(boost::bind(&LLSpinCtrl::onUpBtn,this));
|
||||
mUpBtn->setHeldDownCallback(boost::bind(&LLSpinCtrl::onUpBtn,this, _2));
|
||||
mUpBtn->setTabStop(FALSE);
|
||||
addChild(mUpBtn);
|
||||
|
||||
@@ -112,17 +111,17 @@ LLSpinCtrl::LLSpinCtrl( const std::string& name, const LLRect& rect, const std::
|
||||
out_id,
|
||||
in_id,
|
||||
LLStringUtil::null,
|
||||
&LLSpinCtrl::onDownBtn, this, LLFontGL::getFontSansSerif() );
|
||||
boost::bind(&LLSpinCtrl::onDownBtn, this, _2), LLFontGL::getFontSansSerif() );
|
||||
mDownBtn->setFollowsLeft();
|
||||
mDownBtn->setFollowsBottom();
|
||||
mDownBtn->setHeldDownCallback(boost::bind(&LLSpinCtrl::onDownBtn,this));
|
||||
mDownBtn->setHeldDownCallback(boost::bind(&LLSpinCtrl::onDownBtn,this, _2));
|
||||
mDownBtn->setTabStop(FALSE);
|
||||
addChild(mDownBtn);
|
||||
|
||||
LLRect editor_rect( btn_right + 1, centered_top, getRect().getWidth(), centered_bottom );
|
||||
mEditor = new LLLineEditor( std::string("SpinCtrl Editor"), editor_rect, LLStringUtil::null, font,
|
||||
MAX_STRING_LENGTH,
|
||||
&LLSpinCtrl::onEditorCommit, NULL, NULL, this,
|
||||
boost::bind(&LLSpinCtrl::onEditorCommit, this, _2), NULL, NULL,
|
||||
&LLLineEditor::prevalidateASCII );
|
||||
mEditor->setFollowsLeft();
|
||||
mEditor->setFollowsBottom();
|
||||
@@ -186,60 +185,59 @@ F32 get_increment(F32 inc, S32 decimal_precision) //CF: finetune increments
|
||||
|
||||
|
||||
// static
|
||||
void LLSpinCtrl::onUpBtn( void *userdata )
|
||||
void LLSpinCtrl::onUpBtn( const LLSD& data )
|
||||
{
|
||||
LLSpinCtrl* self = (LLSpinCtrl*) userdata;
|
||||
if( self->getEnabled() )
|
||||
if( getEnabled() )
|
||||
{
|
||||
// use getValue()/setValue() to force reload from/to control
|
||||
F32 val = (F32)self->getValue().asReal() + get_increment(self->mIncrement, self->mPrecision);
|
||||
val = clamp_precision(val, self->mPrecision);
|
||||
val = llmin( val, self->mMaxValue );
|
||||
F32 val = (F32)getValue().asReal() + get_increment(mIncrement, mPrecision);
|
||||
val = clamp_precision(val, mPrecision);
|
||||
val = llmin( val, mMaxValue );
|
||||
if (val < mMinValue) val = mMinValue;
|
||||
if (val > mMaxValue) val = mMaxValue;
|
||||
|
||||
F32 saved_val = (F32)self->getValue().asReal();
|
||||
self->setValue(val);
|
||||
if( (self->mValidateCallback && !self->mValidateCallback( self, self->mCallbackUserData ) ) ||
|
||||
(self->mValidateSignal && !(*(self->mValidateSignal))( self, val ) ))
|
||||
F32 saved_val = (F32)getValue().asReal();
|
||||
setValue(val);
|
||||
if( (mValidateCallback && !mValidateCallback( this, mCallbackUserData ) ) ||
|
||||
(mValidateSignal && !(*mValidateSignal)( this, val ) ))
|
||||
{
|
||||
self->setValue( saved_val );
|
||||
self->reportInvalidData();
|
||||
self->updateEditor();
|
||||
setValue( saved_val );
|
||||
reportInvalidData();
|
||||
updateEditor();
|
||||
return;
|
||||
}
|
||||
|
||||
self->updateEditor();
|
||||
self->onCommit();
|
||||
updateEditor();
|
||||
onCommit();
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLSpinCtrl::onDownBtn( void *userdata )
|
||||
|
||||
void LLSpinCtrl::onDownBtn( const LLSD& data )
|
||||
{
|
||||
LLSpinCtrl* self = (LLSpinCtrl*) userdata;
|
||||
|
||||
if( self->getEnabled() )
|
||||
if( getEnabled() )
|
||||
{
|
||||
F32 val = (F32)self->getValue().asReal() - get_increment(self->mIncrement, self->mPrecision);
|
||||
val = clamp_precision(val, self->mPrecision);
|
||||
val = llmax( val, self->mMinValue );
|
||||
F32 val = (F32)getValue().asReal() - get_increment(mIncrement, mPrecision);
|
||||
val = clamp_precision(val, mPrecision);
|
||||
val = llmax( val, mMinValue );
|
||||
|
||||
|
||||
if (val < self->mMinValue) val = self->mMinValue;
|
||||
if (val > self->mMaxValue) val = self->mMaxValue;
|
||||
if (val < mMinValue) val = mMinValue;
|
||||
if (val > mMaxValue) val = mMaxValue;
|
||||
|
||||
F32 saved_val = (F32)self->getValue().asReal();
|
||||
self->setValue(val);
|
||||
if( (self->mValidateCallback && !self->mValidateCallback( self, self->mCallbackUserData ) ) ||
|
||||
(self->mValidateSignal && !(*(self->mValidateSignal))( self, val ) ))
|
||||
F32 saved_val = (F32)getValue().asReal();
|
||||
setValue(val);
|
||||
if( (mValidateCallback && !mValidateCallback( this, mCallbackUserData ) ) ||
|
||||
(mValidateSignal && !(*mValidateSignal)( this, val ) ))
|
||||
{
|
||||
self->setValue( saved_val );
|
||||
self->reportInvalidData();
|
||||
self->updateEditor();
|
||||
setValue( saved_val );
|
||||
reportInvalidData();
|
||||
updateEditor();
|
||||
return;
|
||||
}
|
||||
|
||||
self->updateEditor();
|
||||
self->onCommit();
|
||||
updateEditor();
|
||||
onCommit();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -278,7 +276,13 @@ void LLSpinCtrl::clear()
|
||||
mbHasBeenSet = FALSE;
|
||||
}
|
||||
|
||||
|
||||
void LLSpinCtrl::updateLabelColor()
|
||||
{
|
||||
if( mLabelBox )
|
||||
{
|
||||
mLabelBox->setColor( getEnabled() ? mTextEnabledColor : mTextDisabledColor );
|
||||
}
|
||||
}
|
||||
|
||||
void LLSpinCtrl::updateEditor()
|
||||
{
|
||||
@@ -297,52 +301,50 @@ void LLSpinCtrl::updateEditor()
|
||||
mEditor->setText( text );
|
||||
}
|
||||
|
||||
void LLSpinCtrl::onEditorCommit( LLUICtrl* caller, void *userdata )
|
||||
void LLSpinCtrl::onEditorCommit( const LLSD& data )
|
||||
{
|
||||
BOOL success = FALSE;
|
||||
|
||||
LLSpinCtrl* self = (LLSpinCtrl*) userdata;
|
||||
llassert( caller == self->mEditor );
|
||||
|
||||
if( self->mEditor->evaluateFloat() )
|
||||
if( mEditor->evaluateFloat() )
|
||||
{
|
||||
std::string text = self->mEditor->getText();
|
||||
std::string text = mEditor->getText();
|
||||
|
||||
LLLocale locale(LLLocale::USER_LOCALE);
|
||||
F32 val = (F32) atof(text.c_str());
|
||||
|
||||
if (val < self->mMinValue) val = self->mMinValue;
|
||||
if (val > self->mMaxValue) val = self->mMaxValue;
|
||||
if (val < mMinValue) val = mMinValue;
|
||||
if (val > mMaxValue) val = mMaxValue;
|
||||
|
||||
F32 saved_val = self->mValue;
|
||||
self->mValue = val;
|
||||
F32 saved_val = mValue;
|
||||
mValue = val;
|
||||
|
||||
if( (!self->mValidateCallback || self->mValidateCallback( self, self->mCallbackUserData )) &&
|
||||
(!self->mValidateSignal || (*(self->mValidateSignal))(self, val)))
|
||||
if( (!mValidateCallback || mValidateCallback( this, mCallbackUserData )) &&
|
||||
(!mValidateSignal || (*mValidateSignal)(this, val) ))
|
||||
{
|
||||
success = TRUE;
|
||||
self->onCommit();
|
||||
onCommit();
|
||||
}
|
||||
else
|
||||
{
|
||||
self->mValue = saved_val;
|
||||
mValue = saved_val;
|
||||
}
|
||||
}
|
||||
updateEditor();
|
||||
|
||||
if( success )
|
||||
{
|
||||
self->updateEditor();
|
||||
updateEditor();
|
||||
}
|
||||
else
|
||||
{
|
||||
self->reportInvalidData();
|
||||
reportInvalidData();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LLSpinCtrl::forceEditorCommit()
|
||||
{
|
||||
onEditorCommit(mEditor, this);
|
||||
onEditorCommit( LLSD() );
|
||||
}
|
||||
|
||||
|
||||
@@ -356,6 +358,7 @@ void LLSpinCtrl::setEnabled(BOOL b)
|
||||
{
|
||||
LLView::setEnabled( b );
|
||||
mEditor->setEnabled( b );
|
||||
updateLabelColor();
|
||||
}
|
||||
|
||||
|
||||
@@ -403,6 +406,7 @@ void LLSpinCtrl::setLabel(const LLStringExplicit& label)
|
||||
{
|
||||
llwarns << "Attempting to set label on LLSpinCtrl constructed without one " << getName() << llendl;
|
||||
}
|
||||
updateLabelColor();
|
||||
}
|
||||
|
||||
BOOL LLSpinCtrl::setLabelArg( const std::string& key, const LLStringExplicit& text )
|
||||
@@ -434,29 +438,19 @@ void LLSpinCtrl::reportInvalidData()
|
||||
make_ui_sound("UISndBadKeystroke");
|
||||
}
|
||||
|
||||
void LLSpinCtrl::draw()
|
||||
{
|
||||
if( mLabelBox )
|
||||
{
|
||||
mLabelBox->setColor( getEnabled() ? mTextEnabledColor : mTextDisabledColor );
|
||||
}
|
||||
LLUICtrl::draw();
|
||||
}
|
||||
|
||||
|
||||
BOOL LLSpinCtrl::handleScrollWheel(S32 x, S32 y, S32 clicks)
|
||||
{
|
||||
if( clicks > 0 )
|
||||
{
|
||||
while( clicks-- )
|
||||
{
|
||||
LLSpinCtrl::onDownBtn(this);
|
||||
onDownBtn(getValue());
|
||||
}
|
||||
}
|
||||
else
|
||||
while( clicks++ )
|
||||
{
|
||||
LLSpinCtrl::onUpBtn(this);
|
||||
onUpBtn(getValue());
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
@@ -476,12 +470,12 @@ BOOL LLSpinCtrl::handleKeyHere(KEY key, MASK mask)
|
||||
}
|
||||
if(key == KEY_UP)
|
||||
{
|
||||
LLSpinCtrl::onUpBtn(this);
|
||||
onUpBtn(getValue());
|
||||
return TRUE;
|
||||
}
|
||||
if(key == KEY_DOWN)
|
||||
{
|
||||
LLSpinCtrl::onDownBtn(this);
|
||||
onDownBtn(getValue());
|
||||
return TRUE;
|
||||
}
|
||||
if(key == KEY_RETURN)
|
||||
@@ -557,8 +551,6 @@ LLView* LLSpinCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *
|
||||
BOOL allow_text_entry = TRUE;
|
||||
node->getAttributeBOOL("allow_text_entry", allow_text_entry);
|
||||
|
||||
LLUICtrlCallback callback = NULL;
|
||||
|
||||
if(label.empty())
|
||||
{
|
||||
label.assign( node->getValue() );
|
||||
@@ -568,7 +560,6 @@ LLView* LLSpinCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *
|
||||
rect,
|
||||
label,
|
||||
font,
|
||||
callback,
|
||||
NULL,
|
||||
initial_value,
|
||||
min_value,
|
||||
|
||||
@@ -56,8 +56,7 @@ public:
|
||||
LLSpinCtrl(const std::string& name, const LLRect& rect,
|
||||
const std::string& label,
|
||||
const LLFontGL* font,
|
||||
void (*commit_callback)(LLUICtrl*, void*),
|
||||
void* callback_userdata,
|
||||
commit_callback_t commit_callback,
|
||||
F32 initial_value, F32 min_value, F32 max_value, F32 increment,
|
||||
const std::string& control_name = std::string(),
|
||||
S32 label_width = SPINCTRL_DEFAULT_LABEL_WIDTH );
|
||||
@@ -93,8 +92,8 @@ public:
|
||||
virtual F32 getIncrement() { return mIncrement ; }
|
||||
|
||||
void setLabel(const LLStringExplicit& label);
|
||||
void setLabelColor(const LLColor4& c) { mTextEnabledColor = c; }
|
||||
void setDisabledLabelColor(const LLColor4& c) { mTextDisabledColor = c; }
|
||||
void setLabelColor(const LLColor4& c) { mTextEnabledColor = c; updateLabelColor(); }
|
||||
void setDisabledLabelColor(const LLColor4& c) { mTextDisabledColor = c; updateLabelColor();}
|
||||
void setAllowEdit(BOOL allow_edit);
|
||||
|
||||
virtual void onTabInto();
|
||||
@@ -107,17 +106,15 @@ public:
|
||||
virtual BOOL handleScrollWheel(S32 x,S32 y,S32 clicks);
|
||||
virtual BOOL handleKeyHere(KEY key, MASK mask);
|
||||
|
||||
virtual void draw();
|
||||
void onEditorCommit(const LLSD& data);
|
||||
|
||||
static void onEditorCommit(LLUICtrl* caller, void* userdata);
|
||||
static void onEditorChangeFocus(LLUICtrl* caller, S32 direction, void *userdata);
|
||||
|
||||
static void onUpBtn(void *userdata);
|
||||
static void onDownBtn(void *userdata);
|
||||
void onUpBtn(const LLSD& data);
|
||||
void onDownBtn(const LLSD& data);
|
||||
|
||||
virtual BOOL setLabelArg( const std::string& key, const LLStringExplicit& text );
|
||||
|
||||
private:
|
||||
void updateLabelColor();
|
||||
void updateEditor();
|
||||
void reportInvalidData();
|
||||
|
||||
|
||||
@@ -30,7 +30,8 @@
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
//#include "llviewerprecompiledheaders.h"
|
||||
#include "linden_common.h"
|
||||
|
||||
#include "llstatbar.h"
|
||||
|
||||
@@ -40,30 +41,31 @@
|
||||
#include "llfontgl.h"
|
||||
|
||||
#include "llstat.h"
|
||||
#include "lluictrlfactory.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
LLStatBar::LLStatBar(const std::string& name, const LLRect& rect, const std::string& setting,
|
||||
BOOL default_bar, BOOL default_history)
|
||||
: LLView(name, rect, TRUE),
|
||||
mSetting(setting)
|
||||
mSetting(setting),
|
||||
mLabel(name),
|
||||
mMinBar(0.f),
|
||||
mMaxBar(50.f),
|
||||
mStatp(NULL),
|
||||
mTickSpacing(10.f),
|
||||
mLabelSpacing(10.f),
|
||||
mPrecision(0),
|
||||
mUpdatesPerSec(5),
|
||||
mPerSec(true),
|
||||
mDisplayMean(true)
|
||||
{
|
||||
mMinBar = 0.f;
|
||||
mMaxBar = 50.f;
|
||||
mStatp = NULL;
|
||||
mTickSpacing = 10.f;
|
||||
mLabelSpacing = 10.f;
|
||||
mPrecision = 0;
|
||||
mUpdatesPerSec = 5;
|
||||
mLabel = name;
|
||||
mPerSec = TRUE;
|
||||
mValue = 0.f;
|
||||
mDisplayMean = TRUE;
|
||||
|
||||
S32 mode = -1;
|
||||
if (mSetting.length() > 0)
|
||||
{
|
||||
mode = gSavedSettings.getS32(mSetting);
|
||||
mode = LLUI::sConfigGroup->getS32(mSetting);
|
||||
|
||||
}
|
||||
|
||||
@@ -114,7 +116,7 @@ BOOL LLStatBar::handleMouseDown(S32 x, S32 y, MASK mask)
|
||||
mode |= STAT_HISTORY_FLAG;
|
||||
}
|
||||
|
||||
gSavedSettings.setS32(mSetting, mode);
|
||||
LLUI::sConfigGroup->setS32(mSetting, mode);
|
||||
}
|
||||
|
||||
|
||||
@@ -294,16 +296,6 @@ void LLStatBar::draw()
|
||||
LLView::draw();
|
||||
}
|
||||
|
||||
const std::string& LLStatBar::getLabel() const
|
||||
{
|
||||
return mLabel;
|
||||
}
|
||||
|
||||
void LLStatBar::setLabel(const std::string& label)
|
||||
{
|
||||
mLabel = label;
|
||||
}
|
||||
|
||||
void LLStatBar::setUnitLabel(const std::string& unit_label)
|
||||
{
|
||||
mUnitLabel = unit_label;
|
||||
@@ -317,7 +309,7 @@ LLRect LLStatBar::getRequiredRect()
|
||||
{
|
||||
if (mDisplayHistory)
|
||||
{
|
||||
rect.mTop = 67;
|
||||
rect.mTop = 35 + mStatp->getNumBins();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -35,7 +35,6 @@
|
||||
|
||||
#include "llview.h"
|
||||
#include "llframetimer.h"
|
||||
#include "llviewercontrol.h"
|
||||
|
||||
class LLStat;
|
||||
|
||||
@@ -54,8 +53,6 @@ public:
|
||||
virtual void draw();
|
||||
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
|
||||
|
||||
const std::string& getLabel() const;
|
||||
void setLabel(const std::string& label);
|
||||
void setUnitLabel(const std::string& unit_label);
|
||||
/*virtual*/ LLRect getRequiredRect(); // Return the height of this object, given the set options.
|
||||
|
||||
@@ -64,16 +61,16 @@ public:
|
||||
F32 mTickSpacing;
|
||||
F32 mLabelSpacing;
|
||||
U32 mPrecision;
|
||||
F32 mUpdatesPerSec;
|
||||
BOOL mPerSec; // Use the per sec stats.
|
||||
BOOL mDisplayBar; // Display the bar graph.
|
||||
BOOL mDisplayHistory;
|
||||
BOOL mDisplayMean; // If true, display mean, if false, display current value
|
||||
|
||||
F32 mUpdatesPerSec;
|
||||
LLStat *mStatp;
|
||||
private:
|
||||
LLFrameTimer mUpdateTimer;
|
||||
std::string mLabel;
|
||||
LLUIString mLabel;
|
||||
std::string mUnitLabel;
|
||||
F32 mValue;
|
||||
std::string mSetting;
|
||||
@@ -30,7 +30,8 @@
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
//#include "llviewerprecompiledheaders.h"
|
||||
#include "linden_common.h"
|
||||
|
||||
#include "llstatgraph.h"
|
||||
#include "llrender.h"
|
||||
@@ -40,7 +41,7 @@
|
||||
#include "llstat.h"
|
||||
#include "llgl.h"
|
||||
#include "llglheaders.h"
|
||||
#include "llviewercontrol.h"
|
||||
//#include "llviewercontrol.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -109,7 +110,7 @@ void LLStatGraph::draw()
|
||||
// gColors.getColor("ColorDropShadow"),
|
||||
// (S32) gSavedSettings.getF32("DropShadowFloater") );
|
||||
|
||||
static const LLCachedControl<LLColor4> menu_default_color(gColors,"MenuDefaultBgColor",LLColor4(0.f,0.f,0.f,1.f));
|
||||
static const LLCachedControl<LLColor4> menu_default_color(*LLUI::sColorsGroup,"MenuDefaultBgColor",LLColor4(0.f,0.f,0.f,1.f));
|
||||
color = menu_default_color;
|
||||
gGL.color4fv(color.mV);
|
||||
gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, TRUE);
|
||||
@@ -30,7 +30,7 @@
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
#include "linden_common.h"
|
||||
|
||||
#include "llstatview.h"
|
||||
|
||||
@@ -39,23 +39,21 @@
|
||||
#include "llfontgl.h"
|
||||
#include "llgl.h"
|
||||
#include "llui.h"
|
||||
#include "lluictrlfactory.h"
|
||||
|
||||
#include "llstatbar.h"
|
||||
#include "llviewercontrol.h"
|
||||
|
||||
LLStatView::LLStatView(const std::string& name, const std::string& label, const std::string& setting, const LLRect& rect)
|
||||
: LLContainerView(name, rect),
|
||||
mNumStatBars(0),
|
||||
mSetting(setting)
|
||||
LLStatView::LLStatView(const LLStatView::Params& p)
|
||||
: LLContainerView(p),
|
||||
mNumStatBars(0),
|
||||
mSetting(p.setting)
|
||||
{
|
||||
setFollows(FOLLOWS_TOP | FOLLOWS_LEFT);
|
||||
setLabel(label);
|
||||
BOOL open = FALSE;
|
||||
BOOL isopen = getDisplayChildren();
|
||||
if (mSetting.length() > 0)
|
||||
{
|
||||
open = gSavedSettings.getBOOL(mSetting);
|
||||
isopen = LLUI::sConfigGroup->getBOOL(mSetting);
|
||||
}
|
||||
setDisplayChildren(open); /* Flawfinder: ignore */
|
||||
setDisplayChildren(isopen);
|
||||
}
|
||||
|
||||
LLStatView::~LLStatView()
|
||||
@@ -63,8 +61,8 @@ LLStatView::~LLStatView()
|
||||
// Children all cleaned up by default view destructor.
|
||||
if (mSetting.length() > 0)
|
||||
{
|
||||
BOOL open = getDisplayChildren();
|
||||
gSavedSettings.setBOOL(mSetting, open); /* Flawfinder: ignore */
|
||||
BOOL isopen = getDisplayChildren();
|
||||
LLUI::sConfigGroup->setBOOL(mSetting, isopen); /* Flawfinder: ignore */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,12 +72,6 @@ LLStatBar *LLStatView::addStat(const std::string& name, LLStat *statp,
|
||||
LLStatBar *stat_barp;
|
||||
LLRect r;
|
||||
|
||||
// if (getStatBar(name))
|
||||
// {
|
||||
// llinfos << "LLStatView::addStat - Stat already exists!" << llendl;
|
||||
// return NULL;
|
||||
// }
|
||||
|
||||
mNumStatBars++;
|
||||
|
||||
stat_barp = new LLStatBar(name, r, setting, default_bar, default_history);
|
||||
@@ -94,27 +86,10 @@ LLStatBar *LLStatView::addStat(const std::string& name, LLStat *statp,
|
||||
return stat_barp;
|
||||
}
|
||||
|
||||
LLStatView *LLStatView::addStatView(const std::string& name, const std::string& label, const std::string& setting, const LLRect& rect)
|
||||
LLStatView *LLStatView::addStatView(LLStatView::Params& p)
|
||||
{
|
||||
LLStatView *statview = new LLStatView(name, label, setting, rect);
|
||||
LLStatView* statview = LLUICtrlFactory::create<LLStatView>(p);
|
||||
statview->setVisible(mDisplayChildren);
|
||||
addChildInBack(statview);
|
||||
return statview;
|
||||
}
|
||||
|
||||
|
||||
LLStatBar *LLStatView::getStatBar(const std::string& name)
|
||||
{
|
||||
sb_vector_t::iterator iter;
|
||||
for(iter = mStatBars.begin(); iter != mStatBars.end(); ++iter)
|
||||
{
|
||||
LLStatBar *stat_barp = *iter;
|
||||
if (stat_barp->getLabel() == name)
|
||||
{
|
||||
return stat_barp;
|
||||
}
|
||||
}
|
||||
|
||||
// Not found!
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@@ -42,20 +42,25 @@ class LLStatBar;
|
||||
class LLStatView : public LLContainerView
|
||||
{
|
||||
public:
|
||||
LLStatView(const std::string& name, const std::string& label, const std::string& setting, const LLRect& rect);
|
||||
struct Params : public LLInitParam::Block<Params, LLContainerView::Params>
|
||||
{
|
||||
Optional<std::string> setting;
|
||||
Params()
|
||||
: setting("setting")
|
||||
{
|
||||
changeDefault(follows.flags, FOLLOWS_TOP | FOLLOWS_LEFT);
|
||||
}
|
||||
};
|
||||
~LLStatView();
|
||||
|
||||
/*
|
||||
virtual void draw();
|
||||
virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
|
||||
virtual LLRect getRequiredRect(); // Return the height of this object, given the set options.
|
||||
*/
|
||||
protected:
|
||||
LLStatView(const Params&);
|
||||
friend class LLUICtrlFactory;
|
||||
public:
|
||||
|
||||
LLStatBar *addStat(const std::string& name, LLStat *statp,
|
||||
const std::string& setting = std::string(), BOOL default_bar = FALSE, BOOL default_history = FALSE);
|
||||
LLStatBar *getStatBar(const std::string& name);
|
||||
LLStatView *addStatView(const std::string& name, const std::string& label, const std::string& setting, const LLRect& rect);
|
||||
|
||||
LLStatView *addStatView(LLStatView::Params& p);
|
||||
protected:
|
||||
typedef std::vector<LLStatBar *> sb_vector_t;
|
||||
sb_vector_t mStatBars;
|
||||
@@ -318,15 +318,15 @@ void LLTabContainer::draw()
|
||||
if( mIsVertical && has_scroll_arrows )
|
||||
{
|
||||
// Redraw the arrows so that they appears on top.
|
||||
gGL.pushMatrix();
|
||||
gGL.translatef((F32)mPrevArrowBtn->getRect().mLeft, (F32)mPrevArrowBtn->getRect().mBottom, 0.f);
|
||||
gGL.pushUIMatrix();
|
||||
gGL.translateUI((F32)mPrevArrowBtn->getRect().mLeft, (F32)mPrevArrowBtn->getRect().mBottom, 0.f);
|
||||
mPrevArrowBtn->draw();
|
||||
gGL.popMatrix();
|
||||
gGL.popUIMatrix();
|
||||
|
||||
gGL.pushMatrix();
|
||||
gGL.translatef((F32)mNextArrowBtn->getRect().mLeft, (F32)mNextArrowBtn->getRect().mBottom, 0.f);
|
||||
gGL.pushUIMatrix();
|
||||
gGL.translateUI((F32)mNextArrowBtn->getRect().mLeft, (F32)mNextArrowBtn->getRect().mBottom, 0.f);
|
||||
mNextArrowBtn->draw();
|
||||
gGL.popMatrix();
|
||||
gGL.popUIMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -817,7 +817,7 @@ void LLTabContainer::addTabPanel(LLPanel* child,
|
||||
btn_rect.translate(0, -LLBUTTON_V_PAD-2);
|
||||
textbox = new LLTextBox(trimmed_label, btn_rect, trimmed_label, font);
|
||||
|
||||
btn = new LLButton(LLStringUtil::null, LLRect(0,0,0,0));
|
||||
btn = new LLButton(LLStringUtil::null);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -828,7 +828,7 @@ void LLTabContainer::addTabPanel(LLPanel* child,
|
||||
LLStringUtil::null,
|
||||
LLStringUtil::null,
|
||||
LLStringUtil::null,
|
||||
NULL, NULL,
|
||||
NULL,
|
||||
font,
|
||||
trimmed_label, trimmed_label);
|
||||
btn->setImages(std::string("tab_left.tga"), std::string("tab_left_selected.tga"));
|
||||
@@ -850,7 +850,7 @@ void LLTabContainer::addTabPanel(LLPanel* child,
|
||||
btn = new LLButton(std::string(child->getName()) + " tab",
|
||||
btn_rect,
|
||||
LLStringUtil::null, LLStringUtil::null, LLStringUtil::null,
|
||||
NULL, NULL, // set userdata below
|
||||
NULL, // set userdata below
|
||||
font,
|
||||
trimmed_label, trimmed_label );
|
||||
btn->setVisible( FALSE );
|
||||
@@ -1646,19 +1646,17 @@ void LLTabContainer::initButtons()
|
||||
out_id = "UIImgBtnScrollUpOutUUID";
|
||||
in_id = "UIImgBtnScrollUpInUUID";
|
||||
mPrevArrowBtn = new LLButton(std::string("Up Arrow"), up_arrow_btn_rect,
|
||||
out_id, in_id, LLStringUtil::null, NULL );
|
||||
out_id, in_id, LLStringUtil::null, boost::bind(&LLTabContainer::onPrevBtn,this,_2));
|
||||
mPrevArrowBtn->setFollowsTop();
|
||||
mPrevArrowBtn->setFollowsLeft();
|
||||
mPrevArrowBtn->setCommitCallback(boost::bind(&LLTabContainer::onPrevBtn,this,_2));
|
||||
mPrevArrowBtn->setHeldDownCallback(boost::bind(&LLTabContainer::onPrevBtnHeld, this, _2));
|
||||
|
||||
out_id = "UIImgBtnScrollDownOutUUID";
|
||||
in_id = "UIImgBtnScrollDownInUUID";
|
||||
mNextArrowBtn = new LLButton(std::string("Down Arrow"), down_arrow_btn_rect,
|
||||
out_id, in_id, LLStringUtil::null, NULL );
|
||||
out_id, in_id, LLStringUtil::null, boost::bind(&LLTabContainer::onNextBtn,this,_2) );
|
||||
mNextArrowBtn->setFollowsBottom();
|
||||
mNextArrowBtn->setFollowsLeft();
|
||||
mNextArrowBtn->setCommitCallback(boost::bind(&LLTabContainer::onNextBtn,this,_2));
|
||||
mNextArrowBtn->setHeldDownCallback(boost::bind(&LLTabContainer::onNextBtnHeld, this, _2));
|
||||
}
|
||||
else // Horizontal
|
||||
@@ -1697,17 +1695,14 @@ void LLTabContainer::initButtons()
|
||||
in_id = "UIImgBtnJumpLeftInUUID";
|
||||
mJumpPrevArrowBtn = new LLButton(std::string("Jump Left Arrow"), jump_left_arrow_btn_rect,
|
||||
out_id, in_id, LLStringUtil::null,
|
||||
NULL, NULL, LLFontGL::getFontSansSerif() );
|
||||
mJumpPrevArrowBtn->setCommitCallback(boost::bind(&LLTabContainer::onJumpFirstBtn, this, _2));
|
||||
boost::bind(&LLTabContainer::onJumpFirstBtn, this, _2), LLFontGL::getFontSansSerif() );
|
||||
mJumpPrevArrowBtn->setFollowsLeft();
|
||||
|
||||
out_id = "UIImgBtnScrollLeftOutUUID";
|
||||
in_id = "UIImgBtnScrollLeftInUUID";
|
||||
mPrevArrowBtn = new LLButton(std::string("Left Arrow"), left_arrow_btn_rect,
|
||||
out_id, in_id, LLStringUtil::null,
|
||||
NULL, NULL, LLFontGL::getFontSansSerif() );
|
||||
|
||||
mPrevArrowBtn->setCommitCallback(boost::bind(&LLTabContainer::onPrevBtn, this, _2));
|
||||
boost::bind(&LLTabContainer::onPrevBtn, this, _2), LLFontGL::getFontSansSerif() );
|
||||
mPrevArrowBtn->setHeldDownCallback(boost::bind(&LLTabContainer::onPrevBtnHeld, this, _2));
|
||||
mPrevArrowBtn->setFollowsLeft();
|
||||
|
||||
@@ -1715,16 +1710,14 @@ void LLTabContainer::initButtons()
|
||||
in_id = "UIImgBtnJumpRightInUUID";
|
||||
mJumpNextArrowBtn = new LLButton(std::string("Jump Right Arrow"), jump_right_arrow_btn_rect,
|
||||
out_id, in_id, LLStringUtil::null,
|
||||
NULL, NULL, LLFontGL::getFontSansSerif());
|
||||
mJumpNextArrowBtn->setCommitCallback(boost::bind(&LLTabContainer::onJumpLastBtn, this, _2));
|
||||
boost::bind(&LLTabContainer::onJumpLastBtn, this, _2), LLFontGL::getFontSansSerif());
|
||||
mJumpNextArrowBtn->setFollowsRight();
|
||||
|
||||
out_id = "UIImgBtnScrollRightOutUUID";
|
||||
in_id = "UIImgBtnScrollRightInUUID";
|
||||
mNextArrowBtn = new LLButton(std::string("Right Arrow"), right_arrow_btn_rect,
|
||||
out_id, in_id, LLStringUtil::null,
|
||||
NULL, NULL, LLFontGL::getFontSansSerif());
|
||||
mNextArrowBtn->setCommitCallback(boost::bind(&LLTabContainer::onNextBtn, this, _2));
|
||||
boost::bind(&LLTabContainer::onNextBtn, this, _2), LLFontGL::getFontSansSerif());
|
||||
mNextArrowBtn->setHeldDownCallback(boost::bind(&LLTabContainer::onNextBtnHeld, this, _2));
|
||||
mNextArrowBtn->setFollowsRight();
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ static LLRegisterWidget<LLTextBox> r("text");
|
||||
|
||||
LLTextBox::LLTextBox(const std::string& name, const LLRect& rect, const std::string& text,
|
||||
const LLFontGL* font, BOOL mouse_opaque)
|
||||
: LLUICtrl(name, rect, mouse_opaque, NULL, NULL, FOLLOWS_LEFT | FOLLOWS_TOP ),
|
||||
: LLUICtrl(name, rect, mouse_opaque, NULL, FOLLOWS_LEFT | FOLLOWS_TOP ),
|
||||
mFontGL(font ? font : LLFontGL::getFontSansSerifSmall())
|
||||
{
|
||||
initDefaults();
|
||||
@@ -50,7 +50,7 @@ LLTextBox::LLTextBox(const std::string& name, const LLRect& rect, const std::str
|
||||
|
||||
LLTextBox::LLTextBox(const std::string& name, const std::string& text, F32 max_width,
|
||||
const LLFontGL* font, BOOL mouse_opaque) :
|
||||
LLUICtrl(name, LLRect(0, 0, 1, 1), mouse_opaque, NULL, NULL, FOLLOWS_LEFT | FOLLOWS_TOP),
|
||||
LLUICtrl(name, LLRect(0, 0, 1, 1), mouse_opaque, NULL, FOLLOWS_LEFT | FOLLOWS_TOP),
|
||||
mFontGL(font ? font : LLFontGL::getFontSansSerifSmall())
|
||||
{
|
||||
initDefaults();
|
||||
@@ -60,7 +60,7 @@ LLTextBox::LLTextBox(const std::string& name, const std::string& text, F32 max_w
|
||||
}
|
||||
|
||||
LLTextBox::LLTextBox(const std::string& name_and_label, const LLRect& rect) :
|
||||
LLUICtrl(name_and_label, rect, TRUE, NULL, NULL, FOLLOWS_LEFT | FOLLOWS_TOP),
|
||||
LLUICtrl(name_and_label, rect, TRUE, NULL, FOLLOWS_LEFT | FOLLOWS_TOP),
|
||||
mFontGL(LLFontGL::getFontSansSerifSmall())
|
||||
{
|
||||
initDefaults();
|
||||
@@ -89,7 +89,6 @@ void LLTextBox::initDefaults()
|
||||
mHAlign = LLFontGL::LEFT;
|
||||
mVAlign = LLFontGL::TOP;
|
||||
mClickedCallback = NULL;
|
||||
mCallbackUserData = NULL;
|
||||
}
|
||||
|
||||
BOOL LLTextBox::handleMouseDown(S32 x, S32 y, MASK mask)
|
||||
@@ -140,7 +139,7 @@ BOOL LLTextBox::handleMouseUp(S32 x, S32 y, MASK mask)
|
||||
// If mouseup in the widget, it's been clicked
|
||||
if (mClickedCallback)
|
||||
{
|
||||
(*mClickedCallback)( mCallbackUserData );
|
||||
mClickedCallback();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -298,8 +297,7 @@ void LLTextBox::draw()
|
||||
|
||||
if (mBackgroundVisible)
|
||||
{
|
||||
LLRect r( 0, getRect().getHeight(), getRect().getWidth(), 0 );
|
||||
gl_rect_2d( r, mBackgroundColor );
|
||||
gl_rect_2d( getLocalRect(), mBackgroundColor );
|
||||
}
|
||||
|
||||
S32 text_x = 0;
|
||||
|
||||
@@ -43,6 +43,7 @@ class LLTextBox
|
||||
: public LLUICtrl
|
||||
{
|
||||
public:
|
||||
typedef boost::function<void (void)> callback_t;
|
||||
// By default, follows top and left and is mouse-opaque.
|
||||
// If no text, text = name.
|
||||
// If no font, uses default system font.
|
||||
@@ -93,7 +94,7 @@ public:
|
||||
void setVPad(S32 pixels) { mVPad = pixels; }
|
||||
void setRightAlign() { mHAlign = LLFontGL::RIGHT; }
|
||||
void setHAlign( LLFontGL::HAlign align ) { mHAlign = align; }
|
||||
void setClickedCallback( void (*cb)(void *data), void* data = NULL ){ mClickedCallback = cb; mCallbackUserData = data; } // mouse down and up within button
|
||||
void setClickedCallback( callback_t cb ) { mClickedCallback = cb; }
|
||||
|
||||
const LLFontGL* getFont() const { return mFontGL; }
|
||||
|
||||
@@ -137,7 +138,7 @@ private:
|
||||
LLFontGL::VAlign mVAlign;
|
||||
|
||||
std::vector<S32> mLineLengthList;
|
||||
void (*mClickedCallback)(void* data );
|
||||
callback_t mClickedCallback;
|
||||
void* mCallbackUserData;
|
||||
};
|
||||
|
||||
|
||||
@@ -257,7 +257,7 @@ LLTextEditor::LLTextEditor(
|
||||
const LLFontGL* font,
|
||||
BOOL allow_embedded_items)
|
||||
:
|
||||
LLUICtrl( name, rect, TRUE, NULL, NULL, FOLLOWS_TOP | FOLLOWS_LEFT ),
|
||||
LLUICtrl( name, rect, TRUE, NULL, FOLLOWS_TOP | FOLLOWS_LEFT ),
|
||||
mTextIsUpToDate(TRUE),
|
||||
mMaxTextByteLength( max_length ),
|
||||
mPopupMenuHandle(),
|
||||
@@ -331,7 +331,7 @@ LLTextEditor::LLTextEditor(
|
||||
lines_in_doc,
|
||||
0,
|
||||
page_size,
|
||||
NULL, this );
|
||||
NULL);
|
||||
mScrollbar->setFollowsRight();
|
||||
mScrollbar->setFollowsTop();
|
||||
mScrollbar->setFollowsBottom();
|
||||
@@ -373,8 +373,6 @@ LLTextEditor::~LLTextEditor()
|
||||
gFocusMgr.releaseFocusIfNeeded( this ); // calls onCommit()
|
||||
|
||||
// Scrollbar is deleted by LLView
|
||||
mHoverSegment = NULL;
|
||||
std::for_each(mSegments.begin(), mSegments.end(), DeletePointer());
|
||||
|
||||
std::for_each(mUndoStack.begin(), mUndoStack.end(), DeletePointer());
|
||||
//LLView::deleteViewByHandle(mPopupMenuHandle);
|
||||
@@ -946,10 +944,10 @@ const LLTextSegment* LLTextEditor::getPreviousSegment() const
|
||||
{
|
||||
// find segment index at character to left of cursor (or rightmost edge of selection)
|
||||
S32 idx = llmax(0, getSegmentIdxAtOffset(mCursorPos) - 1);
|
||||
return idx >= 0 ? mSegments[idx] : NULL;
|
||||
return idx >= 0 ? mSegments[idx] : LLTextSegmentPtr();
|
||||
}
|
||||
|
||||
void LLTextEditor::getSelectedSegments(std::vector<const LLTextSegment*>& segments) const
|
||||
void LLTextEditor::getSelectedSegments(std::vector<LLTextSegmentPtr>& segments) const
|
||||
{
|
||||
S32 left = hasSelection() ? llmin(mSelectionStart, mSelectionEnd) : mCursorPos;
|
||||
S32 right = hasSelection() ? llmax(mSelectionStart, mSelectionEnd) : mCursorPos;
|
||||
@@ -1527,7 +1525,7 @@ BOOL LLTextEditor::handleHover(S32 x, S32 y, MASK mask)
|
||||
// Check to see if we're over an HTML-style link
|
||||
if( !mSegments.empty() )
|
||||
{
|
||||
const LLTextSegment* cur_segment = getSegmentAtLocalPos( x, y );
|
||||
LLTextSegment* cur_segment = getSegmentAtLocalPos( x, y );
|
||||
if( cur_segment )
|
||||
{
|
||||
if(cur_segment->getStyle()->isLink())
|
||||
@@ -2128,6 +2126,8 @@ void LLTextEditor::cut()
|
||||
deleteSelection( FALSE );
|
||||
|
||||
needsReflow();
|
||||
|
||||
onKeyStroke();
|
||||
}
|
||||
|
||||
BOOL LLTextEditor::canCopy() const
|
||||
@@ -2244,6 +2244,8 @@ void LLTextEditor::pasteHelper(bool is_primary)
|
||||
deselect();
|
||||
|
||||
needsReflow();
|
||||
|
||||
onKeyStroke();
|
||||
}
|
||||
|
||||
|
||||
@@ -2506,6 +2508,10 @@ BOOL LLTextEditor::handleSpecialKey(const KEY key, const MASK mask, BOOL* return
|
||||
break;
|
||||
}
|
||||
|
||||
if (handled)
|
||||
{
|
||||
onKeyStroke();
|
||||
}
|
||||
return handled;
|
||||
}
|
||||
|
||||
@@ -2665,6 +2671,7 @@ BOOL LLTextEditor::handleUnicodeCharHere(llwchar uni_char)
|
||||
deselect();
|
||||
|
||||
needsReflow();
|
||||
onKeyStroke();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2723,6 +2730,7 @@ void LLTextEditor::doDelete()
|
||||
}
|
||||
|
||||
needsReflow();
|
||||
onKeyStroke();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -2766,6 +2774,7 @@ void LLTextEditor::undo()
|
||||
setCursorPos(pos);
|
||||
|
||||
needsReflow();
|
||||
onKeyStroke();
|
||||
}
|
||||
|
||||
BOOL LLTextEditor::canRedo() const
|
||||
@@ -2808,6 +2817,7 @@ void LLTextEditor::redo()
|
||||
setCursorPos(pos);
|
||||
|
||||
needsReflow();
|
||||
onKeyStroke();
|
||||
}
|
||||
|
||||
void LLTextEditor::onFocusReceived()
|
||||
@@ -3635,7 +3645,6 @@ void LLTextEditor::onTabInto()
|
||||
void LLTextEditor::clear()
|
||||
{
|
||||
setText(LLStringUtil::null);
|
||||
std::for_each(mSegments.begin(), mSegments.end(), DeletePointer());
|
||||
mSegments.clear();
|
||||
}
|
||||
|
||||
@@ -4153,7 +4162,7 @@ void LLTextEditor::appendText(const std::string &new_text, bool allow_undo, bool
|
||||
{
|
||||
S32 segment_start = old_length;
|
||||
S32 segment_end = getLength();
|
||||
LLTextSegment* segment = new LLTextSegment(stylep, segment_start, segment_end );
|
||||
LLTextSegmentPtr segment = new LLTextSegment(stylep, segment_start, segment_end );
|
||||
mSegments.push_back(segment);
|
||||
}
|
||||
|
||||
@@ -4371,13 +4380,12 @@ void LLTextEditor::updateSegments()
|
||||
// Make sure we have at least one segment
|
||||
if (mSegments.size() == 1 && mSegments[0]->getIsDefault())
|
||||
{
|
||||
delete mSegments[0];
|
||||
mSegments.clear(); // create default segment
|
||||
}
|
||||
if (mSegments.empty())
|
||||
{
|
||||
LLColor4& text_color = ( mReadOnly ? mReadOnlyFgColor : mFgColor );
|
||||
LLTextSegment* default_segment = new LLTextSegment( text_color, 0, mWText.length() );
|
||||
LLTextSegmentPtr default_segment = new LLTextSegment( text_color, 0, mWText.length() );
|
||||
default_segment->setIsDefault(TRUE);
|
||||
mSegments.push_back(default_segment);
|
||||
}
|
||||
@@ -4408,7 +4416,6 @@ void LLTextEditor::pruneSegments()
|
||||
{
|
||||
// erase invalid segments
|
||||
++iter;
|
||||
std::for_each(iter, mSegments.end(), DeletePointer());
|
||||
mSegments.erase(iter, mSegments.end());
|
||||
}
|
||||
else
|
||||
@@ -4420,7 +4427,6 @@ void LLTextEditor::pruneSegments()
|
||||
void LLTextEditor::findEmbeddedItemSegments()
|
||||
{
|
||||
mHoverSegment = NULL;
|
||||
std::for_each(mSegments.begin(), mSegments.end(), DeletePointer());
|
||||
mSegments.clear();
|
||||
|
||||
BOOL found_embedded_items = FALSE;
|
||||
@@ -4501,18 +4507,18 @@ BOOL LLTextEditor::handleMouseUpOverSegment(S32 x, S32 y, MASK mask)
|
||||
|
||||
|
||||
// Finds the text segment (if any) at the give local screen position
|
||||
const LLTextSegment* LLTextEditor::getSegmentAtLocalPos( S32 x, S32 y ) const
|
||||
LLTextSegment* LLTextEditor::getSegmentAtLocalPos( S32 x, S32 y ) const
|
||||
{
|
||||
// Find the cursor position at the requested local screen position
|
||||
S32 offset = getCursorPosFromLocalCoord( x, y, FALSE );
|
||||
S32 idx = getSegmentIdxAtOffset(offset);
|
||||
return idx >= 0 ? mSegments[idx] : NULL;
|
||||
return idx >= 0 ? mSegments[idx] : LLTextSegmentPtr();
|
||||
}
|
||||
|
||||
const LLTextSegment* LLTextEditor::getSegmentAtOffset(S32 offset) const
|
||||
{
|
||||
S32 idx = getSegmentIdxAtOffset(offset);
|
||||
return idx >= 0 ? mSegments[idx] : NULL;
|
||||
return idx >= 0 ? mSegments[idx] : LLTextSegmentPtr();
|
||||
}
|
||||
|
||||
S32 LLTextEditor::getSegmentIdxAtOffset(S32 offset) const
|
||||
@@ -5068,6 +5074,7 @@ void LLTextEditor::updatePreedit(const LLWString &preedit_string,
|
||||
|
||||
// Update of the preedit should be caused by some key strokes.
|
||||
mKeystrokeTimer.reset();
|
||||
onKeyStroke();
|
||||
}
|
||||
|
||||
BOOL LLTextEditor::getPreeditLocation(S32 query_offset, LLCoordGL *coord, LLRect *bounds, LLRect *control) const
|
||||
@@ -5226,3 +5233,13 @@ S32 LLTextEditor::getPreeditFontSize() const
|
||||
{
|
||||
return llround(mGLFont->getLineHeight() * LLUI::getScaleFactor().mV[VY]);
|
||||
}
|
||||
|
||||
void LLTextEditor::setKeystrokeCallback(const keystroke_signal_t::slot_type& callback)
|
||||
{
|
||||
mKeystrokeSignal.connect(callback);
|
||||
}
|
||||
|
||||
void LLTextEditor::onKeyStroke()
|
||||
{
|
||||
mKeystrokeSignal(this);
|
||||
}
|
||||
|
||||
@@ -73,6 +73,10 @@ public:
|
||||
|
||||
virtual ~LLTextEditor();
|
||||
|
||||
typedef boost::signals2::signal<void (LLTextEditor* caller)> keystroke_signal_t;
|
||||
|
||||
void setKeystrokeCallback(const keystroke_signal_t::slot_type& callback);
|
||||
|
||||
virtual LLXMLNodePtr getXML(bool save_children = true) const;
|
||||
static LLView* fromXML(LLXMLNodePtr node, LLView *parent, class LLUICtrlFactory *factory);
|
||||
void setTextEditorParameters(LLXMLNodePtr node);
|
||||
@@ -289,7 +293,7 @@ public:
|
||||
|
||||
const LLTextSegment* getCurrentSegment() const { return getSegmentAtOffset(mCursorPos); }
|
||||
const LLTextSegment* getPreviousSegment() const;
|
||||
void getSelectedSegments(std::vector<const LLTextSegment*>& segments) const;
|
||||
void getSelectedSegments(std::vector<LLTextSegmentPtr>& segments) const;
|
||||
|
||||
static bool isPartOfWord(llwchar c) { return ( (c == '_') || (c == '\'') || LLStringOps::isAlnum((char)c)); }
|
||||
|
||||
@@ -323,7 +327,7 @@ protected:
|
||||
void unindentLineBeforeCloseBrace();
|
||||
|
||||
S32 getSegmentIdxAtOffset(S32 offset) const;
|
||||
const LLTextSegment* getSegmentAtLocalPos(S32 x, S32 y) const;
|
||||
LLTextSegment* getSegmentAtLocalPos(S32 x, S32 y) const;
|
||||
const LLTextSegment* getSegmentAtOffset(S32 offset) const;
|
||||
|
||||
void reportBadKeystroke() { make_ui_sound("UISndBadKeystroke"); }
|
||||
@@ -458,9 +462,9 @@ protected:
|
||||
BOOL mParseHighlights;
|
||||
std::string mHTML;
|
||||
|
||||
typedef std::vector<LLTextSegment *> segment_list_t;
|
||||
typedef std::vector<LLTextSegmentPtr> segment_list_t;
|
||||
segment_list_t mSegments;
|
||||
const LLTextSegment* mHoverSegment;
|
||||
LLTextSegmentPtr mHoverSegment;
|
||||
|
||||
// Scrollbar data
|
||||
class LLScrollbar* mScrollbar;
|
||||
@@ -480,6 +484,7 @@ private:
|
||||
// Methods
|
||||
//
|
||||
void pasteHelper(bool is_primary);
|
||||
void onKeyStroke();
|
||||
|
||||
void updateSegments();
|
||||
void pruneSegments();
|
||||
@@ -603,11 +608,12 @@ private:
|
||||
BOOL mHandleEditKeysDirectly;
|
||||
|
||||
LLCoordGL mLastIMEPosition; // Last position of the IME editor
|
||||
keystroke_signal_t mKeystrokeSignal;
|
||||
}; // end class LLTextEditor
|
||||
|
||||
|
||||
|
||||
class LLTextSegment
|
||||
class LLTextSegment : public LLRefCount
|
||||
{
|
||||
public:
|
||||
// for creating a compare value
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
#include "lltrans.h"
|
||||
#include "llxmlnode.h"
|
||||
#include "lluictrlfactory.h"
|
||||
#include "llalertdialog.h"
|
||||
#include "llnotificationsutil.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
@@ -60,14 +60,16 @@ BOOL gShowTextEditCursor = TRUE;
|
||||
std::map<std::string, std::string> gTranslation;
|
||||
std::list<std::string> gUntranslated;
|
||||
|
||||
LLControlGroup* LLUI::sConfigGroup = NULL;
|
||||
LLControlGroup* LLUI::sIgnoresGroup = NULL;
|
||||
LLControlGroup* LLUI::sColorsGroup = NULL;
|
||||
LLUIAudioCallback LLUI::sAudioCallback = NULL;
|
||||
LLWindow* LLUI::sWindow = NULL;
|
||||
LLHtmlHelp* LLUI::sHtmlHelp = NULL;
|
||||
BOOL LLUI::sShowXUINames = FALSE;
|
||||
BOOL LLUI::sQAMode = FALSE;
|
||||
/*static*/ LLControlGroup* LLUI::sConfigGroup = NULL;
|
||||
/*static*/ LLControlGroup* LLUI::sAccountGroup = NULL;
|
||||
/*static*/ LLControlGroup* LLUI::sIgnoresGroup = NULL;
|
||||
/*static*/ LLControlGroup* LLUI::sColorsGroup = NULL;
|
||||
/*static*/ LLUIAudioCallback LLUI::sAudioCallback = NULL;
|
||||
/*static*/ LLWindow* LLUI::sWindow = NULL;
|
||||
/*static*/ LLView* LLUI::sRootView = NULL;
|
||||
/*static*/ LLHtmlHelp* LLUI::sHtmlHelp = NULL;
|
||||
/*static*/ BOOL LLUI::sShowXUINames = FALSE;
|
||||
/*static*/ BOOL LLUI::sQAMode = FALSE;
|
||||
|
||||
//
|
||||
// Functions
|
||||
@@ -115,6 +117,7 @@ bool handleShowXUINamesChanged(const LLSD& newvalue)
|
||||
}
|
||||
|
||||
void LLUI::initClass(LLControlGroup* config,
|
||||
LLControlGroup* account,
|
||||
LLControlGroup* ignores,
|
||||
LLControlGroup* colors,
|
||||
LLImageProviderInterface* image_provider,
|
||||
@@ -125,10 +128,12 @@ void LLUI::initClass(LLControlGroup* config,
|
||||
{
|
||||
LLRender2D::initClass(image_provider, scale_factor);
|
||||
sConfigGroup = config;
|
||||
sAccountGroup = account;
|
||||
sIgnoresGroup = ignores;
|
||||
sColorsGroup = colors;
|
||||
|
||||
if (sConfigGroup == NULL
|
||||
|| sAccountGroup == NULL
|
||||
|| sIgnoresGroup == NULL
|
||||
|| sColorsGroup == NULL)
|
||||
{
|
||||
@@ -286,6 +291,20 @@ void LLUI::glRectToScreen(const LLRect& gl, LLRect *screen)
|
||||
glPointToScreen(gl.mRight, gl.mBottom, &screen->mRight, &screen->mBottom);
|
||||
}
|
||||
|
||||
|
||||
LLControlGroup& LLUI::getControlControlGroup (const std::string& controlname)
|
||||
{
|
||||
if(sConfigGroup->controlExists(controlname))
|
||||
return *sConfigGroup;
|
||||
if(sAccountGroup->controlExists(controlname))
|
||||
return *sAccountGroup;
|
||||
//if(sIgnoresGroup->controlExists(controlname)) //Identical to sConfigGroup currently.
|
||||
// return *sIgnoresGroup;
|
||||
if(sColorsGroup->controlExists(controlname))
|
||||
return *sColorsGroup;
|
||||
return *sConfigGroup;
|
||||
}
|
||||
|
||||
// static
|
||||
void LLUI::setHtmlHelp(LLHtmlHelp* html_help)
|
||||
{
|
||||
|
||||
@@ -62,6 +62,7 @@ public:
|
||||
// Methods
|
||||
//
|
||||
static void initClass(LLControlGroup* config,
|
||||
LLControlGroup* account,
|
||||
LLControlGroup* ignores,
|
||||
LLControlGroup* colors,
|
||||
LLImageProviderInterface* image_provider,
|
||||
@@ -80,6 +81,8 @@ public:
|
||||
static std::string getLanguage();
|
||||
|
||||
//helper functions (should probably move free standing rendering helper functions here)
|
||||
static LLView* getRootView() { return sRootView; }
|
||||
static void setRootView(LLView* view) { sRootView = view; }
|
||||
static std::string locateSkin(const std::string& filename);
|
||||
static void setMousePositionScreen(S32 x, S32 y);
|
||||
static void getMousePositionScreen(S32 *x, S32 *y);
|
||||
@@ -97,16 +100,20 @@ public:
|
||||
static void glPointToScreen(S32 gl_x, S32 gl_y, S32 *screen_x, S32 *screen_y);
|
||||
static void screenRectToGL(const LLRect& screen, LLRect *gl);
|
||||
static void glRectToScreen(const LLRect& gl, LLRect *screen);
|
||||
// Returns the control group containing the control name, or the default group
|
||||
static LLControlGroup& getControlControlGroup (const std::string& controlname);
|
||||
static void setHtmlHelp(LLHtmlHelp* html_help);
|
||||
|
||||
//
|
||||
// Data
|
||||
//
|
||||
static LLControlGroup* sConfigGroup;
|
||||
static LLControlGroup* sAccountGroup;
|
||||
static LLControlGroup* sIgnoresGroup;
|
||||
static LLControlGroup* sColorsGroup;
|
||||
static LLUIAudioCallback sAudioCallback;
|
||||
static LLWindow* sWindow;
|
||||
static LLView* sRootView;
|
||||
static BOOL sShowXUINames;
|
||||
static LLHtmlHelp* sHtmlHelp;
|
||||
|
||||
@@ -389,6 +396,24 @@ template <typename T> LLRegisterWith<LLInitClassList> LLInitClass<T>::sRegister(
|
||||
template <typename T> LLRegisterWith<LLDestroyClassList> LLDestroyClass<T>::sRegister(&T::destroyClass);
|
||||
|
||||
|
||||
template <class T>
|
||||
class LLUICachedControl : public LLCachedControl<T>
|
||||
{
|
||||
public:
|
||||
// This constructor will declare a control if it doesn't exist in the contol group
|
||||
LLUICachedControl(const std::string& name,
|
||||
const T& default_value,
|
||||
const std::string& comment = "Declared In Code")
|
||||
: LLCachedControl<T>(LLUI::getControlControlGroup(name), name, default_value, comment)
|
||||
{}
|
||||
|
||||
// This constructor will signal an error if the control doesn't exist in the control group
|
||||
LLUICachedControl(const std::string& name)
|
||||
: LLCachedControl<T>(LLUI::getControlControlGroup(name), name)
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
template <typename DERIVED>
|
||||
class LLParamBlock
|
||||
{
|
||||
|
||||
@@ -54,23 +54,24 @@ LLUICtrl::LLUICtrl() :
|
||||
{
|
||||
}
|
||||
|
||||
LLUICtrl::LLUICtrl(const std::string& name, const LLRect& rect, BOOL mouse_opaque,
|
||||
void (*on_commit_callback)(LLUICtrl*, void*),
|
||||
void* callback_userdata,
|
||||
LLUICtrl::LLUICtrl(const std::string& name, const LLRect rect, BOOL mouse_opaque,
|
||||
commit_callback_t commit_callback,
|
||||
U32 reshape)
|
||||
: // can't make this automatically follow top and left, breaks lots
|
||||
// of buttons in the UI. JC 7/20/2002
|
||||
LLView( name, rect, mouse_opaque, reshape ),
|
||||
mCommitSignal(NULL),
|
||||
mValidateSignal(NULL),
|
||||
mCommitCallback(NULL),
|
||||
mViewModel(LLViewModelPtr(new LLViewModel)),
|
||||
mCommitCallback( on_commit_callback),
|
||||
mValidateCallback( NULL ),
|
||||
mCallbackUserData( callback_userdata ),
|
||||
mCallbackUserData( NULL ),
|
||||
mTentative( FALSE ),
|
||||
mTabStop( TRUE ),
|
||||
mIsChrome(FALSE)
|
||||
{
|
||||
if(commit_callback)
|
||||
setCommitCallback(commit_callback);
|
||||
}
|
||||
|
||||
LLUICtrl::~LLUICtrl()
|
||||
|
||||
@@ -54,9 +54,8 @@ public:
|
||||
typedef BOOL (*LLUICtrlValidate)(LLUICtrl* ctrl, void* userdata);
|
||||
|
||||
LLUICtrl();
|
||||
LLUICtrl( const std::string& name, const LLRect& rect, BOOL mouse_opaque,
|
||||
LLUICtrlCallback callback,
|
||||
void* callback_userdata,
|
||||
LLUICtrl( const std::string& name, const LLRect rect = LLRect(), BOOL mouse_opaque = TRUE,
|
||||
commit_callback_t commit_callback = NULL,
|
||||
U32 reshape=FOLLOWS_NONE);
|
||||
/*virtual*/ ~LLUICtrl();
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
|
||||
#include "linden_common.h"
|
||||
|
||||
#define LLUICTRLFACTORY_CPP
|
||||
#include "lluictrlfactory.h"
|
||||
|
||||
#include <fstream>
|
||||
@@ -70,6 +71,10 @@
|
||||
#include "lluiimage.h"
|
||||
#include "llviewborder.h"
|
||||
|
||||
LLFastTimer::DeclareTimer FTM_WIDGET_CONSTRUCTION("Widget Construction");
|
||||
LLFastTimer::DeclareTimer FTM_INIT_FROM_PARAMS("Widget InitFromParams");
|
||||
LLFastTimer::DeclareTimer FTM_WIDGET_SETUP("Widget Setup");
|
||||
|
||||
const char XML_HEADER[] = "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\" ?>\n";
|
||||
|
||||
const S32 HPAD = 4;
|
||||
@@ -83,7 +88,7 @@ std::vector<std::string> LLUICtrlFactory::sXUIPaths;
|
||||
class LLUICtrlLocate : public LLUICtrl
|
||||
{
|
||||
public:
|
||||
LLUICtrlLocate() : LLUICtrl(std::string("locate"), LLRect(0,0,0,0), FALSE, NULL, NULL) { setTabStop(FALSE); }
|
||||
LLUICtrlLocate() : LLUICtrl(std::string("locate"), LLRect(0,0,0,0), FALSE) { setTabStop(FALSE); }
|
||||
virtual void draw() { }
|
||||
|
||||
virtual LLXMLNodePtr getXML(bool save_children = true) const
|
||||
@@ -110,6 +115,9 @@ public:
|
||||
static LLRegisterWidget<LLUICtrlLocate> r1("locate");
|
||||
static LLRegisterWidget<LLUICtrlLocate> r2("pad");
|
||||
|
||||
// Build time optimization, generate this once in .cpp file
|
||||
template class LLUICtrlFactory* LLSingleton<class LLUICtrlFactory>::getInstance();
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// LLUICtrlFactory()
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -556,12 +564,19 @@ LLView* LLUICtrlFactory::createWidget(LLPanel *parent, LLXMLNodePtr node)
|
||||
|
||||
if (view)
|
||||
{
|
||||
parent->addChild(view, tab_group);
|
||||
setCtrlParent(view, parent, tab_group);
|
||||
}
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
//static
|
||||
void LLUICtrlFactory::setCtrlParent(LLView* view, LLView* parent, S32 tab_group)
|
||||
{
|
||||
if (tab_group == S32_MAX) tab_group = parent->getLastTabGroup();
|
||||
parent->addChild(view, tab_group);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// createFactoryPanel()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@@ -41,17 +41,54 @@
|
||||
#include "llinitparam.h"
|
||||
|
||||
class LLView;
|
||||
class LLPanel;
|
||||
|
||||
|
||||
extern LLFastTimer::DeclareTimer FTM_WIDGET_SETUP;
|
||||
extern LLFastTimer::DeclareTimer FTM_WIDGET_CONSTRUCTION;
|
||||
extern LLFastTimer::DeclareTimer FTM_INIT_FROM_PARAMS;
|
||||
|
||||
// Build time optimization, generate this once in .cpp file
|
||||
#ifndef LLUICTRLFACTORY_CPP
|
||||
extern template class LLUICtrlFactory* LLSingleton<class LLUICtrlFactory>::getInstance();
|
||||
#endif
|
||||
|
||||
class LLUICtrlFactory : public LLSingleton<LLUICtrlFactory>
|
||||
{
|
||||
public:
|
||||
private:
|
||||
friend class LLSingleton<LLUICtrlFactory>;
|
||||
LLUICtrlFactory();
|
||||
// do not call! needs to be public so run-time can clean up the singleton
|
||||
virtual ~LLUICtrlFactory();
|
||||
~LLUICtrlFactory();
|
||||
|
||||
// only partial specialization allowed in inner classes, so use extra dummy parameter
|
||||
template <typename PARAM_BLOCK, int DUMMY>
|
||||
class ParamDefaults : public LLSingleton<ParamDefaults<PARAM_BLOCK, DUMMY> >
|
||||
{
|
||||
public:
|
||||
ParamDefaults()
|
||||
{
|
||||
// recursively fill from base class param block
|
||||
((typename PARAM_BLOCK::base_block_t&)mPrototype).fillFrom(ParamDefaults<typename PARAM_BLOCK::base_block_t, DUMMY>::instance().get());
|
||||
}
|
||||
|
||||
const PARAM_BLOCK& get() { return mPrototype; }
|
||||
|
||||
private:
|
||||
PARAM_BLOCK mPrototype;
|
||||
};
|
||||
|
||||
// base case for recursion, there are NO base classes of LLInitParam::BaseBlock
|
||||
template<int DUMMY>
|
||||
class ParamDefaults<LLInitParam::BaseBlock, DUMMY> : public LLSingleton<ParamDefaults<LLInitParam::BaseBlock, DUMMY> >
|
||||
{
|
||||
public:
|
||||
const LLInitParam::BaseBlock& get() { return mBaseBlock; }
|
||||
private:
|
||||
LLInitParam::BaseBlock mBaseBlock;
|
||||
};
|
||||
|
||||
public:
|
||||
void setupPaths();
|
||||
|
||||
|
||||
void buildFloater(LLFloater* floaterp, const std::string &filename,
|
||||
const LLCallbackMap::map_t* factory_map = NULL, BOOL open = TRUE);
|
||||
void buildFloaterFromBuffer(LLFloater *floaterp, const std::string &buffer,
|
||||
@@ -82,8 +119,22 @@ public:
|
||||
|
||||
LLPanel* createFactoryPanel(const std::string& name);
|
||||
|
||||
virtual LLView* createCtrlWidget(LLPanel *parent, LLXMLNodePtr node);
|
||||
virtual LLView* createWidget(LLPanel *parent, LLXMLNodePtr node);
|
||||
LLView* createCtrlWidget(LLPanel *parent, LLXMLNodePtr node);
|
||||
LLView* createWidget(LLPanel *parent, LLXMLNodePtr node);
|
||||
|
||||
template<typename T>
|
||||
static T* create(typename T::Params& params, LLView* parent = NULL)
|
||||
{
|
||||
params.fillFrom(ParamDefaults<typename T::Params, 0>::instance().get());
|
||||
|
||||
T* widget = createWidgetImpl<T>(params, parent);
|
||||
if (widget)
|
||||
{
|
||||
widget->postBuild();
|
||||
}
|
||||
|
||||
return widget;
|
||||
}
|
||||
|
||||
static bool getLayeredXMLNode(const std::string &filename, LLXMLNodePtr& root);
|
||||
static bool getLayeredXMLNodeFromBuffer(const std::string &buffer, LLXMLNodePtr& root);
|
||||
@@ -93,6 +144,43 @@ public:
|
||||
private:
|
||||
bool getLayeredXMLNodeImpl(const std::string &filename, LLXMLNodePtr& root);
|
||||
|
||||
|
||||
void buildFloaterInternal(LLFloater *floaterp, LLXMLNodePtr &root, const std::string &filename,
|
||||
const LLCallbackMap::map_t *factory_map, BOOL open);
|
||||
BOOL buildPanelInternal(LLPanel* panelp, LLXMLNodePtr &root, const std::string &filename,
|
||||
const LLCallbackMap::map_t* factory_map = NULL);
|
||||
|
||||
template<typename T>
|
||||
static T* createWidgetImpl(const typename T::Params& params, LLView* parent = NULL)
|
||||
{
|
||||
T* widget = NULL;
|
||||
|
||||
if (!params.validateBlock())
|
||||
{
|
||||
llwarns << /*getInstance()->getCurFileName() <<*/ ": Invalid parameter block for " << typeid(T).name() << llendl;
|
||||
//return NULL;
|
||||
}
|
||||
|
||||
{ LLFastTimer _(FTM_WIDGET_CONSTRUCTION);
|
||||
widget = new T(params);
|
||||
}
|
||||
{ LLFastTimer _(FTM_INIT_FROM_PARAMS);
|
||||
widget->initFromParams(params);
|
||||
}
|
||||
|
||||
if (parent)
|
||||
{
|
||||
S32 tab_group = params.tab_group.isProvided() ? params.tab_group() : S32_MAX;
|
||||
setCtrlParent(widget, parent, tab_group);
|
||||
}
|
||||
return widget;
|
||||
}
|
||||
|
||||
// this exists to get around dependency on llview
|
||||
static void setCtrlParent(LLView* view, LLView* parent, S32 tab_group);
|
||||
|
||||
LLPanel* mDummyPanel;
|
||||
|
||||
typedef std::map<LLHandle<LLPanel>, std::string> built_panel_t;
|
||||
built_panel_t mBuiltPanels;
|
||||
|
||||
@@ -102,13 +190,6 @@ private:
|
||||
std::deque<const LLCallbackMap::map_t*> mFactoryStack;
|
||||
|
||||
static std::vector<std::string> sXUIPaths;
|
||||
|
||||
LLPanel* mDummyPanel;
|
||||
|
||||
void buildFloaterInternal(LLFloater *floaterp, LLXMLNodePtr &root, const std::string &filename,
|
||||
const LLCallbackMap::map_t *factory_map, BOOL open);
|
||||
BOOL buildPanelInternal(LLPanel* panelp, LLXMLNodePtr &root, const std::string &filename,
|
||||
const LLCallbackMap::map_t* factory_map = NULL);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -33,31 +33,35 @@
|
||||
#include "linden_common.h"
|
||||
#include "lluistring.h"
|
||||
#include "llsd.h"
|
||||
#include "lltrans.h"
|
||||
|
||||
const LLStringUtil::format_map_t LLUIString::sNullArgs;
|
||||
LLFastTimer::DeclareTimer FTM_UI_STRING("UI String");
|
||||
|
||||
|
||||
LLUIString::LLUIString(const std::string& instring, const LLStringUtil::format_map_t& args)
|
||||
: mOrig(instring),
|
||||
mArgs(args)
|
||||
: mOrig(instring),
|
||||
mArgs(new LLStringUtil::format_map_t(args))
|
||||
{
|
||||
format();
|
||||
dirty();
|
||||
}
|
||||
|
||||
void LLUIString::assign(const std::string& s)
|
||||
{
|
||||
mOrig = s;
|
||||
format();
|
||||
dirty();
|
||||
}
|
||||
|
||||
void LLUIString::setArgList(const LLStringUtil::format_map_t& args)
|
||||
|
||||
{
|
||||
mArgs = args;
|
||||
format();
|
||||
getArgs() = args;
|
||||
dirty();
|
||||
}
|
||||
|
||||
void LLUIString::setArgs(const LLSD& sd)
|
||||
{
|
||||
LLFastTimer timer(FTM_UI_STRING);
|
||||
|
||||
if (!sd.isMap()) return;
|
||||
for(LLSD::map_const_iterator sd_it = sd.beginMap();
|
||||
sd_it != sd.endMap();
|
||||
@@ -65,40 +69,40 @@ void LLUIString::setArgs(const LLSD& sd)
|
||||
{
|
||||
setArg(sd_it->first, sd_it->second.asString());
|
||||
}
|
||||
format();
|
||||
dirty();
|
||||
}
|
||||
|
||||
void LLUIString::setArg(const std::string& key, const std::string& replacement)
|
||||
{
|
||||
mArgs[key] = replacement;
|
||||
format();
|
||||
getArgs()[key] = replacement;
|
||||
dirty();
|
||||
}
|
||||
|
||||
void LLUIString::truncate(S32 maxchars)
|
||||
{
|
||||
if (mWResult.size() > (size_t)maxchars)
|
||||
if (getUpdatedWResult().size() > (size_t)maxchars)
|
||||
{
|
||||
LLWStringUtil::truncate(mWResult, maxchars);
|
||||
mResult = wstring_to_utf8str(mWResult);
|
||||
LLWStringUtil::truncate(getUpdatedWResult(), maxchars);
|
||||
mResult = wstring_to_utf8str(getUpdatedWResult());
|
||||
}
|
||||
}
|
||||
|
||||
void LLUIString::erase(S32 charidx, S32 len)
|
||||
{
|
||||
mWResult.erase(charidx, len);
|
||||
mResult = wstring_to_utf8str(mWResult);
|
||||
getUpdatedWResult().erase(charidx, len);
|
||||
mResult = wstring_to_utf8str(getUpdatedWResult());
|
||||
}
|
||||
|
||||
void LLUIString::insert(S32 charidx, const LLWString& wchars)
|
||||
{
|
||||
mWResult.insert(charidx, wchars);
|
||||
mResult = wstring_to_utf8str(mWResult);
|
||||
getUpdatedWResult().insert(charidx, wchars);
|
||||
mResult = wstring_to_utf8str(getUpdatedWResult());
|
||||
}
|
||||
|
||||
void LLUIString::replace(S32 charidx, llwchar wc)
|
||||
{
|
||||
mWResult[charidx] = wc;
|
||||
mResult = wstring_to_utf8str(mWResult);
|
||||
getUpdatedWResult()[charidx] = wc;
|
||||
mResult = wstring_to_utf8str(getUpdatedWResult());
|
||||
}
|
||||
|
||||
void LLUIString::clear()
|
||||
@@ -109,9 +113,48 @@ void LLUIString::clear()
|
||||
mWResult.clear();
|
||||
}
|
||||
|
||||
void LLUIString::format()
|
||||
void LLUIString::dirty()
|
||||
{
|
||||
mResult = mOrig;
|
||||
LLStringUtil::format(mResult, mArgs);
|
||||
mWResult = utf8str_to_wstring(mResult);
|
||||
mNeedsResult = true;
|
||||
mNeedsWResult = true;
|
||||
}
|
||||
|
||||
void LLUIString::updateResult() const
|
||||
{
|
||||
mNeedsResult = false;
|
||||
|
||||
LLFastTimer timer(FTM_UI_STRING);
|
||||
|
||||
// optimize for empty strings (don't attempt string replacement)
|
||||
if (mOrig.empty())
|
||||
{
|
||||
mResult.clear();
|
||||
mWResult.clear();
|
||||
return;
|
||||
}
|
||||
mResult = mOrig;
|
||||
|
||||
// get the default args + local args
|
||||
LLStringUtil::format_map_t combined_args = LLTrans::getDefaultArgs();
|
||||
if (mArgs && !mArgs->empty())
|
||||
{
|
||||
combined_args.insert(mArgs->begin(), mArgs->end());
|
||||
}
|
||||
LLStringUtil::format(mResult, combined_args);
|
||||
}
|
||||
|
||||
void LLUIString::updateWResult() const
|
||||
{
|
||||
mNeedsWResult = false;
|
||||
|
||||
mWResult = utf8str_to_wstring(getUpdatedResult());
|
||||
}
|
||||
|
||||
LLStringUtil::format_map_t& LLUIString::getArgs()
|
||||
{
|
||||
if (!mArgs)
|
||||
{
|
||||
mArgs = new LLStringUtil::format_map_t;
|
||||
}
|
||||
return *mArgs;
|
||||
}
|
||||
|
||||
@@ -51,9 +51,9 @@
|
||||
// llinfos << mMessage.getString() << llendl; // outputs "Welcome Steve to Second Life"
|
||||
// mMessage.setArg("[USERNAME]", "Joe");
|
||||
// llinfos << mMessage.getString() << llendl; // outputs "Welcome Joe to Second Life"
|
||||
// mMessage = "Recepcin a la [SECONDLIFE] [USERNAME]"
|
||||
// mMessage = "Bienvenido a la [SECONDLIFE] [USERNAME]"
|
||||
// mMessage.setArg("[SECONDLIFE]", "Segunda Vida");
|
||||
// llinfos << mMessage.getString() << llendl; // outputs "Recepcin a la Segunda Vida Joe"
|
||||
// llinfos << mMessage.getString() << llendl; // outputs "Bienvenido a la Segunda Vida Joe"
|
||||
|
||||
// Implementation Notes:
|
||||
// Attempting to have operator[](const std::string& s) return mArgs[s] fails because we have
|
||||
@@ -64,9 +64,10 @@ class LLUIString
|
||||
public:
|
||||
// These methods all perform appropriate argument substitution
|
||||
// and modify mOrig where appropriate
|
||||
LLUIString() {}
|
||||
LLUIString() : mArgs(NULL), mNeedsResult(false), mNeedsWResult(false) {}
|
||||
LLUIString(const std::string& instring, const LLStringUtil::format_map_t& args);
|
||||
LLUIString(const std::string& instring) { assign(instring); }
|
||||
LLUIString(const std::string& instring) : mArgs(NULL) { assign(instring); }
|
||||
~LLUIString() { delete mArgs; }
|
||||
|
||||
void assign(const std::string& instring);
|
||||
LLUIString& operator=(const std::string& s) { assign(s); return *this; }
|
||||
@@ -76,34 +77,45 @@ public:
|
||||
void setArgs(const class LLSD& sd);
|
||||
void setArg(const std::string& key, const std::string& replacement);
|
||||
|
||||
const std::string& getString() const { return mResult; }
|
||||
operator std::string() const { return mResult; }
|
||||
const std::string& getString() const { return getUpdatedResult(); }
|
||||
operator std::string() const { return getUpdatedResult(); }
|
||||
|
||||
const LLWString& getWString() const { return mWResult; }
|
||||
operator LLWString() const { return mWResult; }
|
||||
const LLWString& getWString() const { return getUpdatedWResult(); }
|
||||
operator LLWString() const { return getUpdatedWResult(); }
|
||||
|
||||
bool empty() const { return mWResult.empty(); }
|
||||
S32 length() const { return mWResult.size(); }
|
||||
bool empty() const { return getUpdatedResult().empty(); }
|
||||
S32 length() const { return getUpdatedWResult().size(); }
|
||||
|
||||
void clear();
|
||||
void clearArgs() { mArgs.clear(); }
|
||||
|
||||
// These utuilty functions are included for text editing.
|
||||
void clearArgs() { if (mArgs) mArgs->clear(); }
|
||||
|
||||
// These utility functions are included for text editing.
|
||||
// They do not affect mOrig and do not perform argument substitution
|
||||
void truncate(S32 maxchars);
|
||||
void erase(S32 charidx, S32 len);
|
||||
void insert(S32 charidx, const LLWString& wchars);
|
||||
void replace(S32 charidx, llwchar wc);
|
||||
|
||||
static const LLStringUtil::format_map_t sNullArgs;
|
||||
|
||||
private:
|
||||
void format();
|
||||
|
||||
// something changed, requiring reformatting of strings
|
||||
void dirty();
|
||||
|
||||
std::string& getUpdatedResult() const { if (mNeedsResult) { updateResult(); } return mResult; }
|
||||
LLWString& getUpdatedWResult() const{ if (mNeedsWResult) { updateWResult(); } return mWResult; }
|
||||
|
||||
// do actual work of updating strings (non-inlined)
|
||||
void updateResult() const;
|
||||
void updateWResult() const;
|
||||
LLStringUtil::format_map_t& getArgs();
|
||||
|
||||
std::string mOrig;
|
||||
std::string mResult;
|
||||
LLWString mWResult; // for displaying
|
||||
LLStringUtil::format_map_t mArgs;
|
||||
mutable std::string mResult;
|
||||
mutable LLWString mWResult; // for displaying
|
||||
LLStringUtil::format_map_t* mArgs;
|
||||
|
||||
// controls lazy evaluation
|
||||
mutable bool mNeedsResult;
|
||||
mutable bool mNeedsWResult;
|
||||
};
|
||||
|
||||
#endif // LL_LLUISTRING_H
|
||||
|
||||
@@ -146,7 +146,7 @@ void LLView::init(const LLView::Params& p)
|
||||
|
||||
// create rect first, as this will supply initial follows flags
|
||||
setShape(p.rect);
|
||||
mReshapeFlags = p.follows.flags;
|
||||
parseFollowsFlags(p);
|
||||
}
|
||||
|
||||
LLView::LLView()
|
||||
@@ -1164,7 +1164,7 @@ void LLView::drawChildren()
|
||||
}*/
|
||||
if (!mChildList.empty())
|
||||
{
|
||||
LLView* rootp = getRootView();
|
||||
LLView* rootp = LLUI::getRootView();
|
||||
++sDepth;
|
||||
|
||||
for (child_list_const_reverse_iter_t child_iter = mChildList.rbegin(); child_iter != mChildList.rend(); ++child_iter)
|
||||
@@ -2409,6 +2409,78 @@ const S32 FLOATER_H_MARGIN = 15;
|
||||
const S32 MIN_WIDGET_HEIGHT = 10;
|
||||
const S32 VPAD = 4;
|
||||
|
||||
void LLView::initFromParams(const LLView::Params& params)
|
||||
{
|
||||
LLRect required_rect = getRequiredRect();
|
||||
|
||||
S32 width = llmax(getRect().getWidth(), required_rect.getWidth());
|
||||
S32 height = llmax(getRect().getHeight(), required_rect.getHeight());
|
||||
|
||||
reshape(width, height);
|
||||
|
||||
// call virtual methods with most recent data
|
||||
// use getters because these values might not come through parameter block
|
||||
setEnabled(getEnabled());
|
||||
setVisible(getVisible());
|
||||
|
||||
if (!params.name().empty())
|
||||
{
|
||||
setName(params.name());
|
||||
}
|
||||
}
|
||||
|
||||
void LLView::parseFollowsFlags(const LLView::Params& params)
|
||||
{
|
||||
// preserve follows flags set by code if user did not override
|
||||
/*if (!params.follows.isProvided())
|
||||
{
|
||||
return;
|
||||
}*/
|
||||
|
||||
// interpret either string or bitfield version of follows
|
||||
if (params.follows.string.isChosen())
|
||||
{
|
||||
setFollows(FOLLOWS_NONE);
|
||||
|
||||
std::string follows = params.follows.string;
|
||||
|
||||
typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
|
||||
boost::char_separator<char> sep("|");
|
||||
tokenizer tokens(follows, sep);
|
||||
tokenizer::iterator token_iter = tokens.begin();
|
||||
|
||||
while(token_iter != tokens.end())
|
||||
{
|
||||
const std::string& token_str = *token_iter;
|
||||
if (token_str == "left")
|
||||
{
|
||||
setFollowsLeft();
|
||||
}
|
||||
else if (token_str == "right")
|
||||
{
|
||||
setFollowsRight();
|
||||
}
|
||||
else if (token_str == "top")
|
||||
{
|
||||
setFollowsTop();
|
||||
}
|
||||
else if (token_str == "bottom")
|
||||
{
|
||||
setFollowsBottom();
|
||||
}
|
||||
else if (token_str == "all")
|
||||
{
|
||||
setFollowsAll();
|
||||
}
|
||||
++token_iter;
|
||||
}
|
||||
}
|
||||
else if (params.follows.flags.isChosen())
|
||||
{
|
||||
setFollows(params.follows.flags);
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
U32 LLView::createRect(LLXMLNodePtr node, LLRect &rect, LLView* parent_view, const LLRect &required_rect)
|
||||
{
|
||||
|
||||
@@ -307,7 +307,9 @@ public:
|
||||
// remove the specified child from the view, and set it's parent to NULL.
|
||||
virtual void removeChild(LLView* view);
|
||||
|
||||
child_tab_order_t getCtrlOrder() const { return mCtrlOrder; }
|
||||
virtual BOOL postBuild() { return TRUE; }
|
||||
|
||||
const child_tab_order_t& getCtrlOrder() const { return mCtrlOrder; }
|
||||
ctrl_list_t getCtrlList() const;
|
||||
ctrl_list_t getCtrlListSorted() const;
|
||||
|
||||
@@ -410,6 +412,8 @@ public:
|
||||
|
||||
virtual void draw();
|
||||
|
||||
void parseFollowsFlags(const LLView::Params& params);
|
||||
|
||||
virtual LLXMLNodePtr getXML(bool save_children = true) const;
|
||||
//FIXME: make LLView non-instantiable from XML
|
||||
static LLView* fromXML(LLXMLNodePtr node, LLView *parent, class LLUICtrlFactory *factory);
|
||||
|
||||
@@ -933,9 +933,8 @@ U32 LLControlGroup::saveToFile(const std::string& filename, BOOL nondefault_only
|
||||
|
||||
U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_values, bool save_values)
|
||||
{
|
||||
if(mIncludedFiles.find(filename) != mIncludedFiles.end())
|
||||
if(!mIncludedFiles.insert(filename).second)
|
||||
return 0; //Already included this file.
|
||||
mIncludedFiles.insert(filename);
|
||||
|
||||
LLSD settings;
|
||||
llifstream infile;
|
||||
|
||||
@@ -135,7 +135,6 @@ set(viewer_SOURCE_FILES
|
||||
llcompilequeue.cpp
|
||||
llconfirmationmanager.cpp
|
||||
llconsole.cpp
|
||||
llcontainerview.cpp
|
||||
llcurrencyuimanager.cpp
|
||||
llcylinder.cpp
|
||||
lldaycyclemanager.cpp
|
||||
@@ -416,12 +415,8 @@ set(viewer_SOURCE_FILES
|
||||
llsky.cpp
|
||||
llspatialpartition.cpp
|
||||
llsprite.cpp
|
||||
llsrv.cpp
|
||||
llstartup.cpp
|
||||
llstatbar.cpp
|
||||
llstatgraph.cpp
|
||||
llstatusbar.cpp
|
||||
llstatview.cpp
|
||||
llstylemap.cpp
|
||||
llsurface.cpp
|
||||
llsurfacepatch.cpp
|
||||
@@ -638,7 +633,6 @@ set(viewer_HEADER_FILES
|
||||
llcompilequeue.h
|
||||
llconfirmationmanager.h
|
||||
llconsole.h
|
||||
llcontainerview.h
|
||||
llcurrencyuimanager.h
|
||||
llcylinder.h
|
||||
lldaycyclemanager.h
|
||||
@@ -921,12 +915,8 @@ set(viewer_HEADER_FILES
|
||||
llsky.h
|
||||
llspatialpartition.h
|
||||
llsprite.h
|
||||
llsrv.h
|
||||
llstartup.h
|
||||
llstatbar.h
|
||||
llstatgraph.h
|
||||
llstatusbar.h
|
||||
llstatview.h
|
||||
llstylemap.h
|
||||
llsurface.h
|
||||
llsurfacepatch.h
|
||||
|
||||
@@ -885,11 +885,11 @@ return Leave current function or event handler
|
||||
# Comment
|
||||
[one_sided_delimiter .8, .3, .15]
|
||||
// Comment:Non-functional commentary or disabled code
|
||||
[two_sided_delimiter_esc .8, .3, .15]
|
||||
[two_sided_delimiter .8, .3, .15]
|
||||
/* */ Comment:Non-functional commentary or disabled code
|
||||
|
||||
# String literals
|
||||
[two_sided_delimiter_esc 0, .2, 0]
|
||||
" " String literal
|
||||
[double_quotation_marks 0, .2, 0]
|
||||
" String literal
|
||||
|
||||
#functions are supplied by the program now
|
||||
|
||||
@@ -38,180 +38,132 @@
|
||||
#include "llscrolllistctrl.h"
|
||||
|
||||
#include "llagent.h"
|
||||
#include "llfiltereditor.h"
|
||||
#include "lltracker.h"
|
||||
#include "llviewerobjectlist.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "jcfloaterareasearch.h"
|
||||
|
||||
JCFloaterAreaSearch* JCFloaterAreaSearch::sInstance = NULL;
|
||||
LLViewerRegion* JCFloaterAreaSearch::sLastRegion = NULL;
|
||||
S32 JCFloaterAreaSearch::sRequested = 0;
|
||||
std::map<LLUUID, AObjectDetails> JCFloaterAreaSearch::sObjectDetails;
|
||||
std::string JCFloaterAreaSearch::sSearchedName;
|
||||
std::string JCFloaterAreaSearch::sSearchedDesc;
|
||||
std::string JCFloaterAreaSearch::sSearchedOwner;
|
||||
std::string JCFloaterAreaSearch::sSearchedGroup;
|
||||
|
||||
const std::string request_string = "JCFloaterAreaSearch::Requested_\xF8\xA7\xB5";
|
||||
const F32 min_refresh_interval = 0.25f; // Minimum interval between list refreshes in seconds.
|
||||
|
||||
JCFloaterAreaSearch::JCFloaterAreaSearch() :
|
||||
LLFloater(),
|
||||
mCounterText(0),
|
||||
mResultList(0)
|
||||
JCFloaterAreaSearch::JCFloaterAreaSearch(const LLSD& data) :
|
||||
LLFloater(),
|
||||
mCounterText(0),
|
||||
mResultList(0),
|
||||
mLastRegion(0),
|
||||
mStopped(false)
|
||||
{
|
||||
llassert_always(sInstance == NULL);
|
||||
sInstance = this;
|
||||
mLastUpdateTimer.reset();
|
||||
LLUICtrlFactory::getInstance()->buildFloater(this, "floater_area_search.xml");
|
||||
}
|
||||
|
||||
JCFloaterAreaSearch::~JCFloaterAreaSearch()
|
||||
{
|
||||
sInstance = NULL;
|
||||
}
|
||||
|
||||
void JCFloaterAreaSearch::close(bool app)
|
||||
{
|
||||
if (app)
|
||||
if (app || mStopped)
|
||||
{
|
||||
LLFloater::close(app);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sInstance)
|
||||
{
|
||||
sInstance->setVisible(FALSE);
|
||||
}
|
||||
setVisible(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
BOOL JCFloaterAreaSearch::postBuild()
|
||||
{
|
||||
mResultList = getChild<LLScrollListCtrl>("result_list");
|
||||
mResultList->setDoubleClickCallback(onDoubleClick,this);
|
||||
mResultList->setDoubleClickCallback(boost::bind(&JCFloaterAreaSearch::onDoubleClick,this));
|
||||
mResultList->sortByColumn("Name", TRUE);
|
||||
|
||||
mCounterText = getChild<LLTextBox>("counter");
|
||||
|
||||
childSetAction("Refresh", search, this);
|
||||
childSetAction("Stop", cancel, this);
|
||||
getChild<LLButton>("Refresh")->setClickedCallback(boost::bind(&JCFloaterAreaSearch::onRefresh,this));
|
||||
getChild<LLButton>("Stop")->setClickedCallback(boost::bind(&JCFloaterAreaSearch::onStop,this));
|
||||
|
||||
childSetKeystrokeCallback("Name query chunk", onCommitLine, 0);
|
||||
childSetKeystrokeCallback("Description query chunk", onCommitLine, 0);
|
||||
childSetKeystrokeCallback("Owner query chunk", onCommitLine, 0);
|
||||
childSetKeystrokeCallback("Group query chunk", onCommitLine, 0);
|
||||
getChild<LLFilterEditor>("Name query chunk")->setCommitCallback(boost::bind(&JCFloaterAreaSearch::onCommitLine,this,_1,_2,LIST_OBJECT_NAME));
|
||||
getChild<LLFilterEditor>("Description query chunk")->setCommitCallback(boost::bind(&JCFloaterAreaSearch::onCommitLine,this,_1,_2,LIST_OBJECT_DESC));
|
||||
getChild<LLFilterEditor>("Owner query chunk")->setCommitCallback(boost::bind(&JCFloaterAreaSearch::onCommitLine,this,_1,_2,LIST_OBJECT_OWNER));
|
||||
getChild<LLFilterEditor>("Group query chunk")->setCommitCallback(boost::bind(&JCFloaterAreaSearch::onCommitLine,this,_1,_2,LIST_OBJECT_GROUP));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// static
|
||||
void JCFloaterAreaSearch::checkRegion()
|
||||
void JCFloaterAreaSearch::onOpen()
|
||||
{
|
||||
// Check if we changed region, and if we did, clear the object details cache.
|
||||
LLViewerRegion* region = gAgent.getRegion();
|
||||
if (region != sLastRegion)
|
||||
{
|
||||
sLastRegion = region;
|
||||
sRequested = 0;
|
||||
sObjectDetails.clear();
|
||||
if (sInstance)
|
||||
{
|
||||
sInstance->mResultList->deleteAllItems();
|
||||
sInstance->mCounterText->setText(std::string("Listed/Pending/Total"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void JCFloaterAreaSearch::toggle()
|
||||
{
|
||||
if (sInstance)
|
||||
{
|
||||
if (sInstance->getVisible())
|
||||
{
|
||||
sInstance->setVisible(FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
checkRegion();
|
||||
sInstance->setVisible(TRUE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sInstance = new JCFloaterAreaSearch();
|
||||
LLUICtrlFactory::getInstance()->buildFloater(sInstance, "floater_area_search.xml");
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void JCFloaterAreaSearch::onDoubleClick(void *userdata)
|
||||
{
|
||||
JCFloaterAreaSearch *self = (JCFloaterAreaSearch*)userdata;
|
||||
LLScrollListItem *item = self->mResultList->getFirstSelected();
|
||||
if (!item) return;
|
||||
LLUUID object_id = item->getUUID();
|
||||
LLViewerObject* objectp = gObjectList.findObject(object_id);
|
||||
if (objectp)
|
||||
{
|
||||
LLTracker::trackLocation(objectp->getPositionGlobal(), sObjectDetails[object_id].name, "", LLTracker::LOCATION_ITEM);
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void JCFloaterAreaSearch::cancel(void* data)
|
||||
{
|
||||
checkRegion();
|
||||
if (sInstance)
|
||||
{
|
||||
sInstance->close(TRUE);
|
||||
}
|
||||
sSearchedName = "";
|
||||
sSearchedDesc = "";
|
||||
sSearchedOwner = "";
|
||||
sSearchedGroup = "";
|
||||
}
|
||||
|
||||
// static
|
||||
void JCFloaterAreaSearch::search(void* data)
|
||||
{
|
||||
//llinfos << "Clicked search" << llendl;
|
||||
checkRegion();
|
||||
results();
|
||||
}
|
||||
|
||||
// static
|
||||
void JCFloaterAreaSearch::onCommitLine(LLLineEditor* line, void* user_data)
|
||||
void JCFloaterAreaSearch::checkRegion(bool force_clear)
|
||||
{
|
||||
std::string name = line->getName();
|
||||
std::string text = line->getText();
|
||||
LLStringUtil::toLower(text);
|
||||
line->setText(text);
|
||||
if (name == "Name query chunk") sSearchedName = text;
|
||||
else if (name == "Description query chunk") sSearchedDesc = text;
|
||||
else if (name == "Owner query chunk") sSearchedOwner = text;
|
||||
else if (name == "Group query chunk") sSearchedGroup = text;
|
||||
//llinfos << "loaded " << name << " with "<< text << llendl;
|
||||
|
||||
if (text.length() > 3)
|
||||
// Check if we changed region, and if we did, clear the object details cache.
|
||||
LLViewerRegion* region = gAgent.getRegion();
|
||||
if (force_clear || region != mLastRegion)
|
||||
{
|
||||
checkRegion();
|
||||
results();
|
||||
mLastRegion = region;
|
||||
mPendingObjects.clear();
|
||||
mCachedObjects.clear();
|
||||
mResultList->deleteAllItems();
|
||||
mCounterText->setText(std::string("Listed/Pending/Total"));
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void JCFloaterAreaSearch::requestIfNeeded(LLViewerObject *objectp)
|
||||
void JCFloaterAreaSearch::onDoubleClick()
|
||||
{
|
||||
LLUUID object_id = objectp->getID();
|
||||
if (sObjectDetails.count(object_id) == 0)
|
||||
LLScrollListItem *item = mResultList->getFirstSelected();
|
||||
if (!item) return;
|
||||
LLUUID object_id = item->getUUID();
|
||||
std::map<LLUUID,ObjectData>::iterator it = mCachedObjects.find(object_id);
|
||||
if(it != mCachedObjects.end())
|
||||
{
|
||||
LLViewerObject* objectp = gObjectList.findObject(object_id);
|
||||
if (objectp)
|
||||
{
|
||||
LLTracker::trackLocation(objectp->getPositionGlobal(), it->second.name, "", LLTracker::LOCATION_ITEM);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JCFloaterAreaSearch::onStop()
|
||||
{
|
||||
mStopped = true;
|
||||
mPendingObjects.clear();
|
||||
mCounterText->setText(std::string("Stopped"));
|
||||
}
|
||||
|
||||
void JCFloaterAreaSearch::onRefresh()
|
||||
{
|
||||
//llinfos << "Clicked search" << llendl;
|
||||
mStopped = false;
|
||||
checkRegion(true);
|
||||
results();
|
||||
}
|
||||
|
||||
void JCFloaterAreaSearch::onCommitLine(LLUICtrl* caller, const LLSD& value, OBJECT_COLUMN_ORDER type)
|
||||
{
|
||||
std::string text = value.asString();
|
||||
LLStringUtil::toLower(text);
|
||||
caller->setValue(text);
|
||||
mFilterStrings[type] = text;
|
||||
//llinfos << "loaded " << name << " with "<< text << llendl;
|
||||
checkRegion();
|
||||
results();
|
||||
}
|
||||
|
||||
bool JCFloaterAreaSearch::requestIfNeeded(LLUUID object_id)
|
||||
{
|
||||
if (!mCachedObjects.count(object_id) && !mPendingObjects.count(object_id))
|
||||
{
|
||||
if(mStopped)
|
||||
return true;
|
||||
|
||||
//llinfos << "not in list" << llendl;
|
||||
AObjectDetails* details = &sObjectDetails[object_id];
|
||||
details->name = request_string;
|
||||
details->desc = request_string;
|
||||
details->owner_id = LLUUID::null;
|
||||
details->group_id = LLUUID::null;
|
||||
mPendingObjects.insert(object_id);
|
||||
|
||||
LLMessageSystem* msg = gMessageSystem;
|
||||
msg->newMessageFast(_PREHASH_RequestObjectPropertiesFamily);
|
||||
@@ -223,20 +175,20 @@ void JCFloaterAreaSearch::requestIfNeeded(LLViewerObject *objectp)
|
||||
msg->addUUIDFast(_PREHASH_ObjectID, object_id);
|
||||
gAgent.sendReliableMessage();
|
||||
//llinfos << "Sent data request for object " << object_id << llendl;
|
||||
sRequested++;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// static
|
||||
void JCFloaterAreaSearch::results()
|
||||
{
|
||||
if (!sInstance) return;
|
||||
if (!(sInstance->getVisible())) return;
|
||||
if (sRequested > 0 && sInstance->mLastUpdateTimer.getElapsedTimeF32() < min_refresh_interval) return;
|
||||
if (!getVisible()) return;
|
||||
|
||||
if (mPendingObjects.size() > 0 && mLastUpdateTimer.getElapsedTimeF32() < min_refresh_interval) return;
|
||||
//llinfos << "results()" << llendl;
|
||||
uuid_vec_t selected = sInstance->mResultList->getSelectedIDs();
|
||||
S32 scrollpos = sInstance->mResultList->getScrollPos();
|
||||
sInstance->mResultList->deleteAllItems();
|
||||
uuid_vec_t selected = mResultList->getSelectedIDs();
|
||||
S32 scrollpos = mResultList->getScrollPos();
|
||||
mResultList->deleteAllItems();
|
||||
S32 i;
|
||||
S32 total = gObjectList.getNumObjects();
|
||||
|
||||
@@ -250,23 +202,18 @@ void JCFloaterAreaSearch::results()
|
||||
!objectp->flagTemporary() && !objectp->flagTemporaryOnRez())
|
||||
{
|
||||
LLUUID object_id = objectp->getID();
|
||||
if (sObjectDetails.count(object_id) == 0)
|
||||
if(!requestIfNeeded(object_id))
|
||||
{
|
||||
//llinfos << "not all entries are \"\"" << llendl;
|
||||
requestIfNeeded(objectp);
|
||||
}
|
||||
else
|
||||
{
|
||||
//llinfos << "all entries are \"\" or we have data" << llendl;
|
||||
AObjectDetails* details = &sObjectDetails[object_id];
|
||||
std::string object_name = details->name;
|
||||
std::string object_desc = details->desc;
|
||||
std::string object_owner;
|
||||
std::string object_group;
|
||||
gCacheName->getFullName(details->owner_id, object_owner);
|
||||
gCacheName->getGroupName(details->group_id, object_group);
|
||||
if (object_name != request_string)
|
||||
std::map<LLUUID,ObjectData>::iterator it = mCachedObjects.find(object_id);
|
||||
if(it != mCachedObjects.end())
|
||||
{
|
||||
//llinfos << "all entries are \"\" or we have data" << llendl;
|
||||
std::string object_name = it->second.name;
|
||||
std::string object_desc = it->second.desc;
|
||||
std::string object_owner;
|
||||
std::string object_group;
|
||||
gCacheName->getFullName(it->second.owner_id, object_owner);
|
||||
gCacheName->getGroupName(it->second.group_id, object_group);
|
||||
//llinfos << "both names are loaded or aren't needed" << llendl;
|
||||
std::string onU = object_owner;
|
||||
std::string cnU = object_group;
|
||||
@@ -274,62 +221,67 @@ void JCFloaterAreaSearch::results()
|
||||
LLStringUtil::toLower(object_desc);
|
||||
LLStringUtil::toLower(object_owner);
|
||||
LLStringUtil::toLower(object_group);
|
||||
if ((sSearchedName == "" || object_name.find(sSearchedName) != -1) &&
|
||||
(sSearchedDesc == "" || object_desc.find(sSearchedDesc) != -1) &&
|
||||
(sSearchedOwner == "" || object_owner.find(sSearchedOwner) != -1) &&
|
||||
(sSearchedGroup == "" || object_group.find(sSearchedGroup) != -1))
|
||||
if ((mFilterStrings[LIST_OBJECT_NAME].empty() || object_name.find(mFilterStrings[LIST_OBJECT_NAME]) != -1) &&
|
||||
(mFilterStrings[LIST_OBJECT_DESC].empty() || object_desc.find(mFilterStrings[LIST_OBJECT_DESC]) != -1) &&
|
||||
(mFilterStrings[LIST_OBJECT_OWNER].empty() || object_owner.find(mFilterStrings[LIST_OBJECT_OWNER]) != -1) &&
|
||||
(mFilterStrings[LIST_OBJECT_GROUP].empty() || object_group.find(mFilterStrings[LIST_OBJECT_GROUP]) != -1))
|
||||
{
|
||||
//llinfos << "pass" << llendl;
|
||||
LLSD element;
|
||||
element["id"] = object_id;
|
||||
element["columns"][LIST_OBJECT_NAME]["column"] = "Name";
|
||||
element["columns"][LIST_OBJECT_NAME]["type"] = "text";
|
||||
element["columns"][LIST_OBJECT_NAME]["value"] = details->name; //item->getName();//ai->second//"avatar_icon";
|
||||
element["columns"][LIST_OBJECT_NAME]["value"] = it->second.name;
|
||||
element["columns"][LIST_OBJECT_DESC]["column"] = "Description";
|
||||
element["columns"][LIST_OBJECT_DESC]["type"] = "text";
|
||||
element["columns"][LIST_OBJECT_DESC]["value"] = details->desc; //ai->second;
|
||||
element["columns"][LIST_OBJECT_DESC]["value"] = it->second.desc;
|
||||
element["columns"][LIST_OBJECT_OWNER]["column"] = "Owner";
|
||||
element["columns"][LIST_OBJECT_OWNER]["type"] = "text";
|
||||
element["columns"][LIST_OBJECT_OWNER]["value"] = onU; //ai->first;
|
||||
element["columns"][LIST_OBJECT_OWNER]["value"] = onU;
|
||||
element["columns"][LIST_OBJECT_GROUP]["column"] = "Group";
|
||||
element["columns"][LIST_OBJECT_GROUP]["type"] = "text";
|
||||
element["columns"][LIST_OBJECT_GROUP]["value"] = cnU; //ai->second;
|
||||
sInstance->mResultList->addElement(element, ADD_BOTTOM);
|
||||
mResultList->addElement(element, ADD_BOTTOM);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sInstance->mResultList->updateSort();
|
||||
sInstance->mResultList->selectMultiple(selected);
|
||||
sInstance->mResultList->setScrollPos(scrollpos);
|
||||
sInstance->mCounterText->setText(llformat("%d listed/%d pending/%d total", sInstance->mResultList->getItemCount(), sRequested, sObjectDetails.size()));
|
||||
sInstance->mLastUpdateTimer.reset();
|
||||
mResultList->updateSort();
|
||||
mResultList->selectMultiple(selected);
|
||||
mResultList->setScrollPos(scrollpos);
|
||||
mCounterText->setText(llformat("%d listed/%d pending/%d total", mResultList->getItemCount(), mPendingObjects.size(), mPendingObjects.size()+mCachedObjects.size()));
|
||||
mLastUpdateTimer.reset();
|
||||
}
|
||||
|
||||
// static
|
||||
void JCFloaterAreaSearch::processObjectPropertiesFamily(LLMessageSystem* msg, void** user_data)
|
||||
{
|
||||
checkRegion();
|
||||
JCFloaterAreaSearch* floater = findInstance();
|
||||
if(!floater)
|
||||
return;
|
||||
floater->checkRegion();
|
||||
|
||||
LLUUID object_id;
|
||||
msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_ObjectID, object_id);
|
||||
|
||||
bool exists = (sObjectDetails.count(object_id) != 0);
|
||||
AObjectDetails* details = &sObjectDetails[object_id];
|
||||
if (!exists || details->name == request_string)
|
||||
{
|
||||
// We cache unknown objects (to avoid having to request them later)
|
||||
// and requested objects.
|
||||
if (exists && sRequested > 0) sRequested--;
|
||||
msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_OwnerID, details->owner_id);
|
||||
msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_GroupID, details->group_id);
|
||||
msg->getStringFast(_PREHASH_ObjectData, _PREHASH_Name, details->name);
|
||||
msg->getStringFast(_PREHASH_ObjectData, _PREHASH_Description, details->desc);
|
||||
gCacheName->get(details->owner_id, false, boost::bind(&JCFloaterAreaSearch::results));
|
||||
gCacheName->get(details->group_id, true, boost::bind(&JCFloaterAreaSearch::results));
|
||||
//llinfos << "Got info for " << (exists ? "requested" : "unknown") << " object " << object_id << llendl;
|
||||
}
|
||||
std::set<LLUUID>::iterator it = floater->mPendingObjects.find(object_id);
|
||||
if(it != floater->mPendingObjects.end())
|
||||
floater->mPendingObjects.erase(it);
|
||||
//else if(floater->mCachedObjects.count(object_id)) //Let entries update.
|
||||
// return;
|
||||
|
||||
ObjectData* data = &floater->mCachedObjects[object_id];
|
||||
// We cache unknown objects (to avoid having to request them later)
|
||||
// and requested objects.
|
||||
msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_OwnerID, data->owner_id);
|
||||
msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_GroupID, data->group_id);
|
||||
msg->getStringFast(_PREHASH_ObjectData, _PREHASH_Name, data->name);
|
||||
msg->getStringFast(_PREHASH_ObjectData, _PREHASH_Description, data->desc);
|
||||
gCacheName->get(data->owner_id, false, boost::bind(&JCFloaterAreaSearch::results,floater));
|
||||
gCacheName->get(data->group_id, true, boost::bind(&JCFloaterAreaSearch::results,floater));
|
||||
//llinfos << "Got info for " << (exists ? "requested" : "unknown") << " object " << object_id << llendl;
|
||||
}
|
||||
|
||||
@@ -40,59 +40,53 @@ class LLTextBox;
|
||||
class LLScrollListCtrl;
|
||||
class LLViewerRegion;
|
||||
|
||||
struct AObjectDetails
|
||||
{
|
||||
LLUUID id;
|
||||
std::string name;
|
||||
std::string desc;
|
||||
LLUUID owner_id;
|
||||
LLUUID group_id;
|
||||
};
|
||||
|
||||
class JCFloaterAreaSearch : public LLFloater
|
||||
class JCFloaterAreaSearch : public LLFloater, public LLFloaterSingleton<JCFloaterAreaSearch>
|
||||
{
|
||||
public:
|
||||
JCFloaterAreaSearch();
|
||||
JCFloaterAreaSearch(const LLSD& data);
|
||||
virtual ~JCFloaterAreaSearch();
|
||||
|
||||
/*virtual*/ BOOL postBuild();
|
||||
/*virtual*/ void close(bool app = false);
|
||||
/*virtual*/ void onOpen();
|
||||
|
||||
static void results();
|
||||
static void toggle();
|
||||
static JCFloaterAreaSearch* getInstance() { return sInstance; }
|
||||
void results();
|
||||
static void processObjectPropertiesFamily(LLMessageSystem* msg, void** user_data);
|
||||
|
||||
private:
|
||||
static void checkRegion();
|
||||
static void cancel(void* data);
|
||||
static void search(void* data);
|
||||
static void onCommitLine(LLLineEditor* line, void* user_data);
|
||||
static void requestIfNeeded(LLViewerObject *objectp);
|
||||
static void onDoubleClick(void *userdata);
|
||||
|
||||
enum OBJECT_COLUMN_ORDER
|
||||
{
|
||||
LIST_OBJECT_NAME,
|
||||
LIST_OBJECT_NAME = 0,
|
||||
LIST_OBJECT_DESC,
|
||||
LIST_OBJECT_OWNER,
|
||||
LIST_OBJECT_GROUP
|
||||
LIST_OBJECT_GROUP,
|
||||
LIST_OBJECT_COUNT
|
||||
};
|
||||
|
||||
static JCFloaterAreaSearch* sInstance;
|
||||
|
||||
static S32 sRequested;
|
||||
void checkRegion(bool force_clear = false);
|
||||
void onStop();
|
||||
void onRefresh();
|
||||
void onCommitLine(LLUICtrl* caller, const LLSD& value, OBJECT_COLUMN_ORDER type);
|
||||
bool requestIfNeeded(LLUUID object_id);
|
||||
void onDoubleClick();
|
||||
|
||||
LLTextBox* mCounterText;
|
||||
LLScrollListCtrl* mResultList;
|
||||
LLFrameTimer mLastUpdateTimer;
|
||||
LLViewerRegion* mLastRegion;
|
||||
bool mStopped;
|
||||
|
||||
static std::map<LLUUID, AObjectDetails> sObjectDetails;
|
||||
struct ObjectData
|
||||
{
|
||||
LLUUID id;
|
||||
std::string name;
|
||||
std::string desc;
|
||||
LLUUID owner_id;
|
||||
LLUUID group_id;
|
||||
};
|
||||
std::set<LLUUID> mPendingObjects;
|
||||
std::map<LLUUID, ObjectData> mCachedObjects;
|
||||
|
||||
static std::string sSearchedName;
|
||||
static std::string sSearchedDesc;
|
||||
static std::string sSearchedOwner;
|
||||
static std::string sSearchedGroup;
|
||||
|
||||
static LLViewerRegion* sLastRegion;
|
||||
std::string mFilterStrings[LIST_OBJECT_COUNT];
|
||||
};
|
||||
|
||||
@@ -1493,7 +1493,7 @@ void LLAgentCamera::updateCamera()
|
||||
|
||||
gAgentAvatarp->mRoot->updateWorldMatrixChildren();
|
||||
|
||||
for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin();
|
||||
/*for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin(); //Can be an array.
|
||||
iter != gAgentAvatarp->mAttachmentPoints.end(); )
|
||||
{
|
||||
LLVOAvatar::attachment_map_t::iterator curiter = iter++;
|
||||
@@ -1502,7 +1502,11 @@ void LLAgentCamera::updateCamera()
|
||||
attachment_iter != attachment->mAttachedObjects.end();
|
||||
++attachment_iter)
|
||||
{
|
||||
LLViewerObject *attached_object = (*attachment_iter);
|
||||
LLViewerObject *attached_object = (*attachment_iter);*/
|
||||
std::vector<std::pair<LLViewerObject*,LLViewerJointAttachment*> >::iterator attachment_iter = gAgentAvatarp->mAttachedObjectsVector.begin();
|
||||
for(;attachment_iter!=gAgentAvatarp->mAttachedObjectsVector.end();++attachment_iter)
|
||||
{{
|
||||
LLViewerObject* attached_object = attachment_iter->first;
|
||||
if (attached_object && !attached_object->isDead() && attached_object->mDrawable.notNull())
|
||||
{
|
||||
// clear any existing "early" movements of attachment
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user