diff options
author | Bjørn Lindeijer <bjorn@lindeijer.nl> | 2005-01-08 01:33:53 +0000 |
---|---|---|
committer | Bjørn Lindeijer <bjorn@lindeijer.nl> | 2005-01-08 01:33:53 +0000 |
commit | ee416a5f3de03a689247a290077e7fdf451e1a23 (patch) | |
tree | f456df99f954919ac7a425606df51f010aa4ef2d /src | |
parent | 4070dda1560bc729c3e272f0a5c03d77391e2661 (diff) | |
download | mana-ee416a5f3de03a689247a290077e7fdf451e1a23.tar.gz mana-ee416a5f3de03a689247a290077e7fdf451e1a23.tar.bz2 mana-ee416a5f3de03a689247a290077e7fdf451e1a23.tar.xz mana-ee416a5f3de03a689247a290077e7fdf451e1a23.zip |
Well improved window container and window widgets a bit, and made a start
on support for modal dialogs. Still some issues to work out. Tell me if you
experience something unsettling.
Diffstat (limited to 'src')
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); @@ -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"); |