summaryrefslogtreecommitdiff
path: root/src/components
diff options
context:
space:
mode:
authorouwou <26526779+ouwou@users.noreply.github.com>2023-12-27 01:57:22 -0500
committerouwou <26526779+ouwou@users.noreply.github.com>2023-12-27 01:57:22 -0500
commit1bb749687b92fa7fbccb77ee18654210a647a1f3 (patch)
tree68b79b6ca1ef7b3c17c4ada5655255c20f2fa8d3 /src/components
parent8bd628c1776c20dbf41d2fb18f6204c4a398da0e (diff)
parent155d95e29cc50a66cbe7711b172b195be637bc48 (diff)
downloadabaddon-portaudio-1bb749687b92fa7fbccb77ee18654210a647a1f3.tar.gz
abaddon-portaudio-1bb749687b92fa7fbccb77ee18654210a647a1f3.zip
Merge branch 'master' into classic-channels
Diffstat (limited to 'src/components')
-rw-r--r--src/components/cellrenderermemberlist.cpp34
-rw-r--r--src/components/cellrenderermemberlist.hpp3
-rw-r--r--src/components/channellist/cellrendererchannels.cpp229
-rw-r--r--src/components/channellist/channellisttree.cpp1
-rw-r--r--src/components/chatinput.cpp82
-rw-r--r--src/components/chatinput.hpp20
-rw-r--r--src/components/chatmessage.cpp33
-rw-r--r--src/components/chatwindow.cpp10
-rw-r--r--src/components/memberlist.cpp19
-rw-r--r--src/components/memberlist.hpp3
-rw-r--r--src/components/progressbar.cpp19
-rw-r--r--src/components/progressbar.hpp11
-rw-r--r--src/components/statusindicator.cpp122
-rw-r--r--src/components/statusindicator.hpp29
14 files changed, 226 insertions, 389 deletions
diff --git a/src/components/cellrenderermemberlist.cpp b/src/components/cellrenderermemberlist.cpp
index 66b223e..ee1ea3e 100644
--- a/src/components/cellrenderermemberlist.cpp
+++ b/src/components/cellrenderermemberlist.cpp
@@ -6,7 +6,8 @@ CellRendererMemberList::CellRendererMemberList()
, m_property_id(*this, "id")
, m_property_name(*this, "name")
, m_property_pixbuf(*this, "pixbuf")
- , m_property_color(*this, "color") {
+ , m_property_color(*this, "color")
+ , m_property_status(*this, "status") {
property_mode() = Gtk::CELL_RENDERER_MODE_ACTIVATABLE;
property_xpad() = 2;
property_ypad() = 2;
@@ -35,6 +36,10 @@ Glib::PropertyProxy<Gdk::RGBA> CellRendererMemberList::property_color() {
return m_property_color.get_proxy();
}
+Glib::PropertyProxy<PresenceStatus> CellRendererMemberList::property_status() {
+ return m_property_status.get_proxy();
+}
+
void CellRendererMemberList::get_preferred_width_vfunc(Gtk::Widget &widget, int &minimum_width, int &natural_width) const {
switch (m_property_type.get_value()) {
case MemberListRenderType::Role:
@@ -117,8 +122,9 @@ void CellRendererMemberList::get_preferred_height_for_width_vfunc_member(Gtk::Wi
}
void CellRendererMemberList::render_vfunc_member(const Cairo::RefPtr<Cairo::Context> &cr, Gtk::Widget &widget, const Gdk::Rectangle &background_area, const Gdk::Rectangle &cell_area, Gtk::CellRendererState flags) {
+ // Text
Gdk::Rectangle text_cell_area = cell_area;
- text_cell_area.set_x(22);
+ text_cell_area.set_x(31);
const auto color = m_property_color.get_value();
if (color.get_alpha_u() > 0) {
m_renderer_text.property_foreground_rgba().set_value(color);
@@ -126,6 +132,30 @@ void CellRendererMemberList::render_vfunc_member(const Cairo::RefPtr<Cairo::Cont
m_renderer_text.render(cr, widget, background_area, text_cell_area, flags);
m_renderer_text.property_foreground_set().set_value(false);
+ // Status indicator
+ // TODO: reintroduce custom status colors... somehow
+ cr->begin_new_path();
+ switch (m_property_status.get_value()) {
+ case PresenceStatus::Online:
+ cr->set_source_rgb(33.0 / 255.0, 157.0 / 255.0, 86.0 / 255.0);
+ break;
+ case PresenceStatus::Idle:
+ cr->set_source_rgb(230.0 / 255.0, 170.0 / 255.0, 48.0 / 255.0);
+ break;
+ case PresenceStatus::DND:
+ cr->set_source_rgb(233.0 / 255.0, 61.0 / 255.0, 65.0 / 255.0);
+ break;
+ case PresenceStatus::Offline:
+ cr->set_source_rgb(122.0 / 255.0, 126.0 / 255.0, 135.0 / 255.0);
+ break;
+ }
+
+ cr->arc(background_area.get_x() + 6.0 + 16.0 + 6.0, background_area.get_y() + background_area.get_height() / 2.0, 2.0, 0.0, 2 * (4 * std::atan(1)));
+ cr->close_path();
+ cr->fill_preserve();
+ cr->stroke();
+
+ // Icon
const double icon_x = background_area.get_x() + 6.0;
const double icon_y = background_area.get_y() + background_area.get_height() / 2.0 - 8.0;
Gdk::Cairo::set_source_pixbuf(cr, m_property_pixbuf.get_value(), icon_x, icon_y);
diff --git a/src/components/cellrenderermemberlist.hpp b/src/components/cellrenderermemberlist.hpp
index 7a49ccf..79d32e3 100644
--- a/src/components/cellrenderermemberlist.hpp
+++ b/src/components/cellrenderermemberlist.hpp
@@ -1,5 +1,6 @@
#pragma once
#include <gtkmm/cellrenderer.h>
+#include "discord/activity.hpp"
enum class MemberListRenderType : uint8_t {
Role,
@@ -16,6 +17,7 @@ public:
Glib::PropertyProxy<Glib::ustring> property_name();
Glib::PropertyProxy<Glib::RefPtr<Gdk::Pixbuf>> property_pixbuf();
Glib::PropertyProxy<Gdk::RGBA> property_color();
+ Glib::PropertyProxy<PresenceStatus> property_status();
protected:
void get_preferred_width_vfunc(Gtk::Widget &widget, int &minimum_width, int &natural_width) const override;
@@ -56,6 +58,7 @@ private:
Glib::Property<Glib::ustring> m_property_name;
Glib::Property<Glib::RefPtr<Gdk::Pixbuf>> m_property_pixbuf;
Glib::Property<Gdk::RGBA> m_property_color;
+ Glib::Property<PresenceStatus> m_property_status;
using type_signal_render = sigc::signal<void(uint64_t)>;
type_signal_render m_signal_render;
diff --git a/src/components/channellist/cellrendererchannels.cpp b/src/components/channellist/cellrendererchannels.cpp
index e0079cd..3db136b 100644
--- a/src/components/channellist/cellrendererchannels.cpp
+++ b/src/components/channellist/cellrendererchannels.cpp
@@ -7,6 +7,49 @@ constexpr static double M_PI = 3.14159265358979;
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);
+
+ const auto color = color_setting.get_alpha_u() > 0 ? color_setting : widget.get_style_context()->get_background_color(Gtk::STATE_FLAG_SELECTED);
+
+ cr->set_source_rgb(color.get_red(), color.get_green(), color.get_blue());
+ const auto x = background_area.get_x();
+ const auto y = background_area.get_y();
+ const auto w = background_area.get_width();
+ const auto h = background_area.get_height();
+ cr->rectangle(x, y, 3, h);
+ cr->fill();
+}
+
+void RenderExpander(int x_offset, const Cairo::RefPtr<Cairo::Context> &cr, Gtk::Widget &widget, const Gdk::Rectangle &background_area, bool is_expanded) {
+ constexpr static int len = 5;
+ int x1, y1, x2, y2, x3, y3;
+ if (is_expanded) {
+ x1 = background_area.get_x() + x_offset;
+ y1 = background_area.get_y() + background_area.get_height() / 2 - len;
+ x2 = background_area.get_x() + x_offset + len;
+ y2 = background_area.get_y() + background_area.get_height() / 2 + len;
+ x3 = background_area.get_x() + x_offset + len * 2;
+ y3 = background_area.get_y() + background_area.get_height() / 2 - len;
+ } else {
+ x1 = background_area.get_x() + x_offset;
+ y1 = background_area.get_y() + background_area.get_height() / 2 - len;
+ x2 = background_area.get_x() + x_offset + len * 2;
+ y2 = background_area.get_y() + background_area.get_height() / 2;
+ x3 = background_area.get_x() + x_offset;
+ y3 = background_area.get_y() + background_area.get_height() / 2 + len;
+ }
+ cr->move_to(x1, y1);
+ cr->line_to(x2, y2);
+ cr->line_to(x3, y3);
+ auto expander_color = Gdk::RGBA(Abaddon::Get().GetSettings().ChannelsExpanderColor);
+ if (expander_color.get_alpha_u() == 0) {
+ expander_color = widget.get_style_context()->get_background_color(Gtk::STATE_FLAG_SELECTED);
+ }
+ cr->set_source_rgb(expander_color.get_red(), expander_color.get_green(), expander_color.get_blue());
+ cr->stroke();
+}
+
CellRendererChannels::CellRendererChannels()
: Glib::ObjectBase(typeid(CellRendererChannels))
, Gtk::CellRenderer()
@@ -207,30 +250,7 @@ void CellRendererChannels::get_preferred_height_for_width_vfunc_folder(Gtk::Widg
}
void CellRendererChannels::render_vfunc_folder(const Cairo::RefPtr<Cairo::Context> &cr, Gtk::Widget &widget, const Gdk::Rectangle &background_area, const Gdk::Rectangle &cell_area, Gtk::CellRendererState flags) {
- constexpr static int len = 5;
- int x1, y1, x2, y2, x3, y3;
- if (property_expanded()) {
- x1 = background_area.get_x() + 7;
- y1 = background_area.get_y() + background_area.get_height() / 2 - len;
- x2 = background_area.get_x() + 7 + len;
- y2 = background_area.get_y() + background_area.get_height() / 2 + len;
- x3 = background_area.get_x() + 7 + len * 2;
- y3 = background_area.get_y() + background_area.get_height() / 2 - len;
- } else {
- x1 = background_area.get_x() + 7;
- y1 = background_area.get_y() + background_area.get_height() / 2 - len;
- x2 = background_area.get_x() + 7 + len * 2;
- y2 = background_area.get_y() + background_area.get_height() / 2;
- x3 = background_area.get_x() + 7;
- y3 = background_area.get_y() + background_area.get_height() / 2 + len;
- }
- cr->move_to(x1, y1);
- cr->line_to(x2, y2);
- cr->line_to(x3, y3);
- const auto expander_color = Gdk::RGBA(Abaddon::Get().GetSettings().ChannelsExpanderColor);
- cr->set_source_rgb(expander_color.get_red(), expander_color.get_green(), expander_color.get_blue());
- cr->stroke();
-
+ RenderExpander(7, cr, widget, background_area, property_expanded());
Gtk::Requisition text_minimum, text_natural;
m_renderer_text.get_preferred_size(widget, text_minimum, text_natural);
@@ -241,11 +261,8 @@ void CellRendererChannels::render_vfunc_folder(const Cairo::RefPtr<Cairo::Contex
Gdk::Rectangle text_cell_area(text_x, text_y, text_w, text_h);
- static const auto color = Gdk::RGBA(Abaddon::Get().GetSettings().ChannelColor);
if (m_property_color.get_value().has_value()) {
m_renderer_text.property_foreground_rgba() = *m_property_color.get_value();
- } else {
- m_renderer_text.property_foreground_rgba() = color;
}
m_renderer_text.render(cr, widget, background_area, text_cell_area, flags);
m_renderer_text.property_foreground_set() = false;
@@ -325,8 +342,6 @@ void CellRendererChannels::render_vfunc_guild(const Cairo::RefPtr<Cairo::Context
static_cast<int>(text_w),
static_cast<int>(text_h));
- static const auto color = Gdk::RGBA(Abaddon::Get().GetSettings().ChannelColor);
- m_renderer_text.property_foreground_rgba() = color;
m_renderer_text.render(cr, widget, background_area, text_cell_area, flags);
const bool hover_only = Abaddon::Get().GetSettings().AnimatedGuildHoverOnly;
@@ -373,14 +388,9 @@ void CellRendererChannels::render_vfunc_guild(const Cairo::RefPtr<Cairo::Context
const auto has_unread = discord.GetUnreadStateForGuild(id, total_mentions);
if (has_unread && !discord.IsGuildMuted(id)) {
- static const auto color = Gdk::RGBA(Abaddon::Get().GetSettings().UnreadIndicatorColor);
- cr->set_source_rgb(color.get_red(), color.get_green(), color.get_blue());
- const auto x = background_area.get_x();
- const auto y = background_area.get_y();
- const auto w = background_area.get_width();
- const auto h = background_area.get_height();
- cr->rectangle(x, y + h / 2.0 - 24.0 / 2.0, 3.0, 24.0);
- cr->fill();
+ auto area = background_area;
+ area.set_y(area.get_y() + area.get_height() / 2.0 - 24.0 / 2.0);
+ AddUnreadIndicator(cr, widget, area);
}
if (total_mentions < 1) return;
@@ -410,42 +420,8 @@ void CellRendererChannels::get_preferred_height_for_width_vfunc_category(Gtk::Wi
m_renderer_text.get_preferred_height_for_width(widget, width, minimum_height, natural_height);
}
-void AddUnreadIndicator(const Cairo::RefPtr<Cairo::Context> &cr, const Gdk::Rectangle &background_area) {
- static const auto color = Gdk::RGBA(Abaddon::Get().GetSettings().UnreadIndicatorColor);
- cr->set_source_rgb(color.get_red(), color.get_green(), color.get_blue());
- const auto x = background_area.get_x();
- const auto y = background_area.get_y();
- const auto w = background_area.get_width();
- const auto h = background_area.get_height();
- cr->rectangle(x, y, 3, h);
- cr->fill();
-}
-
void CellRendererChannels::render_vfunc_category(const Cairo::RefPtr<Cairo::Context> &cr, Gtk::Widget &widget, const Gdk::Rectangle &background_area, const Gdk::Rectangle &cell_area, Gtk::CellRendererState flags) {
- // todo: figure out how Gtk::Arrow is rendered because i like it better :^)
- constexpr static int len = 5;
- int x1, y1, x2, y2, x3, y3;
- if (property_expanded()) {
- x1 = background_area.get_x() + 7;
- y1 = background_area.get_y() + background_area.get_height() / 2 - len;
- x2 = background_area.get_x() + 7 + len;
- y2 = background_area.get_y() + background_area.get_height() / 2 + len;
- x3 = background_area.get_x() + 7 + len * 2;
- y3 = background_area.get_y() + background_area.get_height() / 2 - len;
- } else {
- x1 = background_area.get_x() + 7;
- y1 = background_area.get_y() + background_area.get_height() / 2 - len;
- x2 = background_area.get_x() + 7 + len * 2;
- y2 = background_area.get_y() + background_area.get_height() / 2;
- x3 = background_area.get_x() + 7;
- y3 = background_area.get_y() + background_area.get_height() / 2 + len;
- }
- cr->move_to(x1, y1);
- cr->line_to(x2, y2);
- cr->line_to(x3, y3);
- const auto expander_color = Gdk::RGBA(Abaddon::Get().GetSettings().ChannelsExpanderColor);
- cr->set_source_rgb(expander_color.get_red(), expander_color.get_green(), expander_color.get_blue());
- cr->stroke();
+ RenderExpander(7, cr, widget, background_area, property_expanded());
Gtk::Requisition text_minimum, text_natural;
m_renderer_text.get_preferred_size(widget, text_minimum, text_natural);
@@ -457,23 +433,14 @@ void CellRendererChannels::render_vfunc_category(const Cairo::RefPtr<Cairo::Cont
Gdk::Rectangle text_cell_area(text_x, text_y, text_w, text_h);
- static const auto color = Gdk::RGBA(Abaddon::Get().GetSettings().ChannelColor);
auto &discord = Abaddon::Get().GetDiscordClient();
const auto id = m_property_id.get_value();
- if (discord.IsChannelMuted(m_property_id.get_value())) {
- auto muted = color;
- muted.set_red(muted.get_red() * 0.5);
- muted.set_green(muted.get_green() * 0.5);
- muted.set_blue(muted.get_blue() * 0.5);
- m_renderer_text.property_foreground_rgba() = muted;
- } else {
+ if (!discord.IsChannelMuted(m_property_id.get_value())) {
if (discord.GetUnreadChannelsCountForCategory(id) > 0) {
- AddUnreadIndicator(cr, background_area);
+ AddUnreadIndicator(cr, widget, background_area);
}
- m_renderer_text.property_foreground_rgba() = color;
}
m_renderer_text.render(cr, widget, background_area, text_cell_area, flags);
- m_renderer_text.property_foreground_set() = false;
}
// text channel
@@ -509,23 +476,14 @@ void CellRendererChannels::render_vfunc_channel(const Cairo::RefPtr<Cairo::Conte
const auto id = m_property_id.get_value();
const bool is_muted = discord.IsChannelMuted(id);
- static const auto sfw_unmuted = Gdk::RGBA(Abaddon::Get().GetSettings().ChannelColor);
-
- m_renderer_text.property_sensitive() = false;
static const auto nsfw_color = Gdk::RGBA(Abaddon::Get().GetSettings().NSFWChannelColor);
- if (m_property_nsfw.get_value())
- m_renderer_text.property_foreground_rgba() = nsfw_color;
- else
- m_renderer_text.property_foreground_rgba() = sfw_unmuted;
- if (is_muted) {
- auto col = m_renderer_text.property_foreground_rgba().get_value();
- col.set_red(col.get_red() * 0.5);
- col.set_green(col.get_green() * 0.5);
- col.set_blue(col.get_blue() * 0.5);
- m_renderer_text.property_foreground_rgba() = col;
- }
+
+ auto color = widget.get_style_context()->get_color(Gtk::STATE_FLAG_NORMAL);
+ if (property_nsfw()) color = nsfw_color;
+ if (is_muted) color.set_alpha(0.6);
+
+ m_renderer_text.property_foreground_rgba() = color;
m_renderer_text.render(cr, widget, background_area, text_cell_area, flags);
- // unset foreground to default so properties dont bleed
m_renderer_text.property_foreground_set() = false;
// unread
@@ -535,7 +493,7 @@ void CellRendererChannels::render_vfunc_channel(const Cairo::RefPtr<Cairo::Conte
if (unread_state < 0) return;
if (!is_muted) {
- AddUnreadIndicator(cr, background_area);
+ AddUnreadIndicator(cr, widget, background_area);
}
if (unread_state < 1) return;
@@ -580,18 +538,7 @@ void CellRendererChannels::render_vfunc_thread(const Cairo::RefPtr<Cairo::Contex
const auto id = m_property_id.get_value();
const bool is_muted = discord.IsChannelMuted(id);
- static const auto color = Gdk::RGBA(Abaddon::Get().GetSettings().ChannelColor);
- if (Abaddon::Get().GetDiscordClient().IsChannelMuted(m_property_id.get_value())) {
- auto muted = color;
- muted.set_red(muted.get_red() * 0.5);
- muted.set_green(muted.get_green() * 0.5);
- muted.set_blue(muted.get_blue() * 0.5);
- m_renderer_text.property_foreground_rgba() = muted;
- } else {
- m_renderer_text.property_foreground_rgba() = color;
- }
m_renderer_text.render(cr, widget, background_area, text_cell_area, flags);
- m_renderer_text.property_foreground_set() = false;
// unread
if (!Abaddon::Get().GetSettings().Unreads) return;
@@ -600,14 +547,7 @@ void CellRendererChannels::render_vfunc_thread(const Cairo::RefPtr<Cairo::Contex
if (unread_state < 0) return;
if (!is_muted) {
- static const auto color = Gdk::RGBA(Abaddon::Get().GetSettings().UnreadIndicatorColor);
- cr->set_source_rgb(color.get_red(), color.get_green(), color.get_blue());
- const auto x = background_area.get_x();
- const auto y = background_area.get_y();
- const auto w = background_area.get_width();
- const auto h = background_area.get_height();
- cr->rectangle(x, y, 3, h);
- cr->fill();
+ AddUnreadIndicator(cr, widget, background_area);
}
if (unread_state < 1) return;
@@ -667,31 +607,7 @@ void CellRendererChannels::render_vfunc_voice_channel(const Cairo::RefPtr<Cairo:
cell_area.get_y() + cell_area.get_height() / 2.0 - height / 2.0);
layout->show_in_cairo_context(cr);
- // expander
- constexpr static int len = 5;
- constexpr static int offset = 24;
- int x1, y1, x2, y2, x3, y3;
- if (property_expanded()) {
- x1 = background_area.get_x() + offset;
- y1 = background_area.get_y() + background_area.get_height() / 2 - len;
- x2 = background_area.get_x() + offset + len;
- y2 = background_area.get_y() + background_area.get_height() / 2 + len;
- x3 = background_area.get_x() + offset + len * 2;
- y3 = background_area.get_y() + background_area.get_height() / 2 - len;
- } else {
- x1 = background_area.get_x() + offset;
- y1 = background_area.get_y() + background_area.get_height() / 2 - len;
- x2 = background_area.get_x() + offset + len * 2;
- y2 = background_area.get_y() + background_area.get_height() / 2;
- x3 = background_area.get_x() + offset;
- y3 = background_area.get_y() + background_area.get_height() / 2 + len;
- }
- cr->move_to(x1, y1);
- cr->line_to(x2, y2);
- cr->line_to(x3, y3);
- const auto expander_color = Gdk::RGBA(Abaddon::Get().GetSettings().ChannelsExpanderColor);
- cr->set_source_rgb(expander_color.get_red(), expander_color.get_green(), expander_color.get_blue());
- cr->stroke();
+ RenderExpander(24, cr, widget, background_area, property_expanded());
}
// voice participant
@@ -897,18 +813,7 @@ void CellRendererChannels::render_vfunc_dm(const Cairo::RefPtr<Cairo::Context> &
const auto id = m_property_id.get_value();
const bool is_muted = discord.IsChannelMuted(id);
- static const auto color = Gdk::RGBA(Abaddon::Get().GetSettings().ChannelColor);
- if (Abaddon::Get().GetDiscordClient().IsChannelMuted(m_property_id.get_value())) {
- auto muted = color;
- muted.set_red(muted.get_red() * 0.5);
- muted.set_green(muted.get_green() * 0.5);
- muted.set_blue(muted.get_blue() * 0.5);
- m_renderer_text.property_foreground_rgba() = muted;
- } else {
- m_renderer_text.property_foreground_rgba() = color;
- }
m_renderer_text.render(cr, widget, background_area, text_cell_area, flags);
- m_renderer_text.property_foreground_set() = false;
Gdk::Cairo::set_source_pixbuf(cr, m_property_pixbuf.get_value(), icon_x, icon_y);
cr->rectangle(icon_x, icon_y, icon_w, icon_h);
@@ -921,14 +826,7 @@ void CellRendererChannels::render_vfunc_dm(const Cairo::RefPtr<Cairo::Context> &
if (unread_state < 0) return;
if (!is_muted) {
- static const auto color = Gdk::RGBA(Abaddon::Get().GetSettings().UnreadIndicatorColor);
- cr->set_source_rgb(color.get_red(), color.get_green(), color.get_blue());
- const auto x = background_area.get_x();
- const auto y = background_area.get_y();
- const auto w = background_area.get_width();
- const auto h = background_area.get_height();
- cr->rectangle(x, y, 3, h);
- cr->fill();
+ AddUnreadIndicator(cr, widget, background_area);
}
}
@@ -955,8 +853,11 @@ void CellRendererChannels::unread_render_mentions(const Cairo::RefPtr<Cairo::Con
int width, height;
layout->get_pixel_size(width, height);
{
- static const auto bg = Gdk::RGBA(Abaddon::Get().GetSettings().MentionBadgeColor);
- static const auto text = Gdk::RGBA(Abaddon::Get().GetSettings().MentionBadgeTextColor);
+ 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 : widget.get_style_context()->get_background_color(Gtk::STATE_FLAG_SELECTED);
+ auto text = text_setting.get_alpha_u() > 0 ? text_setting : widget.get_style_context()->get_color(Gtk::STATE_FLAG_SELECTED);
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;
diff --git a/src/components/channellist/channellisttree.cpp b/src/components/channellist/channellisttree.cpp
index c166d42..0e2cda6 100644
--- a/src/components/channellist/channellisttree.cpp
+++ b/src/components/channellist/channellisttree.cpp
@@ -1,6 +1,5 @@
#include "channellisttree.hpp"
#include "imgmanager.hpp"
-#include "components/statusindicator.hpp"
#include <algorithm>
#include <map>
#include <unordered_map>
diff --git a/src/components/chatinput.cpp b/src/components/chatinput.cpp
index c802413..1db03ed 100644
--- a/src/components/chatinput.cpp
+++ b/src/components/chatinput.cpp
@@ -20,7 +20,7 @@ ChatInputText::ChatInputText() {
m_textview.signal_key_press_event().connect(cb, false);
m_textview.set_hexpand(false);
m_textview.set_halign(Gtk::ALIGN_FILL);
- m_textview.set_valign(Gtk::ALIGN_CENTER);
+ m_textview.set_valign(Gtk::ALIGN_FILL);
m_textview.set_wrap_mode(Gtk::WRAP_WORD_CHAR);
m_textview.show();
add(m_textview);
@@ -113,30 +113,25 @@ ChatInputTextContainer::ChatInputTextContainer() {
};
m_input.signal_key_press_proxy().connect(cb);
+ m_upload_button.set_image(m_upload_img);
+ m_upload_button.set_halign(Gtk::ALIGN_CENTER);
+ m_upload_button.set_valign(Gtk::ALIGN_CENTER);
+ m_upload_button.get_style_context()->add_class(GTK_STYLE_CLASS_FLAT);
+
m_upload_img.property_icon_name() = "document-send-symbolic";
m_upload_img.property_icon_size() = Gtk::ICON_SIZE_LARGE_TOOLBAR;
m_upload_img.get_style_context()->add_class("message-input-browse-icon");
- AddPointerCursor(m_upload_ev);
-
- m_upload_ev.signal_button_press_event().connect([this](GdkEventButton *ev) -> bool {
- if (ev->button == GDK_BUTTON_PRIMARY) {
- ShowFileChooser();
- // return focus
- m_input.grab_focus();
- return true;
- }
- return false;
+ m_upload_button.signal_clicked().connect([this]() {
+ ShowFileChooser();
+ m_input.grab_focus();
});
- m_upload_ev.add(m_upload_img);
- add_overlay(m_upload_ev);
- add(m_input);
+ m_upload_box.pack_start(m_upload_button);
+ pack_start(m_upload_box, false, false);
+ pack_start(m_input);
show_all_children();
-
- // stop the overlay from using (start) padding
- signal_get_child_position().connect(sigc::mem_fun(*this, &ChatInputTextContainer::GetChildPosition), false);
}
void ChatInputTextContainer::ShowFileChooser() {
@@ -160,39 +155,11 @@ ChatInputText &ChatInputTextContainer::Get() {
}
void ChatInputTextContainer::ShowChooserIcon() {
- m_upload_ev.show();
+ m_upload_button.show();
}
void ChatInputTextContainer::HideChooserIcon() {
- m_upload_ev.hide();
-}
-
-bool ChatInputTextContainer::GetChildPosition(Gtk::Widget *child, Gdk::Rectangle &pos) {
- Gtk::Allocation main_alloc;
- {
- auto *grandchild = m_input.get_child();
- int x, y;
- if (grandchild->translate_coordinates(m_input, 0, 0, x, y)) {
- main_alloc.set_x(x);
- main_alloc.set_y(y);
- } else {
- main_alloc.set_x(0);
- main_alloc.set_y(0);
- }
- main_alloc.set_width(grandchild->get_allocated_width());
- main_alloc.set_height(grandchild->get_allocated_height());
- }
-
- Gtk::Requisition min, req;
- child->get_preferred_size(min, req);
-
- // let css move it around
- pos.set_x(0);
- pos.set_y(0);
- pos.set_width(std::max(min.width, std::min(main_alloc.get_width(), req.width)));
- pos.set_height(std::max(min.height, std::min(main_alloc.get_height(), req.height)));
-
- return true;
+ m_upload_button.hide();
}
ChatInputTextContainer::type_signal_add_attachment ChatInputTextContainer::signal_add_attachment() {
@@ -295,7 +262,7 @@ std::vector<ChatSubmitParams::Attachment> ChatInputAttachmentContainer::GetAttac
for (auto *x : m_attachments) {
if (!x->GetFile()->query_exists())
puts("bad!");
- ret.push_back({ x->GetFile(), x->GetType(), x->GetFilename() });
+ ret.push_back({ x->GetFile(), x->GetType(), x->GetFilename(), x->GetDescription() });
}
return ret;
}
@@ -343,6 +310,7 @@ ChatInputAttachmentItem::ChatInputAttachmentItem(const Glib::RefPtr<Gio::File> &
, m_img(Gtk::make_managed<Gtk::Image>())
, m_type(is_extant ? ChatSubmitParams::ExtantFile : ChatSubmitParams::PastedImage)
, m_filename("unknown.png")
+ , m_is_image(true)
, m_label("unknown.png")
, m_box(Gtk::ORIENTATION_VERTICAL) {
get_style_context()->add_class("attachment-item");
@@ -389,10 +357,18 @@ std::string ChatInputAttachmentItem::GetFilename() const {
return m_filename;
}
+std::optional<std::string> ChatInputAttachmentItem::GetDescription() const {
+ return m_description.empty() ? std::nullopt : std::optional<std::string>(m_description);
+}
+
bool ChatInputAttachmentItem::IsTemp() const noexcept {
return m_type == ChatSubmitParams::PastedImage;
}
+bool ChatInputAttachmentItem::IsImage() const noexcept {
+ return m_is_image;
+}
+
void ChatInputAttachmentItem::RemoveIfTemp() {
if (IsTemp())
m_file->remove();
@@ -420,12 +396,22 @@ void ChatInputAttachmentItem::SetupMenu() {
}
});
+ m_menu_set_alt_text.set_label("Change Alt-Text");
+ m_menu_set_alt_text.signal_activate().connect([this]() {
+ const auto description = Abaddon::Get().ShowTextPrompt("Enter description (alt-text) for attachment", "Enter alt-text", m_description);
+ if (description.has_value()) {
+ m_description = *description;
+ }
+ });
+
m_menu.add(m_menu_set_filename);
+ m_menu.add(m_menu_set_alt_text);
m_menu.add(m_menu_remove);
m_menu.show_all();
signal_button_press_event().connect([this](GdkEventButton *ev) -> bool {
if (ev->button == GDK_BUTTON_SECONDARY) {
+ m_menu_set_alt_text.set_visible(IsImage());
m_menu.popup_at_pointer(reinterpret_cast<GdkEvent *>(ev));
return true;
}
diff --git a/src/components/chatinput.hpp b/src/components/chatinput.hpp
index a3c9742..231d67c 100644
--- a/src/components/chatinput.hpp
+++ b/src/components/chatinput.hpp
@@ -7,10 +7,13 @@ public:
ChatInputAttachmentItem(const Glib::RefPtr<Gio::File> &file);
ChatInputAttachmentItem(const Glib::RefPtr<Gio::File> &file, const Glib::RefPtr<Gdk::Pixbuf> &pb, bool is_extant = false);
- [[nodiscard]] Glib::RefPtr<Gio::File> GetFile() const;
- [[nodiscard]] ChatSubmitParams::AttachmentType GetType() const;
- [[nodiscard]] std::string GetFilename() const;
- [[nodiscard]] bool IsTemp() const noexcept;
+ Glib::RefPtr<Gio::File> GetFile() const;
+ ChatSubmitParams::AttachmentType GetType() const;
+ std::string GetFilename() const;
+ std::optional<std::string> GetDescription() const;
+ bool IsTemp() const noexcept;
+ bool IsImage() const noexcept;
+
void RemoveIfTemp();
private:
@@ -21,6 +24,7 @@ private:
Gtk::Menu m_menu;
Gtk::MenuItem m_menu_remove;
Gtk::MenuItem m_menu_set_filename;
+ Gtk::MenuItem m_menu_set_alt_text;
Gtk::Box m_box;
Gtk::Label m_label;
@@ -29,6 +33,8 @@ private:
Glib::RefPtr<Gio::File> m_file;
ChatSubmitParams::AttachmentType m_type;
std::string m_filename;
+ std::string m_description;
+ bool m_is_image = false;
private:
using type_signal_item_removed = sigc::signal<void>;
@@ -98,7 +104,7 @@ private:
};
// file upload, text
-class ChatInputTextContainer : public Gtk::Overlay {
+class ChatInputTextContainer : public Gtk::Box {
public:
ChatInputTextContainer();
@@ -110,9 +116,9 @@ public:
private:
void ShowFileChooser();
- bool GetChildPosition(Gtk::Widget *child, Gdk::Rectangle &pos);
- Gtk::EventBox m_upload_ev;
+ Gtk::Box m_upload_box;
+ Gtk::Button m_upload_button;
Gtk::Image m_upload_img;
ChatInputText m_input;
diff --git a/src/components/chatmessage.cpp b/src/components/chatmessage.cpp
index 44396a2..a503294 100644
--- a/src/components/chatmessage.cpp
+++ b/src/components/chatmessage.cpp
@@ -46,6 +46,9 @@ ChatMessageItemContainer *ChatMessageItemContainer::FromMessage(const Message &d
for (const auto &a : data.Attachments) {
if (IsURLViewableImage(a.ProxyURL) && a.Width.has_value() && a.Height.has_value()) {
auto *widget = container->CreateImageComponent(a.ProxyURL, a.URL, *a.Width, *a.Height);
+ if (a.Description.has_value()) {
+ widget->set_tooltip_text(*a.Description);
+ }
container->m_main.add(*widget);
} else {
auto *widget = container->CreateAttachmentComponent(a);
@@ -361,7 +364,7 @@ Gtk::Widget *ChatMessageItemContainer::CreateEmbedComponent(const EmbedData &emb
}
return false;
});
- static auto color = Abaddon::Get().GetSettings().LinkColor;
+ const auto color = title_label->get_style_context()->get_color(Gtk::STATE_FLAG_LINK);
title_label->override_color(Gdk::RGBA(color));
title_label->set_markup("<b>" + Glib::Markup::escape_text(*embed.Title) + "</b>");
}
@@ -620,7 +623,11 @@ Gtk::Widget *ChatMessageItemContainer::CreateReactionsComponent(const Message &d
} else { // custom
ev->set_tooltip_text(reaction.Emoji.Name);
- auto img = Gtk::manage(new LazyImage(reaction.Emoji.GetURL(), 16, 16));
+ auto *img = Gtk::make_managed<LazyImage>(reaction.Emoji.GetURL(), 16, 16);
+ if (reaction.Emoji.IsEmojiAnimated() && Abaddon::Get().GetSettings().ShowAnimations) {
+ img->SetURL(reaction.Emoji.GetURL("gif"));
+ img->SetAnimated(true);
+ }
img->set_can_focus(false);
box->add(*img);
}
@@ -657,7 +664,12 @@ Gtk::Widget *ChatMessageItemContainer::CreateReplyComponent(const Message &data)
if (role.has_value()) {
const auto author = discord.GetUser(author_id);
if (author.has_value()) {
- return "<b><span color=\"#" + IntToCSSColor(role->Color) + "\">" + author->GetDisplayNameEscaped(guild_id) + "</span></b>";
+ const auto is_mention = !data.Interaction.has_value() && data.DoesMention(author_id);
+ if (is_mention) {
+ return "<b><span color=\"#" + IntToCSSColor(role->Color) + "\">@" + author->GetDisplayNameEscaped(guild_id) + "</span></b>";
+ } else {
+ return "<b><span color=\"#" + IntToCSSColor(role->Color) + "\">" + author->GetDisplayNameEscaped(guild_id) + "</span></b>";
+ }
}
}
}
@@ -713,16 +725,12 @@ Gtk::Widget *ChatMessageItemContainer::CreateReplyComponent(const Message &data)
HandleChannelMentions(buf);
text = Glib::Markup::escape_text(buf->get_text());
}
- // getting markup out of a textbuffer seems like something that to me should be really simple
- // but actually is horribly annoying. replies won't have mention colors because you can't do this
- // also no emojis because idk how to make a textview act like a label
- // which of course would not be an issue if i could figure out how to get fonts to work on this god-forsaken framework
- // oh well
- // but ill manually get colors for the user who is being replied to
- if (referenced.GuildID.has_value())
+
+ if (referenced.GuildID.has_value()) {
lbl->set_markup(get_author_markup(referenced.Author.ID, *referenced.GuildID) + ": " + text);
- else
+ } else {
lbl->set_markup(get_author_markup(referenced.Author.ID) + ": " + text);
+ }
}
} else {
lbl->set_markup("<i>reply unavailable</i>");
@@ -848,7 +856,8 @@ void ChatMessageItemContainer::HandleLinks(Gtk::TextView &tv) {
std::string link = match.fetch(0);
auto tag = buf->create_tag();
m_link_tagmap[tag] = link;
- tag->property_foreground_rgba() = Gdk::RGBA(Abaddon::Get().GetSettings().LinkColor);
+ const auto color = tv.get_style_context()->get_color(Gtk::STATE_FLAG_LINK);
+ tag->property_foreground_rgba() = color;
tag->set_property("underline", 1); // stupid workaround for vcpkg bug (i think)
const auto chars_start = g_utf8_pointer_to_offset(text.c_str(), text.c_str() + mstart);
diff --git a/src/components/chatwindow.cpp b/src/components/chatwindow.cpp
index aeed4ed..9a2493d 100644
--- a/src/components/chatwindow.cpp
+++ b/src/components/chatwindow.cpp
@@ -5,7 +5,7 @@
#include "chatlist.hpp"
#include "constants.hpp"
#ifdef WITH_LIBHANDY
- #include "channeltabswitcherhandy.hpp"
+#include "channeltabswitcherhandy.hpp"
#endif
ChatWindow::ChatWindow() {
@@ -109,7 +109,13 @@ ChatWindow::ChatWindow() {
m_main->add(*m_meta);
m_main->add(m_progress);
- m_progress.show();
+ m_progress.signal_start().connect([this]() {
+ m_progress.show();
+ });
+
+ m_progress.signal_stop().connect([this]() {
+ m_progress.hide();
+ });
m_main->show();
}
diff --git a/src/components/memberlist.cpp b/src/components/memberlist.cpp
index b082daa..7046b52 100644
--- a/src/components/memberlist.cpp
+++ b/src/components/memberlist.cpp
@@ -28,6 +28,7 @@ MemberList::MemberList()
column->add_attribute(renderer->property_name(), m_columns.m_name);
column->add_attribute(renderer->property_pixbuf(), m_columns.m_pixbuf);
column->add_attribute(renderer->property_color(), m_columns.m_color);
+ column->add_attribute(renderer->property_status(), m_columns.m_status);
m_view.append_column(*column);
m_model->set_sort_column(m_columns.m_sort, Gtk::SORT_ASCENDING);
@@ -44,6 +45,8 @@ MemberList::MemberList()
m_menu_role_copy_id.signal_activate().connect([this]() {
Gtk::Clipboard::get()->set_text(std::to_string((*m_model->get_iter(m_path_for_menu))[m_columns.m_id]));
});
+
+ Abaddon::Get().GetDiscordClient().signal_presence_update().connect(sigc::mem_fun(*this, &MemberList::OnPresenceUpdate));
}
Gtk::Widget *MemberList::GetRoot() {
@@ -73,6 +76,7 @@ void MemberList::UpdateMemberList() {
row[m_columns.m_color] = color_transparent;
row[m_columns.m_av_requested] = false;
row[m_columns.m_pixbuf] = Abaddon::Get().GetImageManager().GetPlaceholder(16);
+ row[m_columns.m_status] = Abaddon::Get().GetDiscordClient().GetUserStatus(user.ID);
m_pending_avatars[user.ID] = row_iter;
}
}
@@ -126,6 +130,7 @@ void MemberList::UpdateMemberList() {
row[m_columns.m_id] = user.ID;
row[m_columns.m_name] = user.GetDisplayNameEscaped();
row[m_columns.m_pixbuf] = Abaddon::Get().GetImageManager().GetPlaceholder(16);
+ row[m_columns.m_status] = Abaddon::Get().GetDiscordClient().GetUserStatus(user.ID);
row[m_columns.m_av_requested] = false;
if (const auto iter = user_to_color.find(user.ID); iter != user_to_color.end()) {
row[m_columns.m_color] = IntToRGBA(iter->second);
@@ -241,12 +246,24 @@ int MemberList::SortFunc(const Gtk::TreeModel::iterator &a, const Gtk::TreeModel
return 0;
}
+void MemberList::OnPresenceUpdate(const UserData &user, PresenceStatus status) {
+ for (auto &role : m_model->children()) {
+ for (auto &member : role.children()) {
+ if ((*member)[m_columns.m_id] == user.ID) {
+ (*member)[m_columns.m_status] = status;
+ return;
+ }
+ }
+ }
+}
+
MemberList::ModelColumns::ModelColumns() {
add(m_type);
add(m_id);
add(m_name);
add(m_pixbuf);
- add(m_av_requested);
add(m_color);
+ add(m_status);
add(m_sort);
+ add(m_av_requested);
}
diff --git a/src/components/memberlist.hpp b/src/components/memberlist.hpp
index cb6c191..1c4aaf4 100644
--- a/src/components/memberlist.hpp
+++ b/src/components/memberlist.hpp
@@ -26,6 +26,8 @@ private:
int SortFunc(const Gtk::TreeModel::iterator &a, const Gtk::TreeModel::iterator &b);
+ void OnPresenceUpdate(const UserData &user, PresenceStatus status);
+
class ModelColumns : public Gtk::TreeModel::ColumnRecord {
public:
ModelColumns();
@@ -35,6 +37,7 @@ private:
Gtk::TreeModelColumn<Glib::ustring> m_name;
Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf>> m_pixbuf;
Gtk::TreeModelColumn<Gdk::RGBA> m_color;
+ Gtk::TreeModelColumn<PresenceStatus> m_status;
Gtk::TreeModelColumn<int> m_sort;
Gtk::TreeModelColumn<bool> m_av_requested;
diff --git a/src/components/progressbar.cpp b/src/components/progressbar.cpp
index 75f86bb..65abfae 100644
--- a/src/components/progressbar.cpp
+++ b/src/components/progressbar.cpp
@@ -5,12 +5,19 @@ MessageUploadProgressBar::MessageUploadProgressBar() {
auto &discord = Abaddon::Get().GetDiscordClient();
discord.signal_message_progress().connect([this](const std::string &nonce, float percent) {
if (nonce == m_last_nonce) {
+ if (!m_active) {
+ m_active = true;
+ m_signal_start.emit();
+ }
set_fraction(percent);
}
});
discord.signal_message_send_fail().connect([this](const std::string &nonce, float) {
- if (nonce == m_last_nonce)
+ if (nonce == m_last_nonce) {
set_fraction(0.0);
+ m_active = false;
+ m_signal_stop.emit();
+ }
});
discord.signal_message_create().connect([this](const Message &msg) {
if (msg.IsPending) {
@@ -18,6 +25,16 @@ MessageUploadProgressBar::MessageUploadProgressBar() {
} else if (msg.Nonce.has_value() && (*msg.Nonce == m_last_nonce)) {
m_last_nonce = "";
set_fraction(0.0);
+ m_active = false;
+ m_signal_stop.emit();
}
});
}
+
+MessageUploadProgressBar::type_signal_start MessageUploadProgressBar::signal_start() {
+ return m_signal_start;
+}
+
+MessageUploadProgressBar::type_signal_stop MessageUploadProgressBar::signal_stop() {
+ return m_signal_stop;
+}
diff --git a/src/components/progressbar.hpp b/src/components/progressbar.hpp
index 483ee47..8efb87a 100644
--- a/src/components/progressbar.hpp
+++ b/src/components/progressbar.hpp
@@ -6,5 +6,16 @@ public:
MessageUploadProgressBar();
private:
+ bool m_active = false;
std::string m_last_nonce;
+
+ using type_signal_start = sigc::signal<void()>;
+ using type_signal_stop = sigc::signal<void()>;
+
+ type_signal_start m_signal_start;
+ type_signal_stop m_signal_stop;
+
+public:
+ type_signal_start signal_start();
+ type_signal_stop signal_stop();
};
diff --git a/src/components/statusindicator.cpp b/src/components/statusindicator.cpp
deleted file mode 100644
index 47e8b44..0000000
--- a/src/components/statusindicator.cpp
+++ /dev/null
@@ -1,122 +0,0 @@
-#include "statusindicator.hpp"
-
-static const constexpr int Diameter = 8;
-
-StatusIndicator::StatusIndicator(Snowflake user_id)
- : Glib::ObjectBase("statusindicator")
- , Gtk::Widget()
- , m_id(user_id)
- , m_status(static_cast<PresenceStatus>(-1)) {
- set_has_window(true);
- set_name("status-indicator");
-
- get_style_context()->add_class("status-indicator");
-
- Abaddon::Get().GetDiscordClient().signal_guild_member_list_update().connect(sigc::hide(sigc::mem_fun(*this, &StatusIndicator::CheckStatus)));
- auto cb = [this](const UserData &user, PresenceStatus status) {
- if (user.ID == m_id) CheckStatus();
- };
- Abaddon::Get().GetDiscordClient().signal_presence_update().connect(sigc::track_obj(cb, *this));
-
- CheckStatus();
-}
-
-void StatusIndicator::CheckStatus() {
- const auto status = Abaddon::Get().GetDiscordClient().GetUserStatus(m_id);
- const auto last_status = m_status;
- get_style_context()->remove_class("online");
- get_style_context()->remove_class("dnd");
- get_style_context()->remove_class("idle");
- get_style_context()->remove_class("offline");
- get_style_context()->add_class(GetPresenceString(status));
- m_status = status;
-
- if (last_status != m_status)
- queue_draw();
-}
-
-Gtk::SizeRequestMode StatusIndicator::get_request_mode_vfunc() const {
- return Gtk::Widget::get_request_mode_vfunc();
-}
-
-void StatusIndicator::get_preferred_width_vfunc(int &minimum_width, int &natural_width) const {
- minimum_width = 0;
- natural_width = Diameter;
-}
-
-void StatusIndicator::get_preferred_height_for_width_vfunc(int width, int &minimum_height, int &natural_height) const {
- minimum_height = 0;
- natural_height = Diameter;
-}
-
-void StatusIndicator::get_preferred_height_vfunc(int &minimum_height, int &natural_height) const {
- minimum_height = 0;
- natural_height = Diameter;
-}
-
-void StatusIndicator::get_preferred_width_for_height_vfunc(int height, int &minimum_width, int &natural_width) const {
- minimum_width = 0;
- natural_width = Diameter;
-}
-
-void StatusIndicator::on_size_allocate(Gtk::Allocation &allocation) {
- set_allocation(allocation);
-
- if (m_window)
- m_window->move_resize(allocation.get_x(), allocation.get_y(), allocation.get_width(), allocation.get_height());
-}
-
-void StatusIndicator::on_map() {
- Gtk::Widget::on_map();
-}
-
-void StatusIndicator::on_unmap() {
- Gtk::Widget::on_unmap();
-}
-
-void StatusIndicator::on_realize() {
- set_realized(true);
-
- if (!m_window) {
- GdkWindowAttr attributes;
- std::memset(&attributes, 0, sizeof(attributes));
-
- auto allocation = get_allocation();
-
- attributes.x = allocation.get_x();
- attributes.y = allocation.get_y();
- attributes.width = allocation.get_width();
- attributes.height = allocation.get_height();
-
- attributes.event_mask = get_events() | Gdk::EXPOSURE_MASK;
- attributes.window_type = GDK_WINDOW_CHILD;
- attributes.wclass = GDK_INPUT_OUTPUT;
-
- m_window = Gdk::Window::create(get_parent_window(), &attributes, GDK_WA_X | GDK_WA_Y);
- set_window(m_window);
-
- m_window->set_user_data(gobj());
- }
-}
-
-void StatusIndicator::on_unrealize() {
- m_window.reset();
-
- Gtk::Widget::on_unrealize();
-}
-
-bool StatusIndicator::on_draw(const Cairo::RefPtr<Cairo::Context> &cr) {
- const auto allocation = get_allocation();
- const auto width = allocation.get_width();
- const auto height = allocation.get_height();
-
- const auto color = get_style_context()->get_color(Gtk::STATE_FLAG_NORMAL);
-
- cr->set_source_rgb(color.get_red(), color.get_green(), color.get_blue());
- cr->arc(width / 2.0, height / 2.0, width / 3.0, 0.0, 2 * (4 * std::atan(1)));
- cr->close_path();
- cr->fill_preserve();
- cr->stroke();
-
- return true;
-}
diff --git a/src/components/statusindicator.hpp b/src/components/statusindicator.hpp
deleted file mode 100644
index edd64ea..0000000
--- a/src/components/statusindicator.hpp
+++ /dev/null
@@ -1,29 +0,0 @@
-#pragma once
-#include "discord/snowflake.hpp"
-#include "discord/activity.hpp"
-
-class StatusIndicator : public Gtk::Widget {
-public:
- StatusIndicator(Snowflake user_id);
- ~StatusIndicator() override = default;
-
-protected:
- Gtk::SizeRequestMode get_request_mode_vfunc() const override;
- void get_preferred_width_vfunc(int &minimum_width, int &natural_width) const override;
- void get_preferred_width_for_height_vfunc(int height, int &minimum_width, int &natural_width) const override;
- void get_preferred_height_vfunc(int &minimum_height, int &natural_height) const override;
- void get_preferred_height_for_width_vfunc(int width, int &minimum_height, int &natural_height) const override;
- void on_size_allocate(Gtk::Allocation &allocation) override;
- void on_map() override;
- void on_unmap() override;
- void on_realize() override;
- void on_unrealize() override;
- bool on_draw(const Cairo::RefPtr<Cairo::Context> &cr) override;
-
- Glib::RefPtr<Gdk::Window> m_window;
-
- void CheckStatus();
-
- Snowflake m_id;
- PresenceStatus m_status;
-};