Using new RichTextBox instead of CollabTextBox in program. Fixes still needed to work properly

This commit is contained in:
Yousef Khadadeh 2025-10-20 17:30:36 +03:00
parent ec68dd9b71
commit 4db5838a64
18 changed files with 157 additions and 1441 deletions

View file

@ -59,8 +59,10 @@ void RichTextBox::process_key_input(Cursor& cur, InputKey in, bool ctrl, bool sh
cur.selectionEndPos = cur.selectionBeginPos = cur.pos = remove(cur.pos, move(Movement::RIGHT, cur.pos));
break;
case InputKey::ENTER:
if(newlinesAllowed)
process_text_input(cur, "\n");
process_text_input(cur, "\n");
break;
case InputKey::TAB:
process_text_input(cur, "\t");
break;
case InputKey::SELECT_ALL:
cur.selectionBeginPos = {0, 0};
@ -214,6 +216,10 @@ RichTextBox::TextPosition RichTextBox::get_text_pos_closest_to_point(Vector2f po
return TextPosition{0, pIndex};
}
std::string RichTextBox::get_string() {
return get_text_between({0, 0}, move(RichTextBox::Movement::END, {0, 0}));
}
std::string RichTextBox::get_text_between(TextPosition p1, TextPosition p2) {
p1 = move(Movement::NOWHERE, p1);
p2 = move(Movement::NOWHERE, p2);
@ -349,11 +355,10 @@ RichTextBox::TextPosition RichTextBox::move(Movement movement, TextPosition pos,
break;
}
case Movement::LEFT_WORD: {
TextPosition endPos = move(Movement::END, {0, 0});
if(pos == TextPosition{0, 0})
break;
std::string fullText = get_text_between({0, 0}, endPos);
std::string fullText = get_string();
size_t bytePosInFullText = get_byte_pos_from_text_pos(pos);
auto u = SkUnicodes::ICU::Make();
@ -380,7 +385,7 @@ RichTextBox::TextPosition RichTextBox::move(Movement movement, TextPosition pos,
if(pos == endPos)
break;
std::string fullText = get_text_between({0, 0}, endPos);
std::string fullText = get_string();
size_t bytePosInFullText = get_byte_pos_from_text_pos(pos);
auto u = SkUnicodes::ICU::Make();
@ -421,7 +426,7 @@ void RichTextBox::set_width(float newWidth) {
}
void RichTextBox::set_allow_newlines(bool allow) {
newlinesAllowed = true;
newlinesAllowed = allow;
}
void RichTextBox::set_font_collection(const sk_sp<skia::textlayout::FontCollection>& fC) {
@ -452,16 +457,26 @@ void RichTextBox::rebuild() {
}
}
void RichTextBox::set_tab_space_width(unsigned newTabWidth) {
tabWidth = newTabWidth;
}
RichTextBox::TextPosition RichTextBox::insert(TextPosition pos, std::string_view textToInsert) {
pos = move(Movement::NOWHERE, pos);
for(char c : textToInsert) {
if(c == '\n') {
paragraphs.insert(paragraphs.begin() + pos.fParagraphIndex + 1, ParagraphData{});
paragraphs[pos.fParagraphIndex + 1].text = paragraphs[pos.fParagraphIndex].text.substr(pos.fTextByteIndex, paragraphs[pos.fParagraphIndex].text.size() - pos.fTextByteIndex);
paragraphs[pos.fParagraphIndex].text.erase(pos.fTextByteIndex, paragraphs[pos.fParagraphIndex].text.size() - pos.fTextByteIndex);
pos.fParagraphIndex++;
pos.fTextByteIndex = 0;
if(newlinesAllowed) {
paragraphs.insert(paragraphs.begin() + pos.fParagraphIndex + 1, ParagraphData{});
paragraphs[pos.fParagraphIndex + 1].text = paragraphs[pos.fParagraphIndex].text.substr(pos.fTextByteIndex, paragraphs[pos.fParagraphIndex].text.size() - pos.fTextByteIndex);
paragraphs[pos.fParagraphIndex].text.erase(pos.fTextByteIndex, paragraphs[pos.fParagraphIndex].text.size() - pos.fTextByteIndex);
pos.fParagraphIndex++;
pos.fTextByteIndex = 0;
}
}
else if(c == '\t') {
paragraphs[pos.fParagraphIndex].text.insert(pos.fTextByteIndex, std::string(tabWidth, ' '));
pos.fTextByteIndex += tabWidth;
}
else {
paragraphs[pos.fParagraphIndex].text.insert(paragraphs[pos.fParagraphIndex].text.begin() + pos.fTextByteIndex, c);
@ -571,7 +586,6 @@ void RichTextBox::rects_between_text_positions_func(TextPosition p1, TextPositio
}
}
void RichTextBox::paint(SkCanvas* canvas, const PaintOpts& paintOpts) {
rebuild();

View file

@ -36,6 +36,9 @@ class RichTextBox {
TextPosition pos = {0, 0};
TextPosition selectionBeginPos = {0, 0};
TextPosition selectionEndPos = {0, 0};
template <typename Archive> void serialize(Archive& a) {
a(pos, selectionBeginPos, selectionEndPos);
}
std::optional<float> previousX;
};
@ -62,6 +65,7 @@ class RichTextBox {
BACKSPACE,
DELETE,
ENTER,
TAB,
SELECT_ALL
};
@ -70,8 +74,10 @@ class RichTextBox {
std::string process_copy(Cursor& cur);
std::string process_cut(Cursor& cur);
std::string get_text_between(TextPosition p1, TextPosition p2);
std::string get_string();
void set_tab_space_width(unsigned newTabWidth);
void process_text_input(Cursor& cur, const std::string& in);
private:
static size_t count_grapheme(const std::string& text);
static size_t next_grapheme(const std::string& text, size_t textBytePos);
@ -91,6 +97,7 @@ class RichTextBox {
float width = 0.0f;
float fontSize = 0.0f;
bool needsRebuild = true;
unsigned tabWidth = 8;
sk_sp<skia::textlayout::FontCollection> fontCollection;
struct ParagraphData {