diff options
Diffstat (limited to 'src/gui')
174 files changed, 11086 insertions, 3317 deletions
diff --git a/src/gui/box.cpp b/src/gui/box.cpp deleted file mode 100644 index 59d8c135..00000000 --- a/src/gui/box.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/* - * The Mana World - * Copyright 2004 The Mana World Development Team - * - * This file is part of The Mana World. - * - * The Mana World 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. - * - * The Mana World 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 The Mana World; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "box.h" - -Box::Box(): - padding(0) -{ - setOpaque(false); -} - -Box::~Box() -{ -} - -unsigned int Box::getPadding() -{ - return padding; -} - -void Box::setPadding(unsigned int p) -{ - padding = p; -} diff --git a/src/gui/box.h b/src/gui/box.h deleted file mode 100644 index 46654b48..00000000 --- a/src/gui/box.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * The Mana World - * Copyright 2004 The Mana World Development Team - * - * This file is part of The Mana World. - * - * The Mana World 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. - * - * The Mana World 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 The Mana World; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#ifndef BOX_H -#define BOX_H - -#include <guichan/widgets/container.hpp> - -#include "../guichanfwd.h" - -class Box : public gcn::Container -{ - public: - /** - * Returns padding. - */ - unsigned int getPadding(); - - /** - * Sets padding between widgets. - */ - void setPadding(unsigned int); - - protected: - Box(); - virtual ~Box(); - - /** - * Spacing between client widgets. - */ - unsigned int padding; - - virtual void draw(gcn::Graphics *) = 0; - - typedef std::list<gcn::Widget*> Widgets; - typedef Widgets::iterator WidgetIterator; -}; - -#endif diff --git a/src/gui/browserbox.cpp b/src/gui/browserbox.cpp index 03540d31..7c0ae1a7 100644 --- a/src/gui/browserbox.cpp +++ b/src/gui/browserbox.cpp @@ -1,35 +1,37 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include <algorithm> -#include "browserbox.h" +#include <guichan/graphics.hpp> +#include "browserbox.h" +#include "color.h" #include "linkhandler.h" #include "truetypefont.h" -BrowserBox::BrowserBox(unsigned int mode): +BrowserBox::BrowserBox(unsigned int mode, bool opaque): gcn::Widget(), mMode(mode), mHighMode(UNDERLINE | BACKGROUND), - mOpaque(true), + mOpaque(opaque), mUseLinksAndUserColors(true), mSelectedLink(-1), mMaxRows(0) @@ -98,12 +100,12 @@ void BrowserBox::addRow(const std::string &row) mLinks.push_back(bLink); - newRow += "##L" + bLink.caption; + newRow += "##<" + bLink.caption; tmp.erase(0, idx3 + 2); - if(tmp != "") + if (!tmp.empty()) { - newRow += "##P"; + newRow += "##>"; } idx1 = tmp.find("@@"); } @@ -122,7 +124,18 @@ void BrowserBox::addRow(const std::string &row) //discard older rows when a row limit has been set if (mMaxRows > 0) { - while (mTextRows.size() > mMaxRows) mTextRows.pop_front(); + while (mTextRows.size() > mMaxRows) + { + mTextRows.pop_front(); + for (unsigned int i = 0; i < mLinks.size(); i++) + { + mLinks[i].y1 -= font->getHeight(); + mLinks[i].y2 -= font->getHeight(); + + if (mLinks[i].y1 < 0) + mLinks.erase(mLinks.begin() + i); + } + } } // Auto size mode @@ -210,8 +223,7 @@ struct MouseOverLink int mX, mY; }; -void -BrowserBox::mousePressed(gcn::MouseEvent &event) +void BrowserBox::mousePressed(gcn::MouseEvent &event) { LinkIterator i = find_if(mLinks.begin(), mLinks.end(), MouseOverLink(event.getX(), event.getY())); @@ -221,8 +233,7 @@ BrowserBox::mousePressed(gcn::MouseEvent &event) } } -void -BrowserBox::mouseMoved(gcn::MouseEvent &event) +void BrowserBox::mouseMoved(gcn::MouseEvent &event) { LinkIterator i = find_if(mLinks.begin(), mLinks.end(), MouseOverLink(event.getX(), event.getY())); @@ -230,8 +241,7 @@ BrowserBox::mouseMoved(gcn::MouseEvent &event) mSelectedLink = (i != mLinks.end()) ? (i - mLinks.begin()) : -1; } -void -BrowserBox::draw(gcn::Graphics *graphics) +void BrowserBox::draw(gcn::Graphics *graphics) { if (mOpaque) { @@ -241,9 +251,10 @@ BrowserBox::draw(gcn::Graphics *graphics) if (mSelectedLink >= 0) { + bool valid; if ((mHighMode & BACKGROUND)) { - graphics->setColor(gcn::Color(HIGHLIGHT)); + graphics->setColor(gcn::Color(textColor->getColor('H', valid))); graphics->fillRectangle(gcn::Rectangle( mLinks[mSelectedLink].x1, mLinks[mSelectedLink].y1, @@ -254,7 +265,7 @@ BrowserBox::draw(gcn::Graphics *graphics) if ((mHighMode & UNDERLINE)) { - graphics->setColor(gcn::Color(LINK)); + graphics->setColor(gcn::Color(textColor->getColor('<', valid))); graphics->drawLine( mLinks[mSelectedLink].x1, mLinks[mSelectedLink].y2, @@ -265,6 +276,7 @@ BrowserBox::draw(gcn::Graphics *graphics) int x = 0, y = 0; int wrappedLines = 0; + int link = 0; TrueTypeFont *font = static_cast<TrueTypeFont*>(getFont()); graphics->setColor(BLACK); @@ -311,57 +323,36 @@ BrowserBox::draw(gcn::Graphics *graphics) // Check for color change in format "##x", x = [L,P,0..9] if (row.find("##", start) == start && row.size() > start + 2) { - switch (row.at(start + 2)) + char c = row.at(start + 2); + if (c == '>') { - case 'L': // Link color - prevColor = selColor; - selColor = LINK; - break; - case 'P': // Previous color - selColor = prevColor; - break; - case '1': - prevColor = selColor; - selColor = RED; - break; - case '2': - prevColor = selColor; - selColor = GREEN; - break; - case '3': - prevColor = selColor; - selColor = BLUE; - break; - case '4': - prevColor = selColor; - selColor = ORANGE; - break; - case '5': - prevColor = selColor; - selColor = YELLOW; - break; - case '6': - prevColor = selColor; - selColor = PINK; - break; - case '7': - prevColor = selColor; - selColor = PURPLE; - break; - case '8': - prevColor = selColor; - selColor = GRAY; - break; - case '9': - prevColor = selColor; - selColor = BROWN; - break; - case '0': - default: + selColor = prevColor; + } + else + { + bool valid; + int rgb = textColor->getColor(c, valid); + if (c == '<') + { + const int size = mLinks[link].x2 - mLinks[link].x1; + mLinks[link].x1 = x; + mLinks[link].y1 = y; + mLinks[link].x2 = mLinks[link].x1 + size; + mLinks[link].y2 = y + font->getHeight(); + link++; prevColor = selColor; - selColor = BLACK; + } + if (valid) + { + selColor = rgb; + } } start += 3; + + if (start == row.size()) + { + break; + } } graphics->setColor(gcn::Color(selColor)); } diff --git a/src/gui/browserbox.h b/src/gui/browserbox.h index cb4c23ed..090c03e1 100644 --- a/src/gui/browserbox.h +++ b/src/gui/browserbox.h @@ -1,36 +1,33 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef __TMW_BROWSERBOX_H__ -#define __TMW_BROWSERBOX_H__ +#ifndef BROWSERBOX_H +#define BROWSERBOX_H -#include <iosfwd> +#include <list> #include <vector> #include <guichan/mouselistener.hpp> #include <guichan/widget.hpp> -#include "../guichanfwd.h" -#include "../main.h" - class LinkHandler; struct BROWSER_LINK { @@ -49,7 +46,7 @@ class BrowserBox : public gcn::Widget, public gcn::MouseListener /** * Constructor. */ - BrowserBox(unsigned int mode = AUTO_SIZE); + BrowserBox(unsigned int mode = AUTO_SIZE, bool opaque = true); /** * Destructor. @@ -124,7 +121,7 @@ class BrowserBox : public gcn::Widget, public gcn::MouseListener enum { BLACK = 0x000000, /**< Color 0 */ RED = 0xff0000, /**< Color 1 */ - GREEN = 0x1fa052, /**< Color 2 */ + GREEN = 0x009000, /**< Color 2 */ BLUE = 0x0000ff, /**< Color 3 */ ORANGE = 0xe0980e, /**< Color 4 */ YELLOW = 0xf1dc27, /**< Color 5 */ diff --git a/src/gui/button.cpp b/src/gui/button.cpp index 40ecd1b7..1d3a04e4 100644 --- a/src/gui/button.cpp +++ b/src/gui/button.cpp @@ -1,32 +1,30 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include <algorithm> - #include <guichan/exception.hpp> -#include <guichan/graphics.hpp> -#include <guichan/imagefont.hpp> +#include <guichan/font.hpp> #include "button.h" +#include "../configuration.h" #include "../graphics.h" #include "../resources/image.h" @@ -35,6 +33,7 @@ #include "../utils/dtor.h" int Button::mInstances = 0; +float Button::mAlpha = config.getValue("guialpha", 0.8); enum{ BUTTON_STANDARD, // 0 @@ -52,10 +51,10 @@ struct ButtonData }; static ButtonData const data[BUTTON_COUNT] = { - {"graphics/gui/button.png", 0, 0}, - {"graphics/gui/buttonhi.png", 9, 4}, - {"graphics/gui/buttonpress.png", 16, 19}, - {"graphics/gui/button_disabled.png", 25, 23} + { "graphics/gui/button.png", 0, 0 }, + { "graphics/gui/buttonhi.png", 9, 4 }, + { "graphics/gui/buttonpress.png", 16, 19 }, + { "graphics/gui/button_disabled.png", 25, 23 } }; ImageRect Button::button[BUTTON_COUNT]; @@ -100,6 +99,7 @@ void Button::init() data[x].gridX, data[y].gridY, data[x + 1].gridX - data[x].gridX + 1, data[y + 1].gridY - data[y].gridY + 1); + button[mode].grid[a]->setAlpha(mAlpha); a++; } } @@ -122,22 +122,29 @@ Button::~Button() } } -void -Button::draw(gcn::Graphics *graphics) +void Button::draw(gcn::Graphics *graphics) { int mode; - if (!isEnabled()) { + if (!isEnabled()) mode = BUTTON_DISABLED; - } - else if (isPressed() || mIsLogged) { + else if (isPressed() || mIsLogged) mode = BUTTON_PRESSED; - } - else if (mHasMouse || isFocused()) { + else if (mHasMouse || isFocused()) mode = BUTTON_HIGHLIGHTED; - } - else { + else mode = BUTTON_STANDARD; + + if (config.getValue("guialpha", 0.8) != mAlpha) + { + mAlpha = config.getValue("guialpha", 0.8); + for (int a = 0; a < 9; a++) + { + button[BUTTON_DISABLED].grid[a]->setAlpha(mAlpha); + button[BUTTON_PRESSED].grid[a]->setAlpha(mAlpha); + button[BUTTON_HIGHLIGHTED].grid[a]->setAlpha(mAlpha); + button[BUTTON_STANDARD].grid[a]->setAlpha(mAlpha); + } } static_cast<Graphics*>(graphics)-> @@ -148,7 +155,8 @@ Button::draw(gcn::Graphics *graphics) int textX; int textY = getHeight() / 2 - getFont()->getHeight() / 2; - switch (getAlignment()) { + switch (getAlignment()) + { case gcn::Graphics::LEFT: textX = 4; break; @@ -164,10 +172,8 @@ Button::draw(gcn::Graphics *graphics) graphics->setFont(getFont()); - if (isPressed()) { + if (isPressed()) graphics->drawText(getCaption(), textX + 1, textY + 1, getAlignment()); - } - else { + else graphics->drawText(getCaption(), textX, textY, getAlignment()); - } } diff --git a/src/gui/button.h b/src/gui/button.h index f451416c..abaf5c43 100644 --- a/src/gui/button.h +++ b/src/gui/button.h @@ -1,28 +1,26 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TMW_BUTTON_H -#define _TMW_BUTTON_H - -#include <iosfwd> +#ifndef BUTTON_H +#define BUTTON_H #include <guichan/widgets/button.hpp> @@ -33,7 +31,8 @@ class ImageRect; * * \ingroup GUI */ -class Button : public gcn::Button { +class Button : public gcn::Button +{ public: /** * Default constructor. @@ -44,7 +43,7 @@ class Button : public gcn::Button { * Constructor, sets the caption of the button to the given string and * adds the given action listener. */ - Button(const std::string& caption, const std::string &actionEventId, + Button(const std::string &caption, const std::string &actionEventId, gcn::ActionListener *listener); /** @@ -55,7 +54,7 @@ class Button : public gcn::Button { /** * Draws the button. */ - void draw(gcn::Graphics* graphics); + void draw(gcn::Graphics *graphics); /** * Enable/Disable highlighting @@ -68,6 +67,7 @@ class Button : public gcn::Button { static ImageRect button[4]; /**< Button state graphics */ static int mInstances; /**< Number of button instances */ + static float mAlpha; bool mIsLogged; /**< Makes the button appear pressed all the time */ }; diff --git a/src/gui/buy.cpp b/src/gui/buy.cpp index cc2262ec..15a558a3 100644 --- a/src/gui/buy.cpp +++ b/src/gui/buy.cpp @@ -1,29 +1,28 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "buy.h" - #include <guichan/widgets/label.hpp> #include "button.h" +#include "buy.h" #include "scrollarea.h" #include "shop.h" #include "shoplistbox.h" @@ -32,12 +31,27 @@ #include "widgets/layout.h" #include "../npc.h" +#include "../units.h" + +#ifdef TMWSERV_SUPPORT #include "../net/gameserver/player.h" +#else +#include "../net/messageout.h" +#include "../net/ea/protocol.h" +#endif + #include "../utils/gettext.h" #include "../utils/strprintf.h" +#ifdef TMWSERV_SUPPORT BuyDialog::BuyDialog(): +#else +BuyDialog::BuyDialog(Network *network): +#endif Window(_("Buy")), +#ifndef TMWSERV_SUPPORT + mNetwork(network), +#endif mMoney(0), mAmountItems(0), mMaxItems(0) { setWindowName("Buy"); @@ -52,7 +66,8 @@ BuyDialog::BuyDialog(): mScrollArea = new ScrollArea(mShopItemList); mSlider = new Slider(1.0); mQuantityLabel = new gcn::Label("0"); - mMoneyLabel = new gcn::Label(strprintf(_("Price: %d GP / Total: %d GP"), 0, 0)); + mMoneyLabel = new gcn::Label(strprintf(_("Price: %s / Total: %s"), + "", "")); mIncreaseButton = new Button("+", "+", this); mDecreaseButton = new Button("-", "-", this); mBuyButton = new Button(_("Buy"), "buy", this); @@ -128,7 +143,7 @@ void BuyDialog::action(const gcn::ActionEvent &event) if (event.getId() == "quit") { setVisible(false); - current_npc = 0; + if (current_npc) current_npc->handleDeath(); return; } @@ -162,8 +177,16 @@ void BuyDialog::action(const gcn::ActionEvent &event) else if (event.getId() == "buy" && mAmountItems > 0 && mAmountItems <= mMaxItems) { +#ifdef TMWSERV_SUPPORT Net::GameServer::Player::tradeWithNPC (mShopItems->at(selectedItem)->getId(), mAmountItems); +#else + MessageOut outMsg(mNetwork); + outMsg.writeInt16(CMSG_NPC_BUY_REQUEST); + outMsg.writeInt16(8); + outMsg.writeInt16(mAmountItems); + outMsg.writeInt16(mShopItems->at(selectedItem)->getId()); +#endif // Update money and adjust the max number of items that can be bought mMaxItems -= mAmountItems; @@ -230,5 +253,7 @@ void BuyDialog::updateButtonsAndLabels() // Update quantity and money labels mQuantityLabel->setCaption(strprintf("%d / %d", mAmountItems, mMaxItems)); mMoneyLabel->setCaption - (strprintf(_("Price: %d GP / Total: %d GP"), price, mMoney - price)); + (strprintf(_("Price: %s / Total: %s"), + Units::formatCurrency(price).c_str(), + Units::formatCurrency(mMoney - price).c_str())); } diff --git a/src/gui/buy.h b/src/gui/buy.h index a80ffed7..5510ccc6 100644 --- a/src/gui/buy.h +++ b/src/gui/buy.h @@ -1,26 +1,26 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TMW_BUY_H -#define _TMW_BUY_H +#ifndef BUY_H +#define BUY_H #include <guichan/actionlistener.hpp> #include <guichan/selectionlistener.hpp> @@ -29,6 +29,9 @@ #include "../guichanfwd.h" +#ifndef TMWSERV_SUPPORT +class Network; +#endif class ShopItems; class ShopListBox; class ListBox; @@ -39,7 +42,7 @@ class ListBox; * \ingroup Interface */ class BuyDialog : public Window, public gcn::ActionListener, - gcn::SelectionListener + public gcn::SelectionListener { public: /** @@ -47,7 +50,11 @@ class BuyDialog : public Window, public gcn::ActionListener, * * @see Window::Window */ +#ifdef TMWSERV_SUPPORT BuyDialog(); +#else + BuyDialog(Network *network); +#endif /** * Destructor @@ -95,6 +102,9 @@ class BuyDialog : public Window, public gcn::ActionListener, void updateButtonsAndLabels(); private: +#ifdef EATHENA_SUPPORT + Network *mNetwork; +#endif gcn::Button *mBuyButton; gcn::Button *mQuitButton; gcn::Button *mIncreaseButton; diff --git a/src/gui/buysell.cpp b/src/gui/buysell.cpp index 42380882..2d39eac7 100644 --- a/src/gui/buysell.cpp +++ b/src/gui/buysell.cpp @@ -1,42 +1,43 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "buysell.h" - #include "button.h" +#include "buysell.h" #include "../npc.h" +#include "../utils/gettext.h" + BuySellDialog::BuySellDialog(): - Window("Shop") + Window(_("Shop")) { Button *buyButton = 0; - const char *buttonNames[] = { - "Buy", "Sell", "Cancel", 0 + static const char *buttonNames[] = { + N_("Buy"), N_("Sell"), N_("Cancel"), 0 }; int x = 10, y = 10; for (const char **curBtn = buttonNames; *curBtn; curBtn++) { - Button *btn = new Button(*curBtn, *curBtn, this); + Button *btn = new Button(gettext(*curBtn), *curBtn, this); if (!buyButton) buyButton = btn; // For focus request btn->setPosition(x, y); add(btn); @@ -57,7 +58,7 @@ void BuySellDialog::action(const gcn::ActionEvent &event) } else if (event.getId() == "Sell") { current_npc->sell(); } else if (event.getId() == "Cancel") { - current_npc = 0; + if (current_npc) current_npc->handleDeath(); } setVisible(false); } diff --git a/src/gui/buysell.h b/src/gui/buysell.h index 2391ed1c..e3cdc52a 100644 --- a/src/gui/buysell.h +++ b/src/gui/buysell.h @@ -1,26 +1,26 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TMW_BUYSELL_H -#define _TMW_BUYSELL_H +#ifndef BUYSELL_H +#define BUYSELL_H #include <guichan/actionlistener.hpp> diff --git a/src/gui/char_select.cpp b/src/gui/char_select.cpp index f800c266..84270d10 100644 --- a/src/gui/char_select.cpp +++ b/src/gui/char_select.cpp @@ -1,57 +1,65 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "char_select.h" - #include <string> +#include <guichan/font.hpp> + #include <guichan/widgets/label.hpp> #include "button.h" -#include "radiobutton.h" +#include "char_select.h" #include "confirm_dialog.h" #include "ok_dialog.h" #include "playerbox.h" -#include "slider.h" #include "textfield.h" +#ifdef TMWSERV_SUPPORT +#include "radiobutton.h" +#include "slider.h" + #include "unregisterdialog.h" #include "changepassworddialog.h" #include "changeemaildialog.h" +#include "../logindata.h" + +#include "../net/accountserver/account.h" +#endif + #include "widgets/layout.h" #include "../game.h" #include "../localplayer.h" #include "../main.h" -#include "../logindata.h" +#include "../units.h" -#include "../net/accountserver/account.h" #include "../net/charserverhandler.h" #include "../net/messageout.h" +#include "../resources/colordb.h" + #include "../utils/gettext.h" #include "../utils/strprintf.h" -#include "../utils/tostring.h" -#include "../utils/trim.h" +#include "../utils/stringutils.h" // Defined in main.cpp, used here for setting the char create dialog extern CharServerHandler charServerHandler; @@ -78,24 +86,37 @@ CharDeleteConfirm::CharDeleteConfirm(CharSelectDialog *m): void CharDeleteConfirm::action(const gcn::ActionEvent &event) { //ConfirmDialog::action(event); - if (event.getId() == "yes") { + if (event.getId() == "yes") + { master->attemptCharDelete(); } ConfirmDialog::action(event); } +#ifdef TMWSERV_SUPPORT CharSelectDialog::CharSelectDialog(LockedArray<LocalPlayer*> *charInfo, LoginData *loginData): Window(_("Account and Character Management")), mCharInfo(charInfo), mCharSelected(false), mLoginData(loginData) +#else +CharSelectDialog::CharSelectDialog(Network *network, + LockedArray<LocalPlayer*> *charInfo, + Gender gender): + Window(_("Select Character")), mNetwork(network), + mCharInfo(charInfo), + mCharSelected(false), + mGender(gender) +#endif { - mSelectButton = new Button(_("Ok"), "ok", this); mCancelButton = new Button(_("Cancel"), "cancel", this); - mNewCharButton = new Button(_("New"), "new", this); - mDelCharButton = new Button(_("Delete"), "delete", this); mPreviousButton = new Button(_("Previous"), "previous", this); mNextButton = new Button(_("Next"), "next", this); + mNameLabel = new gcn::Label(strprintf(_("Name: %s"), "")); + mLevelLabel = new gcn::Label(strprintf(_("Level: %d"), 0)); +#ifdef TMWSERV_SUPPORT + mNewCharButton = new Button(_("New"), "new", this); + mDelCharButton = new Button(_("Delete"), "delete", this); mUnRegisterButton = new Button(_("Unregister"), "unregister", this); mChangePasswordButton = new Button(_("Change Password"), "change_password", this); mChangeEmailButton = new Button(_("Change Email Address"), "change_email", this); @@ -129,6 +150,42 @@ CharSelectDialog::CharSelectDialog(LockedArray<LocalPlayer*> *charInfo, place(0, 0, mSelectButton); place(1, 0, mCancelButton); reflowLayout(265, 0); +#else + mCharInfo->select(0); + LocalPlayer *pi = mCharInfo->getEntry(); + if (pi) + mMoney = Units::formatCurrency(pi->getMoney()); + // Control that shows the Player + mPlayerBox = new PlayerBox; + mPlayerBox->setWidth(74); + + mJobLevelLabel = new gcn::Label(strprintf(_("Job Level: %d"), 0)); + mMoneyLabel = new gcn::Label(strprintf(_("Money: %s"), mMoney.c_str())); + + const std::string tempString = getFont()->getWidth(_("New")) < + getFont()->getWidth(_("Delete")) ? + _("Delete") : _("New"); + + mNewDelCharButton = new Button(tempString, "newdel", this); + + ContainerPlacer place; + place = getPlacer(0, 0); + + place(0, 0, mPlayerBox, 1, 6).setPadding(3); + place(1, 0, mNewDelCharButton); + place(1, 1, mNameLabel, 5); + place(1, 2, mLevelLabel, 5); + place(1, 3, mJobLevelLabel, 5); + place(1, 4, mMoneyLabel, 5); + place.getCell().matchColWidth(1, 4); + place = getPlacer(0, 2); + place(0, 0, mPreviousButton); + place(1, 0, mNextButton); + place(4, 0, mCancelButton); + place(5, 0, mSelectButton); + + reflowLayout(250, 0); +#endif setLocationRelativeTo(getParent()); setVisible(true); @@ -138,25 +195,37 @@ CharSelectDialog::CharSelectDialog(LockedArray<LocalPlayer*> *charInfo, void CharSelectDialog::action(const gcn::ActionEvent &event) { +#ifdef TMWSERV_SUPPORT // The pointers are set to NULL if there is no character stored if (event.getId() == "ok" && (mCharInfo->getEntry())) +#else + if (event.getId() == "ok" && n_character > 0) +#endif { // Start game +#ifdef TMWSERV_SUPPORT mNewCharButton->setEnabled(false); mDelCharButton->setEnabled(false); - mSelectButton->setEnabled(false); mUnRegisterButton->setEnabled(false); +#else + mNewDelCharButton->setEnabled(false); +#endif + mSelectButton->setEnabled(false); mPreviousButton->setEnabled(false); mNextButton->setEnabled(false); mCharSelected = true; - Net::AccountServer::Account::selectCharacter(mCharInfo->getPos()); - mCharInfo->lock(); + attemptCharSelect(); } else if (event.getId() == "cancel") { +#ifdef TMWSERV_SUPPORT mCharInfo->clear(); state = STATE_SWITCH_ACCOUNTSERVER_ATTEMPT; +#else + state = STATE_EXIT; +#endif } +#ifdef TMWSERV_SUPPORT else if (event.getId() == "new") { // TODO: Search the first free slot, and start CharCreateDialog @@ -177,14 +246,39 @@ void CharSelectDialog::action(const gcn::ActionEvent &event) new CharDeleteConfirm(this); } } +#else + else if (event.getId() == "newdel") + { + // Check for a character + if (mCharInfo->getEntry() && n_character <= MAX_SLOT + 1) + { + new CharDeleteConfirm(this); + } + else + { + // Start new character dialog + CharCreateDialog *charCreateDialog = + new CharCreateDialog(this, mCharInfo->getPos(), + mNetwork, mGender); + charServerHandler.setCharCreateDialog(charCreateDialog); + } + } +#endif else if (event.getId() == "previous") { mCharInfo->prev(); + LocalPlayer *pi = mCharInfo->getEntry(); + if (pi) + mMoney = Units::formatCurrency(pi->getMoney()); } else if (event.getId() == "next") { mCharInfo->next(); + LocalPlayer *pi = mCharInfo->getEntry(); + if (pi) + mMoney = Units::formatCurrency(pi->getMoney()); } +#ifdef TMWSERV_SUPPORT else if (event.getId() == "unregister") { new UnRegisterDialog(this, mLoginData); @@ -197,6 +291,7 @@ void CharSelectDialog::action(const gcn::ActionEvent &event) { new ChangeEmailDialog(this, mLoginData); } +#endif } void CharSelectDialog::updatePlayerInfo() @@ -205,22 +300,39 @@ void CharSelectDialog::updatePlayerInfo() if (pi) { - mNameLabel->setCaption(strprintf(_("Name: %s"), pi->getName().c_str())); + mNameLabel->setCaption(strprintf(_("Name: %s"), + pi->getName().c_str())); mLevelLabel->setCaption(strprintf(_("Level: %d"), pi->getLevel())); - mMoneyLabel->setCaption(strprintf(_("Money: %d"), pi->getMoney())); +#ifndef TMWSERV_SUPPORT + mJobLevelLabel->setCaption(strprintf(_("Job Level: %d"), + pi->mJobLevel)); +#endif + mMoneyLabel->setCaption(strprintf(_("Money: %s"), mMoney.c_str())); if (!mCharSelected) { +#ifdef TMWSERV_SUPPORT mNewCharButton->setEnabled(false); mDelCharButton->setEnabled(true); +#else + mNewDelCharButton->setCaption(_("Delete")); +#endif mSelectButton->setEnabled(true); } } - else { + else + { mNameLabel->setCaption(strprintf(_("Name: %s"), "")); mLevelLabel->setCaption(strprintf(_("Level: %d"), 0)); - mMoneyLabel->setCaption(strprintf(_("Money: %d"), 0)); +#ifndef TMWSERV_SUPPORT + mJobLevelLabel->setCaption(strprintf(_("Job Level: %d"), 0)); +#endif + mMoneyLabel->setCaption(strprintf(_("Money: %s"), "")); +#ifdef TMWSERV_SUPPORT mNewCharButton->setEnabled(true); mDelCharButton->setEnabled(false); +#else + mNewDelCharButton->setCaption(_("New")); +#endif mSelectButton->setEnabled(false); } @@ -229,7 +341,28 @@ void CharSelectDialog::updatePlayerInfo() void CharSelectDialog::attemptCharDelete() { +#ifdef TMWSERV_SUPPORT Net::AccountServer::Account::deleteCharacter(mCharInfo->getPos()); +#else + // Request character deletion + MessageOut outMsg(mNetwork); + outMsg.writeInt16(0x0068); + outMsg.writeInt32(mCharInfo->getEntry()->mCharId); + outMsg.writeString("a@a.com", 40); +#endif + mCharInfo->lock(); +} + +void CharSelectDialog::attemptCharSelect() +{ +#ifdef TMWSERV_SUPPORT + Net::AccountServer::Account::selectCharacter(mCharInfo->getPos()); +#else + // Request character selection + MessageOut outMsg(mNetwork); + outMsg.writeInt16(0x0066); + outMsg.writeInt8(mCharInfo->getPos()); +#endif mCharInfo->lock(); } @@ -246,7 +379,8 @@ bool CharSelectDialog::selectByName(const std::string &name) unsigned int oldPos = mCharInfo->getPos(); mCharInfo->select(0); - do { + do + { LocalPlayer *player = mCharInfo->getEntry(); if (player && player->getName() == name) @@ -260,14 +394,29 @@ bool CharSelectDialog::selectByName(const std::string &name) return false; } - +#ifdef TMWSERV_SUPPORT CharCreateDialog::CharCreateDialog(Window *parent, int slot): - Window(_("Create Character"), true, parent), mSlot(slot) +#else +CharCreateDialog::CharCreateDialog(Window *parent, int slot, Network *network, + Gender gender): +#endif + Window(_("Create Character"), true, parent), +#ifndef TMWSERV_SUPPORT + mNetwork(network), +#endif + mSlot(slot) { mPlayer = new Player(0, 0, NULL); - mPlayer->setHairStyle(rand() % Being::getHairStylesNr(), - rand() % Being::getHairColorsNr()); +#ifdef TMWSERV_SUPPORT mPlayer->setGender(GENDER_MALE); +#else + mPlayer->setGender(gender); +#endif + + int numberOfHairColors = ColorDB::size(); + + mPlayer->setHairStyle(rand() % mPlayer->getNumOfHairstyles(), + rand() % numberOfHairColors); mNameField = new TextField(""); mNameLabel = new gcn::Label(_("Name:")); @@ -279,19 +428,34 @@ CharCreateDialog::CharCreateDialog(Window *parent, int slot): mHairStyleLabel = new gcn::Label(_("Hair Style:")); mCreateButton = new Button(_("Create"), "create", this); mCancelButton = new Button(_("Cancel"), "cancel", this); - +#ifdef TMWSERV_SUPPORT mMale = new RadioButton(_("Male"), "gender"); mFemale = new RadioButton(_("Female"), "gender"); + // Default to a Male character + mMale->setSelected(true); + + mMale->setActionEventId("gender"); + mFemale->setActionEventId("gender"); + + mMale->addActionListener(this); + mFemale->addActionListener(this); +#endif mPlayerBox = new PlayerBox(mPlayer); + mPlayerBox->setWidth(74); + + mNameField->setActionEventId("create"); + mNameField->addActionListener(this); + +#ifdef TMWSERV_SUPPORT mAttributeLabel[0] = new gcn::Label(_("Strength:")); mAttributeLabel[1] = new gcn::Label(_("Agility:")); mAttributeLabel[2] = new gcn::Label(_("Dexterity:")); mAttributeLabel[3] = new gcn::Label(_("Vitality:")); mAttributeLabel[4] = new gcn::Label(_("Intelligence:")); mAttributeLabel[5] = new gcn::Label(_("Willpower:")); - for (int i=0; i<6; i++) + for (int i = 0; i < 6; i++) { mAttributeLabel[i]->setWidth(70); mAttributeSlider[i] = new Slider(1, 20); @@ -300,8 +464,6 @@ CharCreateDialog::CharCreateDialog(Window *parent, int slot): mAttributesLeft = new gcn::Label(strprintf(_("Please distribute %d points"), 99)); - mNameField->setActionEventId("create"); - int w = 200; int h = 330; setContentSize(w, h); @@ -334,19 +496,8 @@ CharCreateDialog::CharCreateDialog(Window *parent, int slot): mCancelButton->getX() - 5 - mCreateButton->getWidth(), h - 5 - mCancelButton->getHeight()); - mNameField->addActionListener(this); - - mMale->setPosition( 30, 120 ); - mFemale->setPosition( 100, 120 ); - - // Default to a Male character - mMale->setSelected(true); - - mMale->setActionEventId("gender"); - mFemale->setActionEventId("gender"); - - mMale->addActionListener(this); - mFemale->addActionListener(this); + mMale->setPosition(30, 120); + mFemale->setPosition(100, 120); add(mPlayerBox); add(mNameField); @@ -357,7 +508,7 @@ CharCreateDialog::CharCreateDialog(Window *parent, int slot): add(mNextHairStyleButton); add(mPrevHairStyleButton); add(mHairStyleLabel); - for (int i=0; i<6; i++) + for (int i = 0; i < 6; i++) { add(mAttributeSlider[i]); add(mAttributeValue[i]); @@ -370,6 +521,28 @@ CharCreateDialog::CharCreateDialog(Window *parent, int slot): add(mMale); add(mFemale); +#else + + ContainerPlacer place; + place = getPlacer(0, 0); + + place(0, 0, mNameLabel, 1); + place(1, 0, mNameField, 6); + place(0, 1, mHairStyleLabel, 1); + place(1, 1, mPrevHairStyleButton); + place(2, 1, mPlayerBox, 1, 8).setPadding(3); + place(3, 1, mNextHairStyleButton); + place(0, 2, mHairColorLabel, 1); + place(1, 2, mPrevHairColorButton); + place(3, 2, mNextHairColorButton); + place.getCell().matchColWidth(0, 2); + place = getPlacer(0, 2); + place(4, 0, mCancelButton); + place(5, 0, mCreateButton); + + reflowLayout(225, 0); +#endif + setLocationRelativeTo(getParent()); setVisible(true); mNameField->requestFocus(); @@ -383,14 +556,16 @@ CharCreateDialog::~CharCreateDialog() charServerHandler.setCharCreateDialog(0); } -void -CharCreateDialog::action(const gcn::ActionEvent &event) +void CharCreateDialog::action(const gcn::ActionEvent &event) { - if (event.getId() == "create") { - if (getName().length() >= 4) { + int numberOfColors = ColorDB::size(); + if (event.getId() == "create") + { + if (getName().length() >= 4) + { // Attempt to create the character mCreateButton->setEnabled(false); - +#ifdef TMWSERV_SUPPORT unsigned int genderSelected; if (mMale->isSelected()) { genderSelected = GENDER_MALE; @@ -410,26 +585,34 @@ CharCreateDialog::action(const gcn::ActionEvent &event) (int) mAttributeSlider[4]->getValue(), // INT (int) mAttributeSlider[5]->getValue() // WILL ); +#else + attemptCharCreate(); +#endif } - else { - new OkDialog(_("Error"),_("Your name needs to be at least 4 characters."), this); + else + { + new OkDialog(_("Error"), + _("Your name needs to be at least 4 characters."), + this); } } - else if (event.getId() == "cancel") { + else if (event.getId() == "cancel") scheduleDelete(); - } - else if (event.getId() == "nextcolor") { - mPlayer->setHairStyle(-1, mPlayer->getHairColor() + 1); - } - else if (event.getId() == "prevcolor") { - mPlayer->setHairStyle(-1, mPlayer->getHairColor() + Being::getHairColorsNr() - 1); - } - else if (event.getId() == "nextstyle") { - mPlayer->setHairStyle(mPlayer->getHairStyle() + 1, -1); - } - else if (event.getId() == "prevstyle") { - mPlayer->setHairStyle(mPlayer->getHairStyle() + Being::getHairStylesNr() - 1, -1); - } + else if (event.getId() == "nextcolor") + mPlayer->setHairStyle(mPlayer->getHairStyle(), + (mPlayer->getHairColor() + 1) % numberOfColors); + else if (event.getId() == "prevcolor") + mPlayer->setHairStyle(mPlayer->getHairStyle(), + (mPlayer->getHairColor() + numberOfColors - 1) % + numberOfColors); + else if (event.getId() == "nextstyle") + mPlayer->setHairStyle(mPlayer->getHairStyle() + 1, + mPlayer->getHairColor()); + else if (event.getId() == "prevstyle") + mPlayer->setHairStyle(mPlayer->getHairStyle() + + mPlayer->getNumOfHairstyles() - 1, + mPlayer->getHairColor()); +#ifdef TMWSERV_SUPPORT else if (event.getId() == "statslider") { UpdateSliders(); } @@ -440,16 +623,17 @@ CharCreateDialog::action(const gcn::ActionEvent &event) mPlayer->setGender(GENDER_FEMALE); } } +#endif } -std::string -CharCreateDialog::getName() +std::string CharCreateDialog::getName() { std::string name = mNameField->getText(); trim(name); return name; } +#ifdef TMWSERV_SUPPORT void CharCreateDialog::UpdateSliders() { for (int i = 0; i < 6; i++) @@ -482,13 +666,14 @@ void CharCreateDialog::UpdateSliders() mAttributesLeft->adjustSize(); } +#endif -void -CharCreateDialog::unlock() +void CharCreateDialog::unlock() { mCreateButton->setEnabled(true); } +#ifdef TMWSERV_SUPPORT int CharCreateDialog::getDistributedPoints() { int points = 0; @@ -499,3 +684,23 @@ int CharCreateDialog::getDistributedPoints() } return points; } +#endif + +#ifndef TMWSERV_SUPPORT +void CharCreateDialog::attemptCharCreate() +{ + // Send character infos + MessageOut outMsg(mNetwork); + outMsg.writeInt16(0x0067); + outMsg.writeString(getName(), 24); + outMsg.writeInt8(5); + outMsg.writeInt8(5); + outMsg.writeInt8(5); + outMsg.writeInt8(5); + outMsg.writeInt8(5); + outMsg.writeInt8(5); + outMsg.writeInt8(mSlot); + outMsg.writeInt16(mPlayer->getHairColor()); + outMsg.writeInt16(mPlayer->getHairStyle()); +} +#endif diff --git a/src/gui/char_select.h b/src/gui/char_select.h index ed03cedd..0ff1d18f 100644 --- a/src/gui/char_select.h +++ b/src/gui/char_select.h @@ -1,38 +1,43 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _CHAR_SELECT_H #define _CHAR_SELECT_H +#include <guichan/actionlistener.hpp> + #include "window.h" +#include "../being.h" #include "../guichanfwd.h" #include "../lockedarray.h" -#include <guichan/actionlistener.hpp> - +#ifdef TMWSERV_SUPPORT #include "../logindata.h" +#else +class Network; +#endif -class Player; class LocalPlayer; +class Player; class PlayerBox; /** @@ -47,8 +52,14 @@ class CharSelectDialog : public Window, public gcn::ActionListener /** * Constructor. */ +#ifdef TMWSERV_SUPPORT CharSelectDialog(LockedArray<LocalPlayer*> *charInfo, LoginData *loginData); +#else + CharSelectDialog(Network *network, + LockedArray<LocalPlayer*> *charInfo, + Gender gender); +#endif void action(const gcn::ActionEvent &event); @@ -59,28 +70,40 @@ class CharSelectDialog : public Window, public gcn::ActionListener bool selectByName(const std::string &name); private: +#ifdef EATHENA_SUPPORT + Network *mNetwork; +#endif LockedArray<LocalPlayer*> *mCharInfo; gcn::Button *mSelectButton; gcn::Button *mCancelButton; - gcn::Button *mNewCharButton; - gcn::Button *mDelCharButton; gcn::Button *mPreviousButton; gcn::Button *mNextButton; - gcn::Button *mUnRegisterButton; - gcn::Button *mChangePasswordButton; - gcn::Button *mChangeEmailButton; - gcn::Label *mAccountNameLabel; gcn::Label *mNameLabel; gcn::Label *mLevelLabel; gcn::Label *mMoneyLabel; + std::string mMoney; PlayerBox *mPlayerBox; bool mCharSelected; +#ifdef TMWSERV_SUPPORT + gcn::Button *mNewCharButton; + gcn::Button *mDelCharButton; + gcn::Button *mUnRegisterButton; + gcn::Button *mChangePasswordButton; + gcn::Button *mChangeEmailButton; + gcn::Label *mAccountNameLabel; + LoginData *mLoginData; +#else + gcn::Button *mNewDelCharButton; + gcn::Label *mJobLevelLabel; + Gender mGender; +#endif + /** * Communicate character deletion to the server. */ @@ -103,7 +126,12 @@ class CharCreateDialog : public Window, public gcn::ActionListener /** * Constructor. */ +#ifdef TMWSERV_SUPPORT CharCreateDialog(Window *parent, int slot); +#else + CharCreateDialog(Window *parent, int slot, Network *network, + Gender gender); +#endif /** * Destructor. @@ -118,9 +146,11 @@ class CharCreateDialog : public Window, public gcn::ActionListener void unlock(); private: +#ifdef TMWSERV_SUPPORT int getDistributedPoints(); void UpdateSliders(); +#endif /** * Returns the name of the character to create. @@ -132,6 +162,9 @@ class CharCreateDialog : public Window, public gcn::ActionListener */ void attemptCharCreate(); +#ifdef EATHENA_SUPPORT + Network *mNetwork; +#endif gcn::TextField *mNameField; gcn::Label *mNameLabel; gcn::Button *mNextHairColorButton; @@ -141,6 +174,7 @@ class CharCreateDialog : public Window, public gcn::ActionListener gcn::Button *mPrevHairStyleButton; gcn::Label *mHairStyleLabel; +#ifdef TMWSERV_SUPPORT gcn::RadioButton *mMale; gcn::RadioButton *mFemale; @@ -149,6 +183,10 @@ class CharCreateDialog : public Window, public gcn::ActionListener gcn::Label *mAttributeValue[6]; gcn::Label *mAttributesLeft; + static const int mMaxPoints = 60; + int mUsedPoints; +#endif + gcn::Button *mCreateButton; gcn::Button *mCancelButton; @@ -156,9 +194,6 @@ class CharCreateDialog : public Window, public gcn::ActionListener PlayerBox *mPlayerBox; int mSlot; - - static const int mMaxPoints = 60; - int mUsedPoints; }; #endif diff --git a/src/gui/char_server.cpp b/src/gui/char_server.cpp new file mode 100644 index 00000000..fa03bdc2 --- /dev/null +++ b/src/gui/char_server.cpp @@ -0,0 +1,122 @@ +/* + * The Mana World + * Copyright (C) 2004 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 "button.h" +#include "char_server.h" +#include "listbox.h" +#include "scrollarea.h" + +#include "../logindata.h" +#include "../main.h" +#include "../serverinfo.h" + +#include "../utils/gettext.h" +#include "../utils/stringutils.h" + +extern SERVER_INFO **server_info; + +/** + * The list model for the server list. + */ +class ServerListModel : public gcn::ListModel +{ + public: + virtual ~ServerListModel() {}; + + int getNumberOfElements(); + std::string getElementAt(int i); +}; + +ServerSelectDialog::ServerSelectDialog(LoginData *loginData, int nextState): + Window(_("Select Server")), + mLoginData(loginData), + mNextState(nextState) +{ + mServerListModel = new ServerListModel; + mServerList = new ListBox(mServerListModel); + ScrollArea *mScrollArea = new ScrollArea(mServerList); + mOkButton = new Button(_("OK"), "ok", this); + Button *mCancelButton = new Button(_("Cancel"), "cancel", this); + + setContentSize(200, 100); + + mCancelButton->setPosition( + 200 - mCancelButton->getWidth() - 5, + 100 - mCancelButton->getHeight() - 5); + mOkButton->setPosition( + mCancelButton->getX() - mOkButton->getWidth() - 5, + 100 - mOkButton->getHeight() - 5); + mScrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); + mScrollArea->setDimension(gcn::Rectangle( + 5, 5, 200 - 2 * 5, + 100 - 3 * 5 - mCancelButton->getHeight() - + mScrollArea->getFrameSize())); + + mServerList->setActionEventId("ok"); + + //mServerList->addActionListener(this); + + add(mScrollArea); + add(mOkButton); + add(mCancelButton); + + if (n_server == 0) + // Disable Ok button + mOkButton->setEnabled(false); + else + // Select first server + mServerList->setSelected(1); + + setLocationRelativeTo(getParent()); + setVisible(true); + mOkButton->requestFocus(); +} + +ServerSelectDialog::~ServerSelectDialog() +{ + delete mServerListModel; +} + +void ServerSelectDialog::action(const gcn::ActionEvent &event) +{ + if (event.getId() == "ok") + { + mOkButton->setEnabled(false); + const SERVER_INFO *si = server_info[mServerList->getSelected()]; + mLoginData->hostname = ipToString(si->address); + mLoginData->port = si->port; + mLoginData->updateHost = si->updateHost; + state = mNextState; + } + else if (event.getId() == "cancel") + state = STATE_LOGIN; +} + +int ServerListModel::getNumberOfElements() +{ + return n_server; +} + +std::string ServerListModel::getElementAt(int i) +{ + const SERVER_INFO *si = server_info[i]; + return si->name + " (" + toString(si->online_users) + ")"; +} diff --git a/src/gui/char_server.h b/src/gui/char_server.h new file mode 100644 index 00000000..49a5b47b --- /dev/null +++ b/src/gui/char_server.h @@ -0,0 +1,65 @@ +/* + * The Mana World + * Copyright (C) 2004 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 _CHAR_SEL_SERVER_H +#define _CHAR_SEL_SERVER_H + +#include <guichan/actionlistener.hpp> +#include <guichan/listmodel.hpp> + +#include "window.h" + +class LoginData; +class ServerListModel; + +/** + * The server select dialog. + * + * \ingroup Interface + */ +class ServerSelectDialog : public Window, public gcn::ActionListener { + public: + /** + * Constructor + * + * @see Window::Window + */ + ServerSelectDialog(LoginData *loginData, int nextState); + + /** + * Destructor. + */ + ~ServerSelectDialog(); + + /** + * Called when receiving actions from the widgets. + */ + void action(const gcn::ActionEvent &event); + + private: + LoginData *mLoginData; + ServerListModel *mServerListModel; + gcn::ListBox *mServerList; + gcn::Button *mOkButton; + int mNextState; +}; + +#endif diff --git a/src/gui/chat.cpp b/src/gui/chat.cpp index 3d1b5643..37250091 100644 --- a/src/gui/chat.cpp +++ b/src/gui/chat.cpp @@ -1,68 +1,83 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include <algorithm> -#include <sstream> - #include <guichan/focushandler.hpp> -#include "chat.h" - #include "browserbox.h" +#include "chat.h" #include "chatinput.h" #include "itemlinkhandler.h" +#include "recorder.h" #include "scrollarea.h" #include "sdlinput.h" #include "windowcontainer.h" +#include "widgets/layout.h" #include "widgets/tab.h" #include "widgets/tabbedarea.h" +#include "../beingmanager.h" +#ifdef TMWSERV_SUPPORT #include "../commandhandler.h" +#endif #include "../channelmanager.h" #include "../channel.h" #include "../configuration.h" #include "../game.h" #include "../localplayer.h" +#ifdef TMWSERV_SUPPORT #include "../net/chatserver/chatserver.h" #include "../net/gameserver/player.h" +#else +#include "../party.h" +#include "../net/messageout.h" +#include "../net/ea/protocol.h" +#endif #include "../resources/iteminfo.h" #include "../resources/itemdb.h" #include "../utils/dtor.h" -#include "../utils/trim.h" -#include "../utils/tostring.h" +#include "../utils/gettext.h" +#include "../utils/strprintf.h" +#include "../utils/stringutils.h" +#ifdef TMWSERV_SUPPORT ChatWindow::ChatWindow(): Window("Chat"), +#else +ChatWindow::ChatWindow(Network * network): + Window(""), mNetwork(network), +#endif mTmpVisible(false) { setWindowName("Chat"); + setResizable(true); setDefaultSize(0, windowContainer->getHeight() - 123, 600, 123); - setOpaque(false); + setMinWidth(150); + setMinHeight(90); - mItemLinkHandler = new ItemLinkHandler(); + mItemLinkHandler = new ItemLinkHandler; mChatInput = new ChatInput; mChatInput->setActionEventId("chatinput"); @@ -74,47 +89,51 @@ ChatWindow::ChatWindow(): textOutput->setLinkHandler(mItemLinkHandler); ScrollArea *scrollArea = new ScrollArea(textOutput); - scrollArea->setPosition( - scrollArea->getFrameSize(), scrollArea->getFrameSize()); - scrollArea->setScrollPolicy( - gcn::ScrollArea::SHOW_NEVER, gcn::ScrollArea::SHOW_ALWAYS); + scrollArea->setScrollPolicy(gcn::ScrollArea::SHOW_NEVER, + gcn::ScrollArea::SHOW_ALWAYS); scrollArea->setScrollAmount(0, 1); scrollArea->setOpaque(false); mChatTabs = new TabbedArea(); mChatTabs->addTab("General", scrollArea); - mChatTabs->setPosition(mChatTabs->getFrameSize(), - mChatTabs->getFrameSize()); - mChannels.insert( - std::make_pair("General", ChatArea(textOutput, scrollArea))); + place(0, 0, mChatTabs, 5, 5).setPadding(0); + place(0, 5, mChatInput, 5).setPadding(1); + + Layout &layout = getLayout(); + layout.setRowHeight(0, Layout::AUTO_SET); + layout.setMargin(2); - add(mChatTabs); - add(mChatInput); + loadWindowState(); // Add key listener to chat input to be able to respond to up/down mChatInput->addKeyListener(this); mCurHist = mHistory.end(); - loadWindowState(); +#ifdef EATHENA_SUPPORT + // Read the party prefix + std::string partyPrefix = config.getValue("PartyPrefix", "$"); + mPartyPrefix = (partyPrefix.empty() ? '$' : partyPrefix.at(0)); + mReturnToggles = config.getValue("ReturnToggles", "0") == "1"; + mRecorder = new Recorder(this); + mParty = new Party(this, mNetwork); + + // If the player had @assert on in the last session, ask the server to + // run the @assert command for the player again. Convenience for GMs. + if (config.getValue(player_node->getName() + "GMassert", 0)) + chatSend(player_node->getName(), "@assert"); +#endif } ChatWindow::~ChatWindow() { - delete mChatInput; - delete mChatTabs; -} - -const std::string &ChatWindow::getFocused() const -{ - return mChatTabs->getSelectedTab()->getCaption(); -} - -void ChatWindow::clearTab(const std::string &tab) -{ - ChannelMap::const_iterator chan = mChannels.find(tab); - if (chan != mChannels.end()) - chan->second.browser->clearRows(); +#ifdef EATHENA_SUPPORT + char partyPrefix[2] = "."; + *partyPrefix = mPartyPrefix; + config.setValue("PartyPrefix", partyPrefix); + config.setValue("ReturnToggles", mReturnToggles ? "1" : "0"); + delete mRecorder; +#endif } void ChatWindow::widgetResized(const gcn::Event &event) @@ -159,7 +178,8 @@ void ChatWindow::logic() } } -void ChatWindow::chatLog(std::string line, int own, std::string channelName) +void ChatWindow::chatLog(std::string line, int own, std::string channelName, + bool ignoreRecord) { if(channelName.empty()) channelName = getFocused(); @@ -174,60 +194,122 @@ void ChatWindow::chatLog(std::string line, int own, std::string channelName) // Trim whitespace trim(line); + if (line.empty()) + return; + CHATLOG tmp; - tmp.own = own; + tmp.own = own; tmp.nick = ""; tmp.text = line; std::string::size_type pos = line.find(" : "); - if (pos != std::string::npos) { + if (pos != std::string::npos) + { tmp.nick = line.substr(0, pos); tmp.text = line.substr(pos + 3); } + else + { + // Fix the owner of welcome message. + if (line.substr(0, 7) == "Welcome") + { + own = BY_SERVER; + } + } + + // *implements actions in a backwards compatible way* + if (own == BY_PLAYER && + tmp.text.at(0) == '*' && + tmp.text.at(tmp.text.length()-1) == '*') + { + tmp.text[0] = ' '; + tmp.text.erase(tmp.text.length() - 1); + own = ACT_IS; + } - std::string lineColor = "##0"; // Equiv. to BrowserBox::BLACK - switch (own) { + std::string lineColor = "##C"; + switch (own) + { case BY_GM: - tmp.nick += "Global announcement: "; - lineColor = "##1"; // Equiv. to BrowserBox::RED + if (tmp.nick.empty()) + { + tmp.nick = std::string(_("Global announcement:")); + tmp.nick += " "; + lineColor = "##G"; + } + else + { + tmp.nick = strprintf(_("Global announcement from %s:"), + tmp.nick.c_str()); + tmp.nick += " "; + lineColor = "##1"; // Equiv. to BrowserBox::RED + } break; case BY_PLAYER: - tmp.nick += ": "; - lineColor = "##3"; // Equiv. to BrowserBox::BLUE + tmp.nick += CAT_NORMAL; + lineColor = "##Y"; break; case BY_OTHER: - tmp.nick += ": "; - lineColor = "##0"; // Equiv. to BrowserBox::BLACK + tmp.nick += CAT_NORMAL; + lineColor = "##C"; break; case BY_SERVER: - tmp.nick = "Server: "; + tmp.nick = _("Server:"); + tmp.nick += " "; tmp.text = line; - lineColor = "##7"; // Equiv. to BrowserBox::PINK + lineColor = "##S"; break; case BY_CHANNEL: tmp.nick = ""; + // TODO: Use a predefined color lineColor = "##2"; // Equiv. to BrowserBox::GREEN break; +#ifdef EATHENA_SUPPORT + case BY_PARTY: + tmp.nick += CAT_NORMAL; + lineColor = "##P"; + break; +#endif + case ACT_WHISPER: + tmp.nick = strprintf(_("%s whispers:"), tmp.nick.c_str()); + tmp.nick += " "; + lineColor = "##W"; + break; + case ACT_IS: + tmp.nick += CAT_IS; + lineColor = "##I"; + break; case BY_LOGGER: tmp.nick = ""; tmp.text = line; - lineColor = "##8"; // Equiv. to BrowserBox::GREY + lineColor = "##L"; break; } + if (tmp.nick == ": ") + { + tmp.nick = ""; + lineColor = "##S"; + } + +#ifdef EATHENA_SUPPORT + if (tmp.nick.empty() && tmp.text.substr(0, 17) == "Visible GM status") + { + player_node->setGM(); + } +#endif + // Get the current system time time_t t; time(&t); // Format the time string properly std::stringstream timeStr; - timeStr << "[" - << ((((t / 60) / 60) % 24 < 10) ? "0" : "") - << (int)(((t / 60) / 60) % 24) - << ":" - << (((t / 60) % 60 < 10) ? "0" : "") - << (int)((t / 60) % 60) - << "] "; + timeStr << "[" << ((((t / 60) / 60) % 24 < 10) ? "0" : "") + << (int) (((t / 60) / 60) % 24) + << ":" << (((t / 60) % 60 < 10) ? "0" : "") + << (int) ((t / 60) % 60) + << "] "; line = lineColor + timeStr.str() + tmp.nick + tmp.text; @@ -245,6 +327,26 @@ void ChatWindow::chatLog(std::string line, int own, std::string channelName) } scroll->logic(); + mRecorder->record(line.substr(3)); +} + +#ifdef EATHENA_SUPPORT +void ChatWindow::chatLog(CHATSKILL act) +{ + chatLog(const_msg(act), BY_SERVER); +} +#endif + +const std::string &ChatWindow::getFocused() const +{ + return mChatTabs->getSelectedTab()->getCaption(); +} + +void ChatWindow::clearTab(const std::string &tab) +{ + ChannelMap::const_iterator chan = mChannels.find(tab); + if (chan != mChannels.end()) + chan->second.browser->clearRows(); } void ChatWindow::action(const gcn::ActionEvent &event) @@ -253,29 +355,36 @@ void ChatWindow::action(const gcn::ActionEvent &event) { std::string message = mChatInput->getText(); - if (!message.empty()) { + if (!message.empty()) + { // If message different from previous, put it in the history - if (mHistory.empty() || message != mHistory.back()) { + if (mHistory.empty() || message != mHistory.back()) + { mHistory.push_back(message); } - // Reset history iterator mCurHist = mHistory.end(); // Send the message to the server +#ifdef TMWSERV_SUPPORT chatSend(message); +#else + chatSend(player_node->getName(), message); +#endif // Clear the text from the chat input mChatInput->setText(""); } - // Remove focus and hide input - mFocusHandler->focusNone(); + if (message.empty() || !mReturnToggles) + { + // Remove focus and hide input + mFocusHandler->focusNone(); - // If the chatWindow is shown up because you want to send a message - // It should hide now - if (mTmpVisible) { - setVisible(false); + // If the chatWindow is shown up because you want to send a message + // It should hide now + if (mTmpVisible) + setVisible(false); } } } @@ -305,6 +414,56 @@ bool ChatWindow::isInputFocused() return mChatInput->isFocused(); } +void ChatWindow::whisper(const std::string &nick, std::string msg) +{ + std::string recvnick = ""; + + if (msg.substr(0, 1) == "\"") + { + const std::string::size_type pos = msg.find('"', 1); + if (pos != std::string::npos) + { + recvnick = msg.substr(1, pos - 1); + msg.erase(0, pos + 2); + } + } + else + { + const std::string::size_type pos = msg.find(" "); + if (pos != std::string::npos) + { + recvnick = msg.substr(0, pos); + msg.erase(0, pos + 1); + } + } + + trim(msg); + + std::string playerName = player_node->getName(); + std::string tempNick = recvnick; + + toLower(playerName); + toLower(tempNick); + + if (tempNick.compare(playerName) == 0 || msg.empty()) + return; + + // TODO: Implement whispering on tmwserv +#ifdef EATHENA_SUPPORT + MessageOut outMsg(mNetwork); + outMsg.writeInt16(CMSG_CHAT_WHISPER); + outMsg.writeInt16(msg.length() + 28); + outMsg.writeString(recvnick, 24); + outMsg.writeString(msg, msg.length()); + + chatLog(strprintf(_("Whispering to %s: %s"), + recvnick.c_str(), msg.c_str()), + BY_PLAYER); +#endif +} + +#ifdef TMWSERV_SUPPORT + void ChatWindow::chatSend(std::string &msg) { if (msg.empty()) return; @@ -415,6 +574,387 @@ void ChatWindow::sendToChannel(short channelId, } } +#else + +void ChatWindow::chatSend(const std::string &nick, std::string msg) +{ + /* Some messages are managed client side, while others + * require server handling by proper packet. Probably + * those if elses should be replaced by protocol calls */ + + trim(msg); + + if (msg.compare("") == 0) + return; + + // Send party message + if (msg.at(0) == mPartyPrefix) + { + msg.erase(0, 1); + std::size_t length = msg.length() + 1; + + if (length == 0) + { + chatLog(_("Trying to send a blank party message."), BY_SERVER); + return; + } + MessageOut outMsg(mNetwork); + + outMsg.writeInt16(CMSG_PARTY_MESSAGE); + outMsg.writeInt16(length + 4); + outMsg.writeString(msg, length); + return; + } + + // Check for item link + std::string::size_type start = msg.find('['); + while (start != std::string::npos && msg[start+1] != '@') + { + std::string::size_type end = msg.find(']', start); + if (start+1 != end && end != std::string::npos) + { + // Catch multiple embeds and ignore them + // so it doesn't crash the client. + while ((msg.find('[', start + 1) != std::string::npos) && + (msg.find('[', start + 1) < end)) + { + start = msg.find('[', start + 1); + } + + std::string temp = msg.substr(start + 1, end - start - 1); + + toLower(trim(temp)); + + const ItemInfo itemInfo = ItemDB::get(temp); + if (itemInfo.getName() != _("Unknown item")) + { + msg.insert(end, "@@"); + msg.insert(start+1, "|"); + msg.insert(start+1, toString(itemInfo.getId())); + msg.insert(start+1, "@@"); + } + } + start = msg.find('[', start + 1); + } + + // Prepare ordinary message + if (msg.substr(0, 1) != "/") + { + msg = nick + " : " + msg; + + MessageOut outMsg(mNetwork); + outMsg.writeInt16(CMSG_CHAT_MESSAGE); + // Added + 1 in order to let eAthena parse admin commands correctly + outMsg.writeInt16(msg.length() + 4 + 1); + outMsg.writeString(msg, msg.length() + 1); + return; + } + + msg.erase(0, 1); + trim(msg); + + std::size_t space = msg.find(" "); + std::string command = msg.substr(0, space); + + if (space == std::string::npos) + { + msg = ""; + } + else + { + msg = msg.substr(space); + trim(msg); + } + + if (command == "announce") + { + MessageOut outMsg(mNetwork); + outMsg.writeInt16(0x0099); + outMsg.writeInt16(msg.length() + 4); + outMsg.writeString(msg, msg.length()); + } + else if (command == "help") + { + trim(msg); + std::size_t space = msg.find(" "); + std::string msg1; + + if (space == std::string::npos) + { + msg1 = ""; + } + else + { + msg1 = msg.substr(space + 1, msg.length()); + msg = msg.substr(0, space); + } + + if (!msg.empty() && msg.at(0) == '/') + { + msg.erase(0, 1); + } + + trim(msg1); + help(msg, msg1); + } + else if (command == "where") + { + // Display the current map, X, and Y + std::ostringstream where; + where << map_path << " " << player_node->mX << "," << player_node->mY; + chatLog(where.str(), BY_SERVER); + } + else if (command == "who") + { + MessageOut outMsg(mNetwork); + outMsg.writeInt16(0x00c1); + } + else if (command == "clear") + clearTab(getFocused()); + else if (command == "whisper" || command == "msg" || command == "w") + whisper(nick, msg); + else if (command == "record") + mRecorder->changeRecordingStatus(msg); + else if (command == "toggle") + { + if (msg.empty()) + { + chatLog(mReturnToggles ? _("Return toggles chat.") + : _("Message closes chat."), BY_SERVER); + return; + } + + msg = msg.substr(0, 1); + + if (msg == "1" || + msg == "y" || msg == "Y" || + msg == "t" || msg == "T") + { + chatLog(_("Return now toggles chat."), BY_SERVER); + mReturnToggles = true; + return; + } + else if (msg == "0" || + msg == "n" || msg == "N" || + msg == "f" || msg == "F") + { + chatLog(_("Message now closes chat."), BY_SERVER); + mReturnToggles = false; + return; + } + else + chatLog(_("Options to /toggle are \"yes\", \"no\", \"true\", " + "\"false\", \"1\", \"0\"."), BY_SERVER); + } + else if (command == "party") + { + if (msg.empty()) + { + chatLog(_("Unknown party command... Type \"/help\" party for more " + "information."), BY_SERVER); + return; + } + + const std::string::size_type space = msg.find(" "); + std::string rest = (space == std::string::npos ? "" + : msg.substr(space + 1, msg.length())); + + if (!rest.empty()) + { + msg = msg.substr(0, space); + trim(msg); + } + + party(msg, rest); + return; + } + else if (command == "cast") + { + /* + * This will eventually be replaced by a GUI, so + * we don't need to get too sophisticated + */ + MessageOut outMsg(mNetwork); + if (msg == "heal") + { + outMsg.writeInt16(0x03f3); + outMsg.writeInt16(0x01); + outMsg.writeInt32(0); + outMsg.writeInt8(0); + outMsg.writeInt8(0); + outMsg.writeString("", 24); + } + else if (msg == "gather") + { + outMsg.writeInt16(0x03f3); + outMsg.writeInt16(0x02); + outMsg.writeInt32(0); + outMsg.writeInt8(0); + outMsg.writeInt8(0); + outMsg.writeString("", 24); + } + else + chatLog(_("No such spell!"), BY_SERVER); + } + else if (command == "present") + { + Beings & beings = beingManager->getAll(); + std::string response = ""; + + for (BeingIterator bi = beings.begin(), be = beings.end(); + bi != be; ++bi) + { + if ((*bi)->getType() == Being::PLAYER) + { + if (!response.empty()) + { + response += ", "; + } + response += (*bi)->getName(); + } + } + + if (mRecorder->isRecording()) + { + // Get the current system time + time_t t; + time(&t); + + // Format the time string properly + std::stringstream timeStr; + timeStr << "[" << ((((t / 60) / 60) % 24 < 10) ? "0" : "") + << (int) (((t / 60) / 60) % 24) + << ":" << (((t / 60) % 60 < 10) ? "0" : "") + << (int) ((t / 60) % 60) + << "] "; + + + mRecorder->record(timeStr.str() + _("Present: ") + response + "."); + chatLog(_("Attendance written to record log."), BY_SERVER, std::string(), true); + } + else + { + chatLog(_("Present: ") + response, BY_SERVER); + } + } + else if (command == "me") + { + std::stringstream actionStr; + actionStr << "*" << msg << "*"; + chatSend(player_node->getName(), actionStr.str()); + } + else + { + chatLog(_("Unknown command"), BY_SERVER); + } +} + +std::string ChatWindow::const_msg(CHATSKILL act) +{ + std::string msg; + if (act.success == SKILL_FAILED && act.skill == SKILL_BASIC) + { + switch (act.bskill) + { + case BSKILL_TRADE: + msg = _("Trade failed!"); + break; + case BSKILL_EMOTE: + msg = _("Emote failed!"); + break; + case BSKILL_SIT: + msg = _("Sit failed!"); + break; + case BSKILL_CREATECHAT: + msg = _("Chat creating failed!"); + break; + case BSKILL_JOINPARTY: + msg = _("Could not join party!"); + break; + case BSKILL_SHOUT: + msg = _("Cannot shout!"); + break; + } + + msg += " "; + + switch (act.reason) + { + case RFAIL_SKILLDEP: + msg += _("You have not yet reached a high enough lvl!"); + break; + case RFAIL_INSUFHP: + msg += _("Insufficient HP!"); + break; + case RFAIL_INSUFSP: + msg += _("Insufficient SP!"); + break; + case RFAIL_NOMEMO: + msg += _("You have no memos!"); + break; + case RFAIL_SKILLDELAY: + msg += _("You cannot do that right now!"); + break; + case RFAIL_ZENY: + msg += _("Seems you need more money... ;-)"); + break; + case RFAIL_WEAPON: + msg += _("You cannot use this skill with that kind of weapon!"); + break; + case RFAIL_REDGEM: + msg += _("You need another red gem!"); + break; + case RFAIL_BLUEGEM: + msg += _("You need another blue gem!"); + break; + case RFAIL_OVERWEIGHT: + msg += _("You're carrying to much to do this!"); + break; + default: + msg += _("Huh? What's that?"); + break; + } + } + else + { + switch (act.skill) + { + case SKILL_WARP : + msg = _("Warp failed..."); + break; + case SKILL_STEAL : + msg = _("Could not steal anything..."); + break; + case SKILL_ENVENOM : + msg = _("Poison had no effect..."); + break; + } + } + + return msg; +} + +#endif + +void ChatWindow::scroll(int amount) +{ + if (!isVisible()) + return; + + ChannelMap::const_iterator chan = mChannels.find(getFocused()); + if (chan == mChannels.end()) + return; + + BrowserBox *browser = chan->second.browser; + ScrollArea *scroll = chan->second.scroll; + + int range = scroll->getHeight() / 8 * amount; + gcn::Rectangle scr; + scr.y = scroll->getVerticalScrollAmount() + range; + scr.height = abs(range); + browser->showPart(scr); +} + void ChatWindow::keyPressed(gcn::KeyEvent &event) { if (event.getKey().getValue() == Key::DOWN && @@ -422,11 +962,14 @@ void ChatWindow::keyPressed(gcn::KeyEvent &event) { // Move forward through the history HistoryIterator prevHist = mCurHist++; - if (mCurHist != mHistory.end()) { + + if (mCurHist != mHistory.end()) + { mChatInput->setText(*mCurHist); mChatInput->setCaretPosition(mChatInput->getText().length()); } - else { + else + { mCurHist = prevHist; } } @@ -446,23 +989,171 @@ void ChatWindow::setInputText(std::string input_str) requestChatFocus(); } -void ChatWindow::addItemText(int itemId, const std::string &item) +void ChatWindow::addItemText(const std::string &item) { std::ostringstream text; - text << "[@@" << itemId << "|" << item << "@@] "; + text << "[" << item << "] "; mChatInput->setText(mChatInput->getText() + text.str()); requestChatFocus(); } void ChatWindow::setVisible(bool isVisible) { - Window::setVisible(isVisible); + Window::setVisible(isVisible); + + /* + * For whatever reason, if setVisible is called, the mTmpVisible effect + * should be disabled. + */ + mTmpVisible = false; +} + +#ifdef EATHENA_SUPPORT +void ChatWindow::party(const std::string & command, const std::string & rest) +{ + if (command == "prefix") + { + if (rest.empty()) + { + char temp[2] = "."; + *temp = mPartyPrefix; + chatLog(_("The current party prefix is ") + std::string(temp), + BY_SERVER); + } + else if (rest.length() != 1) + { + chatLog(_("Party prefix must be one character long."), BY_SERVER); + } + else + { + if (rest == "/") + { + chatLog(_("Cannot use a '/' as the prefix."), BY_SERVER); + } + else + { + mPartyPrefix = rest.at(0); + chatLog(_("Changing prefix to ") + rest, BY_SERVER); + } + } + } + else + mParty->respond(command, rest); +} +#endif - /* - * For whatever reason, if setVisible is called, the mTmpVisible effect - * should be disabled. - */ - mTmpVisible = false; +void ChatWindow::help(const std::string & msg1, const std::string & msg2) +{ + chatLog(_("-- Help --"), BY_SERVER); + if (msg1.empty()) + { + chatLog(_("/announce: Global announcement (GM only)"), BY_SERVER); + chatLog(_("/clear: Clears this window"), BY_SERVER); + chatLog(_("/help: Display this help"), BY_SERVER); + chatLog(_("/me <message>: Tell something about yourself"), BY_SERVER); + chatLog(_("/msg <nick> <message>: Alternate form for /whisper"), + BY_SERVER); + chatLog(_("/party <command> <params>: Party commands"), BY_SERVER); + chatLog(_("/present: Get list of players present"), BY_SERVER); + chatLog(_("/record <filename>: Start recording the chat to an " + "external file"), BY_SERVER); + chatLog(_("/toggle: Determine whether <return> toggles the chat log"), + BY_SERVER); + chatLog(_("/w <nick> <message>: Short form for /whisper"), BY_SERVER); + chatLog(_("/where: Display map name"), BY_SERVER); + chatLog(_("/whisper <nick> <message>: Sends a private <message> " + "to <nick>"), BY_SERVER); + chatLog(_("/who: Display number of online users"), BY_SERVER); + chatLog(_("For more information, type /help <command>"), BY_SERVER); + } + else if (msg1 == "announce") + { + chatLog(_("Command: /announce <msg>"), BY_SERVER); + chatLog(_("*** only available to a GM ***"), BY_SERVER); + chatLog(_("This command sends the message <msg> to " + "all players currently online."), BY_SERVER); + } + else if (msg1 == "clear") + { + chatLog(_("Command: /clear"), BY_SERVER); + chatLog(_("This command clears the chat log of previous chat."), + BY_SERVER); + } + else if (msg1 == "help") + { + chatLog(_("Command: /help"), BY_SERVER); + chatLog(_("This command displays a list of all commands available."), + BY_SERVER); + chatLog(_("Command: /help <command>"), BY_SERVER); + chatLog(_("This command displays help on <command>."), BY_SERVER); + } + else if (msg1 == "me") + { + chatLog(_("Command: /me <msg>"), BY_SERVER); + chatLog(_("This command tell others you are (doing) <msg>."), + BY_SERVER); + } +#ifdef EATHENA_SUPPORT + else if (msg1 == "party") + { + mParty->help(msg2); + } +#endif + else if (msg1 == "present") + { + chatLog(_("Command: /present"), BY_SERVER); + chatLog(_("This command gets a list of players within hearing and " + "sends it to either the record log if recording, or the chat " + "log otherwise."), BY_SERVER); + } + else if (msg1 == "record") + { + chatLog(_("Command: /record <filename>"), BY_SERVER); + chatLog(_("This command starts recording the chat log to the file " + "<filename>."), BY_SERVER); + chatLog(_("Command: /record"), BY_SERVER); + chatLog(_("This command finishes a recording session."), BY_SERVER); + } + else if (msg1 == "toggle") + { + chatLog(_("Command: /toggle <state>"), BY_SERVER); + chatLog(_("This command sets whether the return key should toggle the " + "chat log, or whether the chat log turns off automatically."), + BY_SERVER); + chatLog(_("<state> can be one of \"1\", \"yes\", \"true\" to " + "turn the toggle on, or \"0\", \"no\", \"false\" to turn the " + "toggle off."), BY_SERVER); + chatLog(_("Command: /toggle"), BY_SERVER); + chatLog(_("This command displays the return toggle status."), + BY_SERVER); + } + else if (msg1 == "where") + { + chatLog(_("Command: /where"), BY_SERVER); + chatLog(_("This command displays the name of the current map."), + BY_SERVER); + } + else if (msg1 == "whisper" || msg1 == "msg" || msg1 == "w") + { + chatLog(_("Command: /msg <nick> <msg>"), BY_SERVER); + chatLog(_("Command: /whisper <nick> <msg>"), BY_SERVER); + chatLog(_("Command: /w <nick> <msg>"), BY_SERVER); + chatLog(_("This command sends the message <msg> to <nick>."), + BY_SERVER); + chatLog(_("If the <nick> has spaces in it, enclose it in " + "double quotes (\")."), BY_SERVER); + } + else if (msg1 == "who") + { + chatLog(_("Command: /who"), BY_SERVER); + chatLog(_("This command displays the number of players currently " + "online."), BY_SERVER); + } + else + { + chatLog(_("Unknown command."), BY_SERVER); + chatLog(_("Type /help for a list of commands."), BY_SERVER); + } } bool ChatWindow::tabExists(const std::string &tabName) diff --git a/src/gui/chat.h b/src/gui/chat.h index 114b389c..bbca76ad 100644 --- a/src/gui/chat.h +++ b/src/gui/chat.h @@ -1,26 +1,26 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TMW_CHAT_H -#define _TMW_CHAT_H +#ifndef CHAT_H +#define CHAT_H #include <list> #include <string> @@ -31,25 +31,86 @@ #include "window.h" -#include "../guichanfwd.h" - class BrowserBox; +class Channel; +class Recorder; class ScrollArea; class TabbedArea; -class Channel; class ItemLinkHandler; +#ifdef EATHENA_SUPPORT +class Network; +class Party; +#endif enum { - BY_GM = 0, - BY_PLAYER = 1, - BY_OTHER = 2, - BY_SERVER = 3, - BY_CHANNEL = 4, + BY_GM, +#ifdef EATHENA_SUPPORT + BY_PARTY, +#endif + BY_PLAYER, + BY_OTHER, + BY_SERVER, + BY_CHANNEL, + ACT_WHISPER, // getting whispered at + ACT_IS, // equivalent to "/me" on IRC BY_LOGGER }; /** + * gets in between usernick and message text depending on + * message type + */ +#define CAT_NORMAL ": " +#define CAT_IS "" +#define CAT_WHISPER " whispers: " + +#ifdef EATHENA_SUPPORT +/** job dependend identifiers (?) */ +#define SKILL_BASIC 0x0001 +#define SKILL_WARP 0x001b +#define SKILL_STEAL 0x0032 +#define SKILL_ENVENOM 0x0034 + +/** basic skills identifiers */ +#define BSKILL_TRADE 0x0000 +#define BSKILL_EMOTE 0x0001 +#define BSKILL_SIT 0x0002 +#define BSKILL_CREATECHAT 0x0003 +#define BSKILL_JOINPARTY 0x0004 +#define BSKILL_SHOUT 0x0005 +#define BSKILL_PK 0x0006 // ?? +#define BSKILL_SETALLIGN 0x0007 // ?? + +/** reasons why action failed */ +#define RFAIL_SKILLDEP 0x00 +#define RFAIL_INSUFHP 0x01 +#define RFAIL_INSUFSP 0x02 +#define RFAIL_NOMEMO 0x03 +#define RFAIL_SKILLDELAY 0x04 +#define RFAIL_ZENY 0x05 +#define RFAIL_WEAPON 0x06 +#define RFAIL_REDGEM 0x07 +#define RFAIL_BLUEGEM 0x08 +#define RFAIL_OVERWEIGHT 0x09 +#define RFAIL_GENERIC 0x0a + +/** should always be zero if failed */ +#define SKILL_FAILED 0x00 + +struct CHATSKILL +{ + short skill; + short bskill; + short unused; + char success; + char reason; +}; +#endif + +#define DEFAULT_CHAT_WINDOW_SCROLL 7 // 1 means `1/8th of the window size'. + +/** * The chat window. * * \ingroup Interface @@ -62,10 +123,14 @@ class ChatWindow : public Window, /** * Constructor. */ +#ifdef TMWSERV_SUPPORT ChatWindow(); +#else + ChatWindow(Network *network); +#endif /** - * + * Destructor: used to write back values to the config file */ ~ChatWindow(); @@ -75,26 +140,36 @@ class ChatWindow : public Window, */ void widgetResized(const gcn::Event &event); - /** - * Gets the focused tab's name - */ - const std::string& getFocused() const; - - /** - * Clear the tab with the given name - */ - void clearTab(const std::string &tab); + void logic(); /** * Adds a line of text to our message list. Parameters: * * @param line Text message. - * @param own Type of message (usually the owner-type). + * @parem own Type of message (usually the owner-type). * @param channelName which channel to send the message to. */ void chatLog(std::string line, int own = BY_SERVER, - std::string channelName = ""); + std::string channelName = "", + bool ignoreRecord = false); + +#ifdef EATHENA_SUPPORT + /** + * Calls original chat_log() after processing the packet. + */ + void chatLog(CHATSKILL); +#endif + + /** + * Gets the focused tab's name + */ + const std::string& getFocused() const; + + /** + * Clear the tab with the given name + */ + void clearTab(const std::string &tab); /** * Performs action. @@ -111,6 +186,7 @@ class ChatWindow : public Window, */ bool isInputFocused(); +#ifdef TMWSERV_SUPPORT /** * Determines whether the message is a command or message, then * sends the given message to the game server to be said, or to the @@ -135,6 +211,33 @@ class ChatWindow : public Window, void sendToChannel(short channel, const std::string &user, const std::string &msg); +#else + /** + * Determines whether to send a command or an ordinary message, then + * contructs packets & sends them. + * + * @param nick The character's name to display in front. + * @param msg The message text which is to be send. + * + * NOTE: + * The nickname is required by the server, if not specified + * the message may not be sent unless a command was intended + * which requires another packet to be constructed! you can + * achieve this by putting a slash ("/") infront of the + * message followed by the command name and the message. + * of course all slash-commands need implemented handler- + * routines. ;-) + * remember, a line starting with "@" is not a command that needs + * to be parsed rather is sent using the normal chat-packet. + * + * EXAMPLE: + * // for an global announcement /- command + * chatlog.chat_send("", "/announce Hello to all logged in users!"); + * // for simple message by a user /- message + * chatlog.chat_send("Zaeiru", "Hello to all users on the screen!"); + */ + void chatSend(const std::string &nick, std::string msg); +#endif /** Called when key is pressed */ void keyPressed(gcn::KeyEvent &event); @@ -143,7 +246,7 @@ class ChatWindow : public Window, void setInputText(std::string input_str); /** Called to add item to chat */ - void addItemText(int itemid, const std::string &item); + void addItemText(const std::string &item); /** Override to reset mTmpVisible */ void setVisible(bool visible); @@ -151,14 +254,45 @@ class ChatWindow : public Window, /** Check if tab with that name already exists */ bool tabExists(const std::string &tabName); - void logic(); + /** + * Scrolls the chat window + * + * @param amount direction and amount to scroll. Negative numbers scroll + * up, positive numbers scroll down. The absolute amount indicates the + * amount of 1/8ths of chat window real estate that should be scrolled. + */ + void scroll(int amount); + +#ifdef EATHENA_SUPPORT + /** + * party implements the partying chat commands + * + * @param command is the party command to perform + * @param msg is the remainder of the message + */ + void party(const std::string &command, const std::string &msg); +#endif + + /** + * help implements the /help command + * + * @param msg1 is the command that the player needs help on + * @param msg2 is the sub-command relating to the command + */ + void help(const std::string &msg1, const std::string &msg2); private: +#ifdef EATHENA_SUPPORT + Network *mNetwork; +#endif bool mTmpVisible; int mItems; int mItemsKeep; + void whisper(const std::string &nick, std::string msg); + + /** One item in the chat log */ struct CHATLOG { std::string nick; @@ -166,6 +300,11 @@ class ChatWindow : public Window, int own; }; +#ifdef EATHENA_SUPPORT + /** Constructs failed messages for actions */ + std::string const_msg(CHATSKILL); +#endif + /** * A structure combining a BrowserBox with its ScrollArea. */ @@ -196,6 +335,14 @@ class ChatWindow : public Window, typedef History::iterator HistoryIterator; History mHistory; /**< Command history. */ HistoryIterator mCurHist; /**< History iterator. */ + Recorder *mRecorder; /**< Recording class */ + bool mReturnToggles; /**< Marks whether <Return> toggles the chat log + or not */ +#ifdef EATHENA_SUPPORT + char mPartyPrefix; /**< Messages beginning with the prefix are sent to + the party */ + Party *mParty; +#endif }; extern ChatWindow *chatWindow; diff --git a/src/gui/chatinput.cpp b/src/gui/chatinput.cpp index afe7f037..43f3cde4 100644 --- a/src/gui/chatinput.cpp +++ b/src/gui/chatinput.cpp @@ -1,21 +1,21 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ diff --git a/src/gui/chatinput.h b/src/gui/chatinput.h index e04dfa6e..3bc16928 100644 --- a/src/gui/chatinput.h +++ b/src/gui/chatinput.h @@ -1,26 +1,28 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TMW_CHATINPUT_H -#define _TMW_CHATINPUT_H +#ifndef CHATINPUT_H +#define CHATINPUT_H + +#include <guichan/focuslistener.hpp> #include "textfield.h" diff --git a/src/gui/checkbox.cpp b/src/gui/checkbox.cpp index 20e24dee..7fa4fa81 100644 --- a/src/gui/checkbox.cpp +++ b/src/gui/checkbox.cpp @@ -1,32 +1,34 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "checkbox.h" +#include "../configuration.h" #include "../graphics.h" #include "../resources/image.h" #include "../resources/resourcemanager.h" int CheckBox::instances = 0; +float CheckBox::mAlpha = config.getValue("guialpha", 0.8); Image *CheckBox::checkBoxNormal; Image *CheckBox::checkBoxChecked; Image *CheckBox::checkBoxDisabled; @@ -43,6 +45,10 @@ CheckBox::CheckBox(const std::string& caption, bool selected): checkBoxChecked = checkBox->getSubImage(9, 0, 9, 10); checkBoxDisabled = checkBox->getSubImage(18, 0, 9, 10); checkBoxDisabledChecked = checkBox->getSubImage(27, 0, 9, 10); + checkBoxNormal->setAlpha(mAlpha); + checkBoxChecked->setAlpha(mAlpha); + checkBoxDisabled->setAlpha(mAlpha); + checkBoxDisabledChecked->setAlpha(mAlpha); checkBox->decRef(); } @@ -66,16 +72,25 @@ void CheckBox::drawBox(gcn::Graphics* graphics) { Image *box; - if (isSelected()) { - if (isEnabled()) { + if (isSelected()) + { + if (isEnabled()) box = checkBoxChecked; - } else { + else box = checkBoxDisabledChecked; - } - } else if (isEnabled()) { + } + else if (isEnabled()) box = checkBoxNormal; - } else { + else box = checkBoxDisabled; + + if (config.getValue("guialpha", 0.8) != mAlpha) + { + mAlpha = config.getValue("guialpha", 0.8); + checkBoxNormal->setAlpha(mAlpha); + checkBoxChecked->setAlpha(mAlpha); + checkBoxDisabled->setAlpha(mAlpha); + checkBoxDisabledChecked->setAlpha(mAlpha); } static_cast<Graphics*>(graphics)->drawImage(box, 2, 2); diff --git a/src/gui/checkbox.h b/src/gui/checkbox.h index 839ca97e..20adb43c 100644 --- a/src/gui/checkbox.h +++ b/src/gui/checkbox.h @@ -1,28 +1,26 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TMW_CHECKBOX_H -#define _TMW_CHECKBOX_H - -#include <iosfwd> +#ifndef CHECKBOX_H +#define CHECKBOX_H #include <guichan/widgets/checkbox.hpp> @@ -33,7 +31,8 @@ class Image; * * \ingroup GUI */ -class CheckBox : public gcn::CheckBox { +class CheckBox : public gcn::CheckBox +{ public: /** * Constructor. @@ -52,6 +51,7 @@ class CheckBox : public gcn::CheckBox { private: static int instances; + static float mAlpha; static Image *checkBoxNormal; static Image *checkBoxChecked; static Image *checkBoxDisabled; diff --git a/src/gui/color.cpp b/src/gui/color.cpp new file mode 100644 index 00000000..f9b89857 --- /dev/null +++ b/src/gui/color.cpp @@ -0,0 +1,146 @@ +/* + * Configurable text colors + * Copyright (C) 2008 Douglas Boffey <dougaboffey@netscape.net> + * + * 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 "color.h" + +#include "../configuration.h" + +#include "../utils/gettext.h" +#include "../utils/stringutils.h" + +Color::Color() +{ + addColor('C', 0x000000, _("Chat")); + addColor('G', 0xff0000, _("GM")); + addColor('H', 0xebc873, _("Highlight")); + addColor('Y', 0x1fa052, _("Player")); + addColor('W', 0x0000ff, _("Whisper")); + addColor('I', 0xa08527, _("Is")); + addColor('P', 0xff00d8, _("Party")); + addColor('S', 0x8415e2, _("Server")); + addColor('L', 0x919191, _("Logger")); + addColor('<', 0xe50d0d, _("Hyperlink")); + commit(); +} + +Color::~Color() +{ + for (ColVector::iterator col = mColVector.begin(), + colEnd = mColVector.end(); + col != colEnd; + ++col) + { + config.setValue("Color" + col->text, toString(col->rgb)); + } +} + +void Color::setColor(char c, int rgb) +{ + for (ColVector::iterator col = mColVector.begin(), + colEnd = mColVector.end(); + col != colEnd; + ++col) + { + if (col->ch == c) + { + col->rgb = rgb; + return; + } + } +} + +int Color::getColor(char c, bool &valid) const +{ + for (ColVector::const_iterator col = mColVector.begin(), + colEnd = mColVector.end(); + col != colEnd; + ++col) + { + if (col->ch == c) + { + valid = true; + return col->rgb; + } + } + valid = false; + return 0x000000; +} + +std::string Color::getElementAt(int i) +{ + if (i < 0 || i >= getNumberOfElements()) + { + return ""; + } + return mColVector[i].text; +} + +char Color::getColorCharAt(int i) +{ + if (i < 0 || i >= getNumberOfElements()) + { + return 'C'; + } + return mColVector[i].ch; +} + +void Color::addColor(char c, int rgb, const std::string &text) +{ + int trueRgb = (int) config.getValue("Color" + text, rgb); + mColVector.push_back(ColorElem(c, trueRgb, text)); +} + +int Color::getColorAt(int i) +{ + if (i < 0 || i >= getNumberOfElements()) + { + return 0; + } + return mColVector[i].rgb; +} + +void Color::setColorAt(int i, int rgb) +{ + if (i >= 0 && i < getNumberOfElements()) + { + mColVector[i].rgb = rgb; + } +} + +void Color::commit() +{ + for (ColVector::iterator i = mColVector.begin(), iEnd = mColVector.end(); + i != iEnd; + ++i) + { + i->committedRgb = i->rgb; + } +} + +void Color::rollback() +{ + for (ColVector::iterator i = mColVector.begin(), iEnd = mColVector.end(); + i != iEnd; + ++i) + { + i->rgb = i->committedRgb; + } +} diff --git a/src/gui/color.h b/src/gui/color.h new file mode 100644 index 00000000..2816cedc --- /dev/null +++ b/src/gui/color.h @@ -0,0 +1,136 @@ +/* + * Configurable text colors + * Copyright (C) 2008 Douglas Boffey <dougaboffey@netscape.net> + * + * 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 COLOR_H +#define COLOR_H + +#include <string> +#include <vector> + +#include <guichan/listmodel.hpp> + +class Color : public gcn::ListModel +{ + public: + /** + * Constructor + */ + Color(); + + /** + * Destructor + */ + ~Color(); + + /** + * Define the color replacement for a character + * + * @param c charater to be replaced + * @param rgb color to replace character + */ + void setColor(char c, int rgb); + + /** + * Define the color replacement for a character + * + * @param c character to be replaced + * @param r red component + * @param g green component + * @param b blue component + */ + void setColor(char c, int r, int g, int b) + { + setColor(c, (r << 16) | (g << 8) | b); + } + + /** + * Return the color associated with a character, if exists + * + * @param c character requested + * @param valid indicate whether character is known + */ + int getColor(char c, bool &valid) const; + + /** + * Return the number of colors known + */ + int getNumberOfElements() { return mColVector.size(); } + + /** + * Return the name of the ith color + * + * @param i index of color interested in + */ + std::string getElementAt(int i); + + /** + * Get the color for the element at index i in the current color + * model + */ + int getColorAt(int i); + + /** + * Get the character used by the color for the element at index i in + * the current color model + */ + char getColorCharAt(int i); + + /** + * Set the color for the element at index i + */ + void setColorAt(int i, int rgb); + + /** + * Commit the colors + */ + void commit(); + + /** + * Rollback the colors + */ + void rollback(); + + private: + struct ColorElem + { + ColorElem(char c, int rgb, const std::string &text) : + ch(c), rgb(rgb), text(text) {} + char ch; + int rgb; + int committedRgb; + std::string text; + }; + typedef std::vector<ColorElem> ColVector; + ColVector mColVector; + + /** + * Initialise color + * + * @param c character that needs initialising + * @param rgb default color if not found in config + * @param text identifier of color + */ + void addColor(char c, int rgb, const std::string &text); +}; + +extern Color *textColor; + +#endif diff --git a/src/gui/confirm_dialog.cpp b/src/gui/confirm_dialog.cpp index 5f2b9cb2..5ad2e26c 100644 --- a/src/gui/confirm_dialog.cpp +++ b/src/gui/confirm_dialog.cpp @@ -1,29 +1,30 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "confirm_dialog.h" - -#include <guichan/widgets/label.hpp> +#include <guichan/font.hpp> #include "button.h" +#include "confirm_dialog.h" +#include "scrollarea.h" +#include "textbox.h" #include "../utils/gettext.h" @@ -31,32 +32,55 @@ ConfirmDialog::ConfirmDialog(const std::string &title, const std::string &msg, Window *parent): Window(title, true, parent) { - gcn::Label *textLabel = new gcn::Label(msg); + mTextBox = new TextBox; + mTextBox->setEditable(false); + mTextBox->setOpaque(false); + + mTextArea = new ScrollArea(mTextBox); gcn::Button *yesButton = new Button(_("Yes"), "yes", this); gcn::Button *noButton = new Button(_("No"), "no", this); - int w = textLabel->getWidth() + 20; + mTextArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); + mTextArea->setVerticalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); + mTextArea->setOpaque(false); + + mTextBox->setTextWrapped(msg, 260); + + int numRows = mTextBox->getNumberOfRows(); + int width = getFont()->getWidth(title); int inWidth = yesButton->getWidth() + noButton->getWidth() + 5; - int h = textLabel->getHeight() + 25 + yesButton->getHeight(); - if (w < inWidth + 10) { - w = inWidth + 10; + if (numRows > 1) + { + // 15 == height of each line of text (based on font heights) + // 14 == row top + bottom graphic pixel heights + setContentSize(mTextBox->getMinWidth() + 15, 15 + (numRows * 15) + noButton->getHeight()); + mTextArea->setDimension(gcn::Rectangle(4, 5, mTextBox->getMinWidth() + 5, + 3 + (numRows * 14))); + } + else + { + if (width < getFont()->getWidth(msg)) + width = getFont()->getWidth(msg); + if (width < inWidth) + width = inWidth; + setContentSize(width + 15, 30 + noButton->getHeight()); + mTextArea->setDimension(gcn::Rectangle(4, 5, width + 5, 17)); } - setContentSize(w, h); - textLabel->setPosition(10, 10); yesButton->setPosition( - (w - inWidth) / 2, - h - 5 - noButton->getHeight()); + (mTextBox->getMinWidth() - inWidth) / 2, + (numRows * 14) + noButton->getHeight() - 8); noButton->setPosition( yesButton->getX() + yesButton->getWidth() + 5, - h - 5 - noButton->getHeight()); + (numRows * 14) + noButton->getHeight() - 8); - add(textLabel); + add(mTextArea); add(yesButton); add(noButton); - if (getParent()) { + if (getParent()) + { setLocationRelativeTo(getParent()); getParent()->moveToTop(this); } @@ -64,6 +88,11 @@ ConfirmDialog::ConfirmDialog(const std::string &title, const std::string &msg, yesButton->requestFocus(); } +unsigned int ConfirmDialog::getNumRows() +{ + return mTextBox->getNumberOfRows(); +} + void ConfirmDialog::action(const gcn::ActionEvent &event) { // Proxy button events to our listeners diff --git a/src/gui/confirm_dialog.h b/src/gui/confirm_dialog.h index c9bfca02..8d8c0436 100644 --- a/src/gui/confirm_dialog.h +++ b/src/gui/confirm_dialog.h @@ -1,38 +1,41 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TMW_OPTION_DIALOG_H -#define _TMW_OPTION_DIALOG_H +#ifndef OPTION_DIALOG_H +#define OPTION_DIALOG_H #include <guichan/actionlistener.hpp> #include "window.h" +class ScrollArea; +class TextBox; /** * An option dialog. * * \ingroup GUI */ -class ConfirmDialog : public Window, public gcn::ActionListener { +class ConfirmDialog : public Window, public gcn::ActionListener +{ public: /** * Constructor. @@ -42,10 +45,16 @@ class ConfirmDialog : public Window, public gcn::ActionListener { ConfirmDialog(const std::string &title, const std::string &msg, Window *parent = NULL); + unsigned int getNumRows(); + /** * Called when receiving actions from the widgets. */ void action(const gcn::ActionEvent &event); + + private: + TextBox *mTextBox; + ScrollArea *mTextArea; }; #endif diff --git a/src/gui/connection.cpp b/src/gui/connection.cpp index f54c9dd5..fbf127de 100644 --- a/src/gui/connection.cpp +++ b/src/gui/connection.cpp @@ -1,29 +1,28 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "connection.h" - #include <guichan/widgets/label.hpp> #include "button.h" +#include "connection.h" #include "progressbar.h" #include "../main.h" @@ -61,10 +60,10 @@ void ConnectionDialog::action(gcn::ActionEvent const &) void ConnectionDialog::logic() { mProgress += 0.005f; + if (mProgress > 1.0f) - { mProgress = 0.0f; - } + mProgressBar->setProgress(mProgress); Window::logic(); } diff --git a/src/gui/connection.h b/src/gui/connection.h index 36ccd8a9..0e347266 100644 --- a/src/gui/connection.h +++ b/src/gui/connection.h @@ -1,26 +1,26 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TMW_CONNECTION_H -#define _TMW_CONNECTION_H +#ifndef CONNECTION_H +#define CONNECTION_H #include <guichan/actionlistener.hpp> diff --git a/src/gui/debugwindow.cpp b/src/gui/debugwindow.cpp index ab09ec4e..2ed891db 100644 --- a/src/gui/debugwindow.cpp +++ b/src/gui/debugwindow.cpp @@ -1,113 +1,102 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "debugwindow.h" - #include <SDL_mouse.h> #include <guichan/widgets/label.hpp> -#include "button.h" -#include "gui.h" +#include "debugwindow.h" #include "viewport.h" -#include "../game.h" +#include "widgets/layout.h" + #include "../engine.h" +#include "../game.h" #include "../particle.h" #include "../map.h" -#include "../utils/tostring.h" +#include "../utils/stringutils.h" DebugWindow::DebugWindow(): Window("Debug") { setWindowName("Debug"); + setResizable(true); setCloseButton(true); setDefaultSize(0, 0, 400, 60); loadWindowState(); - mFPSLabel = new gcn::Label("[0 FPS]"); - mFPSLabel->setPosition(0,0); - + mFPSLabel = new gcn::Label("0 FPS"); mMusicFileLabel = new gcn::Label("Music: "); - mMusicFileLabel->setPosition(0, 15); - mMapLabel = new gcn::Label("Map: "); - mMapLabel->setPosition(0, 30); - mMiniMapLabel = new gcn::Label("Mini-Map: "); - mMiniMapLabel->setPosition(0, 45); - - mTileMouseLabel = new gcn::Label("[Mouse: 0, 0]"); - mTileMouseLabel->setPosition(200, 0); + mTileMouseLabel = new gcn::Label("Mouse: 0, 0"); + mParticleCountLabel = new gcn::Label("Particle count: 0"); - mParticleCountLabel = new gcn::Label("[Particle count: 0]"); - mParticleCountLabel->setPosition(200, 15); + place(0, 0, mFPSLabel); + place(3, 0, mTileMouseLabel); + place(0, 1, mMusicFileLabel, 2); + place(3, 1, mParticleCountLabel); + place(0, 2, mMapLabel, 2); + place(0, 3, mMiniMapLabel, 2); - add(mFPSLabel); - add(mMusicFileLabel); - add(mMiniMapLabel); - add(mMapLabel); - add(mTileMouseLabel); - add(mParticleCountLabel); + reflowLayout(375, 0); } -void -DebugWindow::logic() +void DebugWindow::logic() { // Get the current mouse position int mouseX, mouseY; SDL_GetMouseState(&mouseX, &mouseY); - int mouseTileX = mouseX + viewport->getCameraX(); - int mouseTileY = mouseY + viewport->getCameraY(); + int mouseTileX = mouseX / 32 + viewport->getCameraX(); + int mouseTileY = mouseY / 32 + viewport->getCameraY(); - mFPSLabel->setCaption("[" + toString(fps) + " FPS]"); + mFPSLabel->setCaption(toString(fps) + " FPS"); mFPSLabel->adjustSize(); - mTileMouseLabel->setCaption("[Mouse: " + - toString(mouseTileX) + ", " + toString(mouseTileY) + "]"); + mTileMouseLabel->setCaption("Mouse: " + + toString(mouseTileX) + ", " + toString(mouseTileY)); mTileMouseLabel->adjustSize(); Map *currentMap = engine->getCurrentMap(); - if (currentMap != NULL) + if (currentMap) { const std::string music = - " [Music: " + currentMap->getProperty("music") + "]"; + "Music: " + currentMap->getProperty("music"); mMusicFileLabel->setCaption(music); mMusicFileLabel->adjustSize(); const std::string minimap = - " [MiniMap: " + currentMap->getProperty("minimap") + "]"; + "MiniMap: " + currentMap->getProperty("minimap"); mMiniMapLabel->setCaption(minimap); mMiniMapLabel->adjustSize(); const std::string map = - " [Map: " + currentMap->getProperty("_filename") + "]"; + "Map: " + currentMap->getProperty("_filename"); mMapLabel->setCaption(map); mMapLabel->adjustSize(); } - mParticleCountLabel->setCaption("[Particle count: " + - toString(Particle::particleCount) - +"]"); + mParticleCountLabel->setCaption("Particle count: " + + toString(Particle::particleCount)); mParticleCountLabel->adjustSize(); } diff --git a/src/gui/debugwindow.h b/src/gui/debugwindow.h index 8d8b7822..e089de27 100644 --- a/src/gui/debugwindow.h +++ b/src/gui/debugwindow.h @@ -1,35 +1,31 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TMW_DEBUGWINDOW_H -#define _TMW_DEBUGWINDOW_H - -#include <iosfwd> +#ifndef DEBUGWINDOW_H +#define DEBUGWINDOW_H #include <guichan/actionlistener.hpp> #include "window.h" -#include "../guichanfwd.h" - /** * The debug window. * diff --git a/src/gui/emotecontainer.cpp b/src/gui/emotecontainer.cpp new file mode 100644 index 00000000..e22b031b --- /dev/null +++ b/src/gui/emotecontainer.cpp @@ -0,0 +1,172 @@ +/* + * Extended support for activating emotes + * Copyright (C) 2009 Aethyra 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 <guichan/mouseinput.hpp> +#include <guichan/selectionlistener.hpp> + +#include "emotecontainer.h" + +#include "../animatedsprite.h" +#include "../configuration.h" +#include "../emoteshortcut.h" +#include "../graphics.h" +#include "../localplayer.h" +#include "../log.h" + +#include "../resources/emotedb.h" +#include "../resources/image.h" +#include "../resources/iteminfo.h" +#include "../resources/resourcemanager.h" + +#include "../utils/dtor.h" +#include "../utils/gettext.h" +#include "../utils/stringutils.h" + +const int EmoteContainer::gridWidth = 34; // emote icon width + 4 +const int EmoteContainer::gridHeight = 36; // emote icon height + 4 + +static const int NO_EMOTE = -1; + +EmoteContainer::EmoteContainer(): + mSelectedEmoteIndex(NO_EMOTE) +{ + ResourceManager *resman = ResourceManager::getInstance(); + + // Setup emote sprites + for (int i = 0; i <= EmoteDB::getLast(); i++) + { + mEmoteImg.push_back(player_node->getEmote(i)); + } + + mSelImg = resman->getImage("graphics/gui/selection.png"); + if (!mSelImg) logger->error(_("Unable to load selection.png")); + + mSelImg->setAlpha(config.getValue("guialpha", 0.8)); + + mMaxEmote = EmoteDB::getLast() + 1; + + addMouseListener(this); + addWidgetListener(this); +} + +EmoteContainer::~EmoteContainer() +{ + if (!mSelImg) + { + mSelImg->decRef(); + mSelImg = NULL; + } +} + +void EmoteContainer::draw(gcn::Graphics *graphics) +{ + int columns = getWidth() / gridWidth; + + // Have at least 1 column + if (columns < 1) + { + columns = 1; + } + + for (int i = 0; i < mMaxEmote ; i++) + { + int emoteX = ((i) % columns) * gridWidth; + int emoteY = ((i) / columns) * gridHeight; + + // Draw emote icon + mEmoteImg[i]->draw(static_cast<Graphics*>(graphics), emoteX, emoteY); + + // Draw selection image below selected item + if (mSelectedEmoteIndex == i) + { + static_cast<Graphics*>(graphics)->drawImage( + mSelImg, emoteX, emoteY); + } + } +} + +void EmoteContainer::widgetResized(const gcn::Event &event) +{ + recalculateHeight(); +} + +void EmoteContainer::recalculateHeight() +{ + int cols = getWidth() / gridWidth; + + if (cols < 1) + cols = 1; + + const int rows = (mMaxEmote / cols) + (mMaxEmote % cols > 0 ? 1 : 0); + const int height = rows * gridHeight + 8; + if (height != getHeight()) + setHeight(height); +} + +int EmoteContainer::getSelectedEmote() +{ + if (mSelectedEmoteIndex == NO_EMOTE) + return 0; + + return 1 + mSelectedEmoteIndex; +} + +void EmoteContainer::selectNone() +{ + setSelectedEmoteIndex(NO_EMOTE); +} + +void EmoteContainer::setSelectedEmoteIndex(int index) +{ + if (index < 0 || index >= mMaxEmote ) + mSelectedEmoteIndex = NO_EMOTE; + else + mSelectedEmoteIndex = index; +} + +void EmoteContainer::distributeValueChangedEvent() +{ + gcn::SelectionEvent event(this); + std::list<gcn::SelectionListener*>::iterator i_end = mListeners.end(); + std::list<gcn::SelectionListener*>::iterator i; + + for (i = mListeners.begin(); i != i_end; ++i) + { + (*i)->valueChanged(event); + } +} + +void EmoteContainer::mousePressed(gcn::MouseEvent &event) +{ + int button = event.getButton(); + if (button == gcn::MouseEvent::LEFT || button == gcn::MouseEvent::RIGHT) + { + int columns = getWidth() / gridWidth; + int mx = event.getX(); + int my = event.getY(); + int index = mx / gridWidth + ((my / gridHeight) * columns); + if (index < mMaxEmote) + { + setSelectedEmoteIndex(index); + emoteShortcut->setEmoteSelected(index + 1); + } + } +} diff --git a/src/gui/emotecontainer.h b/src/gui/emotecontainer.h new file mode 100644 index 00000000..fefce793 --- /dev/null +++ b/src/gui/emotecontainer.h @@ -0,0 +1,136 @@ +/* + * Extended support for activating emotes + * Copyright (C) 2009 Aethyra 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 EMOTECONTAINER_H +#define EMOTECONTAINER_H + +#include <list> +#include <vector> + +#include <guichan/mouselistener.hpp> +#include <guichan/widget.hpp> +#include <guichan/widgetlistener.hpp> + +class AnimatedSprite; +class Image; + +namespace gcn { + class SelectionListener; +} + +/** + * An emote container. Used to show emotes in inventory and trade dialog. + * + * \ingroup GUI + */ +class EmoteContainer : public gcn::Widget, + public gcn::MouseListener, + public gcn::WidgetListener +{ + public: + /** + * Constructor. Initializes the graphic. + */ + EmoteContainer(); + + /** + * Destructor. + */ + virtual ~EmoteContainer(); + + /** + * Draws the emotes. + */ + void draw(gcn::Graphics *graphics); + + /** + * Called whenever the widget changes size. + */ + void widgetResized(const gcn::Event &event); + + /** + * Handles mouse click. + */ + void mousePressed(gcn::MouseEvent &event); + + /** + * Returns the selected emote. + */ + int getSelectedEmote(); + + /** + * Sets selected emote to NULL. + */ + void selectNone(); + + /** + * Adds a listener to the list that's notified each time a change to + * the selection occurs. + */ + void addSelectionListener(gcn::SelectionListener *listener) + { + mListeners.push_back(listener); + } + + /** + * Removes a listener from the list that's notified each time a change + * to the selection occurs. + */ + void removeSelectionListener(gcn::SelectionListener *listener) + { + mListeners.remove(listener); + } + + private: + /** + * Sets the currently selected emote. Invalid (e.g., negative) indices + * set `no emotr'. + */ + void setSelectedEmoteIndex(int index); + + /** + * Find the current emote index by the most recently used emote ID + */ + void refindSelectedEmote(void); + + /** + * Determine and set the height of the container. + */ + void recalculateHeight(void); + + /** + * Sends out selection events to the list of selection listeners. + */ + void distributeValueChangedEvent(void); + + std::vector<AnimatedSprite*> mEmoteImg; + Image *mSelImg; + int mSelectedEmoteIndex; + + int mMaxEmote; + + std::list<gcn::SelectionListener*> mListeners; + + static const int gridWidth; + static const int gridHeight; +}; + +#endif diff --git a/src/gui/emoteshortcutcontainer.cpp b/src/gui/emoteshortcutcontainer.cpp new file mode 100644 index 00000000..a0739723 --- /dev/null +++ b/src/gui/emoteshortcutcontainer.cpp @@ -0,0 +1,204 @@ +/* + * Extended support for activating emotes + * Copyright (C) 2009 Aethyra 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 "emoteshortcutcontainer.h" + +#include "../animatedsprite.h" +#include "../configuration.h" +#include "../emoteshortcut.h" +#include "../graphics.h" +#include "../inventory.h" +#include "../item.h" +#include "../itemshortcut.h" +#include "../keyboardconfig.h" +#include "../localplayer.h" +#include "../log.h" + +#include "../resources/emotedb.h" +#include "../resources/image.h" +#include "../resources/resourcemanager.h" + +#include "../utils/dtor.h" +#include "../utils/gettext.h" +#include "../utils/stringutils.h" + +static const int MAX_ITEMS = 12; + +EmoteShortcutContainer::EmoteShortcutContainer(): + ShortcutContainer(), + mEmoteClicked(false), + mEmoteMoved(0) +{ + addMouseListener(this); + addWidgetListener(this); + + ResourceManager *resman = ResourceManager::getInstance(); + + mBackgroundImg = resman->getImage("graphics/gui/item_shortcut_bgr.png"); + + mBackgroundImg->setAlpha(config.getValue("guialpha", 0.8)); + + // Setup emote sprites + for (int i = 0; i <= EmoteDB::getLast(); i++) + { + mEmoteImg.push_back(player_node->getEmote(i)); + } + + mMaxItems = EmoteDB::getLast() < MAX_ITEMS ? EmoteDB::getLast() : MAX_ITEMS; + + mBoxHeight = mBackgroundImg->getHeight(); + mBoxWidth = mBackgroundImg->getWidth(); +} + +EmoteShortcutContainer::~EmoteShortcutContainer() +{ + mBackgroundImg->decRef(); +} + +void EmoteShortcutContainer::draw(gcn::Graphics *graphics) +{ + Graphics *g = static_cast<Graphics*>(graphics); + + graphics->setFont(getFont()); + + for (int i = 0; i < mMaxItems; i++) + { + const int emoteX = (i % mGridWidth) * mBoxWidth; + const int emoteY = (i / mGridWidth) * mBoxHeight; + + g->drawImage(mBackgroundImg, emoteX, emoteY); + + // Draw emote keyboard shortcut. + const char *key = SDL_GetKeyName( + (SDLKey) keyboard.getKeyValue(keyboard.KEY_EMOTE_1 + i)); + graphics->setColor(0x000000); + g->drawText(key, emoteX + 2, emoteY + 2, gcn::Graphics::LEFT); + + if (emoteShortcut->getEmote(i)) + { + mEmoteImg[emoteShortcut->getEmote(i) - 1]->draw(g, emoteX + 2, emoteY + 10); + } + + } + + if (mEmoteMoved) + { + // Draw the emote image being dragged by the cursor. + AnimatedSprite* sprite = mEmoteImg[mEmoteMoved - 1]; + if (sprite) + { + const int tPosX = mCursorPosX - (sprite->getWidth() / 2); + const int tPosY = mCursorPosY - (sprite->getHeight() / 2); + + sprite->draw(g, tPosX, tPosY); + } + } + + if (config.getValue("guialpha", 0.8) != mAlpha) + { + mAlpha = config.getValue("guialpha", 0.8); + mBackgroundImg->setAlpha(mAlpha); + } +} + +void EmoteShortcutContainer::mouseDragged(gcn::MouseEvent &event) +{ + if (event.getButton() == gcn::MouseEvent::LEFT) + { + if (!mEmoteMoved && mEmoteClicked) + { + const int index = getIndexFromGrid(event.getX(), event.getY()); + const int emoteId = emoteShortcut->getEmote(index); + + if (index == -1) + { + return; + } + + if (emoteId) + { + mEmoteMoved = emoteId; + emoteShortcut->removeEmote(index); + } + } + if (mEmoteMoved) + { + mCursorPosX = event.getX(); + mCursorPosY = event.getY(); + } + } +} + +void EmoteShortcutContainer::mousePressed(gcn::MouseEvent &event) +{ + const int index = getIndexFromGrid(event.getX(), event.getY()); + + if (index == -1) + { + return; + } + + // Stores the selected emote if there is one. + if (emoteShortcut->isEmoteSelected()) + { + emoteShortcut->setEmote(index); + emoteShortcut->setEmoteSelected(0); + } + else if (emoteShortcut->getEmote(index)) + { + mEmoteClicked = true; + } +} + +void EmoteShortcutContainer::mouseReleased(gcn::MouseEvent &event) +{ + if (event.getButton() == gcn::MouseEvent::LEFT) + { + const int index = getIndexFromGrid(event.getX(), event.getY()); + + if (emoteShortcut->isEmoteSelected()) + { + emoteShortcut->setEmoteSelected(0); + } + + if (index == -1) + { + mEmoteMoved = 0; + return; + } + + if (mEmoteMoved) + { + emoteShortcut->setEmotes(index, mEmoteMoved); + mEmoteMoved = 0; + } + else if (emoteShortcut->getEmote(index) && mEmoteClicked) + { + emoteShortcut->useEmote(index + 1); + } + + if (mEmoteClicked) + { + mEmoteClicked = false; + } + } +} + diff --git a/src/gui/emoteshortcutcontainer.h b/src/gui/emoteshortcutcontainer.h new file mode 100644 index 00000000..d32a9f79 --- /dev/null +++ b/src/gui/emoteshortcutcontainer.h @@ -0,0 +1,77 @@ +/* + * Extended support for activating emotes + * Copyright (C) 2009 Aethyra 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 EMOTESHORTCUTCONTAINER_H +#define EMOTESHORTCUTCONTAINER_H + +#include <vector> + +#include "shortcutcontainer.h" + +class AnimatedSprite; +class Image; + +/** + * An emote shortcut container. Used to quickly use emoticons. + * + * \ingroup GUI + */ +class EmoteShortcutContainer : public ShortcutContainer +{ + public: + /** + * Constructor. Initializes the graphic. + */ + EmoteShortcutContainer(); + + /** + * Destructor. + */ + virtual ~EmoteShortcutContainer(); + + /** + * Draws the items. + */ + void draw(gcn::Graphics *graphics); + + /** + * Handles mouse when dragged. + */ + void mouseDragged(gcn::MouseEvent &event); + + /** + * Handles mouse when pressed. + */ + void mousePressed(gcn::MouseEvent &event); + + /** + * Handles mouse release. + */ + void mouseReleased(gcn::MouseEvent &event); + + private: + std::vector<AnimatedSprite*> mEmoteImg; + + bool mEmoteClicked; + int mEmoteMoved; +}; + +#endif diff --git a/src/gui/emotewindow.cpp b/src/gui/emotewindow.cpp new file mode 100644 index 00000000..48635720 --- /dev/null +++ b/src/gui/emotewindow.cpp @@ -0,0 +1,77 @@ +/* + * Extended support for activating emotes + * Copyright (C) 2009 Aethyra 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 "button.h" +#include "gui.h" +#include "emotewindow.h" +#include "emotecontainer.h" +#include "scrollarea.h" + +#include "widgets/layout.h" + +#include "../localplayer.h" + +#include "../utils/gettext.h" +#include "../utils/stringutils.h" + +EmoteWindow::EmoteWindow(): + Window(_("Emote")) +{ + setWindowName("Emote"); + setResizable(true); + setCloseButton(true); + setMinWidth(80); + setMinHeight(130); + setDefaultSize(115, 25, 322, 200); + + mUseButton = new Button(_("Use"), "use", this); + + mEmotes = new EmoteContainer; + mEmotes->addSelectionListener(this); + + mEmoteScroll = new ScrollArea(mEmotes); + mEmoteScroll->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); + + place(0, 0, mEmoteScroll, 5, 4); + place(4, 4, mUseButton); + + Layout &layout = getLayout(); + layout.setRowHeight(0, Layout::AUTO_SET); + + mUseButton->setSize(60, mUseButton->getHeight()); + + loadWindowState(); +} + +void EmoteWindow::action(const gcn::ActionEvent &event) +{ + int emote = mEmotes->getSelectedEmote(); + + if (!emote) + return; + + player_node->emote(emote); +} + +int EmoteWindow::getSelectedEmote() const +{ + return mEmotes->getSelectedEmote(); +} diff --git a/src/gui/emotewindow.h b/src/gui/emotewindow.h new file mode 100644 index 00000000..8af24a7b --- /dev/null +++ b/src/gui/emotewindow.h @@ -0,0 +1,66 @@ +/* + * Extended support for activating emotes + * Copyright (C) 2009 Aethyra 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 EMOTEWINDOW_H +#define EMOTEWINDOW_H + +#include <guichan/actionlistener.hpp> +#include <guichan/selectionlistener.hpp> + +#include "window.h" + +class EmoteContainer; +class TextBox; + +/** + * Emote dialog. + * + * \ingroup Interface + */ +class EmoteWindow : public Window, gcn::ActionListener, + gcn::SelectionListener +{ + public: + /** + * Constructor. + */ + EmoteWindow(); + + /** + * Called when receiving actions from the widgets. + */ + void action(const gcn::ActionEvent &event); + + /** + * Returns the selected item. + */ + int getSelectedEmote() const; + + private: + EmoteContainer *mEmotes; + + gcn::Button *mUseButton; + gcn::ScrollArea *mEmoteScroll; +}; + +extern EmoteWindow *emoteWindow; + +#endif diff --git a/src/gui/equipmentwindow.cpp b/src/gui/equipmentwindow.cpp index 6848b4d8..a44ae3ec 100644 --- a/src/gui/equipmentwindow.cpp +++ b/src/gui/equipmentwindow.cpp @@ -1,73 +1,100 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #define BOX_WIDTH 36 #define BOX_HEIGHT 36 -#include "equipmentwindow.h" +#include <guichan/font.hpp> #include "button.h" +#include "equipmentwindow.h" +#include "itempopup.h" +#include "playerbox.h" +#include "viewport.h" +#include "../equipment.h" #include "../graphics.h" +#include "../inventory.h" #include "../item.h" #include "../localplayer.h" #include "../resources/image.h" +#include "../resources/iteminfo.h" #include "../resources/resourcemanager.h" #include "../utils/gettext.h" +#include "../utils/stringutils.h" // Positions of the boxes, 2nd dimension is X and Y respectively. static const int boxPosition[][2] = { - {90, 100}, // EQUIP_TORSO_SLOT - {135, 60}, // EQUIP_ARMS_SLOT - {90, 10}, // EQUIP_HEAD_SLOT - {90, 145}, // EQUIP_LEGS_SLOT - {90, 190}, // EQUIP_FEET_SLOT - {35, 105}, // EQUIP_RING1_SLOT - {145, 105}, // EQUIP_RING2_SLOT - {90, 55}, // EQUIP_NECKLACE_SLOT - {20, 150}, // EQUIP_FIGHT1_SLOT - {160, 150}, // EQUIP_FIGHT2_SLOT - {45, 60} // EQUIP_PROJECTILE_SLOT + {50, 208}, // EQUIP_LEGS_SLOT + {8, 123}, // EQUIP_FIGHT1_SLOT + {8, 78}, // EQUIP_GLOVES_SLOT + {129, 168}, // EQUIP_RING2_SLOT + {8, 168}, // EQUIP_RING1_SLOT + {129, 123}, // EQUIP_FIGHT2_SLOT + {90, 208}, // EQUIP_FEET_SLOT + {50, 40}, // EQUIP_CAPE_SLOT + {70, 0}, // EQUIP_HEAD_SLOT + {90, 40}, // EQUIP_TORSO_SLOT + {129, 78} // EQUIP_AMMO_SLOT }; +#ifdef TMWSERV_SUPPORT EquipmentWindow::EquipmentWindow(Equipment *equipment): +#else +EquipmentWindow::EquipmentWindow(): +#endif Window(_("Equipment")), +#ifdef TMWSERV_SUPPORT mEquipment(equipment), +#endif mBackground(NULL), mSelected(-1) { + mItemPopup = new ItemPopup; + + // Control that shows the Player + mPlayerBox = new PlayerBox; + mPlayerBox->setDimension(gcn::Rectangle(50, 80, 74, 123)); + mPlayerBox->setPlayer(player_node); + setWindowName("Equipment"); setCloseButton(true); - setDefaultSize(5, 195, 216, 260); + setDefaultSize(5, 195, 180, 300); loadWindowState(); mUnequip = new Button(_("Unequip"), "unequip", this); gcn::Rectangle const &area = getChildrenArea(); mUnequip->setPosition(area.width - mUnequip->getWidth() - 5, area.height - mUnequip->getHeight() - 5); + + add(mPlayerBox); add(mUnequip); +#ifdef TMWSERV_SUPPORT for (int i = 0; i < EQUIPMENT_SIZE; i++) +#else + for (int i = EQUIP_LEGS_SLOT; i < EQUIP_VECTOREND; i++) +#endif { mEquipBox[i].posX = boxPosition[i][0] + getPadding(); mEquipBox[i].posY = boxPosition[i][1] + getTitleBarHeight(); @@ -76,11 +103,17 @@ EquipmentWindow::EquipmentWindow(Equipment *equipment): ResourceManager *resman = ResourceManager::getInstance(); mBackground = resman->getImage("graphics/gui/equip_bg.png"); mBackground->setAlpha(0.3); + +#ifdef EATHENA_SUPPORT + mEquipment = player_node->mEquipment.get(); + mInventory = player_node->getInventory(); +#endif } EquipmentWindow::~EquipmentWindow() { mBackground->decRef(); + delete mItemPopup; delete mUnequip; } @@ -91,21 +124,36 @@ void EquipmentWindow::draw(gcn::Graphics *graphics) Graphics *g = static_cast<Graphics*>(graphics); - if (mBackground) - { - g->drawImage(mBackground, getPadding() + 10, 0); - } - Window::drawChildren(graphics); +#ifdef TMWSERV_SUPPORT for (int i = 0; i < EQUIPMENT_SIZE; i++) +#else + for (int i = EQUIP_LEGS_SLOT; i < EQUIP_VECTOREND; i++) +#endif { +#ifdef TMWSERV_SUPPORT Item *item = mEquipment->getEquipment(i); +#else + Item *item = (i != EQUIP_AMMO_SLOT) ? + mInventory->getItem(mEquipment->getEquipment(i)) : + mInventory->getItem(mEquipment->getArrows()); +#endif if (item) { // Draw Item. Image *image = item->getImage(); g->drawImage(image, mEquipBox[i].posX, mEquipBox[i].posY); +#ifdef EATHENA_SUPPORT + if (i == EQUIP_AMMO_SLOT) + { + g->setColor(gcn::Color(0, 0, 0)); + graphics->drawText(toString(item->getQuantity()), + mEquipBox[i].posX + (BOX_WIDTH / 2), + mEquipBox[i].posY - getFont()->getHeight(), + gcn::Graphics::CENTER); + } +#endif } if (i == mSelected) @@ -118,6 +166,7 @@ void EquipmentWindow::draw(gcn::Graphics *graphics) // Set color black. g->setColor(gcn::Color(0, 0, 0)); } + // Draw box border. g->drawRectangle(gcn::Rectangle(mEquipBox[i].posX, mEquipBox[i].posY, BOX_WIDTH, BOX_HEIGHT)); @@ -128,11 +177,43 @@ void EquipmentWindow::action(const gcn::ActionEvent &event) { if (event.getId() == "unequip" && mSelected > -1) { +#ifdef TMWSERV_SUPPORT player_node->unequipItem(mSelected); +#else + Item* item = (mSelected != EQUIP_AMMO_SLOT) ? + mInventory->getItem(mEquipment->getEquipment(mSelected)) : + mInventory->getItem(mEquipment->getArrows()); + player_node->unequipItem(item); +#endif mSelected = -1; } } +Item* EquipmentWindow::getItem(int x, int y) const +{ +#ifdef TMWSERV_SUPPORT + for (int i = 0; i < EQUIPMENT_SIZE; i++) +#else + for (int i = EQUIP_LEGS_SLOT; i < EQUIP_VECTOREND; i++) +#endif + { + gcn::Rectangle tRect(mEquipBox[i].posX, mEquipBox[i].posY, + BOX_WIDTH, BOX_HEIGHT); + + if (tRect.isPointInRect(x, y)) + { +#ifdef TMWSERV_SUPPORT + return mEquipment->getEquipment(i); +#else + return (i != EQUIP_AMMO_SLOT) ? + mInventory->getItem(mEquipment->getEquipment(i)) : + mInventory->getItem(mEquipment->getArrows()); +#endif + } + } + return NULL; +} + void EquipmentWindow::mousePressed(gcn::MouseEvent& mouseEvent) { Window::mousePressed(mouseEvent); @@ -140,17 +221,77 @@ void EquipmentWindow::mousePressed(gcn::MouseEvent& mouseEvent) const int x = mouseEvent.getX(); const int y = mouseEvent.getY(); - // Checks if any of the presses were in the equip boxes. - for (int i = 0; i < EQUIPMENT_SIZE; i++) + Item* item; + + if (mouseEvent.getButton() == gcn::MouseEvent::LEFT) { - gcn::Rectangle tRect(mEquipBox[i].posX, mEquipBox[i].posY, - BOX_WIDTH, BOX_HEIGHT); - if (tRect.isPointInRect(x, y)) + // Checks if any of the presses were in the equip boxes. +#ifdef TMWSERV_SUPPORT + for (int i = 0; i < EQUIPMENT_SIZE; i++) +#else + for (int i = EQUIP_LEGS_SLOT; i < EQUIP_VECTOREND; i++) +#endif { - if (mEquipment->getEquipment(i)) +#ifdef TMWSERV_SUPPORT + item = mEquipment->getEquipment(i); +#else + item = (i != EQUIP_AMMO_SLOT) ? + mInventory->getItem(mEquipment->getEquipment(i)) : + mInventory->getItem(mEquipment->getArrows()); +#endif + gcn::Rectangle tRect(mEquipBox[i].posX, mEquipBox[i].posY, + BOX_WIDTH, BOX_HEIGHT); + + if (tRect.isPointInRect(x, y)) { - mSelected = i; + if (item) + { + mSelected = i; + } } } } + else if (mouseEvent.getButton() == gcn::MouseEvent::RIGHT) + { + item = getItem(x, y); + + if (!item) + return; + + /* Convert relative to the window coordinates to absolute screen + * coordinates. + */ + const int mx = x + getX(); + const int my = y + getY(); + viewport->showPopup(mx, my, item); + } +} + +// Show ItemTooltip +void EquipmentWindow::mouseMoved(gcn::MouseEvent &event) +{ + const int x = event.getX(); + const int y = event.getY(); + + Item* item = getItem(x, y); + + if (item) + { + int mouseX, mouseY; + SDL_GetMouseState(&mouseX, &mouseY); + + mItemPopup->setItem(item->getInfo()); + mItemPopup->setOpaque(false); + mItemPopup->view(x + getX(), y + getY()); + } + else + { + mItemPopup->setVisible(false); + } +} + +// Hide ItemTooltip +void EquipmentWindow::mouseExited(gcn::MouseEvent &event) +{ + mItemPopup->setVisible(false); } diff --git a/src/gui/equipmentwindow.h b/src/gui/equipmentwindow.h index b6d2e2f4..7f7150ff 100644 --- a/src/gui/equipmentwindow.h +++ b/src/gui/equipmentwindow.h @@ -1,35 +1,37 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TMW_EQUIPMENT_H -#define _TMW_EQUIPMENT_H - -#include "window.h" +#ifndef EQUIPMENTWINDOW_H +#define EQUIPMENTWINDOW_H #include <guichan/actionlistener.hpp> -#include "../equipment.h" +#include "window.h" class Equipment; class Image; +class Inventory; +class Item; +class ItemPopup; +class PlayerBox; /** * Equipment box. @@ -51,7 +53,11 @@ class EquipmentWindow : public Window, public gcn::ActionListener /** * Constructor. */ +#ifdef TMWSERV_SUPPORT EquipmentWindow(Equipment *equipment); +#else + EquipmentWindow(); +#endif /** * Destructor. @@ -67,6 +73,7 @@ class EquipmentWindow : public Window, public gcn::ActionListener void mousePressed(gcn::MouseEvent& mouseEvent); +#ifdef TMWSERV_SUPPORT enum{ // Equipment rules: EQUIP_TORSO_SLOT = 0, @@ -79,15 +86,46 @@ class EquipmentWindow : public Window, public gcn::ActionListener EQUIP_NECKLACE_SLOT = 7, EQUIP_FIGHT1_SLOT = 8, EQUIP_FIGHT2_SLOT = 9, - EQUIP_PROJECTILE_SLOT = 10 + EQUIP_PROJECTILE_SLOT = 10, + EQUIP_VECTOREND }; +#else + enum { + // Equipment rules: + EQUIP_LEGS_SLOT = 0, + EQUIP_FIGHT1_SLOT, + EQUIP_GLOVES_SLOT, + EQUIP_RING2_SLOT, + EQUIP_RING1_SLOT, + EQUIP_FIGHT2_SLOT, + EQUIP_FEET_SLOT, + EQUIP_CAPE_SLOT, + EQUIP_HEAD_SLOT, + EQUIP_TORSO_SLOT, + EQUIP_AMMO_SLOT, + EQUIP_VECTOREND + }; +#endif + private: + void mouseExited(gcn::MouseEvent &event); + void mouseMoved(gcn::MouseEvent &event); + + Item* getItem(int x, int y) const; + Equipment *mEquipment; - gcn::Button *mUnequip; /**< Button for unequipping. */ +#ifdef EATHENA_SUPPORT + Inventory *mInventory; +#endif + gcn::Button *mUnequip; /**< Button for unequipping. */ Image *mBackground; /**< Background Image. */ - EquipBox mEquipBox[EQUIPMENT_SIZE]; /**< Equipment Boxes. */ + EquipBox mEquipBox[EQUIP_VECTOREND]; /**< Equipment Boxes. */ + + ItemPopup *mItemPopup; + + PlayerBox *mPlayerBox; - int mSelected; /**< Index of selected item. */ + int mSelected; /**< Index of selected item. */ }; extern EquipmentWindow *equipmentWindow; diff --git a/src/gui/focushandler.cpp b/src/gui/focushandler.cpp index 1bda568e..b9cfd789 100644 --- a/src/gui/focushandler.cpp +++ b/src/gui/focushandler.cpp @@ -1,33 +1,32 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "focushandler.h" - void FocusHandler::requestModalFocus(gcn::Widget *widget) { /* If there is another widget with modal focus, remove its modal focus * and put it on the modal widget stack. */ - if (mModalFocusedWidget != NULL && mModalFocusedWidget != widget) + if (mModalFocusedWidget && mModalFocusedWidget != widget) { mModalStack.push_front(mModalFocusedWidget); mModalFocusedWidget = NULL; diff --git a/src/gui/focushandler.h b/src/gui/focushandler.h index a5218485..b0639bd8 100644 --- a/src/gui/focushandler.h +++ b/src/gui/focushandler.h @@ -1,33 +1,31 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TMW_FOCUSHANDLER_H -#define _TMW_FOCUSHANDLER_H +#ifndef FOCUSHANDLER_H +#define FOCUSHANDLER_H #include <list> #include <guichan/focushandler.hpp> -#include "../guichanfwd.h" - /** * The focus handler. This focus handler does exactly the same as the Guichan * focus handler, but keeps a stack of modal widgets to be able to handle diff --git a/src/gui/gccontainer.cpp b/src/gui/gccontainer.cpp index ec3c8a5c..8325ccd4 100644 --- a/src/gui/gccontainer.cpp +++ b/src/gui/gccontainer.cpp @@ -1,21 +1,21 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ diff --git a/src/gui/gccontainer.h b/src/gui/gccontainer.h index cc7c9336..da584a42 100644 --- a/src/gui/gccontainer.h +++ b/src/gui/gccontainer.h @@ -1,26 +1,26 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TMW_GUI_GCCONTAINER_H -#define _TMW_GUI_GCCONTAINER_H +#ifndef GUI_GCCONTAINER_H +#define GUI_GCCONTAINER_H #include <list> diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index dc6306b4..1ef0219a 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -1,31 +1,30 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * 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.h" - #include <guichan/exception.hpp> #include <guichan/image.hpp> #include <guichan/imagefont.hpp> #include "focushandler.h" +#include "gui.h" #include "sdlinput.h" #include "truetypefont.h" #include "viewport.h" @@ -39,20 +38,21 @@ #include "../resources/image.h" #include "../resources/imageset.h" -#include "../resources/resourcemanager.h" #include "../resources/imageloader.h" +#include "../resources/resourcemanager.h" // Guichan stuff -Gui *gui; -Viewport *viewport; /**< Viewport on the map. */ -SDLInput *guiInput; +Gui *gui = 0; +Viewport *viewport = 0; /**< Viewport on the map. */ +SDLInput *guiInput = 0; // Fonts used in showing hits -gcn::Font *hitRedFont; -gcn::Font *hitBlueFont; -gcn::Font *hitYellowFont; -// Font used to display speech and player names -gcn::Font *speechFont; +gcn::Font *hitRedFont = 0; +gcn::Font *hitBlueFont = 0; +gcn::Font *hitYellowFont = 0; + +// Bolded font +gcn::Font *boldFont = 0; class GuiConfigListener : public ConfigListener { @@ -63,7 +63,8 @@ class GuiConfigListener : public ConfigListener void optionChanged(const std::string &name) { - if (name == "customcursor") { + if (name == "customcursor") + { bool bCustomCursor = config.getValue("customcursor", 1) == 1; mGui->setUseCustomCursor(bCustomCursor); } @@ -96,7 +97,7 @@ Gui::Gui(Graphics *graphics): mFocusHandler = new FocusHandler; // Initialize top GUI widget - WindowContainer *guiTop = new WindowContainer(); + WindowContainer *guiTop = new WindowContainer; guiTop->setDimension(gcn::Rectangle(0, 0, graphics->getWidth(), graphics->getHeight())); guiTop->setOpaque(false); @@ -107,35 +108,48 @@ Gui::Gui(Graphics *graphics): // Set global font std::string path = resman->getPath( - branding.getValue("guiFont","fonts/dejavusans.ttf")); - if (!path.empty()) + branding.getValue("font", "fonts/dejavusans.ttf")); + try + { + const int fontSize = (int)config.getValue("fontSize", 11); + mGuiFont = new TrueTypeFont(path, fontSize); + } + catch (gcn::Exception e) { - mGuiFont = new TrueTypeFont(path.c_str(), 11); + logger->error(std::string("Unable to load dejavusans.ttf: ") + + e.getMessage()); } - // Set speech font + // Set bold font path = resman->getPath( - branding.getValue("speechFont","fonts/dejavusans.ttf")); - if (!path.empty()) + branding.getValue("boldFont", "fonts/dejavusans.ttf")); + try { - speechFont = new TrueTypeFont(path.c_str(), 11); + const int fontSize = (int)config.getValue("fontSize", 11); + boldFont = new TrueTypeFont(path, fontSize); + } + catch (gcn::Exception e) + { + logger->error(std::string("Unable to load dejavusans-bold.ttf: ") + + e.getMessage()); } gcn::Widget::setGlobalFont(mGuiFont); - // Load hits' colourful fonts - try { + // Load hits' colorful fonts + try + { hitRedFont = new gcn::ImageFont("graphics/gui/hits_red.png", - "0123456789"); + "0123456789crit! "); hitBlueFont = new gcn::ImageFont("graphics/gui/hits_blue.png", - "0123456789"); + "0123456789crit! "); hitYellowFont = new gcn::ImageFont("graphics/gui/hits_yellow.png", "0123456789misxp "); } catch (gcn::Exception e) { - logger->log("Unable to load colored hits' fonts: %s", e.getMessage().c_str()); - throw; + logger->error(std::string("Unable to load colored hits' fonts: ") + + e.getMessage()); } // Initialize mouse cursor and listen for changes to the option @@ -144,7 +158,7 @@ Gui::Gui(Graphics *graphics): config.addListener("customcursor", mConfigListener); // Create the viewport - viewport = new Viewport(); + viewport = new Viewport; viewport->setDimension(gcn::Rectangle(0, 0, graphics->getWidth(), graphics->getHeight())); guiTop->add(viewport); @@ -164,7 +178,7 @@ Gui::~Gui() mMouseCursors->decRef(); delete mGuiFont; - delete speechFont; + delete boldFont; delete viewport; delete getTop(); @@ -174,12 +188,13 @@ Gui::~Gui() void Gui::logic() { // Fade out mouse cursor after extended inactivity - if (mMouseInactivityTimer < 100 * 15) { + if (mMouseInactivityTimer < 100 * 15) + { ++mMouseInactivityTimer; mMouseCursorAlpha = std::min(1.0f, mMouseCursorAlpha + 0.05f); - } else { - mMouseCursorAlpha = std::max(0.0f, mMouseCursorAlpha - 0.005f); } + else + mMouseCursorAlpha = std::max(0.0f, mMouseCursorAlpha - 0.005f); gcn::Gui::logic(); } @@ -224,9 +239,8 @@ void Gui::setUseCustomCursor(bool customCursor) mMouseCursors = resman->getImageSet("graphics/gui/mouse.png", 40, 40); - if (!mMouseCursors) { + if (!mMouseCursors) logger->error("Unable to load mouse cursors."); - } } else { @@ -234,7 +248,8 @@ void Gui::setUseCustomCursor(bool customCursor) SDL_ShowCursor(SDL_ENABLE); // Unload the mouse cursor - if (mMouseCursors) { + if (mMouseCursors) + { mMouseCursors->decRef(); mMouseCursors = NULL; } diff --git a/src/gui/gui.h b/src/gui/gui.h index 7d390df9..5c0c24f7 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -1,33 +1,33 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TMW_GUI -#define _TMW_GUI +#ifndef GUI +#define GUI #include <guichan/gui.hpp> #include "../guichanfwd.h" -class GuiConfigListener; class Graphics; +class GuiConfigListener; class ImageSet; class SDLInput; class Viewport; @@ -115,7 +115,6 @@ class Gui : public gcn::Gui }; extern Gui *gui; /**< The GUI system */ -extern Viewport *viewport; /**< The viewport */ extern SDLInput *guiInput; /**< GUI input */ /** @@ -124,9 +123,10 @@ extern SDLInput *guiInput; /**< GUI input */ extern gcn::Font *hitRedFont; extern gcn::Font *hitBlueFont; extern gcn::Font *hitYellowFont; + /** - * Font used to display speech and player names + * Bolded text font */ -extern gcn::Font *speechFont; +extern gcn::Font *boldFont; #endif diff --git a/src/gui/hbox.cpp b/src/gui/hbox.cpp deleted file mode 100644 index 020e85c6..00000000 --- a/src/gui/hbox.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/* - * The Mana World - * Copyright 2004 The Mana World Development Team - * - * This file is part of The Mana World. - * - * The Mana World 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. - * - * The Mana World 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 The Mana World; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "hbox.h" - -void HBox::draw(gcn::Graphics *graphics) -{ - int widgetCount = mWidgets.size(); - int childHeight = getHeight(); - if (widgetCount == 0) - return; - int childWidth = getWidth() / widgetCount; - - int i = 0; - for (WidgetIterator w = mWidgets.begin(); w != mWidgets.end(); w++) { - (*w)->setPosition(childWidth * i - padding, 0); - (*w)->setSize(childWidth, childHeight); - i++; - } - gcn::Container::draw(graphics); -} diff --git a/src/gui/hbox.h b/src/gui/hbox.h deleted file mode 100644 index 4b241383..00000000 --- a/src/gui/hbox.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * The Mana World - * Copyright 2004 The Mana World Development Team - * - * This file is part of The Mana World. - * - * The Mana World 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. - * - * The Mana World 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 The Mana World; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef HBOX_H -#define HBOX_H - -#include "box.h" - -class HBox : public Box -{ - public: - void draw(gcn::Graphics *); -}; - -#endif diff --git a/src/gui/help.cpp b/src/gui/help.cpp index 290679b9..30c6a9c4 100644 --- a/src/gui/help.cpp +++ b/src/gui/help.cpp @@ -1,42 +1,48 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "help.h" - #include "button.h" #include "browserbox.h" +#include "help.h" #include "scrollarea.h" +#include "widgets/layout.h" + #include "../resources/resourcemanager.h" +#include "../utils/gettext.h" + HelpWindow::HelpWindow(): - Window("Help") + Window(_("Help")) { + setMinWidth(300); + setMinHeight(250); setContentSize(455, 350); setWindowName("Help"); + setResizable(true); - mBrowserBox = new BrowserBox(); + mBrowserBox = new BrowserBox; mBrowserBox->setOpaque(false); mScrollArea = new ScrollArea(mBrowserBox); - Button *okButton = new Button("Close", "close", this); + Button *okButton = new Button(_("Close"), "close", this); mScrollArea->setDimension(gcn::Rectangle( 5, 5, 445, 335 - okButton->getHeight())); @@ -46,8 +52,11 @@ HelpWindow::HelpWindow(): mBrowserBox->setLinkHandler(this); - add(mScrollArea); - add(okButton); + place(0, 0, mScrollArea, 5, 3).setPadding(3); + place(4, 3, okButton); + + Layout &layout = getLayout(); + layout.setRowHeight(0, Layout::AUTO_SET); setLocationRelativeTo(getParent()); } diff --git a/src/gui/help.h b/src/gui/help.h index 053df723..98e3aa67 100644 --- a/src/gui/help.h +++ b/src/gui/help.h @@ -1,33 +1,31 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TMW_HELP_H -#define _TMW_HELP_H +#ifndef HELP_H +#define HELP_H #include <guichan/actionlistener.hpp> -#include "window.h" #include "linkhandler.h" - -#include "../guichanfwd.h" +#include "window.h" class BrowserBox; diff --git a/src/gui/inttextbox.cpp b/src/gui/inttextbox.cpp deleted file mode 100644 index 644601cf..00000000 --- a/src/gui/inttextbox.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/* - * The Mana World - * Copyright 2004 The Mana World Development Team - * - * This file is part of The Mana World. - * - * The Mana World 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. - * - * The Mana World 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 The Mana World; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "inttextbox.h" - -#include "sdlinput.h" - -#include "../utils/tostring.h" - -IntTextBox::IntTextBox(int i): - mValue(i) -{ -} - -void -IntTextBox::keyPressed(gcn::KeyEvent &event) -{ - const gcn::Key &key = event.getKey(); - - if (key.getValue() == Key::BACKSPACE || - key.getValue() == Key::DELETE) - { - setText(std::string()); - event.consume(); - } - - if (!key.isNumber()) return; - TextField::keyPressed(event); - - std::istringstream s(getText()); - int i; - s >> i; - setInt(i); - distributeActionEvent(); -} - -void IntTextBox::setRange(int min, int max) -{ - mMin = min; - mMax = max; -} - -int IntTextBox::getInt() -{ - return getText().empty() ? mMin : mValue; -} - -void IntTextBox::setInt(int i) -{ - if (i >= mMin && i <= mMax) - mValue = i; - - const std::string valStr = toString(mValue); - setText(valStr); - setCaretPosition(valStr.length() + 1); -} diff --git a/src/gui/inttextfield.cpp b/src/gui/inttextfield.cpp new file mode 100644 index 00000000..d3fe448b --- /dev/null +++ b/src/gui/inttextfield.cpp @@ -0,0 +1,104 @@ +/* + * The Mana World + * Copyright (C) 2004 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 "inttextfield.h" +#include "sdlinput.h" + +#include "../utils/stringutils.h" + +IntTextField::IntTextField(int def): + TextField(toString(def)), + mDefault(def), + mValue(def) +{ +} + +void IntTextField::keyPressed(gcn::KeyEvent &event) +{ + const gcn::Key &key = event.getKey(); + + if (key.getValue() == Key::BACKSPACE || + key.getValue() == Key::DELETE) + { + setText(std::string()); + event.consume(); + } + + if (!key.isNumber()) + return; + + TextField::keyPressed(event); + + std::istringstream s(getText()); + int i; + s >> i; + setValue(i); +} + +void IntTextField::setRange(int min, int max) +{ + mMin = min; + mMax = max; + + if (mValue < mMin) + mValue = mMin; + else if (mValue > mMax) + mValue = mMax; + + if (mDefault < mMin) + mDefault = mMin; + else if (mDefault > mMax) + mDefault = mMax; +} + +int IntTextField::getValue() +{ + return getText().empty() ? mMin : mValue; +} + +void IntTextField::setValue(int i) +{ + if (i < mMin) + mValue = mMin; + else if (i > mMax) + mValue = mMax; + else + mValue = i; + + const std::string valStr = toString(mValue); + setText(valStr); + setCaretPosition(valStr.length() + 1); +} + +void IntTextField::setDefaultValue(int value) +{ + if (value < mMin) + mDefault = mMin; + else if (value > mMax) + mDefault = mMax; + else + mDefault = value; +} + +void IntTextField::reset() +{ + setValue(mDefault); +} diff --git a/src/gui/inttextbox.h b/src/gui/inttextfield.h index 8dad0c39..ec768bea 100644 --- a/src/gui/inttextbox.h +++ b/src/gui/inttextfield.h @@ -1,39 +1,39 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef INTTEXTBOX_H -#define INTTEXTBOX_H +#ifndef INTTEXTFIELD_H +#define INTTEXTFIELD_H #include "textfield.h" /** * TextBox which only accepts numbers as input. */ -class IntTextBox : public TextField +class IntTextField : public TextField { public: /** - * Constructor, sets initial value. + * Constructor, sets default value. */ - IntTextBox(int value=0); + IntTextField(int def = 0); /** * Sets the minimum and maximum values of the text box. @@ -43,22 +43,32 @@ class IntTextBox : public TextField /** * Returns the value in the text box. */ - int getInt(); + int getValue(); + + /** + * Reset the field to the default value. + */ + void reset(); /** * Set the value of the text box to the specified value. */ - void setInt(int value); + void setValue(int value); + + /** + * Set the default value of the text box to the specified value. + */ + void setDefaultValue(int value); /** * Responds to key presses. */ - void - keyPressed(gcn::KeyEvent &event); + void keyPressed(gcn::KeyEvent &event); private: int mMin; /**< Minimum value */ int mMax; /**< Maximum value */ + int mDefault; /**< Default value */ int mValue; /**< Current value */ }; diff --git a/src/gui/inventorywindow.cpp b/src/gui/inventorywindow.cpp index b4a96394..d18490a4 100644 --- a/src/gui/inventorywindow.cpp +++ b/src/gui/inventorywindow.cpp @@ -1,56 +1,57 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "inventorywindow.h" - #include <string> +#include <guichan/font.hpp> #include <guichan/mouseinput.hpp> #include <guichan/widgets/label.hpp> -#include <guichan/widgets/checkbox.hpp> -#include <guichan/widgets/textbox.hpp> #include "button.h" -#include "gui.h" +#include "inventorywindow.h" #include "item_amount.h" #include "itemcontainer.h" -#include "itempopup.h" +#include "progressbar.h" #include "scrollarea.h" #include "sdlinput.h" #include "viewport.h" #include "widgets/layout.h" +#include "../inventory.h" #include "../item.h" #include "../localplayer.h" #include "../log.h" +#include "../units.h" #include "../resources/iteminfo.h" #include "../utils/gettext.h" +#include "../utils/stringutils.h" #include "../utils/strprintf.h" -InventoryWindow::InventoryWindow(): +InventoryWindow::InventoryWindow(int invSize): Window(_("Inventory")), + mMaxSlots(invSize), mSplit(false), mItemDesc(false) { @@ -65,28 +66,67 @@ InventoryWindow::InventoryWindow(): setDefaultSize(115, 30, 375, 283); addKeyListener(this); - mUseButton = new Button(_("Use"), "use", this); + std::string longestUseString = getFont()->getWidth(_("Equip")) > + getFont()->getWidth(_("Use")) ? + _("Equip") : _("Use"); + + if (getFont()->getWidth(longestUseString) < + getFont()->getWidth(_("Unequip"))) + { + longestUseString = _("Unequip"); + } + + mUseButton = new Button(longestUseString, "use", this); mDropButton = new Button(_("Drop"), "drop", this); +#ifdef TMWSERV_SUPPORT mSplitButton = new Button(_("Split"), "split", this); +#endif - mItems = new ItemContainer(player_node->mInventory, 10, 5); +#ifdef TMWSERV_SUPPORT + mItems = new ItemContainer(player_node->getInventory(), 10, 5); +#else + mItems = new ItemContainer(player_node->getInventory(), 10, 5, 2); +#endif mItems->addSelectionListener(this); mInvenScroll = new ScrollArea(mItems); + mInvenScroll->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); + + mTotalWeight = -1; + mMaxWeight = -1; + mUsedSlots = toString(player_node->getInventory()->getNumberOfSlotsUsed()); + + mSlotsLabel = new gcn::Label(_("Slots: ")); + mWeightLabel = new gcn::Label(_("Weight: ")); + + mSlotsBar = new ProgressBar(1.0f, 100, 20, 225, 200, 25); + mWeightBar = new ProgressBar(1.0f, 100, 20, 0, 0, 255); + + setMinHeight(130); + setMinWidth(mWeightLabel->getWidth() + mSlotsLabel->getWidth() + 280); + + place(0, 0, mWeightLabel).setPadding(3); + place(1, 0, mWeightBar, 3); + place(4, 0, mSlotsLabel).setPadding(3); + place(5, 0, mSlotsBar, 2); + place(0, 1, mInvenScroll, 100).setPadding(3); + place(0, 2, mUseButton); + place(1, 2, mDropButton); +#ifdef TMWSERV_SUPPORT + place(2, 2, mSplitButton); +#endif - place(0, 0, mInvenScroll, 100).setPadding(3); - place(0, 1, mUseButton); - place(1, 1, mDropButton); - place(2, 1, mSplitButton); Layout &layout = getLayout(); - layout.setColWidth(0, 48); - layout.setColWidth(1, 48); - layout.setColWidth(2, 48); layout.setRowHeight(0, Layout::AUTO_SET); loadWindowState(); } +InventoryWindow::~InventoryWindow() +{ + delete mItems; +} + void InventoryWindow::logic() { Window::logic(); @@ -95,24 +135,69 @@ void InventoryWindow::logic() // redesign of InventoryWindow and ItemContainer probably. updateButtons(); - // Update weight information - // mWeightLabel->setCaption(strprintf(_("Total Weight: %d - Maximum Weight: %d"), player_node->getTotalWeight(), player_node->getMaxWeight())); + if (mMaxWeight != player_node->getMaxWeight() || + mTotalWeight != player_node->getTotalWeight() || + mUsedSlots != toString(player_node->getInventory()->getNumberOfSlotsUsed())) + { + mTotalWeight = player_node->getTotalWeight(); + mMaxWeight = player_node->getMaxWeight(); + mUsedSlots = toString(player_node->getInventory()->getNumberOfSlotsUsed()); + + // Weight Bar coloration + if (int(player_node->getTotalWeight()) < int(player_node->getMaxWeight() / 3)) + { + mWeightBar->setColor(0, 0, 255); // Blue + } + else if (int(player_node->getTotalWeight()) < + int((player_node->getMaxWeight() / 3) * 2)) + { + mWeightBar->setColor(255, 255, 0); // Yellow + } + else + { + mWeightBar->setColor(255, 0, 0); // Red + } + + // Adjust progress bars + mSlotsBar->setProgress((float) + player_node->getInventory()->getNumberOfSlotsUsed() / mMaxSlots); + mWeightBar->setProgress((float) player_node->getTotalWeight() / + player_node->getMaxWeight()); + + mSlotsBar->setText(strprintf("%s/%d", mUsedSlots.c_str(), mMaxSlots)); + mWeightBar->setText(strprintf("%s/%s", + Units::formatWeight(mTotalWeight).c_str(), + Units::formatWeight(mMaxWeight).c_str())); + } } void InventoryWindow::action(const gcn::ActionEvent &event) { - Item *item = mItems->getItem(); + Item *item = mItems->getSelectedItem(); + if (!item) return; if (event.getId() == "use") { +#ifdef TMWSERV_SUPPORT if (item->isEquipment()) { player_node->equipItem(item); } else { player_node->useItem(item->getInvIndex()); } +#else + if (item->isEquipment()) + { + if (item->isEquipped()) + player_node->unequipItem(item); + else + player_node->equipItem(item); + } + else + player_node->useItem(item); +#endif } else if (event.getId() == "drop") { @@ -134,18 +219,9 @@ void InventoryWindow::action(const gcn::ActionEvent &event) } } -void InventoryWindow::valueChanged(const gcn::SelectionEvent &event) +Item* InventoryWindow::getSelectedItem() const { - Item *item = mItems->getItem(); - - if (mSplit) - { - if (item && !item->isEquipment() && item->getQuantity() > 1) - { - mSplit = false; - new ItemAmountWindow(AMOUNT_ITEM_SPLIT, this, item, (item->getQuantity() - 1)); - } - } + return mItems->getSelectedItem(); } void InventoryWindow::mouseClicked(gcn::MouseEvent &event) @@ -154,7 +230,7 @@ void InventoryWindow::mouseClicked(gcn::MouseEvent &event) if (event.getButton() == gcn::MouseEvent::RIGHT) { - Item *item = mItems->getItem(); + Item *item = mItems->getSelectedItem(); if (!item) return; @@ -168,31 +244,7 @@ void InventoryWindow::mouseClicked(gcn::MouseEvent &event) } } -void InventoryWindow::updateButtons() -{ - Item *item = mItems->getItem(); - - if (item && item->isEquipment()) { - mUseButton->setCaption(_("Equip")); - } - else { - mUseButton->setCaption(_("Use")); - } - mUseButton->setEnabled(!!item); - mDropButton->setEnabled(!!item); - if (item && !item->isEquipment() && item->getQuantity() > 1) { - mSplitButton->setEnabled(true); - } - else { - mSplitButton->setEnabled(false); - } -} - -Item* InventoryWindow::getItem() -{ - return mItems->getItem(); -} - +#ifdef TMWSERV_SUPPORT void InventoryWindow::keyPressed(gcn::KeyEvent &event) { switch (event.getKey().getValue()) @@ -214,3 +266,49 @@ void InventoryWindow::keyReleased(gcn::KeyEvent &event) break; } } +#endif + +void InventoryWindow::valueChanged(const gcn::SelectionEvent &event) +{ + if (mSplit) + { + Item *item = mItems->getSelectedItem(); + + if (item && !item->isEquipment() && item->getQuantity() > 1) + { + mSplit = false; + new ItemAmountWindow(AMOUNT_ITEM_SPLIT, this, item, (item->getQuantity() - 1)); + } + } +} + +void InventoryWindow::updateButtons() +{ + const Item *selectedItem = mItems->getSelectedItem(); + + if (selectedItem && selectedItem->isEquipment()) + { +#ifdef EATHENA_SUPPORT + if (selectedItem->isEquipped()) + mUseButton->setCaption(_("Unequip")); + else +#endif + mUseButton->setCaption(_("Equip")); + } + else + mUseButton->setCaption(_("Use")); + + mUseButton->setEnabled(selectedItem != 0); + mDropButton->setEnabled(selectedItem != 0); + +#ifdef TMWSERV_SUPPORT + if (selectedItem && !selectedItem->isEquipment() && + selectedItem->getQuantity() > 1) + { + mSplitButton->setEnabled(true); + } + else { + mSplitButton->setEnabled(false); + } +#endif +} diff --git a/src/gui/inventorywindow.h b/src/gui/inventorywindow.h index 9d342c83..6a51c66d 100644 --- a/src/gui/inventorywindow.h +++ b/src/gui/inventorywindow.h @@ -1,38 +1,39 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TMW_INVENTORYWINDOW_H -#define _TMW_INVENTORYWINDOW_H +#ifndef INVENTORYWINDOW_H +#define INVENTORYWINDOW_H #include <guichan/actionlistener.hpp> -#include <guichan/keylistener.hpp> #include <guichan/selectionlistener.hpp> -#include <guichan/widgets/checkbox.hpp> +#include <guichan/keylistener.hpp> #include "window.h" -#include "../guichanfwd.h" +#include "../localplayer.h" class Item; class ItemContainer; +class ProgressBar; +class TextBox; /** * Inventory dialog. @@ -48,7 +49,16 @@ class InventoryWindow : public Window, /** * Constructor. */ - InventoryWindow(); +#ifdef TMWSERV_SUPPORT + InventoryWindow(int invSize = (INVENTORY_SIZE)); +#else + InventoryWindow(int invSize = (INVENTORY_SIZE - 2)); +#endif + + /** + * Destructor. + */ + ~InventoryWindow(); /** * Logic (updates buttons and weight information). @@ -61,10 +71,16 @@ class InventoryWindow : public Window, void action(const gcn::ActionEvent &event); /** + * Returns the selected item. + */ + Item* getSelectedItem() const; + + /** * Handles the mouse clicks. */ void mouseClicked(gcn::MouseEvent &event); +#ifdef TMWSERV_SUPPORT /** * Handles the key presses. */ @@ -74,8 +90,7 @@ class InventoryWindow : public Window, * Handles the key releases. */ void keyReleased(gcn::KeyEvent &event); - - Item* getItem(); +#endif /** * Updates labels to currently selected item. @@ -87,13 +102,25 @@ class InventoryWindow : public Window, ItemContainer *mItems; - /**< Use, Drop, Split Item Buttons. */ - gcn::Button *mUseButton, *mDropButton, *mSplitButton; - + std::string mWeight; + std::string mSlots; + std::string mUsedSlots; + int mTotalWeight, mMaxWeight; + gcn::Button *mUseButton; + gcn::Button *mDropButton; +#ifdef TMWSERV_SUPPORT + gcn::Button *mSplitButton; +#endif gcn::ScrollArea *mInvenScroll; /**< Inventory Scroll Area. */ + gcn::Label *mWeightLabel; + gcn::Label *mSlotsLabel; - bool mSplit; + ProgressBar *mWeightBar; + ProgressBar *mSlotsBar; + int mMaxSlots; + + bool mSplit; bool mItemDesc; }; diff --git a/src/gui/item_amount.cpp b/src/gui/item_amount.cpp index cae681d4..3bd388f4 100644 --- a/src/gui/item_amount.cpp +++ b/src/gui/item_amount.cpp @@ -1,28 +1,27 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "item_amount.h" - #include "button.h" -#include "inttextbox.h" +#include "inttextfield.h" +#include "item_amount.h" #include "slider.h" #include "trade.h" @@ -44,11 +43,11 @@ ItemAmountWindow::ItemAmountWindow(int usage, Window *parent, Item *item, } // Integer field - mItemAmountTextBox = new IntTextBox(1); - mItemAmountTextBox->setRange(1, maxRange); - mItemAmountTextBox->setWidth(30); - mItemAmountTextBox->setActionEventId("Dummy"); - mItemAmountTextBox->addActionListener(this); + mItemAmountTextField = new IntTextField(1); + mItemAmountTextField->setRange(1, maxRange); + mItemAmountTextField->setWidth(30); + mItemAmountTextField->setActionEventId("Dummy"); + mItemAmountTextField->addActionListener(this); // Slider mItemAmountSlide = new Slider(1.0, maxRange); @@ -66,7 +65,7 @@ ItemAmountWindow::ItemAmountWindow(int usage, Window *parent, Item *item, // Set positions place(0, 0, minusButton); - place(1, 0, mItemAmountTextBox).setPadding(2); + place(1, 0, mItemAmountTextField).setPadding(2); place(2, 0, plusButton); place(0, 1, mItemAmountSlide, 6); place(4, 2, okButton); @@ -75,7 +74,8 @@ ItemAmountWindow::ItemAmountWindow(int usage, Window *parent, Item *item, resetAmount(); - switch (usage) { + switch (usage) + { case AMOUNT_TRADE_ADD: setCaption(_("Select amount of items to trade.")); okButton->setActionEventId("AddTrade"); @@ -98,12 +98,12 @@ ItemAmountWindow::ItemAmountWindow(int usage, Window *parent, Item *item, void ItemAmountWindow::resetAmount() { - mItemAmountTextBox->setInt(1); + mItemAmountTextField->setValue(1); } void ItemAmountWindow::action(const gcn::ActionEvent &event) { - int amount = mItemAmountTextBox->getInt(); + int amount = mItemAmountTextField->getValue(); if (event.getId() == "Cancel") { @@ -123,19 +123,21 @@ void ItemAmountWindow::action(const gcn::ActionEvent &event) } else if (event.getId() == "Drop") { - player_node->dropItem(mItem, mItemAmountTextBox->getInt()); + player_node->dropItem(mItem, mItemAmountTextField->getValue()); scheduleDelete(); } else if (event.getId() == "AddTrade") { - tradeWindow->tradeItem(mItem, mItemAmountTextBox->getInt()); + tradeWindow->tradeItem(mItem, mItemAmountTextField->getValue()); scheduleDelete(); } +#ifdef TMWSERV_SUPPORT else if (event.getId() == "Split") { - player_node->splitItem(mItem, mItemAmountTextBox->getInt()); + player_node->splitItem(mItem, mItemAmountTextField->getValue()); scheduleDelete(); } - mItemAmountTextBox->setInt(amount); +#endif + mItemAmountTextField->setValue(amount); mItemAmountSlide->setValue(amount); } diff --git a/src/gui/item_amount.h b/src/gui/item_amount.h index c0d2b2c0..4fdb8dc6 100644 --- a/src/gui/item_amount.h +++ b/src/gui/item_amount.h @@ -1,36 +1,32 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TMW_ITEM_AMOUNT_WINDOW_H -#define _TMW_ITEM_AMOUNT_WINDOW_H - -#include <iosfwd> +#ifndef ITEM_AMOUNT_WINDOW_H +#define ITEM_AMOUNT_WINDOW_H #include <guichan/actionlistener.hpp> #include "window.h" -#include "../guichanfwd.h" - -class IntTextBox; +class IntTextField; class Item; #define AMOUNT_TRADE_ADD 1 @@ -61,7 +57,7 @@ class ItemAmountWindow : public Window, public gcn::ActionListener void resetAmount(); private: - IntTextBox *mItemAmountTextBox; /**< Item amount caption. */ + IntTextField *mItemAmountTextField; /**< Item amount caption. */ Item *mItem; /** @@ -70,4 +66,4 @@ class ItemAmountWindow : public Window, public gcn::ActionListener gcn::Slider *mItemAmountSlide; }; -#endif /* _TMW_ITEM_AMOUNT_WINDOW_H */ +#endif /* ITEM_AMOUNT_WINDOW_H */ diff --git a/src/gui/itemcontainer.cpp b/src/gui/itemcontainer.cpp index 4a90510c..bdae9ada 100644 --- a/src/gui/itemcontainer.cpp +++ b/src/gui/itemcontainer.cpp @@ -1,27 +1,29 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "itemcontainer.h" #include "chat.h" +#include "itempopup.h" + #include <guichan/mouseinput.hpp> #include <guichan/selectionlistener.hpp> @@ -32,12 +34,12 @@ #include "../item.h" #include "../itemshortcut.h" #include "../localplayer.h" +#include "../log.h" #include "../resources/image.h" -#include "../resources/iteminfo.h" #include "../resources/resourcemanager.h" -#include "../utils/tostring.h" +#include "../utils/stringutils.h" // TODO: Add support for adding items to the item shortcut window (global // itemShortcut). @@ -55,10 +57,13 @@ enum }; ItemContainer::ItemContainer(Inventory *inventory, - int gridColumns = 1, int gridRows = 1): + int gridColumns, + int gridRows, + int offset): mInventory(inventory), mGridColumns(gridColumns), mGridRows(gridRows), + mOffset(offset), mSelectedItem(NULL), mHighlightedItem(NULL), mSelectionStatus(SEL_NONE), @@ -71,17 +76,19 @@ ItemContainer::ItemContainer(Inventory *inventory, ResourceManager *resman = ResourceManager::getInstance(); mSelImg = resman->getImage("graphics/gui/selection.png"); + if (!mSelImg) logger->error("Unable to load selection.png"); addKeyListener(this); addMouseListener(this); setSize((BOX_WIDTH - 1) * mGridColumns + 1, - (BOX_HEIGHT - 1) * mGridRows + 1); + (BOX_HEIGHT - 1) * mGridRows + 1); } ItemContainer::~ItemContainer() { mSelImg->decRef(); + delete mItemPopup; } void ItemContainer::draw(gcn::Graphics *graphics) @@ -174,8 +181,7 @@ void ItemContainer::distributeValueChangedEvent() } } -void -ItemContainer::keyPressed(gcn::KeyEvent &event) +void ItemContainer::keyPressed(gcn::KeyEvent &event) { switch (event.getKey().getValue()) { @@ -204,8 +210,7 @@ ItemContainer::keyPressed(gcn::KeyEvent &event) } } -void -ItemContainer::keyReleased(gcn::KeyEvent &event) +void ItemContainer::keyReleased(gcn::KeyEvent &event) { switch (event.getKey().getValue()) { @@ -219,8 +224,7 @@ ItemContainer::keyReleased(gcn::KeyEvent &event) } } -void -ItemContainer::mousePressed(gcn::MouseEvent &event) +void ItemContainer::mousePressed(gcn::MouseEvent &event) { const int button = event.getButton(); if (button == gcn::MouseEvent::LEFT || button == gcn::MouseEvent::RIGHT) @@ -235,7 +239,7 @@ ItemContainer::mousePressed(gcn::MouseEvent &event) // put item name into chat window if (mDescItems) { - chatWindow->addItemText(item->getId(), item->getInfo().getName()); + chatWindow->addItemText(item->getInfo().getName()); } if (mSelectedItem && mSelectedItem == item) @@ -246,6 +250,8 @@ ItemContainer::mousePressed(gcn::MouseEvent &event) { setSelectedItem(item); mSelectionStatus = SEL_SELECTING; + + itemShortcut->setItemSelected(item->getId()); } else { @@ -255,8 +261,7 @@ ItemContainer::mousePressed(gcn::MouseEvent &event) } } -void -ItemContainer::mouseDragged(gcn::MouseEvent &event) +void ItemContainer::mouseDragged(gcn::MouseEvent &event) { if (mSelectionStatus != SEL_NONE) { @@ -297,15 +302,16 @@ void ItemContainer::mouseReleased(gcn::MouseEvent &event) // Show ItemTooltip void ItemContainer::mouseMoved(gcn::MouseEvent &event) { - Item *item = mInventory->getItem( getSlotIndex(event.getX(), event.getY() ) ); + Item *item = mInventory->getItem(getSlotIndex(event.getX(), event.getY())); - if( item ) + if (item) { - mItemPopup->setPosition(getParent()->getParent()->getX() + getParent()->getParent()->getWidth(), getParent()->getParent()->getY()); + int mouseX, mouseY; + SDL_GetMouseState(&mouseX, &mouseY); mItemPopup->setItem(item->getInfo()); - - mItemPopup->setVisible(true); + mItemPopup->setOpaque(false); + mItemPopup->view(mouseX, mouseY); } else { @@ -313,14 +319,6 @@ void ItemContainer::mouseMoved(gcn::MouseEvent &event) } } - -// Show ItemTooltip -void ItemContainer::mouseEntered(gcn::MouseEvent &event) -{ - -} - - // Hide ItemTooltip void ItemContainer::mouseExited(gcn::MouseEvent &event) { diff --git a/src/gui/itemcontainer.h b/src/gui/itemcontainer.h index 7636ef0c..38eaba01 100644 --- a/src/gui/itemcontainer.h +++ b/src/gui/itemcontainer.h @@ -1,39 +1,37 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TMW_ITEMCONTAINER_H__ -#define _TMW_ITEMCONTAINER_H__ +#ifndef ITEMCONTAINER_H +#define ITEMCONTAINER_H + +#include <list> #include <guichan/keylistener.hpp> #include <guichan/mouselistener.hpp> - #include <guichan/widget.hpp> -#include "itempopup.h" - -#include <list> - class Image; class Inventory; class Item; +class ItemPopup; namespace gcn { class SelectionListener; @@ -53,9 +51,11 @@ class ItemContainer : public gcn::Widget, * Constructor. Initializes the graphic. * @param inventory * @param gridColumns Amount of columns in grid. - * @param gridRows Amount of rows in grid. + * @param gridRows Amount of rows in grid. + * @param offset Index offset */ - ItemContainer(Inventory *inventory, int gridColumns, int gridRows); + ItemContainer(Inventory *inventory, int gridColumns, int gridRows, + int offset = 0); /** * Destructor. @@ -95,7 +95,7 @@ class ItemContainer : public gcn::Widget, /** * Returns the selected item. */ - Item* getItem() const + Item* getSelectedItem() const { return mSelectedItem; } /** @@ -133,7 +133,6 @@ class ItemContainer : public gcn::Widget, */ void keyAction(); - void mouseEntered(gcn::MouseEvent &event); void mouseExited(gcn::MouseEvent &event); void mouseMoved(gcn::MouseEvent &event); @@ -150,6 +149,16 @@ class ItemContainer : public gcn::Widget, void setSelectedItem(Item *item); /** + * Find the current item index by the most recently used item ID + */ + void refindSelectedItem(); + + /** + * Determine and set the height of the container. + */ + void recalculateHeight(); + + /** * Sends out selection events to the list of selection listeners. */ void distributeValueChangedEvent(); @@ -161,10 +170,11 @@ class ItemContainer : public gcn::Widget, * @param posY The Y Coordinate position. * @return The slot index on success, -1 on failure. */ - int getSlotIndex(const int posX, const int posY) const; + int getSlotIndex(int posX, int posY) const; Inventory *mInventory; int mGridColumns, mGridRows; + int mOffset; Image *mSelImg; Item *mSelectedItem, *mHighlightedItem; int mSelectionStatus; diff --git a/src/gui/itemlinkhandler.cpp b/src/gui/itemlinkhandler.cpp index bdfa2ca6..4060b303 100644 --- a/src/gui/itemlinkhandler.cpp +++ b/src/gui/itemlinkhandler.cpp @@ -1,33 +1,35 @@ /* * The Mana World - * Copyright 2009 The Mana World Development Team + * Copyright (C) 2009 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include <sstream> +#include <string> + +#include <SDL_mouse.h> + #include "itemlinkhandler.h" #include "itempopup.h" #include "../resources/iteminfo.h" #include "../resources/itemdb.h" -#include <sstream> -#include <string> - ItemLinkHandler::ItemLinkHandler() { mItemPopup = new ItemPopup; @@ -47,14 +49,15 @@ void ItemLinkHandler::handleLink(const std::string &link) if (id > 0) { const ItemInfo &iteminfo = ItemDB::get(id); + int mouseX, mouseY; + + SDL_GetMouseState(&mouseX, &mouseY); + mItemPopup->setItem(iteminfo); + if (mItemPopup->isVisible()) - { mItemPopup->setVisible(false); - } else - { - mItemPopup->setVisible(true); - } + mItemPopup->view(mouseX, mouseY); } } diff --git a/src/gui/itemlinkhandler.h b/src/gui/itemlinkhandler.h index 973aab75..c04afa9e 100644 --- a/src/gui/itemlinkhandler.h +++ b/src/gui/itemlinkhandler.h @@ -1,26 +1,26 @@ /* * The Mana World - * Copyright 2009 The Mana World Development Team + * Copyright (C) 2009 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TMW_ITEM_LINK_HANDLER_H_ -#define _TMW_ITEM_LINK_HANDLER_H_ +#ifndef ITEM_LINK_HANDLER_H +#define ITEM_LINK_HANDLER_H #include "linkhandler.h" diff --git a/src/gui/itempopup.cpp b/src/gui/itempopup.cpp index 7a662151..25e6e78e 100644 --- a/src/gui/itempopup.cpp +++ b/src/gui/itempopup.cpp @@ -5,107 +5,216 @@ * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "itempopup.h" +#include <guichan/font.hpp> + #include <guichan/widgets/label.hpp> -#include "widgets/layout.h" #include "gui.h" +#include "itempopup.h" +#include "scrollarea.h" +#include "textbox.h" +#include "windowcontainer.h" + +#include "widgets/layout.h" + +#include "../units.h" -#include "../resources/image.h" -#include "../resources/resourcemanager.h" #include "../resources/iteminfo.h" -#include "../utils/gettext.h" -#include "../utils/strprintf.h" +#include "../utils/gettext.h" +#include "../utils/stringutils.h" -ItemPopup::ItemPopup() +ItemPopup::ItemPopup(): + Window() { - setResizable(false); + setShowTitle(false); setTitleBarHeight(0); - loadSkin("graphics/gui/gui.xml"); // Item Name mItemName = new gcn::Label("Label"); - mItemName->setFont(gui->getFont()); + mItemName->setFont(boldFont); mItemName->setPosition(2, 2); - mItemName->setWidth(getWidth() - 4); // Item Description - mItemDesc = new TextBox(); + mItemDesc = new TextBox; mItemDesc->setEditable(false); mItemDescScroll = new ScrollArea(mItemDesc); mItemDescScroll->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); mItemDescScroll->setVerticalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); - mItemDescScroll->setDimension(gcn::Rectangle(0, 0, 196, 14)); + mItemDescScroll->setDimension(gcn::Rectangle(0, 0, 196, getFont()->getHeight())); mItemDescScroll->setOpaque(false); - mItemDescScroll->setPosition(2, 15); + mItemDescScroll->setPosition(2, getFont()->getHeight()); // Item Effect - mItemEffect = new TextBox(); + mItemEffect = new TextBox; mItemEffect->setEditable(false); mItemEffectScroll = new ScrollArea(mItemEffect); mItemEffectScroll->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); mItemEffectScroll->setVerticalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); - mItemEffectScroll->setDimension(gcn::Rectangle(0, 0, 196, 14)); + mItemEffectScroll->setDimension(gcn::Rectangle(0, 0, 196, getFont()->getHeight())); mItemEffectScroll->setOpaque(false); - mItemEffectScroll->setPosition(2, 35); + mItemEffectScroll->setPosition(2, (2 * getFont()->getHeight()) + 5); + + // Item Weight + mItemWeight = new TextBox; + mItemWeight->setEditable(false); + mItemWeightScroll = new ScrollArea(mItemWeight); + + mItemWeightScroll->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); + mItemWeightScroll->setVerticalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); + mItemWeightScroll->setDimension(gcn::Rectangle(0, 0, 196, getFont()->getHeight())); + mItemWeightScroll->setOpaque(false); + mItemWeightScroll->setPosition(2, (3 * getFont()->getHeight()) + 10); add(mItemName); add(mItemDescScroll); add(mItemEffectScroll); + add(mItemWeightScroll); setLocationRelativeTo(getParent()); +} - // LEEOR / TODO: This causes an exception error. - //moveToBottom(getParent()); - - mItemDesc->setTextWrapped( "" ); - mItemEffect->setTextWrapped( "" ); +ItemPopup::~ItemPopup() +{ + delete mItemName; + delete mItemDesc; + delete mItemDescScroll; + delete mItemEffect; + delete mItemEffectScroll; + delete mItemWeight; + delete mItemWeightScroll; } void ItemPopup::setItem(const ItemInfo &item) { mItemName->setCaption(item.getName()); - mItemDesc->setTextWrapped(item.getDescription()); - mItemEffect->setTextWrapped(item.getEffect()); +#ifdef EATHENA_SUPPORT + mItemName->setForegroundColor(getColor(item.getType())); +#endif + mItemName->setWidth(boldFont->getWidth(item.getName())); + mItemDesc->setTextWrapped(item.getDescription(), 196); + mItemEffect->setTextWrapped(item.getEffect(), 196); + mItemWeight->setTextWrapped(_("Weight: ") + + Units::formatWeight(item.getWeight()), 196); + + int minWidth = mItemName->getWidth(); + + if (mItemDesc->getMinWidth() > minWidth) + minWidth = mItemDesc->getMinWidth(); + if (mItemEffect->getMinWidth() > minWidth) + minWidth = mItemEffect->getMinWidth(); + if (mItemWeight->getMinWidth() > minWidth) + minWidth = mItemWeight->getMinWidth(); + + minWidth += 8; + setWidth(minWidth); int numRowsDesc = mItemDesc->getNumberOfRows(); int numRowsEffect = mItemEffect->getNumberOfRows(); + int numRowsWeight = mItemWeight->getNumberOfRows(); - if(item.getEffect() == "") - { - setContentSize(200, (numRowsDesc * 14) + 30); - } else { - setContentSize(200, (numRowsDesc * 14) + (numRowsEffect*14) + 30); - } + mItemDescScroll->setDimension(gcn::Rectangle(2, 0, minWidth, + numRowsDesc * getFont()->getHeight())); - mItemDescScroll->setDimension(gcn::Rectangle(2, 0, 196, numRowsDesc * 14)); + mItemEffectScroll->setDimension(gcn::Rectangle(2, 0, minWidth, + numRowsEffect * getFont()->getHeight())); - mItemEffectScroll->setDimension(gcn::Rectangle(2, 0, 196, numRowsEffect * 14)); + mItemWeightScroll->setDimension(gcn::Rectangle(2, 0, minWidth, + numRowsWeight * getFont()->getHeight())); + + if (item.getEffect().empty()) + { + setContentSize(minWidth, (numRowsDesc * getFont()->getHeight() + + (3 * getFont()->getHeight()))); + + mItemWeightScroll->setPosition(2, + (numRowsDesc * getFont()->getHeight()) + + (2 * getFont()->getHeight())); + } + else + { + setContentSize(minWidth, (numRowsDesc * getFont()->getHeight()) + + (numRowsEffect * getFont()->getHeight()) + + (3 * getFont()->getHeight())); + + mItemWeightScroll->setPosition(2, + (numRowsDesc * getFont()->getHeight()) + + (numRowsEffect * getFont()->getHeight()) + + (2 * getFont()->getHeight())); + } mItemDescScroll->setPosition(2, 20); - mItemEffectScroll->setPosition(2, (numRowsDesc * 15) + 25); + mItemEffectScroll->setPosition(2, (numRowsDesc * getFont()->getHeight()) + + (2 * getFont()->getHeight())); +} + +gcn::Color ItemPopup::getColor(const std::string& type) +{ + gcn::Color color; + + if (type.compare("generic") == 0) + color = 0x21a5b1; + else if (type.compare("equip-head") == 0) + color = 0x527fa4; + else if (type.compare("usable") == 0) + color = 0x268d24; + else if (type.compare("equip-torso") == 0) + color = 0xd12aa4; + else if (type.compare("equip-1hand") == 0) + color = 0xf42a2a; + else if (type.compare("equip-legs") == 0) + color = 0x699900; + else if (type.compare("equip-feet") == 0) + color = 0xaa1d48; + else if (type.compare("equip-2hand") == 0) + color = 0xf46d0e; + else if (type.compare("equip-shield") == 0) + color = 0x9c2424; + else if (type.compare("equip-ring") == 0) + color = 0x0000ff; + else if (type.compare("equip-arms") == 0) + color = 0x9c24e8; + else if (type.compare("equip-ammo") == 0) + color = 0x8b6311; + else + color = 0x000000; + + return color; } unsigned int ItemPopup::getNumRows() { - return mItemDesc->getNumberOfRows(), mItemEffect->getNumberOfRows(); + return mItemDesc->getNumberOfRows() + mItemEffect->getNumberOfRows() + + mItemWeight->getNumberOfRows(); +} + +void ItemPopup::view(int x, int y) +{ + if (windowContainer->getWidth() < (x + getWidth() + 5)) + x = windowContainer->getWidth() - getWidth(); + if ((y - getHeight() - 10) < 0) + y = 0; + else + y = y - getHeight() - 10; + setPosition(x, y); + setVisible(true); + requestMoveToTop(); } diff --git a/src/gui/itempopup.h b/src/gui/itempopup.h index 8da0b32a..c820e3a0 100644 --- a/src/gui/itempopup.h +++ b/src/gui/itempopup.h @@ -5,44 +5,50 @@ * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TMW_ITEMPOPUP_H__ -#define _TMW_ITEMPOPUP_H__ +#ifndef ITEMPOPUP_H +#define ITEMPOPUP_H -#include "textbox.h" -#include "scrollarea.h" #include "window.h" -#include "../item.h" +class ItemInfo; +class ScrollArea; +class TextBox; class ItemPopup : public Window { public: ItemPopup(); + ~ItemPopup(); void setItem(const ItemInfo &item); unsigned int getNumRows(); + void view(int x, int y); private: gcn::Label *mItemName; TextBox *mItemDesc; TextBox *mItemEffect; + TextBox *mItemWeight; ScrollArea *mItemDescScroll; ScrollArea *mItemEffectScroll; + ScrollArea *mItemWeightScroll; + + gcn::Color getColor(const std::string& type); }; -#endif // _TMW_ITEMPOPUP_H__ +#endif // ITEMPOPUP_H diff --git a/src/gui/itemshortcutcontainer.cpp b/src/gui/itemshortcutcontainer.cpp index e0604c78..8864cbd9 100644 --- a/src/gui/itemshortcutcontainer.cpp +++ b/src/gui/itemshortcutcontainer.cpp @@ -1,62 +1,70 @@ /* * The Mana World - * Copyright 2007 The Mana World Development Team + * Copyright (C) 2007 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include <SDL_mouse.h> #include "itemshortcutcontainer.h" +#include "itempopup.h" +#include "viewport.h" -#include "../localplayer.h" +#include "../configuration.h" #include "../graphics.h" +#include "../inventory.h" #include "../item.h" #include "../itemshortcut.h" #include "../keyboardconfig.h" +#include "../localplayer.h" #include "../resources/image.h" #include "../resources/resourcemanager.h" -#include "../utils/tostring.h" +#include "../utils/stringutils.h" ItemShortcutContainer::ItemShortcutContainer(): - mGridWidth(1), - mGridHeight(1), + ShortcutContainer(), mItemClicked(false), mItemMoved(NULL) { addMouseListener(this); addWidgetListener(this); + mItemPopup = new ItemPopup; + ResourceManager *resman = ResourceManager::getInstance(); mBackgroundImg = resman->getImage("graphics/gui/item_shortcut_bgr.png"); mMaxItems = itemShortcut->getItemCount(); - mBoxHeight = 42; - mBoxWidth = 36; + mBackgroundImg->setAlpha(config.getValue("guialpha", 0.8)); + + mBoxHeight = mBackgroundImg->getHeight(); + mBoxWidth = mBackgroundImg->getWidth(); } ItemShortcutContainer::~ItemShortcutContainer() { mBackgroundImg->decRef(); + delete mItemPopup; } -void -ItemShortcutContainer::logic() +void ItemShortcutContainer::logic() { gcn::Widget::logic(); @@ -69,11 +77,11 @@ ItemShortcutContainer::logic() } } -void -ItemShortcutContainer::draw(gcn::Graphics *graphics) +void ItemShortcutContainer::draw(gcn::Graphics *graphics) { Graphics *g = static_cast<Graphics*>(graphics); + graphics->setColor(gcn::Color(0, 0, 0)); graphics->setFont(getFont()); for (int i = 0; i < mMaxItems; i++) @@ -85,19 +93,27 @@ ItemShortcutContainer::draw(gcn::Graphics *graphics) // Draw item keyboard shortcut. const char *key = SDL_GetKeyName( - (SDLKey) keyboard.getKeyValue(keyboard.KEY_SHORTCUT_0 + i)); + (SDLKey) keyboard.getKeyValue(keyboard.KEY_SHORTCUT_1 + i)); + graphics->setColor(0x000000); g->drawText(key, itemX + 2, itemY + 2, gcn::Graphics::LEFT); if (itemShortcut->getItem(i) < 0) continue; - Item *item = player_node->searchForItem(itemShortcut->getItem(i)); - if (item) { + Item *item = + player_node->getInventory()->findItem(itemShortcut->getItem(i)); + if (item) + { // Draw item icon. Image* image = item->getImage(); - if (image) { - // TODO: Have label indicate equipped status - const std::string label = toString(item->getQuantity()); + + if (image) + { + const std::string label = +#ifdef EATHENA_SUPPORT + item->isEquipped() ? "Eq." : +#endif + toString(item->getQuantity()); g->drawImage(image, itemX, itemY); g->drawText( label, @@ -124,36 +140,30 @@ ItemShortcutContainer::draw(gcn::Graphics *graphics) gcn::Graphics::CENTER); } } -} - -void ItemShortcutContainer::widgetResized(const gcn::Event &event) -{ - mGridWidth = getWidth() / mBoxWidth; - if (mGridWidth < 1) { - mGridWidth = 1; - } - - setHeight((mMaxItems / mGridWidth + - (mMaxItems % mGridWidth > 0 ? 1 : 0)) * mBoxHeight); - mGridHeight = getHeight() / mBoxHeight; - if (mGridHeight < 1) { - mGridHeight = 1; + if (config.getValue("guialpha", 0.8) != mAlpha) + { + mBackgroundImg->setAlpha(config.getValue("guialpha", 0.8)); } } -void -ItemShortcutContainer::mouseDragged(gcn::MouseEvent &event) +void ItemShortcutContainer::mouseDragged(gcn::MouseEvent &event) { - if (event.getButton() == gcn::MouseEvent::LEFT) { - if (!mItemMoved && mItemClicked) { + if (event.getButton() == gcn::MouseEvent::LEFT) + { + if (!mItemMoved && mItemClicked) + { const int index = getIndexFromGrid(event.getX(), event.getY()); - if (index == -1) { + const int itemId = itemShortcut->getItem(index); + + if (index == -1) return; - } - if (itemShortcut->getItem(index) < 0) + + if (itemId < 0) return; - Item *item = player_node->searchForItem(itemShortcut->getItem(index)); + + Item *item = player_node->getInventory()->findItem(itemId); + if (item) { mItemMoved = item; @@ -167,39 +177,56 @@ ItemShortcutContainer::mouseDragged(gcn::MouseEvent &event) } } -void -ItemShortcutContainer::mousePressed(gcn::MouseEvent &event) +void ItemShortcutContainer::mousePressed(gcn::MouseEvent &event) { const int index = getIndexFromGrid(event.getX(), event.getY()); - if (index == -1) { + if (index == -1) return; - } - // Stores the selected item if theirs one. - if (itemShortcut->isItemSelected()) { - itemShortcut->setItem(index); - itemShortcut->setItemSelected(-1); + if (event.getButton() == gcn::MouseEvent::LEFT) + { + + // Stores the selected item if theirs one. + if (itemShortcut->isItemSelected()) + { + itemShortcut->setItem(index); + itemShortcut->setItemSelected(-1); + } + else if (itemShortcut->getItem(index)) + mItemClicked = true; } - else if (itemShortcut->getItem(index)) { - mItemClicked = true; + else if (event.getButton() == gcn::MouseEvent::RIGHT) + { + Item *item = player_node->getInventory()-> + findItem(itemShortcut->getItem(index)); + + if (!item) + return; + + /* Convert relative to the window coordinates to absolute screen + * coordinates. + */ + int mx, my; + SDL_GetMouseState(&mx, &my); + viewport->showPopup(mx, my, item); } } -void -ItemShortcutContainer::mouseReleased(gcn::MouseEvent &event) +void ItemShortcutContainer::mouseReleased(gcn::MouseEvent &event) { if (event.getButton() == gcn::MouseEvent::LEFT) { if (itemShortcut->isItemSelected()) - { itemShortcut->setItemSelected(-1); - } + const int index = getIndexFromGrid(event.getX(), event.getY()); - if (index == -1) { + if (index == -1) + { mItemMoved = NULL; return; } - if (mItemMoved) { + if (mItemMoved) + { itemShortcut->setItems(index, mItemMoved->getId()); mItemMoved = NULL; } @@ -207,25 +234,43 @@ ItemShortcutContainer::mouseReleased(gcn::MouseEvent &event) { itemShortcut->useItem(index); } - if (mItemClicked) { + if (mItemClicked) mItemClicked = false; - } } } -int -ItemShortcutContainer::getIndexFromGrid(int pointX, int pointY) const +// Show ItemTooltip +void ItemShortcutContainer::mouseMoved(gcn::MouseEvent &event) { - const gcn::Rectangle tRect = gcn::Rectangle( - 0, 0, mGridWidth * mBoxWidth, mGridHeight * mBoxHeight); - if (!tRect.isPointInRect(pointX, pointY)) { - return -1; + const int index = getIndexFromGrid(event.getX(), event.getY()); + const int itemId = itemShortcut->getItem(index); + + if (index == -1) + return; + + if (itemId < 0) + return; + + Item *item = player_node->getInventory()->findItem(itemId); + + if (item) + { + int mouseX, mouseY; + SDL_GetMouseState(&mouseX, &mouseY); + + mItemPopup->setItem(item->getInfo()); + mItemPopup->setOpaque(false); + mItemPopup->view(mouseX, mouseY); } - const int index = ((pointY / mBoxHeight) * mGridWidth) + - pointX / mBoxWidth; - if (index >= mMaxItems) + else { - return -1; + mItemPopup->setVisible(false); } - return index; } + +// Hide ItemTooltip +void ItemShortcutContainer::mouseExited(gcn::MouseEvent &event) +{ + mItemPopup->setVisible(false); +} + diff --git a/src/gui/itemshortcutcontainer.h b/src/gui/itemshortcutcontainer.h index 76ca870c..22d94ec2 100644 --- a/src/gui/itemshortcutcontainer.h +++ b/src/gui/itemshortcutcontainer.h @@ -1,42 +1,41 @@ /* * The Mana World - * Copyright 2007 The Mana World Development Team + * Copyright (C) 2007 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TMW_ITEMSHORTCUTCONTAINER_H__ -#define _TMW_ITEMSHORTCUTCONTAINER_H__ +#ifndef ITEMSHORTCUTCONTAINER_H +#define ITEMSHORTCUTCONTAINER_H #include <guichan/mouselistener.hpp> -#include <guichan/widget.hpp> -#include <guichan/widgetlistener.hpp> + +#include "shortcutcontainer.h" class Image; class Item; +class ItemPopup; /** * An item shortcut container. Used to quickly use items. * * \ingroup GUI */ -class ItemShortcutContainer : public gcn::Widget, - public gcn::WidgetListener, - public gcn::MouseListener +class ItemShortcutContainer : public ShortcutContainer { public: /** @@ -60,12 +59,6 @@ class ItemShortcutContainer : public gcn::Widget, void draw(gcn::Graphics *graphics); /** - * Invoked when a widget changes its size. This is used to determine - * the new height of the container. - */ - void widgetResized(const gcn::Event &event); - - /** * Handles mouse when dragged. */ void mouseDragged(gcn::MouseEvent &event); @@ -80,34 +73,14 @@ class ItemShortcutContainer : public gcn::Widget, */ void mouseReleased(gcn::MouseEvent &event); - int getMaxItems() - { return mMaxItems; } - - int getBoxWidth() - { return mBoxWidth; } - - int getBoxHeight() - { return mBoxHeight; } - private: - /** - * Gets the index from the grid provided the point is in an item box. - * - * @param pointX X coordinate of the point. - * @param pointY Y coordinate of the point. - * @return index on success, -1 on failure. - */ - int getIndexFromGrid(int pointX, int pointY) const; + void mouseExited(gcn::MouseEvent &event); + void mouseMoved(gcn::MouseEvent &event); - Image *mBackgroundImg; - - int mMaxItems; - int mBoxWidth; - int mBoxHeight; - int mCursorPosX, mCursorPosY; - int mGridWidth, mGridHeight; bool mItemClicked; Item *mItemMoved; + + ItemPopup *mItemPopup; }; #endif diff --git a/src/gui/linkhandler.h b/src/gui/linkhandler.h index 44f906db..fc9da6da 100644 --- a/src/gui/linkhandler.h +++ b/src/gui/linkhandler.h @@ -1,26 +1,28 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TMW_LINK_HANDLER_H_ -#define _TMW_LINK_HANDLER_H_ +#ifndef LINK_HANDLER_H +#define LINK_HANDLER_H + +#include <string> #include <string> diff --git a/src/gui/listbox.cpp b/src/gui/listbox.cpp index 204d7961..74d0b9ad 100644 --- a/src/gui/listbox.cpp +++ b/src/gui/listbox.cpp @@ -1,70 +1,74 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "listbox.h" - #include <guichan/font.hpp> #include <guichan/graphics.hpp> #include <guichan/listmodel.hpp> -#include <guichan/mouseinput.hpp> + +#include "color.h" +#include "listbox.h" + +#include "../configuration.h" + +float ListBox::mAlpha = config.getValue("guialpha", 0.8); ListBox::ListBox(gcn::ListModel *listModel): gcn::ListBox(listModel) { } -ListBox::ListBox(): - gcn::ListBox() -{ - -} - void ListBox::draw(gcn::Graphics *graphics) { if (!mListModel) return; - graphics->setColor(gcn::Color(110, 160, 255)); + if (config.getValue("guialpha", 0.8) != mAlpha) + mAlpha = config.getValue("guialpha", 0.8); + + bool valid; + const int red = (textColor->getColor('H', valid) >> 16) & 0xFF; + const int green = (textColor->getColor('H', valid) >> 8) & 0xFF; + const int blue = textColor->getColor('H', valid) & 0xFF; + const int alpha = (int)(mAlpha * 255.0f); + + graphics->setColor(gcn::Color(red, green, blue, alpha)); graphics->setFont(getFont()); - int fontHeight = getFont()->getHeight(); + const int fontHeight = getFont()->getHeight(); // Draw rectangle below the selected list element - if (mSelected >= 0) { + if (mSelected >= 0) graphics->fillRectangle(gcn::Rectangle(0, fontHeight * mSelected, getWidth(), fontHeight)); - } // Draw the list elements - graphics->setColor(gcn::Color(0, 0, 0)); - for (int i = 0, y = 0; - i < mListModel->getNumberOfElements(); + graphics->setColor(gcn::Color(0, 0, 0, 255)); + for (int i = 0, y = 0; i < mListModel->getNumberOfElements(); ++i, y += fontHeight) { graphics->drawText(mListModel->getElementAt(i), 1, y); } } -void -ListBox::mouseDragged(gcn::MouseEvent &event) +void ListBox::mouseDragged(gcn::MouseEvent &event) { // Pretend mouse is pressed continuously while dragged. Causes list // selection to be updated as is default in many GUIs. diff --git a/src/gui/listbox.h b/src/gui/listbox.h index d42c7d3e..12fcb955 100644 --- a/src/gui/listbox.h +++ b/src/gui/listbox.h @@ -1,26 +1,26 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TMW_LISTBOX_H -#define _TMW_LISTBOX_H +#ifndef LISTBOX_H +#define LISTBOX_H #include <guichan/widgets/listbox.hpp> @@ -40,7 +40,6 @@ class ListBox : public gcn::ListBox * Constructor. */ ListBox(gcn::ListModel *listModel); - ListBox(); /** * Draws the list box. @@ -48,6 +47,9 @@ class ListBox : public gcn::ListBox void draw(gcn::Graphics *graphics); void mouseDragged(gcn::MouseEvent &event); + + private: + static float mAlpha; }; #endif diff --git a/src/gui/login.cpp b/src/gui/login.cpp index 615045b6..e68a8da1 100644 --- a/src/gui/login.cpp +++ b/src/gui/login.cpp @@ -1,72 +1,127 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "login.h" - -#include <string> - #include <guichan/widgets/label.hpp> -#include "../main.h" -#include "../logindata.h" - #include "button.h" #include "checkbox.h" +#include "listbox.h" +#include "login.h" #include "ok_dialog.h" #include "passwordfield.h" +#include "scrollarea.h" #include "textfield.h" +#include "widgets/dropdown.h" #include "widgets/layout.h" +#include "../main.h" +#include "../logindata.h" +#include "../configuration.h" + #include "../utils/gettext.h" +#include "../utils/stringutils.h" + +static const int MAX_SERVER_LIST_SIZE = 5; +static const int LOGIN_DIALOG_WIDTH = 220; +static const int LOGIN_DIALOG_HEIGHT = 140; +static const int FIELD_WIDTH = LOGIN_DIALOG_WIDTH - 70; LoginDialog::LoginDialog(LoginData *loginData): Window(_("Login")), mLoginData(loginData) { gcn::Label *userLabel = new gcn::Label(_("Name:")); gcn::Label *passLabel = new gcn::Label(_("Password:")); +#ifdef EATHENA_SUPPORT + gcn::Label *serverLabel = new gcn::Label(_("Server:")); + gcn::Label *portLabel = new gcn::Label(_("Port:")); + gcn::Label *dropdownLabel = new gcn::Label(_("Recent:")); + std::vector<std::string> dfltServer; + dfltServer.push_back("server.themanaworld.org"); + std::vector<std::string> dfltPort; + dfltPort.push_back("6901"); + mServerList = new DropDownList("MostRecent00", dfltServer, dfltPort, + MAX_SERVER_LIST_SIZE); + mServerListBox = new ListBox(mServerList); + mServerScrollArea = new ScrollArea; +#endif + mUserField = new TextField(mLoginData->username); mPassField = new PasswordField(mLoginData->password); +#ifdef EATHENA_SUPPORT + mServerField = new TextField(mServerList->getServerAt(0)); + mPortField = new TextField(mServerList->getPortAt(0)); + mServerDropDown = new DropDown(mServerList, + mServerScrollArea, + mServerListBox); + mServerDropDown->setOpaque(false); +#endif + mKeepCheck = new CheckBox(_("Remember Username"), mLoginData->remember); - mOkButton = new Button(_("Ok"), "ok", this); + mOkButton = new Button(_("OK"), "ok", this); mCancelButton = new Button(_("Cancel"), "cancel", this); mRegisterButton = new Button(_("Register"), "register", this); mUserField->setActionEventId("ok"); mPassField->setActionEventId("ok"); +#ifdef EATHENA_SUPPORT + mServerField->setActionEventId("ok"); + mPortField->setActionEventId("ok"); + mServerDropDown->setActionEventId("changeSelection"); +#endif mUserField->addKeyListener(this); mPassField->addKeyListener(this); +#ifdef EATHENA_SUPPORT + mServerField->addKeyListener(this); + mPortField->addKeyListener(this); + mServerDropDown->addKeyListener(this); +#endif mUserField->addActionListener(this); mPassField->addActionListener(this); +#ifdef EATHENA_SUPPORT + mServerField->addActionListener(this); + mPortField->addActionListener(this); + mServerDropDown->addActionListener(this); mKeepCheck->addActionListener(this); +#endif place(0, 0, userLabel); place(0, 1, passLabel); - place(1, 0, mUserField, 3).setPadding(2); - place(1, 1, mPassField, 3).setPadding(2); - place(0, 2, mKeepCheck, 4); - place(0, 3, mRegisterButton).setHAlign(LayoutCell::LEFT); - place(2, 3, mOkButton); - place(3, 3, mCancelButton); +#ifdef EATHENA_SUPPORT + place(0, 2, serverLabel); + place(0, 3, portLabel); + place(0, 4, dropdownLabel); +#endif + place(1, 0, mUserField, 3).setPadding(1); + place(1, 1, mPassField, 3).setPadding(1); +#ifdef EATHENA_SUPPORT + place(1, 2, mServerField, 3).setPadding(1); + place(1, 3, mPortField, 3).setPadding(1); + place(1, 4, mServerDropDown, 3).setPadding(1); +#endif + place(0, 5, mKeepCheck, 4); + place(0, 6, mRegisterButton).setHAlign(LayoutCell::LEFT); + place(2, 6, mCancelButton); + place(3, 6, mOkButton); reflowLayout(250, 0); setLocationRelativeTo(getParent()); @@ -81,14 +136,14 @@ LoginDialog::LoginDialog(LoginData *loginData): mOkButton->setEnabled(canSubmit()); } -LoginDialog::~LoginDialog() -{ -} - void LoginDialog::action(const gcn::ActionEvent &event) { if (event.getId() == "ok" && canSubmit()) { +#ifdef EATHENA_SUPPORT + mLoginData->hostname = mServerField->getText(); + mLoginData->port = getUShort(mPortField->getText()); +#endif mLoginData->username = mUserField->getText(); mLoginData->password = mPassField->getText(); mLoginData->remember = mKeepCheck->isSelected(); @@ -96,16 +151,43 @@ void LoginDialog::action(const gcn::ActionEvent &event) mOkButton->setEnabled(false); mRegisterButton->setEnabled(false); - +#ifdef EATHENA_SUPPORT + mServerList->save(mServerField->getText(), mPortField->getText()); + state = STATE_ACCOUNT; +#else state = STATE_LOGIN_ATTEMPT; +#endif } +#ifdef EATHENA_SUPPORT + else if (event.getId() == "changeSelection") + { + int selected = mServerListBox->getSelected(); + mServerField->setText(mServerList->getServerAt(selected)); + mPortField->setText(mServerList->getPortAt(selected)); + } +#endif else if (event.getId() == "cancel") { +#ifdef TMWSERV_SUPPORT state = STATE_SWITCH_ACCOUNTSERVER; +#else + state = STATE_EXIT; +#endif } else if (event.getId() == "register") { +#ifdef EATHENA_SUPPORT // Transfer these fields on to the register dialog + mLoginData->hostname = mServerField->getText(); + if (isUShort(mPortField->getText())) + { + mLoginData->port = getUShort(mPortField->getText()); + } + else + { + mLoginData->port = 6901; + } +#endif mLoginData->username = mUserField->getText(); mLoginData->password = mPassField->getText(); @@ -122,5 +204,143 @@ bool LoginDialog::canSubmit() { return !mUserField->getText().empty() && !mPassField->getText().empty() && +#ifdef EATHENA_SUPPORT + !mServerField->getText().empty() && + isUShort(mPortField->getText()) && +#endif state == STATE_LOGIN; } + +#ifdef EATHENA_SUPPORT +bool LoginDialog::isUShort(const std::string &str) +{ + if (str.empty()) + { + return false; + } + unsigned long l = 0; + for (std::string::const_iterator strPtr = str.begin(), strEnd = str.end(); + strPtr != strEnd; ++strPtr) + { + if (*strPtr < '0' || *strPtr > '9') + { + return false; + } + l = l * 10 + (*strPtr - '0'); // *strPtr - '0' will never be negative + if (l > 65535) + { + return false; + } + } + return true; +} + +unsigned short LoginDialog::getUShort(const std::string &str) +{ + unsigned long l = 0; + for (std::string::const_iterator strPtr = str.begin(), strEnd = str.end(); + strPtr != strEnd; ++strPtr) + { + l = l * 10 + (*strPtr - '0'); + } + return static_cast<unsigned short>(l); +} + +/** + * LoginDialog::DropDownList + */ + +void LoginDialog::DropDownList::saveEntry(const std::string &server, + const std::string &port, int &saved) +{ + if (saved < MAX_SERVER_LIST_SIZE && !server.empty()) + { + config.setValue(mConfigPrefix + "Server" + toString(saved), server); + config.setValue(mConfigPrefix + "Port" + toString(saved), port); + ++saved; + } +} + +LoginDialog::DropDownList::DropDownList(std::string prefix, + std::vector<std::string> dflt, + std::vector<std::string> dfltPort, + int maxEntries) : + mConfigPrefix(prefix), + mMaxEntries(maxEntries) +{ + for (int i = 0; i < maxEntries; ++i) + { + std::string server = config.getValue(mConfigPrefix + "Server" + + toString(i), ""); + if (server.empty()) // Just in case had original config entries + { + server = config.getValue(mConfigPrefix + "ServerList" + + toString(i), ""); + } + std::string port = config.getValue(mConfigPrefix + "Port" + + toString(i), dfltPort.front()); + + if (!server.empty()) + { + mServers.push_back(server); + mPorts.push_back(port); + } + } + if (mServers.empty()) + { + mServers.assign(dflt.begin(), dflt.end()); + mPorts.assign(dfltPort.begin(), dfltPort.end()); + } +} + +void LoginDialog::DropDownList::save(const std::string &server, + const std::string &port) +{ + int position = 0; + saveEntry(server, port, position); + for (std::vector<std::string>::const_iterator sPtr = mServers.begin(), + sEnd = mServers.end(), + pPtr = mPorts.begin(), + pEnd = mPorts.end(); + sPtr != sEnd && pPtr != pEnd; + ++sPtr, ++pPtr) + { + if (*sPtr != server || *pPtr != port) + { + saveEntry(*sPtr, *pPtr, position); + } + } +} + +int LoginDialog::DropDownList::getNumberOfElements() +{ + return mServers.size(); +} + +std::string LoginDialog::DropDownList::getElementAt(int i) +{ + if (i < 0 || i >= getNumberOfElements()) + { + return ""; + } + return getServerAt(i) + ":" + getPortAt(i); +} + +std::string LoginDialog::DropDownList::getServerAt(int i) +{ + if (i < 0 || i >= getNumberOfElements()) + { + return ""; + } + return mServers.at(i); +} + +std::string LoginDialog::DropDownList::getPortAt(int i) +{ + if (i < 0 || i >= getNumberOfElements()) + { + return ""; + } + return mPorts.at(i); +} +#endif diff --git a/src/gui/login.h b/src/gui/login.h index 1c23a0f5..9a97cd4d 100644 --- a/src/gui/login.h +++ b/src/gui/login.h @@ -1,35 +1,43 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TMW_LOGIN_H -#define _TMW_LOGIN_H +#ifndef LOGIN_H +#define LOGIN_H + +#include <string> +#include <vector> -#include <iosfwd> #include <guichan/actionlistener.hpp> #include <guichan/keylistener.hpp> +#ifdef EATHENA_SUPPORT +#include <guichan/listmodel.hpp> +#endif #include "window.h" -#include "../guichanfwd.h" class LoginData; +#ifdef EATHENA_SUPPORT +class DropDown; +class ScrollArea; +#endif /** * The login dialog. @@ -48,11 +56,6 @@ class LoginDialog : public Window, public gcn::ActionListener, LoginDialog(LoginData *loginData); /** - * Destructor - */ - ~LoginDialog(); - - /** * Called when receiving actions from the widgets. */ void action(const gcn::ActionEvent &event); @@ -67,17 +70,71 @@ class LoginDialog : public Window, public gcn::ActionListener, * Returns whether submit can be enabled. This is true in the login * state, when all necessary fields have some text. */ - bool - canSubmit(); + bool canSubmit(); + +#ifdef EATHENA_SUPPORT + /** + * Function to decide whether string is an unsigned short or not + * + * @param str the string to parse + * + * @return true is str is an unsigned short, false otherwise + */ + static bool isUShort(const std::string &str); + /** + * Converts string to an unsigned short (undefined if invalid) + * + * @param str the string to parse + * + * @return the value str represents + */ + static unsigned short getUShort(const std::string &str); + +#endif gcn::TextField *mUserField; gcn::TextField *mPassField; +#ifdef EATHENA_SUPPORT + gcn::TextField *mServerField; + gcn::TextField *mPortField; + DropDown *mServerDropDown; +#endif gcn::CheckBox *mKeepCheck; gcn::Button *mOkButton; gcn::Button *mCancelButton; gcn::Button *mRegisterButton; LoginData *mLoginData; + +#ifdef EATHENA_SUPPORT + /** + * Helper class to keep a list of all the recent entries for the + * dropdown + */ + class DropDownList : public gcn::ListModel + { + private: + std::vector<std::string> mServers; + std::vector<std::string> mPorts; + std::string mConfigPrefix; + int mMaxEntries; + void saveEntry(const std::string &server, + const std::string &port, int &saved); + public: + DropDownList(std::string prefix, + std::vector<std::string> dfltServer, + std::vector<std::string> dfltPort, + int maxEntries); + void save(const std::string &server, const std::string &port); + int getNumberOfElements(); + std::string getElementAt(int i); + std::string getServerAt(int i); + std::string getPortAt(int i); + }; + DropDownList *mServerList; + gcn::ListBox *mServerListBox; + gcn::ScrollArea *mServerScrollArea; +#endif }; #endif diff --git a/src/gui/magic.cpp b/src/gui/magic.cpp index 2c81321b..0e56e853 100644 --- a/src/gui/magic.cpp +++ b/src/gui/magic.cpp @@ -29,7 +29,6 @@ #include "../localplayer.h" #include "../utils/dtor.h" -#include "../utils/tostring.h" #include "../utils/gettext.h" MagicDialog::MagicDialog(): diff --git a/src/gui/menuwindow.cpp b/src/gui/menuwindow.cpp index 9415188e..25ece461 100644 --- a/src/gui/menuwindow.cpp +++ b/src/gui/menuwindow.cpp @@ -1,44 +1,47 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "menuwindow.h" - #include <string> #include <guichan/actionlistener.hpp> #include "button.h" +#include "menuwindow.h" #include "windowcontainer.h" #include "../utils/gettext.h" -extern Window *setupWindow; -extern Window *inventoryWindow; +extern Window *chatWindow; extern Window *equipmentWindow; +extern Window *inventoryWindow; +extern Window *itemShortcutWindow; +extern Window *emoteWindow; +extern Window *setupWindow; extern Window *skillDialog; -extern Window *magicDialog; extern Window *statusWindow; -extern Window *guildWindow; -extern Window *itemShortcutWindow; +#ifdef TMWSERV_SUPPORT extern Window *buddyWindow; +extern Window *guildWindow; +extern Window *magicDialog; +#endif namespace { struct MenuWindowListener : public gcn::ActionListener @@ -54,20 +57,25 @@ MenuWindow::MenuWindow(): Window() { setResizable(false); + setWindowName("Menu"); setMovable(false); setTitleBarHeight(0); // Buttons static const char *buttonNames[] = { + N_("Chat"), N_("Status"), N_("Equipment"), N_("Inventory"), N_("Skills"), +#ifdef TMWSERV_SUPPORT N_("Magic"), N_("Guilds"), N_("Buddys"), +#endif N_("Shortcut"), + N_("Emote"), N_("Setup"), 0 }; @@ -96,7 +104,11 @@ void MenuWindowListener::action(const gcn::ActionEvent &event) { Window *window = NULL; - if (event.getId() == "Status") + if (event.getId() == "Chat") + { + window = chatWindow; + } + else if (event.getId() == "Status") { window = statusWindow; } @@ -112,6 +124,7 @@ void MenuWindowListener::action(const gcn::ActionEvent &event) { window = skillDialog; } +#ifdef TMWSERV_SUPPORT else if (event.getId() == "Magic") { window = magicDialog; @@ -124,10 +137,15 @@ void MenuWindowListener::action(const gcn::ActionEvent &event) { window = buddyWindow; } +#endif else if (event.getId() == "Shortcut") { window = itemShortcutWindow; } + else if (event.getId() == "Emote") + { + window = emoteWindow; + } else if (event.getId() == "Setup") { window = setupWindow; diff --git a/src/gui/menuwindow.h b/src/gui/menuwindow.h index 03ec3380..9bb54e29 100644 --- a/src/gui/menuwindow.h +++ b/src/gui/menuwindow.h @@ -1,31 +1,29 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TMW_MENU_H -#define _TMW_MENU_H +#ifndef MENU_H +#define MENU_H #include "window.h" -#include "../guichanfwd.h" - /** * The Button Menu. * diff --git a/src/gui/minimap.cpp b/src/gui/minimap.cpp index f7749755..4347c9cc 100644 --- a/src/gui/minimap.cpp +++ b/src/gui/minimap.cpp @@ -1,28 +1,31 @@ /* * The Mana World - * Copyright 2004-2005 The Mana World Development Team + * Copyright (C) 2004-2005 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include <guichan/font.hpp> + #include "minimap.h" #include "../being.h" #include "../beingmanager.h" +#include "../configuration.h" #include "../graphics.h" #include "../localplayer.h" @@ -30,22 +33,27 @@ #include "../utils/gettext.h" +bool Minimap::mShow = true; + Minimap::Minimap(): Window(_("MiniMap")), - mMapImage(NULL) + mMapImage(NULL), + mProportion(0.5) { setWindowName("MiniMap"); + mShow = config.getValue(getWindowName() + "Show", true); setDefaultSize(5, 25, 100, 100); + setResizable(true); + loadWindowState(); - // LEEOR: The Window class needs to modified to accept - // setAlignment calls. - setAlignment(gcn::Graphics::CENTER); } Minimap::~Minimap() { if (mMapImage) mMapImage->decRef(); + + config.setValue(getWindowName() + "Show", mShow); } void Minimap::setMapImage(Image *img) @@ -55,30 +63,94 @@ void Minimap::setMapImage(Image *img) mMapImage = img; - if (mMapImage) { - mMapImage->setAlpha(0.7); - setContentSize(mMapImage->getWidth(), mMapImage->getHeight()); + if (mMapImage) + { + const int offsetX = 2 * getPadding(); + const int offsetY = getTitleBarHeight() + getPadding(); + const int titleWidth = getFont()->getWidth(getCaption()) + 15; + const int mapWidth = mMapImage->getWidth() < 100 ? + mMapImage->getWidth() + offsetX : 100; + const int mapHeight = mMapImage->getHeight() < 100 ? + mMapImage->getHeight() + offsetY : 100; + + setMinWidth(mapWidth > titleWidth ? mapWidth : titleWidth); + setMinHeight(mapHeight); + setMaxWidth(mMapImage->getWidth() > titleWidth ? + mMapImage->getWidth() + offsetX : titleWidth); + setMaxHeight(mMapImage->getHeight() + offsetY); + + // Make sure the window is within the minimum and maximum boundaries + // TODO: Shouldn't this be happening automatically within the Window + // class? + if (getMinWidth() > getWidth()) + setWidth(getMinWidth()); + else if (getMaxWidth() < getWidth()) + setWidth(getMaxWidth()); + if (getMinHeight() > getHeight()) + setHeight(getMinHeight()); + else if (getMaxHeight() < getHeight()) + setHeight(getMaxHeight()); + + setContentSize(getWidth() - offsetX, getHeight() - offsetY); + setDefaultSize(getX(), getY(), getWidth(), getHeight()); + resetToDefaultSize(); + + setVisible(mShow); } + else + { + setVisible(false); + } +} + +void Minimap::toggle() +{ + mShow = !mShow; } void Minimap::draw(gcn::Graphics *graphics) { + setVisible(mShow); + Window::draw(graphics); + if (!mShow) + return; + const gcn::Rectangle a = getChildrenArea(); - int mapOriginX = a.x; - int mapOriginY = a.y; + graphics->pushClipArea(a); + + int mapOriginX = 0; + int mapOriginY = 0; if (mMapImage) { if (mMapImage->getWidth() > a.width || mMapImage->getHeight() > a.height) { - const Vector &pos = player_node->getPosition(); - mapOriginX += (a.width - (int) (pos.x / 32)) / 2; - mapOriginY += (a.height - (int) (pos.y / 32)) / 2; +#ifdef TMWSERV_SUPPORT + const Vector &p = player_node->getPosition(); + mapOriginX = (int) (((a.width) / 2) - (int) (p.x * mProportion) / 32); + mapOriginY = (int) (((a.height) / 2) - (int) (p.y * mProportion) / 32); +#else + mapOriginX = (int) (((a.width) / 2) - (player_node->mX * mProportion)); + mapOriginY = (int) (((a.height) / 2) - (player_node->mY * mProportion)); +#endif + + const int minOriginX = a.width - mMapImage->getWidth(); + const int minOriginY = a.height - mMapImage->getHeight(); + + if (mapOriginX < minOriginX) + mapOriginX = minOriginX; + if (mapOriginY < minOriginY) + mapOriginY = minOriginY; + if (mapOriginX > 0) + mapOriginX = 0; + if (mapOriginY > 0) + mapOriginY = 0; } + static_cast<Graphics*>(graphics)-> drawImage(mMapImage, mapOriginX, mapOriginY); } @@ -102,24 +174,26 @@ void Minimap::draw(gcn::Graphics *graphics) graphics->setColor(gcn::Color(61, 52, 209)); break; - case Being::NPC: - graphics->setColor(gcn::Color(255, 255, 0)); - break; - case Being::MONSTER: graphics->setColor(gcn::Color(209, 52, 61)); break; + case Being::NPC: + graphics->setColor(gcn::Color(255, 255, 0)); + break; + default: continue; } - const int offset = (dotSize - 1) / 2; + const int offset = (int) ((dotSize - 1) * mProportion); const Vector &pos = being->getPosition(); graphics->fillRectangle(gcn::Rectangle( - (int) pos.x / 64 + mapOriginX - offset, - (int) pos.x / 64 + mapOriginY - offset, + (int) (pos.x * mProportion) / 32 + mapOriginX - offset, + (int) (pos.x * mProportion) / 32 + mapOriginY - offset, dotSize, dotSize)); } + + graphics->popClipArea(); } diff --git a/src/gui/minimap.h b/src/gui/minimap.h index f91dc22d..3ce0aacd 100644 --- a/src/gui/minimap.h +++ b/src/gui/minimap.h @@ -1,26 +1,26 @@ /* * The Mana World - * Copyright 2004-2005 The Mana World Development Team + * Copyright (C) 2004-2005 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TMW_MINIMAP_H -#define _TMW_MINIMAP_H +#ifndef MINIMAP_H +#define MINIMAP_H #include "window.h" @@ -50,12 +50,24 @@ class Minimap : public Window void setMapImage(Image *img); /** + * Sets the map proportion (1 means 1 tile to one pixel, .5 means 2 tiles to 1 pixel, etc.) + */ + void setProportion(float proportion) { mProportion = proportion; } + + /** + * Toggles the displaying of the minimap. + */ + void toggle(); + + /** * Draws the minimap. */ void draw(gcn::Graphics *graphics); private: Image *mMapImage; + float mProportion; + static bool mShow; }; extern Minimap *minimap; diff --git a/src/gui/ministatus.cpp b/src/gui/ministatus.cpp index 86e5a8f1..5bc25bdb 100644 --- a/src/gui/ministatus.cpp +++ b/src/gui/ministatus.cpp @@ -1,65 +1,94 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "ministatus.h" - -#include <guichan/widgets/label.hpp> - #include "gui.h" +#include "ministatus.h" #include "progressbar.h" -#include "../localplayer.h" +#include "../animatedsprite.h" #include "../configuration.h" #include "../graphics.h" +#include "../localplayer.h" -#include "../utils/tostring.h" +#include "../utils/stringutils.h" MiniStatusWindow::MiniStatusWindow() { + setWindowName("MiniStatus"); setResizable(false); setMovable(false); setTitleBarHeight(0); mHpBar = new ProgressBar(1.0f, 100, 20, 0, 171, 34); - mHpLabel = new gcn::Label(""); +#ifdef EATHENA_SUPPORT + mMpBar = new ProgressBar(1.0f, 100, 20, 26, 102, 230); + mXpBar = new ProgressBar(1.0f, 100, 20, 143, 192, 211); +#endif mHpBar->setPosition(0, 3); +#ifdef EATHENA_SUPPORT + mMpBar->setPosition(mHpBar->getWidth() + 3, 3); + mXpBar->setPosition(mMpBar->getX() + mMpBar->getWidth() + 3, 3); +#endif - mHpLabel->setDimension(mHpBar->getDimension()); + add(mHpBar); +#ifdef EATHENA_SUPPORT + add(mMpBar); + add(mXpBar); +#endif + +#ifdef EATHENA_SUPPORT + setContentSize(mXpBar->getX() + mXpBar->getWidth(), + mXpBar->getY() + mXpBar->getHeight()); +#else + setContentSize(mHpBar->getX() + mHpBar->getWidth(), + mHpBar->getY() + mHpBar->getHeight()); +#endif + setDefaultSize(0, 0, getWidth(), getHeight()); + loadWindowState(); +} - mHpLabel->setForegroundColor(gcn::Color(255, 255, 255)); +void MiniStatusWindow::setIcon(int index, AnimatedSprite *sprite) +{ + if (index >= (int) mIcons.size()) + mIcons.resize(index + 1, NULL); - mHpLabel->setFont(speechFont); + if (mIcons[index]) + delete mIcons[index]; - mHpLabel->setAlignment(gcn::Graphics::CENTER); + mIcons[index] = sprite; +} - add(mHpBar); - add(mHpLabel); +void MiniStatusWindow::eraseIcon(int index) +{ + mIcons.erase(mIcons.begin() + index); } +extern volatile int tick_time; + void MiniStatusWindow::update() { // HP Bar coloration - int maxHp = player_node->getMaxHP(); - int hp = player_node->getHP(); + int maxHp = player_node->getMaxHp(); + int hp = player_node->getHp(); if (hp < int(maxHp / 3)) { mHpBar->setColor(223, 32, 32); // Red @@ -73,10 +102,47 @@ void MiniStatusWindow::update() mHpBar->setColor(0, 171, 34); // Green } +#ifdef EATHENA_SUPPORT + float xp = (float) player_node->getXp() / player_node->mXpForNextLevel; + + if (xp != xp) xp = 0.0f; // check for NaN + if (xp < 0.0f) xp = 0.0f; // make sure the experience isn't negative (uninitialized pointer most likely) + if (xp > 1.0f) xp = 1.0f; +#endif + mHpBar->setProgress((float) hp / maxHp); +#ifdef EATHENA_SUPPORT + mMpBar->setProgress((float) player_node->mMp / player_node->mMaxMp); + mXpBar->setProgress(xp); +#endif // Update labels - mHpLabel->setCaption(toString(hp)); + mHpBar->setText(toString(player_node->getHp())); +#ifdef EATHENA_SUPPORT + mMpBar->setText(toString(player_node->mMp)); + + std::stringstream updatedText; + updatedText << (float) ((int) (xp * 10000.0f)) / 100.0f << "%"; + + // Displays the number of monsters to next lvl + // (disabled for now but interesting idea) + /* + if (config.getValue("xpBarMonsterCounterExp", 0)!=0) + { + updatedText << " | " + << (int)(((float)player_node->mXpForNextLevel - (float)player_node->mXp) + / (float)config.getValue("xpBarMonsterCounterExp", 0)) + << " " + << config.getValue("xpBarMonsterCounterName", "Monsters") <<" left..."; + } + */ + + mXpBar->setText(updatedText.str()); +#endif + + for (unsigned int i = 0; i < mIcons.size(); i++) + if (mIcons[i]) + mIcons[i]->update(tick_time * 10); } void MiniStatusWindow::draw(gcn::Graphics *graphics) @@ -84,3 +150,19 @@ void MiniStatusWindow::draw(gcn::Graphics *graphics) update(); drawChildren(graphics); } + +void MiniStatusWindow::drawIcons(Graphics *graphics) +{ + // Draw icons +#ifdef TMWSERV_SUPPORT + int icon_x = mHpBar->getX() + mHpBar->getWidth() + 4; +#else + int icon_x = mXpBar->getX() + mXpBar->getWidth() + 4; +#endif + for (unsigned int i = 0; i < mIcons.size(); i++) { + if (mIcons[i]) { + mIcons[i]->draw(graphics, icon_x, 3); + icon_x += 2 + mIcons[i]->getWidth(); + } + } +} diff --git a/src/gui/ministatus.h b/src/gui/ministatus.h index f512ef25..b69f9a14 100644 --- a/src/gui/ministatus.h +++ b/src/gui/ministatus.h @@ -1,33 +1,32 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TMW_MINISTATUS_H -#define _TMW_MINISTATUS_H - -#include <iosfwd> +#ifndef MINISTATUS_H +#define MINISTATUS_H #include "window.h" -#include "../guichanfwd.h" +#include <vector> +class AnimatedSprite; class ProgressBar; /** @@ -44,13 +43,22 @@ class MiniStatusWindow : public Window MiniStatusWindow(); /** - * Draw this window + * Draw this window. */ void draw(gcn::Graphics *graphics); + /** + * Sets one of the icons. + */ + void setIcon(int index, AnimatedSprite *sprite); + + void eraseIcon(int index); + + void drawIcons(Graphics *graphics); + private: /** - * Updates this dialog with values from player_node + * Updates this dialog with values from player_node. */ void update(); @@ -58,7 +66,12 @@ class MiniStatusWindow : public Window * Mini Status Bars */ ProgressBar *mHpBar; - gcn::Label *mHpLabel; +#ifdef EATHENA_SUPPORT + ProgressBar *mMpBar; + ProgressBar *mXpBar; +#endif + + std::vector<AnimatedSprite *> mIcons; }; #endif diff --git a/src/gui/npc_text.cpp b/src/gui/npc_text.cpp index c9ace303..48f2adb7 100644 --- a/src/gui/npc_text.cpp +++ b/src/gui/npc_text.cpp @@ -1,102 +1,117 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include "button.h" #include "npc_text.h" - -#include <string> - #include "scrollarea.h" -#include "button.h" #include "textbox.h" +#include "widgets/layout.h" + #include "../npc.h" #include "../utils/gettext.h" NpcTextDialog::NpcTextDialog(): - Window(_("NPC")) + Window(_("NPC")), + mState(NPC_TEXT_STATE_WAITING) { setResizable(true); setMinWidth(200); setMinHeight(150); + setDefaultSize(0, 0, 260, 200); + mTextBox = new TextBox; mTextBox->setEditable(false); + mTextBox->setOpaque(false); - scrollArea = new ScrollArea(mTextBox); - okButton = new Button(_("OK"), "ok", this); + mScrollArea = new ScrollArea(mTextBox); + mButton = new Button(_("Waiting for server"), "ok", this); - setContentSize(260, 175); - scrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); - scrollArea->setVerticalScrollPolicy(gcn::ScrollArea::SHOW_ALWAYS); - scrollArea->setDimension(gcn::Rectangle( - 5, 5, 250, 160 - okButton->getHeight())); - okButton->setPosition( - 260 - 5 - okButton->getWidth(), - 175 - 5 - okButton->getHeight()); + mScrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); + mScrollArea->setVerticalScrollPolicy(gcn::ScrollArea::SHOW_ALWAYS); - add(scrollArea); - add(okButton); + place(0, 0, mScrollArea, 5).setPadding(3); + place(4, 1, mButton); + Layout &layout = getLayout(); + layout.setRowHeight(0, Layout::AUTO_SET); + + loadWindowState(); setLocationRelativeTo(getParent()); } void NpcTextDialog::setText(const std::string &text) { mText = text; - mTextBox->setTextWrapped(mText); + mTextBox->setTextWrapped(mText, mScrollArea->getWidth() - 15); } void NpcTextDialog::addText(const std::string &text) { setText(mText + text + "\n"); + mScrollArea->setVerticalScrollAmount(mScrollArea->getVerticalMaxScroll()); } -void NpcTextDialog::widgetResized(const gcn::Event &event) +void NpcTextDialog::showNextButton() { - Window::widgetResized(event); - - const gcn::Rectangle &area = getChildrenArea(); - const int width = area.width; - const int height = area.height; - - scrollArea->setDimension(gcn::Rectangle( - 5, 5, width - 10, height - 15 - okButton->getHeight())); - okButton->setPosition( - width - 5 - okButton->getWidth(), - height - 5 - okButton->getHeight()); + mButton->setCaption(_("Next")); + mState = NPC_TEXT_STATE_NEXT; + mButton->setEnabled(true); +} - // Set the text again so that it gets wrapped according to the new size - mTextBox->setTextWrapped(mText); +void NpcTextDialog::showCloseButton() +{ + mButton->setCaption(_("Close")); + mState = NPC_TEXT_STATE_CLOSE; + mButton->setEnabled(true); } void NpcTextDialog::action(const gcn::ActionEvent &event) { if (event.getId() == "ok") { - setText(""); - setVisible(false); - if (current_npc) + if (mState == NPC_TEXT_STATE_NEXT && current_npc) { current_npc->nextDialog(); - current_npc = 0; + addText("\n> Next\n"); + } else if (mState == NPC_TEXT_STATE_CLOSE || + (mState == NPC_TEXT_STATE_NEXT && !current_npc)) { + setText(""); + setVisible(false); + if (current_npc) current_npc->handleDeath(); + } else return; } + else return; + + mButton->setEnabled(false); + mButton->setCaption(_("Waiting for server")); + mState = NPC_TEXT_STATE_WAITING; +} + +void NpcTextDialog::widgetResized(const gcn::Event &event) +{ + Window::widgetResized(event); + + setText(mText); } + diff --git a/src/gui/npc_text.h b/src/gui/npc_text.h index b6eccf95..a1373830 100644 --- a/src/gui/npc_text.h +++ b/src/gui/npc_text.h @@ -1,28 +1,29 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TMW_NPC_TEXT_H -#define _TMW_NPC_TEXT_H +#ifndef NPC_TEXT_H +#define NPC_TEXT_H + +#include <string> -#include <iosfwd> #include <guichan/actionlistener.hpp> #include "window.h" @@ -45,16 +46,14 @@ class NpcTextDialog : public Window, public gcn::ActionListener NpcTextDialog(); /** - * Called when resizing the window. - * - * @param event The calling event + * Called when receiving actions from the widgets. */ - void widgetResized(const gcn::Event &event); + void action(const gcn::ActionEvent &event); /** - * Called when receiving actions from the widgets. + * Clears the text shown in the dialog. */ - void action(const gcn::ActionEvent &event); + void clearText(); /** * Sets the text shows in the dialog. @@ -71,12 +70,30 @@ class NpcTextDialog : public Window, public gcn::ActionListener */ void addText(const std::string &string); + void showNextButton(); + + void showCloseButton(); + + /** + * Called when resizing the window. + * + * @param event The calling event + */ + void widgetResized(const gcn::Event &event); + private: - gcn::Button *okButton; - gcn::ScrollArea *scrollArea; + gcn::ScrollArea *mScrollArea; TextBox *mTextBox; + gcn::Button *mButton; std::string mText; + + enum NPCTextState { + NPC_TEXT_STATE_WAITING, + NPC_TEXT_STATE_NEXT, + NPC_TEXT_STATE_CLOSE + }; + int mState; }; -#endif // _TMW_NPC_TEXT_H +#endif // NPC_TEXT_H diff --git a/src/gui/npcintegerdialog.cpp b/src/gui/npcintegerdialog.cpp new file mode 100644 index 00000000..463f46ae --- /dev/null +++ b/src/gui/npcintegerdialog.cpp @@ -0,0 +1,125 @@ +/* + * The Mana World + * Copyright (C) 2004 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 "button.h" +#include "inttextfield.h" +#include "npc_text.h" +#include "npcintegerdialog.h" + +#include "widgets/layout.h" + +#include "../npc.h" + +#include "../utils/gettext.h" +#include "../utils/strprintf.h" + +extern NpcTextDialog *npcTextDialog; + +NpcIntegerDialog::NpcIntegerDialog(): + Window(_("NPC Number Request")) +{ + mValueField = new IntTextField; + + mDecButton = new Button("-", "decvalue", this); + mIncButton = new Button("+", "incvalue", this); + gcn::Button *okButton = new Button(_("OK"), "ok", this); + gcn::Button *cancelButton = new Button(_("Cancel"), "cancel", this); + gcn::Button *resetButton = new Button(_("Reset"), "reset", this); + + mDecButton->setSize(20, 20); + mIncButton->setSize(20, 20); + + ContainerPlacer place; + place = getPlacer(0, 0); + + place(0, 0, mDecButton); + place(1, 0, mValueField, 3); + place(4, 0, mIncButton); + place.getCell().matchColWidth(1, 0); + place = getPlacer(0, 1); + place(0, 0, resetButton); + place(2, 0, cancelButton); + place(3, 0, okButton); + reflowLayout(175, 0); + + setLocationRelativeTo(getParent()); +} + +void NpcIntegerDialog::setRange(int min, int max) +{ + mValueField->setRange(min, max); +} + +int NpcIntegerDialog::getValue() +{ + return mValueField->getValue(); +} + +void NpcIntegerDialog::action(const gcn::ActionEvent &event) +{ + int finish = 0; + + if (event.getId() == "ok") + { + finish = 1; + npcTextDialog->addText(strprintf("\n> %d\n", mValueField->getValue())); + } + else if (event.getId() == "cancel") + { + finish = 1; + mValueField->reset(); + npcTextDialog->addText(_("\n> Cancel\n")); + } + else if (event.getId() == "decvalue") + { + mValueField->setValue(mValueField->getValue() - 1); + } + else if (event.getId() == "incvalue") + { + mValueField->setValue(mValueField->getValue() + 1); + } + else if (event.getId() == "reset") + { + mValueField->reset(); + } + + if (finish) + { + setVisible(false); + current_npc->integerInput(mValueField->getValue()); + mValueField->reset(); + } +} + +void NpcIntegerDialog::setDefaultValue(int value) +{ + mValueField->setDefaultValue(value); +} + +bool NpcIntegerDialog::isInputFocused() +{ + return mValueField->isFocused(); +} + +void NpcIntegerDialog::requestFocus() +{ + mValueField->requestFocus(); +} diff --git a/src/gui/npcintegerdialog.h b/src/gui/npcintegerdialog.h new file mode 100644 index 00000000..941bb55a --- /dev/null +++ b/src/gui/npcintegerdialog.h @@ -0,0 +1,87 @@ +/* + * The Mana World + * Copyright (C) 2004 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_NPCINTEGERDIALOG_H +#define GUI_NPCINTEGERDIALOG_H + +#include <guichan/actionlistener.hpp> + +#include "window.h" + +class IntTextField; + +/** + * The npc integer input dialog. + * + * \ingroup Interface + */ +class NpcIntegerDialog : public Window, public gcn::ActionListener +{ + public: + /** + * Constructor. + * + * @see Window::Window + */ + NpcIntegerDialog(); + + /** + * Called when receiving actions from the widgets. + */ + void action(const gcn::ActionEvent &event); + + /** + * Returns the current value. + */ + int getValue(); + + /** + * Prepares the NPC dialog. + * + * @param min The minimum value to allow + * @param max The maximum value to allow + */ + void setRange(int min, int max); + + /** + * Sets the default value. + * + * @param value The new default value + */ + void setDefaultValue(int value); + + /** + * Checks whether NpcStringDialog is Focused or not. + */ + bool isInputFocused(); + + /** + * Requests the textfield to take focus for input. + */ + void requestFocus(); + + private: + gcn::Button *mDecButton; + gcn::Button *mIncButton; + IntTextField *mValueField; +}; + +#endif // GUI_NPCINTEGERDIALOG_H diff --git a/src/gui/npclistdialog.cpp b/src/gui/npclistdialog.cpp index c55255ea..82e05fd5 100644 --- a/src/gui/npclistdialog.cpp +++ b/src/gui/npclistdialog.cpp @@ -1,35 +1,40 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "npclistdialog.h" - #include <sstream> #include "button.h" -#include "scrollarea.h" #include "listbox.h" +#include "npc_text.h" +#include "npclistdialog.h" +#include "scrollarea.h" + +#include "widgets/layout.h" #include "../npc.h" #include "../utils/gettext.h" +#include "../utils/strprintf.h" + +extern NpcTextDialog *npcTextDialog; NpcListDialog::NpcListDialog(): Window(_("NPC")) @@ -39,30 +44,25 @@ NpcListDialog::NpcListDialog(): setMinWidth(200); setMinHeight(150); + setDefaultSize(0, 0, 260, 200); + mItemList = new ListBox(this); - scrollArea = new ScrollArea(mItemList); - okButton = new Button(_("OK"), "ok", this); - cancelButton = new Button(_("Cancel"), "cancel", this); + mItemList->setWrappingEnabled(true); + gcn::ScrollArea *scrollArea = new ScrollArea(mItemList); + gcn::Button *okButton = new Button(_("OK"), "ok", this); + gcn::Button *cancelButton = new Button(_("Cancel"), "cancel", this); setContentSize(260, 175); scrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); - scrollArea->setDimension(gcn::Rectangle( - 5, 5, 250, 160 - okButton->getHeight())); - cancelButton->setPosition( - 260 - 5 - cancelButton->getWidth(), - 175 - 5 - cancelButton->getHeight()); - okButton->setPosition( - cancelButton->getX() - 5 - okButton->getWidth(), - cancelButton->getY()); - mItemList->setActionEventId("item"); + place(0, 0, scrollArea, 5).setPadding(3); + place(3, 1, okButton); + place(4, 1, cancelButton); - mItemList->addActionListener(this); - - add(scrollArea); - add(okButton); - add(cancelButton); + Layout &layout = getLayout(); + layout.setRowHeight(0, Layout::AUTO_SET); + loadWindowState(); setLocationRelativeTo(getParent()); } @@ -81,33 +81,23 @@ void NpcListDialog::addItem(const std::string &item) mItems.push_back(item); } -void NpcListDialog::reset() +void NpcListDialog::parseItems(const std::string &itemString) { - mItems.clear(); + std::istringstream iss(itemString); + + std::string tmp; + while (getline(iss, tmp, ':')) + mItems.push_back(tmp); } -void NpcListDialog::widgetResized(const gcn::Event &event) +void NpcListDialog::reset() { - Window::widgetResized(event); - - const gcn::Rectangle &area = getChildrenArea(); - const int width = area.width; - const int height = area.height; - - scrollArea->setDimension(gcn::Rectangle( - 5, 5, width - 10, height - 15 - okButton->getHeight())); - cancelButton->setPosition( - width - 5 - cancelButton->getWidth(), - height - 5 - cancelButton->getHeight()); - okButton->setPosition( - cancelButton->getX() - 5 - okButton->getWidth(), - cancelButton->getY()); + mItems.clear(); } void NpcListDialog::action(const gcn::ActionEvent &event) { int choice = 0; - if (event.getId() == "ok") { // Send the selected index back to the server @@ -115,11 +105,14 @@ void NpcListDialog::action(const gcn::ActionEvent &event) if (selectedIndex > -1) { choice = selectedIndex + 1; + npcTextDialog->addText(strprintf("\n> \"%s\"\n", + mItems[selectedIndex].c_str())); } } else if (event.getId() == "cancel") { choice = 0xff; // 0xff means cancel + npcTextDialog->addText(_("\n> Cancel\n")); } if (choice) @@ -127,6 +120,5 @@ void NpcListDialog::action(const gcn::ActionEvent &event) setVisible(false); reset(); current_npc->dialogChoice(choice); - current_npc = 0; } } diff --git a/src/gui/npclistdialog.h b/src/gui/npclistdialog.h index 65281f58..7e37c7e6 100644 --- a/src/gui/npclistdialog.h +++ b/src/gui/npclistdialog.h @@ -1,36 +1,33 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TMW_GUI_NPCLISTDIALOG_H -#define _TMW_GUI_NPCLISTDIALOG_H +#ifndef GUI_NPCLISTDIALOG_H +#define GUI_NPCLISTDIALOG_H -#include <iosfwd> -#include <vector> +#include "window.h" #include <guichan/actionlistener.hpp> #include <guichan/listmodel.hpp> -#include "window.h" - -#include "../guichanfwd.h" +#include <vector> /** * The npc list dialog. @@ -49,13 +46,6 @@ class NpcListDialog : public Window, public gcn::ActionListener, NpcListDialog(); /** - * Called when resizing the window - * - * @param event The calling event - */ - void widgetResized(const gcn::Event &event); - - /** * Called when receiving actions from the widgets. */ void action(const gcn::ActionEvent &event); @@ -76,17 +66,21 @@ class NpcListDialog : public Window, public gcn::ActionListener, void addItem(const std::string &); /** + * Fills the options list for an NPC dialog. + * + * @param itemString A string with the options separated with colons. + */ + void parseItems(const std::string &itemString); + + /** * Resets the list by removing all items. */ void reset(); private: gcn::ListBox *mItemList; - gcn::ScrollArea *scrollArea; - gcn::Button *okButton; - gcn::Button *cancelButton; std::vector<std::string> mItems; }; -#endif // _TMW_GUI_NPCLISTDIALOG_H +#endif // GUI_NPCLISTDIALOG_H diff --git a/src/gui/npcstringdialog.cpp b/src/gui/npcstringdialog.cpp new file mode 100644 index 00000000..d9bf5682 --- /dev/null +++ b/src/gui/npcstringdialog.cpp @@ -0,0 +1,89 @@ +/* + * The Mana World + * Copyright (C) 2004 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 "button.h" +#include "npc_text.h" +#include "npcstringdialog.h" +#include "textfield.h" + +#include "widgets/layout.h" + +#include "../npc.h" + +#include "../utils/gettext.h" +#include "../utils/strprintf.h" + +extern NpcTextDialog *npcTextDialog; + +NpcStringDialog::NpcStringDialog(): + Window(_("NPC Text Request")) +{ + mValueField = new TextField(""); + + gcn::Button *okButton = new Button(_("OK"), "ok", this); + gcn::Button *cancelButton = new Button(_("Cancel"), "cancel", this); + + place(0, 0, mValueField, 3); + place(1, 1, cancelButton); + place(2, 1, okButton); + reflowLayout(175, 0); + + setLocationRelativeTo(getParent()); +} + +std::string NpcStringDialog::getValue() +{ + return mValueField->getText(); +} + +void NpcStringDialog::setValue(const std::string &value) +{ + mValueField->setText(value); + mDefault = value; +} + +void NpcStringDialog::action(const gcn::ActionEvent &event) +{ + if (event.getId() == "cancel") + { + mValueField->setText(mDefault); + npcTextDialog->addText(_("\n> Cancel\n")); + } + else + { + npcTextDialog->addText(strprintf("\n> \"%s\"\n", + mValueField->getText().c_str())); + } + + setVisible(false); + current_npc->stringInput(mValueField->getText()); + mValueField->setText(""); +} + +bool NpcStringDialog::isInputFocused() +{ + return mValueField->isFocused(); +} + +void NpcStringDialog::requestFocus() +{ + mValueField->requestFocus(); +} diff --git a/src/gui/npcstringdialog.h b/src/gui/npcstringdialog.h new file mode 100644 index 00000000..0faaf203 --- /dev/null +++ b/src/gui/npcstringdialog.h @@ -0,0 +1,76 @@ +/* + * The Mana World + * Copyright (C) 2004 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_NPCSTRINGDIALOG_H +#define GUI_NPCSTRINGDIALOG_H + +#include "window.h" + +#include <guichan/actionlistener.hpp> + +/** + * The npc integer input dialog. + * + * \ingroup Interface + */ +class NpcStringDialog : public Window, public gcn::ActionListener +{ + public: + /** + * Constructor. + * + * @see Window::Window + */ + NpcStringDialog(); + + /** + * Called when receiving actions from the widgets. + */ + void action(const gcn::ActionEvent &event); + + /** + * Returns the current value. + */ + std::string getValue(); + + /** + * Chnages the current value. + * + * @param value The new value + */ + void setValue(const std::string &value); + + /** + * Checks whether NpcStringDialog is Focused or not. + */ + bool isInputFocused(); + + /** + * Requests the textfield to take focus for input. + */ + void requestFocus(); + + private: + gcn::TextField *mValueField; + std::string mDefault; +}; + +#endif // GUI_NPCSTRINGDIALOG_H diff --git a/src/gui/ok_dialog.cpp b/src/gui/ok_dialog.cpp index b03c3964..4df3fa07 100644 --- a/src/gui/ok_dialog.cpp +++ b/src/gui/ok_dialog.cpp @@ -1,29 +1,30 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "ok_dialog.h" - -#include <guichan/widgets/label.hpp> +#include <guichan/font.hpp> #include "button.h" +#include "ok_dialog.h" +#include "scrollarea.h" +#include "textbox.h" #include "../utils/gettext.h" @@ -31,22 +32,44 @@ OkDialog::OkDialog(const std::string &title, const std::string &msg, Window *parent): Window(title, true, parent) { - gcn::Label *textLabel = new gcn::Label(msg); + mTextBox = new TextBox; + mTextBox->setEditable(false); + mTextBox->setOpaque(false); + + mTextArea = new ScrollArea(mTextBox); gcn::Button *okButton = new Button(_("Ok"), "ok", this); - int w = textLabel->getWidth() + 20; - int h = textLabel->getHeight() + 25 + okButton->getHeight(); + mTextArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); + mTextArea->setVerticalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); + mTextArea->setOpaque(false); + + mTextBox->setTextWrapped(msg, 260); + + int numRows = mTextBox->getNumberOfRows(); - if (okButton->getWidth() + 10 > w) { - w = okButton->getWidth() + 10; + if (numRows > 1) + { + // 15 == height of each line of text (based on font heights) + // 14 == row top + bottom graphic pixel heights + setContentSize(mTextBox->getMinWidth() + 15, 15 + (numRows * 15) + okButton->getHeight()); + mTextArea->setDimension(gcn::Rectangle(4, 5, mTextBox->getMinWidth() + 5, + 3 + (numRows * 14))); + } + else + { + int width = getFont()->getWidth(title); + if (width < getFont()->getWidth(msg)) + width = getFont()->getWidth(msg); + if (width < okButton->getWidth()) + width = okButton->getWidth(); + setContentSize(width + 15, 30 + okButton->getHeight()); + mTextArea->setDimension(gcn::Rectangle(4, 5, width + 5, 17)); } - setContentSize(w, h); - textLabel->setPosition(10, 10); - okButton->setPosition((w - okButton->getWidth()) / 2, - h - 5 - okButton->getHeight()); + okButton->setPosition((mTextBox->getMinWidth() - okButton->getWidth()) / 2, + (numRows * 14) + okButton->getHeight() - 8); - add(textLabel); + add(mTextArea); add(okButton); setLocationRelativeTo(getParent()); @@ -54,6 +77,11 @@ OkDialog::OkDialog(const std::string &title, const std::string &msg, okButton->requestFocus(); } +unsigned int OkDialog::getNumRows() +{ + return mTextBox->getNumberOfRows(); +} + void OkDialog::action(const gcn::ActionEvent &event) { // Proxy button events to our listeners diff --git a/src/gui/ok_dialog.h b/src/gui/ok_dialog.h index cba12d72..24325c2f 100644 --- a/src/gui/ok_dialog.h +++ b/src/gui/ok_dialog.h @@ -1,30 +1,33 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _OK_DIALOG_H -#define _OK_DIALOG_H +#ifndef OK_DIALOG_H +#define OK_DIALOG_H + +#include "window.h" #include <guichan/actionlistener.hpp> -#include "window.h" +class ScrollArea; +class TextBox; /** * An 'Ok' button dialog. @@ -41,10 +44,16 @@ class OkDialog : public Window, public gcn::ActionListener { OkDialog(const std::string &title, const std::string &msg, Window *parent = NULL); + unsigned int getNumRows(); + /** * Called when receiving actions from the widgets. */ void action(const gcn::ActionEvent &event); + + private: + TextBox *mTextBox; + ScrollArea *mTextArea; }; #endif diff --git a/src/gui/passwordfield.cpp b/src/gui/passwordfield.cpp index 01c7e15d..345ee1c3 100644 --- a/src/gui/passwordfield.cpp +++ b/src/gui/passwordfield.cpp @@ -1,28 +1,26 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "passwordfield.h" -#include <string> - PasswordField::PasswordField(const std::string& text): TextField(text) { diff --git a/src/gui/passwordfield.h b/src/gui/passwordfield.h index 8a14b72a..86195bd1 100644 --- a/src/gui/passwordfield.h +++ b/src/gui/passwordfield.h @@ -1,26 +1,26 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TMW_PASSWORDFIELD_H_ -#define _TMW_PASSWORDFIELD_H_ +#ifndef PASSWORDFIELD_H +#define PASSWORDFIELD_H #include "textfield.h" @@ -29,7 +29,8 @@ * * \ingroup GUI */ -class PasswordField : public TextField { +class PasswordField : public TextField +{ public: /** * Constructor, initializes the password field with the given string. diff --git a/src/gui/playerbox.cpp b/src/gui/playerbox.cpp index 6888d69a..2bfa798c 100644 --- a/src/gui/playerbox.cpp +++ b/src/gui/playerbox.cpp @@ -1,30 +1,30 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include <algorithm> - #include "playerbox.h" -#include "../player.h" +#include "../animatedsprite.h" +#include "../configuration.h" #include "../graphics.h" +#include "../player.h" #include "../resources/image.h" #include "../resources/resourcemanager.h" @@ -32,6 +32,7 @@ #include "../utils/dtor.h" int PlayerBox::instances = 0; +float PlayerBox::mAlpha = config.getValue("guialpha", 0.8); ImageRect PlayerBox::background; PlayerBox::PlayerBox(const Player *player): @@ -54,6 +55,7 @@ PlayerBox::PlayerBox(const Player *player): bggridx[x], bggridy[y], bggridx[x + 1] - bggridx[x] + 1, bggridy[y + 1] - bggridy[y] + 1); + background.grid[a]->setAlpha(config.getValue("guialpha", 0.8)); a++; } } @@ -80,9 +82,29 @@ void PlayerBox::draw(gcn::Graphics *graphics) { // Draw character const int bs = getFrameSize(); +#ifdef TMWSERV_SUPPORT const int x = getWidth() / 2 + bs; const int y = getHeight() - bs - 8; mPlayer->draw(static_cast<Graphics*>(graphics), x, y); +#else + const int x = getWidth() / 2 - 16 + bs; + const int y = getHeight() / 2 + bs; + for (int i = 0; i < Being::VECTOREND_SPRITE; i++) + { + if (mPlayer->getSprite(i)) + { + mPlayer->getSprite(i)->draw(static_cast<Graphics*>(graphics), x, y); + } + } +#endif + } + + if (config.getValue("guialpha", 0.8) != mAlpha) + { + for (int a = 0; a < 9; a++) + { + background.grid[a]->setAlpha(config.getValue("guialpha", 0.8)); + } } } diff --git a/src/gui/playerbox.h b/src/gui/playerbox.h index 78eeee91..7c08defd 100644 --- a/src/gui/playerbox.h +++ b/src/gui/playerbox.h @@ -1,26 +1,26 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef __TMW_PLAYERBOX_H__ -#define __TMW_PLAYERBOX_H__ +#ifndef PLAYERBOX_H +#define PLAYERBOX_H #include <guichan/widgets/scrollarea.hpp> @@ -51,8 +51,7 @@ class PlayerBox : public gcn::ScrollArea * player to <code>NULL</code> causes the box not to draw any * character. */ - void - setPlayer(const Player *player) { mPlayer = player; } + void setPlayer(const Player *player) { mPlayer = player; } /** * Draws the scroll area. @@ -67,6 +66,7 @@ class PlayerBox : public gcn::ScrollArea private: const Player *mPlayer; /**< The character used for display */ + static float mAlpha; static int instances; static ImageRect background; }; diff --git a/src/gui/popupmenu.cpp b/src/gui/popupmenu.cpp index a430ff10..ced44f42 100644 --- a/src/gui/popupmenu.cpp +++ b/src/gui/popupmenu.cpp @@ -1,43 +1,46 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "popupmenu.h" - #include <cassert> -#include <iostream> - -#include <guichan/focushandler.hpp> #include "browserbox.h" +#include "chat.h" #include "inventorywindow.h" #include "item_amount.h" +#include "popupmenu.h" #include "windowcontainer.h" #include "../being.h" +#include "../beingmanager.h" #include "../floor_item.h" #include "../item.h" #include "../localplayer.h" #include "../npc.h" +#include "../player_relations.h" + +#ifdef EATHENA_SUPPORT +#include "../net/messageout.h" +#include "../net/ea/protocol.h" +#endif -#include "../resources/iteminfo.h" #include "../resources/itemdb.h" #include "../utils/gettext.h" @@ -47,14 +50,15 @@ extern std::string tradePartnerName; PopupMenu::PopupMenu(): Window(), - mBeing(NULL), + mBeingId(0), mFloorItem(NULL), mItem(NULL) { setResizable(false); setTitleBarHeight(0); + setShowTitle(false); - mBrowserBox = new BrowserBox(); + mBrowserBox = new BrowserBox; mBrowserBox->setPosition(4, 4); mBrowserBox->setHighlightMode(BrowserBox::BACKGROUND); mBrowserBox->setOpaque(false); @@ -64,22 +68,47 @@ PopupMenu::PopupMenu(): void PopupMenu::showPopup(int x, int y, Being *being) { - mBeing = being; + mBeingId = being->getId(); mBrowserBox->clearRows(); - switch (mBeing->getType()) + switch (being->getType()) { case Being::PLAYER: { // Players can be traded with. Later also attack, follow and // add as buddy will be options in this menu. - const std::string &name = mBeing->getName(); + const std::string &name = being->getName(); mBrowserBox->addRow(strprintf(_("@@trade|Trade With %s@@"), name.c_str())); mBrowserBox->addRow(strprintf(_("@@attack|Attack %s@@"), name.c_str())); - //mBrowserBox->addRow("@@follow|Follow " + name + "@@"); - //mBrowserBox->addRow("@@buddy|Add " + name + " to Buddy List@@"); + + mBrowserBox->addRow("##3---"); + + switch (player_relations.getRelation(name)) { + case PlayerRelation::NEUTRAL: + mBrowserBox->addRow(strprintf(_("@@friend|Befriend %s@@"), name.c_str())); + + case PlayerRelation::FRIEND: + mBrowserBox->addRow(strprintf(_("@@disregard|Disregard %s@@"), name.c_str())); + mBrowserBox->addRow(strprintf(_("@@ignore|Ignore %s@@"), name.c_str())); + break; + + case PlayerRelation::DISREGARDED: + mBrowserBox->addRow(strprintf(_("@@unignore|Un-Ignore %s@@"), name.c_str())); + mBrowserBox->addRow(strprintf(_("@@ignore|Completely ignore %s@@"), name.c_str())); + break; + + case PlayerRelation::IGNORED: + mBrowserBox->addRow(strprintf(_("@@unignore|Un-Ignore %s@@"), name.c_str())); + break; + } + + //mBrowserBox->addRow(_("@@follow|Follow ") + name + "@@"); + //mBrowserBox->addRow(_("@@buddy|Add ") + name + " to Buddy List@@"); mBrowserBox->addRow(strprintf(_("@@guild|Invite %s@@"), name.c_str())); mBrowserBox->addRow(strprintf(_("@@party|Invite %s to join your party@@"), name.c_str())); + + mBrowserBox->addRow("##3---"); + mBrowserBox->addRow(strprintf(_("@@party-invite|Invite %s to party@@"), name.c_str())); } break; @@ -119,37 +148,76 @@ void PopupMenu::showPopup(int x, int y, FloorItem *floorItem) void PopupMenu::handleLink(const std::string& link) { + Being *being = beingManager->findBeing(mBeingId); + // Talk To action if (link == "talk" && - mBeing != NULL && - mBeing->getType() == Being::NPC) + being && + being->getType() == Being::NPC && + current_npc == 0) { - static_cast<NPC*>(mBeing)->talk(); + dynamic_cast<NPC*>(being)->talk(); } // Trade action else if (link == "trade" && - mBeing != NULL && - mBeing->getType() == Being::PLAYER) + being && + being->getType() == Being::PLAYER) + { + player_node->trade(being); + tradePartnerName = being->getName(); + } +#ifdef EATHENA_SUPPORT + // Attack action + else if (link == "attack" && + being && + being->getType() == Being::PLAYER) { - player_node->trade(mBeing); - tradePartnerName = mBeing->getName(); + player_node->attack(being, true); + } +#endif + else if (link == "unignore" && + being && + being->getType() == Being::PLAYER) + { + player_relations.setRelation(being->getName(), PlayerRelation::NEUTRAL); } + else if (link == "ignore" && + being && + being->getType() == Being::PLAYER) + { + player_relations.setRelation(being->getName(), PlayerRelation::IGNORED); + } + + else if (link == "disregard" && + being && + being->getType() == Being::PLAYER) + { + player_relations.setRelation(being->getName(), PlayerRelation::DISREGARDED); + } + + else if (link == "friend" && + being && + being->getType() == Being::PLAYER) + { + player_relations.setRelation(being->getName(), PlayerRelation::FRIEND); + } +#ifdef TMWSERV_SUPPORT // Guild action else if (link == "guild" && - mBeing != NULL && - mBeing->getType() == Being::PLAYER) + being != NULL && + being->getType() == Being::PLAYER) { - player_node->inviteToGuild(mBeing); + player_node->inviteToGuild(being); } // Add player to your party else if (link == "party") { - player_node->inviteToParty(mBeing->getName()); + player_node->inviteToParty(being->getName()); } - +#endif /* // Follow Player action else if (link == "follow") @@ -158,16 +226,16 @@ void PopupMenu::handleLink(const std::string& link) /* // Add Buddy action - else if ((link == "buddy") && mBeing != NULL && mBeing->isPlayer()) + else if ((link == "buddy") && being && being->isPlayer()) { if (!buddyWindow->isVisible()) buddyWindow->setVisible(true); - buddyWindow->addBuddy(mBeing->getName()); + buddyWindow->addBuddy(being->getName()); }*/ // Pick Up Floor Item action - else if ((link == "pickup") && mFloorItem != NULL) + else if ((link == "pickup") && mFloorItem) { player_node->pickUp(mFloorItem); } @@ -182,13 +250,34 @@ void PopupMenu::handleLink(const std::string& link) assert(mItem); if (mItem->isEquipment()) { +#ifdef TMWSERV_SUPPORT player_node->equipItem(mItem); +#else + if (mItem->isEquipped()) + { + player_node->unequipItem(mItem); + } + else + { + player_node->equipItem(mItem); + } +#endif } else { +#ifdef TMWSERV_SUPPORT player_node->useItem(mItem->getInvIndex()); +#else + player_node->useItem(mItem); +#endif } } + + else if (link == "chat") + { + chatWindow->addItemText(mItem->getInfo().getName()); + } + else if (link == "split") { new ItemAmountWindow(AMOUNT_ITEM_SPLIT, inventoryWindow, mItem); @@ -197,12 +286,16 @@ void PopupMenu::handleLink(const std::string& link) { new ItemAmountWindow(AMOUNT_ITEM_DROP, inventoryWindow, mItem); } - - else if (link == "description") +#ifdef EATHENA_SUPPORT + else if (link == "party-invite" && + being && + being->getType() == Being::PLAYER) { - // do nothing for now, I need to write - // a window for the description first + MessageOut outMsg(player_node->getNetwork()); + outMsg.writeInt16(CMSG_PARTY_INVITE); + outMsg.writeInt32(being->getId()); } +#endif // Unknown actions else @@ -212,7 +305,7 @@ void PopupMenu::handleLink(const std::string& link) setVisible(false); - mBeing = NULL; + mBeingId = 0; mFloorItem = NULL; mItem = NULL; } @@ -225,14 +318,24 @@ void PopupMenu::showPopup(int x, int y, Item *item) if (item->isEquipment()) { +#ifdef TMWSERV_SUPPORT mBrowserBox->addRow(_("@@use|Equip@@")); +#else + if (item->isEquipped()) + mBrowserBox->addRow(_("@@use|Unequip@@")); + else + mBrowserBox->addRow(_("@@use|Equip@@")); +#endif } else mBrowserBox->addRow(_("@@use|Use@@")); + mBrowserBox->addRow(_("@@drop|Drop@@")); - mBrowserBox->addRow(_("@@description|Description@@")); +#ifdef TMWSERV_SUPPORT if (!item->isEquipment()) - { mBrowserBox->addRow(_("@@split|Split@@")); } + mBrowserBox->addRow(_("@@split|Split@@")); +#endif + mBrowserBox->addRow(_("@@chat|Add to Chat@@")); mBrowserBox->addRow("##3---"); mBrowserBox->addRow(_("@@cancel|Cancel@@")); diff --git a/src/gui/popupmenu.h b/src/gui/popupmenu.h index 2d10e6eb..2694abd8 100644 --- a/src/gui/popupmenu.h +++ b/src/gui/popupmenu.h @@ -1,36 +1,37 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TMW_POPUP_MENU_H -#define _TMW_POPUP_MENU_H +#ifndef POPUP_MENU_H +#define POPUP_MENU_H + +#include <SDL.h> // for Uint32 -#include "window.h" #include "linkhandler.h" +#include "window.h" class Being; class BrowserBox; class FloorItem; class Item; - /** * Window showing popup menu. */ @@ -67,7 +68,7 @@ class PopupMenu : public Window, public LinkHandler private: BrowserBox* mBrowserBox; - Being* mBeing; + Uint32 mBeingId; FloorItem* mFloorItem; Item *mItem; diff --git a/src/gui/progressbar.cpp b/src/gui/progressbar.cpp index 9a47eefc..85f21604 100644 --- a/src/gui/progressbar.cpp +++ b/src/gui/progressbar.cpp @@ -1,26 +1,30 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include <guichan/font.hpp> + +#include "gui.h" #include "progressbar.h" +#include "../configuration.h" #include "../graphics.h" #include "../resources/image.h" @@ -28,6 +32,7 @@ ImageRect ProgressBar::mBorder; int ProgressBar::mInstances = 0; +float ProgressBar::mAlpha = config.getValue("guialpha", 0.8); ProgressBar::ProgressBar(float progress, unsigned int width, unsigned int height, @@ -56,6 +61,12 @@ ProgressBar::ProgressBar(float progress, mBorder.grid[6] = dBorders->getSubImage(0, 15, 4, 4); mBorder.grid[7] = dBorders->getSubImage(4, 15, 3, 4); mBorder.grid[8] = dBorders->getSubImage(7, 15, 4, 4); + + for (int i = 0; i < 9; i++) + { + mBorder.grid[i]->setAlpha(mAlpha); + } + dBorders->decRef(); } @@ -109,32 +120,62 @@ void ProgressBar::logic() mProgress = mProgressToGo; } -void -ProgressBar::draw(gcn::Graphics *graphics) +void ProgressBar::draw(gcn::Graphics *graphics) { + if (config.getValue("guialpha", 0.8) != mAlpha) + { + mAlpha = config.getValue("guialpha", 0.8); + for (int i = 0; i < 9; i++) + { + mBorder.grid[i]->setAlpha(mAlpha); + } + } + static_cast<Graphics*>(graphics)-> drawImageRect(0, 0, getWidth(), getHeight(), mBorder); + const int alpha = (int)(mAlpha * 255.0f); + // The bar if (mProgress > 0) { - graphics->setColor(gcn::Color(mRed, mGreen, mBlue, 200)); + + graphics->setColor(gcn::Color(mRed, mGreen, mBlue, alpha)); graphics->fillRectangle(gcn::Rectangle(4, 4, - (int)(mProgress * (getWidth() - 8)), + (int) (mProgress * (getWidth() - 8)), getHeight() - 8)); } + + // The label + if (!mText.empty()) + { + gcn::Font *f = boldFont; + const int textX = getWidth() / 2; + const int textY = (getHeight() - f->getHeight()) / 2; + + graphics->setFont(f); + + graphics->setColor(gcn::Color(0, 0, 0, alpha)); + graphics->drawText(mText, textX + 1, textY, gcn::Graphics::CENTER); + graphics->drawText(mText, textX, textY - 1, gcn::Graphics::CENTER); + graphics->drawText(mText, textX, textY + 1, gcn::Graphics::CENTER); + graphics->drawText(mText, textX - 1, textY, gcn::Graphics::CENTER); + + graphics->setColor(gcn::Color(255, 255, 255, alpha)); + graphics->drawText(mText, textX, textY, gcn::Graphics::CENTER); + + graphics->setColor(gcn::Color(0, 0, 0)); + } } -void -ProgressBar::setProgress(float progress) +void ProgressBar::setProgress(float progress) { if (progress < 0.0f) mProgressToGo = 0.0; else if (progress > 1.0f) mProgressToGo = 1.0; else mProgressToGo = progress; } -void -ProgressBar::setColor(Uint8 red, Uint8 green, Uint8 blue) +void ProgressBar::setColor(Uint8 red, Uint8 green, Uint8 blue) { mRedToGo = red; mGreenToGo = green; diff --git a/src/gui/progressbar.h b/src/gui/progressbar.h index 0b1616f5..49bc3edd 100644 --- a/src/gui/progressbar.h +++ b/src/gui/progressbar.h @@ -1,26 +1,28 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TMW_PROGRESSBAR_H -#define _TMW_PROGRESSBAR_H +#ifndef PROGRESSBAR_H +#define PROGRESSBAR_H + +#include <string> #include <guichan/widget.hpp> @@ -28,13 +30,13 @@ class ImageRect; - /** * A progress bar. * * \ingroup GUI */ -class ProgressBar : public gcn::Widget { +class ProgressBar : public gcn::Widget +{ public: /** * Constructor, initializes the progress with the given value. @@ -51,63 +53,65 @@ class ProgressBar : public gcn::Widget { /** * Performs progress bar logic (fading colors) */ - void - logic(); + void logic(); /** * Draws the progress bar. */ - void - draw(gcn::Graphics *graphics); + void draw(gcn::Graphics *graphics); /** * Sets the current progress. */ - void - setProgress(float progress); + void setProgress(float progress); /** * Returns the current progress. */ - float - getProgress() { return mProgress; } + float getProgress() const { return mProgress; } /** * Change the filling of the progress bar. */ - void - setColor(Uint8, Uint8 green, Uint8 blue); + void setColor(Uint8, Uint8 green, Uint8 blue); + + /** + * Returns the red value of color. + */ + Uint8 getRed() const { return mRed; } /** - * Get The red value of color + * Returns the green value of color. */ - Uint8 - getRed() { return mRed; } + Uint8 getGreen() const { return mGreen; } - /** - * Get The red value of color + /** + * Returns the blue value of color. */ - Uint8 - getGreen() { return mGreen; } + Uint8 getBlue() const { return mBlue; } /** - * Get The red value of color + * Sets the text shown on the progress bar. */ - Uint8 - getBlue() { return mBlue; } + void setText(const std::string &text) + { mText = text; } /** - * Set wether the progress is moved smoothly + * Returns the text shown on the progress bar. */ - void - setSmoothProgress(bool smoothProgress) + const std::string &text() const + { return mText; } + + /** + * Set wether the progress is moved smoothly. + */ + void setSmoothProgress(bool smoothProgress) { mSmoothProgress = smoothProgress; } /** - * Set wether the color changing is made smoothly + * Set wether the color changing is made smoothly. */ - void - setSmoothColorChange(bool smoothColorChange) + void setSmoothColorChange(bool smoothColorChange) { mSmoothColorChange = smoothColorChange; } @@ -119,8 +123,11 @@ class ProgressBar : public gcn::Widget { Uint8 mRedToGo, mGreenToGo, mBlueToGo; bool mSmoothColorChange; + std::string mText; + static ImageRect mBorder; static int mInstances; + static float mAlpha; }; #endif diff --git a/src/gui/radiobutton.cpp b/src/gui/radiobutton.cpp index 619ec84f..c8ae2fad 100644 --- a/src/gui/radiobutton.cpp +++ b/src/gui/radiobutton.cpp @@ -1,32 +1,34 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "radiobutton.h" +#include "../configuration.h" #include "../graphics.h" #include "../resources/image.h" #include "../resources/resourcemanager.h" int RadioButton::instances = 0; +float RadioButton::mAlpha = config.getValue("guialpha", 0.8); Image *RadioButton::radioNormal; Image *RadioButton::radioChecked; Image *RadioButton::radioDisabled; @@ -43,6 +45,10 @@ RadioButton::RadioButton(const std::string& caption, const std::string& group, radioChecked = resman->getImage("graphics/gui/radioin.png"); radioDisabled = resman->getImage("graphics/gui/radioout.png"); radioDisabledChecked = resman->getImage("graphics/gui/radioin.png"); + radioNormal->setAlpha(mAlpha); + radioChecked->setAlpha(mAlpha); + radioDisabled->setAlpha(mAlpha); + radioDisabledChecked->setAlpha(mAlpha); } instances++; @@ -63,32 +69,37 @@ RadioButton::~RadioButton() void RadioButton::drawBox(gcn::Graphics* graphics) { + if (config.getValue("guialpha", 0.8) != mAlpha) + { + mAlpha = config.getValue("guialpha", 0.8); + radioNormal->setAlpha(mAlpha); + radioChecked->setAlpha(mAlpha); + radioDisabled->setAlpha(mAlpha); + radioDisabledChecked->setAlpha(mAlpha); + } + Image *box = NULL; - if (isSelected()) { - if (isEnabled()) { + if (isSelected()) + { + if (isEnabled()) box = radioChecked; - } else { + else box = radioDisabledChecked; - } - } else if (isEnabled()) { + } + else if (isEnabled()) box = radioNormal; - } else { + else box = radioDisabled; - } - if (box != NULL) { + if (box) static_cast<Graphics*>(graphics)->drawImage(box, 2, 2); - } } void RadioButton::draw(gcn::Graphics* graphics) { - - graphics->pushClipArea(gcn::Rectangle(1, - 1, - getWidth() - 1, - getHeight() - 1)); + graphics->pushClipArea(gcn::Rectangle(1, 1, getWidth() - 1, + getHeight() - 1)); drawBox(graphics); diff --git a/src/gui/radiobutton.h b/src/gui/radiobutton.h index 09f703dc..3d952b3f 100644 --- a/src/gui/radiobutton.h +++ b/src/gui/radiobutton.h @@ -1,36 +1,36 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TMW_RADIOBUTTON_H -#define _TMW_RADIOBUTTON_H +#ifndef RADIOBUTTON_H +#define RADIOBUTTON_H #include <guichan/widgets/radiobutton.hpp> class Image; - /* * Guichan based RadioButton with custom look */ -class RadioButton : public gcn::RadioButton { +class RadioButton : public gcn::RadioButton +{ public: /* * Constructor. @@ -56,10 +56,11 @@ class RadioButton : public gcn::RadioButton { private: static int instances; + static float mAlpha; static Image *radioNormal; static Image *radioChecked; static Image *radioDisabled; static Image *radioDisabledChecked; }; -#endif /* _TMW_RADIOBUTTON_H */ +#endif /* RADIOBUTTON_H */ diff --git a/src/gui/recorder.cpp b/src/gui/recorder.cpp new file mode 100644 index 00000000..ce097db2 --- /dev/null +++ b/src/gui/recorder.cpp @@ -0,0 +1,116 @@ +/* + * A chat recorder + * Copyright (C) 2008 Lloyd Bryant <lloyd_bryant@netzero.net> + * + * 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 <physfs.h> + +#include "button.h" +#include "chat.h" +#include "recorder.h" +#include "windowcontainer.h" + +#include "widgets/layout.h" + +#include "../utils/stringutils.h" + +Recorder::Recorder(ChatWindow *chat, const std::string &title, + const std::string &buttonTxt) : + Window(title) +{ + setWindowName("Recorder"); + const int offsetX = 2 * getPadding() + 10; + const int offsetY = getTitleBarHeight() + getPadding() + 10; + + mChat = chat; + Button *button = new Button(buttonTxt, "activate", this); + setDefaultSize(0, windowContainer->getHeight() - 123 - button->getHeight() - + offsetY, button->getWidth() + offsetX, button->getHeight() + + offsetY); + + place(0, 0, button); + + Layout &layout = getLayout(); + layout.setRowHeight(0, Layout::AUTO_SET); + + loadWindowState(); +} + +Recorder::~Recorder() +{ +} + +void Recorder::record(const std::string &msg) +{ + if (mStream.is_open()) + { + mStream << msg << std::endl; + } +} + +void Recorder::changeRecordingStatus(const std::string &msg) +{ + std::string msgCopy = msg; + trim(msgCopy); + + if (msgCopy.empty()) + { + if (mStream.is_open()) + { + mStream.close(); + setVisible(false); + + /* + * Message should go after mStream is closed so that it isn't + * recorded. + */ + mChat->chatLog(_("Finishing recording."), BY_SERVER); + } + else + { + mChat->chatLog(_("Not currently recording."), BY_SERVER); + } + } + else if (mStream.is_open()) + { + mChat->chatLog(_("Already recording."), BY_SERVER); + } + else + { + /* + * Message should go before mStream is opened so that it isn't + * recorded. + */ + mChat->chatLog(_("Starting to record..."), BY_SERVER); + const std::string file = + std::string(PHYSFS_getUserDir()) + "/.tmw/" + msgCopy; + + mStream.open(file.c_str(), std::ios_base::trunc); + + if (mStream.is_open()) + setVisible(true); + else + mChat->chatLog(_("Failed to start recording."), BY_SERVER); + } +} + +void Recorder::action(const gcn::ActionEvent &event) +{ + changeRecordingStatus(""); +} diff --git a/src/gui/recorder.h b/src/gui/recorder.h new file mode 100644 index 00000000..0bbab012 --- /dev/null +++ b/src/gui/recorder.h @@ -0,0 +1,76 @@ +/* + * A chat recorder + * Copyright (C) 2008 Lloyd Bryant <lloyd_bryant@netzero.net> + * + * 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 RECORD_H +#define RECORD_H + +#include <fstream> +#include <string> + +#include <guichan/actionlistener.hpp> + +#include "window.h" + +#include "../utils/gettext.h" + +class ChatWindow; + +class Recorder : public Window, public gcn::ActionListener +{ + public: + Recorder(ChatWindow *chat, const std::string &title = _("Recording..."), + const std::string &buttonTxt = _("Stop recording")); + + virtual ~Recorder(); + + /* + * Outputs the message to the recorder file + * + * @param msg the line to write to the recorded file. + */ + void record(const std::string &msg); + + /* + * Outputs the message to the recorder file + * + * @param msg The file to write out to. If null, then stop recording. + */ + void changeRecordingStatus(const std::string &msg); + + /* + * Whether or not the recorder is in use. + */ + bool isRecording() {return (bool) mStream.is_open();} + + /* + * called when the button is pressed + * + * @param event is the event that is generated + */ + void action(const gcn::ActionEvent &event); + + private: + ChatWindow *mChat; + + std::ofstream mStream; +}; + +#endif diff --git a/src/gui/register.cpp b/src/gui/register.cpp index 051c0fa4..216ac211 100644 --- a/src/gui/register.cpp +++ b/src/gui/register.cpp @@ -1,55 +1,52 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "register.h" - -#include <string> -#include <sstream> - #include <guichan/widgets/label.hpp> -#include "../main.h" #include "../configuration.h" #include "../log.h" #include "../logindata.h" +#include "../main.h" #include "button.h" #include "checkbox.h" #include "login.h" +#include "ok_dialog.h" #include "passwordfield.h" #include "radiobutton.h" +#include "register.h" #include "textfield.h" -#include "ok_dialog.h" + +#include "widgets/layout.h" #include "../utils/gettext.h" #include "../utils/strprintf.h" +#include "../utils/stringutils.h" -void -WrongDataNoticeListener::setTarget(gcn::TextField *textField) +void WrongDataNoticeListener::setTarget(gcn::TextField *textField) { mTarget = textField; } -void -WrongDataNoticeListener::action(const gcn::ActionEvent &event) +void WrongDataNoticeListener::action(const gcn::ActionEvent &event) { if (event.getId() == "ok") { @@ -57,54 +54,61 @@ WrongDataNoticeListener::action(const gcn::ActionEvent &event) } } + RegisterDialog::RegisterDialog(LoginData *loginData): Window(_("Register")), - mWrongDataNoticeListener(new WrongDataNoticeListener()), + mWrongDataNoticeListener(new WrongDataNoticeListener), mLoginData(loginData) { gcn::Label *userLabel = new gcn::Label(_("Name:")); gcn::Label *passwordLabel = new gcn::Label(_("Password:")); gcn::Label *confirmLabel = new gcn::Label(_("Confirm:")); - gcn::Label *emailLabel = new gcn::Label(_("Email:")); +#ifdef EATHENA_SUPPORT + gcn::Label *serverLabel = new gcn::Label(_("Server:")); + gcn::Label *portLabel = new gcn::Label(_("Port:")); +#endif mUserField = new TextField(loginData->username); mPasswordField = new PasswordField(loginData->password); - mConfirmField = new PasswordField(); - mEmailField = new TextField(); + mConfirmField = new PasswordField; +#ifdef EATHENA_SUPPORT + mServerField = new TextField(loginData->hostname); + mPortField = new TextField(toString(loginData->port)); + mMaleButton = new RadioButton(_("Male"), "sex", true); + mFemaleButton = new RadioButton(_("Female"), "sex", false); +#endif mRegisterButton = new Button(_("Register"), "register", this); mCancelButton = new Button(_("Cancel"), "cancel", this); - const int width = 220; - const int height = 130; - setContentSize(width, height); - - mUserField->setPosition(65, 5); - mUserField->setWidth(width - 70); - mPasswordField->setPosition( - 65, mUserField->getY() + mUserField->getHeight() + 7); - mPasswordField->setWidth(mUserField->getWidth()); - mConfirmField->setPosition( - 65, mPasswordField->getY() + mPasswordField->getHeight() + 7); - mConfirmField->setWidth(mUserField->getWidth()); - mEmailField->setPosition( - 65, mConfirmField->getY() + mConfirmField->getHeight() + 7); - mEmailField->setWidth(mUserField->getWidth()); - - userLabel->setPosition(5, mUserField->getY() + 1); - passwordLabel->setPosition(5, mPasswordField->getY() + 1); - confirmLabel->setPosition(5, mConfirmField->getY() + 1); - emailLabel->setPosition(5, mEmailField->getY() + 1); - - mCancelButton->setPosition( - width - mCancelButton->getWidth() - 5, - height - mCancelButton->getHeight() - 5); - mRegisterButton->setPosition( - mCancelButton->getX() - mRegisterButton->getWidth() - 5, - height - mRegisterButton->getHeight() - 5); + ContainerPlacer place; + place = getPlacer(0, 0); + place(0, 0, userLabel); + place(0, 1, passwordLabel); + place(0, 2, confirmLabel); +#ifdef EATHENA_SUPPORT + place(1, 3, mMaleButton); + place(2, 3, mFemaleButton); + place(0, 4, serverLabel); + place(0, 5, portLabel); +#endif + place(1, 0, mUserField, 3).setPadding(2); + place(1, 1, mPasswordField, 3).setPadding(2); + place(1, 2, mConfirmField, 3).setPadding(2); +#ifdef EATHENA_SUPPORT + place(1, 4, mServerField, 3).setPadding(2); + place(1, 5, mPortField, 3).setPadding(2); +#endif + place = getPlacer(0, 2); + place(1, 0, mRegisterButton); + place(2, 0, mCancelButton); + reflowLayout(250, 0); mUserField->addKeyListener(this); mPasswordField->addKeyListener(this); mConfirmField->addKeyListener(this); - mEmailField->addKeyListener(this); +#ifdef EATHENA_SUPPORT + mServerField->addKeyListener(this); + mPortField->addKeyListener(this); +#endif /* TODO: * This is a quick and dirty way to respond to the ENTER key, regardless of @@ -114,22 +118,18 @@ RegisterDialog::RegisterDialog(LoginData *loginData): mUserField->setActionEventId("register"); mPasswordField->setActionEventId("register"); mConfirmField->setActionEventId("register"); - mEmailField->setActionEventId("register"); + mUserField->addActionListener(this); mPasswordField->addActionListener(this); mConfirmField->addActionListener(this); - mEmailField->addActionListener(this); - - add(userLabel); - add(passwordLabel); - add(emailLabel); - add(confirmLabel); - add(mUserField); - add(mPasswordField); - add(mConfirmField); - add(mEmailField); - add(mRegisterButton); - add(mCancelButton); + +#ifdef EATHENA_SUPPORT + mServerField->setActionEventId("register"); + mPortField->setActionEventId("register"); + + mServerField->addActionListener(this); + mPortField->addActionListener(this); +#endif setLocationRelativeTo(getParent()); setVisible(true); @@ -144,8 +144,7 @@ RegisterDialog::~RegisterDialog() delete mWrongDataNoticeListener; } -void -RegisterDialog::action(const gcn::ActionEvent &event) +void RegisterDialog::action(const gcn::ActionEvent &event) { if (event.getId() == "cancel") { @@ -225,25 +224,73 @@ RegisterDialog::action(const gcn::ActionEvent &event) mLoginData->username = mUserField->getText(); mLoginData->password = mPasswordField->getText(); +#ifdef EATHENA_SUPPORT + mLoginData->hostname = mServerField->getText(); + mLoginData->port = getUShort(mPortField->getText()); + mLoginData->username += mFemaleButton->isSelected() ? "_F" : "_M"; +#else mLoginData->email = mEmailField->getText(); +#endif mLoginData->registerLogin = true; +#ifdef TMWSERV_SUPPORT state = STATE_REGISTER_ATTEMPT; +#else + state = STATE_ACCOUNT; +#endif } } } -void -RegisterDialog::keyPressed(gcn::KeyEvent &keyEvent) +void RegisterDialog::keyPressed(gcn::KeyEvent &keyEvent) { mRegisterButton->setEnabled(canSubmit()); } -bool -RegisterDialog::canSubmit() +bool RegisterDialog::canSubmit() const { return !mUserField->getText().empty() && !mPasswordField->getText().empty() && !mConfirmField->getText().empty() && +#ifdef EATHENA_SUPPORT + !mServerField->getText().empty() && + isUShort(mPortField->getText()) && +#endif state == STATE_REGISTER; } + +#ifdef EATHENA_SUPPORT +bool RegisterDialog::isUShort(const std::string &str) +{ + if (str.empty()) + { + return false; + } + unsigned long l = 0; + for (std::string::const_iterator strPtr = str.begin(), strEnd = str.end(); + strPtr != strEnd; ++strPtr) + { + if (*strPtr < '0' || *strPtr > '9') + { + return false; + } + l = l * 10 + (*strPtr - '0'); // *strPtr - '0' will never be negative + if (l > 65535) + { + return false; + } + } + return true; +} + +unsigned short RegisterDialog::getUShort(const std::string &str) +{ + unsigned long l = 0; + for (std::string::const_iterator strPtr = str.begin(), strEnd = str.end(); + strPtr != strEnd; ++strPtr) + { + l = l * 10 + (*strPtr - '0'); + } + return static_cast<unsigned short>(l); +} +#endif diff --git a/src/gui/register.h b/src/gui/register.h index 79578461..fde82a40 100644 --- a/src/gui/register.h +++ b/src/gui/register.h @@ -1,33 +1,33 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TMW_REGISTER_H -#define _TMW_REGISTER_H +#ifndef REGISTER_H +#define REGISTER_H + +#include <string> -#include <iosfwd> #include <guichan/actionlistener.hpp> #include <guichan/keylistener.hpp> #include "window.h" -#include "../guichanfwd.h" class LoginData; class OkDialog; @@ -82,16 +82,44 @@ class RegisterDialog : public Window, public gcn::ActionListener, * Returns whether submit can be enabled. This is true in the register * state, when all necessary fields have some text. */ - bool - canSubmit(); + bool canSubmit() const; + +#ifdef EATHENA_SUPPORT + /** + * Function to decide whether string is an unsigned short or not + * + * @param str the string to parse + * + * @return true if str is an unsigned short, false otherwise + */ + static bool isUShort(const std::string &str); + + /** + * Converts string to an unsigned short (undefined if invalid) + * + * @param str the string to parse + * + * @return the value str represents + */ + static unsigned short getUShort(const std::string &str); +#endif gcn::TextField *mUserField; gcn::TextField *mPasswordField; gcn::TextField *mConfirmField; +#ifdef EATHENA_SUPPORT + gcn::TextField *mServerField; + gcn::TextField *mPortField; +#else gcn::TextField *mEmailField; +#endif gcn::Button *mRegisterButton; gcn::Button *mCancelButton; +#ifdef EATHENA_SUPPORT + gcn::RadioButton *mMaleButton; + gcn::RadioButton *mFemaleButton; +#endif WrongDataNoticeListener *mWrongDataNoticeListener; diff --git a/src/gui/scrollarea.cpp b/src/gui/scrollarea.cpp index 032e3f78..70504a03 100644 --- a/src/gui/scrollarea.cpp +++ b/src/gui/scrollarea.cpp @@ -1,28 +1,27 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include <algorithm> - #include "scrollarea.h" +#include "../configuration.h" #include "../graphics.h" #include "../resources/image.h" @@ -31,20 +30,21 @@ #include "../utils/dtor.h" int ScrollArea::instances = 0; +float ScrollArea::mAlpha = config.getValue("guialpha", 0.8); ImageRect ScrollArea::background; ImageRect ScrollArea::vMarker; Image *ScrollArea::buttons[4][2]; -ScrollArea::ScrollArea(bool gc): +ScrollArea::ScrollArea(): gcn::ScrollArea(), - mGC(gc) + mOpaque(true) { init(); } -ScrollArea::ScrollArea(gcn::Widget *widget, bool gc): +ScrollArea::ScrollArea(gcn::Widget *widget): gcn::ScrollArea(widget), - mGC(gc) + mOpaque(true) { init(); } @@ -52,9 +52,7 @@ ScrollArea::ScrollArea(gcn::Widget *widget, bool gc): ScrollArea::~ScrollArea() { // Garbage collection - if (mGC) { - delete getContent(); - } + delete getContent(); instances--; @@ -88,12 +86,15 @@ void ScrollArea::init() const int bggridy[4] = {0, 3, 28, 31}; int a = 0, x, y; - for (y = 0; y < 3; y++) { - for (x = 0; x < 3; x++) { + for (y = 0; y < 3; y++) + { + for (x = 0; x < 3; x++) + { background.grid[a] = textbox->getSubImage( bggridx[x], bggridy[y], bggridx[x + 1] - bggridx[x] + 1, bggridy[y + 1] - bggridy[y] + 1); + background.grid[a]->setAlpha(config.getValue("guialpha", 0.8)); a++; } } @@ -106,12 +107,15 @@ void ScrollArea::init() int vsgridy[4] = {0, 4, 15, 19}; a = 0; - for (y = 0; y < 3; y++) { - for (x = 0; x < 3; x++) { + for (y = 0; y < 3; y++) + { + for (x = 0; x < 3; x++) + { vMarker.grid[a] = vscroll->getSubImage( vsgridx[x], vsgridy[y], vsgridx[x + 1] - vsgridx[x], vsgridy[y + 1] - vsgridy[y]); + vMarker.grid[a]->setAlpha(config.getValue("guialpha", 0.8)); a++; } } @@ -146,7 +150,7 @@ void ScrollArea::logic() // When no scrollbar in a certain direction, adapt content size to match // the content dimension exactly. - if (content != NULL) + if (content) { if (getHorizontalScrollPolicy() == gcn::ScrollArea::SHOW_NEVER) { @@ -188,6 +192,16 @@ void ScrollArea::draw(gcn::Graphics *graphics) mScrollbarWidth)); } + if (config.getValue("guialpha", 0.8) != mAlpha) + { + mAlpha = config.getValue("guialpha", 0.8); + for (int a = 0; a < 9; a++) + { + background.grid[a]->setAlpha(mAlpha); + vMarker.grid[a]->setAlpha(mAlpha); + } + } + drawChildren(graphics); } @@ -197,7 +211,8 @@ void ScrollArea::drawFrame(gcn::Graphics *graphics) int w = getWidth() + bs * 2; int h = getHeight() + bs * 2; - if (mOpaque) { + if (mOpaque) + { static_cast<Graphics*>(graphics)-> drawImageRect(0, 0, w, h, background); } @@ -207,10 +222,12 @@ void ScrollArea::setOpaque(bool opaque) { mOpaque = opaque; - if (mOpaque) { + if (mOpaque) + { setFrameSize(2); } - else { + else + { setFrameSize(0); } } @@ -220,7 +237,8 @@ void ScrollArea::drawButton(gcn::Graphics *graphics, BUTTON_DIR dir) int state = 0; gcn::Rectangle dim; - switch(dir) { + switch (dir) + { case UP: state = mUpButtonPressed ? 1 : 0; dim = getUpButtonDimension(); diff --git a/src/gui/scrollarea.h b/src/gui/scrollarea.h index d21dae11..e9aa5ed2 100644 --- a/src/gui/scrollarea.h +++ b/src/gui/scrollarea.h @@ -1,26 +1,26 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef __TMW_SCROLLAREA_H__ -#define __TMW_SCROLLAREA_H__ +#ifndef SCROLLAREA_H +#define SCROLLAREA_H #include <guichan/widgets/scrollarea.hpp> @@ -30,6 +30,10 @@ class ImageRect; /** * A scroll area. * + * Contrary to Guichan's scroll area, this scroll area takes ownership over its + * content. However, it won't delete a previously set content widget when + * setContent is called! + * * \ingroup GUI */ class ScrollArea : public gcn::ScrollArea @@ -38,12 +42,12 @@ class ScrollArea : public gcn::ScrollArea /** * Constructor. */ - ScrollArea(bool gc = true); + ScrollArea(); /** * Constructor. */ - ScrollArea(gcn::Widget *content, bool gc = true); + ScrollArea(gcn::Widget *content); /** * Destructor. @@ -100,12 +104,12 @@ class ScrollArea : public gcn::ScrollArea void drawHMarker(gcn::Graphics *graphics); static int instances; + static float mAlpha; static ImageRect background; static ImageRect vMarker; static Image *buttons[4][2]; bool mOpaque; - bool mGC; }; #endif diff --git a/src/gui/sdlinput.cpp b/src/gui/sdlinput.cpp index ee94b2c6..51442798 100644 --- a/src/gui/sdlinput.cpp +++ b/src/gui/sdlinput.cpp @@ -7,7 +7,7 @@ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/ * * Copyright (c) 2004, 2005, 2006, 2007 Olof Naessén and Per Larsson - * Copyright 2007 The Mana World Development Team + * Copyright (C) 2007 The Mana World Development Team * * Js_./ * Per Larsson a.k.a finalman _RqZ{a<^_aa @@ -228,7 +228,7 @@ int SDLInput::convertMouseButton(int button) int SDLInput::convertKeyCharacter(SDL_Event event) { SDL_keysym keysym = event.key.keysym; - + int value = keysym.unicode; switch (keysym.sym) diff --git a/src/gui/sdlinput.h b/src/gui/sdlinput.h index 72d949e1..3901589a 100644 --- a/src/gui/sdlinput.h +++ b/src/gui/sdlinput.h @@ -7,7 +7,7 @@ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/ * * Copyright (c) 2004, 2005, 2006, 2007 Olof Naessén and Per Larsson - * Copyright 2007 The Mana World Development Team + * Copyright (C) 2007 The Mana World Development Team * * Js_./ * Per Larsson a.k.a finalman _RqZ{a<^_aa @@ -55,8 +55,8 @@ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef _TMW_SDLINPUT_ -#define _TMW_SDLINPUT_ +#ifndef SDLINPUT_ +#define SDLINPUT_ #include <queue> diff --git a/src/gui/sell.cpp b/src/gui/sell.cpp index 9aee4bee..957ff861 100644 --- a/src/gui/sell.cpp +++ b/src/gui/sell.cpp @@ -1,47 +1,56 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "sell.h" - -#include <cassert> - #include <guichan/widgets/label.hpp> #include "button.h" -#include "shoplistbox.h" #include "scrollarea.h" +#include "sell.h" #include "shop.h" +#include "shoplistbox.h" #include "slider.h" #include "widgets/layout.h" -#include "../item.h" #include "../npc.h" +#include "../units.h" + +#include "../net/messageout.h" +#ifdef TMWSERV_SUPPORT #include "../net/gameserver/player.h" -#include "../resources/iteminfo.h" +#else +#include "../net/ea/protocol.h" +#endif + #include "../utils/gettext.h" #include "../utils/strprintf.h" +#ifdef TMWSERV_SUPPORT SellDialog::SellDialog(): Window(_("Sell")), +#else +SellDialog::SellDialog(Network *network): + Window(_("Sell")), + mNetwork(network), +#endif mMaxItems(0), mAmountItems(0) { setWindowName("Sell"); @@ -50,13 +59,14 @@ SellDialog::SellDialog(): setMinHeight(230); setDefaultSize(0, 0, 260, 230); - mShopItems = new ShopItems(); + mShopItems = new ShopItems; mShopItemList = new ShopListBox(mShopItems, mShopItems); mScrollArea = new ScrollArea(mShopItemList); mSlider = new Slider(1.0); mQuantityLabel = new gcn::Label("0"); - mMoneyLabel = new gcn::Label(strprintf(_("Price: %d GP / Total: %d GP"), 0, 0)); + mMoneyLabel = new gcn::Label(strprintf(_("Price: %s / Total: %s"), + "", "")); mIncreaseButton = new Button("+", "+", this); mDecreaseButton = new Button("-", "-", this); mSellButton = new Button(_("Sell"), "sell", this); @@ -111,12 +121,30 @@ void SellDialog::reset() updateButtonsAndLabels(); } +#ifdef TMWSERV_SUPPORT + void SellDialog::addItem(int item, int amount, int price) { mShopItems->addItem(item, amount, price); mShopItemList->adjustSize(); } +#else + +void SellDialog::addItem(const Item *item, int price) +{ + if (!item) + return; + + mShopItems->addItem( + item->getInvIndex(), item->getId(), + item->getQuantity(), price); + + mShopItemList->adjustSize(); +} + +#endif + void SellDialog::action(const gcn::ActionEvent &event) { int selectedItem = mShopItemList->getSelected(); @@ -124,7 +152,7 @@ void SellDialog::action(const gcn::ActionEvent &event) if (event.getId() == "quit") { setVisible(false); - current_npc = 0; + if (current_npc) current_npc->handleDeath(); return; } @@ -155,8 +183,17 @@ void SellDialog::action(const gcn::ActionEvent &event) else if (event.getId() == "sell" && mAmountItems > 0 && mAmountItems <= mMaxItems) { +#ifdef TMWSERV_SUPPORT Net::GameServer::Player::tradeWithNPC (mShopItems->at(selectedItem)->getId(), mAmountItems); +#else + // Attempt sell + MessageOut outMsg(mNetwork); + outMsg.writeInt16(CMSG_NPC_SELL_REQUEST); + outMsg.writeInt16(8); + outMsg.writeInt16(mShopItems->at(selectedItem)->getInvIndex()); + outMsg.writeInt16(mAmountItems); +#endif mMaxItems -= mAmountItems; mShopItems->getShop()->at(selectedItem)->setQuantity(mMaxItems); @@ -239,7 +276,7 @@ void SellDialog::updateButtonsAndLabels() // Update the quantity and money labels mQuantityLabel->setCaption(strprintf("%d / %d", mAmountItems, mMaxItems)); - mMoneyLabel->setCaption - (strprintf(_("Price: %d GP / Total: %d GP"), - income, mPlayerMoney + income)); + mMoneyLabel->setCaption(strprintf(_("Price: %s / Total: %s"), + Units::formatCurrency(income).c_str(), + Units::formatCurrency(mPlayerMoney - income).c_str())); } diff --git a/src/gui/sell.h b/src/gui/sell.h index 742c28fb..f64a6fd5 100644 --- a/src/gui/sell.h +++ b/src/gui/sell.h @@ -1,35 +1,38 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TMW_SELL_H -#define _TMW_SELL_H +#ifndef SELL_H +#define SELL_H #include <guichan/actionlistener.hpp> #include <guichan/selectionlistener.hpp> -#include "window.h" +#include <SDL_types.h> -#include "../guichanfwd.h" +#include "window.h" class Item; +#ifdef EATHENA_SUPPORT +class Network; +#endif class ShopItems; class ShopListBox; @@ -46,7 +49,11 @@ class SellDialog : public Window, gcn::ActionListener, gcn::SelectionListener * * @see Window::Window */ +#ifdef TMWSERV_SUPPORT SellDialog(); +#else + SellDialog(Network *network); +#endif /** * Destructor @@ -61,7 +68,11 @@ class SellDialog : public Window, gcn::ActionListener, gcn::SelectionListener /** * Adds an item to the inventory. */ +#ifdef TMWSERV_SUPPORT void addItem(int item, int amount, int price); +#else + void addItem(const Item *item, int price); +#endif /** * Called when receiving actions from the widgets. @@ -86,6 +97,9 @@ class SellDialog : public Window, gcn::ActionListener, gcn::SelectionListener */ void updateButtonsAndLabels(); +#ifdef EATHENA_SUPPORT + Network *mNetwork; +#endif gcn::Button *mSellButton; gcn::Button *mQuitButton; gcn::Button *mIncreaseButton; diff --git a/src/gui/serverdialog.cpp b/src/gui/serverdialog.cpp index b11aea6c..a8074b0c 100644 --- a/src/gui/serverdialog.cpp +++ b/src/gui/serverdialog.cpp @@ -41,7 +41,7 @@ #include "../main.h" #include "../utils/gettext.h" -#include "../utils/tostring.h" +#include "../utils/stringutils.h" const short MAX_SERVERLIST = 5; diff --git a/src/gui/setup.cpp b/src/gui/setup.cpp index 59b54be0..c8b7f900 100644 --- a/src/gui/setup.cpp +++ b/src/gui/setup.cpp @@ -1,71 +1,80 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include <algorithm> - -#include "setup.h" - #include "button.h" +#include "setup.h" #include "setup_audio.h" +#include "setup_colors.h" #include "setup_joystick.h" -#include "setup_video.h" #include "setup_keyboard.h" +#include "setup_players.h" +#include "setup_video.h" #include "widgets/tabbedarea.h" #include "../utils/dtor.h" #include "../utils/gettext.h" -extern Window *statusWindow; -extern Window *minimap; extern Window *chatWindow; -extern Window *inventoryWindow; extern Window *equipmentWindow; extern Window *helpWindow; +extern Window *inventoryWindow; +extern Window *minimap; extern Window *skillDialog; +extern Window *statusWindow; +extern Window *itemShortcutWindow; +extern Window *emoteShortcutWindow; +extern Window *emoteWindow; +extern Window *tradeWindow; +#ifdef TMWSERV_SUPPORT extern Window *magicDialog; extern Window *guildWindow; -extern Window *itemShortcutWindow; +#endif Setup::Setup(): Window(_("Setup")) { setCloseButton(true); - int width = 260; - int height = 265; + int width = 340; + int height = 340; setContentSize(width, height); static const char *buttonNames[] = { N_("Apply"), N_("Cancel"), N_("Reset Windows"), 0 }; int x = width; - for (const char **curBtn = buttonNames; *curBtn; ++curBtn) { + for (const char **curBtn = buttonNames; *curBtn; ++curBtn) + { Button *btn = new Button(gettext(*curBtn), *curBtn, this); x -= btn->getWidth() + 5; btn->setPosition(x, height - btn->getHeight() - 5); add(btn); + + // Disable this button when the windows aren't created yet + if (!strcmp(*curBtn, "Reset Windows")) + btn->setEnabled(statusWindow != NULL); } - TabbedArea *panel = new TabbedArea(); - panel->setDimension(gcn::Rectangle(5, 5, 260, 225)); + TabbedArea *panel = new TabbedArea; + panel->setDimension(gcn::Rectangle(5, 5, width - 10, height - 40)); SetupTab *tab; @@ -85,6 +94,14 @@ Setup::Setup(): panel->addTab(_("Keyboard"), tab); mTabs.push_back(tab); + tab = new Setup_Colors(); + panel->addTab(_("Colors"), tab); + mTabs.push_back(tab); + + tab = new Setup_Players(); + panel->addTab(_("Players"), tab); + mTabs.push_back(tab); + add(panel); setLocationRelativeTo(getParent()); @@ -109,6 +126,11 @@ void Setup::action(const gcn::ActionEvent &event) } else if (event.getId() == "Reset Windows") { + // Bail out if this action happens to be activated before the windows + // are created (though it should be disabled then) + if (!statusWindow) + return; + statusWindow->resetToDefaultSize(); minimap->resetToDefaultSize(); chatWindow->resetToDefaultSize(); @@ -116,8 +138,13 @@ void Setup::action(const gcn::ActionEvent &event) equipmentWindow->resetToDefaultSize(); helpWindow->resetToDefaultSize(); skillDialog->resetToDefaultSize(); + itemShortcutWindow->resetToDefaultSize(); + emoteShortcutWindow->resetToDefaultSize(); + emoteWindow->resetToDefaultSize(); + tradeWindow->resetToDefaultSize(); +#ifdef TMWSERV_SUPPORT magicDialog->resetToDefaultSize(); guildWindow->resetToDefaultSize(); - itemShortcutWindow->resetToDefaultSize(); +#endif } } diff --git a/src/gui/setup.h b/src/gui/setup.h index 2142a67d..e4eb0902 100644 --- a/src/gui/setup.h +++ b/src/gui/setup.h @@ -1,26 +1,26 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TMW_SETUP_H -#define _TMW_SETUP_H +#ifndef SETUP_H +#define SETUP_H #include <list> @@ -28,6 +28,8 @@ #include "window.h" +#include "../guichanfwd.h" + class SetupTab; /** @@ -51,8 +53,7 @@ class Setup : public Window, public gcn::ActionListener /** * Event handling method. */ - void - action(const gcn::ActionEvent &event); + void action(const gcn::ActionEvent &event); private: std::list<SetupTab*> mTabs; diff --git a/src/gui/setup_audio.cpp b/src/gui/setup_audio.cpp index 4f09cde0..43cc28e6 100644 --- a/src/gui/setup_audio.cpp +++ b/src/gui/setup_audio.cpp @@ -1,32 +1,33 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "setup_audio.h" - #include <guichan/widgets/label.hpp> #include "checkbox.h" #include "ok_dialog.h" +#include "setup_audio.h" #include "slider.h" +#include "widgets/layouthelper.h" + #include "../configuration.h" #include "../log.h" #include "../sound.h" @@ -54,19 +55,24 @@ Setup_Audio::Setup_Audio(): mMusicSlider->addActionListener(this); mSoundCheckBox->setPosition(10, 10); - mSfxSlider->setDimension(gcn::Rectangle(10, 30, 100, 10)); - mMusicSlider->setDimension(gcn::Rectangle(10, 50, 100, 10)); - sfxLabel->setPosition(20 + mSfxSlider->getWidth(), 27); - musicLabel->setPosition(20 + mMusicSlider->getWidth(), 47); mSfxSlider->setValue(mSfxVolume); mMusicSlider->setValue(mMusicVolume); - add(mSoundCheckBox); - add(mSfxSlider); - add(mMusicSlider); - add(sfxLabel); - add(musicLabel); + mSfxSlider->setWidth(90); + mMusicSlider->setWidth(90); + + // Do the layout + LayoutHelper h(this); + ContainerPlacer place = h.getPlacer(0, 0); + + place(0, 0, mSoundCheckBox); + place(0, 1, mSfxSlider); + place(1, 1, sfxLabel); + place(0, 2, mMusicSlider); + place(1, 2, musicLabel); + + setDimension(gcn::Rectangle(0, 0, 325, 280)); } void Setup_Audio::apply() @@ -104,8 +110,8 @@ void Setup_Audio::cancel() sound.setMusicVolume(mMusicVolume); mMusicSlider->setValue(mMusicVolume); - config.setValue("sound", mSoundEnabled ? 1 : 0); - config.setValue("sfxVolume", mSfxVolume ? 1 : 0); + config.setValue("sound", mSoundEnabled ? true : false); + config.setValue("sfxVolume", mSfxVolume); config.setValue("musicVolume", mMusicVolume); } diff --git a/src/gui/setup_audio.h b/src/gui/setup_audio.h index eaa55de6..9e951895 100644 --- a/src/gui/setup_audio.h +++ b/src/gui/setup_audio.h @@ -1,32 +1,30 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TMW_GUI_SETUP_AUDIO_H -#define _TMW_GUI_SETUP_AUDIO_H - -#include "setuptab.h" +#ifndef GUI_SETUP_AUDIO_H +#define GUI_SETUP_AUDIO_H #include <guichan/actionlistener.hpp> -#include "../guichanfwd.h" +#include "setuptab.h" class Setup_Audio : public SetupTab, public gcn::ActionListener { diff --git a/src/gui/setup_colors.cpp b/src/gui/setup_colors.cpp new file mode 100644 index 00000000..49c99996 --- /dev/null +++ b/src/gui/setup_colors.cpp @@ -0,0 +1,249 @@ +/* + * Configurable text colors + * Copyright (C) 2008 Douglas Boffey <dougaboffey@netscape.net> + * + * 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 <string> +#include <cmath> + +#include <guichan/listmodel.hpp> +#include <guichan/widgets/label.hpp> +#include <guichan/widgets/slider.hpp> + +#include "browserbox.h" +#include "color.h" +#include "itemlinkhandler.h" +#include "listbox.h" +#include "scrollarea.h" +#include "setup_colors.h" +#include "slider.h" +#include "textfield.h" + +#include "widgets/layouthelper.h" + +#include "../configuration.h" + +#include "../utils/gettext.h" +#include "../utils/stringutils.h" + +Setup_Colors::Setup_Colors() : + mSelected(-1) +{ + setOpaque(false); + + mColorBox = new ListBox(textColor); + mColorBox->setActionEventId("color_box"); + mColorBox->addActionListener(this); + + mScroll = new ScrollArea(mColorBox); + mScroll->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); + + mPreview = new BrowserBox(BrowserBox::AUTO_WRAP); + mPreview->setOpaque(false); + + // Replace this later with a more appropriate link handler. For now, this'll + // do, as it'll do nothing when clicked on. + mPreview->setLinkHandler(new ItemLinkHandler); + + mPreviewBox = new ScrollArea(mPreview); + mPreviewBox->setHeight(20); + mPreviewBox->setScrollPolicy(gcn::ScrollArea::SHOW_NEVER, + gcn::ScrollArea::SHOW_NEVER); + + mRedLabel = new gcn::Label(_("Red: ")); + + mRedText = new TextField; + mRedText->setWidth(40); + mRedText->setRange(0, 255); + mRedText->setNumeric(true); + mRedText->addListener(this); + + mRedSlider = new Slider(0, 255); + mRedSlider->setWidth(160); + mRedSlider->setValue(mRedText->getValue()); + mRedSlider->setActionEventId("slider_red"); + mRedSlider->addActionListener(this); + + mGreenLabel = new gcn::Label(_("Green: ")); + + mGreenText = new TextField; + mGreenText->setWidth(40); + mGreenText->setRange(0, 255); + mGreenText->setNumeric(true); + mGreenText->addListener(this); + + mGreenSlider = new Slider(0, 255); + mGreenSlider->setWidth(160); + mGreenSlider->setValue(mGreenText->getValue()); + mGreenSlider->setActionEventId("slider_green"); + mGreenSlider->addActionListener(this); + + mBlueLabel = new gcn::Label(_("Blue: ")); + + mBlueText = new TextField; + mBlueText->setWidth(40); + mBlueText->setRange(0, 255); + mBlueText->setNumeric(true); + mBlueText->addListener(this); + + mBlueSlider = new Slider(0, 255); + mBlueSlider->setWidth(160); + mBlueSlider->setValue(mBlueText->getValue()); + mBlueSlider->setActionEventId("slider_blue"); + mBlueSlider->addActionListener(this); + + setOpaque(false); + + // Do the layout + LayoutHelper h(this); + ContainerPlacer place = h.getPlacer(0, 0); + + place(0, 0, mScroll, 4, 7).setPadding(2); + place(0, 7, mPreviewBox, 4).setPadding(2); + place(0, 8, mRedLabel, 2); + place(2, 8, mRedSlider); + place(3, 8, mRedText).setPadding(1); + place(0, 9, mGreenLabel, 2); + place(2, 9, mGreenSlider); + place(3, 9, mGreenText).setPadding(1); + place(0, 10, mBlueLabel, 2); + place(2, 10, mBlueSlider); + place(3, 10, mBlueText).setPadding(1); + + setDimension(gcn::Rectangle(0, 0, 325, 280)); +} + +Setup_Colors::~Setup_Colors() +{ + delete mRedLabel; + delete mRedSlider; + delete mRedText; + + delete mGreenLabel; + delete mGreenSlider; + delete mGreenText; + + delete mBlueLabel; + delete mBlueSlider; + delete mBlueText; + + delete mScroll; +} + +void Setup_Colors::action(const gcn::ActionEvent &event) +{ + if (event.getId() == "color_box") + { + mSelected = mColorBox->getSelected(); + int col = textColor->getColorAt(mSelected); + char ch = textColor->getColorCharAt(mSelected); + std::string msg; + + if (ch == '<') + msg = toString("@@|") + + _("This is what the color looks like") + "@@"; + else + msg = "##" + toString(ch) + + _("This is what the color looks like"); + + mPreview->clearRows(); + mPreview->addRow(msg); + setEntry(mRedSlider, mRedText, col >> 16); + setEntry(mGreenSlider, mGreenText, (col >> 8) & 0xff); + setEntry(mBlueSlider, mBlueText, col & 0xff); + return; + } + + if (event.getId() == "slider_red") + { + mRedText->setText(toString(std::floor(mRedSlider->getValue()))); + updateColor(); + return; + } + + if (event.getId() == "slider_green") + { + mGreenText->setText(toString(std::floor(mGreenSlider->getValue()))); + updateColor(); + return; + } + + if (event.getId() == "slider_blue") + { + mBlueText->setText(toString(std::floor(mBlueSlider->getValue()))); + updateColor(); + return; + } +} + +void Setup_Colors::setEntry(gcn::Slider *s, TextField *t, int value) +{ + s->setValue(value); + char buffer[100]; + sprintf(buffer, "%d", value); + t->setText(buffer); +} + +void Setup_Colors::apply() +{ + textColor->commit(); +} + +void Setup_Colors::cancel() +{ + textColor->rollback(); + int col = textColor->getColorAt(mSelected); + setEntry(mRedSlider, mRedText, col >> 16); + setEntry(mGreenSlider, mGreenText, (col >> 8) & 0xff); + setEntry(mBlueSlider, mBlueText, col & 0xff); +} + +void Setup_Colors::listen(const TextField *tf) +{ + if (tf == mRedText) + { + mRedSlider->setValue(tf->getValue()); + updateColor(); + return; + } + if (tf == mGreenText) + { + mGreenSlider->setValue(tf->getValue()); + updateColor(); + return; + } + if (tf == mBlueText) + { + mBlueSlider->setValue(tf->getValue()); + updateColor(); + return; + } +} + +void Setup_Colors::updateColor() +{ + if (mSelected == -1) + { + return; + } + int rgb = static_cast<int>(mRedSlider->getValue()) << 16 | + static_cast<int>(mGreenSlider->getValue()) << 8 | + static_cast<int>(mBlueSlider->getValue()); + textColor->setColorAt(mSelected, rgb); +} diff --git a/src/gui/setup_colors.h b/src/gui/setup_colors.h new file mode 100644 index 00000000..2831297f --- /dev/null +++ b/src/gui/setup_colors.h @@ -0,0 +1,75 @@ +/* + * Configurable text colors + * Copyright (C) 2008 Douglas Boffey <dougaboffey@netscape.net> + * + * 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 SETUP_COLORS_H +#define SETUP_COLORS_H + +#include <string> + +#include <guichan/actionlistener.hpp> + +#include <guichan/widgets/label.hpp> +#include <guichan/widgets/listbox.hpp> + +#include "setuptab.h" +#include "textfield.h" + +#include "../guichanfwd.h" + +class BrowserBox; + +class Setup_Colors : public SetupTab, public gcn::ActionListener, + public TextFieldListener +{ + public: + Setup_Colors(); + ~Setup_Colors(); + void apply(); + void cancel(); + void action(const gcn::ActionEvent &event); + + void listen(const TextField *tf); + private: + gcn::ListBox *mColorBox; + gcn::ScrollArea *mScroll; + BrowserBox *mPreview; + gcn::ScrollArea *mPreviewBox; + int mSelected; + + gcn::Label *mRedLabel; + gcn::Slider *mRedSlider; + TextField *mRedText; + int mRedValue; + + gcn::Label *mGreenLabel; + gcn::Slider *mGreenSlider; + TextField *mGreenText; + int mGreenValue; + + gcn::Label *mBlueLabel; + gcn::Slider *mBlueSlider; + TextField *mBlueText; + int mBlueValue; + + void setEntry(gcn::Slider *s, TextField *t, int value); + void updateColor(); +}; +#endif diff --git a/src/gui/setup_joystick.cpp b/src/gui/setup_joystick.cpp index 9de5be9f..c0c04949 100644 --- a/src/gui/setup_joystick.cpp +++ b/src/gui/setup_joystick.cpp @@ -1,30 +1,32 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "setup_joystick.h" - #include <guichan/widgets/label.hpp> #include "button.h" #include "checkbox.h" +#include "setup_joystick.h" + +#include "widgets/layouthelper.h" + #include "../configuration.h" #include "../joystick.h" @@ -38,25 +40,29 @@ Setup_Joystick::Setup_Joystick(): mJoystickEnabled(new CheckBox(_("Enable joystick"))) { setOpaque(false); - setDimension(gcn::Rectangle(0, 0, 250, 200)); - mJoystickEnabled->setPosition(10, 10); - mCalibrateLabel->setPosition(10, 25); - mCalibrateButton->setPosition(10, 30 + mCalibrateLabel->getHeight()); - - mOriginalJoystickEnabled = (int)config.getValue("joystickEnabled", 0) != 0; + mOriginalJoystickEnabled = !config.getValue("joystickEnabled", false); mJoystickEnabled->setSelected(mOriginalJoystickEnabled); mJoystickEnabled->addActionListener(this); - add(mCalibrateLabel); - add(mCalibrateButton); - add(mJoystickEnabled); + // Do the layout + LayoutHelper h(this); + ContainerPlacer place = h.getPlacer(0, 0); + + place(0, 0, mJoystickEnabled); + place(0, 1, mCalibrateLabel); + place.getCell().matchColWidth(0, 0); + place = h.getPlacer(0, 1); + place(0, 0, mCalibrateButton); + + setDimension(gcn::Rectangle(0, 0, 325, 75)); } void Setup_Joystick::action(const gcn::ActionEvent &event) { - if (!joystick) { + if (!joystick) + { return; } @@ -66,12 +72,15 @@ void Setup_Joystick::action(const gcn::ActionEvent &event) } else { - if (joystick->isCalibrating()) { + if (joystick->isCalibrating()) + { mCalibrateButton->setCaption(_("Calibrate")); mCalibrateLabel->setCaption (_("Press the button to start calibration")); joystick->finishCalibration(); - } else { + } + else + { mCalibrateButton->setCaption(_("Stop")); mCalibrateLabel->setCaption(_("Rotate the stick")); joystick->startCalibration(); diff --git a/src/gui/setup_joystick.h b/src/gui/setup_joystick.h index 0b7ebe98..eba8a2cc 100644 --- a/src/gui/setup_joystick.h +++ b/src/gui/setup_joystick.h @@ -1,32 +1,30 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TMW_GUI_SETUP_JOYSTICK_H -#define _TMW_GUI_SETUP_JOYSTICK_H - -#include "setuptab.h" +#ifndef GUI_SETUP_JOYSTICK_H +#define GUI_SETUP_JOYSTICK_H #include <guichan/actionlistener.hpp> -#include "../guichanfwd.h" +#include "setuptab.h" class Setup_Joystick : public SetupTab, public gcn::ActionListener { diff --git a/src/gui/setup_keyboard.cpp b/src/gui/setup_keyboard.cpp index e4d1af0c..aba8cf35 100644 --- a/src/gui/setup_keyboard.cpp +++ b/src/gui/setup_keyboard.cpp @@ -1,25 +1,26 @@ /* - * The Mana World - * Copyright 2007 The Mana World Development Team + * Custom keyboard shortcuts configuration + * Copyright (C) 2007 Joshua Langley <joshlangley@optusnet.com.au> + * Copyright (C) 2009 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "setup_keyboard.h" +#include <SDL_keyboard.h> #include <guichan/widgets/label.hpp> #include <guichan/listmodel.hpp> @@ -28,14 +29,14 @@ #include "listbox.h" #include "ok_dialog.h" #include "scrollarea.h" +#include "setup_keyboard.h" + +#include "widgets/layouthelper.h" -#include "../configuration.h" #include "../keyboardconfig.h" #include "../utils/gettext.h" -#include "../utils/tostring.h" - -#include <SDL_keyboard.h> +#include "../utils/stringutils.h" /** * The list model for key function list. @@ -68,34 +69,36 @@ class KeyListModel : public gcn::ListModel }; Setup_Keyboard::Setup_Keyboard(): - mKeyListModel(new KeyListModel()), + mKeyListModel(new KeyListModel), mKeyList(new ListBox(mKeyListModel)), mKeySetting(false) { keyboard.setSetupKeyboard(this); setOpaque(false); - setDimension(gcn::Rectangle(0, 0, 250, 200)); refreshKeys(); - mKeyList->setDimension(gcn::Rectangle(0, 0, 185, 140)); mKeyList->addActionListener(this); - mKeyList->setSelected(-1); ScrollArea *scrollArea = new ScrollArea(mKeyList); - scrollArea->setDimension(gcn::Rectangle(10, 10, 200, 140)); - add(scrollArea); + scrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); mAssignKeyButton = new Button(_("Assign"), "assign", this); - mAssignKeyButton->setPosition(165, 155); mAssignKeyButton->addActionListener(this); mAssignKeyButton->setEnabled(false); - add(mAssignKeyButton); mMakeDefaultButton = new Button(_("Default"), "makeDefault", this); - mMakeDefaultButton->setPosition(10, 155); mMakeDefaultButton->addActionListener(this); - add(mMakeDefaultButton); + + // Do the layout + LayoutHelper h(this); + ContainerPlacer place = h.getPlacer(0, 0); + + place(0, 0, scrollArea, 4, 6).setPadding(2); + place(0, 6, mMakeDefaultButton); + place(3, 6, mAssignKeyButton); + + setDimension(gcn::Rectangle(0, 0, 325, 280)); } Setup_Keyboard::~Setup_Keyboard() @@ -135,9 +138,8 @@ void Setup_Keyboard::action(const gcn::ActionEvent &event) { if (event.getSource() == mKeyList) { - if (!mKeySetting) { + if (!mKeySetting) mAssignKeyButton->setEnabled(true); - } } else if (event.getId() == "assign") { @@ -181,7 +183,8 @@ void Setup_Keyboard::refreshKeys() void Setup_Keyboard::keyUnresolved() { - if (mKeySetting) { + if (mKeySetting) + { newKeyCallback(keyboard.getNewKeyIndex()); keyboard.setNewKeyIndex(keyboard.KEY_NO_VALUE); } diff --git a/src/gui/setup_keyboard.h b/src/gui/setup_keyboard.h index 50fa76fb..dee12135 100644 --- a/src/gui/setup_keyboard.h +++ b/src/gui/setup_keyboard.h @@ -1,35 +1,34 @@ /* - * The Mana World - * Copyright 2007 The Mana World Development Team + * Custom keyboard shortcuts configuration + * Copyright (C) 2007 Joshua Langley <joshlangley@optusnet.com.au> * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TMW_GUI_SETUP_KEYBOARD_H -#define _TMW_GUI_SETUP_KEYBOARD_H +#ifndef GUI_SETUP_KEYBOARD_H +#define GUI_SETUP_KEYBOARD_H -#include "setuptab.h" -#include "button.h" -#include "../guichanfwd.h" +#include <string> #include <guichan/actionlistener.hpp> +#include "setuptab.h" -#include <string> +#include "../guichanfwd.h" class Setup_Keyboard : public SetupTab, public gcn::ActionListener { diff --git a/src/gui/setup_players.cpp b/src/gui/setup_players.cpp new file mode 100644 index 00000000..96792436 --- /dev/null +++ b/src/gui/setup_players.cpp @@ -0,0 +1,388 @@ +/* + * 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 <string> +#include <vector> + +#include <guichan/widgets/label.hpp> + +#include "button.h" +#include "checkbox.h" +#include "listbox.h" +#include "ok_dialog.h" +#include "scrollarea.h" +#include "setup_players.h" +#include "table.h" + +#include "widgets/dropdown.h" +#include "widgets/layouthelper.h" + +#include "../configuration.h" +#include "../log.h" + +#include "../utils/gettext.h" + +#define COLUMNS_NR 2 // name plus listbox +#define NAME_COLUMN 0 +#define RELATION_CHOICE_COLUMN 1 + +#define ROW_HEIGHT 12 +// The following column widths really shouldn't be hardcoded but should scale with the size of the widget... except +// that, right now, the widget doesn't exactly scale either. +#define NAME_COLUMN_WIDTH 230 +#define RELATION_CHOICE_COLUMN_WIDTH 80 + +#define WIDGET_AT(row, column) (((row) * COLUMNS_NR) + column) + +static const char *table_titles[COLUMNS_NR] = +{ + N_("Name"), + N_("Relation") +}; + +static const char *RELATION_NAMES[PlayerRelation::RELATIONS_NR] = +{ + N_("Neutral"), + N_("Friend"), + N_("Disregarded"), + N_("Ignored") +}; + +class PlayerRelationListModel : public gcn::ListModel +{ +public: + virtual ~PlayerRelationListModel() { } + + virtual int getNumberOfElements() + { + return PlayerRelation::RELATIONS_NR; + } + + virtual std::string getElementAt(int i) + { + if (i >= getNumberOfElements() || i < 0) + return ""; + return gettext(RELATION_NAMES[i]); + } +}; + +class PlayerTableModel : public TableModel +{ +public: + PlayerTableModel() : + mPlayers(NULL) + { + playerRelationsUpdated(); + } + + virtual ~PlayerTableModel() + { + freeWidgets(); + if (mPlayers) + delete mPlayers; + } + + virtual int getRows() + { + return mPlayers->size(); + } + + virtual int getColumns() + { + return COLUMNS_NR; + } + + virtual int getRowHeight() + { + return ROW_HEIGHT; + } + + virtual int getColumnWidth(int index) + { + if (index == NAME_COLUMN) + return NAME_COLUMN_WIDTH; + else + return RELATION_CHOICE_COLUMN_WIDTH; + } + + virtual void playerRelationsUpdated() + { + signalBeforeUpdate(); + + freeWidgets(); + std::vector<std::string> *player_names = player_relations.getPlayers(); + if (mPlayers) + delete mPlayers; + mPlayers = player_names; + + // set up widgets + for (unsigned int r = 0; r < player_names->size(); ++r) + { + std::string name = (*player_names)[r]; + gcn::Widget *widget = new gcn::Label(name); + mWidgets.push_back(widget); + gcn::ListModel *playerRelation = new PlayerRelationListModel; + + gcn::DropDown *choicebox = new DropDown(playerRelation, + new ScrollArea, + new ListBox(playerRelation), + false); + choicebox->setSelected(player_relations.getRelation(name)); + mWidgets.push_back(choicebox); + } + + signalAfterUpdate(); + } + + virtual void updateModelInRow(int row) + { + gcn::DropDown *choicebox = dynamic_cast<gcn::DropDown *>( + getElementAt(row, RELATION_CHOICE_COLUMN)); + player_relations.setRelation(getPlayerAt(row), + static_cast<PlayerRelation::relation>( + choicebox->getSelected())); + } + + + virtual gcn::Widget *getElementAt(int row, int column) + { + return mWidgets[WIDGET_AT(row, column)]; + } + + virtual void freeWidgets() + { + if (mPlayers) + delete mPlayers; + mPlayers = NULL; + + for (std::vector<gcn::Widget *>::const_iterator it = mWidgets.begin(); + it != mWidgets.end(); it++) + { + delete *it; + } + + mWidgets.clear(); + } + + std::string getPlayerAt(int index) + { + return (*mPlayers)[index]; + } + +protected: + std::vector<std::string> *mPlayers; + std::vector<gcn::Widget *> mWidgets; +}; + +/** + * Class for choosing one of the various `what to do when ignoring a player' options + */ +class IgnoreChoicesListModel : public gcn::ListModel +{ +public: + virtual ~IgnoreChoicesListModel() { } + + virtual int getNumberOfElements() + { + return player_relations.getPlayerIgnoreStrategies()->size(); + } + + virtual std::string getElementAt(int i) + { + if (i >= getNumberOfElements()) + return _("???"); + + return (*player_relations.getPlayerIgnoreStrategies())[i]->mDescription; + } +}; + +#define ACTION_DELETE "delete" +#define ACTION_TABLE "table" +#define ACTION_STRATEGY "strategy" + +Setup_Players::Setup_Players(): + mPlayerTableTitleModel(new StaticTableModel(1, COLUMNS_NR)), + mPlayerTableModel(new PlayerTableModel), + mPlayerTable(new GuiTable(mPlayerTableModel)), + mPlayerTitleTable(new GuiTable(mPlayerTableTitleModel)), + mPlayerScrollArea(new ScrollArea(mPlayerTable)), + mPersistIgnores(new CheckBox(_("Save player list"), + player_relations.getPersistIgnores())), + mDefaultTrading(new CheckBox(_("Allow trading"), + player_relations.getDefault() & PlayerRelation::TRADE)), + mDefaultWhisper(new CheckBox(_("Allow whispers"), + player_relations.getDefault() & PlayerRelation::WHISPER)), + mDeleteButton(new Button(_("Delete"), ACTION_DELETE, this)) +{ + setOpaque(false); + mPlayerTable->setOpaque(false); + + mPlayerTableTitleModel->fixColumnWidth(NAME_COLUMN, NAME_COLUMN_WIDTH); + mPlayerTableTitleModel->fixColumnWidth(RELATION_CHOICE_COLUMN, + RELATION_CHOICE_COLUMN_WIDTH); + mPlayerTitleTable->setBackgroundColor(gcn::Color(0xbf, 0xbf, 0xbf)); + + gcn::ListModel *ignoreChoices = new IgnoreChoicesListModel; + mIgnoreActionChoicesBox = new DropDown(ignoreChoices, new ScrollArea, + new ListBox(ignoreChoices), false); + + for (int i = 0; i < COLUMNS_NR; i++) + { + mPlayerTableTitleModel->set(0, i, + new gcn::Label(gettext(table_titles[i]))); + } + + mPlayerTitleTable->setLinewiseSelection(true); + + mPlayerScrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); + mPlayerTable->setActionEventId(ACTION_TABLE); + mPlayerTable->setLinewiseSelection(true); + mPlayerTable->addActionListener(this); + + gcn::Label *ignore_action_label = new gcn::Label(_("When ignoring:")); + + mIgnoreActionChoicesBox->setActionEventId(ACTION_STRATEGY); + mIgnoreActionChoicesBox->addActionListener(this); + + int ignore_strategy_index = 0; // safe default + + if (player_relations.getPlayerIgnoreStrategy()) + { + ignore_strategy_index = player_relations.getPlayerIgnoreStrategyIndex( + player_relations.getPlayerIgnoreStrategy()->mShortName); + if (ignore_strategy_index < 0) + ignore_strategy_index = 0; + } + mIgnoreActionChoicesBox->setSelected(ignore_strategy_index); + mIgnoreActionChoicesBox->adjustHeight(); + + reset(); + + // Do the layout + LayoutHelper h(this); + ContainerPlacer place = h.getPlacer(0, 0); + + place(0, 0, mPlayerTitleTable, 4); + place(0, 1, mPlayerScrollArea, 4, 4).setPadding(2); + place(0, 5, mDeleteButton); + place(2, 5, ignore_action_label); + place(2, 6, mIgnoreActionChoicesBox, 2).setPadding(2); + place(2, 7, mPersistIgnores); + place(2, 8, mDefaultTrading); + place(2, 9, mDefaultWhisper); + + player_relations.addListener(this); + + setDimension(gcn::Rectangle(0, 0, 325, 280)); +} + +Setup_Players::~Setup_Players() +{ + player_relations.removeListener(this); +} + + +void Setup_Players::reset() +{ + // We now have to search through the list of ignore choices to find the + // current selection. We could use an index into the table of config + // options in player_relations instead of strategies to sidestep this. + int selection = 0; + for (unsigned int i = 0; + i < player_relations.getPlayerIgnoreStrategies()->size(); + ++i) + if ((*player_relations.getPlayerIgnoreStrategies())[i] == + player_relations.getPlayerIgnoreStrategy()) + { + + selection = i; + break; + } + + mIgnoreActionChoicesBox->setSelected(selection); +} + +void Setup_Players::apply() +{ + player_relations.setPersistIgnores(mPersistIgnores->isSelected()); + player_relations.store(); + + unsigned int old_default_relations = player_relations.getDefault() & + ~(PlayerRelation::TRADE | + PlayerRelation::WHISPER); + player_relations.setDefault(old_default_relations + | (mDefaultTrading->isSelected() ? + PlayerRelation::TRADE : 0) + | (mDefaultWhisper->isSelected() ? + PlayerRelation::WHISPER : 0)); +} + +void Setup_Players::cancel() +{ +} + +void Setup_Players::action(const gcn::ActionEvent &event) +{ + if (event.getId() == ACTION_TABLE) + { + // temporarily eliminate ourselves: we are fully aware of this change, + // so there is no need for asynchronous updates. (In fact, thouse + // might destroy the widet that triggered them, which would be rather + // embarrassing.) + player_relations.removeListener(this); + + int row = mPlayerTable->getSelectedRow(); + if (row >= 0) + mPlayerTableModel->updateModelInRow(row); + + player_relations.addListener(this); + + } + else if (event.getId() == ACTION_DELETE) + { + int player_index = mPlayerTable->getSelectedRow(); + + if (player_index < 0) + return; + + std::string name = mPlayerTableModel->getPlayerAt(player_index); + + player_relations.removePlayer(name); + + } + else if (event.getId() == ACTION_STRATEGY) + { + PlayerIgnoreStrategy *s = + (*player_relations.getPlayerIgnoreStrategies())[ + mIgnoreActionChoicesBox->getSelected()]; + + player_relations.setPlayerIgnoreStrategy(s); + } +} + +void Setup_Players::updatedPlayer(const std::string &name) +{ + mPlayerTableModel->playerRelationsUpdated(); + mDefaultTrading->setSelected( + player_relations.getDefault() & PlayerRelation::TRADE); + mDefaultWhisper->setSelected( + player_relations.getDefault() & PlayerRelation::WHISPER); +} diff --git a/src/gui/setup_players.h b/src/gui/setup_players.h new file mode 100644 index 00000000..72d81f71 --- /dev/null +++ b/src/gui/setup_players.h @@ -0,0 +1,67 @@ +/* + * 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 + */ + +#ifndef GUI_SETUP_PLAYERS_H +#define GUI_SETUP_PLAYERS_H + +#include <guichan/actionlistener.hpp> + +#include "setuptab.h" + +#include "../player_relations.h" + +class GuiTable; +class PlayerTableModel; +class StaticTableModel; + +class Setup_Players : public SetupTab, + public gcn::ActionListener, + public PlayerRelationsListener +{ +public: + Setup_Players(); + virtual ~Setup_Players(); + + void apply(); + void cancel(); + + void reset(); + + void action(const gcn::ActionEvent &event); + + virtual void updatedPlayer(const std::string &name); + +private: + StaticTableModel *mPlayerTableTitleModel; + PlayerTableModel *mPlayerTableModel; + GuiTable *mPlayerTable; + GuiTable *mPlayerTitleTable; + gcn::ScrollArea *mPlayerScrollArea; + + gcn::CheckBox *mPersistIgnores; + gcn::CheckBox *mDefaultTrading; + gcn::CheckBox *mDefaultWhisper; + + gcn::Button *mDeleteButton; + gcn::DropDown *mIgnoreActionChoicesBox; +}; + +#endif diff --git a/src/gui/setup_video.cpp b/src/gui/setup_video.cpp index bac342a0..526c67ce 100644 --- a/src/gui/setup_video.cpp +++ b/src/gui/setup_video.cpp @@ -1,29 +1,27 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "setup_video.h" - +#include <SDL.h> #include <string> #include <vector> -#include <SDL.h> #include <guichan/key.hpp> #include <guichan/listmodel.hpp> @@ -34,16 +32,21 @@ #include "listbox.h" #include "ok_dialog.h" #include "scrollarea.h" +#include "setup_video.h" #include "slider.h" #include "textfield.h" +#include "widgets/layouthelper.h" + #include "../configuration.h" #include "../graphics.h" +#include "../localplayer.h" #include "../log.h" #include "../main.h" +#include "../particle.h" #include "../utils/gettext.h" -#include "../utils/tostring.h" +#include "../utils/stringutils.h" extern Graphics *graphics; @@ -101,18 +104,25 @@ ModeListModel::ModeListModel() } Setup_Video::Setup_Video(): - mFullScreenEnabled(config.getValue("screen", 0)), - mOpenGLEnabled(config.getValue("opengl", 0)), - mCustomCursorEnabled(config.getValue("customcursor", 1)), + mFullScreenEnabled(config.getValue("screen", false)), + mOpenGLEnabled(config.getValue("opengl", false)), + mCustomCursorEnabled(config.getValue("customcursor", true)), mVisibleNamesEnabled(config.getValue("visiblenames", 1)), + mParticleEffectsEnabled(config.getValue("particleeffects", true)), + mNameEnabled(config.getValue("showownname", false)), mOpacity(config.getValue("guialpha", 0.8)), mFps((int) config.getValue("fpslimit", 0)), + mSpeechMode((int) config.getValue("speech", 3)), mModeListModel(new ModeListModel), mModeList(new ListBox(mModeListModel)), mFsCheckBox(new CheckBox(_("Full screen"), mFullScreenEnabled)), mOpenGLCheckBox(new CheckBox(_("OpenGL"), mOpenGLEnabled)), mCustomCursorCheckBox(new CheckBox(_("Custom cursor"), mCustomCursorEnabled)), mVisibleNamesCheckBox(new CheckBox(_("Visible names"), mVisibleNamesEnabled)), + mParticleEffectsCheckBox(new CheckBox(_("Particle effects"), mParticleEffectsEnabled)), + mNameCheckBox(new CheckBox(_("Show name"), mNameEnabled)), + mSpeechSlider(new Slider(0, 3)), + mSpeechLabel(new gcn::Label("")), mAlphaSlider(new Slider(0.2, 1.0)), mFpsCheckBox(new CheckBox(_("FPS Limit:"))), mFpsSlider(new Slider(10, 200)), @@ -125,46 +135,47 @@ Setup_Video::Setup_Video(): mScrollRadiusField(new TextField), mOverlayDetail((int) config.getValue("OverlayDetail", 2)), mOverlayDetailSlider(new Slider(0, 2)), - mOverlayDetailField(new gcn::Label("")) + mOverlayDetailField(new gcn::Label("")), + mParticleDetail(3 - (int) config.getValue("particleEmitterSkip", 1)), + mParticleDetailSlider(new Slider(0, 3)), + mParticleDetailField(new gcn::Label("")) { setOpaque(false); - setDimension(gcn::Rectangle(0, 0, 250, 200)); ScrollArea *scrollArea = new ScrollArea(mModeList); - gcn::Label *alphaLabel = new gcn::Label(_("Gui opacity")); + scrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); - mModeList->setEnabled(false); + speechLabel = new gcn::Label(_("Overhead text")); + alphaLabel = new gcn::Label(_("Gui opacity")); + scrollRadiusLabel = new gcn::Label(_("Scroll radius")); + scrollLazinessLabel = new gcn::Label(_("Scroll laziness")); + overlayDetailLabel = new gcn::Label(_("Ambient FX")); + particleDetailLabel = new gcn::Label(_("Particle Detail")); + + mModeList->setEnabled(true); #ifndef USE_OPENGL mOpenGLCheckBox->setEnabled(false); #endif - mModeList->setDimension(gcn::Rectangle(0, 0, 60, 50)); - scrollArea->setDimension(gcn::Rectangle(10, 10, 90, 50)); - mFsCheckBox->setPosition(110, 10); - mOpenGLCheckBox->setPosition(110, 30); - mCustomCursorCheckBox->setPosition(110, 50); - mVisibleNamesCheckBox->setPosition(110, 70); - mAlphaSlider->setDimension(gcn::Rectangle(10, 100, 100, 10)); - alphaLabel->setPosition(20 + mAlphaSlider->getWidth(), - mAlphaSlider->getY()); - mFpsCheckBox->setPosition(90, 120); - mFpsSlider->setDimension(gcn::Rectangle(10, 120, 75, 10)); - mFpsField->setPosition(100 + mFpsCheckBox->getWidth(), 120); - mFpsField->setWidth(30); - mModeList->setSelected(-1); mAlphaSlider->setValue(mOpacity); + mAlphaSlider->setWidth(90); mFpsField->setText(toString(mFps)); mFpsField->setEnabled(mFps > 0); + mFpsField->setWidth(30); mFpsSlider->setValue(mFps); mFpsSlider->setEnabled(mFps > 0); mFpsCheckBox->setSelected(mFps > 0); + mModeList->setActionEventId("videomode"); mCustomCursorCheckBox->setActionEventId("customcursor"); mVisibleNamesCheckBox->setActionEventId("visiblenames"); + mParticleEffectsCheckBox->setActionEventId("particleeffects"); + mNameCheckBox->setActionEventId("showownname"); mAlphaSlider->setActionEventId("guialpha"); mFpsCheckBox->setActionEventId("fpslimitcheckbox"); + mSpeechSlider->setActionEventId("speech"); mFpsSlider->setActionEventId("fpslimitslider"); mScrollRadiusSlider->setActionEventId("scrollradiusslider"); mScrollRadiusField->setActionEventId("scrollradiusfield"); @@ -172,11 +183,17 @@ Setup_Video::Setup_Video(): mScrollLazinessField->setActionEventId("scrolllazinessfield"); mOverlayDetailSlider->setActionEventId("overlaydetailslider"); mOverlayDetailField->setActionEventId("overlaydetailfield"); + mParticleDetailSlider->setActionEventId("particledetailslider"); + mParticleDetailField->setActionEventId("particledetailfield"); + mModeList->addActionListener(this); mCustomCursorCheckBox->addActionListener(this); mVisibleNamesCheckBox->addActionListener(this); + mParticleEffectsCheckBox->addActionListener(this); + mNameCheckBox->addActionListener(this); mAlphaSlider->addActionListener(this); mFpsCheckBox->addActionListener(this); + mSpeechSlider->addActionListener(this); mFpsSlider->addActionListener(this); mFpsField->addKeyListener(this); mScrollRadiusSlider->addActionListener(this); @@ -185,28 +202,32 @@ Setup_Video::Setup_Video(): mScrollLazinessField->addKeyListener(this); mOverlayDetailSlider->addActionListener(this); mOverlayDetailField->addKeyListener(this); + mParticleDetailSlider->addActionListener(this); + mParticleDetailField->addKeyListener(this); - mScrollRadiusSlider->setDimension(gcn::Rectangle(10, 140, 75, 10)); - gcn::Label *scrollRadiusLabel = new gcn::Label(_("Scroll radius")); - scrollRadiusLabel->setPosition(90, 140); - mScrollRadiusField->setPosition(mFpsField->getX(), 140); - mScrollRadiusField->setWidth(30); mScrollRadiusField->setText(toString(mOriginalScrollRadius)); mScrollRadiusSlider->setValue(mOriginalScrollRadius); - mScrollLazinessSlider->setDimension(gcn::Rectangle(10, 160, 75, 10)); - gcn::Label *scrollLazinessLabel = new gcn::Label(_("Scroll laziness")); - scrollLazinessLabel->setPosition(90, 160); - mScrollLazinessField->setPosition(mFpsField->getX(), 160); - mScrollLazinessField->setWidth(30); mScrollLazinessField->setText(toString(mOriginalScrollLaziness)); mScrollLazinessSlider->setValue(mOriginalScrollLaziness); - mOverlayDetailSlider->setDimension(gcn::Rectangle(10, 180, 75, 10)); - gcn::Label *overlayDetailLabel = new gcn::Label(_("Ambient FX")); - overlayDetailLabel->setPosition(90, 180); - mOverlayDetailField->setPosition(180, 180); - mOverlayDetailField->setWidth(30); + switch (mSpeechMode) + { + case 0: + mSpeechLabel->setCaption(_("No text")); + break; + case 1: + mSpeechLabel->setCaption(_("Text")); + break; + case 2: + mSpeechLabel->setCaption(_("Bubbles, no names")); + break; + case 3: + mSpeechLabel->setCaption(_("Bubbles with names")); + break; + } + mSpeechSlider->setValue(mSpeechMode); + switch (mOverlayDetail) { case 0: @@ -221,37 +242,66 @@ Setup_Video::Setup_Video(): } mOverlayDetailSlider->setValue(mOverlayDetail); - add(scrollArea); - add(mFsCheckBox); - add(mOpenGLCheckBox); - add(mCustomCursorCheckBox); - add(mVisibleNamesCheckBox); - add(mAlphaSlider); - add(alphaLabel); - add(mFpsCheckBox); - add(mFpsSlider); - add(mFpsField); - add(mScrollRadiusSlider); - add(scrollRadiusLabel); - add(mScrollRadiusField); - add(mScrollLazinessSlider); - add(scrollLazinessLabel); - add(mScrollLazinessField); - add(mOverlayDetailSlider); - add(overlayDetailLabel); - add(mOverlayDetailField); -} - -Setup_Video::~Setup_Video() -{ - delete mModeListModel; + switch (mParticleDetail) + { + case 0: + mParticleDetailField->setCaption(_("low")); + break; + case 1: + mParticleDetailField->setCaption(_("medium")); + break; + case 2: + mParticleDetailField->setCaption(_("high")); + break; + case 3: + mParticleDetailField->setCaption(_("max")); + break; + } + mParticleDetailSlider->setValue(mParticleDetail); + + // Do the layout + LayoutHelper h(this); + ContainerPlacer place = h.getPlacer(0, 0); + + place(0, 0, scrollArea, 1, 6).setPadding(2); + place(1, 0, mFsCheckBox, 3); + place(1, 1, mOpenGLCheckBox, 3); + place(1, 2, mCustomCursorCheckBox, 3); + place(1, 3, mVisibleNamesCheckBox, 3); + place(1, 4, mNameCheckBox, 3); + place(1, 5, mParticleEffectsCheckBox, 3); + + place(0, 6, mAlphaSlider); + place(0, 7, mFpsSlider); + place(0, 8, mScrollRadiusSlider); + place(0, 9, mScrollLazinessSlider); + place(0, 10, mSpeechSlider); + place(0, 11, mOverlayDetailSlider); + place(0, 12, mParticleDetailSlider); + + place(1, 6, alphaLabel, 2); + place(1, 7, mFpsCheckBox).setPadding(3); + place(1, 8, scrollRadiusLabel); + place(1, 9, scrollLazinessLabel); + place(1, 10, speechLabel); + place(1, 11, overlayDetailLabel); + place(1, 12, particleDetailLabel); + + place(2, 7, mFpsField).setPadding(1); + place(2, 8, mScrollRadiusField).setPadding(1); + place(2, 9, mScrollLazinessField).setPadding(1); + place(2, 10, mSpeechLabel, 2).setPadding(2); + place(2, 11, mOverlayDetailField, 2).setPadding(2); + place(2, 12, mParticleDetailField, 2).setPadding(2); + + setDimension(gcn::Rectangle(0, 0, 325, 280)); } void Setup_Video::apply() { // Full screen changes bool fullscreen = mFsCheckBox->isSelected(); - if (fullscreen != (config.getValue("screen", 0) == 1)) + if (fullscreen != (config.getValue("screen", false) == 1)) { /* The OpenGL test is only necessary on Windows, since switching * to/from full screen works fine on Linux. On Windows we'd have to @@ -260,9 +310,9 @@ void Setup_Video::apply() * See http://libsdl.org/cgi/docwiki.cgi/SDL_SetVideoMode */ -#ifdef WIN32 +#if defined(WIN32) || defined(__APPLE__) // checks for opengl usage - if (!(config.getValue("opengl", 0) == 1)) + if (!(config.getValue("opengl", false) == 1)) { #endif if (!graphics->setFullscreen(fullscreen)) @@ -271,26 +321,26 @@ void Setup_Video::apply() if (!graphics->setFullscreen(fullscreen)) { std::stringstream error; - error << "Failed to switch to " << - (fullscreen ? "windowed" : "fullscreen") << - "mode and restoration of old mode also failed!" << + error << _("Failed to switch to ") << + (fullscreen ? _("windowed") : _("fullscreen")) << + _("mode and restoration of old mode also failed!") << std::endl; logger->error(error.str()); } } -#ifdef WIN32 +#if defined(WIN32) || defined(__APPLE__) } else { new OkDialog(_("Switching to full screen"), _("Restart needed for changes to take effect.")); } #endif - config.setValue("screen", fullscreen ? 1 : 0); + config.setValue("screen", fullscreen ? true : false); } // OpenGL change if (mOpenGLCheckBox->isSelected() != mOpenGLEnabled) { - config.setValue("opengl", mOpenGLCheckBox->isSelected() ? 1 : 0); + config.setValue("opengl", mOpenGLCheckBox->isSelected() ? true : false); // OpenGL can currently only be changed by restarting, notify user. new OkDialog(_("Changing OpenGL"), @@ -301,17 +351,19 @@ void Setup_Video::apply() config.setValue("fpslimit", mFps); // We sync old and new values at apply time - mFullScreenEnabled = config.getValue("screen", 0); - mCustomCursorEnabled = config.getValue("customcursor", 1); + mFullScreenEnabled = config.getValue("screen", false); + mCustomCursorEnabled = config.getValue("customcursor", true); mVisibleNamesEnabled = config.getValue("visiblenames", 1); + mParticleEffectsEnabled = config.getValue("particleeffects", true); + mNameEnabled = config.getValue("showownname", false); + mSpeechMode = (int) config.getValue("speech", 3); mOpacity = config.getValue("guialpha", 0.8); - mOverlayDetail = (int)config.getValue("OverlayDetail", 2); - mOpenGLEnabled = config.getValue("opengl", 0); + mOverlayDetail = (int) config.getValue("OverlayDetail", 2); + mOpenGLEnabled = config.getValue("opengl", false); } -int -Setup_Video::updateSlider(gcn::Slider *slider, gcn::TextField *field, - const std::string &configName) +int Setup_Video::updateSlider(gcn::Slider *slider, gcn::TextField *field, + const std::string &configName) { int value; std::stringstream temp(field->getText()); @@ -336,37 +388,94 @@ void Setup_Video::cancel() mOpenGLCheckBox->setSelected(mOpenGLEnabled); mCustomCursorCheckBox->setSelected(mCustomCursorEnabled); mVisibleNamesCheckBox->setSelected(mVisibleNamesEnabled); + mParticleEffectsCheckBox->setSelected(mParticleEffectsEnabled); + mSpeechSlider->setValue(mSpeechMode); + mNameCheckBox->setSelected(mNameEnabled); mAlphaSlider->setValue(mOpacity); mOverlayDetailSlider->setValue(mOverlayDetail); + mParticleDetailSlider->setValue(mParticleDetail); mScrollRadiusField->setText(toString(mOriginalScrollRadius)); mScrollLazinessField->setText(toString(mOriginalScrollLaziness)); updateSlider(mScrollRadiusSlider, mScrollRadiusField, "ScrollRadius"); updateSlider(mScrollLazinessSlider, mScrollLazinessField, "ScrollLaziness"); - config.setValue("screen", mFullScreenEnabled ? 1 : 0); - config.setValue("customcursor", mCustomCursorEnabled ? 1 : 0); + config.setValue("screen", mFullScreenEnabled ? true : false); + config.setValue("customcursor", mCustomCursorEnabled ? true : false); config.setValue("visiblenames", mVisibleNamesEnabled ? 1 : 0); + config.setValue("particleeffects", mParticleEffectsEnabled ? true : false); + config.setValue("speech", mSpeechMode); + config.setValue("showownname", mNameEnabled ? true : false); config.setValue("guialpha", mOpacity); - config.setValue("opengl", mOpenGLEnabled ? 1 : 0); + config.setValue("opengl", mOpenGLEnabled ? true : false); } void Setup_Video::action(const gcn::ActionEvent &event) { - if (event.getId() == "guialpha") + if (event.getId() == "videomode") + { + const std::string mode = mModeListModel->getElementAt(mModeList->getSelected()); + const int width = atoi(mode.substr(0, mode.find("x")).c_str()); + const int height = atoi(mode.substr(mode.find("x") + 1).c_str()); + + // TODO: Find out why the drawing area doesn't resize without a restart. + new OkDialog(_("Screen resolution changed"), + _("Restart your client for the change to take effect.")); + + config.setValue("screenwidth", width); + config.setValue("screenheight", height); + } + else if (event.getId() == "guialpha") { config.setValue("guialpha", mAlphaSlider->getValue()); } else if (event.getId() == "customcursor") { config.setValue("customcursor", - mCustomCursorCheckBox->isSelected() ? 1 : 0); + mCustomCursorCheckBox->isSelected() ? true : false); } else if (event.getId() == "visiblenames") { config.setValue("visiblenames", mVisibleNamesCheckBox->isSelected() ? 1 : 0); } + else if (event.getId() == "particleeffects") + { + config.setValue("particleeffects", + mParticleEffectsCheckBox->isSelected() ? true : false); + new OkDialog(_("Particle effect settings changed"), + _("Restart your client or change maps for the change to take effect.")); + } + else if (event.getId() == "speech") + { + int val = (int) mSpeechSlider->getValue(); + switch (val) + { + case 0: + mSpeechLabel->setCaption(_("No text")); + break; + case 1: + mSpeechLabel->setCaption(_("Text")); + break; + case 2: + mSpeechLabel->setCaption(_("Bubbles, no names")); + break; + case 3: + mSpeechLabel->setCaption(_("Bubbles with names")); + break; + } + mSpeechSlider->setValue(val); + config.setValue("speech", val); + } + else if (event.getId() == "showownname") + { + // Notify the local player that settings have changed for the name + // and requires an update + if (player_node) + player_node->mUpdateName = true; + config.setValue("showownname", + mNameCheckBox->isSelected() ? true : false); + } else if (event.getId() == "fpslimitslider") { mFps = (int) mFpsSlider->getValue(); @@ -401,6 +510,27 @@ void Setup_Video::action(const gcn::ActionEvent &event) } config.setValue("OverlayDetail", val); } + else if (event.getId() == "particledetailslider") + { + int val = (int) mParticleDetailSlider->getValue(); + switch (val) + { + case 0: + mParticleDetailField->setCaption(_("low")); + break; + case 1: + mParticleDetailField->setCaption(_("medium")); + break; + case 2: + mParticleDetailField->setCaption(_("high")); + break; + case 3: + mParticleDetailField->setCaption(_("max")); + break; + } + config.setValue("particleEmitterSkip", 3 - val); + Particle::emitterSkip = 4 - val; + } else if (event.getId() == "fpslimitcheckbox") { if (mFpsCheckBox->isSelected()) @@ -418,8 +548,7 @@ void Setup_Video::action(const gcn::ActionEvent &event) } } -void -Setup_Video::keyPressed(gcn::KeyEvent &event) +void Setup_Video::keyPressed(gcn::KeyEvent &event) { std::stringstream tempFps(mFpsField->getText()); diff --git a/src/gui/setup_video.h b/src/gui/setup_video.h index 17ca1241..44ecdfe5 100644 --- a/src/gui/setup_video.h +++ b/src/gui/setup_video.h @@ -1,40 +1,37 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TMW_GUI_SETUP_VIDEO_H -#define _TMW_GUI_SETUP_VIDEO_H - -#include "setuptab.h" +#ifndef GUI_SETUP_VIDEO_H +#define GUI_SETUP_VIDEO_H #include <guichan/actionlistener.hpp> #include <guichan/keylistener.hpp> -#include "../guichanfwd.h" +#include "setuptab.h" class Setup_Video : public SetupTab, public gcn::ActionListener, public gcn::KeyListener { public: Setup_Video(); - ~Setup_Video(); void apply(); void cancel(); @@ -42,25 +39,43 @@ class Setup_Video : public SetupTab, public gcn::ActionListener, void action(const gcn::ActionEvent &event); /** Called when key is pressed */ - void - keyPressed(gcn::KeyEvent &event); + void keyPressed(gcn::KeyEvent &event); private: + void updateSliders(bool originalValues); + + int updateSlider(gcn::Slider *slider, gcn::TextField *field, + const std::string &configName); + bool mFullScreenEnabled; bool mOpenGLEnabled; bool mCustomCursorEnabled; bool mVisibleNamesEnabled; + bool mParticleEffectsEnabled; + bool mNameEnabled; double mOpacity; int mFps; + int mSpeechMode; class ModeListModel *mModeListModel; + gcn::Label *speechLabel; + gcn::Label *alphaLabel; + gcn::Label *scrollRadiusLabel; + gcn::Label *scrollLazinessLabel; + gcn::Label *overlayDetailLabel; + gcn::Label *particleDetailLabel; + gcn::ListBox *mModeList; gcn::CheckBox *mFsCheckBox; gcn::CheckBox *mOpenGLCheckBox; gcn::CheckBox *mCustomCursorCheckBox; gcn::CheckBox *mVisibleNamesCheckBox; + gcn::CheckBox *mParticleEffectsCheckBox; + gcn::CheckBox *mNameCheckBox; + gcn::Slider *mSpeechSlider; + gcn::Label *mSpeechLabel; gcn::Slider *mAlphaSlider; gcn::CheckBox *mFpsCheckBox; gcn::Slider *mFpsSlider; @@ -78,12 +93,9 @@ class Setup_Video : public SetupTab, public gcn::ActionListener, gcn::Slider *mOverlayDetailSlider; gcn::Label *mOverlayDetailField; - void - updateSliders(bool originalValues); - - int - updateSlider(gcn::Slider *slider, gcn::TextField *field, - const std::string &configName); + int mParticleDetail; + gcn::Slider *mParticleDetailSlider; + gcn::Label *mParticleDetailField; }; #endif diff --git a/src/gui/setuptab.h b/src/gui/setuptab.h index 6c276c35..3e0c51e2 100644 --- a/src/gui/setuptab.h +++ b/src/gui/setuptab.h @@ -1,34 +1,34 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TMW_GUI_SETUPTAB_H -#define _TMW_GUI_SETUPTAB_H +#ifndef GUI_SETUPTAB_H +#define GUI_SETUPTAB_H #include "gccontainer.h" class SetupTab : public GCContainer { public: - virtual void apply() =0; - virtual void cancel() =0; + virtual void apply() = 0; + virtual void cancel() = 0; }; #endif diff --git a/src/gui/shop.cpp b/src/gui/shop.cpp index a521c75b..7b28cef4 100644 --- a/src/gui/shop.cpp +++ b/src/gui/shop.cpp @@ -1,21 +1,21 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ @@ -43,7 +43,16 @@ void ShopItems::addItem(int id, int amount, int price) mShopItems.push_back(new ShopItem(id, amount, price)); } -ShopItem* ShopItems::at(int i) +#ifdef EATHENA_SUPPORT +void ShopItems::addItem(int inventoryIndex, int id, int amount, int price) +{ + ShopItem *item = new ShopItem(id, amount, price); + item->setInvIndex(inventoryIndex); + mShopItems.push_back(item); +} +#endif + +ShopItem* ShopItems::at(int i) const { return mShopItems.at(i); } diff --git a/src/gui/shop.h b/src/gui/shop.h index 62b60cae..aa72bf2a 100644 --- a/src/gui/shop.h +++ b/src/gui/shop.h @@ -1,21 +1,21 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ @@ -27,10 +27,10 @@ #include <guichan/listmodel.hpp> -#include "../resources/image.h" - #include "../shopitem.h" +class ShopItem; + class ShopItems : public gcn::ListModel { public: @@ -40,10 +40,17 @@ class ShopItems : public gcn::ListModel ~ShopItems(); /** - * Adds an item and its associated picture. + * Adds an item to the list. */ void addItem(int id, int amount, int price); +#ifdef EATHENA_SUPPORT + /** + * Adds an item to the list (used by eAthena sell dialog). + */ + void addItem(int inventoryIndex, int id, int amount, int price); +#endif + /** * Returns the number of items in the shop. */ @@ -57,7 +64,7 @@ class ShopItems : public gcn::ListModel /** * Returns the item number i in the shop. */ - ShopItem* at(int i); + ShopItem* at(int i) const; /** * Clear the vector. diff --git a/src/gui/shoplistbox.cpp b/src/gui/shoplistbox.cpp index bce6a48c..8aed3c77 100644 --- a/src/gui/shoplistbox.cpp +++ b/src/gui/shoplistbox.cpp @@ -1,37 +1,38 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "shoplistbox.h" - #include <guichan/font.hpp> -#include <guichan/graphics.hpp> #include <guichan/listmodel.hpp> -#include <guichan/mouseinput.hpp> -#include <guichan/imagefont.hpp> -#include <guichan/basiccontainer.hpp> +#include "color.h" +#include "shop.h" +#include "shoplistbox.h" + +#include "../configuration.h" #include "../graphics.h" const int ITEM_ICON_SIZE = 32; +float ShopListBox::mAlpha = config.getValue("guialpha", 0.8); + ShopListBox::ShopListBox(gcn::ListModel *listModel): ListBox(listModel), mPlayerMoney(0) @@ -59,6 +60,15 @@ void ShopListBox::draw(gcn::Graphics *gcnGraphics) if (!mListModel) return; + if (config.getValue("guialpha", 0.8) != mAlpha) + mAlpha = config.getValue("guialpha", 0.8); + + bool valid; + const int red = (textColor->getColor('H', valid) >> 16) & 0xFF; + const int green = (textColor->getColor('H', valid) >> 8) & 0xFF; + const int blue = textColor->getColor('H', valid) & 0xFF; + const int alpha = (int)(mAlpha * 255.0f); + Graphics *graphics = static_cast<Graphics*>(gcnGraphics); graphics->setFont(getFont()); @@ -68,16 +78,16 @@ void ShopListBox::draw(gcn::Graphics *gcnGraphics) i < mListModel->getNumberOfElements(); ++i, y += mRowHeight) { - gcn::Color backgroundColor = gcn::Color(0xffffff); + gcn::Color backgroundColor = gcn::Color(255, 255, 255, alpha); if (i == mSelected) { - backgroundColor = gcn::Color(110, 160, 255); + backgroundColor = gcn::Color(red, green, blue, alpha); } else if (mShopItems && mPlayerMoney < mShopItems->at(i)->getPrice() && mPriceCheck) { - backgroundColor = gcn::Color(0x919191); + backgroundColor = gcn::Color(145, 145, 145, alpha); } graphics->setColor(backgroundColor); diff --git a/src/gui/shoplistbox.h b/src/gui/shoplistbox.h index 75f514ab..cde4786e 100644 --- a/src/gui/shoplistbox.h +++ b/src/gui/shoplistbox.h @@ -1,29 +1,30 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TMW_SHOPLISTBOX_H -#define _TMW_SHOPLISTBOX_H +#ifndef SHOPLISTBOX_H +#define SHOPLISTBOX_H #include "listbox.h" -#include "shop.h" + +class ShopItems; /** * A list box, meant to be used inside a scroll area. Same as the Guichan list @@ -84,6 +85,8 @@ class ShopListBox : public ListBox unsigned int mRowHeight; /**< Row Height */ + static float mAlpha; + bool mPriceCheck; }; diff --git a/src/gui/shortcutcontainer.cpp b/src/gui/shortcutcontainer.cpp new file mode 100644 index 00000000..74609fa1 --- /dev/null +++ b/src/gui/shortcutcontainer.cpp @@ -0,0 +1,71 @@ +/* + * The Mana World + * Copyright (C) 2007 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 "shortcutcontainer.h" + +#include "../configuration.h" + +#include "../resources/image.h" + +#include "../utils/stringutils.h" + +float ShortcutContainer::mAlpha = config.getValue("guialpha", 0.8); + +ShortcutContainer::ShortcutContainer(): + mGridWidth(1), + mGridHeight(1) +{ +} + +void ShortcutContainer::widgetResized(const gcn::Event &event) +{ + mGridWidth = getWidth() / mBoxWidth; + if (mGridWidth < 1) + { + mGridWidth = 1; + } + + setHeight((mMaxItems / mGridWidth + + (mMaxItems % mGridWidth > 0 ? 1 : 0)) * mBoxHeight); + + mGridHeight = getHeight() / mBoxHeight; + if (mGridHeight < 1) + { + mGridHeight = 1; + } +} + +int ShortcutContainer::getIndexFromGrid(int pointX, int pointY) const +{ + const gcn::Rectangle tRect = gcn::Rectangle( + 0, 0, mGridWidth * mBoxWidth, mGridHeight * mBoxHeight); + if (!tRect.isPointInRect(pointX, pointY)) + { + return -1; + } + const int index = ((pointY / mBoxHeight) * mGridWidth) + + pointX / mBoxWidth; + if (index >= mMaxItems) + { + return -1; + } + return index; +} diff --git a/src/gui/shortcutcontainer.h b/src/gui/shortcutcontainer.h new file mode 100644 index 00000000..7b09fb96 --- /dev/null +++ b/src/gui/shortcutcontainer.h @@ -0,0 +1,107 @@ +/* + * The Mana World + * Copyright (C) 2007 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 SHORTCUTCONTAINER_H +#define SHORTCUTCONTAINER_H + +#include <guichan/mouselistener.hpp> +#include <guichan/widget.hpp> +#include <guichan/widgetlistener.hpp> + +class Image; + +/** + * A generic shortcut container. + * + * \ingroup GUI + */ +class ShortcutContainer : public gcn::Widget, + public gcn::WidgetListener, + public gcn::MouseListener +{ + public: + /** + * Constructor. Initializes the shortcut container. + */ + ShortcutContainer(); + + /** + * Destructor. + */ + ~ShortcutContainer(){} + + /** + * Draws the shortcuts + */ + virtual void draw(gcn::Graphics *graphics) = 0; + + /** + * Invoked when a widget changes its size. This is used to determine + * the new height of the container. + */ + virtual void widgetResized(const gcn::Event &event); + + /** + * Handles mouse when dragged. + */ + virtual void mouseDragged(gcn::MouseEvent &event) = 0; + + /** + * Handles mouse when pressed. + */ + virtual void mousePressed(gcn::MouseEvent &event) = 0; + + /** + * Handles mouse release. + */ + virtual void mouseReleased(gcn::MouseEvent &event) = 0; + + virtual int getMaxItems() + { return mMaxItems; } + + virtual int getBoxWidth() + { return mBoxWidth; } + + virtual int getBoxHeight() + { return mBoxHeight; } + + protected: + /** + * Gets the index from the grid provided the point is in an item box. + * + * @param pointX X coordinate of the point. + * @param pointY Y coordinate of the point. + * @return index on success, -1 on failure. + */ + int getIndexFromGrid(int pointX, int pointY) const; + + Image *mBackgroundImg; + + static float mAlpha; + + int mMaxItems; + int mBoxWidth; + int mBoxHeight; + int mCursorPosX, mCursorPosY; + int mGridWidth, mGridHeight; +}; + +#endif diff --git a/src/gui/shortcutwindow.cpp b/src/gui/shortcutwindow.cpp new file mode 100644 index 00000000..c704fc44 --- /dev/null +++ b/src/gui/shortcutwindow.cpp @@ -0,0 +1,83 @@ +/* + * The Mana World + * Copyright (C) 2007 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 "scrollarea.h" +#include "shortcutcontainer.h" +#include "shortcutwindow.h" + +#include "../configuration.h" + +static const int SCROLL_PADDING = 0; + +int ShortcutWindow::mInstances = 0; + +ShortcutWindow::ShortcutWindow(const char *title, ShortcutContainer *content) +{ + setWindowName(title); + // no title presented, title bar is padding so window can be moved. + gcn::Window::setTitleBarHeight(gcn::Window::getPadding()); + setShowTitle(false); + setResizable(true); + + mItems = content; + + mInstances++; + + const int border = SCROLL_PADDING * 2 + getPadding() * 2; + setMinWidth(mItems->getBoxWidth() + border); + setMinHeight(mItems->getBoxHeight() + border); + setMaxWidth(mItems->getBoxWidth() * mItems->getMaxItems() + border); + setMaxHeight(mItems->getBoxHeight() * mItems->getMaxItems() + border); + + const int width = (int) config.getValue("screenwidth", 800); + const int height = (int) config.getValue("screenheight", 600); + + setDefaultSize(width - (mInstances * mItems->getBoxWidth()) - + (mInstances * border), height - (mItems->getBoxHeight() * + mItems->getMaxItems()) - border, mItems->getBoxWidth() + + border, (mItems->getBoxHeight() * mItems->getMaxItems()) + + border); + + mScrollArea = new ScrollArea(mItems); + mScrollArea->setPosition(SCROLL_PADDING, SCROLL_PADDING); + mScrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); + mScrollArea->setOpaque(false); + + add(mScrollArea); + + loadWindowState(); +} + +ShortcutWindow::~ShortcutWindow() +{ + delete mItems; +} + +void ShortcutWindow::widgetResized(const gcn::Event &event) +{ + Window::widgetResized(event); + + const gcn::Rectangle &area = getChildrenArea(); + + mScrollArea->setSize( + area.width - SCROLL_PADDING, + area.height - SCROLL_PADDING); +} diff --git a/src/gui/shortcutwindow.h b/src/gui/shortcutwindow.h new file mode 100644 index 00000000..64592328 --- /dev/null +++ b/src/gui/shortcutwindow.h @@ -0,0 +1,65 @@ +/* + * The Mana World + * Copyright (C) 2007 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 SHORTCUTWINDOW_H +#define SHORTCUTWINDOW_H + +#include "window.h" + +class ScrollArea; +class ShortcutContainer; + +/** + * A window around the ItemShortcutContainer. + * + * \ingroup Interface + */ +class ShortcutWindow : public Window +{ + public: + /** + * Constructor. + */ + ShortcutWindow(const char *title, ShortcutContainer *content); + + /** + * Destructor. + */ + ~ShortcutWindow(); + + /** + * Called whenever the widget changes size. + */ + void widgetResized(const gcn::Event &event); + + private: + ShortcutWindow(); + ShortcutContainer *mItems; + + ScrollArea *mScrollArea; + + static int mInstances; +}; + +extern ShortcutWindow *itemShortcutWindow; +extern ShortcutWindow *emoteShortcutWindow; + +#endif diff --git a/src/gui/skill.cpp b/src/gui/skill.cpp index 6d747641..61bb9ce9 100644 --- a/src/gui/skill.cpp +++ b/src/gui/skill.cpp @@ -1,73 +1,161 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include <guichan/widgets/label.hpp> -#include <guichan/widgets/container.hpp> -#include <guichan/widgets/icon.hpp> -#include "skill.h" - -#include "icon.h" #include "button.h" #include "listbox.h" #include "scrollarea.h" +#include "skill.h" +#include "table.h" #include "windowcontainer.h" -#include "progressbar.h" -#include "widgets/tabbedarea.h" +#include "widgets/layout.h" #include "../localplayer.h" +#include "../log.h" #include "../utils/dtor.h" -#include "../utils/tostring.h" #include "../utils/gettext.h" +#include "../utils/strprintf.h" +#include "../utils/xml.h" + +static const char *SKILLS_FILE = _("skills.xml"); + +struct SkillInfo +{ + std::string name; + bool modifiable; +}; + +static const SkillInfo fakeSkillInfo = { + _("Mystery Skill"), + false +}; + +std::vector<SkillInfo> skill_db; + +static void initSkillinfo(); + +class SkillGuiTableModel : public StaticTableModel +{ +public: + SkillGuiTableModel(SkillDialog *dialog) : + StaticTableModel(0, 3) + { + mEntriesNr = 0; + mDialog = dialog; + update(); + } + + virtual int getRows(void) + { + return mEntriesNr; + } + + virtual int getColumnWidth(int index) + { + if (index == 0) + return 160; + + return 35; + } + + virtual int getRowHeight() + { + return 12; + } + + virtual void update() + { + mEntriesNr = mDialog->getSkills().size(); + resize(); + + for (int i = 0; i < mEntriesNr; i++) + { + SKILL *skill = mDialog->getSkills()[i]; + SkillInfo const *info; + char tmp[128]; + + if (skill->id >= 0 + && (unsigned int) skill->id < skill_db.size()) + info = &skill_db[skill->id]; + else + info = &fakeSkillInfo; + + sprintf(tmp, "%c%s", info->modifiable? ' ' : '*', info->name.c_str()); + gcn::Label *name_label = new gcn::Label(tmp); + + sprintf(tmp, "Lv:%i", skill->lv); + gcn::Label *lv_label = new gcn::Label(tmp); + + sprintf(tmp, "Sp:%i", skill->sp); + gcn::Label *sp_label = new gcn::Label(tmp); + + set(i, 0, name_label); + set(i, 1, lv_label); + set(i, 2, sp_label); + } + } + +private: + SkillDialog *mDialog; + int mEntriesNr; +}; + SkillDialog::SkillDialog(): Window(_("Skills")) { + initSkillinfo(); + mTableModel = new SkillGuiTableModel(this); + mTable = new GuiTable(mTableModel); + mTable->setOpaque(false); + mTable->setLinewiseSelection(true); + mTable->setWrappingEnabled(true); + mTable->setActionEventId("skill"); + mTable->addActionListener(this); + setWindowName("Skills"); setCloseButton(true); - setDefaultSize(windowContainer->getWidth() - 280, 30, 275, 425); + setDefaultSize(windowContainer->getWidth() - 260, 25, 255, 260); - TabbedArea *panel = new TabbedArea(); - panel->setDimension(gcn::Rectangle(5, 5, 270, 420)); + setMinHeight(50 + mTableModel->getHeight()); + setMinWidth(200); - Skill_Tab* tab; + ScrollArea *skillScrollArea = new ScrollArea(mTable); + mPointsLabel = new gcn::Label(strprintf(_("Skill points: %d"), 0)); + mIncButton = new Button(_("Up"), _("inc"), this); + mUseButton = new Button(_("Use"), _("use"), this); + mUseButton->setEnabled(false); - // Add each type of skill tab to the panel - tab = new Skill_Tab("Weapon"); - panel->addTab(_("Weapons"), tab); - mTabs.push_back(tab); + skillScrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); - tab = new Skill_Tab("Magic"); - panel->addTab(_("Magic"), tab); - mTabs.push_back(tab); + place(0, 0, skillScrollArea, 5).setPadding(3); + place(0, 1, mPointsLabel, 2); + place(3, 2, mIncButton); + place(4, 2, mUseButton); - tab = new Skill_Tab("Craft"); - panel->addTab(_("Crafts"), tab); - mTabs.push_back(tab); - - add(panel); - - update(); + Layout &layout = getLayout(); + layout.setRowHeight(0, Layout::AUTO_SET); setLocationRelativeTo(getParent()); loadWindowState(); @@ -75,189 +163,135 @@ SkillDialog::SkillDialog(): SkillDialog::~SkillDialog() { - delete_all(mTabs); + delete mTable; } void SkillDialog::action(const gcn::ActionEvent &event) { - if (event.getId() == "skill") + if (event.getId() == "inc") { + // Increment skill + int selectedSkill = mTable->getSelectedRow(); + if (selectedSkill >= 0) + player_node->raiseSkill(mSkillList[selectedSkill]->id); } - else if (event.getId() == "close") + else if (event.getId() == "skill" && mTable->getSelectedRow() > -1) { - setVisible(false); - } -} - -void SkillDialog::draw(gcn::Graphics *g) -{ - update(); + SKILL *skill = mSkillList[mTable->getSelectedRow()]; + SkillInfo const *info; - Window::draw(g); -} + if (skill->id >= 0 && (unsigned int) skill->id < skill_db.size()) + info = &skill_db[skill->id]; + else + info = &fakeSkillInfo; -void SkillDialog::update() -{ - for(std::list<Skill_Tab*>::const_iterator i = mTabs.begin(); - i != mTabs.end(); ++i) - { - (*i)->update(); + mIncButton->setEnabled(player_node->mSkillPoint > 0 && + info->modifiable); } + else if (event.getId() == "close") + setVisible(false); } -Skill_Tab::Skill_Tab(const std::string &type): type(type) +void SkillDialog::update() { - setOpaque(false); - setDimension(gcn::Rectangle(0, 0, 270, 420)); - int skillNum = getSkillNum(); - - mSkillIcons.resize(skillNum); - mSkillNameLabels.resize(skillNum); - mSkillLevelLabels.resize(skillNum); - mSkillExpLabels.resize(skillNum); - mSkillProgress.resize(skillNum); - - // Set the initial positions of the skill information - for (int a=0; a < skillNum; a++) - { - mSkillIcons.at(a) = getIcon(a); - mSkillIcons.at(a)->setPosition(1, a*32); - add(mSkillIcons.at(a)); + mPointsLabel->setCaption(strprintf(_("Skill points: %d"), + player_node->mSkillPoint)); - mSkillNameLabels.at(a) = new gcn::Label(""); - mSkillNameLabels.at(a)->setPosition(35, a*32 ); - add(mSkillNameLabels.at(a)); + int selectedSkill = mTable->getSelectedRow(); - mSkillProgress.at(a) = new ProgressBar(0.0f, 200, 20, 150, 150, 150); - mSkillProgress.at(a)->setPosition(35, a*32 + 13); - add(mSkillProgress.at(a)); + if (selectedSkill >= 0) + { + int skillId = mSkillList[selectedSkill]->id; + bool modifiable; - mSkillExpLabels.at(a) = new gcn::Label(""); - mSkillExpLabels.at(a)->setPosition(45, a*32 + 16); - add(mSkillExpLabels.at(a)); + if (skillId >= 0 && (unsigned int) skillId < skill_db.size()) + modifiable = skill_db[skillId].modifiable; + else + modifiable = false; - mSkillLevelLabels.at(a) = new gcn::Label(""); - mSkillLevelLabels.at(a)->setPosition(165, a*32); - add(mSkillLevelLabels.at(a)); + mIncButton->setEnabled(modifiable + && player_node->mSkillPoint > 0); } + else + mIncButton->setEnabled(false); - update(); - + mTableModel->update(); + setMinHeight(50 + mTableModel->getHeight()); } -int Skill_Tab::getSkillNum() +int SkillDialog::getNumberOfElements() { - int skillNum = 0; + return mSkillList.size(); +} - if (type == "Weapon") - { - skillNum = CHAR_SKILL_WEAPON_NB; - return skillNum; - } - else if (type == "Magic") - { - skillNum = CHAR_SKILL_MAGIC_NB; - return skillNum; - } - else if (type == "Craft") +bool SkillDialog::hasSkill(int id) +{ + for (unsigned int i = 0; i < mSkillList.size(); i++) { - skillNum = CHAR_SKILL_CRAFT_NB; - return skillNum; + if (mSkillList[i]->id == id) + return true; } - else return skillNum; + return false; } -int Skill_Tab::getSkillBegin() +void SkillDialog::addSkill(int id, int lvl, int mp) { - int skillBegin = 0; + SKILL *tmp = new SKILL; + tmp->id = id; + tmp->lv = lvl; + tmp->sp = mp; + mSkillList.push_back(tmp); +} - if (type == "Weapon") - { - skillBegin = CHAR_SKILL_WEAPON_BEGIN - CHAR_SKILL_BEGIN; - return skillBegin; - } - else if (type == "Magic") - { - skillBegin = CHAR_SKILL_MAGIC_BEGIN - CHAR_SKILL_BEGIN; - return skillBegin; - } - else if (type == "Craft") +void SkillDialog::setSkill(int id, int lvl, int mp) +{ + for (unsigned int i = 0; i < mSkillList.size(); i++) { - skillBegin = CHAR_SKILL_CRAFT_BEGIN - CHAR_SKILL_BEGIN; - return skillBegin; + if (mSkillList[i]->id == id) + { + mSkillList[i]->lv = lvl; + mSkillList[i]->sp = mp; + } } - else return skillBegin; } -Icon* Skill_Tab::getIcon(int index) +void SkillDialog::cleanList() { - int skillBegin = getSkillBegin(); - std::string icon = LocalPlayer::getSkillInfo(index + skillBegin).icon; - return new Icon(icon); + delete_all(mSkillList); + mSkillList.clear(); } -void Skill_Tab::updateSkill(int index) +static void initSkillinfo() { - int skillBegin = getSkillBegin(); + SkillInfo emptySkillInfo = { "", false }; - int baseLevel = player_node->getAttributeBase(index + - skillBegin + - CHAR_SKILL_BEGIN); + XML::Document doc(SKILLS_FILE); + xmlNodePtr root = doc.rootNode(); - int effLevel = player_node->getAttributeEffective(index + - skillBegin + - CHAR_SKILL_BEGIN); - if(baseLevel <= 0) + if (!root || !xmlStrEqual(root->name, BAD_CAST "skills")) { - mSkillProgress.at(index)->setVisible(false); - mSkillExpLabels.at(index)->setVisible(false); - mSkillLevelLabels.at(index)->setVisible(false); - mSkillNameLabels.at(index)->setVisible(false); - mSkillIcons.at(index)->setVisible(false); + logger->log("Error loading skills file: %s", SKILLS_FILE); + skill_db.resize(2, emptySkillInfo); + skill_db[1].name = "Basic"; + skill_db[1].modifiable = true; + return; } - else + + for_each_xml_child_node(node, root) { - mSkillProgress.at(index)->setVisible(true); - mSkillExpLabels.at(index)->setVisible(true); - mSkillLevelLabels.at(index)->setVisible(true); - mSkillNameLabels.at(index)->setVisible(true); - mSkillIcons.at(index)->setVisible(true); - std::string skillLevel("Lvl: " + toString(baseLevel)); - if (effLevel < baseLevel) - { - skillLevel.append(" - " + toString(baseLevel - effLevel)); - } - else if (effLevel > baseLevel) + if (xmlStrEqual(node->name, BAD_CAST "skill")) { - skillLevel.append(" + " + toString(effLevel - baseLevel)); + int index = atoi(XML::getProperty(node, "id", "-1").c_str()); + std::string name = XML::getProperty(node, "name", ""); + bool modifiable = !atoi(XML::getProperty(node, "fixed", "0").c_str()); + + if (index >= 0) + { + skill_db.resize(index + 1, emptySkillInfo); + skill_db[index].name = name; + skill_db[index].modifiable = modifiable; + } } - mSkillLevelLabels.at(index)->setCaption(skillLevel); - - std::pair<int, int> exp = player_node->getExperience(index + skillBegin); - std::string sExp (toString(exp.first) + " / " + toString(exp.second)); - - - mSkillNameLabels.at(index)->setCaption(LocalPlayer::getSkillInfo(index + skillBegin).name); - mSkillNameLabels.at(index)->adjustSize(); - mSkillLevelLabels.at(index)->adjustSize(); - mSkillExpLabels.at(index)->setCaption(sExp); - mSkillExpLabels.at(index)->adjustSize(); - mSkillExpLabels.at(index)->setAlignment(gcn::Graphics::RIGHT); - - // More intense red as exp grows - int color = 150 - (int)(150 * ((float) exp.first / exp.second)); - mSkillProgress.at(index)->setColor(244, color, color); - mSkillProgress.at(index)->setProgress((float) exp.first / exp.second); } } -void Skill_Tab::update() -{ - int skillNum = getSkillNum(); - - // Update the skill information for reach skill - for (int a = 0; a < skillNum; a++) - { - updateSkill(a); - } -} diff --git a/src/gui/skill.h b/src/gui/skill.h index 3d010daa..0600d106 100644 --- a/src/gui/skill.h +++ b/src/gui/skill.h @@ -1,95 +1,40 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TMW_SKILL_H -#define _TMW_SKILL_H +#ifndef SKILL_H +#define SKILL_H #include <vector> -#include <list> -#include <guichan/listmodel.hpp> #include <guichan/actionlistener.hpp> #include "window.h" -#include "gccontainer.h" -#include "../guichanfwd.h" - -class ProgressBar; -class Icon; - -class Skill_Tab : public GCContainer, public gcn::ActionListener -{ - public: - /** - * The type of this skill tab - */ - const std::string type; - - /** - * Constructor - */ - Skill_Tab(const std::string &type); - - /** - * Update this tab - */ - void update(); - - /** - * Called when receiving actions from widget. - */ - void action(const gcn::ActionEvent &event) {} - - private: - /** - * Update the information of a skill at - * the given index - */ - void updateSkill(int index); - - /** - * Gets the number of skills in this particular - * type of tab. - */ - int getSkillNum(); - - /** - * Get the first enumeration of this skill tab's - * skill type. - */ - int getSkillBegin(); - - /** - * Get the icon associated with the given index - */ - Icon* getIcon(int index); - - std::vector<Icon *> mSkillIcons; - std::vector<gcn::Label *> mSkillNameLabels; - std::vector<gcn::Label *> mSkillLevelLabels; - std::vector<gcn::Label *> mSkillExpLabels; - std::vector<ProgressBar *> mSkillProgress; +struct SKILL { + short id; /**< Index into "skill_db" array */ + short lv, sp; }; +class GuiTable; +class SkillGuiTableModel; /** * The skill dialog. @@ -109,31 +54,30 @@ class SkillDialog : public Window, public gcn::ActionListener */ ~SkillDialog(); - /** - * Called when receiving actions from widget. - */ void action(const gcn::ActionEvent &event); - /** - * Update the tabs in this dialog - */ void update(); - /** - * Draw this window. - */ - void draw(gcn::Graphics *g); - - private: + int getNumberOfElements(); + bool hasSkill(int id); + void addSkill(int id, int lv, int sp); + void setSkill(int id, int lv, int sp); + void cleanList(); - std::list<Skill_Tab*> mTabs; + const std::vector<SKILL*>& getSkills() const { return mSkillList; } + private: + GuiTable *mTable; + ScrollArea *skillScrollArea; + SkillGuiTableModel *mTableModel; + gcn::Label *mPointsLabel; + gcn::Button *mIncButton; + gcn::Button *mUseButton; + + std::vector<SKILL*> mSkillList; }; - - - extern SkillDialog *skillDialog; #endif diff --git a/src/gui/skilldialog.cpp b/src/gui/skilldialog.cpp new file mode 100644 index 00000000..22d1db60 --- /dev/null +++ b/src/gui/skilldialog.cpp @@ -0,0 +1,263 @@ +/* + * The Mana World + * Copyright 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * The Mana World 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. + * + * The Mana World 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 The Mana World; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <guichan/widgets/label.hpp> +#include <guichan/widgets/container.hpp> +#include <guichan/widgets/icon.hpp> + +#include "skilldialog.h" + +#include "icon.h" +#include "button.h" +#include "listbox.h" +#include "scrollarea.h" +#include "windowcontainer.h" +#include "progressbar.h" + +#include "widgets/tabbedarea.h" + +#include "../localplayer.h" + +#include "../utils/dtor.h" +#include "../utils/gettext.h" +#include "../utils/stringutils.h" + +SkillDialog::SkillDialog(): + Window(_("Skills")) +{ + setWindowName("Skills"); + setCloseButton(true); + setDefaultSize(windowContainer->getWidth() - 280, 30, 275, 425); + + TabbedArea *panel = new TabbedArea(); + panel->setDimension(gcn::Rectangle(5, 5, 270, 420)); + + Skill_Tab* tab; + + // Add each type of skill tab to the panel + tab = new Skill_Tab("Weapon"); + panel->addTab(_("Weapons"), tab); + mTabs.push_back(tab); + + tab = new Skill_Tab("Magic"); + panel->addTab(_("Magic"), tab); + mTabs.push_back(tab); + + tab = new Skill_Tab("Craft"); + panel->addTab(_("Crafts"), tab); + mTabs.push_back(tab); + + add(panel); + + update(); + + setLocationRelativeTo(getParent()); + loadWindowState(); +} + +SkillDialog::~SkillDialog() +{ + delete_all(mTabs); +} + +void SkillDialog::action(const gcn::ActionEvent &event) +{ + if (event.getId() == "skill") + { + } + else if (event.getId() == "close") + { + setVisible(false); + } +} + +void SkillDialog::draw(gcn::Graphics *g) +{ + update(); + + Window::draw(g); +} + +void SkillDialog::update() +{ + for(std::list<Skill_Tab*>::const_iterator i = mTabs.begin(); + i != mTabs.end(); ++i) + { + (*i)->update(); + } +} + +Skill_Tab::Skill_Tab(const std::string &type): type(type) +{ + setOpaque(false); + setDimension(gcn::Rectangle(0, 0, 270, 420)); + int skillNum = getSkillNum(); + + mSkillIcons.resize(skillNum); + mSkillNameLabels.resize(skillNum); + mSkillLevelLabels.resize(skillNum); + mSkillExpLabels.resize(skillNum); + mSkillProgress.resize(skillNum); + + // Set the initial positions of the skill information + for (int a=0; a < skillNum; a++) + { + mSkillIcons.at(a) = getIcon(a); + mSkillIcons.at(a)->setPosition(1, a*32); + add(mSkillIcons.at(a)); + + mSkillNameLabels.at(a) = new gcn::Label(""); + mSkillNameLabels.at(a)->setPosition(35, a*32 ); + add(mSkillNameLabels.at(a)); + + mSkillProgress.at(a) = new ProgressBar(0.0f, 200, 20, 150, 150, 150); + mSkillProgress.at(a)->setPosition(35, a*32 + 13); + add(mSkillProgress.at(a)); + + mSkillExpLabels.at(a) = new gcn::Label(""); + mSkillExpLabels.at(a)->setPosition(45, a*32 + 16); + add(mSkillExpLabels.at(a)); + + mSkillLevelLabels.at(a) = new gcn::Label(""); + mSkillLevelLabels.at(a)->setPosition(165, a*32); + add(mSkillLevelLabels.at(a)); + } + + update(); + +} + +int Skill_Tab::getSkillNum() +{ + int skillNum = 0; + + if (type == "Weapon") + { + skillNum = CHAR_SKILL_WEAPON_NB; + return skillNum; + } + else if (type == "Magic") + { + skillNum = CHAR_SKILL_MAGIC_NB; + return skillNum; + } + else if (type == "Craft") + { + skillNum = CHAR_SKILL_CRAFT_NB; + return skillNum; + } + else return skillNum; +} + +int Skill_Tab::getSkillBegin() +{ + int skillBegin = 0; + + if (type == "Weapon") + { + skillBegin = CHAR_SKILL_WEAPON_BEGIN - CHAR_SKILL_BEGIN; + return skillBegin; + } + else if (type == "Magic") + { + skillBegin = CHAR_SKILL_MAGIC_BEGIN - CHAR_SKILL_BEGIN; + return skillBegin; + } + else if (type == "Craft") + { + skillBegin = CHAR_SKILL_CRAFT_BEGIN - CHAR_SKILL_BEGIN; + return skillBegin; + } + else return skillBegin; +} + +Icon* Skill_Tab::getIcon(int index) +{ + int skillBegin = getSkillBegin(); + std::string icon = LocalPlayer::getSkillInfo(index + skillBegin).icon; + return new Icon(icon); +} + +void Skill_Tab::updateSkill(int index) +{ + int skillBegin = getSkillBegin(); + + int baseLevel = player_node->getAttributeBase(index + + skillBegin + + CHAR_SKILL_BEGIN); + + int effLevel = player_node->getAttributeEffective(index + + skillBegin + + CHAR_SKILL_BEGIN); + if(baseLevel <= 0) + { + mSkillProgress.at(index)->setVisible(false); + mSkillExpLabels.at(index)->setVisible(false); + mSkillLevelLabels.at(index)->setVisible(false); + mSkillNameLabels.at(index)->setVisible(false); + mSkillIcons.at(index)->setVisible(false); + } + else + { + mSkillProgress.at(index)->setVisible(true); + mSkillExpLabels.at(index)->setVisible(true); + mSkillLevelLabels.at(index)->setVisible(true); + mSkillNameLabels.at(index)->setVisible(true); + mSkillIcons.at(index)->setVisible(true); + std::string skillLevel("Lvl: " + toString(baseLevel)); + if (effLevel < baseLevel) + { + skillLevel.append(" - " + toString(baseLevel - effLevel)); + } + else if (effLevel > baseLevel) + { + skillLevel.append(" + " + toString(effLevel - baseLevel)); + } + mSkillLevelLabels.at(index)->setCaption(skillLevel); + + std::pair<int, int> exp = player_node->getExperience(index + skillBegin); + std::string sExp (toString(exp.first) + " / " + toString(exp.second)); + + + mSkillNameLabels.at(index)->setCaption(LocalPlayer::getSkillInfo(index + skillBegin).name); + mSkillNameLabels.at(index)->adjustSize(); + mSkillLevelLabels.at(index)->adjustSize(); + mSkillExpLabels.at(index)->setCaption(sExp); + mSkillExpLabels.at(index)->adjustSize(); + mSkillExpLabels.at(index)->setAlignment(gcn::Graphics::RIGHT); + + // More intense red as exp grows + int color = 150 - (int)(150 * ((float) exp.first / exp.second)); + mSkillProgress.at(index)->setColor(244, color, color); + mSkillProgress.at(index)->setProgress((float) exp.first / exp.second); + } +} + +void Skill_Tab::update() +{ + int skillNum = getSkillNum(); + + // Update the skill information for reach skill + for (int a = 0; a < skillNum; a++) + { + updateSkill(a); + } +} diff --git a/src/gui/skilldialog.h b/src/gui/skilldialog.h new file mode 100644 index 00000000..3d010daa --- /dev/null +++ b/src/gui/skilldialog.h @@ -0,0 +1,139 @@ +/* + * The Mana World + * Copyright 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * The Mana World 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. + * + * The Mana World 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 The Mana World; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _TMW_SKILL_H +#define _TMW_SKILL_H + +#include <vector> +#include <list> + +#include <guichan/listmodel.hpp> +#include <guichan/actionlistener.hpp> + +#include "window.h" +#include "gccontainer.h" + +#include "../guichanfwd.h" + +class ProgressBar; +class Icon; + +class Skill_Tab : public GCContainer, public gcn::ActionListener +{ + public: + /** + * The type of this skill tab + */ + const std::string type; + + /** + * Constructor + */ + Skill_Tab(const std::string &type); + + /** + * Update this tab + */ + void update(); + + /** + * Called when receiving actions from widget. + */ + void action(const gcn::ActionEvent &event) {} + + private: + /** + * Update the information of a skill at + * the given index + */ + void updateSkill(int index); + + /** + * Gets the number of skills in this particular + * type of tab. + */ + int getSkillNum(); + + /** + * Get the first enumeration of this skill tab's + * skill type. + */ + int getSkillBegin(); + + /** + * Get the icon associated with the given index + */ + Icon* getIcon(int index); + + std::vector<Icon *> mSkillIcons; + std::vector<gcn::Label *> mSkillNameLabels; + std::vector<gcn::Label *> mSkillLevelLabels; + std::vector<gcn::Label *> mSkillExpLabels; + std::vector<ProgressBar *> mSkillProgress; +}; + + +/** + * The skill dialog. + * + * \ingroup Interface + */ +class SkillDialog : public Window, public gcn::ActionListener +{ + public: + /** + * Constructor. + */ + SkillDialog(); + + /** + * Destructor. + */ + ~SkillDialog(); + + /** + * Called when receiving actions from widget. + */ + void action(const gcn::ActionEvent &event); + + /** + * Update the tabs in this dialog + */ + void update(); + + /** + * Draw this window. + */ + void draw(gcn::Graphics *g); + + private: + + + std::list<Skill_Tab*> mTabs; + +}; + + + + +extern SkillDialog *skillDialog; + +#endif diff --git a/src/gui/slider.cpp b/src/gui/slider.cpp index afeecf17..9bfa840f 100644 --- a/src/gui/slider.cpp +++ b/src/gui/slider.cpp @@ -1,26 +1,27 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "slider.h" +#include "../configuration.h" #include "../graphics.h" #include "../resources/image.h" @@ -28,6 +29,7 @@ Image *Slider::hStart, *Slider::hMid, *Slider::hEnd, *Slider::hGrip; Image *Slider::vStart, *Slider::vMid, *Slider::vEnd, *Slider::vGrip; +float Slider::mAlpha = config.getValue("guialpha", 0.8); int Slider::mInstances = 0; Slider::Slider(double scaleEnd): @@ -107,6 +109,20 @@ void Slider::draw(gcn::Graphics *graphics) int x = 0; int y = (h - hStart->getHeight()) / 2; + if (config.getValue("guialpha", 0.8) != mAlpha) + { + mAlpha = config.getValue("guialpha", 0.8); + hStart->setAlpha(mAlpha); + hMid->setAlpha(mAlpha); + hEnd->setAlpha(mAlpha); + hGrip->setAlpha(mAlpha); + + vStart->setAlpha(mAlpha); + vMid->setAlpha(mAlpha); + vEnd->setAlpha(mAlpha); + vGrip->setAlpha(mAlpha); + } + static_cast<Graphics*>(graphics)->drawImage(hStart, x, y); w -= hStart->getWidth() + hEnd->getWidth(); diff --git a/src/gui/slider.h b/src/gui/slider.h index 3b796425..56ea334a 100644 --- a/src/gui/slider.h +++ b/src/gui/slider.h @@ -1,32 +1,31 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TMW_SLIDER_H -#define _TMW_SLIDER_H +#ifndef SLIDER_H +#define SLIDER_H #include <guichan/widgets/slider.hpp> class Image; - /** * Slider widget. Same as the Guichan slider but with custom look. * @@ -67,6 +66,7 @@ class Slider : public gcn::Slider { static Image *hStart, *hMid, *hEnd, *hGrip; static Image *vStart, *vMid, *vEnd, *vGrip; + static float mAlpha; static int mInstances; }; diff --git a/src/gui/speechbubble.cpp b/src/gui/speechbubble.cpp index 843a973d..165d216f 100644 --- a/src/gui/speechbubble.cpp +++ b/src/gui/speechbubble.cpp @@ -1,68 +1,94 @@ /* - * The Mana World + * Speech bubbles * Copyright (C) 2008 The Legend of Mazzeroth Development Team * Copyright (C) 2008 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include <guichan/font.hpp> + +#include <guichan/widgets/label.hpp> + +#include "gui.h" +#include "scrollarea.h" #include "speechbubble.h" +#include "textbox.h" -#include "../resources/image.h" -#include "../resources/resourcemanager.h" +#include "../utils/gettext.h" -SpeechBubble::SpeechBubble() +SpeechBubble::SpeechBubble(): + Window(_("Speech"), false, NULL, "graphics/gui/speechbubble.xml") { - mSpeechBox = new TextBox(); + setContentSize(140, 46); + setShowTitle(false); + setTitleBarHeight(0); + + mCaption = new gcn::Label(""); + mCaption->setFont(boldFont); + mCaption->setPosition(5, 3); + + mSpeechBox = new TextBox; mSpeechBox->setEditable(false); mSpeechBox->setOpaque(false); mSpeechArea = new ScrollArea(mSpeechBox); - // Height == Top Graphic (14px) + 1 Row of Text (15px) + Bottom Graphic (17px) - setContentSize(135, 46); - setTitleBarHeight(0); - loadSkin("graphics/gui/speechbubble.xml"); - mSpeechArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); mSpeechArea->setVerticalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); - mSpeechArea->setDimension(gcn::Rectangle(4, 15, 130, 28)); + mSpeechArea->setDimension(gcn::Rectangle(4, boldFont->getHeight() + 3, + 130, 28)); mSpeechArea->setOpaque(false); + add(mCaption); add(mSpeechArea); setLocationRelativeTo(getParent()); +} - // LEEOR / TODO: This causes an exception error. - //moveToBottom(getParent()); - - mSpeechBox->setTextWrapped( "" ); +void SpeechBubble::setCaption(const std::string &name, const gcn::Color &color) +{ + mCaption->setCaption(name); + mCaption->adjustSize(); + mCaption->setForegroundColor(color); } -void SpeechBubble::setText(const std::string mText) +void SpeechBubble::setText(std::string mText, bool showName) { - mSpeechBox->setTextWrapped( mText ); + int width = mCaption->getWidth(); + mSpeechBox->setTextWrapped(mText, 130 > width ? 130 : width); + + const int fontHeight = getFont()->getHeight(); + const int numRows = showName ? mSpeechBox->getNumberOfRows() + 1 : + mSpeechBox->getNumberOfRows(); + int yPos = showName ? fontHeight + 3 : 3; + int height = (numRows * fontHeight); + + if (width < mSpeechBox->getMinWidth()) + width = mSpeechBox->getMinWidth(); - int numRows = mSpeechBox->getNumberOfRows(); + if (numRows == 1) + { + yPos = (fontHeight / 4) + 3; + height = ((3 * fontHeight) / 2) + 1; + } - // 31 == speechbubble Top + Bottom graphic pixel heights - // 15 == height of each line of text (based on font heights) - setContentSize(135, 31 + (numRows * 15) ); - mSpeechArea->setDimension(gcn::Rectangle(4, 15, 130, (31 + (numRows * 14)) - 18 )); + setContentSize(width + fontHeight, height + 6); + mSpeechArea->setDimension(gcn::Rectangle(4, yPos, width + 5, height)); } unsigned int SpeechBubble::getNumRows() diff --git a/src/gui/speechbubble.h b/src/gui/speechbubble.h index 9fe61943..5d582b1d 100644 --- a/src/gui/speechbubble.h +++ b/src/gui/speechbubble.h @@ -1,44 +1,48 @@ /* - * The Mana World + * Speech bubbles * Copyright (C) 2008 The Legend of Mazzeroth Development Team * Copyright (C) 2008 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TMW_SPEECHBUBBLE_H__ -#define _TMW_SPEECHBUBBLE_H__ +#ifndef SPEECHBUBBLE_H +#define SPEECHBUBBLE_H -#include "textbox.h" -#include "scrollarea.h" #include "window.h" +class ScrollArea; +class TextBox; + class SpeechBubble : public Window { public: SpeechBubble(); - void setText(const std::string mText); + void setCaption(const std::string &name, + const gcn::Color &color = 0x000000); + void setText(std::string mText, bool showName = true); void setLocation(int x, int y); unsigned int getNumRows(); private: + gcn::Label *mCaption; TextBox *mSpeechBox; ScrollArea *mSpeechArea; }; -#endif // _TMW_SPEECHBUBBLE_H__ +#endif diff --git a/src/gui/status.cpp b/src/gui/status.cpp index 283a771b..3c48d045 100644 --- a/src/gui/status.cpp +++ b/src/gui/status.cpp @@ -1,226 +1,204 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "status.h" - #include <guichan/widgets/label.hpp> #include "button.h" #include "progressbar.h" +#include "status.h" #include "windowcontainer.h" +#include "widgets/layout.h" + #include "../localplayer.h" +#include "../units.h" +#include "../utils/gettext.h" #include "../utils/strprintf.h" -#include "../utils/tostring.h" +#include "../utils/stringutils.h" StatusWindow::StatusWindow(LocalPlayer *player): Window(player->getName()), - mPlayer(player) + mPlayer(player), + mCurrency(0) { setWindowName("Status"); - setResizable(true); setCloseButton(true); setDefaultSize((windowContainer->getWidth() - 365) / 2, - (windowContainer->getHeight() - 255) / 2, 365, 275); - loadWindowState(); + (windowContainer->getHeight() - 255) / 2, 400, 345); // ---------------------- // Status Part // ---------------------- - mLvlLabel = new gcn::Label("Level:"); - mMoneyLabel = new gcn::Label("Money:"); + mLvlLabel = new gcn::Label(strprintf(_("Level: %d"), 0)); + mJobLvlLabel = new gcn::Label(strprintf(_("Job: %d"), 0)); + mGpLabel = new gcn::Label(strprintf(_("Money: %s"), + Units::formatCurrency(mCurrency).c_str())); - mHpLabel = new gcn::Label("HP:"); + mHpLabel = new gcn::Label(_("HP:")); mHpBar = new ProgressBar(1.0f, 80, 15, 0, 171, 34); - mHpValueLabel = new gcn::Label(""); - - int y = 3; - int x = 5; - - mLvlLabel->setPosition(x, y); - x += mLvlLabel->getWidth() + 40; - mMoneyLabel->setPosition(x, y); - y += mLvlLabel->getHeight() + 5; // Next Row - x = 5; + mXpLabel = new gcn::Label(_("Exp:")); + mXpBar = new ProgressBar(1.0f, 80, 15, 143, 192, 211); - mHpLabel->setPosition(x, y); - x += mHpLabel->getWidth() + 5; - mHpBar->setPosition(x, y); - x += mHpBar->getWidth() + 5; - mHpValueLabel->setPosition(x, y); + mMpLabel = new gcn::Label(_("MP:")); + mMpBar = new ProgressBar(1.0f, 80, 15, 26, 102, 230); - y += mHpLabel->getHeight() + 5; // Next Row - x = 5; - - add(mLvlLabel); - add(mMoneyLabel); - add(mHpLabel); - add(mHpValueLabel); - add(mHpBar); + mJobLabel = new gcn::Label(_("Job:")); + mJobBar = new ProgressBar(1.0f, 80, 15, 220, 135, 203); // ---------------------- // Stats Part // ---------------------- // Static Labels - gcn::Label *mStatsTitleLabel = new gcn::Label("Stats"); - gcn::Label *mStatsTotalLabel = new gcn::Label("Total"); + gcn::Label *mStatsTitleLabel = new gcn::Label(_("Stats")); + gcn::Label *mStatsTotalLabel = new gcn::Label(_("Total")); + gcn::Label *mStatsCostLabel = new gcn::Label(_("Cost")); + mStatsTotalLabel->setAlignment(gcn::Graphics::CENTER); // Derived Stats -/* - mStatsAttackLabel = new gcn::Label("Attack:"); - mStatsDefenseLabel= new gcn::Label("Defense:"); - mStatsMagicAttackLabel = new gcn::Label("M.Attack:"); - mStatsMagicDefenseLabel = new gcn::Label("M.Defense:"); - mStatsAccuracyLabel = new gcn::Label("% Accuracy:"); - mStatsEvadeLabel = new gcn::Label("% Evade:"); - mStatsReflexLabel = new gcn::Label("% Reflex:"); - - mStatsAttackPoints = new gcn::Label(""); - mStatsDefensePoints = new gcn::Label(""); - mStatsMagicAttackPoints = new gcn::Label(""); - mStatsMagicDefensePoints = new gcn::Label(""); - mStatsAccuracyPoints = new gcn::Label("% Accuracy:"); - mStatsEvadePoints = new gcn::Label("% Evade:"); - mStatsReflexPoints = new gcn::Label("% Reflex:"); -*/ + mStatsAttackLabel = new gcn::Label(_("Attack:")); + mStatsDefenseLabel= new gcn::Label(_("Defense:")); + mStatsMagicAttackLabel = new gcn::Label(_("M.Attack:")); + mStatsMagicDefenseLabel = new gcn::Label(_("M.Defense:")); + // Gettext flag for next line: xgettext:no-c-format + mStatsAccuracyLabel = new gcn::Label(_("% Accuracy:")); + // Gettext flag for next line: xgettext:no-c-format + mStatsEvadeLabel = new gcn::Label(_("% Evade:")); + // Gettext flag for next line: xgettext:no-c-format + mStatsReflexLabel = new gcn::Label(_("% Reflex:")); + + mStatsAttackPoints = new gcn::Label; + mStatsDefensePoints = new gcn::Label; + mStatsMagicAttackPoints = new gcn::Label; + mStatsMagicDefensePoints = new gcn::Label; + mStatsAccuracyPoints = new gcn::Label; + mStatsEvadePoints = new gcn::Label; + mStatsReflexPoints = new gcn::Label; + // New labels - for (int i = 0; i < 6; i++) { - mStatsLabel[i] = new gcn::Label(); - mStatsDisplayLabel[i] = new gcn::Label(); + for (int i = 0; i < 6; i++) + { + mStatsLabel[i] = new gcn::Label("0"); + mStatsLabel[i]->setAlignment(gcn::Graphics::CENTER); + mStatsDisplayLabel[i] = new gcn::Label; + mPointsLabel[i] = new gcn::Label("0"); + mPointsLabel[i]->setAlignment(gcn::Graphics::CENTER); } - mCharacterPointsLabel = new gcn::Label(); - mCorrectionPointsLabel = new gcn::Label(); + mRemainingStatsPointsLabel = new gcn::Label; // Set button events Id - mStatsPlus[0] = new Button("+", "STR+", this); - mStatsPlus[1] = new Button("+", "AGI+", this); - mStatsPlus[2] = new Button("+", "DEX+", this); - mStatsPlus[3] = new Button("+", "VIT+", this); - mStatsPlus[4] = new Button("+", "INT+", this); - mStatsPlus[5] = new Button("+", "WIL+", this); - - mStatsMinus[0] = new Button("-", "STR-", this); - mStatsMinus[1] = new Button("-", "AGI-", this); - mStatsMinus[2] = new Button("-", "DEX-", this); - mStatsMinus[3] = new Button("-", "VIT-", this); - mStatsMinus[4] = new Button("-", "INT-", this); - mStatsMinus[5] = new Button("-", "WIL-", this); - - - - // Set position - mStatsTitleLabel->setPosition(mHpLabel->getX(), mHpLabel->getY() + 23 ); - mStatsTotalLabel->setPosition(110, mStatsTitleLabel->getY() + 15); - int totalLabelY = mStatsTotalLabel->getY(); + mStatsButton[0] = new Button("+", "STR", this); + mStatsButton[1] = new Button("+", "AGI", this); + mStatsButton[2] = new Button("+", "VIT", this); + mStatsButton[3] = new Button("+", "INT", this); + mStatsButton[4] = new Button("+", "DEX", this); + mStatsButton[5] = new Button("+", "LUK", this); + // Assemble + ContainerPlacer place; + place = getPlacer(0, 0); + + place(0, 0, mLvlLabel, 3); + place(5, 0, mJobLvlLabel, 3); + place(8, 0, mGpLabel, 3); + place(1, 1, mHpLabel).setPadding(3); + place(2, 1, mHpBar, 3); + place(6, 1, mXpLabel).setPadding(3); + place(7, 1, mXpBar, 3); + place(1, 2, mMpLabel).setPadding(3); + place(2, 2, mMpBar, 3); + place(6, 2, mJobLabel).setPadding(3); + place(7, 2, mJobBar, 3); + place.getCell().matchColWidth(0, 1); + place = getPlacer(0, 3); + place(0, 0, mStatsTitleLabel, 5); + place(5, 1, mStatsTotalLabel, 5); + place(12, 1, mStatsCostLabel, 5); for (int i = 0; i < 6; i++) { - mStatsLabel[i]->setPosition(5, - mStatsTotalLabel->getY() + (i * 23) + 15); - mStatsMinus[i]->setPosition(85, totalLabelY + (i * 23) + 15); - mStatsDisplayLabel[i]->setPosition(125, - totalLabelY + (i * 23) + 15); - mStatsPlus[i]->setPosition(185, totalLabelY + (i * 23) + 15); + place(0, 2 + i, mStatsLabel[i], 7).setPadding(5); + place(7, 2 + i, mStatsDisplayLabel[i]).setPadding(5); + place(10, 2 + i, mStatsButton[i]); + place(12, 2 + i, mPointsLabel[i]).setPadding(5); } + place(14, 2, mStatsAttackLabel, 7).setPadding(5); + place(14, 3, mStatsDefenseLabel, 7).setPadding(5); + place(14, 4, mStatsMagicAttackLabel, 7).setPadding(5); + place(14, 5, mStatsMagicDefenseLabel, 7).setPadding(5); + place(14, 6, mStatsAccuracyLabel, 7).setPadding(5); + place(14, 7, mStatsEvadeLabel, 7).setPadding(5); + place(14, 8, mStatsReflexLabel, 7).setPadding(5); + place(21, 2, mStatsAttackPoints, 3).setPadding(5); + place(21, 3, mStatsDefensePoints, 3).setPadding(5); + place(21, 4, mStatsMagicAttackPoints, 3).setPadding(5); + place(21, 5, mStatsMagicDefensePoints, 3).setPadding(5); + place(21, 6, mStatsAccuracyPoints, 3).setPadding(5); + place(21, 7, mStatsEvadePoints, 3).setPadding(5); + place(21, 8, mStatsReflexPoints, 3).setPadding(5); + place(0, 8, mRemainingStatsPointsLabel, 3).setPadding(5); + + Layout &layout = getLayout(); + layout.setRowHeight(0, Layout::AUTO_SET); - mCharacterPointsLabel->setPosition(5, mStatsDisplayLabel[5]->getY() + 25); - mCorrectionPointsLabel->setPosition(5, mStatsDisplayLabel[5]->getY() + 35); -/* - mStatsAttackLabel->setPosition(220, mStatsLabel[0]->getY()); - mStatsDefenseLabel->setPosition(220, mStatsLabel[1]->getY()); - mStatsMagicAttackLabel->setPosition(220, mStatsLabel[2]->getY()); - mStatsMagicDefenseLabel->setPosition(220, mStatsLabel[3]->getY()); - mStatsAccuracyLabel->setPosition(220, mStatsLabel[4]->getY()); - mStatsEvadeLabel->setPosition(220, mStatsLabel[5]->getY()); - mStatsReflexLabel->setPosition(220, mStatsLabel[6]->getY()); - - mStatsAttackPoints->setPosition(310, mStatsLabel[0]->getY()); - mStatsDefensePoints->setPosition(310, mStatsLabel[1]->getY()); - mStatsMagicAttackPoints->setPosition(310, mStatsLabel[2]->getY()); - mStatsMagicDefensePoints->setPosition(310, mStatsLabel[3]->getY()); - mStatsAccuracyPoints->setPosition(310, mStatsLabel[4]->getY()); - mStatsEvadePoints->setPosition(310, mStatsLabel[5]->getY()); - mStatsReflexPoints->setPosition(310, mStatsLabel[6]->getY()); -*/ - // Assemble - add(mStatsTitleLabel); - add(mStatsTotalLabel); - for(int i = 0; i < 6; i++) - { - add(mStatsLabel[i]); - add(mStatsDisplayLabel[i]); - add(mStatsPlus[i]); - add(mStatsMinus[i]); - }/* - add(mStatsAttackLabel); - add(mStatsDefenseLabel); - add(mStatsMagicAttackLabel); - add(mStatsMagicDefenseLabel); - add(mStatsAccuracyLabel); - add(mStatsEvadeLabel); - add(mStatsReflexLabel); - - add(mStatsAttackPoints); - add(mStatsDefensePoints); - add(mStatsMagicAttackPoints); - add(mStatsMagicDefensePoints); - add(mStatsAccuracyPoints); - add(mStatsEvadePoints); - add(mStatsReflexPoints);*/ - - add(mCharacterPointsLabel); - add(mCorrectionPointsLabel); + loadWindowState(); } void StatusWindow::update() { // Status Part // ----------- - mLvlLabel->setCaption( "Level: " + - toString(mPlayer->getLevel()) + - " (" + - toString(mPlayer->getLevelProgress()) + - "%)"); + mLvlLabel->setCaption(strprintf(_("Level: %d"), mPlayer->getLevel())); mLvlLabel->adjustSize(); - mMoneyLabel->setCaption("Money: " + toString(mPlayer->getMoney()) + " GP"); - mMoneyLabel->adjustSize(); + mJobLvlLabel->setCaption(strprintf(_("Job: %d"), mPlayer->mJobLevel)); + mJobLvlLabel->adjustSize(); - int hp = mPlayer->getHP(); - int maxHp = mPlayer->getMaxHP(); + if (mCurrency != mPlayer->getMoney()) { + mCurrency = mPlayer->getMoney(); + mGpLabel->setCaption(strprintf(_("Money: %s"), + Units::formatCurrency(mCurrency).c_str())); + mGpLabel->adjustSize(); + } + + mHpBar->setText(toString(mPlayer->getHp()) + + "/" + toString(mPlayer->getMaxHp())); + + mMpBar->setText(toString(mPlayer->mMp) + + "/" + toString(mPlayer->mMaxMp)); - mHpValueLabel->setCaption(toString(hp) + - " / " + toString(maxHp)); - mHpValueLabel->adjustSize(); + mXpBar->setText(toString(mPlayer->getXp()) + + "/" + toString(mPlayer->mXpForNextLevel)); + + mJobBar->setText(toString(mPlayer->mJobXp) + + "/" + toString(mPlayer->mJobXpForNextLevel)); // HP Bar coloration - if (hp < int(maxHp / 3)) + if (mPlayer->getHp() < int(mPlayer->getMaxHp() / 3)) { mHpBar->setColor(223, 32, 32); // Red } - else if (hp < int((maxHp / 3) * 2)) + else if (mPlayer->getHp() < int((mPlayer->getMaxHp() / 3) * 2)) { mHpBar->setColor(230, 171, 34); // Orange } @@ -229,43 +207,43 @@ void StatusWindow::update() mHpBar->setColor(0, 171, 34); // Green } - mHpBar->setProgress((float) hp / maxHp); + mHpBar->setProgress((float) mPlayer->getHp() / (float) mPlayer->getMaxHp()); + mMpBar->setProgress((float) mPlayer->mMp / (float) mPlayer->mMaxMp); + + mXpBar->setProgress( + (float) mPlayer->getXp() / (float) mPlayer->mXpForNextLevel); + mJobBar->setProgress( + (float) mPlayer->mJobXp / (float) mPlayer->mJobXpForNextLevel); // Stats Part // ---------- - const std::string attrNames[6] = { - "Strength", - "Agility", - "Dexterity", - "Vitality", - "Intelligence", - "Willpower" + static const char *attrNames[6] = { + N_("Strength"), + N_("Agility"), + N_("Vitality"), + N_("Intelligence"), + N_("Dexterity"), + N_("Luck") }; - int characterPoints = mPlayer->getCharacterPoints(); - int correctionPoints = mPlayer->getCorrectionPoints(); + int statusPoints = mPlayer->mStatsPointsToAttribute; + // Update labels for (int i = 0; i < 6; i++) { - mStatsLabel[i]->setCaption(attrNames[i]); - mStatsDisplayLabel[i]->setCaption( - strprintf("%d / %d", - mPlayer->getAttributeEffective(CHAR_ATTR_BEGIN + i), - mPlayer->getAttributeBase(CHAR_ATTR_BEGIN + i))); + mStatsLabel[i]->setCaption(gettext(attrNames[i])); + mStatsDisplayLabel[i]->setCaption(toString((int) mPlayer->mAttr[i])); + mPointsLabel[i]->setCaption(toString((int) mPlayer->mAttrUp[i])); mStatsLabel[i]->adjustSize(); mStatsDisplayLabel[i]->adjustSize(); + mPointsLabel[i]->adjustSize(); - mStatsPlus[i]->setEnabled(characterPoints); - mStatsMinus[i]->setEnabled(correctionPoints); + mStatsButton[i]->setEnabled(mPlayer->mAttrUp[i] <= statusPoints); } - mCharacterPointsLabel->setCaption("Character Points: " + - toString(characterPoints)); - mCharacterPointsLabel->adjustSize(); + mRemainingStatsPointsLabel->setCaption( + strprintf(_("Remaining Status Points: %d"), statusPoints)); + mRemainingStatsPointsLabel->adjustSize(); - mCorrectionPointsLabel->setCaption("Correction Points: " + - toString(correctionPoints)); - mCorrectionPointsLabel->adjustSize(); -/* // Derived Stats Points // Attack TODO: Count equipped Weapons and items attack bonuses @@ -299,11 +277,6 @@ void StatusWindow::update() // Reflex % mStatsReflexPoints->setCaption(toString(mPlayer->DEX / 4)); // + counter mStatsReflexPoints->adjustSize(); -*/ - // Update Second column widgets position - mMoneyLabel->setPosition(mLvlLabel->getX() + mLvlLabel->getWidth() + 20, - mLvlLabel->getY()); - } void StatusWindow::draw(gcn::Graphics *g) @@ -315,56 +288,33 @@ void StatusWindow::draw(gcn::Graphics *g) void StatusWindow::action(const gcn::ActionEvent &event) { - const std::string &eventId = event.getId(); - // Stats Part - if (eventId == "STR+") - { - mPlayer->raiseAttribute(LocalPlayer::STR); - } - else if (eventId == "AGI+") - { - mPlayer->raiseAttribute(LocalPlayer::AGI); - } - else if (eventId == "DEX+") + if (event.getId().length() == 3) { - mPlayer->raiseAttribute(LocalPlayer::DEX); - } - else if (eventId == "VIT+") - { - mPlayer->raiseAttribute(LocalPlayer::VIT); - } - else if (eventId == "INT+") - { - mPlayer->raiseAttribute(LocalPlayer::INT); - } - else if (eventId == "WIL+") - { - mPlayer->raiseAttribute(LocalPlayer::WIL); - } - - else if (eventId == "STR-") - { - mPlayer->lowerAttribute(LocalPlayer::STR); - } - else if (eventId == "AGI-") - { - mPlayer->lowerAttribute(LocalPlayer::AGI); - } - else if (eventId == "DEX-") - { - mPlayer->lowerAttribute(LocalPlayer::DEX); - } - else if (eventId == "VIT-") - { - mPlayer->lowerAttribute(LocalPlayer::VIT); - } - else if (eventId == "INT-") - { - mPlayer->lowerAttribute(LocalPlayer::INT); - } - else if (eventId == "WIL-") - { - mPlayer->lowerAttribute(LocalPlayer::WIL); + if (event.getId() == "STR") + { + player_node->raiseAttribute(LocalPlayer::STR); + } + if (event.getId() == "AGI") + { + player_node->raiseAttribute(LocalPlayer::AGI); + } + if (event.getId() == "VIT") + { + player_node->raiseAttribute(LocalPlayer::VIT); + } + if (event.getId() == "INT") + { + player_node->raiseAttribute(LocalPlayer::INT); + } + if (event.getId() == "DEX") + { + player_node->raiseAttribute(LocalPlayer::DEX); + } + if (event.getId() == "LUK") + { + player_node->raiseAttribute(LocalPlayer::LUK); + } } } + diff --git a/src/gui/status.h b/src/gui/status.h index 262b89f6..9e4de3fd 100644 --- a/src/gui/status.h +++ b/src/gui/status.h @@ -1,39 +1,34 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TMW_STATUS_H -#define _TMW_STATUS_H - -#include <iosfwd> +#ifndef STATUS_H +#define STATUS_H #include <guichan/actionlistener.hpp> #include "window.h" -#include "../guichanfwd.h" - class LocalPlayer; class ProgressBar; - /** * The player status dialog. * @@ -68,13 +63,16 @@ class StatusWindow : public Window, public gcn::ActionListener /** * Status Part */ - gcn::Label *mLvlLabel, *mMoneyLabel, *mHpLabel, *mHpValueLabel; - ProgressBar *mHpBar; + gcn::Label *mLvlLabel, *mJobLvlLabel; + gcn::Label *mGpLabel; + int mCurrency; + gcn::Label *mHpLabel, *mMpLabel, *mXpLabel, *mJobLabel; + ProgressBar *mHpBar, *mMpBar; + ProgressBar *mXpBar, *mJobBar; /** * Derived Statistics captions */ -/* gcn::Label *mStatsAttackLabel, *mStatsDefenseLabel; gcn::Label *mStatsMagicAttackLabel, *mStatsMagicDefenseLabel; gcn::Label *mStatsAccuracyLabel, *mStatsEvadeLabel; @@ -84,20 +82,19 @@ class StatusWindow : public Window, public gcn::ActionListener gcn::Label *mStatsMagicAttackPoints, *mStatsMagicDefensePoints; gcn::Label *mStatsAccuracyPoints, *mStatsEvadePoints; gcn::Label *mStatsReflexPoints; -*/ + /** * Stats captions. */ gcn::Label *mStatsLabel[6]; + gcn::Label *mPointsLabel[6]; gcn::Label *mStatsDisplayLabel[6]; - gcn::Label *mCharacterPointsLabel; - gcn::Label *mCorrectionPointsLabel; + gcn::Label *mRemainingStatsPointsLabel; /** * Stats buttons. */ - gcn::Button *mStatsPlus[6]; - gcn::Button *mStatsMinus[6]; + gcn::Button *mStatsButton[6]; }; extern StatusWindow *statusWindow; diff --git a/src/gui/statuswindow.cpp b/src/gui/statuswindow.cpp new file mode 100644 index 00000000..bcac0a90 --- /dev/null +++ b/src/gui/statuswindow.cpp @@ -0,0 +1,370 @@ +/* + * The Mana World + * Copyright 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * The Mana World 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. + * + * The Mana World 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 The Mana World; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "statuswindow.h" + +#include <guichan/widgets/label.hpp> + +#include "button.h" +#include "progressbar.h" +#include "windowcontainer.h" + +#include "../localplayer.h" + +#include "../utils/strprintf.h" +#include "../utils/stringutils.h" + +StatusWindow::StatusWindow(LocalPlayer *player): + Window(player->getName()), + mPlayer(player) +{ + setWindowName("Status"); + setResizable(true); + setCloseButton(true); + setDefaultSize((windowContainer->getWidth() - 365) / 2, + (windowContainer->getHeight() - 255) / 2, 365, 275); + loadWindowState(); + + // ---------------------- + // Status Part + // ---------------------- + + mLvlLabel = new gcn::Label("Level:"); + mMoneyLabel = new gcn::Label("Money:"); + + mHpLabel = new gcn::Label("HP:"); + mHpBar = new ProgressBar(1.0f, 80, 15, 0, 171, 34); + mHpValueLabel = new gcn::Label(""); + + int y = 3; + int x = 5; + + mLvlLabel->setPosition(x, y); + x += mLvlLabel->getWidth() + 40; + mMoneyLabel->setPosition(x, y); + + y += mLvlLabel->getHeight() + 5; // Next Row + x = 5; + + mHpLabel->setPosition(x, y); + x += mHpLabel->getWidth() + 5; + mHpBar->setPosition(x, y); + x += mHpBar->getWidth() + 5; + mHpValueLabel->setPosition(x, y); + + y += mHpLabel->getHeight() + 5; // Next Row + x = 5; + + add(mLvlLabel); + add(mMoneyLabel); + add(mHpLabel); + add(mHpValueLabel); + add(mHpBar); + + // ---------------------- + // Stats Part + // ---------------------- + + // Static Labels + gcn::Label *mStatsTitleLabel = new gcn::Label("Stats"); + gcn::Label *mStatsTotalLabel = new gcn::Label("Total"); + + // Derived Stats +/* + mStatsAttackLabel = new gcn::Label("Attack:"); + mStatsDefenseLabel= new gcn::Label("Defense:"); + mStatsMagicAttackLabel = new gcn::Label("M.Attack:"); + mStatsMagicDefenseLabel = new gcn::Label("M.Defense:"); + mStatsAccuracyLabel = new gcn::Label("% Accuracy:"); + mStatsEvadeLabel = new gcn::Label("% Evade:"); + mStatsReflexLabel = new gcn::Label("% Reflex:"); + + mStatsAttackPoints = new gcn::Label(""); + mStatsDefensePoints = new gcn::Label(""); + mStatsMagicAttackPoints = new gcn::Label(""); + mStatsMagicDefensePoints = new gcn::Label(""); + mStatsAccuracyPoints = new gcn::Label("% Accuracy:"); + mStatsEvadePoints = new gcn::Label("% Evade:"); + mStatsReflexPoints = new gcn::Label("% Reflex:"); +*/ + // New labels + for (int i = 0; i < 6; i++) { + mStatsLabel[i] = new gcn::Label(); + mStatsDisplayLabel[i] = new gcn::Label(); + } + mCharacterPointsLabel = new gcn::Label(); + mCorrectionPointsLabel = new gcn::Label(); + + // Set button events Id + mStatsPlus[0] = new Button("+", "STR+", this); + mStatsPlus[1] = new Button("+", "AGI+", this); + mStatsPlus[2] = new Button("+", "DEX+", this); + mStatsPlus[3] = new Button("+", "VIT+", this); + mStatsPlus[4] = new Button("+", "INT+", this); + mStatsPlus[5] = new Button("+", "WIL+", this); + + mStatsMinus[0] = new Button("-", "STR-", this); + mStatsMinus[1] = new Button("-", "AGI-", this); + mStatsMinus[2] = new Button("-", "DEX-", this); + mStatsMinus[3] = new Button("-", "VIT-", this); + mStatsMinus[4] = new Button("-", "INT-", this); + mStatsMinus[5] = new Button("-", "WIL-", this); + + + + // Set position + mStatsTitleLabel->setPosition(mHpLabel->getX(), mHpLabel->getY() + 23 ); + mStatsTotalLabel->setPosition(110, mStatsTitleLabel->getY() + 15); + int totalLabelY = mStatsTotalLabel->getY(); + + for (int i = 0; i < 6; i++) + { + mStatsLabel[i]->setPosition(5, + mStatsTotalLabel->getY() + (i * 23) + 15); + mStatsMinus[i]->setPosition(85, totalLabelY + (i * 23) + 15); + mStatsDisplayLabel[i]->setPosition(125, + totalLabelY + (i * 23) + 15); + mStatsPlus[i]->setPosition(185, totalLabelY + (i * 23) + 15); + } + + mCharacterPointsLabel->setPosition(5, mStatsDisplayLabel[5]->getY() + 25); + mCorrectionPointsLabel->setPosition(5, mStatsDisplayLabel[5]->getY() + 35); +/* + mStatsAttackLabel->setPosition(220, mStatsLabel[0]->getY()); + mStatsDefenseLabel->setPosition(220, mStatsLabel[1]->getY()); + mStatsMagicAttackLabel->setPosition(220, mStatsLabel[2]->getY()); + mStatsMagicDefenseLabel->setPosition(220, mStatsLabel[3]->getY()); + mStatsAccuracyLabel->setPosition(220, mStatsLabel[4]->getY()); + mStatsEvadeLabel->setPosition(220, mStatsLabel[5]->getY()); + mStatsReflexLabel->setPosition(220, mStatsLabel[6]->getY()); + + mStatsAttackPoints->setPosition(310, mStatsLabel[0]->getY()); + mStatsDefensePoints->setPosition(310, mStatsLabel[1]->getY()); + mStatsMagicAttackPoints->setPosition(310, mStatsLabel[2]->getY()); + mStatsMagicDefensePoints->setPosition(310, mStatsLabel[3]->getY()); + mStatsAccuracyPoints->setPosition(310, mStatsLabel[4]->getY()); + mStatsEvadePoints->setPosition(310, mStatsLabel[5]->getY()); + mStatsReflexPoints->setPosition(310, mStatsLabel[6]->getY()); +*/ + // Assemble + add(mStatsTitleLabel); + add(mStatsTotalLabel); + for(int i = 0; i < 6; i++) + { + add(mStatsLabel[i]); + add(mStatsDisplayLabel[i]); + add(mStatsPlus[i]); + add(mStatsMinus[i]); + }/* + add(mStatsAttackLabel); + add(mStatsDefenseLabel); + add(mStatsMagicAttackLabel); + add(mStatsMagicDefenseLabel); + add(mStatsAccuracyLabel); + add(mStatsEvadeLabel); + add(mStatsReflexLabel); + + add(mStatsAttackPoints); + add(mStatsDefensePoints); + add(mStatsMagicAttackPoints); + add(mStatsMagicDefensePoints); + add(mStatsAccuracyPoints); + add(mStatsEvadePoints); + add(mStatsReflexPoints);*/ + + add(mCharacterPointsLabel); + add(mCorrectionPointsLabel); +} + +void StatusWindow::update() +{ + // Status Part + // ----------- + mLvlLabel->setCaption( "Level: " + + toString(mPlayer->getLevel()) + + " (" + + toString(mPlayer->getLevelProgress()) + + "%)"); + mLvlLabel->adjustSize(); + + mMoneyLabel->setCaption("Money: " + toString(mPlayer->getMoney()) + " GP"); + mMoneyLabel->adjustSize(); + + int hp = mPlayer->getHp(); + int maxHp = mPlayer->getMaxHp(); + + mHpValueLabel->setCaption(toString(hp) + + " / " + toString(maxHp)); + mHpValueLabel->adjustSize(); + + // HP Bar coloration + if (hp < int(maxHp / 3)) + { + mHpBar->setColor(223, 32, 32); // Red + } + else if (hp < int((maxHp / 3) * 2)) + { + mHpBar->setColor(230, 171, 34); // Orange + } + else + { + mHpBar->setColor(0, 171, 34); // Green + } + + mHpBar->setProgress((float) hp / maxHp); + + // Stats Part + // ---------- + const std::string attrNames[6] = { + "Strength", + "Agility", + "Dexterity", + "Vitality", + "Intelligence", + "Willpower" + }; + int characterPoints = mPlayer->getCharacterPoints(); + int correctionPoints = mPlayer->getCorrectionPoints(); + // Update labels + for (int i = 0; i < 6; i++) + { + mStatsLabel[i]->setCaption(attrNames[i]); + mStatsDisplayLabel[i]->setCaption( + strprintf("%d / %d", + mPlayer->getAttributeEffective(CHAR_ATTR_BEGIN + i), + mPlayer->getAttributeBase(CHAR_ATTR_BEGIN + i))); + + mStatsLabel[i]->adjustSize(); + mStatsDisplayLabel[i]->adjustSize(); + + mStatsPlus[i]->setEnabled(characterPoints); + mStatsMinus[i]->setEnabled(correctionPoints); + } + mCharacterPointsLabel->setCaption("Character Points: " + + toString(characterPoints)); + mCharacterPointsLabel->adjustSize(); + + mCorrectionPointsLabel->setCaption("Correction Points: " + + toString(correctionPoints)); + mCorrectionPointsLabel->adjustSize(); +/* + // Derived Stats Points + + // Attack TODO: Count equipped Weapons and items attack bonuses + mStatsAttackPoints->setCaption( + toString(mPlayer->ATK + mPlayer->ATK_BONUS)); + mStatsAttackPoints->adjustSize(); + + // Defense TODO: Count equipped Armors and items defense bonuses + mStatsDefensePoints->setCaption( + toString(mPlayer->DEF + mPlayer->DEF_BONUS)); + mStatsDefensePoints->adjustSize(); + + // Magic Attack TODO: Count equipped items M.Attack bonuses + mStatsMagicAttackPoints->setCaption( + toString(mPlayer->MATK + mPlayer->MATK_BONUS)); + mStatsMagicAttackPoints->adjustSize(); + + // Magic Defense TODO: Count equipped items M.Defense bonuses + mStatsMagicDefensePoints->setCaption( + toString(mPlayer->MDEF + mPlayer->MDEF_BONUS)); + mStatsMagicDefensePoints->adjustSize(); + + // Accuracy % + mStatsAccuracyPoints->setCaption(toString(mPlayer->HIT)); + mStatsAccuracyPoints->adjustSize(); + + // Evasion % + mStatsEvadePoints->setCaption(toString(mPlayer->FLEE)); + mStatsEvadePoints->adjustSize(); + + // Reflex % + mStatsReflexPoints->setCaption(toString(mPlayer->DEX / 4)); // + counter + mStatsReflexPoints->adjustSize(); +*/ + // Update Second column widgets position + mMoneyLabel->setPosition(mLvlLabel->getX() + mLvlLabel->getWidth() + 20, + mLvlLabel->getY()); + +} + +void StatusWindow::draw(gcn::Graphics *g) +{ + update(); + + Window::draw(g); +} + +void StatusWindow::action(const gcn::ActionEvent &event) +{ + const std::string &eventId = event.getId(); + + // Stats Part + if (eventId == "STR+") + { + mPlayer->raiseAttribute(LocalPlayer::STR); + } + else if (eventId == "AGI+") + { + mPlayer->raiseAttribute(LocalPlayer::AGI); + } + else if (eventId == "DEX+") + { + mPlayer->raiseAttribute(LocalPlayer::DEX); + } + else if (eventId == "VIT+") + { + mPlayer->raiseAttribute(LocalPlayer::VIT); + } + else if (eventId == "INT+") + { + mPlayer->raiseAttribute(LocalPlayer::INT); + } + else if (eventId == "WIL+") + { + mPlayer->raiseAttribute(LocalPlayer::WIL); + } + + else if (eventId == "STR-") + { + mPlayer->lowerAttribute(LocalPlayer::STR); + } + else if (eventId == "AGI-") + { + mPlayer->lowerAttribute(LocalPlayer::AGI); + } + else if (eventId == "DEX-") + { + mPlayer->lowerAttribute(LocalPlayer::DEX); + } + else if (eventId == "VIT-") + { + mPlayer->lowerAttribute(LocalPlayer::VIT); + } + else if (eventId == "INT-") + { + mPlayer->lowerAttribute(LocalPlayer::INT); + } + else if (eventId == "WIL-") + { + mPlayer->lowerAttribute(LocalPlayer::WIL); + } +} diff --git a/src/gui/statuswindow.h b/src/gui/statuswindow.h new file mode 100644 index 00000000..262b89f6 --- /dev/null +++ b/src/gui/statuswindow.h @@ -0,0 +1,105 @@ +/* + * The Mana World + * Copyright 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * The Mana World 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. + * + * The Mana World 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 The Mana World; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _TMW_STATUS_H +#define _TMW_STATUS_H + +#include <iosfwd> + +#include <guichan/actionlistener.hpp> + +#include "window.h" + +#include "../guichanfwd.h" + +class LocalPlayer; +class ProgressBar; + + +/** + * The player status dialog. + * + * \ingroup Interface + */ +class StatusWindow : public Window, public gcn::ActionListener +{ + public: + /** + * Constructor. + */ + StatusWindow(LocalPlayer *player); + + /** + * Called when receiving actions from widget. + */ + void action(const gcn::ActionEvent &event); + + /** + * Draw this window + */ + void draw(gcn::Graphics *graphics); + + /** + * Updates this dialog with values from PLAYER_INFO *char_info + */ + void update(); + + private: + LocalPlayer *mPlayer; + + /** + * Status Part + */ + gcn::Label *mLvlLabel, *mMoneyLabel, *mHpLabel, *mHpValueLabel; + ProgressBar *mHpBar; + + /** + * Derived Statistics captions + */ +/* + gcn::Label *mStatsAttackLabel, *mStatsDefenseLabel; + gcn::Label *mStatsMagicAttackLabel, *mStatsMagicDefenseLabel; + gcn::Label *mStatsAccuracyLabel, *mStatsEvadeLabel; + gcn::Label *mStatsReflexLabel; + + gcn::Label *mStatsAttackPoints, *mStatsDefensePoints; + gcn::Label *mStatsMagicAttackPoints, *mStatsMagicDefensePoints; + gcn::Label *mStatsAccuracyPoints, *mStatsEvadePoints; + gcn::Label *mStatsReflexPoints; +*/ + /** + * Stats captions. + */ + gcn::Label *mStatsLabel[6]; + gcn::Label *mStatsDisplayLabel[6]; + gcn::Label *mCharacterPointsLabel; + gcn::Label *mCorrectionPointsLabel; + + /** + * Stats buttons. + */ + gcn::Button *mStatsPlus[6]; + gcn::Button *mStatsMinus[6]; +}; + +extern StatusWindow *statusWindow; + +#endif diff --git a/src/gui/table.cpp b/src/gui/table.cpp new file mode 100644 index 00000000..1fd088ce --- /dev/null +++ b/src/gui/table.cpp @@ -0,0 +1,561 @@ +/* + * 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 <guichan/actionlistener.hpp> +#include <guichan/graphics.hpp> +#include <guichan/key.hpp> + +#include "color.h" +#include "table.h" + +#include "../configuration.h" + +#include "../utils/dtor.h" + +float GuiTable::mAlpha = config.getValue("guialpha", 0.8); + +class GuiTableActionListener : public gcn::ActionListener +{ +public: + GuiTableActionListener(GuiTable *_table, gcn::Widget *_widget, int _row, int _column); + + virtual ~GuiTableActionListener(); + + virtual void action(const gcn::ActionEvent& actionEvent); + +protected: + GuiTable *mTable; + int mRow; + int mColumn; + gcn::Widget *mWidget; +}; + + +GuiTableActionListener::GuiTableActionListener(GuiTable *table, gcn::Widget *widget, int row, int column) : + mTable(table), + mRow(row), + mColumn(column), + mWidget(widget) +{ + if (widget) + { + widget->addActionListener(this); + widget->_setParent(table); + } +} + +GuiTableActionListener::~GuiTableActionListener() +{ + if (mWidget) + { + mWidget->removeActionListener(this); + mWidget->_setParent(NULL); + } +} + +void GuiTableActionListener::action(const gcn::ActionEvent& actionEvent) +{ + mTable->setSelected(mRow, mColumn); + mTable->distributeActionEvent(); +} + + +GuiTable::GuiTable(TableModel *initial_model, gcn::Color background, + bool opacity) : + mLinewiseMode(false), + mWrappingEnabled(false), + mOpaque(opacity), + mBackgroundColor(background), + mModel(NULL), + mSelectedRow(0), + mSelectedColumn(0), + mTopWidget(NULL) +{ + setModel(initial_model); + setFocusable(true); + + addMouseListener(this); + addKeyListener(this); +} + +GuiTable::~GuiTable() +{ + delete mModel; +} + +TableModel *GuiTable::getModel() const +{ + return mModel; +} + +void GuiTable::setModel(TableModel *new_model) +{ + if (mModel) + { + uninstallActionListeners(); + mModel->removeListener(this); + } + + mModel = new_model; + installActionListeners(); + + if (new_model) + { + new_model->installListener(this); + recomputeDimensions(); + } +} + +void GuiTable::recomputeDimensions() +{ + int rows_nr = mModel->getRows(); + int columns_nr = mModel->getColumns(); + int width = 0; + int height = 0; + + if (mSelectedRow >= rows_nr) + mSelectedRow = rows_nr - 1; + + if (mSelectedColumn >= columns_nr) + mSelectedColumn = columns_nr - 1; + + for (int i = 0; i < columns_nr; i++) + width += getColumnWidth(i); + + height = getRowHeight() * rows_nr; + + setWidth(width); + setHeight(height); +} + +void GuiTable::setSelected(int row, int column) +{ + mSelectedColumn = column; + mSelectedRow = row; +} + +int GuiTable::getSelectedRow() +{ + return mSelectedRow; +} + +int GuiTable::getSelectedColumn() +{ + return mSelectedColumn; +} + +void GuiTable::setLinewiseSelection(bool linewise) +{ + mLinewiseMode = linewise; +} + +int GuiTable::getRowHeight() +{ + if (mModel) + return mModel->getRowHeight() + 1; // border + else + return 0; +} + +int GuiTable::getColumnWidth(int i) +{ + if (mModel) + return mModel->getColumnWidth(i) + 1; // border + else + return 0; +} + +void GuiTable::setSelectedRow(int selected) +{ + if (!mModel) + { + mSelectedRow = -1; + } + else + { + if (selected < 0 && !mWrappingEnabled) + { + mSelectedRow = -1; + } + else if (selected >= mModel->getRows() && mWrappingEnabled) + { + mSelectedRow = 0; + } + else if ((selected >= mModel->getRows() && !mWrappingEnabled) || + (selected < 0 && mWrappingEnabled)) + { + mSelectedRow = mModel->getRows() - 1; + } + else + { + mSelectedRow = selected; + } + } +} + +void GuiTable::setSelectedColumn(int selected) +{ + if (!mModel) + { + mSelectedColumn = -1; + } + else + { + if ((selected >= mModel->getColumns() && mWrappingEnabled) || + (selected < 0 && !mWrappingEnabled)) + { + mSelectedColumn = 0; + } + else if ((selected >= mModel->getColumns() && !mWrappingEnabled) || + (selected < 0 && mWrappingEnabled)) + { + mSelectedColumn = mModel->getColumns() - 1; + } + else + { + mSelectedColumn = selected; + } + } +} + +void GuiTable::uninstallActionListeners(void) +{ + delete_all(mActionListeners); + mActionListeners.clear(); +} + +void GuiTable::installActionListeners() +{ + if (!mModel) + return; + + int rows = mModel->getRows(); + int columns = mModel->getColumns(); + + for (int row = 0; row < rows; ++row) + for (int column = 0; column < columns; ++column) + { + gcn::Widget *widget = mModel->getElementAt(row, column); + mActionListeners.push_back(new GuiTableActionListener(this, widget, + row, column)); + } + + _setFocusHandler(_getFocusHandler()); // propagate focus handler to widgets +} + +// -- widget ops +void GuiTable::draw(gcn::Graphics* graphics) +{ + if (!mModel) + return; + + if (config.getValue("guialpha", 0.8) != mAlpha) + mAlpha = config.getValue("guialpha", 0.8); + + if (mOpaque) + { + const int red = getBackgroundColor().r; + const int green = getBackgroundColor().g; + const int blue = getBackgroundColor().b; + const int alpha = (int)(mAlpha * 255.0f); + graphics->setColor(gcn::Color(red, green, blue, alpha)); + graphics->fillRectangle(gcn::Rectangle(0, 0, getWidth(), getHeight())); + } + + // First, determine how many rows we need to draw, and where we should start. + int first_row = -(getY() / getRowHeight()); + + if (first_row < 0) + first_row = 0; + + int rows_nr = 1 + (getHeight() / getRowHeight()); // May overestimate by one. + + int max_rows_nr = mModel->getRows() - first_row; // clip if neccessary: + if (max_rows_nr < rows_nr) + rows_nr = max_rows_nr; + + // Now determine the first and last column + // Take the easy way out; these are usually bounded and all visible. + int first_column = 0; + int last_column = mModel->getColumns() - 1; + + // Set up everything for drawing + int height = getRowHeight(); + int y_offset = first_row * height; + + for (int r = first_row; r < first_row + rows_nr; ++r) + { + int x_offset = 0; + + for (int c = first_column; c <= last_column; ++c) + { + gcn::Widget *widget = mModel->getElementAt(r, c); + int width = getColumnWidth(c); + if (widget) + { + gcn::Rectangle bounds(x_offset, y_offset, width, height); + + if (widget == mTopWidget) + { + bounds.height = widget->getHeight(); + bounds.width = widget->getWidth(); + } + + widget->setDimension(bounds); + + if (!mLinewiseMode && c == mSelectedColumn && r == mSelectedRow) + { + bool valid; + const int red = + (textColor->getColor('H', valid) >> 16) & 0xFF; + const int green = + (textColor->getColor('H', valid) >> 8) & 0xFF; + const int blue = textColor->getColor('H', valid) & 0xFF; + const int alpha = (int)(mAlpha * 127.0f); + + graphics->setColor(gcn::Color(red, green, blue, alpha)); + graphics->fillRectangle(bounds); + } + + graphics->pushClipArea(bounds); + widget->draw(graphics); + graphics->popClipArea(); + } + + x_offset += width; + } + + if (mLinewiseMode && r == mSelectedRow) + { + bool valid; + const int red = + (textColor->getColor('H', valid) >> 16) & 0xFF; + const int green = + (textColor->getColor('H', valid) >> 8) & 0xFF; + const int blue = textColor->getColor('H', valid) & 0xFF; + const int alpha = (int)(mAlpha * 127.0f); + + graphics->setColor(gcn::Color(red, green, blue, alpha)); + graphics->fillRectangle(gcn::Rectangle(0, y_offset, + x_offset, height)); + } + + y_offset += height; + } + + if (mTopWidget) + { + gcn::Rectangle bounds = mTopWidget->getDimension(); + graphics->pushClipArea(bounds); + mTopWidget->draw(graphics); + graphics->popClipArea(); + } +} + +void GuiTable::moveToTop(gcn::Widget *widget) +{ + gcn::Widget::moveToTop(widget); + mTopWidget = widget; +} + +void GuiTable::moveToBottom(gcn::Widget *widget) +{ + gcn::Widget::moveToBottom(widget); + if (widget == mTopWidget) + mTopWidget = NULL; +} + +gcn::Rectangle GuiTable::getChildrenArea() +{ + return gcn::Rectangle(0, 0, getWidth(), getHeight()); +} + +// -- KeyListener notifications +void GuiTable::keyPressed(gcn::KeyEvent& keyEvent) +{ + gcn::Key key = keyEvent.getKey(); + + if (key.getValue() == gcn::Key::ENTER || key.getValue() == gcn::Key::SPACE) + { + distributeActionEvent(); + keyEvent.consume(); + } + else if (key.getValue() == gcn::Key::UP) + { + setSelectedRow(mSelectedRow - 1); + + keyEvent.consume(); + } + else if (key.getValue() == gcn::Key::DOWN) + { + setSelectedRow(mSelectedRow + 1); + + keyEvent.consume(); + } + else if (key.getValue() == gcn::Key::LEFT) + { + setSelectedColumn(mSelectedColumn - 1); + + keyEvent.consume(); + } + else if (key.getValue() == gcn::Key::RIGHT) + { + setSelectedColumn(mSelectedColumn + 1); + + keyEvent.consume(); + } + else if (key.getValue() == gcn::Key::HOME) + { + setSelectedRow(0); + setSelectedColumn(0); + keyEvent.consume(); + } + else if (key.getValue() == gcn::Key::END) + { + setSelectedRow(mModel->getRows() - 1); + setSelectedColumn(mModel->getColumns() - 1); + keyEvent.consume(); + } +} + +// -- MouseListener notifications +void GuiTable::mousePressed(gcn::MouseEvent& mouseEvent) +{ + if (mouseEvent.getButton() == gcn::MouseEvent::LEFT) + { + int row = getRowForY(mouseEvent.getY()); + int column = getColumnForX(mouseEvent.getX()); + + if (row > -1 && column > -1 && + row < mModel->getRows() && column < mModel->getColumns()) + { + mSelectedColumn = column; + mSelectedRow = row; + } + + distributeActionEvent(); + } +} + +void GuiTable::mouseWheelMovedUp(gcn::MouseEvent& mouseEvent) +{ + if (isFocused()) + { + if (getSelectedRow() >= 0 ) + { + setSelectedRow(getSelectedRow() - 1); + } + + mouseEvent.consume(); + } +} + +void GuiTable::mouseWheelMovedDown(gcn::MouseEvent& mouseEvent) +{ + if (isFocused()) + { + setSelectedRow(getSelectedRow() + 1); + + mouseEvent.consume(); + } +} + +void GuiTable::mouseDragged(gcn::MouseEvent& mouseEvent) +{ +} + +// -- TableModelListener notifications +void GuiTable::modelUpdated(bool completed) +{ + if (completed) + { + recomputeDimensions(); + installActionListeners(); + } + else + { // before the update? + mTopWidget = NULL; // No longer valid in general + uninstallActionListeners(); + } +} + +gcn::Widget *GuiTable::getWidgetAt(int x, int y) +{ + int row = getRowForY(y); + int column = getColumnForX(x); + + if (mTopWidget && mTopWidget->getDimension().isPointInRect(x, y)) + return mTopWidget; + + if (row > -1 && column > -1) + { + gcn::Widget *w = mModel->getElementAt(row, column); + if (w && w->isFocusable()) + return w; + else + return NULL; // Grab the event locally + } + else + return NULL; +} + +int GuiTable::getRowForY(int y) +{ + int row = y / getRowHeight(); + + if (row < 0 || row >= mModel->getRows()) + return -1; + else + return row; +} + +int GuiTable::getColumnForX(int x) +{ + int column; + int delta = 0; + + for (column = 0; column < mModel->getColumns(); column++) + { + delta += getColumnWidth(column); + if (x <= delta) + break; + } + + if (column < 0 || column >= mModel->getColumns()) + return -1; + else + return column; +} + +void GuiTable::_setFocusHandler(gcn::FocusHandler* focusHandler) +{ + gcn::Widget::_setFocusHandler(focusHandler); + + if (mModel) { + for (int r = 0; r < mModel->getRows(); ++r) { + for (int c = 0; c < mModel->getColumns(); ++c) { + gcn::Widget *w = mModel->getElementAt(r, c); + if (w) + w->_setFocusHandler(focusHandler); + } + } + } +} diff --git a/src/gui/table.h b/src/gui/table.h new file mode 100644 index 00000000..d73cf340 --- /dev/null +++ b/src/gui/table.h @@ -0,0 +1,187 @@ +/* + * 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 + */ + +#ifndef TABLE_H +#define TABLE_H + +#include <vector> + +#include <guichan/keylistener.hpp> +#include <guichan/mouselistener.hpp> +#include <guichan/widget.hpp> + +#include "table_model.h" + +class GuiTableActionListener; + +/** + * A table, with rows and columns made out of sub-widgets. Largely inspired by + * (and can be thought of as a generalisation of) the guichan listbox + * implementation. + * + * Normally you want this within a ScrollArea. + * + * \ingroup GUI + */ +class GuiTable : public gcn::Widget, + public gcn::MouseListener, + public gcn::KeyListener, + public TableModelListener +{ + // so that the action listener can call distributeActionEvent + friend class GuiTableActionListener; + +public: + GuiTable(TableModel * initial_model = NULL, gcn::Color background = 0xffffff, + bool opacity = true); + + virtual ~GuiTable(); + + /** + * Retrieves the active table model + */ + TableModel *getModel() const; + + /** + * Sets the table model + * + * Note that actions issued by widgets returned from the model will update + * the table selection, but only AFTER any event handlers installed within + * the widget have been triggered. To be notified after such an update, add + * an action listener to the table instead. + */ + void setModel(TableModel *m); + + const TableModel* getModel() {return mModel;} + + void setSelected(int row, int column); + + int getSelectedRow(); + + int getSelectedColumn(); + + void setSelectedRow(int selected); + + void setSelectedColumn(int selected); + + bool isWrappingEnabled() const {return mWrappingEnabled;} + + void setWrappingEnabled(bool wrappingEnabled) + {mWrappingEnabled = wrappingEnabled;} + + gcn::Rectangle getChildrenArea(void); + + /** + * Toggle whether to use linewise selection mode, in which the table selects + * an entire line at a time, rather than a single cell. + * + * Note that column information is tracked even in linewise selection mode; + * this mode therefore only affects visualisation. + * + * Disabled by default. + * + * \param linewise: Whether to enable linewise selection mode + */ + void setLinewiseSelection(bool linewise); + + // Inherited from Widget + virtual void draw(gcn::Graphics* graphics); + + virtual gcn::Widget *getWidgetAt(int x, int y); + + virtual void moveToTop(gcn::Widget *child); + + virtual void moveToBottom(gcn::Widget *child); + + virtual void _setFocusHandler(gcn::FocusHandler* focusHandler); + + // Inherited from KeyListener + virtual void keyPressed(gcn::KeyEvent& keyEvent); + + /** + * Sets the table to be opaque, that is sets the table + * to display its background. + * + * @param opaque True if the table should be opaque, false otherwise. + */ + virtual void setOpaque(bool opaque) {mOpaque = opaque;} + + /** + * Checks if the table is opaque, that is if the table area displays its + * background. + * + * @return True if the table is opaque, false otherwise. + */ + virtual bool isOpaque() const {return mOpaque;} + + // Inherited from MouseListener + virtual void mousePressed(gcn::MouseEvent& mouseEvent); + + virtual void mouseWheelMovedUp(gcn::MouseEvent& mouseEvent); + + virtual void mouseWheelMovedDown(gcn::MouseEvent& mouseEvent); + + virtual void mouseDragged(gcn::MouseEvent& mouseEvent); + + // Constraints inherited from TableModelListener + virtual void modelUpdated(bool); + +protected: + /** Frees all action listeners on inner widgets. */ + virtual void uninstallActionListeners(); + /** Installs all action listeners on inner widgets. */ + virtual void installActionListeners(); + + virtual int getRowHeight(); + virtual int getColumnWidth(int i); + +private: + int getRowForY(int y); // -1 on error + int getColumnForX(int x); // -1 on error + void recomputeDimensions(); + bool mLinewiseMode; + bool mWrappingEnabled; + bool mOpaque; + + static float mAlpha; + + /** + * Holds the background color of the table. + */ + gcn::Color mBackgroundColor; + + TableModel *mModel; + + int mSelectedRow; + int mSelectedColumn; + + /** Number of frames to skip upwards when drawing the selected widget. */ + int mPopFramesNr; + + /** If someone moves a fresh widget to the top, we must display it. */ + gcn::Widget *mTopWidget; + + /** Vector for compactness; used as a list in practice. */ + std::vector<GuiTableActionListener *> mActionListeners; +}; + + +#endif /* !defined(TABLE_H) */ diff --git a/src/gui/table_model.cpp b/src/gui/table_model.cpp new file mode 100644 index 00000000..4fa13bae --- /dev/null +++ b/src/gui/table_model.cpp @@ -0,0 +1,161 @@ +/* + * 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 <guichan/widget.hpp> + +#include "table_model.h" + +#include "../utils/dtor.h" + +void TableModel::installListener(TableModelListener *listener) +{ + listeners.insert(listener); +} + +void TableModel::removeListener(TableModelListener *listener) +{ + listeners.erase(listener); +} + +void TableModel::signalBeforeUpdate() +{ + for (std::set<TableModelListener *>::const_iterator it = listeners.begin(); it != listeners.end(); it++) + (*it)->modelUpdated(false); +} + +void TableModel::signalAfterUpdate() +{ + for (std::set<TableModelListener *>::const_iterator it = listeners.begin(); it != listeners.end(); it++) + (*it)->modelUpdated(true); +} + + +#define WIDGET_AT(row, column) (((row) * mColumns) + (column)) +#define DYN_SIZE(h) ((h) >= 0) // determines whether this size is tagged for auto-detection + +StaticTableModel::StaticTableModel(int row, int column) : + mRows(row), + mColumns(column), + mHeight(1) +{ + mTableModel.resize(row * column, NULL); + mWidths.resize(column, 1); +} + +StaticTableModel::~StaticTableModel() +{ + delete_all(mTableModel); +} + +void StaticTableModel::resize() +{ + mRows = getRows(); + mColumns = getColumns(); + mTableModel.resize(mRows * mColumns, NULL); +} + +void StaticTableModel::set(int row, int column, gcn::Widget *widget) +{ + if (row >= mRows || row < 0 + || column >= mColumns || column < 0) + // raise exn? + return; + + if (DYN_SIZE(mHeight) + && widget->getHeight() > mHeight) + mHeight = widget->getHeight(); + + if (DYN_SIZE(mWidths[column]) + && widget->getWidth() > mWidths[column]) + mWidths[column] = widget->getWidth(); + + signalBeforeUpdate(); + + if (mTableModel[WIDGET_AT(row, column)]) + delete mTableModel[WIDGET_AT(row, column)]; + + mTableModel[WIDGET_AT(row, column)] = widget; + + signalAfterUpdate(); +} + +gcn::Widget *StaticTableModel::getElementAt(int row, int column) +{ + return mTableModel[WIDGET_AT(row, column)]; +} + +void StaticTableModel::fixColumnWidth(int column, int width) +{ + if (width < 0 + || column < 0 || column >= mColumns) + return; + + mWidths[column] = -width; // Negate to tag as fixed +} + +void StaticTableModel::fixRowHeight(int height) +{ + if (height < 0) + return; + + mHeight = -height; +} + +int StaticTableModel::getRowHeight() +{ + return abs(mHeight); +} + +int StaticTableModel::getColumnWidth(int column) +{ + if (column < 0 || column >= mColumns) + return 0; + + return abs(mWidths[column]); +} + +int StaticTableModel::getRows() +{ + return mRows; +} + +int StaticTableModel::getColumns() +{ + return mColumns; +} + +int StaticTableModel::getWidth(void) +{ + int width = 0; + + for (unsigned int i = 0; i < mWidths.size(); i++) + { + width += mWidths[i]; + } + + return width; +} + +int StaticTableModel::getHeight(void) +{ + return (mColumns * mHeight); +} + diff --git a/src/gui/table_model.h b/src/gui/table_model.h new file mode 100644 index 00000000..9ca36120 --- /dev/null +++ b/src/gui/table_model.h @@ -0,0 +1,144 @@ +/* + * 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 + */ + +#ifndef TABLE_MODEL_H +#define TABLE_MODEL_H + +#include <set> +#include <vector> + +class TableModelListener +{ +public: + /** + * Must be invoked by the TableModel whenever a global change is about to + * occur or has occurred (e.g., when a row or column is being removed or + * added). + * + * This method is triggered twice, once before and once after the update. + * + * \param completed whether we are signalling the end of the update + */ + virtual void modelUpdated(bool completed) = 0; +}; + +/** + * A model for a regular table of widgets. + */ +class TableModel +{ +public: + virtual ~TableModel() { } + + /** + * Determines the number of rows (lines) in the table + */ + virtual int getRows() = 0; + + /** + * Determines the number of columns in each row + */ + virtual int getColumns() = 0; + + /** + * Determines the height for each row + */ + virtual int getRowHeight() = 0; + + /** + * Determines the width of each individual column + */ + virtual int getColumnWidth(int index) = 0; + + /** + * Retrieves the widget stored at the specified location within the table. + */ + virtual gcn::Widget *getElementAt(int row, int column) = 0; + + virtual void installListener(TableModelListener *listener); + + virtual void removeListener(TableModelListener *listener); + +protected: + /** + * Tells all listeners that the table is about to see an update + */ + virtual void signalBeforeUpdate(); + + /** + * Tells all listeners that the table has seen an update + */ + virtual void signalAfterUpdate(); + +private: + std::set<TableModelListener *> listeners; +}; + + +class StaticTableModel : public TableModel +{ +public: + StaticTableModel(int width, int height); + virtual ~StaticTableModel(); + + /** + * Inserts a widget into the table model. + * The model is resized to accomodate the widget's width and height, + * unless column width / row height have been fixed. + */ + virtual void set(int row, int column, gcn::Widget *widget); + + /** + * Fixes the column width for a given column; this overrides dynamic width + * inference. + * + * Semantics are undefined for width 0. + */ + virtual void fixColumnWidth(int column, int width); + + /** + * Fixes the row height; this overrides dynamic height inference. + * + * Semantics are undefined for width 0. + */ + virtual void fixRowHeight(int height); + + /** + * Resizes the table model + */ + virtual void resize(); + + virtual int getRows(); + virtual int getColumns(); + virtual int getRowHeight(); + virtual int getWidth(); + virtual int getHeight(); + virtual int getColumnWidth(int index); + virtual gcn::Widget *getElementAt(int row, int column); + +protected: + int mRows, mColumns; + int mHeight; + std::vector<gcn::Widget *> mTableModel; + std::vector<int> mWidths; +}; + +#endif /* !defined(TABLE_MODEL_H) */ diff --git a/src/gui/textbox.cpp b/src/gui/textbox.cpp index 619265ec..2a86d549 100644 --- a/src/gui/textbox.cpp +++ b/src/gui/textbox.cpp @@ -1,39 +1,39 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "textbox.h" - #include <sstream> -#include <guichan/basiccontainer.hpp> #include <guichan/font.hpp> +#include "textbox.h" + TextBox::TextBox(): gcn::TextBox() { setOpaque(false); setFrameSize(0); + mMinWidth = getWidth(); } -void TextBox::setTextWrapped(const std::string &text) +void TextBox::setTextWrapped(const std::string &text, int minDimension) { // Make sure parent scroll area sets width of this widget if (getParent()) @@ -41,8 +41,13 @@ void TextBox::setTextWrapped(const std::string &text) getParent()->logic(); } + // Take the supplied minimum dimension as a starting point and try to beat it + mMinWidth = minDimension; + std::stringstream wrappedStream; std::string::size_type newlinePos, lastNewlinePos = 0; + int minWidth = 0; + int xpos; do { @@ -57,7 +62,18 @@ void TextBox::setTextWrapped(const std::string &text) std::string line = text.substr(lastNewlinePos, newlinePos - lastNewlinePos); std::string::size_type spacePos, lastSpacePos = 0; - int xpos = 0; + xpos = 0; + + spacePos = text.rfind(" ", text.size()); + + if (spacePos != std::string::npos) + { + const std::string word = text.substr(spacePos + 1); + const int length = getFont()->getWidth(word); + + if (length > mMinWidth) + mMinWidth = length; + } do { @@ -73,7 +89,7 @@ void TextBox::setTextWrapped(const std::string &text) int width = getFont()->getWidth(word); - if (xpos != 0 && xpos + width < getWidth()) + if (xpos != 0 && xpos + width + getFont()->getWidth(" ") <= mMinWidth) { xpos += width + getFont()->getWidth(" "); wrappedStream << " " << word; @@ -85,22 +101,46 @@ void TextBox::setTextWrapped(const std::string &text) } else { + if (xpos > minWidth) + minWidth = xpos; + + // The window wasn't big enough. Resize it and try again. + if (minWidth > mMinWidth) + { + mMinWidth = minWidth; + wrappedStream.clear(); + wrappedStream.str(""); + spacePos = 0; + lastNewlinePos = 0; + newlinePos = text.find("\n", lastNewlinePos); + if (newlinePos == std::string::npos) + newlinePos = text.size(); + line = text.substr(lastNewlinePos, newlinePos - + lastNewlinePos); + width = 0; + break; + } + else + { + wrappedStream << "\n" << word; + } xpos = width; - wrappedStream << "\n" << word; } - lastSpacePos = spacePos + 1; } while (spacePos != line.size()); if (text.find("\n", lastNewlinePos) != std::string::npos) - { wrappedStream << "\n"; - } lastNewlinePos = newlinePos + 1; } while (newlinePos != text.size()); + if (xpos > minWidth) + minWidth = xpos; + + mMinWidth = minWidth; + gcn::TextBox::setText(wrappedStream.str()); } diff --git a/src/gui/textbox.h b/src/gui/textbox.h index 2060e377..10a81fc0 100644 --- a/src/gui/textbox.h +++ b/src/gui/textbox.h @@ -1,26 +1,26 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef __TMW_TEXTBOX_H__ -#define __TMW_TEXTBOX_H__ +#ifndef TEXTBOX_H +#define TEXTBOX_H #include <guichan/widgets/textbox.hpp> @@ -31,7 +31,8 @@ * * \ingroup GUI */ -class TextBox : public gcn::TextBox { +class TextBox : public gcn::TextBox +{ public: /** * Constructor. @@ -41,7 +42,15 @@ class TextBox : public gcn::TextBox { /** * Sets the text after wrapping it to the current width of the widget. */ - void setTextWrapped(const std::string &text); + void setTextWrapped(const std::string &text, int minDimension); + + /** + * Get the minimum text width for the text box. + */ + int getMinWidth() { return mMinWidth; } + + private: + int mMinWidth; }; #endif diff --git a/src/gui/textfield.cpp b/src/gui/textfield.cpp index 49c0c91d..99a95a2e 100644 --- a/src/gui/textfield.cpp +++ b/src/gui/textfield.cpp @@ -1,32 +1,30 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include <algorithm> - #include <guichan/font.hpp> -#include "textfield.h" - #include "sdlinput.h" +#include "textfield.h" +#include "../configuration.h" #include "../graphics.h" #include "../resources/image.h" @@ -37,10 +35,13 @@ #undef DELETE //Win32 compatibility hack int TextField::instances = 0; +float TextField::mAlpha = config.getValue("guialpha", 0.8); ImageRect TextField::skin; TextField::TextField(const std::string& text): - gcn::TextField(text) + gcn::TextField(text), + mNumeric(false), + mListener(0) { setFrameSize(2); @@ -51,9 +52,6 @@ TextField::TextField(const std::string& text): Image *textbox = resman->getImage("graphics/gui/deepbox.png"); int gridx[4] = {0, 3, 28, 31}; int gridy[4] = {0, 3, 28, 31}; - //Image *textbox = resman->getImage("graphics/gui/textbox.png"); - //int gridx[4] = {0, 5, 26, 31}; - //int gridy[4] = {0, 5, 26, 31}; int a = 0, x, y; for (y = 0; y < 3; y++) { @@ -62,6 +60,7 @@ TextField::TextField(const std::string& text): gridx[x], gridy[y], gridx[x + 1] - gridx[x] + 1, gridy[y + 1] - gridy[y] + 1); + skin.grid[a]->setAlpha(config.getValue("guialpha", 0.8)); a++; } } @@ -93,6 +92,15 @@ void TextField::draw(gcn::Graphics *graphics) graphics->setColor(getForegroundColor()); graphics->setFont(getFont()); graphics->drawText(mText, 1 - mXScroll, 1); + + if (config.getValue("guialpha", 0.8) != mAlpha) + { + mAlpha = config.getValue("guialpha", 0.8); + for (int a = 0; a < 9; a++) + { + skin.grid[a]->setAlpha(mAlpha); + } + } } void TextField::drawFrame(gcn::Graphics *graphics) @@ -105,6 +113,42 @@ void TextField::drawFrame(gcn::Graphics *graphics) static_cast<Graphics*>(graphics)->drawImageRect(0, 0, w, h, skin); } +void TextField::setNumeric(bool numeric) +{ + mNumeric = numeric; + if (!numeric) + { + return; + } + const char *text = mText.c_str(); + for (const char *textPtr = text; *textPtr; ++textPtr) + { + if (*textPtr < '0' || *textPtr > '9') + { + setText(mText.substr(0, textPtr - text)); + return; + } + } +} + +int TextField::getValue() const +{ + if (!mNumeric) + { + return 0; + } + int value = atoi(mText.c_str()); + if (value < mMinimum) + { + return mMinimum; + } + if (value > mMaximum) + { + return mMaximum; + } + return value; +} + void TextField::keyPressed(gcn::KeyEvent &keyEvent) { int val = keyEvent.getKey().getValue(); diff --git a/src/gui/textfield.h b/src/gui/textfield.h index b808fad2..73824615 100644 --- a/src/gui/textfield.h +++ b/src/gui/textfield.h @@ -1,30 +1,37 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef __TMW_TEXTFIELD_H__ -#define __TMW_TEXTFIELD_H__ +#ifndef TEXTFIELD_H +#define TEXTFIELD_H #include <guichan/widgets/textfield.hpp> class ImageRect; +class TextField; + +class TextFieldListener +{ + public: + virtual void listen(const TextField *value) = 0; +}; /** * A text field. @@ -54,13 +61,48 @@ class TextField : public gcn::TextField { void drawFrame(gcn::Graphics *graphics); /** + * Determine whether the field should be numeric or not + */ + void setNumeric(bool numeric); + + /** + * Set the range on the field if it is numeric + */ + void setRange(int min, int max) {mMinimum = min; mMaximum = max; } + + /** * Processes one keypress. */ void keyPressed(gcn::KeyEvent &keyEvent); + /** + * Set the minimum value for a range + */ + void setMinimum(int min) {mMinimum = min; } + + /** + * Set the maximum value for a range + */ + void setMaximum(int max) {mMaximum = max; } + + /** + * Return the value for a numeric field + */ + int getValue() const; + + /** + * Add a listener + */ + void addListener(TextFieldListener *listener) {mListener = listener; } + private: static int instances; + static float mAlpha; static ImageRect skin; + bool mNumeric; + int mMinimum; + int mMaximum; + TextFieldListener *mListener; }; #endif diff --git a/src/gui/trade.cpp b/src/gui/trade.cpp index 0592c485..98214a79 100644 --- a/src/gui/trade.cpp +++ b/src/gui/trade.cpp @@ -1,21 +1,21 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ @@ -24,8 +24,6 @@ #include <guichan/font.hpp> #include <guichan/widgets/label.hpp> -#include "trade.h" - #include "button.h" #include "chat.h" #include "inventorywindow.h" @@ -33,42 +31,68 @@ #include "itemcontainer.h" #include "scrollarea.h" #include "textfield.h" +#include "trade.h" #include "widgets/layout.h" #include "../inventory.h" #include "../item.h" #include "../localplayer.h" +#include "../units.h" +#ifdef TMWSERV_SUPPORT #include "../net/gameserver/player.h" - -#include "../resources/iteminfo.h" +#else +#include "../net/messageout.h" +#include "../net/ea/protocol.h" +#endif #include "../utils/gettext.h" +#include "../utils/stringutils.h" #include "../utils/strprintf.h" +#ifdef TMWSERV_SUPPORT TradeWindow::TradeWindow(): - Window("Trade: You"), - mMyInventory(new Inventory), - mPartnerInventory(new Inventory), - mStatus(PREPARING) +#else +TradeWindow::TradeWindow(Network *network): +#endif + Window(_("Trade: You")), +#ifdef EATHENA_SUPPORT + mNetwork(network), +#endif + mMyInventory(new Inventory(INVENTORY_SIZE)), + mPartnerInventory(new Inventory(INVENTORY_SIZE)) +#ifdef TMWSERV_SUPPORT + , mStatus(PREPARING) +#endif { setWindowName("Trade"); setResizable(true); setDefaultSize(115, 197, 332, 209); Button *mAddButton = new Button(_("Add"), "add", this); +#ifdef EATHENA_SUPPORT + mOkButton = new Button(_("Ok"), "ok", this); +#endif Button *mCancelButton = new Button(_("Cancel"), "cancel", this); mTradeButton = new Button(_("Propose trade"), "trade", this); mTradeButton->setWidth(8 + std::max( mTradeButton->getFont()->getWidth(_("Propose trade")), mTradeButton->getFont()->getWidth(_("Confirm trade")))); - mMyItemContainer = new ItemContainer(mMyInventory, 4, 3); +#ifdef TMWSERV_SUPPORT + mMyItemContainer = new ItemContainer(mMyInventory.get(), 4, 3, 0); +#else + mMyItemContainer = new ItemContainer(mMyInventory.get(), 4, 3, 2); +#endif mMyItemContainer->addSelectionListener(this); ScrollArea *mMyScroll = new ScrollArea(mMyItemContainer); - mPartnerItemContainer = new ItemContainer(mPartnerInventory, 4, 3); +#ifdef TMWSERV_SUPPORT + mPartnerItemContainer = new ItemContainer(mPartnerInventory.get(), 4, 3, 0); +#else + mPartnerItemContainer = new ItemContainer(mPartnerInventory.get(), 4, 3, 2); +#endif mPartnerItemContainer->addSelectionListener(this); ScrollArea *mPartnerScroll = new ScrollArea(mPartnerItemContainer); @@ -78,10 +102,6 @@ TradeWindow::TradeWindow(): mMoneyField->setWidth(40); Button *mMoneyChange = new Button(_("Change"), "money", this); - mItemNameLabel = new gcn::Label(strprintf(_("Name: %s"), "")); - mItemDescriptionLabel = new gcn::Label( - strprintf(_("Description: %s"), "")); - place(1, 0, mMoneyLabel); place(0, 1, mMyScroll).setPadding(3); place(1, 1, mPartnerScroll).setPadding(3); @@ -91,11 +111,12 @@ TradeWindow::TradeWindow(): place(1, 0, mMoneyField); place(2, 0, mMoneyChange).setHAlign(LayoutCell::LEFT); place = getPlacer(0, 2); - place(0, 0, mItemNameLabel, 4); - place(0, 1, mItemDescriptionLabel, 4); - place(0, 2, mAddButton); - place(2, 2, mTradeButton); - place(3, 2, mCancelButton); + place(0, 0, mAddButton); +#ifdef EATHENA_SUPPORT + place(1, 0, mOkButton); +#endif + place(2, 0, mTradeButton); + place(3, 0, mCancelButton); Layout &layout = getLayout(); layout.extend(0, 2, 2, 1); layout.setRowHeight(1, Layout::AUTO_SET); @@ -108,69 +129,151 @@ TradeWindow::TradeWindow(): TradeWindow::~TradeWindow() { - delete mMyInventory; - delete mPartnerInventory; } void TradeWindow::setMoney(int amount) { - mMoneyLabel->setCaption(strprintf(_("You get %d GP."), amount)); + mMoneyLabel->setCaption(strprintf(_("You get %s."), + Units::formatCurrency(amount).c_str())); + mMoneyLabel->adjustSize(); +#ifdef TMWSERV_SUPPORT setStatus(PREPARING); +#endif } +#ifdef TMWSERV_SUPPORT void TradeWindow::addItem(int id, bool own, int quantity) { (own ? mMyInventory : mPartnerInventory)->addItem(id, quantity); setStatus(PREPARING); } +#endif + +#ifdef EATHENA_SUPPORT +void TradeWindow::addItem(int id, bool own, int quantity, bool equipment) +{ + if (own) + { + mMyInventory->addItem(id, quantity, equipment); + } + else + { + mPartnerInventory->addItem(id, quantity, equipment); + } +} + +void TradeWindow::changeQuantity(int index, bool own, int quantity) +{ + if (own) + mMyInventory->getItem(index)->setQuantity(quantity); + else + mPartnerInventory->getItem(index)->setQuantity(quantity); +} + +void TradeWindow::increaseQuantity(int index, bool own, int quantity) +{ + if (own) + mMyInventory->getItem(index)->increaseQuantity(quantity); + else + mPartnerInventory->getItem(index)->increaseQuantity(quantity); +} +#endif void TradeWindow::reset() { mMyInventory->clear(); mPartnerInventory->clear(); - mMoneyLabel->setCaption(strprintf(_("You get %d GP."), 0)); +#ifdef EATHENA_SUPPORT + mTradeButton->setEnabled(false); + mOkButton->setEnabled(true); + mOkOther = false; + mOkMe = false; +#endif + mMoneyLabel->setCaption(strprintf(_("You get %s."), "")); mMoneyField->setEnabled(true); mMoneyField->setText(""); +#ifdef TMWSERV_SUPPORT setStatus(PREPARING); +#endif } +#ifdef TMWSERV_SUPPORT + void TradeWindow::receivedOk() { setStatus(ACCEPTING); } +#else + +void TradeWindow::setTradeButton(bool enabled) +{ + mTradeButton->setEnabled(enabled); +} + +void TradeWindow::receivedOk(bool own) +{ + if (own) + { + mOkMe = true; + if (mOkOther) + { + mTradeButton->setEnabled(true); + mOkButton->setEnabled(false); + } + else + { + mTradeButton->setEnabled(false); + mOkButton->setEnabled(false); + } + } + else + { + mOkOther = true; + if (mOkMe) + { + mTradeButton->setEnabled(true); + mOkButton->setEnabled(false); + } + else + { + mTradeButton->setEnabled(false); + mOkButton->setEnabled(true); + } + } +} + +#endif + void TradeWindow::tradeItem(Item *item, int quantity) { +#ifdef TMWSERV_SUPPORT Net::GameServer::Player::tradeItem(item->getInvIndex(), quantity); addItem(item->getId(), true, quantity); item->increaseQuantity(-quantity); +#else + MessageOut outMsg(mNetwork); + outMsg.writeInt16(CMSG_TRADE_ITEM_ADD_REQUEST); + outMsg.writeInt16(item->getInvIndex()); + outMsg.writeInt32(quantity); +#endif } void TradeWindow::valueChanged(const gcn::SelectionEvent &event) { - Item *item; + const Item *item; /* If an item is selected in one container, make sure no item is selected * in the other container. */ if (event.getSource() == mMyItemContainer && - (item = mMyItemContainer->getItem())) - { + (item = mMyItemContainer->getSelectedItem())) mPartnerItemContainer->selectNone(); - } - else if ((item = mPartnerItemContainer->getItem())) - { + else if ((item = mPartnerItemContainer->getSelectedItem())) mMyItemContainer->selectNone(); - } - - // Update name and description - ItemInfo const *info = item ? &item->getInfo() : NULL; - mItemNameLabel->setCaption(strprintf(_("Name: %s"), - info ? info->getName().c_str() : "")); - mItemDescriptionLabel->setCaption(strprintf(_("Description: %s"), - info ? info->getDescription().c_str() : "")); } +#ifdef TMWSERV_SUPPORT void TradeWindow::setStatus(Status s) { if (s == mStatus) return; @@ -180,44 +283,86 @@ void TradeWindow::setStatus(Status s) (s == PREPARING ? _("Propose trade") : _("Confirm trade")); mTradeButton->setEnabled(s != PROPOSING); } +#endif void TradeWindow::action(const gcn::ActionEvent &event) { - Item *item = inventoryWindow->getItem(); + Item *item = inventoryWindow->getSelectedItem(); if (event.getId() == "add") { if (!item) return; + if (mMyInventory->getFreeSlot() < 1) + return; + if (mMyInventory->contains(item)) { chatWindow->chatLog("Failed adding item. You can not " "overlap one kind of item on the window.", BY_SERVER); return; } - if (item->getQuantity() == 1) { + if (item->getQuantity() == 1) + { tradeItem(item, 1); } - else { + else + { // Choose amount of items to trade new ItemAmountWindow(AMOUNT_TRADE_ADD, this, item); } +#ifdef TMWSERV_SUPPORT setStatus(PREPARING); +#endif } else if (event.getId() == "cancel") { setVisible(false); reset(); player_node->setTrading(false); +#ifdef TMWSERV_SUPPORT Net::GameServer::Player::acceptTrade(false); +#else + MessageOut outMsg(mNetwork); + outMsg.writeInt16(CMSG_TRADE_CANCEL_REQUEST); +#endif + } +#ifdef EATHENA_SUPPORT + else if (event.getId() == "ok") + { + std::stringstream tempMoney(mMoneyField->getText()); + int tempInt; + if (tempMoney >> tempInt) + { + mMoneyField->setText(toString(tempInt)); + + MessageOut outMsg(mNetwork); + outMsg.writeInt16(CMSG_TRADE_ITEM_ADD_REQUEST); + outMsg.writeInt16(0); + outMsg.writeInt32(tempInt); + } + else + { + mMoneyField->setText(""); + } + mMoneyField->setEnabled(false); + MessageOut outMsg(mNetwork); + outMsg.writeInt16(CMSG_TRADE_ADD_COMPLETE); } +#endif else if (event.getId() == "trade") { +#ifdef TMWSERV_SUPPORT Net::GameServer::Player::acceptTrade(true); setStatus(PROPOSING); +#else + MessageOut outMsg(mNetwork); + outMsg.writeInt16(CMSG_TRADE_OK); +#endif } +#ifdef TMWSERV_SUPPORT else if (event.getId() == "money") { int v = atoi(mMoneyField->getText().c_str()); @@ -225,4 +370,5 @@ void TradeWindow::action(const gcn::ActionEvent &event) mMoneyField->setText(strprintf("%d", v)); setStatus(PREPARING); } +#endif } diff --git a/src/gui/trade.h b/src/gui/trade.h index c51e0fdd..bde0481c 100644 --- a/src/gui/trade.h +++ b/src/gui/trade.h @@ -1,26 +1,28 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TMW_TRADE_H -#define _TMW_TRADE_H +#ifndef TRADE_H +#define TRADE_H + +#include <memory> #include <guichan/actionlistener.hpp> #include <guichan/selectionlistener.hpp> @@ -32,6 +34,9 @@ class Inventory; class Item; class ItemContainer; +#ifdef EATHENA_SUPPORT +class Network; +#endif class ScrollArea; /** @@ -45,7 +50,11 @@ class TradeWindow : public Window, gcn::ActionListener, gcn::SelectionListener /** * Constructor. */ +#ifdef TMWSERV_SUPPORT TradeWindow(); +#else + TradeWindow(Network *network); +#endif /** * Destructor. @@ -67,16 +76,41 @@ class TradeWindow : public Window, gcn::ActionListener, gcn::SelectionListener */ void reset(); +#ifdef EATHENA_SUPPORT + /** + * Add an item to the trade window. + */ + void addItem(int id, bool own, int quantity, bool equipment); + + /** + * Change quantity of an item. + */ + void changeQuantity(int index, bool own, int quantity); + + /** + * Increase quantity of an item. + */ + void increaseQuantity(int index, bool own, int quantity); + + /** + * Set trade Button disabled + */ + void setTradeButton(bool enabled); +#endif + /** * Player received ok message from server */ +#ifdef TMWSERV_SUPPORT void receivedOk(); +#else + void receivedOk(bool own); +#endif /** * Send trade packet. */ - void - tradeItem(Item *item, int quantity); + void tradeItem(Item *item, int quantity); /** * Updates the labels and makes sure only one item is selected in @@ -90,6 +124,7 @@ class TradeWindow : public Window, gcn::ActionListener, gcn::SelectionListener void action(const gcn::ActionEvent &event); private: +#ifdef TMWSERV_SUPPORT enum Status { PREPARING, /**< Players are adding items. */ @@ -101,20 +136,31 @@ class TradeWindow : public Window, gcn::ActionListener, gcn::SelectionListener * Sets the current status of the trade. */ void setStatus(Status); +#endif + +#ifdef EATHENA_SUPPORT + Network *mNetwork; +#endif - Inventory *mMyInventory; - Inventory *mPartnerInventory; + typedef const std::auto_ptr<Inventory> InventoryPtr; + InventoryPtr mMyInventory; + InventoryPtr mPartnerInventory; ItemContainer *mMyItemContainer; ItemContainer *mPartnerItemContainer; - gcn::Label *mItemNameLabel; - gcn::Label *mItemDescriptionLabel; gcn::Label *mMoneyLabel; gcn::Button *mTradeButton; +#ifdef EATHENA_SUPPORT + gcn::Button *mOkButton; +#endif gcn::TextField *mMoneyField; +#ifdef TMWSERV_SUPPORT Status mStatus; +#else + bool mOkOther, mOkMe; +#endif }; extern TradeWindow *tradeWindow; diff --git a/src/gui/truetypefont.cpp b/src/gui/truetypefont.cpp index 1132c3b5..7c72e2f5 100644 --- a/src/gui/truetypefont.cpp +++ b/src/gui/truetypefont.cpp @@ -1,30 +1,28 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "truetypefont.h" - -#include <list> - #include <guichan/exception.hpp> +#include "truetypefont.h" + #include "../graphics.h" #include "../resources/image.h" @@ -45,8 +43,7 @@ class TextChunk bool operator==(const TextChunk &chunk) const { - return ( - chunk.text == text && chunk.color == color); + return (chunk.text == text && chunk.color == color); } void generate(TTF_Font *font) @@ -75,14 +72,11 @@ class TextChunk gcn::Color color; }; - -// Word surfaces cache -static std::list<TextChunk> cache; typedef std::list<TextChunk>::iterator CacheIterator; static int fontCounter; -TrueTypeFont::TrueTypeFont(const std::string& filename, int size) +TrueTypeFont::TrueTypeFont(const std::string &filename, int size) { if (fontCounter == 0 && TTF_Init() == -1) { @@ -93,7 +87,7 @@ TrueTypeFont::TrueTypeFont(const std::string& filename, int size) ++fontCounter; mFont = TTF_OpenFont(filename.c_str(), size); - if (mFont == NULL) + if (!mFont) { throw GCN_EXCEPTION("SDLTrueTypeFont::SDLTrueTypeFont: " + std::string(TTF_GetError())); @@ -112,13 +106,11 @@ TrueTypeFont::~TrueTypeFont() } void TrueTypeFont::drawString(gcn::Graphics *graphics, - const std::string &text, - int x, int y) + const std::string &text, + int x, int y) { if (text.empty()) - { return; - } Graphics *g = dynamic_cast<Graphics *>(graphics); @@ -139,12 +131,12 @@ void TrueTypeFont::drawString(gcn::Graphics *graphics, bool found = false; - for (CacheIterator i = cache.begin(); i != cache.end(); i++) + for (CacheIterator i = mCache.begin(); i != mCache.end(); ++i) { if (chunk == (*i)) { // Raise priority: move it to front - cache.splice(cache.begin(), cache, i); + mCache.splice(mCache.begin(), mCache, i); found = true; break; } @@ -153,19 +145,19 @@ void TrueTypeFont::drawString(gcn::Graphics *graphics, // Surface not found if (!found) { - if (cache.size() >= CACHE_SIZE) + if (mCache.size() >= CACHE_SIZE) { - cache.pop_back(); + mCache.pop_back(); } - cache.push_front(chunk); - cache.front().generate(mFont); + mCache.push_front(chunk); + mCache.front().generate(mFont); } - cache.front().img->setAlpha(alpha); - g->drawImage(cache.front().img, x, y); + mCache.front().img->setAlpha(alpha); + g->drawImage(mCache.front().img, x, y); } -int TrueTypeFont::getWidth(const std::string& text) const +int TrueTypeFont::getWidth(const std::string &text) const { int w, h; TTF_SizeUTF8(mFont, text.c_str(), &w, &h); diff --git a/src/gui/truetypefont.h b/src/gui/truetypefont.h index 3b39329e..71b45fd1 100644 --- a/src/gui/truetypefont.h +++ b/src/gui/truetypefont.h @@ -1,37 +1,39 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TMW_TRUETYPEFONT_H -#define _TMW_TRUETYPEFONT_H +#ifndef TRUETYPEFONT_H +#define TRUETYPEFONT_H +#include <list> #include <string> #include <guichan/font.hpp> -#include <guichan/graphics.hpp> -#ifdef __APPLE__ -#include <SDL_ttf/SDL_ttf.h> -#else +#ifndef __APPLE__ #include <SDL/SDL_ttf.h> +#else +#include <SDL_ttf.h> #endif +class TextChunk; + /** * A wrapper around SDL_ttf for allowing the use of TrueType fonts. * @@ -46,7 +48,7 @@ class TrueTypeFont : public gcn::Font * @param filename Font filename. * @param size Font size. */ - TrueTypeFont(const std::string& filename, int size); + TrueTypeFont(const std::string &filename, int size); /** * Destructor. @@ -60,10 +62,15 @@ class TrueTypeFont : public gcn::Font /** * @see Font::drawString */ - void drawString(gcn::Graphics* graphics, const std::string& text, int x, int y); + void drawString(gcn::Graphics *graphics, + const std::string &text, + int x, int y); private: TTF_Font *mFont; + + // Word surfaces cache + std::list<TextChunk> mCache; }; #endif diff --git a/src/gui/unregisterdialog.h b/src/gui/unregisterdialog.h index 4056d251..1e3cc88f 100644 --- a/src/gui/unregisterdialog.h +++ b/src/gui/unregisterdialog.h @@ -1,26 +1,26 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TMW_UNREGISTERDIALOG_H -#define _TMW_UNREGISTERDIALOG_H +#ifndef UNREGISTERDIALOG_H +#define UNREGISTERDIALOG_H #include <iosfwd> #include <guichan/actionlistener.hpp> diff --git a/src/gui/updatewindow.cpp b/src/gui/updatewindow.cpp index 997a9b82..ca41dbda 100644 --- a/src/gui/updatewindow.cpp +++ b/src/gui/updatewindow.cpp @@ -1,26 +1,24 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "updatewindow.h" - #include <iostream> #include <SDL.h> #include <SDL_thread.h> @@ -28,22 +26,26 @@ #include <guichan/widgets/label.hpp> +// Curl should be included after Guichan to avoid Windows redefinitions +#include <curl/curl.h> + #include "browserbox.h" #include "button.h" #include "progressbar.h" #include "scrollarea.h" +#include "updatewindow.h" -// Curl should be included after Guichan to avoid Windows redefinitions -#include <curl/curl.h> +#include "widgets/layout.h" #include "../configuration.h" #include "../log.h" #include "../main.h" -#include "../utils/tostring.h" - #include "../resources/resourcemanager.h" +#include "../utils/gettext.h" +#include "../utils/stringutils.h" + /** * Calculates the Alder-32 checksum for the given file. */ @@ -67,8 +69,7 @@ static unsigned long fadler32(FILE *file) /** * Load the given file into a vector of strings. */ -std::vector<std::string> -loadTextFile(const std::string &fileName) +std::vector<std::string> loadTextFile(const std::string &fileName) { std::vector<std::string> lines; std::ifstream fin(fileName.c_str()); @@ -89,7 +90,7 @@ loadTextFile(const std::string &fileName) UpdaterWindow::UpdaterWindow(const std::string &updateHost, const std::string &updatesDir): - Window("Updating..."), + Window(_("Updating...")), mThread(NULL), mDownloadStatus(UPDATE_NEWS), mUpdateHost(updateHost), @@ -106,34 +107,29 @@ UpdaterWindow::UpdaterWindow(const std::string &updateHost, { mCurlError[0] = 0; - const int h = 240; - const int w = 320; - setContentSize(w, h); - - mBrowserBox = new BrowserBox(); + mBrowserBox = new BrowserBox; mScrollArea = new ScrollArea(mBrowserBox); - mLabel = new gcn::Label("Connecting..."); - mProgressBar = new ProgressBar(0.0, w - 10, 20, 37, 70, 200); - mCancelButton = new Button("Cancel", "cancel", this); - mPlayButton = new Button("Play", "play", this); + mLabel = new gcn::Label(_("Connecting...")); + mProgressBar = new ProgressBar(0.0, 310, 20, 168, 116, 31); + mCancelButton = new Button(_("Cancel"), "cancel", this); + mPlayButton = new Button(_("Play"), "play", this); mBrowserBox->setOpaque(false); mPlayButton->setEnabled(false); - mCancelButton->setPosition(5, h - 5 - mCancelButton->getHeight()); - mPlayButton->setPosition( - mCancelButton->getX() + mCancelButton->getWidth() + 5, - h - 5 - mPlayButton->getHeight()); - mProgressBar->setPosition(5, mCancelButton->getY() - 20 - 5); - mLabel->setPosition(5, mProgressBar->getY() - mLabel->getHeight() - 5); + ContainerPlacer place; + place = getPlacer(0, 0); + + place(0, 0, mScrollArea, 5, 3).setPadding(3); + place(0, 3, mLabel, 5); + place(0, 4, mProgressBar, 5); + place(3, 5, mCancelButton); + place(4, 5, mPlayButton); - mScrollArea->setDimension(gcn::Rectangle(5, 5, 310, mLabel->getY() - 12)); + reflowLayout(320, 240); - add(mScrollArea); - add(mLabel); - add(mProgressBar); - add(mCancelButton); - add(mPlayButton); + Layout &layout = getLayout(); + layout.setRowHeight(0, Layout::AUTO_SET); setLocationRelativeTo(getParent()); setVisible(true); @@ -209,7 +205,7 @@ void UpdaterWindow::loadNews() // Tokenize and add each line separately char *line = strtok(mMemoryBuffer, "\n"); - while (line != NULL) + while (line) { mBrowserBox->addRow(line); line = strtok(NULL, "\n"); @@ -228,8 +224,9 @@ int UpdaterWindow::updateProgress(void *ptr, float progress = dn / dt; UpdaterWindow *uw = reinterpret_cast<UpdaterWindow *>(ptr); - if (progress < 0) progress = 0.0f; - if (progress > 1) progress = 1.0f; + if (progress != progress) progress = 0.0f; // check for NaN + if (progress < 0.0f) progress = 0.0f; // no idea how this could ever happen, but why not check for it anyway. + if (progress > 1.0f) progress = 1.0f; uw->setLabel( uw->mCurrentFile + " (" + toString((int) (progress * 100)) + "%)"); @@ -244,8 +241,7 @@ int UpdaterWindow::updateProgress(void *ptr, return 0; } -size_t -UpdaterWindow::memoryWrite(void *ptr, size_t size, size_t nmemb, FILE *stream) +size_t UpdaterWindow::memoryWrite(void *ptr, size_t size, size_t nmemb, FILE *stream) { UpdaterWindow *uw = reinterpret_cast<UpdaterWindow *>(stream); size_t totalMem = size * nmemb; @@ -328,8 +324,8 @@ int UpdaterWindow::downloadThread(void *ptr) { case CURLE_COULDNT_CONNECT: default: - std::cerr << "curl error " << res << ": " - << uw->mCurlError << " host: " << url.c_str() + std::cerr << _("curl error ") << res << ": " + << uw->mCurlError << _(" host: ") << url.c_str() << std::endl; break; } @@ -412,7 +408,7 @@ void UpdaterWindow::download() mDownloadComplete = false; mThread = SDL_CreateThread(UpdaterWindow::downloadThread, this); - if (mThread == NULL) + if (!mThread) { logger->log("Unable to create mThread"); mDownloadStatus = UPDATE_ERROR; @@ -452,9 +448,9 @@ void UpdaterWindow::logic() mThread = NULL; } mBrowserBox->addRow(""); - mBrowserBox->addRow("##1 The update process is incomplete."); - mBrowserBox->addRow("##1 It is strongly recommended that"); - mBrowserBox->addRow("##1 you try again later"); + mBrowserBox->addRow(_("##1 The update process is incomplete.")); + mBrowserBox->addRow(_("##1 It is strongly recommended that")); + mBrowserBox->addRow(_("##1 you try again later")); mBrowserBox->addRow(mCurlError); mScrollArea->setVerticalScrollAmount( mScrollArea->getVerticalMaxScroll()); @@ -521,7 +517,7 @@ void UpdaterWindow::logic() break; case UPDATE_COMPLETE: enable(); - setLabel("Completed"); + setLabel(_("Completed")); break; case UPDATE_IDLE: break; diff --git a/src/gui/updatewindow.h b/src/gui/updatewindow.h index a7dfe2cb..ace398b4 100644 --- a/src/gui/updatewindow.h +++ b/src/gui/updatewindow.h @@ -1,21 +1,21 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ @@ -23,12 +23,13 @@ #define _UPDATERWINDOW_H #include <guichan/actionlistener.hpp> + #include <string> #include <vector> #include "window.h" -#include "../guichanfwd.h" +#include "../utils/mutex.h" #include "../utils/mutex.h" diff --git a/src/gui/vbox.cpp b/src/gui/vbox.cpp deleted file mode 100644 index 2ec1112d..00000000 --- a/src/gui/vbox.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/* - * The Mana World - * Copyright 2004 The Mana World Development Team - * - * This file is part of The Mana World. - * - * The Mana World 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. - * - * The Mana World 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 The Mana World; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "vbox.h" - -void VBox::draw(gcn::Graphics *graphics) -{ - if (mWidgets.empty()) - { - return; - } - - int childWidth = getWidth(); - int childHeight = getHeight() / mWidgets.size(); - int i = 0; - - for (WidgetIterator w = mWidgets.begin(); w != mWidgets.end(); w++) - { - (*w)->setPosition(0, childHeight * i - padding); - (*w)->setSize(childWidth, childHeight); - i++; - } - - gcn::Container::draw(graphics); -} diff --git a/src/gui/vbox.h b/src/gui/vbox.h deleted file mode 100644 index 2072ab24..00000000 --- a/src/gui/vbox.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * The Mana World - * Copyright 2004 The Mana World Development Team - * - * This file is part of The Mana World. - * - * The Mana World 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. - * - * The Mana World 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 The Mana World; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef VBOX_H -#define VBOX_H - -#include "box.h" - -class VBox : public Box -{ - public: - void draw(gcn::Graphics *); -}; - -#endif diff --git a/src/gui/viewport.cpp b/src/gui/viewport.cpp index a746fb03..cbd1f3f7 100644 --- a/src/gui/viewport.cpp +++ b/src/gui/viewport.cpp @@ -1,62 +1,61 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "viewport.h" - -#include <guichan/sdl/sdlinput.hpp> - -#include "gui.h" +#include "ministatus.h" #include "popupmenu.h" +#include "viewport.h" -#include "../simpleanimation.h" #include "../beingmanager.h" #include "../configuration.h" #include "../flooritemmanager.h" +#include "../game.h" #include "../graphics.h" +#include "../keyboardconfig.h" #include "../localplayer.h" #include "../map.h" #include "../monster.h" #include "../npc.h" +#include "../textmanager.h" -#include "../resources/animation.h" #include "../resources/monsterinfo.h" #include "../resources/resourcemanager.h" -#include "../resources/image.h" -#include "../resources/imageset.h" - -#include "../utils/tostring.h" -#include <cassert> +#include "../utils/stringutils.h" extern volatile int tick_time; -extern int get_elapsed_time(int start_time); Viewport::Viewport(): mMap(0), - mViewX(0.0f), - mViewY(0.0f), + mPixelViewX(0.0f), + mPixelViewY(0.0f), + mTileViewX(0), + mTileViewY(0), mShowDebugPath(false), mVisibleNames(false), mPlayerFollowMouse(false), +#ifdef TMWSERV_SUPPORT mLocalWalkTime(-1) +#else + mWalkTime(0) +#endif { setOpaque(false); addMouseListener(this); @@ -71,52 +70,7 @@ Viewport::Viewport(): config.addListener("ScrollRadius", this); config.addListener("visiblenames", this); - mPopupMenu = new PopupMenu(); - - // Load target cursors - loadTargetCursor("graphics/gui/target-cursor-blue-s.png", 44, 35, - false, Being::TC_SMALL); - loadTargetCursor("graphics/gui/target-cursor-red-s.png", 44, 35, - true, Being::TC_SMALL); - loadTargetCursor("graphics/gui/target-cursor-blue-m.png", 62, 44, - false, Being::TC_MEDIUM); - loadTargetCursor("graphics/gui/target-cursor-red-m.png", 62, 44, - true, Being::TC_MEDIUM); - loadTargetCursor("graphics/gui/target-cursor-blue-l.png", 82, 60, - false, Being::TC_LARGE); - loadTargetCursor("graphics/gui/target-cursor-red-l.png", 82, 60, - true, Being::TC_LARGE); -} - -void Viewport::loadTargetCursor(const std::string &filename, - int width, int height, - bool outRange, Being::TargetCursorSize size) -{ - assert(size >= Being::TC_SMALL); - assert(size < Being::NUM_TC); - - ImageSet* currentImageSet; - SimpleAnimation* currentCursor; - - ResourceManager *resman = ResourceManager::getInstance(); - - currentImageSet = resman->getImageSet(filename, width, height); - Animation *anim = new Animation(); - for (unsigned int i = 0; i < currentImageSet->size(); ++i) - { - anim->addFrame(currentImageSet->get(i), 75, 0, 0); - } - currentCursor = new SimpleAnimation(anim); - - if (outRange) - { - mOutRangeImages[size] = currentImageSet; - mTargetCursorOutRange[size] = currentCursor; - } - else { - mInRangeImages[size] = currentImageSet; - mTargetCursorInRange[size] = currentCursor; - } + mPopupMenu = new PopupMenu; } Viewport::~Viewport() @@ -124,14 +78,6 @@ Viewport::~Viewport() delete mPopupMenu; config.removeListener("visiblenames", this); - - for (int i = Being::TC_SMALL; i < Being::NUM_TC; i++) - { - delete mTargetCursorInRange[i]; - delete mTargetCursorOutRange[i]; - mInRangeImages[i]->decRef(); - mOutRangeImages[i]->decRef(); - } } void Viewport::setMap(Map *map) @@ -139,6 +85,8 @@ void Viewport::setMap(Map *map) mMap = map; } +extern MiniStatusWindow *miniStatusWindow; + void Viewport::draw(gcn::Graphics *gcnGraphics) { static int lastTick = tick_time; @@ -148,6 +96,10 @@ void Viewport::draw(gcn::Graphics *gcnGraphics) Graphics *graphics = static_cast<Graphics*>(gcnGraphics); + // Ensure the client doesn't freak out if a feature localplayer uses + // is dependent on a map. + player_node->mMapInitialized = true; + // Avoid freaking out when tick_time overflows if (tick_time < lastTick) { @@ -155,12 +107,22 @@ void Viewport::draw(gcn::Graphics *gcnGraphics) } // Calculate viewpoint +#ifdef TMWSERV_SUPPORT int midTileX = (graphics->getWidth() + mScrollCenterOffsetX) / 2; int midTileY = (graphics->getHeight() + mScrollCenterOffsetX) / 2; const Vector &playerPos = player_node->getPosition(); const int player_x = (int) playerPos.x - midTileX; const int player_y = (int) playerPos.y - midTileY; +#else + int midTileX = (graphics->getWidth() + mScrollCenterOffsetX) / 32 / 2; + int midTileY = (graphics->getHeight() + mScrollCenterOffsetY) / 32 / 2; + + int player_x = (player_node->mX - midTileX) * 32 + + player_node->getXOffset(); + int player_y = (player_node->mY - midTileY) * 32 + + player_node->getYOffset(); +#endif if (mScrollLaziness < 1) mScrollLaziness = 1; // Avoids division by zero @@ -168,34 +130,34 @@ void Viewport::draw(gcn::Graphics *gcnGraphics) // Apply lazy scrolling while (lastTick < tick_time) { - if (player_x > mViewX + mScrollRadius) + if (player_x > mPixelViewX + mScrollRadius) { - mViewX += (player_x - mViewX - mScrollRadius) / mScrollLaziness; + mPixelViewX += (player_x - mPixelViewX - mScrollRadius) / mScrollLaziness; } - if (player_x < mViewX - mScrollRadius) + if (player_x < mPixelViewX - mScrollRadius) { - mViewX += (player_x - mViewX + mScrollRadius) / mScrollLaziness; + mPixelViewX += (player_x - mPixelViewX + mScrollRadius) / mScrollLaziness; } - if (player_y > mViewY + mScrollRadius) + if (player_y > mPixelViewY + mScrollRadius) { - mViewY += (player_y - mViewY - mScrollRadius) / mScrollLaziness; + mPixelViewY += (player_y - mPixelViewY - mScrollRadius) / mScrollLaziness; } - if (player_y < mViewY - mScrollRadius) + if (player_y < mPixelViewY - mScrollRadius) { - mViewY += (player_y - mViewY + mScrollRadius) / mScrollLaziness; + mPixelViewY += (player_y - mPixelViewY + mScrollRadius) / mScrollLaziness; } lastTick++; } // Auto center when player is off screen - if ( player_x - mViewX > graphics->getWidth() / 2 - || mViewX - player_x > graphics->getWidth() / 2 - || mViewY - player_y > graphics->getHeight() / 2 - || player_y - mViewY > graphics->getHeight() / 2 + if ( player_x - mPixelViewX > graphics->getWidth() / 2 + || mPixelViewX - player_x > graphics->getWidth() / 2 + || mPixelViewY - player_y > graphics->getHeight() / 2 + || player_y - mPixelViewY > graphics->getHeight() / 2 ) { - mViewX = player_x; - mViewY = player_y; + mPixelViewX = player_x; + mPixelViewY = player_y; }; // Don't move camera so that the end of the map is on screen @@ -205,49 +167,62 @@ void Viewport::draw(gcn::Graphics *gcnGraphics) mMap->getHeight() * mMap->getTileHeight() - graphics->getHeight(); if (mMap) { - if (mViewX < 0) { - mViewX = 0; + if (mPixelViewX < 0) { + mPixelViewX = 0; } - if (mViewY < 0) { - mViewY = 0; + if (mPixelViewY < 0) { + mPixelViewY = 0; } - if (mViewX > viewXmax) { - mViewX = viewXmax; + if (mPixelViewX > viewXmax) { + mPixelViewX = viewXmax; } - if (mViewY > viewYmax) { - mViewY = viewYmax; + if (mPixelViewY > viewYmax) { + mPixelViewY = viewYmax; } } + mTileViewX = (int) (mPixelViewX + 16) / 32; + mTileViewY = (int) (mPixelViewY + 16) / 32; + // Draw tiles and sprites if (mMap) { - mMap->draw(graphics, (int) mViewX, (int) mViewY); - drawTargetCursor(graphics); // TODO: Draw the cursor with the sprite - drawTargetName(graphics); + mMap->draw(graphics, (int) mPixelViewX, (int) mPixelViewY); + if (mShowDebugPath) { - mMap->drawCollision(graphics, (int) mViewX, (int) mViewY); + mMap->drawCollision(graphics, + (int) mPixelViewX, + (int) mPixelViewY); #if 0 drawDebugPath(graphics); #endif } } + if (player_node->mUpdateName) + { + player_node->mUpdateName = false; + player_node->setName(player_node->getName()); + } + + + // Draw text + if (textManager) + { + textManager->draw(graphics, (int) mPixelViewX, (int) mPixelViewY); + } + // Draw player names, speech, and emotion sprite as needed Beings &beings = beingManager->getAll(); for (BeingIterator i = beings.begin(); i != beings.end(); i++) { - (*i)->drawSpeech(graphics, -(int) mViewX, -(int) mViewY); - if (mVisibleNames) - (*i)->drawName(graphics, -(int) mViewX, -(int) mViewY); - else if ((*i) == mSelectedBeing) - (*i)->drawName(graphics, -(int) mViewX, -(int) mViewY); - (*i)->drawEmotion(graphics, -(int) mViewX, -(int) mViewY); - - if (mShowDebugPath && !(*i)->getPath().empty()) - drawPath(graphics, (*i)->getPath()); + (*i)->drawSpeech(-(int) mPixelViewX, -(int) mPixelViewY); + (*i)->drawEmotion(graphics, -(int) mPixelViewX, -(int) mPixelViewY); } + if (miniStatusWindow) + miniStatusWindow->drawIcons(graphics); + // Draw contained widgets WindowContainer::draw(gcnGraphics); } @@ -263,67 +238,19 @@ void Viewport::logic() Uint8 button = SDL_GetMouseState(&mouseX, &mouseY); if (mPlayerFollowMouse && button & SDL_BUTTON(1) && +#ifdef TMWSERV_SUPPORT get_elapsed_time(mLocalWalkTime) >= walkingMouseDelay) { mLocalWalkTime = tick_time; - player_node->setDestination(mouseX + (int) mViewX, - mouseY + (int) mViewY); - } - - for (int i = Being::TC_SMALL; i < Being::NUM_TC; i++) + player_node->setDestination(mouseX + (int) mPixelViewX, + mouseY + (int) mPixelViewY); +#else + mWalkTime != player_node->mWalkTime) { - mTargetCursorInRange[i]->update(10); - mTargetCursorOutRange[i]->update(10); - } -} - -void Viewport::drawTargetCursor(Graphics *graphics) -{ - // Draw target marker if needed - Being *target = player_node->getTarget(); - if (target) - { - // Calculate target circle position - - // Find whether target is in range - const Vector &dist = - target->getPosition() - player_node->getPosition(); - const int rangeX = abs((int) dist.x); - const int rangeY = abs((int) dist.y); - const int attackRange = player_node->getAttackRange(); - - // Get the correct target cursors graphic - Being::TargetCursorSize cursorSize = target->getTargetCursorSize(); - Image* targetCursor; - if (rangeX > attackRange || rangeY > attackRange) - targetCursor = mTargetCursorOutRange[cursorSize]->getCurrentImage(); - else - targetCursor = mTargetCursorInRange[cursorSize]->getCurrentImage(); - - // Draw the target cursor at the correct position - int posX = target->getPixelX() - - targetCursor->getWidth() / 2 - (int) mViewX; - int posY = target->getPixelY() - 16 - - targetCursor->getHeight() / 2 - (int) mViewY; - - graphics->drawImage(targetCursor, posX, posY); - } -} - -void Viewport::drawTargetName(Graphics *graphics) -{ - // Draw target marker if needed - Being *target = player_node->getTarget(); - if (target && target->getType() == Being::MONSTER) - { - graphics->setFont(speechFont); - graphics->setColor(gcn::Color(255, 32, 32)); - - const MonsterInfo &mi = static_cast<Monster*>(target)->getInfo(); - int posX = target->getPixelX() - (int) mViewX; - int posY = target->getPixelY() + 16 - target->getHeight() - (int) mViewY; - - graphics->drawText(mi.getName(), posX, posY, gcn::Graphics::CENTER); + player_node->setDestination(mouseX / 32 + mTileViewX, + mouseY / 32 + mTileViewY); + mWalkTime = player_node->mWalkTime; +#endif } } @@ -333,8 +260,8 @@ void Viewport::drawDebugPath(Graphics *graphics) int mouseX, mouseY; SDL_GetMouseState(&mouseX, &mouseY); - const int mouseTileX = (mouseX + (int) mViewX) / 32; - const int mouseTileY = (mouseY + (int) mViewY) / 32; + const int mouseTileX = (mouseX + (int) mPixelViewX) / 32; + const int mouseTileY = (mouseY + (int) mPixelViewY) / 32; const Vector &playerPos = player_node->getPosition(); Path debugPath = mMap->findPath( @@ -350,8 +277,8 @@ void Viewport::drawPath(Graphics *graphics, const Path &path) graphics->setColor(gcn::Color(255, 0, 0)); for (Path::const_iterator i = path.begin(); i != path.end(); ++i) { - int squareX = i->x * 32 - (int) mViewX + 12; - int squareY = i->y * 32 - (int) mViewY + 12; + int squareX = i->x * 32 - (int) mPixelViewX + 12; + int squareY = i->y * 32 - (int) mPixelViewY + 12; graphics->fillRectangle(gcn::Rectangle(squareX, squareY, 8, 8)); graphics->drawText( @@ -366,10 +293,14 @@ void Viewport::mousePressed(gcn::MouseEvent &event) if (!mMap || !player_node || player_node->mAction == Being::DEAD) return; + // Check if we are busy + if (current_npc) + return; + mPlayerFollowMouse = false; - const int pixelx = event.getX() + (int) mViewX; - const int pixely = event.getY() + (int) mViewY; + const int pixelx = event.getX() + (int) mPixelViewX; + const int pixely = event.getY() + (int) mPixelViewY; const int tilex = pixelx / mMap->getTileWidth(); const int tiley = pixely / mMap->getTileHeight(); @@ -380,12 +311,13 @@ void Viewport::mousePressed(gcn::MouseEvent &event) FloorItem *floorItem; if ((being = beingManager->findBeingByPixel(pixelx, pixely)) && - being != player_node) + being != player_node) { - mPopupMenu->showPopup(event.getX(), event.getY(), being); - return; + mPopupMenu->showPopup(event.getX(), event.getY(), being); + return; } - else if((floorItem = floorItemManager->findByCoordinates(tilex, tiley))) + else if ((floorItem = floorItemManager->findByCoordinates(tilex, + tiley))) { mPopupMenu->showPopup(event.getX(), event.getY(), floorItem); return; @@ -403,24 +335,63 @@ void Viewport::mousePressed(gcn::MouseEvent &event) if (event.getButton() == gcn::MouseEvent::LEFT) { FloorItem *item; +#ifdef EATHENA_SUPPORT + Being *being; + // Interact with some being +// if ((being = beingManager->findBeing(tilex, tiley))) + if ((being = beingManager->findBeingByPixel(pixelx, pixely))) + { + switch (being->getType()) + { + case Being::NPC: + dynamic_cast<NPC*>(being)->talk(); + break; + + case Being::MONSTER: + case Being::PLAYER: + if (being->mAction == Being::DEAD) + break; + + if (player_node->withinAttackRange(being) || keyboard.isKeyActive(keyboard.KEY_ATTACK)) + { + player_node->setGotoTarget(being); + player_node->attack(being, !keyboard.isKeyActive(keyboard.KEY_TARGET)); + } + else + { + player_node->setDestination(tilex, tiley); + } + break; + + default: + break; + } + } // Pick up some item + else +#endif if ((item = floorItemManager->findByCoordinates(tilex, tiley))) { - player_node->pickUp(item); + player_node->pickUp(item); } // Just walk around else { +#ifdef TMWSERV_SUPPORT // FIXME: REALLY UGLY! Uint8 *keys = SDL_GetKeyState(NULL); if (!(keys[SDLK_LSHIFT] || keys[SDLK_RSHIFT]) && get_elapsed_time(mLocalWalkTime) >= walkingMouseDelay) { mLocalWalkTime = tick_time; - player_node->setDestination(event.getX() + (int) mViewX, - event.getY() + (int) mViewY); + player_node->setDestination(event.getX() + (int) mPixelViewX, + event.getY() + (int) mPixelViewY); } +#else + player_node->stopAttack(); + player_node->setDestination(tilex, tiley); +#endif mPlayerFollowMouse = true; } } @@ -443,13 +414,22 @@ void Viewport::mouseDragged(gcn::MouseEvent &event) if (!mMap || !player_node) return; +#ifdef TMWSERV_SUPPORT if (mPlayerFollowMouse && get_elapsed_time(mLocalWalkTime) >= walkingMouseDelay) { mLocalWalkTime = tick_time; - player_node->setDestination(event.getX() + (int) mViewX, - event.getY() + (int) mViewY); + player_node->setDestination(event.getX() + (int) mPixelViewX, + event.getY() + (int) mPixelViewY); } +#else + if (mPlayerFollowMouse && mWalkTime == player_node->mWalkTime) + { + int destX = event.getX() / 32 + mTileViewX; + int destY = event.getY() / 32 + mTileViewY; + player_node->setDestination(destX, destY); + } +#endif } void Viewport::mouseReleased(gcn::MouseEvent &event) @@ -478,9 +458,8 @@ void Viewport::mouseMoved(gcn::MouseEvent &event) if (!mMap || !player_node) return; - const int tilex = (event.getX() + (int) mViewX) / 32; - const int tiley = (event.getY() + (int) mViewY) / 32; + const int tilex = (event.getX() + (int) mPixelViewX) / 32; + const int tiley = (event.getY() + (int) mPixelViewY) / 32; mSelectedBeing = beingManager->findBeing(tilex, tiley); } - diff --git a/src/gui/viewport.h b/src/gui/viewport.h index dd17fa24..a097a4ac 100644 --- a/src/gui/viewport.h +++ b/src/gui/viewport.h @@ -1,41 +1,41 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TMW_VIEWPORT_H_ -#define _TMW_VIEWPORT_H_ +#ifndef VIEWPORT_H +#define VIEWPORT_H #include <guichan/mouselistener.hpp> #include "windowcontainer.h" #include "../configlistener.h" -#include "../being.h" +#include "../position.h" -class Map; +class Being; class FloorItem; +class Graphics; class ImageSet; class Item; +class Map; class PopupMenu; -class Graphics; -class SimpleAnimation; /** Delay between two mouse calls when dragging mouse and move the player */ const int walkingMouseDelay = 500; @@ -65,101 +65,71 @@ class Viewport : public WindowContainer, public gcn::MouseListener, /** * Sets the map displayed by the viewport. */ - void - setMap(Map *map); + void setMap(Map *map); /** * Draws the viewport. */ - void - draw(gcn::Graphics *graphics); + void draw(gcn::Graphics *graphics); /** * Implements player to keep following mouse. */ - void - logic(); + void logic(); /** * Toggles whether the path debug graphics are shown */ - void - toggleDebugPath() { mShowDebugPath = !mShowDebugPath; } + void toggleDebugPath() { mShowDebugPath = !mShowDebugPath; } /** * Handles mouse press on map. */ - void - mousePressed(gcn::MouseEvent &event); + void mousePressed(gcn::MouseEvent &event); /** * Handles mouse move on map */ - void - mouseDragged(gcn::MouseEvent &event); + void mouseDragged(gcn::MouseEvent &event); /** * Handles mouse button release on map. */ - void - mouseReleased(gcn::MouseEvent &event); + void mouseReleased(gcn::MouseEvent &event); /** * Handles mouse move on map. */ - void - mouseMoved(gcn::MouseEvent &event); + void mouseMoved(gcn::MouseEvent &event); /** * Shows a popup for an item. * TODO Find some way to get rid of Item here */ - void - showPopup(int x, int y, Item *item); + void showPopup(int x, int y, Item *item); /** * A relevant config option changed. */ - void - optionChanged(const std::string &name); + void optionChanged(const std::string &name); /** * Returns camera x offset in pixels. */ - int - getCameraX() const { return (int) mViewX; } + int getCameraX() const { return (int) mPixelViewX; } /** * Returns camera y offset in pixels. */ - int - getCameraY() const { return (int) mViewY; } + int getCameraY() const { return (int) mPixelViewY; } /** * Changes viewpoint by relative pixel coordinates. */ - void - scrollBy(float x, float y) { mViewX += x; mViewY += y; } + void scrollBy(float x, float y) { mPixelViewX += x; mPixelViewY += y; } private: /** - * Helper function for loading target cursors. - */ - void loadTargetCursor(const std::string &filename, - int width, int height, - bool outRange, Being::TargetCursorSize size); - - /** - * Draws range based target cursor - */ - void drawTargetCursor(Graphics *graphics); - - /** - * Draws target name - */ - void drawTargetName(Graphics *graphics); - - /** * Finds a path from the player to the mouse, and draws it. This is for * debug purposes. */ @@ -170,35 +140,31 @@ class Viewport : public WindowContainer, public gcn::MouseListener, */ void drawPath(Graphics *graphics, const Path &path); - Map *mMap; /**< The current map. */ int mScrollRadius; int mScrollLaziness; int mScrollCenterOffsetX; int mScrollCenterOffsetY; - float mViewX; /**< Current viewpoint in pixels. */ - float mViewY; /**< Current viewpoint in pixels. */ + float mPixelViewX; /**< Current viewpoint in pixels. */ + float mPixelViewY; /**< Current viewpoint in pixels. */ + int mTileViewX; /**< Current viewpoint in tiles. */ + int mTileViewY; /**< Current viewpoint in tiles. */ bool mShowDebugPath; /**< Show a path from player to pointer. */ bool mVisibleNames; /**< Show target names. */ - /** Images of in range target cursor. */ - ImageSet *mInRangeImages[Being::NUM_TC]; - - /** Images of out of range target cursor. */ - ImageSet *mOutRangeImages[Being::NUM_TC]; - - /** Animated in range target cursor. */ - SimpleAnimation *mTargetCursorInRange[Being::NUM_TC]; - - /** Animated out of range target cursor. */ - SimpleAnimation *mTargetCursorOutRange[Being::NUM_TC]; - bool mPlayerFollowMouse; +#ifdef TMWSERV_SUPPORT int mLocalWalkTime; /**< Timestamp before the next walk can be sent. */ +#else + int mWalkTime; +#endif PopupMenu *mPopupMenu; /**< Popup menu. */ Being *mSelectedBeing; /**< Current selected being. */ + }; +extern Viewport *viewport; /**< The viewport */ + #endif diff --git a/src/gui/widgets/dropdown.cpp b/src/gui/widgets/dropdown.cpp index d4c2bc4b..92837603 100644 --- a/src/gui/widgets/dropdown.cpp +++ b/src/gui/widgets/dropdown.cpp @@ -1,21 +1,21 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2006 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ @@ -23,6 +23,11 @@ #include "dropdown.h" +#include "../color.h" +#include "../listbox.h" +#include "../scrollarea.h" + +#include "../../configuration.h" #include "../../graphics.h" #include "../../resources/image.h" @@ -33,12 +38,12 @@ int DropDown::instances = 0; Image *DropDown::buttons[2][2]; ImageRect DropDown::skin; +float DropDown::mAlpha = config.getValue("guialpha", 0.8); -DropDown::DropDown(gcn::ListModel *listModel, - gcn::ScrollArea *scrollArea, - gcn::ListBox *listBox): - gcn::DropDown::DropDown(listModel, - scrollArea, listBox) +DropDown::DropDown(gcn::ListModel *listModel, gcn::ScrollArea *scrollArea, + gcn::ListBox *listBox, bool opacity): + gcn::DropDown::DropDown(listModel, scrollArea, listBox), + mOpaque(opacity) { setFrameSize(2); @@ -58,6 +63,11 @@ DropDown::DropDown(gcn::ListModel *listModel, buttons[0][1] = resman->getImage("graphics/gui/vscroll_down_pressed.png"); + buttons[0][0]->setAlpha(mAlpha); + buttons[0][1]->setAlpha(mAlpha); + buttons[1][0]->setAlpha(mAlpha); + buttons[1][1]->setAlpha(mAlpha); + // get the border skin Image *boxBorder = resman->getImage("graphics/gui/deepbox.png"); int gridx[4] = {0, 3, 28, 31}; @@ -70,6 +80,7 @@ DropDown::DropDown(gcn::ListModel *listModel, gridx[x], gridy[y], gridx[x + 1] - gridx[x] + 1, gridy[y + 1] - gridy[y] + 1); + skin.grid[a]->setAlpha(mAlpha); a++; } } @@ -108,19 +119,44 @@ void DropDown::draw(gcn::Graphics* graphics) h = getHeight(); } - int alpha = getBaseColor().a; + if (config.getValue("guialpha", 0.8) != mAlpha) + { + mAlpha = config.getValue("guialpha", 0.8); + + buttons[0][0]->setAlpha(mAlpha); + buttons[0][1]->setAlpha(mAlpha); + buttons[1][0]->setAlpha(mAlpha); + buttons[1][1]->setAlpha(mAlpha); + + for (int a = 0; a < 9; a++) + { + skin.grid[a]->setAlpha(mAlpha); + } + } + + bool valid; + const int alpha = (int)(mAlpha * 255.0f); gcn::Color faceColor = getBaseColor(); faceColor.a = alpha; - gcn::Color highlightColor = faceColor + 0x303030; + gcn::Color highlightColor = textColor->getColor('H', valid); highlightColor.a = alpha; gcn::Color shadowColor = faceColor - 0x303030; shadowColor.a = alpha; + if (mOpaque) + { + int red = getBackgroundColor().r; + int green = getBackgroundColor().g; + int blue = getBackgroundColor().b; + graphics->setColor(gcn::Color(red, green, blue, alpha)); + graphics->fillRectangle(gcn::Rectangle(0, 0, getWidth(), h)); + + red = getForegroundColor().r; + green = getForegroundColor().g; + blue = getForegroundColor().b; + graphics->setColor(gcn::Color(red, green, blue, alpha)); + } - graphics->setColor(getBackgroundColor()); - graphics->fillRectangle(gcn::Rectangle(0, 0, getWidth(), h)); - - graphics->setColor(getForegroundColor()); graphics->setFont(getFont()); if (mListBox->getListModel() && mListBox->getSelected() >= 0) @@ -140,7 +176,7 @@ void DropDown::draw(gcn::Graphics* graphics) { drawChildren(graphics); - // Draw two lines separating the ListBox with se selected + // Draw two lines separating the ListBox with selected // element view. graphics->setColor(highlightColor); graphics->drawLine(0, h, getWidth(), h); @@ -163,5 +199,5 @@ void DropDown::drawButton(gcn::Graphics *graphics) int height = mDroppedDown ? mFoldedUpHeight : getHeight(); static_cast<Graphics*>(graphics)-> - drawImage(buttons[mDroppedDown][mPushed], getWidth() - height, 1); + drawImage(buttons[mDroppedDown][mPushed], getWidth() - height + 2, 1); } diff --git a/src/gui/widgets/dropdown.h b/src/gui/widgets/dropdown.h index 58a18a15..1e6dc821 100644 --- a/src/gui/widgets/dropdown.h +++ b/src/gui/widgets/dropdown.h @@ -1,32 +1,28 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2006 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef DROPDOWN_H #define DROPDOWN_H -#include <iosfwd> - #include <guichan/widgets/dropdown.hpp> -#include "../scrollarea.h" -#include "../listbox.h" class Image; class ImageRect; @@ -53,7 +49,8 @@ class DropDown : public gcn::DropDown */ DropDown(gcn::ListModel *listModel = NULL, gcn::ScrollArea *scrollArea = NULL, - gcn::ListBox *listBox = NULL); + gcn::ListBox *listBox = NULL, + bool opacity = true); /** * Destructor. @@ -64,6 +61,22 @@ class DropDown : public gcn::DropDown void drawFrame(gcn::Graphics* graphics); + /** + * Sets the widget to be opaque, that is sets the widget to display its + * background. + * + * @param opaque True if the widget should be opaque, false otherwise. + */ + void setOpaque(bool opaque) {mOpaque = opaque;} + + /** + * Checks if the widget is opaque, that is if the widget area displays + * its background. + * + * @return True if the widget is opaque, false otherwise. + */ + bool isOpaque() const {return mOpaque;} + protected: /** @@ -77,6 +90,9 @@ class DropDown : public gcn::DropDown static int instances; static Image *buttons[2][2]; static ImageRect skin; + static float mAlpha; + + bool mOpaque; }; #endif // end DROPDOWN_H diff --git a/src/gui/widgets/layout.cpp b/src/gui/widgets/layout.cpp index bcc54cf7..4ffdda36 100644 --- a/src/gui/widgets/layout.cpp +++ b/src/gui/widgets/layout.cpp @@ -1,21 +1,21 @@ /* * The Mana World - * Copyright 2007 The Mana World Development Team + * Copyright (C) 2007 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ diff --git a/src/gui/widgets/layout.h b/src/gui/widgets/layout.h index d631c154..20a4222d 100644 --- a/src/gui/widgets/layout.h +++ b/src/gui/widgets/layout.h @@ -1,26 +1,26 @@ /* * The Mana World - * Copyright 2007 The Mana World Development Team + * Copyright (C) 2007 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TMW_WIDGET_LAYOUT_H__ -#define _TMW_WIDGET_LAYOUT_H__ +#ifndef WIDGET_LAYOUT_H +#define WIDGET_LAYOUT_H #include <vector> @@ -317,4 +317,4 @@ class Layout: public LayoutCell bool mComputed; }; -#endif +#endif // WIDGET_LAYOUT_H diff --git a/src/gui/widgets/layouthelper.cpp b/src/gui/widgets/layouthelper.cpp new file mode 100644 index 00000000..410de98a --- /dev/null +++ b/src/gui/widgets/layouthelper.cpp @@ -0,0 +1,63 @@ +/* + * 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 "layouthelper.h" + +LayoutHelper::LayoutHelper(gcn::Container *container): + mContainer(container) +{ + mContainer->addWidgetListener(this); +} + +LayoutHelper::~LayoutHelper() +{ + mContainer->removeWidgetListener(this); +} + +Layout &LayoutHelper::getLayout() +{ + return mLayout; +} + +LayoutCell &LayoutHelper::place(int x, int y, gcn::Widget *wg, int w, int h) +{ + mContainer->add(wg); + return mLayout.place(wg, x, y, w, h); +} + +ContainerPlacer LayoutHelper::getPlacer(int x, int y) +{ + return ContainerPlacer(mContainer, &mLayout.at(x, y)); +} + +void LayoutHelper::reflowLayout(int w, int h) +{ + mLayout.reflow(w, h); + mContainer->setSize(w, h); +} + +void LayoutHelper::widgetResized(const gcn::Event &event) +{ + const gcn::Rectangle area = mContainer->getChildrenArea(); + int w = area.width; + int h = area.height; + mLayout.reflow(w, h); +} diff --git a/src/gui/widgets/layouthelper.h b/src/gui/widgets/layouthelper.h new file mode 100644 index 00000000..afa92a18 --- /dev/null +++ b/src/gui/widgets/layouthelper.h @@ -0,0 +1,84 @@ +/* + * 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 LAYOUTHELPER_H +#define LAYOUTHELPER_H + +#include "layout.h" + +#include <guichan/widgetlistener.hpp> + +/** + * A helper class for adding a layout to a Guichan container widget. The layout + * will register itself as a widget listener and relayout the widgets in the + * container dynamically on resize. + */ +class LayoutHelper : public gcn::WidgetListener +{ + public: + /** + * Constructor. + */ + LayoutHelper(gcn::Container *container); + + /** + * Destructor. + */ + ~LayoutHelper(); + + /** + * Gets the layout handler. + */ + Layout &getLayout(); + + /** + * Computes the position of the widgets according to the current + * layout. Resizes the managed container so that the layout fits. + * + * @note This function is meant to be called with fixed-size + * containers. + * + * @param w if non-zero, force the container to this width. + * @param h if non-zero, force the container to this height. + */ + void reflowLayout(int w = 0, int h = 0); + + /** + * Adds a widget to the container and sets it at given cell. + */ + LayoutCell &place(int x, int y, gcn::Widget *, int w = 1, int h = 1); + + /** + * Returns a proxy for adding widgets in an inner table of the layout. + */ + ContainerPlacer getPlacer(int x, int y); + + /** + * Called whenever the managed container changes size. + */ + void widgetResized(const gcn::Event &event); + + private: + Layout mLayout; /**< Layout handler */ + gcn::Container *mContainer; /**< Managed container */ +}; + +#endif // LAYOUTHELPER_H diff --git a/src/gui/widgets/resizegrip.cpp b/src/gui/widgets/resizegrip.cpp index c3b537db..fa264e37 100644 --- a/src/gui/widgets/resizegrip.cpp +++ b/src/gui/widgets/resizegrip.cpp @@ -1,28 +1,29 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "resizegrip.h" - #include <guichan/graphics.hpp> +#include "resizegrip.h" + +#include "../../configuration.h" #include "../../graphics.h" #include "../../resources/image.h" @@ -30,14 +31,16 @@ Image *ResizeGrip::gripImage = 0; int ResizeGrip::mInstances = 0; +float ResizeGrip::mAlpha = config.getValue("guialpha", 0.8); -ResizeGrip::ResizeGrip() +ResizeGrip::ResizeGrip(std::string image) { if (mInstances == 0) { // Load the grip image ResourceManager *resman = ResourceManager::getInstance(); - gripImage = resman->getImage("graphics/gui/resize.png"); + gripImage = resman->getImage(image); + gripImage->setAlpha(mAlpha); } mInstances++; @@ -56,8 +59,13 @@ ResizeGrip::~ResizeGrip() } } -void -ResizeGrip::draw(gcn::Graphics *graphics) +void ResizeGrip::draw(gcn::Graphics *graphics) { + if (config.getValue("guialpha", 0.8) != mAlpha) + { + mAlpha = config.getValue("guialpha", 0.8); + gripImage->setAlpha(mAlpha); + } + static_cast<Graphics*>(graphics)->drawImage(gripImage, 0, 0); } diff --git a/src/gui/widgets/resizegrip.h b/src/gui/widgets/resizegrip.h index f57eda94..620c133f 100644 --- a/src/gui/widgets/resizegrip.h +++ b/src/gui/widgets/resizegrip.h @@ -1,26 +1,26 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TMW_RESIZEGRIP_H -#define _TMW_RESIZEGRIP_H +#ifndef RESIZEGRIP_H +#define RESIZEGRIP_H #include <guichan/widget.hpp> @@ -39,7 +39,7 @@ class ResizeGrip : public gcn::Widget /** * Constructor. */ - ResizeGrip(); + ResizeGrip(std::string image = "graphics/gui/resize.png"); /** * Destructor. @@ -54,6 +54,7 @@ class ResizeGrip : public gcn::Widget private: static Image *gripImage; /**< Resize grip image */ static int mInstances; /**< Number of resize grip instances */ + static float mAlpha; }; #endif diff --git a/src/gui/widgets/tab.cpp b/src/gui/widgets/tab.cpp index b09bc5b3..21402c89 100644 --- a/src/gui/widgets/tab.cpp +++ b/src/gui/widgets/tab.cpp @@ -1,31 +1,30 @@ /* * The Mana World - * Copyright 2008 The Mana World Development Team + * Copyright (C) 2008 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include <algorithm> - #include <guichan/widgets/label.hpp> #include "tab.h" #include "tabbedarea.h" +#include "../../configuration.h" #include "../../graphics.h" #include "../../resources/image.h" @@ -34,6 +33,7 @@ #include "../../utils/dtor.h" int Tab::mInstances = 0; +float Tab::mAlpha = config.getValue("guialpha", 0.8); enum{ TAB_STANDARD, // 0 @@ -51,10 +51,10 @@ struct TabData }; static TabData const data[TAB_COUNT] = { - {"graphics/gui/tab.png", 0, 0}, - {"graphics/gui/tab.png", 9, 4}, - {"graphics/gui/tabselected.png", 16, 19}, - {"graphics/gui/tab.png", 25, 23} + { "graphics/gui/tab.png", 0, 0 }, + { "graphics/gui/tab.png", 9, 4 }, + { "graphics/gui/tabselected.png", 16, 19 }, + { "graphics/gui/tab.png", 25, 23 } }; ImageRect Tab::tabImg[TAB_COUNT]; @@ -100,6 +100,7 @@ void Tab::init() data[x].gridX, data[y].gridY, data[x + 1].gridX - data[x].gridX + 1, data[y + 1].gridY - data[y].gridY + 1); + tabImg[mode].grid[a]->setAlpha(mAlpha); a++; } } @@ -116,7 +117,7 @@ void Tab::draw(gcn::Graphics *graphics) // check which type of tab to draw if (mTabbedArea) { - if(mTabbedArea->isTabSelected(this)) + if (mTabbedArea->isTabSelected(this)) { mode = TAB_SELECTED; // if tab is selected, it doesnt need to highlight activity @@ -130,6 +131,15 @@ void Tab::draw(gcn::Graphics *graphics) } } + if (config.getValue("guialpha", 0.8) != mAlpha) + { + mAlpha = config.getValue("guialpha", 0.8); + for (int a = 0; a < 9; a++) + { + tabImg[TAB_SELECTED].grid[a]->setAlpha(mAlpha); + tabImg[TAB_STANDARD].grid[a]->setAlpha(mAlpha); + } + } // draw tab static_cast<Graphics*>(graphics)-> diff --git a/src/gui/widgets/tab.h b/src/gui/widgets/tab.h index 65cc3fa0..3af4e2bf 100644 --- a/src/gui/widgets/tab.h +++ b/src/gui/widgets/tab.h @@ -1,26 +1,26 @@ /* * The Mana World - * Copyright 2008 The Mana World Development Team + * Copyright (C) 2008 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TMW_TAB_H -#define _TMW_TAB_H +#ifndef TAB_H +#define TAB_H #include <guichan/widgets/tab.hpp> @@ -58,6 +58,7 @@ class Tab : public gcn::Tab static ImageRect tabImg[4]; /**< Tab state graphics */ static int mInstances; /**< Number of tab instances */ + static float mAlpha; bool mHighlighted; }; diff --git a/src/gui/widgets/tabbedarea.cpp b/src/gui/widgets/tabbedarea.cpp index 205fdc99..ce11fe69 100644 --- a/src/gui/widgets/tabbedarea.cpp +++ b/src/gui/widgets/tabbedarea.cpp @@ -1,21 +1,21 @@ /* * The Mana World - * Copyright 2008 The Mana World Development Team + * Copyright (C) 2008 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ @@ -75,7 +75,7 @@ gcn::Widget* TabbedArea::getWidget(const std::string &name) void TabbedArea::addTab(const std::string &caption, gcn::Widget *widget) { - Tab* tab = new Tab(); + Tab* tab = new Tab; tab->setCaption(caption); mTabsToDelete.push_back(tab); @@ -90,7 +90,7 @@ void TabbedArea::addTab(Tab *tab, gcn::Widget *widget) mTabContainer->add(tab); mTabs.push_back(std::pair<Tab*, gcn::Widget*>(tab, widget)); - if (mSelectedTab == NULL) + if (!mSelectedTab) { setSelectedTab(tab); } diff --git a/src/gui/widgets/tabbedarea.h b/src/gui/widgets/tabbedarea.h index 2199264b..01d70380 100644 --- a/src/gui/widgets/tabbedarea.h +++ b/src/gui/widgets/tabbedarea.h @@ -1,26 +1,26 @@ /* * The Mana World - * Copyright 2008 The Mana World Development Team + * Copyright (C) 2008 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TMW_TABBEDAREA_H -#define _TMW_TABBEDAREA_H +#ifndef TABBEDAREA_H +#define TABBEDAREA_H #include <guichan/widget.hpp> #include <guichan/widgets/tabbedarea.hpp> diff --git a/src/gui/window.cpp b/src/gui/window.cpp index 64607243..58439316 100644 --- a/src/gui/window.cpp +++ b/src/gui/window.cpp @@ -1,21 +1,21 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ @@ -24,13 +24,9 @@ #include <climits> #include <guichan/exception.hpp> -#include <guichan/widgets/icon.hpp> - -#include <libxml/tree.h> - -#include "window.h" #include "gui.h" +#include "window.h" #include "windowcontainer.h" #include "widgets/layout.h" @@ -38,7 +34,6 @@ #include "../configlistener.h" #include "../configuration.h" -#include "../graphics.h" #include "../log.h" #include "../resources/image.h" @@ -50,55 +45,53 @@ ConfigListener *Window::windowConfigListener = 0; WindowContainer *Window::windowContainer = 0; int Window::instances = 0; int Window::mouseResize = 0; +//ImageRect Window::border; Image *Window::closeImage = NULL; -bool mLoaded = false; bool Window::mAlphaChanged = false; class WindowConfigListener : public ConfigListener { - /* - void optionChanged(const std::string &) - { - for_each(Window::border.grid, Window::border.grid + 9, - std::bind2nd(std::mem_fun(&Image::setAlpha), - config.getValue("guialpha", 0.8))); - } - */ - void optionChanged(const std::string &) { Window::mAlphaChanged = true; } }; -Window::Window(const std::string& caption, bool modal, Window *parent): +Window::Window(const std::string& caption, bool modal, Window *parent, const std::string& skin): gcn::Window(caption), mGrip(0), mParent(parent), mLayout(NULL), + mWindowName("window"), + mShowTitle(true), mModal(modal), mCloseButton(false), mSticky(false), mMinWinWidth(100), mMinWinHeight(40), mMaxWinWidth(INT_MAX), - mMaxWinHeight(INT_MAX) + mMaxWinHeight(INT_MAX), + mSkin(skin) { logger->log("Window::Window(\"%s\")", caption.c_str()); - if (!windowContainer) { + if (!windowContainer) + { throw GCN_EXCEPTION("Window::Window(): no windowContainer set"); } - loadSkin("graphics/gui/gui.xml"); + // Loads the skin + loadSkin(mSkin); + + setGuiAlpha(); - //if (instances == 0) - //{ - //WindowConfigListener = new WindowConfigListener(); + if (instances == 0) + { + windowConfigListener = new WindowConfigListener; // Send GUI alpha changed for initialization - //windowConfigListener->optionChanged("guialpha"); - //config.addListener("guialpha", windowConfigListener); - //} + windowConfigListener->optionChanged("guialpha"); + config.addListener("guialpha", windowConfigListener); + } instances++; @@ -106,8 +99,6 @@ Window::Window(const std::string& caption, bool modal, Window *parent): setPadding(3); setTitleBarHeight(20); - setGuiAlpha(); - // Add this window to the window container windowContainer->add(this); @@ -125,16 +116,18 @@ Window::Window(const std::string& caption, bool modal, Window *parent): Window::~Window() { - logger->log("UNLOAD: Window::~Window(\"%s\")", getCaption().c_str()); + logger->log("Window::~Window(\"%s\")", getCaption().c_str()); const std::string &name = mWindowName; // Saving X, Y and Width and Height for resizables in the config - if (!name.empty()) { + if (!name.empty()) + { config.setValue(name + "WinX", getX()); config.setValue(name + "WinY", getY()); config.setValue(name + "Visible", isVisible()); - if (mGrip) { + if (mGrip) + { config.setValue(name + "WinWidth", getWidth()); config.setValue(name + "WinHeight", getHeight()); } @@ -151,22 +144,21 @@ Window::~Window() instances--; + // Clean up static resources + for (int i = 0; i < 9; i++) + { + delete border.grid[i]; + border.grid[i] = NULL; + } + if (instances == 0) { config.removeListener("guialpha", windowConfigListener); delete windowConfigListener; windowConfigListener = NULL; - // Clean up static resources closeImage->decRef(); } - - // Clean up Border images. - for( int i = 0; i < 9; i++ ) - { - delete border[i]; - border[i] = NULL; - } } void Window::setWindowContainer(WindowContainer *wc) @@ -176,17 +168,12 @@ void Window::setWindowContainer(WindowContainer *wc) void Window::draw(gcn::Graphics *graphics) { - if (mAlphaChanged) - setGuiAlpha(); - Graphics *g = static_cast<Graphics*>(graphics); - //g->drawImageRect(0, 0, getWidth(), getHeight(), border); - - g->drawImageRect(0, 0, getWidth(), getHeight(), border[0], border[2], border[6], border[8], border[1], border[5], border[7], border[3], border[4]); + g->drawImageRect(0, 0, getWidth(), getHeight(), border); // Draw title - if (getTitleBarHeight()) + if (mShowTitle) { g->setColor(gcn::Color(0, 0, 0)); g->setFont(getFont()); @@ -201,6 +188,15 @@ void Window::draw(gcn::Graphics *graphics) getPadding() ); } + + // Update window alpha values + if (mAlphaChanged) + { + for_each(border.grid, border.grid + 9, + std::bind2nd(std::mem_fun(&Image::setAlpha), + config.getValue("guialpha", 0.8))); + closeImage->setAlpha(config.getValue("guialpha", 0.8)); + } drawChildren(graphics); } @@ -248,7 +244,7 @@ void Window::setResizable(bool r) if (r) { - mGrip = new ResizeGrip(); + mGrip = new ResizeGrip; mGrip->setX(getWidth() - mGrip->getWidth() - getChildrenArea().x); mGrip->setY(getHeight() - mGrip->getHeight() - getChildrenArea().y); add(mGrip); @@ -263,17 +259,16 @@ void Window::setResizable(bool r) void Window::widgetResized(const gcn::Event &event) { + const gcn::Rectangle area = getChildrenArea(); + if (mGrip) - { - const gcn::Rectangle area = getChildrenArea(); mGrip->setPosition(getWidth() - mGrip->getWidth() - area.x, getHeight() - mGrip->getHeight() - area.y); - } if (mLayout) { - int w = getWidth() - 2 * getPadding(); - int h = getHeight() - getPadding() - getTitleBarHeight(); + int w = area.width; + int h = area.height; mLayout->reflow(w, h); } } @@ -527,39 +522,13 @@ int Window::getResizeHandles(gcn::MouseEvent &event) return resizeHandles; } -Layout &Window::getLayout() -{ - if (!mLayout) mLayout = new Layout; - return *mLayout; -} - -LayoutCell &Window::place(int x, int y, gcn::Widget *wg, int w, int h) -{ - add(wg); - return getLayout().place(wg, x, y, w, h); -} - -ContainerPlacer Window::getPlacer(int x, int y) -{ - return ContainerPlacer(this, &getLayout().at(x, y)); -} - -void Window::reflowLayout(int w, int h) -{ - assert(mLayout); - mLayout->reflow(w, h); - delete mLayout; - mLayout = NULL; - setContentSize(w, h); -} - void Window::setGuiAlpha() { //logger->log("Window::setGuiAlpha: Alpha Value %f", config.getValue("guialpha", 0.8)); - for(int i = 0; i < 9; i++) + for (int i = 0; i < 9; i++) { //logger->log("Window::setGuiAlpha: Border Image (%i)", i); - border[i]->setAlpha(config.getValue("guialpha", 0.8)); + border.grid[i]->setAlpha(config.getValue("guialpha", 0.8)); } mAlphaChanged = false; @@ -567,13 +536,15 @@ void Window::setGuiAlpha() void Window::loadSkin(const std::string &fileName) { + const std::string windowId = Window::getId(); + ResourceManager *resman = ResourceManager::getInstance(); logger->log("Loading Window Skin '%s'.", fileName.c_str()); - logger->log("Loading Window ID '%s'.", Window::getId().c_str()); + logger->log("Loading Window ID '%s'.", windowId.c_str()); - if (fileName == "") + if (fileName.empty()) logger->error("Window::loadSkin(): Invalid File Name."); // TODO: @@ -591,7 +562,7 @@ void Window::loadSkin(const std::string &fileName) std::string skinSetImage; skinSetImage = XML::getProperty(rootNode, "image", ""); Image *dBorders = NULL; - if(skinSetImage != "") + if (!skinSetImage.empty()) { logger->log("Window::loadSkin(): <skinset> defines '%s' as a skin image.", skinSetImage.c_str()); dBorders = resman->getImage("graphics/gui/" + skinSetImage);//"graphics/gui/speech_bubble.png"); @@ -611,7 +582,7 @@ void Window::loadSkin(const std::string &fileName) widgetType = XML::getProperty(widgetNode, "type", "unknown"); if (widgetType == "Window") { - // Itarate through <part>'s + // Iterate through <part>'s // LEEOR / TODO: // We need to make provisions to load in a CloseButton image. For now it // can just be hard-coded. @@ -625,90 +596,90 @@ void Window::loadSkin(const std::string &fileName) std::string partType; partType = XML::getProperty(partNode, "type", "unknown"); // TOP ROW - if(partType == "top-left-corner") + if (partType == "top-left-corner") { const int xPos = XML::getProperty(partNode, "xpos", 0); const int yPos = XML::getProperty(partNode, "ypos", 0); const int width = XML::getProperty(partNode, "width", 1); const int height = XML::getProperty(partNode, "height", 1); - border[0] = dBorders->getSubImage(xPos, yPos, width, height); + border.grid[0] = dBorders->getSubImage(xPos, yPos, width, height); } - else if(partType == "top-edge") + else if (partType == "top-edge") { const int xPos = XML::getProperty(partNode, "xpos", 0); const int yPos = XML::getProperty(partNode, "ypos", 0); const int width = XML::getProperty(partNode, "width", 1); const int height = XML::getProperty(partNode, "height", 1); - border[1] = dBorders->getSubImage(xPos, yPos, width, height); + border.grid[1] = dBorders->getSubImage(xPos, yPos, width, height); } - else if(partType == "top-right-corner") + else if (partType == "top-right-corner") { const int xPos = XML::getProperty(partNode, "xpos", 0); const int yPos = XML::getProperty(partNode, "ypos", 0); const int width = XML::getProperty(partNode, "width", 1); const int height = XML::getProperty(partNode, "height", 1); - border[2] = dBorders->getSubImage(xPos, yPos, width, height); + border.grid[2] = dBorders->getSubImage(xPos, yPos, width, height); } // MIDDLE ROW - else if(partType == "left-edge") + else if (partType == "left-edge") { const int xPos = XML::getProperty(partNode, "xpos", 0); const int yPos = XML::getProperty(partNode, "ypos", 0); const int width = XML::getProperty(partNode, "width", 1); const int height = XML::getProperty(partNode, "height", 1); - border[3] = dBorders->getSubImage(xPos, yPos, width, height); + border.grid[3] = dBorders->getSubImage(xPos, yPos, width, height); } - else if(partType == "bg-quad") + else if (partType == "bg-quad") { const int xPos = XML::getProperty(partNode, "xpos", 0); const int yPos = XML::getProperty(partNode, "ypos", 0); const int width = XML::getProperty(partNode, "width", 1); const int height = XML::getProperty(partNode, "height", 1); - border[4] = dBorders->getSubImage(xPos, yPos, width, height); + border.grid[4] = dBorders->getSubImage(xPos, yPos, width, height); } - else if(partType == "right-edge") + else if (partType == "right-edge") { const int xPos = XML::getProperty(partNode, "xpos", 0); const int yPos = XML::getProperty(partNode, "ypos", 0); const int width = XML::getProperty(partNode, "width", 1); const int height = XML::getProperty(partNode, "height", 1); - border[5] = dBorders->getSubImage(xPos, yPos, width, height); + border.grid[5] = dBorders->getSubImage(xPos, yPos, width, height); } // BOTTOM ROW - else if(partType == "bottom-left-corner") + else if (partType == "bottom-left-corner") { const int xPos = XML::getProperty(partNode, "xpos", 0); const int yPos = XML::getProperty(partNode, "ypos", 0); const int width = XML::getProperty(partNode, "width", 1); const int height = XML::getProperty(partNode, "height", 1); - border[6] = dBorders->getSubImage(xPos, yPos, width, height); + border.grid[6] = dBorders->getSubImage(xPos, yPos, width, height); } - else if(partType == "bottom-edge") + else if (partType == "bottom-edge") { const int xPos = XML::getProperty(partNode, "xpos", 0); const int yPos = XML::getProperty(partNode, "ypos", 0); const int width = XML::getProperty(partNode, "width", 1); const int height = XML::getProperty(partNode, "height", 1); - border[7] = dBorders->getSubImage(xPos, yPos, width, height); + border.grid[7] = dBorders->getSubImage(xPos, yPos, width, height); } - else if(partType == "bottom-right-corner") + else if (partType == "bottom-right-corner") { const int xPos = XML::getProperty(partNode, "xpos", 0); const int yPos = XML::getProperty(partNode, "ypos", 0); const int width = XML::getProperty(partNode, "width", 1); const int height = XML::getProperty(partNode, "height", 1); - border[8] = dBorders->getSubImage(xPos, yPos, width, height); + border.grid[8] = dBorders->getSubImage(xPos, yPos, width, height); } // Part is of an uknown type. @@ -731,3 +702,29 @@ void Window::loadSkin(const std::string &fileName) // Hard-coded for now until we update the above code to look for window buttons. closeImage = resman->getImage("graphics/gui/close_button.png"); } + +Layout &Window::getLayout() +{ + if (!mLayout) mLayout = new Layout; + return *mLayout; +} + +LayoutCell &Window::place(int x, int y, gcn::Widget *wg, int w, int h) +{ + add(wg); + return getLayout().place(wg, x, y, w, h); +} + +ContainerPlacer Window::getPlacer(int x, int y) +{ + return ContainerPlacer(this, &getLayout().at(x, y)); +} + +void Window::reflowLayout(int w, int h) +{ + assert(mLayout); + mLayout->reflow(w, h); + delete mLayout; + mLayout = NULL; + setContentSize(w, h); +} diff --git a/src/gui/window.h b/src/gui/window.h index 50a206f0..3806342a 100644 --- a/src/gui/window.h +++ b/src/gui/window.h @@ -1,30 +1,32 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TMW_WINDOW_H__ -#define _TMW_WINDOW_H__ +#ifndef WINDOW_H +#define WINDOW_H -#include <guichan/widgets/window.hpp> #include <guichan/widgetlistener.hpp> +#include <guichan/widgets/window.hpp> + +#include "../graphics.h" #include "../guichanfwd.h" class ConfigListener; @@ -56,9 +58,10 @@ class Window : public gcn::Window, gcn::WidgetListener * @param parent The parent window. This is the window standing above * this one in the window hiearchy. When reordering, * a window will never go below its parent window. + * @param skin The location where the window's skin XML can be found. */ Window(const std::string &caption = "Window", bool modal = false, - Window *parent = NULL); + Window *parent = NULL, const std::string &skin = "graphics/gui/gui.xml"); /** * Destructor. Deletes all the added widgets. @@ -126,6 +129,26 @@ class Window : public gcn::Window, gcn::WidgetListener void setMaxHeight(unsigned int height); /** + * Gets the minimum width of the window. + */ + int getMinWidth() { return mMinWinWidth; } + + /** + * Gets the minimum height of the window. + */ + int getMinHeight() { return mMinWinHeight; } + + /** + * Gets the maximum width of the window. + */ + int getMaxWidth() { return mMaxWinWidth; } + + /** + * Gets the minimum height of the window. + */ + int getMaxHeight() { return mMaxWinHeight; } + + /** * Sets flag to show a title or not. */ void setShowTitle(bool flag) @@ -238,6 +261,11 @@ class Window : public gcn::Window, gcn::WidgetListener void reflowLayout(int w = 0, int h = 0); /** + * Loads a window skin + */ + void loadSkin(const std::string &fileName); + + /** * Adds a widget to the window and sets it at given cell. */ LayoutCell &place(int x, int y, gcn::Widget *, int w = 1, int h = 1); @@ -247,11 +275,6 @@ class Window : public gcn::Window, gcn::WidgetListener */ ContainerPlacer getPlacer(int x, int y); - /** - * Loads a window skin - */ - void loadSkin(const std::string &fileName); - protected: /** The window container windows add themselves to. */ static WindowContainer *windowContainer; @@ -274,6 +297,8 @@ class Window : public gcn::Window, gcn::WidgetListener */ int getResizeHandles(gcn::MouseEvent &event); + void setGuiAlpha(); + ResizeGrip *mGrip; /**< Resize grip */ Window *mParent; /**< The parent window */ Layout *mLayout; /**< Layout handler */ @@ -282,6 +307,7 @@ class Window : public gcn::Window, gcn::WidgetListener bool mModal; /**< Window is modal */ bool mCloseButton; /**< Window has a close button */ bool mSticky; /**< Window resists minimization */ + static bool mAlphaChanged; /**< Whether the alpha percent was changed */ int mMinWinWidth; /**< Minimum window width */ int mMinWinHeight; /**< Minimum window height */ int mMaxWinWidth; /**< Maximum window width */ @@ -290,6 +316,7 @@ class Window : public gcn::Window, gcn::WidgetListener int mDefaultY; /**< Default window Y position */ int mDefaultWidth; /**< Default window width */ int mDefaultHeight; /**< Default window height */ + std::string mSkin; /**< Name of the skin to use */ /** * The config listener that listens to changes relevant to all windows. @@ -298,10 +325,7 @@ class Window : public gcn::Window, gcn::WidgetListener static int mouseResize; /**< Active resize handles */ static int instances; /**< Number of Window instances */ - - void setGuiAlpha(); - static bool mAlphaChanged; - Image *border[9]; + ImageRect border; /**< The window border and background */ static Image *closeImage; /**< Close Button Image */ /** diff --git a/src/gui/windowcontainer.cpp b/src/gui/windowcontainer.cpp index d8535f73..2846b1c1 100644 --- a/src/gui/windowcontainer.cpp +++ b/src/gui/windowcontainer.cpp @@ -1,21 +1,21 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ diff --git a/src/gui/windowcontainer.h b/src/gui/windowcontainer.h index 88a13d31..62704d1b 100644 --- a/src/gui/windowcontainer.h +++ b/src/gui/windowcontainer.h @@ -1,26 +1,26 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 2004 The Mana World Development Team * * This file is part of The Mana World. * - * The Mana World is free software; you can redistribute it and/or modify + * 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. * - * The Mana World is distributed in the hope that it will be useful, + * 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 The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _TMW_WINDOWCONTAINER_H_ -#define _TMW_WINDOWCONTAINER_H_ +#ifndef WINDOWCONTAINER_H +#define WINDOWCONTAINER_H #include <guichan/widgets/container.hpp> @@ -30,7 +30,8 @@ * * \ingroup GUI */ -class WindowContainer : public gcn::Container { +class WindowContainer : public gcn::Container +{ public: /** * Do GUI logic. This functions adds automatic deletion of objects that |