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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
25 #include "vpicturebanner.h"
28 #include "wselectlist.h"
40 Colour VPicture::pictureBack=Colour(140,140,140);
41 Colour VPicture::infoBack=Colour(110,110,110);
44 class VPreader : public JpegReader {
48 VPreader(VPicture *p){
50 virtual ULONG readChunk(ULONG offset,ULONG len,char ** buf) {
51 Log::getInstance()->log("VPicture::jpegReader", Log::DEBUG, "read chunk o=%d,len=%d,buf=%p",
54 *buf=(char *)VDR::getInstance()->getImageBlock(offset,(UINT)len,&numrec);
55 Log::getInstance()->log("VPicture::jpegReader", Log::DEBUG, "got n=%d,buf=%p",
59 virtual ULONG initRead(const char *filename) {
60 Log::getInstance()->log("VPicture::jpegReader", Log::DEBUG, "load image %s",filename);
61 Video* video = Video::getInstance();
62 ULONG size=VDR::getInstance()->loadImage(filename,video->getScreenWidth(), video->getScreenHeight());
63 Log::getInstance()->log("VPicture::jpegReader", Log::DEBUG, "load image %s returned %d",filename,size);
68 VPicture::VPicture(VMediaList *p)
71 reader=new VPreader(this);
73 Video* video = Video::getInstance();
74 setSize(video->getScreenWidth(), video->getScreenHeight());
76 // jpeg.setSurface(surface);
77 jpeg.setDimensions(area.w,area.h);
83 showtime=INITIAL_SHOWTIME;
89 jpeg.setBackgroundColour(pictureBack);
93 void VPicture::preDelete()
95 Timers::getInstance()->cancelTimer(this,1);
96 Timers::getInstance()->cancelTimer(this,2);
97 Timers::getInstance()->cancelTimer(this,3);
100 VPicture::~VPicture()
103 if (banner) BoxStack::getInstance()->remove(banner);
104 if (fullname) delete fullname;
105 if (filename) delete filename;
111 void VPicture::draw()
113 Log::getInstance()->log("VPicture::draw", Log::DEBUG, "needDraw=%d,p=%p", needDraw,this);
117 drawText(mediaError,20,area.h-10,Colour::LIGHTTEXT);
123 int VPicture::handleCommand(int command)
125 Timers::getInstance()->cancelTimer(this,1);
131 case Remote::SKIPBACK:
132 showPicture(VMediaList::MV_PREV);
133 BoxStack::getInstance()->update(this);
136 case Remote::FORWARD:
137 if (showtime > 1) showtime--;
140 case Remote::DF_DOWN:
142 case Remote::SKIPFORWARD:
143 showPicture(VMediaList::MV_NEXT);
144 BoxStack::getInstance()->update(this);
147 case Remote::REVERSE:
148 if (showtime < 50 ) showtime++;
164 showPicture(VMediaList::MV_NEXT);
165 BoxStack::getInstance()->update(this);
176 showtime=INITIAL_SHOWTIME;
183 rotate=WJpeg::ROT_90;
186 rotate=WJpeg::ROT_180;
189 rotate=WJpeg::ROT_270;
195 showPicture(VMediaList::MV_NONE,rotate);
196 BoxStack::getInstance()->update(this);
200 if (info) destroyInfo();
211 if (slideshow) startSlideshow();
212 // stop command getting to any more views
216 void VPicture::processMessage(Message* m)
218 if (m->message == Message::MOUSE_MOVE)
222 else if (m->message == Message::MOUSE_LBDOWN)
225 //check if press is outside this view! then simulate cancel
226 int x=(m->parameter>>16)-getScreenX();
227 int y=(m->parameter&0xFFFF)-getScreenY();
228 if (x<0 || y <0 || x>(int)getWidth() || y>(int)getHeight())
230 BoxStack::getInstance()->handleCommand(Remote::BACK); //simulate cancel press
235 VPicture * VPicture::createViewer(VMediaList * mparent, bool bslideshow) {
236 Log::getInstance()->log("VPicture::createViewer", Log::DEBUG, "p=%p",
238 VPicture *vmn=new VPicture(mparent);
239 BoxStack::getInstance()->add(vmn);
240 BoxStack::getInstance()->update(vmn);
242 if (bslideshow) vmn->startSlideshow();
244 BoxStack::getInstance()->update(vmn);
248 void VPicture::startSlideshow() {
250 Timers::getInstance()->setTimerD(this,1,showtime);
253 void VPicture::showPicture(ULONG move, int rt) {
255 currentMedia=parent->getMedia(MEDIA_TYPE_PICTURE,move);
257 if (mediaError || jpeg.hasError()) destroyInfo();
259 BoxStack::getInstance()->update(this);
263 int VPicture::load(Media *md) {
264 jpeg.init(NULL,false,NULL);
265 mediaError=tr("No media found");
268 const char *fname=md->getFileName();
270 int len=strlen(fname)+2+strlen(parent->getDirname());
275 fullname=new char[len];
276 sprintf(fullname,"%s/%s",parent->getDirname(),fname);
277 if (filename) delete filename;
279 filename=new char[len];
280 strcpy(filename,fname);
281 Log::getInstance()->log("VPicture::load", Log::DEBUG, "filename=%s,p=%p",
283 VDR* vdr=VDR::getInstance();
284 //do we have a banner?
285 bool haveBanner=banner!=NULL && ! shortBanner;
286 if (vdr->isConnected()) {
288 jpeg.init(fullname,false,reader);
289 jpeg.setRotate(rotate);
293 //only show the banner if it was there before
294 if (haveBanner) showBanner();
296 if(banner) destroyBanner();
298 Log::getInstance()->log("VPicture::load", Log::DEBUG, "success: filename=%s,p=%p",
303 mediaError=tr("no VDR connection");
308 void VPicture::showBanner(bool loading,int shortDisplay) {
309 //we are in the main thread - so we can (and must) safely hard destroy/create the banner
310 Timers::getInstance()->cancelTimer(this,2);
311 if (! filename || ! currentMedia) {
313 destroyBanner(!loading);
316 if (banner) destroyBanner(!loading);
317 banner= new VPictureBanner(this, loading, slideshow);
318 banner->fillColour(infoBack);
320 int len=strlen(filename)+Media::TIMEBUFLEN+20;
321 char *buf=new char[len];
322 char tbuf[Media::TIMEBUFLEN];
323 SNPRINTF(buf,len,"%c%02ds%c %s %s ",
327 currentMedia->getTimeString(tbuf),
329 banner->setText(buf);
333 banner->setText(filename);
336 if (shortDisplay != 0) shortBanner=true;
337 if (! slideshow && shortDisplay == 0) shortDisplay=8;
338 //OK we start timer if we don't load and either shortDisplay or no slideshow
339 if (! loading && shortDisplay != 0) Timers::getInstance()->setTimerD(this,2,shortDisplay);
340 BoxStack::getInstance()->add(banner);
341 BoxStack::getInstance()->update(banner);
345 void VPicture::destroyBanner(bool fromTimer) {
348 if (fromTimer) sendViewMsg(banner,true);
349 else BoxStack::getInstance()->remove(banner);
351 if (! fromTimer) Timers::getInstance()->cancelTimer(this,2);
354 void VPicture::updateBanner(bool shortDisplay) {
355 if (banner && ! shortBanner) {
358 else if (shortDisplay) {
362 void VPicture::timercall(int clientref) {
366 if (! slideshow) return;
367 Log::getInstance()->log("VPicture::timercall", Log::DEBUG, "slideshow");
368 sendCommandMsg(Remote::PLAY);
381 void VPicture::showInfo(){
382 if (info) destroyInfo();
383 if (! currentMedia) return;
386 info->setTitleText(currentMedia->getFileName());
387 info->setDropThrough();
388 info->setSize(500, 300);
389 info->createBuffer();
390 info->setBorderOn(1);
391 info->setTitleBarOn(1);
393 if (Video::getInstance()->getFormat() == Video::PAL)
394 info->setPosition(100, 180);
396 info->setPosition(100, 150);
398 char tbuf[Media::TIMEBUFLEN];
399 SNPRINTF(buf,INFOBUF,"%s= %s\n%s= %ld x %ld\n%s= %ld kBytes\n%s= %s\n%s= %ld\n%s= 1/%ld",
400 tr("Directory"), parent->getDirname(),
401 tr("Format(px)"),jpeg.getJpegInfo(WJpeg::JPEG_WIDTH),jpeg.getJpegInfo(WJpeg::JPEG_HEIGHT),
402 tr("Filesize"),jpeg.getJpegInfo(WJpeg::JPEG_SIZE)/1000,
403 tr("Time"),currentMedia->getTimeString(tbuf),
404 tr("Rotation"),90*jpeg.getJpegInfo(WJpeg::JPEG_ROTATE),
405 tr("Scale"),jpeg.getJpegInfo(WJpeg::JPEG_SCALE));
406 info->setMainText(buf);
408 sendViewMsg(info,false);
409 Timers::getInstance()->setTimerD(this,3,8);
411 void VPicture::updateInfo(){
416 void VPicture::destroyInfo(bool fromTimer){
418 sendViewMsg(info,true);
421 if (! fromTimer) Timers::getInstance()->cancelTimer(this,3);
424 void VPicture::sendViewMsg(Boxx *v,bool vdestroy) {
425 Message* m = new Message();
426 m->message = vdestroy?Message::CLOSE_ME:Message::ADD_VIEW;
427 m->to = BoxStack::getInstance();
429 m->parameter=(ULONG)v;
430 Command::getInstance()->postMessageFromOuterSpace(m);
432 void VPicture::sendCommandMsg(int command) {
433 Message* m = new Message();
434 m->message = Message::UDP_BUTTON;
435 m->to = Command::getInstance();
437 m->parameter=command;
438 Command::getInstance()->postMessageFromOuterSpace(m);