diff options
author | ouwou <26526779+ouwou@users.noreply.github.com> | 2023-05-19 20:20:33 -0400 |
---|---|---|
committer | ouwou <26526779+ouwou@users.noreply.github.com> | 2023-05-19 20:20:33 -0400 |
commit | 3e67e8a7aeb265914d538314b17f36a988017081 (patch) | |
tree | 42e6830f3bf9c7bacde92d75be961c591ef2732a /src/components | |
parent | 0a1138fbd025da2c3f28cec73f823d9274ebc4db (diff) | |
download | abaddon-portaudio-3e67e8a7aeb265914d538314b17f36a988017081.tar.gz abaddon-portaudio-3e67e8a7aeb265914d538314b17f36a988017081.zip |
add voice state icons to participant rows
Diffstat (limited to 'src/components')
-rw-r--r-- | src/components/channels.cpp | 14 | ||||
-rw-r--r-- | src/components/channels.hpp | 2 | ||||
-rw-r--r-- | src/components/channelscellrenderer.cpp | 52 | ||||
-rw-r--r-- | src/components/channelscellrenderer.hpp | 7 |
4 files changed, 73 insertions, 2 deletions
diff --git a/src/components/channels.cpp b/src/components/channels.cpp index 5e3da86..0e97837 100644 --- a/src/components/channels.cpp +++ b/src/components/channels.cpp @@ -96,6 +96,7 @@ ChannelList::ChannelList() 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); + column->add_attribute(renderer->property_voice_state(), m_columns.m_voice_flags); m_view.append_column(*column); m_menu_guild_copy_id.signal_activate().connect([this] { @@ -282,6 +283,7 @@ ChannelList::ChannelList() #if WITH_VOICE discord.signal_voice_user_connect().connect(sigc::mem_fun(*this, &ChannelList::OnVoiceUserConnect)); discord.signal_voice_user_disconnect().connect(sigc::mem_fun(*this, &ChannelList::OnVoiceUserDisconnect)); + discord.signal_voice_state_set().connect(sigc::mem_fun(*this, &ChannelList::OnVoiceStateSet)); #endif } @@ -537,6 +539,12 @@ void ChannelList::OnVoiceUserDisconnect(Snowflake user_id, Snowflake channel_id) m_model->erase(iter); } } + +void ChannelList::OnVoiceStateSet(Snowflake user_id, Snowflake channel_id, VoiceStateFlags flags) { + if (auto iter = GetIteratorForRowFromIDOfType(user_id, RenderType::VoiceParticipant)) { + (*iter)[m_columns.m_voice_flags] = flags; + } +} #endif void ChannelList::DeleteThreadRow(Snowflake id) { @@ -857,6 +865,11 @@ Gtk::TreeModel::iterator ChannelList::CreateVoiceParticipantRow(const UserData & row[m_columns.m_id] = user.ID; row[m_columns.m_name] = user.GetEscapedName(); + const auto voice_state = Abaddon::Get().GetDiscordClient().GetVoiceState(user.ID); + if (voice_state.has_value()) { + row[m_columns.m_voice_flags] = voice_state->second; + } + auto &img = Abaddon::Get().GetImageManager(); row[m_columns.m_icon] = img.GetPlaceholder(VoiceParticipantIconSize); const auto cb = [this, user_id = user.ID](const Glib::RefPtr<Gdk::Pixbuf> &pb) { @@ -1283,4 +1296,5 @@ ChannelList::ModelColumns::ModelColumns() { add(m_nsfw); add(m_expanded); add(m_color); + add(m_voice_flags); } diff --git a/src/components/channels.hpp b/src/components/channels.hpp index 2ad1a7c..7a23b3d 100644 --- a/src/components/channels.hpp +++ b/src/components/channels.hpp @@ -55,6 +55,7 @@ protected: void OnVoiceUserConnect(Snowflake user_id, Snowflake channel_id); void OnVoiceUserDisconnect(Snowflake user_id, Snowflake channel_id); + void OnVoiceStateSet(Snowflake user_id, Snowflake channel_id, VoiceStateFlags flags); Gtk::TreeView m_view; @@ -70,6 +71,7 @@ protected: Gtk::TreeModelColumn<int64_t> m_sort; Gtk::TreeModelColumn<bool> m_nsfw; Gtk::TreeModelColumn<std::optional<Gdk::RGBA>> m_color; // for folders right now + Gtk::TreeModelColumn<VoiceStateFlags> m_voice_flags; // 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 diff --git a/src/components/channelscellrenderer.cpp b/src/components/channelscellrenderer.cpp index ab3113c..6de7a00 100644 --- a/src/components/channelscellrenderer.cpp +++ b/src/components/channelscellrenderer.cpp @@ -17,7 +17,8 @@ CellRendererChannels::CellRendererChannels() , m_property_pixbuf_animation(*this, "pixbuf-animation") , m_property_expanded(*this, "expanded") , m_property_nsfw(*this, "nsfw") - , m_property_color(*this, "color") { + , m_property_color(*this, "color") + , m_property_voice_state(*this, "voice-state") { property_mode() = Gtk::CELL_RENDERER_MODE_ACTIVATABLE; property_xpad() = 2; property_ypad() = 2; @@ -58,6 +59,10 @@ Glib::PropertyProxy<std::optional<Gdk::RGBA>> CellRendererChannels::property_col return m_property_color.get_proxy(); } +Glib::PropertyProxy<VoiceStateFlags> CellRendererChannels::property_voice_state() { + return m_property_voice_state.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: @@ -733,6 +738,51 @@ void CellRendererChannels::render_vfunc_voice_participant(const Cairo::RefPtr<Ca cr->rectangle(icon_x, icon_y, icon_w, icon_h); cr->fill(); } + + auto *paned = dynamic_cast<Gtk::Paned *>(widget.get_ancestor(Gtk::Paned::get_type())); + if (paned != nullptr) { + const auto edge = std::min(paned->get_position(), background_area.get_width()); + + const static std::array<std::pair<VoiceStateFlags, Glib::ustring>, 3> icon_order = { { + { VoiceStateFlags::SelfMute | VoiceStateFlags::Mute, "microphone-disabled-symbolic" }, + { VoiceStateFlags::SelfDeaf | VoiceStateFlags::Deaf, "audio-volume-muted-symbolic" }, + { VoiceStateFlags::SelfVideo, "camera-web-symbolic" }, + } }; + + constexpr static int IconSize = 18; + constexpr static int IconPad = 2; + + const VoiceStateFlags voice_flags = m_property_voice_state.get_value(); + + int offset = 0; + for (auto iter = icon_order.rbegin(); iter != icon_order.rend(); iter++) { + const auto &[flag, icon] = *iter; + if ((voice_flags & flag) == VoiceStateFlags::Clear) continue; + + const double icon_w = 18; + const double icon_h = 18; + const double icon_x = background_area.get_x() + edge - icon_w + offset; + const double icon_y = background_area.get_y() + background_area.get_height() / 2 - icon_h / 2; + Gdk::Rectangle icon_cell_area(icon_x, icon_y, icon_w, icon_h); + + offset -= (IconSize + IconPad); + + const bool is_server_mute = (voice_flags & VoiceStateFlags::Mute) == VoiceStateFlags::Mute; + const bool is_server_deaf = (voice_flags & VoiceStateFlags::Deaf) == VoiceStateFlags::Deaf; + auto context = widget.get_style_context(); + if (is_server_mute || is_server_deaf) { + context->context_save(); + context->add_class("voice-state-server"); + } + + m_renderer_pixbuf.property_icon_name() = icon; + m_renderer_pixbuf.render(cr, widget, background_area, icon_cell_area, flags); + + if (is_server_mute || is_server_deaf) { + context->context_restore(); + } + } + } } #endif diff --git a/src/components/channelscellrenderer.hpp b/src/components/channelscellrenderer.hpp index f6859dc..934ce5b 100644 --- a/src/components/channelscellrenderer.hpp +++ b/src/components/channelscellrenderer.hpp @@ -3,6 +3,8 @@ #include <glibmm/property.h> #include <map> #include "discord/snowflake.hpp" +#include "discord/voicestateflags.hpp" +#include "misc/bitwise.hpp" enum class RenderType : uint8_t { Folder, @@ -34,6 +36,7 @@ public: Glib::PropertyProxy<bool> property_expanded(); Glib::PropertyProxy<bool> property_nsfw(); Glib::PropertyProxy<std::optional<Gdk::RGBA>> property_color(); + Glib::PropertyProxy<VoiceStateFlags> property_voice_state(); protected: void get_preferred_width_vfunc(Gtk::Widget &widget, int &minimum_width, int &natural_width) const override; @@ -113,7 +116,7 @@ protected: const Gdk::Rectangle &cell_area, Gtk::CellRendererState flags); - // voice channel + // voice participant void get_preferred_width_vfunc_voice_participant(Gtk::Widget &widget, int &minimum_width, int &natural_width) const; void get_preferred_width_for_height_vfunc_voice_participant(Gtk::Widget &widget, int height, int &minimum_width, int &natural_width) const; void get_preferred_height_vfunc_voice_participant(Gtk::Widget &widget, int &minimum_height, int &natural_height) const; @@ -152,6 +155,7 @@ protected: private: Gtk::CellRendererText m_renderer_text; + Gtk::CellRendererPixbuf m_renderer_pixbuf; Glib::Property<RenderType> m_property_type; // all Glib::Property<Glib::ustring> m_property_name; // all @@ -161,6 +165,7 @@ private: Glib::Property<bool> m_property_expanded; // category Glib::Property<bool> m_property_nsfw; // channel Glib::Property<std::optional<Gdk::RGBA>> m_property_color; // folder + Glib::Property<VoiceStateFlags> m_property_voice_state; // 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 |