forked from OpenGamers/abaddon
basic channel mentions count indicator
This commit is contained in:
@@ -176,6 +176,14 @@ ChannelList::ChannelList()
|
|||||||
discord.signal_message_ack().connect(sigc::mem_fun(*this, &ChannelList::OnMessageAck));
|
discord.signal_message_ack().connect(sigc::mem_fun(*this, &ChannelList::OnMessageAck));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ChannelList::UsePanedHack(Gtk::Paned& paned) {
|
||||||
|
paned.property_position().signal_changed().connect(sigc::mem_fun(*this, &ChannelList::OnPanedPositionChanged));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChannelList::OnPanedPositionChanged() {
|
||||||
|
m_view.queue_draw();
|
||||||
|
}
|
||||||
|
|
||||||
void ChannelList::UpdateListing() {
|
void ChannelList::UpdateListing() {
|
||||||
m_updating_listing = true;
|
m_updating_listing = true;
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,11 @@ public:
|
|||||||
void UseExpansionState(const ExpansionStateRoot &state);
|
void UseExpansionState(const ExpansionStateRoot &state);
|
||||||
ExpansionStateRoot GetExpansionState() const;
|
ExpansionStateRoot GetExpansionState() const;
|
||||||
|
|
||||||
|
void UsePanedHack(Gtk::Paned &paned);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
void OnPanedPositionChanged();
|
||||||
|
|
||||||
void UpdateNewGuild(const GuildData &guild);
|
void UpdateNewGuild(const GuildData &guild);
|
||||||
void UpdateRemoveGuild(Snowflake id);
|
void UpdateRemoveGuild(Snowflake id);
|
||||||
void UpdateRemoveChannel(Snowflake id);
|
void UpdateRemoveChannel(Snowflake id);
|
||||||
|
|||||||
@@ -240,7 +240,7 @@ void CellRendererChannels::render_vfunc_guild(const Cairo::RefPtr<Cairo::Context
|
|||||||
cr->fill();
|
cr->fill();
|
||||||
}
|
}
|
||||||
|
|
||||||
UnreadRenderer::RenderUnreadOnGuild(m_property_id.get_value(), cr, background_area, cell_area);
|
UnreadRenderer::RenderUnreadOnGuild(m_property_id.get_value(), widget, cr, background_area, cell_area);
|
||||||
}
|
}
|
||||||
|
|
||||||
// category
|
// category
|
||||||
@@ -337,7 +337,7 @@ void CellRendererChannels::render_vfunc_channel(const Cairo::RefPtr<Cairo::Conte
|
|||||||
// so unset it
|
// so unset it
|
||||||
m_renderer_text.property_foreground_set() = false;
|
m_renderer_text.property_foreground_set() = false;
|
||||||
|
|
||||||
UnreadRenderer::RenderUnreadOnChannel(m_property_id.get_value(), cr, background_area, cell_area);
|
UnreadRenderer::RenderUnreadOnChannel(m_property_id.get_value(), widget, cr, background_area, cell_area);
|
||||||
}
|
}
|
||||||
|
|
||||||
// thread
|
// thread
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#include "unreadrenderer.hpp"
|
#include "unreadrenderer.hpp"
|
||||||
#include "abaddon.hpp"
|
#include "abaddon.hpp"
|
||||||
|
|
||||||
void UnreadRenderer::RenderUnreadOnGuild(Snowflake id, const Cairo::RefPtr<Cairo::Context> &cr, const Gdk::Rectangle &background_area, const Gdk::Rectangle &cell_area) {
|
void UnreadRenderer::RenderUnreadOnGuild(Snowflake id, Gtk::Widget &widget, const Cairo::RefPtr<Cairo::Context> &cr, const Gdk::Rectangle &background_area, const Gdk::Rectangle &cell_area) {
|
||||||
// maybe have DiscordClient track this?
|
// maybe have DiscordClient track this?
|
||||||
auto &discord = Abaddon::Get().GetDiscordClient();
|
auto &discord = Abaddon::Get().GetDiscordClient();
|
||||||
const auto channels = discord.GetChannelsInGuild(id);
|
const auto channels = discord.GetChannelsInGuild(id);
|
||||||
@@ -23,15 +23,38 @@ void UnreadRenderer::RenderUnreadOnGuild(Snowflake id, const Cairo::RefPtr<Cairo
|
|||||||
cr->fill();
|
cr->fill();
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnreadRenderer::RenderUnreadOnChannel(Snowflake id, const Cairo::RefPtr<Cairo::Context> &cr, const Gdk::Rectangle &background_area, const Gdk::Rectangle &cell_area) {
|
void UnreadRenderer::RenderUnreadOnChannel(Snowflake id, Gtk::Widget &widget, const Cairo::RefPtr<Cairo::Context> &cr, const Gdk::Rectangle &background_area, const Gdk::Rectangle &cell_area) {
|
||||||
const auto state = Abaddon::Get().GetDiscordClient().GetUnreadStateForChannel(id);
|
const auto state = Abaddon::Get().GetDiscordClient().GetUnreadStateForChannel(id);
|
||||||
if (state >= 0) {
|
if (state < 0) return;
|
||||||
cr->set_source_rgb(1.0, 1.0, 1.0);
|
cr->set_source_rgb(1.0, 1.0, 1.0);
|
||||||
const auto x = background_area.get_x();
|
const auto x = background_area.get_x();
|
||||||
const auto y = background_area.get_y();
|
const auto y = background_area.get_y();
|
||||||
const auto w = background_area.get_width();
|
const auto w = background_area.get_width();
|
||||||
const auto h = background_area.get_height();
|
const auto h = background_area.get_height();
|
||||||
cr->rectangle(x, y, 3, h);
|
cr->rectangle(x, y, 3, h);
|
||||||
cr->fill();
|
cr->fill();
|
||||||
|
|
||||||
|
if (state < 1) return;
|
||||||
|
auto *paned = static_cast<Gtk::Paned *>(widget.get_ancestor(Gtk::Paned::get_type()));
|
||||||
|
const auto edge = paned->get_position();
|
||||||
|
|
||||||
|
// surely this shouldnt be run every draw?
|
||||||
|
// https://developer-old.gnome.org/gtkmm-tutorial/3.22/sec-drawing-text.html.en
|
||||||
|
|
||||||
|
Pango::FontDescription font;
|
||||||
|
font.set_family("sans 14");
|
||||||
|
font.set_weight(Pango::WEIGHT_BOLD);
|
||||||
|
|
||||||
|
auto layout = widget.create_pango_layout(std::to_string(state));
|
||||||
|
layout->set_font_description(font);
|
||||||
|
layout->set_alignment(Pango::ALIGN_RIGHT);
|
||||||
|
|
||||||
|
int width, height;
|
||||||
|
layout->get_pixel_size(width, height);
|
||||||
|
{
|
||||||
|
const auto x = cell_area.get_x() + std::min(edge, cell_area.get_width()) - 14 - 2;
|
||||||
|
const auto y = cell_area.get_y() + cell_area.get_height() / 2.0 - height / 2.0;
|
||||||
|
cr->move_to(x, y);
|
||||||
|
layout->show_in_cairo_context(cr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <cairomm/context.h>
|
#include <cairomm/context.h>
|
||||||
#include <gdkmm/rectangle.h>
|
#include <gdkmm/rectangle.h>
|
||||||
|
#include <gtkmm/widget.h>
|
||||||
#include "discord/snowflake.hpp"
|
#include "discord/snowflake.hpp"
|
||||||
|
|
||||||
class UnreadRenderer {
|
class UnreadRenderer {
|
||||||
public:
|
public:
|
||||||
static void RenderUnreadOnGuild(Snowflake id, const Cairo::RefPtr<Cairo::Context> &cr, const Gdk::Rectangle &background_area, const Gdk::Rectangle &cell_area);
|
static void RenderUnreadOnGuild(Snowflake id, Gtk::Widget &widget, const Cairo::RefPtr<Cairo::Context> &cr, const Gdk::Rectangle &background_area, const Gdk::Rectangle &cell_area);
|
||||||
static void RenderUnreadOnChannel(Snowflake id, const Cairo::RefPtr<Cairo::Context> &cr, const Gdk::Rectangle &background_area, const Gdk::Rectangle &cell_area);
|
static void RenderUnreadOnChannel(Snowflake id, Gtk::Widget &widget, const Cairo::RefPtr<Cairo::Context> &cr, const Gdk::Rectangle &background_area, const Gdk::Rectangle &cell_area);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1467,9 +1467,10 @@ void DiscordClient::HandleGatewayMessageCreate(const GatewayMessage &msg) {
|
|||||||
if (data.GuildID.has_value())
|
if (data.GuildID.has_value())
|
||||||
AddUserToGuild(data.Author.ID, *data.GuildID);
|
AddUserToGuild(data.Author.ID, *data.GuildID);
|
||||||
m_last_message_id[data.ChannelID] = data.ID;
|
m_last_message_id[data.ChannelID] = data.ID;
|
||||||
const auto iter = m_unread.find(data.ChannelID);
|
m_unread[data.ChannelID];
|
||||||
if (iter == m_unread.end())
|
if (data.DoesMention(GetUserData().ID)) {
|
||||||
m_unread[data.ChannelID] = 0;
|
m_unread[data.ChannelID]++;
|
||||||
|
}
|
||||||
m_signal_message_create.emit(data);
|
m_signal_message_create.emit(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -263,3 +263,9 @@ bool Message::IsDeleted() const {
|
|||||||
bool Message::IsEdited() const {
|
bool Message::IsEdited() const {
|
||||||
return m_edited;
|
return m_edited;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Message::DoesMention(Snowflake id) const noexcept {
|
||||||
|
return std::any_of(Mentions.begin(), Mentions.end(), [id](const UserData &user) {
|
||||||
|
return user.ID == id;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
@@ -212,6 +212,8 @@ struct Message {
|
|||||||
bool IsDeleted() const;
|
bool IsDeleted() const;
|
||||||
bool IsEdited() const;
|
bool IsEdited() const;
|
||||||
|
|
||||||
|
bool DoesMention(Snowflake id) const noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_deleted = false;
|
bool m_deleted = false;
|
||||||
bool m_edited = false;
|
bool m_edited = false;
|
||||||
|
|||||||
@@ -153,6 +153,7 @@ MainWindow::MainWindow()
|
|||||||
m_chan_content_paned.set_position(200);
|
m_chan_content_paned.set_position(200);
|
||||||
m_chan_content_paned.show();
|
m_chan_content_paned.show();
|
||||||
m_content_box.add(m_chan_content_paned);
|
m_content_box.add(m_chan_content_paned);
|
||||||
|
m_channel_list.UsePanedHack(m_chan_content_paned);
|
||||||
|
|
||||||
m_content_members_paned.pack1(m_content_stack);
|
m_content_members_paned.pack1(m_content_stack);
|
||||||
m_content_members_paned.pack2(*member_list);
|
m_content_members_paned.pack2(*member_list);
|
||||||
|
|||||||
Reference in New Issue
Block a user