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