Added richtext clipboard to Emscripten and fixed emscripten compilation warning
This commit is contained in:
parent
8830386dc0
commit
9eeee0dfff
5 changed files with 66 additions and 26 deletions
|
|
@ -26,7 +26,7 @@ template <typename T> class ColorPicker : public Element {
|
|||
.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0) }
|
||||
},
|
||||
.aspectRatio = 1.0f,
|
||||
.aspectRatio = {1.0f},
|
||||
.custom = { .customData = this }
|
||||
}) {
|
||||
selection.update(Clay_Hovered(), io.mouse.leftClick, io.mouse.leftHeld);
|
||||
|
|
|
|||
|
|
@ -141,6 +141,7 @@ std::string InputManager::get_clipboard_data_for_mimetype(const std::string& mim
|
|||
void InputManager::set_clipboard_str(std::string_view s) {
|
||||
#ifdef __EMSCRIPTEN__
|
||||
emscripten_browser_clipboard::copy(std::string(s));
|
||||
lastCopiedRichText = std::nullopt;
|
||||
#else
|
||||
SDL_SetClipboardText(s.data());
|
||||
#endif
|
||||
|
|
@ -150,13 +151,14 @@ std::string InputManager::get_infpnt_richtext_mimetype() {
|
|||
return "web text/infpnt";
|
||||
}
|
||||
|
||||
void InputManager::set_clipboard_plain_and_richtext_pair(const std::pair<std::string, std::string>& plainAndRichtextPair) {
|
||||
void InputManager::set_clipboard_plain_and_richtext_pair(const std::pair<std::string, RichText::TextData>& plainAndRichtextPair) {
|
||||
#ifdef __EMSCRIPTEN__
|
||||
set_clipboard_str(plainAndRichtextPair.first);
|
||||
lastCopiedRichText = plainAndRichtextPair.second;
|
||||
#else
|
||||
std::unordered_map<std::string, std::string> clipboardData;
|
||||
clipboardData["text/plain"] = plainAndRichtextPair.first;
|
||||
clipboardData[get_infpnt_richtext_mimetype()] = plainAndRichtextPair.second;
|
||||
clipboardData[get_infpnt_richtext_mimetype()] = plainAndRichtextPair.second.get_serialized();
|
||||
set_clipboard_data(clipboardData);
|
||||
#endif
|
||||
}
|
||||
|
|
@ -385,11 +387,24 @@ void InputManager::backend_key_down_update(const SDL_KeyboardEvent& e) {
|
|||
|
||||
void InputManager::process_text_paste() {
|
||||
if(text.textBox) {
|
||||
std::string richTextClipboard = get_clipboard_data_for_mimetype(get_infpnt_richtext_mimetype());
|
||||
if(!richTextClipboard.empty())
|
||||
text.textBox->process_rich_text_input(*text.cursor, richTextClipboard);
|
||||
else
|
||||
text.textBox->process_text_input(*text.cursor, get_clipboard_data_for_mimetype("text/plain"), text.modMap);
|
||||
#ifdef __EMSCRIPTEN__
|
||||
// Workaround for not being able to copy richtext to system clipboard, this should at least work within the application itself
|
||||
std::string plainClipboardStr = get_clipboard_str();
|
||||
if(lastCopiedRichText.has_value()) {
|
||||
if(lastCopiedRichText.value().get_plain_text() == plainClipboardStr)
|
||||
text.textBox->process_rich_text_input(*text.cursor, lastCopiedRichText.value());
|
||||
else
|
||||
text.textBox->process_text_input(*text.cursor, plainClipboardStr, text.modMap);
|
||||
}
|
||||
else
|
||||
text.textBox->process_text_input(*text.cursor, plainClipboardStr, text.modMap);
|
||||
#else
|
||||
std::string richTextClipboard = get_clipboard_data_for_mimetype(get_infpnt_richtext_mimetype());
|
||||
if(!richTextClipboard.empty())
|
||||
text.textBox->process_rich_text_input(*text.cursor, RichText::TextData::deserialize_string(richTextClipboard));
|
||||
else
|
||||
text.textBox->process_text_input(*text.cursor, get_clipboard_data_for_mimetype("text/plain"), text.modMap);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -199,7 +199,7 @@ struct InputManager {
|
|||
std::string get_clipboard_data_for_mimetype(const std::string& mimeType);
|
||||
|
||||
void set_clipboard_str(std::string_view s);
|
||||
void set_clipboard_plain_and_richtext_pair(const std::pair<std::string, std::string>& plainAndRichtextPair);
|
||||
void set_clipboard_plain_and_richtext_pair(const std::pair<std::string, RichText::TextData>& plainAndRichtextPair);
|
||||
void set_clipboard_data(const std::unordered_map<std::string, std::string>& newClipboardData);
|
||||
void process_text_paste();
|
||||
|
||||
|
|
@ -210,6 +210,7 @@ struct InputManager {
|
|||
#ifdef __EMSCRIPTEN__
|
||||
bool clipboardPasteEventHappened = false;
|
||||
std::unordered_map<std::string, std::string> clipboardPasteEventData;
|
||||
std::optional<RichText::TextData> lastCopiedRichText;
|
||||
#endif
|
||||
|
||||
std::string key_assignment_to_str(const Vector2ui32& k);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#include "TextBox.hpp"
|
||||
#include "Helpers/Networking/ByteStream.hpp"
|
||||
#include "TextStyleModifier.hpp"
|
||||
#include "cereal/archives/portable_binary.hpp"
|
||||
#include <limits>
|
||||
|
|
@ -16,7 +17,7 @@
|
|||
|
||||
namespace RichText {
|
||||
|
||||
std::string TextData::get_serialized() {
|
||||
std::string TextData::get_serialized() const {
|
||||
std::stringstream s;
|
||||
{
|
||||
cereal::PortableBinaryOutputArchive a(s);
|
||||
|
|
@ -54,6 +55,33 @@ void TextData::load(cereal::PortableBinaryInputArchive& a) {
|
|||
}
|
||||
}
|
||||
|
||||
TextData TextData::deserialize_string(std::string& s) {
|
||||
if(s.empty()) {
|
||||
RichText::TextData textData;
|
||||
textData.paragraphs.emplace_back();
|
||||
return textData;
|
||||
}
|
||||
RichText::TextData textData;
|
||||
ByteMemStream ss(s.data(), s.length());
|
||||
{
|
||||
cereal::PortableBinaryInputArchive a(ss);
|
||||
a(textData);
|
||||
}
|
||||
return textData;
|
||||
}
|
||||
|
||||
std::string TextData::get_plain_text() const {
|
||||
if(paragraphs.empty())
|
||||
return "";
|
||||
std::string toRet;
|
||||
for(auto& p : paragraphs) {
|
||||
toRet += p.text;
|
||||
toRet += '\n';
|
||||
}
|
||||
toRet.pop_back();
|
||||
return toRet;
|
||||
}
|
||||
|
||||
bool TextPosition::operator<(const TextPosition& o) const {
|
||||
return (this->fParagraphIndex < o.fParagraphIndex) || (this->fParagraphIndex == o.fParagraphIndex && this->fTextByteIndex < o.fTextByteIndex);
|
||||
}
|
||||
|
|
@ -151,11 +179,11 @@ void TextBox::process_mouse_left_button(Cursor& cur, const Vector2f& pos, bool c
|
|||
}
|
||||
}
|
||||
|
||||
std::pair<std::string, std::string> TextBox::process_copy(Cursor& cur) {
|
||||
return {get_text_between(cur.selectionBeginPos, cur.selectionEndPos), get_rich_text_data_between(cur.selectionBeginPos, cur.selectionEndPos).get_serialized()};
|
||||
std::pair<std::string, TextData> TextBox::process_copy(Cursor& cur) {
|
||||
return {get_text_between(cur.selectionBeginPos, cur.selectionEndPos), get_rich_text_data_between(cur.selectionBeginPos, cur.selectionEndPos)};
|
||||
}
|
||||
|
||||
std::pair<std::string, std::string> TextBox::process_cut(Cursor& cur) {
|
||||
std::pair<std::string, TextData> TextBox::process_cut(Cursor& cur) {
|
||||
auto toRet = process_copy(cur);
|
||||
if(cur.selectionBeginPos != cur.selectionEndPos) {
|
||||
cur.selectionEndPos = cur.selectionBeginPos = cur.pos = remove(cur.selectionBeginPos, cur.selectionEndPos);
|
||||
|
|
@ -175,17 +203,11 @@ void TextBox::process_text_input(Cursor& cur, const std::string& in, const std::
|
|||
}
|
||||
}
|
||||
|
||||
void TextBox::process_rich_text_input(Cursor& cur, const std::string& serializedRichText) {
|
||||
if(!serializedRichText.empty()) {
|
||||
void TextBox::process_rich_text_input(Cursor& cur, const TextData& richText) {
|
||||
if(!richText.paragraphs.empty() && !(richText.paragraphs.size() == 1 && richText.paragraphs[0].text.empty())) {
|
||||
if(cur.selectionBeginPos != cur.selectionEndPos)
|
||||
cur.selectionEndPos = cur.selectionBeginPos = cur.pos = remove(cur.selectionBeginPos, cur.selectionEndPos);
|
||||
RichText::TextData textData;
|
||||
std::stringstream ss(serializedRichText);
|
||||
{
|
||||
cereal::PortableBinaryInputArchive a(ss);
|
||||
a(textData);
|
||||
}
|
||||
cur.selectionEndPos = cur.selectionBeginPos = cur.pos = insert_rich_text(cur.pos, textData);
|
||||
cur.selectionEndPos = cur.selectionBeginPos = cur.pos = insert_rich_text(cur.pos, richText);
|
||||
cur.previousX = std::nullopt;
|
||||
inputChangedTextBox = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,7 +48,9 @@ class TextData {
|
|||
a(text, pStyleData);
|
||||
}
|
||||
};
|
||||
std::string get_serialized();
|
||||
std::string get_serialized() const;
|
||||
static TextData deserialize_string(std::string& s);
|
||||
std::string get_plain_text() const;
|
||||
void save(cereal::PortableBinaryOutputArchive& a) const;
|
||||
void load(cereal::PortableBinaryInputArchive& a);
|
||||
TextStyleModContainer tStyleMods;
|
||||
|
|
@ -133,13 +135,13 @@ class TextBox {
|
|||
|
||||
void process_mouse_left_button(Cursor& cur, const Vector2f& pos, bool clicked, bool held, bool shift);
|
||||
void process_key_input(Cursor& cur, InputKey in, bool ctrl, bool shift, const std::optional<TextStyleModifier::ModifierMap>& inputModMap = std::nullopt);
|
||||
std::pair<std::string, std::string> process_copy(Cursor& cur);
|
||||
std::pair<std::string, std::string> process_cut(Cursor& cur);
|
||||
std::pair<std::string, TextData> process_copy(Cursor& cur);
|
||||
std::pair<std::string, TextData> 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, const std::optional<TextStyleModifier::ModifierMap>& inputModMap = std::nullopt);
|
||||
void process_rich_text_input(Cursor& cur, const std::string& serializedRichText);
|
||||
void process_rich_text_input(Cursor& cur, const TextData& richText);
|
||||
|
||||
private:
|
||||
std::pair<TextPosition, TextPosition> get_start_end_text_pos(TextPosition p1, TextPosition p2);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue