summaryrefslogtreecommitdiff
path: root/src/components
diff options
context:
space:
mode:
authorouwou <26526779+ouwou@users.noreply.github.com>2023-02-01 23:49:48 -0500
committerouwou <26526779+ouwou@users.noreply.github.com>2023-02-01 23:49:48 -0500
commitecc83036c1522a024e1f5a1efc6fe533b907daf1 (patch)
treeceb75059aec90e01a314e59851beefffa733cdb0 /src/components
parent5a6f8cac09770d315fe4a3258fa6116e65750f24 (diff)
parent3ed51eb155444859c3aa00119857b602066c9c10 (diff)
downloadabaddon-portaudio-ecc83036c1522a024e1f5a1efc6fe533b907daf1.tar.gz
abaddon-portaudio-ecc83036c1522a024e1f5a1efc6fe533b907daf1.zip
Merge branch 'master' into pch
Diffstat (limited to 'src/components')
-rw-r--r--src/components/channels.cpp109
-rw-r--r--src/components/channels.hpp4
-rw-r--r--src/components/channelscellrenderer.cpp80
-rw-r--r--src/components/channelscellrenderer.hpp14
4 files changed, 194 insertions, 13 deletions
diff --git a/src/components/channels.cpp b/src/components/channels.cpp
index 80990ab..589b103 100644
--- a/src/components/channels.cpp
+++ b/src/components/channels.cpp
@@ -87,6 +87,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] {
@@ -260,14 +261,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
+ }
+ ]
+
+ so if id != null then its a folder (they can have single entries)
+ */
+
+ int sort_value = 0;
- auto iter = AddGuild(*guild);
- (*iter)[m_columns.m_sort] = sortnum++;
+ 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;
@@ -275,8 +313,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()) {
@@ -403,6 +442,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);
@@ -544,11 +585,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>";
@@ -677,8 +755,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 {};
}
@@ -884,6 +969,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
@@ -996,4 +1082,5 @@ ChannelList::ModelColumns::ModelColumns() {
add(m_sort);
add(m_nsfw);
add(m_expanded);
+ add(m_color);
}
diff --git a/src/components/channels.hpp b/src/components/channels.hpp
index cca2ad5..6c16fcd 100644
--- a/src/components/channels.hpp
+++ b/src/components/channels.hpp
@@ -60,6 +60,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
@@ -71,7 +72,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);
diff --git a/src/components/channelscellrenderer.cpp b/src/components/channelscellrenderer.cpp
index e7dbf25..1fa4a1a 100644
--- a/src/components/channelscellrenderer.cpp
+++ b/src/components/channelscellrenderer.cpp
@@ -16,7 +16,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;
@@ -53,8 +54,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:
@@ -72,6 +79,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:
@@ -89,6 +98,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:
@@ -106,6 +117,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:
@@ -123,6 +136,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:
@@ -138,6 +153,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 {
diff --git a/src/components/channelscellrenderer.hpp b/src/components/channelscellrenderer.hpp
index d20a1b1..00c537b 100644
--- a/src/components/channelscellrenderer.hpp
+++ b/src/components/channelscellrenderer.hpp
@@ -5,6 +5,7 @@
#include "discord/snowflake.hpp"
enum class RenderType : uint8_t {
+ Folder,
Guild,
Category,
TextChannel,
@@ -26,6 +27,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:
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;
void get_preferred_height_vfunc_guild(Gtk::Widget &widget, int &minimum_height, int &natural_height) const;
@@ -117,6 +130,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