]> git.vomp.tv Git - vompclient.git/blob - wselectlist.cc
Preparations for dynamic mode switching
[vompclient.git] / wselectlist.cc
1 /*\r
2     Copyright 2004-2005 Chris Tallon\r
3 \r
4     This file is part of VOMP.\r
5 \r
6     VOMP is free software; you can redistribute it and/or modify\r
7     it under the terms of the GNU General Public License as published by\r
8     the Free Software Foundation; either version 2 of the License, or\r
9     (at your option) any later version.\r
10 \r
11     VOMP is distributed in the hope that it will be useful,\r
12     but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14     GNU General Public License for more details.\r
15 \r
16     You should have received a copy of the GNU General Public License\r
17     along with VOMP; if not, write to the Free Software\r
18     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.\r
19 */\r
20 \r
21 #include "wselectlist.h"\r
22 \r
23 #include "colour.h"\r
24 #include "log.h"\r
25 \r
26 WSelectList::WSelectList():\r
27 backgroundColour(DrawStyle::VIEWBACKGROUND)\r
28 {\r
29   selectedOption = 0;\r
30   topOption = 0;\r
31   numOptionsDisplayable = 0;\r
32   numColumns = 0;\r
33   noLoop = 0;\r
34   gap = 1;\r
35   showseloption = true;\r
36   darkseloption = false;\r
37 \r
38 }\r
39 \r
40 WSelectList::~WSelectList()\r
41 {\r
42   clear();\r
43 }\r
44 \r
45 void WSelectList::clear()\r
46 {\r
47   int vsize = options.size();\r
48   for (int i = 0; i < vsize; i++)\r
49   {\r
50     delete[] options[i].text;\r
51   }\r
52   options.clear();\r
53 \r
54   selectedOption = 0;\r
55   topOption = 0;\r
56   numOptionsDisplayable = 0;\r
57   numColumns = 0;\r
58 }\r
59 \r
60 void WSelectList::setNoLoop()\r
61 {\r
62   noLoop = 1;\r
63 }\r
64 \r
65 void WSelectList::setBackgroundColour(const DrawStyle& colour)\r
66 {\r
67   backgroundColour = colour;\r
68 }\r
69 \r
70 void WSelectList::hintSetCurrent(int idx)\r
71 {\r
72   selectedOption = idx;\r
73   if (selectedOption >= options.size()) selectedOption = options.size() - 1;\r
74 }\r
75 \r
76 void WSelectList::hintSetTop(int idx)\r
77 {\r
78   topOption = idx;\r
79 }\r
80 \r
81 int WSelectList::addOption(const char* text, ULONG data, int selected)\r
82 {\r
83   int thisNewOption = options.size();\r
84 \r
85   wsloption wslo;\r
86   wslo.text = new char[strlen(text) + 1];\r
87   strcpy(wslo.text, text);\r
88   wslo.data = data;\r
89   options.push_back(wslo);\r
90   if (selected) selectedOption = thisNewOption;\r
91   return thisNewOption;\r
92 }\r
93 \r
94 void WSelectList::draw()\r
95 {\r
96   int fontHeight = getFontHeight();\r
97   int ySeperation = fontHeight + gap;\r
98 \r
99   numOptionsDisplayable = (area.h - 5) / ySeperation;\r
100 \r
101   if (selectedOption == (topOption + numOptionsDisplayable)) topOption++;\r
102   if (selectedOption == ((UINT)topOption - 1)) topOption--;\r
103   // if still not visible...\r
104   if ((selectedOption < (UINT)topOption) || (selectedOption > (topOption + numOptionsDisplayable)))\r
105   {\r
106     topOption = selectedOption - (numOptionsDisplayable / 2);\r
107   }\r
108 \r
109   if (topOption < 0) topOption = 0;\r
110 \r
111 \r
112   fillColour(backgroundColour);\r
113 \r
114   UINT ypos = 5;\r
115   for (UINT i = topOption; i < (topOption + numOptionsDisplayable); i++)\r
116   {\r
117     if (i == options.size()) return;\r
118     if ((ypos + ySeperation) > area.h) break;\r
119 \r
120     if (i == selectedOption && showseloption)\r
121     {\r
122 \r
123       rectangle(0, ypos, area.w, fontHeight, darkseloption ? DrawStyle::SELECTDARKHIGHLIGHT: DrawStyle::SELECTHIGHLIGHT);\r
124 \r
125       drawOptionLine(options[i].text, 5, ypos, area.w - 5, DrawStyle::DARKTEXT);\r
126     }\r
127     else\r
128     {\r
129 \r
130       drawOptionLine(options[i].text, 5, ypos, area.w - 5, DrawStyle::LIGHTTEXT);\r
131     }\r
132     ypos += ySeperation;\r
133   }\r
134 \r
135 }\r
136 \r
137 void WSelectList::addColumn(int x)\r
138 {\r
139   if (numColumns == 10) return;\r
140   columns[numColumns++] = x;\r
141 }\r
142 \r
143 void WSelectList::drawOptionLine(char* text, int xpos, int ypos, int width, const DrawStyle& colour)\r
144 {\r
145   if (!numColumns)\r
146   {\r
147 \r
148     drawText(text, xpos, ypos, width, colour);\r
149   }\r
150   else\r
151   {\r
152     char buffer[200];\r
153     strncpy(buffer, text, 199);\r
154     int currentColumn = 0;\r
155     char* pointer;\r
156 \r
157     pointer = strtok(buffer, "\t");\r
158     while(pointer)\r
159     {\r
160 \r
161       drawText(pointer, xpos + columns[currentColumn], ypos, width - columns[currentColumn], colour);\r
162 \r
163       currentColumn++;\r
164       if (currentColumn == 10) return;\r
165       pointer = strtok(NULL, "\t");\r
166     }\r
167   }\r
168 }\r
169 \r
170 void WSelectList::up()\r
171 {\r
172   if (selectedOption > 0)\r
173   {\r
174     selectedOption--;\r
175   }\r
176   else\r
177   {\r
178     if (!noLoop) selectedOption = options.size() - 1;\r
179   }\r
180 }\r
181 \r
182 void WSelectList::down()\r
183 {\r
184   if (selectedOption < options.size() - 1)\r
185   {\r
186     selectedOption++;\r
187   }\r
188   else\r
189   {\r
190     if (!noLoop) selectedOption = 0;\r
191   }\r
192 }\r
193 \r
194 void WSelectList::pageUp()\r
195 {\r
196   topOption -= numOptionsDisplayable;\r
197   if (topOption < 0) topOption = 0;\r
198 \r
199   selectedOption = topOption;\r
200 }\r
201 \r
202 void WSelectList::pageDown()\r
203 {\r
204   if ((topOption + numOptionsDisplayable) >= options.size())\r
205   {\r
206     selectedOption = options.size() - 1;\r
207   }\r
208   else\r
209   {\r
210     topOption += numOptionsDisplayable;\r
211     selectedOption = topOption;\r
212   }\r
213 }\r
214 \r
215 int WSelectList::getTopOption()\r
216 {\r
217   return topOption;\r
218 }\r
219 \r
220 int WSelectList::getNumOptions()\r
221 {\r
222   return options.size();\r
223 }\r
224 \r
225 int WSelectList::getBottomOption()\r
226 {\r
227   UINT retval = topOption + numOptionsDisplayable;\r
228   if (retval > options.size()) return options.size();\r
229   else return retval;\r
230 }\r
231 \r
232 int WSelectList::getCurrentOption()\r
233 {\r
234   return selectedOption;\r
235 }\r
236 \r
237 ULONG WSelectList::getCurrentOptionData()\r
238 {\r
239   if (!options.size()) return 0;\r
240   return options[selectedOption].data;\r
241 }\r
242 \r
243 bool WSelectList::mouseAndroidScroll(int x, int y,int sx, int sy)\r
244 {\r
245 /*      int fontHeight = getFontHeight();\r
246         int movelines= sy/fontHeight;\r
247 \r
248         int seloption=selectedOption+movelines;\r
249         if (seloption<0) seloption=0;\r
250         else if (seloption>options.size()-1) seloption=options.size()-1;\r
251         selectedOption=seloption;*/\r
252 \r
253 }\r
254 \r
255 bool WSelectList::mouseMove(int x, int y)\r
256 {\r
257   int ml = getMouseLine(x-getRootBoxOffsetX(), y-getRootBoxOffsetY());\r
258   if (ml>=0 && ml!=(int)selectedOption)\r
259   {\r
260     selectedOption = ml;\r
261     return true;\r
262   }\r
263   return false;\r
264 }\r
265 \r
266 bool WSelectList::mouseLBDOWN(int x, int y)\r
267 {\r
268   int ml = getMouseLine(x-getRootBoxOffsetX(), y-getRootBoxOffsetY());\r
269   if (ml == (int)selectedOption)\r
270   {\r
271     /* caller should generate a OK message*/\r
272     return true;\r
273   }\r
274   return false;\r
275 }\r
276 \r
277 int WSelectList::getMouseLine(int x,int y)\r
278 {\r
279   int fontHeight = getFontHeight();\r
280   int ySeperation = fontHeight + gap;\r
281 \r
282   if (y<0) return -1;\r
283   if (x<0 || x>(int)area.w) return -1;\r
284   if (y>(int)(10+numOptionsDisplayable*ySeperation)) return -1;\r
285 \r
286   int cy = y - 5;\r
287 \r
288   int selected=cy/ySeperation;\r
289   if (y<5) selected=-1;\r
290   if (selected> ((int)numOptionsDisplayable)) return -1;\r
291   /* Important: should be the same algorithm used in draw! */\r
292   if (selectedOption == (topOption + numOptionsDisplayable)) topOption++;\r
293   if (selectedOption == ((UINT)topOption - 1)) topOption--;\r
294   // if still not visible...\r
295   if ((selectedOption < (UINT)topOption) || (selectedOption > (topOption + numOptionsDisplayable)))\r
296   {\r
297     topOption = selectedOption - (numOptionsDisplayable / 2);\r
298   }\r
299 \r
300   if (topOption < 0) topOption = 0;\r
301 \r
302   if ((selected+topOption >= (int) options.size()) ||\r
303       (selected + topOption < 0)) return -1;\r
304 \r
305   return selected + topOption;\r
306 }\r