From 7ffded5b1373444cf3442d759a3bd8ae0940bd7d Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Wed, 11 Aug 2021 03:32:09 -0400 Subject: rest of view threads window --- windows/threadswindow.cpp | 107 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 windows/threadswindow.cpp (limited to 'windows/threadswindow.cpp') diff --git a/windows/threadswindow.cpp b/windows/threadswindow.cpp new file mode 100644 index 0000000..a772eeb --- /dev/null +++ b/windows/threadswindow.cpp @@ -0,0 +1,107 @@ +#include "threadswindow.hpp" +#include "../abaddon.hpp" + +ThreadsWindow::ThreadsWindow(const ChannelData &channel) + : m_channel_id(channel.ID) + , m_box(Gtk::ORIENTATION_VERTICAL) + , m_active(channel) + , m_archived(channel) { + set_name("threads-window"); + set_default_size(450, 375); + set_title("#" + *channel.Name + " - Threads"); + set_position(Gtk::WIN_POS_CENTER); + get_style_context()->add_class("app-window"); + get_style_context()->add_class("app-popup"); + get_style_context()->add_class("threads-window"); + + const auto cb = [this](Snowflake id) { + Abaddon::Get().ActionChannelOpened(id); + hide(); + }; + m_active.signal_thread_open().connect(cb); + m_archived.signal_thread_open().connect(cb); + + m_switcher.set_halign(Gtk::ALIGN_CENTER); + m_switcher.set_stack(m_stack); + + m_stack.add(m_active, "active", "Active Threads"); + m_stack.add(m_archived, "archived", "Archived Threads"); + + m_active.show(); + m_archived.show(); + m_switcher.show(); + m_stack.show(); + m_box.show(); + + m_box.add(m_switcher); + m_box.add(m_stack); + add(m_box); +} + +ThreadListRow::ThreadListRow(const ChannelData &channel) + : ID(channel.ID) + , m_label(*channel.Name, Gtk::ALIGN_START) { + m_label.show(); + add(m_label); +} + +ActiveThreadsList::ActiveThreadsList(const ChannelData &channel) { + set_vexpand(true); + + m_list.set_selection_mode(Gtk::SELECTION_SINGLE); + m_list.set_hexpand(true); + m_list.show(); + + add(m_list); + + m_list.signal_button_press_event().connect([this](GdkEventButton *ev) -> bool { + if (ev->button == GDK_BUTTON_PRIMARY && ev->type == GDK_2BUTTON_PRESS) { + if (auto row = dynamic_cast(m_list.get_selected_row())) + m_signal_thread_open.emit(row->ID); + } + return false; + }); + + const auto threads = Abaddon::Get().GetDiscordClient().GetActiveThreads(channel.ID); + for (const auto &thread : threads) { + auto row = Gtk::manage(new ThreadListRow(thread)); + row->show(); + m_list.add(*row); + } +} + +ActiveThreadsList::type_signal_thread_open ActiveThreadsList::signal_thread_open() { + return m_signal_thread_open; +} + +ArchivedThreadsList::ArchivedThreadsList(const ChannelData &channel) { + set_vexpand(true); + + m_list.set_selection_mode(Gtk::SELECTION_SINGLE); + m_list.set_hexpand(true); + m_list.show(); + + add(m_list); + + m_list.signal_button_press_event().connect([this](GdkEventButton *ev) -> bool { + if (ev->button == GDK_BUTTON_PRIMARY && ev->type == GDK_2BUTTON_PRESS) { + if (auto row = dynamic_cast(m_list.get_selected_row())) + m_signal_thread_open.emit(row->ID); + } + return false; + }); + + Abaddon::Get().GetDiscordClient().GetArchivedPublicThreads(channel.ID, sigc::mem_fun(*this, &ArchivedThreadsList::OnPublicFetched)); +} + +void ArchivedThreadsList::OnPublicFetched(DiscordError code, const ArchivedThreadsResponseData &data) { + for (const auto &thread : data.Threads) { + auto row = Gtk::manage(new ThreadListRow(thread)); + row->show(); + m_list.add(*row); + } +} + +ArchivedThreadsList::type_signal_thread_open ArchivedThreadsList::signal_thread_open() { + return m_signal_thread_open; +} -- cgit v1.2.3 From 69e03bbfb7ffa9167ca608d72caa6bc90ec190a6 Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Sun, 22 Aug 2021 01:21:06 -0400 Subject: public/private filter in threads window --- windows/threadswindow.cpp | 50 +++++++++++++++++++++++++++++++++++++++++++---- windows/threadswindow.hpp | 23 ++++++++++++++++++++-- 2 files changed, 67 insertions(+), 6 deletions(-) (limited to 'windows/threadswindow.cpp') diff --git a/windows/threadswindow.cpp b/windows/threadswindow.cpp index a772eeb..1bfb326 100644 --- a/windows/threadswindow.cpp +++ b/windows/threadswindow.cpp @@ -4,8 +4,10 @@ ThreadsWindow::ThreadsWindow(const ChannelData &channel) : m_channel_id(channel.ID) , m_box(Gtk::ORIENTATION_VERTICAL) - , m_active(channel) - , m_archived(channel) { + , m_active(channel, sigc::mem_fun(*this, &ThreadsWindow::ListFilterFunc)) + , m_archived(channel, sigc::mem_fun(*this, &ThreadsWindow::ListFilterFunc)) + , m_filter_public(m_group, "Public") + , m_filter_private(m_group, "Private") { set_name("threads-window"); set_default_size(450, 375); set_title("#" + *channel.Name + " - Threads"); @@ -27,27 +29,58 @@ ThreadsWindow::ThreadsWindow(const ChannelData &channel) m_stack.add(m_active, "active", "Active Threads"); m_stack.add(m_archived, "archived", "Archived Threads"); + m_filter_buttons.set_homogeneous(true); + m_filter_buttons.set_halign(Gtk::ALIGN_CENTER); + m_filter_buttons.add(m_filter_public); + m_filter_buttons.add(m_filter_private); + + // a little strange + const auto btncb = [this](Gtk::RadioButton *btn) { + if (btn->get_active()) { + if (btn == &m_filter_public) + m_filter_mode = FILTER_PUBLIC; + else if (btn == &m_filter_private) + m_filter_mode = FILTER_PRIVATE; + + m_active.InvalidateFilter(); + m_archived.InvalidateFilter(); + } + }; + m_filter_public.signal_toggled().connect(sigc::bind(btncb, &m_filter_public)); + m_filter_private.signal_toggled().connect(sigc::bind(btncb, &m_filter_private)); + m_active.show(); m_archived.show(); m_switcher.show(); + m_filter_buttons.show_all(); m_stack.show(); m_box.show(); m_box.add(m_switcher); + m_box.add(m_filter_buttons); m_box.add(m_stack); add(m_box); } +bool ThreadsWindow::ListFilterFunc(Gtk::ListBoxRow *row_) { + if (auto *row = dynamic_cast(row_)) + return (m_filter_mode == FILTER_PUBLIC && (row->Type == ChannelType::GUILD_PUBLIC_THREAD || row->Type == ChannelType::GUILD_NEWS_THREAD)) || + (m_filter_mode == FILTER_PRIVATE && row->Type == ChannelType::GUILD_PRIVATE_THREAD); + return false; +} + ThreadListRow::ThreadListRow(const ChannelData &channel) : ID(channel.ID) + , Type(channel.Type) , m_label(*channel.Name, Gtk::ALIGN_START) { m_label.show(); add(m_label); } -ActiveThreadsList::ActiveThreadsList(const ChannelData &channel) { +ActiveThreadsList::ActiveThreadsList(const ChannelData &channel, const Gtk::ListBox::SlotFilter &filter) { set_vexpand(true); + m_list.set_filter_func(filter); m_list.set_selection_mode(Gtk::SELECTION_SINGLE); m_list.set_hexpand(true); m_list.show(); @@ -70,13 +103,18 @@ ActiveThreadsList::ActiveThreadsList(const ChannelData &channel) { } } +void ActiveThreadsList::InvalidateFilter() { + m_list.invalidate_filter(); +} + ActiveThreadsList::type_signal_thread_open ActiveThreadsList::signal_thread_open() { return m_signal_thread_open; } -ArchivedThreadsList::ArchivedThreadsList(const ChannelData &channel) { +ArchivedThreadsList::ArchivedThreadsList(const ChannelData &channel, const Gtk::ListBox::SlotFilter &filter) { set_vexpand(true); + m_list.set_filter_func(filter); m_list.set_selection_mode(Gtk::SELECTION_SINGLE); m_list.set_hexpand(true); m_list.show(); @@ -94,6 +132,10 @@ ArchivedThreadsList::ArchivedThreadsList(const ChannelData &channel) { Abaddon::Get().GetDiscordClient().GetArchivedPublicThreads(channel.ID, sigc::mem_fun(*this, &ArchivedThreadsList::OnPublicFetched)); } +void ArchivedThreadsList::InvalidateFilter() { + m_list.invalidate_filter(); +} + void ArchivedThreadsList::OnPublicFetched(DiscordError code, const ArchivedThreadsResponseData &data) { for (const auto &thread : data.Threads) { auto row = Gtk::manage(new ThreadListRow(thread)); diff --git a/windows/threadswindow.hpp b/windows/threadswindow.hpp index a0c77e8..28d9c7f 100644 --- a/windows/threadswindow.hpp +++ b/windows/threadswindow.hpp @@ -4,7 +4,9 @@ class ActiveThreadsList : public Gtk::ScrolledWindow { public: - ActiveThreadsList(const ChannelData &channel); + ActiveThreadsList(const ChannelData &channel, const Gtk::ListBox::SlotFilter &filter); + + void InvalidateFilter(); private: Gtk::ListBox m_list; @@ -18,7 +20,9 @@ public: class ArchivedThreadsList : public Gtk::ScrolledWindow { public: - ArchivedThreadsList(const ChannelData &channel); + ArchivedThreadsList(const ChannelData &channel, const Gtk::ListBox::SlotFilter &filter); + + void InvalidateFilter(); private: Gtk::ListBox m_list; @@ -38,11 +42,25 @@ public: ThreadsWindow(const ChannelData &channel); private: + // this filtering is rather cringe but idk what a better alternative would be + bool ListFilterFunc(Gtk::ListBoxRow *row_); + + enum FilterMode { + FILTER_PUBLIC = 0, + FILTER_PRIVATE = 1, + }; + bool m_filter_mode = FILTER_PUBLIC; + Snowflake m_channel_id; Gtk::StackSwitcher m_switcher; Gtk::Stack m_stack; + Gtk::RadioButtonGroup m_group; + Gtk::ButtonBox m_filter_buttons; + Gtk::RadioButton m_filter_public; + Gtk::RadioButton m_filter_private; + Gtk::Box m_box; ActiveThreadsList m_active; @@ -54,6 +72,7 @@ public: ThreadListRow(const ChannelData &channel); Snowflake ID; + ChannelType Type; private: Gtk::Label m_label; -- cgit v1.2.3