summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJared Adams <jaxad0127@gmail.com>2010-02-08 14:40:04 -0700
committerJared Adams <jaxad0127@gmail.com>2010-02-08 14:43:51 -0700
commit8a31e96d8534d402db9cd48183c0b15732f7d95e (patch)
tree885d83febf301c1289c3bf7f83bf9dca89e0347c
parentbc5c031e43eff506c925682349dd2a52b89d6565 (diff)
downloadMana-8a31e96d8534d402db9cd48183c0b15732f7d95e.tar.gz
Mana-8a31e96d8534d402db9cd48183c0b15732f7d95e.tar.bz2
Mana-8a31e96d8534d402db9cd48183c0b15732f7d95e.tar.xz
Mana-8a31e96d8534d402db9cd48183c0b15732f7d95e.zip
Merge PartyWindow and GuildWindow into SocialWindow
-rw-r--r--mana.cbp16
-rw-r--r--mana.files19
-rw-r--r--src/CMakeLists.txt16
-rw-r--r--src/Makefile.am16
-rw-r--r--src/avatar.cpp33
-rw-r--r--src/avatar.h (renamed from src/gui/widgets/avatar.h)28
-rw-r--r--src/game.cpp68
-rw-r--r--src/gui/chat.cpp22
-rw-r--r--src/gui/chat.h3
-rw-r--r--src/gui/confirmdialog.cpp8
-rw-r--r--src/gui/guildwindow.cpp284
-rw-r--r--src/gui/guildwindow.h129
-rw-r--r--src/gui/okdialog.cpp8
-rw-r--r--src/gui/partywindow.cpp274
-rw-r--r--src/gui/partywindow.h149
-rw-r--r--src/gui/socialwindow.cpp570
-rw-r--r--src/gui/socialwindow.h105
-rw-r--r--src/gui/textdialog.cpp11
-rw-r--r--src/gui/widgets/avatar.cpp122
-rw-r--r--src/gui/widgets/avatarlistbox.cpp133
-rw-r--r--src/gui/widgets/avatarlistbox.h (renamed from src/gui/widgets/guildlistbox.h)40
-rw-r--r--src/gui/widgets/guildlistbox.cpp131
-rw-r--r--src/gui/widgets/listbox.h2
-rw-r--r--src/gui/widgets/scrollarea.cpp3
-rw-r--r--src/gui/widgets/tabbedarea.cpp3
-rw-r--r--src/gui/windowmenu.cpp8
-rw-r--r--src/guild.cpp42
-rw-r--r--src/guild.h26
-rw-r--r--src/keyboardconfig.cpp2
-rw-r--r--src/keyboardconfig.h2
-rw-r--r--src/net/ea/beinghandler.cpp10
-rw-r--r--src/net/ea/generalhandler.cpp12
-rw-r--r--src/net/ea/partyhandler.cpp104
-rw-r--r--src/net/ea/partyhandler.h2
-rw-r--r--src/net/manaserv/chathandler.cpp1
-rw-r--r--src/net/manaserv/generalhandler.cpp4
-rw-r--r--src/net/manaserv/guildhandler.cpp26
-rw-r--r--src/net/manaserv/partyhandler.cpp30
-rw-r--r--src/net/manaserv/partyhandler.h4
-rw-r--r--src/party.cpp233
-rw-r--r--src/party.h175
-rw-r--r--src/player.cpp45
-rw-r--r--src/player.h22
43 files changed, 1552 insertions, 1389 deletions
diff --git a/mana.cbp b/mana.cbp
index 19170e94..239ca320 100644
--- a/mana.cbp
+++ b/mana.cbp
@@ -97,6 +97,8 @@
<Unit filename="src\animatedsprite.h" />
<Unit filename="src\animationparticle.cpp" />
<Unit filename="src\animationparticle.h" />
+ <Unit filename="src\avatar.cpp" />
+ <Unit filename="src\avatar.h" />
<Unit filename="src\being.cpp" />
<Unit filename="src\being.h" />
<Unit filename="src\beingmanager.cpp" />
@@ -153,8 +155,6 @@
<Unit filename="src\gui\focushandler.h" />
<Unit filename="src\gui\gui.cpp" />
<Unit filename="src\gui\gui.h" />
- <Unit filename="src\gui\guildwindow.cpp" />
- <Unit filename="src\gui\guildwindow.h" />
<Unit filename="src\gui\help.cpp" />
<Unit filename="src\gui\help.h" />
<Unit filename="src\gui\inventorywindow.cpp" />
@@ -179,8 +179,6 @@
<Unit filename="src\gui\outfitwindow.h" />
<Unit filename="src\gui\palette.cpp" />
<Unit filename="src\gui\palette.h" />
- <Unit filename="src\gui\partywindow.cpp" />
- <Unit filename="src\gui\partywindow.h" />
<Unit filename="src\gui\popupmenu.cpp" />
<Unit filename="src\gui\popupmenu.h" />
<Unit filename="src\gui\quitdialog.cpp" />
@@ -215,6 +213,8 @@
<Unit filename="src\gui\skilldialog.h" />
<Unit filename="src\gui\skin.cpp" />
<Unit filename="src\gui\skin.h" />
+ <Unit filename="src\gui\socialwindow.cpp" />
+ <Unit filename="src\gui\socialwindow.h" />
<Unit filename="src\gui\specialswindow.cpp" />
<Unit filename="src\gui\specialswindow.h" />
<Unit filename="src\gui\speechbubble.cpp" />
@@ -235,8 +235,8 @@
<Unit filename="src\gui\updatewindow.h" />
<Unit filename="src\gui\viewport.cpp" />
<Unit filename="src\gui\viewport.h" />
- <Unit filename="src\gui\widgets\avatar.cpp" />
- <Unit filename="src\gui\widgets\avatar.h" />
+ <Unit filename="src\gui\widgets\avatarlistbox.cpp" />
+ <Unit filename="src\gui\widgets\avatarlistbox.h" />
<Unit filename="src\gui\widgets\browserbox.cpp" />
<Unit filename="src\gui\widgets\browserbox.h" />
<Unit filename="src\gui\widgets\button.cpp" />
@@ -257,8 +257,6 @@
<Unit filename="src\gui\widgets\emoteshortcutcontainer.h" />
<Unit filename="src\gui\widgets\flowcontainer.cpp" />
<Unit filename="src\gui\widgets\flowcontainer.h" />
- <Unit filename="src\gui\widgets\guildlistbox.cpp" />
- <Unit filename="src\gui\widgets\guildlistbox.h" />
<Unit filename="src\gui\widgets\icon.cpp" />
<Unit filename="src\gui\widgets\icon.h" />
<Unit filename="src\gui\widgets\inttextfield.cpp" />
@@ -485,6 +483,8 @@
<Unit filename="src\particleemitter.cpp" />
<Unit filename="src\particleemitter.h" />
<Unit filename="src\particleemitterprop.h" />
+ <Unit filename="src\party.cpp" />
+ <Unit filename="src\party.h" />
<Unit filename="src\player.cpp" />
<Unit filename="src\player.h" />
<Unit filename="src\playerrelations.cpp" />
diff --git a/mana.files b/mana.files
index 07489c37..06edd1e2 100644
--- a/mana.files
+++ b/mana.files
@@ -1,10 +1,5 @@
-./build/CMakeCache.txt
-./build/CMakeFiles/CMakeRuleHashes.txt
-./build/CMakeFiles/CompilerIdCXX/CMakeCXXCompilerId.cpp
-./build/CMakeFiles/TargetDirectories.txt
-./build/src/CMakeFiles/mana.dir/link.txt
-./build/src/CMakeFiles/mana-ea.dir/link.txt
./CMakeLists.txt
+./config.h
./data/branding.xml
./data/CMakeLists.txt
./data/fonts/CMakeLists.txt
@@ -46,6 +41,8 @@
./src/animatedsprite.h
./src/animationparticle.cpp
./src/animationparticle.h
+./src/avatar.cpp
+./src/avatar.h
./src/being.cpp
./src/being.h
./src/beingmanager.cpp
@@ -130,8 +127,6 @@
./src/gui/outfitwindow.h
./src/gui/palette.cpp
./src/gui/palette.h
-./src/gui/partywindow.cpp
-./src/gui/partywindow.h
./src/gui/popupmenu.cpp
./src/gui/popupmenu.h
./src/gui/quitdialog.cpp
@@ -166,6 +161,8 @@
./src/gui/skilldialog.h
./src/gui/skin.cpp
./src/gui/skin.h
+./src/gui/socialwindow.cpp
+./src/gui/socialwindow.h
./src/gui/specialswindow.cpp
./src/gui/specialswindow.h
./src/gui/speechbubble.cpp
@@ -186,8 +183,8 @@
./src/gui/updatewindow.h
./src/gui/viewport.cpp
./src/gui/viewport.h
-./src/gui/widgets/avatar.cpp
-./src/gui/widgets/avatar.h
+./src/gui/widgets/avatarlistbox.cpp
+./src/gui/widgets/avatarlistbox.h
./src/gui/widgets/browserbox.cpp
./src/gui/widgets/browserbox.h
./src/gui/widgets/button.cpp
@@ -432,6 +429,8 @@
./src/particleemitter.h
./src/particleemitterprop.h
./src/particle.h
+./src/party.cpp
+./src/party.h
./src/player.cpp
./src/player.h
./src/playerrelations.cpp
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index a7b1322b..221d7d8b 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -101,8 +101,8 @@ MARK_AS_ADVANCED(SDL_INCLUDE_DIR)
MARK_AS_ADVANCED(SDL_LIBRARY)
SET(SRCS
- gui/widgets/avatar.cpp
- gui/widgets/avatar.h
+ gui/widgets/avatarlistbox.cpp
+ gui/widgets/avatarlistbox.h
gui/widgets/browserbox.cpp
gui/widgets/browserbox.h
gui/widgets/button.cpp
@@ -123,8 +123,6 @@ SET(SRCS
gui/widgets/emoteshortcutcontainer.h
gui/widgets/flowcontainer.cpp
gui/widgets/flowcontainer.h
- gui/widgets/guildlistbox.cpp
- gui/widgets/guildlistbox.h
gui/widgets/icon.cpp
gui/widgets/icon.h
gui/widgets/inttextfield.cpp
@@ -220,8 +218,6 @@ SET(SRCS
gui/focushandler.h
gui/gui.cpp
gui/gui.h
- gui/guildwindow.cpp
- gui/guildwindow.h
gui/help.cpp
gui/help.h
gui/inventorywindow.cpp
@@ -246,8 +242,6 @@ SET(SRCS
gui/outfitwindow.h
gui/palette.cpp
gui/palette.h
- gui/partywindow.cpp
- gui/partywindow.h
gui/popupmenu.cpp
gui/popupmenu.h
gui/quitdialog.cpp
@@ -282,6 +276,8 @@ SET(SRCS
gui/skilldialog.h
gui/skin.cpp
gui/skin.h
+ gui/socialwindow.cpp
+ gui/socialwindow.h
gui/speechbubble.cpp
gui/speechbubble.h
gui/specialswindow.cpp
@@ -393,6 +389,8 @@ SET(SRCS
animatedsprite.h
animationparticle.cpp
animationparticle.h
+ avatar.cpp
+ avatar.h
being.cpp
being.h
beingmanager.cpp
@@ -456,6 +454,8 @@ SET(SRCS
particleemitter.cpp
particleemitter.h
particleemitterprop.h
+ party.cpp
+ party.h
player.cpp
player.h
playerrelations.cpp
diff --git a/src/Makefile.am b/src/Makefile.am
index 9d02ea84..3b3773ab 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -6,8 +6,8 @@ mana_CXXFLAGS = -DPKG_DATADIR=\""$(pkgdatadir)/"\" \
-DLOCALEDIR=\""$(localedir)"\" \
-Wall
-mana_SOURCES = gui/widgets/avatar.cpp \
- gui/widgets/avatar.h \
+mana_SOURCES = gui/widgets/avatarlistbox.cpp \
+ gui/widgets/avatarlistbox.h \
gui/widgets/browserbox.cpp \
gui/widgets/browserbox.h \
gui/widgets/button.cpp \
@@ -28,8 +28,6 @@ mana_SOURCES = gui/widgets/avatar.cpp \
gui/widgets/emoteshortcutcontainer.h \
gui/widgets/flowcontainer.cpp \
gui/widgets/flowcontainer.h \
- gui/widgets/guildlistbox.cpp \
- gui/widgets/guildlistbox.h \
gui/widgets/icon.cpp \
gui/widgets/icon.h \
gui/widgets/inttextfield.cpp \
@@ -125,8 +123,6 @@ mana_SOURCES = gui/widgets/avatar.cpp \
gui/focushandler.h \
gui/gui.cpp \
gui/gui.h \
- gui/guildwindow.cpp \
- gui/guildwindow.h \
gui/help.cpp \
gui/help.h \
gui/inventorywindow.cpp \
@@ -151,8 +147,6 @@ mana_SOURCES = gui/widgets/avatar.cpp \
gui/outfitwindow.h \
gui/palette.cpp \
gui/palette.h \
- gui/partywindow.cpp \
- gui/partywindow.h \
gui/popupmenu.cpp \
gui/popupmenu.h \
gui/quitdialog.cpp \
@@ -187,6 +181,8 @@ mana_SOURCES = gui/widgets/avatar.cpp \
gui/skilldialog.h \
gui/skin.cpp \
gui/skin.h \
+ gui/socialwindow.cpp \
+ gui/socialwindow.h \
gui/speechbubble.cpp \
gui/speechbubble.h \
gui/specialswindow.cpp \
@@ -298,6 +294,8 @@ mana_SOURCES = gui/widgets/avatar.cpp \
animatedsprite.h \
animationparticle.cpp \
animationparticle.h \
+ avatar.cpp \
+ avatar.h \
being.cpp \
being.h \
beingmanager.cpp \
@@ -361,6 +359,8 @@ mana_SOURCES = gui/widgets/avatar.cpp \
particleemitter.cpp \
particleemitter.h \
particleemitterprop.h \
+ party.cpp \
+ party.h \
player.cpp \
player.h \
playerrelations.cpp \
diff --git a/src/avatar.cpp b/src/avatar.cpp
new file mode 100644
index 00000000..3f4dd5d7
--- /dev/null
+++ b/src/avatar.cpp
@@ -0,0 +1,33 @@
+/*
+ * The Mana World
+ * Copyright (C) 2008 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "avatar.h"
+
+#include "localplayer.h"
+
+#include <sstream>
+
+Avatar::Avatar(const std::string &name):
+ mName(name),
+ mHp(0), mMaxHp(0),
+ mDisplayBold(false)
+{
+}
diff --git a/src/gui/widgets/avatar.h b/src/avatar.h
index 8d6dd928..8c0e935a 100644
--- a/src/gui/widgets/avatar.h
+++ b/src/avatar.h
@@ -22,30 +22,22 @@
#ifndef AVATAR_H
#define AVATAR_H
-#include "guichanfwd.h"
-
-#include "gui/widgets/container.h"
-
#include <string>
-class Image;
-class Icon;
-
-class Avatar : public Container
+class Avatar
{
public:
- Avatar();
- ~Avatar();
+ Avatar(const std::string &name = "");
/**
* Returns the avatar's name.
*/
- std::string getName() const { return mName; };
+ std::string getName() const { return mName; }
/**
* Set the avatar's name.
*/
- void setName(const std::string &name);
+ void setName(const std::string &name) { mName = name; }
/**
* Returns the avatar's online status.
@@ -55,28 +47,24 @@ public:
/**
* Set the avatar's online status.
*/
- void setOnline(bool online);
+ void setOnline(bool online) { mOnline = online; }
int getHp() const { return mHp; }
- void setHp(int hp);
+ void setHp(int hp) { mHp = hp; }
int getMaxHp() const { return mMaxHp; }
- void setMaxHp(int maxHp);
+ void setMaxHp(int maxHp) { mMaxHp = maxHp; }
bool getDisplayBold() const { return mDisplayBold; }
- void setDisplayBold(bool displayBold) { mDisplayBold = displayBold; updateAvatarLabel(); }
+ void setDisplayBold(bool displayBold) { mDisplayBold = displayBold; }
private:
- void updateAvatarLabel();
-
std::string mName;
int mHp;
int mMaxHp;
- Icon *mStatus;
- gcn::Label *mLabel;
bool mOnline;
bool mDisplayBold;
};
diff --git a/src/game.cpp b/src/game.cpp
index ea1979be..900a6794 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -54,23 +54,22 @@
#include "gui/minimap.h"
#include "gui/ministatus.h"
#include "gui/npcdialog.h"
+#include "gui/npcpostdialog.h"
#include "gui/okdialog.h"
#include "gui/outfitwindow.h"
+#include "gui/quitdialog.h"
#include "gui/sdlinput.h"
#include "gui/sell.h"
#include "gui/setup.h"
+#include "gui/socialwindow.h"
+#include "gui/specialswindow.h"
+#include "gui/storagewindow.h"
#include "gui/skilldialog.h"
#include "gui/statuswindow.h"
#include "gui/textdialog.h"
#include "gui/trade.h"
#include "gui/viewport.h"
#include "gui/windowmenu.h"
-#include "gui/partywindow.h"
-#include "gui/guildwindow.h"
-#include "gui/npcpostdialog.h"
-#include "gui/quitdialog.h"
-#include "gui/specialswindow.h"
-#include "gui/storagewindow.h"
#include "gui/widgets/chattab.h"
#include "gui/widgets/emoteshortcutcontainer.h"
@@ -118,8 +117,6 @@ SellDialog *sellDialog;
BuySellDialog *buySellDialog;
InventoryWindow *inventoryWindow;
SkillDialog *skillDialog;
-PartyWindow *partyWindow;
-GuildWindow *guildWindow;
NpcDialog *npcDialog;
NpcPostDialog *npcPostDialog;
StorageWindow *storageWindow;
@@ -132,6 +129,7 @@ ShortcutWindow *itemShortcutWindow;
ShortcutWindow *emoteShortcutWindow;
OutfitWindow *outfitWindow;
SpecialsWindow *specialsWindow;
+SocialWindow *socialWindow;
BeingManager *beingManager = NULL;
FloorItemManager *floorItemManager = NULL;
@@ -218,8 +216,6 @@ static void createGuiWindows()
buyDialog = new BuyDialog;
sellDialog = new SellDialog;
tradeWindow = new TradeWindow;
- partyWindow = new PartyWindow;
- guildWindow = new GuildWindow;
buySellDialog = new BuySellDialog;
equipmentWindow = new EquipmentWindow(player_node->mEquipment.get());
npcDialog = new NpcDialog;
@@ -238,6 +234,7 @@ static void createGuiWindows()
new EmoteShortcutContainer);
outfitWindow = new OutfitWindow();
specialsWindow = new SpecialsWindow();
+ socialWindow = new SocialWindow();
localChatTab = new ChatTab(_("General"));
@@ -258,29 +255,28 @@ static void destroyGuiWindows()
{
Net::getGeneralHandler()->guiWindowsUnloaded();
logger->setChatWindow(NULL);
- del_0(localChatTab); // Need to do this first, so it can remove itself
- del_0(chatWindow);
- del_0(statusWindow);
- del_0(miniStatusWindow);
- del_0(buyDialog);
- del_0(sellDialog);
- del_0(buySellDialog);
- del_0(inventoryWindow);
- del_0(partyWindow);
- del_0(npcDialog);
- del_0(npcPostDialog);
- del_0(guildWindow);
- del_0(skillDialog);
- del_0(minimap);
- del_0(equipmentWindow);
- del_0(tradeWindow);
- del_0(helpWindow);
- del_0(debugWindow);
- del_0(itemShortcutWindow);
- del_0(emoteShortcutWindow);
- del_0(storageWindow);
- del_0(outfitWindow);
- del_0(specialsWindow);
+ del_0(localChatTab) // Need to do this first, so it can remove itself
+ del_0(chatWindow)
+ del_0(statusWindow)
+ del_0(miniStatusWindow)
+ del_0(buyDialog)
+ del_0(sellDialog)
+ del_0(buySellDialog)
+ del_0(inventoryWindow)
+ del_0(npcDialog)
+ del_0(npcPostDialog)
+ del_0(skillDialog)
+ del_0(minimap)
+ del_0(equipmentWindow)
+ del_0(tradeWindow)
+ del_0(helpWindow)
+ del_0(debugWindow)
+ del_0(itemShortcutWindow)
+ del_0(emoteShortcutWindow)
+ del_0(storageWindow)
+ del_0(outfitWindow)
+ del_0(specialsWindow)
+ del_0(socialWindow)
}
Game *Game::mInstance = 0;
@@ -795,7 +791,7 @@ void Game::handleInput()
equipmentWindow->setVisible(false);
helpWindow->setVisible(false);
debugWindow->setVisible(false);
- guildWindow->setVisible(false);
+ socialWindow->setVisible(false);
}
break;
case KeyboardConfig::KEY_WINDOW_STATUS:
@@ -825,8 +821,8 @@ void Game::handleInput()
case KeyboardConfig::KEY_WINDOW_DEBUG:
requestedWindow = debugWindow;
break;
- case KeyboardConfig::KEY_WINDOW_PARTY:
- requestedWindow = partyWindow;
+ case KeyboardConfig::KEY_WINDOW_SOCIAL:
+ requestedWindow = socialWindow;
break;
case KeyboardConfig::KEY_WINDOW_EMOTE_SHORTCUT:
requestedWindow = emoteShortcutWindow;
diff --git a/src/gui/chat.cpp b/src/gui/chat.cpp
index 1c18a438..0377dbf8 100644
--- a/src/gui/chat.cpp
+++ b/src/gui/chat.cpp
@@ -24,11 +24,11 @@
#include "beingmanager.h"
#include "configuration.h"
#include "localplayer.h"
+#include "party.h"
#include "gui/recorder.h"
#include "gui/setup.h"
#include "gui/sdlinput.h"
-#include "gui/partywindow.h"
#include "gui/widgets/chattab.h"
#include "gui/widgets/itemlinkhandler.h"
@@ -75,8 +75,7 @@ class ChatInput : public TextField, public gcn::FocusListener
ChatWindow::ChatWindow():
Window(_("Chat")),
- mTmpVisible(false),
- mCurrentTab(NULL)
+ mTmpVisible(false)
{
setWindowName("Chat");
@@ -128,15 +127,6 @@ void ChatWindow::resetToDefaultSize()
Window::resetToDefaultSize();
}
-void ChatWindow::logic()
-{
- Window::logic();
-
- Tab *tab = getFocused();
- if (tab != mCurrentTab)
- mCurrentTab = tab;
-}
-
ChatTab *ChatWindow::getFocused() const
{
return dynamic_cast<ChatTab*>(mChatTabs->getSelectedTab());
@@ -338,7 +328,7 @@ void ChatWindow::mousePressed(gcn::MouseEvent &event)
if (event.isConsumed())
return;
- mMoved = event.getY() <= mCurrentTab->getHeight();
+ mMoved = event.getY() <= getFocused()->getHeight();
mDragOffsetX = event.getX();
mDragOffsetY = event.getY();
@@ -533,7 +523,11 @@ void ChatWindow::autoComplete()
std::vector<std::string> nameList;
if (cTab && cTab->getType() == ChatTab::PARTY)
{
- partyWindow->getNames(nameList);
+ Party *p = player_node->getParty();
+
+ if (p) // Shouldn't be needed, but lets be safe
+ p->getNames(nameList);
+
newName = autoComplete(nameList, name);
}
if (newName == "")
diff --git a/src/gui/chat.h b/src/gui/chat.h
index cd9b6170..cc48b78a 100644
--- a/src/gui/chat.h
+++ b/src/gui/chat.h
@@ -75,8 +75,6 @@ class ChatWindow : public Window,
*/
~ChatWindow();
- void logic();
-
/**
* Reset the chat window and recorder window attached to it to their
* default positions.
@@ -207,7 +205,6 @@ class ChatWindow : public Window,
/** Tabbed area for holding each channel. */
TabbedArea *mChatTabs;
- Tab *mCurrentTab;
typedef std::map<const std::string, ChatTab*> TabMap;
/** Manage whisper tabs */
diff --git a/src/gui/confirmdialog.cpp b/src/gui/confirmdialog.cpp
index b38e801b..79e3bec1 100644
--- a/src/gui/confirmdialog.cpp
+++ b/src/gui/confirmdialog.cpp
@@ -79,12 +79,8 @@ ConfirmDialog::ConfirmDialog(const std::string &title, const std::string &msg,
void ConfirmDialog::action(const gcn::ActionEvent &event)
{
- // Proxy button events to our listeners
- ActionListenerIterator i;
- for (i = mActionListeners.begin(); i != mActionListeners.end(); ++i)
- {
- (*i)->action(event);
- }
+ setActionEventId(event.getId());
+ distributeActionEvent();
// Can we receive anything else anyway?
if (event.getId() == "yes" || event.getId() == "no")
diff --git a/src/gui/guildwindow.cpp b/src/gui/guildwindow.cpp
deleted file mode 100644
index 94646261..00000000
--- a/src/gui/guildwindow.cpp
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * The Mana World
- * Copyright (C) 2004-2010 The Mana World Development Team
- *
- * This file is part of The Mana World.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * $$
- */
-
-#include "gui/guildwindow.h"
-
-#include "guild.h"
-#include "log.h"
-#include "localplayer.h"
-
-#include "gui/confirmdialog.h"
-#include "gui/setup.h"
-#include "gui/textdialog.h"
-
-#include "gui/widgets/button.h"
-#include "gui/widgets/chattab.h"
-#include "gui/widgets/guildlistbox.h"
-#include "gui/widgets/layout.h"
-#include "gui/widgets/scrollarea.h"
-#include "gui/widgets/tabbedarea.h"
-#include "gui/widgets/windowcontainer.h"
-
-#include "net/guildhandler.h"
-#include "net/net.h"
-
-#include "utils/dtor.h"
-#include "utils/gettext.h"
-#include "utils/stringutils.h"
-
-#include <guichan/widgets/tab.hpp>
-
-#include <algorithm>
-
-GuildWindow::GuildWindow():
- Window(_("Guild")),
- mFocus(false)
-{
- setWindowName("Guild");
- setCaption(_("Guild"));
- setResizable(false);
- setCloseButton(true);
- setSaveVisible(true);
- setMinWidth(200);
- setMinHeight(280);
- setDefaultSize(124, 41, 288, 330);
- setupWindow->registerWindowForReset(this);
-
- // Set button events Id
- mGuildButton[0] = new Button(_("Create Guild"), "CREATE_GUILD", this);
- mGuildButton[1] = new Button(_("Invite User"), "INVITE_USER", this);
- mGuildButton[2] = new Button(_("Quit Guild"), "QUIT_GUILD", this);
- mGuildButton[1]->setEnabled(false);
- mGuildButton[2]->setEnabled(false);
-
- mGuildTabs = new TabbedArea;
-
- place(0, 0, mGuildButton[0]);
- place(1, 0, mGuildButton[1]);
- place(2, 0, mGuildButton[2]);
- place(0, 1, mGuildTabs);
- Layout &layout = getLayout();
- layout.setColWidth(0, 48);
- layout.setColWidth(1, 65);
-
- loadWindowState();
-}
-
-GuildWindow::~GuildWindow()
-{
-}
-
-void GuildWindow::update()
-{
- updateTab();
-
- if (mGuildButton[2]->isEnabled() && mGuildTabs->getNumberOfTabs() <= 0)
- {
- mGuildButton[2]->setEnabled(false);
- mGuildButton[1]->setEnabled(false);
- }
-}
-
-void GuildWindow::draw(gcn::Graphics *g)
-{
- update();
-
- Window::draw(g);
-}
-
-void GuildWindow::action(const gcn::ActionEvent &event)
-{
- const std::string &eventId = event.getId();
-
- // Stats Part
- if (eventId == "CREATE_GUILD")
- {
- // Set focus so that guild name to be created can be typed.
- mFocus = true;
- guildDialog = new TextDialog(_("Guild Name"),
- _("Choose your guild's name."), this);
- guildDialog->setOKButtonActionId("CREATE_GUILD_OK");
- guildDialog->addActionListener(this);
- }
- else if (eventId == "INVITE_USER")
- {
- // TODO - Give feedback on whether the invite succeeded
- mFocus = true;
- inviteDialog = new TextDialog(_("Member Invite"),
- _("Who would you like to invite?"), this);
- inviteDialog->setOKButtonActionId("INVITE_USER_OK");
- inviteDialog->addActionListener(this);
- }
- else if (eventId == "QUIT_GUILD")
- {
- short guild = getSelectedGuild();
- if (guild)
- {
- Net::getGuildHandler()->leave(guild);
- localChatTab->chatLog(strprintf(_("Guild %s quit."),
- mGuildTabs->getSelectedTab()->getCaption().c_str()), BY_SERVER);
- }
- }
- else if (eventId == "CREATE_GUILD_OK")
- {
- std::string name = guildDialog->getText();
- if (name.size() > 16)
- {
- // TODO : State too many characters in input.
- return;
- }
- // Process guild name to be created, and unfocus.
- Net::getGuildHandler()->create(name);
-
- // Defocus dialog
- mFocus = false;
- localChatTab->chatLog(strprintf(_("Creating guild called %s."),
- name.c_str()), BY_SERVER);
- guildDialog->scheduleDelete();
- }
- else if (eventId == "INVITE_USER_OK")
- {
- std::string name = inviteDialog->getText();
- short selectedGuild = getSelectedGuild();
-
- // Process invited user to be created and unfocus.
- Net::getGuildHandler()->invite(selectedGuild, name);
-
- // Defocus dialog
- mFocus = false;
- localChatTab->chatLog(strprintf(_("Invited user %s."), name.c_str()), BY_SERVER);
- inviteDialog->scheduleDelete();
- }
- else if (eventId == "yes")
- {
- logger->log("Sending invitation acceptance.");
- Net::getGuildHandler()->inviteResponse(invitedGuildId, true);
- }
-}
-
-void GuildWindow::newGuildTab(const std::string &guildName)
-{
- // Create new tab
- GuildListBox *list = new GuildListBox;
- list->setListModel(player_node->getGuild(guildName));
- ScrollArea *sa = new ScrollArea(list);
- sa->setDimension(gcn::Rectangle(5, 5, 135, 250));
-
- // Add the listbox to the map
- mGuildLists.insert(std::pair<std::string, GuildListBox*>(guildName, list));
-
- mGuildTabs->addTab(guildName, sa);
- mGuildTabs->setDimension(gcn::Rectangle(28,35,140,250));
-
- updateTab();
-}
-
-void GuildWindow::updateTab()
-{
- gcn::Tab *tab = mGuildTabs->getSelectedTab();
- if (tab)
- {
- setTab(tab->getCaption());
- }
- mGuildTabs->logic();
-}
-
-void GuildWindow::setTab(const std::string &guildName)
-{
- // Only enable invite button if user has rights
- if (player_node->checkInviteRights(guildName))
- {
- mGuildButton[1]->setEnabled(true);
- }
- else
- {
- mGuildButton[1]->setEnabled(false);
- }
-
- mGuildButton[2]->setEnabled(true);
-}
-
-bool GuildWindow::isWindowFocused()
-{
- return mFocus;
-}
-
-short GuildWindow::getSelectedGuild()
-{
- if (mGuildTabs->getNumberOfTabs() > 0)
- {
-
- Guild *guild = player_node->getGuild(mGuildTabs->getSelectedTab()->getCaption());
-
- if (guild)
- {
- return guild->getId();
- }
- }
-
- return 0;
-}
-
-void GuildWindow::openAcceptDialog(const std::string &inviterName,
- const std::string &guildName,
- const int guildId)
-{
- std::string msg = strprintf(_("%s has invited you to join the guild %s."),
- inviterName.c_str(), guildName.c_str());
- localChatTab->chatLog(msg, BY_SERVER);
-
- acceptDialog = new ConfirmDialog(_("Accept Guild Invite"), msg, this);
- acceptDialog->addActionListener(this);
-
- invitedGuildId = guildId;
-}
-
-void GuildWindow::requestMemberList(short guildId)
-{
- // Get the list of members for displaying in the guild window.
- Net::getGuildHandler()->memberList(guildId);
-}
-
-void GuildWindow::removeTab(int guildId)
-{
- Guild* guild = player_node->getGuild(guildId);
- if (guild)
- {
- Tab *tab = mGuildTabs->getTab(guild->getName());
- if (tab)
- {
- mGuildTabs->removeTab(tab);
- }
- updateTab();
- }
- mGuildTabs->logic();
-}
-
-void GuildWindow::setOnline(const std::string &guildName, const std::string &member,
- bool online)
-{
- GuildListMap::iterator itr = mGuildLists.find(guildName);
- if (itr != mGuildLists.end())
- {
- itr->second->setOnlineStatus(member, online);
- }
-}
diff --git a/src/gui/guildwindow.h b/src/gui/guildwindow.h
deleted file mode 100644
index e0a28694..00000000
--- a/src/gui/guildwindow.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * The Mana World
- * Copyright (C) 2008-2010 The Mana World Development Team
- *
- * This file is part of The Mana World.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef GUI_GUILDWINDOW_H
-#define GUI_GUILDWINDOW_H
-
-#include "guichanfwd.h"
-
-#include "gui/widgets/window.h"
-
-#include <guichan/actionlistener.hpp>
-
-#include <guichan/widgets/listbox.hpp>
-
-#include <iosfwd>
-#include <map>
-#include <vector>
-
-class LocalPlayer;
-class TextDialog;
-class ConfirmDialog;
-class GuildListBox;
-class ScrollArea;
-class TabbedArea;
-
-class GuildWindow : public Window, public gcn::ActionListener
-{
-public:
- GuildWindow();
- ~GuildWindow();
-
- /**
- * Called when receiving actions from widget.
- */
- void action(const gcn::ActionEvent &event);
-
- /**
- * Draw this window.
- */
- void draw(gcn::Graphics *graphics);
-
- /**
- * Updates this dialog.
- */
- void update();
-
- /**
- * Create a new tab for a guild list.
- */
- void newGuildTab(const std::string &guildName);
-
- /**
- * Display guild's member list to active tab
- */
- void setTab(const std::string &guildName);
-
- /**
- * Update the contents of the active tab
- */
- void updateTab();
-
- /**
- * Check if the window is in focus.
- */
- bool isWindowFocused();
-
- /**
- * Create a dialog for accepting an invite
- */
- void openAcceptDialog(const std::string &inviterName,
- const std::string &guildName, const int guildId);
-
- /**
- * Request member list
- */
- void requestMemberList(short guildId);
-
- /**
- * Removes the selected tab
- */
- void removeTab(int guildId);
-
- /**
- * Set guild member status in userlist
- */
- void setOnline(const std::string &guildName, const std::string &member,
- bool online);
-
-protected:
- /**
- * Get selected guild tab
- * @return Returns selected guild
- */
- short getSelectedGuild();
-
-private:
- gcn::Button *mGuildButton[3];
- TextDialog *guildDialog;
- TextDialog *inviteDialog;
- ConfirmDialog *acceptDialog;
- TabbedArea *mGuildTabs;
- ScrollArea *mScrollArea;
- bool mFocus;
- int invitedGuildId;
- typedef std::map<std::string, GuildListBox*> GuildListMap;
- GuildListMap mGuildLists;
-};
-
-extern GuildWindow *guildWindow;
-
-#endif
diff --git a/src/gui/okdialog.cpp b/src/gui/okdialog.cpp
index 512a9994..3693f3e9 100644
--- a/src/gui/okdialog.cpp
+++ b/src/gui/okdialog.cpp
@@ -69,12 +69,8 @@ OkDialog::OkDialog(const std::string &title, const std::string &msg,
void OkDialog::action(const gcn::ActionEvent &event)
{
- // Proxy button events to our listeners
- ActionListenerIterator i;
- for (i = mActionListeners.begin(); i != mActionListeners.end(); ++i)
- {
- (*i)->action(event);
- }
+ setActionEventId(event.getId());
+ distributeActionEvent();
// Can we receive anything else anyway?
if (event.getId() == "ok")
diff --git a/src/gui/partywindow.cpp b/src/gui/partywindow.cpp
deleted file mode 100644
index e5cac08f..00000000
--- a/src/gui/partywindow.cpp
+++ /dev/null
@@ -1,274 +0,0 @@
-/*
- * The Mana World
- * Copyright (C) 2008-2010 The Mana World Development Team
- *
- * This file is part of The Mana World.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "gui/partywindow.h"
-
-#include "beingmanager.h"
-#include "player.h"
-
-#include "gui/setup.h"
-
-#include "gui/widgets/chattab.h"
-
-#include "net/net.h"
-#include "net/partyhandler.h"
-
-#include "utils/dtor.h"
-#include "utils/gettext.h"
-#include "utils/stringutils.h"
-
-PartyMember::PartyMember():
- mAvatar(new Avatar)
-{
-}
-
-PartyMember::~PartyMember()
-{
- delete mAvatar;
-}
-
-void PartyMember::setLeader(bool leader)
-{
- if (mLeader != leader)
- {
- mLeader = leader;
- mAvatar->setDisplayBold(leader);
- }
-}
-
-
-PartyWindow::PartyWindow() :
- Window(_("Party"))
-{
- setWindowName("Party");
- setVisible(false);
- setSaveVisible(true);
- setResizable(true);
- setSaveVisible(true);
- setCloseButton(true);
- setMinWidth(120);
- setMinHeight(55);
- setDefaultSize(590, 200, 150, 60);
- setupWindow->registerWindowForReset(this);
-
- loadWindowState();
-}
-
-PartyWindow::~PartyWindow()
-{
- delete_all(mMembers);
-}
-
-void PartyWindow::setPartyName(const std::string &name)
-{
- setCaption(strprintf(_("Party (%s)"), name.c_str()));
-}
-
-void PartyWindow::clearPartyName()
-{
- setCaption(_("Party"));
-}
-
-PartyMember *PartyWindow::findMember(int id) const
-{
- PartyList::const_iterator it = mMembers.find(id);
- if (it == mMembers.end())
- return NULL;
- else
- return it->second;
-}
-
-PartyMember *PartyWindow::findOrCreateMember(int id)
-{
- PartyMember *member = findMember(id);
-
- if (!member)
- {
- member = new PartyMember;
- mMembers[id] = member;
- }
-
- buildLayout();
-
- return member;
-}
-
-int PartyWindow::findMember(const std::string &name) const
-{
- PartyList::const_iterator itr = mMembers.begin(),
- itr_end = mMembers.end();
-
- while (itr != itr_end)
- {
- if ((*itr).second->mAvatar->getName() == name)
- {
- return (*itr).first;
- }
- ++itr;
- }
-
- return -1;
-}
-
-void PartyWindow::updateMember(int id, const std::string &memberName,
- bool leader, bool online)
-{
- PartyMember *member = findOrCreateMember(id);
- member->mAvatar->setName(memberName);
- member->setLeader(leader);
- member->mAvatar->setOnline(online);
-
- Player *player = dynamic_cast<Player*>(beingManager->findBeing(id));
- if (player && online)
- player->setInParty(true);
-}
-
-void PartyWindow::updateMemberHP(int id, int hp, int maxhp)
-{
- PartyMember *player = findOrCreateMember(id);
- player->mAvatar->setHp(hp);
- player->mAvatar->setMaxHp(maxhp);
-}
-
-void PartyWindow::removeMember(int id)
-{
- mMembers.erase(id);
-
- if (Player *player = dynamic_cast<Player*>(beingManager->findBeing(id)))
- player->setInParty(false);
-}
-
-void PartyWindow::removeMember(const std::string &name)
-{
- removeMember(findMember(name));
-
- buildLayout();
-}
-
-void PartyWindow::updateOnlne(int id, bool online)
-{
- PartyMember *player = findMember(id);
-
- if (!player)
- return;
-
- player->mAvatar->setOnline(online);
-}
-
-void PartyWindow::showPartyInvite(const std::string &inviter,
- const std::string &partyName)
-{
- // check there isnt already an invite showing
- if (mPartyInviter != "")
- {
- localChatTab->chatLog(_("Received party request, but one already "
- "exists."), BY_SERVER);
- return;
- }
-
- std::string msg;
- // log invite
- if (partyName.empty())
- msg = strprintf(N_("%s has invited you to join their party."),
- inviter.c_str());
- else
- msg = strprintf(N_("%s has invited you to join the %s party."),
- inviter.c_str(), partyName.c_str());
-
- localChatTab->chatLog(msg, BY_SERVER);
-
- // show invite
- acceptDialog = new ConfirmDialog(_("Accept Party Invite"), msg, this);
- acceptDialog->addActionListener(this);
-
- mPartyInviter = inviter;
-}
-
-void PartyWindow::action(const gcn::ActionEvent &event)
-{
- const std::string &eventId = event.getId();
-
- // check if they accepted the invite
- if (eventId == "yes")
- {
- localChatTab->chatLog(strprintf(_("Accepted invite from %s."),
- mPartyInviter.c_str()));
- Net::getPartyHandler()->inviteResponse(mPartyInviter, true);
- mPartyInviter = "";
- }
- else if (eventId == "no")
- {
- localChatTab->chatLog(strprintf(_("Rejected invite from %s."),
- mPartyInviter.c_str()));
- Net::getPartyHandler()->inviteResponse(mPartyInviter, false);
- mPartyInviter = "";
- }
-}
-
-void clearMembersSub(const std::pair<int, PartyMember*> &p)
-{
- Player *player = dynamic_cast<Player*>(beingManager->findBeing(p.first));
- if (player)
- player->setInParty(false);
-}
-
-void PartyWindow::clearMembers()
-{
- clearLayout();
-
- std::for_each(mMembers.begin(), mMembers.end(), clearMembersSub);
-
- delete_all(mMembers);
- mMembers.clear();
-}
-
-void PartyWindow::buildLayout()
-{
- clearLayout();
- int lastPos = 0;
-
- PartyList::iterator it;
- PartyMember *member;
-
- for (it = mMembers.begin(); it != mMembers.end(); it++)
- {
- member = (*it).second;
- add(member->mAvatar, 0, lastPos);
- lastPos += member->mAvatar->getHeight() + 2;
- }
-}
-
-void PartyWindow::getNames(std::vector<std::string> &names)
-{
- PartyList::iterator i = mMembers.begin();
- names.clear();
-
- while (i != mMembers.end())
- {
- PartyMember *member = (*i).second;
- if (member->getAvatar() && member->getAvatar()->getName() != "")
- {
- std::string name = member->getAvatar()->getName();
- names.push_back(name);
- }
- ++i;
- }
-}
diff --git a/src/gui/partywindow.h b/src/gui/partywindow.h
deleted file mode 100644
index 4a423f8b..00000000
--- a/src/gui/partywindow.h
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * The Mana World
- * Copyright (C) 2008-2010 The Mana World Development Team
- *
- * This file is part of The Mana World.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef PARTYWINDOW_H
-#define PARTYWINDOW_H
-
-#include "gui/confirmdialog.h"
-
-#include "gui/widgets/avatar.h"
-#include "gui/widgets/window.h"
-
-#include <guichan/actionevent.hpp>
-#include <guichan/actionlistener.hpp>
-
-#include <string>
-#include <map>
-#include <vector>
-
-class PartyWindow;
-
-/**
- * Party Member
- * Used for storing players in the party
- */
-class PartyMember
-{
- public:
- PartyMember();
- ~PartyMember();
-
- Avatar *getAvatar() const { return mAvatar; }
-
- bool getLeader() const { return mLeader; }
-
- void setLeader(bool leader);
-
- private:
- friend class PartyWindow;
- bool mLeader;
- Avatar *mAvatar;
-};
-
-
-/**
- * Party window.
- *
- * \ingroup Interface
- */
-class PartyWindow : public Window, gcn::ActionListener
-{
- public:
- PartyWindow();
-
- /**
- * Release all the players created.
- */
- ~PartyWindow();
-
- void setPartyName(const std::string &name);
-
- void clearPartyName();
-
- /**
- * Find a party member based on ID. Returns NULL if not found.
- */
- PartyMember *findMember(int id) const;
-
- /**
- * Returns the id of the first member found with the given name or -1
- * if it isn't found.
- */
- int findMember(const std::string &name) const;
-
- /**
- * Update/add a party member.
- */
- void updateMember(int id, const std::string &memberName,
- bool leader = false, bool online = true);
-
- /**
- * Update a member's HP and Max HP
- */
- void updateMemberHP(int id, int hp, int maxhp);
-
- /**
- * Remove party member with the given id.
- */
- void removeMember(int id);
-
- /**
- * Remove party member with the given name.
- */
- void removeMember(const std::string &name);
-
- /**
- * Updates the online state of the member with the given id.
- */
- void updateOnlne(int id, bool online);
-
- /**
- * Show party invite.
- */
- void showPartyInvite(const std::string &inviter,
- const std::string &partyName = "");
-
- /**
- * Handle events.
- */
- void action(const gcn::ActionEvent &event);
-
- void clearMembers();
-
- void getNames(std::vector<std::string> &names);
-
- private:
- /**
- * Find a party member based on ID. Creates if not found.
- */
- PartyMember *findOrCreateMember(int id);
-
- void buildLayout();
-
- typedef std::map<int, PartyMember*> PartyList;
- PartyList mMembers;
- std::string mPartyInviter;
- ConfirmDialog *acceptDialog;
-};
-
-extern PartyWindow *partyWindow;
-
-#endif
diff --git a/src/gui/socialwindow.cpp b/src/gui/socialwindow.cpp
new file mode 100644
index 00000000..67a9474a
--- /dev/null
+++ b/src/gui/socialwindow.cpp
@@ -0,0 +1,570 @@
+/*
+ * The Mana World
+ * Copyright (C) 2010 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "gui/socialwindow.h"
+
+#include "beingmanager.h"
+#include "guild.h"
+#include "localplayer.h"
+#include "party.h"
+#include "player.h"
+
+#include "gui/confirmdialog.h"
+#include "gui/okdialog.h"
+#include "gui/setup.h"
+#include "gui/textdialog.h"
+
+#include "gui/widgets/avatarlistbox.h"
+#include "gui/widgets/browserbox.h"
+#include "gui/widgets/button.h"
+#include "gui/widgets/chattab.h"
+#include "gui/widgets/container.h"
+#include "gui/widgets/label.h"
+#include "gui/widgets/layouthelper.h"
+#include "gui/widgets/linkhandler.h"
+#include "gui/widgets/popup.h"
+#include "gui/widgets/scrollarea.h"
+#include "gui/widgets/tab.h"
+#include "gui/widgets/tabbedarea.h"
+
+#include "net/net.h"
+#include "net/guildhandler.h"
+#include "net/partyhandler.h"
+
+#include "utils/dtor.h"
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+class SocialTab : public Tab
+{
+protected:
+ friend class SocialWindow;
+
+ SocialTab():
+ mInviteDialog(NULL),
+ mConfirmDialog(NULL)
+ {}
+
+ ~SocialTab()
+ {
+ // Cleanup dialogs
+ if (mInviteDialog)
+ {
+ mInviteDialog->close();
+ mInviteDialog->scheduleDelete();
+ mInviteDialog = NULL;
+ }
+
+ if (mConfirmDialog)
+ {
+ mConfirmDialog->close();
+ mConfirmDialog->scheduleDelete();
+ mConfirmDialog = NULL;
+ }
+ }
+
+ virtual void invite() = 0;
+
+ virtual void leave() = 0;
+
+ TextDialog *mInviteDialog;
+ ConfirmDialog *mConfirmDialog;
+ ScrollArea *mScroll;
+ AvatarListBox *mList;
+};
+
+class GuildTab : public SocialTab, public gcn::ActionListener
+{
+public:
+ GuildTab(Guild *guild):
+ mGuild(guild)
+ {
+ setCaption(guild->getName());
+
+ mList = new AvatarListBox(guild);
+ mScroll = new ScrollArea(mList);
+
+ mScroll->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_AUTO);
+ mScroll->setVerticalScrollPolicy(gcn::ScrollArea::SHOW_ALWAYS);
+ }
+
+ void action(const gcn::ActionEvent &event)
+ {
+ if (event.getId() == "do invite")
+ {
+ std::string name = mInviteDialog->getText();
+ Net::getGuildHandler()->invite(mGuild->getId(), name);
+
+ localChatTab->chatLog(strprintf(_("Invited user %s to guild %s."),
+ name.c_str(),
+ mGuild->getName().c_str()),
+ BY_SERVER);
+ mInviteDialog = NULL;
+ }
+ else if (event.getId() == "yes")
+ {
+ Net::getGuildHandler()->leave(mGuild->getId());
+ localChatTab->chatLog(strprintf(_("Guild %s quit requested."),
+ mGuild->getName().c_str()), BY_SERVER);
+ mConfirmDialog = NULL;
+ }
+ }
+
+protected:
+ void invite()
+ {
+ // TODO - Give feedback on whether the invite succeeded
+ mInviteDialog = new TextDialog(_("Member Invite to Guild"),
+ strprintf(_("Who would you like to invite to guild %s?"),
+ mGuild->getName().c_str()),
+ socialWindow);
+ mInviteDialog->setOKButtonActionId("do invite");
+ mInviteDialog->addActionListener(this);
+ }
+
+ void leave()
+ {
+ mConfirmDialog = new ConfirmDialog(_("Leave Guild?"),
+ strprintf(_("Are you sure you want to leave guild %s?"),
+ mGuild->getName().c_str()),
+ socialWindow);
+
+ mConfirmDialog->addActionListener(this);
+ }
+
+private:
+ Guild *mGuild;
+};
+
+class PartyTab : public SocialTab, public gcn::ActionListener
+{
+public:
+ PartyTab(Party *party):
+ mParty(party)
+ {
+ setCaption(party->getName());
+
+ mList = new AvatarListBox(party);
+ mScroll = new ScrollArea(mList);
+
+ mScroll->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_AUTO);
+ mScroll->setVerticalScrollPolicy(gcn::ScrollArea::SHOW_ALWAYS);
+ }
+
+ void action(const gcn::ActionEvent &event)
+ {
+ if (event.getId() == "do invite")
+ {
+ std::string name = mInviteDialog->getText();
+ Net::getPartyHandler()->invite(name);
+
+ localChatTab->chatLog(strprintf(_("Invited user %s to party."),
+ name.c_str()), BY_SERVER);
+ mInviteDialog = NULL;
+ }
+ else if (event.getId() == "yes")
+ {
+ Net::getPartyHandler()->leave();
+ localChatTab->chatLog(strprintf(_("Party %s quit requested."),
+ mParty->getName().c_str()), BY_SERVER);
+ mConfirmDialog = NULL;
+ }
+ }
+
+protected:
+ void invite()
+ {
+ // TODO - Give feedback on whether the invite succeeded
+ mInviteDialog = new TextDialog(_("Member Invite to Party"),
+ strprintf(_("Who would you like to invite to party %s?"),
+ mParty->getName().c_str()),
+ socialWindow);
+ mInviteDialog->setOKButtonActionId("do invite");
+ mInviteDialog->addActionListener(this);
+ }
+
+ void leave()
+ {
+ mConfirmDialog = new ConfirmDialog(_("Leave Party?"),
+ strprintf(_("Are you sure you want to leave party %s?"),
+ mParty->getName().c_str()),
+ socialWindow);
+
+ mConfirmDialog->addActionListener(this);
+ }
+
+private:
+ Party *mParty;
+};
+
+/*class BuddyTab : public SocialTab
+{
+ // TODO?
+};*/
+
+class CreatePopup : public Popup, public LinkHandler
+{
+public:
+ CreatePopup():
+ Popup("SocialCreatePopup")
+ {
+ mBrowserBox = new BrowserBox;
+ mBrowserBox->setPosition(4, 4);
+ mBrowserBox->setHighlightMode(BrowserBox::BACKGROUND);
+ mBrowserBox->setOpaque(false);
+ mBrowserBox->setLinkHandler(this);
+
+ mBrowserBox->addRow(strprintf("@@guild|%s@@", _("Create Guild")));
+ mBrowserBox->addRow(strprintf("@@party|%s@@", _("Create Party")));
+ mBrowserBox->addRow("##3---");
+ mBrowserBox->addRow(strprintf("@@cancel|%s@@", _("Cancel")));
+
+ add(mBrowserBox);
+
+ setContentSize(mBrowserBox->getWidth() + 8,
+ mBrowserBox->getHeight() + 8);
+ }
+
+ void handleLink(const std::string &link)
+ {
+ if (link == "guild")
+ {
+ socialWindow->showGuildCreate();
+ }
+ else if (link == "party")
+ {
+ socialWindow->showPartyCreate();
+ // TODO
+
+ printf("Create party\n");
+ }
+
+ setVisible(false);
+ }
+
+ void show(gcn::Widget *parent)
+ {
+ int x, y;
+ parent->getAbsolutePosition(x, y);
+ y += parent->getHeight();
+ setPosition(x, y);
+ setVisible(true);
+ requestMoveToTop();
+ }
+
+private:
+ BrowserBox* mBrowserBox;
+};
+
+SocialWindow::SocialWindow() :
+ Window(_("Social")),
+ mGuildAcceptDialog(NULL),
+ mPartyAcceptDialog(NULL)
+{
+ setWindowName("Social");
+ setVisible(false);
+ setSaveVisible(true);
+ setResizable(true);
+ setSaveVisible(true);
+ setCloseButton(true);
+ setMinWidth(120);
+ setMinHeight(55);
+ setDefaultSize(590, 200, 150, 60);
+ setupWindow->registerWindowForReset(this);
+
+ loadWindowState();
+
+ mCreateButton = new Button(_("Create"), "create", this);
+ mInviteButton = new Button(_("Invite"), "invite", this);
+ mLeaveButton = new Button(_("Leave"), "leave", this);
+ mTabs = new TabbedArea;
+
+ place(0, 0, mCreateButton);
+ place(1, 0, mInviteButton);
+ place(2, 0, mLeaveButton);
+ place(0, 1, mTabs, 4, 4);
+
+ widgetResized(NULL);
+
+ mCreatePopup = new CreatePopup();
+}
+
+SocialWindow::~SocialWindow()
+{
+ // Cleanup invites
+ if (mGuildAcceptDialog)
+ {
+ mGuildAcceptDialog->close();
+ mGuildAcceptDialog->scheduleDelete();
+ mGuildAcceptDialog = NULL;
+
+ mGuildInvited = 0;
+ }
+
+ if (mPartyAcceptDialog)
+ {
+ mPartyAcceptDialog->close();
+ mPartyAcceptDialog->scheduleDelete();
+ mPartyAcceptDialog = NULL;
+
+ mPartyInviter = "";
+ }
+}
+
+bool SocialWindow::addTab(Guild *guild)
+{
+ if (mGuilds.find(guild) != mGuilds.end())
+ return false;
+
+ GuildTab *tab = new GuildTab(guild);
+ mGuilds[guild] = tab;
+
+ mTabs->addTab(tab, tab->mScroll);
+
+ return true;
+}
+
+bool SocialWindow::removeTab(Guild *guild)
+{
+ GuildMap::iterator it = mGuilds.find(guild);
+ if (it == mGuilds.end())
+ return false;
+
+ mTabs->removeTab(it->second);
+ delete it->second;
+ mGuilds.erase(it);
+
+ return true;
+}
+
+bool SocialWindow::addTab(Party *party)
+{
+ if (mParties.find(party) != mParties.end())
+ return false;
+
+ PartyTab *tab = new PartyTab(party);
+ mParties[party] = tab;
+
+ mTabs->addTab(tab, tab->mScroll);
+
+ return true;
+}
+
+bool SocialWindow::removeTab(Party *party)
+{
+ PartyMap::iterator it = mParties.find(party);
+ if (it == mParties.end())
+ return false;
+
+ mTabs->removeTab(it->second);
+ delete it->second;
+ mParties.erase(it);
+
+ return true;
+}
+
+void SocialWindow::action(const gcn::ActionEvent &event)
+{
+ const std::string &eventId = event.getId();
+
+ if (event.getSource() == mPartyAcceptDialog)
+ {
+ // check if they accepted the invite
+ if (eventId == "yes")
+ {
+ localChatTab->chatLog(strprintf(_("Accepted party invite from %s."),
+ mPartyInviter.c_str()));
+ Net::getPartyHandler()->inviteResponse(mPartyInviter, true);
+ }
+ else if (eventId == "no")
+ {
+ localChatTab->chatLog(strprintf(_("Rejected party invite from %s."),
+ mPartyInviter.c_str()));
+ Net::getPartyHandler()->inviteResponse(mPartyInviter, false);
+ }
+
+ mPartyInviter = "";
+ mPartyAcceptDialog = NULL;
+ }
+ else if (event.getSource() == mGuildAcceptDialog)
+ {
+ // check if they accepted the invite
+ if (eventId == "yes")
+ {
+ localChatTab->chatLog(strprintf(_("Accepted guild invite from %s."),
+ mPartyInviter.c_str()));
+ Net::getGuildHandler()->inviteResponse(mGuildInvited, true);
+ }
+ else if (eventId == "no")
+ {
+ localChatTab->chatLog(strprintf(_("Rejected guild invite from %s."),
+ mPartyInviter.c_str()));
+ Net::getGuildHandler()->inviteResponse(mGuildInvited, false);
+ }
+
+ mGuildInvited = 0;
+ mGuildAcceptDialog = NULL;
+ }
+ else if (event.getId() == "create")
+ {
+ mCreatePopup->show(mCreateButton);
+ }
+ else if (event.getId() == "invite")
+ {
+ SocialTab *tab = dynamic_cast<SocialTab*>(mTabs->getSelectedTab());
+
+ if (tab)
+ {
+ tab->invite();
+ }
+ }
+ else if (event.getId() == "leave")
+ {
+ SocialTab *tab = dynamic_cast<SocialTab*>(mTabs->getSelectedTab());
+
+ if (tab)
+ {
+ tab->leave();
+ }
+ }
+ else if (event.getId() == "create guild")
+ {
+ std::string name = mGuildCreateDialog->getText();
+
+ if (name.size() > 16)
+ {
+ // TODO : State too many characters in input.
+ return;
+ }
+
+ Net::getGuildHandler()->create(name);
+ localChatTab->chatLog(strprintf(_("Creating guild called %s."),
+ name.c_str()), BY_SERVER);
+ }
+ else if (event.getId() == "create party")
+ {
+ std::string name = mPartyCreateDialog->getText();
+
+ if (name.size() > 16)
+ {
+ // TODO : State too many characters in input.
+ return;
+ }
+
+ Net::getPartyHandler()->create(name);
+ localChatTab->chatLog(strprintf(_("Creating party called %s."),
+ name.c_str()), BY_SERVER);
+ }
+}
+
+void SocialWindow::showGuildCreate()
+{
+ mGuildCreateDialog = new TextDialog(_("Guild Name"),
+ _("Choose your guild's name."), this);
+ mGuildCreateDialog->setOKButtonActionId("create guild");
+ mGuildCreateDialog->addActionListener(this);
+}
+
+void SocialWindow::showGuildInvite(const std::string &guildName,
+ const int guildId,
+ const std::string &inviterName)
+{
+ // check there isnt already an invite showing
+ if (mGuildInvited != 0)
+ {
+ localChatTab->chatLog(_("Received guild request, but one already "
+ "exists."), BY_SERVER);
+ return;
+ }
+
+ std::string msg = strprintf(_("%s has invited you to join the guild %s."),
+ inviterName.c_str(), guildName.c_str());
+ localChatTab->chatLog(msg, BY_SERVER);
+
+ // show invite
+ mGuildAcceptDialog = new ConfirmDialog(_("Accept Guild Invite"), msg, this);
+ mGuildAcceptDialog->addActionListener(this);
+
+ mGuildInvited = guildId;
+}
+
+void SocialWindow::showPartyInvite(const std::string &partyName,
+ const std::string &inviter)
+{
+ // check there isnt already an invite showing
+ if (mPartyInviter != "")
+ {
+ localChatTab->chatLog(_("Received party request, but one already "
+ "exists."), BY_SERVER);
+ return;
+ }
+
+ std::string msg;
+ if (inviter.empty())
+ {
+ if (partyName.empty())
+ {
+ msg = _("You have been invited you to join a party.");
+ }
+ else
+ {
+ msg = strprintf(_("You have been invited to join the %s party."),
+ partyName.c_str());
+ }
+ }
+ else
+ {
+ if (partyName.empty())
+ {
+ msg = strprintf(_("%s has invited you to join their party."),
+ inviter.c_str());
+ }
+ else
+ {
+ msg = strprintf(_("%s has invited you to join the %s party."),
+ inviter.c_str(), partyName.c_str());
+ }
+ }
+
+ localChatTab->chatLog(msg, BY_SERVER);
+
+ // show invite
+ mPartyAcceptDialog = new ConfirmDialog(_("Accept Party Invite"), msg, this);
+ mPartyAcceptDialog->addActionListener(this);
+
+ mPartyInviter = inviter;
+}
+
+void SocialWindow::showPartyCreate()
+{
+ if (player_node->getParty())
+ {
+ new OkDialog(_("Create Party"),
+ _("Cannot create party. You are already in a party"),
+ this);
+ return;
+ }
+
+ mPartyCreateDialog = new TextDialog(_("Party Name"),
+ _("Choose your part's name."), this);
+ mPartyCreateDialog->setOKButtonActionId("create party");
+ mPartyCreateDialog->addActionListener(this);
+}
diff --git a/src/gui/socialwindow.h b/src/gui/socialwindow.h
new file mode 100644
index 00000000..56460230
--- /dev/null
+++ b/src/gui/socialwindow.h
@@ -0,0 +1,105 @@
+/*
+ * The Mana World
+ * Copyright (C) 2010 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef SOCIALWINDOW_H
+#define SOCIALWINDOW_H
+
+#include "gui/widgets/window.h"
+
+#include <guichan/actionevent.hpp>
+#include <guichan/actionlistener.hpp>
+
+#include <string>
+#include <map>
+
+class Button;
+class ConfirmDialog;
+class CreatePopup;
+class Guild;
+class Party;
+class SocialTab;
+class Tab;
+class TabbedArea;
+class TextDialog;
+
+/**
+ * Party window.
+ *
+ * \ingroup Interface
+ */
+class SocialWindow : public Window, gcn::ActionListener
+{
+public:
+ SocialWindow();
+
+ ~SocialWindow();
+
+ bool addTab(Guild *guild);
+
+ bool removeTab(Guild *guild);
+
+ bool addTab(Party *party);
+
+ bool removeTab(Party *party);
+
+ /**
+ * Handle events.
+ */
+ void action(const gcn::ActionEvent &event);
+
+ void showGuildInvite(const std::string &guildName, const int guildId,
+ const std::string &inviterName);
+
+ void showGuildCreate();
+
+ void showPartyInvite(const std::string &partyName,
+ const std::string &inviter = "");
+
+ void showPartyCreate();
+
+protected:
+ friend class SocialTab;
+
+ int mGuildInvited;
+ ConfirmDialog *mGuildAcceptDialog;
+ TextDialog *mGuildCreateDialog;
+
+ std::string mPartyInviter;
+ ConfirmDialog *mPartyAcceptDialog;
+ TextDialog *mPartyCreateDialog;
+
+ typedef std::map<Guild*, SocialTab*> GuildMap;
+ GuildMap mGuilds;
+
+ typedef std::map<Party*, SocialTab*> PartyMap;
+ PartyMap mParties;
+
+ CreatePopup *mCreatePopup;
+
+ Button *mCreateButton;
+ Button *mInviteButton;
+ Button *mLeaveButton;
+ TabbedArea *mTabs;
+};
+
+extern SocialWindow *socialWindow;
+
+#endif // SOCIALWINDOW_H
diff --git a/src/gui/textdialog.cpp b/src/gui/textdialog.cpp
index 0bdd6030..3e8af7e8 100644
--- a/src/gui/textdialog.cpp
+++ b/src/gui/textdialog.cpp
@@ -65,6 +65,7 @@ TextDialog::TextDialog(const std::string &title, const std::string &msg,
getParent()->moveToTop(this);
}
setVisible(true);
+ requestModalFocus();
mTextField->requestFocus();
instances++;
@@ -77,14 +78,10 @@ TextDialog::~TextDialog()
void TextDialog::action(const gcn::ActionEvent &event)
{
- // Proxy button events to our listeners
- ActionListenerIterator i;
- for (i = mActionListeners.begin(); i != mActionListeners.end(); ++i)
- {
- (*i)->action(event);
- }
+ setActionEventId(event.getId());
+ distributeActionEvent();
- if (event.getId() == "CANCEL" || event.getId() == "OK")
+ if (event.getId() == "CANCEL" || event.getSource() == mOkButton)
{
scheduleDelete();
}
diff --git a/src/gui/widgets/avatar.cpp b/src/gui/widgets/avatar.cpp
deleted file mode 100644
index 7102fe4f..00000000
--- a/src/gui/widgets/avatar.cpp
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * The Mana World
- * Copyright (C) 2008-2010 The Mana World Development Team
- *
- * This file is part of The Mana World.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "gui/widgets/avatar.h"
-
-#include "localplayer.h"
-
-#include "gui/gui.h"
-
-#include "gui/widgets/icon.h"
-#include "gui/widgets/label.h"
-
-#include "resources/image.h"
-#include "resources/resourcemanager.h"
-
-#include <sstream>
-
-namespace {
- Image *avatarStatusOffline;
- Image *avatarStatusOnline;
- int avatarCount = 0;
-}
-
-Avatar::Avatar():
- mHp(0),
- mMaxHp(0),
- mDisplayBold(false)
-{
- setOpaque(false);
-
- if (avatarCount == 0)
- {
- ResourceManager *resman = ResourceManager::getInstance();
- avatarStatusOffline = resman->getImage("graphics/gui/circle-gray.png");
- avatarStatusOnline = resman->getImage("graphics/gui/circle-green.png");
- }
- avatarCount++;
- avatarStatusOffline->incRef();
- avatarStatusOnline->incRef();
-
- mLabel = new Label;
- mLabel->adjustSize();
-
- mStatus = new Icon(avatarStatusOffline);
- mStatus->setSize(10, 10);
-
- add(mStatus, 4, (mLabel->getHeight() - 10) / 2);
- add(mLabel, 18, 0);
-
- setSize(250, mLabel->getHeight());
-
-}
-
-Avatar::~Avatar()
-{
- avatarCount--;
-
- avatarStatusOffline->decRef();
- avatarStatusOnline->decRef();
-}
-
-void Avatar::setName(const std::string &name)
-{
- mName = name;
- updateAvatarLabel();
-}
-
-void Avatar::setOnline(bool online)
-{
- mOnline = online;
- mStatus->setImage(online ? avatarStatusOnline : avatarStatusOffline);
-}
-
-void Avatar::setHp(int hp)
-{
- if (hp == mHp)
- return;
-
- mHp = hp;
- updateAvatarLabel();
-}
-
-void Avatar::setMaxHp(int maxHp)
-{
- if (maxHp == mMaxHp)
- return;
-
- mMaxHp = maxHp;
- updateAvatarLabel();
-}
-
-void Avatar::updateAvatarLabel()
-{
- std::ostringstream ss;
- ss << mName;
-
- if (mName != player_node->getName() && mMaxHp != 0)
- ss << " (" << mHp << "/" << mMaxHp << ")";
-
- if (mDisplayBold)
- mLabel->setFont(boldFont);
- mLabel->setCaption(ss.str());
- mLabel->adjustSize();
-}
diff --git a/src/gui/widgets/avatarlistbox.cpp b/src/gui/widgets/avatarlistbox.cpp
new file mode 100644
index 00000000..566cd9de
--- /dev/null
+++ b/src/gui/widgets/avatarlistbox.cpp
@@ -0,0 +1,133 @@
+/*
+ * The Mana World
+ * Copyright (C) 2008 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "gui/widgets/avatarlistbox.h"
+
+#include "graphics.h"
+
+#include "gui/gui.h"
+#include "gui/palette.h"
+
+#include "resources/image.h"
+#include "resources/resourcemanager.h"
+
+#include <guichan/font.hpp>
+
+int AvatarListBox::instances = 0;
+Image *AvatarListBox::onlineIcon = 0;
+Image *AvatarListBox::offlineIcon = 0;
+
+AvatarListBox::AvatarListBox(AvatarListModel *model):
+ ListBox(model)
+{
+ instances++;
+
+ if (instances == 1)
+ {
+ onlineIcon = ResourceManager::getInstance()->getImage("graphics/gui/circle-green.png");
+ offlineIcon = ResourceManager::getInstance()->getImage("graphics/gui/circle-gray.png");
+ }
+
+ setWidth(200);
+}
+
+AvatarListBox::~AvatarListBox()
+{
+ instances--;
+
+ if (instances == 0)
+ {
+ onlineIcon->decRef();
+ offlineIcon->decRef();
+ }
+}
+
+void AvatarListBox::draw(gcn::Graphics *gcnGraphics)
+{
+ AvatarListModel* model = dynamic_cast<AvatarListModel*>(mListModel);
+
+ if (!model)
+ return;
+
+ updateAlpha();
+
+ Graphics *graphics = static_cast<Graphics*>(gcnGraphics);
+
+ graphics->setColor(guiPalette->getColor(Palette::HIGHLIGHT,
+ (int)(mAlpha * 255.0f)));
+ graphics->setFont(getFont());
+
+ const int fontHeight = getFont()->getHeight();
+
+ // Draw filled rectangle around the selected list element
+ if (mSelected >= 0)
+ graphics->fillRectangle(gcn::Rectangle(0, fontHeight * mSelected,
+ getWidth(), fontHeight));
+
+ int newWidth = 0;
+ int width = 0;
+
+ // Draw the list elements
+ graphics->setColor(guiPalette->getColor(Palette::TEXT));
+ for (int i = 0, y = 0;
+ i < model->getNumberOfElements();
+ ++i, y += fontHeight)
+ {
+ Avatar *a = model->getAvatarAt(i);
+ // Draw online status
+ Image *icon = a->getOnline() ? onlineIcon : offlineIcon;
+ if (icon)
+ graphics->drawImage(icon, 2, y + 1);
+
+ if (a->getDisplayBold())
+ graphics->setFont(boldFont);
+
+ // Draw Name
+ graphics->drawText(a->getName(), 15, y);
+
+ width = getFont()->getWidth(a->getName()) + 17; // Extra right padding
+
+ if (width > newWidth)
+ {
+ newWidth = width;
+ }
+
+ if (a->getDisplayBold())
+ graphics->setFont(getFont());
+ }
+
+ setWidth(newWidth);
+}
+
+void AvatarListBox::mousePressed(gcn::MouseEvent &event)
+{
+ if (event.getButton() == gcn::MouseEvent::LEFT)
+ {
+ int y = event.getY();
+ setSelected(y / getFont()->getHeight());
+ distributeActionEvent();
+ }
+ // TODO: Add support for context menu
+ else if (event.getButton() == gcn::MouseEvent::RIGHT)
+ {
+ // Show context menu
+ }
+}
diff --git a/src/gui/widgets/guildlistbox.h b/src/gui/widgets/avatarlistbox.h
index 387b2a7a..5c05cae6 100644
--- a/src/gui/widgets/guildlistbox.h
+++ b/src/gui/widgets/avatarlistbox.h
@@ -1,6 +1,6 @@
/*
* The Mana World
- * Copyright (C) 2008-2010 The Mana World Development Team
+ * Copyright (C) 2008 The Mana World Development Team
*
* This file is part of The Mana World.
*
@@ -22,6 +22,8 @@
#ifndef GUI_GUILDLISTBOX_H
#define GUI_GUILDLISTBOX_H
+#include "avatar.h"
+
#include "gui/widgets/listbox.h"
#include <map>
@@ -30,13 +32,21 @@
class Image;
-class GuildListBox : public ListBox
+class AvatarListModel : public gcn::ListModel
{
public:
- /**
- * Constructor
- */
- GuildListBox();
+ virtual Avatar *getAvatarAt(int i) = 0;
+
+ std::string getElementAt(int i)
+ { return getAvatarAt(i)->getName(); }
+};
+
+class AvatarListBox : public ListBox
+{
+public:
+ AvatarListBox(AvatarListModel *model);
+
+ ~AvatarListBox();
/**
* Draws the list box.
@@ -45,21 +55,11 @@ public:
void mousePressed(gcn::MouseEvent &event);
- /**
- * Sets the index of the selected element.
- */
-// void setSelected(int selected);
-
- /**
- * Set whether a member is online or offline
- */
- void setOnlineStatus(const std::string &user, bool online);
-
private:
- Image *onlineIcon;
- Image *offlineIcon;
- typedef std::map<std::string, bool> UserMap;
- UserMap mUsers;
+ static int instances;
+ static Image *onlineIcon;
+ static Image *offlineIcon;
+
};
#endif
diff --git a/src/gui/widgets/guildlistbox.cpp b/src/gui/widgets/guildlistbox.cpp
deleted file mode 100644
index 362e79d1..00000000
--- a/src/gui/widgets/guildlistbox.cpp
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * The Mana World
- * Copyright (C) 2008-2010 The Mana World Development Team
- *
- * This file is part of The Mana World.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "gui/widgets/guildlistbox.h"
-
-#include "graphics.h"
-
-#include "resources/image.h"
-#include "resources/resourcemanager.h"
-
-#include <guichan/font.hpp>
-
-GuildListBox::GuildListBox():
- ListBox(NULL)
-{
- onlineIcon = ResourceManager::getInstance()->getImage("graphics/gui/circle-green.png");
- offlineIcon = ResourceManager::getInstance()->getImage("graphics/gui/circle-gray.png");
-}
-
-void GuildListBox::draw(gcn::Graphics *gcnGraphics)
-{
- if (!mListModel)
- return;
-
- Graphics *graphics = static_cast<Graphics*>(gcnGraphics);
-
- graphics->setColor(gcn::Color(110, 160, 255));
- graphics->setFont(getFont());
-
- int fontHeight = getFont()->getHeight();
-
- // Draw rectangle below the selected list element
- if (mSelected >= 0)
- {
- graphics->fillRectangle(gcn::Rectangle(0, fontHeight * mSelected,
- getWidth(), fontHeight));
- }
-
- // Draw the list elements
- for (int i = 0, y = 0;
- i < mListModel->getNumberOfElements();
- ++i, y += fontHeight)
- {
- // Draw online status
- bool online = false;
- UserMap::iterator itr = mUsers.find(mListModel->getElementAt(i));
- if (itr != mUsers.end())
- {
- online = itr->second;
- }
- Image *icon = online ? onlineIcon : offlineIcon;
- if (icon)
- graphics->drawImage(icon, 1, y);
- // Draw Name
- graphics->setColor(gcn::Color(0, 0, 0));
- graphics->drawText(mListModel->getElementAt(i), 33, y);
- }
-}
-/*
-void GuildListBox::setSelected(int selected)
-{
- if (!mListModel)
- {
- mSelected = -1;
- }
- else
- {
- // Update mSelected with bounds checking
- mSelected = std::min(mListModel->getNumberOfElements() - 1,
- std::max(-1, selected));
-
- gcn::Widget *parent;
- parent = (gcn::Widget*)getParent();
- if (parent)
- {
- gcn::Rectangle scroll;
- scroll.y = (mSelected < 0) ? 0 : getFont()->getHeight() * mSelected;
- scroll.height = getFont()->getHeight();
- parent->showWidgetPart(this, scroll);
- }
- }
-
- distributeValueChangedEvent();
-}
-*/
-void GuildListBox::mousePressed(gcn::MouseEvent &event)
-{
- if (event.getButton() == gcn::MouseEvent::LEFT)
- {
- int y = event.getY();
- setSelected(y / getFont()->getHeight());
- distributeActionEvent();
- }
- // TODO: Add guild functions, ie private messaging
- if (event.getButton() == gcn::MouseEvent::RIGHT)
- {
- // Show context menu
- }
-}
-
-void GuildListBox::setOnlineStatus(const std::string &user, bool online)
-{
- UserMap::iterator itr = mUsers.find(user);
- if (itr == mUsers.end())
- {
- mUsers.insert(std::pair<std::string, bool>(user, online));
- }
- else
- {
- itr->second = online;
- }
- adjustSize();
-}
diff --git a/src/gui/widgets/listbox.h b/src/gui/widgets/listbox.h
index ed17c6ad..9110e71c 100644
--- a/src/gui/widgets/listbox.h
+++ b/src/gui/widgets/listbox.h
@@ -65,7 +65,7 @@ class ListBox : public gcn::ListBox
void mouseDragged(gcn::MouseEvent &event);
- private:
+ protected:
static float mAlpha;
};
diff --git a/src/gui/widgets/scrollarea.cpp b/src/gui/widgets/scrollarea.cpp
index abcb858a..71f1a1a8 100644
--- a/src/gui/widgets/scrollarea.cpp
+++ b/src/gui/widgets/scrollarea.cpp
@@ -42,6 +42,7 @@ ScrollArea::ScrollArea():
gcn::ScrollArea(),
mX(0),
mY(0),
+ mHasMouse(false),
mOpaque(true)
{
addWidgetListener(this);
@@ -50,6 +51,8 @@ ScrollArea::ScrollArea():
ScrollArea::ScrollArea(gcn::Widget *widget):
gcn::ScrollArea(widget),
+ mX(0),
+ mY(0),
mHasMouse(false),
mOpaque(true)
{
diff --git a/src/gui/widgets/tabbedarea.cpp b/src/gui/widgets/tabbedarea.cpp
index b5c1eb9f..c0d070cf 100644
--- a/src/gui/widgets/tabbedarea.cpp
+++ b/src/gui/widgets/tabbedarea.cpp
@@ -178,6 +178,5 @@ void TabbedArea::widgetResized(const gcn::Event &event)
gcn::Widget *w = getCurrentWidget();
if (w)
- w->setSize(width,
- height);
+ w->setSize(width, height);
}
diff --git a/src/gui/windowmenu.cpp b/src/gui/windowmenu.cpp
index 460d12b4..e57f35fa 100644
--- a/src/gui/windowmenu.cpp
+++ b/src/gui/windowmenu.cpp
@@ -43,7 +43,7 @@ extern Window *setupWindow;
extern Window *skillDialog;
extern Window *specialsWindow;
extern Window *statusWindow;
-extern Window *guildWindow;
+extern Window *socialWindow;
WindowMenu::WindowMenu():
mEmotePopup(0)
@@ -57,7 +57,7 @@ WindowMenu::WindowMenu():
N_("Inventory"),
N_("Skills"),
N_("Specials"),
- N_("Guilds"),
+ N_("Social"),
N_("Shortcut"),
N_("Setup"),
0
@@ -127,9 +127,9 @@ void WindowMenu::action(const gcn::ActionEvent &event)
{
window = specialsWindow;
}
- else if (event.getId() == "Guilds")
+ else if (event.getId() == "Social")
{
- window = guildWindow;
+ window = socialWindow;
}
else if (event.getId() == "Shortcut")
{
diff --git a/src/guild.cpp b/src/guild.cpp
index 37cf6ef8..b8b277e5 100644
--- a/src/guild.cpp
+++ b/src/guild.cpp
@@ -22,19 +22,19 @@
#include "guild.h"
GuildMember::GuildMember(int guildId, int id, const std::string &name):
- mName(name), mId(id), mOnline(false)
+ Avatar(name), mId(id)
{
mGuild = Guild::getGuild(guildId);
}
GuildMember::GuildMember(int guildId, int id):
- mId(id), mOnline(false)
+ mId(id)
{
mGuild = Guild::getGuild(guildId);
}
GuildMember::GuildMember(int guildId, const std::string &name):
- mName(name), mId(0), mOnline(false)
+ Avatar(name), mId(0)
{
mGuild = Guild::getGuild(guildId);
}
@@ -80,7 +80,7 @@ GuildMember *Guild::getMember(std::string name)
itr_end = mMembers.end();
while (itr != itr_end)
{
- if ((*itr)->mName == name)
+ if((*itr)->getName() == name)
{
return (*itr);
}
@@ -96,7 +96,8 @@ void Guild::removeMember(GuildMember *member)
itr_end = mMembers.end();
while (itr != itr_end)
{
- if ((*itr)->mId == member->mId && (*itr)->mName == member->mName)
+ if((*itr)->mId == member->mId &&
+ (*itr)->getName() == member->getName())
{
mMembers.erase(itr);
}
@@ -122,7 +123,7 @@ void Guild::removeMember(const std::string &name)
itr_end = mMembers.end();
while (itr != itr_end)
{
- if ((*itr)->mName == name)
+ if((*itr)->getName() == name)
{
mMembers.erase(itr);
}
@@ -130,13 +131,9 @@ void Guild::removeMember(const std::string &name)
}
}
-std::string Guild::getElementAt(int index)
+Avatar *Guild::getAvatarAt(int index)
{
- GuildMember *m = mMembers[index];
- if (m->mOnline)
- return "* " + m->mName;
- else
- return m->mName;
+ return mMembers[index];
}
void Guild::setRights(short rights)
@@ -155,8 +152,11 @@ bool Guild::isMember(GuildMember *member) const
itr_end = mMembers.end();
while (itr != itr_end)
{
- if ((*itr)->mId == member->mId && (*itr)->mName == member->mName)
+ if ((*itr)->mId == member->mId &&
+ (*itr)->getName() == member->getName())
+ {
return true;
+ }
++itr;
}
@@ -183,14 +183,28 @@ bool Guild::isMember(const std::string &name) const
itr_end = mMembers.end();
while (itr != itr_end)
{
- if ((*itr)->mName == name)
+ if ((*itr)->getName() == name)
+ {
return true;
+ }
++itr;
}
return false;
}
+void Guild::getNames(std::vector<std::string> &names) const
+{
+ names.clear();
+ MemberList::const_iterator it = mMembers.begin(),
+ it_end = mMembers.end();
+ while (it != it_end)
+ {
+ names.push_back((*it)->getName());
+ ++it;
+ }
+}
+
Guild *Guild::getGuild(int id)
{
GuildMap::iterator it = guilds.find(id);
diff --git a/src/guild.h b/src/guild.h
index fc60ae0a..11ba6e14 100644
--- a/src/guild.h
+++ b/src/guild.h
@@ -22,7 +22,9 @@
#ifndef GUILD_H
#define GUILD_H
-#include <guichan/listmodel.hpp>
+#include "avatar.h"
+
+#include "gui/widgets/avatarlistbox.h"
#include <map>
#include <string>
@@ -30,7 +32,7 @@
class Guild;
-class GuildMember
+class GuildMember : public Avatar
{
public:
GuildMember(int guildId, int id, const std::string &name);
@@ -43,26 +45,16 @@ public:
void setID(int id) { mId = id; }
- std::string getName() const { return mName; }
-
- void setName(std::string name) { mName = name; }
-
Guild *getGuild() const { return mGuild; }
- bool getOnline() const { return mOnline; }
-
- void setOnline(bool online) { mOnline = online; }
-
protected:
friend class Guild;
- std::string mName;
int mId;
Guild *mGuild;
- bool mOnline;
};
-class Guild : public gcn::ListModel
+class Guild : public AvatarListModel
{
public:
@@ -136,11 +128,7 @@ public:
return mMembers.size();
}
- /**
- * Get member at \a index.
- * @return Returns the name of member.
- */
- std::string getElementAt(int index);
+ Avatar *getAvatarAt(int i);
/**
* Get whether user can invite users to this guild.
@@ -159,6 +147,8 @@ public:
bool isMember(const std::string &name) const;
+ void getNames(std::vector<std::string> &names) const;
+
static Guild *getGuild(int id);
private:
diff --git a/src/keyboardconfig.cpp b/src/keyboardconfig.cpp
index 8dc2f0c5..a9b702eb 100644
--- a/src/keyboardconfig.cpp
+++ b/src/keyboardconfig.cpp
@@ -78,7 +78,7 @@ static KeyData const keyData[KeyboardConfig::KEY_TOTAL] = {
{"keyWindowShortcut", SDLK_F8, _("Item Shortcut Window")},
{"keyWindowSetup", SDLK_F9, _("Setup Window")},
{"keyWindowDebug", SDLK_F10, _("Debug Window")},
- {"keyWindowParty", SDLK_F11, _("Party Window")},
+ {"keyWindowSocial", SDLK_F11, _("Social Window")},
{"keyWindowEmoteBar", SDLK_F12, _("Emote Shortcut Window")},
{"keyWindowOutfit", SDLK_o, _("Outfits Window")},
{"keyEmoteShortcut1", SDLK_1, strprintf(_("Emote Shortcut %d"), 1)},
diff --git a/src/keyboardconfig.h b/src/keyboardconfig.h
index 4a36ea63..9c23f53b 100644
--- a/src/keyboardconfig.h
+++ b/src/keyboardconfig.h
@@ -193,7 +193,7 @@ class KeyboardConfig
KEY_WINDOW_SHORTCUT,
KEY_WINDOW_SETUP,
KEY_WINDOW_DEBUG,
- KEY_WINDOW_PARTY,
+ KEY_WINDOW_SOCIAL,
KEY_WINDOW_EMOTE_SHORTCUT,
KEY_WINDOW_OUTFIT,
KEY_EMOTE_1,
diff --git a/src/net/ea/beinghandler.cpp b/src/net/ea/beinghandler.cpp
index 93962613..86bfe929 100644
--- a/src/net/ea/beinghandler.cpp
+++ b/src/net/ea/beinghandler.cpp
@@ -28,10 +28,9 @@
#include "localplayer.h"
#include "log.h"
#include "npc.h"
+#include "party.h"
#include "playerrelations.h"
-#include "gui/partywindow.h"
-
#include "net/ea/protocol.h"
#include "resources/colordb.h"
@@ -515,11 +514,10 @@ void BeingHandler::handleMessage(Net::MessageIn &msg)
player = dynamic_cast<Player*>(dstBeing);
- {
- PartyMember *member = partyWindow->findMember(id);
- if (member && member->getAvatar()->getOnline())
+ if (Party *party = player_node->getParty()){
+ if (party->isMember(id))
{
- player->setInParty(true);
+ player->setParty(party);
}
}
diff --git a/src/net/ea/generalhandler.cpp b/src/net/ea/generalhandler.cpp
index 24bc79bb..547b0609 100644
--- a/src/net/ea/generalhandler.cpp
+++ b/src/net/ea/generalhandler.cpp
@@ -29,6 +29,7 @@
#include "gui/inventorywindow.h"
#include "gui/register.h"
#include "gui/skilldialog.h"
+#include "gui/socialwindow.h"
#include "gui/statuswindow.h"
#include "net/ea/adminhandler.h"
@@ -67,6 +68,8 @@ namespace EAthena {
ServerInfo charServer;
ServerInfo mapServer;
+extern Party *eaParty;
+
GeneralHandler::GeneralHandler():
mAdminHandler(new AdminHandler),
mBeingHandler(new BeingHandler(config.getValue("EnableSync", 0) == 1)),
@@ -202,7 +205,6 @@ void GeneralHandler::flushNetwork()
void GeneralHandler::guiWindowsLoaded()
{
- partyTab = new PartyTab;
inventoryWindow->setSplitAllowed(false);
skillDialog->loadSkills("ea-skills.xml");
@@ -224,8 +226,12 @@ void GeneralHandler::guiWindowsLoaded()
void GeneralHandler::guiWindowsUnloaded()
{
- delete partyTab;
- partyTab = 0;
+ socialWindow->removeTab(eaParty);
+ if (partyTab)
+ {
+ delete partyTab;
+ partyTab = 0;
+ }
}
void GeneralHandler::clearHandlers()
diff --git a/src/net/ea/partyhandler.cpp b/src/net/ea/partyhandler.cpp
index 55331640..6934dde0 100644
--- a/src/net/ea/partyhandler.cpp
+++ b/src/net/ea/partyhandler.cpp
@@ -25,8 +25,7 @@
#include "localplayer.h"
#include "log.h"
-#include "gui/chat.h"
-#include "gui/partywindow.h"
+#include "gui/socialwindow.h"
#include "net/messagein.h"
#include "net/messageout.h"
@@ -38,11 +37,14 @@
#include "utils/gettext.h"
#include "utils/stringutils.h"
+#define PARTY_ID 1
+
extern Net::PartyHandler *partyHandler;
namespace EAthena {
PartyTab *partyTab = 0;
+Party *eaParty;
PartyHandler::PartyHandler():
mShareExp(PARTY_SHARE_UNKNOWN), mShareItems(PARTY_SHARE_UNKNOWN)
@@ -62,13 +64,16 @@ PartyHandler::PartyHandler():
};
handledMessages = _messages;
partyHandler = this;
-
- //newPartyTab();
+ eaParty = Party::getParty(1);
}
PartyHandler::~PartyHandler()
{
- //deletePartyTab();
+ if (partyTab)
+ {
+ delete partyTab;
+ partyTab = 0;
+ }
}
void PartyHandler::handleMessage(Net::MessageIn &msg)
@@ -77,24 +82,19 @@ void PartyHandler::handleMessage(Net::MessageIn &msg)
{
case SMSG_PARTY_CREATE:
if (msg.readInt8())
- partyTab->chatLog(_("Could not create party."), BY_SERVER);
+ localChatTab->chatLog(_("Could not create party."), BY_SERVER);
else
{
- partyTab->chatLog(_("Party successfully created."), BY_SERVER);
- player_node->setInParty(true);
- partyWindow->setVisible(true);
+ localChatTab->chatLog(_("Party successfully created."),
+ BY_SERVER);
}
break;
case SMSG_PARTY_INFO:
{
- if (!partyWindow)
- break;
-
- partyWindow->clearMembers();
+ eaParty->clearMembers();
int length = msg.readInt16();
- std::string party = msg.readString(24);
- partyWindow->setPartyName(party);
+ eaParty->setName(msg.readString(24));
int count = (length - 28) / 46;
for (int i = 0; i < count; i++)
@@ -105,7 +105,10 @@ void PartyHandler::handleMessage(Net::MessageIn &msg)
bool leader = msg.readInt8() == 0;
bool online = msg.readInt8() == 0;
- partyWindow->updateMember(id, nick, leader, online);
+ PartyMember *member = new PartyMember(PARTY_ID, id, nick);
+ member->setLeader(leader);
+ member->setOnline(online);
+ eaParty->addMember(member);
}
}
break;
@@ -136,29 +139,30 @@ void PartyHandler::handleMessage(Net::MessageIn &msg)
case SMSG_PARTY_INVITED:
{
int id = msg.readInt32();
- Being *being = beingManager->findBeing(id);
- if (!being)
- {
- break;
- }
- std::string nick;
- std::string partyName = "";
- if (being->getType() != Being::PLAYER)
- {
- nick = "";
- }
- else
+ std::string partyName = msg.readString(24);
+ std::string nick = "";
+ Being *being;
+
+ if (!(being = beingManager->findBeing(id)))
{
- nick = being->getName();
- partyName = msg.readString(24);
+ if (being->getType() == Being::PLAYER)
+ {
+ nick = being->getName();
+ }
}
- partyWindow->showPartyInvite(nick, partyName);
+
+ socialWindow->showPartyInvite(partyName, nick);
break;
}
case SMSG_PARTY_SETTINGS:
{
if (!partyTab)
- break;
+ {
+ if (!chatWindow)
+ break;
+
+ partyTab = new PartyTab();
+ }
// These seem to indicate the sharing mode for exp and items
short exp = msg.readInt16();
@@ -199,7 +203,7 @@ void PartyHandler::handleMessage(Net::MessageIn &msg)
case PARTY_SHARE_NO:
if (mShareItems == PARTY_SHARE_NO)
break;
- mShareItems =PARTY_SHARE_NO;
+ mShareItems = PARTY_SHARE_NO;
partyTab->chatLog(_("Item sharing disabled."), BY_SERVER);
break;
case PARTY_SHARE_NOT_POSSIBLE:
@@ -232,16 +236,22 @@ void PartyHandler::handleMessage(Net::MessageIn &msg)
msg.readInt8(); // fail
if (id == player_node->getId())
{
- partyWindow->clearMembers();
- partyWindow->clearPartyName();
- partyWindow->setVisible(false);
- partyTab->chatLog(_("You have left the party."), BY_SERVER);
+ eaParty->clearMembers();
+ player_node->setParty(NULL);
+ localChatTab->chatLog(_("You have left the party."),
+ BY_SERVER);
+ if (partyTab)
+ {
+ delete partyTab;
+ partyTab = 0;
+ }
+ socialWindow->removeTab(eaParty);
}
else
{
partyTab->chatLog(strprintf(_("%s has left your party."),
nick.c_str()), BY_SERVER);
- partyWindow->removeMember(id);
+ eaParty->removeMember(id);
}
break;
}
@@ -250,7 +260,12 @@ void PartyHandler::handleMessage(Net::MessageIn &msg)
int id = msg.readInt32();
int hp = msg.readInt16();
int maxhp = msg.readInt16();
- partyWindow->updateMemberHP(id, hp, maxhp);
+ PartyMember *m = eaParty->getMember(id);
+ if (m)
+ {
+ m->setHp(hp);
+ m->setMaxHp(maxhp);
+ }
}
break;
case SMSG_PARTY_UPDATE_COORDS:
@@ -270,9 +285,9 @@ void PartyHandler::handleMessage(Net::MessageIn &msg)
int id = msg.readInt32();
std::string chatMsg = msg.readString(msgLength);
- PartyMember *member = partyWindow->findMember(id);
+ PartyMember *member = eaParty->getMember(id);
if (member)
- partyTab->chatLog(member->getAvatar()->getName(), chatMsg);
+ partyTab->chatLog(member->getName(), chatMsg);
else
partyTab->chatLog(strprintf(_("An unknown member tried to "
"say: %s"), chatMsg.c_str()), BY_SERVER);
@@ -309,7 +324,6 @@ void PartyHandler::inviteResponse(const std::string &inviter, bool accept)
MessageOut outMsg(CMSG_PARTY_INVITED);
outMsg.writeInt32(player_node->getId());
outMsg.writeInt32(accept ? 1 : 0);
- player_node->setInParty(player_node->isInParty() || accept);
}
void PartyHandler::leave()
@@ -326,8 +340,8 @@ void PartyHandler::kick(Player *player)
void PartyHandler::kick(const std::string &name)
{
- int id = partyWindow->findMember(name);
- if (id == -1)
+ PartyMember *m = eaParty->getMember(name);
+ if (!m)
{
partyTab->chatLog(strprintf(_("%s is not in your party!"), name.c_str()),
BY_SERVER);
@@ -335,7 +349,7 @@ void PartyHandler::kick(const std::string &name)
}
MessageOut outMsg(CMSG_PARTY_KICK);
- outMsg.writeInt32(id);
+ outMsg.writeInt32(m->getID());
outMsg.writeString(name, 24); //Unused
}
diff --git a/src/net/ea/partyhandler.h b/src/net/ea/partyhandler.h
index 188df2ac..e58cf0bf 100644
--- a/src/net/ea/partyhandler.h
+++ b/src/net/ea/partyhandler.h
@@ -27,6 +27,8 @@
#include "net/ea/messagehandler.h"
+#include "party.h"
+
namespace EAthena {
class PartyHandler : public MessageHandler, public Net::PartyHandler
diff --git a/src/net/manaserv/chathandler.cpp b/src/net/manaserv/chathandler.cpp
index 08863eca..e849b51a 100644
--- a/src/net/manaserv/chathandler.cpp
+++ b/src/net/manaserv/chathandler.cpp
@@ -29,7 +29,6 @@
#include "main.h"
#include "gui/chat.h"
-#include "gui/guildwindow.h"
#include "gui/widgets/channeltab.h"
diff --git a/src/net/manaserv/generalhandler.cpp b/src/net/manaserv/generalhandler.cpp
index de066aca..aa3b06f5 100644
--- a/src/net/manaserv/generalhandler.cpp
+++ b/src/net/manaserv/generalhandler.cpp
@@ -26,7 +26,6 @@
#include "gui/changeemaildialog.h"
#include "gui/charselectdialog.h"
#include "gui/inventorywindow.h"
-#include "gui/partywindow.h"
#include "gui/register.h"
#include "gui/skilldialog.h"
#include "gui/specialswindow.h"
@@ -159,8 +158,7 @@ void GeneralHandler::flushNetwork()
void GeneralHandler::guiWindowsLoaded()
{
inventoryWindow->setSplitAllowed(true);
- partyWindow->clearPartyName();
- skillDialog->loadSkills("mana-skills.xml");
+ skillDialog->loadSkills("tmw-skills.xml");
specialsWindow->loadSpecials("specials.xml");
player_node->setExpNeeded(100);
diff --git a/src/net/manaserv/guildhandler.cpp b/src/net/manaserv/guildhandler.cpp
index 44220e9a..fc0e7e25 100644
--- a/src/net/manaserv/guildhandler.cpp
+++ b/src/net/manaserv/guildhandler.cpp
@@ -21,17 +21,18 @@
#include "net/manaserv/guildhandler.h"
-#include "gui/widgets/channeltab.h"
-#include "gui/chat.h"
-#include "gui/guildwindow.h"
-
#include "guild.h"
#include "log.h"
#include "localplayer.h"
#include "channel.h"
#include "channelmanager.h"
+#include "gui/widgets/channeltab.h"
+#include "gui/chat.h"
+#include "gui/socialwindow.h"
+
#include "net/messagein.h"
+#include "net/net.h"
#include "net/manaserv/connection.h"
#include "net/manaserv/messagein.h"
@@ -135,8 +136,6 @@ void GuildHandler::handleMessage(Net::MessageIn &msg)
guild->addMember(member);
}
}
-
- guildWindow->updateTab();
}
} break;
@@ -183,9 +182,6 @@ void GuildHandler::handleMessage(Net::MessageIn &msg)
logger->log("Invalid guild event");
}
}
- guildWindow->updateTab();
-
-
} break;
case CPMSG_GUILD_INVITED:
@@ -196,7 +192,7 @@ void GuildHandler::handleMessage(Net::MessageIn &msg)
int guildId = msg.readInt16();
// Open a dialog asking if the player accepts joining the guild.
- guildWindow->openAcceptDialog(inviterName, guildName, guildId);
+ socialWindow->showGuildInvite(guildName, guildId, inviterName);
} break;
case CPMSG_GUILD_PROMOTE_MEMBER_RESPONSE:
@@ -236,7 +232,6 @@ void GuildHandler::handleMessage(Net::MessageIn &msg)
{
Channel *channel = channelManager->findByName(guild->getName());
channelManager->removeChannel(channel);
- guildWindow->removeTab(guildId);
player_node->removeGuild(guildId);
}
}
@@ -252,11 +247,12 @@ void GuildHandler::joinedGuild(Net::MessageIn &msg)
short channelId = msg.readInt16();
std::string announcement = msg.readString();
- // Add guild to player and create new guild tab
- Guild *guild = player_node->addGuild(guildId, permissions);
+ // Add guild to player
+ Guild *guild = Guild::getGuild(guildId);
guild->setName(guildName);
- guildWindow->newGuildTab(guildName);
- guildWindow->requestMemberList(guildId);
+ guild->setRights(permissions);
+ player_node->addGuild(guild);
+ Net::getGuildHandler()->memberList(guildId);
// Automatically create the guild channel
// COMMENT: Should this go here??
diff --git a/src/net/manaserv/partyhandler.cpp b/src/net/manaserv/partyhandler.cpp
index cec33fc4..da97374b 100644
--- a/src/net/manaserv/partyhandler.cpp
+++ b/src/net/manaserv/partyhandler.cpp
@@ -21,13 +21,13 @@
#include "net/manaserv/partyhandler.h"
-#include "gui/partywindow.h"
-
-#include "gui/widgets/chattab.h"
-
#include "log.h"
#include "localplayer.h"
+#include "gui/socialwindow.h"
+
+#include "gui/widgets/chattab.h"
+
#include "net/manaserv/connection.h"
#include "net/manaserv/messagein.h"
#include "net/manaserv/messageout.h"
@@ -38,13 +38,16 @@
#include <iostream>
+#define PARTY_ID 1
+
extern Net::PartyHandler *partyHandler;
namespace ManaServ {
extern Connection *chatServerConnection;
-PartyHandler::PartyHandler()
+PartyHandler::PartyHandler():
+ mParty(Party::getParty(PARTY_ID))
{
static const Uint16 _messages[] = {
CPMSG_PARTY_INVITE_RESPONSE,
@@ -74,15 +77,14 @@ void PartyHandler::handleMessage(Net::MessageIn &msg)
case CPMSG_PARTY_INVITED:
{
- std::string inviter = msg.readString();
- partyWindow->showPartyInvite(inviter);
+ socialWindow->showPartyInvite(msg.readString());
} break;
case CPMSG_PARTY_ACCEPT_INVITE_RESPONSE:
{
if (msg.readInt8() == ERRMSG_OK)
{
- player_node->setInParty(true);
+ //
localChatTab->chatLog(_("Joined party."));
}
}
@@ -91,7 +93,8 @@ void PartyHandler::handleMessage(Net::MessageIn &msg)
{
if (msg.readInt8() == ERRMSG_OK)
{
- player_node->setInParty(false);
+ mParty->clearMembers();
+ player_node->setParty(NULL);
}
} break;
@@ -103,15 +106,16 @@ void PartyHandler::handleMessage(Net::MessageIn &msg)
localChatTab->chatLog(strprintf(_("%s joined the party."),
name.c_str()));
- if (!player_node->isInParty())
- player_node->setInParty(true);
+ if (id == player_node->getId())
+ player_node->setParty(mParty);
- partyWindow->updateMember(id, name);
+ PartyMember *member = new PartyMember(PARTY_ID, id, name);
+ mParty->addMember(member);
} break;
case CPMSG_PARTY_MEMBER_LEFT:
{
- partyWindow->removeMember(msg.readString());
+ mParty->removeMember(msg.readString());
} break;
case CPMSG_PARTY_REJECTED:
diff --git a/src/net/manaserv/partyhandler.h b/src/net/manaserv/partyhandler.h
index 5ab03785..f97d9fb9 100644
--- a/src/net/manaserv/partyhandler.h
+++ b/src/net/manaserv/partyhandler.h
@@ -26,6 +26,8 @@
#include "net/manaserv/messagehandler.h"
+#include "party.h"
+
#include <string>
namespace ManaServ {
@@ -64,6 +66,8 @@ public:
PartyShare getShareItems() { return PARTY_SHARE_NO; }
void setShareItems(PartyShare share) {}
+private:
+ Party *mParty;
};
} // namespace ManaServ
diff --git a/src/party.cpp b/src/party.cpp
new file mode 100644
index 00000000..6bbd0f6b
--- /dev/null
+++ b/src/party.cpp
@@ -0,0 +1,233 @@
+/*
+ * The Mana World
+ * Copyright (C) 2009 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "party.h"
+
+#include "beingmanager.h"
+#include "player.h"
+
+PartyMember::PartyMember(int partyId, int id, const std::string &name):
+ Avatar(name), mId(id), mLeader(false)
+{
+ mParty = Party::getParty(partyId);
+
+ Player *player = dynamic_cast<Player*>(beingManager->findBeing(id));
+ if (player)
+ player->setParty(mParty);
+}
+
+PartyMember::PartyMember(int PartyId, int id):
+ mId(id), mLeader(false)
+{
+ mParty = Party::getParty(PartyId);
+
+ if (beingManager)
+ {
+ Player *player = dynamic_cast<Player*>(beingManager->findBeing(id));
+ if (player)
+ player->setParty(mParty);
+ }
+}
+
+Party::PartyMap Party::parties;
+
+Party::Party(short id):
+ mId(id),
+ mCanInviteUsers(false)
+{
+ parties[id] = this;
+}
+
+void Party::addMember(PartyMember *member)
+{
+ if (member->mParty > 0 && member->mParty != this)
+ {
+ throw "Member in another Party!";
+ }
+
+ if (!isMember(member))
+ {
+ mMembers.push_back(member);
+ member->mParty = this;
+ }
+}
+
+PartyMember *Party::getMember(int id)
+{
+ MemberList::iterator itr = mMembers.begin(),
+ itr_end = mMembers.end();
+ while(itr != itr_end)
+ {
+ if((*itr)->mId == id)
+ {
+ return (*itr);
+ }
+ ++itr;
+ }
+
+ return NULL;
+}
+
+PartyMember *Party::getMember(std::string name)
+{
+ MemberList::iterator itr = mMembers.begin(),
+ itr_end = mMembers.end();
+ while(itr != itr_end)
+ {
+ if((*itr)->getName() == name)
+ {
+ return (*itr);
+ }
+ ++itr;
+ }
+
+ return NULL;
+}
+
+void Party::removeMember(PartyMember *member)
+{
+ MemberList::iterator itr = mMembers.begin(),
+ itr_end = mMembers.end();
+ while(itr != itr_end)
+ {
+ if((*itr)->mId == member->mId &&
+ (*itr)->getName() == member->getName())
+ {
+ mMembers.erase(itr);
+ }
+ ++itr;
+ }
+}
+
+void Party::removeMember(int id)
+{
+ MemberList::iterator itr = mMembers.begin(),
+ itr_end = mMembers.end();
+ while(itr != itr_end)
+ {
+ if((*itr)->mId == id)
+ {
+ mMembers.erase(itr);
+ }
+ ++itr;
+ }
+}
+
+void Party::removeMember(const std::string &name)
+{
+ MemberList::iterator itr = mMembers.begin(),
+ itr_end = mMembers.end();
+ while(itr != itr_end)
+ {
+ if((*itr)->getName() == name)
+ {
+ mMembers.erase(itr);
+ }
+ ++itr;
+ }
+}
+
+Avatar *Party::getAvatarAt(int index)
+{
+ return mMembers[index];
+}
+
+void Party::setRights(short rights)
+{
+ // to invite, rights must be greater than 0
+ if (rights > 0)
+ {
+ mCanInviteUsers = true;
+ }
+}
+
+bool Party::isMember(PartyMember *member) const
+{
+ if (member->mParty > 0 && member->mParty != this)
+ return false;
+
+ MemberList::const_iterator itr = mMembers.begin(),
+ itr_end = mMembers.end();
+ while (itr != itr_end)
+ {
+ if ((*itr)->mId == member->mId &&
+ (*itr)->getName() == member->getName())
+ {
+ return true;
+ }
+ ++itr;
+ }
+
+ return false;
+}
+
+bool Party::isMember(int id) const
+{
+ MemberList::const_iterator itr = mMembers.begin(),
+ itr_end = mMembers.end();
+ while (itr != itr_end)
+ {
+ if ((*itr)->mId == id)
+ {
+ return true;
+ }
+ ++itr;
+ }
+
+ return false;
+}
+
+bool Party::isMember(const std::string &name) const
+{
+ MemberList::const_iterator itr = mMembers.begin(),
+ itr_end = mMembers.end();
+ while (itr != itr_end)
+ {
+ if ((*itr)->getName() == name)
+ {
+ return true;
+ }
+ ++itr;
+ }
+
+ return false;
+}
+
+void Party::getNames(std::vector<std::string> &names) const
+{
+ names.clear();
+ MemberList::const_iterator it = mMembers.begin(),
+ it_end = mMembers.end();
+ while (it != it_end)
+ {
+ names.push_back((*it)->getName());
+ ++it;
+ }
+}
+
+Party *Party::getParty(int id)
+{
+ PartyMap::iterator it = parties.find(id);
+ if (it != parties.end())
+ return it->second;
+
+ return new Party(id);
+}
diff --git a/src/party.h b/src/party.h
new file mode 100644
index 00000000..22a768de
--- /dev/null
+++ b/src/party.h
@@ -0,0 +1,175 @@
+/*
+ * The Mana World
+ * Copyright (C) 2009 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PARTY_H
+#define PARTY_H
+
+#include "avatar.h"
+
+#include "gui/widgets/avatarlistbox.h"
+
+#include <map>
+#include <string>
+#include <vector>
+
+class Party;
+
+class PartyMember : public Avatar
+{
+public:
+ PartyMember(int partyId, int id, const std::string &name);
+
+ PartyMember(int partyId, int id);
+
+ PartyMember(int partyId, const std::string &name);
+
+ int getID() const { return mId; }
+
+ void setID(int id) { mId = id; }
+
+ Party *getParty() const { return mParty; }
+
+ bool getLeader() const { return mLeader; }
+
+ void setLeader(bool leader) { mLeader = leader; setDisplayBold(leader); }
+
+protected:
+ friend class Party;
+
+ int mId;
+ Party *mParty;
+ bool mLeader;
+};
+
+class Party : public AvatarListModel
+{
+public:
+
+ /**
+ * Set the party's name.
+ */
+ void setName(const std::string &name)
+ {
+ mName = name;
+ }
+
+ /**
+ * Adds member to the list.
+ */
+ void addMember(PartyMember *member);
+
+ /**
+ * Find a member by ID.
+ *
+ * @return the member with the given ID, or NULL if they don't exist.
+ */
+ PartyMember *getMember(int id);
+
+ /**
+ * Find a member by name.
+ *
+ * @return the member with the given name, or NULL if they don't exist.
+ */
+ PartyMember *getMember(std::string name);
+
+ /**
+ * Get the name of the party.
+ * @return returns name of the party
+ */
+ const std::string &getName() const
+ {
+ return mName;
+ }
+
+ /**
+ * Get the id of the party.
+ * @return Returns the id of the party
+ */
+ short getId() const
+ {
+ return mId;
+ }
+
+ /**
+ * Removes a member from the party.
+ */
+ void removeMember(PartyMember *member);
+
+ /**
+ * Removes a member from the party.
+ */
+ void removeMember(int id);
+
+ /**
+ * Removes a member from the party.
+ */
+ void removeMember(const std::string &name);
+
+ void clearMembers() { mMembers.clear(); }
+
+ /**
+ * Get size of members list.
+ * @return Returns the number of members in the party.
+ */
+ int getNumberOfElements() {
+ return mMembers.size();
+ }
+
+ Avatar *getAvatarAt(int i);
+
+ /**
+ * Get whether user can invite users to this party.
+ * @return Returns true if user can invite users
+ */
+ bool getInviteRights() const
+ {
+ return mCanInviteUsers;
+ }
+
+ void setRights(short rights);
+
+ bool isMember(PartyMember *member) const;
+
+ bool isMember(int id) const;
+
+ bool isMember(const std::string &name) const;
+
+ void getNames(std::vector<std::string> &names) const;
+
+ static Party *getParty(int id);
+
+private:
+ typedef std::map<int, Party*> PartyMap;
+ static PartyMap parties;
+
+ /**
+ * Constructor with guild id passed to it.
+ */
+ Party(short id);
+
+ typedef std::vector<PartyMember*> MemberList;
+ MemberList mMembers;
+ std::string mName;
+ short mId;
+ bool mCanInviteUsers;
+};
+
+#endif // PARTY_H
diff --git a/src/player.cpp b/src/player.cpp
index e7a63232..3dc0a6df 100644
--- a/src/player.cpp
+++ b/src/player.cpp
@@ -25,10 +25,12 @@
#include "guild.h"
#include "localplayer.h"
#include "particle.h"
+#include "party.h"
#include "player.h"
#include "text.h"
#include "gui/palette.h"
+#include "gui/socialwindow.h"
#include "net/charhandler.h"
#include "net/net.h"
@@ -42,8 +44,8 @@
Player::Player(int id, int job, Map *map, bool isNPC):
Being(id, job, map),
mGender(GENDER_UNSPECIFIED),
- mIsGM(false),
- mInParty(false)
+ mParty(NULL),
+ mIsGM(false)
{
if (!isNPC)
{
@@ -213,16 +215,23 @@ void Player::setSpriteColor(unsigned int slot, const std::string &color)
setSprite(slot, mSpriteIDs[slot], color);
}
-Guild* Player::addGuild(short guildId, short rights)
+void Player::addGuild(Guild *guild)
{
- Guild *guild = Guild::getGuild(guildId);
- guild->setRights(rights);
- mGuilds.insert(std::pair<int, Guild*>(guildId, guild));
- return guild;
+ mGuilds[guild->getId()] = guild;
+
+ if (this == player_node && socialWindow)
+ {
+ socialWindow->addTab(guild);
+ }
}
void Player::removeGuild(int id)
{
+ if (this == player_node && socialWindow)
+ {
+ socialWindow->removeTab(mGuilds[id]);
+ }
+
mGuilds.erase(id);
}
@@ -253,16 +262,24 @@ Guild *Player::getGuild(int id) const
return NULL;
}
-short Player::getNumberOfGuilds()
+void Player::setParty(Party *party)
{
- return mGuilds.size();
-}
+ if (party == mParty)
+ return;
-void Player::setInParty(bool inParty)
-{
- mInParty = inParty;
+ Party *old = mParty;
+ mParty = party;
updateColors();
+
+ if (this == player_node && socialWindow)
+ {
+ if (old)
+ socialWindow->removeTab(old);
+
+ if (party)
+ socialWindow->addTab(party);
+ }
}
void Player::optionChanged(const std::string &value)
@@ -282,7 +299,7 @@ void Player::updateColors()
mTextColor = &guiPalette->getColor(Palette::GM);
mNameColor = &guiPalette->getColor(Palette::GM_NAME);
}
- else if (mInParty)
+ else if (mParty != NULL)
{
mNameColor = &guiPalette->getColor(Palette::PARTY);
}
diff --git a/src/player.h b/src/player.h
index 2d46b4de..6e2566b8 100644
--- a/src/player.h
+++ b/src/player.h
@@ -25,8 +25,9 @@
#include "being.h"
class Graphics;
-class Map;
class Guild;
+class Map;
+class Party;
enum Gender
{
@@ -86,7 +87,7 @@ class Player : public Being
/**
* Adds a guild to the player.
*/
- Guild *addGuild(short guildId, short rights);
+ void addGuild(Guild *guild);
/**
* Removers a guild from the player.
@@ -106,16 +107,13 @@ class Player : public Being
/**
* Get number of guilds the player belongs to.
*/
- short getNumberOfGuilds();
+ short getNumberOfGuilds() const { return mGuilds.size(); }
- /**
- * Set whether the player in the LocalPlayer's party. Players that are
- * in the same party as the local player get their name displayed in
- * a different color.
- */
- void setInParty(bool inParty);
+ bool isInParty() const { return mParty != NULL; }
+
+ void setParty(Party *party);
- bool isInParty() const { return mInParty; }
+ Party *getParty() const { return mParty; }
/**
* Gets the way the character is blocked by other objects.
@@ -143,11 +141,9 @@ class Player : public Being
// Character guild information
std::map<int, Guild*> mGuilds;
+ Party *mParty;
bool mIsGM;
-
- private:
- bool mInParty;
};
#endif