Mana
Loading...
Searching...
No Matches
tradewindow.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/tradewindow.h"
23
24#include "event.h"
25#include "inventory.h"
26#include "item.h"
27#include "playerinfo.h"
28#include "units.h"
29
30#include "gui/inventorywindow.h"
32#include "gui/setup.h"
33
34#include "gui/widgets/button.h"
36#include "gui/widgets/label.h"
39#include "gui/widgets/layout.h"
40
41#include "net/net.h"
42#include "net/tradehandler.h"
43
44#include "utils/gettext.h"
45#include "utils/stringutils.h"
46
47#include <guichan/font.hpp>
48
49#define CAPTION_PROPOSE _("Propose trade")
50#define CAPTION_CONFIRMED _("Confirmed. Waiting...")
51#define CAPTION_ACCEPT _("Agree trade")
52#define CAPTION_ACCEPTED _("Agreed. Waiting...")
53
55 Window(_("Trade: You")),
56 mMyInventory(new Inventory(Inventory::TRADE)),
57 mPartnerInventory(new Inventory(Inventory::TRADE)),
58 mStatus(PROPOSING)
59{
60 setWindowName("Trade");
61 setResizable(true);
62 setCloseButton(true);
64 setMinWidth(386);
65 setMinHeight(180);
67
68 std::string longestName = getFont()->getWidth(_("OK")) >
69 getFont()->getWidth(_("Trade")) ?
70 _("OK") : _("Trade");
71
72 mAddButton = new Button(_("Add"), "add", this);
73 mOkButton = new Button("", "", this); // Will be filled in later
74
75 int width = std::max(mOkButton->getFont()->getWidth(CAPTION_PROPOSE),
76 mOkButton->getFont()->getWidth(CAPTION_CONFIRMED));
77 width = std::max(width, mOkButton->getFont()->getWidth(CAPTION_ACCEPT));
78 width = std::max(width, mOkButton->getFont()->getWidth(CAPTION_ACCEPTED));
79
80 mOkButton->setWidth(8 + width);
81
84
85 auto *myScroll = new ScrollArea(mMyItemContainer);
86 myScroll->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
87
90
91 auto *partnerScroll = new ScrollArea(mPartnerItemContainer);
92 partnerScroll->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
93
94 mMoneyLabel = new Label(strprintf(_("You get %s"), ""));
95 gcn::Label *mMoneyLabel2 = new Label(_("You give:"));
96
98 mMoneyField->setWidth(40);
99 mMoneyChangeButton = new Button(_("Change"), "money", this);
100
101 place(1, 0, mMoneyLabel);
102 place(0, 1, myScroll).setPadding(3);
103 place(1, 1, partnerScroll).setPadding(3);
105 place = getPlacer(0, 0);
106 place(0, 0, mMoneyLabel2);
107 place(1, 0, mMoneyField);
109 place = getPlacer(0, 2);
110 place(0, 0, mAddButton);
111 place(1, 0, mOkButton);
112 Layout &layout = getLayout();
113 layout.extend(0, 2, 2, 1);
115 layout.setRowHeight(2, 0);
116 layout.setColWidth(0, Layout::AUTO_SET);
117 layout.setColWidth(1, Layout::AUTO_SET);
118
120
121 reset();
122}
123
124TradeWindow::~TradeWindow() = default;
125
126void TradeWindow::setMoney(int amount)
127{
128 mMoneyLabel->setCaption(strprintf(_("You get %s"),
129 Units::formatCurrency(amount).c_str()));
130 mMoneyLabel->adjustSize();
131}
132
133void TradeWindow::addItem(int id, bool own, int quantity)
134{
135 if (own)
136 mMyInventory->addItem(id, quantity);
137 else
138 mPartnerInventory->addItem(id, quantity);
139}
140
141void TradeWindow::changeQuantity(int index, bool own, int quantity)
142{
143 if (own)
144 mMyInventory->getItem(index)->setQuantity(quantity);
145 else
146 mPartnerInventory->getItem(index)->setQuantity(quantity);
147}
148
149void TradeWindow::increaseQuantity(int index, bool own, int quantity)
150{
151 if (own)
152 mMyInventory->getItem(index)->increaseQuantity(quantity);
153 else
154 mPartnerInventory->getItem(index)->increaseQuantity(quantity);
155}
156
158{
159 mMyInventory->clear();
160 mPartnerInventory->clear();
161 mOkOther = false;
162 mOkMe = false;
163 setMoney(0);
164 mMoneyField->setEnabled(true);
165 mMoneyField->setText(std::string());
166 mAddButton->setEnabled(true);
167 mMoneyChangeButton->setEnabled(true);
169}
170
172{
173 if (own)
174 mOkMe = true;
175 else
176 mOkOther = true;
177
178 if (mOkMe && mOkOther)
179 {
180 //mOkMe = false;
181 //mOkOther = false;
183 }
184}
185
186void TradeWindow::valueChanged(const gcn::SelectionEvent &event)
187{
188 /* If an item is selected in one container, make sure no item is selected
189 * in the other container.
190 */
191 if (event.getSource() == mMyItemContainer &&
196}
197
199{
200 if (s == mStatus)
201 return;
202 mStatus = s;
203
204 switch (s)
205 {
206 case PREPARING:
207 mOkButton->setCaption(CAPTION_PROPOSE);
208 mOkButton->setActionEventId("ok");
209 break;
210 case PROPOSING:
211 mOkButton->setCaption(CAPTION_CONFIRMED);
212 mOkButton->setActionEventId(std::string());
213 break;
214 case ACCEPTING:
215 mOkButton->setCaption(CAPTION_ACCEPT);
216 mOkButton->setActionEventId("trade");
217 break;
218 case ACCEPTED:
219 mOkButton->setCaption(CAPTION_ACCEPTED);
220 mOkButton->setActionEventId(std::string());
221 break;
222 default:
223 break;
224 }
225
226 mOkButton->setEnabled((s != PROPOSING && s != ACCEPTED));
227}
228
229void TradeWindow::action(const gcn::ActionEvent &event)
230{
232
233 if (event.getId() == "add")
234 {
235 if (mStatus != PREPARING)
236 return;
237
238 if (!inventoryWindow->isVisible())
239 {
241 return;
242 }
243
244 if (!item)
245 return;
246
247 if (mMyInventory->getFreeSlot() == -1)
248 return;
249
250 if (mMyInventory->contains(item))
251 {
252 serverNotice(_("Failed adding item. You cannot "
253 "overlap one kind of item on the window."));
254 return;
255 }
256
257 // Choose amount of items to trade
259
261 }
262 else if (event.getId() == "cancel")
263 {
264 setVisible(false);
265 reset();
266
268 }
269 else if (event.getId() == "ok")
270 {
271 mMoneyField->setEnabled(false);
272 mAddButton->setEnabled(false);
273 mMoneyChangeButton->setEnabled(false);
274 receivedOk(true);
277 }
278 else if (event.getId() == "trade")
279 {
280 receivedOk(true);
283 }
284 else if (event.getId() == "money")
285 {
286 if (mStatus != PREPARING)
287 return;
288
289 int v = atoi(mMoneyField->getText().c_str());
290 int curMoney = PlayerInfo::getAttribute(MONEY);
291 if (v > curMoney)
292 {
293 serverNotice(_("You don't have enough money."));
294 v = curMoney;
295 }
297 mMoneyField->setText(strprintf("%d", v));
298 }
299}
300
Button widget.
Definition button.h:38
This class is a helper for adding widgets to nested tables in a window.
Definition layout.h:34
Item * getSelectedItem() const
Returns the selected item.
static void showWindow(Usage usage, Window *parent, Item *item, int maxRange=0)
Creates the dialog, or bypass it if there aren't enough items.
An item container.
void addSelectionListener(gcn::SelectionListener *listener)
Adds a listener to the list that's notified each time a change to the selection occurs.
Item * getSelectedItem() const
Returns the selected item.
void selectNone()
Sets selected item to NULL.
Represents one or more instances of a certain item type.
Definition item.h:35
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
void setColWidth(int n, int w)
Definition layout.h:215
LayoutCell & setHAlign(Alignment a)
Sets the horizontal alignment of the cell content.
Definition layout.h:185
void extend(int x, int y, int w, int h)
Definition layout.h:227
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 setMoney(int amount)
virtual void cancel()
virtual void finish()
virtual void confirm()
A scroll area.
Definition scrollarea.h:38
void registerWindowForReset(Window *window)
Enables the Reset Windows button.
Definition setup.cpp:108
A text field.
Definition textfield.h:72
Status mStatus
void addItem(int id, bool own, int quantity)
Add an item to the trade window.
void action(const gcn::ActionEvent &event) override
Called when receiving actions from the widgets.
void reset()
Reset both item containers.
@ PREPARING
Players are adding items.
@ ACCEPTED
Local player has accepted the trade.
@ ACCEPTING
Accepting the trade.
@ PROPOSING
Local player has confirmed the trade.
gcn::Label * mMoneyLabel
void receivedOk(bool own)
Player received ok message from server.
void valueChanged(const gcn::SelectionEvent &event) override
Updates the labels and makes sure only one item is selected in either my inventory or partner invento...
const std::unique_ptr< Inventory > mPartnerInventory
gcn::Button * mMoneyChangeButton
void setStatus(Status s)
Sets the current status of the trade.
ItemContainer * mPartnerItemContainer
void increaseQuantity(int index, bool own, int quantity)
Increase quantity of an item.
~TradeWindow() override
void changeQuantity(int index, bool own, int quantity)
Change quantity of an item.
ItemContainer * mMyItemContainer
const std::unique_ptr< Inventory > mMyInventory
gcn::TextField * mMoneyField
gcn::Button * mOkButton
gcn::Button * mAddButton
void setMoney(int quantity)
Displays expected money in the trade window.
void close() override
Closes the Trade Window, as well as telling the server that the window has been closed.
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
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
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 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
void serverNotice(const std::string &message)
Definition event.h:319
InventoryWindow * inventoryWindow
Definition game.cpp:96
#define _(s)
Definition gettext.h:38
TradeHandler * getTradeHandler()
Definition net.cpp:120
int getAttribute(int id)
Returns the value of the given attribute.
@ MONEY
Definition playerinfo.h:34
Setup * setupWindow
Definition setup.cpp:120
std::string strprintf(char const *format,...)
A safe version of sprintf that returns a std::string of the result.
#define CAPTION_PROPOSE
#define CAPTION_ACCEPTED
#define CAPTION_ACCEPT
#define CAPTION_CONFIRMED