From b4f787090c6edcdd6799dfe97e18bb79f0cb5dd2 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sat, 16 Mar 2019 02:14:53 +0100 Subject: IRCClient: Add a little "(n)" indicator to window list for unread messages. --- Applications/IRCClient/IRCAppWindow.cpp | 24 +++++++++++++++--------- Applications/IRCClient/IRCAppWindow.h | 4 +--- Applications/IRCClient/IRCChannel.cpp | 1 + Applications/IRCClient/IRCClient.cpp | 4 +++- Applications/IRCClient/IRCClient.h | 5 +++++ Applications/IRCClient/IRCQuery.cpp | 1 + Applications/IRCClient/IRCWindow.cpp | 26 ++++++++++++++++++++++++++ Applications/IRCClient/IRCWindow.h | 10 ++++++++++ Applications/IRCClient/IRCWindowListModel.cpp | 7 ++++++- 9 files changed, 68 insertions(+), 14 deletions(-) (limited to 'Applications') diff --git a/Applications/IRCClient/IRCAppWindow.cpp b/Applications/IRCClient/IRCAppWindow.cpp index 0a4e12bda5..34181fd637 100644 --- a/Applications/IRCClient/IRCAppWindow.cpp +++ b/Applications/IRCClient/IRCAppWindow.cpp @@ -12,8 +12,7 @@ #include IRCAppWindow::IRCAppWindow() - : GWindow() - , m_client("127.0.0.1", 6667) + : m_client("127.0.0.1", 6667) { set_title(String::format("IRC Client: %s@%s:%d", m_client.nickname().characters(), m_client.hostname().characters(), m_client.port())); set_rect(200, 200, 600, 400); @@ -30,9 +29,15 @@ IRCAppWindow::~IRCAppWindow() void IRCAppWindow::setup_client() { - m_client.aid_create_window = [this] (void* owner, IRCWindow::Type type, const String& name) -> IRCWindow* { + m_client.aid_create_window = [this] (void* owner, IRCWindow::Type type, const String& name) { return &create_window(owner, type, name); }; + m_client.aid_get_active_window = [this] { + return static_cast(m_container->active_widget()); + }; + m_client.aid_update_window_list = [this] { + m_window_list->model()->update(); + }; m_client.on_connect = [this] { m_client.join_channel("#test"); @@ -110,14 +115,15 @@ void IRCAppWindow::setup_widgets() auto* horizontal_container = new GWidget(widget); horizontal_container->set_layout(make(Orientation::Horizontal)); - auto* window_list = new GTableView(horizontal_container); - window_list->set_headers_visible(false); - window_list->set_alternating_row_colors(false); - window_list->set_model(OwnPtr(m_client.client_window_list_model())); - window_list->set_size_policy(SizePolicy::Fixed, SizePolicy::Fill); - window_list->set_preferred_size({ 120, 0 }); + m_window_list = new GTableView(horizontal_container); + m_window_list->set_headers_visible(false); + m_window_list->set_alternating_row_colors(false); + m_window_list->set_model(OwnPtr(m_client.client_window_list_model())); + m_window_list->set_size_policy(SizePolicy::Fixed, SizePolicy::Fill); + m_window_list->set_preferred_size({ 120, 0 }); m_client.client_window_list_model()->on_activation = [this] (IRCWindow& window) { m_container->set_active_widget(&window); + window.clear_unread_count(); }; m_container = new GStackWidget(horizontal_container); diff --git a/Applications/IRCClient/IRCAppWindow.h b/Applications/IRCClient/IRCAppWindow.h index aa97f95e7c..367c494e39 100644 --- a/Applications/IRCClient/IRCAppWindow.h +++ b/Applications/IRCClient/IRCAppWindow.h @@ -20,11 +20,9 @@ private: void setup_widgets(); IRCWindow& create_window(void* owner, IRCWindow::Type, const String& name); - IRCClient m_client; - GStackWidget* m_container { nullptr }; - + GTableView* m_window_list { nullptr }; RetainPtr m_join_action; RetainPtr m_part_action; RetainPtr m_whois_action; diff --git a/Applications/IRCClient/IRCChannel.cpp b/Applications/IRCClient/IRCChannel.cpp index 4e2d68d444..384cd018db 100644 --- a/Applications/IRCClient/IRCChannel.cpp +++ b/Applications/IRCClient/IRCChannel.cpp @@ -37,6 +37,7 @@ void IRCChannel::add_member(const String& name, char prefix) void IRCChannel::add_message(char prefix, const String& name, const String& text) { + window().did_add_message(); log().add_message(prefix, name, text); dump(); } diff --git a/Applications/IRCClient/IRCClient.cpp b/Applications/IRCClient/IRCClient.cpp index d8b6f63b76..40d394d075 100644 --- a/Applications/IRCClient/IRCClient.cpp +++ b/Applications/IRCClient/IRCClient.cpp @@ -237,8 +237,10 @@ void IRCClient::handle(const Message& msg, const String&) if (msg.command == "PRIVMSG") return handle_privmsg(msg); - if (msg.arguments.size() >= 2) + if (msg.arguments.size() >= 2) { m_log->add_message(0, "Server", String::format("[%s] %s", msg.command.characters(), msg.arguments[1].characters())); + m_server_subwindow->did_add_message(); + } } void IRCClient::send_privmsg(const String& target, const String& text) diff --git a/Applications/IRCClient/IRCClient.h b/Applications/IRCClient/IRCClient.h index 87a3935387..eb3ac55b35 100644 --- a/Applications/IRCClient/IRCClient.h +++ b/Applications/IRCClient/IRCClient.h @@ -30,11 +30,16 @@ public: bool is_nick_prefix(char) const; + IRCWindow* current_window() { return aid_get_active_window(); } + const IRCWindow* current_window() const { return aid_get_active_window(); } + Function on_connect; Function on_disconnect; Function on_server_message; Function aid_create_window; + Function aid_get_active_window; + Function aid_update_window_list; void register_subwindow(IRCWindow&); void unregister_subwindow(IRCWindow&); diff --git a/Applications/IRCClient/IRCQuery.cpp b/Applications/IRCClient/IRCQuery.cpp index 4a539fa42b..932a07b250 100644 --- a/Applications/IRCClient/IRCQuery.cpp +++ b/Applications/IRCClient/IRCQuery.cpp @@ -29,6 +29,7 @@ void IRCQuery::dump() const void IRCQuery::add_message(char prefix, const String& name, const String& text) { + window().did_add_message(); log().add_message(prefix, name, text); dump(); } diff --git a/Applications/IRCClient/IRCWindow.cpp b/Applications/IRCClient/IRCWindow.cpp index e4540986b8..b94fee665f 100644 --- a/Applications/IRCClient/IRCWindow.cpp +++ b/Applications/IRCClient/IRCWindow.cpp @@ -61,3 +61,29 @@ void IRCWindow::set_log_buffer(const IRCLogBuffer& log_buffer) m_log_buffer = &log_buffer; m_table_view->set_model(OwnPtr((IRCLogBufferModel*)log_buffer.model())); } + +bool IRCWindow::is_active() const +{ + return m_client.current_window() == this; +} + +void IRCWindow::did_add_message() +{ + if (!is_active()) { + ++m_unread_count; + m_client.aid_update_window_list(); + } +} + +void IRCWindow::clear_unread_count() +{ + if (!m_unread_count) + return; + m_unread_count = 0; + m_client.aid_update_window_list(); +} + +int IRCWindow::unread_count() const +{ + return m_unread_count; +} diff --git a/Applications/IRCClient/IRCWindow.h b/Applications/IRCClient/IRCWindow.h index b727048e6b..2fce542fe5 100644 --- a/Applications/IRCClient/IRCWindow.h +++ b/Applications/IRCClient/IRCWindow.h @@ -27,6 +27,13 @@ public: void set_log_buffer(const IRCLogBuffer&); + bool is_active() const; + + int unread_count() const; + void clear_unread_count(); + + void did_add_message(); + IRCChannel& channel() { return *(IRCChannel*)m_owner; } const IRCChannel& channel() const { return *(const IRCChannel*)m_owner; } @@ -34,6 +41,8 @@ public: const IRCQuery& query() const { return *(const IRCQuery*)m_owner; } private: + const char* class_name() const override { return "IRCWindow"; } + IRCClient& m_client; void* m_owner { nullptr }; Type m_type; @@ -41,4 +50,5 @@ private: GTableView* m_table_view { nullptr }; GTextEditor* m_text_editor { nullptr }; RetainPtr m_log_buffer; + int m_unread_count { 0 }; }; diff --git a/Applications/IRCClient/IRCWindowListModel.cpp b/Applications/IRCClient/IRCWindowListModel.cpp index b6cf241ba5..b6aa3239a8 100644 --- a/Applications/IRCClient/IRCWindowListModel.cpp +++ b/Applications/IRCClient/IRCWindowListModel.cpp @@ -43,7 +43,12 @@ GTableModel::ColumnMetadata IRCWindowListModel::column_metadata(int column) cons GVariant IRCWindowListModel::data(const GModelIndex& index, Role) const { switch (index.column()) { - case Column::Name: return m_client.window_at(index.row()).name(); + case Column::Name: { + auto& window = m_client.window_at(index.row()); + if (!window.unread_count()) + return window.name(); + return String::format("%s (%d)\n", window.name().characters(), window.unread_count()); + } } ASSERT_NOT_REACHED(); } -- cgit v1.2.3