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 delete[] options[i].text;
43 if (options[i].pict) delete options[i].pict;
49 numOptionsDisplayable = 0;
53 void WSelectList::setNoLoop()
58 void WSelectList::setBackgroundColour(const DrawStyle& colour)
60 backgroundColour = colour;
63 void WSelectList::hintSetCurrent(int idx)
66 if (selectedOption >= static_cast<int>(options.size())) selectedOption = options.size() - 1;
69 void WSelectList::hintSetTop(int idx)
74 int WSelectList::addOption(const char* text, void* data, int selected, TVMediaInfo* pict)
76 int thisNewOption = options.size();
79 wslo.text = new char[strlen(text) + 1];
80 strcpy(wslo.text, text);
83 options.push_back(wslo);
84 if (selected) selectedOption = thisNewOption;
88 int WSelectList::addOption(const std::string& text, void* data, int selected, TVMediaInfo* pict) // FIXME convert WSelectList wslo to use std::string
90 int thisNewOption = options.size();
93 wslo.text = new char[text.length() + 1];
94 strcpy(wslo.text, text.c_str());
97 options.push_back(wslo);
98 if (selected) selectedOption = thisNewOption;
102 void WSelectList::draw()
104 int fontHeight = getFontHeight();
105 int ySeparation = static_cast<int>(static_cast<float>(fontHeight) * linesPerOption) + gap;
107 numOptionsDisplayable = (area.h - 5) / ySeparation;
109 if (selectedOption == (topOption + numOptionsDisplayable)) topOption++;
110 if (selectedOption == (topOption - 1)) topOption--;
111 // if still not visible...
112 if ((selectedOption < topOption) || (selectedOption > (topOption + numOptionsDisplayable)))
114 topOption = selectedOption - (numOptionsDisplayable / 2);
117 if (topOption < 0) topOption = 0;
119 fillColour(backgroundColour);
122 for (int i = topOption; i < (topOption + numOptionsDisplayable); i++)
124 if (i == static_cast<int>(options.size())) return;
125 if ((ypos + ySeparation) > area.h) break;
127 if (i == selectedOption && showseloption)
129 rectangle(0, ypos, area.w, static_cast<UINT>(static_cast<float>(fontHeight) * linesPerOption) - 1, darkseloption ? DrawStyle::SELECTDARKHIGHLIGHT : DrawStyle::SELECTHIGHLIGHT);
130 drawOptionLine(options[i].text, 5, ypos, area.w - 5, DrawStyle::DARKTEXT, options[i].pict);
134 rectangle(0, ypos, area.w, static_cast<UINT>(static_cast<float>(fontHeight) * linesPerOption) - 1, DrawStyle::SELECTBACKGROUND);
135 drawOptionLine(options[i].text, 5, ypos, area.w - 5, DrawStyle::LIGHTTEXT, options[i].pict);
141 void WSelectList::addColumn(int x)
143 if (numColumns == 10) return;
144 columns[numColumns++] = x;
147 int WSelectList::getColumn(int x)
149 if (x >= numColumns) return 0;
153 void WSelectList::drawOptionLine(char* text, int xpos, int ypos, int width, const DrawStyle& colour, TVMediaInfo* pict)
157 int fontHeight = getFontHeight();
158 float ypos_mod = static_cast<float>(ypos) + (linesPerOption - floor(linesPerOption)) * static_cast<float>(fontHeight) * 0.5f;
162 if (numColumns > 1) imagewidth = columns[1] - columns[0];
165 drawTVMedia(*pict, static_cast<float>(xpos), static_cast<float>(ypos), static_cast<float>(imagewidth),
166 static_cast<float>(fontHeight) * linesPerOption, TopLeftLimited);
171 if (!numColumns && linesPerOption == 1)
173 drawText(text, xpos, ypos, width, colour);
178 strncpy(buffer, text, 199);
179 int currentColumn = taboffset;
183 pointer = STRTOKR(buffer, "\t\n", &savepointer);
186 drawText(pointer, xposmod + columns[currentColumn], (fontHeight * curline) + static_cast<int>(ypos_mod), width - columns[currentColumn], colour);
188 pointer = STRTOKR(NULL, "\t\n", &savepointer);
191 char delimiter = text[pointer - buffer - 1];
192 if (delimiter == '\t') currentColumn++;
193 else if (delimiter == '\n')
195 currentColumn = taboffset;
199 if (static_cast<float>(curline) >= linesPerOption) return;
201 if (currentColumn == 10) return;
206 void WSelectList::up()
208 if (selectedOption > 0)
214 if (!noLoop) selectedOption = options.size() - 1;
218 void WSelectList::down()
220 if (selectedOption < (static_cast<int>(options.size()) - 1))
226 if (!noLoop) selectedOption = 0;
230 void WSelectList::pageUp()
232 topOption -= numOptionsDisplayable;
233 if (topOption < 0) topOption = 0;
235 selectedOption = topOption;
238 void WSelectList::pageDown()
240 if ((topOption + numOptionsDisplayable) >= static_cast<int>(options.size()))
242 selectedOption = options.size() - 1;
246 topOption += numOptionsDisplayable;
247 selectedOption = topOption;
251 int WSelectList::getTopOption()
256 int WSelectList::getNumOptions()
258 return options.size();
261 int WSelectList::getBottomOption()
263 UINT retval = topOption + numOptionsDisplayable;
264 if (retval > options.size()) return options.size();
268 int WSelectList::getCurrentOption()
270 return selectedOption;
273 void* WSelectList::getCurrentOptionData()
275 if (!options.size()) return 0;
276 return options[selectedOption].data;
279 int WSelectList::getNumOptionsDisplayable()
281 return numOptionsDisplayable;
284 bool WSelectList::mouseAndroidScroll(int /* x */, int /* y */, int /* sx */, int /* sy */)
287 * int fontHeight = getFontHeight();
288 * int movelines= sy/fontHeight;
290 * int seloption=selectedOption+movelines;
291 * if (seloption<0) seloption=0;
292 * else if (seloption>options.size()-1) seloption=options.size()-1;
293 * selectedOption=seloption;
298 bool WSelectList::mouseMove(int x, int y)
300 int ml = getMouseLine(x - getRootBoxOffsetX(), y - getRootBoxOffsetY());
301 if (ml >= 0 && ml != selectedOption)
309 bool WSelectList::mouseLBDOWN(int x, int y)
311 int ml = getMouseLine(x - getRootBoxOffsetX(), y - getRootBoxOffsetY());
312 if (ml == selectedOption)
314 /* caller should generate a OK message*/
320 int WSelectList::getMouseLine(int x, int y)
322 int fontHeight = getFontHeight();
323 int ySeparation = static_cast<int>(static_cast<float>(fontHeight) * linesPerOption) + gap;
325 if (y < 0) return -1;
326 if (x < 0 || x > static_cast<int>(area.w)) return -1;
327 if (y > (10 + numOptionsDisplayable * ySeparation)) return -1;
331 int selected = cy / ySeparation;
332 if (y < 5) selected = -1;
333 if (selected > numOptionsDisplayable) return -1;
334 /* Important: should be the same algorithm used in draw! */
335 if (selectedOption == (topOption + numOptionsDisplayable)) topOption++;
336 if (selectedOption == (topOption - 1)) topOption--;
337 // if still not visible...
338 if ((selectedOption < topOption) || (selectedOption > (topOption + numOptionsDisplayable)))
340 topOption = selectedOption - (numOptionsDisplayable / 2);
343 if (topOption < 0) topOption = 0;
344 if ((selected + topOption >= static_cast<int>(options.size())) || (selected + topOption < 0)) return -1;
345 return selected + topOption;