]> git.vomp.tv Git - vompclient.git/blob - vchannellist.cc
Fix text corruption in live TV OSD clock
[vompclient.git] / vchannellist.cc
1 /*
2     Copyright 2004-2007 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19 */
20
21 #include "vchannellist.h"
22
23 #include "input.h"
24 #include "wsymbol.h"
25 #include "vvideolivetv.h"
26 #include "colour.h"
27 #include "video.h"
28 #include "i18n.h"
29 #include "channel.h"
30 #include "message.h"
31 #include "boxstack.h"
32 #include "vchannelselect.h"
33 #include "staticartwork.h"
34
35 static const char* TAG = "VChannelList";
36
37 VChannelList::VChannelList(ULONG ttype)
38 {
39   boxstack = BoxStack::getInstance();
40   setSize(570, 420);
41   createBuffer();
42   if (Video::getInstance()->getFormat() == Video::PAL)
43   {
44     setPosition(80, 70);
45   }
46   else
47   {
48     setPosition(70, 35);
49   }
50
51   setTitleBarOn(1);
52
53   type = ttype;
54   if (type == VDR::VIDEO)
55   {
56     setTitleText(tr("Channels"));
57     TVMediaInfo *info= new TVMediaInfo();
58     info->setStaticArtwork(sa_tv);
59     setTitleBarIcon(info);
60   }
61   else if (type == VDR::RADIO)
62   {
63     setTitleText(tr("Radio Stations"));
64     TVMediaInfo *info= new TVMediaInfo();
65     info->setStaticArtwork(sa_radio);
66     setTitleBarIcon(info);
67   }
68
69   setTitleBarColour(DrawStyle::TITLEBARBACKGROUND);
70
71   sl.setPosition(10, 30 + 5);
72   sl.setSize(area.w - 20, area.h - 30 - 15 - 30);
73   add(&sl);
74   MessageQueue::getInstance()->addReceiver(this);
75 }
76
77 VChannelList::~VChannelList()
78 {
79   MessageQueue::getInstance()->removeReceiver(this);
80
81   if (chanList)
82   {
83     for (UINT i = 0; i < chanList->size(); i++)
84     {
85       delete (*chanList)[i];
86     }
87
88     chanList->clear();
89     delete chanList;
90   }
91 }
92
93 void VChannelList::setList(ChannelList* tlist)
94 {
95   char str[500];
96   OsdVector *osdv=dynamic_cast<OsdVector*>(Osd::getInstance());
97
98   sl.addColumn(0);
99   if (osdv) sl.addColumn(20);
100   sl.addColumn(60);
101
102   chanList = tlist;
103
104   Channel* chan;
105   int first = 1;
106   if (chanList)
107   {
108
109     for (UINT i = 0; i < chanList->size(); i++)
110     {
111       chan = (*chanList)[i];
112       sprintf(str, "%lu\t%s", chan->number, chan->name);
113       TVMediaInfo *info=NULL;
114       if (osdv) {
115           info= new TVMediaInfo();
116           info->setChannelLogo((*chanList)[i]->number);
117           if (type == VDR::VIDEO) info->setStaticFallback(sa_tv);
118           else info->setStaticFallback(sa_radio);
119       }
120       chan->index = sl.addOption(str, chan, first, info);
121       first = 0;
122     }
123   }
124 }
125
126 void VChannelList::highlightChannel(Channel* chan)
127 {
128   sl.hintSetCurrent(chan->index);
129   sl.draw();
130   doShowingBar();
131   boxstack->update(this);
132 }
133
134 void VChannelList::draw()
135 {
136   TBBoxx::draw();
137   sl.draw();
138
139   // Put the status stuff at the bottom
140
141   WSymbol w;
142   TEMPADD(&w);
143
144   w.nextSymbol = WSymbol::UP;
145   w.setPosition(20, 385);
146   w.draw();
147
148   w.nextSymbol = WSymbol::DOWN;
149   w.setPosition(50, 385);
150   w.draw();
151
152   w.nextSymbol = WSymbol::SKIPBACK;
153   w.setPosition(85, 385);
154   w.draw();
155
156   w.nextSymbol = WSymbol::SKIPFORWARD;
157   w.setPosition(115, 385);
158   w.draw();
159
160   w.nextSymbol = WSymbol::PLAY;
161   w.setPosition(150, 385);
162   w.draw();
163
164   doShowingBar();
165 }
166
167 void VChannelList::doShowingBar()
168 {
169   int topOption = sl.getTopOption() + 1;
170   if (sl.getNumOptions() == 0) topOption = 0;
171
172   rectangle(220, 385, 160, 25, DrawStyle::VIEWBACKGROUND);
173
174   char showing[200];
175   sprintf(showing, tr("%i to %i of %i"), topOption, sl.getBottomOption(), sl.getNumOptions());
176   drawText(showing, 220, 385, DrawStyle::LIGHTTEXT);
177
178   /*
179    * The following would work but the translation files need changing to {} instead of %i
180    * This is server side and so requires a server version bump breaking compatibility with older clients
181    * Maybe this will happen for v0.6 ?
182    *
183    * drawText(
184    * fmt::format(tr("%i to %i of %i"), topOption, sl.getBottomOption(), sl.getNumOptions()).c_str(),
185    * 220, 385, DrawStyle::LIGHTTEXT);
186    *
187    */
188 }
189
190 void VChannelList::quickUpdate() { //only quick for plattform that need it!
191 #ifdef GRADIENT_DRAWING
192       draw();
193 #else
194       sl.draw();
195       doShowingBar();
196 #endif
197 }
198
199 int VChannelList::handleCommand(int command)
200 {
201   switch(command)
202   {
203     case Input::UP:
204     {
205       sl.up();
206       quickUpdate();
207
208       boxstack->update(this);
209       return BoxStack::COMMAND_HANDLED;
210     }
211     case Input::DOWN:
212     {
213       sl.down();
214       quickUpdate();
215
216       boxstack->update(this);
217       return BoxStack::COMMAND_HANDLED;
218     }
219     case Input::SKIPBACK:
220     {
221       sl.pageUp();
222       quickUpdate();
223
224       boxstack->update(this);
225       return BoxStack::COMMAND_HANDLED;
226     }
227     case Input::SKIPFORWARD:
228     {
229       sl.pageDown();
230       quickUpdate();
231
232       boxstack->update(this);
233       return BoxStack::COMMAND_HANDLED;
234     }
235     case Input::ZERO:
236     case Input::ONE:
237     case Input::TWO:
238     case Input::THREE:
239     case Input::FOUR:
240     case Input::FIVE:
241     case Input::SIX:
242     case Input::SEVEN:
243     case Input::EIGHT:
244     case Input::NINE:
245     {
246       VChannelSelect* v = new VChannelSelect(this);
247       v->draw();
248       boxstack->add(v);
249       boxstack->update(v);
250       v->handleCommand(command);
251       return BoxStack::COMMAND_HANDLED;
252     }
253     case Input::OK:
254     case Input::PLAY:
255     {
256       Channel* chan = NULL;
257       if (chanList) chan = reinterpret_cast<Channel*>(sl.getCurrentOptionData());
258       if (chan == NULL) return 2;
259  
260       VVideoLiveTV* v = new VVideoLiveTV(chanList, chan->number, this);
261       boxstack->add(v);
262       v->go();
263
264       return BoxStack::COMMAND_HANDLED;
265     }
266     case Input::BACK:
267     {
268       return BoxStack::DELETE_ME;
269     }
270   }
271   // stop command getting to any more views
272   return BoxStack::ABANDON_COMMAND;
273 }
274
275 void VChannelList::processMessage(Message* m)
276 {
277  /* if (m->message == Message::MOUSE_MOVE) {
278         if (sl.mouseAndroidScroll((m->tag >> 16),(m->tag & 0xFFFF),
279                         (m->parameter >> 16),(m->parameter & 0xFFFF))) {
280                 sl.draw();
281                 doShowingBar();
282                 boxstack->update(this);
283         }
284   }
285   else */if (m->message == Message::MOUSE_MOVE)
286   {
287     if (sl.mouseMove(m->parameter - getScreenX(), m->tag - getScreenY()))
288     {
289       quickUpdate();
290       boxstack->update(this);
291     }
292   }
293   else if (m->message == Message::MOUSE_LBDOWN)
294   {
295     if (sl.mouseLBDOWN(m->parameter - getScreenX(), m->tag - getScreenY()))
296     {
297       Input::sendInputKey(Input::OK);
298     }
299     else if (coordsOutsideBox(m))
300     {
301       Input::sendInputKey(Input::BACK);
302     }
303   }
304   else if (m->message == Message::CHANNEL_CHANGE)
305   {
306     LogNT::getInstance()->debug(TAG, "Channel change {}", m->parameter);
307     Channel* chan = NULL;
308     for (UINT i = 0; i < chanList->size(); i++)
309     {
310       if ((*chanList)[i]->number == m->parameter)
311       {
312         chan = (*chanList)[i];
313         break;
314       }
315     }
316     if (!chan) return;
317
318 /*    if (chan->type == VDR::VIDEO)
319     {*/
320       VVideoLiveTV* v = new VVideoLiveTV(chanList, chan->number, this);
321       boxstack->add(v);
322       v->go();    
323 /*    }
324     else
325     {
326     
327       VVideoLive* v = new VVideoLive(chanList, chan->type, this);
328       v->draw();
329       boxstack->add(v);
330       boxstack->update(v);
331       v->channelChange(VVideoLive::NUMBER, chan->number);
332     
333     }*/
334   }
335 }