From 7c793020c6bae9a3090f5c0e2f8399efd8b954ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tam=C3=A1s=20B=C3=A1lint=20Misius?= Date: Fri, 19 Jul 2019 09:22:55 +0200 Subject: [PATCH] Fix highlighting in ConsoleView --- src/gui/console/ConsoleView.cpp | 6 ++-- src/gui/interface/Label.cpp | 43 ++++++++++++++--------- src/gui/interface/Label.h | 7 +++- src/gui/interface/TextWrapper.cpp | 57 ++++++++++++++++++------------- src/gui/interface/TextWrapper.h | 7 ++-- src/gui/interface/Textbox.cpp | 6 ++-- 6 files changed, 76 insertions(+), 50 deletions(-) diff --git a/src/gui/console/ConsoleView.cpp b/src/gui/console/ConsoleView.cpp index 958be631e..1c60dad91 100644 --- a/src/gui/console/ConsoleView.cpp +++ b/src/gui/console/ConsoleView.cpp @@ -26,7 +26,7 @@ ConsoleView::ConsoleView(): CommandHighlighter(ConsoleView * v_) { v = v_; } void TextChangedCallback(ui::Textbox * sender) override { - // sender->SetDisplayText(v->c->FormatCommand(sender->GetText())); + sender->SetDisplayText(v->c->FormatCommand(sender->GetText())); } }; commandField = new ui::Textbox(ui::Point(0, Size.Y-16), ui::Point(Size.X, 16), ""); @@ -52,7 +52,7 @@ void ConsoleView::DoKeyPress(int key, int scan, bool repeat, bool shift, bool ct case SDLK_KP_ENTER: c->EvaluateCommand(commandField->GetText()); commandField->SetText(""); - // commandField->SetDisplayText(""); + commandField->SetDisplayText(""); break; case SDLK_DOWN: c->NextCommand(); @@ -106,7 +106,7 @@ void ConsoleView::NotifyPreviousCommandsChanged(ConsoleModel * sender) void ConsoleView::NotifyCurrentCommandChanged(ConsoleModel * sender) { commandField->SetText(sender->GetCurrentCommand().Command); - // commandField->SetDisplayText(c->FormatCommand(commandField->GetText())); + commandField->SetDisplayText(c->FormatCommand(commandField->GetText())); } diff --git a/src/gui/interface/Label.cpp b/src/gui/interface/Label.cpp index 72449591f..6c0aab346 100644 --- a/src/gui/interface/Label.cpp +++ b/src/gui/interface/Label.cpp @@ -35,7 +35,7 @@ void Label::SetMultiline(bool status) multiline = status; updateTextWrapper(); updateSelection(); - TextPosition(textWrapper.WrappedText()); + TextPosition(displayTextWrapper.WrappedText()); } void Label::SetText(String newText) @@ -43,7 +43,7 @@ void Label::SetText(String newText) this->text = newText; updateTextWrapper(); updateSelection(); - TextPosition(textWrapper.WrappedText()); + TextPosition(displayTextWrapper.WrappedText()); } void Label::AutoHeight() @@ -56,7 +56,16 @@ void Label::AutoHeight() void Label::updateTextWrapper() { - int lines = textWrapper.Update(text, multiline, Size.X - Appearance.Margin.Left - Appearance.Margin.Right); + int lines = textWrapper.Update( + text, + multiline, + Size.X - Appearance.Margin.Left - Appearance.Margin.Right + ); + displayTextWrapper.Update( + displayText.size() ? displayText : text, + multiline, + Size.X - Appearance.Margin.Left - Appearance.Margin.Right + ); if (autoHeight) { Size.Y = lines * 12 + 3; @@ -192,28 +201,28 @@ void Label::updateSelection() if (selectionIndexH.raw_index < 0) selectionIndexH = textWrapper.IndexBegin(); if (selectionIndexH.raw_index > (int)text.length()) selectionIndexH = textWrapper.IndexEnd(); - displayTextWithSelection = textWrapper.WrappedText(); + displayTextWithSelection = displayTextWrapper.WrappedText(); if (HasSelection()) { - displayTextWithSelection.Insert(selectionIndexL.wrapped_index, "\x01"); - displayTextWithSelection.Insert(selectionIndexH.wrapped_index + 1, "\x01"); + displayTextWithSelection.Insert(displayTextWrapper.Clear2Index(selectionIndexL.clear_index).wrapped_index, "\x01"); + displayTextWithSelection.Insert(displayTextWrapper.Clear2Index(selectionIndexH.clear_index).wrapped_index + 1, "\x01"); } } -// void Label::SetDisplayText(String newText) -// { - // displayText = newText; - // ClearSelection(); - // updateTextWrapper(); - // updateSelection(); - // TextPosition(textWrapper.WrappedText()); -// } +void Label::SetDisplayText(String newText) +{ + displayText = newText; + ClearSelection(); + updateTextWrapper(); + updateSelection(); + TextPosition(displayTextWrapper.WrappedText()); +} void Label::Draw(const Point& screenPos) { if (!drawn) { - TextPosition(textWrapper.WrappedText()); + TextPosition(displayTextWrapper.WrappedText()); updateTextWrapper(); updateSelection(); drawn = true; @@ -222,11 +231,11 @@ void Label::Draw(const Point& screenPos) int selectionXL; int selectionYL; - int selectionLineL = textWrapper.Index2Point(selectionIndexL, selectionXL, selectionYL); + int selectionLineL = displayTextWrapper.Index2Point(selectionIndexL, selectionXL, selectionYL); int selectionXH; int selectionYH; - int selectionLineH = textWrapper.Index2Point(selectionIndexH, selectionXH, selectionYH); + int selectionLineH = displayTextWrapper.Index2Point(selectionIndexH, selectionXH, selectionYH); if (HasSelection()) { diff --git a/src/gui/interface/Label.h b/src/gui/interface/Label.h index 10b6e4b43..37433b540 100644 --- a/src/gui/interface/Label.h +++ b/src/gui/interface/Label.h @@ -16,6 +16,11 @@ namespace ui String displayTextWithSelection; String text; + TextWrapper textWrapper; + + String displayText; + TextWrapper displayTextWrapper; + Colour textColour; TextWrapper::Index selectionIndex0; TextWrapper::Index selectionIndex1; @@ -32,7 +37,6 @@ namespace ui int getLowerSelectionBound(); int getHigherSelectionBound(); - TextWrapper textWrapper; void copySelection(); public: @@ -44,6 +48,7 @@ namespace ui void SetMultiline(bool status); virtual void SetText(String text); + virtual void SetDisplayText(String text); virtual String GetText(); bool HasSelection(); diff --git a/src/gui/interface/TextWrapper.cpp b/src/gui/interface/TextWrapper.cpp index 108974fcb..7748efff2 100644 --- a/src/gui/interface/TextWrapper.cpp +++ b/src/gui/interface/TextWrapper.cpp @@ -17,7 +17,8 @@ namespace ui { String::value_type character; int width; - std::iterator_traits::difference_type position; + int raw_index; + int clear_index; bool wraps; }; int line_width = 0; @@ -27,14 +28,16 @@ namespace ui int word_width; int lines = 1; int char_width; + int clear_count = 0; - auto wrap_if_needed = [&](int width_to_consider) { + auto wrap_if_needed = [&](int width_to_consider) -> bool { if (do_wrapping && width_to_consider + char_width > max_width) { records.push_back(wrap_record{ '\n', // character; makes the line wrap when rendered 0, // width; fools the clickmap generator into not seeing this newline 0, // position; the clickmap generator is fooled, this can be anything + 0, true // signal the end of the line to the clickmap generator }); line_width = 0; @@ -66,12 +69,14 @@ namespace ui records.push_back(wrap_record{ *it, char_width, - it - text.begin(), + (int)(it - text.begin()), + clear_count, false }); line_width += char_width; } word_begins_at = -1; // reset word state + ++clear_count; break; // add more supported linebreaks here @@ -79,12 +84,14 @@ namespace ui records.push_back(wrap_record{ *it, // character; makes the line wrap when rendered max_width - line_width, // width; make it span all the way to the end - it - text.begin(), // position; so the clickmap generator knows where *it is + (int)(it - text.begin()), // position; so the clickmap generator knows where *it is + clear_count, true // signal the end of the line to the clickmap generator }); lines += 1; line_width = 0; word_begins_at = -1; // reset word state + ++clear_count; break; default: @@ -101,6 +108,7 @@ namespace ui *it, // character; forward the sequence to the output 0, // width; fools the clickmap generator into not seeing this sequence 0, // position; the clickmap generator is fooled, this can be anything + 0, false // signal nothing to the clickmap generator }); } @@ -114,24 +122,6 @@ namespace ui word_width = 0; } - - auto wrap_if_needed = [&](int width_to_consider) { - if (do_wrapping && width_to_consider + char_width > max_width) - { - records.push_back(wrap_record{ - '\n', // character; makes the line wrap when rendered - 0, // width; fools the clickmap generator into not seeing this newline - 0, // position; the clickmap generator is fooled, this can be anything - true // signal the end of the line to the clickmap generator - }); - line_width = 0; - lines += 1; - return true; - } - return false; - }; - - if (wrap_if_needed(word_width)) { word_begins_at = records.size(); @@ -160,11 +150,13 @@ namespace ui records.push_back(wrap_record{ *it, // character; make the line wrap with *it char_width, // width; make it span all the way to the end - it - text.begin(), // position; so the clickmap generator knows where *it is + (int)(it - text.begin()), // position; so the clickmap generator knows where *it is + clear_count, false // signal nothing to the clickmap generator }); word_width += char_width; line_width += char_width; + ++clear_count; switch (*it) { @@ -192,7 +184,7 @@ namespace ui int counter = 0; for (auto const &record : records) { - regions.push_back(clickmap_region{ x, l * FONT_H, record.width, l + 1, Index{ (int)record.position, counter } }); + regions.push_back(clickmap_region{ x, l * FONT_H, record.width, l + 1, Index{ record.raw_index, counter, record.clear_index } }); ++counter; x += record.width; if (record.wraps) @@ -203,6 +195,7 @@ namespace ui wrapped_text.append(1, record.character); } + clear_text_size = clear_count; wrapped_lines = lines; return lines; } @@ -291,4 +284,20 @@ namespace ui } return IndexEnd(); } + + TextWrapper::Index TextWrapper::Clear2Index(int clear_index) const + { + if (clear_index < 0) + { + return IndexBegin(); + } + for (auto const ®ion : regions) + { + if (region.index.clear_index >= clear_index) + { + return region.index; + } + } + return IndexEnd(); + } } diff --git a/src/gui/interface/TextWrapper.h b/src/gui/interface/TextWrapper.h index e85b8f222..c2640f63b 100644 --- a/src/gui/interface/TextWrapper.h +++ b/src/gui/interface/TextWrapper.h @@ -14,10 +14,12 @@ namespace ui { int raw_index; int wrapped_index; + int clear_index; }; private: int raw_text_size; + int clear_text_size; String wrapped_text; struct clickmap_region { @@ -30,6 +32,7 @@ namespace ui public: int Update(String const &text, bool do_wrapping, int max_width); Index Raw2Index(int raw_index) const; + Index Clear2Index(int clear_index) const; Index Point2Index(int x, int y) const; int Index2Point(Index index, int &x, int &y) const; @@ -40,12 +43,12 @@ namespace ui Index IndexBegin() const { - return Index{ 0, 0 }; + return Index{ 0, 0, 0 }; } Index IndexEnd() const { - return Index{ raw_text_size, (int)wrapped_text.size() }; + return Index{ raw_text_size, (int)wrapped_text.size(), clear_text_size }; } }; } diff --git a/src/gui/interface/Textbox.cpp b/src/gui/interface/Textbox.cpp index 2c11a7a27..43fbc251c 100644 --- a/src/gui/interface/Textbox.cpp +++ b/src/gui/interface/Textbox.cpp @@ -171,7 +171,7 @@ void Textbox::cutSelection() updateTextWrapper(); updateSelection(); - TextPosition(text); + TextPosition(displayTextWrapper.WrappedText()); if(cursor) { @@ -241,7 +241,7 @@ void Textbox::pasteIntoSelection() updateTextWrapper(); updateSelection(); - TextPosition(textWrapper.WrappedText()); + TextPosition(displayTextWrapper.WrappedText()); if(cursor) { @@ -459,7 +459,7 @@ void Textbox::AfterTextChange(bool changed) updateTextWrapper(); updateSelection(); - TextPosition(textWrapper.WrappedText()); + TextPosition(displayTextWrapper.WrappedText()); if(cursor) {