mirror of
https://github.com/RGBCube/serenity
synced 2025-05-20 13:55:08 +00:00
LibGUI: Move GTextDocument out of GTextEditor
The idea here is to decouple the document from the editor widget so you could have multiple editors being views onto the same document. This doesn't work yet, since the document and editor are coupled in various ways still (including a per-line back-pointer to the editor.)
This commit is contained in:
parent
1bcbc3f827
commit
f1c6193d6d
6 changed files with 302 additions and 240 deletions
113
Libraries/LibGUI/GTextDocument.cpp
Normal file
113
Libraries/LibGUI/GTextDocument.cpp
Normal file
|
@ -0,0 +1,113 @@
|
|||
#include <LibGUI/GTextDocument.h>
|
||||
#include <ctype.h>
|
||||
|
||||
GTextDocument::GTextDocument(GTextEditor& editor)
|
||||
: m_editor(editor)
|
||||
{
|
||||
m_lines.append(make<GTextDocumentLine>(m_editor));
|
||||
}
|
||||
|
||||
void GTextDocument::set_text(const StringView& text)
|
||||
{
|
||||
m_spans.clear();
|
||||
m_lines.clear();
|
||||
int start_of_current_line = 0;
|
||||
|
||||
auto add_line = [&](int current_position) {
|
||||
int line_length = current_position - start_of_current_line;
|
||||
auto line = make<GTextDocumentLine>(m_editor);
|
||||
if (line_length)
|
||||
line->set_text(text.substring_view(start_of_current_line, current_position - start_of_current_line));
|
||||
m_lines.append(move(line));
|
||||
start_of_current_line = current_position + 1;
|
||||
};
|
||||
int i = 0;
|
||||
for (i = 0; i < text.length(); ++i) {
|
||||
if (text[i] == '\n')
|
||||
add_line(i);
|
||||
}
|
||||
add_line(i);
|
||||
}
|
||||
|
||||
int GTextDocumentLine::first_non_whitespace_column() const
|
||||
{
|
||||
for (int i = 0; i < length(); ++i) {
|
||||
if (!isspace(m_text[i]))
|
||||
return i;
|
||||
}
|
||||
return length();
|
||||
}
|
||||
|
||||
GTextDocumentLine::GTextDocumentLine(GTextEditor& editor)
|
||||
: m_editor(editor)
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
GTextDocumentLine::GTextDocumentLine(GTextEditor& editor, const StringView& text)
|
||||
: m_editor(editor)
|
||||
{
|
||||
set_text(text);
|
||||
}
|
||||
|
||||
void GTextDocumentLine::clear()
|
||||
{
|
||||
m_text.clear();
|
||||
m_text.append(0);
|
||||
}
|
||||
|
||||
void GTextDocumentLine::set_text(const StringView& text)
|
||||
{
|
||||
if (text.length() == length() && !memcmp(text.characters_without_null_termination(), characters(), length()))
|
||||
return;
|
||||
if (text.is_empty()) {
|
||||
clear();
|
||||
return;
|
||||
}
|
||||
m_text.resize(text.length() + 1);
|
||||
memcpy(m_text.data(), text.characters_without_null_termination(), text.length() + 1);
|
||||
}
|
||||
|
||||
void GTextDocumentLine::append(const char* characters, int length)
|
||||
{
|
||||
int old_length = m_text.size() - 1;
|
||||
m_text.resize(m_text.size() + length);
|
||||
memcpy(m_text.data() + old_length, characters, length);
|
||||
m_text.last() = 0;
|
||||
}
|
||||
|
||||
void GTextDocumentLine::append(char ch)
|
||||
{
|
||||
insert(length(), ch);
|
||||
}
|
||||
|
||||
void GTextDocumentLine::prepend(char ch)
|
||||
{
|
||||
insert(0, ch);
|
||||
}
|
||||
|
||||
void GTextDocumentLine::insert(int index, char ch)
|
||||
{
|
||||
if (index == length()) {
|
||||
m_text.last() = ch;
|
||||
m_text.append(0);
|
||||
} else {
|
||||
m_text.insert(index, move(ch));
|
||||
}
|
||||
}
|
||||
|
||||
void GTextDocumentLine::remove(int index)
|
||||
{
|
||||
if (index == length()) {
|
||||
m_text.take_last();
|
||||
m_text.last() = 0;
|
||||
} else {
|
||||
m_text.remove(index);
|
||||
}
|
||||
}
|
||||
|
||||
void GTextDocumentLine::truncate(int length)
|
||||
{
|
||||
m_text.resize(length + 1);
|
||||
m_text.last() = 0;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue