]> git.vomp.tv Git - vompclient.git/blob - voptions.cc
Fix line endings
[vompclient.git] / voptions.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 "voptions.h"
22
23 VOptions::VOptions(View* tparent, const char* title, const OPTIONDATA* toptionData, const int tnumOptions)
24 {
25   viewman = ViewMan::getInstance();
26
27   parent = tparent;
28   optionData = toptionData;
29   numOptions = tnumOptions;
30
31   UINT newHeight = 85;
32   if (numOptions < 4) newHeight += (4 * 30);
33   else newHeight += (numOptions * 30);
34
35   create(530, newHeight);
36
37   setBackgroundColour(Colour::VIEWBACKGROUND);
38   setTitleBarOn(1);
39   setTitleBarColour(Colour::TITLEBARBACKGROUND);
40   setTitleText(title);
41
42   int fontHeight = surface->getFontHeight();
43
44   optionBoxes = new WOptionBox[numOptions];
45
46   UINT i, j;
47   char* config;
48   vdr = VDR::getInstance();
49   // After setup, save all current indexes
50   optionsAtStart = new int[numOptions];
51
52   for (i = 0; i < numOptions; i++)
53   {
54     optionBoxes[i].setSurface(surface);
55     optionBoxes[i].setSurfaceOffset(346, 45 + (i * 30));
56     optionBoxes[i].setDimensions(150, fontHeight);
57
58     if (optionData[i].optionType == OPTIONTYPE_TEXT)
59     {
60       for (j = 0; j < optionData[i].optionCount; j++)
61       {
62         Log::getInstance()->log("Options", Log::DEBUG, "Add option: %s", optionData[i].options[j]);
63         optionBoxes[i].addOption(tr((char*)optionData[i].options[j]));
64       }
65
66       // Set the built in default
67       optionBoxes[i].setSelected(tr((char*)optionData[i].options[optionData[i].defaultOption]));
68     }
69     else
70     {
71       // int mode
72       optionBoxes[i].setIntMode(optionData[i].startInt, optionData[i].optionCount);
73       optionBoxes[i].setSelected(optionData[i].defaultOption);
74     }
75
76     // Now see if there is a config option for it
77     config = vdr->configLoad(optionData[i].configSection, optionData[i].configParam);
78     if (config)
79     {
80       if (optionData[i].optionType == OPTIONTYPE_TEXT)
81       {
82         for (j = 0; j < optionData[i].optionCount; j++)
83         {
84           if (!STRCASECMP(config, optionData[i].options[j]))
85           {
86             optionBoxes[i].setSelected(tr((char*)optionData[i].options[j]));
87           }
88         }
89       }
90       else
91       {
92         optionBoxes[i].setSelected(atoi(config));
93       }
94       delete[] config;
95     }
96
97     // After setup, save initial option
98     optionsAtStart[i] = optionBoxes[i].getSelectedIndex();
99   }
100
101   selectedOption = 0;
102   optionBoxes[0].setActive(1);
103
104   int voff = 0;
105   if ((numOptions < 8) && (numOptions >= 4))
106   {
107     voff = (8 - numOptions) * 10;
108   }
109   else if (numOptions < 4)
110   {
111     voff = 40; //(4 * 10)
112   }
113
114   if (Video::getInstance()->getFormat() == Video::PAL)
115   {
116     setScreenPos(104, 130 + voff);
117   }
118   else
119   {
120     setScreenPos(94, 70 + voff);
121   }
122
123   if (!vdr->isConnected()) Command::getInstance()->connectionLost();
124 }
125
126 VOptions::~VOptions()
127 {
128   delete[] optionsAtStart;
129   delete[] optionBoxes;
130 }
131
132 void VOptions::draw()
133 {
134   View::draw();
135
136   WSymbol wsy;
137   Colour cl;
138
139   drawText(tr("Press back to exit, <, > or [ok] to change"), 10, area.h - 30, Colour::LIGHTTEXT);
140
141   wsy.setSurface(surface);
142
143   for (UINT i = 0; i < numOptions; i++)
144   {
145     drawText(tr(optionData[i].title), 10, 45+i*30, Colour::LIGHTTEXT);
146
147     if (i == selectedOption) cl = Colour::SELECTHIGHLIGHT;
148     else cl = Colour::BUTTONBACKGROUND;
149
150     wsy.nextSymbol = WSymbol::LEFTARROW;
151     wsy.nextColour = cl;
152
153     wsy.setSurfaceOffset(328, 47 + (i * 30));
154     wsy.draw();
155     wsy.nextSymbol = WSymbol::RIGHTARROW;
156     wsy.setSurfaceOffset(498, 47 + (i * 30));
157     wsy.draw();
158     optionBoxes[i].draw();
159   }
160 }
161
162 int VOptions::handleCommand(int command)
163 {
164   switch(command)
165   {
166     case Remote::DF_UP:
167     case Remote::UP:
168     {
169       if (selectedOption > 0)
170       {
171         optionBoxes[selectedOption].setActive(0);
172         --selectedOption;
173         optionBoxes[selectedOption].setActive(1);
174         draw();
175         viewman->updateView(this);
176       }
177       return 2;
178     }
179     case Remote::DF_DOWN:
180     case Remote::DOWN:
181     {
182       if (selectedOption < (numOptions - 1))
183       {
184         optionBoxes[selectedOption].setActive(0);
185         ++selectedOption;
186         optionBoxes[selectedOption].setActive(1);
187         draw();
188         viewman->updateView(this);
189       }
190       return 2;
191     }
192     case Remote::DF_LEFT:
193     case Remote::LEFT:
194     {
195       optionBoxes[selectedOption].left();
196       draw();
197       viewman->updateView(this);
198       return 2;
199     }
200     case Remote::DF_RIGHT:
201     case Remote::RIGHT:
202     {
203       optionBoxes[selectedOption].right();
204       draw();
205       viewman->updateView(this);
206       return 2;
207     }
208     case Remote::BACK:
209     {
210       doSave();
211
212       // Instead of returning 4 here which would delete this view
213       // before the doSave message is processed, let the message queue
214       // do the doSave then this close message. That will make the options menu
215       // disappear before this view
216
217       Message* m = new Message();
218       m->message = Message::CLOSE_ME;
219       m->from = this;
220       m->to = viewman;
221       Command::getInstance()->postMessageNoLock(m);
222
223       return 2;
224     }
225     case Remote::OK:
226     {
227       optionBoxes[selectedOption].cycle();
228       draw();
229       viewman->updateView(this);
230     }
231   }
232
233   return 1;
234 }
235
236 void VOptions::doSave()
237 {
238   UINT i;
239   int* result = new int[numOptions];
240
241   for (i = 0; i < numOptions; i++)
242   {
243     result[i] = optionBoxes[i].getSelectedIndex();
244
245     if (result[i] != optionsAtStart[i])
246     {
247       Log::getInstance()->log("Options", Log::DEBUG, "Option %i has changed", i);
248
249       if (optionData[i].optionType == OPTIONTYPE_TEXT)
250       {
251         vdr->configSave(optionData[i].configSection, optionData[i].configParam,
252           optionData[i].options[result[i]]);
253       }
254       else
255       {
256         char buffer[20];
257         sprintf(buffer, "%i", result[i]);
258         vdr->configSave(optionData[i].configSection, optionData[i].configParam,
259           buffer);
260       }
261     }
262   }
263
264   // Save a vector of option IDs that have changed
265
266   map<int, int>* optionChanges = new map<int, int>;
267
268   for (i = 0; i < numOptions; i++)
269   {
270     if (result[i] != optionsAtStart[i])
271     {
272       (*optionChanges)[optionData[i].id] = result[i];
273     }
274   }
275
276   delete[] result;
277
278   // Send it to parent for changes to be applied
279   Message* m = new Message();
280   m->message = Message::CHANGED_OPTIONS;
281   m->to = parent;
282   m->parameter = (ULONG)optionChanges;
283   Command::getInstance()->postMessageNoLock(m);
284
285 }
286
287
288 void VOptions::processMessage(Message* m)
289 {
290   if (m->message == Message::MOUSE_MOVE)
291   {
292     int x=(m->parameter>>16)-getScreenX();
293     int y=(m->parameter&0xFFFF)-getScreenY();
294     UINT i;
295     for (i = 0; i < numOptions; i++)
296     {
297       if (optionBoxes[i].mouseMove(x,y))
298       {
299         optionBoxes[selectedOption].setActive(0);
300         optionBoxes[i].setActive(1);
301         selectedOption=i;
302         draw();
303         ViewMan::getInstance()->updateView(this);
304         break;
305       }
306     }
307   }
308   else if (m->message == Message::MOUSE_LBDOWN)
309   {
310     int x=(m->parameter>>16)-getScreenX();
311     int y=(m->parameter&0xFFFF)-getScreenY();
312     UINT i;
313     bool butpress=false;
314     for (i = 0; i < numOptions; i++)
315     {
316       if (optionBoxes[i].mouseLBDOWN(x,y))
317       {
318         ViewMan::getInstance()->handleCommand(Remote::OK); //simulate OK press
319         butpress=true;
320         break;
321       }
322     }
323     if (!butpress)
324     {
325       //check if press is outside this view! then simulate cancel
326       if (x<0 || y <0 || x>getWidth() || y>getHeight())
327       {
328         ViewMan::getInstance()->handleCommand(Remote::BACK); //simulate cancel press
329       }
330     }
331   }
332 }