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