mirror of
https://github.com/uowuo/abaddon.git
synced 2024-11-10 06:00:10 +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 <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());
|
||||
|
@ -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:
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
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