Skip to content

Commit

Permalink
fix channel tree expansion under folders
Browse files Browse the repository at this point in the history
  • Loading branch information
ouwou committed Feb 5, 2023
1 parent 84cb4df commit 156bd2b
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 12 deletions.
45 changes: 34 additions & 11 deletions src/components/channels.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -535,22 +535,27 @@ void ChannelList::SetActiveChannel(Snowflake id, bool expand_to) {

void ChannelList::UseExpansionState(const ExpansionStateRoot &root) {
auto recurse = [this](auto &self, const ExpansionStateRoot &root) -> void {
// and these are only channels
for (const auto &[id, state] : root.Children) {
if (const auto iter = m_tmp_channel_map.find(id); iter != m_tmp_channel_map.end()) {
Gtk::TreeModel::iterator row_iter;
if (const auto map_iter = m_tmp_row_map.find(id); map_iter != m_tmp_row_map.end()) {
row_iter = map_iter->second;
} else if (const auto map_iter = m_tmp_guild_row_map.find(id); map_iter != m_tmp_guild_row_map.end()) {
row_iter = map_iter->second;
}

if (row_iter) {
if (state.IsExpanded)
m_view.expand_row(m_model->get_path(iter->second), false);
m_view.expand_row(m_model->get_path(row_iter), false);
else
m_view.collapse_row(m_model->get_path(iter->second));
m_view.collapse_row(m_model->get_path(row_iter));
}

self(self, state.Children);
}
};

// top level is guild
for (const auto &[id, state] : root.Children) {
if (const auto iter = GetIteratorForGuildFromID(id)) {
if (const auto iter = GetIteratorForTopLevelFromID(id)) {
if (state.IsExpanded)
m_view.expand_row(m_model->get_path(iter), false);
else
Expand All @@ -560,7 +565,7 @@ void ChannelList::UseExpansionState(const ExpansionStateRoot &root) {
recurse(recurse, state.Children);
}

m_tmp_channel_map.clear();
m_tmp_row_map.clear();
}

ExpansionStateRoot ChannelList::GetExpansionState() const {
Expand Down Expand Up @@ -598,6 +603,7 @@ Gtk::TreeModel::iterator ChannelList::AddFolder(const UserSettingsGuildFoldersEn
auto folder_row = *m_model->append();
folder_row[m_columns.m_type] = RenderType::Folder;
folder_row[m_columns.m_id] = *folder.ID;
m_tmp_row_map[*folder.ID] = folder_row;
if (folder.Name.has_value()) {
folder_row[m_columns.m_name] = Glib::Markup::escape_text(*folder.Name);
} else {
Expand Down Expand Up @@ -631,6 +637,7 @@ Gtk::TreeModel::iterator ChannelList::AddGuild(const GuildData &guild, const Gtk
guild_row[m_columns.m_id] = guild.ID;
guild_row[m_columns.m_name] = "<b>" + Glib::Markup::escape_text(guild.Name) + "</b>";
guild_row[m_columns.m_icon] = img.GetPlaceholder(GuildIconSize);
m_tmp_guild_row_map[guild.ID] = guild_row;

if (Abaddon::Get().GetSettings().ShowAnimations && guild.HasAnimatedIcon()) {
const auto cb = [this, id = guild.ID](const Glib::RefPtr<Gdk::PixbufAnimation> &pb) {
Expand Down Expand Up @@ -678,7 +685,7 @@ Gtk::TreeModel::iterator ChannelList::AddGuild(const GuildData &guild, const Gtk
if (it == threads.end()) return;

for (const auto &thread : it->second)
m_tmp_channel_map[thread.ID] = CreateThreadRow(row.children(), thread);
m_tmp_row_map[thread.ID] = CreateThreadRow(row.children(), thread);
};

for (const auto &channel : orphan_channels) {
Expand All @@ -689,7 +696,7 @@ Gtk::TreeModel::iterator ChannelList::AddGuild(const GuildData &guild, const Gtk
channel_row[m_columns.m_sort] = *channel.Position + OrphanChannelSortOffset;
channel_row[m_columns.m_nsfw] = channel.NSFW();
add_threads(channel, channel_row);
m_tmp_channel_map[channel.ID] = channel_row;
m_tmp_row_map[channel.ID] = channel_row;
}

for (const auto &[category_id, channels] : categories) {
Expand All @@ -701,7 +708,7 @@ Gtk::TreeModel::iterator ChannelList::AddGuild(const GuildData &guild, const Gtk
cat_row[m_columns.m_name] = Glib::Markup::escape_text(*category->Name);
cat_row[m_columns.m_sort] = *category->Position;
cat_row[m_columns.m_expanded] = true;
m_tmp_channel_map[category_id] = cat_row;
m_tmp_row_map[category_id] = cat_row;
// m_view.expand_row wont work because it might not have channels

for (const auto &channel : channels) {
Expand All @@ -712,7 +719,7 @@ Gtk::TreeModel::iterator ChannelList::AddGuild(const GuildData &guild, const Gtk
channel_row[m_columns.m_sort] = *channel.Position;
channel_row[m_columns.m_nsfw] = channel.NSFW();
add_threads(channel, channel_row);
m_tmp_channel_map[channel.ID] = channel_row;
m_tmp_row_map[channel.ID] = channel_row;
}
}

Expand Down Expand Up @@ -753,6 +760,22 @@ void ChannelList::UpdateChannelCategory(const ChannelData &channel) {
(*iter)[m_columns.m_name] = Glib::Markup::escape_text(*channel.Name);
}

// todo this all needs refactoring for shooore
Gtk::TreeModel::iterator ChannelList::GetIteratorForTopLevelFromID(Snowflake id) {
for (const auto &child : m_model->children()) {
if ((child[m_columns.m_type] == RenderType::Guild || child[m_columns.m_type] == RenderType::Folder) && 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 {};
}

Gtk::TreeModel::iterator ChannelList::GetIteratorForGuildFromID(Snowflake id) {
for (const auto &child : m_model->children()) {
if (child[m_columns.m_type] == RenderType::Guild && child[m_columns.m_id] == id) {
Expand Down
9 changes: 8 additions & 1 deletion src/components/channels.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@
#include <mutex>
#include <unordered_set>
#include <unordered_map>
#include <gtkmm/paned.h>
#include <gtkmm/scrolledwindow.h>
#include <gtkmm/treemodel.h>
#include <gtkmm/treestore.h>
#include <gtkmm/treeview.h>
#include <sigc++/sigc++.h>
#include "discord/discord.hpp"
#include "state.hpp"
Expand Down Expand Up @@ -80,6 +85,7 @@ class ChannelList : public Gtk::ScrolledWindow {
void UpdateChannelCategory(const ChannelData &channel);

// separation necessary because a channel and guild can share the same id
Gtk::TreeModel::iterator GetIteratorForTopLevelFromID(Snowflake id);
Gtk::TreeModel::iterator GetIteratorForGuildFromID(Snowflake id);
Gtk::TreeModel::iterator GetIteratorForChannelFromID(Snowflake id);

Expand Down Expand Up @@ -155,7 +161,8 @@ class ChannelList : public Gtk::ScrolledWindow {

// (GetIteratorForChannelFromID is rather slow)
// only temporary since i dont want to worry about maintaining this map
std::unordered_map<Snowflake, Gtk::TreeModel::iterator> m_tmp_channel_map;
std::unordered_map<Snowflake, Gtk::TreeModel::iterator> m_tmp_row_map;
std::unordered_map<Snowflake, Gtk::TreeModel::iterator> m_tmp_guild_row_map;

public:
using type_signal_action_channel_item_select = sigc::signal<void, Snowflake>;
Expand Down

0 comments on commit 156bd2b

Please sign in to comment.