GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
Line | Branch | Exec | Source |
1 |
/* |
||
2 |
* The ManaPlus Client |
||
3 |
* Copyright (C) 2004-2009 The Mana World Development Team |
||
4 |
* Copyright (C) 2009-2010 The Mana Developers |
||
5 |
* Copyright (C) 2011-2019 The ManaPlus Developers |
||
6 |
* Copyright (C) 2019-2021 Andrei Karas |
||
7 |
* |
||
8 |
* This file is part of The ManaPlus Client. |
||
9 |
* |
||
10 |
* This program is free software; you can redistribute it and/or modify |
||
11 |
* it under the terms of the GNU General Public License as published by |
||
12 |
* the Free Software Foundation; either version 2 of the License, or |
||
13 |
* any later version. |
||
14 |
* |
||
15 |
* This program is distributed in the hope that it will be useful, |
||
16 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
17 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
18 |
* GNU General Public License for more details. |
||
19 |
* |
||
20 |
* You should have received a copy of the GNU General Public License |
||
21 |
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
||
22 |
*/ |
||
23 |
|||
24 |
#include "gui/widgets/itemcontainer.h" |
||
25 |
|||
26 |
#include "dragdrop.h" |
||
27 |
#include "settings.h" |
||
28 |
|||
29 |
#include "being/playerinfo.h" |
||
30 |
|||
31 |
#include "gui/gui.h" |
||
32 |
#include "gui/skin.h" |
||
33 |
#include "gui/viewport.h" |
||
34 |
|||
35 |
#include "gui/fonts/font.h" |
||
36 |
|||
37 |
#include "gui/shortcut/itemshortcut.h" |
||
38 |
|||
39 |
#include "gui/popups/itempopup.h" |
||
40 |
|||
41 |
#include "gui/windows/chatwindow.h" |
||
42 |
#include "gui/windows/inventorywindow.h" |
||
43 |
#include "gui/windows/shopwindow.h" |
||
44 |
#include "gui/windows/shortcutwindow.h" |
||
45 |
#include "gui/windows/itemamountwindow.h" |
||
46 |
#include "gui/windows/maileditwindow.h" |
||
47 |
#include "gui/windows/npcdialog.h" |
||
48 |
|||
49 |
#include "input/inputmanager.h" |
||
50 |
|||
51 |
#include "net/inventoryhandler.h" |
||
52 |
#include "net/net.h" |
||
53 |
#include "net/mail2handler.h" |
||
54 |
#include "net/npchandler.h" |
||
55 |
#include "net/tradehandler.h" |
||
56 |
|||
57 |
#include "utils/delete2.h" |
||
58 |
#include "utils/foreach.h" |
||
59 |
#include "utils/gettext.h" |
||
60 |
#include "utils/stringutils.h" |
||
61 |
|||
62 |
#include "render/vertexes/imagecollection.h" |
||
63 |
|||
64 |
#include "resources/iteminfo.h" |
||
65 |
|||
66 |
#include <algorithm> |
||
67 |
|||
68 |
#include "debug.h" |
||
69 |
|||
70 |
namespace |
||
71 |
{ |
||
72 |
class ItemIdPair final |
||
73 |
{ |
||
74 |
public: |
||
75 |
A_DELETE_COPY(ItemIdPair) |
||
76 |
|||
77 |
ItemIdPair(const int id, Item *const item) : |
||
78 |
mId(id), mItem(item) |
||
79 |
{ |
||
80 |
} |
||
81 |
|||
82 |
int mId; |
||
83 |
Item* mItem; |
||
84 |
}; |
||
85 |
|||
86 |
class SortItemAlphaFunctor final |
||
87 |
{ |
||
88 |
public: |
||
89 |
A_DEFAULT_COPY(SortItemAlphaFunctor) |
||
90 |
|||
91 |
bool operator() (const ItemIdPair *const pair1, |
||
92 |
const ItemIdPair *const pair2) const |
||
93 |
{ |
||
94 |
const Item *const item1 = pair1->mItem; |
||
95 |
const Item *const item2 = pair2->mItem; |
||
96 |
if ((item1 == nullptr) || (item2 == nullptr)) |
||
97 |
return false; |
||
98 |
|||
99 |
const std::string name1 = item1->getInfo().getName( |
||
100 |
item1->getColor()); |
||
101 |
const std::string name2 = item2->getInfo().getName( |
||
102 |
item2->getColor()); |
||
103 |
if (name1 == name2) |
||
104 |
{ |
||
105 |
return item1->getInvIndex() < |
||
106 |
item2->getInvIndex(); |
||
107 |
} |
||
108 |
return name1 < name2; |
||
109 |
} |
||
110 |
} itemAlphaInvSorter; |
||
111 |
|||
112 |
class SortItemIdFunctor final |
||
113 |
{ |
||
114 |
public: |
||
115 |
A_DEFAULT_COPY(SortItemIdFunctor) |
||
116 |
|||
117 |
bool operator() (const ItemIdPair *const pair1, |
||
118 |
const ItemIdPair *const pair2) const |
||
119 |
{ |
||
120 |
if ((pair1->mItem == nullptr) || (pair2->mItem == nullptr)) |
||
121 |
return false; |
||
122 |
|||
123 |
const int id1 = pair1->mItem->getId(); |
||
124 |
const int id2 = pair2->mItem->getId(); |
||
125 |
if (id1 == id2) |
||
126 |
{ |
||
127 |
return pair1->mItem->getInvIndex() < |
||
128 |
pair2->mItem->getInvIndex(); |
||
129 |
} |
||
130 |
return id1 < id2; |
||
131 |
} |
||
132 |
} itemIdInvSorter; |
||
133 |
|||
134 |
class SortItemWeightFunctor final |
||
135 |
{ |
||
136 |
public: |
||
137 |
A_DEFAULT_COPY(SortItemWeightFunctor) |
||
138 |
|||
139 |
bool operator() (const ItemIdPair *const pair1, |
||
140 |
const ItemIdPair *const pair2) const |
||
141 |
{ |
||
142 |
if ((pair1->mItem == nullptr) || (pair2->mItem == nullptr)) |
||
143 |
return false; |
||
144 |
|||
145 |
const int w1 = pair1->mItem->getInfo().getWeight(); |
||
146 |
const int w2 = pair2->mItem->getInfo().getWeight(); |
||
147 |
if (w1 == w2) |
||
148 |
{ |
||
149 |
const std::string name1 = |
||
150 |
pair1->mItem->getInfo().getName(); |
||
151 |
const std::string name2 = |
||
152 |
pair2->mItem->getInfo().getName(); |
||
153 |
if (name1 == name2) |
||
154 |
{ |
||
155 |
return pair1->mItem->getInvIndex() < |
||
156 |
pair2->mItem->getInvIndex(); |
||
157 |
} |
||
158 |
return name1 < name2; |
||
159 |
} |
||
160 |
return w1 < w2; |
||
161 |
} |
||
162 |
} itemWeightInvSorter; |
||
163 |
|||
164 |
class SortItemAmountFunctor final |
||
165 |
{ |
||
166 |
public: |
||
167 |
A_DEFAULT_COPY(SortItemAmountFunctor) |
||
168 |
|||
169 |
bool operator() (const ItemIdPair *const pair1, |
||
170 |
const ItemIdPair *const pair2) const |
||
171 |
{ |
||
172 |
if ((pair1->mItem == nullptr) || (pair2->mItem == nullptr)) |
||
173 |
return false; |
||
174 |
|||
175 |
const int c1 = pair1->mItem->getQuantity(); |
||
176 |
const int c2 = pair2->mItem->getQuantity(); |
||
177 |
if (c1 == c2) |
||
178 |
{ |
||
179 |
const std::string name1 = |
||
180 |
pair1->mItem->getInfo().getName(); |
||
181 |
const std::string name2 = |
||
182 |
pair2->mItem->getInfo().getName(); |
||
183 |
if (name1 == name2) |
||
184 |
{ |
||
185 |
return pair1->mItem->getInvIndex() < |
||
186 |
pair2->mItem->getInvIndex(); |
||
187 |
} |
||
188 |
return name1 < name2; |
||
189 |
} |
||
190 |
return c1 < c2; |
||
191 |
} |
||
192 |
} itemAmountInvSorter; |
||
193 |
|||
194 |
class SortItemTypeFunctor final |
||
195 |
{ |
||
196 |
public: |
||
197 |
A_DEFAULT_COPY(SortItemTypeFunctor) |
||
198 |
|||
199 |
bool operator() (const ItemIdPair *const pair1, |
||
200 |
const ItemIdPair *const pair2) const |
||
201 |
{ |
||
202 |
if ((pair1->mItem == nullptr) || (pair2->mItem == nullptr)) |
||
203 |
return false; |
||
204 |
|||
205 |
const ItemInfo &info1 = pair1->mItem->getInfo(); |
||
206 |
const ItemInfo &info2 = pair2->mItem->getInfo(); |
||
207 |
const ItemDbTypeT t1 = info1.getType(); |
||
208 |
const ItemDbTypeT t2 = info2.getType(); |
||
209 |
if (t1 == t2) |
||
210 |
{ |
||
211 |
const std::string &name1 = info1.getName(); |
||
212 |
const std::string &name2 = info2.getName(); |
||
213 |
if (name1 == name2) |
||
214 |
{ |
||
215 |
return pair1->mItem->getInvIndex() < |
||
216 |
pair2->mItem->getInvIndex(); |
||
217 |
} |
||
218 |
return name1 < name2; |
||
219 |
} |
||
220 |
return t1 < t2; |
||
221 |
} |
||
222 |
} itemTypeInvSorter; |
||
223 |
} // namespace |
||
224 |
|||
225 |
6 |
ItemContainer::ItemContainer(const Widget2 *const widget, |
|
226 |
Inventory *const inventory, |
||
227 |
const int maxColumns, |
||
228 |
const ShowEmptyRows showEmptyRows, |
||
229 |
6 |
const ForceQuantity forceQuantity) : |
|
230 |
Widget(widget), |
||
231 |
KeyListener(), |
||
232 |
MouseListener(), |
||
233 |
WidgetListener(), |
||
234 |
mInventory(inventory), |
||
235 |
✓✗✓✗ ✓✗ |
42 |
mSelImg(Theme::getImageFromThemeXml("item_selection.xml", "")), |
236 |
✓✗✓✗ |
24 |
mProtectedImg(Theme::getImageFromTheme("lock.png")), |
237 |
✓✗✓✗ ✓✗ |
42 |
mCellBackgroundImg(Theme::getImageFromThemeXml("inventory_cell.xml", "")), |
238 |
mName(), |
||
239 |
mShowMatrix(nullptr), |
||
240 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✗✗✗ |
42 |
mSkin(theme != nullptr ? theme->load("itemcontainer.xml", "", |
241 |
✗✓✗✗ |
12 |
true, Theme::getThemePath()) : nullptr), |
242 |
✓✗✓✗ |
6 |
mVertexes(new ImageCollection), |
243 |
12 |
mEquipedColor(getThemeColor(ThemeColorId::ITEM_EQUIPPED, 255U)), |
|
244 |
12 |
mEquipedColor2(getThemeColor(ThemeColorId::ITEM_EQUIPPED_OUTLINE, 255U)), |
|
245 |
12 |
mUnEquipedColor(getThemeColor(ThemeColorId::ITEM_NOT_EQUIPPED, 255U)), |
|
246 |
mUnEquipedColor2(getThemeColor(ThemeColorId::ITEM_NOT_EQUIPPED_OUTLINE, |
||
247 |
12 |
255U)), |
|
248 |
mSelectionListeners(), |
||
249 |
mGridColumns(1), |
||
250 |
mGridRows(1), |
||
251 |
mDrawRows(1), |
||
252 |
mSelectedIndex(-1), |
||
253 |
mLastUsedSlot(-1), |
||
254 |
mTag(0), |
||
255 |
mSortType(0), |
||
256 |
mClicks(1), |
||
257 |
✓✗✓✗ ✓✗✓✗ ✗✗ |
24 |
mBoxWidth(mSkin != nullptr ? mSkin->getOption("boxWidth", 35) : 35), |
258 |
✓✗✓✗ ✓✗✓✗ ✗✗ |
24 |
mBoxHeight(mSkin != nullptr ? mSkin->getOption("boxHeight", 43) : 43), |
259 |
✓✗✓✗ ✓✗✓✗ ✗✗ |
24 |
mEquippedTextPadding(mSkin != nullptr ? mSkin->getOption( |
260 |
"equippedTextPadding", 29) : 29), |
||
261 |
✓✗✓✗ ✓✗✓✗ ✗✗ |
24 |
mPaddingItemX(mSkin != nullptr ? mSkin->getOption("paddingItemX", 0) : 0), |
262 |
✓✗✓✗ ✓✗✓✗ ✗✗ |
24 |
mPaddingItemY(mSkin != nullptr ? mSkin->getOption("paddingItemY", 0) : 0), |
263 |
mMaxColumns(maxColumns), |
||
264 |
mSelectionStatus(SEL_NONE), |
||
265 |
mForceQuantity(forceQuantity), |
||
266 |
mShowEmptyRows(showEmptyRows), |
||
267 |
132 |
mDescItems(false) |
|
268 |
{ |
||
269 |
✓✗ | 6 |
setFocusable(true); |
270 |
✓✗ | 6 |
addKeyListener(this); |
271 |
✓✗ | 6 |
addMouseListener(this); |
272 |
✓✗ | 6 |
addWidgetListener(this); |
273 |
6 |
mAllowLogic = false; |
|
274 |
6 |
} |
|
275 |
|||
276 |
48 |
ItemContainer::~ItemContainer() |
|
277 |
{ |
||
278 |
✓✗ | 6 |
if (gui != nullptr) |
279 |
6 |
gui->removeDragged(this); |
|
280 |
|||
281 |
✓✗ | 6 |
if (mSelImg != nullptr) |
282 |
{ |
||
283 |
6 |
mSelImg->decRef(); |
|
284 |
6 |
mSelImg = nullptr; |
|
285 |
} |
||
286 |
✓✗ | 6 |
if (mProtectedImg != nullptr) |
287 |
{ |
||
288 |
6 |
mProtectedImg->decRef(); |
|
289 |
6 |
mProtectedImg = nullptr; |
|
290 |
} |
||
291 |
✗✓ | 6 |
if (mCellBackgroundImg != nullptr) |
292 |
{ |
||
293 |
mCellBackgroundImg->decRef(); |
||
294 |
mCellBackgroundImg = nullptr; |
||
295 |
} |
||
296 |
|||
297 |
✓✗ | 6 |
if (theme != nullptr) |
298 |
6 |
theme->unload(mSkin); |
|
299 |
|||
300 |
✓✓ | 6 |
delete []mShowMatrix; |
301 |
✓✗ | 6 |
delete2(mVertexes) |
302 |
12 |
} |
|
303 |
|||
304 |
void ItemContainer::logic() |
||
305 |
{ |
||
306 |
BLOCK_START("ItemContainer::logic") |
||
307 |
Widget::logic(); |
||
308 |
|||
309 |
if (mInventory == nullptr) |
||
310 |
{ |
||
311 |
BLOCK_END("ItemContainer::logic") |
||
312 |
return; |
||
313 |
} |
||
314 |
|||
315 |
const int lastUsedSlot = mInventory->getLastUsedSlot(); |
||
316 |
|||
317 |
if (lastUsedSlot != mLastUsedSlot) |
||
318 |
{ |
||
319 |
mLastUsedSlot = lastUsedSlot; |
||
320 |
adjustHeight(); |
||
321 |
} |
||
322 |
BLOCK_END("ItemContainer::logic") |
||
323 |
} |
||
324 |
|||
325 |
2 |
void ItemContainer::draw(Graphics *const graphics) |
|
326 |
{ |
||
327 |
✓✗✗✓ |
2 |
if ((mInventory == nullptr) || (mShowMatrix == nullptr)) |
328 |
return; |
||
329 |
|||
330 |
BLOCK_START("ItemContainer::draw") |
||
331 |
Font *const font = getFont(); |
||
332 |
|||
333 |
if (mCellBackgroundImg != nullptr) |
||
334 |
{ |
||
335 |
if (mRedraw || graphics->getRedraw()) |
||
336 |
{ |
||
337 |
mRedraw = false; |
||
338 |
mVertexes->clear(); |
||
339 |
|||
340 |
const int invSize = mInventory->getSize(); |
||
341 |
const int maxRows = mShowEmptyRows == ShowEmptyRows_true ? |
||
342 |
std::max(invSize / mGridColumns, mGridRows) : mGridRows; |
||
343 |
const int maxColumns = mGridColumns > invSize ? |
||
344 |
invSize : mGridColumns; |
||
345 |
for (int j = 0; j < maxRows; j++) |
||
346 |
{ |
||
347 |
const int intY0 = j * mBoxHeight; |
||
348 |
for (int i = 0; i < maxColumns; i++) |
||
349 |
{ |
||
350 |
int itemX = i * mBoxWidth; |
||
351 |
int itemY = intY0; |
||
352 |
graphics->calcTileCollection(mVertexes, |
||
353 |
mCellBackgroundImg, |
||
354 |
itemX + mPaddingItemX, |
||
355 |
itemY + mPaddingItemY); |
||
356 |
} |
||
357 |
} |
||
358 |
graphics->finalize(mVertexes); |
||
359 |
} |
||
360 |
graphics->drawTileCollection(mVertexes); |
||
361 |
} |
||
362 |
|||
363 |
for (int j = 0; j < mDrawRows; j++) |
||
364 |
{ |
||
365 |
const int intY0 = j * mBoxHeight; |
||
366 |
int itemIndex = j * mGridColumns - 1; |
||
367 |
for (int i = 0; i < mGridColumns; i++) |
||
368 |
{ |
||
369 |
itemIndex ++; |
||
370 |
if (mShowMatrix[itemIndex] < 0) |
||
371 |
continue; |
||
372 |
|||
373 |
const Item *const item = mInventory->getItem( |
||
374 |
mShowMatrix[itemIndex]); |
||
375 |
|||
376 |
if ((item == nullptr) || item->getId() == 0) |
||
377 |
continue; |
||
378 |
|||
379 |
Image *const image = item->getImage(); |
||
380 |
if (image != nullptr) |
||
381 |
{ |
||
382 |
int itemX = i * mBoxWidth; |
||
383 |
int itemY = intY0; |
||
384 |
if (mShowMatrix[itemIndex] == mSelectedIndex) |
||
385 |
{ |
||
386 |
if (mSelImg != nullptr) |
||
387 |
graphics->drawImage(mSelImg, itemX, itemY); |
||
388 |
} |
||
389 |
image->setAlpha(1.0F); // ensure the image if fully drawn... |
||
390 |
graphics->drawImage(image, |
||
391 |
itemX + mPaddingItemX, |
||
392 |
itemY + mPaddingItemY); |
||
393 |
if ((mProtectedImg != nullptr) && PlayerInfo::isItemProtected( |
||
394 |
item->getId())) |
||
395 |
{ |
||
396 |
graphics->drawImage(mProtectedImg, |
||
397 |
itemX + mPaddingItemX, |
||
398 |
itemY + mPaddingItemY); |
||
399 |
} |
||
400 |
} |
||
401 |
} |
||
402 |
} |
||
403 |
|||
404 |
for (int j = 0; j < mDrawRows; j++) |
||
405 |
{ |
||
406 |
const int intY0 = j * mBoxHeight; |
||
407 |
int itemIndex = j * mGridColumns - 1; |
||
408 |
for (int i = 0; i < mGridColumns; i++) |
||
409 |
{ |
||
410 |
int itemX = i * mBoxWidth; |
||
411 |
int itemY = intY0; |
||
412 |
itemIndex ++; |
||
413 |
if (mShowMatrix[itemIndex] < 0) |
||
414 |
continue; |
||
415 |
|||
416 |
const Item *const item = mInventory->getItem( |
||
417 |
mShowMatrix[itemIndex]); |
||
418 |
|||
419 |
if ((item == nullptr) || item->getId() == 0) |
||
420 |
continue; |
||
421 |
|||
422 |
// Draw item caption |
||
423 |
std::string caption; |
||
424 |
if (item->getQuantity() > 1 || |
||
425 |
mForceQuantity == ForceQuantity_true) |
||
426 |
{ |
||
427 |
caption = toString(item->getQuantity()); |
||
428 |
} |
||
429 |
else if (item->isEquipped() == Equipped_true) |
||
430 |
{ |
||
431 |
// TRANSLATORS: Text under equipped items (should be small) |
||
432 |
caption = _("Eq."); |
||
433 |
} |
||
434 |
|||
435 |
if (item->isEquipped() == Equipped_true) |
||
436 |
{ |
||
437 |
font->drawString(graphics, |
||
438 |
mEquipedColor, mEquipedColor2, |
||
439 |
caption, |
||
440 |
itemX + (mBoxWidth - font->getWidth(caption)) / 2, |
||
441 |
itemY + mEquippedTextPadding); |
||
442 |
} |
||
443 |
else |
||
444 |
{ |
||
445 |
font->drawString(graphics, |
||
446 |
mUnEquipedColor, mUnEquipedColor2, |
||
447 |
caption, |
||
448 |
itemX + (mBoxWidth - font->getWidth(caption)) / 2, |
||
449 |
itemY + mEquippedTextPadding); |
||
450 |
} |
||
451 |
} |
||
452 |
} |
||
453 |
BLOCK_END("ItemContainer::draw") |
||
454 |
} |
||
455 |
|||
456 |
void ItemContainer::safeDraw(Graphics *const graphics) |
||
457 |
{ |
||
458 |
if ((mInventory == nullptr) || (mShowMatrix == nullptr)) |
||
459 |
return; |
||
460 |
|||
461 |
BLOCK_START("ItemContainer::draw") |
||
462 |
Font *const font = getFont(); |
||
463 |
|||
464 |
if (mCellBackgroundImg != nullptr) |
||
465 |
{ |
||
466 |
const int invSize = mInventory->getSize(); |
||
467 |
const int maxRows = mShowEmptyRows == ShowEmptyRows_true ? |
||
468 |
std::max(invSize / mGridColumns, mGridRows) : mGridRows; |
||
469 |
const int maxColumns = mGridColumns > invSize ? |
||
470 |
invSize : mGridColumns; |
||
471 |
for (int j = 0; j < maxRows; j++) |
||
472 |
{ |
||
473 |
const int intY0 = j * mBoxHeight; |
||
474 |
for (int i = 0; i < maxColumns; i++) |
||
475 |
{ |
||
476 |
int itemX = i * mBoxWidth; |
||
477 |
int itemY = intY0; |
||
478 |
graphics->drawImage(mCellBackgroundImg, |
||
479 |
itemX + mPaddingItemX, |
||
480 |
itemY + mPaddingItemY); |
||
481 |
} |
||
482 |
} |
||
483 |
} |
||
484 |
|||
485 |
for (int j = 0; j < mDrawRows; j++) |
||
486 |
{ |
||
487 |
const int intY0 = j * mBoxHeight; |
||
488 |
int itemIndex = j * mGridColumns - 1; |
||
489 |
for (int i = 0; i < mGridColumns; i++) |
||
490 |
{ |
||
491 |
itemIndex ++; |
||
492 |
if (mShowMatrix[itemIndex] < 0) |
||
493 |
continue; |
||
494 |
|||
495 |
const Item *const item = mInventory->getItem( |
||
496 |
mShowMatrix[itemIndex]); |
||
497 |
|||
498 |
if ((item == nullptr) || item->getId() == 0) |
||
499 |
continue; |
||
500 |
|||
501 |
Image *const image = item->getImage(); |
||
502 |
if (image != nullptr) |
||
503 |
{ |
||
504 |
int itemX = i * mBoxWidth; |
||
505 |
int itemY = intY0; |
||
506 |
if (mShowMatrix[itemIndex] == mSelectedIndex) |
||
507 |
{ |
||
508 |
if (mSelImg != nullptr) |
||
509 |
graphics->drawImage(mSelImg, itemX, itemY); |
||
510 |
} |
||
511 |
image->setAlpha(1.0F); // ensure the image if fully drawn... |
||
512 |
graphics->drawImage(image, |
||
513 |
itemX + mPaddingItemX, |
||
514 |
itemY + mPaddingItemY); |
||
515 |
if ((mProtectedImg != nullptr) && PlayerInfo::isItemProtected( |
||
516 |
item->getId())) |
||
517 |
{ |
||
518 |
graphics->drawImage(mProtectedImg, |
||
519 |
itemX + mPaddingItemX, |
||
520 |
itemY + mPaddingItemY); |
||
521 |
} |
||
522 |
} |
||
523 |
} |
||
524 |
} |
||
525 |
|||
526 |
for (int j = 0; j < mDrawRows; j++) |
||
527 |
{ |
||
528 |
const int intY0 = j * mBoxHeight; |
||
529 |
int itemIndex = j * mGridColumns - 1; |
||
530 |
for (int i = 0; i < mGridColumns; i++) |
||
531 |
{ |
||
532 |
int itemX = i * mBoxWidth; |
||
533 |
int itemY = intY0; |
||
534 |
itemIndex ++; |
||
535 |
if (mShowMatrix[itemIndex] < 0) |
||
536 |
continue; |
||
537 |
|||
538 |
const Item *const item = mInventory->getItem( |
||
539 |
mShowMatrix[itemIndex]); |
||
540 |
|||
541 |
if ((item == nullptr) || item->getId() == 0) |
||
542 |
continue; |
||
543 |
|||
544 |
// Draw item caption |
||
545 |
std::string caption; |
||
546 |
if (item->getQuantity() > 1 || |
||
547 |
mForceQuantity == ForceQuantity_true) |
||
548 |
{ |
||
549 |
caption = toString(item->getQuantity()); |
||
550 |
} |
||
551 |
else if (item->isEquipped() == Equipped_true) |
||
552 |
{ |
||
553 |
// TRANSLATORS: Text under equipped items (should be small) |
||
554 |
caption = _("Eq."); |
||
555 |
} |
||
556 |
|||
557 |
if (item->isEquipped() == Equipped_true) |
||
558 |
{ |
||
559 |
font->drawString(graphics, |
||
560 |
mEquipedColor, mEquipedColor2, |
||
561 |
caption, |
||
562 |
itemX + (mBoxWidth - font->getWidth(caption)) / 2, |
||
563 |
itemY + mEquippedTextPadding); |
||
564 |
} |
||
565 |
else |
||
566 |
{ |
||
567 |
font->drawString(graphics, |
||
568 |
mUnEquipedColor, mUnEquipedColor2, |
||
569 |
caption, |
||
570 |
itemX + (mBoxWidth - font->getWidth(caption)) / 2, |
||
571 |
itemY + mEquippedTextPadding); |
||
572 |
} |
||
573 |
} |
||
574 |
} |
||
575 |
BLOCK_END("ItemContainer::draw") |
||
576 |
} |
||
577 |
|||
578 |
void ItemContainer::selectNone() |
||
579 |
{ |
||
580 |
dragDrop.clear(); |
||
581 |
|||
582 |
setSelectedIndex(-1); |
||
583 |
mSelectionStatus = SEL_NONE; |
||
584 |
/* |
||
585 |
if (outfitWindow) |
||
586 |
outfitWindow->setItemSelected(-1); |
||
587 |
if (shopWindow) |
||
588 |
shopWindow->setItemSelected(-1); |
||
589 |
*/ |
||
590 |
} |
||
591 |
|||
592 |
void ItemContainer::setSelectedIndex(const int newIndex) |
||
593 |
{ |
||
594 |
if (mSelectedIndex != newIndex) |
||
595 |
{ |
||
596 |
mSelectedIndex = newIndex; |
||
597 |
distributeValueChangedEvent(); |
||
598 |
} |
||
599 |
} |
||
600 |
|||
601 |
1 |
Item *ItemContainer::getSelectedItem() const |
|
602 |
{ |
||
603 |
✓✗ | 1 |
if (mInventory != nullptr) |
604 |
1 |
return mInventory->getItem(mSelectedIndex); |
|
605 |
return nullptr; |
||
606 |
} |
||
607 |
|||
608 |
void ItemContainer::distributeValueChangedEvent() |
||
609 |
{ |
||
610 |
FOR_EACH (SelectionListenerIterator, i, mSelectionListeners) |
||
611 |
{ |
||
612 |
if (*i != nullptr) |
||
613 |
{ |
||
614 |
SelectionEvent event(this); |
||
615 |
(*i)->valueChanged(event); |
||
616 |
} |
||
617 |
} |
||
618 |
} |
||
619 |
|||
620 |
void ItemContainer::keyPressed(KeyEvent &event A_UNUSED) |
||
621 |
{ |
||
622 |
} |
||
623 |
|||
624 |
void ItemContainer::keyReleased(KeyEvent &event A_UNUSED) |
||
625 |
{ |
||
626 |
} |
||
627 |
|||
628 |
void ItemContainer::mousePressed(MouseEvent &event) |
||
629 |
{ |
||
630 |
if (mInventory == nullptr) |
||
631 |
return; |
||
632 |
|||
633 |
const MouseButtonT button = event.getButton(); |
||
634 |
mClicks = event.getClickCount(); |
||
635 |
|||
636 |
if (button == MouseButton::LEFT || button == MouseButton::RIGHT) |
||
637 |
{ |
||
638 |
event.consume(); |
||
639 |
const int index = getSlotIndex(event.getX(), event.getY()); |
||
640 |
if (index == Inventory::NO_SLOT_INDEX) |
||
641 |
return; |
||
642 |
|||
643 |
Item *const item = mInventory->getItem(index); |
||
644 |
|||
645 |
// put item name into chat window |
||
646 |
if ((item != nullptr) && mDescItems && (chatWindow != nullptr)) |
||
647 |
chatWindow->addItemText(item->getInfo().getName()); |
||
648 |
|||
649 |
DragDropSourceT src = DragDropSource::Empty; |
||
650 |
switch (mInventory->getType()) |
||
651 |
{ |
||
652 |
case InventoryType::Inventory: |
||
653 |
src = DragDropSource::Inventory; |
||
654 |
break; |
||
655 |
case InventoryType::Storage: |
||
656 |
src = DragDropSource::Storage; |
||
657 |
break; |
||
658 |
case InventoryType::Trade: |
||
659 |
src = DragDropSource::Trade; |
||
660 |
break; |
||
661 |
case InventoryType::Npc: |
||
662 |
src = DragDropSource::Npc; |
||
663 |
break; |
||
664 |
case InventoryType::Cart: |
||
665 |
src = DragDropSource::Cart; |
||
666 |
break; |
||
667 |
case InventoryType::MailEdit: |
||
668 |
src = DragDropSource::MailEdit; |
||
669 |
break; |
||
670 |
case InventoryType::MailView: |
||
671 |
src = DragDropSource::MailView; |
||
672 |
break; |
||
673 |
case InventoryType::Craft: |
||
674 |
src = DragDropSource::Craft; |
||
675 |
break; |
||
676 |
default: |
||
677 |
case InventoryType::Vending: |
||
678 |
case InventoryType::TypeEnd: |
||
679 |
break; |
||
680 |
} |
||
681 |
if (src == DragDropSource::MailView) |
||
682 |
return; |
||
683 |
if (mSelectedIndex == index && mClicks != 2) |
||
684 |
{ |
||
685 |
dragDrop.dragItem(item, src, index); |
||
686 |
dragDrop.select(item); |
||
687 |
mSelectionStatus = SEL_DESELECTING; |
||
688 |
} |
||
689 |
else if ((item != nullptr) && (item->getId() != 0)) |
||
690 |
{ |
||
691 |
if (index >= 0) |
||
692 |
{ |
||
693 |
dragDrop.dragItem(item, src, index); |
||
694 |
dragDrop.select(item); |
||
695 |
setSelectedIndex(index); |
||
696 |
mSelectionStatus = SEL_SELECTING; |
||
697 |
|||
698 |
if (itemShortcutWindow != nullptr) |
||
699 |
{ |
||
700 |
const int num = itemShortcutWindow->getTabIndex(); |
||
701 |
if (num >= 0 && num < CAST_S32(SHORTCUT_TABS)) |
||
702 |
{ |
||
703 |
if (itemShortcut[num] != nullptr) |
||
704 |
itemShortcut[num]->setItemSelected(item); |
||
705 |
} |
||
706 |
} |
||
707 |
if (shopWindow != nullptr) |
||
708 |
shopWindow->setItemSelected(item->getId()); |
||
709 |
} |
||
710 |
} |
||
711 |
else |
||
712 |
{ |
||
713 |
dragDrop.deselect(); |
||
714 |
selectNone(); |
||
715 |
} |
||
716 |
} |
||
717 |
} |
||
718 |
|||
719 |
void ItemContainer::mouseDragged(MouseEvent &event A_UNUSED) |
||
720 |
{ |
||
721 |
if (mSelectionStatus != SEL_NONE) |
||
722 |
mSelectionStatus = SEL_DRAGGING; |
||
723 |
} |
||
724 |
|||
725 |
void ItemContainer::mouseReleased(MouseEvent &event) |
||
726 |
{ |
||
727 |
if (mClicks == 2 || |
||
728 |
inventoryHandler == nullptr || |
||
729 |
tradeHandler == nullptr) |
||
730 |
{ |
||
731 |
return; |
||
732 |
} |
||
733 |
|||
734 |
switch (mSelectionStatus) |
||
735 |
{ |
||
736 |
case SEL_SELECTING: |
||
737 |
mSelectionStatus = SEL_SELECTED; |
||
738 |
break; |
||
739 |
case SEL_DESELECTING: |
||
740 |
selectNone(); |
||
741 |
break; |
||
742 |
case SEL_DRAGGING: |
||
743 |
mSelectionStatus = SEL_SELECTED; |
||
744 |
break; |
||
745 |
case SEL_NONE: |
||
746 |
case SEL_SELECTED: |
||
747 |
default: |
||
748 |
break; |
||
749 |
} |
||
750 |
|||
751 |
if (dragDrop.isEmpty()) |
||
752 |
{ |
||
753 |
const int index = getSlotIndex(event.getX(), event.getY()); |
||
754 |
if (index == Inventory::NO_SLOT_INDEX) |
||
755 |
return; |
||
756 |
if (index == mSelectedIndex || mSelectedIndex == -1) |
||
757 |
return; |
||
758 |
inventoryHandler->moveItem(mSelectedIndex, index); |
||
759 |
selectNone(); |
||
760 |
} |
||
761 |
else if (mInventory != nullptr) |
||
762 |
{ |
||
763 |
const DragDropSourceT src = dragDrop.getSource(); |
||
764 |
DragDropSourceT dst = DragDropSource::Empty; |
||
765 |
switch (mInventory->getType()) |
||
766 |
{ |
||
767 |
case InventoryType::Inventory: |
||
768 |
dst = DragDropSource::Inventory; |
||
769 |
break; |
||
770 |
case InventoryType::Storage: |
||
771 |
dst = DragDropSource::Storage; |
||
772 |
break; |
||
773 |
case InventoryType::Trade: |
||
774 |
dst = DragDropSource::Trade; |
||
775 |
break; |
||
776 |
case InventoryType::Npc: |
||
777 |
dst = DragDropSource::Npc; |
||
778 |
break; |
||
779 |
case InventoryType::MailEdit: |
||
780 |
dst = DragDropSource::MailEdit; |
||
781 |
break; |
||
782 |
case InventoryType::MailView: |
||
783 |
dst = DragDropSource::MailView; |
||
784 |
break; |
||
785 |
case InventoryType::Cart: |
||
786 |
dst = DragDropSource::Cart; |
||
787 |
break; |
||
788 |
case InventoryType::Craft: |
||
789 |
dst = DragDropSource::Craft; |
||
790 |
break; |
||
791 |
default: |
||
792 |
case InventoryType::Vending: |
||
793 |
case InventoryType::TypeEnd: |
||
794 |
break; |
||
795 |
} |
||
796 |
InventoryTypeT srcContainer = InventoryType::TypeEnd; |
||
797 |
InventoryTypeT dstContainer = InventoryType::TypeEnd; |
||
798 |
bool checkProtection(false); |
||
799 |
Inventory *inventory = nullptr; |
||
800 |
if (src == DragDropSource::Inventory |
||
801 |
&& dst == DragDropSource::Storage) |
||
802 |
{ |
||
803 |
srcContainer = InventoryType::Inventory; |
||
804 |
dstContainer = InventoryType::Storage; |
||
805 |
inventory = PlayerInfo::getInventory(); |
||
806 |
} |
||
807 |
else if (src == DragDropSource::Storage |
||
808 |
&& dst == DragDropSource::Inventory) |
||
809 |
{ |
||
810 |
srcContainer = InventoryType::Storage; |
||
811 |
dstContainer = InventoryType::Inventory; |
||
812 |
inventory = PlayerInfo::getStorageInventory(); |
||
813 |
} |
||
814 |
if (src == DragDropSource::Inventory |
||
815 |
&& dst == DragDropSource::Cart) |
||
816 |
{ |
||
817 |
srcContainer = InventoryType::Inventory; |
||
818 |
dstContainer = InventoryType::Cart; |
||
819 |
inventory = PlayerInfo::getInventory(); |
||
820 |
} |
||
821 |
if (src == DragDropSource::Inventory |
||
822 |
&& dst == DragDropSource::Inventory) |
||
823 |
{ |
||
824 |
if (Net::getNetworkType() == ServerType::TMWATHENA) |
||
825 |
return; |
||
826 |
const int index = getSlotIndex(event.getX(), event.getY()); |
||
827 |
if (index == Inventory::NO_SLOT_INDEX) |
||
828 |
return; |
||
829 |
if (index == mSelectedIndex || mSelectedIndex == -1) |
||
830 |
return; |
||
831 |
if (inventoryWindow != nullptr) |
||
832 |
inventoryWindow->combineItems(index, mSelectedIndex); |
||
833 |
return; |
||
834 |
} |
||
835 |
else if (src == DragDropSource::Cart |
||
836 |
&& dst == DragDropSource::Inventory) |
||
837 |
{ |
||
838 |
srcContainer = InventoryType::Cart; |
||
839 |
dstContainer = InventoryType::Inventory; |
||
840 |
inventory = PlayerInfo::getCartInventory(); |
||
841 |
} |
||
842 |
else if (src == DragDropSource::Cart |
||
843 |
&& dst == DragDropSource::Storage) |
||
844 |
{ |
||
845 |
srcContainer = InventoryType::Cart; |
||
846 |
dstContainer = InventoryType::Storage; |
||
847 |
inventory = PlayerInfo::getCartInventory(); |
||
848 |
} |
||
849 |
else if (src == DragDropSource::Storage |
||
850 |
&& dst == DragDropSource::Cart) |
||
851 |
{ |
||
852 |
srcContainer = InventoryType::Storage; |
||
853 |
dstContainer = InventoryType::Cart; |
||
854 |
inventory = PlayerInfo::getStorageInventory(); |
||
855 |
} |
||
856 |
if (src == DragDropSource::Inventory |
||
857 |
&& dst == DragDropSource::Trade) |
||
858 |
{ |
||
859 |
checkProtection = true; |
||
860 |
inventory = PlayerInfo::getInventory(); |
||
861 |
} |
||
862 |
else if (src == DragDropSource::Inventory && |
||
863 |
dst == DragDropSource::Npc) |
||
864 |
{ |
||
865 |
inventory = PlayerInfo::getInventory(); |
||
866 |
if (inventory != nullptr) |
||
867 |
{ |
||
868 |
Item *const item = inventory->getItem(dragDrop.getTag()); |
||
869 |
if (mInventory->addVirtualItem( |
||
870 |
item, |
||
871 |
getSlotByXY(event.getX(), event.getY()), |
||
872 |
1)) |
||
873 |
{ |
||
874 |
inventory->virtualRemove(item, 1); |
||
875 |
} |
||
876 |
} |
||
877 |
return; |
||
878 |
} |
||
879 |
else if (src == DragDropSource::Inventory && |
||
880 |
dst == DragDropSource::MailEdit) |
||
881 |
{ |
||
882 |
inventory = PlayerInfo::getInventory(); |
||
883 |
if (inventory == nullptr) |
||
884 |
return; |
||
885 |
Item *const item = inventory->getItem(dragDrop.getTag()); |
||
886 |
if (item == nullptr) |
||
887 |
return; |
||
888 |
if (settings.enableNewMailSystem) |
||
889 |
{ |
||
890 |
if (item->getQuantity() > 1 |
||
891 |
&& !inputManager.isActionActive(InputAction::STOP_ATTACK)) |
||
892 |
{ |
||
893 |
ItemAmountWindow::showWindow( |
||
894 |
ItemAmountWindowUsage::MailAdd, |
||
895 |
mailEditWindow, |
||
896 |
item, |
||
897 |
0, |
||
898 |
0); |
||
899 |
} |
||
900 |
else |
||
901 |
{ |
||
902 |
mail2Handler->addItem(item, 1); |
||
903 |
} |
||
904 |
} |
||
905 |
else |
||
906 |
{ |
||
907 |
if (mInventory->addVirtualItem( |
||
908 |
item, |
||
909 |
getSlotByXY(event.getX(), event.getY()), |
||
910 |
1)) |
||
911 |
{ |
||
912 |
inventory->virtualRemove(item, 1); |
||
913 |
} |
||
914 |
} |
||
915 |
return; |
||
916 |
} |
||
917 |
else if (src == DragDropSource::Npc) |
||
918 |
{ |
||
919 |
inventory = PlayerInfo::getInventory(); |
||
920 |
if (dst == DragDropSource::Npc) |
||
921 |
{ |
||
922 |
const Item *const item = mInventory->getItem( |
||
923 |
dragDrop.getTag()); |
||
924 |
const int index = getSlotByXY(event.getX(), event.getY()); |
||
925 |
if (index == Inventory::NO_SLOT_INDEX) |
||
926 |
{ |
||
927 |
if (inventory != nullptr) |
||
928 |
inventory->virtualRestore(item, 1); |
||
929 |
mInventory->removeItemAt(dragDrop.getTag()); |
||
930 |
return; |
||
931 |
} |
||
932 |
mInventory->removeItemAt(index); |
||
933 |
mInventory->setItem(index, |
||
934 |
item->getId(), |
||
935 |
item->getType(), |
||
936 |
1, |
||
937 |
1, |
||
938 |
item->getColor(), |
||
939 |
item->getIdentified(), |
||
940 |
item->getDamaged(), |
||
941 |
item->getFavorite(), |
||
942 |
Equipm_false, |
||
943 |
Equipped_false); |
||
944 |
Item *const item2 = mInventory->getItem(index); |
||
945 |
if (item2 != nullptr) |
||
946 |
item2->setTag(item->getTag()); |
||
947 |
mInventory->removeItemAt(dragDrop.getTag()); |
||
948 |
} |
||
949 |
else |
||
950 |
{ |
||
951 |
if (inventory != nullptr) |
||
952 |
{ |
||
953 |
const Item *const item = inventory->getItem( |
||
954 |
dragDrop.getTag()); |
||
955 |
if (item != nullptr) |
||
956 |
{ |
||
957 |
inventory->virtualRestore(item, 1); |
||
958 |
mInventory->removeItemAt(dragDrop.getTag()); |
||
959 |
} |
||
960 |
} |
||
961 |
return; |
||
962 |
} |
||
963 |
} |
||
964 |
else if (src == DragDropSource::Inventory && |
||
965 |
dst == DragDropSource::Craft) |
||
966 |
{ |
||
967 |
inventory = PlayerInfo::getInventory(); |
||
968 |
if (inventory != nullptr) |
||
969 |
{ |
||
970 |
Item *const item = inventory->getItem(dragDrop.getTag()); |
||
971 |
if ((item == nullptr) || item->isEquipped() == Equipped_true) |
||
972 |
return; |
||
973 |
const int slot = getSlotByXY(event.getX(), event.getY()); |
||
974 |
if (item->getQuantity() > 1 |
||
975 |
&& !inputManager.isActionActive(InputAction::STOP_ATTACK)) |
||
976 |
{ |
||
977 |
ItemAmountWindow::showWindow( |
||
978 |
ItemAmountWindowUsage::CraftAdd, |
||
979 |
npcHandler->getCurrentNpcDialog(), |
||
980 |
item, |
||
981 |
0, |
||
982 |
slot); |
||
983 |
} |
||
984 |
else |
||
985 |
{ |
||
986 |
if (mInventory->addVirtualItem( |
||
987 |
item, |
||
988 |
slot, |
||
989 |
1)) |
||
990 |
{ |
||
991 |
inventory->virtualRemove(item, 1); |
||
992 |
} |
||
993 |
} |
||
994 |
} |
||
995 |
return; |
||
996 |
} |
||
997 |
else if (src == DragDropSource::Craft) |
||
998 |
{ |
||
999 |
inventory = PlayerInfo::getInventory(); |
||
1000 |
if (dst == DragDropSource::Craft) |
||
1001 |
{ |
||
1002 |
const Item *const item = mInventory->getItem( |
||
1003 |
dragDrop.getTag()); |
||
1004 |
const int index = getSlotByXY(event.getX(), event.getY()); |
||
1005 |
if (index == Inventory::NO_SLOT_INDEX) |
||
1006 |
{ |
||
1007 |
if (inventory != nullptr) |
||
1008 |
{ |
||
1009 |
inventory->virtualRestore(item, |
||
1010 |
item->getQuantity()); |
||
1011 |
mInventory->removeItemAt(dragDrop.getTag()); |
||
1012 |
} |
||
1013 |
return; |
||
1014 |
} |
||
1015 |
mInventory->moveItem(index, dragDrop.getTag()); |
||
1016 |
} |
||
1017 |
else |
||
1018 |
{ |
||
1019 |
if (inventory != nullptr) |
||
1020 |
{ |
||
1021 |
const Item *const item = inventory->getItem( |
||
1022 |
dragDrop.getTag()); |
||
1023 |
if (item != nullptr) |
||
1024 |
{ |
||
1025 |
inventory->virtualRestore(item, |
||
1026 |
item->getQuantity()); |
||
1027 |
mInventory->removeItemAt(dragDrop.getTag()); |
||
1028 |
} |
||
1029 |
} |
||
1030 |
return; |
||
1031 |
} |
||
1032 |
} |
||
1033 |
else if (src == DragDropSource::MailEdit) |
||
1034 |
{ |
||
1035 |
if (event.getType() == MouseEventType::RELEASED2) |
||
1036 |
return; |
||
1037 |
if (settings.enableNewMailSystem) |
||
1038 |
{ |
||
1039 |
if (mailEditWindow == nullptr) |
||
1040 |
return; |
||
1041 |
inventory = mailEditWindow->getInventory(); |
||
1042 |
if (inventory == nullptr) |
||
1043 |
return; |
||
1044 |
const Item *const item = inventory->getItem(dragDrop.getTag()); |
||
1045 |
if (item == nullptr) |
||
1046 |
return; |
||
1047 |
mail2Handler->removeItem(item->getTag(), |
||
1048 |
item->getQuantity()); |
||
1049 |
} |
||
1050 |
else |
||
1051 |
{ |
||
1052 |
inventory = PlayerInfo::getInventory(); |
||
1053 |
if (inventory == nullptr) |
||
1054 |
return; |
||
1055 |
const Item *const item = inventory->getItem(dragDrop.getTag()); |
||
1056 |
if (item == nullptr) |
||
1057 |
return; |
||
1058 |
mInventory->removeItemAt(dragDrop.getTag()); |
||
1059 |
} |
||
1060 |
return; |
||
1061 |
} |
||
1062 |
|||
1063 |
if (inventory != nullptr) |
||
1064 |
{ |
||
1065 |
const Item *const item = inventory->getItem(dragDrop.getTag()); |
||
1066 |
if (item != nullptr) |
||
1067 |
{ |
||
1068 |
if (srcContainer != InventoryType::TypeEnd) |
||
1069 |
{ // inventory <--> storage, cart |
||
1070 |
inventoryHandler->moveItem2(srcContainer, |
||
1071 |
item->getInvIndex(), |
||
1072 |
item->getQuantity(), |
||
1073 |
dstContainer); |
||
1074 |
} |
||
1075 |
else |
||
1076 |
{ // inventory --> trade |
||
1077 |
if (!checkProtection || !PlayerInfo::isItemProtected( |
||
1078 |
item->getId())) |
||
1079 |
{ |
||
1080 |
tradeHandler->addItem(item, item->getQuantity()); |
||
1081 |
} |
||
1082 |
} |
||
1083 |
} |
||
1084 |
} |
||
1085 |
} |
||
1086 |
} |
||
1087 |
|||
1088 |
void ItemContainer::mouseMoved(MouseEvent &event) |
||
1089 |
{ |
||
1090 |
if (mInventory == nullptr) |
||
1091 |
return; |
||
1092 |
|||
1093 |
const Item *const item = mInventory->getItem( |
||
1094 |
getSlotIndex(event.getX(), event.getY())); |
||
1095 |
|||
1096 |
if ((item != nullptr) && (viewport != nullptr)) |
||
1097 |
{ |
||
1098 |
itemPopup->setItem(item, false); |
||
1099 |
itemPopup->position(viewport->mMouseX, viewport->mMouseY); |
||
1100 |
} |
||
1101 |
else |
||
1102 |
{ |
||
1103 |
itemPopup->setVisible(Visible_false); |
||
1104 |
} |
||
1105 |
} |
||
1106 |
|||
1107 |
void ItemContainer::mouseExited(MouseEvent &event A_UNUSED) |
||
1108 |
{ |
||
1109 |
itemPopup->setVisible(Visible_false); |
||
1110 |
} |
||
1111 |
|||
1112 |
void ItemContainer::widgetResized(const Event &event A_UNUSED) |
||
1113 |
{ |
||
1114 |
updateSize(); |
||
1115 |
} |
||
1116 |
|||
1117 |
void ItemContainer::updateSize() |
||
1118 |
{ |
||
1119 |
mGridColumns = std::min(mMaxColumns, |
||
1120 |
std::max(1, mDimension.width / mBoxWidth)); |
||
1121 |
if (mGridColumns > mMaxColumns) |
||
1122 |
mGridColumns = mMaxColumns; |
||
1123 |
adjustHeight(); |
||
1124 |
mRedraw = true; |
||
1125 |
} |
||
1126 |
|||
1127 |
void ItemContainer::widgetMoved(const Event &event A_UNUSED) |
||
1128 |
{ |
||
1129 |
mRedraw = true; |
||
1130 |
} |
||
1131 |
|||
1132 |
void ItemContainer::adjustHeight() |
||
1133 |
{ |
||
1134 |
if (mGridColumns == 0) |
||
1135 |
return; |
||
1136 |
|||
1137 |
mGridRows = (mLastUsedSlot + 1) / mGridColumns; |
||
1138 |
if (mGridRows == 0 || (mLastUsedSlot + 1) % mGridColumns > 0) |
||
1139 |
++mGridRows; |
||
1140 |
|||
1141 |
const int invSize = mInventory->getSize(); |
||
1142 |
int maxRows = mShowEmptyRows == ShowEmptyRows_true ? |
||
1143 |
std::max(invSize / mGridColumns, mGridRows) : mGridRows; |
||
1144 |
|||
1145 |
if (mShowEmptyRows == ShowEmptyRows_true) |
||
1146 |
{ |
||
1147 |
if (mGridColumns * maxRows < invSize) |
||
1148 |
maxRows ++; |
||
1149 |
mGridRows = maxRows; |
||
1150 |
} |
||
1151 |
|||
1152 |
if (mShowEmptyRows == ShowEmptyRows_false) |
||
1153 |
{ |
||
1154 |
const int num = updateMatrix(); |
||
1155 |
mDrawRows = num / mGridColumns; |
||
1156 |
if (mDrawRows == 0 || num % mGridColumns > 0) |
||
1157 |
++mDrawRows; |
||
1158 |
|||
1159 |
maxRows = mDrawRows; |
||
1160 |
} |
||
1161 |
else |
||
1162 |
{ |
||
1163 |
mDrawRows = mGridRows; |
||
1164 |
} |
||
1165 |
setHeight(maxRows * mBoxHeight); |
||
1166 |
} |
||
1167 |
|||
1168 |
3 |
int ItemContainer::updateMatrix() |
|
1169 |
{ |
||
1170 |
✓✗ | 3 |
if (mInventory == nullptr) |
1171 |
return 0; |
||
1172 |
|||
1173 |
3 |
mRedraw = true; |
|
1174 |
✓✓ | 3 |
delete []mShowMatrix; |
1175 |
✓✗ | 3 |
mShowMatrix = new int[CAST_SIZE(mGridRows * mGridColumns)]; |
1176 |
|||
1177 |
3 |
STD_VECTOR<ItemIdPair*> sortedItems; |
|
1178 |
3 |
int i = 0; |
|
1179 |
3 |
int j = 0; |
|
1180 |
|||
1181 |
9 |
std::string temp = mName; |
|
1182 |
✓✗ | 3 |
toLower(temp); |
1183 |
|||
1184 |
6 |
const unsigned int invSize = mInventory->getSize(); |
|
1185 |
✓✓ | 303 |
for (unsigned int idx = 0; idx < invSize; idx ++) |
1186 |
{ |
||
1187 |
✓✗ | 300 |
Item *const item = mInventory->getItem(idx); |
1188 |
|||
1189 |
✗✗✓✗ |
300 |
if (item == nullptr || |
1190 |
item->getId() == 0 || |
||
1191 |
✗✓✗✗ ✗✗ |
300 |
!item->isHaveTag(mTag) || |
1192 |
item->getQuantity() == 0) |
||
1193 |
{ |
||
1194 |
✗✓ | 300 |
if (mShowEmptyRows == ShowEmptyRows_true) |
1195 |
sortedItems.push_back(new ItemIdPair(idx, nullptr)); |
||
1196 |
300 |
continue; |
|
1197 |
} |
||
1198 |
|||
1199 |
if (!item->isHaveTag(mTag)) |
||
1200 |
continue; |
||
1201 |
|||
1202 |
if (mName.empty()) |
||
1203 |
{ |
||
1204 |
sortedItems.push_back(new ItemIdPair(idx, item)); |
||
1205 |
continue; |
||
1206 |
} |
||
1207 |
std::string name = item->getInfo().getName(); |
||
1208 |
toLower(name); |
||
1209 |
if (name.find(temp) != std::string::npos) |
||
1210 |
sortedItems.push_back(new ItemIdPair(idx, item)); |
||
1211 |
} |
||
1212 |
|||
1213 |
✗✗✗✗ ✗✓ |
3 |
switch (mSortType) |
1214 |
{ |
||
1215 |
case 0: |
||
1216 |
default: |
||
1217 |
break; |
||
1218 |
case 1: |
||
1219 |
std::sort(sortedItems.begin(), sortedItems.end(), |
||
1220 |
itemAlphaInvSorter); |
||
1221 |
break; |
||
1222 |
case 2: |
||
1223 |
std::sort(sortedItems.begin(), sortedItems.end(), itemIdInvSorter); |
||
1224 |
break; |
||
1225 |
case 3: |
||
1226 |
std::sort(sortedItems.begin(), sortedItems.end(), |
||
1227 |
itemWeightInvSorter); |
||
1228 |
break; |
||
1229 |
case 4: |
||
1230 |
std::sort(sortedItems.begin(), sortedItems.end(), |
||
1231 |
itemAmountInvSorter); |
||
1232 |
break; |
||
1233 |
case 5: |
||
1234 |
std::sort(sortedItems.begin(), sortedItems.end(), |
||
1235 |
itemTypeInvSorter); |
||
1236 |
break; |
||
1237 |
} |
||
1238 |
|||
1239 |
3 |
int jMult = j * mGridColumns; |
|
1240 |
3 |
const int maxSize = mGridRows * mGridColumns; |
|
1241 |
✗✓ | 15 |
FOR_EACH (STD_VECTOR<ItemIdPair*>::const_iterator, iter, sortedItems) |
1242 |
{ |
||
1243 |
if (jMult >= maxSize) |
||
1244 |
break; |
||
1245 |
|||
1246 |
mShowMatrix[jMult + i] = (*iter)->mId; |
||
1247 |
|||
1248 |
i ++; |
||
1249 |
if (i >= mGridColumns) |
||
1250 |
{ |
||
1251 |
i = 0; |
||
1252 |
j ++; |
||
1253 |
jMult += mGridColumns; |
||
1254 |
} |
||
1255 |
} |
||
1256 |
|||
1257 |
✓✓ | 6 |
for (int idx = j * mGridColumns + i; idx < maxSize; idx ++) |
1258 |
3 |
mShowMatrix[idx] = -1; |
|
1259 |
|||
1260 |
3 |
const int num = CAST_S32(sortedItems.size()); |
|
1261 |
✗✓ | 3 |
for (size_t idx = 0, sz = num; idx < sz; idx ++) |
1262 |
delete sortedItems[idx]; |
||
1263 |
3 |
return num; |
|
1264 |
} |
||
1265 |
|||
1266 |
int ItemContainer::getSlotIndex(int x, int y) const |
||
1267 |
{ |
||
1268 |
if (mShowMatrix == nullptr) |
||
1269 |
return Inventory::NO_SLOT_INDEX; |
||
1270 |
|||
1271 |
if (x < mDimension.width && y < mDimension.height && x >= 0 && y >= 0) |
||
1272 |
{ |
||
1273 |
if (x > mBoxWidth * mGridColumns) |
||
1274 |
return Inventory::NO_SLOT_INDEX; |
||
1275 |
const int idx = (y / mBoxHeight) * mGridColumns + (x / mBoxWidth); |
||
1276 |
if (idx >= 0 && idx < mGridRows * mGridColumns |
||
1277 |
&& mShowMatrix[idx] >= 0) |
||
1278 |
{ |
||
1279 |
return mShowMatrix[idx]; |
||
1280 |
} |
||
1281 |
} |
||
1282 |
|||
1283 |
return Inventory::NO_SLOT_INDEX; |
||
1284 |
} |
||
1285 |
|||
1286 |
int ItemContainer::getSlotByXY(int x, int y) const |
||
1287 |
{ |
||
1288 |
if (mShowMatrix == nullptr) |
||
1289 |
return Inventory::NO_SLOT_INDEX; |
||
1290 |
|||
1291 |
if (x < mDimension.width && y < mDimension.height && x >= 0 && y >= 0) |
||
1292 |
{ |
||
1293 |
if (x > mBoxWidth * mGridColumns) |
||
1294 |
return Inventory::NO_SLOT_INDEX; |
||
1295 |
const int idx = (y / mBoxHeight) * mGridColumns + (x / mBoxWidth); |
||
1296 |
if (idx >= 0 && idx < mGridRows * mGridColumns) |
||
1297 |
return idx; |
||
1298 |
} |
||
1299 |
|||
1300 |
return Inventory::NO_SLOT_INDEX; |
||
1301 |
} |
||
1302 |
|||
1303 |
void ItemContainer::setFilter(const int tag) |
||
1304 |
{ |
||
1305 |
mTag = tag; |
||
1306 |
adjustHeight(); |
||
1307 |
} |
||
1308 |
|||
1309 |
2 |
void ItemContainer::setSortType(const int sortType) |
|
1310 |
{ |
||
1311 |
2 |
mSortType = sortType; |
|
1312 |
2 |
updateMatrix(); |
|
1313 |
2 |
} |
|
1314 |
|||
1315 |
void ItemContainer::setCellBackgroundImage(const std::string &xmlName) |
||
1316 |
{ |
||
1317 |
if (mCellBackgroundImg != nullptr) |
||
1318 |
mCellBackgroundImg->decRef(); |
||
1319 |
mCellBackgroundImg = Theme::getImageFromThemeXml(xmlName, ""); |
||
1320 |
mRedraw = true; |
||
1321 |
} |
||
1322 |
|||
1323 |
void ItemContainer::setMaxColumns(const int maxColumns) |
||
1324 |
{ |
||
1325 |
mMaxColumns = maxColumns; |
||
1326 |
updateSize(); |
||
1327 |
2 |
} |
Generated by: GCOVR (Version 3.3) |