diff options
-rw-r--r-- | res/css/application-low-priority.css | 25 | ||||
-rw-r--r-- | src/components/channeltabswitcherhandy.cpp | 40 | ||||
-rw-r--r-- | src/components/channeltabswitcherhandy.hpp | 6 |
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>; |