STORM-2035 - Invert the background color in script editors for highlighting sections. Since the background color can be changed by the user, this ensures distinctive highlighting

master
Cinder 2014-06-20 13:43:31 -06:00
parent 984353d7ca
commit 8d2e0fb3a0
6 changed files with 155 additions and 47 deletions

View File

@ -321,6 +321,7 @@ Cinder Roxley
STORM-1958
STORM-1952
STORM-1951
STORM-2035
STORM-2036
Clara Young
Coaldust Numbers

View File

@ -70,43 +70,36 @@ bool LLTextBase::compare_segment_end::operator()(const LLTextSegmentPtr& a, cons
// helper functors
struct LLTextBase::compare_bottom
bool LLTextBase::compare_bottom::operator()(const S32& a, const LLTextBase::line_info& b) const
{
bool operator()(const S32& a, const LLTextBase::line_info& b) const
{
return a > b.mRect.mBottom; // bottom of a is higher than bottom of b
}
return a > b.mRect.mBottom; // bottom of a is higher than bottom of b
}
bool operator()(const LLTextBase::line_info& a, const S32& b) const
{
return a.mRect.mBottom > b; // bottom of a is higher than bottom of b
}
bool LLTextBase::compare_bottom::operator()(const LLTextBase::line_info& a, const S32& b) const
{
return a.mRect.mBottom > b; // bottom of a is higher than bottom of b
}
bool operator()(const LLTextBase::line_info& a, const LLTextBase::line_info& b) const
{
return a.mRect.mBottom > b.mRect.mBottom; // bottom of a is higher than bottom of b
}
};
bool LLTextBase::compare_bottom::operator()(const LLTextBase::line_info& a, const LLTextBase::line_info& b) const
{
return a.mRect.mBottom > b.mRect.mBottom; // bottom of a is higher than bottom of b
}
// helper functors
struct LLTextBase::compare_top
bool LLTextBase::compare_top::operator()(const S32& a, const LLTextBase::line_info& b) const
{
bool operator()(const S32& a, const LLTextBase::line_info& b) const
{
return a > b.mRect.mTop; // top of a is higher than top of b
}
return a > b.mRect.mTop; // top of a is higher than top of b
}
bool operator()(const LLTextBase::line_info& a, const S32& b) const
{
return a.mRect.mTop > b; // top of a is higher than top of b
}
bool LLTextBase::compare_top::operator()(const LLTextBase::line_info& a, const S32& b) const
{
return a.mRect.mTop > b; // top of a is higher than top of b
}
bool operator()(const LLTextBase::line_info& a, const LLTextBase::line_info& b) const
{
return a.mRect.mTop > b.mRect.mTop; // top of a is higher than top of b
}
};
bool LLTextBase::compare_top::operator()(const LLTextBase::line_info& a, const LLTextBase::line_info& b) const
{
return a.mRect.mTop > b.mRect.mTop; // top of a is higher than top of b
}
struct LLTextBase::line_end_compare
{

View File

@ -451,9 +451,31 @@ public:
LLScrollContainer* getScrollContainer() const { return mScroller; }
protected:
// protected member variables
// List of offsets and segment index of the start of each line. Always has at least one node (0).
struct line_info
{
line_info(S32 index_start, S32 index_end, LLRect rect, S32 line_num);
S32 mDocIndexStart;
S32 mDocIndexEnd;
LLRect mRect;
S32 mLineNum; // actual line count (ignoring soft newlines due to word wrap)
};
typedef std::vector<line_info> line_list_t;
// helper structs
struct compare_bottom;
struct compare_top;
struct compare_bottom
{
bool operator()(const S32& a, const line_info& b) const;
bool operator()(const line_info& a, const S32& b) const;
bool operator()(const line_info& a, const line_info& b) const;
};
struct compare_top
{
bool operator()(const S32& a, const line_info& b) const;
bool operator()(const line_info& a, const S32& b) const;
bool operator()(const line_info& a, const line_info& b) const;
};
struct line_end_compare;
typedef std::vector<LLTextSegmentPtr> segment_vec_t;
@ -501,18 +523,6 @@ protected:
};
typedef std::multiset<LLTextSegmentPtr, compare_segment_end> segment_set_t;
// protected member variables
// List of offsets and segment index of the start of each line. Always has at least one node (0).
struct line_info
{
line_info(S32 index_start, S32 index_end, LLRect rect, S32 line_num);
S32 mDocIndexStart;
S32 mDocIndexEnd;
LLRect mRect;
S32 mLineNum; // actual line count (ignoring soft newlines due to word wrap)
};
typedef std::vector<line_info> line_list_t;
// member functions
LLTextBase(const Params &p);
virtual ~LLTextBase();
@ -522,7 +532,7 @@ protected:
virtual bool useLabel() const;
// draw methods
void drawSelectionBackground(); // draws the black box behind the selected text
virtual void drawSelectionBackground(); // draws the black box behind the selected text
void drawCursor();
void drawText();

View File

@ -183,3 +183,107 @@ void LLScriptEditor::clearSegments()
mSegments.clear();
}
}
// Most of this is shamelessly copied from LLTextBase
void LLScriptEditor::drawSelectionBackground()
{
// Draw selection even if we don't have keyboard focus for search/replace
if( hasSelection() && !mLineInfoList.empty())
{
std::vector<LLRect> selection_rects;
S32 selection_left = llmin( mSelectionStart, mSelectionEnd );
S32 selection_right = llmax( mSelectionStart, mSelectionEnd );
// Skip through the lines we aren't drawing.
LLRect content_display_rect = getVisibleDocumentRect();
// 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, LLTextBase::compare_bottom());
line_list_t::const_iterator end_iter = std::upper_bound(mLineInfoList.begin(), mLineInfoList.end(), content_display_rect.mBottom, LLTextBase::compare_top());
bool done = false;
// 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;
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;
S32 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->getDimensions(segment_offset, num_chars, segment_width, segment_height);
selection_rect.mLeft += 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->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;
break;
}
}
selection_rects.push_back(selection_rect);
}
}
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
const LLColor4& color = mReadOnly ? mReadOnlyBgColor : mWriteableBgColor;
F32 alpha = hasFocus() ? 0.7f : 0.3f;
alpha *= getDrawContext().mAlpha;
// We want to invert the background color in script editors
LLColor4 selection_color(1.f - color.mV[VRED],
1.f - color.mV[VGREEN],
1.f - color.mV[VBLUE],
alpha);
for (std::vector<LLRect>::iterator rect_it = selection_rects.begin();
rect_it != selection_rects.end();
++rect_it)
{
LLRect selection_rect = *rect_it;
selection_rect = *rect_it;
selection_rect.translate(mVisibleTextRect.mLeft - content_display_rect.mLeft, mVisibleTextRect.mBottom - content_display_rect.mBottom);
gl_rect_2d(selection_rect, selection_color);
}
}
}

View File

@ -48,7 +48,7 @@ public:
void initKeywords();
void loadKeywords();
void clearSegments();
/* virtual */ void clearSegments();
LLKeywords::keyword_iterator_t keywordsBegin() { return mKeywords.begin(); }
LLKeywords::keyword_iterator_t keywordsEnd() { return mKeywords.end(); }
@ -58,7 +58,8 @@ protected:
private:
void drawLineNumbers();
void updateSegments();
/* virtual */ void updateSegments();
/* virtual */ void drawSelectionBackground();
void loadKeywords(const std::string& filename_keywords,
const std::string& filename_colors);

View File

@ -176,7 +176,6 @@
bg_focus_color="ScriptBackground"
text_readonly_color="ScriptText"
bg_readonly_color="ScriptBackground"
bg_selected_color="ScriptSelectedColor"
cursor_color="ScriptCursorColor"
enable_tooltip_paste="true"
word_wrap="true"