]> git.vomp.tv Git - vompclient.git/blob - vlivebanner.cc
Variable width channel numbers
[vompclient.git] / vlivebanner.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 "vlivebanner.h"
22
23 VLiveBanner* VLiveBanner::instance = NULL;
24
25 VLiveBanner::VLiveBanner(VVideoLive* tvvideoLive, Channel* channel, bool bannerTakesCommands)
26 {
27   instance = this;
28   eventList = NULL;
29   vvideoLive = tvvideoLive;
30   takeCommands = bannerTakesCommands;
31
32   clockRegion.x = 440;
33   clockRegion.y = 0;
34   clockRegion.w = 60;
35   clockRegion.h = 30;
36
37   create(500, 120);
38   if (Video::getInstance()->getFormat() == Video::PAL)
39   {
40     setScreenPos(124, 410);
41   }
42   else
43   {
44     setScreenPos(114, 320);
45   }
46
47
48   setBackgroundColour(Colour::VIEWBACKGROUND);
49   setTitleBarOn(1);
50   setTitleBarColour(Colour::TITLEBARBACKGROUND);
51
52   sl.setSurface(surface);
53   sl.setSurfaceOffset(0, 30);
54   sl.setDimensions(area.w, area.h - 60);
55   sl.setNoLoop();
56
57   setChannel(channel);
58 }
59
60 VLiveBanner::~VLiveBanner()
61 {
62   instance = NULL;
63   Timers::getInstance()->cancelTimer(this, 1);
64   Timers::getInstance()->cancelTimer(this, 2);
65   delData();
66 }
67
68 VLiveBanner* VLiveBanner::getInstance()
69 {
70   return instance;
71 }
72
73 void VLiveBanner::delData()
74 {
75   if (eventList)
76   {
77     int eventListSize = eventList->size();
78     for(int i = 0; i < eventListSize; i++)
79     {
80       delete (*eventList)[i];
81     }
82     eventList->clear();
83     delete eventList;
84
85   }
86   sl.clear();
87 }
88
89 void VLiveBanner::setChannel(Channel* tChannel)
90 {
91   delData();
92   currentChannel = tChannel;
93   // get the data
94
95   int numberWidth = (int)VDR::getInstance()->getChannelNumberWidth();
96
97   char ttitleText[100];
98   SNPRINTF(ttitleText, 99, "%0*lu - %s", numberWidth, currentChannel->number, currentChannel->name);
99
100   setTitleText(ttitleText);
101   eventList = VDR::getInstance()->getChannelSchedule(currentChannel->number);
102
103   if (!eventList)
104   {
105     sl.addOption(tr("No channel data available"), 0, 1);
106   }
107   else
108   {
109     sort(eventList->begin(), eventList->end(), EventSorter());
110
111     char tempString[300];
112     char tempString2[300];
113     struct tm* btime;
114     Event* event;
115     int first = 1;
116     int eventListSize = eventList->size();
117     for(int i = 0; i < eventListSize; i++)
118     {
119       event = (*eventList)[i];
120
121       //btime = localtime((time_t*)&event->time);
122       time_t etime = event->time;
123       btime = localtime(&etime);
124 #ifndef _MSC_VER
125       strftime(tempString2, 299, "%0H:%0M ", btime);
126 #else
127       strftime(tempString2, 299, "%H:%M ", btime);
128 #endif
129       SNPRINTF(tempString, 299, "%s %s", tempString2, event->title);
130       sl.addOption(tempString, (ULONG)event, first);
131       first = 0;
132     }
133   }
134
135   // Reset the timer as it probably took 1-2 seconds to change the channel
136   Timers::getInstance()->setTimerD(this, 1, 4);
137 }
138
139 void VLiveBanner::draw()
140 {
141   View::draw();
142   sl.draw();
143   rectangle(0, area.h - 30, area.w, 30, titleBarColour);
144
145   rectangle(7, area.h - 24, 18, 16, Colour::RED);
146   drawText(tr("EPG"), 32, area.h - 25, Colour::LIGHTTEXT);
147
148   rectangle(110, area.h - 24, 18, 16, Colour::GREEN);
149   drawText(tr("info"), 135, area.h - 25, Colour::LIGHTTEXT);
150
151   drawClock();
152 }
153
154 int VLiveBanner::handleCommand(int command)
155 {
156   switch (command)
157   {
158     case Remote::OK:
159     case Remote::BACK:
160     {
161       Timers::getInstance()->cancelTimer(this, 1); // if it exists
162       return 4;
163     }
164     case Remote::DF_UP:
165     {
166       if (!takeCommands) return 0; // banner was auto, old remote
167     } // else drop through
168     case Remote::UP:
169     {
170       sl.up();
171       sl.draw();
172
173       ViewMan::getInstance()->updateView(this);
174
175       // Arrows pressed, go to an 8s timer
176       Timers::getInstance()->setTimerD(this, 1, 8);
177
178       return 2;
179     }
180     case Remote::DF_DOWN:
181     {
182       if (!takeCommands) return 0; // banner was auto, old remote
183     } // else drop through
184     case Remote::DOWN:
185     {
186       sl.down();
187       sl.draw();
188
189       ViewMan::getInstance()->updateView(this);
190
191       // Arrows pressed, go to an 8s timer
192       Timers::getInstance()->setTimerD(this, 1, 8);
193
194       return 2;
195     }
196     case Remote::CHANNELUP:
197     {
198       // cancel timer so this view is still here later
199       Timers::getInstance()->cancelTimer(this, 1); // if it exists
200       vvideoLive->channelChange(VVideoLive::OFFSET, VVideoLive::UP);
201       return 2;
202     }
203     case Remote::CHANNELDOWN:
204     {
205       // cancel timer so this view is still here later
206       Timers::getInstance()->cancelTimer(this, 1); // if it exists
207       vvideoLive->channelChange(VVideoLive::OFFSET, VVideoLive::DOWN);
208       return 2;
209     }
210     case Remote::GREEN:
211     case Remote::MENU:
212     {
213       if (!eventList) return 2;
214       Event* event = (Event*)sl.getCurrentOptionData();
215       Log::getInstance()->log("VLiveBanner", Log::DEBUG, "Found the option you pointed at. %s", event->title);
216       // First, cancel my delete timer
217       Timers::getInstance()->cancelTimer(this, 1); // if it exists
218
219       VInfo* vi = new VInfo();
220       vi->setTitleText(event->title);
221       vi->setBorderOn(1);
222       vi->setExitable();
223       if (event->description) vi->setMainText(event->description);
224       else vi->setMainText(tr("Summary unavailable"));
225       if (Video::getInstance()->getFormat() == Video::PAL)
226       {
227         vi->setScreenPos(120, 130);
228       }
229       else
230       {
231         vi->setScreenPos(110, 90);
232       }
233       vi->create(510, 270);
234       vi->draw();
235
236       ViewMan::getInstance()->add(vi);
237       ViewMan::getInstance()->updateView(vi);
238
239       return 2;
240     }
241     case Remote::GUIDE:
242     case Remote::RED:
243     {
244       // full epg
245       Timers::getInstance()->cancelTimer(this, 1); // if it exists
246       Message* m = new Message(); // Must be done after this view deleted
247       m->message = Message::EPG;
248       m->to = vvideoLive;
249       m->from = this;
250       Command::getInstance()->postMessageNoLock(m);
251       return 4;
252     }
253   }
254
255   return 1;
256 }
257
258 void VLiveBanner::timercall(int clientReference)
259 {
260   if (clientReference == 1)
261   {
262     // delete me!
263     Message* m = new Message();  // Delete self
264     m->message = Message::CLOSE_ME;
265     m->to = ViewMan::getInstance();
266     m->from = this;
267     Command::getInstance()->postMessageFromOuterSpace(m);
268   }
269   else if (clientReference == 2)
270   {
271     // redraw clock
272     drawClock();
273     Message* m = new Message();
274     m->message = Message::REDRAW;
275     m->to = ViewMan::getInstance();
276     m->from = this;
277     m->parameter = (ULONG)&clockRegion;
278     Command::getInstance()->postMessageFromOuterSpace(m);
279   }
280 }
281
282 void VLiveBanner::drawClock()
283 {
284   // Blank the area first
285   rectangle(area.w - 60, 0, 60, 30, titleBarColour);
286
287   char timeString[20];
288   time_t t;
289   time(&t);
290   struct tm* tms = localtime(&t);
291   strftime(timeString, 19, "%H:%M", tms);
292   drawTextRJ(timeString, 490, 5, Colour::LIGHTTEXT);
293
294   time_t dt = 60 - (t % 60);  // seconds to the next minute
295   if (dt == 0) dt = 60; // advance a whole minute if necessary
296   dt += t;  // get a time_t value for it rather than using duration
297   // (so it will occur at the actual second and not second and a half)
298
299   Timers::getInstance()->setTimerT(this, 2, dt);
300 }
301
302 void VLiveBanner::processMessage(Message* m)
303 {
304   if (m->message == Message::MOUSE_MOVE)
305   {
306     if (sl.mouseMove((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY()))
307     {
308       sl.draw();
309       ViewMan::getInstance()->updateView(this);
310     }
311   }
312   else if (m->message == Message::MOUSE_LBDOWN)
313   {
314     //check if press is outside this view! then simulate cancel
315     int x=(m->parameter>>16)-getScreenX();
316     int y=(m->parameter&0xFFFF)-getScreenY();
317     if (x<0 || y <0 || x>getWidth() || y>getHeight())
318     {
319       ViewMan::getInstance()->handleCommand(Remote::BACK); //simulate cancel press
320     }
321     else if (y>=(int)area.h-24 && y<=(int)area.h-6)
322     {
323       //y coordinate is right!
324       if (x>=7 &&x<=25)
325       {
326         ViewMan::getInstance()->handleCommand(Remote::RED); //simulate red press
327       }
328       else if (x>=110 &&x<=128)
329       {
330         ViewMan::getInstance()->handleCommand(Remote::GREEN); //simulate red press
331       }
332     }
333   }
334 }