summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorouwou <26526779+ouwou@users.noreply.github.com>2022-04-09 02:45:09 -0400
committerouwou <26526779+ouwou@users.noreply.github.com>2022-04-09 02:45:09 -0400
commit44317e2d349acb859821691801692c87433c1b83 (patch)
treeb991824e8e7353cbb5f9f7f0122f634a8171d995
parent5b806a25894bf183515c64ac8099911da8f4a0c7 (diff)
downloadabaddon-portaudio-44317e2d349acb859821691801692c87433c1b83.tar.gz
abaddon-portaudio-44317e2d349acb859821691801692c87433c1b83.zip
more tab work
- only one tab for any channel can be open - rudimentary unread indicators - add some css
-rw-r--r--res/css/application-low-priority.css25
-rw-r--r--src/components/channeltabswitcherhandy.cpp40
-rw-r--r--src/components/channeltabswitcherhandy.hpp6
3 files changed, 71 insertions, 0 deletions
diff --git a/res/css/application-low-priority.css b/res/css/application-low-priority.css
index cf108f4..9df0fa3 100644
--- a/res/css/application-low-priority.css
+++ b/res/css/application-low-priority.css
@@ -3,6 +3,31 @@ application wide stuff
has to be separate to allow main.css to override certain things
*/
+.app-window tabbar .box {
+ margin: -7px -1px -7px -1px;
+ background: #2a2a2a;
+ border: 1px solid black;
+}
+
+.app-window tabbar tab:hover {
+ box-shadow: inset 0 -7px lighter(blue);
+}
+
+.app-window tabbar tab:checked {
+ box-shadow: inset 0 -7px blue;
+}
+
+.app-window tabbar tab {
+ background: #1A1A1A;
+ border: 1px solid #808080;
+}
+
+.app-window tabbar tab.needs-attention {
+ font-weight: bold;
+ animation: 150ms ease-in;
+ background-image: radial-gradient(ellipse at bottom, #FF5370, #1A1A1A 30%);
+}
+
.app-window label:not(:disabled) {
color: @text_color;
}
diff --git a/src/components/channeltabswitcherhandy.cpp b/src/components/channeltabswitcherhandy.cpp
index 94d5c29..f9dc6c4 100644
--- a/src/components/channeltabswitcherhandy.cpp
+++ b/src/components/channeltabswitcherhandy.cpp
@@ -10,6 +10,12 @@ void selected_page_notify_cb(HdyTabView *view, GParamSpec *pspec, ChannelTabSwit
}
}
+gboolean close_page_cb(HdyTabView *view, HdyTabPage *page, ChannelTabSwitcherHandy *switcher) {
+ switcher->ClearPage(page);
+ hdy_tab_view_close_page_finish(view, page, true);
+ return GDK_EVENT_STOP;
+}
+
ChannelTabSwitcherHandy::ChannelTabSwitcherHandy() {
m_tab_bar = hdy_tab_bar_new();
m_tab_bar_wrapped = Glib::wrap(GTK_WIDGET(m_tab_bar));
@@ -17,13 +23,25 @@ ChannelTabSwitcherHandy::ChannelTabSwitcherHandy() {
m_tab_view_wrapped = Glib::wrap(GTK_WIDGET(m_tab_view));
g_signal_connect(m_tab_view, "notify::selected-page", G_CALLBACK(selected_page_notify_cb), this);
+ g_signal_connect(m_tab_view, "close-page", G_CALLBACK(close_page_cb), this);
hdy_tab_bar_set_view(m_tab_bar, m_tab_view);
add(*m_tab_bar_wrapped);
m_tab_bar_wrapped->show();
+
+ auto &discord = Abaddon::Get().GetDiscordClient();
+ discord.signal_message_create().connect([this](const Message &data) {
+ CheckUnread(data.ChannelID);
+ });
+
+ discord.signal_message_ack().connect([this](const MessageAckData &data) {
+ CheckUnread(data.ChannelID);
+ });
}
void ChannelTabSwitcherHandy::AddChannelTab(Snowflake id) {
+ if (m_pages.find(id) != m_pages.end()) return;
+
auto &discord = Abaddon::Get().GetDiscordClient();
const auto channel = discord.GetChannel(id);
if (!channel.has_value()) return;
@@ -35,20 +53,42 @@ void ChannelTabSwitcherHandy::AddChannelTab(Snowflake id) {
m_pages[id] = page;
m_pages_rev[page] = id;
+
+ CheckUnread(id);
}
void ChannelTabSwitcherHandy::ReplaceActiveTab(Snowflake id) {
auto *page = hdy_tab_view_get_selected_page(m_tab_view);
if (page == nullptr) {
AddChannelTab(id);
+ } else if (auto it = m_pages.find(id); it != m_pages.end()) {
+ hdy_tab_view_set_selected_page(m_tab_view, it->second);
} else {
auto &discord = Abaddon::Get().GetDiscordClient();
const auto channel = discord.GetChannel(id);
if (!channel.has_value()) return;
hdy_tab_page_set_title(page, ("#" + *channel->Name).c_str());
+
+ ClearPage(page);
+ m_pages[id] = page;
m_pages_rev[page] = id;
+
+ CheckUnread(id);
+ }
+}
+
+void ChannelTabSwitcherHandy::CheckUnread(Snowflake id) {
+ if (auto it = m_pages.find(id); it != m_pages.end()) {
+ hdy_tab_page_set_needs_attention(it->second, Abaddon::Get().GetDiscordClient().GetUnreadStateForChannel(id) > -1);
+ }
+}
+
+void ChannelTabSwitcherHandy::ClearPage(HdyTabPage *page) {
+ if (auto it = m_pages_rev.find(page); it != m_pages_rev.end()) {
+ m_pages.erase(it->second);
}
+ m_pages_rev.erase(page);
}
ChannelTabSwitcherHandy::type_signal_channel_switched_to ChannelTabSwitcherHandy::signal_channel_switched_to() {
diff --git a/src/components/channeltabswitcherhandy.hpp b/src/components/channeltabswitcherhandy.hpp
index 53e1624..bc38091 100644
--- a/src/components/channeltabswitcherhandy.hpp
+++ b/src/components/channeltabswitcherhandy.hpp
@@ -12,10 +12,15 @@ class ChannelTabSwitcherHandy : public Gtk::Box {
public:
ChannelTabSwitcherHandy();
+ // no-op if already added
void AddChannelTab(Snowflake id);
+ // switches to existing tab if it exists
void ReplaceActiveTab(Snowflake id);
private:
+ void CheckUnread(Snowflake id);
+ void ClearPage(HdyTabPage *page);
+
HdyTabBar *m_tab_bar;
Gtk::Widget *m_tab_bar_wrapped;
HdyTabView *m_tab_view;
@@ -25,6 +30,7 @@ private:
std::unordered_map<HdyTabPage *, Snowflake> m_pages_rev;
friend void selected_page_notify_cb(HdyTabView *, GParamSpec *, ChannelTabSwitcherHandy *);
+ friend gboolean close_page_cb(HdyTabView *, HdyTabPage *, ChannelTabSwitcherHandy *);
public:
using type_signal_channel_switched_to = sigc::signal<void, Snowflake>;