]> git.vomp.tv Git - vompclient.git/blob - voptions.cc
Updated
[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
124 VOptions::~VOptions()
125 {
126   delete[] optionsAtStart;
127   delete[] optionBoxes;
128 }
129
130 void VOptions::draw()
131 {
132   View::draw();
133
134   WSymbol wsy;
135   Colour cl;
136
137   drawText(tr("Press back to exit, <, > or [ok] to change"), 10, area.h - 30, Colour::LIGHTTEXT);
138
139   wsy.setSurface(surface);
140
141   for (UINT i = 0; i < numOptions; i++)
142   {
143     drawText(tr(optionData[i].title), 10, 45+i*30, Colour::LIGHTTEXT);
144
145     if (i == selectedOption) cl = Colour::SELECTHIGHLIGHT;
146     else cl = Colour::BUTTONBACKGROUND;
147
148     wsy.nextSymbol = WSymbol::LEFTARROW;
149     wsy.nextColour = cl;
150
151     wsy.setSurfaceOffset(328, 47 + (i * 30));
152     wsy.draw();
153     wsy.nextSymbol = WSymbol::RIGHTARROW;
154     wsy.setSurfaceOffset(498, 47 + (i * 30));
155     wsy.draw();
156     optionBoxes[i].draw();
157   }
158 }
159
160 int VOptions::handleCommand(int command)
161 {
162   switch(command)
163   {
164     case Remote::DF_UP:
165     case Remote::UP:
166     {
167       if (selectedOption > 0)
168       {
169         optionBoxes[selectedOption].setActive(0);
170         --selectedOption;
171         optionBoxes[selectedOption].setActive(1);
172         draw();
173         viewman->updateView(this);
174       }
175       return 2;
176     }
177     case Remote::DF_DOWN:
178     case Remote::DOWN:
179     {
180       if (selectedOption < (numOptions - 1))
181       {
182         optionBoxes[selectedOption].setActive(0);
183         ++selectedOption;
184         optionBoxes[selectedOption].setActive(1);
185         draw();
186         viewman->updateView(this);
187       }
188       return 2;
189     }
190     case Remote::DF_LEFT:
191     case Remote::LEFT:
192     {
193       optionBoxes[selectedOption].left();
194       draw();
195       viewman->updateView(this);
196       return 2;
197     }
198     case Remote::DF_RIGHT:
199     case Remote::RIGHT:
200     {
201       optionBoxes[selectedOption].right();
202       draw();
203       viewman->updateView(this);
204       return 2;
205     }
206     case Remote::BACK:
207     {
208       doSave();
209
210       // Instead of returning 4 here which would delete this view
211       // before the doSave message is processed, let the message queue
212       // do the doSave then this close message. That will make the options menu
213       // disappear before this view
214
215       Message* m = new Message();
216       m->message = Message::CLOSE_ME;
217       m->from = this;
218       m->to = viewman;
219       viewman->postMessage(m);
220
221       return 2;
222     }
223     case Remote::OK:
224     {
225       optionBoxes[selectedOption].cycle();
226       draw();
227       viewman->updateView(this);
228     }
229   }
230
231   return 1;
232 }
233
234 void VOptions::doSave()
235 {
236   UINT i;
237   int result[numOptions];
238
239   for (i = 0; i < numOptions; i++)
240   {
241     result[i] = optionBoxes[i].getSelectedIndex();
242
243     if (result[i] != optionsAtStart[i])
244     {
245       Log::getInstance()->log("Options", Log::DEBUG, "Option %i has changed", i);
246
247       if (optionData[i].optionType == OPTIONTYPE_TEXT)
248       {
249         vdr->configSave(optionData[i].configSection, optionData[i].configParam,
250           optionData[i].options[result[i]]);
251       }
252       else
253       {
254         char buffer[20];
255         sprintf(buffer, "%i", result[i]);
256         vdr->configSave(optionData[i].configSection, optionData[i].configParam,
257           buffer);
258       }
259     }
260   }
261
262   // Save a vector of option IDs that have changed
263
264   map<int, int>* optionChanges = new map<int, int>;
265
266   for (i = 0; i < numOptions; i++)
267   {
268     if (result[i] != optionsAtStart[i])
269     {
270       (*optionChanges)[optionData[i].id] = result[i];
271     }
272   }
273
274   // Send it to parent for changes to be applied
275   Message* m = new Message();
276   m->message = Message::CHANGED_OPTIONS;
277   m->to = parent;
278   m->parameter = (ULONG)optionChanges;
279   viewman->postMessage(m);
280
281 }
282