#include "RichTextUserInput.hpp" template std::optional shared_ptr_to_opt(const std::shared_ptr o) { if(o) return *o; else return std::nullopt; } RichTextUserInput::RichTextUserInput(const std::shared_ptr& initTextBox, const std::shared_ptr& initCursor, const std::shared_ptr& initModMap, const std::function& initOnTextEdit): textBox(initTextBox), cursor(initCursor), modMap(initModMap), onTextEdit(initOnTextEdit) {} void RichTextUserInput::add_text_to_textbox(const std::string& inputText) { do_textbox_operation_with_undo([&]() { textBox->process_text_input(*cursor, inputText, shared_ptr_to_opt(modMap)); }); onTextEdit(); } void RichTextUserInput::add_textbox_undo(const RichText::TextBox::Cursor& prevCursor, const RichText::TextData& prevRichText) { textboxUndo.push({[&, prevCursor = prevCursor, prevRichText = prevRichText]() { textBox->set_rich_text_data_for_undo_redo(prevRichText); cursor->selectionBeginPos = cursor->selectionEndPos = cursor->pos = std::max(prevCursor.selectionEndPos, prevCursor.selectionBeginPos); cursor->previousX = std::nullopt; onTextEdit(); return true; }, [&, currentCursor = *cursor, currentRichText = textBox->get_rich_text_data()]() { textBox->set_rich_text_data_for_undo_redo(currentRichText); cursor->selectionBeginPos = cursor->selectionEndPos = cursor->pos = std::max(currentCursor.selectionEndPos, currentCursor.selectionBeginPos); cursor->previousX = std::nullopt; onTextEdit(); return true; }}); } void RichTextUserInput::do_textbox_operation_with_undo(const std::function& func) { auto prevRichText = textBox->get_rich_text_data(); auto prevCursor = *cursor; func(); add_textbox_undo(prevCursor, prevRichText); onTextEdit(); } void RichTextUserInput::input_key_callback(InputManager& input, const InputManager::KeyCallbackArgs& key) { std::optional modMapOpt = shared_ptr_to_opt(modMap); if(key.down) { switch(key.key) { case InputManager::KEY_GENERIC_UP: textBox->process_key_input(*cursor, RichText::TextBox::InputKey::UP, input.ctrl_or_meta_held(), input.key(InputManager::KEY_GENERIC_LSHIFT).held, modMapOpt); break; case InputManager::KEY_GENERIC_DOWN: textBox->process_key_input(*cursor, RichText::TextBox::InputKey::DOWN, input.ctrl_or_meta_held(), input.key(InputManager::KEY_GENERIC_LSHIFT).held, modMapOpt); break; case InputManager::KEY_GENERIC_LEFT: textBox->process_key_input(*cursor, RichText::TextBox::InputKey::LEFT, input.ctrl_or_meta_held(), input.key(InputManager::KEY_GENERIC_LSHIFT).held, modMapOpt); break; case InputManager::KEY_GENERIC_RIGHT: textBox->process_key_input(*cursor, RichText::TextBox::InputKey::RIGHT, input.ctrl_or_meta_held(), input.key(InputManager::KEY_GENERIC_LSHIFT).held, modMapOpt); break; case InputManager::KEY_TEXT_BACKSPACE: do_textbox_operation_with_undo([&] { textBox->process_key_input(*cursor, RichText::TextBox::InputKey::BACKSPACE, input.ctrl_or_meta_held(), input.key(InputManager::KEY_GENERIC_LSHIFT).held, modMapOpt); }); break; case InputManager::KEY_TEXT_DELETE: do_textbox_operation_with_undo([&] { textBox->process_key_input(*cursor, RichText::TextBox::InputKey::DEL, input.ctrl_or_meta_held(), input.key(InputManager::KEY_GENERIC_LSHIFT).held, modMapOpt); }); break; case InputManager::KEY_TEXT_HOME: textBox->process_key_input(*cursor, RichText::TextBox::InputKey::HOME, input.ctrl_or_meta_held(), input.key(InputManager::KEY_GENERIC_LSHIFT).held, modMapOpt); break; case InputManager::KEY_TEXT_END: textBox->process_key_input(*cursor, RichText::TextBox::InputKey::END, input.ctrl_or_meta_held(), input.key(InputManager::KEY_GENERIC_LSHIFT).held, modMapOpt); break; case InputManager::KEY_TEXT_COPY: input.set_clipboard_plain_and_richtext_pair(textBox->process_copy(*cursor)); break; case InputManager::KEY_TEXT_CUT: do_textbox_operation_with_undo([&] { input.set_clipboard_plain_and_richtext_pair(textBox->process_cut(*cursor)); }); break; case InputManager::KEY_TEXT_PASTE: do_textbox_operation_with_undo([&]() { input.call_text_paste([textBox = textBox, cursor = cursor, modMapOpt] (const InputManager::TextPasteCallbackArgs& pasteArgs) { if(pasteArgs.richText.has_value()) textBox->process_rich_text_input(*cursor, pasteArgs.richText.value()); else textBox->process_text_input(*cursor, pasteArgs.text, modMapOpt); }); }); break; case InputManager::KEY_TEXT_SELECTALL: textBox->process_key_input(*cursor, RichText::TextBox::InputKey::SELECT_ALL, input.ctrl_or_meta_held(), input.key(InputManager::KEY_GENERIC_LSHIFT).held, modMapOpt); break; case InputManager::KEY_TEXT_UNDO: textboxUndo.undo(); break; case InputManager::KEY_TEXT_REDO: textboxUndo.redo(); break; case InputManager::KEY_GENERIC_ENTER: do_textbox_operation_with_undo([&] { textBox->process_key_input(*cursor, RichText::TextBox::InputKey::ENTER, input.ctrl_or_meta_held(), input.key(InputManager::KEY_GENERIC_LSHIFT).held, modMapOpt); }); break; case InputManager::KEY_TEXT_TAB: do_textbox_operation_with_undo([&] { textBox->process_key_input(*cursor, RichText::TextBox::InputKey::TAB, input.ctrl_or_meta_held(), input.key(InputManager::KEY_GENERIC_LSHIFT).held, modMapOpt); }); break; default: break; } } }