From a535703add6bf29878845cb270997514489cfc16 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Wed, 31 Oct 2018 18:12:49 +0100 Subject: Start with images/gif, resize chat input --- src/Cache.cpp | 63 ----------------------------------------------------- src/ChatMessage.cpp | 32 +++++++++++++++++++++++++-- src/ChatWindow.cpp | 59 +++++++++++++++++++++++++++++++++++++++++++------ src/GlobalCache.cpp | 18 +++++++++++++++ src/GtkGif.cpp | 31 ++++++++++++++++++++++++++ src/Window.cpp | 8 ++++++- 6 files changed, 138 insertions(+), 73 deletions(-) delete mode 100644 src/Cache.cpp create mode 100644 src/GlobalCache.cpp create mode 100644 src/GtkGif.cpp (limited to 'src') diff --git a/src/Cache.cpp b/src/Cache.cpp deleted file mode 100644 index d4c19fb..0000000 --- a/src/Cache.cpp +++ /dev/null @@ -1,63 +0,0 @@ -#include "../include/Cache.hpp" -#include "../include/env.hpp" -#include - -#if OS_FAMILY == OS_FAMILY_POSIX -#include -#else -#include -#endif - -using namespace std; - -namespace dchat -{ - static boost::filesystem::path getHomeDir() - { - #if OS_FAMILY == OS_FAMILY_POSIX - const char *homeDir = getenv("HOME"); - if(!homeDir) - { - passwd *pw = getpwuid(getuid()); - homeDir = pw->pw_dir; - } - return boost::filesystem::path(homeDir); - #elif OS_FAMILY == OS_FAMILY_WINDOWS - BOOL ret; - HANDLE hToken; - std::wstring homeDir; - DWORD homeDirLen = MAX_PATH; - homeDir.resize(homeDirLen); - - if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &hToken)) - return Result::Err("Failed to open process token"); - - if (!GetUserProfileDirectory(hToken, &homeDir[0], &homeDirLen)) - { - CloseHandle(hToken); - return Result::Err("Failed to get home directory"); - } - - CloseHandle(hToken); - homeDir.resize(wcslen(homeDir.c_str())); - return boost::filesystem::path(homeDir); - #endif - } - - Cache::Cache() - { - - } - - Cache::~Cache() - { - - } - - boost::filesystem::path Cache::getDchatDir() - { - boost::filesystem::path dchatHomeDir = getHomeDir() / ".local" / "share" / "dchat"; - boost::filesystem::create_directories(dchatHomeDir); - return dchatHomeDir; - } -} diff --git a/src/ChatMessage.cpp b/src/ChatMessage.cpp index db5fad2..93b52e9 100644 --- a/src/ChatMessage.cpp +++ b/src/ChatMessage.cpp @@ -1,4 +1,6 @@ #include "../include/ChatMessage.hpp" +#include "../include/GlobalCache.hpp" +#include "../include/GtkGif.hpp" namespace dchat { @@ -8,6 +10,9 @@ namespace dchat timestampSeconds(_timestampSeconds), user(_user) { + avatar.set_halign(Gtk::ALIGN_START); + avatar.set_valign(Gtk::ALIGN_START); + username.set_selectable(true); username.set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_START); username.get_style_context()->add_class("chat-message-username"); @@ -18,8 +23,31 @@ namespace dchat text.set_line_wrap_mode(Pango::WRAP_WORD_CHAR); text.get_style_context()->add_class("chat-message-text"); - attach(username, 0, 0, 1, 1); - attach(text, 0, 1, 1, 1); + 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("chat-message"); + + signal_draw().connect(sigc::mem_fun(*this, &ChatMessage::updateContent)); + } + + bool ChatMessage::updateContent(const Cairo::RefPtr &cairo) + { + #if 0 + auto result = getGlobalCache().getContentByUrl("https://discordemoji.com/assets/emoji/3644_epicKirby.gif"); + printf("result type: %d\n", result.type); + if(result.type == ContentByUrlResult::Type::CACHED && result.gif) + { + Gtk::Widget *child = avatar.get_child_at(0, 0); + if(!child) + { + printf("add gif!\n"); + //GtkGif *gif = new GtkGif(GtkGif*)result.gif; + //gif->copy + //avatar.attach(*(GtkGif*)result.gif, 0, 0, 1, 1); + } + } + #endif + return true; } } \ No newline at end of file diff --git a/src/ChatWindow.cpp b/src/ChatWindow.cpp index b0bb696..041d2c3 100644 --- a/src/ChatWindow.cpp +++ b/src/ChatWindow.cpp @@ -1,6 +1,8 @@ #include "../include/ChatWindow.hpp" #include "../include/ChatMessage.hpp" #include +#include +#include #include namespace dchat @@ -82,23 +84,66 @@ namespace dchat void ChatWindow::setupMessageArea(Gtk::Grid *rightPanel) { - chatArea.set_vexpand(true); - chatArea.set_policy(Gtk::PolicyType::POLICY_NEVER, Gtk::PolicyType::POLICY_AUTOMATIC); - rightPanel->attach(chatArea, 0, 0, 1, 2); + //messageArea.set_valign(Gtk::ALIGN_START); + messageArea.set_vexpand(true); + messageArea.set_policy(Gtk::PolicyType::POLICY_NEVER, Gtk::PolicyType::POLICY_AUTOMATIC); + rightPanel->attach(messageArea, 0, 0, 1, 2); - chatAreaLayout.set_name("chat-area-layout"); - chatArea.add(chatAreaLayout); + messageAreaLayout.set_name("chat-area-layout"); + messageArea.add(messageAreaLayout); } void ChatWindow::setupChatInput(Gtk::Grid *rightPanel) { + Gtk::Grid *chatArea = Gtk::manage(new Gtk::Grid()); + rightPanel->attach_next_to(*chatArea, messageArea, Gtk::POS_BOTTOM, 1, 1); + Gtk::ScrolledWindow *chatScrollWindow = Gtk::manage(new Gtk::ScrolledWindow()); + chatScrollWindow->set_hexpand(true); + chatScrollWindow->set_policy(Gtk::PolicyType::POLICY_NEVER, Gtk::PolicyType::POLICY_NEVER); chatScrollWindow->set_name("chat-scroll-view"); - rightPanel->attach_next_to(*chatScrollWindow, chatArea, Gtk::POS_BOTTOM, 1, 1); + chatArea->attach(*chatScrollWindow, 0, 0, 1, 1); chatInput.set_hexpand(true); chatInput.set_name("chat-input"); chatInput.set_wrap_mode(Gtk::WrapMode::WRAP_WORD_CHAR); + + double fontSize = 18.5;//PANGO_PIXELS(chatInput.get_style_context()->get_font().get_size()); + chatPrevNumLines = 1; + chatInput.get_buffer()->signal_changed().connect([this, chatScrollWindow, fontSize] + { + int numLines = chatInput.get_buffer()->get_line_count(); + numLines = std::min(numLines, 10); + if(numLines != chatPrevNumLines) + { + chatPrevNumLines = numLines; + chatScrollWindow->set_min_content_height(fontSize * numLines); + + auto adj = chatScrollWindow->get_vadjustment(); + if(chatInput.get_buffer()->get_line_count() <= 10) + { + chatScrollWindow->set_policy(Gtk::PolicyType::POLICY_NEVER, Gtk::PolicyType::POLICY_NEVER); + adj->set_value(0); + } + else + { + chatScrollWindow->set_policy(Gtk::PolicyType::POLICY_NEVER, Gtk::PolicyType::POLICY_ALWAYS); + } + } + }); + chatScrollWindow->get_vadjustment()->signal_value_changed().connect([this, chatScrollWindow]() + { + auto adj = chatScrollWindow->get_vadjustment(); + if(chatInput.get_buffer()->get_line_count() <= 11) + { + chatScrollWindow->set_policy(Gtk::PolicyType::POLICY_NEVER, Gtk::PolicyType::POLICY_NEVER); + adj->set_value(0); + } + else + { + chatScrollWindow->set_policy(Gtk::PolicyType::POLICY_NEVER, Gtk::PolicyType::POLICY_ALWAYS); + } + }); chatScrollWindow->add(chatInput); } @@ -143,7 +188,7 @@ namespace dchat message->set_valign(Gtk::Align::ALIGN_START); message->set_hexpand(true); message->show_all(); - chatAreaLayout.attach(*message, 0, it->second.messageCount, 1, 1); + messageAreaLayout.attach(*message, 0, it->second.messageCount, 1, 1); ++it->second.messageCount; } diff --git a/src/GlobalCache.cpp b/src/GlobalCache.cpp new file mode 100644 index 0000000..e627a33 --- /dev/null +++ b/src/GlobalCache.cpp @@ -0,0 +1,18 @@ +#include "../include/GlobalCache.hpp" +#include "../include/GtkGif.hpp" + +namespace dchat +{ + static Cache *cache = nullptr; + Cache& getGlobalCache() + { + if(!cache) + { + cache = new Cache([](StringView fileContent) + { + return new GtkGif(fileContent); + }); + } + return *cache; + } +} \ No newline at end of file diff --git a/src/GtkGif.cpp b/src/GtkGif.cpp new file mode 100644 index 0000000..1da48a8 --- /dev/null +++ b/src/GtkGif.cpp @@ -0,0 +1,31 @@ +#include "../include/GtkGif.hpp" + +namespace dchat +{ + GtkGif::GtkGif(StringView fileContent) : + Gif(fileContent) + { + //signal_draw().connect(sigc::mem_fun(*this, &GtkGif::updateContent)); + set_app_paintable(true); + } + + bool GtkGif::createTexture(int width, int height) + { + surface = Cairo::ImageSurface::create(Cairo::Format::FORMAT_ARGB32, width, height); + return true; + } + + void GtkGif::updateTexture(void *textureData) + { + unsigned char *pixels = surface->get_data(); + memcpy(pixels, textureData, surface->get_stride() * surface->get_height()); + } + + bool GtkGif::on_draw(const Cairo::RefPtr &cairo) + { + update(); + cairo->set_source(surface, 0.0, 0.0); + cairo->fill(); + return true; + } +} \ No newline at end of file diff --git a/src/Window.cpp b/src/Window.cpp index b1efc20..6a0ab64 100644 --- a/src/Window.cpp +++ b/src/Window.cpp @@ -1,7 +1,7 @@ #include "../include/Window.hpp" -#include "../include/Cache.hpp" #include "../include/ChannelDataType.hpp" #include "../include/WindowNotification.hpp" +#include #include #include #include @@ -181,6 +181,7 @@ namespace dchat prevTimeMillis = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count() - 5000; drawBackgroundConnection = signal_draw().connect(sigc::mem_fun(*this, &Window::drawBackground)); set_size_request(640, 480); + //set_app_paintable(true); } Window::~Window() @@ -201,6 +202,11 @@ namespace dchat { int windowWidth, windowHeight; get_size(windowWidth, windowHeight); + + //cairo->set_source_rgb(0.1843137254901961, 0.19215686274509805, 0.21176470588235294); + //cairo->rectangle(0.0, 0.0, windowWidth, windowHeight); + //cairo->fill(); + cairo->set_source_rgb(0.5, 0.5, 0.5); int currentTimeMillis = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); -- cgit v1.2.3