Updated LLResizeBar and LLResizeHandle to use LLView::Param based ctors.

Cleaned up LLKeyWords
Cleaned up LLStatBar
Added per-account setting access to ui library
Added LLUICachedControl
Updated LLUIString
This commit is contained in:
Shyotl
2013-05-20 00:36:34 -05:00
parent df404c42d0
commit c5fc945f33
24 changed files with 628 additions and 329 deletions

View File

@@ -30,24 +30,25 @@
* $/LicenseInfo$
*/
#ifndef LL_CALLBACK_MAP_H
#define LL_CALLBACK_MAP_H
#ifndef LLCALLBACKMAP_H
#define LLCALLBACKMAP_H
#include <map>
#include "llstring.h"
#include <string>
#include <boost/function.hpp>
class LLCallbackMap
{
public:
// callback definition.
typedef void* (*callback_t)(void* data);
typedef boost::function<void* (void* data)> callback_t;
typedef std::map<std::string, LLCallbackMap> map_t;
typedef map_t::iterator map_iter_t;
typedef map_t::const_iterator map_const_iter_t;
LLCallbackMap() : mCallback(NULL), mData(NULL) { }
LLCallbackMap(callback_t callback, void* data) : mCallback(callback), mData(data) { }
LLCallbackMap(callback_t callback, void* data = NULL) : mCallback(callback), mData(data) { }
callback_t mCallback;
void* mData;

View File

@@ -314,67 +314,7 @@ void LLFloater::initFloater(const std::string& title,
if( mResizable )
{
// Resize bars (sides)
const S32 RESIZE_BAR_THICKNESS = 3;
mResizeBar[LLResizeBar::LEFT] = new LLResizeBar(
std::string("resizebar_left"),
this,
LLRect( 0, getRect().getHeight(), RESIZE_BAR_THICKNESS, 0),
min_width, S32_MAX, LLResizeBar::LEFT );
addChild( mResizeBar[0] );
mResizeBar[LLResizeBar::TOP] = new LLResizeBar(
std::string("resizebar_top"),
this,
LLRect( 0, getRect().getHeight(), getRect().getWidth(), getRect().getHeight() - RESIZE_BAR_THICKNESS),
min_height, S32_MAX, LLResizeBar::TOP );
addChild( mResizeBar[1] );
mResizeBar[LLResizeBar::RIGHT] = new LLResizeBar(
std::string("resizebar_right"),
this,
LLRect( getRect().getWidth() - RESIZE_BAR_THICKNESS, getRect().getHeight(), getRect().getWidth(), 0),
min_width, S32_MAX, LLResizeBar::RIGHT );
addChild( mResizeBar[2] );
mResizeBar[LLResizeBar::BOTTOM] = new LLResizeBar(
std::string("resizebar_bottom"),
this,
LLRect( 0, RESIZE_BAR_THICKNESS, getRect().getWidth(), 0),
min_height, S32_MAX, LLResizeBar::BOTTOM );
addChild( mResizeBar[3] );
// Resize handles (corners)
mResizeHandle[0] = new LLResizeHandle(
std::string("Resize Handle"),
LLRect( getRect().getWidth() - RESIZE_HANDLE_WIDTH, RESIZE_HANDLE_HEIGHT, getRect().getWidth(), 0),
min_width,
min_height,
LLResizeHandle::RIGHT_BOTTOM);
addChild(mResizeHandle[0]);
mResizeHandle[1] = new LLResizeHandle(
std::string("resize"),
LLRect( getRect().getWidth() - RESIZE_HANDLE_WIDTH, getRect().getHeight(), getRect().getWidth(), getRect().getHeight() - RESIZE_HANDLE_HEIGHT),
min_width,
min_height,
LLResizeHandle::RIGHT_TOP );
addChild(mResizeHandle[1]);
mResizeHandle[2] = new LLResizeHandle( std::string("resize"),
LLRect( 0, RESIZE_HANDLE_HEIGHT, RESIZE_HANDLE_WIDTH, 0 ),
min_width,
min_height,
LLResizeHandle::LEFT_BOTTOM );
addChild(mResizeHandle[2]);
mResizeHandle[3] = new LLResizeHandle( std::string("resize"),
LLRect( 0, getRect().getHeight(), RESIZE_HANDLE_WIDTH, getRect().getHeight() - RESIZE_HANDLE_HEIGHT ),
min_width,
min_height,
LLResizeHandle::LEFT_TOP );
addChild(mResizeHandle[3]);
addResizeCtrls();
}
// Close button.
@@ -414,6 +354,94 @@ void LLFloater::initFloater(const std::string& title,
}
}
void LLFloater::addResizeCtrls()
{
// Resize bars (sides)
LLResizeBar::Params p;
p.name("resizebar_left");
p.resizing_view(this);
p.min_size(mMinWidth);
p.side(LLResizeBar::LEFT);
mResizeBar[LLResizeBar::LEFT] = LLUICtrlFactory::create<LLResizeBar>(p);
addChild( mResizeBar[LLResizeBar::LEFT] );
p.name("resizebar_top");
p.min_size(mMinHeight);
p.side(LLResizeBar::TOP);
mResizeBar[LLResizeBar::TOP] = LLUICtrlFactory::create<LLResizeBar>(p);
addChild( mResizeBar[LLResizeBar::TOP] );
p.name("resizebar_right");
p.min_size(mMinWidth);
p.side(LLResizeBar::RIGHT);
mResizeBar[LLResizeBar::RIGHT] = LLUICtrlFactory::create<LLResizeBar>(p);
addChild( mResizeBar[LLResizeBar::RIGHT] );
p.name("resizebar_bottom");
p.min_size(mMinHeight);
p.side(LLResizeBar::BOTTOM);
mResizeBar[LLResizeBar::BOTTOM] = LLUICtrlFactory::create<LLResizeBar>(p);
addChild( mResizeBar[LLResizeBar::BOTTOM] );
// Resize handles (corners)
LLResizeHandle::Params handle_p;
// handles must not be mouse-opaque, otherwise they block hover events
// to other buttons like the close box. JC
handle_p.mouse_opaque(false);
handle_p.min_width(mMinWidth);
handle_p.min_height(mMinHeight);
handle_p.corner(LLResizeHandle::RIGHT_BOTTOM);
mResizeHandle[0] = LLUICtrlFactory::create<LLResizeHandle>(handle_p);
addChild(mResizeHandle[0]);
handle_p.corner(LLResizeHandle::RIGHT_TOP);
mResizeHandle[1] = LLUICtrlFactory::create<LLResizeHandle>(handle_p);
addChild(mResizeHandle[1]);
handle_p.corner(LLResizeHandle::LEFT_BOTTOM);
mResizeHandle[2] = LLUICtrlFactory::create<LLResizeHandle>(handle_p);
addChild(mResizeHandle[2]);
handle_p.corner(LLResizeHandle::LEFT_TOP);
mResizeHandle[3] = LLUICtrlFactory::create<LLResizeHandle>(handle_p);
addChild(mResizeHandle[3]);
layoutResizeCtrls();
}
void LLFloater::layoutResizeCtrls()
{
LLRect rect;
// Resize bars (sides)
const S32 RESIZE_BAR_THICKNESS = 3;
rect = LLRect( 0, getRect().getHeight(), RESIZE_BAR_THICKNESS, 0);
mResizeBar[LLResizeBar::LEFT]->setRect(rect);
rect = LLRect( 0, getRect().getHeight(), getRect().getWidth(), getRect().getHeight() - RESIZE_BAR_THICKNESS);
mResizeBar[LLResizeBar::TOP]->setRect(rect);
rect = LLRect(getRect().getWidth() - RESIZE_BAR_THICKNESS, getRect().getHeight(), getRect().getWidth(), 0);
mResizeBar[LLResizeBar::RIGHT]->setRect(rect);
rect = LLRect(0, RESIZE_BAR_THICKNESS, getRect().getWidth(), 0);
mResizeBar[LLResizeBar::BOTTOM]->setRect(rect);
// Resize handles (corners)
rect = LLRect( getRect().getWidth() - RESIZE_HANDLE_WIDTH, RESIZE_HANDLE_HEIGHT, getRect().getWidth(), 0);
mResizeHandle[0]->setRect(rect);
rect = LLRect( getRect().getWidth() - RESIZE_HANDLE_WIDTH, getRect().getHeight(), getRect().getWidth(), getRect().getHeight() - RESIZE_HANDLE_HEIGHT);
mResizeHandle[1]->setRect(rect);
rect = LLRect( 0, RESIZE_HANDLE_HEIGHT, RESIZE_HANDLE_WIDTH, 0 );
mResizeHandle[2]->setRect(rect);
rect = LLRect( 0, getRect().getHeight(), RESIZE_HANDLE_WIDTH, getRect().getHeight() - RESIZE_HANDLE_HEIGHT );
mResizeHandle[3]->setRect(rect);
}
void LLFloater::enableResizeCtrls(bool enable, bool width, bool height)
{
mResizeBar[LLResizeBar::LEFT]->setVisible(enable && width);
@@ -1547,66 +1575,7 @@ void LLFloater::setCanResize(BOOL can_resize)
}
else if (!mResizable && can_resize)
{
// Resize bars (sides)
const S32 RESIZE_BAR_THICKNESS = 3;
mResizeBar[0] = new LLResizeBar(
std::string("resizebar_left"),
this,
LLRect( 0, getRect().getHeight(), RESIZE_BAR_THICKNESS, 0),
mMinWidth, S32_MAX, LLResizeBar::LEFT );
addChild( mResizeBar[0] );
mResizeBar[1] = new LLResizeBar(
std::string("resizebar_top"),
this,
LLRect( 0, getRect().getHeight(), getRect().getWidth(), getRect().getHeight() - RESIZE_BAR_THICKNESS),
mMinHeight, S32_MAX, LLResizeBar::TOP );
addChild( mResizeBar[1] );
mResizeBar[2] = new LLResizeBar(
std::string("resizebar_right"),
this,
LLRect( getRect().getWidth() - RESIZE_BAR_THICKNESS, getRect().getHeight(), getRect().getWidth(), 0),
mMinWidth, S32_MAX, LLResizeBar::RIGHT );
addChild( mResizeBar[2] );
mResizeBar[3] = new LLResizeBar(
std::string("resizebar_bottom"),
this,
LLRect( 0, RESIZE_BAR_THICKNESS, getRect().getWidth(), 0),
mMinHeight, S32_MAX, LLResizeBar::BOTTOM );
addChild( mResizeBar[3] );
// Resize handles (corners)
mResizeHandle[0] = new LLResizeHandle(
std::string("Resize Handle"),
LLRect( getRect().getWidth() - RESIZE_HANDLE_WIDTH, RESIZE_HANDLE_HEIGHT, getRect().getWidth(), 0),
mMinWidth,
mMinHeight,
LLResizeHandle::RIGHT_BOTTOM);
addChild(mResizeHandle[0]);
mResizeHandle[1] = new LLResizeHandle( std::string("resize"),
LLRect( getRect().getWidth() - RESIZE_HANDLE_WIDTH, getRect().getHeight(), getRect().getWidth(), getRect().getHeight() - RESIZE_HANDLE_HEIGHT),
mMinWidth,
mMinHeight,
LLResizeHandle::RIGHT_TOP );
addChild(mResizeHandle[1]);
mResizeHandle[2] = new LLResizeHandle( std::string("resize"),
LLRect( 0, RESIZE_HANDLE_HEIGHT, RESIZE_HANDLE_WIDTH, 0 ),
mMinWidth,
mMinHeight,
LLResizeHandle::LEFT_BOTTOM );
addChild(mResizeHandle[2]);
mResizeHandle[3] = new LLResizeHandle( std::string("resize"),
LLRect( 0, getRect().getHeight(), RESIZE_HANDLE_WIDTH, getRect().getHeight() - RESIZE_HANDLE_HEIGHT ),
mMinWidth,
mMinHeight,
LLResizeHandle::LEFT_TOP );
addChild(mResizeHandle[3]);
addResizeCtrls();
enableResizeCtrls(can_resize);
}
mResizable = can_resize;

View File

@@ -269,6 +269,8 @@ private:
void updateButtons();
void buildButtons();
BOOL offerClickToButton(S32 x, S32 y, MASK mask, EFloaterButtons index);
void addResizeCtrls();
void layoutResizeCtrls();
LLRect mExpandedRect;
LLDragHandle* mDragHandle;

View File

@@ -42,31 +42,25 @@
const U32 KEYWORD_FILE_CURRENT_VERSION = 2;
inline BOOL LLKeywordToken::isHead(const llwchar* s, bool search_end_c_comment) const
inline BOOL LLKeywordToken::isHead(const llwchar* s) const
{
// strncmp is much faster than string compare
BOOL res = TRUE;
const llwchar* t = mToken.c_str();
S32 len = mToken.size();
if (search_end_c_comment && len == 2 && t[0] == '/' && t[1] == '*')
{
// Special case for C-like */ end comment token
if (s[0] == '*' && s[1] == '/')
{
return TRUE;
}
else
{
return FALSE;
}
}
for (S32 i = 0; i < len; i++)
for (S32 i=0; i<len; i++)
{
if (s[i] != t[i])
{
return FALSE;
res = FALSE;
break;
}
}
return TRUE;
return res;
}
LLKeywords::LLKeywords() : mLoaded(FALSE)
{
}
inline BOOL LLKeywordToken::isTail(const llwchar* s) const
@@ -85,10 +79,6 @@ inline BOOL LLKeywordToken::isTail(const llwchar* s) const
return res;
}
LLKeywords::LLKeywords() : mLoaded(FALSE)
{
}
LLKeywords::~LLKeywords()
{
std::for_each(mWordTokenMap.begin(), mWordTokenMap.end(), DeletePairedPointer());
@@ -138,7 +128,7 @@ BOOL LLKeywords::loadFromFile( const std::string& filename )
std::string SOL_LINE("[line ");
std::string SOL_ONE_SIDED_DELIMITER("[one_sided_delimiter ");
std::string SOL_TWO_SIDED_DELIMITER("[two_sided_delimiter ");
std::string SOL_TWO_SIDED_DELIMITER_ESC("[two_sided_delimiter_esc ");
std::string SOL_DOUBLE_QUOTATION_MARKS("[double_quotation_marks ");
LLColor3 cur_color( 1, 0, 0 );
LLKeywordToken::TOKEN_TYPE cur_type = LLKeywordToken::WORD;
@@ -170,10 +160,10 @@ BOOL LLKeywords::loadFromFile( const std::string& filename )
cur_type = LLKeywordToken::TWO_SIDED_DELIMITER;
continue;
}
else if( line.find(SOL_TWO_SIDED_DELIMITER_ESC) == 0 )
else if( line.find(SOL_DOUBLE_QUOTATION_MARKS) == 0 )
{
cur_color = readColor( line.substr(SOL_TWO_SIDED_DELIMITER_ESC.size()) );
cur_type = LLKeywordToken::TWO_SIDED_DELIMITER_ESC;
cur_color = readColor( line.substr(SOL_DOUBLE_QUOTATION_MARKS.size()) );
cur_type = LLKeywordToken::DOUBLE_QUOTATION_MARKS;
continue;
}
else if( line.find(SOL_ONE_SIDED_DELIMITER) == 0 )
@@ -193,13 +183,13 @@ BOOL LLKeywords::loadFromFile( const std::string& filename )
if( !token_buffer.empty() && token_word_iter != word_tokens.end() )
{
// first word is keyword
// first word is the keyword or a left delimiter
std::string keyword = (*token_word_iter);
LLStringUtil::trim(keyword);
// second word may be right delimiter
// second word may be a right delimiter
std::string delimiter;
if (cur_type == LLKeywordToken::TWO_SIDED_DELIMITER || cur_type == LLKeywordToken::TWO_SIDED_DELIMITER_ESC)
if (cur_type == LLKeywordToken::TWO_SIDED_DELIMITER)
{
while (delimiter.length() == 0 && ++token_word_iter != word_tokens.end())
{
@@ -207,6 +197,11 @@ BOOL LLKeywords::loadFromFile( const std::string& filename )
LLStringUtil::trim(delimiter);
}
}
else if (cur_type == LLKeywordToken::DOUBLE_QUOTATION_MARKS)
{
// Closing delimiter is identical to the opening one.
delimiter = keyword;
}
// following words are tooltip
std::string tool_tip;
@@ -256,7 +251,7 @@ void LLKeywords::addToken(LLKeywordToken::TOKEN_TYPE type,
break;
case LLKeywordToken::TWO_SIDED_DELIMITER:
case LLKeywordToken::TWO_SIDED_DELIMITER_ESC:
case LLKeywordToken::DOUBLE_QUOTATION_MARKS:
case LLKeywordToken::ONE_SIDED_DELIMITER:
mDelimiterTokenList.push_front(new LLKeywordToken(type, color, key, tool_tip, delimiter));
break;
@@ -265,24 +260,106 @@ void LLKeywords::addToken(LLKeywordToken::TOKEN_TYPE type,
llassert(0);
}
}
LLKeywords::WStringMapIndex::WStringMapIndex(const WStringMapIndex& other)
{
if(other.mOwner)
{
copyData(other.mData, other.mLength);
}
else
{
mOwner = false;
mLength = other.mLength;
mData = other.mData;
}
}
LLKeywords::WStringMapIndex::WStringMapIndex(const LLWString& str)
{
copyData(str.data(), str.size());
}
LLKeywords::WStringMapIndex::WStringMapIndex(const llwchar *start, size_t length):
mData(start), mLength(length), mOwner(false)
{
}
LLKeywords::WStringMapIndex::~WStringMapIndex()
{
if(mOwner)
delete[] mData;
}
void LLKeywords::WStringMapIndex::copyData(const llwchar *start, size_t length)
{
llwchar *data = new llwchar[length];
memcpy((void*)data, (const void*)start, length * sizeof(llwchar));
mOwner = true;
mLength = length;
mData = data;
}
bool LLKeywords::WStringMapIndex::operator<(const LLKeywords::WStringMapIndex &other) const
{
// NOTE: Since this is only used to organize a std::map, it doesn't matter if it uses correct collate order or not.
// The comparison only needs to strictly order all possible strings, and be stable.
bool result = false;
const llwchar* self_iter = mData;
const llwchar* self_end = mData + mLength;
const llwchar* other_iter = other.mData;
const llwchar* other_end = other.mData + other.mLength;
while(true)
{
if(other_iter >= other_end)
{
// We've hit the end of other.
// This covers two cases: other being shorter than self, or the strings being equal.
// In either case, we want to return false.
result = false;
break;
}
else if(self_iter >= self_end)
{
// self is shorter than other.
result = true;
break;
}
else if(*self_iter != *other_iter)
{
// The current character differs. The strings are not equal.
result = *self_iter < *other_iter;
break;
}
self_iter++;
other_iter++;
}
return result;
}
LLColor3 LLKeywords::readColor( const std::string& s )
{
F32 r, g, b;
r = g = b = 0.0f;
S32 read = sscanf(s.c_str(), "%f, %f, %f]", &r, &g, &b );
if( read != 3 ) /* Flawfinder: ignore */
S32 values_read = sscanf(s.c_str(), "%f, %f, %f]", &r, &g, &b );
if( values_read != 3 )
{
llinfos << " poorly formed color in keyword file" << llendl;
}
return LLColor3( r, g, b );
}
LLFastTimer::DeclareTimer FTM_SYNTAX_COLORING("Syntax Coloring");
// Walk through a string, applying the rules specified by the keyword token list and
// create a list of color segments.
void LLKeywords::findSegments(std::vector<LLTextSegment *>* seg_list, const LLWString& wtext, const LLColor4 &defaultColor)
void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLWString& wtext, const LLColor4 &defaultColor)
{
std::for_each(seg_list->begin(), seg_list->end(), DeletePointer());
LLFastTimer ft(FTM_SYNTAX_COLORING);
seg_list->clear();
if( wtext.empty() )
@@ -290,7 +367,7 @@ void LLKeywords::findSegments(std::vector<LLTextSegment *>* seg_list, const LLWS
return;
}
S32 text_len = wtext.size();
S32 text_len = wtext.size() + 1;
seg_list->push_back( new LLTextSegment( LLColor3(defaultColor), 0, text_len ) );
@@ -343,9 +420,9 @@ void LLKeywords::findSegments(std::vector<LLTextSegment *>* seg_list, const LLWS
}
S32 seg_end = cur - base;
LLTextSegment* text_segment = new LLTextSegment( cur_token->getColor(), seg_start, seg_end );
LLTextSegmentPtr text_segment = new LLTextSegment( cur_token->getColor(), seg_start, seg_end );
text_segment->setToken( cur_token );
insertSegment( seg_list, text_segment, text_len, defaultColor);
insertSegment( *seg_list, text_segment, text_len, defaultColor);
line_done = TRUE; // to break out of second loop.
break;
}
@@ -387,17 +464,15 @@ void LLKeywords::findSegments(std::vector<LLTextSegment *>* seg_list, const LLWS
S32 seg_end = 0;
seg_start = cur - base;
cur += cur_delimiter->getLength();
cur += cur_delimiter->getLengthHead();
//if( cur_delimiter->getType() == LLKeywordToken::TWO_SIDED_DELIMITER )
LLKeywordToken::TOKEN_TYPE type = cur_delimiter->getType();
if( type == LLKeywordToken::TWO_SIDED_DELIMITER || type == LLKeywordToken::TWO_SIDED_DELIMITER_ESC )
if( type == LLKeywordToken::TWO_SIDED_DELIMITER || type == LLKeywordToken::DOUBLE_QUOTATION_MARKS )
{
//llassert( cur_delimiter->getDelimiter() != NULL );
while( *cur && !cur_delimiter->isTail(cur) )
while( *cur && !cur_delimiter->isTail(cur))
{
// Check for an escape sequence.
if (type == LLKeywordToken::TWO_SIDED_DELIMITER_ESC && *cur == '\\')
if (type == LLKeywordToken::DOUBLE_QUOTATION_MARKS && *cur == '\\')
{
// Count the number of backslashes.
S32 num_backslashes = 0;
@@ -433,13 +508,13 @@ void LLKeywords::findSegments(std::vector<LLTextSegment *>* seg_list, const LLWS
if( *cur )
{
cur += cur_delimiter->getLength();
seg_end = seg_start + between_delimiters + cur_delimiter->getLength() + cur_delimiter->getLength2();
cur += cur_delimiter->getLengthHead();
seg_end = seg_start + between_delimiters + cur_delimiter->getLengthHead() + cur_delimiter->getLengthTail();
}
else
{
// eof
seg_end = seg_start + between_delimiters + cur_delimiter->getLength();
seg_end = seg_start + between_delimiters + cur_delimiter->getLengthHead();
}
}
else
@@ -451,13 +526,13 @@ void LLKeywords::findSegments(std::vector<LLTextSegment *>* seg_list, const LLWS
between_delimiters++;
cur++;
}
seg_end = seg_start + between_delimiters + cur_delimiter->getLength();
seg_end = seg_start + between_delimiters + cur_delimiter->getLengthHead();
}
LLTextSegment* text_segment = new LLTextSegment( cur_delimiter->getColor(), seg_start, seg_end );
LLTextSegmentPtr text_segment = new LLTextSegment( cur_delimiter->getColor(), seg_start, seg_end );
text_segment->setToken( cur_delimiter );
insertSegment( seg_list, text_segment, text_len, defaultColor);
insertSegment( *seg_list, text_segment, text_len, defaultColor);
// Note: we don't increment cur, since the end of one delimited seg may be immediately
// followed by the start of another one.
@@ -477,7 +552,7 @@ void LLKeywords::findSegments(std::vector<LLTextSegment *>* seg_list, const LLWS
S32 seg_len = p - cur;
if( seg_len > 0 )
{
LLWString word( cur, 0, seg_len );
WStringMapIndex word( cur, seg_len );
word_token_map_t::iterator map_iter = mWordTokenMap.find(word);
if( map_iter != mWordTokenMap.end() )
{
@@ -488,9 +563,9 @@ void LLKeywords::findSegments(std::vector<LLTextSegment *>* seg_list, const LLWS
// llinfos << "Seg: [" << word.c_str() << "]" << llendl;
LLTextSegment* text_segment = new LLTextSegment( cur_token->getColor(), seg_start, seg_end );
LLTextSegmentPtr text_segment = new LLTextSegment( cur_token->getColor(), seg_start, seg_end );
text_segment->setToken( cur_token );
insertSegment( seg_list, text_segment, text_len, defaultColor);
insertSegment( *seg_list, text_segment, text_len, defaultColor);
}
cur += seg_len;
continue;
@@ -505,25 +580,24 @@ void LLKeywords::findSegments(std::vector<LLTextSegment *>* seg_list, const LLWS
}
}
void LLKeywords::insertSegment(std::vector<LLTextSegment*>* seg_list, LLTextSegment* new_segment, S32 text_len, const LLColor4 &defaultColor )
void LLKeywords::insertSegment(std::vector<LLTextSegmentPtr>& seg_list, LLTextSegmentPtr new_segment, S32 text_len, const LLColor4 &defaultColor )
{
LLTextSegment* last = seg_list->back();
LLTextSegmentPtr last = seg_list.back();
S32 new_seg_end = new_segment->getEnd();
if( new_segment->getStart() == last->getStart() )
{
*last = *new_segment;
delete new_segment;
seg_list.pop_back();
}
else
{
last->setEnd( new_segment->getStart() );
seg_list->push_back( new_segment );
}
seg_list.push_back( new_segment );
if( new_seg_end < text_len )
{
seg_list->push_back( new LLTextSegment( defaultColor, new_seg_end, text_len ) );
seg_list.push_back( new LLTextSegment( defaultColor, new_seg_end, text_len ) );
}
}

View File

@@ -39,14 +39,32 @@
#include <map>
#include <list>
#include <deque>
#include "llpointer.h"
class LLTextSegment;
typedef LLPointer<LLTextSegment> LLTextSegmentPtr;
class LLKeywordToken
{
public:
enum TOKEN_TYPE { WORD, LINE, TWO_SIDED_DELIMITER, ONE_SIDED_DELIMITER, TWO_SIDED_DELIMITER_ESC };
/**
* @brief Types of tokens/delimters being parsed.
*
* @desc Tokens/delimiters that need to be identified/highlighted. All are terminated if an EOF is encountered.
* - WORD are keywords in the normal sense, i.e. constants, events, etc.
* - LINE are for entire lines (currently only flow control labels use this).
* - ONE_SIDED_DELIMITER are for open-ended delimiters which are terminated by EOL.
* - TWO_SIDED_DELIMITER are for delimiters that end with a different delimiter than they open with.
* - DOUBLE_QUOTATION_MARKS are for delimiting areas using the same delimiter to open and close.
*/
enum TOKEN_TYPE
{
WORD,
LINE,
TWO_SIDED_DELIMITER,
ONE_SIDED_DELIMITER,
DOUBLE_QUOTATION_MARKS
};
LLKeywordToken( TOKEN_TYPE type, const LLColor3& color, const LLWString& token, const LLWString& tool_tip, const LLWString& delimiter )
:
@@ -58,9 +76,9 @@ public:
{
}
S32 getLength() const { return mToken.size(); }
S32 getLength2() const { return mDelimiter.size(); }
BOOL isHead(const llwchar* s, bool search_end_c_comment = false) const;
S32 getLengthHead() const { return mToken.size(); }
S32 getLengthTail() const { return mDelimiter.size(); }
BOOL isHead(const llwchar* s) const;
BOOL isTail(const llwchar* s) const;
const LLWString& getToken() const { return mToken; }
const LLColor3& getColor() const { return mColor; }
@@ -89,7 +107,7 @@ public:
BOOL loadFromFile(const std::string& filename);
BOOL isLoaded() const { return mLoaded; }
void findSegments(std::vector<LLTextSegment *> *seg_list, const LLWString& text, const LLColor4 &defaultColor );
void findSegments(std::vector<LLTextSegmentPtr> *seg_list, const LLWString& text, const LLColor4 &defaultColor );
// Add the token as described
void addToken(LLKeywordToken::TOKEN_TYPE type,
@@ -97,8 +115,33 @@ public:
const LLColor3& color,
const std::string& tool_tip = LLStringUtil::null,
const std::string& delimiter = LLStringUtil::null);
// This class is here as a performance optimization.
// The word token map used to be defined as std::map<LLWString, LLKeywordToken*>.
// This worked, but caused a performance bottleneck due to memory allocation and string copies
// because it's not possible to search such a map without creating an LLWString.
// Using this class as the map index instead allows us to search using segments of an existing
// text run without copying them first, which greatly reduces overhead in LLKeywords::findSegments().
class WStringMapIndex
{
public:
// copy constructor
WStringMapIndex(const WStringMapIndex& other);
// constructor from a string (copies the string's data into the new object)
WStringMapIndex(const LLWString& str);
// constructor from pointer and length
// NOTE: does NOT copy data, caller must ensure that the lifetime of the pointer exceeds that of the new object!
WStringMapIndex(const llwchar *start, size_t length);
~WStringMapIndex();
bool operator<(const WStringMapIndex &other) const;
private:
void copyData(const llwchar *start, size_t length);
const llwchar *mData;
size_t mLength;
bool mOwner;
};
typedef std::map<LLWString, LLKeywordToken*> word_token_map_t;
typedef std::map<WStringMapIndex, LLKeywordToken*> word_token_map_t;
typedef word_token_map_t::const_iterator keyword_iterator_t;
keyword_iterator_t begin() const { return mWordTokenMap.begin(); }
keyword_iterator_t end() const { return mWordTokenMap.end(); }
@@ -109,7 +152,7 @@ public:
private:
LLColor3 readColor(const std::string& s);
void insertSegment(std::vector<LLTextSegment *> *seg_list, LLTextSegment* new_segment, S32 text_len, const LLColor4 &defaultColor);
void insertSegment(std::vector<LLTextSegmentPtr>& seg_list, LLTextSegmentPtr new_segment, S32 text_len, const LLColor4 &defaultColor);
BOOL mLoaded;
word_token_map_t mWordTokenMap;

View File

@@ -1053,7 +1053,13 @@ struct LLLayoutStack::LLEmbeddedPanel
{
min_dim = mMinWidth;
}
mResizeBar = new LLResizeBar(std::string("resizer"), mPanel, LLRect(), min_dim, S32_MAX, side);
LLResizeBar::Params p;
p.name = "resizer";
p.resizing_view = mPanel;
p.min_size = min_dim;
p.max_size = S32_MAX;
p.side = side;
mResizeBar = LLUICtrlFactory::create<LLResizeBar>(p);
mResizeBar->setEnableSnapping(FALSE);
// panels initialized as hidden should not start out partially visible
if (!mPanel->getVisible())

View File

@@ -40,23 +40,22 @@
#include "llfocusmgr.h"
#include "llwindow.h"
LLResizeBar::LLResizeBar( const std::string& name, LLView* resizing_view, const LLRect& rect, S32 min_size, S32 max_size, Side side )
:
LLView( name, rect, TRUE ),
LLResizeBar::LLResizeBar(const LLResizeBar::Params& p)
: LLView(p),
mDragLastScreenX( 0 ),
mDragLastScreenY( 0 ),
mLastMouseScreenX( 0 ),
mLastMouseScreenY( 0 ),
mMinSize( min_size ),
mMaxSize( max_size ),
mSide( side ),
mSnappingEnabled(TRUE),
mAllowDoubleClickSnapping(TRUE),
mResizingView(resizing_view)
mMinSize( p.min_size ),
mMaxSize( p.max_size ),
mSide( p.side ),
mSnappingEnabled(p.snapping_enabled),
mAllowDoubleClickSnapping(p.allow_double_click_snapping),
mResizingView(p.resizing_view)
{
setFollowsNone();
// set up some generically good follow code.
switch( side )
switch( mSide )
{
case LEFT:
setFollowsLeft();
@@ -180,6 +179,11 @@ BOOL LLResizeBar::handleHover(S32 x, S32 y, MASK mask)
break;
}
notifyParent(LLSD().with("action", "resize")
.with("view_name", mResizingView->getName())
.with("new_height", new_height)
.with("new_width", new_width));
scaled_rect.mTop = scaled_rect.mBottom + new_height;
scaled_rect.mRight = scaled_rect.mLeft + new_width;
mResizingView->setRect(scaled_rect);
@@ -188,8 +192,7 @@ BOOL LLResizeBar::handleHover(S32 x, S32 y, MASK mask)
if (mSnappingEnabled)
{
//static LLCachedControl<S32> snap_margin (*LLUI::sConfigGroup,"SnapMargin", 0);
S32 snap_margin = LLUI::sConfigGroup->getS32("SnapMargin");
static LLUICachedControl<S32> snap_margin ("SnapMargin", 0);
switch( mSide )
{
case LEFT:
@@ -220,17 +223,62 @@ BOOL LLResizeBar::handleHover(S32 x, S32 y, MASK mask)
switch(mSide)
{
case LEFT:
mDragLastScreenX += new_rect.mLeft - orig_rect.mLeft;
{
S32 actual_delta_x = new_rect.mLeft - orig_rect.mLeft;
if (actual_delta_x != delta_x)
{
// restore everything by left
new_rect.mBottom = orig_rect.mBottom;
new_rect.mTop = orig_rect.mTop;
new_rect.mRight = orig_rect.mRight;
mResizingView->setShape(new_rect, true);
}
mDragLastScreenX += actual_delta_x;
break;
}
case RIGHT:
{
S32 actual_delta_x = new_rect.mRight - orig_rect.mRight;
if (actual_delta_x != delta_x)
{
// restore everything by left
new_rect.mBottom = orig_rect.mBottom;
new_rect.mTop = orig_rect.mTop;
new_rect.mLeft = orig_rect.mLeft;
mResizingView->setShape(new_rect, true);
}
mDragLastScreenX += new_rect.mRight - orig_rect.mRight;
break;
}
case TOP:
{
S32 actual_delta_y = new_rect.mTop - orig_rect.mTop;
if (actual_delta_y != delta_y)
{
// restore everything by left
new_rect.mBottom = orig_rect.mBottom;
new_rect.mLeft = orig_rect.mLeft;
new_rect.mRight = orig_rect.mRight;
mResizingView->setShape(new_rect, true);
}
mDragLastScreenY += new_rect.mTop - orig_rect.mTop;
break;
}
case BOTTOM:
{
S32 actual_delta_y = new_rect.mBottom - orig_rect.mBottom;
if (actual_delta_y != delta_y)
{
// restore everything by left
new_rect.mTop = orig_rect.mTop;
new_rect.mLeft = orig_rect.mLeft;
new_rect.mRight = orig_rect.mRight;
mResizingView->setShape(new_rect, true);
}
mDragLastScreenY += new_rect.mBottom- orig_rect.mBottom;
break;
}
default:
break;
}

View File

@@ -41,7 +41,31 @@ class LLResizeBar : public LLView
public:
enum Side { LEFT, TOP, RIGHT, BOTTOM };
LLResizeBar(const std::string& name, LLView* resizing_view, const LLRect& rect, S32 min_size, S32 max_size, Side side );
struct Params : public LLInitParam::Block<Params, LLView::Params>
{
Mandatory<LLView*> resizing_view;
Mandatory<Side> side;
Optional<S32> min_size;
Optional<S32> max_size;
Optional<bool> snapping_enabled;
Optional<bool> allow_double_click_snapping;
Params()
: max_size("max_size", S32_MAX),
snapping_enabled("snapping_enabled", true),
resizing_view("resizing_view"),
side("side"),
allow_double_click_snapping("allow_double_click_snapping", true)
{
name = "resize_bar";
}
};
protected:
LLResizeBar(const LLResizeBar::Params& p);
friend class LLUICtrlFactory;
public:
// virtual void draw(); No appearance
virtual BOOL handleHover(S32 x, S32 y, MASK mask);

View File

@@ -44,31 +44,36 @@
const S32 RESIZE_BORDER_WIDTH = 3;
LLResizeHandle::LLResizeHandle( const std::string& name, const LLRect& rect, S32 min_width, S32 min_height, ECorner corner )
:
LLView( name, rect, FALSE ),
LLResizeHandle::Params::Params()
: corner("corner"),
min_width("min_width"),
min_height("min_height")
{
name = "resize_handle";
}
LLResizeHandle::LLResizeHandle(const LLResizeHandle::Params& p)
: LLView(p),
mDragLastScreenX( 0 ),
mDragLastScreenY( 0 ),
mLastMouseScreenX( 0 ),
mLastMouseScreenY( 0 ),
mImage( NULL ),
mMinWidth( min_width ),
mMinHeight( min_height ),
mCorner( corner )
mMinWidth( p.min_width ),
mMinHeight( p.min_height ),
mCorner( p.corner )
{
setSaveToXML(false);
if( RIGHT_BOTTOM == mCorner)
{
mImage = LLUI::getUIImage("UIImgResizeBottomRightUUID");
}
switch( mCorner )
switch( p.corner )
{
case LEFT_TOP: setFollows( FOLLOWS_LEFT | FOLLOWS_TOP ); break;
case LEFT_BOTTOM: setFollows( FOLLOWS_LEFT | FOLLOWS_BOTTOM ); break;
case RIGHT_TOP: setFollows( FOLLOWS_RIGHT | FOLLOWS_TOP ); break;
case RIGHT_BOTTOM: setFollows( FOLLOWS_RIGHT | FOLLOWS_BOTTOM ); break;
case LEFT_TOP: setFollows( FOLLOWS_LEFT | FOLLOWS_TOP ); break;
case LEFT_BOTTOM: setFollows( FOLLOWS_LEFT | FOLLOWS_BOTTOM ); break;
case RIGHT_TOP: setFollows( FOLLOWS_RIGHT | FOLLOWS_TOP ); break;
case RIGHT_BOTTOM: setFollows( FOLLOWS_RIGHT | FOLLOWS_BOTTOM ); break;
}
// decorator object, don't serialize
@@ -205,8 +210,7 @@ BOOL LLResizeHandle::handleHover(S32 x, S32 y, MASK mask)
LLView* snap_view = NULL;
LLView* test_view = NULL;
//static LLCachedControl<S32> snap_margin (*LLUI::sConfigGroup,"SnapMargin", 0);
S32 snap_margin = LLUI::sConfigGroup->getS32("SnapMargin");
static LLUICachedControl<S32> snap_margin ("SnapMargin", 0);
// now do snapping
switch(mCorner)
{
@@ -255,23 +259,65 @@ BOOL LLResizeHandle::handleHover(S32 x, S32 y, MASK mask)
// update last valid mouse cursor position based on resized view's actual size
LLRect new_rect = resizing_view->getRect();
S32 actual_delta_x = 0;
S32 actual_delta_y = 0;
switch(mCorner)
{
case LEFT_TOP:
mDragLastScreenX += new_rect.mLeft - orig_rect.mLeft;
mDragLastScreenY += new_rect.mTop - orig_rect.mTop;
actual_delta_x = new_rect.mLeft - orig_rect.mLeft;
actual_delta_y = new_rect.mTop - orig_rect.mTop;
if (actual_delta_x != delta_x
|| actual_delta_y != delta_y)
{
new_rect.mRight = orig_rect.mRight;
new_rect.mBottom = orig_rect.mBottom;
resizing_view->setShape(new_rect, true);
}
mDragLastScreenX += actual_delta_x;
mDragLastScreenY += actual_delta_y;
break;
case LEFT_BOTTOM:
mDragLastScreenX += new_rect.mLeft - orig_rect.mLeft;
mDragLastScreenY += new_rect.mBottom- orig_rect.mBottom;
actual_delta_x = new_rect.mLeft - orig_rect.mLeft;
actual_delta_y = new_rect.mBottom - orig_rect.mBottom;
if (actual_delta_x != delta_x
|| actual_delta_y != delta_y)
{
new_rect.mRight = orig_rect.mRight;
new_rect.mTop = orig_rect.mTop;
resizing_view->setShape(new_rect, true);
}
mDragLastScreenX += actual_delta_x;
mDragLastScreenY += actual_delta_y;
break;
case RIGHT_TOP:
mDragLastScreenX += new_rect.mRight - orig_rect.mRight;
mDragLastScreenY += new_rect.mTop - orig_rect.mTop;
actual_delta_x = new_rect.mRight - orig_rect.mRight;
actual_delta_y = new_rect.mTop - orig_rect.mTop;
if (actual_delta_x != delta_x
|| actual_delta_y != delta_y)
{
new_rect.mLeft = orig_rect.mLeft;
new_rect.mBottom = orig_rect.mBottom;
resizing_view->setShape(new_rect, true);
}
mDragLastScreenX += actual_delta_x;
mDragLastScreenY += actual_delta_y;
break;
case RIGHT_BOTTOM:
mDragLastScreenX += new_rect.mRight - orig_rect.mRight;
mDragLastScreenY += new_rect.mBottom- orig_rect.mBottom;
actual_delta_x = new_rect.mRight - orig_rect.mRight;
actual_delta_y = new_rect.mBottom - orig_rect.mBottom;
if (actual_delta_x != delta_x
|| actual_delta_y != delta_y)
{
new_rect.mLeft = orig_rect.mLeft;
new_rect.mTop = orig_rect.mTop;
resizing_view->setShape(new_rect, true);
}
mDragLastScreenX += actual_delta_x;
mDragLastScreenY += actual_delta_y;
break;
default:
break;

View File

@@ -35,7 +35,6 @@
#include "stdtypes.h"
#include "llview.h"
#include "llimagegl.h"
#include "llcoord.h"
@@ -44,9 +43,18 @@ class LLResizeHandle : public LLView
public:
enum ECorner { LEFT_TOP, LEFT_BOTTOM, RIGHT_TOP, RIGHT_BOTTOM };
LLResizeHandle(const std::string& name, const LLRect& rect, S32 min_width, S32 min_height, ECorner corner = RIGHT_BOTTOM );
struct Params : public LLInitParam::Block<Params, LLView::Params>
{
Mandatory<ECorner> corner;
Optional<S32> min_width;
Optional<S32> min_height;
Params();
};
protected:
LLResizeHandle(const LLResizeHandle::Params&);
friend class LLUICtrlFactory;
public:
virtual void draw();
virtual BOOL handleHover(S32 x, S32 y, MASK mask);
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);

View File

@@ -3888,11 +3888,14 @@ LLScrollColumnHeader::LLScrollColumnHeader(const std::string& label, const LLRec
// resize handles on left and right
const S32 RESIZE_BAR_THICKNESS = 3;
mResizeBar = new LLResizeBar(
std::string("resizebar"),
this,
LLRect( getRect().getWidth() - RESIZE_BAR_THICKNESS, getRect().getHeight(), getRect().getWidth(), 0),
MIN_COLUMN_WIDTH, S32_MAX, LLResizeBar::RIGHT );
LLResizeBar::Params p;
p.name = "resizebar";
p.resizing_view = this;
p.rect = LLRect( getRect().getWidth() - RESIZE_BAR_THICKNESS, getRect().getHeight(), getRect().getWidth(), 0);
p.min_size = MIN_COLUMN_WIDTH;
p.max_size = S32_MAX;
p.side = LLResizeBar::RIGHT;
mResizeBar = LLUICtrlFactory::create<LLResizeBar>(p);
addChild(mResizeBar);
mResizeBar->setEnabled(FALSE);

View File

@@ -48,19 +48,19 @@
LLStatBar::LLStatBar(const std::string& name, const LLRect& rect, const std::string& setting,
BOOL default_bar, BOOL default_history)
: LLView(name, rect, TRUE),
mSetting(setting)
mSetting(setting),
mLabel(name),
mMinBar(0.f),
mMaxBar(50.f),
mStatp(NULL),
mTickSpacing(10.f),
mLabelSpacing(10.f),
mPrecision(0),
mUpdatesPerSec(5),
mPerSec(true),
mDisplayMean(true)
{
mMinBar = 0.f;
mMaxBar = 50.f;
mStatp = NULL;
mTickSpacing = 10.f;
mLabelSpacing = 10.f;
mPrecision = 0;
mUpdatesPerSec = 5;
mLabel = name;
mPerSec = TRUE;
mValue = 0.f;
mDisplayMean = TRUE;
S32 mode = -1;
if (mSetting.length() > 0)
@@ -296,16 +296,6 @@ void LLStatBar::draw()
LLView::draw();
}
const std::string& LLStatBar::getLabel() const
{
return mLabel;
}
void LLStatBar::setLabel(const std::string& label)
{
mLabel = label;
}
void LLStatBar::setUnitLabel(const std::string& unit_label)
{
mUnitLabel = unit_label;
@@ -319,7 +309,7 @@ LLRect LLStatBar::getRequiredRect()
{
if (mDisplayHistory)
{
rect.mTop = 67;
rect.mTop = 35 + mStatp->getNumBins();
}
else
{

View File

@@ -53,8 +53,6 @@ public:
virtual void draw();
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
const std::string& getLabel() const;
void setLabel(const std::string& label);
void setUnitLabel(const std::string& unit_label);
/*virtual*/ LLRect getRequiredRect(); // Return the height of this object, given the set options.
@@ -72,7 +70,7 @@ public:
LLStat *mStatp;
private:
LLFrameTimer mUpdateTimer;
std::string mLabel;
LLUIString mLabel;
std::string mUnitLabel;
F32 mValue;
std::string mSetting;

View File

@@ -373,8 +373,6 @@ LLTextEditor::~LLTextEditor()
gFocusMgr.releaseFocusIfNeeded( this ); // calls onCommit()
// Scrollbar is deleted by LLView
mHoverSegment = NULL;
std::for_each(mSegments.begin(), mSegments.end(), DeletePointer());
std::for_each(mUndoStack.begin(), mUndoStack.end(), DeletePointer());
//LLView::deleteViewByHandle(mPopupMenuHandle);
@@ -949,7 +947,7 @@ const LLTextSegment* LLTextEditor::getPreviousSegment() const
return idx >= 0 ? mSegments[idx] : NULL;
}
void LLTextEditor::getSelectedSegments(std::vector<const LLTextSegment*>& segments) const
void LLTextEditor::getSelectedSegments(std::vector<const LLTextSegmentPtr>& segments) const
{
S32 left = hasSelection() ? llmin(mSelectionStart, mSelectionEnd) : mCursorPos;
S32 right = hasSelection() ? llmax(mSelectionStart, mSelectionEnd) : mCursorPos;
@@ -1527,7 +1525,7 @@ BOOL LLTextEditor::handleHover(S32 x, S32 y, MASK mask)
// Check to see if we're over an HTML-style link
if( !mSegments.empty() )
{
const LLTextSegment* cur_segment = getSegmentAtLocalPos( x, y );
LLTextSegment* cur_segment = getSegmentAtLocalPos( x, y );
if( cur_segment )
{
if(cur_segment->getStyle()->isLink())
@@ -3647,7 +3645,6 @@ void LLTextEditor::onTabInto()
void LLTextEditor::clear()
{
setText(LLStringUtil::null);
std::for_each(mSegments.begin(), mSegments.end(), DeletePointer());
mSegments.clear();
}
@@ -4165,7 +4162,7 @@ void LLTextEditor::appendText(const std::string &new_text, bool allow_undo, bool
{
S32 segment_start = old_length;
S32 segment_end = getLength();
LLTextSegment* segment = new LLTextSegment(stylep, segment_start, segment_end );
LLTextSegmentPtr segment = new LLTextSegment(stylep, segment_start, segment_end );
mSegments.push_back(segment);
}
@@ -4383,13 +4380,12 @@ void LLTextEditor::updateSegments()
// Make sure we have at least one segment
if (mSegments.size() == 1 && mSegments[0]->getIsDefault())
{
delete mSegments[0];
mSegments.clear(); // create default segment
}
if (mSegments.empty())
{
LLColor4& text_color = ( mReadOnly ? mReadOnlyFgColor : mFgColor );
LLTextSegment* default_segment = new LLTextSegment( text_color, 0, mWText.length() );
LLTextSegmentPtr default_segment = new LLTextSegment( text_color, 0, mWText.length() );
default_segment->setIsDefault(TRUE);
mSegments.push_back(default_segment);
}
@@ -4420,7 +4416,6 @@ void LLTextEditor::pruneSegments()
{
// erase invalid segments
++iter;
std::for_each(iter, mSegments.end(), DeletePointer());
mSegments.erase(iter, mSegments.end());
}
else
@@ -4432,7 +4427,6 @@ void LLTextEditor::pruneSegments()
void LLTextEditor::findEmbeddedItemSegments()
{
mHoverSegment = NULL;
std::for_each(mSegments.begin(), mSegments.end(), DeletePointer());
mSegments.clear();
BOOL found_embedded_items = FALSE;
@@ -4513,7 +4507,7 @@ BOOL LLTextEditor::handleMouseUpOverSegment(S32 x, S32 y, MASK mask)
// Finds the text segment (if any) at the give local screen position
const LLTextSegment* LLTextEditor::getSegmentAtLocalPos( S32 x, S32 y ) const
LLTextSegment* LLTextEditor::getSegmentAtLocalPos( S32 x, S32 y ) const
{
// Find the cursor position at the requested local screen position
S32 offset = getCursorPosFromLocalCoord( x, y, FALSE );

View File

@@ -293,7 +293,7 @@ public:
const LLTextSegment* getCurrentSegment() const { return getSegmentAtOffset(mCursorPos); }
const LLTextSegment* getPreviousSegment() const;
void getSelectedSegments(std::vector<const LLTextSegment*>& segments) const;
void getSelectedSegments(std::vector<const LLTextSegmentPtr>& segments) const;
static bool isPartOfWord(llwchar c) { return ( (c == '_') || (c == '\'') || LLStringOps::isAlnum((char)c)); }
@@ -327,7 +327,7 @@ protected:
void unindentLineBeforeCloseBrace();
S32 getSegmentIdxAtOffset(S32 offset) const;
const LLTextSegment* getSegmentAtLocalPos(S32 x, S32 y) const;
LLTextSegment* getSegmentAtLocalPos(S32 x, S32 y) const;
const LLTextSegment* getSegmentAtOffset(S32 offset) const;
void reportBadKeystroke() { make_ui_sound("UISndBadKeystroke"); }
@@ -462,9 +462,9 @@ protected:
BOOL mParseHighlights;
std::string mHTML;
typedef std::vector<LLTextSegment *> segment_list_t;
typedef std::vector<LLTextSegmentPtr> segment_list_t;
segment_list_t mSegments;
const LLTextSegment* mHoverSegment;
LLTextSegmentPtr mHoverSegment;
// Scrollbar data
class LLScrollbar* mScrollbar;
@@ -613,7 +613,7 @@ private:
class LLTextSegment
class LLTextSegment : public LLRefCount
{
public:
// for creating a compare value

View File

@@ -61,6 +61,7 @@ std::map<std::string, std::string> gTranslation;
std::list<std::string> gUntranslated;
/*static*/ LLControlGroup* LLUI::sConfigGroup = NULL;
/*static*/ LLControlGroup* LLUI::sAccountGroup = NULL;
/*static*/ LLControlGroup* LLUI::sIgnoresGroup = NULL;
/*static*/ LLControlGroup* LLUI::sColorsGroup = NULL;
/*static*/ LLUIAudioCallback LLUI::sAudioCallback = NULL;
@@ -116,6 +117,7 @@ bool handleShowXUINamesChanged(const LLSD& newvalue)
}
void LLUI::initClass(LLControlGroup* config,
LLControlGroup* account,
LLControlGroup* ignores,
LLControlGroup* colors,
LLImageProviderInterface* image_provider,
@@ -126,10 +128,12 @@ void LLUI::initClass(LLControlGroup* config,
{
LLRender2D::initClass(image_provider, scale_factor);
sConfigGroup = config;
sAccountGroup = account;
sIgnoresGroup = ignores;
sColorsGroup = colors;
if (sConfigGroup == NULL
|| sAccountGroup == NULL
|| sIgnoresGroup == NULL
|| sColorsGroup == NULL)
{
@@ -287,6 +291,20 @@ void LLUI::glRectToScreen(const LLRect& gl, LLRect *screen)
glPointToScreen(gl.mRight, gl.mBottom, &screen->mRight, &screen->mBottom);
}
LLControlGroup& LLUI::getControlControlGroup (const std::string& controlname)
{
if(sConfigGroup->controlExists(controlname))
return *sConfigGroup;
if(sAccountGroup->controlExists(controlname))
return *sAccountGroup;
//if(sIgnoresGroup->controlExists(controlname)) //Identical to sConfigGroup currently.
// return *sIgnoresGroup;
if(sColorsGroup->controlExists(controlname))
return *sColorsGroup;
return *sConfigGroup;
}
// static
void LLUI::setHtmlHelp(LLHtmlHelp* html_help)
{

View File

@@ -62,6 +62,7 @@ public:
// Methods
//
static void initClass(LLControlGroup* config,
LLControlGroup* account,
LLControlGroup* ignores,
LLControlGroup* colors,
LLImageProviderInterface* image_provider,
@@ -99,12 +100,15 @@ public:
static void glPointToScreen(S32 gl_x, S32 gl_y, S32 *screen_x, S32 *screen_y);
static void screenRectToGL(const LLRect& screen, LLRect *gl);
static void glRectToScreen(const LLRect& gl, LLRect *screen);
// Returns the control group containing the control name, or the default group
static LLControlGroup& getControlControlGroup (const std::string& controlname);
static void setHtmlHelp(LLHtmlHelp* html_help);
//
// Data
//
static LLControlGroup* sConfigGroup;
static LLControlGroup* sAccountGroup;
static LLControlGroup* sIgnoresGroup;
static LLControlGroup* sColorsGroup;
static LLUIAudioCallback sAudioCallback;
@@ -392,6 +396,24 @@ template <typename T> LLRegisterWith<LLInitClassList> LLInitClass<T>::sRegister(
template <typename T> LLRegisterWith<LLDestroyClassList> LLDestroyClass<T>::sRegister(&T::destroyClass);
template <class T>
class LLUICachedControl : public LLCachedControl<T>
{
public:
// This constructor will declare a control if it doesn't exist in the contol group
LLUICachedControl(const std::string& name,
const T& default_value,
const std::string& comment = "Declared In Code")
: LLCachedControl<T>(LLUI::getControlControlGroup(name), name, default_value, comment)
{}
// This constructor will signal an error if the control doesn't exist in the control group
LLUICachedControl(const std::string& name)
: LLCachedControl<T>(LLUI::getControlControlGroup(name), name)
{}
};
template <typename DERIVED>
class LLParamBlock
{

View File

@@ -33,31 +33,35 @@
#include "linden_common.h"
#include "lluistring.h"
#include "llsd.h"
#include "lltrans.h"
const LLStringUtil::format_map_t LLUIString::sNullArgs;
LLFastTimer::DeclareTimer FTM_UI_STRING("UI String");
LLUIString::LLUIString(const std::string& instring, const LLStringUtil::format_map_t& args)
: mOrig(instring),
mArgs(args)
: mOrig(instring),
mArgs(new LLStringUtil::format_map_t(args))
{
format();
dirty();
}
void LLUIString::assign(const std::string& s)
{
mOrig = s;
format();
dirty();
}
void LLUIString::setArgList(const LLStringUtil::format_map_t& args)
{
mArgs = args;
format();
getArgs() = args;
dirty();
}
void LLUIString::setArgs(const LLSD& sd)
{
LLFastTimer timer(FTM_UI_STRING);
if (!sd.isMap()) return;
for(LLSD::map_const_iterator sd_it = sd.beginMap();
sd_it != sd.endMap();
@@ -65,40 +69,40 @@ void LLUIString::setArgs(const LLSD& sd)
{
setArg(sd_it->first, sd_it->second.asString());
}
format();
dirty();
}
void LLUIString::setArg(const std::string& key, const std::string& replacement)
{
mArgs[key] = replacement;
format();
getArgs()[key] = replacement;
dirty();
}
void LLUIString::truncate(S32 maxchars)
{
if (mWResult.size() > (size_t)maxchars)
if (getUpdatedWResult().size() > (size_t)maxchars)
{
LLWStringUtil::truncate(mWResult, maxchars);
mResult = wstring_to_utf8str(mWResult);
LLWStringUtil::truncate(getUpdatedWResult(), maxchars);
mResult = wstring_to_utf8str(getUpdatedWResult());
}
}
void LLUIString::erase(S32 charidx, S32 len)
{
mWResult.erase(charidx, len);
mResult = wstring_to_utf8str(mWResult);
getUpdatedWResult().erase(charidx, len);
mResult = wstring_to_utf8str(getUpdatedWResult());
}
void LLUIString::insert(S32 charidx, const LLWString& wchars)
{
mWResult.insert(charidx, wchars);
mResult = wstring_to_utf8str(mWResult);
getUpdatedWResult().insert(charidx, wchars);
mResult = wstring_to_utf8str(getUpdatedWResult());
}
void LLUIString::replace(S32 charidx, llwchar wc)
{
mWResult[charidx] = wc;
mResult = wstring_to_utf8str(mWResult);
getUpdatedWResult()[charidx] = wc;
mResult = wstring_to_utf8str(getUpdatedWResult());
}
void LLUIString::clear()
@@ -109,9 +113,48 @@ void LLUIString::clear()
mWResult.clear();
}
void LLUIString::format()
void LLUIString::dirty()
{
mResult = mOrig;
LLStringUtil::format(mResult, mArgs);
mWResult = utf8str_to_wstring(mResult);
mNeedsResult = true;
mNeedsWResult = true;
}
void LLUIString::updateResult() const
{
mNeedsResult = false;
LLFastTimer timer(FTM_UI_STRING);
// optimize for empty strings (don't attempt string replacement)
if (mOrig.empty())
{
mResult.clear();
mWResult.clear();
return;
}
mResult = mOrig;
// get the default args + local args
LLStringUtil::format_map_t combined_args = LLTrans::getDefaultArgs();
if (mArgs && !mArgs->empty())
{
combined_args.insert(mArgs->begin(), mArgs->end());
}
LLStringUtil::format(mResult, combined_args);
}
void LLUIString::updateWResult() const
{
mNeedsWResult = false;
mWResult = utf8str_to_wstring(getUpdatedResult());
}
LLStringUtil::format_map_t& LLUIString::getArgs()
{
if (!mArgs)
{
mArgs = new LLStringUtil::format_map_t;
}
return *mArgs;
}

View File

@@ -51,9 +51,9 @@
// llinfos << mMessage.getString() << llendl; // outputs "Welcome Steve to Second Life"
// mMessage.setArg("[USERNAME]", "Joe");
// llinfos << mMessage.getString() << llendl; // outputs "Welcome Joe to Second Life"
// mMessage = "Recepcin a la [SECONDLIFE] [USERNAME]"
// mMessage = "Bienvenido a la [SECONDLIFE] [USERNAME]"
// mMessage.setArg("[SECONDLIFE]", "Segunda Vida");
// llinfos << mMessage.getString() << llendl; // outputs "Recepcin a la Segunda Vida Joe"
// llinfos << mMessage.getString() << llendl; // outputs "Bienvenido a la Segunda Vida Joe"
// Implementation Notes:
// Attempting to have operator[](const std::string& s) return mArgs[s] fails because we have
@@ -64,9 +64,10 @@ class LLUIString
public:
// These methods all perform appropriate argument substitution
// and modify mOrig where appropriate
LLUIString() {}
LLUIString() : mArgs(NULL), mNeedsResult(false), mNeedsWResult(false) {}
LLUIString(const std::string& instring, const LLStringUtil::format_map_t& args);
LLUIString(const std::string& instring) { assign(instring); }
LLUIString(const std::string& instring) : mArgs(NULL) { assign(instring); }
~LLUIString() { delete mArgs; }
void assign(const std::string& instring);
LLUIString& operator=(const std::string& s) { assign(s); return *this; }
@@ -76,34 +77,45 @@ public:
void setArgs(const class LLSD& sd);
void setArg(const std::string& key, const std::string& replacement);
const std::string& getString() const { return mResult; }
operator std::string() const { return mResult; }
const std::string& getString() const { return getUpdatedResult(); }
operator std::string() const { return getUpdatedResult(); }
const LLWString& getWString() const { return mWResult; }
operator LLWString() const { return mWResult; }
const LLWString& getWString() const { return getUpdatedWResult(); }
operator LLWString() const { return getUpdatedWResult(); }
bool empty() const { return mWResult.empty(); }
S32 length() const { return mWResult.size(); }
bool empty() const { return getUpdatedResult().empty(); }
S32 length() const { return getUpdatedWResult().size(); }
void clear();
void clearArgs() { mArgs.clear(); }
// These utuilty functions are included for text editing.
void clearArgs() { if (mArgs) mArgs->clear(); }
// These utility functions are included for text editing.
// They do not affect mOrig and do not perform argument substitution
void truncate(S32 maxchars);
void erase(S32 charidx, S32 len);
void insert(S32 charidx, const LLWString& wchars);
void replace(S32 charidx, llwchar wc);
static const LLStringUtil::format_map_t sNullArgs;
private:
void format();
// something changed, requiring reformatting of strings
void dirty();
std::string& getUpdatedResult() const { if (mNeedsResult) { updateResult(); } return mResult; }
LLWString& getUpdatedWResult() const{ if (mNeedsWResult) { updateWResult(); } return mWResult; }
// do actual work of updating strings (non-inlined)
void updateResult() const;
void updateWResult() const;
LLStringUtil::format_map_t& getArgs();
std::string mOrig;
std::string mResult;
LLWString mWResult; // for displaying
LLStringUtil::format_map_t mArgs;
mutable std::string mResult;
mutable LLWString mWResult; // for displaying
LLStringUtil::format_map_t* mArgs;
// controls lazy evaluation
mutable bool mNeedsResult;
mutable bool mNeedsWResult;
};
#endif // LL_LLUISTRING_H

View File

@@ -885,11 +885,11 @@ return Leave current function or event handler
# Comment
[one_sided_delimiter .8, .3, .15]
// Comment:Non-functional commentary or disabled code
[two_sided_delimiter_esc .8, .3, .15]
[two_sided_delimiter .8, .3, .15]
/* */ Comment:Non-functional commentary or disabled code
# String literals
[two_sided_delimiter_esc 0, .2, 0]
" " String literal
[double_quotation_marks 0, .2, 0]
" String literal
#functions are supplied by the program now

View File

@@ -689,6 +689,7 @@ bool LLAppViewer::init()
// Widget construction depends on LLUI being initialized
LLUI::initClass(&gSavedSettings,
&gSavedPerAccountSettings,
&gSavedSettings,
&gColors,
LLUIImageList::getInstance(),

View File

@@ -160,7 +160,6 @@ void LLFloaterStats::buildStats()
stat_barp->mPerSec = FALSE;
stat_barp = render_statviewp->addStat("New Objs", &(LLViewerStats::getInstance()->mNumNewObjectsStat), "DebugStatModeNewObjs");
stat_barp->setLabel("New Objs");
stat_barp->setUnitLabel("/sec");
stat_barp->mMinBar = 0.f;
stat_barp->mMaxBar = 1000.f;
@@ -169,7 +168,6 @@ void LLFloaterStats::buildStats()
stat_barp->mPerSec = TRUE;
stat_barp = render_statviewp->addStat("Object Cache Hit Rate", &(LLViewerStats::getInstance()->mNumNewObjectsStat), std::string(), false, true);
stat_barp->setLabel("Object Cache Hit Rate");
stat_barp->setUnitLabel("%");
stat_barp->mMinBar = 0.f;
stat_barp->mMaxBar = 100.f;
@@ -186,7 +184,6 @@ void LLFloaterStats::buildStats()
LLStatView *texture_statviewp = render_statviewp->addStatView(params);
stat_barp = texture_statviewp->addStat("Cache Hit Rate", &(LLTextureFetch::sCacheHitRate), std::string(), false, true);
stat_barp->setLabel("Cache Hit Rate");
stat_barp->setUnitLabel("%");
stat_barp->mMinBar = 0.f;
stat_barp->mMaxBar = 100.f;

View File

@@ -597,11 +597,11 @@ void LLScriptEdCore::updateDynamicHelp(BOOL immediate)
}
const LLTextSegment* segment = NULL;
std::vector<const LLTextSegment*> selected_segments;
std::vector<const LLTextSegmentPtr> selected_segments;
mEditor->getSelectedSegments(selected_segments);
// try segments in selection range first
std::vector<const LLTextSegment*>::iterator segment_iter;
std::vector<const LLTextSegmentPtr>::iterator segment_iter;
for (segment_iter = selected_segments.begin(); segment_iter != selected_segments.end(); ++segment_iter)
{
if((*segment_iter)->getToken() && (*segment_iter)->getToken()->getType() == LLKeywordToken::WORD)

View File

@@ -869,7 +869,7 @@ BOOL LLViewerTextEditor::handleHover(S32 x, S32 y, MASK mask)
// Check to see if we're over an HTML-style link
if( !mSegments.empty() )
{
const LLTextSegment* cur_segment = getSegmentAtLocalPos( x, y );
LLTextSegment* cur_segment = getSegmentAtLocalPos( x, y );
if( cur_segment )
{
if(cur_segment->getStyle()->isLink())