#include "../include/ChatMessage.hpp" #include #include namespace dchat { static void appendRichText(Gtk::TextView *textView, Glib::RefPtr buffer, Gtk::TextIter iter, const Glib::ustring &text) { parseIncomingMessage(text.data(), text.bytes(), [textView, &text, &iter, &buffer](IncomingMessagePart messagePart) { switch(messagePart.type) { case IncomingMessagePart::Type::TEXT: { iter = buffer->insert(iter, text.data() + messagePart.textRange.start, text.data() + messagePart.textRange.end); break; } case IncomingMessagePart::Type::EMOJI: { auto anchor = Gtk::TextChildAnchor::create(); iter = buffer->insert_child_anchor(iter, anchor); auto image = Gtk::manage(new DynamicImage()); image->url = text.substr(messagePart.textRange.start, messagePart.textRange.length()); image->set_size_request(35, 35); textView->add_child_at_anchor(*image, anchor); break; } default: assert(false); break; } }); } void applyRichText(Gtk::TextView *textView, const Glib::ustring &text) { auto buffer = textView->get_buffer(); buffer->set_text(""); appendRichText(textView, buffer, buffer->begin(), text); } ChatMessage::ChatMessage(const Glib::ustring &_username, const Glib::ustring &_text, uint32_t _timestampSeconds) : username(_username), timestampSeconds(_timestampSeconds) { avatar.set_halign(Gtk::ALIGN_START); avatar.set_valign(Gtk::ALIGN_START); avatar.set_size_request(35, 35); username.set_selectable(true); username.set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_START); username.get_style_context()->add_class("message-message-username"); text.set_wrap_mode(Gtk::WRAP_WORD_CHAR); //text.set_halign(Gtk::ALIGN_START); //text.set_valign(Gtk::ALIGN_START); text.set_hexpand(true); text.set_editable(false); applyRichText(&text, _text); text.get_style_context()->add_class("message-message-text"); attach(avatar, 0, 0, 1, 2); attach_next_to(username, avatar, Gtk::POS_RIGHT, 1, 1); attach_next_to(text, username, Gtk::POS_BOTTOM, 1, 1); get_style_context()->add_class("message-message"); set_column_spacing(10); set_row_spacing(0); set_vexpand(false); } void ChatMessage::appendText(const Glib::ustring &_text) { auto buffer = text.get_buffer(); // Optimized for single ascii characters, such as "\n" if(_text.bytes() == 1) { buffer->insert(buffer->end(), _text); } else { appendRichText(&text, buffer, buffer->end(), _text); } } }