mirror of
https://github.com/RGBCube/serenity
synced 2025-05-19 23:35:08 +00:00
GTextEditor: Let's use a Vector for the line backing store.
I'm eventually gonna want to replace this with something more clever, like a automagically splicing vector or something, but for now, at least we move away from immutable Strings.
This commit is contained in:
parent
a21ecd440a
commit
ce35cddb1b
4 changed files with 36 additions and 17 deletions
|
@ -112,7 +112,7 @@ void GTextEditor::paint_event(GPaintEvent& event)
|
||||||
line_rect.set_width(exposed_width);
|
line_rect.set_width(exposed_width);
|
||||||
if (i == m_cursor.line() && is_focused())
|
if (i == m_cursor.line() && is_focused())
|
||||||
painter.fill_rect(line_rect, Color(230, 230, 230));
|
painter.fill_rect(line_rect, Color(230, 230, 230));
|
||||||
painter.draw_text(line_rect, line.text(), TextAlignment::CenterLeft, Color::Black);
|
painter.draw_text(line_rect, line.characters(), line.length(), TextAlignment::CenterLeft, Color::Black);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_focused() && m_cursor_state)
|
if (is_focused() && m_cursor_state)
|
||||||
|
@ -176,9 +176,17 @@ void GTextEditor::keydown_event(GKeyEvent& event)
|
||||||
set_cursor(line_count() - 1, m_lines[line_count() - 1].length());
|
set_cursor(line_count() - 1, m_lines[line_count() - 1].length());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!event.text().is_empty())
|
||||||
|
insert_at_cursor(event.text()[0]);
|
||||||
|
|
||||||
return GWidget::keydown_event(event);
|
return GWidget::keydown_event(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GTextEditor::insert_at_cursor(char ch)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
Rect GTextEditor::visible_content_rect() const
|
Rect GTextEditor::visible_content_rect() const
|
||||||
{
|
{
|
||||||
return {
|
return {
|
||||||
|
@ -194,7 +202,7 @@ Rect GTextEditor::cursor_content_rect() const
|
||||||
if (!m_cursor.is_valid())
|
if (!m_cursor.is_valid())
|
||||||
return { };
|
return { };
|
||||||
ASSERT(!m_lines.is_empty());
|
ASSERT(!m_lines.is_empty());
|
||||||
ASSERT(m_cursor.column() <= (current_line().text().length() + 1));
|
ASSERT(m_cursor.column() <= (current_line().length() + 1));
|
||||||
return { m_cursor.column() * glyph_width(), m_cursor.line() * line_height(), 1, line_height() };
|
return { m_cursor.column() * glyph_width(), m_cursor.line() * line_height(), 1, line_height() };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,17 +288,20 @@ void GTextEditor::timer_event(GTimerEvent&)
|
||||||
update_cursor();
|
update_cursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GTextEditor::Line::Line()
|
||||||
|
{
|
||||||
|
m_text.append(0);
|
||||||
|
}
|
||||||
|
|
||||||
void GTextEditor::Line::set_text(const String& text)
|
void GTextEditor::Line::set_text(const String& text)
|
||||||
{
|
{
|
||||||
if (text == m_text)
|
if (text.length() == length() && !memcmp(text.characters(), characters(), length()))
|
||||||
return;
|
return;
|
||||||
m_text = text;
|
m_text.resize(text.length() + 1);
|
||||||
m_cached_width = -1;
|
memcpy(m_text.data(), text.characters(), text.length() + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int GTextEditor::Line::width(const Font& font) const
|
int GTextEditor::Line::width(const Font& font) const
|
||||||
{
|
{
|
||||||
if (m_cached_width < 0)
|
return font.glyph_width('x') * length();
|
||||||
m_cached_width = font.width(m_text);
|
|
||||||
return m_cached_width;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,18 +57,20 @@ private:
|
||||||
virtual void timer_event(GTimerEvent&) override;
|
virtual void timer_event(GTimerEvent&) override;
|
||||||
virtual bool accepts_focus() const override { return true; }
|
virtual bool accepts_focus() const override { return true; }
|
||||||
|
|
||||||
|
void insert_at_cursor(char);
|
||||||
|
|
||||||
class Line {
|
class Line {
|
||||||
public:
|
public:
|
||||||
Line() { }
|
Line();
|
||||||
|
|
||||||
String text() const { return m_text; }
|
const char* characters() const { return m_text.data(); }
|
||||||
int length() const { return m_text.length(); }
|
int length() const { return m_text.size() - 1; }
|
||||||
int width(const Font&) const;
|
int width(const Font&) const;
|
||||||
void set_text(const String&);
|
void set_text(const String&);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
String m_text;
|
// NOTE: This vector is null terminated.
|
||||||
mutable int m_cached_width { -1 };
|
Vector<char> m_text;
|
||||||
};
|
};
|
||||||
|
|
||||||
void update_scrollbar_ranges();
|
void update_scrollbar_ranges();
|
||||||
|
|
|
@ -323,7 +323,7 @@ void Painter::blit(const Point& position, const GraphicsBitmap& source, const Re
|
||||||
draw_bitmap(point, font().glyph_bitmap(ch), color);
|
draw_bitmap(point, font().glyph_bitmap(ch), color);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Painter::draw_text(const Rect& rect, const String& text, TextAlignment alignment, Color color)
|
void Painter::draw_text(const Rect& rect, const char* text, int length, TextAlignment alignment, Color color)
|
||||||
{
|
{
|
||||||
Point point;
|
Point point;
|
||||||
|
|
||||||
|
@ -343,8 +343,8 @@ void Painter::draw_text(const Rect& rect, const String& text, TextAlignment alig
|
||||||
}
|
}
|
||||||
|
|
||||||
int space_width = font().glyph_width(' ') + font().glyph_spacing();
|
int space_width = font().glyph_width(' ') + font().glyph_spacing();
|
||||||
for (ssize_t i = 0; i < text.length(); ++i) {
|
for (ssize_t i = 0; i < length; ++i) {
|
||||||
byte ch = text[i];
|
char ch = text[i];
|
||||||
if (ch == ' ') {
|
if (ch == ' ') {
|
||||||
point.move_by(space_width, 0);
|
point.move_by(space_width, 0);
|
||||||
continue;
|
continue;
|
||||||
|
@ -354,6 +354,11 @@ void Painter::draw_text(const Rect& rect, const String& text, TextAlignment alig
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Painter::draw_text(const Rect& rect, const String& text, TextAlignment alignment, Color color)
|
||||||
|
{
|
||||||
|
draw_text(rect, text.characters(), text.length(), alignment, color);
|
||||||
|
}
|
||||||
|
|
||||||
void Painter::set_pixel(const Point& p, Color color)
|
void Painter::set_pixel(const Point& p, Color color)
|
||||||
{
|
{
|
||||||
auto point = p;
|
auto point = p;
|
||||||
|
|
|
@ -35,6 +35,7 @@ public:
|
||||||
void blit(const Point&, const GraphicsBitmap&, const Rect& src_rect);
|
void blit(const Point&, const GraphicsBitmap&, const Rect& src_rect);
|
||||||
void blit_with_opacity(const Point&, const GraphicsBitmap&, const Rect& src_rect, float opacity);
|
void blit_with_opacity(const Point&, const GraphicsBitmap&, const Rect& src_rect, float opacity);
|
||||||
|
|
||||||
|
void draw_text(const Rect&, const char* text, int length, TextAlignment = TextAlignment::TopLeft, Color = Color());
|
||||||
void draw_text(const Rect&, const String&, TextAlignment = TextAlignment::TopLeft, Color = Color());
|
void draw_text(const Rect&, const String&, TextAlignment = TextAlignment::TopLeft, Color = Color());
|
||||||
void draw_glyph(const Point&, char, Color);
|
void draw_glyph(const Point&, char, Color);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue