mirror of
https://github.com/celisej567/abaddon.git
synced 2026-09-13 20:18:50 +03:00
Merge branch 'folders'
This commit is contained in:
@@ -89,6 +89,7 @@ ChannelList::ChannelList()
|
||||
column->add_attribute(renderer->property_id(), m_columns.m_id);
|
||||
column->add_attribute(renderer->property_expanded(), m_columns.m_expanded);
|
||||
column->add_attribute(renderer->property_nsfw(), m_columns.m_nsfw);
|
||||
column->add_attribute(renderer->property_color(), m_columns.m_color);
|
||||
m_view.append_column(*column);
|
||||
|
||||
m_menu_guild_copy_id.signal_activate().connect([this] {
|
||||
@@ -262,14 +263,51 @@ void ChannelList::UpdateListing() {
|
||||
|
||||
auto &discord = Abaddon::Get().GetDiscordClient();
|
||||
|
||||
const auto guild_ids = discord.GetUserSortedGuilds();
|
||||
int sortnum = 0;
|
||||
for (const auto &guild_id : guild_ids) {
|
||||
const auto guild = discord.GetGuild(guild_id);
|
||||
if (!guild.has_value()) continue;
|
||||
/*
|
||||
guild_folders looks something like this
|
||||
"guild_folders": [
|
||||
{
|
||||
"color": null,
|
||||
"guild_ids": [
|
||||
"8009060___________"
|
||||
],
|
||||
"id": null,
|
||||
"name": null
|
||||
},
|
||||
{
|
||||
"color": null,
|
||||
"guild_ids": [
|
||||
"99615594__________",
|
||||
"86132141__________",
|
||||
"35450138__________",
|
||||
"83714048__________"
|
||||
],
|
||||
"id": 2853066769,
|
||||
"name": null
|
||||
}
|
||||
]
|
||||
|
||||
auto iter = AddGuild(*guild);
|
||||
(*iter)[m_columns.m_sort] = sortnum++;
|
||||
so if id != null then its a folder (they can have single entries)
|
||||
*/
|
||||
|
||||
int sort_value = 0;
|
||||
|
||||
const auto folders = discord.GetUserSettings().GuildFolders;
|
||||
if (folders.empty()) {
|
||||
// fallback if no organization has occurred (guild_folders will be empty)
|
||||
const auto guild_ids = discord.GetUserSortedGuilds();
|
||||
for (const auto &guild_id : guild_ids) {
|
||||
const auto guild = discord.GetGuild(guild_id);
|
||||
if (!guild.has_value()) continue;
|
||||
|
||||
auto iter = AddGuild(*guild, m_model->children());
|
||||
(*iter)[m_columns.m_sort] = sort_value++;
|
||||
}
|
||||
} else {
|
||||
for (const auto &group : folders) {
|
||||
auto iter = AddFolder(group);
|
||||
(*iter)[m_columns.m_sort] = sort_value++;
|
||||
}
|
||||
}
|
||||
|
||||
m_updating_listing = false;
|
||||
@@ -277,8 +315,9 @@ void ChannelList::UpdateListing() {
|
||||
AddPrivateChannels();
|
||||
}
|
||||
|
||||
// TODO update for folders
|
||||
void ChannelList::UpdateNewGuild(const GuildData &guild) {
|
||||
AddGuild(guild);
|
||||
AddGuild(guild, m_model->children());
|
||||
// update sort order
|
||||
int sortnum = 0;
|
||||
for (const auto guild_id : Abaddon::Get().GetDiscordClient().GetUserSortedGuilds()) {
|
||||
@@ -405,6 +444,8 @@ void ChannelList::OnThreadListSync(const ThreadListSyncData &data) {
|
||||
// get the threads in the guild
|
||||
std::vector<Snowflake> threads;
|
||||
auto guild_iter = GetIteratorForGuildFromID(data.GuildID);
|
||||
if (!guild_iter) return;
|
||||
|
||||
std::queue<Gtk::TreeModel::iterator> queue;
|
||||
queue.push(guild_iter);
|
||||
|
||||
@@ -546,11 +587,48 @@ ExpansionStateRoot ChannelList::GetExpansionState() const {
|
||||
return r;
|
||||
}
|
||||
|
||||
Gtk::TreeModel::iterator ChannelList::AddGuild(const GuildData &guild) {
|
||||
Gtk::TreeModel::iterator ChannelList::AddFolder(const UserSettingsGuildFoldersEntry &folder) {
|
||||
if (!folder.ID.has_value()) {
|
||||
// just a guild
|
||||
if (!folder.GuildIDs.empty()) {
|
||||
const auto guild = Abaddon::Get().GetDiscordClient().GetGuild(folder.GuildIDs[0]);
|
||||
if (guild.has_value()) {
|
||||
return AddGuild(*guild, m_model->children());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
auto folder_row = *m_model->append();
|
||||
folder_row[m_columns.m_type] = RenderType::Folder;
|
||||
folder_row[m_columns.m_id] = *folder.ID;
|
||||
if (folder.Name.has_value()) {
|
||||
folder_row[m_columns.m_name] = Glib::Markup::escape_text(*folder.Name);
|
||||
} else {
|
||||
folder_row[m_columns.m_name] = "Folder";
|
||||
}
|
||||
if (folder.Color.has_value()) {
|
||||
folder_row[m_columns.m_color] = IntToRGBA(*folder.Color);
|
||||
}
|
||||
|
||||
int sort_value = 0;
|
||||
for (const auto &guild_id : folder.GuildIDs) {
|
||||
const auto guild = Abaddon::Get().GetDiscordClient().GetGuild(guild_id);
|
||||
if (guild.has_value()) {
|
||||
auto guild_row = AddGuild(*guild, folder_row->children());
|
||||
(*guild_row)[m_columns.m_sort] = sort_value++;
|
||||
}
|
||||
}
|
||||
|
||||
return folder_row;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
Gtk::TreeModel::iterator ChannelList::AddGuild(const GuildData &guild, const Gtk::TreeNodeChildren &root) {
|
||||
auto &discord = Abaddon::Get().GetDiscordClient();
|
||||
auto &img = Abaddon::Get().GetImageManager();
|
||||
|
||||
auto guild_row = *m_model->append();
|
||||
auto guild_row = *m_model->append(root);
|
||||
guild_row[m_columns.m_type] = RenderType::Guild;
|
||||
guild_row[m_columns.m_id] = guild.ID;
|
||||
guild_row[m_columns.m_name] = "<b>" + Glib::Markup::escape_text(guild.Name) + "</b>";
|
||||
@@ -679,8 +757,15 @@ void ChannelList::UpdateChannelCategory(const ChannelData &channel) {
|
||||
|
||||
Gtk::TreeModel::iterator ChannelList::GetIteratorForGuildFromID(Snowflake id) {
|
||||
for (const auto &child : m_model->children()) {
|
||||
if (child[m_columns.m_id] == id)
|
||||
if (child[m_columns.m_type] == RenderType::Guild && child[m_columns.m_id] == id) {
|
||||
return child;
|
||||
} else if (child[m_columns.m_type] == RenderType::Folder) {
|
||||
for (const auto &folder_child : child->children()) {
|
||||
if (folder_child[m_columns.m_id] == id) {
|
||||
return folder_child;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
@@ -886,6 +971,7 @@ void ChannelList::MoveRow(const Gtk::TreeModel::iterator &iter, const Gtk::TreeM
|
||||
M(m_sort);
|
||||
M(m_nsfw);
|
||||
M(m_expanded);
|
||||
M(m_color);
|
||||
#undef M
|
||||
|
||||
// recursively move children
|
||||
@@ -998,4 +1084,5 @@ ChannelList::ModelColumns::ModelColumns() {
|
||||
add(m_sort);
|
||||
add(m_nsfw);
|
||||
add(m_expanded);
|
||||
add(m_color);
|
||||
}
|
||||
|
||||
@@ -61,6 +61,7 @@ protected:
|
||||
Gtk::TreeModelColumn<Glib::RefPtr<Gdk::PixbufAnimation>> m_icon_anim;
|
||||
Gtk::TreeModelColumn<int64_t> m_sort;
|
||||
Gtk::TreeModelColumn<bool> m_nsfw;
|
||||
Gtk::TreeModelColumn<std::optional<Gdk::RGBA>> m_color; // for folders right now
|
||||
// Gtk::CellRenderer's property_is_expanded only works how i want it to if it has children
|
||||
// because otherwise it doesnt count as an "expander" (property_is_expander)
|
||||
// so this solution will have to do which i hate but the alternative is adding invisible children
|
||||
@@ -72,7 +73,8 @@ protected:
|
||||
ModelColumns m_columns;
|
||||
Glib::RefPtr<Gtk::TreeStore> m_model;
|
||||
|
||||
Gtk::TreeModel::iterator AddGuild(const GuildData &guild);
|
||||
Gtk::TreeModel::iterator AddFolder(const UserSettingsGuildFoldersEntry &folder);
|
||||
Gtk::TreeModel::iterator AddGuild(const GuildData &guild, const Gtk::TreeNodeChildren &root);
|
||||
Gtk::TreeModel::iterator UpdateCreateChannelCategory(const ChannelData &channel);
|
||||
Gtk::TreeModel::iterator CreateThreadRow(const Gtk::TreeNodeChildren &children, const ChannelData &channel);
|
||||
|
||||
|
||||
@@ -18,7 +18,8 @@ CellRendererChannels::CellRendererChannels()
|
||||
, m_property_pixbuf(*this, "pixbuf")
|
||||
, m_property_pixbuf_animation(*this, "pixbuf-animation")
|
||||
, m_property_expanded(*this, "expanded")
|
||||
, m_property_nsfw(*this, "nsfw") {
|
||||
, m_property_nsfw(*this, "nsfw")
|
||||
, m_property_color(*this, "color") {
|
||||
property_mode() = Gtk::CELL_RENDERER_MODE_ACTIVATABLE;
|
||||
property_xpad() = 2;
|
||||
property_ypad() = 2;
|
||||
@@ -55,8 +56,14 @@ Glib::PropertyProxy<bool> CellRendererChannels::property_nsfw() {
|
||||
return m_property_nsfw.get_proxy();
|
||||
}
|
||||
|
||||
Glib::PropertyProxy<std::optional<Gdk::RGBA>> CellRendererChannels::property_color() {
|
||||
return m_property_color.get_proxy();
|
||||
}
|
||||
|
||||
void CellRendererChannels::get_preferred_width_vfunc(Gtk::Widget &widget, int &minimum_width, int &natural_width) const {
|
||||
switch (m_property_type.get_value()) {
|
||||
case RenderType::Folder:
|
||||
return get_preferred_width_vfunc_folder(widget, minimum_width, natural_width);
|
||||
case RenderType::Guild:
|
||||
return get_preferred_width_vfunc_guild(widget, minimum_width, natural_width);
|
||||
case RenderType::Category:
|
||||
@@ -74,6 +81,8 @@ void CellRendererChannels::get_preferred_width_vfunc(Gtk::Widget &widget, int &m
|
||||
|
||||
void CellRendererChannels::get_preferred_width_for_height_vfunc(Gtk::Widget &widget, int height, int &minimum_width, int &natural_width) const {
|
||||
switch (m_property_type.get_value()) {
|
||||
case RenderType::Folder:
|
||||
return get_preferred_width_for_height_vfunc_folder(widget, height, minimum_width, natural_width);
|
||||
case RenderType::Guild:
|
||||
return get_preferred_width_for_height_vfunc_guild(widget, height, minimum_width, natural_width);
|
||||
case RenderType::Category:
|
||||
@@ -91,6 +100,8 @@ void CellRendererChannels::get_preferred_width_for_height_vfunc(Gtk::Widget &wid
|
||||
|
||||
void CellRendererChannels::get_preferred_height_vfunc(Gtk::Widget &widget, int &minimum_height, int &natural_height) const {
|
||||
switch (m_property_type.get_value()) {
|
||||
case RenderType::Folder:
|
||||
return get_preferred_height_vfunc_folder(widget, minimum_height, natural_height);
|
||||
case RenderType::Guild:
|
||||
return get_preferred_height_vfunc_guild(widget, minimum_height, natural_height);
|
||||
case RenderType::Category:
|
||||
@@ -108,6 +119,8 @@ void CellRendererChannels::get_preferred_height_vfunc(Gtk::Widget &widget, int &
|
||||
|
||||
void CellRendererChannels::get_preferred_height_for_width_vfunc(Gtk::Widget &widget, int width, int &minimum_height, int &natural_height) const {
|
||||
switch (m_property_type.get_value()) {
|
||||
case RenderType::Folder:
|
||||
return get_preferred_height_for_width_vfunc_folder(widget, width, minimum_height, natural_height);
|
||||
case RenderType::Guild:
|
||||
return get_preferred_height_for_width_vfunc_guild(widget, width, minimum_height, natural_height);
|
||||
case RenderType::Category:
|
||||
@@ -125,6 +138,8 @@ void CellRendererChannels::get_preferred_height_for_width_vfunc(Gtk::Widget &wid
|
||||
|
||||
void CellRendererChannels::render_vfunc(const Cairo::RefPtr<Cairo::Context> &cr, Gtk::Widget &widget, const Gdk::Rectangle &background_area, const Gdk::Rectangle &cell_area, Gtk::CellRendererState flags) {
|
||||
switch (m_property_type.get_value()) {
|
||||
case RenderType::Folder:
|
||||
return render_vfunc_folder(cr, widget, background_area, cell_area, flags);
|
||||
case RenderType::Guild:
|
||||
return render_vfunc_guild(cr, widget, background_area, cell_area, flags);
|
||||
case RenderType::Category:
|
||||
@@ -140,6 +155,69 @@ void CellRendererChannels::render_vfunc(const Cairo::RefPtr<Cairo::Context> &cr,
|
||||
}
|
||||
}
|
||||
|
||||
// folder functions
|
||||
|
||||
void CellRendererChannels::get_preferred_width_vfunc_folder(Gtk::Widget &widget, int &minimum_width, int &natural_width) const {
|
||||
m_renderer_text.get_preferred_width(widget, minimum_width, natural_width);
|
||||
}
|
||||
|
||||
void CellRendererChannels::get_preferred_width_for_height_vfunc_folder(Gtk::Widget &widget, int height, int &minimum_width, int &natural_width) const {
|
||||
m_renderer_text.get_preferred_width_for_height(widget, height, minimum_width, natural_width);
|
||||
}
|
||||
|
||||
void CellRendererChannels::get_preferred_height_vfunc_folder(Gtk::Widget &widget, int &minimum_height, int &natural_height) const {
|
||||
m_renderer_text.get_preferred_height(widget, minimum_height, natural_height);
|
||||
}
|
||||
|
||||
void CellRendererChannels::get_preferred_height_for_width_vfunc_folder(Gtk::Widget &widget, int width, int &minimum_height, int &natural_height) const {
|
||||
m_renderer_text.get_preferred_height_for_width(widget, width, minimum_height, natural_height);
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
Gtk::Requisition text_minimum, text_natural;
|
||||
m_renderer_text.get_preferred_size(widget, text_minimum, text_natural);
|
||||
|
||||
const int text_x = background_area.get_x() + 22;
|
||||
const int text_y = background_area.get_y() + background_area.get_height() / 2 - text_natural.height / 2;
|
||||
const int text_w = text_natural.width;
|
||||
const int text_h = text_natural.height;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// guild functions
|
||||
|
||||
void CellRendererChannels::get_preferred_width_vfunc_guild(Gtk::Widget &widget, int &minimum_width, int &natural_width) const {
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "discord/snowflake.hpp"
|
||||
|
||||
enum class RenderType : uint8_t {
|
||||
Folder,
|
||||
Guild,
|
||||
Category,
|
||||
TextChannel,
|
||||
@@ -27,6 +28,7 @@ public:
|
||||
Glib::PropertyProxy<Glib::RefPtr<Gdk::PixbufAnimation>> property_icon_animation();
|
||||
Glib::PropertyProxy<bool> property_expanded();
|
||||
Glib::PropertyProxy<bool> property_nsfw();
|
||||
Glib::PropertyProxy<std::optional<Gdk::RGBA>> property_color();
|
||||
|
||||
protected:
|
||||
void get_preferred_width_vfunc(Gtk::Widget &widget, int &minimum_width, int &natural_width) const override;
|
||||
@@ -39,6 +41,17 @@ protected:
|
||||
const Gdk::Rectangle &cell_area,
|
||||
Gtk::CellRendererState flags) override;
|
||||
|
||||
// guild functions
|
||||
void get_preferred_width_vfunc_folder(Gtk::Widget &widget, int &minimum_width, int &natural_width) const;
|
||||
void get_preferred_width_for_height_vfunc_folder(Gtk::Widget &widget, int height, int &minimum_width, int &natural_width) const;
|
||||
void get_preferred_height_vfunc_folder(Gtk::Widget &widget, int &minimum_height, int &natural_height) const;
|
||||
void get_preferred_height_for_width_vfunc_folder(Gtk::Widget &widget, int width, int &minimum_height, int &natural_height) const;
|
||||
void 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);
|
||||
|
||||
// guild functions
|
||||
void get_preferred_width_vfunc_guild(Gtk::Widget &widget, int &minimum_width, int &natural_width) const;
|
||||
void get_preferred_width_for_height_vfunc_guild(Gtk::Widget &widget, int height, int &minimum_width, int &natural_width) const;
|
||||
@@ -118,6 +131,7 @@ private:
|
||||
Glib::Property<Glib::RefPtr<Gdk::PixbufAnimation>> m_property_pixbuf_animation; // guild
|
||||
Glib::Property<bool> m_property_expanded; // category
|
||||
Glib::Property<bool> m_property_nsfw; // channel
|
||||
Glib::Property<std::optional<Gdk::RGBA>> m_property_color; // folder
|
||||
|
||||
// same pitfalls as in https://github.com/uowuo/abaddon/blob/60404783bd4ce9be26233fe66fc3a74475d9eaa3/components/cellrendererpixbufanimation.hpp#L32-L39
|
||||
// this will manifest though since guild icons can change
|
||||
|
||||
Reference in New Issue
Block a user