]> git.vomp.tv Git - vompclient.git/blob - vrecording.cc
Rework master loop
[vompclient.git] / vrecording.cc
1 /*
2     Copyright 2004-2019 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, see <https://www.gnu.org/licenses/>.
18 */
19
20 #include "vrecording.h"
21
22 #include "remote.h"
23 #include "recinfo.h"
24 #include "vquestion.h"
25 #include "vinfo.h"
26 #include "vdr.h"
27 #include "colour.h"
28 #include "video.h"
29 #include "i18n.h"
30 #include "messagequeue.h"
31 #include "vrecmove.h"
32 #include "boxstack.h"
33 #include "recman.h"
34 #include "vrecordinglist.h"
35 #include "recording.h"
36 #include "message.h"
37 #include "log.h"
38 #include "wmovieview.h"
39 #include "wseriesview.h"
40 #include "wpictureview.h"
41
42 VRecording::VRecording(RecMan* trecman, Recording* trec)
43 {
44   rec = trec;
45   recman = trecman;
46   buttons = true;
47   selected = RESUME;
48   
49   Log::getInstance()->log("VRecording", Log::DEBUG, "%s", rec->getProgName());
50   rec->loadRecInfo();
51   Log::getInstance()->log("VRecording", Log::DEBUG, "%s", rec->getProgName());
52
53
54   if (Video::getInstance()->getFormat() == Video::PAL)
55   {
56     setSize(640, 500);
57         createBuffer();
58   }
59   else
60   {
61         setSize(560, 400);
62         createBuffer();
63   }
64   setPosition(40, 40);
65
66   setTitleBarOn(1);
67   setBorderOn(1);
68   if (rec->recInfo && strlen(rec->recInfo->title))
69           setTitleText(rec->recInfo->title);
70   else
71           setTitleText(rec->getProgName());
72   setTitleBarColour(DrawStyle::TITLEBARBACKGROUND);
73
74   tabbar.setPosition(10+130+10, 30 + 5);
75   tabbar.setSize(area.w - 20-10-130, area.h - 30 - 10);
76   add(&tabbar);
77
78
79
80   epgSummaryTextBox = new WTextbox();
81
82   epgSummaryTextBox->setParaMode(true);
83
84   if (rec->recInfo)
85     epgSummaryTextBox->setText(rec->recInfo->buildSummaryWithDetails());
86   else
87     epgSummaryTextBox->setText(tr("Summary unavailable"));
88
89   OsdVector *osdv=dynamic_cast<OsdVector*>(Osd::getInstance());
90
91   tabbar.addTab(tr("EPG"), epgSummaryTextBox);
92   if (rec->movieInfo) {
93           WMovieView *movieview = new WMovieView(rec->movieInfo);
94           movieview->setParaMode(true);
95           tabbar.addTab(tr("TheTVDB Info"), movieview);
96           if (osdv) {
97                   if (rec->movieInfo->actors.size() > 0 && osdv)
98                   {
99                           WActorGallery *gallery= new WActorGallery(rec->movieInfo->actors);
100                           tabbar.addTab(tr("Cast"),gallery);
101                   }
102                   WArtworkGallery *artgallery= new WArtworkGallery(*rec->movieInfo);
103                   tabbar.addTab(tr("Gallery"),artgallery);
104           }
105   } else if (rec->seriesInfo) {
106           WSeriesView *seriesview = new WSeriesView(rec->seriesInfo);
107           seriesview->setParaMode(true);
108           tabbar.addTab(tr("TheTVDB Info"), seriesview);
109           if (osdv) {
110                   if (rec->seriesInfo->actors.size() > 0 && osdv)
111                   {
112                           WActorGallery *gallery= new WActorGallery(rec->seriesInfo->actors);
113                           tabbar.addTab(tr("Cast"),gallery);
114                   }
115                   WArtworkGallery *artgallery= new WArtworkGallery(*rec->seriesInfo);
116                   tabbar.addTab(tr("Gallery"),artgallery);
117           }
118
119   }
120
121
122   
123   int sfh = getFontHeight();
124   buttonRegion.x = 10;
125   buttonRegion.y = 10+30;
126   buttonRegion.w = 130;
127   buttonRegion.h = sfh*2*last;
128
129   button[PLAY].setText(tr("Play"));
130   button[RESUME].setText(tr("Resume"));
131   button[MARKASNEW].setText(tr("Mark as new"));
132   button[MOVE].setText(tr("Move"));
133   button[A_DELETE].setText(tr("Delete"));
134   
135   for (int i=PLAY, ver=10+30; i<last; i++, ver+= sfh*2)
136   {
137     button[i].setPosition(10, ver);
138     button[i].setSize(130, sfh);
139     add(&button[i]);
140   }
141   
142
143   button[selected].setActive(1);
144   tabbar.activateFocus(false);
145 }
146
147 VRecording::~VRecording()
148 {
149 }
150
151 void VRecording::setParent(VRecordingList* tvRecList)
152 {
153   vRecList = tvRecList;
154 }
155
156 void VRecording::draw()
157 {
158   TBBoxx::draw();
159   OsdVector *osdv=dynamic_cast<OsdVector*>(Osd::getInstance());
160   if (osdv) {
161           TVMedia poster;
162           if (rec->movieInfo) {
163                   poster=rec->movieInfo->poster;
164           }
165           if (rec->seriesInfo) {
166                   if (rec->seriesInfo->seasonposter.height) {
167                           poster=rec->seriesInfo->seasonposter;
168                   }
169                   else
170                   if (rec->seriesInfo->posters.size()) {
171                           poster=rec->seriesInfo->posters[0];
172                   }
173           }
174           if (poster.height) {
175                  // float aspect=((float)poster.height)/((float)poster.width)/Osd::getInstance()->getPixelAspect();
176                   drawTVMedia(poster.info,buttonRegion.x,
177                                          tabbar.getY2()-3,
178                                                 buttonRegion.w,/*buttonRegion.w*aspect*/0.f,BottomLeft);
179           }
180   }
181
182 }
183
184 int VRecording::handleCommand(int command)
185 {
186         if (command==Remote::BACK) {
187                 return 4;
188         }
189         if (buttons) {
190                 switch(command)
191                 {
192                 case Remote::DF_UP:
193                 case Remote::UP:
194                 {
195                         tabbar.activateFocus(false);
196                         moveCursor(LEFT);
197                         return 2;
198                 }
199
200                 case Remote::DF_DOWN:
201                 case Remote::DOWN:
202                 {
203                         tabbar.activateFocus(false);
204                         moveCursor(RIGHT);
205                         return 2;
206                 }
207                 case Remote::LEFT:
208                 case Remote::DF_LEFT:
209                 case Remote::RIGHT:
210                 case Remote::DF_RIGHT:
211                 {
212                         buttons = false;
213                         button[selected].setActive(0);
214                         tabbar.activateFocus(true);
215                         button[selected].draw();
216                         tabbar.draw();
217                         BoxStack::getInstance()->update(this);
218                         return 2;
219                 }
220                 case Remote::OK:
221                 {
222
223                         if (selected == PLAY)
224                         {
225                                 Message* m = new Message(); // Must be done after this view deleted
226                                 m->from = this;
227                                 m->to = vRecList;
228                                 m->message = Message::PLAY_SELECTED_RECORDING;
229                                 MessageQueue::getInstance()->postMessage(m);
230                                 return 4;
231                         }
232
233                         if (selected == RESUME)
234                         {
235                                 Message* m = new Message(); // Must be done after this view deleted
236                                 m->from = this;
237                                 m->to = vRecList;
238                                 m->message = Message::RESUME_SELECTED_RECORDING;
239                                 MessageQueue::getInstance()->postMessage(m);
240                                 return 4;
241                         }
242
243                         if (selected == MARKASNEW)
244             {
245               int ret = rec->resetResume();
246
247               VInfo* vi = new VInfo();
248               vi->setSize(400, 150);
249               vi->createBuffer();
250               vi->setExitable();
251               vi->setBorderOn(1);
252               vi->setTitleBarOn(0);
253
254               if (Video::getInstance()->getFormat() == Video::PAL)
255               vi->setPosition(170, 200);
256               else
257               vi->setPosition(160, 150);
258
259               if (ret == 1) vi->setOneLiner(tr("Success"));
260               else if (ret == 2) vi->setOneLiner(tr("No resume point exists"));
261               else if (ret == 4) vi->setOneLiner(tr("Failure deleting resume point"));
262               else if (ret == 5) vi->setOneLiner(tr("Not supported with VDR < 2.4.0"));
263               vi->draw();
264
265               Message* m = new Message();
266               m->message = Message::ADD_VIEW;
267               m->to = BoxStack::getInstance();
268               m->parameter = (ULONG)vi;
269               MessageQueue::getInstance()->postMessage(m);
270
271               if (ret == 1)
272               {
273                 // Change Resume at text in summary
274                 rec->recInfo->resumePoint = 0;
275                 epgSummaryTextBox->setText(rec->recInfo->buildSummaryWithDetails(true));
276                 draw();
277                 BoxStack::getInstance()->update(this);
278
279                 // Update vrecordingslist to remove the * for new
280                 rec->setNew(true);
281                 Message* m2 = new Message();
282                 m2->from = this;
283                 m2->to = vRecList;
284                 m2->message = Message::REDRAW;
285                 MessageQueue::getInstance()->postMessage(m2);
286               }
287
288               return 2;
289             }
290
291                         if (selected == MOVE)
292                         {
293                                 VRecMove* vrm = new VRecMove(recman);
294                                 vrm->setParent(this);
295                                 vrm->draw();
296                                 BoxStack::getInstance()->add(vrm);
297                                 BoxStack::getInstance()->update(vrm);
298                                 return 2;
299                         }
300
301                         if (selected == A_DELETE)
302                         {
303                                 VQuestion* v = new VQuestion(this);
304                                 v->setSize(260, 180);
305                                 v->createBuffer();
306                                 v->setTitleBarColour(DrawStyle::DANGER);
307                                 v->setTitleBarOn(1);
308                                 v->setBorderOn(1);
309                                 v->setTitleText(tr("Delete recording"));
310                                 v->setMainText(tr("Are you sure you want to delete this recording?"));
311                                 v->setDefault(VQuestion::NO);
312                                 if (Video::getInstance()->getFormat() == Video::PAL)
313                                 {
314                                         v->setPosition(230, 160);
315                                 }
316                                 else
317                                 {
318                                         v->setPosition(220, 140);
319                                 }
320
321                                 v->draw();
322                                 BoxStack::getInstance()->add(v);
323                                 BoxStack::getInstance()->update(v);
324                                 return 2;
325                         }
326                 }
327                 }
328         } else {
329                 // Pass to tabbar
330                 int retval = tabbar.handleCommand(command);
331                 if (retval == 1)
332                 {
333                         BoxStack::getInstance()->update(this);
334                         return 2;
335                 }
336                 else if (retval == 2)
337                 {
338                         // command was taken and actively ignored
339                         if (command==Remote::LEFT || command==Remote::DF_LEFT
340                                         || command==Remote::RIGHT || command==Remote::DF_RIGHT)
341                         {
342                                 buttons=true;
343                                 button[selected].setActive(1);
344                                 tabbar.activateFocus(false);
345                                 button[selected].draw();
346                                 tabbar.draw();
347                                 BoxStack::getInstance()->update(this);
348                         }
349                         return 2;
350                 }
351         }
352
353
354         // stop command getting to any more views
355         return 1;
356 }
357
358 void VRecording::moveCursor(Direction direction)
359 {
360   button[selected].setActive(0);
361   button[selected].draw();
362   if (direction == RIGHT)
363   { 
364     if (++selected == last) selected = PLAY;
365   }
366   else
367   {
368     if (--selected < 0) selected = last - 1;
369   }
370   button[selected].setActive(1);
371   button[selected].draw();
372   BoxStack::getInstance()->update(this, &buttonRegion);
373 }
374
375 void VRecording::processMessage(Message* m)
376 {
377   if (m->message == Message::MOUSE_MOVE)
378   {
379     for (int i = PLAY; i < last; i++)
380     {
381           if (button[i].mouseMove((m->parameter >> 16) - getScreenX(), (m->parameter & 0xFFFF) - getScreenY()))
382       {
383         for (int j = PLAY; j < last; j++)
384           button[j].setActive(0);
385         button[i].setActive(1);
386                 tabbar.activateFocus(false);
387                 buttons = true;
388         selected=i;
389         draw();
390         BoxStack::getInstance()->update(this);
391         break;
392       }
393     }
394         if (tabbar.mouseMove((m->parameter >> 16) - getScreenX(), (m->parameter & 0xFFFF) - getScreenY()))
395         {
396                 BoxStack::getInstance()->update(this);
397                 return;
398         }
399   }
400   else if (m->message == Message::MOUSE_SCROLL)
401   {
402           if (tabbar.mouseAndroidScroll((m->tag >> 16) - getScreenX(), (m->tag & 0xFFFF) - getScreenY(),
403                   (short)(m->parameter >> 16), (short) (m->parameter & 0xFFFF)))
404           {
405                   BoxStack::getInstance()->update(this);
406                   return;
407           }
408   }
409   else if (m->message == Message::MOUSE_LBDOWN)
410   {
411     int cancel = true;
412     for (int i = PLAY; i < last; i++)
413     {
414       if (button[i].mouseLBDOWN((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY()))
415       {
416         BoxStack::getInstance()->handleCommand(Remote::OK); //simulate OK press
417                 buttons = true;
418         cancel = false;
419         break;
420       }
421     }
422         if (cancel && tabbar.mouseLBDOWN((m->parameter >> 16) - getScreenX(), (m->parameter & 0xFFFF) - getScreenY()))
423         {
424                 buttons = false;
425                 button[selected].setActive(0);
426
427                 BoxStack::getInstance()->update(this);
428                 cancel = false;
429         }
430     if (cancel)
431     {
432       //check if press is outside this view! then simulate cancel
433       int x=(m->parameter>>16)-getScreenX();
434       int y=(m->parameter&0xFFFF)-getScreenY();
435       if (x<0 || y <0 || x>(int)getWidth() || y>(int)getHeight())
436       {
437         BoxStack::getInstance()->handleCommand(Remote::BACK); //simulate cancel press
438       }
439     }
440   }
441   else if (m->message == Message::QUESTION_YES)
442   {
443     if (selected == A_DELETE)
444     {
445       Message* m2 = new Message(); // Delete self
446       m2->from = this;
447       m2->to = BoxStack::getInstance();
448       m2->message = Message::CLOSE_ME;
449       MessageQueue::getInstance()->postMessage(m2);
450
451       m2 = new Message(); // OK. Want this to delete before this message does its job
452       m2->from = this;
453       m2->to = vRecList;
454       m2->message = Message::DELETE_SELECTED_RECORDING;
455       MessageQueue::getInstance()->postMessage(m2);
456     }
457   }
458   else if (m->message == Message::MOVE_RECORDING)
459   {
460     Message* m2 = new Message(); // Delete self
461     m2->from = this;
462     m2->to = BoxStack::getInstance();
463     m2->message = Message::CLOSE_ME;
464     MessageQueue::getInstance()->postMessage(m2);
465
466     m2 = new Message();
467     m2->from = this;
468     m2->to = vRecList;
469     m2->message = Message::MOVE_RECORDING;
470     m2->parameter = m->parameter;
471     MessageQueue::getInstance()->postMessage(m2);
472   }
473 }
474