Created RichText namespace, and tweaked scrollbar behaviour
This commit is contained in:
parent
e0143f49f0
commit
435d9346a9
17 changed files with 163 additions and 139 deletions
|
|
@ -53,8 +53,9 @@ set(sources "src/main.cpp"
|
|||
"src/ResourceDisplay/FileResourceDisplay.cpp"
|
||||
"src/Server/MainServer.cpp"
|
||||
"src/Server/ServerData.cpp"
|
||||
"src/RichTextBox/RichTextBox.cpp"
|
||||
"src/RichTextBox/TextStyleModifier.cpp"
|
||||
"src/RichText/TextBox.cpp"
|
||||
"src/RichText/TextStyleModifier.cpp"
|
||||
"src/RichText/ParagraphStyleData.cpp"
|
||||
"src/DrawingProgram/DrawingProgramCache.cpp"
|
||||
"src/DrawingProgram/DrawingProgram.cpp"
|
||||
"src/DrawingProgram/BrushTool.cpp"
|
||||
|
|
|
|||
|
|
@ -9,9 +9,11 @@
|
|||
#include "../DrawCollision.hpp"
|
||||
#endif
|
||||
|
||||
using namespace RichText;
|
||||
|
||||
DrawTextBox::DrawTextBox():
|
||||
textBox(std::make_shared<RichTextBox>()),
|
||||
cursor(std::make_shared<RichTextBox::Cursor>())
|
||||
textBox(std::make_shared<TextBox>()),
|
||||
cursor(std::make_shared<TextBox::Cursor>())
|
||||
{
|
||||
skia::textlayout::TextStyle tStyle;
|
||||
textBox->set_initial_text_style(tStyle);
|
||||
|
|
@ -30,7 +32,7 @@ void DrawTextBox::save(cereal::PortableBinaryOutputArchive& a) const {
|
|||
}
|
||||
|
||||
void DrawTextBox::load(cereal::PortableBinaryInputArchive& a) {
|
||||
RichTextBox::RichTextData richText;
|
||||
TextData richText;
|
||||
a(d.editing, d.p1, d.p2, richText, *cursor);
|
||||
textBox->set_rich_text_data(richText);
|
||||
}
|
||||
|
|
@ -78,7 +80,7 @@ void DrawTextBox::draw(SkCanvas* canvas, const DrawData& drawData) {
|
|||
canvas->clipRect(clipR);
|
||||
canvas->translate(d.p1.x(), d.p1.y());
|
||||
|
||||
RichTextBox::PaintOpts paintOpts;
|
||||
TextBox::PaintOpts paintOpts;
|
||||
paintOpts.cursorColor = {0.7f, 0.7f, 1.0f};
|
||||
if(d.editing && cursor)
|
||||
paintOpts.cursor = *cursor;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
#include "../SharedTypes.hpp"
|
||||
#include "DrawComponent.hpp"
|
||||
#include "../CoordSpaceHelper.hpp"
|
||||
#include "../RichTextBox/RichTextBox.hpp"
|
||||
#include "../RichText/TextBox.hpp"
|
||||
|
||||
#ifndef IS_SERVER
|
||||
#include <include/core/SkPath.h>
|
||||
|
|
@ -39,8 +39,8 @@ class DrawTextBox : public DrawComponent {
|
|||
|
||||
virtual SCollision::AABB<float> get_obj_coord_bounds() const override;
|
||||
|
||||
std::shared_ptr<RichTextBox> textBox;
|
||||
std::shared_ptr<RichTextBox::Cursor> cursor;
|
||||
std::shared_ptr<RichText::TextBox> textBox;
|
||||
std::shared_ptr<RichText::TextBox::Cursor> cursor;
|
||||
SCollision::BVHContainer<float> collisionTree;
|
||||
#endif
|
||||
};
|
||||
|
|
|
|||
|
|
@ -14,11 +14,14 @@
|
|||
#include <memory>
|
||||
#include "EditTool.hpp"
|
||||
|
||||
using namespace RichText;
|
||||
|
||||
TextBoxEditTool::TextBoxEditTool(DrawingProgram& initDrawP):
|
||||
DrawingProgramEditToolBase(initDrawP)
|
||||
{}
|
||||
|
||||
bool TextBoxEditTool::edit_gui(const std::shared_ptr<DrawComponent>& comp) {
|
||||
|
||||
std::shared_ptr<DrawTextBox> a = std::static_pointer_cast<DrawTextBox>(comp);
|
||||
Toolbar& t = drawP.world.main.toolbar;
|
||||
|
||||
|
|
@ -117,10 +120,10 @@ uint8_t TextBoxEditTool::get_new_decoration_value() {
|
|||
}
|
||||
|
||||
void TextBoxEditTool::set_mods_at_selection(const std::shared_ptr<DrawTextBox>& a) {
|
||||
RichTextBox::TextPosition start = std::min(a->cursor->selectionBeginPos, a->cursor->selectionEndPos);
|
||||
RichTextBox::TextPosition end = std::max(a->cursor->selectionBeginPos, a->cursor->selectionEndPos);
|
||||
TextPosition start = std::min(a->cursor->selectionBeginPos, a->cursor->selectionEndPos);
|
||||
TextPosition end = std::max(a->cursor->selectionBeginPos, a->cursor->selectionEndPos);
|
||||
if(start == end)
|
||||
currentMods = a->textBox->get_mods_used_at_pos(a->textBox->move(RichTextBox::Movement::LEFT, start));
|
||||
currentMods = a->textBox->get_mods_used_at_pos(a->textBox->move(TextBox::Movement::LEFT, start));
|
||||
else
|
||||
currentMods = a->textBox->get_mods_used_at_pos(start);
|
||||
}
|
||||
|
|
@ -131,7 +134,7 @@ void TextBoxEditTool::commit_edit_updates(const std::shared_ptr<DrawComponent>&
|
|||
a->d.editing = false;
|
||||
auto pData = std::any_cast<TextBoxEditToolAllData>(prevData);
|
||||
TextBoxEditToolAllData cData = get_all_data(a);
|
||||
RichTextBox::RichTextData richText = a->textBox->get_rich_text_data();
|
||||
TextData richText = a->textBox->get_rich_text_data();
|
||||
drawP.world.undo.push(UndoManager::UndoRedoPair{
|
||||
[&drawP = drawP, a, pData]() {
|
||||
a->d = pData.textboxData;
|
||||
|
|
@ -163,7 +166,7 @@ void TextBoxEditTool::edit_start(EditTool& editTool, const std::shared_ptr<DrawC
|
|||
std::shared_ptr<DrawTextBox> a = std::static_pointer_cast<DrawTextBox>(comp);
|
||||
auto& cur = a->cursor;
|
||||
auto& textbox = a->textBox;
|
||||
cur = std::make_shared<RichTextBox::Cursor>();
|
||||
cur = std::make_shared<TextBox::Cursor>();
|
||||
Vector2f textSelectPos = a->get_mouse_pos(drawP);
|
||||
textbox->process_mouse_left_button(*cur, textSelectPos, true, false, false);
|
||||
prevData = get_all_data(a);
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ class TextBoxEditTool : public DrawingProgramEditToolBase {
|
|||
private:
|
||||
struct TextBoxEditToolAllData {
|
||||
DrawTextBox::Data textboxData;
|
||||
RichTextBox::RichTextData richText;
|
||||
RichText::TextData richText;
|
||||
};
|
||||
|
||||
uint32_t newFontSize = 15;
|
||||
|
|
@ -31,7 +31,7 @@ class TextBoxEditTool : public DrawingProgramEditToolBase {
|
|||
|
||||
uint8_t get_new_decoration_value();
|
||||
void set_mods_at_selection(const std::shared_ptr<DrawTextBox>& a);
|
||||
TextStyleModifier::ModifierMap currentMods;
|
||||
RichText::TextStyleModifier::ModifierMap currentMods;
|
||||
|
||||
std::vector<std::string> sortedFontList;
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
#include <Helpers/SCollision.hpp>
|
||||
#include <Helpers/Serializers.hpp>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include "../../RichTextBox/RichTextBox.hpp"
|
||||
#include "../../RichText/TextBox.hpp"
|
||||
|
||||
using namespace Eigen;
|
||||
|
||||
|
|
@ -103,7 +103,7 @@ struct UpdateInputData {
|
|||
std::optional<std::string> textOut;
|
||||
} clipboard;
|
||||
|
||||
std::function<void(std::shared_ptr<RichTextBox>, std::shared_ptr<RichTextBox::Cursor>)> richTextBoxEdit;
|
||||
std::function<void(std::shared_ptr<RichText::TextBox>, std::shared_ptr<RichText::TextBox::Cursor>)> richTextBoxEdit;
|
||||
|
||||
SkFont get_font(float fSize) const;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
#include "Element.hpp"
|
||||
#include "../../RichTextBox/RichTextBox.hpp"
|
||||
#include "../../RichText/TextBox.hpp"
|
||||
#include <limits>
|
||||
#include <modules/skparagraph/include/TextStyle.h>
|
||||
|
||||
|
|
@ -73,7 +73,7 @@ template <typename T> class TextBox : public Element {
|
|||
|
||||
canvas->translate(bb.min.x() + 2.0f, bb.min.y());
|
||||
|
||||
RichTextBox::PaintOpts paintOpts;
|
||||
RichText::TextBox::PaintOpts paintOpts;
|
||||
if(selection.selected)
|
||||
paintOpts.cursor = *cur;
|
||||
paintOpts.cursorColor = {io.theme->fillColor1.fR, io.theme->fillColor1.fG, io.theme->fillColor1.fB};
|
||||
|
|
@ -97,11 +97,11 @@ template <typename T> class TextBox : public Element {
|
|||
if(data && (*data == oldData) && !reallyForce && textbox && cur)
|
||||
return;
|
||||
|
||||
textbox = std::make_shared<RichTextBox>();
|
||||
textbox = std::make_shared<RichText::TextBox>();
|
||||
textbox->set_font_collection(io.fontCollection);
|
||||
textbox->set_allow_newlines(!singleLine);
|
||||
|
||||
cur = std::make_shared<RichTextBox::Cursor>();
|
||||
cur = std::make_shared<RichText::TextBox::Cursor>();
|
||||
|
||||
if(data) {
|
||||
cur->pos = cur->selectionBeginPos = cur->selectionEndPos = textbox->insert({0, 0}, toStr(*data));
|
||||
|
|
@ -125,8 +125,8 @@ template <typename T> class TextBox : public Element {
|
|||
std::function<std::optional<T>(const std::string&)> fromStr;
|
||||
std::function<std::string(const T&)> toStr;
|
||||
|
||||
std::shared_ptr<RichTextBox> textbox;
|
||||
std::shared_ptr<RichTextBox::Cursor> cur;
|
||||
std::shared_ptr<RichText::TextBox> textbox;
|
||||
std::shared_ptr<RichText::TextBox::Cursor> cur;
|
||||
|
||||
SCollision::AABB<float> bb;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -669,7 +669,6 @@ void GUIManager::scroll_bar_area(const std::string& id, const std::function<void
|
|||
float currentScrollPos = 0.0f;
|
||||
bool isMoving = false;
|
||||
|
||||
bool clickedOnScroller = false;
|
||||
float scrollerStartPos;
|
||||
float mouseStartPos;
|
||||
|
||||
|
|
@ -749,20 +748,17 @@ void GUIManager::scroll_bar_area(const std::string& id, const std::function<void
|
|||
CLAY({ .layout = {.sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0)}}}) {}
|
||||
if(Clay_Hovered() && io->mouse.leftClick) {
|
||||
sD.isMoving = true;
|
||||
sD.clickedOnScroller = isHoveringOverScroller;
|
||||
if(isHoveringOverScroller) {
|
||||
if(isHoveringOverScroller)
|
||||
sD.scrollerStartPos = scrollAreaBB.y + areaAboveScrollerSize + scrollerSize * 0.5f;
|
||||
sD.mouseStartPos = io->mouse.pos.y();
|
||||
}
|
||||
else
|
||||
sD.scrollerStartPos = std::clamp(io->mouse.pos.y(), scrollAreaBB.y + scrollerSize * 0.5f, scrollAreaBB.y + scrollAreaBB.height - scrollerSize * 0.5f);
|
||||
sD.mouseStartPos = io->mouse.pos.y();
|
||||
}
|
||||
if(!io->mouse.leftHeld)
|
||||
sD.isMoving = false;
|
||||
if(sD.isMoving) {
|
||||
float newScrollPosFrac;
|
||||
if(sD.clickedOnScroller)
|
||||
newScrollPosFrac = std::clamp((sD.scrollerStartPos - (sD.mouseStartPos - io->mouse.pos.y()) - scrollAreaBB.y - scrollerSize * 0.5f) / (scrollAreaBB.height - scrollerSize), 0.0f, 1.0f);
|
||||
else
|
||||
newScrollPosFrac = std::clamp((io->mouse.pos.y() - scrollAreaBB.y - scrollerSize * 0.5f) / (scrollAreaBB.height - scrollerSize), 0.0f, 1.0f);
|
||||
newScrollPosFrac = std::clamp((sD.scrollerStartPos - (sD.mouseStartPos - io->mouse.pos.y()) - scrollAreaBB.y - scrollerSize * 0.5f) / (scrollAreaBB.height - scrollerSize), 0.0f, 1.0f);
|
||||
sD.currentScrollPos = newScrollPosFrac * (-scrollPosMax);
|
||||
}
|
||||
sD.currentScrollPos = std::clamp(sD.currentScrollPos, -scrollPosMax, 0.0f);
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ void InputManager::text_input_silence_everything() {
|
|||
text.newInput.clear();
|
||||
}
|
||||
|
||||
void InputManager::Text::set_rich_text_box_input(const std::shared_ptr<RichTextBox>& nTextBox, const std::shared_ptr<RichTextBox::Cursor>& nCursor, const std::optional<TextStyleModifier::ModifierMap>& nModMap) {
|
||||
void InputManager::Text::set_rich_text_box_input(const std::shared_ptr<RichText::TextBox>& nTextBox, const std::shared_ptr<RichText::TextBox::Cursor>& nCursor, const std::optional<RichText::TextStyleModifier::ModifierMap>& nModMap) {
|
||||
set_accepting_input();
|
||||
newTextBox = nTextBox;
|
||||
newCursor = nCursor;
|
||||
|
|
@ -219,42 +219,42 @@ void InputManager::backend_key_down_update(const SDL_KeyboardEvent& e) {
|
|||
case SDLK_UP:
|
||||
set_key_down(e, KEY_TEXT_UP);
|
||||
if(text.textBox && key(KEY_TEXT_UP).repeat)
|
||||
text.textBox->process_key_input(*text.cursor, RichTextBox::InputKey::UP, ctrl_or_meta_held(), key(KEY_GENERIC_LSHIFT).held, text.modMap);
|
||||
text.textBox->process_key_input(*text.cursor, RichText::TextBox::InputKey::UP, ctrl_or_meta_held(), key(KEY_GENERIC_LSHIFT).held, text.modMap);
|
||||
break;
|
||||
case SDLK_DOWN:
|
||||
set_key_down(e, KEY_TEXT_DOWN);
|
||||
if(text.textBox && key(KEY_TEXT_DOWN).repeat)
|
||||
text.textBox->process_key_input(*text.cursor, RichTextBox::InputKey::DOWN, ctrl_or_meta_held(), key(KEY_GENERIC_LSHIFT).held, text.modMap);
|
||||
text.textBox->process_key_input(*text.cursor, RichText::TextBox::InputKey::DOWN, ctrl_or_meta_held(), key(KEY_GENERIC_LSHIFT).held, text.modMap);
|
||||
break;
|
||||
case SDLK_LEFT:
|
||||
set_key_down(e, KEY_TEXT_LEFT);
|
||||
if(text.textBox && key(KEY_TEXT_LEFT).repeat)
|
||||
text.textBox->process_key_input(*text.cursor, RichTextBox::InputKey::LEFT, ctrl_or_meta_held(), key(KEY_GENERIC_LSHIFT).held, text.modMap);
|
||||
text.textBox->process_key_input(*text.cursor, RichText::TextBox::InputKey::LEFT, ctrl_or_meta_held(), key(KEY_GENERIC_LSHIFT).held, text.modMap);
|
||||
break;
|
||||
case SDLK_RIGHT:
|
||||
set_key_down(e, KEY_TEXT_RIGHT);
|
||||
if(text.textBox && key(KEY_TEXT_RIGHT).repeat)
|
||||
text.textBox->process_key_input(*text.cursor, RichTextBox::InputKey::RIGHT, ctrl_or_meta_held(), key(KEY_GENERIC_LSHIFT).held, text.modMap);
|
||||
text.textBox->process_key_input(*text.cursor, RichText::TextBox::InputKey::RIGHT, ctrl_or_meta_held(), key(KEY_GENERIC_LSHIFT).held, text.modMap);
|
||||
break;
|
||||
case SDLK_BACKSPACE:
|
||||
set_key_down(e, KEY_TEXT_BACKSPACE);
|
||||
if(text.textBox && key(KEY_TEXT_BACKSPACE).repeat)
|
||||
text.textBox->process_key_input(*text.cursor, RichTextBox::InputKey::BACKSPACE, ctrl_or_meta_held(), key(KEY_GENERIC_LSHIFT).held, text.modMap);
|
||||
text.textBox->process_key_input(*text.cursor, RichText::TextBox::InputKey::BACKSPACE, ctrl_or_meta_held(), key(KEY_GENERIC_LSHIFT).held, text.modMap);
|
||||
break;
|
||||
case SDLK_DELETE:
|
||||
set_key_down(e, KEY_TEXT_DELETE);
|
||||
if(text.textBox && key(KEY_TEXT_DELETE).repeat)
|
||||
text.textBox->process_key_input(*text.cursor, RichTextBox::InputKey::DELETE, ctrl_or_meta_held(), key(KEY_GENERIC_LSHIFT).held, text.modMap);
|
||||
text.textBox->process_key_input(*text.cursor, RichText::TextBox::InputKey::DELETE, ctrl_or_meta_held(), key(KEY_GENERIC_LSHIFT).held, text.modMap);
|
||||
break;
|
||||
case SDLK_HOME:
|
||||
set_key_down(e, KEY_TEXT_HOME);
|
||||
if(text.textBox && key(KEY_TEXT_HOME).repeat)
|
||||
text.textBox->process_key_input(*text.cursor, RichTextBox::InputKey::HOME, ctrl_or_meta_held(), key(KEY_GENERIC_LSHIFT).held, text.modMap);
|
||||
text.textBox->process_key_input(*text.cursor, RichText::TextBox::InputKey::HOME, ctrl_or_meta_held(), key(KEY_GENERIC_LSHIFT).held, text.modMap);
|
||||
break;
|
||||
case SDLK_END:
|
||||
set_key_down(e, KEY_TEXT_END);
|
||||
if(text.textBox && key(KEY_TEXT_END).repeat)
|
||||
text.textBox->process_key_input(*text.cursor, RichTextBox::InputKey::END, ctrl_or_meta_held(), key(KEY_GENERIC_LSHIFT).held, text.modMap);
|
||||
text.textBox->process_key_input(*text.cursor, RichText::TextBox::InputKey::END, ctrl_or_meta_held(), key(KEY_GENERIC_LSHIFT).held, text.modMap);
|
||||
break;
|
||||
case SDLK_LSHIFT:
|
||||
set_key_down(e, KEY_TEXT_SHIFT);
|
||||
|
|
@ -294,18 +294,18 @@ void InputManager::backend_key_down_update(const SDL_KeyboardEvent& e) {
|
|||
if((kMod & SDL_KMOD_GUI) || (kMod & SDL_KMOD_CTRL))
|
||||
set_key_down(e, KEY_TEXT_SELECTALL);
|
||||
if(text.textBox && key(KEY_TEXT_SELECTALL).repeat)
|
||||
text.textBox->process_key_input(*text.cursor, RichTextBox::InputKey::SELECT_ALL, ctrl_or_meta_held(), key(KEY_GENERIC_LSHIFT).held, text.modMap);
|
||||
text.textBox->process_key_input(*text.cursor, RichText::TextBox::InputKey::SELECT_ALL, ctrl_or_meta_held(), key(KEY_GENERIC_LSHIFT).held, text.modMap);
|
||||
break;
|
||||
case SDLK_RETURN: {
|
||||
set_key_down(e, KEY_TEXT_ENTER);
|
||||
if(text.textBox && key(KEY_TEXT_ENTER).repeat)
|
||||
text.textBox->process_key_input(*text.cursor, RichTextBox::InputKey::ENTER, ctrl_or_meta_held(), key(KEY_GENERIC_LSHIFT).held, text.modMap);
|
||||
text.textBox->process_key_input(*text.cursor, RichText::TextBox::InputKey::ENTER, ctrl_or_meta_held(), key(KEY_GENERIC_LSHIFT).held, text.modMap);
|
||||
break;
|
||||
}
|
||||
case SDLK_TAB: {
|
||||
set_key_down(e, KEY_TEXT_TAB);
|
||||
if(text.textBox && key(KEY_TEXT_TAB).repeat)
|
||||
text.textBox->process_key_input(*text.cursor, RichTextBox::InputKey::TAB, ctrl_or_meta_held(), key(KEY_GENERIC_LSHIFT).held, text.modMap);
|
||||
text.textBox->process_key_input(*text.cursor, RichText::TextBox::InputKey::TAB, ctrl_or_meta_held(), key(KEY_GENERIC_LSHIFT).held, text.modMap);
|
||||
break;
|
||||
}
|
||||
case SDLK_ESCAPE:
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
#pragma once
|
||||
#include <Eigen/Dense>
|
||||
#include <array>
|
||||
#include "RichTextBox/TextStyleModifier.hpp"
|
||||
#include "RichText/TextStyleModifier.hpp"
|
||||
#include "RichText/TextBox.hpp"
|
||||
#include "TimePoint.hpp"
|
||||
#include <Helpers/Hashes.hpp>
|
||||
#include <unordered_map>
|
||||
|
|
@ -11,7 +12,6 @@
|
|||
#include <SDL3/SDL.h>
|
||||
#include <SDL3/SDL_events.h>
|
||||
#include <SDL3/SDL_keycode.h>
|
||||
#include "RichTextBox/RichTextBox.hpp"
|
||||
|
||||
using namespace Eigen;
|
||||
|
||||
|
|
@ -88,17 +88,17 @@ struct InputManager {
|
|||
void set_accepting_input();
|
||||
bool get_accepting_input();
|
||||
|
||||
void set_rich_text_box_input(const std::shared_ptr<RichTextBox>& nTextBox, const std::shared_ptr<RichTextBox::Cursor>& nCursor, const std::optional<TextStyleModifier::ModifierMap>& nModMap = std::nullopt);
|
||||
void set_rich_text_box_input(const std::shared_ptr<RichText::TextBox>& nTextBox, const std::shared_ptr<RichText::TextBox::Cursor>& nCursor, const std::optional<RichText::TextStyleModifier::ModifierMap>& nModMap = std::nullopt);
|
||||
void add_text_to_textbox(const std::string& inputText);
|
||||
|
||||
private:
|
||||
std::shared_ptr<RichTextBox> textBox;
|
||||
std::shared_ptr<RichTextBox::Cursor> cursor;
|
||||
std::optional<TextStyleModifier::ModifierMap> modMap;
|
||||
std::shared_ptr<RichText::TextBox> textBox;
|
||||
std::shared_ptr<RichText::TextBox::Cursor> cursor;
|
||||
std::optional<RichText::TextStyleModifier::ModifierMap> modMap;
|
||||
|
||||
std::shared_ptr<RichTextBox> newTextBox;
|
||||
std::shared_ptr<RichTextBox::Cursor> newCursor;
|
||||
std::optional<TextStyleModifier::ModifierMap> newModMap;
|
||||
std::shared_ptr<RichText::TextBox> newTextBox;
|
||||
std::shared_ptr<RichText::TextBox::Cursor> newCursor;
|
||||
std::optional<RichText::TextStyleModifier::ModifierMap> newModMap;
|
||||
|
||||
bool acceptingInput = false;
|
||||
bool acceptingInputNew = false;
|
||||
|
|
|
|||
0
src/RichText/ParagraphStyleData.cpp
Normal file
0
src/RichText/ParagraphStyleData.cpp
Normal file
6
src/RichText/ParagraphStyleData.hpp
Normal file
6
src/RichText/ParagraphStyleData.hpp
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
struct ParagraphStyleData {
|
||||
|
||||
};
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
#include "RichTextBox.hpp"
|
||||
#include "TextBox.hpp"
|
||||
#include "TextStyleModifier.hpp"
|
||||
#include <limits>
|
||||
#include <modules/skparagraph/include/DartTypes.h>
|
||||
|
|
@ -12,7 +12,9 @@
|
|||
#include <src/base/SkUTF.h>
|
||||
#include <cereal/types/string.hpp>
|
||||
|
||||
void RichTextBox::RichTextData::save(cereal::PortableBinaryOutputArchive& a) const {
|
||||
namespace RichText {
|
||||
|
||||
void TextData::save(cereal::PortableBinaryOutputArchive& a) const {
|
||||
a(paragraphs);
|
||||
a(static_cast<uint32_t>(tStyleMods.size()));
|
||||
for(auto& [pos, modsInPos] : tStyleMods) {
|
||||
|
|
@ -22,7 +24,7 @@ void RichTextBox::RichTextData::save(cereal::PortableBinaryOutputArchive& a) con
|
|||
}
|
||||
}
|
||||
|
||||
void RichTextBox::RichTextData::load(cereal::PortableBinaryInputArchive& a) {
|
||||
void TextData::load(cereal::PortableBinaryInputArchive& a) {
|
||||
a(paragraphs);
|
||||
uint32_t tStyleModCount;
|
||||
a(tStyleModCount);
|
||||
|
|
@ -41,27 +43,27 @@ void RichTextBox::RichTextData::load(cereal::PortableBinaryInputArchive& a) {
|
|||
}
|
||||
}
|
||||
|
||||
bool RichTextBox::TextPosition::operator<(const RichTextBox::TextPosition& o) const {
|
||||
bool TextPosition::operator<(const TextPosition& o) const {
|
||||
return (this->fParagraphIndex < o.fParagraphIndex) || (this->fParagraphIndex == o.fParagraphIndex && this->fTextByteIndex < o.fTextByteIndex);
|
||||
}
|
||||
|
||||
bool RichTextBox::TextPosition::operator>(const RichTextBox::TextPosition& o) const {
|
||||
bool TextPosition::operator>(const TextPosition& o) const {
|
||||
return !(*this < o) && !(*this == o);
|
||||
}
|
||||
|
||||
bool RichTextBox::TextPosition::operator>=(const RichTextBox::TextPosition& o) const {
|
||||
bool TextPosition::operator>=(const TextPosition& o) const {
|
||||
return (*this > o) || (*this == o);
|
||||
}
|
||||
|
||||
bool RichTextBox::TextPosition::operator<=(const RichTextBox::TextPosition& o) const {
|
||||
bool TextPosition::operator<=(const TextPosition& o) const {
|
||||
return (*this < o) || (*this == o);
|
||||
}
|
||||
|
||||
RichTextBox::RichTextBox() {
|
||||
TextBox::TextBox() {
|
||||
paragraphs.emplace_back();
|
||||
}
|
||||
|
||||
void RichTextBox::process_key_input(Cursor& cur, InputKey in, bool ctrl, bool shift, const std::optional<TextStyleModifier::ModifierMap>& inputModMap) {
|
||||
void TextBox::process_key_input(Cursor& cur, InputKey in, bool ctrl, bool shift, const std::optional<TextStyleModifier::ModifierMap>& inputModMap) {
|
||||
bool moved = false;
|
||||
|
||||
switch(in) {
|
||||
|
|
@ -122,7 +124,7 @@ void RichTextBox::process_key_input(Cursor& cur, InputKey in, bool ctrl, bool sh
|
|||
inputChangedTextBox = true;
|
||||
}
|
||||
|
||||
void RichTextBox::process_mouse_left_button(Cursor& cur, const Vector2f& pos, bool clicked, bool held, bool shift) {
|
||||
void TextBox::process_mouse_left_button(Cursor& cur, const Vector2f& pos, bool clicked, bool held, bool shift) {
|
||||
if(clicked || held) {
|
||||
rebuild();
|
||||
|
||||
|
|
@ -138,11 +140,11 @@ void RichTextBox::process_mouse_left_button(Cursor& cur, const Vector2f& pos, bo
|
|||
}
|
||||
}
|
||||
|
||||
std::string RichTextBox::process_copy(Cursor& cur) {
|
||||
std::string TextBox::process_copy(Cursor& cur) {
|
||||
return get_text_between(cur.selectionBeginPos, cur.selectionEndPos);
|
||||
}
|
||||
|
||||
std::string RichTextBox::process_cut(Cursor& cur) {
|
||||
std::string TextBox::process_cut(Cursor& cur) {
|
||||
std::string toRet = process_copy(cur);
|
||||
if(cur.selectionBeginPos != cur.selectionEndPos) {
|
||||
cur.selectionEndPos = cur.selectionBeginPos = cur.pos = remove(cur.selectionBeginPos, cur.selectionEndPos);
|
||||
|
|
@ -152,7 +154,7 @@ std::string RichTextBox::process_cut(Cursor& cur) {
|
|||
return toRet;
|
||||
}
|
||||
|
||||
void RichTextBox::process_text_input(Cursor& cur, const std::string& in, const std::optional<TextStyleModifier::ModifierMap>& inputModMap) {
|
||||
void TextBox::process_text_input(Cursor& cur, const std::string& in, const std::optional<TextStyleModifier::ModifierMap>& inputModMap) {
|
||||
if(!in.empty()) {
|
||||
if(cur.selectionBeginPos != cur.selectionEndPos)
|
||||
cur.selectionEndPos = cur.selectionBeginPos = cur.pos = remove(cur.selectionBeginPos, cur.selectionEndPos);
|
||||
|
|
@ -162,7 +164,7 @@ void RichTextBox::process_text_input(Cursor& cur, const std::string& in, const s
|
|||
}
|
||||
}
|
||||
|
||||
size_t RichTextBox::count_grapheme(const std::string& text) {
|
||||
size_t TextBox::count_grapheme(const std::string& text) {
|
||||
auto u = SkUnicodes::ICU::Make();
|
||||
auto breakIterator = u->makeBreakIterator(SkUnicode::BreakType::kGraphemes);
|
||||
breakIterator->setText(text.c_str(), text.size());
|
||||
|
|
@ -174,7 +176,7 @@ size_t RichTextBox::count_grapheme(const std::string& text) {
|
|||
return count - 1;
|
||||
}
|
||||
|
||||
size_t RichTextBox::next_grapheme(const std::string& text, size_t textBytePos) {
|
||||
size_t TextBox::next_grapheme(const std::string& text, size_t textBytePos) {
|
||||
if(textBytePos == text.size())
|
||||
return text.size();
|
||||
auto u = SkUnicodes::ICU::Make();
|
||||
|
|
@ -184,7 +186,7 @@ size_t RichTextBox::next_grapheme(const std::string& text, size_t textBytePos) {
|
|||
return count + textBytePos;
|
||||
}
|
||||
|
||||
size_t RichTextBox::prev_grapheme(const std::string& text, size_t textBytePos) {
|
||||
size_t TextBox::prev_grapheme(const std::string& text, size_t textBytePos) {
|
||||
if(textBytePos == 0)
|
||||
return 0;
|
||||
auto u = SkUnicodes::ICU::Make();
|
||||
|
|
@ -199,7 +201,7 @@ size_t RichTextBox::prev_grapheme(const std::string& text, size_t textBytePos) {
|
|||
}
|
||||
}
|
||||
|
||||
RichTextBox::TextPosition RichTextBox::get_text_pos_from_byte_pos(const std::string& text, size_t textBytePos) {
|
||||
TextPosition TextBox::get_text_pos_from_byte_pos(const std::string& text, size_t textBytePos) {
|
||||
TextPosition toRet{0, 0};
|
||||
for(size_t i = 0; i < textBytePos; i++) {
|
||||
char c = text[i];
|
||||
|
|
@ -213,7 +215,7 @@ RichTextBox::TextPosition RichTextBox::get_text_pos_from_byte_pos(const std::str
|
|||
return toRet;
|
||||
}
|
||||
|
||||
size_t RichTextBox::get_byte_pos_from_text_pos(TextPosition textPos) {
|
||||
size_t TextBox::get_byte_pos_from_text_pos(TextPosition textPos) {
|
||||
size_t toRet = 0;
|
||||
for(size_t pIndex = 0; pIndex < textPos.fParagraphIndex; pIndex++)
|
||||
toRet += paragraphs[pIndex].text.size() + 1; // Add 1 byte for newline
|
||||
|
|
@ -221,7 +223,7 @@ size_t RichTextBox::get_byte_pos_from_text_pos(TextPosition textPos) {
|
|||
return toRet;
|
||||
}
|
||||
|
||||
RichTextBox::TextPosition RichTextBox::get_text_pos_closest_to_point(Vector2f point) {
|
||||
TextPosition TextBox::get_text_pos_closest_to_point(Vector2f point) {
|
||||
rebuild();
|
||||
|
||||
skia::textlayout::Paragraph::GlyphClusterInfo glyphInfo;
|
||||
|
|
@ -267,8 +269,8 @@ RichTextBox::TextPosition RichTextBox::get_text_pos_closest_to_point(Vector2f po
|
|||
return TextPosition{pIndex, 0};
|
||||
}
|
||||
|
||||
RichTextBox::RichTextData RichTextBox::get_rich_text_data() {
|
||||
RichTextData toRet;
|
||||
TextData TextBox::get_rich_text_data() {
|
||||
TextData toRet;
|
||||
for(auto& p : paragraphs) {
|
||||
toRet.paragraphs.emplace_back();
|
||||
toRet.paragraphs.back().text = p.text;
|
||||
|
|
@ -277,18 +279,18 @@ RichTextBox::RichTextData RichTextBox::get_rich_text_data() {
|
|||
return toRet;
|
||||
}
|
||||
|
||||
void RichTextBox::clear_text() {
|
||||
void TextBox::clear_text() {
|
||||
paragraphs.clear();
|
||||
tStyleMods.clear();
|
||||
paragraphs.emplace_back();
|
||||
}
|
||||
|
||||
void RichTextBox::set_string(const std::string& str) {
|
||||
void TextBox::set_string(const std::string& str) {
|
||||
clear_text();
|
||||
insert({0, 0}, str);
|
||||
}
|
||||
|
||||
void RichTextBox::set_rich_text_data(const RichTextData& richText) {
|
||||
void TextBox::set_rich_text_data(const TextData& richText) {
|
||||
paragraphs.clear();
|
||||
for(auto& p : richText.paragraphs) {
|
||||
paragraphs.emplace_back();
|
||||
|
|
@ -301,11 +303,11 @@ void RichTextBox::set_rich_text_data(const RichTextData& richText) {
|
|||
needsRebuild = true;
|
||||
}
|
||||
|
||||
std::string RichTextBox::get_string() {
|
||||
return get_text_between({0, 0}, move(RichTextBox::Movement::END, {0, 0}));
|
||||
std::string TextBox::get_string() {
|
||||
return get_text_between({0, 0}, move(TextBox::Movement::END, {0, 0}));
|
||||
}
|
||||
|
||||
std::string RichTextBox::get_text_between(TextPosition p1, TextPosition p2) {
|
||||
std::string TextBox::get_text_between(TextPosition p1, TextPosition p2) {
|
||||
p1 = move(Movement::NOWHERE, p1);
|
||||
p2 = move(Movement::NOWHERE, p2);
|
||||
|
||||
|
|
@ -329,7 +331,7 @@ std::string RichTextBox::get_text_between(TextPosition p1, TextPosition p2) {
|
|||
}
|
||||
|
||||
|
||||
void RichTextBox::set_initial_text_style(const skia::textlayout::TextStyle& tStyle) {
|
||||
void TextBox::set_initial_text_style(const skia::textlayout::TextStyle& tStyle) {
|
||||
if(!tStyle.equals(initialTStyle)) {
|
||||
initialTStyle = tStyle;
|
||||
inputChangedTextBox = true;
|
||||
|
|
@ -337,7 +339,7 @@ void RichTextBox::set_initial_text_style(const skia::textlayout::TextStyle& tSty
|
|||
}
|
||||
}
|
||||
|
||||
void RichTextBox::set_initial_text_style_modifier(const std::shared_ptr<TextStyleModifier>& modifier) {
|
||||
void TextBox::set_initial_text_style_modifier(const std::shared_ptr<TextStyleModifier>& modifier) {
|
||||
if(tStyleMods.empty() || tStyleMods[0].pos != TextPosition{0, 0}) {
|
||||
if(tStyleMods.empty())
|
||||
tStyleMods.emplace_back();
|
||||
|
|
@ -349,7 +351,7 @@ void RichTextBox::set_initial_text_style_modifier(const std::shared_ptr<TextStyl
|
|||
remove_duplicate_text_style_mods();
|
||||
}
|
||||
|
||||
TextStyleModifier::ModifierMap RichTextBox::get_mods_used_at_pos(TextPosition p) {
|
||||
TextStyleModifier::ModifierMap TextBox::get_mods_used_at_pos(TextPosition p) {
|
||||
p = move(Movement::NOWHERE, p);
|
||||
|
||||
TextStyleModifier::ModifierMap toRet = TextStyleModifier::get_default_modifiers();
|
||||
|
|
@ -366,7 +368,7 @@ TextStyleModifier::ModifierMap RichTextBox::get_mods_used_at_pos(TextPosition p)
|
|||
return toRet;
|
||||
}
|
||||
|
||||
std::shared_ptr<TextStyleModifier> RichTextBox::get_last_text_style_mod_before_pos(TextPosition pos, TextStyleModifier::ModifierType modType) {
|
||||
std::shared_ptr<TextStyleModifier> TextBox::get_last_text_style_mod_before_pos(TextPosition pos, TextStyleModifier::ModifierType modType) {
|
||||
std::shared_ptr<TextStyleModifier> lastModOfThisTypeBeforeEnd = TextStyleModifier::get_default_modifier(modType);
|
||||
for(auto& [tPos, tStyleModsInPos] : tStyleMods) {
|
||||
if(tPos <= pos) {
|
||||
|
|
@ -380,7 +382,7 @@ std::shared_ptr<TextStyleModifier> RichTextBox::get_last_text_style_mod_before_p
|
|||
return lastModOfThisTypeBeforeEnd;
|
||||
}
|
||||
|
||||
void RichTextBox::erase_if_over_all_styles_until_pos(TextPosition pos, const std::function<bool(TextPosition, const std::shared_ptr<TextStyleModifier>&)>& func) {
|
||||
void TextBox::erase_if_over_all_styles_until_pos(TextPosition pos, const std::function<bool(TextPosition, const std::shared_ptr<TextStyleModifier>&)>& func) {
|
||||
for(auto& [tPos, tStyleModsInPos] : tStyleMods) {
|
||||
if(tPos <= pos) {
|
||||
std::erase_if(tStyleModsInPos, [&](auto& item) {
|
||||
|
|
@ -392,7 +394,7 @@ void RichTextBox::erase_if_over_all_styles_until_pos(TextPosition pos, const std
|
|||
}
|
||||
}
|
||||
|
||||
void RichTextBox::set_text_style_modifier_between(TextPosition p1, TextPosition p2, const std::shared_ptr<TextStyleModifier>& modifier) {
|
||||
void TextBox::set_text_style_modifier_between(TextPosition p1, TextPosition p2, const std::shared_ptr<TextStyleModifier>& modifier) {
|
||||
p1 = move(Movement::NOWHERE, p1);
|
||||
p2 = move(Movement::NOWHERE, p2);
|
||||
if(p1 != p2) {
|
||||
|
|
@ -411,7 +413,7 @@ void RichTextBox::set_text_style_modifier_between(TextPosition p1, TextPosition
|
|||
}
|
||||
}
|
||||
|
||||
void RichTextBox::insert_style_at_pos(TextPosition pos, const std::shared_ptr<TextStyleModifier>& modifier) {
|
||||
void TextBox::insert_style_at_pos(TextPosition pos, const std::shared_ptr<TextStyleModifier>& modifier) {
|
||||
size_t indexToPlaceAt = 0;
|
||||
bool finishedInsertingStyle = false;
|
||||
for(auto& [tPos, tStyleModsInPos] : tStyleMods) {
|
||||
|
|
@ -432,7 +434,7 @@ void RichTextBox::insert_style_at_pos(TextPosition pos, const std::shared_ptr<Te
|
|||
}
|
||||
}
|
||||
|
||||
RichTextBox::TextPosition RichTextBox::move(Movement movement, TextPosition pos, std::optional<float>* previousX, bool flipDependingOnTextDirection) {
|
||||
TextPosition TextBox::move(Movement movement, TextPosition pos, std::optional<float>* previousX, bool flipDependingOnTextDirection) {
|
||||
if(pos.fParagraphIndex >= paragraphs.size()) {
|
||||
pos.fParagraphIndex = paragraphs.size() - 1;
|
||||
pos.fTextByteIndex = paragraphs[pos.fParagraphIndex].text.size();
|
||||
|
|
@ -608,7 +610,7 @@ RichTextBox::TextPosition RichTextBox::move(Movement movement, TextPosition pos,
|
|||
|
||||
}
|
||||
|
||||
void RichTextBox::set_width(float newWidth) {
|
||||
void TextBox::set_width(float newWidth) {
|
||||
if(width != newWidth) {
|
||||
width = std::max(newWidth, 4.0f);
|
||||
inputChangedTextBox = true;
|
||||
|
|
@ -616,11 +618,11 @@ void RichTextBox::set_width(float newWidth) {
|
|||
}
|
||||
}
|
||||
|
||||
void RichTextBox::set_allow_newlines(bool allow) {
|
||||
void TextBox::set_allow_newlines(bool allow) {
|
||||
newlinesAllowed = allow;
|
||||
}
|
||||
|
||||
void RichTextBox::set_font_collection(const sk_sp<skia::textlayout::FontCollection>& fC) {
|
||||
void TextBox::set_font_collection(const sk_sp<skia::textlayout::FontCollection>& fC) {
|
||||
if(fontCollection != fC) {
|
||||
fontCollection = fC;
|
||||
inputChangedTextBox = true;
|
||||
|
|
@ -628,7 +630,7 @@ void RichTextBox::set_font_collection(const sk_sp<skia::textlayout::FontCollecti
|
|||
}
|
||||
}
|
||||
|
||||
void RichTextBox::rebuild() {
|
||||
void TextBox::rebuild() {
|
||||
if(needsRebuild) {
|
||||
float heightOffset = 0.0f;
|
||||
|
||||
|
|
@ -683,7 +685,7 @@ void RichTextBox::rebuild() {
|
|||
}
|
||||
}
|
||||
|
||||
void RichTextBox::remove_duplicate_text_style_mods() {
|
||||
void TextBox::remove_duplicate_text_style_mods() {
|
||||
TextStyleModifier::ModifierMap previouslyAppliedMods = TextStyleModifier::get_default_modifiers();
|
||||
|
||||
std::erase_if(tStyleMods, [&previouslyAppliedMods](PositionedTextStyleMod& tStyleModsInPos) {
|
||||
|
|
@ -700,11 +702,11 @@ void RichTextBox::remove_duplicate_text_style_mods() {
|
|||
});
|
||||
}
|
||||
|
||||
void RichTextBox::set_tab_space_width(unsigned newTabWidth) {
|
||||
void TextBox::set_tab_space_width(unsigned newTabWidth) {
|
||||
tabWidth = newTabWidth;
|
||||
}
|
||||
|
||||
RichTextBox::TextPosition RichTextBox::insert(TextPosition pos, std::string_view textToInsert, const std::optional<TextStyleModifier::ModifierMap>& inputModMap) {
|
||||
TextPosition TextBox::insert(TextPosition pos, std::string_view textToInsert, const std::optional<TextStyleModifier::ModifierMap>& inputModMap) {
|
||||
TextPosition oldPos = pos = move(Movement::NOWHERE, pos);
|
||||
|
||||
for(char c : textToInsert) {
|
||||
|
|
@ -756,7 +758,7 @@ RichTextBox::TextPosition RichTextBox::insert(TextPosition pos, std::string_view
|
|||
return pos;
|
||||
}
|
||||
|
||||
RichTextBox::TextPosition RichTextBox::remove(TextPosition p1, TextPosition p2) {
|
||||
TextPosition TextBox::remove(TextPosition p1, TextPosition p2) {
|
||||
p1 = move(Movement::NOWHERE, p1);
|
||||
p2 = move(Movement::NOWHERE, p2);
|
||||
|
||||
|
|
@ -807,7 +809,7 @@ RichTextBox::TextPosition RichTextBox::remove(TextPosition p1, TextPosition p2)
|
|||
return start;
|
||||
}
|
||||
|
||||
SkRect RichTextBox::get_cursor_rect(TextPosition pos) {
|
||||
SkRect TextBox::get_cursor_rect(TextPosition pos) {
|
||||
pos = move(Movement::NOWHERE, pos);
|
||||
|
||||
SkPoint topPoint;
|
||||
|
|
@ -853,7 +855,7 @@ SkRect RichTextBox::get_cursor_rect(TextPosition pos) {
|
|||
return SkRect::MakeXYWH(topPoint.x() - CURSOR_WIDTH * 0.5f, topPoint.y(), CURSOR_WIDTH, height);
|
||||
}
|
||||
|
||||
void RichTextBox::rects_between_text_positions_func(TextPosition p1, TextPosition p2, std::function<void(const SkRect& r)> f) {
|
||||
void TextBox::rects_between_text_positions_func(TextPosition p1, TextPosition p2, std::function<void(const SkRect& r)> f) {
|
||||
p1 = move(Movement::NOWHERE, p1);
|
||||
p2 = move(Movement::NOWHERE, p2);
|
||||
|
||||
|
|
@ -882,7 +884,7 @@ void RichTextBox::rects_between_text_positions_func(TextPosition p1, TextPositio
|
|||
}
|
||||
}
|
||||
|
||||
void RichTextBox::paint(SkCanvas* canvas, const PaintOpts& paintOpts) {
|
||||
void TextBox::paint(SkCanvas* canvas, const PaintOpts& paintOpts) {
|
||||
rebuild();
|
||||
|
||||
if(paintOpts.cursor.has_value()) {
|
||||
|
|
@ -901,3 +903,5 @@ void RichTextBox::paint(SkCanvas* canvas, const PaintOpts& paintOpts) {
|
|||
for(auto& pData : paragraphs)
|
||||
pData.p->paint(canvas, 0.0f, pData.heightOffset);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -9,9 +9,45 @@
|
|||
#include "TextStyleModifier.hpp"
|
||||
#include "cereal/archives/portable_binary.hpp"
|
||||
|
||||
class RichTextBox {
|
||||
namespace RichText {
|
||||
|
||||
struct TextPosition {
|
||||
// Set to uint32_t values because theyll be saved and sent over networks. Size has to be consistent
|
||||
size_t fParagraphIndex = std::numeric_limits<uint32_t>::max();
|
||||
size_t fTextByteIndex = std::numeric_limits<uint32_t>::max();
|
||||
template <typename Archive> void serialize(Archive& a) {
|
||||
a((uint32_t)fParagraphIndex, (uint32_t)fTextByteIndex);
|
||||
}
|
||||
bool operator==(const TextPosition& o) const = default;
|
||||
bool operator<(const TextPosition& o) const;
|
||||
bool operator>(const TextPosition& o) const;
|
||||
bool operator>=(const TextPosition& o) const;
|
||||
bool operator<=(const TextPosition& o) const;
|
||||
};
|
||||
|
||||
struct PositionedTextStyleMod {
|
||||
TextPosition pos;
|
||||
TextStyleModifier::ModifierMap mods;
|
||||
};
|
||||
|
||||
typedef std::vector<PositionedTextStyleMod> TextStyleModContainer;
|
||||
|
||||
struct TextData {
|
||||
struct Paragraph {
|
||||
std::string text;
|
||||
template<typename Archive> void serialize(Archive& a) {
|
||||
a(text);
|
||||
}
|
||||
};
|
||||
void save(cereal::PortableBinaryOutputArchive& a) const;
|
||||
void load(cereal::PortableBinaryInputArchive& a);
|
||||
TextStyleModContainer tStyleMods;
|
||||
std::vector<Paragraph> paragraphs;
|
||||
};
|
||||
|
||||
class TextBox {
|
||||
public:
|
||||
RichTextBox();
|
||||
TextBox();
|
||||
|
||||
bool inputChangedTextBox = false;
|
||||
|
||||
|
|
@ -27,27 +63,6 @@ class RichTextBox {
|
|||
END
|
||||
};
|
||||
|
||||
struct TextPosition {
|
||||
// Set to uint32_t values because theyll be saved and sent over networks. Size has to be consistent
|
||||
size_t fParagraphIndex = std::numeric_limits<uint32_t>::max();
|
||||
size_t fTextByteIndex = std::numeric_limits<uint32_t>::max();
|
||||
template <typename Archive> void serialize(Archive& a) {
|
||||
a((uint32_t)fParagraphIndex, (uint32_t)fTextByteIndex);
|
||||
}
|
||||
bool operator==(const TextPosition& o) const = default;
|
||||
bool operator<(const TextPosition& o) const;
|
||||
bool operator>(const TextPosition& o) const;
|
||||
bool operator>=(const RichTextBox::TextPosition& o) const;
|
||||
bool operator<=(const RichTextBox::TextPosition& o) const;
|
||||
};
|
||||
|
||||
struct PositionedTextStyleMod {
|
||||
TextPosition pos;
|
||||
TextStyleModifier::ModifierMap mods;
|
||||
};
|
||||
|
||||
typedef std::vector<PositionedTextStyleMod> TextStyleModContainer;
|
||||
|
||||
struct Cursor {
|
||||
TextPosition pos = {0, 0};
|
||||
TextPosition selectionBeginPos = {0, 0};
|
||||
|
|
@ -65,19 +80,6 @@ class RichTextBox {
|
|||
std::optional<Cursor> cursor;
|
||||
};
|
||||
|
||||
struct RichTextData {
|
||||
struct Paragraph {
|
||||
std::string text;
|
||||
template<typename Archive> void serialize(Archive& a) {
|
||||
a(text);
|
||||
}
|
||||
};
|
||||
void save(cereal::PortableBinaryOutputArchive& a) const;
|
||||
void load(cereal::PortableBinaryInputArchive& a);
|
||||
TextStyleModContainer tStyleMods;
|
||||
std::vector<Paragraph> paragraphs;
|
||||
};
|
||||
|
||||
TextPosition move(Movement movement, TextPosition pos, std::optional<float>* previousX = nullptr, bool flipDependingOnTextDirection = false);
|
||||
void set_width(float newWidth);
|
||||
TextPosition insert(TextPosition pos, std::string_view textToInsert, const std::optional<TextStyleModifier::ModifierMap>& inputModMap = std::nullopt);
|
||||
|
|
@ -105,8 +107,8 @@ class RichTextBox {
|
|||
void set_text_style_modifier_between(TextPosition p1, TextPosition p2, const std::shared_ptr<TextStyleModifier>& modifier);
|
||||
TextStyleModifier::ModifierMap get_mods_used_at_pos(TextPosition p);
|
||||
|
||||
RichTextData get_rich_text_data();
|
||||
void set_rich_text_data(const RichTextData& richText);
|
||||
TextData get_rich_text_data();
|
||||
void set_rich_text_data(const TextData& richText);
|
||||
void clear_text();
|
||||
void set_string(const std::string& str);
|
||||
|
||||
|
|
@ -157,3 +159,5 @@ class RichTextBox {
|
|||
TextStyleModContainer tStyleMods;
|
||||
std::vector<ParagraphData> paragraphs;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
#define WEIGHT_VALUE_MODIFIER 100
|
||||
|
||||
namespace RichText {
|
||||
|
||||
TextStyleModifier::ModifierMap TextStyleModifier::defaultMods;
|
||||
|
||||
std::shared_ptr<TextStyleModifier> TextStyleModifier::allocate_modifier(ModifierType type) {
|
||||
|
|
@ -223,3 +225,5 @@ void DecorationTextStyleModifier::modify_text_style(skia::textlayout::TextStyle&
|
|||
bool DecorationTextStyleModifier::equivalent_data(TextStyleModifier& modifier) const {
|
||||
return decorationValue == static_cast<DecorationTextStyleModifier&>(modifier).decorationValue;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -5,6 +5,8 @@
|
|||
#include "cereal/archives/portable_binary.hpp"
|
||||
#include "../SharedTypes.hpp"
|
||||
|
||||
namespace RichText {
|
||||
|
||||
class TextStyleModifier {
|
||||
public:
|
||||
enum class ModifierType : uint16_t {
|
||||
|
|
@ -117,3 +119,5 @@ class FontFamiliesTextStyleModifier : public TextStyleModifier {
|
|||
std::vector<SkString> families;
|
||||
virtual bool equivalent_data(TextStyleModifier& modifier) const override;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -1915,7 +1915,7 @@ void Toolbar::initialize_io_before_update() {
|
|||
io->key.paste = main.input.get_clipboard_paste_happened();
|
||||
io->key.cut = main.input.key(InputManager::KEY_TEXT_CUT).repeat;
|
||||
io->key.escape = main.input.key(InputManager::KEY_GENERIC_ESCAPE).repeat;
|
||||
io->richTextBoxEdit = [&](std::shared_ptr<RichTextBox> t, std::shared_ptr<RichTextBox::Cursor> c) {
|
||||
io->richTextBoxEdit = [&](std::shared_ptr<RichText::TextBox> t, std::shared_ptr<RichText::TextBox::Cursor> c) {
|
||||
main.input.text.set_rich_text_box_input(t, c);
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue