1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-24 14:27:35 +00:00

IRCClient: Refactor window creation responsibilities.

IRCChannel and IRCQuery objects now create their own windows with the
help of an aid_create_window callback provided by IRCAppWindow.

There's still a bit of murk but this is already an improvement.
This commit is contained in:
Andreas Kling 2019-03-16 01:45:49 +01:00
parent fc7f700c20
commit 1394677528
10 changed files with 40 additions and 48 deletions

View file

@ -17,10 +17,11 @@ IRCAppWindow::IRCAppWindow()
{ {
set_title(String::format("IRC Client: %s@%s:%d", m_client.nickname().characters(), m_client.hostname().characters(), m_client.port())); 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); set_rect(200, 200, 600, 400);
setup_client();
setup_actions(); setup_actions();
setup_menus(); setup_menus();
setup_widgets(); setup_widgets();
setup_client();
} }
IRCAppWindow::~IRCAppWindow() IRCAppWindow::~IRCAppWindow()
@ -29,22 +30,14 @@ IRCAppWindow::~IRCAppWindow()
void IRCAppWindow::setup_client() void IRCAppWindow::setup_client()
{ {
m_client.aid_create_window = [this] (void* owner, IRCWindow::Type type, const String& name) -> IRCWindow* {
return &create_window(owner, type, name);
};
m_client.on_connect = [this] { m_client.on_connect = [this] {
m_client.join_channel("#test"); m_client.join_channel("#test");
}; };
m_client.on_channel_message = [this] (const String& channel_name) {
ensure_window(IRCWindow::Channel, channel_name);
};
m_client.on_join = [this] (const String& channel_name) {
ensure_window(IRCWindow::Channel, channel_name);
};
m_client.on_query_message = [this] (const String& name) {
ensure_window(IRCWindow::Query, name);
};
m_client.connect(); m_client.connect();
} }
@ -129,20 +122,10 @@ void IRCAppWindow::setup_widgets()
m_container = new GStackWidget(horizontal_container); m_container = new GStackWidget(horizontal_container);
create_subwindow(IRCWindow::Server, "Server"); create_window(&m_client, IRCWindow::Server, "Server");
} }
IRCWindow& IRCAppWindow::create_subwindow(IRCWindow::Type type, const String& name) IRCWindow& IRCAppWindow::create_window(void* owner, IRCWindow::Type type, const String& name)
{ {
return *new IRCWindow(m_client, type, name, m_container); return *new IRCWindow(m_client, owner, type, name, m_container);
}
IRCWindow& IRCAppWindow::ensure_window(IRCWindow::Type type, const String& name)
{
for (int i = 0; i < m_client.window_count(); ++i) {
auto& window = m_client.window_at(i);
if (window.name() == name)
return window;
}
return create_subwindow(type, name);
} }

View file

@ -19,8 +19,7 @@ private:
void setup_menus(); void setup_menus();
void setup_widgets(); void setup_widgets();
IRCWindow& create_subwindow(IRCWindow::Type, const String& name); IRCWindow& create_window(void* owner, IRCWindow::Type, const String& name);
IRCWindow& ensure_window(IRCWindow::Type, const String& name);
IRCClient m_client; IRCClient m_client;

View file

@ -10,6 +10,8 @@ IRCChannel::IRCChannel(IRCClient& client, const String& name)
, m_log(IRCLogBuffer::create()) , m_log(IRCLogBuffer::create())
{ {
m_member_model = new IRCChannelMemberListModel(*this); m_member_model = new IRCChannelMemberListModel(*this);
m_window = m_client.aid_create_window(this, IRCWindow::Channel, m_name);
m_window->set_log_buffer(*m_log);
} }
IRCChannel::~IRCChannel() IRCChannel::~IRCChannel()

View file

@ -9,6 +9,7 @@
class IRCClient; class IRCClient;
class IRCChannelMemberListModel; class IRCChannelMemberListModel;
class IRCWindow;
class IRCChannel : public Retainable<IRCChannel> { class IRCChannel : public Retainable<IRCChannel> {
public: public:
@ -38,6 +39,9 @@ public:
int member_count() const { return m_members.size(); } int member_count() const { return m_members.size(); }
String member_at(int i) { return m_members[i].name; } String member_at(int i) { return m_members[i].name; }
IRCWindow& window() { return *m_window; }
const IRCWindow& window() const { return *m_window; }
private: private:
IRCChannel(IRCClient&, const String&); IRCChannel(IRCClient&, const String&);
@ -52,4 +56,5 @@ private:
Retained<IRCLogBuffer> m_log; Retained<IRCLogBuffer> m_log;
IRCChannelMemberListModel* m_member_model { nullptr }; IRCChannelMemberListModel* m_member_model { nullptr };
IRCWindow* m_window { nullptr };
}; };

View file

@ -306,15 +306,11 @@ void IRCClient::handle_privmsg(const Message& msg)
auto it = m_channels.find(target); auto it = m_channels.find(target);
if (it != m_channels.end()) { if (it != m_channels.end()) {
(*it).value->add_message(sender_prefix, sender_nick, msg.arguments[1]); (*it).value->add_message(sender_prefix, sender_nick, msg.arguments[1]);
if (on_channel_message)
on_channel_message(target);
return; return;
} }
} }
auto& query = ensure_query(sender_nick); auto& query = ensure_query(sender_nick);
query.add_message(sender_prefix, sender_nick, msg.arguments[1]); query.add_message(sender_prefix, sender_nick, msg.arguments[1]);
if (on_query_message)
on_query_message(sender_nick);
} }
IRCQuery& IRCClient::ensure_query(const String& name) IRCQuery& IRCClient::ensure_query(const String& name)
@ -353,8 +349,6 @@ void IRCClient::handle_join(const Message& msg)
return; return;
auto& channel_name = msg.arguments[0]; auto& channel_name = msg.arguments[0];
ensure_channel(channel_name); ensure_channel(channel_name);
if (on_join)
on_join(channel_name);
} }
void IRCClient::handle_namreply(const Message& msg) void IRCClient::handle_namreply(const Message& msg)
@ -389,13 +383,6 @@ void IRCClient::register_subwindow(IRCWindow& subwindow)
if (subwindow.type() == IRCWindow::Server) { if (subwindow.type() == IRCWindow::Server) {
m_server_subwindow = &subwindow; m_server_subwindow = &subwindow;
subwindow.set_log_buffer(*m_log); subwindow.set_log_buffer(*m_log);
} else if (subwindow.type() == IRCWindow::Channel) {
auto it = m_channels.find(subwindow.name());
ASSERT(it != m_channels.end());
auto& channel = *(*it).value;
subwindow.set_log_buffer(channel.log());
} else if (subwindow.type() == IRCWindow::Query) {
subwindow.set_log_buffer(ensure_query(subwindow.name()).log());
} }
m_windows.append(&subwindow); m_windows.append(&subwindow);
m_client_window_list_model->update(); m_client_window_list_model->update();

View file

@ -5,10 +5,10 @@
#include <AK/CircularQueue.h> #include <AK/CircularQueue.h>
#include <AK/Function.h> #include <AK/Function.h>
#include "IRCLogBuffer.h" #include "IRCLogBuffer.h"
#include "IRCWindow.h"
class IRCChannel; class IRCChannel;
class IRCQuery; class IRCQuery;
class IRCWindow;
class IRCWindowListModel; class IRCWindowListModel;
class GNotifier; class GNotifier;
@ -32,11 +32,10 @@ public:
Function<void()> on_connect; Function<void()> on_connect;
Function<void()> on_disconnect; Function<void()> on_disconnect;
Function<void(const String& channel)> on_channel_message;
Function<void(const String& name)> on_query_message;
Function<void(const String& channel)> on_join;
Function<void()> on_server_message; Function<void()> on_server_message;
Function<IRCWindow*(void*, IRCWindow::Type, const String&)> aid_create_window;
void register_subwindow(IRCWindow&); void register_subwindow(IRCWindow&);
void unregister_subwindow(IRCWindow&); void unregister_subwindow(IRCWindow&);

View file

@ -8,6 +8,8 @@ IRCQuery::IRCQuery(IRCClient& client, const String& name)
, m_name(name) , m_name(name)
, m_log(IRCLogBuffer::create()) , m_log(IRCLogBuffer::create())
{ {
m_window = m_client.aid_create_window(this, IRCWindow::Query, m_name);
m_window->set_log_buffer(*m_log);
} }
IRCQuery::~IRCQuery() IRCQuery::~IRCQuery()

View file

@ -8,6 +8,7 @@
#include "IRCLogBuffer.h" #include "IRCLogBuffer.h"
class IRCClient; class IRCClient;
class IRCWindow;
class IRCQuery : public Retainable<IRCQuery> { class IRCQuery : public Retainable<IRCQuery> {
public: public:
@ -24,11 +25,15 @@ public:
void say(const String&); void say(const String&);
IRCWindow& window() { return *m_window; }
const IRCWindow& window() const { return *m_window; }
private: private:
IRCQuery(IRCClient&, const String& name); IRCQuery(IRCClient&, const String& name);
IRCClient& m_client; IRCClient& m_client;
String m_name; String m_name;
IRCWindow* m_window { nullptr };
Retained<IRCLogBuffer> m_log; Retained<IRCLogBuffer> m_log;
}; };

View file

@ -8,9 +8,10 @@
#include <LibGUI/GTextEditor.h> #include <LibGUI/GTextEditor.h>
#include <LibGUI/GTextBox.h> #include <LibGUI/GTextBox.h>
IRCWindow::IRCWindow(IRCClient& client, Type type, const String& name, GWidget* parent) IRCWindow::IRCWindow(IRCClient& client, void* owner, Type type, const String& name, GWidget* parent)
: GWidget(parent) : GWidget(parent)
, m_client(client) , m_client(client)
, m_owner(owner)
, m_type(type) , m_type(type)
, m_name(name) , m_name(name)
{ {
@ -31,7 +32,7 @@ IRCWindow::IRCWindow(IRCClient& client, Type type, const String& name, GWidget*
member_view->set_size_policy(SizePolicy::Fixed, SizePolicy::Fill); member_view->set_size_policy(SizePolicy::Fixed, SizePolicy::Fill);
member_view->set_preferred_size({ 100, 0 }); member_view->set_preferred_size({ 100, 0 });
member_view->set_alternating_row_colors(false); member_view->set_alternating_row_colors(false);
member_view->set_model(OwnPtr<IRCChannelMemberListModel>(m_client.ensure_channel(m_name).member_model())); member_view->set_model(OwnPtr<IRCChannelMemberListModel>(channel().member_model()));
} }
m_text_editor = new GTextEditor(GTextEditor::SingleLine, this); m_text_editor = new GTextEditor(GTextEditor::SingleLine, this);

View file

@ -2,7 +2,9 @@
#include <LibGUI/GWidget.h> #include <LibGUI/GWidget.h>
class IRCChannel;
class IRCClient; class IRCClient;
class IRCQuery;
class IRCLogBuffer; class IRCLogBuffer;
class GTableView; class GTableView;
class GTextEditor; class GTextEditor;
@ -15,7 +17,7 @@ public:
Query, Query,
}; };
explicit IRCWindow(IRCClient&, Type, const String& name, GWidget* parent); IRCWindow(IRCClient&, void* owner, Type, const String& name, GWidget* parent);
virtual ~IRCWindow() override; virtual ~IRCWindow() override;
String name() const { return m_name; } String name() const { return m_name; }
@ -25,8 +27,15 @@ public:
void set_log_buffer(const IRCLogBuffer&); void set_log_buffer(const IRCLogBuffer&);
IRCChannel& channel() { return *(IRCChannel*)m_owner; }
const IRCChannel& channel() const { return *(const IRCChannel*)m_owner; }
IRCQuery& query() { return *(IRCQuery*)m_owner; }
const IRCQuery& query() const { return *(const IRCQuery*)m_owner; }
private: private:
IRCClient& m_client; IRCClient& m_client;
void* m_owner { nullptr };
Type m_type; Type m_type;
String m_name; String m_name;
GTableView* m_table_view { nullptr }; GTableView* m_table_view { nullptr };