1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-24 15:57: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_rect(200, 200, 600, 400);
setup_client();
setup_actions();
setup_menus();
setup_widgets();
setup_client();
}
IRCAppWindow::~IRCAppWindow()
@ -29,22 +30,14 @@ IRCAppWindow::~IRCAppWindow()
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.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();
}
@ -129,20 +122,10 @@ void IRCAppWindow::setup_widgets()
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);
}
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);
return *new IRCWindow(m_client, owner, type, name, m_container);
}

View file

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

View file

@ -10,6 +10,8 @@ IRCChannel::IRCChannel(IRCClient& client, const String& name)
, m_log(IRCLogBuffer::create())
{
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()

View file

@ -9,6 +9,7 @@
class IRCClient;
class IRCChannelMemberListModel;
class IRCWindow;
class IRCChannel : public Retainable<IRCChannel> {
public:
@ -38,6 +39,9 @@ public:
int member_count() const { return m_members.size(); }
String member_at(int i) { return m_members[i].name; }
IRCWindow& window() { return *m_window; }
const IRCWindow& window() const { return *m_window; }
private:
IRCChannel(IRCClient&, const String&);
@ -52,4 +56,5 @@ private:
Retained<IRCLogBuffer> m_log;
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);
if (it != m_channels.end()) {
(*it).value->add_message(sender_prefix, sender_nick, msg.arguments[1]);
if (on_channel_message)
on_channel_message(target);
return;
}
}
auto& query = ensure_query(sender_nick);
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)
@ -353,8 +349,6 @@ void IRCClient::handle_join(const Message& msg)
return;
auto& channel_name = msg.arguments[0];
ensure_channel(channel_name);
if (on_join)
on_join(channel_name);
}
void IRCClient::handle_namreply(const Message& msg)
@ -389,13 +383,6 @@ void IRCClient::register_subwindow(IRCWindow& subwindow)
if (subwindow.type() == IRCWindow::Server) {
m_server_subwindow = &subwindow;
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_client_window_list_model->update();

View file

@ -5,10 +5,10 @@
#include <AK/CircularQueue.h>
#include <AK/Function.h>
#include "IRCLogBuffer.h"
#include "IRCWindow.h"
class IRCChannel;
class IRCQuery;
class IRCWindow;
class IRCWindowListModel;
class GNotifier;
@ -32,11 +32,10 @@ public:
Function<void()> on_connect;
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<IRCWindow*(void*, IRCWindow::Type, const String&)> aid_create_window;
void register_subwindow(IRCWindow&);
void unregister_subwindow(IRCWindow&);

View file

@ -8,6 +8,8 @@ IRCQuery::IRCQuery(IRCClient& client, const String& name)
, m_name(name)
, 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()

View file

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

View file

@ -8,9 +8,10 @@
#include <LibGUI/GTextEditor.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)
, m_client(client)
, m_owner(owner)
, m_type(type)
, 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_preferred_size({ 100, 0 });
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);

View file

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