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"
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", needDraw,this);
113 drawText(mediaError,20,area.h-10,Colour::LIGHTTEXT);
119 int VPicture::handleCommand(int command)
121 Timers::getInstance()->cancelTimer(this,1);
127 case Remote::SKIPBACK:
128 showPicture(VMediaList::MV_PREV);
129 BoxStack::getInstance()->update(this);
132 case Remote::FORWARD:
133 if (showtime > 1) showtime--;
136 case Remote::DF_DOWN:
138 case Remote::SKIPFORWARD:
139 showPicture(VMediaList::MV_NEXT);
140 BoxStack::getInstance()->update(this);
143 case Remote::REVERSE:
144 if (showtime < 50 ) showtime++;
160 showPicture(VMediaList::MV_NEXT);
161 BoxStack::getInstance()->update(this);
172 showtime=INITIAL_SHOWTIME;
179 rotate=WJpeg::ROT_90;
182 rotate=WJpeg::ROT_180;
185 rotate=WJpeg::ROT_270;
191 showPicture(VMediaList::MV_NONE,rotate);
192 BoxStack::getInstance()->update(this);
196 if (info) destroyInfo();
206 if (slideshow) startSlideshow();
207 // stop command getting to any more views
211 void VPicture::processMessage(Message* m)
213 if (m->message == Message::MOUSE_MOVE)
217 else if (m->message == Message::MOUSE_LBDOWN)
220 //check if press is outside this view! then simulate cancel
221 int x=(m->parameter>>16)-getScreenX();
222 int y=(m->parameter&0xFFFF)-getScreenY();
223 if (x<0 || y <0 || x>(int)getWidth() || y>(int)getHeight())
225 BoxStack::getInstance()->handleCommand(Remote::BACK); //simulate cancel press
230 VPicture * VPicture::createViewer(VMediaList * mparent, bool bslideshow) {
231 Log::getInstance()->log("VPicture::createViewer", Log::DEBUG, "p=%p",
233 VPicture *vmn=new VPicture(mparent);
234 BoxStack::getInstance()->add(vmn);
235 BoxStack::getInstance()->update(vmn);
237 if (bslideshow) vmn->startSlideshow();
239 BoxStack::getInstance()->update(vmn);
243 void VPicture::startSlideshow() {
245 Timers::getInstance()->setTimerD(this,1,showtime);
248 void VPicture::showPicture(ULONG move, int rt) {
250 currentMedia=parent->getMedia(MEDIA_TYPE_PICTURE,move);
252 if (mediaError || jpeg.hasError()) destroyInfo();
254 BoxStack::getInstance()->update(this);
258 int VPicture::load(Media *md) {
259 jpeg.init(NULL,false,NULL);
260 mediaError=tr("No media found");
263 const char *fname=md->getFileName();
265 int len=strlen(fname)+2+strlen(parent->getDirname());
270 fullname=new char[len];
271 sprintf(fullname,"%s/%s",parent->getDirname(),fname);
272 if (filename) delete filename;
274 filename=new char[len];
275 strcpy(filename,fname);
276 Log::getInstance()->log("VPicture::load", Log::DEBUG, "filename=%s,p=%p",
278 VDR* vdr=VDR::getInstance();
279 //do we have a banner?
280 bool haveBanner=banner!=NULL && ! shortBanner;
281 if (vdr->isConnected()) {
283 jpeg.init(fullname,false,reader);
284 jpeg.setRotate(rotate);
288 //only show the banner if it was there before
289 if (haveBanner) showBanner();
291 if(banner) destroyBanner();
293 Log::getInstance()->log("VPicture::load", Log::DEBUG, "success: filename=%s,p=%p",
298 mediaError=tr("no VDR connection");
303 void VPicture::showBanner(bool loading,int shortDisplay) {
304 //we are in the main thread - so we can (and must) safely hard destroy/create the banner
305 Timers::getInstance()->cancelTimer(this,2);
306 if (! filename || ! currentMedia) {
308 destroyBanner(!loading);
311 if (banner) destroyBanner(!loading);
312 banner= new VPictureBanner(this, loading, slideshow);
313 banner->fillColour(infoBack);
315 int len=strlen(filename)+Media::TIMEBUFLEN+20;
316 char *buf=new char[len];
317 char tbuf[Media::TIMEBUFLEN];
318 SNPRINTF(buf,len,"%c%02ds%c %s %s ",
322 currentMedia->getTimeString(tbuf),
324 banner->setText(buf);
328 banner->setText(filename);
331 if (shortDisplay != 0) shortBanner=true;
332 if (! slideshow && shortDisplay == 0) shortDisplay=8;
333 //OK we start timer if we don't load and either shortDisplay or no slideshow
334 if (! loading && shortDisplay != 0) Timers::getInstance()->setTimerD(this,2,shortDisplay);
335 BoxStack::getInstance()->add(banner);
336 BoxStack::getInstance()->update(banner);
340 void VPicture::destroyBanner(bool fromTimer) {
343 if (fromTimer) sendViewMsg(banner,true);
344 else BoxStack::getInstance()->remove(banner);
346 if (! fromTimer) Timers::getInstance()->cancelTimer(this,2);
349 void VPicture::updateBanner(bool shortDisplay) {
350 if (banner && ! shortBanner) {
353 else if (shortDisplay) {
357 void VPicture::timercall(int clientref) {
361 if (! slideshow) return;
362 Log::getInstance()->log("VPicture::timercall", Log::DEBUG, "slideshow");
363 sendCommandMsg(Remote::PLAY);
376 void VPicture::showInfo(){
377 if (info) destroyInfo();
378 if (! currentMedia) return;
381 info->setTitleText(currentMedia->getFileName());
382 info->setDropThrough();
383 info->setSize(500, 300);
384 info->createBuffer();
385 info->setBorderOn(1);
386 info->setTitleBarOn(1);
388 if (Video::getInstance()->getFormat() == Video::PAL)
389 info->setPosition(100, 180);
391 info->setPosition(100, 150);
393 char tbuf[Media::TIMEBUFLEN];
394 SNPRINTF(buf,INFOBUF,"%s= %s\n%s= %ld x %ld\n%s= %ld kBytes\n%s= %s\n%s= %ld\n%s= 1/%ld",
395 tr("Directory"), parent->getDirname(),
396 tr("Format(px)"),jpeg.getJpegInfo(WJpeg::JPEG_WIDTH),jpeg.getJpegInfo(WJpeg::JPEG_HEIGHT),
397 tr("Filesize"),jpeg.getJpegInfo(WJpeg::JPEG_SIZE)/1000,
398 tr("Time"),currentMedia->getTimeString(tbuf),
399 tr("Rotation"),90*jpeg.getJpegInfo(WJpeg::JPEG_ROTATE),
400 tr("Scale"),jpeg.getJpegInfo(WJpeg::JPEG_SCALE));
401 info->setMainText(buf);
403 sendViewMsg(info,false);
404 Timers::getInstance()->setTimerD(this,3,8);
406 void VPicture::updateInfo(){
411 void VPicture::destroyInfo(bool fromTimer){
413 sendViewMsg(info,true);
416 if (! fromTimer) Timers::getInstance()->cancelTimer(this,3);
419 void VPicture::sendViewMsg(Boxx *v,bool vdestroy) {
420 Message* m = new Message();
421 m->message = vdestroy?Message::CLOSE_ME:Message::ADD_VIEW;
422 m->to = BoxStack::getInstance();
424 m->parameter=(ULONG)v;
425 Command::getInstance()->postMessageFromOuterSpace(m);
427 void VPicture::sendCommandMsg(int command) {
428 Message* m = new Message();
429 m->message = Message::UDP_BUTTON;
430 m->to = Command::getInstance();
432 m->parameter=command;
433 Command::getInstance()->postMessageFromOuterSpace(m);