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_; }
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()));
}

View File

@ -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())
{

View File

@ -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();

View File

@ -17,7 +17,8 @@ namespace ui
{
String::value_type character;
int width;
std::iterator_traits<String::iterator>::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 &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 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 };
}
};
}

View File

@ -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)
{