From e72c803df01e95d4ce73c0b207b1da9ea89eb144 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Sat, 9 Jul 2022 00:19:14 +0300 Subject: SL-17741 Paste is not disabled when copying 'no copy' items We should allow to copy 'no copy' items for the ability to paste them as links, but regular 'paste' should be disabled in such case Also fixed library items enabling 'paste as link', we can not link library items. --- indra/llui/llfolderviewmodel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llui') diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h index 093e213be3..618169a8fe 100644 --- a/indra/llui/llfolderviewmodel.h +++ b/indra/llui/llfolderviewmodel.h @@ -172,7 +172,7 @@ public: virtual BOOL removeItem() = 0; virtual void removeBatch(std::vector& batch) = 0; - virtual BOOL isItemCopyable() const = 0; + virtual bool isItemCopyable(bool can_copy_as_link = true) const = 0; virtual BOOL copyToClipboard() const = 0; virtual BOOL cutToClipboard() = 0; virtual bool isCutToClipboard() { return false; }; -- cgit v1.2.3 From 477f173ad55ca145ff027cb54f86c6553cf6f62d Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 19 Jul 2022 01:25:30 +0300 Subject: SL-16745 Some checkboxes are truncated after changing 'UI size' --- indra/llui/llcheckboxctrl.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llcheckboxctrl.cpp b/indra/llui/llcheckboxctrl.cpp index 08da599ef2..362fe0c19e 100644 --- a/indra/llui/llcheckboxctrl.cpp +++ b/indra/llui/llcheckboxctrl.cpp @@ -203,11 +203,9 @@ void LLCheckBoxCtrl::reshape(S32 width, S32 height, BOOL called_from_parent) // it will work fine in case of decrease of space, but if we get more space or text // becomes longer, label will fail to grow so reinit label's dimentions. - static LLUICachedControl llcheckboxctrl_hpad("UICheckboxctrlHPad", 0); LLRect label_rect = mLabel->getRect(); - S32 new_width = getRect().getWidth() - label_rect.mLeft - llcheckboxctrl_hpad; - label_rect.mRight = label_rect.mLeft + new_width; - mLabel->setRect(label_rect); + S32 new_width = rect.getWidth() - label_rect.mLeft; + mLabel->reshape(new_width, label_rect.getHeight(), TRUE); S32 label_top = label_rect.mTop; mLabel->reshapeToFitText(TRUE); -- cgit v1.2.3 From 4c3f343799ca4be4b618dca8cf13a86e8941fb44 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 26 Jul 2022 19:40:10 +0300 Subject: SL-17045 LSL editor cursor position desynchronization 1. Fixed cursor position calculations 2. Fixed selection rect calculation --- indra/llui/lltextbase.cpp | 197 ++++++++++++++++++++++++++-------------------- indra/llui/lltextbase.h | 2 + 2 files changed, 112 insertions(+), 87 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 0dc99fdde6..44546c7897 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -353,95 +353,113 @@ void LLTextBase::onValueChange(S32 start, S32 end) { } - -// Draws the black box behind the selected text -void LLTextBase::drawSelectionBackground() +std::vector LLTextBase::getSelctionRects() { - // Draw selection even if we don't have keyboard focus for search/replace - if( hasSelection() && !mLineInfoList.empty()) - { - std::vector selection_rects; + // Nor supposed to be called without selection + llassert(hasSelection()); + llassert(!mLineInfoList.empty()); - S32 selection_left = llmin( mSelectionStart, mSelectionEnd ); - S32 selection_right = llmax( mSelectionStart, mSelectionEnd ); + std::vector selection_rects; - // Skip through the lines we aren't drawing. - LLRect content_display_rect = getVisibleDocumentRect(); + S32 selection_left = llmin(mSelectionStart, mSelectionEnd); + S32 selection_right = llmax(mSelectionStart, mSelectionEnd); - // binary search for line that starts before top of visible buffer - line_list_t::const_iterator line_iter = std::lower_bound(mLineInfoList.begin(), mLineInfoList.end(), content_display_rect.mTop, compare_bottom()); - line_list_t::const_iterator end_iter = std::upper_bound(mLineInfoList.begin(), mLineInfoList.end(), content_display_rect.mBottom, compare_top()); + // Skip through the lines we aren't drawing. + LLRect content_display_rect = getVisibleDocumentRect(); - bool done = false; + // binary search for line that starts before top of visible buffer + line_list_t::const_iterator line_iter = std::lower_bound(mLineInfoList.begin(), mLineInfoList.end(), content_display_rect.mTop, compare_bottom()); + line_list_t::const_iterator end_iter = std::upper_bound(mLineInfoList.begin(), mLineInfoList.end(), content_display_rect.mBottom, compare_top()); - // Find the coordinates of the selected area - for (;line_iter != end_iter && !done; ++line_iter) - { - // is selection visible on this line? - if (line_iter->mDocIndexEnd > selection_left && line_iter->mDocIndexStart < selection_right) - { - segment_set_t::iterator segment_iter; - S32 segment_offset; - getSegmentAndOffset(line_iter->mDocIndexStart, &segment_iter, &segment_offset); - - LLRect selection_rect; - selection_rect.mLeft = line_iter->mRect.mLeft; - selection_rect.mRight = line_iter->mRect.mLeft; - selection_rect.mBottom = line_iter->mRect.mBottom; - selection_rect.mTop = line_iter->mRect.mTop; - - for(;segment_iter != mSegments.end(); ++segment_iter, segment_offset = 0) - { - LLTextSegmentPtr segmentp = *segment_iter; + bool done = false; - S32 segment_line_start = segmentp->getStart() + segment_offset; - S32 segment_line_end = llmin(segmentp->getEnd(), line_iter->mDocIndexEnd); + // Find the coordinates of the selected area + for (; line_iter != end_iter && !done; ++line_iter) + { + // is selection visible on this line? + if (line_iter->mDocIndexEnd > selection_left && line_iter->mDocIndexStart < selection_right) + { + segment_set_t::iterator segment_iter; + S32 segment_offset; + getSegmentAndOffset(line_iter->mDocIndexStart, &segment_iter, &segment_offset); - if (segment_line_start > segment_line_end) break; + // Use F32 otherwise a string of multiple segments + // will accumulate a large error + F32 left_precise = line_iter->mRect.mLeft; + F32 right_precise = line_iter->mRect.mLeft; - S32 segment_width = 0; - S32 segment_height = 0; + for (; segment_iter != mSegments.end(); ++segment_iter, segment_offset = 0) + { + LLTextSegmentPtr segmentp = *segment_iter; + + S32 segment_line_start = segmentp->getStart() + segment_offset; + S32 segment_line_end = llmin(segmentp->getEnd(), line_iter->mDocIndexEnd); + + if (segment_line_start > segment_line_end) break; + + F32 segment_width = 0; + S32 segment_height = 0; + + // if selection after beginning of segment + if (selection_left >= segment_line_start) + { + S32 num_chars = llmin(selection_left, segment_line_end) - segment_line_start; + segmentp->getDimensionsF32(segment_offset, num_chars, segment_width, segment_height); + left_precise += segment_width; + } + + // if selection_right == segment_line_end then that means we are the first character of the next segment + // or first character of the next line, in either case we want to add the length of the current segment + // to the selection rectangle and continue. + // if selection right > segment_line_end then selection spans end of current segment... + if (selection_right >= segment_line_end) + { + // extend selection slightly beyond end of line + // to indicate selection of newline character (use "n" character to determine width) + S32 num_chars = segment_line_end - segment_line_start; + segmentp->getDimensionsF32(segment_offset, num_chars, segment_width, segment_height); + right_precise += segment_width; + } + // else if selection ends on current segment... + else + { + S32 num_chars = selection_right - segment_line_start; + segmentp->getDimensionsF32(segment_offset, num_chars, segment_width, segment_height); + right_precise += segment_width; + + break; + } + } - // if selection after beginning of segment - if(selection_left >= segment_line_start) - { - S32 num_chars = llmin(selection_left, segment_line_end) - segment_line_start; - segmentp->getDimensions(segment_offset, num_chars, segment_width, segment_height); - selection_rect.mLeft += segment_width; - } + LLRect selection_rect; + selection_rect.mLeft = left_precise; + selection_rect.mRight = right_precise; + selection_rect.mBottom = line_iter->mRect.mBottom; + selection_rect.mTop = line_iter->mRect.mTop; - // if selection_right == segment_line_end then that means we are the first character of the next segment - // or first character of the next line, in either case we want to add the length of the current segment - // to the selection rectangle and continue. - // if selection right > segment_line_end then selection spans end of current segment... - if (selection_right >= segment_line_end) - { - // extend selection slightly beyond end of line - // to indicate selection of newline character (use "n" character to determine width) - S32 num_chars = segment_line_end - segment_line_start; - segmentp->getDimensions(segment_offset, num_chars, segment_width, segment_height); - selection_rect.mRight += segment_width; - } - // else if selection ends on current segment... - else - { - S32 num_chars = selection_right - segment_line_start; - segmentp->getDimensions(segment_offset, num_chars, segment_width, segment_height); - selection_rect.mRight += segment_width; + selection_rects.push_back(selection_rect); + } + } - break; - } - } - selection_rects.push_back(selection_rect); - } - } + return selection_rects; +} + +// Draws the black box behind the selected text +void LLTextBase::drawSelectionBackground() +{ + // Draw selection even if we don't have keyboard focus for search/replace + if (hasSelection() && !mLineInfoList.empty()) + { + std::vector selection_rects = getSelctionRects(); // Draw the selection box (we're using a box instead of reversing the colors on the selected text). gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); const LLColor4& color = mSelectedBGColor; F32 alpha = hasFocus() ? 0.7f : 0.3f; alpha *= getDrawContext().mAlpha; + LLColor4 selection_color(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], alpha); + LLRect content_display_rect = getVisibleDocumentRect(); for (std::vector::iterator rect_it = selection_rects.begin(); rect_it != selection_rects.end(); @@ -2508,7 +2526,7 @@ S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round, } S32 pos = getLength(); - S32 start_x = line_iter->mRect.mLeft + doc_rect.mLeft; + F32 start_x = line_iter->mRect.mLeft + doc_rect.mLeft; segment_set_t::iterator line_seg_iter; S32 line_seg_offset; @@ -2520,8 +2538,9 @@ S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round, S32 segment_line_start = segmentp->getStart() + line_seg_offset; S32 segment_line_length = llmin(segmentp->getEnd(), line_iter->mDocIndexEnd) - segment_line_start; - S32 text_width, text_height; - bool newline = segmentp->getDimensions(line_seg_offset, segment_line_length, text_width, text_height); + F32 text_width; + S32 text_height; + bool newline = segmentp->getDimensionsF32(line_seg_offset, segment_line_length, text_width, text_height); if(newline) { @@ -2541,8 +2560,9 @@ S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round, S32 offset; if (!segmentp->canEdit()) { - S32 segment_width, segment_height; - segmentp->getDimensions(0, segmentp->getEnd() - segmentp->getStart(), segment_width, segment_height); + F32 segment_width; + S32 segment_height; + segmentp->getDimensionsF32(0, segmentp->getEnd() - segmentp->getStart(), segment_width, segment_height); if (round && local_x - start_x > segment_width / 2) { offset = segment_line_length; @@ -2589,17 +2609,11 @@ LLRect LLTextBase::getDocRectFromDocIndex(S32 pos) const return LLRect(); } - LLRect doc_rect; - // clamp pos to valid values pos = llclamp(pos, 0, mLineInfoList.back().mDocIndexEnd - 1); line_list_t::const_iterator line_iter = std::upper_bound(mLineInfoList.begin(), mLineInfoList.end(), pos, line_end_compare()); - doc_rect.mLeft = line_iter->mRect.mLeft; - doc_rect.mBottom = line_iter->mRect.mBottom; - doc_rect.mTop = line_iter->mRect.mTop; - segment_set_t::iterator line_seg_iter; S32 line_seg_offset; segment_set_t::iterator cursor_seg_iter; @@ -2607,6 +2621,8 @@ LLRect LLTextBase::getDocRectFromDocIndex(S32 pos) const getSegmentAndOffset(line_iter->mDocIndexStart, &line_seg_iter, &line_seg_offset); getSegmentAndOffset(pos, &cursor_seg_iter, &cursor_seg_offset); + F32 doc_left_precise = line_iter->mRect.mLeft; + while(line_seg_iter != mSegments.end()) { const LLTextSegmentPtr segmentp = *line_seg_iter; @@ -2614,18 +2630,20 @@ LLRect LLTextBase::getDocRectFromDocIndex(S32 pos) const if (line_seg_iter == cursor_seg_iter) { // cursor advanced to right based on difference in offset of cursor to start of line - S32 segment_width, segment_height; - segmentp->getDimensions(line_seg_offset, cursor_seg_offset - line_seg_offset, segment_width, segment_height); - doc_rect.mLeft += segment_width; + F32 segment_width; + S32 segment_height; + segmentp->getDimensionsF32(line_seg_offset, cursor_seg_offset - line_seg_offset, segment_width, segment_height); + doc_left_precise += segment_width; break; } else { // add remainder of current text segment to cursor position - S32 segment_width, segment_height; - segmentp->getDimensions(line_seg_offset, (segmentp->getEnd() - segmentp->getStart()) - line_seg_offset, segment_width, segment_height); - doc_rect.mLeft += segment_width; + F32 segment_width; + S32 segment_height; + segmentp->getDimensionsF32(line_seg_offset, (segmentp->getEnd() - segmentp->getStart()) - line_seg_offset, segment_width, segment_height); + doc_left_precise += segment_width; // offset will be 0 for all segments after the first line_seg_offset = 0; // go to next text segment on this line @@ -2633,6 +2651,11 @@ LLRect LLTextBase::getDocRectFromDocIndex(S32 pos) const } } + LLRect doc_rect; + doc_rect.mLeft = doc_left_precise; + doc_rect.mBottom = line_iter->mRect.mBottom; + doc_rect.mTop = line_iter->mRect.mTop; + // set rect to 0 width doc_rect.mRight = doc_rect.mLeft; diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index a4e83b42b4..82844200cf 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -635,6 +635,8 @@ protected: return mLabel.getString() + getToolTip(); } + std::vector getSelctionRects(); + protected: // text segmentation and flow segment_set_t mSegments; -- cgit v1.2.3 From 3f3735c1f810f6a6c5635a5895689f5a366571de Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Tue, 2 Aug 2022 14:59:04 +0300 Subject: SL-17851 Highlight matching notifications when using Search Box in Preference --- indra/llui/llscrolllistctrl.cpp | 39 +++++++++++++++++++++++++++++++++++++++ indra/llui/llscrolllistctrl.h | 2 ++ 2 files changed, 41 insertions(+) (limited to 'indra/llui') diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index 11b0eb9f80..f3211b23c9 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -3307,3 +3307,42 @@ boost::signals2::connection LLScrollListCtrl::setIsFriendCallback(const is_frien } return mIsFriendSignal->connect(cb); } + +bool LLScrollListCtrl::highlightMatchingItems(const std::string& filter_str) +{ + if (filter_str == "" || filter_str == " ") + { + clearHighlightedItems(); + return false; + } + + bool res = false; + + setHighlightedColor(LLUIColorTable::instance().getColor("SearchableControlHighlightColor", LLColor4::red)); + + std::string filter_str_lc(filter_str); + LLStringUtil::toLower(filter_str_lc); + + std::vector data = getAllData(); + std::vector::iterator iter = data.begin(); + while (iter != data.end()) + { + LLScrollListCell* cell = (*iter)->getColumn(0); + if (cell) + { + std::string value = cell->getValue().asString(); + LLStringUtil::toLower(value); + if (value.find(filter_str_lc) == std::string::npos) + { + (*iter)->setHighlighted(false); + } + else + { + (*iter)->setHighlighted(true); + res = true; + } + } + iter++; + } + return res; +} diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index 08134bbfc8..af553843bd 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -410,6 +410,8 @@ public: void setNeedsSort(bool val = true) { mSorted = !val; } void dirtyColumns(); // some operation has potentially affected column layout or ordering + bool highlightMatchingItems(const std::string& filter_str); + boost::signals2::connection setSortCallback(sort_signal_t::slot_type cb ) { if (!mSortCallback) mSortCallback = new sort_signal_t(); -- cgit v1.2.3 From 1f53d3abbf612531dd10672127552e189255da01 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 14 Jul 2022 22:39:23 +0300 Subject: SL-17628 Added attachments can be moved past limit #2 --- indra/llui/llspinctrl.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llspinctrl.cpp b/indra/llui/llspinctrl.cpp index ef7c8ec012..c411aafb1a 100644 --- a/indra/llui/llspinctrl.cpp +++ b/indra/llui/llspinctrl.cpp @@ -101,7 +101,10 @@ LLSpinCtrl::LLSpinCtrl(const LLSpinCtrl::Params& p) // Spin buttons LLButton::Params up_button_params(p.up_button); up_button_params.rect = LLRect(btn_left, getRect().getHeight(), btn_right, getRect().getHeight() - spinctrl_btn_height); - up_button_params.click_callback.function(boost::bind(&LLSpinCtrl::onUpBtn, this, _2)); + // Click callback starts within the button and ends within the button, + // but LLSpinCtrl handles the action continuosly so subsribers needs to + // be informed about click ending even if outside view, use 'up' instead + up_button_params.mouse_up_callback.function(boost::bind(&LLSpinCtrl::onUpBtn, this, _2)); up_button_params.mouse_held_callback.function(boost::bind(&LLSpinCtrl::onUpBtn, this, _2)); up_button_params.commit_on_capture_lost = true; @@ -110,7 +113,7 @@ LLSpinCtrl::LLSpinCtrl(const LLSpinCtrl::Params& p) LLButton::Params down_button_params(p.down_button); down_button_params.rect = LLRect(btn_left, getRect().getHeight() - spinctrl_btn_height, btn_right, getRect().getHeight() - 2 * spinctrl_btn_height); - down_button_params.click_callback.function(boost::bind(&LLSpinCtrl::onDownBtn, this, _2)); + down_button_params.mouse_up_callback.function(boost::bind(&LLSpinCtrl::onDownBtn, this, _2)); down_button_params.mouse_held_callback.function(boost::bind(&LLSpinCtrl::onDownBtn, this, _2)); down_button_params.commit_on_capture_lost = true; mDownBtn = LLUICtrlFactory::create(down_button_params); -- cgit v1.2.3 From 0191ee5f6f96eafa20e838ee1737eea58dafb1de Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Wed, 17 Aug 2022 14:50:03 +0300 Subject: SL-17973 FIXED region name is not shown in the IM chat --- indra/llui/llchat.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'indra/llui') diff --git a/indra/llui/llchat.h b/indra/llui/llchat.h index c39e44200c..b4fd5f60aa 100644 --- a/indra/llui/llchat.h +++ b/indra/llui/llchat.h @@ -38,7 +38,8 @@ typedef enum e_chat_source_type CHAT_SOURCE_AGENT = 1, CHAT_SOURCE_OBJECT = 2, CHAT_SOURCE_TELEPORT = 3, - CHAT_SOURCE_UNKNOWN = 4 + CHAT_SOURCE_UNKNOWN = 4, + CHAT_SOURCE_REGION = 5, } EChatSourceType; typedef enum e_chat_type -- cgit v1.2.3