aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2018-11-03 22:49:29 +0100
committerdec05eba <dec05eba@protonmail.com>2018-11-03 22:49:32 +0100
commitc7138bca7ea7d007198c544b2d8bc27ae414d2e2 (patch)
treeb27752bc5e4e452a9a4c047e884b8952a22a0f0a
parent405459e93be718b0e6aad26746036105dd3f3226 (diff)
Start with gif/image widget
-rw-r--r--.gitignore1
m---------depends/dchat_core0
-rw-r--r--include/ChatMessage.hpp5
-rw-r--r--include/DynamicImage.hpp18
-rw-r--r--include/GtkGif.hpp10
-rw-r--r--src/ChatMessage.cpp29
-rw-r--r--src/DynamicImage.cpp28
-rw-r--r--src/GtkGif.cpp29
-rw-r--r--src/Window.cpp7
9 files changed, 88 insertions, 39 deletions
diff --git a/.gitignore b/.gitignore
index 0dee329..b583353 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,4 @@ compile_commands.json
tests/sibs-build/
tests/compile_commands.json
.vscode/
+.gdb_history
diff --git a/depends/dchat_core b/depends/dchat_core
-Subproject c5b916157ae111da514481899d53f3e2bf5be98
+Subproject 38d987b7583cda88c0485acf0fecc65cd15edcc
diff --git a/include/ChatMessage.hpp b/include/ChatMessage.hpp
index c1ef459..5259a9c 100644
--- a/include/ChatMessage.hpp
+++ b/include/ChatMessage.hpp
@@ -1,5 +1,6 @@
#pragma once
+#include "DynamicImage.hpp"
#include <dchat/types.hpp>
#include <gtkmm/grid.h>
#include <gtkmm/label.h>
@@ -12,11 +13,9 @@ namespace dchat
public:
ChatMessage(const Glib::ustring &username, const Glib::ustring &text, uint32_t timestampSeconds);
- Gtk::Grid avatar;
+ DynamicImage avatar;
Gtk::Label username;
Gtk::Label text;
uint32_t timestampSeconds;
- private:
- bool updateContent(const Cairo::RefPtr<Cairo::Context> &cairo);
};
} \ No newline at end of file
diff --git a/include/DynamicImage.hpp b/include/DynamicImage.hpp
new file mode 100644
index 0000000..578b91a
--- /dev/null
+++ b/include/DynamicImage.hpp
@@ -0,0 +1,18 @@
+#pragma once
+
+#include <string>
+#include <gtkmm/drawingarea.h>
+
+namespace dchat
+{
+ class DynamicImage : public Gtk::DrawingArea
+ {
+ public:
+ DynamicImage(int downloadLimitBytes = 12582912);
+
+ std::string url;
+ int downloadLimitBytes;
+ private:
+ bool updateContent(const Cairo::RefPtr<Cairo::Context> &cairo);
+ };
+} \ No newline at end of file
diff --git a/include/GtkGif.hpp b/include/GtkGif.hpp
index 91b3a12..a4a28d7 100644
--- a/include/GtkGif.hpp
+++ b/include/GtkGif.hpp
@@ -1,24 +1,24 @@
#pragma once
#include <dchat/Gif.hpp>
-#include <gtkmm/drawingarea.h>
-#include <gdkmm/pixbuf.h>
+#include <cairomm/context.h>
+#include <cairomm/surface.h>
namespace dchat
{
- class GtkGif : public Gif, public Gtk::DrawingArea
+ class GtkGif : public Gif
{
public:
GtkGif(StringView fileContent);
virtual ~GtkGif(){}
+
+ void draw(const Cairo::RefPtr<Cairo::Context> &cairo, int width, int height);
protected:
// Return false if texture creation failed
bool createTexture(int width, int height) override;
// Size of texture data is same as the size that the texture was created with (also same size returned by @getSize function)
void updateTexture(void *textureData) override;
private:
- bool on_draw(const Cairo::RefPtr<Cairo::Context> &cairo) override;
- private:
Cairo::RefPtr<Cairo::ImageSurface> surface;
};
} \ No newline at end of file
diff --git a/src/ChatMessage.cpp b/src/ChatMessage.cpp
index d48a6a9..fe3afdc 100644
--- a/src/ChatMessage.cpp
+++ b/src/ChatMessage.cpp
@@ -1,6 +1,4 @@
#include "../include/ChatMessage.hpp"
-#include "../include/GlobalCache.hpp"
-#include "../include/GtkGif.hpp"
namespace dchat
{
@@ -11,6 +9,8 @@ namespace dchat
{
avatar.set_halign(Gtk::ALIGN_START);
avatar.set_valign(Gtk::ALIGN_START);
+ avatar.set_size_request(50, 50);
+ avatar.url = "https://discordemoji.com/assets/emoji/7752_PepePOOGERSFAST.gif";
username.set_selectable(true);
username.set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_START);
@@ -20,6 +20,7 @@ namespace dchat
text.set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_START);
text.set_line_wrap(true);
text.set_line_wrap_mode(Pango::WRAP_WORD_CHAR);
+ text.set_vexpand(true);
text.get_style_context()->add_class("chat-message-text");
attach(avatar, 0, 0, 1, 2);
@@ -27,26 +28,8 @@ namespace dchat
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::Context> &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;
+ set_column_spacing(10);
+ set_row_spacing(0);
+ set_vexpand(false);
}
} \ No newline at end of file
diff --git a/src/DynamicImage.cpp b/src/DynamicImage.cpp
new file mode 100644
index 0000000..8759497
--- /dev/null
+++ b/src/DynamicImage.cpp
@@ -0,0 +1,28 @@
+#include "../include/DynamicImage.hpp"
+#include "../include/GlobalCache.hpp"
+#include "../include/GtkGif.hpp"
+
+namespace dchat
+{
+ DynamicImage::DynamicImage(int _downloadLimitBytes) :
+ downloadLimitBytes(_downloadLimitBytes)
+ {
+ signal_draw().connect(sigc::mem_fun(*this, &DynamicImage::updateContent));
+ }
+
+ bool DynamicImage::updateContent(const Cairo::RefPtr<Cairo::Context> &cairo)
+ {
+ if(!url.empty())
+ {
+ Gtk::Allocation alloc = get_allocation();
+ auto result = getGlobalCache().getContentByUrl(url, downloadLimitBytes);
+ if(result.type == ContentByUrlResult::Type::CACHED && result.gif)
+ {
+ GtkGif *gif = (GtkGif*)result.gif;
+ gif->draw(cairo, alloc.get_width(), alloc.get_height());
+ }
+ }
+ queue_draw();
+ return true;
+ }
+} \ No newline at end of file
diff --git a/src/GtkGif.cpp b/src/GtkGif.cpp
index 1da48a8..92aae88 100644
--- a/src/GtkGif.cpp
+++ b/src/GtkGif.cpp
@@ -5,8 +5,7 @@ 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)
@@ -18,14 +17,32 @@ namespace dchat
void GtkGif::updateTexture(void *textureData)
{
unsigned char *pixels = surface->get_data();
- memcpy(pixels, textureData, surface->get_stride() * surface->get_height());
+ surface->flush();
+ char *p = (char*)textureData;
+ // TODO: Optimize this
+ for(int i = 0; i < surface->get_stride() * surface->get_height(); i += 4)
+ {
+ pixels[i + 0] = p[i + 2];
+ pixels[i + 1] = p[i + 1];
+ pixels[i + 2] = p[i + 0];
+ pixels[i + 3] = p[i + 3];
+ }
+ //memcpy(pixels, textureData, surface->get_stride() * surface->get_height());
+ surface->mark_dirty();
}
- bool GtkGif::on_draw(const Cairo::RefPtr<Cairo::Context> &cairo)
+ void GtkGif::draw(const Cairo::RefPtr<Cairo::Context> &cairo, int width, int height)
{
update();
+
+ int minSize = std::min(width/2, height/2);
+ cairo->arc(width/2, height/2, minSize, 0.0, 2.0 * M_PI);
+ cairo->clip();
+
+ double scaleX = (double)width / (double)surface->get_width();
+ double scaleY = (double)height / (double)surface->get_height();
+ cairo->scale(scaleX, scaleY);
cairo->set_source(surface, 0.0, 0.0);
- cairo->fill();
- return true;
+ cairo->paint();
}
} \ No newline at end of file
diff --git a/src/Window.cpp b/src/Window.cpp
index 8b23aa9..b5a9f26 100644
--- a/src/Window.cpp
+++ b/src/Window.cpp
@@ -43,7 +43,7 @@ namespace dchat
{
fprintf(stderr, "Trying to login with username %s\n", username.raw().c_str());
rooms->loginUser(username.raw(), password.raw());
- windowNotification->show(Glib::ustring("Successfully logged in as ") + username);
+ //windowNotification->show(Glib::ustring("Successfully logged in as ") + username);
drawBackgroundConnection.disconnect();
chatWindow.show_all();
stack.set_visible_child(chatWindow);
@@ -260,7 +260,10 @@ namespace dchat
//cairo->paint();
*/
- overlay.draw(cairo);
+ Gtk::Allocation alloc = overlay.get_allocation();
+ // For some reason gtk sometimes needs time to allocate the overlay, and it freezes the application if you do not wait for it
+ if(!alloc.has_zero_area())
+ overlay.draw(cairo);
queue_draw();
return true;
}