diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/gui/buy.cpp | 36 | ||||
-rw-r--r-- | src/gui/buy.h | 3 | ||||
-rw-r--r-- | src/gui/sell.cpp | 4 | ||||
-rw-r--r-- | src/gui/shop.cpp | 39 | ||||
-rw-r--r-- | src/gui/shop.h | 32 | ||||
-rw-r--r-- | src/gui/shoplistbox.cpp | 191 | ||||
-rw-r--r-- | src/gui/shoplistbox.h | 116 |
8 files changed, 393 insertions, 30 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 2315a7af..7d37edf8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -91,6 +91,8 @@ tmw_SOURCES = graphic/imagerect.h \ gui/setup_video.h \ gui/shop.cpp \ gui/shop.h \ + gui/shoplistbox.cpp \ + gui/shoplistbox.h \ gui/skill.cpp \ gui/skill.h \ gui/slider.cpp \ diff --git a/src/gui/buy.cpp b/src/gui/buy.cpp index cad2e06f..0bf4c56d 100644 --- a/src/gui/buy.cpp +++ b/src/gui/buy.cpp @@ -26,14 +26,12 @@ #include <guichan/widgets/label.hpp> #include "button.h" -#include "listbox.h" #include "scrollarea.h" #include "shop.h" #include "slider.h" #include "../npc.h" -#include "../resources/iteminfo.h" #include "../resources/itemmanager.h" #include "../net/messageout.h" @@ -48,8 +46,8 @@ BuyDialog::BuyDialog(Network *network): { mShopItems = new ShopItems; - mItemList = new ListBox(mShopItems); - mScrollArea = new ScrollArea(mItemList); + mShopItemList = new ShopListBox(mShopItems, mShopItems); + mScrollArea = new ScrollArea(mShopItemList); mSlider = new Slider(1.0); mQuantityLabel = new gcn::Label("0"); mMoneyLabel = new gcn::Label("Price : 0 GP / 0 GP"); @@ -63,7 +61,7 @@ BuyDialog::BuyDialog(Network *network): setContentSize(260, 210); mScrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); mScrollArea->setDimension(gcn::Rectangle(5, 5, 250, 110)); - mItemList->setDimension(gcn::Rectangle(5, 5, 238, 110)); + mShopItemList->setDimension(gcn::Rectangle(5, 5, 238, 110)); mSlider->setDimension(gcn::Rectangle(5, 120, 200, 10)); mSlider->setEnabled(false); @@ -87,11 +85,11 @@ BuyDialog::BuyDialog(Network *network): mItemEffectLabel->setDimension(gcn::Rectangle(5, 150, 240, 14)); mItemDescLabel->setDimension(gcn::Rectangle(5, 169, 240, 14)); - mItemList->setEventId("item"); + mShopItemList->setEventId("item"); mSlider->setEventId("slider"); - mItemList->addActionListener(this); - mItemList->addSelectionListener(this); + mShopItemList->addActionListener(this); + mShopItemList->addSelectionListener(this); mSlider->addActionListener(this); add(mScrollArea); @@ -116,6 +114,7 @@ BuyDialog::~BuyDialog() void BuyDialog::setMoney(int amount) { mMoney = amount; + mShopItemList->setPlayersMoney(amount); mMoneyLabel->setCaption("Price : 0 GP / " + toString(mMoney) + " GP"); mMoneyLabel->adjustSize(); } @@ -128,7 +127,7 @@ void BuyDialog::reset() mAmountItems = 0; // Reset Previous Selected Items to prevent failing asserts - mItemList->setSelected(-1); + mShopItemList->setSelected(-1); mIncreaseButton->setEnabled(false); mDecreaseButton->setEnabled(false); mQuantityLabel->setCaption("0"); @@ -141,20 +140,13 @@ void BuyDialog::reset() void BuyDialog::addItem(short id, int price) { - ITEM_SHOP item_shop; - - item_shop.name = itemDb->getItemInfo(id).getName() + " " - + toString(price) + " GP"; - item_shop.price = price; - item_shop.id = id; - - mShopItems->push_back(item_shop); - mItemList->adjustSize(); + mShopItems->addItem(id, price); + mShopItemList->adjustSize(); } void BuyDialog::action(const std::string& eventId, gcn::Widget* widget) { - int selectedItem = mItemList->getSelected(); + int selectedItem = mShopItemList->getSelected(); if (eventId == "item") { @@ -172,7 +164,7 @@ void BuyDialog::action(const std::string& eventId, gcn::Widget* widget) // If no item was selected, none can be bought, otherwise // calculate how many the player can afford - mMaxItems = (mItemList->getSelected() == -1) ? 0 : + mMaxItems = (mShopItemList->getSelected() == -1) ? 0 : mMoney / mShopItems->at(selectedItem).price; // When at least one item can be bought, enable the slider and the @@ -187,7 +179,7 @@ void BuyDialog::action(const std::string& eventId, gcn::Widget* widget) } // The following actions require a valid selection - if (selectedItem < 0 || selectedItem >= int(mShopItems->size())) + if (selectedItem < 0 || selectedItem >= int(mShopItems->getNumberOfElements())) { return; } @@ -270,7 +262,7 @@ void BuyDialog::action(const std::string& eventId, gcn::Widget* widget) void BuyDialog::selectionChanged(const SelectionEvent &event) { - int selectedItem = mItemList->getSelected(); + int selectedItem = mShopItemList->getSelected(); if (selectedItem > -1) { diff --git a/src/gui/buy.h b/src/gui/buy.h index 6a8d45e3..2af6cfe8 100644 --- a/src/gui/buy.h +++ b/src/gui/buy.h @@ -28,6 +28,7 @@ #include "window.h" #include "selectionlistener.h" +#include "shoplistbox.h" #include "../guichanfwd.h" @@ -98,7 +99,7 @@ class BuyDialog : public Window, public gcn::ActionListener, SelectionListener gcn::Button *mQuitButton; gcn::Button *mIncreaseButton; gcn::Button *mDecreaseButton; - ListBox *mItemList; + ShopListBox *mShopItemList; gcn::ScrollArea *mScrollArea; gcn::Label *mItemDescLabel; gcn::Label *mItemEffectLabel; diff --git a/src/gui/sell.cpp b/src/gui/sell.cpp index cc43d36c..92669ab6 100644 --- a/src/gui/sell.cpp +++ b/src/gui/sell.cpp @@ -185,7 +185,7 @@ void SellDialog::action(const std::string& eventId, gcn::Widget* widget) } // The following actions require a valid item selection - if (selectedItem == -1 || selectedItem >= int(mShopItems->size())) { + if (selectedItem == -1 || selectedItem >= int(mShopItems->getNumberOfElements())) { return; } @@ -233,7 +233,7 @@ void SellDialog::action(const std::string& eventId, gcn::Widget* widget) // All were sold if (!mMaxItems) { mItemList->setSelected(-1); - mShopItems->erase(mShopItems->begin() + selectedItem); + mShopItems->mItemsShop.erase(mShopItems->mItemsShop.begin() + selectedItem); } // Update only when there are items left, the entry doesn't exist diff --git a/src/gui/shop.cpp b/src/gui/shop.cpp index 3706cdf8..39c285d7 100644 --- a/src/gui/shop.cpp +++ b/src/gui/shop.cpp @@ -22,13 +22,48 @@ */ #include "shop.h" +#include "../utils/tostring.h" +#include "../resources/itemmanager.h" + +ShopItems::~ShopItems() +{ + clear(); +} int ShopItems::getNumberOfElements() { - return size(); + return mItemsShop.size(); } std::string ShopItems::getElementAt(int i) { - return at(i).name; + return mItemsShop.at(i).name; +} + +void ShopItems::addItem(short id, int price) +{ + ITEM_SHOP item_shop; + + item_shop.name = itemDb->getItemInfo(id).getName() + + " " + toString(price) + " GP"; + item_shop.price = price; + item_shop.id = id; + item_shop.image = itemDb->getItemInfo(id).getImage(); + + mItemsShop.push_back(item_shop); +} + +ITEM_SHOP ShopItems::at(int i) +{ + return mItemsShop.at(i); +} + +void ShopItems::push_back(ITEM_SHOP item_shop) +{ + mItemsShop.push_back(item_shop); +} + +void ShopItems::clear() +{ + mItemsShop.clear(); } diff --git a/src/gui/shop.h b/src/gui/shop.h index fb1f33fd..0736003b 100644 --- a/src/gui/shop.h +++ b/src/gui/shop.h @@ -28,22 +28,34 @@ #include <vector> #include <guichan/listmodel.hpp> +#include "../resources/image.h" struct ITEM_SHOP { + short id; std::string name; + Image *image; int price; - short id; int index; int quantity; }; -class ShopItems : public std::vector<ITEM_SHOP>, public gcn::ListModel +class ShopItems : public gcn::ListModel { public: /** * Destructor */ - virtual ~ShopItems() {}; + ~ShopItems(); + + /** + * Adds an item and its associated picture + */ + void addItem(short id, int price); + + /** + * Convenience function for adding items + */ + void push_back(ITEM_SHOP item_shop); /** * Returns the number of items in the shop. @@ -54,6 +66,20 @@ class ShopItems : public std::vector<ITEM_SHOP>, public gcn::ListModel * Returns the name of item number i in the shop. */ std::string getElementAt(int i); + + /** + * Returns the item number i in the shop. + */ + ITEM_SHOP at(int i); + + /** + * Clear the vector and delete the pictures' instances. + */ + void clear(); + +// private: // This is to be readded as soon as the sell dialog is redone. + std::vector<ITEM_SHOP> mItemsShop; + }; #endif diff --git a/src/gui/shoplistbox.cpp b/src/gui/shoplistbox.cpp new file mode 100644 index 00000000..0aec33ed --- /dev/null +++ b/src/gui/shoplistbox.cpp @@ -0,0 +1,191 @@ +/* + * The Mana World + * Copyright 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * The Mana World is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * The Mana World is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with The Mana World; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id: listbox.cpp 2655 2006-09-03 21:25:02Z b_lindeijer $ + */ + +#include "shoplistbox.h" + +#include "selectionlistener.h" + +#include <guichan/font.hpp> +#include <guichan/graphics.hpp> +#include <guichan/listmodel.hpp> +#include <guichan/mouseinput.hpp> +#include <guichan/imagefont.hpp> +#include <guichan/basiccontainer.hpp> + +#include "../graphics.h" + +const int ITEM_SPRITE_HEIGHT = 32; + +ShopListBox::ShopListBox(gcn::ListModel *listModel): + gcn::ListBox(listModel), + mMousePressed(false), + mPlayerMoney(0) +{ + mRowHeight = getFont()->getHeight(); + +} + +ShopListBox::ShopListBox(gcn::ListModel *listModel, ShopItems *shopListModel): + gcn::ListBox(listModel), + mMousePressed(false), + mPlayerMoney(0), + mShopItems(shopListModel) +{ + mRowHeight = (getFont()->getHeight() > ITEM_SPRITE_HEIGHT ? + getFont()->getHeight() : ITEM_SPRITE_HEIGHT); +} + + +void ShopListBox::setPlayersMoney(int money) +{ + mPlayerMoney = money; +} + +void ShopListBox::draw(gcn::Graphics *graphics) +{ + if (mListModel == NULL) { + return; + } + + graphics->setFont(getFont()); + + // Draw the list elements + for (int i = 0, y = 0; i < mListModel->getNumberOfElements(); ++i, y += mRowHeight) + { + graphics->setColor(gcn::Color(0xffffff)); + if (mShopItems) + { + if(mPlayerMoney < mShopItems->at(i).price) + { + graphics->setColor(gcn::Color(0x919191)); + } + } + graphics->fillRectangle(gcn::Rectangle(0, y, getWidth(), mRowHeight)); + if (mShopItems) + dynamic_cast<Graphics*>(graphics)->drawImage(mShopItems->at(i).image, 1, y); + graphics->drawText(mListModel->getElementAt(i), ITEM_SPRITE_HEIGHT, y); + } + + // Draw rectangle below the selected list element and the list element + // not shown. + if (mSelected >= 0) { + graphics->setColor(gcn::Color(110, 160, 255)); + graphics->fillRectangle(gcn::Rectangle(0, mRowHeight * mSelected, + getWidth(), mRowHeight)); + if (mShopItems) + dynamic_cast<Graphics*>(graphics)->drawImage( + mShopItems->at(mSelected).image, 1, mRowHeight * mSelected); + graphics->drawText(mListModel->getElementAt(mSelected), + ITEM_SPRITE_HEIGHT, mRowHeight * mSelected); + } +} + +void ShopListBox::setSelected(int selected) +{ + gcn::ListBox::setSelected(selected); + if (mListModel != NULL) + { + gcn::BasicContainer *par = getParent(); + if (par == NULL) + { + return; + } + + gcn::Rectangle scroll; + + if (mSelected < 0) + { + scroll.y = 0; + } + else + { + scroll.y = mRowHeight * mSelected; + } + + scroll.height = mRowHeight; + par->showWidgetPart(this, scroll); + } + fireSelectionChangedEvent(); +} + +void ShopListBox::mousePress(int x, int y, int button) +{ + + bool enoughMoney = false; + if (button == gcn::MouseInput::LEFT && hasMouse()) + { + if (mShopItems) + { + if(mPlayerMoney >= mShopItems->at(y / mRowHeight).price) + enoughMoney = true; + } + else // Old Behaviour + enoughMoney = true; + + if (enoughMoney) + { + setSelected(y / mRowHeight); + generateAction(); + mMousePressed = true; + } + } +} + +void ShopListBox::mouseRelease(int x, int y, int button) +{ + gcn::ListBox::mouseRelease(x, y, button); + + mMousePressed = false; +} + +void ShopListBox::mouseMotion(int x, int y) +{ + gcn::ListBox::mouseMotion(x, y); + + // Pretend mouse is pressed continuously while dragged. Causes list + // selection to be updated as is default in many GUIs. + if (mMousePressed) + { + mousePress(x, y, gcn::MouseInput::LEFT); + } +} + +void ShopListBox::fireSelectionChangedEvent() +{ + SelectionEvent event(this); + SelectionListeners::iterator i_end = mListeners.end(); + SelectionListeners::iterator i; + + for (i = mListeners.begin(); i != i_end; ++i) + { + (*i)->selectionChanged(event); + } +} + +void ShopListBox::adjustSize() +{ + if (mListModel != NULL) + { + setHeight(mRowHeight * mListModel->getNumberOfElements()); + } +} diff --git a/src/gui/shoplistbox.h b/src/gui/shoplistbox.h new file mode 100644 index 00000000..88e1c4b6 --- /dev/null +++ b/src/gui/shoplistbox.h @@ -0,0 +1,116 @@ +/* + * The Mana World + * Copyright 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * The Mana World is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * The Mana World is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with The Mana World; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id: listbox.h 2655 2006-09-03 21:25:02Z b_lindeijer $ + */ + +#ifndef _TMW_LISTBOX_H +#define _TMW_LISTBOX_H + +#include <guichan/widgets/listbox.hpp> +#include "shop.h" + +class SelectionListener; + +/** + * A list box, meant to be used inside a scroll area. Same as the Guichan list + * box except this one doesn't have a background, instead completely relying + * on the scroll area. It also adds selection listener functionality. + * + * \ingroup GUI + */ +class ShopListBox : public gcn::ListBox +{ + public: + /** + * Constructor. + */ + ShopListBox(gcn::ListModel *listModel); + + /** + * Constructor with shopitems + */ + ShopListBox(gcn::ListModel *listModel, ShopItems *shopListModel); + + /** + * Draws the list box. + */ + void draw(gcn::Graphics *graphics); + + void mousePress(int x, int y, int button); + void mouseRelease(int x, int y, int button); + void mouseMotion(int x, int y); + + /** + * Adds a listener to the list that's notified each time a change to + * the selection occurs. + */ + void addSelectionListener(SelectionListener *listener) + { + mListeners.push_back(listener); + } + + /** + * Removes a listener from the list that's notified each time a change + * to the selection occurs. + */ + void removeSelectionListener(SelectionListener *listener) + { + mListeners.remove(listener); + } + + /** + * Sets the index of the selected element. + */ + void setSelected(int selected); + + /** + * gives information about the current player's money + */ + void setPlayersMoney(int money); + + /** + * Adjust List draw size + */ + void adjustSize(); + + private: + /** + * Sends out selection events to the list of selection listeners. + */ + void fireSelectionChangedEvent(); + + bool mMousePressed; /**< Keeps track of mouse pressed status. */ + + std::list<SelectionListener*> mListeners; + + int mPlayerMoney; + + /** + * Keeps another pointer to the same listModel, permitting to + * use the ShopItems specific functions. + */ + ShopItems *mShopItems; + + int mRowHeight; /**< Row Height */ + +}; + +#endif |