diff --git a/examples/ircclient/src/ircclient/net/client.d b/examples/ircclient/src/ircclient/net/client.d index d48b33e6..34c01646 100644 --- a/examples/ircclient/src/ircclient/net/client.d +++ b/examples/ircclient/src/ircclient/net/client.d @@ -114,7 +114,7 @@ class IRCMessage { target = params[1]; break; case CHANNEL_NAMES_LIST: - if (params.length > 2 && params[1] == "=") + if (params.length > 2 && (params[1] == "=" || params[1] == "@")) target = params[2]; break; default: @@ -174,6 +174,22 @@ class UserList { _users.add(u); } } + int findUser(string name) { + for(int i = 0; i < _users.length; i++) { + if (_users[i].nick == name) + return i; + } + return -1; + } + void addUser(string name) { + if (findUser(name) < 0) + _users.add(new IRCUser(name)); + } + void removeUser(string name) { + if (int index = findUser(name)) { + _users.remove(index); + } + } } class IRCChannel { @@ -215,6 +231,12 @@ class IRCChannel { Log.d("user list for " ~ name ~ " : " ~ userListBuffer); userListBuffer = null; break; + case JOIN: + users.addUser(msg.sourceAddress.nick); + break; + case PART: + users.removeUser(msg.sourceAddress.nick); + break; default: break; } @@ -274,6 +296,8 @@ protected: case CHANNEL_TOPIC_SET_BY: case CHANNEL_NAMES_LIST: case CHANNEL_NAMES_LIST_END: + case JOIN: + case PART: if (msg.target.startsWith("#")) { auto channel = channelByName(msg.target, true); channel.handleMessage(msg); diff --git a/examples/ircclient/src/ircclient/ui/frame.d b/examples/ircclient/src/ircclient/ui/frame.d index 2ecd788c..8ab6c9f6 100644 --- a/examples/ircclient/src/ircclient/ui/frame.d +++ b/examples/ircclient/src/ircclient/ui/frame.d @@ -174,6 +174,11 @@ class IRCFrame : AppFrame, IRCClientCallback { _tabs.layoutHeight = FILL_PARENT; //tabs.addTab(new IRCWindow("sample"), "Sample"d); statusLine.setStatusText(toUTF32("Not Connected")); + _tabs.tabChanged = delegate(string newActiveTabId, string previousTabId) { + if (IRCWindow w = cast(IRCWindow)_tabs.tabBody(newActiveTabId)) { + w.onTabActivated(); + } + }; return _tabs; } @@ -187,18 +192,23 @@ class IRCFrame : AppFrame, IRCClientCallback { _client.connect(_settings.host, _settings.port); } - IRCWindow getOrCreateWindowFor(string party) { + IRCWindow getOrCreateWindowFor(string party, bool activate) { string winId = party; IRCWindow w = cast(IRCWindow)_tabs.tabBody(winId); if (!w) { - w = new IRCWindow(winId, _client); + w = new IRCWindow(winId, this, _client); _tabs.addTab(w, toUTF32(winId)); + activate = true; + } + if (activate) { + _tabs.selectTab(winId); + w.onTabActivated(); } return w; } void onIRCConnect(IRCClient client) { - IRCWindow w = getOrCreateWindowFor(client.hostPort); + IRCWindow w = getOrCreateWindowFor(client.hostPort, true); w.addLine("connected to " ~ client.hostPort); client.sendMessage("USER " ~ _settings.userName ~ " 0 * :" ~ _settings.userRealName); client.nick(_settings.nick); @@ -209,13 +219,13 @@ class IRCFrame : AppFrame, IRCClientCallback { } void onIRCDisconnect(IRCClient client) { - IRCWindow w = getOrCreateWindowFor(client.hostPort); + IRCWindow w = getOrCreateWindowFor(client.hostPort, false); w.addLine("disconnected from " ~ client.hostPort); statusLine.setStatusText(toUTF32("Disconnected")); } void onIRCPing(IRCClient client, string message) { - IRCWindow w = getOrCreateWindowFor(client.hostPort); + IRCWindow w = getOrCreateWindowFor(client.hostPort, false); w.addLine("PING " ~ message); client.pong(message); } @@ -226,32 +236,34 @@ class IRCFrame : AppFrame, IRCClientCallback { wid = source.nick; else if (source.nick == client.nick) wid = target; - IRCWindow w = getOrCreateWindowFor(wid); + IRCWindow w = getOrCreateWindowFor(wid, false); w.addLine("<" ~ (!source.nick.empty ? source.nick : source.full) ~ "> " ~ message); } void onIRCNotice(IRCClient client, IRCAddress source, string target, string message) { - IRCWindow w = getOrCreateWindowFor(target.startsWith("#") ? target : client.hostPort); + IRCWindow w = getOrCreateWindowFor(target.startsWith("#") ? target : client.hostPort, false); w.addLine("-" ~ source.full ~ "- " ~ message); } void onIRCMessage(IRCClient client, IRCMessage message) { - IRCWindow w = getOrCreateWindowFor(client.hostPort); + IRCWindow w = getOrCreateWindowFor(client.hostPort, false); switch (message.commandId) with (IRCCommand) { case JOIN: case PART: if (message.sourceAddress && !message.sourceAddress.nick.empty && message.target.startsWith("#")) { - w = getOrCreateWindowFor(message.target); + w = getOrCreateWindowFor(message.target, false); if (message.commandId == JOIN) { w.addLine("* " ~ message.sourceAddress.longName ~ " has joined " ~ message.target); } else { w.addLine("* " ~ message.sourceAddress.longName ~ " has left " ~ message.target ~ (message.message.empty ? "" : ("(Reason: " ~ message.message ~ ")"))); } + IRCChannel channel = _client.channelByName(message.target); + w.updateUserList(channel); } return; case CHANNEL_NAMES_LIST_END: if (message.target.startsWith("#")) { - w = getOrCreateWindowFor(message.target); + w = getOrCreateWindowFor(message.target, false); IRCChannel channel = _client.channelByName(message.target); w.updateUserList(channel); } @@ -275,14 +287,19 @@ enum IRCWindowKind { } class IRCWindow : VerticalLayout, EditorActionHandler { +private: + IRCFrame _frame; LogWidget _editBox; StringListWidget _listBox; EditLine _editLine; IRCClient _client; IRCWindowKind _kind; - this(string ID, IRCClient client) { + dstring[] _userNames; +public: + this(string ID, IRCFrame frame, IRCClient client) { super(ID); _client = client; + _frame = frame; layoutWidth = FILL_PARENT; layoutHeight = FILL_PARENT; HorizontalLayout hlayout = new HorizontalLayout(); @@ -302,6 +319,15 @@ class IRCWindow : VerticalLayout, EditorActionHandler { //_listBox.items = ["Nick1"d, "Nick2"d]; hlayout.addChild(new ResizerWidget(null, Orientation.Horizontal)); hlayout.addChild(_listBox); + + _listBox.itemClick = delegate(Widget source, int itemIndex) { + auto user = itemIndex >= 0 && itemIndex < _userNames.length ? toUTF8(_userNames[itemIndex]) : null; + if (!user.empty && user != _client.nick) { + _frame.getOrCreateWindowFor(user, true); + } + return true; + }; + _kind = IRCWindowKind.Channel; } else { if (id.indexOf(':') >= 0) @@ -320,8 +346,10 @@ class IRCWindow : VerticalLayout, EditorActionHandler { window.update(); } void updateUserList(IRCChannel channel) { - _listBox.items = channel.userNames; - window.update(); + _userNames = channel.userNames; + _listBox.items = _userNames; + if (window) + window.update(); } bool onEditorAction(const Action action) { if (!_editLine.text.empty) { @@ -359,4 +387,7 @@ class IRCWindow : VerticalLayout, EditorActionHandler { } return true; } + void onTabActivated() { + _editLine.setFocus(); + } } diff --git a/src/dlangui/widgets/lists.d b/src/dlangui/widgets/lists.d index a983e797..a3dfcb14 100644 --- a/src/dlangui/widgets/lists.d +++ b/src/dlangui/widgets/lists.d @@ -568,8 +568,8 @@ class ListWidget : WidgetGroup, OnScrollHandler, OnAdapterChangeHandler { @property ListWidget orientation(Orientation value) { _orientation = value; _scrollbar.orientation = value; - requestLayout(); - return this; + requestLayout(); + return this; } protected Rect[] _itemRects; @@ -1313,23 +1313,24 @@ class StringListWidget : ListWidget { this(string ID, string[] items) { super(ID); styleId = STYLE_EDIT_BOX; - adapter = new StringListAdapter(items); + ownAdapter = new StringListAdapter(items); } this(string ID, dstring[] items) { super(ID); styleId = STYLE_EDIT_BOX; - adapter = new StringListAdapter(items); + ownAdapter = new StringListAdapter(items); } this(string ID, StringListValue[] items) { super(ID); styleId = STYLE_EDIT_BOX; - adapter = new StringListAdapter(items); + ownAdapter = new StringListAdapter(items); } @property void items(string[] itemResourceIds) { - adapter = new StringListAdapter(itemResourceIds); + _selectedItemIndex = -1; + ownAdapter = new StringListAdapter(itemResourceIds); if(itemResourceIds.length > 0) { selectedItemIndex = 0; } @@ -1337,7 +1338,8 @@ class StringListWidget : ListWidget { } @property void items(dstring[] items) { - adapter = new StringListAdapter(items); + _selectedItemIndex = -1; + ownAdapter = new StringListAdapter(items); if(items.length > 0) { selectedItemIndex = 0; } @@ -1345,7 +1347,8 @@ class StringListWidget : ListWidget { } @property void items(StringListValue[] items) { - adapter = new StringListAdapter(items); + _selectedItemIndex = -1; + ownAdapter = new StringListAdapter(items); if(items.length > 0) { selectedItemIndex = 0; }