forked from OpenGamers/abaddon
support animated guild icon
This commit is contained in:
parent
486d184c83
commit
d8ff05ddf8
|
@ -119,13 +119,25 @@ ChannelListRowGuild::ChannelListRowGuild(const Guild *data) {
|
|||
|
||||
m_menu.show_all();
|
||||
|
||||
const auto show_animations = Abaddon::Get().GetSettings().GetShowAnimations();
|
||||
auto &img = Abaddon::Get().GetImageManager();
|
||||
if (data->HasIcon()) {
|
||||
auto buf = Abaddon::Get().GetImageManager().GetFromURLIfCached(data->GetIconURL("png", "32"));
|
||||
if (buf)
|
||||
m_icon = Gtk::manage(new Gtk::Image(buf->scale_simple(24, 24, Gdk::INTERP_BILINEAR)));
|
||||
else {
|
||||
m_icon = Gtk::manage(new Gtk::Image(Abaddon::Get().GetImageManager().GetPlaceholder(24)));
|
||||
Abaddon::Get().GetImageManager().LoadFromURL(data->GetIconURL("png", "32"), sigc::mem_fun(*this, &ChannelListRowGuild::OnImageLoad));
|
||||
if (data->HasAnimatedIcon() && show_animations) {
|
||||
auto buf = img.GetAnimationFromURLIfCached(data->GetIconURL("gif", "32"), 24, 24);
|
||||
if (buf)
|
||||
m_icon = Gtk::manage(new Gtk::Image(buf));
|
||||
else {
|
||||
m_icon = Gtk::manage(new Gtk::Image(img.GetPlaceholder(24)));
|
||||
img.LoadAnimationFromURL(data->GetIconURL("gif", "32"), 24, 24, sigc::mem_fun(*this, &ChannelListRowGuild::OnAnimatedImageLoad));
|
||||
}
|
||||
} else {
|
||||
auto buf = img.GetFromURLIfCached(data->GetIconURL("png", "32"));
|
||||
if (buf)
|
||||
m_icon = Gtk::manage(new Gtk::Image(buf->scale_simple(24, 24, Gdk::INTERP_BILINEAR)));
|
||||
else {
|
||||
m_icon = Gtk::manage(new Gtk::Image(img.GetPlaceholder(24)));
|
||||
img.LoadFromURL(data->GetIconURL("png", "32"), sigc::mem_fun(*this, &ChannelListRowGuild::OnImageLoad));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
m_icon = Gtk::manage(new Gtk::Image(Abaddon::Get().GetImageManager().GetPlaceholder(24)));
|
||||
|
@ -148,10 +160,14 @@ ChannelListRowGuild::ChannelListRowGuild(const Guild *data) {
|
|||
show_all_children();
|
||||
}
|
||||
|
||||
void ChannelListRowGuild::OnImageLoad(Glib::RefPtr<Gdk::Pixbuf> buf) {
|
||||
void ChannelListRowGuild::OnImageLoad(const Glib::RefPtr<Gdk::Pixbuf> &buf) {
|
||||
m_icon->property_pixbuf() = buf->scale_simple(24, 24, Gdk::INTERP_BILINEAR);
|
||||
}
|
||||
|
||||
void ChannelListRowGuild::OnAnimatedImageLoad(const Glib::RefPtr<Gdk::PixbufAnimation> &buf) {
|
||||
m_icon->property_pixbuf_animation() = buf;
|
||||
}
|
||||
|
||||
ChannelListRowGuild::type_signal_copy_id ChannelListRowGuild::signal_copy_id() {
|
||||
return m_signal_copy_id;
|
||||
}
|
||||
|
|
|
@ -53,7 +53,8 @@ public:
|
|||
int GuildIndex;
|
||||
|
||||
protected:
|
||||
void OnImageLoad(Glib::RefPtr<Gdk::Pixbuf> buf);
|
||||
void OnImageLoad(const Glib::RefPtr<Gdk::Pixbuf> &buf);
|
||||
void OnAnimatedImageLoad(const Glib::RefPtr<Gdk::PixbufAnimation> &buf);
|
||||
|
||||
Gtk::EventBox *m_ev;
|
||||
Gtk::Box *m_box;
|
||||
|
|
|
@ -122,6 +122,10 @@ bool Guild::HasIcon() const {
|
|||
return Icon != "";
|
||||
}
|
||||
|
||||
bool Guild::HasAnimatedIcon() const {
|
||||
return HasIcon() && Icon[0] == 'a' && Icon[1] == '_';
|
||||
}
|
||||
|
||||
std::string Guild::GetIconURL(std::string ext, std::string size) const {
|
||||
return "https://cdn.discordapp.com/icons/" + std::to_string(ID) + "/" + Icon + "." + ext + "?size=" + size;
|
||||
}
|
||||
|
|
|
@ -68,6 +68,7 @@ struct Guild {
|
|||
void update_from_json(const nlohmann::json &j);
|
||||
|
||||
bool HasIcon() const;
|
||||
bool HasAnimatedIcon() const;
|
||||
std::string GetIconURL(std::string ext = "png", std::string size = "32") const;
|
||||
std::vector<Snowflake> GetSortedChannels(Snowflake ignore = Snowflake::Invalid) const;
|
||||
};
|
||||
|
|
|
@ -20,9 +20,19 @@ Glib::RefPtr<Gdk::Pixbuf> ImageManager::ReadFileToPixbuf(std::string path) {
|
|||
});
|
||||
loader->write(static_cast<const guint8 *>(data.data()), data.size());
|
||||
loader->close();
|
||||
auto buf = loader->get_pixbuf();
|
||||
return loader->get_pixbuf();
|
||||
}
|
||||
|
||||
return buf;
|
||||
Glib::RefPtr<Gdk::PixbufAnimation> ImageManager::ReadFileToPixbufAnimation(std::string path, int w, int h) {
|
||||
const auto &data = ReadWholeFile(path);
|
||||
if (data.size() == 0) return Glib::RefPtr<Gdk::PixbufAnimation>(nullptr);
|
||||
auto loader = Gdk::PixbufLoader::create();
|
||||
loader->signal_size_prepared().connect([&loader, w, h](int, int) {
|
||||
loader->set_size(w, h);
|
||||
});
|
||||
loader->write(static_cast<const guint8 *>(data.data()), data.size());
|
||||
loader->close();
|
||||
return loader->get_animation();
|
||||
}
|
||||
|
||||
void ImageManager::LoadFromURL(std::string url, callback_type cb) {
|
||||
|
@ -35,12 +45,28 @@ void ImageManager::LoadFromURL(std::string url, callback_type cb) {
|
|||
m_cb_queue.push([signal, buf]() { signal.emit(buf); });
|
||||
m_cb_dispatcher.emit();
|
||||
m_cb_mutex.unlock();
|
||||
} catch (std::exception &e) {
|
||||
} catch (const std::exception &e) {
|
||||
fprintf(stderr, "err loading pixbuf from %s: %s\n", path.c_str(), e.what());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void ImageManager::LoadAnimationFromURL(std::string url, int w, int h, callback_anim_type cb) {
|
||||
sigc::signal<void(Glib::RefPtr<Gdk::PixbufAnimation>)> signal;
|
||||
signal.connect(cb);
|
||||
m_cache.GetFileFromURL(url, [this, url, signal, w, h](std::string path) {
|
||||
try {
|
||||
auto buf = ReadFileToPixbufAnimation(path, w, h);
|
||||
m_cb_mutex.lock();
|
||||
m_cb_queue.push([signal, buf]() { signal.emit(buf); });
|
||||
m_cb_dispatcher.emit();
|
||||
m_cb_mutex.unlock();
|
||||
} catch (const std::exception &e) {
|
||||
fprintf(stderr, "err loading pixbuf animation from %s: %s\n", path.c_str(), e.what());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void ImageManager::Prefetch(std::string url) {
|
||||
m_cache.GetFileFromURL(url, [](const auto &) {});
|
||||
}
|
||||
|
@ -60,6 +86,14 @@ Glib::RefPtr<Gdk::Pixbuf> ImageManager::GetFromURLIfCached(std::string url) {
|
|||
return Glib::RefPtr<Gdk::Pixbuf>(nullptr);
|
||||
}
|
||||
|
||||
Glib::RefPtr<Gdk::PixbufAnimation> ImageManager::GetAnimationFromURLIfCached(std::string url, int w, int h) {
|
||||
std::string path = m_cache.GetPathIfCached(url);
|
||||
if (path != "")
|
||||
return ReadFileToPixbufAnimation(path, w, h);
|
||||
|
||||
return Glib::RefPtr<Gdk::PixbufAnimation>(nullptr);
|
||||
}
|
||||
|
||||
Glib::RefPtr<Gdk::Pixbuf> ImageManager::GetPlaceholder(int size) {
|
||||
std::string name = "/placeholder" + std::to_string(size);
|
||||
if (m_pixs.find(name) != m_pixs.end())
|
||||
|
|
|
@ -10,16 +10,21 @@ class ImageManager {
|
|||
public:
|
||||
ImageManager();
|
||||
|
||||
using callback_anim_type = sigc::slot<void(Glib::RefPtr<Gdk::PixbufAnimation>)>;
|
||||
using callback_type = sigc::slot<void(Glib::RefPtr<Gdk::Pixbuf>)>;
|
||||
|
||||
Cache &GetCache();
|
||||
void LoadFromURL(std::string url, callback_type cb);
|
||||
// animations need dimensions before loading since there is no (easy) way to scale a PixbufAnimation
|
||||
void LoadAnimationFromURL(std::string url, int w, int h, callback_anim_type cb);
|
||||
void Prefetch(std::string url);
|
||||
Glib::RefPtr<Gdk::Pixbuf> GetFromURLIfCached(std::string url);
|
||||
Glib::RefPtr<Gdk::PixbufAnimation> GetAnimationFromURLIfCached(std::string url, int w, int h);
|
||||
Glib::RefPtr<Gdk::Pixbuf> GetPlaceholder(int size);
|
||||
|
||||
private:
|
||||
Glib::RefPtr<Gdk::Pixbuf> ReadFileToPixbuf(std::string path);
|
||||
Glib::RefPtr<Gdk::PixbufAnimation> ReadFileToPixbufAnimation(std::string path, int w, int h);
|
||||
|
||||
mutable std::mutex m_load_mutex;
|
||||
void RunCallbacks();
|
||||
|
|
|
@ -73,3 +73,7 @@ bool SettingsManager::GetPrefetch() const {
|
|||
std::string SettingsManager::GetMainCSS() const {
|
||||
return GetSettingString("gui", "css", "./css/main.css");
|
||||
}
|
||||
|
||||
bool SettingsManager::GetShowAnimations() const {
|
||||
return GetSettingBool("gui", "animations", true);
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ public:
|
|||
int GetCacheHTTPConcurrency() const;
|
||||
bool GetPrefetch() const;
|
||||
std::string GetMainCSS() const;
|
||||
bool GetShowAnimations() const;
|
||||
|
||||
bool IsValid() const;
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user