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