viewer#2411 Use font buffer in text segments
parent
49abe2c8bc
commit
238a2a64b3
|
|
@ -42,6 +42,8 @@ LLFontVertexBuffer::~LLFontVertexBuffer()
|
|||
|
||||
void LLFontVertexBuffer::reset()
|
||||
{
|
||||
// Todo: some form of debug only frequecy check&assert to see if this is happening too often.
|
||||
// Regenerating this list is expensive
|
||||
mBufferList.clear();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -948,7 +948,6 @@ S32 LLTextBase::insertStringNoUndo(S32 pos, const LLWString &wstr, LLTextBase::s
|
|||
|
||||
S32 LLTextBase::removeStringNoUndo(S32 pos, S32 length)
|
||||
{
|
||||
|
||||
beforeValueChange();
|
||||
segment_set_t::iterator seg_iter = getSegIterContaining(pos);
|
||||
while(seg_iter != mSegments.end())
|
||||
|
|
@ -1325,6 +1324,7 @@ void LLTextBase::reshape(S32 width, S32 height, bool called_from_parent)
|
|||
//virtual
|
||||
void LLTextBase::draw()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;
|
||||
// reflow if needed, on demand
|
||||
reflow();
|
||||
|
||||
|
|
@ -2586,6 +2586,11 @@ const LLWString& LLTextBase::getWText() const
|
|||
return getViewModel()->getDisplay();
|
||||
}
|
||||
|
||||
S32 LLTextBase::getTextGeneration() const
|
||||
{
|
||||
return getViewModel()->getDisplayGeneration();
|
||||
}
|
||||
|
||||
// If round is true, if the position is on the right half of a character, the cursor
|
||||
// will be put to its right. If round is false, the cursor will always be put to the
|
||||
// character's left.
|
||||
|
|
@ -3280,7 +3285,8 @@ LLNormalTextSegment::LLNormalTextSegment( LLStyleConstSP style, S32 start, S32 e
|
|||
: LLTextSegment(start, end),
|
||||
mStyle( style ),
|
||||
mToken(NULL),
|
||||
mEditor(editor)
|
||||
mEditor(editor),
|
||||
mLastGeneration(-1)
|
||||
{
|
||||
mFontHeight = mStyle->getFont()->getLineHeight();
|
||||
|
||||
|
|
@ -3294,7 +3300,8 @@ LLNormalTextSegment::LLNormalTextSegment( LLStyleConstSP style, S32 start, S32 e
|
|||
LLNormalTextSegment::LLNormalTextSegment( const LLUIColor& color, S32 start, S32 end, LLTextBase& editor, bool is_visible)
|
||||
: LLTextSegment(start, end),
|
||||
mToken(NULL),
|
||||
mEditor(editor)
|
||||
mEditor(editor),
|
||||
mLastGeneration(-1)
|
||||
{
|
||||
mStyle = new LLStyle(LLStyle::Params().visible(is_visible).color(color));
|
||||
|
||||
|
|
@ -3313,22 +3320,38 @@ F32 LLNormalTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selec
|
|||
{
|
||||
return drawClippedSegment( getStart() + start, getStart() + end, selection_start, selection_end, draw_rect);
|
||||
}
|
||||
else
|
||||
{
|
||||
mFontBufferPreSelection.reset();
|
||||
mFontBufferSelection.reset();
|
||||
mFontBufferPostSelection.reset();
|
||||
}
|
||||
return draw_rect.mLeft;
|
||||
}
|
||||
|
||||
// Draws a single text segment, reversing the color for selection if needed.
|
||||
F32 LLNormalTextSegment::drawClippedSegment(S32 seg_start, S32 seg_end, S32 selection_start, S32 selection_end, LLRectf rect)
|
||||
{
|
||||
F32 alpha = LLViewDrawContext::getCurrentContext().mAlpha;
|
||||
|
||||
const LLWString &text = getWText();
|
||||
|
||||
F32 right_x = rect.mLeft;
|
||||
if (!mStyle->isVisible())
|
||||
{
|
||||
return right_x;
|
||||
}
|
||||
|
||||
F32 alpha = LLViewDrawContext::getCurrentContext().mAlpha;
|
||||
|
||||
const LLWString& text = getWText();
|
||||
S32 text_gen = mEditor.getTextGeneration();
|
||||
|
||||
if (text_gen != mLastGeneration)
|
||||
{
|
||||
mLastGeneration = text_gen;
|
||||
|
||||
mFontBufferPreSelection.reset();
|
||||
mFontBufferSelection.reset();
|
||||
mFontBufferPostSelection.reset();
|
||||
}
|
||||
|
||||
const LLFontGL* font = mStyle->getFont();
|
||||
|
||||
LLColor4 color = (mEditor.getReadOnly() ? mStyle->getReadOnlyColor() : mStyle->getColor()) % (alpha * mStyle->getAlpha());
|
||||
|
|
@ -3339,7 +3362,8 @@ F32 LLNormalTextSegment::drawClippedSegment(S32 seg_start, S32 seg_end, S32 sele
|
|||
S32 start = seg_start;
|
||||
S32 end = llmin( selection_start, seg_end );
|
||||
S32 length = end - start;
|
||||
font->render(text, start,
|
||||
mFontBufferPreSelection.render(font,
|
||||
text, start,
|
||||
rect,
|
||||
color,
|
||||
LLFontGL::LEFT, mEditor.mTextVAlign,
|
||||
|
|
@ -3359,7 +3383,8 @@ F32 LLNormalTextSegment::drawClippedSegment(S32 seg_start, S32 seg_end, S32 sele
|
|||
S32 end = llmin( selection_end, seg_end );
|
||||
S32 length = end - start;
|
||||
|
||||
font->render(text, start,
|
||||
mFontBufferSelection.render(font,
|
||||
text, start,
|
||||
rect,
|
||||
mStyle->getSelectedColor().get(),
|
||||
LLFontGL::LEFT, mEditor.mTextVAlign,
|
||||
|
|
@ -3377,7 +3402,8 @@ F32 LLNormalTextSegment::drawClippedSegment(S32 seg_start, S32 seg_end, S32 sele
|
|||
S32 start = llmax( selection_end, seg_start );
|
||||
S32 end = seg_end;
|
||||
S32 length = end - start;
|
||||
font->render(text, start,
|
||||
mFontBufferPostSelection.render(font,
|
||||
text, start,
|
||||
rect,
|
||||
color,
|
||||
LLFontGL::LEFT, mEditor.mTextVAlign,
|
||||
|
|
@ -3573,6 +3599,15 @@ S32 LLNormalTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 lin
|
|||
return num_chars;
|
||||
}
|
||||
|
||||
void LLNormalTextSegment::updateLayout(const class LLTextBase& editor)
|
||||
{
|
||||
LLTextSegment::updateLayout(editor);
|
||||
|
||||
mFontBufferPreSelection.reset();
|
||||
mFontBufferSelection.reset();
|
||||
mFontBufferPostSelection.reset();
|
||||
}
|
||||
|
||||
void LLNormalTextSegment::dump() const
|
||||
{
|
||||
LL_INFOS() << "Segment [" <<
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#include "v4color.h"
|
||||
#include "lleditmenuhandler.h"
|
||||
#include "llfontvertexbuffer.h"
|
||||
#include "llspellcheckmenuhandler.h"
|
||||
#include "llstyle.h"
|
||||
#include "llkeywords.h"
|
||||
|
|
@ -131,6 +132,7 @@ public:
|
|||
/*virtual*/ bool getDimensionsF32(S32 first_char, S32 num_chars, F32& width, S32& height) const;
|
||||
/*virtual*/ S32 getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const;
|
||||
/*virtual*/ S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars, S32 line_ind) const;
|
||||
/*virtual*/ void updateLayout(const class LLTextBase& editor);
|
||||
/*virtual*/ F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect);
|
||||
/*virtual*/ bool canEdit() const { return true; }
|
||||
/*virtual*/ const LLUIColor& getColor() const { return mStyle->getColor(); }
|
||||
|
|
@ -161,6 +163,12 @@ protected:
|
|||
LLKeywordToken* mToken;
|
||||
std::string mTooltip;
|
||||
boost::signals2::connection mImageLoadedConnection;
|
||||
|
||||
// font rendering
|
||||
LLFontVertexBuffer mFontBufferPreSelection;
|
||||
LLFontVertexBuffer mFontBufferSelection;
|
||||
LLFontVertexBuffer mFontBufferPostSelection;
|
||||
S32 mLastGeneration = -1;
|
||||
};
|
||||
|
||||
// This text segment is the same as LLNormalTextSegment, the only difference
|
||||
|
|
@ -432,6 +440,7 @@ public:
|
|||
// wide-char versions
|
||||
void setWText(const LLWString& text);
|
||||
const LLWString& getWText() const;
|
||||
S32 getTextGeneration() const;
|
||||
|
||||
void appendText(const std::string &new_text, bool prepend_newline, const LLStyle::Params& input_params = LLStyle::Params());
|
||||
|
||||
|
|
|
|||
|
|
@ -82,11 +82,20 @@ void LLTextViewModel::setValue(const LLSD& value)
|
|||
// approximate LLSD storage usage
|
||||
LLViewModel::setValue(value);
|
||||
mDisplay = utf8str_to_wstring(mStringValue = value.asString());
|
||||
mDisplayGeneration++;
|
||||
|
||||
// mDisplay and mValue agree
|
||||
mUpdateFromDisplay = false;
|
||||
}
|
||||
|
||||
LLWString& LLTextViewModel::getEditableDisplay()
|
||||
{
|
||||
mDirty = true;
|
||||
mDisplayGeneration++;
|
||||
mUpdateFromDisplay = true;
|
||||
return mDisplay;
|
||||
}
|
||||
|
||||
void LLTextViewModel::setDisplay(const LLWString& value)
|
||||
{
|
||||
// This is the strange way to alter the value. Normally we'd setValue()
|
||||
|
|
@ -94,6 +103,7 @@ void LLTextViewModel::setDisplay(const LLWString& value)
|
|||
// value. But a text editor might want to edit the display string
|
||||
// directly, then convert back to UTF8 on commit.
|
||||
mDisplay = value;
|
||||
mDisplayGeneration++;
|
||||
mDirty = true;
|
||||
// Don't immediately convert to UTF8 -- do it lazily -- we expect many
|
||||
// more setDisplay() calls than getValue() calls. Just flag that it needs
|
||||
|
|
|
|||
|
|
@ -105,7 +105,8 @@ public:
|
|||
// New functions
|
||||
/// Get the stored value in string form
|
||||
const LLWString& getDisplay() const { return mDisplay; }
|
||||
LLWString& getEditableDisplay() { mDirty = true; mUpdateFromDisplay = true; return mDisplay; }
|
||||
S32 getDisplayGeneration() const { return mDisplayGeneration; }
|
||||
LLWString& getEditableDisplay();
|
||||
|
||||
/**
|
||||
* Set the display string directly (see LLTextEditor). What the user is
|
||||
|
|
@ -120,6 +121,7 @@ private:
|
|||
/// To avoid converting every widget's stored value from LLSD to LLWString
|
||||
/// every frame, cache the converted value
|
||||
LLWString mDisplay;
|
||||
S32 mDisplayGeneration = -1;
|
||||
|
||||
/// As the user edits individual characters (setDisplay()), defer
|
||||
/// LLWString-to-UTF8 conversions until s/he's done.
|
||||
|
|
|
|||
|
|
@ -963,59 +963,87 @@ void LLPanelMainInventory::draw()
|
|||
|
||||
void LLPanelMainInventory::updateItemcountText()
|
||||
{
|
||||
if(mItemCount != gInventory.getItemCount())
|
||||
bool update = false;
|
||||
if (mSingleFolderMode)
|
||||
{
|
||||
mItemCount = gInventory.getItemCount();
|
||||
mItemCountString = "";
|
||||
LLLocale locale(LLLocale::USER_LOCALE);
|
||||
LLResMgr::getInstance()->getIntegerString(mItemCountString, mItemCount);
|
||||
}
|
||||
LLInventoryModel::cat_array_t* cats;
|
||||
LLInventoryModel::item_array_t* items;
|
||||
|
||||
if(mCategoryCount != gInventory.getCategoryCount())
|
||||
{
|
||||
mCategoryCount = gInventory.getCategoryCount();
|
||||
mCategoryCountString = "";
|
||||
LLLocale locale(LLLocale::USER_LOCALE);
|
||||
LLResMgr::getInstance()->getIntegerString(mCategoryCountString, mCategoryCount);
|
||||
}
|
||||
gInventory.getDirectDescendentsOf(getCurrentSFVRoot(), cats, items);
|
||||
S32 item_count = items ? (S32)items->size() : 0;
|
||||
S32 cat_count = cats ? (S32)cats->size() : 0;
|
||||
|
||||
LLStringUtil::format_map_t string_args;
|
||||
string_args["[ITEM_COUNT]"] = mItemCountString;
|
||||
string_args["[CATEGORY_COUNT]"] = mCategoryCountString;
|
||||
string_args["[FILTER]"] = getFilterText();
|
||||
|
||||
std::string text = "";
|
||||
|
||||
if (LLInventoryModelBackgroundFetch::instance().folderFetchActive())
|
||||
{
|
||||
text = getString("ItemcountFetching", string_args);
|
||||
}
|
||||
else if (LLInventoryModelBackgroundFetch::instance().isEverythingFetched())
|
||||
{
|
||||
text = getString("ItemcountCompleted", string_args);
|
||||
if (mItemCount != item_count)
|
||||
{
|
||||
mItemCount = item_count;
|
||||
update = true;
|
||||
}
|
||||
if (mCategoryCount != cat_count)
|
||||
{
|
||||
mCategoryCount = cat_count;
|
||||
update = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
text = getString("ItemcountUnknown", string_args);
|
||||
}
|
||||
|
||||
if (mSingleFolderMode)
|
||||
{
|
||||
LLInventoryModel::cat_array_t *cats;
|
||||
LLInventoryModel::item_array_t *items;
|
||||
|
||||
gInventory.getDirectDescendentsOf(getCurrentSFVRoot(), cats, items);
|
||||
|
||||
if (items && cats)
|
||||
if (mItemCount != gInventory.getItemCount())
|
||||
{
|
||||
string_args["[ITEM_COUNT]"] = llformat("%d", items->size());
|
||||
string_args["[CATEGORY_COUNT]"] = llformat("%d", cats->size());
|
||||
text = getString("ItemcountCompleted", string_args);
|
||||
mItemCount = gInventory.getItemCount();
|
||||
update = true;
|
||||
}
|
||||
|
||||
if (mCategoryCount != gInventory.getCategoryCount())
|
||||
{
|
||||
mCategoryCount = gInventory.getCategoryCount();
|
||||
update = true;
|
||||
}
|
||||
}
|
||||
|
||||
mCounterCtrl->setValue(text);
|
||||
mCounterCtrl->setToolTip(text);
|
||||
if (mLastFilterText != getFilterText())
|
||||
{
|
||||
mLastFilterText = getFilterText();
|
||||
update = true;
|
||||
}
|
||||
|
||||
if (update)
|
||||
{
|
||||
mItemCountString = "";
|
||||
LLLocale locale(LLLocale::USER_LOCALE);
|
||||
LLResMgr::getInstance()->getIntegerString(mItemCountString, mItemCount);
|
||||
|
||||
mCategoryCountString = "";
|
||||
LLResMgr::getInstance()->getIntegerString(mCategoryCountString, mCategoryCount);
|
||||
|
||||
LLStringUtil::format_map_t string_args;
|
||||
string_args["[ITEM_COUNT]"] = mItemCountString;
|
||||
string_args["[CATEGORY_COUNT]"] = mCategoryCountString;
|
||||
string_args["[FILTER]"] = mLastFilterText;
|
||||
|
||||
std::string text = "";
|
||||
|
||||
if (mSingleFolderMode)
|
||||
{
|
||||
text = getString("ItemcountCompleted", string_args);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (LLInventoryModelBackgroundFetch::instance().folderFetchActive())
|
||||
{
|
||||
text = getString("ItemcountFetching", string_args);
|
||||
}
|
||||
else if (LLInventoryModelBackgroundFetch::instance().isEverythingFetched())
|
||||
{
|
||||
text = getString("ItemcountCompleted", string_args);
|
||||
}
|
||||
else
|
||||
{
|
||||
text = getString("ItemcountUnknown", string_args);
|
||||
}
|
||||
}
|
||||
|
||||
mCounterCtrl->setValue(text);
|
||||
mCounterCtrl->setToolTip(text);
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelMainInventory::onFocusReceived()
|
||||
|
|
|
|||
|
|
@ -196,9 +196,10 @@ private:
|
|||
LLSaveFolderState* mSavedFolderState;
|
||||
std::string mFilterText;
|
||||
std::string mFilterSubString;
|
||||
S32 mItemCount;
|
||||
S32 mItemCount = 0;
|
||||
std::string mLastFilterText;
|
||||
std::string mItemCountString;
|
||||
S32 mCategoryCount;
|
||||
S32 mCategoryCount = 0;
|
||||
std::string mCategoryCountString;
|
||||
LLComboBox* mSearchTypeCombo;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue