summaryrefslogtreecommitdiff
path: root/indra/llui
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llui')
-rwxr-xr-xindra/llui/llfolderview.cpp3
-rw-r--r--indra/llui/llfolderviewitem.cpp30
-rw-r--r--indra/llui/llfolderviewitem.h1
-rwxr-xr-xindra/llui/lllineeditor.cpp1
-rwxr-xr-xindra/llui/llstatgraph.cpp3
-rwxr-xr-xindra/llui/lltextbase.cpp39
-rwxr-xr-xindra/llui/lltextbase.h1
-rwxr-xr-xindra/llui/lltexteditor.cpp65
-rwxr-xr-xindra/llui/llui.h1
9 files changed, 124 insertions, 20 deletions
diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
index cca26f335a..474b545f00 100755
--- a/indra/llui/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -1371,7 +1371,8 @@ BOOL LLFolderView::search(LLFolderViewItem* first_item, const std::string &searc
}
}
- const std::string current_item_label(search_item->getViewModelItem()->getSearchableName());
+ std::string current_item_label(search_item->getViewModelItem()->getSearchableName());
+ LLStringUtil::toUpper(current_item_label);
S32 search_string_length = llmin(upper_case_string.size(), current_item_label.size());
if (!current_item_label.compare(0, search_string_length, upper_case_string))
{
diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index 83254c2840..7c88f8fb9b 100644
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -256,6 +256,24 @@ BOOL LLFolderViewItem::passedFilter(S32 filter_generation)
return getViewModelItem()->passedFilter(filter_generation);
}
+BOOL LLFolderViewItem::isPotentiallyVisible(S32 filter_generation)
+{
+ // Item should be visible if:
+ // 1. item passed current filter
+ // 2. item was updated (gen < 0) but has descendants that passed filter
+ // 3. item was recently updated and was visible before update
+
+ LLFolderViewModelItem* model = getViewModelItem();
+ if (model->getLastFilterGeneration() < 0 && !getFolderViewModel()->getFilter().isModified())
+ {
+ return model->descendantsPassedFilter(filter_generation) || getVisible();
+ }
+ else
+ {
+ return model->passedFilter(filter_generation);
+ }
+}
+
void LLFolderViewItem::refresh()
{
LLFolderViewModelItem& vmi = *getViewModelItem();
@@ -655,7 +673,7 @@ void LLFolderViewItem::drawOpenFolderArrow(const Params& default_params, const L
//
const S32 TOP_PAD = default_params.item_top_pad;
- if (hasVisibleChildren() || getViewModelItem()->hasChildren())
+ if (hasVisibleChildren())
{
LLUIImage* arrow_image = default_params.folder_arrow_image;
gl_draw_scaled_rotated_image(
@@ -968,7 +986,7 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height )
getRoot()->getFolderViewModel()->sort(this);
LL_RECORD_BLOCK_TIME(FTM_ARRANGE);
-
+
// evaluate mHasVisibleChildren
mHasVisibleChildren = false;
if (getViewModelItem()->descendantsPassedFilter())
@@ -979,7 +997,7 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height )
for (items_t::iterator iit = mItems.begin(); iit != mItems.end(); ++iit)
{
LLFolderViewItem* itemp = (*iit);
- found = itemp->passedFilter();
+ found = itemp->isPotentiallyVisible();
if (found)
break;
}
@@ -989,7 +1007,7 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height )
for (folders_t::iterator fit = mFolders.begin(); fit != mFolders.end(); ++fit)
{
LLFolderViewFolder* folderp = (*fit);
- found = folderp->passedFilter();
+ found = folderp->isPotentiallyVisible();
if (found)
break;
}
@@ -1022,7 +1040,7 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height )
for(folders_t::iterator fit = mFolders.begin(); fit != mFolders.end(); ++fit)
{
LLFolderViewFolder* folderp = (*fit);
- folderp->setVisible(folderp->passedFilter()); // passed filter or has descendants that passed filter
+ folderp->setVisible(folderp->isPotentiallyVisible());
if (folderp->getVisible())
{
@@ -1041,7 +1059,7 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height )
iit != mItems.end(); ++iit)
{
LLFolderViewItem* itemp = (*iit);
- itemp->setVisible(itemp->passedFilter());
+ itemp->setVisible(itemp->isPotentiallyVisible());
if (itemp->getVisible())
{
diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h
index a9b0201236..0cd20a0f2d 100644
--- a/indra/llui/llfolderviewitem.h
+++ b/indra/llui/llfolderviewitem.h
@@ -254,6 +254,7 @@ public:
S32 getIndentation() { return mIndentation; }
virtual BOOL passedFilter(S32 filter_generation = -1);
+ virtual BOOL isPotentiallyVisible(S32 filter_generation = -1);
// refresh information from the object being viewed.
virtual void refresh();
diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp
index b09c927782..45f4272aa7 100755
--- a/indra/llui/lllineeditor.cpp
+++ b/indra/llui/lllineeditor.cpp
@@ -254,6 +254,7 @@ void LLLineEditor::onCommit()
setControlValue(getValue());
LLUICtrl::onCommit();
+ resetDirty();
// Selection on commit needs to be turned off when evaluating maths
// expressions, to allow indication of the error position
diff --git a/indra/llui/llstatgraph.cpp b/indra/llui/llstatgraph.cpp
index a44bc18733..98962aff9a 100755
--- a/indra/llui/llstatgraph.cpp
+++ b/indra/llui/llstatgraph.cpp
@@ -44,9 +44,10 @@ LLStatGraph::LLStatGraph(const Params& p)
: LLView(p),
mMin(p.min),
mMax(p.max),
- mPerSec(true),
+ mPerSec(p.per_sec),
mPrecision(p.precision),
mValue(p.value),
+ mUnits(p.units),
mNewStatFloatp(p.stat.count_stat_float)
{
setToolTip(p.name());
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 71db0ac030..2d7062e71d 100755
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -218,7 +218,8 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p)
mParseHighlights(p.parse_highlights),
mBGVisible(p.bg_visible),
mScroller(NULL),
- mStyleDirty(true)
+ mStyleDirty(true),
+ mDrawRightmostCursor(false)
{
if(p.allow_scroll)
{
@@ -1307,14 +1308,14 @@ void LLTextBase::replaceWithSuggestion(U32 index)
if ( (it->first <= (U32)mCursorPos) && (it->second >= (U32)mCursorPos) )
{
deselect();
-
- // Delete the misspelled word
- removeStringNoUndo(it->first, it->second - it->first);
-
// Insert the suggestion in its place
LLWString suggestion = utf8str_to_wstring(mSuggestionList[index]);
insertStringNoUndo(it->first, utf8str_to_wstring(mSuggestionList[index]));
+ // Delete the misspelled word
+ removeStringNoUndo(it->first + (S32)suggestion.length(), it->second - it->first);
+
+
setCursorPos(it->first + (S32)suggestion.length());
break;
@@ -1504,6 +1505,11 @@ void LLTextBase::reflow()
// find and erase line info structs starting at start_index and going to end of document
if (!mLineInfoList.empty())
{
+ if (mDrawRightmostCursor)
+ {
+ start_index--;
+ }
+
// find first element whose end comes after start_index
line_list_t::iterator iter = std::upper_bound(mLineInfoList.begin(), mLineInfoList.end(), start_index, line_end_compare());
line_start_index = iter->mDocIndexStart;
@@ -1692,6 +1698,11 @@ S32 LLTextBase::getLineNumFromDocIndex( S32 doc_index, bool include_wordwrap) co
}
else
{
+ if (mDrawRightmostCursor)
+ {
+ doc_index--;
+ }
+
line_list_t::const_iterator iter = std::upper_bound(mLineInfoList.begin(), mLineInfoList.end(), doc_index, line_end_compare());
if (include_wordwrap)
{
@@ -1720,6 +1731,11 @@ S32 LLTextBase::getLineOffsetFromDocIndex( S32 startpos, bool include_wordwrap)
}
else
{
+ if (mDrawRightmostCursor)
+ {
+ startpos--;
+ }
+
line_list_t::const_iterator iter = std::upper_bound(mLineInfoList.begin(), mLineInfoList.end(), startpos, line_end_compare());
return startpos - iter->mDocIndexStart;
}
@@ -2381,7 +2397,7 @@ S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round,
// binary search for line that starts before local_y
line_list_t::const_iterator line_iter = std::lower_bound(mLineInfoList.begin(), mLineInfoList.end(), doc_y, compare_bottom());
- if (line_iter == mLineInfoList.end())
+ if (!mLineInfoList.size() || line_iter == mLineInfoList.end())
{
return getLength(); // past the end
}
@@ -2440,7 +2456,7 @@ S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round,
}
else if (hit_past_end_of_line && segmentp->getEnd() >= line_iter->mDocIndexEnd)
{
- if (getLineNumFromDocIndex(line_iter->mDocIndexEnd - 1) == line_iter->mLineNum)
+ if (getLineNumFromDocIndex(line_iter->mDocIndexEnd - 1) == line_iter->mLineNum && !mDrawRightmostCursor)
{
// if segment wraps to the next line we should step one char back
// to compensate for the space char between words
@@ -2473,8 +2489,13 @@ LLRect LLTextBase::getDocRectFromDocIndex(S32 pos) const
// clamp pos to valid values
pos = llclamp(pos, 0, mLineInfoList.back().mDocIndexEnd - 1);
- // find line that contains cursor
- line_list_t::const_iterator line_iter = std::upper_bound(mLineInfoList.begin(), mLineInfoList.end(), pos, line_end_compare());
+ S32 corrected_pos = pos;
+ if (mDrawRightmostCursor && pos > 0)
+ {
+ corrected_pos--;
+ }
+
+ line_list_t::const_iterator line_iter = std::upper_bound(mLineInfoList.begin(), mLineInfoList.end(), corrected_pos, line_end_compare());
doc_rect.mLeft = line_iter->mRect.mLeft;
doc_rect.mBottom = line_iter->mRect.mBottom;
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index 738b4d5b8e..9c3bc3ed98 100755
--- a/indra/llui/lltextbase.h
+++ b/indra/llui/lltextbase.h
@@ -618,6 +618,7 @@ protected:
// cursor
S32 mCursorPos; // I-beam is just after the mCursorPos-th character.
+ bool mDrawRightmostCursor; // When cursor is on the rightmost position on the line
S32 mDesiredXPixel; // X pixel position where the user wants the cursor to be
LLFrameTimer mCursorBlinkTimer; // timer that controls cursor blinking
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index 576e8f7600..9219490bf2 100755
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -1124,8 +1124,14 @@ void LLTextEditor::addChar(llwchar wc)
setCursorPos(new_cursor_pos);
}
}
-}
+ if (mCursorPos > 0)
+ {
+ LLRect current_cursor_rect = getDocRectFromDocIndex(mCursorPos);
+ LLRect prev_cursor_rect = getDocRectFromDocIndex(mCursorPos - 1);
+ mDrawRightmostCursor = current_cursor_rect.mBottom < prev_cursor_rect.mBottom;
+ }
+}
void LLTextEditor::addLineBreakChar(BOOL group_together)
{
@@ -1271,6 +1277,12 @@ BOOL LLTextEditor::handleNavigationKey(const KEY key, const MASK mask)
break;
case KEY_HOME:
+ if(mDrawRightmostCursor && mCursorPos > 0)
+ {
+ mCursorPos--;
+ mDrawRightmostCursor = false;
+ }
+
startOfLine();
break;
@@ -1285,6 +1297,23 @@ BOOL LLTextEditor::handleNavigationKey(const KEY key, const MASK mask)
case KEY_END:
endOfLine();
+ {
+ S32 last_line_index = mLineInfoList.size() - 1;
+ if (getLineNumFromDocIndex(mCursorPos, true) < last_line_index)
+ {
+ mDrawRightmostCursor = true;
+ setCursorPos(mCursorPos + 1);
+ }
+ else if (last_line_index > 0) // only for two and more lines
+ {
+ S32 prev_line_width = mLineInfoList[last_line_index - 1].mRect.getWidth();
+ S32 last_line_width = mLineInfoList[last_line_index].mRect.getWidth();
+ if (prev_line_width <= last_line_width)
+ {
+ mDrawRightmostCursor = true;
+ }
+ }
+ }
break;
case KEY_LEFT:
@@ -1296,7 +1325,18 @@ BOOL LLTextEditor::handleNavigationKey(const KEY key, const MASK mask)
{
if( 0 < mCursorPos )
{
- setCursorPos(mCursorPos - 1);
+ LLRect current_cursor_rect = getDocRectFromDocIndex(mCursorPos);
+ LLRect next_cursor_rect = getDocRectFromDocIndex(mCursorPos - 1);
+
+ if (current_cursor_rect.mBottom < next_cursor_rect.mBottom)
+ {
+ mDrawRightmostCursor = true;
+ }
+ else
+ {
+ mDrawRightmostCursor = false;
+ setCursorPos(mCursorPos - 1);
+ }
}
else
{
@@ -1314,7 +1354,26 @@ BOOL LLTextEditor::handleNavigationKey(const KEY key, const MASK mask)
{
if( mCursorPos < getLength() )
{
- setCursorPos(mCursorPos + 1);
+ LLRect current_cursor_rect = getDocRectFromDocIndex(mCursorPos);
+ LLRect next_cursor_rect = getDocRectFromDocIndex(mCursorPos + 1);
+
+ if (current_cursor_rect.mBottom > next_cursor_rect.mBottom)
+ {
+ if (mDrawRightmostCursor)
+ {
+ mDrawRightmostCursor = false;
+ }
+ else
+ {
+ mDrawRightmostCursor = true;
+ setCursorPos(mCursorPos + 1);
+ }
+ }
+ else
+ {
+ mDrawRightmostCursor = false;
+ setCursorPos(mCursorPos + 1);
+ }
}
else
{
diff --git a/indra/llui/llui.h b/indra/llui/llui.h
index b162f25887..c727f75c4f 100755
--- a/indra/llui/llui.h
+++ b/indra/llui/llui.h
@@ -86,6 +86,7 @@ enum EAcceptance
{
ACCEPT_POSTPONED, // we are asynchronously determining acceptance
ACCEPT_NO, // Uninformative, general purpose denial.
+ ACCEPT_NO_CUSTOM, // Denial with custom message.
ACCEPT_NO_LOCKED, // Operation would be valid, but permissions are set to disallow it.
ACCEPT_YES_COPY_SINGLE, // We'll take a copy of a single item
ACCEPT_YES_SINGLE, // Accepted. OK to drag and drop single item here.