diff options
author | ouwou <26526779+ouwou@users.noreply.github.com> | 2024-01-17 16:46:25 -0500 |
---|---|---|
committer | ouwou <26526779+ouwou@users.noreply.github.com> | 2024-01-17 16:46:25 -0500 |
commit | 6e847ea31f6f9ddbbdd4a6d283812516dc56ef1d (patch) | |
tree | 834d564a4e41da59f3772f9e45f1f2305a18412a | |
parent | e9521ce7801eb2cb3b573bc85c2daeaab1003d26 (diff) | |
download | abaddon-portaudio-6e847ea31f6f9ddbbdd4a6d283812516dc56ef1d.tar.gz abaddon-portaudio-6e847ea31f6f9ddbbdd4a6d283812516dc56ef1d.zip |
use expansion state
-rw-r--r-- | src/components/channellist/channellisttree.cpp | 54 | ||||
-rw-r--r-- | src/components/channellist/channellisttree.hpp | 4 |
2 files changed, 58 insertions, 0 deletions
diff --git a/src/components/channellist/channellisttree.cpp b/src/components/channellist/channellisttree.cpp index 5a8b783..5b1a632 100644 --- a/src/components/channellist/channellisttree.cpp +++ b/src/components/channellist/channellisttree.cpp @@ -689,6 +689,55 @@ void ChannelListTree::SetActiveChannel(Snowflake id, bool expand_to) { } void ChannelListTree::UseExpansionState(const ExpansionStateRoot &root) { + m_updating_listing = true; + m_filter_model->refilter(); + + auto recurse = [this](auto &self, const ExpansionStateRoot &root) -> void { + for (const auto &[id, state] : root.Children) { + 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) { + (*row_iter)[m_columns.m_expanded] = state.IsExpanded; + auto filter_iter = m_filter_model->convert_child_iter_to_iter(row_iter); + if (filter_iter) { + if (state.IsExpanded) { + m_view.expand_row(m_filter_model->get_path(filter_iter), false); + } else { + m_view.collapse_row(m_filter_model->get_path(filter_iter)); + } + } + } + + self(self, state.Children); + } + }; + + for (const auto &[id, state] : root.Children) { + if (const auto iter = GetIteratorForTopLevelFromID(id)) { + (*iter)[m_columns.m_expanded] = state.IsExpanded; + auto filter_iter = m_filter_model->convert_child_iter_to_iter(iter); + if (filter_iter) { + if (state.IsExpanded) { + m_view.expand_row(m_filter_model->get_path(filter_iter), false); + } else { + m_view.collapse_row(m_filter_model->get_path(filter_iter)); + } + } + } + + recurse(recurse, state.Children); + } + + m_updating_listing = false; + m_filter_model->refilter(); + + m_tmp_row_map.clear(); + m_tmp_guild_row_map.clear(); } ExpansionStateRoot ChannelListTree::GetExpansionState() const { @@ -727,6 +776,7 @@ Gtk::TreeModel::iterator ChannelListTree::AddFolder(const UserSettingsGuildFolde 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 { @@ -760,6 +810,7 @@ Gtk::TreeModel::iterator ChannelListTree::AddGuild(const GuildData &guild, const 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) { @@ -842,6 +893,7 @@ Gtk::TreeModel::iterator ChannelListTree::AddGuild(const GuildData &guild, const channel_row[m_columns.m_sort] = *channel.Position + OrphanChannelSortOffset; channel_row[m_columns.m_nsfw] = channel.NSFW(); add_threads(channel, channel_row); + m_tmp_row_map[channel.ID] = channel_row; } for (const auto &[category_id, channels] : categories) { @@ -853,6 +905,7 @@ Gtk::TreeModel::iterator ChannelListTree::AddGuild(const GuildData &guild, const 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_row_map[category_id] = cat_row; // m_view.expand_row wont work because it might not have channels for (const auto &channel : channels) { @@ -872,6 +925,7 @@ Gtk::TreeModel::iterator ChannelListTree::AddGuild(const GuildData &guild, const channel_row[m_columns.m_sort] = *channel.Position; channel_row[m_columns.m_nsfw] = channel.NSFW(); add_threads(channel, channel_row); + m_tmp_row_map[channel.ID] = channel_row; } } diff --git a/src/components/channellist/channellisttree.hpp b/src/components/channellist/channellisttree.hpp index 7ad0d29..b49187a 100644 --- a/src/components/channellist/channellisttree.hpp +++ b/src/components/channellist/channellisttree.hpp @@ -198,6 +198,10 @@ protected: Snowflake m_active_channel; + // hashtable for the billion lookups done in UseExpansionState + 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>; using type_signal_action_guild_leave = sigc::signal<void, Snowflake>; |