merge
commit
54a95f706f
|
|
@ -171,8 +171,8 @@ if (LINUX)
|
|||
if (NOT STANDALONE)
|
||||
# this stops us requiring a really recent glibc at runtime
|
||||
add_definitions(-fno-stack-protector)
|
||||
# linking can be so slow - give us a chance to figure out why
|
||||
set(CMAKE_CXX_LINK_FLAGS "-Wl,--stats,--no-keep-memory")
|
||||
# linking can be very memory-hungry, especially the final viewer link
|
||||
set(CMAKE_CXX_LINK_FLAGS "-Wl,--no-keep-memory")
|
||||
endif (NOT STANDALONE)
|
||||
endif (VIEWER)
|
||||
|
||||
|
|
|
|||
|
|
@ -54,7 +54,10 @@ else (STANDALONE)
|
|||
endif (WINDOWS)
|
||||
set(APR_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/apr-1)
|
||||
|
||||
if (LINUX AND VIEWER)
|
||||
list(APPEND APRUTIL_LIBRARIES ${DB_LIBRARIES} uuid)
|
||||
endif (LINUX AND VIEWER)
|
||||
if (LINUX)
|
||||
if (VIEWER)
|
||||
list(APPEND APRUTIL_LIBRARIES ${DB_LIBRARIES} uuid)
|
||||
endif (VIEWER)
|
||||
list(APPEND APRUTIL_LIBRARIES ${DB_LIBRARIES} rt)
|
||||
endif (LINUX)
|
||||
endif (STANDALONE)
|
||||
|
|
|
|||
|
|
@ -38,12 +38,12 @@ else (STANDALONE)
|
|||
debug libboost_signals-vc80-mt-gd-${BOOST_VERSION})
|
||||
endif (MSVC71)
|
||||
elseif (DARWIN)
|
||||
set(BOOST_PROGRAM_OPTIONS_LIBRARY boost_program_options-mt)
|
||||
set(BOOST_REGEX_LIBRARY boost_regex-mt)
|
||||
set(BOOST_SIGNALS_LIBRARY boost_signals-mt)
|
||||
set(BOOST_PROGRAM_OPTIONS_LIBRARY boost_program_options-xgcc40-mt)
|
||||
set(BOOST_REGEX_LIBRARY boost_regex-xgcc40-mt)
|
||||
set(BOOST_SIGNALS_LIBRARY boost_signals-xgcc40-mt)
|
||||
elseif (LINUX)
|
||||
set(BOOST_PROGRAM_OPTIONS_LIBRARY boost_program_options-mt)
|
||||
set(BOOST_REGEX_LIBRARY boost_regex-mt)
|
||||
set(BOOST_SIGNALS_LIBRARY boost_signals-mt)
|
||||
set(BOOST_PROGRAM_OPTIONS_LIBRARY boost_program_options-gcc41-mt)
|
||||
set(BOOST_REGEX_LIBRARY boost_regex-gcc41-mt)
|
||||
set(BOOST_SIGNALS_LIBRARY boost_signals-gcc41-mt)
|
||||
endif (WINDOWS)
|
||||
endif (STANDALONE)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
# -*- cmake -*-
|
||||
|
||||
if (VIEWER)
|
||||
|
||||
set(OS_DRAG_DROP ON CACHE BOOL "Build the viewer with OS level drag and drop turned on or off")
|
||||
|
||||
if (OS_DRAG_DROP)
|
||||
|
||||
if (WINDOWS)
|
||||
add_definitions(-DLL_OS_DRAGDROP_ENABLED=1)
|
||||
endif (WINDOWS)
|
||||
|
||||
if (DARWIN)
|
||||
add_definitions(-DLL_OS_DRAGDROP_ENABLED=1)
|
||||
endif (DARWIN)
|
||||
|
||||
if (LINUX)
|
||||
add_definitions(-DLL_OS_DRAGDROP_ENABLED=0)
|
||||
endif (LINUX)
|
||||
|
||||
endif (OS_DRAG_DROP)
|
||||
|
||||
endif (VIEWER)
|
||||
|
|
@ -24,7 +24,6 @@ elseif (LINUX)
|
|||
gmodule-2.0
|
||||
dl
|
||||
gthread-2.0
|
||||
rt
|
||||
glib-2.0
|
||||
)
|
||||
endif (STANDALONE)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
# -*- cmake -*-
|
||||
include(Prebuilt)
|
||||
|
||||
if (STANDALONE)
|
||||
include(FindPkgConfig)
|
||||
|
||||
pkg_check_modules(PULSEAUDIO REQUIRED libpulse-mainloop-glib)
|
||||
|
||||
elseif (LINUX)
|
||||
use_prebuilt_binary(pulseaudio)
|
||||
set(PULSEAUDIO_FOUND ON FORCE BOOL)
|
||||
set(PULSEAUDIO_INCLUDE_DIRS
|
||||
${LIBS_PREBUILT_DIR}/include
|
||||
)
|
||||
# We don't need to explicitly link against pulseaudio itself, because
|
||||
# the viewer probes for the system's copy at runtime.
|
||||
set(PULSEAUDIO_LIBRARIES
|
||||
# none needed!
|
||||
)
|
||||
endif (STANDALONE)
|
||||
|
||||
if (PULSEAUDIO_FOUND)
|
||||
set(PULSEAUDIO ON CACHE BOOL "Build with PulseAudio support, if available.")
|
||||
endif (PULSEAUDIO_FOUND)
|
||||
|
||||
if (PULSEAUDIO)
|
||||
add_definitions(-DLL_PULSEAUDIO_ENABLED=1)
|
||||
endif (PULSEAUDIO)
|
||||
|
|
@ -54,12 +54,5 @@ target_link_libraries(linux-crash-logger
|
|||
${DB_LIBRARIES}
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT linux-crash-logger-stripped
|
||||
COMMAND strip
|
||||
ARGS --strip-debug -o linux-crash-logger-stripped linux-crash-logger
|
||||
DEPENDS linux-crash-logger
|
||||
)
|
||||
|
||||
add_custom_target(linux-crash-logger-strip-target ALL
|
||||
DEPENDS linux-crash-logger-stripped)
|
||||
add_custom_target(linux-crash-logger-target ALL
|
||||
DEPENDS linux-crash-logger)
|
||||
|
|
|
|||
|
|
@ -47,12 +47,5 @@ target_link_libraries(linux-updater
|
|||
${LLCOMMON_LIBRARIES}
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT linux-updater-stripped
|
||||
COMMAND strip
|
||||
ARGS --strip-debug -o linux-updater-stripped linux-updater
|
||||
DEPENDS linux-updater
|
||||
)
|
||||
|
||||
add_custom_target(linux-updater-strip-target ALL
|
||||
DEPENDS linux-updater-stripped)
|
||||
add_custom_target(linux-updater-target ALL
|
||||
DEPENDS linux-updater)
|
||||
|
|
|
|||
|
|
@ -181,6 +181,8 @@ LLVorbisDecodeState::LLVorbisDecodeState(const LLUUID &uuid, const std::string &
|
|||
mFileHandle = LLLFSThread::nullHandle();
|
||||
#endif
|
||||
// No default value for mVF, it's an ogg structure?
|
||||
// Hey, let's zero it anyway, for predictability.
|
||||
memset(&mVF, 0, sizeof(mVF));
|
||||
}
|
||||
|
||||
LLVorbisDecodeState::~LLVorbisDecodeState()
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -68,7 +68,8 @@ typedef enum e_chat_audible_level
|
|||
typedef enum e_chat_style
|
||||
{
|
||||
CHAT_STYLE_NORMAL,
|
||||
CHAT_STYLE_IRC
|
||||
CHAT_STYLE_IRC,
|
||||
CHAT_STYLE_HISTORY
|
||||
}EChatStyle;
|
||||
|
||||
// A piece of chat
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -114,7 +114,11 @@ static timer_tree_dfs_iterator_t end_timer_tree()
|
|||
class NamedTimerFactory : public LLSingleton<NamedTimerFactory>
|
||||
{
|
||||
public:
|
||||
NamedTimerFactory()
|
||||
NamedTimerFactory()
|
||||
: mActiveTimerRoot(NULL),
|
||||
mTimerRoot(NULL),
|
||||
mAppTimer(NULL),
|
||||
mRootFrameState(NULL)
|
||||
{}
|
||||
|
||||
/*virtual */ void initSingleton()
|
||||
|
|
@ -214,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
|
||||
|
|
@ -367,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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -482,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;
|
||||
|
|
@ -527,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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -571,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;
|
||||
|
||||
|
|
|
|||
|
|
@ -95,7 +95,6 @@ public:
|
|||
bool notNull() const { return (mPointer != NULL); }
|
||||
|
||||
operator Type*() const { return mPointer; }
|
||||
operator const Type*() const { return mPointer; }
|
||||
bool operator !=(Type* ptr) const { return (mPointer != ptr); }
|
||||
bool operator ==(Type* ptr) const { return (mPointer == ptr); }
|
||||
bool operator ==(const LLPointer<Type>& ptr) const { return (mPointer == ptr.mPointer); }
|
||||
|
|
|
|||
|
|
@ -35,6 +35,17 @@
|
|||
|
||||
#include "llerror.h"
|
||||
|
||||
LLRefCount::LLRefCount(const LLRefCount& other)
|
||||
: mRef(0)
|
||||
{
|
||||
}
|
||||
|
||||
LLRefCount& LLRefCount::operator=(const LLRefCount&)
|
||||
{
|
||||
// do nothing, since ref count is specific to *this* reference
|
||||
return *this;
|
||||
}
|
||||
|
||||
LLRefCount::LLRefCount() :
|
||||
mRef(0)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -41,22 +41,20 @@
|
|||
|
||||
class LL_COMMON_API LLRefCount
|
||||
{
|
||||
private:
|
||||
LLRefCount(const LLRefCount& other); // no implementation
|
||||
private:
|
||||
LLRefCount& operator=(const LLRefCount&); // no implementation
|
||||
protected:
|
||||
LLRefCount(const LLRefCount& other);
|
||||
LLRefCount& operator=(const LLRefCount&);
|
||||
virtual ~LLRefCount(); // use unref()
|
||||
|
||||
public:
|
||||
LLRefCount();
|
||||
|
||||
void ref()
|
||||
void ref() const
|
||||
{
|
||||
mRef++;
|
||||
}
|
||||
|
||||
S32 unref()
|
||||
S32 unref() const
|
||||
{
|
||||
llassert(mRef >= 1);
|
||||
if (0 == --mRef)
|
||||
|
|
@ -67,13 +65,15 @@ public:
|
|||
return mRef;
|
||||
}
|
||||
|
||||
//NOTE: when passing around a const LLRefCount object, this can return different results
|
||||
// at different types, since mRef is mutable
|
||||
S32 getNumRefs() const
|
||||
{
|
||||
return mRef;
|
||||
}
|
||||
|
||||
private:
|
||||
S32 mRef;
|
||||
mutable S32 mRef;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -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,54 +555,3 @@ void secondsToTimecodeString(F32 current_time, std::string& tcstring)
|
|||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// LLEventTimer Implementation
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
LLEventTimer::LLEventTimer(F32 period)
|
||||
: mEventTimer()
|
||||
{
|
||||
mPeriod = period;
|
||||
}
|
||||
|
||||
LLEventTimer::LLEventTimer(const LLDate& time)
|
||||
: mEventTimer()
|
||||
{
|
||||
mPeriod = (F32)(time.secondsSinceEpoch() - LLDate::now().secondsSinceEpoch());
|
||||
}
|
||||
|
||||
|
||||
LLEventTimer::~LLEventTimer()
|
||||
{
|
||||
}
|
||||
|
||||
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();
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -39,8 +39,6 @@
|
|||
#include <limits.h>
|
||||
|
||||
#include "stdtypes.h"
|
||||
#include "lldate.h"
|
||||
#include "llinstancetracker.h"
|
||||
|
||||
#include <string>
|
||||
#include <list>
|
||||
|
|
@ -171,25 +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;
|
||||
};
|
||||
|
||||
U64 LL_COMMON_API totalTime(); // Returns current system time in microseconds
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -343,20 +343,20 @@ public:
|
|||
/// Instantiate an LLTreeDFSIter to start a depth-first walk. Pass
|
||||
/// functors to extract the 'child begin' and 'child end' iterators from
|
||||
/// each node.
|
||||
LLTreeDFSIter(const ptr_type& node, const func_type& beginfunc, const func_type& endfunc):
|
||||
mBeginFunc(beginfunc),
|
||||
mEndFunc(endfunc),
|
||||
mSkipChildren(false)
|
||||
LLTreeDFSIter(const ptr_type& node, const func_type& beginfunc, const func_type& endfunc)
|
||||
: mBeginFunc(beginfunc),
|
||||
mEndFunc(endfunc),
|
||||
mSkipChildren(false)
|
||||
{
|
||||
// Only push back this node if it's non-NULL!
|
||||
if (node)
|
||||
mPending.push_back(node);
|
||||
}
|
||||
/// Instantiate an LLTreeDFSIter to mark the end of the walk
|
||||
LLTreeDFSIter() {}
|
||||
LLTreeDFSIter() : mSkipChildren(false) {}
|
||||
|
||||
/// flags iterator logic to skip traversing children of current node on next increment
|
||||
void skipDescendants(bool skip = true) { mSkipChildren = skip; }
|
||||
/// flags iterator logic to skip traversing children of current node on next increment
|
||||
void skipDescendants(bool skip = true) { mSkipChildren = skip; }
|
||||
|
||||
private:
|
||||
/// leverage boost::iterator_facade
|
||||
|
|
@ -405,8 +405,8 @@ private:
|
|||
func_type mBeginFunc;
|
||||
/// functor to extract end() child iterator
|
||||
func_type mEndFunc;
|
||||
/// flag which controls traversal of children (skip children of current node if true)
|
||||
bool mSkipChildren;
|
||||
/// flag which controls traversal of children (skip children of current node if true)
|
||||
bool mSkipChildren;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -451,21 +451,21 @@ public:
|
|||
/// Instantiate an LLTreeDFSPostIter to start a depth-first walk. Pass
|
||||
/// functors to extract the 'child begin' and 'child end' iterators from
|
||||
/// each node.
|
||||
LLTreeDFSPostIter(const ptr_type& node, const func_type& beginfunc, const func_type& endfunc):
|
||||
mBeginFunc(beginfunc),
|
||||
mEndFunc(endfunc),
|
||||
mSkipAncestors(false)
|
||||
{
|
||||
LLTreeDFSPostIter(const ptr_type& node, const func_type& beginfunc, const func_type& endfunc)
|
||||
: mBeginFunc(beginfunc),
|
||||
mEndFunc(endfunc),
|
||||
mSkipAncestors(false)
|
||||
{
|
||||
if (! node)
|
||||
return;
|
||||
mPending.push_back(typename list_type::value_type(node, false));
|
||||
makeCurrent();
|
||||
}
|
||||
/// Instantiate an LLTreeDFSPostIter to mark the end of the walk
|
||||
LLTreeDFSPostIter() {}
|
||||
LLTreeDFSPostIter() : mSkipAncestors(false) {}
|
||||
|
||||
/// flags iterator logic to skip traversing ancestors of current node on next increment
|
||||
void skipAncestors(bool skip = true) { mSkipAncestors = skip; }
|
||||
/// flags iterator logic to skip traversing ancestors of current node on next increment
|
||||
void skipAncestors(bool skip = true) { mSkipAncestors = skip; }
|
||||
|
||||
private:
|
||||
/// leverage boost::iterator_facade
|
||||
|
|
|
|||
|
|
@ -188,6 +188,7 @@ LLWorkerClass::LLWorkerClass(LLWorkerThread* workerthread, const std::string& na
|
|||
: mWorkerThread(workerthread),
|
||||
mWorkerClassName(name),
|
||||
mRequestHandle(LLWorkerThread::nullHandle()),
|
||||
mRequestPriority(LLWorkerThread::PRIORITY_NORMAL),
|
||||
mMutex(NULL),
|
||||
mWorkFlags(0)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -97,7 +97,8 @@ void info_callback(const char* msg, void*)
|
|||
}
|
||||
|
||||
|
||||
LLImageJ2COJ::LLImageJ2COJ() : LLImageJ2CImpl()
|
||||
LLImageJ2COJ::LLImageJ2COJ()
|
||||
: LLImageJ2CImpl()
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -51,9 +51,6 @@ protected:
|
|||
// Divide a by b to the power of 2 and round upwards.
|
||||
return (a + (1 << b) - 1) >> b;
|
||||
}
|
||||
|
||||
// Temporary variables for in-progress decodes...
|
||||
LLImageRaw *mRawImagep;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -45,7 +45,8 @@ LLCamera::LLCamera() :
|
|||
mNearPlane(DEFAULT_NEAR_PLANE),
|
||||
mFarPlane(DEFAULT_FAR_PLANE),
|
||||
mFixedDistance(-1.f),
|
||||
mPlaneCount(6)
|
||||
mPlaneCount(6),
|
||||
mFrustumCornerDist(0.f)
|
||||
{
|
||||
calculateFrustumPlanes();
|
||||
}
|
||||
|
|
@ -55,7 +56,8 @@ LLCamera::LLCamera(F32 vertical_fov_rads, F32 aspect_ratio, S32 view_height_in_p
|
|||
LLCoordFrame(),
|
||||
mViewHeightInPixels(view_height_in_pixels),
|
||||
mFixedDistance(-1.f),
|
||||
mPlaneCount(6)
|
||||
mPlaneCount(6),
|
||||
mFrustumCornerDist(0.f)
|
||||
{
|
||||
mAspect = llclamp(aspect_ratio, MIN_ASPECT_RATIO, MAX_ASPECT_RATIO);
|
||||
mNearPlane = llclamp(near_plane, MIN_NEAR_PLANE, MAX_NEAR_PLANE);
|
||||
|
|
@ -648,7 +650,6 @@ void LLCamera::ignoreAgentFrustumPlane(S32 idx)
|
|||
|
||||
void LLCamera::calcAgentFrustumPlanes(LLVector3* frust)
|
||||
{
|
||||
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
mAgentFrustum[i] = frust[i];
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -42,11 +42,14 @@
|
|||
|
||||
LLPacketBuffer::LLPacketBuffer(const LLHost &host, const char *datap, const S32 size) : mHost(host)
|
||||
{
|
||||
mSize = 0;
|
||||
mData[0] = '!';
|
||||
|
||||
if (size > NET_BUFFER_SIZE)
|
||||
{
|
||||
llerrs << "Sending packet > " << NET_BUFFER_SIZE << " of size " << size << llendl;
|
||||
}
|
||||
else // we previously relied on llerrs being fatal to not get here...
|
||||
else
|
||||
{
|
||||
if (datap != NULL)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1196,6 +1196,7 @@ LLTransferTarget::LLTransferTarget(
|
|||
mType(type),
|
||||
mSourceType(source_type),
|
||||
mID(transfer_id),
|
||||
mChannelp(NULL),
|
||||
mGotInfo(FALSE),
|
||||
mSize(0),
|
||||
mLastPacketID(-1)
|
||||
|
|
|
|||
|
|
@ -226,7 +226,10 @@ void LLTransferSourceAsset::responderCallback(LLVFS *vfs, const LLUUID& uuid, LL
|
|||
|
||||
|
||||
|
||||
LLTransferSourceParamsAsset::LLTransferSourceParamsAsset() : LLTransferSourceParams(LLTST_ASSET)
|
||||
LLTransferSourceParamsAsset::LLTransferSourceParamsAsset()
|
||||
: LLTransferSourceParams(LLTST_ASSET),
|
||||
|
||||
mAssetType(LLAssetType::AT_NONE)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,12 @@ typedef void (*LLTTFCompleteCallback)(const LLTSCode status, void *user_data);
|
|||
class LLTransferTargetParamsFile : public LLTransferTargetParams
|
||||
{
|
||||
public:
|
||||
LLTransferTargetParamsFile() : LLTransferTargetParams(LLTTT_FILE) {}
|
||||
LLTransferTargetParamsFile()
|
||||
: LLTransferTargetParams(LLTTT_FILE),
|
||||
|
||||
mCompleteCallback(NULL),
|
||||
mUserData(NULL)
|
||||
{}
|
||||
void setFilename(const std::string& filename) { mFilename = filename; }
|
||||
void setCallback(LLTTFCompleteCallback cb, void *user_data) { mCompleteCallback = cb; mUserData = user_data; }
|
||||
|
||||
|
|
|
|||
|
|
@ -68,7 +68,6 @@ protected:
|
|||
LLTTVFCompleteCallback mCompleteCallback;
|
||||
void* mUserDatap;
|
||||
S32 mErrCode;
|
||||
LLVFSThread::handle_t mHandle;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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$
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -104,6 +104,8 @@ void LLPluginClassMedia::reset()
|
|||
mSetMediaHeight = -1;
|
||||
mRequestedMediaWidth = 0;
|
||||
mRequestedMediaHeight = 0;
|
||||
mRequestedTextureWidth = 0;
|
||||
mRequestedTextureHeight = 0;
|
||||
mFullMediaWidth = 0;
|
||||
mFullMediaHeight = 0;
|
||||
mTextureWidth = 0;
|
||||
|
|
@ -469,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;
|
||||
|
||||
|
|
@ -526,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);
|
||||
}
|
||||
|
|
@ -544,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);
|
||||
|
||||
|
|
@ -680,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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ static const F32 PLUGIN_IDLE_SECONDS = 1.0f / 100.0f; // Each call to idle will
|
|||
|
||||
LLPluginProcessChild::LLPluginProcessChild()
|
||||
{
|
||||
mState = STATE_UNINITIALIZED;
|
||||
mInstance = NULL;
|
||||
mSocket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP);
|
||||
mSleepTime = PLUGIN_IDLE_SECONDS; // default: send idle messages at 100Hz
|
||||
|
|
@ -277,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)
|
||||
|
|
|
|||
|
|
@ -89,8 +89,9 @@ private:
|
|||
STATE_ERROR, // generic bailout state
|
||||
STATE_DONE // state machine will sit in this state after either error or normal termination.
|
||||
};
|
||||
EState mState;
|
||||
void setState(EState state);
|
||||
|
||||
EState mState;
|
||||
|
||||
LLHost mLauncherHost;
|
||||
LLSocket::ptr_t mSocket;
|
||||
|
|
|
|||
|
|
@ -50,6 +50,8 @@ LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner)
|
|||
mOwner = owner;
|
||||
mBoundPort = 0;
|
||||
mState = STATE_UNINITIALIZED;
|
||||
mSleepTime = 0.0;
|
||||
mCPUUsage = 0.0;
|
||||
mDisableTimeout = false;
|
||||
mDebug = false;
|
||||
|
||||
|
|
|
|||
|
|
@ -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: ";
|
||||
|
|
|
|||
|
|
@ -63,6 +63,12 @@ LLCubeMap::LLCubeMap()
|
|||
mTextureCoordStage(0),
|
||||
mMatrixStage(0)
|
||||
{
|
||||
mTargets[0] = GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB;
|
||||
mTargets[1] = GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB;
|
||||
mTargets[2] = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB;
|
||||
mTargets[3] = GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB;
|
||||
mTargets[4] = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB;
|
||||
mTargets[5] = GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB;
|
||||
}
|
||||
|
||||
LLCubeMap::~LLCubeMap()
|
||||
|
|
@ -75,13 +81,6 @@ void LLCubeMap::initGL()
|
|||
|
||||
if (gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps)
|
||||
{
|
||||
mTargets[0] = GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB;
|
||||
mTargets[1] = GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB;
|
||||
mTargets[2] = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB;
|
||||
mTargets[3] = GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB;
|
||||
mTargets[4] = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB;
|
||||
mTargets[5] = GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB;
|
||||
|
||||
// Not initialized, do stuff.
|
||||
if (mImages[0].isNull())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -270,6 +270,14 @@ F32 LLFontFreetype::getXAdvance(llwchar wch) const
|
|||
return (F32)mFontBitmapCachep->getMaxCharWidth();
|
||||
}
|
||||
|
||||
F32 LLFontFreetype::getXAdvance(const LLFontGlyphInfo* glyph) const
|
||||
{
|
||||
if (mFTFace == NULL)
|
||||
return 0.0;
|
||||
|
||||
return glyph->mXAdvance;
|
||||
}
|
||||
|
||||
F32 LLFontFreetype::getXKerning(llwchar char_left, llwchar char_right) const
|
||||
{
|
||||
if (mFTFace == NULL)
|
||||
|
|
@ -289,6 +297,21 @@ F32 LLFontFreetype::getXKerning(llwchar char_left, llwchar char_right) const
|
|||
return delta.x*(1.f/64.f);
|
||||
}
|
||||
|
||||
F32 LLFontFreetype::getXKerning(const LLFontGlyphInfo* left_glyph_info, const LLFontGlyphInfo* right_glyph_info) const
|
||||
{
|
||||
if (mFTFace == NULL)
|
||||
return 0.0;
|
||||
|
||||
U32 left_glyph = left_glyph_info ? left_glyph_info->mGlyphIndex : 0;
|
||||
U32 right_glyph = right_glyph_info ? right_glyph_info->mGlyphIndex : 0;
|
||||
|
||||
FT_Vector delta;
|
||||
|
||||
llverify(!FT_Get_Kerning(mFTFace, left_glyph, right_glyph, ft_kerning_unfitted, &delta));
|
||||
|
||||
return delta.x*(1.f/64.f);
|
||||
}
|
||||
|
||||
BOOL LLFontFreetype::hasGlyph(llwchar wch) const
|
||||
{
|
||||
llassert(!mIsFallback);
|
||||
|
|
@ -504,8 +527,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()
|
||||
|
|
|
|||
|
|
@ -128,7 +128,9 @@ public:
|
|||
};
|
||||
|
||||
F32 getXAdvance(llwchar wc) const;
|
||||
F32 getXAdvance(const LLFontGlyphInfo* glyph) const;
|
||||
F32 getXKerning(llwchar char_left, llwchar char_right) const; // Get the kerning between the two characters
|
||||
F32 getXKerning(const LLFontGlyphInfo* left_glyph_info, const LLFontGlyphInfo* right_glyph_info) const; // Get the kerning between the two characters
|
||||
|
||||
LLFontGlyphInfo* getGlyphInfo(llwchar wch) const;
|
||||
|
||||
|
|
|
|||
|
|
@ -248,11 +248,18 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
|
|||
}
|
||||
|
||||
|
||||
const LLFontGlyphInfo* next_glyph = NULL;
|
||||
|
||||
for (i = begin_offset; i < begin_offset + length; i++)
|
||||
{
|
||||
llwchar wch = wstr[i];
|
||||
|
||||
const LLFontGlyphInfo* fgi= mFontFreetype->getGlyphInfo(wch);
|
||||
const LLFontGlyphInfo* fgi = next_glyph;
|
||||
next_glyph = NULL;
|
||||
if(!fgi)
|
||||
{
|
||||
fgi = mFontFreetype->getGlyphInfo(wch);
|
||||
}
|
||||
if (!fgi)
|
||||
{
|
||||
llerrs << "Missing Glyph Info" << llendl;
|
||||
|
|
@ -290,7 +297,8 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
|
|||
if (next_char && (next_char < LAST_CHARACTER))
|
||||
{
|
||||
// Kern this puppy.
|
||||
cur_x += mFontFreetype->getXKerning(wch, next_char);
|
||||
next_glyph = mFontFreetype->getGlyphInfo(next_char);
|
||||
cur_x += mFontFreetype->getXKerning(fgi, next_glyph);
|
||||
}
|
||||
|
||||
// Round after kerning.
|
||||
|
|
@ -427,14 +435,21 @@ F32 LLFontGL::getWidthF32(const llwchar* wchars, S32 begin_offset, S32 max_chars
|
|||
F32 cur_x = 0;
|
||||
const S32 max_index = begin_offset + max_chars;
|
||||
|
||||
const LLFontGlyphInfo* next_glyph = NULL;
|
||||
|
||||
F32 width_padding = 0.f;
|
||||
for (S32 i = begin_offset; i < max_index && wchars[i] != 0; i++)
|
||||
{
|
||||
llwchar wch = wchars[i];
|
||||
|
||||
const LLFontGlyphInfo* fgi= mFontFreetype->getGlyphInfo(wch);
|
||||
const LLFontGlyphInfo* fgi = next_glyph;
|
||||
next_glyph = NULL;
|
||||
if(!fgi)
|
||||
{
|
||||
fgi = mFontFreetype->getGlyphInfo(wch);
|
||||
}
|
||||
|
||||
F32 advance = mFontFreetype->getXAdvance(wch);
|
||||
F32 advance = mFontFreetype->getXAdvance(fgi);
|
||||
|
||||
// for the last character we want to measure the greater of its width and xadvance values
|
||||
// so keep track of the difference between these values for the each character we measure
|
||||
|
|
@ -451,7 +466,8 @@ F32 LLFontGL::getWidthF32(const llwchar* wchars, S32 begin_offset, S32 max_chars
|
|||
&& (next_char < LAST_CHARACTER))
|
||||
{
|
||||
// Kern this puppy.
|
||||
cur_x += mFontFreetype->getXKerning(wch, next_char);
|
||||
next_glyph = mFontFreetype->getGlyphInfo(next_char);
|
||||
cur_x += mFontFreetype->getXKerning(fgi, next_glyph);
|
||||
}
|
||||
// Round after kerning.
|
||||
cur_x = (F32)llround(cur_x);
|
||||
|
|
@ -484,6 +500,8 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch
|
|||
// avoid S32 overflow when max_pixels == S32_MAX by staying in floating point
|
||||
F32 scaled_max_pixels = ceil(max_pixels * sScaleX);
|
||||
F32 width_padding = 0.f;
|
||||
|
||||
LLFontGlyphInfo* next_glyph = NULL;
|
||||
|
||||
S32 i;
|
||||
for (i=0; (i < max_chars); i++)
|
||||
|
|
@ -526,8 +544,13 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch
|
|||
in_word = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
LLFontGlyphInfo* fgi = mFontFreetype->getGlyphInfo(wch);
|
||||
|
||||
LLFontGlyphInfo* fgi = next_glyph;
|
||||
next_glyph = NULL;
|
||||
if(!fgi)
|
||||
{
|
||||
fgi = mFontFreetype->getGlyphInfo(wch);
|
||||
}
|
||||
|
||||
// account for glyphs that run beyond the starting point for the next glyphs
|
||||
width_padding = llmax( 0.f, // always use positive padding amount
|
||||
|
|
@ -546,7 +569,8 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch
|
|||
if (((i+1) < max_chars) && wchars[i+1])
|
||||
{
|
||||
// Kern this puppy.
|
||||
cur_x += mFontFreetype->getXKerning(wch, wchars[i+1]);
|
||||
next_glyph = mFontFreetype->getGlyphInfo(wchars[i+1]);
|
||||
cur_x += mFontFreetype->getXKerning(fgi, next_glyph);
|
||||
}
|
||||
|
||||
// Round after kerning.
|
||||
|
|
@ -593,14 +617,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 )
|
||||
|
|
@ -618,7 +648,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
|
||||
|
|
@ -636,6 +676,8 @@ S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, S32 begin_offset, F32 t
|
|||
const S32 max_index = begin_offset + llmin(S32_MAX - begin_offset, max_chars);
|
||||
|
||||
F32 scaled_max_pixels = max_pixels * sScaleX;
|
||||
|
||||
const LLFontGlyphInfo* next_glyph = NULL;
|
||||
|
||||
S32 pos;
|
||||
for (pos = begin_offset; pos < max_index; pos++)
|
||||
|
|
@ -645,7 +687,15 @@ S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, S32 begin_offset, F32 t
|
|||
{
|
||||
break; // done
|
||||
}
|
||||
F32 char_width = mFontFreetype->getXAdvance(wch);
|
||||
|
||||
const LLFontGlyphInfo* glyph = next_glyph;
|
||||
next_glyph = NULL;
|
||||
if(!glyph)
|
||||
{
|
||||
glyph = mFontFreetype->getGlyphInfo(wch);
|
||||
}
|
||||
|
||||
F32 char_width = mFontFreetype->getXAdvance(glyph);
|
||||
|
||||
if (round)
|
||||
{
|
||||
|
|
@ -671,11 +721,12 @@ S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, S32 begin_offset, F32 t
|
|||
if (((pos + 1) < max_index)
|
||||
&& (wchars[(pos + 1)]))
|
||||
{
|
||||
llwchar next_char = wchars[pos + 1];
|
||||
// Kern this puppy.
|
||||
cur_x += mFontFreetype->getXKerning(wch, next_char);
|
||||
next_glyph = mFontFreetype->getGlyphInfo(wchars[pos + 1]);
|
||||
cur_x += mFontFreetype->getXKerning(glyph, next_glyph);
|
||||
}
|
||||
|
||||
|
||||
// Round after kerning.
|
||||
cur_x = llround(cur_x);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -332,6 +332,8 @@ LLGLManager::LLGLManager() :
|
|||
mHasFragmentShader(FALSE),
|
||||
mHasOcclusionQuery(FALSE),
|
||||
mHasPointParameters(FALSE),
|
||||
mHasDrawBuffers(FALSE),
|
||||
mHasTextureRectangle(FALSE),
|
||||
|
||||
mHasAnisotropic(FALSE),
|
||||
mHasARBEnvCombine(FALSE),
|
||||
|
|
@ -671,7 +673,7 @@ void LLGLManager::initExtensions()
|
|||
llinfos << "initExtensions() checking shell variables to adjust features..." << llendl;
|
||||
// Our extension support for the Linux Client is very young with some
|
||||
// potential driver gotchas, so offer a semi-secret way to turn it off.
|
||||
if (getenv("LL_GL_NOEXT")) /* Flawfinder: ignore */
|
||||
if (getenv("LL_GL_NOEXT"))
|
||||
{
|
||||
//mHasMultitexture = FALSE; // NEEDED!
|
||||
mHasARBEnvCombine = FALSE;
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ hasGamma(false), hasLighting(false), calculatesAtmospherics(false)
|
|||
// LLGLSL Shader implementation
|
||||
//===============================
|
||||
LLGLSLShader::LLGLSLShader()
|
||||
: mProgramObject(0), mShaderLevel(0), mShaderGroup(SG_DEFAULT)
|
||||
: mProgramObject(0), mActiveTextureChannels(0), mShaderLevel(0), mShaderGroup(SG_DEFAULT), mUniformsDirty(FALSE)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -59,6 +59,8 @@ LLPostProcess::LLPostProcess(void) :
|
|||
mSceneRenderTexture = NULL ;
|
||||
mNoiseTexture = NULL ;
|
||||
mTempBloomTexture = NULL ;
|
||||
|
||||
noiseTextureScale = 1.0f;
|
||||
|
||||
/* Do nothing. Needs to be updated to use our current shader system, and to work with the move into llrender.
|
||||
std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight", XML_FILENAME));
|
||||
|
|
|
|||
|
|
@ -737,8 +737,11 @@ void LLTexUnit::debugTextureUnit(void)
|
|||
|
||||
|
||||
LLRender::LLRender()
|
||||
: mDirty(false), mCount(0), mMode(LLRender::TRIANGLES),
|
||||
mMaxAnisotropy(0.f)
|
||||
: mDirty(false),
|
||||
mCount(0),
|
||||
mMode(LLRender::TRIANGLES),
|
||||
mCurrTextureUnitIndex(0),
|
||||
mMaxAnisotropy(0.f)
|
||||
{
|
||||
mBuffer = new LLVertexBuffer(immediate_mask, 0);
|
||||
mBuffer->allocateBuffer(4096, 0, TRUE);
|
||||
|
|
|
|||
|
|
@ -215,14 +215,18 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
|
|||
|
||||
void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const
|
||||
{
|
||||
llassert(mRequestedNumVerts >= 0);
|
||||
|
||||
if (start >= (U32) mRequestedNumVerts ||
|
||||
end >= (U32) mRequestedNumVerts)
|
||||
end >= (U32) mRequestedNumVerts)
|
||||
{
|
||||
llerrs << "Bad vertex buffer draw range: [" << start << ", " << end << "]" << llendl;
|
||||
}
|
||||
|
||||
llassert(mRequestedNumIndices >= 0);
|
||||
|
||||
if (indices_offset >= (U32) mRequestedNumIndices ||
|
||||
indices_offset + count > (U32) mRequestedNumIndices)
|
||||
indices_offset + count > (U32) mRequestedNumIndices)
|
||||
{
|
||||
llerrs << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << llendl;
|
||||
}
|
||||
|
|
@ -251,8 +255,9 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi
|
|||
|
||||
void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
|
||||
{
|
||||
llassert(mRequestedNumIndices >= 0);
|
||||
if (indices_offset >= (U32) mRequestedNumIndices ||
|
||||
indices_offset + count > (U32) mRequestedNumIndices)
|
||||
indices_offset + count > (U32) mRequestedNumIndices)
|
||||
{
|
||||
llerrs << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << llendl;
|
||||
}
|
||||
|
|
@ -281,8 +286,9 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
|
|||
|
||||
void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
|
||||
{
|
||||
llassert(mRequestedNumVerts >= 0);
|
||||
if (first >= (U32) mRequestedNumVerts ||
|
||||
first + count > (U32) mRequestedNumVerts)
|
||||
first + count > (U32) mRequestedNumVerts)
|
||||
{
|
||||
llerrs << "Bad vertex buffer draw range: [" << first << ", " << first+count << "]" << llendl;
|
||||
}
|
||||
|
|
@ -354,7 +360,14 @@ void LLVertexBuffer::clientCopy(F64 max_time)
|
|||
|
||||
LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :
|
||||
LLRefCount(),
|
||||
mNumVerts(0), mNumIndices(0), mUsage(usage), mGLBuffer(0), mGLIndices(0),
|
||||
|
||||
mNumVerts(0),
|
||||
mNumIndices(0),
|
||||
mRequestedNumVerts(-1),
|
||||
mRequestedNumIndices(-1),
|
||||
mUsage(usage),
|
||||
mGLBuffer(0),
|
||||
mGLIndices(0),
|
||||
mMappedData(NULL),
|
||||
mMappedIndexData(NULL), mLocked(FALSE),
|
||||
mFinal(FALSE),
|
||||
|
|
@ -600,6 +613,8 @@ void LLVertexBuffer::updateNumVerts(S32 nverts)
|
|||
{
|
||||
LLMemType mt2(LLMemType::MTYPE_VERTEX_UPDATE_VERTS);
|
||||
|
||||
llassert(nverts >= 0);
|
||||
|
||||
if (nverts >= 65535)
|
||||
{
|
||||
llwarns << "Vertex buffer overflow!" << llendl;
|
||||
|
|
@ -628,6 +643,9 @@ void LLVertexBuffer::updateNumVerts(S32 nverts)
|
|||
void LLVertexBuffer::updateNumIndices(S32 nindices)
|
||||
{
|
||||
LLMemType mt2(LLMemType::MTYPE_VERTEX_UPDATE_INDICES);
|
||||
|
||||
llassert(nindices >= 0);
|
||||
|
||||
mRequestedNumIndices = nindices;
|
||||
if (!mDynamicSize)
|
||||
{
|
||||
|
|
@ -668,6 +686,9 @@ void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)
|
|||
|
||||
void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices)
|
||||
{
|
||||
llassert(newnverts >= 0);
|
||||
llassert(newnindices >= 0);
|
||||
|
||||
mRequestedNumVerts = newnverts;
|
||||
mRequestedNumIndices = newnindices;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -103,6 +103,13 @@ void LLAccordionCtrl::draw()
|
|||
LLLocalClipRect clip(local_rect);
|
||||
|
||||
LLPanel::draw();
|
||||
/*
|
||||
S32 width = getRect().getWidth();
|
||||
S32 height = getRect().getHeight();
|
||||
|
||||
gl_rect_2d(0, 0 , width - 1 ,height - 1,LLColor4::green,true);
|
||||
gl_line_2d(0, 0 , width - 1 ,height - 1,LLColor4::black);
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -338,36 +345,55 @@ void LLAccordionCtrl::addCollapsibleCtrl(LLView* view)
|
|||
|
||||
}
|
||||
|
||||
|
||||
void LLAccordionCtrl::arrange()
|
||||
void LLAccordionCtrl::arrangeSinge()
|
||||
{
|
||||
if( mAccordionTabs.size() == 0)
|
||||
S32 panel_left = BORDER_MARGIN; // Margin from left side of Splitter
|
||||
S32 panel_top = getRect().getHeight() - BORDER_MARGIN; // Top coordinate of the first panel
|
||||
S32 panel_width = getRect().getWidth() - 4; // Top coordinate of the first panel
|
||||
S32 panel_height;
|
||||
|
||||
S32 collapsed_height = 0;
|
||||
|
||||
for(size_t i=0;i<mAccordionTabs.size();++i)
|
||||
{
|
||||
//We do not arrange if we do not have what should be arranged
|
||||
return;
|
||||
LLAccordionCtrlTab* accordion_tab = dynamic_cast<LLAccordionCtrlTab*>(mAccordionTabs[i]);
|
||||
|
||||
if(accordion_tab->getVisible() == false) //skip hidden accordion tabs
|
||||
continue;
|
||||
if(!accordion_tab->isExpanded() )
|
||||
{
|
||||
collapsed_height+=mAccordionTabs[i]->getRect().getHeight();
|
||||
}
|
||||
}
|
||||
|
||||
//Calculate params
|
||||
S32 expanded_height = getRect().getHeight() - BORDER_MARGIN - collapsed_height;
|
||||
|
||||
for(size_t i=0;i<mAccordionTabs.size();++i)
|
||||
{
|
||||
LLAccordionCtrlTab* accordion_tab = dynamic_cast<LLAccordionCtrlTab*>(mAccordionTabs[i]);
|
||||
|
||||
if(accordion_tab->getVisible() == false) //skip hidden accordion tabs
|
||||
continue;
|
||||
if(!accordion_tab->isExpanded() )
|
||||
{
|
||||
panel_height = accordion_tab->getRect().getHeight();
|
||||
}
|
||||
else
|
||||
{
|
||||
panel_height = expanded_height;
|
||||
}
|
||||
ctrlSetLeftTopAndSize(mAccordionTabs[i], panel_left, panel_top, panel_width, panel_height);
|
||||
panel_top-=mAccordionTabs[i]->getRect().getHeight();
|
||||
}
|
||||
}
|
||||
|
||||
void LLAccordionCtrl::arrangeMultiple()
|
||||
{
|
||||
S32 panel_left = BORDER_MARGIN; // Margin from left side of Splitter
|
||||
S32 panel_top = getRect().getHeight() - BORDER_MARGIN; // Top coordinate of the first panel
|
||||
S32 panel_width = getRect().getWidth() - 4; // Top coordinate of the first panel
|
||||
|
||||
|
||||
if(mAccordionTabs.size() == 1)
|
||||
{
|
||||
LLAccordionCtrlTab* accordion_tab = dynamic_cast<LLAccordionCtrlTab*>(mAccordionTabs[0]);
|
||||
|
||||
LLRect panel_rect = accordion_tab->getRect();
|
||||
|
||||
S32 panel_height = getRect().getHeight() - 2*BORDER_MARGIN;
|
||||
|
||||
ctrlSetLeftTopAndSize(accordion_tab,panel_rect.mLeft,panel_top,panel_width,panel_height);
|
||||
|
||||
show_hide_scrollbar(getRect().getWidth(),getRect().getHeight());
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
//Calculate params
|
||||
for(size_t i = 0; i < mAccordionTabs.size(); i++ )
|
||||
{
|
||||
LLAccordionCtrlTab* accordion_tab = dynamic_cast<LLAccordionCtrlTab*>(mAccordionTabs[i]);
|
||||
|
|
@ -415,7 +441,40 @@ void LLAccordionCtrl::arrange()
|
|||
show_hide_scrollbar(getRect().getWidth(),getRect().getHeight());
|
||||
|
||||
updateLayout(getRect().getWidth(),getRect().getHeight());
|
||||
}
|
||||
|
||||
|
||||
void LLAccordionCtrl::arrange()
|
||||
{
|
||||
if( mAccordionTabs.size() == 0)
|
||||
{
|
||||
//We do not arrange if we do not have what should be arranged
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if(mAccordionTabs.size() == 1)
|
||||
{
|
||||
S32 panel_top = getRect().getHeight() - BORDER_MARGIN; // Top coordinate of the first panel
|
||||
S32 panel_width = getRect().getWidth() - 4; // Top coordinate of the first panel
|
||||
|
||||
LLAccordionCtrlTab* accordion_tab = dynamic_cast<LLAccordionCtrlTab*>(mAccordionTabs[0]);
|
||||
|
||||
LLRect panel_rect = accordion_tab->getRect();
|
||||
|
||||
S32 panel_height = getRect().getHeight() - 2*BORDER_MARGIN;
|
||||
|
||||
ctrlSetLeftTopAndSize(accordion_tab,panel_rect.mLeft,panel_top,panel_width,panel_height);
|
||||
|
||||
show_hide_scrollbar(getRect().getWidth(),getRect().getHeight());
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if(mSingleExpansion)
|
||||
arrangeSinge ();
|
||||
else
|
||||
arrangeMultiple ();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -105,6 +105,9 @@ public:
|
|||
void reset ();
|
||||
|
||||
private:
|
||||
void arrangeSinge();
|
||||
void arrangeMultiple();
|
||||
|
||||
// Calc Splitter's height that is necessary to display all child content
|
||||
S32 calcRecuiredHeight();
|
||||
S32 getRecuiredHeight() const { return mInnerRect.getHeight(); }
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
|
@ -258,6 +257,8 @@ public:
|
|||
|
||||
void setForcePressedState(bool b) { mForcePressedState = b; }
|
||||
|
||||
void setAutoResize(bool auto_resize) { mAutoResize = auto_resize; }
|
||||
|
||||
protected:
|
||||
LLPointer<LLUIImage> getImageUnselected() const { return mImageUnselected; }
|
||||
LLPointer<LLUIImage> getImageSelected() const { return mImageSelected; }
|
||||
|
|
@ -328,11 +329,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)
|
||||
{
|
||||
|
|
@ -317,7 +300,8 @@ void LLConsole::Paragraph::updateLines(F32 screen_width, const LLFontGL* font, b
|
|||
S32 paragraph_offset = 0; //Offset into the paragraph text.
|
||||
|
||||
// Wrap lines that are longer than the view is wide.
|
||||
while( paragraph_offset < (S32)mParagraphText.length() )
|
||||
while( paragraph_offset < (S32)mParagraphText.length() &&
|
||||
mParagraphText[paragraph_offset] != 0)
|
||||
{
|
||||
S32 skip_chars; // skip '\n'
|
||||
// Figure out if a word-wrapped line fits here.
|
||||
|
|
@ -383,21 +367,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:
|
||||
|
|
|
|||
|
|
@ -42,8 +42,6 @@ static const LLDefaultChildRegistry::Register<LLFlatListView> flat_list_view("fl
|
|||
const LLSD SELECTED_EVENT = LLSD().with("selected", true);
|
||||
const LLSD UNSELECTED_EVENT = LLSD().with("selected", false);
|
||||
|
||||
static const std::string COMMENT_TEXTBOX = "comment_text";
|
||||
|
||||
//forward declaration
|
||||
bool llsds_are_equal(const LLSD& llsd_1, const LLSD& llsd_2);
|
||||
|
||||
|
|
@ -51,7 +49,8 @@ LLFlatListView::Params::Params()
|
|||
: item_pad("item_pad"),
|
||||
allow_select("allow_select"),
|
||||
multi_select("multi_select"),
|
||||
keep_one_selected("keep_one_selected")
|
||||
keep_one_selected("keep_one_selected"),
|
||||
no_items_text("no_items_text")
|
||||
{};
|
||||
|
||||
void LLFlatListView::reshape(S32 width, S32 height, BOOL called_from_parent /* = TRUE */)
|
||||
|
|
@ -295,19 +294,6 @@ void LLFlatListView::resetSelection(bool no_commit_on_deselection /*= false*/)
|
|||
|
||||
void LLFlatListView::setNoItemsCommentText(const std::string& comment_text)
|
||||
{
|
||||
if (NULL == mNoItemsCommentTextbox)
|
||||
{
|
||||
LLRect comment_rect = getRect();
|
||||
comment_rect.setOriginAndSize(0, 0, comment_rect.getWidth(), comment_rect.getHeight());
|
||||
comment_rect.stretch(-getBorderWidth());
|
||||
LLTextBox::Params text_p;
|
||||
text_p.name(COMMENT_TEXTBOX);
|
||||
text_p.border_visible(false);
|
||||
text_p.rect(comment_rect);
|
||||
text_p.follows.flags(FOLLOWS_ALL);
|
||||
mNoItemsCommentTextbox = LLUICtrlFactory::create<LLTextBox>(text_p, this);
|
||||
}
|
||||
|
||||
mNoItemsCommentTextbox->setValue(comment_text);
|
||||
}
|
||||
|
||||
|
|
@ -361,7 +347,6 @@ bool LLFlatListView::updateValue(const LLSD& old_value, const LLSD& new_value)
|
|||
// PROTECTED STUFF
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
LLFlatListView::LLFlatListView(const LLFlatListView::Params& p)
|
||||
: LLScrollContainer(p)
|
||||
, mItemComparator(NULL)
|
||||
|
|
@ -398,6 +383,25 @@ LLFlatListView::LLFlatListView(const LLFlatListView::Params& p)
|
|||
params.bevel_style(LLViewBorder::BEVEL_IN);
|
||||
mSelectedItemsBorder = LLUICtrlFactory::create<LLViewBorder> (params);
|
||||
mItemsPanel->addChild( mSelectedItemsBorder );
|
||||
|
||||
{
|
||||
// create textbox for "No Items" comment text
|
||||
LLTextBox::Params text_p = p.no_items_text;
|
||||
if (!text_p.rect.isProvided())
|
||||
{
|
||||
LLRect comment_rect = getRect();
|
||||
comment_rect.setOriginAndSize(0, 0, comment_rect.getWidth(), comment_rect.getHeight());
|
||||
comment_rect.stretch(-getBorderWidth());
|
||||
text_p.rect(comment_rect);
|
||||
}
|
||||
text_p.border_visible(false);
|
||||
|
||||
if (!text_p.follows.isProvided())
|
||||
{
|
||||
text_p.follows.flags(FOLLOWS_ALL);
|
||||
}
|
||||
mNoItemsCommentTextbox = LLUICtrlFactory::create<LLTextBox>(text_p, this);
|
||||
}
|
||||
};
|
||||
|
||||
// virtual
|
||||
|
|
@ -861,7 +865,11 @@ void LLFlatListView::notifyParentItemsRectChanged()
|
|||
// take into account comment text height if exists
|
||||
if (mNoItemsCommentTextbox && mNoItemsCommentTextbox->getVisible())
|
||||
{
|
||||
// top text padding inside the textbox is included into the height
|
||||
comment_height = mNoItemsCommentTextbox->getTextPixelHeight();
|
||||
|
||||
// take into account a distance from parent's top border to textbox's top
|
||||
comment_height += getRect().getHeight() - mNoItemsCommentTextbox->getRect().mTop;
|
||||
}
|
||||
|
||||
LLRect req_rect = getItemsRect();
|
||||
|
|
@ -892,6 +900,10 @@ void LLFlatListView::setNoItemsCommentVisible(bool visible) const
|
|||
{
|
||||
if (visible)
|
||||
{
|
||||
/*
|
||||
// *NOTE: MA 2010-02-04
|
||||
// Deprecated after params of the comment text box were moved into widget (flat_list_view.xml)
|
||||
// can be removed later if nothing happened.
|
||||
// We have to update child rect here because of issues with rect after reshaping while creating LLTextbox
|
||||
// It is possible to have invalid LLRect if Flat List is in LLAccordionTab
|
||||
LLRect comment_rect = getLocalRect();
|
||||
|
|
@ -903,6 +915,7 @@ void LLFlatListView::setNoItemsCommentVisible(bool visible) const
|
|||
LLViewBorder* scroll_border = getChild<LLViewBorder>("scroll border");
|
||||
comment_rect.stretch(-scroll_border->getBorderWidth());
|
||||
mNoItemsCommentTextbox->setRect(comment_rect);
|
||||
*/
|
||||
}
|
||||
mNoItemsCommentTextbox->setVisible(visible);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,8 +35,8 @@
|
|||
|
||||
#include "llpanel.h"
|
||||
#include "llscrollcontainer.h"
|
||||
#include "lltextbox.h"
|
||||
|
||||
class LLTextBox;
|
||||
|
||||
/**
|
||||
* LLFlatListView represents a flat list ui control that operates on items in a form of LLPanel's.
|
||||
|
|
@ -108,6 +108,9 @@ public:
|
|||
/** padding between items */
|
||||
Optional<U32> item_pad;
|
||||
|
||||
/** textbox with info message when list is empty*/
|
||||
Optional<LLTextBox::Params> no_items_text;
|
||||
|
||||
Params();
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1565,43 +1565,34 @@ void LLFloater::draw()
|
|||
// draw background
|
||||
if( isBackgroundVisible() )
|
||||
{
|
||||
drawShadow(this);
|
||||
|
||||
S32 left = LLPANEL_BORDER_WIDTH;
|
||||
S32 top = getRect().getHeight() - LLPANEL_BORDER_WIDTH;
|
||||
S32 right = getRect().getWidth() - LLPANEL_BORDER_WIDTH;
|
||||
S32 bottom = LLPANEL_BORDER_WIDTH;
|
||||
|
||||
static LLUICachedControl<S32> shadow_offset_S32 ("DropShadowFloater", 0);
|
||||
static LLUIColor shadow_color_cached = LLUIColorTable::instance().getColor("ColorDropShadow");
|
||||
LLColor4 shadow_color = shadow_color_cached;
|
||||
F32 shadow_offset = (F32)shadow_offset_S32;
|
||||
|
||||
if (!isBackgroundOpaque())
|
||||
{
|
||||
shadow_offset *= 0.2f;
|
||||
shadow_color.mV[VALPHA] *= 0.5f;
|
||||
}
|
||||
gl_drop_shadow(left, top, right, bottom,
|
||||
shadow_color % alpha,
|
||||
llround(shadow_offset));
|
||||
|
||||
LLUIImage* image = NULL;
|
||||
LLColor4 color;
|
||||
LLColor4 overlay_color;
|
||||
if (isBackgroundOpaque())
|
||||
{
|
||||
// NOTE: image may not be set
|
||||
image = getBackgroundImage();
|
||||
color = getBackgroundColor();
|
||||
overlay_color = getBackgroundImageOverlay();
|
||||
}
|
||||
else
|
||||
{
|
||||
image = getTransparentImage();
|
||||
color = getTransparentColor();
|
||||
overlay_color = getTransparentImageOverlay();
|
||||
}
|
||||
|
||||
if (image)
|
||||
{
|
||||
// We're using images for this floater's backgrounds
|
||||
image->draw(getLocalRect(), UI_VERTEX_COLOR % alpha);
|
||||
image->draw(getLocalRect(), overlay_color % alpha);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1650,24 +1641,8 @@ void LLFloater::draw()
|
|||
}
|
||||
else
|
||||
{
|
||||
//FIXME: get rid of this hack
|
||||
// draw children
|
||||
LLView* focused_child = dynamic_cast<LLView*>(gFocusMgr.getKeyboardFocus());
|
||||
BOOL focused_child_visible = FALSE;
|
||||
if (focused_child && focused_child->getParent() == this)
|
||||
{
|
||||
focused_child_visible = focused_child->getVisible();
|
||||
focused_child->setVisible(FALSE);
|
||||
}
|
||||
|
||||
// don't call LLPanel::draw() since we've implemented custom background rendering
|
||||
LLView::draw();
|
||||
|
||||
if (focused_child_visible)
|
||||
{
|
||||
focused_child->setVisible(TRUE);
|
||||
}
|
||||
drawChild(focused_child);
|
||||
}
|
||||
|
||||
// update tearoff button for torn off floaters
|
||||
|
|
@ -1682,6 +1657,29 @@ void LLFloater::draw()
|
|||
}
|
||||
}
|
||||
|
||||
void LLFloater::drawShadow(LLPanel* panel)
|
||||
{
|
||||
F32 alpha = panel->getDrawContext().mAlpha;
|
||||
S32 left = LLPANEL_BORDER_WIDTH;
|
||||
S32 top = panel->getRect().getHeight() - LLPANEL_BORDER_WIDTH;
|
||||
S32 right = panel->getRect().getWidth() - LLPANEL_BORDER_WIDTH;
|
||||
S32 bottom = LLPANEL_BORDER_WIDTH;
|
||||
|
||||
static LLUICachedControl<S32> shadow_offset_S32 ("DropShadowFloater", 0);
|
||||
static LLUIColor shadow_color_cached = LLUIColorTable::instance().getColor("ColorDropShadow");
|
||||
LLColor4 shadow_color = shadow_color_cached;
|
||||
F32 shadow_offset = (F32)shadow_offset_S32;
|
||||
|
||||
if (!panel->isBackgroundOpaque())
|
||||
{
|
||||
shadow_offset *= 0.2f;
|
||||
shadow_color.mV[VALPHA] *= 0.5f;
|
||||
}
|
||||
gl_drop_shadow(left, top, right, bottom,
|
||||
shadow_color % alpha,
|
||||
llround(shadow_offset));
|
||||
}
|
||||
|
||||
void LLFloater::setCanMinimize(BOOL can_minimize)
|
||||
{
|
||||
// if removing minimize/restore button programmatically,
|
||||
|
|
@ -2392,10 +2390,17 @@ void LLFloaterView::adjustToFitScreen(LLFloater* floater, BOOL allow_partial_out
|
|||
LLRect new_rect;
|
||||
new_rect.setLeftTopAndSize(view_rect.mLeft,view_rect.mTop,new_width, new_height);
|
||||
|
||||
floater->reshape( new_width, new_height, TRUE );
|
||||
floater->setRect(new_rect);
|
||||
floater->setShape(new_rect);
|
||||
|
||||
floater->translateIntoRect( getLocalRect(), false );
|
||||
if (floater->followsRight())
|
||||
{
|
||||
floater->translate(old_width - new_width, 0);
|
||||
}
|
||||
|
||||
if (floater->followsTop())
|
||||
{
|
||||
floater->translate(0, old_height - new_height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2579,6 +2584,8 @@ void LLFloaterView::pushVisibleAll(BOOL visible, const skip_list_t& skip_list)
|
|||
view->pushVisible(visible);
|
||||
}
|
||||
}
|
||||
|
||||
LLFloaterReg::blockShowFloaters(true);
|
||||
}
|
||||
|
||||
void LLFloaterView::popVisibleAll(const skip_list_t& skip_list)
|
||||
|
|
@ -2596,6 +2603,8 @@ void LLFloaterView::popVisibleAll(const skip_list_t& skip_list)
|
|||
view->popVisible();
|
||||
}
|
||||
}
|
||||
|
||||
LLFloaterReg::blockShowFloaters(false);
|
||||
}
|
||||
|
||||
void LLFloater::setInstanceName(const std::string& name)
|
||||
|
|
|
|||
|
|
@ -222,6 +222,7 @@ public:
|
|||
virtual BOOL handleScrollWheel(S32 x, S32 y, S32 mask);
|
||||
|
||||
virtual void draw();
|
||||
virtual void drawShadow(LLPanel* panel);
|
||||
|
||||
virtual void onOpen(const LLSD& key) {}
|
||||
virtual void onClose(bool app_quitting) {}
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
|
||||
#include "llfloaterreg.h"
|
||||
|
||||
//#include "llagent.h"
|
||||
#include "llfloater.h"
|
||||
#include "llmultifloater.h"
|
||||
#include "llfloaterreglistener.h"
|
||||
|
|
@ -45,6 +46,7 @@ LLFloaterReg::instance_list_t LLFloaterReg::sNullInstanceList;
|
|||
LLFloaterReg::instance_map_t LLFloaterReg::sInstanceMap;
|
||||
LLFloaterReg::build_map_t LLFloaterReg::sBuildMap;
|
||||
std::map<std::string,std::string> LLFloaterReg::sGroupMap;
|
||||
bool LLFloaterReg::sBlockShowFloaters = false;
|
||||
|
||||
static LLFloaterRegListener sFloaterRegListener;
|
||||
|
||||
|
|
@ -217,6 +219,8 @@ LLFloaterReg::const_instance_list_t& LLFloaterReg::getFloaterList(const std::str
|
|||
//static
|
||||
LLFloater* LLFloaterReg::showInstance(const std::string& name, const LLSD& key, BOOL focus)
|
||||
{
|
||||
if( sBlockShowFloaters )
|
||||
return 0;//
|
||||
LLFloater* instance = getInstance(name, key);
|
||||
if (instance)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -75,6 +75,7 @@ private:
|
|||
static instance_map_t sInstanceMap;
|
||||
static build_map_t sBuildMap;
|
||||
static std::map<std::string,std::string> sGroupMap;
|
||||
static bool sBlockShowFloaters;
|
||||
|
||||
public:
|
||||
// Registration
|
||||
|
|
@ -152,6 +153,8 @@ public:
|
|||
{
|
||||
return dynamic_cast<T*>(showInstance(name, key, focus));
|
||||
}
|
||||
|
||||
static void blockShowFloaters(bool value) { sBlockShowFloaters = value;}
|
||||
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -218,6 +218,86 @@ void LLKeywords::addToken(LLKeywordToken::TOKEN_TYPE type,
|
|||
llassert(0);
|
||||
}
|
||||
}
|
||||
LLKeywords::WStringMapIndex::WStringMapIndex(const WStringMapIndex& other)
|
||||
{
|
||||
if(other.mOwner)
|
||||
{
|
||||
copyData(other.mData, other.mLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
mOwner = false;
|
||||
mLength = other.mLength;
|
||||
mData = other.mData;
|
||||
}
|
||||
}
|
||||
|
||||
LLKeywords::WStringMapIndex::WStringMapIndex(const LLWString& str)
|
||||
{
|
||||
copyData(str.data(), str.size());
|
||||
}
|
||||
|
||||
LLKeywords::WStringMapIndex::WStringMapIndex(const llwchar *start, size_t length):
|
||||
mData(start), mLength(length), mOwner(false)
|
||||
{
|
||||
}
|
||||
|
||||
LLKeywords::WStringMapIndex::~WStringMapIndex()
|
||||
{
|
||||
if(mOwner)
|
||||
delete[] mData;
|
||||
}
|
||||
|
||||
void LLKeywords::WStringMapIndex::copyData(const llwchar *start, size_t length)
|
||||
{
|
||||
llwchar *data = new llwchar[length];
|
||||
memcpy((void*)data, (const void*)start, length * sizeof(llwchar));
|
||||
|
||||
mOwner = true;
|
||||
mLength = length;
|
||||
mData = data;
|
||||
}
|
||||
|
||||
bool LLKeywords::WStringMapIndex::operator<(const LLKeywords::WStringMapIndex &other) const
|
||||
{
|
||||
// NOTE: Since this is only used to organize a std::map, it doesn't matter if it uses correct collate order or not.
|
||||
// The comparison only needs to strictly order all possible strings, and be stable.
|
||||
|
||||
bool result = false;
|
||||
const llwchar* self_iter = mData;
|
||||
const llwchar* self_end = mData + mLength;
|
||||
const llwchar* other_iter = other.mData;
|
||||
const llwchar* other_end = other.mData + other.mLength;
|
||||
|
||||
while(true)
|
||||
{
|
||||
if(other_iter >= other_end)
|
||||
{
|
||||
// We've hit the end of other.
|
||||
// This covers two cases: other being shorter than self, or the strings being equal.
|
||||
// In either case, we want to return false.
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
else if(self_iter >= self_end)
|
||||
{
|
||||
// self is shorter than other.
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
else if(*self_iter != *other_iter)
|
||||
{
|
||||
// The current character differs. The strings are not equal.
|
||||
result = *self_iter < *other_iter;
|
||||
break;
|
||||
}
|
||||
|
||||
self_iter++;
|
||||
other_iter++;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
LLColor3 LLKeywords::readColor( const std::string& s )
|
||||
{
|
||||
|
|
@ -429,7 +509,7 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW
|
|||
S32 seg_len = p - cur;
|
||||
if( seg_len > 0 )
|
||||
{
|
||||
LLWString word( cur, 0, seg_len );
|
||||
WStringMapIndex word( cur, seg_len );
|
||||
word_token_map_t::iterator map_iter = mWordTokenMap.find(word);
|
||||
if( map_iter != mWordTokenMap.end() )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -92,8 +92,33 @@ public:
|
|||
const std::string& key,
|
||||
const LLColor3& color,
|
||||
const std::string& tool_tip = LLStringUtil::null);
|
||||
|
||||
// This class is here as a performance optimization.
|
||||
// The word token map used to be defined as std::map<LLWString, LLKeywordToken*>.
|
||||
// This worked, but caused a performance bottleneck due to memory allocation and string copies
|
||||
// because it's not possible to search such a map without creating an LLWString.
|
||||
// Using this class as the map index instead allows us to search using segments of an existing
|
||||
// text run without copying them first, which greatly reduces overhead in LLKeywords::findSegments().
|
||||
class WStringMapIndex
|
||||
{
|
||||
public:
|
||||
// copy constructor
|
||||
WStringMapIndex(const WStringMapIndex& other);
|
||||
// constructor from a string (copies the string's data into the new object)
|
||||
WStringMapIndex(const LLWString& str);
|
||||
// constructor from pointer and length
|
||||
// NOTE: does NOT copy data, caller must ensure that the lifetime of the pointer exceeds that of the new object!
|
||||
WStringMapIndex(const llwchar *start, size_t length);
|
||||
~WStringMapIndex();
|
||||
bool operator<(const WStringMapIndex &other) const;
|
||||
private:
|
||||
void copyData(const llwchar *start, size_t length);
|
||||
const llwchar *mData;
|
||||
size_t mLength;
|
||||
bool mOwner;
|
||||
};
|
||||
|
||||
typedef std::map<LLWString, LLKeywordToken*> word_token_map_t;
|
||||
typedef std::map<WStringMapIndex, LLKeywordToken*> word_token_map_t;
|
||||
typedef word_token_map_t::const_iterator keyword_iterator_t;
|
||||
keyword_iterator_t begin() const { return mWordTokenMap.begin(); }
|
||||
keyword_iterator_t end() const { return mWordTokenMap.end(); }
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -70,7 +71,7 @@ const S32 SCROLL_INCREMENT_DEL = 4; // make space for baskspacing
|
|||
const F32 AUTO_SCROLL_TIME = 0.05f;
|
||||
const F32 TRIPLE_CLICK_INTERVAL = 0.3f; // delay between double and triple click. *TODO: make this equal to the double click interval?
|
||||
|
||||
const std::string PASSWORD_ASTERISK( "\xE2\x97\x8F" ); // U+25CF BLACK CIRCLE
|
||||
const std::string PASSWORD_ASTERISK( "\xE2\x80\xA2" ); // U+2022 BULLET
|
||||
|
||||
static LLDefaultChildRegistry::Register<LLLineEditor> r1("line_editor");
|
||||
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -657,11 +657,38 @@ LLMenuItemVerticalSeparatorGL::LLMenuItemVerticalSeparatorGL( void )
|
|||
// Class LLMenuItemTearOffGL
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
LLMenuItemTearOffGL::LLMenuItemTearOffGL(const LLMenuItemTearOffGL::Params& p)
|
||||
: LLMenuItemGL(p),
|
||||
mParentHandle(p.parent_floater_handle)
|
||||
: LLMenuItemGL(p)
|
||||
{
|
||||
}
|
||||
|
||||
// Returns the first floater ancestor if there is one
|
||||
LLFloater* LLMenuItemTearOffGL::getParentFloater()
|
||||
{
|
||||
LLView* parent_view = getMenu();
|
||||
|
||||
while (parent_view)
|
||||
{
|
||||
if (dynamic_cast<LLFloater*>(parent_view))
|
||||
{
|
||||
return dynamic_cast<LLFloater*>(parent_view);
|
||||
}
|
||||
|
||||
bool parent_is_menu = dynamic_cast<LLMenuGL*>(parent_view) && !dynamic_cast<LLMenuBarGL*>(parent_view);
|
||||
|
||||
if (parent_is_menu)
|
||||
{
|
||||
// use menu parent
|
||||
parent_view = dynamic_cast<LLMenuGL*>(parent_view)->getParentMenuItem();
|
||||
}
|
||||
else
|
||||
{
|
||||
// just use regular view parent
|
||||
parent_view = parent_view->getParent();
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void LLMenuItemTearOffGL::onCommit()
|
||||
{
|
||||
|
|
@ -680,7 +707,7 @@ void LLMenuItemTearOffGL::onCommit()
|
|||
|
||||
getMenu()->needsArrange();
|
||||
|
||||
LLFloater* parent_floater = mParentHandle.get();
|
||||
LLFloater* parent_floater = getParentFloater();
|
||||
LLFloater* tear_off_menu = LLTearOffMenu::create(getMenu());
|
||||
|
||||
if (tear_off_menu)
|
||||
|
|
@ -1671,7 +1698,6 @@ LLMenuGL::LLMenuGL(const LLMenuGL::Params& p)
|
|||
mSpilloverMenu(NULL),
|
||||
mJumpKey(p.jump_key),
|
||||
mCreateJumpKeys(p.create_jump_keys),
|
||||
mParentFloaterHandle(p.parent_floater),
|
||||
mNeedsArrange(FALSE),
|
||||
mShortcutPad(p.shortcut_pad)
|
||||
{
|
||||
|
|
@ -1699,7 +1725,7 @@ LLMenuGL::LLMenuGL(const LLMenuGL::Params& p)
|
|||
void LLMenuGL::initFromParams(const LLMenuGL::Params& p)
|
||||
{
|
||||
LLUICtrl::initFromParams(p);
|
||||
setCanTearOff(p.can_tear_off, p.parent_floater);
|
||||
setCanTearOff(p.can_tear_off);
|
||||
}
|
||||
|
||||
// Destroys the object
|
||||
|
|
@ -1711,12 +1737,11 @@ LLMenuGL::~LLMenuGL( void )
|
|||
mJumpKeys.clear();
|
||||
}
|
||||
|
||||
void LLMenuGL::setCanTearOff(BOOL tear_off, LLHandle<LLFloater> parent_floater_handle )
|
||||
void LLMenuGL::setCanTearOff(BOOL tear_off)
|
||||
{
|
||||
if (tear_off && mTearOffItem == NULL)
|
||||
{
|
||||
LLMenuItemTearOffGL::Params p;
|
||||
p.parent_floater_handle = parent_floater_handle;
|
||||
mTearOffItem = LLUICtrlFactory::create<LLMenuItemTearOffGL>(p);
|
||||
addChildInBack(mTearOffItem);
|
||||
}
|
||||
|
|
@ -2233,7 +2258,6 @@ void LLMenuGL::createSpilloverBranch()
|
|||
LLMenuGL::Params p;
|
||||
p.name("More");
|
||||
p.label("More"); // *TODO: Translate
|
||||
p.parent_floater(mParentFloaterHandle);
|
||||
p.bg_color(mBackgroundColor);
|
||||
p.bg_visible(true);
|
||||
p.can_tear_off(false);
|
||||
|
|
@ -3941,7 +3965,6 @@ BOOL LLContextMenu::appendContextSubMenu(LLContextMenu *menu)
|
|||
|
||||
item = LLUICtrlFactory::create<LLContextMenuBranch>(p);
|
||||
LLMenuGL::sMenuContainer->addChild(item->getBranch());
|
||||
item->setFont( LLFontGL::getFontSansSerif() );
|
||||
|
||||
return append( item );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -355,7 +355,6 @@ class LLMenuGL
|
|||
public:
|
||||
struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
|
||||
{
|
||||
Optional<LLHandle<LLFloater> > parent_floater;
|
||||
Optional<KEY> jump_key;
|
||||
Optional<bool> horizontal_layout,
|
||||
can_tear_off,
|
||||
|
|
@ -430,7 +429,7 @@ public:
|
|||
void setBackgroundColor( const LLUIColor& color ) { mBackgroundColor = color; }
|
||||
const LLUIColor& getBackgroundColor() const { return mBackgroundColor; }
|
||||
void setBackgroundVisible( BOOL b ) { mBgVisible = b; }
|
||||
void setCanTearOff(BOOL tear_off, LLHandle<LLFloater> parent_floater_handle = LLHandle<LLFloater>());
|
||||
void setCanTearOff(BOOL tear_off);
|
||||
|
||||
// add a separator to this menu
|
||||
virtual BOOL addSeparator();
|
||||
|
|
@ -553,7 +552,6 @@ private:
|
|||
class LLMenuItemTearOffGL* mTearOffItem;
|
||||
class LLMenuItemBranchGL* mSpilloverBranch;
|
||||
LLMenuGL* mSpilloverMenu;
|
||||
LLHandle<LLFloater> mParentFloaterHandle;
|
||||
KEY mJumpKey;
|
||||
BOOL mCreateJumpKeys;
|
||||
S32 mShortcutPad;
|
||||
|
|
@ -814,7 +812,6 @@ class LLMenuItemTearOffGL : public LLMenuItemGL
|
|||
public:
|
||||
struct Params : public LLInitParam::Block<Params, LLMenuItemGL::Params>
|
||||
{
|
||||
Optional<LLHandle<LLFloater> > parent_floater_handle;
|
||||
Params()
|
||||
{
|
||||
name = "tear off";
|
||||
|
|
@ -823,13 +820,12 @@ public:
|
|||
};
|
||||
|
||||
LLMenuItemTearOffGL( const Params& );
|
||||
|
||||
|
||||
virtual void onCommit(void);
|
||||
virtual void draw(void);
|
||||
virtual U32 getNominalHeight() const;
|
||||
|
||||
private:
|
||||
LLHandle<LLFloater> mParentHandle;
|
||||
LLFloater* getParentFloater();
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -371,7 +371,7 @@ private:
|
|||
|
||||
// this is just for making it easy to look things up in a set organized by UUID -- DON'T USE IT
|
||||
// for anything real!
|
||||
LLNotification(LLUUID uuid) : mId(uuid), mCancelled(false), mRespondedTo(false), mIgnored(false), mTemporaryResponder(false) {}
|
||||
LLNotification(LLUUID uuid) : mId(uuid), mCancelled(false), mRespondedTo(false), mIgnored(false), mPriority(NOTIFICATION_PRIORITY_UNSPECIFIED), mTemporaryResponder(false) {}
|
||||
|
||||
void cancel();
|
||||
|
||||
|
|
|
|||
|
|
@ -80,6 +80,8 @@ LLPanel::Params::Params()
|
|||
background_opaque("background_opaque", false),
|
||||
bg_opaque_color("bg_opaque_color"),
|
||||
bg_alpha_color("bg_alpha_color"),
|
||||
bg_opaque_image_overlay("bg_opaque_image_overlay"),
|
||||
bg_alpha_image_overlay("bg_alpha_image_overlay"),
|
||||
bg_opaque_image("bg_opaque_image"),
|
||||
bg_alpha_image("bg_alpha_image"),
|
||||
min_width("min_width", 100),
|
||||
|
|
@ -103,6 +105,8 @@ LLPanel::LLPanel(const LLPanel::Params& p)
|
|||
mBgOpaque(p.background_opaque),
|
||||
mBgOpaqueColor(p.bg_opaque_color()),
|
||||
mBgAlphaColor(p.bg_alpha_color()),
|
||||
mBgOpaqueImageOverlay(p.bg_opaque_image_overlay),
|
||||
mBgAlphaImageOverlay(p.bg_alpha_image_overlay),
|
||||
mBgOpaqueImage(p.bg_opaque_image()),
|
||||
mBgAlphaImage(p.bg_alpha_image()),
|
||||
mDefaultBtn(NULL),
|
||||
|
|
@ -199,7 +203,7 @@ void LLPanel::draw()
|
|||
// opaque, in-front look
|
||||
if (mBgOpaqueImage.notNull())
|
||||
{
|
||||
mBgOpaqueImage->draw( local_rect, UI_VERTEX_COLOR % alpha );
|
||||
mBgOpaqueImage->draw( local_rect, mBgOpaqueImageOverlay % alpha );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -212,7 +216,7 @@ void LLPanel::draw()
|
|||
// transparent, in-back look
|
||||
if (mBgAlphaImage.notNull())
|
||||
{
|
||||
mBgAlphaImage->draw( local_rect, UI_VERTEX_COLOR % alpha );
|
||||
mBgAlphaImage->draw( local_rect, mBgAlphaImageOverlay % alpha );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -397,6 +401,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 +424,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();
|
||||
}
|
||||
|
|
@ -475,6 +485,8 @@ void LLPanel::initFromParams(const LLPanel::Params& p)
|
|||
setTransparentColor(p.bg_alpha_color().get());
|
||||
mBgOpaqueImage = p.bg_opaque_image();
|
||||
mBgAlphaImage = p.bg_alpha_image();
|
||||
mBgOpaqueImageOverlay = p.bg_opaque_image_overlay;
|
||||
mBgAlphaImageOverlay = p.bg_alpha_image_overlay;
|
||||
}
|
||||
|
||||
static LLFastTimer::DeclareTimer FTM_PANEL_SETUP("Panel Setup");
|
||||
|
|
@ -936,7 +948,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)
|
||||
|
|
|
|||
|
|
@ -77,7 +77,9 @@ public:
|
|||
background_opaque;
|
||||
|
||||
Optional<LLUIColor> bg_opaque_color,
|
||||
bg_alpha_color;
|
||||
bg_alpha_color,
|
||||
bg_opaque_image_overlay,
|
||||
bg_alpha_image_overlay;
|
||||
// opaque image is for "panel in foreground" look
|
||||
Optional<LLUIImage*> bg_opaque_image,
|
||||
bg_alpha_image;
|
||||
|
|
@ -137,6 +139,8 @@ public:
|
|||
const LLColor4& getTransparentColor() const { return mBgAlphaColor; }
|
||||
LLPointer<LLUIImage> getBackgroundImage() const { return mBgOpaqueImage; }
|
||||
LLPointer<LLUIImage> getTransparentImage() const { return mBgAlphaImage; }
|
||||
LLColor4 getBackgroundImageOverlay() { return mBgOpaqueImageOverlay; }
|
||||
LLColor4 getTransparentImageOverlay() { return mBgAlphaImageOverlay; }
|
||||
void setBackgroundVisible( BOOL b ) { mBgVisible = b; }
|
||||
BOOL isBackgroundVisible() const { return mBgVisible; }
|
||||
void setBackgroundOpaque(BOOL b) { mBgOpaque = b; }
|
||||
|
|
@ -226,7 +230,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);
|
||||
|
|
@ -262,6 +266,8 @@ private:
|
|||
BOOL mBgOpaque; // use opaque color or image
|
||||
LLUIColor mBgOpaqueColor;
|
||||
LLUIColor mBgAlphaColor;
|
||||
LLUIColor mBgOpaqueImageOverlay;
|
||||
LLUIColor mBgAlphaImageOverlay;
|
||||
LLPointer<LLUIImage> mBgOpaqueImage; // "panel in front" look
|
||||
LLPointer<LLUIImage> mBgAlphaImage; // "panel in back" look
|
||||
LLViewBorder* mBorder;
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ BOOL LLResizeHandle::handleHover(S32 x, S32 y, MASK mask)
|
|||
{
|
||||
// Make sure the mouse in still over the application. We don't want to make the parent
|
||||
// so big that we can't see the resize handle any more.
|
||||
|
||||
|
||||
S32 screen_x;
|
||||
S32 screen_y;
|
||||
localPointToScreen(x, y, &screen_x, &screen_y);
|
||||
|
|
@ -136,9 +136,10 @@ BOOL LLResizeHandle::handleHover(S32 x, S32 y, MASK mask)
|
|||
if( resizing_view )
|
||||
{
|
||||
// undock floater when user resize it
|
||||
if (((LLFloater*)getParent())->isDocked())
|
||||
LLFloater* floater_parent = dynamic_cast<LLFloater*>(getParent());
|
||||
if (floater_parent && floater_parent->isDocked())
|
||||
{
|
||||
((LLFloater*)getParent())->setDocked(false, false);
|
||||
floater_parent->setDocked(false, false);
|
||||
}
|
||||
|
||||
// Resize the parent
|
||||
|
|
@ -146,61 +147,68 @@ BOOL LLResizeHandle::handleHover(S32 x, S32 y, MASK mask)
|
|||
LLRect scaled_rect = orig_rect;
|
||||
S32 delta_x = screen_x - mDragLastScreenX;
|
||||
S32 delta_y = screen_y - mDragLastScreenY;
|
||||
|
||||
if(delta_x == 0 && delta_y == 0)
|
||||
return FALSE;
|
||||
|
||||
LLCoordGL mouse_dir;
|
||||
// use hysteresis on mouse motion to preserve user intent when mouse stops moving
|
||||
mouse_dir.mX = (screen_x == mLastMouseScreenX) ? mLastMouseDir.mX : screen_x - mLastMouseScreenX;
|
||||
mouse_dir.mY = (screen_y == mLastMouseScreenY) ? mLastMouseDir.mY : screen_y - mLastMouseScreenY;
|
||||
|
||||
mLastMouseScreenX = screen_x;
|
||||
mLastMouseScreenY = screen_y;
|
||||
mLastMouseDir = mouse_dir;
|
||||
|
||||
S32 new_width = orig_rect.getWidth();
|
||||
S32 new_height = orig_rect.getHeight();
|
||||
|
||||
S32 new_pos_x = orig_rect.mLeft;
|
||||
S32 new_pos_y = orig_rect.mTop;
|
||||
|
||||
S32 x_multiple = 1;
|
||||
S32 y_multiple = 1;
|
||||
switch( mCorner )
|
||||
{
|
||||
case LEFT_TOP:
|
||||
new_width-=delta_x;
|
||||
new_height+=delta_y;
|
||||
new_pos_x+=delta_x;
|
||||
new_pos_y+=delta_y;
|
||||
x_multiple = -1;
|
||||
y_multiple = 1;
|
||||
break;
|
||||
case LEFT_BOTTOM:
|
||||
new_width-=delta_x;
|
||||
new_height-=delta_y;
|
||||
new_pos_x+=delta_x;
|
||||
x_multiple = -1;
|
||||
y_multiple = -1;
|
||||
break;
|
||||
case RIGHT_TOP:
|
||||
new_width+=delta_x;
|
||||
new_height+=delta_y;
|
||||
new_pos_y+=delta_y;
|
||||
x_multiple = 1;
|
||||
y_multiple = 1;
|
||||
break;
|
||||
case RIGHT_BOTTOM:
|
||||
new_width+=delta_x;
|
||||
new_height-=delta_y;
|
||||
x_multiple = 1;
|
||||
y_multiple = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
S32 new_width = orig_rect.getWidth() + x_multiple * delta_x;
|
||||
if( new_width < mMinWidth )
|
||||
{
|
||||
new_width = mMinWidth;
|
||||
delta_x = x_multiple * (mMinWidth - orig_rect.getWidth());
|
||||
}
|
||||
|
||||
S32 new_height = orig_rect.getHeight() + y_multiple * delta_y;
|
||||
if( new_height < mMinHeight )
|
||||
{
|
||||
new_height = mMinHeight;
|
||||
delta_y = y_multiple * (mMinHeight - orig_rect.getHeight());
|
||||
}
|
||||
|
||||
switch( mCorner )
|
||||
{
|
||||
case LEFT_TOP:
|
||||
scaled_rect.translate(delta_x, 0);
|
||||
break;
|
||||
case LEFT_BOTTOM:
|
||||
scaled_rect.translate(delta_x, delta_y);
|
||||
break;
|
||||
case RIGHT_TOP:
|
||||
break;
|
||||
case RIGHT_BOTTOM:
|
||||
scaled_rect.translate(0, delta_y);
|
||||
break;
|
||||
}
|
||||
|
||||
new_width = llmax(new_width,mMinWidth);
|
||||
new_height = llmax(new_height,mMinHeight);
|
||||
|
||||
LLRect::tCoordType screen_width = resizing_view->getParent()->getSnapRect().getWidth();
|
||||
LLRect::tCoordType screen_height = resizing_view->getParent()->getSnapRect().getHeight();
|
||||
|
||||
new_width = llmin(new_width, screen_width);
|
||||
new_height = llmin(new_height, screen_height);
|
||||
|
||||
// temporarily set new parent rect
|
||||
scaled_rect.setLeftTopAndSize(new_pos_x,new_pos_y,new_width,new_height);
|
||||
|
||||
scaled_rect.mRight = scaled_rect.mLeft + new_width;
|
||||
scaled_rect.mTop = scaled_rect.mBottom + new_height;
|
||||
resizing_view->setRect(scaled_rect);
|
||||
|
||||
LLView* snap_view = NULL;
|
||||
|
|
@ -251,11 +259,7 @@ BOOL LLResizeHandle::handleHover(S32 x, S32 y, MASK mask)
|
|||
resizing_view->setRect(orig_rect);
|
||||
|
||||
// translate and scale to new shape
|
||||
resizing_view->reshape(scaled_rect.getWidth(),scaled_rect.getHeight());
|
||||
resizing_view->setRect(scaled_rect);
|
||||
//set shape to handle dependent floaters...
|
||||
resizing_view->handleReshape(scaled_rect, false);
|
||||
|
||||
resizing_view->setShape(scaled_rect, true);
|
||||
|
||||
// update last valid mouse cursor position based on resized view's actual size
|
||||
LLRect new_rect = resizing_view->getRect();
|
||||
|
|
|
|||
|
|
@ -71,8 +71,9 @@ static LLDefaultChildRegistry::Register<LLScrollListCtrl> r("scroll_list");
|
|||
// local structures & classes.
|
||||
struct SortScrollListItem
|
||||
{
|
||||
SortScrollListItem(const std::vector<std::pair<S32, BOOL> >& sort_orders)
|
||||
SortScrollListItem(const std::vector<std::pair<S32, BOOL> >& sort_orders,const LLScrollListCtrl::sort_signal_t* sort_signal)
|
||||
: mSortOrders(sort_orders)
|
||||
, mSortSignal(sort_signal)
|
||||
{}
|
||||
|
||||
bool operator()(const LLScrollListItem* i1, const LLScrollListItem* i2)
|
||||
|
|
@ -85,12 +86,20 @@ struct SortScrollListItem
|
|||
S32 col_idx = it->first;
|
||||
BOOL sort_ascending = it->second;
|
||||
|
||||
S32 order = sort_ascending ? 1 : -1; // ascending or descending sort for this column?
|
||||
|
||||
const LLScrollListCell *cell1 = i1->getColumn(col_idx);
|
||||
const LLScrollListCell *cell2 = i2->getColumn(col_idx);
|
||||
S32 order = sort_ascending ? 1 : -1; // ascending or descending sort for this column?
|
||||
if (cell1 && cell2)
|
||||
{
|
||||
sort_result = order * LLStringUtil::compareDict(cell1->getValue().asString(), cell2->getValue().asString());
|
||||
if(mSortSignal)
|
||||
{
|
||||
sort_result = order * (*mSortSignal)(col_idx,i1, i2);
|
||||
}
|
||||
else
|
||||
{
|
||||
sort_result = order * LLStringUtil::compareDict(cell1->getValue().asString(), cell2->getValue().asString());
|
||||
}
|
||||
if (sort_result != 0)
|
||||
{
|
||||
break; // we have a sort order!
|
||||
|
|
@ -100,8 +109,10 @@ struct SortScrollListItem
|
|||
|
||||
return sort_result < 0;
|
||||
}
|
||||
|
||||
|
||||
typedef std::vector<std::pair<S32, BOOL> > sort_order_t;
|
||||
const LLScrollListCtrl::sort_signal_t* mSortSignal;
|
||||
const sort_order_t& mSortOrders;
|
||||
};
|
||||
|
||||
|
|
@ -169,6 +180,7 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p)
|
|||
mOnSortChangedCallback( NULL ),
|
||||
mHighlightedItem(-1),
|
||||
mBorder(NULL),
|
||||
mSortCallback(NULL),
|
||||
mPopupMenu(NULL),
|
||||
mNumDynamicWidthColumns(0),
|
||||
mTotalStaticColumnWidth(0),
|
||||
|
|
@ -309,6 +321,8 @@ bool LLScrollListCtrl::preProcessChildNode(LLXMLNodePtr child)
|
|||
|
||||
LLScrollListCtrl::~LLScrollListCtrl()
|
||||
{
|
||||
delete mSortCallback;
|
||||
|
||||
std::for_each(mItemList.begin(), mItemList.end(), DeletePointer());
|
||||
|
||||
if( gEditMenuHandler == this )
|
||||
|
|
@ -540,7 +554,7 @@ BOOL LLScrollListCtrl::addItem( LLScrollListItem* item, EAddPosition pos, BOOL r
|
|||
std::stable_sort(
|
||||
mItemList.begin(),
|
||||
mItemList.end(),
|
||||
SortScrollListItem(single_sort_column));
|
||||
SortScrollListItem(single_sort_column,mSortCallback));
|
||||
|
||||
// ADD_SORTED just sorts by first column...
|
||||
// this might not match user sort criteria, so flag list as being in unsorted state
|
||||
|
|
@ -1388,6 +1402,8 @@ void LLScrollListCtrl::drawItems()
|
|||
|
||||
LLGLSUIDefault gls_ui;
|
||||
|
||||
F32 alpha = getDrawContext().mAlpha;
|
||||
|
||||
{
|
||||
LLLocalClipRect clip(mItemListRect);
|
||||
|
||||
|
|
@ -1463,7 +1479,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;
|
||||
}
|
||||
|
|
@ -2393,7 +2409,7 @@ void LLScrollListCtrl::updateSort() const
|
|||
std::stable_sort(
|
||||
mItemList.begin(),
|
||||
mItemList.end(),
|
||||
SortScrollListItem(mSortColumns));
|
||||
SortScrollListItem(mSortColumns,mSortCallback));
|
||||
|
||||
mSorted = true;
|
||||
}
|
||||
|
|
@ -2409,7 +2425,7 @@ void LLScrollListCtrl::sortOnce(S32 column, BOOL ascending)
|
|||
std::stable_sort(
|
||||
mItemList.begin(),
|
||||
mItemList.end(),
|
||||
SortScrollListItem(sort_column));
|
||||
SortScrollListItem(sort_column,mSortCallback));
|
||||
}
|
||||
|
||||
void LLScrollListCtrl::dirtyColumns()
|
||||
|
|
|
|||
|
|
@ -73,6 +73,32 @@ public:
|
|||
|
||||
// *TODO: Add callbacks to Params
|
||||
typedef boost::function<void (void)> callback_t;
|
||||
|
||||
template<typename T> struct maximum
|
||||
{
|
||||
typedef T result_type;
|
||||
|
||||
template<typename InputIterator>
|
||||
T operator()(InputIterator first, InputIterator last) const
|
||||
{
|
||||
// If there are no slots to call, just return the
|
||||
// default-constructed value
|
||||
if(first == last ) return T();
|
||||
T max_value = *first++;
|
||||
while (first != last) {
|
||||
if (max_value < *first)
|
||||
max_value = *first;
|
||||
++first;
|
||||
}
|
||||
|
||||
return max_value;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//typedef boost::signals2::signal<void (S32,const LLScrollListItem*,const LLScrollListItem*),maximum<S32>> sort_signal_t;
|
||||
//typedef boost::signals2::signal<void (S32,const LLScrollListItem*,const LLScrollListItem*)> sort_signal_t;
|
||||
typedef boost::signals2::signal<S32 (S32,const LLScrollListItem*,const LLScrollListItem*),maximum<S32> > sort_signal_t;
|
||||
|
||||
struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
|
||||
{
|
||||
|
|
@ -362,6 +388,13 @@ public:
|
|||
void setNeedsSort(bool val = true) { mSorted = !val; }
|
||||
void dirtyColumns(); // some operation has potentially affected column layout or ordering
|
||||
|
||||
boost::signals2::connection setSortCallback(sort_signal_t::slot_type cb )
|
||||
{
|
||||
if (!mSortCallback) mSortCallback = new sort_signal_t();
|
||||
return mSortCallback->connect(cb);
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
// "Full" interface: use this when you're creating a list that has one or more of the following:
|
||||
// * contains icons
|
||||
|
|
@ -474,6 +507,8 @@ private:
|
|||
|
||||
typedef std::pair<S32, BOOL> sort_column_t;
|
||||
std::vector<sort_column_t> mSortColumns;
|
||||
|
||||
sort_signal_t* mSortCallback;
|
||||
}; // end class LLScrollListCtrl
|
||||
|
||||
#endif // LL_SCROLLLISTCTRL_H
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
@ -153,7 +156,7 @@ void LLSearchEditor::setFocus( BOOL b )
|
|||
void LLSearchEditor::onClearButtonClick(const LLSD& data)
|
||||
{
|
||||
setText(LLStringUtil::null);
|
||||
mSearchEditor->doDelete(); // force keystroke callback
|
||||
mSearchEditor->onCommit(); // force keystroke callback
|
||||
}
|
||||
|
||||
void LLSearchEditor::handleKeystroke()
|
||||
|
|
|
|||
|
|
@ -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 ));
|
||||
|
|
@ -270,13 +270,19 @@ void LLSpinCtrl::clear()
|
|||
mbHasBeenSet = FALSE;
|
||||
}
|
||||
|
||||
|
||||
void LLSpinCtrl::updateLabelColor()
|
||||
{
|
||||
if( mLabelBox )
|
||||
{
|
||||
mLabelBox->setColor( getEnabled() ? mTextEnabledColor.get() : mTextDisabledColor.get() );
|
||||
}
|
||||
}
|
||||
|
||||
void LLSpinCtrl::updateEditor()
|
||||
{
|
||||
LLLocale locale(LLLocale::USER_LOCALE);
|
||||
|
||||
// Don't display very small negative values as -0.000
|
||||
// Don't display very small negative valu es as -0.000
|
||||
F32 displayed_value = clamp_precision((F32)getValue().asReal(), mPrecision);
|
||||
|
||||
// if( S32( displayed_value * pow( 10, mPrecision ) ) == 0 )
|
||||
|
|
@ -339,10 +345,7 @@ void LLSpinCtrl::setEnabled(BOOL b)
|
|||
{
|
||||
LLView::setEnabled( b );
|
||||
mEditor->setEnabled( b );
|
||||
if( mLabelBox )
|
||||
{
|
||||
mLabelBox->setColor( b ? mTextEnabledColor.get() : mTextDisabledColor.get() );
|
||||
}
|
||||
updateLabelColor();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -390,6 +393,7 @@ void LLSpinCtrl::setLabel(const LLStringExplicit& label)
|
|||
{
|
||||
llwarns << "Attempting to set label on LLSpinCtrl constructed without one " << getName() << llendl;
|
||||
}
|
||||
updateLabelColor();
|
||||
}
|
||||
|
||||
void LLSpinCtrl::setAllowEdit(BOOL allow_edit)
|
||||
|
|
|
|||
|
|
@ -81,8 +81,8 @@ public:
|
|||
virtual void setPrecision(S32 precision);
|
||||
|
||||
void setLabel(const LLStringExplicit& label);
|
||||
void setLabelColor(const LLColor4& c) { mTextEnabledColor = c; }
|
||||
void setDisabledLabelColor(const LLColor4& c) { mTextDisabledColor = c; }
|
||||
void setLabelColor(const LLColor4& c) { mTextEnabledColor = c; updateLabelColor(); }
|
||||
void setDisabledLabelColor(const LLColor4& c) { mTextDisabledColor = c; updateLabelColor();}
|
||||
void setAllowEdit(BOOL allow_edit);
|
||||
|
||||
virtual void onTabInto();
|
||||
|
|
@ -103,6 +103,7 @@ public:
|
|||
void onDownBtn(const LLSD& data);
|
||||
|
||||
private:
|
||||
void updateLabelColor();
|
||||
void updateEditor();
|
||||
void reportInvalidData();
|
||||
|
||||
|
|
|
|||
|
|
@ -59,11 +59,12 @@ public:
|
|||
void setColor(const LLColor4 &color) { mColor = color; }
|
||||
|
||||
const LLColor4& getReadOnlyColor() const { return mReadOnlyColor; }
|
||||
void setReadOnlyColor(const LLColor4& color) { mReadOnlyColor = color; }
|
||||
|
||||
BOOL isVisible() const;
|
||||
void setVisible(BOOL is_visible);
|
||||
|
||||
LLFontGL::ShadowType getShadowType() { return mDropShadow; }
|
||||
LLFontGL::ShadowType getShadowType() const { return mDropShadow; }
|
||||
|
||||
void setFont(const LLFontGL* font);
|
||||
const LLFontGL* getFont() const;
|
||||
|
|
@ -116,5 +117,6 @@ private:
|
|||
};
|
||||
|
||||
typedef LLPointer<LLStyle> LLStyleSP;
|
||||
typedef LLPointer<const LLStyle> LLStyleConstSP;
|
||||
|
||||
#endif // LL_LLSTYLE_H
|
||||
|
|
|
|||
|
|
@ -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,95 @@ 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();
|
||||
}
|
||||
}
|
||||
|
||||
LLIconCtrl* getIconCtrl() const
|
||||
{
|
||||
return mIcon;
|
||||
}
|
||||
|
||||
private:
|
||||
LLIconCtrl* mIcon;
|
||||
LLFontGL::HAlign mIconAlignment;
|
||||
S32 mIconCtrlPad;
|
||||
};
|
||||
//============================================================================
|
||||
|
||||
struct LLPlaceHolderPanel : public LLPanel
|
||||
{
|
||||
// create dummy param block to register with "placeholder" nane
|
||||
|
|
@ -127,7 +215,11 @@ 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"),
|
||||
font_halign("halign")
|
||||
{
|
||||
name(std::string("tab_container"));
|
||||
mouse_opaque = false;
|
||||
|
|
@ -162,7 +254,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 +896,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 +1004,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 +1028,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 +1048,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 +1097,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 +1497,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 +1608,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,31 +1618,48 @@ 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);
|
||||
reshapeTuple(tuple);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
S32 image_overlay_width = 0;
|
||||
|
||||
if(mCustomIconCtrlUsed)
|
||||
{
|
||||
LLCustomButtonIconCtrl* button = dynamic_cast<LLCustomButtonIconCtrl*>(tuple->mButton);
|
||||
LLIconCtrl* icon_ctrl = button->getIconCtrl();
|
||||
image_overlay_width = icon_ctrl ? icon_ctrl->getRect().getWidth() : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
image_overlay_width = tuple->mButton->getImageOverlay().notNull() ?
|
||||
tuple->mButton->getImageOverlay()->getImage()->getWidth(0) : 0;
|
||||
}
|
||||
// remove current width from total tab strip width
|
||||
mTotalTabWidth -= tuple->mButton->getRect().getWidth();
|
||||
|
||||
S32 image_overlay_width = tuple->mButton->getImageOverlay().notNull() ?
|
||||
tuple->mButton->getImageOverlay()->getImage()->getWidth(0) : 0;
|
||||
|
||||
tuple->mPadding = image_overlay_width;
|
||||
|
||||
tuple->mButton->reshape(llclamp(mFont->getWidth(tuple->mButton->getLabelSelected()) + tab_padding + tuple->mPadding, mMinTabWidth, mMaxTabWidth),
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -185,7 +185,7 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p)
|
|||
mWriteableBgColor(p.bg_writeable_color),
|
||||
mReadOnlyBgColor(p.bg_readonly_color),
|
||||
mFocusBgColor(p.bg_focus_color),
|
||||
mReflowNeeded(FALSE),
|
||||
mReflowIndex(S32_MAX),
|
||||
mCursorPos( 0 ),
|
||||
mScrollNeeded(FALSE),
|
||||
mDesiredXPixel(-1),
|
||||
|
|
@ -292,9 +292,13 @@ bool LLTextBase::truncate()
|
|||
return did_truncate;
|
||||
}
|
||||
|
||||
LLStyle::Params LLTextBase::getDefaultStyle()
|
||||
LLStyle::Params LLTextBase::getDefaultStyleParams()
|
||||
{
|
||||
return LLStyle::Params().color(mFgColor.get()).readonly_color(mReadOnlyFgColor.get()).font(mDefaultFont).drop_shadow(mFontShadow);
|
||||
return LLStyle::Params()
|
||||
.color(LLUIColor(&mFgColor))
|
||||
.readonly_color(LLUIColor(&mReadOnlyFgColor))
|
||||
.font(mDefaultFont)
|
||||
.drop_shadow(mFontShadow);
|
||||
}
|
||||
|
||||
void LLTextBase::onValueChange(S32 start, S32 end)
|
||||
|
|
@ -308,7 +312,6 @@ void LLTextBase::drawSelectionBackground()
|
|||
// Draw selection even if we don't have keyboard focus for search/replace
|
||||
if( hasSelection() && !mLineInfoList.empty())
|
||||
{
|
||||
LLWString text = getWText();
|
||||
std::vector<LLRect> selection_rects;
|
||||
|
||||
S32 selection_left = llmin( mSelectionStart, mSelectionEnd );
|
||||
|
|
@ -407,7 +410,7 @@ void LLTextBase::drawCursor()
|
|||
&& gFocusMgr.getAppHasFocus()
|
||||
&& !mReadOnly)
|
||||
{
|
||||
LLWString wtext = getWText();
|
||||
const LLWString &wtext = getWText();
|
||||
const llwchar* text = wtext.c_str();
|
||||
|
||||
LLRect cursor_rect = getLocalRectFromDocIndex(mCursorPos);
|
||||
|
|
@ -493,7 +496,6 @@ void LLTextBase::drawCursor()
|
|||
|
||||
void LLTextBase::drawText()
|
||||
{
|
||||
LLWString text = getWText();
|
||||
const S32 text_len = getLength();
|
||||
if( text_len <= 0 )
|
||||
{
|
||||
|
|
@ -620,7 +622,8 @@ S32 LLTextBase::insertStringNoUndo(S32 pos, const LLWString &wstr, LLTextBase::s
|
|||
else
|
||||
{
|
||||
// create default editable segment to hold new text
|
||||
default_segment = new LLNormalTextSegment( new LLStyle(getDefaultStyle()), pos, pos + insert_len, *this);
|
||||
LLStyleConstSP sp(new LLStyle(getDefaultStyleParams()));
|
||||
default_segment = new LLNormalTextSegment( sp, pos, pos + insert_len, *this);
|
||||
}
|
||||
|
||||
// shift remaining segments to right
|
||||
|
|
@ -657,7 +660,7 @@ S32 LLTextBase::insertStringNoUndo(S32 pos, const LLWString &wstr, LLTextBase::s
|
|||
}
|
||||
|
||||
onValueChange(pos, pos + insert_len);
|
||||
needsReflow();
|
||||
needsReflow(pos);
|
||||
|
||||
return insert_len;
|
||||
}
|
||||
|
|
@ -717,7 +720,7 @@ S32 LLTextBase::removeStringNoUndo(S32 pos, S32 length)
|
|||
createDefaultSegment();
|
||||
|
||||
onValueChange(pos, pos);
|
||||
needsReflow();
|
||||
needsReflow(pos);
|
||||
|
||||
return -length; // This will be wrong if someone calls removeStringNoUndo with an excessive length
|
||||
}
|
||||
|
|
@ -733,7 +736,7 @@ S32 LLTextBase::overwriteCharNoUndo(S32 pos, llwchar wc)
|
|||
getViewModel()->setDisplay(text);
|
||||
|
||||
onValueChange(pos, pos + 1);
|
||||
needsReflow();
|
||||
needsReflow(pos);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -744,7 +747,8 @@ void LLTextBase::createDefaultSegment()
|
|||
// ensures that there is always at least one segment
|
||||
if (mSegments.empty())
|
||||
{
|
||||
LLTextSegmentPtr default_segment = new LLNormalTextSegment( new LLStyle(getDefaultStyle()), 0, getLength() + 1, *this);
|
||||
LLStyleConstSP sp(new LLStyle(getDefaultStyleParams()));
|
||||
LLTextSegmentPtr default_segment = new LLNormalTextSegment( sp, 0, getLength() + 1, *this);
|
||||
mSegments.insert(default_segment);
|
||||
default_segment->linkToDocument(this);
|
||||
}
|
||||
|
|
@ -758,15 +762,18 @@ void LLTextBase::insertSegment(LLTextSegmentPtr segment_to_insert)
|
|||
}
|
||||
|
||||
segment_set_t::iterator cur_seg_iter = getSegIterContaining(segment_to_insert->getStart());
|
||||
S32 reflow_start_index = 0;
|
||||
|
||||
if (cur_seg_iter == mSegments.end())
|
||||
{
|
||||
mSegments.insert(segment_to_insert);
|
||||
segment_to_insert->linkToDocument(this);
|
||||
reflow_start_index = segment_to_insert->getStart();
|
||||
}
|
||||
else
|
||||
{
|
||||
LLTextSegmentPtr cur_segmentp = *cur_seg_iter;
|
||||
reflow_start_index = cur_segmentp->getStart();
|
||||
if (cur_segmentp->getStart() < segment_to_insert->getStart())
|
||||
{
|
||||
S32 old_segment_end = cur_segmentp->getEnd();
|
||||
|
|
@ -774,7 +781,8 @@ void LLTextBase::insertSegment(LLTextSegmentPtr segment_to_insert)
|
|||
cur_segmentp->setEnd(segment_to_insert->getStart());
|
||||
// advance to next segment
|
||||
// insert remainder of old segment
|
||||
LLTextSegmentPtr remainder_segment = new LLNormalTextSegment( cur_segmentp->getStyle(), segment_to_insert->getStart(), old_segment_end, *this);
|
||||
LLStyleConstSP sp = cur_segmentp->getStyle();
|
||||
LLTextSegmentPtr remainder_segment = new LLNormalTextSegment( sp, segment_to_insert->getStart(), old_segment_end, *this);
|
||||
mSegments.insert(cur_seg_iter, remainder_segment);
|
||||
remainder_segment->linkToDocument(this);
|
||||
// insert new segment before remainder of old segment
|
||||
|
|
@ -824,7 +832,7 @@ void LLTextBase::insertSegment(LLTextSegmentPtr segment_to_insert)
|
|||
}
|
||||
|
||||
// layout potentially changed
|
||||
needsReflow();
|
||||
needsReflow(reflow_start_index);
|
||||
}
|
||||
|
||||
BOOL LLTextBase::handleMouseDown(S32 x, S32 y, MASK mask)
|
||||
|
|
@ -1010,16 +1018,6 @@ void LLTextBase::draw()
|
|||
void LLTextBase::setColor( const LLColor4& c )
|
||||
{
|
||||
mFgColor = c;
|
||||
//textsegments have own style property ,
|
||||
//so we have to update it also to apply changes, EXT-4433
|
||||
for(segment_set_t::iterator it = mSegments.begin(); it != mSegments.end(); it++)
|
||||
{
|
||||
LLTextSegment* segment = it->get();
|
||||
if(segment)
|
||||
{
|
||||
segment->setColor(mFgColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//virtual
|
||||
|
|
@ -1028,6 +1026,16 @@ void LLTextBase::setReadOnlyColor(const LLColor4 &c)
|
|||
mReadOnlyFgColor = c;
|
||||
}
|
||||
|
||||
//virtual
|
||||
void LLTextBase::handleVisibilityChange( BOOL new_visibility )
|
||||
{
|
||||
if(!new_visibility && mPopupMenu)
|
||||
{
|
||||
mPopupMenu->hide();
|
||||
}
|
||||
LLUICtrl::handleVisibilityChange(new_visibility);
|
||||
}
|
||||
|
||||
//virtual
|
||||
void LLTextBase::setValue(const LLSD& value )
|
||||
{
|
||||
|
|
@ -1079,15 +1087,16 @@ S32 LLTextBase::getLeftOffset(S32 width)
|
|||
|
||||
|
||||
static LLFastTimer::DeclareTimer FTM_TEXT_REFLOW ("Text Reflow");
|
||||
void LLTextBase::reflow(S32 start_index)
|
||||
void LLTextBase::reflow()
|
||||
{
|
||||
LLFastTimer ft(FTM_TEXT_REFLOW);
|
||||
|
||||
updateSegments();
|
||||
|
||||
while(mReflowNeeded)
|
||||
while(mReflowIndex < S32_MAX)
|
||||
{
|
||||
mReflowNeeded = false;
|
||||
S32 start_index = mReflowIndex;
|
||||
mReflowIndex = S32_MAX;
|
||||
|
||||
// shrink document to minimum size (visible portion of text widget)
|
||||
// to force inlined widgets with follows set to shrink
|
||||
|
|
@ -1119,7 +1128,6 @@ void LLTextBase::reflow(S32 start_index)
|
|||
S32 line_start_index = 0;
|
||||
const S32 text_available_width = mVisibleTextRect.getWidth() - mHPad; // reserve room for margin
|
||||
S32 remaining_pixels = text_available_width;
|
||||
LLWString text(getWText());
|
||||
S32 line_count = 0;
|
||||
|
||||
// find and erase line info structs starting at start_index and going to end of document
|
||||
|
|
@ -1129,6 +1137,7 @@ void LLTextBase::reflow(S32 start_index)
|
|||
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());
|
||||
}
|
||||
|
|
@ -1436,10 +1445,10 @@ LLTextBase::segment_set_t::const_iterator LLTextBase::getSegIterContaining(S32 i
|
|||
}
|
||||
|
||||
// Finds the text segment (if any) at the give local screen position
|
||||
LLTextSegmentPtr LLTextBase::getSegmentAtLocalPos( S32 x, S32 y )
|
||||
LLTextSegmentPtr LLTextBase::getSegmentAtLocalPos( S32 x, S32 y, bool hit_past_end_of_line)
|
||||
{
|
||||
// Find the cursor position at the requested local screen position
|
||||
S32 offset = getDocIndexFromLocalCoord( x, y, FALSE );
|
||||
S32 offset = getDocIndexFromLocalCoord( x, y, FALSE, hit_past_end_of_line);
|
||||
segment_set_t::iterator seg_iter = getSegIterContaining(offset);
|
||||
if (seg_iter != mSegments.end())
|
||||
{
|
||||
|
|
@ -1521,16 +1530,7 @@ std::string LLTextBase::getText() const
|
|||
void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, const LLStyle::Params& input_params)
|
||||
{
|
||||
LLStyle::Params style_params(input_params);
|
||||
style_params.fillFrom(getDefaultStyle());
|
||||
|
||||
if (!style_params.font.isProvided())
|
||||
{
|
||||
style_params.font = mDefaultFont;
|
||||
}
|
||||
if (!style_params.drop_shadow.isProvided())
|
||||
{
|
||||
style_params.drop_shadow = mFontShadow;
|
||||
}
|
||||
style_params.fillFrom(getDefaultStyleParams());
|
||||
|
||||
S32 part = (S32)LLTextParser::WHOLE;
|
||||
if(mParseHTML)
|
||||
|
|
@ -1547,13 +1547,7 @@ void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, c
|
|||
LLStyle::Params link_params = style_params;
|
||||
link_params.color = match.getColor();
|
||||
link_params.readonly_color = match.getColor();
|
||||
// apply font name from requested style_params
|
||||
std::string font_name = LLFontGL::nameFromFont(style_params.font());
|
||||
std::string font_size = LLFontGL::sizeFromFont(style_params.font());
|
||||
link_params.font.name(font_name);
|
||||
link_params.font.size(font_size);
|
||||
link_params.font.style("UNDERLINE");
|
||||
|
||||
link_params.link_href = match.getUrl();
|
||||
|
||||
// output the text before the Url
|
||||
|
|
@ -1581,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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1630,9 +1626,15 @@ void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, c
|
|||
}
|
||||
}
|
||||
|
||||
void LLTextBase::appendAndHighlightText(const std::string &new_text, bool prepend_newline, S32 highlight_part, const LLStyle::Params& stylep)
|
||||
void LLTextBase::needsReflow(S32 index)
|
||||
{
|
||||
if (new_text.empty()) return;
|
||||
lldebugs << "reflow on object " << (void*)this << " index = " << mReflowIndex << ", new index = " << index << llendl;
|
||||
mReflowIndex = llmin(mReflowIndex, index);
|
||||
}
|
||||
|
||||
void LLTextBase::appendAndHighlightText(const std::string &new_text, bool prepend_newline, S32 highlight_part, const LLStyle::Params& style_params)
|
||||
{
|
||||
if (new_text.empty()) return;
|
||||
|
||||
// Save old state
|
||||
S32 selection_start = mSelectionStart;
|
||||
|
|
@ -1650,7 +1652,7 @@ void LLTextBase::appendAndHighlightText(const std::string &new_text, bool prepen
|
|||
|
||||
if (mParseHighlights && highlight)
|
||||
{
|
||||
LLStyle::Params highlight_params = stylep;
|
||||
LLStyle::Params highlight_params(style_params);
|
||||
|
||||
LLSD pieces = highlight->parsePartialLineHighlights(new_text, highlight_params.color(), (LLTextParser::EHighlightPosition)highlight_part);
|
||||
for (S32 i = 0; i < pieces.size(); i++)
|
||||
|
|
@ -1670,7 +1672,8 @@ void LLTextBase::appendAndHighlightText(const std::string &new_text, bool prepen
|
|||
wide_text = utf8str_to_wstring(pieces[i]["text"].asString());
|
||||
}
|
||||
S32 cur_length = getLength();
|
||||
LLTextSegmentPtr segmentp = new LLNormalTextSegment(new LLStyle(highlight_params), cur_length, cur_length + wide_text.size(), *this);
|
||||
LLStyleConstSP sp(new LLStyle(highlight_params));
|
||||
LLTextSegmentPtr segmentp = new LLNormalTextSegment(sp, cur_length, cur_length + wide_text.size(), *this);
|
||||
segment_vec_t segments;
|
||||
segments.push_back(segmentp);
|
||||
insertStringNoUndo(cur_length, wide_text, &segments);
|
||||
|
|
@ -1694,7 +1697,8 @@ void LLTextBase::appendAndHighlightText(const std::string &new_text, bool prepen
|
|||
segment_vec_t segments;
|
||||
S32 segment_start = old_length;
|
||||
S32 segment_end = old_length + wide_text.size();
|
||||
segments.push_back(new LLNormalTextSegment(new LLStyle(stylep), segment_start, segment_end, *this ));
|
||||
LLStyleConstSP sp(new LLStyle(style_params));
|
||||
segments.push_back(new LLNormalTextSegment(sp, segment_start, segment_end, *this ));
|
||||
|
||||
insertStringNoUndo(getLength(), wide_text, &segments);
|
||||
}
|
||||
|
|
@ -1738,7 +1742,7 @@ void LLTextBase::replaceUrlLabel(const std::string &url,
|
|||
for (it = mSegments.begin(); it != mSegments.end(); ++it)
|
||||
{
|
||||
LLTextSegment *seg = *it;
|
||||
const LLStyleSP style = seg->getStyle();
|
||||
LLStyleConstSP style = seg->getStyle();
|
||||
|
||||
// update segment start/end length in case we replaced text earlier
|
||||
S32 seg_length = seg->getEnd() - seg->getStart();
|
||||
|
|
@ -1775,7 +1779,7 @@ void LLTextBase::setWText(const LLWString& text)
|
|||
setText(wstring_to_utf8str(text));
|
||||
}
|
||||
|
||||
LLWString LLTextBase::getWText() const
|
||||
const LLWString& LLTextBase::getWText() const
|
||||
{
|
||||
return getViewModel()->getDisplay();
|
||||
}
|
||||
|
|
@ -1784,7 +1788,7 @@ LLWString LLTextBase::getWText() const
|
|||
// will be put to its right. If round is false, the cursor will always be put to the
|
||||
// character's left.
|
||||
|
||||
S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round ) const
|
||||
S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round, bool hit_past_end_of_line) const
|
||||
{
|
||||
// Figure out which line we're nearest to.
|
||||
LLRect visible_region = getVisibleDocumentRect();
|
||||
|
|
@ -1813,7 +1817,7 @@ S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round
|
|||
S32 text_width, text_height;
|
||||
segmentp->getDimensions(line_seg_offset, segment_line_length, text_width, text_height);
|
||||
if (local_x < start_x + text_width // cursor to left of right edge of text
|
||||
|| segmentp->getEnd() >= line_iter->mDocIndexEnd - 1) // or this segment wraps to next line
|
||||
|| (hit_past_end_of_line && (segmentp->getEnd() >= line_iter->mDocIndexEnd - 1))) // or this segment wraps to next line
|
||||
{
|
||||
// Figure out which character we're nearest to.
|
||||
S32 offset;
|
||||
|
|
@ -2231,9 +2235,9 @@ bool LLTextSegment::canEdit() const { return false; }
|
|||
void LLTextSegment::unlinkFromDocument(LLTextBase*) {}
|
||||
void LLTextSegment::linkToDocument(LLTextBase*) {}
|
||||
const LLColor4& LLTextSegment::getColor() const { return LLColor4::white; }
|
||||
void LLTextSegment::setColor(const LLColor4 &color) {}
|
||||
const LLStyleSP LLTextSegment::getStyle() const {static LLStyleSP sp(new LLStyle()); return sp; }
|
||||
void LLTextSegment::setStyle(const LLStyleSP &style) {}
|
||||
//void LLTextSegment::setColor(const LLColor4 &color) {}
|
||||
LLStyleConstSP LLTextSegment::getStyle() const {static LLStyleConstSP sp(new LLStyle()); return sp; }
|
||||
void LLTextSegment::setStyle(LLStyleConstSP style) {}
|
||||
void LLTextSegment::setToken( LLKeywordToken* token ) {}
|
||||
LLKeywordToken* LLTextSegment::getToken() const { return NULL; }
|
||||
void LLTextSegment::setToolTip( const std::string &msg ) {}
|
||||
|
|
@ -2258,7 +2262,7 @@ BOOL LLTextSegment::hasMouseCapture() { return FALSE; }
|
|||
// LLNormalTextSegment
|
||||
//
|
||||
|
||||
LLNormalTextSegment::LLNormalTextSegment( const LLStyleSP& style, S32 start, S32 end, LLTextBase& editor )
|
||||
LLNormalTextSegment::LLNormalTextSegment( LLStyleConstSP style, S32 start, S32 end, LLTextBase& editor )
|
||||
: LLTextSegment(start, end),
|
||||
mStyle( style ),
|
||||
mToken(NULL),
|
||||
|
|
@ -2269,7 +2273,7 @@ LLNormalTextSegment::LLNormalTextSegment( const LLStyleSP& style, S32 start, S32
|
|||
LLUIImagePtr image = mStyle->getImage();
|
||||
if (image.notNull())
|
||||
{
|
||||
mImageLoadedConnection = image->addLoadedCallback(boost::bind(&LLTextBase::needsReflow, &mEditor));
|
||||
mImageLoadedConnection = image->addLoadedCallback(boost::bind(&LLTextBase::needsReflow, &mEditor, start));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2295,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);
|
||||
|
|
@ -2332,8 +2343,6 @@ F32 LLNormalTextSegment::drawClippedSegment(S32 seg_start, S32 seg_end, S32 sele
|
|||
|
||||
LLColor4 color = (mEditor.getReadOnly() ? mStyle->getReadOnlyColor() : mStyle->getColor()) % alpha;
|
||||
|
||||
font = mStyle->getFont();
|
||||
|
||||
if( selection_start > seg_start )
|
||||
{
|
||||
// Draw normally
|
||||
|
|
@ -2393,8 +2402,12 @@ BOOL LLNormalTextSegment::handleHover(S32 x, S32 y, MASK mask)
|
|||
{
|
||||
if (getStyle() && getStyle()->isLink())
|
||||
{
|
||||
LLUI::getWindow()->setCursor(UI_CURSOR_HAND);
|
||||
return TRUE;
|
||||
// Only process the click if it's actually in this segment, not to the right of the end-of-line.
|
||||
if(mEditor.getSegmentAtLocalPos(x, y, false) == this)
|
||||
{
|
||||
LLUI::getWindow()->setCursor(UI_CURSOR_HAND);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
|
@ -2403,8 +2416,12 @@ BOOL LLNormalTextSegment::handleRightMouseDown(S32 x, S32 y, MASK mask)
|
|||
{
|
||||
if (getStyle() && getStyle()->isLink())
|
||||
{
|
||||
mEditor.createUrlContextMenu(x, y, getStyle()->getLinkHREF());
|
||||
return TRUE;
|
||||
// Only process the click if it's actually in this segment, not to the right of the end-of-line.
|
||||
if(mEditor.getSegmentAtLocalPos(x, y, false) == this)
|
||||
{
|
||||
mEditor.createUrlContextMenu(x, y, getStyle()->getLinkHREF());
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
|
@ -2413,8 +2430,12 @@ BOOL LLNormalTextSegment::handleMouseDown(S32 x, S32 y, MASK mask)
|
|||
{
|
||||
if (getStyle() && getStyle()->isLink())
|
||||
{
|
||||
// eat mouse down event on hyperlinks, so we get the mouse up
|
||||
return TRUE;
|
||||
// Only process the click if it's actually in this segment, not to the right of the end-of-line.
|
||||
if(mEditor.getSegmentAtLocalPos(x, y, false) == this)
|
||||
{
|
||||
// eat mouse down event on hyperlinks, so we get the mouse up
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
|
|
@ -2424,8 +2445,12 @@ BOOL LLNormalTextSegment::handleMouseUp(S32 x, S32 y, MASK mask)
|
|||
{
|
||||
if (getStyle() && getStyle()->isLink())
|
||||
{
|
||||
LLUrlAction::clickAction(getStyle()->getLinkHREF());
|
||||
return TRUE;
|
||||
// Only process the click if it's actually in this segment, not to the right of the end-of-line.
|
||||
if(mEditor.getSegmentAtLocalPos(x, y, false) == this)
|
||||
{
|
||||
LLUrlAction::clickAction(getStyle()->getLinkHREF());
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
|
|
@ -2470,7 +2495,7 @@ bool LLNormalTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& widt
|
|||
if (num_chars > 0)
|
||||
{
|
||||
height = mFontHeight;
|
||||
LLWString text = mEditor.getWText();
|
||||
const LLWString &text = mEditor.getWText();
|
||||
// if last character is a newline, then return true, forcing line break
|
||||
llwchar last_char = text[mStart + first_char + num_chars - 1];
|
||||
if (last_char == '\n')
|
||||
|
|
@ -2497,7 +2522,7 @@ bool LLNormalTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& widt
|
|||
|
||||
S32 LLNormalTextSegment::getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const
|
||||
{
|
||||
LLWString text = mEditor.getWText();
|
||||
const LLWString &text = mEditor.getWText();
|
||||
return mStyle->getFont()->charFromPixelOffset(text.c_str(), mStart + start_offset,
|
||||
(F32)segment_local_x_coord,
|
||||
F32_MAX,
|
||||
|
|
@ -2507,12 +2532,12 @@ S32 LLNormalTextSegment::getOffset(S32 segment_local_x_coord, S32 start_offset,
|
|||
|
||||
S32 LLNormalTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const
|
||||
{
|
||||
LLWString text = mEditor.getWText();
|
||||
const LLWString &text = mEditor.getWText();
|
||||
|
||||
LLUIImagePtr image = mStyle->getImage();
|
||||
if( image.notNull())
|
||||
{
|
||||
num_pixels -= image->getWidth();
|
||||
num_pixels = llmax(0, num_pixels - image->getWidth());
|
||||
}
|
||||
|
||||
// search for newline and if found, truncate there
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@
|
|||
|
||||
class LLContextMenu;
|
||||
class LLTextSegment;
|
||||
class LLNormalTextSegment;
|
||||
|
||||
typedef LLPointer<LLTextSegment> LLTextSegmentPtr;
|
||||
|
||||
|
|
@ -61,6 +62,9 @@ class LLTextBase
|
|||
protected LLEditMenuHandler
|
||||
{
|
||||
public:
|
||||
friend class LLTextSegment;
|
||||
friend class LLNormalTextSegment;
|
||||
|
||||
struct LineSpacingParams : public LLInitParam::Choice<LineSpacingParams>
|
||||
{
|
||||
Alternative<F32> multiple;
|
||||
|
|
@ -122,6 +126,7 @@ public:
|
|||
/*virtual*/ BOOL acceptsTextInput() const { return !mReadOnly; }
|
||||
/*virtual*/ void setColor( const LLColor4& c );
|
||||
virtual void setReadOnlyColor(const LLColor4 &c);
|
||||
virtual void handleVisibilityChange( BOOL new_visibility );
|
||||
|
||||
/*virtual*/ void setValue(const LLSD& value );
|
||||
/*virtual*/ LLTextViewModel* getViewModel() const;
|
||||
|
|
@ -145,11 +150,11 @@ public:
|
|||
|
||||
// wide-char versions
|
||||
void setWText(const LLWString& text);
|
||||
LLWString getWText() const;
|
||||
const LLWString& getWText() const;
|
||||
|
||||
void appendText(const std::string &new_text, bool prepend_newline, const LLStyle::Params& input_params = LLStyle::Params());
|
||||
// force reflow of text
|
||||
void needsReflow() { mReflowNeeded = TRUE; }
|
||||
void needsReflow(S32 index = 0);
|
||||
|
||||
S32 getLength() const { return getWText().length(); }
|
||||
S32 getLineCount() const { return mLineInfoList.size(); }
|
||||
|
|
@ -164,7 +169,7 @@ public:
|
|||
S32 getVPad() { return mVPad; }
|
||||
S32 getHPad() { return mHPad; }
|
||||
|
||||
S32 getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round ) const;
|
||||
S32 getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round, bool hit_past_end_of_line = true) const;
|
||||
LLRect getLocalRectFromDocIndex(S32 pos) const;
|
||||
LLRect getDocRectFromDocIndex(S32 pos) const;
|
||||
|
||||
|
|
@ -185,7 +190,6 @@ public:
|
|||
bool scrolledToEnd();
|
||||
|
||||
const LLFontGL* getDefaultFont() const { return mDefaultFont; }
|
||||
LLStyle::Params getDefaultStyle();
|
||||
|
||||
public:
|
||||
// Fired when a URL link is clicked
|
||||
|
|
@ -275,14 +279,15 @@ protected:
|
|||
// manage segments
|
||||
void getSegmentAndOffset( S32 startpos, segment_set_t::const_iterator* seg_iter, S32* offsetp ) const;
|
||||
void getSegmentAndOffset( S32 startpos, segment_set_t::iterator* seg_iter, S32* offsetp );
|
||||
LLTextSegmentPtr getSegmentAtLocalPos( S32 x, S32 y );
|
||||
LLTextSegmentPtr getSegmentAtLocalPos( S32 x, S32 y, bool hit_past_end_of_line = true);
|
||||
segment_set_t::iterator getSegIterContaining(S32 index);
|
||||
segment_set_t::const_iterator getSegIterContaining(S32 index) const;
|
||||
void clearSegments();
|
||||
void createDefaultSegment();
|
||||
virtual void updateSegments();
|
||||
void insertSegment(LLTextSegmentPtr segment_to_insert);
|
||||
|
||||
LLStyle::Params getDefaultStyleParams();
|
||||
|
||||
// manage lines
|
||||
S32 getLineStart( S32 line ) const;
|
||||
S32 getLineEnd( S32 line ) const;
|
||||
|
|
@ -291,7 +296,7 @@ protected:
|
|||
S32 getFirstVisibleLine() const;
|
||||
std::pair<S32, S32> getVisibleLines(bool fully_visible = false);
|
||||
S32 getLeftOffset(S32 width);
|
||||
void reflow(S32 start_index = 0);
|
||||
void reflow();
|
||||
|
||||
// cursor
|
||||
void updateCursorXPos();
|
||||
|
|
@ -361,7 +366,7 @@ protected:
|
|||
class LLScrollContainer* mScroller;
|
||||
|
||||
// transient state
|
||||
bool mReflowNeeded; // need to reflow text because of change to text contents or display region
|
||||
S32 mReflowIndex; // index at which to start reflow. S32_MAX indicates no reflow needed.
|
||||
bool mScrollNeeded; // need to change scroll region because of change to cursor position
|
||||
S32 mScrollIndex; // index of first character to keep visible in scroll region
|
||||
|
||||
|
|
@ -389,9 +394,9 @@ public:
|
|||
virtual void linkToDocument(class LLTextBase* editor);
|
||||
|
||||
virtual const LLColor4& getColor() const;
|
||||
virtual void setColor(const LLColor4 &color);
|
||||
virtual const LLStyleSP getStyle() const;
|
||||
virtual void setStyle(const LLStyleSP &style);
|
||||
//virtual void setColor(const LLColor4 &color);
|
||||
virtual LLStyleConstSP getStyle() const;
|
||||
virtual void setStyle(LLStyleConstSP style);
|
||||
virtual void setToken( LLKeywordToken* token );
|
||||
virtual LLKeywordToken* getToken() const;
|
||||
virtual void setToolTip(const std::string& tooltip);
|
||||
|
|
@ -427,7 +432,7 @@ protected:
|
|||
class LLNormalTextSegment : public LLTextSegment
|
||||
{
|
||||
public:
|
||||
LLNormalTextSegment( const LLStyleSP& style, S32 start, S32 end, LLTextBase& editor );
|
||||
LLNormalTextSegment( LLStyleConstSP style, S32 start, S32 end, LLTextBase& editor );
|
||||
LLNormalTextSegment( const LLColor4& color, S32 start, S32 end, LLTextBase& editor, BOOL is_visible = TRUE);
|
||||
~LLNormalTextSegment();
|
||||
|
||||
|
|
@ -437,9 +442,8 @@ public:
|
|||
/*virtual*/ F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect);
|
||||
/*virtual*/ bool canEdit() const { return true; }
|
||||
/*virtual*/ const LLColor4& getColor() const { return mStyle->getColor(); }
|
||||
/*virtual*/ void setColor(const LLColor4 &color) { mStyle->setColor(color); }
|
||||
/*virtual*/ const LLStyleSP getStyle() const { return mStyle; }
|
||||
/*virtual*/ void setStyle(const LLStyleSP &style) { mStyle = style; }
|
||||
/*virtual*/ LLStyleConstSP getStyle() const { return mStyle; }
|
||||
/*virtual*/ void setStyle(LLStyleConstSP style) { mStyle = style; }
|
||||
/*virtual*/ void setToken( LLKeywordToken* token ) { mToken = token; }
|
||||
/*virtual*/ LLKeywordToken* getToken() const { return mToken; }
|
||||
/*virtual*/ BOOL getToolTip( std::string& msg ) const;
|
||||
|
|
@ -457,7 +461,7 @@ protected:
|
|||
|
||||
protected:
|
||||
class LLTextBase& mEditor;
|
||||
LLStyleSP mStyle;
|
||||
LLStyleConstSP mStyle;
|
||||
S32 mFontHeight;
|
||||
LLKeywordToken* mToken;
|
||||
std::string mTooltip;
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue