Fix highlighting in ConsoleView

This commit is contained in:
Tamás Bálint Misius 2019-07-19 09:22:55 +02:00
parent bea4576d89
commit 7c793020c6
No known key found for this signature in database
GPG Key ID: 5B472A12F6ECA9F2
6 changed files with 76 additions and 50 deletions

View File

@ -26,7 +26,7 @@ ConsoleView::ConsoleView():
CommandHighlighter(ConsoleView * v_) { v = v_; } CommandHighlighter(ConsoleView * v_) { v = v_; }
void TextChangedCallback(ui::Textbox * sender) override 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), ""); 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: case SDLK_KP_ENTER:
c->EvaluateCommand(commandField->GetText()); c->EvaluateCommand(commandField->GetText());
commandField->SetText(""); commandField->SetText("");
// commandField->SetDisplayText(""); commandField->SetDisplayText("");
break; break;
case SDLK_DOWN: case SDLK_DOWN:
c->NextCommand(); c->NextCommand();
@ -106,7 +106,7 @@ void ConsoleView::NotifyPreviousCommandsChanged(ConsoleModel * sender)
void ConsoleView::NotifyCurrentCommandChanged(ConsoleModel * sender) void ConsoleView::NotifyCurrentCommandChanged(ConsoleModel * sender)
{ {
commandField->SetText(sender->GetCurrentCommand().Command); commandField->SetText(sender->GetCurrentCommand().Command);
// commandField->SetDisplayText(c->FormatCommand(commandField->GetText())); commandField->SetDisplayText(c->FormatCommand(commandField->GetText()));
} }

View File

@ -35,7 +35,7 @@ void Label::SetMultiline(bool status)
multiline = status; multiline = status;
updateTextWrapper(); updateTextWrapper();
updateSelection(); updateSelection();
TextPosition(textWrapper.WrappedText()); TextPosition(displayTextWrapper.WrappedText());
} }
void Label::SetText(String newText) void Label::SetText(String newText)
@ -43,7 +43,7 @@ void Label::SetText(String newText)
this->text = newText; this->text = newText;
updateTextWrapper(); updateTextWrapper();
updateSelection(); updateSelection();
TextPosition(textWrapper.WrappedText()); TextPosition(displayTextWrapper.WrappedText());
} }
void Label::AutoHeight() void Label::AutoHeight()
@ -56,7 +56,16 @@ void Label::AutoHeight()
void Label::updateTextWrapper() 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) if (autoHeight)
{ {
Size.Y = lines * 12 + 3; Size.Y = lines * 12 + 3;
@ -192,28 +201,28 @@ void Label::updateSelection()
if (selectionIndexH.raw_index < 0) selectionIndexH = textWrapper.IndexBegin(); if (selectionIndexH.raw_index < 0) selectionIndexH = textWrapper.IndexBegin();
if (selectionIndexH.raw_index > (int)text.length()) selectionIndexH = textWrapper.IndexEnd(); if (selectionIndexH.raw_index > (int)text.length()) selectionIndexH = textWrapper.IndexEnd();
displayTextWithSelection = textWrapper.WrappedText(); displayTextWithSelection = displayTextWrapper.WrappedText();
if (HasSelection()) if (HasSelection())
{ {
displayTextWithSelection.Insert(selectionIndexL.wrapped_index, "\x01"); displayTextWithSelection.Insert(displayTextWrapper.Clear2Index(selectionIndexL.clear_index).wrapped_index, "\x01");
displayTextWithSelection.Insert(selectionIndexH.wrapped_index + 1, "\x01"); displayTextWithSelection.Insert(displayTextWrapper.Clear2Index(selectionIndexH.clear_index).wrapped_index + 1, "\x01");
} }
} }
// void Label::SetDisplayText(String newText) void Label::SetDisplayText(String newText)
// { {
// displayText = newText; displayText = newText;
// ClearSelection(); ClearSelection();
// updateTextWrapper(); updateTextWrapper();
// updateSelection(); updateSelection();
// TextPosition(textWrapper.WrappedText()); TextPosition(displayTextWrapper.WrappedText());
// } }
void Label::Draw(const Point& screenPos) void Label::Draw(const Point& screenPos)
{ {
if (!drawn) if (!drawn)
{ {
TextPosition(textWrapper.WrappedText()); TextPosition(displayTextWrapper.WrappedText());
updateTextWrapper(); updateTextWrapper();
updateSelection(); updateSelection();
drawn = true; drawn = true;
@ -222,11 +231,11 @@ void Label::Draw(const Point& screenPos)
int selectionXL; int selectionXL;
int selectionYL; int selectionYL;
int selectionLineL = textWrapper.Index2Point(selectionIndexL, selectionXL, selectionYL); int selectionLineL = displayTextWrapper.Index2Point(selectionIndexL, selectionXL, selectionYL);
int selectionXH; int selectionXH;
int selectionYH; int selectionYH;
int selectionLineH = textWrapper.Index2Point(selectionIndexH, selectionXH, selectionYH); int selectionLineH = displayTextWrapper.Index2Point(selectionIndexH, selectionXH, selectionYH);
if (HasSelection()) if (HasSelection())
{ {

View File

@ -16,6 +16,11 @@ namespace ui
String displayTextWithSelection; String displayTextWithSelection;
String text; String text;
TextWrapper textWrapper;
String displayText;
TextWrapper displayTextWrapper;
Colour textColour; Colour textColour;
TextWrapper::Index selectionIndex0; TextWrapper::Index selectionIndex0;
TextWrapper::Index selectionIndex1; TextWrapper::Index selectionIndex1;
@ -32,7 +37,6 @@ namespace ui
int getLowerSelectionBound(); int getLowerSelectionBound();
int getHigherSelectionBound(); int getHigherSelectionBound();
TextWrapper textWrapper;
void copySelection(); void copySelection();
public: public:
@ -44,6 +48,7 @@ namespace ui
void SetMultiline(bool status); void SetMultiline(bool status);
virtual void SetText(String text); virtual void SetText(String text);
virtual void SetDisplayText(String text);
virtual String GetText(); virtual String GetText();
bool HasSelection(); bool HasSelection();

View File

@ -17,7 +17,8 @@ namespace ui
{ {
String::value_type character; String::value_type character;
int width; int width;
std::iterator_traits<String::iterator>::difference_type position; int raw_index;
int clear_index;
bool wraps; bool wraps;
}; };
int line_width = 0; int line_width = 0;
@ -27,14 +28,16 @@ namespace ui
int word_width; int word_width;
int lines = 1; int lines = 1;
int char_width; 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) if (do_wrapping && width_to_consider + char_width > max_width)
{ {
records.push_back(wrap_record{ records.push_back(wrap_record{
'\n', // character; makes the line wrap when rendered '\n', // character; makes the line wrap when rendered
0, // width; fools the clickmap generator into not seeing this newline 0, // width; fools the clickmap generator into not seeing this newline
0, // position; the clickmap generator is fooled, this can be anything 0, // position; the clickmap generator is fooled, this can be anything
0,
true // signal the end of the line to the clickmap generator true // signal the end of the line to the clickmap generator
}); });
line_width = 0; line_width = 0;
@ -66,12 +69,14 @@ namespace ui
records.push_back(wrap_record{ records.push_back(wrap_record{
*it, *it,
char_width, char_width,
it - text.begin(), (int)(it - text.begin()),
clear_count,
false false
}); });
line_width += char_width; line_width += char_width;
} }
word_begins_at = -1; // reset word state word_begins_at = -1; // reset word state
++clear_count;
break; break;
// add more supported linebreaks here // add more supported linebreaks here
@ -79,12 +84,14 @@ namespace ui
records.push_back(wrap_record{ records.push_back(wrap_record{
*it, // character; makes the line wrap when rendered *it, // character; makes the line wrap when rendered
max_width - line_width, // width; make it span all the way to the end 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 true // signal the end of the line to the clickmap generator
}); });
lines += 1; lines += 1;
line_width = 0; line_width = 0;
word_begins_at = -1; // reset word state word_begins_at = -1; // reset word state
++clear_count;
break; break;
default: default:
@ -101,6 +108,7 @@ namespace ui
*it, // character; forward the sequence to the output *it, // character; forward the sequence to the output
0, // width; fools the clickmap generator into not seeing this sequence 0, // width; fools the clickmap generator into not seeing this sequence
0, // position; the clickmap generator is fooled, this can be anything 0, // position; the clickmap generator is fooled, this can be anything
0,
false // signal nothing to the clickmap generator false // signal nothing to the clickmap generator
}); });
} }
@ -114,24 +122,6 @@ namespace ui
word_width = 0; 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)) if (wrap_if_needed(word_width))
{ {
word_begins_at = records.size(); word_begins_at = records.size();
@ -160,11 +150,13 @@ namespace ui
records.push_back(wrap_record{ records.push_back(wrap_record{
*it, // character; make the line wrap with *it *it, // character; make the line wrap with *it
char_width, // width; make it span all the way to the end 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 false // signal nothing to the clickmap generator
}); });
word_width += char_width; word_width += char_width;
line_width += char_width; line_width += char_width;
++clear_count;
switch (*it) switch (*it)
{ {
@ -192,7 +184,7 @@ namespace ui
int counter = 0; int counter = 0;
for (auto const &record : records) 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; ++counter;
x += record.width; x += record.width;
if (record.wraps) if (record.wraps)
@ -203,6 +195,7 @@ namespace ui
wrapped_text.append(1, record.character); wrapped_text.append(1, record.character);
} }
clear_text_size = clear_count;
wrapped_lines = lines; wrapped_lines = lines;
return lines; return lines;
} }
@ -291,4 +284,20 @@ namespace ui
} }
return IndexEnd(); return IndexEnd();
} }
TextWrapper::Index TextWrapper::Clear2Index(int clear_index) const
{
if (clear_index < 0)
{
return IndexBegin();
}
for (auto const &region : regions)
{
if (region.index.clear_index >= clear_index)
{
return region.index;
}
}
return IndexEnd();
}
} }

View File

@ -14,10 +14,12 @@ namespace ui
{ {
int raw_index; int raw_index;
int wrapped_index; int wrapped_index;
int clear_index;
}; };
private: private:
int raw_text_size; int raw_text_size;
int clear_text_size;
String wrapped_text; String wrapped_text;
struct clickmap_region struct clickmap_region
{ {
@ -30,6 +32,7 @@ namespace ui
public: public:
int Update(String const &text, bool do_wrapping, int max_width); int Update(String const &text, bool do_wrapping, int max_width);
Index Raw2Index(int raw_index) const; Index Raw2Index(int raw_index) const;
Index Clear2Index(int clear_index) const;
Index Point2Index(int x, int y) const; Index Point2Index(int x, int y) const;
int Index2Point(Index index, int &x, int &y) const; int Index2Point(Index index, int &x, int &y) const;
@ -40,12 +43,12 @@ namespace ui
Index IndexBegin() const Index IndexBegin() const
{ {
return Index{ 0, 0 }; return Index{ 0, 0, 0 };
} }
Index IndexEnd() const Index IndexEnd() const
{ {
return Index{ raw_text_size, (int)wrapped_text.size() }; return Index{ raw_text_size, (int)wrapped_text.size(), clear_text_size };
} }
}; };
} }

View File

@ -171,7 +171,7 @@ void Textbox::cutSelection()
updateTextWrapper(); updateTextWrapper();
updateSelection(); updateSelection();
TextPosition(text); TextPosition(displayTextWrapper.WrappedText());
if(cursor) if(cursor)
{ {
@ -241,7 +241,7 @@ void Textbox::pasteIntoSelection()
updateTextWrapper(); updateTextWrapper();
updateSelection(); updateSelection();
TextPosition(textWrapper.WrappedText()); TextPosition(displayTextWrapper.WrappedText());
if(cursor) if(cursor)
{ {
@ -459,7 +459,7 @@ void Textbox::AfterTextChange(bool changed)
updateTextWrapper(); updateTextWrapper();
updateSelection(); updateSelection();
TextPosition(textWrapper.WrappedText()); TextPosition(displayTextWrapper.WrappedText());
if(cursor) if(cursor)
{ {