summaryrefslogtreecommitdiff
path: root/src/components
diff options
context:
space:
mode:
authorouwou <26526779+ouwou@users.noreply.github.com>2024-05-21 02:06:20 -0400
committerouwou <26526779+ouwou@users.noreply.github.com>2024-05-21 02:06:20 -0400
commit057dd2a1f8de65e4885f48211e324e1b966f4e2f (patch)
tree3c6d44061589b636ac9624a988baae969a1c6b80 /src/components
parenta4856a5378507bc5d32c86d638a7175c29bf4301 (diff)
downloadabaddon-portaudio-057dd2a1f8de65e4885f48211e324e1b966f4e2f.tar.gz
abaddon-portaudio-057dd2a1f8de65e4885f48211e324e1b966f4e2f.zip
add ugly little mention indicator to classic guild listing
Diffstat (limited to 'src/components')
-rw-r--r--src/components/channellist/cellrendererchannels.cpp19
-rw-r--r--src/components/channellist/cellrendererchannels.hpp1
-rw-r--r--src/components/channellist/classic/guildlist.cpp14
-rw-r--r--src/components/channellist/classic/guildlistfolderitem.cpp2
-rw-r--r--src/components/channellist/classic/guildlistfolderitem.hpp2
-rw-r--r--src/components/channellist/classic/mentionoverlay.cpp62
-rw-r--r--src/components/channellist/classic/mentionoverlay.hpp19
7 files changed, 100 insertions, 19 deletions
diff --git a/src/components/channellist/cellrendererchannels.cpp b/src/components/channellist/cellrendererchannels.cpp
index b049252..bb2b9ba 100644
--- a/src/components/channellist/cellrendererchannels.cpp
+++ b/src/components/channellist/cellrendererchannels.cpp
@@ -1,13 +1,15 @@
#include "cellrendererchannels.hpp"
+
#include <gdkmm/general.h>
+
+#include "misc/cairo.hpp"
+
#include "abaddon.hpp"
constexpr static int MentionsRightPad = 7;
#ifndef M_PI
constexpr static double M_PI = 3.14159265358979;
#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) {
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) {
Pango::FontDescription font;
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 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->fill();
cr->set_source_rgb(text.get_red(), text.get_green(), text.get_blue());
diff --git a/src/components/channellist/cellrendererchannels.hpp b/src/components/channellist/cellrendererchannels.hpp
index e142b2a..a313dc7 100644
--- a/src/components/channellist/cellrendererchannels.hpp
+++ b/src/components/channellist/cellrendererchannels.hpp
@@ -153,7 +153,6 @@ protected:
const Gdk::Rectangle &cell_area,
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);
private:
diff --git a/src/components/channellist/classic/guildlist.cpp b/src/components/channellist/classic/guildlist.cpp
index 6a6e3d4..17cd79a 100644
--- a/src/components/channellist/classic/guildlist.cpp
+++ b/src/components/channellist/classic/guildlist.cpp
@@ -3,6 +3,7 @@
#include "abaddon.hpp"
#include "util.hpp"
#include "guildlistfolderitem.hpp"
+#include "mentionoverlay.hpp"
class GuildListDMsButton : public Gtk::EventBox {
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) {
if (auto item = CreateGuildWidget(id)) {
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) {
if (auto *guild_widget = CreateGuildWidget(guild_id)) {
guild_widget->show();
- folder_widget->AddGuildWidget(guild_widget);
+ folder_widget->AddGuildWidget(AddMentionOverlay(guild_widget, guild_id));
}
}
diff --git a/src/components/channellist/classic/guildlistfolderitem.cpp b/src/components/channellist/classic/guildlistfolderitem.cpp
index e062d42..337d4b3 100644
--- a/src/components/channellist/classic/guildlistfolderitem.cpp
+++ b/src/components/channellist/classic/guildlistfolderitem.cpp
@@ -95,7 +95,7 @@ GuildListFolderItem::GuildListFolderItem(const UserSettingsGuildFoldersEntry &fo
CheckUnreadStatus();
}
-void GuildListFolderItem::AddGuildWidget(GuildListGuildItem *widget) {
+void GuildListFolderItem::AddGuildWidget(Gtk::Widget *widget) {
m_box.add(*widget);
}
diff --git a/src/components/channellist/classic/guildlistfolderitem.hpp b/src/components/channellist/classic/guildlistfolderitem.hpp
index e5772c0..06d05f1 100644
--- a/src/components/channellist/classic/guildlistfolderitem.hpp
+++ b/src/components/channellist/classic/guildlistfolderitem.hpp
@@ -24,7 +24,7 @@ class GuildListFolderItem : public Gtk::VBox {
public:
GuildListFolderItem(const UserSettingsGuildFoldersEntry &folder);
- void AddGuildWidget(GuildListGuildItem *widget);
+ void AddGuildWidget(Gtk::Widget *widget);
private:
void OnMessageCreate(const Message &msg);
diff --git a/src/components/channellist/classic/mentionoverlay.cpp b/src/components/channellist/classic/mentionoverlay.cpp
new file mode 100644
index 0000000..c734ced
--- /dev/null
+++ b/src/components/channellist/classic/mentionoverlay.cpp
@@ -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;
+}
diff --git a/src/components/channellist/classic/mentionoverlay.hpp b/src/components/channellist/classic/mentionoverlay.hpp
new file mode 100644
index 0000000..24eb7e2
--- /dev/null
+++ b/src/components/channellist/classic/mentionoverlay.hpp
@@ -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;
+};