GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/gui/widgets/shoplistbox.cpp Lines: 28 118 23.7 %
Date: 2017-11-29 Branches: 9 98 9.2 %

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-2017  The ManaPlus Developers
6
 *
7
 *  This file is part of The ManaPlus Client.
8
 *
9
 *  This program is free software; you can redistribute it and/or modify
10
 *  it under the terms of the GNU General Public License as published by
11
 *  the Free Software Foundation; either version 2 of the License, or
12
 *  any later version.
13
 *
14
 *  This program is distributed in the hope that it will be useful,
15
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 *  GNU General Public License for more details.
18
 *
19
 *  You should have received a copy of the GNU General Public License
20
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
21
 */
22
23
#include "gui/widgets/shoplistbox.h"
24
25
#include "dragdrop.h"
26
#include "settings.h"
27
28
#include "being/playerinfo.h"
29
30
#include "gui/viewport.h"
31
32
#include "gui/fonts/font.h"
33
34
#include "gui/popups/itempopup.h"
35
#include "gui/popups/popupmenu.h"
36
37
#include "gui/models/shopitems.h"
38
39
#include "gui/windows/itemamountwindow.h"
40
41
#include "net/net.h"
42
43
#include "resources/inventory/inventory.h"
44
45
#include "resources/item/shopitem.h"
46
47
#include "debug.h"
48
49
const int ITEM_ICON_SIZE = 32;
50
51
ShopListBox::ShopListBox(const Widget2 *const widget,
52
                         ListModel *const listModel,
53
                         const ShopListBoxTypeT type) :
54
    ListBox(widget, listModel, "shoplistbox.xml"),
55
    mPlayerMoney(0),
56
    mShopItems(nullptr),
57
    mWarningColor(getThemeColor(ThemeColorId::SHOP_WARNING)),
58
    mType(type),
59
    mPriceCheck(true),
60
    mProtectItems(false)
61
{
62
    mRowHeight = getFont()->getHeight();
63
    mHighlightColor = getThemeColor(ThemeColorId::HIGHLIGHT);
64
    mForegroundColor = getThemeColor(ThemeColorId::LISTBOX);
65
    mBackgroundColor = getThemeColor(ThemeColorId::BACKGROUND);
66
}
67
68
20
ShopListBox::ShopListBox(const Widget2 *const widget,
69
                         ListModel *const listModel,
70
                         ShopItems *const shopListModel,
71
20
                         const ShopListBoxTypeT type) :
72
    ListBox(widget, listModel, "shoplistbox.xml"),
73
    mPlayerMoney(0),
74
    mShopItems(shopListModel),
75
40
    mWarningColor(getThemeColor(ThemeColorId::SHOP_WARNING)),
76
    mType(type),
77
    mPriceCheck(true),
78

100
    mProtectItems(false)
79
{
80

40
    mRowHeight = std::max(getFont()->getHeight(), ITEM_ICON_SIZE);
81
40
    mHighlightColor = getThemeColor(ThemeColorId::HIGHLIGHT);
82
40
    mForegroundColor = getThemeColor(ThemeColorId::LISTBOX);
83
40
    mBackgroundColor = getThemeColor(ThemeColorId::BACKGROUND);
84
20
}
85
86
void ShopListBox::setPlayersMoney(const int money)
87
{
88
    mPlayerMoney = money;
89
}
90
91
16
void ShopListBox::draw(Graphics *const graphics)
92
{
93
    BLOCK_START("ShopListBox::draw")
94

16
    if ((mListModel == nullptr) || (mShopItems == nullptr))
95
    {
96
        BLOCK_END("ShopListBox::draw")
97
        return;
98
    }
99
100
16
    if (settings.guiAlpha != mAlpha)
101
        mAlpha = settings.guiAlpha;
102
103
16
    const unsigned int alpha = CAST_U32(mAlpha * 255.0F);
104
16
    Font *const font = getFont();
105
106
16
    const int sz = mListModel->getNumberOfElements();
107
16
    const int fontHeigh = getFont()->getHeight();
108
16
    const int width = mDimension.width - 2 * mPadding;
109
    // Draw the list elements
110
16
    for (int i = 0, y = 0;
111
16
         i < sz;
112
         ++i, y += mRowHeight)
113
    {
114
        bool needDraw(false);
115
        Color temp;
116
        Color* backgroundColor = &mBackgroundColor;
117
118
        ShopItem *const item = mShopItems->at(i);
119
        if ((item != nullptr) &&
120
            (item->getDisabled() ||
121
            (mPlayerMoney < item->getPrice() && mPriceCheck) ||
122
            (mProtectItems && PlayerInfo::isItemProtected(item->getId()))))
123
        {
124
            if (i != mSelected)
125
            {
126
                backgroundColor = &mWarningColor;
127
                backgroundColor->a = alpha;
128
            }
129
            else
130
            {
131
                temp = mWarningColor;
132
                temp.r = (temp.r + mHighlightColor.r) / 2;
133
                temp.g = (temp.g + mHighlightColor.g) / 2;
134
                temp.b = (temp.b + mHighlightColor.b) / 2;
135
                temp.a = alpha;
136
                backgroundColor = &temp;
137
            }
138
            needDraw = true;
139
        }
140
        else if (i == mSelected)
141
        {
142
            mHighlightColor.a = alpha;
143
            backgroundColor = &mHighlightColor;
144
            needDraw = true;
145
        }
146
        else
147
        {
148
            mBackgroundColor.a = alpha;
149
        }
150
151
        if (needDraw)
152
        {
153
            graphics->setColor(*backgroundColor);
154
            graphics->fillRectangle(Rect(mPadding, y + mPadding,
155
                width, mRowHeight));
156
        }
157
158
        if ((mShopItems != nullptr) && (item != nullptr))
159
        {
160
            Image *const icon = item->getImage();
161
            if (icon != nullptr)
162
            {
163
                icon->setAlpha(1.0F);
164
                graphics->drawImage(icon, mPadding, y + mPadding);
165
            }
166
        }
167
        if (mSelected == i)
168
        {
169
            font->drawString(graphics,
170
                mForegroundSelectedColor,
171
                mForegroundSelectedColor2,
172
                mListModel->getElementAt(i),
173
                ITEM_ICON_SIZE + mPadding,
174
                y + (ITEM_ICON_SIZE - fontHeigh) / 2 + mPadding);
175
        }
176
        else
177
        {
178
            font->drawString(graphics,
179
                mForegroundColor,
180
                mForegroundColor2,
181
                mListModel->getElementAt(i),
182
                ITEM_ICON_SIZE + mPadding,
183
                y + (ITEM_ICON_SIZE - fontHeigh) / 2 + mPadding);
184
        }
185
    }
186
    BLOCK_END("ShopListBox::draw")
187
}
188
189
void ShopListBox::safeDraw(Graphics *const graphics)
190
{
191
    ShopListBox::draw(graphics);
192
}
193
194
20
void ShopListBox::adjustSize()
195
{
196
    BLOCK_START("ShopListBox::adjustSize")
197
20
    if (mListModel != nullptr)
198
    {
199
40
        setHeight(mRowHeight * mListModel->getNumberOfElements()
200
20
            + 2 * mPadding);
201
    }
202
    BLOCK_END("ShopListBox::adjustSize")
203
20
}
204
205
12
void ShopListBox::setPriceCheck(const bool check)
206
{
207
12
    mPriceCheck = check;
208
12
}
209
210
void ShopListBox::mouseMoved(MouseEvent &event)
211
{
212
    if ((itemPopup == nullptr) || (mRowHeight == 0u))
213
        return;
214
215
    if (mShopItems == nullptr)
216
    {
217
        itemPopup->hide();
218
        return;
219
    }
220
221
    const int index = (event.getY() - mPadding) / mRowHeight;
222
223
    if (index < 0 || index >= mShopItems->getNumberOfElements())
224
    {
225
        itemPopup->hide();
226
    }
227
    else
228
    {
229
        const Item *const item = mShopItems->at(index);
230
        if (item != nullptr)
231
        {
232
            itemPopup->setItem(item, false);
233
            itemPopup->position(viewport->mMouseX, viewport->mMouseY);
234
        }
235
        else
236
        {
237
            itemPopup->setVisible(Visible_false);
238
        }
239
    }
240
}
241
242
void ShopListBox::mouseReleased(MouseEvent& event)
243
{
244
    ListBox::mouseReleased(event);
245
    if (event.getType() == MouseEventType::RELEASED2)
246
    {
247
        if (dragDrop.isEmpty())
248
            return;
249
        const DragDropSourceT src = dragDrop.getSource();
250
        if (mType != ShopListBoxType::SellShop &&
251
            mType != ShopListBoxType::BuyShop)
252
        {
253
            return;
254
        }
255
        if (mType == ShopListBoxType::SellShop &&
256
            Net::getNetworkType() != ServerType::TMWATHENA &&
257
            src != DragDropSource::Cart)
258
        {
259
            return;
260
        }
261
        Inventory *inventory;
262
        if (src == DragDropSource::Inventory)
263
            inventory = PlayerInfo::getInventory();
264
        else if (src == DragDropSource::Cart)
265
            inventory = PlayerInfo::getCartInventory();
266
        else
267
            return;
268
        if (inventory == nullptr)
269
            return;
270
        Item *const item = inventory->getItem(dragDrop.getTag());
271
        if (mType == ShopListBoxType::BuyShop)
272
        {
273
            ItemAmountWindow::showWindow(
274
                ItemAmountWindowUsage::ShopBuyAdd,
275
                nullptr,
276
                item);
277
        }
278
        else
279
        {
280
            ItemAmountWindow::showWindow(
281
                ItemAmountWindowUsage::ShopSellAdd,
282
                nullptr,
283
                item);
284
        }
285
    }
286
287
    if (event.getButton() == MouseButton::RIGHT)
288
    {
289
        setSelected(std::max(0, getSelectionByMouse(event.getY())));
290
291
        if (mSelected < 0 || mSelected >= mShopItems->getNumberOfElements())
292
            return;
293
294
        Item *const item = mShopItems->at(mSelected);
295
        if ((popupMenu != nullptr) && (viewport != nullptr))
296
        {
297
            popupMenu->showItemPopup(viewport->mMouseX,
298
            viewport->mMouseY,
299
            item);
300
        }
301
    }
302
}
303
304
void ShopListBox::mouseExited(MouseEvent& event A_UNUSED)
305
{
306
    if (itemPopup == nullptr)
307
        return;
308
309
    itemPopup->hide();
310
4
}