ManaPlus
extendedlistbox.cpp
Go to the documentation of this file.
1 /*
2  * The ManaPlus Client
3  * Copyright (C) 2012-2017 The ManaPlus Developers
4  *
5  * This file is part of The ManaPlus Client.
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
22 
24 
25 #include "gui/skin.h"
26 
27 #include "gui/fonts/font.h"
28 
29 #include "render/graphics.h"
30 
31 #include "debug.h"
32 
34  ListModel *const listModel,
35  const std::string &skin,
36  const unsigned int rowHeight) :
37  ListBox(widget, listModel, skin),
38  mImagePadding(mSkin != nullptr ? mSkin->getOption("imagePadding") : 0),
39  mSpacing(mSkin != nullptr ? mSkin->getOption("spacing") : 0),
40  mHeight(0),
41  mListItems(),
42  mSelectedItems()
43 {
44  if (rowHeight != 0u)
45  mRowHeight = rowHeight;
46 }
47 
49 {
50 }
51 
52 void ExtendedListBox::draw(Graphics *const graphics)
53 {
54  if (mListModel == nullptr)
55  return;
56 
57  BLOCK_START("ExtendedListBox::draw")
58  ExtendedListModel *const model = static_cast<ExtendedListModel *>(
59  mListModel);
60 
61  updateAlpha();
62  Font *const font = getFont();
63 
64  const int height = CAST_S32(mRowHeight);
65  const int pad2 = 2 + mPadding;
66  const int width = mDimension.width;
67  int textPos = (height - font->getHeight()) / 2 + mPadding;
68  if (textPos < 0)
69  textPos = 0;
70 
71  const int sz = mListModel->getNumberOfElements();
72  mListItems.clear();
73  mSelectedItems.clear();
74  int y = 0;
75  const int insideWidth = width - pad2;
76  for (int f = 0; f < sz; f ++)
77  {
78  int row = f;
79  bool useImage = true;
80  std::string str = mListModel->getElementAt(f);
81  int strWidth = font->getWidth(str) + 8;
82 
83  const Image *const image = model->getImageAt(row);
84  if (image != nullptr)
85  strWidth += image->getWidth() + mImagePadding;
86 
87  STD_VECTOR<ExtendedListBoxItem> &list =
89 
90  if (insideWidth < strWidth)
91  {
92  const size_t strSize = str.size();
93  size_t divPos = strSize / 2;
94  if (divPos > 0 && CAST_U8(
95  str[divPos - 1]) >= 0xc0)
96  {
97  divPos --;
98  }
99  for (size_t d = divPos; d > 10; d --)
100  {
101  if (str[d] == 32)
102  {
103  divPos = d + 1;
104  break;
105  }
106  }
107  list.push_back(ExtendedListBoxItem(row,
108  str.substr(0, divPos), useImage, y));
109  str = str.substr(divPos);
110  y += height;
111  useImage = false;
112  }
113  list.push_back(ExtendedListBoxItem(row, str, useImage, y));
114 
115  y += height;
116  }
117  mHeight = y + height;
118 
119  const size_t itemsSz = mListItems.size();
120  const size_t selSz = mSelectedItems.size();
121  int minY = -1;
122  int maxY = -1;
123  for (size_t f = 0; f < selSz; f ++)
124  {
126  const int y1 = item.y;
127  if (minY == -1)
128  minY = y1;
129  if (maxY < y1)
130  maxY = y1;
131  }
132 
133  if (minY != -1)
134  {
135  mHighlightColor.a = CAST_U32(mAlpha * 255.0F);
136  graphics->setColor(mHighlightColor);
137  graphics->fillRectangle(Rect(mPadding, minY + mPadding,
138  width - pad2, maxY - minY + height));
139  }
140 
141  for (size_t f = 0; f < itemsSz; ++f)
142  {
143  const ExtendedListBoxItem &item = mListItems[f];
144  const int row1 = item.row;
145  if (item.image)
146  {
147  const Image *const image = model->getImageAt(row1);
148  if (image != nullptr)
149  {
150  graphics->drawImage(image,
152  item.y + (height - image->getHeight()) / 2 + mPadding);
153  }
154  }
155  }
156 
157  for (size_t f = 0; f < itemsSz; ++f)
158  {
159  const ExtendedListBoxItem &item = mListItems[f];
160  const int row1 = item.row;
161  const int y1 = item.y;
162  const Image *const image = model->getImageAt(row1);
163  if ((image == nullptr) || !item.image)
164  {
165  font->drawString(graphics,
167  item.text,
168  mPadding, y1 + textPos);
169  }
170  else
171  {
172  font->drawString(graphics,
174  item.text,
175  image->getWidth() + mImagePadding + mSpacing, y1 + textPos);
176  }
177  }
178 
179  for (size_t f = 0; f < selSz; ++f)
180  {
182  const int row1 = item.row;
183  const int y1 = item.y;
184  const Image *const image = model->getImageAt(row1);
185  if ((image == nullptr) || !item.image)
186  {
187  font->drawString(graphics,
189  item.text,
190  mPadding, y1 + textPos);
191  }
192  else
193  {
194  font->drawString(graphics,
196  item.text,
197  image->getWidth() + mImagePadding + mSpacing, y1 + textPos);
198  }
199  }
200 
201  for (size_t f = 0; f < selSz; ++f)
202  {
204  const int row1 = item.row;
205  if (item.image)
206  {
207  const Image *const image = model->getImageAt(row1);
208  if (image != nullptr)
209  {
210  graphics->drawImage(image,
212  item.y + (height - image->getHeight()) / 2 + mPadding);
213  }
214  }
215  }
216 
217  BLOCK_END("ExtendedListBox::draw")
218 }
219 
220 void ExtendedListBox::safeDraw(Graphics *const graphics)
221 {
222  ExtendedListBox::draw(graphics);
223 }
224 
226 {
227  if (mHeight != 0)
228  setHeight(mHeight + 2 * mPadding);
229  else
231 }
232 
234 {
235  if (mListItems.empty() && mSelectedItems.empty())
237 
238  const int height = CAST_S32(mRowHeight);
239  const size_t itemsSz = mListItems.size();
240  for (size_t f = 0; f < itemsSz; f ++)
241  {
242  const ExtendedListBoxItem &item = mListItems[f];
243  const int y2 = item.y + mPadding;
244  if (y2 <= y && y2 + height > y)
245  return item.row;
246  }
247 
248  const size_t selSz = mSelectedItems.size();
249  for (size_t f = 0; f < selSz; f ++)
250  {
252  const int y2 = item.y + mPadding;
253  if (y2 <= y && y2 + height > y)
254  return item.row;
255  }
256  return 0;
257 }
#define CAST_U32
Definition: cast.h:30
Font * getFont() const
Definition: widget.cpp:330
int mSelected
Definition: listbox.h:255
int width
Definition: rect.h:218
int mPadding
Definition: listbox.h:286
Color mForegroundSelectedColor2
Definition: listbox.h:284
#define CAST_U8
Definition: cast.h:26
Definition: font.h:88
void safeDraw(Graphics *const graphics)
unsigned int a
Definition: color.h:250
Definition: rect.h:72
ExtendedListBox(const Widget2 *const widget, ListModel *const listModel, const std::string &skin, const unsigned int rowHeight=13)
#define BLOCK_START(name)
Definition: perfomance.h:78
unsigned int mRowHeight
Definition: listbox.h:288
Color mHighlightColor
Definition: listbox.h:282
#define BLOCK_END(name)
Definition: perfomance.h:79
std::vector< ExtendedListBoxItem > mListItems
virtual int getNumberOfElements()=0
virtual void adjustSize()
Definition: listbox.cpp:367
std::vector< ExtendedListBoxItem > mSelectedItems
Color mForegroundColor
Definition: widget.h:1085
ListModel * mListModel
Definition: listbox.h:260
Color mForegroundSelectedColor
Definition: listbox.h:283
int getSelectionByMouse(const int y) const
void draw(Graphics *const graphics)
virtual int getSelectionByMouse(const int y) const
Definition: listbox.cpp:385
virtual void setColor(const Color &color)
Definition: graphics.h:319
#define CAST_S32
Definition: cast.h:29
virtual const Image * getImageAt(int i)=0
void drawString(Graphics *const graphics, Color col, const Color &col2, const std::string &text, const int x, const int y)
Definition: font.cpp:253
void updateAlpha()
Definition: listbox.cpp:147
#define nullptr
Definition: localconsts.h:44
static float mAlpha
Definition: listbox.h:291
virtual std::string getElementAt(int i)=0
void setHeight(const int height)
Definition: widget.cpp:139
virtual void fillRectangle(const Rect &rectangle)=0
Color mForegroundColor2
Definition: widget2.h:112
virtual void drawImage(const Image *const image, int dstX, int dstY)=0
int getWidth(const std::string &text) const
Definition: font.cpp:333
Definition: image.h:61
int getWidth() const A_INLINE
Definition: image.h:116
int getHeight() const
Definition: font.cpp:360
Rect mDimension
Definition: widget.h:1100
int getHeight() const A_INLINE
Definition: image.h:122