summaryrefslogtreecommitdiff
path: root/src/components
diff options
context:
space:
mode:
authorouwou <26526779+ouwou@users.noreply.github.com>2024-07-05 03:51:58 -0400
committerGitHub <noreply@github.com>2024-07-05 03:51:58 -0400
commit68db143c8939e12dd569d6ac737213ad856c139b (patch)
treed5e814329fb19912b69b9804fc68b852674d8277 /src/components
parente6191d95341d164eacaf91739c8aa7020dd5c9b6 (diff)
parentb19782c16dffd38ac5651641131a48f8ff961b32 (diff)
downloadabaddon-portaudio-68db143c8939e12dd569d6ac737213ad856c139b.tar.gz
abaddon-portaudio-68db143c8939e12dd569d6ac737213ad856c139b.zip
Merge pull request #279 from uowuo/stages
Support for stages
Diffstat (limited to 'src/components')
-rw-r--r--src/components/channellist/cellrendererchannels.cpp12
-rw-r--r--src/components/channellist/cellrendererchannels.hpp6
-rw-r--r--src/components/channellist/channellisttree.cpp57
-rw-r--r--src/components/channellist/channellisttree.hpp5
4 files changed, 71 insertions, 9 deletions
diff --git a/src/components/channellist/cellrendererchannels.cpp b/src/components/channellist/cellrendererchannels.cpp
index 8a6097e..af9109a 100644
--- a/src/components/channellist/cellrendererchannels.cpp
+++ b/src/components/channellist/cellrendererchannels.cpp
@@ -123,6 +123,7 @@ void CellRendererChannels::get_preferred_width_vfunc(Gtk::Widget &widget, int &m
case RenderType::Thread:
return get_preferred_width_vfunc_thread(widget, minimum_width, natural_width);
case RenderType::VoiceChannel:
+ case RenderType::VoiceStage:
return get_preferred_width_vfunc_voice_channel(widget, minimum_width, natural_width);
case RenderType::VoiceParticipant:
return get_preferred_width_vfunc_voice_participant(widget, minimum_width, natural_width);
@@ -146,6 +147,7 @@ void CellRendererChannels::get_preferred_width_for_height_vfunc(Gtk::Widget &wid
case RenderType::Thread:
return get_preferred_width_for_height_vfunc_thread(widget, height, minimum_width, natural_width);
case RenderType::VoiceChannel:
+ case RenderType::VoiceStage:
return get_preferred_width_for_height_vfunc_voice_channel(widget, height, minimum_width, natural_width);
case RenderType::VoiceParticipant:
return get_preferred_width_for_height_vfunc_voice_participant(widget, height, minimum_width, natural_width);
@@ -169,6 +171,7 @@ void CellRendererChannels::get_preferred_height_vfunc(Gtk::Widget &widget, int &
case RenderType::Thread:
return get_preferred_height_vfunc_thread(widget, minimum_height, natural_height);
case RenderType::VoiceChannel:
+ case RenderType::VoiceStage:
return get_preferred_height_vfunc_voice_channel(widget, minimum_height, natural_height);
case RenderType::VoiceParticipant:
return get_preferred_height_vfunc_voice_participant(widget, minimum_height, natural_height);
@@ -192,6 +195,7 @@ void CellRendererChannels::get_preferred_height_for_width_vfunc(Gtk::Widget &wid
case RenderType::Thread:
return get_preferred_height_for_width_vfunc_thread(widget, width, minimum_height, natural_height);
case RenderType::VoiceChannel:
+ case RenderType::VoiceStage:
return get_preferred_height_for_width_vfunc_voice_channel(widget, width, minimum_height, natural_height);
case RenderType::VoiceParticipant:
return get_preferred_height_for_width_vfunc_voice_participant(widget, width, minimum_height, natural_height);
@@ -215,7 +219,9 @@ void CellRendererChannels::render_vfunc(const Cairo::RefPtr<Cairo::Context> &cr,
case RenderType::Thread:
return render_vfunc_thread(cr, widget, background_area, cell_area, flags);
case RenderType::VoiceChannel:
- return render_vfunc_voice_channel(cr, widget, background_area, cell_area, flags);
+ return render_vfunc_voice_channel(cr, widget, background_area, cell_area, flags, "\U0001F50A");
+ case RenderType::VoiceStage:
+ return render_vfunc_voice_channel(cr, widget, background_area, cell_area, flags, "\U0001F4E1");
case RenderType::VoiceParticipant:
return render_vfunc_voice_participant(cr, widget, background_area, cell_area, flags);
case RenderType::DMHeader:
@@ -571,7 +577,7 @@ void CellRendererChannels::get_preferred_height_for_width_vfunc_voice_channel(Gt
m_renderer_text.get_preferred_height_for_width(widget, width, minimum_height, natural_height);
}
-void CellRendererChannels::render_vfunc_voice_channel(const Cairo::RefPtr<Cairo::Context> &cr, Gtk::Widget &widget, const Gdk::Rectangle &background_area, const Gdk::Rectangle &cell_area, Gtk::CellRendererState flags) {
+void CellRendererChannels::render_vfunc_voice_channel(const Cairo::RefPtr<Cairo::Context> &cr, Gtk::Widget &widget, const Gdk::Rectangle &background_area, const Gdk::Rectangle &cell_area, Gtk::CellRendererState flags, const char *emoji) {
// channel name text
Gtk::Requisition minimum_size, natural_size;
m_renderer_text.get_preferred_size(widget, minimum_size, natural_size);
@@ -588,7 +594,7 @@ void CellRendererChannels::render_vfunc_voice_channel(const Cairo::RefPtr<Cairo:
Pango::FontDescription font;
font.set_family("sans 14");
- auto layout = widget.create_pango_layout("\U0001F50A");
+ auto layout = widget.create_pango_layout(emoji);
layout->set_font_description(font);
layout->set_alignment(Pango::ALIGN_LEFT);
cr->set_source_rgba(1.0, 1.0, 1.0, 1.0);
diff --git a/src/components/channellist/cellrendererchannels.hpp b/src/components/channellist/cellrendererchannels.hpp
index ebe4957..7059c6f 100644
--- a/src/components/channellist/cellrendererchannels.hpp
+++ b/src/components/channellist/cellrendererchannels.hpp
@@ -6,7 +6,7 @@
#include <gtkmm/cellrendererpixbuf.h>
#include <gtkmm/cellrenderertext.h>
#include "discord/snowflake.hpp"
-#include "discord/voicestateflags.hpp"
+#include "discord/voicestate.hpp"
#include "misc/bitwise.hpp"
enum class RenderType : uint8_t {
@@ -16,6 +16,7 @@ enum class RenderType : uint8_t {
TextChannel,
Thread,
VoiceChannel,
+ VoiceStage, // identical to non-stage except for icon
VoiceParticipant,
DMHeader,
@@ -112,7 +113,8 @@ protected:
Gtk::Widget &widget,
const Gdk::Rectangle &background_area,
const Gdk::Rectangle &cell_area,
- Gtk::CellRendererState flags);
+ Gtk::CellRendererState flags,
+ const char *emoji);
// voice participant
void get_preferred_width_vfunc_voice_participant(Gtk::Widget &widget, int &minimum_width, int &natural_width) const;
diff --git a/src/components/channellist/channellisttree.cpp b/src/components/channellist/channellisttree.cpp
index d673060..e824933 100644
--- a/src/components/channellist/channellisttree.cpp
+++ b/src/components/channellist/channellisttree.cpp
@@ -28,6 +28,8 @@ ChannelListTree::ChannelListTree()
#endif
, m_menu_voice_channel_join("_Join", true)
, m_menu_voice_channel_disconnect("_Disconnect", true)
+ , m_menu_voice_stage_join("_Join", true)
+ , m_menu_voice_stage_disconnect("_Disconnect", true)
, m_menu_voice_channel_mark_as_read("Mark as _Read", true)
, m_menu_voice_open_chat("Open _Chat", true)
, m_menu_dm_copy_id("_Copy ID", true)
@@ -225,6 +227,21 @@ ChannelListTree::ChannelListTree()
m_menu_voice_channel.append(m_menu_voice_open_chat);
m_menu_voice_channel.show_all();
+#ifdef WITH_VOICE
+ m_menu_voice_stage_join.signal_activate().connect([this]() {
+ const auto id = static_cast<Snowflake>((*m_model->get_iter(m_path_for_menu))[m_columns.m_id]);
+ m_signal_action_join_voice_channel.emit(id);
+ });
+
+ m_menu_voice_stage_disconnect.signal_activate().connect([this]() {
+ m_signal_action_disconnect_voice.emit();
+ });
+#endif
+
+ m_menu_voice_stage.append(m_menu_voice_stage_join);
+ m_menu_voice_stage.append(m_menu_voice_stage_disconnect);
+ m_menu_voice_stage.show_all();
+
m_menu_dm_copy_id.signal_activate().connect([this] {
Gtk::Clipboard::get()->set_text(std::to_string((*m_model->get_iter(m_path_for_menu))[m_columns.m_id]));
});
@@ -366,8 +383,8 @@ int ChannelListTree::SortFunc(const Gtk::TreeModel::iterator &a, const Gtk::Tree
const int64_t b_sort = (*b)[m_columns.m_sort];
if (a_type == RenderType::DMHeader) return -1;
if (b_type == RenderType::DMHeader) return 1;
- if (a_type == RenderType::TextChannel && b_type == RenderType::VoiceChannel) return -1;
- if (b_type == RenderType::TextChannel && a_type == RenderType::VoiceChannel) return 1;
+ if (a_type == RenderType::TextChannel && (b_type == RenderType::VoiceChannel || b_type == RenderType::VoiceStage)) return -1;
+ if (b_type == RenderType::TextChannel && (a_type == RenderType::VoiceChannel || a_type == RenderType::VoiceStage)) return 1;
return static_cast<int>(std::clamp(a_sort - b_sort, int64_t(-1), int64_t(1)));
}
@@ -634,6 +651,7 @@ void ChannelListTree::OnThreadListSync(const ThreadListSyncData &data) {
void ChannelListTree::OnVoiceUserConnect(Snowflake user_id, Snowflake channel_id) {
auto parent_iter = GetIteratorForRowFromIDOfType(channel_id, RenderType::VoiceChannel);
+ if (!parent_iter) parent_iter = GetIteratorForRowFromIDOfType(channel_id, RenderType::VoiceStage);
if (!parent_iter) parent_iter = GetIteratorForRowFromIDOfType(channel_id, RenderType::DM);
if (!parent_iter) return;
const auto user = Abaddon::Get().GetDiscordClient().GetUser(user_id);
@@ -914,7 +932,7 @@ Gtk::TreeModel::iterator ChannelListTree::AddGuild(const GuildData &guild, const
for (const auto &channel_ : *guild.Channels) {
const auto channel = discord.GetChannel(channel_.ID);
if (!channel.has_value()) continue;
- if (channel->Type == ChannelType::GUILD_TEXT || channel->Type == ChannelType::GUILD_NEWS || channel->Type == ChannelType::GUILD_VOICE) {
+ if (channel->Type == ChannelType::GUILD_TEXT || channel->Type == ChannelType::GUILD_NEWS || channel->Type == ChannelType::GUILD_VOICE || channel->Type == ChannelType::GUILD_STAGE_VOICE) {
if (channel->ParentID.has_value())
categories[*channel->ParentID].push_back(*channel);
else
@@ -954,6 +972,10 @@ Gtk::TreeModel::iterator ChannelListTree::AddGuild(const GuildData &guild, const
if (IsTextChannel(channel.Type)) {
channel_row[m_columns.m_type] = RenderType::TextChannel;
channel_row[m_columns.m_name] = "#" + Glib::Markup::escape_text(*channel.Name);
+ } else if (channel.Type == ChannelType::GUILD_STAGE_VOICE) {
+ channel_row[m_columns.m_type] = RenderType::VoiceStage;
+ channel_row[m_columns.m_name] = Glib::Markup::escape_text(*channel.Name);
+ add_voice_participants(channel, channel_row->children());
} else {
channel_row[m_columns.m_type] = RenderType::VoiceChannel;
channel_row[m_columns.m_name] = Glib::Markup::escape_text(*channel.Name);
@@ -983,6 +1005,10 @@ Gtk::TreeModel::iterator ChannelListTree::AddGuild(const GuildData &guild, const
if (IsTextChannel(channel.Type)) {
channel_row[m_columns.m_type] = RenderType::TextChannel;
channel_row[m_columns.m_name] = "#" + Glib::Markup::escape_text(*channel.Name);
+ } else if (channel.Type == ChannelType::GUILD_STAGE_VOICE) {
+ channel_row[m_columns.m_type] = RenderType::VoiceStage;
+ channel_row[m_columns.m_name] = Glib::Markup::escape_text(*channel.Name);
+ add_voice_participants(channel, channel_row->children());
} else {
channel_row[m_columns.m_type] = RenderType::VoiceChannel;
channel_row[m_columns.m_name] = Glib::Markup::escape_text(*channel.Name);
@@ -1033,7 +1059,7 @@ Gtk::TreeModel::iterator ChannelListTree::CreateVoiceParticipantRow(const UserDa
const auto voice_state = Abaddon::Get().GetDiscordClient().GetVoiceState(user.ID);
if (voice_state.has_value()) {
- row[m_columns.m_voice_flags] = voice_state->second;
+ row[m_columns.m_voice_flags] = voice_state->second.Flags;
}
auto &img = Abaddon::Get().GetImageManager();
@@ -1331,6 +1357,10 @@ bool ChannelListTree::OnButtonPressEvent(GdkEventButton *ev) {
OnVoiceChannelSubmenuPopup();
m_menu_voice_channel.popup_at_pointer(reinterpret_cast<GdkEvent *>(ev));
break;
+ case RenderType::VoiceStage:
+ OnVoiceStageSubmenuPopup();
+ m_menu_voice_stage.popup_at_pointer(reinterpret_cast<GdkEvent *>(ev));
+ break;
case RenderType::DM: {
OnDMSubmenuPopup();
const auto channel = Abaddon::Get().GetDiscordClient().GetChannel(static_cast<Snowflake>(row[m_columns.m_id]));
@@ -1442,6 +1472,25 @@ void ChannelListTree::OnVoiceChannelSubmenuPopup() {
#endif
}
+void ChannelListTree::OnVoiceStageSubmenuPopup() {
+#ifdef WITH_VOICE
+ const auto iter = m_model->get_iter(m_path_for_menu);
+ if (!iter) return;
+ const auto id = static_cast<Snowflake>((*iter)[m_columns.m_id]);
+ auto &discord = Abaddon::Get().GetDiscordClient();
+ if (discord.IsVoiceConnected() || discord.IsVoiceConnecting()) {
+ m_menu_voice_stage_join.set_sensitive(false);
+ m_menu_voice_stage_disconnect.set_sensitive(discord.GetVoiceChannelID() == id);
+ } else {
+ m_menu_voice_stage_join.set_sensitive(true);
+ m_menu_voice_stage_disconnect.set_sensitive(false);
+ }
+#else
+ m_menu_voice_stage_join.set_sensitive(false);
+ m_menu_voice_stage_disconnect.set_sensitive(false);
+#endif
+}
+
void ChannelListTree::OnDMSubmenuPopup() {
auto iter = m_model->get_iter(m_path_for_menu);
if (!iter) return;
diff --git a/src/components/channellist/channellisttree.hpp b/src/components/channellist/channellisttree.hpp
index 9e2c544..323f843 100644
--- a/src/components/channellist/channellisttree.hpp
+++ b/src/components/channellist/channellisttree.hpp
@@ -162,6 +162,10 @@ protected:
Gtk::Menu m_menu_voice_channel;
Gtk::MenuItem m_menu_voice_channel_join;
Gtk::MenuItem m_menu_voice_channel_disconnect;
+
+ Gtk::Menu m_menu_voice_stage;
+ Gtk::MenuItem m_menu_voice_stage_join;
+ Gtk::MenuItem m_menu_voice_stage_disconnect;
Gtk::MenuItem m_menu_voice_channel_mark_as_read;
Gtk::MenuItem m_menu_voice_open_chat;
@@ -192,6 +196,7 @@ protected:
void OnDMSubmenuPopup();
void OnThreadSubmenuPopup();
void OnVoiceChannelSubmenuPopup();
+ void OnVoiceStageSubmenuPopup();
bool m_updating_listing = false;