2 Copyright 2004-2005 Chris Tallon, Andreas Vogel
4 This file is part of VOMP.
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.
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.
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
25 #include "vpicturebanner.h"
28 #include "wselectlist.h"
34 #include "vvideolive.h"
41 Colour VPicture::pictureBack=Colour(140,140,140);
42 Colour VPicture::infoBack=Colour(110,110,110);
45 class VPreader : public JpegReader {
49 VPreader(VPicture *p){
51 virtual ULONG readChunk(ULONG offset,ULONG len,char ** buf) {
52 Log::getInstance()->log("VPicture::jpegReader", Log::DEBUG, "read chunk o=%d,len=%d,buf=%p",
55 *buf=(char *)VDR::getInstance()->getImageBlock(offset,(UINT)len,&numrec);
56 Log::getInstance()->log("VPicture::jpegReader", Log::DEBUG, "got n=%d,buf=%p",
60 virtual ULONG initRead(const char *filename) {
61 Log::getInstance()->log("VPicture::jpegReader", Log::DEBUG, "load image %s",filename);
62 Video* video = Video::getInstance();
63 ULONG size=VDR::getInstance()->loadImage(filename,video->getScreenWidth(), video->getScreenHeight());
64 Log::getInstance()->log("VPicture::jpegReader", Log::DEBUG, "load image %s returned %d",filename,size);
69 VPicture::VPicture(VMediaList *p)
72 reader=new VPreader(this);
74 Video* video = Video::getInstance();
75 setSize(video->getScreenWidth(), video->getScreenHeight());
77 jpeg.setSurface(surface);
78 jpeg.setDimensions(area.w,area.h);
84 showtime=INITIAL_SHOWTIME;
90 jpeg.setBackgroundColour(pictureBack);
97 if (banner) BoxStack::getInstance()->remove(banner);
98 if (fullname) delete fullname;
99 if (filename) delete filename;
100 Timers::getInstance()->cancelTimer(this,1);
101 Timers::getInstance()->cancelTimer(this,2);
102 Timers::getInstance()->cancelTimer(this,3);
107 void VPicture::draw()
109 Log::getInstance()->log("VPicture::draw", Log::DEBUG, "needDraw=%d,p=%p",
113 drawText(mediaError,20,area.h-10,Colour::LIGHTTEXT);
122 int VPicture::handleCommand(int command)
124 Timers::getInstance()->cancelTimer(this,1);
130 case Remote::SKIPBACK:
131 showPicture(VMediaList::MV_PREV);
132 BoxStack::getInstance()->update(this);
135 case Remote::FORWARD:
136 if (showtime > 1) showtime--;
139 case Remote::DF_DOWN:
141 case Remote::SKIPFORWARD:
142 showPicture(VMediaList::MV_NEXT);
143 BoxStack::getInstance()->update(this);
146 case Remote::REVERSE:
147 if (showtime < 50 ) showtime++;
163 showPicture(VMediaList::MV_NEXT);
164 BoxStack::getInstance()->update(this);
175 showtime=INITIAL_SHOWTIME;
182 rotate=WJpeg::ROT_90;
185 rotate=WJpeg::ROT_180;
188 rotate=WJpeg::ROT_270;
194 showPicture(VMediaList::MV_NONE,rotate);
195 BoxStack::getInstance()->update(this);
199 if (info) destroyInfo();
209 if (slideshow) startSlideshow();
210 // stop command getting to any more views
214 void VPicture::processMessage(Message* m)
216 if (m->message == Message::MOUSE_MOVE)
220 else if (m->message == Message::MOUSE_LBDOWN)
223 //check if press is outside this view! then simulate cancel
224 int x=(m->parameter>>16)-getScreenX();
225 int y=(m->parameter&0xFFFF)-getScreenY();
226 if (x<0 || y <0 || x>(int)getWidth() || y>(int)getHeight())
228 BoxStack::getInstance()->handleCommand(Remote::BACK); //simulate cancel press
233 VPicture * VPicture::createViewer(VMediaList * mparent, bool bslideshow) {
234 Log::getInstance()->log("VPicture::createViewer", Log::DEBUG, "p=%p",
236 VPicture *vmn=new VPicture(mparent);
237 BoxStack::getInstance()->add(vmn);
238 BoxStack::getInstance()->update(vmn);
240 if (bslideshow) vmn->startSlideshow();
242 BoxStack::getInstance()->update(vmn);
246 void VPicture::startSlideshow() {
248 Timers::getInstance()->setTimerD(this,1,showtime);
251 void VPicture::showPicture(ULONG move, int rt) {
253 currentMedia=parent->getMedia(MEDIA_TYPE_PICTURE,move);
255 if (mediaError || jpeg.hasError()) destroyInfo();
257 BoxStack::getInstance()->update(this);
261 int VPicture::load(Media *md) {
262 jpeg.init(NULL,false,NULL);
263 mediaError=tr("No media found");
266 const char *fname=md->getFileName();
268 int len=strlen(fname)+2+strlen(parent->getDirname());
273 fullname=new char[len];
274 sprintf(fullname,"%s/%s",parent->getDirname(),fname);
275 if (filename) delete filename;
277 filename=new char[len];
278 strcpy(filename,fname);
279 Log::getInstance()->log("VPicture::load", Log::DEBUG, "filename=%s,p=%p",
281 VDR* vdr=VDR::getInstance();
282 //do we have a banner?
283 bool haveBanner=banner!=NULL && ! shortBanner;
284 if (vdr->isConnected()) {
286 jpeg.init(fullname,false,reader);
287 jpeg.setRotate(rotate);
291 //only show the banner if it was there before
292 if (haveBanner) showBanner();
294 if(banner) destroyBanner();
296 Log::getInstance()->log("VPicture::load", Log::DEBUG, "success: filename=%s,p=%p",
301 mediaError=tr("no VDR connection");
306 void VPicture::showBanner(bool loading,int shortDisplay) {
307 //if the loading flag is set,
308 //we are in the main thread - so we can (and must) safely hard destroy/create the banner
309 Timers::getInstance()->cancelTimer(this,2);
310 if (! filename || ! currentMedia) {
312 destroyBanner(!loading);
315 if (banner) destroyBanner(!loading);
316 banner= new VPictureBanner(this, loading, slideshow);
317 banner->fillColour(infoBack);
319 int len=strlen(filename)+Media::TIMEBUFLEN+20;
321 char tbuf[Media::TIMEBUFLEN];
322 snprintf(buf,len,"%c%02ds%c %s %s ",
326 currentMedia->getTimeString(tbuf),
328 banner->setText(buf);
331 banner->setText(filename);
334 if (shortDisplay != 0) shortBanner=true;
335 if (! slideshow && shortDisplay == 0) shortDisplay=8;
336 //OK we start timer if we don't load and either shortDisplay or no slideshow
337 if (! loading && shortDisplay != 0) Timers::getInstance()->setTimerD(this,2,shortDisplay);
338 if (! loading) ; /*sendViewMsg(banner,false); upgrade to boxx */
340 BoxStack::getInstance()->add(banner);
341 BoxStack::getInstance()->update(banner);
346 void VPicture::destroyBanner(bool fromTimer) {
349 if (fromTimer) ;/* sendViewMsg(banner,true); upgrade to boxx*/
350 else BoxStack::getInstance()->remove(banner);
352 if (! fromTimer) Timers::getInstance()->cancelTimer(this,2);
355 void VPicture::updateBanner(bool shortDisplay) {
356 if (banner && ! shortBanner) {
359 else if (shortDisplay) {
363 void VPicture::timercall(int clientref) {
367 if (! slideshow) return;
368 Log::getInstance()->log("VPicture::timercall", Log::DEBUG, "slideshow");
369 sendCommandMsg(Remote::PLAY);
382 void VPicture::showInfo(){
383 if (info) destroyInfo();
384 if (! currentMedia) return;
387 info->setTitleText(currentMedia->getFileName());
388 info->setDropThrough();
389 info->setSize(500, 300);
390 info->createBuffer();
391 info->setBorderOn(1);
392 info->setTitleBarOn(1);
394 if (Video::getInstance()->getFormat() == Video::PAL)
395 info->setPosition(100, 180);
397 info->setPosition(100, 150);
399 char tbuf[Media::TIMEBUFLEN];
400 snprintf(buf,INFOBUF,"%s= %s\n%s= %ld x %ld\n%s= %ld kBytes\n%s= %s\n%s= %ld\n%s= 1/%ld",
401 tr("Directory"), parent->getDirname(),
402 tr("Format(px)"),jpeg.getJpegInfo(WJpeg::JPEG_WIDTH),jpeg.getJpegInfo(WJpeg::JPEG_HEIGHT),
403 tr("Filesize"),jpeg.getJpegInfo(WJpeg::JPEG_SIZE)/1000,
404 tr("Time"),currentMedia->getTimeString(tbuf),
405 tr("Rotation"),90*jpeg.getJpegInfo(WJpeg::JPEG_ROTATE),
406 tr("Scale"),jpeg.getJpegInfo(WJpeg::JPEG_SCALE));
407 info->setMainText(buf);
409 sendViewMsg(info,false);
410 Timers::getInstance()->setTimerD(this,3,8);
412 void VPicture::updateInfo(){
417 void VPicture::destroyInfo(bool fromTimer){
419 sendViewMsg(info,true);
422 if (! fromTimer) Timers::getInstance()->cancelTimer(this,3);
425 void VPicture::sendViewMsg(Boxx *v,bool vdestroy) {
426 Message* m = new Message();
427 m->message = vdestroy?Message::CLOSE_ME:Message::ADD_VIEW;
428 m->to = BoxStack::getInstance();
430 m->parameter=(ULONG)v;
431 Command::getInstance()->postMessageFromOuterSpace(m);
433 void VPicture::sendCommandMsg(int command) {
434 Message* m = new Message();
435 m->message = Message::UDP_BUTTON;
436 m->to = Command::getInstance();
438 m->parameter=command;
439 Command::getInstance()->postMessageFromOuterSpace(m);