Skip to content

Commit

Permalink
add ugly little mention indicator to classic guild listing
Browse files Browse the repository at this point in the history
  • Loading branch information
ouwou committed May 21, 2024
1 parent a4856a5 commit 057dd2a
Show file tree
Hide file tree
Showing 9 changed files with 122 additions and 19 deletions.
19 changes: 5 additions & 14 deletions src/components/channellist/cellrendererchannels.cpp
Original file line number Diff line number Diff line change
@@ -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);
Expand Down Expand Up @@ -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");
Expand All @@ -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());
Expand Down
1 change: 0 additions & 1 deletion src/components/channellist/cellrendererchannels.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,6 @@ class CellRendererChannels : public Gtk::CellRenderer {
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:
Expand Down
14 changes: 12 additions & 2 deletions src/components/channellist/classic/guildlist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "abaddon.hpp"
#include "util.hpp"
#include "guildlistfolderitem.hpp"
#include "mentionoverlay.hpp"

class GuildListDMsButton : public Gtk::EventBox {
public:
Expand Down Expand Up @@ -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));
}
}

Expand Down Expand Up @@ -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));
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/components/channellist/classic/guildlistfolderitem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
2 changes: 1 addition & 1 deletion src/components/channellist/classic/guildlistfolderitem.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
62 changes: 62 additions & 0 deletions src/components/channellist/classic/mentionoverlay.cpp
Original file line number Diff line number Diff line change
@@ -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 changes: 19 additions & 0 deletions src/components/channellist/classic/mentionoverlay.hpp
Original file line number Diff line number Diff line change
@@ -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 changes: 17 additions & 0 deletions src/misc/cairo.cpp
Original file line number Diff line number Diff line change
@@ -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 changes: 5 additions & 0 deletions src/misc/cairo.hpp
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 057dd2a

Please sign in to comment.