2 Copyright 2004-2020 Chris Tallon
4 This file is part of VOMP.
6 VOMP is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 VOMP is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with VOMP. If not, see <https://www.gnu.org/licenses/>.
25 #include "wselectlist.h"
27 WSelectList::WSelectList():
28 backgroundColour(DrawStyle::VIEWBACKGROUND)
32 WSelectList::~WSelectList()
37 void WSelectList::clear()
39 int vsize = options.size();
40 for (int i = 0; i < vsize; i++)
42 if (options[i].pict) delete options[i].pict;
48 numOptionsDisplayable = 0;
52 void WSelectList::setNoLoop()
57 void WSelectList::setBackgroundColour(const DrawStyle& colour)
59 backgroundColour = colour;
62 void WSelectList::hintSetCurrent(int idx)
65 if (selectedOption >= static_cast<int>(options.size())) selectedOption = options.size() - 1;
68 void WSelectList::hintSetTop(int idx)
73 int WSelectList::addOption(const char* text, void* data, int selected, TVMediaInfo* pict)
75 int thisNewOption = options.size();
81 options.push_back(wslo);
82 if (selected) selectedOption = thisNewOption;
86 int WSelectList::addOption(const std::string& text, void* data, int selected, TVMediaInfo* pict)
88 int thisNewOption = options.size();
94 options.push_back(wslo);
95 if (selected) selectedOption = thisNewOption;
99 void WSelectList::draw()
101 int fontHeight = getFontHeight();
102 int ySeparation = static_cast<int>(static_cast<float>(fontHeight) * linesPerOption) + gap;
104 numOptionsDisplayable = (area.h - 5) / ySeparation;
106 if (selectedOption == (topOption + numOptionsDisplayable)) topOption++;
107 if (selectedOption == (topOption - 1)) topOption--;
108 // if still not visible...
109 if ((selectedOption < topOption) || (selectedOption > (topOption + numOptionsDisplayable)))
111 topOption = selectedOption - (numOptionsDisplayable / 2);
114 if (topOption < 0) topOption = 0;
116 fillColour(backgroundColour);
119 for (int i = topOption; i < (topOption + numOptionsDisplayable); i++)
121 if (i == static_cast<int>(options.size())) return;
122 if ((ypos + ySeparation) > area.h) break;
124 if (i == selectedOption && showseloption)
126 rectangle(0, ypos, area.w, static_cast<UINT>(static_cast<float>(fontHeight) * linesPerOption) - 1, darkseloption ? DrawStyle::SELECTDARKHIGHLIGHT : DrawStyle::SELECTHIGHLIGHT);
127 drawOptionLine(options[i].text, 5, ypos, area.w - 5, DrawStyle::DARKTEXT, options[i].pict);
131 rectangle(0, ypos, area.w, static_cast<UINT>(static_cast<float>(fontHeight) * linesPerOption) - 1, DrawStyle::SELECTBACKGROUND);
132 drawOptionLine(options[i].text, 5, ypos, area.w - 5, DrawStyle::LIGHTTEXT, options[i].pict);
138 void WSelectList::addColumn(int x)
140 if (numColumns == 10) return;
141 columns[numColumns++] = x;
144 int WSelectList::getColumn(int x)
146 if (x >= numColumns) return 0;
150 void WSelectList::drawOptionLine(const std::string& text, int xpos, int ypos, int width, const DrawStyle& colour, TVMediaInfo* pict)
154 int fontHeight = getFontHeight();
155 float ypos_mod = static_cast<float>(ypos) + (linesPerOption - floor(linesPerOption)) * static_cast<float>(fontHeight) * 0.5f;
159 if (numColumns > 1) imagewidth = columns[1] - columns[0];
162 drawTVMedia(*pict, static_cast<float>(xpos), static_cast<float>(ypos), static_cast<float>(imagewidth),
163 static_cast<float>(fontHeight) * linesPerOption, TopLeftLimited);
168 if (!numColumns && linesPerOption == 1)
170 drawText(text.c_str(), xpos, ypos, width, colour);
174 const char* ctext = text.c_str();
176 strncpy(buffer, ctext, 199);
177 int currentColumn = taboffset;
181 pointer = STRTOKR(buffer, "\t\n", &savepointer);
184 drawText(pointer, xposmod + columns[currentColumn], (fontHeight * curline) + static_cast<int>(ypos_mod), width - columns[currentColumn], colour);
186 pointer = STRTOKR(NULL, "\t\n", &savepointer);
189 char delimiter = ctext[pointer - buffer - 1];
190 if (delimiter == '\t') currentColumn++;
191 else if (delimiter == '\n')
193 currentColumn = taboffset;
197 if (static_cast<float>(curline) >= linesPerOption) return;
199 if (currentColumn == 10) return;
204 void WSelectList::up()
206 if (selectedOption > 0)
212 if (!noLoop) selectedOption = options.size() - 1;
216 void WSelectList::down()
218 if (selectedOption < (static_cast<int>(options.size()) - 1))
224 if (!noLoop) selectedOption = 0;
228 void WSelectList::pageUp()
230 topOption -= numOptionsDisplayable;
231 if (topOption < 0) topOption = 0;
233 selectedOption = topOption;
236 void WSelectList::pageDown()
238 if ((topOption + numOptionsDisplayable) >= static_cast<int>(options.size()))
240 selectedOption = options.size() - 1;
244 topOption += numOptionsDisplayable;
245 selectedOption = topOption;
249 int WSelectList::getTopOption()
254 int WSelectList::getNumOptions()
256 return options.size();
259 int WSelectList::getBottomOption()
261 UINT retval = topOption + numOptionsDisplayable;
262 if (retval > options.size()) return options.size();
266 int WSelectList::getCurrentOption()
268 return selectedOption;
271 void* WSelectList::getCurrentOptionData()
273 if (!options.size()) return 0;
274 return options[selectedOption].data;
277 int WSelectList::getNumOptionsDisplayable()
279 return numOptionsDisplayable;
282 bool WSelectList::mouseAndroidScroll(int /* x */, int /* y */, int /* sx */, int /* sy */)
285 * int fontHeight = getFontHeight();
286 * int movelines= sy/fontHeight;
288 * int seloption=selectedOption+movelines;
289 * if (seloption<0) seloption=0;
290 * else if (seloption>options.size()-1) seloption=options.size()-1;
291 * selectedOption=seloption;
296 bool WSelectList::mouseMove(int x, int y)
298 int ml = getMouseLine(x - getRootBoxOffsetX(), y - getRootBoxOffsetY());
299 if (ml >= 0 && ml != selectedOption)
307 bool WSelectList::mouseLBDOWN(int x, int y)
309 int ml = getMouseLine(x - getRootBoxOffsetX(), y - getRootBoxOffsetY());
310 if (ml == selectedOption)
312 /* caller should generate a OK message*/
318 int WSelectList::getMouseLine(int x, int y)
320 int fontHeight = getFontHeight();
321 int ySeparation = static_cast<int>(static_cast<float>(fontHeight) * linesPerOption) + gap;
323 if (y < 0) return -1;
324 if (x < 0 || x > static_cast<int>(area.w)) return -1;
325 if (y > (10 + numOptionsDisplayable * ySeparation)) return -1;
329 int selected = cy / ySeparation;
330 if (y < 5) selected = -1;
331 if (selected > numOptionsDisplayable) return -1;
332 /* Important: should be the same algorithm used in draw! */
333 if (selectedOption == (topOption + numOptionsDisplayable)) topOption++;
334 if (selectedOption == (topOption - 1)) topOption--;
335 // if still not visible...
336 if ((selectedOption < topOption) || (selectedOption > (topOption + numOptionsDisplayable)))
338 topOption = selectedOption - (numOptionsDisplayable / 2);
341 if (topOption < 0) topOption = 0;
342 if ((selected + topOption >= static_cast<int>(options.size())) || (selected + topOption < 0)) return -1;
343 return selected + topOption;