master
Leyla Farazha 2010-09-27 17:54:52 -07:00
commit a4b223248e
584 changed files with 6648 additions and 12527 deletions

View File

@ -22,3 +22,5 @@ c6969fe44e58c542bfc6f1bd6c0be2fa860929ac 2-1-beta-4
d2382d374139850efa5bb6adfb229e3e656cfc40 howard-demo
d40ac9dd949cba6dab1cc386da6a2027690c2519 alpha-5
d6781e22543acd7e21b967209f3c6e7003d380e3 fork to viewer-2-0
c6e6324f5be1401f077ad18a4a0f6b46451c2f7b last_sprint
7076e22f9f43f479a4ea75eac447a36364bead5a beta_2.1.3

View File

@ -78,6 +78,14 @@ brad-parabuild.email = brad@lindenlab.com
brad-parabuild.build_server = false
brad-parabuild.build_server_tests = false
# ========================================
# CG
# ========================================
cg_viewer-development_lenny.collect_metrics = true
cg_viewer-development_lenny.show_changes_since = 4b140ce7839d
cg_viewer-development_lenny.email = cg@lindenlab.com
# ========================================
# gooey
# ========================================

View File

@ -64,7 +64,8 @@ pre_build()
-DVIEWER_LOGIN_CHANNEL:STRING="$login_channel" \
-DINSTALL_PROPRIETARY:BOOL=ON \
-DLOCALIZESETUP:BOOL=ON \
-DPACKAGE:BOOL=ON
-DPACKAGE:BOOL=ON \
-DCMAKE_VERBOSE_MAKEFILE:BOOL=TRUE
end_section "Pre$variant"
}
@ -223,7 +224,10 @@ do
fi
else
begin_section "Build$variant"
build "$variant" "$build_dir" 2>&1 | tee -a "$build_log" | grep --line-buffered "^##teamcity"
build "$variant" "$build_dir" > "$build_log" 2>&1
begin_section Tests
grep --line-buffered "^##teamcity" "$build_log"
end_section Tests
if `cat "$build_dir/build_ok"`
then
echo so far so good.
@ -252,13 +256,15 @@ then
begin_section "Build$variant"
build_dir=`build_dir_$arch $variant`
build_dir_stubs="$build_dir/win_setup/$variant"
tee -a $build_log < "$build_dir/build.log" | grep --line-buffered "^##teamcity"
if `cat "$build_dir/build_ok"`
then
echo so far so good.
else
record_failure "Parallel build of \"$variant\" failed."
fi
begin_section Tests
tee -a $build_log < "$build_dir/build.log" | grep --line-buffered "^##teamcity"
end_section Tests
end_section "Build$variant"
done
end_section WaitParallel
@ -279,6 +285,7 @@ then
succeeded=$build_coverity
else
upload_item installer "$package" binary/octet-stream
upload_item quicklink "$package" binary/octet-stream
# Upload crash reporter files.
case "$last_built_variant" in

View File

@ -20,6 +20,7 @@ Aimee Trescothick
SNOW-227
SNOW-570
SNOW-572
SNOW-575
VWR-3321
VWR-3336
VWR-3903
@ -33,6 +34,7 @@ Aimee Trescothick
VWR-6550
VWR-6583
VWR-6482
VWR-6918
VWR-7109
VWR-7383
VWR-7800
@ -59,13 +61,17 @@ Aimee Trescothick
Alejandro Rosenthal
VWR-1184
Aleric Inglewood
SNOW-522
SNOW-764
VWR-10001
VWR-10759
VWR-10837
VWR-12691
VWR-13996
VWR-14426
SNOW-84
SNOW-766
STORM-163
Ales Beaumont
VWR-9352
SNOW-240
@ -162,7 +168,10 @@ Boroondas Gupte
SNOW-527
SNOW-610
SNOW-624
SNOW-737
VWR-233
VWR-20583
VWR-20891
WEB-262
Bulli Schumann
CT-218
@ -379,6 +388,7 @@ Matthew Dowd
VWR-1761
VWR-2681
McCabe Maxsted
SNOW-387
VWR-1318
VWR-4065
VWR-4826
@ -555,6 +565,7 @@ Robin Cornelius
VWR-12758
VWR-12763
VWR-12995
VWR-20911
Ryozu Kojima
VWR-53
VWR-287
@ -644,9 +655,13 @@ Teardrops Fall
VWR-5366
Techwolf Lupindo
SNOW-92
SNOW-592
SNOW-649
SNOW-650
SNOW-687
SNOW-680
SNOW-681
SNOW-685
SNOW-690
VWR-12385
tenebrous pau
@ -655,9 +670,12 @@ Tharax Ferraris
VWR-605
Thickbrick Sleaford
SNOW-207
SNOW-390
SNOW-421
SNOW-462
SNOW-586
SNOW-592
SNOW-635
SNOW-743
VWR-7109
VWR-9287

View File

@ -221,6 +221,7 @@ elseif(LINUX)
libcrypto.so.0.9.7
libdb-4.2.so
libexpat.so
libexpat.so.1
libgmock_main.so
libgmock.so.0
libgmodule-2.0.so

View File

@ -9,5 +9,5 @@ if (STANDALONE)
else (STANDALONE)
use_prebuilt_binary(libpng)
set(PNG_LIBRARIES png12)
set(PNG_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include)
set(PNG_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/libpng12)
endif (STANDALONE)

View File

@ -54,19 +54,20 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
set(LINUX ON BOOl FORCE)
# If someone has specified a word size, use that to determine the
# architecture. Otherwise, let the architecture specify the word size.
# architecture. Otherwise, let the compiler specify the word size.
# Using uname will break under chroots and other cross arch compiles. RC
if (WORD_SIZE EQUAL 32)
set(ARCH i686)
elseif (WORD_SIZE EQUAL 64)
set(ARCH x86_64)
else (WORD_SIZE EQUAL 32)
execute_process(COMMAND uname -m COMMAND sed s/i.86/i686/
OUTPUT_VARIABLE ARCH OUTPUT_STRIP_TRAILING_WHITESPACE)
if (ARCH STREQUAL x86_64)
set(WORD_SIZE 64)
else (ARCH STREQUAL x86_64)
if(CMAKE_SIZEOF_VOID_P MATCHES 4)
set(ARCH i686)
set(WORD_SIZE 32)
endif (ARCH STREQUAL x86_64)
else(CMAKE_SIZEOF_VOID_P MATCHES 4)
set(ARCH x86_64)
set(WORD_SIZE 64)
endif(CMAKE_SIZEOF_VOID_P MATCHES 4)
endif (WORD_SIZE EQUAL 32)
set(LL_ARCH ${ARCH}_linux)

View File

@ -82,10 +82,24 @@ def main(command, libpath=[], vars={}):
dirs = os.environ.get(var, "").split(os.pathsep)
# Append the sequence in libpath
print "%s += %r" % (var, libpath)
dirs.extend(libpath)
for dir in libpath:
# append system paths at the end
if dir in ('/lib', '/usr/lib'):
dirs.append(dir)
# prepend non-system paths
else:
dirs.insert(0, dir)
# Filter out some useless pieces
clean_dirs = []
for dir in dirs:
if dir and dir not in ('', '.'):
clean_dirs.append(dir)
# Now rebuild the path string. This way we use a minimum of separators
# -- and we avoid adding a pointless separator when libpath is empty.
os.environ[var] = os.pathsep.join(dirs)
os.environ[var] = os.pathsep.join(clean_dirs)
print "%s = %r" % (var, os.environ[var])
# Now handle arbitrary environment variables. The tricky part is ensuring
# that all the keys and values we try to pass are actually strings.
if vars:

View File

@ -185,10 +185,9 @@ void export_test_floaters()
// Build a floater and output new attributes
LLXMLNodePtr output_node = new LLXMLNode();
LLFloater* floater = new LLFloater(LLSD());
LLUICtrlFactory::getInstance()->buildFloater(floater,
filename,
// FALSE, // don't open floater
output_node);
floater->buildFromFile( filename,
// FALSE, // don't open floater
output_node);
std::string out_filename = xui_dir + filename;
std::string::size_type extension_pos = out_filename.rfind(".xml");
out_filename.resize(extension_pos);

View File

@ -78,7 +78,7 @@ void LLWidgetReg::initClass(bool register_widgets)
LLDefaultChildRegistry::Register<LLMultiSlider> multi_slider_bar("multi_slider_bar");
LLDefaultChildRegistry::Register<LLMultiSliderCtrl> multi_slider("multi_slider");
LLDefaultChildRegistry::Register<LLPanel> panel("panel", &LLPanel::fromXML);
LLDefaultChildRegistry::Register<LLLayoutStack> layout_stack("layout_stack", &LLLayoutStack::fromXML);
LLDefaultChildRegistry::Register<LLLayoutStack> layout_stack("layout_stack");
LLDefaultChildRegistry::Register<LLProgressBar> progress_bar("progress_bar");
LLDefaultChildRegistry::Register<LLRadioGroup> radio_group("radio_group");
LLDefaultChildRegistry::Register<LLSearchEditor> search_editor("search_editor");

View File

@ -36,14 +36,6 @@ import os.path
import re
import time
#import sys # *TODO: remove. only used in testing.
#import pprint # *TODO: remove. only used in testing.
try:
set = set
except NameError:
from sets import Set as set
from indra.base import llsd
from indra.base import config
@ -195,8 +187,6 @@ class NamedQuery(object):
style. It also has to look for %:name% and :name% and
ready them for use in LIKE statements"""
if sql:
#print >>sys.stderr, "sql:",sql
# This first sub is to properly escape any % signs that
# are meant to be literally passed through to mysql in the
# query. It leaves any %'s that are used for
@ -408,7 +398,6 @@ class NamedQuery(object):
# build the query from the options available and the params
base_query = []
base_query.append(self._base_query)
#print >>sys.stderr, "base_query:",base_query
for opt, extra_where in self._options.items():
if type(extra_where) in (dict, list, tuple):
if opt in params:
@ -418,7 +407,6 @@ class NamedQuery(object):
base_query.append(extra_where)
if self._query_suffix:
base_query.append(self._query_suffix)
#print >>sys.stderr, "base_query:",base_query
full_query = '\n'.join(base_query)
# Go through the query and rewrite all of the ones with the

View File

@ -446,8 +446,14 @@ def uuid1(node=None, clock_seq=None):
def uuid3(namespace, name):
"""Generate a UUID from the MD5 hash of a namespace UUID and a name."""
import md5
hash = md5.md5(namespace.bytes + name).digest()
try:
# Python 2.6
from hashlib import md5
except ImportError:
# Python 2.5 and earlier
from md5 import new as md5
hash = md5(namespace.bytes + name).digest()
return UUID(bytes=hash[:16], version=3)
def uuid4():

View File

@ -97,6 +97,7 @@ void LLAudioEngine::setDefaults()
}
mMasterGain = 1.f;
mInternalGain = 0.f;
mNextWindUpdate = 0.f;
mStreamingAudioImpl = NULL;
@ -247,15 +248,6 @@ void LLAudioEngine::idle(F32 max_decode_time)
// Primarily does position updating, cleanup of unused audio sources.
// Also does regeneration of the current priority of each audio source.
if (getMuted())
{
setInternalGain(0.f);
}
else
{
setInternalGain(getMasterGain());
}
S32 i;
for (i = 0; i < MAX_BUFFERS; i++)
{
@ -284,6 +276,12 @@ void LLAudioEngine::idle(F32 max_decode_time)
continue;
}
if (sourcep->isMuted())
{
++iter;
continue;
}
if (!sourcep->getChannel() && sourcep->getCurrentBuffer())
{
// We could potentially play this sound if its priority is high enough.
@ -336,9 +334,9 @@ void LLAudioEngine::idle(F32 max_decode_time)
// attached to each channel, since only those with active channels
// can have anything interesting happen with their queue? (Maybe not true)
LLAudioSource *sourcep = iter->second;
if (!sourcep->mQueuedDatap)
if (!sourcep->mQueuedDatap || sourcep->isMuted())
{
// Nothing queued, so we don't care.
// Muted, or nothing queued, so we don't care.
continue;
}
@ -418,6 +416,10 @@ void LLAudioEngine::idle(F32 max_decode_time)
for (iter = mAllSources.begin(); iter != mAllSources.end(); ++iter)
{
LLAudioSource *sourcep = iter->second;
if (sourcep->isMuted())
{
continue;
}
if (sourcep->isSyncMaster())
{
if (sourcep->getPriority() > max_sm_priority)
@ -691,15 +693,23 @@ bool LLAudioEngine::isWindEnabled()
void LLAudioEngine::setMuted(bool muted)
{
mMuted = muted;
if (muted != mMuted)
{
mMuted = muted;
setMasterGain(mMasterGain);
}
enableWind(!mMuted);
}
void LLAudioEngine::setMasterGain(const F32 gain)
{
mMasterGain = gain;
setInternalGain(gain);
F32 internal_gain = getMuted() ? 0.f : gain;
if (internal_gain != mInternalGain)
{
mInternalGain = internal_gain;
setInternalGain(mInternalGain);
}
}
F32 LLAudioEngine::getMasterGain()
@ -1243,13 +1253,14 @@ LLAudioSource::LLAudioSource(const LLUUID& id, const LLUUID& owner_id, const F32
mOwnerID(owner_id),
mPriority(0.f),
mGain(gain),
mType(type),
mSourceMuted(false),
mAmbient(false),
mLoop(false),
mSyncMaster(false),
mSyncSlave(false),
mQueueSounds(false),
mPlayedOnce(false),
mType(type),
mChannelp(NULL),
mCurrentDatap(NULL),
mQueuedDatap(NULL)
@ -1301,6 +1312,10 @@ void LLAudioSource::updatePriority()
{
mPriority = 1.f;
}
else if (isMuted())
{
mPriority = 0.f;
}
else
{
// Priority is based on distance
@ -1349,25 +1364,33 @@ bool LLAudioSource::setupChannel()
bool LLAudioSource::play(const LLUUID &audio_uuid)
{
// Special abuse of play(); don't play a sound, but kill it.
if (audio_uuid.isNull())
{
if (getChannel())
{
getChannel()->setSource(NULL);
setChannel(NULL);
addAudioData(NULL, true);
if (!isMuted())
{
mCurrentDatap = NULL;
}
}
return false;
}
// Reset our age timeout if someone attempts to play the source.
mAgeTimer.reset();
LLAudioData *adp = gAudiop->getAudioData(audio_uuid);
bool has_buffer = gAudiop->updateBufferForData(adp, audio_uuid);
addAudioData(adp);
if (isMuted())
{
return false;
}
bool has_buffer = gAudiop->updateBufferForData(adp, audio_uuid);
if (!has_buffer)
{
// Don't bother trying to set up a channel or anything, we don't have an audio buffer.
@ -1392,10 +1415,11 @@ bool LLAudioSource::play(const LLUUID &audio_uuid)
}
bool LLAudioSource::isDone()
bool LLAudioSource::isDone() const
{
const F32 MAX_AGE = 60.f;
const F32 MAX_UNPLAYED_AGE = 15.f;
const F32 MAX_MUTED_AGE = 11.f;
if (isLoop())
{
@ -1403,7 +1427,6 @@ bool LLAudioSource::isDone()
return false;
}
if (hasPendingPreloads())
{
return false;
@ -1420,10 +1443,10 @@ bool LLAudioSource::isDone()
// This is a single-play source
if (!mChannelp)
{
if ((elapsed > MAX_UNPLAYED_AGE) || mPlayedOnce)
if ((elapsed > (mSourceMuted ? MAX_MUTED_AGE : MAX_UNPLAYED_AGE)) || mPlayedOnce)
{
// We don't have a channel assigned, and it's been
// over 5 seconds since we tried to play it. Don't bother.
// over 15 seconds since we tried to play it. Don't bother.
//llinfos << "No channel assigned, source is done" << llendl;
return true;
}
@ -1449,7 +1472,7 @@ bool LLAudioSource::isDone()
if ((elapsed > MAX_UNPLAYED_AGE) || mPlayedOnce)
{
// The sound isn't playing back after 5 seconds or we're already done playing it, kill it.
// The sound isn't playing back after 15 seconds or we're already done playing it, kill it.
return true;
}

View File

@ -118,8 +118,8 @@ public:
// Use these for temporarily muting the audio system.
// Does not change buffers, initialization, etc. but
// stops playing new sounds.
virtual void setMuted(bool muted);
virtual bool getMuted() const { return mMuted; }
void setMuted(bool muted);
bool getMuted() const { return mMuted; }
#ifdef USE_PLUGIN_MEDIA
LLPluginClassMedia* initializeMedia(const std::string& media_type);
#endif
@ -239,6 +239,7 @@ protected:
LLAudioBuffer *mBuffers[MAX_BUFFERS];
F32 mMasterGain;
F32 mInternalGain; // Actual gain set; either mMasterGain or 0 when mMuted is true.
F32 mSecondaryGain[AUDIO_TYPE_COUNT];
F32 mNextWindUpdate;
@ -303,7 +304,8 @@ public:
virtual void setGain(const F32 gain) { mGain = llclamp(gain, 0.f, 1.f); }
const LLUUID &getID() const { return mID; }
bool isDone();
bool isDone() const;
bool isMuted() const { return mSourceMuted; }
LLAudioData *getCurrentData();
LLAudioData *getQueuedData();
@ -325,6 +327,7 @@ protected:
LLUUID mOwnerID; // owner of the object playing the sound
F32 mPriority;
F32 mGain;
bool mSourceMuted;
bool mAmbient;
bool mLoop;
bool mSyncMaster;

View File

@ -159,6 +159,7 @@ set(llcommon_HEADER_FILES
lleventemitter.h
llextendedstatus.h
llfasttimer.h
llfasttimer_class.h
llfile.h
llfindlocale.h
llfixedbuffer.h

View File

@ -469,9 +469,9 @@ void LLFastTimer::NamedTimer::accumulateTimings()
int hidx = cur_frame % HISTORY_NUM;
timerp->mCountHistory[hidx] = timerp->mTotalTimeCounter;
timerp->mCountAverage = (timerp->mCountAverage * cur_frame + timerp->mTotalTimeCounter) / (cur_frame+1);
timerp->mCountAverage = ((U64)timerp->mCountAverage * cur_frame + timerp->mTotalTimeCounter) / (cur_frame+1);
timerp->mCallHistory[hidx] = timerp->getFrameState().mCalls;
timerp->mCallAverage = (timerp->mCallAverage * cur_frame + timerp->getFrameState().mCalls) / (cur_frame+1);
timerp->mCallAverage = ((U64)timerp->mCallAverage * cur_frame + timerp->getFrameState().mCalls) / (cur_frame+1);
}
}
}

View File

@ -1115,7 +1115,7 @@ bool LLStringUtil::formatDatetime(std::string& replacement, std::string token,
else if(LLStringOps::sMonthList.size() == 12 && code == "%B")
{
struct tm * gmt = gmtime (&loc_seconds);
replacement = LLStringOps::sWeekDayList[gmt->tm_mon];
replacement = LLStringOps::sMonthList[gmt->tm_mon];
}
else if( !LLStringOps::sDayFormat.empty() && code == "%d" )
{

View File

@ -28,8 +28,8 @@
#define LL_LLVERSIONVIEWER_H
const S32 LL_VERSION_MAJOR = 2;
const S32 LL_VERSION_MINOR = 1;
const S32 LL_VERSION_PATCH = 2;
const S32 LL_VERSION_MINOR = 2;
const S32 LL_VERSION_PATCH = 1;
const S32 LL_VERSION_BUILD = 0;
const char * const LL_CHANNEL = "Second Life Developer";

View File

@ -113,8 +113,8 @@ enum EObjectPropertiesExtraID
enum EAddPosition
{
ADD_TOP,
ADD_SORTED,
ADD_BOTTOM
ADD_BOTTOM,
ADD_DEFAULT
};
enum LLGroupChange

View File

@ -210,7 +210,7 @@ void LLPngWrapper::normalizeImage()
}
if (mColorType == PNG_COLOR_TYPE_GRAY && mBitDepth < 8)
{
png_set_gray_1_2_4_to_8(mReadPngPtr);
png_set_expand_gray_1_2_4_to_8(mReadPngPtr);
}
if (mColorType == PNG_COLOR_TYPE_GRAY
|| mColorType == PNG_COLOR_TYPE_GRAY_ALPHA)
@ -358,7 +358,7 @@ void LLPngWrapper::releaseResources()
{
if (mReadPngPtr || mReadInfoPtr)
{
png_destroy_read_struct(&mReadPngPtr, &mReadInfoPtr, png_infopp_NULL);
png_destroy_read_struct(&mReadPngPtr, &mReadInfoPtr, NULL);
mReadPngPtr = NULL;
mReadInfoPtr = NULL;
}

View File

@ -26,7 +26,7 @@
#ifndef LL_LLPNGWRAPPER_H
#define LL_LLPNGWRAPPER_H
#include "libpng12/png.h"
#include "png.h"
#include "llimage.h"
class LLPngWrapper

View File

@ -74,6 +74,7 @@ bool LLPluginClassMedia::init(const std::string &launcher_filename, const std::s
// Queue up the media init message -- it will be sent after all the currently queued messages.
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "init");
message.setValue("target", mTarget);
sendMessage(message);
mPlugin->init(launcher_filename, plugin_filename, debug);
@ -143,7 +144,7 @@ void LLPluginClassMedia::reset()
mProgressPercent = 0;
mClickURL.clear();
mClickTarget.clear();
mClickTargetType = TARGET_NONE;
mClickUUID.clear();
// media_time class
mCurrentTime = 0.0f;
@ -669,6 +670,18 @@ F64 LLPluginClassMedia::getCPUUsage()
return result;
}
void LLPluginClassMedia::sendPickFileResponse(const std::string &file)
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "pick_file_response");
message.setValue("file", file);
if(mPlugin->isBlocked())
{
// If the plugin sent a blocking pick-file request, the response should unblock it.
message.setValueBoolean("blocking_response", true);
}
sendMessage(message);
}
void LLPluginClassMedia::cut()
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_cut");
@ -715,24 +728,9 @@ void LLPluginClassMedia::setJavascriptEnabled(const bool enabled)
sendMessage(message);
}
LLPluginClassMedia::ETargetType getTargetTypeFromLLQtWebkit(int target_type)
void LLPluginClassMedia::setTarget(const std::string &target)
{
// convert a LinkTargetType value from llqtwebkit to an ETargetType
// so that we don't expose the llqtwebkit header in viewer code
switch (target_type)
{
case LLQtWebKit::LTT_TARGET_NONE:
return LLPluginClassMedia::TARGET_NONE;
case LLQtWebKit::LTT_TARGET_BLANK:
return LLPluginClassMedia::TARGET_BLANK;
case LLQtWebKit::LTT_TARGET_EXTERNAL:
return LLPluginClassMedia::TARGET_EXTERNAL;
default:
return LLPluginClassMedia::TARGET_OTHER;
}
mTarget = target;
}
/* virtual */
@ -945,6 +943,10 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
mMediaName = message.getValue("name");
mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_NAME_CHANGED);
}
else if(message_name == "pick_file")
{
mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_PICK_FILE_REQUEST);
}
else
{
LL_WARNS("Plugin") << "Unknown " << message_name << " class message: " << message_name << LL_ENDL;
@ -987,15 +989,13 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
{
mClickURL = message.getValue("uri");
mClickTarget = message.getValue("target");
U32 target_type = message.getValueU32("target_type");
mClickTargetType = ::getTargetTypeFromLLQtWebkit(target_type);
mClickUUID = message.getValue("uuid");
mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_CLICK_LINK_HREF);
}
else if(message_name == "click_nofollow")
{
mClickURL = message.getValue("uri");
mClickTarget.clear();
mClickTargetType = TARGET_NONE;
mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_CLICK_LINK_NOFOLLOW);
}
else if(message_name == "cookie_set")
@ -1005,6 +1005,20 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
mOwner->handleCookieSet(this, message.getValue("cookie"));
}
}
else if(message_name == "close_request")
{
mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_CLOSE_REQUEST);
}
else if(message_name == "geometry_change")
{
mClickUUID = message.getValue("uuid");
mGeometryX = message.getValueS32("x");
mGeometryY = message.getValueS32("y");
mGeometryWidth = message.getValueS32("width");
mGeometryHeight = message.getValueS32("height");
mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_GEOMETRY_CHANGE);
}
else
{
LL_WARNS("Plugin") << "Unknown " << message_name << " class message: " << message_name << LL_ENDL;
@ -1159,6 +1173,25 @@ void LLPluginClassMedia::setBrowserUserAgent(const std::string& user_agent)
sendMessage(message);
}
void LLPluginClassMedia::proxyWindowOpened(const std::string &target, const std::string &uuid)
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "proxy_window_opened");
message.setValue("target", target);
message.setValue("uuid", uuid);
sendMessage(message);
}
void LLPluginClassMedia::proxyWindowClosed(const std::string &uuid)
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "proxy_window_closed");
message.setValue("uuid", uuid);
sendMessage(message);
}
void LLPluginClassMedia::crashPlugin()
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "crash");

View File

@ -156,6 +156,8 @@ public:
void setLowPrioritySizeLimit(int size);
F64 getCPUUsage();
void sendPickFileResponse(const std::string &file);
// Valid after a MEDIA_EVENT_CURSOR_CHANGED event
std::string getCursorName() const { return mCursorName; };
@ -176,7 +178,8 @@ public:
void setLanguageCode(const std::string &language_code);
void setPluginsEnabled(const bool enabled);
void setJavascriptEnabled(const bool enabled);
void setTarget(const std::string &target);
///////////////////////////////////
// media browser class functions
bool pluginSupportsMediaBrowser(void);
@ -193,6 +196,8 @@ public:
void browse_back();
void set_status_redirect(int code, const std::string &url);
void setBrowserUserAgent(const std::string& user_agent);
void proxyWindowOpened(const std::string &target, const std::string &uuid);
void proxyWindowClosed(const std::string &uuid);
// This is valid after MEDIA_EVENT_NAVIGATE_BEGIN or MEDIA_EVENT_NAVIGATE_COMPLETE
std::string getNavigateURI() const { return mNavigateURI; };
@ -218,16 +223,14 @@ public:
// This is valid after MEDIA_EVENT_CLICK_LINK_HREF
std::string getClickTarget() const { return mClickTarget; };
typedef enum
{
TARGET_NONE, // empty href target string
TARGET_BLANK, // target to open link in user's preferred browser
TARGET_EXTERNAL, // target to open link in external browser
TARGET_OTHER // nonempty and unsupported target type
}ETargetType;
// This is valid after MEDIA_EVENT_CLICK_LINK_HREF
ETargetType getClickTargetType() const { return mClickTargetType; };
// This is valid during MEDIA_EVENT_CLICK_LINK_HREF and MEDIA_EVENT_GEOMETRY_CHANGE
std::string getClickUUID() const { return mClickUUID; };
// These are valid during MEDIA_EVENT_GEOMETRY_CHANGE
S32 getGeometryX() const { return mGeometryX; };
S32 getGeometryY() const { return mGeometryY; };
S32 getGeometryWidth() const { return mGeometryWidth; };
S32 getGeometryHeight() const { return mGeometryHeight; };
std::string getMediaName() const { return mMediaName; };
std::string getMediaDescription() const { return mMediaDescription; };
@ -347,6 +350,8 @@ protected:
LLColor4 mBackgroundColor;
std::string mTarget;
/////////////////////////////////////////
// media_browser class
std::string mNavigateURI;
@ -359,7 +364,11 @@ protected:
std::string mLocation;
std::string mClickURL;
std::string mClickTarget;
ETargetType mClickTargetType;
std::string mClickUUID;
S32 mGeometryX;
S32 mGeometryY;
S32 mGeometryWidth;
S32 mGeometryHeight;
/////////////////////////////////////////
// media_time class

View File

@ -54,6 +54,9 @@ public:
MEDIA_EVENT_LOCATION_CHANGED, // browser location (URL) has changed (maybe due to internal navagation/frames/etc)
MEDIA_EVENT_CLICK_LINK_HREF, // I'm not entirely sure what the semantics of these two are
MEDIA_EVENT_CLICK_LINK_NOFOLLOW,
MEDIA_EVENT_CLOSE_REQUEST, // The plugin requested its window be closed (currently hooked up to javascript window.close in webkit)
MEDIA_EVENT_PICK_FILE_REQUEST, // The plugin wants the user to pick a file
MEDIA_EVENT_GEOMETRY_CHANGE, // The plugin requested its window geometry be changed (per the javascript window interface)
MEDIA_EVENT_PLUGIN_FAILED_LAUNCH, // The plugin failed to launch
MEDIA_EVENT_PLUGIN_FAILED // The plugin died unexpectedly

View File

@ -977,37 +977,43 @@ LLFontGL::VAlign LLFontGL::vAlignFromName(const std::string& name)
//static
LLFontGL* LLFontGL::getFontMonospace()
{
return getFont(LLFontDescriptor("Monospace","Monospace",0));
static LLFontGL* fontp = getFont(LLFontDescriptor("Monospace","Monospace",0));
return fontp;
}
//static
LLFontGL* LLFontGL::getFontSansSerifSmall()
{
return getFont(LLFontDescriptor("SansSerif","Small",0));
static LLFontGL* fontp = getFont(LLFontDescriptor("SansSerif","Small",0));
return fontp;
}
//static
LLFontGL* LLFontGL::getFontSansSerif()
{
return getFont(LLFontDescriptor("SansSerif","Medium",0));
static LLFontGL* fontp = getFont(LLFontDescriptor("SansSerif","Medium",0));
return fontp;
}
//static
LLFontGL* LLFontGL::getFontSansSerifBig()
{
return getFont(LLFontDescriptor("SansSerif","Large",0));
static LLFontGL* fontp = getFont(LLFontDescriptor("SansSerif","Large",0));
return fontp;
}
//static
LLFontGL* LLFontGL::getFontSansSerifHuge()
{
return getFont(LLFontDescriptor("SansSerif","Huge",0));
static LLFontGL* fontp = getFont(LLFontDescriptor("SansSerif","Large",0));
return fontp;
}
//static
LLFontGL* LLFontGL::getFontSansSerifBold()
{
return getFont(LLFontDescriptor("SansSerif","Medium",BOLD));
static LLFontGL* fontp = getFont(LLFontDescriptor("SansSerif","Medium",BOLD));
return fontp;
}
//static

View File

@ -158,6 +158,7 @@ set(llui_HEADER_FILES
llnotifications.h
llnotificationslistener.h
llnotificationsutil.h
llnotificationtemplate.h
llpanel.h
llprogressbar.h
llradiogroup.h

View File

@ -83,7 +83,7 @@ LLAccordionCtrl::LLAccordionCtrl() : LLPanel()
mSingleExpansion = false;
mFitParent = false;
LLUICtrlFactory::getInstance()->buildPanel(this, "accordion_parent.xml");
buildFromFile( "accordion_parent.xml");
}
//---------------------------------------------------------------------------------

View File

@ -85,10 +85,10 @@ public:
Optional<bool> selection_enabled;
Optional<S32> padding_left;
Optional<S32> padding_right;
Optional<S32> padding_top;
Optional<S32> padding_bottom;
Optional<S32> padding_left,
padding_right,
padding_top,
padding_bottom;
Params();
};
@ -170,7 +170,7 @@ public:
virtual BOOL handleScrollWheel( S32 x, S32 y, S32 clicks );
virtual bool addChild(LLView* child, S32 tab_group);
virtual bool addChild(LLView* child, S32 tab_group = 0 );
bool isExpanded() const { return mDisplayChildren; }

View File

@ -114,7 +114,6 @@ LLButton::LLButton(const LLButton::Params& p)
mFlashing( FALSE ),
mCurGlowStrength(0.f),
mNeedsHighlight(FALSE),
mMouseOver(false),
mUnselectedLabel(p.label()),
mSelectedLabel(p.label_selected()),
mGLFont(p.font),
@ -499,19 +498,14 @@ void LLButton::onMouseEnter(S32 x, S32 y, MASK mask)
LLUICtrl::onMouseEnter(x, y, mask);
if (isInEnabledChain())
{
mNeedsHighlight = TRUE;
}
mMouseOver = true;
}
void LLButton::onMouseLeave(S32 x, S32 y, MASK mask)
{
LLUICtrl::onMouseLeave(x, y, mask);
mNeedsHighlight = FALSE;
mMouseOver = true;
}
void LLButton::setHighlight(bool b)
@ -564,11 +558,19 @@ void LLButton::draw()
pressed_by_keyboard = gKeyboard->getKeyDown(' ') || (mCommitOnReturn && gKeyboard->getKeyDown(KEY_RETURN));
}
// Unselected image assignments
bool mouse_pressed_and_over = false;
if (hasMouseCapture())
{
S32 local_mouse_x ;
S32 local_mouse_y;
LLUI::getMousePositionLocal(this, &local_mouse_x, &local_mouse_y);
mouse_pressed_and_over = pointInView(local_mouse_x, local_mouse_y);
}
bool enabled = isInEnabledChain();
bool pressed = pressed_by_keyboard
|| (hasMouseCapture() && mMouseOver)
|| mouse_pressed_and_over
|| mForcePressedState;
bool selected = getToggleState();

View File

@ -350,7 +350,6 @@ private:
BOOL mCommitOnReturn;
BOOL mFadeWhenDisabled;
bool mForcePressedState;
bool mMouseOver;
LLFrameTimer mFlashingTimer;
};

View File

@ -50,9 +50,7 @@ template class LLCheckBoxCtrl* LLView::getChild<class LLCheckBoxCtrl>(
const std::string& name, BOOL recurse) const;
LLCheckBoxCtrl::Params::Params()
: text_enabled_color("text_enabled_color"),
text_disabled_color("text_disabled_color"),
initial_value("initial_value", false),
: initial_value("initial_value", false),
label_text("label_text"),
check_button("check_button"),
radio_style("radio_style")
@ -61,8 +59,8 @@ LLCheckBoxCtrl::Params::Params()
LLCheckBoxCtrl::LLCheckBoxCtrl(const LLCheckBoxCtrl::Params& p)
: LLUICtrl(p),
mTextEnabledColor(p.text_enabled_color()),
mTextDisabledColor(p.text_disabled_color()),
mTextEnabledColor(p.label_text.text_color()),
mTextDisabledColor(p.label_text.text_readonly_color()),
mFont(p.font())
{
mViewModel->setValue(LLSD(p.initial_value));
@ -89,7 +87,6 @@ LLCheckBoxCtrl::LLCheckBoxCtrl(const LLCheckBoxCtrl::Params& p)
{
tbparams.font(p.font);
}
tbparams.text_color( p.enabled() ? p.text_enabled_color() : p.text_disabled_color() );
mLabel = LLUICtrlFactory::create<LLTextBox> (tbparams);
addChild(mLabel);

View File

@ -52,8 +52,6 @@ public:
struct Params
: public LLInitParam::Block<Params, LLUICtrl::Params>
{
Optional<LLUIColor> text_enabled_color;
Optional<LLUIColor> text_disabled_color;
Optional<bool> initial_value; // override LLUICtrl initial_value
Optional<LLTextBox::Params> label_text;

View File

@ -137,8 +137,8 @@ LLComboBox::LLComboBox(const LLComboBox::Params& p)
// Grab the mouse-up event and make sure the button state is correct
mList->setMouseUpCallback(boost::bind(&LLComboBox::onListMouseUp, this));
for (LLInitParam::ParamIterator<ItemParams>::const_iterator it = p.items().begin();
it != p.items().end();
for (LLInitParam::ParamIterator<ItemParams>::const_iterator it = p.items.begin();
it != p.items.end();
++it)
{
LLScrollListItem::Params item_params = *it;

View File

@ -36,6 +36,7 @@
#include "lluictrlfactory.h"
#include "llbutton.h"
#include "llcheckboxctrl.h"
#include "lldir.h"
#include "lldraghandle.h"
#include "llfloaterreg.h"
#include "llfocusmgr.h"
@ -2390,7 +2391,9 @@ void LLFloaterView::closeAllChildren(bool app_quitting)
// Attempt to close floater. This will cause the "do you want to save"
// dialogs to appear.
if (floaterp->canClose() && !floaterp->isDead())
// Skip invisible floaters if we're not quitting (STORM-192).
if (floaterp->canClose() && !floaterp->isDead() &&
(app_quitting || floaterp->getVisible()))
{
floaterp->closeFloater(app_quitting);
}
@ -2813,7 +2816,8 @@ LLFastTimer::DeclareTimer POST_BUILD("Floater Post Build");
bool LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, const std::string& filename, LLXMLNodePtr output_node)
{
Params params(LLUICtrlFactory::getDefaultParams<LLFloater>());
LLXUIParser::instance().readXUI(node, params, filename); // *TODO: Error checking
LLXUIParser parser;
parser.readXUI(node, params, filename); // *TODO: Error checking
if (output_node)
{
@ -2821,8 +2825,7 @@ bool LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, const std::str
setupParamsForExport(output_params, parent);
Params default_params(LLUICtrlFactory::getDefaultParams<LLFloater>());
output_node->setName(node->getName()->mString);
LLXUIParser::instance().writeXUI(
output_node, output_params, &default_params);
parser.writeXUI(output_node, output_params, &default_params);
}
// Default floater position to top-left corner of screen
@ -2917,3 +2920,64 @@ bool LLFloater::isVisible(const LLFloater* floater)
{
return floater && floater->getVisible();
}
static LLFastTimer::DeclareTimer FTM_BUILD_FLOATERS("Build Floaters");
bool LLFloater::buildFromFile(const std::string& filename, LLXMLNodePtr output_node)
{
LLFastTimer timer(FTM_BUILD_FLOATERS);
LLXMLNodePtr root;
//if exporting, only load the language being exported,
//instead of layering localized version on top of english
if (output_node)
{
if (!LLUICtrlFactory::getLocalizedXMLNode(filename, root))
{
llwarns << "Couldn't parse floater from: " << LLUI::getLocalizedSkinPath() + gDirUtilp->getDirDelimiter() + filename << llendl;
return false;
}
}
else if (!LLUICtrlFactory::getLayeredXMLNode(filename, root))
{
llwarns << "Couldn't parse floater from: " << LLUI::getSkinPath() + gDirUtilp->getDirDelimiter() + filename << llendl;
return false;
}
// root must be called floater
if( !(root->hasName("floater") || root->hasName("multi_floater")) )
{
llwarns << "Root node should be named floater in: " << filename << llendl;
return false;
}
bool res = true;
lldebugs << "Building floater " << filename << llendl;
LLUICtrlFactory::instance().pushFileName(filename);
{
if (!getFactoryMap().empty())
{
LLPanel::sFactoryStack.push_front(&getFactoryMap());
}
// for local registry callbacks; define in constructor, referenced in XUI or postBuild
getCommitCallbackRegistrar().pushScope();
getEnableCallbackRegistrar().pushScope();
res = initFloaterXML(root, getParent(), filename, output_node);
setXMLFilename(filename);
getCommitCallbackRegistrar().popScope();
getEnableCallbackRegistrar().popScope();
if (!getFactoryMap().empty())
{
LLPanel::sFactoryStack.pop_front();
}
}
LLUICtrlFactory::instance().popFileName();
return res;
}

View File

@ -141,6 +141,7 @@ public:
// Don't export top/left for rect, only height/width
static void setupParamsForExport(Params& p, LLView* parent);
bool buildFromFile(const std::string &filename, LLXMLNodePtr output_node = NULL);
void initFromParams(const LLFloater::Params& p);
bool initFloaterXML(LLXMLNodePtr node, LLView *parent, const std::string& filename, LLXMLNodePtr output_node = NULL);

View File

@ -121,7 +121,7 @@ LLFloater* LLFloaterReg::getInstance(const std::string& name, const LLSD& key)
res = build_func(key);
bool success = LLUICtrlFactory::getInstance()->buildFloater(res, xui_file, NULL);
bool success = res->buildFromFile(xui_file, NULL);
if (!success)
{
llwarns << "Failed to build floater type: '" << name << "'." << llendl;

View File

@ -315,6 +315,20 @@ void LLFocusMgr::removeKeyboardFocusWithoutCallback( const LLFocusableElement* f
}
}
bool LLFocusMgr::keyboardFocusHasAccelerators() const
{
LLView* focus_view = dynamic_cast<LLView*>(mKeyboardFocus);
while( focus_view )
{
if(focus_view->hasAccelerators())
{
return true;
}
focus_view = focus_view->getParent();
}
return false;
}
void LLFocusMgr::setMouseCapture( LLMouseHandler* new_captor )
{

View File

@ -118,6 +118,8 @@ public:
void unlockFocus();
BOOL focusLocked() const { return mLockedView != NULL; }
bool keyboardFocusHasAccelerators() const;
private:
LLUICtrl* mLockedView;

View File

@ -35,95 +35,66 @@
#include "llresizebar.h"
#include "llcriticaldamp.h"
static LLDefaultChildRegistry::Register<LLLayoutStack> register_layout_stack("layout_stack", &LLLayoutStack::fromXML);
static LLDefaultChildRegistry::Register<LLLayoutStack> register_layout_stack("layout_stack");
static LLLayoutStack::LayoutStackRegistry::Register<LLLayoutPanel> register_layout_panel("layout_panel");
//
// LLLayoutStack
// LLLayoutPanel
//
struct LLLayoutStack::LayoutPanel
{
LayoutPanel(LLPanel* panelp, ELayoutOrientation orientation, S32 min_width, S32 min_height, S32 max_width, S32 max_height, BOOL auto_resize, BOOL user_resize) : mPanel(panelp),
mMinWidth(min_width),
mMinHeight(min_height),
mMaxWidth(max_width),
mMaxHeight(max_height),
mAutoResize(auto_resize),
mUserResize(user_resize),
mOrientation(orientation),
LLLayoutPanel::LLLayoutPanel(const Params& p)
: LLPanel(p),
mMinDim(p.min_dim),
mMaxDim(p.max_dim),
mAutoResize(p.auto_resize),
mUserResize(p.user_resize),
mCollapsed(FALSE),
mCollapseAmt(0.f),
mVisibleAmt(1.f), // default to fully visible
mResizeBar(NULL)
{
LLResizeBar::Side side = (orientation == HORIZONTAL) ? LLResizeBar::RIGHT : LLResizeBar::BOTTOM;
LLRect resize_bar_rect = panelp->getRect();
// panels initialized as hidden should not start out partially visible
if (!getVisible())
{
mVisibleAmt = 0.f;
}
}
S32 min_dim;
if (orientation == HORIZONTAL)
void LLLayoutPanel::initFromParams(const Params& p)
{
min_dim = mMinHeight;
}
else
{
min_dim = mMinWidth;
}
LLResizeBar::Params p;
p.name("resize");
p.resizing_view(mPanel);
p.min_size(min_dim);
p.side(side);
p.snapping_enabled(false);
mResizeBar = LLUICtrlFactory::create<LLResizeBar>(p);
// panels initialized as hidden should not start out partially visible
if (!mPanel->getVisible())
{
mVisibleAmt = 0.f;
}
LLPanel::initFromParams(p);
setFollowsNone();
}
~LayoutPanel()
LLLayoutPanel::~LLLayoutPanel()
{
// probably not necessary, but...
delete mResizeBar;
mResizeBar = NULL;
}
F32 getCollapseFactor()
F32 LLLayoutPanel::getCollapseFactor(LLLayoutStack::ELayoutOrientation orientation)
{
if (mOrientation == HORIZONTAL)
if (orientation == LLLayoutStack::HORIZONTAL)
{
F32 collapse_amt =
clamp_rescale(mCollapseAmt, 0.f, 1.f, 1.f, (F32)mMinWidth / (F32)llmax(1, mPanel->getRect().getWidth()));
clamp_rescale(mCollapseAmt, 0.f, 1.f, 1.f, (F32)mMinDim / (F32)llmax(1, getRect().getWidth()));
return mVisibleAmt * collapse_amt;
}
else
{
F32 collapse_amt =
clamp_rescale(mCollapseAmt, 0.f, 1.f, 1.f, llmin(1.f, (F32)mMinHeight / (F32)llmax(1, mPanel->getRect().getHeight())));
clamp_rescale(mCollapseAmt, 0.f, 1.f, 1.f, llmin(1.f, (F32)mMinDim / (F32)llmax(1, getRect().getHeight())));
return mVisibleAmt * collapse_amt;
}
}
LLPanel* mPanel;
S32 mMinWidth;
S32 mMinHeight;
// mMaxWidth & mMaxHeight are added to make configurable max width of the nearby chat bar. EXT-5589
// they are not processed by LLLayoutStack but they can be if necessary
S32 mMaxWidth;
S32 mMaxHeight;
BOOL mAutoResize;
BOOL mUserResize;
BOOL mCollapsed;
LLResizeBar* mResizeBar;
ELayoutOrientation mOrientation;
F32 mVisibleAmt;
F32 mCollapseAmt;
};
//
// LLLayoutStack
//
LLLayoutStack::Params::Params()
: orientation("orientation", std::string("vertical")),
: orientation("orientation"),
animate("animate", true),
clip("clip", true),
border_size("border_size", LLCachedControl<S32>(*LLUI::sSettingGroups["config"], "UIResizeBarHeight", 0))
@ -157,18 +128,18 @@ void LLLayoutStack::draw()
for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
{
// clip to layout rectangle, not bounding rectangle
LLRect clip_rect = (*panel_it)->mPanel->getRect();
LLRect clip_rect = (*panel_it)->getRect();
// scale clipping rectangle by visible amount
if (mOrientation == HORIZONTAL)
{
clip_rect.mRight = clip_rect.mLeft + llround((F32)clip_rect.getWidth() * (*panel_it)->getCollapseFactor());
clip_rect.mRight = clip_rect.mLeft + llround((F32)clip_rect.getWidth() * (*panel_it)->getCollapseFactor(mOrientation));
}
else
{
clip_rect.mBottom = clip_rect.mTop - llround((F32)clip_rect.getHeight() * (*panel_it)->getCollapseFactor());
clip_rect.mBottom = clip_rect.mTop - llround((F32)clip_rect.getHeight() * (*panel_it)->getCollapseFactor(mOrientation));
}
LLPanel* panelp = (*panel_it)->mPanel;
LLPanel* panelp = (*panel_it);
LLLocalClipRect clip(clip_rect, mClip);
// only force drawing invisible children if visible amount is non-zero
@ -179,7 +150,7 @@ void LLLayoutStack::draw()
void LLLayoutStack::removeChild(LLView* view)
{
LayoutPanel* embedded_panelp = findEmbeddedPanel(dynamic_cast<LLPanel*>(view));
LLLayoutPanel* embedded_panelp = findEmbeddedPanel(dynamic_cast<LLPanel*>(view));
if (embedded_panelp)
{
@ -200,149 +171,16 @@ BOOL LLLayoutStack::postBuild()
return TRUE;
}
static void get_attribute_s32_and_write(LLXMLNodePtr node,
const char* name,
S32 *value,
S32 default_value,
LLXMLNodePtr output_child)
{
BOOL has_attr = node->getAttributeS32(name, *value);
if (has_attr && *value != default_value && output_child)
{
// create an attribute child node
LLXMLNodePtr child_attr = output_child->createChild(name, TRUE);
child_attr->setIntValue(*value);
}
}
static void get_attribute_bool_and_write(LLXMLNodePtr node,
const char* name,
BOOL *value,
BOOL default_value,
LLXMLNodePtr output_child)
{
BOOL has_attr = node->getAttributeBOOL(name, *value);
if (has_attr && *value != default_value && output_child)
{
LLXMLNodePtr child_attr = output_child->createChild(name, TRUE);
child_attr->setBoolValue(*value);
}
}
//static
LLView* LLLayoutStack::fromXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node)
{
LLLayoutStack::Params p(LLUICtrlFactory::getDefaultParams<LLLayoutStack>());
LLXUIParser::instance().readXUI(node, p, LLUICtrlFactory::getInstance()->getCurFileName());
// Export must happen before setupParams() mungles rectangles and before
// this item gets added to parent (otherwise screws up last_child_rect
// logic). JC
if (output_node)
{
Params output_params(p);
setupParamsForExport(output_params, parent);
LLLayoutStack::Params default_params(LLUICtrlFactory::getDefaultParams<LLLayoutStack>());
output_node->setName(node->getName()->mString);
LLXUIParser::instance().writeXUI(
output_node, output_params, &default_params);
}
p.from_xui = true;
applyXUILayout(p, parent);
LLLayoutStack* layout_stackp = LLUICtrlFactory::create<LLLayoutStack>(p);
if (parent && layout_stackp)
{
S32 tab_group = p.tab_group.isProvided() ? p.tab_group() : parent->getLastTabGroup();
parent->addChild(layout_stackp, tab_group);
}
for (LLXMLNodePtr child_node = node->getFirstChild(); child_node.notNull(); child_node = child_node->getNextSibling())
{
const S32 DEFAULT_MIN_WIDTH = 0;
const S32 DEFAULT_MIN_HEIGHT = 0;
const S32 DEFAULT_MAX_WIDTH = S32_MAX;
const S32 DEFAULT_MAX_HEIGHT = S32_MAX;
const BOOL DEFAULT_AUTO_RESIZE = TRUE;
S32 min_width = DEFAULT_MIN_WIDTH;
S32 min_height = DEFAULT_MIN_HEIGHT;
S32 max_width = DEFAULT_MAX_WIDTH;
S32 max_height = DEFAULT_MAX_HEIGHT;
BOOL auto_resize = DEFAULT_AUTO_RESIZE;
LLXMLNodePtr output_child;
if (output_node)
bool LLLayoutStack::addChild(LLView* child, S32 tab_group)
{
output_child = output_node->createChild("", FALSE);
}
// Layout stack allows child nodes to acquire additional attributes,
// such as "min_width" in: <button label="Foo" min_width="100"/>
// If these attributes exist and have non-default values, write them
// to the output node.
get_attribute_s32_and_write(child_node, "min_width", &min_width,
DEFAULT_MIN_WIDTH, output_child);
get_attribute_s32_and_write(child_node, "min_height", &min_height,
DEFAULT_MIN_HEIGHT, output_child);
get_attribute_s32_and_write(child_node, "max_width", &max_width,
DEFAULT_MAX_WIDTH, output_child);
get_attribute_s32_and_write(child_node, "max_height", &max_height,
DEFAULT_MAX_HEIGHT, output_child);
get_attribute_bool_and_write(child_node, "auto_resize", &auto_resize,
DEFAULT_AUTO_RESIZE, output_child);
if (child_node->hasName("layout_panel"))
{
BOOL user_resize = TRUE;
get_attribute_bool_and_write(child_node, "user_resize", &user_resize,
TRUE, output_child);
LLPanel* panelp = (LLPanel*)LLPanel::fromXML(child_node, layout_stackp, output_child);
LLLayoutPanel* panelp = dynamic_cast<LLLayoutPanel*>(child);
if (panelp)
{
panelp->setFollowsNone();
layout_stackp->addPanel(panelp, min_width, min_height, max_width, max_height, auto_resize, user_resize);
mPanels.push_back(panelp);
}
return LLView::addChild(child, tab_group);
}
else
{
BOOL user_resize = FALSE;
get_attribute_bool_and_write(child_node, "user_resize", &user_resize,
FALSE, output_child);
LLPanel::Params p;
p.mouse_opaque(false);
LLPanel* panelp = LLUICtrlFactory::create<LLPanel>(p);
LLView* new_child = LLUICtrlFactory::getInstance()->createFromXML(child_node, panelp, LLStringUtil::null, LLPanel::child_registry_t::instance(), output_child);
if (new_child)
{
// put child in new embedded panel
layout_stackp->addPanel(panelp, min_width, min_height, max_width, max_height, auto_resize, user_resize);
// resize panel to contain widget and move widget to be contained in panel
panelp->setRect(new_child->getRect());
new_child->setOrigin(0, 0);
}
else
{
panelp->die();
}
}
if (output_child && !output_child->mChildren && output_child->mAttributes.empty() && output_child->getValue().empty())
{
output_node->deleteChild(output_child);
}
}
if (!layout_stackp->postBuild())
{
delete layout_stackp;
return NULL;
}
return layout_stackp;
}
S32 LLLayoutStack::getDefaultHeight(S32 cur_height)
{
@ -370,8 +208,8 @@ S32 LLLayoutStack::getDefaultWidth(S32 cur_width)
void LLLayoutStack::movePanel(LLPanel* panel_to_move, LLPanel* target_panel, bool move_to_front)
{
LayoutPanel* embedded_panel_to_move = findEmbeddedPanel(panel_to_move);
LayoutPanel* embedded_target_panel = move_to_front ? *mPanels.begin() : findEmbeddedPanel(target_panel);
LLLayoutPanel* embedded_panel_to_move = findEmbeddedPanel(panel_to_move);
LLLayoutPanel* embedded_target_panel = move_to_front ? *mPanels.begin() : findEmbeddedPanel(target_panel);
if (!embedded_panel_to_move || !embedded_target_panel || embedded_panel_to_move == embedded_target_panel)
{
@ -384,34 +222,14 @@ void LLLayoutStack::movePanel(LLPanel* panel_to_move, LLPanel* target_panel, boo
mPanels.insert(it, embedded_panel_to_move);
}
void LLLayoutStack::addPanel(LLPanel* panel, S32 min_width, S32 min_height, S32 max_width, S32 max_height, BOOL auto_resize, BOOL user_resize, EAnimate animate, S32 index)
void LLLayoutStack::addPanel(LLLayoutPanel* panel, EAnimate animate)
{
addChild(panel);
// panel starts off invisible (collapsed)
if (animate == ANIMATE)
{
panel->setVisible(FALSE);
}
LayoutPanel* embedded_panel = new LayoutPanel(panel, mOrientation, min_width, min_height, max_width, max_height, auto_resize, user_resize);
mPanels.insert(mPanels.begin() + llclamp(index, 0, (S32)mPanels.size()), embedded_panel);
if (panel->getParent() != this)
{
addChild(panel);
}
addChild(embedded_panel->mResizeBar);
// bring all resize bars to the front so that they are clickable even over the panels
// with a bit of overlap
for (e_panel_list_t::iterator panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
{
LLResizeBar* resize_barp = (*panel_it)->mResizeBar;
sendChildToFront(resize_barp);
}
// start expanding panel animation
if (animate == ANIMATE)
{
panel->mVisibleAmt = 0.f;
panel->setVisible(TRUE);
}
}
@ -423,7 +241,7 @@ void LLLayoutStack::removePanel(LLPanel* panel)
void LLLayoutStack::collapsePanel(LLPanel* panel, BOOL collapsed)
{
LayoutPanel* panel_container = findEmbeddedPanel(panel);
LLLayoutPanel* panel_container = findEmbeddedPanel(panel);
if (!panel_container) return;
panel_container->mCollapsed = collapsed;
@ -431,7 +249,7 @@ void LLLayoutStack::collapsePanel(LLPanel* panel, BOOL collapsed)
void LLLayoutStack::updatePanelAutoResize(const std::string& panel_name, BOOL auto_resize)
{
LayoutPanel* panel = findEmbeddedPanelByName(panel_name);
LLLayoutPanel* panel = findEmbeddedPanelByName(panel_name);
if (panel)
{
@ -441,7 +259,7 @@ void LLLayoutStack::updatePanelAutoResize(const std::string& panel_name, BOOL au
void LLLayoutStack::setPanelUserResize(const std::string& panel_name, BOOL user_resize)
{
LayoutPanel* panel = findEmbeddedPanelByName(panel_name);
LLLayoutPanel* panel = findEmbeddedPanelByName(panel_name);
if (panel)
{
@ -449,27 +267,25 @@ void LLLayoutStack::setPanelUserResize(const std::string& panel_name, BOOL user_
}
}
bool LLLayoutStack::getPanelMinSize(const std::string& panel_name, S32* min_widthp, S32* min_heightp)
bool LLLayoutStack::getPanelMinSize(const std::string& panel_name, S32* min_dimp)
{
LayoutPanel* panel = findEmbeddedPanelByName(panel_name);
LLLayoutPanel* panel = findEmbeddedPanelByName(panel_name);
if (panel)
{
if (min_widthp) *min_widthp = panel->mMinWidth;
if (min_heightp) *min_heightp = panel->mMinHeight;
if (min_dimp) *min_dimp = panel->mMinDim;
}
return NULL != panel;
}
bool LLLayoutStack::getPanelMaxSize(const std::string& panel_name, S32* max_widthp, S32* max_heightp)
bool LLLayoutStack::getPanelMaxSize(const std::string& panel_name, S32* max_dimp)
{
LayoutPanel* panel = findEmbeddedPanelByName(panel_name);
LLLayoutPanel* panel = findEmbeddedPanelByName(panel_name);
if (panel)
{
if (max_widthp) *max_widthp = panel->mMaxWidth;
if (max_heightp) *max_heightp = panel->mMaxHeight;
if (max_dimp) *max_dimp = panel->mMaxDim;
}
return NULL != panel;
@ -481,6 +297,7 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
LLFastTimer ft(FTM_UPDATE_LAYOUT);
static LLUICachedControl<S32> resize_bar_overlap ("UIResizeBarOverlap", 0);
calcMinExtents();
createResizeBars();
// calculate current extents
S32 total_width = 0;
@ -492,7 +309,7 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
e_panel_list_t::iterator panel_it;
for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
{
LLPanel* panelp = (*panel_it)->mPanel;
LLPanel* panelp = (*panel_it);
if (panelp->getVisible())
{
if (mAnimate)
@ -542,11 +359,11 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
if (mOrientation == HORIZONTAL)
{
// enforce minimize size constraint by default
if (panelp->getRect().getWidth() < (*panel_it)->mMinWidth)
if (panelp->getRect().getWidth() < (*panel_it)->mMinDim)
{
panelp->reshape((*panel_it)->mMinWidth, panelp->getRect().getHeight());
panelp->reshape((*panel_it)->mMinDim, panelp->getRect().getHeight());
}
total_width += llround(panelp->getRect().getWidth() * (*panel_it)->getCollapseFactor());
total_width += llround(panelp->getRect().getWidth() * (*panel_it)->getCollapseFactor(mOrientation));
// want n-1 panel gaps for n panels
if (panel_it != mPanels.begin())
{
@ -556,11 +373,11 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
else //VERTICAL
{
// enforce minimize size constraint by default
if (panelp->getRect().getHeight() < (*panel_it)->mMinHeight)
if (panelp->getRect().getHeight() < (*panel_it)->mMinDim)
{
panelp->reshape(panelp->getRect().getWidth(), (*panel_it)->mMinHeight);
panelp->reshape(panelp->getRect().getWidth(), (*panel_it)->mMinDim);
}
total_height += llround(panelp->getRect().getHeight() * (*panel_it)->getCollapseFactor());
total_height += llround(panelp->getRect().getHeight() * (*panel_it)->getCollapseFactor(mOrientation));
if (panel_it != mPanels.begin())
{
total_height += mPanelSpacing;
@ -574,7 +391,7 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
{
// panels that are not fully visible do not count towards shrink headroom
if ((*panel_it)->getCollapseFactor() < 1.f)
if ((*panel_it)->getCollapseFactor(mOrientation) < 1.f)
{
continue;
}
@ -587,11 +404,11 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
{
if (mOrientation == HORIZONTAL)
{
shrink_headroom_total += (*panel_it)->mPanel->getRect().getWidth() - (*panel_it)->mMinWidth;
shrink_headroom_total += (*panel_it)->getRect().getWidth() - (*panel_it)->mMinDim;
}
else //VERTICAL
{
shrink_headroom_total += (*panel_it)->mPanel->getRect().getHeight() - (*panel_it)->mMinHeight;
shrink_headroom_total += (*panel_it)->getRect().getHeight() - (*panel_it)->mMinDim;
}
}
else
@ -599,13 +416,13 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
num_resizable_panels++;
if (mOrientation == HORIZONTAL)
{
shrink_headroom_available += (*panel_it)->mPanel->getRect().getWidth() - (*panel_it)->mMinWidth;
shrink_headroom_total += (*panel_it)->mPanel->getRect().getWidth() - (*panel_it)->mMinWidth;
shrink_headroom_available += (*panel_it)->getRect().getWidth() - (*panel_it)->mMinDim;
shrink_headroom_total += (*panel_it)->getRect().getWidth() - (*panel_it)->mMinDim;
}
else //VERTICAL
{
shrink_headroom_available += (*panel_it)->mPanel->getRect().getHeight() - (*panel_it)->mMinHeight;
shrink_headroom_total += (*panel_it)->mPanel->getRect().getHeight() - (*panel_it)->mMinHeight;
shrink_headroom_available += (*panel_it)->getRect().getHeight() - (*panel_it)->mMinDim;
shrink_headroom_total += (*panel_it)->getRect().getHeight() - (*panel_it)->mMinDim;
}
}
}
@ -628,17 +445,25 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
{
LLPanel* panelp = (*panel_it)->mPanel;
LLPanel* panelp = (*panel_it);
S32 cur_width = panelp->getRect().getWidth();
S32 cur_height = panelp->getRect().getHeight();
S32 new_width = llmax((*panel_it)->mMinWidth, cur_width);
S32 new_height = llmax((*panel_it)->mMinHeight, cur_height);
S32 new_width = cur_width;
S32 new_height = cur_height;
if (mOrientation == HORIZONTAL)
{
new_width = llmax((*panel_it)->mMinDim, new_width);
}
else
{
new_height = llmax((*panel_it)->mMinDim, new_height);
}
S32 delta_size = 0;
// if panel can automatically resize (not animating, and resize flag set)...
if ((*panel_it)->getCollapseFactor() == 1.f
if ((*panel_it)->getCollapseFactor(mOrientation) == 1.f
&& (force_resize || (*panel_it)->mAutoResize)
&& !(*panel_it)->mResizeBar->hasMouseCapture())
{
@ -649,8 +474,8 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
{
// shrink proportionally to amount over minimum
// so we can do this in one pass
delta_size = (shrink_headroom_available > 0) ? llround((F32)pixels_to_distribute * ((F32)(cur_width - (*panel_it)->mMinWidth) / (F32)shrink_headroom_available)) : 0;
shrink_headroom_available -= (cur_width - (*panel_it)->mMinWidth);
delta_size = (shrink_headroom_available > 0) ? llround((F32)pixels_to_distribute * ((F32)(cur_width - (*panel_it)->mMinDim) / (F32)shrink_headroom_available)) : 0;
shrink_headroom_available -= (cur_width - (*panel_it)->mMinDim);
}
else
{
@ -659,7 +484,7 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
num_resizable_panels--;
}
pixels_to_distribute -= delta_size;
new_width = llmax((*panel_it)->mMinWidth, cur_width + delta_size);
new_width = llmax((*panel_it)->mMinDim, cur_width + delta_size);
}
else
{
@ -672,8 +497,8 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
{
// shrink proportionally to amount over minimum
// so we can do this in one pass
delta_size = (shrink_headroom_available > 0) ? llround((F32)pixels_to_distribute * ((F32)(cur_height - (*panel_it)->mMinHeight) / (F32)shrink_headroom_available)) : 0;
shrink_headroom_available -= (cur_height - (*panel_it)->mMinHeight);
delta_size = (shrink_headroom_available > 0) ? llround((F32)pixels_to_distribute * ((F32)(cur_height - (*panel_it)->mMinDim) / (F32)shrink_headroom_available)) : 0;
shrink_headroom_available -= (cur_height - (*panel_it)->mMinDim);
}
else
{
@ -681,7 +506,7 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
num_resizable_panels--;
}
pixels_to_distribute -= delta_size;
new_height = llmax((*panel_it)->mMinHeight, cur_height + delta_size);
new_height = llmax((*panel_it)->mMinDim, cur_height + delta_size);
}
else
{
@ -722,11 +547,11 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
if (mOrientation == HORIZONTAL)
{
cur_x += llround(new_width * (*panel_it)->getCollapseFactor()) + mPanelSpacing;
cur_x += llround(new_width * (*panel_it)->getCollapseFactor(mOrientation)) + mPanelSpacing;
}
else //VERTICAL
{
cur_y -= llround(new_height * (*panel_it)->getCollapseFactor()) + mPanelSpacing;
cur_y -= llround(new_height * (*panel_it)->getCollapseFactor(mOrientation)) + mPanelSpacing;
}
}
@ -734,19 +559,19 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
LLResizeBar* last_resize_bar = NULL;
for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
{
LLPanel* panelp = (*panel_it)->mPanel;
LLPanel* panelp = (*panel_it);
if (mOrientation == HORIZONTAL)
{
(*panel_it)->mResizeBar->setResizeLimits(
(*panel_it)->mMinWidth,
(*panel_it)->mMinWidth + shrink_headroom_total);
(*panel_it)->mMinDim,
(*panel_it)->mMinDim + shrink_headroom_total);
}
else //VERTICAL
{
(*panel_it)->mResizeBar->setResizeLimits(
(*panel_it)->mMinHeight,
(*panel_it)->mMinHeight + shrink_headroom_total);
(*panel_it)->mMinDim,
(*panel_it)->mMinDim + shrink_headroom_total);
}
// toggle resize bars based on panel visibility, resizability, etc
@ -782,14 +607,14 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
} // end LLLayoutStack::updateLayout
LLLayoutStack::LayoutPanel* LLLayoutStack::findEmbeddedPanel(LLPanel* panelp) const
LLLayoutPanel* LLLayoutStack::findEmbeddedPanel(LLPanel* panelp) const
{
if (!panelp) return NULL;
e_panel_list_t::const_iterator panel_it;
for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
{
if ((*panel_it)->mPanel == panelp)
if ((*panel_it) == panelp)
{
return *panel_it;
}
@ -797,15 +622,15 @@ LLLayoutStack::LayoutPanel* LLLayoutStack::findEmbeddedPanel(LLPanel* panelp) co
return NULL;
}
LLLayoutStack::LayoutPanel* LLLayoutStack::findEmbeddedPanelByName(const std::string& name) const
LLLayoutPanel* LLLayoutStack::findEmbeddedPanelByName(const std::string& name) const
{
LayoutPanel* result = NULL;
LLLayoutPanel* result = NULL;
for (e_panel_list_t::const_iterator panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
{
LayoutPanel* p = *panel_it;
LLLayoutPanel* p = *panel_it;
if (p->mPanel->getName() == name)
if (p->getName() == name)
{
result = p;
break;
@ -826,9 +651,7 @@ void LLLayoutStack::calcMinExtents()
{
if (mOrientation == HORIZONTAL)
{
mMinHeight = llmax( mMinHeight,
(*panel_it)->mMinHeight);
mMinWidth += (*panel_it)->mMinWidth;
mMinWidth += (*panel_it)->mMinDim;
if (panel_it != mPanels.begin())
{
mMinWidth += mPanelSpacing;
@ -836,9 +659,7 @@ void LLLayoutStack::calcMinExtents()
}
else //VERTICAL
{
mMinWidth = llmax( mMinWidth,
(*panel_it)->mMinWidth);
mMinHeight += (*panel_it)->mMinHeight;
mMinHeight += (*panel_it)->mMinDim;
if (panel_it != mPanels.begin())
{
mMinHeight += mPanelSpacing;
@ -847,6 +668,37 @@ void LLLayoutStack::calcMinExtents()
}
}
void LLLayoutStack::createResizeBars()
{
for (e_panel_list_t::iterator panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
{
LLLayoutPanel* lp = (*panel_it);
if (lp->mResizeBar == NULL)
{
LLResizeBar::Side side = (mOrientation == HORIZONTAL) ? LLResizeBar::RIGHT : LLResizeBar::BOTTOM;
LLRect resize_bar_rect = getRect();
LLResizeBar::Params resize_params;
resize_params.name("resize");
resize_params.resizing_view(lp);
resize_params.min_size(lp->mMinDim);
resize_params.side(side);
resize_params.snapping_enabled(false);
LLResizeBar* resize_bar = LLUICtrlFactory::create<LLResizeBar>(resize_params);
lp->mResizeBar = resize_bar;
LLView::addChild(resize_bar, 0);
// bring all resize bars to the front so that they are clickable even over the panels
// with a bit of overlap
for (e_panel_list_t::iterator panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
{
LLResizeBar* resize_barp = (*panel_it)->mResizeBar;
sendChildToFront(resize_barp);
}
}
}
}
// update layout stack animations, etc. once per frame
// NOTE: we use this to size world view based on animating UI, *before* we draw the UI
// we might still need to call updateLayout during UI draw phase, in case UI elements

View File

@ -28,16 +28,21 @@
#ifndef LL_LLLAYOUTSTACK_H
#define LL_LLLAYOUTSTACK_H
#include "llview.h"
#include "llpanel.h"
class LLPanel;
class LLLayoutPanel;
class LLLayoutStack : public LLView, public LLInstanceTracker<LLLayoutStack>
{
public:
struct LayoutStackRegistry : public LLChildRegistry<LayoutStackRegistry>
{};
struct Params : public LLInitParam::Block<Params, LLView::Params>
{
Optional<std::string> orientation;
Mandatory<std::string> orientation;
Optional<S32> border_size;
Optional<bool> animate,
clip;
@ -45,6 +50,8 @@ public:
Params();
};
typedef LayoutStackRegistry child_registry_t;
typedef enum e_layout_orientation
{
HORIZONTAL,
@ -56,6 +63,7 @@ public:
/*virtual*/ void draw();
/*virtual*/ void removeChild(LLView*);
/*virtual*/ BOOL postBuild();
/*virtual*/ bool addChild(LLView* child, S32 tab_group = 0);
static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node = NULL);
@ -68,7 +76,7 @@ public:
ANIMATE
} EAnimate;
void addPanel(LLPanel* panel, S32 min_width, S32 min_height, S32 max_width, S32 max_height, BOOL auto_resize, BOOL user_resize, EAnimate animate = NO_ANIMATE, S32 index = S32_MAX);
void addPanel(LLLayoutPanel* panel, EAnimate animate = NO_ANIMATE);
void removePanel(LLPanel* panel);
void collapsePanel(LLPanel* panel, BOOL collapsed = TRUE);
S32 getNumPanels() { return mPanels.size(); }
@ -82,20 +90,18 @@ public:
void setPanelUserResize(const std::string& panel_name, BOOL user_resize);
/**
* Gets minimal width and/or height of the specified by name panel.
* Gets minimal dimension along layout_stack axis of the specified by name panel.
*
* If it is necessary to get only the one dimension pass NULL for another one.
* @returns true if specified by panel_name internal panel exists, false otherwise.
*/
bool getPanelMinSize(const std::string& panel_name, S32* min_widthp, S32* min_heightp);
bool getPanelMinSize(const std::string& panel_name, S32* min_dimp);
/**
* Gets maximal width and/or height of the specified by name panel.
* Gets maximal dimension along layout_stack axis of the specified by name panel.
*
* If it is necessary to get only the one dimension pass NULL for another one.
* @returns true if specified by panel_name internal panel exists, false otherwise.
*/
bool getPanelMaxSize(const std::string& panel_name, S32* max_width, S32* max_height);
bool getPanelMaxSize(const std::string& panel_name, S32* max_dim);
void updateLayout(BOOL force_resize = FALSE);
@ -110,19 +116,18 @@ protected:
friend class LLUICtrlFactory;
private:
struct LayoutPanel;
void createResizeBars();
void calcMinExtents();
S32 getDefaultHeight(S32 cur_height);
S32 getDefaultWidth(S32 cur_width);
const ELayoutOrientation mOrientation;
typedef std::vector<LayoutPanel*> e_panel_list_t;
typedef std::vector<LLLayoutPanel*> e_panel_list_t;
e_panel_list_t mPanels;
LayoutPanel* findEmbeddedPanel(LLPanel* panelp) const;
LayoutPanel* findEmbeddedPanelByName(const std::string& name) const;
LLLayoutPanel* findEmbeddedPanel(LLPanel* panelp) const;
LLLayoutPanel* findEmbeddedPanelByName(const std::string& name) const;
S32 mMinWidth; // calculated by calcMinExtents
S32 mMinHeight; // calculated by calcMinExtents
@ -134,4 +139,49 @@ private:
bool mClip;
}; // end class LLLayoutStack
class LLLayoutPanel : public LLPanel
{
friend class LLLayoutStack;
friend class LLUICtrlFactory;
public:
struct Params : public LLInitParam::Block<Params, LLPanel::Params>
{
Optional<S32> min_dim,
max_dim;
Optional<bool> user_resize,
auto_resize;
Params()
: min_dim("min_dim", 0),
max_dim("max_dim", 0),
user_resize("user_resize", true),
auto_resize("auto_resize", true)
{
addSynonym(min_dim, "min_width");
addSynonym(min_dim, "min_height");
addSynonym(max_dim, "max_width");
addSynonym(max_dim, "max_height");
}
};
~LLLayoutPanel();
void initFromParams(const Params& p);
protected:
LLLayoutPanel(const Params& p) ;
F32 getCollapseFactor(LLLayoutStack::ELayoutOrientation orientation);
S32 mMinDim;
S32 mMaxDim;
BOOL mAutoResize;
BOOL mUserResize;
BOOL mCollapsed;
class LLResizeBar* mResizeBar;
F32 mVisibleAmt;
F32 mCollapseAmt;
};
#endif

View File

@ -1304,7 +1304,7 @@ BOOL LLLineEditor::handleSpecialKey(KEY key, MASK mask)
if( mCurrentHistoryLine > mLineHistory.begin() )
{
mText.assign( *(--mCurrentHistoryLine) );
setCursor(llmin((S32)mText.length(), getCursor()));
setCursorToEnd();
}
else
{
@ -1321,7 +1321,7 @@ BOOL LLLineEditor::handleSpecialKey(KEY key, MASK mask)
if( !mLineHistory.empty() && mCurrentHistoryLine < mLineHistory.end() - 1 )
{
mText.assign( *(++mCurrentHistoryLine) );
setCursor(llmin((S32)mText.length(), getCursor()));
setCursorToEnd();
}
else
{

View File

@ -3738,8 +3738,7 @@ void LLContextMenuBranch::buildDrawLabel( void )
appendAcceleratorString( st );
mDrawAccelLabel = st;
// No special branch suffix
mDrawBranchLabel.clear();
mDrawBranchLabel = LLMenuGL::BRANCH_SUFFIX;
}
void LLContextMenuBranch::showSubMenu()

View File

@ -101,8 +101,8 @@ LLMultiSlider::LLMultiSlider(const LLMultiSlider::Params& p)
setMouseUpCallback(initCommitCallback(p.mouse_up_callback));
}
for (LLInitParam::ParamIterator<SliderParams>::const_iterator it = p.sliders().begin();
it != p.sliders().end();
for (LLInitParam::ParamIterator<SliderParams>::const_iterator it = p.sliders.begin();
it != p.sliders.end();
++it)
{
if (it->name.isProvided())

View File

@ -27,6 +27,7 @@
#include "linden_common.h"
#include "llnotifications.h"
#include "llnotificationtemplate.h"
#include "llavatarnamecache.h"
#include "llinstantmessage.h"
@ -39,6 +40,8 @@
#include "lltrans.h"
#include "llnotificationslistener.h"
#include "llstring.h"
#include "llsdparam.h"
#include "llsdutil.h"
#include <algorithm>
#include <boost/regex.hpp>
@ -46,6 +49,56 @@
const std::string NOTIFICATION_PERSIST_VERSION = "0.93";
void NotificationPriorityValues::declareValues()
{
declare("low", NOTIFICATION_PRIORITY_LOW);
declare("normal", NOTIFICATION_PRIORITY_NORMAL);
declare("high", NOTIFICATION_PRIORITY_HIGH);
declare("critical", NOTIFICATION_PRIORITY_CRITICAL);
}
LLNotificationForm::FormElementBase::FormElementBase()
: name("name")
{}
LLNotificationForm::FormIgnore::FormIgnore()
: text("text"),
control("control"),
invert_control("invert_control", true),
save_option("save_option", false)
{}
LLNotificationForm::FormButton::FormButton()
: index("index"),
text("text"),
ignore("ignore"),
is_default("default"),
type("type")
{
// set type here so it gets serialized
type = "button";
}
LLNotificationForm::FormInput::FormInput()
: type("type"),
width("width", 0)
{}
LLNotificationForm::FormElement::FormElement()
: button("button"),
input("input")
{}
LLNotificationForm::FormElements::FormElements()
: elements("")
{}
LLNotificationForm::Params::Params()
: name("name"),
ignore("ignore"),
form_elements("")
{}
// Local channel for persistent notifications
// Stores only persistent notifications.
// Class users can use connectChanged() to process persistent notifications
@ -90,12 +143,7 @@ bool filterIgnoredNotifications(LLNotificationPtr notification)
LLNotificationFormPtr form = notification->getForm();
// Check to see if the user wants to ignore this alert
if (form->getIgnoreType() != LLNotificationForm::IGNORE_NO)
{
return LLUI::sSettingGroups["ignores"]->getBOOL(notification->getName());
}
return true;
return !notification->getForm()->getIgnored();
}
bool handleIgnoredNotification(const LLSD& payload)
@ -137,63 +185,68 @@ namespace LLNotificationFilters
};
LLNotificationForm::LLNotificationForm()
: mFormData(LLSD::emptyArray()),
mIgnore(IGNORE_NO)
: mIgnore(IGNORE_NO)
{
}
LLNotificationForm::LLNotificationForm(const std::string& name, const LLXMLNodePtr xml_node)
: mFormData(LLSD::emptyArray()),
mIgnore(IGNORE_NO)
LLNotificationForm::LLNotificationForm(const std::string& name, const LLNotificationForm::Params& p)
: mIgnore(IGNORE_NO),
mInvertSetting(true) // ignore settings by default mean true=show, false=ignore
{
if (!xml_node->hasName("form"))
if (p.ignore.isProvided())
{
llwarns << "Bad xml node for form: " << xml_node->getName() << llendl;
}
LLXMLNodePtr child = xml_node->getFirstChild();
while(child)
{
child = LLNotifications::instance().checkForXMLTemplate(child);
mIgnoreMsg = p.ignore.text;
LLSD item_entry;
std::string element_name = child->getName()->mString;
if (element_name == "ignore" )
if (!p.ignore.save_option)
{
bool save_option = false;
child->getAttribute_bool("save_option", save_option);
if (!save_option)
{
mIgnore = IGNORE_WITH_DEFAULT_RESPONSE;
}
else
{
// remember last option chosen by user and automatically respond with that in the future
mIgnore = IGNORE_WITH_LAST_RESPONSE;
LLUI::sSettingGroups["ignores"]->declareLLSD(std::string("Default") + name, "", std::string("Default response for notification " + name));
}
child->getAttributeString("text", mIgnoreMsg);
BOOL show_notification = TRUE;
LLUI::sSettingGroups["ignores"]->declareBOOL(name, show_notification, "Ignore notification with this name", TRUE);
mIgnore = IGNORE_WITH_DEFAULT_RESPONSE;
}
else
{
// flatten xml form entry into single LLSD map with type==name
item_entry["type"] = element_name;
const LLXMLAttribList::iterator attrib_end = child->mAttributes.end();
for(LLXMLAttribList::iterator attrib_it = child->mAttributes.begin();
attrib_it != attrib_end;
++attrib_it)
{
item_entry[std::string(attrib_it->second->getName()->mString)] = attrib_it->second->getValue();
}
item_entry["value"] = child->getTextContents();
mFormData.append(item_entry);
// remember last option chosen by user and automatically respond with that in the future
mIgnore = IGNORE_WITH_LAST_RESPONSE;
LLUI::sSettingGroups["ignores"]->declareLLSD(std::string("Default") + name, "", std::string("Default response for notification " + name));
}
child = child->getNextSibling();
BOOL show_notification = TRUE;
if (p.ignore.control.isProvided())
{
mIgnoreSetting = LLUI::sSettingGroups["config"]->getControl(p.ignore.control);
mInvertSetting = p.ignore.invert_control;
}
else
{
LLUI::sSettingGroups["ignores"]->declareBOOL(name, show_notification, "Ignore notification with this name", TRUE);
mIgnoreSetting = LLUI::sSettingGroups["ignores"]->getControl(name);
}
}
LLParamSDParser parser;
parser.writeSD(mFormData, p.form_elements);
mFormData = mFormData[""];
if (!mFormData.isArray())
{
// change existing contents to a one element array
LLSD new_llsd_array = LLSD::emptyArray();
new_llsd_array.append(mFormData);
mFormData = new_llsd_array;
}
for (LLSD::array_iterator it = mFormData.beginArray(), end_it = mFormData.endArray();
it != end_it;
++it)
{
// lift contents of form element up a level, since element type is already encoded in "type" param
if (it->isMap() && it->beginMap() != it->endMap())
{
*it = it->beginMap()->second;
}
}
LL_DEBUGS("Notifications") << name << LL_ENDL;
LL_DEBUGS("Notifications") << ll_pretty_print_sd(mFormData) << LL_ENDL;
}
LLNotificationForm::LLNotificationForm(const LLSD& sd)
@ -295,16 +348,64 @@ std::string LLNotificationForm::getDefaultOption()
return "";
}
LLNotificationTemplate::LLNotificationTemplate() :
mExpireSeconds(0),
mExpireOption(-1),
mURLOption(-1),
mURLOpenExternally(-1),
mPersist(false),
mUnique(false),
mPriority(NOTIFICATION_PRIORITY_NORMAL)
LLControlVariablePtr LLNotificationForm::getIgnoreSetting()
{
return mIgnoreSetting;
}
bool LLNotificationForm::getIgnored()
{
mForm = LLNotificationFormPtr(new LLNotificationForm());
bool ignored = false;
if (mIgnore != LLNotificationForm::IGNORE_NO
&& mIgnoreSetting)
{
ignored = mIgnoreSetting->getValue().asBoolean();
if (mInvertSetting) ignored = !ignored;
}
return ignored;
}
void LLNotificationForm::setIgnored(bool ignored)
{
if (mIgnoreSetting)
{
if (mInvertSetting) ignored = !ignored;
mIgnoreSetting->setValue(ignored);
}
}
LLNotificationTemplate::LLNotificationTemplate(const LLNotificationTemplate::Params& p)
: mName(p.name),
mType(p.type),
mMessage(p.value),
mLabel(p.label),
mIcon(p.icon),
mURL(p.url.value),
mExpireSeconds(p.duration),
mExpireOption(p.expire_option),
mURLOption(p.url.option),
mURLTarget(p.url.target),
mUnique(p.unique.isProvided()),
mPriority(p.priority),
mPersist(p.persist),
mDefaultFunctor(p.functor.isProvided() ? p.functor() : p.name())
{
if (p.sound.isProvided()
&& LLUI::sSettingGroups["config"]->controlExists(p.sound))
{
mSoundEffect = LLUUID(LLUI::sSettingGroups["config"]->getString(p.sound));
}
for(LLInitParam::ParamIterator<LLNotificationTemplate::UniquenessContext>::const_iterator it = p.unique.contexts.begin(),
end_it = p.unique.contexts.end();
it != end_it;
++it)
{
mUniqueContext.push_back(it->key);
}
mForm = LLNotificationFormPtr(new LLNotificationForm(p.name, p.form_ref.form));
}
LLNotification::LLNotification(const LLNotification::Params& p) :
@ -501,7 +602,7 @@ void LLNotification::respond(const LLSD& response)
{
mResponder->handleRespond(asLLSD(), response);
}
else
else if (!mResponseFunctorName.empty())
{
// look up the functor
LLNotificationFunctorRegistry::ResponseFunctor functor =
@ -509,6 +610,11 @@ void LLNotification::respond(const LLSD& response)
// and then call it
functor(asLLSD(), response);
}
else
{
// no registered responder
return;
}
if (mTemporaryResponder && !isReusable())
{
@ -519,8 +625,7 @@ void LLNotification::respond(const LLSD& response)
if (mForm->getIgnoreType() != LLNotificationForm::IGNORE_NO)
{
BOOL show_notification = mIgnored ? FALSE : TRUE;
LLUI::sSettingGroups["ignores"]->setBOOL(getName(), show_notification);
mForm->setIgnored(mIgnored);
if (mIgnored && mForm->getIgnoreType() == LLNotificationForm::IGNORE_WITH_LAST_RESPONSE)
{
LLUI::sSettingGroups["ignores"]->setLLSD("Default" + getName(), response);
@ -530,6 +635,49 @@ void LLNotification::respond(const LLSD& response)
update();
}
void LLNotification::respondWithDefault()
{
respond(getResponseTemplate(WITH_DEFAULT_BUTTON));
}
const std::string& LLNotification::getName() const
{
return mTemplatep->mName;
}
const std::string& LLNotification::getIcon() const
{
return mTemplatep->mIcon;
}
bool LLNotification::isPersistent() const
{
return mTemplatep->mPersist;
}
std::string LLNotification::getType() const
{
return (mTemplatep ? mTemplatep->mType : "");
}
S32 LLNotification::getURLOption() const
{
return (mTemplatep ? mTemplatep->mURLOption : -1);
}
S32 LLNotification::getURLOpenExternally() const
{
return(mTemplatep? mTemplatep->mURLTarget == "_external": -1);
}
bool LLNotification::hasUniquenessConstraints() const
{
return (mTemplatep ? mTemplatep->mUnique : false);
}
void LLNotification::setIgnored(bool ignore)
{
mIgnored = ignore;
@ -609,6 +757,8 @@ void LLNotification::init(const std::string& template_name, const LLSD& form_ele
// apply substitution to form labels
mForm->formatElements(mSubstitutions);
mIgnored = mForm->getIgnored();
LLDate rightnow = LLDate::now();
if (mTemplatep->mExpireSeconds)
{
@ -1097,11 +1247,6 @@ bool LLNotifications::templateExists(const std::string& name)
return (mTemplates.count(name) != 0);
}
void LLNotifications::clearTemplates()
{
mTemplates.clear();
}
void LLNotifications::forceResponse(const LLNotification::Params& params, S32 option)
{
LLNotificationPtr temp_notify(new LLNotification(params));
@ -1164,190 +1309,88 @@ void replaceSubstitutionStrings(LLXMLNodePtr node, StringMap& replacements)
}
}
// private to this file
// returns true if the template request was invalid and there's nothing else we
// can do with this node, false if you should keep processing (it may have
// replaced the contents of the node referred to)
LLXMLNodePtr LLNotifications::checkForXMLTemplate(LLXMLNodePtr item)
void replaceFormText(LLNotificationForm::Params& form, const std::string& pattern, const std::string& replace)
{
if (item->hasName("usetemplate"))
if (form.ignore.isProvided() && form.ignore.text() == pattern)
{
std::string replacementName;
if (item->getAttributeString("name", replacementName))
form.ignore.text = replace;
}
for (LLInitParam::ParamIterator<LLNotificationForm::FormElement>::iterator it = form.form_elements.elements.begin(),
end_it = form.form_elements.elements.end();
it != end_it;
++it)
{
if (it->button.isChosen() && it->button.text() == pattern)
{
StringMap replacements;
for (LLXMLAttribList::const_iterator it=item->mAttributes.begin();
it != item->mAttributes.end(); ++it)
{
replacements[it->second->getName()->mString] = it->second->getValue();
}
if (mXmlTemplates.count(replacementName))
{
item=LLXMLNode::replaceNode(item, mXmlTemplates[replacementName]);
// walk the nodes looking for $(substitution) here and replace
replaceSubstitutionStrings(item, replacements);
}
else
{
llwarns << "XML template lookup failure on '" << replacementName << "' " << llendl;
}
it->button.text = replace;
}
}
return item;
}
bool LLNotifications::loadTemplates()
{
const std::string xml_filename = "notifications.xml";
std::string full_filename = gDirUtilp->findSkinnedFilename(LLUI::getXUIPaths().front(), xml_filename);
LLXMLNodePtr root;
BOOL success = LLUICtrlFactory::getLayeredXMLNode(xml_filename, root);
if (!success || root.isNull() || !root->hasName( "notifications" ))
{
llerrs << "Problem reading UI Notifications file: " << xml_filename << llendl;
llerrs << "Problem reading UI Notifications file: " << full_filename << llendl;
return false;
}
clearTemplates();
for (LLXMLNodePtr item = root->getFirstChild();
item.notNull(); item = item->getNextSibling())
LLNotificationTemplate::Notifications params;
LLXUIParser parser;
parser.readXUI(root, params, full_filename);
mTemplates.clear();
for(LLInitParam::ParamIterator<LLNotificationTemplate::GlobalString>::const_iterator it = params.strings.begin(), end_it = params.strings.end();
it != end_it;
++it)
{
// we do this FIRST so that item can be changed if we
// encounter a usetemplate -- we just replace the
// current xml node and keep processing
item = checkForXMLTemplate(item);
if (item->hasName("global"))
{
std::string global_name;
if (item->getAttributeString("name", global_name))
{
mGlobalStrings[global_name] = item->getTextContents();
}
continue;
}
if (item->hasName("template"))
{
// store an xml template; templates must have a single node (can contain
// other nodes)
std::string name;
item->getAttributeString("name", name);
LLXMLNodePtr ptr = item->getFirstChild();
mXmlTemplates[name] = ptr;
continue;
}
if (!item->hasName("notification"))
{
llwarns << "Unexpected entity " << item->getName()->mString <<
" found in " << xml_filename << llendl;
continue;
}
// now we know we have a notification entry, so let's build it
LLNotificationTemplatePtr pTemplate(new LLNotificationTemplate());
if (!item->getAttributeString("name", pTemplate->mName))
{
llwarns << "Unable to parse notification with no name" << llendl;
continue;
}
//llinfos << "Parsing " << pTemplate->mName << llendl;
pTemplate->mMessage = item->getTextContents();
pTemplate->mDefaultFunctor = pTemplate->mName;
item->getAttributeString("type", pTemplate->mType);
item->getAttributeString("icon", pTemplate->mIcon);
item->getAttributeString("label", pTemplate->mLabel);
item->getAttributeU32("duration", pTemplate->mExpireSeconds);
item->getAttributeU32("expireOption", pTemplate->mExpireOption);
std::string priority;
item->getAttributeString("priority", priority);
pTemplate->mPriority = NOTIFICATION_PRIORITY_NORMAL;
if (!priority.empty())
{
if (priority == "low") pTemplate->mPriority = NOTIFICATION_PRIORITY_LOW;
if (priority == "normal") pTemplate->mPriority = NOTIFICATION_PRIORITY_NORMAL;
if (priority == "high") pTemplate->mPriority = NOTIFICATION_PRIORITY_HIGH;
if (priority == "critical") pTemplate->mPriority = NOTIFICATION_PRIORITY_CRITICAL;
}
item->getAttributeString("functor", pTemplate->mDefaultFunctor);
BOOL persist = false;
item->getAttributeBOOL("persist", persist);
pTemplate->mPersist = persist;
std::string sound;
item->getAttributeString("sound", sound);
if (!sound.empty())
{
// test for bad sound effect name / missing effect
if (LLUI::sSettingGroups["config"]->controlExists(sound))
{
pTemplate->mSoundEffect =
LLUUID(LLUI::sSettingGroups["config"]->getString(sound));
}
else
{
llwarns << "Unknown sound effect control name " << sound
<< llendl;
}
}
for (LLXMLNodePtr child = item->getFirstChild();
!child.isNull(); child = child->getNextSibling())
{
child = checkForXMLTemplate(child);
// <url>
if (child->hasName("url"))
{
pTemplate->mURL = child->getTextContents();
child->getAttributeU32("option", pTemplate->mURLOption);
child->getAttributeU32("openexternally", pTemplate->mURLOpenExternally);
}
if (child->hasName("unique"))
{
pTemplate->mUnique = true;
for (LLXMLNodePtr formitem = child->getFirstChild();
!formitem.isNull(); formitem = formitem->getNextSibling())
{
if (formitem->hasName("context"))
{
std::string key;
formitem->getAttributeString("key", key);
pTemplate->mUniqueContext.push_back(key);
//llwarns << "adding " << key << " to unique context" << llendl;
}
else
{
llwarns << "'unique' has unrecognized subelement "
<< formitem->getName()->mString << llendl;
}
}
}
// <form>
if (child->hasName("form"))
{
pTemplate->mForm = LLNotificationFormPtr(new LLNotificationForm(pTemplate->mName, child));
}
}
addTemplate(pTemplate->mName, pTemplate);
mGlobalStrings[it->name] = it->value;
}
//std::ostringstream ostream;
//root->writeToOstream(ostream, "\n ");
//llwarns << ostream.str() << llendl;
std::map<std::string, LLNotificationForm::Params> form_templates;
for(LLInitParam::ParamIterator<LLNotificationTemplate::Template>::const_iterator it = params.templates.begin(), end_it = params.templates.end();
it != end_it;
++it)
{
form_templates[it->name] = it->form;
}
for(LLInitParam::ParamIterator<LLNotificationTemplate::Params>::iterator it = params.notifications.begin(), end_it = params.notifications.end();
it != end_it;
++it)
{
if (it->form_ref.form_template.isChosen())
{
// replace form contents from template
it->form_ref.form = form_templates[it->form_ref.form_template.name];
if(it->form_ref.form_template.yes_text.isProvided())
{
replaceFormText(it->form_ref.form, "$yestext", it->form_ref.form_template.yes_text);
}
if(it->form_ref.form_template.no_text.isProvided())
{
replaceFormText(it->form_ref.form, "$notext", it->form_ref.form_template.no_text);
}
if(it->form_ref.form_template.cancel_text.isProvided())
{
replaceFormText(it->form_ref.form, "$canceltext", it->form_ref.form_template.cancel_text);
}
if(it->form_ref.form_template.ignore_text.isProvided())
{
replaceFormText(it->form_ref.form, "$ignoretext", it->form_ref.form_template.ignore_text);
}
}
addTemplate(it->name, LLNotificationTemplatePtr(new LLNotificationTemplate(*it)));
}
return true;
}
@ -1398,6 +1441,8 @@ LLNotificationPtr LLNotifications::add(const LLNotification::Params& p)
void LLNotifications::add(const LLNotificationPtr pNotif)
{
if (pNotif == NULL) return;
// first see if we already have it -- if so, that's a problem
LLNotificationSet::iterator it=mItems.find(pNotif);
if (it != mItems.end())
@ -1410,6 +1455,8 @@ void LLNotifications::add(const LLNotificationPtr pNotif)
void LLNotifications::cancel(LLNotificationPtr pNotif)
{
if (pNotif == NULL) return;
LLNotificationSet::iterator it=mItems.find(pNotif);
if (it == mItems.end())
{
@ -1419,6 +1466,30 @@ void LLNotifications::cancel(LLNotificationPtr pNotif)
updateItem(LLSD().with("sigtype", "delete").with("id", pNotif->id()), pNotif);
}
void LLNotifications::cancelByName(const std::string& name)
{
std::vector<LLNotificationPtr> notifs_to_cancel;
for (LLNotificationSet::iterator it=mItems.begin(), end_it = mItems.end();
it != end_it;
++it)
{
LLNotificationPtr pNotif = *it;
if (pNotif->getName() == name)
{
notifs_to_cancel.push_back(pNotif);
}
}
for (std::vector<LLNotificationPtr>::iterator it = notifs_to_cancel.begin(), end_it = notifs_to_cancel.end();
it != end_it;
++it)
{
LLNotificationPtr pNotif = *it;
pNotif->cancel();
updateItem(LLSD().with("sigtype", "delete").with("id", pNotif->id()), pNotif);
}
}
void LLNotifications::update(const LLNotificationPtr pNotif)
{
LLNotificationSet::iterator it=mItems.find(pNotif);

View File

@ -100,7 +100,6 @@
#include "llnotificationptr.h"
class LLAvatarName;
typedef enum e_notification_priority
{
NOTIFICATION_PRIORITY_UNSPECIFIED,
@ -110,6 +109,11 @@ typedef enum e_notification_priority
NOTIFICATION_PRIORITY_CRITICAL
} ENotificationPriority;
struct NotificationPriorityValues : public LLInitParam::TypeValuesHelper<ENotificationPriority, NotificationPriorityValues>
{
static void declareValues();
};
class LLNotificationResponderInterface
{
public:
@ -157,6 +161,66 @@ class LLNotificationForm
LOG_CLASS(LLNotificationForm);
public:
struct FormElementBase : public LLInitParam::Block<FormElementBase>
{
Optional<std::string> name;
FormElementBase();
};
struct FormIgnore : public LLInitParam::Block<FormIgnore, FormElementBase>
{
Optional<std::string> text;
Optional<bool> save_option;
Optional<std::string> control;
Optional<bool> invert_control;
FormIgnore();
};
struct FormButton : public LLInitParam::Block<FormButton, FormElementBase>
{
Mandatory<S32> index;
Mandatory<std::string> text;
Optional<std::string> ignore;
Optional<bool> is_default;
Mandatory<std::string> type;
FormButton();
};
struct FormInput : public LLInitParam::Block<FormInput, FormElementBase>
{
Mandatory<std::string> type;
Optional<S32> width;
FormInput();
};
struct FormElement : public LLInitParam::Choice<FormElement>
{
Alternative<FormButton> button;
Alternative<FormInput> input;
FormElement();
};
struct FormElements : public LLInitParam::Block<FormElements>
{
Multiple<FormElement> elements;
FormElements();
};
struct Params : public LLInitParam::Block<Params>
{
Optional<std::string> name;
Optional<FormIgnore> ignore;
Optional<FormElements> form_elements;
Params();
};
typedef enum e_ignore_type
{
IGNORE_NO,
@ -167,8 +231,7 @@ public:
LLNotificationForm();
LLNotificationForm(const LLSD& sd);
LLNotificationForm(const std::string& name,
const LLPointer<class LLXMLNode> xml_node);
LLNotificationForm(const std::string& name, const Params& p);
LLSD asLLSD() const;
@ -181,92 +244,25 @@ public:
// appends form elements from another form serialized as LLSD
void append(const LLSD& sub_form);
std::string getDefaultOption();
LLPointer<class LLControlVariable> getIgnoreSetting();
bool getIgnored();
void setIgnored(bool ignored);
EIgnoreType getIgnoreType() { return mIgnore; }
std::string getIgnoreMessage() { return mIgnoreMsg; }
private:
LLSD mFormData;
EIgnoreType mIgnore;
std::string mIgnoreMsg;
LLSD mFormData;
EIgnoreType mIgnore;
std::string mIgnoreMsg;
LLPointer<class LLControlVariable> mIgnoreSetting;
bool mInvertSetting;
};
typedef boost::shared_ptr<LLNotificationForm> LLNotificationFormPtr;
// This is the class of object read from the XML file (notifications.xml,
// from the appropriate local language directory).
struct LLNotificationTemplate
{
LLNotificationTemplate();
// the name of the notification -- the key used to identify it
// Ideally, the key should follow variable naming rules
// (no spaces or punctuation).
std::string mName;
// The type of the notification
// used to control which queue it's stored in
std::string mType;
// The text used to display the notification. Replaceable parameters
// are enclosed in square brackets like this [].
std::string mMessage;
// The label for the notification; used for
// certain classes of notification (those with a window and a window title).
// Also used when a notification pops up underneath the current one.
// Replaceable parameters can be used in the label.
std::string mLabel;
// The name of the icon image. This should include an extension.
std::string mIcon;
// This is the Highlander bit -- "There Can Be Only One"
// An outstanding notification with this bit set
// is updated by an incoming notification with the same name,
// rather than creating a new entry in the queue.
// (used for things like progress indications, or repeating warnings
// like "the grid is going down in N minutes")
bool mUnique;
// if we want to be unique only if a certain part of the payload is constant
// specify the field names for the payload. The notification will only be
// combined if all of the fields named in the context are identical in the
// new and the old notification; otherwise, the notification will be
// duplicated. This is to support suppressing duplicate offers from the same
// sender but still differentiating different offers. Example: Invitation to
// conference chat.
std::vector<std::string> mUniqueContext;
// If this notification expires automatically, this value will be
// nonzero, and indicates the number of seconds for which the notification
// will be valid (a teleport offer, for example, might be valid for
// 300 seconds).
U32 mExpireSeconds;
// if the offer expires, one of the options is chosen automatically
// based on its "value" parameter. This controls which one.
// If expireSeconds is specified, expireOption should also be specified.
U32 mExpireOption;
// if the notification contains a url, it's stored here (and replaced
// into the message where [_URL] is found)
std::string mURL;
// if there's a URL in the message, this controls which option visits
// that URL. Obsolete this and eliminate the buttons for affected
// messages when we allow clickable URLs in the UI
U32 mURLOption;
U32 mURLOpenExternally;
//This is a flag that tells if the url needs to open externally dispite
//what the user setting is.
// does this notification persist across sessions? if so, it will be
// serialized to disk on first receipt and read on startup
bool mPersist;
// This is the name of the default functor, if present, to be
// used for the notification's callback. It is optional, and used only if
// the notification is constructed without an identified functor.
std::string mDefaultFunctor;
// The form data associated with a given notification (buttons, text boxes, etc)
LLNotificationFormPtr mForm;
// default priority for notifications of this type
ENotificationPriority mPriority;
// UUID of the audio file to be played when this notification arrives
// this is loaded as a name, but looked up to get the UUID upon template load.
// If null, it wasn't specified.
LLUUID mSoundEffect;
};
struct LLNotificationTemplate;
// we want to keep a map of these by name, and it's best to manage them
// with smart pointers
@ -302,7 +298,7 @@ public:
// optional
Optional<LLSD> substitutions;
Optional<LLSD> payload;
Optional<ENotificationPriority> priority;
Optional<ENotificationPriority, NotificationPriorityValues> priority;
Optional<LLSD> form_elements;
Optional<LLDate> time_stamp;
Optional<LLNotificationContext*> context;
@ -445,6 +441,7 @@ public:
LLSD asLLSD();
void respond(const LLSD& sd);
void respondWithDefault();
void* getResponder() { return mResponderObj; }
@ -462,6 +459,13 @@ public:
return mRespondedTo;
}
bool isActive() const
{
return !isRespondedTo()
&& !isCancelled()
&& !isExpired();
}
const LLSD& getResponse() { return mResponse; }
bool isIgnored() const
@ -469,15 +473,11 @@ public:
return mIgnored;
}
const std::string& getName() const
{
return mTemplatep->mName;
}
const std::string& getName() const;
bool isPersistent() const
{
return mTemplatep->mPersist;
}
const std::string& getIcon() const;
bool isPersistent() const;
const LLUUID& id() const
{
@ -499,28 +499,12 @@ public:
return mTimestamp;
}
std::string getType() const
{
return (mTemplatep ? mTemplatep->mType : "");
}
std::string getType() const;
std::string getMessage() const;
std::string getLabel() const;
std::string getURL() const;
// {
// return (mTemplatep ? mTemplatep->mURL : "");
// }
S32 getURLOption() const
{
return (mTemplatep ? mTemplatep->mURLOption : -1);
}
S32 getURLOpenExternally() const
{
return(mTemplatep? mTemplatep->mURLOpenExternally : -1);
}
S32 getURLOption() const;
S32 getURLOpenExternally() const;
const LLNotificationFormPtr getForm();
@ -590,7 +574,7 @@ public:
std::string summarize() const;
bool hasUniquenessConstraints() const { return (mTemplatep ? mTemplatep->mUnique : false);}
bool hasUniquenessConstraints() const;
virtual ~LLNotification() {}
};
@ -872,7 +856,6 @@ public:
// load notification descriptions from file;
// OK to call more than once because it will reload
bool loadTemplates();
LLPointer<class LLXMLNode> checkForXMLTemplate(LLPointer<class LLXMLNode> item);
// Add a simple notification (from XUI)
void addFromCallback(const LLSD& name);
@ -894,6 +877,7 @@ public:
void add(const LLNotificationPtr pNotif);
void cancel(LLNotificationPtr pNotif);
void cancelByName(const std::string& name);
void update(const LLNotificationPtr pNotif);
LLNotificationPtr find(LLUUID uuid);
@ -917,8 +901,6 @@ public:
// test for existence
bool templateExists(const std::string& name);
// useful if you're reloading the file
void clearTemplates(); // erase all templates
void forceResponse(const LLNotification::Params& params, S32 option);
@ -956,9 +938,6 @@ private:
std::string mFileName;
typedef std::map<std::string, LLPointer<class LLXMLNode> > XMLTemplateMap;
XMLTemplateMap mXmlTemplates;
LLNotificationMap mUniqueNotifications;
typedef std::map<std::string, std::string> GlobalStringMap;

View File

@ -29,6 +29,7 @@
#include "linden_common.h"
#include "llnotificationslistener.h"
#include "llnotifications.h"
#include "llnotificationtemplate.h"
#include "llsd.h"
#include "llui.h"
@ -182,7 +183,11 @@ void LLNotificationsListener::ignore(const LLSD& params) const
if (params["name"].isDefined())
{
// ["name"] was passed: ignore just that notification
LLUI::sSettingGroups["ignores"]->setBOOL(params["name"], ignore);
LLNotificationTemplatePtr templatep = mNotifications.getTemplate(params["name"]);
if (templatep)
{
templatep->mForm->setIgnored(ignore);
}
}
else
{

View File

@ -0,0 +1,282 @@
/**
* @file llnotificationtemplate.h
* @brief Description of notification contents
* @author Q (with assistance from Richard and Coco)
*
* $LicenseInfo:firstyear=2008&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_LLNOTIFICATION_TEMPLATE_H
#define LL_LLNOTIFICATION_TEMPLATE_H
//#include <string>
//#include <list>
//#include <vector>
//#include <map>
//#include <set>
//#include <iomanip>
//#include <sstream>
//
//#include <boost/utility.hpp>
//#include <boost/shared_ptr.hpp>
//#include <boost/enable_shared_from_this.hpp>
//#include <boost/type_traits.hpp>
//
//// we want to minimize external dependencies, but this one is important
//#include "llsd.h"
//
//// and we need this to manage the notification callbacks
//#include "llevents.h"
//#include "llfunctorregistry.h"
//#include "llpointer.h"
#include "llinitparam.h"
//#include "llnotificationslistener.h"
//#include "llnotificationptr.h"
//#include "llcachename.h"
#include "llnotifications.h"
typedef boost::shared_ptr<LLNotificationForm> LLNotificationFormPtr;
// This is the class of object read from the XML file (notifications.xml,
// from the appropriate local language directory).
struct LLNotificationTemplate
{
struct GlobalString : public LLInitParam::Block<GlobalString>
{
Mandatory<std::string> name,
value;
GlobalString()
: name("name"),
value("value")
{}
};
struct UniquenessContext : public LLInitParam::Block<UniquenessContext>
{
Mandatory<std::string> key;
UniquenessContext()
: key("key")
{}
};
struct UniquenessConstraint : public LLInitParam::Block<UniquenessConstraint>
{
private:
// this idiom allows
// <notification unique="true">
// as well as
// <notification> <unique> <context key=""/> </unique>...
Optional<bool> dummy_val;
public:
Multiple<UniquenessContext> contexts;
UniquenessConstraint()
: contexts("context"),
dummy_val("")
{}
};
// Templates are used to define common form types, such as OK/Cancel dialogs, etc.
struct Template : public LLInitParam::Block<Template>
{
Mandatory<std::string> name;
Mandatory<LLNotificationForm::Params> form;
Template()
: name("name"),
form("form")
{}
};
// Reference a template to use its form elements
struct TemplateRef : public LLInitParam::Block<TemplateRef>
{
Mandatory<std::string> name;
Optional<std::string> yes_text,
no_text,
cancel_text,
ignore_text;
TemplateRef()
: name("name"),
yes_text("yestext"),
no_text("notext"),
cancel_text("canceltext"),
ignore_text("ignoretext")
{}
};
struct URL : public LLInitParam::Block<URL>
{
Mandatory<S32> option;
Mandatory<std::string> value;
Optional<std::string> target;
Ignored name;
URL()
: option("option", -1),
value("value"),
target("target", "_blank"),
name("name")
{}
};
struct FormRef : public LLInitParam::Choice<FormRef>
{
Alternative<LLNotificationForm::Params> form;
Alternative<TemplateRef> form_template;
FormRef()
: form("form"),
form_template("usetemplate")
{}
};
struct Params : public LLInitParam::Block<Params>
{
Mandatory<std::string> name;
Optional<bool> persist;
Optional<std::string> functor,
icon,
label,
sound,
type,
value;
Optional<U32> duration;
Optional<S32> expire_option;
Optional<URL> url;
Optional<UniquenessConstraint> unique;
Optional<FormRef> form_ref;
Optional<ENotificationPriority,
NotificationPriorityValues> priority;
Params()
: name("name"),
persist("persist", false),
functor("functor"),
icon("icon"),
label("label"),
priority("priority"),
sound("sound"),
type("type"),
value("value"),
duration("duration"),
expire_option("expireOption", -1),
url("url"),
unique("unique"),
form_ref("")
{}
};
struct Notifications : public LLInitParam::Block<Notifications>
{
Multiple<GlobalString> strings;
Multiple<Template> templates;
Multiple<Params> notifications;
Notifications()
: strings("global"),
notifications("notification"),
templates("template")
{}
};
LLNotificationTemplate(const Params& p);
// the name of the notification -- the key used to identify it
// Ideally, the key should follow variable naming rules
// (no spaces or punctuation).
std::string mName;
// The type of the notification
// used to control which queue it's stored in
std::string mType;
// The text used to display the notification. Replaceable parameters
// are enclosed in square brackets like this [].
std::string mMessage;
// The label for the notification; used for
// certain classes of notification (those with a window and a window title).
// Also used when a notification pops up underneath the current one.
// Replaceable parameters can be used in the label.
std::string mLabel;
// The name of the icon image. This should include an extension.
std::string mIcon;
// This is the Highlander bit -- "There Can Be Only One"
// An outstanding notification with this bit set
// is updated by an incoming notification with the same name,
// rather than creating a new entry in the queue.
// (used for things like progress indications, or repeating warnings
// like "the grid is going down in N minutes")
bool mUnique;
// if we want to be unique only if a certain part of the payload is constant
// specify the field names for the payload. The notification will only be
// combined if all of the fields named in the context are identical in the
// new and the old notification; otherwise, the notification will be
// duplicated. This is to support suppressing duplicate offers from the same
// sender but still differentiating different offers. Example: Invitation to
// conference chat.
std::vector<std::string> mUniqueContext;
// If this notification expires automatically, this value will be
// nonzero, and indicates the number of seconds for which the notification
// will be valid (a teleport offer, for example, might be valid for
// 300 seconds).
U32 mExpireSeconds;
// if the offer expires, one of the options is chosen automatically
// based on its "value" parameter. This controls which one.
// If expireSeconds is specified, expireOption should also be specified.
U32 mExpireOption;
// if the notification contains a url, it's stored here (and replaced
// into the message where [_URL] is found)
std::string mURL;
// if there's a URL in the message, this controls which option visits
// that URL. Obsolete this and eliminate the buttons for affected
// messages when we allow clickable URLs in the UI
U32 mURLOption;
std::string mURLTarget;
//This is a flag that tells if the url needs to open externally dispite
//what the user setting is.
// does this notification persist across sessions? if so, it will be
// serialized to disk on first receipt and read on startup
bool mPersist;
// This is the name of the default functor, if present, to be
// used for the notification's callback. It is optional, and used only if
// the notification is constructed without an identified functor.
std::string mDefaultFunctor;
// The form data associated with a given notification (buttons, text boxes, etc)
LLNotificationFormPtr mForm;
// default priority for notifications of this type
ENotificationPriority mPriority;
// UUID of the audio file to be played when this notification arrives
// this is loaded as a name, but looked up to get the UUID upon template load.
// If null, it wasn't specified.
LLUUID mSoundEffect;
};
#endif //LL_LLNOTIFICATION_TEMPLATE_H

View File

@ -35,6 +35,7 @@
#include "llfontgl.h"
#include "llrect.h"
#include "llerror.h"
#include "lldir.h"
#include "lltimer.h"
#include "llaccordionctrltab.h"
@ -52,6 +53,8 @@
#include "lltabcontainer.h"
static LLDefaultChildRegistry::Register<LLPanel> r1("panel", &LLPanel::fromXML);
LLPanel::factory_stack_t LLPanel::sFactoryStack;
// Compiler optimization, generate extern template
template class LLPanel* LLView::getChild<class LLPanel>(
@ -380,8 +383,7 @@ LLView* LLPanel::fromXML(LLXMLNodePtr node, LLView* parent, LLXMLNodePtr output_
LLPanel* panelp = NULL;
{
LLFastTimer timer(FTM_PANEL_CONSTRUCTION);
{ LLFastTimer _(FTM_PANEL_CONSTRUCTION);
if(!class_attr.empty())
{
@ -394,7 +396,7 @@ LLView* LLPanel::fromXML(LLXMLNodePtr node, LLView* parent, LLXMLNodePtr output_
if (!panelp)
{
panelp = LLUICtrlFactory::getInstance()->createFactoryPanel(name);
panelp = createFactoryPanel(name);
llassert(panelp);
if (!panelp)
@ -407,20 +409,20 @@ LLView* LLPanel::fromXML(LLXMLNodePtr node, LLView* parent, LLXMLNodePtr output_
// factory panels may have registered their own factory maps
if (!panelp->getFactoryMap().empty())
{
LLUICtrlFactory::instance().pushFactoryFunctions(&panelp->getFactoryMap());
sFactoryStack.push_back(&panelp->getFactoryMap());
}
// for local registry callbacks; define in constructor, referenced in XUI or postBuild
panelp->mCommitCallbackRegistrar.pushScope();
panelp->mEnableCallbackRegistrar.pushScope();
panelp->initPanelXML(node, parent, output_node);
panelp->initPanelXML(node, parent, output_node, LLUICtrlFactory::getDefaultParams<LLPanel>());
panelp->mCommitCallbackRegistrar.popScope();
panelp->mEnableCallbackRegistrar.popScope();
if (!panelp->getFactoryMap().empty())
{
LLUICtrlFactory::instance().popFactoryFunctions();
sFactoryStack.pop_back();
}
return panelp;
@ -444,8 +446,8 @@ void LLPanel::initFromParams(const LLPanel::Params& p)
setVisibleCallback(initCommitCallback(p.visible_callback));
}
for (LLInitParam::ParamIterator<LocalizedString>::const_iterator it = p.strings().begin();
it != p.strings().end();
for (LLInitParam::ParamIterator<LocalizedString>::const_iterator it = p.strings.begin();
it != p.strings.end();
++it)
{
mUIStrings[it->name] = it->value;
@ -487,11 +489,9 @@ static LLFastTimer::DeclareTimer FTM_PANEL_SETUP("Panel Setup");
static LLFastTimer::DeclareTimer FTM_EXTERNAL_PANEL_LOAD("Load Extern Panel Reference");
static LLFastTimer::DeclareTimer FTM_PANEL_POSTBUILD("Panel PostBuild");
BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node)
BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node, const LLPanel::Params& default_params)
{
const LLPanel::Params& default_params(LLUICtrlFactory::getDefaultParams<LLPanel>());
Params params(default_params);
{
LLFastTimer timer(FTM_PANEL_SETUP);
@ -505,6 +505,8 @@ BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr outpu
setXMLFilename(xml_filename);
}
LLXUIParser parser;
if (!xml_filename.empty())
{
LLUICtrlFactory::instance().pushFileName(xml_filename);
@ -514,12 +516,11 @@ BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr outpu
{
//if we are exporting, we want to export the current xml
//not the referenced xml
LLXUIParser::instance().readXUI(node, params, LLUICtrlFactory::getInstance()->getCurFileName());
parser.readXUI(node, params, LLUICtrlFactory::getInstance()->getCurFileName());
Params output_params(params);
setupParamsForExport(output_params, parent);
output_node->setName(node->getName()->mString);
LLXUIParser::instance().writeXUI(
output_node, output_params, &default_params);
parser.writeXUI(output_node, output_params, &default_params);
return TRUE;
}
@ -530,7 +531,7 @@ BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr outpu
return FALSE;
}
LLXUIParser::instance().readXUI(referenced_xml, params, LLUICtrlFactory::getInstance()->getCurFileName());
parser.readXUI(referenced_xml, params, LLUICtrlFactory::getInstance()->getCurFileName());
// add children using dimensions from referenced xml for consistent layout
setShape(params.rect);
@ -540,15 +541,14 @@ BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr outpu
}
// ask LLUICtrlFactory for filename, since xml_filename might be empty
LLXUIParser::instance().readXUI(node, params, LLUICtrlFactory::getInstance()->getCurFileName());
parser.readXUI(node, params, LLUICtrlFactory::getInstance()->getCurFileName());
if (output_node)
{
Params output_params(params);
setupParamsForExport(output_params, parent);
output_node->setName(node->getName()->mString);
LLXUIParser::instance().writeXUI(
output_node, output_params, &default_params);
parser.writeXUI(output_node, output_params, &default_params);
}
params.from_xui = true;
@ -959,3 +959,89 @@ boost::signals2::connection LLPanel::setVisibleCallback( const commit_signal_t::
return mVisibleSignal->connect(cb);
}
static LLFastTimer::DeclareTimer FTM_BUILD_PANELS("Build Panels");
//-----------------------------------------------------------------------------
// buildPanel()
//-----------------------------------------------------------------------------
BOOL LLPanel::buildFromFile(const std::string& filename, LLXMLNodePtr output_node, const LLPanel::Params& default_params)
{
LLFastTimer timer(FTM_BUILD_PANELS);
BOOL didPost = FALSE;
LLXMLNodePtr root;
//if exporting, only load the language being exported,
//instead of layering localized version on top of english
if (output_node)
{
if (!LLUICtrlFactory::getLocalizedXMLNode(filename, root))
{
llwarns << "Couldn't parse panel from: " << LLUI::getLocalizedSkinPath() + gDirUtilp->getDirDelimiter() + filename << llendl;
return didPost;
}
}
else if (!LLUICtrlFactory::getLayeredXMLNode(filename, root))
{
llwarns << "Couldn't parse panel from: " << LLUI::getSkinPath() + gDirUtilp->getDirDelimiter() + filename << llendl;
return didPost;
}
// root must be called panel
if( !root->hasName("panel" ) )
{
llwarns << "Root node should be named panel in : " << filename << llendl;
return didPost;
}
lldebugs << "Building panel " << filename << llendl;
LLUICtrlFactory::instance().pushFileName(filename);
{
if (!getFactoryMap().empty())
{
sFactoryStack.push_back(&getFactoryMap());
}
// for local registry callbacks; define in constructor, referenced in XUI or postBuild
getCommitCallbackRegistrar().pushScope();
getEnableCallbackRegistrar().pushScope();
didPost = initPanelXML(root, NULL, output_node, default_params);
getCommitCallbackRegistrar().popScope();
getEnableCallbackRegistrar().popScope();
setXMLFilename(filename);
if (!getFactoryMap().empty())
{
sFactoryStack.pop_back();
}
}
LLUICtrlFactory::instance().popFileName();
return didPost;
}
//-----------------------------------------------------------------------------
// createFactoryPanel()
//-----------------------------------------------------------------------------
LLPanel* LLPanel::createFactoryPanel(const std::string& name)
{
std::deque<const LLCallbackMap::map_t*>::iterator itor;
for (itor = sFactoryStack.begin(); itor != sFactoryStack.end(); ++itor)
{
const LLCallbackMap::map_t* factory_map = *itor;
// Look up this panel's name in the map.
LLCallbackMap::map_const_iter_t iter = factory_map->find( name );
if (iter != factory_map->end())
{
// Use the factory to create the panel, instead of using a default LLPanel.
LLPanel *ret = (LLPanel*) iter->second.mCallback( iter->second.mData );
return ret;
}
}
LLPanel::Params panel_p;
return LLUICtrlFactory::create<LLPanel>(panel_p);
}

View File

@ -104,7 +104,10 @@ protected:
LLPanel(const LLPanel::Params& params = getDefaultParams());
public:
// LLPanel(const std::string& name, const LLRect& rect = LLRect(), BOOL bordered = TRUE);
BOOL buildFromFile(const std::string &filename, LLXMLNodePtr output_node = NULL, const LLPanel::Params&default_params = getDefaultParams());
static LLPanel* createFactoryPanel(const std::string& name);
/*virtual*/ ~LLPanel();
// LLView interface
@ -157,7 +160,7 @@ public:
EnableCallbackRegistry::ScopedRegistrar& getEnableCallbackRegistrar() { return mEnableCallbackRegistrar; }
void initFromParams(const Params& p);
BOOL initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node = NULL);
BOOL initPanelXML( LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node, const LLPanel::Params& default_params);
bool hasString(const std::string& name);
std::string getString(const std::string& name, const LLStringUtil::format_map_t& args) const;
@ -256,6 +259,8 @@ protected:
commit_signal_t* mVisibleSignal; // Called when visibility changes, passes new visibility as LLSD()
std::string mHelpTopic; // the name of this panel's help topic to display in the Help Viewer
typedef std::deque<const LLCallbackMap::map_t*> factory_stack_t;
static factory_stack_t sFactoryStack;
private:
BOOL mBgVisible; // any background at all?
@ -285,4 +290,57 @@ extern template class LLPanel* LLView::getChild<class LLPanel>(
const std::string& name, BOOL recurse) const;
#endif
typedef boost::function<LLPanel* (void)> LLPanelClassCreatorFunc;
// local static instance for registering a particular panel class
class LLRegisterPanelClass
: public LLSingleton< LLRegisterPanelClass >
{
public:
// reigister with either the provided builder, or the generic templated builder
void addPanelClass(const std::string& tag,LLPanelClassCreatorFunc func)
{
mPanelClassesNames[tag] = func;
}
LLPanel* createPanelClass(const std::string& tag)
{
param_name_map_t::iterator iT = mPanelClassesNames.find(tag);
if(iT == mPanelClassesNames.end())
return 0;
return iT->second();
}
template<typename T>
static T* defaultPanelClassBuilder()
{
T* pT = new T();
return pT;
}
private:
typedef std::map< std::string, LLPanelClassCreatorFunc> param_name_map_t;
param_name_map_t mPanelClassesNames;
};
// local static instance for registering a particular panel class
template<typename T>
class LLRegisterPanelClassWrapper
: public LLRegisterPanelClass
{
public:
// reigister with either the provided builder, or the generic templated builder
LLRegisterPanelClassWrapper(const std::string& tag);
};
template<typename T>
LLRegisterPanelClassWrapper<T>::LLRegisterPanelClassWrapper(const std::string& tag)
{
LLRegisterPanelClass::instance().addPanelClass(tag,&LLRegisterPanelClass::defaultPanelClassBuilder<T>);
}
#endif

View File

@ -100,8 +100,8 @@ LLRadioGroup::LLRadioGroup(const LLRadioGroup::Params& p)
void LLRadioGroup::initFromParams(const Params& p)
{
for (LLInitParam::ParamIterator<ItemParams>::const_iterator it = p.items().begin();
it != p.items().end();
for (LLInitParam::ParamIterator<ItemParams>::const_iterator it = p.items.begin();
it != p.items.end();
++it)
{
LLRadioGroup::ItemParams item_params(*it);

View File

@ -30,10 +30,15 @@
#include "lluicolor.h"
#include "lluictrlfactory.h"
static LLInitParam::Parser::parser_read_func_map_t sReadFuncs;
static LLInitParam::Parser::parser_write_func_map_t sWriteFuncs;
static LLInitParam::Parser::parser_inspect_func_map_t sInspectFuncs;
//
// LLRNGWriter - writes Relax NG schema files based on a param block
//
LLRNGWriter::LLRNGWriter()
: Parser(sReadFuncs, sWriteFuncs, sInspectFuncs)
{
// register various callbacks for inspecting the contents of a param block
registerInspectFunc<bool>(boost::bind(&LLRNGWriter::writeAttribute, this, "boolean", _1, _2, _3, _4));

View File

@ -259,15 +259,15 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p)
}
for (LLInitParam::ParamIterator<LLScrollListColumn::Params>::const_iterator row_it = p.contents.columns().begin();
row_it != p.contents.columns().end();
for (LLInitParam::ParamIterator<LLScrollListColumn::Params>::const_iterator row_it = p.contents.columns.begin();
row_it != p.contents.columns.end();
++row_it)
{
addColumn(*row_it);
}
for (LLInitParam::ParamIterator<LLScrollListItem::Params>::const_iterator row_it = p.contents.rows().begin();
row_it != p.contents.rows().end();
for (LLInitParam::ParamIterator<LLScrollListItem::Params>::const_iterator row_it = p.contents.rows.begin();
row_it != p.contents.rows.end();
++row_it)
{
addRow(*row_it);
@ -537,23 +537,7 @@ BOOL LLScrollListCtrl::addItem( LLScrollListItem* item, EAddPosition pos, BOOL r
setNeedsSort();
break;
case ADD_SORTED:
{
// sort by column 0, in ascending order
std::vector<sort_column_t> single_sort_column;
single_sort_column.push_back(std::make_pair(0, TRUE));
mItemList.push_back(item);
std::stable_sort(
mItemList.begin(),
mItemList.end(),
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
setNeedsSort();
break;
}
case ADD_DEFAULT:
case ADD_BOTTOM:
mItemList.push_back(item);
setNeedsSort();
@ -2578,7 +2562,8 @@ BOOL LLScrollListCtrl::canDeselect() const
void LLScrollListCtrl::addColumn(const LLSD& column, EAddPosition pos)
{
LLScrollListColumn::Params p;
LLParamSDParser::instance().readSD(column, p);
LLParamSDParser parser;
parser.readSD(column, p);
addColumn(p, pos);
}
@ -2764,31 +2749,35 @@ LLScrollListColumn* LLScrollListCtrl::getColumn(const std::string& name)
return NULL;
}
LLFastTimer::DeclareTimer FTM_ADD_SCROLLLIST_ELEMENT("Add Scroll List Item");
LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& element, EAddPosition pos, void* userdata)
{
LLFastTimer _(FTM_ADD_SCROLLLIST_ELEMENT);
LLScrollListItem::Params item_params;
LLParamSDParser::instance().readSD(element, item_params);
LLParamSDParser parser;
parser.readSD(element, item_params);
item_params.userdata = userdata;
return addRow(item_params, pos);
}
LLScrollListItem* LLScrollListCtrl::addRow(const LLScrollListItem::Params& item_p, EAddPosition pos)
{
LLFastTimer _(FTM_ADD_SCROLLLIST_ELEMENT);
LLScrollListItem *new_item = new LLScrollListItem(item_p);
return addRow(new_item, item_p, pos);
}
LLScrollListItem* LLScrollListCtrl::addRow(LLScrollListItem *new_item, const LLScrollListItem::Params& item_p, EAddPosition pos)
{
LLFastTimer _(FTM_ADD_SCROLLLIST_ELEMENT);
if (!item_p.validateBlock() || !new_item) return NULL;
new_item->setNumColumns(mColumns.size());
// Add any columns we don't already have
S32 col_index = 0;
for(LLInitParam::ParamIterator<LLScrollListCell::Params>::const_iterator itor = item_p.columns().begin();
itor != item_p.columns().end();
for(LLInitParam::ParamIterator<LLScrollListCell::Params>::const_iterator itor = item_p.columns.begin();
itor != item_p.columns.end();
++itor)
{
LLScrollListCell::Params cell_p = *itor;
@ -2839,7 +2828,7 @@ LLScrollListItem* LLScrollListCtrl::addRow(LLScrollListItem *new_item, const LLS
col_index++;
}
if (item_p.columns().empty())
if (item_p.columns.empty())
{
if (mColumns.empty())
{

View File

@ -29,49 +29,42 @@
// Project includes
#include "llsdparam.h"
#include "llsdutil.h"
static LLInitParam::Parser::parser_read_func_map_t sReadFuncs;
static LLInitParam::Parser::parser_write_func_map_t sWriteFuncs;
static LLInitParam::Parser::parser_inspect_func_map_t sInspectFuncs;
//
// LLParamSDParser
//
LLParamSDParser::LLParamSDParser()
: Parser(sReadFuncs, sWriteFuncs, sInspectFuncs)
{
using boost::bind;
registerParserFuncs<S32>(bind(&LLParamSDParser::readTypedValue<S32>, this, _1, &LLSD::asInteger),
bind(&LLParamSDParser::writeTypedValue<S32>, this, _1, _2));
registerParserFuncs<U32>(bind(&LLParamSDParser::readTypedValue<U32>, this, _1, &LLSD::asInteger),
bind(&LLParamSDParser::writeU32Param, this, _1, _2));
registerParserFuncs<F32>(bind(&LLParamSDParser::readTypedValue<F32>, this, _1, &LLSD::asReal),
bind(&LLParamSDParser::writeTypedValue<F32>, this, _1, _2));
registerParserFuncs<F64>(bind(&LLParamSDParser::readTypedValue<F64>, this, _1, &LLSD::asReal),
bind(&LLParamSDParser::writeTypedValue<F64>, this, _1, _2));
registerParserFuncs<bool>(bind(&LLParamSDParser::readTypedValue<F32>, this, _1, &LLSD::asBoolean),
bind(&LLParamSDParser::writeTypedValue<F32>, this, _1, _2));
registerParserFuncs<std::string>(bind(&LLParamSDParser::readTypedValue<std::string>, this, _1, &LLSD::asString),
bind(&LLParamSDParser::writeTypedValue<std::string>, this, _1, _2));
registerParserFuncs<LLUUID>(bind(&LLParamSDParser::readTypedValue<LLUUID>, this, _1, &LLSD::asUUID),
bind(&LLParamSDParser::writeTypedValue<LLUUID>, this, _1, _2));
registerParserFuncs<LLDate>(bind(&LLParamSDParser::readTypedValue<LLDate>, this, _1, &LLSD::asDate),
bind(&LLParamSDParser::writeTypedValue<LLDate>, this, _1, _2));
registerParserFuncs<LLURI>(bind(&LLParamSDParser::readTypedValue<LLURI>, this, _1, &LLSD::asURI),
bind(&LLParamSDParser::writeTypedValue<LLURI>, this, _1, _2));
registerParserFuncs<LLSD>(bind(&LLParamSDParser::readSDParam, this, _1),
bind(&LLParamSDParser::writeTypedValue<LLSD>, this, _1, _2));
}
bool LLParamSDParser::readSDParam(void* value_ptr)
{
if (!mCurReadSD) return false;
*((LLSD*)value_ptr) = *mCurReadSD;
return true;
if (sReadFuncs.empty())
{
registerParserFuncs<S32>(readS32, &LLParamSDParser::writeTypedValue<S32>);
registerParserFuncs<U32>(readU32, &LLParamSDParser::writeU32Param);
registerParserFuncs<F32>(readF32, &LLParamSDParser::writeTypedValue<F32>);
registerParserFuncs<F64>(readF64, &LLParamSDParser::writeTypedValue<F64>);
registerParserFuncs<bool>(readBool, &LLParamSDParser::writeTypedValue<bool>);
registerParserFuncs<std::string>(readString, &LLParamSDParser::writeTypedValue<std::string>);
registerParserFuncs<LLUUID>(readUUID, &LLParamSDParser::writeTypedValue<LLUUID>);
registerParserFuncs<LLDate>(readDate, &LLParamSDParser::writeTypedValue<LLDate>);
registerParserFuncs<LLURI>(readURI, &LLParamSDParser::writeTypedValue<LLURI>);
registerParserFuncs<LLSD>(readSD, &LLParamSDParser::writeTypedValue<LLSD>);
}
}
// special case handling of U32 due to ambiguous LLSD::assign overload
bool LLParamSDParser::writeU32Param(const void* val_ptr, const parser_t::name_stack_t& name_stack)
bool LLParamSDParser::writeU32Param(LLParamSDParser::parser_t& parser, const void* val_ptr, const parser_t::name_stack_t& name_stack)
{
if (!mWriteSD) return false;
LLParamSDParser& sdparser = static_cast<LLParamSDParser&>(parser);
if (!sdparser.mWriteRootSD) return false;
LLSD* sd_to_write = getSDWriteNode(name_stack);
LLSD* sd_to_write = sdparser.getSDWriteNode(name_stack);
if (!sd_to_write) return false;
sd_to_write->assign((S32)*((const U32*)val_ptr));
@ -89,7 +82,8 @@ void LLParamSDParser::readSD(const LLSD& sd, LLInitParam::BaseBlock& block, bool
void LLParamSDParser::writeSD(LLSD& sd, const LLInitParam::BaseBlock& block)
{
mWriteSD = &sd;
mNameStack.clear();
mWriteRootSD = &sd;
block.serializeBlock(*this);
}
@ -139,6 +133,155 @@ void LLParamSDParser::readSDValues(const LLSD& sd, LLInitParam::BaseBlock& block
LLSD* LLParamSDParser::getSDWriteNode(const parser_t::name_stack_t& name_stack)
{
//TODO: implement nested LLSD writing
return mWriteSD;
LLSD* sd_to_write = mWriteRootSD;
bool new_traversal = false;
for (name_stack_t::const_iterator it = name_stack.begin(), prev_it = mNameStack.begin();
it != name_stack.end();
++it)
{
bool new_array_entry = false;
if (prev_it == mNameStack.end())
{
new_traversal = true;
}
else
{
if (!new_traversal // have not diverged yet from previous trace
&& prev_it->first == it->first // names match
&& prev_it->second != it->second) // versions differ
{
// name stacks match, but version numbers differ in last place.
// create a different entry at this point using an LLSD array
new_array_entry = true;
}
if (prev_it->first != it->first // names differ
|| prev_it->second != it->second) // versions differ
{
// at this point we have diverged from our last trace
// so any elements referenced here are new
new_traversal = true;
}
}
LLSD* child_sd = &(*sd_to_write)[it->first];
if (child_sd->isArray())
{
if (new_traversal)
{
// write to new element at end
sd_to_write = &(*child_sd)[child_sd->size()];
}
else
{
// write to last of existing elements, or first element if empty
sd_to_write = &(*child_sd)[llmax(0, child_sd->size() - 1)];
}
}
else
{
if (new_array_entry && !child_sd->isArray())
{
// copy child contents into first element of an array
LLSD new_array = LLSD::emptyArray();
new_array.append(*child_sd);
// assign array to slot that previously held the single value
*child_sd = new_array;
// return next element in that array
sd_to_write = &((*child_sd)[1]);
}
else
{
sd_to_write = child_sd;
}
}
if (prev_it != mNameStack.end())
{
++prev_it;
}
}
mNameStack = name_stack;
//llinfos << ll_pretty_print_sd(*mWriteRootSD) << llendl;
return sd_to_write;
}
bool LLParamSDParser::readS32(Parser& parser, void* val_ptr)
{
LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
*((S32*)val_ptr) = self.mCurReadSD->asInteger();
return true;
}
bool LLParamSDParser::readU32(Parser& parser, void* val_ptr)
{
LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
*((U32*)val_ptr) = self.mCurReadSD->asInteger();
return true;
}
bool LLParamSDParser::readF32(Parser& parser, void* val_ptr)
{
LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
*((F32*)val_ptr) = self.mCurReadSD->asReal();
return true;
}
bool LLParamSDParser::readF64(Parser& parser, void* val_ptr)
{
LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
*((F64*)val_ptr) = self.mCurReadSD->asReal();
return true;
}
bool LLParamSDParser::readBool(Parser& parser, void* val_ptr)
{
LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
*((bool*)val_ptr) = self.mCurReadSD->asBoolean();
return true;
}
bool LLParamSDParser::readString(Parser& parser, void* val_ptr)
{
LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
*((std::string*)val_ptr) = self.mCurReadSD->asString();
return true;
}
bool LLParamSDParser::readUUID(Parser& parser, void* val_ptr)
{
LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
*((LLUUID*)val_ptr) = self.mCurReadSD->asUUID();
return true;
}
bool LLParamSDParser::readDate(Parser& parser, void* val_ptr)
{
LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
*((LLDate*)val_ptr) = self.mCurReadSD->asDate();
return true;
}
bool LLParamSDParser::readURI(Parser& parser, void* val_ptr)
{
LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
*((LLURI*)val_ptr) = self.mCurReadSD->asURI();
return true;
}
bool LLParamSDParser::readSD(Parser& parser, void* val_ptr)
{
LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
*((LLSD*)val_ptr) = *self.mCurReadSD;
return true;
}

View File

@ -31,17 +31,14 @@
#include "llinitparam.h"
class LLParamSDParser
: public LLInitParam::Parser,
public LLSingleton<LLParamSDParser>
: public LLInitParam::Parser
{
LOG_CLASS(LLParamSDParser);
typedef LLInitParam::Parser parser_t;
protected:
LLParamSDParser();
friend class LLSingleton<LLParamSDParser>;
public:
LLParamSDParser();
void readSD(const LLSD& sd, LLInitParam::BaseBlock& block, bool silent = false);
void writeSD(LLSD& sd, const LLInitParam::BaseBlock& block);
@ -51,20 +48,12 @@ private:
void readSDValues(const LLSD& sd, LLInitParam::BaseBlock& block);
template<typename T>
bool readTypedValue(void* val_ptr, boost::function<T(const LLSD&)> parser_func)
{
if (!mCurReadSD) return false;
*((T*)val_ptr) = parser_func(*mCurReadSD);
return true;
}
template<typename T>
bool writeTypedValue(const void* val_ptr, const parser_t::name_stack_t& name_stack)
static bool writeTypedValue(Parser& parser, const void* val_ptr, const parser_t::name_stack_t& name_stack)
{
if (!mWriteSD) return false;
LLParamSDParser& sdparser = static_cast<LLParamSDParser&>(parser);
if (!sdparser.mWriteRootSD) return false;
LLSD* sd_to_write = getSDWriteNode(name_stack);
LLSD* sd_to_write = sdparser.getSDWriteNode(name_stack);
if (!sd_to_write) return false;
sd_to_write->assign(*((const T*)val_ptr));
@ -73,12 +62,23 @@ private:
LLSD* getSDWriteNode(const parser_t::name_stack_t& name_stack);
bool readSDParam(void* value_ptr);
bool writeU32Param(const void* value_ptr, const parser_t::name_stack_t& name_stack);
static bool writeU32Param(Parser& parser, const void* value_ptr, const parser_t::name_stack_t& name_stack);
static bool readS32(Parser& parser, void* val_ptr);
static bool readU32(Parser& parser, void* val_ptr);
static bool readF32(Parser& parser, void* val_ptr);
static bool readF64(Parser& parser, void* val_ptr);
static bool readBool(Parser& parser, void* val_ptr);
static bool readString(Parser& parser, void* val_ptr);
static bool readUUID(Parser& parser, void* val_ptr);
static bool readDate(Parser& parser, void* val_ptr);
static bool readURI(Parser& parser, void* val_ptr);
static bool readSD(Parser& parser, void* val_ptr);
Parser::name_stack_t mNameStack;
const LLSD* mCurReadSD;
LLSD* mWriteSD;
LLSD* mWriteRootSD;
LLSD* mCurWriteSD;
};
template<typename T>
@ -88,7 +88,8 @@ class LLSDParamAdapter : public T
LLSDParamAdapter() {}
LLSDParamAdapter(const LLSD& sd)
{
LLParamSDParser::instance().readSD(sd, *this);
LLParamSDParser parser;
parser.readSD(sd, *this);
}
LLSDParamAdapter(const T& val)

View File

@ -235,6 +235,7 @@ class LLTextBase
public:
friend class LLTextSegment;
friend class LLNormalTextSegment;
friend class LLUICtrlFactory;
struct LineSpacingParams : public LLInitParam::Choice<LineSpacingParams>
{

View File

@ -78,9 +78,9 @@ BOOL LLToolTipView::handleHover(S32 x, S32 y, MASK mask)
LLToolTipMgr& tooltip_mgr = LLToolTipMgr::instance();
if (x != last_x && y != last_y)
if (x != last_x && y != last_y && !tooltip_mgr.getMouseNearRect().pointInRect(x, y))
{
// allow new tooltips because mouse moved
// allow new tooltips because mouse moved outside of mouse near rect
tooltip_mgr.unblockToolTips();
}
@ -276,8 +276,8 @@ void LLToolTip::initFromParams(const LLToolTip::Params& p)
if (p.styled_message.isProvided())
{
for (LLInitParam::ParamIterator<LLToolTip::StyledText>::const_iterator text_it = p.styled_message().begin();
text_it != p.styled_message().end();
for (LLInitParam::ParamIterator<LLToolTip::StyledText>::const_iterator text_it = p.styled_message.begin();
text_it != p.styled_message.end();
++text_it)
{
mTextBox->appendText(text_it->text(), false, text_it->style);
@ -580,6 +580,7 @@ void LLToolTipMgr::updateToolTipVisibility()
if (mToolTip->getVisibleTime() > tooltip_timeout)
{
hideToolTips();
unblockToolTips();
}
}
}

View File

@ -1796,7 +1796,8 @@ void LLUI::setupPaths()
LLXMLNodePtr root;
BOOL success = LLXMLNode::parseFile(filename, root, NULL);
Paths paths;
LLXUIParser::instance().readXUI(root, paths, filename);
LLXUIParser parser;
parser.readXUI(root, paths, filename);
sXUIPaths.clear();
@ -1805,14 +1806,14 @@ void LLUI::setupPaths()
LLStringUtil::format_map_t path_args;
path_args["[LANGUAGE]"] = LLUI::getLanguage();
for (LLInitParam::ParamIterator<Directory>::const_iterator it = paths.directories().begin(),
end_it = paths.directories().end();
for (LLInitParam::ParamIterator<Directory>::const_iterator it = paths.directories.begin(),
end_it = paths.directories.end();
it != end_it;
++it)
{
std::string path_val_ui;
for (LLInitParam::ParamIterator<SubDir>::const_iterator subdir_it = it->subdirs().begin(),
subdir_end_it = it->subdirs().end();
for (LLInitParam::ParamIterator<SubDir>::const_iterator subdir_it = it->subdirs.begin(),
subdir_end_it = it->subdirs.end();
subdir_it != subdir_end_it;)
{
path_val_ui += subdir_it->value();

View File

@ -56,8 +56,8 @@ void LLUIColorTable::insertFromParams(const Params& p, string_color_map_t& table
typedef std::map<std::string, std::string> string_string_map_t;
string_string_map_t unresolved_refs;
for(LLInitParam::ParamIterator<ColorEntryParams>::const_iterator it = p.color_entries().begin();
it != p.color_entries().end();
for(LLInitParam::ParamIterator<ColorEntryParams>::const_iterator it = p.color_entries.begin();
it != p.color_entries.end();
++it)
{
ColorEntryParams color_entry = *it;
@ -237,7 +237,8 @@ void LLUIColorTable::saveUserSettings() const
}
LLXMLNodePtr output_node = new LLXMLNode("colors", false);
LLXUIParser::instance().writeXUI(output_node, params);
LLXUIParser parser;
parser.writeXUI(output_node, params);
if(!output_node->isNull())
{
@ -303,7 +304,8 @@ bool LLUIColorTable::loadFromFilename(const std::string& filename, string_color_
}
Params params;
LLXUIParser::instance().readXUI(root, params, filename);
LLXUIParser parser;
parser.readXUI(root, params, filename);
if(params.validateBlock())
{

View File

@ -42,7 +42,7 @@
#include "llquaternion.h"
// this library includes
#include "llfloater.h"
#include "llpanel.h"
LLFastTimer::DeclareTimer FTM_WIDGET_CONSTRUCTION("Widget Construction");
LLFastTimer::DeclareTimer FTM_INIT_FROM_PARAMS("Widget InitFromParams");
@ -93,10 +93,12 @@ void LLUICtrlFactory::loadWidgetTemplate(const std::string& widget_tag, LLInitPa
std::string filename = std::string("widgets") + gDirUtilp->getDirDelimiter() + widget_tag + ".xml";
LLXMLNodePtr root_node;
if (LLUICtrlFactory::getLayeredXMLNode(filename, root_node))
std::string full_filename = gDirUtilp->findSkinnedFilename(LLUI::getXUIPaths().front(), filename);
if (!full_filename.empty())
{
LLUICtrlFactory::instance().pushFileName(filename);
LLXUIParser::instance().readXUI(root_node, block, filename);
LLUICtrlFactory::instance().pushFileName(full_filename);
LLSimpleXUIParser parser;
parser.readXUI(full_filename, block);
LLUICtrlFactory::instance().popFileName();
}
}
@ -171,70 +173,6 @@ bool LLUICtrlFactory::getLocalizedXMLNode(const std::string &xui_filename, LLXML
}
}
static LLFastTimer::DeclareTimer FTM_BUILD_FLOATERS("Build Floaters");
//-----------------------------------------------------------------------------
// buildFloater()
//-----------------------------------------------------------------------------
bool LLUICtrlFactory::buildFloater(LLFloater* floaterp, const std::string& filename, LLXMLNodePtr output_node)
{
LLFastTimer timer(FTM_BUILD_FLOATERS);
LLXMLNodePtr root;
//if exporting, only load the language being exported,
//instead of layering localized version on top of english
if (output_node)
{
if (!LLUICtrlFactory::getLocalizedXMLNode(filename, root))
{
llwarns << "Couldn't parse floater from: " << LLUI::getLocalizedSkinPath() + gDirUtilp->getDirDelimiter() + filename << llendl;
return false;
}
}
else if (!LLUICtrlFactory::getLayeredXMLNode(filename, root))
{
llwarns << "Couldn't parse floater from: " << LLUI::getSkinPath() + gDirUtilp->getDirDelimiter() + filename << llendl;
return false;
}
// root must be called floater
if( !(root->hasName("floater") || root->hasName("multi_floater")) )
{
llwarns << "Root node should be named floater in: " << filename << llendl;
return false;
}
bool res = true;
lldebugs << "Building floater " << filename << llendl;
pushFileName(filename);
{
if (!floaterp->getFactoryMap().empty())
{
mFactoryStack.push_front(&floaterp->getFactoryMap());
}
// for local registry callbacks; define in constructor, referenced in XUI or postBuild
floaterp->getCommitCallbackRegistrar().pushScope();
floaterp->getEnableCallbackRegistrar().pushScope();
res = floaterp->initFloaterXML(root, floaterp->getParent(), filename, output_node);
floaterp->setXMLFilename(filename);
floaterp->getCommitCallbackRegistrar().popScope();
floaterp->getEnableCallbackRegistrar().popScope();
if (!floaterp->getFactoryMap().empty())
{
mFactoryStack.pop_front();
}
}
popFileName();
return res;
}
//-----------------------------------------------------------------------------
// saveToXML()
//-----------------------------------------------------------------------------
@ -243,69 +181,6 @@ S32 LLUICtrlFactory::saveToXML(LLView* viewp, const std::string& filename)
return 0;
}
static LLFastTimer::DeclareTimer FTM_BUILD_PANELS("Build Panels");
//-----------------------------------------------------------------------------
// buildPanel()
//-----------------------------------------------------------------------------
BOOL LLUICtrlFactory::buildPanel(LLPanel* panelp, const std::string& filename, LLXMLNodePtr output_node)
{
LLFastTimer timer(FTM_BUILD_PANELS);
BOOL didPost = FALSE;
LLXMLNodePtr root;
//if exporting, only load the language being exported,
//instead of layering localized version on top of english
if (output_node)
{
if (!LLUICtrlFactory::getLocalizedXMLNode(filename, root))
{
llwarns << "Couldn't parse panel from: " << LLUI::getLocalizedSkinPath() + gDirUtilp->getDirDelimiter() + filename << llendl;
return didPost;
}
}
else if (!LLUICtrlFactory::getLayeredXMLNode(filename, root))
{
llwarns << "Couldn't parse panel from: " << LLUI::getSkinPath() + gDirUtilp->getDirDelimiter() + filename << llendl;
return didPost;
}
// root must be called panel
if( !root->hasName("panel" ) )
{
llwarns << "Root node should be named panel in : " << filename << llendl;
return didPost;
}
lldebugs << "Building panel " << filename << llendl;
pushFileName(filename);
{
if (!panelp->getFactoryMap().empty())
{
mFactoryStack.push_front(&panelp->getFactoryMap());
}
// for local registry callbacks; define in constructor, referenced in XUI or postBuild
panelp->getCommitCallbackRegistrar().pushScope();
panelp->getEnableCallbackRegistrar().pushScope();
didPost = panelp->initPanelXML(root, NULL, output_node);
panelp->getCommitCallbackRegistrar().popScope();
panelp->getEnableCallbackRegistrar().popScope();
panelp->setXMLFilename(filename);
if (!panelp->getFactoryMap().empty())
{
mFactoryStack.pop_front();
}
}
popFileName();
return didPost;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
@ -337,29 +212,6 @@ LLView *LLUICtrlFactory::createFromXML(LLXMLNodePtr node, LLView* parent, const
return view;
}
//-----------------------------------------------------------------------------
// createFactoryPanel()
//-----------------------------------------------------------------------------
LLPanel* LLUICtrlFactory::createFactoryPanel(const std::string& name)
{
std::deque<const LLCallbackMap::map_t*>::iterator itor;
for (itor = mFactoryStack.begin(); itor != mFactoryStack.end(); ++itor)
{
const LLCallbackMap::map_t* factory_map = *itor;
// Look up this panel's name in the map.
LLCallbackMap::map_const_iter_t iter = factory_map->find( name );
if (iter != factory_map->end())
{
// Use the factory to create the panel, instead of using a default LLPanel.
LLPanel *ret = (LLPanel*) iter->second.mCallback( iter->second.mData );
return ret;
}
}
LLPanel::Params panel_p;
return create<LLPanel>(panel_p);
}
std::string LLUICtrlFactory::getCurFileName()
{
return mFileNames.empty() ? "" : gDirUtilp->getWorkingDir() + gDirUtilp->getDirDelimiter() + mFileNames.back();
@ -376,36 +228,6 @@ void LLUICtrlFactory::popFileName()
mFileNames.pop_back();
}
//-----------------------------------------------------------------------------
//static
BOOL LLUICtrlFactory::getAttributeColor(LLXMLNodePtr node, const std::string& name, LLColor4& color)
{
std::string colorstring;
BOOL res = node->getAttributeString(name.c_str(), colorstring);
if (res)
{
if (LLUIColorTable::instance().colorExists(colorstring))
{
color.setVec(LLUIColorTable::instance().getColor(colorstring));
}
else
{
res = FALSE;
}
}
if (!res)
{
res = LLColor4::parseColor(colorstring, &color);
}
if (!res)
{
res = node->getAttributeColor(name.c_str(), color);
}
return res;
}
//static
void LLUICtrlFactory::setCtrlParent(LLView* view, LLView* parent, S32 tab_group)
{
@ -421,28 +243,22 @@ std::string LLUICtrlFactory::findSkinnedFilename(const std::string& filename)
return gDirUtilp->findSkinnedFilename(LLUI::getSkinPath(), filename);
}
void LLUICtrlFactory::pushFactoryFunctions(const LLCallbackMap::map_t* map)
{
mFactoryStack.push_back(map);
}
void LLUICtrlFactory::popFactoryFunctions()
{
if (!mFactoryStack.empty())
{
mFactoryStack.pop_back();
}
}
//static
void LLUICtrlFactory::copyName(LLXMLNodePtr src, LLXMLNodePtr dest)
{
dest->setName(src->getName()->mString);
}
template<typename T>
const LLInitParam::BaseBlock& get_empty_param_block()
{
static typename T::Params params;
return params;
}
// adds a widget and its param block to various registries
//static
void LLUICtrlFactory::registerWidget(const std::type_info* widget_type, const std::type_info* param_block_type, dummy_widget_creator_func_t creator_func, const std::string& tag)
void LLUICtrlFactory::registerWidget(const std::type_info* widget_type, const std::type_info* param_block_type, const std::string& tag)
{
// associate parameter block type with template .xml file
std::string* existing_tag = LLWidgetNameRegistry::instance().getValue(param_block_type);
@ -462,17 +278,9 @@ void LLUICtrlFactory::registerWidget(const std::type_info* widget_type, const st
}
}
LLWidgetNameRegistry::instance().defaultRegistrar().add(param_block_type, tag);
// associate widget type with factory function
LLDefaultWidgetRegistry::instance().defaultRegistrar().add(widget_type, creator_func);
//FIXME: comment this in when working on schema generation
//LLWidgetTypeRegistry::instance().defaultRegistrar().add(tag, widget_type);
//LLDefaultParamBlockRegistry::instance().defaultRegistrar().add(widget_type, &getEmptyParamBlock<T>);
}
//static
dummy_widget_creator_func_t* LLUICtrlFactory::getDefaultWidgetFunc(const std::type_info* widget_type)
{
return LLDefaultWidgetRegistry::instance().getValue(widget_type);
//LLDefaultParamBlockRegistry::instance().defaultRegistrar().add(widget_type, &get_empty_param_block<T>);
}
//static

View File

@ -27,24 +27,13 @@
#ifndef LLUICTRLFACTORY_H
#define LLUICTRLFACTORY_H
#include "llcallbackmap.h"
#include "llfasttimer.h"
#include "llinitparam.h"
#include "llregistry.h"
#include "v4color.h"
#include "llfasttimer.h"
#include "llxuiparser.h"
#include <boost/function.hpp>
#include <iosfwd>
#include <stack>
#include <set>
class LLPanel;
class LLFloater;
class LLView;
// sort functor for typeid maps
struct LLCompareTypeID
{
@ -85,12 +74,6 @@ class LLWidgetNameRegistry
: public LLRegistrySingleton<const std::type_info*, std::string, LLWidgetNameRegistry , LLCompareTypeID>
{};
// lookup factory functions for default widget instances by widget type
typedef LLView* (*dummy_widget_creator_func_t)(const std::string&);
class LLDefaultWidgetRegistry
: public LLRegistrySingleton<const std::type_info*, dummy_widget_creator_func_t, LLDefaultWidgetRegistry, LLCompareTypeID>
{};
// lookup function for generating empty param block by widget type
// this is used for schema generation
//typedef const LLInitParam::BaseBlock& (*empty_param_block_func_t)();
@ -157,58 +140,21 @@ public:
return ParamDefaults<typename T::Params, 0>::instance().get();
}
bool buildFloater(LLFloater* floaterp, const std::string &filename, LLXMLNodePtr output_node);
BOOL buildPanel(LLPanel* panelp, const std::string &filename, LLXMLNodePtr output_node = NULL);
// Does what you want for LLFloaters and LLPanels
// Returns 0 on success
S32 saveToXML(LLView* viewp, const std::string& filename);
// filename tracking for debugging info
std::string getCurFileName();
void pushFileName(const std::string& name);
void popFileName();
static BOOL getAttributeColor(LLXMLNodePtr node, const std::string& name, LLColor4& color);
LLPanel* createFactoryPanel(const std::string& name);
void pushFactoryFunctions(const LLCallbackMap::map_t* map);
void popFactoryFunctions();
template<typename T>
static T* createWidget(const typename T::Params& params, LLView* parent = NULL)
{
T* widget = NULL;
if (!params.validateBlock())
{
llwarns << getInstance()->getCurFileName() << ": Invalid parameter block for " << typeid(T).name() << llendl;
//return NULL;
}
{
LLFastTimer timer(FTM_WIDGET_CONSTRUCTION);
widget = new T(params);
}
{
LLFastTimer timer(FTM_INIT_FROM_PARAMS);
widget->initFromParams(params);
}
if (parent)
{
S32 tab_group = params.tab_group.isProvided() ? params.tab_group() : S32_MAX;
setCtrlParent(widget, parent, tab_group);
}
return widget;
}
template<typename T>
static T* create(typename T::Params& params, LLView* parent = NULL)
{
params.fillFrom(ParamDefaults<typename T::Params, 0>::instance().get());
T* widget = createWidget<T>(params, parent);
T* widget = createWidgetImpl<T>(params, parent);
if (widget)
{
widget->postBuild();
@ -266,21 +212,54 @@ fail:
template<class T>
static T* getDefaultWidget(const std::string& name)
{
dummy_widget_creator_func_t* dummy_func = getDefaultWidgetFunc(&typeid(T));
return dummy_func ? dynamic_cast<T*>((*dummy_func)(name)) : NULL;
typename T::Params widget_params;
widget_params.name = name;
return create<T>(widget_params);
}
template <class T>
static LLView* createDefaultWidget(const std::string& name)
{
typename T::Params params;
params.name(name);
return create<T>(params);
}
static void createChildren(LLView* viewp, LLXMLNodePtr node, const widget_registry_t&, LLXMLNodePtr output_node = NULL);
static bool getLayeredXMLNode(const std::string &filename, LLXMLNodePtr& root);
static bool getLocalizedXMLNode(const std::string &xui_filename, LLXMLNodePtr& root);
private:
//NOTE: both friend declarations are necessary to keep both gcc and msvc happy
template <typename T> friend class LLChildRegistry;
template <typename T> template <typename U> friend class LLChildRegistry<T>::Register;
static void copyName(LLXMLNodePtr src, LLXMLNodePtr dest);
// helper function for adding widget type info to various registries
static void registerWidget(const std::type_info* widget_type, const std::type_info* param_block_type, const std::string& tag);
static void loadWidgetTemplate(const std::string& widget_tag, LLInitParam::BaseBlock& block);
template<typename T>
static T* createWidgetImpl(const typename T::Params& params, LLView* parent = NULL)
{
T* widget = NULL;
if (!params.validateBlock())
{
llwarns << getInstance()->getCurFileName() << ": Invalid parameter block for " << typeid(T).name() << llendl;
//return NULL;
}
{ LLFastTimer _(FTM_WIDGET_CONSTRUCTION);
widget = new T(params);
}
{ LLFastTimer _(FTM_INIT_FROM_PARAMS);
widget->initFromParams(params);
}
if (parent)
{
S32 tab_group = params.tab_group.isProvided() ? params.tab_group() : S32_MAX;
setCtrlParent(widget, parent, tab_group);
}
return widget;
}
template<typename T>
static T* defaultBuilder(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node)
{
@ -288,7 +267,8 @@ fail:
typename T::Params params(getDefaultParams<T>());
LLXUIParser::instance().readXUI(node, params, LLUICtrlFactory::getInstance()->getCurFileName());
LLXUIParser parser;
parser.readXUI(node, params, LLUICtrlFactory::getInstance()->getCurFileName());
if (output_node)
{
@ -298,14 +278,13 @@ fail:
// Export only the differences between this any default params
typename T::Params default_params(getDefaultParams<T>());
copyName(node, output_node);
LLXUIParser::instance().writeXUI(
output_node, output_params, &default_params);
parser.writeXUI(output_node, output_params, &default_params);
}
// Apply layout transformations, usually munging rect
params.from_xui = true;
T::applyXUILayout(params, parent);
T* widget = createWidget<T>(params, parent);
T* widget = createWidgetImpl<T>(params, parent);
typedef typename T::child_registry_t registry_t;
@ -320,20 +299,6 @@ fail:
return widget;
}
static void createChildren(LLView* viewp, LLXMLNodePtr node, const widget_registry_t&, LLXMLNodePtr output_node = NULL);
static bool getLayeredXMLNode(const std::string &filename, LLXMLNodePtr& root);
static bool getLocalizedXMLNode(const std::string &xui_filename, LLXMLNodePtr& root);
static void loadWidgetTemplate(const std::string& widget_tag, LLInitParam::BaseBlock& block);
// helper function for adding widget type info to various registries
static void registerWidget(const std::type_info* widget_type, const std::type_info* param_block_type, dummy_widget_creator_func_t creator_func, const std::string& tag);
private:
// return default widget instance factory func for a given type
static dummy_widget_creator_func_t* getDefaultWidgetFunc(const std::type_info* widget_type);
static const std::string* getWidgetTag(const std::type_info* widget_type);
@ -343,20 +308,10 @@ private:
// Avoid directly using LLUI and LLDir in the template code
static std::string findSkinnedFilename(const std::string& filename);
typedef std::deque<const LLCallbackMap::map_t*> factory_stack_t;
factory_stack_t mFactoryStack;
LLPanel* mDummyPanel;
class LLPanel* mDummyPanel;
std::vector<std::string> mFileNames;
};
template<typename T>
const LLInitParam::BaseBlock& getEmptyParamBlock()
{
static typename T::Params params;
return params;
}
// this is here to make gcc happy with reference to LLUICtrlFactory
template<typename DERIVED>
template<typename T>
@ -364,7 +319,7 @@ LLChildRegistry<DERIVED>::Register<T>::Register(const char* tag, LLWidgetCreator
: LLChildRegistry<DERIVED>::StaticRegistrar(tag, func.empty() ? (LLWidgetCreatorFunc)&LLUICtrlFactory::defaultBuilder<T> : func)
{
// add this widget to various registries
LLUICtrlFactory::instance().registerWidget(&typeid(T), &typeid(typename T::Params), &LLUICtrlFactory::createDefaultWidget<T>, tag);
LLUICtrlFactory::instance().registerWidget(&typeid(T), &typeid(typename T::Params), tag);
// since registry_t depends on T, do this in line here
// TODO: uncomment this for schema generation
@ -372,58 +327,4 @@ LLChildRegistry<DERIVED>::Register<T>::Register(const char* tag, LLWidgetCreator
//LLChildRegistryRegistry::instance().defaultRegistrar().add(&typeid(T), registry_t::instance());
}
typedef boost::function<LLPanel* (void)> LLPanelClassCreatorFunc;
// local static instance for registering a particular panel class
class LLRegisterPanelClass
: public LLSingleton< LLRegisterPanelClass >
{
public:
// reigister with either the provided builder, or the generic templated builder
void addPanelClass(const std::string& tag,LLPanelClassCreatorFunc func)
{
mPanelClassesNames[tag] = func;
}
LLPanel* createPanelClass(const std::string& tag)
{
param_name_map_t::iterator iT = mPanelClassesNames.find(tag);
if(iT == mPanelClassesNames.end())
return 0;
return iT->second();
}
template<typename T>
static T* defaultPanelClassBuilder()
{
T* pT = new T();
return pT;
}
private:
typedef std::map< std::string, LLPanelClassCreatorFunc> param_name_map_t;
param_name_map_t mPanelClassesNames;
};
// local static instance for registering a particular panel class
template<typename T>
class LLRegisterPanelClassWrapper
: public LLRegisterPanelClass
{
public:
// reigister with either the provided builder, or the generic templated builder
LLRegisterPanelClassWrapper(const std::string& tag);
};
template<typename T>
LLRegisterPanelClassWrapper<T>::LLRegisterPanelClassWrapper(const std::string& tag)
{
LLRegisterPanelClass::instance().addPanelClass(tag,&LLRegisterPanelClass::defaultPanelClassBuilder<T>);
}
#endif //LLUICTRLFACTORY_H

View File

@ -34,7 +34,7 @@ LLFastTimer::DeclareTimer FTM_UI_STRING("UI String");
LLUIString::LLUIString(const std::string& instring, const LLStringUtil::format_map_t& args)
: mOrig(instring),
mArgs(args)
mArgs(new LLStringUtil::format_map_t(args))
{
dirty();
}
@ -48,7 +48,7 @@ void LLUIString::assign(const std::string& s)
void LLUIString::setArgList(const LLStringUtil::format_map_t& args)
{
mArgs = args;
getArgs() = args;
dirty();
}
@ -68,7 +68,7 @@ void LLUIString::setArgs(const LLSD& sd)
void LLUIString::setArg(const std::string& key, const std::string& replacement)
{
mArgs[key] = replacement;
getArgs()[key] = replacement;
dirty();
}
@ -129,14 +129,14 @@ void LLUIString::updateResult() const
mResult = mOrig;
// get the defailt args + local args
if (mArgs.empty())
if (!mArgs || mArgs->empty())
{
LLStringUtil::format(mResult, LLTrans::getDefaultArgs());
}
else
{
LLStringUtil::format_map_t combined_args = LLTrans::getDefaultArgs();
combined_args.insert(mArgs.begin(), mArgs.end());
combined_args.insert(mArgs->begin(), mArgs->end());
LLStringUtil::format(mResult, combined_args);
}
}
@ -147,3 +147,12 @@ void LLUIString::updateWResult() const
mWResult = utf8str_to_wstring(getUpdatedResult());
}
LLStringUtil::format_map_t& LLUIString::getArgs()
{
if (!mArgs)
{
mArgs = new LLStringUtil::format_map_t;
}
return *mArgs;
}

View File

@ -58,9 +58,9 @@ class LLUIString
public:
// These methods all perform appropriate argument substitution
// and modify mOrig where appropriate
LLUIString() : mNeedsResult(false), mNeedsWResult(false) {}
LLUIString() : mArgs(NULL), mNeedsResult(false), mNeedsWResult(false) {}
LLUIString(const std::string& instring, const LLStringUtil::format_map_t& args);
LLUIString(const std::string& instring) { assign(instring); }
LLUIString(const std::string& instring) : mArgs(NULL) { assign(instring); }
void assign(const std::string& instring);
LLUIString& operator=(const std::string& s) { assign(s); return *this; }
@ -80,7 +80,7 @@ public:
S32 length() const { return getUpdatedWResult().size(); }
void clear();
void clearArgs() { mArgs.clear(); }
void clearArgs() { if (mArgs) mArgs->clear(); }
// These utility functions are included for text editing.
// They do not affect mOrig and do not perform argument substitution
@ -99,11 +99,12 @@ private:
// do actual work of updating strings (non-inlined)
void updateResult() const;
void updateWResult() const;
LLStringUtil::format_map_t& getArgs();
std::string mOrig;
mutable std::string mResult;
mutable LLWString mWResult; // for displaying
LLStringUtil::format_map_t mArgs;
LLStringUtil::format_map_t* mArgs;
// controls lazy evaluation
mutable bool mNeedsResult;

View File

@ -102,11 +102,7 @@ LLView::Params::Params()
left_pad("left_pad"),
left_delta("left_delta", S32_MAX),
from_xui("from_xui", false),
user_resize("user_resize"),
auto_resize("auto_resize"),
needs_translate("translate"),
min_width("min_width"),
max_width("max_width"),
xmlns("xmlns"),
xmlns_xsi("xmlns:xsi"),
xsi_schemaLocation("xsi:schemaLocation"),
@ -218,7 +214,7 @@ void LLView::setUseBoundingRect( BOOL use_bounding_rect )
}
}
BOOL LLView::getUseBoundingRect()
BOOL LLView::getUseBoundingRect() const
{
return mUseBoundingRect;
}
@ -1370,12 +1366,12 @@ void LLView::drawDebugRect()
// drawing solids requires texturing be disabled
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
if (mUseBoundingRect)
if (getUseBoundingRect())
{
LLUI::translate((F32)mBoundingRect.mLeft - (F32)mRect.mLeft, (F32)mBoundingRect.mBottom - (F32)mRect.mBottom, 0.f);
}
LLRect debug_rect = mUseBoundingRect ? mBoundingRect : mRect;
LLRect debug_rect = getUseBoundingRect() ? mBoundingRect : mRect;
// draw red rectangle for the border
LLColor4 border_color(0.25f, 0.25f, 0.25f, 1.f);
@ -1573,7 +1569,7 @@ void LLView::updateBoundingRect()
LLRect cur_rect = mBoundingRect;
if (mUseBoundingRect)
if (getUseBoundingRect())
{
mBoundingRect = calcBoundingRect();
}
@ -1583,7 +1579,7 @@ void LLView::updateBoundingRect()
}
// give parent view a chance to resize, in case we just moved, for example
if (getParent() && getParent()->mUseBoundingRect)
if (getParent() && getParent()->getUseBoundingRect())
{
getParent()->updateBoundingRect();
}
@ -1607,7 +1603,7 @@ LLRect LLView::calcScreenBoundingRect() const
{
LLRect screen_rect;
// get bounding rect, if used
LLRect bounding_rect = mUseBoundingRect ? mBoundingRect : mRect;
LLRect bounding_rect = getUseBoundingRect() ? mBoundingRect : mRect;
// convert to local coordinates, as defined by mRect
bounding_rect.translate(-mRect.mLeft, -mRect.mBottom);
@ -1692,7 +1688,9 @@ LLView* LLView::getChildView(const std::string& name, BOOL recurse) const
child = getDefaultWidget<LLView>(name);
if (!child)
{
child = LLUICtrlFactory::createDefaultWidget<LLView>(name);
LLView::Params view_params;
view_params.name = name;
child = LLUICtrlFactory::create<LLView>(view_params);
}
}
return child;
@ -1736,14 +1734,14 @@ LLView* LLView::findChildView(const std::string& name, BOOL recurse) const
BOOL LLView::parentPointInView(S32 x, S32 y, EHitTestType type) const
{
return (mUseBoundingRect && type == HIT_TEST_USE_BOUNDING_RECT)
return (getUseBoundingRect() && type == HIT_TEST_USE_BOUNDING_RECT)
? mBoundingRect.pointInRect( x, y )
: mRect.pointInRect( x, y );
}
BOOL LLView::pointInView(S32 x, S32 y, EHitTestType type) const
{
return (mUseBoundingRect && type == HIT_TEST_USE_BOUNDING_RECT)
return (getUseBoundingRect() && type == HIT_TEST_USE_BOUNDING_RECT)
? mBoundingRect.pointInRect( x + mRect.mLeft, y + mRect.mBottom )
: mRect.localPointInRect( x, y );
}

View File

@ -128,26 +128,22 @@ public:
Optional<std::string> layout;
Optional<LLRect> rect;
// Historical bottom-left layout used bottom_delta and left_delta
// for relative positioning. New layout "topleft" prefers specifying
// based on top edge.
Optional<S32> bottom_delta, // deprecated
top_pad, // from last bottom to my top
top_delta, // from last top to my top
left_pad, // from last right to my left
left_delta; // from last left to my left
// these are nested attributes for LLLayoutPanel
Optional<S32> bottom_delta, // from last bottom to my bottom
top_pad, // from last bottom to my top
top_delta, // from last top to my top
left_pad, // from last right to my left
left_delta; // from last left to my left
//FIXME: get parent context involved in parsing traversal
Ignored user_resize,
auto_resize,
needs_translate,
min_width,
max_width,
xmlns,
xmlns_xsi,
xsi_schemaLocation,
xsi_type;
Ignored needs_translate, // cue for translation tools
xmlns, // xml namespace
xmlns_xsi, // xml namespace
xsi_schemaLocation, // xml schema
xsi_type; // xml schema type
Params();
};
@ -238,7 +234,7 @@ public:
void setSoundFlags(U8 flags) { mSoundFlags = flags; }
void setName(std::string name) { mName = name; }
void setUseBoundingRect( BOOL use_bounding_rect );
BOOL getUseBoundingRect();
BOOL getUseBoundingRect() const;
ECursorType getHoverCursor() { return mHoverCursor; }
@ -277,6 +273,11 @@ public:
BOOL focusNextRoot();
BOOL focusPrevRoot();
// Normally we want the app menus to get priority on accelerated keys
// However, sometimes we want to give specific views a first chance
// iat handling them. (eg. the script editor)
virtual bool hasAccelerators() const { return false; };
// delete all children. Override this function if you need to
// perform any extra clean up such as cached pointers to selected
// children, etc.

View File

@ -120,7 +120,6 @@ namespace LLInitParam
void BaseBlock::init(BlockDescriptor& descriptor, BlockDescriptor& base_descriptor, size_t block_size)
{
mBlockDescriptor = &descriptor;
descriptor.mCurrentBlockPtr = this;
}
bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack){ return true; }

View File

@ -73,7 +73,6 @@ namespace LLInitParam
void BaseBlock::init(BlockDescriptor& descriptor, BlockDescriptor& base_descriptor, size_t block_size)
{
mBlockDescriptor = &descriptor;
descriptor.mCurrentBlockPtr = this;
}

View File

@ -93,7 +93,7 @@ LLDir_Linux::LLDir_Linux()
#else
mAppRODataDir = tmp_str;
#endif
U32 indra_pos = mExecutableDir.find("/indra");
std::string::size_type indra_pos = mExecutableDir.find("/indra");
if (indra_pos != std::string::npos)
{
// ...we're in a dev checkout

View File

@ -116,10 +116,6 @@ LLDir_Win32::LLDir_Win32()
mExecutableDir = utf16str_to_utf8str(llutf16string(w_str));
#endif
mAppRODataDir = ".";
mSkinBaseDir = mAppRODataDir + mDirDelimiter + "skins";
if (mExecutableDir.find("indra") == std::string::npos)
{
// Running from installed directory. Make sure current
@ -129,8 +125,12 @@ LLDir_Win32::LLDir_Win32()
GetCurrentDirectory(MAX_PATH, w_str);
mWorkingDir = utf16str_to_utf8str(llutf16string(w_str));
}
mAppRODataDir = mWorkingDir;
llinfos << "mAppRODataDir = " << mAppRODataDir << llendl;
mSkinBaseDir = mAppRODataDir + mDirDelimiter + "skins";
// Build the default cache directory
mDefaultCacheDir = buildSLOSCacheDir();

View File

@ -68,7 +68,6 @@ namespace LLInitParam
void BlockDescriptor::aggregateBlockData(BlockDescriptor& src_block_data)
{
mNamedParams.insert(src_block_data.mNamedParams.begin(), src_block_data.mNamedParams.end());
mSynonyms.insert(src_block_data.mSynonyms.begin(), src_block_data.mSynonyms.end());
std::copy(src_block_data.mUnnamedParams.begin(), src_block_data.mUnnamedParams.end(), std::back_inserter(mUnnamedParams));
std::copy(src_block_data.mValidationList.begin(), src_block_data.mValidationList.end(), std::back_inserter(mValidationList));
std::copy(src_block_data.mAllParams.begin(), src_block_data.mAllParams.end(), std::back_inserter(mAllParams));
@ -78,8 +77,7 @@ namespace LLInitParam
// BaseBlock
//
BaseBlock::BaseBlock()
: mChangeVersion(0),
mBlockDescriptor(NULL)
: mChangeVersion(0)
{}
BaseBlock::~BaseBlock()
@ -88,8 +86,6 @@ namespace LLInitParam
// called by each derived class in least to most derived order
void BaseBlock::init(BlockDescriptor& descriptor, BlockDescriptor& base_descriptor, size_t block_size)
{
mBlockDescriptor = &descriptor;
descriptor.mCurrentBlockPtr = this;
descriptor.mMaxParamOffset = block_size;
@ -182,7 +178,7 @@ namespace LLInitParam
param_handle_t param_handle = it->second->mParamHandle;
const Param* param = getParamFromHandle(param_handle);
ParamDescriptor::serialize_func_t serialize_func = it->second->mSerializeFunc;
if (serialize_func)
if (serialize_func && param->anyProvided())
{
// Ensure this param has not already been serialized
// Prevents <rect> from being serialized as its own tag.
@ -274,22 +270,6 @@ namespace LLInitParam
}
}
for(BlockDescriptor::param_map_t::const_iterator it = block_data.mSynonyms.begin();
it != block_data.mSynonyms.end();
++it)
{
param_handle_t param_handle = it->second->mParamHandle;
const Param* param = getParamFromHandle(param_handle);
ParamDescriptor::inspect_func_t inspect_func = it->second->mInspectFunc;
if (inspect_func)
{
// use existing serial number for param
name_stack.push_back(std::make_pair(it->first, it->second->mGeneration));
inspect_func(*param, parser, name_stack, it->second->mMinCount, it->second->mMaxCount);
name_stack.pop_back();
}
}
return true;
}
@ -311,22 +291,9 @@ namespace LLInitParam
// find pointer to member parameter from offset table
paramp = getParamFromHandle(found_it->second->mParamHandle);
deserialize_func = found_it->second->mDeserializeFunc;
}
else
{
BlockDescriptor::param_map_t::iterator found_it = block_data.mSynonyms.find(top_name);
if (found_it != block_data.mSynonyms.end())
{
// find pointer to member parameter from offset table
paramp = getParamFromHandle(found_it->second->mParamHandle);
deserialize_func = found_it->second->mDeserializeFunc;
}
}
Parser::name_stack_range_t new_name_stack(name_stack.first, name_stack.second);
++new_name_stack.first;
if (deserialize_func)
{
Parser::name_stack_range_t new_name_stack(name_stack.first, name_stack.second);
++new_name_stack.first;
return deserialize_func(*paramp, p, new_name_stack, name_stack.first == name_stack.second ? -1 : name_stack.first->second);
}
}
@ -401,7 +368,7 @@ namespace LLInitParam
}
else
{
block_data.mSynonyms[synonym] = param_descriptor;
block_data.mNamedParams[synonym] = param_descriptor;
}
}
}
@ -426,14 +393,6 @@ namespace LLInitParam
}
}
for (BlockDescriptor::param_map_t::const_iterator it = block_data.mSynonyms.begin(); it != block_data.mSynonyms.end(); ++it)
{
if (it->second->mParamHandle == handle)
{
return it->first;
}
}
return LLStringUtil::null;
}

View File

@ -34,6 +34,7 @@ f * @file llinitparam.h
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/unordered_map.hpp>
#include "llregistry.h"
#include "llmemory.h"
@ -196,36 +197,39 @@ namespace LLInitParam
typedef std::pair<name_stack_t::const_iterator, name_stack_t::const_iterator> name_stack_range_t;
typedef std::vector<std::string> possible_values_t;
typedef boost::function<bool (void*)> parser_read_func_t;
typedef boost::function<bool (const void*, const name_stack_t&)> parser_write_func_t;
typedef bool (*parser_read_func_t)(Parser& parser, void* output);
typedef bool (*parser_write_func_t)(Parser& parser, const void*, const name_stack_t&);
typedef boost::function<void (const name_stack_t&, S32, S32, const possible_values_t*)> parser_inspect_func_t;
typedef std::map<const std::type_info*, parser_read_func_t, CompareTypeID> parser_read_func_map_t;
typedef std::map<const std::type_info*, parser_write_func_t, CompareTypeID> parser_write_func_map_t;
typedef std::map<const std::type_info*, parser_inspect_func_t, CompareTypeID> parser_inspect_func_map_t;
Parser()
Parser(parser_read_func_map_t& read_map, parser_write_func_map_t& write_map, parser_inspect_func_map_t& inspect_map)
: mParseSilently(false),
mParseGeneration(0)
mParseGeneration(0),
mParserReadFuncs(&read_map),
mParserWriteFuncs(&write_map),
mParserInspectFuncs(&inspect_map)
{}
virtual ~Parser();
template <typename T> bool readValue(T& param)
{
parser_read_func_map_t::iterator found_it = mParserReadFuncs.find(&typeid(T));
if (found_it != mParserReadFuncs.end())
parser_read_func_map_t::iterator found_it = mParserReadFuncs->find(&typeid(T));
if (found_it != mParserReadFuncs->end())
{
return found_it->second((void*)&param);
return found_it->second(*this, (void*)&param);
}
return false;
}
template <typename T> bool writeValue(const T& param, const name_stack_t& name_stack)
{
parser_write_func_map_t::iterator found_it = mParserWriteFuncs.find(&typeid(T));
if (found_it != mParserWriteFuncs.end())
parser_write_func_map_t::iterator found_it = mParserWriteFuncs->find(&typeid(T));
if (found_it != mParserWriteFuncs->end())
{
return found_it->second((const void*)&param, name_stack);
return found_it->second(*this, (const void*)&param, name_stack);
}
return false;
}
@ -233,8 +237,8 @@ namespace LLInitParam
// dispatch inspection to registered inspection functions, for each parameter in a param block
template <typename T> bool inspectValue(const name_stack_t& name_stack, S32 min_count, S32 max_count, const possible_values_t* possible_values)
{
parser_inspect_func_map_t::iterator found_it = mParserInspectFuncs.find(&typeid(T));
if (found_it != mParserInspectFuncs.end())
parser_inspect_func_map_t::iterator found_it = mParserInspectFuncs->find(&typeid(T));
if (found_it != mParserInspectFuncs->end())
{
found_it->second(name_stack, min_count, max_count, possible_values);
return true;
@ -246,7 +250,6 @@ namespace LLInitParam
virtual void parserWarning(const std::string& message);
virtual void parserError(const std::string& message);
void setParseSilently(bool silent) { mParseSilently = silent; }
bool getParseSilently() { return mParseSilently; }
S32 getParseGeneration() { return mParseGeneration; }
S32 newParseGeneration() { return ++mParseGeneration; }
@ -254,24 +257,24 @@ namespace LLInitParam
protected:
template <typename T>
void registerParserFuncs(parser_read_func_t read_func, parser_write_func_t write_func)
void registerParserFuncs(parser_read_func_t read_func, parser_write_func_t write_func = NULL)
{
mParserReadFuncs.insert(std::make_pair(&typeid(T), read_func));
mParserWriteFuncs.insert(std::make_pair(&typeid(T), write_func));
mParserReadFuncs->insert(std::make_pair(&typeid(T), read_func));
mParserWriteFuncs->insert(std::make_pair(&typeid(T), write_func));
}
template <typename T>
void registerInspectFunc(parser_inspect_func_t inspect_func)
{
mParserInspectFuncs.insert(std::make_pair(&typeid(T), inspect_func));
mParserInspectFuncs->insert(std::make_pair(&typeid(T), inspect_func));
}
bool mParseSilently;
private:
parser_read_func_map_t mParserReadFuncs;
parser_write_func_map_t mParserWriteFuncs;
parser_inspect_func_map_t mParserInspectFuncs;
parser_read_func_map_t* mParserReadFuncs;
parser_write_func_map_t* mParserWriteFuncs;
parser_inspect_func_map_t* mParserInspectFuncs;
S32 mParseGeneration;
};
@ -284,7 +287,7 @@ namespace LLInitParam
void setProvided(bool is_provided) { mIsProvided = is_provided; }
protected:
bool getProvided() const { return mIsProvided; }
bool anyProvided() const { return mIsProvided; }
Param(class BaseBlock* enclosing_block);
@ -380,14 +383,13 @@ namespace LLInitParam
void aggregateBlockData(BlockDescriptor& src_block_data);
public:
typedef std::map<const std::string, ParamDescriptor*> param_map_t; // references param descriptors stored in mAllParams
typedef boost::unordered_map<const std::string, ParamDescriptor*> param_map_t; // references param descriptors stored in mAllParams
typedef std::vector<ParamDescriptor*> param_list_t;
typedef std::list<ParamDescriptor> all_params_list_t;// references param descriptors stored in mAllParams
typedef std::vector<std::pair<param_handle_t, ParamDescriptor::validation_func_t> > param_validation_list_t;
param_map_t mNamedParams; // parameters with associated names
param_map_t mSynonyms; // parameters with alternate names
param_list_t mUnnamedParams; // parameters with_out_ associated names
param_validation_list_t mValidationList; // parameters that must be validated
all_params_list_t mAllParams; // all parameters, owns descriptors
@ -473,8 +475,8 @@ namespace LLInitParam
bool serializeBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), const BaseBlock* diff_block = NULL) const;
bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t()) const;
const BlockDescriptor& mostDerivedBlockDescriptor() const { return *mBlockDescriptor; }
BlockDescriptor& mostDerivedBlockDescriptor() { return *mBlockDescriptor; }
virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return selfBlockDescriptor(); }
virtual BlockDescriptor& mostDerivedBlockDescriptor() { return selfBlockDescriptor(); }
// take all provided params from other and apply to self
bool overwriteFrom(const BaseBlock& other)
@ -499,8 +501,6 @@ namespace LLInitParam
// can be updated in getters
mutable S32 mChangeVersion;
BlockDescriptor* mBlockDescriptor; // most derived block descriptor
static BlockDescriptor& selfBlockDescriptor()
{
static BlockDescriptor sBlockDescriptor;
@ -568,7 +568,7 @@ namespace LLInitParam
mData.mValue = value;
}
bool isProvided() const { return Param::getProvided(); }
bool isProvided() const { return Param::anyProvided(); }
static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack, S32 generation)
{
@ -576,7 +576,7 @@ namespace LLInitParam
// no further names in stack, attempt to parse value now
if (name_stack.first == name_stack.second)
{
if (parser.readValue<T>(typed_param.mData.mValue))
if (parser.readValue(typed_param.mData.mValue))
{
typed_param.mData.clearKey();
typed_param.setProvided(true);
@ -589,7 +589,7 @@ namespace LLInitParam
{
// try to parse a known named value
std::string name;
if (parser.readValue<std::string>(name))
if (parser.readValue(name))
{
// try to parse a per type named value
if (NAME_VALUE_LOOKUP::get(name, typed_param.mData.mValue))
@ -624,7 +624,7 @@ namespace LLInitParam
{
if (!diff_param || !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->mData.getKey(), key))
{
if (!parser.writeValue<std::string>(key, name_stack))
if (!parser.writeValue(key, name_stack))
{
return;
}
@ -632,7 +632,7 @@ namespace LLInitParam
}
// then try to serialize value directly
else if (!diff_param || !ParamCompare<T>::equals(typed_param.get(), static_cast<const self_t*>(diff_param)->get())) {
if (!parser.writeValue<T>(typed_param.mData.mValue, name_stack))
if (!parser.writeValue(typed_param.mData.mValue, name_stack))
{
return;
}
@ -745,7 +745,7 @@ namespace LLInitParam
{
// try to parse a known named value
std::string name;
if (parser.readValue<std::string>(name))
if (parser.readValue(name))
{
// try to parse a per type named value
if (NAME_VALUE_LOOKUP::get(name, typed_param))
@ -772,7 +772,7 @@ namespace LLInitParam
std::string key = typed_param.mData.getKey();
if (!key.empty() && typed_param.mData.mKeyVersion == typed_param.getLastChangeVersion())
{
if (!parser.writeValue<std::string>(key, name_stack))
if (!parser.writeValue(key, name_stack))
{
return;
}
@ -795,13 +795,13 @@ namespace LLInitParam
bool isProvided() const
{
// only validate block when it hasn't already passed validation and user has supplied *some* value
if (Param::getProvided() && mData.mValidatedVersion < T::getLastChangeVersion())
if (Param::anyProvided() && mData.mValidatedVersion < T::getLastChangeVersion())
{
// a sub-block is "provided" when it has been filled in enough to be valid
mData.mValidated = T::validateBlock(false);
mData.mValidatedVersion = T::getLastChangeVersion();
}
return Param::getProvided() && mData.mValidated;
return Param::anyProvided() && mData.mValidated;
}
// assign block contents to this param-that-is-a-block
@ -852,7 +852,7 @@ namespace LLInitParam
{
const self_t& src_typed_param = static_cast<const self_t&>(src);
self_t& dst_typed_param = static_cast<self_t&>(dst);
if (dst_typed_param.T::merge(T::selfBlockDescriptor(), src_typed_param, overwrite || !dst_typed_param.isProvided()))
if (dst_typed_param.T::merge(T::selfBlockDescriptor(), src_typed_param, overwrite))
{
dst_typed_param.mData.clearKey();
return true;
@ -909,7 +909,7 @@ namespace LLInitParam
}
}
bool isProvided() const { return Param::getProvided(); }
bool isProvided() const { return Param::anyProvided(); }
static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack, S32 generation)
{
@ -919,7 +919,7 @@ namespace LLInitParam
if (name_stack.first == name_stack.second)
{
// attempt to read value directly
if (parser.readValue<value_t>(value))
if (parser.readValue(value))
{
typed_param.mValues.push_back(value);
// save an empty name/value key as a placeholder
@ -934,7 +934,7 @@ namespace LLInitParam
{
// try to parse a known named value
std::string name;
if (parser.readValue<std::string>(name))
if (parser.readValue(name))
{
// try to parse a per type named value
if (NAME_VALUE_LOOKUP::get(name, typed_param.mValues))
@ -958,7 +958,7 @@ namespace LLInitParam
const self_t& typed_param = static_cast<const self_t&>(param);
if (!typed_param.isProvided() || name_stack.empty()) return;
typename container_t::const_iterator it = typed_param.mValues.begin();
const_iterator it = typed_param.mValues.begin();
for (typename std::vector<key_cache_t>::const_iterator key_it = typed_param.mCachedKeys.begin();
it != typed_param.mValues.end();
++key_it, ++it)
@ -968,13 +968,13 @@ namespace LLInitParam
if(!key.empty())
{
if(!parser.writeValue<std::string>(key, name_stack))
if(!parser.writeValue(key, name_stack))
{
return;
}
}
// not parse via name values, write out value directly
else if (!parser.writeValue<VALUE_TYPE>(*it, name_stack))
else if (!parser.writeValue(*it, name_stack))
{
return;
}
@ -1025,8 +1025,15 @@ namespace LLInitParam
// implicit conversion
operator value_assignment_t() const { return self_t::get(); }
// explicit conversion
value_assignment_t operator()() const { return get(); }
typedef typename container_t::iterator iterator;
typedef typename container_t::const_iterator const_iterator;
iterator begin() { return mValues.begin(); }
iterator end() { return mValues.end(); }
const_iterator begin() const { return mValues.begin(); }
const_iterator end() const { return mValues.end(); }
bool empty() const { return mValues.empty(); }
size_t size() const { return mValues.size(); }
U32 numValidElements() const
{
@ -1092,7 +1099,7 @@ namespace LLInitParam
}
}
bool isProvided() const { return Param::getProvided(); }
bool isProvided() const { return Param::anyProvided(); }
value_ref_t operator[](S32 index) { return mValues[index]; }
value_const_ref_t operator[](S32 index) const { return mValues[index]; }
@ -1100,32 +1107,41 @@ namespace LLInitParam
static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack, S32 generation)
{
self_t& typed_param = static_cast<self_t&>(param);
bool new_value = false;
if (generation != typed_param.mLastParamGeneration || typed_param.mValues.empty())
{
new_value = true;
typed_param.mValues.push_back(value_t());
typed_param.mCachedKeys.push_back(Data());
typed_param.enclosingBlock().setLastChangedParam(param, true);
typed_param.mLastParamGeneration = generation;
}
value_t& value = typed_param.mValues.back();
value_ref_t value = typed_param.mValues.back();
// attempt to parse block...
if(value.deserializeBlock(parser, name_stack))
{
if (new_value)
{ // successfully parsed new value, let's keep it
typed_param.mLastParamGeneration = generation;
}
typed_param.enclosingBlock().setLastChangedParam(param, true);
typed_param.setProvided(true);
return true;
}
if(!NAME_VALUE_LOOKUP::empty())
else if(!NAME_VALUE_LOOKUP::empty())
{
// try to parse a known named value
std::string name;
if (parser.readValue<std::string>(name))
if (parser.readValue(name))
{
// try to parse a per type named value
if (NAME_VALUE_LOOKUP::get(name, value))
{
if (new_value)
{ // successfully parsed new value, let's keep it
typed_param.mLastParamGeneration = generation;
}
typed_param.mCachedKeys.back().setKey(name);
typed_param.mCachedKeys.back().mKeyVersion = value.getLastChangeVersion();
typed_param.enclosingBlock().setLastChangedParam(param, true);
@ -1136,6 +1152,12 @@ namespace LLInitParam
}
}
if (new_value)
{ // failed to parse new value, pop it off
typed_param.mValues.pop_back();
typed_param.mCachedKeys.pop_back();
}
return false;
}
@ -1144,7 +1166,7 @@ namespace LLInitParam
const self_t& typed_param = static_cast<const self_t&>(param);
if (!typed_param.isProvided() || name_stack.empty()) return;
typename container_t::const_iterator it = typed_param.mValues.begin();
const_iterator it = typed_param.mValues.begin();
for (typename std::vector<Data>::const_iterator key_it = typed_param.mCachedKeys.begin();
it != typed_param.mValues.end();
++key_it, ++it)
@ -1154,7 +1176,7 @@ namespace LLInitParam
std::string key = key_it->getKey();
if (!key.empty() && key_it->mKeyVersion == it->getLastChangeVersion())
{
if(!parser.writeValue<std::string>(key, name_stack))
if(!parser.writeValue(key, name_stack))
{
return;
}
@ -1208,13 +1230,20 @@ namespace LLInitParam
// implicit conversion
operator value_assignment_t() const { return self_t::get(); }
// explicit conversion
value_assignment_t operator()() const { return get(); }
typedef typename container_t::iterator iterator;
typedef typename container_t::const_iterator const_iterator;
iterator begin() { return mValues.begin(); }
iterator end() { return mValues.end(); }
const_iterator begin() const { return mValues.begin(); }
const_iterator end() const { return mValues.end(); }
bool empty() const { return mValues.empty(); }
size_t size() const { return mValues.size(); }
U32 numValidElements() const
{
U32 count = 0;
for (typename container_t::const_iterator it = mValues.begin();
for (const_iterator it = mValues.begin();
it != mValues.end();
++it)
{
@ -1306,6 +1335,9 @@ namespace LLInitParam
BaseBlock::setLastChangedParam(last_param, user_provided);
}
virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return selfBlockDescriptor(); }
virtual BlockDescriptor& mostDerivedBlockDescriptor() { return selfBlockDescriptor(); }
protected:
Choice()
: mCurChoice(0)
@ -1415,6 +1447,10 @@ namespace LLInitParam
{
return BaseBlock::merge(selfBlockDescriptor(), other, false);
}
virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return selfBlockDescriptor(); }
virtual BlockDescriptor& mostDerivedBlockDescriptor() { return selfBlockDescriptor(); }
protected:
Block()
{
@ -1494,15 +1530,13 @@ namespace LLInitParam
typedef Multiple<T, RANGE, NAME_VALUE_LOOKUP> self_t;
typedef typename super_t::container_t container_t;
typedef typename super_t::value_assignment_t value_assignment_t;
typedef typename container_t::iterator iterator;
typedef typename container_t::const_iterator const_iterator;
typedef typename super_t::iterator iterator;
typedef typename super_t::const_iterator const_iterator;
explicit Multiple(const char* name = "", value_assignment_t val = DefaultInitializer<container_t>::get())
: super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, &validate, RANGE::minCount(), RANGE::maxCount())
{}
using super_t::operator();
Multiple& operator=(value_assignment_t val)
{
set(val);
@ -1612,7 +1646,7 @@ namespace LLInitParam
// type to apply parse direct value T
if (name_stack.first == name_stack.second)
{
if(parser.readValue<T>(typed_param.mData.mValue))
if(parser.readValue(typed_param.mData.mValue))
{
typed_param.enclosingBlock().setLastChangedParam(param, true);
typed_param.setProvided(true);
@ -1627,7 +1661,7 @@ namespace LLInitParam
{
// try to parse a known named value
std::string name;
if (parser.readValue<std::string>(name))
if (parser.readValue(name))
{
// try to parse a per type named value
if (TypeValues<T>::get(name, typed_param.mData.mValue))
@ -1669,7 +1703,7 @@ namespace LLInitParam
{
if (!diff_param || !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->mData.getKey(), key))
{
if (!parser.writeValue<std::string>(key, name_stack))
if (!parser.writeValue(key, name_stack))
{
return;
}
@ -1679,7 +1713,7 @@ namespace LLInitParam
else if (!diff_param || !ParamCompare<T>::equals(typed_param.get(), (static_cast<const self_t*>(diff_param))->get()))
{
if (parser.writeValue<T>(typed_param.mData.mValue, name_stack))
if (parser.writeValue(typed_param.mData.mValue, name_stack))
{
return;
}
@ -1712,7 +1746,7 @@ namespace LLInitParam
bool isProvided() const
{
if (!Param::getProvided()) return false;
if (!Param::anyProvided()) return false;
// block has an updated parameter
// if cached value is stale, regenerate from params
@ -1779,7 +1813,7 @@ namespace LLInitParam
value_assignment_t get() const
{
// if some parameters were provided, issue warnings on invalid blocks
if (Param::getProvided() && (mData.mValueAge == OLDER_THAN_BLOCK))
if (Param::anyProvided() && (mData.mValueAge == OLDER_THAN_BLOCK))
{
// go ahead and issue warnings at this point if any param is invalid
if(block_t::validateBlock(true))

View File

@ -70,6 +70,11 @@ public:
mMap.erase(key);
}
void replace(ref_const_key_t key, ref_const_value_t value)
{
mMap[key] = value;
}
typename registry_map_t::const_iterator beginItems() const
{
return mMap.begin();

View File

@ -66,7 +66,8 @@ bool LLTrans::parseStrings(LLXMLNodePtr &root, const std::set<std::string>& defa
}
StringTable string_table;
LLXUIParser::instance().readXUI(root, string_table, xml_filename);
LLXUIParser parser;
parser.readXUI(root, string_table, xml_filename);
if (!string_table.validateBlock())
{
@ -77,8 +78,8 @@ bool LLTrans::parseStrings(LLXMLNodePtr &root, const std::set<std::string>& defa
sStringTemplates.clear();
sDefaultArgs.clear();
for(LLInitParam::ParamIterator<StringDef>::const_iterator it = string_table.strings().begin();
it != string_table.strings().end();
for(LLInitParam::ParamIterator<StringDef>::const_iterator it = string_table.strings.begin();
it != string_table.strings.end();
++it)
{
LLTransTemplate xml_template(it->name, it->value);
@ -109,7 +110,8 @@ bool LLTrans::parseLanguageStrings(LLXMLNodePtr &root)
}
StringTable string_table;
LLXUIParser::instance().readXUI(root, string_table, xml_filename);
LLXUIParser parser;
parser.readXUI(root, string_table, xml_filename);
if (!string_table.validateBlock())
{
@ -117,8 +119,8 @@ bool LLTrans::parseLanguageStrings(LLXMLNodePtr &root)
return false;
}
for(LLInitParam::ParamIterator<StringDef>::const_iterator it = string_table.strings().begin();
it != string_table.strings().end();
for(LLInitParam::ParamIterator<StringDef>::const_iterator it = string_table.strings.begin();
it != string_table.strings.end();
++it)
{
// share the same map with parseStrings() so we can search the strings using the same getString() function.- angela

View File

@ -29,17 +29,28 @@
#include "llxuiparser.h"
#include "llxmlnode.h"
#include "expat/expat.h"
#include <fstream>
#include <boost/tokenizer.hpp>
//#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/classic_core.hpp>
#include "lluicolor.h"
using namespace BOOST_SPIRIT_CLASSIC_NS;
const S32 MAX_STRING_ATTRIBUTE_SIZE = 40;
static LLInitParam::Parser::parser_read_func_map_t sXSDReadFuncs;
static LLInitParam::Parser::parser_write_func_map_t sXSDWriteFuncs;
static LLInitParam::Parser::parser_inspect_func_map_t sXSDInspectFuncs;
//
// LLXSDWriter
//
LLXSDWriter::LLXSDWriter()
: Parser(sXSDReadFuncs, sXSDWriteFuncs, sXSDInspectFuncs)
{
registerInspectFunc<bool>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:boolean", _1, _2, _3, _4));
registerInspectFunc<std::string>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:string", _1, _2, _3, _4));
@ -357,41 +368,35 @@ void LLXUIXSDWriter::writeXSD(const std::string& type_name, const std::string& p
fclose(xsd_file);
}
static LLInitParam::Parser::parser_read_func_map_t sXUIReadFuncs;
static LLInitParam::Parser::parser_write_func_map_t sXUIWriteFuncs;
static LLInitParam::Parser::parser_inspect_func_map_t sXUIInspectFuncs;
//
// LLXUIParser
//
LLXUIParser::LLXUIParser()
: mLastWriteGeneration(-1),
: Parser(sXUIReadFuncs, sXUIWriteFuncs, sXUIInspectFuncs),
mLastWriteGeneration(-1),
mCurReadDepth(0)
{
registerParserFuncs<bool>(boost::bind(&LLXUIParser::readBoolValue, this, _1),
boost::bind(&LLXUIParser::writeBoolValue, this, _1, _2));
registerParserFuncs<std::string>(boost::bind(&LLXUIParser::readStringValue, this, _1),
boost::bind(&LLXUIParser::writeStringValue, this, _1, _2));
registerParserFuncs<U8>(boost::bind(&LLXUIParser::readU8Value, this, _1),
boost::bind(&LLXUIParser::writeU8Value, this, _1, _2));
registerParserFuncs<S8>(boost::bind(&LLXUIParser::readS8Value, this, _1),
boost::bind(&LLXUIParser::writeS8Value, this, _1, _2));
registerParserFuncs<U16>(boost::bind(&LLXUIParser::readU16Value, this, _1),
boost::bind(&LLXUIParser::writeU16Value, this, _1, _2));
registerParserFuncs<S16>(boost::bind(&LLXUIParser::readS16Value, this, _1),
boost::bind(&LLXUIParser::writeS16Value, this, _1, _2));
registerParserFuncs<U32>(boost::bind(&LLXUIParser::readU32Value, this, _1),
boost::bind(&LLXUIParser::writeU32Value, this, _1, _2));
registerParserFuncs<S32>(boost::bind(&LLXUIParser::readS32Value, this, _1),
boost::bind(&LLXUIParser::writeS32Value, this, _1, _2));
registerParserFuncs<F32>(boost::bind(&LLXUIParser::readF32Value, this, _1),
boost::bind(&LLXUIParser::writeF32Value, this, _1, _2));
registerParserFuncs<F64>(boost::bind(&LLXUIParser::readF64Value, this, _1),
boost::bind(&LLXUIParser::writeF64Value, this, _1, _2));
registerParserFuncs<LLColor4>(boost::bind(&LLXUIParser::readColor4Value, this, _1),
boost::bind(&LLXUIParser::writeColor4Value, this, _1, _2));
registerParserFuncs<LLUIColor>(boost::bind(&LLXUIParser::readUIColorValue, this, _1),
boost::bind(&LLXUIParser::writeUIColorValue, this, _1, _2));
registerParserFuncs<LLUUID>(boost::bind(&LLXUIParser::readUUIDValue, this, _1),
boost::bind(&LLXUIParser::writeUUIDValue, this, _1, _2));
registerParserFuncs<LLSD>(boost::bind(&LLXUIParser::readSDValue, this, _1),
boost::bind(&LLXUIParser::writeSDValue, this, _1, _2));
if (sXUIReadFuncs.empty())
{
registerParserFuncs<bool>(readBoolValue, writeBoolValue);
registerParserFuncs<std::string>(readStringValue, writeStringValue);
registerParserFuncs<U8>(readU8Value, writeU8Value);
registerParserFuncs<S8>(readS8Value, writeS8Value);
registerParserFuncs<U16>(readU16Value, writeU16Value);
registerParserFuncs<S16>(readS16Value, writeS16Value);
registerParserFuncs<U32>(readU32Value, writeU32Value);
registerParserFuncs<S32>(readS32Value, writeS32Value);
registerParserFuncs<F32>(readF32Value, writeF32Value);
registerParserFuncs<F64>(readF64Value, writeF64Value);
registerParserFuncs<LLColor4>(readColor4Value, writeColor4Value);
registerParserFuncs<LLUIColor>(readUIColorValue, writeUIColorValue);
registerParserFuncs<LLUUID>(readUUIDValue, writeUUIDValue);
registerParserFuncs<LLSD>(readSDValue, writeSDValue);
}
}
static LLFastTimer::DeclareTimer FTM_PARSE_XUI("XUI Parsing");
@ -400,6 +405,7 @@ void LLXUIParser::readXUI(LLXMLNodePtr node, LLInitParam::BaseBlock& block, cons
{
LLFastTimer timer(FTM_PARSE_XUI);
mNameStack.clear();
mRootNodeName = node->getName()->mString;
mCurFileName = filename;
mCurReadDepth = 0;
setParseSilently(silent);
@ -410,11 +416,11 @@ void LLXUIParser::readXUI(LLXMLNodePtr node, LLInitParam::BaseBlock& block, cons
}
else
{
readXUIImpl(node, std::string(node->getName()->mString), block);
readXUIImpl(node, block);
}
}
bool LLXUIParser::readXUIImpl(LLXMLNodePtr nodep, const std::string& scope, LLInitParam::BaseBlock& block)
bool LLXUIParser::readXUIImpl(LLXMLNodePtr nodep, LLInitParam::BaseBlock& block)
{
typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
boost::char_separator<char> sep(".");
@ -481,7 +487,15 @@ bool LLXUIParser::readXUIImpl(LLXMLNodePtr nodep, const std::string& scope, LLIn
}
// check for proper nesting
if(!scope.empty() && *name_token_it != scope)
if (mNameStack.empty())
{
if (*name_token_it != mRootNodeName)
{
childp = childp->getNextSibling();
continue;
}
}
else if(mNameStack.back().first != *name_token_it)
{
childp = childp->getNextSibling();
continue;
@ -499,7 +513,7 @@ bool LLXUIParser::readXUIImpl(LLXMLNodePtr nodep, const std::string& scope, LLIn
}
// recurse and visit children XML nodes
if(readXUIImpl(childp, mNameStack.empty() ? scope : mNameStack.back().first, block))
if(readXUIImpl(childp, block))
{
// child node successfully parsed, remove from DOM
@ -615,17 +629,19 @@ LLXMLNodePtr LLXUIParser::getNode(const name_stack_t& stack)
}
bool LLXUIParser::readBoolValue(void* val_ptr)
bool LLXUIParser::readBoolValue(Parser& parser, void* val_ptr)
{
S32 value;
bool success = mCurReadNode->getBoolValue(1, &value);
LLXUIParser& self = static_cast<LLXUIParser&>(parser);
bool success = self.mCurReadNode->getBoolValue(1, &value);
*((bool*)val_ptr) = (value != FALSE);
return success;
}
bool LLXUIParser::writeBoolValue(const void* val_ptr, const name_stack_t& stack)
bool LLXUIParser::writeBoolValue(Parser& parser, const void* val_ptr, const name_stack_t& stack)
{
LLXMLNodePtr node = getNode(stack);
LLXUIParser& self = static_cast<LLXUIParser&>(parser);
LLXMLNodePtr node = self.getNode(stack);
if (node.notNull())
{
node->setBoolValue(*((bool*)val_ptr));
@ -634,15 +650,17 @@ bool LLXUIParser::writeBoolValue(const void* val_ptr, const name_stack_t& stack)
return false;
}
bool LLXUIParser::readStringValue(void* val_ptr)
bool LLXUIParser::readStringValue(Parser& parser, void* val_ptr)
{
*((std::string*)val_ptr) = mCurReadNode->getSanitizedValue();
LLXUIParser& self = static_cast<LLXUIParser&>(parser);
*((std::string*)val_ptr) = self.mCurReadNode->getSanitizedValue();
return true;
}
bool LLXUIParser::writeStringValue(const void* val_ptr, const name_stack_t& stack)
bool LLXUIParser::writeStringValue(Parser& parser, const void* val_ptr, const name_stack_t& stack)
{
LLXMLNodePtr node = getNode(stack);
LLXUIParser& self = static_cast<LLXUIParser&>(parser);
LLXMLNodePtr node = self.getNode(stack);
if (node.notNull())
{
const std::string* string_val = reinterpret_cast<const std::string*>(val_ptr);
@ -671,14 +689,16 @@ bool LLXUIParser::writeStringValue(const void* val_ptr, const name_stack_t& stac
return false;
}
bool LLXUIParser::readU8Value(void* val_ptr)
bool LLXUIParser::readU8Value(Parser& parser, void* val_ptr)
{
return mCurReadNode->getByteValue(1, (U8*)val_ptr);
LLXUIParser& self = static_cast<LLXUIParser&>(parser);
return self.mCurReadNode->getByteValue(1, (U8*)val_ptr);
}
bool LLXUIParser::writeU8Value(const void* val_ptr, const name_stack_t& stack)
bool LLXUIParser::writeU8Value(Parser& parser, const void* val_ptr, const name_stack_t& stack)
{
LLXMLNodePtr node = getNode(stack);
LLXUIParser& self = static_cast<LLXUIParser&>(parser);
LLXMLNodePtr node = self.getNode(stack);
if (node.notNull())
{
node->setUnsignedValue(*((U8*)val_ptr));
@ -687,10 +707,11 @@ bool LLXUIParser::writeU8Value(const void* val_ptr, const name_stack_t& stack)
return false;
}
bool LLXUIParser::readS8Value(void* val_ptr)
bool LLXUIParser::readS8Value(Parser& parser, void* val_ptr)
{
LLXUIParser& self = static_cast<LLXUIParser&>(parser);
S32 value;
if(mCurReadNode->getIntValue(1, &value))
if(self.mCurReadNode->getIntValue(1, &value))
{
*((S8*)val_ptr) = value;
return true;
@ -698,9 +719,10 @@ bool LLXUIParser::readS8Value(void* val_ptr)
return false;
}
bool LLXUIParser::writeS8Value(const void* val_ptr, const name_stack_t& stack)
bool LLXUIParser::writeS8Value(Parser& parser, const void* val_ptr, const name_stack_t& stack)
{
LLXMLNodePtr node = getNode(stack);
LLXUIParser& self = static_cast<LLXUIParser&>(parser);
LLXMLNodePtr node = self.getNode(stack);
if (node.notNull())
{
node->setIntValue(*((S8*)val_ptr));
@ -709,10 +731,11 @@ bool LLXUIParser::writeS8Value(const void* val_ptr, const name_stack_t& stack)
return false;
}
bool LLXUIParser::readU16Value(void* val_ptr)
bool LLXUIParser::readU16Value(Parser& parser, void* val_ptr)
{
LLXUIParser& self = static_cast<LLXUIParser&>(parser);
U32 value;
if(mCurReadNode->getUnsignedValue(1, &value))
if(self.mCurReadNode->getUnsignedValue(1, &value))
{
*((U16*)val_ptr) = value;
return true;
@ -720,9 +743,10 @@ bool LLXUIParser::readU16Value(void* val_ptr)
return false;
}
bool LLXUIParser::writeU16Value(const void* val_ptr, const name_stack_t& stack)
bool LLXUIParser::writeU16Value(Parser& parser, const void* val_ptr, const name_stack_t& stack)
{
LLXMLNodePtr node = getNode(stack);
LLXUIParser& self = static_cast<LLXUIParser&>(parser);
LLXMLNodePtr node = self.getNode(stack);
if (node.notNull())
{
node->setUnsignedValue(*((U16*)val_ptr));
@ -731,10 +755,11 @@ bool LLXUIParser::writeU16Value(const void* val_ptr, const name_stack_t& stack)
return false;
}
bool LLXUIParser::readS16Value(void* val_ptr)
bool LLXUIParser::readS16Value(Parser& parser, void* val_ptr)
{
LLXUIParser& self = static_cast<LLXUIParser&>(parser);
S32 value;
if(mCurReadNode->getIntValue(1, &value))
if(self.mCurReadNode->getIntValue(1, &value))
{
*((S16*)val_ptr) = value;
return true;
@ -742,9 +767,10 @@ bool LLXUIParser::readS16Value(void* val_ptr)
return false;
}
bool LLXUIParser::writeS16Value(const void* val_ptr, const name_stack_t& stack)
bool LLXUIParser::writeS16Value(Parser& parser, const void* val_ptr, const name_stack_t& stack)
{
LLXMLNodePtr node = getNode(stack);
LLXUIParser& self = static_cast<LLXUIParser&>(parser);
LLXMLNodePtr node = self.getNode(stack);
if (node.notNull())
{
node->setIntValue(*((S16*)val_ptr));
@ -753,14 +779,16 @@ bool LLXUIParser::writeS16Value(const void* val_ptr, const name_stack_t& stack)
return false;
}
bool LLXUIParser::readU32Value(void* val_ptr)
bool LLXUIParser::readU32Value(Parser& parser, void* val_ptr)
{
return mCurReadNode->getUnsignedValue(1, (U32*)val_ptr);
LLXUIParser& self = static_cast<LLXUIParser&>(parser);
return self.mCurReadNode->getUnsignedValue(1, (U32*)val_ptr);
}
bool LLXUIParser::writeU32Value(const void* val_ptr, const name_stack_t& stack)
bool LLXUIParser::writeU32Value(Parser& parser, const void* val_ptr, const name_stack_t& stack)
{
LLXMLNodePtr node = getNode(stack);
LLXUIParser& self = static_cast<LLXUIParser&>(parser);
LLXMLNodePtr node = self.getNode(stack);
if (node.notNull())
{
node->setUnsignedValue(*((U32*)val_ptr));
@ -769,14 +797,16 @@ bool LLXUIParser::writeU32Value(const void* val_ptr, const name_stack_t& stack)
return false;
}
bool LLXUIParser::readS32Value(void* val_ptr)
bool LLXUIParser::readS32Value(Parser& parser, void* val_ptr)
{
return mCurReadNode->getIntValue(1, (S32*)val_ptr);
LLXUIParser& self = static_cast<LLXUIParser&>(parser);
return self.mCurReadNode->getIntValue(1, (S32*)val_ptr);
}
bool LLXUIParser::writeS32Value(const void* val_ptr, const name_stack_t& stack)
bool LLXUIParser::writeS32Value(Parser& parser, const void* val_ptr, const name_stack_t& stack)
{
LLXMLNodePtr node = getNode(stack);
LLXUIParser& self = static_cast<LLXUIParser&>(parser);
LLXMLNodePtr node = self.getNode(stack);
if (node.notNull())
{
node->setIntValue(*((S32*)val_ptr));
@ -785,14 +815,16 @@ bool LLXUIParser::writeS32Value(const void* val_ptr, const name_stack_t& stack)
return false;
}
bool LLXUIParser::readF32Value(void* val_ptr)
bool LLXUIParser::readF32Value(Parser& parser, void* val_ptr)
{
return mCurReadNode->getFloatValue(1, (F32*)val_ptr);
LLXUIParser& self = static_cast<LLXUIParser&>(parser);
return self.mCurReadNode->getFloatValue(1, (F32*)val_ptr);
}
bool LLXUIParser::writeF32Value(const void* val_ptr, const name_stack_t& stack)
bool LLXUIParser::writeF32Value(Parser& parser, const void* val_ptr, const name_stack_t& stack)
{
LLXMLNodePtr node = getNode(stack);
LLXUIParser& self = static_cast<LLXUIParser&>(parser);
LLXMLNodePtr node = self.getNode(stack);
if (node.notNull())
{
node->setFloatValue(*((F32*)val_ptr));
@ -801,14 +833,16 @@ bool LLXUIParser::writeF32Value(const void* val_ptr, const name_stack_t& stack)
return false;
}
bool LLXUIParser::readF64Value(void* val_ptr)
bool LLXUIParser::readF64Value(Parser& parser, void* val_ptr)
{
return mCurReadNode->getDoubleValue(1, (F64*)val_ptr);
LLXUIParser& self = static_cast<LLXUIParser&>(parser);
return self.mCurReadNode->getDoubleValue(1, (F64*)val_ptr);
}
bool LLXUIParser::writeF64Value(const void* val_ptr, const name_stack_t& stack)
bool LLXUIParser::writeF64Value(Parser& parser, const void* val_ptr, const name_stack_t& stack)
{
LLXMLNodePtr node = getNode(stack);
LLXUIParser& self = static_cast<LLXUIParser&>(parser);
LLXMLNodePtr node = self.getNode(stack);
if (node.notNull())
{
node->setDoubleValue(*((F64*)val_ptr));
@ -817,10 +851,11 @@ bool LLXUIParser::writeF64Value(const void* val_ptr, const name_stack_t& stack)
return false;
}
bool LLXUIParser::readColor4Value(void* val_ptr)
bool LLXUIParser::readColor4Value(Parser& parser, void* val_ptr)
{
LLXUIParser& self = static_cast<LLXUIParser&>(parser);
LLColor4* colorp = (LLColor4*)val_ptr;
if(mCurReadNode->getFloatValue(4, colorp->mV) >= 3)
if(self.mCurReadNode->getFloatValue(4, colorp->mV) >= 3)
{
return true;
}
@ -828,9 +863,10 @@ bool LLXUIParser::readColor4Value(void* val_ptr)
return false;
}
bool LLXUIParser::writeColor4Value(const void* val_ptr, const name_stack_t& stack)
bool LLXUIParser::writeColor4Value(Parser& parser, const void* val_ptr, const name_stack_t& stack)
{
LLXMLNodePtr node = getNode(stack);
LLXUIParser& self = static_cast<LLXUIParser&>(parser);
LLXMLNodePtr node = self.getNode(stack);
if (node.notNull())
{
LLColor4 color = *((LLColor4*)val_ptr);
@ -840,11 +876,12 @@ bool LLXUIParser::writeColor4Value(const void* val_ptr, const name_stack_t& stac
return false;
}
bool LLXUIParser::readUIColorValue(void* val_ptr)
bool LLXUIParser::readUIColorValue(Parser& parser, void* val_ptr)
{
LLXUIParser& self = static_cast<LLXUIParser&>(parser);
LLUIColor* param = (LLUIColor*)val_ptr;
LLColor4 color;
bool success = mCurReadNode->getFloatValue(4, color.mV) >= 3;
bool success = self.mCurReadNode->getFloatValue(4, color.mV) >= 3;
if (success)
{
param->set(color);
@ -853,9 +890,10 @@ bool LLXUIParser::readUIColorValue(void* val_ptr)
return false;
}
bool LLXUIParser::writeUIColorValue(const void* val_ptr, const name_stack_t& stack)
bool LLXUIParser::writeUIColorValue(Parser& parser, const void* val_ptr, const name_stack_t& stack)
{
LLXMLNodePtr node = getNode(stack);
LLXUIParser& self = static_cast<LLXUIParser&>(parser);
LLXMLNodePtr node = self.getNode(stack);
if (node.notNull())
{
LLUIColor color = *((LLUIColor*)val_ptr);
@ -868,11 +906,12 @@ bool LLXUIParser::writeUIColorValue(const void* val_ptr, const name_stack_t& sta
return false;
}
bool LLXUIParser::readUUIDValue(void* val_ptr)
bool LLXUIParser::readUUIDValue(Parser& parser, void* val_ptr)
{
LLXUIParser& self = static_cast<LLXUIParser&>(parser);
LLUUID temp_id;
// LLUUID::set is destructive, so use temporary value
if (temp_id.set(mCurReadNode->getSanitizedValue()))
if (temp_id.set(self.mCurReadNode->getSanitizedValue()))
{
*(LLUUID*)(val_ptr) = temp_id;
return true;
@ -880,9 +919,10 @@ bool LLXUIParser::readUUIDValue(void* val_ptr)
return false;
}
bool LLXUIParser::writeUUIDValue(const void* val_ptr, const name_stack_t& stack)
bool LLXUIParser::writeUUIDValue(Parser& parser, const void* val_ptr, const name_stack_t& stack)
{
LLXMLNodePtr node = getNode(stack);
LLXUIParser& self = static_cast<LLXUIParser&>(parser);
LLXMLNodePtr node = self.getNode(stack);
if (node.notNull())
{
node->setStringValue(((LLUUID*)val_ptr)->asString());
@ -891,15 +931,18 @@ bool LLXUIParser::writeUUIDValue(const void* val_ptr, const name_stack_t& stack)
return false;
}
bool LLXUIParser::readSDValue(void* val_ptr)
bool LLXUIParser::readSDValue(Parser& parser, void* val_ptr)
{
*((LLSD*)val_ptr) = LLSD(mCurReadNode->getSanitizedValue());
LLXUIParser& self = static_cast<LLXUIParser&>(parser);
*((LLSD*)val_ptr) = LLSD(self.mCurReadNode->getSanitizedValue());
return true;
}
bool LLXUIParser::writeSDValue(const void* val_ptr, const name_stack_t& stack)
bool LLXUIParser::writeSDValue(Parser& parser, const void* val_ptr, const name_stack_t& stack)
{
LLXMLNodePtr node = getNode(stack);
LLXUIParser& self = static_cast<LLXUIParser&>(parser);
LLXMLNodePtr node = self.getNode(stack);
if (node.notNull())
{
std::string string_val = ((LLSD*)val_ptr)->asString();
@ -962,3 +1005,438 @@ void LLXUIParser::parserError(const std::string& message)
Parser::parserError(message);
#endif
}
//
// LLSimpleXUIParser
//
struct ScopedFile
{
ScopedFile( const std::string& filename, const char* accessmode )
{
mFile = LLFile::fopen(filename, accessmode);
}
~ScopedFile()
{
fclose(mFile);
mFile = NULL;
}
S32 getRemainingBytes()
{
if (!isOpen()) return 0;
S32 cur_pos = ftell(mFile);
fseek(mFile, 0L, SEEK_END);
S32 file_size = ftell(mFile);
fseek(mFile, cur_pos, SEEK_SET);
return file_size - cur_pos;
}
bool isOpen() { return mFile != NULL; }
LLFILE* mFile;
};
static LLInitParam::Parser::parser_read_func_map_t sSimpleXUIReadFuncs;
static LLInitParam::Parser::parser_write_func_map_t sSimpleXUIWriteFuncs;
static LLInitParam::Parser::parser_inspect_func_map_t sSimpleXUIInspectFuncs;
LLSimpleXUIParser::LLSimpleXUIParser(LLSimpleXUIParser::element_start_callback_t element_cb)
: Parser(sSimpleXUIReadFuncs, sSimpleXUIWriteFuncs, sSimpleXUIInspectFuncs),
mLastWriteGeneration(-1),
mCurReadDepth(0),
mElementCB(element_cb)
{
if (sSimpleXUIReadFuncs.empty())
{
registerParserFuncs<bool>(readBoolValue);
registerParserFuncs<std::string>(readStringValue);
registerParserFuncs<U8>(readU8Value);
registerParserFuncs<S8>(readS8Value);
registerParserFuncs<U16>(readU16Value);
registerParserFuncs<S16>(readS16Value);
registerParserFuncs<U32>(readU32Value);
registerParserFuncs<S32>(readS32Value);
registerParserFuncs<F32>(readF32Value);
registerParserFuncs<F64>(readF64Value);
registerParserFuncs<LLColor4>(readColor4Value);
registerParserFuncs<LLUIColor>(readUIColorValue);
registerParserFuncs<LLUUID>(readUUIDValue);
registerParserFuncs<LLSD>(readSDValue);
}
}
LLSimpleXUIParser::~LLSimpleXUIParser()
{
}
bool LLSimpleXUIParser::readXUI(const std::string& filename, LLInitParam::BaseBlock& block, bool silent)
{
LLFastTimer timer(FTM_PARSE_XUI);
mParser = XML_ParserCreate(NULL);
XML_SetUserData(mParser, this);
XML_SetElementHandler( mParser, startElementHandler, endElementHandler);
XML_SetCharacterDataHandler( mParser, characterDataHandler);
mOutputStack.push_back(std::make_pair(&block, 0));
mNameStack.clear();
mCurFileName = filename;
mCurReadDepth = 0;
setParseSilently(silent);
ScopedFile file(filename, "rb");
if( !file.isOpen() )
{
LL_WARNS("ReadXUI") << "Unable to open file " << filename << LL_ENDL;
return false;
}
S32 bytes_read = 0;
S32 buffer_size = file.getRemainingBytes();
void* buffer = XML_GetBuffer(mParser, buffer_size);
if( !buffer )
{
LL_WARNS("ReadXUI") << "Unable to allocate XML buffer while reading file " << filename << LL_ENDL;
XML_ParserFree( mParser );
return false;
}
bytes_read = (S32)fread(buffer, 1, buffer_size, file.mFile);
if( bytes_read <= 0 )
{
LL_WARNS("ReadXUI") << "Error while reading file " << filename << LL_ENDL;
XML_ParserFree( mParser );
return false;
}
if( !XML_ParseBuffer(mParser, bytes_read, TRUE ) )
{
LL_WARNS("ReadXUI") << "Error while parsing file " << filename << LL_ENDL;
XML_ParserFree( mParser );
return false;
}
XML_ParserFree( mParser );
return true;
}
void LLSimpleXUIParser::startElementHandler(void *userData, const char *name, const char **atts)
{
LLSimpleXUIParser* self = reinterpret_cast<LLSimpleXUIParser*>(userData);
self->startElement(name, atts);
}
void LLSimpleXUIParser::endElementHandler(void *userData, const char *name)
{
LLSimpleXUIParser* self = reinterpret_cast<LLSimpleXUIParser*>(userData);
self->endElement(name);
}
void LLSimpleXUIParser::characterDataHandler(void *userData, const char *s, int len)
{
LLSimpleXUIParser* self = reinterpret_cast<LLSimpleXUIParser*>(userData);
self->characterData(s, len);
}
void LLSimpleXUIParser::startElement(const char *name, const char **atts)
{
processText();
typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
boost::char_separator<char> sep(".");
if (mElementCB)
{
LLInitParam::BaseBlock* blockp = mElementCB(*this, name);
if (blockp)
{
mOutputStack.push_back(std::make_pair(blockp, 0));
}
}
mOutputStack.back().second++;
S32 num_tokens_pushed = 0;
std::string child_name(name);
if (mOutputStack.back().second == 1)
{ // root node for this block
mScope.push_back(child_name);
}
else
{ // compound attribute
if (child_name.find(".") == std::string::npos)
{
mNameStack.push_back(std::make_pair(child_name, newParseGeneration()));
num_tokens_pushed++;
mScope.push_back(child_name);
}
else
{
// parse out "dotted" name into individual tokens
tokenizer name_tokens(child_name, sep);
tokenizer::iterator name_token_it = name_tokens.begin();
if(name_token_it == name_tokens.end())
{
return;
}
// check for proper nesting
if(!mScope.empty() && *name_token_it != mScope.back())
{
return;
}
// now ignore first token
++name_token_it;
// copy remaining tokens on to our running token list
for(tokenizer::iterator token_to_push = name_token_it; token_to_push != name_tokens.end(); ++token_to_push)
{
mNameStack.push_back(std::make_pair(*token_to_push, newParseGeneration()));
num_tokens_pushed++;
}
mScope.push_back(mNameStack.back().first);
}
}
mTokenSizeStack.push_back(num_tokens_pushed);
readAttributes(atts);
}
bool LLSimpleXUIParser::readAttributes(const char **atts)
{
typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
boost::char_separator<char> sep(".");
bool any_parsed = false;
for(S32 i = 0; atts[i] && atts[i+1]; i += 2 )
{
std::string attribute_name(atts[i]);
mCurAttributeValueBegin = atts[i+1];
S32 num_tokens_pushed = 0;
tokenizer name_tokens(attribute_name, sep);
// copy remaining tokens on to our running token list
for(tokenizer::iterator token_to_push = name_tokens.begin(); token_to_push != name_tokens.end(); ++token_to_push)
{
mNameStack.push_back(std::make_pair(*token_to_push, newParseGeneration()));
num_tokens_pushed++;
}
// child nodes are not necessarily valid attributes, so don't complain once we've recursed
any_parsed |= mOutputStack.back().first->submitValue(mNameStack, *this, mParseSilently);
while(num_tokens_pushed-- > 0)
{
mNameStack.pop_back();
}
}
return any_parsed;
}
void LLSimpleXUIParser::processText()
{
if (!mTextContents.empty())
{
LLStringUtil::trim(mTextContents);
if (!mTextContents.empty())
{
mNameStack.push_back(std::make_pair(std::string("value"), newParseGeneration()));
mCurAttributeValueBegin = mTextContents.c_str();
mOutputStack.back().first->submitValue(mNameStack, *this, mParseSilently);
mNameStack.pop_back();
}
mTextContents.clear();
}
}
void LLSimpleXUIParser::endElement(const char *name)
{
processText();
if (--mOutputStack.back().second == 0)
{
if (mOutputStack.empty())
{
LL_ERRS("ReadXUI") << "Parameter block output stack popped while empty." << LL_ENDL;
}
mOutputStack.pop_back();
}
S32 num_tokens_to_pop = mTokenSizeStack.back();
mTokenSizeStack.pop_back();
while(num_tokens_to_pop-- > 0)
{
mNameStack.pop_back();
}
mScope.pop_back();
}
void LLSimpleXUIParser::characterData(const char *s, int len)
{
mTextContents += std::string(s, len);
}
/*virtual*/ std::string LLSimpleXUIParser::getCurrentElementName()
{
std::string full_name;
for (name_stack_t::iterator it = mNameStack.begin();
it != mNameStack.end();
++it)
{
full_name += it->first + "."; // build up dotted names: "button.param.nestedparam."
}
return full_name;
}
const S32 LINE_NUMBER_HERE = 0;
void LLSimpleXUIParser::parserWarning(const std::string& message)
{
#ifdef LL_WINDOWS
// use Visual Studo friendly formatting of output message for easy access to originating xml
llutf16string utf16str = utf8str_to_utf16str(llformat("%s(%d):\t%s", mCurFileName.c_str(), LINE_NUMBER_HERE, message.c_str()).c_str());
utf16str += '\n';
OutputDebugString(utf16str.c_str());
#else
Parser::parserWarning(message);
#endif
}
void LLSimpleXUIParser::parserError(const std::string& message)
{
#ifdef LL_WINDOWS
llutf16string utf16str = utf8str_to_utf16str(llformat("%s(%d):\t%s", mCurFileName.c_str(), LINE_NUMBER_HERE, message.c_str()).c_str());
utf16str += '\n';
OutputDebugString(utf16str.c_str());
#else
Parser::parserError(message);
#endif
}
bool LLSimpleXUIParser::readBoolValue(Parser& parser, void* val_ptr)
{
LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
if (!strcmp(self.mCurAttributeValueBegin, "true"))
{
*((bool*)val_ptr) = true;
return true;
}
else if (!strcmp(self.mCurAttributeValueBegin, "false"))
{
*((bool*)val_ptr) = false;
return true;
}
return false;
}
bool LLSimpleXUIParser::readStringValue(Parser& parser, void* val_ptr)
{
LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
*((std::string*)val_ptr) = self.mCurAttributeValueBegin;
return true;
}
bool LLSimpleXUIParser::readU8Value(Parser& parser, void* val_ptr)
{
LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
return parse(self.mCurAttributeValueBegin, uint_p[assign_a(*(U8*)val_ptr)]).full;
}
bool LLSimpleXUIParser::readS8Value(Parser& parser, void* val_ptr)
{
LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
return parse(self.mCurAttributeValueBegin, int_p[assign_a(*(S8*)val_ptr)]).full;
}
bool LLSimpleXUIParser::readU16Value(Parser& parser, void* val_ptr)
{
LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
return parse(self.mCurAttributeValueBegin, uint_p[assign_a(*(U16*)val_ptr)]).full;
}
bool LLSimpleXUIParser::readS16Value(Parser& parser, void* val_ptr)
{
LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
return parse(self.mCurAttributeValueBegin, int_p[assign_a(*(S16*)val_ptr)]).full;
}
bool LLSimpleXUIParser::readU32Value(Parser& parser, void* val_ptr)
{
LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
return parse(self.mCurAttributeValueBegin, uint_p[assign_a(*(U32*)val_ptr)]).full;
}
bool LLSimpleXUIParser::readS32Value(Parser& parser, void* val_ptr)
{
LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
return parse(self.mCurAttributeValueBegin, int_p[assign_a(*(S32*)val_ptr)]).full;
}
bool LLSimpleXUIParser::readF32Value(Parser& parser, void* val_ptr)
{
LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
return parse(self.mCurAttributeValueBegin, real_p[assign_a(*(F32*)val_ptr)]).full;
}
bool LLSimpleXUIParser::readF64Value(Parser& parser, void* val_ptr)
{
LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
return parse(self.mCurAttributeValueBegin, real_p[assign_a(*(F64*)val_ptr)]).full;
}
bool LLSimpleXUIParser::readColor4Value(Parser& parser, void* val_ptr)
{
LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
LLColor4 value;
if (parse(self.mCurAttributeValueBegin, real_p[assign_a(value.mV[0])] >> real_p[assign_a(value.mV[1])] >> real_p[assign_a(value.mV[2])] >> real_p[assign_a(value.mV[3])], space_p).full)
{
*(LLColor4*)(val_ptr) = value;
return true;
}
return false;
}
bool LLSimpleXUIParser::readUIColorValue(Parser& parser, void* val_ptr)
{
LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
LLColor4 value;
LLUIColor* colorp = (LLUIColor*)val_ptr;
if (parse(self.mCurAttributeValueBegin, real_p[assign_a(value.mV[0])] >> real_p[assign_a(value.mV[1])] >> real_p[assign_a(value.mV[2])] >> real_p[assign_a(value.mV[3])], space_p).full)
{
colorp->set(value);
return true;
}
return false;
}
bool LLSimpleXUIParser::readUUIDValue(Parser& parser, void* val_ptr)
{
LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
LLUUID temp_id;
// LLUUID::set is destructive, so use temporary value
if (temp_id.set(std::string(self.mCurAttributeValueBegin)))
{
*(LLUUID*)(val_ptr) = temp_id;
return true;
}
return false;
}
bool LLSimpleXUIParser::readSDValue(Parser& parser, void* val_ptr)
{
LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
*((LLSD*)val_ptr) = LLSD(self.mCurAttributeValueBegin);
return true;
}

View File

@ -96,14 +96,12 @@ public:
class LLXUIParser : public LLInitParam::Parser, public LLSingleton<LLXUIParser>
class LLXUIParser : public LLInitParam::Parser
{
LOG_CLASS(LLXUIParser);
protected:
LLXUIParser();
friend class LLSingleton<LLXUIParser>;
public:
LLXUIParser();
typedef LLInitParam::Parser::name_stack_t name_stack_t;
/*virtual*/ std::string getCurrentElementName();
@ -114,42 +112,40 @@ public:
void writeXUI(LLXMLNodePtr node, const LLInitParam::BaseBlock& block, const LLInitParam::BaseBlock* diff_block = NULL);
private:
typedef std::list<std::pair<std::string, bool> > token_list_t;
bool readXUIImpl(LLXMLNodePtr node, const std::string& scope, LLInitParam::BaseBlock& block);
bool readXUIImpl(LLXMLNodePtr node, LLInitParam::BaseBlock& block);
bool readAttributes(LLXMLNodePtr nodep, LLInitParam::BaseBlock& block);
//reader helper functions
bool readBoolValue(void* val_ptr);
bool readStringValue(void* val_ptr);
bool readU8Value(void* val_ptr);
bool readS8Value(void* val_ptr);
bool readU16Value(void* val_ptr);
bool readS16Value(void* val_ptr);
bool readU32Value(void* val_ptr);
bool readS32Value(void* val_ptr);
bool readF32Value(void* val_ptr);
bool readF64Value(void* val_ptr);
bool readColor4Value(void* val_ptr);
bool readUIColorValue(void* val_ptr);
bool readUUIDValue(void* val_ptr);
bool readSDValue(void* val_ptr);
static bool readBoolValue(Parser& parser, void* val_ptr);
static bool readStringValue(Parser& parser, void* val_ptr);
static bool readU8Value(Parser& parser, void* val_ptr);
static bool readS8Value(Parser& parser, void* val_ptr);
static bool readU16Value(Parser& parser, void* val_ptr);
static bool readS16Value(Parser& parser, void* val_ptr);
static bool readU32Value(Parser& parser, void* val_ptr);
static bool readS32Value(Parser& parser, void* val_ptr);
static bool readF32Value(Parser& parser, void* val_ptr);
static bool readF64Value(Parser& parser, void* val_ptr);
static bool readColor4Value(Parser& parser, void* val_ptr);
static bool readUIColorValue(Parser& parser, void* val_ptr);
static bool readUUIDValue(Parser& parser, void* val_ptr);
static bool readSDValue(Parser& parser, void* val_ptr);
//writer helper functions
bool writeBoolValue(const void* val_ptr, const name_stack_t&);
bool writeStringValue(const void* val_ptr, const name_stack_t&);
bool writeU8Value(const void* val_ptr, const name_stack_t&);
bool writeS8Value(const void* val_ptr, const name_stack_t&);
bool writeU16Value(const void* val_ptr, const name_stack_t&);
bool writeS16Value(const void* val_ptr, const name_stack_t&);
bool writeU32Value(const void* val_ptr, const name_stack_t&);
bool writeS32Value(const void* val_ptr, const name_stack_t&);
bool writeF32Value(const void* val_ptr, const name_stack_t&);
bool writeF64Value(const void* val_ptr, const name_stack_t&);
bool writeColor4Value(const void* val_ptr, const name_stack_t&);
bool writeUIColorValue(const void* val_ptr, const name_stack_t&);
bool writeUUIDValue(const void* val_ptr, const name_stack_t&);
bool writeSDValue(const void* val_ptr, const name_stack_t&);
static bool writeBoolValue(Parser& parser, const void* val_ptr, const name_stack_t&);
static bool writeStringValue(Parser& parser, const void* val_ptr, const name_stack_t&);
static bool writeU8Value(Parser& parser, const void* val_ptr, const name_stack_t&);
static bool writeS8Value(Parser& parser, const void* val_ptr, const name_stack_t&);
static bool writeU16Value(Parser& parser, const void* val_ptr, const name_stack_t&);
static bool writeS16Value(Parser& parser, const void* val_ptr, const name_stack_t&);
static bool writeU32Value(Parser& parser, const void* val_ptr, const name_stack_t&);
static bool writeS32Value(Parser& parser, const void* val_ptr, const name_stack_t&);
static bool writeF32Value(Parser& parser, const void* val_ptr, const name_stack_t&);
static bool writeF64Value(Parser& parser, const void* val_ptr, const name_stack_t&);
static bool writeColor4Value(Parser& parser, const void* val_ptr, const name_stack_t&);
static bool writeUIColorValue(Parser& parser, const void* val_ptr, const name_stack_t&);
static bool writeUUIDValue(Parser& parser, const void* val_ptr, const name_stack_t&);
static bool writeSDValue(Parser& parser, const void* val_ptr, const name_stack_t&);
LLXMLNodePtr getNode(const name_stack_t& stack);
@ -165,6 +161,78 @@ private:
LLXMLNodePtr mLastWrittenChild;
S32 mCurReadDepth;
std::string mCurFileName;
std::string mRootNodeName;
};
// LLSimpleXUIParser is a streamlined SAX-based XUI parser that does not support localization
// or parsing of a tree of independent param blocks, such as child widgets.
// Use this for reading non-localized files that only need a single param block as a result.
//
// NOTE: In order to support nested block parsing, we need callbacks for start element that
// push new blocks contexts on the mScope stack.
// NOTE: To support localization without building a DOM, we need to enforce consistent
// ordering of child elements from base file to localized diff file. Then we can use a pair
// of coroutines to perform matching of xml nodes during parsing. Not sure if the overhead
// of coroutines would offset the gain from SAX parsing
class LLSimpleXUIParser : public LLInitParam::Parser
{
LOG_CLASS(LLSimpleXUIParser);
public:
typedef LLInitParam::Parser::name_stack_t name_stack_t;
typedef LLInitParam::BaseBlock* (*element_start_callback_t)(LLSimpleXUIParser&, const char* block_name);
LLSimpleXUIParser(element_start_callback_t element_cb = NULL);
virtual ~LLSimpleXUIParser();
/*virtual*/ std::string getCurrentElementName();
/*virtual*/ void parserWarning(const std::string& message);
/*virtual*/ void parserError(const std::string& message);
bool readXUI(const std::string& filename, LLInitParam::BaseBlock& block, bool silent=false);
private:
//reader helper functions
static bool readBoolValue(Parser&, void* val_ptr);
static bool readStringValue(Parser&, void* val_ptr);
static bool readU8Value(Parser&, void* val_ptr);
static bool readS8Value(Parser&, void* val_ptr);
static bool readU16Value(Parser&, void* val_ptr);
static bool readS16Value(Parser&, void* val_ptr);
static bool readU32Value(Parser&, void* val_ptr);
static bool readS32Value(Parser&, void* val_ptr);
static bool readF32Value(Parser&, void* val_ptr);
static bool readF64Value(Parser&, void* val_ptr);
static bool readColor4Value(Parser&, void* val_ptr);
static bool readUIColorValue(Parser&, void* val_ptr);
static bool readUUIDValue(Parser&, void* val_ptr);
static bool readSDValue(Parser&, void* val_ptr);
private:
static void startElementHandler(void *userData, const char *name, const char **atts);
static void endElementHandler(void *userData, const char *name);
static void characterDataHandler(void *userData, const char *s, int len);
void startElement(const char *name, const char **atts);
void endElement(const char *name);
void characterData(const char *s, int len);
bool readAttributes(const char **atts);
void processText();
Parser::name_stack_t mNameStack;
struct XML_ParserStruct* mParser;
S32 mLastWriteGeneration;
LLXMLNodePtr mLastWrittenChild;
S32 mCurReadDepth;
std::string mCurFileName;
std::string mTextContents;
const char* mCurAttributeValueBegin;
std::vector<S32> mTokenSizeStack;
std::vector<std::string> mScope;
element_start_callback_t mElementCB;
std::vector<std::pair<LLInitParam::BaseBlock*, S32> > mOutputStack;
};

View File

@ -42,13 +42,6 @@ set(media_plugin_gstreamer010_HEADER_FILES
llmediaimplgstreamertriviallogging.h
)
if (${CXX_VERSION_NUMBER} MATCHES "4[23456789].")
# Work around a bad interaction between broken gstreamer headers and
# g++ >= 4.2's increased strictness.
set_source_files_properties(llmediaimplgstreamervidplug.cpp PROPERTIES
COMPILE_FLAGS -Wno-write-strings)
endif (${CXX_VERSION_NUMBER} MATCHES "4[23456789].")
add_library(media_plugin_gstreamer010
SHARED
${media_plugin_gstreamer010_SOURCE_FILES}

View File

@ -48,7 +48,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_slvideo_debug);
#define SLV_ALLCAPS GST_VIDEO_CAPS_RGBx SLV_SIZECAPS
static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE (
"sink",
(gchar*)"sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (SLV_ALLCAPS)
@ -508,18 +508,18 @@ plugin_init (GstPlugin * plugin)
some g++ versions buggily avoid __attribute__((constructor)) functions -
so we provide an explicit plugin init function.
*/
#define PACKAGE (gchar*)"packagehack"
// this macro quietly refers to PACKAGE internally
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
GST_VERSION_MINOR,
(gchar*)"private-slvideoplugin",
(gchar*)"SL Video sink plugin",
plugin_init, (gchar*)"1.0", (gchar*)"LGPL",
(gchar*)"Second Life",
(gchar*)"http://www.secondlife.com/");
#undef PACKAGE
void gst_slvideo_init_class (void)
{
#define PACKAGE "packagehack"
// this macro quietly refers to PACKAGE internally
static GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
GST_VERSION_MINOR,
"private-slvideoplugin",
"SL Video sink plugin",
plugin_init, "0.1", GST_LICENSE_UNKNOWN,
"Second Life",
"http://www.secondlife.com/");
#undef PACKAGE
ll_gst_plugin_register_static (&gst_plugin_desc);
DEBUGMSG("CLASS INIT");
}

View File

@ -51,9 +51,9 @@ set(media_plugin_webkit_LINK_LIBRARIES
# Select which VolumeCatcher implementation to use
if (LINUX)
if (PULSEAUDIO)
if (PULSEAUDIO_FOUND)
list(APPEND media_plugin_webkit_SOURCE_FILES linux_volume_catcher.cpp)
endif (PULSEAUDIO)
endif (PULSEAUDIO_FOUND)
list(APPEND media_plugin_webkit_LINK_LIBRARIES
${UI_LIBRARIES} # for glib/GTK
)

View File

@ -115,6 +115,7 @@ private:
F32 mBackgroundR;
F32 mBackgroundG;
F32 mBackgroundB;
std::string mTarget;
VolumeCatcher mVolumeCatcher;
@ -303,7 +304,7 @@ private:
LLQtWebKit::getInstance()->enableJavascript( mJavascriptEnabled );
// create single browser window
mBrowserWindowId = LLQtWebKit::getInstance()->createBrowserWindow( mWidth, mHeight );
mBrowserWindowId = LLQtWebKit::getInstance()->createBrowserWindow( mWidth, mHeight, mTarget);
// tell LLQtWebKit about the size of the browser window
LLQtWebKit::getInstance()->setSize( mBrowserWindowId, mWidth, mHeight );
@ -313,9 +314,6 @@ private:
// append details to agent string
LLQtWebKit::getInstance()->setBrowserAgentId( mUserAgent );
// Set up window open behavior
LLQtWebKit::getInstance()->setWindowOpenBehavior(mBrowserWindowId, LLQtWebKit::WOB_SIMULATE_BLANK_HREF_CLICK);
#if !LL_QTWEBKIT_USES_PIXMAPS
// don't flip bitmap
@ -507,9 +505,9 @@ private:
void onClickLinkHref(const EventType& event)
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_href");
message.setValue("uri", event.getStringValue());
message.setValue("target", event.getStringValue2());
message.setValueU32("target_type", event.getLinkType());
message.setValue("uri", event.getEventUri());
message.setValue("target", event.getStringValue());
message.setValue("uuid", event.getStringValue2());
sendMessage(message);
}
@ -518,7 +516,7 @@ private:
void onClickLinkNoFollow(const EventType& event)
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_nofollow");
message.setValue("uri", event.getStringValue());
message.setValue("uri", event.getEventUri());
sendMessage(message);
}
@ -534,6 +532,42 @@ private:
// message.setValueBoolean("dead", (event.getIntValue() != 0))
sendMessage(message);
}
////////////////////////////////////////////////////////////////////////////////
// virtual
void onWindowCloseRequested(const EventType& event)
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "close_request");
message.setValue("uuid", event.getStringValue());
sendMessage(message);
}
////////////////////////////////////////////////////////////////////////////////
// virtual
void onWindowGeometryChangeRequested(const EventType& event)
{
int x, y, width, height;
event.getRectValue(x, y, width, height);
// This sometimes gets called with a zero-size request. Don't pass these along.
if(width > 0 && height > 0)
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "geometry_change");
message.setValue("uuid", event.getStringValue());
message.setValueS32("x", x);
message.setValueS32("y", y);
message.setValueS32("width", width);
message.setValueS32("height", height);
sendMessage(message);
}
}
////////////////////////////////////////////////////////////////////////////////
// virtual
std::string onRequestFilePicker( const EventType& eventIn )
{
return blockingPickFile();
}
LLQtWebKit::EKeyboardModifier decodeModifiers(std::string &modifiers)
{
@ -679,6 +713,26 @@ private:
}
}
std::string mPickedFile;
std::string blockingPickFile(void)
{
mPickedFile.clear();
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "pick_file");
message.setValueBoolean("blocking_request", true);
// The "blocking_request" key in the message means this sendMessage call will block until a response is received.
sendMessage(message);
return mPickedFile;
}
void onPickFileResponse(const std::string &file)
{
mPickedFile = file;
}
};
@ -817,6 +871,8 @@ void MediaPluginWebKit::receiveMessage(const char *message_string)
{
if(message_name == "init")
{
mTarget = message_in.getValue("target");
// This is the media init message -- all necessary data for initialization should have been received.
if(initBrowser())
{
@ -1036,10 +1092,14 @@ void MediaPluginWebKit::receiveMessage(const char *message_string)
LLQtWebKit::getInstance()->userAction( mBrowserWindowId, LLQtWebKit::UA_EDIT_PASTE );
checkEditState();
}
if(message_name == "pick_file_response")
{
onPickFileResponse(message_in.getValue("file"));
}
else
{
// std::cerr << "MediaPluginWebKit::receiveMessage: unknown media message: " << message_string << std::endl;
};
}
}
else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER)
{
@ -1139,6 +1199,17 @@ void MediaPluginWebKit::receiveMessage(const char *message_string)
}
}
}
else if(message_name == "proxy_window_opened")
{
std::string target = message_in.getValue("target");
std::string uuid = message_in.getValue("uuid");
LLQtWebKit::getInstance()->proxyWindowOpened(mBrowserWindowId, target, uuid);
}
else if(message_name == "proxy_window_closed")
{
std::string uuid = message_in.getValue("uuid");
LLQtWebKit::getInstance()->proxyWindowClosed(mBrowserWindowId, uuid);
}
else
{
// std::cerr << "MediaPluginWebKit::receiveMessage: unknown media_browser message: " << message_string << std::endl;

View File

@ -94,6 +94,7 @@ set(viewer_SOURCE_FILES
llbottomtray.cpp
llbox.cpp
llbreadcrumbview.cpp
llbrowsernotification.cpp
llbuycurrencyhtml.cpp
llcallbacklist.cpp
llcallfloater.cpp
@ -216,7 +217,6 @@ set(viewer_SOURCE_FILES
llfloatertos.cpp
llfloateruipreview.cpp
llfloaterurlentry.cpp
llfloatervoicedevicesettings.cpp
llfloatervoiceeffect.cpp
llfloaterwater.cpp
llfloaterwhitelistentry.cpp
@ -234,6 +234,7 @@ set(viewer_SOURCE_FILES
llgroupiconctrl.cpp
llgrouplist.cpp
llgroupmgr.cpp
llhints.cpp
llhomelocationresponder.cpp
llhudeffect.cpp
llhudeffectbeam.cpp
@ -305,6 +306,7 @@ set(viewer_SOURCE_FILES
llnotificationalerthandler.cpp
llnotificationgrouphandler.cpp
llnotificationhandlerutil.cpp
llnotificationhinthandler.cpp
llnotificationmanager.cpp
llnotificationofferhandler.cpp
llnotificationscripthandler.cpp
@ -364,6 +366,7 @@ set(viewer_SOURCE_FILES
llpaneltiptoast.cpp
llpanelvoiceeffect.cpp
llpaneltopinfobar.cpp
llpanelvoicedevicesettings.cpp
llpanelvolume.cpp
llpanelvolumepulldown.cpp
llpanelwearing.cpp
@ -746,7 +749,6 @@ set(viewer_HEADER_FILES
llfloatertos.h
llfloateruipreview.h
llfloaterurlentry.h
llfloatervoicedevicesettings.h
llfloatervoiceeffect.h
llfloaterwater.h
llfloaterwhitelistentry.h
@ -764,6 +766,7 @@ set(viewer_HEADER_FILES
llgroupiconctrl.h
llgrouplist.h
llgroupmgr.h
llhints.h
llhomelocationresponder.h
llhudeffect.h
llhudeffectbeam.h
@ -887,6 +890,7 @@ set(viewer_HEADER_FILES
llpanelprofileview.h
llpanelteleporthistory.h
llpaneltiptoast.h
llpanelvoicedevicesettings.h
llpanelvoiceeffect.h
llpaneltopinfobar.h
llpanelvolume.h
@ -1313,6 +1317,7 @@ set(viewer_APPSETTINGS_FILES
app_settings/cmd_line.xml
app_settings/grass.xml
app_settings/high_graphics.xml
app_settings/ignorable_dialogs.xml
app_settings/keys.ini
app_settings/keywords.ini
app_settings/logcontrol.xml

View File

@ -296,7 +296,7 @@
<key>multiple</key>
<map>
<key>desc</key>
<string>Allow multple viewers.</string>
<string>Allow multiple viewers.</string>
<key>map-to</key>
<string>AllowMultipleViewers</string>
</map>

View File

@ -1,10 +1,10 @@
<?xml version="1.0" ?>
<llsd>
<map>
<key>FirstAppearance</key>
<key>FirstInventoryOffer</key>
<map>
<key>Comment</key>
<string>Enables FirstAppearance warning dialog</string>
<string>Shows hint when a person or object offers resident an inventory item</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@ -12,120 +12,54 @@
<key>Value</key>
<integer>1</integer>
</map>
<key>FirstAttach</key>
<key>FirstNotUseDestinationGuide</key>
<map>
<key>Comment</key>
<string>Shows hint when resident doesn't activate destination guide</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>FirstNotUseSidePanel</key>
<map>
<key>Comment</key>
<string>Shows hint when resident doesn't activate side panel</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>FirstNotMoving</key>
<map>
<key>Comment</key>
<string>Shows hint when resident doesn't move</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>FirstReceiveLindens</key>
<map>
<key>Comment</key>
<string>Shows hint when resident receives linden dollars</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>FirstOtherChatBeforeUser</key>
<map>
<key>Comment</key>
<string>Enables FirstAttach warning dialog</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>FirstBalanceDecrease</key>
<map>
<key>Comment</key>
<string>Enables FirstBalanceDecrease warning dialog</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>FirstBalanceIncrease</key>
<map>
<key>Comment</key>
<string>Enables FirstBalanceIncrease warning dialog</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>FirstBuild</key>
<map>
<key>Comment</key>
<string>Enables FirstBuild warning dialog</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>FirstDebugMenus</key>
<map>
<key>Comment</key>
<string>Enables FirstDebugMenus warning dialog</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>FirstFlexible</key>
<map>
<key>Comment</key>
<string>Enables FirstFlexible warning dialog</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>FirstGoTo</key>
<map>
<key>Comment</key>
<string>Enables FirstGoTo warning dialog</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>FirstInventory</key>
<map>
<key>Comment</key>
<string>Enables FirstInventory warning dialog</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>FirstLeftClickNoHit</key>
<map>
<key>Comment</key>
<string>Enables FirstLeftClickNoHit warning dialog</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>FirstMap</key>
<map>
<key>Comment</key>
<string>Enables FirstMap warning dialog</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>FirstMedia</key>
<map>
<key>Comment</key>
<string>Enables FirstMedia warning dialog</string>
<string>Shows hint when someone else chats first</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@ -155,43 +89,11 @@
<key>Value</key>
<integer>1</integer>
</map>
<key>FirstSculptedPrim</key>
<map>
<key>Comment</key>
<string>Enables FirstSculptedPrim warning dialog</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>FirstSit</key>
<map>
<key>Comment</key>
<string>Enables FirstSit warning dialog</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>FirstTeleport</key>
<map>
<key>Comment</key>
<string>Enables FirstTeleport warning dialog</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>FirstVoice</key>
<map>
<key>Comment</key>
<string>Enables FirstVoice warning dialog</string>
<string>Shows hint when someone sits for the first time</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>

View File

@ -2842,6 +2842,17 @@
<key>Value</key>
<integer>0</integer>
</map>
<key>EnableUIHints</key>
<map>
<key>Comment</key>
<string>Toggles UI hint popups</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>EnableVoiceChat</key>
<map>
<key>Comment</key>
@ -3826,7 +3837,7 @@
<key>Comment</key>
<string>URL for the web page to display in the Home side panel</string>
<key>Persist</key>
<integer>0</integer>
<integer>1</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
@ -5219,6 +5230,17 @@
<key>Value</key>
<real>3.0</real>
</map>
<key>MediaEnablePopups</key>
<map>
<key>Comment</key>
<string>If true, enable targeted links and javascript in media to open new media browser windows without a prompt.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>MediaOnAPrimUI</key>
<map>
<key>Comment</key>
@ -6480,6 +6502,17 @@
<key>Value</key>
<real>1.0</real>
</map>
<key>MediaBrowserWindowLimit</key>
<map>
<key>Comment</key>
<string>Maximum number of media brower windows that can be open at once (0 for no limit)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>S32</string>
<key>Value</key>
<integer>5</integer>
</map>
<key>MediaRollOffRate</key>
<map>
<key>Comment</key>
@ -7899,6 +7932,17 @@
<key>Value</key>
<integer>0</integer>
</map>
<key>RenderHighlightSelections</key>
<map>
<key>Comment</key>
<string>Show selection outlines on objects</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>RenderHiddenSelections</key>
<map>
<key>Comment</key>
@ -8921,7 +8965,7 @@
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
<integer>0</integer>
</map>
<key>GroupListShowIcons</key>
<map>
@ -12057,5 +12101,38 @@
<key>Value</key>
<integer>10</integer>
</map>
<key>NotMovingHintTimeout</key>
<map>
<key>Comment</key>
<string>Number of seconds to wait for resident to move before displaying move hint.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>120.0</real>
</map>
<key>DestinationGuideHintTimeout</key>
<map>
<key>Comment</key>
<string>Number of seconds to wait before telling resident about destination guide.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>600.0</real>
</map>
<key>SidePanelHintTimeout</key>
<map>
<key>Comment</key>
<string>Number of seconds to wait before telling resident about side panel.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>300.0</real>
</map>
</map>
</llsd>

View File

@ -550,4 +550,3 @@ list NVIDIA_GeForce_Go_7800
RenderShaderLightingMaxLevel 1 2
list NVIDIA_GeForce_Go_7900
RenderShaderLightingMaxLevel 1 2

View File

@ -38,6 +38,7 @@
#include "llcallingcard.h"
#include "llchannelmanager.h"
#include "llconsole.h"
#include "llfirstuse.h"
#include "llfloatercamera.h"
#include "llfloaterreg.h"
#include "llfloatertools.h"
@ -194,8 +195,6 @@ LLAgent::LLAgent() :
mbFlagsDirty(FALSE),
mbFlagsNeedReset(FALSE),
mbJump(FALSE),
mAutoPilot(FALSE),
mAutoPilotFlyOnStop(FALSE),
mAutoPilotTargetGlobal(),
@ -227,8 +226,9 @@ LLAgent::LLAgent() :
mControlsTakenPassedOnCount[i] = 0;
}
mListener.reset(new LLAgentListener(*this));
mMoveTimer.stop();
}
// Requires gSavedSettings to be initialized.
@ -237,6 +237,8 @@ LLAgent::LLAgent() :
//-----------------------------------------------------------------------------
void LLAgent::init()
{
mMoveTimer.start();
gSavedSettings.declareBOOL("SlowMotionAnimation", FALSE, "Declared in code", FALSE);
gSavedSettings.getControl("SlowMotionAnimation")->getSignal()->connect(boost::bind(&handleSlowMotionAnimation, _2));
@ -301,6 +303,9 @@ void LLAgent::ageChat()
//-----------------------------------------------------------------------------
void LLAgent::moveAt(S32 direction, bool reset)
{
mMoveTimer.reset();
LLFirstUse::notMoving(false);
// age chat timer so it fades more quickly when you are intentionally moving
ageChat();
@ -326,6 +331,9 @@ void LLAgent::moveAt(S32 direction, bool reset)
//-----------------------------------------------------------------------------
void LLAgent::moveAtNudge(S32 direction)
{
mMoveTimer.reset();
LLFirstUse::notMoving(false);
// age chat timer so it fades more quickly when you are intentionally moving
ageChat();
@ -348,6 +356,9 @@ void LLAgent::moveAtNudge(S32 direction)
//-----------------------------------------------------------------------------
void LLAgent::moveLeft(S32 direction)
{
mMoveTimer.reset();
LLFirstUse::notMoving(false);
// age chat timer so it fades more quickly when you are intentionally moving
ageChat();
@ -370,6 +381,9 @@ void LLAgent::moveLeft(S32 direction)
//-----------------------------------------------------------------------------
void LLAgent::moveLeftNudge(S32 direction)
{
mMoveTimer.reset();
LLFirstUse::notMoving(false);
// age chat timer so it fades more quickly when you are intentionally moving
ageChat();
@ -392,6 +406,9 @@ void LLAgent::moveLeftNudge(S32 direction)
//-----------------------------------------------------------------------------
void LLAgent::moveUp(S32 direction)
{
mMoveTimer.reset();
LLFirstUse::notMoving(false);
// age chat timer so it fades more quickly when you are intentionally moving
ageChat();
@ -537,6 +554,9 @@ void LLAgent::toggleFlying()
{
BOOL fly = !gAgent.getFlying();
gAgent.mMoveTimer.reset();
LLFirstUse::notMoving(false);
gAgent.setFlying( fly );
gAgentCamera.resetView();
}
@ -1534,6 +1554,11 @@ void LLAgent::propagate(const F32 dt)
//-----------------------------------------------------------------------------
void LLAgent::updateAgentPosition(const F32 dt, const F32 yaw_radians, const S32 mouse_x, const S32 mouse_y)
{
if (mMoveTimer.getStarted() && mMoveTimer.getElapsedTimeF32() > gSavedSettings.getF32("NotMovingHintTimeout"))
{
LLFirstUse::notMoving();
}
propagate(dt);
// static S32 cameraUpdateCount = 0;
@ -2962,12 +2987,6 @@ void LLAgent::processScriptControlChange(LLMessageSystem *msg, void **)
total_count++;
}
}
// Any control taken? If so, might be first time.
//if (total_count > 0)
//{
//LLFirstUse::useOverrideKeys();
//}
}
else
{
@ -3431,16 +3450,16 @@ void LLAgent::setTeleportState(ETeleportState state)
break;
case TELEPORT_MOVING:
// We're outa here. Save "back" slurl.
LLAgentUI::buildSLURL(mTeleportSourceSLURL);
// We're outa here. Save "back" slurl.
LLAgentUI::buildSLURL(mTeleportSourceSLURL);
break;
case TELEPORT_ARRIVING:
// First two position updates after a teleport tend to be weird
LLViewerStats::getInstance()->mAgentPositionSnaps.mCountOfNextUpdatesToIgnore = 2;
// Let the interested parties know we've teleported.
LLViewerParcelMgr::getInstance()->onTeleportFinished(false, getPositionGlobal());
// First two position updates after a teleport tend to be weird
LLViewerStats::getInstance()->mAgentPositionSnaps.mCountOfNextUpdatesToIgnore = 2;
// Let the interested parties know we've teleported.
LLViewerParcelMgr::getInstance()->onTeleportFinished(false, getPositionGlobal());
break;
default:

View File

@ -264,6 +264,7 @@ public:
private:
LLFrameTimer mFidgetTimer;
LLFrameTimer mFocusObjectFadeTimer;
LLFrameTimer mMoveTimer;
F32 mNextFidgetTime;
S32 mCurrentFidget;
@ -359,14 +360,6 @@ public:
private:
BOOL mIsBusy;
//--------------------------------------------------------------------
// Jump
//--------------------------------------------------------------------
public:
BOOL getJump() const { return mbJump; }
private:
BOOL mbJump;
//--------------------------------------------------------------------
// Grab
//--------------------------------------------------------------------

View File

@ -262,6 +262,7 @@ const F64 FRAME_STALL_THRESHOLD = 1.0;
LLTimer gRenderStartTime;
LLFrameTimer gForegroundTime;
LLFrameTimer gLoggedInTime;
LLTimer gLogoutTimer;
static const F32 LOGOUT_REQUEST_TIME = 6.f; // this will be cut short by the LogoutReply msg.
F32 gLogoutMaxTime = LOGOUT_REQUEST_TIME;
@ -360,19 +361,19 @@ bool create_text_segment_icon_from_url_match(LLUrlMatch* match,LLTextBase* base)
if(gAgent.isInGroup(match_id, TRUE))
{
LLGroupIconCtrl::Params icon_params = LLUICtrlFactory::instance().getDefaultParams<LLGroupIconCtrl>();
LLGroupIconCtrl::Params icon_params;
icon_params.group_id = match_id;
icon_params.rect = LLRect(0, 16, 16, 0);
icon_params.visible = true;
icon = LLUICtrlFactory::instance().createWidget<LLGroupIconCtrl>(icon_params);
icon = LLUICtrlFactory::instance().create<LLGroupIconCtrl>(icon_params);
}
else
{
LLAvatarIconCtrl::Params icon_params = LLUICtrlFactory::instance().getDefaultParams<LLAvatarIconCtrl>();
LLAvatarIconCtrl::Params icon_params;
icon_params.avatar_id = match_id;
icon_params.rect = LLRect(0, 16, 16, 0);
icon_params.visible = true;
icon = LLUICtrlFactory::instance().createWidget<LLAvatarIconCtrl>(icon_params);
icon = LLUICtrlFactory::instance().create<LLAvatarIconCtrl>(icon_params);
}
LLInlineViewSegment::Params params;
@ -588,6 +589,7 @@ LLAppViewer::LLAppViewer() :
setupErrorHandling();
sInstance = this;
gLoggedInTime.stop();
}
LLAppViewer::~LLAppViewer()
@ -925,8 +927,9 @@ bool LLAppViewer::init()
//EXT-7013 - On windows for some locale (Japanese) standard
//datetime formatting functions didn't support some parameters such as "weekday".
//Names for days and months localized in xml are also useful for Polish locale(STORM-107).
std::string language = LLControlGroup::getInstance(sGlobalSettingsName)->getString("Language");
if(language == "ja")
if(language == "ja" || language == "pl")
{
LLStringOps::setupWeekDaysNames(LLTrans::getString("dateTimeWeekdaysNames"));
LLStringOps::setupWeekDaysShortNames(LLTrans::getString("dateTimeWeekdaysShortNames"));
@ -4332,6 +4335,7 @@ void LLAppViewer::pingMainloopTimeout(const std::string& state, F32 secs)
void LLAppViewer::handleLoginComplete()
{
gLoggedInTime.start();
initMainloopTimeout("Mainloop Init");
// Store some data to DebugInfo in case of a freeze.

View File

@ -310,6 +310,7 @@ extern U32 gFrameStalls;
extern LLTimer gRenderStartTime;
extern LLFrameTimer gForegroundTime;
extern LLFrameTimer gLoggedInTime;
extern F32 gLogoutMaxTime;
extern LLTimer gLogoutTimer;

View File

@ -35,11 +35,8 @@
LLAudioSourceVO::LLAudioSourceVO(const LLUUID &sound_id, const LLUUID& owner_id, const F32 gain, LLViewerObject *objectp)
: LLAudioSource(sound_id, owner_id, gain, LLAudioEngine::AUDIO_TYPE_SFX),
mObjectp(objectp),
mActualGain(gain)
mObjectp(objectp)
{
setAmbient(FALSE);
updateGain();
update();
}
@ -54,18 +51,18 @@ LLAudioSourceVO::~LLAudioSourceVO()
void LLAudioSourceVO::setGain(const F32 gain)
{
mActualGain = llclamp(gain, 0.f, 1.f);
updateGain();
mGain = llclamp(gain, 0.f, 1.f);
}
void LLAudioSourceVO::updateGain()
void LLAudioSourceVO::updateMute()
{
if (!mObjectp)
if (!mObjectp || mObjectp->isDead())
{
mSourceMuted = true;
return;
}
BOOL mute = FALSE;
bool mute = false;
LLVector3d pos_global;
if (mObjectp->isAttachment())
@ -84,21 +81,21 @@ void LLAudioSourceVO::updateGain()
{
pos_global = mObjectp->getPositionGlobal();
}
if (!LLViewerParcelMgr::getInstance()->canHearSound(pos_global))
{
mute = TRUE;
mute = true;
}
if (!mute)
{
if (LLMuteList::getInstance()->isMuted(mObjectp->getID()))
{
mute = TRUE;
mute = true;
}
else if (LLMuteList::getInstance()->isMuted(mOwnerID, LLMute::flagObjectSounds))
{
mute = TRUE;
mute = true;
}
else if (mObjectp->isAttachment())
{
@ -110,24 +107,38 @@ void LLAudioSourceVO::updateGain()
if (parent
&& LLMuteList::getInstance()->isMuted(parent->getID()))
{
mute = TRUE;
mute = true;
}
}
}
if (!mute)
if (mute != mSourceMuted)
{
mGain = mActualGain;
}
else
{
mGain = 0.f;
mSourceMuted = mute;
if (mSourceMuted)
{
// Stop the sound.
this->play(LLUUID::null);
}
else
{
// Muted sounds keep there data at all times, because
// it's the place where the audio UUID is stored.
// However, it's possible that mCurrentDatap is
// NULL when this source did only preload sounds.
if (mCurrentDatap)
{
// Restart the sound.
this->play(mCurrentDatap->getID());
}
}
}
}
void LLAudioSourceVO::update()
{
updateMute();
if (!mObjectp)
{
return;
@ -139,7 +150,11 @@ void LLAudioSourceVO::update()
return;
}
updateGain();
if (mSourceMuted)
{
return;
}
if (mObjectp->isHUDAttachment())
{
mPositionGlobal = gAgentCamera.getCameraPositionGlobal();

View File

@ -42,11 +42,10 @@ public:
/*virtual*/ void setGain(const F32 gain);
private:
void updateGain();
void updateMute();
private:
LLPointer<LLViewerObject> mObjectp;
F32 mActualGain; // The "real" gain, when not off due to parcel effects
};
#endif // LL_LLAUDIOSOURCEVO_H

View File

@ -545,7 +545,7 @@ LLAvalineListItem::LLAvalineListItem(bool hide_number/* = true*/) : LLAvatarList
, mIsHideNumber(hide_number)
{
// should not use buildPanel from the base class to ensure LLAvalineListItem::postBuild is called.
LLUICtrlFactory::getInstance()->buildPanel(this, "panel_avatar_list_item.xml");
buildFromFile( "panel_avatar_list_item.xml");
}
BOOL LLAvalineListItem::postBuild()

View File

@ -71,11 +71,12 @@ LLAvatarListItem::LLAvatarListItem(bool not_from_ui_factory/* = true*/)
mOnlineStatus(E_UNKNOWN),
mShowInfoBtn(true),
mShowProfileBtn(true),
mShowPermissions(false)
mShowPermissions(false),
mHovered(false)
{
if (not_from_ui_factory)
{
LLUICtrlFactory::getInstance()->buildPanel(this, "panel_avatar_list_item.xml");
buildFromFile("panel_avatar_list_item.xml");
}
// *NOTE: mantipov: do not use any member here. They can be uninitialized here in case instance
// is created from the UICtrlFactory
@ -466,20 +467,20 @@ void LLAvatarListItem::initChildrenWidths(LLAvatarListItem* avatar_item)
//info btn width + padding
S32 info_btn_width = avatar_item->mProfileBtn->getRect().mLeft - avatar_item->mInfoBtn->getRect().mLeft;
// edit their objects permission icon width + padding
S32 permission_edit_theirs_width = avatar_item->mInfoBtn->getRect().mLeft - avatar_item->mIconPermissionEditTheirs->getRect().mLeft;
// edit my objects permission icon width + padding
S32 permission_edit_mine_width = avatar_item->mIconPermissionEditTheirs->getRect().mLeft - avatar_item->mIconPermissionEditMine->getRect().mLeft;
// online permission icon width + padding
S32 permission_online_width = avatar_item->mInfoBtn->getRect().mLeft - avatar_item->mIconPermissionOnline->getRect().mLeft;
// map permission icon width + padding
S32 permission_map_width = avatar_item->mIconPermissionEditMine->getRect().mLeft - avatar_item->mIconPermissionMap->getRect().mLeft;
S32 permission_map_width = avatar_item->mIconPermissionOnline->getRect().mLeft - avatar_item->mIconPermissionMap->getRect().mLeft;
// online permission icon width + padding
S32 permission_online_width = avatar_item->mIconPermissionMap->getRect().mLeft - avatar_item->mIconPermissionOnline->getRect().mLeft;
// edit my objects permission icon width + padding
S32 permission_edit_mine_width = avatar_item->mIconPermissionMap->getRect().mLeft - avatar_item->mIconPermissionEditMine->getRect().mLeft;
// edit their objects permission icon width + padding
S32 permission_edit_theirs_width = avatar_item->mIconPermissionEditMine->getRect().mLeft - avatar_item->mIconPermissionEditTheirs->getRect().mLeft;
// last interaction time textbox width + padding
S32 last_interaction_time_width = avatar_item->mIconPermissionOnline->getRect().mLeft - avatar_item->mLastInteractionTime->getRect().mLeft;
S32 last_interaction_time_width = avatar_item->mIconPermissionEditTheirs->getRect().mLeft - avatar_item->mLastInteractionTime->getRect().mLeft;
// avatar icon width + padding
S32 icon_width = avatar_item->mAvatarName->getRect().mLeft - avatar_item->mAvatarIcon->getRect().mLeft;
@ -491,10 +492,10 @@ void LLAvatarListItem::initChildrenWidths(LLAvatarListItem* avatar_item)
sChildrenWidths[--index] = icon_width;
sChildrenWidths[--index] = 0; // for avatar name we don't need its width, it will be calculated as "left available space"
sChildrenWidths[--index] = last_interaction_time_width;
sChildrenWidths[--index] = permission_online_width;
sChildrenWidths[--index] = permission_map_width;
sChildrenWidths[--index] = permission_edit_mine_width;
sChildrenWidths[--index] = permission_edit_theirs_width;
sChildrenWidths[--index] = permission_edit_mine_width;
sChildrenWidths[--index] = permission_map_width;
sChildrenWidths[--index] = permission_online_width;
sChildrenWidths[--index] = info_btn_width;
sChildrenWidths[--index] = profile_btn_width;
sChildrenWidths[--index] = speaking_indicator_width;

View File

@ -147,10 +147,10 @@ private:
ALIC_SPEAKER_INDICATOR,
ALIC_PROFILE_BUTTON,
ALIC_INFO_BUTTON,
ALIC_PERMISSION_EDIT_THEIRS,
ALIC_PERMISSION_EDIT_MINE,
ALIC_PERMISSION_MAP,
ALIC_PERMISSION_ONLINE,
ALIC_PERMISSION_MAP,
ALIC_PERMISSION_EDIT_MINE,
ALIC_PERMISSION_EDIT_THEIRS,
ALIC_INTERACTION_TIME,
ALIC_NAME,
ALIC_ICON,

View File

@ -41,6 +41,7 @@
#include "llagentcamera.h"
#include "llchiclet.h"
#include "llfloatercamera.h"
#include "llhints.h"
#include "llimfloater.h" // for LLIMFloater
#include "llnearbychatbar.h"
#include "llspeakbutton.h"
@ -104,10 +105,6 @@ template class LLBottomTray* LLSingleton<class LLBottomTray>::getInstance();
namespace
{
const std::string& PANEL_CHICLET_NAME = "chiclet_list_panel";
const std::string& PANEL_CHATBAR_NAME = "chat_bar";
const std::string& PANEL_MOVEMENT_NAME = "movement_panel";
const std::string& PANEL_CAMERA_NAME = "cam_panel";
const std::string& PANEL_GESTURE_NAME = "gesture_panel";
S32 get_panel_min_width(LLLayoutStack* stack, LLView* panel)
{
@ -115,7 +112,7 @@ namespace
llassert(stack);
if ( stack && panel && panel->getVisible() )
{
stack->getPanelMinSize(panel->getName(), &minimal_width, NULL);
stack->getPanelMinSize(panel->getName(), &minimal_width);
}
return minimal_width;
}
@ -126,7 +123,7 @@ namespace
llassert(stack);
if ( stack && panel && panel->getVisible() )
{
stack->getPanelMaxSize(panel->getName(), &max_width, NULL);
stack->getPanelMaxSize(panel->getName(), &max_width);
}
return max_width;
}
@ -148,26 +145,30 @@ class LLBottomTrayLite
public:
LLBottomTrayLite()
: mNearbyChatBar(NULL),
mChatBarContainer(NULL),
mGesturePanel(NULL)
{
mFactoryMap["chat_bar"] = LLCallbackMap(LLBottomTray::createNearbyChatBar, NULL);
LLUICtrlFactory::getInstance()->buildPanel(this, "panel_bottomtray_lite.xml");
buildFromFile("panel_bottomtray_lite.xml");
// Necessary for focus movement among child controls
setFocusRoot(TRUE);
}
BOOL postBuild()
{
mNearbyChatBar = getChild<LLNearbyChatBar>("chat_bar");
mNearbyChatBar = findChild<LLNearbyChatBar>("chat_bar");
mChatBarContainer = getChild<LLLayoutPanel>("chat_bar_layout_panel");
mGesturePanel = getChild<LLPanel>("gesture_panel");
// Hide "show_nearby_chat" button
LLLineEditor* chat_box = mNearbyChatBar->getChatBox();
LLUICtrl* show_btn = mNearbyChatBar->getChild<LLUICtrl>("show_nearby_chat");
S32 delta_width = show_btn->getRect().getWidth();
show_btn->setVisible(FALSE);
chat_box->reshape(chat_box->getRect().getWidth() + delta_width, chat_box->getRect().getHeight());
if (mNearbyChatBar)
{
LLLineEditor* chat_box = mNearbyChatBar->getChatBox();
LLUICtrl* show_btn = mNearbyChatBar->getChild<LLUICtrl>("show_nearby_chat");
S32 delta_width = show_btn->getRect().getWidth();
show_btn->setVisible(FALSE);
chat_box->reshape(chat_box->getRect().getWidth() + delta_width, chat_box->getRect().getHeight());
}
return TRUE;
}
@ -180,6 +181,7 @@ public:
}
LLNearbyChatBar* mNearbyChatBar;
LLLayoutPanel* mChatBarContainer;
LLPanel* mGesturePanel;
};
@ -188,17 +190,18 @@ LLBottomTray::LLBottomTray(const LLSD&)
mSpeakPanel(NULL),
mSpeakBtn(NULL),
mNearbyChatBar(NULL),
mToolbarStack(NULL)
, mMovementButton(NULL)
, mResizeState(RS_NORESIZE)
, mBottomTrayContextMenu(NULL)
, mCamButton(NULL)
, mBottomTrayLite(NULL)
, mIsInLiteMode(false)
, mDragStarted(false)
, mDraggedItem(NULL)
, mLandingTab(NULL)
, mCheckForDrag(false)
mChatBarContainer(NULL),
mToolbarStack(NULL),
mMovementButton(NULL),
mResizeState(RS_NORESIZE),
mBottomTrayContextMenu(NULL),
mCamButton(NULL),
mBottomTrayLite(NULL),
mIsInLiteMode(false),
mDragStarted(false),
mDraggedItem(NULL),
mLandingTab(NULL),
mCheckForDrag(false)
{
// Firstly add ourself to IMSession observers, so we catch session events
// before chiclets do that.
@ -206,7 +209,7 @@ LLBottomTray::LLBottomTray(const LLSD&)
mFactoryMap["chat_bar"] = LLCallbackMap(LLBottomTray::createNearbyChatBar, NULL);
LLUICtrlFactory::getInstance()->buildPanel(this,"panel_bottomtray.xml");
buildFromFile("panel_bottomtray.xml");
LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("CameraPresets.ChangeView", boost::bind(&LLFloaterCamera::onClickCameraItem, _2));
@ -225,6 +228,7 @@ LLBottomTray::LLBottomTray(const LLSD&)
}
mImageDragIndication = LLUI::getUIImage(getString("DragIndicationImageName"));
mDesiredNearbyChatWidth = mNearbyChatBar ? mNearbyChatBar->getRect().getWidth() : 0;
}
LLBottomTray::~LLBottomTray()
@ -237,7 +241,7 @@ LLBottomTray::~LLBottomTray()
if (mNearbyChatBar)
{
// store custom width of chatbar panel.
S32 custom_width = mNearbyChatBar->getRect().getWidth();
S32 custom_width = mChatBarContainer->getRect().getWidth();
gSavedSettings.setS32("ChatBarCustomWidth", custom_width);
}
@ -432,7 +436,7 @@ S32 LLBottomTray::notifyParent(const LLSD& info)
const std::string& name = info["view_name"];
// expected only resize of nearby chatbar
if (mNearbyChatBar->getName() != name) return LLPanel::notifyParent(info);
if (mChatBarContainer->getName() != name) return LLPanel::notifyParent(info);
const S32 new_width = info["new_width"];
@ -462,8 +466,8 @@ void LLBottomTray::updateContextMenu(S32 x, S32 y, MASK mask)
{
LLUICtrl* edit_box = mNearbyChatBar->getChild<LLUICtrl>("chat_box");
S32 local_x = x - mNearbyChatBar->getRect().mLeft - edit_box->getRect().mLeft;
S32 local_y = y - mNearbyChatBar->getRect().mBottom - edit_box->getRect().mBottom;
S32 local_x = x - mChatBarContainer->getRect().mLeft - edit_box->getRect().mLeft;
S32 local_y = y - mChatBarContainer->getRect().mBottom - edit_box->getRect().mBottom;
bool in_edit_box = edit_box->pointInView(local_x, local_y);
@ -516,10 +520,14 @@ BOOL LLBottomTray::postBuild()
mBottomTrayContextMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_bottomtray.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
gMenuHolder->addChild(mBottomTrayContextMenu);
mNearbyChatBar = findChild<LLNearbyChatBar>("chat_bar");
LLHints::registerHintTarget("chat_bar", mNearbyChatBar->LLView::getHandle());
mChatBarContainer = getChild<LLLayoutPanel>("chat_bar_layout_panel");
mNearbyChatBar = getChild<LLNearbyChatBar>("chat_bar");
mToolbarStack = getChild<LLLayoutStack>("toolbar_stack");
mMovementButton = getChild<LLButton>("movement_btn");
LLHints::registerHintTarget("move_btn", mMovementButton->getHandle());
mCamButton = getChild<LLButton>("camera_btn");
setRightMouseDownCallback(boost::bind(&LLBottomTray::showBottomTrayContextMenu,this, _2, _3,_4));
@ -961,14 +969,15 @@ void LLBottomTray::reshape(S32 width, S32 height, BOOL called_from_parent)
// we can not to do this from postBuild because reshape is called from parent view on startup
// creation after it and reset width according to resize logic.
static bool needs_restore_custom_state = true;
if (mNearbyChatBar && needs_restore_custom_state)
if (mChatBarContainer && needs_restore_custom_state)
{
// restore custom width of chatbar panel.
S32 new_width = gSavedSettings.getS32("ChatBarCustomWidth");
if (new_width > 0)
{
mDesiredNearbyChatWidth = new_width;
processChatbarCustomization(new_width);
mNearbyChatBar->reshape(new_width, mNearbyChatBar->getRect().getHeight());
mChatBarContainer->reshape(new_width, mChatBarContainer->getRect().getHeight());
}
needs_restore_custom_state = false;
}
@ -982,6 +991,9 @@ S32 LLBottomTray::processWidthDecreased(S32 delta_width)
const S32 chiclet_panel_width = mChicletPanel->getParent()->getRect().getWidth();
const S32 chiclet_panel_min_width = mChicletPanel->getMinWidth();
// There are four steps of processing width decrease. If in one of them required width was reached,
// further are not needed.
// 1. Decreasing width of chiclet panel.
if (chiclet_panel_width > chiclet_panel_min_width)
{
// we have some space to decrease chiclet panel
@ -1007,8 +1019,15 @@ S32 LLBottomTray::processWidthDecreased(S32 delta_width)
<< llendl;
}
const S32 chatbar_panel_width = mNearbyChatBar->getRect().getWidth();
S32 buttons_freed_width = 0;
// 2. Decreasing width of buttons.
if (still_should_be_processed)
{
processShrinkButtons(delta_width, buttons_freed_width);
}
// 3. Decreasing width of nearby chat.
const S32 chatbar_panel_min_width = get_panel_min_width(mToolbarStack, mNearbyChatBar);
const S32 chatbar_panel_width = mChatBarContainer->getRect().getWidth();
if (still_should_be_processed && chatbar_panel_width > chatbar_panel_min_width)
{
// we have some space to decrease chatbar panel
@ -1021,7 +1040,11 @@ S32 LLBottomTray::processWidthDecreased(S32 delta_width)
still_should_be_processed = delta_width < 0;
mNearbyChatBar->reshape(mNearbyChatBar->getRect().getWidth() - delta_panel, mNearbyChatBar->getRect().getHeight());
// chatbar should only be shrunk here, not stretched
if(delta_panel > 0)
{
mChatBarContainer->reshape(mNearbyChatBar->getRect().getWidth() - delta_panel, mChatBarContainer->getRect().getHeight());
}
log(mNearbyChatBar, "after processing panel decreasing via nearby chatbar panel");
@ -1032,11 +1055,9 @@ S32 LLBottomTray::processWidthDecreased(S32 delta_width)
}
S32 extra_shrink_width = 0;
S32 buttons_freed_width = 0;
// 4. Hiding buttons if needed.
if (still_should_be_processed)
{
processShrinkButtons(delta_width, buttons_freed_width);
processHideButtons(delta_width, buttons_freed_width);
if (delta_width < 0)
@ -1048,10 +1069,15 @@ S32 LLBottomTray::processWidthDecreased(S32 delta_width)
if (buttons_freed_width > 0)
{
log(mNearbyChatBar, "before applying compensative width");
mNearbyChatBar->reshape(mNearbyChatBar->getRect().getWidth() + buttons_freed_width, mNearbyChatBar->getRect().getHeight() );
log(mNearbyChatBar, "after applying compensative width");
lldebugs << buttons_freed_width << llendl;
S32 nearby_needed_width = mDesiredNearbyChatWidth - mNearbyChatBar->getRect().getWidth();
if (nearby_needed_width > 0)
{
S32 compensative_width = nearby_needed_width > buttons_freed_width ? buttons_freed_width : nearby_needed_width;
log(mNearbyChatBar, "before applying compensative width");
mChatBarContainer->reshape(mChatBarContainer->getRect().getWidth() + compensative_width, mChatBarContainer->getRect().getHeight() );
log(mNearbyChatBar, "after applying compensative width");
lldebugs << buttons_freed_width << llendl;
}
}
}
@ -1065,18 +1091,12 @@ void LLBottomTray::processWidthIncreased(S32 delta_width)
const S32 chiclet_panel_width = mChicletPanel->getParent()->getRect().getWidth();
static const S32 chiclet_panel_min_width = mChicletPanel->getMinWidth();
const S32 chatbar_panel_width = mNearbyChatBar->getRect().getWidth();
static const S32 chatbar_panel_min_width = get_panel_min_width(mToolbarStack, mNearbyChatBar);
static const S32 chatbar_panel_max_width = get_panel_max_width(mToolbarStack, mNearbyChatBar);
const S32 chatbar_available_shrink_width = chatbar_panel_width - chatbar_panel_min_width;
const S32 available_width_chiclet = chiclet_panel_width - chiclet_panel_min_width;
// how many room we have to show hidden buttons
S32 total_available_width = delta_width + chatbar_available_shrink_width + available_width_chiclet;
S32 total_available_width = delta_width + available_width_chiclet;
lldebugs << "Processing extending, available width:"
<< ", chatbar - " << chatbar_available_shrink_width
<< ", chiclets - " << available_width_chiclet
<< ", total - " << total_available_width
<< llendl;
@ -1085,8 +1105,6 @@ void LLBottomTray::processWidthIncreased(S32 delta_width)
processShowButtons(available_width);
processExtendButtons(available_width);
// if we have to show/extend some buttons but resized delta width is not enough...
S32 processed_width = total_available_width - available_width;
if (processed_width > delta_width)
@ -1097,21 +1115,7 @@ void LLBottomTray::processWidthIncreased(S32 delta_width)
// 1. use delta width of resizing
required_to_process_width -= delta_width;
// 2. use width available via decreasing of nearby chat panel
S32 chatbar_shrink_width = required_to_process_width;
if (chatbar_available_shrink_width < chatbar_shrink_width)
{
chatbar_shrink_width = chatbar_available_shrink_width;
}
log(mNearbyChatBar, "increase width: before applying compensative width");
mNearbyChatBar->reshape(mNearbyChatBar->getRect().getWidth() - chatbar_shrink_width, mNearbyChatBar->getRect().getHeight() );
if (mNearbyChatBar) log(mNearbyChatBar, "after applying compensative width");
lldebugs << chatbar_shrink_width << llendl;
// 3. use width available via decreasing of chiclet panel
required_to_process_width -= chatbar_shrink_width;
// 2. use width available via decreasing of chiclet panel
if (required_to_process_width > 0)
{
mChicletPanel->getParent()->reshape(mChicletPanel->getParent()->getRect().getWidth() - required_to_process_width, mChicletPanel->getParent()->getRect().getHeight());
@ -1126,10 +1130,10 @@ void LLBottomTray::processWidthIncreased(S32 delta_width)
// how many space can nearby chatbar take?
S32 chatbar_panel_width_ = mNearbyChatBar->getRect().getWidth();
if (delta_width > 0 && chatbar_panel_width_ < chatbar_panel_max_width)
S32 chatbar_panel_width_ = mChatBarContainer->getRect().getWidth();
if (delta_width > 0 && chatbar_panel_width_ < mDesiredNearbyChatWidth)
{
S32 delta_panel_max = chatbar_panel_max_width - chatbar_panel_width_;
S32 delta_panel_max = mDesiredNearbyChatWidth - chatbar_panel_width_;
S32 delta_panel = llmin(delta_width, delta_panel_max);
lldebugs << "Unprocesed delta width: " << delta_width
<< ", can be applied to chatbar: " << delta_panel_max
@ -1137,9 +1141,13 @@ void LLBottomTray::processWidthIncreased(S32 delta_width)
<< llendl;
delta_width -= delta_panel_max;
mNearbyChatBar->reshape(chatbar_panel_width_ + delta_panel, mNearbyChatBar->getRect().getHeight());
mChatBarContainer->reshape(chatbar_panel_width_ + delta_panel, mChatBarContainer->getRect().getHeight());
log(mNearbyChatBar, "applied unprocessed delta width");
}
if (delta_width > 0)
{
processExtendButtons(delta_width);
}
}
void LLBottomTray::processShowButtons(S32& available_width)
@ -1259,7 +1267,7 @@ void LLBottomTray::processShrinkButtons(S32& required_width, S32& buttons_freed_
S32 panel_min_width = 0;
std::string panel_name = mSpeakPanel->getName();
bool success = mToolbarStack->getPanelMinSize(panel_name, &panel_min_width, NULL);
bool success = mToolbarStack->getPanelMinSize(panel_name, &panel_min_width);
if (!success)
{
lldebugs << "Panel was not found to get its min width: " << panel_name << llendl;
@ -1305,7 +1313,7 @@ void LLBottomTray::processShrinkButton(EResizeState processed_object_type, S32&
S32 panel_width = panel->getRect().getWidth();
S32 panel_min_width = 0;
std::string panel_name = panel->getName();
bool success = mToolbarStack->getPanelMinSize(panel_name, &panel_min_width, NULL);
bool success = mToolbarStack->getPanelMinSize(panel_name, &panel_min_width);
S32 possible_shrink_width = panel_width - panel_min_width;
if (!success)
@ -1597,7 +1605,7 @@ bool LLBottomTray::setVisibleAndFitWidths(EResizeState object_type, bool visible
{
// Calculate the possible shrunk width as difference between current and minimal widths
const S32 chatbar_shrunk_width =
mNearbyChatBar->getRect().getWidth() - get_panel_min_width(mToolbarStack, mNearbyChatBar);
mChatBarContainer->getRect().getWidth() - get_panel_min_width(mToolbarStack, mChatBarContainer);
S32 sum_of_min_widths = get_panel_min_width(mToolbarStack, mSpeakPanel);
S32 sum_of_curr_widths = get_curr_width(mSpeakPanel);
@ -1617,7 +1625,7 @@ bool LLBottomTray::setVisibleAndFitWidths(EResizeState object_type, bool visible
// Minimal width of current panel
S32 minimal_width = 0;
mToolbarStack->getPanelMinSize(cur_panel->getName(), &minimal_width, NULL);
mToolbarStack->getPanelMinSize(cur_panel->getName(), &minimal_width);
if ( (available_width + possible_shrunk_width) >= minimal_width)
{
@ -1694,10 +1702,12 @@ void LLBottomTray::processChatbarCustomization(S32 new_width)
{
if (NULL == mNearbyChatBar) return;
const S32 delta_width = mNearbyChatBar->getRect().getWidth() - new_width;
const S32 delta_width = mChatBarContainer->getRect().getWidth() - new_width;
if (delta_width == 0) return;
mDesiredNearbyChatWidth = new_width;
LLView * chiclet_layout_panel = mChicletPanel->getParent();
const S32 chiclet_min_width = get_panel_min_width(mToolbarStack, chiclet_layout_panel);
const S32 chiclet_panel_width = chiclet_layout_panel->getRect().getWidth();

View File

@ -27,20 +27,18 @@
#ifndef LL_LLBOTTOMPANEL_H
#define LL_LLBOTTOMPANEL_H
#include "llmenugl.h"
#include "llpanel.h"
#include "llimview.h"
#include "llcombobox.h"
#include "llbutton.h"
class LLChicletPanel;
class LLLineEditor;
class LLLayoutStack;
class LLNotificationChiclet;
class LLSpeakButton;
class LLNearbyChatBar;
class LLIMChiclet;
class LLBottomTrayLite;
class LLLayoutPanel;
class LLMenuGL;
// Build time optimization, generate once in .cpp file
#ifndef LLBOTTOMTRAY_CPP
@ -439,10 +437,15 @@ protected:
void onContextMenuItemClicked(const LLSD& userdata);
bool onContextMenuItemEnabled(const LLSD& userdata);
// Either default or saved after user's manual resize width of nearby chat.
// Nearby chat will not always have it, because sometimes it can be shrunk on resize,
// but when possible it will be restored back to this value.
S32 mDesiredNearbyChatWidth;
LLChicletPanel* mChicletPanel;
LLPanel* mSpeakPanel;
LLSpeakButton* mSpeakBtn;
LLNearbyChatBar* mNearbyChatBar;
LLLayoutPanel* mChatBarContainer;
LLLayoutStack* mToolbarStack;
LLMenuGL* mBottomTrayContextMenu;
LLButton* mCamButton;

View File

@ -0,0 +1,48 @@
/**
* @file llbrowsernotification.cpp
* @brief Notification Handler Class for browser popups
*
* $LicenseInfo:firstyear=2000&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h" // must be first include
#include "llnotificationhandler.h"
#include "llnotifications.h"
#include "llfloaterreg.h"
#include "llmediactrl.h"
using namespace LLNotificationsUI;
bool LLBrowserNotification::processNotification(const LLSD& notify)
{
LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
if (!notification) return false;
LLMediaCtrl* media_instance = LLMediaCtrl::getInstance(notification->getPayload()["media_id"].asUUID());
if (media_instance)
{
media_instance->showNotification(notification);
}
return false;
}

View File

@ -146,7 +146,7 @@ BOOL LLCallFloater::postBuild()
childSetAction("leave_call_btn", boost::bind(&LLCallFloater::leaveCall, this));
mNonAvatarCaller = getChild<LLNonAvatarCaller>("non_avatar_caller");
mNonAvatarCaller = findChild<LLNonAvatarCaller>("non_avatar_caller");
mNonAvatarCaller->setVisible(FALSE);
LLView *anchor_panel = LLBottomTray::getInstance()->getChild<LLView>("speak_flyout_btn");

View File

@ -565,6 +565,10 @@ void LLChatBar::sendChatFromViewer(const std::string &utf8text, EChatType type,
void LLChatBar::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate)
{
// as soon as we say something, we no longer care about teaching the user
// how to chat
gWarningSettings.setBOOL("FirstOtherChatBeforeUser", FALSE);
// Look for "/20 foo" channel chats.
S32 channel = 0;
LLWString out_text = stripChannelNumber(wtext, &channel);
@ -685,14 +689,14 @@ public:
}
else
{
S32 channel = tokens[0].asInteger();
S32 channel = tokens[0].asInteger();
// VWR-19499 Restrict function to chat channels greater than 0.
if ((channel > 0) && (channel < 2147483647))
{
retval = true;
// Say mesg on channel
std::string mesg = tokens[1].asString();
send_chat_from_viewer(mesg, CHAT_TYPE_NORMAL, channel);
std::string mesg = tokens[1].asString();
send_chat_from_viewer(mesg, CHAT_TYPE_NORMAL, channel);
}
else
{

View File

@ -115,7 +115,7 @@ public:
static LLChatHistoryHeader* createInstance(const std::string& file_name)
{
LLChatHistoryHeader* pInstance = new LLChatHistoryHeader;
LLUICtrlFactory::getInstance()->buildPanel(pInstance, file_name);
pInstance->buildFromFile(file_name);
return pInstance;
}
@ -443,7 +443,7 @@ protected:
return;
}
LLTextBase* name = getChild<LLTextBase>("user_name");
LLTextBox* name = getChild<LLTextBox>("user_name");
LLRect sticky_rect = name->getRect();
S32 icon_x = llmin(sticky_rect.mLeft + name->getTextBoundingRect().getWidth() + 7, sticky_rect.mRight - 3);
sInfoCtrl->setOrigin(icon_x, sticky_rect.getCenterY() - sInfoCtrl->getRect().getHeight() / 2 ) ;
@ -544,12 +544,17 @@ void LLChatHistory::initFromParams(const LLChatHistory::Params& p)
const S32 NEW_TEXT_NOTICE_HEIGHT = 20;
LLPanel::Params panel_p;
LLLayoutPanel::Params panel_p;
panel_p.name = "spacer";
panel_p.background_visible = false;
panel_p.has_border = false;
panel_p.mouse_opaque = false;
stackp->addPanel(LLUICtrlFactory::create<LLPanel>(panel_p), 0, 30, S32_MAX, S32_MAX, true, false, LLLayoutStack::ANIMATE);
panel_p.min_dim = 30;
panel_p.max_dim = S32_MAX;
panel_p.auto_resize = true;
panel_p.user_resize = false;
stackp->addPanel(LLUICtrlFactory::create<LLLayoutPanel>(panel_p), LLLayoutStack::ANIMATE);
panel_p.name = "new_text_notice_holder";
LLRect new_text_notice_rect = getLocalRect();
@ -558,7 +563,10 @@ void LLChatHistory::initFromParams(const LLChatHistory::Params& p)
panel_p.background_opaque = true;
panel_p.background_visible = true;
panel_p.visible = false;
mMoreChatPanel = LLUICtrlFactory::create<LLPanel>(panel_p);
panel_p.min_dim = 0;
panel_p.auto_resize = false;
panel_p.user_resize = false;
mMoreChatPanel = LLUICtrlFactory::create<LLLayoutPanel>(panel_p);
LLTextBox::Params text_p(p.more_chat_text);
text_p.rect = mMoreChatPanel->getLocalRect();
@ -567,7 +575,7 @@ void LLChatHistory::initFromParams(const LLChatHistory::Params& p)
mMoreChatText = LLUICtrlFactory::create<LLTextBox>(text_p, mMoreChatPanel);
mMoreChatText->setClickedCallback(boost::bind(&LLChatHistory::onClickMoreText, this));
stackp->addPanel(mMoreChatPanel, 0, 0, S32_MAX, S32_MAX, false, false, LLLayoutStack::ANIMATE);
stackp->addPanel(mMoreChatPanel, LLLayoutStack::ANIMATE);
}

View File

@ -138,7 +138,7 @@ class LLChatHistory : public LLUICtrl
S32 mTopHeaderPad;
S32 mBottomHeaderPad;
LLPanel* mMoreChatPanel;
class LLLayoutPanel* mMoreChatPanel;
LLTextBox* mMoreChatText;
LLTextEditor* mEditor;
typedef std::set<std::string> unread_chat_source_t;

View File

@ -51,7 +51,7 @@ static const S32 msg_height_pad = 5;
LLNearbyChatToastPanel* LLNearbyChatToastPanel::createInstance()
{
LLNearbyChatToastPanel* item = new LLNearbyChatToastPanel();
LLUICtrlFactory::getInstance()->buildPanel(item, "panel_chat_item.xml");
item->buildFromFile("panel_chat_item.xml");
item->setFollows(FOLLOWS_NONE);
return item;
}

Some files were not shown because too many files have changed in this diff Show More