]> git.vomp.tv Git - vompclient.git/blob - wselectlist.cc
Some changes for windows comptibility
[vompclient.git] / wselectlist.cc
1 /*
2     Copyright 2004-2005 Chris Tallon
3
4     This file is part of VOMP.
5
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.
10
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.
15
16     You should have received a copy of the GNU General Public License
17     along with VOMP; if not, write to the Free Software
18     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19 */
20
21 #include "wselectlist.h"
22
23 #include "colour.h"
24 #include "log.h"
25
26 #include <math.h>
27
28 WSelectList::WSelectList():
29 backgroundColour(DrawStyle::VIEWBACKGROUND)
30 {
31   selectedOption = 0;
32   topOption = 0;
33   numOptionsDisplayable = 0;
34   numColumns = 0;
35   noLoop = 0;
36   gap = 1;
37   showseloption = true;
38   darkseloption = false;
39   linesPerOption = 1;
40
41 }
42
43 WSelectList::~WSelectList()
44 {
45   clear();
46 }
47
48 void WSelectList::clear()
49 {
50   int vsize = options.size();
51   for (int i = 0; i < vsize; i++)
52   {
53     delete[] options[i].text;
54     if (options[i].pict) delete options[i].pict;
55   }
56   options.clear();
57
58   selectedOption = 0;
59   topOption = 0;
60   numOptionsDisplayable = 0;
61   numColumns = 0;
62 }
63
64 void WSelectList::setNoLoop()
65 {
66   noLoop = 1;
67 }
68
69 void WSelectList::setBackgroundColour(const DrawStyle& colour)
70 {
71   backgroundColour = colour;
72 }
73
74 void WSelectList::hintSetCurrent(int idx)
75 {
76   selectedOption = idx;
77   if (selectedOption >= options.size()) selectedOption = options.size() - 1;
78 }
79
80 void WSelectList::hintSetTop(int idx)
81 {
82   topOption = idx;
83 }
84
85 int WSelectList::addOption(const char* text, ULONG data, int selected, TVMediaInfo * pict)
86 {
87   int thisNewOption = options.size();
88
89   wsloption wslo;
90   wslo.text = new char[strlen(text) + 1];
91   strcpy(wslo.text, text);
92   wslo.data = data;
93   wslo.pict = pict;
94   options.push_back(wslo);
95   if (selected) selectedOption = thisNewOption;
96   return thisNewOption;
97 }
98
99 void WSelectList::draw()
100 {
101   int fontHeight = getFontHeight();
102   int ySeperation = fontHeight * linesPerOption + gap;
103
104   numOptionsDisplayable = (area.h - 5) / ySeperation;
105
106   if (selectedOption == (topOption + numOptionsDisplayable)) topOption++;
107   if (selectedOption == ((UINT)topOption - 1)) topOption--;
108   // if still not visible...
109   if ((selectedOption < (UINT)topOption) || (selectedOption > (topOption + numOptionsDisplayable)))
110   {
111     topOption = selectedOption - (numOptionsDisplayable / 2);
112   }
113
114   if (topOption < 0) topOption = 0;
115
116
117   fillColour(backgroundColour);
118
119   UINT ypos = 5;
120   for (UINT i = topOption; i < (topOption + numOptionsDisplayable); i++)
121   {
122     if (i == options.size()) return;
123     if ((ypos + ySeperation) > area.h) break;
124
125     if (i == selectedOption && showseloption)
126     {
127
128       rectangle(0, ypos, area.w, fontHeight * linesPerOption-1, darkseloption ? DrawStyle::SELECTDARKHIGHLIGHT: DrawStyle::SELECTHIGHLIGHT);
129
130       drawOptionLine(options[i].text, 5, ypos, area.w - 5, DrawStyle::DARKTEXT, options[i].pict);
131     }
132     else
133     {
134         rectangle(0, ypos, area.w, fontHeight * linesPerOption-1, DrawStyle::SELECTBACKGROUND);
135
136         drawOptionLine(options[i].text, 5, ypos, area.w - 5, DrawStyle::LIGHTTEXT, options[i].pict);
137     }
138     ypos += ySeperation;
139   }
140
141 }
142
143 void WSelectList::addColumn(int x)
144 {
145   if (numColumns == 10) return;
146   columns[numColumns++] = x;
147 }
148
149 int WSelectList::getColumn(int x)
150 {
151         if (x>= numColumns) return 0;
152         return  columns[x];
153 }
154
155 void WSelectList::drawOptionLine(char* text, int xpos, int ypos, int width, const DrawStyle& colour, TVMediaInfo* pict)
156 {
157   UINT curline = 0;
158   UINT taboffset = 0;
159   int fontHeight = getFontHeight();
160   float ypos_mod= ypos + (linesPerOption-floor(linesPerOption))*((float)fontHeight)*0.5f;
161
162   int imagewidth=0;
163   int xposmod=xpos;
164   if (numColumns>1) imagewidth=columns[1]-columns[0];
165   if (pict)
166   {
167           drawTVMedia(*pict, xpos,ypos,imagewidth,fontHeight*linesPerOption,TopLeftLimited);
168           taboffset++;
169           xposmod+=xpos;
170   }
171
172   if (!numColumns && linesPerOption == 1)
173   {
174
175     drawText(text, xpos, ypos, width, colour);
176   }
177   else
178   {
179     char buffer[200];
180     strncpy(buffer, text, 199);
181     int currentColumn = taboffset;
182     char* pointer;
183     char* savepointer;
184
185     pointer = STRTOKR(buffer, "\t\n", &savepointer);
186     while(pointer)
187     {
188       drawText(pointer, xposmod + columns[currentColumn], ypos_mod + curline * fontHeight, width - columns[currentColumn], colour);
189
190       pointer = STRTOKR(NULL, "\t\n", &savepointer);
191       if (pointer) {
192           char delimiter = text[pointer - buffer-1];
193           if (delimiter == '\t') currentColumn++;
194           else if (delimiter == '\n' ){
195                   currentColumn = taboffset;
196                   curline++;
197           }
198       }
199       if (curline >= linesPerOption) return;
200
201       if (currentColumn == 10) return;
202     }
203   }
204 }
205
206 void WSelectList::up()
207 {
208   if (selectedOption > 0)
209   {
210     selectedOption--;
211   }
212   else
213   {
214     if (!noLoop) selectedOption = options.size() - 1;
215   }
216 }
217
218 void WSelectList::down()
219 {
220   if (selectedOption < options.size() - 1)
221   {
222     selectedOption++;
223   }
224   else
225   {
226     if (!noLoop) selectedOption = 0;
227   }
228 }
229
230 void WSelectList::pageUp()
231 {
232   topOption -= numOptionsDisplayable;
233   if (topOption < 0) topOption = 0;
234
235   selectedOption = topOption;
236 }
237
238 void WSelectList::pageDown()
239 {
240   if ((topOption + numOptionsDisplayable) >= options.size())
241   {
242     selectedOption = options.size() - 1;
243   }
244   else
245   {
246     topOption += numOptionsDisplayable;
247     selectedOption = topOption;
248   }
249 }
250
251 int WSelectList::getTopOption()
252 {
253   return topOption;
254 }
255
256 int WSelectList::getNumOptions()
257 {
258   return options.size();
259 }
260
261 int WSelectList::getBottomOption()
262 {
263   UINT retval = topOption + numOptionsDisplayable;
264   if (retval > options.size()) return options.size();
265   else return retval;
266 }
267
268 int WSelectList::getCurrentOption()
269 {
270   return selectedOption;
271 }
272
273 ULONG WSelectList::getCurrentOptionData()
274 {
275   if (!options.size()) return 0;
276   return options[selectedOption].data;
277 }
278
279 int WSelectList::getNumOptionsDisplayable()
280 {
281         return numOptionsDisplayable;
282 }
283
284 bool WSelectList::mouseAndroidScroll(int x, int y,int sx, int sy)
285 {
286 /*      int fontHeight = getFontHeight();
287         int movelines= sy/fontHeight;
288
289         int seloption=selectedOption+movelines;
290         if (seloption<0) seloption=0;
291         else if (seloption>options.size()-1) seloption=options.size()-1;
292         selectedOption=seloption;*/
293     return false;
294
295 }
296
297 bool WSelectList::mouseMove(int x, int y)
298 {
299   int ml = getMouseLine(x-getRootBoxOffsetX(), y-getRootBoxOffsetY());
300   if (ml>=0 && ml!=(int)selectedOption)
301   {
302     selectedOption = ml;
303     return true;
304   }
305   return false;
306 }
307
308 bool WSelectList::mouseLBDOWN(int x, int y)
309 {
310   int ml = getMouseLine(x-getRootBoxOffsetX(), y-getRootBoxOffsetY());
311   if (ml == (int)selectedOption)
312   {
313     /* caller should generate a OK message*/
314     return true;
315   }
316   return false;
317 }
318
319 int WSelectList::getMouseLine(int x,int y)
320 {
321   int fontHeight = getFontHeight();
322   int ySeperation = fontHeight + gap;
323
324   if (y<0) return -1;
325   if (x<0 || x>(int)area.w) return -1;
326   if (y>(int)(10+numOptionsDisplayable*ySeperation)) return -1;
327
328   int cy = y - 5;
329
330   int selected=cy/ySeperation;
331   if (y<5) selected=-1;
332   if (selected> ((int)numOptionsDisplayable)) return -1;
333   /* Important: should be the same algorithm used in draw! */
334   if (selectedOption == (topOption + numOptionsDisplayable)) topOption++;
335   if (selectedOption == ((UINT)topOption - 1)) topOption--;
336   // if still not visible...
337   if ((selectedOption < (UINT)topOption) || (selectedOption > (topOption + numOptionsDisplayable)))
338   {
339     topOption = selectedOption - (numOptionsDisplayable / 2);
340   }
341
342   if (topOption < 0) topOption = 0;
343
344   if ((selected+topOption >= (int) options.size()) ||
345       (selected + topOption < 0)) return -1;
346
347   return selected + topOption;
348 }