diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/components/channellist/cellrendererchannels.cpp (renamed from src/components/channelscellrenderer.cpp) | 2 | ||||
-rw-r--r-- | src/components/channellist/cellrendererchannels.hpp (renamed from src/components/channelscellrenderer.hpp) | 0 | ||||
-rw-r--r-- | src/components/channellist/channellist.cpp (renamed from src/components/channels.cpp) | 91 | ||||
-rw-r--r-- | src/components/channellist/channellist.hpp (renamed from src/components/channels.hpp) | 6 | ||||
-rw-r--r-- | src/components/channellist/classic/guildlist.cpp | 23 | ||||
-rw-r--r-- | src/components/channellist/classic/guildlist.hpp | 12 | ||||
-rw-r--r-- | src/components/channellist/classic/guildlistfolderitem.cpp | 18 | ||||
-rw-r--r-- | src/components/channellist/classic/guildlistfolderitem.hpp | 18 | ||||
-rw-r--r-- | src/components/channellist/classic/guildlistguilditem.cpp | 29 | ||||
-rw-r--r-- | src/components/channellist/classic/guildlistguilditem.hpp | 17 | ||||
-rw-r--r-- | src/windows/mainwindow.cpp | 1 | ||||
-rw-r--r-- | src/windows/mainwindow.hpp | 2 |
12 files changed, 152 insertions, 67 deletions
diff --git a/src/components/channelscellrenderer.cpp b/src/components/channellist/cellrendererchannels.cpp index ac98512..e0079cd 100644 --- a/src/components/channelscellrenderer.cpp +++ b/src/components/channellist/cellrendererchannels.cpp @@ -1,4 +1,4 @@ -#include "channelscellrenderer.hpp" +#include "cellrendererchannels.hpp" constexpr static int MentionsRightPad = 7; #ifndef M_PI diff --git a/src/components/channelscellrenderer.hpp b/src/components/channellist/cellrendererchannels.hpp index 934ce5b..934ce5b 100644 --- a/src/components/channelscellrenderer.hpp +++ b/src/components/channellist/cellrendererchannels.hpp diff --git a/src/components/channels.cpp b/src/components/channellist/channellist.cpp index 9fd4abd..51e8f33 100644 --- a/src/components/channels.cpp +++ b/src/components/channellist/channellist.cpp @@ -1,6 +1,6 @@ -#include "channels.hpp" +#include "channellist.hpp" #include "imgmanager.hpp" -#include "statusindicator.hpp" +#include "components/statusindicator.hpp" #include <algorithm> #include <map> #include <unordered_map> @@ -8,6 +8,7 @@ ChannelList::ChannelList() : Glib::ObjectBase(typeid(ChannelList)) , m_model(Gtk::TreeStore::create(m_columns)) + , m_filter_model(Gtk::TreeModelFilter::create(m_model)) , m_menu_guild_copy_id("_Copy ID", true) , m_menu_guild_settings("View _Settings", true) , m_menu_guild_leave("_Leave", true) @@ -36,9 +37,9 @@ ChannelList::ChannelList() , m_menu_thread_mark_as_read("Mark as _Read", true) { get_style_context()->add_class("channel-list"); - // todo: move to method + // Filter iters const auto cb = [this](const Gtk::TreeModel::Path &path, Gtk::TreeViewColumn *column) { - auto row = *m_model->get_iter(path); + auto row = *m_filter_model->get_iter(path); const auto type = row[m_columns.m_type]; // text channels should not be allowed to be collapsed // maybe they should be but it seems a little difficult to handle expansion to permit this @@ -72,13 +73,22 @@ ChannelList::ChannelList() m_view.set_show_expanders(false); m_view.set_enable_search(false); m_view.set_headers_visible(false); - m_view.set_model(m_model); + m_view.set_model(m_filter_model); m_model->set_sort_column(m_columns.m_sort, Gtk::SORT_ASCENDING); m_model->signal_row_inserted().connect([this](const Gtk::TreeModel::Path &path, const Gtk::TreeModel::iterator &iter) { if (m_updating_listing) return; - if (auto parent = iter->parent(); parent && (*parent)[m_columns.m_expanded]) - m_view.expand_row(m_model->get_path(parent), false); + if (auto parent = iter->parent(); parent && (*parent)[m_columns.m_expanded]) { + const auto filter_path = m_filter_model->convert_child_path_to_path(m_model->get_path(parent)); + m_view.expand_row(filter_path, false); + } + }); + + m_filter_model->set_visible_func([this](const Gtk::TreeModel::const_iterator &iter) -> bool { + if ((*iter)[m_columns.m_type] == RenderType::Guild) { + return (*iter)[m_columns.m_id] == 754921263616753776ULL; + } + return true; }); m_view.show(); @@ -594,9 +604,9 @@ void ChannelList::SetActiveChannel(Snowflake id, bool expand_to) { const auto channel_iter = GetIteratorForRowFromID(id); if (channel_iter) { if (expand_to) { - m_view.expand_to_path(m_model->get_path(channel_iter)); + m_view.expand_to_path(m_filter_model->convert_child_path_to_path(m_model->get_path(channel_iter))); } - m_view.get_selection()->select(channel_iter); + m_view.get_selection()->select(m_filter_model->convert_child_iter_to_iter(channel_iter)); } else { m_view.get_selection()->unselect_all(); const auto channel = Abaddon::Get().GetDiscordClient().GetChannel(id); @@ -604,64 +614,17 @@ void ChannelList::SetActiveChannel(Snowflake id, bool expand_to) { auto parent_iter = GetIteratorForRowFromID(*channel->ParentID); if (!parent_iter) return; m_temporary_thread_row = CreateThreadRow(parent_iter->children(), *channel); - m_view.get_selection()->select(m_temporary_thread_row); + m_view.get_selection()->select(m_filter_model->convert_child_iter_to_iter(m_temporary_thread_row)); } } void ChannelList::UseExpansionState(const ExpansionStateRoot &root) { - 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) { - if (state.IsExpanded) - m_view.expand_row(m_model->get_path(row_iter), false); - else - m_view.collapse_row(m_model->get_path(row_iter)); - } - - self(self, state.Children); - } - }; - - for (const auto &[id, state] : root.Children) { - if (const auto iter = GetIteratorForTopLevelFromID(id)) { - if (state.IsExpanded) - m_view.expand_row(m_model->get_path(iter), false); - else - m_view.collapse_row(m_model->get_path(iter)); - } - - recurse(recurse, state.Children); - } - m_tmp_row_map.clear(); } ExpansionStateRoot ChannelList::GetExpansionState() const { ExpansionStateRoot r; - auto recurse = [this](auto &self, const Gtk::TreeRow &row) -> ExpansionState { - ExpansionState r; - - r.IsExpanded = row[m_columns.m_expanded]; - for (const auto &child : row.children()) - r.Children.Children[static_cast<Snowflake>(child[m_columns.m_id])] = self(self, child); - - return r; - }; - - for (const auto &child : m_model->children()) { - const auto id = static_cast<Snowflake>(child[m_columns.m_id]); - if (static_cast<uint64_t>(id) == 0ULL) continue; // dont save DM header - r.Children[id] = recurse(recurse, child); - } - return r; } @@ -969,7 +932,7 @@ void ChannelList::OnRowExpanded(const Gtk::TreeModel::iterator &iter, const Gtk: // restore previous expansion for (auto it = iter->children().begin(); it != iter->children().end(); it++) { if ((*it)[m_columns.m_expanded]) - m_view.expand_row(m_model->get_path(it), false); + m_view.expand_row(m_filter_model->get_path(it), false); } // try and restore selection if previous collapsed @@ -981,11 +944,13 @@ void ChannelList::OnRowExpanded(const Gtk::TreeModel::iterator &iter, const Gtk: } bool ChannelList::SelectionFunc(const Glib::RefPtr<Gtk::TreeModel> &model, const Gtk::TreeModel::Path &path, bool is_currently_selected) { - if (auto selection = m_view.get_selection()) - if (auto row = selection->get_selected()) - m_last_selected = m_model->get_path(row); + if (auto selection = m_view.get_selection()) { + if (auto row = selection->get_selected()) { + m_last_selected = m_filter_model->get_path(row); + } + } - auto type = (*m_model->get_iter(path))[m_columns.m_type]; + auto type = (*model->get_iter(path))[m_columns.m_type]; return type == RenderType::TextChannel || type == RenderType::DM || type == RenderType::Thread; } @@ -1139,7 +1104,7 @@ void ChannelList::OnMessageCreate(const Message &msg) { bool ChannelList::OnButtonPressEvent(GdkEventButton *ev) { if (ev->button == GDK_BUTTON_SECONDARY && ev->type == GDK_BUTTON_PRESS) { if (m_view.get_path_at_pos(static_cast<int>(ev->x), static_cast<int>(ev->y), m_path_for_menu)) { - auto row = (*m_model->get_iter(m_path_for_menu)); + auto row = (*m_filter_model->get_iter(m_path_for_menu)); switch (static_cast<RenderType>(row[m_columns.m_type])) { case RenderType::Guild: OnGuildSubmenuPopup(); diff --git a/src/components/channels.hpp b/src/components/channellist/channellist.hpp index 9d449e4..df7dbac 100644 --- a/src/components/channels.hpp +++ b/src/components/channellist/channellist.hpp @@ -8,11 +8,12 @@ #include <gtkmm/scrolledwindow.h> #include <gtkmm/treemodel.h> #include <gtkmm/treestore.h> +#include <gtkmm/treemodelfilter.h> #include <gtkmm/treeview.h> #include <sigc++/sigc++.h> #include "discord/discord.hpp" #include "state.hpp" -#include "channelscellrenderer.hpp" +#include "cellrendererchannels.hpp" constexpr static int GuildIconSize = 24; constexpr static int DMIconSize = 20; @@ -82,6 +83,7 @@ protected: ModelColumns m_columns; Glib::RefPtr<Gtk::TreeStore> m_model; + Glib::RefPtr<Gtk::TreeModelFilter> m_filter_model; Gtk::TreeModel::iterator AddFolder(const UserSettingsGuildFoldersEntry &folder); Gtk::TreeModel::iterator AddGuild(const GuildData &guild, const Gtk::TreeNodeChildren &root); @@ -116,7 +118,7 @@ protected: void UpdateCreateDMChannel(const ChannelData &channel); void SetDMChannelIcon(Gtk::TreeIter iter, const ChannelData &dm); - void RedrawUnreadIndicatorsForChannel(const ChannelData& channel); + void RedrawUnreadIndicatorsForChannel(const ChannelData &channel); void OnMessageAck(const MessageAckData &data); void OnMessageCreate(const Message &msg); diff --git a/src/components/channellist/classic/guildlist.cpp b/src/components/channellist/classic/guildlist.cpp new file mode 100644 index 0000000..0d5737b --- /dev/null +++ b/src/components/channellist/classic/guildlist.cpp @@ -0,0 +1,23 @@ +#include "guildlist.hpp" +#include "guildlistfolderitem.hpp" + +GuildList::GuildList() { + set_selection_mode(Gtk::SELECTION_NONE); + show_all_children(); +} + +void GuildList::AddGuild(Snowflake id) { + const auto guild = Abaddon::Get().GetDiscordClient().GetGuild(id); + if (!guild.has_value()) return; + + auto *item = Gtk::make_managed<GuildListGuildItem>(*guild); + item->show(); + add(*item); +} + +void GuildList::Clear() { + const auto children = get_children(); + for (auto child : children) { + delete child; + } +} diff --git a/src/components/channellist/classic/guildlist.hpp b/src/components/channellist/classic/guildlist.hpp new file mode 100644 index 0000000..244313f --- /dev/null +++ b/src/components/channellist/classic/guildlist.hpp @@ -0,0 +1,12 @@ +#pragma once +#include <gtkmm/listbox.h> +#include "discord/snowflake.hpp" + +class GuildList : public Gtk::ListBox { +public: + GuildList(); + + void AddGuild(Snowflake id); + + void Clear(); +}; diff --git a/src/components/channellist/classic/guildlistfolderitem.cpp b/src/components/channellist/classic/guildlistfolderitem.cpp new file mode 100644 index 0000000..36d5a5a --- /dev/null +++ b/src/components/channellist/classic/guildlistfolderitem.cpp @@ -0,0 +1,18 @@ +#include "guildlistfolderitem.hpp" + +GuildListFolderItem::GuildListFolderItem() { + m_revealer.add(m_box); + m_revealer.set_reveal_child(true); + + m_ev.signal_button_press_event().connect([this](GdkEventButton *event) -> bool { + if (event->type == GDK_BUTTON_PRESS && event->button == GDK_BUTTON_PRIMARY) { + m_revealer.set_reveal_child(!m_revealer.get_reveal_child()); + } + return false; + }); + + m_ev.add(m_image); + add(m_ev); + add(m_revealer); + show_all_children(); +} diff --git a/src/components/channellist/classic/guildlistfolderitem.hpp b/src/components/channellist/classic/guildlistfolderitem.hpp new file mode 100644 index 0000000..3506969 --- /dev/null +++ b/src/components/channellist/classic/guildlistfolderitem.hpp @@ -0,0 +1,18 @@ +#pragma once +#include <gtkmm/box.h> +#include <gtkmm/eventbox.h> +#include <gtkmm/image.h> +#include <gtkmm/revealer.h> + +#include "guildlistguilditem.hpp" + +class GuildListFolderItem : public Gtk::VBox { +public: + GuildListFolderItem(); + +private: + Gtk::EventBox m_ev; + Gtk::Image m_image; + Gtk::Revealer m_revealer; + Gtk::VBox m_box; +}; diff --git a/src/components/channellist/classic/guildlistguilditem.cpp b/src/components/channellist/classic/guildlistguilditem.cpp new file mode 100644 index 0000000..88ed2a9 --- /dev/null +++ b/src/components/channellist/classic/guildlistguilditem.cpp @@ -0,0 +1,29 @@ +#include "guildlistguilditem.hpp" + +GuildListGuildItem::GuildListGuildItem(const GuildData &guild) + : ID(guild.ID) { + m_image.property_pixbuf() = Abaddon::Get().GetImageManager().GetPlaceholder(48); + add(m_image); + show_all_children(); + + signal_button_press_event().connect([this](GdkEventButton *event) -> bool { + if (event->type == GDK_BUTTON_PRESS && event->button == GDK_BUTTON_PRIMARY) { + printf("Click %llu\n", (uint64_t)ID); + } + return true; + }); + + set_tooltip_text(guild.Name); + + UpdateIcon(); +} + +void GuildListGuildItem::UpdateIcon() { + const auto guild = Abaddon::Get().GetDiscordClient().GetGuild(ID); + if (!guild.has_value()) return; + Abaddon::Get().GetImageManager().LoadFromURL(guild->GetIconURL("png", "64"), sigc::mem_fun(*this, &GuildListGuildItem::OnIconFetched)); +} + +void GuildListGuildItem::OnIconFetched(const Glib::RefPtr<Gdk::Pixbuf> &pb) { + m_image.property_pixbuf() = pb->scale_simple(48, 48, Gdk::INTERP_BILINEAR); +} diff --git a/src/components/channellist/classic/guildlistguilditem.hpp b/src/components/channellist/classic/guildlistguilditem.hpp new file mode 100644 index 0000000..3114a05 --- /dev/null +++ b/src/components/channellist/classic/guildlistguilditem.hpp @@ -0,0 +1,17 @@ +#pragma once +#include <gtkmm/box.h> +#include <gtkmm/image.h> +#include "discord/guild.hpp" + +class GuildListGuildItem : public Gtk::EventBox { +public: + GuildListGuildItem(const GuildData &guild); + + Snowflake ID; + +private: + void UpdateIcon(); + void OnIconFetched(const Glib::RefPtr<Gdk::Pixbuf> &pb); + + Gtk::Image m_image; +}; diff --git a/src/windows/mainwindow.cpp b/src/windows/mainwindow.cpp index 8e030ed..8156659 100644 --- a/src/windows/mainwindow.cpp +++ b/src/windows/mainwindow.cpp @@ -1,4 +1,5 @@ #include "mainwindow.hpp" +#include "components/channellist/channellist.hpp" MainWindow::MainWindow() : m_main_box(Gtk::ORIENTATION_VERTICAL) diff --git a/src/windows/mainwindow.hpp b/src/windows/mainwindow.hpp index ce2e636..37c1b87 100644 --- a/src/windows/mainwindow.hpp +++ b/src/windows/mainwindow.hpp @@ -1,5 +1,5 @@ #pragma once -#include "components/channels.hpp" +#include "components/channellist/channellist.hpp" #include "components/chatwindow.hpp" #include "components/memberlist.hpp" #include "components/friendslist.hpp" |