From 81306cf16bd4660b868f24a74b1e731c8a00af95 Mon Sep 17 00:00:00 2001 From: Thorbjørn Lindeijer Date: Sun, 15 Jan 2012 23:56:26 +0100 Subject: Renamed some file names for consistency with the class names This was already done by ManaPlus. It's a good idea anyway and it makes comparing the code a little easier. Reviewed-by: Yohann Ferreira --- src/gui/buy.cpp | 305 --------------------- src/gui/buy.h | 128 --------- src/gui/buydialog.cpp | 305 +++++++++++++++++++++ src/gui/buydialog.h | 128 +++++++++ src/gui/buysell.cpp | 119 --------- src/gui/buysell.h | 67 ----- src/gui/buyselldialog.cpp | 119 +++++++++ src/gui/buyselldialog.h | 67 +++++ src/gui/chat.cpp | 543 -------------------------------------- src/gui/chat.h | 227 ---------------- src/gui/chatwindow.cpp | 543 ++++++++++++++++++++++++++++++++++++++ src/gui/chatwindow.h | 227 ++++++++++++++++ src/gui/help.cpp | 107 -------- src/gui/help.h | 66 ----- src/gui/helpwindow.cpp | 107 ++++++++ src/gui/helpwindow.h | 66 +++++ src/gui/inventorywindow.cpp | 2 +- src/gui/itemamount.cpp | 249 ----------------- src/gui/itemamount.h | 104 -------- src/gui/itemamountwindow.cpp | 249 +++++++++++++++++ src/gui/itemamountwindow.h | 104 ++++++++ src/gui/login.cpp | 158 ----------- src/gui/login.h | 76 ------ src/gui/logindialog.cpp | 158 +++++++++++ src/gui/logindialog.h | 76 ++++++ src/gui/ministatus.cpp | 261 ------------------ src/gui/ministatus.h | 82 ------ src/gui/ministatuswindow.cpp | 261 ++++++++++++++++++ src/gui/ministatuswindow.h | 82 ++++++ src/gui/outfitwindow.cpp | 2 +- src/gui/popupmenu.cpp | 4 +- src/gui/recorder.cpp | 2 +- src/gui/register.cpp | 2 +- src/gui/sell.cpp | 326 ----------------------- src/gui/sell.h | 117 -------- src/gui/selldialog.cpp | 326 +++++++++++++++++++++++ src/gui/selldialog.h | 117 ++++++++ src/gui/serverdialog.cpp | 2 +- src/gui/trade.cpp | 315 ---------------------- src/gui/trade.h | 139 ---------- src/gui/tradewindow.cpp | 315 ++++++++++++++++++++++ src/gui/tradewindow.h | 139 ++++++++++ src/gui/updaterwindow.cpp | 520 ++++++++++++++++++++++++++++++++++++ src/gui/updaterwindow.h | 195 ++++++++++++++ src/gui/updatewindow.cpp | 520 ------------------------------------ src/gui/updatewindow.h | 195 -------------- src/gui/viewport.cpp | 2 +- src/gui/widgets/chattab.cpp | 2 +- src/gui/widgets/chattab.h | 2 +- src/gui/widgets/itemcontainer.cpp | 2 +- src/gui/widgets/whispertab.cpp | 2 +- 51 files changed, 4116 insertions(+), 4116 deletions(-) delete mode 100644 src/gui/buy.cpp delete mode 100644 src/gui/buy.h create mode 100644 src/gui/buydialog.cpp create mode 100644 src/gui/buydialog.h delete mode 100644 src/gui/buysell.cpp delete mode 100644 src/gui/buysell.h create mode 100644 src/gui/buyselldialog.cpp create mode 100644 src/gui/buyselldialog.h delete mode 100644 src/gui/chat.cpp delete mode 100644 src/gui/chat.h create mode 100644 src/gui/chatwindow.cpp create mode 100644 src/gui/chatwindow.h delete mode 100644 src/gui/help.cpp delete mode 100644 src/gui/help.h create mode 100644 src/gui/helpwindow.cpp create mode 100644 src/gui/helpwindow.h delete mode 100644 src/gui/itemamount.cpp delete mode 100644 src/gui/itemamount.h create mode 100644 src/gui/itemamountwindow.cpp create mode 100644 src/gui/itemamountwindow.h delete mode 100644 src/gui/login.cpp delete mode 100644 src/gui/login.h create mode 100644 src/gui/logindialog.cpp create mode 100644 src/gui/logindialog.h delete mode 100644 src/gui/ministatus.cpp delete mode 100644 src/gui/ministatus.h create mode 100644 src/gui/ministatuswindow.cpp create mode 100644 src/gui/ministatuswindow.h delete mode 100644 src/gui/sell.cpp delete mode 100644 src/gui/sell.h create mode 100644 src/gui/selldialog.cpp create mode 100644 src/gui/selldialog.h delete mode 100644 src/gui/trade.cpp delete mode 100644 src/gui/trade.h create mode 100644 src/gui/tradewindow.cpp create mode 100644 src/gui/tradewindow.h create mode 100644 src/gui/updaterwindow.cpp create mode 100644 src/gui/updaterwindow.h delete mode 100644 src/gui/updatewindow.cpp delete mode 100644 src/gui/updatewindow.h (limited to 'src/gui') diff --git a/src/gui/buy.cpp b/src/gui/buy.cpp deleted file mode 100644 index 0ef187be..00000000 --- a/src/gui/buy.cpp +++ /dev/null @@ -1,305 +0,0 @@ -/* - * The Mana Client - * Copyright (C) 2004-2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers - * - * This file is part of The Mana Client. - * - * 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, see . - */ - -#include "gui/buy.h" - -#include "client.h" -#include "playerinfo.h" -#include "shopitem.h" -#include "units.h" - -#include "gui/setup.h" - -#include "gui/widgets/button.h" -#include "gui/widgets/label.h" -#include "gui/widgets/layout.h" -#include "gui/widgets/scrollarea.h" -#include "gui/widgets/shopitems.h" -#include "gui/widgets/shoplistbox.h" -#include "gui/widgets/slider.h" - -#include "net/net.h" -#include "net/npchandler.h" - -#include "resources/iteminfo.h" - -#include "utils/gettext.h" -#include "utils/stringutils.h" - -BuyDialog::DialogList BuyDialog::instances; - -BuyDialog::BuyDialog(int npcId): - Window(_("Buy")), - mNpcId(npcId), mMoney(0), mAmountItems(0), mMaxItems(0) -{ - setWindowName("Buy"); - //setupWindow->registerWindowForReset(this); - setResizable(true); - setCloseButton(true); - setMinWidth(260); - setMinHeight(230); - setDefaultSize(260, 230, ImageRect::CENTER); - - mShopItems = new ShopItems; - - mShopItemList = new ShopListBox(mShopItems, mShopItems); - mScrollArea = new ScrollArea(mShopItemList); - mScrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); - - mSlider = new Slider(1.0); - mQuantityLabel = new Label(strprintf("%d / %d", mAmountItems, mMaxItems)); - mQuantityLabel->setAlignment(gcn::Graphics::CENTER); - mMoneyLabel = new Label(strprintf(_("Price: %s / Total: %s"), - "", "")); - - // TRANSLATORS: This is a narrow symbol used to denote 'increasing'. - // You may change this symbol if your language uses another. - mIncreaseButton = new Button(_("+"), "inc", this); - // TRANSLATORS: This is a narrow symbol used to denote 'decreasing'. - // You may change this symbol if your language uses another. - mDecreaseButton = new Button(_("-"), "dec", this); - mBuyButton = new Button(_("Buy"), "buy", this); - mQuitButton = new Button(_("Quit"), "quit", this); - mAddMaxButton = new Button(_("Max"), "max", this); - - mDecreaseButton->adjustSize(); - mDecreaseButton->setWidth(mIncreaseButton->getWidth()); - - mIncreaseButton->setEnabled(false); - mDecreaseButton->setEnabled(false); - mBuyButton->setEnabled(false); - mSlider->setEnabled(false); - - mSlider->setActionEventId("slider"); - mSlider->addActionListener(this); - mShopItemList->addSelectionListener(this); - - ContainerPlacer place; - place = getPlacer(0, 0); - - place(0, 0, mScrollArea, 8, 5).setPadding(3); - place(0, 5, mDecreaseButton); - place(1, 5, mSlider, 3); - place(4, 5, mIncreaseButton); - place(5, 5, mQuantityLabel, 2); - place(7, 5, mAddMaxButton); - place(0, 6, mMoneyLabel, 8); - place(6, 7, mBuyButton); - place(7, 7, mQuitButton); - - Layout &layout = getLayout(); - layout.setRowHeight(0, Layout::AUTO_SET); - - center(); - loadWindowState(); - - instances.push_back(this); - setVisible(true); - - PlayerInfo::setBuySellState(BUYSELL_BUYING); -} - -BuyDialog::~BuyDialog() -{ - delete mShopItems; - - instances.remove(this); - - if (PlayerInfo::getBuySellState() == BUYSELL_BUYING) - PlayerInfo::setBuySellState(BUYSELL_NONE); -} - -void BuyDialog::setMoney(int amount) -{ - mMoney = amount; - mShopItemList->setPlayersMoney(amount); - - updateButtonsAndLabels(); -} - -void BuyDialog::reset() -{ - mShopItems->clear(); - mShopItemList->adjustSize(); - - // Reset previous selected items to prevent failing asserts - mShopItemList->setSelected(-1); - mSlider->setValue(0); - - setMoney(0); -} - -void BuyDialog::addItem(int id, int amount, int price) -{ - mShopItems->addItem(id, amount, price); - mShopItemList->adjustSize(); -} - -void BuyDialog::action(const gcn::ActionEvent &event) -{ - if (event.getId() == "quit") - { - close(); - return; - } - - int selectedItem = mShopItemList->getSelected(); - - // The following actions require a valid selection - if (selectedItem < 0 || - selectedItem >= (int) mShopItems->getNumberOfElements()) - { - return; - } - - if (event.getId() == "slider") - { - mAmountItems = (int) mSlider->getValue(); - updateButtonsAndLabels(); - } - else if (event.getId() == "inc" && mAmountItems < mMaxItems) - { - mAmountItems++; - mSlider->setValue(mAmountItems); - updateButtonsAndLabels(); - } - else if (event.getId() == "dec" && mAmountItems > 1) - { - mAmountItems--; - mSlider->setValue(mAmountItems); - updateButtonsAndLabels(); - } - else if (event.getId() == "max") - { - mAmountItems = mMaxItems; - mSlider->setValue(mAmountItems); - updateButtonsAndLabels(); - } - // TODO: Actually we'd have a bug elsewhere if this check for the number - // of items to be bought ever fails, Bertram removed the assertions, is - // there a better way to ensure this fails in an _obvious_ way in C++? - else if (event.getId() == "buy" && mAmountItems > 0 && - mAmountItems <= mMaxItems) - { - Net::getNpcHandler()->buyItem(mNpcId, - mShopItems->at(selectedItem)->getId(), - mAmountItems); - - // Update money and adjust the max number of items that can be bought - mMaxItems -= mAmountItems; - int price = mShopItems->at(selectedItem)->getPrice(); - if (price < 0) - price = 0; - setMoney(mMoney - mAmountItems * price); - valueChanged(gcn::SelectionEvent(mShopItemList)); - } -} - -void BuyDialog::valueChanged(const gcn::SelectionEvent &event) -{ - // Reset amount of items and update labels - mAmountItems = 1; - mSlider->setValue(1); - - updateButtonsAndLabels(); - mSlider->gcn::Slider::setScale(1, mMaxItems); -} - -void BuyDialog::mouseClicked(gcn::MouseEvent &mouseEvent) -{ - if (mouseEvent.getSource() == mShopItemList && - isDoubleClick(mShopItemList->getSelected())) - { - action(gcn::ActionEvent(mBuyButton, mBuyButton->getActionEventId())); - } -} - -void BuyDialog::updateButtonsAndLabels() -{ - const int selectedItem = mShopItemList->getSelected(); - int price = 0; - - if (selectedItem > -1) - { - int itemPrice = mShopItems->at(selectedItem)->getPrice(); - - // Calculate how many the player can afford - if (itemPrice > 0) - { - mMaxItems = mMoney / itemPrice; - } - else - { - // Let the player no more than 1 of them at a time, since it - // shouldn't be a permitted case. - mMaxItems = 1; - } - - if (mAmountItems > mMaxItems) - mAmountItems = mMaxItems; - - // Calculate price of pending purchase - price = mAmountItems * itemPrice; - } - else - { - mMaxItems = 0; - mAmountItems = 0; - } - - // Enable or disable buttons and slider - mIncreaseButton->setEnabled(mAmountItems < mMaxItems); - mDecreaseButton->setEnabled(mAmountItems > 1); - mBuyButton->setEnabled(mAmountItems > 0); - mSlider->setEnabled(mMaxItems > 1); - - // Update quantity and money labels - mQuantityLabel->setCaption(strprintf("%d / %d", mAmountItems, mMaxItems)); - mMoneyLabel->setCaption - (strprintf(_("Price: %s / Total: %s"), - Units::formatCurrency(price).c_str(), - Units::formatCurrency(mMoney - price).c_str())); -} - -void BuyDialog::setVisible(bool visible) -{ - Window::setVisible(visible); - - if (visible) - { - mShopItemList->requestFocus(); - } - else - { - scheduleDelete(); - } -} - -void BuyDialog::closeAll() -{ - DialogList::iterator it = instances.begin(); - DialogList::iterator it_end = instances.end(); - - for (; it != it_end; it++) - { - (*it)->close(); - } -} diff --git a/src/gui/buy.h b/src/gui/buy.h deleted file mode 100644 index 2ecf89e1..00000000 --- a/src/gui/buy.h +++ /dev/null @@ -1,128 +0,0 @@ -/* - * The Mana Client - * Copyright (C) 2004-2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers - * - * This file is part of The Mana Client. - * - * 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, see . - */ - -#ifndef BUY_H -#define BUY_H - -#include "guichanfwd.h" - -#include "gui/widgets/window.h" - -#include -#include - -class ShopItems; -class ShopListBox; -class ListBox; - -/** - * The buy dialog. - * - * \ingroup Interface - */ -class BuyDialog : public Window, public gcn::ActionListener, - public gcn::SelectionListener -{ - public: - BuyDialog(int npcId); - - ~BuyDialog(); - - /** - * Resets the dialog, clearing shop inventory. - */ - void reset(); - - /** - * Sets the amount of available money. - */ - void setMoney(int amount); - - /** - * Adds an item to the shop inventory. - */ - void addItem(int id, int amount, int price); - - /** - * Called when receiving actions from the widgets. - */ - void action(const gcn::ActionEvent &event); - - /** - * Returns the number of items in the shop inventory. - */ - int getNumberOfElements(); - - /** - * Updates the labels according to the selected item. - */ - void valueChanged(const gcn::SelectionEvent &event); - - /** - * Allows for quick-buying by extending double-click events. - */ - void mouseClicked(gcn::MouseEvent &mouseEvent); - - /** - * Returns the name of item number i in the shop inventory. - */ - std::string getElementAt(int i); - - /** - * Updates the state of buttons and labels. - */ - void updateButtonsAndLabels(); - - /** - * Sets the visibility of this window. - */ - void setVisible(bool visible); - - /** - * Closes all instances. - */ - static void closeAll(); - - private: - typedef std::list DialogList; - static DialogList instances; - - int mNpcId; - - gcn::Button *mBuyButton; - gcn::Button *mQuitButton; - gcn::Button *mAddMaxButton; - gcn::Button *mIncreaseButton; - gcn::Button *mDecreaseButton; - ShopListBox *mShopItemList; - gcn::ScrollArea *mScrollArea; - gcn::Label *mMoneyLabel; - gcn::Label *mQuantityLabel; - gcn::Slider *mSlider; - - ShopItems *mShopItems; - - int mMoney; - int mAmountItems; - int mMaxItems; -}; - -#endif diff --git a/src/gui/buydialog.cpp b/src/gui/buydialog.cpp new file mode 100644 index 00000000..1f9781c4 --- /dev/null +++ b/src/gui/buydialog.cpp @@ -0,0 +1,305 @@ +/* + * The Mana Client + * Copyright (C) 2004-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * + * This file is part of The Mana Client. + * + * 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, see . + */ + +#include "gui/buydialog.h" + +#include "client.h" +#include "playerinfo.h" +#include "shopitem.h" +#include "units.h" + +#include "gui/setup.h" + +#include "gui/widgets/button.h" +#include "gui/widgets/label.h" +#include "gui/widgets/layout.h" +#include "gui/widgets/scrollarea.h" +#include "gui/widgets/shopitems.h" +#include "gui/widgets/shoplistbox.h" +#include "gui/widgets/slider.h" + +#include "net/net.h" +#include "net/npchandler.h" + +#include "resources/iteminfo.h" + +#include "utils/gettext.h" +#include "utils/stringutils.h" + +BuyDialog::DialogList BuyDialog::instances; + +BuyDialog::BuyDialog(int npcId): + Window(_("Buy")), + mNpcId(npcId), mMoney(0), mAmountItems(0), mMaxItems(0) +{ + setWindowName("Buy"); + //setupWindow->registerWindowForReset(this); + setResizable(true); + setCloseButton(true); + setMinWidth(260); + setMinHeight(230); + setDefaultSize(260, 230, ImageRect::CENTER); + + mShopItems = new ShopItems; + + mShopItemList = new ShopListBox(mShopItems, mShopItems); + mScrollArea = new ScrollArea(mShopItemList); + mScrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); + + mSlider = new Slider(1.0); + mQuantityLabel = new Label(strprintf("%d / %d", mAmountItems, mMaxItems)); + mQuantityLabel->setAlignment(gcn::Graphics::CENTER); + mMoneyLabel = new Label(strprintf(_("Price: %s / Total: %s"), + "", "")); + + // TRANSLATORS: This is a narrow symbol used to denote 'increasing'. + // You may change this symbol if your language uses another. + mIncreaseButton = new Button(_("+"), "inc", this); + // TRANSLATORS: This is a narrow symbol used to denote 'decreasing'. + // You may change this symbol if your language uses another. + mDecreaseButton = new Button(_("-"), "dec", this); + mBuyButton = new Button(_("Buy"), "buy", this); + mQuitButton = new Button(_("Quit"), "quit", this); + mAddMaxButton = new Button(_("Max"), "max", this); + + mDecreaseButton->adjustSize(); + mDecreaseButton->setWidth(mIncreaseButton->getWidth()); + + mIncreaseButton->setEnabled(false); + mDecreaseButton->setEnabled(false); + mBuyButton->setEnabled(false); + mSlider->setEnabled(false); + + mSlider->setActionEventId("slider"); + mSlider->addActionListener(this); + mShopItemList->addSelectionListener(this); + + ContainerPlacer place; + place = getPlacer(0, 0); + + place(0, 0, mScrollArea, 8, 5).setPadding(3); + place(0, 5, mDecreaseButton); + place(1, 5, mSlider, 3); + place(4, 5, mIncreaseButton); + place(5, 5, mQuantityLabel, 2); + place(7, 5, mAddMaxButton); + place(0, 6, mMoneyLabel, 8); + place(6, 7, mBuyButton); + place(7, 7, mQuitButton); + + Layout &layout = getLayout(); + layout.setRowHeight(0, Layout::AUTO_SET); + + center(); + loadWindowState(); + + instances.push_back(this); + setVisible(true); + + PlayerInfo::setBuySellState(BUYSELL_BUYING); +} + +BuyDialog::~BuyDialog() +{ + delete mShopItems; + + instances.remove(this); + + if (PlayerInfo::getBuySellState() == BUYSELL_BUYING) + PlayerInfo::setBuySellState(BUYSELL_NONE); +} + +void BuyDialog::setMoney(int amount) +{ + mMoney = amount; + mShopItemList->setPlayersMoney(amount); + + updateButtonsAndLabels(); +} + +void BuyDialog::reset() +{ + mShopItems->clear(); + mShopItemList->adjustSize(); + + // Reset previous selected items to prevent failing asserts + mShopItemList->setSelected(-1); + mSlider->setValue(0); + + setMoney(0); +} + +void BuyDialog::addItem(int id, int amount, int price) +{ + mShopItems->addItem(id, amount, price); + mShopItemList->adjustSize(); +} + +void BuyDialog::action(const gcn::ActionEvent &event) +{ + if (event.getId() == "quit") + { + close(); + return; + } + + int selectedItem = mShopItemList->getSelected(); + + // The following actions require a valid selection + if (selectedItem < 0 || + selectedItem >= (int) mShopItems->getNumberOfElements()) + { + return; + } + + if (event.getId() == "slider") + { + mAmountItems = (int) mSlider->getValue(); + updateButtonsAndLabels(); + } + else if (event.getId() == "inc" && mAmountItems < mMaxItems) + { + mAmountItems++; + mSlider->setValue(mAmountItems); + updateButtonsAndLabels(); + } + else if (event.getId() == "dec" && mAmountItems > 1) + { + mAmountItems--; + mSlider->setValue(mAmountItems); + updateButtonsAndLabels(); + } + else if (event.getId() == "max") + { + mAmountItems = mMaxItems; + mSlider->setValue(mAmountItems); + updateButtonsAndLabels(); + } + // TODO: Actually we'd have a bug elsewhere if this check for the number + // of items to be bought ever fails, Bertram removed the assertions, is + // there a better way to ensure this fails in an _obvious_ way in C++? + else if (event.getId() == "buy" && mAmountItems > 0 && + mAmountItems <= mMaxItems) + { + Net::getNpcHandler()->buyItem(mNpcId, + mShopItems->at(selectedItem)->getId(), + mAmountItems); + + // Update money and adjust the max number of items that can be bought + mMaxItems -= mAmountItems; + int price = mShopItems->at(selectedItem)->getPrice(); + if (price < 0) + price = 0; + setMoney(mMoney - mAmountItems * price); + valueChanged(gcn::SelectionEvent(mShopItemList)); + } +} + +void BuyDialog::valueChanged(const gcn::SelectionEvent &event) +{ + // Reset amount of items and update labels + mAmountItems = 1; + mSlider->setValue(1); + + updateButtonsAndLabels(); + mSlider->gcn::Slider::setScale(1, mMaxItems); +} + +void BuyDialog::mouseClicked(gcn::MouseEvent &mouseEvent) +{ + if (mouseEvent.getSource() == mShopItemList && + isDoubleClick(mShopItemList->getSelected())) + { + action(gcn::ActionEvent(mBuyButton, mBuyButton->getActionEventId())); + } +} + +void BuyDialog::updateButtonsAndLabels() +{ + const int selectedItem = mShopItemList->getSelected(); + int price = 0; + + if (selectedItem > -1) + { + int itemPrice = mShopItems->at(selectedItem)->getPrice(); + + // Calculate how many the player can afford + if (itemPrice > 0) + { + mMaxItems = mMoney / itemPrice; + } + else + { + // Let the player no more than 1 of them at a time, since it + // shouldn't be a permitted case. + mMaxItems = 1; + } + + if (mAmountItems > mMaxItems) + mAmountItems = mMaxItems; + + // Calculate price of pending purchase + price = mAmountItems * itemPrice; + } + else + { + mMaxItems = 0; + mAmountItems = 0; + } + + // Enable or disable buttons and slider + mIncreaseButton->setEnabled(mAmountItems < mMaxItems); + mDecreaseButton->setEnabled(mAmountItems > 1); + mBuyButton->setEnabled(mAmountItems > 0); + mSlider->setEnabled(mMaxItems > 1); + + // Update quantity and money labels + mQuantityLabel->setCaption(strprintf("%d / %d", mAmountItems, mMaxItems)); + mMoneyLabel->setCaption + (strprintf(_("Price: %s / Total: %s"), + Units::formatCurrency(price).c_str(), + Units::formatCurrency(mMoney - price).c_str())); +} + +void BuyDialog::setVisible(bool visible) +{ + Window::setVisible(visible); + + if (visible) + { + mShopItemList->requestFocus(); + } + else + { + scheduleDelete(); + } +} + +void BuyDialog::closeAll() +{ + DialogList::iterator it = instances.begin(); + DialogList::iterator it_end = instances.end(); + + for (; it != it_end; it++) + { + (*it)->close(); + } +} diff --git a/src/gui/buydialog.h b/src/gui/buydialog.h new file mode 100644 index 00000000..2ecf89e1 --- /dev/null +++ b/src/gui/buydialog.h @@ -0,0 +1,128 @@ +/* + * The Mana Client + * Copyright (C) 2004-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * + * This file is part of The Mana Client. + * + * 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, see . + */ + +#ifndef BUY_H +#define BUY_H + +#include "guichanfwd.h" + +#include "gui/widgets/window.h" + +#include +#include + +class ShopItems; +class ShopListBox; +class ListBox; + +/** + * The buy dialog. + * + * \ingroup Interface + */ +class BuyDialog : public Window, public gcn::ActionListener, + public gcn::SelectionListener +{ + public: + BuyDialog(int npcId); + + ~BuyDialog(); + + /** + * Resets the dialog, clearing shop inventory. + */ + void reset(); + + /** + * Sets the amount of available money. + */ + void setMoney(int amount); + + /** + * Adds an item to the shop inventory. + */ + void addItem(int id, int amount, int price); + + /** + * Called when receiving actions from the widgets. + */ + void action(const gcn::ActionEvent &event); + + /** + * Returns the number of items in the shop inventory. + */ + int getNumberOfElements(); + + /** + * Updates the labels according to the selected item. + */ + void valueChanged(const gcn::SelectionEvent &event); + + /** + * Allows for quick-buying by extending double-click events. + */ + void mouseClicked(gcn::MouseEvent &mouseEvent); + + /** + * Returns the name of item number i in the shop inventory. + */ + std::string getElementAt(int i); + + /** + * Updates the state of buttons and labels. + */ + void updateButtonsAndLabels(); + + /** + * Sets the visibility of this window. + */ + void setVisible(bool visible); + + /** + * Closes all instances. + */ + static void closeAll(); + + private: + typedef std::list DialogList; + static DialogList instances; + + int mNpcId; + + gcn::Button *mBuyButton; + gcn::Button *mQuitButton; + gcn::Button *mAddMaxButton; + gcn::Button *mIncreaseButton; + gcn::Button *mDecreaseButton; + ShopListBox *mShopItemList; + gcn::ScrollArea *mScrollArea; + gcn::Label *mMoneyLabel; + gcn::Label *mQuantityLabel; + gcn::Slider *mSlider; + + ShopItems *mShopItems; + + int mMoney; + int mAmountItems; + int mMaxItems; +}; + +#endif diff --git a/src/gui/buysell.cpp b/src/gui/buysell.cpp deleted file mode 100644 index 4419ffcc..00000000 --- a/src/gui/buysell.cpp +++ /dev/null @@ -1,119 +0,0 @@ -/* - * The Mana Client - * Copyright (C) 2004-2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers - * - * This file is part of The Mana Client. - * - * 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, see . - */ - -#include "buysell.h" - -#include "playerinfo.h" - -#include "gui/setup.h" - -#include "gui/widgets/button.h" - -#include "net/net.h" -#include "net/npchandler.h" - -#include "utils/gettext.h" - -BuySellDialog::DialogList BuySellDialog::instances; - -BuySellDialog::BuySellDialog(int npcId): - Window(_("Shop")), - mNpcId(npcId), - mBuyButton(0) -{ - setWindowName("BuySell"); - //setupWindow->registerWindowForReset(this); - setCloseButton(true); - - 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(gettext(*curBtn), *curBtn, this); - if (!mBuyButton) - mBuyButton = btn; // For focus request - btn->setPosition(x, y); - add(btn); - x += btn->getWidth() + 10; - } - mBuyButton->requestFocus(); - - setContentSize(x, 2 * y + mBuyButton->getHeight()); - - center(); - setDefaultSize(); - loadWindowState(); - - instances.push_back(this); - setVisible(true); - - PlayerInfo::setBuySellState(BUYSELL_CHOOSING); -} - -BuySellDialog::~BuySellDialog() -{ - instances.remove(this); - - if (PlayerInfo::getBuySellState() == BUYSELL_CHOOSING) - PlayerInfo::setBuySellState(BUYSELL_NONE); -} - -void BuySellDialog::setVisible(bool visible) -{ - Window::setVisible(visible); - - if (visible) - { - mBuyButton->requestFocus(); - } - else - { - scheduleDelete(); - } -} - -void BuySellDialog::action(const gcn::ActionEvent &event) -{ - if (event.getId() == "Buy") - { - Net::getNpcHandler()->buy(mNpcId); - } - else if (event.getId() == "Sell") - { - Net::getNpcHandler()->sell(mNpcId); - } - - close(); -} - -void BuySellDialog::closeAll() -{ - DialogList::iterator it = instances.begin(); - DialogList::iterator it_end = instances.end(); - - for (; it != it_end; it++) - { - (*it)->close(); - } -} diff --git a/src/gui/buysell.h b/src/gui/buysell.h deleted file mode 100644 index 3408821a..00000000 --- a/src/gui/buysell.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * The Mana Client - * Copyright (C) 2004-2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers - * - * This file is part of The Mana Client. - * - * 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, see . - */ - -#ifndef BUYSELL_H -#define BUYSELL_H - -#include "gui/widgets/window.h" - -#include - -/** - * A dialog to choose between buying or selling at a shop. - * - * \ingroup Interface - */ -class BuySellDialog : public Window, public gcn::ActionListener -{ - public: - /** - * Constructor. The action listener passed will receive "sell", "buy" - * or "cancel" events when the respective buttons are pressed. - * - * @see Window::Window - */ - BuySellDialog(int npcId); - - ~BuySellDialog(); - - void setVisible(bool visible); - - /** - * Called when receiving actions from the widgets. - */ - void action(const gcn::ActionEvent &event); - - /** - * Closes all instances. - */ - static void closeAll(); - - private: - typedef std::list DialogList; - static DialogList instances; - - int mNpcId; - gcn::Button *mBuyButton; -}; - -#endif diff --git a/src/gui/buyselldialog.cpp b/src/gui/buyselldialog.cpp new file mode 100644 index 00000000..a0248650 --- /dev/null +++ b/src/gui/buyselldialog.cpp @@ -0,0 +1,119 @@ +/* + * The Mana Client + * Copyright (C) 2004-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * + * This file is part of The Mana Client. + * + * 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, see . + */ + +#include "buyselldialog.h" + +#include "playerinfo.h" + +#include "gui/setup.h" + +#include "gui/widgets/button.h" + +#include "net/net.h" +#include "net/npchandler.h" + +#include "utils/gettext.h" + +BuySellDialog::DialogList BuySellDialog::instances; + +BuySellDialog::BuySellDialog(int npcId): + Window(_("Shop")), + mNpcId(npcId), + mBuyButton(0) +{ + setWindowName("BuySell"); + //setupWindow->registerWindowForReset(this); + setCloseButton(true); + + 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(gettext(*curBtn), *curBtn, this); + if (!mBuyButton) + mBuyButton = btn; // For focus request + btn->setPosition(x, y); + add(btn); + x += btn->getWidth() + 10; + } + mBuyButton->requestFocus(); + + setContentSize(x, 2 * y + mBuyButton->getHeight()); + + center(); + setDefaultSize(); + loadWindowState(); + + instances.push_back(this); + setVisible(true); + + PlayerInfo::setBuySellState(BUYSELL_CHOOSING); +} + +BuySellDialog::~BuySellDialog() +{ + instances.remove(this); + + if (PlayerInfo::getBuySellState() == BUYSELL_CHOOSING) + PlayerInfo::setBuySellState(BUYSELL_NONE); +} + +void BuySellDialog::setVisible(bool visible) +{ + Window::setVisible(visible); + + if (visible) + { + mBuyButton->requestFocus(); + } + else + { + scheduleDelete(); + } +} + +void BuySellDialog::action(const gcn::ActionEvent &event) +{ + if (event.getId() == "Buy") + { + Net::getNpcHandler()->buy(mNpcId); + } + else if (event.getId() == "Sell") + { + Net::getNpcHandler()->sell(mNpcId); + } + + close(); +} + +void BuySellDialog::closeAll() +{ + DialogList::iterator it = instances.begin(); + DialogList::iterator it_end = instances.end(); + + for (; it != it_end; it++) + { + (*it)->close(); + } +} diff --git a/src/gui/buyselldialog.h b/src/gui/buyselldialog.h new file mode 100644 index 00000000..3408821a --- /dev/null +++ b/src/gui/buyselldialog.h @@ -0,0 +1,67 @@ +/* + * The Mana Client + * Copyright (C) 2004-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * + * This file is part of The Mana Client. + * + * 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, see . + */ + +#ifndef BUYSELL_H +#define BUYSELL_H + +#include "gui/widgets/window.h" + +#include + +/** + * A dialog to choose between buying or selling at a shop. + * + * \ingroup Interface + */ +class BuySellDialog : public Window, public gcn::ActionListener +{ + public: + /** + * Constructor. The action listener passed will receive "sell", "buy" + * or "cancel" events when the respective buttons are pressed. + * + * @see Window::Window + */ + BuySellDialog(int npcId); + + ~BuySellDialog(); + + void setVisible(bool visible); + + /** + * Called when receiving actions from the widgets. + */ + void action(const gcn::ActionEvent &event); + + /** + * Closes all instances. + */ + static void closeAll(); + + private: + typedef std::list DialogList; + static DialogList instances; + + int mNpcId; + gcn::Button *mBuyButton; +}; + +#endif diff --git a/src/gui/chat.cpp b/src/gui/chat.cpp deleted file mode 100644 index 92386e76..00000000 --- a/src/gui/chat.cpp +++ /dev/null @@ -1,543 +0,0 @@ -/* - * The Mana Client - * Copyright (C) 2004-2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers - * - * This file is part of The Mana Client. - * - * 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, see . - */ - -#include "chat.h" - -#include "actorspritemanager.h" -#include "channel.h" -#include "channelmanager.h" -#include "configuration.h" -#include "localplayer.h" -#include "party.h" -#include "playerrelations.h" - -#include "gui/recorder.h" -#include "gui/setup.h" -#include "gui/sdlinput.h" - -#include "gui/widgets/channeltab.h" -#include "gui/widgets/chattab.h" -#include "gui/widgets/itemlinkhandler.h" -#include "gui/widgets/scrollarea.h" -#include "gui/widgets/tabbedarea.h" -#include "gui/widgets/textfield.h" -#include "gui/widgets/whispertab.h" - -#include "net/chathandler.h" -#include "net/net.h" - -#include "utils/dtor.h" -#include "utils/gettext.h" -#include "utils/stringutils.h" - -#include -#include - -#include - -/** - * The chat input hides when it loses focus. It is also invisible by default. - */ -class ChatInput : public TextField, public gcn::FocusListener -{ - public: - ChatInput(): - TextField("", false) - { - setVisible(false); - addFocusListener(this); - } - - /** - * Called if the chat input loses focus. It will set itself to - * invisible as result. - */ - void focusLost(const gcn::Event &event) - { - setVisible(false); - } -}; - -class ChatAutoComplete : public AutoCompleteLister -{ - void getAutoCompleteList(std::vector &list) const - { - ChatTab *tab = static_cast(chatWindow->mChatTabs - ->getSelectedTab()); - - return tab->getAutoCompleteList(list); - } -}; - -ChatWindow::ChatWindow(): - Window(_("Chat")), - mHistory(new TextHistory()), - mAutoComplete(new ChatAutoComplete), - mTmpVisible(false) -{ - listen(Event::ChatChannel); - listen(Event::NoticesChannel); - - setWindowName("Chat"); - - setupWindow->registerWindowForReset(this); - - // no title presented, title bar is padding so window can be moved. - gcn::Window::setTitleBarHeight(gcn::Window::getPadding() + 4); - setShowTitle(false); - setResizable(true); - setDefaultVisible(true); - setSaveVisible(true); - setDefaultSize(600, 123, ImageRect::LOWER_LEFT); - setMinWidth(150); - setMinHeight(90); - - mItemLinkHandler = new ItemLinkHandler; - - mChatInput = new ChatInput; - mChatInput->setActionEventId("chatinput"); - mChatInput->addActionListener(this); - - mChatTabs = new TabbedArea; - - place(0, 0, mChatTabs, 3, 3); - place(0, 3, mChatInput, 3); - - loadWindowState(); - - mChatInput->setHistory(mHistory); - mChatInput->setAutoComplete(mAutoComplete); - - mReturnToggles = config.getBoolValue("ReturnToggles"); - - mRecorder = new Recorder(this); -} - -ChatWindow::~ChatWindow() -{ - config.setValue("ReturnToggles", mReturnToggles); - delete mRecorder; - removeAllWhispers(); - delete mItemLinkHandler; - delete mHistory; - delete mAutoComplete; -} - -void ChatWindow::resetToDefaultSize() -{ - mRecorder->resetToDefaultSize(); - Window::resetToDefaultSize(); -} - -ChatTab *ChatWindow::getFocused() const -{ - return static_cast(mChatTabs->getSelectedTab()); -} - -void ChatWindow::clearTab(ChatTab *tab) -{ - if (tab) - tab->clearText(); -} - -void ChatWindow::clearTab() -{ - clearTab(getFocused()); -} - -void ChatWindow::prevTab() -{ - int tab = mChatTabs->getSelectedTabIndex(); - - if (tab == 0) - tab = mChatTabs->getNumberOfTabs(); - tab--; - - mChatTabs->setSelectedTab(tab); -} - -void ChatWindow::nextTab() -{ - int tab = mChatTabs->getSelectedTabIndex(); - - tab++; - if (tab == mChatTabs->getNumberOfTabs()) - tab = 0; - - mChatTabs->setSelectedTab(tab); -} - -void ChatWindow::action(const gcn::ActionEvent &event) -{ - if (event.getId() == "chatinput") - { - std::string message = mChatInput->getText(); - - if (!message.empty()) - { - // Send the message to the server - chatInput(message); - - // Clear the text from the chat input - mChatInput->setText(""); - } - - 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); - } - } -} - -bool ChatWindow::requestChatFocus() -{ - // Make sure chatWindow is visible - if (!isVisible()) - { - setVisible(true); - - /* - * This is used to hide chatWindow after sending the message. There is - * a trick here, because setVisible will set mTmpVisible to false, you - * have to put this sentence *after* setVisible, not before it - */ - mTmpVisible = true; - } - - // Don't do anything else if the input is already visible and has focus - if (mChatInput->isVisible() && mChatInput->isFocused()) - return false; - - // Give focus to the chat input - mChatInput->setVisible(true); - mChatInput->requestFocus(); - return true; -} - -bool ChatWindow::isInputFocused() const -{ - return mChatInput->isFocused(); -} - -void ChatWindow::removeTab(ChatTab *tab) -{ - mChatTabs->removeTab(tab); -} - -void ChatWindow::addTab(ChatTab *tab) -{ - // Make sure we don't end up with duplicates in the gui - // TODO - - mChatTabs->addTab(tab, tab->mScrollArea); - - // Update UI - logic(); -} - -void ChatWindow::removeWhisper(const std::string &nick) -{ - std::string tempNick = nick; - toLower(tempNick); - mWhispers.erase(tempNick); -} - -void ChatWindow::removeAllWhispers() -{ - TabMap::iterator iter; - std::list tabs; - - for (iter = mWhispers.begin(); iter != mWhispers.end(); ++iter) - { - tabs.push_back(iter->second); - } - - for (std::list::iterator it = tabs.begin(); - it != tabs.end(); ++it) - { - delete *it; - } - - mWhispers.clear(); -} - -void ChatWindow::chatInput(const std::string &msg) -{ - ChatTab *tab = getFocused(); - tab->chatInput(msg); -} - -void ChatWindow::doPresent() -{ - const ActorSprites &actors = actorSpriteManager->getAll(); - std::string response = ""; - int playercount = 0; - - for (ActorSpritesConstIterator it = actors.begin(), it_end = actors.end(); - it != it_end; it++) - { - if ((*it)->getType() == ActorSprite::PLAYER) - { - if (!response.empty()) - { - response += ", "; - } - response += static_cast(*it)->getName(); - ++playercount; - } - } - - std::string log = strprintf(_("Present: %s; %d players are present."), - response.c_str(), playercount); - - if (mRecorder->isRecording()) - { - // Get the current system time - time_t t; - time(&t); - - // Format the time string properly - std::ostringstream 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() + log); - getFocused()->chatLog(_("Attendance written to record log."), - BY_SERVER, true); - } - else - { - getFocused()->chatLog(log, BY_SERVER); - } -} - -void ChatWindow::scroll(int amount) -{ - if (!isVisible()) - return; - - ChatTab *tab = getFocused(); - if (tab) - tab->scroll(amount); -} - -void ChatWindow::mousePressed(gcn::MouseEvent &event) -{ - Window::mousePressed(event); - - if (event.isConsumed()) - return; - - mMoved = event.getY() <= getFocused()->getHeight(); - mDragOffsetX = event.getX(); - mDragOffsetY = event.getY(); - -} - -void ChatWindow::mouseDragged(gcn::MouseEvent &event) -{ - Window::mouseDragged(event); - - if (event.isConsumed()) - return; - - if (isMovable() && mMoved) - { - int newX = std::max(0, getX() + event.getX() - mDragOffsetX); - int newY = std::max(0, getY() + event.getY() - mDragOffsetY); - newX = std::min(graphics->getWidth() - getWidth(), newX); - newY = std::min(graphics->getHeight() - getHeight(), newY); - setPosition(newX, newY); - } -} - -void ChatWindow::event(Event::Channel channel, const Event &event) -{ - if (channel == Event::NoticesChannel) - { - if (event.getType() == Event::ServerNotice) - localChatTab->chatLog(event.getString("message"), BY_SERVER); - } - else if (channel == Event::ChatChannel) - { - if (event.getType() == Event::Whisper) - { - whisper(event.getString("nick"), event.getString("message")); - } - else if (event.getType() == Event::WhisperError) - { - whisper(event.getString("nick"), - event.getString("error"), BY_SERVER); - } - else if (event.getType() == Event::Player) - { - localChatTab->chatLog(event.getString("message"), BY_PLAYER); - } - else if (event.getType() == Event::Announcement) - { - // Show on local tab - localChatTab->chatLog(event.getString("message"), BY_GM); - // Spread over channels - for (std::list::iterator - it = channelManager->mChannels.begin(), - it_end = channelManager->mChannels.end(); - it != it_end; ++it) - { - if (*it) - (*it)->getTab()->chatLog(event.getString("message"), BY_GM); - } - // Spread over whispers - for (TabMap::const_iterator it = mWhispers.begin(), - it_end = mWhispers.end(); it != it_end; ++it) - { - if (it->second) - it->second->chatLog(event.getString("message"), BY_GM); - } - } - else if (event.getType() == Event::Being) - { - if (event.getInt("permissions") & PlayerRelation::SPEECH_LOG) - localChatTab->chatLog(event.getString("message"), BY_OTHER); - } - } -} - -void ChatWindow::addInputText(const std::string &text) -{ - const int caretPos = mChatInput->getCaretPosition(); - const std::string inputText = mChatInput->getText(); - - std::ostringstream ss; - ss << inputText.substr(0, caretPos) << text << " "; - ss << inputText.substr(caretPos); - - mChatInput->setText(ss.str()); - mChatInput->setCaretPosition(caretPos + text.length() + 1); - requestChatFocus(); -} - -void ChatWindow::addItemText(const std::string &item) -{ - std::ostringstream text; - text << "[" << item << "]"; - addInputText(text.str()); -} - -void ChatWindow::setVisible(bool isVisible) -{ - Window::setVisible(isVisible); - - /* - * For whatever reason, if setVisible is called, the mTmpVisible effect - * should be disabled. - */ - mTmpVisible = false; -} - -void ChatWindow::setRecordingFile(const std::string &msg) -{ - mRecorder->setRecordingFile(msg); -} - -void ChatWindow::whisper(const std::string &nick, - const std::string &mes, Own own) -{ - if (mes.empty()) - return; - - std::string playerName = local_player->getName(); - std::string tempNick = nick; - - toLower(playerName); - toLower(tempNick); - - if (tempNick.compare(playerName) == 0) - return; - - ChatTab *tab = 0; - TabMap::const_iterator i = mWhispers.find(tempNick); - - if (i != mWhispers.end()) - tab = i->second; - else if (config.getBoolValue("whispertab")) - tab = addWhisperTab(nick); - - if (tab) - { - if (own == BY_PLAYER) - { - tab->chatInput(mes); - } - else if (own == BY_SERVER) - { - tab->chatLog(mes); - } - else - { - tab->chatLog(nick, mes); - local_player->afkRespond(tab, nick); - } - } - else - { - if (own == BY_PLAYER) - { - Net::getChatHandler()->privateMessage(nick, mes); - - localChatTab->chatLog(strprintf(_("Whispering to %s: %s"), - nick.c_str(), mes.c_str()), BY_PLAYER); - } - else - { - localChatTab->chatLog(nick + " : " + mes, ACT_WHISPER, false); - } - } -} - -ChatTab *ChatWindow::addWhisperTab(const std::string &nick, bool switchTo) -{ - std::string playerName = local_player->getName(); - std::string tempNick = nick; - - toLower(playerName); - toLower(tempNick); - - if (mWhispers.find(tempNick) != mWhispers.end() - || tempNick.compare(playerName) == 0) - return NULL; - - ChatTab *ret = new WhisperTab(nick); - mWhispers[tempNick] = ret; - - if (switchTo) - mChatTabs->setSelectedTab(ret); - - return ret; -} diff --git a/src/gui/chat.h b/src/gui/chat.h deleted file mode 100644 index c6acf532..00000000 --- a/src/gui/chat.h +++ /dev/null @@ -1,227 +0,0 @@ -/* - * The Mana Client - * Copyright (C) 2004-2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers - * - * This file is part of The Mana Client. - * - * 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, see . - */ - -#ifndef CHAT_H -#define CHAT_H - -#include "eventlistener.h" - -#include "gui/widgets/window.h" -#include "gui/widgets/textfield.h" - -#include -#include -#include -#include - -#include -#include -#include -#include - -class BrowserBox; -class ChatTab; -class Channel; -class ChatInput; -class Recorder; -class ScrollArea; -class TabbedArea; -class ItemLinkHandler; -class Tab; -class WhisperTab; - -#define DEFAULT_CHAT_WINDOW_SCROLL 7 // 1 means `1/8th of the window size'. - -enum Own -{ - BY_GM, - BY_PLAYER, - BY_OTHER, - BY_SERVER, - BY_CHANNEL, - ACT_WHISPER, // getting whispered at - ACT_IS, // equivalent to "/me" on IRC - BY_LOGGER -}; - -/** One item in the chat log */ -struct CHATLOG -{ - std::string nick; - std::string text; - Own own; -}; - -/** - * The chat window. - * - * \ingroup Interface - */ -class ChatWindow : public Window, - public gcn::ActionListener, - public EventListener -{ - public: - ChatWindow(); - - /** - * Destructor: used to write back values to the config file - */ - ~ChatWindow(); - - /** - * Reset the chat window and recorder window attached to it to their - * default positions. - */ - void resetToDefaultSize(); - - /** - * Gets the focused tab. - */ - ChatTab *getFocused() const; - - /** - * Clear the given tab. - */ - void clearTab(ChatTab *tab); - - /** - * Clear the current tab. - */ - void clearTab(); - - /** - * Switch to the previous tab in order - */ - void prevTab(); - - /** - * Switch to the next tab in order - */ - void nextTab(); - - /** - * Performs action. - */ - void action(const gcn::ActionEvent &event); - - /** - * Request focus for typing chat message. - * - * \returns true if the input was shown - * false otherwise - */ - bool requestChatFocus(); - - /** - * Checks whether ChatWindow is Focused or not. - */ - bool isInputFocused() const; - - /** - * Passes the text to the current tab as input - * - * @param msg The message text which is to be sent. - */ - void chatInput(const std::string &msg); - - /** Add the given text to the chat input. */ - void addInputText(const std::string &text); - - /** Called to add item to chat */ - void addItemText(const std::string &item); - - /** Override to reset mTmpVisible */ - void setVisible(bool visible); - - void mousePressed(gcn::MouseEvent &event); - void mouseDragged(gcn::MouseEvent &event); - - void event(Event::Channel channel, const Event &event); - - /** - * 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); - - /** - * Sets the file being recorded to - * - * @param msg The file to write out to. If null, then stop recording. - */ - void setRecordingFile(const std::string &msg); - - bool getReturnTogglesChat() const { return mReturnToggles; } - void setReturnTogglesChat(bool toggles) { mReturnToggles = toggles; } - - void doPresent(); - - void whisper(const std::string &nick, const std::string &mes, - Own own = BY_OTHER); - - ChatTab *addWhisperTab(const std::string &nick, bool switchTo = false); - - protected: - friend class ChatTab; - friend class WhisperTab; - friend class ChatAutoComplete; - - /** Remove the given tab from the window */ - void removeTab(ChatTab *tab); - - /** Add the tab to the window */ - void addTab(ChatTab *tab); - - void removeWhisper(const std::string &nick); - - void removeAllWhispers(); - - /** Used for showing item popup on clicking links **/ - ItemLinkHandler *mItemLinkHandler; - Recorder *mRecorder; - - /** Input box for typing chat messages. */ - ChatInput *mChatInput; - - TextHistory *mHistory; - AutoCompleteLister *mAutoComplete; - - private: - bool mTmpVisible; - - /** Tabbed area for holding each channel. */ - TabbedArea *mChatTabs; - - typedef std::map TabMap; - /** Manage whisper tabs */ - TabMap mWhispers; - - bool mReturnToggles; /**< Marks whether toggles the chat log - or not */ -}; - -extern ChatWindow *chatWindow; - -#endif diff --git a/src/gui/chatwindow.cpp b/src/gui/chatwindow.cpp new file mode 100644 index 00000000..95323387 --- /dev/null +++ b/src/gui/chatwindow.cpp @@ -0,0 +1,543 @@ +/* + * The Mana Client + * Copyright (C) 2004-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * + * This file is part of The Mana Client. + * + * 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, see . + */ + +#include "chatwindow.h" + +#include "actorspritemanager.h" +#include "channel.h" +#include "channelmanager.h" +#include "configuration.h" +#include "localplayer.h" +#include "party.h" +#include "playerrelations.h" + +#include "gui/recorder.h" +#include "gui/setup.h" +#include "gui/sdlinput.h" + +#include "gui/widgets/channeltab.h" +#include "gui/widgets/chattab.h" +#include "gui/widgets/itemlinkhandler.h" +#include "gui/widgets/scrollarea.h" +#include "gui/widgets/tabbedarea.h" +#include "gui/widgets/textfield.h" +#include "gui/widgets/whispertab.h" + +#include "net/chathandler.h" +#include "net/net.h" + +#include "utils/dtor.h" +#include "utils/gettext.h" +#include "utils/stringutils.h" + +#include +#include + +#include + +/** + * The chat input hides when it loses focus. It is also invisible by default. + */ +class ChatInput : public TextField, public gcn::FocusListener +{ + public: + ChatInput(): + TextField("", false) + { + setVisible(false); + addFocusListener(this); + } + + /** + * Called if the chat input loses focus. It will set itself to + * invisible as result. + */ + void focusLost(const gcn::Event &event) + { + setVisible(false); + } +}; + +class ChatAutoComplete : public AutoCompleteLister +{ + void getAutoCompleteList(std::vector &list) const + { + ChatTab *tab = static_cast(chatWindow->mChatTabs + ->getSelectedTab()); + + return tab->getAutoCompleteList(list); + } +}; + +ChatWindow::ChatWindow(): + Window(_("Chat")), + mHistory(new TextHistory()), + mAutoComplete(new ChatAutoComplete), + mTmpVisible(false) +{ + listen(Event::ChatChannel); + listen(Event::NoticesChannel); + + setWindowName("Chat"); + + setupWindow->registerWindowForReset(this); + + // no title presented, title bar is padding so window can be moved. + gcn::Window::setTitleBarHeight(gcn::Window::getPadding() + 4); + setShowTitle(false); + setResizable(true); + setDefaultVisible(true); + setSaveVisible(true); + setDefaultSize(600, 123, ImageRect::LOWER_LEFT); + setMinWidth(150); + setMinHeight(90); + + mItemLinkHandler = new ItemLinkHandler; + + mChatInput = new ChatInput; + mChatInput->setActionEventId("chatinput"); + mChatInput->addActionListener(this); + + mChatTabs = new TabbedArea; + + place(0, 0, mChatTabs, 3, 3); + place(0, 3, mChatInput, 3); + + loadWindowState(); + + mChatInput->setHistory(mHistory); + mChatInput->setAutoComplete(mAutoComplete); + + mReturnToggles = config.getBoolValue("ReturnToggles"); + + mRecorder = new Recorder(this); +} + +ChatWindow::~ChatWindow() +{ + config.setValue("ReturnToggles", mReturnToggles); + delete mRecorder; + removeAllWhispers(); + delete mItemLinkHandler; + delete mHistory; + delete mAutoComplete; +} + +void ChatWindow::resetToDefaultSize() +{ + mRecorder->resetToDefaultSize(); + Window::resetToDefaultSize(); +} + +ChatTab *ChatWindow::getFocused() const +{ + return static_cast(mChatTabs->getSelectedTab()); +} + +void ChatWindow::clearTab(ChatTab *tab) +{ + if (tab) + tab->clearText(); +} + +void ChatWindow::clearTab() +{ + clearTab(getFocused()); +} + +void ChatWindow::prevTab() +{ + int tab = mChatTabs->getSelectedTabIndex(); + + if (tab == 0) + tab = mChatTabs->getNumberOfTabs(); + tab--; + + mChatTabs->setSelectedTab(tab); +} + +void ChatWindow::nextTab() +{ + int tab = mChatTabs->getSelectedTabIndex(); + + tab++; + if (tab == mChatTabs->getNumberOfTabs()) + tab = 0; + + mChatTabs->setSelectedTab(tab); +} + +void ChatWindow::action(const gcn::ActionEvent &event) +{ + if (event.getId() == "chatinput") + { + std::string message = mChatInput->getText(); + + if (!message.empty()) + { + // Send the message to the server + chatInput(message); + + // Clear the text from the chat input + mChatInput->setText(""); + } + + 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); + } + } +} + +bool ChatWindow::requestChatFocus() +{ + // Make sure chatWindow is visible + if (!isVisible()) + { + setVisible(true); + + /* + * This is used to hide chatWindow after sending the message. There is + * a trick here, because setVisible will set mTmpVisible to false, you + * have to put this sentence *after* setVisible, not before it + */ + mTmpVisible = true; + } + + // Don't do anything else if the input is already visible and has focus + if (mChatInput->isVisible() && mChatInput->isFocused()) + return false; + + // Give focus to the chat input + mChatInput->setVisible(true); + mChatInput->requestFocus(); + return true; +} + +bool ChatWindow::isInputFocused() const +{ + return mChatInput->isFocused(); +} + +void ChatWindow::removeTab(ChatTab *tab) +{ + mChatTabs->removeTab(tab); +} + +void ChatWindow::addTab(ChatTab *tab) +{ + // Make sure we don't end up with duplicates in the gui + // TODO + + mChatTabs->addTab(tab, tab->mScrollArea); + + // Update UI + logic(); +} + +void ChatWindow::removeWhisper(const std::string &nick) +{ + std::string tempNick = nick; + toLower(tempNick); + mWhispers.erase(tempNick); +} + +void ChatWindow::removeAllWhispers() +{ + TabMap::iterator iter; + std::list tabs; + + for (iter = mWhispers.begin(); iter != mWhispers.end(); ++iter) + { + tabs.push_back(iter->second); + } + + for (std::list::iterator it = tabs.begin(); + it != tabs.end(); ++it) + { + delete *it; + } + + mWhispers.clear(); +} + +void ChatWindow::chatInput(const std::string &msg) +{ + ChatTab *tab = getFocused(); + tab->chatInput(msg); +} + +void ChatWindow::doPresent() +{ + const ActorSprites &actors = actorSpriteManager->getAll(); + std::string response = ""; + int playercount = 0; + + for (ActorSpritesConstIterator it = actors.begin(), it_end = actors.end(); + it != it_end; it++) + { + if ((*it)->getType() == ActorSprite::PLAYER) + { + if (!response.empty()) + { + response += ", "; + } + response += static_cast(*it)->getName(); + ++playercount; + } + } + + std::string log = strprintf(_("Present: %s; %d players are present."), + response.c_str(), playercount); + + if (mRecorder->isRecording()) + { + // Get the current system time + time_t t; + time(&t); + + // Format the time string properly + std::ostringstream 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() + log); + getFocused()->chatLog(_("Attendance written to record log."), + BY_SERVER, true); + } + else + { + getFocused()->chatLog(log, BY_SERVER); + } +} + +void ChatWindow::scroll(int amount) +{ + if (!isVisible()) + return; + + ChatTab *tab = getFocused(); + if (tab) + tab->scroll(amount); +} + +void ChatWindow::mousePressed(gcn::MouseEvent &event) +{ + Window::mousePressed(event); + + if (event.isConsumed()) + return; + + mMoved = event.getY() <= getFocused()->getHeight(); + mDragOffsetX = event.getX(); + mDragOffsetY = event.getY(); + +} + +void ChatWindow::mouseDragged(gcn::MouseEvent &event) +{ + Window::mouseDragged(event); + + if (event.isConsumed()) + return; + + if (isMovable() && mMoved) + { + int newX = std::max(0, getX() + event.getX() - mDragOffsetX); + int newY = std::max(0, getY() + event.getY() - mDragOffsetY); + newX = std::min(graphics->getWidth() - getWidth(), newX); + newY = std::min(graphics->getHeight() - getHeight(), newY); + setPosition(newX, newY); + } +} + +void ChatWindow::event(Event::Channel channel, const Event &event) +{ + if (channel == Event::NoticesChannel) + { + if (event.getType() == Event::ServerNotice) + localChatTab->chatLog(event.getString("message"), BY_SERVER); + } + else if (channel == Event::ChatChannel) + { + if (event.getType() == Event::Whisper) + { + whisper(event.getString("nick"), event.getString("message")); + } + else if (event.getType() == Event::WhisperError) + { + whisper(event.getString("nick"), + event.getString("error"), BY_SERVER); + } + else if (event.getType() == Event::Player) + { + localChatTab->chatLog(event.getString("message"), BY_PLAYER); + } + else if (event.getType() == Event::Announcement) + { + // Show on local tab + localChatTab->chatLog(event.getString("message"), BY_GM); + // Spread over channels + for (std::list::iterator + it = channelManager->mChannels.begin(), + it_end = channelManager->mChannels.end(); + it != it_end; ++it) + { + if (*it) + (*it)->getTab()->chatLog(event.getString("message"), BY_GM); + } + // Spread over whispers + for (TabMap::const_iterator it = mWhispers.begin(), + it_end = mWhispers.end(); it != it_end; ++it) + { + if (it->second) + it->second->chatLog(event.getString("message"), BY_GM); + } + } + else if (event.getType() == Event::Being) + { + if (event.getInt("permissions") & PlayerRelation::SPEECH_LOG) + localChatTab->chatLog(event.getString("message"), BY_OTHER); + } + } +} + +void ChatWindow::addInputText(const std::string &text) +{ + const int caretPos = mChatInput->getCaretPosition(); + const std::string inputText = mChatInput->getText(); + + std::ostringstream ss; + ss << inputText.substr(0, caretPos) << text << " "; + ss << inputText.substr(caretPos); + + mChatInput->setText(ss.str()); + mChatInput->setCaretPosition(caretPos + text.length() + 1); + requestChatFocus(); +} + +void ChatWindow::addItemText(const std::string &item) +{ + std::ostringstream text; + text << "[" << item << "]"; + addInputText(text.str()); +} + +void ChatWindow::setVisible(bool isVisible) +{ + Window::setVisible(isVisible); + + /* + * For whatever reason, if setVisible is called, the mTmpVisible effect + * should be disabled. + */ + mTmpVisible = false; +} + +void ChatWindow::setRecordingFile(const std::string &msg) +{ + mRecorder->setRecordingFile(msg); +} + +void ChatWindow::whisper(const std::string &nick, + const std::string &mes, Own own) +{ + if (mes.empty()) + return; + + std::string playerName = local_player->getName(); + std::string tempNick = nick; + + toLower(playerName); + toLower(tempNick); + + if (tempNick.compare(playerName) == 0) + return; + + ChatTab *tab = 0; + TabMap::const_iterator i = mWhispers.find(tempNick); + + if (i != mWhispers.end()) + tab = i->second; + else if (config.getBoolValue("whispertab")) + tab = addWhisperTab(nick); + + if (tab) + { + if (own == BY_PLAYER) + { + tab->chatInput(mes); + } + else if (own == BY_SERVER) + { + tab->chatLog(mes); + } + else + { + tab->chatLog(nick, mes); + local_player->afkRespond(tab, nick); + } + } + else + { + if (own == BY_PLAYER) + { + Net::getChatHandler()->privateMessage(nick, mes); + + localChatTab->chatLog(strprintf(_("Whispering to %s: %s"), + nick.c_str(), mes.c_str()), BY_PLAYER); + } + else + { + localChatTab->chatLog(nick + " : " + mes, ACT_WHISPER, false); + } + } +} + +ChatTab *ChatWindow::addWhisperTab(const std::string &nick, bool switchTo) +{ + std::string playerName = local_player->getName(); + std::string tempNick = nick; + + toLower(playerName); + toLower(tempNick); + + if (mWhispers.find(tempNick) != mWhispers.end() + || tempNick.compare(playerName) == 0) + return NULL; + + ChatTab *ret = new WhisperTab(nick); + mWhispers[tempNick] = ret; + + if (switchTo) + mChatTabs->setSelectedTab(ret); + + return ret; +} diff --git a/src/gui/chatwindow.h b/src/gui/chatwindow.h new file mode 100644 index 00000000..c6acf532 --- /dev/null +++ b/src/gui/chatwindow.h @@ -0,0 +1,227 @@ +/* + * The Mana Client + * Copyright (C) 2004-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * + * This file is part of The Mana Client. + * + * 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, see . + */ + +#ifndef CHAT_H +#define CHAT_H + +#include "eventlistener.h" + +#include "gui/widgets/window.h" +#include "gui/widgets/textfield.h" + +#include +#include +#include +#include + +#include +#include +#include +#include + +class BrowserBox; +class ChatTab; +class Channel; +class ChatInput; +class Recorder; +class ScrollArea; +class TabbedArea; +class ItemLinkHandler; +class Tab; +class WhisperTab; + +#define DEFAULT_CHAT_WINDOW_SCROLL 7 // 1 means `1/8th of the window size'. + +enum Own +{ + BY_GM, + BY_PLAYER, + BY_OTHER, + BY_SERVER, + BY_CHANNEL, + ACT_WHISPER, // getting whispered at + ACT_IS, // equivalent to "/me" on IRC + BY_LOGGER +}; + +/** One item in the chat log */ +struct CHATLOG +{ + std::string nick; + std::string text; + Own own; +}; + +/** + * The chat window. + * + * \ingroup Interface + */ +class ChatWindow : public Window, + public gcn::ActionListener, + public EventListener +{ + public: + ChatWindow(); + + /** + * Destructor: used to write back values to the config file + */ + ~ChatWindow(); + + /** + * Reset the chat window and recorder window attached to it to their + * default positions. + */ + void resetToDefaultSize(); + + /** + * Gets the focused tab. + */ + ChatTab *getFocused() const; + + /** + * Clear the given tab. + */ + void clearTab(ChatTab *tab); + + /** + * Clear the current tab. + */ + void clearTab(); + + /** + * Switch to the previous tab in order + */ + void prevTab(); + + /** + * Switch to the next tab in order + */ + void nextTab(); + + /** + * Performs action. + */ + void action(const gcn::ActionEvent &event); + + /** + * Request focus for typing chat message. + * + * \returns true if the input was shown + * false otherwise + */ + bool requestChatFocus(); + + /** + * Checks whether ChatWindow is Focused or not. + */ + bool isInputFocused() const; + + /** + * Passes the text to the current tab as input + * + * @param msg The message text which is to be sent. + */ + void chatInput(const std::string &msg); + + /** Add the given text to the chat input. */ + void addInputText(const std::string &text); + + /** Called to add item to chat */ + void addItemText(const std::string &item); + + /** Override to reset mTmpVisible */ + void setVisible(bool visible); + + void mousePressed(gcn::MouseEvent &event); + void mouseDragged(gcn::MouseEvent &event); + + void event(Event::Channel channel, const Event &event); + + /** + * 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); + + /** + * Sets the file being recorded to + * + * @param msg The file to write out to. If null, then stop recording. + */ + void setRecordingFile(const std::string &msg); + + bool getReturnTogglesChat() const { return mReturnToggles; } + void setReturnTogglesChat(bool toggles) { mReturnToggles = toggles; } + + void doPresent(); + + void whisper(const std::string &nick, const std::string &mes, + Own own = BY_OTHER); + + ChatTab *addWhisperTab(const std::string &nick, bool switchTo = false); + + protected: + friend class ChatTab; + friend class WhisperTab; + friend class ChatAutoComplete; + + /** Remove the given tab from the window */ + void removeTab(ChatTab *tab); + + /** Add the tab to the window */ + void addTab(ChatTab *tab); + + void removeWhisper(const std::string &nick); + + void removeAllWhispers(); + + /** Used for showing item popup on clicking links **/ + ItemLinkHandler *mItemLinkHandler; + Recorder *mRecorder; + + /** Input box for typing chat messages. */ + ChatInput *mChatInput; + + TextHistory *mHistory; + AutoCompleteLister *mAutoComplete; + + private: + bool mTmpVisible; + + /** Tabbed area for holding each channel. */ + TabbedArea *mChatTabs; + + typedef std::map TabMap; + /** Manage whisper tabs */ + TabMap mWhispers; + + bool mReturnToggles; /**< Marks whether toggles the chat log + or not */ +}; + +extern ChatWindow *chatWindow; + +#endif diff --git a/src/gui/help.cpp b/src/gui/help.cpp deleted file mode 100644 index aca036c1..00000000 --- a/src/gui/help.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/* - * The Mana Client - * Copyright (C) 2004-2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers - * - * This file is part of The Mana Client. - * - * 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, see . - */ - -#include "gui/help.h" - -#include "gui/setup.h" - -#include "gui/widgets/button.h" -#include "gui/widgets/browserbox.h" -#include "gui/widgets/layout.h" -#include "gui/widgets/scrollarea.h" - -#include "resources/resourcemanager.h" -#include "configuration.h" - -#include "utils/gettext.h" - -HelpWindow::HelpWindow(): - Window(_("Help")) -{ - setMinWidth(300); - setMinHeight(250); - setContentSize(455, 350); - setWindowName("Help"); - setResizable(true); - setupWindow->registerWindowForReset(this); - - setDefaultSize(500, 400, ImageRect::CENTER); - - mBrowserBox = new BrowserBox; - mBrowserBox->setOpaque(false); - mScrollArea = new ScrollArea(mBrowserBox); - Button *okButton = new Button(_("Close"), "close", this); - - mScrollArea->setDimension(gcn::Rectangle(5, 5, 445, - 335 - okButton->getHeight())); - okButton->setPosition(450 - okButton->getWidth(), - 345 - okButton->getHeight()); - - mBrowserBox->setLinkHandler(this); - - place(0, 0, mScrollArea, 5, 3).setPadding(3); - place(4, 3, okButton); - - Layout &layout = getLayout(); - layout.setRowHeight(0, Layout::AUTO_SET); - - loadWindowState(); -} - -void HelpWindow::action(const gcn::ActionEvent &event) -{ - if (event.getId() == "close") - { - setVisible(false); - } -} - -void HelpWindow::handleLink(const std::string &link) -{ - std::string helpFile = link; - loadHelp(helpFile); -} - -void HelpWindow::loadHelp(const std::string &helpFile) -{ - mBrowserBox->clearRows(); - - loadFile("header"); - loadFile(helpFile); - - mScrollArea->setVerticalScrollAmount(0); - setVisible(true); -} - -void HelpWindow::loadFile(const std::string &file) -{ - ResourceManager *resman = ResourceManager::getInstance(); - std::string helpPath = branding.getStringValue("helpPath"); - if (helpPath.empty()) - helpPath = paths.getStringValue("help"); - std::vector lines = - resman->loadTextFile(helpPath + file + ".txt"); - - for (unsigned int i = 0; i < lines.size(); ++i) - { - mBrowserBox->addRow(lines[i]); - } -} diff --git a/src/gui/help.h b/src/gui/help.h deleted file mode 100644 index add49ced..00000000 --- a/src/gui/help.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * The Mana Client - * Copyright (C) 2004-2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers - * - * This file is part of The Mana Client. - * - * 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, see . - */ - -#ifndef HELP_H -#define HELP_H - -#include "gui/widgets/linkhandler.h" -#include "gui/widgets/window.h" - -#include - -class BrowserBox; -class LinkHandler; - -/** - * The help dialog. - */ -class HelpWindow : public Window, public LinkHandler, - public gcn::ActionListener -{ - public: - HelpWindow(); - - /** - * Called when receiving actions from the widgets. - */ - void action(const gcn::ActionEvent &event); - - /** - * Handles link action. - */ - void handleLink(const std::string &link); - - /** - * Loads help in the dialog. - */ - void loadHelp(const std::string &helpFile); - - private: - void loadFile(const std::string &file); - - BrowserBox *mBrowserBox; - gcn::ScrollArea *mScrollArea; -}; - -extern HelpWindow *helpWindow; - -#endif diff --git a/src/gui/helpwindow.cpp b/src/gui/helpwindow.cpp new file mode 100644 index 00000000..e059daaf --- /dev/null +++ b/src/gui/helpwindow.cpp @@ -0,0 +1,107 @@ +/* + * The Mana Client + * Copyright (C) 2004-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * + * This file is part of The Mana Client. + * + * 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, see . + */ + +#include "gui/helpwindow.h" + +#include "gui/setup.h" + +#include "gui/widgets/button.h" +#include "gui/widgets/browserbox.h" +#include "gui/widgets/layout.h" +#include "gui/widgets/scrollarea.h" + +#include "resources/resourcemanager.h" +#include "configuration.h" + +#include "utils/gettext.h" + +HelpWindow::HelpWindow(): + Window(_("Help")) +{ + setMinWidth(300); + setMinHeight(250); + setContentSize(455, 350); + setWindowName("Help"); + setResizable(true); + setupWindow->registerWindowForReset(this); + + setDefaultSize(500, 400, ImageRect::CENTER); + + mBrowserBox = new BrowserBox; + mBrowserBox->setOpaque(false); + mScrollArea = new ScrollArea(mBrowserBox); + Button *okButton = new Button(_("Close"), "close", this); + + mScrollArea->setDimension(gcn::Rectangle(5, 5, 445, + 335 - okButton->getHeight())); + okButton->setPosition(450 - okButton->getWidth(), + 345 - okButton->getHeight()); + + mBrowserBox->setLinkHandler(this); + + place(0, 0, mScrollArea, 5, 3).setPadding(3); + place(4, 3, okButton); + + Layout &layout = getLayout(); + layout.setRowHeight(0, Layout::AUTO_SET); + + loadWindowState(); +} + +void HelpWindow::action(const gcn::ActionEvent &event) +{ + if (event.getId() == "close") + { + setVisible(false); + } +} + +void HelpWindow::handleLink(const std::string &link) +{ + std::string helpFile = link; + loadHelp(helpFile); +} + +void HelpWindow::loadHelp(const std::string &helpFile) +{ + mBrowserBox->clearRows(); + + loadFile("header"); + loadFile(helpFile); + + mScrollArea->setVerticalScrollAmount(0); + setVisible(true); +} + +void HelpWindow::loadFile(const std::string &file) +{ + ResourceManager *resman = ResourceManager::getInstance(); + std::string helpPath = branding.getStringValue("helpPath"); + if (helpPath.empty()) + helpPath = paths.getStringValue("help"); + std::vector lines = + resman->loadTextFile(helpPath + file + ".txt"); + + for (unsigned int i = 0; i < lines.size(); ++i) + { + mBrowserBox->addRow(lines[i]); + } +} diff --git a/src/gui/helpwindow.h b/src/gui/helpwindow.h new file mode 100644 index 00000000..add49ced --- /dev/null +++ b/src/gui/helpwindow.h @@ -0,0 +1,66 @@ +/* + * The Mana Client + * Copyright (C) 2004-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * + * This file is part of The Mana Client. + * + * 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, see . + */ + +#ifndef HELP_H +#define HELP_H + +#include "gui/widgets/linkhandler.h" +#include "gui/widgets/window.h" + +#include + +class BrowserBox; +class LinkHandler; + +/** + * The help dialog. + */ +class HelpWindow : public Window, public LinkHandler, + public gcn::ActionListener +{ + public: + HelpWindow(); + + /** + * Called when receiving actions from the widgets. + */ + void action(const gcn::ActionEvent &event); + + /** + * Handles link action. + */ + void handleLink(const std::string &link); + + /** + * Loads help in the dialog. + */ + void loadHelp(const std::string &helpFile); + + private: + void loadFile(const std::string &file); + + BrowserBox *mBrowserBox; + gcn::ScrollArea *mScrollArea; +}; + +extern HelpWindow *helpWindow; + +#endif diff --git a/src/gui/inventorywindow.cpp b/src/gui/inventorywindow.cpp index 0bf2b313..73b59d95 100644 --- a/src/gui/inventorywindow.cpp +++ b/src/gui/inventorywindow.cpp @@ -28,7 +28,7 @@ #include "keyboardconfig.h" #include "playerinfo.h" -#include "gui/itemamount.h" +#include "gui/itemamountwindow.h" #include "gui/setup.h" #include "gui/sdlinput.h" #include "gui/viewport.h" diff --git a/src/gui/itemamount.cpp b/src/gui/itemamount.cpp deleted file mode 100644 index 43cdf1cf..00000000 --- a/src/gui/itemamount.cpp +++ /dev/null @@ -1,249 +0,0 @@ -/* - * The Mana Client - * Copyright (C) 2004-2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers - * - * This file is part of The Mana Client. - * - * 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, see . - */ - -#include "gui/itemamount.h" - -#include "item.h" -#include "keyboardconfig.h" - -#include "gui/trade.h" -#include "gui/itempopup.h" -#include "gui/viewport.h" - -#include "gui/widgets/button.h" -#include "gui/widgets/inttextfield.h" -#include "gui/widgets/layout.h" -#include "gui/widgets/slider.h" -#include "gui/widgets/icon.h" - -#include "net/inventoryhandler.h" -#include "net/net.h" - -#include "utils/gettext.h" - -void ItemAmountWindow::finish(Item *item, int amount, Usage usage) -{ - switch (usage) - { - case TradeAdd: - tradeWindow->tradeItem(item, amount); - break; - case ItemDrop: - item->doEvent(Event::DoDrop, amount); - break; - case ItemSplit: - item->doEvent(Event::DoSplit, amount); - break; - case StoreAdd: - { - Event event(Event::DoMove); - event.setItem("item", item); - event.setInt("amount", amount); - event.setInt("source", Inventory::INVENTORY); - event.setInt("destination", Inventory::STORAGE); - event.trigger(Event::ItemChannel); - } - break; - case StoreRemove: - { - Event event(Event::DoMove); - event.setItem("item", item); - event.setInt("amount", amount); - event.setInt("source", Inventory::STORAGE); - event.setInt("destination", Inventory::INVENTORY); - event.trigger(Event::ItemChannel); - } - break; - default: - break; - } -} - -ItemAmountWindow::ItemAmountWindow(Usage usage, Window *parent, Item *item, - int maxRange): - Window("", true, parent), - mItem(item), - mMax(maxRange), - mUsage(usage) -{ - if (!mMax) - mMax = mItem->getQuantity(); - - // Save keyboard state - mEnabledKeyboard = keyboard.isEnabled(); - keyboard.setEnabled(false); - - // Integer field - mItemAmountTextField = new IntTextField(1); - mItemAmountTextField->setRange(1, mMax); - mItemAmountTextField->setWidth(35); - mItemAmountTextField->addKeyListener(this); - - // Slider - mItemAmountSlide = new Slider(1.0, mMax); - mItemAmountSlide->setHeight(10); - mItemAmountSlide->setActionEventId("slide"); - mItemAmountSlide->addActionListener(this); - - //Item icon - Image *image = item->getImage(); - mItemIcon = new Icon(image); - - // Buttons - Button *minusButton = new Button(_("-"), "dec", this); - Button *plusButton = new Button(_("+"), "inc", this); - Button *okButton = new Button(_("OK"), "ok", this); - Button *cancelButton = new Button(_("Cancel"), "cancel", this); - Button *addAllButton = new Button(_("All"), "all", this); - - minusButton->adjustSize(); - minusButton->setWidth(plusButton->getWidth()); - - // Set positions - ContainerPlacer place; - place = getPlacer(0, 0); - place(1, 0, minusButton); - place(2, 0, mItemAmountTextField); - place(3, 0, plusButton); - place(4, 0, addAllButton); - - place(0, 0, mItemIcon, 1, 3); - place(1, 1, mItemAmountSlide, 5); - - place(4, 2, cancelButton); - place(5, 2, okButton); - - reflowLayout(225, 0); - - resetAmount(); - - switch (usage) - { - case TradeAdd: - setCaption(_("Select amount of items to trade.")); - break; - case ItemDrop: - setCaption(_("Select amount of items to drop.")); - break; - case StoreAdd: - setCaption(_("Select amount of items to store.")); - break; - case StoreRemove: - setCaption(_("Select amount of items to retrieve.")); - break; - case ItemSplit: - setCaption(_("Select amount of items to split.")); - break; - } - - setLocationRelativeTo(getParentWindow()); - setVisible(true); - - mItemPopup = new ItemPopup; - mItemIcon->addMouseListener(this); -} - -ItemAmountWindow::~ItemAmountWindow() -{ - delete mItemPopup; -} - -// Show ItemTooltip -void ItemAmountWindow::mouseMoved(gcn::MouseEvent &event) -{ - if (event.getSource() == mItemIcon) - { - mItemPopup->setItem(mItem->getInfo()); - mItemPopup->position(viewport->getMouseX(), viewport->getMouseY()); - } -} - -// Hide ItemTooltip -void ItemAmountWindow::mouseExited(gcn::MouseEvent &event) -{ - mItemPopup->setVisible(false); -} - -void ItemAmountWindow::resetAmount() -{ - mItemAmountTextField->setValue(1); -} - -void ItemAmountWindow::action(const gcn::ActionEvent &event) -{ - int amount = mItemAmountTextField->getValue(); - - if (event.getId() == "cancel") - { - close(); - } - else if (event.getId() == "inc" && amount < mMax) - { - amount++; - } - else if (event.getId() == "dec" && amount > 1) - { - amount--; - } - else if (event.getId() == "all") - { - amount = mMax; - } - else if (event.getId() == "slide") - { - amount = static_cast(mItemAmountSlide->getValue()); - } - else if (event.getId() == "ok") - { - finish(mItem, amount, mUsage); - close(); - return; - } - mItemAmountTextField->setValue(amount); - mItemAmountSlide->setValue(amount); -} - -void ItemAmountWindow::close() -{ - keyboard.setEnabled(mEnabledKeyboard); - scheduleDelete(); -} - -void ItemAmountWindow::keyReleased(gcn::KeyEvent &keyEvent) -{ - mItemAmountSlide->setValue(mItemAmountTextField->getValue()); -} - -void ItemAmountWindow::showWindow(Usage usage, Window *parent, Item *item, - int maxRange) -{ - if (!maxRange) - maxRange = item->getQuantity(); - - if (maxRange <= 1) - { - finish(item, maxRange, usage); - } - else - { - new ItemAmountWindow(usage, parent, item, maxRange); - } -} diff --git a/src/gui/itemamount.h b/src/gui/itemamount.h deleted file mode 100644 index 81243444..00000000 --- a/src/gui/itemamount.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * The Mana Client - * Copyright (C) 2004-2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers - * - * This file is part of The Mana Client. - * - * 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, see . - */ - -#ifndef ITEM_AMOUNT_WINDOW_H -#define ITEM_AMOUNT_WINDOW_H - -#include "gui/widgets/window.h" - -#include -#include - -class IntTextField; -class Item; -class ItemPopup; -class Icon; - -/** - * Window used for selecting the amount of items to drop, trade or split. - * - * \ingroup Interface - */ -class ItemAmountWindow : public Window, - public gcn::ActionListener, - public gcn::KeyListener -{ - public: - enum Usage { - TradeAdd, - ItemDrop, - StoreAdd, - StoreRemove, - ItemSplit - }; - - /** - * Called when receiving actions from widget. - */ - void action(const gcn::ActionEvent &event); - - /** - * Sets default amount value. - */ - void resetAmount(); - - // MouseListener - void mouseMoved(gcn::MouseEvent &event); - void mouseExited(gcn::MouseEvent &event); - - /** - * Schedules the Item Amount window for deletion. - */ - void close(); - - void keyReleased(gcn::KeyEvent &keyEvent); - - /** - * Creates the dialog, or bypass it if there aren't enough items. - */ - static void showWindow(Usage usage, Window *parent, Item *item, - int maxRange = 0); - - ~ItemAmountWindow(); - - private: - static void finish(Item *item, int amount, Usage usage); - - ItemAmountWindow(Usage usage, Window *parent, Item *item, - int maxRange = 0); - - IntTextField *mItemAmountTextField; /**< Item amount caption. */ - Item *mItem; - Icon *mItemIcon; - - int mMax; - Usage mUsage; - ItemPopup *mItemPopup; - - /** - * Item Amount buttons. - */ - gcn::Slider *mItemAmountSlide; - - bool mEnabledKeyboard; -}; - -#endif // ITEM_AMOUNT_WINDOW_H diff --git a/src/gui/itemamountwindow.cpp b/src/gui/itemamountwindow.cpp new file mode 100644 index 00000000..58197092 --- /dev/null +++ b/src/gui/itemamountwindow.cpp @@ -0,0 +1,249 @@ +/* + * The Mana Client + * Copyright (C) 2004-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * + * This file is part of The Mana Client. + * + * 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, see . + */ + +#include "gui/itemamountwindow.h" + +#include "item.h" +#include "keyboardconfig.h" + +#include "gui/tradewindow.h" +#include "gui/itempopup.h" +#include "gui/viewport.h" + +#include "gui/widgets/button.h" +#include "gui/widgets/inttextfield.h" +#include "gui/widgets/layout.h" +#include "gui/widgets/slider.h" +#include "gui/widgets/icon.h" + +#include "net/inventoryhandler.h" +#include "net/net.h" + +#include "utils/gettext.h" + +void ItemAmountWindow::finish(Item *item, int amount, Usage usage) +{ + switch (usage) + { + case TradeAdd: + tradeWindow->tradeItem(item, amount); + break; + case ItemDrop: + item->doEvent(Event::DoDrop, amount); + break; + case ItemSplit: + item->doEvent(Event::DoSplit, amount); + break; + case StoreAdd: + { + Event event(Event::DoMove); + event.setItem("item", item); + event.setInt("amount", amount); + event.setInt("source", Inventory::INVENTORY); + event.setInt("destination", Inventory::STORAGE); + event.trigger(Event::ItemChannel); + } + break; + case StoreRemove: + { + Event event(Event::DoMove); + event.setItem("item", item); + event.setInt("amount", amount); + event.setInt("source", Inventory::STORAGE); + event.setInt("destination", Inventory::INVENTORY); + event.trigger(Event::ItemChannel); + } + break; + default: + break; + } +} + +ItemAmountWindow::ItemAmountWindow(Usage usage, Window *parent, Item *item, + int maxRange): + Window("", true, parent), + mItem(item), + mMax(maxRange), + mUsage(usage) +{ + if (!mMax) + mMax = mItem->getQuantity(); + + // Save keyboard state + mEnabledKeyboard = keyboard.isEnabled(); + keyboard.setEnabled(false); + + // Integer field + mItemAmountTextField = new IntTextField(1); + mItemAmountTextField->setRange(1, mMax); + mItemAmountTextField->setWidth(35); + mItemAmountTextField->addKeyListener(this); + + // Slider + mItemAmountSlide = new Slider(1.0, mMax); + mItemAmountSlide->setHeight(10); + mItemAmountSlide->setActionEventId("slide"); + mItemAmountSlide->addActionListener(this); + + //Item icon + Image *image = item->getImage(); + mItemIcon = new Icon(image); + + // Buttons + Button *minusButton = new Button(_("-"), "dec", this); + Button *plusButton = new Button(_("+"), "inc", this); + Button *okButton = new Button(_("OK"), "ok", this); + Button *cancelButton = new Button(_("Cancel"), "cancel", this); + Button *addAllButton = new Button(_("All"), "all", this); + + minusButton->adjustSize(); + minusButton->setWidth(plusButton->getWidth()); + + // Set positions + ContainerPlacer place; + place = getPlacer(0, 0); + place(1, 0, minusButton); + place(2, 0, mItemAmountTextField); + place(3, 0, plusButton); + place(4, 0, addAllButton); + + place(0, 0, mItemIcon, 1, 3); + place(1, 1, mItemAmountSlide, 5); + + place(4, 2, cancelButton); + place(5, 2, okButton); + + reflowLayout(225, 0); + + resetAmount(); + + switch (usage) + { + case TradeAdd: + setCaption(_("Select amount of items to trade.")); + break; + case ItemDrop: + setCaption(_("Select amount of items to drop.")); + break; + case StoreAdd: + setCaption(_("Select amount of items to store.")); + break; + case StoreRemove: + setCaption(_("Select amount of items to retrieve.")); + break; + case ItemSplit: + setCaption(_("Select amount of items to split.")); + break; + } + + setLocationRelativeTo(getParentWindow()); + setVisible(true); + + mItemPopup = new ItemPopup; + mItemIcon->addMouseListener(this); +} + +ItemAmountWindow::~ItemAmountWindow() +{ + delete mItemPopup; +} + +// Show ItemTooltip +void ItemAmountWindow::mouseMoved(gcn::MouseEvent &event) +{ + if (event.getSource() == mItemIcon) + { + mItemPopup->setItem(mItem->getInfo()); + mItemPopup->position(viewport->getMouseX(), viewport->getMouseY()); + } +} + +// Hide ItemTooltip +void ItemAmountWindow::mouseExited(gcn::MouseEvent &event) +{ + mItemPopup->setVisible(false); +} + +void ItemAmountWindow::resetAmount() +{ + mItemAmountTextField->setValue(1); +} + +void ItemAmountWindow::action(const gcn::ActionEvent &event) +{ + int amount = mItemAmountTextField->getValue(); + + if (event.getId() == "cancel") + { + close(); + } + else if (event.getId() == "inc" && amount < mMax) + { + amount++; + } + else if (event.getId() == "dec" && amount > 1) + { + amount--; + } + else if (event.getId() == "all") + { + amount = mMax; + } + else if (event.getId() == "slide") + { + amount = static_cast(mItemAmountSlide->getValue()); + } + else if (event.getId() == "ok") + { + finish(mItem, amount, mUsage); + close(); + return; + } + mItemAmountTextField->setValue(amount); + mItemAmountSlide->setValue(amount); +} + +void ItemAmountWindow::close() +{ + keyboard.setEnabled(mEnabledKeyboard); + scheduleDelete(); +} + +void ItemAmountWindow::keyReleased(gcn::KeyEvent &keyEvent) +{ + mItemAmountSlide->setValue(mItemAmountTextField->getValue()); +} + +void ItemAmountWindow::showWindow(Usage usage, Window *parent, Item *item, + int maxRange) +{ + if (!maxRange) + maxRange = item->getQuantity(); + + if (maxRange <= 1) + { + finish(item, maxRange, usage); + } + else + { + new ItemAmountWindow(usage, parent, item, maxRange); + } +} diff --git a/src/gui/itemamountwindow.h b/src/gui/itemamountwindow.h new file mode 100644 index 00000000..81243444 --- /dev/null +++ b/src/gui/itemamountwindow.h @@ -0,0 +1,104 @@ +/* + * The Mana Client + * Copyright (C) 2004-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * + * This file is part of The Mana Client. + * + * 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, see . + */ + +#ifndef ITEM_AMOUNT_WINDOW_H +#define ITEM_AMOUNT_WINDOW_H + +#include "gui/widgets/window.h" + +#include +#include + +class IntTextField; +class Item; +class ItemPopup; +class Icon; + +/** + * Window used for selecting the amount of items to drop, trade or split. + * + * \ingroup Interface + */ +class ItemAmountWindow : public Window, + public gcn::ActionListener, + public gcn::KeyListener +{ + public: + enum Usage { + TradeAdd, + ItemDrop, + StoreAdd, + StoreRemove, + ItemSplit + }; + + /** + * Called when receiving actions from widget. + */ + void action(const gcn::ActionEvent &event); + + /** + * Sets default amount value. + */ + void resetAmount(); + + // MouseListener + void mouseMoved(gcn::MouseEvent &event); + void mouseExited(gcn::MouseEvent &event); + + /** + * Schedules the Item Amount window for deletion. + */ + void close(); + + void keyReleased(gcn::KeyEvent &keyEvent); + + /** + * Creates the dialog, or bypass it if there aren't enough items. + */ + static void showWindow(Usage usage, Window *parent, Item *item, + int maxRange = 0); + + ~ItemAmountWindow(); + + private: + static void finish(Item *item, int amount, Usage usage); + + ItemAmountWindow(Usage usage, Window *parent, Item *item, + int maxRange = 0); + + IntTextField *mItemAmountTextField; /**< Item amount caption. */ + Item *mItem; + Icon *mItemIcon; + + int mMax; + Usage mUsage; + ItemPopup *mItemPopup; + + /** + * Item Amount buttons. + */ + gcn::Slider *mItemAmountSlide; + + bool mEnabledKeyboard; +}; + +#endif // ITEM_AMOUNT_WINDOW_H diff --git a/src/gui/login.cpp b/src/gui/login.cpp deleted file mode 100644 index b12e6a5d..00000000 --- a/src/gui/login.cpp +++ /dev/null @@ -1,158 +0,0 @@ -/* - * The Mana Client - * Copyright (C) 2004-2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers - * - * This file is part of The Mana Client. - * - * 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, see . - */ - -#include "gui/login.h" - -#include "client.h" -#include "configuration.h" - -#include "gui/okdialog.h" -#include "gui/sdlinput.h" - -#include "gui/widgets/button.h" -#include "gui/widgets/checkbox.h" -#include "gui/widgets/dropdown.h" -#include "gui/widgets/label.h" -#include "gui/widgets/layout.h" -#include "gui/widgets/passwordfield.h" -#include "gui/widgets/textfield.h" - -#include "net/logindata.h" -#include "net/loginhandler.h" -#include "net/net.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 Label(_("Name:")); - gcn::Label *passLabel = new Label(_("Password:")); - - mUserField = new TextField(mLoginData->username); - mPassField = new PasswordField(mLoginData->password); - - mKeepCheck = new CheckBox(_("Remember username"), mLoginData->remember); - mRegisterButton = new Button(_("Register"), "register", this); - mServerButton = new Button(_("Change Server"), "server", this); - mLoginButton = new Button(_("Login"), "login", this); - - mUserField->setActionEventId("login"); - mPassField->setActionEventId("login"); - - mUserField->addKeyListener(this); - mPassField->addKeyListener(this); - mUserField->addActionListener(this); - mPassField->addActionListener(this); - - place(0, 0, userLabel); - place(0, 1, passLabel); - place(1, 0, mUserField, 3).setPadding(1); - place(1, 1, mPassField, 3).setPadding(1); - place(0, 5, mKeepCheck, 4); - place(0, 6, mRegisterButton).setHAlign(LayoutCell::LEFT); - place(2, 6, mServerButton); - place(3, 6, mLoginButton); - reflowLayout(); - - addKeyListener(this); - - center(); - setVisible(true); - - if (mUserField->getText().empty()) - mUserField->requestFocus(); - else - mPassField->requestFocus(); - - mLoginButton->setEnabled(canSubmit()); -} - -LoginDialog::~LoginDialog() -{ -} - -void LoginDialog::action(const gcn::ActionEvent &event) -{ - if (event.getId() == "login" && canSubmit()) - { - mLoginData->username = mUserField->getText(); - mLoginData->password = mPassField->getText(); - mLoginData->remember = mKeepCheck->isSelected(); - mLoginData->registerLogin = false; - - mRegisterButton->setEnabled(false); - mServerButton->setEnabled(false); - mLoginButton->setEnabled(false); - - Client::setState(STATE_LOGIN_ATTEMPT); - } - else if (event.getId() == "server") - { - Client::setState(STATE_SWITCH_SERVER); - } - else if (event.getId() == "register") - { - if (Net::getLoginHandler()->isRegistrationEnabled()) - { - mLoginData->username = mUserField->getText(); - mLoginData->password = mPassField->getText(); - Client::setState(STATE_REGISTER_PREP); - } - else - { - new OkDialog(_("Registration disabled"), _("You need to use the " - "website to register an account for this server.")); - } - } -} - -void LoginDialog::keyPressed(gcn::KeyEvent &keyEvent) -{ - gcn::Key key = keyEvent.getKey(); - - if (key.getValue() == Key::ESCAPE) - { - action(gcn::ActionEvent(NULL, mServerButton->getActionEventId())); - } - else if (key.getValue() == Key::ENTER) - { - action(gcn::ActionEvent(NULL, mLoginButton->getActionEventId())); - } - else - { - mLoginButton->setEnabled(canSubmit()); - } -} - -bool LoginDialog::canSubmit() const -{ - return !mUserField->getText().empty() && - !mPassField->getText().empty() && - Client::getState() == STATE_LOGIN; -} diff --git a/src/gui/login.h b/src/gui/login.h deleted file mode 100644 index 38e858f6..00000000 --- a/src/gui/login.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * The Mana Client - * Copyright (C) 2004-2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers - * - * This file is part of The Mana Client. - * - * 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, see . - */ - -#ifndef LOGIN_H -#define LOGIN_H - -#include "gui/widgets/window.h" - -#include -#include -#include - -#include -#include - -class LoginData; - -/** - * The login dialog. - * - * \ingroup Interface - */ -class LoginDialog : public Window, public gcn::ActionListener, - public gcn::KeyListener -{ - public: - LoginDialog(LoginData *loginData); - - ~LoginDialog(); - - /** - * Called when receiving actions from the widgets. - */ - void action(const gcn::ActionEvent &event); - - /** - * Called when a key is pressed in one of the text fields. - */ - void keyPressed(gcn::KeyEvent &keyEvent); - - private: - /** - * Returns whether submit can be enabled. This is true in the login - * state, when all necessary fields have some text. - */ - bool canSubmit() const; - - gcn::TextField *mUserField; - gcn::TextField *mPassField; - gcn::CheckBox *mKeepCheck; - gcn::Button *mServerButton; - gcn::Button *mLoginButton; - gcn::Button *mRegisterButton; - - LoginData *mLoginData; -}; - -#endif diff --git a/src/gui/logindialog.cpp b/src/gui/logindialog.cpp new file mode 100644 index 00000000..abb5cff2 --- /dev/null +++ b/src/gui/logindialog.cpp @@ -0,0 +1,158 @@ +/* + * The Mana Client + * Copyright (C) 2004-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * + * This file is part of The Mana Client. + * + * 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, see . + */ + +#include "gui/logindialog.h" + +#include "client.h" +#include "configuration.h" + +#include "gui/okdialog.h" +#include "gui/sdlinput.h" + +#include "gui/widgets/button.h" +#include "gui/widgets/checkbox.h" +#include "gui/widgets/dropdown.h" +#include "gui/widgets/label.h" +#include "gui/widgets/layout.h" +#include "gui/widgets/passwordfield.h" +#include "gui/widgets/textfield.h" + +#include "net/logindata.h" +#include "net/loginhandler.h" +#include "net/net.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 Label(_("Name:")); + gcn::Label *passLabel = new Label(_("Password:")); + + mUserField = new TextField(mLoginData->username); + mPassField = new PasswordField(mLoginData->password); + + mKeepCheck = new CheckBox(_("Remember username"), mLoginData->remember); + mRegisterButton = new Button(_("Register"), "register", this); + mServerButton = new Button(_("Change Server"), "server", this); + mLoginButton = new Button(_("Login"), "login", this); + + mUserField->setActionEventId("login"); + mPassField->setActionEventId("login"); + + mUserField->addKeyListener(this); + mPassField->addKeyListener(this); + mUserField->addActionListener(this); + mPassField->addActionListener(this); + + place(0, 0, userLabel); + place(0, 1, passLabel); + place(1, 0, mUserField, 3).setPadding(1); + place(1, 1, mPassField, 3).setPadding(1); + place(0, 5, mKeepCheck, 4); + place(0, 6, mRegisterButton).setHAlign(LayoutCell::LEFT); + place(2, 6, mServerButton); + place(3, 6, mLoginButton); + reflowLayout(); + + addKeyListener(this); + + center(); + setVisible(true); + + if (mUserField->getText().empty()) + mUserField->requestFocus(); + else + mPassField->requestFocus(); + + mLoginButton->setEnabled(canSubmit()); +} + +LoginDialog::~LoginDialog() +{ +} + +void LoginDialog::action(const gcn::ActionEvent &event) +{ + if (event.getId() == "login" && canSubmit()) + { + mLoginData->username = mUserField->getText(); + mLoginData->password = mPassField->getText(); + mLoginData->remember = mKeepCheck->isSelected(); + mLoginData->registerLogin = false; + + mRegisterButton->setEnabled(false); + mServerButton->setEnabled(false); + mLoginButton->setEnabled(false); + + Client::setState(STATE_LOGIN_ATTEMPT); + } + else if (event.getId() == "server") + { + Client::setState(STATE_SWITCH_SERVER); + } + else if (event.getId() == "register") + { + if (Net::getLoginHandler()->isRegistrationEnabled()) + { + mLoginData->username = mUserField->getText(); + mLoginData->password = mPassField->getText(); + Client::setState(STATE_REGISTER_PREP); + } + else + { + new OkDialog(_("Registration disabled"), _("You need to use the " + "website to register an account for this server.")); + } + } +} + +void LoginDialog::keyPressed(gcn::KeyEvent &keyEvent) +{ + gcn::Key key = keyEvent.getKey(); + + if (key.getValue() == Key::ESCAPE) + { + action(gcn::ActionEvent(NULL, mServerButton->getActionEventId())); + } + else if (key.getValue() == Key::ENTER) + { + action(gcn::ActionEvent(NULL, mLoginButton->getActionEventId())); + } + else + { + mLoginButton->setEnabled(canSubmit()); + } +} + +bool LoginDialog::canSubmit() const +{ + return !mUserField->getText().empty() && + !mPassField->getText().empty() && + Client::getState() == STATE_LOGIN; +} diff --git a/src/gui/logindialog.h b/src/gui/logindialog.h new file mode 100644 index 00000000..38e858f6 --- /dev/null +++ b/src/gui/logindialog.h @@ -0,0 +1,76 @@ +/* + * The Mana Client + * Copyright (C) 2004-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * + * This file is part of The Mana Client. + * + * 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, see . + */ + +#ifndef LOGIN_H +#define LOGIN_H + +#include "gui/widgets/window.h" + +#include +#include +#include + +#include +#include + +class LoginData; + +/** + * The login dialog. + * + * \ingroup Interface + */ +class LoginDialog : public Window, public gcn::ActionListener, + public gcn::KeyListener +{ + public: + LoginDialog(LoginData *loginData); + + ~LoginDialog(); + + /** + * Called when receiving actions from the widgets. + */ + void action(const gcn::ActionEvent &event); + + /** + * Called when a key is pressed in one of the text fields. + */ + void keyPressed(gcn::KeyEvent &keyEvent); + + private: + /** + * Returns whether submit can be enabled. This is true in the login + * state, when all necessary fields have some text. + */ + bool canSubmit() const; + + gcn::TextField *mUserField; + gcn::TextField *mPassField; + gcn::CheckBox *mKeepCheck; + gcn::Button *mServerButton; + gcn::Button *mLoginButton; + gcn::Button *mRegisterButton; + + LoginData *mLoginData; +}; + +#endif diff --git a/src/gui/ministatus.cpp b/src/gui/ministatus.cpp deleted file mode 100644 index 2bdf79b4..00000000 --- a/src/gui/ministatus.cpp +++ /dev/null @@ -1,261 +0,0 @@ -/* - * The Mana Client - * Copyright (C) 2004-2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers - * - * This file is part of The Mana Client. - * - * 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, see . - */ - -#include "gui/ministatus.h" - -#include "animatedsprite.h" -#include "configuration.h" -#include "graphics.h" -#include "playerinfo.h" -#include "statuseffect.h" - -#include "gui/gui.h" -#include "gui/statuswindow.h" -#include "gui/textpopup.h" - -#include "gui/widgets/progressbar.h" - -#include "net/net.h" -#include "net/playerhandler.h" -#include "net/gamehandler.h" - -#include "resources/theme.h" - -#include "utils/gettext.h" -#include "utils/stringutils.h" - -extern volatile int tick_time; - -MiniStatusWindow::MiniStatusWindow(): - Popup("MiniStatus") -{ - listen(Event::AttributesChannel); - - mHpBar = new ProgressBar(0, 100, 20, Theme::PROG_HP); - StatusWindow::updateHPBar(mHpBar); - - if (Net::getGameHandler()->canUseMagicBar()) - { - mMpBar = new ProgressBar(0, 100, 20, - Net::getPlayerHandler()->canUseMagic() - ? Theme::PROG_MP : Theme::PROG_NO_MP); - - StatusWindow::updateMPBar(mMpBar); - } - else - mMpBar = 0; - - mXpBar = new ProgressBar(0, 100, 20, Theme::PROG_EXP); - StatusWindow::updateXPBar(mXpBar); - - // Add the progressbars to the window - - mHpBar->setPosition(0, 3); - if (mMpBar) - mMpBar->setPosition(mHpBar->getWidth() + 3, 3); - mXpBar->setPosition(mMpBar ? mMpBar->getX() + mMpBar->getWidth() + 3 : - mHpBar->getX() + mHpBar->getWidth() + 3, 3); - - add(mHpBar); - if (mMpBar) - add(mMpBar); - add(mXpBar); - - setContentSize(mXpBar->getX() + mXpBar->getWidth(), - mXpBar->getY() + mXpBar->getHeight()); - - setVisible((bool) config.getValue(getPopupName() + "Visible", true)); - - mTextPopup = new TextPopup(); - - addMouseListener(this); -} - -void MiniStatusWindow::setIcon(int index, AnimatedSprite *sprite) -{ - if (index >= (int) mIcons.size()) - mIcons.resize(index + 1); - - delete mIcons[index]; - mIcons[index] = sprite; -} - -void MiniStatusWindow::eraseIcon(int index) -{ - mIcons.erase(mIcons.begin() + index); -} - -void MiniStatusWindow::drawIcons(Graphics *graphics) -{ - // Draw icons - int icon_x = mXpBar->getX() + mXpBar->getWidth() + 4; - 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(); - } - } -} - -void MiniStatusWindow::event(Event::Channel channel, - const Event &event) -{ - if (channel == Event::AttributesChannel) - { - if (event.getType() == Event::UpdateAttribute) - { - int id = event.getInt("id"); - if (id == HP || id == MAX_HP) - { - StatusWindow::updateHPBar(mHpBar); - } - else if (id == MP || id == MAX_MP) - { - StatusWindow::updateMPBar(mMpBar); - } - else if (id == EXP || id == EXP_NEEDED) - { - StatusWindow::updateXPBar(mXpBar); - } - } - } - else if (channel == Event::ActorSpriteChannel) - { - if (event.getType() == Event::UpdateStatusEffect) - { - int index = event.getInt("index"); - bool newStatus = event.getBool("newStatus"); - - StatusEffect *effect = StatusEffect::getStatusEffect(index, - newStatus); - - if (effect) - { - effect->deliverMessage(); - effect->playSFX(); - - AnimatedSprite *sprite = effect->getIcon(); - - typedef std::vector IntMap; - - if (!sprite) - { - // delete sprite, if necessary - for (unsigned int i = 0; i < mStatusEffectIcons.size();) - if (mStatusEffectIcons[i] == index) - { - mStatusEffectIcons.erase(mStatusEffectIcons.begin() - + i); - miniStatusWindow->eraseIcon(i); - } - else - i++; - } - else - { - // replace sprite or append - bool found = false; - - for (unsigned int i = 0; i < mStatusEffectIcons.size(); - i++) - if (mStatusEffectIcons[i] == index) - { - miniStatusWindow->setIcon(i, sprite); - found = true; - break; - } - - if (!found) - { // add new - int offset = mStatusEffectIcons.size(); - miniStatusWindow->setIcon(offset, sprite); - mStatusEffectIcons.push_back(index); - } - } - } - } - } -} - -void MiniStatusWindow::logic() -{ - Popup::logic(); - - // Displays the number of monsters to next lvl - // (disabled for now but interesting idea) - /* - if (config.getValue("xpBarMonsterCounterExp", 0)!=0) - { - updatedText << " | " - << (int)(((float)local_player->mXpForNextLevel - (float)local_player->mXp) - / (float)config.getValue("xpBarMonsterCounterExp", 0)) - << " " - << config.getValue("xpBarMonsterCounterName", "Monsters") <<" left..."; - } - */ - - for (unsigned int i = 0; i < mIcons.size(); i++) - if (mIcons[i]) - mIcons[i]->update(tick_time * 10); -} - -void MiniStatusWindow::mouseMoved(gcn::MouseEvent &event) -{ - Popup::mouseMoved(event); - - const int x = event.getX(); - const int y = event.getY(); - - if (event.getSource() == mXpBar) - { - mTextPopup->show(x + getX(), y + getY(), - strprintf("%u/%u", PlayerInfo::getAttribute(EXP), - PlayerInfo::getAttribute(EXP_NEEDED)), - strprintf("%s: %u", _("Need"), - PlayerInfo::getAttribute(EXP_NEEDED) - - PlayerInfo::getAttribute(EXP))); - } - else if (event.getSource() == mHpBar) - { - mTextPopup->show(x + getX(), y + getY(), - strprintf("%u/%u", PlayerInfo::getAttribute(HP), - PlayerInfo::getAttribute(MAX_HP))); - } - else if (event.getSource() == mMpBar) - { - mTextPopup->show(x + getX(), y + getY(), - strprintf("%u/%u", PlayerInfo::getAttribute(MP), - PlayerInfo::getAttribute(MAX_MP))); - } - else - { - mTextPopup->setVisible(false); - } -} - -void MiniStatusWindow::mouseExited(gcn::MouseEvent &event) -{ - Popup::mouseExited(event); - - mTextPopup->setVisible(false); -} diff --git a/src/gui/ministatus.h b/src/gui/ministatus.h deleted file mode 100644 index 38025202..00000000 --- a/src/gui/ministatus.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * The Mana Client - * Copyright (C) 2004-2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers - * - * This file is part of The Mana Client. - * - * 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, see . - */ - -#ifndef MINISTATUS_H -#define MINISTATUS_H - -#include "eventlistener.h" - -#include "gui/widgets/popup.h" - -#include - -class AnimatedSprite; -class Graphics; -class ProgressBar; -class TextPopup; - -/** - * The player mini-status dialog. - * - * \ingroup Interface - */ -class MiniStatusWindow : public Popup, public EventListener -{ - public: - MiniStatusWindow(); - - void drawIcons(Graphics *graphics); - - void event(Event::Channel channel, const Event &event); - - void logic(); // Updates icons - - void draw(gcn::Graphics *graphics) - { drawChildren(graphics); } - - void mouseMoved(gcn::MouseEvent &mouseEvent); - void mouseExited(gcn::MouseEvent &event); - - private: - bool isInBar(ProgressBar *bar, int x, int y) const; - - /** - * Sets one of the icons. - */ - void setIcon(int index, AnimatedSprite *sprite); - - void eraseIcon(int index); - - /* - * Mini Status Bars - */ - ProgressBar *mHpBar; - ProgressBar *mMpBar; - ProgressBar *mXpBar; - TextPopup *mTextPopup; - - std::vector mStatusEffectIcons; - std::vector mIcons; -}; - -extern MiniStatusWindow *miniStatusWindow; - -#endif diff --git a/src/gui/ministatuswindow.cpp b/src/gui/ministatuswindow.cpp new file mode 100644 index 00000000..c4400656 --- /dev/null +++ b/src/gui/ministatuswindow.cpp @@ -0,0 +1,261 @@ +/* + * The Mana Client + * Copyright (C) 2004-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * + * This file is part of The Mana Client. + * + * 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, see . + */ + +#include "gui/ministatuswindow.h" + +#include "animatedsprite.h" +#include "configuration.h" +#include "graphics.h" +#include "playerinfo.h" +#include "statuseffect.h" + +#include "gui/gui.h" +#include "gui/statuswindow.h" +#include "gui/textpopup.h" + +#include "gui/widgets/progressbar.h" + +#include "net/net.h" +#include "net/playerhandler.h" +#include "net/gamehandler.h" + +#include "resources/theme.h" + +#include "utils/gettext.h" +#include "utils/stringutils.h" + +extern volatile int tick_time; + +MiniStatusWindow::MiniStatusWindow(): + Popup("MiniStatus") +{ + listen(Event::AttributesChannel); + + mHpBar = new ProgressBar(0, 100, 20, Theme::PROG_HP); + StatusWindow::updateHPBar(mHpBar); + + if (Net::getGameHandler()->canUseMagicBar()) + { + mMpBar = new ProgressBar(0, 100, 20, + Net::getPlayerHandler()->canUseMagic() + ? Theme::PROG_MP : Theme::PROG_NO_MP); + + StatusWindow::updateMPBar(mMpBar); + } + else + mMpBar = 0; + + mXpBar = new ProgressBar(0, 100, 20, Theme::PROG_EXP); + StatusWindow::updateXPBar(mXpBar); + + // Add the progressbars to the window + + mHpBar->setPosition(0, 3); + if (mMpBar) + mMpBar->setPosition(mHpBar->getWidth() + 3, 3); + mXpBar->setPosition(mMpBar ? mMpBar->getX() + mMpBar->getWidth() + 3 : + mHpBar->getX() + mHpBar->getWidth() + 3, 3); + + add(mHpBar); + if (mMpBar) + add(mMpBar); + add(mXpBar); + + setContentSize(mXpBar->getX() + mXpBar->getWidth(), + mXpBar->getY() + mXpBar->getHeight()); + + setVisible((bool) config.getValue(getPopupName() + "Visible", true)); + + mTextPopup = new TextPopup(); + + addMouseListener(this); +} + +void MiniStatusWindow::setIcon(int index, AnimatedSprite *sprite) +{ + if (index >= (int) mIcons.size()) + mIcons.resize(index + 1); + + delete mIcons[index]; + mIcons[index] = sprite; +} + +void MiniStatusWindow::eraseIcon(int index) +{ + mIcons.erase(mIcons.begin() + index); +} + +void MiniStatusWindow::drawIcons(Graphics *graphics) +{ + // Draw icons + int icon_x = mXpBar->getX() + mXpBar->getWidth() + 4; + 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(); + } + } +} + +void MiniStatusWindow::event(Event::Channel channel, + const Event &event) +{ + if (channel == Event::AttributesChannel) + { + if (event.getType() == Event::UpdateAttribute) + { + int id = event.getInt("id"); + if (id == HP || id == MAX_HP) + { + StatusWindow::updateHPBar(mHpBar); + } + else if (id == MP || id == MAX_MP) + { + StatusWindow::updateMPBar(mMpBar); + } + else if (id == EXP || id == EXP_NEEDED) + { + StatusWindow::updateXPBar(mXpBar); + } + } + } + else if (channel == Event::ActorSpriteChannel) + { + if (event.getType() == Event::UpdateStatusEffect) + { + int index = event.getInt("index"); + bool newStatus = event.getBool("newStatus"); + + StatusEffect *effect = StatusEffect::getStatusEffect(index, + newStatus); + + if (effect) + { + effect->deliverMessage(); + effect->playSFX(); + + AnimatedSprite *sprite = effect->getIcon(); + + typedef std::vector IntMap; + + if (!sprite) + { + // delete sprite, if necessary + for (unsigned int i = 0; i < mStatusEffectIcons.size();) + if (mStatusEffectIcons[i] == index) + { + mStatusEffectIcons.erase(mStatusEffectIcons.begin() + + i); + miniStatusWindow->eraseIcon(i); + } + else + i++; + } + else + { + // replace sprite or append + bool found = false; + + for (unsigned int i = 0; i < mStatusEffectIcons.size(); + i++) + if (mStatusEffectIcons[i] == index) + { + miniStatusWindow->setIcon(i, sprite); + found = true; + break; + } + + if (!found) + { // add new + int offset = mStatusEffectIcons.size(); + miniStatusWindow->setIcon(offset, sprite); + mStatusEffectIcons.push_back(index); + } + } + } + } + } +} + +void MiniStatusWindow::logic() +{ + Popup::logic(); + + // Displays the number of monsters to next lvl + // (disabled for now but interesting idea) + /* + if (config.getValue("xpBarMonsterCounterExp", 0)!=0) + { + updatedText << " | " + << (int)(((float)local_player->mXpForNextLevel - (float)local_player->mXp) + / (float)config.getValue("xpBarMonsterCounterExp", 0)) + << " " + << config.getValue("xpBarMonsterCounterName", "Monsters") <<" left..."; + } + */ + + for (unsigned int i = 0; i < mIcons.size(); i++) + if (mIcons[i]) + mIcons[i]->update(tick_time * 10); +} + +void MiniStatusWindow::mouseMoved(gcn::MouseEvent &event) +{ + Popup::mouseMoved(event); + + const int x = event.getX(); + const int y = event.getY(); + + if (event.getSource() == mXpBar) + { + mTextPopup->show(x + getX(), y + getY(), + strprintf("%u/%u", PlayerInfo::getAttribute(EXP), + PlayerInfo::getAttribute(EXP_NEEDED)), + strprintf("%s: %u", _("Need"), + PlayerInfo::getAttribute(EXP_NEEDED) + - PlayerInfo::getAttribute(EXP))); + } + else if (event.getSource() == mHpBar) + { + mTextPopup->show(x + getX(), y + getY(), + strprintf("%u/%u", PlayerInfo::getAttribute(HP), + PlayerInfo::getAttribute(MAX_HP))); + } + else if (event.getSource() == mMpBar) + { + mTextPopup->show(x + getX(), y + getY(), + strprintf("%u/%u", PlayerInfo::getAttribute(MP), + PlayerInfo::getAttribute(MAX_MP))); + } + else + { + mTextPopup->setVisible(false); + } +} + +void MiniStatusWindow::mouseExited(gcn::MouseEvent &event) +{ + Popup::mouseExited(event); + + mTextPopup->setVisible(false); +} diff --git a/src/gui/ministatuswindow.h b/src/gui/ministatuswindow.h new file mode 100644 index 00000000..38025202 --- /dev/null +++ b/src/gui/ministatuswindow.h @@ -0,0 +1,82 @@ +/* + * The Mana Client + * Copyright (C) 2004-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * + * This file is part of The Mana Client. + * + * 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, see . + */ + +#ifndef MINISTATUS_H +#define MINISTATUS_H + +#include "eventlistener.h" + +#include "gui/widgets/popup.h" + +#include + +class AnimatedSprite; +class Graphics; +class ProgressBar; +class TextPopup; + +/** + * The player mini-status dialog. + * + * \ingroup Interface + */ +class MiniStatusWindow : public Popup, public EventListener +{ + public: + MiniStatusWindow(); + + void drawIcons(Graphics *graphics); + + void event(Event::Channel channel, const Event &event); + + void logic(); // Updates icons + + void draw(gcn::Graphics *graphics) + { drawChildren(graphics); } + + void mouseMoved(gcn::MouseEvent &mouseEvent); + void mouseExited(gcn::MouseEvent &event); + + private: + bool isInBar(ProgressBar *bar, int x, int y) const; + + /** + * Sets one of the icons. + */ + void setIcon(int index, AnimatedSprite *sprite); + + void eraseIcon(int index); + + /* + * Mini Status Bars + */ + ProgressBar *mHpBar; + ProgressBar *mMpBar; + ProgressBar *mXpBar; + TextPopup *mTextPopup; + + std::vector mStatusEffectIcons; + std::vector mIcons; +}; + +extern MiniStatusWindow *miniStatusWindow; + +#endif diff --git a/src/gui/outfitwindow.cpp b/src/gui/outfitwindow.cpp index 053c6659..3cb3e9d9 100644 --- a/src/gui/outfitwindow.cpp +++ b/src/gui/outfitwindow.cpp @@ -29,7 +29,7 @@ #include "log.h" #include "playerinfo.h" -#include "gui/chat.h" +#include "gui/chatwindow.h" #include "gui/widgets/button.h" #include "gui/widgets/checkbox.h" diff --git a/src/gui/popupmenu.cpp b/src/gui/popupmenu.cpp index 742d480d..4e994dc3 100644 --- a/src/gui/popupmenu.cpp +++ b/src/gui/popupmenu.cpp @@ -31,10 +31,10 @@ #include "playerinfo.h" #include "playerrelations.h" -#include "gui/chat.h" +#include "gui/chatwindow.h" #include "gui/equipmentwindow.h" #include "gui/inventorywindow.h" -#include "gui/itemamount.h" +#include "gui/itemamountwindow.h" #include "gui/widgets/browserbox.h" diff --git a/src/gui/recorder.cpp b/src/gui/recorder.cpp index 2345369e..da2ee80f 100644 --- a/src/gui/recorder.cpp +++ b/src/gui/recorder.cpp @@ -23,7 +23,7 @@ #include "client.h" #include "event.h" -#include "gui/chat.h" +#include "gui/chatwindow.h" #include "gui/widgets/button.h" #include "gui/widgets/layout.h" diff --git a/src/gui/register.cpp b/src/gui/register.cpp index 9fbd8cc8..2b3dd1cc 100644 --- a/src/gui/register.cpp +++ b/src/gui/register.cpp @@ -25,7 +25,7 @@ #include "configuration.h" #include "log.h" -#include "gui/login.h" +#include "gui/logindialog.h" #include "gui/okdialog.h" #include "gui/widgets/button.h" diff --git a/src/gui/sell.cpp b/src/gui/sell.cpp deleted file mode 100644 index 46bef092..00000000 --- a/src/gui/sell.cpp +++ /dev/null @@ -1,326 +0,0 @@ -/* - * The Mana Client - * Copyright (C) 2004-2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers - * - * This file is part of The Mana Client. - * - * 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, see . - */ - -#include "gui/sell.h" - -#include "client.h" -#include "playerinfo.h" -#include "shopitem.h" -#include "units.h" - -#include "gui/setup.h" - -#include "gui/widgets/button.h" -#include "gui/widgets/label.h" -#include "gui/widgets/layout.h" -#include "gui/widgets/scrollarea.h" -#include "gui/widgets/shopitems.h" -#include "gui/widgets/shoplistbox.h" -#include "gui/widgets/slider.h" - -#include "net/net.h" -#include "net/npchandler.h" - -#include "resources/iteminfo.h" - -#include "utils/gettext.h" -#include "utils/stringutils.h" - -SellDialog::DialogList SellDialog::instances; - -SellDialog::SellDialog(int npcId): - Window(_("Sell")), - mNpcId(npcId), mMaxItems(0), mAmountItems(0) -{ - setWindowName("Sell"); - //setupWindow->registerWindowForReset(this); - setResizable(true); - setCloseButton(true); - setMinWidth(260); - setMinHeight(230); - setDefaultSize(260, 230, ImageRect::CENTER); - - // Create a ShopItems instance, that is aware of duplicate entries. - mShopItems = new ShopItems(true); - - mShopItemList = new ShopListBox(mShopItems, mShopItems); - mScrollArea = new ScrollArea(mShopItemList); - mScrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); - - mSlider = new Slider(1.0); - - mQuantityLabel = new Label(strprintf("%d / %d", mAmountItems, mMaxItems)); - mQuantityLabel->setAlignment(gcn::Graphics::CENTER); - mMoneyLabel = new Label(strprintf(_("Price: %s / Total: %s"), - "", "")); - - mIncreaseButton = new Button(_("+"), "inc", this); - mDecreaseButton = new Button(_("-"), "dec", this); - mSellButton = new Button(_("Sell"), "sell", this); - mQuitButton = new Button(_("Quit"), "quit", this); - mAddMaxButton = new Button(_("Max"), "max", this); - - mDecreaseButton->adjustSize(); - mDecreaseButton->setWidth(mIncreaseButton->getWidth()); - - mIncreaseButton->setEnabled(false); - mDecreaseButton->setEnabled(false); - mSellButton->setEnabled(false); - mSlider->setEnabled(false); - - mShopItemList->setPriceCheck(false); - mShopItemList->addSelectionListener(this); - mSlider->setActionEventId("slider"); - mSlider->addActionListener(this); - - ContainerPlacer place; - place = getPlacer(0, 0); - - place(0, 0, mScrollArea, 8, 5).setPadding(3); - place(0, 5, mDecreaseButton); - place(1, 5, mSlider, 3); - place(4, 5, mIncreaseButton); - place(5, 5, mQuantityLabel, 2); - place(7, 5, mAddMaxButton); - place(0, 6, mMoneyLabel, 8); - place(6, 7, mSellButton); - place(7, 7, mQuitButton); - - Layout &layout = getLayout(); - layout.setRowHeight(0, Layout::AUTO_SET); - - center(); - loadWindowState(); - - instances.push_back(this); - setVisible(true); - - PlayerInfo::setBuySellState(BUYSELL_SELLING); -} - -SellDialog::~SellDialog() -{ - delete mShopItems; - - instances.remove(this); - - if (PlayerInfo::getBuySellState() == BUYSELL_SELLING) - PlayerInfo::setBuySellState(BUYSELL_NONE); -} - -void SellDialog::reset() -{ - mShopItems->clear(); - mSlider->setValue(0); - - // Reset previous selected item to prevent failing asserts - mShopItemList->setSelected(-1); - - updateButtonsAndLabels(); -} - -void SellDialog::addItem(const Item *item, int price) -{ - if (!item) - return; - - mShopItems->addItem(item->getInvIndex(), item->getId(), - item->getQuantity(), price); - - mShopItemList->adjustSize(); -} - -void SellDialog::action(const gcn::ActionEvent &event) -{ - if (event.getId() == "quit") - { - close(); - return; - } - - int selectedItem = mShopItemList->getSelected(); - - // The following actions require a valid item selection - if (selectedItem == -1 || - selectedItem >= (int) mShopItems->getNumberOfElements()) - { - return; - } - - if (event.getId() == "slider") - { - mAmountItems = (int) mSlider->getValue(); - updateButtonsAndLabels(); - } - else if (event.getId() == "inc" && mAmountItems < mMaxItems) - { - mAmountItems++; - mSlider->setValue(mAmountItems); - updateButtonsAndLabels(); - } - else if (event.getId() == "dec" && mAmountItems > 1) - { - mAmountItems--; - mSlider->setValue(mAmountItems); - updateButtonsAndLabels(); - } - else if (event.getId() == "max") - { - mAmountItems = mMaxItems; - mSlider->setValue(mAmountItems); - updateButtonsAndLabels(); - } - else if (event.getId() == "sell" && mAmountItems > 0 - && mAmountItems <= mMaxItems) - { - // Attempt sell - ShopItem *item = mShopItems->at(selectedItem); - int sellCount, itemIndex; - mPlayerMoney += - mAmountItems * mShopItems->at(selectedItem)->getPrice(); - mMaxItems -= mAmountItems; - while (mAmountItems > 0) - { - // This order is important, item->getCurrentInvIndex() would return - // the inventory index of the next Duplicate otherwise. - itemIndex = item->getCurrentInvIndex(); - sellCount = item->sellCurrentDuplicate(mAmountItems); - - // For Manaserv, the Item id is to be given as index. - if ((Net::getNetworkType() == ServerInfo::MANASERV)) - itemIndex = item->getId(); - - Net::getNpcHandler()->sellItem(mNpcId, itemIndex, sellCount); - mAmountItems -= sellCount; - } - - mPlayerMoney += - mAmountItems * mShopItems->at(selectedItem)->getPrice(); - mAmountItems = 1; - mSlider->setValue(0); - - if (!mMaxItems) - { - // All were sold - mShopItemList->setSelected(-1); - delete mShopItems->at(selectedItem); - mShopItems->erase(selectedItem); - - gcn::Rectangle scroll; - scroll.y = mShopItemList->getRowHeight() * (selectedItem + 1); - scroll.height = mShopItemList->getRowHeight(); - mShopItemList->showPart(scroll); - } - else - { - mSlider->gcn::Slider::setScale(1, mMaxItems); - // Update only when there are items left, the entry doesn't exist - // otherwise and can't be updated - updateButtonsAndLabels(); - } - } -} - -void SellDialog::valueChanged(const gcn::SelectionEvent &event) -{ - // Reset amount of items and update labels - mAmountItems = 1; - mSlider->setValue(0); - - updateButtonsAndLabels(); - mSlider->gcn::Slider::setScale(1, mMaxItems); -} - -void SellDialog::mouseClicked(gcn::MouseEvent &mouseEvent) -{ - if (mouseEvent.getSource() == mShopItemList && - isDoubleClick(mShopItemList->getSelected())) - { - action(gcn::ActionEvent(mSellButton, mSellButton->getActionEventId())); - } -} - -void SellDialog::setMoney(int amount) -{ - mPlayerMoney = amount; - mShopItemList->setPlayersMoney(amount); - - updateButtonsAndLabels(); -} - -void SellDialog::updateButtonsAndLabels() -{ - int selectedItem = mShopItemList->getSelected(); - int income = 0; - - if (selectedItem > -1) - { - mMaxItems = mShopItems->at(selectedItem)->getQuantity(); - if (mAmountItems > mMaxItems) - { - mAmountItems = mMaxItems; - } - - income = mAmountItems * mShopItems->at(selectedItem)->getPrice(); - } - else - { - mMaxItems = 0; - mAmountItems = 0; - } - - // Update Buttons and slider - mSellButton->setEnabled(mAmountItems > 0); - mDecreaseButton->setEnabled(mAmountItems > 1); - mIncreaseButton->setEnabled(mAmountItems < mMaxItems); - mSlider->setEnabled(mMaxItems > 1); - - // Update the quantity and money labels - mQuantityLabel->setCaption(strprintf("%d / %d", mAmountItems, mMaxItems)); - mMoneyLabel->setCaption(strprintf(_("Price: %s / Total: %s"), - Units::formatCurrency(income).c_str(), - Units::formatCurrency(mPlayerMoney + income).c_str())); -} - -void SellDialog::setVisible(bool visible) -{ - Window::setVisible(visible); - - if (visible) - { - mShopItemList->requestFocus(); - } - else - { - scheduleDelete(); - } -} - -void SellDialog::closeAll() -{ - DialogList::iterator it = instances.begin(); - DialogList::iterator it_end = instances.end(); - - for (; it != it_end; it++) - { - (*it)->close(); - } -} diff --git a/src/gui/sell.h b/src/gui/sell.h deleted file mode 100644 index e28b0744..00000000 --- a/src/gui/sell.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * The Mana Client - * Copyright (C) 2004-2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers - * - * This file is part of The Mana Client. - * - * 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, see . - */ - -#ifndef SELL_H -#define SELL_H - -#include "gui/widgets/window.h" - -#include -#include - -class Item; -class ShopItems; -class ShopListBox; - -/** - * The sell dialog. - * - * \ingroup Interface - */ -class SellDialog : public Window, gcn::ActionListener, gcn::SelectionListener -{ - public: - SellDialog(int npcId); - - virtual ~SellDialog(); - - /** - * Resets the dialog, clearing inventory. - */ - void reset(); - - /** - * Adds an item to the inventory. - */ - void addItem(const Item *item, int price); - - /** - * Called when receiving actions from the widgets. - */ - void action(const gcn::ActionEvent &event); - - /** - * Updates labels according to selected item. - * - * @see SelectionListener::selectionChanged - */ - void valueChanged(const gcn::SelectionEvent &event); - - /** - * Allows for quick-selling by extending double-click events. - */ - void mouseClicked(gcn::MouseEvent &mouseEvent); - - /** - * Gives Player's Money amount - */ - void setMoney(int amount); - - /** - * Sets the visibility of this window. - */ - void setVisible(bool visible); - - /** - * Closes all instances. - */ - static void closeAll(); - - private: - typedef std::list DialogList; - static DialogList instances; - - /** - * Updates the state of buttons and labels. - */ - void updateButtonsAndLabels(); - - int mNpcId; - - gcn::Button *mSellButton; - gcn::Button *mQuitButton; - gcn::Button *mAddMaxButton; - gcn::Button *mIncreaseButton; - gcn::Button *mDecreaseButton; - ShopListBox *mShopItemList; - gcn::ScrollArea *mScrollArea; - gcn::Label *mMoneyLabel; - gcn::Label *mQuantityLabel; - gcn::Slider *mSlider; - - ShopItems *mShopItems; - int mPlayerMoney; - - int mMaxItems; - int mAmountItems; -}; - -#endif diff --git a/src/gui/selldialog.cpp b/src/gui/selldialog.cpp new file mode 100644 index 00000000..f8b497ea --- /dev/null +++ b/src/gui/selldialog.cpp @@ -0,0 +1,326 @@ +/* + * The Mana Client + * Copyright (C) 2004-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * + * This file is part of The Mana Client. + * + * 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, see . + */ + +#include "gui/selldialog.h" + +#include "client.h" +#include "playerinfo.h" +#include "shopitem.h" +#include "units.h" + +#include "gui/setup.h" + +#include "gui/widgets/button.h" +#include "gui/widgets/label.h" +#include "gui/widgets/layout.h" +#include "gui/widgets/scrollarea.h" +#include "gui/widgets/shopitems.h" +#include "gui/widgets/shoplistbox.h" +#include "gui/widgets/slider.h" + +#include "net/net.h" +#include "net/npchandler.h" + +#include "resources/iteminfo.h" + +#include "utils/gettext.h" +#include "utils/stringutils.h" + +SellDialog::DialogList SellDialog::instances; + +SellDialog::SellDialog(int npcId): + Window(_("Sell")), + mNpcId(npcId), mMaxItems(0), mAmountItems(0) +{ + setWindowName("Sell"); + //setupWindow->registerWindowForReset(this); + setResizable(true); + setCloseButton(true); + setMinWidth(260); + setMinHeight(230); + setDefaultSize(260, 230, ImageRect::CENTER); + + // Create a ShopItems instance, that is aware of duplicate entries. + mShopItems = new ShopItems(true); + + mShopItemList = new ShopListBox(mShopItems, mShopItems); + mScrollArea = new ScrollArea(mShopItemList); + mScrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); + + mSlider = new Slider(1.0); + + mQuantityLabel = new Label(strprintf("%d / %d", mAmountItems, mMaxItems)); + mQuantityLabel->setAlignment(gcn::Graphics::CENTER); + mMoneyLabel = new Label(strprintf(_("Price: %s / Total: %s"), + "", "")); + + mIncreaseButton = new Button(_("+"), "inc", this); + mDecreaseButton = new Button(_("-"), "dec", this); + mSellButton = new Button(_("Sell"), "sell", this); + mQuitButton = new Button(_("Quit"), "quit", this); + mAddMaxButton = new Button(_("Max"), "max", this); + + mDecreaseButton->adjustSize(); + mDecreaseButton->setWidth(mIncreaseButton->getWidth()); + + mIncreaseButton->setEnabled(false); + mDecreaseButton->setEnabled(false); + mSellButton->setEnabled(false); + mSlider->setEnabled(false); + + mShopItemList->setPriceCheck(false); + mShopItemList->addSelectionListener(this); + mSlider->setActionEventId("slider"); + mSlider->addActionListener(this); + + ContainerPlacer place; + place = getPlacer(0, 0); + + place(0, 0, mScrollArea, 8, 5).setPadding(3); + place(0, 5, mDecreaseButton); + place(1, 5, mSlider, 3); + place(4, 5, mIncreaseButton); + place(5, 5, mQuantityLabel, 2); + place(7, 5, mAddMaxButton); + place(0, 6, mMoneyLabel, 8); + place(6, 7, mSellButton); + place(7, 7, mQuitButton); + + Layout &layout = getLayout(); + layout.setRowHeight(0, Layout::AUTO_SET); + + center(); + loadWindowState(); + + instances.push_back(this); + setVisible(true); + + PlayerInfo::setBuySellState(BUYSELL_SELLING); +} + +SellDialog::~SellDialog() +{ + delete mShopItems; + + instances.remove(this); + + if (PlayerInfo::getBuySellState() == BUYSELL_SELLING) + PlayerInfo::setBuySellState(BUYSELL_NONE); +} + +void SellDialog::reset() +{ + mShopItems->clear(); + mSlider->setValue(0); + + // Reset previous selected item to prevent failing asserts + mShopItemList->setSelected(-1); + + updateButtonsAndLabels(); +} + +void SellDialog::addItem(const Item *item, int price) +{ + if (!item) + return; + + mShopItems->addItem(item->getInvIndex(), item->getId(), + item->getQuantity(), price); + + mShopItemList->adjustSize(); +} + +void SellDialog::action(const gcn::ActionEvent &event) +{ + if (event.getId() == "quit") + { + close(); + return; + } + + int selectedItem = mShopItemList->getSelected(); + + // The following actions require a valid item selection + if (selectedItem == -1 || + selectedItem >= (int) mShopItems->getNumberOfElements()) + { + return; + } + + if (event.getId() == "slider") + { + mAmountItems = (int) mSlider->getValue(); + updateButtonsAndLabels(); + } + else if (event.getId() == "inc" && mAmountItems < mMaxItems) + { + mAmountItems++; + mSlider->setValue(mAmountItems); + updateButtonsAndLabels(); + } + else if (event.getId() == "dec" && mAmountItems > 1) + { + mAmountItems--; + mSlider->setValue(mAmountItems); + updateButtonsAndLabels(); + } + else if (event.getId() == "max") + { + mAmountItems = mMaxItems; + mSlider->setValue(mAmountItems); + updateButtonsAndLabels(); + } + else if (event.getId() == "sell" && mAmountItems > 0 + && mAmountItems <= mMaxItems) + { + // Attempt sell + ShopItem *item = mShopItems->at(selectedItem); + int sellCount, itemIndex; + mPlayerMoney += + mAmountItems * mShopItems->at(selectedItem)->getPrice(); + mMaxItems -= mAmountItems; + while (mAmountItems > 0) + { + // This order is important, item->getCurrentInvIndex() would return + // the inventory index of the next Duplicate otherwise. + itemIndex = item->getCurrentInvIndex(); + sellCount = item->sellCurrentDuplicate(mAmountItems); + + // For Manaserv, the Item id is to be given as index. + if ((Net::getNetworkType() == ServerInfo::MANASERV)) + itemIndex = item->getId(); + + Net::getNpcHandler()->sellItem(mNpcId, itemIndex, sellCount); + mAmountItems -= sellCount; + } + + mPlayerMoney += + mAmountItems * mShopItems->at(selectedItem)->getPrice(); + mAmountItems = 1; + mSlider->setValue(0); + + if (!mMaxItems) + { + // All were sold + mShopItemList->setSelected(-1); + delete mShopItems->at(selectedItem); + mShopItems->erase(selectedItem); + + gcn::Rectangle scroll; + scroll.y = mShopItemList->getRowHeight() * (selectedItem + 1); + scroll.height = mShopItemList->getRowHeight(); + mShopItemList->showPart(scroll); + } + else + { + mSlider->gcn::Slider::setScale(1, mMaxItems); + // Update only when there are items left, the entry doesn't exist + // otherwise and can't be updated + updateButtonsAndLabels(); + } + } +} + +void SellDialog::valueChanged(const gcn::SelectionEvent &event) +{ + // Reset amount of items and update labels + mAmountItems = 1; + mSlider->setValue(0); + + updateButtonsAndLabels(); + mSlider->gcn::Slider::setScale(1, mMaxItems); +} + +void SellDialog::mouseClicked(gcn::MouseEvent &mouseEvent) +{ + if (mouseEvent.getSource() == mShopItemList && + isDoubleClick(mShopItemList->getSelected())) + { + action(gcn::ActionEvent(mSellButton, mSellButton->getActionEventId())); + } +} + +void SellDialog::setMoney(int amount) +{ + mPlayerMoney = amount; + mShopItemList->setPlayersMoney(amount); + + updateButtonsAndLabels(); +} + +void SellDialog::updateButtonsAndLabels() +{ + int selectedItem = mShopItemList->getSelected(); + int income = 0; + + if (selectedItem > -1) + { + mMaxItems = mShopItems->at(selectedItem)->getQuantity(); + if (mAmountItems > mMaxItems) + { + mAmountItems = mMaxItems; + } + + income = mAmountItems * mShopItems->at(selectedItem)->getPrice(); + } + else + { + mMaxItems = 0; + mAmountItems = 0; + } + + // Update Buttons and slider + mSellButton->setEnabled(mAmountItems > 0); + mDecreaseButton->setEnabled(mAmountItems > 1); + mIncreaseButton->setEnabled(mAmountItems < mMaxItems); + mSlider->setEnabled(mMaxItems > 1); + + // Update the quantity and money labels + mQuantityLabel->setCaption(strprintf("%d / %d", mAmountItems, mMaxItems)); + mMoneyLabel->setCaption(strprintf(_("Price: %s / Total: %s"), + Units::formatCurrency(income).c_str(), + Units::formatCurrency(mPlayerMoney + income).c_str())); +} + +void SellDialog::setVisible(bool visible) +{ + Window::setVisible(visible); + + if (visible) + { + mShopItemList->requestFocus(); + } + else + { + scheduleDelete(); + } +} + +void SellDialog::closeAll() +{ + DialogList::iterator it = instances.begin(); + DialogList::iterator it_end = instances.end(); + + for (; it != it_end; it++) + { + (*it)->close(); + } +} diff --git a/src/gui/selldialog.h b/src/gui/selldialog.h new file mode 100644 index 00000000..e28b0744 --- /dev/null +++ b/src/gui/selldialog.h @@ -0,0 +1,117 @@ +/* + * The Mana Client + * Copyright (C) 2004-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * + * This file is part of The Mana Client. + * + * 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, see . + */ + +#ifndef SELL_H +#define SELL_H + +#include "gui/widgets/window.h" + +#include +#include + +class Item; +class ShopItems; +class ShopListBox; + +/** + * The sell dialog. + * + * \ingroup Interface + */ +class SellDialog : public Window, gcn::ActionListener, gcn::SelectionListener +{ + public: + SellDialog(int npcId); + + virtual ~SellDialog(); + + /** + * Resets the dialog, clearing inventory. + */ + void reset(); + + /** + * Adds an item to the inventory. + */ + void addItem(const Item *item, int price); + + /** + * Called when receiving actions from the widgets. + */ + void action(const gcn::ActionEvent &event); + + /** + * Updates labels according to selected item. + * + * @see SelectionListener::selectionChanged + */ + void valueChanged(const gcn::SelectionEvent &event); + + /** + * Allows for quick-selling by extending double-click events. + */ + void mouseClicked(gcn::MouseEvent &mouseEvent); + + /** + * Gives Player's Money amount + */ + void setMoney(int amount); + + /** + * Sets the visibility of this window. + */ + void setVisible(bool visible); + + /** + * Closes all instances. + */ + static void closeAll(); + + private: + typedef std::list DialogList; + static DialogList instances; + + /** + * Updates the state of buttons and labels. + */ + void updateButtonsAndLabels(); + + int mNpcId; + + gcn::Button *mSellButton; + gcn::Button *mQuitButton; + gcn::Button *mAddMaxButton; + gcn::Button *mIncreaseButton; + gcn::Button *mDecreaseButton; + ShopListBox *mShopItemList; + gcn::ScrollArea *mScrollArea; + gcn::Label *mMoneyLabel; + gcn::Label *mQuantityLabel; + gcn::Slider *mSlider; + + ShopItems *mShopItems; + int mPlayerMoney; + + int mMaxItems; + int mAmountItems; +}; + +#endif diff --git a/src/gui/serverdialog.cpp b/src/gui/serverdialog.cpp index 2bb0e0dc..78a86d24 100644 --- a/src/gui/serverdialog.cpp +++ b/src/gui/serverdialog.cpp @@ -21,7 +21,7 @@ #include "gui/serverdialog.h" -#include "chatlog.h" +#include "chatlogger.h" #include "client.h" #include "configuration.h" #include "gui.h" diff --git a/src/gui/trade.cpp b/src/gui/trade.cpp deleted file mode 100644 index 37662bef..00000000 --- a/src/gui/trade.cpp +++ /dev/null @@ -1,315 +0,0 @@ -/* - * The Mana Client - * Copyright (C) 2004-2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers - * - * This file is part of The Mana Client. - * - * 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, see . - */ - -#include "gui/trade.h" - -#include "event.h" -#include "inventory.h" -#include "item.h" -#include "localplayer.h" -#include "playerinfo.h" -#include "units.h" - -#include "gui/inventorywindow.h" -#include "gui/itemamount.h" -#include "gui/setup.h" - -#include "gui/widgets/button.h" -#include "gui/widgets/itemcontainer.h" -#include "gui/widgets/label.h" -#include "gui/widgets/scrollarea.h" -#include "gui/widgets/textfield.h" -#include "gui/widgets/layout.h" - -#include "net/inventoryhandler.h" -#include "net/net.h" -#include "net/tradehandler.h" - -#include "utils/gettext.h" -#include "utils/stringutils.h" - -#include - -#include - -#define CAPTION_PROPOSE _("Propose trade") -#define CAPTION_CONFIRMED _("Confirmed. Waiting...") -#define CAPTION_ACCEPT _("Agree trade") -#define CAPTION_ACCEPTED _("Agreed. Waiting...") - -TradeWindow::TradeWindow(): - Window(_("Trade: You")), - mMyInventory(new Inventory(Inventory::TRADE)), - mPartnerInventory(new Inventory(Inventory::TRADE)), - mStatus(PROPOSING) -{ - setWindowName("Trade"); - setResizable(true); - setCloseButton(true); - setDefaultSize(386, 180, ImageRect::CENTER); - setMinWidth(386); - setMinHeight(180); - setupWindow->registerWindowForReset(this); - - std::string longestName = getFont()->getWidth(_("OK")) > - getFont()->getWidth(_("Trade")) ? - _("OK") : _("Trade"); - - mAddButton = new Button(_("Add"), "add", this); - mOkButton = new Button("", "", this); // Will be filled in later - - int width = std::max(mOkButton->getFont()->getWidth(CAPTION_PROPOSE), - mOkButton->getFont()->getWidth(CAPTION_CONFIRMED)); - width = std::max(width, mOkButton->getFont()->getWidth(CAPTION_ACCEPT)); - width = std::max(width, mOkButton->getFont()->getWidth(CAPTION_ACCEPTED)); - - mOkButton->setWidth(8 + width); - - mMyItemContainer = new ItemContainer(mMyInventory.get()); - mMyItemContainer->addSelectionListener(this); - - ScrollArea *myScroll = new ScrollArea(mMyItemContainer); - myScroll->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); - - mPartnerItemContainer = new ItemContainer(mPartnerInventory.get()); - mPartnerItemContainer->addSelectionListener(this); - - ScrollArea *partnerScroll = new ScrollArea(mPartnerItemContainer); - partnerScroll->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); - - mMoneyLabel = new Label(strprintf(_("You get %s"), "")); - gcn::Label *mMoneyLabel2 = new Label(_("You give:")); - - mMoneyField = new TextField; - mMoneyField->setWidth(40); - mMoneyChangeButton = new Button(_("Change"), "money", this); - - place(1, 0, mMoneyLabel); - place(0, 1, myScroll).setPadding(3); - place(1, 1, partnerScroll).setPadding(3); - ContainerPlacer place; - place = getPlacer(0, 0); - place(0, 0, mMoneyLabel2); - place(1, 0, mMoneyField); - place(2, 0, mMoneyChangeButton).setHAlign(LayoutCell::LEFT); - place = getPlacer(0, 2); - place(0, 0, mAddButton); - place(1, 0, mOkButton); - Layout &layout = getLayout(); - layout.extend(0, 2, 2, 1); - layout.setRowHeight(1, Layout::AUTO_SET); - layout.setRowHeight(2, 0); - layout.setColWidth(0, Layout::AUTO_SET); - layout.setColWidth(1, Layout::AUTO_SET); - - loadWindowState(); - - reset(); -} - -TradeWindow::~TradeWindow() -{ -} - -void TradeWindow::setMoney(int amount) -{ - mMoneyLabel->setCaption(strprintf(_("You get %s"), - Units::formatCurrency(amount).c_str())); - mMoneyLabel->adjustSize(); -} - -void TradeWindow::addItem(int id, bool own, int quantity) -{ - (own ? mMyInventory : mPartnerInventory)->addItem(id, quantity); -} - -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); -} - -void TradeWindow::reset() -{ - mMyInventory->clear(); - mPartnerInventory->clear(); - mOkOther = false; - mOkMe = false; - setMoney(0); - mMoneyField->setEnabled(true); - mMoneyField->setText(""); - mAddButton->setEnabled(true); - mMoneyChangeButton->setEnabled(true); - setStatus(PREPARING); -} - -void TradeWindow::receivedOk(bool own) -{ - if (own) - mOkMe = true; - else - mOkOther = true; - - if (mOkMe && mOkOther) - { - //mOkMe = false; - //mOkOther = false; - setStatus(ACCEPTING); - } -} - -void TradeWindow::tradeItem(Item *item, int quantity) -{ - Net::getTradeHandler()->addItem(item, quantity); -} - -void TradeWindow::valueChanged(const gcn::SelectionEvent &event) -{ - 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->getSelectedItem())) - mPartnerItemContainer->selectNone(); - else if ((item = mPartnerItemContainer->getSelectedItem())) - mMyItemContainer->selectNone(); -} - -void TradeWindow::setStatus(Status s) -{ - if (s == mStatus) - return; - mStatus = s; - - switch (s) - { - case PREPARING: - mOkButton->setCaption(CAPTION_PROPOSE); - mOkButton->setActionEventId("ok"); - break; - case PROPOSING: - mOkButton->setCaption(CAPTION_CONFIRMED); - mOkButton->setActionEventId(""); - break; - case ACCEPTING: - mOkButton->setCaption(CAPTION_ACCEPT); - mOkButton->setActionEventId("trade"); - break; - case ACCEPTED: - mOkButton->setCaption(CAPTION_ACCEPTED); - mOkButton->setActionEventId(""); - break; - default: - break; - } - - mOkButton->setEnabled((s != PROPOSING && s != ACCEPTED)); -} - -void TradeWindow::action(const gcn::ActionEvent &event) -{ - Item *item = inventoryWindow->getSelectedItem(); - - if (event.getId() == "add") - { - if (mStatus != PREPARING) - return; - - if (!inventoryWindow->isVisible()) - { - inventoryWindow->setVisible(true); - return; - } - - if (!item) - return; - - if (mMyInventory->getFreeSlot() == -1) - return; - - if (mMyInventory->contains(item)) - { - SERVER_NOTICE(_("Failed adding item. You can not " - "overlap one kind of item on the window.")) - return; - } - - // Choose amount of items to trade - ItemAmountWindow::showWindow(ItemAmountWindow::TradeAdd, this, item); - - setStatus(PREPARING); - } - else if (event.getId() == "cancel") - { - setVisible(false); - reset(); - PlayerInfo::setTrading(false); - - Net::getTradeHandler()->cancel(); - } - else if (event.getId() == "ok") - { - mMoneyField->setEnabled(false); - mAddButton->setEnabled(false); - mMoneyChangeButton->setEnabled(false); - receivedOk(true); - setStatus(PROPOSING); - Net::getTradeHandler()->confirm(); - } - else if (event.getId() == "trade") - { - receivedOk(true); - setStatus(ACCEPTED); - Net::getTradeHandler()->finish(); - } - else if (event.getId() == "money") - { - if (mStatus != PREPARING) - return; - - int v = atoi(mMoneyField->getText().c_str()); - int curMoney = PlayerInfo::getAttribute(MONEY); - if (v > curMoney) - { - SERVER_NOTICE(_("You don't have enough money.")) - v = curMoney; - } - Net::getTradeHandler()->setMoney(v); - mMoneyField->setText(strprintf("%d", v)); - } -} - -void TradeWindow::close() -{ - Net::getTradeHandler()->cancel(); -} diff --git a/src/gui/trade.h b/src/gui/trade.h deleted file mode 100644 index f854d698..00000000 --- a/src/gui/trade.h +++ /dev/null @@ -1,139 +0,0 @@ -/* - * The Mana Client - * Copyright (C) 2004-2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers - * - * This file is part of The Mana Client. - * - * 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, see . - */ - -#ifndef TRADE_H -#define TRADE_H - -#include "gui/widgets/window.h" - -#include -#include - -#include - -class Inventory; -class Item; -class ItemContainer; -class ScrollArea; - -/** - * Trade dialog. - * - * \ingroup Interface - */ -class TradeWindow : public Window, gcn::ActionListener, gcn::SelectionListener -{ - public: - TradeWindow(); - - ~TradeWindow(); - - /** - * Displays expected money in the trade window. - */ - void setMoney(int quantity); - - /** - * Add an item to the trade window. - */ - void addItem(int id, bool own, int quantity); - - /** - * Reset both item containers - */ - void reset(); - - /** - * 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); - - /** - * Player received ok message from server - */ - void receivedOk(bool own); - - /** - * Send trade packet. - */ - void tradeItem(Item *item, int quantity); - - /** - * Updates the labels and makes sure only one item is selected in - * either my inventory or partner inventory. - */ - void valueChanged(const gcn::SelectionEvent &event); - - /** - * Called when receiving actions from the widgets. - */ - void action(const gcn::ActionEvent &event); - - /** - * Closes the Trade Window, as well as telling the server that the - * window has been closed. - */ - void close(); - - private: - enum Status - { - PREPARING, /**< Players are adding items. (1) */ - PROPOSING, /**< Local player has confirmed the trade. (1) */ - ACCEPTING, /**< Accepting the trade. (2) */ - ACCEPTED /**< Local player has accepted the trade. */ - }; - - /** - * Sets the current status of the trade. - */ - void setStatus(Status s); - - typedef const std::auto_ptr InventoryPtr; - InventoryPtr mMyInventory; - InventoryPtr mPartnerInventory; - - ItemContainer *mMyItemContainer; - ItemContainer *mPartnerItemContainer; - - gcn::Label *mMoneyLabel; - gcn::Button *mAddButton; - gcn::Button *mOkButton; - gcn::Button *mMoneyChangeButton; - gcn::TextField *mMoneyField; - - Status mStatus; - bool mOkOther, mOkMe; -}; - -extern TradeWindow *tradeWindow; - -#endif diff --git a/src/gui/tradewindow.cpp b/src/gui/tradewindow.cpp new file mode 100644 index 00000000..16b66c1d --- /dev/null +++ b/src/gui/tradewindow.cpp @@ -0,0 +1,315 @@ +/* + * The Mana Client + * Copyright (C) 2004-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * + * This file is part of The Mana Client. + * + * 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, see . + */ + +#include "gui/tradewindow.h" + +#include "event.h" +#include "inventory.h" +#include "item.h" +#include "localplayer.h" +#include "playerinfo.h" +#include "units.h" + +#include "gui/inventorywindow.h" +#include "gui/itemamountwindow.h" +#include "gui/setup.h" + +#include "gui/widgets/button.h" +#include "gui/widgets/itemcontainer.h" +#include "gui/widgets/label.h" +#include "gui/widgets/scrollarea.h" +#include "gui/widgets/textfield.h" +#include "gui/widgets/layout.h" + +#include "net/inventoryhandler.h" +#include "net/net.h" +#include "net/tradehandler.h" + +#include "utils/gettext.h" +#include "utils/stringutils.h" + +#include + +#include + +#define CAPTION_PROPOSE _("Propose trade") +#define CAPTION_CONFIRMED _("Confirmed. Waiting...") +#define CAPTION_ACCEPT _("Agree trade") +#define CAPTION_ACCEPTED _("Agreed. Waiting...") + +TradeWindow::TradeWindow(): + Window(_("Trade: You")), + mMyInventory(new Inventory(Inventory::TRADE)), + mPartnerInventory(new Inventory(Inventory::TRADE)), + mStatus(PROPOSING) +{ + setWindowName("Trade"); + setResizable(true); + setCloseButton(true); + setDefaultSize(386, 180, ImageRect::CENTER); + setMinWidth(386); + setMinHeight(180); + setupWindow->registerWindowForReset(this); + + std::string longestName = getFont()->getWidth(_("OK")) > + getFont()->getWidth(_("Trade")) ? + _("OK") : _("Trade"); + + mAddButton = new Button(_("Add"), "add", this); + mOkButton = new Button("", "", this); // Will be filled in later + + int width = std::max(mOkButton->getFont()->getWidth(CAPTION_PROPOSE), + mOkButton->getFont()->getWidth(CAPTION_CONFIRMED)); + width = std::max(width, mOkButton->getFont()->getWidth(CAPTION_ACCEPT)); + width = std::max(width, mOkButton->getFont()->getWidth(CAPTION_ACCEPTED)); + + mOkButton->setWidth(8 + width); + + mMyItemContainer = new ItemContainer(mMyInventory.get()); + mMyItemContainer->addSelectionListener(this); + + ScrollArea *myScroll = new ScrollArea(mMyItemContainer); + myScroll->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); + + mPartnerItemContainer = new ItemContainer(mPartnerInventory.get()); + mPartnerItemContainer->addSelectionListener(this); + + ScrollArea *partnerScroll = new ScrollArea(mPartnerItemContainer); + partnerScroll->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); + + mMoneyLabel = new Label(strprintf(_("You get %s"), "")); + gcn::Label *mMoneyLabel2 = new Label(_("You give:")); + + mMoneyField = new TextField; + mMoneyField->setWidth(40); + mMoneyChangeButton = new Button(_("Change"), "money", this); + + place(1, 0, mMoneyLabel); + place(0, 1, myScroll).setPadding(3); + place(1, 1, partnerScroll).setPadding(3); + ContainerPlacer place; + place = getPlacer(0, 0); + place(0, 0, mMoneyLabel2); + place(1, 0, mMoneyField); + place(2, 0, mMoneyChangeButton).setHAlign(LayoutCell::LEFT); + place = getPlacer(0, 2); + place(0, 0, mAddButton); + place(1, 0, mOkButton); + Layout &layout = getLayout(); + layout.extend(0, 2, 2, 1); + layout.setRowHeight(1, Layout::AUTO_SET); + layout.setRowHeight(2, 0); + layout.setColWidth(0, Layout::AUTO_SET); + layout.setColWidth(1, Layout::AUTO_SET); + + loadWindowState(); + + reset(); +} + +TradeWindow::~TradeWindow() +{ +} + +void TradeWindow::setMoney(int amount) +{ + mMoneyLabel->setCaption(strprintf(_("You get %s"), + Units::formatCurrency(amount).c_str())); + mMoneyLabel->adjustSize(); +} + +void TradeWindow::addItem(int id, bool own, int quantity) +{ + (own ? mMyInventory : mPartnerInventory)->addItem(id, quantity); +} + +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); +} + +void TradeWindow::reset() +{ + mMyInventory->clear(); + mPartnerInventory->clear(); + mOkOther = false; + mOkMe = false; + setMoney(0); + mMoneyField->setEnabled(true); + mMoneyField->setText(""); + mAddButton->setEnabled(true); + mMoneyChangeButton->setEnabled(true); + setStatus(PREPARING); +} + +void TradeWindow::receivedOk(bool own) +{ + if (own) + mOkMe = true; + else + mOkOther = true; + + if (mOkMe && mOkOther) + { + //mOkMe = false; + //mOkOther = false; + setStatus(ACCEPTING); + } +} + +void TradeWindow::tradeItem(Item *item, int quantity) +{ + Net::getTradeHandler()->addItem(item, quantity); +} + +void TradeWindow::valueChanged(const gcn::SelectionEvent &event) +{ + 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->getSelectedItem())) + mPartnerItemContainer->selectNone(); + else if ((item = mPartnerItemContainer->getSelectedItem())) + mMyItemContainer->selectNone(); +} + +void TradeWindow::setStatus(Status s) +{ + if (s == mStatus) + return; + mStatus = s; + + switch (s) + { + case PREPARING: + mOkButton->setCaption(CAPTION_PROPOSE); + mOkButton->setActionEventId("ok"); + break; + case PROPOSING: + mOkButton->setCaption(CAPTION_CONFIRMED); + mOkButton->setActionEventId(""); + break; + case ACCEPTING: + mOkButton->setCaption(CAPTION_ACCEPT); + mOkButton->setActionEventId("trade"); + break; + case ACCEPTED: + mOkButton->setCaption(CAPTION_ACCEPTED); + mOkButton->setActionEventId(""); + break; + default: + break; + } + + mOkButton->setEnabled((s != PROPOSING && s != ACCEPTED)); +} + +void TradeWindow::action(const gcn::ActionEvent &event) +{ + Item *item = inventoryWindow->getSelectedItem(); + + if (event.getId() == "add") + { + if (mStatus != PREPARING) + return; + + if (!inventoryWindow->isVisible()) + { + inventoryWindow->setVisible(true); + return; + } + + if (!item) + return; + + if (mMyInventory->getFreeSlot() == -1) + return; + + if (mMyInventory->contains(item)) + { + SERVER_NOTICE(_("Failed adding item. You can not " + "overlap one kind of item on the window.")) + return; + } + + // Choose amount of items to trade + ItemAmountWindow::showWindow(ItemAmountWindow::TradeAdd, this, item); + + setStatus(PREPARING); + } + else if (event.getId() == "cancel") + { + setVisible(false); + reset(); + PlayerInfo::setTrading(false); + + Net::getTradeHandler()->cancel(); + } + else if (event.getId() == "ok") + { + mMoneyField->setEnabled(false); + mAddButton->setEnabled(false); + mMoneyChangeButton->setEnabled(false); + receivedOk(true); + setStatus(PROPOSING); + Net::getTradeHandler()->confirm(); + } + else if (event.getId() == "trade") + { + receivedOk(true); + setStatus(ACCEPTED); + Net::getTradeHandler()->finish(); + } + else if (event.getId() == "money") + { + if (mStatus != PREPARING) + return; + + int v = atoi(mMoneyField->getText().c_str()); + int curMoney = PlayerInfo::getAttribute(MONEY); + if (v > curMoney) + { + SERVER_NOTICE(_("You don't have enough money.")) + v = curMoney; + } + Net::getTradeHandler()->setMoney(v); + mMoneyField->setText(strprintf("%d", v)); + } +} + +void TradeWindow::close() +{ + Net::getTradeHandler()->cancel(); +} diff --git a/src/gui/tradewindow.h b/src/gui/tradewindow.h new file mode 100644 index 00000000..f854d698 --- /dev/null +++ b/src/gui/tradewindow.h @@ -0,0 +1,139 @@ +/* + * The Mana Client + * Copyright (C) 2004-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * + * This file is part of The Mana Client. + * + * 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, see . + */ + +#ifndef TRADE_H +#define TRADE_H + +#include "gui/widgets/window.h" + +#include +#include + +#include + +class Inventory; +class Item; +class ItemContainer; +class ScrollArea; + +/** + * Trade dialog. + * + * \ingroup Interface + */ +class TradeWindow : public Window, gcn::ActionListener, gcn::SelectionListener +{ + public: + TradeWindow(); + + ~TradeWindow(); + + /** + * Displays expected money in the trade window. + */ + void setMoney(int quantity); + + /** + * Add an item to the trade window. + */ + void addItem(int id, bool own, int quantity); + + /** + * Reset both item containers + */ + void reset(); + + /** + * 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); + + /** + * Player received ok message from server + */ + void receivedOk(bool own); + + /** + * Send trade packet. + */ + void tradeItem(Item *item, int quantity); + + /** + * Updates the labels and makes sure only one item is selected in + * either my inventory or partner inventory. + */ + void valueChanged(const gcn::SelectionEvent &event); + + /** + * Called when receiving actions from the widgets. + */ + void action(const gcn::ActionEvent &event); + + /** + * Closes the Trade Window, as well as telling the server that the + * window has been closed. + */ + void close(); + + private: + enum Status + { + PREPARING, /**< Players are adding items. (1) */ + PROPOSING, /**< Local player has confirmed the trade. (1) */ + ACCEPTING, /**< Accepting the trade. (2) */ + ACCEPTED /**< Local player has accepted the trade. */ + }; + + /** + * Sets the current status of the trade. + */ + void setStatus(Status s); + + typedef const std::auto_ptr InventoryPtr; + InventoryPtr mMyInventory; + InventoryPtr mPartnerInventory; + + ItemContainer *mMyItemContainer; + ItemContainer *mPartnerItemContainer; + + gcn::Label *mMoneyLabel; + gcn::Button *mAddButton; + gcn::Button *mOkButton; + gcn::Button *mMoneyChangeButton; + gcn::TextField *mMoneyField; + + Status mStatus; + bool mOkOther, mOkMe; +}; + +extern TradeWindow *tradeWindow; + +#endif diff --git a/src/gui/updaterwindow.cpp b/src/gui/updaterwindow.cpp new file mode 100644 index 00000000..54373f05 --- /dev/null +++ b/src/gui/updaterwindow.cpp @@ -0,0 +1,520 @@ +/* + * The Mana Client + * Copyright (C) 2004-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * + * This file is part of The Mana Client. + * + * 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, see . + */ + +#include "gui/updaterwindow.h" + +#include "client.h" +#include "configuration.h" +#include "log.h" + +#include "gui/sdlinput.h" + +#include "gui/widgets/browserbox.h" +#include "gui/widgets/button.h" +#include "gui/widgets/label.h" +#include "gui/widgets/layout.h" +#include "gui/widgets/progressbar.h" +#include "gui/widgets/scrollarea.h" + +#include "net/download.h" + +#include "resources/resourcemanager.h" + +#include "utils/gettext.h" +#include "utils/stringutils.h" +#include "utils/xml.h" + +#include +#include + +const std::string xmlUpdateFile = "resources.xml"; +const std::string txtUpdateFile = "resources2.txt"; + +/** + * Load the given file into a vector of updateFiles. + */ +std::vector loadXMLFile(const std::string &fileName) +{ + std::vector files; + XML::Document doc(fileName, false); + xmlNodePtr rootNode = doc.rootNode(); + + if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "updates")) + { + logger->log("Error loading update file: %s", fileName.c_str()); + return files; + } + + for_each_xml_child_node(fileNode, rootNode) + { + // Ignore all tags except for the "update" tags + if (!xmlStrEqual(fileNode->name, BAD_CAST "update")) + continue; + + updateFile file; + file.name = XML::getProperty(fileNode, "file", ""); + file.hash = XML::getProperty(fileNode, "hash", ""); + file.type = XML::getProperty(fileNode, "type", "data"); + file.desc = XML::getProperty(fileNode, "description", ""); + if (XML::getProperty(fileNode, "required", "yes") == "yes") + file.required = true; + else + file.required = false; + + files.push_back(file); + } + + return files; +} + +std::vector loadTxtFile(const std::string &fileName) +{ + std::vector files; + std::ifstream fileHandler; + fileHandler.open(fileName.c_str(), std::ios::in); + + if (fileHandler.is_open()) + { + while (fileHandler.good()) + { + char name[256], hash[50]; + fileHandler.getline(name, 256, ' '); + fileHandler.getline(hash, 50); + + updateFile thisFile; + thisFile.name = name; + thisFile.hash = hash; + thisFile.type = "data"; + thisFile.required = true; + thisFile.desc = ""; + + files.push_back(thisFile); + } + } + else + { + logger->log("Error loading update file: %s", fileName.c_str()); + } + fileHandler.close(); + + return files; +} + +UpdaterWindow::UpdaterWindow(const std::string &updateHost, + const std::string &updatesDir, + bool applyUpdates): + Window(_("Updating...")), + mDownloadStatus(UPDATE_NEWS), + mUpdateHost(updateHost), + mUpdatesDir(updatesDir), + mCurrentFile("news.txt"), + mDownloadProgress(0.0f), + mCurrentChecksum(0), + mStoreInMemory(true), + mDownloadComplete(true), + mUserCancel(false), + mDownloadedBytes(0), + mMemoryBuffer(NULL), + mDownload(NULL), + mUpdateIndex(0), + mLoadUpdates(applyUpdates) +{ + mBrowserBox = new BrowserBox; + mScrollArea = new ScrollArea(mBrowserBox); + mLabel = new Label(_("Connecting...")); + mProgressBar = new ProgressBar(0.0, 310, 20); + mCancelButton = new Button(_("Cancel"), "cancel", this); + mPlayButton = new Button(_("Play"), "play", this); + + mProgressBar->setSmoothProgress(false); + mBrowserBox->setOpaque(false); + mPlayButton->setEnabled(false); + + 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); + + reflowLayout(320, 240); + + Layout &layout = getLayout(); + layout.setRowHeight(0, Layout::AUTO_SET); + + addKeyListener(this); + + center(); + setVisible(true); + mCancelButton->requestFocus(); + + // Try to download the updates list + download(); +} + +UpdaterWindow::~UpdaterWindow() +{ + if (mLoadUpdates) + loadUpdates(); + + if (mDownload) + { + mDownload->cancel(); + + delete mDownload; + mDownload = 0; + } + free(mMemoryBuffer); +} + +void UpdaterWindow::setProgress(float p) +{ + // Do delayed progress bar update, since Guichan isn't thread-safe + MutexLocker lock(&mDownloadMutex); + mDownloadProgress = p; +} + +void UpdaterWindow::setLabel(const std::string &str) +{ + // Do delayed label text update, since Guichan isn't thread-safe + MutexLocker lock(&mDownloadMutex); + mNewLabelCaption = str; +} + +void UpdaterWindow::enable() +{ + mCancelButton->setEnabled(false); + mPlayButton->setEnabled(true); + mPlayButton->requestFocus(); +} + +void UpdaterWindow::action(const gcn::ActionEvent &event) +{ + if (event.getId() == "cancel") + { + // Register the user cancel + mUserCancel = true; + // Skip the updating process + if (mDownloadStatus != UPDATE_COMPLETE) + { + mDownload->cancel(); + mDownloadStatus = UPDATE_ERROR; + } + } + else if (event.getId() == "play") + { + Client::setState(STATE_LOAD_DATA); + } +} + +void UpdaterWindow::keyPressed(gcn::KeyEvent &keyEvent) +{ + gcn::Key key = keyEvent.getKey(); + + if (key.getValue() == Key::ESCAPE) + { + action(gcn::ActionEvent(NULL, mCancelButton->getActionEventId())); + Client::setState(STATE_WORLD_SELECT); + } + else if (key.getValue() == Key::ENTER) + { + if (mDownloadStatus == UPDATE_COMPLETE || + mDownloadStatus == UPDATE_ERROR) + { + action(gcn::ActionEvent(NULL, mPlayButton->getActionEventId())); + } + else + { + action(gcn::ActionEvent(NULL, mCancelButton->getActionEventId())); + } + } +} + +void UpdaterWindow::loadNews() +{ + if (!mMemoryBuffer) + { + logger->log("Couldn't load news"); + return; + } + + // Reallocate and include terminating 0 character + mMemoryBuffer = (char*)realloc(mMemoryBuffer, mDownloadedBytes + 1); + mMemoryBuffer[mDownloadedBytes] = '\0'; + + mBrowserBox->clearRows(); + + // Tokenize and add each line separately + char *line = strtok(mMemoryBuffer, "\n"); + while (line) + { + mBrowserBox->addRow(line); + line = strtok(NULL, "\n"); + } + + // Free the memory buffer now that we don't need it anymore + free(mMemoryBuffer); + mMemoryBuffer = NULL; + + mScrollArea->setVerticalScrollAmount(0); +} + +int UpdaterWindow::updateProgress(void *ptr, DownloadStatus status, + size_t dt, size_t dn) +{ + UpdaterWindow *uw = reinterpret_cast(ptr); + + if (status == DOWNLOAD_STATUS_COMPLETE) + { + uw->mDownloadComplete = true; + } + else if (status == DOWNLOAD_STATUS_ERROR || + status == DOWNLOAD_STATUS_CANCELLED) + { + uw->mDownloadStatus = UPDATE_ERROR; + } + + float progress = (float) dn / dt; + + 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)) + "%)"); + uw->setProgress(progress); + + if (Client::getState() != STATE_UPDATE || uw->mDownloadStatus == UPDATE_ERROR) + { + // If the action was canceled return an error code to stop the mThread + return -1; + } + + return 0; +} + +size_t UpdaterWindow::memoryWrite(void *ptr, size_t size, size_t nmemb, void *stream) +{ + UpdaterWindow *uw = reinterpret_cast(stream); + size_t totalMem = size * nmemb; + uw->mMemoryBuffer = (char*) realloc(uw->mMemoryBuffer, + uw->mDownloadedBytes + totalMem); + if (uw->mMemoryBuffer) + { + memcpy(&(uw->mMemoryBuffer[uw->mDownloadedBytes]), ptr, totalMem); + uw->mDownloadedBytes += totalMem; + } + + return totalMem; +} + +void UpdaterWindow::download() +{ + mDownload = new Net::Download(this, mUpdateHost + "/" + mCurrentFile, + updateProgress); + + if (mStoreInMemory) + { + mDownload->setWriteFunction(UpdaterWindow::memoryWrite); + } + else + { + if (mDownloadStatus == UPDATE_RESOURCES) + { + mDownload->setFile(mUpdatesDir + "/" + mCurrentFile, + mCurrentChecksum); + } + else + { + mDownload->setFile(mUpdatesDir + "/" + mCurrentFile); + } + } + + if (mDownloadStatus != UPDATE_RESOURCES) + mDownload->noCache(); + + setLabel(mCurrentFile + " (0%)"); + mDownloadComplete = false; + + // TODO: check return + mDownload->start(); +} + +void UpdaterWindow::loadUpdates() +{ + ResourceManager *resman = ResourceManager::getInstance(); + + if (!mUpdateFiles.size()) + { // updates not downloaded + mUpdateFiles = loadXMLFile(mUpdatesDir + "/" + xmlUpdateFile); + if (!mUpdateFiles.size()) + { + logger->log("Warning this server does not have a" + " %s file falling back to %s", xmlUpdateFile.c_str(), + txtUpdateFile.c_str()); + mUpdateFiles = loadTxtFile(mUpdatesDir + "/" + txtUpdateFile); + } + } + + for (mUpdateIndex = 0; mUpdateIndex < mUpdateFiles.size(); mUpdateIndex++) + { + resman->addToSearchPath(mUpdatesDir + "/" + + mUpdateFiles[mUpdateIndex].name, false); + } +} + +void UpdaterWindow::logic() +{ + const std::string xmlUpdateFile = "resources.xml"; + const std::string txtUpdateFile = "resources2.txt"; + + // Update Scroll logic + mScrollArea->logic(); + + // Synchronize label caption when necessary + { + MutexLocker lock(&mDownloadMutex); + + if (mLabel->getCaption() != mNewLabelCaption) + { + mLabel->setCaption(mNewLabelCaption); + mLabel->adjustSize(); + } + + mProgressBar->setProgress(mDownloadProgress); + } + + std::string filename = mUpdatesDir + "/" + mCurrentFile; + + switch (mDownloadStatus) + { + case UPDATE_ERROR: + // TODO: Only send complete sentences to gettext + mBrowserBox->addRow(""); + mBrowserBox->addRow(_("##1 The update process is incomplete.")); + // TRANSLATORS: Continues "you try again later.". + mBrowserBox->addRow(_("##1 It is strongly recommended that")); + // TRANSLATORS: Begins "It is strongly recommended that". + mBrowserBox->addRow(_("##1 you try again later.")); + + mBrowserBox->addRow(mDownload->getError()); + mScrollArea->setVerticalScrollAmount( + mScrollArea->getVerticalMaxScroll()); + mDownloadStatus = UPDATE_COMPLETE; + break; + case UPDATE_NEWS: + if (mDownloadComplete) + { + // Parse current memory buffer as news and dispose of the data + loadNews(); + + mCurrentFile = xmlUpdateFile; + mStoreInMemory = false; + mDownloadStatus = UPDATE_LIST; + download(); // download() changes mDownloadComplete to false + } + break; + case UPDATE_LIST: + if (mDownloadComplete) + { + if (mCurrentFile == xmlUpdateFile) + { + mUpdateFiles = loadXMLFile(mUpdatesDir + "/" + xmlUpdateFile); + if (mUpdateFiles.size() == 0) + { + logger->log("Warning this server does not have a %s" + " file falling back to %s", + xmlUpdateFile.c_str(), txtUpdateFile.c_str()); + + // If the resources.xml file fails, fall back onto a older version + mCurrentFile = txtUpdateFile; + mStoreInMemory = false; + mDownloadStatus = UPDATE_LIST; + download(); + break; + } + } + else if (mCurrentFile == txtUpdateFile) + { + mUpdateFiles = loadTxtFile(mUpdatesDir + "/" + txtUpdateFile); + } + mStoreInMemory = false; + mDownloadStatus = UPDATE_RESOURCES; + } + break; + case UPDATE_RESOURCES: + if (mDownloadComplete) + { + if (mUpdateIndex < mUpdateFiles.size()) + { + updateFile thisFile = mUpdateFiles[mUpdateIndex]; + if (!thisFile.required) + { + // This statement checks to see if the file type is music, and if download-music is true + // If it fails, this statement returns true, and results in not downloading the file + // Else it will ignore the break, and download the file. + if ( !(thisFile.type == "music" && config.getBoolValue("download-music")) ) + { + mUpdateIndex++; + break; + } + } + mCurrentFile = thisFile.name; + std::string checksum; + checksum = thisFile.hash; + std::stringstream ss(checksum); + ss >> std::hex >> mCurrentChecksum; + + std::ifstream temp( + (mUpdatesDir + "/" + mCurrentFile).c_str()); + + if (!temp.is_open()) + { + temp.close(); + download(); + } + else + { + temp.close(); + logger->log("%s already here", mCurrentFile.c_str()); + } + mUpdateIndex++; + } + else + { + // Download of updates completed + mDownloadStatus = UPDATE_COMPLETE; + } + } + break; + case UPDATE_COMPLETE: + enable(); + setLabel(_("Completed")); + break; + case UPDATE_IDLE: + break; + } +} diff --git a/src/gui/updaterwindow.h b/src/gui/updaterwindow.h new file mode 100644 index 00000000..a4dbf674 --- /dev/null +++ b/src/gui/updaterwindow.h @@ -0,0 +1,195 @@ +/* + * The Mana Client + * Copyright (C) 2004-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * + * This file is part of The Mana Client. + * + * 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, see . + */ + +#ifndef UPDATERWINDOW_H +#define UPDATERWINDOW_H + +#include "gui/widgets/window.h" + +#include "net/download.h" + +#include "utils/mutex.h" + +#include +#include + +#include +#include + +class BrowserBox; +class Button; +class ProgressBar; +class ScrollArea; + +struct updateFile +{ + public: + std::string name; + std::string hash; + std::string type; + bool required; + std::string desc; +}; + +/** + * Update progress window GUI + * + * \ingroup GUI + */ +class UpdaterWindow : public Window, public gcn::ActionListener, + public gcn::KeyListener +{ + public: + /** + * Constructor. + * + * @param updateHost Host where to get the updated files. + * @param updatesDir Directory where to store updates (should be absolute + * and already created). + * @param applyUpdates If true, the update window will pass the updates to teh + * resource manager + */ + UpdaterWindow(const std::string &updateHost, + const std::string &updatesDir, + bool applyUpdates); + + ~UpdaterWindow(); + + /** + * Set's progress bar status + */ + void setProgress(float p); + + /** + * Set's label above progress + */ + void setLabel(const std::string &); + + /** + * Enables play button + */ + void enable(); + + /** + * Loads and display news. Assumes the news file contents have been loaded + * into the memory buffer. + */ + void loadNews(); + + void action(const gcn::ActionEvent &event); + + void keyPressed(gcn::KeyEvent &keyEvent); + + void logic(); + + int updateState; + +private: + void download(); + + /** + * Loads the updates this window has gotten into the resource manager + */ + void loadUpdates(); + + + /** + * A download callback for progress updates. + */ + static int updateProgress(void *ptr, DownloadStatus status, + size_t dt, size_t dn); + + /** + * A libcurl callback for writing to memory. + */ + static size_t memoryWrite(void *ptr, size_t size, size_t nmemb, + void *stream); + + enum UpdateDownloadStatus + { + UPDATE_ERROR, + UPDATE_IDLE, + UPDATE_LIST, + UPDATE_COMPLETE, + UPDATE_NEWS, + UPDATE_RESOURCES + }; + + /** Status of the current download. */ + UpdateDownloadStatus mDownloadStatus; + + /** Host where we get the updated files. */ + std::string mUpdateHost; + + /** Place where the updates are stored (absolute path). */ + std::string mUpdatesDir; + + /** The file currently downloading. */ + std::string mCurrentFile; + + /** The new label caption to be set in the logic method. */ + std::string mNewLabelCaption; + + /** The new progress value to be set in the logic method. */ + float mDownloadProgress; + + /** The mutex used to guard access to mNewLabelCaption and mDownloadProgress. */ + Mutex mDownloadMutex; + + /** The Adler32 checksum of the file currently downloading. */ + unsigned long mCurrentChecksum; + + /** A flag to indicate whether to use a memory buffer or a regular file. */ + bool mStoreInMemory; + + /** Flag that show if current download is complete. */ + bool mDownloadComplete; + + /** Flag that show if the user has canceled the update. */ + bool mUserCancel; + + /** Byte count currently downloaded in mMemoryBuffer. */ + int mDownloadedBytes; + + /** Buffer for files downloaded to memory. */ + char *mMemoryBuffer; + + /** Download handle. */ + Net::Download *mDownload; + + /** List of files to download. */ + std::vector mUpdateFiles; + + /** Index of the file to be downloaded. */ + unsigned int mUpdateIndex; + + /** Tells ~UpdaterWindow() if it should load updates */ + bool mLoadUpdates; + + gcn::Label *mLabel; /**< Progress bar caption. */ + Button *mCancelButton; /**< Button to stop the update process. */ + Button *mPlayButton; /**< Button to start playing. */ + ProgressBar *mProgressBar; /**< Update progress bar. */ + BrowserBox *mBrowserBox; /**< Box to display news. */ + ScrollArea *mScrollArea; /**< Used to scroll news box. */ +}; + +#endif diff --git a/src/gui/updatewindow.cpp b/src/gui/updatewindow.cpp deleted file mode 100644 index 23d23b5e..00000000 --- a/src/gui/updatewindow.cpp +++ /dev/null @@ -1,520 +0,0 @@ -/* - * The Mana Client - * Copyright (C) 2004-2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers - * - * This file is part of The Mana Client. - * - * 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, see . - */ - -#include "gui/updatewindow.h" - -#include "client.h" -#include "configuration.h" -#include "log.h" - -#include "gui/sdlinput.h" - -#include "gui/widgets/browserbox.h" -#include "gui/widgets/button.h" -#include "gui/widgets/label.h" -#include "gui/widgets/layout.h" -#include "gui/widgets/progressbar.h" -#include "gui/widgets/scrollarea.h" - -#include "net/download.h" - -#include "resources/resourcemanager.h" - -#include "utils/gettext.h" -#include "utils/stringutils.h" -#include "utils/xml.h" - -#include -#include - -const std::string xmlUpdateFile = "resources.xml"; -const std::string txtUpdateFile = "resources2.txt"; - -/** - * Load the given file into a vector of updateFiles. - */ -std::vector loadXMLFile(const std::string &fileName) -{ - std::vector files; - XML::Document doc(fileName, false); - xmlNodePtr rootNode = doc.rootNode(); - - if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "updates")) - { - logger->log("Error loading update file: %s", fileName.c_str()); - return files; - } - - for_each_xml_child_node(fileNode, rootNode) - { - // Ignore all tags except for the "update" tags - if (!xmlStrEqual(fileNode->name, BAD_CAST "update")) - continue; - - updateFile file; - file.name = XML::getProperty(fileNode, "file", ""); - file.hash = XML::getProperty(fileNode, "hash", ""); - file.type = XML::getProperty(fileNode, "type", "data"); - file.desc = XML::getProperty(fileNode, "description", ""); - if (XML::getProperty(fileNode, "required", "yes") == "yes") - file.required = true; - else - file.required = false; - - files.push_back(file); - } - - return files; -} - -std::vector loadTxtFile(const std::string &fileName) -{ - std::vector files; - std::ifstream fileHandler; - fileHandler.open(fileName.c_str(), std::ios::in); - - if (fileHandler.is_open()) - { - while (fileHandler.good()) - { - char name[256], hash[50]; - fileHandler.getline(name, 256, ' '); - fileHandler.getline(hash, 50); - - updateFile thisFile; - thisFile.name = name; - thisFile.hash = hash; - thisFile.type = "data"; - thisFile.required = true; - thisFile.desc = ""; - - files.push_back(thisFile); - } - } - else - { - logger->log("Error loading update file: %s", fileName.c_str()); - } - fileHandler.close(); - - return files; -} - -UpdaterWindow::UpdaterWindow(const std::string &updateHost, - const std::string &updatesDir, - bool applyUpdates): - Window(_("Updating...")), - mDownloadStatus(UPDATE_NEWS), - mUpdateHost(updateHost), - mUpdatesDir(updatesDir), - mCurrentFile("news.txt"), - mDownloadProgress(0.0f), - mCurrentChecksum(0), - mStoreInMemory(true), - mDownloadComplete(true), - mUserCancel(false), - mDownloadedBytes(0), - mMemoryBuffer(NULL), - mDownload(NULL), - mUpdateIndex(0), - mLoadUpdates(applyUpdates) -{ - mBrowserBox = new BrowserBox; - mScrollArea = new ScrollArea(mBrowserBox); - mLabel = new Label(_("Connecting...")); - mProgressBar = new ProgressBar(0.0, 310, 20); - mCancelButton = new Button(_("Cancel"), "cancel", this); - mPlayButton = new Button(_("Play"), "play", this); - - mProgressBar->setSmoothProgress(false); - mBrowserBox->setOpaque(false); - mPlayButton->setEnabled(false); - - 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); - - reflowLayout(320, 240); - - Layout &layout = getLayout(); - layout.setRowHeight(0, Layout::AUTO_SET); - - addKeyListener(this); - - center(); - setVisible(true); - mCancelButton->requestFocus(); - - // Try to download the updates list - download(); -} - -UpdaterWindow::~UpdaterWindow() -{ - if (mLoadUpdates) - loadUpdates(); - - if (mDownload) - { - mDownload->cancel(); - - delete mDownload; - mDownload = 0; - } - free(mMemoryBuffer); -} - -void UpdaterWindow::setProgress(float p) -{ - // Do delayed progress bar update, since Guichan isn't thread-safe - MutexLocker lock(&mDownloadMutex); - mDownloadProgress = p; -} - -void UpdaterWindow::setLabel(const std::string &str) -{ - // Do delayed label text update, since Guichan isn't thread-safe - MutexLocker lock(&mDownloadMutex); - mNewLabelCaption = str; -} - -void UpdaterWindow::enable() -{ - mCancelButton->setEnabled(false); - mPlayButton->setEnabled(true); - mPlayButton->requestFocus(); -} - -void UpdaterWindow::action(const gcn::ActionEvent &event) -{ - if (event.getId() == "cancel") - { - // Register the user cancel - mUserCancel = true; - // Skip the updating process - if (mDownloadStatus != UPDATE_COMPLETE) - { - mDownload->cancel(); - mDownloadStatus = UPDATE_ERROR; - } - } - else if (event.getId() == "play") - { - Client::setState(STATE_LOAD_DATA); - } -} - -void UpdaterWindow::keyPressed(gcn::KeyEvent &keyEvent) -{ - gcn::Key key = keyEvent.getKey(); - - if (key.getValue() == Key::ESCAPE) - { - action(gcn::ActionEvent(NULL, mCancelButton->getActionEventId())); - Client::setState(STATE_WORLD_SELECT); - } - else if (key.getValue() == Key::ENTER) - { - if (mDownloadStatus == UPDATE_COMPLETE || - mDownloadStatus == UPDATE_ERROR) - { - action(gcn::ActionEvent(NULL, mPlayButton->getActionEventId())); - } - else - { - action(gcn::ActionEvent(NULL, mCancelButton->getActionEventId())); - } - } -} - -void UpdaterWindow::loadNews() -{ - if (!mMemoryBuffer) - { - logger->log("Couldn't load news"); - return; - } - - // Reallocate and include terminating 0 character - mMemoryBuffer = (char*)realloc(mMemoryBuffer, mDownloadedBytes + 1); - mMemoryBuffer[mDownloadedBytes] = '\0'; - - mBrowserBox->clearRows(); - - // Tokenize and add each line separately - char *line = strtok(mMemoryBuffer, "\n"); - while (line) - { - mBrowserBox->addRow(line); - line = strtok(NULL, "\n"); - } - - // Free the memory buffer now that we don't need it anymore - free(mMemoryBuffer); - mMemoryBuffer = NULL; - - mScrollArea->setVerticalScrollAmount(0); -} - -int UpdaterWindow::updateProgress(void *ptr, DownloadStatus status, - size_t dt, size_t dn) -{ - UpdaterWindow *uw = reinterpret_cast(ptr); - - if (status == DOWNLOAD_STATUS_COMPLETE) - { - uw->mDownloadComplete = true; - } - else if (status == DOWNLOAD_STATUS_ERROR || - status == DOWNLOAD_STATUS_CANCELLED) - { - uw->mDownloadStatus = UPDATE_ERROR; - } - - float progress = (float) dn / dt; - - 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)) + "%)"); - uw->setProgress(progress); - - if (Client::getState() != STATE_UPDATE || uw->mDownloadStatus == UPDATE_ERROR) - { - // If the action was canceled return an error code to stop the mThread - return -1; - } - - return 0; -} - -size_t UpdaterWindow::memoryWrite(void *ptr, size_t size, size_t nmemb, void *stream) -{ - UpdaterWindow *uw = reinterpret_cast(stream); - size_t totalMem = size * nmemb; - uw->mMemoryBuffer = (char*) realloc(uw->mMemoryBuffer, - uw->mDownloadedBytes + totalMem); - if (uw->mMemoryBuffer) - { - memcpy(&(uw->mMemoryBuffer[uw->mDownloadedBytes]), ptr, totalMem); - uw->mDownloadedBytes += totalMem; - } - - return totalMem; -} - -void UpdaterWindow::download() -{ - mDownload = new Net::Download(this, mUpdateHost + "/" + mCurrentFile, - updateProgress); - - if (mStoreInMemory) - { - mDownload->setWriteFunction(UpdaterWindow::memoryWrite); - } - else - { - if (mDownloadStatus == UPDATE_RESOURCES) - { - mDownload->setFile(mUpdatesDir + "/" + mCurrentFile, - mCurrentChecksum); - } - else - { - mDownload->setFile(mUpdatesDir + "/" + mCurrentFile); - } - } - - if (mDownloadStatus != UPDATE_RESOURCES) - mDownload->noCache(); - - setLabel(mCurrentFile + " (0%)"); - mDownloadComplete = false; - - // TODO: check return - mDownload->start(); -} - -void UpdaterWindow::loadUpdates() -{ - ResourceManager *resman = ResourceManager::getInstance(); - - if (!mUpdateFiles.size()) - { // updates not downloaded - mUpdateFiles = loadXMLFile(mUpdatesDir + "/" + xmlUpdateFile); - if (!mUpdateFiles.size()) - { - logger->log("Warning this server does not have a" - " %s file falling back to %s", xmlUpdateFile.c_str(), - txtUpdateFile.c_str()); - mUpdateFiles = loadTxtFile(mUpdatesDir + "/" + txtUpdateFile); - } - } - - for (mUpdateIndex = 0; mUpdateIndex < mUpdateFiles.size(); mUpdateIndex++) - { - resman->addToSearchPath(mUpdatesDir + "/" - + mUpdateFiles[mUpdateIndex].name, false); - } -} - -void UpdaterWindow::logic() -{ - const std::string xmlUpdateFile = "resources.xml"; - const std::string txtUpdateFile = "resources2.txt"; - - // Update Scroll logic - mScrollArea->logic(); - - // Synchronize label caption when necessary - { - MutexLocker lock(&mDownloadMutex); - - if (mLabel->getCaption() != mNewLabelCaption) - { - mLabel->setCaption(mNewLabelCaption); - mLabel->adjustSize(); - } - - mProgressBar->setProgress(mDownloadProgress); - } - - std::string filename = mUpdatesDir + "/" + mCurrentFile; - - switch (mDownloadStatus) - { - case UPDATE_ERROR: - // TODO: Only send complete sentences to gettext - mBrowserBox->addRow(""); - mBrowserBox->addRow(_("##1 The update process is incomplete.")); - // TRANSLATORS: Continues "you try again later.". - mBrowserBox->addRow(_("##1 It is strongly recommended that")); - // TRANSLATORS: Begins "It is strongly recommended that". - mBrowserBox->addRow(_("##1 you try again later.")); - - mBrowserBox->addRow(mDownload->getError()); - mScrollArea->setVerticalScrollAmount( - mScrollArea->getVerticalMaxScroll()); - mDownloadStatus = UPDATE_COMPLETE; - break; - case UPDATE_NEWS: - if (mDownloadComplete) - { - // Parse current memory buffer as news and dispose of the data - loadNews(); - - mCurrentFile = xmlUpdateFile; - mStoreInMemory = false; - mDownloadStatus = UPDATE_LIST; - download(); // download() changes mDownloadComplete to false - } - break; - case UPDATE_LIST: - if (mDownloadComplete) - { - if (mCurrentFile == xmlUpdateFile) - { - mUpdateFiles = loadXMLFile(mUpdatesDir + "/" + xmlUpdateFile); - if (mUpdateFiles.size() == 0) - { - logger->log("Warning this server does not have a %s" - " file falling back to %s", - xmlUpdateFile.c_str(), txtUpdateFile.c_str()); - - // If the resources.xml file fails, fall back onto a older version - mCurrentFile = txtUpdateFile; - mStoreInMemory = false; - mDownloadStatus = UPDATE_LIST; - download(); - break; - } - } - else if (mCurrentFile == txtUpdateFile) - { - mUpdateFiles = loadTxtFile(mUpdatesDir + "/" + txtUpdateFile); - } - mStoreInMemory = false; - mDownloadStatus = UPDATE_RESOURCES; - } - break; - case UPDATE_RESOURCES: - if (mDownloadComplete) - { - if (mUpdateIndex < mUpdateFiles.size()) - { - updateFile thisFile = mUpdateFiles[mUpdateIndex]; - if (!thisFile.required) - { - // This statement checks to see if the file type is music, and if download-music is true - // If it fails, this statement returns true, and results in not downloading the file - // Else it will ignore the break, and download the file. - if ( !(thisFile.type == "music" && config.getBoolValue("download-music")) ) - { - mUpdateIndex++; - break; - } - } - mCurrentFile = thisFile.name; - std::string checksum; - checksum = thisFile.hash; - std::stringstream ss(checksum); - ss >> std::hex >> mCurrentChecksum; - - std::ifstream temp( - (mUpdatesDir + "/" + mCurrentFile).c_str()); - - if (!temp.is_open()) - { - temp.close(); - download(); - } - else - { - temp.close(); - logger->log("%s already here", mCurrentFile.c_str()); - } - mUpdateIndex++; - } - else - { - // Download of updates completed - mDownloadStatus = UPDATE_COMPLETE; - } - } - break; - case UPDATE_COMPLETE: - enable(); - setLabel(_("Completed")); - break; - case UPDATE_IDLE: - break; - } -} diff --git a/src/gui/updatewindow.h b/src/gui/updatewindow.h deleted file mode 100644 index a4dbf674..00000000 --- a/src/gui/updatewindow.h +++ /dev/null @@ -1,195 +0,0 @@ -/* - * The Mana Client - * Copyright (C) 2004-2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers - * - * This file is part of The Mana Client. - * - * 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, see . - */ - -#ifndef UPDATERWINDOW_H -#define UPDATERWINDOW_H - -#include "gui/widgets/window.h" - -#include "net/download.h" - -#include "utils/mutex.h" - -#include -#include - -#include -#include - -class BrowserBox; -class Button; -class ProgressBar; -class ScrollArea; - -struct updateFile -{ - public: - std::string name; - std::string hash; - std::string type; - bool required; - std::string desc; -}; - -/** - * Update progress window GUI - * - * \ingroup GUI - */ -class UpdaterWindow : public Window, public gcn::ActionListener, - public gcn::KeyListener -{ - public: - /** - * Constructor. - * - * @param updateHost Host where to get the updated files. - * @param updatesDir Directory where to store updates (should be absolute - * and already created). - * @param applyUpdates If true, the update window will pass the updates to teh - * resource manager - */ - UpdaterWindow(const std::string &updateHost, - const std::string &updatesDir, - bool applyUpdates); - - ~UpdaterWindow(); - - /** - * Set's progress bar status - */ - void setProgress(float p); - - /** - * Set's label above progress - */ - void setLabel(const std::string &); - - /** - * Enables play button - */ - void enable(); - - /** - * Loads and display news. Assumes the news file contents have been loaded - * into the memory buffer. - */ - void loadNews(); - - void action(const gcn::ActionEvent &event); - - void keyPressed(gcn::KeyEvent &keyEvent); - - void logic(); - - int updateState; - -private: - void download(); - - /** - * Loads the updates this window has gotten into the resource manager - */ - void loadUpdates(); - - - /** - * A download callback for progress updates. - */ - static int updateProgress(void *ptr, DownloadStatus status, - size_t dt, size_t dn); - - /** - * A libcurl callback for writing to memory. - */ - static size_t memoryWrite(void *ptr, size_t size, size_t nmemb, - void *stream); - - enum UpdateDownloadStatus - { - UPDATE_ERROR, - UPDATE_IDLE, - UPDATE_LIST, - UPDATE_COMPLETE, - UPDATE_NEWS, - UPDATE_RESOURCES - }; - - /** Status of the current download. */ - UpdateDownloadStatus mDownloadStatus; - - /** Host where we get the updated files. */ - std::string mUpdateHost; - - /** Place where the updates are stored (absolute path). */ - std::string mUpdatesDir; - - /** The file currently downloading. */ - std::string mCurrentFile; - - /** The new label caption to be set in the logic method. */ - std::string mNewLabelCaption; - - /** The new progress value to be set in the logic method. */ - float mDownloadProgress; - - /** The mutex used to guard access to mNewLabelCaption and mDownloadProgress. */ - Mutex mDownloadMutex; - - /** The Adler32 checksum of the file currently downloading. */ - unsigned long mCurrentChecksum; - - /** A flag to indicate whether to use a memory buffer or a regular file. */ - bool mStoreInMemory; - - /** Flag that show if current download is complete. */ - bool mDownloadComplete; - - /** Flag that show if the user has canceled the update. */ - bool mUserCancel; - - /** Byte count currently downloaded in mMemoryBuffer. */ - int mDownloadedBytes; - - /** Buffer for files downloaded to memory. */ - char *mMemoryBuffer; - - /** Download handle. */ - Net::Download *mDownload; - - /** List of files to download. */ - std::vector mUpdateFiles; - - /** Index of the file to be downloaded. */ - unsigned int mUpdateIndex; - - /** Tells ~UpdaterWindow() if it should load updates */ - bool mLoadUpdates; - - gcn::Label *mLabel; /**< Progress bar caption. */ - Button *mCancelButton; /**< Button to stop the update process. */ - Button *mPlayButton; /**< Button to start playing. */ - ProgressBar *mProgressBar; /**< Update progress bar. */ - BrowserBox *mBrowserBox; /**< Box to display news. */ - ScrollArea *mScrollArea; /**< Used to scroll news box. */ -}; - -#endif diff --git a/src/gui/viewport.cpp b/src/gui/viewport.cpp index 453f615e..e6115805 100644 --- a/src/gui/viewport.cpp +++ b/src/gui/viewport.cpp @@ -32,7 +32,7 @@ #include "textmanager.h" #include "gui/gui.h" -#include "gui/ministatus.h" +#include "gui/ministatuswindow.h" #include "gui/popupmenu.h" #include "gui/beingpopup.h" diff --git a/src/gui/widgets/chattab.cpp b/src/gui/widgets/chattab.cpp index 20aadfb7..ce9ee878 100644 --- a/src/gui/widgets/chattab.cpp +++ b/src/gui/widgets/chattab.cpp @@ -22,7 +22,7 @@ #include "gui/widgets/chattab.h" #include "actorspritemanager.h" -#include "chatlog.h" +#include "chatlogger.h" #include "commandhandler.h" #include "configuration.h" #include "localplayer.h" diff --git a/src/gui/widgets/chattab.h b/src/gui/widgets/chattab.h index 1b666da1..93636b8f 100644 --- a/src/gui/widgets/chattab.h +++ b/src/gui/widgets/chattab.h @@ -22,7 +22,7 @@ #ifndef CHATTAB_H #define CHATTAB_H -#include "gui/chat.h" +#include "gui/chatwindow.h" #include "gui/widgets/tab.h" #include "gui/widgets/textfield.h" diff --git a/src/gui/widgets/itemcontainer.cpp b/src/gui/widgets/itemcontainer.cpp index d88a5747..27f952c4 100644 --- a/src/gui/widgets/itemcontainer.cpp +++ b/src/gui/widgets/itemcontainer.cpp @@ -27,7 +27,7 @@ #include "itemshortcut.h" #include "log.h" -#include "gui/chat.h" +#include "gui/chatwindow.h" #include "gui/itempopup.h" #include "gui/outfitwindow.h" #include "gui/palette.h" diff --git a/src/gui/widgets/whispertab.cpp b/src/gui/widgets/whispertab.cpp index c3674c54..6da9461d 100644 --- a/src/gui/widgets/whispertab.cpp +++ b/src/gui/widgets/whispertab.cpp @@ -21,7 +21,7 @@ #include "whispertab.h" -#include "chatlog.h" +#include "chatlogger.h" #include "commandhandler.h" #include "localplayer.h" -- cgit v1.2.3-60-g2f50