automated merge
commit
a2efe4bb41
|
|
@ -115,7 +115,7 @@ TestImageProvider gTestImageProvider;
|
|||
static std::string get_xui_dir()
|
||||
{
|
||||
std::string delim = gDirUtilp->getDirDelimiter();
|
||||
return gDirUtilp->getSkinBaseDir() + delim + "default" + delim + "xui" + delim;
|
||||
return gDirUtilp->getSkinBaseDir() + delim + "base" + delim + "xui" + delim;
|
||||
}
|
||||
|
||||
void init_llui()
|
||||
|
|
@ -127,7 +127,7 @@ void init_llui()
|
|||
const char* newview_path = "../../../newview";
|
||||
#endif
|
||||
gDirUtilp->initAppDirs("SecondLife", newview_path);
|
||||
gDirUtilp->setSkinFolder("default");
|
||||
gDirUtilp->setSkinFolder("base");
|
||||
|
||||
// colors are no longer stored in a LLControlGroup file
|
||||
LLUIColorTable::instance().loadFromSettings();
|
||||
|
|
|
|||
|
|
@ -77,13 +77,15 @@ def find_vc_dir():
|
|||
|
||||
def find_mt_path():
|
||||
vc_dir = find_vc_dir()
|
||||
mt_path = '\"%sbin\\mt.exe\"' % vc_dir
|
||||
print "Found vc_dir: %s" % vc_dir
|
||||
mt_path = '\"%s\\VC\\bin\\mt.exe\"' % vc_dir
|
||||
return mt_path
|
||||
|
||||
def test_assembly_binding(src_filename, assembly_name, assembly_ver):
|
||||
print "checking %s dependency %s..." % (src_filename, assembly_name)
|
||||
|
||||
(tmp_file_fd, tmp_file_name) = tempfile.mkstemp(suffix='.xml')
|
||||
print tmp_file_name
|
||||
tmp_file = os.fdopen(tmp_file_fd)
|
||||
tmp_file.close()
|
||||
|
||||
|
|
|
|||
|
|
@ -202,12 +202,12 @@ void LLAudioEngine::updateInternetStream()
|
|||
}
|
||||
|
||||
// virtual
|
||||
int LLAudioEngine::isInternetStreamPlaying()
|
||||
LLAudioEngine::LLAudioPlayState LLAudioEngine::isInternetStreamPlaying()
|
||||
{
|
||||
if (mStreamingAudioImpl)
|
||||
return mStreamingAudioImpl->isPlaying();
|
||||
return (LLAudioEngine::LLAudioPlayState) mStreamingAudioImpl->isPlaying();
|
||||
|
||||
return 0; // Stopped
|
||||
return LLAudioEngine::AUDIO_STOPPED; // Stopped
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -91,6 +91,15 @@ public:
|
|||
AUDIO_TYPE_COUNT = 4 // last
|
||||
};
|
||||
|
||||
enum LLAudioPlayState
|
||||
{
|
||||
// isInternetStreamPlaying() returns an *int*, with
|
||||
// 0 = stopped, 1 = playing, 2 = paused.
|
||||
AUDIO_STOPPED = 0,
|
||||
AUDIO_PLAYING = 1,
|
||||
AUDIO_PAUSED = 2
|
||||
};
|
||||
|
||||
LLAudioEngine();
|
||||
virtual ~LLAudioEngine();
|
||||
|
||||
|
|
@ -156,7 +165,7 @@ public:
|
|||
void stopInternetStream();
|
||||
void pauseInternetStream(int pause);
|
||||
void updateInternetStream(); // expected to be called often
|
||||
int isInternetStreamPlaying();
|
||||
LLAudioPlayState isInternetStreamPlaying();
|
||||
// use a value from 0.0 to 1.0, inclusive
|
||||
void setInternetStreamGain(F32 vol);
|
||||
std::string getInternetStreamURL();
|
||||
|
|
|
|||
|
|
@ -181,16 +181,18 @@ void LLCharacter::requestStopMotion( LLMotion* motion)
|
|||
// updateMotions()
|
||||
//-----------------------------------------------------------------------------
|
||||
static LLFastTimer::DeclareTimer FTM_UPDATE_ANIMATION("Update Animation");
|
||||
static LLFastTimer::DeclareTimer FTM_UPDATE_HIDDEN_ANIMATION("Update Hidden Anim");
|
||||
|
||||
void LLCharacter::updateMotions(e_update_t update_type)
|
||||
{
|
||||
LLFastTimer t(FTM_UPDATE_ANIMATION);
|
||||
if (update_type == HIDDEN_UPDATE)
|
||||
{
|
||||
LLFastTimer t(FTM_UPDATE_HIDDEN_ANIMATION);
|
||||
mMotionController.updateMotionsMinimal();
|
||||
}
|
||||
else
|
||||
{
|
||||
LLFastTimer t(FTM_UPDATE_ANIMATION);
|
||||
// unpause if the number of outstanding pause requests has dropped to the initial one
|
||||
if (mMotionController.isPaused() && mPauseRequest->getNumRefs() == 1)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -221,7 +221,7 @@ BOOL LLEditingMotion::onUpdate(F32 time, U8* joint_mask)
|
|||
if (!target.isFinite())
|
||||
{
|
||||
llerrs << "Non finite target in editing motion with target distance of " << target_dist <<
|
||||
" and focus point " << focus_pt << " and pointAtPt: " << *pointAtPt << llendl;
|
||||
" and focus point " << focus_pt << llendl;
|
||||
}
|
||||
|
||||
mTarget.setPosition( target + mParentJoint.getPosition());
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ set(llcommon_SOURCE_FILES
|
|||
lleventdispatcher.cpp
|
||||
lleventfilter.cpp
|
||||
llevents.cpp
|
||||
lleventtimer.cpp
|
||||
llfasttimer_class.cpp
|
||||
llfile.cpp
|
||||
llfindlocale.cpp
|
||||
|
|
@ -164,7 +165,6 @@ set(llcommon_HEADER_FILES
|
|||
llhttpstatuscodes.h
|
||||
llindexedqueue.h
|
||||
llinstancetracker.h
|
||||
llinstancetracker.h
|
||||
llkeythrottle.h
|
||||
lllazy.h
|
||||
lllistenerwrapper.h
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@
|
|||
#include "lllivefile.h"
|
||||
#include "llmemory.h"
|
||||
#include "llstl.h" // for DeletePointer()
|
||||
#include "lltimer.h"
|
||||
#include "lleventtimer.h"
|
||||
|
||||
//
|
||||
// Signal handling
|
||||
|
|
|
|||
|
|
@ -0,0 +1,95 @@
|
|||
/**
|
||||
* @file lleventtimer.cpp
|
||||
* @brief Cross-platform objects for doing timing
|
||||
*
|
||||
* $LicenseInfo:firstyear=2000&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2000-2009, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "linden_common.h"
|
||||
|
||||
#include "lleventtimer.h"
|
||||
|
||||
#include "u64.h"
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// LLEventTimer Implementation
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
LLEventTimer::LLEventTimer(F32 period)
|
||||
: mEventTimer()
|
||||
{
|
||||
mPeriod = period;
|
||||
}
|
||||
|
||||
LLEventTimer::LLEventTimer(const LLDate& time)
|
||||
: mEventTimer()
|
||||
{
|
||||
mPeriod = (F32)(time.secondsSinceEpoch() - LLDate::now().secondsSinceEpoch());
|
||||
}
|
||||
|
||||
|
||||
LLEventTimer::~LLEventTimer()
|
||||
{
|
||||
}
|
||||
|
||||
//static
|
||||
void LLEventTimer::updateClass()
|
||||
{
|
||||
std::list<LLEventTimer*> completed_timers;
|
||||
|
||||
{
|
||||
LLInstanceTrackerScopedGuard guard;
|
||||
for (instance_iter iter = guard.beginInstances(); iter != guard.endInstances(); )
|
||||
{
|
||||
LLEventTimer& timer = *iter++;
|
||||
F32 et = timer.mEventTimer.getElapsedTimeF32();
|
||||
if (timer.mEventTimer.getStarted() && et > timer.mPeriod) {
|
||||
timer.mEventTimer.reset();
|
||||
if ( timer.tick() )
|
||||
{
|
||||
completed_timers.push_back( &timer );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( completed_timers.size() > 0 )
|
||||
{
|
||||
for (std::list<LLEventTimer*>::iterator completed_iter = completed_timers.begin();
|
||||
completed_iter != completed_timers.end();
|
||||
completed_iter++ )
|
||||
{
|
||||
delete *completed_iter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
/**
|
||||
* @file lleventtimer.h
|
||||
* @brief Cross-platform objects for doing timing
|
||||
*
|
||||
* $LicenseInfo:firstyear=2000&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2000-2009, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_EVENTTIMER_H
|
||||
#define LL_EVENTTIMER_H
|
||||
|
||||
#include "stdtypes.h"
|
||||
#include "lldate.h"
|
||||
#include "llinstancetracker.h"
|
||||
#include "lltimer.h"
|
||||
|
||||
// class for scheduling a function to be called at a given frequency (approximate, inprecise)
|
||||
class LL_COMMON_API LLEventTimer : protected LLInstanceTracker<LLEventTimer>
|
||||
{
|
||||
public:
|
||||
LLEventTimer(F32 period); // period is the amount of time between each call to tick() in seconds
|
||||
LLEventTimer(const LLDate& time);
|
||||
virtual ~LLEventTimer();
|
||||
|
||||
//function to be called at the supplied frequency
|
||||
// Normally return FALSE; TRUE will delete the timer after the function returns.
|
||||
virtual BOOL tick() = 0;
|
||||
|
||||
static void updateClass();
|
||||
|
||||
protected:
|
||||
LLTimer mEventTimer;
|
||||
F32 mPeriod;
|
||||
};
|
||||
|
||||
#endif //LL_EVENTTIMER_H
|
||||
|
|
@ -218,9 +218,10 @@ LLFastTimer::DeclareTimer::DeclareTimer(const std::string& name)
|
|||
// static
|
||||
void LLFastTimer::DeclareTimer::updateCachedPointers()
|
||||
{
|
||||
DeclareTimer::LLInstanceTrackerScopedGuard guard;
|
||||
// propagate frame state pointers to timer declarations
|
||||
for (DeclareTimer::instance_iter it = DeclareTimer::beginInstances();
|
||||
it != DeclareTimer::endInstances();
|
||||
for (DeclareTimer::instance_iter it = guard.beginInstances();
|
||||
it != guard.endInstances();
|
||||
++it)
|
||||
{
|
||||
// update cached pointer
|
||||
|
|
@ -371,20 +372,23 @@ void LLFastTimer::NamedTimer::buildHierarchy()
|
|||
if (sCurFrameIndex < 0 ) return;
|
||||
|
||||
// set up initial tree
|
||||
for (instance_iter it = NamedTimer::beginInstances();
|
||||
it != endInstances();
|
||||
++it)
|
||||
{
|
||||
NamedTimer& timer = *it;
|
||||
if (&timer == NamedTimerFactory::instance().getRootTimer()) continue;
|
||||
|
||||
// bootstrap tree construction by attaching to last timer to be on stack
|
||||
// when this timer was called
|
||||
if (timer.getFrameState().mLastCaller && timer.mParent == NamedTimerFactory::instance().getRootTimer())
|
||||
NamedTimer::LLInstanceTrackerScopedGuard guard;
|
||||
for (instance_iter it = guard.beginInstances();
|
||||
it != guard.endInstances();
|
||||
++it)
|
||||
{
|
||||
timer.setParent(timer.getFrameState().mLastCaller->mTimer);
|
||||
// no need to push up tree on first use, flag can be set spuriously
|
||||
timer.getFrameState().mMoveUpTree = false;
|
||||
NamedTimer& timer = *it;
|
||||
if (&timer == NamedTimerFactory::instance().getRootTimer()) continue;
|
||||
|
||||
// bootstrap tree construction by attaching to last timer to be on stack
|
||||
// when this timer was called
|
||||
if (timer.getFrameState().mLastCaller && timer.mParent == NamedTimerFactory::instance().getRootTimer())
|
||||
{
|
||||
timer.setParent(timer.getFrameState().mLastCaller->mTimer);
|
||||
// no need to push up tree on first use, flag can be set spuriously
|
||||
timer.getFrameState().mMoveUpTree = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -486,18 +490,21 @@ void LLFastTimer::NamedTimer::resetFrame()
|
|||
F64 total_time = 0;
|
||||
LLSD sd;
|
||||
|
||||
for (NamedTimer::instance_iter it = NamedTimer::beginInstances();
|
||||
it != NamedTimer::endInstances();
|
||||
++it)
|
||||
{
|
||||
NamedTimer& timer = *it;
|
||||
FrameState& info = timer.getFrameState();
|
||||
sd[timer.getName()]["Time"] = (LLSD::Real) (info.mSelfTimeCounter*iclock_freq);
|
||||
sd[timer.getName()]["Calls"] = (LLSD::Integer) info.mCalls;
|
||||
|
||||
// computing total time here because getting the root timer's getCountHistory
|
||||
// doesn't work correctly on the first frame
|
||||
total_time = total_time + info.mSelfTimeCounter * iclock_freq;
|
||||
NamedTimer::LLInstanceTrackerScopedGuard guard;
|
||||
for (NamedTimer::instance_iter it = guard.beginInstances();
|
||||
it != guard.endInstances();
|
||||
++it)
|
||||
{
|
||||
NamedTimer& timer = *it;
|
||||
FrameState& info = timer.getFrameState();
|
||||
sd[timer.getName()]["Time"] = (LLSD::Real) (info.mSelfTimeCounter*iclock_freq);
|
||||
sd[timer.getName()]["Calls"] = (LLSD::Integer) info.mCalls;
|
||||
|
||||
// computing total time here because getting the root timer's getCountHistory
|
||||
// doesn't work correctly on the first frame
|
||||
total_time = total_time + info.mSelfTimeCounter * iclock_freq;
|
||||
}
|
||||
}
|
||||
|
||||
sd["Total"]["Time"] = (LLSD::Real) total_time;
|
||||
|
|
@ -531,21 +538,24 @@ void LLFastTimer::NamedTimer::resetFrame()
|
|||
DeclareTimer::updateCachedPointers();
|
||||
|
||||
// reset for next frame
|
||||
for (NamedTimer::instance_iter it = NamedTimer::beginInstances();
|
||||
it != NamedTimer::endInstances();
|
||||
++it)
|
||||
{
|
||||
NamedTimer& timer = *it;
|
||||
|
||||
FrameState& info = timer.getFrameState();
|
||||
info.mSelfTimeCounter = 0;
|
||||
info.mCalls = 0;
|
||||
info.mLastCaller = NULL;
|
||||
info.mMoveUpTree = false;
|
||||
// update parent pointer in timer state struct
|
||||
if (timer.mParent)
|
||||
NamedTimer::LLInstanceTrackerScopedGuard guard;
|
||||
for (NamedTimer::instance_iter it = guard.beginInstances();
|
||||
it != guard.endInstances();
|
||||
++it)
|
||||
{
|
||||
info.mParent = &timer.mParent->getFrameState();
|
||||
NamedTimer& timer = *it;
|
||||
|
||||
FrameState& info = timer.getFrameState();
|
||||
info.mSelfTimeCounter = 0;
|
||||
info.mCalls = 0;
|
||||
info.mLastCaller = NULL;
|
||||
info.mMoveUpTree = false;
|
||||
// update parent pointer in timer state struct
|
||||
if (timer.mParent)
|
||||
{
|
||||
info.mParent = &timer.mParent->getFrameState();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -575,20 +585,23 @@ void LLFastTimer::NamedTimer::reset()
|
|||
}
|
||||
|
||||
// reset all history
|
||||
for (NamedTimer::instance_iter it = NamedTimer::beginInstances();
|
||||
it != NamedTimer::endInstances();
|
||||
++it)
|
||||
{
|
||||
NamedTimer& timer = *it;
|
||||
if (&timer != NamedTimerFactory::instance().getRootTimer())
|
||||
NamedTimer::LLInstanceTrackerScopedGuard guard;
|
||||
for (NamedTimer::instance_iter it = guard.beginInstances();
|
||||
it != guard.endInstances();
|
||||
++it)
|
||||
{
|
||||
timer.setParent(NamedTimerFactory::instance().getRootTimer());
|
||||
NamedTimer& timer = *it;
|
||||
if (&timer != NamedTimerFactory::instance().getRootTimer())
|
||||
{
|
||||
timer.setParent(NamedTimerFactory::instance().getRootTimer());
|
||||
}
|
||||
|
||||
timer.mCountAverage = 0;
|
||||
timer.mCallAverage = 0;
|
||||
memset(timer.mCountHistory, 0, sizeof(U32) * HISTORY_NUM);
|
||||
memset(timer.mCallHistory, 0, sizeof(U32) * HISTORY_NUM);
|
||||
}
|
||||
|
||||
timer.mCountAverage = 0;
|
||||
timer.mCallAverage = 0;
|
||||
memset(timer.mCountHistory, 0, sizeof(U32) * HISTORY_NUM);
|
||||
memset(timer.mCallHistory, 0, sizeof(U32) * HISTORY_NUM);
|
||||
}
|
||||
|
||||
sLastFrameIndex = 0;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
/**
|
||||
* @file lllinstancetracker.cpp
|
||||
*
|
||||
* $LicenseInfo:firstyear=2009&license=viewergpl$
|
||||
* Copyright (c) 2009, Linden Research, Inc.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
// Precompiled header
|
||||
#include "linden_common.h"
|
||||
// associated header
|
||||
#include "llinstancetracker.h"
|
||||
// STL headers
|
||||
// std headers
|
||||
// external library headers
|
||||
// other Linden headers
|
||||
|
||||
// llinstancetracker.h is presently header-only. This file exists only because our CMake
|
||||
// test macro ADD_BUILD_TEST requires it.
|
||||
int dummy = 0;
|
||||
|
|
@ -98,7 +98,10 @@ private:
|
|||
mKey = key;
|
||||
getMap_()[key] = static_cast<T*>(this);
|
||||
}
|
||||
void remove_() { getMap_().erase(mKey); }
|
||||
void remove_()
|
||||
{
|
||||
getMap_().erase(mKey);
|
||||
}
|
||||
|
||||
static InstanceMap& getMap_()
|
||||
{
|
||||
|
|
@ -129,31 +132,65 @@ public:
|
|||
|
||||
/// for completeness of analogy with the generic implementation
|
||||
static T* getInstance(T* k) { return k; }
|
||||
static key_iter beginKeys() { return getSet_().begin(); }
|
||||
static key_iter endKeys() { return getSet_().end(); }
|
||||
static instance_iter beginInstances() { return instance_iter(getSet_().begin()); }
|
||||
static instance_iter endInstances() { return instance_iter(getSet_().end()); }
|
||||
static S32 instanceCount() { return getSet_().size(); }
|
||||
|
||||
// Instantiate this to get access to iterators for this type. It's a 'guard' in the sense
|
||||
// that it treats deletes of this type as errors as long as there is an instance of
|
||||
// this class alive in scope somewhere (i.e. deleting while iterating is bad).
|
||||
class LLInstanceTrackerScopedGuard
|
||||
{
|
||||
public:
|
||||
LLInstanceTrackerScopedGuard()
|
||||
{
|
||||
++sIterationNestDepth;
|
||||
}
|
||||
|
||||
~LLInstanceTrackerScopedGuard()
|
||||
{
|
||||
--sIterationNestDepth;
|
||||
}
|
||||
|
||||
static instance_iter beginInstances() { return instance_iter(getSet_().begin()); }
|
||||
static instance_iter endInstances() { return instance_iter(getSet_().end()); }
|
||||
static key_iter beginKeys() { return getSet_().begin(); }
|
||||
static key_iter endKeys() { return getSet_().end(); }
|
||||
};
|
||||
|
||||
protected:
|
||||
LLInstanceTracker() { getSet_().insert(static_cast<T*>(this)); }
|
||||
virtual ~LLInstanceTracker() { getSet_().erase(static_cast<T*>(this)); }
|
||||
LLInstanceTracker()
|
||||
{
|
||||
// it's safe but unpredictable to create instances of this type while all instances are being iterated over. I hate unpredictable. This assert will probably be turned on early in the next development cycle.
|
||||
//llassert(sIterationNestDepth == 0);
|
||||
getSet_().insert(static_cast<T*>(this));
|
||||
}
|
||||
virtual ~LLInstanceTracker()
|
||||
{
|
||||
// it's unsafe to delete instances of this type while all instances are being iterated over.
|
||||
llassert(sIterationNestDepth == 0);
|
||||
getSet_().erase(static_cast<T*>(this));
|
||||
}
|
||||
|
||||
LLInstanceTracker(const LLInstanceTracker& other) { getSet_().insert(static_cast<T*>(this)); }
|
||||
LLInstanceTracker(const LLInstanceTracker& other)
|
||||
{
|
||||
//llassert(sIterationNestDepth == 0);
|
||||
getSet_().insert(static_cast<T*>(this));
|
||||
}
|
||||
|
||||
static InstanceSet& getSet_() // called after getReady() but before go()
|
||||
{
|
||||
if (! sInstances)
|
||||
{
|
||||
sInstances = new InstanceSet;
|
||||
}
|
||||
return *sInstances;
|
||||
}
|
||||
static InstanceSet& getSet_()
|
||||
{
|
||||
if (! sInstances)
|
||||
{
|
||||
sInstances = new InstanceSet;
|
||||
}
|
||||
return *sInstances;
|
||||
}
|
||||
|
||||
static InstanceSet* sInstances;
|
||||
static S32 sIterationNestDepth;
|
||||
};
|
||||
|
||||
template <typename T, typename KEY> typename LLInstanceTracker<T, KEY>::InstanceMap* LLInstanceTracker<T, KEY>::sInstances = NULL;
|
||||
template <typename T> typename LLInstanceTracker<T, T*>::InstanceSet* LLInstanceTracker<T, T*>::sInstances = NULL;
|
||||
template <typename T> S32 LLInstanceTracker<T, T*>::sIterationNestDepth = 0;
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@
|
|||
|
||||
#include "lllivefile.h"
|
||||
#include "llframetimer.h"
|
||||
#include "lltimer.h"
|
||||
#include "lleventtimer.h"
|
||||
|
||||
const F32 DEFAULT_CONFIG_FILE_REFRESH = 5.0f;
|
||||
|
||||
|
|
|
|||
|
|
@ -139,12 +139,8 @@ S32 LLSDXMLFormatter::format_impl(const LLSD& data, std::ostream& ostr, U32 opti
|
|||
case LLSD::TypeBoolean:
|
||||
ostr << pre << "<boolean>";
|
||||
if(mBoolAlpha ||
|
||||
#if( LL_WINDOWS || __GNUC__ > 2)
|
||||
(ostr.flags() & std::ios::boolalpha)
|
||||
#else
|
||||
(ostr.flags() & 0x0100)
|
||||
#endif
|
||||
)
|
||||
)
|
||||
{
|
||||
ostr << (data.asBoolean() ? "true" : "false");
|
||||
}
|
||||
|
|
@ -511,12 +507,7 @@ void LLSDXMLParser::Impl::reset()
|
|||
|
||||
mSkipping = false;
|
||||
|
||||
#if( LL_WINDOWS || __GNUC__ > 2)
|
||||
mCurrentKey.clear();
|
||||
#else
|
||||
mCurrentKey = std::string();
|
||||
#endif
|
||||
|
||||
|
||||
XML_ParserReset(mParser, "utf-8");
|
||||
XML_SetUserData(mParser, this);
|
||||
|
|
@ -644,11 +635,7 @@ void LLSDXMLParser::Impl::startElementHandler(const XML_Char* name, const XML_Ch
|
|||
LLSD& newElement = map[mCurrentKey];
|
||||
mStack.push_back(&newElement);
|
||||
|
||||
#if( LL_WINDOWS || __GNUC__ > 2)
|
||||
mCurrentKey.clear();
|
||||
#else
|
||||
mCurrentKey = std::string();
|
||||
#endif
|
||||
}
|
||||
else if (mStack.back()->isArray())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -555,60 +555,3 @@ void secondsToTimecodeString(F32 current_time, std::string& tcstring)
|
|||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// LLEventTimer Implementation
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
LLEventTimer::LLEventTimer(F32 period)
|
||||
: mEventTimer()
|
||||
{
|
||||
mPeriod = period;
|
||||
mBusy = false;
|
||||
}
|
||||
|
||||
LLEventTimer::LLEventTimer(const LLDate& time)
|
||||
: mEventTimer()
|
||||
{
|
||||
mPeriod = (F32)(time.secondsSinceEpoch() - LLDate::now().secondsSinceEpoch());
|
||||
mBusy = false;
|
||||
}
|
||||
|
||||
|
||||
LLEventTimer::~LLEventTimer()
|
||||
{
|
||||
llassert(!mBusy); // this LLEventTimer was destroyed from within its own tick() function - bad. if you want tick() to cause destruction of its own timer, make it return true.
|
||||
}
|
||||
|
||||
//static
|
||||
void LLEventTimer::updateClass()
|
||||
{
|
||||
std::list<LLEventTimer*> completed_timers;
|
||||
for (instance_iter iter = beginInstances(); iter != endInstances(); )
|
||||
{
|
||||
LLEventTimer& timer = *iter++;
|
||||
F32 et = timer.mEventTimer.getElapsedTimeF32();
|
||||
if (timer.mEventTimer.getStarted() && et > timer.mPeriod) {
|
||||
timer.mEventTimer.reset();
|
||||
timer.mBusy = true;
|
||||
if ( timer.tick() )
|
||||
{
|
||||
completed_timers.push_back( &timer );
|
||||
}
|
||||
timer.mBusy = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ( completed_timers.size() > 0 )
|
||||
{
|
||||
for (std::list<LLEventTimer*>::iterator completed_iter = completed_timers.begin();
|
||||
completed_iter != completed_timers.end();
|
||||
completed_iter++ )
|
||||
{
|
||||
delete *completed_iter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -39,8 +39,6 @@
|
|||
#include <limits.h>
|
||||
|
||||
#include "stdtypes.h"
|
||||
#include "lldate.h"
|
||||
#include "llinstancetracker.h"
|
||||
|
||||
#include <string>
|
||||
#include <list>
|
||||
|
|
@ -171,26 +169,6 @@ LL_COMMON_API struct tm* utc_to_pacific_time(time_t utc_time, BOOL pacific_dayli
|
|||
LL_COMMON_API void microsecondsToTimecodeString(U64 current_time, std::string& tcstring);
|
||||
LL_COMMON_API void secondsToTimecodeString(F32 current_time, std::string& tcstring);
|
||||
|
||||
// class for scheduling a function to be called at a given frequency (approximate, inprecise)
|
||||
class LL_COMMON_API LLEventTimer : protected LLInstanceTracker<LLEventTimer>
|
||||
{
|
||||
public:
|
||||
LLEventTimer(F32 period); // period is the amount of time between each call to tick() in seconds
|
||||
LLEventTimer(const LLDate& time);
|
||||
virtual ~LLEventTimer();
|
||||
|
||||
//function to be called at the supplied frequency
|
||||
// Normally return FALSE; TRUE will delete the timer after the function returns.
|
||||
virtual BOOL tick() = 0;
|
||||
|
||||
static void updateClass();
|
||||
|
||||
protected:
|
||||
LLTimer mEventTimer;
|
||||
F32 mPeriod;
|
||||
bool mBusy;
|
||||
};
|
||||
|
||||
U64 LL_COMMON_API totalTime(); // Returns current system time in microseconds
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -138,23 +138,29 @@ namespace tut
|
|||
keys.insert(&one);
|
||||
keys.insert(&two);
|
||||
keys.insert(&three);
|
||||
for (Unkeyed::key_iter ki(Unkeyed::beginKeys()), kend(Unkeyed::endKeys());
|
||||
ki != kend; ++ki)
|
||||
{
|
||||
ensure_equals("spurious key", keys.erase(*ki), 1);
|
||||
}
|
||||
{
|
||||
Unkeyed::LLInstanceTrackerScopedGuard guard;
|
||||
for (Unkeyed::key_iter ki(guard.beginKeys()), kend(guard.endKeys());
|
||||
ki != kend; ++ki)
|
||||
{
|
||||
ensure_equals("spurious key", keys.erase(*ki), 1);
|
||||
}
|
||||
}
|
||||
ensure_equals("unreported key", keys.size(), 0);
|
||||
|
||||
KeySet instances;
|
||||
instances.insert(&one);
|
||||
instances.insert(&two);
|
||||
instances.insert(&three);
|
||||
for (Unkeyed::instance_iter ii(Unkeyed::beginInstances()), iend(Unkeyed::endInstances());
|
||||
ii != iend; ++ii)
|
||||
{
|
||||
Unkeyed& ref = *ii;
|
||||
ensure_equals("spurious instance", instances.erase(&ref), 1);
|
||||
}
|
||||
{
|
||||
Unkeyed::LLInstanceTrackerScopedGuard guard;
|
||||
for (Unkeyed::instance_iter ii(guard.beginInstances()), iend(guard.endInstances());
|
||||
ii != iend; ++ii)
|
||||
{
|
||||
Unkeyed& ref = *ii;
|
||||
ensure_equals("spurious instance", instances.erase(&ref), 1);
|
||||
}
|
||||
}
|
||||
ensure_equals("unreported instance", instances.size(), 0);
|
||||
}
|
||||
} // namespace tut
|
||||
|
|
|
|||
|
|
@ -676,9 +676,6 @@ void LLImageRaw::copy(LLImageRaw* src)
|
|||
|
||||
LLImageRaw* dst = this; // Just for clarity.
|
||||
|
||||
llassert( (3 == src->getComponents()) || (4 == src->getComponents()) );
|
||||
llassert( (3 == dst->getComponents()) || (4 == dst->getComponents()) );
|
||||
|
||||
if( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) )
|
||||
{
|
||||
// No scaling needed
|
||||
|
|
|
|||
|
|
@ -54,9 +54,14 @@ S32 LLImageDecodeThread::update(U32 max_time_ms)
|
|||
{
|
||||
creation_info& info = *iter;
|
||||
ImageRequest* req = new ImageRequest(info.handle, info.image,
|
||||
info.priority, info.discard, info.needs_aux,
|
||||
info.responder);
|
||||
addRequest(req);
|
||||
info.priority, info.discard, info.needs_aux,
|
||||
info.responder);
|
||||
|
||||
bool res = addRequest(req);
|
||||
if (!res)
|
||||
{
|
||||
llerrs << "request added after LLLFSThread::cleanupClass()" << llendl;
|
||||
}
|
||||
}
|
||||
mCreationList.clear();
|
||||
S32 res = LLQueuedThread::update(max_time_ms);
|
||||
|
|
|
|||
|
|
@ -3822,6 +3822,7 @@ BOOL LLVolume::cleanupTriangleData( const S32 num_input_vertices,
|
|||
|
||||
// Generate the vertex mapping and the list of vertices without
|
||||
// duplicates. This will crash if there are no vertices.
|
||||
llassert(num_input_vertices > 0); // check for no vertices!
|
||||
S32 *vertex_mapping = new S32[num_input_vertices];
|
||||
LLVector3 *new_vertices = new LLVector3[num_input_vertices];
|
||||
LLVertexIndexPair *prev_pairp = NULL;
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
* @date 2009-02-26
|
||||
* @brief Tests of llareslistener.h.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2009&license=internal$
|
||||
* $LicenseInfo:firstyear=2009&license=viewergpl$
|
||||
* Copyright (c) 2009, Linden Research, Inc.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -471,7 +471,7 @@ void LLPluginClassMedia::mouseEvent(EMouseEventType type, int button, int x, int
|
|||
sendMessage(message);
|
||||
}
|
||||
|
||||
bool LLPluginClassMedia::keyEvent(EKeyEventType type, int key_code, MASK modifiers)
|
||||
bool LLPluginClassMedia::keyEvent(EKeyEventType type, int key_code, MASK modifiers, LLSD native_key_data)
|
||||
{
|
||||
bool result = true;
|
||||
|
||||
|
|
@ -528,6 +528,7 @@ bool LLPluginClassMedia::keyEvent(EKeyEventType type, int key_code, MASK modifie
|
|||
message.setValueS32("key", key_code);
|
||||
|
||||
message.setValue("modifiers", translateModifiers(modifiers));
|
||||
message.setValueLLSD("native_key_data", native_key_data);
|
||||
|
||||
sendMessage(message);
|
||||
}
|
||||
|
|
@ -546,12 +547,13 @@ void LLPluginClassMedia::scrollEvent(int x, int y, MASK modifiers)
|
|||
sendMessage(message);
|
||||
}
|
||||
|
||||
bool LLPluginClassMedia::textInput(const std::string &text, MASK modifiers)
|
||||
bool LLPluginClassMedia::textInput(const std::string &text, MASK modifiers, LLSD native_key_data)
|
||||
{
|
||||
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "text_event");
|
||||
|
||||
message.setValue("text", text);
|
||||
message.setValue("modifiers", translateModifiers(modifiers));
|
||||
message.setValueLLSD("native_key_data", native_key_data);
|
||||
|
||||
sendMessage(message);
|
||||
|
||||
|
|
@ -682,13 +684,13 @@ LLPluginClassMedia::ETargetType getTargetTypeFromLLQtWebkit(int target_type)
|
|||
// so that we don't expose the llqtwebkit header in viewer code
|
||||
switch (target_type)
|
||||
{
|
||||
case LinkTargetType::LTT_TARGET_NONE:
|
||||
case LLQtWebKit::LTT_TARGET_NONE:
|
||||
return LLPluginClassMedia::TARGET_NONE;
|
||||
|
||||
case LinkTargetType::LTT_TARGET_BLANK:
|
||||
case LLQtWebKit::LTT_TARGET_BLANK:
|
||||
return LLPluginClassMedia::TARGET_BLANK;
|
||||
|
||||
case LinkTargetType::LTT_TARGET_EXTERNAL:
|
||||
case LLQtWebKit::LTT_TARGET_EXTERNAL:
|
||||
return LLPluginClassMedia::TARGET_EXTERNAL;
|
||||
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -114,12 +114,12 @@ public:
|
|||
KEY_EVENT_REPEAT
|
||||
}EKeyEventType;
|
||||
|
||||
bool keyEvent(EKeyEventType type, int key_code, MASK modifiers);
|
||||
bool keyEvent(EKeyEventType type, int key_code, MASK modifiers, LLSD native_key_data);
|
||||
|
||||
void scrollEvent(int x, int y, MASK modifiers);
|
||||
|
||||
// Text may be unicode (utf8 encoded)
|
||||
bool textInput(const std::string &text, MASK modifiers);
|
||||
bool textInput(const std::string &text, MASK modifiers, LLSD native_key_data);
|
||||
|
||||
void loadURI(const std::string &uri);
|
||||
|
||||
|
|
|
|||
|
|
@ -304,7 +304,14 @@ void LLPluginMessagePipe::processInput(void)
|
|||
while((delim = mInput.find(MESSAGE_DELIMITER, start)) != std::string::npos)
|
||||
{
|
||||
// Let the owner process this message
|
||||
mOwner->receiveMessageRaw(mInput.substr(start, delim - start));
|
||||
if (mOwner)
|
||||
{
|
||||
mOwner->receiveMessageRaw(mInput.substr(start, delim - start));
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS("Plugin") << "!mOwner" << LL_ENDL;
|
||||
}
|
||||
|
||||
start = delim + 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -278,14 +278,21 @@ bool LLPluginProcessChild::isDone(void)
|
|||
|
||||
void LLPluginProcessChild::sendMessageToPlugin(const LLPluginMessage &message)
|
||||
{
|
||||
std::string buffer = message.generate();
|
||||
|
||||
LL_DEBUGS("Plugin") << "Sending to plugin: " << buffer << LL_ENDL;
|
||||
LLTimer elapsed;
|
||||
|
||||
mInstance->sendMessage(buffer);
|
||||
|
||||
mCPUElapsed += elapsed.getElapsedTimeF64();
|
||||
if (mInstance)
|
||||
{
|
||||
std::string buffer = message.generate();
|
||||
|
||||
LL_DEBUGS("Plugin") << "Sending to plugin: " << buffer << LL_ENDL;
|
||||
LLTimer elapsed;
|
||||
|
||||
mInstance->sendMessage(buffer);
|
||||
|
||||
mCPUElapsed += elapsed.getElapsedTimeF64();
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS("Plugin") << "mInstance == NULL" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
void LLPluginProcessChild::sendMessageToParent(const LLPluginMessage &message)
|
||||
|
|
|
|||
|
|
@ -157,14 +157,9 @@ namespace
|
|||
|
||||
namespace tut
|
||||
{
|
||||
bool llsd_equals(const LLSD& a, const LLSD& b) {
|
||||
// cheesy, brute force, but it works
|
||||
return std::string(ll_pretty_print_sd(a)) == std::string(ll_pretty_print_sd(b));
|
||||
}
|
||||
|
||||
void ensure_llsd_equals(const std::string& msg, const LLSD& expected, const LLSD& actual)
|
||||
{
|
||||
if (!tut::llsd_equals(expected, actual))
|
||||
if (!llsd_equals(expected, actual))
|
||||
{
|
||||
std::string message = msg;
|
||||
message += ": actual: ";
|
||||
|
|
|
|||
|
|
@ -504,8 +504,13 @@ void LLFontFreetype::resetBitmapCache()
|
|||
mCharGlyphInfoMap.clear();
|
||||
mFontBitmapCachep->reset();
|
||||
|
||||
// Add the empty glyph
|
||||
addGlyphFromFont(this, 0, 0);
|
||||
// Adding default glyph is skipped for fallback fonts here as well as in loadFace().
|
||||
// This if was added as fix for EXT-4971.
|
||||
if(!mIsFallback)
|
||||
{
|
||||
// Add the empty glyph
|
||||
addGlyphFromFont(this, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void LLFontFreetype::destroyGL()
|
||||
|
|
|
|||
|
|
@ -601,14 +601,20 @@ S32 LLFontGL::firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_
|
|||
{
|
||||
llwchar wch = wchars[i];
|
||||
|
||||
F32 char_width = mFontFreetype->getXAdvance(wch);
|
||||
const LLFontGlyphInfo* fgi= mFontFreetype->getGlyphInfo(wch);
|
||||
|
||||
if( scaled_max_pixels < (total_width + char_width) )
|
||||
// last character uses character width, since the whole character needs to be visible
|
||||
// other characters just use advance
|
||||
F32 width = (i == start)
|
||||
? (F32)(fgi->mWidth + fgi->mXBearing) // use actual width for last character
|
||||
: fgi->mXAdvance; // use advance for all other characters
|
||||
|
||||
if( scaled_max_pixels < (total_width + width) )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
total_width += char_width;
|
||||
total_width += width;
|
||||
drawable_chars++;
|
||||
|
||||
if( max_chars >= 0 && drawable_chars >= max_chars )
|
||||
|
|
@ -626,7 +632,17 @@ S32 LLFontGL::firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_
|
|||
total_width = llround(total_width);
|
||||
}
|
||||
|
||||
return start_pos - drawable_chars;
|
||||
if (drawable_chars == 0)
|
||||
{
|
||||
return start_pos; // just draw last character
|
||||
}
|
||||
else
|
||||
{
|
||||
// if only 1 character is drawable, we want to return start_pos as the first character to draw
|
||||
// if 2 are drawable, return start_pos and character before start_pos, etc.
|
||||
return start_pos + 1 - drawable_chars;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, S32 begin_offset, F32 target_x, F32 max_pixels, S32 max_chars, BOOL round) const
|
||||
|
|
|
|||
|
|
@ -90,6 +90,7 @@ set(llui_SOURCE_FILES
|
|||
lltextbox.cpp
|
||||
lltexteditor.cpp
|
||||
lltextparser.cpp
|
||||
lltextvalidate.cpp
|
||||
lltransutil.cpp
|
||||
lltoggleablemenu.cpp
|
||||
lltooltip.cpp
|
||||
|
|
@ -182,6 +183,7 @@ set(llui_HEADER_FILES
|
|||
lltextbox.h
|
||||
lltexteditor.h
|
||||
lltextparser.h
|
||||
lltextvalidate.h
|
||||
lltoggleablemenu.h
|
||||
lltooltip.h
|
||||
lltransutil.h
|
||||
|
|
|
|||
|
|
@ -81,10 +81,9 @@ LLButton::Params::Params()
|
|||
image_pressed_selected("image_pressed_selected"),
|
||||
image_overlay("image_overlay"),
|
||||
image_overlay_alignment("image_overlay_alignment", std::string("center")),
|
||||
image_left_pad("image_left_pad"),
|
||||
image_right_pad("image_right_pad"),
|
||||
image_top_pad("image_top_pad"),
|
||||
image_bottom_pad("image_bottom_pad"),
|
||||
imgoverlay_label_space("imgoverlay_label_space", 1),
|
||||
label_color("label_color"),
|
||||
label_color_selected("label_color_selected"), // requires is_toggle true
|
||||
label_color_disabled("label_color_disabled"),
|
||||
|
|
@ -144,10 +143,9 @@ LLButton::LLButton(const LLButton::Params& p)
|
|||
mImageOverlay(p.image_overlay()),
|
||||
mImageOverlayColor(p.image_overlay_color()),
|
||||
mImageOverlayAlignment(LLFontGL::hAlignFromName(p.image_overlay_alignment)),
|
||||
mImageOverlayLeftPad(p.image_left_pad),
|
||||
mImageOverlayRightPad(p.image_right_pad),
|
||||
mImageOverlayTopPad(p.image_top_pad),
|
||||
mImageOverlayBottomPad(p.image_bottom_pad),
|
||||
mImgOverlayLabelSpace(p.imgoverlay_label_space),
|
||||
mIsToggle(p.is_toggle),
|
||||
mScaleImage(p.scale_image),
|
||||
mDropShadowedText(p.label_shadow),
|
||||
|
|
@ -771,12 +769,7 @@ void LLButton::draw()
|
|||
center_x++;
|
||||
}
|
||||
|
||||
S32 text_width_delta = overlay_width + 1;
|
||||
// if image paddings set, they should participate in scaling process
|
||||
S32 image_size_delta = mImageOverlayTopPad + mImageOverlayBottomPad;
|
||||
overlay_width = overlay_width - image_size_delta;
|
||||
overlay_height = overlay_height - image_size_delta;
|
||||
|
||||
center_y += (mImageOverlayBottomPad - mImageOverlayTopPad);
|
||||
// fade out overlay images on disabled buttons
|
||||
LLColor4 overlay_color = mImageOverlayColor.get();
|
||||
if (!enabled)
|
||||
|
|
@ -788,10 +781,9 @@ void LLButton::draw()
|
|||
switch(mImageOverlayAlignment)
|
||||
{
|
||||
case LLFontGL::LEFT:
|
||||
text_left += overlay_width + mImageOverlayRightPad + 1;
|
||||
text_width -= text_width_delta;
|
||||
text_left += overlay_width + mImgOverlayLabelSpace;
|
||||
mImageOverlay->draw(
|
||||
mLeftHPad,
|
||||
mLeftHPad,
|
||||
center_y - (overlay_height / 2),
|
||||
overlay_width,
|
||||
overlay_height,
|
||||
|
|
@ -806,10 +798,9 @@ void LLButton::draw()
|
|||
overlay_color);
|
||||
break;
|
||||
case LLFontGL::RIGHT:
|
||||
text_right -= overlay_width + mImageOverlayLeftPad+ 1;
|
||||
text_width -= text_width_delta;
|
||||
text_right -= overlay_width + mImgOverlayLabelSpace;
|
||||
mImageOverlay->draw(
|
||||
getRect().getWidth() - mRightHPad - overlay_width,
|
||||
getRect().getWidth() - mRightHPad - overlay_width,
|
||||
center_y - (overlay_height / 2),
|
||||
overlay_width,
|
||||
overlay_height,
|
||||
|
|
|
|||
|
|
@ -107,11 +107,14 @@ public:
|
|||
Optional<S32> pad_bottom; // under text label
|
||||
|
||||
//image overlay paddings
|
||||
Optional<S32> image_left_pad;
|
||||
Optional<S32> image_right_pad;
|
||||
Optional<S32> image_top_pad;
|
||||
Optional<S32> image_bottom_pad;
|
||||
|
||||
/**
|
||||
* Space between image_overlay and label
|
||||
*/
|
||||
Optional<S32> imgoverlay_label_space;
|
||||
|
||||
// callbacks
|
||||
Optional<CommitCallbackParam> click_callback, // alias -> commit_callback
|
||||
mouse_down_callback,
|
||||
|
|
@ -192,10 +195,6 @@ public:
|
|||
void setLeftHPad( S32 pad ) { mLeftHPad = pad; }
|
||||
void setRightHPad( S32 pad ) { mRightHPad = pad; }
|
||||
|
||||
void setImageOverlayLeftPad( S32 pad ) { mImageOverlayLeftPad = pad; }
|
||||
S32 getImageOverlayLeftPad() const { return mImageOverlayLeftPad; }
|
||||
void setImageOverlayRightPad( S32 pad ) { mImageOverlayRightPad = pad; }
|
||||
S32 getImageOverlayRightPad() const { return mImageOverlayRightPad; }
|
||||
void setImageOverlayTopPad( S32 pad ) { mImageOverlayTopPad = pad; }
|
||||
S32 getImageOverlayTopPad() const { return mImageOverlayTopPad; }
|
||||
void setImageOverlayBottomPad( S32 pad ) { mImageOverlayBottomPad = pad; }
|
||||
|
|
@ -328,11 +327,14 @@ private:
|
|||
S32 mRightHPad;
|
||||
S32 mBottomVPad; // under text label
|
||||
|
||||
S32 mImageOverlayLeftPad;
|
||||
S32 mImageOverlayRightPad;
|
||||
S32 mImageOverlayTopPad;
|
||||
S32 mImageOverlayBottomPad;
|
||||
|
||||
/*
|
||||
* Space between image_overlay and label
|
||||
*/
|
||||
S32 mImgOverlayLabelSpace;
|
||||
|
||||
F32 mHoverGlowStrength;
|
||||
F32 mCurGlowStrength;
|
||||
|
||||
|
|
|
|||
|
|
@ -244,23 +244,6 @@ void LLConsole::draw()
|
|||
}
|
||||
}
|
||||
|
||||
void LLConsole::addLine(const std::string& utf8line)
|
||||
{
|
||||
LLWString wline = utf8str_to_wstring(utf8line);
|
||||
addLine(wline, 0.f, LLColor4(1.f, 1.f, 1.f, 1.f));
|
||||
}
|
||||
|
||||
void LLConsole::addLine(const LLWString& wline)
|
||||
{
|
||||
addLine(wline, 0.f, LLColor4(1.f, 1.f, 1.f, 1.f));
|
||||
}
|
||||
|
||||
void LLConsole::addLine(const std::string& utf8line, F32 size, const LLColor4 &color)
|
||||
{
|
||||
LLWString wline = utf8str_to_wstring(utf8line);
|
||||
addLine(wline, size, color);
|
||||
}
|
||||
|
||||
//Generate highlight color segments for this paragraph. Pass in default color of paragraph.
|
||||
void LLConsole::Paragraph::makeParagraphColorSegments (const LLColor4 &color)
|
||||
{
|
||||
|
|
@ -383,21 +366,45 @@ void LLConsole::Paragraph::updateLines(F32 screen_width, const LLFontGL* font, b
|
|||
|
||||
//Pass in the string and the default color for this block of text.
|
||||
LLConsole::Paragraph::Paragraph (LLWString str, const LLColor4 &color, F32 add_time, const LLFontGL* font, F32 screen_width)
|
||||
: mParagraphText(str), mAddTime(add_time), mMaxWidth(-1)
|
||||
: mParagraphText(str), mAddTime(add_time), mMaxWidth(-1)
|
||||
{
|
||||
makeParagraphColorSegments(color);
|
||||
updateLines( screen_width, font );
|
||||
}
|
||||
|
||||
void LLConsole::addLine(const LLWString& wline, F32 size, const LLColor4 &color)
|
||||
// called once per frame regardless of console visibility
|
||||
// static
|
||||
void LLConsole::updateClass()
|
||||
{
|
||||
Paragraph paragraph(wline, color, mTimer.getElapsedTimeF32(), mFont, (F32)getRect().getWidth() );
|
||||
|
||||
mParagraphs.push_back ( paragraph );
|
||||
LLInstanceTrackerScopedGuard guard;
|
||||
|
||||
for (instance_iter it = guard.beginInstances(); it != guard.endInstances(); ++it)
|
||||
{
|
||||
it->update();
|
||||
}
|
||||
}
|
||||
|
||||
void LLConsole::update()
|
||||
{
|
||||
{
|
||||
LLMutexLock lock(&mMutex);
|
||||
|
||||
while (!mLines.empty())
|
||||
{
|
||||
mParagraphs.push_back(
|
||||
Paragraph( mLines.front(),
|
||||
LLColor4::white,
|
||||
mTimer.getElapsedTimeF32(),
|
||||
mFont,
|
||||
(F32)getRect().getWidth()));
|
||||
mLines.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
// remove old paragraphs which can't possibly be visible any more. ::draw() will do something similar but more conservative - we do this here because ::draw() isn't guaranteed to ever be called! (i.e. the console isn't visible)
|
||||
while ((S32)mParagraphs.size() > llmax((S32)0, (S32)(mMaxLines)))
|
||||
{
|
||||
mParagraphs.pop_front();
|
||||
}
|
||||
while ((S32)mParagraphs.size() > llmax((S32)0, (S32)(mMaxLines)))
|
||||
{
|
||||
mParagraphs.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@
|
|||
|
||||
class LLSD;
|
||||
|
||||
class LLConsole : public LLFixedBuffer, public LLUICtrl
|
||||
class LLConsole : public LLFixedBuffer, public LLUICtrl, public LLInstanceTracker<LLConsole>
|
||||
{
|
||||
public:
|
||||
typedef enum e_font_size
|
||||
|
|
@ -68,6 +68,9 @@ protected:
|
|||
friend class LLUICtrlFactory;
|
||||
|
||||
public:
|
||||
// call once per frame to pull data out of LLFixedBuffer
|
||||
static void updateClass();
|
||||
|
||||
//A paragraph color segment defines the color of text in a line
|
||||
//of text that was received for console display. It has no
|
||||
//notion of line wraps, screen position, or the text it contains.
|
||||
|
|
@ -139,14 +142,12 @@ public:
|
|||
// -1 = monospace, 0 means small, font size = 1 means big
|
||||
void setFontSize(S32 size_index);
|
||||
|
||||
void addLine(const std::string& utf8line, F32 size, const LLColor4 &color);
|
||||
void addLine(const LLWString& wline, F32 size, const LLColor4 &color);
|
||||
|
||||
// Overrides
|
||||
/*virtual*/ void draw();
|
||||
/*virtual*/ void addLine(const std::string& utf8line);
|
||||
/*virtual*/ void addLine(const LLWString& line);
|
||||
private:
|
||||
void update();
|
||||
|
||||
F32 mLinePersistTime; // Age at which to stop drawing.
|
||||
F32 mFadeTime; // Age at which to start fading
|
||||
const LLFontGL* mFont;
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ void LLDockableFloater::toggleInstance(const LLSD& sdname)
|
|||
LLDockableFloater* instance =
|
||||
dynamic_cast<LLDockableFloater*> (LLFloaterReg::findInstance(name));
|
||||
// if floater closed or docked
|
||||
if (instance == NULL || instance != NULL && instance->isDocked())
|
||||
if (instance == NULL || (instance && instance->isDocked()))
|
||||
{
|
||||
LLFloaterReg::toggleInstance(name, key);
|
||||
// restore button toggle state
|
||||
|
|
@ -223,10 +223,10 @@ void LLDockableFloater::draw()
|
|||
LLFloater::draw();
|
||||
}
|
||||
|
||||
void LLDockableFloater::setDockControl(LLDockControl* dockControl)
|
||||
void LLDockableFloater::setDockControl(LLDockControl* dockControl, bool docked /* = true */)
|
||||
{
|
||||
mDockControl.reset(dockControl);
|
||||
setDocked(mDockControl.get() != NULL && mDockControl.get()->isDockVisible());
|
||||
setDocked(docked && mDockControl.get() != NULL && mDockControl.get()->isDockVisible());
|
||||
}
|
||||
|
||||
const LLUIImagePtr& LLDockableFloater::getDockTongue()
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@ private:
|
|||
void resetInstance();
|
||||
|
||||
protected:
|
||||
void setDockControl(LLDockControl* dockControl);
|
||||
void setDockControl(LLDockControl* dockControl, bool docked = true);
|
||||
const LLUIImagePtr& getDockTongue();
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -162,7 +162,9 @@ bool LLDockControl::isDockVisible()
|
|||
{
|
||||
case LEFT: // to keep compiler happy
|
||||
break;
|
||||
case BOTTOM:
|
||||
case TOP:
|
||||
{
|
||||
// check is dock inside parent rect
|
||||
LLRect dockParentRect =
|
||||
mDockWidget->getParent()->calcScreenRect();
|
||||
|
|
@ -173,6 +175,9 @@ bool LLDockControl::isDockVisible()
|
|||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -254,6 +259,42 @@ void LLDockControl::moveDockable()
|
|||
}
|
||||
mDockTongueY = dockRect.mTop;
|
||||
|
||||
break;
|
||||
case BOTTOM:
|
||||
x = dockRect.getCenterX() - dockableRect.getWidth() / 2;
|
||||
y = dockRect.mBottom;
|
||||
// unique docking used with dock tongue, so add tongue height o the Y coordinate
|
||||
if (use_tongue)
|
||||
{
|
||||
y -= mDockTongue->getHeight();
|
||||
}
|
||||
|
||||
// check is dockable inside root view rect
|
||||
if (x < rootRect.mLeft)
|
||||
{
|
||||
x = rootRect.mLeft;
|
||||
}
|
||||
if (x + dockableRect.getWidth() > rootRect.mRight)
|
||||
{
|
||||
x = rootRect.mRight - dockableRect.getWidth();
|
||||
}
|
||||
|
||||
// calculate dock tongue position
|
||||
dockParentRect = mDockWidget->getParent()->calcScreenRect();
|
||||
if (dockRect.getCenterX() < dockParentRect.mLeft)
|
||||
{
|
||||
mDockTongueX = dockParentRect.mLeft - mDockTongue->getWidth() / 2;
|
||||
}
|
||||
else if (dockRect.getCenterX() > dockParentRect.mRight)
|
||||
{
|
||||
mDockTongueX = dockParentRect.mRight - mDockTongue->getWidth() / 2;;
|
||||
}
|
||||
else
|
||||
{
|
||||
mDockTongueX = dockRect.getCenterX() - mDockTongue->getWidth() / 2;
|
||||
}
|
||||
mDockTongueY = dockRect.mBottom - mDockTongue->getHeight();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,8 +47,9 @@ class LLDockControl
|
|||
public:
|
||||
enum DocAt
|
||||
{
|
||||
TOP
|
||||
,LEFT
|
||||
TOP,
|
||||
LEFT,
|
||||
BOTTOM
|
||||
};
|
||||
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -816,7 +816,10 @@ void LLLayoutStack::calcMinExtents()
|
|||
//static
|
||||
void LLLayoutStack::updateClass()
|
||||
{
|
||||
for (LLLayoutStack::instance_iter it = beginInstances(); it != endInstances(); ++it)
|
||||
LLInstanceTrackerScopedGuard guard;
|
||||
for (LLLayoutStack::instance_iter it = guard.beginInstances();
|
||||
it != guard.endInstances();
|
||||
++it)
|
||||
{
|
||||
it->updateLayout();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@
|
|||
#include "llui.h"
|
||||
#include "lluictrlfactory.h"
|
||||
#include "llclipboard.h"
|
||||
#include "llmenugl.h"
|
||||
|
||||
//
|
||||
// Imported globals
|
||||
|
|
@ -82,19 +83,6 @@ template class LLLineEditor* LLView::getChild<class LLLineEditor>(
|
|||
// Member functions
|
||||
//
|
||||
|
||||
void LLLineEditor::PrevalidateNamedFuncs::declareValues()
|
||||
{
|
||||
declare("ascii", LLLineEditor::prevalidateASCII);
|
||||
declare("float", LLLineEditor::prevalidateFloat);
|
||||
declare("int", LLLineEditor::prevalidateInt);
|
||||
declare("positive_s32", LLLineEditor::prevalidatePositiveS32);
|
||||
declare("non_negative_s32", LLLineEditor::prevalidateNonNegativeS32);
|
||||
declare("alpha_num", LLLineEditor::prevalidateAlphaNum);
|
||||
declare("alpha_num_space", LLLineEditor::prevalidateAlphaNumSpace);
|
||||
declare("ascii_printable_no_pipe", LLLineEditor::prevalidateASCIIPrintableNoPipe);
|
||||
declare("ascii_printable_no_space", LLLineEditor::prevalidateASCIIPrintableNoSpace);
|
||||
}
|
||||
|
||||
LLLineEditor::Params::Params()
|
||||
: max_length_bytes("max_length", 254),
|
||||
keystroke_callback("keystroke_callback"),
|
||||
|
|
@ -164,7 +152,8 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p)
|
|||
mTentativeFgColor(p.text_tentative_color()),
|
||||
mHighlightColor(p.highlight_color()),
|
||||
mPreeditBgColor(p.preedit_bg_color()),
|
||||
mGLFont(p.font)
|
||||
mGLFont(p.font),
|
||||
mContextMenuHandle()
|
||||
{
|
||||
llassert( mMaxLengthBytes > 0 );
|
||||
|
||||
|
|
@ -191,6 +180,12 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p)
|
|||
setCursor(mText.length());
|
||||
|
||||
setPrevalidate(p.prevalidate_callback());
|
||||
|
||||
LLContextMenu* menu = LLUICtrlFactory::instance().createFromFile<LLContextMenu>
|
||||
("menu_text_editor.xml",
|
||||
LLMenuGL::sMenuContainer,
|
||||
LLMenuHolderGL::child_registry_t::instance());
|
||||
setContextMenu(menu);
|
||||
}
|
||||
|
||||
LLLineEditor::~LLLineEditor()
|
||||
|
|
@ -422,12 +417,16 @@ void LLLineEditor::setCursor( S32 pos )
|
|||
S32 old_cursor_pos = getCursor();
|
||||
mCursorPos = llclamp( pos, 0, mText.length());
|
||||
|
||||
// position of end of next character after cursor
|
||||
S32 pixels_after_scroll = findPixelNearestPos();
|
||||
if( pixels_after_scroll > mTextRightEdge )
|
||||
{
|
||||
S32 width_chars_to_left = mGLFont->getWidth(mText.getWString().c_str(), 0, mScrollHPos);
|
||||
S32 last_visible_char = mGLFont->maxDrawableChars(mText.getWString().c_str(), llmax(0.f, (F32)(mTextRightEdge - mTextLeftEdge + width_chars_to_left)));
|
||||
S32 min_scroll = mGLFont->firstDrawableChar(mText.getWString().c_str(), (F32)(mTextRightEdge - mTextLeftEdge), mText.length(), getCursor());
|
||||
// character immediately to left of cursor should be last one visible (SCROLL_INCREMENT_ADD will scroll in more characters)
|
||||
// or first character if cursor is at beginning
|
||||
S32 new_last_visible_char = llmax(0, getCursor() - 1);
|
||||
S32 min_scroll = mGLFont->firstDrawableChar(mText.getWString().c_str(), (F32)(mTextRightEdge - mTextLeftEdge), mText.length(), new_last_visible_char);
|
||||
if (old_cursor_pos == last_visible_char)
|
||||
{
|
||||
mScrollHPos = llmin(mText.length(), llmax(min_scroll, mScrollHPos + SCROLL_INCREMENT_ADD));
|
||||
|
|
@ -663,6 +662,16 @@ BOOL LLLineEditor::handleMiddleMouseDown(S32 x, S32 y, MASK mask)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL LLLineEditor::handleRightMouseDown(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
setFocus(TRUE);
|
||||
if (!LLUICtrl::handleRightMouseDown(x, y, mask))
|
||||
{
|
||||
showContextMenu(x, y);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL LLLineEditor::handleHover(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
BOOL handled = FALSE;
|
||||
|
|
@ -1962,51 +1971,12 @@ void LLLineEditor::setRect(const LLRect& rect)
|
|||
}
|
||||
}
|
||||
|
||||
void LLLineEditor::setPrevalidate(LLLinePrevalidateFunc func)
|
||||
void LLLineEditor::setPrevalidate(LLTextValidate::validate_func_t func)
|
||||
{
|
||||
mPrevalidateFunc = func;
|
||||
updateAllowingLanguageInput();
|
||||
}
|
||||
|
||||
// Limits what characters can be used to [1234567890.-] with [-] only valid in the first position.
|
||||
// Does NOT ensure that the string is a well-formed number--that's the job of post-validation--for
|
||||
// the simple reasons that intermediate states may be invalid even if the final result is valid.
|
||||
//
|
||||
// static
|
||||
BOOL LLLineEditor::prevalidateFloat(const LLWString &str)
|
||||
{
|
||||
LLLocale locale(LLLocale::USER_LOCALE);
|
||||
|
||||
BOOL success = TRUE;
|
||||
LLWString trimmed = str;
|
||||
LLWStringUtil::trim(trimmed);
|
||||
S32 len = trimmed.length();
|
||||
if( 0 < len )
|
||||
{
|
||||
// May be a comma or period, depending on the locale
|
||||
llwchar decimal_point = (llwchar)LLResMgr::getInstance()->getDecimalPoint();
|
||||
|
||||
S32 i = 0;
|
||||
|
||||
// First character can be a negative sign
|
||||
if( '-' == trimmed[0] )
|
||||
{
|
||||
i++;
|
||||
}
|
||||
|
||||
for( ; i < len; i++ )
|
||||
{
|
||||
if( (decimal_point != trimmed[i] ) && !LLStringOps::isDigit( trimmed[i] ) )
|
||||
{
|
||||
success = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
// static
|
||||
BOOL LLLineEditor::postvalidateFloat(const std::string &str)
|
||||
{
|
||||
|
|
@ -2066,223 +2036,6 @@ BOOL LLLineEditor::postvalidateFloat(const std::string &str)
|
|||
return success;
|
||||
}
|
||||
|
||||
// Limits what characters can be used to [1234567890-] with [-] only valid in the first position.
|
||||
// Does NOT ensure that the string is a well-formed number--that's the job of post-validation--for
|
||||
// the simple reasons that intermediate states may be invalid even if the final result is valid.
|
||||
//
|
||||
// static
|
||||
BOOL LLLineEditor::prevalidateInt(const LLWString &str)
|
||||
{
|
||||
LLLocale locale(LLLocale::USER_LOCALE);
|
||||
|
||||
BOOL success = TRUE;
|
||||
LLWString trimmed = str;
|
||||
LLWStringUtil::trim(trimmed);
|
||||
S32 len = trimmed.length();
|
||||
if( 0 < len )
|
||||
{
|
||||
S32 i = 0;
|
||||
|
||||
// First character can be a negative sign
|
||||
if( '-' == trimmed[0] )
|
||||
{
|
||||
i++;
|
||||
}
|
||||
|
||||
for( ; i < len; i++ )
|
||||
{
|
||||
if( !LLStringOps::isDigit( trimmed[i] ) )
|
||||
{
|
||||
success = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
// static
|
||||
BOOL LLLineEditor::prevalidatePositiveS32(const LLWString &str)
|
||||
{
|
||||
LLLocale locale(LLLocale::USER_LOCALE);
|
||||
|
||||
LLWString trimmed = str;
|
||||
LLWStringUtil::trim(trimmed);
|
||||
S32 len = trimmed.length();
|
||||
BOOL success = TRUE;
|
||||
if(0 < len)
|
||||
{
|
||||
if(('-' == trimmed[0]) || ('0' == trimmed[0]))
|
||||
{
|
||||
success = FALSE;
|
||||
}
|
||||
S32 i = 0;
|
||||
while(success && (i < len))
|
||||
{
|
||||
if(!LLStringOps::isDigit(trimmed[i++]))
|
||||
{
|
||||
success = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (success)
|
||||
{
|
||||
S32 val = strtol(wstring_to_utf8str(trimmed).c_str(), NULL, 10);
|
||||
if (val <= 0)
|
||||
{
|
||||
success = FALSE;
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
BOOL LLLineEditor::prevalidateNonNegativeS32(const LLWString &str)
|
||||
{
|
||||
LLLocale locale(LLLocale::USER_LOCALE);
|
||||
|
||||
LLWString trimmed = str;
|
||||
LLWStringUtil::trim(trimmed);
|
||||
S32 len = trimmed.length();
|
||||
BOOL success = TRUE;
|
||||
if(0 < len)
|
||||
{
|
||||
if('-' == trimmed[0])
|
||||
{
|
||||
success = FALSE;
|
||||
}
|
||||
S32 i = 0;
|
||||
while(success && (i < len))
|
||||
{
|
||||
if(!LLStringOps::isDigit(trimmed[i++]))
|
||||
{
|
||||
success = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (success)
|
||||
{
|
||||
S32 val = strtol(wstring_to_utf8str(trimmed).c_str(), NULL, 10);
|
||||
if (val < 0)
|
||||
{
|
||||
success = FALSE;
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
BOOL LLLineEditor::prevalidateAlphaNum(const LLWString &str)
|
||||
{
|
||||
LLLocale locale(LLLocale::USER_LOCALE);
|
||||
|
||||
BOOL rv = TRUE;
|
||||
S32 len = str.length();
|
||||
if(len == 0) return rv;
|
||||
while(len--)
|
||||
{
|
||||
if( !LLStringOps::isAlnum((char)str[len]) )
|
||||
{
|
||||
rv = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
// static
|
||||
BOOL LLLineEditor::prevalidateAlphaNumSpace(const LLWString &str)
|
||||
{
|
||||
LLLocale locale(LLLocale::USER_LOCALE);
|
||||
|
||||
BOOL rv = TRUE;
|
||||
S32 len = str.length();
|
||||
if(len == 0) return rv;
|
||||
while(len--)
|
||||
{
|
||||
if(!(LLStringOps::isAlnum((char)str[len]) || (' ' == str[len])))
|
||||
{
|
||||
rv = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Used for most names of things stored on the server, due to old file-formats
|
||||
// that used the pipe (|) for multiline text storage. Examples include
|
||||
// inventory item names, parcel names, object names, etc.
|
||||
// static
|
||||
BOOL LLLineEditor::prevalidateASCIIPrintableNoPipe(const LLWString &str)
|
||||
{
|
||||
BOOL rv = TRUE;
|
||||
S32 len = str.length();
|
||||
if(len == 0) return rv;
|
||||
while(len--)
|
||||
{
|
||||
llwchar wc = str[len];
|
||||
if (wc < 0x20
|
||||
|| wc > 0x7f
|
||||
|| wc == '|')
|
||||
{
|
||||
rv = FALSE;
|
||||
break;
|
||||
}
|
||||
if(!(wc == ' '
|
||||
|| LLStringOps::isAlnum((char)wc)
|
||||
|| LLStringOps::isPunct((char)wc) ) )
|
||||
{
|
||||
rv = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
// Used for avatar names
|
||||
// static
|
||||
BOOL LLLineEditor::prevalidateASCIIPrintableNoSpace(const LLWString &str)
|
||||
{
|
||||
BOOL rv = TRUE;
|
||||
S32 len = str.length();
|
||||
if(len == 0) return rv;
|
||||
while(len--)
|
||||
{
|
||||
llwchar wc = str[len];
|
||||
if (wc < 0x20
|
||||
|| wc > 0x7f
|
||||
|| LLStringOps::isSpace(wc))
|
||||
{
|
||||
rv = FALSE;
|
||||
break;
|
||||
}
|
||||
if( !(LLStringOps::isAlnum((char)str[len]) ||
|
||||
LLStringOps::isPunct((char)str[len]) ) )
|
||||
{
|
||||
rv = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
BOOL LLLineEditor::prevalidateASCII(const LLWString &str)
|
||||
{
|
||||
BOOL rv = TRUE;
|
||||
S32 len = str.length();
|
||||
while(len--)
|
||||
{
|
||||
if (str[len] < 0x20 || str[len] > 0x7f)
|
||||
{
|
||||
rv = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
void LLLineEditor::onMouseCaptureLost()
|
||||
{
|
||||
endSelection();
|
||||
|
|
@ -2560,3 +2313,25 @@ LLWString LLLineEditor::getConvertedText() const
|
|||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
void LLLineEditor::showContextMenu(S32 x, S32 y)
|
||||
{
|
||||
LLContextMenu* menu = static_cast<LLContextMenu*>(mContextMenuHandle.get());
|
||||
|
||||
if (menu)
|
||||
{
|
||||
gEditMenuHandler = this;
|
||||
|
||||
S32 screen_x, screen_y;
|
||||
localPointToScreen(x, y, &screen_x, &screen_y);
|
||||
menu->show(screen_x, screen_y);
|
||||
}
|
||||
}
|
||||
|
||||
void LLLineEditor::setContextMenu(LLContextMenu* new_context_menu)
|
||||
{
|
||||
if (new_context_menu)
|
||||
mContextMenuHandle = new_context_menu->getHandle();
|
||||
else
|
||||
mContextMenuHandle.markDead();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,26 +51,18 @@
|
|||
#include "llviewborder.h"
|
||||
|
||||
#include "llpreeditor.h"
|
||||
#include <boost/function.hpp>
|
||||
#include "lltextvalidate.h"
|
||||
|
||||
class LLFontGL;
|
||||
class LLLineEditorRollback;
|
||||
class LLButton;
|
||||
|
||||
typedef boost::function<BOOL (const LLWString &wstr)> LLLinePrevalidateFunc;
|
||||
class LLContextMenu;
|
||||
|
||||
class LLLineEditor
|
||||
: public LLUICtrl, public LLEditMenuHandler, protected LLPreeditor
|
||||
{
|
||||
public:
|
||||
|
||||
struct PrevalidateNamedFuncs
|
||||
: public LLInitParam::TypeValuesHelper<LLLinePrevalidateFunc, PrevalidateNamedFuncs>
|
||||
|
||||
{
|
||||
static void declareValues();
|
||||
};
|
||||
|
||||
typedef boost::function<void (LLLineEditor* caller)> keystroke_callback_t;
|
||||
|
||||
struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
|
||||
|
|
@ -80,7 +72,7 @@ public:
|
|||
|
||||
Optional<keystroke_callback_t> keystroke_callback;
|
||||
|
||||
Optional<LLLinePrevalidateFunc, PrevalidateNamedFuncs> prevalidate_callback;
|
||||
Optional<LLTextValidate::validate_func_t, LLTextValidate::ValidateTextNamedFuncs> prevalidate_callback;
|
||||
|
||||
Optional<LLViewBorder::Params> border;
|
||||
|
||||
|
|
@ -113,6 +105,7 @@ protected:
|
|||
LLLineEditor(const Params&);
|
||||
friend class LLUICtrlFactory;
|
||||
friend class LLFloaterEditUI;
|
||||
void showContextMenu(S32 x, S32 y);
|
||||
public:
|
||||
virtual ~LLLineEditor();
|
||||
|
||||
|
|
@ -122,6 +115,7 @@ public:
|
|||
/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
|
||||
/*virtual*/ BOOL handleDoubleClick(S32 x,S32 y,MASK mask);
|
||||
/*virtual*/ BOOL handleMiddleMouseDown(S32 x,S32 y,MASK mask);
|
||||
/*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
|
||||
/*virtual*/ BOOL handleKeyHere(KEY key, MASK mask );
|
||||
/*virtual*/ BOOL handleUnicodeCharHere(llwchar uni_char);
|
||||
/*virtual*/ void onMouseCaptureLost();
|
||||
|
|
@ -204,6 +198,8 @@ public:
|
|||
const LLColor4& getReadOnlyFgColor() const { return mReadOnlyFgColor.get(); }
|
||||
const LLColor4& getTentativeFgColor() const { return mTentativeFgColor.get(); }
|
||||
|
||||
const LLFontGL* getFont() const { return mGLFont; }
|
||||
|
||||
void setIgnoreArrowKeys(BOOL b) { mIgnoreArrowKeys = b; }
|
||||
void setIgnoreTab(BOOL b) { mIgnoreTab = b; }
|
||||
void setPassDelete(BOOL b) { mPassDelete = b; }
|
||||
|
|
@ -231,17 +227,7 @@ public:
|
|||
void setTextPadding(S32 left, S32 right);
|
||||
|
||||
// Prevalidation controls which keystrokes can affect the editor
|
||||
void setPrevalidate( LLLinePrevalidateFunc func );
|
||||
static BOOL prevalidateFloat(const LLWString &str );
|
||||
static BOOL prevalidateInt(const LLWString &str );
|
||||
static BOOL prevalidatePositiveS32(const LLWString &str);
|
||||
static BOOL prevalidateNonNegativeS32(const LLWString &str);
|
||||
static BOOL prevalidateAlphaNum(const LLWString &str );
|
||||
static BOOL prevalidateAlphaNumSpace(const LLWString &str );
|
||||
static BOOL prevalidateASCIIPrintableNoPipe(const LLWString &str);
|
||||
static BOOL prevalidateASCIIPrintableNoSpace(const LLWString &str);
|
||||
static BOOL prevalidateASCII(const LLWString &str);
|
||||
|
||||
void setPrevalidate( LLTextValidate::validate_func_t func );
|
||||
static BOOL postvalidateFloat(const std::string &str);
|
||||
|
||||
// line history support:
|
||||
|
|
@ -249,7 +235,9 @@ public:
|
|||
void updateHistory(); // stores current line in history
|
||||
|
||||
void setReplaceNewlinesWithSpaces(BOOL replace);
|
||||
|
||||
|
||||
void setContextMenu(LLContextMenu* new_context_menu);
|
||||
|
||||
private:
|
||||
// private helper methods
|
||||
|
||||
|
|
@ -319,7 +307,7 @@ protected:
|
|||
S32 mLastSelectionStart;
|
||||
S32 mLastSelectionEnd;
|
||||
|
||||
LLLinePrevalidateFunc mPrevalidateFunc;
|
||||
LLTextValidate::validate_func_t mPrevalidateFunc;
|
||||
|
||||
LLFrameTimer mKeystrokeTimer;
|
||||
LLTimer mTripleClickTimer;
|
||||
|
|
@ -348,6 +336,8 @@ protected:
|
|||
std::vector<S32> mPreeditPositions;
|
||||
LLPreeditor::standouts_t mPreeditStandouts;
|
||||
|
||||
LLHandle<LLView> mContextMenuHandle;
|
||||
|
||||
private:
|
||||
// Instances that by default point to the statics but can be overidden in XML.
|
||||
LLPointer<LLUIImage> mBgImage;
|
||||
|
|
|
|||
|
|
@ -3941,7 +3941,6 @@ BOOL LLContextMenu::appendContextSubMenu(LLContextMenu *menu)
|
|||
|
||||
item = LLUICtrlFactory::create<LLContextMenuBranch>(p);
|
||||
LLMenuGL::sMenuContainer->addChild(item->getBranch());
|
||||
item->setFont( LLFontGL::getFontSansSerif() );
|
||||
|
||||
return append( item );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -92,14 +92,6 @@ void LLMultiFloater::draw()
|
|||
}
|
||||
else
|
||||
{
|
||||
for (S32 i = 0; i < mTabContainer->getTabCount(); i++)
|
||||
{
|
||||
LLFloater* floaterp = (LLFloater*)mTabContainer->getPanelByIndex(i);
|
||||
if (floaterp->getShortTitle() != mTabContainer->getPanelTitle(i))
|
||||
{
|
||||
mTabContainer->setPanelTitle(i, floaterp->getShortTitle());
|
||||
}
|
||||
}
|
||||
LLFloater::draw();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ LLMultiSliderCtrl::LLMultiSliderCtrl(const LLMultiSliderCtrl::Params& p)
|
|||
params.font(p.font);
|
||||
params.max_length_bytes(MAX_STRING_LENGTH);
|
||||
params.commit_callback.function(LLMultiSliderCtrl::onEditorCommit);
|
||||
params.prevalidate_callback(&LLLineEditor::prevalidateFloat);
|
||||
params.prevalidate_callback(&LLTextValidate::validateFloat);
|
||||
params.follows.flags(FOLLOWS_LEFT | FOLLOWS_BOTTOM);
|
||||
mEditor = LLUICtrlFactory::create<LLLineEditor> (params);
|
||||
mEditor->setFocusReceivedCallback( boost::bind(LLMultiSliderCtrl::onEditorGainFocus, _1, this) );
|
||||
|
|
@ -330,9 +330,14 @@ void LLMultiSliderCtrl::updateText()
|
|||
// static
|
||||
void LLMultiSliderCtrl::onEditorCommit( LLUICtrl* ctrl, const LLSD& userdata)
|
||||
{
|
||||
LLMultiSliderCtrl* self = dynamic_cast<LLMultiSliderCtrl*>(ctrl->getParent());
|
||||
llassert(ctrl);
|
||||
if (!ctrl)
|
||||
return;
|
||||
|
||||
LLMultiSliderCtrl* self = dynamic_cast<LLMultiSliderCtrl*>(ctrl->getParent());
|
||||
llassert(self);
|
||||
if (!self) // cast failed - wrong type! :O
|
||||
return;
|
||||
|
||||
BOOL success = FALSE;
|
||||
F32 val = self->mCurValue;
|
||||
|
|
|
|||
|
|
@ -397,6 +397,12 @@ LLView* LLPanel::fromXML(LLXMLNodePtr node, LLView* parent, LLXMLNodePtr output_
|
|||
if (!panelp)
|
||||
{
|
||||
panelp = LLUICtrlFactory::getInstance()->createFactoryPanel(name);
|
||||
llassert(panelp);
|
||||
|
||||
if (!panelp)
|
||||
{
|
||||
return NULL; // :(
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -414,7 +420,7 @@ LLView* LLPanel::fromXML(LLXMLNodePtr node, LLView* parent, LLXMLNodePtr output_
|
|||
panelp->mCommitCallbackRegistrar.popScope();
|
||||
panelp->mEnableCallbackRegistrar.popScope();
|
||||
|
||||
if (panelp && !panelp->getFactoryMap().empty())
|
||||
if (!panelp->getFactoryMap().empty())
|
||||
{
|
||||
LLUICtrlFactory::instance().popFactoryFunctions();
|
||||
}
|
||||
|
|
@ -936,7 +942,7 @@ LLPanel *LLPanel::childGetVisiblePanelWithHelp()
|
|||
return ::childGetVisiblePanelWithHelp(this);
|
||||
}
|
||||
|
||||
void LLPanel::childSetPrevalidate(const std::string& id, BOOL (*func)(const LLWString &) )
|
||||
void LLPanel::childSetPrevalidate(const std::string& id, bool (*func)(const LLWString &) )
|
||||
{
|
||||
LLLineEditor* child = findChild<LLLineEditor>(id);
|
||||
if (child)
|
||||
|
|
|
|||
|
|
@ -226,7 +226,7 @@ public:
|
|||
std::string childGetText(const std::string& id) const { return childGetValue(id).asString(); }
|
||||
|
||||
// LLLineEditor
|
||||
void childSetPrevalidate(const std::string& id, BOOL (*func)(const LLWString &) );
|
||||
void childSetPrevalidate(const std::string& id, bool (*func)(const LLWString &) );
|
||||
|
||||
// LLButton
|
||||
void childSetAction(const std::string& id, boost::function<void(void*)> function, void* value = NULL);
|
||||
|
|
|
|||
|
|
@ -1388,6 +1388,8 @@ void LLScrollListCtrl::drawItems()
|
|||
|
||||
LLGLSUIDefault gls_ui;
|
||||
|
||||
F32 alpha = getDrawContext().mAlpha;
|
||||
|
||||
{
|
||||
LLLocalClipRect clip(mItemListRect);
|
||||
|
||||
|
|
@ -1463,7 +1465,7 @@ void LLScrollListCtrl::drawItems()
|
|||
bg_color = mBgReadOnlyColor.get();
|
||||
}
|
||||
|
||||
item->draw(item_rect, fg_color, bg_color, highlight_color, mColumnPadding);
|
||||
item->draw(item_rect, fg_color % alpha, bg_color% alpha, highlight_color % alpha, mColumnPadding);
|
||||
|
||||
cur_y -= mLineHeight;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ LLSearchEditor::LLSearchEditor(const LLSearchEditor::Params& p)
|
|||
line_editor_params.keystroke_callback(boost::bind(&LLSearchEditor::handleKeystroke, this));
|
||||
|
||||
mSearchEditor = LLUICtrlFactory::create<LLLineEditor>(line_editor_params);
|
||||
mSearchEditor->setPassDelete(TRUE);
|
||||
addChild(mSearchEditor);
|
||||
|
||||
if (p.search_button_visible)
|
||||
|
|
@ -79,10 +80,12 @@ LLSearchEditor::LLSearchEditor(const LLSearchEditor::Params& p)
|
|||
if (p.clear_button_visible)
|
||||
{
|
||||
// Set up clear button.
|
||||
S32 clr_btn_width = getRect().getHeight(); // button is square, and as tall as search editor
|
||||
LLRect clear_btn_rect(getRect().getWidth() - clr_btn_width, getRect().getHeight(), getRect().getWidth(), 0);
|
||||
LLButton::Params clr_btn_params(p.clear_button);
|
||||
clr_btn_params.name(std::string("clear button"));
|
||||
S32 clr_btn_top = clr_btn_params.rect.bottom + clr_btn_params.rect.height;
|
||||
S32 clr_btn_right = getRect().getWidth() - clr_btn_params.pad_right;
|
||||
S32 clr_btn_left = clr_btn_right - clr_btn_params.rect.width;
|
||||
LLRect clear_btn_rect(clr_btn_left, clr_btn_top, clr_btn_right, p.clear_button.rect.bottom);
|
||||
clr_btn_params.rect(clear_btn_rect) ;
|
||||
clr_btn_params.follows.flags(FOLLOWS_RIGHT|FOLLOWS_TOP);
|
||||
clr_btn_params.tab_stop(false);
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ LLSliderCtrl::LLSliderCtrl(const LLSliderCtrl::Params& p)
|
|||
line_p.rect.setIfNotProvided(text_rect);
|
||||
line_p.font.setIfNotProvided(p.font);
|
||||
line_p.commit_callback.function(&LLSliderCtrl::onEditorCommit);
|
||||
line_p.prevalidate_callback(&LLLineEditor::prevalidateFloat);
|
||||
line_p.prevalidate_callback(&LLTextValidate::validateFloat);
|
||||
mEditor = LLUICtrlFactory::create<LLLineEditor>(line_p);
|
||||
|
||||
mEditor->setFocusReceivedCallback( boost::bind(&LLSliderCtrl::onEditorGainFocus, _1, this ));
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@ LLSpinCtrl::LLSpinCtrl(const LLSpinCtrl::Params& p)
|
|||
}
|
||||
params.max_length_bytes(MAX_STRING_LENGTH);
|
||||
params.commit_callback.function((boost::bind(&LLSpinCtrl::onEditorCommit, this, _2)));
|
||||
params.prevalidate_callback(&LLLineEditor::prevalidateFloat);
|
||||
params.prevalidate_callback(&LLTextValidate::validateFloat);
|
||||
params.follows.flags(FOLLOWS_LEFT | FOLLOWS_BOTTOM);
|
||||
mEditor = LLUICtrlFactory::create<LLLineEditor> (params);
|
||||
mEditor->setFocusReceivedCallback( boost::bind(&LLSpinCtrl::onEditorGainFocus, _1, this ));
|
||||
|
|
|
|||
|
|
@ -35,7 +35,6 @@
|
|||
#include "lltabcontainer.h"
|
||||
|
||||
#include "llfocusmgr.h"
|
||||
#include "llbutton.h"
|
||||
#include "lllocalcliprect.h"
|
||||
#include "llrect.h"
|
||||
#include "llresizehandle.h"
|
||||
|
|
@ -96,6 +95,91 @@ public:
|
|||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//============================================================================
|
||||
/*
|
||||
* @file lltabcontainer.cpp
|
||||
* @brief class implements LLButton with LLIconCtrl on it
|
||||
*/
|
||||
class LLCustomButtonIconCtrl : public LLButton
|
||||
{
|
||||
public:
|
||||
struct Params
|
||||
: public LLInitParam::Block<Params, LLButton::Params>
|
||||
{
|
||||
// LEFT, RIGHT, TOP, BOTTOM paddings of LLIconCtrl in this class has same value
|
||||
Optional<S32> icon_ctrl_pad;
|
||||
|
||||
Params():
|
||||
icon_ctrl_pad("icon_ctrl_pad", 1)
|
||||
{}
|
||||
};
|
||||
|
||||
protected:
|
||||
friend class LLUICtrlFactory;
|
||||
LLCustomButtonIconCtrl(const Params& p):
|
||||
LLButton(p),
|
||||
mIcon(NULL),
|
||||
mIconAlignment(LLFontGL::HCENTER),
|
||||
mIconCtrlPad(p.icon_ctrl_pad)
|
||||
{}
|
||||
|
||||
public:
|
||||
|
||||
void updateLayout()
|
||||
{
|
||||
LLRect button_rect = getRect();
|
||||
LLRect icon_rect = mIcon->getRect();
|
||||
|
||||
S32 icon_size = button_rect.getHeight() - 2*mIconCtrlPad;
|
||||
|
||||
switch(mIconAlignment)
|
||||
{
|
||||
case LLFontGL::LEFT:
|
||||
icon_rect.setLeftTopAndSize(button_rect.mLeft + mIconCtrlPad, button_rect.mTop - mIconCtrlPad,
|
||||
icon_size, icon_size);
|
||||
setLeftHPad(icon_size + mIconCtrlPad * 2);
|
||||
break;
|
||||
case LLFontGL::HCENTER:
|
||||
icon_rect.setLeftTopAndSize(button_rect.mRight - (button_rect.getWidth() + mIconCtrlPad - icon_size)/2, button_rect.mTop - mIconCtrlPad,
|
||||
icon_size, icon_size);
|
||||
setRightHPad(icon_size + mIconCtrlPad * 2);
|
||||
break;
|
||||
case LLFontGL::RIGHT:
|
||||
icon_rect.setLeftTopAndSize(button_rect.mRight - mIconCtrlPad - icon_size, button_rect.mTop - mIconCtrlPad,
|
||||
icon_size, icon_size);
|
||||
setRightHPad(icon_size + mIconCtrlPad * 2);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
mIcon->setRect(icon_rect);
|
||||
}
|
||||
|
||||
void setIcon(LLIconCtrl* icon, LLFontGL::HAlign alignment = LLFontGL::LEFT)
|
||||
{
|
||||
if(icon)
|
||||
{
|
||||
if(mIcon)
|
||||
{
|
||||
removeChild(mIcon);
|
||||
mIcon->die();
|
||||
}
|
||||
mIcon = icon;
|
||||
mIconAlignment = alignment;
|
||||
|
||||
addChild(mIcon);
|
||||
updateLayout();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
LLIconCtrl* mIcon;
|
||||
LLFontGL::HAlign mIconAlignment;
|
||||
S32 mIconCtrlPad;
|
||||
};
|
||||
//============================================================================
|
||||
|
||||
struct LLPlaceHolderPanel : public LLPanel
|
||||
{
|
||||
// create dummy param block to register with "placeholder" nane
|
||||
|
|
@ -127,7 +211,10 @@ LLTabContainer::Params::Params()
|
|||
tab_padding_right("tab_padding_right"),
|
||||
first_tab("first_tab"),
|
||||
middle_tab("middle_tab"),
|
||||
last_tab("last_tab")
|
||||
last_tab("last_tab"),
|
||||
use_custom_icon_ctrl("use_custom_icon_ctrl", false),
|
||||
tab_icon_ctrl_pad("tab_icon_ctrl_pad", 0),
|
||||
use_ellipses("use_ellipses")
|
||||
{
|
||||
name(std::string("tab_container"));
|
||||
mouse_opaque = false;
|
||||
|
|
@ -162,7 +249,10 @@ LLTabContainer::LLTabContainer(const LLTabContainer::Params& p)
|
|||
mFont(p.font),
|
||||
mFirstTabParams(p.first_tab),
|
||||
mMiddleTabParams(p.middle_tab),
|
||||
mLastTabParams(p.last_tab)
|
||||
mLastTabParams(p.last_tab),
|
||||
mCustomIconCtrlUsed(p.use_custom_icon_ctrl),
|
||||
mTabIconCtrlPad(p.tab_icon_ctrl_pad),
|
||||
mUseTabEllipses(p.use_ellipses)
|
||||
{
|
||||
static LLUICachedControl<S32> tabcntr_vert_tab_min_width ("UITabCntrVertTabMinWidth", 0);
|
||||
|
||||
|
|
@ -801,6 +891,10 @@ void LLTabContainer::update_images(LLTabTuple* tuple, TabParams params, LLTabCon
|
|||
void LLTabContainer::addTabPanel(const TabPanelParams& panel)
|
||||
{
|
||||
LLPanel* child = panel.panel();
|
||||
|
||||
llassert(child);
|
||||
if (!child) return;
|
||||
|
||||
const std::string& label = panel.label.isProvided()
|
||||
? panel.label()
|
||||
: panel.panel()->getLabel();
|
||||
|
|
@ -905,6 +999,11 @@ void LLTabContainer::addTabPanel(const TabPanelParams& panel)
|
|||
|
||||
LLTextBox* textbox = NULL;
|
||||
LLButton* btn = NULL;
|
||||
LLCustomButtonIconCtrl::Params custom_btn_params;
|
||||
{
|
||||
custom_btn_params.icon_ctrl_pad(mTabIconCtrlPad);
|
||||
}
|
||||
LLButton::Params normal_btn_params;
|
||||
|
||||
if (placeholder)
|
||||
{
|
||||
|
|
@ -924,7 +1023,9 @@ void LLTabContainer::addTabPanel(const TabPanelParams& panel)
|
|||
{
|
||||
if (mIsVertical)
|
||||
{
|
||||
LLButton::Params p;
|
||||
LLButton::Params& p = (mCustomIconCtrlUsed)?
|
||||
custom_btn_params:normal_btn_params;
|
||||
|
||||
p.name(std::string("vert tab button"));
|
||||
p.rect(btn_rect);
|
||||
p.follows.flags(FOLLOWS_TOP | FOLLOWS_LEFT);
|
||||
|
|
@ -942,11 +1043,22 @@ void LLTabContainer::addTabPanel(const TabPanelParams& panel)
|
|||
{
|
||||
p.pad_left(indent);
|
||||
}
|
||||
btn = LLUICtrlFactory::create<LLButton>(p);
|
||||
|
||||
|
||||
if(mCustomIconCtrlUsed)
|
||||
{
|
||||
btn = LLUICtrlFactory::create<LLCustomButtonIconCtrl>(custom_btn_params);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
btn = LLUICtrlFactory::create<LLButton>(p);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LLButton::Params p;
|
||||
LLButton::Params& p = (mCustomIconCtrlUsed)?
|
||||
custom_btn_params:normal_btn_params;
|
||||
p.name(std::string(child->getName()) + " tab");
|
||||
p.rect(btn_rect);
|
||||
p.click_callback.function(boost::bind(&LLTabContainer::onTabBtn, this, _2, child));
|
||||
|
|
@ -980,7 +1092,14 @@ void LLTabContainer::addTabPanel(const TabPanelParams& panel)
|
|||
p.follows.flags = p.follows.flags() | FOLLOWS_BOTTOM;
|
||||
}
|
||||
|
||||
++ btn = LLUICtrlFactory::create<LLButton>(p);
|
||||
if(mCustomIconCtrlUsed)
|
||||
{
|
||||
btn = LLUICtrlFactory::create<LLCustomButtonIconCtrl>(custom_btn_params);
|
||||
}
|
||||
else
|
||||
{
|
||||
btn = LLUICtrlFactory::create<LLButton>(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1373,8 +1492,8 @@ BOOL LLTabContainer::setTab(S32 which)
|
|||
{
|
||||
LLTabTuple* tuple = *iter;
|
||||
BOOL is_selected = ( tuple == selected_tuple );
|
||||
tuple->mButton->setUseEllipses(TRUE);
|
||||
tuple->mButton->setHAlign(LLFontGL::LEFT);
|
||||
tuple->mButton->setUseEllipses(mUseTabEllipses);
|
||||
tuple->mButton->setHAlign(mFontHalign);
|
||||
tuple->mTabPanel->setVisible( is_selected );
|
||||
// tuple->mTabPanel->setFocus(is_selected); // not clear that we want to do this here.
|
||||
tuple->mButton->setToggleState( is_selected );
|
||||
|
|
@ -1484,7 +1603,7 @@ void LLTabContainer::setTabImage(LLPanel* child, std::string image_name, const L
|
|||
if( tuple )
|
||||
{
|
||||
tuple->mButton->setImageOverlay(image_name, LLFontGL::LEFT, color);
|
||||
reshape_tuple(tuple);
|
||||
reshapeTuple(tuple);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1494,25 +1613,31 @@ void LLTabContainer::setTabImage(LLPanel* child, const LLUUID& image_id, const L
|
|||
if( tuple )
|
||||
{
|
||||
tuple->mButton->setImageOverlay(image_id, LLFontGL::LEFT, color);
|
||||
reshape_tuple(tuple);
|
||||
reshapeTuple(tuple);
|
||||
}
|
||||
}
|
||||
|
||||
void LLTabContainer::reshape_tuple(LLTabTuple* tuple)
|
||||
void LLTabContainer::setTabImage(LLPanel* child, LLIconCtrl* icon)
|
||||
{
|
||||
LLTabTuple* tuple = getTabByPanel(child);
|
||||
LLCustomButtonIconCtrl* button;
|
||||
|
||||
if(tuple)
|
||||
{
|
||||
button = dynamic_cast<LLCustomButtonIconCtrl*>(tuple->mButton);
|
||||
if(button)
|
||||
{
|
||||
button->setIcon(icon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLTabContainer::reshapeTuple(LLTabTuple* tuple)
|
||||
{
|
||||
static LLUICachedControl<S32> tab_padding ("UITabPadding", 0);
|
||||
static LLUICachedControl<S32> image_left_padding ("UIButtonImageLeftPadding", 4);
|
||||
static LLUICachedControl<S32> image_right_padding ("UIButtonImageRightPadding", 4);
|
||||
static LLUICachedControl<S32> image_top_padding ("UIButtonImageTopPadding", 2);
|
||||
static LLUICachedControl<S32> image_bottom_padding ("UIButtonImageBottomPadding", 2);
|
||||
|
||||
if (!mIsVertical)
|
||||
{
|
||||
tuple->mButton->setImageOverlayLeftPad(image_left_padding);
|
||||
tuple->mButton->setImageOverlayRightPad(image_right_padding);
|
||||
tuple->mButton->setImageOverlayTopPad(image_top_padding);
|
||||
tuple->mButton->setImageOverlayBottomPad(image_bottom_padding);
|
||||
|
||||
// remove current width from total tab strip width
|
||||
mTotalTabWidth -= tuple->mButton->getRect().getWidth();
|
||||
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@
|
|||
#include "llpanel.h"
|
||||
#include "lltextbox.h"
|
||||
#include "llframetimer.h"
|
||||
#include "lliconctrl.h"
|
||||
#include "llbutton.h"
|
||||
|
||||
class LLTabTuple;
|
||||
|
||||
|
|
@ -90,6 +92,26 @@ public:
|
|||
middle_tab,
|
||||
last_tab;
|
||||
|
||||
/**
|
||||
* Tab label horizontal alignment
|
||||
*/
|
||||
Optional<LLFontGL::HAlign> font_halign;
|
||||
|
||||
/**
|
||||
* Tab label ellipses
|
||||
*/
|
||||
Optional<bool> use_ellipses;
|
||||
|
||||
/**
|
||||
* Use LLCustomButtonIconCtrl or LLButton in LLTabTuple
|
||||
*/
|
||||
Optional<bool> use_custom_icon_ctrl;
|
||||
|
||||
/**
|
||||
* Paddings for LLIconCtrl in case of LLCustomButtonIconCtrl usage(use_custom_icon_ctrl = true)
|
||||
*/
|
||||
Optional<S32> tab_icon_ctrl_pad;
|
||||
|
||||
Params();
|
||||
};
|
||||
|
||||
|
|
@ -173,6 +195,7 @@ public:
|
|||
void setTabPanelFlashing(LLPanel* child, BOOL state);
|
||||
void setTabImage(LLPanel* child, std::string img_name, const LLColor4& color = LLColor4::white);
|
||||
void setTabImage(LLPanel* child, const LLUUID& img_id, const LLColor4& color = LLColor4::white);
|
||||
void setTabImage(LLPanel* child, LLIconCtrl* icon);
|
||||
void setTitle( const std::string& title );
|
||||
const std::string getPanelTitle(S32 index);
|
||||
|
||||
|
|
@ -228,7 +251,7 @@ private:
|
|||
|
||||
// updates tab button images given the tuple, tab position and the corresponding params
|
||||
void update_images(LLTabTuple* tuple, TabParams params, LLTabContainer::TabPosition pos);
|
||||
void reshape_tuple(LLTabTuple* tuple);
|
||||
void reshapeTuple(LLTabTuple* tuple);
|
||||
|
||||
// Variables
|
||||
|
||||
|
|
@ -278,6 +301,10 @@ private:
|
|||
TabParams mFirstTabParams;
|
||||
TabParams mMiddleTabParams;
|
||||
TabParams mLastTabParams;
|
||||
|
||||
bool mCustomIconCtrlUsed;
|
||||
S32 mTabIconCtrlPad;
|
||||
bool mUseTabEllipses;
|
||||
};
|
||||
|
||||
#endif // LL_TABCONTAINER_H
|
||||
|
|
|
|||
|
|
@ -1137,6 +1137,7 @@ void LLTextBase::reflow()
|
|||
line_list_t::iterator iter = std::upper_bound(mLineInfoList.begin(), mLineInfoList.end(), start_index, line_end_compare());
|
||||
line_start_index = iter->mDocIndexStart;
|
||||
line_count = iter->mLineNum;
|
||||
cur_top = iter->mRect.mTop;
|
||||
getSegmentAndOffset(iter->mDocIndexStart, &seg_iter, &seg_offset);
|
||||
mLineInfoList.erase(iter, mLineInfoList.end());
|
||||
}
|
||||
|
|
@ -1574,8 +1575,10 @@ void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, c
|
|||
{
|
||||
LLStyle::Params icon;
|
||||
icon.image = image;
|
||||
// HACK: fix spacing of images and remove the fixed char spacing
|
||||
appendAndHighlightText(" ", prepend_newline, part, icon);
|
||||
// Text will be replaced during rendering with the icon,
|
||||
// but string cannot be empty or the segment won't be
|
||||
// added (or drawn).
|
||||
appendAndHighlightText(" ", prepend_newline, part, icon);
|
||||
prepend_newline = false;
|
||||
}
|
||||
}
|
||||
|
|
@ -2296,14 +2299,21 @@ F32 LLNormalTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selec
|
|||
{
|
||||
if ( mStyle->isImage() && (start >= 0) && (end <= mEnd - mStart))
|
||||
{
|
||||
// ...for images, only render the image, not the underlying text,
|
||||
// which is only a placeholder space
|
||||
LLColor4 color = LLColor4::white % mEditor.getDrawContext().mAlpha;
|
||||
LLUIImagePtr image = mStyle->getImage();
|
||||
S32 style_image_height = image->getHeight();
|
||||
S32 style_image_width = image->getWidth();
|
||||
// Center the image vertically
|
||||
S32 image_bottom = draw_rect.getCenterY() - (style_image_height/2);
|
||||
// Text is drawn from the top of the draw_rect downward
|
||||
S32 text_center = draw_rect.mTop - (mFontHeight / 2);
|
||||
// Align image to center of text
|
||||
S32 image_bottom = text_center - (style_image_height / 2);
|
||||
image->draw(draw_rect.mLeft, image_bottom,
|
||||
style_image_width, style_image_height, color);
|
||||
|
||||
const S32 IMAGE_HPAD = 3;
|
||||
return draw_rect.mLeft + style_image_width + IMAGE_HPAD;
|
||||
}
|
||||
|
||||
return drawClippedSegment( getStart() + start, getStart() + end, selection_start, selection_end, draw_rect);
|
||||
|
|
|
|||
|
|
@ -237,13 +237,17 @@ private:
|
|||
///////////////////////////////////////////////////////////////////
|
||||
LLTextEditor::Params::Params()
|
||||
: default_text("default_text"),
|
||||
prevalidate_callback("prevalidate_callback"),
|
||||
embedded_items("embedded_items", false),
|
||||
ignore_tab("ignore_tab", true),
|
||||
handle_edit_keys_directly("handle_edit_keys_directly", false),
|
||||
show_line_numbers("show_line_numbers", false),
|
||||
default_color("default_color"),
|
||||
commit_on_focus_lost("commit_on_focus_lost", false)
|
||||
{}
|
||||
commit_on_focus_lost("commit_on_focus_lost", false),
|
||||
show_context_menu("show_context_menu")
|
||||
{
|
||||
addSynonym(prevalidate_callback, "text_type");
|
||||
}
|
||||
|
||||
LLTextEditor::LLTextEditor(const LLTextEditor::Params& p) :
|
||||
LLTextBase(p),
|
||||
|
|
@ -258,7 +262,9 @@ LLTextEditor::LLTextEditor(const LLTextEditor::Params& p) :
|
|||
mMouseDownX(0),
|
||||
mMouseDownY(0),
|
||||
mTabsToNextField(p.ignore_tab),
|
||||
mContextMenu(NULL)
|
||||
mPrevalidateFunc(p.prevalidate_callback()),
|
||||
mContextMenu(NULL),
|
||||
mShowContextMenu(p.show_context_menu)
|
||||
{
|
||||
mDefaultFont = p.font;
|
||||
|
||||
|
|
@ -318,6 +324,17 @@ LLTextEditor::~LLTextEditor()
|
|||
|
||||
void LLTextEditor::setText(const LLStringExplicit &utf8str, const LLStyle::Params& input_params)
|
||||
{
|
||||
// validate incoming text if necessary
|
||||
if (mPrevalidateFunc)
|
||||
{
|
||||
LLWString test_text = utf8str_to_wstring(utf8str);
|
||||
if (!mPrevalidateFunc(test_text))
|
||||
{
|
||||
// not valid text, nothing to do
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
blockUndo();
|
||||
deselect();
|
||||
|
||||
|
|
@ -720,7 +737,7 @@ BOOL LLTextEditor::handleRightMouseDown(S32 x, S32 y, MASK mask)
|
|||
}
|
||||
if (!LLTextBase::handleRightMouseDown(x, y, mask))
|
||||
{
|
||||
if(getMouseOpaque())
|
||||
if(getShowContextMenu())
|
||||
{
|
||||
showContextMenu(x, y);
|
||||
}
|
||||
|
|
@ -909,6 +926,21 @@ S32 LLTextEditor::execute( TextCmd* cmd )
|
|||
// Push the new command is now on the top (front) of the undo stack.
|
||||
mUndoStack.push_front(cmd);
|
||||
mLastCmd = cmd;
|
||||
|
||||
bool need_to_rollback = mPrevalidateFunc
|
||||
&& !mPrevalidateFunc(getViewModel()->getDisplay());
|
||||
if (need_to_rollback)
|
||||
{
|
||||
// get rid of this last command and clean up undo stack
|
||||
undo();
|
||||
|
||||
// remove any evidence of this command from redo history
|
||||
mUndoStack.pop_front();
|
||||
delete cmd;
|
||||
|
||||
// failure, nothing changed
|
||||
delta = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1032,7 +1064,21 @@ S32 LLTextEditor::addChar(S32 pos, llwchar wc)
|
|||
if (mLastCmd && mLastCmd->canExtend(pos))
|
||||
{
|
||||
S32 delta = 0;
|
||||
if (mPrevalidateFunc)
|
||||
{
|
||||
// get a copy of current text contents
|
||||
LLWString test_string(getViewModel()->getDisplay());
|
||||
|
||||
// modify text contents as if this addChar succeeded
|
||||
llassert(pos <= (S32)test_string.size());
|
||||
test_string.insert(pos, 1, wc);
|
||||
if (!mPrevalidateFunc( test_string))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
mLastCmd->extendAndExecute(this, pos, wc, &delta);
|
||||
|
||||
return delta;
|
||||
}
|
||||
else
|
||||
|
|
@ -2478,9 +2524,9 @@ void LLTextEditor::loadKeywords(const std::string& filename,
|
|||
|
||||
void LLTextEditor::updateSegments()
|
||||
{
|
||||
LLFastTimer ft(FTM_SYNTAX_HIGHLIGHTING);
|
||||
if (mKeywords.isLoaded())
|
||||
if (mReflowIndex < S32_MAX && mKeywords.isLoaded())
|
||||
{
|
||||
LLFastTimer ft(FTM_SYNTAX_HIGHLIGHTING);
|
||||
// HACK: No non-ascii keywords for now
|
||||
segment_vec_t segment_list;
|
||||
mKeywords.findSegments(&segment_list, getWText(), mDefaultColor.get(), *this);
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@
|
|||
#include "lldarray.h"
|
||||
#include "llviewborder.h" // for params
|
||||
#include "lltextbase.h"
|
||||
#include "lltextvalidate.h"
|
||||
|
||||
#include "llpreeditor.h"
|
||||
#include "llcontrol.h"
|
||||
|
|
@ -63,12 +64,14 @@ public:
|
|||
struct Params : public LLInitParam::Block<Params, LLTextBase::Params>
|
||||
{
|
||||
Optional<std::string> default_text;
|
||||
Optional<LLTextValidate::validate_func_t, LLTextValidate::ValidateTextNamedFuncs> prevalidate_callback;
|
||||
|
||||
Optional<bool> embedded_items,
|
||||
ignore_tab,
|
||||
handle_edit_keys_directly,
|
||||
show_line_numbers,
|
||||
commit_on_focus_lost;
|
||||
commit_on_focus_lost,
|
||||
show_context_menu;
|
||||
|
||||
//colors
|
||||
Optional<LLUIColor> default_color;
|
||||
|
|
@ -200,6 +203,9 @@ public:
|
|||
const LLTextSegmentPtr getPreviousSegment() const;
|
||||
void getSelectedSegments(segment_vec_t& segments) const;
|
||||
|
||||
void setShowContextMenu(bool show) { mShowContextMenu = show; }
|
||||
bool getShowContextMenu() const { return mShowContextMenu; }
|
||||
|
||||
protected:
|
||||
void showContextMenu(S32 x, S32 y);
|
||||
void drawPreeditMarker();
|
||||
|
|
@ -319,6 +325,7 @@ private:
|
|||
BOOL mTakesFocus;
|
||||
|
||||
BOOL mAllowEmbeddedItems;
|
||||
bool mShowContextMenu;
|
||||
|
||||
LLUUID mSourceID;
|
||||
|
||||
|
|
@ -329,6 +336,7 @@ private:
|
|||
LLCoordGL mLastIMEPosition; // Last position of the IME editor
|
||||
|
||||
keystroke_signal_t mKeystrokeSignal;
|
||||
LLTextValidate::validate_func_t mPrevalidateFunc;
|
||||
|
||||
LLContextMenu* mContextMenu;
|
||||
}; // end class LLTextEditor
|
||||
|
|
|
|||
|
|
@ -0,0 +1,302 @@
|
|||
/**
|
||||
* @file lltextvalidate.cpp
|
||||
* @brief Text validation helper functions
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2001-2009, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
// Text editor widget to let users enter a single line.
|
||||
|
||||
#include "linden_common.h"
|
||||
|
||||
#include "lltextvalidate.h"
|
||||
#include "llresmgr.h" // for LLLocale
|
||||
|
||||
namespace LLTextValidate
|
||||
{
|
||||
void ValidateTextNamedFuncs::declareValues()
|
||||
{
|
||||
declare("ascii", validateASCII);
|
||||
declare("float", validateFloat);
|
||||
declare("int", validateInt);
|
||||
declare("positive_s32", validatePositiveS32);
|
||||
declare("non_negative_s32", validateNonNegativeS32);
|
||||
declare("alpha_num", validateAlphaNum);
|
||||
declare("alpha_num_space", validateAlphaNumSpace);
|
||||
declare("ascii_printable_no_pipe", validateASCIIPrintableNoPipe);
|
||||
declare("ascii_printable_no_space", validateASCIIPrintableNoSpace);
|
||||
}
|
||||
|
||||
// Limits what characters can be used to [1234567890.-] with [-] only valid in the first position.
|
||||
// Does NOT ensure that the string is a well-formed number--that's the job of post-validation--for
|
||||
// the simple reasons that intermediate states may be invalid even if the final result is valid.
|
||||
//
|
||||
bool validateFloat(const LLWString &str)
|
||||
{
|
||||
LLLocale locale(LLLocale::USER_LOCALE);
|
||||
|
||||
bool success = TRUE;
|
||||
LLWString trimmed = str;
|
||||
LLWStringUtil::trim(trimmed);
|
||||
S32 len = trimmed.length();
|
||||
if( 0 < len )
|
||||
{
|
||||
// May be a comma or period, depending on the locale
|
||||
llwchar decimal_point = (llwchar)LLResMgr::getInstance()->getDecimalPoint();
|
||||
|
||||
S32 i = 0;
|
||||
|
||||
// First character can be a negative sign
|
||||
if( '-' == trimmed[0] )
|
||||
{
|
||||
i++;
|
||||
}
|
||||
|
||||
for( ; i < len; i++ )
|
||||
{
|
||||
if( (decimal_point != trimmed[i] ) && !LLStringOps::isDigit( trimmed[i] ) )
|
||||
{
|
||||
success = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
// Limits what characters can be used to [1234567890-] with [-] only valid in the first position.
|
||||
// Does NOT ensure that the string is a well-formed number--that's the job of post-validation--for
|
||||
// the simple reasons that intermediate states may be invalid even if the final result is valid.
|
||||
//
|
||||
bool validateInt(const LLWString &str)
|
||||
{
|
||||
LLLocale locale(LLLocale::USER_LOCALE);
|
||||
|
||||
bool success = TRUE;
|
||||
LLWString trimmed = str;
|
||||
LLWStringUtil::trim(trimmed);
|
||||
S32 len = trimmed.length();
|
||||
if( 0 < len )
|
||||
{
|
||||
S32 i = 0;
|
||||
|
||||
// First character can be a negative sign
|
||||
if( '-' == trimmed[0] )
|
||||
{
|
||||
i++;
|
||||
}
|
||||
|
||||
for( ; i < len; i++ )
|
||||
{
|
||||
if( !LLStringOps::isDigit( trimmed[i] ) )
|
||||
{
|
||||
success = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool validatePositiveS32(const LLWString &str)
|
||||
{
|
||||
LLLocale locale(LLLocale::USER_LOCALE);
|
||||
|
||||
LLWString trimmed = str;
|
||||
LLWStringUtil::trim(trimmed);
|
||||
S32 len = trimmed.length();
|
||||
bool success = TRUE;
|
||||
if(0 < len)
|
||||
{
|
||||
if(('-' == trimmed[0]) || ('0' == trimmed[0]))
|
||||
{
|
||||
success = FALSE;
|
||||
}
|
||||
S32 i = 0;
|
||||
while(success && (i < len))
|
||||
{
|
||||
if(!LLStringOps::isDigit(trimmed[i++]))
|
||||
{
|
||||
success = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (success)
|
||||
{
|
||||
S32 val = strtol(wstring_to_utf8str(trimmed).c_str(), NULL, 10);
|
||||
if (val <= 0)
|
||||
{
|
||||
success = FALSE;
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
bool validateNonNegativeS32(const LLWString &str)
|
||||
{
|
||||
LLLocale locale(LLLocale::USER_LOCALE);
|
||||
|
||||
LLWString trimmed = str;
|
||||
LLWStringUtil::trim(trimmed);
|
||||
S32 len = trimmed.length();
|
||||
bool success = TRUE;
|
||||
if(0 < len)
|
||||
{
|
||||
if('-' == trimmed[0])
|
||||
{
|
||||
success = FALSE;
|
||||
}
|
||||
S32 i = 0;
|
||||
while(success && (i < len))
|
||||
{
|
||||
if(!LLStringOps::isDigit(trimmed[i++]))
|
||||
{
|
||||
success = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (success)
|
||||
{
|
||||
S32 val = strtol(wstring_to_utf8str(trimmed).c_str(), NULL, 10);
|
||||
if (val < 0)
|
||||
{
|
||||
success = FALSE;
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
bool validateAlphaNum(const LLWString &str)
|
||||
{
|
||||
LLLocale locale(LLLocale::USER_LOCALE);
|
||||
|
||||
bool rv = TRUE;
|
||||
S32 len = str.length();
|
||||
if(len == 0) return rv;
|
||||
while(len--)
|
||||
{
|
||||
if( !LLStringOps::isAlnum((char)str[len]) )
|
||||
{
|
||||
rv = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
bool validateAlphaNumSpace(const LLWString &str)
|
||||
{
|
||||
LLLocale locale(LLLocale::USER_LOCALE);
|
||||
|
||||
bool rv = TRUE;
|
||||
S32 len = str.length();
|
||||
if(len == 0) return rv;
|
||||
while(len--)
|
||||
{
|
||||
if(!(LLStringOps::isAlnum((char)str[len]) || (' ' == str[len])))
|
||||
{
|
||||
rv = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Used for most names of things stored on the server, due to old file-formats
|
||||
// that used the pipe (|) for multiline text storage. Examples include
|
||||
// inventory item names, parcel names, object names, etc.
|
||||
bool validateASCIIPrintableNoPipe(const LLWString &str)
|
||||
{
|
||||
bool rv = TRUE;
|
||||
S32 len = str.length();
|
||||
if(len == 0) return rv;
|
||||
while(len--)
|
||||
{
|
||||
llwchar wc = str[len];
|
||||
if (wc < 0x20
|
||||
|| wc > 0x7f
|
||||
|| wc == '|')
|
||||
{
|
||||
rv = FALSE;
|
||||
break;
|
||||
}
|
||||
if(!(wc == ' '
|
||||
|| LLStringOps::isAlnum((char)wc)
|
||||
|| LLStringOps::isPunct((char)wc) ) )
|
||||
{
|
||||
rv = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
// Used for avatar names
|
||||
bool validateASCIIPrintableNoSpace(const LLWString &str)
|
||||
{
|
||||
bool rv = TRUE;
|
||||
S32 len = str.length();
|
||||
if(len == 0) return rv;
|
||||
while(len--)
|
||||
{
|
||||
llwchar wc = str[len];
|
||||
if (wc < 0x20
|
||||
|| wc > 0x7f
|
||||
|| LLStringOps::isSpace(wc))
|
||||
{
|
||||
rv = FALSE;
|
||||
break;
|
||||
}
|
||||
if( !(LLStringOps::isAlnum((char)str[len]) ||
|
||||
LLStringOps::isPunct((char)str[len]) ) )
|
||||
{
|
||||
rv = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
bool validateASCII(const LLWString &str)
|
||||
{
|
||||
bool rv = TRUE;
|
||||
S32 len = str.length();
|
||||
while(len--)
|
||||
{
|
||||
if (str[len] < 0x20 || str[len] > 0x7f)
|
||||
{
|
||||
rv = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
/**
|
||||
* @file lltextbase.h
|
||||
* @author Martin Reddy
|
||||
* @brief The base class of text box/editor, providing Url handling support
|
||||
*
|
||||
* $LicenseInfo:firstyear=2009&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2009, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLTEXTVALIDATE_H
|
||||
#define LL_LLTEXTVALIDATE_H
|
||||
|
||||
#include "llstring.h"
|
||||
#include "llinitparam.h"
|
||||
#include <boost/function.hpp>
|
||||
|
||||
namespace LLTextValidate
|
||||
{
|
||||
typedef boost::function<BOOL (const LLWString &wstr)> validate_func_t;
|
||||
|
||||
struct ValidateTextNamedFuncs
|
||||
: public LLInitParam::TypeValuesHelper<validate_func_t, ValidateTextNamedFuncs>
|
||||
{
|
||||
static void declareValues();
|
||||
};
|
||||
|
||||
bool validateFloat(const LLWString &str );
|
||||
bool validateInt(const LLWString &str );
|
||||
bool validatePositiveS32(const LLWString &str);
|
||||
bool validateNonNegativeS32(const LLWString &str);
|
||||
bool validateAlphaNum(const LLWString &str );
|
||||
bool validateAlphaNumSpace(const LLWString &str );
|
||||
bool validateASCIIPrintableNoPipe(const LLWString &str);
|
||||
bool validateASCIIPrintableNoSpace(const LLWString &str);
|
||||
bool validateASCII(const LLWString &str);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -129,12 +129,6 @@ BOOL LLToolTipView::handleScrollWheel( S32 x, S32 y, S32 clicks )
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
void LLToolTipView::onMouseLeave(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
LLToolTipMgr::instance().blockToolTips();
|
||||
}
|
||||
|
||||
|
||||
void LLToolTipView::drawStickyRect()
|
||||
{
|
||||
gl_rect_2d(LLToolTipMgr::instance().getMouseNearRect(), LLColor4::white, false);
|
||||
|
|
|
|||
|
|
@ -56,8 +56,6 @@ public:
|
|||
/*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
|
||||
/*virtual*/ BOOL handleScrollWheel( S32 x, S32 y, S32 clicks );
|
||||
|
||||
/*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask);
|
||||
|
||||
void drawStickyRect();
|
||||
|
||||
/*virtual*/ void draw();
|
||||
|
|
@ -129,7 +127,8 @@ private:
|
|||
class LLInspector : public LLToolTip
|
||||
{
|
||||
public:
|
||||
struct Params : public LLInitParam::Block<Params, LLToolTip::Params> {};
|
||||
struct Params : public LLInitParam::Block<Params, LLToolTip::Params>
|
||||
{};
|
||||
};
|
||||
|
||||
class LLToolTipMgr : public LLSingleton<LLToolTipMgr>
|
||||
|
|
|
|||
|
|
@ -1894,7 +1894,9 @@ namespace LLInitParam
|
|||
blue("blue"),
|
||||
alpha("alpha"),
|
||||
control("")
|
||||
{}
|
||||
{
|
||||
setBlockFromValue();
|
||||
}
|
||||
|
||||
void TypedParam<LLUIColor>::setValueFromBlock() const
|
||||
{
|
||||
|
|
@ -1939,6 +1941,7 @@ namespace LLInitParam
|
|||
size("size"),
|
||||
style("style")
|
||||
{
|
||||
setBlockFromValue();
|
||||
addSynonym(name, "");
|
||||
}
|
||||
|
||||
|
|
@ -1979,7 +1982,9 @@ namespace LLInitParam
|
|||
bottom("bottom"),
|
||||
width("width"),
|
||||
height("height")
|
||||
{}
|
||||
{
|
||||
setBlockFromValue();
|
||||
}
|
||||
|
||||
void TypedParam<LLRect>::setValueFromBlock() const
|
||||
{
|
||||
|
|
@ -2064,6 +2069,7 @@ namespace LLInitParam
|
|||
x("x"),
|
||||
y("y")
|
||||
{
|
||||
setBlockFromValue();
|
||||
}
|
||||
|
||||
void TypedParam<LLCoordGL>::setValueFromBlock() const
|
||||
|
|
|
|||
|
|
@ -426,8 +426,8 @@ namespace LLInitParam
|
|||
{
|
||||
typedef BlockValue<const LLFontGL*> super_t;
|
||||
public:
|
||||
Mandatory<std::string> name;
|
||||
Optional<std::string> size,
|
||||
Optional<std::string> name,
|
||||
size,
|
||||
style;
|
||||
|
||||
TypedParam(BlockDescriptor& descriptor, const char* name, const LLFontGL* const value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count);
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ LLUIColorTable::Params::Params()
|
|||
{
|
||||
}
|
||||
|
||||
void LLUIColorTable::insertFromParams(const Params& p)
|
||||
void LLUIColorTable::insertFromParams(const Params& p, string_color_map_t& table)
|
||||
{
|
||||
// this map will contain all color references after the following loop
|
||||
typedef std::map<std::string, std::string> string_string_map_t;
|
||||
|
|
@ -69,14 +69,7 @@ void LLUIColorTable::insertFromParams(const Params& p)
|
|||
ColorEntryParams color_entry = *it;
|
||||
if(color_entry.color.value.isChosen())
|
||||
{
|
||||
if(mUserSetColors.find(color_entry.name)!=mUserSetColors.end())
|
||||
{
|
||||
setColor(color_entry.name, color_entry.color.value);
|
||||
}
|
||||
else
|
||||
{
|
||||
setColor(color_entry.name, color_entry.color.value, mLoadedColors);
|
||||
}
|
||||
setColor(color_entry.name, color_entry.color.value, table);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -220,16 +213,16 @@ bool LLUIColorTable::loadFromSettings()
|
|||
bool result = false;
|
||||
|
||||
std::string default_filename = gDirUtilp->getExpandedFilename(LL_PATH_DEFAULT_SKIN, "colors.xml");
|
||||
result |= loadFromFilename(default_filename);
|
||||
result |= loadFromFilename(default_filename, mLoadedColors);
|
||||
|
||||
std::string current_filename = gDirUtilp->getExpandedFilename(LL_PATH_TOP_SKIN, "colors.xml");
|
||||
if(current_filename != default_filename)
|
||||
{
|
||||
result |= loadFromFilename(current_filename);
|
||||
result |= loadFromFilename(current_filename, mLoadedColors);
|
||||
}
|
||||
|
||||
std::string user_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "colors.xml");
|
||||
loadFromFilename(user_filename);
|
||||
loadFromFilename(user_filename, mUserSetColors);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
@ -299,7 +292,7 @@ void LLUIColorTable::setColor(const std::string& name, const LLColor4& color, st
|
|||
}
|
||||
}
|
||||
|
||||
bool LLUIColorTable::loadFromFilename(const std::string& filename)
|
||||
bool LLUIColorTable::loadFromFilename(const std::string& filename, string_color_map_t& table)
|
||||
{
|
||||
LLXMLNodePtr root;
|
||||
|
||||
|
|
@ -320,7 +313,7 @@ bool LLUIColorTable::loadFromFilename(const std::string& filename)
|
|||
|
||||
if(params.validateBlock())
|
||||
{
|
||||
insertFromParams(params);
|
||||
insertFromParams(params, table);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -330,3 +323,11 @@ bool LLUIColorTable::loadFromFilename(const std::string& filename)
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
void LLUIColorTable::insertFromParams(const Params& p)
|
||||
{
|
||||
insertFromParams(p, mUserSetColors);
|
||||
}
|
||||
|
||||
// EOF
|
||||
|
||||
|
|
|
|||
|
|
@ -45,6 +45,10 @@ class LLUIColor;
|
|||
class LLUIColorTable : public LLSingleton<LLUIColorTable>
|
||||
{
|
||||
LOG_CLASS(LLUIColorTable);
|
||||
|
||||
// consider using sorted vector, can be much faster
|
||||
typedef std::map<std::string, LLUIColor> string_color_map_t;
|
||||
|
||||
public:
|
||||
struct ColorParams : LLInitParam::Choice<ColorParams>
|
||||
{
|
||||
|
|
@ -91,10 +95,9 @@ public:
|
|||
void saveUserSettings() const;
|
||||
|
||||
private:
|
||||
bool loadFromFilename(const std::string& filename);
|
||||
bool loadFromFilename(const std::string& filename, string_color_map_t& table);
|
||||
|
||||
// consider using sorted vector, can be much faster
|
||||
typedef std::map<std::string, LLUIColor> string_color_map_t;
|
||||
void insertFromParams(const Params& p, string_color_map_t& table);
|
||||
|
||||
void clearTable(string_color_map_t& table);
|
||||
void setColor(const std::string& name, const LLColor4& color, string_color_map_t& table);
|
||||
|
|
|
|||
|
|
@ -109,6 +109,7 @@ namespace LLInitParam
|
|||
TypedParam(BlockDescriptor& descriptor, const char* name, super_t::value_assignment_t value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count)
|
||||
: super_t(descriptor, name, value, func, min_count, max_count)
|
||||
{
|
||||
setBlockFromValue();
|
||||
}
|
||||
|
||||
void setValueFromBlock() const;
|
||||
|
|
|
|||
|
|
@ -290,7 +290,7 @@ std::string LLUrlEntrySLURL::getLabel(const std::string &url, const LLUrlLabelCa
|
|||
std::string LLUrlEntrySLURL::getLocation(const std::string &url) const
|
||||
{
|
||||
// return the part of the Url after slurl.com/secondlife/
|
||||
const std::string search_string = "secondlife";
|
||||
const std::string search_string = "/secondlife";
|
||||
size_t pos = url.find(search_string);
|
||||
if (pos == std::string::npos)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1720,6 +1720,7 @@ LLView* LLView::findChildView(const std::string& name, BOOL recurse) const
|
|||
for ( child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it)
|
||||
{
|
||||
LLView* childp = *child_it;
|
||||
llassert(childp);
|
||||
if (childp->getName() == name)
|
||||
{
|
||||
return childp;
|
||||
|
|
@ -1731,6 +1732,7 @@ LLView* LLView::findChildView(const std::string& name, BOOL recurse) const
|
|||
for ( child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it)
|
||||
{
|
||||
LLView* childp = *child_it;
|
||||
llassert(childp);
|
||||
LLView* viewp = childp->findChildView(name, recurse);
|
||||
if ( viewp )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -638,7 +638,7 @@ void LLDir::setSkinFolder(const std::string &skin_folder)
|
|||
// e.g. c:\program files\secondlife\skins\default
|
||||
mDefaultSkinDir = getSkinBaseDir();
|
||||
mDefaultSkinDir += mDirDelimiter;
|
||||
mDefaultSkinDir += "default";
|
||||
mDefaultSkinDir += "base";
|
||||
}
|
||||
|
||||
bool LLDir::setCacheDir(const std::string &path)
|
||||
|
|
|
|||
|
|
@ -113,6 +113,7 @@ if (WINDOWS)
|
|||
)
|
||||
list(APPEND llwindow_LINK_LIBRARIES
|
||||
comdlg32 # Common Dialogs for ChooseColor
|
||||
ole32
|
||||
)
|
||||
endif (WINDOWS)
|
||||
|
||||
|
|
|
|||
|
|
@ -50,7 +50,8 @@ class LLDragDropWin32Target:
|
|||
LLDragDropWin32Target( HWND hWnd ) :
|
||||
mRefCount( 1 ),
|
||||
mAppWindowHandle( hWnd ),
|
||||
mAllowDrop( false)
|
||||
mAllowDrop(false),
|
||||
mIsSlurl(false)
|
||||
{
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
#include "llcoord.h"
|
||||
#include "llstring.h"
|
||||
#include "llcursortypes.h"
|
||||
#include "llsd.h"
|
||||
|
||||
class LLSplashScreen;
|
||||
class LLPreeditor;
|
||||
|
|
@ -162,6 +163,9 @@ public:
|
|||
virtual void spawnWebBrowser(const std::string& escaped_url) {};
|
||||
|
||||
static std::vector<std::string> getDynamicFallbackFontList();
|
||||
|
||||
// Provide native key event data
|
||||
virtual LLSD getNativeKeyData() { return LLSD::emptyMap(); }
|
||||
|
||||
protected:
|
||||
LLWindow(LLWindowCallbacks* callbacks, BOOL fullscreen, U32 flags);
|
||||
|
|
|
|||
|
|
@ -260,6 +260,7 @@ LLWindowMacOSX::LLWindowMacOSX(LLWindowCallbacks* callbacks,
|
|||
mTSMScriptCode = 0;
|
||||
mTSMLangCode = 0;
|
||||
mPreeditor = NULL;
|
||||
mRawKeyEvent = NULL;
|
||||
mFSAASamples = fsaa_samples;
|
||||
mForceRebuild = FALSE;
|
||||
|
||||
|
|
@ -2140,10 +2141,11 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e
|
|||
{
|
||||
UInt32 modifiers = 0;
|
||||
|
||||
|
||||
// First, process the raw event.
|
||||
{
|
||||
EventRef rawEvent;
|
||||
|
||||
EventRef rawEvent = NULL;
|
||||
|
||||
// Get the original event and extract the modifier keys, so we can ignore command-key events.
|
||||
if (GetEventParameter(event, kEventParamTextInputSendKeyboardEvent, typeEventRef, NULL, sizeof(rawEvent), NULL, &rawEvent) == noErr)
|
||||
{
|
||||
|
|
@ -2152,6 +2154,9 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e
|
|||
|
||||
// and call this function recursively to handle the raw key event.
|
||||
eventHandler (myHandler, rawEvent);
|
||||
|
||||
// save the raw event until we're done processing the unicode input as well.
|
||||
mRawKeyEvent = rawEvent;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2202,6 +2207,7 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e
|
|||
delete[] buffer;
|
||||
}
|
||||
|
||||
mRawKeyEvent = NULL;
|
||||
result = err;
|
||||
}
|
||||
break;
|
||||
|
|
@ -2276,6 +2282,9 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e
|
|||
GetEventParameter (event, kEventParamKeyCode, typeUInt32, NULL, sizeof(UInt32), NULL, &keyCode);
|
||||
GetEventParameter (event, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers);
|
||||
|
||||
// save the raw event so getNativeKeyData can use it.
|
||||
mRawKeyEvent = event;
|
||||
|
||||
// printf("key event, key code = 0x%08x, char code = 0x%02x (%c), modifiers = 0x%08x\n", keyCode, charCode, (char)charCode, modifiers);
|
||||
// fflush(stdout);
|
||||
|
||||
|
|
@ -2371,6 +2380,8 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e
|
|||
result = eventNotHandledErr;
|
||||
break;
|
||||
}
|
||||
|
||||
mRawKeyEvent = NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -3211,6 +3222,60 @@ void LLWindowMacOSX::spawnWebBrowser(const std::string& escaped_url)
|
|||
}
|
||||
}
|
||||
|
||||
LLSD LLWindowMacOSX::getNativeKeyData()
|
||||
{
|
||||
LLSD result = LLSD::emptyMap();
|
||||
|
||||
if(mRawKeyEvent)
|
||||
{
|
||||
char char_code = 0;
|
||||
UInt32 key_code = 0;
|
||||
UInt32 modifiers = 0;
|
||||
UInt32 keyboard_type = 0;
|
||||
|
||||
GetEventParameter (mRawKeyEvent, kEventParamKeyMacCharCodes, typeChar, NULL, sizeof(char), NULL, &char_code);
|
||||
GetEventParameter (mRawKeyEvent, kEventParamKeyCode, typeUInt32, NULL, sizeof(UInt32), NULL, &key_code);
|
||||
GetEventParameter (mRawKeyEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers);
|
||||
GetEventParameter (mRawKeyEvent, kEventParamKeyboardType, typeUInt32, NULL, sizeof(UInt32), NULL, &keyboard_type);
|
||||
|
||||
result["char_code"] = (S32)char_code;
|
||||
result["key_code"] = (S32)key_code;
|
||||
result["modifiers"] = (S32)modifiers;
|
||||
result["keyboard_type"] = (S32)keyboard_type;
|
||||
|
||||
#if 0
|
||||
// This causes trouble for control characters -- apparently character codes less than 32 (escape, control-A, etc)
|
||||
// cause llsd serialization to create XML that the llsd deserializer won't parse!
|
||||
std::string unicode;
|
||||
OSStatus err = noErr;
|
||||
EventParamType actualType = typeUTF8Text;
|
||||
UInt32 actualSize = 0;
|
||||
char *buffer = NULL;
|
||||
|
||||
err = GetEventParameter (mRawKeyEvent, kEventParamKeyUnicodes, typeUTF8Text, &actualType, 0, &actualSize, NULL);
|
||||
if(err == noErr)
|
||||
{
|
||||
// allocate a buffer and get the actual data.
|
||||
buffer = new char[actualSize];
|
||||
err = GetEventParameter (mRawKeyEvent, kEventParamKeyUnicodes, typeUTF8Text, &actualType, actualSize, &actualSize, buffer);
|
||||
if(err == noErr)
|
||||
{
|
||||
unicode.assign(buffer, actualSize);
|
||||
}
|
||||
delete[] buffer;
|
||||
}
|
||||
|
||||
result["unicode"] = unicode;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
lldebugs << "native key data is: " << result << llendl;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
BOOL LLWindowMacOSX::dialogColorPicker( F32 *r, F32 *g, F32 *b)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -120,6 +120,10 @@ public:
|
|||
|
||||
static std::vector<std::string> getDynamicFallbackFontList();
|
||||
|
||||
// Provide native key event data
|
||||
/*virtual*/ LLSD getNativeKeyData();
|
||||
|
||||
|
||||
protected:
|
||||
LLWindowMacOSX(LLWindowCallbacks* callbacks,
|
||||
const std::string& title, const std::string& name, int x, int y, int width, int height, U32 flags,
|
||||
|
|
@ -218,6 +222,7 @@ protected:
|
|||
|
||||
friend class LLWindowManager;
|
||||
static WindowRef sMediaWindow;
|
||||
EventRef mRawKeyEvent;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -251,6 +251,10 @@ LLWindowSDL::LLWindowSDL(LLWindowCallbacks* callbacks,
|
|||
#if LL_X11
|
||||
mFlashing = FALSE;
|
||||
#endif // LL_X11
|
||||
|
||||
mKeyScanCode = 0;
|
||||
mKeyVirtualKey = 0;
|
||||
mKeyModifiers = KMOD_NONE;
|
||||
}
|
||||
|
||||
static SDL_Surface *Load_BMP_Resource(const char *basename)
|
||||
|
|
@ -1617,7 +1621,7 @@ void LLWindowSDL::processMiscNativeEvents()
|
|||
pump_timer.setTimerExpirySec(1.0f / 15.0f);
|
||||
do {
|
||||
// Always do at least one non-blocking pump
|
||||
gtk_main_iteration_do(0);
|
||||
gtk_main_iteration_do(FALSE);
|
||||
} while (gtk_events_pending() &&
|
||||
!pump_timer.hasExpired());
|
||||
|
||||
|
|
@ -1651,24 +1655,32 @@ void LLWindowSDL::gatherInput()
|
|||
}
|
||||
|
||||
case SDL_KEYDOWN:
|
||||
gKeyboard->handleKeyDown(event.key.keysym.sym, event.key.keysym.mod);
|
||||
// part of the fix for SL-13243
|
||||
if (SDLCheckGrabbyKeys(event.key.keysym.sym, TRUE) != 0)
|
||||
SDLReallyCaptureInput(TRUE);
|
||||
mKeyScanCode = event.key.keysym.scancode;
|
||||
mKeyVirtualKey = event.key.keysym.unicode;
|
||||
mKeyModifiers = event.key.keysym.mod;
|
||||
|
||||
if (event.key.keysym.unicode)
|
||||
{
|
||||
handleUnicodeUTF16(event.key.keysym.unicode,
|
||||
gKeyboard->currentMask(FALSE));
|
||||
}
|
||||
gKeyboard->handleKeyDown(event.key.keysym.sym, event.key.keysym.mod);
|
||||
// part of the fix for SL-13243
|
||||
if (SDLCheckGrabbyKeys(event.key.keysym.sym, TRUE) != 0)
|
||||
SDLReallyCaptureInput(TRUE);
|
||||
|
||||
if (event.key.keysym.unicode)
|
||||
{
|
||||
handleUnicodeUTF16(event.key.keysym.unicode,
|
||||
gKeyboard->currentMask(FALSE));
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_KEYUP:
|
||||
if (SDLCheckGrabbyKeys(event.key.keysym.sym, FALSE) == 0)
|
||||
SDLReallyCaptureInput(FALSE); // part of the fix for SL-13243
|
||||
mKeyScanCode = event.key.keysym.scancode;
|
||||
mKeyVirtualKey = event.key.keysym.unicode;
|
||||
mKeyModifiers = event.key.keysym.mod;
|
||||
|
||||
gKeyboard->handleKeyUp(event.key.keysym.sym, event.key.keysym.mod);
|
||||
break;
|
||||
if (SDLCheckGrabbyKeys(event.key.keysym.sym, FALSE) == 0)
|
||||
SDLReallyCaptureInput(FALSE); // part of the fix for SL-13243
|
||||
|
||||
gKeyboard->handleKeyUp(event.key.keysym.sym, event.key.keysym.mod);
|
||||
break;
|
||||
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
{
|
||||
|
|
@ -2224,6 +2236,39 @@ static void color_changed_callback(GtkWidget *widget,
|
|||
gtk_color_selection_get_current_color(colorsel, colorp);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Make the raw keyboard data available - used to poke through to LLQtWebKit so
|
||||
that Qt/Webkit has access to the virtual keycodes etc. that it needs
|
||||
*/
|
||||
LLSD LLWindowSDL::getNativeKeyData()
|
||||
{
|
||||
LLSD result = LLSD::emptyMap();
|
||||
|
||||
U32 modifiers = 0; // pretend-native modifiers... oh what a tangled web we weave!
|
||||
|
||||
// we go through so many levels of device abstraction that I can't really guess
|
||||
// what a plugin under GDK under Qt under SL under SDL under X11 considers
|
||||
// a 'native' modifier mask. this has been sort of reverse-engineered... they *appear*
|
||||
// to match GDK consts, but that may be co-incidence.
|
||||
modifiers |= (mKeyModifiers & KMOD_LSHIFT) ? 0x0001 : 0;
|
||||
modifiers |= (mKeyModifiers & KMOD_RSHIFT) ? 0x0001 : 0;// munge these into the same shift
|
||||
modifiers |= (mKeyModifiers & KMOD_CAPS) ? 0x0002 : 0;
|
||||
modifiers |= (mKeyModifiers & KMOD_LCTRL) ? 0x0004 : 0;
|
||||
modifiers |= (mKeyModifiers & KMOD_RCTRL) ? 0x0004 : 0;// munge these into the same ctrl
|
||||
modifiers |= (mKeyModifiers & KMOD_LALT) ? 0x0008 : 0;// untested
|
||||
modifiers |= (mKeyModifiers & KMOD_RALT) ? 0x0008 : 0;// untested
|
||||
// *todo: test ALTs - I don't have a case for testing these. Do you?
|
||||
// *todo: NUM? - I don't care enough right now (and it's not a GDK modifier).
|
||||
|
||||
result["scan_code"] = (S32)mKeyScanCode;
|
||||
result["virtual_key"] = (S32)mKeyVirtualKey;
|
||||
result["modifiers"] = (S32)modifiers;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
BOOL LLWindowSDL::dialogColorPicker( F32 *r, F32 *g, F32 *b)
|
||||
{
|
||||
BOOL rtn = FALSE;
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ public:
|
|||
/*virtual*/ void gatherInput();
|
||||
/*virtual*/ void swapBuffers();
|
||||
|
||||
/*virtual*/ void delayInputProcessing() { };
|
||||
/*virtual*/ void delayInputProcessing() { };
|
||||
|
||||
// handy coordinate space conversion routines
|
||||
/*virtual*/ BOOL convertCoords(LLCoordScreen from, LLCoordWindow *to);
|
||||
|
|
@ -155,12 +155,13 @@ protected:
|
|||
BOOL ignore_pixel_depth, U32 fsaa_samples);
|
||||
~LLWindowSDL();
|
||||
|
||||
/*virtual*/ BOOL isValid();
|
||||
/*virtual*/ LLSD getNativeKeyData();
|
||||
|
||||
void initCursors();
|
||||
void quitCursors();
|
||||
BOOL isValid();
|
||||
void moveWindow(const LLCoordScreen& position,const LLCoordScreen& size);
|
||||
|
||||
|
||||
// Changes display resolution. Returns true if successful
|
||||
BOOL setDisplayResolution(S32 width, S32 height, S32 bits, S32 refresh);
|
||||
|
||||
|
|
@ -204,12 +205,16 @@ protected:
|
|||
|
||||
friend class LLWindowManager;
|
||||
|
||||
#if LL_X11
|
||||
private:
|
||||
#if LL_X11
|
||||
void x11_set_urgent(BOOL urgent);
|
||||
BOOL mFlashing;
|
||||
LLTimer mFlashTimer;
|
||||
#endif //LL_X11
|
||||
|
||||
U32 mKeyScanCode;
|
||||
U32 mKeyVirtualKey;
|
||||
SDLMod mKeyModifiers;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -378,6 +378,9 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks,
|
|||
mMousePositionModified = FALSE;
|
||||
mInputProcessingPaused = FALSE;
|
||||
mPreeditor = NULL;
|
||||
mKeyCharCode = 0;
|
||||
mKeyScanCode = 0;
|
||||
mKeyVirtualKey = 0;
|
||||
mhDC = NULL;
|
||||
mhRC = NULL;
|
||||
|
||||
|
|
@ -1872,6 +1875,10 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
|
|||
// allow system keys, such as ALT-F4 to be processed by Windows
|
||||
eat_keystroke = FALSE;
|
||||
case WM_KEYDOWN:
|
||||
window_imp->mKeyCharCode = 0; // don't know until wm_char comes in next
|
||||
window_imp->mKeyScanCode = ( l_param >> 16 ) & 0xff;
|
||||
window_imp->mKeyVirtualKey = w_param;
|
||||
|
||||
window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_KEYDOWN");
|
||||
{
|
||||
if (gDebugWindowProc)
|
||||
|
|
@ -1891,6 +1898,9 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
|
|||
eat_keystroke = FALSE;
|
||||
case WM_KEYUP:
|
||||
{
|
||||
window_imp->mKeyScanCode = ( l_param >> 16 ) & 0xff;
|
||||
window_imp->mKeyVirtualKey = w_param;
|
||||
|
||||
window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_KEYUP");
|
||||
LLFastTimer t2(FTM_KEYHANDLER);
|
||||
|
||||
|
|
@ -1976,6 +1986,8 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
|
|||
break;
|
||||
|
||||
case WM_CHAR:
|
||||
window_imp->mKeyCharCode = w_param;
|
||||
|
||||
// Should really use WM_UNICHAR eventually, but it requires a specific Windows version and I need
|
||||
// to figure out how that works. - Doug
|
||||
//
|
||||
|
|
@ -3051,6 +3063,19 @@ void LLWindowWin32::spawnWebBrowser(const std::string& escaped_url )
|
|||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
Make the raw keyboard data available - used to poke through to LLQtWebKit so
|
||||
that Qt/Webkit has access to the virtual keycodes etc. that it needs
|
||||
*/
|
||||
LLSD LLWindowWin32::getNativeKeyData()
|
||||
{
|
||||
LLSD result = LLSD::emptyMap();
|
||||
|
||||
result["scan_code"] = (S32)mKeyScanCode;
|
||||
result["virtual_key"] = (S32)mKeyVirtualKey;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOL LLWindowWin32::dialogColorPicker( F32 *r, F32 *g, F32 *b )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ protected:
|
|||
HCURSOR loadColorCursor(LPCTSTR name);
|
||||
BOOL isValid();
|
||||
void moveWindow(const LLCoordScreen& position,const LLCoordScreen& size);
|
||||
|
||||
LLSD getNativeKeyData();
|
||||
|
||||
// Changes display resolution. Returns true if successful
|
||||
BOOL setDisplayResolution(S32 width, S32 height, S32 bits, S32 refresh);
|
||||
|
|
@ -211,6 +211,10 @@ protected:
|
|||
|
||||
LLDragDropWin32* mDragDrop;
|
||||
|
||||
U32 mKeyCharCode;
|
||||
U32 mKeyScanCode;
|
||||
U32 mKeyVirtualKey;
|
||||
|
||||
friend class LLWindowManager;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -137,7 +137,7 @@ namespace LLInitParam
|
|||
}
|
||||
|
||||
|
||||
bool BaseBlock::validateBlock(bool silent) const
|
||||
bool BaseBlock::validateBlock(bool emit_errors) const
|
||||
{
|
||||
const BlockDescriptor& block_data = getBlockDescriptor();
|
||||
for (BlockDescriptor::param_validation_list_t::const_iterator it = block_data.mValidationList.begin(); it != block_data.mValidationList.end(); ++it)
|
||||
|
|
@ -145,7 +145,7 @@ namespace LLInitParam
|
|||
const Param* param = getParamFromHandle(it->first);
|
||||
if (!it->second(param))
|
||||
{
|
||||
if (!silent)
|
||||
if (emit_errors)
|
||||
{
|
||||
llwarns << "Invalid param \"" << getParamName(block_data, param) << "\"" << llendl;
|
||||
}
|
||||
|
|
@ -458,7 +458,7 @@ namespace LLInitParam
|
|||
|
||||
// take all provided params from other and apply to self
|
||||
// NOTE: this requires that "other" is of the same derived type as this
|
||||
bool BaseBlock::overwriteFromImpl(BlockDescriptor& block_data, const BaseBlock& other)
|
||||
bool BaseBlock::merge(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite)
|
||||
{
|
||||
bool param_changed = false;
|
||||
BlockDescriptor::all_params_list_t::const_iterator end_it = block_data.mAllParams.end();
|
||||
|
|
@ -471,27 +471,7 @@ namespace LLInitParam
|
|||
if (merge_func)
|
||||
{
|
||||
Param* paramp = getParamFromHandle(it->mParamHandle);
|
||||
param_changed |= merge_func(*paramp, *other_paramp, true);
|
||||
}
|
||||
}
|
||||
return param_changed;
|
||||
}
|
||||
|
||||
// take all provided params that are not already provided, and apply to self
|
||||
bool BaseBlock::fillFromImpl(BlockDescriptor& block_data, const BaseBlock& other)
|
||||
{
|
||||
bool param_changed = false;
|
||||
BlockDescriptor::all_params_list_t::const_iterator end_it = block_data.mAllParams.end();
|
||||
for (BlockDescriptor::all_params_list_t::const_iterator it = block_data.mAllParams.begin();
|
||||
it != end_it;
|
||||
++it)
|
||||
{
|
||||
const Param* other_paramp = other.getParamFromHandle(it->mParamHandle);
|
||||
ParamDescriptor::merge_func_t merge_func = it->mMergeFunc;
|
||||
if (merge_func)
|
||||
{
|
||||
Param* paramp = getParamFromHandle(it->mParamHandle);
|
||||
param_changed |= merge_func(*paramp, *other_paramp, false);
|
||||
param_changed |= merge_func(*paramp, *other_paramp, overwrite);
|
||||
}
|
||||
}
|
||||
return param_changed;
|
||||
|
|
|
|||
|
|
@ -407,7 +407,7 @@ namespace LLInitParam
|
|||
class BaseBlock
|
||||
{
|
||||
public:
|
||||
// "Multiple" constraint types
|
||||
// "Multiple" constraint types, put here in root class to avoid ambiguity during use
|
||||
struct AnyAmount
|
||||
{
|
||||
static U32 minCount() { return 0; }
|
||||
|
|
@ -452,7 +452,7 @@ namespace LLInitParam
|
|||
bool submitValue(const Parser::name_stack_t& name_stack, Parser& p, bool silent=false);
|
||||
|
||||
param_handle_t getHandleFromParam(const Param* param) const;
|
||||
bool validateBlock(bool silent = false) const;
|
||||
bool validateBlock(bool emit_errors = true) const;
|
||||
|
||||
Param* getParamFromHandle(const param_handle_t param_handle)
|
||||
{
|
||||
|
|
@ -500,10 +500,7 @@ namespace LLInitParam
|
|||
|
||||
|
||||
// take all provided params from other and apply to self
|
||||
bool overwriteFromImpl(BlockDescriptor& block_data, const BaseBlock& other);
|
||||
|
||||
// take all provided params that are not already provided, and apply to self
|
||||
bool fillFromImpl(BlockDescriptor& block_data, const BaseBlock& other);
|
||||
bool merge(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite);
|
||||
|
||||
// can be updated in getters
|
||||
mutable S32 mChangeVersion;
|
||||
|
|
@ -805,7 +802,7 @@ namespace LLInitParam
|
|||
if (Param::getProvided() && mData.mValidatedVersion < T::getLastChangeVersion())
|
||||
{
|
||||
// a sub-block is "provided" when it has been filled in enough to be valid
|
||||
mData.mValidated = T::validateBlock(true);
|
||||
mData.mValidated = T::validateBlock(false);
|
||||
mData.mValidatedVersion = T::getLastChangeVersion();
|
||||
}
|
||||
return Param::getProvided() && mData.mValidated;
|
||||
|
|
@ -1236,7 +1233,7 @@ namespace LLInitParam
|
|||
it != mValues.end();
|
||||
++it)
|
||||
{
|
||||
if(it->validateBlock(true)) count++;
|
||||
if(it->validateBlock(false)) count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
|
@ -1286,7 +1283,7 @@ namespace LLInitParam
|
|||
bool overwriteFrom(const self_t& other)
|
||||
{
|
||||
mCurChoice = other.mCurChoice;
|
||||
return BaseBlock::overwriteFromImpl(blockDescriptor(), other);
|
||||
return BaseBlock::merge(blockDescriptor(), other, true);
|
||||
}
|
||||
|
||||
// take all provided params that are not already provided, and apply to self
|
||||
|
|
@ -1413,13 +1410,13 @@ namespace LLInitParam
|
|||
// take all provided params from other and apply to self
|
||||
bool overwriteFrom(const self_t& other)
|
||||
{
|
||||
return BaseBlock::overwriteFromImpl(blockDescriptor(), other);
|
||||
return BaseBlock::merge(blockDescriptor(), other, true);
|
||||
}
|
||||
|
||||
// take all provided params that are not already provided, and apply to self
|
||||
bool fillFrom(const self_t& other)
|
||||
{
|
||||
return BaseBlock::fillFromImpl(blockDescriptor(), other);
|
||||
return BaseBlock::merge(blockDescriptor(), other, false);
|
||||
}
|
||||
protected:
|
||||
Block()
|
||||
|
|
@ -1710,7 +1707,7 @@ namespace LLInitParam
|
|||
// if cached value is stale, regenerate from params
|
||||
if (Param::getProvided() && mData.mLastParamVersion < BaseBlock::getLastChangeVersion())
|
||||
{
|
||||
if (block_t::validateBlock(true))
|
||||
if (block_t::validateBlock(false))
|
||||
{
|
||||
static_cast<const DERIVED*>(this)->setValueFromBlock();
|
||||
// clear stale keyword associated with old value
|
||||
|
|
@ -1769,7 +1766,7 @@ namespace LLInitParam
|
|||
if (Param::getProvided() && (mData.mLastParamVersion < BaseBlock::getLastChangeVersion()))
|
||||
{
|
||||
// go ahead and issue warnings at this point if any param is invalid
|
||||
if(block_t::validateBlock(false))
|
||||
if(block_t::validateBlock(true))
|
||||
{
|
||||
static_cast<const DERIVED*>(this)->setValueFromBlock();
|
||||
mData.clearKey();
|
||||
|
|
@ -1797,25 +1794,23 @@ namespace LLInitParam
|
|||
private:
|
||||
static bool mergeWith(Param& dst, const Param& src, bool overwrite)
|
||||
{
|
||||
const self_t& src_param = static_cast<const self_t&>(src);
|
||||
const self_t& src_typed_param = static_cast<const self_t&>(src);
|
||||
self_t& dst_typed_param = static_cast<self_t&>(dst);
|
||||
|
||||
if (src_param.isProvided()
|
||||
if (src_typed_param.isProvided()
|
||||
&& (overwrite || !dst_typed_param.isProvided()))
|
||||
{
|
||||
// assign individual parameters
|
||||
if (overwrite)
|
||||
{
|
||||
dst_typed_param.BaseBlock::overwriteFromImpl(block_t::blockDescriptor(), src_param);
|
||||
}
|
||||
else
|
||||
{
|
||||
dst_typed_param.BaseBlock::fillFromImpl(block_t::blockDescriptor(), src_param);
|
||||
}
|
||||
dst_typed_param.BaseBlock::merge(block_t::blockDescriptor(), src_typed_param, overwrite);
|
||||
|
||||
// then copy actual value
|
||||
dst_typed_param.mData.mValue = src_param.get();
|
||||
dst_typed_param.mData.mValue = src_typed_param.get();
|
||||
dst_typed_param.mData.clearKey();
|
||||
dst_typed_param.setProvided(true);
|
||||
|
||||
// Propagate value back to block params since the value was updated during this merge.
|
||||
// This will result in mData.mValue and the block params being in sync.
|
||||
static_cast<DERIVED&>(dst_typed_param).setBlockFromValue();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -324,33 +324,33 @@ void LLXUIXSDWriter::writeXSD(const std::string& type_name, const std::string& p
|
|||
// add includes for all possible children
|
||||
const std::type_info* type = *LLWidgetTypeRegistry::instance().getValue(type_name);
|
||||
const widget_registry_t* widget_registryp = LLChildRegistryRegistry::instance().getValue(type);
|
||||
|
||||
// add include declarations for all valid children
|
||||
for (widget_registry_t::Registrar::registry_map_t::const_iterator it = widget_registryp->currentRegistrar().beginItems();
|
||||
it != widget_registryp->currentRegistrar().endItems();
|
||||
++it)
|
||||
{
|
||||
std::string widget_name = it->first;
|
||||
if (widget_name == type_name)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
LLXMLNodePtr nodep = new LLXMLNode("xs:include", false);
|
||||
nodep->createChild("schemaLocation", true)->setStringValue(widget_name + ".xsd");
|
||||
|
||||
// add to front of schema
|
||||
mSchemaNode->addChild(nodep, mSchemaNode);
|
||||
}
|
||||
|
||||
// add choices for valid children
|
||||
if (widget_registryp)
|
||||
{
|
||||
// add include declarations for all valid children
|
||||
for (widget_registry_t::Registrar::registry_map_t::const_iterator it = widget_registryp->currentRegistrar().beginItems();
|
||||
it != widget_registryp->currentRegistrar().endItems();
|
||||
++it)
|
||||
{
|
||||
std::string widget_name = it->first;
|
||||
if (widget_name == type_name)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
LLXMLNodePtr nodep = new LLXMLNode("xs:include", false);
|
||||
nodep->createChild("schemaLocation", true)->setStringValue(widget_name + ".xsd");
|
||||
|
||||
// add to front of schema
|
||||
mSchemaNode->addChild(nodep, mSchemaNode);
|
||||
}
|
||||
|
||||
for (widget_registry_t::Registrar::registry_map_t::const_iterator it = widget_registryp->currentRegistrar().beginItems();
|
||||
it != widget_registryp->currentRegistrar().endItems();
|
||||
++it)
|
||||
{
|
||||
std::string widget_name = it->first;
|
||||
//<xs:element name="widget_name" type="widget_name">
|
||||
//<xs:element name="widget_name" type="widget_name">
|
||||
LLXMLNodePtr widget_node = mElementNode->createChild("xs:element", false);
|
||||
widget_node->createChild("name", true)->setStringValue(widget_name);
|
||||
widget_node->createChild("type", true)->setStringValue(widget_name);
|
||||
|
|
|
|||
|
|
@ -9805,6 +9805,9 @@ void LLScriptEventHandler::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCom
|
|||
break;
|
||||
case LSCP_EMIT_BYTE_CODE:
|
||||
{
|
||||
llassert(mEventp);
|
||||
if (!mEventp) return;
|
||||
|
||||
// order for event handler
|
||||
// set jump table value
|
||||
S32 jumpoffset;
|
||||
|
|
@ -9818,13 +9821,11 @@ void LLScriptEventHandler::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCom
|
|||
chunk->addBytes(4);
|
||||
|
||||
// null terminated event name and null terminated parameters
|
||||
if (mEventp)
|
||||
{
|
||||
LLScriptByteCodeChunk *event = new LLScriptByteCodeChunk(FALSE);
|
||||
mEventp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, event, heap, stacksize, entry, entrycount, NULL);
|
||||
chunk->addBytes(event->mCodeChunk, event->mCurrentOffset);
|
||||
delete event;
|
||||
}
|
||||
LLScriptByteCodeChunk *event = new LLScriptByteCodeChunk(FALSE);
|
||||
mEventp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, event, heap, stacksize, entry, entrycount, NULL);
|
||||
chunk->addBytes(event->mCodeChunk, event->mCurrentOffset);
|
||||
delete event;
|
||||
|
||||
chunk->addBytes(1);
|
||||
|
||||
// now we're at the first opcode
|
||||
|
|
@ -10626,6 +10627,8 @@ LLScriptScript::LLScriptScript(LLScritpGlobalStorage *globals,
|
|||
}
|
||||
temp = temp->mNextp;
|
||||
}
|
||||
|
||||
mClassName[0] = '\0';
|
||||
}
|
||||
|
||||
void LLScriptScript::setBytecodeDest(const char* dst_filename)
|
||||
|
|
|
|||
|
|
@ -1876,7 +1876,7 @@ class LLScriptStateChange : public LLScriptStatement
|
|||
{
|
||||
public:
|
||||
LLScriptStateChange(S32 line, S32 col, LLScriptIdentifier *identifier)
|
||||
: LLScriptStatement(line, col, LSSMT_STATE_CHANGE), mIdentifier(identifier)
|
||||
: LLScriptStatement(line, col, LSSMT_STATE_CHANGE), mIdentifier(identifier), mReturnType(LST_NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -2210,7 +2210,7 @@ class LLScriptState : public LLScriptFilePosition
|
|||
{
|
||||
public:
|
||||
LLScriptState(S32 line, S32 col, LSCRIPTStateType type, LLScriptIdentifier *identifier, LLScriptEventHandler *event)
|
||||
: LLScriptFilePosition(line, col), mType(type), mIdentifier(identifier), mEvent(event), mNextp(NULL)
|
||||
: LLScriptFilePosition(line, col), mType(type), mIdentifier(identifier), mEvent(event), mNextp(NULL), mStateScope(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ include(LLPlugin)
|
|||
include(LLMath)
|
||||
include(LLRender)
|
||||
include(LLWindow)
|
||||
include(UI)
|
||||
include(Linking)
|
||||
include(PluginAPI)
|
||||
include(MediaPluginBase)
|
||||
|
|
@ -38,7 +39,7 @@ add_library(media_plugin_webkit
|
|||
${media_plugin_webkit_SOURCE_FILES}
|
||||
)
|
||||
|
||||
target_link_libraries(media_plugin_webkit
|
||||
set(media_plugin_webkit_LINK_LIBRARIES
|
||||
${LLPLUGIN_LIBRARIES}
|
||||
${MEDIA_PLUGIN_BASE_LIBRARIES}
|
||||
${LLCOMMON_LIBRARIES}
|
||||
|
|
@ -46,6 +47,14 @@ target_link_libraries(media_plugin_webkit
|
|||
${PLUGIN_API_WINDOWS_LIBRARIES}
|
||||
)
|
||||
|
||||
if (LINUX)
|
||||
list(APPEND media_plugin_webkit_LINK_LIBRARIES
|
||||
${UI_LIBRARIES} # for glib/GTK
|
||||
)
|
||||
endif (LINUX)
|
||||
|
||||
target_link_libraries(media_plugin_webkit ${media_plugin_webkit_LINK_LIBRARIES})
|
||||
|
||||
add_dependencies(media_plugin_webkit
|
||||
${LLPLUGIN_LIBRARIES}
|
||||
${MEDIA_PLUGIN_BASE_LIBRARIES}
|
||||
|
|
@ -79,4 +88,5 @@ if (DARWIN)
|
|||
DEPENDS media_plugin_webkit ${CMAKE_SOURCE_DIR}/../libraries/universal-darwin/lib_release/libllqtwebkit.dylib
|
||||
)
|
||||
|
||||
endif (DARWIN)
|
||||
endif (DARWIN)
|
||||
|
||||
|
|
|
|||
|
|
@ -470,92 +470,96 @@ private:
|
|||
return (LLQtWebKit::EKeyboardModifier)result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void deserializeKeyboardData( LLSD native_key_data, uint32_t& native_scan_code, uint32_t& native_virtual_key, uint32_t& native_modifiers )
|
||||
{
|
||||
native_scan_code = 0;
|
||||
native_virtual_key = 0;
|
||||
native_modifiers = 0;
|
||||
|
||||
if( native_key_data.isMap() )
|
||||
{
|
||||
#if LL_DARWIN
|
||||
native_scan_code = (uint32_t)(native_key_data["char_code"].asInteger());
|
||||
native_virtual_key = (uint32_t)(native_key_data["key_code"].asInteger());
|
||||
native_modifiers = (uint32_t)(native_key_data["modifiers"].asInteger());
|
||||
#elif LL_WINDOWS
|
||||
native_scan_code = (uint32_t)(native_key_data["scan_code"].asInteger());
|
||||
native_virtual_key = (uint32_t)(native_key_data["virtual_key"].asInteger());
|
||||
// TODO: I don't think we need to do anything with native modifiers here -- please verify
|
||||
#elif LL_LINUX
|
||||
native_scan_code = (uint32_t)(native_key_data["scan_code"].asInteger());
|
||||
native_virtual_key = (uint32_t)(native_key_data["virtual_key"].asInteger());
|
||||
native_modifiers = (uint32_t)(native_key_data["modifiers"].asInteger());
|
||||
#else
|
||||
// Add other platforms here as needed
|
||||
#endif
|
||||
};
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void keyEvent(LLQtWebKit::EKeyEvent key_event, int key, LLQtWebKit::EKeyboardModifier modifiers)
|
||||
void keyEvent(LLQtWebKit::EKeyEvent key_event, int key, LLQtWebKit::EKeyboardModifier modifiers, LLSD native_key_data = LLSD::emptyMap())
|
||||
{
|
||||
int llqt_key;
|
||||
|
||||
// The incoming values for 'key' will be the ones from indra_constants.h
|
||||
// the outgoing values are the ones from llqtwebkit.h
|
||||
std::string utf8_text;
|
||||
|
||||
if(key < KEY_SPECIAL)
|
||||
{
|
||||
// Low-ascii characters need to get passed through.
|
||||
utf8_text = (char)key;
|
||||
}
|
||||
|
||||
// Any special-case handling we want to do for particular keys...
|
||||
switch((KEY)key)
|
||||
{
|
||||
// This is the list that the llqtwebkit implementation actually maps into Qt keys.
|
||||
// case KEY_XXX: llqt_key = LL_DOM_VK_CANCEL; break;
|
||||
// case KEY_XXX: llqt_key = LL_DOM_VK_HELP; break;
|
||||
case KEY_BACKSPACE: llqt_key = LL_DOM_VK_BACK_SPACE; break;
|
||||
case KEY_TAB: llqt_key = LL_DOM_VK_TAB; break;
|
||||
// case KEY_XXX: llqt_key = LL_DOM_VK_CLEAR; break;
|
||||
case KEY_RETURN: llqt_key = LL_DOM_VK_RETURN; break;
|
||||
case KEY_PAD_RETURN: llqt_key = LL_DOM_VK_ENTER; break;
|
||||
case KEY_SHIFT: llqt_key = LL_DOM_VK_SHIFT; break;
|
||||
case KEY_CONTROL: llqt_key = LL_DOM_VK_CONTROL; break;
|
||||
case KEY_ALT: llqt_key = LL_DOM_VK_ALT; break;
|
||||
// case KEY_XXX: llqt_key = LL_DOM_VK_PAUSE; break;
|
||||
case KEY_CAPSLOCK: llqt_key = LL_DOM_VK_CAPS_LOCK; break;
|
||||
case KEY_ESCAPE: llqt_key = LL_DOM_VK_ESCAPE; break;
|
||||
case KEY_PAGE_UP: llqt_key = LL_DOM_VK_PAGE_UP; break;
|
||||
case KEY_PAGE_DOWN: llqt_key = LL_DOM_VK_PAGE_DOWN; break;
|
||||
case KEY_END: llqt_key = LL_DOM_VK_END; break;
|
||||
case KEY_HOME: llqt_key = LL_DOM_VK_HOME; break;
|
||||
case KEY_LEFT: llqt_key = LL_DOM_VK_LEFT; break;
|
||||
case KEY_UP: llqt_key = LL_DOM_VK_UP; break;
|
||||
case KEY_RIGHT: llqt_key = LL_DOM_VK_RIGHT; break;
|
||||
case KEY_DOWN: llqt_key = LL_DOM_VK_DOWN; break;
|
||||
// case KEY_XXX: llqt_key = LL_DOM_VK_PRINTSCREEN; break;
|
||||
case KEY_INSERT: llqt_key = LL_DOM_VK_INSERT; break;
|
||||
case KEY_DELETE: llqt_key = LL_DOM_VK_DELETE; break;
|
||||
// case KEY_XXX: llqt_key = LL_DOM_VK_CONTEXT_MENU; break;
|
||||
// ASCII codes for some standard keys
|
||||
case LLQtWebKit::KEY_BACKSPACE: utf8_text = (char)8; break;
|
||||
case LLQtWebKit::KEY_TAB: utf8_text = (char)9; break;
|
||||
case LLQtWebKit::KEY_RETURN: utf8_text = (char)13; break;
|
||||
case LLQtWebKit::KEY_PAD_RETURN: utf8_text = (char)13; break;
|
||||
case LLQtWebKit::KEY_ESCAPE: utf8_text = (char)27; break;
|
||||
|
||||
default:
|
||||
if(key < KEY_SPECIAL)
|
||||
{
|
||||
// Pass the incoming key through -- it should be regular ASCII, which should be correct for webkit.
|
||||
llqt_key = key;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Don't pass through untranslated special keys -- they'll be all wrong.
|
||||
llqt_key = 0;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// std::cerr << "keypress, original code = 0x" << std::hex << key << ", converted code = 0x" << std::hex << llqt_key << std::dec << std::endl;
|
||||
// std::cerr << "key event " << (int)key_event << ", native_key_data = " << native_key_data << std::endl;
|
||||
|
||||
if(llqt_key != 0)
|
||||
{
|
||||
LLQtWebKit::getInstance()->keyEvent( mBrowserWindowId, key_event, llqt_key, modifiers);
|
||||
}
|
||||
uint32_t native_scan_code = 0;
|
||||
uint32_t native_virtual_key = 0;
|
||||
uint32_t native_modifiers = 0;
|
||||
deserializeKeyboardData( native_key_data, native_scan_code, native_virtual_key, native_modifiers );
|
||||
|
||||
LLQtWebKit::getInstance()->keyboardEvent( mBrowserWindowId, key_event, (uint32_t)key, utf8_text.c_str(), modifiers, native_scan_code, native_virtual_key, native_modifiers);
|
||||
|
||||
checkEditState();
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void unicodeInput( const std::string &utf8str, LLQtWebKit::EKeyboardModifier modifiers)
|
||||
{
|
||||
LLWString wstr = utf8str_to_wstring(utf8str);
|
||||
void unicodeInput( const std::string &utf8str, LLQtWebKit::EKeyboardModifier modifiers, LLSD native_key_data = LLSD::emptyMap())
|
||||
{
|
||||
uint32_t key = LLQtWebKit::KEY_NONE;
|
||||
|
||||
unsigned int i;
|
||||
for(i=0; i < wstr.size(); i++)
|
||||
// std::cerr << "unicode input, native_key_data = " << native_key_data << std::endl;
|
||||
|
||||
if(utf8str.size() == 1)
|
||||
{
|
||||
// std::cerr << "unicode input, code = 0x" << std::hex << (unsigned long)(wstr[i]) << std::dec << std::endl;
|
||||
|
||||
if(wstr[i] == 32)
|
||||
{
|
||||
// For some reason, the webkit plugin really wants the space bar to come in through the key-event path, not the unicode path.
|
||||
LLQtWebKit::getInstance()->keyEvent( mBrowserWindowId, LLQtWebKit::KE_KEY_DOWN, 32, modifiers);
|
||||
LLQtWebKit::getInstance()->keyEvent( mBrowserWindowId, LLQtWebKit::KE_KEY_UP, 32, modifiers);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLQtWebKit::getInstance()->unicodeInput(mBrowserWindowId, wstr[i], modifiers);
|
||||
}
|
||||
// The only way a utf8 string can be one byte long is if it's actually a single 7-bit ascii character.
|
||||
// In this case, use it as the key value.
|
||||
key = utf8str[0];
|
||||
}
|
||||
|
||||
uint32_t native_scan_code = 0;
|
||||
uint32_t native_virtual_key = 0;
|
||||
uint32_t native_modifiers = 0;
|
||||
deserializeKeyboardData( native_key_data, native_scan_code, native_virtual_key, native_modifiers );
|
||||
|
||||
LLQtWebKit::getInstance()->keyboardEvent( mBrowserWindowId, LLQtWebKit::KE_KEY_DOWN, (uint32_t)key, utf8str.c_str(), modifiers, native_scan_code, native_virtual_key, native_modifiers);
|
||||
LLQtWebKit::getInstance()->keyboardEvent( mBrowserWindowId, LLQtWebKit::KE_KEY_UP, (uint32_t)key, utf8str.c_str(), modifiers, native_scan_code, native_virtual_key, native_modifiers);
|
||||
|
||||
checkEditState();
|
||||
};
|
||||
|
||||
|
|
@ -855,6 +859,7 @@ void MediaPluginWebKit::receiveMessage(const char *message_string)
|
|||
std::string event = message_in.getValue("event");
|
||||
S32 key = message_in.getValueS32("key");
|
||||
std::string modifiers = message_in.getValue("modifiers");
|
||||
LLSD native_key_data = message_in.getValueLLSD("native_key_data");
|
||||
|
||||
// Treat unknown events as key-up for safety.
|
||||
LLQtWebKit::EKeyEvent key_event = LLQtWebKit::KE_KEY_UP;
|
||||
|
|
@ -867,14 +872,15 @@ void MediaPluginWebKit::receiveMessage(const char *message_string)
|
|||
key_event = LLQtWebKit::KE_KEY_REPEAT;
|
||||
}
|
||||
|
||||
keyEvent(key_event, key, decodeModifiers(modifiers));
|
||||
keyEvent(key_event, key, decodeModifiers(modifiers), native_key_data);
|
||||
}
|
||||
else if(message_name == "text_event")
|
||||
{
|
||||
std::string text = message_in.getValue("text");
|
||||
std::string modifiers = message_in.getValue("modifiers");
|
||||
LLSD native_key_data = message_in.getValueLLSD("native_key_data");
|
||||
|
||||
unicodeInput(text, decodeModifiers(modifiers));
|
||||
unicodeInput(text, decodeModifiers(modifiers), native_key_data);
|
||||
}
|
||||
if(message_name == "edit_cut")
|
||||
{
|
||||
|
|
|
|||
|
|
@ -162,6 +162,7 @@ set(viewer_SOURCE_FILES
|
|||
llfloatercustomize.cpp
|
||||
llfloaterdaycycle.cpp
|
||||
llfloaterenvsettings.cpp
|
||||
llfloaterevent.cpp
|
||||
llfloaterfonttest.cpp
|
||||
llfloatergesture.cpp
|
||||
llfloatergodtools.cpp
|
||||
|
|
@ -183,7 +184,6 @@ set(viewer_SOURCE_FILES
|
|||
llfloatermediasettings.cpp
|
||||
llfloatermemleak.cpp
|
||||
llfloaternamedesc.cpp
|
||||
llfloaternearbymedia.cpp
|
||||
llfloaternotificationsconsole.cpp
|
||||
llfloateropenobject.cpp
|
||||
llfloaterparcel.cpp
|
||||
|
|
@ -301,7 +301,6 @@ set(viewer_SOURCE_FILES
|
|||
llpanelclassified.cpp
|
||||
llpanelcontents.cpp
|
||||
llpaneleditwearable.cpp
|
||||
llpanelevent.cpp
|
||||
llpanelface.cpp
|
||||
llpanelgroup.cpp
|
||||
llpanelgroupgeneral.cpp
|
||||
|
|
@ -324,6 +323,7 @@ set(viewer_SOURCE_FILES
|
|||
llpanelmediasettingspermissions.cpp
|
||||
llpanelmediasettingssecurity.cpp
|
||||
llpanelme.cpp
|
||||
llpanelnearbymedia.cpp
|
||||
llpanelobject.cpp
|
||||
llpanelobjectinventory.cpp
|
||||
llpaneloutfitsinventory.cpp
|
||||
|
|
@ -665,6 +665,7 @@ set(viewer_HEADER_FILES
|
|||
llfloatercustomize.h
|
||||
llfloaterdaycycle.h
|
||||
llfloaterenvsettings.h
|
||||
llfloaterevent.h
|
||||
llfloaterfonttest.h
|
||||
llfloatergesture.h
|
||||
llfloatergodtools.h
|
||||
|
|
@ -686,7 +687,6 @@ set(viewer_HEADER_FILES
|
|||
llfloatermediasettings.h
|
||||
llfloatermemleak.h
|
||||
llfloaternamedesc.h
|
||||
llfloaternearbymedia.h
|
||||
llfloaternotificationsconsole.h
|
||||
llfloateropenobject.h
|
||||
llfloaterparcel.h
|
||||
|
|
@ -799,7 +799,6 @@ set(viewer_HEADER_FILES
|
|||
llpanelclassified.h
|
||||
llpanelcontents.h
|
||||
llpaneleditwearable.h
|
||||
llpanelevent.h
|
||||
llpanelface.h
|
||||
llpanelgroup.h
|
||||
llpanelgroupgeneral.h
|
||||
|
|
@ -822,6 +821,7 @@ set(viewer_HEADER_FILES
|
|||
llpanelmediasettingspermissions.h
|
||||
llpanelmediasettingssecurity.h
|
||||
llpanelme.h
|
||||
llpanelnearbymedia.h
|
||||
llpanelobject.h
|
||||
llpanelobjectinventory.h
|
||||
llpaneloutfitsinventory.h
|
||||
|
|
@ -1218,18 +1218,18 @@ endif (WINDOWS)
|
|||
# Add the xui files. This is handy for searching for xui elements
|
||||
# from within the IDE.
|
||||
set(viewer_XUI_FILES
|
||||
skins/default/colors.xml
|
||||
skins/default/textures/textures.xml
|
||||
skins/base/colors.xml
|
||||
skins/base/textures/textures.xml
|
||||
|
||||
|
||||
|
||||
)
|
||||
file(GLOB DEFAULT_XUI_FILE_GLOB_LIST
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/skins/default/xui/en/*.xml)
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/skins/base/xui/en/*.xml)
|
||||
list(APPEND viewer_XUI_FILES ${DEFAULT_XUI_FILE_GLOB_LIST})
|
||||
|
||||
file(GLOB DEFAULT_WIDGET_FILE_GLOB_LIST
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/skins/default/xui/en/widgets/*.xml)
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/skins/base/xui/en/widgets/*.xml)
|
||||
list(APPEND viewer_XUI_FILES ${DEFAULT_WIDGET_FILE_GLOB_LIST})
|
||||
|
||||
file(GLOB SILVER_XUI_FILE_GLOB_LIST
|
||||
|
|
|
|||
|
|
@ -177,17 +177,6 @@
|
|||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>FirstStreamingMedia</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Enables FirstStreamingMedia warning dialog</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>FirstTeleport</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
|
|||
|
|
@ -2839,16 +2839,16 @@
|
|||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>HadFirstSuccessfulLogin</key>
|
||||
<key>FirstRunThisInstall</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Specifies whether you have successfully logged in at least once before</string>
|
||||
<string>Specifies that you have not run the viewer since you installed the latest update</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>FirstSelectedDisabledPopups</key>
|
||||
<map>
|
||||
|
|
@ -3629,7 +3629,7 @@
|
|||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string>http://lecs.viewer-sidebar.secondlife.com.s3.amazonaws.com/sidebar.html?p=[AUTH_TOKEN]&lang=[LANGUAGE]&channel=[CHANNEL]&version=[VERSION]&major=[VERSION_MAJOR]&minor=[VERSION_MINOR]</string>
|
||||
<string>https://viewer-sidebar.secondlife.com/sidebar.html?p=[AUTH_TOKEN]&lang=[LANGUAGE]&channel=[CHANNEL]&version=[VERSION]&major=[VERSION_MAJOR]&minor=[VERSION_MINOR]&firstlogin=[FIRST_LOGIN]</string>
|
||||
</map>
|
||||
<key>SearchURL</key>
|
||||
<map>
|
||||
|
|
@ -4600,6 +4600,50 @@
|
|||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>MediaShowOnOthers</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Whether or not to show media on other avatars</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>MediaShowOutsideParcel</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Whether or not to show media from outside the current parcel</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>MediaShowWithinParcel</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Whether or not to show media within the current parcel</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>MediaTentativeAutoPlay</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>This is a tentative flag that may be temporarily set off by the user, until she teleports</string>
|
||||
<key>Persist</key>
|
||||
<integer>0</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>MemoryLogFrequency</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -4655,6 +4699,17 @@
|
|||
<key>Value</key>
|
||||
<integer>410</integer>
|
||||
</map>
|
||||
<key>MePanelOpened</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Indicates that Me Panel was opened at least once after Viewer was installed</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<real>0</real>
|
||||
</map>
|
||||
<key>MigrateCacheDirectory</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -5066,7 +5121,9 @@
|
|||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Default width of buttons in the toast.
|
||||
Note if required width will be less then this one, a button will be reshaped to default size , otherwise to required</string>
|
||||
Notes:
|
||||
If required width will be less then this one, a button will be reshaped to default size , otherwise to required
|
||||
Change of this parameter will affect the layout of buttons in notification toast.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
|
|
@ -5325,7 +5382,7 @@
|
|||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>PerAccountSettingsFile</key>
|
||||
<map>
|
||||
|
|
@ -8432,7 +8489,7 @@
|
|||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>ShowTangentBasis</key>
|
||||
<map>
|
||||
|
|
@ -8478,6 +8535,17 @@
|
|||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>ShowVoiceVisualizersInCalls</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Enables in-world voice visualizers, voice gestures and lip-sync while in group or P2P calls.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>ShowVolumeSettingsPopup</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -9970,50 +10038,6 @@
|
|||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>15</integer>
|
||||
</map>
|
||||
<key>UIButtonImageLeftPadding</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Button Overlay Image Left Padding</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>4</integer>
|
||||
</map>
|
||||
<key>UIButtonImageRightPadding</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Button Overlay Image Right Padding</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>4</integer>
|
||||
</map>
|
||||
<key>UIButtonImageTopPadding</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Button Overlay Image Top Padding</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>2</integer>
|
||||
</map>
|
||||
<key>UIButtonImageBottomPadding</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Button Overlay Image Bottom Padding</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>2</integer>
|
||||
</map>
|
||||
<key>UploadBakedTexOld</key>
|
||||
<map>
|
||||
|
|
@ -10435,17 +10459,6 @@
|
|||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>VoiceDefaultInternalLevel</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Internal level of voice set by default. Is equivalent to 0.5 (from 0.0-1.0 range) external voice level (internal = 400 * external^2).</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>100</integer>
|
||||
</map>
|
||||
<key>VoiceEarLocation</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
|
|||
|
|
@ -956,6 +956,7 @@ void LLAgent::sendMessage()
|
|||
if (!mRegionp)
|
||||
{
|
||||
llerrs << "No region for agent yet!" << llendl;
|
||||
return;
|
||||
}
|
||||
gMessageSystem->sendMessage(mRegionp->getHost());
|
||||
}
|
||||
|
|
@ -4482,7 +4483,9 @@ void LLAgent::setCameraPosAndFocusGlobal(const LLVector3d& camera_pos, const LLV
|
|||
{
|
||||
const F64 ANIM_METERS_PER_SECOND = 10.0;
|
||||
const F64 MIN_ANIM_SECONDS = 0.5;
|
||||
const F64 MAX_ANIM_SECONDS = 10.0;
|
||||
F64 anim_duration = llmax( MIN_ANIM_SECONDS, sqrt(focus_delta_squared) / ANIM_METERS_PER_SECOND );
|
||||
anim_duration = llmin( anim_duration, MAX_ANIM_SECONDS );
|
||||
setAnimationDuration( (F32)anim_duration );
|
||||
}
|
||||
|
||||
|
|
@ -5024,9 +5027,9 @@ void LLAgent::buildFullnameAndTitle(std::string& name) const
|
|||
}
|
||||
}
|
||||
|
||||
BOOL LLAgent::isInGroup(const LLUUID& group_id) const
|
||||
BOOL LLAgent::isInGroup(const LLUUID& group_id, BOOL ignore_god_mode /* FALSE */) const
|
||||
{
|
||||
if (isGodlike())
|
||||
if (!ignore_god_mode && isGodlike())
|
||||
return true;
|
||||
|
||||
S32 count = mGroups.count();
|
||||
|
|
|
|||
|
|
@ -983,7 +983,7 @@ private:
|
|||
//--------------------------------------------------------------------
|
||||
public:
|
||||
// Checks against all groups in the entire agent group list.
|
||||
BOOL isInGroup(const LLUUID& group_id) const;
|
||||
BOOL isInGroup(const LLUUID& group_id, BOOL ingnore_God_mod = FALSE) const;
|
||||
protected:
|
||||
// Only used for building titles.
|
||||
BOOL isGroupMember() const { return !mGroupID.isNull(); }
|
||||
|
|
|
|||
|
|
@ -149,11 +149,17 @@ BOOL LLAgentUI::buildLocationString(std::string& str, ELocationFormat fmt,const
|
|||
sim_access_string.c_str());
|
||||
break;
|
||||
case LOCATION_FORMAT_NO_MATURITY:
|
||||
case LOCATION_FORMAT_FULL:
|
||||
buffer = llformat("%s (%d, %d, %d)",
|
||||
region_name.c_str(),
|
||||
pos_x, pos_y, pos_z);
|
||||
break;
|
||||
case LOCATION_FORMAT_FULL:
|
||||
buffer = llformat("%s (%d, %d, %d)%s%s",
|
||||
region_name.c_str(),
|
||||
pos_x, pos_y, pos_z,
|
||||
sim_access_string.empty() ? "" : " - ",
|
||||
sim_access_string.c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -299,6 +299,10 @@ void LLAgentWearables::addWearableToAgentInventoryCallback::fire(const LLUUID& i
|
|||
{
|
||||
gAgentWearables.makeNewOutfitDone(mType, mIndex);
|
||||
}
|
||||
if (mTodo & CALL_WEARITEM)
|
||||
{
|
||||
LLAppearanceManager::instance().addCOFItemLink(inv_item, true);
|
||||
}
|
||||
}
|
||||
|
||||
void LLAgentWearables::addWearabletoAgentInventoryDone(const S32 type,
|
||||
|
|
@ -310,21 +314,24 @@ void LLAgentWearables::addWearabletoAgentInventoryDone(const S32 type,
|
|||
return;
|
||||
|
||||
LLUUID old_item_id = getWearableItemID((EWearableType)type,index);
|
||||
|
||||
if (wearable)
|
||||
{
|
||||
wearable->setItemID(item_id);
|
||||
|
||||
if (old_item_id.notNull())
|
||||
{
|
||||
gInventory.addChangedMask(LLInventoryObserver::LABEL, old_item_id);
|
||||
setWearable((EWearableType)type,index,wearable);
|
||||
}
|
||||
else
|
||||
{
|
||||
pushWearable((EWearableType)type,wearable);
|
||||
}
|
||||
}
|
||||
|
||||
if (old_item_id.notNull())
|
||||
{
|
||||
gInventory.addChangedMask(LLInventoryObserver::LABEL, old_item_id);
|
||||
setWearable((EWearableType)type,index,wearable);
|
||||
}
|
||||
else
|
||||
{
|
||||
pushWearable((EWearableType)type,wearable);
|
||||
}
|
||||
gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
|
||||
|
||||
LLViewerInventoryItem* item = gInventory.getItem(item_id);
|
||||
if (item && wearable)
|
||||
{
|
||||
|
|
@ -507,7 +514,7 @@ void LLAgentWearables::saveWearableAs(const EWearableType type,
|
|||
type,
|
||||
index,
|
||||
new_wearable,
|
||||
addWearableToAgentInventoryCallback::CALL_UPDATE);
|
||||
addWearableToAgentInventoryCallback::CALL_WEARITEM);
|
||||
LLUUID category_id;
|
||||
if (save_in_lost_and_found)
|
||||
{
|
||||
|
|
@ -761,6 +768,8 @@ void LLAgentWearables::wearableUpdated(LLWearable *wearable)
|
|||
wearable->refreshName();
|
||||
wearable->setLabelUpdated();
|
||||
|
||||
wearable->pullCrossWearableValues();
|
||||
|
||||
// Hack pt 2. If the wearable we just loaded has definition version 24,
|
||||
// then force a re-save of this wearable after slamming the version number to 22.
|
||||
// This number was incorrectly incremented for internal builds before release, and
|
||||
|
|
@ -927,13 +936,6 @@ void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgs
|
|||
if (mInitialWearablesUpdateReceived)
|
||||
return;
|
||||
mInitialWearablesUpdateReceived = true;
|
||||
|
||||
// If this is the very first time the user has logged into viewer2+ (from a legacy viewer, or new account)
|
||||
// then auto-populate outfits from the library into the My Outfits folder.
|
||||
if (LLInventoryModel::getIsFirstTimeInViewer2() || gSavedSettings.getBOOL("MyOutfitsAutofill"))
|
||||
{
|
||||
gAgentWearables.populateMyOutfitsFolder();
|
||||
}
|
||||
|
||||
LLUUID agent_id;
|
||||
gMessageSystem->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id);
|
||||
|
|
@ -1292,25 +1294,29 @@ void LLAgentWearables::makeNewOutfit(const std::string& new_folder_name,
|
|||
j,
|
||||
new_wearable,
|
||||
todo);
|
||||
if (isWearableCopyable((EWearableType)type, j))
|
||||
llassert(item);
|
||||
if (item)
|
||||
{
|
||||
copy_inventory_item(
|
||||
gAgent.getID(),
|
||||
item->getPermissions().getOwner(),
|
||||
item->getUUID(),
|
||||
folder_id,
|
||||
new_name,
|
||||
cb);
|
||||
}
|
||||
else
|
||||
{
|
||||
move_inventory_item(
|
||||
gAgent.getID(),
|
||||
gAgent.getSessionID(),
|
||||
item->getUUID(),
|
||||
folder_id,
|
||||
new_name,
|
||||
cb);
|
||||
if (isWearableCopyable((EWearableType)type, j))
|
||||
{
|
||||
copy_inventory_item(
|
||||
gAgent.getID(),
|
||||
item->getPermissions().getOwner(),
|
||||
item->getUUID(),
|
||||
folder_id,
|
||||
new_name,
|
||||
cb);
|
||||
}
|
||||
else
|
||||
{
|
||||
move_inventory_item(
|
||||
gAgent.getID(),
|
||||
gAgent.getSessionID(),
|
||||
item->getUUID(),
|
||||
folder_id,
|
||||
new_name,
|
||||
cb);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1417,7 +1423,7 @@ LLUUID LLAgentWearables::makeNewOutfitLinks(const std::string& new_folder_name)
|
|||
new_folder_name);
|
||||
|
||||
LLPointer<LLInventoryCallback> cb = new LLShowCreatedOutfit(folder_id);
|
||||
LLAppearanceManager::instance().shallowCopyCategory(LLAppearanceManager::instance().getCOF(),folder_id, cb);
|
||||
LLAppearanceManager::instance().shallowCopyCategoryContents(LLAppearanceManager::instance().getCOF(),folder_id, cb);
|
||||
LLAppearanceManager::instance().createBaseOutfitLink(folder_id, cb);
|
||||
|
||||
return folder_id;
|
||||
|
|
@ -1599,32 +1605,35 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
|
|||
LLWearable* new_wearable = wearables[i];
|
||||
LLPointer<LLInventoryItem> new_item = items[i];
|
||||
|
||||
const EWearableType type = new_wearable->getType();
|
||||
wearables_to_remove[type] = FALSE;
|
||||
|
||||
// MULTI_WEARABLE: using 0th
|
||||
LLWearable* old_wearable = getWearable(type, 0);
|
||||
if (old_wearable)
|
||||
{
|
||||
const LLUUID& old_item_id = getWearableItemID(type, 0);
|
||||
if ((old_wearable->getAssetID() == new_wearable->getAssetID()) &&
|
||||
(old_item_id == new_item->getUUID()))
|
||||
{
|
||||
lldebugs << "No change to wearable asset and item: " << LLWearableDictionary::getInstance()->getWearableEntry(type) << llendl;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Assumes existing wearables are not dirty.
|
||||
if (old_wearable->isDirty())
|
||||
{
|
||||
llassert(0);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
llassert(new_wearable);
|
||||
if (new_wearable)
|
||||
{
|
||||
const EWearableType type = new_wearable->getType();
|
||||
wearables_to_remove[type] = FALSE;
|
||||
|
||||
// MULTI_WEARABLE: using 0th
|
||||
LLWearable* old_wearable = getWearable(type, 0);
|
||||
if (old_wearable)
|
||||
{
|
||||
const LLUUID& old_item_id = getWearableItemID(type, 0);
|
||||
if ((old_wearable->getAssetID() == new_wearable->getAssetID()) &&
|
||||
(old_item_id == new_item->getUUID()))
|
||||
{
|
||||
lldebugs << "No change to wearable asset and item: " << LLWearableDictionary::getInstance()->getWearableEntry(type) << llendl;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Assumes existing wearables are not dirty.
|
||||
if (old_wearable->isDirty())
|
||||
{
|
||||
llassert(0);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
new_wearable->setItemID(new_item->getUUID());
|
||||
setWearable(type,0,new_wearable);
|
||||
setWearable(type,0,new_wearable);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<LLWearable*> wearables_being_removed;
|
||||
|
|
@ -1664,6 +1673,7 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
|
|||
if (mAvatarObject)
|
||||
{
|
||||
mAvatarObject->updateVisualParams();
|
||||
mAvatarObject->invalidateAll();
|
||||
}
|
||||
|
||||
// Start rendering & update the server
|
||||
|
|
@ -2143,6 +2153,8 @@ void LLAgentWearables::updateServer()
|
|||
|
||||
void LLAgentWearables::populateMyOutfitsFolder(void)
|
||||
{
|
||||
llinfos << "starting outfit populate" << llendl;
|
||||
|
||||
LLLibraryOutfitsFetch* outfits = new LLLibraryOutfitsFetch();
|
||||
|
||||
// Get the complete information on the items in the inventory and
|
||||
|
|
@ -2334,7 +2346,7 @@ void LLLibraryOutfitsFetch::libraryDone(void)
|
|||
LLUUID folder_id = gInventory.createNewCategory(mImportedClothingID,
|
||||
LLFolderType::FT_NONE,
|
||||
iter->second);
|
||||
LLAppearanceManager::getInstance()->shallowCopyCategory(iter->first, folder_id, copy_waiter);
|
||||
LLAppearanceManager::getInstance()->shallowCopyCategoryContents(iter->first, folder_id, copy_waiter);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -244,7 +244,8 @@ private:
|
|||
CALL_UPDATE = 1,
|
||||
CALL_RECOVERDONE = 2,
|
||||
CALL_CREATESTANDARDDONE = 4,
|
||||
CALL_MAKENEWOUTFITDONE = 8
|
||||
CALL_MAKENEWOUTFITDONE = 8,
|
||||
CALL_WEARITEM = 16
|
||||
};
|
||||
|
||||
// MULTI-WEARABLE: index is an EWearableType - more confusing usage.
|
||||
|
|
|
|||
|
|
@ -48,6 +48,31 @@
|
|||
#include "llviewerregion.h"
|
||||
#include "llwearablelist.h"
|
||||
|
||||
LLUUID findDescendentCategoryIDByName(const LLUUID& parent_id,const std::string& name)
|
||||
{
|
||||
LLInventoryModel::cat_array_t cat_array;
|
||||
LLInventoryModel::item_array_t item_array;
|
||||
LLNameCategoryCollector has_name(name);
|
||||
gInventory.collectDescendentsIf(parent_id,
|
||||
cat_array,
|
||||
item_array,
|
||||
LLInventoryModel::EXCLUDE_TRASH,
|
||||
has_name);
|
||||
if (0 == cat_array.count())
|
||||
return LLUUID();
|
||||
else
|
||||
{
|
||||
LLViewerInventoryCategory *cat = cat_array.get(0);
|
||||
if (cat)
|
||||
return cat->getUUID();
|
||||
else
|
||||
{
|
||||
llwarns << "null cat" << llendl;
|
||||
return LLUUID();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// support for secondlife:///app/appearance SLapps
|
||||
class LLAppearanceHandler : public LLCommandHandler
|
||||
{
|
||||
|
|
@ -88,6 +113,8 @@ public:
|
|||
protected:
|
||||
~LLWearInventoryCategoryCallback()
|
||||
{
|
||||
llinfos << "done all inventory callbacks" << llendl;
|
||||
|
||||
// Is the destructor called by ordinary dereference, or because the app's shutting down?
|
||||
// If the inventory callback manager goes away, we're shutting down, no longer want the callback.
|
||||
if( LLInventoryCallbackManager::is_instantiated() )
|
||||
|
|
@ -125,12 +152,15 @@ protected:
|
|||
|
||||
void LLOutfitObserver::done()
|
||||
{
|
||||
llinfos << "done 2nd stage fetch" << llendl;
|
||||
gInventory.removeObserver(this);
|
||||
doOnIdle(boost::bind(&LLOutfitObserver::doWearCategory,this));
|
||||
}
|
||||
|
||||
void LLOutfitObserver::doWearCategory()
|
||||
{
|
||||
llinfos << "starting" << llendl;
|
||||
|
||||
// We now have an outfit ready to be copied to agent inventory. Do
|
||||
// it, and wear that outfit normally.
|
||||
if(mCopyItems)
|
||||
|
|
@ -219,6 +249,8 @@ void LLOutfitFetch::done()
|
|||
// What we do here is get the complete information on the items in
|
||||
// the library, and set up an observer that will wait for that to
|
||||
// happen.
|
||||
llinfos << "done first stage fetch" << llendl;
|
||||
|
||||
LLInventoryModel::cat_array_t cat_array;
|
||||
LLInventoryModel::item_array_t item_array;
|
||||
gInventory.collectDescendents(mCompleteFolders.front(),
|
||||
|
|
@ -279,6 +311,8 @@ public:
|
|||
|
||||
virtual ~LLUpdateAppearanceOnDestroy()
|
||||
{
|
||||
llinfos << "done update appearance on destroy" << llendl;
|
||||
|
||||
if (!LLApp::isExiting())
|
||||
{
|
||||
LLAppearanceManager::instance().updateAppearanceFromCOF();
|
||||
|
|
@ -287,6 +321,7 @@ public:
|
|||
|
||||
/* virtual */ void fire(const LLUUID& inv_item)
|
||||
{
|
||||
llinfos << "callback fired" << llendl;
|
||||
mFireCount++;
|
||||
}
|
||||
private:
|
||||
|
|
@ -321,7 +356,7 @@ public:
|
|||
~LLWearableHoldingPattern();
|
||||
|
||||
bool pollCompletion();
|
||||
bool isDone();
|
||||
bool isFetchCompleted();
|
||||
bool isTimedOut();
|
||||
|
||||
typedef std::list<LLFoundData> found_list_t;
|
||||
|
|
@ -330,10 +365,12 @@ public:
|
|||
LLInventoryModel::item_array_t mGestItems;
|
||||
S32 mResolved;
|
||||
LLTimer mWaitTime;
|
||||
bool mFired;
|
||||
};
|
||||
|
||||
LLWearableHoldingPattern::LLWearableHoldingPattern():
|
||||
mResolved(0)
|
||||
mResolved(0),
|
||||
mFired(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -341,31 +378,34 @@ LLWearableHoldingPattern::~LLWearableHoldingPattern()
|
|||
{
|
||||
}
|
||||
|
||||
bool LLWearableHoldingPattern::isDone()
|
||||
bool LLWearableHoldingPattern::isFetchCompleted()
|
||||
{
|
||||
if (mResolved >= (S32)mFoundList.size())
|
||||
return true; // have everything we were waiting for
|
||||
else if (isTimedOut())
|
||||
{
|
||||
llwarns << "Exceeded max wait time, updating appearance based on what has arrived" << llendl;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
return (mResolved >= (S32)mFoundList.size()); // have everything we were waiting for?
|
||||
}
|
||||
|
||||
bool LLWearableHoldingPattern::isTimedOut()
|
||||
{
|
||||
static F32 max_wait_time = 15.0; // give up if wearable fetches haven't completed in max_wait_time seconds.
|
||||
static F32 max_wait_time = 20.0; // give up if wearable fetches haven't completed in max_wait_time seconds.
|
||||
return mWaitTime.getElapsedTimeF32() > max_wait_time;
|
||||
}
|
||||
|
||||
bool LLWearableHoldingPattern::pollCompletion()
|
||||
{
|
||||
bool done = isDone();
|
||||
llinfos << "polling, done status: " << done << " elapsed " << mWaitTime.getElapsedTimeF32() << llendl;
|
||||
bool completed = isFetchCompleted();
|
||||
bool timed_out = isTimedOut();
|
||||
bool done = completed || timed_out;
|
||||
|
||||
llinfos << "polling, done status: " << completed << " timed out? " << timed_out << " elapsed " << mWaitTime.getElapsedTimeF32() << llendl;
|
||||
|
||||
if (done)
|
||||
{
|
||||
mFired = true;
|
||||
|
||||
if (timed_out)
|
||||
{
|
||||
llwarns << "Exceeded max wait time for wearables, updating appearance based on what has arrived" << llendl;
|
||||
}
|
||||
|
||||
// Activate all gestures in this folder
|
||||
if (mGestItems.count() > 0)
|
||||
{
|
||||
|
|
@ -397,7 +437,11 @@ bool LLWearableHoldingPattern::pollCompletion()
|
|||
LLAgentWearables::userUpdateAttachments(mObjItems);
|
||||
}
|
||||
|
||||
delete this;
|
||||
if (completed)
|
||||
{
|
||||
// Only safe to delete if all wearable callbacks completed.
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
return done;
|
||||
}
|
||||
|
|
@ -432,7 +476,11 @@ static void removeDuplicateItems(LLInventoryModel::item_array_t& items)
|
|||
static void onWearableAssetFetch(LLWearable* wearable, void* data)
|
||||
{
|
||||
LLWearableHoldingPattern* holder = (LLWearableHoldingPattern*)data;
|
||||
|
||||
if (holder->mFired)
|
||||
{
|
||||
llwarns << "called after holder fired" << llendl;
|
||||
}
|
||||
|
||||
if(wearable)
|
||||
{
|
||||
for (LLWearableHoldingPattern::found_list_t::iterator iter = holder->mFoundList.begin();
|
||||
|
|
@ -506,8 +554,32 @@ void LLAppearanceManager::changeOutfit(bool proceed, const LLUUID& category, boo
|
|||
LLAppearanceManager::instance().updateCOF(category,append);
|
||||
}
|
||||
|
||||
// Create a copy of src_id + contents as a subfolder of dst_id.
|
||||
void LLAppearanceManager::shallowCopyCategory(const LLUUID& src_id, const LLUUID& dst_id,
|
||||
LLPointer<LLInventoryCallback> cb)
|
||||
{
|
||||
LLInventoryCategory *src_cat = gInventory.getCategory(src_id);
|
||||
if (!src_cat)
|
||||
{
|
||||
llwarns << "folder not found for src " << src_id.asString() << llendl;
|
||||
return;
|
||||
}
|
||||
LLUUID parent_id = dst_id;
|
||||
if(parent_id.isNull())
|
||||
{
|
||||
parent_id = gInventory.getRootFolderID();
|
||||
}
|
||||
LLUUID subfolder_id = gInventory.createNewCategory( parent_id,
|
||||
LLFolderType::FT_NONE,
|
||||
src_cat->getName());
|
||||
shallowCopyCategoryContents(src_id, subfolder_id, cb);
|
||||
|
||||
gInventory.notifyObservers();
|
||||
}
|
||||
|
||||
// Copy contents of src_id to dst_id.
|
||||
void LLAppearanceManager::shallowCopyCategoryContents(const LLUUID& src_id, const LLUUID& dst_id,
|
||||
LLPointer<LLInventoryCallback> cb)
|
||||
{
|
||||
LLInventoryModel::cat_array_t cats;
|
||||
LLInventoryModel::item_array_t items;
|
||||
|
|
@ -604,6 +676,11 @@ void LLAppearanceManager::filterWearableItems(
|
|||
if (!item->isWearableType())
|
||||
continue;
|
||||
EWearableType type = item->getWearableType();
|
||||
if(type < 0 || type >= WT_COUNT)
|
||||
{
|
||||
LL_WARNS("Appearance") << "Invalid wearable type. Inventory type does not match wearable flag bitfield." << LL_ENDL;
|
||||
continue;
|
||||
}
|
||||
items_by_type[type].push_back(item);
|
||||
}
|
||||
|
||||
|
|
@ -641,6 +718,8 @@ void LLAppearanceManager::linkAll(const LLUUID& category,
|
|||
|
||||
void LLAppearanceManager::updateCOF(const LLUUID& category, bool append)
|
||||
{
|
||||
llinfos << "starting" << llendl;
|
||||
|
||||
const LLUUID cof = getCOF();
|
||||
|
||||
// Deactivate currently active gestures in the COF, if replacing outfit
|
||||
|
|
@ -698,6 +777,7 @@ void LLAppearanceManager::updateCOF(const LLUUID& category, bool append)
|
|||
gInventory.notifyObservers();
|
||||
|
||||
// Create links to new COF contents.
|
||||
llinfos << "creating LLUpdateAppearanceOnDestroy" << llendl;
|
||||
LLPointer<LLInventoryCallback> link_waiter = new LLUpdateAppearanceOnDestroy;
|
||||
|
||||
linkAll(cof, body_items, link_waiter);
|
||||
|
|
@ -710,6 +790,7 @@ void LLAppearanceManager::updateCOF(const LLUUID& category, bool append)
|
|||
{
|
||||
createBaseOutfitLink(category, link_waiter);
|
||||
}
|
||||
llinfos << "waiting for LLUpdateAppearanceOnDestroy" << llendl;
|
||||
}
|
||||
|
||||
void LLAppearanceManager::updatePanelOutfitName(const std::string& name)
|
||||
|
|
@ -781,6 +862,8 @@ void LLAppearanceManager::updateAppearanceFromCOF()
|
|||
{
|
||||
// update dirty flag to see if the state of the COF matches
|
||||
// the saved outfit stored as a folder link
|
||||
llinfos << "starting" << llendl;
|
||||
|
||||
updateIsDirty();
|
||||
|
||||
dumpCat(getCOF(),"COF, start");
|
||||
|
|
@ -911,8 +994,9 @@ void LLAppearanceManager::wearInventoryCategory(LLInventoryCategory* category, b
|
|||
{
|
||||
if(!category) return;
|
||||
|
||||
lldebugs << "wearInventoryCategory( " << category->getName()
|
||||
llinfos << "wearInventoryCategory( " << category->getName()
|
||||
<< " )" << llendl;
|
||||
|
||||
// What we do here is get the complete information on the items in
|
||||
// the inventory, and set up an observer that will wait for that to
|
||||
// happen.
|
||||
|
|
@ -941,7 +1025,8 @@ void LLAppearanceManager::wearInventoryCategoryOnAvatar( LLInventoryCategory* ca
|
|||
// this up front to avoid having to deal with the case of multiple
|
||||
// wearables being dirty.
|
||||
if(!category) return;
|
||||
lldebugs << "wearInventoryCategoryOnAvatar( " << category->getName()
|
||||
|
||||
llinfos << "wearInventoryCategoryOnAvatar( " << category->getName()
|
||||
<< " )" << llendl;
|
||||
|
||||
if( gFloaterCustomize )
|
||||
|
|
@ -1218,6 +1303,23 @@ void LLAppearanceManager::updateIsDirty()
|
|||
}
|
||||
}
|
||||
|
||||
void LLAppearanceManager::onFirstFullyVisible()
|
||||
{
|
||||
// If this is the very first time the user has logged into viewer2+ (from a legacy viewer, or new account)
|
||||
// then auto-populate outfits from the library into the My Outfits folder.
|
||||
|
||||
llinfos << "avatar fully visible" << llendl;
|
||||
|
||||
static bool check_populate_my_outfits = true;
|
||||
if (check_populate_my_outfits &&
|
||||
(LLInventoryModel::getIsFirstTimeInViewer2()
|
||||
|| gSavedSettings.getBOOL("MyOutfitsAutofill")))
|
||||
{
|
||||
gAgentWearables.populateMyOutfitsFolder();
|
||||
}
|
||||
check_populate_my_outfits = false;
|
||||
}
|
||||
|
||||
//#define DUMP_CAT_VERBOSE
|
||||
|
||||
void LLAppearanceManager::dumpCat(const LLUUID& cat_id, const std::string& msg)
|
||||
|
|
@ -1340,6 +1442,11 @@ BOOL LLAppearanceManager::getIsInCOF(const LLUUID& obj_id) const
|
|||
BOOL LLAppearanceManager::getIsProtectedCOFItem(const LLUUID& obj_id) const
|
||||
{
|
||||
if (!getIsInCOF(obj_id)) return FALSE;
|
||||
|
||||
// For now, don't allow direct deletion from the COF. Instead, force users
|
||||
// to choose "Detach" or "Take Off".
|
||||
return TRUE;
|
||||
/*
|
||||
const LLInventoryObject *obj = gInventory.getObject(obj_id);
|
||||
if (!obj) return FALSE;
|
||||
|
||||
|
|
@ -1350,4 +1457,5 @@ BOOL LLAppearanceManager::getIsProtectedCOFItem(const LLUUID& obj_id) const
|
|||
if (obj->getActualType() == LLAssetType::AT_LINK_FOLDER) return TRUE;
|
||||
|
||||
return FALSE;
|
||||
*/
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@
|
|||
|
||||
#include "llsingleton.h"
|
||||
#include "llinventorymodel.h"
|
||||
#include "llinventoryobserver.h"
|
||||
#include "llviewerinventory.h"
|
||||
#include "llcallbacklist.h"
|
||||
|
||||
class LLWearable;
|
||||
|
|
@ -54,10 +56,14 @@ public:
|
|||
void wearOutfitByName(const std::string& name);
|
||||
void changeOutfit(bool proceed, const LLUUID& category, bool append);
|
||||
|
||||
// Copy all items in a category.
|
||||
// Copy all items and the src category itself.
|
||||
void shallowCopyCategory(const LLUUID& src_id, const LLUUID& dst_id,
|
||||
LLPointer<LLInventoryCallback> cb);
|
||||
|
||||
// Copy all items in a category.
|
||||
void shallowCopyCategoryContents(const LLUUID& src_id, const LLUUID& dst_id,
|
||||
LLPointer<LLInventoryCallback> cb);
|
||||
|
||||
// Find the Current Outfit folder.
|
||||
const LLUUID getCOF() const;
|
||||
|
||||
|
|
@ -107,6 +113,9 @@ public:
|
|||
// should only be necessary to do on initial login.
|
||||
void updateIsDirty();
|
||||
|
||||
// Called when self avatar is first fully visible.
|
||||
void onFirstFullyVisible();
|
||||
|
||||
protected:
|
||||
LLAppearanceManager();
|
||||
~LLAppearanceManager();
|
||||
|
|
@ -144,6 +153,8 @@ public:
|
|||
|
||||
#define SUPPORT_ENSEMBLES 0
|
||||
|
||||
LLUUID findDescendentCategoryIDByName(const LLUUID& parent_id,const std::string& name);
|
||||
|
||||
// Shim class and template function to allow arbitrary boost::bind
|
||||
// expressions to be run as one-time idle callbacks.
|
||||
template <typename T>
|
||||
|
|
@ -212,4 +223,103 @@ void doOnIdleRepeating(T callable)
|
|||
gIdleCallbacks.addFunction(&OnIdleCallbackRepeating<T>::onIdle,cb_functor);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
class CallAfterCategoryFetchStage2: public LLInventoryFetchObserver
|
||||
{
|
||||
public:
|
||||
CallAfterCategoryFetchStage2(T callable):
|
||||
mCallable(callable)
|
||||
{
|
||||
}
|
||||
~CallAfterCategoryFetchStage2()
|
||||
{
|
||||
}
|
||||
virtual void done()
|
||||
{
|
||||
gInventory.removeObserver(this);
|
||||
doOnIdle(mCallable);
|
||||
delete this;
|
||||
}
|
||||
protected:
|
||||
T mCallable;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class CallAfterCategoryFetchStage1: public LLInventoryFetchDescendentsObserver
|
||||
{
|
||||
public:
|
||||
CallAfterCategoryFetchStage1(T callable):
|
||||
mCallable(callable)
|
||||
{
|
||||
}
|
||||
~CallAfterCategoryFetchStage1()
|
||||
{
|
||||
}
|
||||
virtual void done()
|
||||
{
|
||||
// What we do here is get the complete information on the items in
|
||||
// the library, and set up an observer that will wait for that to
|
||||
// happen.
|
||||
LLInventoryModel::cat_array_t cat_array;
|
||||
LLInventoryModel::item_array_t item_array;
|
||||
gInventory.collectDescendents(mCompleteFolders.front(),
|
||||
cat_array,
|
||||
item_array,
|
||||
LLInventoryModel::EXCLUDE_TRASH);
|
||||
S32 count = item_array.count();
|
||||
if(!count)
|
||||
{
|
||||
llwarns << "Nothing fetched in category " << mCompleteFolders.front()
|
||||
<< llendl;
|
||||
//dec_busy_count();
|
||||
gInventory.removeObserver(this);
|
||||
delete this;
|
||||
return;
|
||||
}
|
||||
|
||||
CallAfterCategoryFetchStage2<T> *stage2 = new CallAfterCategoryFetchStage2<T>(mCallable);
|
||||
LLInventoryFetchObserver::item_ref_t ids;
|
||||
for(S32 i = 0; i < count; ++i)
|
||||
{
|
||||
ids.push_back(item_array.get(i)->getUUID());
|
||||
}
|
||||
|
||||
gInventory.removeObserver(this);
|
||||
|
||||
// do the fetch
|
||||
stage2->fetchItems(ids);
|
||||
if(stage2->isEverythingComplete())
|
||||
{
|
||||
// everything is already here - call done.
|
||||
stage2->done();
|
||||
}
|
||||
else
|
||||
{
|
||||
// it's all on it's way - add an observer, and the inventory
|
||||
// will call done for us when everything is here.
|
||||
gInventory.addObserver(stage2);
|
||||
}
|
||||
delete this;
|
||||
}
|
||||
protected:
|
||||
T mCallable;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
void callAfterCategoryFetch(const LLUUID& cat_id, T callable)
|
||||
{
|
||||
CallAfterCategoryFetchStage1<T> *stage1 = new CallAfterCategoryFetchStage1<T>(callable);
|
||||
LLInventoryFetchDescendentsObserver::folder_ref_t folders;
|
||||
folders.push_back(cat_id);
|
||||
stage1->fetchDescendents(folders);
|
||||
if (stage1->isEverythingComplete())
|
||||
{
|
||||
stage1->done();
|
||||
}
|
||||
else
|
||||
{
|
||||
gInventory.addObserver(stage1);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@
|
|||
#include "lluictrlfactory.h"
|
||||
#include "lltexteditor.h"
|
||||
#include "llerrorcontrol.h"
|
||||
#include "lleventtimer.h"
|
||||
#include "llviewertexturelist.h"
|
||||
#include "llgroupmgr.h"
|
||||
#include "llagent.h"
|
||||
|
|
@ -586,7 +587,7 @@ bool LLAppViewer::init()
|
|||
gDirUtilp->initAppDirs("SecondLife");
|
||||
// set skin search path to default, will be overridden later
|
||||
// this allows simple skinned file lookups to work
|
||||
gDirUtilp->setSkinFolder("default");
|
||||
gDirUtilp->setSkinFolder("base");
|
||||
|
||||
initLogging();
|
||||
|
||||
|
|
@ -1332,9 +1333,6 @@ bool LLAppViewer::cleanup()
|
|||
|
||||
llinfos << "Cache files removed" << llendflush;
|
||||
|
||||
|
||||
cleanup_menus();
|
||||
|
||||
// Wait for any pending VFS IO
|
||||
while (1)
|
||||
{
|
||||
|
|
@ -1653,7 +1651,7 @@ bool LLAppViewer::initThreads()
|
|||
// Image decoding
|
||||
LLAppViewer::sImageDecodeThread = new LLImageDecodeThread(enable_threads && true);
|
||||
LLAppViewer::sTextureCache = new LLTextureCache(enable_threads && true);
|
||||
LLAppViewer::sTextureFetch = new LLTextureFetch(LLAppViewer::getTextureCache(), sImageDecodeThread, enable_threads && false);
|
||||
LLAppViewer::sTextureFetch = new LLTextureFetch(LLAppViewer::getTextureCache(), sImageDecodeThread, enable_threads && true);
|
||||
LLImage::initClass();
|
||||
|
||||
if (LLFastTimer::sLog || LLFastTimer::sMetricLog)
|
||||
|
|
@ -1907,7 +1905,6 @@ bool LLAppViewer::initConfiguration()
|
|||
// LLFirstUse::addConfigVariable("FirstSandbox");
|
||||
// LLFirstUse::addConfigVariable("FirstFlexible");
|
||||
// LLFirstUse::addConfigVariable("FirstDebugMenus");
|
||||
// LLFirstUse::addConfigVariable("FirstStreamingMedia");
|
||||
// LLFirstUse::addConfigVariable("FirstSculptedPrim");
|
||||
// LLFirstUse::addConfigVariable("FirstVoice");
|
||||
// LLFirstUse::addConfigVariable("FirstMedia");
|
||||
|
|
@ -2114,7 +2111,7 @@ bool LLAppViewer::initConfiguration()
|
|||
{
|
||||
// hack to force the skin to default.
|
||||
//gDirUtilp->setSkinFolder(skinfolder->getValue().asString());
|
||||
gDirUtilp->setSkinFolder("default");
|
||||
gDirUtilp->setSkinFolder("base");
|
||||
}
|
||||
|
||||
mYieldTime = gSavedSettings.getS32("YieldTime");
|
||||
|
|
@ -2319,9 +2316,6 @@ bool LLAppViewer::initWindow()
|
|||
// store setting in a global for easy access and modification
|
||||
gNoRender = gSavedSettings.getBOOL("DisableRendering");
|
||||
|
||||
// Hide the splash screen
|
||||
LLSplashScreen::hide();
|
||||
|
||||
// always start windowed
|
||||
BOOL ignorePixelDepth = gSavedSettings.getBOOL("IgnorePixelDepth");
|
||||
gViewerWindow = new LLViewerWindow(gWindowTitle,
|
||||
|
|
@ -2565,7 +2559,7 @@ void LLAppViewer::handleViewerCrash()
|
|||
gDebugInfo["StartupState"] = LLStartUp::getStartupStateString();
|
||||
gDebugInfo["RAMInfo"]["Allocated"] = (LLSD::Integer) LLMemory::getCurrentRSS() >> 10;
|
||||
gDebugInfo["FirstLogin"] = (LLSD::Boolean) gAgent.isFirstLogin();
|
||||
gDebugInfo["HadFirstSuccessfulLogin"] = gSavedSettings.getBOOL("HadFirstSuccessfulLogin");
|
||||
gDebugInfo["FirstRunThisInstall"] = gSavedSettings.getBOOL("FirstRunThisInstall");
|
||||
|
||||
if(gLogoutInProgress)
|
||||
{
|
||||
|
|
@ -2964,7 +2958,7 @@ bool LLAppViewer::initCache()
|
|||
// Purge cache if it belongs to an old version
|
||||
else
|
||||
{
|
||||
static const S32 cache_version = 5;
|
||||
static const S32 cache_version = 6;
|
||||
if (gSavedSettings.getS32("LocalCacheVersion") != cache_version)
|
||||
{
|
||||
mPurgeCache = true;
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@
|
|||
#include "llallocator.h"
|
||||
#include "llcontrol.h"
|
||||
#include "llsys.h" // for LLOSInfo
|
||||
#include "lltimer.h"
|
||||
|
||||
class LLCommandLineParser;
|
||||
class LLFrameTimer;
|
||||
|
|
|
|||
|
|
@ -181,7 +181,12 @@ void LLAvatarActions::startIM(const LLUUID& id)
|
|||
return;
|
||||
|
||||
std::string name;
|
||||
gCacheName->getFullName(id, name);
|
||||
if (!gCacheName->getFullName(id, name))
|
||||
{
|
||||
gCacheName->get(id, FALSE, boost::bind(&LLAvatarActions::startIM, id));
|
||||
return;
|
||||
}
|
||||
|
||||
LLUUID session_id = gIMMgr->addSession(name, IM_NOTHING_SPECIAL, id);
|
||||
if (session_id != LLUUID::null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -526,21 +526,30 @@ void LLAvatarListItem::updateChildren()
|
|||
LLView* LLAvatarListItem::getItemChildView(EAvatarListItemChildIndex child_view_index)
|
||||
{
|
||||
LLView* child_view = mAvatarName;
|
||||
if (child_view_index < 0 || ALIC_COUNT <= child_view_index)
|
||||
{
|
||||
LL_WARNS("AvatarItemReshape") << "Child view index is out of range: " << child_view_index << LL_ENDL;
|
||||
return child_view;
|
||||
}
|
||||
|
||||
switch (child_view_index)
|
||||
{
|
||||
case ALIC_ICON: child_view = mAvatarIcon; break;
|
||||
case ALIC_NAME: child_view = mAvatarName; break;
|
||||
case ALIC_INTERACTION_TIME: child_view = mLastInteractionTime; break;
|
||||
case ALIC_SPEAKER_INDICATOR: child_view = mSpeakingIndicator; break;
|
||||
case ALIC_INFO_BUTTON: child_view = mInfoBtn; break;
|
||||
case ALIC_PROFILE_BUTTON: child_view = mProfileBtn; break;
|
||||
case ALIC_ICON:
|
||||
child_view = mAvatarIcon;
|
||||
break;
|
||||
case ALIC_NAME:
|
||||
child_view = mAvatarName;
|
||||
break;
|
||||
case ALIC_INTERACTION_TIME:
|
||||
child_view = mLastInteractionTime;
|
||||
break;
|
||||
case ALIC_SPEAKER_INDICATOR:
|
||||
child_view = mSpeakingIndicator;
|
||||
break;
|
||||
case ALIC_INFO_BUTTON:
|
||||
child_view = mInfoBtn;
|
||||
break;
|
||||
case ALIC_PROFILE_BUTTON:
|
||||
child_view = mProfileBtn;
|
||||
break;
|
||||
default:
|
||||
LL_WARNS("AvatarItemReshape") << "Unexpected child view index is passed: " << child_view_index << LL_ENDL;
|
||||
// leave child_view untouched
|
||||
}
|
||||
|
||||
return child_view;
|
||||
|
|
|
|||
|
|
@ -60,6 +60,27 @@ namespace
|
|||
const std::string& PANEL_MOVEMENT_NAME = "movement_panel";
|
||||
const std::string& PANEL_CAMERA_NAME = "cam_panel";
|
||||
const std::string& PANEL_GESTURE_NAME = "gesture_panel";
|
||||
|
||||
S32 get_panel_min_width(LLLayoutStack* stack, LLPanel* panel)
|
||||
{
|
||||
S32 minimal_width = 0;
|
||||
llassert(stack);
|
||||
if ( stack && panel && panel->getVisible() )
|
||||
{
|
||||
stack->getPanelMinSize(panel->getName(), &minimal_width, NULL);
|
||||
}
|
||||
return minimal_width;
|
||||
}
|
||||
|
||||
S32 get_curr_width(LLUICtrl* ctrl)
|
||||
{
|
||||
S32 cur_width = 0;
|
||||
if ( ctrl && ctrl->getVisible() )
|
||||
{
|
||||
cur_width = ctrl->getRect().getWidth();
|
||||
}
|
||||
return cur_width;
|
||||
}
|
||||
}
|
||||
|
||||
class LLBottomTrayLite
|
||||
|
|
@ -80,6 +101,14 @@ public:
|
|||
{
|
||||
mNearbyChatBar = getChild<LLNearbyChatBar>("chat_bar");
|
||||
mGesturePanel = getChild<LLPanel>("gesture_panel");
|
||||
|
||||
// Hide "show_nearby_chat" button
|
||||
LLLineEditor* chat_box = mNearbyChatBar->getChatBox();
|
||||
LLUICtrl* show_btn = mNearbyChatBar->getChild<LLUICtrl>("show_nearby_chat");
|
||||
S32 delta_width = show_btn->getRect().getWidth();
|
||||
show_btn->setVisible(FALSE);
|
||||
chat_box->reshape(chat_box->getRect().getWidth() + delta_width, chat_box->getRect().getHeight());
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -433,6 +462,8 @@ BOOL LLBottomTray::postBuild()
|
|||
mObjectDefaultWidthMap[RS_BUTTON_CAMERA] = mCamPanel->getRect().getWidth();
|
||||
mObjectDefaultWidthMap[RS_BUTTON_SPEAK] = mSpeakPanel->getRect().getWidth();
|
||||
|
||||
mNearbyChatBar->getChatBox()->setContextMenu(NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -1084,58 +1115,131 @@ void LLBottomTray::setTrayButtonVisible(EResizeState shown_object_type, bool vis
|
|||
|
||||
if (mDummiesMap.count(shown_object_type))
|
||||
{
|
||||
mDummiesMap[shown_object_type]->setVisible(visible);
|
||||
// Hide/show layout panel for dummy icon.
|
||||
mDummiesMap[shown_object_type]->getParent()->setVisible(visible);
|
||||
}
|
||||
}
|
||||
|
||||
void LLBottomTray::setTrayButtonVisibleIfPossible(EResizeState shown_object_type, bool visible, bool raise_notification)
|
||||
{
|
||||
bool can_be_set = true;
|
||||
if (!setVisibleAndFitWidths(shown_object_type, visible) && visible && raise_notification)
|
||||
{
|
||||
LLNotificationsUtil::add("BottomTrayButtonCanNotBeShown",
|
||||
LLSD(),
|
||||
LLSD(),
|
||||
LLNotificationFunctorRegistry::instance().DONOTHING);
|
||||
}
|
||||
}
|
||||
|
||||
bool LLBottomTray::setVisibleAndFitWidths(EResizeState object_type, bool visible)
|
||||
{
|
||||
LLPanel* cur_panel = mStateProcessedObjectMap[object_type];
|
||||
if (NULL == cur_panel)
|
||||
{
|
||||
lldebugs << "There is no object to process for state: " << object_type << llendl;
|
||||
return false;
|
||||
}
|
||||
|
||||
const S32 dummy_width = mDummiesMap.count(object_type)
|
||||
? mDummiesMap[object_type]->getParent()->getRect().getWidth()
|
||||
: 0;
|
||||
|
||||
bool is_set = true;
|
||||
|
||||
if (visible)
|
||||
{
|
||||
LLPanel* panel = mStateProcessedObjectMap[shown_object_type];
|
||||
if (NULL == panel)
|
||||
// Assume that only chiclet panel can be auto-resized and
|
||||
// don't take into account width of dummy widgets
|
||||
const S32 available_width =
|
||||
mChicletPanel->getParent()->getRect().getWidth() -
|
||||
mChicletPanel->getMinWidth() -
|
||||
dummy_width;
|
||||
|
||||
S32 preferred_width = mObjectDefaultWidthMap[object_type];
|
||||
S32 current_width = cur_panel->getRect().getWidth();
|
||||
S32 result_width = 0;
|
||||
bool decrease_width = false;
|
||||
|
||||
// Mark this button to be shown
|
||||
mResizeState |= object_type;
|
||||
|
||||
if (preferred_width > 0 && available_width >= preferred_width)
|
||||
{
|
||||
lldebugs << "There is no object to process for state: " << shown_object_type << llendl;
|
||||
return;
|
||||
result_width = preferred_width;
|
||||
}
|
||||
else if (available_width >= current_width)
|
||||
{
|
||||
result_width = current_width;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Calculate the possible shrunk width as difference between current and minimal widths
|
||||
const S32 chatbar_shrunk_width =
|
||||
mNearbyChatBar->getRect().getWidth() - mNearbyChatBar->getMinWidth();
|
||||
|
||||
const S32 sum_of_min_widths =
|
||||
get_panel_min_width(mToolbarStack, mStateProcessedObjectMap[RS_BUTTON_CAMERA]) +
|
||||
get_panel_min_width(mToolbarStack, mStateProcessedObjectMap[RS_BUTTON_MOVEMENT]) +
|
||||
get_panel_min_width(mToolbarStack, mStateProcessedObjectMap[RS_BUTTON_GESTURES]) +
|
||||
get_panel_min_width(mToolbarStack, mSpeakPanel);
|
||||
|
||||
const S32 sum_of_curr_widths =
|
||||
get_curr_width(mStateProcessedObjectMap[RS_BUTTON_CAMERA]) +
|
||||
get_curr_width(mStateProcessedObjectMap[RS_BUTTON_MOVEMENT]) +
|
||||
get_curr_width(mStateProcessedObjectMap[RS_BUTTON_GESTURES]) +
|
||||
get_curr_width(mSpeakPanel);
|
||||
|
||||
const S32 possible_shrunk_width =
|
||||
chatbar_shrunk_width + (sum_of_curr_widths - sum_of_min_widths);
|
||||
|
||||
// Minimal width of current panel
|
||||
S32 minimal_width = 0;
|
||||
mToolbarStack->getPanelMinSize(cur_panel->getName(), &minimal_width, NULL);
|
||||
|
||||
if ( (available_width + possible_shrunk_width) >= minimal_width)
|
||||
{
|
||||
// There is enough space for minimal width, but set the result_width
|
||||
// to current_width so buttons widths decreasing will be done in predefined order
|
||||
result_width = current_width;
|
||||
decrease_width = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Nothing can be done, give up...
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const S32 dummy_width = mDummiesMap.count(shown_object_type) ? mDummiesMap[shown_object_type]->getRect().getWidth() : 0;
|
||||
|
||||
const S32 chatbar_panel_width = mNearbyChatBar->getRect().getWidth();
|
||||
const S32 chatbar_panel_min_width = mNearbyChatBar->getMinWidth();
|
||||
|
||||
const S32 chiclet_panel_width = mChicletPanel->getParent()->getRect().getWidth();
|
||||
const S32 chiclet_panel_min_width = mChicletPanel->getMinWidth();
|
||||
|
||||
const S32 available_width = (chatbar_panel_width - chatbar_panel_min_width)
|
||||
+ (chiclet_panel_width - chiclet_panel_min_width);
|
||||
|
||||
const S32 required_width = panel->getRect().getWidth() + dummy_width;
|
||||
can_be_set = available_width >= required_width;
|
||||
}
|
||||
|
||||
if (can_be_set)
|
||||
{
|
||||
setTrayButtonVisible(shown_object_type, visible);
|
||||
|
||||
// if we hide the button mark it NOT to show while future bottom tray extending
|
||||
if (!visible)
|
||||
if (result_width != current_width)
|
||||
{
|
||||
mResizeState &= ~shown_object_type;
|
||||
cur_panel->reshape(result_width, cur_panel->getRect().getHeight());
|
||||
current_width = result_width;
|
||||
}
|
||||
|
||||
is_set = processShowButton(object_type, ¤t_width);
|
||||
|
||||
// Shrink buttons if needed
|
||||
if (is_set && decrease_width)
|
||||
{
|
||||
processWidthDecreased( -result_width - dummy_width );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// mark this button to show it while future bottom tray extending
|
||||
mResizeState |= shown_object_type;
|
||||
if ( raise_notification )
|
||||
LLNotificationsUtil::add("BottomTrayButtonCanNotBeShown",
|
||||
LLSD(),
|
||||
LLSD(),
|
||||
LLNotificationFunctorRegistry::instance().DONOTHING);
|
||||
const S32 delta_width = get_curr_width(cur_panel);
|
||||
|
||||
setTrayButtonVisible(object_type, false);
|
||||
|
||||
// Mark button NOT to show while future bottom tray extending
|
||||
mResizeState &= ~object_type;
|
||||
|
||||
// Extend other buttons if need
|
||||
if (delta_width)
|
||||
{
|
||||
processWidthIncreased(delta_width + dummy_width);
|
||||
}
|
||||
}
|
||||
return is_set;
|
||||
}
|
||||
|
||||
//EOF
|
||||
|
|
|
|||
|
|
@ -173,6 +173,14 @@ private:
|
|||
*/
|
||||
void setTrayButtonVisibleIfPossible(EResizeState shown_object_type, bool visible, bool raise_notification = true);
|
||||
|
||||
/**
|
||||
* Sets passed visibility to required button and fit widths of shown
|
||||
* buttons(notice that method can shrink widths to
|
||||
* allocate needed room in bottom tray).
|
||||
* Returns true if visibility of required button was set.
|
||||
*/
|
||||
bool setVisibleAndFitWidths(EResizeState object_type, bool visible);
|
||||
|
||||
MASK mResizeState;
|
||||
|
||||
typedef std::map<EResizeState, LLPanel*> state_object_map_t;
|
||||
|
|
|
|||
|
|
@ -301,8 +301,10 @@ void LLCallFloater::updateSession()
|
|||
refreshParticipantList();
|
||||
updateAgentModeratorState();
|
||||
|
||||
//show floater for voice calls
|
||||
if (!is_local_chat)
|
||||
//show floater for voice calls & only in CONNECTED to voice channel state
|
||||
if (!is_local_chat &&
|
||||
voice_channel &&
|
||||
LLVoiceChannel::STATE_CONNECTED == voice_channel->getState())
|
||||
{
|
||||
LLIMFloater* im_floater = LLIMFloater::findInstance(session_id);
|
||||
bool show_me = !(im_floater && im_floater->getVisible());
|
||||
|
|
@ -331,6 +333,7 @@ void LLCallFloater::refreshParticipantList()
|
|||
{
|
||||
mParticipants = new LLParticipantList(mSpeakerManager, mAvatarList, true, mVoiceType != VC_GROUP_CHAT && mVoiceType != VC_AD_HOC_CHAT);
|
||||
mParticipants->setValidateSpeakerCallback(boost::bind(&LLCallFloater::validateSpeaker, this, _1));
|
||||
mParticipants->setSortOrder(LLParticipantList::E_SORT_BY_RECENT_SPEAKERS);
|
||||
|
||||
if (LLLocalSpeakerMgr::getInstance() == mSpeakerManager)
|
||||
{
|
||||
|
|
@ -675,8 +678,7 @@ void LLCallFloater::resetVoiceRemoveTimers()
|
|||
|
||||
void LLCallFloater::removeVoiceRemoveTimer(const LLUUID& voice_speaker_id)
|
||||
{
|
||||
bool delete_it = true;
|
||||
mSpeakerDelayRemover->unsetActionTimer(voice_speaker_id, delete_it);
|
||||
mSpeakerDelayRemover->unsetActionTimer(voice_speaker_id);
|
||||
}
|
||||
|
||||
bool LLCallFloater::validateSpeaker(const LLUUID& speaker_id)
|
||||
|
|
@ -718,7 +720,15 @@ void LLCallFloater::connectToChannel(LLVoiceChannel* channel)
|
|||
|
||||
void LLCallFloater::onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state)
|
||||
{
|
||||
updateState(new_state);
|
||||
// check is voice operational and if it doesn't work hide VCP (EXT-4397)
|
||||
if(LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking())
|
||||
{
|
||||
updateState(new_state);
|
||||
}
|
||||
else
|
||||
{
|
||||
closeFloater();
|
||||
}
|
||||
}
|
||||
|
||||
void LLCallFloater::updateState(const LLVoiceChannel::EState& new_state)
|
||||
|
|
@ -747,18 +757,26 @@ void LLCallFloater::reset(const LLVoiceChannel::EState& new_state)
|
|||
mParticipants = NULL;
|
||||
mAvatarList->clear();
|
||||
|
||||
// "loading" is shown in parcel with disabled voice only when state is "ringing"
|
||||
// to avoid showing it in nearby chat vcp all the time- "no_one_near" is now shown there (EXT-4648)
|
||||
bool show_loading = LLVoiceChannel::STATE_RINGING == new_state;
|
||||
if(!show_loading && !LLViewerParcelMgr::getInstance()->allowAgentVoice() && mVoiceType == VC_LOCAL_CHAT)
|
||||
// These ifs were added instead of simply showing "loading" to make VCP work correctly in parcels
|
||||
// with disabled voice (EXT-4648 and EXT-4649)
|
||||
if (!LLViewerParcelMgr::getInstance()->allowAgentVoice() && LLVoiceChannel::STATE_HUNG_UP == new_state)
|
||||
{
|
||||
// hides "Leave Call" when call is ended in parcel with disabled voice- hiding usually happens in
|
||||
// updateSession() which won't be called here because connect to nearby voice never happens
|
||||
childSetVisible("leave_call_btn_panel", false);
|
||||
// setting title to nearby chat an "no one near..." text- because in region with disabled
|
||||
// voice we won't have chance to really connect to nearby, so VCP is changed here manually
|
||||
setTitle(getString("title_nearby"));
|
||||
mAvatarList->setNoItemsCommentText(getString("no_one_near"));
|
||||
}
|
||||
else
|
||||
// "loading" is shown only when state is "ringing" to avoid showing it in nearby chat vcp
|
||||
// of parcels with disabled voice all the time- "no_one_near" is now shown there (EXT-4648)
|
||||
else if (new_state == LLVoiceChannel::STATE_RINGING)
|
||||
{
|
||||
// update floater to show Loading while waiting for data.
|
||||
mAvatarList->setNoItemsCommentText(LLTrans::getString("LoadingData"));
|
||||
}
|
||||
|
||||
mAvatarList->setVisible(TRUE);
|
||||
mNonAvatarCaller->setVisible(FALSE);
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue