]> git.vomp.tv Git - vompclient.git/blob - wselectlist.cc
Rewritten vomp discovery protocol
[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
25 WSelectList::WSelectList()
26 {
27   selectedOption = 0;
28   topOption = 0;
29   numOptionsDisplayable = 0;
30   numColumns = 0;
31   noLoop = 0;
32   gap = 1;
33   showseloption = true;
34   darkseloption = false;
35   backgroundColour = Colour::VIEWBACKGROUND;
36 }
37
38 WSelectList::~WSelectList()
39 {
40   clear();
41 }
42
43 void WSelectList::clear()
44 {
45   int vsize = options.size();
46   for (int i = 0; i < vsize; i++)
47   {
48     delete[] options[i].text;
49   }
50   options.clear();
51
52   selectedOption = 0;
53   topOption = 0;
54   numOptionsDisplayable = 0;
55   numColumns = 0;
56 }
57
58 void WSelectList::setNoLoop()
59 {
60   noLoop = 1;
61 }
62
63 void WSelectList::setBackgroundColour(const Colour& colour)
64 {
65   backgroundColour = colour;
66 }
67
68 void WSelectList::hintSetCurrent(int idx)
69 {
70   selectedOption = idx;
71   if (selectedOption >= options.size()) selectedOption = options.size() - 1;
72 }
73
74 void WSelectList::hintSetTop(int idx)
75 {
76   topOption = idx;
77 }
78
79 int WSelectList::addOption(const char* text, ULONG data, int selected)
80 {
81   int thisNewOption = options.size();
82
83   wsloption wslo;
84   wslo.text = new char[strlen(text) + 1];
85   strcpy(wslo.text, text);
86   wslo.data = data;
87   options.push_back(wslo);
88   if (selected) selectedOption = thisNewOption;
89   return thisNewOption;
90 }
91
92 void WSelectList::draw()
93 {
94   int fontHeight = surface->getFontHeight();
95   int ySeperation = fontHeight + gap;
96
97   numOptionsDisplayable = (area.h - 5) / ySeperation;
98
99   if (selectedOption == (topOption + numOptionsDisplayable)) topOption++;
100   if (selectedOption == ((UINT)topOption - 1)) topOption--;
101   // if still not visible...
102   if ((selectedOption < (UINT)topOption) || (selectedOption > (topOption + numOptionsDisplayable)))
103   {
104     topOption = selectedOption - (numOptionsDisplayable / 2);
105   }
106
107   if (topOption < 0) topOption = 0;
108
109
110   fillColour(backgroundColour);
111
112   UINT ypos = 5;
113   for (UINT i = topOption; i < (topOption + numOptionsDisplayable); i++)
114   {
115     if (i == options.size()) return;
116     if ((ypos + ySeperation) > area.h) break;
117
118     if (i == selectedOption && showseloption)
119     {
120       rectangle(0, ypos, area.w, fontHeight, darkseloption ? Colour::SELECTDARKHIGHLIGHT: Colour::SELECTHIGHLIGHT);
121       drawOptionLine(options[i].text, 5, ypos, area.w - 5, Colour::DARKTEXT);
122     }
123     else
124     {
125       drawOptionLine(options[i].text, 5, ypos, area.w - 5, Colour::LIGHTTEXT);
126     }
127     ypos += ySeperation;
128   }
129 }
130
131 void WSelectList::addColumn(int x)
132 {
133   if (numColumns == 10) return;
134   columns[numColumns++] = x;
135 }
136
137 void WSelectList::drawOptionLine(char* text, int xpos, int ypos, int width, const Colour& colour)
138 {
139   if (!numColumns)
140   {
141     drawText(text, xpos, ypos, width, colour);
142   }
143   else
144   {
145     char buffer[200];
146     strncpy(buffer, text, 199);
147     int currentColumn = 0;
148     char* pointer;
149
150     pointer = strtok(buffer, "\t");
151     while(pointer)
152     {
153       drawText(pointer, xpos + columns[currentColumn], ypos, width - columns[currentColumn], colour);
154       currentColumn++;
155       if (currentColumn == 10) return;
156       pointer = strtok(NULL, "\t");
157     }
158   }
159 }
160
161 void WSelectList::up()
162 {
163   if (selectedOption > 0)
164   {
165     selectedOption--;
166   }
167   else
168   {
169     if (!noLoop) selectedOption = options.size() - 1;
170   }
171 }
172
173 void WSelectList::down()
174 {
175   if (selectedOption < options.size() - 1)
176   {
177     selectedOption++;
178   }
179   else
180   {
181     if (!noLoop) selectedOption = 0;
182   }
183 }
184
185 void WSelectList::pageUp()
186 {
187   topOption -= numOptionsDisplayable;
188   if (topOption < 0) topOption = 0;
189
190   selectedOption = topOption;
191 }
192
193 void WSelectList::pageDown()
194 {
195   if ((topOption + numOptionsDisplayable) >= options.size())
196   {
197     selectedOption = options.size() - 1;
198   }
199   else
200   {
201     topOption += numOptionsDisplayable;
202     selectedOption = topOption;
203   }
204 }
205
206 int WSelectList::getTopOption()
207 {
208   return topOption;
209 }
210
211 int WSelectList::getNumOptions()
212 {
213   return options.size();
214 }
215
216 int WSelectList::getBottomOption()
217 {
218   UINT retval = topOption + numOptionsDisplayable;
219   if (retval > options.size()) return options.size();
220   else return retval;
221 }
222
223 int WSelectList::getCurrentOption()
224 {
225   return selectedOption;
226 }
227
228 ULONG WSelectList::getCurrentOptionData()
229 {
230   if (!options.size()) return 0;
231   return options[selectedOption].data;
232 }
233
234 bool WSelectList::mouseMove(int x, int y)
235 {
236   int ml = getMouseLine(x-getRootBoxOffsetX(), y-getRootBoxOffsetY());
237   if (ml>=0 && ml!=(int)selectedOption)
238   {
239     selectedOption = ml;
240     return true;
241   }
242   return false;
243 }
244
245 bool WSelectList::mouseLBDOWN(int x, int y)
246 {
247   int ml = getMouseLine(x-getRootBoxOffsetX(), y-getRootBoxOffsetY());
248   if (ml == (int)selectedOption)
249   {
250     /* caller should generate a OK message*/
251     return true;
252   }
253   return false;
254 }
255
256 int WSelectList::getMouseLine(int x,int y)
257 {
258   int fontHeight = surface->getFontHeight();
259   int ySeperation = fontHeight + gap;
260
261   if (y<0) return -1;
262   if (x<0 || x>(int)area.w) return -1;
263   if (y>(int)(10+numOptionsDisplayable*ySeperation)) return -1;
264
265   int cy = y - 5;
266
267   int selected=cy/ySeperation;
268   if (y<5) selected=-1;
269   if (selected> ((int)numOptionsDisplayable)) return -1;
270   /* Important: should be the same algorithm used in draw! */
271   if (selectedOption == (topOption + numOptionsDisplayable)) topOption++;
272   if (selectedOption == ((UINT)topOption - 1)) topOption--;
273   // if still not visible...
274   if ((selectedOption < (UINT)topOption) || (selectedOption > (topOption + numOptionsDisplayable)))
275   {
276     topOption = selectedOption - (numOptionsDisplayable / 2);
277   }
278
279   if (topOption < 0) topOption = 0;
280
281   if ((selected+topOption >= (int) options.size()) ||
282       (selected + topOption < 0)) return -1;
283
284   return selected + topOption;
285 }