1 /*
2  *  The ManaPlus Client
3  *  Copyright (C) 2013-2019  The ManaPlus Developers
4  *  Copyright (C) 2019-2021  Andrei Karas
5  *
6  *  This file is part of The ManaPlus 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/widgets/emotepage.h"
23 
24 #include "render/graphics.h"
25 
26 #include "render/vertexes/imagecollection.h"
27 
28 #include "resources/imageset.h"
29 
30 #include "resources/loaders/imagesetloader.h"
31 
32 #include "utils/delete2.h"
33 #include "utils/foreach.h"
34 
35 #include "debug.h"
36 
37 namespace
38 {
39     const unsigned int emoteWidth = 17;
40     const unsigned int emoteHeight = 18;
41 }  // namespace
42 
EmotePage(const Widget2 * const widget)43 EmotePage::EmotePage(const Widget2 *const widget) :
44     Widget(widget),
45     MouseListener(),
46     WidgetListener(),
47     mEmotes(Loader::getImageSet(
48         "graphics/sprites/chatemotes.png", emoteWidth, emoteHeight)),
49     mVertexes(new ImageCollection),
50     mSelectedIndex(-1)
51 {
52     addMouseListener(this);
53     addWidgetListener(this);
54     mAllowLogic = false;
55 }
56 
~EmotePage()57 EmotePage::~EmotePage()
58 {
59     if (mEmotes != nullptr)
60     {
61         mEmotes->decRef();
62         mEmotes = nullptr;
63     }
64     delete2(mVertexes)
65 }
66 
draw(Graphics * const graphics)67 void EmotePage::draw(Graphics *const graphics)
68 {
69     BLOCK_START("EmotePage::draw")
70 
71     if (mRedraw)
72     {
73         if (mEmotes == nullptr)
74             return;
75 
76         const STD_VECTOR<Image*> &images = mEmotes->getImages();
77 
78         const unsigned int width = mDimension.width;
79         unsigned int x = 0;
80         unsigned int y = 0;
81 
82         mRedraw = false;
83         mVertexes->clear();
84         FOR_EACH (STD_VECTOR<Image*>::const_iterator, it, images)
85         {
86             const Image *const image = *it;
87             if (image != nullptr)
88             {
89                 graphics->calcTileCollection(mVertexes, image, x, y);
90                 x += emoteWidth;
91                 if (x + emoteWidth > width)
92                 {
93                     x = 0;
94                     y += emoteHeight;
95                 }
96             }
97         }
98         graphics->finalize(mVertexes);
99     }
100     graphics->drawTileCollection(mVertexes);
101 
102     BLOCK_END("EmotePage::draw")
103 }
104 
safeDraw(Graphics * const graphics)105 void EmotePage::safeDraw(Graphics *const graphics)
106 {
107     BLOCK_START("EmotePage::safeDraw")
108 
109     if (mEmotes == nullptr)
110         return;
111 
112     const STD_VECTOR<Image*> &images = mEmotes->getImages();
113 
114     const unsigned int width = mDimension.width;
115     unsigned int x = 0;
116     unsigned int y = 0;
117 
118     FOR_EACH (STD_VECTOR<Image*>::const_iterator, it, images)
119     {
120         const Image *const image = *it;
121         if (image != nullptr)
122         {
123             graphics->drawImage(image, x, y);
124             x += emoteWidth;
125             if (x + emoteWidth > width)
126             {
127                 x = 0;
128                 y += emoteHeight;
129             }
130         }
131     }
132 
133     BLOCK_END("EmotePage::safeDraw")
134 }
135 
mousePressed(MouseEvent & event)136 void EmotePage::mousePressed(MouseEvent &event)
137 {
138     mSelectedIndex = getIndexFromGrid(event.getX(), event.getY());
139     event.consume();
140     distributeActionEvent();
141 }
142 
getIndexFromGrid(const int x,const int y) const143 int EmotePage::getIndexFromGrid(const int x, const int y) const
144 {
145     const int width = mDimension.width;
146     if (x < 0 || x > width || y < 0 || y > mDimension.height)
147         return -1;
148     const int cols = width / emoteWidth;
149     const int index = (y / emoteHeight) * cols + (x / emoteWidth);
150     if (index >= CAST_S32(mEmotes->size()))
151         return -1;
152     return index;
153 }
154 
resetAction()155 void EmotePage::resetAction()
156 {
157     mSelectedIndex = -1;
158 }
159 
widgetResized(const Event & event A_UNUSED)160 void EmotePage::widgetResized(const Event &event A_UNUSED)
161 {
162     mRedraw = true;
163 }
164 
widgetMoved(const Event & event A_UNUSED)165 void EmotePage::widgetMoved(const Event &event A_UNUSED)
166 {
167     mRedraw = true;
168 }
169