summaryrefslogtreecommitdiff
path: root/src/gui
diff options
context:
space:
mode:
authorPhilipp Sehmisch <tmw@crushnet.org>2007-02-27 16:39:17 +0000
committerPhilipp Sehmisch <tmw@crushnet.org>2007-02-27 16:39:17 +0000
commit7a6e4d3c87ca4d7cc851af47fd9ebb616168f4c9 (patch)
treea880298777fcbb47a897e45ce6344ddbdf61b210 /src/gui
parentec72908d291fff37486a70d1624cfcece23b9bf7 (diff)
downloadMana-7a6e4d3c87ca4d7cc851af47fd9ebb616168f4c9.tar.gz
Mana-7a6e4d3c87ca4d7cc851af47fd9ebb616168f4c9.tar.bz2
Mana-7a6e4d3c87ca4d7cc851af47fd9ebb616168f4c9.tar.xz
Mana-7a6e4d3c87ca4d7cc851af47fd9ebb616168f4c9.zip
Implementation of chat channels by Trapdoor.
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/button.cpp9
-rw-r--r--src/gui/button.h7
-rw-r--r--src/gui/chat.cpp185
-rw-r--r--src/gui/chat.h54
-rw-r--r--src/gui/tabbedcontainer.cpp36
-rw-r--r--src/gui/tabbedcontainer.h10
6 files changed, 262 insertions, 39 deletions
diff --git a/src/gui/button.cpp b/src/gui/button.cpp
index 0055c89a..e607b66a 100644
--- a/src/gui/button.cpp
+++ b/src/gui/button.cpp
@@ -38,8 +38,9 @@ ImageRect Button::button[4];
int Button::mInstances = 0;
Button::Button(const std::string& caption, const std::string &actionEventId,
- gcn::ActionListener *listener):
- gcn::Button(caption)
+ gcn::ActionListener *listener):
+ gcn::Button(caption),
+ mIsLogged(false)
{
setBorderSize(0);
@@ -100,7 +101,7 @@ Button::draw(gcn::Graphics *graphics)
if (!isEnabled()) {
mode = 3;
}
- else if (isPressed()) {
+ else if (isPressed() || mIsLogged) {
mode = 2;
}
else if (mHasMouse) {
@@ -130,7 +131,7 @@ Button::draw(gcn::Graphics *graphics)
textX = getWidth() - 4;
break;
default:
- throw GCN_EXCEPTION("Button::draw. Uknown alignment.");
+ throw GCN_EXCEPTION("Button::draw. Unknown alignment.");
}
graphics->setFont(getFont());
diff --git a/src/gui/button.h b/src/gui/button.h
index 1c2ec41b..eb73e311 100644
--- a/src/gui/button.h
+++ b/src/gui/button.h
@@ -53,9 +53,16 @@ class Button : public gcn::Button {
*/
void draw(gcn::Graphics* graphics);
+ /**
+ * Enable/Disable highlighting
+ */
+ void setLogged(bool enable)
+ { mIsLogged = enable; }
+
private:
static ImageRect button[4]; /**< Button state graphics */
static int mInstances; /**< Number of button instances */
+ bool mIsLogged; /**< Makes the button appear pressed all the time */
};
#endif
diff --git a/src/gui/chat.cpp b/src/gui/chat.cpp
index d992c6dd..eb6b7612 100644
--- a/src/gui/chat.cpp
+++ b/src/gui/chat.cpp
@@ -29,17 +29,22 @@
#include <guichan/key.hpp>
#include "browserbox.h"
+#include "../channelmanager.h"
+#include "../channel.h"
#include "chatinput.h"
+#include "gccontainer.h"
#include "scrollarea.h"
+#include "tabbedcontainer.h"
#include "windowcontainer.h"
#include "../game.h"
#include "../localplayer.h"
#include "../net/chatserver/chatserver.h"
-
#include "../net/gameserver/player.h"
+#include "../utils/dtor.h"
+
ChatWindow::ChatWindow():
Window(""),
mTmpVisible(false)
@@ -56,17 +61,34 @@ ChatWindow::ChatWindow():
mChatInput->setActionEventId("chatinput");
mChatInput->addActionListener(this);
- mTextOutput = new BrowserBox(BrowserBox::AUTO_WRAP);
- mTextOutput->setOpaque(false);
- mTextOutput->disableLinksAndUserColors();
- mScrollArea = new ScrollArea(mTextOutput);
- mScrollArea->setPosition(
- mScrollArea->getBorderSize(), mScrollArea->getBorderSize());
- mScrollArea->setScrollPolicy(
+ BrowserBox *textOutput = new BrowserBox(BrowserBox::AUTO_WRAP);
+ textOutput->setOpaque(false);
+ textOutput->disableLinksAndUserColors();
+ ScrollArea *scrollArea = new ScrollArea(textOutput);
+ scrollArea->setPosition(
+ scrollArea->getBorderSize(), scrollArea->getBorderSize());
+ scrollArea->setScrollPolicy(
gcn::ScrollArea::SHOW_NEVER, gcn::ScrollArea::SHOW_ALWAYS);
- mScrollArea->setOpaque(false);
+ scrollArea->setOpaque(false);
+
+ GCContainer *tab = new GCContainer();
+ tab->setWidth(getWidth() - 2 * tab->getBorderSize());
+ tab->setHeight(getHeight() - 2 * tab->getBorderSize());
+ tab->setOpaque(false);
+ tab->add(scrollArea);
+
+ mContainer = new TabbedContainer();
+ mContainer->addTab(tab, "General");
+ mContainer->setOpaque(false);
+ mChannelOutput["General"] = textOutput;
+ mChannelScroll["General"] = scrollArea;
+
+ mTabs["General"] = tab;
+
+ mTextOutput = textOutput;
+ mScrollArea = scrollArea;
- add(mScrollArea);
+ add(mContainer);
add(mChatInput);
// Add key listener to chat input to be able to respond to up/down
@@ -74,6 +96,11 @@ ChatWindow::ChatWindow():
mCurHist = mHistory.end();
}
+ChatWindow::~ChatWindow()
+{
+ for_each(mTabs.begin(), mTabs.end(), make_dtor(mTabs));
+}
+
void
ChatWindow::logic()
{
@@ -85,14 +112,17 @@ ChatWindow::logic()
area.height - mChatInput->getHeight() -
mChatInput->getBorderSize());
mChatInput->setWidth(area.width - 2 * mChatInput->getBorderSize());
+ mContainer->setWidth(area.width - 2 * mContainer->getBorderSize());
+ mContainer->setHeight(area.height - 2 * mContainer->getBorderSize() -
+ mChatInput->getHeight() - 5);
mScrollArea->setWidth(area.width - 2 * mScrollArea->getBorderSize());
mScrollArea->setHeight(area.height - 2 * mScrollArea->getBorderSize() -
- mChatInput->getHeight() - 5);
+ mChatInput->getHeight() - 26);
mScrollArea->logic();
}
void
-ChatWindow::chatLog(std::string line, int own)
+ChatWindow::chatLog(std::string line, int own, std::string channelName)
{
// Delete overhead from the end of the list
while ((int)mChatlog.size() > mItemsKeep) {
@@ -103,6 +133,9 @@ ChatWindow::chatLog(std::string line, int own)
tmp.own = own;
tmp.nick = "";
+ mTextOutput = mChannelOutput[channelName];
+ mScrollArea = mChannelScroll[channelName];
+
// Fix the owner of welcome message.
if (line.substr(0, 7) == "Welcome")
{
@@ -196,7 +229,7 @@ ChatWindow::action(const gcn::ActionEvent &event)
mCurHist = mHistory.end();
// Send the message to the server
- chatSend(player_node->getName(), message);
+ chatSend(player_node->getName(), message, mContainer->getActiveWidget());
// Clear the text from the chat input
mChatInput->setText("");
@@ -241,7 +274,7 @@ ChatWindow::isFocused()
}
void
-ChatWindow::chatSend(const std::string &nick, std::string msg)
+ChatWindow::chatSend(const std::string &nick, std::string msg, std::string channelName)
{
/* Some messages are managed client side, while others
* require server handling by proper packet. Probably
@@ -249,7 +282,15 @@ ChatWindow::chatSend(const std::string &nick, std::string msg)
// Prepare ordinary message
if (msg.substr(0, 1) != "/") {
- Net::GameServer::Player::say(msg);
+ if(mContainer->getActiveWidget() == "General")
+ {
+ Net::GameServer::Player::say(msg);
+ }
+ else
+ {
+ short channelId = channelManager->findByName(channelName)->getId();
+ Net::ChatServer::chat(channelId, msg);
+ }
}
else if (msg.substr(0, IS_ANNOUNCE_LENGTH) == IS_ANNOUNCE)
{
@@ -258,11 +299,15 @@ ChatWindow::chatSend(const std::string &nick, std::string msg)
}
else if (msg.substr(0, IS_HELP_LENGTH) == IS_HELP)
{
- chatLog("-- Help --", BY_SERVER);
- chatLog("/help : Display this help.", BY_SERVER);
- chatLog("/announce : Global announcement (GM only)", BY_SERVER);
- chatLog("/where : Display map name", BY_SERVER);
- chatLog("/who : Display number of online users", BY_SERVER);
+ chatLog("-- Help --", BY_SERVER, channelName);
+ chatLog("/help > Display this help.", BY_SERVER, channelName);
+ chatLog("/announce > Global announcement (GM only)", BY_SERVER, channelName);
+ chatLog("/where > Display map name", BY_SERVER, channelName);
+ chatLog("/who > Display number of online users", BY_SERVER, channelName);
+ chatLog("/list > Display all public channels", BY_SERVER, channelName);
+ chatLog("/register > Register a new channel", BY_SERVER, channelName);
+ chatLog("/join > Join an already registered channel", BY_SERVER, channelName);
+ chatLog("/quit > Leave a channel", BY_SERVER, channelName);
}
else if (msg.substr(0, IS_WHERE_LENGTH) == IS_WHERE)
{
@@ -275,9 +320,46 @@ ChatWindow::chatSend(const std::string &nick, std::string msg)
MessageOut outMsg(0x00c1);
*/
}
+ else if (msg.substr(0, IS_REGCHANNEL_LENGTH) == IS_REGCHANNEL)
+ {
+ std::string channel = msg.substr(IS_REGCHANNEL_LENGTH, msg.size());
+ chatLog("Requesting to register channel", BY_SERVER);
+ Net::ChatServer::registerChannel(channel, "", "", false);
+ }
+ else if (msg.substr(0, IS_JOINCHANNEL_LENGTH) == IS_JOINCHANNEL)
+ {
+ //TODO: have passwords too
+ msg = msg.substr(IS_JOINCHANNEL_LENGTH, msg.size());
+ chatLog("Requesting to join channel " + msg, BY_SERVER);
+ if(msg != "")
+ {
+ enterChannel(msg, "None");
+ }
+ else
+ {
+ chatLog("No channel name given", BY_SERVER);
+ }
+ }
+ else if (msg.substr(0, IS_LISTCHANNELS_LENGTH) == IS_LISTCHANNELS)
+ {
+ Net::ChatServer::getChannelList();
+ }
+ else if (msg.substr(0, IS_QUITCHANNEL_LENGTH) == IS_QUITCHANNEL)
+ {
+ Channel* channel;
+ channel = channelManager->findByName(channelName);
+ if(channel)
+ {
+ Net::ChatServer::quitChannel(channel->getId());
+ }
+ else
+ {
+ chatLog("Unable to quit this channel", BY_SERVER);
+ }
+ }
else
{
- chatLog("Unknown command", BY_SERVER);
+ chatLog("Unknown command", BY_SERVER, channelName);
}
}
@@ -360,6 +442,67 @@ ChatWindow::const_msg(CHATSKILL act)
}
void
+ChatWindow::addChannel(short channelId, std::string channelName)
+{
+ Channel* channel = new Channel(channelId);
+ channel->setName(channelName);
+ channelManager->addChannel(channel);
+}
+
+void
+ChatWindow::removeChannel(short channelId)
+{
+ Channel* channel = channelManager->findById(channelId);
+ if(channel)
+ {
+ mContainer->removeTab(channel->getName());
+ mTabs.erase(channel->getName());
+ mChannelOutput.erase(channel->getName());
+ mChannelScroll.erase(channel->getName());
+ channelManager->removeChannel(channel);
+ mTextOutput = mChannelOutput["General"];
+ mScrollArea = mChannelScroll["General"];
+ }
+}
+
+void
+ChatWindow::createNewChannelTab(std::string channelName)
+{
+ BrowserBox *textOutput = new BrowserBox(BrowserBox::AUTO_WRAP);
+ textOutput->setOpaque(false);
+ textOutput->disableLinksAndUserColors();
+ ScrollArea *scrollArea = new ScrollArea(textOutput);
+ scrollArea->setPosition(scrollArea->getBorderSize(), scrollArea->getBorderSize());
+ scrollArea->setScrollPolicy(gcn::ScrollArea::SHOW_NEVER, gcn::ScrollArea::SHOW_ALWAYS);
+ scrollArea->setOpaque(false);
+ GCContainer *tab = new GCContainer();
+ tab->setWidth(getWidth() - 2 * tab->getBorderSize());
+ tab->setHeight(getHeight() - 2 * tab->getBorderSize());
+ tab->add(scrollArea);
+ tab->setOpaque(false);
+ mContainer->addTab(tab, channelName);
+ mTabs[channelName] = tab;
+ mChannelOutput[channelName] = textOutput;
+ mChannelScroll[channelName] = scrollArea;
+ mScrollArea = scrollArea;
+ mTextOutput = textOutput;
+ logic();
+}
+
+void
+ChatWindow::enterChannel(std::string channel, std::string password)
+{
+ Net::ChatServer::enterChannel(channel, password);
+}
+
+void
+ChatWindow::sendToChannel(short channelId, std::string user, std::string msg)
+{
+ std::string channelName = channelManager->findById(channelId)->getName();
+ chatLog(user + ": " + msg, user == player_node->getName() ? BY_PLAYER : BY_OTHER, channelName);
+}
+
+void
ChatWindow::keyPressed(gcn::KeyEvent &event)
{
if (event.getKey().getValue() == gcn::Key::DOWN &&
diff --git a/src/gui/chat.h b/src/gui/chat.h
index 963e5e98..c7e51ebf 100644
--- a/src/gui/chat.h
+++ b/src/gui/chat.h
@@ -26,6 +26,7 @@
#include <list>
#include <string>
+#include <map>
#include <guichan/actionlistener.hpp>
#include <guichan/keylistener.hpp>
@@ -36,6 +37,8 @@
class BrowserBox;
class ScrollArea;
+class TabbedContainer;
+class GCContainer;
#define BY_GM 0 // those should be self-explanatory =)
#define BY_PLAYER 1
@@ -53,6 +56,14 @@ class ScrollArea;
#define IS_WHERE_LENGTH 6
#define IS_WHO "/who"
#define IS_WHO_LENGTH 4
+#define IS_JOINCHANNEL "/join "
+#define IS_JOINCHANNEL_LENGTH 6
+#define IS_REGCHANNEL "/register "
+#define IS_REGCHANNEL_LENGTH 10
+#define IS_LISTCHANNELS "/list"
+#define IS_LISTCHANNELS_LENGTH 5
+#define IS_QUITCHANNEL "/quit"
+#define IS_QUITCHANNEL_LENGTH 5
/**
* gets in between usernick and message text depending on
@@ -118,6 +129,11 @@ class ChatWindow : public Window, public gcn::ActionListener,
ChatWindow();
/**
+ *
+ */
+ ~ChatWindow();
+
+ /**
* Logic (updates components' size)
*/
void logic();
@@ -128,7 +144,7 @@ class ChatWindow : public Window, public gcn::ActionListener,
* @param line Text message.
* @parem own Type of message (usually the owner-type).
*/
- void chatLog(std::string line, int own);
+ void chatLog(std::string line, int own, std::string channelName = "General");
/*
* Calls original chat_log() after processing the packet.
@@ -175,7 +191,27 @@ class ChatWindow : public Window, public gcn::ActionListener,
* chatlog.chat_send("Zaeiru", "Hello to all users on the screen!");
*/
void
- chatSend(const std::string &nick, std::string msg);
+ chatSend(const std::string &nick, std::string msg, std::string channelName);
+
+ /** Called to add the channel to the channel manager */
+ void
+ addChannel(short channel, std::string channelName);
+
+ /** Called to remove the channel from the channel manager */
+ void
+ removeChannel(short channel);
+
+ /** Called to create a new channel tab */
+ void
+ createNewChannelTab(std::string channelName);
+
+ /** Called to join channel */
+ void
+ enterChannel(std::string channel, std::string password = "None");
+
+ /** Called to output text to a specific channel */
+ void
+ sendToChannel(short channel, std::string user, std::string msg);
/** Called when key is pressed */
void
@@ -192,7 +228,9 @@ class ChatWindow : public Window, public gcn::ActionListener,
private:
bool mTmpVisible;
- /** One item in the chat log */
+ int mItems;
+ int mItemsKeep;
+
typedef struct CHATLOG
{
std::string nick;
@@ -200,15 +238,17 @@ class ChatWindow : public Window, public gcn::ActionListener,
int own;
};
- std::list<CHATLOG> mChatlog; /**< Chat log */
-
- int mItems;
- int mItemsKeep;
+ std::list<CHATLOG> mChatlog;
/** Constructs failed messages for actions */
std::string const_msg(CHATSKILL);
+ std::map<std::string, GCContainer*> mTabs;
+ TabbedContainer *mContainer; /**< Tabbed container for tabbing between channels */
+ GCContainer *mTab; /**< Tabs */
gcn::TextField *mChatInput; /**< Input box for typing chat messages */
+ std::map<std::string, BrowserBox*> mChannelOutput; /**< Map each TextOutput to a tab */
+ std::map<std::string, ScrollArea*> mChannelScroll; /**< Map each ScrollArea to a tab */
BrowserBox *mTextOutput; /**< Text box for displaying chat history */
ScrollArea *mScrollArea; /**< Scroll area around text output */
diff --git a/src/gui/tabbedcontainer.cpp b/src/gui/tabbedcontainer.cpp
index 75f9f3cf..5d6d21d1 100644
--- a/src/gui/tabbedcontainer.cpp
+++ b/src/gui/tabbedcontainer.cpp
@@ -26,6 +26,7 @@
#include "button.h"
#include "../utils/tostring.h"
+#include "../utils/dtor.h"
#define TABWIDTH 60
#define TABHEIGHT 20
@@ -37,10 +38,7 @@ TabbedContainer::TabbedContainer():
TabbedContainer::~TabbedContainer()
{
- for (WidgetIterator i = mTabs.begin(); i != mTabs.end(); i++) {
- remove(*i);
- delete (*i);
- }
+ for_each(mTabs.begin(), mTabs.end(), make_dtor(mTabs));
mTabs.clear();
mContents.clear();
@@ -55,7 +53,7 @@ void TabbedContainer::addTab(gcn::Widget *widget, const std::string &caption)
tab->setSize(TABWIDTH, TABHEIGHT);
add(tab, TABWIDTH * tabNumber, 0);
- mTabs.push_back(tab);
+ mTabs[caption] = tab;
mContents.push_back(widget);
widget->setPosition(0, TABHEIGHT);
@@ -64,7 +62,18 @@ void TabbedContainer::addTab(gcn::Widget *widget, const std::string &caption)
if (!mActiveContent) {
mActiveContent = widget;
add(mActiveContent);
+ tab->setLogged(true);
}
+
+ mWidgets[widget] = caption;
+}
+
+void TabbedContainer::removeTab(const std::string &caption)
+{
+ gcn::ActionEvent actionEvent(this, "0");
+ action(actionEvent);
+ remove(mTabs[caption]);
+ mTabs.erase(caption);
}
void TabbedContainer::logic()
@@ -80,16 +89,21 @@ void TabbedContainer::logic()
void TabbedContainer::action(const gcn::ActionEvent &event)
{
- std::stringstream ss(event.getId());
int tabNo;
+ std::stringstream ss(event.getId());
ss >> tabNo;
gcn::Widget *newContent = mContents[tabNo];
+
if (newContent) {
if (mActiveContent) {
+ // Unhighlight old tab
+ ((Button*)mTabs[mWidgets[mActiveContent]])->setLogged(false);
remove(mActiveContent);
}
mActiveContent = newContent;
+ // Highlight new tab
+ ((Button*)mTabs[mWidgets[mActiveContent]])->setLogged(true);
add(newContent);
}
}
@@ -98,3 +112,13 @@ void TabbedContainer::setOpaque(bool opaque)
{
Container::setOpaque(opaque);
}
+
+short TabbedContainer::getNumberOfTabs()
+{
+ return mTabs.size();
+}
+
+std::string TabbedContainer::getActiveWidget()
+{
+ return mWidgets[mActiveContent];
+}
diff --git a/src/gui/tabbedcontainer.h b/src/gui/tabbedcontainer.h
index 2dc017ae..7f8deef9 100644
--- a/src/gui/tabbedcontainer.h
+++ b/src/gui/tabbedcontainer.h
@@ -26,6 +26,7 @@
#include <iosfwd>
#include <vector>
+#include <map>
#include <guichan/actionlistener.hpp>
@@ -41,18 +42,25 @@ class TabbedContainer : public gcn::Container, public gcn::ActionListener
void addTab(gcn::Widget *widget, const std::string &caption);
+ void removeTab(const std::string &caption);
+
void logic();
void action(const gcn::ActionEvent &event);
void setOpaque(bool opaque);
+ short getNumberOfTabs();
+
+ std::string getActiveWidget();
+
private:
typedef std::vector<gcn::Widget*> Widgets;
typedef Widgets::iterator WidgetIterator;
- Widgets mTabs; // The actual tabs at the top
+ std::map<std::string, gcn::Widget*> mTabs; // tabs mapped to their channel name
Widgets mContents; // The contents of the tabs
+ std::map<gcn::Widget*, std::string> mWidgets;
gcn::Widget *mActiveContent;
};