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);
96 if (banner) BoxStack::getInstance()->remove(banner);
97 if (fullname) delete fullname;
98 if (filename) delete filename;
99 Timers::getInstance()->cancelTimer(this,1);
100 Timers::getInstance()->cancelTimer(this,2);
101 Timers::getInstance()->cancelTimer(this,3);
106 void VPicture::draw()
108 Log::getInstance()->log("VPicture::draw", Log::DEBUG, "needDraw=%d,p=%p", needDraw,this);
112 drawText(mediaError,20,area.h-10,Colour::LIGHTTEXT);
118 int VPicture::handleCommand(int command)
120 Timers::getInstance()->cancelTimer(this,1);
126 case Remote::SKIPBACK:
127 showPicture(VMediaList::MV_PREV);
128 BoxStack::getInstance()->update(this);
131 case Remote::FORWARD:
132 if (showtime > 1) showtime--;
135 case Remote::DF_DOWN:
137 case Remote::SKIPFORWARD:
138 showPicture(VMediaList::MV_NEXT);
139 BoxStack::getInstance()->update(this);
142 case Remote::REVERSE:
143 if (showtime < 50 ) showtime++;
159 showPicture(VMediaList::MV_NEXT);
160 BoxStack::getInstance()->update(this);
171 showtime=INITIAL_SHOWTIME;
178 rotate=WJpeg::ROT_90;
181 rotate=WJpeg::ROT_180;
184 rotate=WJpeg::ROT_270;
190 showPicture(VMediaList::MV_NONE,rotate);
191 BoxStack::getInstance()->update(this);
195 if (info) destroyInfo();
205 if (slideshow) startSlideshow();
206 // stop command getting to any more views
210 void VPicture::processMessage(Message* m)
212 if (m->message == Message::MOUSE_MOVE)
216 else if (m->message == Message::MOUSE_LBDOWN)
219 //check if press is outside this view! then simulate cancel
220 int x=(m->parameter>>16)-getScreenX();
221 int y=(m->parameter&0xFFFF)-getScreenY();
222 if (x<0 || y <0 || x>(int)getWidth() || y>(int)getHeight())
224 BoxStack::getInstance()->handleCommand(Remote::BACK); //simulate cancel press
229 VPicture * VPicture::createViewer(VMediaList * mparent, bool bslideshow) {
230 Log::getInstance()->log("VPicture::createViewer", Log::DEBUG, "p=%p",
232 VPicture *vmn=new VPicture(mparent);
233 BoxStack::getInstance()->add(vmn);
234 BoxStack::getInstance()->update(vmn);
236 if (bslideshow) vmn->startSlideshow();
238 BoxStack::getInstance()->update(vmn);
242 void VPicture::startSlideshow() {
244 Timers::getInstance()->setTimerD(this,1,showtime);
247 void VPicture::showPicture(ULONG move, int rt) {
249 currentMedia=parent->getMedia(MEDIA_TYPE_PICTURE,move);
251 if (mediaError || jpeg.hasError()) destroyInfo();
253 BoxStack::getInstance()->update(this);
257 int VPicture::load(Media *md) {
258 jpeg.init(NULL,false,NULL);
259 mediaError=tr("No media found");
262 const char *fname=md->getFileName();
264 int len=strlen(fname)+2+strlen(parent->getDirname());
269 fullname=new char[len];
270 sprintf(fullname,"%s/%s",parent->getDirname(),fname);
271 if (filename) delete filename;
273 filename=new char[len];
274 strcpy(filename,fname);
275 Log::getInstance()->log("VPicture::load", Log::DEBUG, "filename=%s,p=%p",
277 VDR* vdr=VDR::getInstance();
278 //do we have a banner?
279 bool haveBanner=banner!=NULL && ! shortBanner;
280 if (vdr->isConnected()) {
282 jpeg.init(fullname,false,reader);
283 jpeg.setRotate(rotate);
287 //only show the banner if it was there before
288 if (haveBanner) showBanner();
290 if(banner) destroyBanner();
292 Log::getInstance()->log("VPicture::load", Log::DEBUG, "success: filename=%s,p=%p",
297 mediaError=tr("no VDR connection");
302 void VPicture::showBanner(bool loading,int shortDisplay) {
303 //we are in the main thread - so we can (and must) safely hard destroy/create the banner
304 Timers::getInstance()->cancelTimer(this,2);
305 if (! filename || ! currentMedia) {
307 destroyBanner(!loading);
310 if (banner) destroyBanner(!loading);
311 banner= new VPictureBanner(this, loading, slideshow);
312 banner->fillColour(infoBack);
314 int len=strlen(filename)+Media::TIMEBUFLEN+20;
315 char *buf=new char[len];
316 char tbuf[Media::TIMEBUFLEN];
317 SNPRINTF(buf,len,"%c%02ds%c %s %s ",
321 currentMedia->getTimeString(tbuf),
323 banner->setText(buf);
327 banner->setText(filename);
330 if (shortDisplay != 0) shortBanner=true;
331 if (! slideshow && shortDisplay == 0) shortDisplay=8;
332 //OK we start timer if we don't load and either shortDisplay or no slideshow
333 if (! loading && shortDisplay != 0) Timers::getInstance()->setTimerD(this,2,shortDisplay);
334 BoxStack::getInstance()->add(banner);
335 BoxStack::getInstance()->update(banner);
339 void VPicture::destroyBanner(bool fromTimer) {
342 if (fromTimer) sendViewMsg(banner,true);
343 else BoxStack::getInstance()->remove(banner);
345 if (! fromTimer) Timers::getInstance()->cancelTimer(this,2);
348 void VPicture::updateBanner(bool shortDisplay) {
349 if (banner && ! shortBanner) {
352 else if (shortDisplay) {
356 void VPicture::timercall(int clientref) {
360 if (! slideshow) return;
361 Log::getInstance()->log("VPicture::timercall", Log::DEBUG, "slideshow");
362 sendCommandMsg(Remote::PLAY);
375 void VPicture::showInfo(){
376 if (info) destroyInfo();
377 if (! currentMedia) return;
380 info->setTitleText(currentMedia->getFileName());
381 info->setDropThrough();
382 info->setSize(500, 300);
383 info->createBuffer();
384 info->setBorderOn(1);
385 info->setTitleBarOn(1);
387 if (Video::getInstance()->getFormat() == Video::PAL)
388 info->setPosition(100, 180);
390 info->setPosition(100, 150);
392 char tbuf[Media::TIMEBUFLEN];
393 SNPRINTF(buf,INFOBUF,"%s= %s\n%s= %ld x %ld\n%s= %ld kBytes\n%s= %s\n%s= %ld\n%s= 1/%ld",
394 tr("Directory"), parent->getDirname(),
395 tr("Format(px)"),jpeg.getJpegInfo(WJpeg::JPEG_WIDTH),jpeg.getJpegInfo(WJpeg::JPEG_HEIGHT),
396 tr("Filesize"),jpeg.getJpegInfo(WJpeg::JPEG_SIZE)/1000,
397 tr("Time"),currentMedia->getTimeString(tbuf),
398 tr("Rotation"),90*jpeg.getJpegInfo(WJpeg::JPEG_ROTATE),
399 tr("Scale"),jpeg.getJpegInfo(WJpeg::JPEG_SCALE));
400 info->setMainText(buf);
402 sendViewMsg(info,false);
403 Timers::getInstance()->setTimerD(this,3,8);
405 void VPicture::updateInfo(){
410 void VPicture::destroyInfo(bool fromTimer){
412 sendViewMsg(info,true);
415 if (! fromTimer) Timers::getInstance()->cancelTimer(this,3);
418 void VPicture::sendViewMsg(Boxx *v,bool vdestroy) {
419 Message* m = new Message();
420 m->message = vdestroy?Message::CLOSE_ME:Message::ADD_VIEW;
421 m->to = BoxStack::getInstance();
423 m->parameter=(ULONG)v;
424 Command::getInstance()->postMessageFromOuterSpace(m);
426 void VPicture::sendCommandMsg(int command) {
427 Message* m = new Message();
428 m->message = Message::UDP_BUTTON;
429 m->to = Command::getInstance();
431 m->parameter=command;
432 Command::getInstance()->postMessageFromOuterSpace(m);