mirror of
https://github.com/uowuo/abaddon.git
synced 2024-09-20 06:51:51 +00:00
add ugly little mention indicator to classic guild listing
This commit is contained in:
parent
a4856a5378
commit
057dd2a1f8
|
@ -1,13 +1,15 @@
|
||||||
#include "cellrendererchannels.hpp"
|
#include "cellrendererchannels.hpp"
|
||||||
|
|
||||||
#include <gdkmm/general.h>
|
#include <gdkmm/general.h>
|
||||||
|
|
||||||
|
#include "misc/cairo.hpp"
|
||||||
|
|
||||||
#include "abaddon.hpp"
|
#include "abaddon.hpp"
|
||||||
|
|
||||||
constexpr static int MentionsRightPad = 7;
|
constexpr static int MentionsRightPad = 7;
|
||||||
#ifndef M_PI
|
#ifndef M_PI
|
||||||
constexpr static double M_PI = 3.14159265358979;
|
constexpr static double M_PI = 3.14159265358979;
|
||||||
#endif
|
#endif
|
||||||
constexpr static double M_PI_H = M_PI / 2.0;
|
|
||||||
constexpr static double M_PI_3_2 = M_PI * 3.0 / 2.0;
|
|
||||||
|
|
||||||
void AddUnreadIndicator(const Cairo::RefPtr<Cairo::Context> &cr, Gtk::Widget &widget, const Gdk::Rectangle &background_area) {
|
void AddUnreadIndicator(const Cairo::RefPtr<Cairo::Context> &cr, Gtk::Widget &widget, const Gdk::Rectangle &background_area) {
|
||||||
static const auto color_setting = Gdk::RGBA(Abaddon::Get().GetSettings().UnreadIndicatorColor);
|
static const auto color_setting = Gdk::RGBA(Abaddon::Get().GetSettings().UnreadIndicatorColor);
|
||||||
|
@ -832,17 +834,6 @@ void CellRendererChannels::render_vfunc_dm(const Cairo::RefPtr<Cairo::Context> &
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CellRendererChannels::cairo_path_rounded_rect(const Cairo::RefPtr<Cairo::Context> &cr, double x, double y, double w, double h, double r) {
|
|
||||||
const double degrees = M_PI / 180.0;
|
|
||||||
|
|
||||||
cr->begin_new_sub_path();
|
|
||||||
cr->arc(x + w - r, y + r, r, -M_PI_H, 0);
|
|
||||||
cr->arc(x + w - r, y + h - r, r, 0, M_PI_H);
|
|
||||||
cr->arc(x + r, y + h - r, r, M_PI_H, M_PI);
|
|
||||||
cr->arc(x + r, y + r, r, M_PI, M_PI_3_2);
|
|
||||||
cr->close_path();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CellRendererChannels::unread_render_mentions(const Cairo::RefPtr<Cairo::Context> &cr, Gtk::Widget &widget, int mentions, int edge, const Gdk::Rectangle &cell_area) {
|
void CellRendererChannels::unread_render_mentions(const Cairo::RefPtr<Cairo::Context> &cr, Gtk::Widget &widget, int mentions, int edge, const Gdk::Rectangle &cell_area) {
|
||||||
Pango::FontDescription font;
|
Pango::FontDescription font;
|
||||||
font.set_family("sans 14");
|
font.set_family("sans 14");
|
||||||
|
@ -863,7 +854,7 @@ void CellRendererChannels::unread_render_mentions(const Cairo::RefPtr<Cairo::Con
|
||||||
|
|
||||||
const auto x = cell_area.get_x() + edge - width - MentionsRightPad;
|
const auto x = cell_area.get_x() + edge - width - MentionsRightPad;
|
||||||
const auto y = cell_area.get_y() + cell_area.get_height() / 2.0 - height / 2.0 - 1;
|
const auto y = cell_area.get_y() + cell_area.get_height() / 2.0 - height / 2.0 - 1;
|
||||||
cairo_path_rounded_rect(cr, x - 4, y + 2, width + 8, height, 5);
|
CairoUtil::PathRoundedRect(cr, x - 4, y + 2, width + 8, height, 5);
|
||||||
cr->set_source_rgb(bg.get_red(), bg.get_green(), bg.get_blue());
|
cr->set_source_rgb(bg.get_red(), bg.get_green(), bg.get_blue());
|
||||||
cr->fill();
|
cr->fill();
|
||||||
cr->set_source_rgb(text.get_red(), text.get_green(), text.get_blue());
|
cr->set_source_rgb(text.get_red(), text.get_green(), text.get_blue());
|
||||||
|
|
|
@ -153,7 +153,6 @@ protected:
|
||||||
const Gdk::Rectangle &cell_area,
|
const Gdk::Rectangle &cell_area,
|
||||||
Gtk::CellRendererState flags);
|
Gtk::CellRendererState flags);
|
||||||
|
|
||||||
static void cairo_path_rounded_rect(const Cairo::RefPtr<Cairo::Context> &cr, double x, double y, double w, double h, double r);
|
|
||||||
static void unread_render_mentions(const Cairo::RefPtr<Cairo::Context> &cr, Gtk::Widget &widget, int mentions, int edge, const Gdk::Rectangle &cell_area);
|
static void unread_render_mentions(const Cairo::RefPtr<Cairo::Context> &cr, Gtk::Widget &widget, int mentions, int edge, const Gdk::Rectangle &cell_area);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include "abaddon.hpp"
|
#include "abaddon.hpp"
|
||||||
#include "util.hpp"
|
#include "util.hpp"
|
||||||
#include "guildlistfolderitem.hpp"
|
#include "guildlistfolderitem.hpp"
|
||||||
|
#include "mentionoverlay.hpp"
|
||||||
|
|
||||||
class GuildListDMsButton : public Gtk::EventBox {
|
class GuildListDMsButton : public Gtk::EventBox {
|
||||||
public:
|
public:
|
||||||
|
@ -93,10 +94,19 @@ void GuildList::UpdateListing() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Gtk::Widget *AddMentionOverlay(Gtk::Widget *widget, Snowflake guild_id) {
|
||||||
|
auto *overlay = Gtk::make_managed<Gtk::Overlay>();
|
||||||
|
overlay->add(*widget);
|
||||||
|
auto *mention_overlay = Gtk::make_managed<MentionOverlay>(guild_id);
|
||||||
|
overlay->add_overlay(*mention_overlay);
|
||||||
|
overlay->show_all();
|
||||||
|
return overlay;
|
||||||
|
}
|
||||||
|
|
||||||
void GuildList::AddGuild(Snowflake id) {
|
void GuildList::AddGuild(Snowflake id) {
|
||||||
if (auto item = CreateGuildWidget(id)) {
|
if (auto item = CreateGuildWidget(id)) {
|
||||||
item->show();
|
item->show();
|
||||||
add(*item);
|
add(*AddMentionOverlay(item, id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,7 +142,7 @@ void GuildList::AddFolder(const UserSettingsGuildFoldersEntry &folder) {
|
||||||
for (const auto guild_id : folder.GuildIDs) {
|
for (const auto guild_id : folder.GuildIDs) {
|
||||||
if (auto *guild_widget = CreateGuildWidget(guild_id)) {
|
if (auto *guild_widget = CreateGuildWidget(guild_id)) {
|
||||||
guild_widget->show();
|
guild_widget->show();
|
||||||
folder_widget->AddGuildWidget(guild_widget);
|
folder_widget->AddGuildWidget(AddMentionOverlay(guild_widget, guild_id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -95,7 +95,7 @@ GuildListFolderItem::GuildListFolderItem(const UserSettingsGuildFoldersEntry &fo
|
||||||
CheckUnreadStatus();
|
CheckUnreadStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GuildListFolderItem::AddGuildWidget(GuildListGuildItem *widget) {
|
void GuildListFolderItem::AddGuildWidget(Gtk::Widget *widget) {
|
||||||
m_box.add(*widget);
|
m_box.add(*widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ class GuildListFolderItem : public Gtk::VBox {
|
||||||
public:
|
public:
|
||||||
GuildListFolderItem(const UserSettingsGuildFoldersEntry &folder);
|
GuildListFolderItem(const UserSettingsGuildFoldersEntry &folder);
|
||||||
|
|
||||||
void AddGuildWidget(GuildListGuildItem *widget);
|
void AddGuildWidget(Gtk::Widget *widget);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void OnMessageCreate(const Message &msg);
|
void OnMessageCreate(const Message &msg);
|
||||||
|
|
62
src/components/channellist/classic/mentionoverlay.cpp
Normal file
62
src/components/channellist/classic/mentionoverlay.cpp
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
#include "mentionoverlay.hpp"
|
||||||
|
|
||||||
|
#include "misc/cairo.hpp"
|
||||||
|
|
||||||
|
#include "abaddon.hpp"
|
||||||
|
|
||||||
|
MentionOverlay::MentionOverlay(Snowflake guild_id)
|
||||||
|
: m_guild_id(guild_id) {
|
||||||
|
m_font.set_family("sans 14");
|
||||||
|
m_layout = create_pango_layout("12");
|
||||||
|
m_layout->set_font_description(m_font);
|
||||||
|
m_layout->set_alignment(Pango::ALIGN_RIGHT);
|
||||||
|
|
||||||
|
get_style_context()->add_class("classic-mention-overlay"); // fuck you
|
||||||
|
|
||||||
|
set_hexpand(false);
|
||||||
|
set_vexpand(false);
|
||||||
|
|
||||||
|
signal_draw().connect(sigc::mem_fun(*this, &MentionOverlay::OnDraw));
|
||||||
|
|
||||||
|
Abaddon::Get().GetDiscordClient().signal_message_ack().connect([this](const MessageAckData &data) {
|
||||||
|
// fetching and checking guild id is probably more expensive than just forcing a redraw anyways
|
||||||
|
queue_draw();
|
||||||
|
});
|
||||||
|
|
||||||
|
Abaddon::Get().GetDiscordClient().signal_message_create().connect([this](const Message &msg) {
|
||||||
|
if (msg.GuildID.has_value() && *msg.GuildID != m_guild_id) return;
|
||||||
|
if (!msg.DoesMentionEveryone && msg.Mentions.empty() && msg.MentionRoles.empty()) return;
|
||||||
|
queue_draw();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MentionOverlay::OnDraw(const Cairo::RefPtr<Cairo::Context> &cr) {
|
||||||
|
int mentions;
|
||||||
|
Abaddon::Get().GetDiscordClient().GetUnreadStateForGuild(m_guild_id, mentions);
|
||||||
|
if (mentions == 0) return true;
|
||||||
|
m_layout->set_text(std::to_string(mentions));
|
||||||
|
|
||||||
|
const int width = get_allocated_width();
|
||||||
|
const int height = get_allocated_height();
|
||||||
|
|
||||||
|
int lw, lh;
|
||||||
|
m_layout->get_pixel_size(lw, lh);
|
||||||
|
{
|
||||||
|
static const auto badge_setting = Gdk::RGBA(Abaddon::Get().GetSettings().MentionBadgeColor);
|
||||||
|
static const auto text_setting = Gdk::RGBA(Abaddon::Get().GetSettings().MentionBadgeTextColor);
|
||||||
|
|
||||||
|
auto bg = badge_setting.get_alpha_u() > 0 ? badge_setting : get_style_context()->get_background_color(Gtk::STATE_FLAG_SELECTED);
|
||||||
|
auto text = text_setting.get_alpha_u() > 0 ? text_setting : get_style_context()->get_color(Gtk::STATE_FLAG_SELECTED);
|
||||||
|
|
||||||
|
const auto x = width - lw - 5;
|
||||||
|
const auto y = height - lh - 1;
|
||||||
|
CairoUtil::PathRoundedRect(cr, x - 4, y + 2, lw + 8, lh, 5);
|
||||||
|
cr->set_source_rgb(bg.get_red(), bg.get_green(), bg.get_blue());
|
||||||
|
cr->fill();
|
||||||
|
cr->set_source_rgb(text.get_red(), text.get_green(), text.get_blue());
|
||||||
|
cr->move_to(x, y);
|
||||||
|
m_layout->show_in_cairo_context(cr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
19
src/components/channellist/classic/mentionoverlay.hpp
Normal file
19
src/components/channellist/classic/mentionoverlay.hpp
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <gtkmm/drawingarea.h>
|
||||||
|
#include <pangomm/fontdescription.h>
|
||||||
|
|
||||||
|
#include "discord/snowflake.hpp"
|
||||||
|
|
||||||
|
class MentionOverlay : public Gtk::DrawingArea {
|
||||||
|
public:
|
||||||
|
MentionOverlay(Snowflake guild_id);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool OnDraw(const Cairo::RefPtr<Cairo::Context> &cr);
|
||||||
|
|
||||||
|
Snowflake m_guild_id;
|
||||||
|
|
||||||
|
Pango::FontDescription m_font;
|
||||||
|
Glib::RefPtr<Pango::Layout> m_layout;
|
||||||
|
};
|
17
src/misc/cairo.cpp
Normal file
17
src/misc/cairo.cpp
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
#include "cairo.hpp"
|
||||||
|
|
||||||
|
#include <cairomm/context.h>
|
||||||
|
|
||||||
|
constexpr static double M_PI_H = M_PI / 2.0;
|
||||||
|
constexpr static double M_PI_3_2 = M_PI * 3.0 / 2.0;
|
||||||
|
|
||||||
|
void CairoUtil::PathRoundedRect(const Cairo::RefPtr<Cairo::Context> &cr, double x, double y, double w, double h, double r) {
|
||||||
|
const double degrees = M_PI / 180.0;
|
||||||
|
|
||||||
|
cr->begin_new_sub_path();
|
||||||
|
cr->arc(x + w - r, y + r, r, -M_PI_H, 0);
|
||||||
|
cr->arc(x + w - r, y + h - r, r, 0, M_PI_H);
|
||||||
|
cr->arc(x + r, y + h - r, r, M_PI_H, M_PI);
|
||||||
|
cr->arc(x + r, y + r, r, M_PI, M_PI_3_2);
|
||||||
|
cr->close_path();
|
||||||
|
}
|
5
src/misc/cairo.hpp
Normal file
5
src/misc/cairo.hpp
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace CairoUtil {
|
||||||
|
void PathRoundedRect(const Cairo::RefPtr<Cairo::Context> &cr, double x, double y, double w, double h, double r);
|
||||||
|
} // namespace CairoUtil
|
Loading…
Reference in New Issue
Block a user