Mana
Loading...
Searching...
No Matches
buydialog.cpp
Go to the documentation of this file.
1/*
2 * The Mana Client
3 * Copyright (C) 2004-2009 The Mana World Development Team
4 * Copyright (C) 2009-2012 The Mana Developers
5 *
6 * This file is part of The Mana Client.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#include "gui/buydialog.h"
23
24#include "client.h"
25#include "playerinfo.h"
26#include "shopitem.h"
27#include "units.h"
28
29#include "gui/widgets/button.h"
30#include "gui/widgets/label.h"
31#include "gui/widgets/layout.h"
35#include "gui/widgets/slider.h"
36
37#include "net/net.h"
38#include "net/npchandler.h"
39
40#include "resources/iteminfo.h"
41
42#include "utils/gettext.h"
43#include "utils/stringutils.h"
44
46
48 Window(_("Buy")),
49 mNpcId(npcId), mMoney(0), mAmountItems(0), mMaxItems(0)
50{
51 setWindowName("Buy");
52 //setupWindow->registerWindowForReset(this);
53 setResizable(true);
54 setCloseButton(true);
55 setMinWidth(260);
56 setMinHeight(230);
58
60
63 mScrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
64
65 mSlider = new Slider(1.0);
67 mQuantityLabel->setAlignment(gcn::Graphics::CENTER);
68 mMoneyLabel = new Label(strprintf(_("Price: %s / Total: %s"),
69 "", ""));
70
71 // TRANSLATORS: This is a narrow symbol used to denote 'increasing'.
72 // You may change this symbol if your language uses another.
73 mIncreaseButton = new Button(_("+"), "inc", this);
74 // TRANSLATORS: This is a narrow symbol used to denote 'decreasing'.
75 // You may change this symbol if your language uses another.
76 mDecreaseButton = new Button(_("-"), "dec", this);
77 mBuyButton = new Button(_("Buy"), "buy", this);
78 mQuitButton = new Button(_("Quit"), "quit", this);
79 mAddMaxButton = new Button(_("Max"), "max", this);
80
81 mDecreaseButton->adjustSize();
82 mDecreaseButton->setWidth(mIncreaseButton->getWidth());
83
84 mIncreaseButton->setEnabled(false);
85 mDecreaseButton->setEnabled(false);
86 mBuyButton->setEnabled(false);
87 mSlider->setEnabled(false);
88
89 mSlider->setActionEventId("slider");
90 mSlider->addActionListener(this);
91 mShopItemList->addSelectionListener(this);
92
94 place = getPlacer(0, 0);
95
96 place(0, 0, mScrollArea, 8, 5).setPadding(3);
98 place(1, 5, mSlider, 3);
100 place(5, 5, mQuantityLabel, 2);
101 place(7, 5, mAddMaxButton);
102 place(0, 6, mMoneyLabel, 8);
103 place(6, 7, mBuyButton);
104 place(7, 7, mQuitButton);
105
106 Layout &layout = getLayout();
108
109 center();
111
112 instances.push_back(this);
113 setVisible(true);
114
116}
117
127
128void BuyDialog::setMoney(int amount)
129{
130 mMoney = amount;
132
134}
135
137{
138 mShopItems->clear();
140
141 // Reset previous selected items to prevent failing asserts
142 mShopItemList->setSelected(-1);
143 mSlider->setValue(0);
144
145 setMoney(0);
146}
147
148void BuyDialog::addItem(int id, int amount, int price)
149{
150 mShopItems->addItem(id, amount, price);
152}
153
154void BuyDialog::action(const gcn::ActionEvent &event)
155{
156 if (event.getId() == "quit")
157 {
158 close();
159 return;
160 }
161
162 int selectedItem = mShopItemList->getSelected();
163
164 // The following actions require a valid selection
165 if (selectedItem < 0 ||
166 selectedItem >= mShopItems->getNumberOfElements())
167 {
168 return;
169 }
170
171 if (event.getId() == "slider")
172 {
173 mAmountItems = (int) mSlider->getValue();
175 }
176 else if (event.getId() == "inc" && mAmountItems < mMaxItems)
177 {
178 mAmountItems++;
179 mSlider->setValue(mAmountItems);
181 }
182 else if (event.getId() == "dec" && mAmountItems > 1)
183 {
184 mAmountItems--;
185 mSlider->setValue(mAmountItems);
187 }
188 else if (event.getId() == "max")
189 {
191 mSlider->setValue(mAmountItems);
193 }
194 // TODO: Actually we'd have a bug elsewhere if this check for the number
195 // of items to be bought ever fails, Bertram removed the assertions, is
196 // there a better way to ensure this fails in an _obvious_ way in C++?
197 else if (event.getId() == "buy" && mAmountItems > 0 &&
199 {
201 mShopItems->at(selectedItem)->getId(),
203
204 // Update money and adjust the max number of items that can be bought
206 int price = mShopItems->at(selectedItem)->getPrice();
207 if (price < 0)
208 price = 0;
209 setMoney(mMoney - mAmountItems * price);
210 valueChanged(gcn::SelectionEvent(mShopItemList));
211 }
212}
213
214void BuyDialog::valueChanged(const gcn::SelectionEvent &event)
215{
216 // Reset amount of items and update labels
217 mAmountItems = 1;
218 mSlider->setValue(1);
219
221 mSlider->gcn::Slider::setScale(1, mMaxItems);
222}
223
224void BuyDialog::mouseClicked(gcn::MouseEvent &mouseEvent)
225{
226 if (mouseEvent.getSource() == mShopItemList &&
227 isDoubleClick(mShopItemList->getSelected()))
228 {
229 action(gcn::ActionEvent(mBuyButton, mBuyButton->getActionEventId()));
230 }
231}
232
234{
235 const int selectedItem = mShopItemList->getSelected();
236 int price = 0;
237
238 if (selectedItem > -1)
239 {
240 const ShopItem *shopItem = mShopItems->at(selectedItem);
241 const int itemPrice = shopItem->getPrice();
242
243 // Calculate how many the player can afford
244 if (itemPrice > 0)
245 {
246 mMaxItems = mMoney / itemPrice;
247 }
248 else
249 {
250 // Let the player no more than 1 of them at a time, since it
251 // shouldn't be a permitted case.
252 mMaxItems = 1;
253 }
254
255 // Calculate how many the player can carry
256 const int itemWeight = shopItem->getInfo().weight;
257 if (itemWeight > 0)
258 {
259 const int myTotalWeight = PlayerInfo::getAttribute(TOTAL_WEIGHT);
260 const int myMaxWeight = PlayerInfo::getAttribute(MAX_WEIGHT);
261 const int myFreeWeight = myMaxWeight - myTotalWeight;
262 const int canCarry = myFreeWeight / itemWeight;
263 mMaxItems = std::min(mMaxItems, canCarry);
264 }
265
268
269 // Calculate price of pending purchase
270 price = mAmountItems * itemPrice;
271 }
272 else
273 {
274 mMaxItems = 0;
275 mAmountItems = 0;
276 }
277
278 // Enable or disable buttons and slider
280 mDecreaseButton->setEnabled(mAmountItems > 1);
281 mBuyButton->setEnabled(mAmountItems > 0);
282 mSlider->setEnabled(mMaxItems > 1);
283
284 // Update quantity and money labels
285 mQuantityLabel->setCaption(strprintf("%d / %d", mAmountItems, mMaxItems));
286 mMoneyLabel->setCaption
287 (strprintf(_("Price: %s / Total: %s"),
288 Units::formatCurrency(price).c_str(),
289 Units::formatCurrency(mMoney - price).c_str()));
290}
291
292void BuyDialog::setVisible(bool visible)
293{
294 Window::setVisible(visible);
295
296 if (visible)
297 {
298 mShopItemList->requestFocus();
299 }
300 else
301 {
303 }
304}
305
307{
308 for (auto &instance : instances)
309 instance->close();
310}
Button widget.
Definition button.h:38
void reset()
Resets the dialog, clearing shop inventory.
static DialogList instances
Definition buydialog.h:105
gcn::Button * mBuyButton
Definition buydialog.h:109
gcn::Button * mQuitButton
Definition buydialog.h:110
BuyDialog(int npcId)
Definition buydialog.cpp:47
gcn::Label * mQuantityLabel
Definition buydialog.h:117
int mMaxItems
Definition buydialog.h:124
int mAmountItems
Definition buydialog.h:123
static void closeAll()
Closes all instances.
void action(const gcn::ActionEvent &event) override
Called when receiving actions from the widgets.
gcn::Slider * mSlider
Definition buydialog.h:118
gcn::ScrollArea * mScrollArea
Definition buydialog.h:115
void addItem(int id, int amount, int price)
Adds an item to the shop inventory.
std::list< BuyDialog * > DialogList
Definition buydialog.h:104
gcn::Button * mDecreaseButton
Definition buydialog.h:113
ShopItems * mShopItems
Definition buydialog.h:120
gcn::Button * mAddMaxButton
Definition buydialog.h:111
gcn::Button * mIncreaseButton
Definition buydialog.h:112
void mouseClicked(gcn::MouseEvent &mouseEvent) override
Allows for quick-buying by extending double-click events.
void updateButtonsAndLabels()
Updates the state of buttons and labels.
~BuyDialog() override
ShopListBox * mShopItemList
Definition buydialog.h:114
void setVisible(bool visible) override
Sets the visibility of this window.
void valueChanged(const gcn::SelectionEvent &event) override
Updates the labels according to the selected item.
void setMoney(int amount)
Sets the amount of available money.
gcn::Label * mMoneyLabel
Definition buydialog.h:116
This class is a helper for adding widgets to nested tables in a window.
Definition layout.h:34
int weight
Weight in grams.
Definition iteminfo.h:117
int getId() const
Returns the item id.
Definition item.h:49
const ItemInfo & getInfo() const
Returns information about this item type.
Definition item.h:103
Label widget.
Definition label.h:34
void setRowHeight(int n, int h)
Definition layout.h:221
LayoutCell & setPadding(int p)
Sets the padding around the cell content.
Definition layout.h:179
This class is an helper for setting the position of widgets.
Definition layout.h:281
@ AUTO_SET
Uses the share as the new size.
Definition layout.h:304
virtual void buyItem(int beingId, int itemId, int amount)=0
A scroll area.
Definition scrollarea.h:38
Represents an item in a shop inventory.
Definition shopitem.h:33
int getPrice() const
Gets the price of the item.
Definition shopitem.h:94
This class handles the list of items available in a shop.
Definition shopitems.h:41
void addItem(int id, int amount, int price)
Adds an item to the list.
Definition shopitems.cpp:48
ShopItem * at(int i) const
Returns the item number i in the shop.
Definition shopitems.cpp:72
int getNumberOfElements() override
Returns the number of items in the shop.
Definition shopitems.cpp:38
void clear()
Clears the list of items in the shop.
Definition shopitems.cpp:82
A list box, meant to be used inside a scroll area.
Definition shoplistbox.h:37
void setPlayersMoney(int money)
gives information about the current player's money
void adjustSize()
Adjust List draw size.
Slider widget.
Definition slider.h:32
static std::string formatCurrency(int value)
Formats the given number in the correct currency format.
Definition units.cpp:216
A window.
Definition window.h:59
void center()
Positions the window in the center of it's parent.
Definition window.cpp:768
virtual void setVisible(bool visible)
Overloads window setVisible by Guichan to allow sticky window handling.
Definition window.cpp:282
void setMinHeight(int height)
Sets the minimum height of the window.
Definition window.cpp:197
virtual void close()
Overrideable functionality for when the window is to close.
Definition window.cpp:327
Layout & getLayout()
Gets the layout handler for this window.
Definition window.cpp:714
void setWindowName(const std::string &name)
Sets the name of the window.
Definition window.h:272
ContainerPlacer getPlacer(int x, int y)
Returns a proxy for adding widgets in an inner table of the layout.
Definition window.cpp:743
void setResizable(bool resize)
Sets whether or not the window can be resized.
Definition window.cpp:212
LayoutCell & place(int x, int y, gcn::Widget *, int w=1, int h=1)
Adds a widget to the window and sets it at given cell.
Definition window.cpp:737
void scheduleDelete()
Schedule this window for deletion.
Definition window.cpp:299
void setCloseButton(bool flag)
Sets whether or not the window has a close button.
Definition window.cpp:262
void setDefaultSize()
Set the default win pos and size to the current ones.
Definition window.cpp:545
void loadWindowState()
Reads the position (and the size for resizable windows) in the configuration based on the given strin...
Definition window.cpp:467
void setMinWidth(int width)
Sets the minimum width of the window.
Definition window.cpp:192
bool isDoubleClick(int selected)
Returns whether this call and the last call were done for the same selected index and within a short ...
Definition client.cpp:126
#define _(s)
Definition gettext.h:38
NpcHandler * getNpcHandler()
Definition net.cpp:100
void setBuySellState(BuySellState buySellState)
Sets which buy, sell, or related interaction the player is currently involved in.
BuySellState getBuySellState()
Returns the current buy, sell, or related interaction the player is involved in.
int getAttribute(int id)
Returns the value of the given attribute.
@ MAX_WEIGHT
Definition playerinfo.h:35
@ TOTAL_WEIGHT
Definition playerinfo.h:35
@ BUYSELL_NONE
Definition playerinfo.h:66
@ BUYSELL_BUYING
Definition playerinfo.h:68
std::string strprintf(char const *format,...)
A safe version of sprintf that returns a std::string of the result.