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",
114 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();
210 if (slideshow) startSlideshow();
211 // stop command getting to any more views
215 void VPicture::processMessage(Message* m)
217 if (m->message == Message::MOUSE_MOVE)
221 else if (m->message == Message::MOUSE_LBDOWN)
224 //check if press is outside this view! then simulate cancel
225 int x=(m->parameter>>16)-getScreenX();
226 int y=(m->parameter&0xFFFF)-getScreenY();
227 if (x<0 || y <0 || x>(int)getWidth() || y>(int)getHeight())
229 BoxStack::getInstance()->handleCommand(Remote::BACK); //simulate cancel press
234 VPicture * VPicture::createViewer(VMediaList * mparent, bool bslideshow) {
235 Log::getInstance()->log("VPicture::createViewer", Log::DEBUG, "p=%p",
237 VPicture *vmn=new VPicture(mparent);
238 BoxStack::getInstance()->add(vmn);
239 BoxStack::getInstance()->update(vmn);
241 if (bslideshow) vmn->startSlideshow();
243 BoxStack::getInstance()->update(vmn);
247 void VPicture::startSlideshow() {
249 Timers::getInstance()->setTimerD(this,1,showtime);
252 void VPicture::showPicture(ULONG move, int rt) {
254 currentMedia=parent->getMedia(MEDIA_TYPE_PICTURE,move);
256 if (mediaError || jpeg.hasError()) destroyInfo();
258 BoxStack::getInstance()->update(this);
262 int VPicture::load(Media *md) {
263 jpeg.init(NULL,false,NULL);
264 mediaError=tr("No media found");
267 const char *fname=md->getFileName();
269 int len=strlen(fname)+2+strlen(parent->getDirname());
274 fullname=new char[len];
275 sprintf(fullname,"%s/%s",parent->getDirname(),fname);
276 if (filename) delete filename;
278 filename=new char[len];
279 strcpy(filename,fname);
280 Log::getInstance()->log("VPicture::load", Log::DEBUG, "filename=%s,p=%p",
282 VDR* vdr=VDR::getInstance();
283 //do we have a banner?
284 bool haveBanner=banner!=NULL && ! shortBanner;
285 if (vdr->isConnected()) {
287 jpeg.init(fullname,false,reader);
288 jpeg.setRotate(rotate);
292 //only show the banner if it was there before
293 if (haveBanner) showBanner();
295 if(banner) destroyBanner();
297 Log::getInstance()->log("VPicture::load", Log::DEBUG, "success: filename=%s,p=%p",
302 mediaError=tr("no VDR connection");
307 void VPicture::showBanner(bool loading,int shortDisplay) {
308 //if the loading flag is set,
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 if (! loading) ; /*sendViewMsg(banner,false); upgrade to boxx */
342 BoxStack::getInstance()->add(banner);
343 BoxStack::getInstance()->update(banner);
348 void VPicture::destroyBanner(bool fromTimer) {
351 if (fromTimer) ;/* sendViewMsg(banner,true); upgrade to boxx*/
352 else BoxStack::getInstance()->remove(banner);
354 if (! fromTimer) Timers::getInstance()->cancelTimer(this,2);
357 void VPicture::updateBanner(bool shortDisplay) {
358 if (banner && ! shortBanner) {
361 else if (shortDisplay) {
365 void VPicture::timercall(int clientref) {
369 if (! slideshow) return;
370 Log::getInstance()->log("VPicture::timercall", Log::DEBUG, "slideshow");
371 sendCommandMsg(Remote::PLAY);
384 void VPicture::showInfo(){
385 if (info) destroyInfo();
386 if (! currentMedia) return;
389 info->setTitleText(currentMedia->getFileName());
390 info->setDropThrough();
391 info->setSize(500, 300);
392 info->createBuffer();
393 info->setBorderOn(1);
394 info->setTitleBarOn(1);
396 if (Video::getInstance()->getFormat() == Video::PAL)
397 info->setPosition(100, 180);
399 info->setPosition(100, 150);
401 char tbuf[Media::TIMEBUFLEN];
402 SNPRINTF(buf,INFOBUF,"%s= %s\n%s= %ld x %ld\n%s= %ld kBytes\n%s= %s\n%s= %ld\n%s= 1/%ld",
403 tr("Directory"), parent->getDirname(),
404 tr("Format(px)"),jpeg.getJpegInfo(WJpeg::JPEG_WIDTH),jpeg.getJpegInfo(WJpeg::JPEG_HEIGHT),
405 tr("Filesize"),jpeg.getJpegInfo(WJpeg::JPEG_SIZE)/1000,
406 tr("Time"),currentMedia->getTimeString(tbuf),
407 tr("Rotation"),90*jpeg.getJpegInfo(WJpeg::JPEG_ROTATE),
408 tr("Scale"),jpeg.getJpegInfo(WJpeg::JPEG_SCALE));
409 info->setMainText(buf);
411 sendViewMsg(info,false);
412 Timers::getInstance()->setTimerD(this,3,8);
414 void VPicture::updateInfo(){
419 void VPicture::destroyInfo(bool fromTimer){
421 sendViewMsg(info,true);
424 if (! fromTimer) Timers::getInstance()->cancelTimer(this,3);
427 void VPicture::sendViewMsg(Boxx *v,bool vdestroy) {
428 Message* m = new Message();
429 m->message = vdestroy?Message::CLOSE_ME:Message::ADD_VIEW;
430 m->to = BoxStack::getInstance();
432 m->parameter=(ULONG)v;
433 Command::getInstance()->postMessageFromOuterSpace(m);
435 void VPicture::sendCommandMsg(int command) {
436 Message* m = new Message();
437 m->message = Message::UDP_BUTTON;
438 m->to = Command::getInstance();
440 m->parameter=command;
441 Command::getInstance()->postMessageFromOuterSpace(m);