summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/game.cpp24
-rw-r--r--src/game.h32
-rw-r--r--src/graphic/graphic.cpp16
-rw-r--r--src/graphic/graphic.h3
-rw-r--r--src/gui/buy.cpp4
-rw-r--r--src/gui/buy.h2
-rw-r--r--src/gui/buysell.cpp4
-rw-r--r--src/gui/buysell.h2
-rw-r--r--src/gui/char_select.cpp26
-rw-r--r--src/gui/char_select.h46
-rw-r--r--src/gui/char_server.cpp42
-rw-r--r--src/gui/char_server.h2
-rw-r--r--src/gui/gui.cpp8
-rw-r--r--src/gui/gui.h3
-rw-r--r--src/gui/inventory.cpp4
-rw-r--r--src/gui/inventory.h18
-rw-r--r--src/gui/login.cpp25
-rw-r--r--src/gui/login.h2
-rw-r--r--src/gui/npc.cpp4
-rw-r--r--src/gui/npc.h2
-rw-r--r--src/gui/npc_text.cpp4
-rw-r--r--src/gui/npc_text.h2
-rw-r--r--src/gui/ok_dialog.cpp7
-rw-r--r--src/gui/ok_dialog.h7
-rw-r--r--src/gui/sell.cpp4
-rw-r--r--src/gui/sell.h2
-rw-r--r--src/gui/setup.cpp6
-rw-r--r--src/gui/setup.h2
-rw-r--r--src/gui/skill.cpp5
-rw-r--r--src/gui/skill.h25
-rw-r--r--src/gui/stats.cpp6
-rw-r--r--src/gui/stats.h2
-rw-r--r--src/gui/status.cpp4
-rw-r--r--src/gui/status.h9
-rw-r--r--src/gui/window.cpp18
-rw-r--r--src/gui/window.h20
-rw-r--r--src/gui/windowcontainer.cpp75
-rw-r--r--src/gui/windowcontainer.h51
-rw-r--r--src/main.cpp74
39 files changed, 392 insertions, 200 deletions
diff --git a/src/game.cpp b/src/game.cpp
index adad9e0f..71340f16 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -101,10 +101,6 @@ void second(void) {
}
END_OF_FUNCTION(second);
-/**
- * Return elapsed time (Warning: very unsafe function. It supposes the delay
- * is always < MAX_TIME ms)
- */
short get_elapsed_time(short start_time) {
if (start_time <= tick_time) {
return tick_time - start_time;
@@ -114,9 +110,6 @@ short get_elapsed_time(short start_time) {
}
}
-/**
- * Main game loop
- */
void game() {
do_init();
GraphicEngine *graphicEngine = new GraphicEngine();
@@ -146,9 +139,6 @@ void game() {
close_session();
}
-/**
- * Initialize game engine
- */
void do_init() {
if (!load_map(map_path)) {
error("Could not find map file");
@@ -188,15 +178,9 @@ void do_init() {
remove("./docs/packet.list");
}
-/**
- * Clean the engine
- */
void do_exit() {
}
-/**
- * Check user input
- */
void do_input() {
if (walk_status == 0) {
int x = get_x(player_node->coordinates);
@@ -354,18 +338,12 @@ bool handle_key(int unicode, int scancode)
return false;
}
-/**
- * Calculate packet length
- */
int get_packet_length(short id) {
int len = get_length(id);
if (len == -1)len = RFIFOW(2);
return len;
}
-/**
- * Parse data received from map server into input buffer
- */
void do_parse() {
unsigned short id;
char *temp;
@@ -665,7 +643,7 @@ void do_parse() {
}
statusWindow->update();
if(char_info->hp==0) {
- OkDialog *death = new OkDialog(guiTop,
+ OkDialog *death = new OkDialog("Message",
"You're now dead, press ok to restart");
alert("","","","","",0,0);
WFIFOW(0) = net_w_value(0x00b2);
diff --git a/src/game.h b/src/game.h
index 148596f1..5598d5ba 100644
--- a/src/game.h
+++ b/src/game.h
@@ -77,18 +77,40 @@ extern int server_tick;
*/
bool handle_key(int unicode, int scancode);
+/**
+ * Main game loop
+ */
void game();
+
+/**
+ * Initialize game engine
+ */
void do_init();
+
+/**
+ * Check user input
+ */
void do_input();
+
+/**
+ * Parse data received from map server into input buffer
+ */
void do_parse();
-void do_graphic();
-void do_logic();
+
+/**
+ * Clean the engine
+ */
void do_exit();
-int get_packet_length(short);
-char get_x_offset(char, char);
-char get_y_offset(char, char);
+/**
+ * Calculate packet length
+ */
+int get_packet_length(short);
+/**
+ * Returns elapsed time. (Warning: very unsafe function, it supposes the delay
+ * is always < 10 seconds)
+ */
short get_elapsed_time(short start_time);
#endif
diff --git a/src/graphic/graphic.cpp b/src/graphic/graphic.cpp
index 3b9e1e1e..0e5b9a32 100644
--- a/src/graphic/graphic.cpp
+++ b/src/graphic/graphic.cpp
@@ -158,29 +158,29 @@ GraphicEngine::GraphicEngine() {
// Create dialogs
- statusWindow = new StatusWindow(guiTop);
+ statusWindow = new StatusWindow();
statusWindow->setPosition(SCREEN_W - statusWindow->getWidth() - 10, 10);
- buyDialog = new BuyDialog(guiTop);
+ buyDialog = new BuyDialog();
buyDialog->setVisible(false);
- sellDialog = new SellDialog(guiTop);
+ sellDialog = new SellDialog();
sellDialog->setVisible(false);
- buySellDialog = new BuySellDialog(guiTop, new BuySellListener());
+ buySellDialog = new BuySellDialog(new BuySellListener());
buySellDialog->setVisible(false);
- inventoryWindow = new InventoryWindow(guiTop);
+ inventoryWindow = new InventoryWindow();
inventoryWindow->setVisible(false);
inventoryWindow->setPosition(100, 100);
- npcTextDialog = new NpcTextDialog(guiTop);
+ npcTextDialog = new NpcTextDialog();
npcTextDialog->setVisible(false);
- npcListDialog = new NpcListDialog(guiTop);
+ npcListDialog = new NpcListDialog();
npcListDialog->setVisible(false);
- skillDialog = new SkillDialog(guiTop);
+ skillDialog = new SkillDialog();
skillDialog->setVisible(false);
// Give focus to the chat input
diff --git a/src/graphic/graphic.h b/src/graphic/graphic.h
index ea9b71f0..ed62bf79 100644
--- a/src/graphic/graphic.h
+++ b/src/graphic/graphic.h
@@ -65,6 +65,9 @@ extern NpcListDialog *npcListDialog;
extern NpcTextDialog *npcTextDialog;
extern SkillDialog *skillDialog;
+char get_x_offset(char, char);
+char get_y_offset(char, char);
+
/**
* The action listener for the chat field.
*/
diff --git a/src/gui/buy.cpp b/src/gui/buy.cpp
index 8eefa503..ca76b40f 100644
--- a/src/gui/buy.cpp
+++ b/src/gui/buy.cpp
@@ -29,8 +29,8 @@
#include <sstream>
-BuyDialog::BuyDialog(gcn::Container *parent):
- Window(parent, "Buy"),
+BuyDialog::BuyDialog():
+ Window("Buy"),
money(0)
{
itemList = new ListBox(this);
diff --git a/src/gui/buy.h b/src/gui/buy.h
index c58f5248..7a6bd484 100644
--- a/src/gui/buy.h
+++ b/src/gui/buy.h
@@ -44,7 +44,7 @@ class BuyDialog : public Window, public gcn::ActionListener,
*
* @see Window::Window
*/
- BuyDialog(gcn::Container *parent);
+ BuyDialog();
/**
* Destructor.
diff --git a/src/gui/buysell.cpp b/src/gui/buysell.cpp
index eae19917..d522e6f2 100644
--- a/src/gui/buysell.cpp
+++ b/src/gui/buysell.cpp
@@ -24,8 +24,8 @@
#include "buysell.h"
#include "button.h"
-BuySellDialog::BuySellDialog(gcn::Container *parent, gcn::ActionListener *al):
- Window(parent, "Shop")
+BuySellDialog::BuySellDialog(gcn::ActionListener *al):
+ Window("Shop")
{
buyButton = new Button("Buy");
sellButton = new Button("Sell");
diff --git a/src/gui/buysell.h b/src/gui/buysell.h
index 5289f649..02ddb816 100644
--- a/src/gui/buysell.h
+++ b/src/gui/buysell.h
@@ -40,7 +40,7 @@ class BuySellDialog : public Window {
*
* @see Window::Window
*/
- BuySellDialog(gcn::Container *parent, gcn::ActionListener *al);
+ BuySellDialog(gcn::ActionListener *al);
/**
* Destructor.
diff --git a/src/gui/char_select.cpp b/src/gui/char_select.cpp
index 537a33ad..d54b8ca7 100644
--- a/src/gui/char_select.cpp
+++ b/src/gui/char_select.cpp
@@ -23,11 +23,13 @@
#include "char_select.h"
#include "textfield.h"
+#include "button.h"
+#include "ok_dialog.h"
#include "../graphic/graphic.h"
#include "../main.h"
-CharSelectDialog::CharSelectDialog(gcn::Container *parent)
- : Window(parent, "Select Character")
+CharSelectDialog::CharSelectDialog():
+ Window("Select Character")
{
selectButton = new Button(" OK ");
cancelButton = new Button("Cancel");
@@ -112,8 +114,8 @@ int curHairColor = 0;
int curHairStyle = 0;
std::string curName;
-CharCreateDialog::CharCreateDialog(gcn::Container *parent)
- : Window(parent, "Create Character")
+CharCreateDialog::CharCreateDialog():
+ Window("Create Character")
{
nameField = new TextField("");
nameLabel = new gcn::Label("Name:");
@@ -208,7 +210,7 @@ void CharCreateDialog::action(const std::string& eventId)
void charSelect()
{
CharSelectDialog *sel;
- sel = new CharSelectDialog(guiTop);
+ sel = new CharSelectDialog();
state = LOGIN;
@@ -306,7 +308,7 @@ void serverCharSelect()
void charCreate()
{
- CharCreateDialog *create = new CharCreateDialog(guiTop);
+ CharCreateDialog *create = new CharCreateDialog();
state = LOGIN;
while (!key[KEY_ESC] && !key[KEY_ENTER] && state != EXIT &&
@@ -344,7 +346,7 @@ void charCreate()
void serverCharDelete() {
state = CHAR_SELECT;
// Delete a character
- if (yes_no("Confirm", "Are you sure?")==0) {
+ if (yes_no("Confirm", "Are you sure?") == 0) {
// Request character deletion
WFIFOW(0) = net_w_value(0x0068);
WFIFOL(2) = net_l_value(char_info->id);
@@ -353,10 +355,11 @@ void serverCharDelete() {
while ((in_size < 2) || (out_size > 0)) flush();
if (RFIFOW(0) == 0x006f) {
RFIFOSKIP(2);
- ok("Info", "Player deleted");
free(char_info);
n_character = 0;
- } else if (RFIFOW(0) == 0x006c) {
+ ok("Info", "Player deleted");
+ }
+ else if (RFIFOW(0) == 0x006c) {
switch (RFIFOB(2)) {
case 0:
ok("Error", "Access denied");
@@ -366,7 +369,10 @@ void serverCharDelete() {
break;
}
RFIFOSKIP(3);
- } else ok("Error", "Unknown error");
+ }
+ else {
+ ok("Error", "Unknown error");
+ }
}
}
diff --git a/src/gui/char_select.h b/src/gui/char_select.h
index ef643725..475deab0 100644
--- a/src/gui/char_select.h
+++ b/src/gui/char_select.h
@@ -29,7 +29,6 @@
#include "../main.h"
#include "../net/network.h"
#include "gui.h"
-#include "button.h"
#include <guichan/allegro.hpp>
/**
@@ -39,10 +38,10 @@
*/
class CharSelectDialog : public Window, public gcn::ActionListener {
private:
- Button *selectButton;
- Button *cancelButton;
- Button *newCharButton;
- Button *delCharButton;
+ gcn::Button *selectButton;
+ gcn::Button *cancelButton;
+ gcn::Button *newCharButton;
+ gcn::Button *delCharButton;
gcn::Label *nameLabel;
gcn::Label *levelLabel;
@@ -50,22 +49,33 @@ class CharSelectDialog : public Window, public gcn::ActionListener {
gcn::Label *moneyLabel;
public:
- CharSelectDialog(gcn::Container *parent);
+ /**
+ * Constructor.
+ */
+ CharSelectDialog();
+
+ /**
+ * Destructor.
+ */
~CharSelectDialog();
void action(const std::string& eventId);
+
void setName(const std::string name)
{
nameLabel->setCaption(name);
}
+
void setLevel(const std::string level)
{
levelLabel->setCaption(level);
}
+
void setJobLevel(const std::string level)
{
jobLevelLabel->setCaption(level);
}
+
void setMoney(const std::string money)
{
moneyLabel->setCaption(money);
@@ -81,21 +91,31 @@ class CharCreateDialog : public Window, public gcn::ActionListener {
private:
gcn::TextField *nameField;
gcn::Label *nameLabel;
- Button *nextHairColorButton;
- Button *prevHairColorButton;
+ gcn::Button *nextHairColorButton;
+ gcn::Button *prevHairColorButton;
gcn::Label *hairColorLabel;
- Button *nextHairStyleButton;
- Button *prevHairStyleButton;
+ gcn::Button *nextHairStyleButton;
+ gcn::Button *prevHairStyleButton;
gcn::Label *hairStyleLabel;
- Button *createButton;
+ gcn::Button *createButton;
public:
- CharCreateDialog(gcn::Container *parent);
+ /**
+ * Constructor.
+ */
+ CharCreateDialog();
+
+ /**
+ * Destructor.
+ */
~CharCreateDialog();
void action(const std::string& eventId);
- std::string getName() { return nameField->getText(); }
+
+ std::string getName() {
+ return nameField->getText();
+ }
};
void charSelect();
diff --git a/src/gui/char_server.cpp b/src/gui/char_server.cpp
index 4543a829..b042a05a 100644
--- a/src/gui/char_server.cpp
+++ b/src/gui/char_server.cpp
@@ -27,13 +27,14 @@
#include "window.h"
#include "scrollarea.h"
#include "listbox.h"
+#include "ok_dialog.h"
char server[30];
int showServerList = 1;
-ServerSelectDialog::ServerSelectDialog(gcn::Container *parent):
- Window(parent, "Select Server")
+ServerSelectDialog::ServerSelectDialog():
+ Window("Select Server")
{
serverListModel = new ServerListModel();
serverList = new ListBox(serverListModel);
@@ -110,7 +111,7 @@ std::string ServerListModel::getElementAt(int i) {
void char_server() {
- ServerSelectDialog *dialog = new ServerSelectDialog(guiTop);
+ ServerSelectDialog *dialog = new ServerSelectDialog();
state = LOGIN;
@@ -132,7 +133,7 @@ void server_char_server(int serverIndex) {
ret = open_session(iptostring(server_info[serverIndex].address),
server_info[serverIndex].port);
if (ret == SOCKET_ERROR) {
- ok("Error", "Unable to connect to char server");
+ new OkDialog("Error", "Unable to connect to char server");
return;
}
@@ -145,16 +146,16 @@ void server_char_server(int serverIndex) {
WFIFOB(16) = net_b_value(sex);
WFIFOSET(17);
- while((in_size<4)||(out_size>0))flush();
+ while ((in_size<4)||(out_size>0))flush();
RFIFOSKIP(4);
- while(in_size<3)flush();
+ while (in_size<3)flush();
- if(RFIFOW(0)==0x006b) {
+ if (RFIFOW(0)==0x006b) {
while(in_size<RFIFOW(2))flush();
n_character = (RFIFOW(2)-24)/106;
- char_info = (PLAYER_INFO *)malloc(sizeof(PLAYER_INFO)*n_character);
- for(int i=0;i<n_character;i++) {
+ char_info = (PLAYER_INFO *)malloc(sizeof(PLAYER_INFO) * n_character);
+ for (int i = 0; i < n_character; i++) {
char_info[i].id = RFIFOL(24+106*i);
strcpy(char_info[i].name, RFIFOP(24+106*i+74));
char_info[i].hp = RFIFOW(24+106*i+42);
@@ -183,20 +184,19 @@ void server_char_server(int serverIndex) {
RFIFOSKIP(RFIFOW(2));
- } else if(RFIFOW(0)==0x006c) {
- switch(RFIFOB(2)) {
- case 0:
- ok("Error", "Access denied");
- break;
- case 1:
- ok("Error", "Cannot use this ID");
- break;
- default:
- ok("Error", "Rejected from server");
- break;
+ }
+ else if (RFIFOW(0) == 0x006c) {
+ std::string errorStr;
+ switch (RFIFOB(2)) {
+ case 0: errorStr = "Access denied"; break;
+ case 1: errorStr = "Cannot use this ID"; break;
+ default: errorStr = "Rejected from server"; break;
}
+ new OkDialog("Error", errorStr);
RFIFOSKIP(3);
close_session();
- } else ok("Error", "Unknown error");
+ } else {
+ new OkDialog("Error", "Unknown error");
+ }
// Todo: add other packets
}
diff --git a/src/gui/char_server.h b/src/gui/char_server.h
index 31c7c448..cc1bbe6b 100644
--- a/src/gui/char_server.h
+++ b/src/gui/char_server.h
@@ -59,7 +59,7 @@ class ServerSelectDialog : public Window, public gcn::ActionListener {
*
* @see Window::Window
*/
- ServerSelectDialog(gcn::Container *parent);
+ ServerSelectDialog();
/**
* Destructor
diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp
index 5cd475af..dac21c00 100644
--- a/src/gui/gui.cpp
+++ b/src/gui/gui.cpp
@@ -28,6 +28,7 @@
#include "../log.h"
#include "../sound/sound.h"
#include "allegroinput.h"
+#include "window.h"
#include "windowcontainer.h"
#define GUI_BMP_COUNT 11
@@ -49,9 +50,9 @@ DATAFILE *gui_gfx;
// Guichan stuff
-Gui* gui;
-gcn::AllegroGraphics* guiGraphics; // Graphics driver
-gcn::Container* guiTop; // The top container
+Gui *gui;
+gcn::AllegroGraphics *guiGraphics; // Graphics driver
+WindowContainer *guiTop; // The top container
Gui::Gui(BITMAP *screen)
@@ -71,6 +72,7 @@ Gui::Gui(BITMAP *screen)
guiTop = new WindowContainer();
guiTop->setDimension(gcn::Rectangle(0, 0, SCREEN_W, SCREEN_H));
guiTop->setOpaque(false);
+ Window::setWindowContainer(guiTop);
// Create focus handler
focusHandler = new gcn::FocusHandler();
diff --git a/src/gui/gui.h b/src/gui/gui.h
index 1055db0b..e3a77f31 100644
--- a/src/gui/gui.h
+++ b/src/gui/gui.h
@@ -32,6 +32,7 @@
#include <guichan/allegro.hpp>
#include <allegro.h>
#include <string.h>
+#include "windowcontainer.h"
/**
* \defgroup GUI GUI related classes
@@ -163,7 +164,7 @@ extern LexSkin gui_skin;
extern BITMAP *gui_bitmap;
extern Gui* gui;
-extern gcn::Container* guiTop; // The top container
+extern WindowContainer* guiTop; // The top container
extern gcn::AllegroGraphics* guiGraphics; // Graphics driver
/** Initialize gui system */
diff --git a/src/gui/inventory.cpp b/src/gui/inventory.cpp
index 8d75f34e..8662841e 100644
--- a/src/gui/inventory.cpp
+++ b/src/gui/inventory.cpp
@@ -24,8 +24,8 @@
#include "inventory.h"
#include <sstream>
-InventoryWindow::InventoryWindow(gcn::Container *parent):
- Window(parent, "Inventory")
+InventoryWindow::InventoryWindow():
+ Window("Inventory")
{
setSize(322, 60);
diff --git a/src/gui/inventory.h b/src/gui/inventory.h
index 21ffe6bc..87a99b07 100644
--- a/src/gui/inventory.h
+++ b/src/gui/inventory.h
@@ -40,12 +40,11 @@
#define INVENTORY_SIZE 100
struct ITEM_HOLDER { // the holder of a item
- int id; // the id of the item
- int quantity; // number of items
- //int index; // item position
+ int id; // the id of the item
+ int quantity; // number of items
+ //int index; // item position
};
-
/**
* Inventory dialog.
*
@@ -53,7 +52,14 @@ struct ITEM_HOLDER { // the holder of a item
*/
class InventoryWindow : public Window {
public:
- InventoryWindow(gcn::Container *parent);
+ /**
+ * Constructor.
+ */
+ InventoryWindow();
+
+ /**
+ * Destructor.
+ */
~InventoryWindow();
/**
@@ -77,7 +83,7 @@ class InventoryWindow : public Window {
int changeQuantity(int index, int quantity);
/**
- * Increase quantity of an item
+ * Increase quantity of an item.
*/
int increaseQuantity(int index, int quantity);
diff --git a/src/gui/login.cpp b/src/gui/login.cpp
index 00797917..08276562 100644
--- a/src/gui/login.cpp
+++ b/src/gui/login.cpp
@@ -27,10 +27,11 @@
#include "checkbox.h"
#include "textfield.h"
#include "passwordfield.h"
+#include "ok_dialog.h"
#include "../graphic/graphic.h"
-LoginDialog::LoginDialog(gcn::Container *parent):
- Window(parent, "Login")
+LoginDialog::LoginDialog():
+ Window("Login")
{
userLabel = new gcn::Label("Name:");
passLabel = new gcn::Label("Password:");
@@ -129,7 +130,7 @@ void LoginDialog::action(const std::string& eventId)
void login() {
- LoginDialog *dialog = new LoginDialog(guiTop);
+ LoginDialog *dialog = new LoginDialog();
while (state == LOGIN) {
blit(login_wallpaper, buffer, 0, 0, 0, 0, 800, 600);
@@ -181,17 +182,17 @@ void server_login(const std::string& user, const std::string& pass) {
while (in_size < RFIFOW(2)) {
flush();
}
- n_server = (RFIFOW(2)-47)/32;
- server_info = (SERVER_INFO*)malloc(sizeof(SERVER_INFO)*n_server);
+ n_server = (RFIFOW(2) - 47) / 32;
+ server_info = (SERVER_INFO*)malloc(sizeof(SERVER_INFO) * n_server);
account_ID = RFIFOL(8);
session_ID1 = RFIFOL(4);
session_ID2 = RFIFOL(12);
sex = RFIFOB(46);
for (int i = 0; i < n_server; i++) {
- server_info[i].address = RFIFOL(47+32*i);
- memcpy(server_info[i].name, RFIFOP(47+32*i+6), 20);
- server_info[i].online_users = RFIFOW(47+32*i+26);
- server_info[i].port = RFIFOW(47+32*i+4);
+ server_info[i].address = RFIFOL(47 + 32 * i);
+ memcpy(server_info[i].name, RFIFOP(47 + 32 * i + 6), 20);
+ server_info[i].online_users = RFIFOW(47 + 32 * i + 26);
+ server_info[i].port = RFIFOW(47 + 32 * i + 4);
state = CHAR_SERVER;
}
log("Network", "Server: %s (%s:%d)", server_info[0].name,
@@ -203,17 +204,17 @@ void server_login(const std::string& user, const std::string& pass) {
else if (RFIFOW(0) == 0x006a) {
switch (RFIFOB(2)) {
case 0:
- ok("Error", "Unregistered ID");
+ new OkDialog("Error", "Unregistered ID");
break;
case 1:
- ok("Error", "Wrong password");
+ new OkDialog("Error", "Wrong password");
break;
}
state = LOGIN;
RFIFOSKIP(23);
}
else {
- ok("Error", "Unknown error");
+ new OkDialog("Error", "Unknown error");
}
// Todo: add other packets, also encrypted
}
diff --git a/src/gui/login.h b/src/gui/login.h
index 3157a727..b133a2c5 100644
--- a/src/gui/login.h
+++ b/src/gui/login.h
@@ -52,7 +52,7 @@ class LoginDialog : public Window, public gcn::ActionListener {
*
* @see Window::Window
*/
- LoginDialog(gcn::Container *parent);
+ LoginDialog();
/**
* Destructor
diff --git a/src/gui/npc.cpp b/src/gui/npc.cpp
index fbb55d65..73e1393a 100644
--- a/src/gui/npc.cpp
+++ b/src/gui/npc.cpp
@@ -27,8 +27,8 @@
#include "listbox.h"
#include "../game.h"
-NpcListDialog::NpcListDialog(gcn::Container *parent):
- Window(parent, "NPC")
+NpcListDialog::NpcListDialog():
+ Window("NPC")
{
itemList = new ListBox(this);
scrollArea = new ScrollArea(itemList);
diff --git a/src/gui/npc.h b/src/gui/npc.h
index d0810201..68d63c4f 100644
--- a/src/gui/npc.h
+++ b/src/gui/npc.h
@@ -43,7 +43,7 @@ class NpcListDialog : public Window, public gcn::ActionListener,
*
* @see Window::Window
*/
- NpcListDialog(gcn::Container *parent);
+ NpcListDialog();
/**
* Destructor.
diff --git a/src/gui/npc_text.cpp b/src/gui/npc_text.cpp
index f86f45e9..27c28512 100644
--- a/src/gui/npc_text.cpp
+++ b/src/gui/npc_text.cpp
@@ -27,8 +27,8 @@
#include "textbox.h"
#include "../game.h"
-NpcTextDialog::NpcTextDialog(gcn::Container *parent):
- Window(parent, "NPC")
+NpcTextDialog::NpcTextDialog():
+ Window("NPC")
{
textBox = new TextBox();
textBox->setEditable(false);
diff --git a/src/gui/npc_text.h b/src/gui/npc_text.h
index 6bb7d943..ed228931 100644
--- a/src/gui/npc_text.h
+++ b/src/gui/npc_text.h
@@ -42,7 +42,7 @@ class NpcTextDialog : public Window, public gcn::ActionListener
*
* @see Window::Window
*/
- NpcTextDialog(gcn::Container *parent);
+ NpcTextDialog();
/**
* Destructor.
diff --git a/src/gui/ok_dialog.cpp b/src/gui/ok_dialog.cpp
index b997cdb2..887c09f7 100644
--- a/src/gui/ok_dialog.cpp
+++ b/src/gui/ok_dialog.cpp
@@ -22,9 +22,10 @@
*/
#include "ok_dialog.h"
+#include "button.h"
-OkDialog::OkDialog(gcn::Container *parent, std::string msg):
- Window(parent, "Message")
+OkDialog::OkDialog(const std::string& title, const std::string& msg):
+ Window(title, true)
{
userLabel = new gcn::Label(msg);
okButton = new Button("OK");
@@ -52,5 +53,7 @@ OkDialog::~OkDialog()
void OkDialog::action(const std::string& eventId)
{
if (eventId == "ok") {
+ //getParent()->remove(this);
+ windowContainer->scheduleDelete(this);
}
}
diff --git a/src/gui/ok_dialog.h b/src/gui/ok_dialog.h
index cc04546b..ad0359b1 100644
--- a/src/gui/ok_dialog.h
+++ b/src/gui/ok_dialog.h
@@ -26,7 +26,6 @@
#include "gui.h"
#include "window.h"
-#include "button.h"
/**
* An 'Ok' button dialog.
@@ -36,14 +35,14 @@
class OkDialog : public Window, public gcn::ActionListener {
public:
/**
- * Constructor
+ * Constructor.
*
* @see Window::Window
*/
- OkDialog(gcn::Container *parent, std::string);
+ OkDialog(const std::string &title, const std::string &msg);
/**
- * Destructor
+ * Destructor.
*/
~OkDialog();
diff --git a/src/gui/sell.cpp b/src/gui/sell.cpp
index bdf6ec6d..d24daff3 100644
--- a/src/gui/sell.cpp
+++ b/src/gui/sell.cpp
@@ -30,8 +30,8 @@
#include <sstream>
-SellDialog::SellDialog(gcn::Container *parent):
- Window(parent, "Sell")
+SellDialog::SellDialog():
+ Window("Sell")
{
itemList = new ListBox(this);
scrollArea = new ScrollArea(itemList);
diff --git a/src/gui/sell.h b/src/gui/sell.h
index 610d1aca..50da5a10 100644
--- a/src/gui/sell.h
+++ b/src/gui/sell.h
@@ -44,7 +44,7 @@ class SellDialog : public Window, public gcn::ActionListener,
*
* @see Window::Window
*/
- SellDialog(gcn::Container *parent);
+ SellDialog();
/**
* Destructor.
diff --git a/src/gui/setup.cpp b/src/gui/setup.cpp
index d3a8e0ae..89f7e0a4 100644
--- a/src/gui/setup.cpp
+++ b/src/gui/setup.cpp
@@ -58,8 +58,8 @@ std::string ModeListModel::getElementAt(int i) {
return modes[i].desc;
}
-Setup::Setup(gcn::Container *parent)
- : Window(parent, "Setup")
+Setup::Setup():
+ Window("Setup")
{
modeListModel = new ModeListModel();
displayLabel = new gcn::Label("Display settings");
@@ -174,7 +174,7 @@ void Setup::action(const std::string& eventId)
Setup *Setup::ptr = NULL;
Setup *Setup::create_setup() {
if (ptr == NULL) {
- ptr = new Setup(guiTop);
+ ptr = new Setup();
}
else {
ptr->setVisible(true);
diff --git a/src/gui/setup.h b/src/gui/setup.h
index 7cb6c120..a1b00ea1 100644
--- a/src/gui/setup.h
+++ b/src/gui/setup.h
@@ -72,7 +72,7 @@ class Setup : public Window, public gcn::ActionListener {
/**
* Constructor.
*/
- Setup(gcn::Container *parent);
+ Setup();
/**
* Destructor.
diff --git a/src/gui/skill.cpp b/src/gui/skill.cpp
index 2139c4ff..b66a5426 100644
--- a/src/gui/skill.cpp
+++ b/src/gui/skill.cpp
@@ -24,6 +24,7 @@
#include "skill.h"
#include "listbox.h"
#include "scrollarea.h"
+#include "button.h"
extern PLAYER_INFO *char_info;
@@ -112,8 +113,8 @@ void SkillListModel::setSkill(int id, int lv, int sp)
}
-SkillDialog::SkillDialog(gcn::Container *parent)
- : Window(parent, "Skills")
+SkillDialog::SkillDialog():
+ Window("Skills")
{
skills = new SkillListModel();
skillListBox = new ListBox(skills);
diff --git a/src/gui/skill.h b/src/gui/skill.h
index 78f48e30..0b0f737b 100644
--- a/src/gui/skill.h
+++ b/src/gui/skill.h
@@ -25,7 +25,6 @@
#define _TMW_SKILL_H
#include <allegro.h>
-#include "button.h"
#include "../main.h"
struct SKILL {
@@ -40,9 +39,18 @@ struct SKILL {
*/
class SkillListModel : public gcn::ListModel
{
- std::vector<SKILL*> skillList;
+ private:
+ std::vector<SKILL*> skillList;
+
public:
+ /**
+ * Constructor.
+ */
SkillListModel();
+
+ /**
+ * Destructor.
+ */
virtual ~SkillListModel();
int getNumberOfElements();
@@ -66,11 +74,18 @@ class SkillDialog : public Window, public gcn::ActionListener
SkillListModel *skills;
gcn::Label *pointsLabel;
- Button *incButton;
- Button *closeButton;
+ gcn::Button *incButton;
+ gcn::Button *closeButton;
public:
- SkillDialog(gcn::Container *);
+ /**
+ * Constructor.
+ */
+ SkillDialog();
+
+ /**
+ * Destructor.
+ */
~SkillDialog();
void action(const std::string&);
diff --git a/src/gui/stats.cpp b/src/gui/stats.cpp
index eebfab70..d8ea9c34 100644
--- a/src/gui/stats.cpp
+++ b/src/gui/stats.cpp
@@ -25,8 +25,8 @@
extern PLAYER_INFO *char_info;
-StatsWindow::StatsWindow(gcn::Container *parent)
- : Window(parent, "Stats")
+StatsWindow::StatsWindow():
+ Window("Stats")
{
// New labels
for (i = 0; i < 6; i++) {
@@ -91,7 +91,7 @@ StatsWindow::~StatsWindow() {
StatsWindow * StatsWindow::ptr = NULL;
StatsWindow * StatsWindow::create_statswindow() {
if (ptr == NULL) {
- ptr = new StatsWindow(guiTop);
+ ptr = new StatsWindow();
}
else {
ptr->setVisible(true);
diff --git a/src/gui/stats.h b/src/gui/stats.h
index b1844e91..95ee235e 100644
--- a/src/gui/stats.h
+++ b/src/gui/stats.h
@@ -69,7 +69,7 @@ class StatsWindow : public Window, public gcn::ActionListener {
/**
* Constructor.
*/
- StatsWindow(gcn::Container *parent);
+ StatsWindow();
/**
* Destructor.
diff --git a/src/gui/status.cpp b/src/gui/status.cpp
index 454b42b3..21a3c4a7 100644
--- a/src/gui/status.cpp
+++ b/src/gui/status.cpp
@@ -23,8 +23,8 @@
#include "status.h"
-StatusWindow::StatusWindow(gcn::Container *parent):
- Window(parent, "%s Lvl: % 2i Job: % 2i")
+StatusWindow::StatusWindow():
+ Window("%s Lvl: % 2i Job: % 2i")
{
hp = new gcn::Label("HP");
sp = new gcn::Label("SP");
diff --git a/src/gui/status.h b/src/gui/status.h
index bf5758bf..77cea322 100644
--- a/src/gui/status.h
+++ b/src/gui/status.h
@@ -41,7 +41,14 @@
*/
class StatusWindow : public Window {
public:
- StatusWindow(gcn::Container *parent);
+ /**
+ * Constructor.
+ */
+ StatusWindow();
+
+ /**
+ * Destructor.
+ */
~StatusWindow();
/**
diff --git a/src/gui/window.cpp b/src/gui/window.cpp
index 52665213..19621c07 100644
--- a/src/gui/window.cpp
+++ b/src/gui/window.cpp
@@ -25,7 +25,9 @@
#include "gui.h"
#include <guichan/allegro.hpp>
-Window::Window(gcn::Container *parent, const std::string& text) :
+WindowContainer *Window::windowContainer = NULL;
+
+Window::Window(const std::string& text, bool modal):
caption(text),
mousePX(0),
mousePY(0),
@@ -53,8 +55,13 @@ Window::Window(gcn::Container *parent, const std::string& text) :
chrome->setY(titlebarHeight);
gcn::Container::add(chrome);
- // Add this window to the parent container
- parent->add(this);
+ // Add this window to the window container
+ if (windowContainer) {
+ windowContainer->add(this, modal);
+ }
+ else {
+ throw GCN_EXCEPTION("Window::Window. no windowContainer set");
+ }
}
Window::~Window()
@@ -67,6 +74,11 @@ Window::~Window()
delete chrome;
}
+void Window::setWindowContainer(WindowContainer *wc)
+{
+ windowContainer = wc;
+}
+
void Window::draw(gcn::Graphics* graphics)
{
// Draw container background when opaque
diff --git a/src/gui/window.h b/src/gui/window.h
index 0a0170d8..b80a14c1 100644
--- a/src/gui/window.h
+++ b/src/gui/window.h
@@ -27,6 +27,7 @@
#include <iostream>
#include <allegro.h>
#include <guichan.hpp>
+#include "windowcontainer.h"
/**
* A window. This window can be dragged around and has a title bar.
@@ -35,7 +36,7 @@
*/
class Window : public gcn::Container, public gcn::MouseListener
{
- private:
+ protected:
gcn::Container *chrome; /**< Contained container */
std::string caption; /**< Title bar caption */
int z; /**< Z position of the window */
@@ -50,21 +51,28 @@ class Window : public gcn::Container, public gcn::MouseListener
BITMAP *dMid; /**< Middle of title bar */
BITMAP *dRight; /**< Right side of title bar */
+ /** The window container windows add themselves to. */
+ static WindowContainer* windowContainer;
+
public:
/**
* Constructor. Initializes the title to the given text and hooks
- * itself into the given parent.
+ * itself into the window container.
*
- * @param parent The parent container to which this window will add
- * itself.
* @param text The initial window title, "Window" by default.
+ * @param modal Block input to other windows.
*/
- Window(gcn::Container *parent, const std::string& text = "Window");
+ Window(const std::string& text = "Window", bool modal = false);
/**
* Destructor.
*/
- ~Window();
+ virtual ~Window();
+
+ /**
+ * Sets the window container to be used by new windows.
+ */
+ static void setWindowContainer(WindowContainer *windowContainer);
/**
* Draws the window.
diff --git a/src/gui/windowcontainer.cpp b/src/gui/windowcontainer.cpp
index 460b99e5..c9ce6eff 100644
--- a/src/gui/windowcontainer.cpp
+++ b/src/gui/windowcontainer.cpp
@@ -21,14 +21,26 @@
* $Id$
*/
+#include <iostream>
#include "windowcontainer.h"
WindowContainer::WindowContainer():
- gcn::Container(),
- mouseDown(false)
+ mouseDown(false),
+ modalWidget(NULL)
{
}
+void WindowContainer::logic()
+{
+ std::list<gcn::Widget*>::iterator i = deathList.begin();
+ while (i != deathList.end()) {
+ delete (*i);
+ i = deathList.erase(i);
+ }
+
+ gcn::Container::logic();
+}
+
void WindowContainer::_mouseInputMessage(const gcn::MouseInput &mouseInput)
{
if (mouseInput.getType() == gcn::MouseInput::PRESS)
@@ -40,19 +52,18 @@ void WindowContainer::_mouseInputMessage(const gcn::MouseInput &mouseInput)
mouseDown = false;
}
- /*
- * Make drag events not change widget with mouse. The Window instances
- * need this behaviour to be able to handle window dragging.
- */
+ // Make drag events not change widget with mouse. The Window instances
+ // need this behaviour to be able to handle window dragging.
if (!(mouseInput.getType() == gcn::MouseInput::MOTION && mouseDown))
{
Widget* tempWidgetWithMouse = NULL;
- WidgetIterator iter;
+ WidgetIterator iter;
for (iter = mWidgets.begin(); iter != mWidgets.end(); iter++)
{
if ((*iter)->getDimension().isPointInRect(
- mouseInput.x, mouseInput.y) && (*iter)->isVisible())
+ mouseInput.x, mouseInput.y) &&
+ (*iter)->isVisible())
{
tempWidgetWithMouse = (*iter);
}
@@ -72,7 +83,8 @@ void WindowContainer::_mouseInputMessage(const gcn::MouseInput &mouseInput)
}
}
- if (mWidgetWithMouse && !mWidgetWithMouse->hasFocus()) {
+ if (mWidgetWithMouse && !mWidgetWithMouse->hasFocus() &&
+ (!modalWidget || modalWidget == mWidgetWithMouse)) {
gcn::MouseInput mi = mouseInput;
mi.x -= mWidgetWithMouse->getX();
mi.y -= mWidgetWithMouse->getY();
@@ -83,3 +95,48 @@ void WindowContainer::_mouseInputMessage(const gcn::MouseInput &mouseInput)
gcn::Widget::_mouseInputMessage(mouseInput);
}
}
+
+void WindowContainer::add(gcn::Widget *widget, bool modal)
+{
+ gcn::Container::add(widget);
+ if (modal) {
+ setModalWidget(widget);
+ }
+}
+
+void WindowContainer::remove(gcn::Widget *widget)
+{
+ if (modalWidget == widget) {
+ modalWidget = NULL;
+ }
+ gcn::Container::remove(widget);
+}
+
+void WindowContainer::_announceDeath(gcn::Widget *widget)
+{
+ if (modalWidget == widget) {
+ modalWidget = NULL;
+ }
+ gcn::Container::_announceDeath(widget);
+}
+
+void WindowContainer::clear()
+{
+ modalWidget = NULL;
+ gcn::Container::clear();
+}
+
+void WindowContainer::setModalWidget(gcn::Widget *widget)
+{
+ modalWidget = widget;
+}
+
+gcn::Widget *WindowContainer::getModalWidget()
+{
+ return modalWidget;
+}
+
+void WindowContainer::scheduleDelete(gcn::Widget *widget)
+{
+ deathList.push_back(widget);
+}
diff --git a/src/gui/windowcontainer.h b/src/gui/windowcontainer.h
index e74b1831..8b5753a5 100644
--- a/src/gui/windowcontainer.h
+++ b/src/gui/windowcontainer.h
@@ -39,13 +39,64 @@ class WindowContainer : public gcn::Container {
WindowContainer();
/**
+ * Do GUI logic. This functions adds automatic deletion of objects that
+ * volunteered to be deleted.
+ */
+ void logic();
+
+ /**
* Handles mouse input messages. Differs from standard behaviour in
* that widget with mouse doesn't change while a button is pressed.
*/
void _mouseInputMessage(const gcn::MouseInput &mouseInput);
+ /**
+ * Adds a widget. The widget can be set to be modal, which will ensure
+ * only that widget will receive input.
+ */
+ void add(gcn::Widget *widget, bool modal = false);
+
+ /**
+ * Removes a widget.
+ */
+ void remove(gcn::Widget *widget);
+
+ /**
+ * This function is called by the containers children when they get
+ * destroyed.
+ */
+ void _announceDeath(gcn::Widget *widget);
+
+ /**
+ * Clears the container of all widgets.
+ */
+ void clear();
+
+ /**
+ * Sets the modal widget. This will ensure only this widget will
+ * receive mouse or keyboard input events.
+ *
+ * @see Window::Window
+ */
+ void setModalWidget(gcn::Widget *widget);
+
+ /**
+ * Returns the current modal widget, or <code>NULL</code> if there
+ * is none.
+ */
+ gcn::Widget *getModalWidget();
+
+ /**
+ * Schedule a widget for deletion. It will be deleted at the start of
+ * the next logic update.
+ */
+ void scheduleDelete(gcn::Widget *widget);
+
protected:
bool mouseDown;
+ gcn::Widget *modalWidget;
+
+ std::list<gcn::Widget*> deathList;
};
#endif
diff --git a/src/main.cpp b/src/main.cpp
index a955ea01..625b385d 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -294,22 +294,8 @@ void init_engine() {
// TODO: Remove Allegro config file usage from GUI look
init_gui(buffer, "data/Skin/aqua.skin");
state = LOGIN;
-}
-/** Clear the engine */
-void exit_engine() {
- config.write(dir);
- delete dir;
- gui_exit();
- destroy_bitmap(buffer);
- allegro_exit();
-}
-
-/** Main */
-int main() {
- init_engine();
#ifndef WIN32
-
// initialize sound-engine and start playing intro-theme /-kth5
try {
if (config.getValue("sound", 0) == 1) {
@@ -328,33 +314,47 @@ int main() {
warning(err);
}
#endif /* not WIN32 */
+}
+
+/** Clear the engine */
+void exit_engine() {
+ config.write(dir);
+ delete dir;
+ gui_exit();
+ destroy_bitmap(buffer);
+ allegro_exit();
+}
+
+/** Main */
+int main() {
+ init_engine();
while (state != EXIT) {
- switch(state) {
- case LOGIN:
- status("LOGIN");
- login();
- break;
- case CHAR_SERVER:
- status("CHAR_SERVER");
- char_server();
- break;
- case CHAR_SELECT:
- status("CHAR_SELECT");
- charSelect();
- break;
- case GAME:
+ switch (state) {
+ case LOGIN:
+ status("LOGIN");
+ login();
+ break;
+ case CHAR_SERVER:
+ status("CHAR_SERVER");
+ char_server();
+ break;
+ case CHAR_SELECT:
+ status("CHAR_SELECT");
+ charSelect();
+ break;
+ case GAME:
#ifndef WIN32
- sound.stopBgm();
+ sound.stopBgm();
#endif /* not WIN32 */
- status("GAME");
- map_start();
- if( state==GAME )
- game();
- break;
- default:
- state = EXIT;
- break;
+ status("GAME");
+ map_start();
+ if (state == GAME)
+ game();
+ break;
+ default:
+ state = EXIT;
+ break;
}
}
status("EXIT");