From 8c39617c9ac469a8635d511142148ad5a38de836 Mon Sep 17 00:00:00 2001 From: Cinder Date: Fri, 18 Apr 2014 12:52:07 -0600 Subject: Begin moving script editor portions of LLTextEditor to their own derived class. This should fix the run off segment bugs by not overriding LLTextBase::clearSegments() in LLTextEditor TODO: Move the rest of the script stuff out of LLTextEditor for simplicity sake --- indra/newview/llscripteditor.cpp | 51 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 indra/newview/llscripteditor.cpp (limited to 'indra/newview/llscripteditor.cpp') diff --git a/indra/newview/llscripteditor.cpp b/indra/newview/llscripteditor.cpp new file mode 100644 index 0000000000..7067f49fba --- /dev/null +++ b/indra/newview/llscripteditor.cpp @@ -0,0 +1,51 @@ +/** + * @file llecripteditor.cpp + * @author Cinder Roxley + * @brief Text editor widget used for viewing and editing scripts + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "linden_common.h" +#include "llscripteditor.h" + +static LLDefaultChildRegistry::Register r("script_editor"); + +LLScriptEditor::LLScriptEditor::Params::Params() +{ + +} + + +LLScriptEditor::LLScriptEditor(const Params& p) +: LLTextEditor(p) +{ + +} + +void LLScriptEditor::clearSegments() +{ + if (!mSegments.empty()) + { + mSegments.clear(); + } +} -- cgit v1.2.3 From 9ec900c3c440a8d1e25d55667c861d27a95b1297 Mon Sep 17 00:00:00 2001 From: Cinder Date: Fri, 18 Apr 2014 12:53:19 -0600 Subject: Trivial typo fix --- indra/newview/llscripteditor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llscripteditor.cpp') diff --git a/indra/newview/llscripteditor.cpp b/indra/newview/llscripteditor.cpp index 7067f49fba..67a43c0ef0 100644 --- a/indra/newview/llscripteditor.cpp +++ b/indra/newview/llscripteditor.cpp @@ -1,5 +1,5 @@ /** - * @file llecripteditor.cpp + * @file llscripteditor.cpp * @author Cinder Roxley * @brief Text editor widget used for viewing and editing scripts * -- cgit v1.2.3 From dcffb97518cb2888489c93b90862518f761967dd Mon Sep 17 00:00:00 2001 From: Cinder Date: Fri, 18 Apr 2014 23:13:57 -0600 Subject: Move some more script editor functions from LLTextEditor to LLScriptEditor --- indra/newview/llscripteditor.cpp | 44 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) (limited to 'indra/newview/llscripteditor.cpp') diff --git a/indra/newview/llscripteditor.cpp b/indra/newview/llscripteditor.cpp index 67a43c0ef0..61b5eec9fc 100644 --- a/indra/newview/llscripteditor.cpp +++ b/indra/newview/llscripteditor.cpp @@ -28,6 +28,8 @@ #include "linden_common.h" #include "llscripteditor.h" +#include "llsyntaxid.h" + static LLDefaultChildRegistry::Register r("script_editor"); LLScriptEditor::LLScriptEditor::Params::Params() @@ -42,6 +44,48 @@ LLScriptEditor::LLScriptEditor(const Params& p) } +void LLScriptEditor::initKeywords() +{ + mKeywords.initialise(LLSyntaxIdLSL::getInstance()->getKeywordsXML()); +} + +static LLFastTimer::DeclareTimer FTM_SYNTAX_HIGHLIGHTING("Syntax Highlighting"); + +void LLScriptEditor::loadKeywords() +{ + LLFastTimer ft(FTM_SYNTAX_HIGHLIGHTING); + mKeywords.processTokens(); + + segment_vec_t segment_list; + mKeywords.findSegments(&segment_list, getWText(), mDefaultColor.get(), *this); + + mSegments.clear(); + segment_set_t::iterator insert_it = mSegments.begin(); + for (segment_vec_t::iterator list_it = segment_list.begin(); list_it != segment_list.end(); ++list_it) + { + insert_it = mSegments.insert(insert_it, *list_it); + } +} + +void LLScriptEditor::updateSegments() +{ + if (mReflowIndex < S32_MAX && mKeywords.isLoaded() && mParseOnTheFly) + { + LLFastTimer ft(FTM_SYNTAX_HIGHLIGHTING); + // HACK: No non-ascii keywords for now + segment_vec_t segment_list; + mKeywords.findSegments(&segment_list, getWText(), mDefaultColor.get(), *this); + + clearSegments(); + for (segment_vec_t::iterator list_it = segment_list.begin(); list_it != segment_list.end(); ++list_it) + { + insertSegment(*list_it); + } + } + + LLTextBase::updateSegments(); +} + void LLScriptEditor::clearSegments() { if (!mSegments.empty()) -- cgit v1.2.3 From 3dc1b32bf32643613c9912f1165de0f52d0a82c8 Mon Sep 17 00:00:00 2001 From: Cinder Date: Mon, 21 Apr 2014 09:33:21 -0600 Subject: Windows build fix. --- indra/newview/llscripteditor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llscripteditor.cpp') diff --git a/indra/newview/llscripteditor.cpp b/indra/newview/llscripteditor.cpp index 61b5eec9fc..bb59a1d821 100644 --- a/indra/newview/llscripteditor.cpp +++ b/indra/newview/llscripteditor.cpp @@ -25,7 +25,7 @@ * $/LicenseInfo$ */ -#include "linden_common.h" +#include "llviewerprecompiledheaders.h" #include "llscripteditor.h" #include "llsyntaxid.h" -- cgit v1.2.3 From 54d392c4ff8a2a211e00a62023409b2dba85e8e9 Mon Sep 17 00:00:00 2001 From: Cinder Date: Mon, 21 Apr 2014 12:07:46 -0600 Subject: Another oops windows build fix. --- indra/newview/llscripteditor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llscripteditor.cpp') diff --git a/indra/newview/llscripteditor.cpp b/indra/newview/llscripteditor.cpp index bb59a1d821..5d87f7ba0c 100644 --- a/indra/newview/llscripteditor.cpp +++ b/indra/newview/llscripteditor.cpp @@ -32,7 +32,7 @@ static LLDefaultChildRegistry::Register r("script_editor"); -LLScriptEditor::LLScriptEditor::Params::Params() +LLScriptEditor::Params::Params() { } -- cgit v1.2.3 From 1e851a2eb70e5f6b12a47c382efb3b9b17674993 Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Wed, 7 May 2014 15:18:44 -0400 Subject: correct bad merges from 3.7.7-release --- indra/newview/llscripteditor.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'indra/newview/llscripteditor.cpp') diff --git a/indra/newview/llscripteditor.cpp b/indra/newview/llscripteditor.cpp index 5d87f7ba0c..12c328e809 100644 --- a/indra/newview/llscripteditor.cpp +++ b/indra/newview/llscripteditor.cpp @@ -49,11 +49,11 @@ void LLScriptEditor::initKeywords() mKeywords.initialise(LLSyntaxIdLSL::getInstance()->getKeywordsXML()); } -static LLFastTimer::DeclareTimer FTM_SYNTAX_HIGHLIGHTING("Syntax Highlighting"); +LLTrace::BlockTimerStatHandle FTM_SYNTAX_HIGHLIGHTING("Syntax Highlighting"); void LLScriptEditor::loadKeywords() { - LLFastTimer ft(FTM_SYNTAX_HIGHLIGHTING); + LL_RECORD_BLOCK_TIME(FTM_SYNTAX_HIGHLIGHTING); mKeywords.processTokens(); segment_vec_t segment_list; @@ -71,7 +71,7 @@ void LLScriptEditor::updateSegments() { if (mReflowIndex < S32_MAX && mKeywords.isLoaded() && mParseOnTheFly) { - LLFastTimer ft(FTM_SYNTAX_HIGHLIGHTING); + LL_RECORD_BLOCK_TIME(FTM_SYNTAX_HIGHLIGHTING); // HACK: No non-ascii keywords for now segment_vec_t segment_list; mKeywords.findSegments(&segment_list, getWText(), mDefaultColor.get(), *this); -- cgit v1.2.3 From 8501d6494bceeea962d7251d882ddc244a8daa7f Mon Sep 17 00:00:00 2001 From: Cinder Date: Wed, 7 May 2014 19:58:56 -0600 Subject: Code policy --- indra/newview/llscripteditor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llscripteditor.cpp') diff --git a/indra/newview/llscripteditor.cpp b/indra/newview/llscripteditor.cpp index 5d87f7ba0c..869368e72c 100644 --- a/indra/newview/llscripteditor.cpp +++ b/indra/newview/llscripteditor.cpp @@ -46,7 +46,7 @@ LLScriptEditor::LLScriptEditor(const Params& p) void LLScriptEditor::initKeywords() { - mKeywords.initialise(LLSyntaxIdLSL::getInstance()->getKeywordsXML()); + mKeywords.initialize(LLSyntaxIdLSL::getInstance()->getKeywordsXML()); } static LLFastTimer::DeclareTimer FTM_SYNTAX_HIGHLIGHTING("Syntax Highlighting"); -- cgit v1.2.3 From e776b600b1a76fcbe316041fc6fa8e885464daee Mon Sep 17 00:00:00 2001 From: Cinder Date: Wed, 14 May 2014 14:08:24 -0600 Subject: Refactor more script editor properties away from LLTextEditor to LLScriptEditor --- indra/newview/llscripteditor.cpp | 96 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 93 insertions(+), 3 deletions(-) (limited to 'indra/newview/llscripteditor.cpp') diff --git a/indra/newview/llscripteditor.cpp b/indra/newview/llscripteditor.cpp index 31d3c29af4..df46380130 100644 --- a/indra/newview/llscripteditor.cpp +++ b/indra/newview/llscripteditor.cpp @@ -29,19 +29,109 @@ #include "llscripteditor.h" #include "llsyntaxid.h" +#include "lllocalcliprect.h" + +const S32 UI_TEXTEDITOR_LINE_NUMBER_MARGIN = 32; +const S32 UI_TEXTEDITOR_LINE_NUMBER_DIGITS = 4; static LLDefaultChildRegistry::Register r("script_editor"); LLScriptEditor::Params::Params() -{ - -} +: show_line_numbers("show_line_numbers", true) +{} LLScriptEditor::LLScriptEditor(const Params& p) : LLTextEditor(p) +, mShowLineNumbers(p.show_line_numbers) +{ + if (mShowLineNumbers) + { + mHPad += UI_TEXTEDITOR_LINE_NUMBER_MARGIN; + updateRects(); + } +} + +void LLScriptEditor::draw() { + { + // pad clipping rectangle so that cursor can draw at full width + // when at left edge of mVisibleTextRect + LLRect clip_rect(mVisibleTextRect); + clip_rect.stretch(1); + LLLocalClipRect clip(clip_rect); + } + LLTextBase::draw(); + drawLineNumbers(); + + drawPreeditMarker(); + + //RN: the decision was made to always show the orange border for keyboard focus but do not put an insertion caret + // when in readonly mode + mBorder->setKeyboardFocusHighlight( hasFocus() );// && !mReadOnly); +} + +void LLScriptEditor::drawLineNumbers() +{ + LLGLSUIDefault gls_ui; + LLRect scrolled_view_rect = getVisibleDocumentRect(); + LLRect content_rect = getVisibleTextRect(); + LLLocalClipRect clip(content_rect); + S32 first_line = getFirstVisibleLine(); + S32 num_lines = getLineCount(); + if (first_line >= num_lines) + { + return; + } + + S32 cursor_line = mLineInfoList[getLineNumFromDocIndex(mCursorPos)].mLineNum; + + if (mShowLineNumbers) + { + S32 left = 0; + S32 top = getRect().getHeight(); + S32 bottom = 0; + + gl_rect_2d(left, top, UI_TEXTEDITOR_LINE_NUMBER_MARGIN, bottom, mReadOnlyBgColor.get() ); // line number area always read-only + gl_rect_2d(UI_TEXTEDITOR_LINE_NUMBER_MARGIN, top, UI_TEXTEDITOR_LINE_NUMBER_MARGIN-1, bottom, LLColor4::grey3); // separator + + S32 last_line_num = -1; + + for (S32 cur_line = first_line; cur_line < num_lines; cur_line++) + { + line_info& line = mLineInfoList[cur_line]; + + if ((line.mRect.mTop - scrolled_view_rect.mBottom) < mVisibleTextRect.mBottom) + { + break; + } + + S32 line_bottom = line.mRect.mBottom - scrolled_view_rect.mBottom + mVisibleTextRect.mBottom; + // draw the line numbers + if(line.mLineNum != last_line_num && line.mRect.mTop <= scrolled_view_rect.mTop) + { + const LLFontGL *num_font = LLFontGL::getFontMonospace(); + const LLWString ltext = utf8str_to_wstring(llformat("%d", line.mLineNum )); + BOOL is_cur_line = cursor_line == line.mLineNum; + const U8 style = is_cur_line ? LLFontGL::BOLD : LLFontGL::NORMAL; + const LLColor4 fg_color = is_cur_line ? mCursorColor : mReadOnlyFgColor; + num_font->render( + ltext, // string to draw + 0, // begin offset + UI_TEXTEDITOR_LINE_NUMBER_MARGIN - 2, // x + line_bottom, // y + fg_color, + LLFontGL::RIGHT, // horizontal alignment + LLFontGL::BOTTOM, // vertical alignment + style, + LLFontGL::NO_SHADOW, + S32_MAX, // max chars + UI_TEXTEDITOR_LINE_NUMBER_MARGIN - 2); // max pixels + last_line_num = line.mLineNum; + } + } + } } void LLScriptEditor::initKeywords() -- cgit v1.2.3 From 8d2e0fb3a047e349b88db80afa09fc97a7f4ff74 Mon Sep 17 00:00:00 2001 From: Cinder Date: Fri, 20 Jun 2014 13:43:31 -0600 Subject: 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 --- indra/newview/llscripteditor.cpp | 104 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) (limited to 'indra/newview/llscripteditor.cpp') diff --git a/indra/newview/llscripteditor.cpp b/indra/newview/llscripteditor.cpp index df46380130..3bbfbad477 100644 --- a/indra/newview/llscripteditor.cpp +++ b/indra/newview/llscripteditor.cpp @@ -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 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::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); + } + } +} -- cgit v1.2.3 From c3573b6d7b53dac583f9fed40a243f7fa98f6c87 Mon Sep 17 00:00:00 2001 From: Cinder Date: Tue, 24 Jun 2014 15:27:08 -0600 Subject: STORM-2035 - Looking for a good selection box contrast --- indra/newview/llscripteditor.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'indra/newview/llscripteditor.cpp') diff --git a/indra/newview/llscripteditor.cpp b/indra/newview/llscripteditor.cpp index 3bbfbad477..81920562a7 100644 --- a/indra/newview/llscripteditor.cpp +++ b/indra/newview/llscripteditor.cpp @@ -267,13 +267,13 @@ void LLScriptEditor::drawSelectionBackground() } gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - const LLColor4& color = mReadOnly ? mReadOnlyBgColor : mWriteableBgColor; + const LLColor4& color = mReadOnly ? mReadOnlyFgColor : mFgColor; 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], + // We want to shift the color to something readable but distinct + LLColor4 selection_color((1.f + color.mV[VRED]) * 0.5f, + (1.f + color.mV[VGREEN]) * 0.5f, + (1.f + color.mV[VBLUE]) * 0.5f, alpha); for (std::vector::iterator rect_it = selection_rects.begin(); -- cgit v1.2.3