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/>.
26 #include "wselectlist.h"
28 WSelectList::WSelectList():
29 backgroundColour(DrawStyle::VIEWBACKGROUND)
33 WSelectList::~WSelectList()
38 void WSelectList::clear()
40 int vsize = options.size();
41 for (int i = 0; i < vsize; i++)
43 delete[] options[i].text;
44 if (options[i].pict) delete options[i].pict;
50 numOptionsDisplayable = 0;
54 void WSelectList::setNoLoop()
59 void WSelectList::setBackgroundColour(const DrawStyle& colour)
61 backgroundColour = colour;
64 void WSelectList::hintSetCurrent(int idx)
67 if (selectedOption >= options.size()) selectedOption = options.size() - 1;
70 void WSelectList::hintSetTop(int idx)
75 int WSelectList::addOption(const char* text, void* data, int selected, TVMediaInfo* pict)
77 int thisNewOption = options.size();
80 wslo.text = new char[strlen(text) + 1];
81 strcpy(wslo.text, text);
84 options.push_back(wslo);
85 if (selected) selectedOption = thisNewOption;
89 void WSelectList::draw()
91 int fontHeight = getFontHeight();
92 int ySeparation = static_cast<int>(static_cast<float>(fontHeight) * linesPerOption) + gap;
94 numOptionsDisplayable = (area.h - 5) / ySeparation;
96 if (selectedOption == (topOption + numOptionsDisplayable)) topOption++;
97 if (selectedOption == ((UINT)topOption - 1)) topOption--;
98 // if still not visible...
99 if ((selectedOption < (UINT)topOption) || (selectedOption > (topOption + numOptionsDisplayable)))
101 topOption = selectedOption - (numOptionsDisplayable / 2);
104 if (topOption < 0) topOption = 0;
107 fillColour(backgroundColour);
110 for (UINT i = topOption; i < (topOption + numOptionsDisplayable); i++)
112 if (i == options.size()) return;
113 if ((ypos + ySeparation) > area.h) break;
115 if (i == selectedOption && showseloption)
118 rectangle(0, ypos, area.w, (UINT)(fontHeight * linesPerOption-1), darkseloption ? DrawStyle::SELECTDARKHIGHLIGHT : DrawStyle::SELECTHIGHLIGHT);
120 drawOptionLine(options[i].text, 5, ypos, area.w - 5, DrawStyle::DARKTEXT, options[i].pict);
124 rectangle(0, ypos, area.w, (UINT)(fontHeight * linesPerOption-1), DrawStyle::SELECTBACKGROUND);
126 drawOptionLine(options[i].text, 5, ypos, area.w - 5, DrawStyle::LIGHTTEXT, options[i].pict);
132 void WSelectList::addColumn(int x)
134 if (numColumns == 10) return;
135 columns[numColumns++] = x;
138 int WSelectList::getColumn(int x)
140 if (x >= numColumns) return 0;
144 void WSelectList::drawOptionLine(char* text, int xpos, int ypos, int width, const DrawStyle& colour, TVMediaInfo* pict)
148 int fontHeight = getFontHeight();
149 float ypos_mod = ypos + (linesPerOption - floor(linesPerOption)) * ((float)fontHeight) * 0.5f;
153 if (numColumns > 1) imagewidth = columns[1] - columns[0];
156 drawTVMedia(*pict, xpos, ypos, imagewidth, fontHeight * linesPerOption, TopLeftLimited);
161 if (!numColumns && linesPerOption == 1)
163 drawText(text, xpos, ypos, width, colour);
168 strncpy(buffer, text, 199);
169 int currentColumn = taboffset;
173 pointer = STRTOKR(buffer, "\t\n", &savepointer);
176 drawText(pointer, xposmod + columns[currentColumn], (int)(ypos_mod + curline * fontHeight), width - columns[currentColumn], colour);
178 pointer = STRTOKR(NULL, "\t\n", &savepointer);
181 char delimiter = text[pointer - buffer - 1];
182 if (delimiter == '\t') currentColumn++;
183 else if (delimiter == '\n')
185 currentColumn = taboffset;
189 if (static_cast<float>(curline) >= linesPerOption) return;
191 if (currentColumn == 10) return;
196 void WSelectList::up()
198 if (selectedOption > 0)
204 if (!noLoop) selectedOption = options.size() - 1;
208 void WSelectList::down()
210 if (selectedOption < options.size() - 1)
216 if (!noLoop) selectedOption = 0;
220 void WSelectList::pageUp()
222 topOption -= numOptionsDisplayable;
223 if (topOption < 0) topOption = 0;
225 selectedOption = topOption;
228 void WSelectList::pageDown()
230 if ((topOption + numOptionsDisplayable) >= options.size())
232 selectedOption = options.size() - 1;
236 topOption += numOptionsDisplayable;
237 selectedOption = topOption;
241 int WSelectList::getTopOption()
246 int WSelectList::getNumOptions()
248 return options.size();
251 int WSelectList::getBottomOption()
253 UINT retval = topOption + numOptionsDisplayable;
254 if (retval > options.size()) return options.size();
258 int WSelectList::getCurrentOption()
260 return selectedOption;
263 void* WSelectList::getCurrentOptionData()
265 if (!options.size()) return 0;
266 return options[selectedOption].data;
269 int WSelectList::getNumOptionsDisplayable()
271 return numOptionsDisplayable;
274 bool WSelectList::mouseAndroidScroll(int /* x */, int /* y */, int /* sx */, int /* sy */)
277 * int fontHeight = getFontHeight();
278 * int movelines= sy/fontHeight;
280 * int seloption=selectedOption+movelines;
281 * if (seloption<0) seloption=0;
282 * else if (seloption>options.size()-1) seloption=options.size()-1;
283 * selectedOption=seloption;
288 bool WSelectList::mouseMove(int x, int y)
290 int ml = getMouseLine(x - getRootBoxOffsetX(), y - getRootBoxOffsetY());
291 if (ml >= 0 && ml != static_cast<int>(selectedOption))
299 bool WSelectList::mouseLBDOWN(int x, int y)
301 int ml = getMouseLine(x - getRootBoxOffsetX(), y - getRootBoxOffsetY());
302 if (ml == static_cast<int>(selectedOption))
304 /* caller should generate a OK message*/
310 int WSelectList::getMouseLine(int x,int y)
312 int fontHeight = getFontHeight();
313 int ySeparation = static_cast<int>(static_cast<float>(fontHeight) * linesPerOption) + gap;
315 if (y < 0) return -1;
316 if (x < 0 || x > (int)area.w) return -1;
317 if (y > (int)(10 + numOptionsDisplayable * ySeparation)) return -1;
321 int selected = cy / ySeparation;
322 if (y < 5) selected = -1;
323 if (selected > static_cast<int>(numOptionsDisplayable)) return -1;
324 /* Important: should be the same algorithm used in draw! */
325 if (selectedOption == (topOption + numOptionsDisplayable)) topOption++;
326 if (selectedOption == static_cast<UINT>(topOption - 1)) topOption--;
327 // if still not visible...
328 if ((selectedOption < static_cast<UINT>(topOption)) || (selectedOption > (topOption + numOptionsDisplayable)))
330 topOption = selectedOption - (numOptionsDisplayable / 2);
333 if (topOption < 0) topOption = 0;
334 if ((selected + topOption >= static_cast<int>(options.size())) || (selected + topOption < 0)) return -1;
335 return selected + topOption;